mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-04-13 07:45:26 +00:00
fix att-xfer...AGAIN
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@15133 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
parent
e6ea90cebf
commit
7681f944b4
@ -262,6 +262,9 @@ SWITCH_DECLARE(switch_event_header_t *) switch_channel_variable_first(switch_cha
|
||||
*/
|
||||
SWITCH_DECLARE(void) switch_channel_variable_last(switch_channel_t *channel);
|
||||
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_channel_caller_extension_masquerade(switch_channel_t *orig_channel, switch_channel_t *new_channel, uint32_t offset);
|
||||
|
||||
/*!
|
||||
\brief Assign a caller extension to a given channel
|
||||
\param channel channel to assign extension to
|
||||
|
@ -4272,9 +4272,7 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t
|
||||
switch_channel_set_variable(channel_b, SWITCH_HOLDING_UUID_VARIABLE, br_a);
|
||||
switch_channel_set_flag(channel_b, CF_XFER_ZOMBIE);
|
||||
switch_channel_set_flag(channel_b, CF_TRANSFER);
|
||||
|
||||
//switch_channel_set_variable(channel_b, "park_timeout", "2");
|
||||
//switch_channel_set_state(channel_b, CS_PARK);
|
||||
|
||||
|
||||
if ((a_session = switch_core_session_locate(br_a))) {
|
||||
const char *moh = profile->hold_music;
|
||||
@ -4307,8 +4305,8 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t
|
||||
nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1), SIPTAG_CONTENT_TYPE_STR("message/sipfrag"),
|
||||
NUTAG_SUBSTATE(nua_substate_terminated), SIPTAG_PAYLOAD_STR("SIP/2.0 200 OK"), SIPTAG_EVENT_STR(etmp), TAG_END());
|
||||
|
||||
|
||||
if (0 && b_tech_pvt) {
|
||||
|
||||
if (1 && b_tech_pvt) {
|
||||
sofia_set_flag_locked(b_tech_pvt, TFLAG_BYE);
|
||||
nua_bye(b_tech_pvt->nh,
|
||||
SIPTAG_REASON_STR("Q.850;cause=16;text=\"normal_clearing\""),
|
||||
|
@ -1664,6 +1664,72 @@ SWITCH_DECLARE(void) switch_channel_clear_state_handler(switch_channel_t *channe
|
||||
switch_mutex_unlock(channel->state_mutex);
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_channel_caller_extension_masquerade(switch_channel_t *orig_channel, switch_channel_t *new_channel, uint32_t offset)
|
||||
{
|
||||
switch_caller_profile_t *caller_profile;
|
||||
switch_caller_extension_t *extension = NULL, *orig_extension = NULL;
|
||||
switch_caller_application_t *ap;
|
||||
switch_status_t status = SWITCH_STATUS_FALSE;
|
||||
switch_event_header_t *hi = NULL;
|
||||
const char *no_copy = switch_channel_get_variable(orig_channel, "attended_transfer_no_copy");
|
||||
char *dup;
|
||||
int i, argc = 0;
|
||||
char *argv[128];
|
||||
|
||||
if (no_copy) {
|
||||
dup = switch_core_session_strdup(new_channel->session, no_copy);
|
||||
argc = switch_separate_string(dup, ',', argv, (sizeof(argv) / sizeof(argv[0])));
|
||||
}
|
||||
|
||||
|
||||
switch_mutex_lock(orig_channel->profile_mutex);
|
||||
switch_mutex_lock(new_channel->profile_mutex);
|
||||
|
||||
|
||||
caller_profile = switch_caller_profile_clone(new_channel->session, new_channel->caller_profile);
|
||||
switch_assert(caller_profile);
|
||||
extension = switch_caller_extension_new(new_channel->session, caller_profile->destination_number, caller_profile->destination_number);
|
||||
orig_extension = switch_channel_get_caller_extension(orig_channel);
|
||||
|
||||
|
||||
if (extension && orig_extension) {
|
||||
for(ap = orig_extension->current_application; ap && offset > 0; offset--) {
|
||||
ap = ap->next;
|
||||
}
|
||||
|
||||
for (; ap; ap = ap->next) {
|
||||
switch_caller_extension_add_application(new_channel->session, extension, ap->application_name, ap->application_data);
|
||||
}
|
||||
|
||||
caller_profile->destination_number = switch_core_strdup(caller_profile->pool, orig_channel->caller_profile->destination_number);
|
||||
switch_channel_set_caller_profile(new_channel, caller_profile);
|
||||
switch_channel_set_caller_extension(new_channel, extension);
|
||||
|
||||
for (hi = orig_channel->variables->headers; hi; hi = hi->next) {
|
||||
int ok = 1;
|
||||
for (i = 0; i < argc; i++) {
|
||||
if (!strcasecmp(argv[i], hi->name)) {
|
||||
ok = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ok) continue;
|
||||
|
||||
switch_channel_set_variable(new_channel, hi->name, hi->value);
|
||||
}
|
||||
|
||||
status = SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
switch_mutex_unlock(new_channel->profile_mutex);
|
||||
switch_mutex_unlock(orig_channel->profile_mutex);
|
||||
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(void) switch_channel_set_caller_extension(switch_channel_t *channel, switch_caller_extension_t *caller_extension)
|
||||
{
|
||||
switch_assert(channel != NULL);
|
||||
|
@ -569,7 +569,8 @@ static switch_status_t audio_bridge_on_exchange_media(switch_core_session_t *ses
|
||||
} else if (state < CS_HANGUP && (var = switch_channel_get_variable(channel, SWITCH_TRANSFER_AFTER_BRIDGE_VARIABLE))) {
|
||||
transfer_after_bridge(session, var);
|
||||
} else {
|
||||
if (!switch_channel_test_flag(channel, CF_TRANSFER) && !switch_channel_test_flag(channel, CF_REDIRECT) && bd && !bd->clean_exit
|
||||
if (!switch_channel_test_flag(channel, CF_TRANSFER) && !switch_channel_test_flag(channel, CF_REDIRECT) &&
|
||||
!switch_channel_test_flag(channel, CF_XFER_ZOMBIE) && bd && !bd->clean_exit
|
||||
&& state != CS_PARK && state != CS_ROUTING && !switch_channel_test_flag(channel, CF_INNER_BRIDGE)) {
|
||||
switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
|
||||
}
|
||||
@ -1082,8 +1083,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_multi_threaded_bridge(switch_core_ses
|
||||
|
||||
state = switch_channel_get_state(caller_channel);
|
||||
|
||||
if (!switch_channel_test_flag(caller_channel, CF_TRANSFER) && !switch_channel_test_flag(caller_channel, CF_REDIRECT)
|
||||
&& !a_leg->clean_exit && !inner_bridge) {
|
||||
if (!switch_channel_test_flag(caller_channel, CF_TRANSFER) && !switch_channel_test_flag(caller_channel, CF_REDIRECT) &&
|
||||
!switch_channel_test_flag(caller_channel, CF_XFER_ZOMBIE) && !a_leg->clean_exit && !inner_bridge) {
|
||||
if ((state != CS_EXECUTE && state != CS_SOFT_EXECUTE && state != CS_PARK && state != CS_ROUTING) ||
|
||||
(switch_channel_test_flag(peer_channel, CF_ANSWERED) && state < CS_HANGUP)) {
|
||||
if (switch_true(switch_channel_get_variable(caller_channel, SWITCH_PARK_AFTER_BRIDGE_VARIABLE))) {
|
||||
|
@ -2078,6 +2078,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
|
||||
if (switch_channel_media_ready(caller_channel)) {
|
||||
tstatus = switch_core_session_read_frame(oglobals.session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
|
||||
if (!SWITCH_READ_ACCEPTABLE(tstatus)) {
|
||||
if (switch_channel_test_flag(caller_channel, CF_XFER_ZOMBIE)) {
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
@ -2133,6 +2136,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
|
||||
}
|
||||
|
||||
if (switch_core_session_write_frame(oglobals.session, &write_frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) {
|
||||
if (switch_channel_test_flag(caller_channel, CF_XFER_ZOMBIE)) {
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -2156,7 +2162,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
|
||||
}
|
||||
}
|
||||
|
||||
if (caller_channel && !switch_channel_ready(caller_channel)) {
|
||||
if (caller_channel && !switch_channel_ready(caller_channel) && !switch_channel_test_flag(caller_channel, CF_XFER_ZOMBIE)) {
|
||||
oglobals.idx = IDX_CANCEL;
|
||||
}
|
||||
|
||||
@ -2206,7 +2212,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
|
||||
const char *context = switch_channel_get_variable(peer_channel, "context");
|
||||
const char *dialplan = switch_channel_get_variable(peer_channel, "dialplan");
|
||||
switch_core_session_t *holding_session;
|
||||
|
||||
|
||||
if (caller_channel) {
|
||||
if (switch_strlen_zero(context)) {
|
||||
context = switch_channel_get_variable(caller_channel, "context");
|
||||
@ -2225,7 +2231,21 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
|
||||
}
|
||||
|
||||
if ((holding_session = switch_core_session_locate(holding))) {
|
||||
switch_ivr_session_transfer(holding_session, dest, dialplan, context);
|
||||
switch_channel_t *holding_channel = switch_core_session_get_channel(holding_session);
|
||||
switch_status_t mstatus = SWITCH_STATUS_FALSE;
|
||||
|
||||
if (caller_channel) {
|
||||
if ((mstatus = switch_channel_caller_extension_masquerade(caller_channel, holding_channel, 1)) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_channel_set_state(holding_channel, CS_RESET);
|
||||
switch_channel_wait_for_state_timeout(holding_channel, CS_RESET, 5000);
|
||||
switch_channel_set_state(holding_channel, CS_EXECUTE);
|
||||
}
|
||||
}
|
||||
|
||||
if (mstatus != SWITCH_STATUS_SUCCESS) {
|
||||
switch_ivr_session_transfer(holding_session, dest, dialplan, context);
|
||||
}
|
||||
|
||||
switch_core_session_rwunlock(holding_session);
|
||||
holding = NULL;
|
||||
holding_session = NULL;
|
||||
@ -2233,6 +2253,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
|
||||
|
||||
switch_channel_hangup(peer_channel, SWITCH_CAUSE_ATTENDED_TRANSFER);
|
||||
switch_core_session_rwunlock(peer_session);
|
||||
force_reason = SWITCH_CAUSE_ATTENDED_TRANSFER;
|
||||
} else {
|
||||
if (peer_channel && switch_channel_ready(peer_channel)) {
|
||||
force_reason = SWITCH_CAUSE_ATTENDED_TRANSFER;
|
||||
@ -2273,9 +2294,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
|
||||
if (i != oglobals.idx) {
|
||||
holding = NULL;
|
||||
|
||||
if (force_reason != SWITCH_CAUSE_NONE) {
|
||||
reason = force_reason;
|
||||
} else if (oglobals.idx == IDX_TIMEOUT || to) {
|
||||
if (oglobals.idx == IDX_TIMEOUT || to) {
|
||||
reason = SWITCH_CAUSE_NO_ANSWER;
|
||||
} else {
|
||||
if (oglobals.idx == IDX_CANCEL) {
|
||||
@ -2437,6 +2456,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(oglobals.session), SWITCH_LOG_DEBUG,
|
||||
"Originate Cancelled by originator termination Cause: %d [%s]\n", *cause, switch_channel_cause2str(*cause));
|
||||
|
||||
} else if (oglobals.idx == IDX_TIMEOUT) {
|
||||
*cause = SWITCH_CAUSE_NO_ANSWER;
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(oglobals.session), SWITCH_LOG_DEBUG,
|
||||
"Originate Resulted in Error Cause: %d [%s]\n", *cause, switch_channel_cause2str(*cause));
|
||||
@ -2561,6 +2582,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
|
||||
switch_channel_clear_flag(caller_channel, CF_XFER_ZOMBIE);
|
||||
}
|
||||
|
||||
if (force_reason != SWITCH_CAUSE_NONE) {
|
||||
*cause = force_reason;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user