LCOV - code coverage report
Current view: top level - test/unitTest/sip_account - sip_srtp.cpp (source / functions) Hit Total Coverage
Test: jami-coverage-filtered.info Lines: 230 249 92.4 %
Date: 2024-12-21 08:56:24 Functions: 25 25 100.0 %

          Line data    Source code
       1             : /*
       2             :  *  Copyright (C) 2004-2024 Savoir-faire Linux Inc.
       3             :  *
       4             :  *  This program is free software: you can redistribute it and/or modify
       5             :  *  it under the terms of the GNU General Public License as published by
       6             :  *  the Free Software Foundation, either version 3 of the License, or
       7             :  *  (at your option) any later version.
       8             :  *
       9             :  *  This program is distributed in the hope that it will be useful,
      10             :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
      12             :  *  GNU General Public License for more details.
      13             :  *
      14             :  *  You should have received a copy of the GNU General Public License
      15             :  *  along with this program. If not, see <https://www.gnu.org/licenses/>.
      16             :  */
      17             : 
      18             : #include <cppunit/TestAssert.h>
      19             : #include <cppunit/TestFixture.h>
      20             : #include <cppunit/extensions/HelperMacros.h>
      21             : 
      22             : #include <condition_variable>
      23             : #include <string>
      24             : 
      25             : #include "callmanager_interface.h"
      26             : #include "manager.h"
      27             : #include "sip/sipaccount.h"
      28             : #include "../../test_runner.h"
      29             : #include "jami.h"
      30             : #include "jami/media_const.h"
      31             : #include "call_const.h"
      32             : #include "account_const.h"
      33             : #include "sip/sipcall.h"
      34             : #include "sip/sdp.h"
      35             : using namespace libjami::Account;
      36             : using namespace libjami::Call;
      37             : 
      38             : namespace jami {
      39             : namespace test {
      40             : 
      41             : struct CallData
      42             : {
      43             :     struct Signal
      44             :     {
      45          12 :         Signal(const std::string& name, const std::string& event = {})
      46          12 :             : name_(std::move(name))
      47          12 :             , event_(std::move(event)) {};
      48             : 
      49             :         std::string name_ {};
      50             :         std::string event_ {};
      51             :     };
      52             : 
      53             :     std::string accountId_ {};
      54             :     uint16_t listeningPort_ {0};
      55             :     std::string userName_ {};
      56             :     std::string alias_ {};
      57             :     std::string callId_ {};
      58             :     std::vector<Signal> signals_;
      59             :     std::condition_variable cv_ {};
      60             :     std::mutex mtx_;
      61             : };
      62             : 
      63             : /**
      64             :  * Call tests for SIP accounts.
      65             :  */
      66             : class SipSrtpTest : public CppUnit::TestFixture
      67             : {
      68             : public:
      69           1 :     SipSrtpTest()
      70           1 :     {
      71             :         // Init daemon
      72           1 :         libjami::init(libjami::InitFlag(libjami::LIBJAMI_FLAG_DEBUG | libjami::LIBJAMI_FLAG_CONSOLE_LOG));
      73           1 :         if (not Manager::instance().initialized)
      74           1 :             CPPUNIT_ASSERT(libjami::start("dring-sample.yml"));
      75           1 :     }
      76           2 :     ~SipSrtpTest() { libjami::fini(); }
      77             : 
      78           2 :     static std::string name() { return "SipSrtpTest"; }
      79             :     void setUp();
      80             :     void tearDown();
      81             : 
      82             : private:
      83             :     // Test cases.
      84             :     void audio_video_srtp_enabled_test();
      85             : 
      86           2 :     CPPUNIT_TEST_SUITE(SipSrtpTest);
      87           1 :     CPPUNIT_TEST(audio_video_srtp_enabled_test);
      88             : 
      89           4 :     CPPUNIT_TEST_SUITE_END();
      90             : 
      91             :     // Event/Signal handlers
      92             :     static void onCallStateChange(const std::string& accountId,
      93             :                                   const std::string& callId,
      94             :                                   const std::string& state,
      95             :                                   CallData& callData);
      96             :     static void onIncomingCallWithMedia(const std::string& accountId,
      97             :                                         const std::string& callId,
      98             :                                         const std::vector<libjami::MediaMap> mediaList,
      99             :                                         CallData& callData);
     100             :     static void onMediaNegotiationStatus(const std::string& callId,
     101             :                                          const std::string& event,
     102             :                                          CallData& callData);
     103             : 
     104             :     // Helpers
     105             :     void audio_video_call(std::vector<MediaAttribute> offer,
     106             :                           std::vector<MediaAttribute> answer,
     107             :                           bool validateMedia = true);
     108             :     static void configureTest(CallData& bob, CallData& alice);
     109             :     static std::string getUserAlias(const std::string& callId);
     110             :     // Wait for a signal from the callbacks. Some signals also report the event that
     111             :     // triggered the signal a like the StateChange signal.
     112             :     static bool waitForSignal(CallData& callData,
     113             :                               const std::string& signal,
     114             :                               const std::string& expectedEvent = {});
     115             : 
     116             : private:
     117             :     CallData aliceData_;
     118             :     CallData bobData_;
     119             : };
     120             : 
     121             : CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(SipSrtpTest, SipSrtpTest::name());
     122             : 
     123             : void
     124           1 : SipSrtpTest::setUp()
     125             : {
     126           1 :     aliceData_.listeningPort_ = 5080;
     127           2 :     std::map<std::string, std::string> details = libjami::getAccountTemplate("SIP");
     128           1 :     details[ConfProperties::TYPE] = "SIP";
     129           1 :     details[ConfProperties::DISPLAYNAME] = "ALICE";
     130           1 :     details[ConfProperties::ALIAS] = "ALICE";
     131           1 :     details[ConfProperties::LOCAL_PORT] = std::to_string(aliceData_.listeningPort_);
     132           1 :     details[ConfProperties::UPNP_ENABLED] = "false";
     133           1 :     details[ConfProperties::SRTP::KEY_EXCHANGE] = "sdes";
     134           1 :     aliceData_.accountId_ = Manager::instance().addAccount(details);
     135             : 
     136           1 :     bobData_.listeningPort_ = 5082;
     137           1 :     details = libjami::getAccountTemplate("SIP");
     138           1 :     details[ConfProperties::TYPE] = "SIP";
     139           1 :     details[ConfProperties::DISPLAYNAME] = "BOB";
     140           1 :     details[ConfProperties::ALIAS] = "BOB";
     141           1 :     details[ConfProperties::LOCAL_PORT] = std::to_string(bobData_.listeningPort_);
     142           1 :     details[ConfProperties::UPNP_ENABLED] = "false";
     143           1 :     details[ConfProperties::SRTP::KEY_EXCHANGE] = "sdes";
     144           1 :     bobData_.accountId_ = Manager::instance().addAccount(details);
     145             : 
     146           1 :     JAMI_INFO("Initialize accounts ...");
     147           1 :     auto aliceAccount = Manager::instance().getAccount<SIPAccount>(aliceData_.accountId_);
     148           1 :     auto bobAccount = Manager::instance().getAccount<SIPAccount>(bobData_.accountId_);
     149           1 : }
     150             : 
     151             : void
     152           1 : SipSrtpTest::tearDown()
     153             : {
     154           1 :     JAMI_INFO("Remove created accounts...");
     155             : 
     156           1 :     std::map<std::string, std::shared_ptr<libjami::CallbackWrapperBase>> confHandlers;
     157           1 :     std::mutex mtx;
     158           1 :     std::unique_lock lk {mtx};
     159           1 :     std::condition_variable cv;
     160           1 :     auto currentAccSize = Manager::instance().getAccountList().size();
     161           1 :     std::atomic_bool accountsRemoved {false};
     162           1 :     confHandlers.insert(
     163           2 :         libjami::exportable_callback<libjami::ConfigurationSignal::AccountsChanged>([&]() {
     164           2 :             if (Manager::instance().getAccountList().size() <= currentAccSize - 2) {
     165           1 :                 accountsRemoved = true;
     166           1 :                 cv.notify_one();
     167             :             }
     168           2 :         }));
     169           1 :     libjami::registerSignalHandlers(confHandlers);
     170             : 
     171           1 :     Manager::instance().removeAccount(aliceData_.accountId_, true);
     172           1 :     Manager::instance().removeAccount(bobData_.accountId_, true);
     173             :     // Because cppunit is not linked with dbus, just poll if removed
     174           2 :     CPPUNIT_ASSERT(
     175             :         cv.wait_for(lk, std::chrono::seconds(30), [&] { return accountsRemoved.load(); }));
     176             : 
     177           1 :     libjami::unregisterSignalHandlers();
     178           1 : }
     179             : 
     180             : std::string
     181          14 : SipSrtpTest::getUserAlias(const std::string& callId)
     182             : {
     183          14 :     auto call = Manager::instance().getCallFromCallID(callId);
     184             : 
     185          14 :     if (not call) {
     186           2 :         JAMI_WARN("Call with ID [%s] does not exist anymore!", callId.c_str());
     187           2 :         return {};
     188             :     }
     189             : 
     190          12 :     auto const& account = call->getAccount().lock();
     191          12 :     if (not account) {
     192           0 :         return {};
     193             :     }
     194             : 
     195          12 :     return account->getAccountDetails()[ConfProperties::ALIAS];
     196          14 : }
     197             : 
     198             : void
     199           1 : SipSrtpTest::onIncomingCallWithMedia(const std::string& accountId,
     200             :                                      const std::string& callId,
     201             :                                      const std::vector<libjami::MediaMap> mediaList,
     202             :                                      CallData& callData)
     203             : {
     204           1 :     CPPUNIT_ASSERT_EQUAL(callData.accountId_, accountId);
     205             : 
     206           1 :     JAMI_INFO("Signal [%s] - user [%s] - call [%s] - media count [%lu]",
     207             :               libjami::CallSignal::IncomingCallWithMedia::name,
     208             :               callData.alias_.c_str(),
     209             :               callId.c_str(),
     210             :               mediaList.size());
     211             : 
     212             :     // NOTE.
     213             :     // We shouldn't access shared_ptr<Call> as this event is supposed to mimic
     214             :     // the client, and the client have no access to this type. But here, we only
     215             :     // needed to check if the call exists. This is the most straightforward and
     216             :     // reliable way to do it until we add a new API (like hasCall(id)).
     217           1 :     if (not Manager::instance().getCallFromCallID(callId)) {
     218           0 :         JAMI_WARN("Call with ID [%s] does not exist!", callId.c_str());
     219           0 :         callData.callId_ = {};
     220           0 :         return;
     221             :     }
     222             : 
     223           1 :     std::unique_lock lock {callData.mtx_};
     224           1 :     callData.callId_ = callId;
     225           1 :     callData.signals_.emplace_back(CallData::Signal(libjami::CallSignal::IncomingCallWithMedia::name));
     226             : 
     227           1 :     callData.cv_.notify_one();
     228           1 : }
     229             : 
     230             : void
     231           9 : SipSrtpTest::onCallStateChange(const std::string&,
     232             :                                const std::string& callId,
     233             :                                const std::string& state,
     234             :                                CallData& callData)
     235             : {
     236           9 :     auto call = Manager::instance().getCallFromCallID(callId);
     237           9 :     if (not call) {
     238           0 :         JAMI_WARN("Call with ID [%s] does not exist anymore!", callId.c_str());
     239           0 :         return;
     240             :     }
     241             : 
     242           9 :     auto account = call->getAccount().lock();
     243           9 :     if (not account) {
     244           0 :         JAMI_WARN("Account owning the call [%s] does not exist!", callId.c_str());
     245           0 :         return;
     246             :     }
     247             : 
     248           9 :     JAMI_INFO("Signal [%s] - user [%s] - call [%s] - state [%s]",
     249             :               libjami::CallSignal::StateChange::name,
     250             :               callData.alias_.c_str(),
     251             :               callId.c_str(),
     252             :               state.c_str());
     253             : 
     254           9 :     if (account->getAccountID() != callData.accountId_)
     255           0 :         return;
     256             : 
     257             :     {
     258           9 :         std::unique_lock lock {callData.mtx_};
     259           9 :         callData.signals_.emplace_back(
     260          18 :             CallData::Signal(libjami::CallSignal::StateChange::name, state));
     261           9 :     }
     262             :     // NOTE. Only states that we are interested on will notify the CV. If this
     263             :     // unit test is modified to process other states, they must be added here.
     264           9 :     if (state == "CURRENT" or state == "OVER" or state == "HUNGUP" or state == "RINGING") {
     265           5 :         callData.cv_.notify_one();
     266             :     }
     267           9 : }
     268             : 
     269             : void
     270           2 : SipSrtpTest::onMediaNegotiationStatus(const std::string& callId,
     271             :                                       const std::string& event,
     272             :                                       CallData& callData)
     273             : {
     274           2 :     auto call = Manager::instance().getCallFromCallID(callId);
     275           2 :     if (not call) {
     276           0 :         JAMI_WARN("Call with ID [%s] does not exist!", callId.c_str());
     277           0 :         return;
     278             :     }
     279             : 
     280           2 :     auto account = call->getAccount().lock();
     281           2 :     if (not account) {
     282           0 :         JAMI_WARN("Account owning the call [%s] does not exist!", callId.c_str());
     283           0 :         return;
     284             :     }
     285             : 
     286           2 :     JAMI_INFO("Signal [%s] - user [%s] - call [%s] - state [%s]",
     287             :               libjami::CallSignal::MediaNegotiationStatus::name,
     288             :               account->getAccountDetails()[ConfProperties::ALIAS].c_str(),
     289             :               call->getCallId().c_str(),
     290             :               event.c_str());
     291             : 
     292           2 :     if (account->getAccountID() != callData.accountId_)
     293           0 :         return;
     294             : 
     295             :     {
     296           2 :         std::unique_lock lock {callData.mtx_};
     297           2 :         callData.signals_.emplace_back(
     298           4 :             CallData::Signal(libjami::CallSignal::MediaNegotiationStatus::name, event));
     299           2 :     }
     300             : 
     301           2 :     callData.cv_.notify_one();
     302           2 : }
     303             : 
     304             : bool
     305           6 : SipSrtpTest::waitForSignal(CallData& callData,
     306             :                            const std::string& expectedSignal,
     307             :                            const std::string& expectedEvent)
     308             : {
     309           6 :     const std::chrono::seconds TIME_OUT {30};
     310           6 :     std::unique_lock lock {callData.mtx_};
     311             : 
     312             :     // Combined signal + event (if any).
     313           6 :     std::string sigEvent(expectedSignal);
     314           6 :     if (not expectedEvent.empty())
     315           5 :         sigEvent += "::" + expectedEvent;
     316             : 
     317           6 :     JAMI_INFO("[%s] is waiting for [%s] signal/event", callData.alias_.c_str(), sigEvent.c_str());
     318             : 
     319           6 :     auto res = callData.cv_.wait_for(lock, TIME_OUT, [&] {
     320             :         // Search for the expected signal in list of received signals.
     321           9 :         bool pred = false;
     322          32 :         for (auto it = callData.signals_.begin(); it != callData.signals_.end(); it++) {
     323             :             // The predicate is true if the signal names match, and if the
     324             :             // expectedEvent is not empty, the events must also match.
     325          29 :             if (it->name_ == expectedSignal
     326          29 :                 and (expectedEvent.empty() or it->event_ == expectedEvent)) {
     327           6 :                 pred = true;
     328             :                 // Done with this signal.
     329           6 :                 callData.signals_.erase(it);
     330           6 :                 break;
     331             :             }
     332             :         }
     333             : 
     334           9 :         return pred;
     335             :     });
     336             : 
     337           6 :     if (not res) {
     338           0 :         JAMI_ERR("[%s] waiting for signal/event [%s] timed-out!",
     339             :                  callData.alias_.c_str(),
     340             :                  sigEvent.c_str());
     341             : 
     342           0 :         JAMI_INFO("[%s] currently has the following signals:", callData.alias_.c_str());
     343             : 
     344           0 :         for (auto const& sig : callData.signals_) {
     345           0 :             JAMI_INFO() << "Signal [" << sig.name_
     346           0 :                         << (sig.event_.empty() ? "" : ("::" + sig.event_)) << "]";
     347             :         }
     348             :     }
     349             : 
     350           6 :     return res;
     351           6 : }
     352             : 
     353             : void
     354           1 : SipSrtpTest::configureTest(CallData& aliceData, CallData& bobData)
     355             : {
     356             :     {
     357           1 :         CPPUNIT_ASSERT(not aliceData.accountId_.empty());
     358           1 :         auto const& account = Manager::instance().getAccount<SIPAccount>(aliceData.accountId_);
     359           1 :         aliceData.userName_ = account->getAccountDetails()[ConfProperties::USERNAME];
     360           1 :         aliceData.alias_ = account->getAccountDetails()[ConfProperties::ALIAS];
     361           1 :         account->setLocalPort(aliceData.listeningPort_);
     362           1 :     }
     363             : 
     364             :     {
     365           1 :         CPPUNIT_ASSERT(not bobData.accountId_.empty());
     366           1 :         auto const& account = Manager::instance().getAccount<SIPAccount>(bobData.accountId_);
     367           1 :         bobData.userName_ = account->getAccountDetails()[ConfProperties::USERNAME];
     368           1 :         bobData.alias_ = account->getAccountDetails()[ConfProperties::ALIAS];
     369           1 :         account->setLocalPort(bobData.listeningPort_);
     370           1 :     }
     371             : 
     372           1 :     std::map<std::string, std::shared_ptr<libjami::CallbackWrapperBase>> signalHandlers;
     373             : 
     374             :     // Insert needed signal handlers.
     375           1 :     signalHandlers.insert(libjami::exportable_callback<libjami::CallSignal::IncomingCallWithMedia>(
     376           1 :         [&](const std::string& accountId,
     377             :             const std::string& callId,
     378             :             const std::string&,
     379             :             const std::vector<libjami::MediaMap> mediaList) {
     380           1 :             auto user = getUserAlias(callId);
     381           1 :             if (not user.empty())
     382           1 :                 onIncomingCallWithMedia(accountId,
     383             :                                         callId,
     384             :                                         mediaList,
     385           1 :                                         user == aliceData.alias_ ? aliceData : bobData);
     386           1 :         }));
     387             : 
     388           1 :     signalHandlers.insert(
     389           2 :         libjami::exportable_callback<libjami::CallSignal::StateChange>([&](const std::string& accountId,
     390             :                                                                        const std::string& callId,
     391             :                                                                        const std::string& state,
     392             :                                                                        signed) {
     393          11 :             auto user = getUserAlias(callId);
     394          11 :             if (not user.empty())
     395           9 :                 onCallStateChange(accountId,
     396             :                                   callId,
     397             :                                   state,
     398           9 :                                   user == aliceData.alias_ ? aliceData : bobData);
     399          11 :         }));
     400             : 
     401           1 :     signalHandlers.insert(libjami::exportable_callback<libjami::CallSignal::MediaNegotiationStatus>(
     402           2 :         [&](const std::string& callId,
     403             :             const std::string& event,
     404             :             const std::vector<std::map<std::string, std::string>>& /* mediaList */) {
     405           2 :             auto user = getUserAlias(callId);
     406           2 :             if (not user.empty())
     407           2 :                 onMediaNegotiationStatus(callId,
     408             :                                          event,
     409           2 :                                          user == aliceData.alias_ ? aliceData : bobData);
     410           2 :         }));
     411             : 
     412           1 :     libjami::registerSignalHandlers(signalHandlers);
     413           1 : }
     414             : 
     415             : void
     416           1 : SipSrtpTest::audio_video_call(std::vector<MediaAttribute> offer,
     417             :                               std::vector<MediaAttribute> answer,
     418             :                               bool validateMedia)
     419             : {
     420           1 :     JAMI_INFO("=== Begin test %s ===", __FUNCTION__);
     421             : 
     422           1 :     configureTest(aliceData_, bobData_);
     423             : 
     424           1 :     JAMI_INFO("=== Start a call and validate ===");
     425             : 
     426           1 :     std::string bobUri = "127.0.0.1:" + std::to_string(bobData_.listeningPort_);
     427             : 
     428           2 :     aliceData_.callId_ = libjami::placeCallWithMedia(aliceData_.accountId_,
     429             :                                                    bobUri,
     430           2 :                                                    MediaAttribute::mediaAttributesToMediaMaps(
     431           1 :                                                        offer));
     432             : 
     433           1 :     CPPUNIT_ASSERT(not aliceData_.callId_.empty());
     434             : 
     435           1 :     JAMI_INFO("ALICE [%s] started a call with BOB [%s] and wait for answer",
     436             :               aliceData_.accountId_.c_str(),
     437             :               bobData_.accountId_.c_str());
     438             : 
     439             :     // Give it some time to ring
     440           1 :     std::this_thread::sleep_for(std::chrono::seconds(2));
     441             : 
     442             :     // Wait for call to be processed.
     443           1 :     CPPUNIT_ASSERT(
     444             :         waitForSignal(aliceData_, libjami::CallSignal::StateChange::name, StateEvent::RINGING));
     445             : 
     446             :     // Wait for incoming call signal.
     447           1 :     CPPUNIT_ASSERT(waitForSignal(bobData_, libjami::CallSignal::IncomingCallWithMedia::name));
     448             : 
     449             :     // Answer the call.
     450           1 :     libjami::acceptWithMedia(bobData_.accountId_,
     451           1 :                            bobData_.callId_,
     452           2 :                            MediaAttribute::mediaAttributesToMediaMaps(answer));
     453             : 
     454             :     // Wait for media negotiation complete signal.
     455           1 :     CPPUNIT_ASSERT(waitForSignal(bobData_,
     456             :                                  libjami::CallSignal::MediaNegotiationStatus::name,
     457             :                                  libjami::Media::MediaNegotiationStatusEvents::NEGOTIATION_SUCCESS));
     458             : 
     459             :     // Wait for the StateChange signal.
     460           1 :     CPPUNIT_ASSERT(
     461             :         waitForSignal(bobData_, libjami::CallSignal::StateChange::name, StateEvent::CURRENT));
     462             : 
     463           1 :     JAMI_INFO("BOB answered the call [%s]", bobData_.callId_.c_str());
     464             : 
     465             :     // Wait for media negotiation complete signal.
     466           1 :     CPPUNIT_ASSERT(waitForSignal(aliceData_,
     467             :                                  libjami::CallSignal::MediaNegotiationStatus::name,
     468             :                                  libjami::Media::MediaNegotiationStatusEvents::NEGOTIATION_SUCCESS));
     469             : 
     470             :     // Validate Alice's media
     471           1 :     if (validateMedia) {
     472           1 :         auto call = Manager::instance().getCallFromCallID(aliceData_.callId_);
     473           1 :         auto activeMediaList = call->getMediaAttributeList();
     474           1 :         CPPUNIT_ASSERT_EQUAL(offer.size(), activeMediaList.size());
     475             :         // Audio
     476           1 :         CPPUNIT_ASSERT_EQUAL(MediaType::MEDIA_AUDIO, activeMediaList[0].type_);
     477           1 :         CPPUNIT_ASSERT_EQUAL(offer[0].enabled_, activeMediaList[0].enabled_);
     478             : 
     479             :         // Video
     480           1 :         if (offer.size() > 1) {
     481           1 :             CPPUNIT_ASSERT_EQUAL(MediaType::MEDIA_VIDEO, activeMediaList[1].type_);
     482           1 :             CPPUNIT_ASSERT_EQUAL(offer[1].enabled_, activeMediaList[1].enabled_);
     483             :         }
     484           1 :     }
     485             : 
     486             :     // Validate Bob's media
     487           1 :     if (validateMedia) {
     488           1 :         auto call = Manager::instance().getCallFromCallID(bobData_.callId_);
     489           1 :         auto activeMediaList = call->getMediaAttributeList();
     490           1 :         CPPUNIT_ASSERT_EQUAL(answer.size(), activeMediaList.size());
     491             :         // Audio
     492           1 :         CPPUNIT_ASSERT_EQUAL(MediaType::MEDIA_AUDIO, activeMediaList[0].type_);
     493           1 :         CPPUNIT_ASSERT_EQUAL(answer[0].enabled_, activeMediaList[0].enabled_);
     494             : 
     495             :         // Video
     496           1 :         if (offer.size() > 1) {
     497           1 :             CPPUNIT_ASSERT_EQUAL(MediaType::MEDIA_VIDEO, activeMediaList[1].type_);
     498           1 :             CPPUNIT_ASSERT_EQUAL(answer[1].enabled_, activeMediaList[1].enabled_);
     499             :         }
     500           1 :     }
     501             : 
     502             :     // Give some time to media to start and flow
     503           1 :     std::this_thread::sleep_for(std::chrono::seconds(3));
     504             : 
     505             :     // Bob hang-up.
     506           1 :     JAMI_INFO("Hang up BOB's call and wait for ALICE to hang up");
     507           1 :     libjami::hangUp(bobData_.accountId_, bobData_.callId_);
     508             : 
     509           1 :     CPPUNIT_ASSERT(
     510             :         waitForSignal(aliceData_, libjami::CallSignal::StateChange::name, StateEvent::HUNGUP));
     511             : 
     512           1 :     JAMI_INFO("Call terminated on both sides");
     513           1 : }
     514             : 
     515             : void
     516           1 : SipSrtpTest::audio_video_srtp_enabled_test()
     517             : {
     518             :     // Test with video enabled on Alice's side and disabled
     519             :     // on Bob's side.
     520             : 
     521           1 :     auto const aliceAcc = Manager::instance().getAccount<SIPAccount>(aliceData_.accountId_);
     522           1 :     CPPUNIT_ASSERT(aliceAcc->isSrtpEnabled());
     523             : 
     524           1 :     auto const bobAcc = Manager::instance().getAccount<SIPAccount>(bobData_.accountId_);
     525           1 :     CPPUNIT_ASSERT(bobAcc->isSrtpEnabled());
     526             : 
     527           1 :     std::vector<MediaAttribute> offer;
     528           1 :     std::vector<MediaAttribute> answer;
     529             : 
     530           1 :     MediaAttribute audio(MediaType::MEDIA_AUDIO);
     531           1 :     MediaAttribute video(MediaType::MEDIA_VIDEO);
     532             : 
     533             :     // Configure Alice
     534           1 :     audio.enabled_ = true;
     535           1 :     audio.label_ = "audio_0";
     536           1 :     offer.emplace_back(audio);
     537             : 
     538           1 :     video.enabled_ = true;
     539           1 :     video.label_ = "video_0";
     540           1 :     aliceAcc->enableVideo(true);
     541           1 :     offer.emplace_back(video);
     542             : 
     543             :     // Configure Bob
     544           1 :     audio.enabled_ = true;
     545           1 :     audio.label_ = "audio_0";
     546           1 :     answer.emplace_back(audio);
     547             : 
     548           1 :     video.enabled_ = false;
     549           1 :     video.label_ = "video_0";
     550           1 :     bobAcc->enableVideo(false);
     551           1 :     answer.emplace_back(video);
     552             : 
     553             :     // Run the scenario
     554           1 :     audio_video_call(offer, answer);
     555           1 : }
     556             : 
     557             : } // namespace test
     558             : } // namespace jami
     559             : 
     560           1 : RING_TEST_RUNNER(jami::test::SipSrtpTest::name())

Generated by: LCOV version 1.14