]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Merged revisions 216438 via svnmerge from
authorOlle Johansson <oej@edvina.net>
Mon, 7 Sep 2009 10:29:15 +0000 (10:29 +0000)
committerOlle Johansson <oej@edvina.net>
Mon, 7 Sep 2009 10:29:15 +0000 (10:29 +0000)
https://origsvn.digium.com/svn/asterisk/trunk

................
r216438 | oej | 2009-09-04 16:02:34 +0200 (Fre, 04 Sep 2009) | 35 lines

Merged revisions 216430 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
r216430 | oej | 2009-09-04 15:45:48 +0200 (Fre, 04 Sep 2009) | 27 lines

Make apps send PROGRESS control frame for early media and fix too early media issue in SIP

The issue at hand is that some legacy (dying) PBX systems send empty media frames on PRI
links *before* any call progress. The SIP channel receives these frames and by default
signals 183 Session progress and starts sending media. This will cause phones to
play silence and ignore the later 180 ringing message. A bad user experience.

The fix is twofold:
- We discovered that asterisk apps that support early media ("noanswer") did not send
  any PROGRESS frame to indicate early media. Fixed.
- We introduce a setting in chan_sip so that users can disable any relay of media frames
  before the outbound channel actually indicates any sort of call progress.
  In 1.4, 1.6.0 and 1.6.1, this will be disabled for backward compatibility. In later versions
  of Asterisk, this will be enabled. We don't assume that it will change your Asterisk
  phone experience - only for the better.

We encourage third-party application developers to make sure that if they have applications
that wants to send early media, add a PROGRESS control frame transmission to make sure that
all channel drivers actually will start sending early media. This has not been the default
in Asterisk previous to this patch, so if you got inspiration from our code, you need to
update accordingly. Sorry for the trouble and thanks for your support.

This code has been running for a few months in a large scale installation (over 250
servers with PRI and/or BRI links to old PBX systems).
That's no proof that this is an excellent patch, but, well, it's tested :-)

........

................

git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.6.0@216645 65c4cc65-6c06-0410-ace0-fbb531ad65f3

apps/app_disa.c
apps/app_playback.c
channels/chan_sip.c
configs/sip.conf.sample
main/pbx.c

index fb8d86e5d7e6e1db88743eecb4933b2c2128b817..0e4ddb189aa8585e16b000dc7a45c1cb5336839c 100644 (file)
@@ -160,8 +160,12 @@ static int disa_exec(struct ast_channel *chan, void *data)
                        /* answer */
                        ast_answer(chan);
                }
-       } else
+       } else {
                special_noanswer = 1;
+               if (chan->_state != AST_STATE_UP) {
+                       ast_indicate(chan, AST_CONTROL_PROGRESS);
+               }
+       }
 
        ast_debug(1, "Context: %s\n",args.context);
 
index cb30b7a9d1fe16169240c7df6d73c7f9c3234af3..0fad48b32a3142fb5a9ddf5676ff6673b022be37 100644 (file)
@@ -426,9 +426,13 @@ static int playback_exec(struct ast_channel *chan, void *data)
                if (option_skip) {
                        /* At the user's option, skip if the line is not up */
                        goto done;
-               } else if (!option_noanswer)
+               } else if (!option_noanswer) {
                        /* Otherwise answer unless we're supposed to send this while on-hook */
                        res = ast_answer(chan);
+               } else {
+                       ast_indicate(chan, AST_CONTROL_PROGRESS);
+               }
+
        }
        if (!res) {
                char *back = args.filenames;
index 92fb7026e3f468256093f744cd85ac2ab59cd1ae..3af8a3525342c8094836c33f6ea1b6e7fc361580 100644 (file)
@@ -689,6 +689,8 @@ static int pedanticsipchecking;             /*!< Extra checking ?  Default off */
 static int autocreatepeer;             /*!< Auto creation of peers at registration? Default off. */
 static int global_match_auth_username;         /*!< Match auth username if available instead of From: Default off. */
 static int global_relaxdtmf;           /*!< Relax DTMF */
+static int global_prematuremediafilter;        /*!< Enable/disable premature frames in a call (causing 183 early media) */
+static int global_relaxdtmf;                   /*!< Relax DTMF */
 static int global_rtptimeout;          /*!< Time out call if no RTP */
 static int global_rtpholdtimeout;      /*!< Time out call if no RTP during hold */
 static int global_rtpkeepalive;                /*!< Send RTP keepalives */
@@ -5297,9 +5299,11 @@ static int sip_write(struct ast_channel *ast, struct ast_frame *frame)
                                    !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
                                    !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
                                        ast_rtp_new_source(p->rtp);
-                                       p->invitestate = INV_EARLY_MEDIA;
-                                       transmit_provisional_response(p, "183 Session Progress", &p->initreq, TRUE);
-                                       ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT);  
+                                       if (!global_prematuremediafilter) {
+                                               p->invitestate = INV_EARLY_MEDIA;
+                                               transmit_provisional_response(p, "183 Session Progress", &p->initreq, TRUE);
+                                               ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT);
+                                       }
                                } else if (p->t38.state == T38_ENABLED) {
                                        change_t38_state(p, T38_DISABLED);
                                        transmit_reinvite_with_sdp(p, FALSE, FALSE);
@@ -13959,6 +13963,7 @@ static char *sip_show_settings(struct ast_cli_entry *e, int cmd, struct ast_cli_
        ast_cli(a->fd, "  Timer T1:               %d\n", global_t1);
        ast_cli(a->fd, "  Timer T1 minimum:       %d\n", global_t1min);
        ast_cli(a->fd, "  Timer B:                %d\n", global_timer_b);
+       ast_cli(a->fd, "  No premature media:     %s\n", global_prematuremediafilter ? "Yes" : "No");
 
        ast_cli(a->fd, "\nDefault Settings:\n");
        ast_cli(a->fd, "-----------------\n");
@@ -21868,6 +21873,7 @@ static int reload_config(enum channelreloadreason reason)
        snprintf(global_useragent, sizeof(global_useragent), "%s %s", DEFAULT_USERAGENT, ast_get_version());
        snprintf(global_sdpsession, sizeof(global_sdpsession), "%s %s", DEFAULT_SDPSESSION, ast_get_version());
        snprintf(global_sdpowner, sizeof(global_sdpowner), "%s", DEFAULT_SDPOWNER);
+       global_prematuremediafilter = TRUE;
        ast_copy_string(default_notifymime, DEFAULT_NOTIFYMIME, sizeof(default_notifymime));
        ast_copy_string(global_realm, S_OR(ast_config_AST_SYSTEM_NAME, DEFAULT_REALM), sizeof(global_realm));
        ast_copy_string(default_callerid, DEFAULT_CALLERID, sizeof(default_callerid));
@@ -22027,6 +22033,8 @@ static int reload_config(enum channelreloadreason reason)
                        ast_set2_flag(&global_flags[1], i || ast_true(v->value), SIP_PAGE2_RTAUTOCLEAR);
                } else if (!strcasecmp(v->name, "usereqphone")) {
                        ast_set2_flag(&global_flags[0], ast_true(v->value), SIP_USEREQPHONE);   
+               } else if (!strcasecmp(v->name, "prematuremedia")) {
+                       global_prematuremediafilter = ast_true(v->value);
                } else if (!strcasecmp(v->name, "relaxdtmf")) {
                        global_relaxdtmf = ast_true(v->value);
                } else if (!strcasecmp(v->name, "vmexten")) {
index 1bf3c1becfaf8f86c7d4d01ee77591a12a8ca011..a4ad6f391bc4300dd7e25d9e52788c4c1b0bc6b6 100644 (file)
@@ -202,6 +202,13 @@ srvlookup=yes                   ; Enable DNS SRV lookups on outbound calls
 ;relaxdtmf=yes                  ; Relax dtmf handling
 ;trustrpid = no                 ; If Remote-Party-ID should be trusted
 ;sendrpid = yes                 ; If Remote-Party-ID should be sent
+;prematuremedia=no             ; Some ISDN links send empty media frames before 
+                               ; the call is in ringing or progress state. The SIP 
+                               ; channel will then send 183 indicating early media
+                               ; which will be empty - thus users get no ring signal.
+                               ; Setting this to "no" will stop any media before we have
+                               ; call progress. Default is "yes".
+
 ;progressinband=never           ; If we should generate in-band ringing always
                                 ; use 'never' to never use in-band signalling, even in cases
                                 ; where some buggy devices might not render it
index d51dce0a221bff57dcf7bbd5c0d8d5a0eed2dcd9..a817822982ecd3f73a55d3bc7daba5a78eb9ef1b 100644 (file)
@@ -7917,6 +7917,8 @@ static int pbx_builtin_background(struct ast_channel *chan, void *data)
                } else if (!ast_test_flag(&flags, BACKGROUND_NOANSWER)) {
                        res = ast_answer(chan);
                }
+               /* Send progress control frame to start early media */
+               ast_indicate(chan, AST_CONTROL_PROGRESS);
        }
 
        if (!res) {