diff --git a/coreapi/conference.cpp b/coreapi/conference.cpp index d113399dd6437b89aa7f2ccd3411bb420692df26..276abd0032a90109b4908ea5048397719dcf2a9e 100644 --- a/coreapi/conference.cpp +++ b/coreapi/conference.cpp @@ -255,10 +255,10 @@ void Conference::setConferenceAddress(const std::shared_ptr<Address> &conference LinphonePrivate::Conference::setConferenceAddress(conferenceAddress); setState(ConferenceInterface::State::CreationPending); - lInfo() << "Conference " << this << " has been given the address " << conferenceAddress; + lInfo() << "Conference " << this << " has been given the address " << *conferenceAddress; } else { lDebug() << "Cannot set the conference address of the Conference in state " << getState() << " to " - << conferenceAddress; + << *conferenceAddress; return; } } diff --git a/coreapi/local_conference.cpp b/coreapi/local_conference.cpp index 1127d0163dc77b7202c62aa7e739d6d89a834404..518a44e419b5555daa0249bd85d21b95abbe6b9c 100644 --- a/coreapi/local_conference.cpp +++ b/coreapi/local_conference.cpp @@ -18,7 +18,8 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "local_conference.h" +#include <tuple> + #include "call/call-log.h" #include "conference/params/media-session-params-p.h" #include "conference/participant-info.h" @@ -28,6 +29,7 @@ #include "core/core-p.h" #include "db/main-db.h" #include "factory/factory.h" +#include "local_conference.h" #ifdef HAVE_ADVANCED_IM #include "conference/handlers/local-audio-video-conference-event-handler.h" #endif // HAVE_ADVANCED_IM @@ -167,6 +169,12 @@ void LocalConference::updateConferenceInformation(SalCallOp *op) { const auto &remoteMd = op->getRemoteMediaDescription(); const auto times = remoteMd->times; + time_t startTime = -1, endTime = -1; + if (times.size() > 0) { + std::tie(startTime, endTime) = times.front(); + confParams->setStartTime(startTime); + confParams->setEndTime(endTime); + } // The following informations are retrieved from the received INVITE: // - start and end time from the SDP active time attribute @@ -201,15 +209,11 @@ void LocalConference::updateConferenceInformation(SalCallOp *op) { auto session = const_pointer_cast<LinphonePrivate::MediaSession>( static_pointer_cast<LinphonePrivate::MediaSession>(getMe()->getSession())); - auto msp = session->getPrivate()->getParams(); - msp->enableAudio(audioEnabled); - msp->enableVideo(videoEnabled); - msp->getPrivate()->setInConference(true); - - if (times.size() > 0) { - const auto [startTime, endTime] = times.front(); - confParams->setStartTime(startTime); - confParams->setEndTime(endTime); + if (session) { + auto msp = session->getPrivate()->getParams(); + msp->enableAudio(audioEnabled); + msp->enableVideo(videoEnabled); + msp->getPrivate()->setInConference(true); msp->getPrivate()->setStartTime(startTime); msp->getPrivate()->setEndTime(endTime); } @@ -241,10 +245,12 @@ void LocalConference::updateConferenceInformation(SalCallOp *op) { conferenceInfoId = mainDb->insertConferenceInfo(conferenceInfo); } #endif - auto callLog = session->getLog(); - if (callLog) { - callLog->setConferenceInfo(conferenceInfo); - callLog->setConferenceInfoId(conferenceInfoId); + if (session) { + auto callLog = session->getLog(); + if (callLog) { + callLog->setConferenceInfo(conferenceInfo); + callLog->setConferenceInfoId(conferenceInfoId); + } } if (isEmpty) { setState(ConferenceInterface::State::TerminationPending); @@ -402,9 +408,9 @@ void LocalConference::configure(SalCallOp *op) { conferenceAddress = info->getUri(); } else if (admin) { conferenceAddress = Address::create(op->getTo()); + shared_ptr<CallSession> session = getMe()->createSession(*this, &msp, true, nullptr); + session->configure(LinphoneCallIncoming, nullptr, op, organizer, conferenceAddress); } - shared_ptr<CallSession> session = getMe()->createSession(*this, &msp, true, nullptr); - session->configure(LinphoneCallIncoming, nullptr, op, organizer, conferenceAddress); } me->setRole(Participant::Role::Speaker); @@ -419,9 +425,12 @@ void LocalConference::configure(SalCallOp *op) { if (isUpdate) { const auto &conferenceInfo = createOrGetConferenceInfo(); - auto callLog = getMe()->getSession()->getLog(); - if (callLog) { - callLog->setConferenceInfo(conferenceInfo); + auto meSession = getMe()->getSession(); + if (meSession) { + auto callLog = meSession->getLog(); + if (callLog) { + callLog->setConferenceInfo(conferenceInfo); + } } updateConferenceInformation(op); } @@ -554,7 +563,7 @@ void LocalConference::finalizeCreation() { } } else { lInfo() << "Conference " << *conferenceAddress - << " has already been created therefore no need to arry out the redirection to its address"; + << " has already been created therefore no need to carry out the redirection to its address"; } } else { lError() << "Session of the me participant " << *me->getAddress() << " of conference " << *conferenceAddress @@ -1228,6 +1237,10 @@ bool LocalConference::addParticipant(std::shared_ptr<LinphonePrivate::Call> call auto contactAddress = session->getContactAddress(); tryAddMeDevice(); + if (!mMixerSession) { + mMixerSession.reset(new MixerSession(*getCore().get())); + } + // Add participant to the conference participant list switch (state) { case LinphoneCallOutgoingInit: @@ -1694,22 +1707,25 @@ bool LocalConference::removeParticipant(const std::shared_ptr<LinphonePrivate::P } void LocalConference::checkIfTerminated() { - if (!confParams->isStatic() && (getParticipantCount() == 0)) { - leave(); - if (getState() == ConferenceInterface::State::TerminationPending) { - setState(ConferenceInterface::State::Terminated); - } else { - setState(ConferenceInterface::State::TerminationPending); + if (getParticipantCount() == 0) { + if (!confParams->isStatic()) { + leave(); + if (getState() == ConferenceInterface::State::TerminationPending) { + setState(ConferenceInterface::State::Terminated); + } else { + setState(ConferenceInterface::State::TerminationPending); #ifdef HAVE_ADVANCED_IM - bool_t eventLogEnabled = linphone_config_get_bool(linphone_core_get_config(getCore()->getCCore()), "misc", - "conference_event_log_enabled", TRUE); - if (!eventLogEnabled || !eventHandler) { + bool_t eventLogEnabled = linphone_config_get_bool(linphone_core_get_config(getCore()->getCCore()), + "misc", "conference_event_log_enabled", TRUE); + if (!eventLogEnabled || !eventHandler) { #endif // HAVE_ADVANCED_IM - setState(ConferenceInterface::State::Terminated); + setState(ConferenceInterface::State::Terminated); #ifdef HAVE_ADVANCED_IM - } + } #endif // HAVE_ADVANCED_IM + } } + mMixerSession.reset(); } } diff --git a/tester/local_conference_edition_tester.cpp b/tester/local_conference_edition_tester.cpp index b3ca9070665795ae69e91f28bf8f550d5568d045..e8fa1cd4826e175d90b0f7f1e7c3e1863fff4998 100644 --- a/tester/local_conference_edition_tester.cpp +++ b/tester/local_conference_edition_tester.cpp @@ -1274,6 +1274,10 @@ static void conference_cancelled_through_edit_base(bool_t server_restart) { coresList = bctbx_list_append(coresList, laure.getLc()); coresList = bctbx_list_append(coresList, michelle.getLc()); + std::list<LinphoneCoreManager *> conferenceMgrs{focus.getCMgr(), marie.getCMgr(), michelle.getCMgr(), + pauline.getCMgr(), laure.getCMgr()}; + std::list<LinphoneCoreManager *> members{marie.getCMgr(), michelle.getCMgr(), pauline.getCMgr(), + laure.getCMgr()}; std::list<LinphoneCoreManager *> participants{michelle.getCMgr(), pauline.getCMgr(), laure.getCMgr()}; time_t start_time = time(NULL) + 600; // Start in 10 minutes @@ -1450,6 +1454,104 @@ static void conference_cancelled_through_edit_base(bool_t server_restart) { coresList = bctbx_list_append(coresList, focus.getLc()); } + for (auto mgr : members) { + LinphoneCallParams *new_params = linphone_core_create_call_params(mgr->lc, nullptr); + linphone_call_params_enable_video(new_params, FALSE); + ms_message("%s is calling conference %s", linphone_core_get_identity(mgr->lc), conference_address_str); + linphone_core_invite_address_with_params_2(mgr->lc, confAddr, new_params, NULL, nullptr); + linphone_call_params_unref(new_params); + } + + for (auto mgr : members) { + BC_ASSERT_TRUE(wait_for_list(coresList, &mgr->stat.number_of_LinphoneCallOutgoingProgress, 1, + liblinphone_tester_sip_timeout)); + BC_ASSERT_TRUE(wait_for_list(coresList, &mgr->stat.number_of_LinphoneCallStreamsRunning, 1, + liblinphone_tester_sip_timeout)); + BC_ASSERT_TRUE(wait_for_list(coresList, &mgr->stat.number_of_LinphoneConferenceStateCreated, + ((mgr == marie.getCMgr()) ? 4 : 2), liblinphone_tester_sip_timeout)); + BC_ASSERT_TRUE( + wait_for_list(coresList, &mgr->stat.number_of_LinphoneSubscriptionOutgoingProgress, 1, 5000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &mgr->stat.number_of_LinphoneSubscriptionActive, 1, 5000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &mgr->stat.number_of_NotifyFullStateReceived, 1, + liblinphone_tester_sip_timeout)); + } + + BC_ASSERT_TRUE(wait_for_list(coresList, &focus.getStats().number_of_LinphoneCallIncomingReceived, + focus_stat.number_of_LinphoneCallIncomingReceived + 3, + liblinphone_tester_sip_timeout)); + BC_ASSERT_TRUE(wait_for_list(coresList, &focus.getStats().number_of_LinphoneCallStreamsRunning, + focus_stat.number_of_LinphoneCallStreamsRunning + 3, + liblinphone_tester_sip_timeout)); + BC_ASSERT_TRUE(wait_for_list(coresList, &focus.getStats().number_of_LinphoneConferenceStateCreated, + focus_stat.number_of_LinphoneConferenceStateCreated + 1, + liblinphone_tester_sip_timeout)); + BC_ASSERT_TRUE(wait_for_list(coresList, &focus.getStats().number_of_LinphoneSubscriptionIncomingReceived, + focus_stat.number_of_LinphoneSubscriptionIncomingReceived + 3, 5000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &focus.getStats().number_of_LinphoneSubscriptionActive, + focus_stat.number_of_LinphoneSubscriptionActive + 3, 5000)); + + BC_ASSERT_TRUE(wait_for_list(coresList, &focus.getStats().number_of_participants_added, + focus_stat.number_of_participants_added + 3, liblinphone_tester_sip_timeout)); + BC_ASSERT_TRUE(wait_for_list(coresList, &focus.getStats().number_of_participant_devices_added, + focus_stat.number_of_participant_devices_added + 3, + liblinphone_tester_sip_timeout)); + BC_ASSERT_TRUE(wait_for_list(coresList, &focus.getStats().number_of_participant_devices_joined, + focus_stat.number_of_participant_devices_joined + 3, + liblinphone_tester_sip_timeout)); + + std::map<LinphoneCoreManager *, LinphoneParticipantInfo *> memberList = + fill_memmber_list(members, participantList, marie.getCMgr(), participants_info); + wait_for_conference_streams({focus, marie, pauline, laure, michelle}, conferenceMgrs, focus.getCMgr(), + memberList, confAddr, FALSE); + + focus_stat = focus.getStats(); + for (auto mgr : members) { + LinphoneCall *call = linphone_core_get_call_by_remote_address2(mgr->lc, confAddr); + BC_ASSERT_PTR_NOT_NULL(call); + if (call) { + ms_message("%s is terminating call with %s", linphone_core_get_identity(mgr->lc), + linphone_core_get_identity(focus.getLc())); + linphone_call_terminate(call); + int call_ended = 1; + BC_ASSERT_TRUE(wait_for_list(coresList, &mgr->stat.number_of_LinphoneCallEnd, call_ended, + liblinphone_tester_sip_timeout)); + BC_ASSERT_TRUE(wait_for_list(coresList, &mgr->stat.number_of_LinphoneCallReleased, call_ended, + liblinphone_tester_sip_timeout)); + BC_ASSERT_TRUE(wait_for_list(coresList, &mgr->stat.number_of_LinphoneSubscriptionTerminated, call_ended, + liblinphone_tester_sip_timeout)); + BC_ASSERT_TRUE(wait_for_list(coresList, &mgr->stat.number_of_LinphoneConferenceStateTerminationPending, + call_ended, liblinphone_tester_sip_timeout)); + BC_ASSERT_TRUE(wait_for_list(coresList, &mgr->stat.number_of_LinphoneConferenceStateTerminated, + call_ended, liblinphone_tester_sip_timeout)); + BC_ASSERT_TRUE(wait_for_list(coresList, &mgr->stat.number_of_LinphoneConferenceStateDeleted, call_ended, + liblinphone_tester_sip_timeout)); + + LinphoneConference *pconference = + linphone_core_search_conference(mgr->lc, NULL, mgr->identity, confAddr, NULL); + BC_ASSERT_PTR_NULL(pconference); + } + } + + BC_ASSERT_TRUE(wait_for_list(coresList, &focus.getStats().number_of_LinphoneCallEnd, + focus_stat.number_of_LinphoneCallEnd + 4, liblinphone_tester_sip_timeout)); + BC_ASSERT_TRUE(wait_for_list(coresList, &focus.getStats().number_of_LinphoneCallReleased, + focus_stat.number_of_LinphoneCallReleased + 4, liblinphone_tester_sip_timeout)); + BC_ASSERT_TRUE(wait_for_list(coresList, &focus.getStats().number_of_LinphoneSubscriptionTerminated, + focus_stat.number_of_LinphoneSubscriptionTerminated + 4, + liblinphone_tester_sip_timeout)); + BC_ASSERT_TRUE(wait_for_list(coresList, &focus.getStats().number_of_participants_removed, + focus_stat.number_of_participants_removed + 4, liblinphone_tester_sip_timeout)); + BC_ASSERT_TRUE(wait_for_list(coresList, &focus.getStats().number_of_participant_devices_removed, + focus_stat.number_of_participant_devices_removed + 4, + liblinphone_tester_sip_timeout)); + + BC_ASSERT_EQUAL(focus.getStats().number_of_LinphoneConferenceStateTerminationPending, + focus_stat.number_of_LinphoneConferenceStateTerminationPending, int, "%d"); + BC_ASSERT_EQUAL(focus.getStats().number_of_LinphoneConferenceStateTerminated, + focus_stat.number_of_LinphoneConferenceStateTerminated, int, "%d"); + BC_ASSERT_EQUAL(focus.getStats().number_of_LinphoneConferenceStateDeleted, + focus_stat.number_of_LinphoneConferenceStateDeleted, int, "%d"); + const char *subject = "Test characters: <S-F12><S-F11><S-F6> £$%§ (+cancelled)"; const char *description2 = "Testing characters (+cancelled)"; @@ -1476,7 +1578,7 @@ static void conference_cancelled_through_edit_base(bool_t server_restart) { linphone_conference_info_set_description(conf_info, description2); const bctbx_list_t *ics_participants = linphone_conference_info_get_participant_infos(conf_info); - BC_ASSERT_EQUAL(bctbx_list_size(ics_participants), 3, size_t, "%zu"); + BC_ASSERT_EQUAL(bctbx_list_size(ics_participants), 4, size_t, "%zu"); conference_scheduler = linphone_core_create_conference_scheduler(marie.getLc()); linphone_conference_scheduler_set_account(conference_scheduler, editing_account);