conference-event-tester.cpp 116.13 KiB
/*
 * Copyright (c) 2010-2022 Belledonne Communications SARL.
 * This file is part of Liblinphone
 * (see https://gitlab.linphone.org/BC/public/liblinphone).
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <map>
#include <string>
#include "bctoolbox/defs.h"
#include "c-wrapper/c-wrapper.h"
#include "address/address.h"
#include "call/call.h"
#include "conference.h"
#include "conference/conference-listener.h"
#include "conference/handlers/local-conference-event-handler.h"
#include "conference/handlers/remote-conference-event-handler.h"
#include "conference/local-conference.h"
#include "conference/participant.h"
#include "conference/remote-conference.h"
#include "liblinphone_tester.h"
#include "linphone/core.h"
#include "local_conference.h"
#include "private.h"
#include "shared_tester_functions.h"
#include "tester_utils.h"
#include "tools/private-access.h"
#include "linphone/api/c-conference-cbs.h"
#include "linphone/api/c-conference.h"
#include "xml/conference-info.h"
using namespace LinphonePrivate;
using namespace std;
static const char *first_notify =
    "<?xml version=\"1.0\" encoding=\"UTF-8\"?> "
    "   <conference-info"
    "    xmlns=\"urn:ietf:params:xml:ns:conference-info\""
    "    entity=\"%s\""
    "    state=\"full\" version=\"1\">"
    "   <!--"
    "     CONFERENCE INFO"
    "   -->"
    "    <conference-description xmlns:p1=\"linphone:xml:ns:conference-info-linphone-extension\">"
    "     <subject>Agenda: This month's goals</subject>"
    "      <service-uris>"
    "       <entry>"
    "        <uri>http://sharepoint/salesgroup/</uri>"
    "        <purpose>web-page</purpose>"
    "       </entry>"
    "      </service-uris>"
    "     </conference-description>"
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
" <!--" " CONFERENCE STATE" " -->" " <conference-state>" " <user-count>33</user-count>" " </conference-state>" " <!--" " USERS" " -->" " <users>" " <user entity=\"sip:bob@example.com\" state=\"full\">" " <display-text>Bob Hoskins</display-text>" " <!--" " ENDPOINTS" " -->" " <endpoint entity=\"sip:bob@pc33.example.com\">" " <display-text>Bob's Laptop</display-text>" " <status>disconnected</status>" " <disconnection-method>departed</disconnection-method>" " <disconnection-info>" " <when>2005-03-04T20:00:00Z</when>" " <reason>bad voice quality</reason>" " <by>sip:mike@example.com</by>" " </disconnection-info>" " <!--" " MEDIA" " -->" " <media id=\"1\">" " <display-text>main audio</display-text>" " <type>audio</type>" " <label>34567</label>" " <src-id>432424</src-id>" " <status>sendrecv</status>" " </media>" " </endpoint>" " </user>" " <!--" " USER" " -->" " <user entity=\"sip:alice@example.com\" state=\"full\">" " <display-text>Alice</display-text>" " <roles>" " <entry>admin</entry>" " <entry>participant</entry>" " </roles>" " <!--" " ENDPOINTS" " -->" " <endpoint entity=\"sip:4kfk4j392jsu@example.com;grid=433kj4j3u\">" " <status>connected</status>" " <joining-method>dialed-out</joining-method>" " <joining-info>" " <when>2005-03-04T20:00:00Z</when>" " <by>sip:mike@example.com</by>" " </joining-info>" " <!--" " MEDIA" " -->" " <media id=\"1\">" " <display-text>main audio</display-text>" " <type>audio</type>" " <label>34567</label>" " <src-id>534232</src-id>" " <status>sendrecv</status>" " </media>" " </endpoint>" " <endpoint entity=\"sip:aliced48ed45@example.com;grid=54def54e8\">" " <status>connected</status>" " <joining-method>dialed-out</joining-method>" " <joining-info>"
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
" <when>2005-03-04T20:00:00Z</when>" " <by>sip:mike@example.com</by>" " </joining-info>" " <!--" " MEDIA" " -->" " <media id=\"1\">" " <display-text>main audio</display-text>" " <type>audio</type>" " <label>34567</label>" " <src-id>534232</src-id>" " <status>sendrecv</status>" " </media>" " </endpoint>" " </user>" " </users>" " </conference-info>"; static const char *sync_full_state_notify = "<?xml version=\"1.0\" encoding=\"UTF-8\"?> " " <conference-info" " xmlns=\"urn:ietf:params:xml:ns:conference-info\"" " entity=\"%s\"" " state=\"full\" version=\"%0d\">" " <!--" " CONFERENCE INFO" " -->" " <conference-description xmlns:p1=\"linphone:xml:ns:conference-info-linphone-extension\">" " <subject>Agenda: This month's goals</subject>" " <service-uris>" " <entry>" " <uri>http://sharepoint/salesgroup/</uri>" " <purpose>web-page</purpose>" " </entry>" " </service-uris>" " </conference-description>" " <!--" " CONFERENCE STATE" " -->" " <conference-state>" " <user-count>33</user-count>" " </conference-state>" " <!--" " USERS" " -->" " <users>" " <user entity=\"sip:bob@example.com\" state=\"full\">" " <display-text>Bob Hoskins</display-text>" " <!--" " ENDPOINTS" " -->" " <endpoint entity=\"sip:bob@pc33.example.com\">" " <display-text>Bob's Laptop</display-text>" " <status>disconnected</status>" " <disconnection-method>departed</disconnection-method>" " <disconnection-info>" " <when>2005-03-04T20:00:00Z</when>" " <reason>bad voice quality</reason>" " <by>sip:mike@example.com</by>" " </disconnection-info>" " <!--" " MEDIA" " -->" " <media id=\"1\">" " <display-text>main audio</display-text>" " <type>audio</type>" " <label>34567</label>" " <src-id>432424</src-id>" " <status>sendrecv</status>" " </media>"
211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
" </endpoint>" " </user>" " <!--" " USER" " -->" " <user entity=\"sip:alice@example.com\" state=\"full\">" " <display-text>Alice</display-text>" " <roles>" " <entry>admin</entry>" " <entry>participant</entry>" " </roles>" " <!--" " ENDPOINTS" " -->" " <endpoint entity=\"sip:4kfk4j392jsu@example.com;grid=433kj4j3u\">" " <status>connected</status>" " <joining-method>dialed-out</joining-method>" " <joining-info>" " <when>2005-03-04T20:00:00Z</when>" " <by>sip:mike@example.com</by>" " </joining-info>" " <!--" " MEDIA" " -->" " <media id=\"1\">" " <display-text>main audio</display-text>" " <type>audio</type>" " <label>34567</label>" " <src-id>534232</src-id>" " <status>sendrecv</status>" " </media>" " </endpoint>" " <endpoint entity=\"sip:aliced48ed45@example.com;grid=54def54e8\">" " <status>connected</status>" " <joining-method>dialed-out</joining-method>" " <joining-info>" " <when>2005-03-04T20:00:00Z</when>" " <by>sip:mike@example.com</by>" " </joining-info>" " <!--" " MEDIA" " -->" " <media id=\"1\">" " <display-text>main audio</display-text>" " <type>audio</type>" " <label>34567</label>" " <src-id>534232</src-id>" " <status>sendrecv</status>" " </media>" " </endpoint>" " </user>" " <!--" " USER" " -->" " <user entity=\"sip:frank@example.com\" state=\"full\">" " <display-text>Bob Hoskins</display-text>" " <!--" " ENDPOINTS" " -->" " <endpoint entity=\"sip:frank@pc33.example.com\">" " <display-text>Frank's Laptop</display-text>" " <status>connected</status>" " <joining-method>dialed-out</joining-method>" " <joining-info>" " <when>2005-03-04T20:06:00Z</when>" " <by>sip:mike@example.com</by>" " </joining-info>" " <!--" " MEDIA" " -->"
281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
" <media id=\"1\">" " <display-text>main audio</display-text>" " <type>audio</type>" " <label>34567</label>" " <src-id>432424</src-id>" " <status>sendrecv</status>" " </media>" " </endpoint>" " </user>" " </users>" " </conference-info>"; /* static const char *first_notify_with_ephemeral = \ "<?xml version=\"1.0\" encoding=\"UTF-8\"?> "\ " <conference-info"\ " xmlns=\"urn:ietf:params:xml:ns:conference-info\""\ " entity=\"%s\""\ " state=\"full\" version=\"1\">"\ " <!--"\ " CONFERENCE INFO"\ " -->"\ " <conference-description xmlns:linphone-cie=\"linphone:xml:ns:conference-info-linphone-extension\">"\ " <subject>Agenda: This month's goals</subject>"\ " <service-uris>"\ " <entry>"\ " <uri>http://sharepoint/salesgroup/</uri>"\ " <purpose>web-page</purpose>"\ " </entry>"\ " </service-uris>"\ " <linphone-cie:ephemeral>"\ " <linphone-cie:mode>auto</linphone-cie:mode>"\ " </linphone-cie:ephemeral>"\ " </conference-description>"\ " <!--"\ " CONFERENCE STATE"\ " -->"\ " <conference-state>"\ " <user-count>33</user-count>"\ " </conference-state>"\ " <!--"\ " USERS"\ " -->"\ " <users>"\ " <user entity=\"sip:bob@example.com\" state=\"full\">"\ " <display-text>Bob Hoskins</display-text>"\ " <!--"\ " ENDPOINTS"\ " -->"\ " <endpoint entity=\"sip:bob@pc33.example.com\">"\ " <display-text>Bob's Laptop</display-text>"\ " <status>disconnected</status>"\ " <disconnection-method>departed</disconnection-method>"\ " <disconnection-info>"\ " <when>2005-03-04T20:00:00Z</when>"\ " <reason>bad voice quality</reason>"\ " <by>sip:mike@example.com</by>"\ " </disconnection-info>"\ " <!--"\ " MEDIA"\ " -->"\ " <media id=\"1\">"\ " <display-text>main audio</display-text>"\ " <type>audio</type>"\ " <label>34567</label>"\ " <src-id>432424</src-id>"\ " <status>sendrecv</status>"\ " </media>"\ " </endpoint>"\ " </user>"\
351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
" <!--"\ " USER"\ " -->"\ " <user entity=\"sip:alice@example.com\" state=\"full\">"\ " <display-text>Alice</display-text>"\ " <roles>"\ " <entry>admin</entry>"\ " <entry>participant</entry>"\ " </roles>"\ " <!--"\ " ENDPOINTS"\ " -->"\ " <endpoint entity=\"sip:4kfk4j392jsu@example.com;grid=433kj4j3u\" xmlns:linphone-cie=\"urn:oma:xml:prs:pidf:oma-pres\">"\ " <status>connected</status>"\ " <joining-method>dialed-out</joining-method>"\ " <joining-info>"\ " <when>2005-03-04T20:00:00Z</when>"\ " <by>sip:mike@example.com</by>"\ " </joining-info>"\ " <linphone-cie:service-description>"\ " <linphone-cie:service-id>ephemeral</linphone-cie:service-id>"\ " <linphone-cie:version>1.0</linphone-cie:version>"\ " </linphone-cie:service-description>"\ " <linphone-cie:service-description>"\ " <linphone-cie:service-id>groupchat</linphone-cie:service-id>"\ " <linphone-cie:version>1.1</linphone-cie:version>"\ " </linphone-cie:service-description>"\ " <linphone-cie:service-description>"\ " <linphone-cie:service-id>lime</linphone-cie:service-id>"\ " <linphone-cie:version>1.0</linphone-cie:version>"\ " </linphone-cie:service-description>"\ " <!--"\ " MEDIA"\ " -->"\ " <media id=\"1\">"\ " <display-text>main audio</display-text>"\ " <type>audio</type>"\ " <label>34567</label>"\ " <src-id>534232</src-id>"\ " <status>sendrecv</status>"\ " </media>"\ " </endpoint>"\ " <endpoint entity=\"sip:aliced48ed45@example.com;grid=54def54e8\">"\ " <status>connected</status>"\ " <joining-method>dialed-out</joining-method>"\ " <joining-info>"\ " <when>2005-03-04T20:00:00Z</when>"\ " <by>sip:mike@example.com</by>"\ " </joining-info>"\ " <!--"\ " MEDIA"\ " -->"\ " <media id=\"1\">"\ " <display-text>main audio</display-text>"\ " <type>audio</type>"\ " <label>34567</label>"\ " <src-id>534232</src-id>"\ " <status>sendrecv</status>"\ " </media>"\ " </endpoint>"\ " </user>"\ " </users>"\ " </conference-info>"; */ static const char *participant_added_notify = "<?xml version=\"1.0\" encoding=\"UTF-8\"?> " " <conference-info" " xmlns=\"urn:ietf:params:xml:ns:conference-info\"" " entity=\"%s\""
421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
" state=\"partial\" version=\"2\">" " <!--" " CONFERENCE INFO" " -->" " <conference-description>" " <subject>Agenda: This month's goals</subject>" " <service-uris>" " <entry>" " <uri>http://sharepoint/salesgroup/</uri>" " <purpose>web-page</purpose>" " </entry>" " </service-uris>" " </conference-description>" " <!--" " CONFERENCE STATE" " -->" " <conference-state>" " <user-count>33</user-count>" " </conference-state>" " <!--" " USERS" " -->" " <users>" " <user entity=\"sip:frank@example.com\" state=\"full\">" " <display-text>Bob Hoskins</display-text>" " <!--" " ENDPOINTS" " -->" " <endpoint entity=\"sip:frank@pc33.example.com\">" " <display-text>Frank's Laptop</display-text>" " <status>disconnected</status>" " <disconnection-method>departed</disconnection-method>" " <disconnection-info>" " <when>2005-03-04T20:00:00Z</when>" " <reason>bad voice quality</reason>" " <by>sip:mike@example.com</by>" " </disconnection-info>" " <!--" " MEDIA" " -->" " <media id=\"1\">" " <display-text>main audio</display-text>" " <type>audio</type>" " <label>34567</label>" " <src-id>432424</src-id>" " <status>sendrecv</status>" " </media>" " </endpoint>" " </user>" " </users>" " </conference-info>"; static const char *participant_not_added_notify = "<?xml version=\"1.0\" encoding=\"UTF-8\"?> " " <conference-info" " xmlns=\"urn:ietf:params:xml:ns:conference-info\"" " entity=\"%s\"" " state=\"partial\" version=\"2\">" " <!--" " CONFERENCE INFO" " -->" " <conference-description>" " <subject>Agenda: This month's goals</subject>" " <service-uris>" " <entry>" " <uri>http://sharepoint/salesgroup/</uri>" " <purpose>web-page</purpose>" " </entry>" " </service-uris>" " </conference-description>" " <!--"
491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
" CONFERENCE STATE" " -->" " <conference-state>" " <user-count>33</user-count>" " </conference-state>" " <!--" " USERS" " -->" " <users>" " <user entity=\"sip:frank@example.com\" state=\"partial\">" " <display-text>Bob Hoskins</display-text>" " <!--" " ENDPOINTS" " -->" " <endpoint entity=\"sip:frank@pc33.example.com\">" " <display-text>Frank's Laptop</display-text>" " <status>disconnected</status>" " <disconnection-method>departed</disconnection-method>" " <disconnection-info>" " <when>2005-03-04T20:00:00Z</when>" " <reason>bad voice quality</reason>" " <by>sip:mike@example.com</by>" " </disconnection-info>" " <!--" " MEDIA" " -->" " <media id=\"1\">" " <display-text>main audio</display-text>" " <type>audio</type>" " <label>34567</label>" " <src-id>432424</src-id>" " <status>sendrecv</status>" " </media>" " </endpoint>" " </user>" " </users>" " </conference-info>"; static const char *participant_device_not_added_notify = "<?xml version=\"1.0\" encoding=\"UTF-8\"?> " " <conference-info" " xmlns=\"urn:ietf:params:xml:ns:conference-info\"" " entity=\"%s\"" " state=\"partial\" version=\"%0d\">" " <!--" " USERS" " -->" " <users state=\"full\">" " <user entity=\"sip:frank@example.com\" state=\"partial\">" " <!--" " ENDPOINTS" " -->" " <endpoint entity=\"sip:frank@pc34.example.com\" state=\"partial\">" " <display-text>Frank's Laptop</display-text>" " <status>connected</status>" " <joining-method>dialed-out</joining-method>" " <joining-info>" " <when>2005-03-04T20:01:00Z</when>" " <by>sip:mike@example.com</by>" " </joining-info>" " <!--" " MEDIA" " -->" " <media id=\"1\">" " <display-text>main audio</display-text>" " <type>audio</type>" " <label>34517</label>" " <src-id>432494</src-id>" " <status>sendonly</status>" " </media>"
561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630
" </endpoint>" " </user>" " </users>" " </conference-info>"; static const char *participant_deleted_notify = "<?xml version=\"1.0\" encoding=\"UTF-8\"?> " " <conference-info" " xmlns=\"urn:ietf:params:xml:ns:conference-info\"" " entity=\"%s\"" " state=\"partial\" version=\"2\">" " <!--" " CONFERENCE INFO" " -->" " <conference-description>" " <subject>Agenda: This month's goals</subject>" " <service-uris>" " <entry>" " <uri>http://sharepoint/salesgroup/</uri>" " <purpose>web-page</purpose>" " </entry>" " </service-uris>" " </conference-description>" " <!--" " CONFERENCE STATE" " -->" " <conference-state>" " <user-count>33</user-count>" " </conference-state>" " <!--" " USERS" " -->" " <users>" " <user entity=\"sip:bob@example.com\" state=\"deleted\">" " <display-text>Bob Hoskins</display-text>" " <!--" " ENDPOINTS" " -->" " <endpoint entity=\"sip:bob@pc33.example.com\">" " <display-text>Bob's Laptop</display-text>" " <status>disconnected</status>" " <disconnection-method>departed</disconnection-method>" " <disconnection-info>" " <when>2005-03-04T20:00:00Z</when>" " <reason>bad voice quality</reason>" " <by>sip:mike@example.com</by>" " </disconnection-info>" " <!--" " MEDIA" " -->" " <media id=\"1\">" " <display-text>main audio</display-text>" " <type>audio</type>" " <label>34567</label>" " <src-id>432424</src-id>" " <status>sendrecv</status>" " </media>" " </endpoint>" " </user>" " </users>" " </conference-info>"; static const char *participant_admined_notify = "<?xml version=\"1.0\" encoding=\"UTF-8\"?> " " <conference-info" " xmlns=\"urn:ietf:params:xml:ns:conference-info\"" " entity=\"%s\"" " state=\"partial\" version=\"2\">" " <!--" " CONFERENCE INFO" " -->" " <conference-description>"
631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700
" <subject>Agenda: This month's goals</subject>" " <service-uris>" " <entry>" " <uri>http://sharepoint/salesgroup/</uri>" " <purpose>web-page</purpose>" " </entry>" " </service-uris>" " </conference-description>" " <!--" " CONFERENCE STATE" " -->" " <conference-state>" " <user-count>33</user-count>" " </conference-state>" " <!--" " USERS" " -->" " <users>" " <user entity=\"sip:bob@example.com\" state=\"partial\">" " <display-text>Bob Hoskins</display-text>" " <roles>" " <entry>participant</entry>" " <entry>admin</entry>" " </roles>" " <!--" " ENDPOINTS" " -->" " <endpoint entity=\"sip:bob@pc33.example.com\">" " <display-text>Bob's Laptop</display-text>" " <status>disconnected</status>" " <disconnection-method>departed</disconnection-method>" " <disconnection-info>" " <when>2005-03-04T20:00:00Z</when>" " <reason>bad voice quality</reason>" " <by>sip:mike@example.com</by>" " </disconnection-info>" " <!--" " MEDIA" " -->" " <media id=\"1\">" " <display-text>main audio</display-text>" " <type>audio</type>" " <label>34567</label>" " <src-id>432424</src-id>" " <status>sendrecv</status>" " </media>" " </endpoint>" " </user>" " </users>" " </conference-info>"; static const char *participant_unadmined_notify = "<?xml version=\"1.0\" encoding=\"UTF-8\"?> " " <conference-info" " xmlns=\"urn:ietf:params:xml:ns:conference-info\"" " entity=\"%s\"" " state=\"partial\" version=\"2\">" " <!--" " CONFERENCE INFO" " -->" " <conference-description>" " <subject>Agenda: This month's goals</subject>" " <service-uris>" " <entry>" " <uri>http://sharepoint/salesgroup/</uri>" " <purpose>web-page</purpose>" " </entry>" " </service-uris>" " </conference-description>" " <!--" " CONFERENCE STATE"
701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770
" -->" " <conference-state>" " <user-count>33</user-count>" " </conference-state>" " <!--" " USERS" " -->" " <users>" " <user entity=\"sip:alice@example.com\" state=\"partial\">" " <display-text>Alice Hoskins</display-text>" " <roles>" " <entry>participant</entry>" " </roles>" " <!--" " ENDPOINTS" " -->" " <endpoint entity=\"sip:alice@pc33.example.com\">" " <display-text>Alice's Laptop</display-text>" " <status>disconnected</status>" " <disconnection-method>departed</disconnection-method>" " <disconnection-info>" " <when>2005-03-04T20:00:00Z</when>" " <reason>bad voice quality</reason>" " <by>sip:mike@example.com</by>" " </disconnection-info>" " <!--" " MEDIA" " -->" " <media id=\"1\">" " <display-text>main audio</display-text>" " <type>audio</type>" " <label>34567</label>" " <src-id>432424</src-id>" " <status>sendrecv</status>" " </media>" " </endpoint>" " </user>" " </users>" " </conference-info>"; static const char *bobUri = "sip:bob@example.com"; static const char *aliceUri = "sip:alice@example.com"; static const char *frankUri = "sip:frank@example.com"; static const char *confUri = "sips:conf233@example.com"; L_ENABLE_ATTR_ACCESS(LocalConference, shared_ptr<LocalConferenceEventHandler>, eventHandler); class ConferenceEventTester : public RemoteConference { public: ConferenceEventTester(const shared_ptr<Core> &core, const std::shared_ptr<Address> &confAddr); ~ConferenceEventTester(); private: void onConferenceCreated(const std::shared_ptr<Address> &addr) override; void onConferenceKeywordsChanged(const vector<string> &keywords) override; void onConferenceTerminated(const std::shared_ptr<Address> &addr) override; void onFirstNotifyReceived(const std::shared_ptr<Address> &addr) override; void onParticipantAdded(const shared_ptr<ConferenceParticipantEvent> &event, const std::shared_ptr<Participant> &participant) override; void onParticipantRemoved(const shared_ptr<ConferenceParticipantEvent> &event, const std::shared_ptr<Participant> &participant) override; void onParticipantSetAdmin(const shared_ptr<ConferenceParticipantEvent> &event, const std::shared_ptr<Participant> &participant) override; void onSubjectChanged(const shared_ptr<ConferenceSubjectEvent> &event) override; void onParticipantDeviceAdded(const shared_ptr<ConferenceParticipantDeviceEvent> &event, const std::shared_ptr<ParticipantDevice> &device) override; void onParticipantDeviceRemoved(const shared_ptr<ConferenceParticipantDeviceEvent> &event, const std::shared_ptr<ParticipantDevice> &device) override; public:
771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840
RemoteConferenceEventHandler *handler; // address - admin map<string, bool> participants; map<string, int> participantDevices; string confSubject; bool oneToOne = false; }; ConferenceEventTester::ConferenceEventTester(const shared_ptr<Core> &core, const std::shared_ptr<Address> &confAddr) : RemoteConference(core, confAddr, nullptr, ConferenceParams::create(core->getCCore())) { handler = new RemoteConferenceEventHandler(this, this); } ConferenceEventTester::~ConferenceEventTester() { delete handler; } void ConferenceEventTester::onConferenceCreated(BCTBX_UNUSED(const std::shared_ptr<Address> &address)) { } void ConferenceEventTester::onConferenceKeywordsChanged(const vector<string> &keywords) { for (const auto &k : keywords) { if (k == "one-to-one") oneToOne = true; } } void ConferenceEventTester::onConferenceTerminated(BCTBX_UNUSED(const std::shared_ptr<Address> &addr)) { } void ConferenceEventTester::onFirstNotifyReceived(BCTBX_UNUSED(const std::shared_ptr<Address> &addr)) { } void ConferenceEventTester::onParticipantAdded(const shared_ptr<ConferenceParticipantEvent> &event, BCTBX_UNUSED(const std::shared_ptr<Participant> &participant)) { const std::shared_ptr<Address> addr = event->getParticipantAddress(); participants.insert({addr->toString(), false}); participantDevices.insert({addr->toString(), 0}); } void ConferenceEventTester::onParticipantRemoved(const shared_ptr<ConferenceParticipantEvent> &event, BCTBX_UNUSED(const std::shared_ptr<Participant> &participant)) { const std::shared_ptr<Address> addr = event->getParticipantAddress(); participants.erase(addr->toString()); participantDevices.erase(addr->toString()); } void ConferenceEventTester::onParticipantSetAdmin(const shared_ptr<ConferenceParticipantEvent> &event, BCTBX_UNUSED(const std::shared_ptr<Participant> &participant)) { const std::shared_ptr<Address> addr = event->getParticipantAddress(); auto it = participants.find(addr->toString()); if (it != participants.end()) it->second = (event->getType() == EventLog::Type::ConferenceParticipantSetAdmin); } void ConferenceEventTester::onSubjectChanged(const shared_ptr<ConferenceSubjectEvent> &event) { confSubject = event->getSubject(); } void ConferenceEventTester::onParticipantDeviceAdded(const shared_ptr<ConferenceParticipantDeviceEvent> &event, BCTBX_UNUSED(const std::shared_ptr<ParticipantDevice> &device)) { const std::shared_ptr<Address> addr = event->getParticipantAddress(); auto it = participantDevices.find(addr->toString()); if (it != participantDevices.end()) it->second++; } void ConferenceEventTester::onParticipantDeviceRemoved(const shared_ptr<ConferenceParticipantDeviceEvent> &event, BCTBX_UNUSED(const std::shared_ptr<ParticipantDevice> &device)) { const std::shared_ptr<Address> addr = event->getParticipantAddress(); auto it = participantDevices.find(addr->toString()); if (it != participantDevices.end() && it->second > 0) it->second--; }
841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910
class LocalConferenceTester : public LocalConference { public: LocalConferenceTester(const std::shared_ptr<Core> &core, const std::shared_ptr<Address> &myAddress, CallSessionListener *listener) : LocalConference(core, myAddress, listener, ConferenceParams::create(core->getCCore())) { } virtual ~LocalConferenceTester() { } /* ConferenceInterface */ // Addressing compilation error -Werror=overloaded-virtual using LinphonePrivate::Conference::addParticipant; bool addParticipant(const std::shared_ptr<Address> &addr) override { bool status = LocalConference::addParticipant(addr); std::shared_ptr<Participant> p = findParticipant(addr); p->addDevice(addr); if (status) { notifyParticipantAdded(time(nullptr), false, p); } return status; } bool removeParticipant(const std::shared_ptr<Participant> &participant) override { participant->clearDevices(); bool status = LocalConference::removeParticipant(participant); if (status) { notifyParticipantRemoved(time(nullptr), false, participant); } return status; } void setSubject(const std::string &subject) override { LocalConference::setSubject(subject); notifySubjectChanged(time(nullptr), false, subject); } }; class ConferenceListenerInterfaceTester : public ConferenceListenerInterface { public: ConferenceListenerInterfaceTester() = default; ~ConferenceListenerInterfaceTester() = default; private: void onParticipantAdded(const shared_ptr<ConferenceParticipantEvent> &event, const std::shared_ptr<Participant> &participant) override; void onParticipantRemoved(const shared_ptr<ConferenceParticipantEvent> &event, const std::shared_ptr<Participant> &participant) override; void onParticipantSetAdmin(const shared_ptr<ConferenceParticipantEvent> &event, const std::shared_ptr<Participant> &participant) override; void onSubjectChanged(const shared_ptr<ConferenceSubjectEvent> &event) override; void onParticipantDeviceAdded(const shared_ptr<ConferenceParticipantDeviceEvent> &event, const std::shared_ptr<ParticipantDevice> &device) override; void onParticipantDeviceRemoved(const shared_ptr<ConferenceParticipantDeviceEvent> &event, const std::shared_ptr<ParticipantDevice> &device) override; public: // first = address // second = isAdmin map<string, bool> participants; // first = address // second = number of devices map<string, int> participantDevices; string confSubject; unsigned int lastNotify = 1; }; void ConferenceListenerInterfaceTester::onParticipantAdded( const shared_ptr<ConferenceParticipantEvent> &event,
911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980
BCTBX_UNUSED(const std::shared_ptr<Participant> &participant)) { const std::shared_ptr<Address> addr = event->getParticipantAddress(); participants.insert({addr->toString(), false}); participantDevices.insert({addr->toString(), 0}); lastNotify++; } void ConferenceListenerInterfaceTester::onParticipantRemoved( const shared_ptr<ConferenceParticipantEvent> &event, BCTBX_UNUSED(const std::shared_ptr<Participant> &participant)) { const std::shared_ptr<Address> addr = event->getParticipantAddress(); participants.erase(addr->toString()); participantDevices.erase(addr->toString()); lastNotify++; } void ConferenceListenerInterfaceTester::onParticipantSetAdmin( const shared_ptr<ConferenceParticipantEvent> &event, BCTBX_UNUSED(const std::shared_ptr<Participant> &participant)) { const std::shared_ptr<Address> addr = event->getParticipantAddress(); auto it = participants.find(addr->toString()); if (it != participants.end()) it->second = (event->getType() == EventLog::Type::ConferenceParticipantSetAdmin); lastNotify++; } void ConferenceListenerInterfaceTester::onSubjectChanged(const shared_ptr<ConferenceSubjectEvent> &event) { confSubject = event->getSubject(); lastNotify++; } void ConferenceListenerInterfaceTester::onParticipantDeviceAdded( const shared_ptr<ConferenceParticipantDeviceEvent> &event, BCTBX_UNUSED(const std::shared_ptr<ParticipantDevice> &device)) { const std::shared_ptr<Address> addr = event->getParticipantAddress(); auto it = participantDevices.find(addr->toString()); if (it != participantDevices.end()) it->second++; lastNotify++; } void ConferenceListenerInterfaceTester::onParticipantDeviceRemoved( const shared_ptr<ConferenceParticipantDeviceEvent> &event, BCTBX_UNUSED(const std::shared_ptr<ParticipantDevice> &device)) { const std::shared_ptr<Address> addr = event->getParticipantAddress(); auto it = participantDevices.find(addr->toString()); if (it != participantDevices.end() && it->second > 0) it->second--; lastNotify++; } static void setParticipantAsAdmin(shared_ptr<LocalConferenceTester> localConf, std::shared_ptr<Address> addr, bool isAdmin) { shared_ptr<Participant> p = localConf->findParticipant(addr); p->setAdmin(isAdmin); localConf->notifyParticipantSetAdmin(time(nullptr), false, p, isAdmin); } void first_notify_parsing() { LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc"); LinphoneAddress *confAddress = linphone_core_interpret_url(marie->lc, confUri); std::shared_ptr<Address> addr = Address::toCpp(confAddress)->getSharedFromThis(); linphone_address_unref(confAddress); shared_ptr<ConferenceEventTester> tester = make_shared<ConferenceEventTester>(marie->lc->cppPtr, addr); LinphoneAddress *bobAddr = linphone_core_interpret_url(marie->lc, bobUri); LinphoneAddress *aliceAddr = linphone_core_interpret_url(marie->lc, aliceUri); size_t size = strlen(first_notify) + strlen(confUri); char *notify = new char[size]; const_cast<ConferenceId &>(tester->handler->getConferenceId()).setPeerAddress(addr); snprintf(notify, size, first_notify, confUri);
981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050
Content content; content.setBodyFromUtf8(notify); content.setContentType(ContentType::ConferenceInfo); tester->handler->notifyReceived(content); delete[] notify; BC_ASSERT_STRING_EQUAL(tester->confSubject.c_str(), "Agenda: This month's goals"); BC_ASSERT_EQUAL((int)tester->participants.size(), 2, int, "%d"); char *bobAddrStr = linphone_address_as_string(bobAddr); char *aliceAddrStr = linphone_address_as_string(aliceAddr); BC_ASSERT_TRUE(tester->participants.find(bobAddrStr) != tester->participants.end()); BC_ASSERT_TRUE(tester->participants.find(aliceAddrStr) != tester->participants.end()); BC_ASSERT_TRUE(!tester->participants.find(bobAddrStr)->second); BC_ASSERT_TRUE(tester->participants.find(aliceAddrStr)->second); BC_ASSERT_EQUAL((int)tester->participantDevices.size(), 2, int, "%d"); BC_ASSERT_TRUE(tester->participantDevices.find(bobAddrStr) != tester->participantDevices.end()); BC_ASSERT_TRUE(tester->participantDevices.find(aliceAddrStr) != tester->participantDevices.end()); BC_ASSERT_EQUAL(tester->participantDevices.find(bobAddrStr)->second, 1, int, "%d"); BC_ASSERT_EQUAL(tester->participantDevices.find(aliceAddrStr)->second, 2, int, "%d"); bctbx_free(bobAddrStr); bctbx_free(aliceAddrStr); linphone_address_unref(bobAddr); linphone_address_unref(aliceAddr); tester = nullptr; linphone_core_manager_destroy(marie); } void first_notify_with_extensions_parsing() { LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc"); LinphoneAddress *confAddress = linphone_core_interpret_url(marie->lc, confUri); std::shared_ptr<Address> addr = Address::toCpp(confAddress)->getSharedFromThis(); linphone_address_unref(confAddress); shared_ptr<ConferenceEventTester> tester = make_shared<ConferenceEventTester>(marie->lc->cppPtr, addr); LinphoneAddress *bobAddr = linphone_core_interpret_url(marie->lc, bobUri); LinphoneAddress *aliceAddr = linphone_core_interpret_url(marie->lc, aliceUri); size_t size = strlen(first_notify) + strlen(confUri); char *notify = new char[size]; const_cast<ConferenceId &>(tester->handler->getConferenceId()).setPeerAddress(addr); snprintf(notify, size, first_notify, confUri); Content content; content.setBodyFromUtf8(notify); content.setContentType(ContentType::ConferenceInfo); tester->handler->notifyReceived(content); delete[] notify; BC_ASSERT_STRING_EQUAL(tester->confSubject.c_str(), "Agenda: This month's goals"); BC_ASSERT_EQUAL((int)tester->participants.size(), 2, int, "%d"); char *bobAddrStr = linphone_address_as_string(bobAddr); char *aliceAddrStr = linphone_address_as_string(aliceAddr); BC_ASSERT_TRUE(tester->participants.find(bobAddrStr) != tester->participants.end()); BC_ASSERT_TRUE(tester->participants.find(aliceAddrStr) != tester->participants.end()); BC_ASSERT_TRUE(!tester->participants.find(bobAddrStr)->second); BC_ASSERT_TRUE(tester->participants.find(aliceAddrStr)->second); BC_ASSERT_EQUAL((int)tester->participantDevices.size(), 2, int, "%d"); BC_ASSERT_TRUE(tester->participantDevices.find(bobAddrStr) != tester->participantDevices.end()); BC_ASSERT_TRUE(tester->participantDevices.find(aliceAddrStr) != tester->participantDevices.end()); BC_ASSERT_EQUAL(tester->participantDevices.find(bobAddrStr)->second, 1, int, "%d"); BC_ASSERT_EQUAL(tester->participantDevices.find(aliceAddrStr)->second, 2, int, "%d"); bctbx_free(bobAddrStr); bctbx_free(aliceAddrStr); linphone_address_unref(bobAddr);
1051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120
linphone_address_unref(aliceAddr); tester = nullptr; linphone_core_manager_destroy(marie); } void first_notify_parsing_wrong_conf() { LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc"); LinphoneAddress *confAddress = linphone_core_interpret_url(marie->lc, "sips:conf322@example.com"); std::shared_ptr<Address> addr = Address::toCpp(confAddress)->getSharedFromThis(); linphone_address_unref(confAddress); shared_ptr<ConferenceEventTester> tester = make_shared<ConferenceEventTester>(marie->lc->cppPtr, addr); LinphoneAddress *bobAddr = linphone_core_interpret_url(marie->lc, bobUri); LinphoneAddress *aliceAddr = linphone_core_interpret_url(marie->lc, aliceUri); size_t size = strlen(first_notify) + strlen(confUri); char *notify = new char[size]; const_cast<ConferenceId &>(tester->handler->getConferenceId()).setPeerAddress(addr); snprintf(notify, size, first_notify, confUri); Content content; content.setBodyFromUtf8(notify); content.setContentType(ContentType::ConferenceInfo); tester->handler->notifyReceived(content); delete[] notify; BC_ASSERT_EQUAL((int)tester->participants.size(), 0, int, "%d"); char *bobAddrStr = linphone_address_as_string(bobAddr); char *aliceAddrStr = linphone_address_as_string(aliceAddr); BC_ASSERT_FALSE(tester->participants.find(bobAddrStr) != tester->participants.end()); BC_ASSERT_FALSE(tester->participants.find(aliceAddrStr) != tester->participants.end()); bctbx_free(bobAddrStr); bctbx_free(aliceAddrStr); linphone_address_unref(bobAddr); linphone_address_unref(aliceAddr); tester = nullptr; linphone_core_manager_destroy(marie); } void participant_added_parsing() { LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc"); LinphoneAddress *confAddress = linphone_core_interpret_url(marie->lc, confUri); std::shared_ptr<Address> addr = Address::toCpp(confAddress)->getSharedFromThis(); linphone_address_unref(confAddress); shared_ptr<ConferenceEventTester> tester = make_shared<ConferenceEventTester>(marie->lc->cppPtr, addr); LinphoneAddress *bobAddr = linphone_core_interpret_url(marie->lc, bobUri); LinphoneAddress *aliceAddr = linphone_core_interpret_url(marie->lc, aliceUri); LinphoneAddress *frankAddr = linphone_core_interpret_url(marie->lc, frankUri); size_t size = strlen(first_notify) + strlen(confUri); char *notify = new char[size]; size_t size2 = strlen(participant_added_notify) + strlen(confUri); char *notify_added = new char[size2]; const_cast<ConferenceId &>(tester->handler->getConferenceId()).setPeerAddress(addr); snprintf(notify, size, first_notify, confUri); Content content; content.setBodyFromUtf8(notify); content.setContentType(ContentType::ConferenceInfo); tester->handler->notifyReceived(content); delete[] notify; char *bobAddrStr = linphone_address_as_string(bobAddr); char *aliceAddrStr = linphone_address_as_string(aliceAddr);
1121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190
BC_ASSERT_EQUAL((int)tester->participants.size(), 2, int, "%d"); BC_ASSERT_EQUAL((int)tester->participantDevices.size(), 2, int, "%d"); BC_ASSERT_TRUE(tester->participants.find(bobAddrStr) != tester->participants.end()); BC_ASSERT_TRUE(tester->participants.find(aliceAddrStr) != tester->participants.end()); BC_ASSERT_TRUE(!tester->participants.find(bobAddrStr)->second); BC_ASSERT_TRUE(tester->participants.find(aliceAddrStr)->second); bctbx_free(bobAddrStr); bctbx_free(aliceAddrStr); snprintf(notify_added, size2, participant_added_notify, confUri); Content content_added; content_added.setBodyFromUtf8(notify_added); content_added.setContentType(ContentType::ConferenceInfo); tester->handler->notifyReceived(content_added); delete[] notify_added; char *frankAddrStr = linphone_address_as_string(frankAddr); BC_ASSERT_EQUAL((int)tester->participants.size(), 3, int, "%d"); BC_ASSERT_EQUAL((int)tester->participantDevices.size(), 3, int, "%d"); BC_ASSERT_TRUE(tester->participants.find(frankAddrStr) != tester->participants.end()); BC_ASSERT_TRUE(!tester->participants.find(frankAddrStr)->second); bctbx_free(frankAddrStr); linphone_address_unref(bobAddr); linphone_address_unref(aliceAddr); linphone_address_unref(frankAddr); tester = nullptr; linphone_core_manager_destroy(marie); } void participant_not_added_parsing() { LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc"); setup_mgr_for_conference(marie, NULL); LinphoneAddress *confAddress = linphone_core_interpret_url(marie->lc, confUri); std::shared_ptr<Address> addr = Address::toCpp(confAddress)->getSharedFromThis(); linphone_address_unref(confAddress); shared_ptr<ConferenceEventTester> tester = make_shared<ConferenceEventTester>(marie->lc->cppPtr, addr); LinphoneAddress *bobAddr = linphone_core_interpret_url(marie->lc, bobUri); LinphoneAddress *aliceAddr = linphone_core_interpret_url(marie->lc, aliceUri); LinphoneAddress *frankAddr = linphone_core_interpret_url(marie->lc, frankUri); size_t size = strlen(first_notify) + strlen(confUri); char *notify = new char[size]; size_t size2 = strlen(participant_not_added_notify) + strlen(confUri); char *notify_not_added = new char[size2]; size_t size3 = strlen(sync_full_state_notify) + strlen(confUri) + sizeof(int); char *notify_full_state_sync = new char[size3]; size_t size4 = strlen(participant_device_not_added_notify) + strlen(confUri) + sizeof(int); char *notify_device_not_added = new char[size4]; const_cast<ConferenceId &>(tester->handler->getConferenceId()).setPeerAddress(addr); const_cast<ConferenceId &>(tester->handler->getConferenceId()) .setLocalAddress(Address::create(linphone_core_get_identity(marie->lc))); snprintf(notify, size, first_notify, confUri); Content content; content.setBodyFromUtf8(notify); content.setContentType(ContentType::ConferenceInfo); tester->handler->notifyReceived(content); delete[] notify; char *bobAddrStr = linphone_address_as_string(bobAddr); char *aliceAddrStr = linphone_address_as_string(aliceAddr); char *frankAddrStr = linphone_address_as_string(frankAddr); BC_ASSERT_EQUAL((int)tester->participants.size(), 2, int, "%d"); BC_ASSERT_EQUAL((int)tester->participantDevices.size(), 2, int, "%d");
1191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260
BC_ASSERT_TRUE(tester->participants.find(bobAddrStr) != tester->participants.end()); BC_ASSERT_TRUE(tester->participants.find(aliceAddrStr) != tester->participants.end()); BC_ASSERT_TRUE(!tester->participants.find(bobAddrStr)->second); BC_ASSERT_TRUE(tester->participants.find(aliceAddrStr)->second); bctbx_free(bobAddrStr); bctbx_free(aliceAddrStr); stats initial_marie_stats = marie->stat; snprintf(notify_not_added, size2, participant_not_added_notify, confUri); Content content_not_added; content_not_added.setBodyFromUtf8(notify_not_added); content_not_added.setContentType(ContentType::ConferenceInfo); tester->handler->notifyReceived(content_not_added); delete[] notify_not_added; BC_ASSERT_EQUAL((int)tester->participants.size(), 2, int, "%d"); BC_ASSERT_FALSE(tester->participants.find(frankAddrStr) != tester->participants.end()); // Add a short wait to ensure that all NOTIFYs are replied BC_ASSERT_TRUE(wait_for_until(marie->lc, NULL, &marie->stat.number_of_LinphoneSubscriptionOutgoingProgress, (initial_marie_stats.number_of_LinphoneSubscriptionOutgoingProgress + 1), 5000)); snprintf(notify_full_state_sync, size3, sync_full_state_notify, confUri, tester->handler->getLastNotify() + 1); Content content_full_state_updated; content_full_state_updated.setBodyFromUtf8(notify_full_state_sync); content_full_state_updated.setContentType(ContentType::ConferenceInfo); tester->handler->notifyReceived(content_full_state_updated); delete[] notify_full_state_sync; BC_ASSERT_EQUAL((int)tester->participants.size(), 3, int, "%d"); BC_ASSERT_EQUAL((int)tester->participantDevices.size(), 3, int, "%d"); BC_ASSERT_TRUE(tester->participants.find(frankAddrStr) != tester->participants.end()); snprintf(notify_device_not_added, size4, participant_device_not_added_notify, confUri, tester->handler->getLastNotify() + 1); initial_marie_stats = marie->stat; Content content_device_not_added; content_device_not_added.setBodyFromUtf8(notify_device_not_added); content_device_not_added.setContentType(ContentType::ConferenceInfo); tester->handler->notifyReceived(content_device_not_added); delete[] notify_device_not_added; BC_ASSERT_EQUAL((int)tester->participants.size(), 3, int, "%d"); BC_ASSERT_EQUAL((int)tester->participantDevices.size(), 3, int, "%d"); BC_ASSERT_TRUE(tester->participants.find(frankAddrStr) != tester->participants.end()); bctbx_free(frankAddrStr); // Add a short wait to ensure that all NOTIFYs are replied BC_ASSERT_TRUE(wait_for_until(marie->lc, NULL, &marie->stat.number_of_LinphoneSubscriptionOutgoingProgress, (initial_marie_stats.number_of_LinphoneSubscriptionOutgoingProgress + 1), 5000)); linphone_address_unref(bobAddr); linphone_address_unref(aliceAddr); linphone_address_unref(frankAddr); tester = nullptr; destroy_mgr_in_conference(marie); } void participant_deleted_parsing() { LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc"); LinphoneAddress *confAddress = linphone_core_interpret_url(marie->lc, confUri); std::shared_ptr<Address> addr = Address::toCpp(confAddress)->getSharedFromThis(); linphone_address_unref(confAddress); shared_ptr<ConferenceEventTester> tester = make_shared<ConferenceEventTester>(marie->lc->cppPtr, addr);
1261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330
LinphoneAddress *bobAddr = linphone_core_interpret_url(marie->lc, bobUri); LinphoneAddress *aliceAddr = linphone_core_interpret_url(marie->lc, aliceUri); size_t size = strlen(first_notify) + strlen(confUri); char *notify = new char[size]; size_t size2 = strlen(participant_deleted_notify) + strlen(confUri); char *notify_deleted = new char[size2]; const_cast<ConferenceId &>(tester->handler->getConferenceId()).setPeerAddress(addr); snprintf(notify, size, first_notify, confUri); Content content; content.setBodyFromUtf8(notify); content.setContentType(ContentType::ConferenceInfo); tester->handler->notifyReceived(content); delete[] notify; char *bobAddrStr = linphone_address_as_string(bobAddr); char *aliceAddrStr = linphone_address_as_string(aliceAddr); BC_ASSERT_EQUAL((int)tester->participants.size(), 2, int, "%d"); BC_ASSERT_EQUAL((int)tester->participantDevices.size(), 2, int, "%d"); BC_ASSERT_TRUE(tester->participants.find(bobAddrStr) != tester->participants.end()); BC_ASSERT_TRUE(tester->participants.find(aliceAddrStr) != tester->participants.end()); BC_ASSERT_TRUE(!tester->participants.find(bobAddrStr)->second); BC_ASSERT_TRUE(tester->participants.find(aliceAddrStr)->second); snprintf(notify_deleted, size2, participant_deleted_notify, confUri); Content content_deleted; content_deleted.setBodyFromUtf8(notify_deleted); content_deleted.setContentType(ContentType::ConferenceInfo); tester->handler->notifyReceived(content_deleted); delete[] notify_deleted; BC_ASSERT_EQUAL((int)tester->participants.size(), 1, int, "%d"); BC_ASSERT_EQUAL((int)tester->participantDevices.size(), 1, int, "%d"); BC_ASSERT_FALSE(tester->participants.find(bobAddrStr) != tester->participants.end()); bctbx_free(bobAddrStr); bctbx_free(aliceAddrStr); linphone_address_unref(bobAddr); linphone_address_unref(aliceAddr); tester = nullptr; linphone_core_manager_destroy(marie); } void participant_admined_parsing() { LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc"); LinphoneAddress *confAddress = linphone_core_interpret_url(marie->lc, confUri); std::shared_ptr<Address> addr = Address::toCpp(confAddress)->getSharedFromThis(); linphone_address_unref(confAddress); shared_ptr<ConferenceEventTester> tester = make_shared<ConferenceEventTester>(marie->lc->cppPtr, addr); LinphoneAddress *bobAddr = linphone_core_interpret_url(marie->lc, bobUri); LinphoneAddress *aliceAddr = linphone_core_interpret_url(marie->lc, aliceUri); size_t size = strlen(first_notify) + strlen(confUri); char *notify = new char[size]; size_t size2 = strlen(participant_admined_notify) + strlen(confUri); char *notify_admined = new char[size2]; const_cast<ConferenceId &>(tester->handler->getConferenceId()).setPeerAddress(addr); snprintf(notify, size, first_notify, confUri); Content content; content.setBodyFromUtf8(notify); content.setContentType(ContentType::ConferenceInfo); tester->handler->notifyReceived(content);
1331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400
delete[] notify; char *bobAddrStr = linphone_address_as_string(bobAddr); char *aliceAddrStr = linphone_address_as_string(aliceAddr); BC_ASSERT_EQUAL((int)tester->participants.size(), 2, int, "%d"); BC_ASSERT_TRUE(tester->participants.find(bobAddrStr) != tester->participants.end()); BC_ASSERT_TRUE(tester->participants.find(aliceAddrStr) != tester->participants.end()); BC_ASSERT_TRUE(!tester->participants.find(bobAddrStr)->second); BC_ASSERT_TRUE(tester->participants.find(aliceAddrStr)->second); snprintf(notify_admined, size2, participant_admined_notify, confUri); Content content_admined; content_admined.setBodyFromUtf8(notify_admined); content_admined.setContentType(ContentType::ConferenceInfo); tester->handler->notifyReceived(content_admined); delete[] notify_admined; BC_ASSERT_EQUAL((int)tester->participants.size(), 2, int, "%d"); BC_ASSERT_TRUE(tester->participants.find(bobAddrStr) != tester->participants.end()); BC_ASSERT_TRUE(tester->participants.find(bobAddrStr)->second); bctbx_free(bobAddrStr); bctbx_free(aliceAddrStr); linphone_address_unref(bobAddr); linphone_address_unref(aliceAddr); tester = nullptr; linphone_core_manager_destroy(marie); } void participant_unadmined_parsing() { LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc"); LinphoneAddress *confAddress = linphone_core_interpret_url(marie->lc, confUri); std::shared_ptr<Address> addr = Address::toCpp(confAddress)->getSharedFromThis(); linphone_address_unref(confAddress); shared_ptr<ConferenceEventTester> tester = make_shared<ConferenceEventTester>(marie->lc->cppPtr, addr); LinphoneAddress *bobAddr = linphone_core_interpret_url(marie->lc, bobUri); LinphoneAddress *aliceAddr = linphone_core_interpret_url(marie->lc, aliceUri); size_t size = strlen(first_notify) + strlen(confUri); char *notify = new char[size]; size_t size2 = strlen(participant_unadmined_notify) + strlen(confUri); char *notify_unadmined = new char[size2]; const_cast<ConferenceId &>(tester->handler->getConferenceId()).setPeerAddress(addr); snprintf(notify, size, first_notify, confUri); Content content; content.setBodyFromUtf8(notify); content.setContentType(ContentType::ConferenceInfo); tester->handler->notifyReceived(content); delete[] notify; char *bobAddrStr = linphone_address_as_string(bobAddr); char *aliceAddrStr = linphone_address_as_string(aliceAddr); BC_ASSERT_EQUAL((int)tester->participants.size(), 2, int, "%d"); BC_ASSERT_TRUE(tester->participants.find(bobAddrStr) != tester->participants.end()); BC_ASSERT_TRUE(tester->participants.find(aliceAddrStr) != tester->participants.end()); BC_ASSERT_TRUE(!tester->participants.find(bobAddrStr)->second); BC_ASSERT_TRUE(tester->participants.find(aliceAddrStr)->second); snprintf(notify_unadmined, size2, participant_unadmined_notify, confUri); Content content_unadmined; content_unadmined.setBodyFromUtf8(notify_unadmined); content_unadmined.setContentType(ContentType::ConferenceInfo);
1401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470
tester->handler->notifyReceived(content_unadmined); delete[] notify_unadmined; BC_ASSERT_EQUAL((int)tester->participants.size(), 2, int, "%d"); BC_ASSERT_TRUE(tester->participants.find(aliceAddrStr) != tester->participants.end()); BC_ASSERT_TRUE(!tester->participants.find(aliceAddrStr)->second); bctbx_free(bobAddrStr); bctbx_free(aliceAddrStr); linphone_address_unref(bobAddr); linphone_address_unref(aliceAddr); tester = nullptr; linphone_core_manager_destroy(marie); } void send_first_notify() { LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc"); LinphoneCoreManager *pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); std::shared_ptr<Address> addr = Address::toCpp(pauline->identity)->getSharedFromThis(); shared_ptr<ConferenceEventTester> tester = make_shared<ConferenceEventTester>(marie->lc->cppPtr, addr); shared_ptr<LocalConference> localConf = make_shared<LocalConference>(pauline->lc->cppPtr, addr, nullptr, ConferenceParams::create(pauline->lc)); std::shared_ptr<ConferenceListenerInterfaceTester> confListener = std::make_shared<ConferenceListenerInterfaceTester>(); localConf->addListener(confListener); LinphoneAddress *cBobAddr = linphone_core_interpret_url(marie->lc, bobUri); std::shared_ptr<Address> bobAddr = Address::toCpp(cBobAddr)->getSharedFromThis(); linphone_address_unref(cBobAddr); LinphoneAddress *cAliceAddr = linphone_core_interpret_url(marie->lc, aliceUri); std::shared_ptr<Address> aliceAddr = Address::toCpp(cAliceAddr)->getSharedFromThis(); linphone_address_unref(cAliceAddr); localConf->addParticipant(bobAddr); localConf->addParticipant(aliceAddr); localConf->setSubject("A random test subject"); shared_ptr<Participant> alice = localConf->findParticipant(aliceAddr); alice->setAdmin(true); LocalConferenceEventHandler *localHandler = (L_ATTR_GET(localConf.get(), eventHandler)).get(); localConf->setConferenceAddress(addr); Content content = localHandler->createNotifyFullState(NULL); const_cast<ConferenceId &>(tester->handler->getConferenceId()).setPeerAddress(addr); tester->handler->notifyReceived(content); BC_ASSERT_STRING_EQUAL(tester->confSubject.c_str(), "A random test subject"); BC_ASSERT_EQUAL((int)tester->participants.size(), 2, int, "%d"); BC_ASSERT_TRUE(tester->participants.find(bobAddr->toString()) != tester->participants.end()); BC_ASSERT_TRUE(tester->participants.find(aliceAddr->toString()) != tester->participants.end()); BC_ASSERT_TRUE(!tester->participants.find(bobAddr->toString())->second); BC_ASSERT_TRUE(tester->participants.find(aliceAddr->toString())->second); tester = nullptr; localConf = nullptr; alice = nullptr; linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } void send_added_notify_through_address() { LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc"); LinphoneCoreManager *pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); std::shared_ptr<Address> addr = Address::toCpp(pauline->identity)->getSharedFromThis(); shared_ptr<LocalConferenceTester> localConf = make_shared<LocalConferenceTester>(pauline->lc->cppPtr, addr, nullptr);
1471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540
std::shared_ptr<ConferenceListenerInterfaceTester> confListener = std::make_shared<ConferenceListenerInterfaceTester>(); localConf->addListener(confListener); LinphoneAddress *cBobAddr = linphone_core_interpret_url(marie->lc, bobUri); std::shared_ptr<Address> bobAddr = Address::toCpp(cBobAddr)->getSharedFromThis(); linphone_address_unref(cBobAddr); LinphoneAddress *cAliceAddr = linphone_core_interpret_url(marie->lc, aliceUri); std::shared_ptr<Address> aliceAddr = Address::toCpp(cAliceAddr)->getSharedFromThis(); linphone_address_unref(cAliceAddr); LinphoneAddress *cFrankAddr = linphone_core_interpret_url(marie->lc, frankUri); std::shared_ptr<Address> frankAddr = Address::toCpp(cFrankAddr)->getSharedFromThis(); linphone_address_unref(cFrankAddr); localConf->addParticipant(bobAddr); localConf->addParticipant(aliceAddr); setParticipantAsAdmin(localConf, aliceAddr, true); localConf->setConferenceAddress(addr); BC_ASSERT_EQUAL((int)confListener->participants.size(), 2, int, "%d"); BC_ASSERT_EQUAL((int)confListener->participantDevices.size(), 2, int, "%d"); BC_ASSERT_TRUE(confListener->participants.find(bobAddr->toString()) != confListener->participants.end()); BC_ASSERT_TRUE(confListener->participants.find(aliceAddr->toString()) != confListener->participants.end()); // Admin check BC_ASSERT_TRUE(!confListener->participants.find(bobAddr->toString())->second); BC_ASSERT_TRUE(confListener->participants.find(aliceAddr->toString())->second); unsigned int lastNotifyCount = confListener->lastNotify; localConf->notifyParticipantAdded(time(nullptr), false, Participant::create(localConf.get(), frankAddr)); BC_ASSERT_EQUAL((int)confListener->participants.size(), 3, int, "%d"); BC_ASSERT_EQUAL((int)confListener->participantDevices.size(), 3, int, "%d"); BC_ASSERT_TRUE(confListener->participants.find(bobAddr->toString()) != confListener->participants.end()); BC_ASSERT_TRUE(confListener->participants.find(aliceAddr->toString()) != confListener->participants.end()); BC_ASSERT_TRUE(confListener->participants.find(frankAddr->toString()) != confListener->participants.end()); // Admin check BC_ASSERT_TRUE(!confListener->participants.find(bobAddr->toString())->second); BC_ASSERT_TRUE(confListener->participants.find(aliceAddr->toString())->second); BC_ASSERT_TRUE(!confListener->participants.find(frankAddr->toString())->second); BC_ASSERT_EQUAL(localConf->getLastNotify(), (lastNotifyCount + 1), int, "%d"); localConf = nullptr; linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } static void remove_participant_from_conference_through_call(bctbx_list_t **removed_mgrs, bctbx_list_t **participants_mgrs, bctbx_list_t *lcs, std::shared_ptr<ConferenceListenerInterfaceTester> confListener, shared_ptr<MediaConference::LocalConference> conf, LinphoneCoreManager *conf_mgr, LinphoneCoreManager *participant_mgr) { stats initial_conf_stats = conf_mgr->stat; stats initial_participant_stats = participant_mgr->stat; stats *other_participants_initial_stats = NULL; bctbx_list_t *other_participants = NULL; int counter = 1; for (bctbx_list_t *it = *participants_mgrs; it; it = bctbx_list_next(it)) { LinphoneCoreManager *m = reinterpret_cast<LinphoneCoreManager *>(bctbx_list_get_data(it)); if ((m != participant_mgr) && (m != conf_mgr)) { // Allocate memory other_participants_initial_stats = (stats *)realloc(other_participants_initial_stats, counter * sizeof(stats)); // Append element other_participants_initial_stats[counter - 1] = m->stat; // Increment counter
1541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610
counter++; other_participants = bctbx_list_append(other_participants, m); } } LinphoneCall *confCall = linphone_core_get_call_by_remote_address2(conf_mgr->lc, participant_mgr->identity); int participantSize = (int)confListener->participants.size(); conf->removeParticipant(Call::toCpp(confCall)->getSharedFromThis()->getActiveSession(), true); // Remove participant from list of managers *participants_mgrs = bctbx_list_remove(*participants_mgrs, participant_mgr); *removed_mgrs = bctbx_list_append(*removed_mgrs, participant_mgr); // Calls are paused when removing a participant BC_ASSERT_TRUE(wait_for_list(lcs, &conf_mgr->stat.number_of_LinphoneCallPausing, (initial_conf_stats.number_of_LinphoneCallPausing + 1), 5000)); BC_ASSERT_TRUE(wait_for_list(lcs, &conf_mgr->stat.number_of_LinphoneCallPaused, (initial_conf_stats.number_of_LinphoneCallPaused + 1), 5000)); BC_ASSERT_TRUE(wait_for_list(lcs, &participant_mgr->stat.number_of_LinphoneCallPausedByRemote, (initial_participant_stats.number_of_LinphoneCallPausedByRemote + 1), 5000)); // Wait for conferences to be terminated BC_ASSERT_TRUE(wait_for_list(lcs, &participant_mgr->stat.number_of_LinphoneConferenceStateTerminationPending, (initial_participant_stats.number_of_LinphoneConferenceStateTerminationPending + 1), 5000)); BC_ASSERT_TRUE(wait_for_list(lcs, &participant_mgr->stat.number_of_LinphoneConferenceStateTerminated, (initial_participant_stats.number_of_LinphoneConferenceStateTerminated + 1), 5000)); BC_ASSERT_TRUE(wait_for_list(lcs, &participant_mgr->stat.number_of_LinphoneConferenceStateDeleted, (initial_participant_stats.number_of_LinphoneConferenceStateDeleted + 1), 5000)); int expectedParticipants = 0; if (participantSize == 2) { expectedParticipants = 0; } else { expectedParticipants = (participantSize - 1); } LinphoneCall *participantCall = linphone_core_get_current_call(participant_mgr->lc); BC_ASSERT_PTR_NOT_NULL(participantCall); if (participantCall) { const LinphoneAddress *cParticipantAddress = linphone_call_get_to_address(participantCall); std::string participantUri = Address::toCpp(const_cast<LinphoneAddress *>(cParticipantAddress))->asStringUriOnly(); BC_ASSERT_TRUE(confListener->participants.find(participantUri) == confListener->participants.end()); } // Other participants call should not have their state modified if (other_participants != NULL) { int idx = 0; for (bctbx_list_t *itm = other_participants; itm; itm = bctbx_list_next(itm)) { LinphoneCoreManager *m = reinterpret_cast<LinphoneCoreManager *>(bctbx_list_get_data(itm)); // If removing last participant, then its call is kicked out of conference // - Remote conference is deleted // - parameters are updated if (participantSize == 2) { BC_ASSERT_TRUE(wait_for_list( lcs, &m->stat.number_of_LinphoneCallUpdatedByRemote, (other_participants_initial_stats[idx].number_of_LinphoneCallUpdatedByRemote + 1), 5000)); BC_ASSERT_TRUE(wait_for_list( lcs, &m->stat.number_of_LinphoneCallStreamsRunning, (other_participants_initial_stats[idx].number_of_LinphoneCallStreamsRunning + 1), 5000)); BC_ASSERT_TRUE(wait_for_list( lcs, &participant_mgr->stat.number_of_LinphoneConferenceStateTerminationPending, (initial_participant_stats.number_of_LinphoneConferenceStateTerminationPending + 1), 5000)); BC_ASSERT_TRUE( wait_for_list(lcs, &participant_mgr->stat.number_of_LinphoneConferenceStateTerminated, (initial_participant_stats.number_of_LinphoneConferenceStateTerminated + 1), 5000));
1611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680
BC_ASSERT_TRUE(wait_for_list(lcs, &participant_mgr->stat.number_of_LinphoneConferenceStateDeleted, (initial_participant_stats.number_of_LinphoneConferenceStateDeleted + 1), 5000)); *participants_mgrs = bctbx_list_remove(*participants_mgrs, m); *removed_mgrs = bctbx_list_append(*removed_mgrs, m); } else { BC_ASSERT_EQUAL(m->stat.number_of_LinphoneCallStreamsRunning, other_participants_initial_stats[idx].number_of_LinphoneCallStreamsRunning, int, "%0d"); } BC_ASSERT_EQUAL(m->stat.number_of_LinphoneCallEnd, other_participants_initial_stats[idx].number_of_LinphoneCallEnd, int, "%0d"); BC_ASSERT_EQUAL(m->stat.number_of_LinphoneCallReleased, other_participants_initial_stats[idx].number_of_LinphoneCallReleased, int, "%0d"); idx++; } } BC_ASSERT_EQUAL((int)confListener->participants.size(), expectedParticipants, int, "%d"); BC_ASSERT_EQUAL((int)confListener->participantDevices.size(), expectedParticipants, int, "%d"); if (other_participants_initial_stats) { ms_free(other_participants_initial_stats); } if (other_participants) { bctbx_list_free(other_participants); } } static void remove_head_participant_list_from_conference_through_call( bctbx_list_t **removed_mgrs, bctbx_list_t **participants_mgrs, bctbx_list_t *lcs, std::shared_ptr<ConferenceListenerInterfaceTester> confListener, shared_ptr<MediaConference::LocalConference> conf, LinphoneCoreManager *conf_mgr) { LinphoneCoreManager *del_mgr = nullptr; for (bctbx_list_t *it = *participants_mgrs; it; it = bctbx_list_next(it)) { del_mgr = reinterpret_cast<LinphoneCoreManager *>(bctbx_list_get_data(it)); if (del_mgr != conf_mgr) { remove_participant_from_conference_through_call(removed_mgrs, participants_mgrs, lcs, confListener, conf, conf_mgr, del_mgr); break; } } } static LinphoneCall * add_participant_to_conference_through_call(bctbx_list_t **mgrs, bctbx_list_t *lcs, std::shared_ptr<ConferenceListenerInterfaceTester> &confListener, shared_ptr<MediaConference::LocalConference> &conf, LinphoneCoreManager *conf_mgr, LinphoneCoreManager *participant_mgr, bool_t pause_call) { stats initial_conf_stats = conf_mgr->stat; stats initial_participant_stats = participant_mgr->stat; int init_subscription_count = conf_mgr->subscription_received; stats *other_participants_initial_stats = NULL; bctbx_list_t *other_participants = NULL; int counter = 1; for (bctbx_list_t *it = *mgrs; it; it = bctbx_list_next(it)) { LinphoneCoreManager *m = reinterpret_cast<LinphoneCoreManager *>(bctbx_list_get_data(it)); if ((m != participant_mgr) && (m != conf_mgr)) { // Allocate memory other_participants_initial_stats =
1681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750
(stats *)realloc(other_participants_initial_stats, counter * sizeof(stats)); // Append element other_participants_initial_stats[counter - 1] = m->stat; // Increment counter counter++; other_participants = bctbx_list_append(other_participants, m); } } BC_ASSERT_TRUE(call(conf_mgr, participant_mgr)); LinphoneCall *participantCall = linphone_core_get_current_call(participant_mgr->lc); BC_ASSERT_PTR_NOT_NULL(participantCall); LinphoneCall *confCall = linphone_core_get_call_by_remote_address2(conf_mgr->lc, participant_mgr->identity); BC_ASSERT_PTR_NOT_NULL(confCall); if (pause_call) { if (participantCall) { BC_ASSERT_TRUE(linphone_call_get_state(participantCall) == LinphoneCallStreamsRunning); } if (confCall) { BC_ASSERT_TRUE(linphone_call_get_state(confCall) == LinphoneCallStreamsRunning); // Conference pauses the call linphone_call_pause(confCall); } BC_ASSERT_TRUE(wait_for_list(lcs, &conf_mgr->stat.number_of_LinphoneCallPaused, (initial_conf_stats.number_of_LinphoneCallPaused + 1), 5000)); BC_ASSERT_TRUE(wait_for_list(lcs, &participant_mgr->stat.number_of_LinphoneCallPausedByRemote, (initial_participant_stats.number_of_LinphoneCallPausedByRemote + 1), 5000)); } else { if (confCall) { BC_ASSERT_TRUE(linphone_call_get_state(confCall) != LinphoneCallPausing); BC_ASSERT_TRUE(linphone_call_get_state(confCall) != LinphoneCallPaused); } if (participantCall) { BC_ASSERT_TRUE(linphone_call_get_state(participantCall) != LinphoneCallPausedByRemote); } } participantCall = linphone_core_get_current_call(participant_mgr->lc); BC_ASSERT_PTR_NOT_NULL(participantCall); int participantSize = (int)confListener->participants.size(); int participantDeviceSize = (int)confListener->participantDevices.size(); conf->addParticipant(Call::toCpp(confCall)->getSharedFromThis()); // Prepend participant managers to ensure that conference focus is last *mgrs = bctbx_list_prepend(*mgrs, participant_mgr); BC_ASSERT_TRUE(wait_for_list(lcs, &participant_mgr->stat.number_of_LinphoneConferenceStateCreationPending, initial_participant_stats.number_of_LinphoneConferenceStateCreationPending + 1, 5000)); // Stream due to call and stream due to the addition to the conference BC_ASSERT_TRUE(wait_for_list(lcs, &conf_mgr->stat.number_of_LinphoneCallStreamsRunning, (initial_conf_stats.number_of_LinphoneCallStreamsRunning + 1), 5000)); BC_ASSERT_TRUE(wait_for_list( lcs, &participant_mgr->stat.number_of_LinphoneCallStreamsRunning, (initial_participant_stats.number_of_LinphoneCallStreamsRunning + 1 + (pause_call) ? 1 : 0), 5000)); if (pause_call) { BC_ASSERT_TRUE(wait_for_list(lcs, &conf_mgr->stat.number_of_LinphoneCallResuming, (initial_conf_stats.number_of_LinphoneCallResuming + 1), 5000)); } else { BC_ASSERT_TRUE(wait_for_list(lcs, &conf_mgr->stat.number_of_LinphoneCallUpdating, (initial_conf_stats.number_of_LinphoneCallUpdating + 1), 5000)); BC_ASSERT_TRUE(wait_for_list(lcs, &participant_mgr->stat.number_of_LinphoneCallUpdatedByRemote, (initial_participant_stats.number_of_LinphoneCallUpdatedByRemote + 1), 5000)); } BC_ASSERT_TRUE(wait_for_list(lcs, &conf_mgr->stat.number_of_LinphoneCallStreamsRunning,
1751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820
(initial_conf_stats.number_of_LinphoneCallStreamsRunning + 2), 5000)); BC_ASSERT_TRUE(wait_for_list( lcs, &participant_mgr->stat.number_of_LinphoneCallStreamsRunning, (initial_participant_stats.number_of_LinphoneCallStreamsRunning + 2 + (pause_call) ? 1 : 0), 5000)); // Check subscriptions BC_ASSERT_TRUE(wait_for_list(lcs, &participant_mgr->stat.number_of_LinphoneSubscriptionOutgoingProgress, (initial_participant_stats.number_of_LinphoneSubscriptionOutgoingProgress + 1), 5000)); BC_ASSERT_TRUE(wait_for_list(lcs, &conf_mgr->stat.number_of_LinphoneSubscriptionIncomingReceived, (initial_conf_stats.number_of_LinphoneSubscriptionIncomingReceived + 1), 5000)); BC_ASSERT_TRUE(wait_for_list(lcs, &conf_mgr->subscription_received, (init_subscription_count + 1), 5000)); BC_ASSERT_TRUE(wait_for_list(lcs, &participant_mgr->stat.number_of_NotifyFullStateReceived, (initial_participant_stats.number_of_NotifyFullStateReceived + 1), 5000)); if (other_participants != NULL) { int idx = 0; for (bctbx_list_t *itm = other_participants; itm; itm = bctbx_list_next(itm)) { LinphoneCoreManager *m = reinterpret_cast<LinphoneCoreManager *>(bctbx_list_get_data(itm)); BC_ASSERT_TRUE(wait_for_list(lcs, &m->stat.number_of_NotifyReceived, (other_participants_initial_stats[idx].number_of_NotifyReceived + 2), 5000)); idx++; } } // Number of subscription errors should not change as the participants should received a notification BC_ASSERT_EQUAL(conf_mgr->stat.number_of_LinphoneSubscriptionError, initial_conf_stats.number_of_LinphoneSubscriptionError, int, "%0d"); BC_ASSERT_EQUAL(participant_mgr->stat.number_of_LinphoneSubscriptionError, initial_participant_stats.number_of_LinphoneSubscriptionError, int, "%0d"); // Number of subscription terminated should not change as the participants should received a notification BC_ASSERT_EQUAL(conf_mgr->stat.number_of_LinphoneSubscriptionTerminated, initial_conf_stats.number_of_LinphoneSubscriptionTerminated, int, "%d"); BC_ASSERT_EQUAL(participant_mgr->stat.number_of_LinphoneSubscriptionTerminated, initial_participant_stats.number_of_LinphoneSubscriptionTerminated, int, "%d"); int increment = 0; if (participantSize == 0) { // Also me is added as participant increment = 2; } else { increment = 1; } BC_ASSERT_EQUAL((int)confListener->participants.size(), (participantSize + increment), int, "%d"); BC_ASSERT_EQUAL((int)confListener->participantDevices.size(), (participantDeviceSize + increment), int, "%d"); if (participantCall) { const LinphoneAddress *cParticipantAddress = linphone_call_get_to_address(participantCall); std::string participantUri = Address::toCpp(const_cast<LinphoneAddress *>(cParticipantAddress))->asStringUriOnly(); BC_ASSERT_TRUE(confListener->participants.find(participantUri) != confListener->participants.end()); // Admin check BC_ASSERT_TRUE(!confListener->participants.find(participantUri)->second); } if (other_participants_initial_stats) { ms_free(other_participants_initial_stats); } if (other_participants) { bctbx_list_free(other_participants); } return participantCall; }
1821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890
LinphoneCoreManager *create_core_and_add_to_conference(const char *rc_file, bctbx_list_t **mgrs, bctbx_list_t **lcs, std::shared_ptr<ConferenceListenerInterfaceTester> &confListener, shared_ptr<MediaConference::LocalConference> &conf, LinphoneCoreManager *conf_mgr, bool_t pause_call) { LinphoneCoreManager *mgr = create_mgr_for_conference(rc_file, TRUE, NULL); *lcs = bctbx_list_append(*lcs, mgr->lc); add_participant_to_conference_through_call(mgrs, *lcs, confListener, conf, conf_mgr, mgr, pause_call); return mgr; } void send_added_notify_through_call() { LinphoneCoreManager *pauline = create_mgr_for_conference( transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc", TRUE, NULL); LinphoneCoreManager *marie = NULL; LinphoneCoreManager *laure = NULL; bctbx_list_t *lcs = NULL; lcs = bctbx_list_append(lcs, pauline->lc); bctbx_list_t *mgrs = NULL; mgrs = bctbx_list_append(mgrs, pauline); std::shared_ptr<Address> addr = Address::toCpp(pauline->identity)->getSharedFromThis(); stats initialPaulineStats = pauline->stat; { shared_ptr<MediaConference::LocalConference> localConf = std::shared_ptr<MediaConference::LocalConference>( new MediaConference::LocalConference(pauline->lc->cppPtr, addr, nullptr, ConferenceParams::create(pauline->lc)), [](MediaConference::LocalConference *c) { c->unref(); }); BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneConferenceStateCreationPending, initialPaulineStats.number_of_LinphoneConferenceStateCreationPending + 1, 5000)); std::shared_ptr<ConferenceListenerInterfaceTester> confListener = std::make_shared<ConferenceListenerInterfaceTester>(); localConf->addListener(confListener); // Add participants // call not paused marie = create_core_and_add_to_conference("marie_rc", &mgrs, &lcs, confListener, localConf, pauline, FALSE); // call paused laure = create_core_and_add_to_conference((liblinphone_tester_ipv6_available()) ? "laure_tcp_rc" : "laure_rc_udp", &mgrs, &lcs, confListener, localConf, pauline, TRUE); BC_ASSERT_TRUE(wait_for_list(lcs, &laure->stat.number_of_LinphoneConferenceStateCreated, 1, 5000)); BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneConferenceStateCreated, initialPaulineStats.number_of_LinphoneConferenceStateCreated + 1, 5000)); BC_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneConferenceStateCreated, 1, 5000)); localConf->terminate(); for (bctbx_list_t *it = mgrs; it; it = bctbx_list_next(it)) { LinphoneCoreManager *m = reinterpret_cast<LinphoneCoreManager *>(bctbx_list_get_data(it)); // Wait for all calls to be terminated BC_ASSERT_TRUE(wait_for_list(lcs, &m->stat.number_of_LinphoneCallEnd, (int)bctbx_list_size(linphone_core_get_calls(m->lc)), 5000)); BC_ASSERT_TRUE(wait_for_list(lcs, &m->stat.number_of_LinphoneCallReleased, (int)bctbx_list_size(linphone_core_get_calls(m->lc)), 5000)); // Wait for all conferences to be terminated BC_ASSERT_TRUE(wait_for_list(lcs, &m->stat.number_of_LinphoneConferenceStateTerminationPending, m->stat.number_of_LinphoneConferenceStateCreated, 5000));
1891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960
BC_ASSERT_TRUE(wait_for_list(lcs, &m->stat.number_of_LinphoneConferenceStateTerminated, m->stat.number_of_LinphoneConferenceStateCreated, 5000)); BC_ASSERT_TRUE(wait_for_list(lcs, &m->stat.number_of_LinphoneConferenceStateDeleted, m->stat.number_of_LinphoneConferenceStateCreated, 5000)); } } destroy_mgr_in_conference(marie); destroy_mgr_in_conference(pauline); destroy_mgr_in_conference(laure); bctbx_list_free(lcs); bctbx_list_free(mgrs); } void send_removed_notify_through_call() { LinphoneCoreManager *pauline = create_mgr_for_conference( transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc", TRUE, NULL); LinphoneCoreManager *marie = NULL; LinphoneCoreManager *laure = NULL; LinphoneCoreManager *chloe = NULL; bctbx_list_t *lcs = NULL; lcs = bctbx_list_append(lcs, pauline->lc); bctbx_list_t *participants_mgrs = NULL; participants_mgrs = bctbx_list_append(participants_mgrs, pauline); bctbx_list_t *removed_mgrs = NULL; std::shared_ptr<Address> addr = Address::toCpp(pauline->identity)->getSharedFromThis(); stats initialPaulineStats = pauline->stat; { shared_ptr<MediaConference::LocalConference> localConf = std::shared_ptr<MediaConference::LocalConference>( new MediaConference::LocalConference(pauline->lc->cppPtr, addr, nullptr, ConferenceParams::create(pauline->lc)), [](MediaConference::LocalConference *c) { c->unref(); }); BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneConferenceStateCreationPending, initialPaulineStats.number_of_LinphoneConferenceStateCreationPending + 1, 5000)); std::shared_ptr<ConferenceListenerInterfaceTester> confListener = std::make_shared<ConferenceListenerInterfaceTester>(); localConf->addListener(confListener); // Add participants marie = create_core_and_add_to_conference("marie_rc", &participants_mgrs, &lcs, confListener, localConf, pauline, FALSE); chloe = create_core_and_add_to_conference("chloe_rc", &participants_mgrs, &lcs, confListener, localConf, pauline, FALSE); laure = create_core_and_add_to_conference((liblinphone_tester_ipv6_available()) ? "laure_tcp_rc" : "laure_rc_udp", &participants_mgrs, &lcs, confListener, localConf, pauline, TRUE); BC_ASSERT_TRUE(wait_for_list(lcs, &laure->stat.number_of_LinphoneConferenceStateCreated, 1, 5000)); BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneConferenceStateCreated, initialPaulineStats.number_of_LinphoneConferenceStateCreated + 1, 5000)); BC_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneConferenceStateCreated, 1, 5000)); for (bctbx_list_t *it = participants_mgrs; it; it = bctbx_list_next(it)) { LinphoneCoreManager *m = reinterpret_cast<LinphoneCoreManager *>(bctbx_list_get_data(it)); LinphoneCall *pCall = linphone_core_get_current_call(m->lc); if (m == pauline) { BC_ASSERT_PTR_NULL(pCall); } else { BC_ASSERT_PTR_NOT_NULL(pCall); } } remove_head_participant_list_from_conference_through_call(&removed_mgrs, &participants_mgrs, lcs, confListener,
1961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030
localConf, pauline); localConf->terminate(); for (bctbx_list_t *it = removed_mgrs; it; it = bctbx_list_next(it)) { LinphoneCoreManager *m = reinterpret_cast<LinphoneCoreManager *>(bctbx_list_get_data(it)); LinphoneCall *call = linphone_core_get_current_call(m->lc); if (call) { linphone_call_terminate(call); } BC_ASSERT_TRUE(wait_for_list(lcs, &m->stat.number_of_LinphoneCallEnd, (int)bctbx_list_size(linphone_core_get_calls(m->lc)), 5000)); BC_ASSERT_TRUE(wait_for_list(lcs, &m->stat.number_of_LinphoneCallReleased, (int)bctbx_list_size(linphone_core_get_calls(m->lc)), 5000)); } for (bctbx_list_t *it = participants_mgrs; it; it = bctbx_list_next(it)) { LinphoneCoreManager *m = reinterpret_cast<LinphoneCoreManager *>(bctbx_list_get_data(it)); // Wait for all calls to be terminated BC_ASSERT_TRUE(wait_for_list(lcs, &m->stat.number_of_LinphoneCallEnd, (int)bctbx_list_size(linphone_core_get_calls(m->lc)), 5000)); BC_ASSERT_TRUE(wait_for_list(lcs, &m->stat.number_of_LinphoneCallReleased, (int)bctbx_list_size(linphone_core_get_calls(m->lc)), 5000)); // Wait for all conferences to be terminated BC_ASSERT_TRUE(wait_for_list(lcs, &m->stat.number_of_LinphoneConferenceStateTerminationPending, m->stat.number_of_LinphoneConferenceStateCreated, 5000)); BC_ASSERT_TRUE(wait_for_list(lcs, &m->stat.number_of_LinphoneConferenceStateTerminated, m->stat.number_of_LinphoneConferenceStateCreated, 5000)); BC_ASSERT_TRUE(wait_for_list(lcs, &m->stat.number_of_LinphoneConferenceStateDeleted, m->stat.number_of_LinphoneConferenceStateCreated, 5000)); } } if (marie) destroy_mgr_in_conference(marie); if (pauline) destroy_mgr_in_conference(pauline); if (laure) destroy_mgr_in_conference(laure); if (chloe) destroy_mgr_in_conference(chloe); bctbx_list_free(lcs); bctbx_list_free(participants_mgrs); bctbx_list_free(removed_mgrs); } void send_removed_notify() { LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc"); LinphoneCoreManager *pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); std::shared_ptr<Address> addr = Address::toCpp(pauline->identity)->getSharedFromThis(); shared_ptr<LocalConferenceTester> localConf = make_shared<LocalConferenceTester>(pauline->lc->cppPtr, addr, nullptr); std::shared_ptr<ConferenceListenerInterfaceTester> confListener = std::make_shared<ConferenceListenerInterfaceTester>(); localConf->addListener(confListener); LinphoneAddress *cBobAddr = linphone_core_interpret_url(marie->lc, bobUri); std::shared_ptr<Address> bobAddr = Address::toCpp(cBobAddr)->getSharedFromThis(); linphone_address_unref(cBobAddr); LinphoneAddress *cAliceAddr = linphone_core_interpret_url(marie->lc, aliceUri); std::shared_ptr<Address> aliceAddr = Address::toCpp(cAliceAddr)->getSharedFromThis(); linphone_address_unref(cAliceAddr); localConf->addParticipant(bobAddr); localConf->addParticipant(aliceAddr); setParticipantAsAdmin(localConf, aliceAddr, true); localConf->setConferenceAddress(addr); BC_ASSERT_EQUAL((int)confListener->participants.size(), 2, int, "%d"); BC_ASSERT_EQUAL((int)confListener->participantDevices.size(), 2, int, "%d"); BC_ASSERT_TRUE(confListener->participants.find(bobAddr->toString()) != confListener->participants.end()); BC_ASSERT_TRUE(confListener->participants.find(aliceAddr->toString()) != confListener->participants.end()); // Admin check
2031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100
BC_ASSERT_TRUE(!confListener->participants.find(bobAddr->toString())->second); BC_ASSERT_TRUE(confListener->participants.find(aliceAddr->toString())->second); unsigned int lastNotifyCount = confListener->lastNotify; localConf->notifyParticipantRemoved(time(nullptr), false, localConf->findParticipant(bobAddr)); BC_ASSERT_EQUAL((int)confListener->participants.size(), 1, int, "%d"); BC_ASSERT_EQUAL((int)confListener->participantDevices.size(), 1, int, "%d"); BC_ASSERT_FALSE(confListener->participants.find(bobAddr->toString()) != confListener->participants.end()); BC_ASSERT_TRUE(confListener->participants.find(aliceAddr->toString()) != confListener->participants.end()); // Admin check BC_ASSERT_TRUE(confListener->participants.find(aliceAddr->toString())->second); BC_ASSERT_EQUAL(localConf->getLastNotify(), (lastNotifyCount + 1), int, "%d"); localConf = nullptr; linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } void send_admined_notify() { LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc"); LinphoneCoreManager *pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); std::shared_ptr<Address> addr = Address::toCpp(pauline->identity)->getSharedFromThis(); shared_ptr<LocalConferenceTester> localConf = make_shared<LocalConferenceTester>(pauline->lc->cppPtr, addr, nullptr); std::shared_ptr<ConferenceListenerInterfaceTester> confListener = std::make_shared<ConferenceListenerInterfaceTester>(); localConf->addListener(confListener); LinphoneAddress *cBobAddr = linphone_core_interpret_url(marie->lc, bobUri); std::shared_ptr<Address> bobAddr = Address::toCpp(cBobAddr)->getSharedFromThis(); linphone_address_unref(cBobAddr); LinphoneAddress *cAliceAddr = linphone_core_interpret_url(marie->lc, aliceUri); std::shared_ptr<Address> aliceAddr = Address::toCpp(cAliceAddr)->getSharedFromThis(); linphone_address_unref(cAliceAddr); localConf->addParticipant(bobAddr); localConf->addParticipant(aliceAddr); setParticipantAsAdmin(localConf, aliceAddr, true); localConf->setConferenceAddress(addr); BC_ASSERT_EQUAL((int)confListener->participants.size(), 2, int, "%d"); BC_ASSERT_TRUE(confListener->participants.find(bobAddr->toString()) != confListener->participants.end()); BC_ASSERT_TRUE(confListener->participants.find(aliceAddr->toString()) != confListener->participants.end()); // Admin check BC_ASSERT_TRUE(!confListener->participants.find(bobAddr->toString())->second); BC_ASSERT_TRUE(confListener->participants.find(aliceAddr->toString())->second); unsigned int lastNotifyCount = confListener->lastNotify; localConf->notifyParticipantSetAdmin(time(nullptr), false, localConf->findParticipant(bobAddr), true); BC_ASSERT_EQUAL((int)confListener->participants.size(), 2, int, "%d"); BC_ASSERT_TRUE(confListener->participants.find(bobAddr->toString()) != confListener->participants.end()); BC_ASSERT_TRUE(confListener->participants.find(aliceAddr->toString()) != confListener->participants.end()); // Admin check BC_ASSERT_TRUE(confListener->participants.find(aliceAddr->toString())->second); BC_ASSERT_TRUE(confListener->participants.find(bobAddr->toString())->second); BC_ASSERT_EQUAL(localConf->getLastNotify(), (lastNotifyCount + 1), int, "%d"); localConf = nullptr; linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } void send_unadmined_notify() { LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc"); LinphoneCoreManager *pauline =
2101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170
linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); std::shared_ptr<Address> addr = Address::toCpp(pauline->identity)->getSharedFromThis(); shared_ptr<LocalConferenceTester> localConf = make_shared<LocalConferenceTester>(pauline->lc->cppPtr, addr, nullptr); std::shared_ptr<ConferenceListenerInterfaceTester> confListener = std::make_shared<ConferenceListenerInterfaceTester>(); localConf->addListener(confListener); LinphoneAddress *cBobAddr = linphone_core_interpret_url(marie->lc, bobUri); std::shared_ptr<Address> bobAddr = Address::toCpp(cBobAddr)->getSharedFromThis(); linphone_address_unref(cBobAddr); LinphoneAddress *cAliceAddr = linphone_core_interpret_url(marie->lc, aliceUri); std::shared_ptr<Address> aliceAddr = Address::toCpp(cAliceAddr)->getSharedFromThis(); linphone_address_unref(cAliceAddr); localConf->addParticipant(bobAddr); localConf->addParticipant(aliceAddr); setParticipantAsAdmin(localConf, aliceAddr, true); localConf->setConferenceAddress(addr); BC_ASSERT_EQUAL((int)confListener->participants.size(), 2, int, "%d"); BC_ASSERT_TRUE(confListener->participants.find(bobAddr->toString()) != confListener->participants.end()); BC_ASSERT_TRUE(confListener->participants.find(aliceAddr->toString()) != confListener->participants.end()); // Admin check BC_ASSERT_TRUE(!confListener->participants.find(bobAddr->toString())->second); BC_ASSERT_TRUE(confListener->participants.find(aliceAddr->toString())->second); unsigned int lastNotifyCount = confListener->lastNotify; localConf->notifyParticipantSetAdmin(time(nullptr), false, localConf->findParticipant(aliceAddr), false); BC_ASSERT_EQUAL((int)confListener->participants.size(), 2, int, "%d"); BC_ASSERT_TRUE(confListener->participants.find(bobAddr->toString()) != confListener->participants.end()); BC_ASSERT_TRUE(confListener->participants.find(aliceAddr->toString()) != confListener->participants.end()); // Admin check BC_ASSERT_TRUE(!confListener->participants.find(aliceAddr->toString())->second); BC_ASSERT_TRUE(!confListener->participants.find(bobAddr->toString())->second); BC_ASSERT_EQUAL(localConf->getLastNotify(), (lastNotifyCount + 1), int, "%d"); localConf = nullptr; linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } void send_subject_changed_notify() { LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc"); LinphoneCoreManager *pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); std::shared_ptr<Address> addr = Address::toCpp(pauline->identity)->getSharedFromThis(); shared_ptr<LocalConferenceTester> localConf = make_shared<LocalConferenceTester>(pauline->lc->cppPtr, addr, nullptr); std::shared_ptr<ConferenceListenerInterfaceTester> confListener = std::make_shared<ConferenceListenerInterfaceTester>(); localConf->addListener(confListener); LinphoneAddress *cBobAddr = linphone_core_interpret_url(marie->lc, bobUri); std::shared_ptr<Address> bobAddr = Address::toCpp(cBobAddr)->getSharedFromThis(); linphone_address_unref(cBobAddr); LinphoneAddress *cAliceAddr = linphone_core_interpret_url(marie->lc, aliceUri); std::shared_ptr<Address> aliceAddr = Address::toCpp(cAliceAddr)->getSharedFromThis(); linphone_address_unref(cAliceAddr); localConf->addParticipant(bobAddr); localConf->addParticipant(aliceAddr); localConf->setSubject("A random test subject"); setParticipantAsAdmin(localConf, aliceAddr, true); localConf->setConferenceAddress(addr); BC_ASSERT_STRING_EQUAL(confListener->confSubject.c_str(), "A random test subject"); BC_ASSERT_EQUAL((int)confListener->participants.size(), 2, int, "%d"); BC_ASSERT_TRUE(confListener->participants.find(bobAddr->toString()) != confListener->participants.end()); BC_ASSERT_TRUE(confListener->participants.find(aliceAddr->toString()) != confListener->participants.end()); // Admin check
2171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240
BC_ASSERT_TRUE(!confListener->participants.find(bobAddr->toString())->second); BC_ASSERT_TRUE(confListener->participants.find(aliceAddr->toString())->second); unsigned int lastNotifyCount = confListener->lastNotify; localConf->setSubject("Another random test subject..."); BC_ASSERT_STRING_EQUAL(confListener->confSubject.c_str(), "Another random test subject..."); BC_ASSERT_EQUAL((int)confListener->participants.size(), 2, int, "%d"); BC_ASSERT_TRUE(confListener->participants.find(bobAddr->toString()) != confListener->participants.end()); BC_ASSERT_TRUE(confListener->participants.find(aliceAddr->toString()) != confListener->participants.end()); // Admin check BC_ASSERT_TRUE(!confListener->participants.find(bobAddr->toString())->second); BC_ASSERT_TRUE(confListener->participants.find(aliceAddr->toString())->second); BC_ASSERT_EQUAL(localConf->getLastNotify(), (lastNotifyCount + 1), int, "%d"); localConf = nullptr; linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } void send_device_added_notify() { LinphoneCoreManager *pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); LinphoneCoreCbs *cbs = linphone_factory_create_core_cbs(linphone_factory_get()); linphone_core_cbs_set_notify_sent(cbs, linphone_notify_sent); _linphone_core_add_callbacks(pauline->lc, cbs, TRUE); linphone_core_cbs_unref(cbs); std::shared_ptr<Address> addr = Address::toCpp(pauline->identity)->getSharedFromThis(); shared_ptr<LocalConferenceTester> localConf = make_shared<LocalConferenceTester>(pauline->lc->cppPtr, addr, nullptr); std::shared_ptr<ConferenceListenerInterfaceTester> confListener = std::make_shared<ConferenceListenerInterfaceTester>(); localConf->addListener(confListener); LinphoneAddress *cBobAddr = linphone_core_interpret_url(pauline->lc, bobUri); std::shared_ptr<Address> bobAddr = Address::toCpp(cBobAddr)->getSharedFromThis(); linphone_address_unref(cBobAddr); LinphoneAddress *cAliceAddr = linphone_core_interpret_url(pauline->lc, aliceUri); std::shared_ptr<Address> aliceAddr = Address::toCpp(cAliceAddr)->getSharedFromThis(); linphone_address_unref(cAliceAddr); localConf->addParticipant(bobAddr); localConf->addParticipant(aliceAddr); shared_ptr<Participant> alice = localConf->findParticipant(aliceAddr); setParticipantAsAdmin(localConf, aliceAddr, true); localConf->setConferenceAddress(addr); BC_ASSERT_EQUAL((int)confListener->participantDevices.size(), 2, int, "%d"); BC_ASSERT_TRUE(confListener->participantDevices.find(bobAddr->toString()) != confListener->participantDevices.end()); BC_ASSERT_TRUE(confListener->participantDevices.find(aliceAddr->toString()) != confListener->participantDevices.end()); BC_ASSERT_EQUAL(confListener->participantDevices.find(bobAddr->toString())->second, 0, int, "%d"); BC_ASSERT_EQUAL(confListener->participantDevices.find(aliceAddr->toString())->second, 0, int, "%d"); // Admin check BC_ASSERT_TRUE(!confListener->participants.find(bobAddr->toString())->second); BC_ASSERT_TRUE(confListener->participants.find(aliceAddr->toString())->second); localConf->notifyParticipantDeviceAdded(time(nullptr), false, alice, alice->findDevice(aliceAddr)); BC_ASSERT_EQUAL((int)confListener->participantDevices.size(), 2, int, "%d"); BC_ASSERT_TRUE(confListener->participantDevices.find(bobAddr->toString()) != confListener->participantDevices.end()); BC_ASSERT_TRUE(confListener->participantDevices.find(aliceAddr->toString()) != confListener->participantDevices.end()); BC_ASSERT_EQUAL(confListener->participantDevices.find(bobAddr->toString())->second, 0, int, "%d"); BC_ASSERT_EQUAL(confListener->participantDevices.find(aliceAddr->toString())->second, 1, int, "%d"); // Admin check BC_ASSERT_TRUE(!confListener->participants.find(bobAddr->toString())->second);
2241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310
BC_ASSERT_TRUE(confListener->participants.find(aliceAddr->toString())->second); for (const auto &p : localConf->getParticipants()) { for (const auto &d : p->getDevices()) { linphone_participant_device_set_state(d->toC(), LinphoneParticipantDeviceStatePresent); } } stats initial_pauline_stats = pauline->stat; auto op = new SalSubscribeOp(pauline->lc->sal.get()); SalAddress *toAddr = sal_address_new(linphone_core_get_identity(pauline->lc)); op->setToAddress(toAddr); op->setFrom(bobAddr->toString().c_str()); op->overrideRemoteContact(bobAddr->toString().c_str()); LinphoneAccount *default_account = linphone_core_get_default_account(pauline->lc); op->setRealm(linphone_account_params_get_realm(linphone_account_get_params(default_account))); const LinphoneAddress *contact = linphone_account_get_contact_address(default_account); SalAddress *contactAddr = sal_address_clone(Address::toCpp(const_cast<LinphoneAddress *>(contact))->getImpl()); op->setContactAddress(contactAddr); SalCustomHeader *ch = sal_custom_header_append(NULL, "Last-Notify-Version", std::to_string(localConf->getLastNotify() + 10).c_str()); op->setRecvCustomHeaders(ch); LinphoneEvent *lev = linphone_event_new_subscribe_with_op(pauline->lc, op, LinphoneSubscriptionIncoming, "conference"); linphone_event_set_state(lev, LinphoneSubscriptionIncomingReceived); localConf->subscribeReceived(dynamic_pointer_cast<EventSubscribe>(Event::toCpp(lev)->getSharedFromThis())); linphone_event_unref(lev); sal_address_unref(toAddr); sal_address_unref(contactAddr); sal_custom_header_unref(ch); BC_ASSERT_TRUE(wait_for_until(pauline->lc, NULL, &pauline->stat.number_of_NotifySent, (initial_pauline_stats.number_of_NotifySent + 1), 5000)); void *notify_body = linphone_event_get_user_data(lev); BC_ASSERT_PTR_NOT_NULL(notify_body); if (notify_body) { LinphoneContent *notify_content = (LinphoneContent *)notify_body; BC_ASSERT_STRING_EQUAL(linphone_content_get_type(notify_content), "application"); BC_ASSERT_STRING_EQUAL(linphone_content_get_subtype(notify_content), "conference-info+xml"); BC_ASSERT_TRUE(linphone_conference_type_is_full_state(linphone_content_get_utf8_text(notify_content))); linphone_content_unref(notify_content); } localConf = nullptr; alice = nullptr; linphone_core_manager_destroy(pauline); } void send_device_removed_notify() { LinphoneCoreManager *pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); std::shared_ptr<Address> addr = Address::toCpp(pauline->identity)->getSharedFromThis(); shared_ptr<LocalConferenceTester> localConf = make_shared<LocalConferenceTester>(pauline->lc->cppPtr, addr, nullptr); std::shared_ptr<ConferenceListenerInterfaceTester> confListener = std::make_shared<ConferenceListenerInterfaceTester>(); localConf->addListener(confListener); LinphoneAddress *cBobAddr = linphone_core_interpret_url(pauline->lc, bobUri); std::shared_ptr<Address> bobAddr = Address::toCpp(cBobAddr)->getSharedFromThis(); linphone_address_unref(cBobAddr); LinphoneAddress *cAliceAddr = linphone_core_interpret_url(pauline->lc, aliceUri); std::shared_ptr<Address> aliceAddr = Address::toCpp(cAliceAddr)->getSharedFromThis(); linphone_address_unref(cAliceAddr); localConf->addParticipant(bobAddr); localConf->addParticipant(aliceAddr);
2311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380
localConf->setSubject("A random test subject"); shared_ptr<Participant> alice = localConf->findParticipant(aliceAddr); setParticipantAsAdmin(localConf, aliceAddr, true); localConf->setConferenceAddress(addr); BC_ASSERT_EQUAL((int)confListener->participantDevices.size(), 2, int, "%d"); BC_ASSERT_TRUE(confListener->participantDevices.find(bobAddr->toString()) != confListener->participantDevices.end()); BC_ASSERT_TRUE(confListener->participantDevices.find(aliceAddr->toString()) != confListener->participantDevices.end()); BC_ASSERT_EQUAL(confListener->participantDevices.find(bobAddr->toString())->second, 0, int, "%d"); BC_ASSERT_EQUAL(confListener->participantDevices.find(aliceAddr->toString())->second, 0, int, "%d"); localConf->notifyParticipantDeviceAdded(time(nullptr), false, alice, alice->findDevice(aliceAddr)); BC_ASSERT_EQUAL((int)confListener->participantDevices.size(), 2, int, "%d"); BC_ASSERT_TRUE(confListener->participantDevices.find(bobAddr->toString()) != confListener->participantDevices.end()); BC_ASSERT_TRUE(confListener->participantDevices.find(aliceAddr->toString()) != confListener->participantDevices.end()); BC_ASSERT_EQUAL(confListener->participantDevices.find(bobAddr->toString())->second, 0, int, "%d"); BC_ASSERT_EQUAL(confListener->participantDevices.find(aliceAddr->toString())->second, 1, int, "%d"); localConf->notifyParticipantDeviceRemoved(time(nullptr), false, alice, alice->findDevice(aliceAddr)); BC_ASSERT_EQUAL((int)confListener->participantDevices.size(), 2, int, "%d"); BC_ASSERT_TRUE(confListener->participantDevices.find(bobAddr->toString()) != confListener->participantDevices.end()); BC_ASSERT_TRUE(confListener->participantDevices.find(aliceAddr->toString()) != confListener->participantDevices.end()); BC_ASSERT_EQUAL(confListener->participantDevices.find(bobAddr->toString())->second, 0, int, "%d"); BC_ASSERT_EQUAL(confListener->participantDevices.find(aliceAddr->toString())->second, 0, int, "%d"); localConf = nullptr; alice = nullptr; linphone_core_manager_destroy(pauline); } void one_to_one_keyword() { LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc"); LinphoneCoreManager *pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); std::shared_ptr<Address> addr = Address::toCpp(pauline->identity)->getSharedFromThis(); shared_ptr<ConferenceEventTester> tester = make_shared<ConferenceEventTester>(marie->lc->cppPtr, addr); shared_ptr<LocalConference> localConf = make_shared<LocalConference>(pauline->lc->cppPtr, addr, nullptr, ConferenceParams::create(pauline->lc)); std::shared_ptr<ConferenceListenerInterfaceTester> confListener = std::make_shared<ConferenceListenerInterfaceTester>(); localConf->addListener(confListener); LinphoneAddress *cBobAddr = linphone_core_interpret_url(marie->lc, bobUri); std::shared_ptr<Address> bobAddr = Address::toCpp(cBobAddr)->getSharedFromThis(); linphone_address_unref(cBobAddr); // Create basic chat room with OneToOne capability to ensure that one to one is added to notify pauline->lc->cppPtr->getOrCreateBasicChatRoom(addr, addr); localConf->addParticipant(bobAddr); LocalConferenceEventHandler *localHandler = (L_ATTR_GET(localConf.get(), eventHandler)).get(); localConf->setConferenceAddress(addr); Content content = localHandler->createNotifyFullState(NULL); const_cast<ConferenceId &>(tester->handler->getConferenceId()).setPeerAddress(addr); tester->handler->notifyReceived(content); BC_ASSERT_EQUAL((int)tester->participantDevices.size(), 1, int, "%d"); BC_ASSERT_TRUE(tester->participantDevices.find(bobAddr->toString()) != tester->participantDevices.end()); BC_ASSERT_EQUAL(tester->participantDevices.find(bobAddr->toString())->second, 0, int, "%d"); BC_ASSERT_TRUE(tester->oneToOne);
238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416
tester = nullptr; localConf = nullptr; linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } test_t conference_event_tests[] = { TEST_NO_TAG("First notify parsing", first_notify_parsing), TEST_NO_TAG("First notify with extensions parsing", first_notify_with_extensions_parsing), TEST_NO_TAG("First notify parsing wrong conf", first_notify_parsing_wrong_conf), TEST_NO_TAG("Participant added", participant_added_parsing), TEST_NO_TAG("Participant not added", participant_not_added_parsing), TEST_NO_TAG("Participant deleted", participant_deleted_parsing), TEST_NO_TAG("Participant admined", participant_admined_parsing), TEST_NO_TAG("Participant unadmined", participant_unadmined_parsing), TEST_NO_TAG("Send first notify", send_first_notify), TEST_NO_TAG("Send participant added notify through address", send_added_notify_through_address), TEST_NO_TAG("Send participant added notify through call", send_added_notify_through_call), TEST_NO_TAG("Send participant removed notify through call", send_removed_notify_through_call), TEST_NO_TAG("Send participant removed notify", send_removed_notify), TEST_NO_TAG("Send participant admined notify", send_admined_notify), TEST_NO_TAG("Send participant unadmined notify", send_unadmined_notify), TEST_NO_TAG("Send subject changed notify", send_subject_changed_notify), TEST_NO_TAG("Send device added notify", send_device_added_notify), TEST_NO_TAG("Send device removed notify", send_device_removed_notify), TEST_NO_TAG("one-to-one keyword", one_to_one_keyword)}; test_suite_t conference_event_test_suite = {"Conference event", nullptr, nullptr, liblinphone_tester_before_each, liblinphone_tester_after_each, sizeof(conference_event_tests) / sizeof(conference_event_tests[0]), conference_event_tests, 0};