[asterisk-commits] oej: trunk r74024 - in /trunk: apps/ channels/ include/asterisk/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon Jul 9 03:27:38 CDT 2007


Author: oej
Date: Mon Jul  9 03:27:37 2007
New Revision: 74024

URL: http://svn.digium.com/view/asterisk?view=rev&rev=74024
Log:
Implementation of a feature that will disable "missed calls" counters on SIP phones.
If the call is answered by another phone, other phones won't display the call as "missed".
You can also add an option to the dial command so that you can have a "followme"
scenario and not count the calls as "missed" when you cancel the call.

Thanks to Ramon and Frank for feedback on this feature.

Modified:
    trunk/apps/app_dial.c
    trunk/channels/chan_local.c
    trunk/channels/chan_sip.c
    trunk/include/asterisk/channel.h

Modified: trunk/apps/app_dial.c
URL: http://svn.digium.com/view/asterisk/trunk/apps/app_dial.c?view=diff&rev=74024&r1=74023&r2=74024
==============================================================================
--- trunk/apps/app_dial.c (original)
+++ trunk/apps/app_dial.c Mon Jul  9 03:27:37 2007
@@ -99,6 +99,8 @@
 "  Options:\n"
 "    A(x) - Play an announcement to the called party, using 'x' as the file.\n"
 "    C    - Reset the CDR for this call.\n"
+"    c    - If DIAL cancels this call, always set the flag to tell the channel\n"
+"           driver that the call is answered elsewhere.\n"
 "    d    - Allow the calling user to dial a 1 digit extension while waiting for\n"
 "           a call to be answered. Exit to that extension if it exists in the\n"
 "           current context, or the context defined in the EXITCONTEXT variable,\n"
@@ -253,6 +255,7 @@
 	OPT_CALLER_PARK =	(1 << 26),
 	OPT_IGNORE_FORWARDING = (1 << 27),
 	OPT_CALLEE_GOSUB =	(1 << 28),
+	OPT_CANCEL_ELSEWHERE =  (1 << 29),
 };
 
 #define DIAL_STILLGOING			(1 << 30)
@@ -276,6 +279,7 @@
 AST_APP_OPTIONS(dial_exec_options, {
 	AST_APP_OPTION_ARG('A', OPT_ANNOUNCE, OPT_ARG_ANNOUNCE),
 	AST_APP_OPTION('C', OPT_RESETCDR),
+	AST_APP_OPTION('c', OPT_CANCEL_ELSEWHERE),
 	AST_APP_OPTION('d', OPT_DTMF_EXIT),
 	AST_APP_OPTION_ARG('D', OPT_SENDDTMF, OPT_ARG_SENDDTMF),
 	AST_APP_OPTION('f', OPT_FORCECLID),
@@ -315,14 +319,17 @@
 };
 
 
-static void hanguptree(struct chanlist *outgoing, struct ast_channel *exception)
+static void hanguptree(struct chanlist *outgoing, struct ast_channel *exception, int answered_elsewhere)
 {
 	/* Hang up a tree of stuff */
 	struct chanlist *oo;
 	while (outgoing) {
 		/* Hangup any existing lines we have open */
-		if (outgoing->chan && (outgoing->chan != exception))
+		if (outgoing->chan && (outgoing->chan != exception)) {
+			if (answered_elsewhere)
+				ast_set_flag(outgoing->chan, AST_FLAG_ANSWERED_ELSEWHERE);
 			ast_hangup(outgoing->chan);
+		}
 		oo = outgoing;
 		outgoing=outgoing->next;
 		ast_free(oo);
@@ -1314,6 +1321,7 @@
 			goto out;
 		if (opts.flags) {
 			ast_copy_flags(tmp, &opts,
+				       OPT_CANCEL_ELSEWHERE |
 				       OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
 				       OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
 				       OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
@@ -1513,7 +1521,7 @@
 		/* 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(outgoing, peer);
+		hanguptree(outgoing, peer, 1);
 		outgoing = NULL;
 		/* If appropriate, log that we have a destination channel */
 		if (chan->cdr)
@@ -1562,7 +1570,7 @@
 			ast_parseable_goto(peer, opt_args[OPT_ARG_GOTO]);
 			peer->priority++;
 			ast_pbx_start(peer);
-			hanguptree(outgoing, NULL);
+			hanguptree(outgoing, NULL, ast_test_flag(&opts, OPT_CANCEL_ELSEWHERE ? 1 : 0));
 			if (continue_exec)
 				*continue_exec = 1;
 			res = 0;
@@ -1800,7 +1808,7 @@
 		ast_indicate(chan, -1);
 	}
 	ast_channel_early_bridge(chan, NULL);
-	hanguptree(outgoing, NULL);
+	hanguptree(outgoing, NULL, 0);	/* In this case, there's no answer anywhere */
 	pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
 	senddialendevent(chan, pa.status);
 	ast_debug(1, "Exiting with DIALSTATUS=%s.\n", pa.status);

Modified: trunk/channels/chan_local.c
URL: http://svn.digium.com/view/asterisk/trunk/channels/chan_local.c?view=diff&rev=74024&r1=74023&r2=74024
==============================================================================
--- trunk/channels/chan_local.c (original)
+++ trunk/channels/chan_local.c Mon Jul  9 03:27:37 2007
@@ -495,6 +495,8 @@
 		return -1;
 
 	ast_mutex_lock(&p->lock);
+	if (p->chan && ast_test_flag(ast, AST_FLAG_ANSWERED_ELSEWHERE)) 
+		ast_set_flag(p->chan, AST_FLAG_ANSWERED_ELSEWHERE);
 	isoutbound = IS_OUTBOUND(ast, p);
 	if (isoutbound) {
 		const char *status = pbx_builtin_getvar_helper(p->chan, "DIALSTATUS");

Modified: trunk/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/trunk/channels/chan_sip.c?view=diff&rev=74024&r1=74023&r2=74024
==============================================================================
--- trunk/channels/chan_sip.c (original)
+++ trunk/channels/chan_sip.c Mon Jul  9 03:27:37 2007
@@ -752,7 +752,7 @@
 #define SIP_REALTIME		(1 << 11)	/*!< P: Flag for realtime users */
 #define SIP_USECLIENTCODE	(1 << 12)	/*!< DP: Trust X-ClientCode info message */
 #define SIP_OUTGOING		(1 << 13)	/*!< D: Direction of the last transaction in this dialog */
-#define SIP_FREE_BIT		(1 << 14)	/*!< ---- */
+#define SIP_DIALOG_ANSWEREDELSEWHERE	(1 << 14)	/*!< D: This call is cancelled due to answer on another channel */
 #define SIP_DEFER_BYE_ON_TRANSFER	(1 << 15)	/*!< D: Do not hangup at first ast_hangup */
 #define SIP_DTMF		(3 << 16)	/*!< DP: DTMF Support: four settings, uses two bits */
 #define SIP_DTMF_RFC2833	(0 << 16)	/*!< DP: DTMF Support: RTP DTMF - "rfc2833" */
@@ -3674,6 +3674,12 @@
 		ast_debug(1, "Asked to hangup channel that was not connected\n");
 		return 0;
 	}
+	if (ast_test_flag(ast, AST_FLAG_ANSWERED_ELSEWHERE)) {
+		if (option_debug)
+			ast_log(LOG_DEBUG, "This call was answered elsewhere");
+		append_history(p, "Cancel", "Call answered elsewhere");
+		ast_set_flag(&p->flags[0], SIP_DIALOG_ANSWEREDELSEWHERE);
+	}
 
 	if (ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) {
 		if (ast_test_flag(&p->flags[0], SIP_INC_COUNT)) {
@@ -8140,6 +8146,9 @@
 		p->invitestate = INV_CONFIRMED;
 
 	reqprep(&resp, p, sipmethod, seqno, newbranch);
+	if (sipmethod == SIP_CANCEL && ast_test_flag(&p->flags[0], SIP_DIALOG_ANSWEREDELSEWHERE)) 
+		add_header(&resp, "Reason:", "SIP;cause=200;text=\"Call completed elsewhere\"");
+
 	add_header_contentLength(&resp, 0);
 	return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq);
 }

Modified: trunk/include/asterisk/channel.h
URL: http://svn.digium.com/view/asterisk/trunk/include/asterisk/channel.h?view=diff&rev=74024&r1=74023&r2=74024
==============================================================================
--- trunk/include/asterisk/channel.h (original)
+++ trunk/include/asterisk/channel.h Mon Jul  9 03:27:37 2007
@@ -539,6 +539,9 @@
 	/*! This is set to tell the channel not to generate DTMF begin frames, and
 	 *  to instead only generate END frames. */
 	AST_FLAG_END_DTMF_ONLY = (1 << 14),
+	/*! Flag to show channels that this call is hangup due to the fact that the call
+	    was indeed anwered, but in another channel */
+	AST_FLAG_ANSWERED_ELSEWHERE = (1 << 15),
 };
 
 /*! \brief ast_bridge_config flags */




More information about the asterisk-commits mailing list