diff --git a/daemon/src/client/callmanager.cpp b/daemon/src/client/callmanager.cpp index feea893e1a409fdc30e3ac5af8288d534b6127f2..435dc29e31136270d1415a50d4634ecaf87bfb21 100644 --- a/daemon/src/client/callmanager.cpp +++ b/daemon/src/client/callmanager.cpp @@ -259,7 +259,11 @@ CallManager::getCallList() void CallManager::playDTMF(const std::string& key) { - Manager::instance().sendDtmf(Manager::instance().getCurrentCallId(), key.data()[0]); + auto code = key.data()[0]; + Manager::instance().playDtmf(code); + + if (auto current_call = Manager::instance().getCurrentCall()) + current_call->carryingDTMFdigits(code); } void diff --git a/daemon/src/iax/iaxcall.cpp b/daemon/src/iax/iaxcall.cpp index 2a4f56c67d3166d96a0cc446ccc8fe93c3477261..e72627838e88adf6d4bd79a33290b65f57b71648 100644 --- a/daemon/src/iax/iaxcall.cpp +++ b/daemon/src/iax/iaxcall.cpp @@ -140,7 +140,7 @@ int IAXCall::getAudioCodec() const void IAXCall::answer() { - Manager::instance().addStream(getCallId()); + Manager::instance().addStream(*this); { std::lock_guard<std::mutex> lock(IAXVoIPLink::mutexIAX); @@ -207,7 +207,7 @@ IAXCall::onhold() void IAXCall::offhold() { - Manager::instance().addStream(getCallId()); + Manager::instance().addStream(*this); { std::lock_guard<std::mutex> lock(IAXVoIPLink::mutexIAX); diff --git a/daemon/src/iax/iaxvoiplink.cpp b/daemon/src/iax/iaxvoiplink.cpp index ba1eb9b7e711df90b7a833bcc27d992174a71c63..47ed7c7f3c6e5d96655b6f80bb4d89f495a09199 100644 --- a/daemon/src/iax/iaxvoiplink.cpp +++ b/daemon/src/iax/iaxvoiplink.cpp @@ -207,7 +207,7 @@ IAXVoIPLink::handleReject(IAXCall& call) { call.setConnectionState(Call::CONNECTED); call.setState(Call::MERROR); - Manager::instance().callFailure(call.getCallId()); + Manager::instance().callFailure(call); call.removeCall(); } @@ -230,9 +230,8 @@ IAXVoIPLink::handleAnswerTransfer(iax_event* event, IAXCall& call) if (event->ies.format) call.format = event->ies.format; - const auto& id = call.getCallId(); - Manager::instance().addStream(id); - Manager::instance().peerAnsweredCall(id); + Manager::instance().addStream(call); + Manager::instance().peerAnsweredCall(call); Manager::instance().startAudioDriverStream(); Manager::instance().getRingBufferPool().flushAllBuffers(); } @@ -243,7 +242,7 @@ IAXVoIPLink::handleBusy(IAXCall& call) call.setConnectionState(Call::CONNECTED); call.setState(Call::BUSY); - Manager::instance().callBusy(call.getCallId()); + Manager::instance().callBusy(call); call.removeCall(); } @@ -260,13 +259,13 @@ void IAXVoIPLink::handleRinging(IAXCall& call) { call.setConnectionState(Call::RINGING); - Manager::instance().peerRingingCall(call.getCallId()); + Manager::instance().peerRingingCall(call); } void IAXVoIPLink::handleHangup(IAXCall& call) { - Manager::instance().peerHungupCall(call.getCallId()); + Manager::instance().peerHungupCall(call); call.removeCall(); } @@ -426,8 +425,7 @@ void IAXVoIPLink::iaxHandlePrecallEvent(iax_event* event) case IAX_EVENT_HANGUP: if (auto raw_call_ptr = iaxGetCallFromSession(event->session)) { - id = raw_call_ptr->getCallId(); - Manager::instance().peerHungupCall(id); + Manager::instance().peerHungupCall(*raw_call_ptr); raw_call_ptr->removeCall(); } diff --git a/daemon/src/managerimpl.cpp b/daemon/src/managerimpl.cpp index 0f3cd20cec164ffdd7fff5f6406ee617d7a5327b..760bcf170b108eebd4a4daf50f1dbd5b6a1e5fd6 100644 --- a/daemon/src/managerimpl.cpp +++ b/daemon/src/managerimpl.cpp @@ -379,32 +379,35 @@ ManagerImpl::outgoingCall(const std::string& preferred_account_id, detachParticipant(sfl::RingBufferPool::DEFAULT_ID); } + std::shared_ptr<Call> call; + try { /* SFL_WARN: after this call the account_id is obsolete * as the factory may decide to use another account (like IP2IP). */ SFL_DBG("New outgoing call to %s", to_cleaned.c_str()); - auto call = newOutgoingCall(call_id, to_cleaned, preferred_account_id); - - // try to reverse match the peer name using the cache - if (call->getDisplayName().empty()) { - const auto& name = history_.getNameFromHistory(call->getPeerNumber(), - call->getAccountId()); - const std::string pseudo_contact_name(name); - if (not pseudo_contact_name.empty()) - call->setDisplayName(pseudo_contact_name); - } - switchCall(call); - call->setConfId(conf_id); + call = newOutgoingCall(call_id, to_cleaned, preferred_account_id); } catch (ost::Socket *) { - callFailure(call_id); SFL_ERR("Could not bind socket"); return false; } catch (const std::exception &e) { - callFailure(call_id); SFL_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(), + call->getAccountId()); + const std::string pseudo_contact_name(name); + if (not pseudo_contact_name.empty()) + call->setDisplayName(pseudo_contact_name); + } + switchCall(call); + call->setConfId(conf_id); return true; } @@ -458,7 +461,7 @@ ManagerImpl::answerCall(const std::string& call_id) switchCall(call); // Connect streams - addStream(call_id); + addStream(*call); // Start recording if set in preference if (audioPreference.getIsAlwaysRecording()) @@ -500,7 +503,7 @@ ManagerImpl::hangupCall(const std::string& callId) } // Disconnect streams - removeStream(callId); + removeStream(*call); if (isConferenceParticipant(callId)) { removeParticipant(callId); @@ -559,21 +562,19 @@ ManagerImpl::onHoldCall(const std::string& callId) std::string current_call_id(getCurrentCallId()); - try { - if (auto call = getCallFromCallID(callId)) { + if (auto call = getCallFromCallID(callId)) { + try { call->onhold(); - } else { - SFL_DBG("CallID %s doesn't exist in call onHold", callId.c_str()); - return false; + removeStream(*call); // Unbind calls in main buffer + } catch (const VoipLinkException &e) { + SFL_ERR("%s", e.what()); + result = false; } - } catch (const VoipLinkException &e) { - SFL_ERR("%s", e.what()); - result = false; + } else { + SFL_DBG("CallID %s doesn't exist in call onHold", callId.c_str()); + return false; } - // Unbind calls in main buffer - removeStream(callId); - // Remove call from teh queue if it was still there removeWaitingCall(callId); @@ -627,7 +628,7 @@ ManagerImpl::offHoldCall(const std::string& callId) else switchCall(call); - addStream(callId); + addStream(*call); return result; } @@ -698,7 +699,7 @@ ManagerImpl::refuseCall(const std::string& id) client_.getCallManager()->callStateChanged(id, "HUNGUP"); // Disconnect streams - removeStream(id); + removeStream(*call); return true; } @@ -918,7 +919,7 @@ ManagerImpl::addParticipant(const std::string& callId, SFL_ERR("Participant list is empty for this conference"); // Connect stream - addStream(callId); + addStream(*call); return true; } @@ -1207,7 +1208,7 @@ ManagerImpl::removeParticipant(const std::string& call_id) conf->remove(call_id); call->setConfId(""); - removeStream(call_id); + removeStream(*call); client_.getCallManager()->conferenceChanged(conf->getConfID(), conf->getStateStr()); @@ -1276,22 +1277,20 @@ ManagerImpl::joinConference(const std::string& conf_id1, } void -ManagerImpl::addStream(const std::string& call_id) +ManagerImpl::addStream(Call& call) { + const auto call_id = call.getCallId(); SFL_DBG("Add audio stream %s", call_id.c_str()); - auto call = getCallFromCallID(call_id); - if (call and isConferenceParticipant(call_id)) { + + if (isConferenceParticipant(call_id)) { SFL_DBG("Add stream to conference"); // bind to conference participant - ConferenceMap::iterator iter = conferenceMap_.find(call->getConfId()); - + ConferenceMap::iterator iter = conferenceMap_.find(call_id); if (iter != conferenceMap_.end() and iter->second) { auto conf = iter->second; - conf->bindParticipant(call_id); } - } else { SFL_DBG("Add stream to call"); @@ -1309,8 +1308,9 @@ ManagerImpl::addStream(const std::string& call_id) } void -ManagerImpl::removeStream(const std::string& call_id) +ManagerImpl::removeStream(Call& call) { + const auto call_id = call.getCallId(); SFL_DBG("Remove audio stream %s", call_id.c_str()); getRingBufferPool().unBindAll(call_id); } @@ -1384,20 +1384,6 @@ ManagerImpl::saveConfig() } } -//THREAD=Main -void -ManagerImpl::sendDtmf(const std::string& id, char code) -{ - playDtmf(code); - - // return if we're not "in" a call - if (id.empty()) - return; - - if (auto call = getCallFromCallID(id)) - call->carryingDTMFdigits(code); -} - //THREAD=Main | VoIPLink void ManagerImpl::playDtmf(char code) @@ -1617,18 +1603,17 @@ ManagerImpl::sendTextMessage(const std::string& callID, //THREAD=VoIP CALL=Outgoing void -ManagerImpl::peerAnsweredCall(const std::string& id) +ManagerImpl::peerAnsweredCall(Call& call) { - auto call = getCallFromCallID(id); - if (!call) return; - SFL_DBG("Peer answered call %s", id.c_str()); + const auto call_id = call.getCallId(); + SFL_DBG("Peer answered call %s", call_id.c_str()); // The if statement is usefull only if we sent two calls at the same time. - if (isCurrentCall(*call)) + if (isCurrentCall(call)) stopTone(); // Connect audio streams - addStream(id); + addStream(call); if (audiodriver_) { std::lock_guard<std::mutex> lock(audioLayerMutex_); @@ -1637,43 +1622,40 @@ ManagerImpl::peerAnsweredCall(const std::string& id) } if (audioPreference.getIsAlwaysRecording()) - toggleRecordingCall(id); + toggleRecordingCall(call_id); - client_.getCallManager()->callStateChanged(id, "CURRENT"); + client_.getCallManager()->callStateChanged(call_id, "CURRENT"); } //THREAD=VoIP Call=Outgoing void -ManagerImpl::peerRingingCall(const std::string& id) +ManagerImpl::peerRingingCall(Call& call) { - auto call = getCallFromCallID(id); - if (!call) return; - SFL_DBG("Peer call %s ringing", id.c_str()); + const auto call_id = call.getCallId(); + SFL_DBG("Peer call %s ringing", call_id.c_str()); - if (isCurrentCall(*call)) + if (isCurrentCall(call)) ringback(); - client_.getCallManager()->callStateChanged(id, "RINGING"); + client_.getCallManager()->callStateChanged(call_id, "RINGING"); } //THREAD=VoIP Call=Outgoing/Ingoing void -ManagerImpl::peerHungupCall(const std::string& call_id) +ManagerImpl::peerHungupCall(Call& call) { - auto call = getCallFromCallID(call_id); - if (!call) return; - + const auto call_id = call.getCallId(); SFL_DBG("Peer hungup call %s", call_id.c_str()); if (isConferenceParticipant(call_id)) { removeParticipant(call_id); - } else if (isCurrentCall(*call)) { + } else if (isCurrentCall(call)) { stopTone(); unsetCurrentCall(); } - history_.addCall(call.get(), preferences.getHistoryLimit()); - call->peerHungup(); + history_.addCall(&call, preferences.getHistoryLimit()); + call.peerHungup(); saveHistory(); client_.getCallManager()->callStateChanged(call_id, "HUNGUP"); @@ -1683,37 +1665,35 @@ ManagerImpl::peerHungupCall(const std::string& call_id) if (not incomingCallsWaiting()) stopTone(); - removeStream(call_id); + removeStream(call); } //THREAD=VoIP void -ManagerImpl::callBusy(const std::string& id) +ManagerImpl::callBusy(Call& call) { - auto call = getCallFromCallID(id); - if (!call) return; + const auto call_id = call.getCallId(); - client_.getCallManager()->callStateChanged(id, "BUSY"); + client_.getCallManager()->callStateChanged(call_id, "BUSY"); - if (isCurrentCall(*call)) { + if (isCurrentCall(call)) { playATone(sfl::Tone::TONE_BUSY); unsetCurrentCall(); } checkAudio(); - removeWaitingCall(id); + removeWaitingCall(call_id); } //THREAD=VoIP void -ManagerImpl::callFailure(const std::string& call_id) +ManagerImpl::callFailure(Call& call) { - client_.getCallManager()->callStateChanged(call_id, "FAILURE"); + const auto call_id = call.getCallId(); - auto call = getCallFromCallID(call_id); - if (!call) return; + client_.getCallManager()->callStateChanged(call_id, "FAILURE"); - if (isCurrentCall(*call)) { + if (isCurrentCall(call)) { playATone(Tone::TONE_BUSY); unsetCurrentCall(); } diff --git a/daemon/src/managerimpl.h b/daemon/src/managerimpl.h index d665bb31f229bd0df58b3d2b9c1819699296e6ce..5dfa2cb4d095facda2bf2939bc35ae1ff4325d52 100644 --- a/daemon/src/managerimpl.h +++ b/daemon/src/managerimpl.h @@ -322,9 +322,9 @@ class ManagerImpl { */ bool joinConference(const std::string& conf_id1, const std::string& conf_id2); - void addStream(const std::string& call_id); + void addStream(Call& call); - void removeStream(const std::string& call_id); + void removeStream(Call& call); /** * Save config to file @@ -336,13 +336,6 @@ class ManagerImpl { */ bool hasTriedToRegister_; - /** - * Handle choice of the DTMF-send-way - * @param id: callid of the line. - * @param code: pressed key. - */ - void sendDtmf(const std::string& id, char code); - /** * Play a ringtone */ @@ -370,20 +363,20 @@ class ManagerImpl { * call in Current state * @param id The call identifier */ - void peerAnsweredCall(const std::string& id); + void peerAnsweredCall(Call& call); /** * Rings back because the outgoing call is ringing and the put the * call in Ringing state * @param id The call identifier */ - void peerRingingCall(const std::string& id); + void peerRingingCall(Call& call); /** * Put the call in Hungup state, remove the call from the list * @param id The call identifier */ - void peerHungupCall(const std::string& id); + void peerHungupCall(Call& call); #if HAVE_INSTANT_MESSAGING /** @@ -689,15 +682,21 @@ class ManagerImpl { */ void congestion(); + /** + * Play the dtmf-associated sound + * @param code The pressed key + */ + void playDtmf(char code); + /** * Handle played sound when a call can not be conpleted because of a busy recipient */ - void callBusy(const std::string& id); + void callBusy(Call& call); /** * Handle played sound when a failure occurs */ - void callFailure(const std::string& id); + void callFailure(Call& call); /** * Retrieve the current telephone tone @@ -754,12 +753,6 @@ class ManagerImpl { const AudioCodecFactory audioCodecFactory; private: - /** - * Play the dtmf-associated sound - * @param code The pressed key - */ - void playDtmf(char code); - void removeAccounts(); bool parseConfiguration(); diff --git a/daemon/src/ringdht/ringaccount.cpp b/daemon/src/ringdht/ringaccount.cpp index c1c06217bfa0314466f2ca70bf67c0811a5dfe34..fcb01f2fa049166d945c63d5ef583a5fdbcd74b0 100644 --- a/daemon/src/ringdht/ringaccount.cpp +++ b/daemon/src/ringdht/ringaccount.cpp @@ -169,7 +169,7 @@ RingAccount::newOutgoingCall(const std::string& id, const std::string& toUrl) auto& this_ = *std::static_pointer_cast<RingAccount>(shared).get(); if (!ok) { call->setConnectionState(Call::DISCONNECTED); - Manager::instance().callFailure(call->getCallId()); + Manager::instance().callFailure(*call); } this_.dht_.cancelPut(callkey, callvid); } @@ -193,7 +193,7 @@ RingAccount::newOutgoingCall(const std::string& id, const std::string& toUrl) ice->start(v->data); if (call->waitForIceNegotiation(ICE_NEGOTIATION_TIMEOUT) <= 0) { call->setConnectionState(Call::DISCONNECTED); - Manager::instance().callFailure(call->getCallId()); + Manager::instance().callFailure(*call); return false; } call->setConnectionState(Call::PROGRESSING); @@ -650,7 +650,7 @@ void RingAccount::doRegister() if (!ok || call->waitForIceNegotiation(ICE_NEGOTIATION_TIMEOUT) <= 0) { SFL_WARN("nego failed"); call->setConnectionState(Call::DISCONNECTED); - Manager::instance().callFailure(call->getCallId()); + Manager::instance().callFailure(*call); } else { SFL_WARN("nego succeeded"); call->setConnectionState(Call::PROGRESSING); diff --git a/daemon/src/sip/sipcall.cpp b/daemon/src/sip/sipcall.cpp index 58573aa18db71ca90b5a8ad243d6f6598a70bb9b..61fe782fd430bab40721fb8468546d9096e83509 100644 --- a/daemon/src/sip/sipcall.cpp +++ b/daemon/src/sip/sipcall.cpp @@ -754,16 +754,14 @@ SIPCall::sendTextMessage(const std::string &message, const std::string &from) void SIPCall::onServerFailure() { - const std::string id(getCallId()); - Manager::instance().callFailure(id); + Manager::instance().callFailure(*this); removeCall(); } void SIPCall::onClosed() { - const std::string id(getCallId()); - Manager::instance().peerHungupCall(id); + Manager::instance().peerHungupCall(*this); removeCall(); Manager::instance().checkAudio(); } @@ -777,7 +775,7 @@ SIPCall::onAnswered() startAllMedia(); setConnectionState(Call::CONNECTED); setState(Call::ACTIVE); - Manager::instance().peerAnsweredCall(getCallId()); + Manager::instance().peerAnsweredCall(*this); } } diff --git a/daemon/src/sip/sipvoiplink.cpp b/daemon/src/sip/sipvoiplink.cpp index 1be1ea63d22e4c9944ff4b79835834fe64a54c84..bfb43b57e5a41111cdc489dea122d7fad42185b6 100644 --- a/daemon/src/sip/sipvoiplink.cpp +++ b/daemon/src/sip/sipvoiplink.cpp @@ -829,7 +829,7 @@ static void makeCallRing(SIPCall &call) { call.setConnectionState(Call::RINGING); - Manager::instance().peerRingingCall(call.getCallId()); + Manager::instance().peerRingingCall(call); } static void @@ -1017,9 +1017,8 @@ sdp_media_update_cb(pjsip_inv_session *inv, pj_status_t status) PJSIP_SC_UNSUPPORTED_MEDIA_TYPE : 0; SFL_WARN("Could not negotiate offer"); - const std::string callID(call->getCallId()); call->hangup(reason); - Manager::instance().callFailure(callID); + Manager::instance().callFailure(*call); return; }