diff --git a/daemon/src/call.h b/daemon/src/call.h index 2c1fae99e7de678c0b88116eb8b7a39179868ede..cab2800ea38c0e6a732e1f16e39cf2437e1fab6b 100644 --- a/daemon/src/call.h +++ b/daemon/src/call.h @@ -283,6 +283,12 @@ class Call : public Recordable { */ virtual void peerHungup() = 0; + /** + * Send DTMF + * @param code The char code + */ + virtual void carryingDTMFdigits(char code) = 0; + private: bool validTransition(CallState newState); diff --git a/daemon/src/iax/iaxcall.cpp b/daemon/src/iax/iaxcall.cpp index 801962a0703c66df79e23f7e5a4e5e2393af5e13..76ba15605605bfbfa01ef931604cee420bf04392 100644 --- a/daemon/src/iax/iaxcall.cpp +++ b/daemon/src/iax/iaxcall.cpp @@ -219,3 +219,10 @@ IAXCall::peerHungup() link_->removeIaxCall(getCallId()); } + +void +IAXCall::carryingDTMFdigits(char code) +{ + std::lock_guard<std::mutex> lock(IAXVoIPLink::mutexIAX); + iax_send_dtmf(session, code); +} diff --git a/daemon/src/iax/iaxcall.h b/daemon/src/iax/iaxcall.h index 36b2048cc0bf77da9b21f5a18b0a4fd3b8ac6e77..84101fb98a9fdc9d645557a62b64142006f53cf5 100644 --- a/daemon/src/iax/iaxcall.h +++ b/daemon/src/iax/iaxcall.h @@ -96,6 +96,8 @@ class IAXCall : public Call { void peerHungup(); + void carryingDTMFdigits(char code); + private: NON_COPYABLE(IAXCall); diff --git a/daemon/src/iax/iaxvoiplink.cpp b/daemon/src/iax/iaxvoiplink.cpp index 12d0b401c947cc5d0d248b4d7e19e49dd07f205b..55ad10a23c8c52a8ded182e95f2f476e69af54d8 100644 --- a/daemon/src/iax/iaxvoiplink.cpp +++ b/daemon/src/iax/iaxvoiplink.cpp @@ -313,20 +313,6 @@ IAXVoIPLink::newOutgoingCall(const std::string& id, const std::string& toUrl, co return call; } -void -IAXVoIPLink::carryingDTMFdigits(const std::string& id, char code) -{ - std::lock_guard<std::mutex> lock(iaxCallMapMutex_); - auto call = getIAXCall(id); - if (!call) - return; - - { - std::lock_guard<std::mutex> lock(mutexIAX); - iax_send_dtmf(call->session, code); - } -} - #if HAVE_INSTANT_MESSAGING void IAXVoIPLink::sendTextMessage(const std::string& callID, diff --git a/daemon/src/iax/iaxvoiplink.h b/daemon/src/iax/iaxvoiplink.h index 4c8a60be4b1fbeb0af7cdc1860cd2b1736be52dc..6fd8acca27bdf9495ce8febad6aa12a1318abac8 100644 --- a/daemon/src/iax/iaxvoiplink.h +++ b/daemon/src/iax/iaxvoiplink.h @@ -127,14 +127,6 @@ class IAXVoIPLink : public VoIPLink { */ virtual void cancel(const std::string& /*id*/) {} - /** - * Send DTMF - * @param id The ID of the call - * @param code The code of the DTMF - */ - virtual void carryingDTMFdigits(const std::string& id, char code); - - #if HAVE_INSTANT_MESSAGING virtual void sendTextMessage(const std::string& callID, const std::string& message, const std::string& from); #endif diff --git a/daemon/src/managerimpl.cpp b/daemon/src/managerimpl.cpp index e780450a1f3523807d99c30e3aa81aab7cb80063..909e32e242b79a55f66f3848267aa2cfdbfbf2a6 100644 --- a/daemon/src/managerimpl.cpp +++ b/daemon/src/managerimpl.cpp @@ -1331,8 +1331,8 @@ void ManagerImpl::sendDtmf(const std::string& id, char code) if (id.empty()) return; - std::string accountid(getAccountFromCall(id)); - getAccountLink(accountid)->carryingDTMFdigits(id, code); + if (auto call = getCallFromCallID(id)) + call->carryingDTMFdigits(code); } //THREAD=Main | VoIPLink diff --git a/daemon/src/sip/sipcall.cpp b/daemon/src/sip/sipcall.cpp index 7166ec2e9b01cf463246c4fb44f49bab7f1557a6..e3a29ba0fb92c2b8496ec98d01b5fc745b785fae 100644 --- a/daemon/src/sip/sipcall.cpp +++ b/daemon/src/sip/sipcall.cpp @@ -36,6 +36,7 @@ #include "logger.h" // for _debug #include "sdp.h" #include "manager.h" +#include "array_size.h" #include "audio/audiortp/audio_rtp_factory.h" // for AudioRtpFactoryException @@ -89,6 +90,35 @@ stopRtpIfCurrent(SIPCall& call) } } +static void +dtmfSend(SIPCall &call, char code, const std::string &dtmf) +{ + if (dtmf == SIPAccount::OVERRTP_STR) { + call.getAudioRtp().sendDtmfDigit(code); + return; + } else if (dtmf != SIPAccount::SIPINFO_STR) { + WARN("Unknown DTMF type %s, defaulting to %s instead", + dtmf.c_str(), SIPAccount::SIPINFO_STR); + } // else : dtmf == SIPINFO + + int duration = Manager::instance().voipPreferences.getPulseLength(); + char dtmf_body[1000]; + const char *normal_str= "Signal=%c\r\nDuration=%d\r\n"; + const char *flash_str = "Signal=%d\r\nDuration=%d\r\n"; + const char *str; + + // handle flash code + if (code == '!') { + str = flash_str; + code = 16; + } else { + str = normal_str; + } + + snprintf(dtmf_body, sizeof dtmf_body - 1, str, code, duration); + call.sendSIPInfo(dtmf_body, "dtmf-relay"); +} + SIPCall::SIPCall(const std::string& id, Call::CallType type, pj_caching_pool *caching_pool, const std::string &account_id) : Call(id, type, account_id) @@ -147,6 +177,35 @@ VoIPLink* SIPCall::getVoIPLink() const { return &SIPVoIPLink::instance(); } +void +SIPCall::sendSIPInfo(const char *const body, const char *const subtype) +{ + pj_str_t methodName = CONST_PJ_STR("INFO"); + pjsip_method method; + pjsip_method_init_np(&method, &methodName); + + /* Create request message. */ + pjsip_tx_data *tdata; + + if (pjsip_dlg_create_request(inv->dlg, &method, -1, &tdata) != PJ_SUCCESS) { + ERROR("Could not create dialog"); + return; + } + + /* Create "application/<subtype>" message body. */ + pj_str_t content; + pj_cstr(&content, body); + const pj_str_t type = CONST_PJ_STR("application"); + pj_str_t pj_subtype; + pj_cstr(&pj_subtype, subtype); + tdata->msg->body = pjsip_msg_body_create(tdata->pool, &type, &pj_subtype, &content); + + if (tdata->msg->body == NULL) + pjsip_tx_data_dec_ref(tdata); + else + pjsip_dlg_send_request(inv->dlg, tdata, SIPVoIPLink::instance().getMod()->id, NULL); +} + void SIPCall::answer() { SIPAccount *account = Manager::instance().getSipAccount(getAccountId()); @@ -578,3 +637,14 @@ SIPCall::peerHungup() siplink.removeSipCall(getCallId()); } + +void +SIPCall::carryingDTMFdigits(char code) +{ + const std::string accountID(getAccountId()); + SIPAccount *account = Manager::instance().getSipAccount(accountID); + if (!account) + return; + + dtmfSend(*this, code, account->getDtmfType()); +} diff --git a/daemon/src/sip/sipcall.h b/daemon/src/sip/sipcall.h index dfd92711291166a06a36cef51a3ae9f7ed906873..9becb5cd0aa373832d6c42be6e1f846bb1c2fa04 100644 --- a/daemon/src/sip/sipcall.h +++ b/daemon/src/sip/sipcall.h @@ -112,6 +112,8 @@ class SIPCall : public Call { VoIPLink* getVoIPLink() const; + void sendSIPInfo(const char *const body, const char *const subtype); + void answer(); void hangup(int reason); @@ -128,6 +130,8 @@ class SIPCall : public Call { void peerHungup(); + void carryingDTMFdigits(char code); + private: // override of Call::createHistoryEntry diff --git a/daemon/src/sip/sipvoiplink.cpp b/daemon/src/sip/sipvoiplink.cpp index 47821142cf39cf9e86f59456c7e266f164ec5f71..5d0b91c45253d974675770411b032f6c12668340 100644 --- a/daemon/src/sip/sipvoiplink.cpp +++ b/daemon/src/sip/sipvoiplink.cpp @@ -1144,65 +1144,6 @@ SIPVoIPLink::tryGetSIPCall(const std::string& id) return call; } -static void -sendSIPInfo(const SIPCall &call, const char *const body, const char *const subtype) -{ - pj_str_t methodName = CONST_PJ_STR("INFO"); - pjsip_method method; - pjsip_method_init_np(&method, &methodName); - - /* Create request message. */ - pjsip_tx_data *tdata; - - if (pjsip_dlg_create_request(call.inv->dlg, &method, -1, &tdata) != PJ_SUCCESS) { - ERROR("Could not create dialog"); - return; - } - - /* Create "application/<subtype>" message body. */ - pj_str_t content; - pj_cstr(&content, body); - const pj_str_t type = CONST_PJ_STR("application"); - pj_str_t pj_subtype; - pj_cstr(&pj_subtype, subtype); - tdata->msg->body = pjsip_msg_body_create(tdata->pool, &type, &pj_subtype, &content); - - if (tdata->msg->body == NULL) - pjsip_tx_data_dec_ref(tdata); - else - pjsip_dlg_send_request(call.inv->dlg, tdata, mod_ua_.id, NULL); -} - -static void -dtmfSend(SIPCall &call, char code, const std::string &dtmf) -{ - if (dtmf == SIPAccount::OVERRTP_STR) { - call.getAudioRtp().sendDtmfDigit(code); - return; - } else if (dtmf != SIPAccount::SIPINFO_STR) { - WARN("Unknown DTMF type %s, defaulting to %s instead", - dtmf.c_str(), SIPAccount::SIPINFO_STR); - } // else : dtmf == SIPINFO - - int duration = Manager::instance().voipPreferences.getPulseLength(); - char dtmf_body[1000]; - - const char *normal_str= "Signal=%c\r\nDuration=%d\r\n"; - const char *flash_str = "Signal=%d\r\nDuration=%d\r\n"; - const char *str; - - // handle flash code - if (code == '!') { - str = flash_str; - code = 16; - } else { - str = normal_str; - } - - snprintf(dtmf_body, sizeof dtmf_body - 1, str, code, duration); - sendSIPInfo(call, dtmf_body, "dtmf-relay"); -} - #ifdef SFL_VIDEO // Called from a video thread void @@ -1246,27 +1187,10 @@ SIPVoIPLink::requestKeyframe(const std::string &callID) "</to_encoder></vc_primitive></media_control>"; DEBUG("Sending video keyframe request via SIP INFO"); - sendSIPInfo(*call, BODY, "media_control+xml"); + call->sendSIPInfo(BODY, "media_control+xml"); } #endif -void -SIPVoIPLink::carryingDTMFdigits(const std::string& id, char code) -{ - auto call = getSipCall(id); - if (!call) - return; - - const std::string accountID(call->getAccountId()); - SIPAccount *account = Manager::instance().getSipAccount(accountID); - - if (!account) - return; - - dtmfSend(*call, code, account->getDtmfType()); -} - - bool SIPVoIPLink::SIPStartCall(std::shared_ptr<SIPCall>& call) { diff --git a/daemon/src/sip/sipvoiplink.h b/daemon/src/sip/sipvoiplink.h index 66fa63a0d286794ae3a28dee7783ed65b7feb0b2..4af99f6e2c0251c8fee6b27d5a7c70df0a830fb8 100644 --- a/daemon/src/sip/sipvoiplink.h +++ b/daemon/src/sip/sipvoiplink.h @@ -159,13 +159,6 @@ class SIPVoIPLink : public VoIPLink { const std::string& toUrl, const std::string &account_id); - /** - * Send DTMF refering to account configuration - * @param id The call identifier - * @param code The char code - */ - virtual void carryingDTMFdigits(const std::string& id, char code); - /** * Tell the user that the call was answered * @param diff --git a/daemon/src/voiplink.h b/daemon/src/voiplink.h index aeb97e6c55c38cc95da4e09f0ab8380973438df2..248e187a752fbc36a81f0b725de48aca93ad7946 100644 --- a/daemon/src/voiplink.h +++ b/daemon/src/voiplink.h @@ -93,13 +93,6 @@ class VoIPLink { */ virtual std::vector<std::shared_ptr<Call> > getCalls(const std::string &account_id) const = 0; - /** - * Send DTMF - * @param id The call identifier - * @param code The char code - */ - virtual void carryingDTMFdigits(const std::string &id, char code) = 0; - /** * Send a message to a call identified by its callid *