From 24a972925b851c39d4f39db5f536d12ef4118a8b Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 11 Mar 2011 13:00:16 -0600 Subject: [PATCH] pass header in X-FS headers on attended transfer CID update to indicate specific situation to flip callee/caller id when targeting a 1 legged call --- src/include/switch_channel.h | 1 + src/include/switch_types.h | 2 ++ src/mod/endpoints/mod_sofia/mod_sofia.c | 11 +++++++ src/mod/endpoints/mod_sofia/sofia.c | 25 +++++++++++++-- src/switch_channel.c | 41 ++++++++++++++++--------- src/switch_ivr_originate.c | 2 ++ 6 files changed, 65 insertions(+), 17 deletions(-) diff --git a/src/include/switch_channel.h b/src/include/switch_channel.h index 25273bafc4..fdbbc9ab91 100644 --- a/src/include/switch_channel.h +++ b/src/include/switch_channel.h @@ -315,6 +315,7 @@ SWITCH_DECLARE(switch_status_t) switch_channel_caller_extension_masquerade(switc */ SWITCH_DECLARE(void) switch_channel_set_caller_extension(switch_channel_t *channel, switch_caller_extension_t *caller_extension); +SWITCH_DECLARE(void) switch_channel_flip_cid(switch_channel_t *channel); SWITCH_DECLARE(void) switch_channel_sort_cid(switch_channel_t *channel, switch_bool_t in); /*! diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 4253d0e542..79494d8979 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -1107,6 +1107,8 @@ typedef enum { CF_DIALPLAN, CF_BLOCK_BROADCAST_UNTIL_MEDIA, CF_CNG_PLC, + CF_ATTENDED_TRANSFER, + CF_LAZY_ATTENDED_TRANSFER, /* WARNING: DO NOT ADD ANY FLAGS BELOW THIS LINE */ CF_FLAG_MAX } switch_channel_flag_t; diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 3bc5cc2231..f50e057d5f 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -1878,6 +1878,17 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi if (switch_stristr("update_display", tech_pvt->x_freeswitch_support_remote)) { snprintf(message, sizeof(message), "X-FS-Display-Name: %s\nX-FS-Display-Number: %s\n", name, number); + if (switch_channel_test_flag(tech_pvt->channel, CF_LAZY_ATTENDED_TRANSFER)) { + snprintf(message + strlen(message), sizeof(message) - strlen(message), "X-FS-Lazy-Attended-Transfer: true\n"); + switch_channel_clear_flag(tech_pvt->channel, CF_LAZY_ATTENDED_TRANSFER); + switch_channel_clear_flag(tech_pvt->channel, CF_ATTENDED_TRANSFER); + } + + if (switch_channel_test_flag(tech_pvt->channel, CF_ATTENDED_TRANSFER)) { + snprintf(message + strlen(message), sizeof(message) - strlen(message), "X-FS-Attended-Transfer: true\n"); + switch_channel_clear_flag(tech_pvt->channel, CF_ATTENDED_TRANSFER); + } + nua_info(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("message/update_display"), TAG_IF(!zstr_buf(message), SIPTAG_HEADER_STR(message)), TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), TAG_END()); diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 761a03ce62..d612e30f0b 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -637,7 +637,7 @@ void sofia_update_callee_id(switch_core_session_t *session, sofia_profile_t *pro char *dup = NULL; switch_event_t *event; const char *val; - int fs = 0; + int fs = 0, lazy = 0, att = 0; if (switch_true(switch_channel_get_variable(channel, SWITCH_IGNORE_DISPLAY_UPDATES_VARIABLE))) { return; @@ -656,6 +656,16 @@ void sofia_update_callee_id(switch_core_session_t *session, sofia_profile_t *pro name = (char *) val; fs++; } + + if ((val = sofia_glue_get_unknown_header(sip, "X-FS-Lazy-Attended-Transfer"))) { + lazy = switch_true(val); + fs++; + } + + if ((val = sofia_glue_get_unknown_header(sip, "X-FS-Attended-Transfer"))) { + att = switch_true(val); + fs++; + } if (!fs) { if ((passerted = sip_p_asserted_identity(sip))) { @@ -727,6 +737,10 @@ void sofia_update_callee_id(switch_core_session_t *session, sofia_profile_t *pro caller_profile->callee_id_name = switch_sanitize_number(switch_core_strdup(caller_profile->pool, name)); caller_profile->callee_id_number = switch_sanitize_number(switch_core_strdup(caller_profile->pool, number)); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s Update Callee ID to \"%s\" <%s>\n", switch_channel_get_name(channel), name, number); + + if (lazy || (att && !switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE))) { + switch_channel_flip_cid(channel); + } } if (send) { @@ -5717,9 +5731,14 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Attended Transfer [%s][%s]\n", switch_str_nil(br_a), switch_str_nil(br_b)); - if ((profile->media_options & MEDIA_OPT_BYPASS_AFTER_ATT_XFER) && (tmp = switch_core_session_locate(br_b))) { + if ((tmp = switch_core_session_locate(br_b))) { switch_channel_t *tchannel = switch_core_session_get_channel(tmp); - switch_channel_set_flag(tchannel, CF_BYPASS_MEDIA_AFTER_BRIDGE); + + if ((profile->media_options & MEDIA_OPT_BYPASS_AFTER_ATT_XFER)) { + switch_channel_set_flag(tchannel, CF_BYPASS_MEDIA_AFTER_BRIDGE); + } + + switch_channel_set_flag(tchannel, CF_ATTENDED_TRANSFER); switch_core_session_rwunlock(tmp); } diff --git a/src/switch_channel.c b/src/switch_channel.c index f737dc53c6..784577c642 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -2434,26 +2434,39 @@ SWITCH_DECLARE(switch_status_t) switch_channel_caller_extension_masquerade(switc return status; } +SWITCH_DECLARE(void) switch_channel_flip_cid(switch_channel_t *channel) +{ + switch_mutex_lock(channel->profile_mutex); + if (channel->caller_profile->callee_id_name) { + switch_channel_set_variable(channel, "pre_transfer_caller_id_name", channel->caller_profile->caller_id_name); + channel->caller_profile->caller_id_name = switch_core_strdup(channel->caller_profile->pool, channel->caller_profile->callee_id_name); + } + channel->caller_profile->callee_id_name = SWITCH_BLANK_STRING; + + if (channel->caller_profile->callee_id_number) { + switch_channel_set_variable(channel, "pre_transfer_caller_id_number", channel->caller_profile->caller_id_number); + channel->caller_profile->caller_id_number = switch_core_strdup(channel->caller_profile->pool, channel->caller_profile->callee_id_number); + } + channel->caller_profile->callee_id_number = SWITCH_BLANK_STRING; + switch_mutex_unlock(channel->profile_mutex); + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(channel->session), SWITCH_LOG_INFO, "%s Flipping CID from \"%s\" <%s> to \"%s\" <%s>\n", + switch_channel_get_name(channel), + switch_channel_get_variable(channel, "pre_transfer_caller_id_name"), + switch_channel_get_variable(channel, "pre_transfer_caller_id_number"), + channel->caller_profile->caller_id_name, + channel->caller_profile->caller_id_number + ); + +} + SWITCH_DECLARE(void) switch_channel_sort_cid(switch_channel_t *channel, switch_bool_t in) { if (in) { if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND && !switch_channel_test_flag(channel, CF_DIALPLAN)) { switch_channel_set_flag(channel, CF_DIALPLAN); - - switch_mutex_lock(channel->profile_mutex); - if (channel->caller_profile->callee_id_name) { - switch_channel_set_variable(channel, "pre_transfer_caller_id_name", channel->caller_profile->caller_id_name); - channel->caller_profile->caller_id_name = switch_core_strdup(channel->caller_profile->pool, channel->caller_profile->callee_id_name); - } - channel->caller_profile->callee_id_name = SWITCH_BLANK_STRING; - - if (channel->caller_profile->callee_id_number) { - switch_channel_set_variable(channel, "pre_transfer_caller_id_number", channel->caller_profile->caller_id_number); - channel->caller_profile->caller_id_number = switch_core_strdup(channel->caller_profile->pool, channel->caller_profile->callee_id_number); - } - channel->caller_profile->callee_id_number = SWITCH_BLANK_STRING; - switch_mutex_unlock(channel->profile_mutex); + switch_channel_flip_cid(channel); } return; diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index 92137ea5d8..fe5edac504 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -3264,6 +3264,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess switch_channel_set_variable(switch_core_session_get_channel(holding_session), SWITCH_HANGUP_AFTER_BRIDGE_VARIABLE, "true"); switch_core_session_rwunlock(holding_session); } + switch_channel_set_flag(peer_channel, CF_LAZY_ATTENDED_TRANSFER); switch_ivr_uuid_bridge(holding, switch_core_session_get_uuid(peer_session)); holding = NULL; oglobals.idx = IDX_NADA; @@ -3335,6 +3336,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess switch_channel_set_variable(switch_core_session_get_channel(holding_session), SWITCH_HANGUP_AFTER_BRIDGE_VARIABLE, "true"); switch_core_session_rwunlock(holding_session); } + switch_channel_set_flag(originate_status[i].peer_channel, CF_LAZY_ATTENDED_TRANSFER); switch_ivr_uuid_bridge(holding, switch_core_session_get_uuid(originate_status[i].peer_session)); holding = NULL; } else {