[svn-commits] rmudgett: trunk r419520 - in /trunk: ./ apps/ include/asterisk/ main/ res/par...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Thu Jul 24 17:48:46 CDT 2014


Author: rmudgett
Date: Thu Jul 24 17:48:38 2014
New Revision: 419520

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=419520
Log:
accountcode: Slightly change accountcode propagation.

The previous behavior was to simply set the accountcode of an outgoing
channel to the accountcode of the channel initiating the call.  It was
done this way a long time ago to allow the accountcode set on the SIP/100
channel to be propagated to a local channel so the dialplan execution on
the Local;2 channel would have the SIP/100 accountcode available.

SIP/100 -> Local;1/Local;2 -> SIP/200

Propagating the SIP/100 accountcode to the local channels is very useful.
Without any dialplan manipulation, all channels in this call would have
the same accountcode.

Using dialplan, you can set a different accountcode on the SIP/200 channel
either by setting the accountcode on the Local;2 channel or by the Dial
application's b(pre-dial), M(macro) or U(gosub) options, or by the
FollowMe application's b(pre-dial) option, or by the Queue application's
macro or gosub options.  Before Asterisk v12, the altered accountcode on
SIP/200 will remain until the local channels optimize out and the
accountcode would change to the SIP/100 accountcode.

Asterisk v1.8 attempted to add peeraccount support but ultimately had to
punt on the support.  The peeraccount support was rendered useless because
of how the CDR code needed to unconditionally force the caller's
accountcode onto the peer channel's accountcode.  The CEL events were thus
intentionally made to always use the channel's accountcode as the
peeraccount value.

With the arrival of Asterisk v12, the situation has improved somewhat so
peeraccount support can be made to work.  Using the indicated example, the
the accountcode values become as follows when the peeraccount is set on
SIP/100 before calling SIP/200:

SIP/100 ---> Local;1 ---- Local;2 ---> SIP/200
acct: 100 \/ acct: 200 \/ acct: 100 \/ acct: 200
peer: 200 /\ peer: 100 /\ peer: 200 /\ peer: 100

If a channel already has an accountcode it can only change by the
following explicit user actions:

1) A channel originate method that can specify an accountcode to use.

2) The calling channel propagating its non-empty peeraccount or its
non-empty accountcode if the peeraccount was empty to the outgoing
channel's accountcode before initiating the dial.  e.g., Dial and
FollowMe.  The exception to this propagation method is Queue.  Queue will
only propagate peeraccounts this way only if the outgoing channel does not
have an accountcode.

3) Dialplan using CHANNEL(accountcode).

4) Dialplan using CHANNEL(peeraccount) on the other end of a local
channel pair.

If a channel does not have an accountcode it can get one from the
following places:

1) The channel driver's configuration at channel creation.

2) Explicit user action as already indicated.

3) Entering a basic or stasis-mixing bridge from a peer channel's
peeraccount value.

You can specify the accountcode for an outgoing channel by setting the
CHANNEL(peeraccount) before using the Dial, FollowMe, and Queue
applications.  Queue adds the wrinkle that it will not overwrite an
existing accountcode on the outgoing channel with the calling channels
values.

Accountcode and peeraccount values propagate to an outgoing channel before
dialing.  Accountcodes also propagate when channels enter or leave a basic
or stasis-mixing bridge.  The peeraccount value only makes sense for
mixing bridges with two channels; it is meaningless otherwise.

* Made peeraccount functional by changing accountcode propagation as
described above.

* Fixed CEL extracting the wrong ie value for the peeraccount.  This was
done intentionally in Asterisk v1.8 when that version had to punt on
peeraccount.

* Fixed a few places dealing with accountcodes that were reading from
channels without the lock held.

AFS-65 #close

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

Modified:
    trunk/CHANGES
    trunk/UPGRADE.txt
    trunk/apps/app_dial.c
    trunk/apps/app_followme.c
    trunk/apps/app_queue.c
    trunk/include/asterisk/channel.h
    trunk/main/bridge.c
    trunk/main/bridge_basic.c
    trunk/main/cel.c
    trunk/main/channel.c
    trunk/main/core_unreal.c
    trunk/main/dial.c
    trunk/main/pbx.c
    trunk/res/parking/parking_bridge_features.c

Modified: trunk/CHANGES
URL: http://svnview.digium.com/svn/asterisk/trunk/CHANGES?view=diff&rev=419520&r1=419519&r2=419520
==============================================================================
--- trunk/CHANGES (original)
+++ trunk/CHANGES Thu Jul 24 17:48:38 2014
@@ -11,6 +11,32 @@
 ------------------------------------------------------------------------------
 --- Functionality changes from Asterisk 12 to Asterisk 13 --------------------
 ------------------------------------------------------------------------------
+
+accountcode
+------------------
+ - Added functional peeraccount support.  Except for Queue, the
+   accountcode propagation is now consistently propagated to outgoing
+   channels before dialing.  The channel accountcode can change from its
+   original non-empty value on channel creation for the following specific
+   reasons.  One, dialplan sets it using CHANNEL(accountcode).  Two, an
+   originate method that can specify an accountcode value.  Three, the
+   calling channel propagates its peeraccount or accountcode to the
+   outgoing channel's accountcode before dialing.  The change has two
+   visible effects.  One, local channels now cross accountcode and
+   peeraccount across the special bridge between the ;1 and ;2 channels
+   just like channels between normal bridges.  Two, the
+   CHANNEL(peeraccount) value can now be set before Dial and FollowMe to
+   set the accountcode on the outgoing channel(s).
+
+   For Queue, an outgoing channel's non-empty accountcode will not change
+   unless explicitly set by CHANNEL(accountcode).  The change has three
+   visible effects.  One, local channels now cross accountcode and
+   peeraccount across the special bridge between the ;1 and ;2 channels
+   just like channels between normal bridges.  Two, the queue member will
+   get an accountcode if it doesn't have one and one is available from the
+   calling channel's peeraccount.  Three, accountcode propagation includes
+   local channel members where the accountcodes are propagated early
+   enough to be available on the ;2 channel.
 
 app_dahdibarge
 ------------------

Modified: trunk/UPGRADE.txt
URL: http://svnview.digium.com/svn/asterisk/trunk/UPGRADE.txt?view=diff&rev=419520&r1=419519&r2=419520
==============================================================================
--- trunk/UPGRADE.txt (original)
+++ trunk/UPGRADE.txt Thu Jul 24 17:48:38 2014
@@ -57,6 +57,13 @@
    update their dialplans to use ',' instead of '|' as a delimiter, and should
    use the Set dialplan application instead of the MSet dialplan application.
 
+accountcode:
+ - Accountcode behavior changed somewhat to add functional peeraccount
+   support.  The main change is that local channels now cross accountcode
+   and peeraccount across the special bridge between the ;1 and ;2 channels
+   just like channels between normal bridges.  See the CHANGES file for
+   more information.
+
 ARI:
  - The ARI version has been changed from 1.0.0 to 1.1.0. This is to reflect
    the backwards compatible changes listed below.

Modified: trunk/apps/app_dial.c
URL: http://svnview.digium.com/svn/asterisk/trunk/apps/app_dial.c?view=diff&rev=419520&r1=419519&r2=419520
==============================================================================
--- trunk/apps/app_dial.c (original)
+++ trunk/apps/app_dial.c Thu Jul 24 17:48:38 2014
@@ -956,7 +956,7 @@
 			ast_connected_line_copy_from_caller(ast_channel_connected(c), ast_channel_caller(in));
 		}
 
-		ast_channel_accountcode_set(c, ast_channel_accountcode(in));
+		ast_channel_req_accountcodes(c, in, AST_CHANNEL_REQUESTOR_BRIDGE_PEER);
 
 		ast_channel_appl_set(c, "AppDial");
 		ast_channel_data_set(c, "(Outgoing Line)");
@@ -2524,9 +2524,7 @@
 
 		ast_channel_dialed(tc)->transit_network_select = ast_channel_dialed(chan)->transit_network_select;
 
-		if (!ast_strlen_zero(ast_channel_accountcode(chan))) {
-			ast_channel_accountcode_set(tc, ast_channel_accountcode(chan));
-		}
+		ast_channel_req_accountcodes(tc, chan, AST_CHANNEL_REQUESTOR_BRIDGE_PEER);
 		if (ast_strlen_zero(ast_channel_musicclass(tc))) {
 			ast_channel_musicclass_set(tc, ast_channel_musicclass(chan));
 		}

Modified: trunk/apps/app_followme.c
URL: http://svnview.digium.com/svn/asterisk/trunk/apps/app_followme.c?view=diff&rev=419520&r1=419519&r2=419520
==============================================================================
--- trunk/apps/app_followme.c (original)
+++ trunk/apps/app_followme.c Thu Jul 24 17:48:38 2014
@@ -1070,7 +1070,7 @@
 			ast_channel_inherit_variables(caller, outbound);
 			ast_channel_datastore_inherit(caller, outbound);
 			ast_channel_language_set(outbound, ast_channel_language(caller));
-			ast_channel_accountcode_set(outbound, ast_channel_accountcode(caller));
+			ast_channel_req_accountcodes(outbound, caller, AST_CHANNEL_REQUESTOR_BRIDGE_PEER);
 			ast_channel_musicclass_set(outbound, ast_channel_musicclass(caller));
 			ast_channel_unlock(outbound);
 			ast_channel_unlock(caller);

Modified: trunk/apps/app_queue.c
URL: http://svnview.digium.com/svn/asterisk/trunk/apps/app_queue.c?view=diff&rev=419520&r1=419519&r2=419520
==============================================================================
--- trunk/apps/app_queue.c (original)
+++ trunk/apps/app_queue.c Thu Jul 24 17:48:38 2014
@@ -4125,6 +4125,8 @@
 
 	ast_channel_lock_both(tmp->chan, qe->chan);
 
+	ast_channel_req_accountcodes_precious(tmp->chan, qe->chan,
+		AST_CHANNEL_REQUESTOR_BRIDGE_PEER);
 	if (qe->cancel_answered_elsewhere) {
 		ast_channel_hangupcause_set(tmp->chan, AST_CAUSE_ANSWERED_ELSEWHERE);
 	}
@@ -4663,7 +4665,7 @@
 							ast_party_connected_line_copy(&o->connected, ast_channel_connected(in));
 						}
 
-						ast_channel_accountcode_set(o->chan, ast_channel_accountcode(in));
+						ast_channel_req_accountcodes(o->chan, in, AST_CHANNEL_REQUESTOR_BRIDGE_PEER);
 
 						if (!ast_channel_redirecting(o->chan)->from.number.valid
 							|| ast_strlen_zero(ast_channel_redirecting(o->chan)->from.number.str)) {

Modified: trunk/include/asterisk/channel.h
URL: http://svnview.digium.com/svn/asterisk/trunk/include/asterisk/channel.h?view=diff&rev=419520&r1=419519&r2=419520
==============================================================================
--- trunk/include/asterisk/channel.h (original)
+++ trunk/include/asterisk/channel.h Thu Jul 24 17:48:38 2014
@@ -1386,6 +1386,45 @@
  * \retval non-NULL channel on success
  */
 struct ast_channel *ast_request(const char *type, struct ast_format_cap *request_cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *addr, int *cause);
+
+enum ast_channel_requestor_relationship {
+	/*! The requestor is the future bridge peer of the channel. */
+	AST_CHANNEL_REQUESTOR_BRIDGE_PEER,
+	/*! The requestor is to be replaced by the channel. */
+	AST_CHANNEL_REQUESTOR_REPLACEMENT,
+};
+
+/*!
+ * \brief Setup new channel accountcodes from the requestor channel after ast_request().
+ * \since 13.0.0
+ *
+ * \param chan New channel to get accountcodes setup.
+ * \param requestor Requesting channel to get accountcodes from.
+ * \param relationship What the new channel was created for.
+ *
+ * \pre The chan and requestor channels are already locked.
+ *
+ * \note Pre-existing accountcodes on chan will be overwritten.
+ *
+ * \return Nothing
+ */
+void ast_channel_req_accountcodes(struct ast_channel *chan, const struct ast_channel *requestor, enum ast_channel_requestor_relationship relationship);
+
+/*!
+ * \brief Setup new channel accountcodes from the requestor channel after ast_request().
+ * \since 13.0.0
+ *
+ * \param chan New channel to get accountcodes setup.
+ * \param requestor Requesting channel to get accountcodes from.
+ * \param relationship What the new channel was created for.
+ *
+ * \pre The chan and requestor channels are already locked.
+ *
+ * \note Pre-existing accountcodes on chan will not be overwritten.
+ *
+ * \return Nothing
+ */
+void ast_channel_req_accountcodes_precious(struct ast_channel *chan, const struct ast_channel *requestor, enum ast_channel_requestor_relationship relationship);
 
 /*!
  * \brief Request a channel of a given type, with data as optional information used

Modified: trunk/main/bridge.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/bridge.c?view=diff&rev=419520&r1=419519&r2=419520
==============================================================================
--- trunk/main/bridge.c (original)
+++ trunk/main/bridge.c Thu Jul 24 17:48:38 2014
@@ -3793,7 +3793,11 @@
 		return AST_BRIDGE_TRANSFER_FAIL;
 	}
 
+	ast_channel_lock_both(local, transferer);
+	ast_channel_req_accountcodes(local, transferer, AST_CHANNEL_REQUESTOR_REPLACEMENT);
 	pbx_builtin_setvar_helper(local, BLINDTRANSFER, ast_channel_name(transferer));
+	ast_channel_unlock(local);
+	ast_channel_unlock(transferer);
 
 	if (new_channel_cb) {
 		new_channel_cb(local, user_data_wrapper, AST_BRIDGE_TRANSFER_MULTI_PARTY);
@@ -3952,12 +3956,15 @@
 
 	local_chan = ast_request("Local", ast_channel_nativeformats(chan1), NULL, chan1,
 			dest, &cause);
-
 	if (!local_chan) {
 		return AST_BRIDGE_TRANSFER_FAIL;
 	}
 
+	ast_channel_lock_both(local_chan, chan1);
+	ast_channel_req_accountcodes(local_chan, chan1, AST_CHANNEL_REQUESTOR_REPLACEMENT);
 	pbx_builtin_setvar_helper(local_chan, ATTENDEDTRANSFER, ast_channel_name(chan1));
+	ast_channel_unlock(local_chan);
+	ast_channel_unlock(chan1);
 
 	if (bridge2) {
 		res = ast_local_setup_bridge(local_chan, bridge2, chan2, NULL);

Modified: trunk/main/bridge_basic.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/bridge_basic.c?view=diff&rev=419520&r1=419519&r2=419520
==============================================================================
--- trunk/main/bridge_basic.c (original)
+++ trunk/main/bridge_basic.c Thu Jul 24 17:48:38 2014
@@ -2982,10 +2982,17 @@
 		return NULL;
 	}
 
+	ast_channel_lock_both(chan, caller);
+
+	ast_channel_req_accountcodes(chan, caller, AST_CHANNEL_REQUESTOR_BRIDGE_PEER);
+
 	/* Who is transferring the call. */
 	pbx_builtin_setvar_helper(chan, "TRANSFERERNAME", ast_channel_name(caller));
 
 	ast_bridge_set_transfer_variables(chan, ast_channel_name(caller), 1);
+
+	ast_channel_unlock(chan);
+	ast_channel_unlock(caller);
 
 	/* Before we actually dial out let's inherit appropriate information. */
 	copy_caller_data(chan, caller);

Modified: trunk/main/cel.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/cel.c?view=diff&rev=419520&r1=419519&r2=419520
==============================================================================
--- trunk/main/cel.c (original)
+++ trunk/main/cel.c Thu Jul 24 17:48:38 2014
@@ -946,7 +946,7 @@
 	r->application_name = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_APPNAME), "");
 	r->application_data = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_APPDATA), "");
 	r->account_code     = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_ACCTCODE), "");
-	r->peer_account     = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_ACCTCODE), "");
+	r->peer_account     = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_PEERACCT), "");
 	r->unique_id        = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_UNIQUEID), "");
 	r->linked_id        = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_LINKEDID), "");
 	r->amaflag          = ast_event_get_ie_uint(e, AST_EVENT_IE_CEL_AMAFLAGS);

Modified: trunk/main/channel.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/channel.c?view=diff&rev=419520&r1=419519&r2=419520
==============================================================================
--- trunk/main/channel.c (original)
+++ trunk/main/channel.c Thu Jul 24 17:48:38 2014
@@ -5549,9 +5549,12 @@
 		if (oh->parent_channel) {
 			call_forward_inherit(new_chan, oh->parent_channel, orig);
 		}
-		if (oh->account) {
+		if (!ast_strlen_zero(oh->account)) {
 			ast_channel_lock(new_chan);
+			ast_channel_stage_snapshot(new_chan);
 			ast_channel_accountcode_set(new_chan, oh->account);
+			ast_channel_peeraccount_set(new_chan, oh->account);
+			ast_channel_stage_snapshot_done(new_chan);
 			ast_channel_unlock(new_chan);
 		}
 	} else if (caller) { /* no outgoing helper so use caller if available */
@@ -5560,9 +5563,9 @@
 	ast_set_flag(ast_channel_flags(new_chan), AST_FLAG_ORIGINATED);
 
 	ast_channel_lock_both(orig, new_chan);
-	ast_channel_accountcode_set(new_chan, ast_channel_accountcode(orig));
 	ast_party_connected_line_copy(ast_channel_connected(new_chan), ast_channel_connected(orig));
 	ast_party_redirecting_copy(ast_channel_redirecting(new_chan), ast_channel_redirecting(orig));
+	ast_channel_req_accountcodes(new_chan, orig, AST_CHANNEL_REQUESTOR_REPLACEMENT);
 	ast_channel_unlock(new_chan);
 	ast_channel_unlock(orig);
 
@@ -5625,9 +5628,12 @@
 			ast_channel_unlock(oh->parent_channel);
 			ast_channel_unlock(chan);
 		}
-		if (oh->account) {
+		if (!ast_strlen_zero(oh->account)) {
 			ast_channel_lock(chan);
+			ast_channel_stage_snapshot(chan);
 			ast_channel_accountcode_set(chan, oh->account);
+			ast_channel_peeraccount_set(chan, oh->account);
+			ast_channel_stage_snapshot_done(chan);
 			ast_channel_unlock(chan);
 		}
 	}
@@ -5655,6 +5661,12 @@
 		connected.id.name.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
 	}
 	ast_channel_set_connected_line(chan, &connected, NULL);
+	if (requestor) {
+		ast_channel_lock_both(chan, (struct ast_channel *) requestor);
+		ast_channel_req_accountcodes(chan, requestor, AST_CHANNEL_REQUESTOR_BRIDGE_PEER);
+		ast_channel_unlock(chan);
+		ast_channel_unlock((struct ast_channel *) requestor);
+	}
 
 	if (ast_call(chan, addr, 0)) {	/* ast_call failed... */
 		ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, addr);
@@ -5880,15 +5892,20 @@
 			return NULL;
 		}
 
-		/* Set newly created channel callid to same as the requestor */
 		if (requestor) {
-			struct ast_callid *callid = ast_channel_callid(requestor);
+			struct ast_callid *callid;
+
+			ast_channel_lock_both(c, (struct ast_channel *) requestor);
+
+			/* Set the newly created channel's callid to the same as the requestor. */
+			callid = ast_channel_callid(requestor);
 			if (callid) {
-				ast_channel_lock(c);
 				ast_channel_callid_set(c, callid);
-				ast_channel_unlock(c);
 				callid = ast_callid_unref(callid);
 			}
+
+			ast_channel_unlock(c);
+			ast_channel_unlock((struct ast_channel *) requestor);
 		}
 
 		ao2_ref(joint_cap, -1);
@@ -5909,6 +5926,88 @@
 	AST_RWLIST_UNLOCK(&backends);
 
 	return NULL;
+}
+
+/*!
+ * \internal
+ * \brief Setup new channel accountcodes from the requestor channel after ast_request().
+ * \since 13.0.0
+ *
+ * \param chan New channel to get accountcodes setup.
+ * \param requestor Requesting channel to get accountcodes from.
+ * \param relationship What the new channel was created for.
+ * \param precious TRUE if pre-existing accountcodes on chan will not be overwritten.
+ *
+ * \pre The chan and requestor channels are already locked.
+ *
+ * \return Nothing
+ */
+static void channel_req_accountcodes(struct ast_channel *chan, const struct ast_channel *requestor, enum ast_channel_requestor_relationship relationship, int precious)
+{
+	/*
+	 * The primary reason for the existence of this function is
+	 * so local channels can propagate accountcodes to the ;2
+	 * channel before ast_call().
+	 *
+	 * The secondary reason is to propagate the CHANNEL(peeraccount)
+	 * value set before Dial, FollowMe, and Queue while maintaining
+	 * the historic straight across accountcode propagation as a
+	 * fallback.
+	 */
+	switch (relationship) {
+	case AST_CHANNEL_REQUESTOR_BRIDGE_PEER:
+		/* Crossover the requestor's accountcode and peeraccount */
+		if (!precious || ast_strlen_zero(ast_channel_accountcode(chan))) {
+			/*
+			 * The newly created channel does not have an accountcode
+			 * or we don't care.
+			 */
+			if (!ast_strlen_zero(ast_channel_peeraccount(requestor))) {
+				/*
+				 * Set it to the requestor's peeraccount.  This allows the
+				 * dialplan to indicate the accountcode to use when dialing
+				 * by setting CHANNEL(peeraccount).
+				 */
+				ast_channel_accountcode_set(chan, ast_channel_peeraccount(requestor));
+			} else if (!precious
+				&& !ast_strlen_zero(ast_channel_accountcode(requestor))) {
+				/*
+				 * Fallback to the historic propagation and set it to the
+				 * requestor's accountcode.
+				 */
+				ast_channel_accountcode_set(chan, ast_channel_accountcode(requestor));
+			}
+		}
+		if (!ast_strlen_zero(ast_channel_accountcode(requestor))) {
+			ast_channel_peeraccount_set(chan, ast_channel_accountcode(requestor));
+		}
+		break;
+	case AST_CHANNEL_REQUESTOR_REPLACEMENT:
+		/* Pass the requestor's accountcode and peeraccount straight. */
+		if (!precious || ast_strlen_zero(ast_channel_accountcode(chan))) {
+			/*
+			 * The newly created channel does not have an accountcode
+			 * or we don't care.
+			 */
+			if (!ast_strlen_zero(ast_channel_accountcode(requestor))) {
+				ast_channel_accountcode_set(chan, ast_channel_accountcode(requestor));
+			}
+		}
+		if (!ast_strlen_zero(ast_channel_peeraccount(requestor))) {
+			ast_channel_peeraccount_set(chan, ast_channel_peeraccount(requestor));
+		}
+		break;
+	}
+}
+
+void ast_channel_req_accountcodes(struct ast_channel *chan, const struct ast_channel *requestor, enum ast_channel_requestor_relationship relationship)
+{
+	channel_req_accountcodes(chan, requestor, relationship, 0);
+}
+
+void ast_channel_req_accountcodes_precious(struct ast_channel *chan, const struct ast_channel *requestor, enum ast_channel_requestor_relationship relationship)
+{
+	channel_req_accountcodes(chan, requestor, relationship, 1);
 }
 
 int ast_pre_call(struct ast_channel *chan, const char *sub_args)

Modified: trunk/main/core_unreal.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/core_unreal.c?view=diff&rev=419520&r1=419519&r2=419520
==============================================================================
--- trunk/main/core_unreal.c (original)
+++ trunk/main/core_unreal.c Thu Jul 24 17:48:38 2014
@@ -36,6 +36,7 @@
 
 #include "asterisk/causes.h"
 #include "asterisk/channel.h"
+#include "asterisk/stasis_channels.h"
 #include "asterisk/pbx.h"
 #include "asterisk/musiconhold.h"
 #include "asterisk/astobj2.h"
@@ -100,6 +101,7 @@
 	struct ast_unreal_pvt *p;
 	struct ast_channel *otherchan = NULL;
 	ast_chan_write_info_t *write_info;
+	char *info_data;
 
 	if (option != AST_OPTION_CHANNEL_WRITE) {
 		return -1;
@@ -112,10 +114,19 @@
 		return -1;
 	}
 
-	if (!strcmp(write_info->function, "CHANNEL")
-		&& !strncasecmp(write_info->data, "hangup_handler_", 15)) {
-		/* Block CHANNEL(hangup_handler_xxx) writes to the other unreal channel. */
-		return 0;
+	info_data = write_info->data;
+	if (!strcmp(write_info->function, "CHANNEL")) {
+		if (!strncasecmp(info_data, "hangup_handler_", 15)) {
+			/* Block CHANNEL(hangup_handler_xxx) writes to the other unreal channel. */
+			return 0;
+		}
+
+		/* Crossover the accountcode and peeraccount to cross the unreal bridge. */
+		if (!strcasecmp(info_data, "accountcode")) {
+			info_data = "peeraccount";
+		} else if (!strcasecmp(info_data, "peeraccount")) {
+			info_data = "accountcode";
+		}
 	}
 
 	/* get the tech pvt */
@@ -140,7 +151,7 @@
 	ao2_unlock(p);
 
 	ast_channel_lock(otherchan);
-	res = write_info->write_fn(otherchan, write_info->function, write_info->data, write_info->value);
+	res = write_info->write_fn(otherchan, write_info->function, info_data, write_info->value);
 	ast_channel_unlock(otherchan);
 
 setoption_cleanup:
@@ -642,6 +653,8 @@
 	struct ast_var_t *varptr;
 	struct ast_var_t *clone_var;
 
+	ast_channel_stage_snapshot(semi2);
+
 	/*
 	 * Note that cid_num and cid_name aren't passed in the
 	 * ast_channel_alloc calls in ast_unreal_new_channels().  It's
@@ -651,11 +664,16 @@
 
 	ast_party_dialed_copy(ast_channel_dialed(semi2), ast_channel_dialed(semi1));
 
+	/* Crossover the CallerID and conected-line to cross the unreal bridge. */
 	ast_connected_line_copy_to_caller(ast_channel_caller(semi2), ast_channel_connected(semi1));
 	ast_connected_line_copy_from_caller(ast_channel_connected(semi2), ast_channel_caller(semi1));
 
 	ast_channel_language_set(semi2, ast_channel_language(semi1));
-	ast_channel_accountcode_set(semi2, ast_channel_accountcode(semi1));
+
+	/* Crossover the accountcode and peeraccount to cross the unreal bridge. */
+	ast_channel_accountcode_set(semi2, ast_channel_peeraccount(semi1));
+	ast_channel_peeraccount_set(semi2, ast_channel_accountcode(semi1));
+
 	ast_channel_musicclass_set(semi2, ast_channel_musicclass(semi1));
 
 	ast_channel_cc_params_init(semi2, ast_channel_get_cc_config_params(semi1));
@@ -682,6 +700,8 @@
 		}
 	}
 	ast_channel_datastore_inherit(semi1, semi2);
+
+	ast_channel_stage_snapshot_done(semi2);
 }
 
 int ast_unreal_channel_push_to_bridge(struct ast_channel *ast, struct ast_bridge *bridge, unsigned int flags)

Modified: trunk/main/dial.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/dial.c?view=diff&rev=419520&r1=419519&r2=419520
==============================================================================
--- trunk/main/dial.c (original)
+++ trunk/main/dial.c Thu Jul 24 17:48:38 2014
@@ -318,7 +318,12 @@
 	cap_request = NULL;
 	ao2_cleanup(cap_all_audio);
 
-	ast_channel_lock(channel->owner);
+	if (chan) {
+		ast_channel_lock_both(chan, channel->owner);
+	} else {
+		ast_channel_lock(channel->owner);
+	}
+
 	ast_channel_stage_snapshot(channel->owner);
 
 	ast_channel_appl_set(channel->owner, "AppDial2");
@@ -339,12 +344,13 @@
 		ast_connected_line_copy_from_caller(ast_channel_connected(channel->owner), ast_channel_caller(chan));
 
 		ast_channel_language_set(channel->owner, ast_channel_language(chan));
-		ast_channel_accountcode_set(channel->owner, ast_channel_accountcode(chan));
+		ast_channel_req_accountcodes(channel->owner, chan, AST_CHANNEL_REQUESTOR_BRIDGE_PEER);
 		if (ast_strlen_zero(ast_channel_musicclass(channel->owner)))
 			ast_channel_musicclass_set(channel->owner, ast_channel_musicclass(chan));
 
 		ast_channel_adsicpe_set(channel->owner, ast_channel_adsicpe(chan));
 		ast_channel_transfercapability_set(channel->owner, ast_channel_transfercapability(chan));
+		ast_channel_unlock(chan);
 	}
 
 	ast_channel_stage_snapshot_done(channel->owner);

Modified: trunk/main/pbx.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/pbx.c?view=diff&rev=419520&r1=419519&r2=419520
==============================================================================
--- trunk/main/pbx.c (original)
+++ trunk/main/pbx.c Thu Jul 24 17:48:38 2014
@@ -10347,8 +10347,11 @@
 	if (vars) {
 		ast_set_variables(dialed, vars);
 	}
-	if (account) {
+	if (!ast_strlen_zero(account)) {
+		ast_channel_stage_snapshot(dialed);
 		ast_channel_accountcode_set(dialed, account);
+		ast_channel_peeraccount_set(dialed, account);
+		ast_channel_stage_snapshot_done(dialed);
 	}
 	ast_set_flag(ast_channel_flags(dialed), AST_FLAG_ORIGINATED);
 	ast_channel_unlock(dialed);

Modified: trunk/res/parking/parking_bridge_features.c
URL: http://svnview.digium.com/svn/asterisk/trunk/res/parking/parking_bridge_features.c?view=diff&rev=419520&r1=419519&r2=419520
==============================================================================
--- trunk/res/parking/parking_bridge_features.c (original)
+++ trunk/res/parking/parking_bridge_features.c Thu Jul 24 17:48:38 2014
@@ -235,6 +235,7 @@
 
 	/* Before we actually dial out let's inherit appropriate information. */
 	ast_channel_lock_both(parker, parkee);
+	ast_channel_req_accountcodes(parkee, parker, AST_CHANNEL_REQUESTOR_REPLACEMENT);
 	ast_connected_line_copy_from_caller(ast_channel_connected(parkee), ast_channel_caller(parker));
 	ast_channel_inherit_variables(parker, parkee);
 	ast_channel_datastore_inherit(parker, parkee);




More information about the svn-commits mailing list