diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c index 9ffd7097a3..e962eceb28 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c @@ -189,7 +189,8 @@ ftdm_state_map_t sangoma_isdn_state_map = { ZSD_OUTBOUND, ZSM_UNACCEPTABLE, {FTDM_CHANNEL_STATE_DIALING, FTDM_END}, - {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_DOWN, FTDM_END} + {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS, + FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_DOWN, FTDM_END} }, { ZSD_OUTBOUND, @@ -558,6 +559,9 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan) /* We are hangup local call because there was a glare, we are waiting for a RELEASE on this call, before we can process the saved call */ ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Waiting for RELEASE on hungup glared call\n"); + } else if (sngisdn_test_flag(sngisdn_info, FLAG_SEND_DISC)) { + /* Remote side sent a PROGRESS message, but cause indicates disconnect or T310 expired*/ + sngisdn_snd_disconnect(ftdmchan); } else { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Hanging up call upon local request!\n"); @@ -568,16 +572,15 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan) if (ftdmchan->last_state == FTDM_CHANNEL_STATE_RING || ftdmchan->last_state == FTDM_CHANNEL_STATE_DIALING) { + sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT); + sngisdn_snd_release(ftdmchan, 0); + if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP)) { sng_isdn_set_avail_rate(ftdmchan->span, SNGISDN_AVAIL_DOWN); } - - sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT); - sngisdn_snd_release(ftdmchan, 0); } else { sngisdn_snd_disconnect(ftdmchan); } - } /* now go to the HANGUP complete state */ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h index 3f63fbc1d4..5f26828529 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h @@ -68,6 +68,7 @@ typedef enum { FLAG_GLARE = (1 << 6), FLAG_DELAYED_REL = (1 << 7), FLAG_SENT_PROCEED = (1 << 8), + FLAG_SEND_DISC = (1 << 9), } sngisdn_flag_t; @@ -127,6 +128,13 @@ typedef enum { SNGISDN_EVENT_RST_IND, } ftdm_sngisdn_event_id_t; +/* Only timers that can be cancelled are listed here */ +#define SNGISDN_NUM_TIMERS 1 +/* Increase NUM_TIMERS as number of ftdm_sngisdn_timer_t increases */ +typedef enum { + SNGISDN_TIMER_FACILITY = 0, +} ftdm_sngisdn_timer_t; + typedef struct sngisdn_glare_data { int16_t suId; uint32_t suInstId; @@ -148,6 +156,7 @@ typedef struct sngisdn_chan_data { uint8_t globalFlg; sngisdn_glare_data_t glare; + ftdm_timer_t *timers[SNGISDN_NUM_TIMERS]; } sngisdn_chan_data_t; /* Span specific data */ @@ -165,6 +174,7 @@ typedef struct sngisdn_span_data { uint8_t overlap_dial; uint8_t setup_arb; uint8_t facility; + int8_t facility_timeout; ftdm_sched_t *sched; ftdm_queue_t *event_queue; } sngisdn_span_data_t; @@ -223,8 +233,8 @@ typedef struct sngisdn_cc { ftdm_trunk_type_t trunktype; uint32_t last_suInstId; ftdm_mutex_t *mutex; - sngisdn_chan_data_t *active_spInstIds[MAX_INSTID]; - sngisdn_chan_data_t *active_suInstIds[MAX_INSTID]; + sngisdn_chan_data_t *active_spInstIds[MAX_INSTID+1]; + sngisdn_chan_data_t *active_suInstIds[MAX_INSTID+1]; }sngisdn_cc_t; /* Global sngisdn data */ @@ -349,6 +359,7 @@ void sngisdn_set_span_sig_status(ftdm_span_t *ftdmspan, ftdm_signaling_status_t void sngisdn_delayed_release(void* p_sngisdn_info); void sngisdn_delayed_connect(void* p_sngisdn_info); void sngisdn_delayed_disconnect(void* p_sngisdn_info); +void sngisdn_facility_timeout(void* p_sngisdn_info); /* Stack management functions */ ftdm_status_t sng_isdn_stack_cfg(ftdm_span_t *span); diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c index ec44142303..96eaf051a2 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c @@ -249,6 +249,11 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_ ftdm_span_set_bearer_capability(val, &span->default_caller_data.bearer_capability); } else if (!strcasecmp(var, "outbound-bearer_layer1")) { ftdm_span_set_bearer_layer1(val, &span->default_caller_data.bearer_layer1); + } else if (!strcasecmp(var, "facility-timeout")) { + signal_data->facility_timeout = atoi(val); + if (signal_data->facility_timeout < 0) { + signal_data->facility_timeout = 0; + } } else { ftdm_log(FTDM_LOG_WARNING, "Ignoring unknown parameter %s\n", ftdm_parameters[paramindex].var); } diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c index c3d97e5c5c..ff9a53b294 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c @@ -78,14 +78,13 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event) } sngisdn_info->suInstId = get_unique_suInstId(suId); - sngisdn_info->spInstId = spInstId; + sngisdn_info->spInstId = spInstId; /* If this is a glared call that was previously saved, we moved all the info to the current call, so clear the glared saved data */ - if (sngisdn_info->glare.spInstId == spInstId) { clear_call_glare_data(sngisdn_info); - } + } ftdm_mutex_lock(g_sngisdn_data.ccs[suId].mutex); g_sngisdn_data.ccs[suId].active_suInstIds[sngisdn_info->suInstId] = sngisdn_info; @@ -105,7 +104,8 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event) ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_TEMPORARY_FAILURE; ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_CANCEL); break; - } + } + /* Fill in call information */ cpy_calling_num_from_stack(&ftdmchan->caller_data, &conEvnt->cgPtyNmb); cpy_called_num_from_stack(&ftdmchan->caller_data, &conEvnt->cdPtyNmb); @@ -142,6 +142,10 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event) if (ret_val == 1) { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Expecting Caller name in FACILITY\n"); ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_GET_CALLERID); + /* Launch timer in case we never get a FACILITY msg */ + if (signal_data->facility_timeout) { + ftdm_sched_timer(signal_data->sched, "facility_timeout", signal_data->facility_timeout, sngisdn_facility_timeout, (void*) sngisdn_info, &sngisdn_info->timers[SNGISDN_TIMER_FACILITY]); + } break; } else if (ret_val == 0) { strcpy(ftdmchan->caller_data.cid_name, retrieved_str); @@ -289,6 +293,8 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event) sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info; ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan; + sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; + CnStEvnt *cnStEvnt = &sngisdn_event->event.cnStEvnt; ftdm_assert(!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE), "State change flag pending\n"); @@ -302,19 +308,49 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event) suId, suInstId, spInstId, ces); switch(evntType) { + case MI_PROGRESS: + if (signal_data->switchtype == SNGISDN_SWITCH_NI2 && + cnStEvnt->causeDgn[0].eh.pres && cnStEvnt->causeDgn[0].causeVal.pres) { + + switch(cnStEvnt->causeDgn[0].causeVal.val) { + case 17: /* User Busy */ + case 18: /* No User responding */ + case 19: /* User alerting, no answer */ + case 21: /* Call rejected, the called party does not with to accept this call */ + case 27: /* Destination out of order */ + case 31: /* Normal, unspecified */ + case 34: /* Circuit/Channel congestion */ + case 41: /* Temporary failure */ + case 42: /* Switching equipment is experiencing a period of high traffic */ + case 47: /* Resource unavailable */ + case 58: /* Bearer Capability not available */ + case 63: /* Service or option not available */ + case 65: /* Bearer Cap not implemented, not supported */ + case 79: /* Service or option not implemented, unspecified */ + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Cause requires disconnect (cause:%d)\n", cnStEvnt->causeDgn[0].causeVal.val); + ftdmchan->caller_data.hangup_cause = cnStEvnt->causeDgn[0].causeVal.val; + + sngisdn_set_flag(sngisdn_info, FLAG_SEND_DISC); + ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); + goto sngisdn_process_cnst_ind_end; + } + } + /* fall-through */ case MI_ALERTING: case MI_CALLPROC: - case MI_PROGRESS: + switch(ftdmchan->state) { - case FTDM_CHANNEL_STATE_DIALING: - if (evntType == MI_PROGRESS) { + case FTDM_CHANNEL_STATE_DIALING: + if (evntType == MI_PROGRESS || + (cnStEvnt->progInd.eh.pres && cnStEvnt->progInd.progDesc.val == IN_PD_IBAVAIL)) { ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA); } else { ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS); } break; case FTDM_CHANNEL_STATE_PROGRESS: - if (evntType == MI_PROGRESS) { + if (evntType == MI_PROGRESS || + (cnStEvnt->progInd.eh.pres && cnStEvnt->progInd.progDesc.val == IN_PD_IBAVAIL)) { ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA); } break; @@ -371,6 +407,7 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event) break; } +sngisdn_process_cnst_ind_end: ISDN_FUNC_TRACE_EXIT(__FUNCTION__); return; } @@ -638,12 +675,14 @@ void sngisdn_process_flc_ind (sngisdn_event_data_t *sngisdn_event) void sngisdn_process_fac_ind (sngisdn_event_data_t *sngisdn_event) { ISDN_FUNC_TRACE_ENTER(__FUNCTION__); + int16_t suId = sngisdn_event->suId; uint32_t suInstId = sngisdn_event->suInstId; uint32_t spInstId = sngisdn_event->spInstId; sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info; ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan; + sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; FacEvnt *facEvnt = &sngisdn_event->event.facEvnt; @@ -659,10 +698,16 @@ void sngisdn_process_fac_ind (sngisdn_event_data_t *sngisdn_event) if (sng_isdn_retrieve_facility_caller_name(facility_str, facEvnt->facElmt.facStr.len, retrieved_str) != FTDM_SUCCESS) { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Failed to retrieve Caller Name from Facility IE\n"); } + /* Cancel facility timeout */ + ftdm_sched_cancel_timer(signal_data->sched, &sngisdn_info->timers[SNGISDN_TIMER_FACILITY]); } ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING); break; + case FTDM_CHANNEL_STATE_RING: + /* We received the caller ID Name in FACILITY, but its too late, facility-timeout already occurred */ + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "FACILITY received, but we already proceeded with call\n"); + break; default: /* We do not support other FACILITY types for now, so do nothing */ break; @@ -794,6 +839,14 @@ void sngisdn_process_sta_cfm (sngisdn_event_data_t *sngisdn_event) break; case 3: switch (ftdmchan->state) { + case FTDM_CHANNEL_STATE_PROGRESS: + /* T310 timer has expired */ + ftdmchan->caller_data.hangup_cause = staEvnt->causeDgn[0].causeVal.val; + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "T310 Timer expired, hanging up call\n"); + sngisdn_set_flag(sngisdn_info, FLAG_SEND_DISC); + ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); + + break; case FTDM_CHANNEL_STATE_UP: /* Remote side is still waiting for our CONNECT message */ if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c index 29cfb2330e..f921b1be8c 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c @@ -45,8 +45,8 @@ void sngisdn_rcv_con_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, Co { ISDN_FUNC_TRACE_ENTER(__FUNCTION__); uint8_t bchan_no = 0; - sngisdn_chan_data_t *sngisdn_info; - sngisdn_event_data_t *sngisdn_event; + sngisdn_chan_data_t *sngisdn_info = NULL; + sngisdn_event_data_t *sngisdn_event = NULL; ftdm_assert(g_sngisdn_data.ccs[suId].activation_done != 0, "Con Ind on unconfigured cc\n"); ftdm_assert(g_sngisdn_data.dchans[dChan].num_spans != 0, "Con Ind on unconfigured dchan\n"); @@ -96,7 +96,7 @@ void sngisdn_rcv_con_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, Co ftdm_mutex_unlock(g_sngisdn_data.ccs[suId].mutex); memcpy(&sngisdn_event->event.conEvnt, conEvnt, sizeof(*conEvnt)); - + ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event); ISDN_FUNC_TRACE_EXIT(__FUNCTION__); } @@ -104,8 +104,8 @@ void sngisdn_rcv_con_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, Co void sngisdn_rcv_con_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, CnStEvnt *cnStEvnt, int16_t dChan, uint8_t ces) { ISDN_FUNC_TRACE_ENTER(__FUNCTION__); - sngisdn_chan_data_t *sngisdn_info; - sngisdn_event_data_t *sngisdn_event; + sngisdn_chan_data_t *sngisdn_info = NULL; + sngisdn_event_data_t *sngisdn_event = NULL; ftdm_assert(g_sngisdn_data.ccs[suId].activation_done != 0, "Con Cfm on unconfigured cc\n"); ftdm_assert(g_sngisdn_data.dchans[dChan].num_spans != 0, "Con Cfm on unconfigured dchan\n"); @@ -118,6 +118,7 @@ void sngisdn_rcv_con_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, Cn if (!sngisdn_info->spInstId) { ftdm_mutex_lock(g_sngisdn_data.ccs[suId].mutex); + sngisdn_info->spInstId = spInstId; g_sngisdn_data.ccs[suId].active_spInstIds[spInstId] = sngisdn_info; ftdm_mutex_unlock(g_sngisdn_data.ccs[suId].mutex); @@ -146,8 +147,8 @@ void sngisdn_rcv_con_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, Cn void sngisdn_rcv_cnst_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, CnStEvnt *cnStEvnt, uint8_t evntType, int16_t dChan, uint8_t ces) { ISDN_FUNC_TRACE_ENTER(__FUNCTION__); - sngisdn_chan_data_t *sngisdn_info; - sngisdn_event_data_t *sngisdn_event; + sngisdn_chan_data_t *sngisdn_info = NULL; + sngisdn_event_data_t *sngisdn_event = NULL; ftdm_assert(g_sngisdn_data.ccs[suId].activation_done != 0, "Cnst Ind on unconfigured cc\n"); ftdm_assert(g_sngisdn_data.dchans[dChan].num_spans != 0, "Cnst Ind on unconfigured dchan\n"); @@ -160,6 +161,7 @@ void sngisdn_rcv_cnst_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, C if (!sngisdn_info->spInstId) { ftdm_mutex_lock(g_sngisdn_data.ccs[suId].mutex); + sngisdn_info->spInstId = spInstId; g_sngisdn_data.ccs[suId].active_spInstIds[spInstId] = sngisdn_info; ftdm_mutex_unlock(g_sngisdn_data.ccs[suId].mutex); @@ -188,15 +190,15 @@ void sngisdn_rcv_cnst_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, C memcpy(&sngisdn_event->event.cnStEvnt, cnStEvnt, sizeof(*cnStEvnt)); - ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event); + ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event); ISDN_FUNC_TRACE_EXIT(__FUNCTION__); } void sngisdn_rcv_disc_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, DiscEvnt *discEvnt) { ISDN_FUNC_TRACE_ENTER(__FUNCTION__); - sngisdn_chan_data_t *sngisdn_info; - sngisdn_event_data_t *sngisdn_event; + sngisdn_chan_data_t *sngisdn_info = NULL; + sngisdn_event_data_t *sngisdn_event = NULL; ftdm_assert(spInstId != 0, "Received DISCONNECT with invalid id"); @@ -207,13 +209,6 @@ void sngisdn_rcv_disc_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, D ftdm_assert(0, "Inconsistent call states\n"); return; } - - if (!sngisdn_info->spInstId) { - ftdm_mutex_lock(g_sngisdn_data.ccs[suId].mutex); - sngisdn_info->spInstId = spInstId; - g_sngisdn_data.ccs[suId].active_spInstIds[spInstId] = sngisdn_info; - ftdm_mutex_unlock(g_sngisdn_data.ccs[suId].mutex); - } ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received DISCONNECT (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); @@ -229,7 +224,7 @@ void sngisdn_rcv_disc_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, D memcpy(&sngisdn_event->event.discEvnt, discEvnt, sizeof(*discEvnt)); - ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event); + ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event); ISDN_FUNC_TRACE_EXIT(__FUNCTION__); } @@ -237,8 +232,8 @@ void sngisdn_rcv_disc_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, D void sngisdn_rcv_rel_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, RelEvnt *relEvnt) { ISDN_FUNC_TRACE_ENTER(__FUNCTION__); - sngisdn_chan_data_t *sngisdn_info; - sngisdn_event_data_t *sngisdn_event; + sngisdn_chan_data_t *sngisdn_info = NULL; + sngisdn_event_data_t *sngisdn_event = NULL; if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) && !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) { @@ -251,7 +246,7 @@ void sngisdn_rcv_rel_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, Re ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received RELEASE/RELEASE COMPLETE (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event, "Failed to allocate memory\n"); + ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n"); memset(sngisdn_event, 0, sizeof(*sngisdn_event)); sngisdn_event->event_id = SNGISDN_EVENT_REL_IND; @@ -270,7 +265,7 @@ void sngisdn_rcv_dat_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, In { ISDN_FUNC_TRACE_ENTER(__FUNCTION__); sngisdn_chan_data_t *sngisdn_info; - sngisdn_event_data_t *sngisdn_event; + sngisdn_event_data_t *sngisdn_event = NULL; if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) && !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) { @@ -283,7 +278,7 @@ void sngisdn_rcv_dat_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, In ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received DATA IND suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId); sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event, "Failed to allocate memory\n"); + ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n"); memset(sngisdn_event, 0, sizeof(*sngisdn_event)); sngisdn_event->event_id = SNGISDN_EVENT_DAT_IND; @@ -302,7 +297,7 @@ void sngisdn_rcv_sshl_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, S { ISDN_FUNC_TRACE_ENTER(__FUNCTION__); sngisdn_chan_data_t *sngisdn_info; - sngisdn_event_data_t *sngisdn_event; + sngisdn_event_data_t *sngisdn_event = NULL; if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) && !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) { @@ -315,7 +310,7 @@ void sngisdn_rcv_sshl_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, S ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received SSHL IND (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event, "Failed to allocate memory\n"); + ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n"); memset(sngisdn_event, 0, sizeof(*sngisdn_event)); sngisdn_event->event_id = SNGISDN_EVENT_SSHL_IND; @@ -335,7 +330,7 @@ void sngisdn_rcv_sshl_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, S { ISDN_FUNC_TRACE_ENTER(__FUNCTION__); sngisdn_chan_data_t *sngisdn_info; - sngisdn_event_data_t *sngisdn_event; + sngisdn_event_data_t *sngisdn_event = NULL; if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) && !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) { @@ -348,7 +343,7 @@ void sngisdn_rcv_sshl_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, S ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received SSHL CFM (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event, "Failed to allocate memory\n"); + ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n"); memset(sngisdn_event, 0, sizeof(*sngisdn_event)); sngisdn_event->event_id = SNGISDN_EVENT_SSHL_CFM; @@ -360,14 +355,14 @@ void sngisdn_rcv_sshl_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, S memcpy(&sngisdn_event->event.ssHlEvnt, ssHlEvnt, sizeof(*ssHlEvnt)); - ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event); + ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event); ISDN_FUNC_TRACE_EXIT(__FUNCTION__); } void sngisdn_rcv_rmrt_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, RmRtEvnt *rmRtEvnt, uint8_t action) { ISDN_FUNC_TRACE_ENTER(__FUNCTION__); sngisdn_chan_data_t *sngisdn_info; - sngisdn_event_data_t *sngisdn_event; + sngisdn_event_data_t *sngisdn_event = NULL; if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) && !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) { @@ -380,7 +375,7 @@ void sngisdn_rcv_rmrt_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, R ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received RMRT IND (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event, "Failed to allocate memory\n"); + ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n"); memset(sngisdn_event, 0, sizeof(*sngisdn_event)); sngisdn_event->event_id = SNGISDN_EVENT_RMRT_IND; @@ -392,7 +387,7 @@ void sngisdn_rcv_rmrt_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, R memcpy(&sngisdn_event->event.rmRtEvnt, rmRtEvnt, sizeof(*rmRtEvnt)); - ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event); + ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event); ISDN_FUNC_TRACE_EXIT(__FUNCTION__); } @@ -400,7 +395,7 @@ void sngisdn_rcv_rmrt_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, R { ISDN_FUNC_TRACE_ENTER(__FUNCTION__); sngisdn_chan_data_t *sngisdn_info; - sngisdn_event_data_t *sngisdn_event; + sngisdn_event_data_t *sngisdn_event = NULL; if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) && !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) { @@ -413,7 +408,7 @@ void sngisdn_rcv_rmrt_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, R ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received RESUME/RETRIEVE CFM (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event, "Failed to allocate memory\n"); + ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n"); memset(sngisdn_event, 0, sizeof(*sngisdn_event)); sngisdn_event->event_id = SNGISDN_EVENT_RMRT_CFM; @@ -425,7 +420,7 @@ void sngisdn_rcv_rmrt_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, R memcpy(&sngisdn_event->event.rmRtEvnt, rmRtEvnt, sizeof(*rmRtEvnt)); - ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event); + ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event); ISDN_FUNC_TRACE_EXIT(__FUNCTION__); } @@ -433,7 +428,7 @@ void sngisdn_rcv_flc_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, St { ISDN_FUNC_TRACE_ENTER(__FUNCTION__); sngisdn_chan_data_t *sngisdn_info; - sngisdn_event_data_t *sngisdn_event; + sngisdn_event_data_t *sngisdn_event = NULL; if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) && !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) { @@ -446,7 +441,7 @@ void sngisdn_rcv_flc_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, St ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received FLOW CONTROL IND (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event, "Failed to allocate memory\n"); + ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n"); memset(sngisdn_event, 0, sizeof(*sngisdn_event)); sngisdn_event->event_id = SNGISDN_EVENT_FLC_IND; @@ -457,7 +452,7 @@ void sngisdn_rcv_flc_ind (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_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event); ISDN_FUNC_TRACE_EXIT(__FUNCTION__); } @@ -466,7 +461,7 @@ void sngisdn_rcv_fac_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, Fa { ISDN_FUNC_TRACE_ENTER(__FUNCTION__); sngisdn_chan_data_t *sngisdn_info; - sngisdn_event_data_t *sngisdn_event; + sngisdn_event_data_t *sngisdn_event = NULL; if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) && !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) { @@ -478,7 +473,7 @@ void sngisdn_rcv_fac_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, Fa ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received FACILITY IND (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event, "Failed to allocate memory\n"); + ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n"); memset(sngisdn_event, 0, sizeof(*sngisdn_event)); sngisdn_event->event_id = SNGISDN_EVENT_FAC_IND; @@ -499,7 +494,7 @@ void sngisdn_rcv_sta_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, St { ISDN_FUNC_TRACE_ENTER(__FUNCTION__); sngisdn_chan_data_t *sngisdn_info; - sngisdn_event_data_t *sngisdn_event; + sngisdn_event_data_t *sngisdn_event = NULL; if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) && !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) { @@ -512,7 +507,7 @@ void sngisdn_rcv_sta_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, St ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received STATUS CONFIRM (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event, "Failed to allocate memory\n"); + ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n"); memset(sngisdn_event, 0, sizeof(*sngisdn_event)); sngisdn_event->event_id = SNGISDN_EVENT_STA_CFM; @@ -532,7 +527,7 @@ void sngisdn_rcv_srv_ind (int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces ISDN_FUNC_TRACE_ENTER(__FUNCTION__); unsigned i; sngisdn_span_data_t *signal_data; - sngisdn_event_data_t *sngisdn_event; + sngisdn_event_data_t *sngisdn_event = NULL; ftdm_log(FTDM_LOG_INFO, "Received SERVICE IND (dChan:%d ces:%u)\n", dChan, ces); @@ -540,7 +535,7 @@ void sngisdn_rcv_srv_ind (int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces for(i=1; i<=g_sngisdn_data.dchans[dChan].num_spans; i++) { signal_data = g_sngisdn_data.dchans[dChan].spans[i]; sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event, "Failed to allocate memory\n"); + ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n"); memset(sngisdn_event, 0, sizeof(*sngisdn_event)); sngisdn_event->event_id = SNGISDN_EVENT_SRV_IND; @@ -550,7 +545,7 @@ void sngisdn_rcv_srv_ind (int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces sngisdn_event->signal_data = signal_data; memcpy(&sngisdn_event->event.srvEvnt, srvEvnt, sizeof(*srvEvnt)); - ftdm_queue_enqueue((signal_data)->event_queue, sngisdn_event); + ftdm_queue_enqueue((signal_data)->event_queue, sngisdn_event); } ISDN_FUNC_TRACE_EXIT(__FUNCTION__); } @@ -560,8 +555,8 @@ void sngisdn_rcv_srv_cfm (int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces { ISDN_FUNC_TRACE_ENTER(__FUNCTION__); unsigned i; - sngisdn_span_data_t *signal_data; - sngisdn_event_data_t *sngisdn_event; + sngisdn_span_data_t *signal_data = NULL; + sngisdn_event_data_t *sngisdn_event = NULL; ftdm_log(FTDM_LOG_INFO, "Received SERVICE CFM (dChan:%d ces:%u)\n", dChan, ces); @@ -569,7 +564,7 @@ void sngisdn_rcv_srv_cfm (int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces for(i=1; i<=g_sngisdn_data.dchans[dChan].num_spans; i++) { signal_data = g_sngisdn_data.dchans[dChan].spans[i]; sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event, "Failed to allocate memory\n"); + ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n"); memset(sngisdn_event, 0, sizeof(*sngisdn_event)); sngisdn_event->event_id = SNGISDN_EVENT_SRV_CFM; @@ -588,8 +583,8 @@ void sngisdn_rcv_rst_ind (int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces { ISDN_FUNC_TRACE_ENTER(__FUNCTION__); unsigned i; - sngisdn_span_data_t *signal_data; - sngisdn_event_data_t *sngisdn_event; + sngisdn_span_data_t *signal_data = NULL; + sngisdn_event_data_t *sngisdn_event = NULL; ftdm_log(FTDM_LOG_INFO, "Received RESTART IND (dChan:%d ces:%u type:%u)\n", dChan, ces, evntType); @@ -597,7 +592,7 @@ void sngisdn_rcv_rst_ind (int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces for(i=1; i<=g_sngisdn_data.dchans[dChan].num_spans; i++) { signal_data = g_sngisdn_data.dchans[dChan].spans[i]; sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event, "Failed to allocate memory\n"); + ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n"); memset(sngisdn_event, 0, sizeof(*sngisdn_event)); sngisdn_event->event_id = SNGISDN_EVENT_RST_IND; @@ -618,7 +613,7 @@ void sngisdn_rcv_rst_cfm (int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces ISDN_FUNC_TRACE_ENTER(__FUNCTION__); unsigned i; sngisdn_span_data_t *signal_data; - sngisdn_event_data_t *sngisdn_event; + sngisdn_event_data_t *sngisdn_event = NULL; ftdm_log(FTDM_LOG_INFO, "Received RESTART CFM (dChan:%d ces:%u type:%u)\n", dChan, ces, evntType); @@ -626,7 +621,7 @@ void sngisdn_rcv_rst_cfm (int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces for(i=1; i<=g_sngisdn_data.dchans[dChan].num_spans; i++) { signal_data = g_sngisdn_data.dchans[dChan].spans[i]; sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event, "Failed to allocate memory\n"); + ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n"); memset(sngisdn_event, 0, sizeof(*sngisdn_event)); sngisdn_event->event_id = SNGISDN_EVENT_RST_CFM; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c index 29e7994c87..5e37e0c684 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c @@ -73,8 +73,10 @@ void __inline__ clear_call_glare_data(sngisdn_chan_data_t *sngisdn_info) sngisdn_info->glare.suInstId, sngisdn_info->glare.spInstId, sngisdn_info->suInstId, sngisdn_info->spInstId); - ftdm_mutex_lock(g_sngisdn_data.ccs[sngisdn_info->glare.suId].mutex); - g_sngisdn_data.ccs[sngisdn_info->glare.suId].active_spInstIds[sngisdn_info->glare.spInstId]=NULL; + ftdm_mutex_lock(g_sngisdn_data.ccs[sngisdn_info->glare.suId].mutex); + if (sngisdn_info->glare.spInstId != sngisdn_info->spInstId) { + g_sngisdn_data.ccs[sngisdn_info->glare.suId].active_spInstIds[sngisdn_info->glare.spInstId]=NULL; + } g_sngisdn_data.ccs[sngisdn_info->glare.suId].active_suInstIds[sngisdn_info->glare.suInstId]=NULL; ftdm_mutex_unlock(g_sngisdn_data.ccs[sngisdn_info->glare.suId].mutex); @@ -427,6 +429,24 @@ void sngisdn_delayed_disconnect(void* p_sngisdn_info) return; } +void sngisdn_facility_timeout(void* p_sngisdn_info) +{ + sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*)p_sngisdn_info; + ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan; + sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; + + ftdm_mutex_lock(ftdmchan->mutex); + if (ftdmchan->state == FTDM_CHANNEL_STATE_GET_CALLERID) { + ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Facility timeout reached proceeding with call (suId:%d suInstId:%u spInstId:%u)\n", + signal_data->cc_id, sngisdn_info->spInstId, sngisdn_info->suInstId); + + ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING); + } + + ftdm_mutex_unlock(ftdmchan->mutex); + return; +} + ftdm_status_t sngisdn_check_free_ids(void) { unsigned i;