From a7ada2076a0315ba420b33b999e94d107879fa61 Mon Sep 17 00:00:00 2001 From: Andrea Gianarda <andrea.gianarda@belledonne-communications.com> Date: Mon, 24 Feb 2025 14:52:54 +0100 Subject: [PATCH] Create tchat within a conference only after receiving the NOTIFY full state --- src/conference/client-conference.cpp | 4 ++-- src/db/main-db.cpp | 16 ++++++++-------- tester/group_chat_tester.c | 10 +++++++++- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/conference/client-conference.cpp b/src/conference/client-conference.cpp index fdab0fca27..4f33d69ee6 100644 --- a/src/conference/client-conference.cpp +++ b/src/conference/client-conference.cpp @@ -195,11 +195,11 @@ void ClientConference::init(SalCallOp *op, BCTBX_UNUSED(ConferenceListener *conf mPendingSubject = mConfParams->getUtf8Subject(); mConfParams->enableLocalParticipant(false); - if (mConfParams->chatEnabled()) { #ifdef HAVE_ADVANCED_IM + if (isChatOnly()) { setChatRoom((new ClientChatRoom(core, getSharedFromThis()))->toSharedPtr()); -#endif // HAVE_ADVANCED_IM } +#endif // HAVE_ADVANCED_IM if (supportsMedia()) { getMe()->setAdmin((focusSession == nullptr) || (organizerAddress == nullptr) || diff --git a/src/db/main-db.cpp b/src/db/main-db.cpp index 0e6bd60b52..5bdf60abd6 100644 --- a/src/db/main-db.cpp +++ b/src/db/main-db.cpp @@ -6266,13 +6266,13 @@ list<shared_ptr<AbstractChatRoom>> MainDb::getChatRooms() { chatRoom->setUtf8Subject(subject); } else if (backend == ChatParams::Backend::FlexisipChat) { #ifdef HAVE_ADVANCED_IM + const auto &localAddress = conferenceId.getLocalAddress(); unsigned int lastNotifyId = d->dbSession.getUnsignedInt(row, 7, 0); list<shared_ptr<Participant>> participants = selectChatRoomParticipants(dbChatRoomId); const auto meIt = - std::find_if(participants.begin(), participants.end(), - [&localAddress = conferenceId.getLocalAddress()](const auto &participant) { - return (participant->getAddress()->weakEqual(*localAddress)); - }); + std::find_if(participants.begin(), participants.end(), [&localAddress](const auto &participant) { + return (participant->getAddress()->weakEqual(*localAddress)); + }); shared_ptr<Participant> me; if (meIt != participants.end()) { me = *meIt; @@ -6310,8 +6310,7 @@ list<shared_ptr<AbstractChatRoom>> MainDb::getChatRooms() { std::shared_ptr<Conference> conference = nullptr; if (serverMode) { params->enableLocalParticipant(false); - conference = - (new ServerConference(core, conferenceId.getLocalAddress(), nullptr, params))->toSharedPtr(); + conference = (new ServerConference(core, localAddress, nullptr, params))->toSharedPtr(); conference->initFromDb(me, conferenceId, lastNotifyId, false); chatRoom = conference->getChatRoom(); conference->setState(ConferenceInterface::State::Created); @@ -6341,10 +6340,11 @@ list<shared_ptr<AbstractChatRoom>> MainDb::getChatRooms() { soci::rowset<soci::row> rows = (session->prepare << query, soci::use(dbChatRoomId)); for (const auto &row : rows) { ConferenceId previousId = ConferenceId(Address::create(row.get<string>(0), true), - conferenceId.getLocalAddress(), conferenceIdParams); + localAddress, conferenceIdParams); if (previousId != conferenceId) { lInfo() << "Keeping around previous chat room ID [" << previousId - << "] in case BYE is received for exhumed chat room [" << conferenceId << "]"; + << "] in case BYE is received for exhumed chat room " << *conference << " [" + << conferenceId << "]"; auto clientChatRoom = dynamic_pointer_cast<ClientChatRoom>(chatRoom); clientChatRoom->addConferenceIdToPreviousList(previousId); } diff --git a/tester/group_chat_tester.c b/tester/group_chat_tester.c index b03b0ea9e3..3f40af1945 100644 --- a/tester/group_chat_tester.c +++ b/tester/group_chat_tester.c @@ -322,7 +322,15 @@ void setup_chat_room_callbacks(LinphoneChatRoomCbs *cbs) { } void core_chat_room_state_changed(BCTBX_UNUSED(LinphoneCore *core), LinphoneChatRoom *cr, LinphoneChatRoomState state) { - if (state == LinphoneChatRoomStateInstantiated) { + const LinphoneConferenceParams *chat_params = linphone_chat_room_get_current_params(cr); + bool hasAudio = !!linphone_conference_params_audio_enabled(chat_params) || + !!linphone_conference_params_video_enabled(chat_params); + // When a chatroom is instantied as part of a conference, the first state it will be notifed is the Created state as + // the core waits for the full state to arrive before creating it. In fact, it may happen that a core wishes to + // create a conference with chat capabilities but the server doesn't supports it. The client would end up having a + // dangling tchat and needs to destroy it + if ((!hasAudio && (state == LinphoneChatRoomStateInstantiated)) || + (hasAudio && (state == LinphoneChatRoomStateCreated))) { LinphoneChatRoomCbs *cbs = linphone_factory_create_chat_room_cbs(linphone_factory_get()); setup_chat_room_callbacks(cbs); linphone_chat_room_add_callbacks(cr, cbs); -- GitLab