From 84a0c3e84f0cea2aaf12660c4c1441eeaf8f1807 Mon Sep 17 00:00:00 2001 From: Donat Zenichev Date: Fri, 28 Apr 2023 08:44:47 +0200 Subject: [PATCH] MT#57256 Do not change OA state of similar 183 SDP We don't have to change the SDP OA state, in case the 183 response has exactly the same SDP content (same SDP session version) as we already have seen before in previous 183 message. Change-Id: Ica008104c31e979cdcb352cefea39db4d1ff3c56 --- core/AmOfferAnswer.cpp | 35 +++++++++++++++++++++++++++-------- core/AmOfferAnswer.h | 2 +- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/core/AmOfferAnswer.cpp b/core/AmOfferAnswer.cpp index df12278c..57322cbb 100644 --- a/core/AmOfferAnswer.cpp +++ b/core/AmOfferAnswer.cpp @@ -268,7 +268,7 @@ int AmOfferAnswer::onRxSdp(unsigned int m_cseq, const AmMimeBody& body, const ch return err_code; } -int AmOfferAnswer::onTxSdp(unsigned int m_cseq, const AmMimeBody& body) +int AmOfferAnswer::onTxSdp(unsigned int m_cseq, const AmMimeBody& body, bool force_no_sdp_update) { DBG("AmOfferAnswer::onTxSdp()\n"); @@ -283,12 +283,14 @@ int AmOfferAnswer::onTxSdp(unsigned int m_cseq, const AmMimeBody& body) case OA_None: case OA_Completed: - setState(OA_OfferSent); + if (!force_no_sdp_update) + setState(OA_OfferSent); cseq = m_cseq; break; case OA_OfferRecved: - setState(OA_Completed); + if (!force_no_sdp_update) + setState(OA_Completed); break; case OA_OfferSent: @@ -336,8 +338,8 @@ int AmOfferAnswer::onRequestOut(AmSipRequest& req) } } - if(has_sdp && (onTxSdp(req.cseq,req.body) != 0)){ - DBG("onTxSdp() failed\n"); + if (has_sdp && (onTxSdp(req.cseq,req.body) != 0)) { + WARN("onTxSdp() failed\n"); return -1; } @@ -347,8 +349,25 @@ int AmOfferAnswer::onRequestOut(AmSipRequest& req) int AmOfferAnswer::onReplyOut(AmSipReply& reply) { AmMimeBody* sdp_body = reply.body.hasContentType(SIP_APPLICATION_SDP); + bool generate_sdp = sdp_body && !sdp_body->getLen(); bool has_sdp = sdp_body && sdp_body->getLen(); + bool force_no_sdp_update = false; /* for sequential 183 responses with similar SDP body (version) */ + + /* check whether 183 has same SDP version it has had before. Then it doesn't change leg's OA state */ + if (has_sdp && !generate_sdp && + reply.cseq_method == SIP_METH_INVITE && reply.code == 183) + { + AmSdp parser_sdp; + if (parser_sdp.parse((const char*)sdp_body->getPayload())) { + WARN("SDP parsing for the coming reply failed (cannot create AmSdp object).\n"); + } else { + force_no_sdp_update = (sdp_local.origin.sessV == parser_sdp.origin.sessV); + if (force_no_sdp_update) + DBG("Forcing no OA state update (no SDP changes, same session version: was <%llu>, now is <%llu>).\n", + sdp_local.origin.sessV, parser_sdp.origin.sessV); + } + } if (!has_sdp && !generate_sdp) { /* let's see whether we should force SDP or not. */ @@ -441,12 +460,12 @@ int AmOfferAnswer::onReplyOut(AmSipReply& reply) } } - if (has_sdp && (onTxSdp(reply.cseq,reply.body) != 0)) { - DBG("onTxSdp() failed\n"); + if (has_sdp && (onTxSdp(reply.cseq, reply.body, force_no_sdp_update) != 0)) { + WARN("onTxSdp() failed\n"); return -1; } - if((reply.code >= 300) && (reply.cseq == cseq)) { + if ((reply.code >= 300) && (reply.cseq == cseq)) { /* final error reply -> cleanup OA state */ DBG("after %u reply to %s: resetting OA state\n", reply.code, reply.cseq_method.c_str()); clearTransitionalState(); diff --git a/core/AmOfferAnswer.h b/core/AmOfferAnswer.h index f1f3abf3..afa6db34 100644 --- a/core/AmOfferAnswer.h +++ b/core/AmOfferAnswer.h @@ -62,7 +62,7 @@ private: /** SDP handling */ int onRxSdp(unsigned int m_cseq, const AmMimeBody& body, const char** err_txt); - int onTxSdp(unsigned int m_cseq, const AmMimeBody& body); + int onTxSdp(unsigned int m_cseq, const AmMimeBody& body, bool force_no_sdp_update = false); int getSdpBody(string& sdp_body); public: