]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Merged revisions 296001 via svnmerge from
authorRussell Bryant <russell@russellbryant.com>
Wed, 24 Nov 2010 17:13:08 +0000 (17:13 +0000)
committerRussell Bryant <russell@russellbryant.com>
Wed, 24 Nov 2010 17:13:08 +0000 (17:13 +0000)
https://origsvn.digium.com/svn/asterisk/branches/1.6.2

................
  r296001 | russell | 2010-11-24 11:03:16 -0600 (Wed, 24 Nov 2010) | 45 lines

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

  ........
    r296000 | russell | 2010-11-24 10:48:39 -0600 (Wed, 24 Nov 2010) | 38 lines

    Handle failures building translation paths more effectively.

    The problem scenario occurred on a heavily loaded system that was using the
    codec_dahdi module and exceeded the hardware transcoding capacity.  The failure
    mode at that point was not good.  The report came in to us as an Asterisk
    lock-up.  The "core show locks" shows a ton of threads locked up (but no
    obvious deadlock).  Upon deeper investigation, when the system is in this
    state, the CPU was maxed out.  The CPU was being consumed by the Asterisk
    logger spewing messages on every audio frame for calls set up after transcoder
    capacity was reached.

    The purpose of this patch is to make Asterisk handle failures to create a
    translation path in a more graceful manner.  If we can't translate, then the
    call just needs to be dropped, as it's not going to work.  These are the
    changes:

    1) In set_format() of channel.c (which is called by set_read_format() and
    set_write_format()), it was ignoring if ast_translator_build_path() failed and
    returned NULL.  It now pays attention to that case and returns a result
    reflecting failure.  With this change in place, the bridging code will
    immediately detect a failure and end the bridge instead of proceeding to try to
    bridge frames that can't be translated and making channel drivers freak out by
    sending them frames in a format they weren't expecting.

    2) In ast_indicate_data() of channel.c, failure of ast_playtones_start() was
    ignored.  It is now reflected in the return value of the function.  This didn't
    turn out to have any affect on the bug, but seemed like a good change to leave
    in.

    3) In app_dial(), when only sending a call to a single endpoint, it will
    attempt to do some bridging of its own of early audio.  It uses
    make_compatible() when it's going to do this.  However, it ignored failure from
    make compatible.  So, even with the fix from #1, if there was early audio going
    through app_dial, there would still be a period of invalid frames passing
    through.  After detecting failure here, Dial() exits.

    ABE-2658
  ........
................

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

apps/app_dial.c
main/channel.c

index 73dbcca3e0301a059cbac47263052893aa21fb71..50d784b1c8e8880753020a6426ffe8a2abca7870 100644 (file)
@@ -984,7 +984,16 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in,
                        ast_deactivate_generator(in);
                        /* If we are calling a single channel, and not providing ringback or music, */
                        /* then, make them compatible for in-band tone purpose */
-                       ast_channel_make_compatible(outgoing->chan, in);
+                       if (ast_channel_make_compatible(outgoing->chan, in) < 0) {
+                               /* If these channels can not be made compatible, 
+                                * there is no point in continuing.  The bridge
+                                * will just fail if it gets that far.
+                                */
+                               *to = -1;
+                               strcpy(pa->status, "CONGESTION");
+                               ast_cdr_failed(in->cdr);
+                               return NULL;
+                       }
                }
 
                if (!ast_test_flag64(peerflags, OPT_IGNORE_CONNECTEDLINE) && !ast_test_flag64(outgoing, DIAL_CALLERID_ABSENT)) {
index a47aa61c6c61d19670c9f3a4e30d4f2402abd5c8..b0bdede94f3a2a28a5e7ea9ff1272442786f1e2a 100644 (file)
@@ -4381,9 +4381,8 @@ int ast_indicate_data(struct ast_channel *chan, int _condition,
        if (ts) {
                /* We have a tone to play, yay. */
                ast_debug(1, "Driver for channel '%s' does not support indication %d, emulating it\n", chan->name, condition);
-               ast_playtones_start(chan, 0, ts->data, 1);
+               res = ast_playtones_start(chan, 0, ts->data, 1);
                ts = ast_tone_zone_sound_unref(ts);
-               res = 0;
        }
 
        if (res) {
@@ -5001,10 +5000,11 @@ static int set_format(struct ast_channel *chan, format_t fmt, format_t *rawforma
        else
                /* writing */
                *trans = ast_translator_build_path(*rawformat, *format);
+       res = *trans ? 0 : -1;
        ast_channel_unlock(chan);
        ast_debug(1, "Set channel %s to %s format %s\n", chan->name,
                direction ? "write" : "read", ast_getformatname(fmt));
-       return 0;
+       return res;
 }
 
 int ast_set_read_format(struct ast_channel *chan, format_t fmt)