freetdm: Fix for DL re-establishment on NFAS

This commit is contained in:
David Yat Sin 2012-09-18 23:11:05 -04:00
parent 96da521634
commit 2aa5b78514
5 changed files with 31 additions and 6 deletions

View File

@ -1,3 +1,4 @@
/* /*
* Copyright (c) 2010, Sangoma Technologies * Copyright (c) 2010, Sangoma Technologies
* David Yat Sin <davidy@sangoma.com> * David Yat Sin <davidy@sangoma.com>
@ -40,7 +41,6 @@
#include <sys/mman.h> #include <sys/mman.h>
#endif #endif
static void *ftdm_sangoma_isdn_run(ftdm_thread_t *me, void *obj); static void *ftdm_sangoma_isdn_run(ftdm_thread_t *me, void *obj);
static ftdm_status_t ftdm_sangoma_isdn_stop(ftdm_span_t *span); static ftdm_status_t ftdm_sangoma_isdn_stop(ftdm_span_t *span);
static ftdm_status_t ftdm_sangoma_isdn_start(ftdm_span_t *span); static ftdm_status_t ftdm_sangoma_isdn_start(ftdm_span_t *span);
@ -696,7 +696,7 @@ static ftdm_status_t ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdm
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Requesting Q.921 Line activation\n"); ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Requesting Q.921 Line activation\n");
sngisdn_set_flag(sngisdn_info, FLAG_ACTIVATING); sngisdn_set_flag(sngisdn_info, FLAG_ACTIVATING);
sngisdn_snd_info_req(ftdmchan); sngisdn_snd_dl_req(ftdmchan);
ftdm_sched_timer(signal_data->sched, "timer_t3", signal_data->timer_t3*1000, sngisdn_t3_timeout, (void*) sngisdn_info, NULL); ftdm_sched_timer(signal_data->sched, "timer_t3", signal_data->timer_t3*1000, sngisdn_t3_timeout, (void*) sngisdn_info, NULL);
} else { } else {
sngisdn_snd_setup(ftdmchan); sngisdn_snd_setup(ftdmchan);

View File

@ -289,6 +289,8 @@ typedef struct sngisdn_span_data {
uint8_t cid_name_method; uint8_t cid_name_method;
uint8_t send_cid_name; uint8_t send_cid_name;
uint8_t send_connect_ack; uint8_t send_connect_ack;
uint8_t dl_request_pending; /* Whether we have a DL request pending */
int32_t timer_t301; int32_t timer_t301;
int32_t timer_t302; int32_t timer_t302;
@ -441,7 +443,7 @@ void sngisdn_snd_release(ftdm_channel_t *ftdmchan, uint8_t glare);
void sngisdn_snd_reset(ftdm_channel_t *ftdmchan); void sngisdn_snd_reset(ftdm_channel_t *ftdmchan);
void sngisdn_snd_con_complete(ftdm_channel_t *ftdmchan); void sngisdn_snd_con_complete(ftdm_channel_t *ftdmchan);
void sngisdn_snd_fac_req(ftdm_channel_t *ftdmchan); void sngisdn_snd_fac_req(ftdm_channel_t *ftdmchan);
void sngisdn_snd_info_req(ftdm_channel_t *ftdmchan); void sngisdn_snd_dl_req(ftdm_channel_t *ftdmchan);
void sngisdn_snd_status_enq(ftdm_channel_t *ftdmchan); void sngisdn_snd_status_enq(ftdm_channel_t *ftdmchan);
void sngisdn_snd_restart(ftdm_channel_t *ftdmchan); void sngisdn_snd_restart(ftdm_channel_t *ftdmchan);
void sngisdn_snd_data(ftdm_channel_t *dchan, uint8_t *data, ftdm_size_t len); void sngisdn_snd_data(ftdm_channel_t *dchan, uint8_t *data, ftdm_size_t len);
@ -581,6 +583,7 @@ void sngisdn_delayed_disconnect(void* p_sngisdn_info);
void sngisdn_facility_timeout(void* p_sngisdn_info); void sngisdn_facility_timeout(void* p_sngisdn_info);
void sngisdn_t3_timeout(void* p_sngisdn_info); void sngisdn_t3_timeout(void* p_sngisdn_info);
void sngisdn_restart_timeout(void* p_signal_data); void sngisdn_restart_timeout(void* p_signal_data);
void sngisdn_delayed_dl_req(void* p_signal_data);
/* Stack management functions */ /* Stack management functions */
ftdm_status_t sngisdn_start_gen_cfg(void); ftdm_status_t sngisdn_start_gen_cfg(void);

View File

@ -70,6 +70,10 @@ void sngisdn_set_span_sig_status(ftdm_span_t *span, ftdm_signaling_status_t stat
((sngisdn_span_data_t*)span->signal_data)->sigstatus = status; ((sngisdn_span_data_t*)span->signal_data)->sigstatus = status;
if (status == FTDM_SIG_STATE_UP) {
((sngisdn_span_data_t*)span->signal_data)->dl_request_pending = 0;
}
chaniter = ftdm_span_get_chan_iterator(span, NULL); chaniter = ftdm_span_get_chan_iterator(span, NULL);
for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) { for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
sngisdn_set_chan_sig_status(((ftdm_channel_t*)ftdm_iterator_current(curr)), status); sngisdn_set_chan_sig_status(((ftdm_channel_t*)ftdm_iterator_current(curr)), status);

View File

@ -307,7 +307,7 @@ void sngisdn_snd_fac_req(ftdm_channel_t *ftdmchan)
} }
/* This is used to request Q.921 to initiate link establishment */ /* This is used to request Q.921 to initiate link establishment */
void sngisdn_snd_info_req(ftdm_channel_t *ftdmchan) void sngisdn_snd_dl_req(ftdm_channel_t *ftdmchan)
{ {
CnStEvnt cnStEvnt; CnStEvnt cnStEvnt;
@ -482,6 +482,9 @@ void sngisdn_snd_data(ftdm_channel_t *dchan, uint8_t *data, ftdm_size_t len)
len, sizeof(l1_frame.data)); len, sizeof(l1_frame.data));
return; return;
} }
if (len <= 2) {
return;
}
memset(&l1_frame, 0, sizeof(l1_frame)); memset(&l1_frame, 0, sizeof(l1_frame));
l1_frame.len = len; l1_frame.len = len;
@ -546,7 +549,8 @@ void sngisdn_snd_event(sngisdn_span_data_t *signal_data, ftdm_oob_event_t event)
l1_event.type = SNG_L1EVENT_ALARM_OFF; l1_event.type = SNG_L1EVENT_ALARM_OFF;
sng_isdn_event_ind(signal_data->link_id, &l1_event); sng_isdn_event_ind(signal_data->link_id, &l1_event);
sngisdn_snd_info_req(signal_data->ftdm_span->channels[1]); ftdm_sched_timer(signal_data->sched, "delayed_dl_req", 8000, sngisdn_delayed_dl_req, (void*) signal_data, NULL);
signal_data->dl_request_pending = 1;
break; break;
case FTDM_OOB_ALARM_TRAP: case FTDM_OOB_ALARM_TRAP:
l1_event.type = SNG_L1EVENT_ALARM_ON; l1_event.type = SNG_L1EVENT_ALARM_ON;

View File

@ -1211,6 +1211,20 @@ void sngisdn_t3_timeout(void *p_sngisdn_info)
ftdm_mutex_unlock(ftdmchan->mutex); ftdm_mutex_unlock(ftdmchan->mutex);
} }
void sngisdn_delayed_dl_req(void *p_signal_data)
{
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t *)p_signal_data;
ftdm_span_t *span = signal_data->ftdm_span;
if (!signal_data->dl_request_pending) {
return;
}
signal_data->dl_request_pending = 0;
sngisdn_snd_dl_req(span->channels[1]);
return;
}
void sngisdn_restart_timeout(void *p_signal_data) void sngisdn_restart_timeout(void *p_signal_data)
{ {
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t *)p_signal_data; sngisdn_span_data_t *signal_data = (sngisdn_span_data_t *)p_signal_data;