]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
freetdm: Verify that the uuid that is being hung up is still attached to the FreeTDM...
authorMoises Silva <moy@sangoma.com>
Thu, 15 Sep 2011 23:32:08 +0000 (19:32 -0400)
committerMoises Silva <moy@sangoma.com>
Thu, 15 Sep 2011 23:42:39 +0000 (19:42 -0400)
         This avoids hanging up a device that is no longer attached to the session, in the
         weird situation where the FreeSWITCH core takes an awful lot of time (more than 3 seconds)
         to come around to acknowledge the SIGEVENT_STOP signal.

libs/freetdm/mod_freetdm/mod_freetdm.c

index 435c9a8e6411ed6211a9e0e1f0bcb66e6ebd03b6..1e07db5e318cbf8ad41cdfe8956b3f249f79b8be 100755 (executable)
@@ -507,7 +507,11 @@ static switch_status_t channel_on_hangup(switch_core_session_t *session)
        const char *name = NULL;
        int span_id = 0;
        int chan_id = 0;
+       int t = 0;
        uint32_t tokencnt;
+       char *uuid = NULL;
+       const char *token = NULL;
+       uint8_t uuid_found = 0;
 
        channel = switch_core_session_get_channel(session);
        assert(channel != NULL);
@@ -525,11 +529,33 @@ static switch_status_t channel_on_hangup(switch_core_session_t *session)
 
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "[%d:%d] %s CHANNEL HANGUP ENTER\n", span_id, chan_id, name);
 
+       /* First verify this call has a device attached */
        if (!tech_pvt->ftdmchan) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s does not have any ftdmchan attached\n", name);
                goto end;
        }
 
+       /* 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, tokencnt);
+               if (!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;
+       }
+
 #ifdef CUDATEL_DEBUG
        {
                pid_t tid = 0;
@@ -561,7 +587,6 @@ static switch_status_t channel_on_hangup(switch_core_session_t *session)
        case FTDM_CHAN_TYPE_FXS:
                {
                        if (!ftdm_channel_call_check_busy(tech_pvt->ftdmchan) && !ftdm_channel_call_check_done(tech_pvt->ftdmchan)) {
-                               tokencnt = ftdm_channel_get_token_count(tech_pvt->ftdmchan);
                                if (tokencnt) {
                                        cycle_foreground(tech_pvt->ftdmchan, 0, NULL);
                                } else {