summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--channels/chan_sip.c4
-rw-r--r--main/features.c74
2 files changed, 47 insertions, 31 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 2a4f8b31d..513de4285 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -24389,7 +24389,7 @@ static int handle_request_refer(struct sip_pvt *p, struct sip_request *req, int
sip_pvt_unlock(p);
/* Parking a call. DO NOT hold any locks while calling ast_parking_ext_valid() */
- if (localtransfer && ast_parking_ext_valid(refer_to, current.chan1, ast_channel_context(current.chan1))) {
+ if (localtransfer && ast_parking_ext_valid(refer_to, current.chan1, refer_to_context)) {
sip_pvt_lock(p);
ast_clear_flag(&p->flags[0], SIP_GOTREFER);
p->refer->status = REFER_200OK;
@@ -24418,7 +24418,7 @@ static int handle_request_refer(struct sip_pvt *p, struct sip_request *req, int
}
/* DO NOT hold any locks while calling sip_park */
- if (sip_park(current.chan2, current.chan1, req, seqno, refer_to, ast_channel_context(current.chan1))) {
+ if (sip_park(current.chan2, current.chan1, req, seqno, refer_to, refer_to_context)) {
sip_pvt_lock(p);
transmit_notify_with_sipfrag(p, seqno, "500 Internal Server Error", TRUE);
} else {
diff --git a/main/features.c b/main/features.c
index d3c98a474..96f76d9cb 100644
--- a/main/features.c
+++ b/main/features.c
@@ -784,6 +784,7 @@ static struct ast_exten *get_parking_exten(const char *exten_str, struct ast_cha
struct pbx_find_info q = { .stacklen = 0 }; /* the rest is reset in pbx_find_extension */
const char *app_at_exten;
+ ast_debug(4, "Checking if %s@%s is a parking exten\n", exten_str, context);
exten = pbx_find_extension(chan, NULL, &q, context, exten_str, 1, NULL, NULL,
E_MATCH);
if (!exten) {
@@ -1388,7 +1389,7 @@ static struct parkeduser *park_space_reserve(struct ast_channel *park_me, struct
static int park_call_full(struct ast_channel *chan, struct ast_channel *peer, struct ast_park_call_args *args)
{
struct parkeduser *pu = args->pu;
- const char *event_from;
+ const char *event_from; /*!< Channel name that is parking the call. */
char app_data[AST_MAX_EXTENSION + AST_MAX_CONTEXT];
if (pu == NULL) {
@@ -1407,10 +1408,10 @@ static int park_call_full(struct ast_channel *chan, struct ast_channel *peer, st
if (chan != peer) {
if (ast_test_flag(args, AST_PARK_OPT_RINGING)) {
pu->hold_method = AST_CONTROL_RINGING;
- ast_indicate(pu->chan, AST_CONTROL_RINGING);
+ ast_indicate(chan, AST_CONTROL_RINGING);
} else {
pu->hold_method = AST_CONTROL_HOLD;
- ast_indicate_data(pu->chan, AST_CONTROL_HOLD,
+ ast_indicate_data(chan, AST_CONTROL_HOLD,
S_OR(pu->parkinglot->cfg.mohclass, NULL),
!ast_strlen_zero(pu->parkinglot->cfg.mohclass) ? strlen(pu->parkinglot->cfg.mohclass) + 1 : 0);
}
@@ -1421,7 +1422,9 @@ static int park_call_full(struct ast_channel *chan, struct ast_channel *peer, st
if (args->extout)
*(args->extout) = pu->parkingnum;
- if (peer) {
+ if (peer) {
+ event_from = S_OR(args->orig_chan_name, ast_channel_name(peer));
+
/*
* This is so ugly that it hurts, but implementing
* get_base_channel() on local channels could have ugly side
@@ -1436,7 +1439,7 @@ static int park_call_full(struct ast_channel *chan, struct ast_channel *peer, st
char other_side[AST_CHANNEL_NAME];
char *c;
- ast_copy_string(other_side, S_OR(args->orig_chan_name, ast_channel_name(peer)), sizeof(other_side));
+ ast_copy_string(other_side, event_from, sizeof(other_side));
if ((c = strrchr(other_side, ';'))) {
*++c = '1';
}
@@ -1449,8 +1452,11 @@ static int park_call_full(struct ast_channel *chan, struct ast_channel *peer, st
tmpchan = ast_channel_unref(tmpchan);
}
} else {
- ast_copy_string(pu->peername, S_OR(args->orig_chan_name, ast_channel_name(peer)), sizeof(pu->peername));
+ ast_copy_string(pu->peername, event_from, sizeof(pu->peername));
}
+ } else {
+ event_from = S_OR(pbx_builtin_getvar_helper(chan, "BLINDTRANSFER"),
+ ast_channel_name(chan));
}
/*
@@ -1486,18 +1492,12 @@ static int park_call_full(struct ast_channel *chan, struct ast_channel *peer, st
/* Wake up the (presumably select()ing) thread */
pthread_kill(parking_thread, SIGURG);
ast_verb(2, "Parked %s on %d (lot %s). Will timeout back to extension [%s] %s, %d in %d seconds\n",
- ast_channel_name(pu->chan), pu->parkingnum, pu->parkinglot->name,
+ ast_channel_name(chan), pu->parkingnum, pu->parkinglot->name,
pu->context, pu->exten, pu->priority, (pu->parkingtime / 1000));
- ast_cel_report_event(pu->chan, AST_CEL_PARK_START, NULL, pu->parkinglot->name, peer);
+ ast_cel_report_event(chan, AST_CEL_PARK_START, NULL, pu->parkinglot->name, peer);
- if (peer) {
- event_from = ast_channel_name(peer);
- } else {
- event_from = pbx_builtin_getvar_helper(chan, "BLINDTRANSFER");
- }
-
- ast_manager_event(pu->chan, EVENT_FLAG_CALL, "ParkedCall",
+ ast_manager_event(chan, EVENT_FLAG_CALL, "ParkedCall",
"Exten: %s\r\n"
"Channel: %s\r\n"
"Parkinglot: %s\r\n"
@@ -1508,14 +1508,19 @@ static int park_call_full(struct ast_channel *chan, struct ast_channel *peer, st
"ConnectedLineNum: %s\r\n"
"ConnectedLineName: %s\r\n"
"Uniqueid: %s\r\n",
- pu->parkingexten, ast_channel_name(pu->chan), pu->parkinglot->name, event_from ? event_from : "",
+ pu->parkingexten, ast_channel_name(chan), pu->parkinglot->name, event_from,
(long)pu->start.tv_sec + (long)(pu->parkingtime/1000) - (long)time(NULL),
- S_COR(pu->chan->caller.id.number.valid, pu->chan->caller.id.number.str, "<unknown>"),
- S_COR(pu->chan->caller.id.name.valid, pu->chan->caller.id.name.str, "<unknown>"),
- S_COR(pu->chan->connected.id.number.valid, pu->chan->connected.id.number.str, "<unknown>"),
- S_COR(pu->chan->connected.id.name.valid, pu->chan->connected.id.name.str, "<unknown>"),
- ast_channel_uniqueid(pu->chan)
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, "<unknown>"),
+ S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, "<unknown>"),
+ S_COR(chan->connected.id.number.valid, chan->connected.id.number.str, "<unknown>"),
+ S_COR(chan->connected.id.name.valid, chan->connected.id.name.str, "<unknown>"),
+ ast_channel_uniqueid(chan)
);
+ ast_debug(4, "peer: %s\n", peer ? ast_channel_name(peer) : "-No peer-");
+ ast_debug(4, "args->orig_chan_name: %s\n", args->orig_chan_name ? args->orig_chan_name : "-none-");
+ ast_debug(4, "pu->peername: %s\n", pu->peername);
+ ast_debug(4, "AMI ParkedCall Channel: %s\n", ast_channel_name(chan));
+ ast_debug(4, "AMI ParkedCall From: %s\n", event_from);
if (peer && adsipark && ast_adsi_available(peer)) {
adsi_announce_park(peer, pu->parkingexten); /* Only supports parking numbers */
@@ -1550,7 +1555,7 @@ static int park_call_full(struct ast_channel *chan, struct ast_channel *peer, st
if (peer == chan) { /* pu->notquiteyet = 1 */
/* Wake up parking thread if we're really done */
pu->hold_method = AST_CONTROL_HOLD;
- ast_indicate_data(pu->chan, AST_CONTROL_HOLD,
+ ast_indicate_data(chan, AST_CONTROL_HOLD,
S_OR(pu->parkinglot->cfg.mohclass, NULL),
!ast_strlen_zero(pu->parkinglot->cfg.mohclass) ? strlen(pu->parkinglot->cfg.mohclass) + 1 : 0);
pu->notquiteyet = 0;
@@ -3877,6 +3882,10 @@ int ast_bridge_call(struct ast_channel *chan, struct ast_channel *peer, struct a
pbx_builtin_setvar_helper(chan, "BRIDGEPEER", ast_channel_name(peer));
pbx_builtin_setvar_helper(peer, "BRIDGEPEER", ast_channel_name(chan));
+ /* Clear any BLINDTRANSFER since the transfer has completed. */
+ pbx_builtin_setvar_helper(chan, "BLINDTRANSFER", NULL);
+ pbx_builtin_setvar_helper(peer, "BLINDTRANSFER", NULL);
+
set_bridge_features_on_config(config, pbx_builtin_getvar_helper(chan, "BRIDGE_FEATURES"));
add_features_datastores(chan, peer, config);
@@ -4920,13 +4929,7 @@ END_OPTIONS );
/*! \brief Park a call */
static int park_call_exec(struct ast_channel *chan, const char *data)
{
- /* Cache the original channel name in case we get masqueraded in the middle
- * of a park--it is still theoretically possible for a transfer to happen before
- * we get here, but it is _really_ unlikely */
- char *orig_chan_name = ast_strdupa(ast_channel_name(chan));
- struct ast_park_call_args args = {
- .orig_chan_name = orig_chan_name,
- };
+ struct ast_park_call_args args = { 0, };
struct ast_flags flags = { 0 };
char orig_exten[AST_MAX_EXTENSION];
int orig_priority;
@@ -4935,6 +4938,19 @@ static int park_call_exec(struct ast_channel *chan, const char *data)
char *parse;
struct park_app_args app_args;
+ /*
+ * Cache the original channel name because we are going to
+ * masquerade the channel. Prefer the BLINDTRANSFER channel
+ * name over this channel name. BLINDTRANSFER could be set if
+ * the parking access extension did not get detected and we are
+ * executing the Park application from the dialplan.
+ *
+ * The orig_chan_name is used to return the call to the
+ * originator on parking timeout.
+ */
+ args.orig_chan_name = ast_strdupa(S_OR(
+ pbx_builtin_getvar_helper(chan, "BLINDTRANSFER"), ast_channel_name(chan)));
+
/* Answer if call is not up */
if (ast_channel_state(chan) != AST_STATE_UP) {
if (ast_answer(chan)) {