summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Mudgett <rmudgett@digium.com>2014-07-24 22:48:38 +0000
committerRichard Mudgett <rmudgett@digium.com>2014-07-24 22:48:38 +0000
commita2ce95d9d2be8f4c14c018ccbc1cb81dfd33ab5c (patch)
treee4de2fd5029ce0b75d2144d4570a00ea6275cfc4
parent7059b001adb2583e1b6b2bb667d538df2fb3709b (diff)
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/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@419520 65c4cc65-6c06-0410-ace0-fbb531ad65f3
-rw-r--r--CHANGES26
-rw-r--r--UPGRADE.txt7
-rw-r--r--apps/app_dial.c6
-rw-r--r--apps/app_followme.c2
-rw-r--r--apps/app_queue.c4
-rw-r--r--include/asterisk/channel.h39
-rw-r--r--main/bridge.c9
-rw-r--r--main/bridge_basic.c7
-rw-r--r--main/cel.c2
-rw-r--r--main/channel.c113
-rw-r--r--main/core_unreal.c32
-rw-r--r--main/dial.c10
-rw-r--r--main/pbx.c5
-rw-r--r--res/parking/parking_bridge_features.c1
14 files changed, 239 insertions, 24 deletions
diff --git a/CHANGES b/CHANGES
index 788a1141c..877014736 100644
--- a/CHANGES
+++ b/CHANGES
@@ -12,6 +12,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
------------------
* This module was deprecated and has been removed. Users of app_dahdibarge
diff --git a/UPGRADE.txt b/UPGRADE.txt
index 535782a86..37160c436 100644
--- a/UPGRADE.txt
+++ b/UPGRADE.txt
@@ -57,6 +57,13 @@ From 12 to 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.
diff --git a/apps/app_dial.c b/apps/app_dial.c
index df9b72aaf..b48a226c7 100644
--- a/apps/app_dial.c
+++ b/apps/app_dial.c
@@ -956,7 +956,7 @@ static void do_forward(struct chanlist *o, struct cause_args *num,
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 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast
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));
}
diff --git a/apps/app_followme.c b/apps/app_followme.c
index 1fb22b185..1355361e2 100644
--- a/apps/app_followme.c
+++ b/apps/app_followme.c
@@ -1070,7 +1070,7 @@ static struct ast_channel *findmeexec(struct fm_args *tpargs, struct ast_channel
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);
diff --git a/apps/app_queue.c b/apps/app_queue.c
index fe6b00ab0..0b53ea619 100644
--- a/apps/app_queue.c
+++ b/apps/app_queue.c
@@ -4125,6 +4125,8 @@ static int ring_entry(struct queue_ent *qe, struct callattempt *tmp, int *busies
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 @@ static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callatte
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)) {
diff --git a/include/asterisk/channel.h b/include/asterisk/channel.h
index d5d32c921..08f4effe6 100644
--- a/include/asterisk/channel.h
+++ b/include/asterisk/channel.h
@@ -1387,6 +1387,45 @@ struct ast_channel *ast_channel_release(struct ast_channel *chan);
*/
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
* by the low level module and attempt to place a call on it
diff --git a/main/bridge.c b/main/bridge.c
index d5fc1699a..45b42380a 100644
--- a/main/bridge.c
+++ b/main/bridge.c
@@ -3793,7 +3793,11 @@ static enum ast_transfer_result blind_transfer_bridge(struct ast_channel *transf
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 @@ static enum ast_transfer_result attended_transfer_bridge(struct ast_channel *cha
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);
diff --git a/main/bridge_basic.c b/main/bridge_basic.c
index cb8c2f992..0d95d83d2 100644
--- a/main/bridge_basic.c
+++ b/main/bridge_basic.c
@@ -2982,11 +2982,18 @@ static struct ast_channel *dial_transfer(struct ast_channel *caller, const char
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);
diff --git a/main/cel.c b/main/cel.c
index a3005af8b..4be13511c 100644
--- a/main/cel.c
+++ b/main/cel.c
@@ -946,7 +946,7 @@ int ast_cel_fill_record(const struct ast_event *e, struct ast_cel_event_record *
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);
diff --git a/main/channel.c b/main/channel.c
index e9e37c0fd..4ce4e916f 100644
--- a/main/channel.c
+++ b/main/channel.c
@@ -5549,9 +5549,12 @@ struct ast_channel *ast_call_forward(struct ast_channel *caller, struct ast_chan
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 @@ struct ast_channel *ast_call_forward(struct ast_channel *caller, struct ast_chan
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 @@ struct ast_channel *__ast_request_and_dial(const char *type, struct ast_format_c
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 @@ struct ast_channel *__ast_request_and_dial(const char *type, struct ast_format_c
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 @@ struct ast_channel *ast_request(const char *type, struct ast_format_cap *request
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);
@@ -5911,6 +5928,88 @@ struct ast_channel *ast_request(const char *type, struct ast_format_cap *request
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)
{
int (*pre_call)(struct ast_channel *chan, const char *sub_args);
diff --git a/main/core_unreal.c b/main/core_unreal.c
index a1ae897b9..b3dc5281c 100644
--- a/main/core_unreal.c
+++ b/main/core_unreal.c
@@ -36,6 +36,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#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 @@ int ast_unreal_setoption(struct ast_channel *ast, int option, void *data, int da
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 @@ int ast_unreal_setoption(struct ast_channel *ast, int option, void *data, int da
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 @@ int ast_unreal_setoption(struct ast_channel *ast, int option, void *data, int da
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 @@ void ast_unreal_call_setup(struct ast_channel *semi1, struct ast_channel *semi2)
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 @@ void ast_unreal_call_setup(struct ast_channel *semi1, struct ast_channel *semi2)
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 @@ void ast_unreal_call_setup(struct ast_channel *semi1, struct ast_channel *semi2)
}
}
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)
diff --git a/main/dial.c b/main/dial.c
index afee5eeca..04249fd71 100644
--- a/main/dial.c
+++ b/main/dial.c
@@ -318,7 +318,12 @@ static int begin_dial_prerun(struct ast_dial_channel *channel, struct ast_channe
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 @@ static int begin_dial_prerun(struct ast_dial_channel *channel, struct ast_channe
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);
diff --git a/main/pbx.c b/main/pbx.c
index 389a4c0f5..48fd119f5 100644
--- a/main/pbx.c
+++ b/main/pbx.c
@@ -10347,8 +10347,11 @@ static int pbx_outgoing_attempt(const char *type, struct ast_format_cap *cap,
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);
diff --git a/res/parking/parking_bridge_features.c b/res/parking/parking_bridge_features.c
index 8f563f7cf..61cb85f00 100644
--- a/res/parking/parking_bridge_features.c
+++ b/res/parking/parking_bridge_features.c
@@ -235,6 +235,7 @@ static struct ast_channel *park_local_transfer(struct ast_channel *parker, const
/* 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);