From 5fb8f9686a059fffeda3c8931013c10b4e3658f7 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Fri, 16 Mar 2018 14:45:54 +0100 Subject: [PATCH] Handle incoming INVITE from conference server to create ClientGroupChatRoom. --- coreapi/callbacks.c | 121 +++++++++++++----- coreapi/misc.c | 7 +- coreapi/private_functions.h | 1 + include/linphone/api/c-callbacks.h | 6 + include/linphone/api/c-chat-room-cbs.h | 14 ++ src/c-wrapper/api/c-chat-room-cbs.cpp | 9 ++ src/c-wrapper/api/c-chat-room.cpp | 4 + src/chat/chat-room/basic-chat-room.cpp | 2 +- src/chat/chat-room/basic-chat-room.h | 2 +- .../basic-to-client-group-chat-room.cpp | 2 +- src/chat/chat-room/client-group-chat-room-p.h | 7 +- src/chat/chat-room/client-group-chat-room.cpp | 97 ++++++++++---- src/chat/chat-room/client-group-chat-room.h | 5 +- src/chat/chat-room/proxy-chat-room.cpp | 2 +- src/chat/chat-room/proxy-chat-room.h | 2 +- src/chat/chat-room/server-group-chat-room-p.h | 3 +- .../chat-room/server-group-chat-room-stub.cpp | 6 +- src/chat/chat-room/server-group-chat-room.h | 2 +- src/conference/conference-interface.h | 2 +- src/conference/conference.cpp | 50 +++++++- src/conference/conference.h | 6 +- src/conference/local-conference.cpp | 27 +--- src/conference/local-conference.h | 5 +- src/conference/participant-device.cpp | 2 +- src/conference/participant-device.h | 6 +- src/conference/remote-conference.cpp | 18 +-- src/conference/remote-conference.h | 4 +- src/content/content-disposition.cpp | 9 +- src/content/content-disposition.h | 1 + src/content/content-type.cpp | 8 +- src/content/content-type.h | 1 + src/core/core-chat-room.cpp | 4 +- src/core/core-p.h | 2 +- src/sal/call-op.cpp | 17 ++- src/utils/background-task.cpp | 4 +- src/utils/background-task.h | 16 +-- tester/group_chat_tester.c | 64 ++++++--- tester/liblinphone_tester.h | 1 + 38 files changed, 365 insertions(+), 174 deletions(-) diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index da809bc05..4a835b704 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -41,6 +41,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "call/call-p.h" #include "chat/chat-message/chat-message-p.h" #include "chat/chat-room/chat-room.h" +#include "chat/chat-room/client-group-chat-room-p.h" #include "chat/chat-room/server-group-chat-room-p.h" #include "conference/participant.h" #include "conference/session/call-session-p.h" @@ -56,8 +57,14 @@ using namespace LinphonePrivate; static void register_failure(SalOp *op); static void call_received(SalCallOp *h) { - /* Look if this INVITE is for a call that has already been notified but broken because of network failure */ LinphoneCore *lc = reinterpret_cast(h->get_sal()->get_user_pointer()); + + if (linphone_core_get_global_state(lc) != LinphoneGlobalOn) { + h->decline(SalReasonServiceUnavailable, nullptr); + return; + } + + /* Look if this INVITE is for a call that has already been notified but broken because of network failure */ if (L_GET_PRIVATE_FROM_C_OBJECT(lc)->inviteReplacesABrokenCall(h)) return; @@ -107,16 +114,28 @@ static void call_received(SalCallOp *h) { // TODO: handle media conference creation if the "text" feature tag is not present return; } else if (sal_address_has_param(h->get_remote_contact_address(), "text")) { - shared_ptr chatRoom = L_GET_CPP_PTR_FROM_C_OBJECT(lc)->findChatRoom( - ChatRoomId(IdentityAddress(h->get_to()), IdentityAddress(h->get_to())) - ); - if (chatRoom) { - L_GET_PRIVATE(static_pointer_cast(chatRoom))->confirmJoining(h); - linphone_address_unref(toAddr); - linphone_address_unref(fromAddr); + linphone_address_unref(toAddr); + linphone_address_unref(fromAddr); + if (linphone_core_conference_server_enabled(lc)) { + shared_ptr chatRoom = L_GET_CPP_PTR_FROM_C_OBJECT(lc)->findChatRoom( + ChatRoomId(IdentityAddress(h->get_to()), IdentityAddress(h->get_to())) + ); + if (chatRoom) { + L_GET_PRIVATE(static_pointer_cast(chatRoom))->confirmJoining(h); + } else { + //invite is for an unknown chatroom + h->decline(SalReasonNotFound, nullptr); + } } else { - //invite is for an unknown chatroom - h->decline(SalReasonNotFound, nullptr); + shared_ptr chatRoom = L_GET_CPP_PTR_FROM_C_OBJECT(lc)->findChatRoom( + ChatRoomId(IdentityAddress(h->get_from()), IdentityAddress(h->get_to())) + ); + if (!chatRoom) { + chatRoom = L_GET_PRIVATE_FROM_C_OBJECT(lc)->createClientGroupChatRoom( + L_C_TO_STRING(h->get_subject()), h->get_remote_contact(), h->get_remote_body(), false + ); + } + L_GET_PRIVATE(static_pointer_cast(chatRoom))->confirmJoining(h); } return; } else { @@ -201,7 +220,8 @@ static void call_rejected(SalCallOp *h){ static void call_ringing(SalOp *h) { LinphonePrivate::CallSession *session = reinterpret_cast(h->get_user_pointer()); if (!session) return; - L_GET_PRIVATE(session)->remoteRinging(); + auto sessionRef = session->getSharedFromThis(); + L_GET_PRIVATE(sessionRef)->remoteRinging(); } /* @@ -215,7 +235,8 @@ static void call_accepted(SalOp *op) { ms_warning("call_accepted: CallSession no longer exists"); return; } - L_GET_PRIVATE(session)->accepted(); + auto sessionRef = session->getSharedFromThis(); + L_GET_PRIVATE(sessionRef)->accepted(); } /* this callback is called when an incoming re-INVITE/ SIP UPDATE modifies the session*/ @@ -225,7 +246,8 @@ static void call_updating(SalOp *op, bool_t is_update) { ms_warning("call_updating: CallSession no longer exists"); return; } - L_GET_PRIVATE(session)->updating(!!is_update); + auto sessionRef = session->getSharedFromThis(); + L_GET_PRIVATE(sessionRef)->updating(!!is_update); } @@ -235,7 +257,8 @@ static void call_ack_received(SalOp *op, SalCustomHeader *ack) { ms_warning("call_ack_received(): no CallSession for which an ack is expected"); return; } - L_GET_PRIVATE(session)->ackReceived(reinterpret_cast(ack)); + auto sessionRef = session->getSharedFromThis(); + L_GET_PRIVATE(sessionRef)->ackReceived(reinterpret_cast(ack)); } @@ -245,25 +268,26 @@ static void call_ack_being_sent(SalOp *op, SalCustomHeader *ack) { ms_warning("call_ack_being_sent(): no CallSession for which an ack is supposed to be sent"); return; } - L_GET_PRIVATE(session)->ackBeingSent(reinterpret_cast(ack)); + auto sessionRef = session->getSharedFromThis(); + L_GET_PRIVATE(sessionRef)->ackBeingSent(reinterpret_cast(ack)); } static void call_terminated(SalOp *op, const char *from) { LinphonePrivate::CallSession *session = reinterpret_cast(op->get_user_pointer()); if (!session) return; - L_GET_PRIVATE(session)->terminated(); + auto sessionRef = session->getSharedFromThis(); + L_GET_PRIVATE(sessionRef)->terminated(); } static void call_failure(SalOp *op) { - shared_ptr session; - if (op->get_user_pointer()) - session = reinterpret_cast(op->get_user_pointer())->getSharedFromThis(); + LinphonePrivate::CallSession *session = reinterpret_cast(op->get_user_pointer()); if (!session) { ms_warning("Failure reported on already terminated CallSession"); return; } - L_GET_PRIVATE(session)->failure(); + auto sessionRef = session->getSharedFromThis(); + L_GET_PRIVATE(sessionRef)->failure(); } static void call_released(SalOp *op) { @@ -273,7 +297,8 @@ static void call_released(SalOp *op) { * when declining an incoming call with busy because maximum number of calls is reached. */ return; } - L_GET_PRIVATE(session)->setState(LinphonePrivate::CallSession::State::Released, "Call released"); + auto sessionRef = session->getSharedFromThis(); + L_GET_PRIVATE(sessionRef)->setState(LinphonePrivate::CallSession::State::Released, "Call released"); } static void call_cancel_done(SalOp *op) { @@ -282,7 +307,8 @@ static void call_cancel_done(SalOp *op) { ms_warning("Cancel done reported on already terminated CallSession"); return; } - L_GET_PRIVATE(session)->cancelDone(); + auto sessionRef = session->getSharedFromThis(); + L_GET_PRIVATE(sessionRef)->cancelDone(); } static void auth_failure(SalOp *op, SalAuthInfo* info) { @@ -344,24 +370,26 @@ static void vfu_request(SalOp *op) { LinphonePrivate::CallSession *session = reinterpret_cast(op->get_user_pointer()); if (!session) return; - LinphonePrivate::MediaSession *mediaSession = dynamic_cast(session); - if (!mediaSession) { + auto sessionRef = session->getSharedFromThis(); + auto mediaSessionRef = dynamic_pointer_cast(sessionRef); + if (!mediaSessionRef) { ms_warning("VFU request but no MediaSession!"); return; } - L_GET_PRIVATE(mediaSession)->sendVfu(); + L_GET_PRIVATE(mediaSessionRef)->sendVfu(); } static void dtmf_received(SalOp *op, char dtmf) { LinphonePrivate::CallSession *session = reinterpret_cast(op->get_user_pointer()); if (!session) return; - LinphonePrivate::MediaSession *mediaSession = dynamic_cast(session); - if (!mediaSession) { + auto sessionRef = session->getSharedFromThis(); + auto mediaSessionRef = dynamic_pointer_cast(sessionRef); + if (!mediaSessionRef) { ms_warning("DTMF received but no MediaSession!"); return; } - L_GET_PRIVATE(mediaSession)->dtmfReceived(dtmf); + L_GET_PRIVATE(mediaSessionRef)->dtmfReceived(dtmf); } static void call_refer_received(SalOp *op, const SalAddress *referTo) { @@ -372,7 +400,8 @@ static void call_refer_received(SalOp *op, const SalAddress *referTo) { if (referToAddr.isValid()) method = referToAddr.getMethodParam(); if (session && (method.empty() || (method == "INVITE"))) { - L_GET_PRIVATE(session)->referred(referToAddr); + auto sessionRef = session->getSharedFromThis(); + L_GET_PRIVATE(sessionRef)->referred(referToAddr); } else { LinphoneCore *lc = reinterpret_cast(op->get_sal()->get_user_pointer()); linphone_core_notify_refer_received(lc, addrStr); @@ -382,6 +411,12 @@ static void call_refer_received(SalOp *op, const SalAddress *referTo) { static void message_received(SalOp *op, const SalMessage *msg){ LinphoneCore *lc=(LinphoneCore *)op->get_sal()->get_user_pointer(); + + if (linphone_core_get_global_state(lc) != LinphoneGlobalOn) { + static_cast(op)->reply(SalReasonServiceUnavailable); + return; + } + LinphoneCall *call=(LinphoneCall*)op->get_user_pointer(); LinphoneReason reason = lc->chat_deny_code; if (reason == LinphoneReasonNone) { @@ -414,6 +449,10 @@ static void notify_presence(SalOp *op, SalSubscribeStatus ss, SalPresenceModel * static void subscribe_presence_received(SalPresenceOp *op, const char *from){ LinphoneCore *lc=(LinphoneCore *)op->get_sal()->get_user_pointer(); + if (linphone_core_get_global_state(lc) != LinphoneGlobalOn) { + op->decline(SalReasonServiceUnavailable); + return; + } linphone_subscription_new(lc,op,from); } @@ -428,7 +467,8 @@ static void ping_reply(SalOp *op) { ms_warning("Ping reply without CallSession attached..."); return; } - L_GET_PRIVATE(session)->pingReply(); + auto sessionRef = session->getSharedFromThis(); + L_GET_PRIVATE(sessionRef)->pingReply(); } static bool_t fill_auth_info_with_client_certificate(LinphoneCore *lc, SalAuthInfo* sai) { @@ -531,6 +571,7 @@ static void notify_refer(SalOp *op, SalReferStatus status) { ms_warning("Receiving notify_refer for unknown CallSession"); return; } + auto sessionRef = session->getSharedFromThis(); LinphonePrivate::CallSession::State cstate; switch (status) { case SalReferTrying: @@ -544,9 +585,9 @@ static void notify_refer(SalOp *op, SalReferStatus status) { cstate = LinphonePrivate::CallSession::State::Error; break; } - L_GET_PRIVATE(session)->setTransferState(cstate); + L_GET_PRIVATE(sessionRef)->setTransferState(cstate); if (cstate == LinphonePrivate::CallSession::State::Connected) - session->terminate(); // Automatically terminate the call as the transfer is complete + sessionRef->terminate(); // Automatically terminate the call as the transfer is complete } static LinphoneChatMessageState chatStatusSal2Linphone(SalMessageDeliveryStatus status){ @@ -575,7 +616,8 @@ static void info_received(SalOp *op, SalBodyHandler *body_handler) { LinphonePrivate::CallSession *session = reinterpret_cast(op->get_user_pointer()); if (!session) return; - L_GET_PRIVATE(session)->infoReceived(body_handler); + auto sessionRef = session->getSharedFromThis(); + L_GET_PRIVATE(sessionRef)->infoReceived(body_handler); } static void subscribe_response(SalOp *op, SalSubscribeStatus status, int will_retry){ @@ -622,6 +664,11 @@ static void subscribe_received(SalSubscribeOp *op, const char *eventname, const LinphoneEvent *lev=(LinphoneEvent*)op->get_user_pointer(); LinphoneCore *lc=(LinphoneCore *)op->get_sal()->get_user_pointer(); + if (linphone_core_get_global_state(lc) != LinphoneGlobalOn) { + op->decline(SalReasonServiceUnavailable); + return; + } + if (lev==NULL) { lev=linphone_event_new_with_op(lc,op,LinphoneSubscriptionIncoming,eventname); linphone_event_set_state(lev,LinphoneSubscriptionIncomingReceived); @@ -700,6 +747,12 @@ static void refer_received(SalOp *op, const SalAddress *refer_to){ bctbx_free(refer_uri); if (addr.isValid()) { LinphoneCore *lc = reinterpret_cast(op->get_sal()->get_user_pointer()); + + if (linphone_core_get_global_state(lc) != LinphoneGlobalOn) { + static_cast(op)->reply(SalReasonDeclined); + return; + } + if (addr.hasUriParam("method") && (addr.getUriParamValue("method") == "BYE")) { if (linphone_core_conference_server_enabled(lc)) { // Removal of a participant at the server side @@ -754,7 +807,7 @@ static void refer_received(SalOp *op, const SalAddress *refer_to){ ChatRoomId(addr, IdentityAddress(op->get_to())) ); if (!chatRoom) - chatRoom = L_GET_PRIVATE_FROM_C_OBJECT(lc)->createClientGroupChatRoom("", addr.asString(), false); + chatRoom = L_GET_PRIVATE_FROM_C_OBJECT(lc)->createClientGroupChatRoom("", addr.asString(), Content(), false); chatRoom->join(); static_cast(op)->reply(SalReasonNone); return; diff --git a/coreapi/misc.c b/coreapi/misc.c index 3e255a354..f0e225112 100644 --- a/coreapi/misc.c +++ b/coreapi/misc.c @@ -919,8 +919,11 @@ void linphone_core_report_call_log(LinphoneCore *lc, LinphoneCallLog *call_log){ } linphone_address_unref(conference_factory_addr); } - const char *username = linphone_address_get_username(call_log->to); - if (username && (strstr(username, "chatroom-") == username)) + const char *usernameFrom = linphone_address_get_username(call_log->from); + const char *usernameTo = linphone_address_get_username(call_log->to); + if ((usernameFrom && (strstr(usernameFrom, "chatroom-") == usernameFrom)) + || (usernameTo && (strstr(usernameTo, "chatroom-") == usernameTo)) + ) return; // End of workaround diff --git a/coreapi/private_functions.h b/coreapi/private_functions.h index e6a27fbe0..35d16b492 100644 --- a/coreapi/private_functions.h +++ b/coreapi/private_functions.h @@ -288,6 +288,7 @@ void _linphone_chat_room_notify_participant_device_removed(LinphoneChatRoom *cr, void _linphone_chat_room_notify_participant_admin_status_changed(LinphoneChatRoom *cr, const LinphoneEventLog *event_log); void _linphone_chat_room_notify_state_changed(LinphoneChatRoom *cr, LinphoneChatRoomState newState); void _linphone_chat_room_notify_subject_changed(LinphoneChatRoom *cr, const LinphoneEventLog *event_log); +void _linphone_chat_room_notify_all_information_received(LinphoneChatRoom *cr); void _linphone_chat_room_notify_undecryptable_message_received(LinphoneChatRoom *cr, LinphoneChatMessage *msg); void _linphone_chat_room_notify_chat_message_received(LinphoneChatRoom *cr, const LinphoneEventLog *event_log); void _linphone_chat_room_notify_chat_message_sent(LinphoneChatRoom *cr, const LinphoneEventLog *event_log); diff --git a/include/linphone/api/c-callbacks.h b/include/linphone/api/c-callbacks.h index 339963691..273e86fac 100644 --- a/include/linphone/api/c-callbacks.h +++ b/include/linphone/api/c-callbacks.h @@ -235,6 +235,12 @@ typedef void (*LinphoneChatRoomCbsParticipantDeviceAddedCb) (LinphoneChatRoom *c */ typedef void (*LinphoneChatRoomCbsParticipantDeviceRemovedCb) (LinphoneChatRoom *cr, const LinphoneEventLog *event_log); +/** + * Callback used to notify a chat room has received all its information. + * @param[in] cr #LinphoneChatRoom object + */ +typedef void (*LinphoneChatRoomCbsAllInformationReceivedCb) (LinphoneChatRoom *cr); + /** * Callback used when a group chat room is created server-side to generate the address of the chat room. * The function linphone_chat_room_set_conference_address() needs to be called by this callback. diff --git a/include/linphone/api/c-chat-room-cbs.h b/include/linphone/api/c-chat-room-cbs.h index 6cbf7bd91..5ec319582 100644 --- a/include/linphone/api/c-chat-room-cbs.h +++ b/include/linphone/api/c-chat-room-cbs.h @@ -229,6 +229,20 @@ LINPHONE_PUBLIC LinphoneChatRoomCbsParticipantDeviceRemovedCb linphone_chat_room */ LINPHONE_PUBLIC void linphone_chat_room_cbs_set_participant_device_removed (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsParticipantDeviceRemovedCb cb); +/** + * Get the all information received callback. + * @param[in] cbs LinphoneChatRoomCbs object. + * @return The current all information received callback. + */ +LINPHONE_PUBLIC LinphoneChatRoomCbsAllInformationReceivedCb linphone_chat_room_cbs_get_all_information_received (const LinphoneChatRoomCbs *cbs); + +/** + * Set the all information received callback. + * @param[in] cbs LinphoneChatRoomCbs object. + * @param[in] cb The all information received callback to be used. + */ +LINPHONE_PUBLIC void linphone_chat_room_cbs_set_all_information_received (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsAllInformationReceivedCb cb); + /** * Get the conference address generation callback. * @param[in] cbs LinphoneChatRoomCbs object diff --git a/src/c-wrapper/api/c-chat-room-cbs.cpp b/src/c-wrapper/api/c-chat-room-cbs.cpp index 1d3d4d8d6..afec92128 100644 --- a/src/c-wrapper/api/c-chat-room-cbs.cpp +++ b/src/c-wrapper/api/c-chat-room-cbs.cpp @@ -35,6 +35,7 @@ struct _LinphoneChatRoomCbs { LinphoneChatRoomCbsParticipantAdminStatusChangedCb participantAdminStatusChangedCb; LinphoneChatRoomCbsStateChangedCb stateChangedCb; LinphoneChatRoomCbsSubjectChangedCb subjectChangedCb; + LinphoneChatRoomCbsAllInformationReceivedCb allInformationReceivedCb; LinphoneChatRoomCbsUndecryptableMessageReceivedCb undecryptableMessageReceivedCb; LinphoneChatRoomCbsChatMessageReceivedCb chatMessageReceivedCb; LinphoneChatRoomCbsChatMessageSentCb chatMessageSentCb; @@ -176,6 +177,14 @@ void linphone_chat_room_cbs_set_participant_device_removed (LinphoneChatRoomCbs cbs->participantDeviceRemovedCb = cb; } +LinphoneChatRoomCbsAllInformationReceivedCb linphone_chat_room_cbs_get_all_information_received (const LinphoneChatRoomCbs *cbs) { + return cbs->allInformationReceivedCb; +} + +void linphone_chat_room_cbs_set_all_information_received (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsAllInformationReceivedCb cb) { + cbs->allInformationReceivedCb = cb; +} + LinphoneChatRoomCbsConferenceAddressGenerationCb linphone_chat_room_cbs_get_conference_address_generation (const LinphoneChatRoomCbs *cbs) { return cbs->conferenceAddressGenerationCb; } diff --git a/src/c-wrapper/api/c-chat-room.cpp b/src/c-wrapper/api/c-chat-room.cpp index e549964e0..3e3f7bb4c 100644 --- a/src/c-wrapper/api/c-chat-room.cpp +++ b/src/c-wrapper/api/c-chat-room.cpp @@ -480,6 +480,10 @@ void _linphone_chat_room_notify_subject_changed(LinphoneChatRoom *cr, const Linp NOTIFY_IF_EXIST(SubjectChanged, subject_changed, cr, event_log) } +void _linphone_chat_room_notify_all_information_received(LinphoneChatRoom *cr) { + NOTIFY_IF_EXIST(AllInformationReceived, all_information_received, cr) +} + void _linphone_chat_room_notify_undecryptable_message_received(LinphoneChatRoom *cr, LinphoneChatMessage *msg) { NOTIFY_IF_EXIST(UndecryptableMessageReceived, undecryptable_message_received, cr, msg) } diff --git a/src/chat/chat-room/basic-chat-room.cpp b/src/chat/chat-room/basic-chat-room.cpp index 619b52dc7..c3752755f 100644 --- a/src/chat/chat-room/basic-chat-room.cpp +++ b/src/chat/chat-room/basic-chat-room.cpp @@ -88,7 +88,7 @@ void BasicChatRoom::addParticipants (const list &, const CallSe lError() << "addParticipants() is not allowed on a BasicChatRoom"; } -void BasicChatRoom::removeParticipant (const shared_ptr &) { +void BasicChatRoom::removeParticipant (const shared_ptr &) { lError() << "removeParticipant() is not allowed on a BasicChatRoom"; } diff --git a/src/chat/chat-room/basic-chat-room.h b/src/chat/chat-room/basic-chat-room.h index e66aceba0..767ebaa35 100644 --- a/src/chat/chat-room/basic-chat-room.h +++ b/src/chat/chat-room/basic-chat-room.h @@ -48,7 +48,7 @@ public: void addParticipant (const IdentityAddress &addr, const CallSessionParams *params, bool hasMedia) override; void addParticipants (const std::list &addresses, const CallSessionParams *params, bool hasMedia) override; - void removeParticipant (const std::shared_ptr &participant) override; + void removeParticipant (const std::shared_ptr &participant) override; void removeParticipants (const std::list> &participants) override; std::shared_ptr findParticipant (const IdentityAddress &addr) const override; 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 67f9ea2fc..960067b14 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(), "", Content(), false) ); clientGroupChatRoom->getPrivate()->setCallSessionListener(this); clientGroupChatRoom->getPrivate()->setChatRoomListener(this); diff --git a/src/chat/chat-room/client-group-chat-room-p.h b/src/chat/chat-room/client-group-chat-room-p.h index e617b517d..f5fbc97b5 100644 --- a/src/chat/chat-room/client-group-chat-room-p.h +++ b/src/chat/chat-room/client-group-chat-room-p.h @@ -35,6 +35,7 @@ public: void notifyReceived (const std::string &body); void multipartNotifyReceived (const std::string &body); + void confirmJoining (SalCallOp *op); void setCallSessionListener (CallSessionListener *listener); void setChatRoomListener (ChatRoomListener *listener) { chatRoomListener = listener; } @@ -47,12 +48,16 @@ public: void onCallSessionSetReleased (const std::shared_ptr &session) override; void onCallSessionStateChanged (const std::shared_ptr &session, CallSession::State state, const std::string &message) override; + void onChatRoomCreated (const Address &remoteContact); + private: + void acceptSession (const std::shared_ptr &session); + CallSessionListener *callSessionListener = this; ChatRoomListener *chatRoomListener = this; ClientGroupChatRoom::CapabilitiesMask capabilities = ClientGroupChatRoom::Capabilities::Conference; bool deletionOnTerminationEnabled = false; - BackgroundTask bgTask; + BackgroundTask bgTask { "Subscribe/notify of full state conference" }; L_DECLARE_PUBLIC(ClientGroupChatRoom); }; diff --git a/src/chat/chat-room/client-group-chat-room.cpp b/src/chat/chat-room/client-group-chat-room.cpp index 29c872d30..5a9639621 100644 --- a/src/chat/chat-room/client-group-chat-room.cpp +++ b/src/chat/chat-room/client-group-chat-room.cpp @@ -101,6 +101,31 @@ void ClientGroupChatRoomPrivate::setCallSessionListener (CallSessionListener *li } } +void ClientGroupChatRoomPrivate::confirmJoining (SalCallOp *op) { + L_Q(); + L_Q_T(RemoteConference, qConference); + + auto focus = qConference->getPrivate()->focus; + bool previousSession = (focus->getPrivate()->getSession() != nullptr); + auto session = focus->getPrivate()->createSession(*q, nullptr, false, this); + session->configure(LinphoneCallIncoming, nullptr, op, Address(op->get_from()), Address(op->get_to())); + session->startIncomingNotification(false); + + if (!previousSession) { + setState(ClientGroupChatRoom::State::CreationPending); + // Handle participants addition + list identAddresses = ClientGroupChatRoom::parseResourceLists(op->get_remote_body()); + for (const auto &addr : identAddresses) { + auto participant = q->findParticipant(addr); + if (!participant) { + participant = make_shared(addr); + qConference->getPrivate()->participants.push_back(participant); + } + } + } + acceptSession(session); +} + // ----------------------------------------------------------------------------- void ClientGroupChatRoomPrivate::onChatRoomInsertRequested (const shared_ptr &chatRoom) { @@ -139,14 +164,11 @@ void ClientGroupChatRoomPrivate::onCallSessionStateChanged ( if (newState == CallSession::State::Connected) { if (q->getState() == ChatRoom::State::CreationPending) { - IdentityAddress addr(session->getRemoteContactAddress()->asStringUriOnly()); - q->onConferenceCreated(addr); - if (session->getRemoteContactAddress()->hasParam("isfocus")) { - bgTask.start(q->getCore(), 32); // It will be stopped when receiving the first notify - qConference->getPrivate()->eventHandler->subscribe(q->getChatRoomId()); - } + onChatRoomCreated(*session->getRemoteContactAddress()); } else if (q->getState() == ChatRoom::State::TerminationPending) qConference->getPrivate()->focus->getPrivate()->getSession()->terminate(); + } else if (newState == CallSession::State::End) { + q->onConferenceTerminated(q->getConferenceAddress()); } else if (newState == CallSession::State::Released) { if (q->getState() == ChatRoom::State::TerminationPending) { if (session->getReason() == LinphoneReasonNone) { @@ -174,23 +196,46 @@ void ClientGroupChatRoomPrivate::onCallSessionStateChanged ( } } +void ClientGroupChatRoomPrivate::onChatRoomCreated (const Address &remoteContact) { + L_Q(); + L_Q_T(RemoteConference, qConference); + + IdentityAddress addr(remoteContact); + q->onConferenceCreated(addr); + if (remoteContact.hasParam("isfocus")) { + bgTask.start(q->getCore(), 32); // It will be stopped when receiving the first notify + qConference->getPrivate()->eventHandler->subscribe(q->getChatRoomId()); + } +} + +// ----------------------------------------------------------------------------- + +void ClientGroupChatRoomPrivate::acceptSession (const shared_ptr &session) { + if (session->getState() == CallSession::State::UpdatedByRemote) + session->acceptUpdate(); + else + session->accept(); +} + // ============================================================================= ClientGroupChatRoom::ClientGroupChatRoom ( const shared_ptr &core, const string &uri, const IdentityAddress &me, - const string &subject + const string &subject, + const Content &content ) : ChatRoom(*new ClientGroupChatRoomPrivate, core, ChatRoomId(IdentityAddress(), me)), RemoteConference(core, me, nullptr) { L_D_T(RemoteConference, dConference); - L_D(); - + IdentityAddress focusAddr(uri); dConference->focus = make_shared(focusAddr); dConference->focus->getPrivate()->addDevice(focusAddr); RemoteConference::setSubject(subject); - d->bgTask.setName("Subscribe/notify of full state conference"); + list identAddresses = Conference::parseResourceLists(content); + for (const auto &addr : identAddresses) + dConference->participants.push_back(make_shared(addr)); } ClientGroupChatRoom::ClientGroupChatRoom ( @@ -251,7 +296,7 @@ ClientGroupChatRoom::CapabilitiesMask ClientGroupChatRoom::getCapabilities () co } bool ClientGroupChatRoom::hasBeenLeft () const { - return getState() != State::Created; + return (getState() != State::Created); } bool ClientGroupChatRoom::canHandleParticipants () const { @@ -328,7 +373,7 @@ void ClientGroupChatRoom::addParticipants ( } } -void ClientGroupChatRoom::removeParticipant (const shared_ptr &participant) { +void ClientGroupChatRoom::removeParticipant (const shared_ptr &participant) { LinphoneCore *cCore = getCore()->getCCore(); SalReferOp *referOp = new SalReferOp(cCore->sal); @@ -422,7 +467,8 @@ void ClientGroupChatRoom::join () { if (session) { if (getState() != ChatRoom::State::TerminationPending) session->startInvite(nullptr, "", nullptr); - d->setState(ChatRoom::State::CreationPending); + if (getState() != ChatRoom::State::Created) + d->setState(ChatRoom::State::CreationPending); } } @@ -454,6 +500,7 @@ void ClientGroupChatRoom::onConferenceCreated (const IdentityAddress &addr) { dConference->focus->getPrivate()->addDevice(addr); d->chatRoomId = ChatRoomId(addr, d->chatRoomId.getLocalAddress()); d->chatRoomListener->onChatRoomInsertRequested(getSharedFromThis()); + d->setState(ChatRoom::State::Created); } void ClientGroupChatRoom::onConferenceKeywordsChanged (const vector &keywords) { @@ -464,6 +511,7 @@ void ClientGroupChatRoom::onConferenceKeywordsChanged (const vector &key void ClientGroupChatRoom::onConferenceTerminated (const IdentityAddress &addr) { L_D(); L_D_T(RemoteConference, dConference); + dConference->eventHandler->unsubscribe(); dConference->eventHandler->resetLastNotify(); d->setState(ChatRoom::State::Terminated); d->addEvent(make_shared( @@ -479,21 +527,26 @@ void ClientGroupChatRoom::onConferenceTerminated (const IdentityAddress &addr) { void ClientGroupChatRoom::onFirstNotifyReceived (const IdentityAddress &addr) { L_D(); - d->setState(ChatRoom::State::Created); - + + bool performMigration = false; + shared_ptr chatRoom; if (getParticipantCount() == 1) { ChatRoomId id(getParticipants().front()->getAddress(), getMe()->getAddress()); - shared_ptr chatRoom = getCore()->findChatRoom(id); - if (chatRoom && (chatRoom->getCapabilities() & ChatRoom::Capabilities::Basic)) { - BasicToClientGroupChatRoom::migrate(getSharedFromThis(), chatRoom); - d->bgTask.stop(); - return; - } + chatRoom = getCore()->findChatRoom(id); + if (chatRoom && (chatRoom->getCapabilities() & ChatRoom::Capabilities::Basic)) + performMigration = true; } - d->chatRoomListener->onChatRoomInsertInDatabaseRequested(getSharedFromThis()); + if (performMigration) + BasicToClientGroupChatRoom::migrate(getSharedFromThis(), chatRoom); + else + d->chatRoomListener->onChatRoomInsertInDatabaseRequested(getSharedFromThis()); + + LinphoneChatRoom *cr = d->getCChatRoom(); + _linphone_chat_room_notify_all_information_received(cr); d->bgTask.stop(); + // TODO: Bug. Event is inserted many times. // Avoid this in the future. Deal with signals/slots system. #if 0 diff --git a/src/chat/chat-room/client-group-chat-room.h b/src/chat/chat-room/client-group-chat-room.h index 9bb13f526..5d28a2ce9 100644 --- a/src/chat/chat-room/client-group-chat-room.h +++ b/src/chat/chat-room/client-group-chat-room.h @@ -43,7 +43,8 @@ public: const std::shared_ptr &core, const std::string &factoryUri, const IdentityAddress &me, - const std::string &subject + const std::string &subject, + const Content &content ); ClientGroupChatRoom ( @@ -77,7 +78,7 @@ public: void addParticipant (const IdentityAddress &addr, const CallSessionParams *params, bool hasMedia) override; void addParticipants (const std::list &addresses, const CallSessionParams *params, bool hasMedia) override; - void removeParticipant (const std::shared_ptr &participant) override; + void removeParticipant (const std::shared_ptr &participant) override; void removeParticipants (const std::list> &participants) override; std::shared_ptr findParticipant (const IdentityAddress &addr) const override; diff --git a/src/chat/chat-room/proxy-chat-room.cpp b/src/chat/chat-room/proxy-chat-room.cpp index 6ddcb4f74..bb4239cce 100644 --- a/src/chat/chat-room/proxy-chat-room.cpp +++ b/src/chat/chat-room/proxy-chat-room.cpp @@ -248,7 +248,7 @@ void ProxyChatRoom::addParticipants ( return d->chatRoom->addParticipants(addresses, params, hasMedia); } -void ProxyChatRoom::removeParticipant (const shared_ptr &participant) { +void ProxyChatRoom::removeParticipant (const shared_ptr &participant) { L_D(); d->chatRoom->removeParticipant(participant); } diff --git a/src/chat/chat-room/proxy-chat-room.h b/src/chat/chat-room/proxy-chat-room.h index 5e4c68d11..35b7ec851 100644 --- a/src/chat/chat-room/proxy-chat-room.h +++ b/src/chat/chat-room/proxy-chat-room.h @@ -97,7 +97,7 @@ public: bool hasMedia ) override; - void removeParticipant (const std::shared_ptr &participant) override; + void removeParticipant (const std::shared_ptr &participant) override; void removeParticipants (const std::list> &participants) override; std::shared_ptr findParticipant (const IdentityAddress &participantAddress) const override; diff --git a/src/chat/chat-room/server-group-chat-room-p.h b/src/chat/chat-room/server-group-chat-room-p.h index 911f31f67..0ddcbdd48 100644 --- a/src/chat/chat-room/server-group-chat-room-p.h +++ b/src/chat/chat-room/server-group-chat-room-p.h @@ -91,6 +91,7 @@ private: static void copyMessageHeaders (const std::shared_ptr &fromMessage, const std::shared_ptr &toMessage); + void byeDevice (const std::shared_ptr &device); void designateAdmin (); void dispatchMessage (const std::shared_ptr &message, const std::string &uri); void finalizeCreation (); @@ -100,7 +101,7 @@ private: void queueMessage (const std::shared_ptr &msg, const IdentityAddress &deviceAddress); void removeNonPresentParticipants (const std::list &compatibleParticipants); - void onParticipantDeviceLeft (const std::shared_ptr &session); + void onParticipantDeviceLeft (const std::shared_ptr &device); // ChatRoomListener void onChatRoomInsertRequested (const std::shared_ptr &chatRoom) override; diff --git a/src/chat/chat-room/server-group-chat-room-stub.cpp b/src/chat/chat-room/server-group-chat-room-stub.cpp index d8204fc5b..bf29ca554 100644 --- a/src/chat/chat-room/server-group-chat-room-stub.cpp +++ b/src/chat/chat-room/server-group-chat-room-stub.cpp @@ -92,6 +92,8 @@ LinphoneReason ServerGroupChatRoomPrivate::onSipMessageReceived (SalOp *, const // ----------------------------------------------------------------------------- +void ServerGroupChatRoomPrivate::byeDevice (const shared_ptr &device) {} + void ServerGroupChatRoomPrivate::designateAdmin () {} void ServerGroupChatRoomPrivate::dispatchMessage (const shared_ptr &message, const string &uri) {} @@ -112,7 +114,7 @@ void ServerGroupChatRoomPrivate::removeNonPresentParticipants (const list &session) {} +void ServerGroupChatRoomPrivate::onParticipantDeviceLeft (const shared_ptr &device) {} // ----------------------------------------------------------------------------- @@ -187,7 +189,7 @@ void ServerGroupChatRoom::addParticipant (const IdentityAddress &, const CallSes void ServerGroupChatRoom::addParticipants (const list &, const CallSessionParams *, bool) {} -void ServerGroupChatRoom::removeParticipant (const shared_ptr &) {} +void ServerGroupChatRoom::removeParticipant (const shared_ptr &participant) {} void ServerGroupChatRoom::removeParticipants (const list> &) {} diff --git a/src/chat/chat-room/server-group-chat-room.h b/src/chat/chat-room/server-group-chat-room.h index 57d49dcfc..c31eda2c6 100644 --- a/src/chat/chat-room/server-group-chat-room.h +++ b/src/chat/chat-room/server-group-chat-room.h @@ -68,7 +68,7 @@ public: bool hasMedia ) override; - void removeParticipant (const std::shared_ptr &participant) override; + void removeParticipant (const std::shared_ptr &participant) override; void removeParticipants (const std::list> &participants) override; std::shared_ptr findParticipant (const IdentityAddress &participantAddress) const override; diff --git a/src/conference/conference-interface.h b/src/conference/conference-interface.h index aacf6bfab..cf694327a 100644 --- a/src/conference/conference-interface.h +++ b/src/conference/conference-interface.h @@ -55,7 +55,7 @@ public: virtual const std::string &getSubject () const = 0; virtual void join () = 0; virtual void leave () = 0; - virtual void removeParticipant (const std::shared_ptr &participant) = 0; + virtual void removeParticipant (const std::shared_ptr &participant) = 0; virtual void removeParticipants (const std::list> &participants) = 0; virtual void setParticipantAdminStatus (const std::shared_ptr &participant, bool isAdmin) = 0; virtual void setSubject (const std::string &subject) = 0; diff --git a/src/conference/conference.cpp b/src/conference/conference.cpp index 9e22d0207..3f362552a 100644 --- a/src/conference/conference.cpp +++ b/src/conference/conference.cpp @@ -19,8 +19,12 @@ #include "conference-p.h" #include "conference/session/call-session-p.h" +#include "content/content.h" +#include "content/content-disposition.h" +#include "content/content-type.h" #include "logger/logger.h" #include "participant-p.h" +#include "xml/resource-lists.h" // ============================================================================= @@ -97,7 +101,7 @@ void Conference::join () {} void Conference::leave () {} -void Conference::removeParticipant (const shared_ptr &participant) { +void Conference::removeParticipant (const shared_ptr &participant) { lError() << "Conference class does not handle removeParticipant() generically"; } @@ -154,6 +158,8 @@ shared_ptr Conference::findParticipantDevice (const shared_pt return nullptr; } +// ----------------------------------------------------------------------------- + bool Conference::isMe (const IdentityAddress &addr) const { L_D(); IdentityAddress cleanedAddr(addr); @@ -163,4 +169,46 @@ bool Conference::isMe (const IdentityAddress &addr) const { return cleanedMeAddr == cleanedAddr; } +// ----------------------------------------------------------------------------- + +string Conference::getResourceLists (const list &addresses) const { + Xsd::ResourceLists::ResourceLists rl = Xsd::ResourceLists::ResourceLists(); + Xsd::ResourceLists::ListType l = Xsd::ResourceLists::ListType(); + for (const auto &addr : addresses) { + Xsd::ResourceLists::EntryType entry = Xsd::ResourceLists::EntryType(addr.asString()); + l.getEntry().push_back(entry); + } + rl.getList().push_back(l); + + Xsd::XmlSchema::NamespaceInfomap map; + stringstream xmlBody; + serializeResourceLists(xmlBody, rl, map); + return xmlBody.str(); +} + +// ----------------------------------------------------------------------------- + +list Conference::parseResourceLists (const Content &content) { + if ((content.getContentType() == ContentType::ResourceLists) + && ((content.getContentDisposition().weakEqual(ContentDisposition::RecipientList)) + || (content.getContentDisposition().weakEqual(ContentDisposition::RecipientListHistory)) + ) + ) { + istringstream data(content.getBodyAsString()); + unique_ptr rl(Xsd::ResourceLists::parseResourceLists( + data, + Xsd::XmlSchema::Flags::dont_validate + )); + list addresses; + for (const auto &l : rl->getList()) { + for (const auto &entry : l.getEntry()) { + IdentityAddress addr(entry.getUri()); + addresses.push_back(move(addr)); + } + } + return addresses; + } + return list(); +} + LINPHONE_END_NAMESPACE diff --git a/src/conference/conference.h b/src/conference/conference.h index 0df0ae998..a5ee6643b 100644 --- a/src/conference/conference.h +++ b/src/conference/conference.h @@ -34,6 +34,7 @@ class CallSession; class CallSessionListener; class CallSessionPrivate; class ConferencePrivate; +class Content; class ParticipantDevice; class LINPHONE_PUBLIC Conference : @@ -62,11 +63,14 @@ public: const std::string &getSubject () const override; void join () override; void leave () override; - void removeParticipant (const std::shared_ptr &participant) override; + void removeParticipant (const std::shared_ptr &participant) override; void removeParticipants (const std::list> &participants) override; void setParticipantAdminStatus (const std::shared_ptr &participant, bool isAdmin) override; void setSubject (const std::string &subject) override; + std::string getResourceLists (const std::list &addresses) const; + static std::list parseResourceLists (const Content &content); + protected: explicit Conference ( ConferencePrivate &p, diff --git a/src/conference/local-conference.cpp b/src/conference/local-conference.cpp index 847400131..def610da1 100644 --- a/src/conference/local-conference.cpp +++ b/src/conference/local-conference.cpp @@ -17,14 +17,10 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#include "content/content.h" -#include "content/content-disposition.h" -#include "content/content-type.h" #include "handlers/local-conference-event-handler.h" #include "local-conference-p.h" #include "logger/logger.h" #include "participant-p.h" -#include "xml/resource-lists.h" // ============================================================================= @@ -59,7 +55,7 @@ void LocalConference::addParticipant (const IdentityAddress &addr, const CallSes d->activeParticipant = participant; } -void LocalConference::removeParticipant (const shared_ptr &participant) { +void LocalConference::removeParticipant (const shared_ptr &participant) { L_D(); for (const auto &p : d->participants) { if (participant->getAddress() == p->getAddress()) { @@ -69,25 +65,4 @@ void LocalConference::removeParticipant (const shared_ptr &pa } } -list LocalConference::parseResourceLists (const Content &content) { - if ((content.getContentType() == ContentType::ResourceLists) - && (content.getContentDisposition() == ContentDisposition::RecipientList) - ) { - istringstream data(content.getBodyAsString()); - unique_ptr rl(Xsd::ResourceLists::parseResourceLists( - data, - Xsd::XmlSchema::Flags::dont_validate - )); - list addresses; - for (const auto &l : rl->getList()) { - for (const auto &entry : l.getEntry()) { - IdentityAddress addr(entry.getUri()); - addresses.push_back(move(addr)); - } - } - return addresses; - } - return list(); -} - LINPHONE_END_NAMESPACE diff --git a/src/conference/local-conference.h b/src/conference/local-conference.h index 7dee773e4..d926ecf54 100644 --- a/src/conference/local-conference.h +++ b/src/conference/local-conference.h @@ -26,7 +26,6 @@ LINPHONE_BEGIN_NAMESPACE -class Content; class LocalConferencePrivate; class LocalConference : public Conference { @@ -38,9 +37,7 @@ public: /* ConferenceInterface */ void addParticipant (const IdentityAddress &addr, const CallSessionParams *params, bool hasMedia) override; - void removeParticipant (const std::shared_ptr &participant) override; - - static std::list parseResourceLists (const Content &content); + void removeParticipant (const std::shared_ptr &participant) override; private: L_DECLARE_PRIVATE(LocalConference); diff --git a/src/conference/participant-device.cpp b/src/conference/participant-device.cpp index 4c147a38d..c6cbcc197 100644 --- a/src/conference/participant-device.cpp +++ b/src/conference/participant-device.cpp @@ -29,7 +29,7 @@ LINPHONE_BEGIN_NAMESPACE ParticipantDevice::ParticipantDevice () {} -ParticipantDevice::ParticipantDevice (const Participant *participant, const IdentityAddress &gruu) +ParticipantDevice::ParticipantDevice (Participant *participant, const IdentityAddress &gruu) : mParticipant(participant), mGruu(gruu) {} ParticipantDevice::~ParticipantDevice () { diff --git a/src/conference/participant-device.h b/src/conference/participant-device.h index e10da6394..284c83917 100644 --- a/src/conference/participant-device.h +++ b/src/conference/participant-device.h @@ -44,13 +44,13 @@ public: }; ParticipantDevice (); - explicit ParticipantDevice (const Participant *participant, const IdentityAddress &gruu); + explicit ParticipantDevice (Participant *participant, const IdentityAddress &gruu); virtual ~ParticipantDevice (); bool operator== (const ParticipantDevice &device) const; inline const IdentityAddress &getAddress () const { return mGruu; } - const Participant *getParticipant () const { return mParticipant; } + Participant *getParticipant () const { return mParticipant; } inline std::shared_ptr getSession () const { return mSession; } inline void setSession (std::shared_ptr session) { mSession = session; } inline State getState () const { return mState; } @@ -63,7 +63,7 @@ public: bool isValid () const { return mGruu.isValid(); } private: - const Participant *mParticipant = nullptr; + Participant *mParticipant = nullptr; IdentityAddress mGruu; std::shared_ptr mSession; LinphoneEvent *mConferenceSubscribeEvent = nullptr; diff --git a/src/conference/remote-conference.cpp b/src/conference/remote-conference.cpp index ffdcde9ab..537832189 100644 --- a/src/conference/remote-conference.cpp +++ b/src/conference/remote-conference.cpp @@ -21,7 +21,6 @@ #include "logger/logger.h" #include "participant-p.h" #include "remote-conference-p.h" -#include "xml/resource-lists.h" // ============================================================================= @@ -59,7 +58,7 @@ void RemoteConference::addParticipant (const IdentityAddress &addr, const CallSe d->activeParticipant = participant; } -void RemoteConference::removeParticipant (const shared_ptr &participant) { +void RemoteConference::removeParticipant (const shared_ptr &participant) { L_D(); for (const auto &p : d->participants) { if (participant->getAddress() == p->getAddress()) { @@ -69,21 +68,6 @@ void RemoteConference::removeParticipant (const shared_ptr &p } } -string RemoteConference::getResourceLists (const list &addresses) const { - Xsd::ResourceLists::ResourceLists rl = Xsd::ResourceLists::ResourceLists(); - Xsd::ResourceLists::ListType l = Xsd::ResourceLists::ListType(); - for (const auto &addr : addresses) { - Xsd::ResourceLists::EntryType entry = Xsd::ResourceLists::EntryType(addr.asString()); - l.getEntry().push_back(entry); - } - rl.getList().push_back(l); - - Xsd::XmlSchema::NamespaceInfomap map; - stringstream xmlBody; - serializeResourceLists(xmlBody, rl, map); - return xmlBody.str(); -} - // ----------------------------------------------------------------------------- void RemoteConference::onConferenceCreated (const IdentityAddress &) {} diff --git a/src/conference/remote-conference.h b/src/conference/remote-conference.h index 1dd2b5931..3490113e5 100644 --- a/src/conference/remote-conference.h +++ b/src/conference/remote-conference.h @@ -38,9 +38,7 @@ public: /* ConferenceInterface */ void addParticipant (const IdentityAddress &addr, const CallSessionParams *params, bool hasMedia) override; - void removeParticipant (const std::shared_ptr &participant) override; - - std::string getResourceLists (const std::list &addresses) const; + void removeParticipant (const std::shared_ptr &participant) override; protected: /* ConferenceListener */ diff --git a/src/content/content-disposition.cpp b/src/content/content-disposition.cpp index ccaf7da15..1a14d9bd7 100644 --- a/src/content/content-disposition.cpp +++ b/src/content/content-disposition.cpp @@ -63,10 +63,13 @@ ContentDisposition &ContentDisposition::operator= (const ContentDisposition &oth return *this; } -bool ContentDisposition::operator== (const ContentDisposition &other) const { +bool ContentDisposition::weakEqual (const ContentDisposition &other) const { L_D(); - return d->disposition == other.getPrivate()->disposition - && getParameter() == other.getParameter(); + return d->disposition == other.getPrivate()->disposition; +} + +bool ContentDisposition::operator== (const ContentDisposition &other) const { + return weakEqual(other) && (getParameter() == other.getParameter()); } bool ContentDisposition::operator!= (const ContentDisposition &other) const { diff --git a/src/content/content-disposition.h b/src/content/content-disposition.h index 6f2fcc9ca..9021f0e2c 100644 --- a/src/content/content-disposition.h +++ b/src/content/content-disposition.h @@ -35,6 +35,7 @@ public: ContentDisposition &operator= (const ContentDisposition &other); + bool weakEqual (const ContentDisposition &other) const; bool operator== (const ContentDisposition &other) const; bool operator!= (const ContentDisposition &other) const; diff --git a/src/content/content-type.cpp b/src/content/content-type.cpp index 78c356af6..34ca68d0e 100644 --- a/src/content/content-type.cpp +++ b/src/content/content-type.cpp @@ -103,10 +103,12 @@ ContentType &ContentType::operator= (const ContentType &other) { return *this; } +bool ContentType::weakEqual (const ContentType &other) const { + return (getType() == other.getType()) && (getSubType() == other.getSubType()); +} + bool ContentType::operator== (const ContentType &other) const { - return getType() == other.getType() && - getSubType() == other.getSubType() && - getParameter() == other.getParameter(); + return weakEqual(other) && (getParameter() == other.getParameter()); } bool ContentType::operator!= (const ContentType &other) const { diff --git a/src/content/content-type.h b/src/content/content-type.h index b13063115..ea4fb980c 100644 --- a/src/content/content-type.h +++ b/src/content/content-type.h @@ -37,6 +37,7 @@ public: ContentType &operator= (const ContentType &other); + bool weakEqual (const ContentType &other) const; bool operator== (const ContentType &other) const; bool operator!= (const ContentType &other) const; diff --git a/src/core/core-chat-room.cpp b/src/core/core-chat-room.cpp index 291c2a600..b02d072bf 100644 --- a/src/core/core-chat-room.cpp +++ b/src/core/core-chat-room.cpp @@ -100,7 +100,7 @@ shared_ptr CorePrivate::createBasicChatRoom ( return chatRoom; } -shared_ptr CorePrivate::createClientGroupChatRoom (const string &subject, const string &uri, bool fallback) { +shared_ptr CorePrivate::createClientGroupChatRoom (const string &subject, const string &uri, const Content &content, bool fallback) { L_Q(); string usedUri; @@ -135,7 +135,7 @@ shared_ptr CorePrivate::createClientGroupChatRoom (const strin shared_ptr chatRoom; { shared_ptr clientGroupChatRoom = make_shared( - q->getSharedFromThis(), usedUri, IdentityAddress(from), subject + q->getSharedFromThis(), usedUri, IdentityAddress(from), subject, content ); ClientGroupChatRoomPrivate *dClientGroupChatRoom = clientGroupChatRoom->getPrivate(); diff --git a/src/core/core-p.h b/src/core/core-p.h index 0106dd502..cfd5e5755 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, const std::string &uri = "", bool fallback = true); + std::shared_ptr createClientGroupChatRoom (const std::string &subject, const std::string &uri = "", const Content &content = Content(), bool fallback = true); void replaceChatRoom (const std::shared_ptr &replacedChatRoom, const std::shared_ptr &newChatRoom); std::unique_ptr mainDb; diff --git a/src/sal/call-op.cpp b/src/sal/call-op.cpp index a900ab5d8..f28a096fa 100644 --- a/src/sal/call-op.cpp +++ b/src/sal/call-op.cpp @@ -237,7 +237,7 @@ void SalCallOp::cancelling_invite(const SalErrorInfo *info) { Content SalCallOp::extract_body(belle_sip_message_t *message) { Content body; belle_sip_header_content_type_t *content_type = belle_sip_message_get_header_by_type(message, belle_sip_header_content_type_t); - belle_sip_header_content_disposition_t *contentDisposition = belle_sip_message_get_header_by_type(message, belle_sip_header_content_disposition_t); + belle_sip_header_content_disposition_t *contentDispositionHeader = belle_sip_message_get_header_by_type(message, belle_sip_header_content_disposition_t); belle_sip_header_content_length_t *content_length = belle_sip_message_get_header_by_type(message, belle_sip_header_content_length_t); const char *type_str = content_type ? belle_sip_header_content_type_get_type(content_type) : NULL; const char *subtype_str = content_type ? belle_sip_header_content_type_get_subtype(content_type) : NULL; @@ -245,10 +245,13 @@ Content SalCallOp::extract_body(belle_sip_message_t *message) { const char *body_str = belle_sip_message_get_body(message); if (type_str && subtype_str) body.setContentType(ContentType(type_str, subtype_str)); - if (contentDisposition) - body.setContentDisposition( - ContentDisposition(belle_sip_header_content_disposition_get_content_disposition(contentDisposition)) - ); + if (contentDispositionHeader) { + auto contentDisposition = ContentDisposition(belle_sip_header_content_disposition_get_content_disposition(contentDispositionHeader)); + if (belle_sip_parameters_has_parameter(BELLE_SIP_PARAMETERS(contentDispositionHeader), "handling")) { + contentDisposition.setParameter("handling=" + string(belle_sip_parameters_get_parameter(BELLE_SIP_PARAMETERS(contentDispositionHeader), "handling"))); + } + body.setContentDisposition(contentDisposition); + } if (length > 0 && body_str) body.setBody(body_str, length); return body; } @@ -497,7 +500,9 @@ void SalCallOp::process_response_cb(void *op_base, const belle_sip_response_even } break; case BELLE_SIP_DIALOG_TERMINATED: { - if (strcmp("INVITE",method)==0 && code >= 300){ + if ((code >= 300) + && ((strcmp("INVITE", method) == 0) || (strcmp("BYE", method) == 0)) + ) { op->set_error(response, TRUE); } } diff --git a/src/utils/background-task.cpp b/src/utils/background-task.cpp index 0aaeb3397..b91a10f8d 100644 --- a/src/utils/background-task.cpp +++ b/src/utils/background-task.cpp @@ -27,6 +27,8 @@ // ============================================================================= +using namespace std; + LINPHONE_BEGIN_NAMESPACE void BackgroundTask::sHandleTimeout (void *context) { @@ -43,7 +45,7 @@ void BackgroundTask::handleSalTimeout () { stop(); } -void BackgroundTask::start (const std::shared_ptr &core, int maxDurationSeconds) { +void BackgroundTask::start (const shared_ptr &core, int maxDurationSeconds) { if (mName.empty()) { lError() << "No name was set on background task"; return; diff --git a/src/utils/background-task.h b/src/utils/background-task.h index 2567a5b6d..fbf11106f 100644 --- a/src/utils/background-task.h +++ b/src/utils/background-task.h @@ -35,23 +35,17 @@ class Core; class BackgroundTask { public: BackgroundTask () {} - BackgroundTask (const std::string &name) {} - virtual ~BackgroundTask () { - stop(); - } + BackgroundTask (const std::string &name) : mName(name) {} + virtual ~BackgroundTask () { stop(); } - void setName (const std::string &name) { - mName = name; - } + void setName (const std::string &name) { mName = name; } - const std::string &getName () const { - return mName; - } + const std::string &getName () const { return mName; } /** * Start a long running task for at most max_duration_seconds, after which it is automatically terminated */ - void start (const std::shared_ptr &core, int maxDurationSeconds = 15 * 60); // 15 min by default, like on iOS + void start (const std::shared_ptr &core, int maxDurationSeconds = 15 * 60); // 15 min by default, like on iOS void stop (); protected: diff --git a/tester/group_chat_tester.c b/tester/group_chat_tester.c index 9ddfc9329..14c0ab1d0 100644 --- a/tester/group_chat_tester.c +++ b/tester/group_chat_tester.c @@ -69,6 +69,7 @@ static void chat_room_participant_device_added (LinphoneChatRoom *cr, const Linp static void chat_room_state_changed (LinphoneChatRoom *cr, LinphoneChatRoomState newState) { LinphoneCore *core = linphone_chat_room_get_core(cr); LinphoneCoreManager *manager = (LinphoneCoreManager *)linphone_core_get_user_data(core); + ms_message("ChatRoom [%p] state changed: %d", cr, newState); switch (newState) { case LinphoneChatRoomStateNone: break; @@ -105,6 +106,12 @@ static void chat_room_subject_changed (LinphoneChatRoom *cr, const LinphoneEvent manager->stat.number_of_subject_changed++; } +static void chat_room_all_information_received (LinphoneChatRoom *cr) { + LinphoneCore *core = linphone_chat_room_get_core(cr); + LinphoneCoreManager *manager = (LinphoneCoreManager *)linphone_core_get_user_data(core); + manager->stat.number_of_LinphoneChatRoomAllInformationReceived++; +} + static void core_chat_room_state_changed (LinphoneCore *core, LinphoneChatRoom *cr, LinphoneChatRoomState state) { if (state == LinphoneChatRoomStateInstantiated) { LinphoneChatRoomCbs *cbs = linphone_factory_create_chat_room_cbs(linphone_factory_get()); @@ -115,6 +122,7 @@ static void core_chat_room_state_changed (LinphoneCore *core, LinphoneChatRoom * linphone_chat_room_cbs_set_state_changed(cbs, chat_room_state_changed); 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_cbs_set_all_information_received(cbs, chat_room_all_information_received); linphone_chat_room_add_callbacks(cr, cbs); linphone_chat_room_cbs_unref(cbs); } @@ -180,9 +188,9 @@ static void _send_file_plus_text(LinphoneChatRoom* cr, const char *sendFilepath, cbs = linphone_chat_message_get_callbacks(msg); 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_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(cr, msg); + linphone_chat_message_send(msg); linphone_content_unref(content); linphone_chat_message_unref(msg); } @@ -255,6 +263,7 @@ static void start_core_for_conference(bctbx_list_t *coreManagerList) { static LinphoneChatRoom * check_creation_chat_room_client_side(bctbx_list_t *lcs, LinphoneCoreManager *lcm, stats *initialStats, const LinphoneAddress *confAddr, const char* subject, int participantNumber, bool_t isAdmin) { BC_ASSERT_TRUE(wait_for_list(lcs, &lcm->stat.number_of_LinphoneChatRoomStateCreationPending, initialStats->number_of_LinphoneChatRoomStateCreationPending + 1, 5000)); BC_ASSERT_TRUE(wait_for_list(lcs, &lcm->stat.number_of_LinphoneChatRoomStateCreated, initialStats->number_of_LinphoneChatRoomStateCreated + 1, 10000)); + BC_ASSERT_TRUE(wait_for_list(lcs, &lcm->stat.number_of_LinphoneChatRoomAllInformationReceived, initialStats->number_of_LinphoneChatRoomAllInformationReceived + 1, 10000)); char *deviceIdentity = linphone_core_get_device_identity(lcm->lc); LinphoneAddress *localAddr = linphone_address_new(deviceIdentity); bctbx_free(deviceIdentity); @@ -284,6 +293,7 @@ static LinphoneChatRoom * create_chat_room_client_side(bctbx_list_t *lcs, Linpho // Check that the chat room is correctly created on Marie's side and that the participants are added BC_ASSERT_TRUE(wait_for_list(lcs, &lcm->stat.number_of_LinphoneChatRoomStateCreationPending, initialStats->number_of_LinphoneChatRoomStateCreationPending + 1, 10000)); BC_ASSERT_TRUE(wait_for_list(lcs, &lcm->stat.number_of_LinphoneChatRoomStateCreated, initialStats->number_of_LinphoneChatRoomStateCreated + 1, 10000)); + BC_ASSERT_TRUE(wait_for_list(lcs, &lcm->stat.number_of_LinphoneChatRoomAllInformationReceived, initialStats->number_of_LinphoneChatRoomAllInformationReceived + 1, 10000)); BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(chatRoom), (expectedParticipantSize >= 0) ? expectedParticipantSize : (int)bctbx_list_size(participantsAddresses), int, "%d"); @@ -1528,13 +1538,14 @@ static void group_chat_room_reinvited_after_removed_base (bool_t offline_when_re bctbx_list_t *tmpCoresManagerList = bctbx_list_append(NULL, laure); 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_concat(coresList, tmpCoresList); coresManagerList = bctbx_list_append(coresManagerList, laure); } if (!offline_when_reinvited) BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneChatRoomStateTerminated, initialLaureStats.number_of_LinphoneChatRoomStateTerminated + 1, 3000)); + wait_for_list(coresList,0, 1, 2000); + initialLaureStats = laure->stat; // Marie adds Laure to the chat room participantsAddresses = bctbx_list_append(participantsAddresses, laureAddr); @@ -1550,16 +1561,13 @@ static void group_chat_room_reinvited_after_removed_base (bool_t offline_when_re bctbx_list_t *tmpCoresManagerList = bctbx_list_append(NULL, laure); 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_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)); - } else { - 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 + 1, 5000)); } + 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 + 1, 5000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneChatRoomAllInformationReceived, initialLaureStats.number_of_LinphoneChatRoomAllInformationReceived + 1, 5000)); 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"); char *laureIdentity = linphone_core_get_device_identity(laure->lc); @@ -2301,12 +2309,14 @@ static void group_chat_room_migrate_from_basic_chat_room (void) { 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(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomAllInformationReceived, initialMarieStats.number_of_LinphoneChatRoomAllInformationReceived + 1, 10000)); BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(marieCr) & LinphoneChatRoomCapabilitiesConference); BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(marieCr), 1, int, "%d"); BC_ASSERT_EQUAL(linphone_chat_room_get_history_size(marieCr), 2, int, "%d"); BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneChatRoomStateCreationPending, initialPaulineStats.number_of_LinphoneChatRoomStateCreationPending + 1, 10000)); BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneChatRoomStateCreated, initialPaulineStats.number_of_LinphoneChatRoomStateCreated + 1, 10000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneChatRoomAllInformationReceived, initialPaulineStats.number_of_LinphoneChatRoomAllInformationReceived + 1, 10000)); BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(paulineCr) & LinphoneChatRoomCapabilitiesConference); BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(paulineCr), 1, int, "%d"); BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived + 1, 1000)); @@ -2440,12 +2450,14 @@ static void group_chat_room_migrate_from_basic_to_client_fail (void) { linphone_chat_message_send(msg); BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateCreationPending, initialMarieStats.number_of_LinphoneChatRoomStateCreationPending + 2, 10000)); BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateCreated, initialMarieStats.number_of_LinphoneChatRoomStateCreated + 1, 10000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomAllInformationReceived, initialMarieStats.number_of_LinphoneChatRoomAllInformationReceived + 1, 10000)); BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(marieCr) & LinphoneChatRoomCapabilitiesConference); BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(marieCr), 1, int, "%d"); BC_ASSERT_EQUAL(linphone_chat_room_get_history_size(marieCr), 5, int, "%d"); BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneChatRoomStateCreationPending, initialPaulineStats.number_of_LinphoneChatRoomStateCreationPending + 1, 10000)); BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneChatRoomStateCreated, initialPaulineStats.number_of_LinphoneChatRoomStateCreated + 1, 10000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneChatRoomAllInformationReceived, initialPaulineStats.number_of_LinphoneChatRoomAllInformationReceived + 1, 10000)); BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(paulineCr) & LinphoneChatRoomCapabilitiesConference); BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(paulineCr), 1, int, "%d"); BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived + 3, 1000)); @@ -2792,10 +2804,10 @@ static void group_chat_room_unique_one_to_one_chat_room_recreated_from_message_w static void group_chat_room_unique_one_to_one_chat_room_recreated_from_message_2 (void) { LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc"); LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc"); - /*create a second device for marie, but it is inactive after registration in this test*/ + // Create a second device for Marie, but it is inactive after registration in this test LinphoneCoreManager *marie2 = linphone_core_manager_create("marie_rc"); - /*Create a seconde device for pauline, but again inactivate after registration*/ - LinphoneCoreManager *pauline2 = linphone_core_manager_create("marie_rc"); + // Create a second device for Pauline, but again inactivate it after registration + LinphoneCoreManager *pauline2 = linphone_core_manager_create("pauline_rc"); bctbx_list_t *coresManagerList = NULL; bctbx_list_t *participantsAddresses = NULL; coresManagerList = bctbx_list_append(coresManagerList, marie); @@ -2807,6 +2819,8 @@ static void group_chat_room_unique_one_to_one_chat_room_recreated_from_message_2 participantsAddresses = bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc))); stats initialMarieStats = marie->stat; stats initialPaulineStats = pauline->stat; + stats initialMarie2Stats = marie2->stat; + stats initialPauline2Stats = pauline2->stat; linphone_core_set_network_reachable(marie2->lc, FALSE); linphone_core_set_network_reachable(pauline2->lc, FALSE); @@ -2852,13 +2866,22 @@ static void group_chat_room_unique_one_to_one_chat_room_recreated_from_message_2 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), textMessage); linphone_chat_message_unref(message); - - // Clean db from chat room - linphone_core_manager_delete_chat_room(marie, marieCr, coresList); } - linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList); - wait_for_list(coresList, 0, 1, 2000); + // Clean db from chat room + linphone_core_set_network_reachable(marie2->lc, TRUE); + linphone_core_set_network_reachable(pauline2->lc, TRUE); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie2->stat.number_of_LinphoneChatRoomStateCreationPending, initialMarie2Stats.number_of_LinphoneChatRoomStateCreationPending + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie2->stat.number_of_LinphoneChatRoomStateCreated, initialMarie2Stats.number_of_LinphoneChatRoomStateCreated + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline2->stat.number_of_LinphoneChatRoomStateCreationPending, initialPauline2Stats.number_of_LinphoneChatRoomStateCreationPending + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline2->stat.number_of_LinphoneChatRoomStateCreated, initialPauline2Stats.number_of_LinphoneChatRoomStateCreated + 1, 3000)); + linphone_core_manager_delete_chat_room(marie, marieCr, coresList); + linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateTerminated, initialMarieStats.number_of_LinphoneChatRoomStateTerminated + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneChatRoomStateTerminated, initialPaulineStats.number_of_LinphoneChatRoomStateTerminated + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie2->stat.number_of_LinphoneChatRoomStateTerminated, initialMarie2Stats.number_of_LinphoneChatRoomStateTerminated + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline2->stat.number_of_LinphoneChatRoomStateTerminated, initialPauline2Stats.number_of_LinphoneChatRoomStateTerminated + 1, 3000)); + BC_ASSERT_EQUAL(linphone_core_get_call_history_size(marie->lc), 0, int,"%i"); BC_ASSERT_EQUAL(linphone_core_get_call_history_size(pauline->lc), 0, int,"%i"); BC_ASSERT_PTR_NULL(linphone_core_get_call_logs(marie->lc)); @@ -2867,8 +2890,6 @@ static void group_chat_room_unique_one_to_one_chat_room_recreated_from_message_2 linphone_address_unref(confAddr); bctbx_list_free(coresList); bctbx_list_free(coresManagerList); - linphone_core_set_network_reachable(marie2->lc, TRUE); - linphone_core_set_network_reachable(pauline2->lc, TRUE); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); linphone_core_manager_destroy(marie2); @@ -2947,6 +2968,9 @@ static void group_chat_room_join_one_to_one_chat_room_with_a_new_device (void) { linphone_chat_message_unref(message); // Clean db from chat room + int previousNbRegistrationOk = marie1->stat.number_of_LinphoneRegistrationOk; + linphone_core_set_network_reachable(marie1->lc, TRUE); + wait_for_until(marie1->lc, NULL, &marie1->stat.number_of_LinphoneRegistrationOk, previousNbRegistrationOk + 1, 2000); linphone_core_manager_delete_chat_room(marie2, marie2Cr, coresList); linphone_core_delete_chat_room(marie1->lc, marie1Cr); linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList); @@ -3272,7 +3296,7 @@ test_t group_chat_tests[] = { 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_ONE_TAG("Join one-to-one chat room with a new device", group_chat_room_join_one_to_one_chat_room_with_a_new_device, "LeaksMemory"), 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), diff --git a/tester/liblinphone_tester.h b/tester/liblinphone_tester.h index 9824c2084..ac42e1714 100644 --- a/tester/liblinphone_tester.h +++ b/tester/liblinphone_tester.h @@ -182,6 +182,7 @@ typedef struct _stats { int number_of_LinphoneIsComposingIdleReceived; int progress_of_LinphoneFileTransfer; + int number_of_LinphoneChatRoomAllInformationReceived; int number_of_LinphoneChatRoomStateInstantiated; int number_of_LinphoneChatRoomStateCreationPending; int number_of_LinphoneChatRoomStateCreated;