Merged revisions 318282 via svnmerge from
authorRichard Mudgett <rmudgett@digium.com>
Mon, 9 May 2011 19:09:16 +0000 (19:09 +0000)
committerRichard Mudgett <rmudgett@digium.com>
Mon, 9 May 2011 19:09:16 +0000 (19:09 +0000)
https://origsvn.digium.com/svn/asterisk/branches/1.8

........
  r318282 | rmudgett | 2011-05-09 14:07:01 -0500 (Mon, 09 May 2011) | 24 lines

  Hangup extension executed twice.

  When a user hangs up a call, in certain circumstances, the hangup
  extension can end up being executed twice:

  1) If a call is bridged and the 'h' extension executes the Hangup
  application, then the 'h' extension will be executed twice.

  2) If a call is bridged within a macro (Dial or Queue), it has its own 'h'
  extension, the main context also has an 'h' extension, and the macro 'h'
  extension executes the Hangup application, then both 'h' extensions will
  be executed.

  * Revert originally commited fix for #16106 and just set
  AST_FLAG_BRIDGE_HANGUP_RUN unconditionally in ast_bridge_call().  The
  bridge code just executed an 'h' extension so the main PBX loop does not
  need to execute one as well.

  (issue #16106)
  Reported by: ajohnson

  (issue #16548)
  Reported by: hajekd
........

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

main/features.c

index 37491cc..da5e5df 100644 (file)
@@ -3892,6 +3892,7 @@ before_you_go:
                if (bridge_cdr && ast_opt_end_cdr_before_h_exten) {
                        ast_cdr_end(bridge_cdr);
                }
+
                /* swap the bridge cdr and the chan cdr for a moment, and let the endbridge
                   dialplan code operate on it */
                ast_channel_lock(chan);
@@ -3906,24 +3907,19 @@ before_you_go:
                ast_copy_string(chan->exten, "h", sizeof(chan->exten));
                chan->priority = 1;
                ast_channel_unlock(chan);
+
                while ((spawn_error = ast_spawn_extension(chan, chan->context, chan->exten,
                        chan->priority,
                        S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL),
                        &found, 1)) == 0) {
                        chan->priority++;
                }
-               if (spawn_error
-                       && (!ast_exists_extension(chan, chan->context, chan->exten, chan->priority,
-                               S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))
-                               || ast_check_hangup(chan))) {
-                       /* if the extension doesn't exist or a hangup occurred, this isn't really a spawn error */
-                       spawn_error = 0;
-               }
                if (found && spawn_error) {
                        /* Something bad happened, or a hangup has been requested. */
                        ast_debug(1, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", chan->context, chan->exten, chan->priority, chan->name);
                        ast_verb(2, "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", chan->context, chan->exten, chan->priority, chan->name);
                }
+
                /* swap it back */
                ast_channel_lock(chan);
                ast_copy_string(chan->exten, save_exten, sizeof(chan->exten));
@@ -3935,10 +3931,10 @@ before_you_go:
                                bridge_cdr = NULL;
                        }
                }
-               if (!spawn_error) {
-                       ast_set_flag(chan, AST_FLAG_BRIDGE_HANGUP_RUN);
-               }
+               /* An "h" exten has been run, so indicate that one has been run. */
+               ast_set_flag(chan, AST_FLAG_BRIDGE_HANGUP_RUN);
                ast_channel_unlock(chan);
+
                /* protect the lastapp/lastdata against the effects of the hangup/dialplan code */
                if (bridge_cdr) {
                        ast_copy_string(bridge_cdr->lastapp, savelastapp, sizeof(bridge_cdr->lastapp));