]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
freetdm: ISDN - Fix for segfault when we receive STA CFM while call is being cleared
authorDavid Yat Sin <dyatsin@sangoma.com>
Thu, 26 May 2011 20:34:42 +0000 (16:34 -0400)
committerDavid Yat Sin <dyatsin@sangoma.com>
Thu, 26 May 2011 20:34:42 +0000 (16:34 -0400)
libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c
libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c
libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c

index 0789c433f94744a0318334f1217d0bd5481fce94..872cf51bc411aad07a742f1a14b895cd2a53ce0d 100644 (file)
@@ -881,6 +881,12 @@ void sngisdn_process_sta_cfm (sngisdn_event_data_t *sngisdn_event)
        uint8_t call_state = 0;
 
        ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
+
+       if (!suInstId && !spInstId) {
+               /* We already cleared this call */
+               ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Dropping STATUS CONFIRM (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
+               return;
+       }
        
        if (staEvnt->callSte.eh.pres && staEvnt->callSte.callGlblSte.pres) {
                call_state = staEvnt->callSte.callGlblSte.val;
index 67de893f5d0d09f110476b0afb3c694492cea7b2..2a523c7cb9ffe4561daabf55e07c16524f64ddbd 100644 (file)
@@ -502,12 +502,16 @@ void sngisdn_rcv_sta_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, St
        sngisdn_event_data_t *sngisdn_event = NULL;
 
        ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
-       
+
+       /* We sometimes receive a STA CFM after receiving a RELEASE/RELEASE COMPLETE, so we need to lock
+               here in case we are calling clear_call_data at the same time this function is called */
+
+       ftdm_mutex_lock(g_sngisdn_data.ccs[suId].mutex);        
        if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
                !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) {
 
                ftdm_log(FTDM_LOG_CRIT, "Could not find matching call suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId);
-               ftdm_assert(0, "Inconsistent call states\n");
+               ftdm_mutex_unlock(g_sngisdn_data.ccs[suId].mutex);
                return;
        }
 
@@ -526,6 +530,7 @@ void sngisdn_rcv_sta_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, St
        memcpy(&sngisdn_event->event.staEvnt, staEvnt, sizeof(*staEvnt));
 
        ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event);
+       ftdm_mutex_unlock(g_sngisdn_data.ccs[suId].mutex);
        ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
 }
 
index 3ba776928dabe684b72a841e6944b7a2631de192..61f340205d13001835aa61776f9dce4ed1b404db 100644 (file)
@@ -100,12 +100,12 @@ void clear_call_data(sngisdn_chan_data_t *sngisdn_info)
        ftdm_mutex_lock(g_sngisdn_data.ccs[cc_id].mutex);
        g_sngisdn_data.ccs[cc_id].active_spInstIds[sngisdn_info->spInstId]=NULL;
        g_sngisdn_data.ccs[cc_id].active_suInstIds[sngisdn_info->suInstId]=NULL;
-       ftdm_mutex_unlock(g_sngisdn_data.ccs[cc_id].mutex);
-       
+               
        sngisdn_info->suInstId = 0;
        sngisdn_info->spInstId = 0;
        sngisdn_info->globalFlg = 0;
        sngisdn_info->flags = 0;
+       ftdm_mutex_unlock(g_sngisdn_data.ccs[cc_id].mutex);
        return;
 }