From 1ce23d4534994fdd8bfb8ad3b9ca1884194097be Mon Sep 17 00:00:00 2001 From: Matthew Jordan <mjordan@digium.com> Date: Thu, 17 Jul 2014 21:04:01 +0000 Subject: [PATCH] chan_sip: Make progressinband=never really mean 'never' progressinband=never in sip.conf is easily defeated if an onward trunk sends a progress indication of its own. This is almost certain to happen if the onward trunk is ISDN or IAX as these technologies send a progress indication even if early media is not required. This progress message is passed to the caller, and causes the "never" option to be rather badly named. This patch changes the behaviour of this setting in the following ways: 1) In sip_write(), do not pass the media unless we have either progressed beyond INV_EARLY_MEDIA, or we are in INV_EARLY_MEDIA state, and early media is both set-up and wanted. This helps resolve double-ringing on some buggy handsets. 2) In sip_indicate(), if we see AST_CONTROL_PROGRESS, but SIP_PROG_INBAND_NEVER is set, send a 180 Ringing instead to avoid implicitly enabling early media. Avoid sending double ring indications. NOTE: the meaning of the SIP_PROGRESS_SENT flag changes slightly in this patch to also encapsulate the fact that a channel has *sent or received* a 183 Progress indication. This makes the updated code in sip_write() much more simple. Review: https://reviewboard.asterisk.org/r/3700 ASTERISK-23972 #close Reported by: Steve Davies patches: inband_never_present_early_media2 uploaded by Steve Davies (License 5012) git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@418868 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- UPGRADE.txt | 7 +++++++ channels/chan_sip.c | 35 +++++++++++++++++++++++++++-------- 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/UPGRADE.txt b/UPGRADE.txt index d25bf55d82..4dab291215 100644 --- a/UPGRADE.txt +++ b/UPGRADE.txt @@ -198,6 +198,13 @@ chan_sip: hash to be specified for the DTLS fingerprint placed in SDP. Supported values are 'sha-1' and 'sha-256' with 'sha-256' being the default. + - The 'progressinband=never' option is now more zealous in the persecution of + progress messages coming from Asterisk. Channels bridged with a SIP channel + that has 'progressinband=never' set will not be able to forward their + progress indications through to the SIP device. chan_sip will now turn such + progress indications into a 180 Ringing (if a 180 has not yet been + transmitted) if 'progressinband=never'. + CLI commands: - "core show settings" now lists the current console verbosity in addition to the root console verbosity. diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 086913b41e..f76963b397 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -7428,8 +7428,11 @@ static int sip_write(struct ast_channel *ast, struct ast_frame *frame) ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); } } - p->lastrtptx = time(NULL); - res = ast_rtp_instance_write(p->rtp, frame); + if (p->invitestate > INV_EARLY_MEDIA || (p->invitestate == INV_EARLY_MEDIA && + ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT))) { + p->lastrtptx = time(NULL); + res = ast_rtp_instance_write(p->rtp, frame); + } } sip_pvt_unlock(p); } @@ -7446,8 +7449,11 @@ static int sip_write(struct ast_channel *ast, struct ast_frame *frame) transmit_provisional_response(p, "183 Session Progress", &p->initreq, TRUE); ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); } - p->lastrtptx = time(NULL); - res = ast_rtp_instance_write(p->vrtp, frame); + if (p->invitestate > INV_EARLY_MEDIA || (p->invitestate == INV_EARLY_MEDIA && + ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT))) { + p->lastrtptx = time(NULL); + res = ast_rtp_instance_write(p->vrtp, frame); + } } sip_pvt_unlock(p); } @@ -7467,8 +7473,11 @@ static int sip_write(struct ast_channel *ast, struct ast_frame *frame) transmit_provisional_response(p, "183 Session Progress", &p->initreq, TRUE); ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); } - p->lastrtptx = time(NULL); - res = ast_rtp_instance_write(p->trtp, frame); + if (p->invitestate > INV_EARLY_MEDIA || (p->invitestate == INV_EARLY_MEDIA && + ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT))) { + p->lastrtptx = time(NULL); + res = ast_rtp_instance_write(p->trtp, frame); + } } } sip_pvt_unlock(p); @@ -7896,8 +7905,14 @@ static int sip_indicate(struct ast_channel *ast, int condition, const void *data !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { p->invitestate = INV_EARLY_MEDIA; - transmit_provisional_response(p, "183 Session Progress", &p->initreq, TRUE); - ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); + /* SIP_PROG_INBAND_NEVER means sending 180 ringing in place of a 183 */ + if (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) != SIP_PROG_INBAND_NEVER) { + transmit_provisional_response(p, "183 Session Progress", &p->initreq, TRUE); + ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); + } else if (ast_channel_state(ast) == AST_STATE_RING && !ast_test_flag(&p->flags[0], SIP_RINGING)) { + transmit_provisional_response(p, "180 Ringing", &p->initreq, 0); + ast_set_flag(&p->flags[0], SIP_RINGING); + } break; } res = -1; @@ -23002,6 +23017,8 @@ static void handle_response_invite(struct sip_pvt *p, int resp, const char *rest if (!req->ignore && p->owner) { /* Queue a progress frame only if we have SDP in 180 or 182 */ ast_queue_control(p->owner, AST_CONTROL_PROGRESS); + /* We have not sent progress, but we have been sent progress so enable early media */ + ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); } ast_rtp_instance_activate(p->rtp); } @@ -23085,6 +23102,8 @@ static void handle_response_invite(struct sip_pvt *p, int resp, const char *rest if (!req->ignore && p->owner) { /* Queue a progress frame */ ast_queue_control(p->owner, AST_CONTROL_PROGRESS); + /* We have not sent progress, but we have been sent progress so enable early media */ + ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); } ast_rtp_instance_activate(p->rtp); } else { -- GitLab