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 "manager.h" 19 : #include "sip/sipaccount.h" 20 : #include "sip/sipcall.h" 21 : #include "sip/siptransport.h" 22 : #include "../../test_runner.h" 23 : #include "jami.h" 24 : #include "account_const.h" 25 : #include "media_const.h" 26 : #include "call_const.h" 27 : #include "common.h" 28 : 29 : #include <dhtnet/connectionmanager.h> 30 : 31 : #include <cppunit/TestAssert.h> 32 : #include <cppunit/TestFixture.h> 33 : #include <cppunit/extensions/HelperMacros.h> 34 : 35 : #include <condition_variable> 36 : #include <filesystem> 37 : #include <string> 38 : 39 : using namespace libjami::Account; 40 : using namespace libjami::Call::Details; 41 : using namespace std::literals::chrono_literals; 42 : 43 : namespace jami { 44 : namespace test { 45 : 46 : class SIPCallTest : public CppUnit::TestFixture 47 : { 48 : public: 49 1 : SIPCallTest() 50 1 : { 51 : // Init daemon 52 1 : libjami::init( 53 : libjami::InitFlag(libjami::LIBJAMI_FLAG_DEBUG | libjami::LIBJAMI_FLAG_CONSOLE_LOG)); 54 1 : if (not Manager::instance().initialized) 55 1 : CPPUNIT_ASSERT(libjami::start("jami-sample.yml")); 56 1 : } 57 2 : ~SIPCallTest() { libjami::fini(); } 58 2 : static std::string name() { return "Call"; } 59 : void setUp(); 60 : void tearDown(); 61 : 62 : std::string aliceId; 63 : std::string bobId; 64 : 65 : private: 66 : void testCall(); 67 : 68 2 : CPPUNIT_TEST_SUITE(SIPCallTest); 69 1 : CPPUNIT_TEST(testCall); 70 4 : CPPUNIT_TEST_SUITE_END(); 71 : }; 72 : 73 : CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(SIPCallTest, SIPCallTest::name()); 74 : 75 : void 76 1 : SIPCallTest::setUp() 77 : { 78 2 : auto actors = load_actors_and_wait_for_announcement("actors/alice-bob_SIP.yml"); 79 1 : aliceId = actors["alice"]; 80 1 : bobId = actors["bob"]; 81 1 : std::this_thread::sleep_for(10s); 82 1 : } 83 : 84 : void 85 1 : SIPCallTest::tearDown() 86 : { 87 3 : wait_for_removal_of({aliceId, bobId}); 88 1 : } 89 : 90 : void 91 1 : SIPCallTest::testCall() 92 : { 93 1 : auto aliceAccount = Manager::instance().getAccount<SIPAccount>(aliceId); 94 1 : auto bobAccount = Manager::instance().getAccount<SIPAccount>(bobId); 95 1 : auto bobUri = bobAccount->getUsername(); 96 1 : auto aliceUri = aliceAccount->getUsername(); 97 : 98 1 : std::mutex mtx; 99 1 : std::unique_lock lk {mtx}; 100 1 : std::condition_variable cv; 101 1 : std::map<std::string, std::shared_ptr<libjami::CallbackWrapperBase>> confHandlers; 102 1 : std::atomic_bool callReceived {false}; 103 1 : std::atomic<int> callStopped {0}; 104 : // Watch signals 105 1 : confHandlers.insert(libjami::exportable_callback<libjami::CallSignal::IncomingCallWithMedia>( 106 1 : [&](const std::string&, 107 : const std::string&, 108 : const std::string&, 109 : const std::vector<std::map<std::string, std::string>>&) { 110 1 : callReceived = true; 111 1 : cv.notify_one(); 112 1 : })); 113 1 : confHandlers.insert(libjami::exportable_callback<libjami::CallSignal::StateChange>( 114 8 : [&](const std::string&, const std::string&, const std::string& state, signed) { 115 8 : if (state == "OVER") { 116 2 : callStopped += 1; 117 2 : if (callStopped == 2) 118 1 : cv.notify_one(); 119 : } 120 8 : })); 121 1 : libjami::registerSignalHandlers(confHandlers); 122 : 123 1 : JAMI_INFO("Start call between alice and Bob"); 124 1 : std::vector<std::map<std::string, std::string>> mediaList; 125 : std::map<std::string, std::string> mediaAttribute 126 : = {{libjami::Media::MediaAttributeKey::MEDIA_TYPE, 127 : libjami::Media::MediaAttributeValue::AUDIO}, 128 : {libjami::Media::MediaAttributeKey::ENABLED, TRUE_STR}, 129 : {libjami::Media::MediaAttributeKey::MUTED, FALSE_STR}, 130 : {libjami::Media::MediaAttributeKey::SOURCE, ""}, 131 7 : {libjami::Media::MediaAttributeKey::LABEL, "audio_0"}}; 132 1 : mediaList.emplace_back(mediaAttribute); 133 : 134 1 : auto call = libjami::placeCallWithMedia(aliceId, bobUri, mediaList); 135 : 136 3 : CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&] { return callReceived.load(); })); 137 : 138 1 : JAMI_INFO("Stop call between alice and Bob"); 139 1 : callStopped = 0; 140 1 : Manager::instance().hangupCall(aliceId, call); 141 3 : CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&] { return callStopped == 2; })); 142 1 : } 143 : 144 : } // namespace test 145 : } // namespace jami 146 : 147 1 : RING_TEST_RUNNER(jami::test::SIPCallTest::name())