Author: mjordan
Date: Wed Jan 21 07:12:04 2015
New Revision: 430844

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=430844
Log:
apps/app_dial: Don't publish DialEnd twice on unexpected GoSub/Macro values

The Dial application has some interesting options with the mid-call Macro (M)
and GoSub (U) options. If the MACRO_RESULT/GOSUB_RESULT returns specific
values, the Dial application will take some action upon the channels involved
in the dial operation (such as hanging up a particular party, etc.) The Dial
application ensures that a Stasis message is published in the event that
MACRO_RESULT/GOSUB_RESULT returns a value that kills the dial operation, so
that there is a corresponding DialEnd event published in AMI/ARI for the
DialBegin event that preceeded it.

A bug exists where that same DialEnd event will be published on Stasis even if
the value returned in MACRO_RESULT/GOSUB_RESULT is not one that the Dial
application cares about. This causes two DialEnd events to be published - one
with the MACRO_RESULT/GOSUB_RESULT and another with "ANSWERED" - which is all
sorts of wrong.

This patch fixes the bug by ensuring that we only publish a DialEnd message to
Stasis if the Dial application's mid-call Macro/GoSub returns something that
Dial cares about.

Review: https://reviewboard.asterisk.org/r/4336

ASTERISK-24682 #close
Reported by: Matt Jordan
........

Merged revisions 430842 from http://svn.asterisk.org/svn/asterisk/branches/13

Modified:
    trunk/   (props changed)
    trunk/apps/app_dial.c

Propchange: trunk/
------------------------------------------------------------------------------
Binary property 'branch-13-merged' - no diff available.

Modified: trunk/apps/app_dial.c
URL: 
http://svnview.digium.com/svn/asterisk/trunk/apps/app_dial.c?view=diff&rev=430844&r1=430843&r2=430844
==============================================================================
--- trunk/apps/app_dial.c (original)
+++ trunk/apps/app_dial.c Wed Jan 21 07:12:04 2015
@@ -2702,6 +2702,7 @@
                }
        } else {
                const char *number;
+               int dial_end_raised = 0;
 
                if (ast_test_flag64(&opts, OPT_CALLER_ANSWER))
                        ast_answer(chan);
@@ -2840,6 +2841,7 @@
 
                if (ast_test_flag64(&opts, OPT_CALLEE_MACRO) && 
!ast_strlen_zero(opt_args[OPT_ARG_CALLEE_MACRO])) {
                        const char *macro_result_peer;
+                       int macro_res;
 
                        /* Set peer->exten and peer->context so that 
MACRO_EXTEN and MACRO_CONTEXT get set */
                        ast_channel_lock_both(chan, peer);
@@ -2848,11 +2850,11 @@
                        ast_channel_unlock(peer);
                        ast_channel_unlock(chan);
                        
ast_replace_subargument_delimiter(opt_args[OPT_ARG_CALLEE_MACRO]);
-                       res = ast_app_exec_macro(chan, peer, 
opt_args[OPT_ARG_CALLEE_MACRO]);
+                       macro_res = ast_app_exec_macro(chan, peer, 
opt_args[OPT_ARG_CALLEE_MACRO]);
 
                        ast_channel_lock(peer);
 
-                       if (!res && (macro_result_peer = 
pbx_builtin_getvar_helper(peer, "MACRO_RESULT"))) {
+                       if (!macro_res && (macro_result_peer = 
pbx_builtin_getvar_helper(peer, "MACRO_RESULT"))) {
                                char *macro_result = 
ast_strdupa(macro_result_peer);
                                char *macro_transfer_dest;
 
@@ -2861,24 +2863,24 @@
                                if (!strcasecmp(macro_result, "BUSY")) {
                                        ast_copy_string(pa.status, 
macro_result, sizeof(pa.status));
                                        ast_set_flag64(peerflags, OPT_GO_ON);
-                                       res = -1;
+                                       macro_res = -1;
                                } else if (!strcasecmp(macro_result, 
"CONGESTION") || !strcasecmp(macro_result, "CHANUNAVAIL")) {
                                        ast_copy_string(pa.status, 
macro_result, sizeof(pa.status));
                                        ast_set_flag64(peerflags, OPT_GO_ON);
-                                       res = -1;
+                                       macro_res = -1;
                                } else if (!strcasecmp(macro_result, 
"CONTINUE")) {
                                        /* hangup peer and keep chan alive 
assuming the macro has changed
                                           the context / exten / priority or 
perhaps
                                           the next priority in the current 
exten is desired.
                                        */
                                        ast_set_flag64(peerflags, OPT_GO_ON);
-                                       res = -1;
+                                       macro_res = -1;
                                } else if (!strcasecmp(macro_result, "ABORT")) {
                                        /* Hangup both ends unless the caller 
has the g flag */
-                                       res = -1;
+                                       macro_res = -1;
                                } else if (!strncasecmp(macro_result, "GOTO:", 
5)) {
                                        macro_transfer_dest = macro_result + 5;
-                                       res = -1;
+                                       macro_res = -1;
                                        /* perform a transfer to a new 
extension */
                                        if (strchr(macro_transfer_dest, '^')) { 
/* context^exten^priority*/
                                                
ast_replace_subargument_delimiter(macro_transfer_dest);
@@ -2887,17 +2889,21 @@
                                                ast_set_flag64(peerflags, 
OPT_GO_ON);
                                        }
                                }
-                               ast_channel_publish_dial(chan, peer, NULL, 
macro_result);
+                               if (macro_res && !dial_end_raised) {
+                                       ast_channel_publish_dial(chan, peer, 
NULL, macro_result);
+                                       dial_end_raised = 1;
+                               }
                        } else {
                                ast_channel_unlock(peer);
                        }
+                       res = macro_res;
                }
 
                if (ast_test_flag64(&opts, OPT_CALLEE_GOSUB) && 
!ast_strlen_zero(opt_args[OPT_ARG_CALLEE_GOSUB])) {
                        const char *gosub_result_peer;
                        char *gosub_argstart;
                        char *gosub_args = NULL;
-                       int res9 = -1;
+                       int gosub_res = -1;
 
                        
ast_replace_subargument_delimiter(opt_args[OPT_ARG_CALLEE_GOSUB]);
                        gosub_argstart = strchr(opt_args[OPT_ARG_CALLEE_GOSUB], 
',');
@@ -2923,7 +2929,7 @@
                                }
                        }
                        if (gosub_args) {
-                               res9 = ast_app_exec_sub(chan, peer, gosub_args, 
0);
+                               gosub_res = ast_app_exec_sub(chan, peer, 
gosub_args, 0);
                                ast_free(gosub_args);
                        } else {
                                ast_log(LOG_ERROR, "Could not Allocate string 
for Gosub arguments -- Gosub Call Aborted!\n");
@@ -2931,7 +2937,7 @@
 
                        ast_channel_lock_both(chan, peer);
 
-                       if (!res9 && (gosub_result_peer = 
pbx_builtin_getvar_helper(peer, "GOSUB_RESULT"))) {
+                       if (!gosub_res && (gosub_result_peer = 
pbx_builtin_getvar_helper(peer, "GOSUB_RESULT"))) {
                                char *gosub_transfer_dest;
                                char *gosub_result = 
ast_strdupa(gosub_result_peer);
                                const char *gosub_retval = 
pbx_builtin_getvar_helper(peer, "GOSUB_RETVAL");
@@ -2947,21 +2953,21 @@
                                if (!strcasecmp(gosub_result, "BUSY")) {
                                        ast_copy_string(pa.status, 
gosub_result, sizeof(pa.status));
                                        ast_set_flag64(peerflags, OPT_GO_ON);
-                                       res = -1;
+                                       gosub_res = -1;
                                } else if (!strcasecmp(gosub_result, 
"CONGESTION") || !strcasecmp(gosub_result, "CHANUNAVAIL")) {
                                        ast_copy_string(pa.status, 
gosub_result, sizeof(pa.status));
                                        ast_set_flag64(peerflags, OPT_GO_ON);
-                                       res = -1;
+                                       gosub_res = -1;
                                } else if (!strcasecmp(gosub_result, 
"CONTINUE")) {
                                        /* Hangup peer and continue with the 
next extension priority. */
                                        ast_set_flag64(peerflags, OPT_GO_ON);
-                                       res = -1;
+                                       gosub_res = -1;
                                } else if (!strcasecmp(gosub_result, "ABORT")) {
                                        /* Hangup both ends unless the caller 
has the g flag */
-                                       res = -1;
+                                       gosub_res = -1;
                                } else if (!strncasecmp(gosub_result, "GOTO:", 
5)) {
                                        gosub_transfer_dest = gosub_result + 5;
-                                       res = -1;
+                                       gosub_res = -1;
                                        /* perform a transfer to a new 
extension */
                                        if (strchr(gosub_transfer_dest, '^')) { 
/* context^exten^priority*/
                                                
ast_replace_subargument_delimiter(gosub_transfer_dest);
@@ -2970,7 +2976,13 @@
                                                ast_set_flag64(peerflags, 
OPT_GO_ON);
                                        }
                                }
-                               ast_channel_publish_dial(chan, peer, NULL, 
gosub_result);
+                               if (gosub_res) {
+                                       res = gosub_res;
+                                       if (!dial_end_raised) {
+                                               ast_channel_publish_dial(chan, 
peer, NULL, gosub_result);
+                                               dial_end_raised = 1;
+                                       }
+                               }
                        } else {
                                ast_channel_unlock(peer);
                                ast_channel_unlock(chan);
@@ -2982,7 +2994,10 @@
                        /* None of the Dial options changed our status; inform
                         * everyone that this channel answered
                         */
-                       ast_channel_publish_dial(chan, peer, NULL, "ANSWER");
+                       if (!dial_end_raised) {
+                               ast_channel_publish_dial(chan, peer, NULL, 
"ANSWER");
+                               dial_end_raised = 1;
+                       }
 
                        if (!ast_tvzero(calldurationlimit)) {
                                struct timeval whentohangup = 
ast_tvadd(ast_tvnow(), calldurationlimit);


-- 
_____________________________________________________________________
-- Bandwidth and Colocation Provided by http://www.api-digital.com --

svn-commits mailing list
To UNSUBSCRIBE or update options visit:
   http://lists.digium.com/mailman/listinfo/svn-commits

Reply via email to