From 7050c330b2509a3083364831cc0be32f038834ca Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 9 May 2008 19:59:42 +0000 Subject: [PATCH] allow blind xfers on no-media calls git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@8342 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- .../applications/mod_dptools/mod_dptools.c | 9 ++++++-- src/mod/endpoints/mod_sofia/sofia.c | 22 +++++++++++++------ src/mod/endpoints/mod_sofia/sofia_presence.c | 4 +--- src/switch_channel.c | 4 ++-- src/switch_core_io.c | 14 +++++++----- src/switch_ivr.c | 5 +++++ src/switch_ivr_originate.c | 16 +++++++++----- 7 files changed, 48 insertions(+), 26 deletions(-) diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index 880c3d6bf0..ca744cf7d8 100644 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -1671,8 +1671,13 @@ SWITCH_STANDARD_APP(audio_bridge_function) && !switch_channel_test_flag(caller_channel, CF_EARLY_MEDIA)) { switch_channel_set_flag(caller_channel, CF_PROXY_MODE); } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Channel is already up, delaying proxy mode 'till both legs are up.\n"); - no_media_bridge = 1; + if (switch_channel_test_flag(caller_channel, CF_PROXY_MODE)) { + switch_ivr_media(switch_core_session_get_uuid(session), SMF_REBRIDGE); + switch_channel_set_flag(caller_channel, CF_PROXY_MODE); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Channel is already up, delaying proxy mode 'till both legs are up.\n"); + no_media_bridge = 1; + } } } diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 5a2d6430d1..e0a55b12d7 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -1520,7 +1520,7 @@ static void sofia_handle_sip_r_options(switch_core_session_t *session, int statu if (gateway) { if (status == 200 || status == 404) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "ping success %s\n", gateway->name); + //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "ping success %s\n", gateway->name); gateway->status = SOFIA_GATEWAY_UP; } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "ping failed %s\n", gateway->name); @@ -2159,11 +2159,6 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t goto done; } - if (switch_channel_test_flag(channel_a, CF_PROXY_MODE)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Re-establishing media.\n"); - switch_ivr_media(switch_core_session_get_uuid(session), SMF_REBRIDGE); - } - from = sip->sip_from; to = sip->sip_to; @@ -2189,6 +2184,15 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t sip_replaces_t *replaces; nua_handle_t *bnh; char *rep; + + if (switch_channel_test_flag(channel_a, CF_PROXY_MODE)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot Attended Transfer BYPASS MEDIA CALLS!\n"); + switch_channel_set_variable(channel_a, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "ATTENDED_TRANSFER_ERROR"); + 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 403 Forbidden"), SIPTAG_EVENT_STR(etmp), + TAG_END()); + goto done; + } if ((rep = strchr(refer_to->r_url->url_headers, '='))) { const char *br_a = NULL, *br_b = NULL; @@ -2209,6 +2213,7 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t sofia_private_t *b_private = NULL; private_object_t *b_tech_pvt = NULL; switch_core_session_t *b_session = NULL; + switch_channel_set_variable(channel_a, SOFIA_REPLACES_HEADER, rep); if ((b_private = nua_handle_magic(bnh))) { @@ -2347,7 +2352,7 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t &tsession, &cause, exten, timeout, &noop_state_handler, NULL, NULL, NULL, SOF_NONE); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot Create Outgoing Channel! [%s]\n", exten); - nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1), SIPTAG_CONTENT_TYPE_STR("message/sipfrag"), + nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1), SIPTAG_CONTENT_TYPE_STR("messsage/sipfrag"), NUTAG_SUBSTATE(nua_substate_terminated), SIPTAG_PAYLOAD_STR("SIP/2.0 403 Forbidden"), SIPTAG_EVENT_STR(etmp), TAG_END()); @@ -2404,6 +2409,9 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t if (!switch_strlen_zero(full_ref_to)) { switch_channel_set_variable(b_channel, SOFIA_REFER_TO_VARIABLE, full_ref_to); } + + + switch_ivr_session_transfer(b_session, exten, NULL, NULL); switch_core_session_rwunlock(b_session); } diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index aff5355863..5077f86357 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -221,9 +221,7 @@ static void actual_sofia_presence_mwi_event_handler(switch_event_t *event) if ((pname = switch_event_get_header(event, "sofia-profile"))) { - if ((profile = sofia_glue_find_profile(pname))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "using profile %s\n", pname); - } else { + if (!(profile = sofia_glue_find_profile(pname))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "no profile %s\n", pname); } } diff --git a/src/switch_channel.c b/src/switch_channel.c index c891bfaaf0..2ab9c8e99b 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -112,8 +112,8 @@ struct switch_channel { switch_core_session_t *session; switch_channel_state_t state; switch_channel_state_t running_state; - uint32_t flags; - uint32_t state_flags; + switch_channel_flag_t flags; + switch_channel_flag_t state_flags; switch_caller_profile_t *caller_profile; const switch_state_handler_table_t *state_handlers[SWITCH_MAX_STATE_HANDLERS]; int state_handler_index; diff --git a/src/switch_core_io.c b/src/switch_core_io.c index 82ab309bfb..6b99552158 100644 --- a/src/switch_core_io.c +++ b/src/switch_core_io.c @@ -106,11 +106,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi top: - if (!(session->read_codec && session->read_codec->implementation)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s has no read codec.\n", switch_channel_get_name(session->channel)); - return SWITCH_STATUS_FALSE; - } - if (switch_channel_get_state(session->channel) >= CS_HANGUP) { *frame = NULL; return SWITCH_STATUS_FALSE; @@ -165,7 +160,14 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi } switch_assert((*frame)->codec != NULL); - if ((session->read_codec && (*frame)->codec && session->read_codec->implementation != (*frame)->codec->implementation)) { + + if (!(session->read_codec && session->read_codec->implementation)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s has no read codec.\n", switch_channel_get_name(session->channel)); + abort(); + return SWITCH_STATUS_FALSE; + } + + if (((*frame)->codec && session->read_codec->implementation != (*frame)->codec->implementation)) { need_codec = TRUE; } diff --git a/src/switch_ivr.c b/src/switch_ivr.c index 53c13f48db..580e35ebe2 100644 --- a/src/switch_ivr.c +++ b/src/switch_ivr.c @@ -60,6 +60,11 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_sleep(switch_core_session_t *session, break; } + if (switch_channel_test_flag(channel, CF_PROXY_MODE)) { + switch_yield(1000); + continue; + } + if (switch_channel_test_flag(channel, CF_SERVICE) || (!switch_channel_test_flag(channel, CF_ANSWERED) && !switch_channel_test_flag(channel, CF_EARLY_MEDIA))) { switch_yield(1000); diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index 5cc22412d0..64382d209d 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -38,8 +38,10 @@ static switch_status_t originate_on_consume_media_transmit(switch_core_session_t { switch_channel_t *channel = switch_core_session_get_channel(session); - while(switch_channel_get_state(channel) == CS_CONSUME_MEDIA) { - switch_ivr_sleep(session, 10); + if (!switch_channel_test_flag(channel, CF_PROXY_MODE)) { + while(switch_channel_get_state(channel) == CS_CONSUME_MEDIA) { + switch_ivr_sleep(session, 10); + } } switch_channel_clear_state_handler(channel, &originate_state_handlers); @@ -1057,10 +1059,12 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess } } - /* read from the channel while we wait if the audio is up on it */ - if (session && (ringback_data || - !(switch_channel_test_flag(caller_channel, CF_PROXY_MODE) && switch_channel_test_flag(caller_channel, CF_PROXY_MODE))) && - (switch_channel_test_flag(caller_channel, CF_ANSWERED) || switch_channel_test_flag(caller_channel, CF_EARLY_MEDIA))) { + /* read from the channel while we wait if the audio is up on it */ + if (session && + !switch_channel_test_flag(caller_channel, CF_PROXY_MODE) && + !switch_channel_test_flag(caller_channel, CF_PROXY_MEDIA) && + (ringback_data || (switch_channel_test_flag(caller_channel, CF_ANSWERED) || switch_channel_test_flag(caller_channel, CF_EARLY_MEDIA)))) { + switch_status_t tstatus = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0); if (!SWITCH_READ_ACCEPTABLE(tstatus)) {