[asterisk-commits] russell: branch russell/ast_channel_ao2 r186561 - in /team/russell/ast_channe...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Sat Apr 4 08:00:59 CDT 2009


Author: russell
Date: Sat Apr  4 08:00:51 2009
New Revision: 186561

URL: http://svn.digium.com/svn-view/asterisk?view=rev&rev=186561
Log:
resolve, reset

Modified:
    team/russell/ast_channel_ao2/   (props changed)
    team/russell/ast_channel_ao2/CHANGES
    team/russell/ast_channel_ao2/apps/app_dial.c
    team/russell/ast_channel_ao2/apps/app_directed_pickup.c
    team/russell/ast_channel_ao2/apps/app_queue.c
    team/russell/ast_channel_ao2/channels/chan_agent.c
    team/russell/ast_channel_ao2/channels/chan_dahdi.c
    team/russell/ast_channel_ao2/channels/chan_h323.c
    team/russell/ast_channel_ao2/channels/chan_iax2.c
    team/russell/ast_channel_ao2/channels/chan_local.c
    team/russell/ast_channel_ao2/channels/chan_mgcp.c
    team/russell/ast_channel_ao2/channels/chan_misdn.c
    team/russell/ast_channel_ao2/channels/chan_phone.c
    team/russell/ast_channel_ao2/channels/chan_sip.c
    team/russell/ast_channel_ao2/channels/chan_skinny.c
    team/russell/ast_channel_ao2/channels/chan_unistim.c
    team/russell/ast_channel_ao2/channels/misdn/chan_misdn_config.h
    team/russell/ast_channel_ao2/channels/misdn/isdn_lib.c
    team/russell/ast_channel_ao2/channels/misdn/isdn_lib.h
    team/russell/ast_channel_ao2/channels/misdn/isdn_lib_intern.h
    team/russell/ast_channel_ao2/channels/misdn/isdn_msg_parser.c
    team/russell/ast_channel_ao2/channels/misdn_config.c
    team/russell/ast_channel_ao2/configs/misdn.conf.sample
    team/russell/ast_channel_ao2/configs/sip.conf.sample
    team/russell/ast_channel_ao2/include/asterisk/callerid.h
    team/russell/ast_channel_ao2/include/asterisk/channel.h
    team/russell/ast_channel_ao2/include/asterisk/frame.h
    team/russell/ast_channel_ao2/include/asterisk/rtp_engine.h   (props changed)
    team/russell/ast_channel_ao2/include/asterisk/stun.h   (props changed)
    team/russell/ast_channel_ao2/main/callerid.c
    team/russell/ast_channel_ao2/main/channel.c
    team/russell/ast_channel_ao2/main/dial.c
    team/russell/ast_channel_ao2/main/features.c
    team/russell/ast_channel_ao2/main/rtp_engine.c   (props changed)
    team/russell/ast_channel_ao2/main/stun.c   (contents, props changed)
    team/russell/ast_channel_ao2/res/res_rtp_asterisk.c   (contents, props changed)

Propchange: team/russell/ast_channel_ao2/
------------------------------------------------------------------------------
    automerge = *

Propchange: team/russell/ast_channel_ao2/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Sat Apr  4 08:00:51 2009
@@ -1,1 +1,1 @@
-/trunk:1-186494
+/trunk:1-186560

Modified: team/russell/ast_channel_ao2/CHANGES
URL: http://svn.digium.com/svn-view/asterisk/team/russell/ast_channel_ao2/CHANGES?view=diff&rev=186561&r1=186560&r2=186561
==============================================================================
--- team/russell/ast_channel_ao2/CHANGES (original)
+++ team/russell/ast_channel_ao2/CHANGES Sat Apr  4 08:00:51 2009
@@ -7,7 +7,6 @@
 === and the other UPGRADE files for older releases.
 ===
 ======================================================================
-
 ------------------------------------------------------------------------------
 --- Functionality changes from Asterisk 1.6.2 to Asterisk 1.6.3  -------------
 ------------------------------------------------------------------------------
@@ -23,9 +22,46 @@
    present, those values are sent immediatly upon receiving a PROGRESS message
    regardless if the call has been answered or not.
 
-Functions
----------
+Dialplan Functions
+------------------
+ * Added new dialplan functions CONNECTEDLINE and REDIRECTING which permits
+   setting various connected line and redirecting party information.
  * The CHANNEL() function now supports the "name" option.
+
+Queue changes
+-------------
+  * A new option, 'I' has been added to both app_queue and app_dial.
+    By setting this option, Asterisk will not update the caller with
+    connected line changes or redirecting party changes when they occur.
+
+mISDN channel driver (chan_misdn) changes
+----------------------------------------
+  * Added display_connected parameter to misdn.conf to put a display string
+    in the CONNECT message containing the connected name and/or number if
+    the presentation setting permits it.
+  * Added display_setup parameter to misdn.conf to put a display string
+    in the SETUP message containing the caller name and/or number if the
+    presentation setting permits it.
+  * Made misdn.conf parameters localdialplan and cpndialplan take a -1 to
+    indicate the dialplan settings are to be obtained from the asterisk
+    channel.
+  * Made misdn.conf parameter callerid accept the "name" <number> format
+    used by the rest of the system.
+  * Made use the nationalprefix and internationalprefix misdn.conf
+    parameters to prefix any received number from the ISDN link if that
+    number has the corresponding Type-Of-Number.
+  * Added the following new parameters: unknownprefix, netspecificprefix,
+    subscriberprefix, and abbreviatedprefix in misdn.conf to prefix any
+    received number from the ISDN link if that number has the corresponding
+    Type-Of-Number.
+
+
+SIP channel driver (chan_sip) changes
+-------------------------------------------
+  * The sendrpid parameter has been expanded to include the options
+    'rpid' and 'pai'. Setting sendrpid to 'rpid' will cause Remote-Party-ID
+    header to be sent (equivalent to setting sendrpid=yes) and setting
+    sendrpid to 'pai' will cause P-Asserted-Identity header to be sent.
 
 Asterisk Manager Interface
 --------------------------

Modified: team/russell/ast_channel_ao2/apps/app_dial.c
URL: http://svn.digium.com/svn-view/asterisk/team/russell/ast_channel_ao2/apps/app_dial.c?view=diff&rev=186561&r1=186560&r2=186561
==============================================================================
--- team/russell/ast_channel_ao2/apps/app_dial.c (original)
+++ team/russell/ast_channel_ao2/apps/app_dial.c Sat Apr  4 08:00:51 2009
@@ -156,6 +156,10 @@
 				</option>
 				<option name="i">
 					<para>Asterisk will ignore any forwarding requests it may receive on this dial attempt.</para>
+				</option>
+				<option name="I">
+					<para>Asterisk will ignore any connected line update requests or redirecting party update
+					requests it may receiveon this dial attempt.</para>
 				</option>
 				<option name="k">
 					<para>Allow the called party to enable parking of the call by sending
@@ -382,7 +386,6 @@
 			This application will report normal termination if the originating channel
 			hangs up, or if the call is bridged and either of the parties in the bridge
 			ends the call.</para>
-
 			<para>If the <variable>OUTBOUND_GROUP</variable> variable is set, all peer channels created by this
 			application will be put into that group (as in Set(GROUP()=...).
 			If the <variable>OUTBOUND_GROUP_ONCE</variable> variable is set, all peer channels created by this
@@ -464,12 +467,13 @@
 	OPT_GO_ON =             (1 << 5),
 	OPT_CALLEE_HANGUP =     (1 << 6),
 	OPT_CALLER_HANGUP =     (1 << 7),
+	OPT_ORIGINAL_CLID =     (1 << 8),
 	OPT_DURATION_LIMIT =    (1 << 9),
 	OPT_MUSICBACK =         (1 << 10),
 	OPT_CALLEE_MACRO =      (1 << 11),
 	OPT_SCREEN_NOINTRO =    (1 << 12),
-	OPT_SCREEN_NOCLID =     (1 << 13),
-	OPT_ORIGINAL_CLID =     (1 << 14),
+	OPT_SCREEN_NOCALLERID = (1 << 13),
+	OPT_IGNORE_CONNECTEDLINE = (1 << 14),
 	OPT_SCREENING =         (1 << 15),
 	OPT_PRIVACY =           (1 << 16),
 	OPT_RINGBACK =          (1 << 17),
@@ -490,9 +494,10 @@
 
 #define DIAL_STILLGOING      (1 << 31)
 #define DIAL_NOFORWARDHTML   ((uint64_t)1 << 32) /* flags are now 64 bits, so keep it up! */
-#define OPT_CANCEL_ELSEWHERE ((uint64_t)1 << 33)
-#define OPT_PEER_H           ((uint64_t)1 << 34)
-#define OPT_CALLEE_GO_ON     ((uint64_t)1 << 35)
+#define DIAL_NOCONNECTEDLINE ((uint64_t)1 << 33)
+#define OPT_CANCEL_ELSEWHERE ((uint64_t)1 << 34)
+#define OPT_PEER_H           ((uint64_t)1 << 35)
+#define OPT_CALLEE_GO_ON     ((uint64_t)1 << 36)
 
 enum {
 	OPT_ARG_ANNOUNCE = 0,
@@ -524,13 +529,14 @@
 	AST_APP_OPTION('h', OPT_CALLEE_HANGUP),
 	AST_APP_OPTION('H', OPT_CALLER_HANGUP),
 	AST_APP_OPTION('i', OPT_IGNORE_FORWARDING),
+	AST_APP_OPTION('I', OPT_IGNORE_CONNECTEDLINE),
 	AST_APP_OPTION('k', OPT_CALLEE_PARK),
 	AST_APP_OPTION('K', OPT_CALLER_PARK),
 	AST_APP_OPTION_ARG('L', OPT_DURATION_LIMIT, OPT_ARG_DURATION_LIMIT),
 	AST_APP_OPTION_ARG('m', OPT_MUSICBACK, OPT_ARG_MUSICBACK),
 	AST_APP_OPTION_ARG('M', OPT_CALLEE_MACRO, OPT_ARG_CALLEE_MACRO),
 	AST_APP_OPTION('n', OPT_SCREEN_NOINTRO),
-	AST_APP_OPTION('N', OPT_SCREEN_NOCLID),
+	AST_APP_OPTION('N', OPT_SCREEN_NOCALLERID),
 	AST_APP_OPTION('o', OPT_ORIGINAL_CLID),
 	AST_APP_OPTION_ARG('O', OPT_OPERMODE, OPT_ARG_OPERMODE),
 	AST_APP_OPTION('p', OPT_SCREENING),
@@ -558,6 +564,7 @@
 	struct chanlist *next;
 	struct ast_channel *chan;
 	uint64_t flags;
+	struct ast_party_connected_line connected;
 };
 
 static int detect_disconnect(struct ast_channel *chan, char code, struct ast_str *featurecode);
@@ -653,7 +660,6 @@
 	}
 	return 0;
 }
-
 
 static const char *get_cid_name(char *name, int namelen, struct ast_channel *chan)
 {
@@ -702,6 +708,8 @@
 	struct ast_channel *original = o->chan;
 	struct ast_channel *c = o->chan; /* the winner */
 	struct ast_channel *in = num->chan; /* the input channel */
+	struct ast_party_redirecting *apr = &o->chan->redirecting;
+	struct ast_party_connected_line *apc = &o->chan->connected;
 	char *stuff;
 	char *tech;
 	int cause;
@@ -742,30 +750,38 @@
 		handle_cause(cause, num);
 		ast_hangup(original);
 	} else {
-		char *new_cid_num, *new_cid_name;
-		struct ast_channel *src;
-
 		if (single) {
 			ast_rtp_instance_early_bridge_make_compatible(c, in);
 		}
+
+		c->cdrflags = in->cdrflags;
+
+		ast_channel_set_redirecting(c, apr);
+		ast_channel_lock(c);
+		while (ast_channel_trylock(in)) {
+			CHANNEL_DEADLOCK_AVOIDANCE(c);
+		}
+		S_REPLACE(c->cid.cid_rdnis, ast_strdup(S_OR(original->cid.cid_rdnis, S_OR(in->macroexten, in->exten))));
+
+		c->cid.cid_tns = in->cid.cid_tns;
+
 		if (ast_test_flag64(o, OPT_FORCECLID)) {
-			new_cid_num = ast_strdup(S_OR(in->macroexten, in->exten));
-			new_cid_name = NULL; /* XXX no name ? */
-			src = c; /* XXX possible bug in previous code, which used 'winner' ? it may have changed */
+			S_REPLACE(c->cid.cid_num, ast_strdupa(S_OR(in->macroexten, in->exten)));
+			S_REPLACE(c->cid.cid_name, NULL);
+			ast_string_field_set(c, accountcode, c->accountcode);
 		} else {
-			new_cid_num = ast_strdup(in->cid.cid_num);
-			new_cid_name = ast_strdup(in->cid.cid_name);
-			src = in;
-		}
-		ast_string_field_set(c, accountcode, src->accountcode);
-		c->cdrflags = src->cdrflags;
-		S_REPLACE(c->cid.cid_num, new_cid_num);
-		S_REPLACE(c->cid.cid_name, new_cid_name);
-
-		if (in->cid.cid_ani) { /* XXX or maybe unconditional ? */
-			S_REPLACE(c->cid.cid_ani, ast_strdup(in->cid.cid_ani));
-		}
-		S_REPLACE(c->cid.cid_rdnis, ast_strdup(S_OR(in->macroexten, in->exten)));
+			ast_party_caller_copy(&c->cid, &in->cid);
+			ast_string_field_set(c, accountcode, in->accountcode);
+		}
+		ast_party_connected_line_copy(&c->connected, apc);
+
+		S_REPLACE(in->cid.cid_rdnis, ast_strdup(c->cid.cid_rdnis));
+		ast_channel_unlock(in);
+		ast_channel_unlock(c);
+		ast_channel_update_redirecting(in, apr);
+
+		ast_clear_flag64(peerflags, OPT_IGNORE_CONNECTEDLINE);
+
 		if (ast_call(c, tmpchan, 0)) {
 			ast_log(LOG_NOTICE, "Failed to dial on local channel for call forward to '%s'\n", tmpchan);
 			ast_clear_flag64(o, DIAL_STILLGOING);
@@ -775,7 +791,6 @@
 			num->nochan++;
 		} else {
 			senddialevent(in, c, stuff);
-			/* After calling, set callerid to extension */
 			if (!ast_test_flag64(peerflags, OPT_ORIGINAL_CLID)) {
 				char cidname[AST_MAX_EXTENSION] = "";
 				ast_set_callerid(c, S_OR(in->macroexten, in->exten), get_cid_name(cidname, sizeof(cidname), in), NULL);
@@ -808,16 +823,28 @@
 	int orig = *to;
 	struct ast_channel *peer = NULL;
 	/* single is set if only one destination is enabled */
-	int single = outgoing && !outgoing->next && !ast_test_flag64(outgoing, OPT_MUSICBACK | OPT_RINGBACK);
+	int single = outgoing && !outgoing->next;
 #ifdef HAVE_EPOLL
 	struct chanlist *epollo;
 #endif
+	struct ast_party_connected_line connected_caller;
 	struct ast_str *featurecode = ast_str_alloca(FEATURE_MAX_LEN + 1);
 	if (single) {
 		/* Turn off hold music, etc */
-		ast_deactivate_generator(in);
+		if (!ast_test_flag64(outgoing, OPT_MUSICBACK | OPT_RINGBACK))
+			ast_deactivate_generator(in);
+
 		/* If we are calling a single channel, make them compatible for in-band tone purpose */
 		ast_channel_make_compatible(outgoing->chan, in);
+
+		if (!ast_test_flag64(peerflags, OPT_IGNORE_CONNECTEDLINE) && !ast_test_flag64(outgoing, DIAL_NOCONNECTEDLINE)) {
+			ast_channel_lock(outgoing->chan);
+			ast_connected_line_copy_from_caller(&connected_caller, &outgoing->chan->cid);
+			ast_channel_unlock(outgoing->chan);
+			connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
+			ast_channel_update_connected_line(in, &connected_caller);
+			ast_party_connected_line_free(&connected_caller);
+		}
 	}
 
 #ifdef HAVE_EPOLL
@@ -864,6 +891,18 @@
 			if (ast_test_flag64(o, DIAL_STILLGOING) && c->_state == AST_STATE_UP) {
 				if (!peer) {
 					ast_verb(3, "%s answered %s\n", c->name, in->name);
+					if (!single && !ast_test_flag64(peerflags, OPT_IGNORE_CONNECTEDLINE)) {
+						if (o->connected.id.number) {
+							ast_channel_update_connected_line(in, &o->connected);
+						} else if (!ast_test_flag64(o, DIAL_NOCONNECTEDLINE)) {
+							ast_channel_lock(c);
+							ast_connected_line_copy_from_caller(&connected_caller, &c->cid);
+							ast_channel_unlock(c);
+							connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
+							ast_channel_update_connected_line(in, &connected_caller);
+							ast_party_connected_line_free(&connected_caller);
+						}
+					}
 					peer = c;
 					ast_copy_flags64(peerflags, o,
 						OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
@@ -902,6 +941,18 @@
 					/* This is our guy if someone answered. */
 					if (!peer) {
 						ast_verb(3, "%s answered %s\n", c->name, in->name);
+						if (!single && !ast_test_flag64(peerflags, OPT_IGNORE_CONNECTEDLINE)) {
+							if (o->connected.id.number) {
+								ast_channel_update_connected_line(in, &o->connected);
+							} else if (!ast_test_flag64(o, DIAL_NOCONNECTEDLINE)) {
+								ast_channel_lock(c);
+								ast_connected_line_copy_from_caller(&connected_caller, &c->cid);
+								ast_channel_unlock(c);
+								connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
+								ast_channel_update_connected_line(in, &connected_caller);
+								ast_party_connected_line_free(&connected_caller);
+							}
+						}
 						peer = c;
 						if (peer->cdr) {
 							peer->cdr->answer = ast_tvnow();
@@ -970,6 +1021,29 @@
 					ast_verb(3, "%s requested a source update, passing it to %s\n", c->name, in->name);
 					ast_indicate(in, AST_CONTROL_SRCUPDATE);
 					break;
+				case AST_CONTROL_CONNECTED_LINE:
+					if (ast_test_flag64(peerflags, OPT_IGNORE_CONNECTEDLINE)) {
+						ast_verb(3, "Connected line update to %s prevented.\n", in->name);
+					} else if (!single) {
+						struct ast_party_connected_line connected;
+						ast_verb(3, "%s connected line has changed. Saving it until answer for %s\n", c->name, in->name);
+						ast_party_connected_line_set_init(&connected, &o->connected);
+						ast_connected_line_parse_data(f->data.ptr, f->datalen, &connected);
+						ast_party_connected_line_set(&o->connected, &connected);
+						ast_party_connected_line_free(&connected);
+					} else {
+						ast_verb(3, "%s connected line has changed, passing it to %s\n", c->name, in->name);
+						ast_indicate_data(in, AST_CONTROL_CONNECTED_LINE, f->data.ptr, f->datalen);
+					}
+					break;
+				case AST_CONTROL_REDIRECTING:
+					if (ast_test_flag64(peerflags, OPT_IGNORE_CONNECTEDLINE)) {
+						ast_verb(3, "Redirecting update to %s prevented.\n", in->name);
+					} else {
+						ast_verb(3, "%s redirecting info has changed, passing it to %s\n", c->name, in->name);
+						ast_indicate_data(in, AST_CONTROL_REDIRECTING, f->data.ptr, f->datalen);
+					}
+					break;
 				case AST_CONTROL_PROCEEDING:
 					ast_verb(3, "%s is proceeding passing it to %s\n", c->name, in->name);
 					if (single && CAN_EARLY_BRIDGE(peerflags, in, c))
@@ -1084,7 +1158,9 @@
 				((f->subclass == AST_CONTROL_HOLD) ||
 				(f->subclass == AST_CONTROL_UNHOLD) ||
 				(f->subclass == AST_CONTROL_VIDUPDATE) ||
-				 (f->subclass == AST_CONTROL_SRCUPDATE))) {
+				(f->subclass == AST_CONTROL_SRCUPDATE) ||
+				(f->subclass == AST_CONTROL_CONNECTED_LINE) ||
+				(f->subclass == AST_CONTROL_REDIRECTING))) {
 				ast_verb(3, "%s requested special control %d, passing it to %s\n", in->name, f->subclass, outgoing->chan->name);
 				ast_indicate_data(outgoing->chan, f->subclass, f->data.ptr, f->datalen);
 			}
@@ -1423,11 +1499,11 @@
 
 	ast_copy_string(pa->privcid, l, sizeof(pa->privcid));
 
-	if (strncmp(pa->privcid, "NOCALLERID", 10) != 0 && ast_test_flag64(opts, OPT_SCREEN_NOCLID)) {
-		/* if callerid is set and OPT_SCREEN_NOCLID is set also */
+	if (strncmp(pa->privcid, "NOCALLERID", 10) != 0 && ast_test_flag64(opts, OPT_SCREEN_NOCALLERID)) {
+		/* if callerid is set and OPT_SCREEN_NOCALLERID is set also */
 		ast_verb(3, "CallerID set (%s); N option set; Screening should be off\n", pa->privcid);
 		pa->privdb_val = AST_PRIVACY_ALLOW;
-	} else if (ast_test_flag64(opts, OPT_SCREEN_NOCLID) && strncmp(pa->privcid, "NOCALLERID", 10) == 0) {
+	} else if (ast_test_flag64(opts, OPT_SCREEN_NOCALLERID) && strncmp(pa->privcid, "NOCALLERID", 10) == 0) {
 		ast_verb(3, "CallerID blank; N option set; Screening should happen; dbval is %d\n", pa->privdb_val);
 	}
 	
@@ -1637,7 +1713,7 @@
 		outbound_group = ast_strdupa(outbound_group);
 	}
 	ast_channel_unlock(chan);	
-	ast_copy_flags64(peerflags, &opts, OPT_DTMF_EXIT | OPT_GO_ON | OPT_ORIGINAL_CLID | OPT_CALLER_HANGUP | OPT_IGNORE_FORWARDING);
+	ast_copy_flags64(peerflags, &opts, OPT_DTMF_EXIT | OPT_GO_ON | OPT_ORIGINAL_CLID | OPT_CALLER_HANGUP | OPT_IGNORE_FORWARDING | OPT_IGNORE_CONNECTEDLINE);
 
 	/* loop through the list of dial destinations */
 	rest = args.peers;
@@ -1674,6 +1750,14 @@
 
 		ast_channel_lock(chan);
 		datastore = ast_channel_datastore_find(chan, &dialed_interface_info, NULL);
+		/* If the incoming channel has previously had connected line information
+		 * set on it (perhaps through the CONNECTED_LINE dialplan function) then
+		 * seed the calllist's connected line information with this previously
+		 * acquired info
+		 */
+		if (chan->connected.id.number) {
+			ast_party_connected_line_copy(&tmp->connected, &chan->connected);
+		}
 		ast_channel_unlock(chan);
 
 		if (datastore)
@@ -1746,6 +1830,10 @@
 		}
 		pbx_builtin_setvar_helper(tc, "DIALEDPEERNUMBER", numsubst);
 
+		ast_channel_lock(tc);
+		while (ast_channel_trylock(chan)) {
+			CHANNEL_DEADLOCK_AVOIDANCE(tc);
+		}
 		/* Setup outgoing SDP to match incoming one */
 		if (!outgoing && !rest) {
 			ast_rtp_instance_early_bridge_make_compatible(tc, chan);
@@ -1759,20 +1847,31 @@
 		tc->data = "(Outgoing Line)";
 		memset(&tc->whentohangup, 0, sizeof(tc->whentohangup));
 
-		S_REPLACE(tc->cid.cid_num, ast_strdup(chan->cid.cid_num));
-		S_REPLACE(tc->cid.cid_name, ast_strdup(chan->cid.cid_name));
-		S_REPLACE(tc->cid.cid_ani, ast_strdup(chan->cid.cid_ani));
+		/* If the new channel has no callerid, try to guess what it should be */
+		if (ast_strlen_zero(tc->cid.cid_num)) {
+			if (!ast_strlen_zero(chan->connected.id.number)) {
+				ast_set_callerid(tc, chan->connected.id.number, chan->connected.id.name, chan->connected.ani);
+			} else if (!ast_strlen_zero(chan->cid.cid_dnid)) {
+				ast_set_callerid(tc, chan->cid.cid_dnid, NULL, NULL);
+			} else if (!ast_strlen_zero(S_OR(chan->macroexten, chan->exten))) {
+				ast_set_callerid(tc, S_OR(chan->macroexten, chan->exten), NULL, NULL);
+			}
+			ast_set_flag64(tmp, DIAL_NOCONNECTEDLINE);
+		}
+		
+		ast_connected_line_copy_from_caller(&tc->connected, &chan->cid);
+
 		S_REPLACE(tc->cid.cid_rdnis, ast_strdup(chan->cid.cid_rdnis));
-		
+		ast_party_redirecting_copy(&tc->redirecting, &chan->redirecting);
+
+		tc->cid.cid_tns = chan->cid.cid_tns;
+
 		ast_string_field_set(tc, accountcode, chan->accountcode);
 		tc->cdrflags = chan->cdrflags;
 		if (ast_strlen_zero(tc->musicclass))
 			ast_string_field_set(tc, musicclass, chan->musicclass);
-		/* Pass callingpres, type of number, tns, ADSI CPE, transfer capability */
-		tc->cid.cid_pres = chan->cid.cid_pres;
-		tc->cid.cid_ton = chan->cid.cid_ton;
-		tc->cid.cid_tns = chan->cid.cid_tns;
-		tc->cid.cid_ani2 = chan->cid.cid_ani2;
+
+		/* Pass ADSI CPE and transfer capability */
 		tc->adsicpe = chan->adsicpe;
 		tc->transfercapability = chan->transfercapability;
 
@@ -1809,6 +1908,8 @@
 			if (tc->hangupcause) {
 				chan->hangupcause = tc->hangupcause;
 			}
+			ast_channel_unlock(chan);
+			ast_channel_unlock(tc);
 			ast_hangup(tc);
 			tc = NULL;
 			ast_free(tmp);
@@ -1816,8 +1917,11 @@
 		} else {
 			senddialevent(chan, tc, numsubst);
 			ast_verb(3, "Called %s\n", numsubst);
-			if (!ast_test_flag64(peerflags, OPT_ORIGINAL_CLID))
+			if (!ast_test_flag64(peerflags, OPT_ORIGINAL_CLID)) {
 				ast_set_callerid(tc, S_OR(chan->macroexten, chan->exten), get_cid_name(cidname, sizeof(cidname), chan), NULL);
+			}
+			ast_channel_unlock(chan);
+			ast_channel_unlock(tc);
 		}
 		/* Put them in the list of outgoing thingies...  We're ready now.
 		   XXX If we're forcibly removed, these outgoing calls won't get

Modified: team/russell/ast_channel_ao2/apps/app_directed_pickup.c
URL: http://svn.digium.com/svn-view/asterisk/team/russell/ast_channel_ao2/apps/app_directed_pickup.c?view=diff&rev=186561&r1=186560&r2=186561
==============================================================================
--- team/russell/ast_channel_ao2/apps/app_directed_pickup.c (original)
+++ team/russell/ast_channel_ao2/apps/app_directed_pickup.c Sat Apr  4 08:00:51 2009
@@ -40,6 +40,7 @@
 #include "asterisk/lock.h"
 #include "asterisk/app.h"
 #include "asterisk/features.h"
+#include "asterisk/callerid.h"
 
 #define PICKUPMARK "PICKUPMARK"
 
@@ -91,8 +92,20 @@
 static int pickup_do(struct ast_channel *chan, struct ast_channel *target)
 {
 	int res = 0;
+	struct ast_party_connected_line connected_caller;
 
 	ast_debug(1, "Call pickup on '%s' by '%s'\n", target->name, chan->name);
+
+	connected_caller = target->connected;
+	connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
+	ast_channel_update_connected_line(chan, &connected_caller);
+
+	ast_channel_lock(chan);
+	ast_connected_line_copy_from_caller(&connected_caller, &chan->cid);
+	ast_channel_unlock(chan);
+	connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
+	ast_channel_queue_connected_line_update(chan, &connected_caller);
+	ast_party_connected_line_free(&connected_caller);
 
 	if ((res = ast_answer(chan))) {
 		ast_log(LOG_WARNING, "Unable to answer '%s'\n", chan->name);

Modified: team/russell/ast_channel_ao2/apps/app_queue.c
URL: http://svn.digium.com/svn-view/asterisk/team/russell/ast_channel_ao2/apps/app_queue.c?view=diff&rev=186561&r1=186560&r2=186561
==============================================================================
--- team/russell/ast_channel_ao2/apps/app_queue.c (original)
+++ team/russell/ast_channel_ao2/apps/app_queue.c Sat Apr  4 08:00:51 2009
@@ -94,6 +94,7 @@
 #include "asterisk/strings.h"
 #include "asterisk/global_datastores.h"
 #include "asterisk/taskprocessor.h"
+#include "asterisk/callerid.h"
 
 /*!
  * \par Please read before modifying this file.
@@ -140,6 +141,10 @@
 					<option name="i">
 						<para>Ignore call forward requests from queue members and do nothing
 						when they are requested.</para>
+					</option>
+					<option name="I">
+						<para>Asterisk will ignore any connected line update requests or any redirecting party
+						update requests it may receive on this dial attempt.</para>
 					</option>
 					<option name="r">
 						<para>Ring instead of playing MOH. Periodic Announcements are still made, if applicable.</para>
@@ -625,6 +630,8 @@
 	time_t lastcall;
 	struct call_queue *lastqueue;
 	struct member *member;
+	unsigned int update_connectedline:1;
+	struct ast_party_connected_line connected;
 };
 
 
@@ -2479,22 +2486,40 @@
 		(*busies)++;
 		return 0;
 	}
-	
+
+	ast_channel_lock(tmp->chan);
+	while (ast_channel_trylock(qe->chan)) {
+		CHANNEL_DEADLOCK_AVOIDANCE(tmp->chan);
+	}
+
 	if (qe->cancel_answered_elsewhere) {
 		ast_set_flag(tmp->chan, AST_FLAG_ANSWERED_ELSEWHERE);
 	}
 	tmp->chan->appl = "AppQueue";
 	tmp->chan->data = "(Outgoing Line)";
 	memset(&tmp->chan->whentohangup, 0, sizeof(tmp->chan->whentohangup));
-	if (tmp->chan->cid.cid_num)
-		ast_free(tmp->chan->cid.cid_num);
-	tmp->chan->cid.cid_num = ast_strdup(qe->chan->cid.cid_num);
-	if (tmp->chan->cid.cid_name)
-		ast_free(tmp->chan->cid.cid_name);
-	tmp->chan->cid.cid_name = ast_strdup(qe->chan->cid.cid_name);
-	if (tmp->chan->cid.cid_ani)
-		ast_free(tmp->chan->cid.cid_ani);
-	tmp->chan->cid.cid_ani = ast_strdup(qe->chan->cid.cid_ani);
+
+	/* If the new channel has no callerid, try to guess what it should be */
+	if (ast_strlen_zero(tmp->chan->cid.cid_num)) {
+		if (!ast_strlen_zero(qe->chan->connected.id.number)) {
+			ast_set_callerid(tmp->chan, qe->chan->connected.id.number, qe->chan->connected.id.name, qe->chan->connected.ani);
+			tmp->chan->cid.cid_pres = qe->chan->connected.id.number_presentation;
+		} else if (!ast_strlen_zero(qe->chan->cid.cid_dnid)) {
+			ast_set_callerid(tmp->chan, qe->chan->cid.cid_dnid, NULL, NULL);
+		} else if (!ast_strlen_zero(S_OR(qe->chan->macroexten, qe->chan->exten))) {
+			ast_set_callerid(tmp->chan, S_OR(qe->chan->macroexten, qe->chan->exten), NULL, NULL); 
+		}
+		tmp->update_connectedline = 0;
+	}
+
+	if (tmp->chan->cid.cid_rdnis)
+		ast_free(tmp->chan->cid.cid_rdnis);
+	tmp->chan->cid.cid_rdnis = ast_strdup(qe->chan->cid.cid_rdnis);
+	ast_party_redirecting_copy(&tmp->chan->redirecting, &qe->chan->redirecting);
+
+	tmp->chan->cid.cid_tns = qe->chan->cid.cid_tns;
+
+	ast_connected_line_copy_from_caller(&tmp->chan->connected, &qe->chan->cid);
 
 	/* Inherit specially named variables from parent channel */
 	ast_channel_inherit_variables(qe->chan, tmp->chan);
@@ -2503,7 +2528,6 @@
 	tmp->chan->adsicpe = qe->chan->adsicpe;
 
 	/* Inherit context and extension */
-	ast_channel_lock(qe->chan);
 	macrocontext = pbx_builtin_getvar_helper(qe->chan, "MACRO_CONTEXT");
 	ast_string_field_set(tmp->chan, dialcontext, ast_strlen_zero(macrocontext) ? qe->chan->context : macrocontext);
 	macroexten = pbx_builtin_getvar_helper(qe->chan, "MACRO_EXTEN");
@@ -2511,13 +2535,14 @@
 		ast_copy_string(tmp->chan->exten, macroexten, sizeof(tmp->chan->exten));
 	else
 		ast_copy_string(tmp->chan->exten, qe->chan->exten, sizeof(tmp->chan->exten));
-	ast_channel_unlock(qe->chan);
 
 	/* Place the call, but don't wait on the answer */
 	if ((res = ast_call(tmp->chan, location, 0))) {
 		/* Again, keep going even if there's an error */
 		ast_debug(1, "ast call on peer returned %d\n", res);
 		ast_verb(3, "Couldn't call %s\n", tmp->interface);
+		ast_channel_unlock(tmp->chan);
+		ast_channel_unlock(qe->chan);
 		do_hang(tmp);
 		(*busies)++;
 		update_status(qe->parent, tmp->member, ast_device_state(tmp->member->state_interface));
@@ -2545,6 +2570,8 @@
 					qe->parent->eventwhencalled == QUEUE_EVENT_VARIABLES ? vars2manager(qe->chan, vars, sizeof(vars)) : "");
 		ast_verb(3, "Called %s\n", tmp->interface);
 	}
+	ast_channel_unlock(tmp->chan);
+	ast_channel_unlock(qe->chan);
 
 	update_status(qe->parent, tmp->member, ast_device_state(tmp->member->state_interface));
 	return 1;
@@ -2775,7 +2802,7 @@
  * \param[in] caller_disconnect if the 'H' option is used when calling Queue(), this is used to detect if the caller pressed * to disconnect the call
  * \param[in] forwardsallowed used to detect if we should allow call forwarding, based on the 'i' option to Queue()
  */
-static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callattempt *outgoing, int *to, char *digit, int prebusies, int caller_disconnect, int forwardsallowed)
+static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callattempt *outgoing, int *to, char *digit, int prebusies, int caller_disconnect, int forwardsallowed, int update_connectedline)
 {
 	const char *queue = qe->parent->name;
 	struct callattempt *o, *start = NULL, *prev = NULL;
@@ -2795,6 +2822,12 @@
 #ifdef HAVE_EPOLL
 	struct callattempt *epollo;
 #endif
+	struct ast_party_connected_line connected_caller;
+	char *inchan_name;
+
+	ast_channel_lock(qe->chan);
+	inchan_name = ast_strdupa(qe->chan->name);
+	ast_channel_unlock(qe->chan);
 
 	starttime = (long) time(NULL);
 #ifdef HAVE_EPOLL
@@ -2845,9 +2878,28 @@
 		}
 		winner = ast_waitfor_n(watchers, pos, to);
 		for (o = start; o; o = o->call_next) {
+			/* We go with a static buffer here instead of using ast_strdupa. Using
+			 * ast_strdupa in a loop like this one can cause a stack overflow
+			 */
+			char ochan_name[AST_CHANNEL_NAME];
+			ast_channel_lock(o->chan);
+			ast_copy_string(ochan_name, o->chan->name, sizeof(ochan_name));
+			ast_channel_unlock(o->chan);
 			if (o->stillgoing && (o->chan) &&  (o->chan->_state == AST_STATE_UP)) {
 				if (!peer) {
-					ast_verb(3, "%s answered %s\n", o->chan->name, in->name);
+					ast_verb(3, "%s answered %s\n", ochan_name, inchan_name);
+					if (update_connectedline) {
+						if (o->connected.id.number) {
+							ast_channel_update_connected_line(in, &o->connected);
+						} else if (o->update_connectedline) {
+							ast_channel_lock(o->chan);
+							ast_connected_line_copy_from_caller(&connected_caller, &o->chan->cid);
+							ast_channel_unlock(o->chan);
+							connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
+							ast_channel_update_connected_line(in, &connected_caller);
+							ast_party_connected_line_free(&connected_caller);
+						}
+					}
 					peer = o;
 				}
 			} else if (o->chan && (o->chan == winner)) {
@@ -2856,12 +2908,15 @@
 				ast_copy_string(membername, o->member->membername, sizeof(membername));
 
 				if (!ast_strlen_zero(o->chan->call_forward) && !forwardsallowed) {
-					ast_verb(3, "Forwarding %s to '%s' prevented.\n", in->name, o->chan->call_forward);
+					ast_verb(3, "Forwarding %s to '%s' prevented.\n", inchan_name, o->chan->call_forward);
 					numnochan++;
 					do_hang(o);
 					winner = NULL;
 					continue;
 				} else if (!ast_strlen_zero(o->chan->call_forward)) {
+					struct ast_party_redirecting *apr = &o->chan->redirecting;
+					struct ast_party_connected_line *apc = &o->chan->connected;
+					struct ast_channel *original = o->chan;
 					char tmpchan[256];
 					char *stuff;
 					char *tech;
@@ -2876,7 +2931,7 @@
 						tech = "Local";
 					}
 					/* Before processing channel, go ahead and check for forwarding */
-					ast_verb(3, "Now forwarding %s to '%s/%s' (thanks to %s)\n", in->name, tech, stuff, o->chan->name);
+					ast_verb(3, "Now forwarding %s to '%s/%s' (thanks to %s)\n", inchan_name, tech, stuff, ochan_name);
 					/* Setup parameters */
 					o->chan = ast_request(tech, in->nativeformats, stuff, &status);
 					if (!o->chan) {
@@ -2884,32 +2939,42 @@
 						o->stillgoing = 0;
 						numnochan++;
 					} else {
+						ast_channel_lock(o->chan);
+						while (ast_channel_trylock(in)) {
+							CHANNEL_DEADLOCK_AVOIDANCE(o->chan);
+						}
 						ast_channel_inherit_variables(in, o->chan);
 						ast_channel_datastore_inherit(in, o->chan);
-						if (o->chan->cid.cid_num)
-							ast_free(o->chan->cid.cid_num);
-						o->chan->cid.cid_num = ast_strdup(in->cid.cid_num);
-
-						if (o->chan->cid.cid_name)
-							ast_free(o->chan->cid.cid_name);
-						o->chan->cid.cid_name = ast_strdup(in->cid.cid_name);
 
 						ast_string_field_set(o->chan, accountcode, in->accountcode);
 						o->chan->cdrflags = in->cdrflags;
 
-						if (in->cid.cid_ani) {
-							if (o->chan->cid.cid_ani)
-								ast_free(o->chan->cid.cid_ani);
-							o->chan->cid.cid_ani = ast_strdup(in->cid.cid_ani);
-						}
+						ast_channel_set_redirecting(o->chan, apr);
+
 						if (o->chan->cid.cid_rdnis)
 							ast_free(o->chan->cid.cid_rdnis);
-						o->chan->cid.cid_rdnis = ast_strdup(S_OR(in->macroexten, in->exten));
+						o->chan->cid.cid_rdnis = ast_strdup(S_OR(original->cid.cid_rdnis,S_OR(in->macroexten, in->exten)));
+
+						o->chan->cid.cid_tns = in->cid.cid_tns;
+
+						ast_party_caller_copy(&o->chan->cid, &in->cid);
+						ast_party_connected_line_copy(&o->chan->connected, apc);
+
+						ast_channel_update_redirecting(in, apr);
+						if (in->cid.cid_rdnis) {
+							ast_free(in->cid.cid_rdnis);
+						}
+						in->cid.cid_rdnis = ast_strdup(o->chan->cid.cid_rdnis);
+
+						update_connectedline = 1;
+
 						if (ast_call(o->chan, tmpchan, 0)) {
 							ast_log(LOG_NOTICE, "Failed to dial on local channel for call forward to '%s'\n", tmpchan);
 							do_hang(o);
 							numnochan++;
 						}
+						ast_channel_unlock(in);
+						ast_channel_unlock(o->chan);
 					}
 					/* Hangup the original channel now, in case we needed it */
 					ast_hangup(winner);
@@ -2922,12 +2987,24 @@
 						case AST_CONTROL_ANSWER:
 							/* This is our guy if someone answered. */
 							if (!peer) {
-								ast_verb(3, "%s answered %s\n", o->chan->name, in->name);
+								ast_verb(3, "%s answered %s\n", ochan_name, inchan_name);
+								if (update_connectedline) {
+									if (o->connected.id.number) {
+										ast_channel_update_connected_line(in, &o->connected);
+									} else if (o->update_connectedline) {
+										ast_channel_lock(o->chan);
+										ast_connected_line_copy_from_caller(&connected_caller, &o->chan->cid);
+										ast_channel_unlock(o->chan);
+										connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
+										ast_channel_update_connected_line(in, &connected_caller);
+										ast_party_connected_line_free(&connected_caller);
+									}
+								}
 								peer = o;
 							}
 							break;
 						case AST_CONTROL_BUSY:
-							ast_verb(3, "%s is busy\n", o->chan->name);
+							ast_verb(3, "%s is busy\n", ochan_name);
 							if (in->cdr)
 								ast_cdr_busy(in->cdr);
 							do_hang(o);
@@ -2942,7 +3019,7 @@
 							numbusies++;
 							break;
 						case AST_CONTROL_CONGESTION:
-							ast_verb(3, "%s is circuit-busy\n", o->chan->name);
+							ast_verb(3, "%s is circuit-busy\n", ochan_name);
 							if (in->cdr)
 								ast_cdr_busy(in->cdr);
 							endtime = (long) time(NULL);
@@ -2957,13 +3034,37 @@
 							numbusies++;
 							break;
 						case AST_CONTROL_RINGING:
-							ast_verb(3, "%s is ringing\n", o->chan->name);
+							ast_verb(3, "%s is ringing\n", ochan_name);
 							break;
 						case AST_CONTROL_OFFHOOK:
 							/* Ignore going off hook */
 							break;
+						case AST_CONTROL_CONNECTED_LINE:
+							if (!update_connectedline) {
+								ast_verb(3, "Connected line update to %s prevented.\n", inchan_name);
+							} else if (qe->parent->strategy == QUEUE_STRATEGY_RINGALL) {
+								struct ast_party_connected_line connected;
+								ast_verb(3, "%s connected line has changed. Saving it until answer for %s\n", ochan_name, inchan_name);
+								ast_party_connected_line_set_init(&connected, &o->connected);
+								ast_connected_line_parse_data(f->data.ptr, f->datalen, &connected);
+								ast_party_connected_line_set(&o->connected, &connected);
+								ast_party_connected_line_free(&connected);
+							} else {
+								ast_verb(3, "%s connected line has changed, passing it to %s\n", ochan_name, inchan_name);
+								ast_indicate_data(in, AST_CONTROL_CONNECTED_LINE, f->data.ptr, f->datalen);
+							}
+							break;
+						case AST_CONTROL_REDIRECTING:
+							if (!update_connectedline) {
+								ast_verb(3, "Redirecting update to %s prevented\n", inchan_name);
+							} else {
+								ast_verb(3, "%s redirecting info has changed, passing it to %s\n", ochan_name, inchan_name);
+								ast_indicate_data(in, AST_CONTROL_REDIRECTING, f->data.ptr, f->datalen);
+							}
+							break;
 						default:
 							ast_debug(1, "Dunno what to do with control type %d\n", f->subclass);
+							break;
 						}
 					}
 					ast_frfree(f);
@@ -3517,6 +3618,7 @@
 	char *p;
 	char vars[2048];
 	int forwardsallowed = 1;
+	int update_connectedline = 1;
 	int callcompletedinsl;
 	struct ao2_iterator memi;
 	struct ast_datastore *datastore, *transfer_ds;
@@ -3582,6 +3684,9 @@
 		case 'i':
 			forwardsallowed = 0;
 			break;
+		case 'I':
+			update_connectedline = 0;
+			break;
 		case 'x':
 			ast_set_flag(&(bridge_config.features_callee), AST_FEATURE_AUTOMIXMON);
 			break;
@@ -3591,7 +3696,6 @@
 		case 'C':
 			qe->cancel_answered_elsewhere = 1;
 			break;
-
 		}
 
 	/* if the calling channel has the ANSWERED_ELSEWHERE flag set, make sure this is inherited. 
@@ -3661,6 +3765,17 @@
 			}
 		}
 		AST_LIST_UNLOCK(dialed_interfaces);
+
+		ast_channel_lock(qe->chan);
+		/* If any pre-existing connected line information exists on this
+		 * channel, like from the CONNECTED_LINE dialplan function, use this
+		 * to seed the connected line information. It may, of course, be updated
+		 * during the call
+		 */
+		if (qe->chan->connected.id.number) {
+			ast_party_connected_line_copy(&tmp->connected, &qe->chan->connected);
+		}
+		ast_channel_unlock(qe->chan);
 		
 		if (di) {
 			free(tmp);
@@ -3692,6 +3807,7 @@
 		tmp->oldstatus = cur->status;
 		tmp->lastcall = cur->lastcall;
 		tmp->lastqueue = cur->lastqueue;
+		tmp->update_connectedline = 1;
 		ast_copy_string(tmp->interface, cur->interface, sizeof(tmp->interface));
 		/* Special case: If we ring everyone, go ahead and ring them, otherwise
 		   just calculate their metric for the appropriate strategy */
@@ -3732,7 +3848,7 @@
 	ring_one(qe, outgoing, &numbusies);
 	if (use_weight)
 		ao2_unlock(queues);
-	lpeer = wait_for_answer(qe, outgoing, &to, &digit, numbusies, ast_test_flag(&(bridge_config.features_caller), AST_FEATURE_DISCONNECT), forwardsallowed);
+	lpeer = wait_for_answer(qe, outgoing, &to, &digit, numbusies, ast_test_flag(&(bridge_config.features_caller), AST_FEATURE_DISCONNECT), forwardsallowed, update_connectedline);
 	/* The ast_channel_datastore_remove() function could fail here if the
 	 * datastore was moved to another channel during a masquerade. If this is
 	 * the case, don't free the datastore here because later, when the channel

Modified: team/russell/ast_channel_ao2/channels/chan_agent.c
URL: http://svn.digium.com/svn-view/asterisk/team/russell/ast_channel_ao2/channels/chan_agent.c?view=diff&rev=186561&r1=186560&r2=186561
==============================================================================
--- team/russell/ast_channel_ao2/channels/chan_agent.c (original)
+++ team/russell/ast_channel_ao2/channels/chan_agent.c Sat Apr  4 08:00:51 2009
@@ -758,8 +758,7 @@
 		time(&p->start);
 		/* Call on this agent */
 		ast_verb(3, "outgoing agentcall, to agent '%s', on '%s'\n", p->agent, p->chan->name);
-		ast_set_callerid(p->chan,
-			ast->cid.cid_num, ast->cid.cid_name, NULL);
+		ast_channel_set_connected_line(p->chan, &ast->connected);
 		ast_channel_inherit_variables(ast, p->chan);
 		res = ast_call(p->chan, p->loginchan, 0);
 		CLEANUP(ast,p);

Modified: team/russell/ast_channel_ao2/channels/chan_dahdi.c
URL: http://svn.digium.com/svn-view/asterisk/team/russell/ast_channel_ao2/channels/chan_dahdi.c?view=diff&rev=186561&r1=186560&r2=186561
==============================================================================
--- team/russell/ast_channel_ao2/channels/chan_dahdi.c (original)

[... 10746 lines stripped ...]



More information about the asterisk-commits mailing list