From 9142eb7790616b1dfffd874dc3f73b73c614f694 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrien=20B=C3=A9raud?= Date: Wed, 18 Mar 2015 18:11:41 -0400 Subject: [PATCH] sip: end call on transport failure Refs #68135 Change-Id: Ic05d6dd781680f3261c40afb4625876d776208fe --- daemon/src/sip/sipcall.cpp | 30 ++++++++++++++++++++++++++++++ daemon/src/sip/sipcall.h | 4 +--- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/daemon/src/sip/sipcall.cpp b/daemon/src/sip/sipcall.cpp index 12eaee3b9..af66eeb21 100644 --- a/daemon/src/sip/sipcall.cpp +++ b/daemon/src/sip/sipcall.cpp @@ -131,6 +131,7 @@ SIPCall::SIPCall(SIPAccountBase& account, const std::string& id, Call::CallType SIPCall::~SIPCall() { + setTransport({}); inv.reset(); // prevents callback usage } @@ -183,6 +184,35 @@ void SIPCall::setContactHeader(pj_str_t *contact) pj_strcpy(&contactHeader_, contact); } +void +SIPCall::setTransport(const std::shared_ptr& t) +{ + const auto list_id = reinterpret_cast(this); + if (transport_) + transport_->removeStateListener(list_id); + transport_ = t; + + if (transport_) { + std::weak_ptr wthis_ = std::static_pointer_cast(shared_from_this()); + + // listen for transport destruction + transport_->addStateListener(list_id, + [wthis_, t, list_id] (pjsip_transport_state state, + const pjsip_transport_state_info*) + { + if (auto this_ = wthis_.lock()) { + // end the call if the SIP transport is shut down + if (not SipTransport::isAlive(t, state)) { + RING_WARN("Ending call because underlying SIP transport was closed"); + Manager::instance().callFailure(*this_); + this_->removeCall(); + } + } else // should not happen + t->removeStateListener(list_id); + }); + } +} + /** * Send a reINVITE inside an active dialog to modify its state * Local SDP session should be modified before calling this method diff --git a/daemon/src/sip/sipcall.h b/daemon/src/sip/sipcall.h index 7c4fe2af6..27fcaafff 100644 --- a/daemon/src/sip/sipcall.h +++ b/daemon/src/sip/sipcall.h @@ -134,9 +134,7 @@ class SIPCall : public Call void setContactHeader(pj_str_t *contact); - void setTransport(const std::shared_ptr& t) { - transport_ = t; - } + void setTransport(const std::shared_ptr& t); inline const std::shared_ptr& getTransport() { return transport_;