]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
Fix for 3000ms timeout on hangup.
authorNenad Corbic <ncorbic@sangoma.com>
Fri, 16 Dec 2011 01:39:38 +0000 (20:39 -0500)
committerNenad Corbic <ncorbic@sangoma.com>
Fri, 16 Dec 2011 01:39:38 +0000 (20:39 -0500)
Where FS does not hangup the channel with in 3sec.
Without this fix, it was possible that 2 FS sessions
use the single span/chan freetdm session.
Merged the feature from git master of freetdm

libs/freetdm/mod_freetdm/mod_freetdm.c

index ecd9189b3933665e57aea0d7e8134fd78df27ea0..003be91b17c8d49d8b2f52c50925b54c3c42c23b 100755 (executable)
@@ -496,6 +496,14 @@ static switch_status_t channel_on_hangup(switch_core_session_t *session)
        private_t *tech_pvt = NULL;
        ftdm_chan_type_t chantype;
        uint32_t tokencnt;
+       char *uuid = NULL;
+       uint8_t uuid_found = 0;
+       uint32_t t = 0;
+       const char *token = NULL;
+       int span_id = 0;
+       int chan_id = 0;
+       const char *name = NULL;
+
 
        channel = switch_core_session_get_channel(session);
        assert(channel != NULL);
@@ -503,10 +511,42 @@ static switch_status_t channel_on_hangup(switch_core_session_t *session)
        tech_pvt = switch_core_session_get_private(session);
        assert(tech_pvt != NULL);
 
+        /* ignore any further I/O requests, we're hanging up already! */
+    switch_clear_flag_locked(tech_pvt, TFLAG_IO);
+
+
        if (!tech_pvt->ftdmchan) {
                goto end;
        } 
 
+       name = switch_channel_get_name(channel);
+
+       span_id = tech_pvt->ftdmchan ? ftdm_channel_get_span_id(tech_pvt->ftdmchan) : 0;
+       chan_id = tech_pvt->ftdmchan ? ftdm_channel_get_id(tech_pvt->ftdmchan) : 0;
+
+
+    /* Now verify the device is still attached to this call :-)
+     * Sometimes the FS core takes too long (more than 3 seconds) in calling
+     * channel_on_hangup() and the FreeTDM core decides to take the brute
+     * force approach and hangup and detach themselves from the call. Later
+     * when FS finally comes around, we might end up hanging up the device
+     * attached to another call, this verification avoids that. */
+    uuid = switch_core_session_get_uuid(session);
+    tokencnt = ftdm_channel_get_token_count(tech_pvt->ftdmchan);
+    for (t = 0; t < tokencnt; t++) {
+        token = ftdm_channel_get_token(tech_pvt->ftdmchan, t);
+        if (!zstr(token) && !strcasecmp(uuid, token)) {
+            uuid_found = 1;
+            break;
+        }
+    }
+
+    if (!uuid_found) {
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Device [%d:%d] is no longer attached to %s. Nothing to do.\n", span_id, chan_id, name);
+        goto end;
+    }
+       
+
        ftdm_channel_clear_token(tech_pvt->ftdmchan, switch_core_session_get_uuid(session));
 
        chantype = ftdm_channel_get_type(tech_pvt->ftdmchan);   
@@ -2459,7 +2499,6 @@ static FIO_SIGNAL_CB_FUNCTION(on_clear_channel_signal)
                                switch_set_flag_locked(tech_pvt, TFLAG_DEAD);
                                channel = switch_core_session_get_channel(session);
                                switch_channel_hangup(channel, caller_data->hangup_cause);
-                               ftdm_channel_clear_token(sigmsg->channel, switch_core_session_get_uuid(session));
                                switch_core_session_rwunlock(session);
                        }
                }