diff options
-rw-r--r-- | channels/chan_sip.c | 4 | ||||
-rw-r--r-- | main/features.c | 74 |
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)) { |