diff --git a/daemon/src/call.h b/daemon/src/call.h index 281f8967241f487d96d3bc2790c735a78592052d..2a4b8da43b2a4241127832b1bb66d8fad5479912 100644 --- a/daemon/src/call.h +++ b/daemon/src/call.h @@ -173,8 +173,6 @@ class Call : public Recordable { isIPToIP_ = IPToIP; } - virtual void answer() = 0; - /** * Set my IP [not protected] * @param ip The local IP address diff --git a/daemon/src/iax/iaxcall.h b/daemon/src/iax/iaxcall.h index 1cf5233cea23d6af5b13e37b4d81333e49e1d771..d9dfde77009e8ebaf08a259e03cb9ec0a4d38465 100644 --- a/daemon/src/iax/iaxcall.h +++ b/daemon/src/iax/iaxcall.h @@ -71,10 +71,11 @@ class IAXCall : public Call { int getAudioCodec() const; + void answer(); + int format; iax_session* session; private: - virtual void answer(); NON_COPYABLE(IAXCall); }; diff --git a/daemon/src/iax/iaxvoiplink.cpp b/daemon/src/iax/iaxvoiplink.cpp index aaf1333cf26eb123af2f7ba986d1cb7af55a72fe..0518937d6e839d140ff4683992ecf0b53390f1d9 100644 --- a/daemon/src/iax/iaxvoiplink.cpp +++ b/daemon/src/iax/iaxvoiplink.cpp @@ -278,7 +278,7 @@ IAXVoIPLink::answer(Call *call) Manager::instance().addStream(call->getCallId()); mutexIAX_.enter(); - call->answer(); + static_cast<IAXCall*>(call)->answer(); mutexIAX_.leave(); call->setState(Call::ACTIVE); diff --git a/daemon/src/sip/sdp.cpp b/daemon/src/sip/sdp.cpp index 0f54dd6621f4deb6b43d0c0415ca22fa70b0bb4e..1c9a547dbae39320d57e5db9855b06e606899662 100644 --- a/daemon/src/sip/sdp.cpp +++ b/daemon/src/sip/sdp.cpp @@ -386,15 +386,16 @@ bool Sdp::createOffer(const vector<int> &selectedCodecs, const vector<map<string, string> > &videoCodecs) { - bool result = true; if (createLocalSession(selectedCodecs, videoCodecs) != PJ_SUCCESS) { ERROR("Failed to create initial offer"); - result = false; - } else if (pjmedia_sdp_neg_create_w_local_offer(memPool_, localSession_, &negotiator_) != PJ_SUCCESS) { + return false; + } + + if (pjmedia_sdp_neg_create_w_local_offer(memPool_, localSession_, &negotiator_) != PJ_SUCCESS) { ERROR("Failed to create an initial SDP negotiator"); - result = false; + return false; } - return result; + return true; } void Sdp::receiveOffer(const pjmedia_sdp_session* remote, diff --git a/daemon/src/sip/sipcall.cpp b/daemon/src/sip/sipcall.cpp index f91a00af429ca5774a300594e371ce4aad36c342..8359bf2fe3e5d4eaea8879a8f5c2994a0ea0e6dd 100644 --- a/daemon/src/sip/sipcall.cpp +++ b/daemon/src/sip/sipcall.cpp @@ -62,10 +62,10 @@ SIPCall::~SIPCall() pj_pool_release(pool_); } -void SIPCall::answer() +void SIPCall::answer(bool needsSdp) { pjsip_tx_data *tdata; - if (pjsip_inv_answer(inv, PJSIP_SC_OK, NULL, NULL, &tdata) != PJ_SUCCESS) + if (pjsip_inv_answer(inv, PJSIP_SC_OK, NULL, needsSdp ? local_sdp_->getLocalSdpSession() : NULL, &tdata) != PJ_SUCCESS) throw std::runtime_error("Could not init invite request answer (200 OK)"); if (pjsip_inv_send_msg(inv, tdata) != PJ_SUCCESS) diff --git a/daemon/src/sip/sipcall.h b/daemon/src/sip/sipcall.h index ba7e5e28780a4512579a2d42be89cfdd3486cd71..edd56b6afe15f5ad9871e012dd48b386cf5d1a65 100644 --- a/daemon/src/sip/sipcall.h +++ b/daemon/src/sip/sipcall.h @@ -100,6 +100,10 @@ class SIPCall : public Call { return pool_; } + // @param needsSdp: true if the invite was received without an SDP + // and thus one must been added, false otherwise + void answer(bool needsSdp); + /** * The invite session to be reused in case of transfer */ @@ -114,8 +118,6 @@ class SIPCall : public Call { std::map<std::string, std::string> createHistoryEntry() const; - virtual void answer(); - NON_COPYABLE(SIPCall); /** diff --git a/daemon/src/sip/sipvoiplink.cpp b/daemon/src/sip/sipvoiplink.cpp index 2c1182b2131396ae06ef66aed8f4654d53b299d8..6967efe2a4614f70c9ac2f86afc51fd4b6c26db6 100644 --- a/daemon/src/sip/sipvoiplink.cpp +++ b/daemon/src/sip/sipvoiplink.cpp @@ -902,7 +902,17 @@ SIPVoIPLink::answer(Call *call) { if (!call) return; - call->answer(); + + SIPCall *sipCall = static_cast<SIPCall*>(call); + bool needsSdp = false; + if (!sipCall->inv->neg) { + WARN("Negotiator is NULL, we've received an INVITE without an SDP"); + pjmedia_sdp_session *dummy; + sdp_create_offer_cb(sipCall->inv, &dummy); + needsSdp = true; + } + + sipCall->answer(needsSdp); } namespace { @@ -946,8 +956,15 @@ SIPVoIPLink::hangup(const std::string& id) pjsip_tx_data *tdata = NULL; + const int status = + inv->state <= PJSIP_INV_STATE_EARLY and inv->role != PJSIP_ROLE_UAC ? + PJSIP_SC_CALL_TSX_DOES_NOT_EXIST : + inv->state >= PJSIP_INV_STATE_DISCONNECTED ? PJSIP_SC_DECLINE : + 0; + + // User hangup current call. Notify peer - if (pjsip_inv_end_session(inv, 0, NULL, &tdata) != PJ_SUCCESS || !tdata) + if (pjsip_inv_end_session(inv, status, NULL, &tdata) != PJ_SUCCESS || !tdata) return; // add contact header