[svn-commits] rmudgett: trunk r371120 - in /trunk: channels/ funcs/ include/asterisk/ main/

SVN commits to the Digium repositories svn-commits at lists.digium.com
Fri Aug 10 14:55:10 CDT 2012


Author: rmudgett
Date: Fri Aug 10 14:54:55 2012
New Revision: 371120

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=371120
Log:
Add private representation of caller, connected and redirecting party ids.

This patch adds the feature "Private representation of caller, connected
and redirecting party ids", as previously discussed with us (DATUS) and
Digium.

1. Feature motivation

Until now it is quite difficult to modify a party number or name which can
only be seen by exactly one particular instantiated technology channel
subscriber.  One example where a modified party number or name on one
channel is spread over several channels are supplementary services like
call transfer or pickup.  To implement these features Asterisk internally
copies caller and connected ids from one channel to another.  Another
example are extension subscriptions.  The monitoring entities (watchers)
are notified of state changes and - if desired - of party numbers or names
which represent the involving call parties.  One major feature where a
private representation of party names is essentially needed, i.e.  where a
party name shall be exclusively signaled to only one particular user, is a
private user-specific name resolution for party numbers.  A lookup in a
private destination-dependent telephone book shall provide party names
which cannot be seen by any other user at any time.

2. Feature Description

This feature comes along with the implementation of additional private
party id elements for caller id, connected id and redirecting ids inside
Asterisk channels.

The private party id elements can be read or set by the user using
Asterisk dialplan functions.

When a technology channel is initiating a call, receives an internal
connected-line update event, or receives an internal redirecting update
event, it merges the corresponding public id with the private id to create
an effective party id.  The effective party id is then used for protocol
signaling.

The channel technologies which initially support the private id
representation with this patch are SIP (chan_sip), mISDN (chan_misdn) and
PRI (chan_dahdi).

Once a private name or number on a channel is set and (implicitly) made
valid, it is generally used for any further protocol signaling until it is
rewritten or invalidated.

To simplify the invalidation of private ids all internally generated
connected/redirecting update events and also all connected/redirecting
update events which are generated by technology channels -- receiving
regarding protocol information - automatically trigger the invalidation of
private ids.

If not using the private party id representation feature at all, i.e.  if
using only the 'regular' caller-id, connected and redirecting related
functions, the current characteristic of Asterisk is not affected by the
new extended functionality.

3. User interface Description

To grant access to the private name and number representation from the
Asterisk dialplan, the CALLERID, CONNECTEDLINE and REDIRECTING dialplan
functions are extended by the following data types.  The formats of these
data types are equal to the corresponding regular 'non-private' already
existing data types:

CALLERID:
priv-all
priv-name priv-name-valid priv-name-charset priv-name-pres
priv-num priv-num-valid priv-num-plan priv-num-pres
priv-subaddr priv-subaddr-valid priv-subaddr-type priv-subaddr-odd
priv-tag

CONNECTEDLINE:
priv-name priv-name-valid priv-name-pres priv-name-charset
priv-num priv-num-valid priv-num-pres priv-num-plan
priv-subaddr priv-subaddr-valid priv-subaddr-type priv-subaddr-odd
priv-tag

REDIRECTING:
priv-orig-name priv-orig-name-valid priv-orig-name-pres priv-orig-name-charset
priv-orig-num priv-orig-num-valid priv-orig-num-pres priv-orig-num-plan
priv-orig-subaddr priv-orig-subaddr-valid priv-orig-subaddr-type priv-orig-subaddr-odd
priv-orig-tag

priv-from-name priv-from-name-valid priv-from-name-pres priv-from-name-charset
priv-from-num priv-from-num-valid priv-from-num-pres priv-from-num-plan
priv-from-subaddr priv-from-subaddr-valid priv-from-subaddr-type priv-from-subaddr-odd
priv-from-tag

priv-to-name priv-to-name-valid priv-to-name-pres priv-to-name-charset
priv-to-num priv-to-num-valid priv-to-num-pres priv-to-num-plan
priv-to-subaddr priv-to-subaddr-valid priv-to-subaddr-type priv-to-subaddr-odd
priv-to-tag

Reported by: Thomas Arimont

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

Modified:
    trunk/channels/chan_misdn.c
    trunk/channels/chan_sip.c
    trunk/channels/sig_pri.c
    trunk/funcs/func_callerid.c
    trunk/include/asterisk/channel.h
    trunk/main/channel.c
    trunk/main/channel_internal_api.c
    trunk/main/cli.c
    trunk/main/features.c

Modified: trunk/channels/chan_misdn.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_misdn.c?view=diff&rev=371120&r1=371119&r2=371120
==============================================================================
--- trunk/channels/chan_misdn.c (original)
+++ trunk/channels/chan_misdn.c Fri Aug 10 14:54:55 2012
@@ -6109,6 +6109,13 @@
 		| misdn_to_ast_plan(id->number_plan);
 	connected.id.number.presentation = misdn_to_ast_pres(id->presentation)
 		| misdn_to_ast_screen(id->screening);
+
+	/*
+	 * Make sure that any earlier private connected id
+	 * representation at the remote end is invalidated
+	 */
+	ast_set_party_id_all(&update_connected.priv);
+
 	connected.id.tag = cid_tag;
 	connected.source = source;
 	ast_channel_queue_connected_line_update(ast, &connected, &update_connected);
@@ -6182,20 +6189,21 @@
 static void misdn_get_connected_line(struct ast_channel *ast, struct misdn_bchannel *bc, int originator)
 {
 	int number_type;
+	struct ast_party_id connected_id = ast_channel_connected_effective_id(ast);
 
 	if (originator == ORG_MISDN) {
 		/* ORIGINATOR MISDN (incoming call) */
 
 		ast_copy_string(bc->connected.name,
-			S_COR(ast_channel_connected(ast)->id.name.valid, ast_channel_connected(ast)->id.name.str, ""),
+			S_COR(connected_id.name.valid, connected_id.name.str, ""),
 			sizeof(bc->connected.name));
-		if (ast_channel_connected(ast)->id.number.valid) {
-			ast_copy_string(bc->connected.number, S_OR(ast_channel_connected(ast)->id.number.str, ""),
+		if (connected_id.number.valid) {
+			ast_copy_string(bc->connected.number, S_OR(connected_id.number.str, ""),
 				sizeof(bc->connected.number));
-			bc->connected.presentation = ast_to_misdn_pres(ast_channel_connected(ast)->id.number.presentation);
-			bc->connected.screening = ast_to_misdn_screen(ast_channel_connected(ast)->id.number.presentation);
-			bc->connected.number_type = ast_to_misdn_ton(ast_channel_connected(ast)->id.number.plan);
-			bc->connected.number_plan = ast_to_misdn_plan(ast_channel_connected(ast)->id.number.plan);
+			bc->connected.presentation = ast_to_misdn_pres(connected_id.number.presentation);
+			bc->connected.screening = ast_to_misdn_screen(connected_id.number.presentation);
+			bc->connected.number_type = ast_to_misdn_ton(connected_id.number.plan);
+			bc->connected.number_plan = ast_to_misdn_plan(connected_id.number.plan);
 		} else {
 			bc->connected.number[0] = '\0';
 			bc->connected.presentation = 0;/* Allowed */
@@ -6215,15 +6223,15 @@
 		/* ORIGINATOR Asterisk (outgoing call) */
 
 		ast_copy_string(bc->caller.name,
-			S_COR(ast_channel_connected(ast)->id.name.valid, ast_channel_connected(ast)->id.name.str, ""),
+			S_COR(connected_id.name.valid, connected_id.name.str, ""),
 			sizeof(bc->caller.name));
-		if (ast_channel_connected(ast)->id.number.valid) {
-			ast_copy_string(bc->caller.number, S_OR(ast_channel_connected(ast)->id.number.str, ""),
+		if (connected_id.number.valid) {
+			ast_copy_string(bc->caller.number, S_OR(connected_id.number.str, ""),
 				sizeof(bc->caller.number));
-			bc->caller.presentation = ast_to_misdn_pres(ast_channel_connected(ast)->id.number.presentation);
-			bc->caller.screening = ast_to_misdn_screen(ast_channel_connected(ast)->id.number.presentation);
-			bc->caller.number_type = ast_to_misdn_ton(ast_channel_connected(ast)->id.number.plan);
-			bc->caller.number_plan = ast_to_misdn_plan(ast_channel_connected(ast)->id.number.plan);
+			bc->caller.presentation = ast_to_misdn_pres(connected_id.number.presentation);
+			bc->caller.screening = ast_to_misdn_screen(connected_id.number.presentation);
+			bc->caller.number_type = ast_to_misdn_ton(connected_id.number.plan);
+			bc->caller.number_plan = ast_to_misdn_plan(connected_id.number.plan);
 		} else {
 			bc->caller.number[0] = '\0';
 			bc->caller.presentation = 0;/* Allowed */
@@ -6336,16 +6344,19 @@
  */
 static void misdn_copy_redirecting_from_ast(struct misdn_bchannel *bc, struct ast_channel *ast)
 {
+	struct ast_party_id from_id = ast_channel_redirecting_effective_from(ast);
+	struct ast_party_id to_id = ast_channel_redirecting_effective_to(ast);
+
 	ast_copy_string(bc->redirecting.from.name,
-		S_COR(ast_channel_redirecting(ast)->from.name.valid, ast_channel_redirecting(ast)->from.name.str, ""),
+		S_COR(from_id.name.valid, from_id.name.str, ""),
 		sizeof(bc->redirecting.from.name));
-	if (ast_channel_redirecting(ast)->from.number.valid) {
-		ast_copy_string(bc->redirecting.from.number, S_OR(ast_channel_redirecting(ast)->from.number.str, ""),
+	if (from_id.number.valid) {
+		ast_copy_string(bc->redirecting.from.number, S_OR(from_id.number.str, ""),
 			sizeof(bc->redirecting.from.number));
-		bc->redirecting.from.presentation = ast_to_misdn_pres(ast_channel_redirecting(ast)->from.number.presentation);
-		bc->redirecting.from.screening = ast_to_misdn_screen(ast_channel_redirecting(ast)->from.number.presentation);
-		bc->redirecting.from.number_type = ast_to_misdn_ton(ast_channel_redirecting(ast)->from.number.plan);
-		bc->redirecting.from.number_plan = ast_to_misdn_plan(ast_channel_redirecting(ast)->from.number.plan);
+		bc->redirecting.from.presentation = ast_to_misdn_pres(from_id.number.presentation);
+		bc->redirecting.from.screening = ast_to_misdn_screen(from_id.number.presentation);
+		bc->redirecting.from.number_type = ast_to_misdn_ton(from_id.number.plan);
+		bc->redirecting.from.number_plan = ast_to_misdn_plan(from_id.number.plan);
 	} else {
 		bc->redirecting.from.number[0] = '\0';
 		bc->redirecting.from.presentation = 0;/* Allowed */
@@ -6355,15 +6366,15 @@
 	}
 
 	ast_copy_string(bc->redirecting.to.name,
-		S_COR(ast_channel_redirecting(ast)->to.name.valid, ast_channel_redirecting(ast)->to.name.str, ""),
+		S_COR(to_id.name.valid, to_id.name.str, ""),
 		sizeof(bc->redirecting.to.name));
-	if (ast_channel_redirecting(ast)->to.number.valid) {
-		ast_copy_string(bc->redirecting.to.number, S_OR(ast_channel_redirecting(ast)->to.number.str, ""),
+	if (to_id.number.valid) {
+		ast_copy_string(bc->redirecting.to.number, S_OR(to_id.number.str, ""),
 			sizeof(bc->redirecting.to.number));
-		bc->redirecting.to.presentation = ast_to_misdn_pres(ast_channel_redirecting(ast)->to.number.presentation);
-		bc->redirecting.to.screening = ast_to_misdn_screen(ast_channel_redirecting(ast)->to.number.presentation);
-		bc->redirecting.to.number_type = ast_to_misdn_ton(ast_channel_redirecting(ast)->to.number.plan);
-		bc->redirecting.to.number_plan = ast_to_misdn_plan(ast_channel_redirecting(ast)->to.number.plan);
+		bc->redirecting.to.presentation = ast_to_misdn_pres(to_id.number.presentation);
+		bc->redirecting.to.screening = ast_to_misdn_screen(to_id.number.presentation);
+		bc->redirecting.to.number_type = ast_to_misdn_ton(to_id.number.plan);
+		bc->redirecting.to.number_plan = ast_to_misdn_plan(to_id.number.plan);
 	} else {
 		bc->redirecting.to.number[0] = '\0';
 		bc->redirecting.to.presentation = 0;/* Allowed */
@@ -6595,6 +6606,8 @@
 	} else
 #endif	/* defined(AST_MISDN_ENHANCEMENTS) */
 	{
+		struct ast_party_id connected_id = ast_channel_connected_effective_id(ast);
+
 		/*
 		 * dest is ---v
 		 * Dial(mISDN/g:group_name[/extension[/options]])
@@ -6616,15 +6629,15 @@
 		ast_copy_string(newbc->dialed.number, args.ext, sizeof(newbc->dialed.number));
 
 		if (ast_strlen_zero(newbc->caller.name)
-			&& ast_channel_connected(ast)->id.name.valid
-			&& !ast_strlen_zero(ast_channel_connected(ast)->id.name.str)) {
-			ast_copy_string(newbc->caller.name, ast_channel_connected(ast)->id.name.str, sizeof(newbc->caller.name));
+			&& connected_id.name.valid
+			&& !ast_strlen_zero(connected_id.name.str)) {
+			ast_copy_string(newbc->caller.name, connected_id.name.str, sizeof(newbc->caller.name));
 			chan_misdn_log(3, port, " --> * set caller:\"%s\" <%s>\n", newbc->caller.name, newbc->caller.number);
 		}
 		if (ast_strlen_zero(newbc->caller.number)
-			&& ast_channel_connected(ast)->id.number.valid
-			&& !ast_strlen_zero(ast_channel_connected(ast)->id.number.str)) {
-			ast_copy_string(newbc->caller.number, ast_channel_connected(ast)->id.number.str, sizeof(newbc->caller.number));
+			&& connected_id.number.valid
+			&& !ast_strlen_zero(connected_id.number.str)) {
+			ast_copy_string(newbc->caller.number, connected_id.number.str, sizeof(newbc->caller.number));
 			chan_misdn_log(3, port, " --> * set caller:\"%s\" <%s>\n", newbc->caller.name, newbc->caller.number);
 		}
 
@@ -6638,9 +6651,9 @@
 
 		misdn_cfg_get(port, MISDN_CFG_LOCALDIALPLAN, &number_type, sizeof(number_type));
 		if (number_type < 0) {
-			if (ast_channel_connected(ast)->id.number.valid) {
-				newbc->caller.number_type = ast_to_misdn_ton(ast_channel_connected(ast)->id.number.plan);
-				newbc->caller.number_plan = ast_to_misdn_plan(ast_channel_connected(ast)->id.number.plan);
+			if (connected_id.number.valid) {
+				newbc->caller.number_type = ast_to_misdn_ton(connected_id.number.plan);
+				newbc->caller.number_plan = ast_to_misdn_plan(connected_id.number.plan);
 			} else {
 				newbc->caller.number_type = NUMTYPE_UNKNOWN;
 				newbc->caller.number_plan = NUMPLAN_ISDN;
@@ -8605,8 +8618,16 @@
 
 	ast_party_connected_line_init(&target_colp);
 	ast_party_connected_line_copy(&target_colp, ast_channel_connected(target));
+
+	/* Reset any earlier private connected id representation */
+	ast_party_id_reset(&target_colp.priv);
+
 	ast_party_connected_line_init(&transferee_colp);
 	ast_party_connected_line_copy(&transferee_colp, ast_channel_connected(held_ch->ast));
+
+	/* Reset any earlier private connected id representation*/
+	ast_party_id_reset(&transferee_colp.priv);
+
 	held_ch->hold.state = MISDN_HOLD_TRANSFER;
 
 	/*
@@ -9283,11 +9304,25 @@
 			bc->div_leg_3_rx_wanted = 0;
 
 			if (ch && ch->ast) {
+				struct ast_party_redirecting redirecting;
+
 				ast_channel_redirecting(ch->ast)->to.number.presentation =
 					bc->fac_in.u.DivertingLegInformation3.PresentationAllowedIndicator
 					? AST_PRES_ALLOWED | AST_PRES_USER_NUMBER_UNSCREENED
 					: AST_PRES_RESTRICTED | AST_PRES_USER_NUMBER_UNSCREENED;
-				ast_channel_queue_redirecting_update(ch->ast, ast_channel_redirecting(ch->ast), NULL);
+				ast_party_redirecting_init(&redirecting);
+				ast_party_redirecting_copy(&redirecting, ast_channel_redirecting(ch->ast));
+
+				/*
+				 * Reset any earlier private redirecting id representations and
+				 * make sure that it is invalidated at the remote end.
+				 */
+				ast_party_id_reset(&redirecting.priv_orig);
+				ast_party_id_reset(&redirecting.priv_from);
+				ast_party_id_reset(&redirecting.priv_to);
+
+				ast_channel_queue_redirecting_update(ch->ast, &redirecting, NULL);
+				ast_party_redirecting_free(&redirecting);
 			}
 		}
 		break;
@@ -10518,9 +10553,23 @@
 			bc->div_leg_3_rx_wanted = 0;
 
 			if (ch->ast) {
+				struct ast_party_redirecting redirecting;
+
 				ast_channel_redirecting(ch->ast)->to.number.presentation =
 					AST_PRES_RESTRICTED | AST_PRES_USER_NUMBER_UNSCREENED;
-				ast_channel_queue_redirecting_update(ch->ast, ast_channel_redirecting(ch->ast), NULL);
+				ast_party_redirecting_init(&redirecting);
+				ast_party_redirecting_copy(&redirecting, ast_channel_redirecting(ch->ast));
+
+				/*
+				 * Reset any earlier private redirecting id representations and
+				 * make sure that it is invalidated at the remote end.
+				 */
+				ast_party_id_reset(&redirecting.priv_orig);
+				ast_party_id_reset(&redirecting.priv_from);
+				ast_party_id_reset(&redirecting.priv_to);
+
+				ast_channel_queue_redirecting_update(ch->ast, &redirecting, NULL);
+				ast_party_redirecting_free(&redirecting);
 			}
 		}
 #endif	/* defined(AST_MISDN_ENHANCEMENTS) */
@@ -10939,6 +10988,9 @@
 			bc->redirecting.to_changed = 0;
 			break;
 		case mISDN_NOTIFY_CODE_CALL_IS_DIVERTING:
+		{
+			struct ast_party_redirecting redirecting;
+
 			if (!bc->redirecting.to_changed) {
 				break;
 			}
@@ -10957,8 +11009,21 @@
 				break;
 			}
 			misdn_copy_redirecting_to_ast(ch->ast, &bc->redirecting, bc->incoming_cid_tag);
-			ast_channel_queue_redirecting_update(ch->ast, ast_channel_redirecting(ch->ast), NULL);
-			break;
+			ast_party_redirecting_init(&redirecting);
+			ast_party_redirecting_copy(&redirecting, ast_channel_redirecting(ch->ast));
+
+			/*
+			 * Reset any earlier private redirecting id representations and
+			 * make sure that it is invalidated at the remote end.
+			 */
+			ast_party_id_reset(&redirecting.priv_orig);
+			ast_party_id_reset(&redirecting.priv_from);
+			ast_party_id_reset(&redirecting.priv_to);
+
+			ast_channel_queue_redirecting_update(ch->ast, &redirecting, NULL);
+			ast_party_redirecting_free(&redirecting);
+			break;
+		}
 		case mISDN_NOTIFY_CODE_CALL_TRANSFER_ALERTING:
 			/*
 			 * It would be preferable to update the connected line information

Modified: trunk/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_sip.c?view=diff&rev=371120&r1=371119&r2=371120
==============================================================================
--- trunk/channels/chan_sip.c (original)
+++ trunk/channels/chan_sip.c Fri Aug 10 14:54:55 2012
@@ -6009,6 +6009,9 @@
 			connected.id.name.presentation = p->callingpres;
 		}
 		if (update_connected.id.number || update_connected.id.name) {
+			/* Invalidate any earlier private connected id representation */
+			ast_set_party_id_all(&update_connected.priv);
+
 			connected.id.tag = (char *) p->cid_tag;
 			connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
 			ast_channel_queue_connected_line_update(ast, &connected, &update_connected);
@@ -11872,25 +11875,28 @@
 	char tmp2[256];
 	char *lid_num = NULL;
 	char *lid_name = NULL;
-	int lid_pres;
+	int lid_pres = AST_PRES_NUMBER_NOT_AVAILABLE;
 	const char *fromdomain;
 	const char *privacy = NULL;
 	const char *screen = NULL;
 	const char *anonymous_string = "\"Anonymous\" <sip:anonymous at anonymous.invalid>";
+	struct ast_party_id connected_id;
 
 	if (!ast_test_flag(&p->flags[0], SIP_SENDRPID)) {
 		return 0;
 	}
 
-	if (p->owner && ast_channel_connected(p->owner)->id.number.valid
-		&& ast_channel_connected(p->owner)->id.number.str) {
-		lid_num = ast_channel_connected(p->owner)->id.number.str;
-	}
-	if (p->owner && ast_channel_connected(p->owner)->id.name.valid
-		&& ast_channel_connected(p->owner)->id.name.str) {
-		lid_name = ast_channel_connected(p->owner)->id.name.str;
-	}
-	lid_pres = (p->owner) ? ast_party_id_presentation(&ast_channel_connected(p->owner)->id) : AST_PRES_NUMBER_NOT_AVAILABLE;
+	if (p->owner) {
+		connected_id = ast_channel_connected_effective_id(p->owner);
+
+		if (connected_id.number.valid) {
+			lid_num = connected_id.number.str;
+		}
+		if (connected_id.name.valid) {
+			lid_name = connected_id.name.str;
+		}
+		lid_pres = ast_party_id_presentation(&connected_id);
+	}
 
 	if (ast_strlen_zero(lid_num))
 		return 0;
@@ -13079,6 +13085,7 @@
 	int ourport;
 	int cid_has_name = 1;
 	int cid_has_num = 1;
+	struct ast_party_id connected_id;
 
 	if (ast_test_flag(&p->flags[0], SIP_USEREQPHONE)) {
 	 	const char *s = p->username;	/* being a string field, cannot be NULL */
@@ -13104,9 +13111,15 @@
 
 	d = S_OR(p->fromdomain, ast_sockaddr_stringify_host_remote(&p->ourip));
 	if (p->owner) {
-		if ((ast_party_id_presentation(&ast_channel_connected(p->owner)->id) & AST_PRES_RESTRICTION) == AST_PRES_ALLOWED) {
-			l = ast_channel_connected(p->owner)->id.number.valid ? ast_channel_connected(p->owner)->id.number.str : NULL;
-			n = ast_channel_connected(p->owner)->id.name.valid ? ast_channel_connected(p->owner)->id.name.str : NULL;
+		connected_id = ast_channel_connected_effective_id(p->owner);
+
+		if ((ast_party_id_presentation(&connected_id) & AST_PRES_RESTRICTION) == AST_PRES_ALLOWED) {
+			if (connected_id.number.valid) {
+				l = connected_id.number.str;
+			}
+			if (connected_id.name.valid) {
+				n = connected_id.name.str;
+			}
 		} else {
 			/* Even if we are using RPID, we shouldn't leak information in the From if the user wants
 			 * their callerid restricted */
@@ -13260,8 +13273,7 @@
  */
 static void add_diversion(struct sip_request *req, struct sip_pvt *pvt)
 {
-	const char *diverting_number;
-	const char *diverting_name;
+	struct ast_party_id diverting_from;
 	const char *reason;
 	char header_text[256];
 
@@ -13274,23 +13286,22 @@
 		return;
 	}
 
-	diverting_number = ast_channel_redirecting(pvt->owner)->from.number.str;
-	if (!ast_channel_redirecting(pvt->owner)->from.number.valid
-		|| ast_strlen_zero(diverting_number)) {
+	diverting_from = ast_channel_redirecting_effective_from(pvt->owner);
+	if (!diverting_from.number.valid
+		|| ast_strlen_zero(diverting_from.number.str)) {
 		return;
 	}
 
 	reason = sip_reason_code_to_str(ast_channel_redirecting(pvt->owner)->reason);
 
 	/* We at least have a number to place in the Diversion header, which is enough */
-	diverting_name = ast_channel_redirecting(pvt->owner)->from.name.str;
-	if (!ast_channel_redirecting(pvt->owner)->from.name.valid
-		|| ast_strlen_zero(diverting_name)) {
-		snprintf(header_text, sizeof(header_text), "<sip:%s@%s>;reason=%s", diverting_number,
+	if (!diverting_from.name.valid
+		|| ast_strlen_zero(diverting_from.name.str)) {
+		snprintf(header_text, sizeof(header_text), "<sip:%s@%s>;reason=%s", diverting_from.number.str,
 				ast_sockaddr_stringify_host_remote(&pvt->ourip), reason);
 	} else {
 		snprintf(header_text, sizeof(header_text), "\"%s\" <sip:%s@%s>;reason=%s",
-				diverting_name, diverting_number,
+				diverting_from.name.str, diverting_from.number.str,
 				ast_sockaddr_stringify_host_remote(&pvt->ourip), reason);
 	}
 
@@ -14195,19 +14206,20 @@
 /*! \brief Notify peer that the connected line has changed */
 static void update_connectedline(struct sip_pvt *p, const void *data, size_t datalen)
 {
+	struct ast_party_id connected_id = ast_channel_connected_effective_id(p->owner);
 
 	if (!ast_test_flag(&p->flags[0], SIP_SENDRPID)) {
 		return;
 	}
-	if (!ast_channel_connected(p->owner)->id.number.valid
-		|| ast_strlen_zero(ast_channel_connected(p->owner)->id.number.str)) {
+	if (!connected_id.number.valid
+		|| ast_strlen_zero(connected_id.number.str)) {
 		return;
 	}
 
 	append_history(p, "ConnectedLine", "%s party is now %s <%s>",
 		ast_test_flag(&p->flags[0], SIP_OUTGOING) ? "Calling" : "Called",
-		S_COR(ast_channel_connected(p->owner)->id.name.valid, ast_channel_connected(p->owner)->id.name.str, ""),
-		S_COR(ast_channel_connected(p->owner)->id.number.valid, ast_channel_connected(p->owner)->id.number.str, ""));
+		S_COR(connected_id.name.valid, connected_id.name.str, ""),
+		S_COR(connected_id.number.valid, connected_id.number.str, ""));
 
 	if (ast_channel_state(p->owner) == AST_STATE_UP || ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
 		struct sip_request req;
@@ -21789,6 +21801,9 @@
 				connected.id.name.str = (char *) p->cid_name;
 				connected.id.name.presentation = p->callingpres;
 
+				/* Invalidate any earlier private connected id representation */
+				ast_set_party_id_all(&update_connected.priv);
+
 				connected.id.tag = (char *) p->cid_tag;
 				connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
 				ast_channel_queue_connected_line_update(p->owner, &connected,
@@ -21832,6 +21847,12 @@
 			memset(&update_redirecting, 0, sizeof(update_redirecting));
 			change_redirecting_information(p, req, &redirecting, &update_redirecting,
 				FALSE);
+
+			/* Invalidate any earlier private redirecting id representations */
+			ast_set_party_id_all(&update_redirecting.priv_orig);
+			ast_set_party_id_all(&update_redirecting.priv_from);
+			ast_set_party_id_all(&update_redirecting.priv_to);
+
 			ast_channel_queue_redirecting_update(p->owner, &redirecting,
 				&update_redirecting);
 			ast_party_redirecting_free(&redirecting);
@@ -21866,6 +21887,9 @@
 				connected.id.name.valid = 1;
 				connected.id.name.str = (char *) p->cid_name;
 				connected.id.name.presentation = p->callingpres;
+
+				/* Invalidate any earlier private connected id representation */
+				ast_set_party_id_all(&update_connected.priv);
 
 				connected.id.tag = (char *) p->cid_tag;
 				connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
@@ -21936,6 +21960,9 @@
 					connected.id.name.presentation = p->callingpres;
 				}
 				if (update_connected.id.number || update_connected.id.name) {
+					/* Invalidate any earlier private connected id representation */
+					ast_set_party_id_all(&update_connected.priv);
+
 					connected.id.tag = (char *) p->cid_tag;
 					connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
 					ast_channel_queue_connected_line_update(p->owner, &connected,
@@ -24010,6 +24037,9 @@
 		connected.id.name.str = (char *) p->cid_name;
 		connected.id.name.presentation = p->callingpres;
 
+		/* Invalidate any earlier private connected id representation */
+		ast_set_party_id_all(&update_connected.priv);
+
 		connected.id.tag = (char *) p->cid_tag;
 		connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
 		ast_channel_queue_connected_line_update(p->owner, &connected, &update_connected);
@@ -24360,6 +24390,9 @@
 				connected.id.name.str = (char *) p->cid_name;
 				connected.id.name.presentation = p->callingpres;
 
+				/* Invalidate any earlier private connected id representation */
+				ast_set_party_id_all(&update_connected.priv);
+
 				connected.id.tag = (char *) p->cid_tag;
 				connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
 				ast_channel_queue_connected_line_update(p->owner, &connected,
@@ -25054,6 +25087,9 @@
 	ast_party_connected_line_copy(&connected_to_transferee, ast_channel_connected(current->chan1));
 	/* No need to lock target.chan1 here since it was locked in get_sip_pvt_byid_locked */
 	ast_party_connected_line_copy(&connected_to_target, ast_channel_connected(target.chan1));
+	/* Reset any earlier private connected id representation */
+	ast_party_id_reset(&connected_to_transferee.priv);
+	ast_party_id_reset(&connected_to_target.priv);
 	connected_to_target.source = connected_to_transferee.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
 	res = attempt_transfer(current, &target);
 	if (res) {

Modified: trunk/channels/sig_pri.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/sig_pri.c?view=diff&rev=371120&r1=371119&r2=371120
==============================================================================
--- trunk/channels/sig_pri.c (original)
+++ trunk/channels/sig_pri.c Fri Aug 10 14:54:55 2012
@@ -906,12 +906,15 @@
 {
 	struct pri_party_redirecting pri_redirecting;
 	const struct ast_party_redirecting *ast_redirecting;
+	struct ast_party_id redirecting_from = ast_channel_redirecting_effective_from(ast);
+	struct ast_party_id redirecting_to = ast_channel_redirecting_effective_to(ast);
+	struct ast_party_id redirecting_orig = ast_channel_redirecting_effective_orig(ast);
 
 	memset(&pri_redirecting, 0, sizeof(pri_redirecting));
 	ast_redirecting = ast_channel_redirecting(ast);
-	sig_pri_party_id_from_ast(&pri_redirecting.from, &ast_redirecting->from);
-	sig_pri_party_id_from_ast(&pri_redirecting.to, &ast_redirecting->to);
-	sig_pri_party_id_from_ast(&pri_redirecting.orig_called, &ast_redirecting->orig);
+	sig_pri_party_id_from_ast(&pri_redirecting.from, &redirecting_from);
+	sig_pri_party_id_from_ast(&pri_redirecting.to, &redirecting_to);
+	sig_pri_party_id_from_ast(&pri_redirecting.orig_called, &redirecting_orig);
 	pri_redirecting.count = ast_redirecting->count;
 	pri_redirecting.orig_reason = ast_to_pri_reason(ast_redirecting->orig_reason);
 	pri_redirecting.reason = ast_to_pri_reason(ast_redirecting->reason);
@@ -4247,6 +4250,12 @@
 				ast_channel_set_redirecting(owner, &ast_redirecting, NULL);
 				if (event_id != PRI_EVENT_RING) {
 					/* This redirection was not from a SETUP message. */
+
+					/* Invalidate any earlier private redirecting id representations */
+					ast_party_id_invalidate(&ast_redirecting.priv_orig);
+					ast_party_id_invalidate(&ast_redirecting.priv_from);
+					ast_party_id_invalidate(&ast_redirecting.priv_to);
+
 					ast_channel_queue_redirecting_update(owner, &ast_redirecting, NULL);
 				}
 				ast_party_redirecting_free(&ast_redirecting);
@@ -7726,10 +7735,11 @@
 	);
 	struct ast_flags opts;
 	char *opt_args[OPT_ARG_ARRAY_SIZE];
+	struct ast_party_id connected_id = ast_channel_connected_effective_id(ast);
 
 	ast_debug(1, "CALLER NAME: %s NUM: %s\n",
-		S_COR(ast_channel_connected(ast)->id.name.valid, ast_channel_connected(ast)->id.name.str, ""),
-		S_COR(ast_channel_connected(ast)->id.number.valid, ast_channel_connected(ast)->id.number.str, ""));
+		S_COR(connected_id.name.valid, connected_id.name.str, ""),
+		S_COR(connected_id.number.valid, connected_id.number.str, ""));
 
 	if (!p->pri) {
 		ast_log(LOG_ERROR, "Could not find pri on channel %d\n", p->channel);
@@ -7785,14 +7795,14 @@
 	l = NULL;
 	n = NULL;
 	if (!p->hidecallerid) {
-		if (ast_channel_connected(ast)->id.number.valid) {
+		if (connected_id.number.valid) {
 			/* If we get to the end of this loop without breaking, there's no
 			 * calleridnum.  This is done instead of testing for "unknown" or
 			 * the thousands of other ways that the calleridnum could be
 			 * invalid. */
-			for (l = ast_channel_connected(ast)->id.number.str; l && *l; l++) {
+			for (l = connected_id.number.str; l && *l; l++) {
 				if (strchr("0123456789", *l)) {
-					l = ast_channel_connected(ast)->id.number.str;
+					l = connected_id.number.str;
 					break;
 				}
 			}
@@ -7800,7 +7810,7 @@
 			l = NULL;
 		}
 		if (!p->hidecalleridname) {
-			n = ast_channel_connected(ast)->id.name.valid ? ast_channel_connected(ast)->id.name.str : NULL;
+			n = connected_id.name.valid ? connected_id.name.str : NULL;
 		}
 	}
 
@@ -8016,7 +8026,7 @@
 		}
 	} else if (prilocaldialplan == -1) {
 		/* Use the numbering plan passed in. */
-		prilocaldialplan = ast_channel_connected(ast)->id.number.plan;
+		prilocaldialplan = connected_id.number.plan;
 	}
 	if (l != NULL) {
 		while (*l > '9' && *l != '*' && *l != '#') {
@@ -8075,14 +8085,14 @@
 		}
 	}
 	pri_sr_set_caller(sr, l ? (l + ldp_strip) : NULL, n, prilocaldialplan,
-		p->use_callingpres ? ast_channel_connected(ast)->id.number.presentation : (l ? PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN : PRES_NUMBER_NOT_AVAILABLE));
+		p->use_callingpres ? connected_id.number.presentation : (l ? PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN : PRES_NUMBER_NOT_AVAILABLE));
 
 #if defined(HAVE_PRI_SUBADDR)
-	if (ast_channel_connected(ast)->id.subaddress.valid) {
+	if (connected_id.subaddress.valid) {
 		struct pri_party_subaddress subaddress;
 
 		memset(&subaddress, 0, sizeof(subaddress));
-		sig_pri_party_subaddress_from_ast(&subaddress, &ast_channel_connected(ast)->id.subaddress);
+		sig_pri_party_subaddress_from_ast(&subaddress, &connected_id.subaddress);
 		pri_sr_set_caller_subaddress(sr, &subaddress);
 	}
 #endif	/* defined(HAVE_PRI_SUBADDR) */
@@ -8313,6 +8323,7 @@
 			int dialplan;
 			int prefix_strip;
 			int colp_allowed = 0;
+			struct ast_party_id connected_id = ast_channel_connected_effective_id(chan);
 
 			pri_grab(p, p->pri);
 
@@ -8341,7 +8352,7 @@
 			}
 
 			memset(&connected, 0, sizeof(connected));
-			sig_pri_party_id_from_ast(&connected.id, &ast_channel_connected(chan)->id);
+			sig_pri_party_id_from_ast(&connected.id, &connected_id);
 
 			/* Determine the connected line numbering plan to actually use. */
 			switch (p->pri->cpndialplan) {

Modified: trunk/funcs/func_callerid.c
URL: http://svnview.digium.com/svn/asterisk/trunk/funcs/func_callerid.c?view=diff&rev=371120&r1=371119&r2=371120
==============================================================================
--- trunk/funcs/func_callerid.c (original)
+++ trunk/funcs/func_callerid.c Fri Aug 10 14:54:55 2012
@@ -103,6 +103,20 @@
 					<enum name = "subaddr-type" />
 					<enum name = "subaddr-odd" />
 					<enum name = "tag" />
+					<enum name = "priv-all" />
+					<enum name = "priv-name" />
+					<enum name = "priv-name-valid" />
+					<enum name = "priv-name-charset" />
+					<enum name = "priv-name-pres" />
+					<enum name = "priv-num" />
+					<enum name = "priv-num-valid" />
+					<enum name = "priv-num-plan" />
+					<enum name = "priv-num-pres" />
+					<enum name = "priv-subaddr" />
+					<enum name = "priv-subaddr-valid" />
+					<enum name = "priv-subaddr-type" />
+					<enum name = "priv-subaddr-odd" />
+					<enum name = "priv-tag" />
 					<enum name = "ANI-all" />
 					<enum name = "ANI-name" />
 					<enum name = "ANI-name-valid" />
@@ -209,6 +223,20 @@
 					<enum name = "subaddr-type" />
 					<enum name = "subaddr-odd" />
 					<enum name = "tag" />
+					<enum name = "priv-all" />
+					<enum name = "priv-name" />
+					<enum name = "priv-name-valid" />
+					<enum name = "priv-name-charset" />
+					<enum name = "priv-name-pres" />
+					<enum name = "priv-num" />
+					<enum name = "priv-num-valid" />
+					<enum name = "priv-num-plan" />
+					<enum name = "priv-num-pres" />
+					<enum name = "priv-subaddr" />
+					<enum name = "priv-subaddr-valid" />
+					<enum name = "priv-subaddr-type" />
+					<enum name = "priv-subaddr-odd" />
+					<enum name = "priv-tag" />
 				</enumlist>
 			</parameter>
 			<parameter name="i">
@@ -285,6 +313,48 @@
 					<enum name = "to-subaddr-type" />
 					<enum name = "to-subaddr-odd" />
 					<enum name = "to-tag" />
+					<enum name = "priv-orig-all" />
+					<enum name = "priv-orig-name" />
+					<enum name = "priv-orig-name-valid" />
+					<enum name = "priv-orig-name-charset" />
+					<enum name = "priv-orig-name-pres" />
+					<enum name = "priv-orig-num" />
+					<enum name = "priv-orig-num-valid" />
+					<enum name = "priv-orig-num-plan" />
+					<enum name = "priv-orig-num-pres" />
+					<enum name = "priv-orig-subaddr" />
+					<enum name = "priv-orig-subaddr-valid" />
+					<enum name = "priv-orig-subaddr-type" />
+					<enum name = "priv-orig-subaddr-odd" />
+					<enum name = "priv-orig-tag" />
+					<enum name = "priv-from-all" />
+					<enum name = "priv-from-name" />
+					<enum name = "priv-from-name-valid" />
+					<enum name = "priv-from-name-charset" />
+					<enum name = "priv-from-name-pres" />
+					<enum name = "priv-from-num" />
+					<enum name = "priv-from-num-valid" />
+					<enum name = "priv-from-num-plan" />
+					<enum name = "priv-from-num-pres" />
+					<enum name = "priv-from-subaddr" />
+					<enum name = "priv-from-subaddr-valid" />
+					<enum name = "priv-from-subaddr-type" />
+					<enum name = "priv-from-subaddr-odd" />
+					<enum name = "priv-from-tag" />
+					<enum name = "priv-to-all" />
+					<enum name = "priv-to-name" />
+					<enum name = "priv-to-name-valid" />
+					<enum name = "priv-to-name-charset" />
+					<enum name = "priv-to-name-pres" />
+					<enum name = "priv-to-num" />
+					<enum name = "priv-to-num-valid" />
+					<enum name = "priv-to-num-plan" />
+					<enum name = "priv-to-num-pres" />
+					<enum name = "priv-to-subaddr" />
+					<enum name = "priv-to-subaddr-valid" />
+					<enum name = "priv-to-subaddr-type" />
+					<enum name = "priv-to-subaddr-odd" />
+					<enum name = "priv-to-tag" />
 					<enum name = "reason" />
 					<enum name = "count" />
 				</enumlist>
@@ -997,6 +1067,17 @@
 				ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
 				break;
 			}
+		} else if (!strcasecmp("priv", member.argv[0])) {
+			status = party_id_read(buf, len, member.argc - 1, member.argv + 1,
+				&ast_channel_caller(chan)->priv);
+			switch (status) {
+			case ID_FIELD_VALID:
+			case ID_FIELD_INVALID:
+				break;
+			default:
+				ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
+				break;
+			}
 		} else {
 			status = party_id_read(buf, len, member.argc, member.argv, &ast_channel_caller(chan)->id);
 			switch (status) {
@@ -1159,6 +1240,23 @@
 			break;
 		}
 		ast_party_caller_free(&caller);
+	} else if (!strcasecmp("priv", member.argv[0])) {
+		ast_party_caller_set_init(&caller, ast_channel_caller(chan));
+		status = party_id_write(&caller.priv, member.argc - 1, member.argv + 1, value);
+		switch (status) {
+		case ID_FIELD_VALID:
+			ast_party_caller_set(ast_channel_caller(chan), &caller, NULL);
+			if (ast_channel_cdr(chan)) {
+				ast_cdr_setcid(ast_channel_cdr(chan), chan);
+			}
+			break;
+		case ID_FIELD_INVALID:
+			break;
+		default:
+			ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
+			break;
+		}
+		ast_party_caller_free(&caller);
 	} else {
 		ast_party_caller_set_init(&caller, ast_channel_caller(chan));
 		status = party_id_write(&caller.id, member.argc, member.argv, value);
@@ -1199,6 +1297,7 @@
 {
 	struct ast_party_members member;
 	char *read_what;
+	enum ID_FIELD_STATUS status;
 
 	/* Ensure that the buffer is empty */
 	*buf = 0;
@@ -1218,8 +1317,18 @@
 
 	if (member.argc == 1 && !strcasecmp("source", member.argv[0])) {
 		ast_copy_string(buf, ast_connected_line_source_name(ast_channel_connected(chan)->source), len);
+	} else if (!strcasecmp("priv", member.argv[0])) {
+		status = party_id_read(buf, len, member.argc - 1, member.argv + 1,
+			&ast_channel_connected(chan)->priv);
+		switch (status) {
+		case ID_FIELD_VALID:
+		case ID_FIELD_INVALID:
+			break;
+		default:
+			ast_log(LOG_ERROR, "Unknown connectedline data type '%s'.\n", data);
+			break;
+		}
 	} else {
-		enum ID_FIELD_STATUS status;
 		status = party_id_read(buf, len, member.argc, member.argv, &ast_channel_connected(chan)->id);
 		switch (status) {
 		case ID_FIELD_VALID:
@@ -1258,6 +1367,7 @@
 	struct ast_party_members member;
 	struct ast_flags opts;
 	char *opt_args[CONNECTED_LINE_OPT_ARG_ARRAY_SIZE];
+	enum ID_FIELD_STATUS status;
 
 	if (!value || !chan) {
 		return -1;
@@ -1312,8 +1422,20 @@
 			connected.source = source;
 			set_it(chan, &connected, NULL);
 		}
+	} else if (!strcasecmp("priv", member.argv[0])) {
+		status = party_id_write(&connected.priv, member.argc - 1, member.argv + 1, value);
+		switch (status) {
+		case ID_FIELD_VALID:
+			set_it(chan, &connected, NULL);
+			break;
+		case ID_FIELD_INVALID:
+			break;
+		default:
+			ast_log(LOG_ERROR, "Unknown connectedline data type '%s'.\n", data);
+			break;
+		}
+		ast_party_connected_line_free(&connected);
 	} else {
-		enum ID_FIELD_STATUS status;
 		status = party_id_write(&connected.id, member.argc, member.argv, value);
 		switch (status) {
 		case ID_FIELD_VALID:
@@ -1418,6 +1540,43 @@
 		ast_copy_string(buf, ast_redirecting_reason_name(ast_redirecting->reason), len);
 	} else if (member.argc == 1 && !strcasecmp("count", member.argv[0])) {
 		snprintf(buf, len, "%d", ast_redirecting->count);
+	} else if (1 < member.argc && !strcasecmp("priv", member.argv[0])) {
+		if (!strcasecmp("orig", member.argv[1])) {
+			status = party_id_read(buf, len, member.argc - 2, member.argv + 2,
+				&ast_redirecting->priv_orig);
+			switch (status) {
+			case ID_FIELD_VALID:
+			case ID_FIELD_INVALID:
+				break;
+			default:
+				ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
+				break;
+			}
+		} else if (!strcasecmp("from", member.argv[1])) {
+			status = party_id_read(buf, len, member.argc - 2, member.argv + 2,
+				&ast_redirecting->priv_from);
+			switch (status) {
+			case ID_FIELD_VALID:
+			case ID_FIELD_INVALID:
+				break;
+			default:

[... 1257 lines stripped ...]



More information about the svn-commits mailing list