MT#56321 call_transfer: add support of 183 in failed transfers

We have to add support for playing an early announce for those
failed trasnfers, which for example reach the timeout.

This means there is a need to do the following:
- send 183 from early announce DSM module
- receive 183 on the B2B leg, which was sending an INVITE to
  the transfer destination
- update the caller with an actual media capabilities,
  so it is able to receive the early announcement

The mechanism behind that is that:
- if Proxy in the other leg, which was used to reach the party
  (to which the transfer has been done),
  requests the force usage of the announcement for the caller
  in the very first leg (with the caller who is on hold now)
- then the DSM functionality adds the 'P-Early-Announce: force' header in 183
  to let sems-b2b in the very first leg know, that there is a need to embed
  the audio from the early media into the media session with the caller.
- hence, caller gets a media re-negotiation
- and the leg with the DSM doesn't get updated, since it's still remains
  in the Early stage of the dialog

All the solution is built around two important things:
- Proxy uses the P-App-Param called ';force_early_announce=1' to show to the
  DSM that it needs a "forcive" early media, which must "override" the MoH
  for the caller, if it's being played.
- Sems-b2b uses the header 'P-Early-Announce' to let the very original leg
  with sems-b2b know, that there is a need to embed early media into
  the already established media session with a caller

Original ticket number: TT#187351

Change-Id: I2cda231e877d9ba91eaa1738322b0981618c1dbf
mr11.2.1
Donat Zenichev 4 years ago
parent cce88b503b
commit d5eaa1c5a2

@ -535,9 +535,34 @@ void CallLeg::b2bInitial2xx(AmSipReply& reply, bool forward)
void CallLeg::onInitialReply(B2BSipReplyEvent *e)
{
if (e->reply.code < 200) b2bInitial1xx(e->reply, e->forward);
else if (e->reply.code < 300) b2bInitial2xx(e->reply, e->forward);
else b2bInitialErr(e->reply, e->forward);
/* 100-199 */
if (e->reply.code < 200) {
string announce = getHeader(e->reply.hdrs, SIP_HDR_P_EARLY_ANNOUNCE);
dlg->setForcedEarlyAnnounce(announce.find("force") != std::string::npos);
/* exceptionally treat 183 with the 'P-Early-Announce: force',
similarly to the 200OK response, this will properly update the caller
with the late SDP capabilities (an early announcement),
which has been put on hold during the transfer
DSM applications using it:
- early_dbprompt (early_announce) */
if (e->reply.code == 183 && !announce.empty() && dlg->getForcedEarlyAnnounce()) {
b2bInitial2xx(e->reply, e->forward);
} else {
b2bInitial1xx(e->reply, e->forward);
}
}
/* 200-299 */
else if (e->reply.code < 300) {
b2bInitial2xx(e->reply, e->forward);
}
/* 300-699 */
else {
b2bInitialErr(e->reply, e->forward);
}
}
void CallLeg::b2bInitialErr(AmSipReply& reply, bool forward)

@ -874,14 +874,18 @@ void AmB2BMedia::updateStreamPair(AudioStreamPair &pair)
TRACE("updating stream in A leg\n");
pair.a.setDtmfSink(b);
if (pair.b.getInput()) pair.a.setRelayStream(NULL); // don't mix relayed RTP into the other's input
else pair.a.setRelayStream(pair.b.getStream());
if (have_a) pair.a.initStream(playout_type, a_leg_local_sdp, a_leg_remote_sdp, pair.media_idx);
TRACE("updating stream in B leg\n");
pair.b.setDtmfSink(a);
if (pair.a.getInput()) pair.b.setRelayStream(NULL); // don't mix relayed RTP into the other's input
else pair.b.setRelayStream(pair.a.getStream());
if (have_b) pair.b.initStream(playout_type, b_leg_local_sdp, b_leg_remote_sdp, pair.media_idx);
TRACE("audio streams updated\n");

@ -65,7 +65,7 @@ AmSipDialog::AmSipDialog(AmSipDialogEventHandler* h)
offeranswer_enabled(true),
early_session_started(false),session_started(false),
pending_invites(0),
sdp_local(), sdp_remote()
sdp_local(), sdp_remote(), force_early_announce(false)
{
}

@ -59,6 +59,9 @@ protected:
// Reliable provisional reply support
Am100rel rel100;
/* dialog variables needed to properly handle 183->200OK faking */
bool force_early_announce;
int onTxReply(const AmSipRequest& req, AmSipReply& reply, int& flags);
int onTxRequest(AmSipRequest& req, int& flags);
@ -99,6 +102,10 @@ protected:
void setOAForceSDP(bool force) { oa.setForceSDP(force); }
bool getOAForceSDP() const { return oa.getForceSDP(); }
/* getter/setter for faked 183 as 200OK responses, TT#187351 */
void setForcedEarlyAnnounce(bool value) { force_early_announce = value; }
bool getForcedEarlyAnnounce() { return force_early_announce; }
const AmSdp& getLocalSdp() { return oa.getLocalSdp(); }
const AmSdp& getRemoteSdp() { return oa.getRemoteSdp(); }

@ -54,6 +54,7 @@
#define SIP_HDR_EVENT "Event"
#define SIP_HDR_SUBSCRIPTION_STATE "Subscription-State"
#define SIP_HDR_REPLACES "Replaces"
#define SIP_HDR_P_EARLY_ANNOUNCE "P-Early-Announce"
#define SIP_HDR_COL(_hdr) _hdr ":"
#define SIP_HDR_COLSP(_hdr) SIP_HDR_COL(_hdr) " "

Loading…
Cancel
Save