diff --git a/daemon/bin/dbus/callmanager-introspec.xml b/daemon/bin/dbus/callmanager-introspec.xml index 8b896903eec1407e3b5e3acfe64dbf49b5327a0a..3ab2b088513dd4204cc6ac13beaebeff978fdba1 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 20d0ee772dc54698344b952fe93bd81f2112c225..6406de46454541acf62cc706cec05fba675905a3 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 0ef4dc42e942cf7b94d37550f42380cd93cdbb60..9b109a2fb09bfe51b012fe2e7c287363bd12058e 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 2505d43032e06c0105f3d8f06adc2f94e52065fa..443d91bd009acb13e02621c5ac21bb747be4322c 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 6fa6b321ba4feb83332ffbedd88d230882aaf86e..10ec3f5e1818a3170737fc301ba503acef063b2b 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 f53970542ccce5840562cb74730ebc9efba32682..9371889256e48cf1f11448170fec33fe649e3b6f 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 6a90d40df2e58f5b920159069ecc68c537086bc7..29a6e8c8d3193efb1bd33390ed8ccc504b9e74bf 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 1aa100ead20b2e884f7796d32aab01590ca67378..7586cae944ba706319f50f6db9a2762762cf55b7 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 86ec4fe68355edb889aa5851eae18581d1955cbb..59f8a6a6b7f312e28bad2081c1b7dd73b594fad2 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 24b9caddcf46dcce1cbea4440ad0724baefaa430..259c346f32e942f52525e358b2e82fed4f5ccb17 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 ed14a7fcf6e8678093a63d0cc0a3f926c636d16d..6ca8eb607f7cbd2127e33fb875402bd7cab6fa24 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 af072842501209f2e81bf931e7548bd26101a870..99bdd685fcf679884542f748e3fdebd200950723 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 8edde3dd6bd526bdc3bec624277f3e716314927f..0249b66907e1082ad06ab795627fa536b220fa0d 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 d4efcbdff8ceef152f4c53c03dbc3b421e51ea18..c376069a14ce56f7d12266fdaac7f3ca7ec32f70 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 5eaf76911c2763db57ef17a5c6385fe3a9ec51a6..f14d22e9567b8146133e0bcd5374521dd9c89c45 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 d77c19826b5814a55d73b5172cd9bb94b7428420..f9a7fa616d519363918b57825cc5470dc705fd6d 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());