From f9653fbd38e569289181076bd1d9dc25ed2bba52 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 10 May 2012 22:34:37 -0500 Subject: [PATCH] FS-4204 --resolve --- src/include/switch_core.h | 2 +- src/mod/endpoints/mod_sofia/mod_sofia.c | 12 +++++ src/mod/endpoints/mod_sofia/mod_sofia.h | 1 + src/mod/endpoints/mod_sofia/sofia.c | 56 ++++++++++++++++++------ src/mod/endpoints/mod_sofia/sofia_glue.c | 4 ++ src/switch_core_media_bug.c | 22 +++++++++- src/switch_ivr_bridge.c | 2 + 7 files changed, 83 insertions(+), 16 deletions(-) diff --git a/src/include/switch_core.h b/src/include/switch_core.h index 91cff21d67..624d491e1d 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -141,7 +141,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_bug_pop(switch_core_session_t SWITCH_DECLARE(switch_status_t) switch_core_media_bug_exec_all(switch_core_session_t *orig_session, const char *function, switch_media_bug_exec_cb_t cb, void *user_data); - +SWITCH_DECLARE(uint32_t) switch_core_media_bug_count(switch_core_session_t *orig_session, const char *function); /*! \brief Add a media bug to the session \param session the session to add the bug to diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index cf095386e5..164d0e76ff 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -5375,11 +5375,23 @@ SWITCH_STANDARD_APP(sofia_sla_function) if (bargee_session == session) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "BARGE: %s (cannot barge on myself)\n", (char *) data); } else { + switch_channel_t *channel; + if (switch_core_session_check_interface(bargee_session, sofia_endpoint_interface)) { tech_pvt = switch_core_session_get_private(bargee_session); + sofia_clear_flag(tech_pvt, TFLAG_SLA_BARGING); sofia_set_flag(tech_pvt, TFLAG_SLA_BARGE); switch_ivr_transfer_variable(bargee_session, session, SWITCH_SIGNAL_BOND_VARIABLE); } + + if (switch_core_session_check_interface(session, sofia_endpoint_interface)) { + tech_pvt = switch_core_session_get_private(session); + sofia_set_flag(tech_pvt, TFLAG_SLA_BARGING); + } + + channel = switch_core_session_get_channel(session); + switch_channel_set_variable(channel, "sip_barging_uuid", (char *)data); + } switch_core_session_rwunlock(bargee_session); diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index 2da82ac0c2..65755500a9 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -334,6 +334,7 @@ typedef enum { TFLAG_CAPTURE, TFLAG_REINVITED, TFLAG_SLA_BARGE, + TFLAG_SLA_BARGING, /* No new flags below this line */ TFLAG_MAX } TFLAGS; diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index f87e8581b0..820118c585 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -599,6 +599,23 @@ void sofia_handle_sip_i_bye(switch_core_session_t *session, int status, status = 200; phrase = "OK"; + if (sofia_test_flag(tech_pvt, TFLAG_SLA_BARGING)) { + const char *bargee_uuid = switch_channel_get_variable(channel, "sip_barging_uuid"); + switch_core_session_t *bargee_session; + uint32_t ttl = 0; + + if ((bargee_session = switch_core_session_locate(bargee_uuid))) { + //switch_channel_t *bargee_channel = switch_core_session_get_channel(bargee_session); + if ((ttl = switch_core_media_bug_count(bargee_session, "eavesdrop")) == 1) { + if (switch_core_session_check_interface(bargee_session, sofia_endpoint_interface)) { + private_object_t *bargee_tech_pvt = switch_core_session_get_private(bargee_session); + sofia_clear_flag(bargee_tech_pvt, TFLAG_SLA_BARGE); + } + } + switch_core_session_rwunlock(bargee_session); + } + } + if (sofia_test_flag(tech_pvt, TFLAG_SLA_BARGE)) { switch_core_session_t *new_session, *other_session; const char *other_uuid = switch_channel_get_variable(tech_pvt->channel, SWITCH_SIGNAL_BOND_VARIABLE); @@ -8419,9 +8436,7 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_ if ((b_session = switch_core_session_locate(b_private->uuid))) { switch_channel_t *b_channel = switch_core_session_get_channel(b_session); - const char *uuid; - const char *app = switch_channel_get_variable(b_channel, SWITCH_CURRENT_APPLICATION_VARIABLE); - const char *data = switch_channel_get_variable(b_channel, SWITCH_CURRENT_APPLICATION_DATA_VARIABLE); + const char *bridge_uuid; switch_caller_profile_t *orig_cp; const char *sent_name, *sent_number; orig_cp = switch_channel_get_caller_profile(b_channel); @@ -8446,24 +8461,37 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Setting NAT mode based on %s\n", is_nat); } + tech_pvt->caller_profile->dialplan = "inline"; - if (app && data && !strcasecmp(app, "conference")) { - tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool, "answer,conference:%s+flags{dist-dtmf}", data); - tech_pvt->caller_profile->dialplan = "inline"; - } else { - if (!(uuid = switch_channel_get_variable(b_channel, SWITCH_SIGNAL_BOND_VARIABLE))) { - uuid = switch_core_session_get_uuid(b_session); - } + bridge_uuid = switch_channel_get_variable(b_channel, SWITCH_SIGNAL_BOND_VARIABLE); - if (uuid) { - uuid = switch_core_session_strdup(b_session, uuid); + if (call_info) { + if (!zstr(bridge_uuid) && switch_channel_test_flag(b_channel, CF_LEG_HOLDING)) { + tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool, + "answer,intercept:%s", bridge_uuid); + } else { tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool, "answer,sofia_sla:%s", b_private->uuid); + } + } else { + if (!zstr(bridge_uuid)) { + switch_channel_mark_hold(b_channel, SWITCH_FALSE); + tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool, "answer,intercept:%s", bridge_uuid); + } else { + const char *b_app = switch_channel_get_variable(b_channel, SWITCH_CURRENT_APPLICATION_VARIABLE); + const char *b_data = switch_channel_get_variable(b_channel, SWITCH_CURRENT_APPLICATION_DATA_VARIABLE); + + if (b_data && b_app) { + tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool, "answer,%s:%s", b_app, b_data); + } else if (b_app) { + tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool, "answer,%s", b_app); + } + - - tech_pvt->caller_profile->dialplan = "inline"; + switch_channel_hangup(b_channel, SWITCH_CAUSE_ATTENDED_TRANSFER); } } + switch_core_session_rwunlock(b_session); } } diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index f787ac3cbb..2039116b41 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -4061,6 +4061,10 @@ int sofia_glue_toggle_hold(private_object_t *tech_pvt, int sendonly) { int changed = 0; + if (sofia_test_flag(tech_pvt, TFLAG_SLA_BARGE) || sofia_test_flag(tech_pvt, TFLAG_SLA_BARGING)) { + return 0; + } + if (sendonly && switch_channel_test_flag(tech_pvt->channel, CF_ANSWERED)) { if (!sofia_test_flag(tech_pvt, TFLAG_SIP_HOLD)) { const char *stream; diff --git a/src/switch_core_media_bug.c b/src/switch_core_media_bug.c index 3d5c26b531..8b466b111e 100644 --- a/src/switch_core_media_bug.c +++ b/src/switch_core_media_bug.c @@ -600,6 +600,24 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_bug_pop(switch_core_session_t return SWITCH_STATUS_FALSE; } +SWITCH_DECLARE(uint32_t) switch_core_media_bug_count(switch_core_session_t *orig_session, const char *function) +{ + switch_media_bug_t *bp; + uint32_t x = 0; + + if (orig_session->bugs) { + switch_thread_rwlock_rdlock(orig_session->bug_rwlock); + for (bp = orig_session->bugs; bp; bp = bp->next) { + if (!switch_test_flag(bp, SMBF_PRUNE) && !switch_test_flag(bp, SMBF_LOCK) && !strcmp(bp->function, function)) { + x++; + } + } + switch_thread_rwlock_unlock(orig_session->bug_rwlock); + } + + return x; +} + SWITCH_DECLARE(switch_status_t) switch_core_media_bug_exec_all(switch_core_session_t *orig_session, const char *function, switch_media_bug_exec_cb_t cb, void *user_data) { @@ -629,7 +647,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_bug_enumerate(switch_core_sess stream->write_function(stream, "\n"); if (session->bugs) { - switch_thread_rwlock_wrlock(session->bug_rwlock); + switch_thread_rwlock_rdlock(session->bug_rwlock); for (bp = session->bugs; bp; bp = bp->next) { int thread_locked = (bp->thread_id && bp->thread_id == switch_thread_self()); stream->write_function(stream, @@ -778,6 +796,8 @@ SWITCH_DECLARE(uint32_t) switch_core_media_bug_prune(switch_core_session_t *sess switch_thread_rwlock_unlock(session->bug_rwlock); if (bp) { + switch_clear_flag(bp, SMBF_LOCK); + bp->thread_id = 0; switch_core_media_bug_close(&bp); ttl++; goto top; diff --git a/src/switch_ivr_bridge.c b/src/switch_ivr_bridge.c index 3d9758f62b..d8b548b048 100644 --- a/src/switch_ivr_bridge.c +++ b/src/switch_ivr_bridge.c @@ -228,6 +228,8 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj) } } + switch_channel_clear_flag(chan_a, CF_INTERCEPT); + switch_channel_clear_flag(chan_a, CF_INTERCEPTED); switch_channel_set_flag(chan_a, CF_BRIDGED);