From 2c7f03af0d5e12551649d515dd6b6e892b9a0d6d Mon Sep 17 00:00:00 2001
From: Stepan Salenikovich <stepan.salenikovich@savoirfairelinux.com>
Date: Thu, 25 Jun 2015 16:07:22 -0400
Subject: [PATCH] deamon: check on/off hold state change success
Do not emit HOLD state change if it did not succeed
in the daemon.
Refs #76232
Change-Id: Ib7c95b934d03152db5592706fdea953d56b6e280
---
src/call.cpp | 7 +++++--
src/call.h | 4 ++--
src/iax/iaxcall.cpp | 13 ++++++++-----
src/iax/iaxcall.h | 4 ++--
src/manager.cpp | 21 ++++++++++++---------
src/sip/sipcall.cpp | 22 +++++++++++++++-------
src/sip/sipcall.h | 6 +++---
7 files changed, 47 insertions(+), 30 deletions(-)
diff --git a/src/call.cpp b/src/call.cpp
index de068038d2..47cedd596a 100644
--- a/src/call.cpp
+++ b/src/call.cpp
@@ -124,10 +124,13 @@ Call::validTransition(CallState newState)
bool
Call::setState(CallState state)
{
+
std::lock_guard<std::mutex> lock(callMutex_);
if (not validTransition(state)) {
- assert((int)callState_ < enum_class_size<CallState>() && (int)state < enum_class_size<CallState>());
- //RING_ERR("Invalid call state transition from %s to %s", states[callState_], states[state]);
+ assert((int)callState_ < enum_class_size<CallState>()
+ && (int)state < enum_class_size<CallState>());
+ RING_ERR("Invalid attempted call state transition from %d to %d",
+ callState_, state);
return false;
}
diff --git a/src/call.h b/src/call.h
index 88f90323b6..767950a243 100644
--- a/src/call.h
+++ b/src/call.h
@@ -271,13 +271,13 @@ class Call : public Recordable, public std::enable_shared_from_this<Call> {
* Put a call on hold
* @return bool True on success
*/
- virtual void onhold() = 0;
+ virtual bool onhold() = 0;
/**
* Resume a call from hold state
* @return bool True on success
*/
- virtual void offhold() = 0;
+ virtual bool offhold() = 0;
/**
* mute/unmute a media of a call
diff --git a/src/iax/iaxcall.cpp b/src/iax/iaxcall.cpp
index 7332f36e8f..38fb846ba4 100644
--- a/src/iax/iaxcall.cpp
+++ b/src/iax/iaxcall.cpp
@@ -194,7 +194,7 @@ IAXCall::attendedTransfer(const std::string& /*targetID*/)
return false; // TODO
}
-void
+bool
IAXCall::onhold()
{
Manager::instance().getRingBufferPool().unBindAll(getCallId());
@@ -204,12 +204,14 @@ IAXCall::onhold()
iax_quelch_moh(session, true);
}
- setState(Call::CallState::HOLD);
+ return setState(Call::CallState::HOLD);
}
-void
+bool
IAXCall::offhold()
{
+ bool success = false;
+
Manager::instance().addStream(*this);
{
@@ -217,9 +219,10 @@ IAXCall::offhold()
iax_unquelch(session);
}
- setState(Call::CallState::ACTIVE);
+ if (success = setState(Call::CallState::ACTIVE))
+ Manager::instance().startAudioDriverStream();
- Manager::instance().startAudioDriverStream();
+ return success;
}
void
diff --git a/src/iax/iaxcall.h b/src/iax/iaxcall.h
index a84599aef8..1ace687369 100644
--- a/src/iax/iaxcall.h
+++ b/src/iax/iaxcall.h
@@ -127,9 +127,9 @@ class IAXCall : public Call
bool attendedTransfer(const std::string& to);
- void onhold();
+ bool onhold();
- void offhold();
+ bool offhold();
//TODO: implement mute for IAX
void muteMedia(const std::string& mediaType, bool isMuted) {}
diff --git a/src/manager.cpp b/src/manager.cpp
index 802a07c247..d686c6eeff 100644
--- a/src/manager.cpp
+++ b/src/manager.cpp
@@ -628,26 +628,29 @@ Manager::onHoldCall(const std::string& callId)
if (auto call = getCallFromCallID(callId)) {
try {
- call->onhold();
- removeStream(*call); // Unbind calls in main buffer
+ if (result = call->onhold())
+ removeStream(*call); // Unbind calls in main buffer
} catch (const VoipLinkException &e) {
RING_ERR("%s", e.what());
result = false;
}
+
} else {
RING_DBG("CallID %s doesn't exist in call onHold", callId.c_str());
return false;
}
- // Remove call from teh queue if it was still there
- removeWaitingCall(callId);
+ if (result) {
+ // Remove call from the queue if it was still there
+ removeWaitingCall(callId);
- // keeps current call id if the action is not holding this call or a new outgoing call
- // this could happen in case of a conference
- if (current_call_id == callId)
- unsetCurrentCall();
+ // keeps current call id if the action is not holding this call
+ // or a new outgoing call. This could happen in case of a conference
+ if (current_call_id == callId)
+ unsetCurrentCall();
- emitSignal<DRing::CallSignal::StateChange>(callId, "HOLD", 0);
+ emitSignal<DRing::CallSignal::StateChange>(callId, "HOLD", 0);
+ }
return result;
}
diff --git a/src/sip/sipcall.cpp b/src/sip/sipcall.cpp
index 4f099f6a3e..efcd8dcb53 100644
--- a/src/sip/sipcall.cpp
+++ b/src/sip/sipcall.cpp
@@ -585,11 +585,11 @@ SIPCall::attendedTransfer(const std::string& to)
return transferCommon(&dst);
}
-void
+bool
SIPCall::onhold()
{
if (not setState(CallState::HOLD))
- return;
+ return false;
stopAllMedia();
@@ -597,30 +597,35 @@ SIPCall::onhold()
if (SIPSessionReinvite() != PJ_SUCCESS)
RING_WARN("Reinvite failed");
}
+
+ return true;
}
-void
+bool
SIPCall::offhold()
{
+ bool success = false;
auto& account = getSIPAccount();
try {
if (account.isStunEnabled())
- internalOffHold([&] { updateSDPFromSTUN(); });
+ success = internalOffHold([&] { updateSDPFromSTUN(); });
else
- internalOffHold([] {});
+ success = internalOffHold([] {});
} catch (const SdpException &e) {
RING_ERR("%s", e.what());
throw VoipLinkException("SDP issue in offhold");
}
+
+ return success;
}
-void
+bool
SIPCall::internalOffHold(const std::function<void()>& sdp_cb)
{
if (not setState(CallState::ACTIVE))
- return;
+ return false;
sdp_cb();
@@ -628,8 +633,11 @@ SIPCall::internalOffHold(const std::function<void()>& sdp_cb)
if (SIPSessionReinvite() != PJ_SUCCESS) {
RING_WARN("Reinvite failed, resuming hold");
onhold();
+ return false;
}
}
+
+ return true;
}
void
diff --git a/src/sip/sipcall.h b/src/sip/sipcall.h
index 46b05b2920..06ac8cbf3c 100644
--- a/src/sip/sipcall.h
+++ b/src/sip/sipcall.h
@@ -152,9 +152,9 @@ class SIPCall : public Call
bool attendedTransfer(const std::string& to);
- void onhold();
+ bool onhold();
- void offhold();
+ bool offhold();
void switchInput(const std::string& resource);
@@ -221,7 +221,7 @@ class SIPCall : public Call
*/
bool transferCommon(pj_str_t *dst);
- void internalOffHold(const std::function<void()> &SDPUpdateFunc);
+ bool internalOffHold(const std::function<void()> &SDPUpdateFunc);
int SIPSessionReinvite();
--
GitLab