Line data Source code
1 : /* 2 : * Copyright (C) 2024 Savoir-faire Linux Inc. 3 : * Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com> 4 : * 5 : * This program is free software; you can redistribute it and/or modify 6 : * it under the terms of the GNU General Public License as published by 7 : * the Free Software Foundation; either version 3 of the License, or 8 : * (at your option) any later version. 9 : * 10 : * This program is distributed in the hope that it will be useful, 11 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 : * GNU General Public License for more details. 14 : * 15 : * You should have received a copy of the GNU General Public License 16 : * along with this program. If not, see <https://www.gnu.org/licenses/>. 17 : */ 18 : 19 : #include "manager.h" 20 : #include "sip/sipaccount.h" 21 : #include "sip/sipcall.h" 22 : #include "sip/siptransport.h" 23 : #include "../../test_runner.h" 24 : #include "jami.h" 25 : #include "account_const.h" 26 : #include "media_const.h" 27 : #include "call_const.h" 28 : #include "common.h" 29 : 30 : #include <dhtnet/connectionmanager.h> 31 : 32 : #include <cppunit/TestAssert.h> 33 : #include <cppunit/TestFixture.h> 34 : #include <cppunit/extensions/HelperMacros.h> 35 : 36 : #include <condition_variable> 37 : #include <filesystem> 38 : #include <string> 39 : 40 : using namespace libjami::Account; 41 : using namespace libjami::Call::Details; 42 : using namespace std::literals::chrono_literals; 43 : 44 : namespace jami { 45 : namespace test { 46 : 47 : class SIPCallTest : public CppUnit::TestFixture 48 : { 49 : public: 50 1 : SIPCallTest() 51 1 : { 52 : // Init daemon 53 1 : libjami::init( 54 : libjami::InitFlag(libjami::LIBJAMI_FLAG_DEBUG | libjami::LIBJAMI_FLAG_CONSOLE_LOG)); 55 1 : if (not Manager::instance().initialized) 56 1 : CPPUNIT_ASSERT(libjami::start("jami-sample.yml")); 57 1 : } 58 2 : ~SIPCallTest() { libjami::fini(); } 59 2 : static std::string name() { return "Call"; } 60 : void setUp(); 61 : void tearDown(); 62 : 63 : std::string aliceId; 64 : std::string bobId; 65 : 66 : private: 67 : void testCall(); 68 : 69 2 : CPPUNIT_TEST_SUITE(SIPCallTest); 70 1 : CPPUNIT_TEST(testCall); 71 4 : CPPUNIT_TEST_SUITE_END(); 72 : }; 73 : 74 : CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(SIPCallTest, SIPCallTest::name()); 75 : 76 : void 77 1 : SIPCallTest::setUp() 78 : { 79 2 : auto actors = load_actors_and_wait_for_announcement("actors/alice-bob_SIP.yml"); 80 1 : aliceId = actors["alice"]; 81 1 : bobId = actors["bob"]; 82 1 : std::this_thread::sleep_for(10s); 83 1 : } 84 : 85 : void 86 1 : SIPCallTest::tearDown() 87 : { 88 3 : wait_for_removal_of({aliceId, bobId}); 89 1 : } 90 : 91 : void 92 1 : SIPCallTest::testCall() 93 : { 94 1 : auto aliceAccount = Manager::instance().getAccount<SIPAccount>(aliceId); 95 1 : auto bobAccount = Manager::instance().getAccount<SIPAccount>(bobId); 96 1 : auto bobUri = bobAccount->getUsername(); 97 1 : auto aliceUri = aliceAccount->getUsername(); 98 : 99 1 : std::mutex mtx; 100 1 : std::unique_lock lk {mtx}; 101 1 : std::condition_variable cv; 102 1 : std::map<std::string, std::shared_ptr<libjami::CallbackWrapperBase>> confHandlers; 103 1 : std::atomic_bool callReceived {false}; 104 1 : std::atomic<int> callStopped {0}; 105 : // Watch signals 106 1 : confHandlers.insert(libjami::exportable_callback<libjami::CallSignal::IncomingCallWithMedia>( 107 1 : [&](const std::string&, 108 : const std::string&, 109 : const std::string&, 110 : const std::vector<std::map<std::string, std::string>>&) { 111 1 : callReceived = true; 112 1 : cv.notify_one(); 113 1 : })); 114 1 : confHandlers.insert(libjami::exportable_callback<libjami::CallSignal::StateChange>( 115 8 : [&](const std::string&, const std::string&, const std::string& state, signed) { 116 8 : if (state == "OVER") { 117 2 : callStopped += 1; 118 2 : if (callStopped == 2) 119 1 : cv.notify_one(); 120 : } 121 8 : })); 122 1 : libjami::registerSignalHandlers(confHandlers); 123 : 124 1 : JAMI_INFO("Start call between alice and Bob"); 125 1 : std::vector<std::map<std::string, std::string>> mediaList; 126 : std::map<std::string, std::string> mediaAttribute 127 : = {{libjami::Media::MediaAttributeKey::MEDIA_TYPE, 128 : libjami::Media::MediaAttributeValue::AUDIO}, 129 : {libjami::Media::MediaAttributeKey::ENABLED, TRUE_STR}, 130 : {libjami::Media::MediaAttributeKey::MUTED, FALSE_STR}, 131 : {libjami::Media::MediaAttributeKey::SOURCE, ""}, 132 7 : {libjami::Media::MediaAttributeKey::LABEL, "audio_0"}}; 133 1 : mediaList.emplace_back(mediaAttribute); 134 : 135 1 : auto call = libjami::placeCallWithMedia(aliceId, bobUri, mediaList); 136 : 137 3 : CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&] { return callReceived.load(); })); 138 : 139 1 : JAMI_INFO("Stop call between alice and Bob"); 140 1 : callStopped = 0; 141 1 : Manager::instance().hangupCall(aliceId, call); 142 3 : CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&] { return callStopped == 2; })); 143 1 : } 144 : 145 : } // namespace test 146 : } // namespace jami 147 : 148 1 : RING_TEST_RUNNER(jami::test::SIPCallTest::name())