diff --git a/src/account.h b/src/account.h index f11a5007612f49198e3d6279cdbb888ab6387a30..4285dd97135081006124f3b7aae7d974afd3a89f 100644 --- a/src/account.h +++ b/src/account.h @@ -49,18 +49,17 @@ #include <mutex> #include <chrono> -namespace jami { -namespace upnp { -class Controller; -} -} // namespace jami - namespace YAML { class Emitter; class Node; } // namespace YAML namespace jami { +static constexpr uint64_t DRING_ID_MAX_VAL = 9007199254740992; + +namespace upnp { +class Controller; +} // namespace upnp class Call; class SystemCodecContainer; diff --git a/src/call_factory.cpp b/src/call_factory.cpp index 5b6d20cfbecc7064326f46c34a81f8a63b8ce70d..e01db1024f527b4d02b822192abc769cf0ba84f8 100644 --- a/src/call_factory.cpp +++ b/src/call_factory.cpp @@ -23,12 +23,23 @@ #include "call_factory.h" #include "sip/sipcall.h" #include "sip/sipaccountbase.h" +#include "string_utils.h" namespace jami { -std::shared_ptr<Call> -CallFactory::createSipCall(const std::shared_ptr<Account>& account, - const std::string& id, +// generate something like 7ea037947eb9fb2f +std::string +CallFactory::getNewCallID() const +{ + std::string random_id; + do { + random_id = std::to_string(std::uniform_int_distribution<uint64_t>(1, DRING_ID_MAX_VAL)(rand_)); + } while (hasCall(random_id)); + return random_id; +} + +std::shared_ptr<SIPCall> +CallFactory::newSipCall(const std::shared_ptr<SIPAccountBase>& account, Call::CallType type, const std::map<std::string, std::string>& details) { @@ -37,26 +48,10 @@ CallFactory::createSipCall(const std::shared_ptr<Account>& account, return nullptr; } - if (hasCall(id, Call::LinkType::SIP)) { - JAMI_ERR("Call %s already exists", id.c_str()); - return nullptr; - } - - if (std::strcmp(account->getAccountType(), "SIP") != 0 - and std::strcmp(account->getAccountType(), "RING") != 0) { - JAMI_ERR("Invalid account type %s!", account->getAccountType()); - assert(false); - } - - auto accountBase = std::dynamic_pointer_cast<SIPAccountBase>(account); - assert(accountBase); - - auto call = std::make_shared<SIPCall>(accountBase, id, type, details); - assert(call); - std::lock_guard<std::recursive_mutex> lk(callMapsMutex_); + auto id = getNewCallID(); + auto call = std::make_shared<SIPCall>(account, id, type, details); callMaps_[call->getLinkType()].emplace(id, call); - return call; } diff --git a/src/call_factory.h b/src/call_factory.h index 343374925750bac18641ba8e7bc36e6bb272112a..4a2225c92ffbd9004e0ce8ec1a7a4a9dea313eb4 100644 --- a/src/call_factory.h +++ b/src/call_factory.h @@ -32,9 +32,14 @@ namespace jami { +class SIPAccountBase; +class SIPCall; + class CallFactory { -private: +public: + CallFactory(std::mt19937_64& rand) : rand_(rand) {} + /** * Create a new call instance. * @param account Account used to create this call @@ -42,21 +47,23 @@ private: * @param type Set the call type * @param details Call details */ - std::shared_ptr<Call> createSipCall(const std::shared_ptr<Account>& account, - const std::string& id, + std::shared_ptr<SIPCall> newSipCall(const std::shared_ptr<SIPAccountBase>& account, Call::CallType type, const std::map<std::string, std::string>& details = {}); -public: - template<class A> - std::shared_ptr<Call> newCall(std::shared_ptr<A> account, - const std::string& id, + template<class C> + std::shared_ptr<C> newCall(std::shared_ptr<Account> account, Call::CallType type, const std::map<std::string, std::string>& details = {}) { - return createSipCall(account, id, type, details); + if (auto base = std::dynamic_pointer_cast<SIPAccountBase>(account)) { + return std::dynamic_pointer_cast<C>(newSipCall(base, type, details)); + } + return nullptr; } + std::string getNewCallID() const; + /** * Forbid creation of new calls. */ @@ -78,6 +85,11 @@ public: std::shared_ptr<Call> getCall(const std::string& id) const; std::shared_ptr<Call> getCall(const std::string& id, Call::LinkType link) const; + template<class C> + std::shared_ptr<C> getCall(const std::string& id) { + return std::dynamic_pointer_cast<C>(getCall(id, C::LINK_TYPE)); + } + /** * Return if given call exists. Type can optionally be specified. */ @@ -114,6 +126,7 @@ public: std::size_t callCount(Call::LinkType link) const; private: + /** * @brief Get the calls map * @param link The call type @@ -130,6 +143,8 @@ private: return nullptr; } + std::mt19937_64& rand_; + mutable std::recursive_mutex callMapsMutex_ {}; std::atomic_bool allowNewCall_ {true}; diff --git a/src/conference.cpp b/src/conference.cpp index f0eca3af16ceb7e2108ffea82148e731b5fe10ec..3228946a48066b303cc4ddf8474fdf28da19dc5c 100644 --- a/src/conference.cpp +++ b/src/conference.cpp @@ -46,7 +46,7 @@ using namespace std::literals; namespace jami { Conference::Conference() - : id_(Manager::instance().getNewCallID()) + : id_(Manager::instance().callFactory.getNewCallID()) #ifdef ENABLE_VIDEO , mediaInput_(Manager::instance().getVideoManager().videoDeviceMonitor.getMRLForDefaultDevice()) #endif diff --git a/src/jamidht/jamiaccount.cpp b/src/jamidht/jamiaccount.cpp index d9748e5eed0aa36f388c39a7f300177f6614aea4..41b799750d0907cae141b267d1b716537326af33 100644 --- a/src/jamidht/jamiaccount.cpp +++ b/src/jamidht/jamiaccount.cpp @@ -368,15 +368,7 @@ JamiAccount::newIncomingCall(const std::string& from, if (cit->transport != sipTr) continue; - auto newCall = Manager::instance().callFactory.newCall<JamiAccount>( - shared(), Manager::instance().getNewCallID(), Call::CallType::INCOMING); - auto call = std::dynamic_pointer_cast<SIPCall>(newCall); - assert(call); - - if (!call) - return {}; - - std::weak_ptr<SIPCall> wcall = call; + auto call = Manager::instance().callFactory.newCall<SIPCall>(shared(), Call::CallType::INCOMING); call->setPeerUri(RING_URI_PREFIX + from); call->setPeerNumber(from); call->updateDetails(details); @@ -415,14 +407,7 @@ JamiAccount::newOutgoingCall(std::string_view toUrl, auto suffix = stripPrefix(toUrl); JAMI_DBG() << *this << "Calling DHT peer " << suffix; auto& manager = Manager::instance(); - auto newCall = manager.callFactory.newCall<JamiAccount>(shared(), - manager.getNewCallID(), - Call::CallType::OUTGOING, - volatileCallDetails); - - auto call = std::dynamic_pointer_cast<SIPCall>(newCall); - assert(call); - + auto call = manager.callFactory.newCall<SIPCall>(shared(), Call::CallType::OUTGOING, volatileCallDetails); call->setIPToIP(true); call->setSecure(isTlsEnabled()); @@ -524,13 +509,7 @@ JamiAccount::startOutgoingCall(const std::shared_ptr<SIPCall>& call, const std:: // NOTE: dummyCall is a call used to avoid to mark the call as failed if the // cached connection is failing with ICE (close event still not detected). auto& manager = Manager::instance(); - auto newCall = manager.callFactory.newCall<JamiAccount>(shared(), - manager.getNewCallID(), - Call::CallType::OUTGOING, - call->getDetails()); - auto dummyCall = std::dynamic_pointer_cast<SIPCall>(newCall); - assert(dummyCall); - + auto dummyCall = manager.callFactory.newCall<SIPCall>(shared(), Call::CallType::OUTGOING, call->getDetails()); dummyCall->setIPToIP(true); dummyCall->setSecure(isTlsEnabled()); call->addSubCall(*dummyCall); @@ -551,14 +530,8 @@ JamiAccount::startOutgoingCall(const std::shared_ptr<SIPCall>& call, const std:: and state != Call::ConnectionState::TRYING) return; - auto newCall = Manager::instance() - .callFactory.newCall<JamiAccount>(shared(), - Manager::instance().getNewCallID(), - Call::CallType::OUTGOING, - call->getDetails()); - auto dev_call = std::dynamic_pointer_cast<SIPCall>(newCall); - assert(dev_call); - + auto dev_call = Manager::instance() + .callFactory.newCall<SIPCall>(shared(), Call::CallType::OUTGOING, call->getDetails()); dev_call->setIPToIP(true); dev_call->setSecure(isTlsEnabled()); dev_call->setState(Call::ConnectionState::TRYING); @@ -602,13 +575,7 @@ JamiAccount::startOutgoingCall(const std::shared_ptr<SIPCall>& call, const std:: JAMI_WARN("[call %s] A channeled socket is detected with this peer.", call->getCallId().c_str()); - auto newCall = manager.callFactory.newCall<JamiAccount>(shared(), - manager.getNewCallID(), - Call::CallType::OUTGOING, - call->getDetails()); - auto dev_call = std::dynamic_pointer_cast<SIPCall>(newCall); - assert(dev_call); - + auto dev_call = manager.callFactory.newCall<SIPCall>(shared(), Call::CallType::OUTGOING, call->getDetails()); dev_call->setIPToIP(true); dev_call->setSecure(isTlsEnabled()); dev_call->setTransport(transport); @@ -2430,13 +2397,8 @@ JamiAccount::incomingCall(dht::IceCandidates&& msg, const std::shared_ptr<dht::crypto::Certificate>& from_cert, const dht::InfoHash& from) { - auto newCall = Manager::instance() - .callFactory.newCall<JamiAccount>(shared(), - Manager::instance().getNewCallID(), - Call::CallType::INCOMING); - auto call = std::dynamic_pointer_cast<SIPCall>(newCall); - assert(call); - + auto call = Manager::instance() + .callFactory.newCall<SIPCall>(shared(), Call::CallType::INCOMING); if (!call) { return; } diff --git a/src/manager.cpp b/src/manager.cpp index a864f040409acbb6802f30a8329cc821a269f448..b3c6e0ac38f42cfaa7526a16a842150a93435c85 100644 --- a/src/manager.cpp +++ b/src/manager.cpp @@ -421,8 +421,6 @@ struct Manager::ManagerPimpl std::atomic_bool finished_ {false}; - std::mt19937_64 rand_; - /* ICE support */ std::unique_ptr<IceTransportFactory> ice_tf_; @@ -446,7 +444,6 @@ Manager::ManagerPimpl::ManagerPimpl(Manager& base) , toneCtrl_(base.preferences) , dtmfBuf_(0, AudioFormat::MONO()) , ringbufferpool_(new RingBufferPool) - , rand_(dht::crypto::getSeededRandomEngine<std::mt19937_64>()) #ifdef ENABLE_VIDEO , videoManager_(new VideoManager) #endif @@ -714,7 +711,8 @@ Manager::instance() } Manager::Manager() - : preferences() + : rand_(dht::crypto::getSeededRandomEngine<std::mt19937_64>()) + , preferences() , voipPreferences() , audioPreference() , shortcutPreferences() @@ -724,7 +722,7 @@ Manager::Manager() #ifdef ENABLE_VIDEO , videoPreferences() #endif - , callFactory() + , callFactory(rand_) , accountFactory() , dataTransfers(std::make_unique<DataTransferFacade>()) , pimpl_(new ManagerPimpl(*this)) @@ -2769,18 +2767,11 @@ Manager::testAccountICEInitialization(const std::string& accountID) std::string Manager::getNewAccountId() { - std::string newAccountID; - static std::uniform_int_distribution<uint64_t> rand_acc_id; - - const std::vector<std::string> accountList(getAccountList()); - + std::string random_id; do { - std::ostringstream accId; - accId << std::hex << rand_acc_id(pimpl_->rand_); - newAccountID = accId.str(); - } while (std::find(accountList.begin(), accountList.end(), newAccountID) != accountList.end()); - - return newAccountID; + random_id = to_hex_string(std::uniform_int_distribution<uint64_t>()(rand_)); + } while (getAccount(random_id)); + return random_id; } std::string @@ -2847,19 +2838,6 @@ Manager::removeAccounts() removeAccount(acc); } -std::string -Manager::getNewCallID() -{ - std::ostringstream random_id; - - // generate something like s7ea037947eb9fb2f - do { - random_id.clear(); - random_id << std::uniform_int_distribution<uint64_t>(1, DRING_ID_MAX_VAL)(pimpl_->rand_); - } while (callFactory.hasCall(random_id.str())); - - return random_id.str(); -} std::vector<std::string_view> Manager::loadAccountOrder() const diff --git a/src/manager.h b/src/manager.h index 60012200fa2895dabcf0f9362cf0cdde38e292cd..c5a2bb1ef097d925b9717c8497b4cc3c47121c56 100644 --- a/src/manager.h +++ b/src/manager.h @@ -64,12 +64,13 @@ class JamiAccount; class SIPVoIPLink; class JamiPluginManager; -static constexpr uint64_t DRING_ID_MAX_VAL = 9007199254740992; /** Manager (controller) of daemon */ // TODO DRING_PUBLIC only if tests class DRING_TESTABLE Manager { +private: + std::mt19937_64 rand_; public: // TODO DRING_PUBLIC only if tests static DRING_TESTABLE Manager& instance(); @@ -752,12 +753,6 @@ public: */ bool incomingCallsWaiting(); - /** - * Return a new random callid that is not present in the list - * @return std::string A brand new callid - */ - std::string getNewCallID(); - /** * Get the current call * @return std::shared_ptr<Call> A call shared pointer (could be empty) diff --git a/src/plugin/callservicesmanager.cpp b/src/plugin/callservicesmanager.cpp index 13541e0d793322181b788731d4294d85e520ed3e..a1749bb46bbc97110330016f87ed7e0bd9425928 100644 --- a/src/plugin/callservicesmanager.cpp +++ b/src/plugin/callservicesmanager.cpp @@ -253,10 +253,9 @@ CallServicesManager::toggleCallMediaHandler(const uintptr_t mediaHandlerId, } #ifndef __ANDROID__ if (applyRestart) { - auto sipCall = std::dynamic_pointer_cast<SIPCall>( - Manager::instance().callFactory.getCall(callId, Call::LinkType::SIP)); - assert(sipCall); - sipCall->getVideoRtp().restartSender(); + if (auto call = Manager::instance().callFactory.getCall<SIPCall>(callId)) { + call->getVideoRtp().restartSender(); + } } #endif } diff --git a/src/sip/sipaccount.cpp b/src/sip/sipaccount.cpp index 5657dc7264ec86079233297e1fa0570de47052ca..30e2209adcf481b94ca9c4d41a962529079a0961 100644 --- a/src/sip/sipaccount.cpp +++ b/src/sip/sipaccount.cpp @@ -180,14 +180,7 @@ SIPAccount::newIncomingCall(const std::string& from UNUSED, const std::shared_ptr<SipTransport>&) { auto& manager = Manager::instance(); - auto call = manager.callFactory.newCall<SIPAccount>(shared(), - manager.getNewCallID(), - Call::CallType::INCOMING, - details); - - auto sipCall = std::dynamic_pointer_cast<SIPCall>(call); - assert(sipCall); - return sipCall; + return manager.callFactory.newCall<SIPCall>(shared(), Call::CallType::INCOMING, details); } template<> @@ -201,13 +194,7 @@ SIPAccount::newOutgoingCall(std::string_view toUrl, JAMI_DBG() << *this << "Calling SIP peer " << toUrl; auto& manager = Manager::instance(); - auto newCall = manager.callFactory.newCall<SIPAccount>(shared(), - manager.getNewCallID(), - Call::CallType::OUTGOING, - volatileCallDetails); - auto call = std::dynamic_pointer_cast<SIPCall>(newCall); - assert(call); - + auto call = manager.callFactory.newCall<SIPCall>(shared(), Call::CallType::OUTGOING, volatileCallDetails); call->setSecure(isTlsEnabled()); if (isIP2IP()) { diff --git a/src/sip/sipcall.cpp b/src/sip/sipcall.cpp index e77e5724ee84136573984c26869c16cee9dd6424..022e0d29d9afd1577609af9e166ed0b16bec4769 100644 --- a/src/sip/sipcall.cpp +++ b/src/sip/sipcall.cpp @@ -738,9 +738,7 @@ SIPCall::transfer(const std::string& to) bool SIPCall::attendedTransfer(const std::string& to) { - auto toCall = std::dynamic_pointer_cast<SIPCall>( - Manager::instance().callFactory.getCall(to, getLinkType())); - + auto toCall = Manager::instance().callFactory.getCall<SIPCall>(to); if (!toCall) return false; diff --git a/src/sip/sipcall.h b/src/sip/sipcall.h index dd12e380b475c684a9ceb50485b3e379b4a8af27..619769accb12f1d988a4f2288282d1e4e694f35d 100644 --- a/src/sip/sipcall.h +++ b/src/sip/sipcall.h @@ -74,6 +74,7 @@ class Controller; class SIPCall : public Call { public: + static constexpr LinkType LINK_TYPE = LinkType::SIP; /** * Destructor */ @@ -90,7 +91,7 @@ public: const std::map<std::string, std::string>& details = {}); // Inherited from Call class - LinkType getLinkType() const { return LinkType::SIP; } + LinkType getLinkType() const override { return LINK_TYPE; } void answer() override; void hangup(int reason) override; void refuse() override; @@ -180,7 +181,7 @@ public: void requestKeyframe(); - void updateRecState(bool state); + void updateRecState(bool state) override; std::shared_ptr<SIPAccountBase> getSIPAccount() const;