[Asterisk-code-review] app dial: Add the "Q" option to set the cause on unanswered... (asterisk[master])

George Joseph asteriskteam at digium.com
Thu Oct 6 10:12:54 CDT 2016


George Joseph has uploaded a new change for review.

  https://gerrit.asterisk.org/4035

Change subject: app_dial:  Add the "Q" option to set the cause on unanswered channels
......................................................................

app_dial:  Add the "Q" option to set the cause on unanswered channels

The "Q" option will set the cause on the unanswered channels when
another channel answers.  It overrides the default of
ANSWERED_ELSEWHERE.

Change-Id: I71742e0919aaa16784c30a2b2e73fbeed7672e47
---
M CHANGES
M apps/app_dial.c
2 files changed, 42 insertions(+), 5 deletions(-)


  git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/35/4035/1

diff --git a/CHANGES b/CHANGES
index be27987..96fdd13 100644
--- a/CHANGES
+++ b/CHANGES
@@ -103,6 +103,12 @@
     instance, allows a channel to immediately exit the ConfBridge without having
     to wait for a leave announcement to play.
 
+app_dial
+------------------
+ * Added the "Q" option which sets the Q.850/Q.931 cause on unanswered channels
+   when another channel answers the call.  The default of ANSWERED_ELSEWHERE
+   is unchanged.
+
 ------------------------------------------------------------------------------
 --- Functionality changes from Asterisk 13 to Asterisk 14 --------------------
 ------------------------------------------------------------------------------
diff --git a/apps/app_dial.c b/apps/app_dial.c
index 316d38d..92ea47a 100644
--- a/apps/app_dial.c
+++ b/apps/app_dial.c
@@ -375,6 +375,19 @@
 					<para>Enable privacy mode. Use <replaceable>x</replaceable> as the family/key in the AstDB database if
 					it is provided. The current extension is used if a database family/key is not specified.</para>
 				</option>
+				<option name="Q">
+					<argument name="cause" required="true"/>
+					<para>Specify the Q.850/Q.931 <replaceable>cause</replaceable> to send to
+					unanswered channels when another channel answers the call.  Any valid
+					Asterisk <replaceable>cause</replaceable> can be used such as
+						<literal>NO_ANSWER</literal>,
+						<literal>USER_BUSY</literal>,
+						<literal>CALL_REJECTED</literal>,
+						<literal>ANSWERED_ELSEWHERE</literal> (the default if Q isn't specified),
+						or <literal>NONE</literal> to send no cause (0).
+						See the <literal>causes.h</literal> file for the full list of valid causes.
+						</para>
+				</option>
 				<option name="r">
 					<para>Default: Indicate ringing to the calling party, even if the called party isn't actually ringing. Pass no audio to the calling
 					party until the called channel has answered.</para>
@@ -519,6 +532,9 @@
 			</example>
 			<example title="Dial with call length limit">
 			 same => n,Dial(PJSIP/alice,,L(60000:30000:10000))
+			</example>
+			<example title="Dial alice and bob and send NO_ANSWER to bob instead of ANSWERED_ELSEWHRE when alice answers">
+			 same => n,Dial(PJSIP/alice&PJSIP/bob,,Q(NO_ANSWER))
 			</example>
 			<example title="Dial with pre-dial subroutines">
 			[default]
@@ -684,6 +700,7 @@
 #define OPT_PREDIAL_CALLEE   (1LLU << 41)
 #define OPT_PREDIAL_CALLER   (1LLU << 42)
 #define OPT_RING_WITH_EARLY_MEDIA (1LLU << 43)
+#define OPT_HANGUPCAUSE (1LLU << 44)
 
 enum {
 	OPT_ARG_ANNOUNCE = 0,
@@ -705,6 +722,7 @@
 	OPT_ARG_FORCE_CID_PRES,
 	OPT_ARG_PREDIAL_CALLEE,
 	OPT_ARG_PREDIAL_CALLER,
+	OPT_ARG_HANGUPCAUSE,
 	/* note: this entry _MUST_ be the last one in the enum */
 	OPT_ARG_ARRAY_SIZE
 };
@@ -738,6 +756,7 @@
 	AST_APP_OPTION_ARG('O', OPT_OPERMODE, OPT_ARG_OPERMODE),
 	AST_APP_OPTION('p', OPT_SCREENING),
 	AST_APP_OPTION_ARG('P', OPT_PRIVACY, OPT_ARG_PRIVACY),
+	AST_APP_OPTION_ARG('Q', OPT_HANGUPCAUSE, OPT_ARG_HANGUPCAUSE),
 	AST_APP_OPTION_ARG('r', OPT_RINGBACK, OPT_ARG_RINGBACK),
 	AST_APP_OPTION('R', OPT_RING_WITH_EARLY_MEDIA),
 	AST_APP_OPTION_ARG('S', OPT_DURATION_STOP, OPT_ARG_DURATION_STOP),
@@ -796,7 +815,7 @@
 	ast_free(outgoing);
 }
 
-static void hanguptree(struct dial_head *out_chans, struct ast_channel *exception, int answered_elsewhere)
+static void hanguptree(struct dial_head *out_chans, struct ast_channel *exception, int hangupcause)
 {
 	/* Hang up a tree of stuff */
 	struct chanlist *outgoing;
@@ -804,9 +823,9 @@
 	while ((outgoing = AST_LIST_REMOVE_HEAD(out_chans, node))) {
 		/* Hangup any existing lines we have open */
 		if (outgoing->chan && (outgoing->chan != exception)) {
-			if (answered_elsewhere) {
+			if (hangupcause > 0) {
 				/* This is for the channel drivers */
-				ast_channel_hangupcause_set(outgoing->chan, AST_CAUSE_ANSWERED_ELSEWHERE);
+				ast_channel_hangupcause_set(outgoing->chan, hangupcause);
 			}
 			ast_hangup(outgoing->chan);
 		}
@@ -2768,6 +2787,7 @@
 	} else {
 		const char *number;
 		int dial_end_raised = 0;
+		int cause = -1;
 
 		if (ast_test_flag64(&opts, OPT_CALLER_ANSWER))
 			ast_answer(chan);
@@ -2778,7 +2798,16 @@
 		/* Ah ha!  Someone answered within the desired timeframe.  Of course after this
 		   we will always return with -1 so that it is hung up properly after the
 		   conversation.  */
-		hanguptree(&out_chans, peer, 1);
+		if (!ast_strlen_zero(opt_args[OPT_ARG_HANGUPCAUSE])) {
+			if (!strcmp(opt_args[OPT_ARG_HANGUPCAUSE], "NONE")) {
+				cause = 0;
+			} else {
+				cause = ast_str2cause(opt_args[OPT_ARG_HANGUPCAUSE]);
+			}
+		}
+
+		hanguptree(&out_chans, peer, cause >= 0 ? cause : AST_CAUSE_ANSWERED_ELSEWHERE);
+
 		/* If appropriate, log that we have a destination channel and set the answer time */
 		if (ast_channel_name(peer))
 			pbx_builtin_setvar_helper(chan, "DIALEDPEERNAME", ast_channel_name(peer));
@@ -3182,7 +3211,9 @@
 	}
 
 	ast_channel_early_bridge(chan, NULL);
-	hanguptree(&out_chans, NULL, ast_channel_hangupcause(chan)==AST_CAUSE_ANSWERED_ELSEWHERE || ast_test_flag64(&opts, OPT_CANCEL_ELSEWHERE) ? 1 : 0 ); /* forward 'answered elsewhere' if we received it */
+	hanguptree(&out_chans, NULL,
+		ast_channel_hangupcause(chan)==AST_CAUSE_ANSWERED_ELSEWHERE
+		|| ast_test_flag64(&opts, OPT_CANCEL_ELSEWHERE) ? AST_CAUSE_ANSWERED_ELSEWHERE : 0 ); /* forward 'answered elsewhere' if we received it */
 	pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
 	ast_debug(1, "Exiting with DIALSTATUS=%s.\n", pa.status);
 

-- 
To view, visit https://gerrit.asterisk.org/4035
To unsubscribe, visit https://gerrit.asterisk.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I71742e0919aaa16784c30a2b2e73fbeed7672e47
Gerrit-PatchSet: 1
Gerrit-Project: asterisk
Gerrit-Branch: master
Gerrit-Owner: George Joseph <gjoseph at digium.com>



More information about the asterisk-code-review mailing list