diff --git a/coreapi/chat_file_transfer.c b/coreapi/chat_file_transfer.c index 79f22ce47..7eab33106 100644 --- a/coreapi/chat_file_transfer.c +++ b/coreapi/chat_file_transfer.c @@ -29,5 +29,5 @@ #include "chat/chat-room.h" LinphoneChatMessage *linphone_chat_room_create_file_transfer_message(LinphoneChatRoom *cr, const LinphoneContent *initial_content) { - return L_GET_CPP_PTR_FROM_C_OBJECT(cr)->createFileTransferMessage(initial_content); + return L_GET_C_BACK_PTR(L_GET_CPP_PTR_FROM_C_OBJECT(cr)->createFileTransferMessage(initial_content)); } diff --git a/include/linphone/api/c-chat-message.h b/include/linphone/api/c-chat-message.h index b62cde920..011427cd2 100644 --- a/include/linphone/api/c-chat-message.h +++ b/include/linphone/api/c-chat-message.h @@ -126,7 +126,7 @@ LINPHONE_PUBLIC const LinphoneAddress* linphone_chat_message_get_to_address(Linp * @param[in] message LinphoneChatMessage object * @return The content type of the chat message */ -LINPHONE_PUBLIC const char * linphone_chat_message_get_content_type(const LinphoneChatMessage *msg); +LINPHONE_PUBLIC const char * linphone_chat_message_get_content_type(LinphoneChatMessage *msg); /** * Set the content type of a chat message. @@ -140,7 +140,7 @@ LINPHONE_PUBLIC void linphone_chat_message_set_content_type(LinphoneChatMessage * Get text part of this message * @return text or NULL if no text. */ -LINPHONE_PUBLIC const char* linphone_chat_message_get_text(const LinphoneChatMessage* msg); +LINPHONE_PUBLIC const char* linphone_chat_message_get_text(LinphoneChatMessage* msg); /** * Returns the id used to identify this message in the storage database @@ -235,14 +235,14 @@ LINPHONE_PUBLIC LinphoneContent* linphone_chat_message_get_file_transfer_informa * @param[in] message LinphoneChatMessage object * @return Whether or not the message is a file tranfer */ -LINPHONE_PUBLIC bool_t linphone_chat_message_is_file_transfer(const LinphoneChatMessage *message); +LINPHONE_PUBLIC bool_t linphone_chat_message_is_file_transfer(LinphoneChatMessage *message); /** * Return whether or not a chat message is a text. * @param[in] message LinphoneChatMessage object * @return Whether or not the message is a text */ -LINPHONE_PUBLIC bool_t linphone_chat_message_is_text(const LinphoneChatMessage *message); +LINPHONE_PUBLIC bool_t linphone_chat_message_is_text(LinphoneChatMessage *message); /** * Get if a chat message is to be stored. diff --git a/src/c-wrapper/api/c-chat-message.cpp b/src/c-wrapper/api/c-chat-message.cpp index 1f66d709a..4206aefee 100644 --- a/src/c-wrapper/api/c-chat-message.cpp +++ b/src/c-wrapper/api/c-chat-message.cpp @@ -173,26 +173,28 @@ void linphone_chat_message_set_appdata(LinphoneChatMessage *msg, const char *dat } void linphone_chat_message_set_from_address(LinphoneChatMessage *msg, const LinphoneAddress *from) { - if (!from) L_GET_CPP_PTR_FROM_C_OBJECT(msg)->setFromAddress(nullptr); - else L_GET_CPP_PTR_FROM_C_OBJECT(msg)->setFromAddress(make_shared(linphone_address_as_string(from))); + LinphonePrivate::Address addr; + if (from) addr = LinphonePrivate::Address(linphone_address_as_string(from)); + else L_GET_CPP_PTR_FROM_C_OBJECT(msg)->setFromAddress(addr); } const LinphoneAddress *linphone_chat_message_get_from_address(LinphoneChatMessage *msg) { if (msg->from) linphone_address_unref(msg->from); - msg->from = linphone_address_new(L_GET_CPP_PTR_FROM_C_OBJECT(msg)->getFromAddress()->asString().c_str()); + msg->from = linphone_address_new(L_GET_CPP_PTR_FROM_C_OBJECT(msg)->getFromAddress().asString().c_str()); return msg->from; } void linphone_chat_message_set_to_address(LinphoneChatMessage *msg, const LinphoneAddress *to) { - if (!to) L_GET_CPP_PTR_FROM_C_OBJECT(msg)->setToAddress(nullptr); - else L_GET_CPP_PTR_FROM_C_OBJECT(msg)->setToAddress(make_shared(linphone_address_as_string(to))); + LinphonePrivate::Address addr; + if (to) addr = LinphonePrivate::Address(linphone_address_as_string(to)); + else L_GET_CPP_PTR_FROM_C_OBJECT(msg)->setToAddress(addr); } const LinphoneAddress *linphone_chat_message_get_to_address(LinphoneChatMessage *msg) { if (msg->to) linphone_address_unref(msg->to); - msg->to = linphone_address_new(L_GET_CPP_PTR_FROM_C_OBJECT(msg)->getToAddress()->asString().c_str()); + msg->to = linphone_address_new(L_GET_CPP_PTR_FROM_C_OBJECT(msg)->getToAddress().asString().c_str()); return msg->to; } @@ -325,7 +327,7 @@ void * linphone_chat_message_get_message_state_changed_cb_user_data(LinphoneChat // Structure has changed, hard to keep the behavior // ============================================================================= -const char * linphone_chat_message_get_content_type(const LinphoneChatMessage *msg) { +const char * linphone_chat_message_get_content_type(LinphoneChatMessage *msg) { return L_STRING_TO_C(L_GET_PRIVATE_FROM_C_OBJECT(msg)->getContentType()); } @@ -333,7 +335,7 @@ void linphone_chat_message_set_content_type(LinphoneChatMessage *msg, const char L_GET_PRIVATE_FROM_C_OBJECT(msg)->setContentType(L_C_TO_STRING(content_type)); } -const char *linphone_chat_message_get_text(const LinphoneChatMessage *msg) { +const char *linphone_chat_message_get_text(LinphoneChatMessage *msg) { return L_STRING_TO_C(L_GET_PRIVATE_FROM_C_OBJECT(msg)->getText()); } @@ -369,11 +371,11 @@ LinphoneReason linphone_chat_message_get_reason(LinphoneChatMessage *msg) { return linphone_error_info_get_reason(linphone_chat_message_get_error_info(msg)); } -bool_t linphone_chat_message_is_file_transfer(const LinphoneChatMessage *msg) { +bool_t linphone_chat_message_is_file_transfer(LinphoneChatMessage *msg) { return LinphonePrivate::ContentType::isFileTransfer(linphone_chat_message_get_content_type(msg)); } -bool_t linphone_chat_message_is_text(const LinphoneChatMessage *msg) { +bool_t linphone_chat_message_is_text(LinphoneChatMessage *msg) { return LinphonePrivate::ContentType::isText(linphone_chat_message_get_content_type(msg)); } diff --git a/src/c-wrapper/api/c-chat-room.cpp b/src/c-wrapper/api/c-chat-room.cpp index dc4bd45d1..1b78fd9e8 100644 --- a/src/c-wrapper/api/c-chat-room.cpp +++ b/src/c-wrapper/api/c-chat-room.cpp @@ -68,12 +68,11 @@ void linphone_chat_room_release (LinphoneChatRoom *cr) { } void linphone_chat_room_remove_transient_message (LinphoneChatRoom *cr, LinphoneChatMessage *msg) { - L_GET_PRIVATE_FROM_C_OBJECT(cr)->removeTransientMessage(msg); + L_GET_PRIVATE_FROM_C_OBJECT(cr)->removeTransientMessage(L_GET_CPP_PTR_FROM_C_OBJECT(msg)); } void linphone_chat_room_send_message (LinphoneChatRoom *cr, const char *msg) { - LinphoneChatMessage *message = L_GET_CPP_PTR_FROM_C_OBJECT(cr)->createMessage(msg); - L_GET_CPP_PTR_FROM_C_OBJECT(cr)->sendMessage(message); + L_GET_CPP_PTR_FROM_C_OBJECT(cr)->sendMessage(L_GET_CPP_PTR_FROM_C_OBJECT(cr)->createMessage(msg)); } bool_t linphone_chat_room_is_remote_composing (const LinphoneChatRoom *cr) { @@ -97,7 +96,7 @@ const LinphoneAddress *linphone_chat_room_get_peer_address (LinphoneChatRoom *cr } LinphoneChatMessage *linphone_chat_room_create_message (LinphoneChatRoom *cr, const char *message) { - return L_GET_CPP_PTR_FROM_C_OBJECT(cr)->createMessage(L_C_TO_STRING(message)); + return L_GET_C_BACK_PTR(L_GET_CPP_PTR_FROM_C_OBJECT(cr)->createMessage(L_C_TO_STRING(message))); } LinphoneChatMessage *linphone_chat_room_create_message_2 ( @@ -135,16 +134,16 @@ void linphone_chat_room_send_message2 ( ) { linphone_chat_message_set_message_state_changed_cb(msg, status_cb); linphone_chat_message_set_message_state_changed_cb_user_data(msg, ud); - L_GET_CPP_PTR_FROM_C_OBJECT(cr)->sendMessage(msg); + L_GET_CPP_PTR_FROM_C_OBJECT(cr)->sendMessage(L_GET_CPP_PTR_FROM_C_OBJECT(msg)); } void linphone_chat_room_send_chat_message_2 (LinphoneChatRoom *cr, LinphoneChatMessage *msg) { linphone_chat_message_ref(msg); - L_GET_CPP_PTR_FROM_C_OBJECT(cr)->sendMessage(msg); + L_GET_CPP_PTR_FROM_C_OBJECT(cr)->sendMessage(L_GET_CPP_PTR_FROM_C_OBJECT(msg)); } void linphone_chat_room_send_chat_message (LinphoneChatRoom *cr, LinphoneChatMessage *msg) { - L_GET_CPP_PTR_FROM_C_OBJECT(cr)->sendMessage(msg); + L_GET_CPP_PTR_FROM_C_OBJECT(cr)->sendMessage(L_GET_CPP_PTR_FROM_C_OBJECT(msg)); } uint32_t linphone_chat_room_get_char (const LinphoneChatRoom *cr) { @@ -169,7 +168,7 @@ void linphone_chat_room_set_call (LinphoneChatRoom *cr, LinphoneCall *call) { } bctbx_list_t *linphone_chat_room_get_transient_messages (const LinphoneChatRoom *cr) { - return L_GET_C_LIST_FROM_CPP_LIST(L_GET_PRIVATE_FROM_C_OBJECT(cr)->getTransientMessages()); + return L_GET_RESOLVED_C_LIST_FROM_CPP_LIST(L_GET_PRIVATE_FROM_C_OBJECT(cr)->getTransientMessages()); } void linphone_chat_room_mark_as_read (LinphoneChatRoom *cr) { @@ -185,7 +184,7 @@ int linphone_chat_room_get_history_size (LinphoneChatRoom *cr) { } void linphone_chat_room_delete_message (LinphoneChatRoom *cr, LinphoneChatMessage *msg) { - L_GET_CPP_PTR_FROM_C_OBJECT(cr)->deleteMessage(msg); + L_GET_CPP_PTR_FROM_C_OBJECT(cr)->deleteMessage(L_GET_CPP_PTR_FROM_C_OBJECT(msg)); } void linphone_chat_room_delete_history (LinphoneChatRoom *cr) { @@ -193,15 +192,15 @@ void linphone_chat_room_delete_history (LinphoneChatRoom *cr) { } bctbx_list_t *linphone_chat_room_get_history_range (LinphoneChatRoom *cr, int startm, int endm) { - return L_GET_C_LIST_FROM_CPP_LIST(L_GET_CPP_PTR_FROM_C_OBJECT(cr)->getHistoryRange(startm, endm)); + return L_GET_RESOLVED_C_LIST_FROM_CPP_LIST(L_GET_CPP_PTR_FROM_C_OBJECT(cr)->getHistoryRange(startm, endm)); } bctbx_list_t *linphone_chat_room_get_history (LinphoneChatRoom *cr, int nb_message) { - return L_GET_C_LIST_FROM_CPP_LIST(L_GET_CPP_PTR_FROM_C_OBJECT(cr)->getHistory(nb_message)); + return L_GET_RESOLVED_C_LIST_FROM_CPP_LIST(L_GET_CPP_PTR_FROM_C_OBJECT(cr)->getHistory(nb_message)); } LinphoneChatMessage *linphone_chat_room_find_message (LinphoneChatRoom *cr, const char *message_id) { - return L_GET_CPP_PTR_FROM_C_OBJECT(cr)->findMessage(message_id); + return L_GET_C_BACK_PTR(L_GET_CPP_PTR_FROM_C_OBJECT(cr)->findMessage(message_id)); } LinphoneChatRoomCbs *linphone_chat_room_get_callbacks (const LinphoneChatRoom *cr) { diff --git a/src/chat/chat-message-p.h b/src/chat/chat-message-p.h index eb9a3d74c..3988857ff 100644 --- a/src/chat/chat-message-p.h +++ b/src/chat/chat-message-p.h @@ -65,10 +65,10 @@ public: // Methods only used for C wrapper // ----------------------------------------------------------------------------- - const std::string& getContentType() const; + const std::string& getContentType(); void setContentType(const std::string& contentType); - const std::string& getText() const; + const std::string& getText(); void setText(const std::string& text); LinphoneContent * getFileTransferInformation() const; @@ -98,11 +98,11 @@ public: private: std::shared_ptr chatRoom; - ChatMessage::Direction direction = ChatMessage::Incoming; - ChatMessage::State state = ChatMessage::Idle; + ChatMessage::Direction direction = ChatMessage::Direction::Incoming; + ChatMessage::State state = ChatMessage::State::Idle; unsigned int storageId = 0; - std::shared_ptr
from; - std::shared_ptr
to; + Address from; + Address to; time_t time = 0; std::string id = ""; std::string appData = ""; @@ -122,9 +122,10 @@ private: SalOp *salOp = NULL; SalCustomHeader *salCustomHeaders = NULL; unsigned long backgroundTaskId; - // Used for compatibility with previous C API + // Cache for returned values, used for compatibility with previous C API std::string cContentType = ""; std::string cText = ""; + // Used for compatibility with previous C API LinphoneContent *cFileTransferInformation = NULL; // ----------------------------------------------------------------------------- diff --git a/src/chat/chat-message.cpp b/src/chat/chat-message.cpp index 9235b0e7b..d3bc1b039 100644 --- a/src/chat/chat-message.cpp +++ b/src/chat/chat-message.cpp @@ -22,11 +22,11 @@ #include "linphone/core.h" #include "linphone/lpconfig.h" #include "c-wrapper/c-wrapper.h" +#include "address/address.h" #include "chat-message-p.h" -#include "chat-message.h" -#include "content/content.h" +#include "content/content.h" #include "modifier/multipart-chat-message-modifier.h" #include "modifier/cpim-chat-message-modifier.h" #include "chat-room-p.h" @@ -133,20 +133,33 @@ string ChatMessagePrivate::getSalCustomHeaderValue(const string& name) { // ----------------------------------------------------------------------------- -const string& ChatMessagePrivate::getContentType() const { +const string& ChatMessagePrivate::getContentType() { + if (internalContent) { + ContentType contentType = internalContent->getContentType(); + cContentType = contentType.asString(); + } return cContentType; } void ChatMessagePrivate::setContentType(const string& contentType) { - cContentType = contentType; + if (!internalContent) { + internalContent = make_shared(); + } + internalContent->setContentType(contentType); } -const string& ChatMessagePrivate::getText() const { +const string& ChatMessagePrivate::getText() { + if (internalContent) { + cText = internalContent->getBodyAsString(); + } return cText; } void ChatMessagePrivate::setText(const string& text) { - cText = text; + if (!internalContent) { + internalContent = make_shared(); + } + internalContent->setBody(text); } LinphoneContent * ChatMessagePrivate::getFileTransferInformation() const { @@ -464,7 +477,7 @@ void ChatMessagePrivate::onRecvBody(belle_sip_user_body_handler_t *bh, belle_sip } } else { ms_warning("File transfer decrypt failed with code %d", (int)retval); - setState(ChatMessage::FileTransferError); + setState(ChatMessage::State::FileTransferError); } return; @@ -654,22 +667,22 @@ void ChatMessagePrivate::processResponseFromPostFile(const belle_http_response_e } xmlFreeDoc(xmlMessageBody); } else { // no encryption key, transfer in plain, just copy the msg sent by server - cText = ms_strdup(body); + setText(body); } - cContentType = "application/vnd.gsma.rcs-ft-http+xml"; - q->updateState(ChatMessage::FileTransferDone); + setContentType("application/vnd.gsma.rcs-ft-http+xml"); + q->updateState(ChatMessage::State::FileTransferDone); releaseHttpRequest(); - chatRoom->sendMessage(L_GET_C_BACK_PTR(q)); + //TODO chatRoom->sendMessage(q); fileUploadEndBackgroundTask(); } else { ms_warning("Received empty response from server, file transfer failed"); - q->updateState(ChatMessage::NotDelivered); + q->updateState(ChatMessage::State::NotDelivered); releaseHttpRequest(); fileUploadEndBackgroundTask(); } } else { ms_warning("Unhandled HTTP code response %d for file transfer", code); - q->updateState(ChatMessage::NotDelivered); + q->updateState(ChatMessage::State::NotDelivered); releaseHttpRequest(); fileUploadEndBackgroundTask(); } @@ -755,7 +768,7 @@ void ChatMessagePrivate::processAuthRequestedDownload(const belle_sip_auth_event L_Q(); ms_error("Error during file download : auth requested for msg [%p]", this); - q->updateState(ChatMessage::FileTransferError); + q->updateState(ChatMessage::State::FileTransferError); releaseHttpRequest(); } @@ -767,9 +780,9 @@ static void _chat_message_process_io_error_upload(void *data, const belle_sip_io void ChatMessagePrivate::processIoErrorUpload(const belle_sip_io_error_event_t *event) { L_Q(); ms_error("I/O Error during file upload of msg [%p]", this); - q->updateState(ChatMessage::NotDelivered); + q->updateState(ChatMessage::State::NotDelivered); releaseHttpRequest(); - chatRoom->getPrivate()->removeTransientMessage(L_GET_C_BACK_PTR(q)); + //TODO chatRoom->getPrivate()->removeTransientMessage(q); } static void _chat_message_process_auth_requested_upload(void *data, belle_sip_auth_event *event) { @@ -780,9 +793,9 @@ static void _chat_message_process_auth_requested_upload(void *data, belle_sip_au void ChatMessagePrivate::processAuthRequestedUpload(const belle_sip_auth_event *event) { L_Q(); ms_error("Error during file upload: auth requested for msg [%p]", this); - q->updateState(ChatMessage::NotDelivered); + q->updateState(ChatMessage::State::NotDelivered); releaseHttpRequest(); - chatRoom->getPrivate()->removeTransientMessage(L_GET_C_BACK_PTR(q)); + //TODO chatRoom->getPrivate()->removeTransientMessage(q); } static void _chat_message_process_io_error_download(void *data, const belle_sip_io_error_event_t *event) { @@ -794,7 +807,7 @@ void ChatMessagePrivate::processIoErrorDownload(const belle_sip_io_error_event_t L_Q(); ms_error("I/O Error during file download msg [%p]", this); - q->updateState(ChatMessage::FileTransferError); + q->updateState(ChatMessage::State::FileTransferError); releaseHttpRequest(); } @@ -809,7 +822,7 @@ void ChatMessagePrivate::processResponseFromGetFile(const belle_http_response_ev int code = belle_http_response_get_status_code(event->response); if (code >= 400 && code < 500) { ms_warning("File transfer failed with code %d", code); - setState(ChatMessage::FileTransferError); + setState(ChatMessage::State::FileTransferError); } else if (code != 200) { ms_warning("Unhandled HTTP code response %d for file transfer", code); } @@ -959,26 +972,36 @@ void ChatMessage::setAppdata (const string &appData) { linphone_chat_message_store_appdata(L_GET_C_BACK_PTR(this)); } -shared_ptr
ChatMessage::getFromAddress () const { +const Address& ChatMessage::getFromAddress () const { L_D(); return d->from; } -void ChatMessage::setFromAddress(shared_ptr
from) { +void ChatMessage::setFromAddress(Address from) { L_D(); d->from = from; } -shared_ptr
ChatMessage::getToAddress () const { +void ChatMessage::setFromAddress(const string& from) { + L_D(); + d->from = Address(from); +} + +const Address& ChatMessage::getToAddress () const { L_D(); return d->to; } -void ChatMessage::setToAddress(shared_ptr
to) { +void ChatMessage::setToAddress(Address to) { L_D(); d->to = to; } +void ChatMessage::setToAddress(const string& to) { + L_D(); + d->to = Address(to); +} + const string& ChatMessage::getFileTransferFilepath() const { L_D(); return d->fileTransferFilePath; @@ -1061,6 +1084,18 @@ void ChatMessage::removeCustomHeader (const string &headerName) { // ----------------------------------------------------------------------------- +void ChatMessage::store() { + L_D(); + + if (d->storageId != 0) { + /* The message has already been stored (probably because of file transfer), update it */ + linphone_chat_message_store_update(L_GET_C_BACK_PTR(this)); + } else { + /* Store the new message */ + linphone_chat_message_store(L_GET_C_BACK_PTR(this)); + } +} + void ChatMessage::updateState(State state) { L_D(); @@ -1068,7 +1103,7 @@ void ChatMessage::updateState(State state) { linphone_chat_message_store_state(L_GET_C_BACK_PTR(this)); if (state == Delivered || state == NotDelivered) { - d->chatRoom->getPrivate()->moveTransientMessageToWeakMessages(L_GET_C_BACK_PTR(this)); + d->chatRoom->getPrivate()->moveTransientMessageToWeakMessages(static_pointer_cast(shared_from_this())); } } @@ -1098,7 +1133,7 @@ void ChatMessage::reSend() { return; } - d->chatRoom->sendMessage(L_GET_C_BACK_PTR(this)); + d->chatRoom->sendMessage(static_pointer_cast(shared_from_this())); } void ChatMessage::sendDeliveryNotification(LinphoneReason reason) { @@ -1201,7 +1236,7 @@ int ChatMessage::putCharacter(uint32_t character) { d->setTime(ms_time(0)); d->state = Displayed; d->direction = Outgoing; - setFromAddress(make_shared(linphone_address_as_string(linphone_address_new(linphone_core_get_identity(lc))))); + setFromAddress(LinphonePrivate::Address(linphone_address_as_string(linphone_address_new(linphone_core_get_identity(lc))))); linphone_chat_message_store(L_GET_C_BACK_PTR(this)); d->rttMessage = ""; } diff --git a/src/chat/chat-message.h b/src/chat/chat-message.h index 153bab0aa..043e1fb1e 100644 --- a/src/chat/chat-message.h +++ b/src/chat/chat-message.h @@ -22,7 +22,7 @@ #include #include -#include "imdn.h" +#include "enums.h" #include "linphone/api/c-types.h" #include "linphone/api/c-chat-message.h" @@ -34,19 +34,22 @@ LINPHONE_BEGIN_NAMESPACE class Address; class ChatRoom; +class ChatRoomPrivate; class Content; class ErrorInfo; class ChatMessagePrivate; class LINPHONE_PUBLIC ChatMessage : public Object { friend class ChatRoom; + friend class ChatRoomPrivate; + friend class RealTimeTextChatRoomPrivate; -public: +public: enum Direction { Incoming, Outgoing }; - + enum State { Idle, InProgress, @@ -69,6 +72,7 @@ public: // Methods // ----------------------------------------------------------------------------- + void store(); void updateState(State state); void send(); void reSend(); @@ -105,11 +109,13 @@ public: const std::string& getAppdata () const; void setAppdata (const std::string &appData); - std::shared_ptr
getFromAddress () const; - void setFromAddress(std::shared_ptr
from); + const Address& getFromAddress () const; + void setFromAddress(Address from); + void setFromAddress(const std::string& from); - std::shared_ptr
getToAddress () const; - void setToAddress(std::shared_ptr
to); + const Address& getToAddress () const; + void setToAddress(Address to); + void setToAddress(const std::string& to); const std::string& getFileTransferFilepath() const; void setFileTransferFilepath(const std::string &path); diff --git a/src/chat/chat-room-p.h b/src/chat/chat-room-p.h index d40d69f5d..02d6e802c 100644 --- a/src/chat/chat-room-p.h +++ b/src/chat/chat-room-p.h @@ -41,16 +41,15 @@ public: private: static int createChatMessageFromDb (void *data, int argc, char **argv, char **colName); - static void onWeakMessageDestroyed (void *obj, belle_sip_object_t *messageBeingDestroyed); public: - void addTransientMessage (LinphoneChatMessage *msg); - void addWeakMessage (LinphoneChatMessage *msg); - std::list getTransientMessages () const { + void addTransientMessage (std::shared_ptr msg); + void addWeakMessage (std::shared_ptr msg); + std::list > getTransientMessages () const { return transientMessages; } - void moveTransientMessageToWeakMessages (LinphoneChatMessage *msg); - void removeTransientMessage (LinphoneChatMessage *msg); + void moveTransientMessageToWeakMessages (std::shared_ptr msg); + void removeTransientMessage (std::shared_ptr msg); void release (); void sendImdn (const std::string &content, LinphoneReason reason); @@ -62,27 +61,26 @@ protected: void sendIsComposingNotification (); int createChatMessageFromDb (int argc, char **argv, char **colName); - void onWeakMessageDestroyed (LinphoneChatMessage *messageBeingDestroyed); - LinphoneChatMessage *getTransientMessage (unsigned int storageId) const; - LinphoneChatMessage *getWeakMessage (unsigned int storageId) const; + std::shared_ptr getTransientMessage (unsigned int storageId) const; + std::shared_ptr getWeakMessage (unsigned int storageId) const; int sqlRequest (sqlite3 *db, const std::string &stmt); void sqlRequestMessage (sqlite3 *db, const std::string &stmt); - std::list findMessages (const std::string &messageId); - void storeOrUpdateMessage (LinphoneChatMessage *msg); + std::list > findMessages (const std::string &messageId); + void storeOrUpdateMessage (std::shared_ptr msg); public: LinphoneReason messageReceived (SalOp *op, const SalMessage *msg); void realtimeTextReceived (uint32_t character, LinphoneCall *call); protected: - void chatMessageReceived (LinphoneChatMessage *msg); + void chatMessageReceived (std::shared_ptr msg); void imdnReceived (const std::string &text); void isComposingReceived (const std::string &text); private: - void notifyChatMessageReceived (LinphoneChatMessage *msg); + void notifyChatMessageReceived (std::shared_ptr msg); void notifyStateChanged (); - void notifyUndecryptableMessageReceived (LinphoneChatMessage *msg); + void notifyUndecryptableMessageReceived (std::shared_ptr msg); private: /* IsComposingListener */ @@ -98,11 +96,11 @@ public: int unreadCount = -1; bool isComposing = false; bool remoteIsComposing = false; - std::list messages; - std::list transientMessages; - std::list weakMessages; + std::list > messages; + std::list > transientMessages; + std::list > weakMessages; std::list receivedRttCharacters; - LinphoneChatMessage *pendingMessage = nullptr; + std::shared_ptr pendingMessage = nullptr; IsComposing isComposingHandler; private: diff --git a/src/chat/chat-room.cpp b/src/chat/chat-room.cpp index b29f39575..8d48b34b1 100644 --- a/src/chat/chat-room.cpp +++ b/src/chat/chat-room.cpp @@ -23,13 +23,12 @@ #include "c-wrapper/c-wrapper.h" #include "chat-room-p.h" -#include "content/content-type.h" #include "imdn.h" -#include "logger/logger.h" - +#include "content/content.h" #include "chat-message-p.h" #include "chat-room.h" #include "sal/message_op.h" +#include "logger/logger.h" // ============================================================================= @@ -41,10 +40,10 @@ ChatRoomPrivate::ChatRoomPrivate (LinphoneCore *core) : core(core), isComposingHandler(core, this) {} ChatRoomPrivate::~ChatRoomPrivate () { - for (auto &message : transientMessages) + /*for (auto &message : transientMessages) linphone_chat_message_release(message); if (pendingMessage) - linphone_chat_message_unref(pendingMessage); + linphone_chat_message_unref(pendingMessage);*/ } // ----------------------------------------------------------------------------- @@ -54,26 +53,20 @@ int ChatRoomPrivate::createChatMessageFromDb (void *data, int argc, char **argv, return d->createChatMessageFromDb(argc, argv, colName); } -void ChatRoomPrivate::onWeakMessageDestroyed (void *obj, belle_sip_object_t *messageBeingDestroyed) { - ChatRoomPrivate *d = reinterpret_cast(obj); - d->onWeakMessageDestroyed(reinterpret_cast(messageBeingDestroyed)); -} - // ----------------------------------------------------------------------------- -void ChatRoomPrivate::addTransientMessage (LinphoneChatMessage *msg) { +void ChatRoomPrivate::addTransientMessage (shared_ptr msg) { auto iter = find(transientMessages.begin(), transientMessages.end(), msg); if (iter == transientMessages.end()) - transientMessages.push_back(linphone_chat_message_ref(msg)); + transientMessages.push_back(msg); } -void ChatRoomPrivate::addWeakMessage (LinphoneChatMessage *msg) { - auto iter = find(weakMessages.begin(), weakMessages.end(), msg); - if (iter == weakMessages.end()) - weakMessages.push_back(reinterpret_cast(belle_sip_object_weak_ref(msg, onWeakMessageDestroyed, this))); +void ChatRoomPrivate::addWeakMessage (shared_ptr msg) { + weak_ptr weakptr(msg); + weakMessages.push_back(weakptr); } -void ChatRoomPrivate::moveTransientMessageToWeakMessages (LinphoneChatMessage *msg) { +void ChatRoomPrivate::moveTransientMessageToWeakMessages (shared_ptr msg) { auto iter = find(transientMessages.begin(), transientMessages.end(), msg); if (iter != transientMessages.end()) { /* msg is not transient anymore, we can remove it from our transient list and unref it */ @@ -84,10 +77,9 @@ void ChatRoomPrivate::moveTransientMessageToWeakMessages (LinphoneChatMessage *m } } -void ChatRoomPrivate::removeTransientMessage (LinphoneChatMessage *msg) { +void ChatRoomPrivate::removeTransientMessage (shared_ptr msg) { auto iter = find(transientMessages.begin(), transientMessages.end(), msg); if (iter != transientMessages.end()) { - linphone_chat_message_unref(*iter); transientMessages.erase(iter); } } @@ -98,16 +90,16 @@ void ChatRoomPrivate::release () { L_Q(); isComposingHandler.stopTimers(); - for (auto &message : weakMessages) + /*for (auto &message : weakMessages) linphone_chat_message_deactivate(message); for (auto &message : transientMessages) - linphone_chat_message_deactivate(message); + linphone_chat_message_deactivate(message);*/ core = nullptr; linphone_chat_room_unref(L_GET_C_BACK_PTR(q)); } -void ChatRoomPrivate::sendImdn (const string &content, LinphoneReason reason) { +void ChatRoomPrivate::sendImdn (const string &payload, LinphoneReason reason) { L_Q(); const char *identity = nullptr; @@ -121,12 +113,15 @@ void ChatRoomPrivate::sendImdn (const string &content, LinphoneReason reason) { /* Sending out of call */ SalMessageOp *op = new SalMessageOp(core->sal); linphone_configure_op(core, op, peer, nullptr, !!lp_config_get_int(core->config, "sip", "chat_msg_with_contact", 0)); - LinphoneChatMessage *msg = q->createMessage(content); - LinphoneAddress *fromAddr = linphone_address_new(identity); - linphone_chat_message_set_from_address(msg, fromAddr); - LinphoneAddress *toAddr = linphone_address_new(peerAddress.asString().c_str()); - linphone_chat_message_set_to_address(msg, toAddr); - linphone_chat_message_set_content_type(msg, "message/imdn+xml"); + + shared_ptr msg = q->createMessage(); + msg->setFromAddress(identity); + msg->setToAddress(peerAddress.asString()); + + shared_ptr content = make_shared(); + content->setContentType("message/imdn+xml"); + content->setBody(payload); + msg->addContent(content); /* Do not try to encrypt the notification when it is reporting an error (maybe it should be bypassed only for some reasons). */ int retval = -1; @@ -135,17 +130,14 @@ void ChatRoomPrivate::sendImdn (const string &content, LinphoneReason reason) { LinphoneImEncryptionEngineCbs *imeeCbs = linphone_im_encryption_engine_get_callbacks(imee); LinphoneImEncryptionEngineCbsOutgoingMessageCb cbProcessOutgoingMessage = linphone_im_encryption_engine_cbs_get_process_outgoing_message(imeeCbs); if (cbProcessOutgoingMessage) { - retval = cbProcessOutgoingMessage(imee, L_GET_C_BACK_PTR(q), msg); + retval = cbProcessOutgoingMessage(imee, L_GET_C_BACK_PTR(q), L_GET_C_BACK_PTR(msg)); } } if (retval <= 0) { - op->send_message(identity, peerAddress.asString().c_str(), linphone_chat_message_get_content_type(msg), linphone_chat_message_get_text(msg), nullptr); + op->send_message(identity, peerAddress.asString().c_str(), msg->getPrivate()->getContentType().c_str(), msg->getPrivate()->getText().c_str(), nullptr); } - linphone_chat_message_unref(msg); - linphone_address_unref(fromAddr); - linphone_address_unref(toAddr); linphone_address_unref(peer); op->unref(); } @@ -210,30 +202,31 @@ void ChatRoomPrivate::sendIsComposingNotification () { /* Sending out of call */ SalMessageOp *op = new SalMessageOp(core->sal); linphone_configure_op(core, op, peer, nullptr, !!lp_config_get_int(core->config, "sip", "chat_msg_with_contact", 0)); - string content = isComposingHandler.marshal(isComposing); - if (!content.empty()) { + string payload = isComposingHandler.marshal(isComposing); + if (!payload.empty()) { int retval = -1; - LinphoneAddress *fromAddr = linphone_address_new(identity); - LinphoneChatMessage *msg = q->createMessage(content); - linphone_chat_message_set_from_address(msg, fromAddr); - linphone_chat_message_set_to_address(msg, peer); - linphone_chat_message_set_content_type(msg, "application/im-iscomposing+xml"); + + shared_ptr msg = q->createMessage(); + msg->setFromAddress(identity); + msg->setToAddress(peerAddress.asString()); + + shared_ptr content = make_shared(); + content->setContentType("application/im-iscomposing+xml"); + content->setBody(payload); + msg->addContent(content); LinphoneImEncryptionEngine *imee = linphone_core_get_im_encryption_engine(core); if (imee) { LinphoneImEncryptionEngineCbs *imeeCbs = linphone_im_encryption_engine_get_callbacks(imee); LinphoneImEncryptionEngineCbsOutgoingMessageCb cbProcessOutgoingMessage = linphone_im_encryption_engine_cbs_get_process_outgoing_message(imeeCbs); if (cbProcessOutgoingMessage) { - retval = cbProcessOutgoingMessage(imee, L_GET_C_BACK_PTR(q), msg); + retval = cbProcessOutgoingMessage(imee, L_GET_C_BACK_PTR(q), L_GET_C_BACK_PTR(msg)); } } if (retval <= 0) { - op->send_message(identity, peerAddress.asString().c_str(), linphone_chat_message_get_content_type(msg), linphone_chat_message_get_text(msg), nullptr); + op->send_message(identity, peerAddress.asString().c_str(), msg->getPrivate()->getContentType().c_str(), msg->getPrivate()->getText().c_str(), nullptr); } - - linphone_chat_message_unref(msg); - linphone_address_unref(fromAddr); op->unref(); } linphone_address_unref(peer); @@ -266,40 +259,53 @@ int ChatRoomPrivate::createChatMessageFromDb (int argc, char **argv, char **colN unsigned int storageId = (unsigned int)atoi(argv[0]); /* Check if the message exists in the weak messages list, in which case we should return that one. */ - LinphoneChatMessage *newMessage = getWeakMessage(storageId); - if (!newMessage) { + shared_ptr message = getWeakMessage(storageId); + if (!message) { /* Check if the message exists in the transient list, in which case we should return that one. */ - newMessage = getTransientMessage(storageId); + message = getTransientMessage(storageId); } - if (!newMessage) { - newMessage = q->createMessage(argv[4] ? argv[4] : ""); + if (!message) { + message = q->createMessage(); - LinphoneAddress *peer = linphone_address_new(peerAddress.asString().c_str()); - if (atoi(argv[3]) == LinphoneChatMessageIncoming) { - linphone_chat_message_set_incoming(newMessage); - linphone_chat_message_set_from_address(newMessage, peer); - } else { - linphone_chat_message_set_outgoing(newMessage); - linphone_chat_message_set_to_address(newMessage, peer); + shared_ptr content = make_shared(); + message->addContent(content); + + if (argv[4]) { + content->setBody(argv[4]); } - linphone_address_unref(peer); + if (argv[13]) { + content->setContentType(argv[13]); + } - linphone_chat_message_set_time(newMessage, (time_t)atol(argv[9])); - linphone_chat_message_set_state(newMessage, static_cast(atoi(argv[7]))); - linphone_chat_message_set_storage_id(newMessage, storageId); - linphone_chat_message_set_external_body_url(newMessage, ms_strdup(argv[8])); - linphone_chat_message_set_appdata(newMessage, ms_strdup(argv[10])); - linphone_chat_message_set_message_id(newMessage, ms_strdup(argv[12])); - linphone_chat_message_set_content_type(newMessage, argv[13]); - linphone_chat_message_set_is_secured(newMessage, (bool_t)atoi(argv[14])); + Address peer(peerAddress.asString()); + if (atoi(argv[3]) == ChatMessage::Direction::Incoming) { + message->getPrivate()->setDirection(ChatMessage::Direction::Incoming); + message->setFromAddress(peer); + } else { + message->getPrivate()->setDirection(ChatMessage::Direction::Outgoing); + message->setToAddress(peer); + } + + message->getPrivate()->setTime((time_t)atol(argv[9])); + message->getPrivate()->setState((ChatMessage::State)atoi(argv[7])); + message->getPrivate()->setStorageId(storageId); + if (argv[8]) { + message->setExternalBodyUrl(argv[8]); + } + if (argv[10]) { + message->setAppdata(argv[10]); + } + message->setId(argv[12]); + message->setIsSecured((bool)atoi(argv[14])); if (argv[11]) { int id = atoi(argv[11]); if (id >= 0) - linphone_chat_message_fetch_content_from_database(core->db, newMessage, id); + linphone_chat_message_fetch_content_from_database(core->db, L_GET_C_BACK_PTR(message), id); } /* Fix content type for old messages that were stored without it */ + /* To keep ? if (!linphone_chat_message_get_content_type(newMessage)) { if (linphone_chat_message_get_file_transfer_information(newMessage)) { linphone_chat_message_set_content_type(newMessage, ms_strdup("application/vnd.gsma.rcs-ft-http+xml")); @@ -308,33 +314,28 @@ int ChatRoomPrivate::createChatMessageFromDb (int argc, char **argv, char **colN } else { linphone_chat_message_set_content_type(newMessage, ms_strdup("text/plain")); } - } + }*/ /* Add the new message to the weak messages list. */ - addWeakMessage(newMessage); + addWeakMessage(message); } - messages.push_front(newMessage); + messages.push_front(message); return 0; } -void ChatRoomPrivate::onWeakMessageDestroyed (LinphoneChatMessage *messageBeingDestroyed) { - auto iter = find(weakMessages.begin(), weakMessages.end(), messageBeingDestroyed); - if (iter != transientMessages.end()) - weakMessages.erase(iter); -} - -LinphoneChatMessage *ChatRoomPrivate::getTransientMessage (unsigned int storageId) const { +shared_ptr ChatRoomPrivate::getTransientMessage (unsigned int storageId) const { for (auto &message : transientMessages) { - if (linphone_chat_message_get_storage_id(message) == storageId) - return linphone_chat_message_ref(message); + if (message->getPrivate()->getStorageId() == storageId) + return message; } return nullptr; } -LinphoneChatMessage *ChatRoomPrivate::getWeakMessage (unsigned int storageId) const { +std::shared_ptr ChatRoomPrivate::getWeakMessage (unsigned int storageId) const { for (auto &message : weakMessages) { - if (linphone_chat_message_get_storage_id(message) == storageId) - return linphone_chat_message_ref(message); + shared_ptr msg(message); + if (msg->getPrivate()->getStorageId() == storageId) + return msg; } return nullptr; } @@ -358,30 +359,21 @@ void ChatRoomPrivate::sqlRequestMessage (sqlite3 *db, const string &stmt) { } } -list ChatRoomPrivate::findMessages (const string &messageId) { +list > ChatRoomPrivate::findMessages (const string &messageId) { if (!core->db) - return list(); + return list >(); string peer = peerAddress.asStringUriOnly(); char *buf = sqlite3_mprintf("SELECT * FROM history WHERE remoteContact = %Q AND messageId = %Q", peer.c_str(), messageId.c_str()); messages.clear(); sqlRequestMessage(core->db, buf); sqlite3_free(buf); - list result = messages; + list > result = messages; messages.clear(); return result; } -/** - * TODO: Should be handled directly by the LinphoneChatMessage object! - */ -void ChatRoomPrivate::storeOrUpdateMessage (LinphoneChatMessage *msg) { - if (linphone_chat_message_get_storage_id(msg) != 0) { - /* The message has already been stored (probably because of file transfer), update it */ - linphone_chat_message_store_update(msg); - } else { - /* Store the new message */ - linphone_chat_message_store(msg); - } +void ChatRoomPrivate::storeOrUpdateMessage (shared_ptr msg) { + msg->store(); } // ----------------------------------------------------------------------------- @@ -391,34 +383,32 @@ LinphoneReason ChatRoomPrivate::messageReceived (SalOp *op, const SalMessage *sa bool increaseMsgCount = true; LinphoneReason reason = LinphoneReasonNone; - LinphoneChatMessage *msg; + shared_ptr msg; /* Check if this is a duplicate message */ - if ((msg = q->findMessageWithDirection(op->get_call_id(), LinphoneChatMessageIncoming))) { + if ((msg = q->findMessageWithDirection(op->get_call_id(), ChatMessage::Direction::Incoming))) { reason = core->chat_deny_code; - if (msg) - linphone_chat_message_unref(msg); return reason; } - msg = q->createMessage(salMsg->text ? salMsg->text : ""); - linphone_chat_message_set_content_type(msg, salMsg->content_type); - LinphoneAddress *peer = linphone_address_new(peerAddress.asString().c_str()); - linphone_chat_message_set_from_address(msg, peer); - linphone_address_unref(peer); + msg = q->createMessage(); - LinphoneAddress *to = op->get_to() ? linphone_address_new(op->get_to()) : linphone_address_new(linphone_core_get_identity(core)); - linphone_chat_message_set_to_address(msg, to); - linphone_chat_message_set_time(msg, salMsg->time); - linphone_chat_message_set_state(msg, LinphoneChatMessageStateDelivered); - linphone_chat_message_set_incoming(msg); - linphone_chat_message_set_message_id(msg, ms_strdup(op->get_call_id())); + shared_ptr content = make_shared(); + content->setContentType(salMsg->content_type); + content->setBody(salMsg->text ? salMsg->text : ""); + msg->addContent(content); + + msg->setToAddress( op->get_to() ? op->get_to() : linphone_core_get_identity(core)); + msg->getPrivate()->setTime(salMsg->time); + msg->getPrivate()->setState(ChatMessage::State::Delivered); + msg->getPrivate()->setDirection(ChatMessage::Direction::Incoming); + msg->setId(op->get_call_id()); const SalCustomHeader *ch = op->get_recv_custom_header(); if (ch) - linphone_chat_message_set_sal_custom_headers(msg, sal_custom_header_clone(ch)); + msg->getPrivate()->setSalCustomHeaders(sal_custom_header_clone(ch)); if (salMsg->url) - linphone_chat_message_set_external_body_url(msg, salMsg->url); + msg->setExternalBodyUrl(salMsg->url); int retval = -1; LinphoneImEncryptionEngine *imee = core->im_encryption_engine; @@ -426,14 +416,14 @@ LinphoneReason ChatRoomPrivate::messageReceived (SalOp *op, const SalMessage *sa LinphoneImEncryptionEngineCbs *imeeCbs = linphone_im_encryption_engine_get_callbacks(imee); LinphoneImEncryptionEngineCbsIncomingMessageCb cbProcessIncomingMessage = linphone_im_encryption_engine_cbs_get_process_incoming_message(imeeCbs); if (cbProcessIncomingMessage) { - retval = cbProcessIncomingMessage(imee, L_GET_C_BACK_PTR(q), msg); + retval = cbProcessIncomingMessage(imee, L_GET_C_BACK_PTR(q), L_GET_C_BACK_PTR(msg)); if (retval == 0) { - linphone_chat_message_set_is_secured(msg, TRUE); + msg->setIsSecured(true); } else if (retval > 0) { /* Unable to decrypt message */ notifyUndecryptableMessageReceived(msg); reason = linphone_error_code_to_reason(retval); - linphone_chat_message_send_delivery_notification(msg, reason); + msg->sendDeliveryNotification(reason); /* Return LinphoneReasonNone to avoid flexisip resending us a message we can't decrypt */ reason = LinphoneReasonNone; goto end; @@ -441,36 +431,36 @@ LinphoneReason ChatRoomPrivate::messageReceived (SalOp *op, const SalMessage *sa } } - if ((retval <= 0) && (linphone_core_is_content_type_supported(core, linphone_chat_message_get_content_type(msg)) == FALSE)) { + if ((retval <= 0) && (linphone_core_is_content_type_supported(core, msg->getPrivate()->getContentType().c_str()) == FALSE)) { retval = 415; - lError() << "Unsupported MESSAGE (content-type " << linphone_chat_message_get_content_type(msg) << " not recognized)"; + lError() << "Unsupported MESSAGE (content-type " << msg->getPrivate()->getContentType() << " not recognized)"; } if (retval > 0) { reason = linphone_error_code_to_reason(retval); - linphone_chat_message_send_delivery_notification(msg, reason); + msg->sendDeliveryNotification(reason); goto end; } - if (ContentType::isFileTransfer(linphone_chat_message_get_content_type(msg))) { - create_file_transfer_information_from_vnd_gsma_rcs_ft_http_xml(msg); - linphone_chat_message_set_to_be_stored(msg, TRUE); - } else if (ContentType::isImIsComposing(linphone_chat_message_get_content_type(msg))) { - isComposingReceived(linphone_chat_message_get_text(msg)); - linphone_chat_message_set_to_be_stored(msg, FALSE); + if (ContentType::isFileTransfer(msg->getPrivate()->getContentType())) { + create_file_transfer_information_from_vnd_gsma_rcs_ft_http_xml(L_GET_C_BACK_PTR(msg)); + msg->setIsToBeStored(true); + } else if (ContentType::isImIsComposing(msg->getPrivate()->getContentType())) { + isComposingReceived(msg->getPrivate()->getText()); + msg->setIsToBeStored(false); increaseMsgCount = FALSE; if (lp_config_get_int(core->config, "sip", "deliver_imdn", 0) != 1) { goto end; } - } else if (ContentType::isImdn(linphone_chat_message_get_content_type(msg))) { - imdnReceived(linphone_chat_message_get_text(msg)); - linphone_chat_message_set_to_be_stored(msg, FALSE); + } else if (ContentType::isImdn(msg->getPrivate()->getContentType())) { + imdnReceived(msg->getPrivate()->getText()); + msg->setIsToBeStored(false); increaseMsgCount = FALSE; if (lp_config_get_int(core->config, "sip", "deliver_imdn", 0) != 1) { goto end; } - } else if (ContentType::isText(linphone_chat_message_get_content_type(msg))) { - linphone_chat_message_set_to_be_stored(msg, TRUE); + } else if (ContentType::isText(msg->getPrivate()->getContentType())) { + msg->setIsToBeStored(true); } if (increaseMsgCount) { @@ -486,27 +476,25 @@ LinphoneReason ChatRoomPrivate::messageReceived (SalOp *op, const SalMessage *sa chatMessageReceived(msg); - if (linphone_chat_message_get_to_be_stored(msg)) { - linphone_chat_message_store(msg); + if (msg->isToBeStored()) { + msg->store(); } pendingMessage = nullptr; end: - if (msg) - linphone_chat_message_unref(msg); return reason; } // ----------------------------------------------------------------------------- -void ChatRoomPrivate::chatMessageReceived (LinphoneChatMessage *msg) { +void ChatRoomPrivate::chatMessageReceived (shared_ptr msg) { L_Q(); - if (!ContentType::isImdn(linphone_chat_message_get_content_type(msg)) && !ContentType::isImIsComposing(linphone_chat_message_get_content_type(msg))) { + if (!ContentType::isImdn(msg->getPrivate()->getContentType()) && !ContentType::isImIsComposing(msg->getPrivate()->getContentType())) { notifyChatMessageReceived(msg); remoteIsComposing = false; linphone_core_notify_is_composing_received(core, L_GET_C_BACK_PTR(q)); - linphone_chat_message_send_delivery_notification(msg, LinphoneReasonNone); + msg->sendDeliveryNotification(LinphoneReasonNone); } } @@ -521,18 +509,18 @@ void ChatRoomPrivate::isComposingReceived (const string &text) { // ----------------------------------------------------------------------------- -void ChatRoomPrivate::notifyChatMessageReceived (LinphoneChatMessage *msg) { +void ChatRoomPrivate::notifyChatMessageReceived (shared_ptr msg) { L_Q(); LinphoneChatRoom *cr = L_GET_C_BACK_PTR(q); - if (linphone_chat_message_get_text(msg)) { + if (!msg->getPrivate()->getText().empty()) { /* Legacy API */ - linphone_core_notify_text_message_received(core, cr, linphone_chat_message_get_from_address(msg), linphone_chat_message_get_text(msg)); + linphone_core_notify_text_message_received(core, cr, L_GET_C_BACK_PTR(&msg->getFromAddress()), msg->getPrivate()->getText().c_str()); } LinphoneChatRoomCbs *cbs = linphone_chat_room_get_callbacks(cr); LinphoneChatRoomCbsMessageReceivedCb cb = linphone_chat_room_cbs_get_message_received(cbs); if (cb) - cb(cr, msg); - linphone_core_notify_message_received(core, cr, msg); + cb(cr, L_GET_C_BACK_PTR(msg)); + linphone_core_notify_message_received(core, cr, L_GET_C_BACK_PTR(msg)); } void ChatRoomPrivate::notifyStateChanged () { @@ -544,14 +532,14 @@ void ChatRoomPrivate::notifyStateChanged () { cb(cr, (LinphoneChatRoomState)state); } -void ChatRoomPrivate::notifyUndecryptableMessageReceived (LinphoneChatMessage *msg) { +void ChatRoomPrivate::notifyUndecryptableMessageReceived (shared_ptr msg) { L_Q(); LinphoneChatRoom *cr = L_GET_C_BACK_PTR(q); LinphoneChatRoomCbs *cbs = linphone_chat_room_get_callbacks(cr); LinphoneChatRoomCbsUndecryptableMessageReceivedCb cb = linphone_chat_room_cbs_get_undecryptable_message_received(cbs); if (cb) - cb(cr, msg); - linphone_core_notify_message_received_unable_decrypt(core, cr, msg); + cb(cr, L_GET_C_BACK_PTR(msg)); + linphone_core_notify_message_received_unable_decrypt(core, cr, L_GET_C_BACK_PTR(msg)); } // ----------------------------------------------------------------------------- @@ -589,30 +577,34 @@ void ChatRoom::compose () { d->isComposingHandler.startIdleTimer(); } -LinphoneChatMessage *ChatRoom::createFileTransferMessage (const LinphoneContent *initialContent) { +shared_ptr ChatRoom::createFileTransferMessage (const LinphoneContent *initialContent) { L_D(); - shared_ptr chatMessage = make_shared(static_pointer_cast(shared_from_this())); + shared_ptr chatMessage = createMessage(); - chatMessage->getPrivate()->setTime(ms_time(0)); chatMessage->getPrivate()->setDirection(ChatMessage::Direction::Outgoing); chatMessage->getPrivate()->setFileTransferInformation(linphone_content_copy(initialContent)); - chatMessage->setToAddress(make_shared
(d->peerAddress.asString().c_str())); - chatMessage->setFromAddress(make_shared
(linphone_core_get_identity(d->core))); + chatMessage->setToAddress(d->peerAddress); + chatMessage->setFromAddress(linphone_core_get_identity(d->core)); - LinphoneChatMessage *msg = chatMessage->getBackPtr(); - return msg; + return chatMessage; } -LinphoneChatMessage *ChatRoom::createMessage (const string &message) { +shared_ptr ChatRoom::createMessage (const string &message) { + shared_ptr chatMessage = createMessage(); + + shared_ptr content = make_shared(); + content->setContentType("text/plain"); + content->setBody(message); + chatMessage->addContent(content); + + return chatMessage; +} + +shared_ptr ChatRoom::createMessage () { shared_ptr chatMessage = make_shared(static_pointer_cast(shared_from_this())); - chatMessage->getPrivate()->setTime(ms_time(0)); - chatMessage->getPrivate()->setContentType("text/plain"); - chatMessage->getPrivate()->setText(message); - - LinphoneChatMessage *msg = chatMessage->getBackPtr(); - return msg; + return chatMessage; } void ChatRoom::deleteHistory () { @@ -625,10 +617,10 @@ void ChatRoom::deleteHistory () { if (d->unreadCount > 0) d->unreadCount = 0; } -void ChatRoom::deleteMessage (LinphoneChatMessage *msg) { +void ChatRoom::deleteMessage (shared_ptr msg) { L_D(); if (!d->core->db) return; - char *buf = sqlite3_mprintf("DELETE FROM history WHERE id = %u;", linphone_chat_message_get_storage_id(msg)); + char *buf = sqlite3_mprintf("DELETE FROM history WHERE id = %u;", msg->getPrivate()->getStorageId()); d->sqlRequest(d->core->db, buf); sqlite3_free(buf); @@ -637,38 +629,30 @@ void ChatRoom::deleteMessage (LinphoneChatMessage *msg) { d->unreadCount = -1; } -LinphoneChatMessage *ChatRoom::findMessage (const string &messageId) { +shared_ptr ChatRoom::findMessage (const string &messageId) { L_D(); - LinphoneChatMessage *cm = nullptr; - list l = d->findMessages(messageId); + shared_ptr cm = nullptr; + list > l = d->findMessages(messageId); if (!l.empty()) { cm = l.front(); - linphone_chat_message_ref(cm); - for (auto &message : l) - linphone_chat_message_unref(message); } return cm; } -LinphoneChatMessage * ChatRoom::findMessageWithDirection (const string &messageId, LinphoneChatMessageDir direction) { +shared_ptr ChatRoom::findMessageWithDirection (const string &messageId, ChatMessage::Direction direction) { L_D(); - LinphoneChatMessage *ret = nullptr; - list l = d->findMessages(messageId); + shared_ptr ret = nullptr; + list > l = d->findMessages(messageId); for (auto &message : l) { - if (linphone_chat_message_get_direction(message) == direction) { - linphone_chat_message_ref(message); + if (message->getDirection() == direction) { ret = message; break; } } - if (!l.empty()) { - for (auto &message : l) - linphone_chat_message_unref(message); - } return ret; } -list ChatRoom::getHistory (int nbMessages) { +list > ChatRoom::getHistory (int nbMessages) { return getHistoryRange(0, nbMessages - 1); } @@ -677,9 +661,9 @@ int ChatRoom::getHistorySize () { return d->getMessagesCount(false); } -list ChatRoom::getHistoryRange (int startm, int endm) { +list > ChatRoom::getHistoryRange (int startm, int endm) { L_D(); - if (!d->core->db) return list(); + if (!d->core->db) return list >(); string peer = d->peerAddress.asStringUriOnly(); d->messages.clear(); @@ -717,18 +701,16 @@ list ChatRoom::getHistoryRange (int startm, int endm) { if (!d->messages.empty()) { /* Fill local addr with core identity instead of per message */ - LinphoneAddress *localAddr = linphone_address_new(linphone_core_get_identity(d->core)); for (auto &message : d->messages) { - if (linphone_chat_message_is_outgoing(message)) { - linphone_chat_message_set_from_address(message, linphone_address_ref(localAddr)); + if (message->isOutgoing()) { + message->setFromAddress(linphone_core_get_identity(d->core)); } else { - linphone_chat_message_set_to_address(message, linphone_address_ref(localAddr)); + message->setToAddress(linphone_core_get_identity(d->core)); } } - linphone_address_unref(localAddr); } - list result = d->messages; + list > result = d->messages; d->messages.clear(); return result; } @@ -752,61 +734,60 @@ void ChatRoom::markAsRead () { if (getUnreadMessagesCount() == 0) return; string peer = d->peerAddress.asStringUriOnly(); - char *buf = sqlite3_mprintf("SELECT * FROM history WHERE remoteContact = %Q AND direction = %i AND status != %i", peer.c_str(), LinphoneChatMessageIncoming, LinphoneChatMessageStateDisplayed); + char *buf = sqlite3_mprintf("SELECT * FROM history WHERE remoteContact = %Q AND direction = %i AND status != %i", peer.c_str(), ChatMessage::Direction::Incoming, ChatMessage::State::Displayed); d->sqlRequestMessage(d->core->db, buf); sqlite3_free(buf); for (auto &message : d->messages) { - linphone_chat_message_send_display_notification(message); - linphone_chat_message_unref(message); + message->sendDisplayNotification(); } d->messages.clear(); - buf = sqlite3_mprintf("UPDATE history SET status=%i WHERE remoteContact=%Q AND direction=%i;", LinphoneChatMessageStateDisplayed, peer.c_str(), LinphoneChatMessageIncoming); + buf = sqlite3_mprintf("UPDATE history SET status=%i WHERE remoteContact=%Q AND direction=%i;", ChatMessage::State::Displayed, peer.c_str(), ChatMessage::Direction::Incoming); d->sqlRequest(d->core->db, buf); sqlite3_free(buf); if (d->pendingMessage) { - linphone_chat_message_set_state(d->pendingMessage, LinphoneChatMessageStateDisplayed); - linphone_chat_message_send_display_notification(d->pendingMessage); + d->pendingMessage->getPrivate()->setState(ChatMessage::State::Displayed); + d->pendingMessage->sendDisplayNotification(); } d->unreadCount = 0; } -void ChatRoom::sendMessage (LinphoneChatMessage *msg) { +void ChatRoom::sendMessage (shared_ptr msg) { L_D(); - linphone_chat_message_set_outgoing(msg); + msg->getPrivate()->setDirection(ChatMessage::Direction::Outgoing); /* Check if we shall upload a file to a server */ - if (linphone_chat_message_get_file_transfer_information(msg) && !linphone_chat_message_get_content_type(msg)) { + if (msg->getPrivate()->getFileTransferInformation() && msg->getPrivate()->getContentType().empty()) { /* Open a transaction with the server and send an empty request(RCS5.1 section 3.5.4.8.3.1) */ - if (linphone_chat_room_upload_file(msg) == 0) { + if (msg->uploadFile() == 0) { /* Add to transient list only if message is going out */ d->addTransientMessage(msg); /* Store the message so that even if the upload is stopped, it can be done again */ d->storeOrUpdateMessage(msg); } else { - linphone_chat_message_unref(msg); return; } } else { - SalOp *op = linphone_chat_message_get_sal_op(msg); + SalOp *op = msg->getPrivate()->getSalOp(); LinphoneCall *call = nullptr; string identity; char *clearTextMessage = nullptr; char *clearTextContentType = nullptr; LinphoneAddress *peer = linphone_address_new(d->peerAddress.asString().c_str()); - if (linphone_chat_message_get_text(msg)) { - clearTextMessage = ms_strdup(linphone_chat_message_get_text(msg)); + if (!msg->getPrivate()->getText().empty()) { + clearTextMessage = ms_strdup(msg->getPrivate()->getText().c_str()); } - if (linphone_chat_message_get_content_type(msg)) { - clearTextContentType = ms_strdup(linphone_chat_message_get_content_type(msg)); + if (!msg->getPrivate()->getContentType().empty()) { + clearTextContentType = ms_strdup(msg->getPrivate()->getContentType().c_str()); } /* Add to transient list */ d->addTransientMessage(msg); - linphone_chat_message_set_time(msg, ms_time(0)); + msg->getPrivate()->setTime(ms_time(0)); + if (lp_config_get_int(d->core->config, "sip", "chat_use_call_dialogs", 0) != 0) { call = linphone_core_get_call_by_remote_address(d->core, d->peerAddress.asString().c_str()); if (call) { @@ -828,7 +809,7 @@ void ChatRoom::sendMessage (LinphoneChatMessage *msg) { identity = linphone_core_get_primary_contact(d->core); } } - linphone_chat_message_set_from_address(msg, linphone_address_new(identity.c_str())); + msg->setFromAddress(identity); int retval = -1; LinphoneImEncryptionEngine *imee = d->core->im_encryption_engine; @@ -836,55 +817,54 @@ void ChatRoom::sendMessage (LinphoneChatMessage *msg) { LinphoneImEncryptionEngineCbs *imeeCbs = linphone_im_encryption_engine_get_callbacks(imee); LinphoneImEncryptionEngineCbsOutgoingMessageCb cbProcessOutgoingMessage = linphone_im_encryption_engine_cbs_get_process_outgoing_message(imeeCbs); if (cbProcessOutgoingMessage) { - retval = cbProcessOutgoingMessage(imee, L_GET_C_BACK_PTR(this), msg); + retval = cbProcessOutgoingMessage(imee, L_GET_C_BACK_PTR(this), L_GET_C_BACK_PTR(msg)); if (retval == 0) { - linphone_chat_message_set_is_secured(msg, TRUE); + msg->setIsSecured(true); } } } if (!op) { /* Sending out of call */ - linphone_chat_message_set_sal_op(msg, op = new SalMessageOp(d->core->sal)); + msg->getPrivate()->setSalOp(op = new SalMessageOp(d->core->sal)); linphone_configure_op( - d->core, op, peer, linphone_chat_message_get_sal_custom_headers(msg), + d->core, op, peer, msg->getPrivate()->getSalCustomHeaders(), !!lp_config_get_int(d->core->config, "sip", "chat_msg_with_contact", 0) ); - op->set_user_pointer(msg); /* If out of call, directly store msg */ + op->set_user_pointer(L_GET_C_BACK_PTR(msg)); /* If out of call, directly store msg */ } if (retval > 0) { sal_error_info_set((SalErrorInfo *)op->get_error_info(), SalReasonNotAcceptable, "SIP", retval, "Unable to encrypt IM", nullptr); d->storeOrUpdateMessage(msg); - linphone_chat_message_update_state(msg, LinphoneChatMessageStateNotDelivered); - linphone_chat_message_unref(msg); + msg->updateState(ChatMessage::State::NotDelivered); linphone_address_unref(peer); return; } - if (linphone_chat_message_get_external_body_url(msg)) { - char *content_type = ms_strdup_printf("message/external-body; access-type=URL; URL=\"%s\"", linphone_chat_message_get_external_body_url(msg)); + if (!msg->getExternalBodyUrl().empty()) { + char *content_type = ms_strdup_printf("message/external-body; access-type=URL; URL=\"%s\"",msg->getExternalBodyUrl().empty()); auto msgOp = dynamic_cast(op); msgOp->send_message(identity.c_str(), d->peerAddress.asString().c_str(), content_type, nullptr, nullptr); ms_free(content_type); } else { auto msgOp = dynamic_cast(op); - if (linphone_chat_message_get_content_type(msg)) { - msgOp->send_message(identity.c_str(), d->peerAddress.asString().c_str(), linphone_chat_message_get_content_type(msg), linphone_chat_message_get_text(msg), d->peerAddress.asStringUriOnly().c_str()); + if (!msg->getPrivate()->getContentType().empty()) { + msgOp->send_message(identity.c_str(), d->peerAddress.asString().c_str(), msg->getPrivate()->getContentType().c_str(), msg->getPrivate()->getText().c_str(), d->peerAddress.asStringUriOnly().c_str()); } else { - msgOp->send_message(identity.c_str(), d->peerAddress.asString().c_str(), linphone_chat_message_get_text(msg)); + msgOp->send_message(identity.c_str(), d->peerAddress.asString().c_str(), msg->getPrivate()->getText().c_str()); } } - if (linphone_chat_message_get_text(msg) && clearTextMessage && strcmp(linphone_chat_message_get_text(msg), clearTextMessage) != 0) { + if (!msg->getPrivate()->getText().empty() && clearTextMessage && strcmp(msg->getPrivate()->getText().c_str(), clearTextMessage) != 0) { /* We replace the encrypted message by the original one so it can be correctly stored and displayed by the application */ - linphone_chat_message_set_text(msg, ms_strdup(clearTextMessage)); + msg->getPrivate()->setText(clearTextMessage); } - if (linphone_chat_message_get_content_type(msg) && clearTextContentType && (strcmp(linphone_chat_message_get_content_type(msg), clearTextContentType) != 0)) { + if (!msg->getPrivate()->getContentType().empty() && clearTextContentType && (strcmp(msg->getPrivate()->getContentType().c_str(), clearTextContentType) != 0)) { /* We replace the encrypted content type by the original one */ - linphone_chat_message_set_content_type(msg, ms_strdup(clearTextContentType)); + msg->getPrivate()->setContentType(clearTextContentType); } - linphone_chat_message_set_message_id(msg, ms_strdup(op->get_call_id())); /* must be known at that time */ + msg->setId(op->get_call_id()); /* must be known at that time */ d->storeOrUpdateMessage(msg); if (d->isComposing) @@ -903,15 +883,14 @@ void ChatRoom::sendMessage (LinphoneChatMessage *msg) { if (call && linphone_call_get_op(call) == op) { /* In this case, chat delivery status is not notified, so unrefing chat message right now */ /* Might be better fixed by delivering status, but too costly for now */ - linphone_chat_room_remove_transient_message(linphone_chat_message_get_chat_room(msg), msg); - linphone_chat_message_unref(msg); + d->removeTransientMessage(msg); return; } } /* If operation failed, we should not change message state */ - if (linphone_chat_message_is_outgoing(msg)) { - linphone_chat_message_set_state(msg, LinphoneChatMessageStateInProgress); + if (msg->isOutgoing()) { + msg->getPrivate()->setState(ChatMessage::State::InProgress); } } diff --git a/src/chat/chat-room.h b/src/chat/chat-room.h index debff026f..e9d2ea018 100644 --- a/src/chat/chat-room.h +++ b/src/chat/chat-room.h @@ -28,6 +28,8 @@ #include "object/object.h" #include "conference/conference-interface.h" +#include "chat-message.h" + #include "linphone/types.h" // ============================================================================= @@ -47,19 +49,20 @@ public: virtual ~ChatRoom () = default; void compose (); - LinphoneChatMessage *createFileTransferMessage (const LinphoneContent *initialContent); - LinphoneChatMessage *createMessage (const std::string &msg); + std::shared_ptr createFileTransferMessage (const LinphoneContent *initialContent); + std::shared_ptr createMessage (const std::string &msg); + std::shared_ptr createMessage (); void deleteHistory (); - void deleteMessage (LinphoneChatMessage *msg); - LinphoneChatMessage * findMessage (const std::string& messageId); - LinphoneChatMessage * findMessageWithDirection (const std::string &messageId, LinphoneChatMessageDir direction); - std::list getHistory (int nbMessages); + void deleteMessage (std::shared_ptr msg); + std::shared_ptr findMessage (const std::string& messageId); + std::shared_ptr findMessageWithDirection (const std::string &messageId, ChatMessage::Direction direction); + std::list > getHistory (int nbMessages); int getHistorySize (); - std::list getHistoryRange (int startm, int endm); + std::list > getHistoryRange (int startm, int endm); int getUnreadMessagesCount (); bool isRemoteComposing () const; void markAsRead (); - virtual void sendMessage (LinphoneChatMessage *msg); + virtual void sendMessage (std::shared_ptr msg); LinphoneCore *getCore () const; diff --git a/src/chat/imdn.cpp b/src/chat/imdn.cpp index e0c0696ca..b63e7199d 100644 --- a/src/chat/imdn.cpp +++ b/src/chat/imdn.cpp @@ -19,6 +19,8 @@ #include "logger/logger.h" #include "imdn.h" +#include "chat/chat-room.h" +#include "chat/chat-message.h" // ============================================================================= @@ -59,7 +61,7 @@ void Imdn::parse (ChatRoom &cr, xmlparsing_context_t *xmlCtx) { } if (messageIdStr && datetimeStr) { - LinphoneChatMessage *cm = cr.findMessageWithDirection(messageIdStr, LinphoneChatMessageOutgoing); + shared_ptr cm = cr.findMessageWithDirection(messageIdStr, ChatMessage::Direction::Outgoing); if (!cm) { lWarning() << "Received IMDN for unknown message " << messageIdStr; } else { @@ -73,9 +75,9 @@ void Imdn::parse (ChatRoom &cr, xmlparsing_context_t *xmlCtx) { xmlNodePtr node = deliveryStatusObject->nodesetval->nodeTab[0]; if (node->children && node->children->name) { if (strcmp((const char *)node->children->name, "delivered") == 0) { - linphone_chat_message_update_state(cm, LinphoneChatMessageStateDeliveredToUser); + cm->updateState(ChatMessage::State::DeliveredToUser); } else if (strcmp((const char *)node->children->name, "error") == 0) { - linphone_chat_message_update_state(cm, LinphoneChatMessageStateNotDelivered); + cm->updateState(ChatMessage::State::NotDelivered); } } } @@ -86,13 +88,12 @@ void Imdn::parse (ChatRoom &cr, xmlparsing_context_t *xmlCtx) { xmlNodePtr node = displayStatusObject->nodesetval->nodeTab[0]; if (node->children && node->children->name) { if (strcmp((const char *)node->children->name, "displayed") == 0) { - linphone_chat_message_update_state(cm, LinphoneChatMessageStateDisplayed); + cm->updateState(ChatMessage::State::Displayed); } } } xmlXPathFreeObject(displayStatusObject); } - linphone_chat_message_unref(cm); } } if (messageIdStr) diff --git a/src/chat/imdn.h b/src/chat/imdn.h index c4bb6d1a5..3a1f332c4 100644 --- a/src/chat/imdn.h +++ b/src/chat/imdn.h @@ -21,14 +21,14 @@ #include "linphone/utils/general.h" -#include "chat-room.h" - #include "private.h" // ============================================================================= LINPHONE_BEGIN_NAMESPACE +class ChatRoom; + class Imdn { public: static void parse (ChatRoom &cr, const std::string &content); diff --git a/src/chat/modifier/chat-message-modifier.h b/src/chat/modifier/chat-message-modifier.h index 1bd6d5a88..0f4071df8 100644 --- a/src/chat/modifier/chat-message-modifier.h +++ b/src/chat/modifier/chat-message-modifier.h @@ -21,6 +21,8 @@ #include "linphone/utils/general.h" +#include "private.h" + // ============================================================================= LINPHONE_BEGIN_NAMESPACE diff --git a/src/chat/modifier/cpim-chat-message-modifier.cpp b/src/chat/modifier/cpim-chat-message-modifier.cpp index dec8d2046..33c2dba62 100644 --- a/src/chat/modifier/cpim-chat-message-modifier.cpp +++ b/src/chat/modifier/cpim-chat-message-modifier.cpp @@ -16,12 +16,13 @@ * along with this program. If not, see . */ -#include "chat/chat-message-p.h" +#include "cpim-chat-message-modifier.h" + #include "chat/cpim/cpim.h" #include "content/content-type.h" #include "content/content.h" - -#include "cpim-chat-message-modifier.h" +#include "address/address.h" +#include "chat/chat-message-p.h" // ============================================================================= diff --git a/src/chat/modifier/multipart-chat-message-modifier.cpp b/src/chat/modifier/multipart-chat-message-modifier.cpp index f0e073cbb..c3c8299ca 100644 --- a/src/chat/modifier/multipart-chat-message-modifier.cpp +++ b/src/chat/modifier/multipart-chat-message-modifier.cpp @@ -16,8 +16,9 @@ * along with this program. If not, see . */ -#include "chat/chat-message-p.h" #include "multipart-chat-message-modifier.h" +#include "address/address.h" +#include "chat/chat-message-p.h" // ============================================================================= diff --git a/src/chat/real-time-text-chat-room-p.h b/src/chat/real-time-text-chat-room-p.h index 41a94f6af..5aaf502c2 100644 --- a/src/chat/real-time-text-chat-room-p.h +++ b/src/chat/real-time-text-chat-room-p.h @@ -43,7 +43,7 @@ public: public: LinphoneCall *call = nullptr; std::list receivedRttCharacters; - LinphoneChatMessage *pendingMessage = nullptr; + std::shared_ptr pendingMessage = nullptr; private: L_DECLARE_PUBLIC(RealTimeTextChatRoom); diff --git a/src/chat/real-time-text-chat-room.cpp b/src/chat/real-time-text-chat-room.cpp index 21b2656ba..0a4939735 100644 --- a/src/chat/real-time-text-chat-room.cpp +++ b/src/chat/real-time-text-chat-room.cpp @@ -21,6 +21,7 @@ #include "linphone/utils/utils.h" #include "real-time-text-chat-room-p.h" +#include "chat-message-p.h" #include "c-wrapper/c-wrapper.h" #include "logger/logger.h" @@ -40,8 +41,6 @@ RealTimeTextChatRoomPrivate::~RealTimeTextChatRoomPrivate () { for (auto &rttChars : receivedRttCharacters) bctbx_free(rttChars); } - if (pendingMessage) - linphone_chat_message_unref(pendingMessage); } // ----------------------------------------------------------------------------- @@ -67,16 +66,11 @@ void RealTimeTextChatRoomPrivate::realtimeTextReceived (uint32_t character, Linp if ((character == new_line) || (character == crlf) || (character == lf)) { /* End of message */ - lDebug() << "New line received, forge a message with content " << linphone_chat_message_get_text(pendingMessage); - LinphoneAddress *peer = linphone_address_new(peerAddress.asString().c_str()); - linphone_chat_message_set_from_address(pendingMessage, peer); - linphone_address_unref(peer); - linphone_chat_message_set_to_address(pendingMessage, linphone_call_get_dest_proxy(call) - ? linphone_address_clone(linphone_call_get_dest_proxy(call)->identity_address) - : linphone_address_new(linphone_core_get_identity(core))); - linphone_chat_message_set_time(pendingMessage, ms_time(0)); - linphone_chat_message_set_state(pendingMessage, LinphoneChatMessageStateDelivered); - linphone_chat_message_set_incoming(pendingMessage); + lDebug() << "New line received, forge a message with content " << pendingMessage->getPrivate()->getText().c_str(); + pendingMessage->setFromAddress(peerAddress); + pendingMessage->setToAddress(linphone_call_get_dest_proxy(call) ? linphone_address_as_string(linphone_call_get_dest_proxy(call)->identity_address) : linphone_core_get_identity(core)); + pendingMessage->getPrivate()->setState(ChatMessage::State::Delivered); + pendingMessage->getPrivate()->setDirection(ChatMessage::Direction::Incoming); if (lp_config_get_int(core->config, "misc", "store_rtt_messages", 1) == 1) storeOrUpdateMessage(pendingMessage); @@ -85,16 +79,15 @@ void RealTimeTextChatRoomPrivate::realtimeTextReceived (uint32_t character, Linp else unreadCount++; chatMessageReceived(pendingMessage); - linphone_chat_message_unref(pendingMessage); pendingMessage = nullptr; for (auto &rttChars : receivedRttCharacters) ms_free(rttChars); receivedRttCharacters.clear(); } else { char *value = Utils::utf8ToChar(character); - char *text = (char *)linphone_chat_message_get_text(pendingMessage); - linphone_chat_message_set_text(pendingMessage, ms_strcat_printf(text, value)); - lDebug() << "Received RTT character: " << value << " (" << character << "), pending text is " << linphone_chat_message_get_text(pendingMessage); + char *text = (char *)pendingMessage->getPrivate()->getText().c_str(); + pendingMessage->getPrivate()->setText(ms_strcat_printf(text, value)); + lDebug() << "Received RTT character: " << value << " (" << character << "), pending text is " << pendingMessage->getPrivate()->getText(); delete value; } } @@ -106,12 +99,11 @@ RealTimeTextChatRoom::RealTimeTextChatRoom (LinphoneCore *core, const Address &p // ----------------------------------------------------------------------------- -void RealTimeTextChatRoom::sendMessage (LinphoneChatMessage *msg) { +void RealTimeTextChatRoom::sendMessage (std::shared_ptr msg) { L_D(); if (d->call && linphone_call_params_realtime_text_enabled(linphone_call_get_current_params(d->call))) { uint32_t new_line = 0x2028; - linphone_chat_message_put_char(msg, new_line); - linphone_chat_message_unref(msg); + msg->putCharacter(new_line); } } diff --git a/src/chat/real-time-text-chat-room.h b/src/chat/real-time-text-chat-room.h index 2f3e3f40d..524296521 100644 --- a/src/chat/real-time-text-chat-room.h +++ b/src/chat/real-time-text-chat-room.h @@ -37,7 +37,7 @@ public: RealTimeTextChatRoom (LinphoneCore *core, const Address &peerAddress); virtual ~RealTimeTextChatRoom () = default; - void sendMessage (LinphoneChatMessage *msg) override; + void sendMessage (std::shared_ptr msg) override; uint32_t getChar () const; LinphoneCall *getCall () const;