]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-4204 --resolve
authorAnthony Minessale <anthm@freeswitch.org>
Fri, 11 May 2012 03:34:37 +0000 (22:34 -0500)
committerAnthony Minessale <anthm@freeswitch.org>
Fri, 11 May 2012 03:34:37 +0000 (22:34 -0500)
src/include/switch_core.h
src/mod/endpoints/mod_sofia/mod_sofia.c
src/mod/endpoints/mod_sofia/mod_sofia.h
src/mod/endpoints/mod_sofia/sofia.c
src/mod/endpoints/mod_sofia/sofia_glue.c
src/switch_core_media_bug.c
src/switch_ivr_bridge.c

index 91cff21d6749f6eafe1ae383990251ce12b8c7dc..624d491e1d13a4b508136e8fc4c9a70a95884b74 100644 (file)
@@ -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
index cf095386e5257ae9bc530c0f8cbb9716d670247e..164d0e76ffe7f0cc0cf3ab9a536c445ff3a1fe66 100644 (file)
@@ -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);
index 2da82ac0c21e3219d434bd94750c4fb15e67cc73..65755500a9b8fa9aa67404f478b8e14117734bb0 100644 (file)
@@ -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;
index f87e8581b0bb0ddf3bfd72bdecc815b7d1b161c5..820118c585c2ccb6703200a66bf8c1f2275f0626 100644 (file)
@@ -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);
                        }
                }
index f787ac3cbbc2e663fa7d84a31e33a7abaea42da7..2039116b41e0e4626971a3ce67131d59bba2d13a 100644 (file)
@@ -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;
index 3d5c26b531a6d83602706457b13c24efc0177d90..8b466b111ed9d7b47a747bdc259a2827a5cf5e7c 100644 (file)
@@ -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, "<media-bugs>\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;
index 3d9758f62bb9cb4eb068566a92c531b9a981e801..d8b548b048bfab6f26f83a0c30deedd1e309cb62 100644 (file)
@@ -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);