From f3d48dd345ab3a6d9faf9625790324219f33830d Mon Sep 17 00:00:00 2001 From: Donat Zenichev Date: Wed, 7 Jun 2023 10:08:00 +0200 Subject: [PATCH] MT#57437 Upstream: support for body content type application/csta+xml Backport from the upstream to add support for body content type application/csta+xml in INVITE and INFO requests/responses. Upstream commit: 6f67d15c3857c1f8ed5b33615b7f5ff0e12d3a92 Change-Id: I085eda4a10e73139bd4dce4d75def82bf6da1e8d --- core/AmOfferAnswer.cpp | 98 +++++++++++++++++++++++++----------------- core/sip/defs.h | 3 +- 2 files changed, 60 insertions(+), 41 deletions(-) diff --git a/core/AmOfferAnswer.cpp b/core/AmOfferAnswer.cpp index 06d36aaf..d34e0806 100644 --- a/core/AmOfferAnswer.cpp +++ b/core/AmOfferAnswer.cpp @@ -126,11 +126,19 @@ int AmOfferAnswer::onRequestIn(const AmSipRequest& req) req.method == SIP_METH_UPDATE || req.method == SIP_METH_ACK || req.method == SIP_METH_PRACK) && - !req.body.empty() ) { - + !req.body.empty() ) + { const AmMimeBody* sdp_body = req.body.hasContentType(SIP_APPLICATION_SDP); - if(sdp_body) + const AmMimeBody * csta_body = req.body.hasContentType(SIP_APPLICATION_CSTA_XML); + + /* if application/sdp present */ + if(sdp_body) { err_code = onRxSdp(req.cseq,*sdp_body,&err_txt); + /* if both application/sdp and application/csta+xml are not present */ + } else if (!csta_body) { + err_code = 400; + err_txt = "unsupported content type"; + } } if(checkStateChange()){ @@ -168,43 +176,42 @@ int AmOfferAnswer::onReplyIn(const AmSipReply& reply) if((reply.cseq_method == SIP_METH_INVITE || reply.cseq_method == SIP_METH_UPDATE || reply.cseq_method == SIP_METH_PRACK) && - !reply.body.empty() ) { - + !reply.body.empty() ) + { const AmMimeBody* sdp_body = reply.body.hasContentType(SIP_APPLICATION_SDP); - if(sdp_body) { + const AmMimeBody* csta_body = reply.body.hasContentType(SIP_APPLICATION_CSTA_XML); - if(((state == OA_Completed) || - (state == OA_OfferRecved)) && - (reply.cseq == cseq)) { - - DBG("ignoring subsequent SDP reply within the same transaction\n"); - DBG("this usually happens when 183 and 200 have SDP\n"); + if (sdp_body || csta_body) { - /* Make sure that session is started when 200 OK is received */ - if (reply.code == 200) dlg->onSdpCompleted(); + if (((state == OA_Completed) || + (state == OA_OfferRecved)) && + (reply.cseq == cseq)) + { + DBG("ignoring subsequent SDP reply within the same transaction\n"); + DBG("this usually happens when 183 and 200 have SDP\n"); - } - else { - saveState(); - err_code = onRxSdp(reply.cseq,reply.body,&err_txt); - checkStateChange(); + /* Make sure that session is started when 200 OK is received */ + if (reply.code == 200) dlg->onSdpCompleted(); + + } else { + saveState(); + err_code = onRxSdp(reply.cseq,reply.body,&err_txt); + checkStateChange(); } } } - 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()); + 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(); } - - if(err_code){ - // TODO: only if initial INVITE (if re-INV, app should decide) - DBG("error %i (%s) with SDP received in %i reply: sending ACK+BYE\n", - err_code,err_txt?err_txt:"none",reply.code); + if (err_code) { + /* TODO: only if initial INVITE (if re-INV, app should decide) */ + DBG("error %i (%s) with SDP received in %i reply: sending ACK+BYE\n", err_code, err_txt ? err_txt : "none", reply.code); dlg->bye(); } @@ -219,14 +226,16 @@ int AmOfferAnswer::onRxSdp(unsigned int m_cseq, const AmMimeBody& body, const ch int err_code = 0; assert(err_txt); - const AmMimeBody *sdp = body.hasContentType("application/sdp"); + /* check if we have a body */ + const AmMimeBody *sdp_body = body.hasContentType(SIP_APPLICATION_SDP); + const AmMimeBody *csta_body = body.hasContentType(SIP_APPLICATION_CSTA_XML); - if (sdp == NULL) { + if (sdp_body == NULL) { err_code = 400; *err_txt = "sdp body part not found"; } - if (sdp_remote.parse((const char*)sdp->getPayload())) { + if (sdp_remote.parse((const char*)body.getPayload())) { err_code = 400; *err_txt = "session description parsing failed"; } @@ -308,13 +317,16 @@ int AmOfferAnswer::onTxSdp(unsigned int m_cseq, const AmMimeBody& body, bool for int AmOfferAnswer::onRequestOut(AmSipRequest& req) { AmMimeBody* sdp_body = req.body.hasContentType(SIP_APPLICATION_SDP); + AmMimeBody* csta_body = req.body.hasContentType(SIP_APPLICATION_CSTA_XML); + bool generate_sdp = sdp_body && !sdp_body->getLen(); bool has_sdp = sdp_body && sdp_body->getLen(); + bool has_csta = csta_body && csta_body->getLen(); - if (!sdp_body && - ((req.method == SIP_METH_PRACK) || - (req.method == SIP_METH_ACK)) - && (state == OA_OfferRecved)) { + if ((!sdp_body && !csta_body) && + ((req.method == SIP_METH_PRACK) || (req.method == SIP_METH_ACK)) && + (state == OA_OfferRecved)) + { generate_sdp = true; sdp_body = req.body.addPart(SIP_APPLICATION_SDP); } @@ -338,7 +350,9 @@ int AmOfferAnswer::onRequestOut(AmSipRequest& req) } } - if (has_sdp && (onTxSdp(req.cseq,req.body) != 0)) { + if ((has_sdp || (has_csta && req.method != SIP_METH_INFO)) && + (onTxSdp(req.cseq,req.body) != 0)) + { WARN("onTxSdp() failed\n"); return -1; } @@ -349,10 +363,12 @@ int AmOfferAnswer::onRequestOut(AmSipRequest& req) int AmOfferAnswer::onReplyOut(AmSipReply& reply) { AmMimeBody* sdp_body = reply.body.hasContentType(SIP_APPLICATION_SDP); + AmMimeBody* csta_body = reply.body.hasContentType(SIP_APPLICATION_CSTA_XML); + bool force_no_sdp_update = false; /* for sequential 183 responses with similar SDP body (version) */ 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) */ + bool has_csta = csta_body && csta_body->getLen(); /* 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 && @@ -369,7 +385,7 @@ int AmOfferAnswer::onReplyOut(AmSipReply& reply) } } - if (!has_sdp && !generate_sdp) { + if (!has_sdp && !has_csta && !generate_sdp) { /* let's see whether we should force SDP or not. */ if (reply.cseq_method == SIP_METH_INVITE) { @@ -460,7 +476,9 @@ int AmOfferAnswer::onReplyOut(AmSipReply& reply) } } - if (has_sdp && (onTxSdp(reply.cseq, reply.body, force_no_sdp_update) != 0)) { + if ((has_sdp || (has_csta && reply.cseq_method != SIP_METH_INFO)) && + (onTxSdp(reply.cseq, reply.body, force_no_sdp_update) != 0)) + { WARN("onTxSdp() failed\n"); return -1; } diff --git a/core/sip/defs.h b/core/sip/defs.h index b4fed09b..07a6fee1 100644 --- a/core/sip/defs.h +++ b/core/sip/defs.h @@ -78,7 +78,8 @@ #define SIP_IS_200_CLASS(code) ((code >= 200) && (code < 300)) -#define SIP_APPLICATION_SDP "application/sdp" +#define SIP_APPLICATION_SDP "application/sdp" +#define SIP_APPLICATION_CSTA_XML "application/csta+xml" #define SIP_REPLY_SERVER_INTERNAL_ERROR "Server Internal Error" #define SIP_REPLY_BAD_EXTENSION "Bad Extension"