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
changes/97/197/1
Richard Mudgett 11 years ago
parent 7059b001ad
commit a2ce95d9d2

@ -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

@ -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.

@ -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));
}

@ -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);

@ -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)) {

@ -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

@ -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);

@ -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);

@ -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);

@ -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);

@ -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)

@ -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);

@ -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);

@ -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);

Loading…
Cancel
Save