From 08e3ad9daf7482646d7f0c0166f167d79ccb141b Mon Sep 17 00:00:00 2001 From: Donat Zenichev Date: Thu, 27 Jun 2024 12:00:27 +0200 Subject: [PATCH] MT#59446 Do not pend call leg update for pick up case Do not take into account `send_491_on_pending_session_leg` when processing pending updates for call-pick call scenario. This is required to let the A side (so caller) be updated, which in a cascading manner later triggers 200OK sending towards the call pick-up'er, and further media updates via re-invite. `send_491_on_pending_session_leg` is used to prevent overlapping updates towards the same other leg. In this situation however, two updates towards the caller is a proper way to finish the call-pickup, so the media update. A new header for interaction between SBC<->B2B introduced: `P-Force-491`, which takes either of values '1' or '0'. If set to '0' the `send_491_on_pending_session_leg` will always be ignored by SBC, and hence re-invite will reach the target, regardless if there has been anyone shortly before. Change-Id: Iee7d2c6ef38e568e7c57a89358b22be0b1cb0438 --- apps/sbc/CallLeg.cpp | 26 +++++++++++++++++++------- core/sip/defs.h | 1 + 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/apps/sbc/CallLeg.cpp b/apps/sbc/CallLeg.cpp index 6d49f2bc..e468ced3 100644 --- a/apps/sbc/CallLeg.cpp +++ b/apps/sbc/CallLeg.cpp @@ -461,7 +461,13 @@ void CallLeg::onB2BEvent(B2BEvent* ev) if (req_ev && req_ev->forward) { /* in case of already ongoing negotiation in the other leg */ if (req_ev->req.method == SIP_METH_INVITE && dlg->getUACInvTransPending()) { - if (AmConfig::send_491_on_pending_session_leg) { + /* if P-Force-491 is present, then it always marks a skip of 491 usage + * for overlapping invite transactions (for the same other leg). + * It's in use by the pick-up functionality, where two competing transactions + * are sent towards caller to update his media capabilities */ + string p_force_491 = getHeader(req_ev->req.hdrs, SIP_HDR_P_FORCE_491, true); + + if (AmConfig::send_491_on_pending_session_leg && p_force_491 != "0") { /** do not send right away one more re-INVITE towards it, * just delay the current leg, which sent us re-INVITE, with with a 491 response. */ @@ -819,14 +825,16 @@ void CallLeg::onB2BReconnect(ReconnectLegEvent* ev) clearRtpReceiverRelay(); relayed_req.clear(); - // the Re-INVITE to be used - SessionUpdate *u = - new Reinvite(ev->hdrs, ev->body, /* establishing = */ true, ev->relayed_invite, ev->r_cseq); - // check if we aren't processing INVITE now (BLF ringing call pickup) AmSipRequest *invite = dlg->getUASPendingInv(); bool is_pending_call = (NULL != invite); if (is_pending_call) { + // the Re-INVITE to be used + string hdrs = ev->hdrs; + if (ev->relayed_invite) + hdrs += SIP_HDR_COLSP(SIP_HDR_P_FORCE_491) "0" CRLF; + SessionUpdate *u = new Reinvite(hdrs, ev->body, true, ev->relayed_invite, ev->r_cseq); + TRACE("INVITE pending - planning session update with SDP from INVITE+replaces for later for ltag %s", getLocalTag().c_str()); pending_updates.push_back(u); @@ -864,8 +872,12 @@ void CallLeg::onB2BReconnect(ReconnectLegEvent* ev) "to", dlg->getRemoteParty().c_str(), "ruri", dlg->getRemoteUri().c_str()); - updateSession(new Reinvite(ev->hdrs, ev->body, - /* establishing = */ true, ev->relayed_invite, ev->r_cseq)); + if (!is_pending_call) { + TRACE("updating session with SDP from INVITE+replaces for ltag %s", getLocalTag().c_str()); + // the Re-INVITE to be used + SessionUpdate *u = new Reinvite(ev->hdrs, ev->body, true, ev->relayed_invite, ev->r_cseq); + updateSession(u); + } } void CallLeg::onB2BReplace(ReplaceLegEvent *e) diff --git a/core/sip/defs.h b/core/sip/defs.h index 085aae6c..670b9c22 100644 --- a/core/sip/defs.h +++ b/core/sip/defs.h @@ -56,6 +56,7 @@ #define SIP_HDR_SUBSCRIPTION_STATE "Subscription-State" #define SIP_HDR_REPLACES "Replaces" #define SIP_HDR_P_DSM_APP "P-DSM-App" +#define SIP_HDR_P_FORCE_491 "P-Force-491" #define DSM_PARAM_EARLY_AN "early-announce" #define DSM_PARAM_PLAYBACK "playback"