From b9eaf0a7e9d35487dfb3bd83fde1fe106d8a8dba Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Tue, 6 Mar 2018 12:20:51 +0100 Subject: [PATCH] Prevent ChatRoom C++ objects from being leaked. --- coreapi/callbacks.c | 10 +- coreapi/linphonecore.c | 3 +- coreapi/private_functions.h | 1 - src/c-wrapper/api/c-chat-room.cpp | 48 +-- .../basic-to-client-group-chat-room.cpp | 2 +- src/chat/chat-room/chat-room-p.h | 6 + src/chat/chat-room/chat-room.cpp | 26 +- src/chat/chat-room/chat-room.h | 2 + src/chat/chat-room/client-group-chat-room.cpp | 12 +- src/chat/chat-room/client-group-chat-room.h | 1 + .../client-group-to-basic-chat-room.cpp | 17 +- src/chat/chat-room/proxy-chat-room-p.h | 4 +- src/chat/chat-room/proxy-chat-room.cpp | 97 +----- src/chat/chat-room/proxy-chat-room.h | 2 + .../chat-room/real-time-text-chat-room.cpp | 2 +- src/conference/conference-interface.h | 2 +- src/conference/session/call-session.cpp | 2 + src/core/core-chat-room.cpp | 82 ++++-- src/core/core-p.h | 6 +- src/core/core.cpp | 4 + src/core/core.h | 3 +- src/sal/refer-op.cpp | 2 + tester/group_chat_tester.c | 275 ++++++++++-------- 23 files changed, 294 insertions(+), 315 deletions(-) diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index 535883882..2faa1cef6 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -748,10 +748,12 @@ static void refer_received(SalOp *op, const SalAddress *refer_to){ return; } } else { - LinphoneChatRoom *cr = L_GET_C_BACK_PTR(L_GET_CPP_PTR_FROM_C_OBJECT(lc)->findChatRoom(ChatRoomId(addr, IdentityAddress(op->get_to())))); - if (!cr) - cr = _linphone_client_group_chat_room_new(lc, addr.asString().c_str(), nullptr, FALSE); - L_GET_CPP_PTR_FROM_C_OBJECT(cr)->join(); + shared_ptr chatRoom = L_GET_CPP_PTR_FROM_C_OBJECT(lc)->findChatRoom( + ChatRoomId(addr, IdentityAddress(op->get_to())) + ); + if (!chatRoom) + chatRoom = L_GET_PRIVATE_FROM_C_OBJECT(lc)->createClientGroupChatRoom("", addr.asString(), false); + chatRoom->join(); static_cast(op)->reply(SalReasonNone); return; } diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 2027b4101..a46771707 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -2145,6 +2145,7 @@ static void linphone_core_internal_notify_received(LinphoneCore *lc, LinphoneEve while ((part = linphone_content_get_part(body, i))) { i++; L_GET_PRIVATE(cgcr)->notifyReceived(linphone_content_get_string_buffer(part)); + linphone_content_unref(part); } } else L_GET_PRIVATE(cgcr)->notifyReceived(linphone_content_get_string_buffer(body)); @@ -3449,7 +3450,7 @@ LinphoneProxyConfig * linphone_core_lookup_known_proxy(LinphoneCore *lc, const L LinphoneProxyConfig *default_cfg=lc->default_proxy; if (linphone_address_get_domain(uri) == NULL) { - ms_message("cannot seach for proxy for uri [%p] if no domain set. returning default",uri); + ms_message("Cannot look for proxy for uri [%p] that has no domain set, returning default", uri); return default_cfg; } /*return default proxy if it is matching the destination uri*/ diff --git a/coreapi/private_functions.h b/coreapi/private_functions.h index 6ecc2f094..9ab4e447f 100644 --- a/coreapi/private_functions.h +++ b/coreapi/private_functions.h @@ -275,7 +275,6 @@ void _linphone_proxy_config_unregister(LinphoneProxyConfig *obj); void _linphone_proxy_config_release_ops(LinphoneProxyConfig *obj); /*chat*/ -LinphoneChatRoom *_linphone_client_group_chat_room_new (LinphoneCore *core, const char *uri, const char *subject, bool_t fallback); LinphoneChatRoom *_linphone_server_group_chat_room_new (LinphoneCore *core, LinphonePrivate::SalCallOp *op); void linphone_chat_room_set_call(LinphoneChatRoom *cr, LinphoneCall *call); LinphoneChatRoomCbs * _linphone_chat_room_cbs_new (void); diff --git a/src/c-wrapper/api/c-chat-room.cpp b/src/c-wrapper/api/c-chat-room.cpp index c0bdaeae7..817a82bbd 100644 --- a/src/c-wrapper/api/c-chat-room.cpp +++ b/src/c-wrapper/api/c-chat-room.cpp @@ -29,9 +29,6 @@ #include "c-wrapper/c-wrapper.h" #include "call/call.h" #include "chat/chat-message/chat-message-p.h" -#include "chat/chat-room/basic-chat-room.h" -#include "chat/chat-room/client-group-chat-room-p.h" -#include "chat/chat-room/client-group-to-basic-chat-room.h" #include "chat/chat-room/real-time-text-chat-room-p.h" #include "chat/chat-room/server-group-chat-room-p.h" #include "conference/participant.h" @@ -435,7 +432,7 @@ const bctbx_list_t *linphone_chat_room_get_callbacks_list(const LinphoneChatRoom if (cb) \ cb(__VA_ARGS__); \ } \ - bctbx_free(callbacksCopy); + bctbx_list_free(callbacksCopy); void _linphone_chat_room_notify_is_composing_received(LinphoneChatRoom *cr, const LinphoneAddress *remoteAddr, bool_t isComposing) { NOTIFY_IF_EXIST(IsComposingReceived, is_composing_received, cr, remoteAddr, isComposing) @@ -526,49 +523,6 @@ void linphone_chat_room_set_user_data (LinphoneChatRoom *cr, void *ud) { // Constructor and destructor functions. // ============================================================================= -LinphoneChatRoom *_linphone_client_group_chat_room_new (LinphoneCore *core, const char *uri, const char *subject, bool_t fallback) { - string from; - LinphoneProxyConfig *proxy = nullptr; - if (uri) { - LinphoneAddress *addr = linphone_address_new(uri); - proxy = linphone_core_lookup_known_proxy(core, addr); - linphone_address_unref(addr); - } else { - proxy = linphone_core_get_default_proxy_config(core); - if (!proxy) - return nullptr; - uri = linphone_proxy_config_get_conference_factory_uri(proxy); - if (!uri) - return nullptr; - } - if (proxy) { - const LinphoneAddress *contactAddr = linphone_proxy_config_get_contact(proxy); - if (contactAddr) { - char *cFrom = linphone_address_as_string(contactAddr); - from = string(cFrom); - bctbx_free(cFrom); - } else { - from = L_GET_CPP_PTR_FROM_C_OBJECT(linphone_proxy_config_get_identity_address(proxy))->asString(); - } - } - if (from.empty()) - from = linphone_core_get_primary_contact(core); - LinphonePrivate::IdentityAddress me(from); - shared_ptr cgcr = make_shared( - L_GET_CPP_PTR_FROM_C_OBJECT(core), L_C_TO_STRING(uri), me, L_C_TO_STRING(subject)); - LinphoneChatRoom *cr = L_INIT(ChatRoom); - if (fallback) { - // Create a ClientGroupToBasicChatRoom to handle fallback from ClientGroupChatRoom to BasicGroupChatRoom if - // only one participant is invited and that it does not support group chat - L_SET_CPP_PTR_FROM_C_OBJECT(cr, make_shared(cgcr)); - L_GET_PRIVATE(cgcr)->setCallSessionListener(L_GET_PRIVATE_FROM_C_OBJECT(cr)); - L_GET_PRIVATE(cgcr)->setChatRoomListener(L_GET_PRIVATE_FROM_C_OBJECT(cr)); - } else - L_SET_CPP_PTR_FROM_C_OBJECT(cr, cgcr); - L_GET_PRIVATE_FROM_C_OBJECT(cr)->setState(LinphonePrivate::ChatRoom::State::Instantiated); - return cr; -} - LinphoneChatRoom *_linphone_server_group_chat_room_new (LinphoneCore *core, LinphonePrivate::SalCallOp *op) { LinphoneChatRoom *cr = L_INIT(ChatRoom); L_SET_CPP_PTR_FROM_C_OBJECT(cr, make_shared( diff --git a/src/chat/chat-room/basic-to-client-group-chat-room.cpp b/src/chat/chat-room/basic-to-client-group-chat-room.cpp index f350d8690..67f9ea2fc 100644 --- a/src/chat/chat-room/basic-to-client-group-chat-room.cpp +++ b/src/chat/chat-room/basic-to-client-group-chat-room.cpp @@ -78,7 +78,7 @@ public: } migrationRealTime = currentRealTime; clientGroupChatRoom = static_pointer_cast( - chatRoom->getCore()->getPrivate()->createClientGroupChatRoom(chatRoom->getSubject(), false) + chatRoom->getCore()->getPrivate()->createClientGroupChatRoom(chatRoom->getSubject(), "", false) ); clientGroupChatRoom->getPrivate()->setCallSessionListener(this); clientGroupChatRoom->getPrivate()->setChatRoomListener(this); diff --git a/src/chat/chat-room/chat-room-p.h b/src/chat/chat-room/chat-room-p.h index 2deeec842..4d177d845 100644 --- a/src/chat/chat-room/chat-room-p.h +++ b/src/chat/chat-room/chat-room-p.h @@ -33,6 +33,8 @@ LINPHONE_BEGIN_NAMESPACE class ChatRoomPrivate : public AbstractChatRoomPrivate, public IsComposingListener { public: + inline void setProxyChatRoom (AbstractChatRoom *value) { proxyChatRoom = value; } + inline void setCreationTime (time_t creationTime) override { this->creationTime = creationTime; } @@ -67,12 +69,16 @@ public: void onIsComposingStateChanged (bool isComposing) override; void onIsRemoteComposingStateChanged (const Address &remoteAddress, bool isComposing) override; + LinphoneChatRoom *getCChatRoom () const; + std::list remoteIsComposing; std::list> transientEvents; ChatRoomId chatRoomId; private: + AbstractChatRoom *proxyChatRoom = nullptr; + ChatRoom::State state = ChatRoom::State::None; time_t creationTime = std::time(nullptr); diff --git a/src/chat/chat-room/chat-room.cpp b/src/chat/chat-room/chat-room.cpp index a55a82560..9404bba69 100644 --- a/src/chat/chat-room/chat-room.cpp +++ b/src/chat/chat-room/chat-room.cpp @@ -51,7 +51,7 @@ void ChatRoomPrivate::sendChatMessage (const shared_ptr &chatMessag dChatMessage->setTime(ms_time(0)); dChatMessage->send(); - LinphoneChatRoom *cr = L_GET_C_BACK_PTR(q); + LinphoneChatRoom *cr = getCChatRoom(); // TODO: server currently don't stock message, remove condition in the future. if (!linphone_core_conference_server_enabled(q->getCore()->getCCore())) { shared_ptr event = static_pointer_cast( @@ -129,7 +129,7 @@ list> ChatRoomPrivate::findChatMessages (const string &m void ChatRoomPrivate::notifyChatMessageReceived (const shared_ptr &chatMessage) { L_Q(); - LinphoneChatRoom *cr = L_GET_C_BACK_PTR(q); + LinphoneChatRoom *cr = getCChatRoom(); if (!chatMessage->getPrivate()->getText().empty()) { /* Legacy API */ LinphoneAddress *fromAddress = linphone_address_new(chatMessage->getFromAddress().asString().c_str()); @@ -153,7 +153,7 @@ void ChatRoomPrivate::notifyIsComposingReceived (const Address &remoteAddress, b else remoteIsComposing.remove(remoteAddress); - LinphoneChatRoom *cr = L_GET_C_BACK_PTR(q); + LinphoneChatRoom *cr = getCChatRoom(); LinphoneAddress *lAddr = linphone_address_new(remoteAddress.asString().c_str()); _linphone_chat_room_notify_is_composing_received(cr, lAddr, !!isComposing); linphone_address_unref(lAddr); @@ -163,14 +163,14 @@ void ChatRoomPrivate::notifyIsComposingReceived (const Address &remoteAddress, b void ChatRoomPrivate::notifyStateChanged () { L_Q(); - linphone_core_notify_chat_room_state_changed(q->getCore()->getCCore(), L_GET_C_BACK_PTR(q), (LinphoneChatRoomState)state); - LinphoneChatRoom *cr = L_GET_C_BACK_PTR(q); + LinphoneChatRoom *cr = getCChatRoom(); + linphone_core_notify_chat_room_state_changed(q->getCore()->getCCore(), cr, (LinphoneChatRoomState)state); _linphone_chat_room_notify_state_changed(cr, (LinphoneChatRoomState)state); } void ChatRoomPrivate::notifyUndecryptableChatMessageReceived (const shared_ptr &chatMessage) { L_Q(); - LinphoneChatRoom *cr = L_GET_C_BACK_PTR(q); + LinphoneChatRoom *cr = getCChatRoom(); _linphone_chat_room_notify_undecryptable_message_received(cr, L_GET_C_BACK_PTR(chatMessage)); linphone_core_notify_message_received_unable_decrypt(q->getCore()->getCCore(), cr, L_GET_C_BACK_PTR(chatMessage)); } @@ -262,6 +262,16 @@ void ChatRoomPrivate::onIsRemoteComposingStateChanged (const Address &remoteAddr notifyIsComposingReceived(remoteAddress, isComposing); } +// ----------------------------------------------------------------------------- + +LinphoneChatRoom *ChatRoomPrivate::getCChatRoom () const { + L_Q(); + if (proxyChatRoom) + return L_GET_C_BACK_PTR(proxyChatRoom); + else + return L_GET_C_BACK_PTR(q); +} + // ============================================================================= ChatRoom::ChatRoom (ChatRoomPrivate &p, const shared_ptr &core, const ChatRoomId &chatRoomId) : @@ -341,7 +351,9 @@ int ChatRoom::getHistorySize () const { void ChatRoom::deleteFromDb () { L_D(); - Core::deleteChatRoom(this->getSharedFromThis()); + // Keep a ref, otherwise the object might be destroyed before we can set the Deleted state + shared_ptr ref = this->getSharedFromThis(); + Core::deleteChatRoom(ref); d->setState(ChatRoom::State::Deleted); } diff --git a/src/chat/chat-room/chat-room.h b/src/chat/chat-room/chat-room.h index e5a270a97..40cad5ae3 100644 --- a/src/chat/chat-room/chat-room.h +++ b/src/chat/chat-room/chat-room.h @@ -30,6 +30,8 @@ class ChatRoomPrivate; class LINPHONE_PUBLIC ChatRoom : public AbstractChatRoom { public: + friend class ProxyChatRoomPrivate; + L_OVERRIDE_SHARED_FROM_THIS(ChatRoom); const ChatRoomId &getChatRoomId () const override; diff --git a/src/chat/chat-room/client-group-chat-room.cpp b/src/chat/chat-room/client-group-chat-room.cpp index a5ea59cb4..e40482457 100644 --- a/src/chat/chat-room/client-group-chat-room.cpp +++ b/src/chat/chat-room/client-group-chat-room.cpp @@ -521,7 +521,7 @@ void ClientGroupChatRoom::onParticipantAdded (const shared_ptraddEvent(event); - LinphoneChatRoom *cr = L_GET_C_BACK_PTR(this); + LinphoneChatRoom *cr = d->getCChatRoom(); _linphone_chat_room_notify_participant_added(cr, L_GET_C_BACK_PTR(event)); } @@ -541,7 +541,7 @@ void ClientGroupChatRoom::onParticipantRemoved (const shared_ptrparticipants.remove(participant); d->addEvent(event); - LinphoneChatRoom *cr = L_GET_C_BACK_PTR(this); + LinphoneChatRoom *cr = d->getCChatRoom(); _linphone_chat_room_notify_participant_removed(cr, L_GET_C_BACK_PTR(event)); } @@ -569,7 +569,7 @@ void ClientGroupChatRoom::onParticipantSetAdmin (const shared_ptraddEvent(event); - LinphoneChatRoom *cr = L_GET_C_BACK_PTR(this); + LinphoneChatRoom *cr = d->getCChatRoom(); _linphone_chat_room_notify_participant_admin_status_changed(cr, L_GET_C_BACK_PTR(event)); } @@ -585,7 +585,7 @@ void ClientGroupChatRoom::onSubjectChanged (const shared_ptraddEvent(event); - LinphoneChatRoom *cr = L_GET_C_BACK_PTR(this); + LinphoneChatRoom *cr = d->getCChatRoom(); _linphone_chat_room_notify_subject_changed(cr, L_GET_C_BACK_PTR(event)); } @@ -609,7 +609,7 @@ void ClientGroupChatRoom::onParticipantDeviceAdded (const shared_ptraddEvent(event); - LinphoneChatRoom *cr = L_GET_C_BACK_PTR(this); + LinphoneChatRoom *cr = d->getCChatRoom(); _linphone_chat_room_notify_participant_device_added(cr, L_GET_C_BACK_PTR(event)); } @@ -631,7 +631,7 @@ void ClientGroupChatRoom::onParticipantDeviceRemoved (const shared_ptrgetPrivate()->removeDevice(event->getDeviceAddress()); d->addEvent(event); - LinphoneChatRoom *cr = L_GET_C_BACK_PTR(this); + LinphoneChatRoom *cr = d->getCChatRoom(); _linphone_chat_room_notify_participant_device_removed(cr, L_GET_C_BACK_PTR(event)); } diff --git a/src/chat/chat-room/client-group-chat-room.h b/src/chat/chat-room/client-group-chat-room.h index 3569dd2d2..9bb13f526 100644 --- a/src/chat/chat-room/client-group-chat-room.h +++ b/src/chat/chat-room/client-group-chat-room.h @@ -33,6 +33,7 @@ class LINPHONE_PUBLIC ClientGroupChatRoom : public ChatRoom, public RemoteConfer friend class BasicToClientGroupChatRoomPrivate; friend class ClientGroupToBasicChatRoomPrivate; friend class Core; + friend class CorePrivate; public: L_OVERRIDE_SHARED_FROM_THIS(ClientGroupChatRoom); diff --git a/src/chat/chat-room/client-group-to-basic-chat-room.cpp b/src/chat/chat-room/client-group-to-basic-chat-room.cpp index 7ca4ab61f..c72f9cfec 100644 --- a/src/chat/chat-room/client-group-to-basic-chat-room.cpp +++ b/src/chat/chat-room/client-group-to-basic-chat-room.cpp @@ -48,7 +48,9 @@ public: void onChatRoomDeleteRequested (const shared_ptr &chatRoom) override { L_Q(); - q->getCore()->deleteChatRoom(q->getSharedFromThis()); + // Keep a ref, otherwise the object might be destroyed before we can set the Deleted state + shared_ptr ref = q->getSharedFromThis(); + q->getCore()->deleteChatRoom(ref); setState(AbstractChatRoom::State::Deleted); } @@ -64,24 +66,23 @@ public: const string &message ) override { L_Q(); + // Keep a ref, otherwise the object might be destroyed when calling Core::deleteChatRoom() + shared_ptr ref = q->getSharedFromThis(); + // TODO: Avoid cast, use capabilities. shared_ptr cgcr = dynamic_pointer_cast(chatRoom); if (!cgcr) return; if ((newState == CallSession::State::Error) && (cgcr->getState() == ChatRoom::State::CreationPending) && (session->getReason() == LinphoneReasonNotAcceptable) && (invitedAddresses.size() == 1)) { - teardownCallbacks(); + teardownProxy(); cgcr->getPrivate()->onCallSessionStateChanged(session, newState, message); cgcr->getPrivate()->setCallSessionListener(nullptr); cgcr->getPrivate()->setChatRoomListener(nullptr); Core::deleteChatRoom(q->getSharedFromThis()); - setupCallbacks(); + setupProxy(); LinphoneChatRoom *lcr = L_GET_C_BACK_PTR(q); - shared_ptr bcr = cgcr->getCore()->onlyGetOrCreateBasicChatRoom(invitedAddresses.front()); + shared_ptr bcr = cgcr->getCore()->getOrCreateBasicChatRoom(invitedAddresses.front()); L_SET_CPP_PTR_FROM_C_OBJECT(lcr, bcr); - bcr->getPrivate()->setState(ChatRoom::State::Instantiated); - cgcr->getCore()->getPrivate()->insertChatRoom(bcr); - bcr->getPrivate()->setState(ChatRoom::State::Created); - cgcr->getCore()->getPrivate()->insertChatRoomWithDb(bcr); return; } cgcr->getPrivate()->onCallSessionStateChanged(session, newState, message); diff --git a/src/chat/chat-room/proxy-chat-room-p.h b/src/chat/chat-room/proxy-chat-room-p.h index 89fb81e21..b10aa3d8a 100644 --- a/src/chat/chat-room/proxy-chat-room-p.h +++ b/src/chat/chat-room/proxy-chat-room-p.h @@ -73,8 +73,8 @@ public: chatRoom->getPrivate()->onChatMessageReceived(chatMessage); } - void setupCallbacks (); - void teardownCallbacks (); + void setupProxy (); + void teardownProxy (); std::shared_ptr chatRoom; diff --git a/src/chat/chat-room/proxy-chat-room.cpp b/src/chat/chat-room/proxy-chat-room.cpp index a81847e10..6ddcb4f74 100644 --- a/src/chat/chat-room/proxy-chat-room.cpp +++ b/src/chat/chat-room/proxy-chat-room.cpp @@ -18,7 +18,7 @@ */ #include "basic-to-client-group-chat-room.h" -#include "chat-room.h" +#include "chat-room-p.h" #include "proxy-chat-room-p.h" #include "c-wrapper/c-wrapper.h" @@ -28,98 +28,13 @@ using namespace std; LINPHONE_BEGIN_NAMESPACE -#define PROXY_CALLBACK(callback, ...) \ - LinphoneChatRoomCbs *proxiedCbs = linphone_chat_room_get_current_callbacks(cr); \ - ProxyChatRoom *pcr = static_cast(linphone_chat_room_cbs_get_user_data(proxiedCbs)); \ - LinphoneChatRoom *lcr = L_GET_C_BACK_PTR(pcr->getSharedFromThis()); \ - _linphone_chat_room_notify_ ## callback(lcr, ##__VA_ARGS__) - -static void chatMessageReceived (LinphoneChatRoom *cr, const LinphoneEventLog *event_log) { - PROXY_CALLBACK(chat_message_received, event_log); -} - -static void chatMessageSent (LinphoneChatRoom *cr, const LinphoneEventLog *event_log) { - PROXY_CALLBACK(chat_message_sent, event_log); -} - -static void conferenceAddressGeneration (LinphoneChatRoom *cr) { - PROXY_CALLBACK(conference_address_generation); -} - -static void isComposingReceived (LinphoneChatRoom *cr, const LinphoneAddress *remoteAddr, bool_t isComposing) { - PROXY_CALLBACK(is_composing_received, remoteAddr, isComposing); -} - -static void messageReceived (LinphoneChatRoom *cr, LinphoneChatMessage *msg) { - PROXY_CALLBACK(message_received, msg); -} - -static void participantAdded (LinphoneChatRoom *cr, const LinphoneEventLog *event_log) { - PROXY_CALLBACK(participant_added, event_log); -} - -static void participantAdminStatusChanged (LinphoneChatRoom *cr, const LinphoneEventLog *event_log) { - PROXY_CALLBACK(participant_admin_status_changed, event_log); -} - -static void participantDeviceAdded (LinphoneChatRoom *cr, const LinphoneEventLog *event_log) { - PROXY_CALLBACK(participant_device_added, event_log); -} - -static void participantDeviceFetched (LinphoneChatRoom *cr, const LinphoneAddress *participantAddr) { - PROXY_CALLBACK(participant_device_fetched, participantAddr); -} - -static void participantDeviceRemoved (LinphoneChatRoom *cr, const LinphoneEventLog *event_log) { - PROXY_CALLBACK(participant_device_removed, event_log); -} - -static void participantRemoved (LinphoneChatRoom *cr, const LinphoneEventLog *event_log) { - PROXY_CALLBACK(participant_removed, event_log); -} - -static void participantsCapabilitiesChecked (LinphoneChatRoom *cr, const LinphoneAddress *deviceAddr, const bctbx_list_t *participantsAddr) { - PROXY_CALLBACK(participants_capabilities_checked, deviceAddr, participantsAddr); -} - -static void stateChanged (LinphoneChatRoom *cr, LinphoneChatRoomState newState) { - PROXY_CALLBACK(state_changed, newState); -} - -static void subjectChanged (LinphoneChatRoom *cr, const LinphoneEventLog *event_log) { - PROXY_CALLBACK(subject_changed, event_log); -} - -static void undecryptableMessageReceived (LinphoneChatRoom *cr, LinphoneChatMessage *msg) { - PROXY_CALLBACK(undecryptable_message_received, msg); -} - -void ProxyChatRoomPrivate::setupCallbacks () { +void ProxyChatRoomPrivate::setupProxy () { L_Q(); - LinphoneChatRoom *lcr = L_GET_C_BACK_PTR(chatRoom); - LinphoneChatRoomCbs *cbs = linphone_factory_create_chat_room_cbs(linphone_factory_get()); - linphone_chat_room_cbs_set_user_data(cbs, q); - linphone_chat_room_cbs_set_chat_message_received(cbs, chatMessageReceived); - linphone_chat_room_cbs_set_chat_message_sent(cbs, chatMessageSent); - linphone_chat_room_cbs_set_conference_address_generation(cbs, conferenceAddressGeneration); - linphone_chat_room_cbs_set_is_composing_received(cbs, isComposingReceived); - linphone_chat_room_cbs_set_message_received(cbs, messageReceived); - linphone_chat_room_cbs_set_participant_added(cbs, participantAdded); - linphone_chat_room_cbs_set_participant_admin_status_changed(cbs, participantAdminStatusChanged); - linphone_chat_room_cbs_set_participant_device_added(cbs, participantDeviceAdded); - linphone_chat_room_cbs_set_participant_device_fetched(cbs, participantDeviceFetched); - linphone_chat_room_cbs_set_participant_device_removed(cbs, participantDeviceRemoved); - linphone_chat_room_cbs_set_participant_removed(cbs, participantRemoved); - linphone_chat_room_cbs_set_participants_capabilities_checked(cbs, participantsCapabilitiesChecked); - linphone_chat_room_cbs_set_state_changed(cbs, stateChanged); - linphone_chat_room_cbs_set_subject_changed(cbs, subjectChanged); - linphone_chat_room_cbs_set_undecryptable_message_received(cbs, undecryptableMessageReceived); - linphone_chat_room_add_callbacks(lcr, cbs); + static_pointer_cast(chatRoom)->getPrivate()->setProxyChatRoom(q); } -void ProxyChatRoomPrivate::teardownCallbacks () { - LinphoneChatRoom *lcr = L_GET_C_BACK_PTR(chatRoom); - _linphone_chat_room_clear_callbacks(lcr); +void ProxyChatRoomPrivate::teardownProxy () { + static_pointer_cast(chatRoom)->getPrivate()->setProxyChatRoom(nullptr); } // ----------------------------------------------------------------------------- @@ -128,7 +43,7 @@ void ProxyChatRoomPrivate::teardownCallbacks () { AbstractChatRoom(p, chatRoom->getCore()) { L_D(); d->chatRoom = chatRoom; - d->setupCallbacks(); + d->setupProxy(); } // ----------------------------------------------------------------------------- diff --git a/src/chat/chat-room/proxy-chat-room.h b/src/chat/chat-room/proxy-chat-room.h index 4f162e8ad..5e4c68d11 100644 --- a/src/chat/chat-room/proxy-chat-room.h +++ b/src/chat/chat-room/proxy-chat-room.h @@ -30,6 +30,8 @@ class ChatRoom; class ProxyChatRoomPrivate; class LINPHONE_PUBLIC ProxyChatRoom : public AbstractChatRoom { + friend class CorePrivate; + public: const ChatRoomId &getChatRoomId () const override; diff --git a/src/chat/chat-room/real-time-text-chat-room.cpp b/src/chat/chat-room/real-time-text-chat-room.cpp index f33162682..a33a19535 100644 --- a/src/chat/chat-room/real-time-text-chat-room.cpp +++ b/src/chat/chat-room/real-time-text-chat-room.cpp @@ -52,7 +52,7 @@ void RealTimeTextChatRoomPrivate::realtimeTextReceived (uint32_t character, cons receivedRttCharacters.push_back(cmc); remoteIsComposing.push_back(q->getPeerAddress()); - linphone_core_notify_is_composing_received(cCore, L_GET_C_BACK_PTR(q)); + linphone_core_notify_is_composing_received(cCore, getCChatRoom()); if ((character == new_line) || (character == crlf) || (character == lf)) { // End of message diff --git a/src/conference/conference-interface.h b/src/conference/conference-interface.h index dc4e740a1..aacf6bfab 100644 --- a/src/conference/conference-interface.h +++ b/src/conference/conference-interface.h @@ -34,7 +34,7 @@ class Participant; class LINPHONE_PUBLIC ConferenceInterface { public: - virtual ~ConferenceInterface() = default; + virtual ~ConferenceInterface () = default; virtual void addParticipant ( const IdentityAddress &participantAddress, diff --git a/src/conference/session/call-session.cpp b/src/conference/session/call-session.cpp index 035f66841..1d525bad9 100644 --- a/src/conference/session/call-session.cpp +++ b/src/conference/session/call-session.cpp @@ -62,6 +62,8 @@ void CallSessionPrivate::notifyReferState () { void CallSessionPrivate::setState (CallSession::State newState, const string &message) { L_Q(); + // Keep a ref on the CallSession, otherwise it might get destroyed before the end of the method + shared_ptr ref = q->getSharedFromThis(); if (state != newState){ prevState = state; diff --git a/src/core/core-chat-room.cpp b/src/core/core-chat-room.cpp index 0bceb5707..291c2a600 100644 --- a/src/core/core-chat-room.cpp +++ b/src/core/core-chat-room.cpp @@ -23,6 +23,8 @@ #include "chat/chat-room/basic-chat-room.h" #include "chat/chat-room/basic-to-client-group-chat-room.h" #include "chat/chat-room/chat-room-p.h" +#include "chat/chat-room/client-group-chat-room-p.h" +#include "chat/chat-room/client-group-to-basic-chat-room.h" #include "chat/chat-room/real-time-text-chat-room.h" #include "conference/participant.h" #include "core-p.h" @@ -98,15 +100,59 @@ shared_ptr CorePrivate::createBasicChatRoom ( return chatRoom; } -shared_ptr CorePrivate::createClientGroupChatRoom (const string &subject, bool fallback) { +shared_ptr CorePrivate::createClientGroupChatRoom (const string &subject, const string &uri, bool fallback) { L_Q(); - LinphoneChatRoom *lcr = _linphone_client_group_chat_room_new( - q->getCCore(), - nullptr, - L_STRING_TO_C(subject), - fallback ? TRUE : FALSE - ); - return lcr ? L_GET_CPP_PTR_FROM_C_OBJECT(lcr) : nullptr; + + string usedUri; + string from; + { + LinphoneProxyConfig *proxy = nullptr; + if (uri.empty()) { + proxy = linphone_core_get_default_proxy_config(q->getCCore()); + if (!proxy) + return nullptr; + const char *conferenceFactoryUri = linphone_proxy_config_get_conference_factory_uri(proxy); + if (!conferenceFactoryUri) + return nullptr; + usedUri = conferenceFactoryUri; + } else { + LinphoneAddress *addr = linphone_address_new(uri.c_str()); + proxy = linphone_core_lookup_known_proxy(q->getCCore(), addr); + linphone_address_unref(addr); + usedUri = uri; + } + if (proxy) { + const LinphoneAddress *contactAddr = linphone_proxy_config_get_contact(proxy); + if (contactAddr) { + char *cFrom = linphone_address_as_string(contactAddr); + from = string(cFrom); + bctbx_free(cFrom); + } else + from = L_GET_CPP_PTR_FROM_C_OBJECT(linphone_proxy_config_get_identity_address(proxy))->asString(); + } + } + + shared_ptr chatRoom; + { + shared_ptr clientGroupChatRoom = make_shared( + q->getSharedFromThis(), usedUri, IdentityAddress(from), subject + ); + ClientGroupChatRoomPrivate *dClientGroupChatRoom = clientGroupChatRoom->getPrivate(); + + if (fallback) { + // Create a ClientGroupToBasicChatRoom to handle fallback from ClientGroupChatRoom to BasicGroupChatRoom if + // only one participant is invited and that it does not support group chat + chatRoom = make_shared(clientGroupChatRoom); + dClientGroupChatRoom->setCallSessionListener(chatRoom->getPrivate()); + dClientGroupChatRoom->setChatRoomListener(chatRoom->getPrivate()); + } else + chatRoom = clientGroupChatRoom; + } + chatRoom->getPrivate()->setState(ChatRoom::State::Instantiated); + + noCreatedClientGroupChatRooms[chatRoom.get()] = chatRoom; + + return chatRoom; } void CorePrivate::insertChatRoom (const shared_ptr &chatRoom) { @@ -117,6 +163,9 @@ void CorePrivate::insertChatRoom (const shared_ptr &chatRoom) // Chat room not exist or yes but with the same pointer! L_ASSERT(it == chatRoomsById.end() || it->second == chatRoom); if (it == chatRoomsById.end()) { + // Remove chat room from workaround cache. + noCreatedClientGroupChatRooms.erase(chatRoom.get()); + chatRooms.push_back(chatRoom); chatRoomsById[chatRoomId] = chatRoom; } @@ -218,21 +267,7 @@ shared_ptr Core::findOneToOneChatRoom ( shared_ptr Core::createClientGroupChatRoom (const string &subject) { L_D(); - return d->createClientGroupChatRoom(subject, true); -} - -shared_ptr Core::onlyGetOrCreateBasicChatRoom (const IdentityAddress &peerAddress, bool isRtt) { - list> chatRooms = findChatRooms(peerAddress); - if (!chatRooms.empty()) - return chatRooms.front(); - - const ChatRoomId &chatRoomId = ChatRoomId(peerAddress, getDefaultLocalAddress(getSharedFromThis(), peerAddress)); - shared_ptr chatRoom; - - BasicChatRoom *basicChatRoom = new BasicChatRoom(getSharedFromThis(), chatRoomId); - chatRoom.reset(basicChatRoom); - - return chatRoom; + return d->createClientGroupChatRoom(subject); } shared_ptr Core::getOrCreateBasicChatRoom (const ChatRoomId &chatRoomId, bool isRtt) { @@ -283,6 +318,7 @@ shared_ptr Core::getOrCreateBasicChatRoomFromUri (const string void Core::deleteChatRoom (const shared_ptr &chatRoom) { CorePrivate *d = chatRoom->getCore()->getPrivate(); + d->noCreatedClientGroupChatRooms.erase(chatRoom.get()); const ChatRoomId &chatRoomId = chatRoom->getChatRoomId(); auto chatRoomsByIdIt = d->chatRoomsById.find(chatRoomId); if (chatRoomsByIdIt != d->chatRoomsById.end()) { diff --git a/src/core/core-p.h b/src/core/core-p.h index 1f47779c6..0106dd502 100644 --- a/src/core/core-p.h +++ b/src/core/core-p.h @@ -61,7 +61,7 @@ public: void insertChatRoom (const std::shared_ptr &chatRoom); void insertChatRoomWithDb (const std::shared_ptr &chatRoom); std::shared_ptr createBasicChatRoom (const ChatRoomId &chatRoomId, AbstractChatRoom::CapabilitiesMask capabilities); - std::shared_ptr createClientGroupChatRoom (const std::string &subject, bool fallback = true); + std::shared_ptr createClientGroupChatRoom (const std::string &subject, const std::string &uri = "", bool fallback = true); void replaceChatRoom (const std::shared_ptr &replacedChatRoom, const std::shared_ptr &newChatRoom); std::unique_ptr mainDb; @@ -73,8 +73,12 @@ private: std::shared_ptr currentCall; std::list> chatRooms; + std::unordered_map> chatRoomsById; + // Ugly cache to deal with C code. + std::unordered_map> noCreatedClientGroupChatRooms; + L_DECLARE_PUBLIC(Core); }; diff --git a/src/core/core.cpp b/src/core/core.cpp index d339db5cf..9e9d94cc6 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -77,6 +77,10 @@ void CorePrivate::uninit () { ms_usleep(10000); } + chatRooms.clear(); + chatRoomsById.clear(); + noCreatedClientGroupChatRooms.clear(); + AddressPrivate::clearSipAddressesCache(); } diff --git a/src/core/core.h b/src/core/core.h index b4ae4d921..a8a15630a 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -107,8 +107,9 @@ public: const IdentityAddress &localAddress ); - std::shared_ptr onlyGetOrCreateBasicChatRoom (const IdentityAddress &peerAddress, bool isRtt = false); std::shared_ptr getOrCreateBasicChatRoom (const ChatRoomId &chatRoomId, bool isRtt = false); + + // TODO: Remove me in the future, a chatroom is identified by a local and peer address now! std::shared_ptr getOrCreateBasicChatRoom (const IdentityAddress &peerAddress, bool isRtt = false); std::shared_ptr getOrCreateBasicChatRoomFromUri (const std::string &uri, bool isRtt = false); diff --git a/src/sal/refer-op.cpp b/src/sal/refer-op.cpp index a6ea0425f..6cc1b34b1 100644 --- a/src/sal/refer-op.cpp +++ b/src/sal/refer-op.cpp @@ -59,12 +59,14 @@ void SalReferOp::process_request_event_cb(void *op_base, const belle_sip_request if (!refer_to){ ms_warning("cannot do anything with the refer without destination"); op->reply(SalReasonUnknown);/*is mapped on bad request*/ + op->unref(); return; } SalAddress *referToAddr = sal_address_new(belle_sip_header_get_unparsed_value(BELLE_SIP_HEADER(refer_to))); op->root->callbacks.refer_received(op, referToAddr); /*the app is expected to reply in the callback*/ sal_address_unref(referToAddr); + op->unref(); } void SalReferOp::fill_cbs() { diff --git a/tester/group_chat_tester.c b/tester/group_chat_tester.c index 083a2a3ee..22cb42d4b 100644 --- a/tester/group_chat_tester.c +++ b/tester/group_chat_tester.c @@ -116,6 +116,7 @@ static void core_chat_room_state_changed (LinphoneCore *core, LinphoneChatRoom * linphone_chat_room_cbs_set_subject_changed(cbs, chat_room_subject_changed); linphone_chat_room_cbs_set_participant_device_added(cbs, chat_room_participant_device_added); linphone_chat_room_add_callbacks(cr, cbs); + linphone_chat_room_cbs_unref(cbs); } } @@ -154,11 +155,12 @@ static void _start_core(LinphoneCoreManager *lcm) { linphone_core_manager_start(lcm, TRUE); } -static void _send_message(LinphoneChatRoom *chatRoom, const char *message) { +static LinphoneChatMessage *_send_message(LinphoneChatRoom *chatRoom, const char *message) { LinphoneChatMessage *msg = linphone_chat_room_create_message(chatRoom, message); LinphoneChatMessageCbs *msgCbs = linphone_chat_message_get_callbacks(msg); linphone_chat_message_cbs_set_msg_state_changed(msgCbs, liblinphone_tester_chat_message_msg_state_changed); linphone_chat_message_send(msg); + return msg; } static void _send_file_plus_text(LinphoneChatRoom* cr, const char *sendFilepath, const char *text) { @@ -180,8 +182,9 @@ static void _send_file_plus_text(LinphoneChatRoom* cr, const char *sendFilepath, linphone_chat_message_cbs_set_file_transfer_send(cbs, tester_file_transfer_send); linphone_chat_message_cbs_set_msg_state_changed(cbs,liblinphone_tester_chat_message_msg_state_changed); linphone_chat_message_cbs_set_file_transfer_progress_indication(cbs, file_transfer_progress_indication); - linphone_chat_room_send_chat_message_2(cr, msg); + linphone_chat_room_send_chat_message(cr, msg); linphone_content_unref(content); + linphone_chat_message_unref(msg); } static void _send_file(LinphoneChatRoom* cr, const char *sendFilepath) { @@ -392,8 +395,8 @@ static void group_chat_room_creation_server (void) { BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneIsComposingActiveReceived, initialMarieStats.number_of_LinphoneIsComposingActiveReceived + 1, 10000)); BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneIsComposingActiveReceived, initialPaulineStats.number_of_LinphoneIsComposingActiveReceived + 1, 10000)); BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneIsComposingActiveReceived, initialLaureStats.number_of_LinphoneIsComposingActiveReceived + 1, 10000)); - const char *chloeMessage = "Hello"; - _send_message(chloeCr, chloeMessage); + const char *chloeTextMessage = "Hello"; + LinphoneChatMessage *chloeMessage = _send_message(chloeCr, chloeTextMessage); BC_ASSERT_TRUE(wait_for_list(coresList, &chloe->stat.number_of_LinphoneMessageDelivered, initialChloeStats.number_of_LinphoneMessageDelivered + 1, 10000)); BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageReceived, initialMarieStats.number_of_LinphoneMessageReceived + 1, 10000)); BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived + 1, 10000)); @@ -401,7 +404,8 @@ static void group_chat_room_creation_server (void) { BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneIsComposingIdleReceived, initialMarieStats.number_of_LinphoneIsComposingIdleReceived + 1, 10000)); BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneIsComposingIdleReceived, initialPaulineStats.number_of_LinphoneIsComposingIdleReceived + 1, 10000)); BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneIsComposingIdleReceived, initialLaureStats.number_of_LinphoneIsComposingIdleReceived + 1, 10000)); - BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(marie->stat.last_received_chat_message), chloeMessage); + BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(marie->stat.last_received_chat_message), chloeTextMessage); + linphone_chat_message_unref(chloeMessage); LinphoneAddress *chloeAddr = linphone_address_new(linphone_core_get_identity(chloe->lc)); BC_ASSERT_TRUE(linphone_address_weak_equal(chloeAddr, linphone_chat_message_get_from_address(marie->stat.last_received_chat_message))); linphone_address_unref(chloeAddr); @@ -488,7 +492,7 @@ static void group_chat_room_add_participant (void) { // Pauline creates a new group chat room const char *initialSubject = "Colleagues"; LinphoneChatRoom *paulineCr = create_chat_room_client_side(coresList, pauline, &initialPaulineStats, participantsAddresses, initialSubject, -1); - const LinphoneAddress *confAddr = linphone_chat_room_get_conference_address(paulineCr); + LinphoneAddress *confAddr = linphone_address_clone(linphone_chat_room_get_conference_address(paulineCr)); // Check that the chat room is correctly created on Pauline's side and that the participants are added LinphoneChatRoom *marieCr = check_creation_chat_room_client_side(coresList, marie, &initialMarieStats, confAddr, initialSubject, 2, FALSE); @@ -498,15 +502,16 @@ static void group_chat_room_add_participant (void) { // To simulate dialog removal for Pauline linphone_core_set_network_reachable(pauline->lc, FALSE); - coresList=bctbx_list_remove(coresList, pauline->lc); + LinphoneAddress *paulineAddr = linphone_address_clone(linphone_chat_room_get_peer_address(paulineCr)); + coresList = bctbx_list_remove(coresList, pauline->lc); linphone_core_manager_reinit(pauline); bctbx_list_t *tmpCoresManagerList = bctbx_list_append(NULL, pauline); - init_core_for_conference(tmpCoresManagerList); + bctbx_list_t *tmpCoresList = init_core_for_conference(tmpCoresManagerList); bctbx_list_free(tmpCoresManagerList); - coresList = bctbx_list_append(coresList, pauline->lc); + coresList = bctbx_list_concat(coresList, tmpCoresList); linphone_core_manager_start(pauline, TRUE); - LinphoneChatRoom *olpaulineCr = paulineCr; - paulineCr = linphone_core_get_chat_room(pauline->lc, linphone_chat_room_get_peer_address(olpaulineCr)); + paulineCr = linphone_core_get_chat_room(pauline->lc, paulineAddr); + linphone_address_unref(paulineAddr); // Pauline adds Chloe to the chat room participantsAddresses = NULL; @@ -533,9 +538,9 @@ static void group_chat_room_add_participant (void) { coresList = bctbx_list_remove(coresList, chloe->lc); linphone_core_manager_reinit(chloe); tmpCoresManagerList = bctbx_list_append(NULL, chloe); - init_core_for_conference(tmpCoresManagerList); + tmpCoresList = init_core_for_conference(tmpCoresManagerList); bctbx_list_free(tmpCoresManagerList); - coresList = bctbx_list_append(coresList, chloe->lc); + coresList = bctbx_list_concat(coresList, tmpCoresList); linphone_core_manager_start(chloe, TRUE); // Pauline adds Chloe to the chat room @@ -565,6 +570,7 @@ static void group_chat_room_add_participant (void) { BC_ASSERT_EQUAL(linphone_core_get_call_history_size(pauline->lc), 0, int,"%i"); BC_ASSERT_EQUAL(linphone_core_get_call_history_size(chloe->lc), 0, int,"%i"); + linphone_address_unref(confAddr); bctbx_list_free(coresList); bctbx_list_free(coresManagerList); linphone_core_manager_destroy(marie); @@ -665,8 +671,8 @@ static void group_chat_room_message (bool_t encrypt) { linphone_chat_room_compose(chloeCr); BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneIsComposingActiveReceived, initialMarieStats.number_of_LinphoneIsComposingActiveReceived + 1, 10000)); BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneIsComposingActiveReceived, initialPaulineStats.number_of_LinphoneIsComposingActiveReceived + 1, 10000)); - const char *chloeMessage = "Hello"; - _send_message(chloeCr, chloeMessage); + const char *chloeTextMessage = "Hello"; + LinphoneChatMessage *chloeMessage = _send_message(chloeCr, chloeTextMessage); BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageReceived, initialMarieStats.number_of_LinphoneMessageReceived + 1, 10000)); BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived + 1, 10000)); BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneIsComposingIdleReceived, initialMarieStats.number_of_LinphoneIsComposingIdleReceived + 1, 10000)); @@ -675,7 +681,8 @@ static void group_chat_room_message (bool_t encrypt) { if (!BC_ASSERT_PTR_NOT_NULL(marieLastMsg)) goto end; - BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(marieLastMsg), chloeMessage); + BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(marieLastMsg), chloeTextMessage); + linphone_chat_message_unref(chloeMessage); LinphoneAddress *chloeAddr = linphone_address_new(linphone_core_get_identity(chloe->lc)); BC_ASSERT_TRUE(linphone_address_weak_equal(chloeAddr, linphone_chat_message_get_from_address(marieLastMsg))); linphone_address_unref(chloeAddr); @@ -684,8 +691,8 @@ static void group_chat_room_message (bool_t encrypt) { linphone_chat_room_compose(paulineCr); BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneIsComposingActiveReceived, initialMarieStats.number_of_LinphoneIsComposingActiveReceived + 1, 10000)); BC_ASSERT_TRUE(wait_for_list(coresList, &chloe->stat.number_of_LinphoneIsComposingActiveReceived, initialChloeStats.number_of_LinphoneIsComposingActiveReceived + 1, 10000)); - const char *paulineMessage = "Héllö Dàrling"; - _send_message(paulineCr, paulineMessage); + const char *paulineTextMessage = "Héllö Dàrling"; + LinphoneChatMessage *paulineMessage = _send_message(paulineCr, paulineTextMessage); BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageReceived, initialMarieStats.number_of_LinphoneMessageReceived + 1, 10000)); BC_ASSERT_TRUE(wait_for_list(coresList, &chloe->stat.number_of_LinphoneMessageReceived, initialChloeStats.number_of_LinphoneMessageReceived + 1, 10000)); BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneIsComposingIdleReceived, initialMarieStats.number_of_LinphoneIsComposingIdleReceived + 1, 10000)); @@ -694,7 +701,8 @@ static void group_chat_room_message (bool_t encrypt) { if (!BC_ASSERT_PTR_NOT_NULL(marieLastMsg)) goto end; - BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(marieLastMsg), paulineMessage); + BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(marieLastMsg), paulineTextMessage); + linphone_chat_message_unref(paulineMessage); LinphoneAddress *paulineAddr = linphone_address_new(linphone_core_get_identity(pauline->lc)); BC_ASSERT_TRUE(linphone_address_weak_equal(paulineAddr, linphone_chat_message_get_from_address(marieLastMsg))); linphone_address_unref(paulineAddr); @@ -1242,8 +1250,9 @@ static void group_chat_room_send_message_with_participant_removed (void) { BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_participants_removed, initialPaulineStats.number_of_participants_removed + 1, 1000)); // Laure try to send a message with the chat room where she was removed - const char *laureMessage = "Hello"; - _send_message(laureCr, laureMessage); + const char *laureTextMessage = "Hello"; + LinphoneChatMessage *laureMessage = _send_message(laureCr, laureTextMessage); + linphone_chat_message_unref(laureMessage); BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneMessageReceived, initialMarieStats.number_of_LinphoneMessageDelivered, 10000)); BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageReceived, initialMarieStats.number_of_LinphoneMessageReceived, 10000)); @@ -1431,13 +1440,17 @@ static void group_chat_room_create_room_with_disconnected_friends_base (bool_t i if (initial_message) { if (BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, 1, 10000))) { LinphoneChatMessage *msg = linphone_chat_room_get_last_message_in_history(paulineCr); - if (BC_ASSERT_PTR_NOT_NULL(msg)) + if (BC_ASSERT_PTR_NOT_NULL(msg)) { BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(msg), "Salut"); + linphone_chat_message_unref(msg); + } } if (BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneMessageReceived, 1, 10000))) { LinphoneChatMessage *msg = linphone_chat_room_get_last_message_in_history(laureCr); - if (BC_ASSERT_PTR_NOT_NULL(msg)) + if (BC_ASSERT_PTR_NOT_NULL(msg)) { BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(msg), "Salut"); + linphone_chat_message_unref(msg); + } } } @@ -1513,11 +1526,11 @@ static void group_chat_room_reinvited_after_removed_base (bool_t offline_when_re lp_config_set_string(linphone_core_get_config(laure->lc), "misc", "uuid", savedLaureUuid); bctbx_free(savedLaureUuid); bctbx_list_t *tmpCoresManagerList = bctbx_list_append(NULL, laure); - init_core_for_conference(tmpCoresManagerList); + bctbx_list_t *tmpCoresList = init_core_for_conference(tmpCoresManagerList); bctbx_list_free(tmpCoresManagerList); initialLaureStats = laure->stat; linphone_core_manager_start(laure, TRUE); - coresList = bctbx_list_append(coresList, laure->lc); + coresList = bctbx_list_concat(coresList, tmpCoresList); coresManagerList = bctbx_list_append(coresManagerList, laure); } if (!offline_when_reinvited) @@ -1535,11 +1548,11 @@ static void group_chat_room_reinvited_after_removed_base (bool_t offline_when_re lp_config_set_string(linphone_core_get_config(laure->lc), "misc", "uuid", savedLaureUuid); bctbx_free(savedLaureUuid); bctbx_list_t *tmpCoresManagerList = bctbx_list_append(NULL, laure); - init_core_for_conference(tmpCoresManagerList); + bctbx_list_t *tmpCoresList = init_core_for_conference(tmpCoresManagerList); bctbx_list_free(tmpCoresManagerList); initialLaureStats = laure->stat; linphone_core_manager_start(laure, TRUE); - coresList = bctbx_list_append(coresList, laure->lc); + coresList = bctbx_list_concat(coresList, tmpCoresList); coresManagerList = bctbx_list_append(coresManagerList, laure); BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneChatRoomStateCreationPending, initialLaureStats.number_of_LinphoneChatRoomStateCreationPending + 1, 5000)); BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneChatRoomStateCreated, initialLaureStats.number_of_LinphoneChatRoomStateCreated + 2, 5000)); @@ -1549,7 +1562,9 @@ static void group_chat_room_reinvited_after_removed_base (bool_t offline_when_re } BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(marieCr), 2, int, "%d"); BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(paulineCr), 2, int, "%d"); - laureAddr = linphone_address_new(linphone_core_get_device_identity(laure->lc)); + char *laureIdentity = linphone_core_get_device_identity(laure->lc); + laureAddr = linphone_address_new(laureIdentity); + bctbx_free(laureIdentity); LinphoneChatRoom *newLaureCr = linphone_core_find_chat_room(laure->lc, confAddr, laureAddr); linphone_address_unref(laureAddr); if (!offline_when_removed) @@ -2059,7 +2074,6 @@ static void multiple_is_composing_notification(void) { } } - // Marie side BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneIsComposingActiveReceived, 2, 1000)); // + 1 composing_addresses = linphone_chat_room_get_composing_addresses(marieCr); @@ -2132,9 +2146,10 @@ static void group_chat_room_fallback_to_basic_chat_room (void) { bctbx_list_free_with_data(participantsAddresses, (bctbx_list_free_func)linphone_address_unref); participantsAddresses = NULL; - // Send a message and check that a basic chat room is create on Pauline's side + // Send a message and check that a basic chat room is created on Pauline's side LinphoneChatMessage *msg = linphone_chat_room_create_message(marieCr, "Hey Pauline!"); linphone_chat_message_send(msg); + linphone_chat_message_unref(msg); BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived + 1, 1000)); BC_ASSERT_PTR_NOT_NULL(pauline->stat.last_received_chat_message); if (pauline->stat.last_received_chat_message) @@ -2251,9 +2266,10 @@ static void group_chat_room_migrate_from_basic_chat_room (void) { LinphoneAddress *paulineAddr = linphone_address_new(linphone_core_get_identity(pauline->lc)); LinphoneChatRoom *marieCr = linphone_core_get_chat_room(marie->lc, paulineAddr); - // Send a message and check that a basic chat room is create on Pauline's side + // Send a message and check that a basic chat room is created on Pauline's side LinphoneChatMessage *msg = linphone_chat_room_create_message(marieCr, "Hey Pauline!"); linphone_chat_message_send(msg); + linphone_chat_message_unref(msg); BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived + 1, 1000)); BC_ASSERT_PTR_NOT_NULL(pauline->stat.last_received_chat_message); if (pauline->stat.last_received_chat_message) @@ -2268,9 +2284,9 @@ static void group_chat_room_migrate_from_basic_chat_room (void) { coresList = bctbx_list_remove(coresList, marie->lc); linphone_core_manager_reinit(marie); bctbx_list_t *tmpCoresManagerList = bctbx_list_append(NULL, marie); - init_core_for_conference(tmpCoresManagerList); + bctbx_list_t *tmpCoresList = init_core_for_conference(tmpCoresManagerList); bctbx_list_free(tmpCoresManagerList); - coresList = bctbx_list_append(coresList, marie->lc); + coresList = bctbx_list_concat(coresList, tmpCoresList); linphone_core_manager_start(marie, TRUE); // Send a new message to initiate chat room migration @@ -2282,6 +2298,7 @@ static void group_chat_room_migrate_from_basic_chat_room (void) { BC_ASSERT_EQUAL(linphone_chat_room_get_capabilities(marieCr), LinphoneChatRoomCapabilitiesBasic | LinphoneChatRoomCapabilitiesProxy | LinphoneChatRoomCapabilitiesMigratable | LinphoneChatRoomCapabilitiesOneToOne, int, "%d"); msg = linphone_chat_room_create_message(marieCr, "Did you migrate?"); linphone_chat_message_send(msg); + linphone_chat_message_unref(msg); BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateCreationPending, initialMarieStats.number_of_LinphoneChatRoomStateCreationPending + 1, 10000)); BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateCreated, initialMarieStats.number_of_LinphoneChatRoomStateCreated + 1, 10000)); BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(marieCr) & LinphoneChatRoomCapabilitiesConference); @@ -2297,12 +2314,14 @@ static void group_chat_room_migrate_from_basic_chat_room (void) { msg = linphone_chat_room_create_message(marieCr, "Let's go drink a beer"); linphone_chat_message_send(msg); + linphone_chat_message_unref(msg); BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived + 2, 1000)); BC_ASSERT_EQUAL(linphone_chat_room_get_history_size(marieCr), 3, int, "%d"); BC_ASSERT_EQUAL(linphone_chat_room_get_history_size(paulineCr), 3, int, "%d"); msg = linphone_chat_room_create_message(paulineCr, "Let's go drink mineral water instead"); linphone_chat_message_send(msg); + linphone_chat_message_unref(msg); BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageReceived, initialMarieStats.number_of_LinphoneMessageReceived + 1, 1000)); BC_ASSERT_EQUAL(linphone_chat_room_get_history_size(marieCr), 4, int, "%d"); BC_ASSERT_EQUAL(linphone_chat_room_get_history_size(paulineCr), 4, int, "%d"); @@ -2315,6 +2334,7 @@ static void group_chat_room_migrate_from_basic_chat_room (void) { linphone_core_manager_delete_chat_room(marie, marieCr, coresList); linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList); + linphone_address_unref(paulineAddr); bctbx_list_free(coresList); bctbx_list_free(coresManagerList); linphone_core_manager_destroy(marie); @@ -2352,7 +2372,7 @@ static void group_chat_room_migrate_from_basic_to_client_fail (void) { bctbx_list_free_with_data(participantsAddresses, (bctbx_list_free_func)linphone_address_unref); participantsAddresses = NULL; - // Send a message and check that a basic chat room is create on Pauline's side + // Send a message and check that a basic chat room is created on Pauline's side LinphoneChatMessage *msg = linphone_chat_room_create_message(marieCr, "Hey Pauline!"); linphone_chat_message_send(msg); BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived + 1, 1000)); @@ -2456,9 +2476,10 @@ static void group_chat_donot_room_migrate_from_basic_chat_room (void) { LinphoneAddress *paulineAddr = linphone_address_new(linphone_core_get_identity(pauline->lc)); LinphoneChatRoom *marieCr = linphone_core_get_chat_room(marie->lc, paulineAddr); - // Send a message and check that a basic chat room is create on Pauline's side + // Send a message and check that a basic chat room is created on Pauline's side LinphoneChatMessage *msg = linphone_chat_room_create_message(marieCr, "Hey Pauline!"); linphone_chat_message_send(msg); + linphone_chat_message_unref(msg); BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived + 1, 1000)); BC_ASSERT_PTR_NOT_NULL(pauline->stat.last_received_chat_message); if (pauline->stat.last_received_chat_message) @@ -2485,6 +2506,7 @@ static void group_chat_donot_room_migrate_from_basic_chat_room (void) { BC_ASSERT_EQUAL(linphone_chat_room_get_capabilities(marieCr), LinphoneChatRoomCapabilitiesBasic | LinphoneChatRoomCapabilitiesOneToOne, int, "%d"); msg = linphone_chat_room_create_message(marieCr, "Did you migrate?"); linphone_chat_message_send(msg); + linphone_chat_message_unref(msg); BC_ASSERT_FALSE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateCreationPending, initialMarieStats.number_of_LinphoneChatRoomStateCreationPending + 1, 10000)); BC_ASSERT_FALSE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateCreated, initialMarieStats.number_of_LinphoneChatRoomStateCreated + 1, 10000)); BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(marieCr) & LinphoneChatRoomCapabilitiesBasic); @@ -2500,12 +2522,14 @@ static void group_chat_donot_room_migrate_from_basic_chat_room (void) { msg = linphone_chat_room_create_message(marieCr, "Let's go drink a beer"); linphone_chat_message_send(msg); + linphone_chat_message_unref(msg); BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived + 2, 1000)); BC_ASSERT_EQUAL(linphone_chat_room_get_history_size(marieCr), 3, int, "%d"); BC_ASSERT_EQUAL(linphone_chat_room_get_history_size(paulineCr), 3, int, "%d"); msg = linphone_chat_room_create_message(paulineCr, "Let's go drink mineral water instead"); linphone_chat_message_send(msg); + linphone_chat_message_unref(msg); BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageReceived, initialMarieStats.number_of_LinphoneMessageReceived + 1, 1000)); BC_ASSERT_EQUAL(linphone_chat_room_get_history_size(marieCr), 4, int, "%d"); BC_ASSERT_EQUAL(linphone_chat_room_get_history_size(paulineCr), 4, int, "%d"); @@ -2515,6 +2539,7 @@ static void group_chat_donot_room_migrate_from_basic_chat_room (void) { linphone_core_delete_chat_room(marie->lc, marieCr); linphone_core_delete_chat_room(pauline->lc, paulineCr); + linphone_address_unref(paulineAddr); bctbx_list_free(coresList); bctbx_list_free(coresManagerList); linphone_core_manager_destroy(marie); @@ -2629,11 +2654,12 @@ static void group_chat_room_unique_one_to_one_chat_room (void) { BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(paulineCr) & LinphoneChatRoomCapabilitiesOneToOne); // Marie sends a message - const char *message = "Hello"; - _send_message(marieCr, message); + const char *textMessage = "Hello"; + LinphoneChatMessage *message = _send_message(marieCr, textMessage); BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageDelivered, initialMarieStats.number_of_LinphoneMessageDelivered + 1, 10000)); BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived + 1, 10000)); - BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(pauline->stat.last_received_chat_message), message); + BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(pauline->stat.last_received_chat_message), textMessage); + linphone_chat_message_unref(message); // Marie deletes the chat room linphone_core_manager_delete_chat_room(marie, marieCr, coresList); @@ -2647,11 +2673,12 @@ static void group_chat_room_unique_one_to_one_chat_room (void) { marieCr = create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject, -1); // Marie sends a new message - message = "Hey again"; - _send_message(marieCr, message); + textMessage = "Hey again"; + message = _send_message(marieCr, textMessage); BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageDelivered, initialMarieStats.number_of_LinphoneMessageDelivered + 1, 10000)); BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived + 1, 10000)); - BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(pauline->stat.last_received_chat_message), message); + BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(pauline->stat.last_received_chat_message), textMessage); + linphone_chat_message_unref(message); // Check that the created address is the same as before const LinphoneAddress *newConfAddr = linphone_chat_room_get_conference_address(marieCr); @@ -2693,28 +2720,28 @@ static void group_chat_room_unique_one_to_one_chat_room_recreated_from_message_b BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(paulineCr) & LinphoneChatRoomCapabilitiesOneToOne); // Marie sends a message - const char *message = "Hello"; - _send_message(marieCr, message); + const char *textMessage = "Hello"; + LinphoneChatMessage *message = _send_message(marieCr, textMessage); BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageDelivered, initialMarieStats.number_of_LinphoneMessageDelivered + 1, 10000)); BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived + 1, 10000)); - BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(pauline->stat.last_received_chat_message), message); + BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(pauline->stat.last_received_chat_message), textMessage); + linphone_chat_message_unref(message); if (with_app_restart) { - //to simulate dialog removal + // To simulate dialog removal + LinphoneAddress *marieAddr = linphone_address_clone(linphone_chat_room_get_peer_address(marieCr)); linphone_core_set_network_reachable(marie->lc, FALSE); - coresList=bctbx_list_remove(coresList, marie->lc); + coresList = bctbx_list_remove(coresList, marie->lc); linphone_core_manager_reinit(marie); bctbx_list_t *tmpCoresManagerList = bctbx_list_append(NULL, marie); - init_core_for_conference(tmpCoresManagerList); + bctbx_list_t *tmpCoresList = init_core_for_conference(tmpCoresManagerList); bctbx_list_free(tmpCoresManagerList); - coresList = bctbx_list_append(coresList, marie->lc); + coresList = bctbx_list_concat(coresList, tmpCoresList); linphone_core_manager_start(marie, TRUE); - //wait_for_list(coresList, 0, 1, 2000); - LinphoneChatRoom *oldMarieCr = marieCr; - marieCr = linphone_core_get_chat_room(marie->lc, linphone_chat_room_get_peer_address(oldMarieCr)); + marieCr = linphone_core_get_chat_room(marie->lc, marieAddr); + linphone_address_unref(marieAddr); } - // Marie deletes the chat room linphone_core_manager_delete_chat_room(marie, marieCr, coresList); wait_for_list(coresList, 0, 1, 2000); @@ -2725,11 +2752,12 @@ static void group_chat_room_unique_one_to_one_chat_room_recreated_from_message_b initialPaulineStats = pauline->stat; // Pauline sends a new message - message = "Hey you"; - _send_message(paulineCr, message); + textMessage = "Hey you"; + message = _send_message(paulineCr, textMessage); BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageDelivered, initialPaulineStats.number_of_LinphoneMessageDelivered + 1, 10000)); BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageReceived, initialMarieStats.number_of_LinphoneMessageReceived + 1, 10000)); - BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(marie->stat.last_received_chat_message), message); + BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(marie->stat.last_received_chat_message), textMessage); + linphone_chat_message_unref(message); // Check that the chat room has been correctly recreated on Marie's side marieCr = check_creation_chat_room_client_side(coresList, marie, &initialMarieStats, confAddr, initialSubject, 1, FALSE); @@ -2779,7 +2807,6 @@ static void group_chat_room_unique_one_to_one_chat_room_recreated_from_message_2 stats initialMarieStats = marie->stat; stats initialPaulineStats = pauline->stat; - linphone_core_set_network_reachable(marie2->lc, FALSE); linphone_core_set_network_reachable(pauline2->lc, FALSE); @@ -2795,11 +2822,12 @@ static void group_chat_room_unique_one_to_one_chat_room_recreated_from_message_2 BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(paulineCr) & LinphoneChatRoomCapabilitiesOneToOne); // Marie sends a message - const char *message = "Hello"; - _send_message(marieCr, message); + const char *textMessage = "Hello"; + LinphoneChatMessage *message = _send_message(marieCr, textMessage); BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageDelivered, initialMarieStats.number_of_LinphoneMessageDelivered + 1, 10000)); BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived + 1, 10000)); - BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(pauline->stat.last_received_chat_message), message); + BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(pauline->stat.last_received_chat_message), textMessage); + linphone_chat_message_unref(message); // Marie deletes the chat room linphone_core_manager_delete_chat_room(marie, marieCr, coresList); @@ -2812,16 +2840,17 @@ static void group_chat_room_unique_one_to_one_chat_room_recreated_from_message_2 initialMarieStats = marie->stat; initialPaulineStats = pauline->stat; marieCr = create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject, -1); + // Check that the chat room has been correctly recreated on Marie's side marieCr = check_creation_chat_room_client_side(coresList, marie, &initialMarieStats, confAddr, initialSubject, 1, FALSE); if (BC_ASSERT_PTR_NOT_NULL(marieCr)){ BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(marieCr) & LinphoneChatRoomCapabilitiesOneToOne); - - message = "Hey you"; - _send_message(marieCr, message); + textMessage = "Hey you"; + message = _send_message(marieCr, textMessage); BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageDelivered, initialMarieStats.number_of_LinphoneMessageDelivered + 1, 10000)); BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived + 1, 10000)); - BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(pauline->stat.last_received_chat_message), message); + BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(pauline->stat.last_received_chat_message), textMessage); + linphone_chat_message_unref(message); // Clean db from chat room linphone_core_manager_delete_chat_room(marie, marieCr, coresList); @@ -2870,18 +2899,20 @@ static void group_chat_room_join_one_to_one_chat_room_with_a_new_device (void) { BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(paulineCr) & LinphoneChatRoomCapabilitiesOneToOne); // Marie1 sends a message - const char *message = "Hello"; - _send_message(marie1Cr, message); + const char *textMessage = "Hello"; + LinphoneChatMessage *message = _send_message(marie1Cr, textMessage); BC_ASSERT_TRUE(wait_for_list(coresList, &marie1->stat.number_of_LinphoneMessageDelivered, initialMarie1Stats.number_of_LinphoneMessageDelivered + 1, 10000)); BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived + 1, 10000)); - BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(pauline->stat.last_received_chat_message), message); + BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(pauline->stat.last_received_chat_message), textMessage); + linphone_chat_message_unref(message); // Pauline answers to the previous message - message = "Hey. How are you?"; - _send_message(paulineCr, message); + textMessage = "Hey. How are you?"; + message = _send_message(paulineCr, textMessage); BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageDelivered, initialPaulineStats.number_of_LinphoneMessageDelivered + 1, 10000)); BC_ASSERT_TRUE(wait_for_list(coresList, &marie1->stat.number_of_LinphoneMessageReceived, initialMarie1Stats.number_of_LinphoneMessageReceived + 1, 10000)); - BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(marie1->stat.last_received_chat_message), message); + BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(marie1->stat.last_received_chat_message), textMessage); + linphone_chat_message_unref(message); // Simulate an uninstall of the application on Marie's side linphone_core_set_network_reachable(marie1->lc, FALSE); @@ -2905,18 +2936,20 @@ static void group_chat_room_join_one_to_one_chat_room_with_a_new_device (void) { BC_ASSERT_TRUE(linphone_address_weak_equal(confAddr, newConfAddr)); // Marie2 sends a new message - message = "Fine and you?"; - _send_message(marie2Cr, message); + textMessage = "Fine and you?"; + message = _send_message(marie2Cr, textMessage); BC_ASSERT_TRUE(wait_for_list(coresList, &marie2->stat.number_of_LinphoneMessageDelivered, initialMarie2Stats.number_of_LinphoneMessageDelivered + 1, 10000)); BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived + 2, 10000)); - BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(pauline->stat.last_received_chat_message), message); + BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(pauline->stat.last_received_chat_message), textMessage); + linphone_chat_message_unref(message); // Pauline answers to the previous message - message = "Perfect!"; - _send_message(paulineCr, message); + textMessage = "Perfect!"; + message = _send_message(paulineCr, textMessage); BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageDelivered, initialPaulineStats.number_of_LinphoneMessageDelivered + 2, 10000)); BC_ASSERT_TRUE(wait_for_list(coresList, &marie2->stat.number_of_LinphoneMessageReceived, initialMarie2Stats.number_of_LinphoneMessageReceived + 1, 10000)); - BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(marie2->stat.last_received_chat_message), message); + BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(marie2->stat.last_received_chat_message), textMessage); + linphone_chat_message_unref(message); // Clean db from chat room linphone_core_manager_delete_chat_room(marie2, marie2Cr, coresList); @@ -3024,14 +3057,14 @@ static void imdn_for_group_chat_room (void) { LinphoneChatRoom *chloeCr = check_creation_chat_room_client_side(coresList, chloe, &initialChloeStats, confAddr, initialSubject, 2, FALSE); // Chloe begins composing a message - const char *chloeMessage = "Hello"; - _send_message(chloeCr, chloeMessage); + const char *chloeTextMessage = "Hello"; + LinphoneChatMessage *chloeMessage = _send_message(chloeCr, chloeTextMessage); BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageReceived, initialMarieStats.number_of_LinphoneMessageReceived + 1, 10000)); BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived + 1, 10000)); LinphoneChatMessage *marieLastMsg = marie->stat.last_received_chat_message; if (!BC_ASSERT_PTR_NOT_NULL(marieLastMsg)) goto end; - BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(marieLastMsg), chloeMessage); + BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(marieLastMsg), chloeTextMessage); LinphoneAddress *chloeAddr = linphone_address_new(linphone_core_get_identity(chloe->lc)); BC_ASSERT_TRUE(linphone_address_weak_equal(chloeAddr, linphone_chat_message_get_from_address(marieLastMsg))); linphone_address_unref(chloeAddr); @@ -3047,6 +3080,8 @@ static void imdn_for_group_chat_room (void) { linphone_chat_room_mark_as_read(paulineCr); BC_ASSERT_TRUE(wait_for_list(coresList, &chloe->stat.number_of_LinphoneMessageDisplayed, initialChloeStats.number_of_LinphoneMessageDisplayed + 1, 1000)); + linphone_chat_message_unref(chloeMessage); + end: // Clean db from chat room linphone_core_manager_delete_chat_room(marie, marieCr, coresList); @@ -3145,49 +3180,49 @@ static void find_one_to_one_chat_room (void) { } test_t group_chat_tests[] = { - TEST_TWO_TAGS("Group chat room creation server", group_chat_room_creation_server, "Server", "LeaksMemory"), - TEST_TWO_TAGS("Add participant", group_chat_room_add_participant, "Server", "LeaksMemory"), - TEST_TWO_TAGS("Send message", group_chat_room_send_message, "Server", "LeaksMemory"), - TEST_TWO_TAGS("Send encrypted message", group_chat_room_send_message_encrypted, "Server", "LeaksMemory"), - TEST_TWO_TAGS("Send invite on a multi register account", group_chat_room_invite_multi_register_account, "Server", "LeaksMemory"), - TEST_TWO_TAGS("Add admin", group_chat_room_add_admin, "Server", "LeaksMemory"), - TEST_TWO_TAGS("Add admin lately notified", group_chat_room_add_admin_lately_notified, "Server", "LeaksMemory"), - TEST_TWO_TAGS("Add admin with a non admin", group_chat_room_add_admin_non_admin, "Server", "LeaksMemory"), - TEST_TWO_TAGS("Remove admin", group_chat_room_remove_admin, "Server", "LeaksMemory"), - TEST_TWO_TAGS("Admin creator leaves the room", group_chat_room_admin_creator_leaves_the_room, "Server", "LeaksMemory"), - TEST_TWO_TAGS("Change subject", group_chat_room_change_subject, "Server", "LeaksMemory"), - TEST_TWO_TAGS("Change subject with a non admin", group_chat_room_change_subject_non_admin, "Server", "LeaksMemory"), - TEST_TWO_TAGS("Remove participant", group_chat_room_remove_participant, "Server", "LeaksMemory"), - TEST_TWO_TAGS("Send message with a participant removed", group_chat_room_send_message_with_participant_removed, "Server", "LeaksMemory"), - TEST_TWO_TAGS("Leave group chat room", group_chat_room_leave, "Server", "LeaksMemory"), - TEST_TWO_TAGS("Come back on a group chat room after a disconnection", group_chat_room_come_back_after_disconnection, "Server", "LeaksMemory"), - TEST_TWO_TAGS("Create chat room with disconnected friends", group_chat_room_create_room_with_disconnected_friends, "Server", "LeaksMemory"), - TEST_TWO_TAGS("Create chat room with disconnected friends and initial message", group_chat_room_create_room_with_disconnected_friends_and_initial_message, "Server", "LeaksMemory"), - TEST_TWO_TAGS("Reinvited after removed from group chat room", group_chat_room_reinvited_after_removed, "Server", "LeaksMemory"), - TEST_TWO_TAGS("Reinvited after removed from group chat room while offline", group_chat_room_reinvited_after_removed_while_offline, "Server", "LeaksMemory"), - TEST_TWO_TAGS("Reinvited after removed from group chat room while offline 2", group_chat_room_reinvited_after_removed_while_offline_2, "Server", "LeaksMemory"), - TEST_TWO_TAGS("Reinvited after removed from group chat room with several devices", group_chat_room_reinvited_after_removed_with_several_devices, "Server", "LeaksMemory"), - TEST_TWO_TAGS("Notify after disconnection", group_chat_room_notify_after_disconnection, "Server", "LeaksMemory"), - TEST_TWO_TAGS("Send refer to all participants devices", group_chat_room_send_refer_to_all_devices, "Server", "LeaksMemory"), + TEST_NO_TAG("Group chat room creation server", group_chat_room_creation_server), + TEST_ONE_TAG("Add participant", group_chat_room_add_participant, "LeaksMemory"), + TEST_NO_TAG("Send message", group_chat_room_send_message), + TEST_NO_TAG("Send encrypted message", group_chat_room_send_message_encrypted), + TEST_NO_TAG("Send invite on a multi register account", group_chat_room_invite_multi_register_account), + TEST_NO_TAG("Add admin", group_chat_room_add_admin), + TEST_NO_TAG("Add admin lately notified", group_chat_room_add_admin_lately_notified), + TEST_NO_TAG("Add admin with a non admin", group_chat_room_add_admin_non_admin), + TEST_NO_TAG("Remove admin", group_chat_room_remove_admin), + TEST_NO_TAG("Admin creator leaves the room", group_chat_room_admin_creator_leaves_the_room), + TEST_NO_TAG("Change subject", group_chat_room_change_subject), + TEST_NO_TAG("Change subject with a non admin", group_chat_room_change_subject_non_admin), + TEST_NO_TAG("Remove participant", group_chat_room_remove_participant), + TEST_NO_TAG("Send message with a participant removed", group_chat_room_send_message_with_participant_removed), + TEST_NO_TAG("Leave group chat room", group_chat_room_leave), + TEST_NO_TAG("Come back on a group chat room after a disconnection", group_chat_room_come_back_after_disconnection), + TEST_NO_TAG("Create chat room with disconnected friends", group_chat_room_create_room_with_disconnected_friends), + TEST_ONE_TAG("Create chat room with disconnected friends and initial message", group_chat_room_create_room_with_disconnected_friends_and_initial_message, "LeaksMemory"), + TEST_NO_TAG("Reinvited after removed from group chat room", group_chat_room_reinvited_after_removed), + TEST_ONE_TAG("Reinvited after removed from group chat room while offline", group_chat_room_reinvited_after_removed_while_offline, "LeaksMemory"), + TEST_ONE_TAG("Reinvited after removed from group chat room while offline 2", group_chat_room_reinvited_after_removed_while_offline_2, "LeaksMemory"), + TEST_ONE_TAG("Reinvited after removed from group chat room with several devices", group_chat_room_reinvited_after_removed_with_several_devices, "LeaksMemory"), + TEST_NO_TAG("Notify after disconnection", group_chat_room_notify_after_disconnection), + TEST_NO_TAG("Send refer to all participants devices", group_chat_room_send_refer_to_all_devices), // TODO: Use when we support adding a new device in created conf - //TEST_TWO_TAGS("Admin add device and doesn't lose admin status", group_chat_room_add_device, "Server", "LeaksMemory"), - TEST_TWO_TAGS("Send multiple is composing", multiple_is_composing_notification, "Server", "LeaksMemory"), - TEST_TWO_TAGS("Fallback to basic chat room", group_chat_room_fallback_to_basic_chat_room, "Server", "LeaksMemory"), - TEST_TWO_TAGS("Group chat room creation fails if invited participants don't support it", group_chat_room_creation_fails_if_invited_participants_dont_support_it, "Server", "LeaksMemory"), - TEST_TWO_TAGS("Group chat room creation successful if at least one invited participant supports it", group_chat_room_creation_successful_if_at_least_one_invited_participant_supports_it, "Server", "LeaksMemory"), - TEST_TWO_TAGS("Migrate basic chat room to client group chat room", group_chat_room_migrate_from_basic_chat_room, "Server", "LeaksMemory"), - TEST_TWO_TAGS("Migrate basic chat room to client group chat room failure", group_chat_room_migrate_from_basic_to_client_fail, "Server", "LeaksMemory"), - TEST_TWO_TAGS("Migrate basic chat room to client group chat room not needed", group_chat_donot_room_migrate_from_basic_chat_room, "Server", "LeaksMemory"), - TEST_TWO_TAGS("Send file", group_chat_room_send_file, "Server", "LeaksMemory"), - TEST_TWO_TAGS("Send file + text", group_chat_room_send_file_plus_text, "Server", "LeaksMemory"), - TEST_TWO_TAGS("Unique one-to-one chatroom", group_chat_room_unique_one_to_one_chat_room, "Server", "LeaksMemory"), - TEST_TWO_TAGS("Unique one-to-one chatroom recreated from message", group_chat_room_unique_one_to_one_chat_room_recreated_from_message, "Server", "LeaksMemory"), - TEST_TWO_TAGS("Unique one-to-one chatroom recreated from message with app restart", group_chat_room_unique_one_to_one_chat_room_recreated_from_message_with_app_restart, "Server", "LeaksMemory"), - TEST_TWO_TAGS("Join one-to-one chat room with a new device", group_chat_room_join_one_to_one_chat_room_with_a_new_device, "Server", "LeaksMemory"), - TEST_TWO_TAGS("New unique one-to-one chatroom after both participants left", group_chat_room_new_unique_one_to_one_chat_room_after_both_participants_left, "Server", "LeaksMemory"), - TEST_TWO_TAGS("Unique one-to-one chatroom re-created from the party that deleted it, with inactive devices", group_chat_room_unique_one_to_one_chat_room_recreated_from_message_2, "Server", "LeaksMemory"), - TEST_TWO_TAGS("IMDN for group chat room", imdn_for_group_chat_room, "Server", "LeaksMemory"), - TEST_TWO_TAGS("Find one to one chat room", find_one_to_one_chat_room, "Server", "LeaksMemory") + //TEST_ONE_TAGS("Admin add device and doesn't lose admin status", group_chat_room_add_device, "LeaksMemory"), + TEST_NO_TAG("Send multiple is composing", multiple_is_composing_notification), + TEST_ONE_TAG("Fallback to basic chat room", group_chat_room_fallback_to_basic_chat_room, "LeaksMemory"), + TEST_NO_TAG("Group chat room creation fails if invited participants don't support it", group_chat_room_creation_fails_if_invited_participants_dont_support_it), + TEST_NO_TAG("Group chat room creation successful if at least one invited participant supports it", group_chat_room_creation_successful_if_at_least_one_invited_participant_supports_it), + TEST_ONE_TAG("Migrate basic chat room to client group chat room", group_chat_room_migrate_from_basic_chat_room, "LeaksMemory"), + TEST_ONE_TAG("Migrate basic chat room to client group chat room failure", group_chat_room_migrate_from_basic_to_client_fail, "LeaksMemory"), + TEST_NO_TAG("Migrate basic chat room to client group chat room not needed", group_chat_donot_room_migrate_from_basic_chat_room), + TEST_NO_TAG("Send file", group_chat_room_send_file), + TEST_NO_TAG("Send file + text", group_chat_room_send_file_plus_text), + TEST_NO_TAG("Unique one-to-one chatroom", group_chat_room_unique_one_to_one_chat_room), + TEST_NO_TAG("Unique one-to-one chatroom recreated from message", group_chat_room_unique_one_to_one_chat_room_recreated_from_message), + TEST_ONE_TAG("Unique one-to-one chatroom recreated from message with app restart", group_chat_room_unique_one_to_one_chat_room_recreated_from_message_with_app_restart, "LeaksMemory"), + TEST_NO_TAG("Join one-to-one chat room with a new device", group_chat_room_join_one_to_one_chat_room_with_a_new_device), + TEST_NO_TAG("New unique one-to-one chatroom after both participants left", group_chat_room_new_unique_one_to_one_chat_room_after_both_participants_left), + TEST_NO_TAG("Unique one-to-one chatroom re-created from the party that deleted it, with inactive devices", group_chat_room_unique_one_to_one_chat_room_recreated_from_message_2), + TEST_NO_TAG("IMDN for group chat room", imdn_for_group_chat_room), + TEST_NO_TAG("Find one to one chat room", find_one_to_one_chat_room) }; test_suite_t group_chat_test_suite = {