From 8a25c67d40b4cf2867d1266ed657226f82e81b7b Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Tue, 11 Sep 2012 01:22:31 -0400 Subject: [PATCH] Freetdm: ISDN fix for link not always recovering after T1/E1 alarm --- .../ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c | 5 ++++- .../ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h | 1 + .../ftmod_sangoma_isdn_stack_cfg.c | 15 ++++++++++----- .../ftmod_sangoma_isdn_stack_cntrl.c | 5 +++++ .../ftmod_sangoma_isdn_stack_out.c | 13 ++++--------- .../ftmod_sangoma_isdn_stack_rcv.c | 11 +++++++++-- .../ftmod_sangoma_isdn_support.c | 4 ++++ 7 files changed, 37 insertions(+), 17 deletions(-) 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 65f17fa47b..2483c01094 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 @@ -1376,8 +1376,11 @@ static FIO_SIG_LOAD_FUNCTION(ftdm_sangoma_isdn_init) } /* initalize sng_isdn library */ - ftdm_assert_return(!sng_isdn_init(&g_sngisdn_event_interface), FTDM_FAIL, "Failed to initialize stack\n"); + + /* Load Stack General Configuration */ + sngisdn_start_gen_cfg(); + return FTDM_SUCCESS; } 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 fc93155ffa..40a89a80c8 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 @@ -583,6 +583,7 @@ void sngisdn_t3_timeout(void* p_sngisdn_info); void sngisdn_restart_timeout(void* p_signal_data); /* Stack management functions */ +ftdm_status_t sngisdn_start_gen_cfg(void); ftdm_status_t sngisdn_stack_cfg(ftdm_span_t *span); ftdm_status_t sngisdn_stack_start(ftdm_span_t *span); ftdm_status_t sngisdn_stack_stop(ftdm_span_t *span); diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cfg.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cfg.c index 52daf3ad7b..946b9769b0 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cfg.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cfg.c @@ -58,12 +58,8 @@ ftdm_status_t sngisdn_stack_cfg_q931_lce(ftdm_span_t *span); ftdm_status_t sngisdn_stack_cfg_cc_sap(ftdm_span_t *span); -ftdm_status_t sngisdn_stack_cfg(ftdm_span_t *span) +ftdm_status_t sngisdn_start_gen_cfg(void) { - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data; - - ftdm_log(FTDM_LOG_DEBUG, "Starting stack configuration for span:%s\n", span->name); - if (!g_sngisdn_data.gen_config_done) { g_sngisdn_data.gen_config_done = 1; ftdm_log(FTDM_LOG_DEBUG, "Starting general stack configuration\n"); @@ -92,6 +88,15 @@ ftdm_status_t sngisdn_stack_cfg(ftdm_span_t *span) ftdm_log(FTDM_LOG_DEBUG, "General stack CC done\n"); ftdm_log(FTDM_LOG_INFO, "General stack configuration done\n"); } + return FTDM_SUCCESS; +} + + +ftdm_status_t sngisdn_stack_cfg(ftdm_span_t *span) +{ + sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data; + + ftdm_log(FTDM_LOG_DEBUG, "Starting stack configuration for span:%s\n", span->name); if (signal_data->dchan) { if (sngisdn_stack_cfg_phy_psap(span) != FTDM_SUCCESS) { diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cntrl.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cntrl.c index 1cc23ddb8d..d745efed0b 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cntrl.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cntrl.c @@ -232,6 +232,11 @@ ftdm_status_t sngisdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t trac { sngisdn_span_data_t *signal_data = sngisdn_dchan((sngisdn_span_data_t*)span->signal_data); + if (!signal_data) { + ftdm_log(FTDM_LOG_ERROR, "%s:Span is not used by signalling module\n", span->name); + return FTDM_FAIL; + } + switch (trace_opt) { case SNGISDN_TRACE_DISABLE: if (sngisdn_test_trace_flag(signal_data, SNGISDN_TRACE_Q921)) { diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c index b05ee41356..9055f7006b 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c @@ -314,19 +314,12 @@ void sngisdn_snd_info_req(ftdm_channel_t *ftdmchan) sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data; sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; - if (ftdmchan->span->trunk_type != FTDM_TRUNK_BRI && - ftdmchan->span->trunk_type != FTDM_TRUNK_BRI_PTMP) { - - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Ignoring INFO REQ on non-BRI channel\n"); - return; - } - memset(&cnStEvnt, 0, sizeof(cnStEvnt)); - ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending INFO REQ (suId:%d dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_dchan(signal_data)->link_id, sngisdn_info->ces); + ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Requesting Link establishment (suId:%d dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_dchan(signal_data)->link_id, sngisdn_info->ces); if (sng_isdn_con_status(signal_data->cc_id, 0, 0, &cnStEvnt, MI_INFO, sngisdn_dchan(signal_data)->link_id, sngisdn_info->ces)) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused INFO request\n"); + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused Link establishment\n"); } return; } @@ -552,6 +545,8 @@ void sngisdn_snd_event(sngisdn_span_data_t *signal_data, ftdm_oob_event_t event) case FTDM_OOB_ALARM_CLEAR: l1_event.type = SNG_L1EVENT_ALARM_OFF; sng_isdn_event_ind(signal_data->link_id, &l1_event); + + sngisdn_snd_info_req(signal_data->ftdm_span->channels[1]); break; case FTDM_OOB_ALARM_TRAP: l1_event.type = SNG_L1EVENT_ALARM_ON; 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 a5ba7c54b9..34b4150ac0 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 @@ -525,10 +525,17 @@ void sngisdn_rcv_sta_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, St ISDN_FUNC_TRACE_ENTER(__FUNCTION__); + if (!suInstId && !spInstId) { + /* This is a response to a sngisdn_snd_info_req + * that was sent to attempt to re-establish DL link */ + ISDN_FUNC_TRACE_EXIT(__FUNCTION__); + return; + } + /* 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); + 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)) { @@ -838,7 +845,7 @@ void sngisdn_rcv_q931_ind(InMngmt *status) if (nfas_data && status->t.usta.alarm.event == LCM_EVENT_DOWN) { if (nfas_data->dchan->sigstatus == FTDM_SIG_STATE_DOWN && - (nfas_data->backup && nfas_data->backup->sigstatus == FTDM_SIG_STATE_DOWN)) { + ((nfas_data->backup && nfas_data->backup->sigstatus == FTDM_SIG_STATE_DOWN) || !nfas_data->backup)) { for (i = 0; i < ftdm_array_len(nfas_data->spans); i++) { if (nfas_data->spans[i] && nfas_data->spans[i]->nfas.sigchan == SNGISDN_NFAS_DCHAN_NONE) { 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 5f63f384d7..8232d1969f 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 @@ -1595,6 +1595,10 @@ void sngisdn_send_signal(sngisdn_chan_data_t *sngisdn_info, ftdm_signal_event_t sngisdn_span_data_t *sngisdn_dchan(sngisdn_span_data_t *signal_data) { + if (!signal_data) { + return NULL; + } + if (!signal_data->nfas.trunk) { return signal_data; }