From 43ed62cf707e8030b708f831788d16b541f0e101 Mon Sep 17 00:00:00 2001 From: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com> Date: Tue, 24 Feb 2015 16:37:05 -0500 Subject: [PATCH] call: let daemon generate all CallID's This patch changes also the DBus API. The client is not longer responsible to generate this ID. It could find it when the call is made. Refs #67104 Change-Id: I31ddfd9b1ba53b9a7da16a7138d1a65f1b3a9eec --- daemon/bin/dbus/callmanager-introspec.xml | 9 +-- daemon/bin/dbus/dbuscallmanager.cpp | 4 +- daemon/bin/dbus/dbuscallmanager.h | 2 +- daemon/src/account.h | 4 +- daemon/src/client/callmanager.cpp | 10 ++- daemon/src/dring/callmanager_interface.h | 2 +- daemon/src/iax/iaxaccount.cpp | 17 +++-- daemon/src/iax/iaxaccount.h | 10 ++- daemon/src/iax/iaxvoiplink.cpp | 5 +- daemon/src/managerimpl.cpp | 84 +++++++++-------------- daemon/src/managerimpl.h | 12 ++-- daemon/src/ringdht/ringaccount.cpp | 12 ++-- daemon/src/ringdht/ringaccount.h | 7 +- daemon/src/sip/sipaccount.cpp | 11 +-- daemon/src/sip/sipaccount.h | 10 ++- daemon/src/sip/sipvoiplink.cpp | 3 +- 16 files changed, 85 insertions(+), 117 deletions(-) diff --git a/daemon/bin/dbus/callmanager-introspec.xml b/daemon/bin/dbus/callmanager-introspec.xml index 8b896903ee..3ab2b08851 100644 --- a/daemon/bin/dbus/callmanager-introspec.xml +++ b/daemon/bin/dbus/callmanager-introspec.xml @@ -6,7 +6,7 @@ <tp:docstring xmlns="http://www.w3.org/1999/xhtml"> <p>The CallManager interface is used to manage call and conference related actions.</p> <p>Since Ring-daemon supports multiple incoming/outgoing calls, any actions involving a specific call must address the method by the means of a unique callID. - Ring-clients is responsible for generating the callID on outgoing calls. Conversely, Ring-daemon will generate a unique callID for incoming calls.</p> + Ring-daemon will generate a unique callID for outgoing and incoming calls.</p> </tp:docstring> <method name="placeCall" tp:name-for-bindings="placeCall"> <tp:docstring> @@ -17,17 +17,12 @@ The ID of the account with which you want to make a call. If the call is to be placed without any account by means of a SIP URI (i.e. sip:num@server), the "IP2IP_PROFILE" is passed as the accountID. For more details on accounts see the configuration manager interface. </tp:docstring> </arg> - <arg type="s" name="callID" direction="in"> - <tp:docstring> - The callID is a unique identifier that must be randomly generated on the client's side. Any subsequent actions refering to this call must use this callID. - </tp:docstring> - </arg> <arg type="s" name="to" direction="in"> <tp:docstring> If bound to a VoIP account, then the argument is the phone number. In case of calls involving "IP2IP_PROFILE", a complete SIP URI must be specified. </tp:docstring> </arg> - <arg type="b" name="callSucceeded" direction="out"/> + <arg type="s" name="callID" direction="out"/> </method> <method name="refuse" tp:name-for-bindings="refuse"> diff --git a/daemon/bin/dbus/dbuscallmanager.cpp b/daemon/bin/dbus/dbuscallmanager.cpp index 20d0ee772d..6406de4645 100644 --- a/daemon/bin/dbus/dbuscallmanager.cpp +++ b/daemon/bin/dbus/dbuscallmanager.cpp @@ -36,9 +36,9 @@ DBusCallManager::DBusCallManager(DBus::Connection& connection) {} auto -DBusCallManager::placeCall(const std::string& accountID, const std::string& callID, const std::string& to) -> decltype(DRing::placeCall(accountID, callID, to)) +DBusCallManager::placeCall(const std::string& accountID, const std::string& to) -> decltype(DRing::placeCall(accountID, to)) { - return DRing::placeCall(accountID, callID, to); + return DRing::placeCall(accountID, to); } auto diff --git a/daemon/bin/dbus/dbuscallmanager.h b/daemon/bin/dbus/dbuscallmanager.h index 0ef4dc42e9..9b109a2fb0 100644 --- a/daemon/bin/dbus/dbuscallmanager.h +++ b/daemon/bin/dbus/dbuscallmanager.h @@ -64,7 +64,7 @@ class DBusCallManager : DBusCallManager(DBus::Connection& connection); // Methods - bool placeCall(const std::string& accountID, const std::string& callID, const std::string& to); + std::string placeCall(const std::string& accountID, const std::string& to); bool refuse(const std::string& callID); bool accept(const std::string& callID); bool hangUp(const std::string& callID); diff --git a/daemon/src/account.h b/daemon/src/account.h index 2505d43032..443d91bd00 100644 --- a/daemon/src/account.h +++ b/daemon/src/account.h @@ -145,12 +145,10 @@ class Account : public Serializable, public std::enable_shared_from_this<Account /** * Create a new outgoing call. * - * @param id The ID of the call * @param toUrl The address to call * @return std::shared_ptr<Call> A pointer on the created call */ - virtual std::shared_ptr<Call> newOutgoingCall(const std::string& id, - const std::string& toUrl) = 0; + virtual std::shared_ptr<Call> newOutgoingCall(const std::string& toUrl) = 0; /* Note: we forbid incoming call creation from an instance of Account. * This is why no newIncomingCall() method exist here. diff --git a/daemon/src/client/callmanager.cpp b/daemon/src/client/callmanager.cpp index 6fa6b321ba..10ec3f5e18 100644 --- a/daemon/src/client/callmanager.cpp +++ b/daemon/src/client/callmanager.cpp @@ -61,17 +61,15 @@ registerCallHandlers(const std::map<std::string, } } -bool -placeCall(const std::string& accountID, - const std::string& callID, - const std::string& to) +std::string +placeCall(const std::string& accountID, const std::string& to) { // Check if a destination number is available if (to.empty()) { RING_DBG("No number entered - Call stopped"); - return false; + return {}; } else { - return ring::Manager::instance().outgoingCall(accountID, callID, to); + return ring::Manager::instance().outgoingCall(accountID, to); } } diff --git a/daemon/src/dring/callmanager_interface.h b/daemon/src/dring/callmanager_interface.h index f53970542c..9371889256 100644 --- a/daemon/src/dring/callmanager_interface.h +++ b/daemon/src/dring/callmanager_interface.h @@ -152,7 +152,7 @@ struct CallSignal { void registerCallHandlers(const std::map<std::string, std::shared_ptr<CallbackWrapperBase>>&); /* Call related methods */ -bool placeCall(const std::string& accountID, const std::string& callID, const std::string& to); +std::string placeCall(const std::string& accountID, const std::string& to); bool refuse(const std::string& callID); bool accept(const std::string& callID); diff --git a/daemon/src/iax/iaxaccount.cpp b/daemon/src/iax/iaxaccount.cpp index 6a90d40df2..29a6e8c8d3 100644 --- a/daemon/src/iax/iaxaccount.cpp +++ b/daemon/src/iax/iaxaccount.cpp @@ -43,6 +43,7 @@ #include "logger.h" #include "manager.h" #include "call_factory.h" +#include "intrin.h" #include "config/yamlparser.h" #include <yaml-cpp/yaml.h> @@ -124,16 +125,20 @@ IAXAccount::loadConfig() template <> std::shared_ptr<IAXCall> -IAXAccount::newIncomingCall(const std::string& id) +IAXAccount::newIncomingCall(const std::string& from UNUSED) { - return Manager::instance().callFactory.newCall<IAXCall, IAXAccount>(*this, id, Call::INCOMING); + auto& manager = Manager::instance(); + return manager.callFactory.newCall<IAXCall, IAXAccount>(*this, manager.getNewCallID(), + Call::INCOMING); } template <> std::shared_ptr<IAXCall> -IAXAccount::newOutgoingCall(const std::string& id, const std::string& toUrl) +IAXAccount::newOutgoingCall(const std::string& toUrl) { - auto call = Manager::instance().callFactory.newCall<IAXCall, IAXAccount>(*this, id, Call::OUTGOING); + auto& manager = Manager::instance(); + auto call = manager.callFactory.newCall<IAXCall, IAXAccount>(*this, manager.getNewCallID(), + Call::OUTGOING); call->setPeerNumber(toUrl); call->initRecFilename(toUrl); @@ -147,9 +152,9 @@ IAXAccount::newOutgoingCall(const std::string& id, const std::string& toUrl) } std::shared_ptr<Call> -IAXAccount::newOutgoingCall(const std::string& id, const std::string& toUrl) +IAXAccount::newOutgoingCall(const std::string& toUrl) { - return newOutgoingCall<IAXCall>(id, toUrl); + return newOutgoingCall<IAXCall>(toUrl); } void diff --git a/daemon/src/iax/iaxaccount.h b/daemon/src/iax/iaxaccount.h index 1aa100ead2..7586cae944 100644 --- a/daemon/src/iax/iaxaccount.h +++ b/daemon/src/iax/iaxaccount.h @@ -106,12 +106,10 @@ class IAXAccount : public Account { * Implementation of Account::newOutgoingCall() * Note: keep declaration before newOutgoingCall template. */ - std::shared_ptr<Call> newOutgoingCall(const std::string& id, - const std::string& toUrl); + std::shared_ptr<Call> newOutgoingCall(const std::string& toUrl); /** * Create outgoing IAXCall. - * @param[in] id The ID of the call * @param[in] toUrl The address to call * @return std::shared_ptr<T> A shared pointer on the created call. * The type of this instance is given in template argument. @@ -119,18 +117,18 @@ class IAXAccount : public Account { */ template <class T=IAXCall> std::shared_ptr<enable_if_base_of<T, IAXCall> > - newOutgoingCall(const std::string& id, const std::string& toUrl); + newOutgoingCall(const std::string& toUrl); /** * Create incoming IAXCall. - * @param[in] id The ID of the call + * @param[in] from The origin uri of the call * @return std::shared_ptr<T> A shared pointer on the created call. * The type of this instance is given in template argument. * This type can be any base class of IAXCall class (included). */ template <class T=IAXCall> std::shared_ptr<enable_if_base_of<T, IAXCall> > - newIncomingCall(const std::string& id); + newIncomingCall(const std::string& from); /** * Set whether or not to use UPnP diff --git a/daemon/src/iax/iaxvoiplink.cpp b/daemon/src/iax/iaxvoiplink.cpp index 86ec4fe683..59f8a6a6b7 100644 --- a/daemon/src/iax/iaxvoiplink.cpp +++ b/daemon/src/iax/iaxvoiplink.cpp @@ -400,13 +400,10 @@ void IAXVoIPLink::iaxHandlePrecallEvent(iax_event* event) { const auto accountID = account_.getAccountID(); std::shared_ptr<IAXCall> call; - std::string id; switch (event->etype) { case IAX_EVENT_CONNECT: - id = Manager::instance().getNewCallID(); - - call = account_.newIncomingCall<IAXCall>(id); + call = account_.newIncomingCall<IAXCall>(""); if (!call) { RING_ERR("failed to create an incoming IAXCall from account %s", accountID.c_str()); diff --git a/daemon/src/managerimpl.cpp b/daemon/src/managerimpl.cpp index 24b9caddcf..259c346f32 100644 --- a/daemon/src/managerimpl.cpp +++ b/daemon/src/managerimpl.cpp @@ -369,32 +369,33 @@ ManagerImpl::switchCall(std::shared_ptr<Call> call) /////////////////////////////////////////////////////////////////////////////// /* Main Thread */ -bool +std::string ManagerImpl::outgoingCall(const std::string& preferred_account_id, - const std::string& call_id, const std::string& to, const std::string& conf_id) { - if (call_id.empty()) { - RING_DBG("New outgoing call abort, missing callid"); - return false; - } + std::string current_call_id(getCurrentCallId()); + std::string prefix(hookPreference.getNumberAddPrefix()); + std::string to_cleaned(NumberCleaner::clean(to, prefix)); + std::shared_ptr<Call> call; - // Call ID must be unique - if (isValidCall(call_id)) { - RING_ERR("Call id already exists in outgoing call"); - return false; + try { + /* RING_WARN: after this call the account_id is obsolete + * as the factory may decide to use another account (like IP2IP). + */ + RING_DBG("New outgoing call to %s", to_cleaned.c_str()); + call = newOutgoingCall(to_cleaned, preferred_account_id); + } catch (const std::exception &e) { + RING_ERR("%s", e.what()); + return {}; } - RING_DBG("New outgoing call %s to %s", call_id.c_str(), to.c_str()); - - stopTone(); - - std::string current_call_id(getCurrentCallId()); + if (not call) + return {}; - std::string prefix(hookPreference.getNumberAddPrefix()); + auto call_id = call->getCallId(); - std::string to_cleaned(NumberCleaner::clean(to, prefix)); + stopTone(); // in any cases we have to detach from current communication if (hasCurrentCall()) { @@ -407,22 +408,6 @@ ManagerImpl::outgoingCall(const std::string& preferred_account_id, detachParticipant(RingBufferPool::DEFAULT_ID); } - std::shared_ptr<Call> call; - - try { - /* RING_WARN: after this call the account_id is obsolete - * as the factory may decide to use another account (like IP2IP). - */ - RING_DBG("New outgoing call to %s", to_cleaned.c_str()); - call = newOutgoingCall(call_id, to_cleaned, preferred_account_id); - } catch (const std::exception &e) { - RING_ERR("%s", e.what()); - return false; - } - - if (not call) - return false; - // try to reverse match the peer name using the cache if (call->getDisplayName().empty()) { const auto& name = history_.getNameFromHistory(call->getPeerNumber(), @@ -433,7 +418,8 @@ ManagerImpl::outgoingCall(const std::string& preferred_account_id, } switchCall(call); call->setConfId(conf_id); - return true; + + return call_id; } //THREAD=Main : for outgoing Call @@ -1118,23 +1104,18 @@ ManagerImpl::createConfFromParticipantList(const std::vector< std::string > &par std::string tostr(numberaccount.substr(0, numberaccount.find(","))); std::string account(numberaccount.substr(numberaccount.find(",") + 1, numberaccount.size())); - std::string generatedCallID(getNewCallID()); - - // Manager methods may behave differently if the call id participates in a conference - conf->add(generatedCallID); - unsetCurrentCall(); // Create call - bool callSuccess = outgoingCall(account, generatedCallID, tostr, conf->getConfID()); - - // If not able to create call remove this participant from the conference - if (!callSuccess) - conf->remove(generatedCallID); - else { - emitSignal<DRing::CallSignal::NewCallCreated>(account, generatedCallID, tostr); - successCounter++; - } + auto call_id = outgoingCall(account, tostr, conf->getConfID()); + if (call_id.empty()) + continue; + + // Manager methods may behave differently if the call id participates in a conference + conf->add(call_id); + + emitSignal<DRing::CallSignal::NewCallCreated>(account, call_id, tostr); + successCounter++; } // Create the conference if and only if at least 2 calls have been successfully created @@ -2781,8 +2762,7 @@ ManagerImpl::getAudioDriver() } std::shared_ptr<Call> -ManagerImpl::newOutgoingCall(const std::string& id, - const std::string& toUrl, +ManagerImpl::newOutgoingCall(const std::string& toUrl, const std::string& preferredAccountId) { std::shared_ptr<Account> account = Manager::instance().getIP2IPAccount(); @@ -2793,7 +2773,7 @@ ManagerImpl::newOutgoingCall(const std::string& id, RING_WARN("Ring DHT call detected"); auto dhtAcc = getAllAccounts<RingAccount>(); if (not dhtAcc.empty()) - return dhtAcc.front()->newOutgoingCall(id, finalToUrl); + return dhtAcc.front()->newOutgoingCall(finalToUrl); } #endif @@ -2815,7 +2795,7 @@ ManagerImpl::newOutgoingCall(const std::string& id, return nullptr; } - return account->newOutgoingCall(id, finalToUrl); + return account->newOutgoingCall(finalToUrl); } } // namespace ring diff --git a/daemon/src/managerimpl.h b/daemon/src/managerimpl.h index ed14a7fcf6..6ca8eb607f 100644 --- a/daemon/src/managerimpl.h +++ b/daemon/src/managerimpl.h @@ -149,13 +149,13 @@ class ManagerImpl { * Functions which occur with a user's action * Place a new call * @param accountId The account to make the call with - * @param call_id The call identifier * @param to The recipient of the call * @param conf_id The conference identifier if any - * @return bool true on success - * false otherwise + * @return id The call ID on success, empty string otherwise */ - bool outgoingCall(const std::string&, const std::string&, const std::string&, const std::string& = ""); + std::string outgoingCall(const std::string& accountId, + const std::string& to, + const std::string& conf_id = ""); /** * Functions which occur with a user's action @@ -919,15 +919,13 @@ class ManagerImpl { /** * Create a new outgoing call - * @param id The ID of the call * @param toUrl The address to call * @param preferredAccountId The IP of preferred account to use. * This is not necessary the account used. * @return Call* A shared pointer on a valid call. * @note This function raises VoipLinkException() on errors. */ - std::shared_ptr<Call> newOutgoingCall(const std::string& id, - const std::string& toUrl, + std::shared_ptr<Call> newOutgoingCall(const std::string& toUrl, const std::string& preferredAccountId); CallFactory callFactory; diff --git a/daemon/src/ringdht/ringaccount.cpp b/daemon/src/ringdht/ringaccount.cpp index af07284250..99bdd685fc 100644 --- a/daemon/src/ringdht/ringaccount.cpp +++ b/daemon/src/ringdht/ringaccount.cpp @@ -135,8 +135,9 @@ RingAccount::newIncomingCall(const std::string& from) template <> std::shared_ptr<SIPCall> -RingAccount::newOutgoingCall(const std::string& id, const std::string& toUrl) +RingAccount::newOutgoingCall(const std::string& toUrl) { + auto& manager = Manager::instance(); auto dhtf = toUrl.find("ring:"); if (dhtf != std::string::npos) { dhtf = dhtf+5; @@ -153,11 +154,12 @@ RingAccount::newOutgoingCall(const std::string& id, const std::string& toUrl) RING_DBG("Calling DHT peer %s", toUri.c_str()); auto toH = dht::InfoHash(toUri); - auto call = Manager::instance().callFactory.newCall<SIPCall, RingAccount>(*this, id, Call::OUTGOING); + auto call = manager.callFactory.newCall<SIPCall, RingAccount>(*this, manager.getNewCallID(), + Call::OUTGOING); call->setIPToIP(true); call->setSecure(isTlsEnabled()); - auto& iceTransportFactory = Manager::instance().getIceTransportFactory(); + auto& iceTransportFactory = manager.getIceTransportFactory(); auto ice = iceTransportFactory.createTransport( ("sip:"+call->getCallId()).c_str(), ICE_COMPONENTS, @@ -277,9 +279,9 @@ RingAccount::createOutgoingCall(const std::shared_ptr<SIPCall>& call, const std: } std::shared_ptr<Call> -RingAccount::newOutgoingCall(const std::string& id, const std::string& toUrl) +RingAccount::newOutgoingCall(const std::string& toUrl) { - return newOutgoingCall<SIPCall>(id, toUrl); + return newOutgoingCall<SIPCall>(toUrl); } bool diff --git a/daemon/src/ringdht/ringaccount.h b/daemon/src/ringdht/ringaccount.h index 8edde3dd6b..0249b66907 100644 --- a/daemon/src/ringdht/ringaccount.h +++ b/daemon/src/ringdht/ringaccount.h @@ -207,11 +207,10 @@ class RingAccount : public SIPAccountBase { * Implementation of Account::newOutgoingCall() * Note: keep declaration before newOutgoingCall template. */ - std::shared_ptr<Call> newOutgoingCall(const std::string& id, const std::string& toUrl); + std::shared_ptr<Call> newOutgoingCall(const std::string& toUrl); /** * Create outgoing SIPCall. - * @param[in] id The ID of the call * @param[in] toUrl The address to call * @return std::shared_ptr<T> A shared pointer on the created call. * The type of this instance is given in template argument. @@ -219,11 +218,11 @@ class RingAccount : public SIPAccountBase { */ template <class T=SIPCall> std::shared_ptr<enable_if_base_of<T, SIPCall> > - newOutgoingCall(const std::string& id, const std::string& toUrl); + newOutgoingCall(const std::string& toUrl); /** * Create incoming SIPCall. - * @param[in] id The ID of the call + * @param[in] from The origin of the call * @return std::shared_ptr<T> A shared pointer on the created call. * The type of this instance is given in template argument. * This type can be any base class of SIPCall class (included). diff --git a/daemon/src/sip/sipaccount.cpp b/daemon/src/sip/sipaccount.cpp index d4efcbdff8..c376069a14 100644 --- a/daemon/src/sip/sipaccount.cpp +++ b/daemon/src/sip/sipaccount.cpp @@ -169,7 +169,7 @@ SIPAccount::~SIPAccount() } std::shared_ptr<SIPCall> -SIPAccount::newIncomingCall(const std::string&) +SIPAccount::newIncomingCall(const std::string& from UNUSED) { auto& manager = Manager::instance(); return manager.callFactory.newCall<SIPCall, SIPAccount>(*this, manager.getNewCallID(), Call::INCOMING); @@ -177,13 +177,14 @@ SIPAccount::newIncomingCall(const std::string&) template <> std::shared_ptr<SIPCall> -SIPAccount::newOutgoingCall(const std::string& id, const std::string& toUrl) +SIPAccount::newOutgoingCall(const std::string& toUrl) { std::string to; std::string toUri; int family; - auto call = Manager::instance().callFactory.newCall<SIPCall, SIPAccount>(*this, id, Call::OUTGOING); + auto& manager = Manager::instance(); + auto call = manager.callFactory.newCall<SIPCall, SIPAccount>(*this, manager.getNewCallID(), Call::OUTGOING); if (isIP2IP()) { bool ipv6 = false; @@ -273,9 +274,9 @@ SIPAccount::newOutgoingCall(const std::string& id, const std::string& toUrl) } std::shared_ptr<Call> -SIPAccount::newOutgoingCall(const std::string& id, const std::string& toUrl) +SIPAccount::newOutgoingCall(const std::string& toUrl) { - return newOutgoingCall<SIPCall>(id, toUrl); + return newOutgoingCall<SIPCall>(toUrl); } bool diff --git a/daemon/src/sip/sipaccount.h b/daemon/src/sip/sipaccount.h index 5eaf76911c..f14d22e956 100644 --- a/daemon/src/sip/sipaccount.h +++ b/daemon/src/sip/sipaccount.h @@ -465,12 +465,10 @@ class SIPAccount : public SIPAccountBase { * Implementation of Account::newOutgoingCall() * Note: keep declaration before newOutgoingCall template. */ - std::shared_ptr<Call> newOutgoingCall(const std::string& id, - const std::string& toUrl); + std::shared_ptr<Call> newOutgoingCall(const std::string& toUrl); /** * Create outgoing SIPCall. - * @param[in] id The ID of the call * @param[in] toUrl The address to call * @return std::shared_ptr<T> A shared pointer on the created call. * The type of this instance is given in template argument. @@ -478,17 +476,17 @@ class SIPAccount : public SIPAccountBase { */ template <class T=SIPCall> std::shared_ptr<enable_if_base_of<T, SIPCall> > - newOutgoingCall(const std::string& id, const std::string& toUrl); + newOutgoingCall(const std::string& toUrl); /** * Create incoming SIPCall. - * @param[in] id The ID of the call + * @param[in] from The origin uri of the call * @return std::shared_ptr<T> A shared pointer on the created call. * The type of this instance is given in template argument. * This type can be any base class of SIPCall class (included). */ std::shared_ptr<SIPCall> - newIncomingCall(const std::string&); + newIncomingCall(const std::string& from); void onRegister(pjsip_regc_cbparam *param); diff --git a/daemon/src/sip/sipvoiplink.cpp b/daemon/src/sip/sipvoiplink.cpp index d77c19826b..f9a7fa616d 100644 --- a/daemon/src/sip/sipvoiplink.cpp +++ b/daemon/src/sip/sipvoiplink.cpp @@ -1216,8 +1216,7 @@ onCallTransfered(pjsip_inv_session *inv, pjsip_rx_data *rdata) } try { - Manager::instance().newOutgoingCall(Manager::instance().getNewCallID(), - std::string(refer_to->hvalue.ptr, + Manager::instance().newOutgoingCall(std::string(refer_to->hvalue.ptr, refer_to->hvalue.slen), currentCall->getAccountId()); Manager::instance().hangupCall(currentCall->getCallId()); -- GitLab