From ea43cacec763e9e6f347e88f32fa91ba58225a2f Mon Sep 17 00:00:00 2001 From: dyatsin Date: Sun, 22 Apr 2012 07:57:37 -0700 Subject: [PATCH 1/5] initial commit --- README.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000000..828df27ffb --- /dev/null +++ b/README.md @@ -0,0 +1,4 @@ +freeswitch +========== + +Personal Copy of Freeswitch \ No newline at end of file From 07a1093cf442a8ebc97474278de0ae0d0eeb2a06 Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Wed, 6 Jun 2012 20:41:48 -0400 Subject: [PATCH 2/5] Fix for NFAS when one of the d-channels are down --- libs/freetdm/mod_freetdm/mod_freetdm.c | 4 +- .../ftmod_sangoma_isdn/ftmod_sangoma_isdn.c | 140 +++++--- .../ftmod_sangoma_isdn/ftmod_sangoma_isdn.h | 71 ++-- .../ftmod_sangoma_isdn_cfg.c | 188 +++++++++-- .../ftmod_sangoma_isdn_cntrl.c | 4 +- .../ftmod_sangoma_isdn_stack_cfg.c | 172 ++++++---- .../ftmod_sangoma_isdn_stack_cntrl.c | 53 +-- .../ftmod_sangoma_isdn_stack_hndl.c | 46 ++- .../ftmod_sangoma_isdn_stack_out.c | 67 ++-- .../ftmod_sangoma_isdn_stack_rcv.c | 302 +++++++++++------- .../ftmod_sangoma_isdn_support.c | 37 ++- 11 files changed, 757 insertions(+), 327 deletions(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index 8b0acc3aef..a2dacafd43 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -1884,10 +1884,8 @@ static FIO_SIGNAL_CB_FUNCTION(on_common_signal) return FTDM_FAIL; } if (sigmsg->event_id == FTDM_SIGEVENT_ALARM_CLEAR) { - ftdm_log(FTDM_LOG_NOTICE, "Alarm cleared on channel %d:%d\n", spanid, chanid); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "condition", "ftdm-alarm-clear"); } else { - ftdm_log(FTDM_LOG_NOTICE, "Alarm raised on channel %d:%d\n", spanid, chanid); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "condition", "ftdm-alarm-trap"); } } @@ -2489,7 +2487,7 @@ static FIO_SIGNAL_CB_FUNCTION(on_clear_channel_signal) break; case FTDM_SIGEVENT_SIGSTATUS_CHANGED: { - ftdm_signaling_status_t sigstatus = sigmsg->ev_data.sigstatus.status; + ftdm_signaling_status_t sigstatus = sigmsg->ev_data.sigstatus.status; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%d:%d signalling changed to :%s\n", spanid, chanid, ftdm_signaling_status2str(sigstatus)); } 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 e3af9d9b98..0f9a63fde2 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 @@ -281,8 +281,8 @@ ftdm_state_map_t sangoma_isdn_state_map = { static void ftdm_sangoma_isdn_process_phy_events(ftdm_span_t *span, ftdm_oob_event_t event) { sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data; - sngisdn_snd_event(signal_data->dchan, event); - + sngisdn_snd_event(signal_data, event); + switch (event) { /* Check if the span woke up from power-saving mode */ case FTDM_OOB_ALARM_CLEAR: @@ -354,7 +354,6 @@ static void *ftdm_sangoma_isdn_io_run(ftdm_thread_t *me, void *obj) short *poll_events = ftdm_malloc(sizeof(short) * span->chan_count); /* Initialize the d-channel */ - ftdm_assert(((sngisdn_span_data_t*)span->signal_data)->dchan, "Span does not have a dchannel"); chaniter = ftdm_span_get_chan_iterator(span, NULL); if (!chaniter) { ftdm_log(FTDM_LOG_CRIT, "Failed to allocate channel iterator for span %s!\n", span->name); @@ -1039,21 +1038,11 @@ static ftdm_status_t ftdm_sangoma_isdn_dtmf(ftdm_channel_t *ftdmchan, const char return FTDM_SUCCESS; } -static ftdm_status_t ftdm_sangoma_isdn_start(ftdm_span_t *span) +static ftdm_status_t ftdm_sangoma_isdn_perform_start(ftdm_span_t *span) { sngisdn_span_data_t *signal_data = span->signal_data; - ftdm_log(FTDM_LOG_INFO,"Starting span %s:%u.\n",span->name,span->span_id); - - ftdm_channel_set_feature(((sngisdn_span_data_t*)span->signal_data)->dchan, FTDM_CHANNEL_FEATURE_IO_STATS); - ftdm_channel_open_chan(((sngisdn_span_data_t*)span->signal_data)->dchan); - ftdm_sangoma_isdn_dchan_set_queue_size(((sngisdn_span_data_t*)span->signal_data)->dchan); - - if (sngisdn_stack_start(span) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_CRIT, "Failed to start span %s\n", span->name); - return FTDM_FAIL; - } - + ftdm_log(FTDM_LOG_DEBUG, "Actually starting span:%s\n", span->name); /* clear the monitor thread stop flag */ ftdm_clear_flag(span, FTDM_SPAN_STOP_THREAD); ftdm_clear_flag(span, FTDM_SPAN_IN_THREAD); @@ -1085,12 +1074,64 @@ static ftdm_status_t ftdm_sangoma_isdn_start(ftdm_span_t *span) if (signal_data->restart_timeout) { ftdm_log(FTDM_LOG_DEBUG, "%s:Scheduling Restart timeout\n", signal_data->ftdm_span->name); ftdm_sched_timer(signal_data->sched, "restart_timeout", signal_data->restart_timeout, - sngisdn_restart_timeout, (void*) signal_data, &signal_data->timers[SNGISDN_SPAN_TIMER_RESTART]); + sngisdn_restart_timeout, (void*) signal_data, &signal_data->timers[SNGISDN_SPAN_TIMER_RESTART]); } + ftdm_log(FTDM_LOG_DEBUG,"Finished starting span %s\n", span->name); return FTDM_SUCCESS; } + +static ftdm_status_t ftdm_sangoma_isdn_start(ftdm_span_t *span) +{ + sngisdn_span_data_t *signal_data = span->signal_data; + + ftdm_log(FTDM_LOG_INFO,"Starting span %s:%u.\n",span->name,span->span_id); + + if (signal_data->dchan) { + ftdm_channel_set_feature(signal_data->dchan, FTDM_CHANNEL_FEATURE_IO_STATS); + ftdm_channel_open_chan(signal_data->dchan); + ftdm_sangoma_isdn_dchan_set_queue_size(signal_data->dchan); + } + + if (signal_data->nfas.trunk) { + if (signal_data->nfas.trunk->num_spans == signal_data->nfas.trunk->num_spans_configured) { + int i; + ftdm_log(FTDM_LOG_DEBUG, "Starting span for all spans within trunkgroup:%s\n", signal_data->nfas.trunk->name); + + sngisdn_stack_start(signal_data->nfas.trunk->dchan->ftdm_span); + ftdm_sangoma_isdn_perform_start(signal_data->nfas.trunk->dchan->ftdm_span); + + if (signal_data->nfas.trunk->backup) { + sngisdn_stack_start(signal_data->nfas.trunk->backup->ftdm_span); + ftdm_sangoma_isdn_perform_start(signal_data->nfas.trunk->backup->ftdm_span); + } + + for (i = 0; i < signal_data->nfas.trunk->num_spans; i++) { + if (signal_data->nfas.trunk->spans[i] && + signal_data->nfas.trunk->spans[i]->nfas.sigchan == SNGISDN_NFAS_DCHAN_NONE) { + sngisdn_stack_start(signal_data->nfas.trunk->spans[i]->ftdm_span); + ftdm_sangoma_isdn_perform_start(signal_data->nfas.trunk->spans[i]->ftdm_span); + } + } + + return FTDM_SUCCESS; + } else { + ftdm_log(FTDM_LOG_DEBUG, "Delaying span start until all spans within trunkgroup are started: %s\n", signal_data->nfas.trunk->name); + return FTDM_SUCCESS; + } + } + + if (sngisdn_stack_start(span) != FTDM_SUCCESS) { + ftdm_log(FTDM_LOG_CRIT, "Failed to start span %s\n", span->name); + return FTDM_FAIL; + } + + ftdm_sangoma_isdn_perform_start(span); + + return FTDM_SUCCESS; +} + static ftdm_status_t ftdm_sangoma_isdn_stop(ftdm_span_t *span) { ftdm_iterator_t *chaniter = NULL; @@ -1138,13 +1179,13 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_isdn_span_config) ftdm_iterator_t *chaniter = NULL; ftdm_iterator_t *curr = NULL; - sngisdn_span_data_t *span_data; + sngisdn_span_data_t *signal_data; ftdm_log(FTDM_LOG_INFO, "Configuring ftmod_sangoma_isdn span = %s\n", span->name); - span_data = ftdm_calloc(1, sizeof(sngisdn_span_data_t)); - span_data->ftdm_span = span; - span->signal_data = span_data; + signal_data = ftdm_calloc(1, sizeof(sngisdn_span_data_t)); + signal_data->ftdm_span = span; + span->signal_data = signal_data; chaniter = ftdm_span_get_chan_iterator(span, NULL); for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) { @@ -1160,79 +1201,98 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_isdn_span_config) return FTDM_FAIL; } - if (sngisdn_stack_cfg(span) != FTDM_SUCCESS) { + if (signal_data->nfas.trunk) { + if (signal_data->nfas.trunk->num_spans == ++signal_data->nfas.trunk->num_spans_configured) { + int i; + ftdm_log(FTDM_LOG_DEBUG, "Starting stack configuration for all spans within trunkgroup:%s\n", signal_data->nfas.trunk->name); + + sngisdn_stack_cfg(signal_data->nfas.trunk->dchan->ftdm_span); + if (signal_data->nfas.trunk->backup) { + sngisdn_stack_cfg(signal_data->nfas.trunk->backup->ftdm_span); + } + + for (i = 0; i < signal_data->nfas.trunk->num_spans; i++) { + if (signal_data->nfas.trunk->spans[i] && + signal_data->nfas.trunk->spans[i]->nfas.sigchan == SNGISDN_NFAS_DCHAN_NONE) { + sngisdn_stack_cfg(signal_data->nfas.trunk->spans[i]->ftdm_span); + } + } + } else { + ftdm_log(FTDM_LOG_DEBUG, "Delaying span stack configuration until all spans within trunkgroup are started:%s\n", signal_data->nfas.trunk->name); + } + } else if (sngisdn_stack_cfg(span) != FTDM_SUCCESS) { ftdm_log(FTDM_LOG_CRIT, "Sangoma ISDN Stack configuration failed\n"); return FTDM_FAIL; } - if (span_data->cid_name_method == SNGISDN_CID_NAME_AUTO) { - switch (span_data->switchtype) { + if (signal_data->cid_name_method == SNGISDN_CID_NAME_AUTO) { + switch (signal_data->switchtype) { case SNGISDN_SWITCH_EUROISDN: if (FTDM_SPAN_IS_BRI(span)) { - span_data->cid_name_method = SNGISDN_CID_NAME_USR_USR_IE; + signal_data->cid_name_method = SNGISDN_CID_NAME_USR_USR_IE; } else { - span_data->cid_name_method = SNGISDN_CID_NAME_DISPLAY_IE; + signal_data->cid_name_method = SNGISDN_CID_NAME_DISPLAY_IE; } break; case SNGISDN_SWITCH_DMS100: - span_data->cid_name_method = SNGISDN_CID_NAME_DISPLAY_IE; + signal_data->cid_name_method = SNGISDN_CID_NAME_DISPLAY_IE; break; case SNGISDN_SWITCH_NI2: case SNGISDN_SWITCH_5ESS: case SNGISDN_SWITCH_4ESS: - span_data->cid_name_method = SNGISDN_CID_NAME_FACILITY_IE; + signal_data->cid_name_method = SNGISDN_CID_NAME_FACILITY_IE; break; default: break; } } - if (span_data->send_cid_name == SNGISDN_OPT_DEFAULT) { - switch (span_data->switchtype) { + if (signal_data->send_cid_name == SNGISDN_OPT_DEFAULT) { + switch (signal_data->switchtype) { case SNGISDN_SWITCH_EUROISDN: #ifdef SNGISDN_SUPPORT_CALLING_NAME_IN_FACILITY case SNGISDN_SWITCH_NI2: case SNGISDN_SWITCH_5ESS: case SNGISDN_SWITCH_4ESS: #endif - if (span_data->signalling == SNGISDN_SIGNALING_NET) { - span_data->send_cid_name = SNGISDN_OPT_TRUE; + if (signal_data->signalling == SNGISDN_SIGNALING_NET) { + signal_data->send_cid_name = SNGISDN_OPT_TRUE; } else { - span_data->send_cid_name = SNGISDN_OPT_FALSE; + signal_data->send_cid_name = SNGISDN_OPT_FALSE; } break; case SNGISDN_SWITCH_DMS100: - span_data->send_cid_name = SNGISDN_OPT_TRUE; + signal_data->send_cid_name = SNGISDN_OPT_TRUE; break; #ifndef SNGISDN_SUPPORT_CALLING_NAME_IN_FACILITY case SNGISDN_SWITCH_NI2: case SNGISDN_SWITCH_5ESS: case SNGISDN_SWITCH_4ESS: - span_data->send_cid_name = SNGISDN_OPT_FALSE; + signal_data->send_cid_name = SNGISDN_OPT_FALSE; break; #endif default: - span_data->send_cid_name = SNGISDN_OPT_FALSE; + signal_data->send_cid_name = SNGISDN_OPT_FALSE; break; } - } else if (span_data->send_cid_name == SNGISDN_OPT_TRUE) { - switch (span_data->switchtype) { + } else if (signal_data->send_cid_name == SNGISDN_OPT_TRUE) { + switch (signal_data->switchtype) { case SNGISDN_SWITCH_NI2: case SNGISDN_SWITCH_5ESS: case SNGISDN_SWITCH_4ESS: #ifndef SNGISDN_SUPPORT_CALLING_NAME_IN_FACILITY ftdm_log(FTDM_LOG_WARNING, "Sending Calling Name in Facility IE not supported, please update your libsng_isdn library\n"); - span_data->send_cid_name = SNGISDN_OPT_FALSE; + signal_data->send_cid_name = SNGISDN_OPT_FALSE; #endif break; case SNGISDN_SWITCH_INSNET: /* Don't know how to transmit caller ID name on INSNET */ case SNGISDN_SWITCH_QSIG: /* It seems like QSIG does not support Caller ID */ - span_data->send_cid_name = SNGISDN_OPT_FALSE; + signal_data->send_cid_name = SNGISDN_OPT_FALSE; break; case SNGISDN_SWITCH_EUROISDN: break; default: - span_data->send_cid_name = SNGISDN_OPT_FALSE; + signal_data->send_cid_name = SNGISDN_OPT_FALSE; break; } } 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 92054b8869..0034add153 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 @@ -58,7 +58,8 @@ /* Theoretical limit for MAX_SPANS_PER_NFAS_LINK is 31, but set to 8 for now to save some memory */ -#define MAX_SPANS_PER_NFAS_LINK 8 +#define MAX_SPANS_PER_NFAS_LINK 16 +#define MAX_NFAS_GROUPS 16 #define NUM_E1_CHANNELS_PER_SPAN 32 #define NUM_T1_CHANNELS_PER_SPAN 24 #define NUM_BRI_CHANNELS_PER_SPAN 2 @@ -66,6 +67,9 @@ #define SNGISDN_EVENT_POLL_RATE 100 #define SNGISDN_NUM_LOCAL_NUMBERS 8 #define SNGISDN_DCHAN_QUEUE_LEN 200 +#define MAX_NFAS_GROUP_NAME 50 + +#define NSG #ifndef MI_NOTIFY #define MI_NOTIFY 0x14 @@ -242,16 +246,25 @@ typedef struct sngisdn_chan_data { ftdm_size_t raw_data_len; } sngisdn_chan_data_t; +struct sngisdn_nfas_data; +typedef struct sngisdn_nfas_data sngisdn_nfas_data_t; + +typedef enum { + SNGISDN_NFAS_DCHAN_NONE, + SNGISDN_NFAS_DCHAN_PRIMARY, + SNGISDN_NFAS_DCHAN_BACKUP, +} sngisdn_nfas_sigchan_t; + /* Span specific data */ typedef struct sngisdn_span_data { ftdm_span_t *ftdm_span; ftdm_channel_t *dchan; uint8_t link_id; uint8_t switchtype; - uint8_t signalling; /* SNGISDN_SIGNALING_CPE or SNGISDN_SIGNALING_NET */ + uint8_t signalling; /* SNGISDN_SIGNALING_CPE or SNGISDN_SIGNALING_NET */ uint8_t cc_id; - uint8_t dchan_id; - uint8_t span_id; + ftdm_signaling_status_t sigstatus; + uint8_t tei; uint8_t min_digits; uint8_t trace_flags; /* TODO change to bit map of sngisdn_tracetype_t */ @@ -274,7 +287,7 @@ typedef struct sngisdn_span_data { uint8_t restart_timeout; uint8_t force_sending_complete; uint8_t cid_name_method; - uint8_t send_cid_name; + uint8_t send_cid_name; int32_t timer_t301; int32_t timer_t302; @@ -292,11 +305,20 @@ typedef struct sngisdn_span_data { int32_t timer_t318; int32_t timer_t319; int32_t timer_t322; - + char* local_numbers[SNGISDN_NUM_LOCAL_NUMBERS]; ftdm_timer_id_t timers[SNGISDN_NUM_SPAN_TIMERS]; ftdm_sched_t *sched; ftdm_queue_t *event_queue; + + struct nfas_info { + sngisdn_nfas_data_t *trunk; + sngisdn_nfas_sigchan_t sigchan; + uint8_t interface_id; + } nfas; + + uint32_t num_chans; + sngisdn_chan_data_t *channels[NUM_E1_CHANNELS_PER_SPAN]; } sngisdn_span_data_t; typedef struct sngisdn_event_data { @@ -331,19 +353,18 @@ typedef struct sngisdn_event_data { } sngisdn_event_data_t; -/* dchan_data can have more than 1 span when running NFAS */ -typedef struct sngisdn_dchan_data { - uint8_t num_spans; - sngisdn_span_data_t *spans[MAX_L1_LINKS+1]; - uint16_t num_chans; - /* worst case for number of channel is when using NFAS, and NFAS is only used on T1, - so we can use MAX_SPANS_PER_NFAS_LINK*NUM_T1_CHANNELS_PER_SPAN instead of - MAX_SPANS_PER_NFAS_LINK*NUM_E1_CHANNELS_PER_SPAN - */ - /* Never seen NFAS on E1 yet, so use NUM_T1_CHANNELS_PER_SPAN */ - /* b-channels are arranged by physical id's not logical */ - sngisdn_chan_data_t *channels[MAX_SPANS_PER_NFAS_LINK*NUM_T1_CHANNELS_PER_SPAN]; -}sngisdn_dchan_data_t; +struct sngisdn_nfas_data { + char name[MAX_NFAS_GROUP_NAME]; + + char dchan_span_name[20]; + sngisdn_span_data_t *dchan; /* Span that contains primary d-channel */ + + char backup_span_name[20]; + sngisdn_span_data_t *backup; /* Span that contains backup d-channel */ + uint8_t num_spans; /* Number of spans within this NFAS */ + uint8_t num_spans_configured; + sngisdn_span_data_t *spans[MAX_SPANS_PER_NFAS_LINK+1]; //indexed by logical span id +}; typedef struct sngisdn_cc { /* TODO: use flags instead of config_done and activation_done */ @@ -360,10 +381,10 @@ typedef struct sngisdn_cc { /* Global sngisdn data */ typedef struct ftdm_sngisdn_data { uint8_t gen_config_done; - uint8_t num_cc; /* 1 ent per switchtype */ - struct sngisdn_cc ccs[MAX_VARIANTS+1]; - uint8_t num_dchan; - sngisdn_dchan_data_t dchans[MAX_L1_LINKS+1]; + uint8_t num_cc; /* 1 ent per switchtype */ + struct sngisdn_cc ccs[MAX_VARIANTS+1]; + uint8_t num_nfas; + sngisdn_nfas_data_t nfass[MAX_NFAS_GROUPS+1]; sngisdn_span_data_t *spans[MAX_L1_LINKS+1]; /* spans are indexed by link_id */ #ifdef SANGOMA_ISDN_CHAN_ID_INVERT_BIT @@ -424,7 +445,7 @@ void sngisdn_snd_info_req(ftdm_channel_t *ftdmchan); void sngisdn_snd_status_enq(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_event(ftdm_channel_t *dchan, ftdm_oob_event_t event); +void sngisdn_snd_event(sngisdn_span_data_t *signal_data, ftdm_oob_event_t event); /* Inbound Call Control functions */ void sngisdn_rcv_con_ind(int16_t suId, uint32_t suInstId, uint32_t spInstId, ConEvnt *conEvnt, int16_t dChan, uint8_t ces); @@ -553,6 +574,7 @@ static __inline__ void sngisdn_set_flag(sngisdn_chan_data_t *sngisdn_info, sngis void handle_sng_log(uint8_t level, char *fmt,...); void sngisdn_delayed_setup(void* p_sngisdn_info); void sngisdn_delayed_release(void* p_sngisdn_info); +void sngisdn_delayed_release_nfas(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); @@ -564,6 +586,7 @@ 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); ftdm_status_t sngisdn_wake_up_phy(ftdm_span_t *span); +sngisdn_span_data_t *sngisdn_dchan(sngisdn_span_data_t *signal_data); ftdm_status_t sngisdn_show_l1_stats(ftdm_stream_handle_t *stream, ftdm_span_t *span); ftdm_status_t sngisdn_show_spans(ftdm_stream_handle_t *stream); 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 ba05d9b4a4..45c6c9cc17 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 @@ -37,6 +37,7 @@ static ftdm_status_t parse_timer(const char* val, int32_t *target); static ftdm_status_t parse_switchtype(const char* switch_name, ftdm_span_t *span); static ftdm_status_t parse_signalling(const char* signalling, ftdm_span_t *span); +static ftdm_status_t parse_trunkgroup(const char *_trunkgroup); static ftdm_status_t add_local_number(const char* val, ftdm_span_t *span); static ftdm_status_t parse_yesno(const char* var, const char* val, uint8_t *target); static ftdm_status_t set_switchtype_defaults(ftdm_span_t *span); @@ -81,7 +82,7 @@ static ftdm_status_t parse_switchtype(const char* switch_name, ftdm_span_t *span unsigned i; ftdm_iterator_t *chaniter = NULL; ftdm_iterator_t *curr = NULL; - sngisdn_dchan_data_t *dchan_data; + //sngisdn_dchan_data_t *dchan_data; sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data; switch(span->trunk_type) { @@ -133,13 +134,15 @@ static ftdm_status_t parse_switchtype(const char* switch_name, ftdm_span_t *span ftdm_log(FTDM_LOG_ERROR, "%s:Unsupported trunktype:%s\n", span->name, switch_name, ftdm_trunk_type2str(span->trunk_type)); return FTDM_FAIL; } + /* see if we have profile with this switch_type already */ - for (i=1; i <= g_sngisdn_data.num_cc; i++) { + for (i = 1; i <= g_sngisdn_data.num_cc; i++) { if (g_sngisdn_data.ccs[i].switchtype == signal_data->switchtype && g_sngisdn_data.ccs[i].trunktype == span->trunk_type) { break; } } + /* need to create a new switch_type */ if (i > g_sngisdn_data.num_cc) { g_sngisdn_data.num_cc++; @@ -151,20 +154,9 @@ static ftdm_status_t parse_switchtype(const char* switch_name, ftdm_span_t *span /* add this span to its ent_cc */ signal_data->cc_id = i; - /* create a new dchan */ /* for NFAS - no-dchan on b-channels-only links */ - g_sngisdn_data.num_dchan++; - signal_data->dchan_id = g_sngisdn_data.num_dchan; - - dchan_data = &g_sngisdn_data.dchans[signal_data->dchan_id]; - dchan_data->num_spans++; - - signal_data->span_id = dchan_data->num_spans; - dchan_data->spans[signal_data->span_id] = signal_data; - g_sngisdn_data.spans[signal_data->link_id] = signal_data; - ftdm_log(FTDM_LOG_DEBUG, "%s: cc_id:%d dchan_id:%d span_id:%d link_id:%d\n", span->name, signal_data->cc_id, signal_data->dchan_id, signal_data->span_id, signal_data->link_id); - + ftdm_log(FTDM_LOG_DEBUG, "%s: cc_id:%d link_id:%d\n", span->name, signal_data->cc_id, signal_data->link_id); chaniter = ftdm_span_get_chan_iterator(span, NULL); for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) { @@ -175,17 +167,16 @@ static ftdm_status_t parse_switchtype(const char* switch_name, ftdm_span_t *span signal_data->dchan = ftdmchan; } else { /* Add the channels to the span */ - /* NFAS is not supported on E1, so span_id will always be 1 for E1 so this will work for E1 as well */ - chan_id = ((signal_data->span_id-1)*NUM_T1_CHANNELS_PER_SPAN)+ftdmchan->physical_chan_id; - dchan_data->channels[chan_id] = (sngisdn_chan_data_t*)ftdmchan->call_data; - dchan_data->num_chans++; + chan_id = ftdmchan->physical_chan_id; + signal_data->channels[chan_id] = (sngisdn_chan_data_t*)ftdmchan->call_data; + signal_data->num_chans++; } } ftdm_iterator_free(chaniter); return FTDM_SUCCESS; } -static ftdm_status_t parse_signalling(const char* signalling, ftdm_span_t *span) +static ftdm_status_t parse_signalling(const char *signalling, ftdm_span_t *span) { sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data; if (!strcasecmp(signalling, "net") || @@ -205,6 +196,146 @@ static ftdm_status_t parse_signalling(const char* signalling, ftdm_span_t *span) return FTDM_SUCCESS; } +static ftdm_status_t parse_spanmap(const char *_spanmap, ftdm_span_t *span) +{ + int i; + char *p, *name, *spanmap; + uint8_t logical_span_id = 0; + ftdm_status_t ret = FTDM_SUCCESS; + sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data; + + spanmap = ftdm_strdup(_spanmap); + + p = name = NULL; + + i = 0; + for (p = strtok(spanmap, ","); p; p = strtok(NULL, ",")) { + while (*p == ' ') { + p++; + } + switch(i++) { + case 0: + name = ftdm_strdup(p); + break; + case 1: + logical_span_id = atoi(p); + break; + } + } + + if (!name || logical_span_id < 0) { + ftdm_log(FTDM_LOG_ERROR, "Invalid spanmap syntax %s\n", _spanmap); + ret = FTDM_FAIL; + goto done; + } + + for (i = 0; i < g_sngisdn_data.num_nfas; i++) { + if (!ftdm_strlen_zero(g_sngisdn_data.nfass[i].name) && + !strcasecmp(g_sngisdn_data.nfass[i].name, name)) { + + signal_data->nfas.trunk = &g_sngisdn_data.nfass[i]; + break; + } + } + + if (!signal_data->nfas.trunk) { + ftdm_log(FTDM_LOG_ERROR, "Could not find trunkgroup with name %s\n", name); + ret = FTDM_FAIL; + goto done; + } + + if (signal_data->nfas.trunk->spans[logical_span_id]) { + ftdm_log(FTDM_LOG_ERROR, "trunkgroup:%s already had a span with logical span id:%d\n", name, logical_span_id); + } else { + signal_data->nfas.trunk->spans[logical_span_id] = signal_data; + signal_data->nfas.interface_id = logical_span_id; + } + + if (!strcasecmp(signal_data->ftdm_span->name, signal_data->nfas.trunk->dchan_span_name)) { + + signal_data->nfas.sigchan = SNGISDN_NFAS_DCHAN_PRIMARY; + signal_data->nfas.trunk->dchan = signal_data; + } + + if (!strcasecmp(signal_data->ftdm_span->name, signal_data->nfas.trunk->backup_span_name)) { + + signal_data->nfas.sigchan = SNGISDN_NFAS_DCHAN_BACKUP; + signal_data->nfas.trunk->backup = signal_data; + } + +done: + ftdm_safe_free(spanmap); + ftdm_safe_free(name); + return ret; +} + +static ftdm_status_t parse_trunkgroup(const char *_trunkgroup) +{ + int i; + char *p, *name, *dchan_span, *backup_span, *trunkgroup; + uint8_t num_spans; + ftdm_status_t ret = FTDM_SUCCESS; + + trunkgroup = ftdm_strdup(_trunkgroup); + + p = name = dchan_span = backup_span = NULL; + + /* format: name, num_chans, dchan_span, [backup_span] */ + + i = 0; + for (p = strtok(trunkgroup, ","); p; p = strtok(NULL, ",")) { + while (*p == ' ') { + p++; + } + switch(i++) { + case 0: + name = ftdm_strdup(p); + break; + case 1: + num_spans = atoi(p); + break; + case 2: + dchan_span = ftdm_strdup(p); + break; + case 3: + backup_span = ftdm_strdup(p); + } + } + + if (!name || !dchan_span || num_spans <= 0) { + ftdm_log(FTDM_LOG_ERROR, "Invalid parameters for trunkgroup:%s\n", _trunkgroup); + ret = FTDM_FAIL; + goto done; + } + + for (i = 0; i < g_sngisdn_data.num_nfas; i++) { + if (!ftdm_strlen_zero(g_sngisdn_data.nfass[i].name) && + !strcasecmp(g_sngisdn_data.nfass[i].name, name)) { + + /* We already configured this trunkgroup */ + goto done; + } + } + + /* Trunk group was not found, need to configure it */ + strncpy(g_sngisdn_data.nfass[i].name, name, sizeof(g_sngisdn_data.nfass[i].name)); + g_sngisdn_data.nfass[i].num_spans = num_spans; + strncpy(g_sngisdn_data.nfass[i].dchan_span_name, dchan_span, sizeof(g_sngisdn_data.nfass[i].dchan_span_name)); + + if (backup_span) { + strncpy(g_sngisdn_data.nfass[i].backup_span_name, backup_span, sizeof(g_sngisdn_data.nfass[i].backup_span_name)); + } + + + g_sngisdn_data.num_nfas++; +done: + ftdm_safe_free(trunkgroup); + ftdm_safe_free(name); + ftdm_safe_free(dchan_span); + ftdm_safe_free(backup_span); + return FTDM_SUCCESS; +} + static ftdm_status_t parse_early_media(const char* opt, ftdm_span_t *span) { sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data; @@ -314,6 +445,19 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_ /* Cannot set default bearer_layer1 yet, as we do not know the switchtype */ span->default_caller_data.bearer_layer1 = FTDM_INVALID_INT_PARM; + /* Find out if NFAS is enabled first */ + for (paramindex = 0; ftdm_parameters[paramindex].var; paramindex++) { + ftdm_log(FTDM_LOG_DEBUG, "Sangoma ISDN key=value, %s=%s\n", ftdm_parameters[paramindex].var, ftdm_parameters[paramindex].val); + var = ftdm_parameters[paramindex].var; + val = ftdm_parameters[paramindex].val; + + if (!strcasecmp(var, "trunkgroup")) { + if (parse_trunkgroup(val) != FTDM_SUCCESS) { + return FTDM_FAIL; + } + } + } + for (paramindex = 0; ftdm_parameters[paramindex].var; paramindex++) { ftdm_log(FTDM_LOG_DEBUG, "Sangoma ISDN key=value, %s=%s\n", ftdm_parameters[paramindex].var, ftdm_parameters[paramindex].val); var = ftdm_parameters[paramindex].var; @@ -331,6 +475,10 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_ if (parse_signalling(val, span) != FTDM_SUCCESS) { return FTDM_FAIL; } + } else if (!strcasecmp(var, "spanmap")) { + if (parse_spanmap(val, span) != FTDM_SUCCESS) { + return FTDM_FAIL; + } } else if (!strcasecmp(var, "tei")) { uint8_t tei = atoi(val); if (tei > 127) { @@ -465,6 +613,8 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_ parse_timer(val, &signal_data->timer_t319); } else if (!strcasecmp(var, "timer-t322")) { parse_timer(val, &signal_data->timer_t322); + } else if (!strcasecmp(var, "trunkgroup")) { + /* Do nothing, we already parsed this parameter */ } 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_cntrl.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cntrl.c index 15def40218..754aff1187 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cntrl.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cntrl.c @@ -40,6 +40,8 @@ void sngisdn_set_chan_sig_status(ftdm_channel_t *ftdmchan, ftdm_signaling_status void sngisdn_set_chan_sig_status(ftdm_channel_t *ftdmchan, ftdm_signaling_status_t status) { ftdm_sigmsg_t sig; + sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)ftdmchan->span->signal_data; + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Signalling link status changed to %s\n", ftdm_signaling_status2str(status)); memset(&sig, 0, sizeof(sig)); @@ -52,7 +54,6 @@ void sngisdn_set_chan_sig_status(ftdm_channel_t *ftdmchan, ftdm_signaling_status if (FTDM_SPAN_IS_BRI(ftdmchan->span)) { sngisdn_chan_data_t *sngisdn_info = ftdmchan->call_data; - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)ftdmchan->span->signal_data; if (ftdm_test_flag(sngisdn_info, FLAG_ACTIVATING)) { ftdm_clear_flag(sngisdn_info, FLAG_ACTIVATING); @@ -67,6 +68,7 @@ void sngisdn_set_span_sig_status(ftdm_span_t *span, ftdm_signaling_status_t stat ftdm_iterator_t *chaniter = NULL; ftdm_iterator_t *curr = NULL; + ((sngisdn_span_data_t*)span->signal_data)->sigstatus = status; chaniter = ftdm_span_get_chan_iterator(span, NULL); for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) { 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 55a156c562..b96a801243 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 @@ -62,6 +62,8 @@ 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 (!g_sngisdn_data.gen_config_done) { g_sngisdn_data.gen_config_done = 1; ftdm_log(FTDM_LOG_DEBUG, "Starting general stack configuration\n"); @@ -91,33 +93,33 @@ ftdm_status_t sngisdn_stack_cfg(ftdm_span_t *span) ftdm_log(FTDM_LOG_INFO, "General stack configuration done\n"); } - /* TODO: for NFAS, should only call these function for spans with d-chans */ - if (sngisdn_stack_cfg_phy_psap(span) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "%s:phy_psap configuration failed\n", span->name); - return FTDM_FAIL; - } - ftdm_log(FTDM_LOG_DEBUG, "%s:phy_psap configuration done\n", span->name); - - if (sngisdn_stack_cfg_q921_msap(span) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "%s:q921_msap configuration failed\n", span->name); - return FTDM_FAIL; - } - ftdm_log(FTDM_LOG_DEBUG, "%s:q921_msap configuration done\n", span->name); - - if (sngisdn_stack_cfg_q921_dlsap(span, 0) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "%s:q921_dlsap configuration failed\n", span->name); - return FTDM_FAIL; - } - ftdm_log(FTDM_LOG_DEBUG, "%s:q921_dlsap configuration done\n", span->name); - - if (span->trunk_type == FTDM_TRUNK_BRI_PTMP) { - if (sngisdn_stack_cfg_q921_dlsap(span, 1) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "%s:q921_dlsap management configuration failed\n", span->name); + if (signal_data->dchan) { + if (sngisdn_stack_cfg_phy_psap(span) != FTDM_SUCCESS) { + ftdm_log(FTDM_LOG_ERROR, "%s:phy_psap configuration failed\n", span->name); return FTDM_FAIL; } - ftdm_log(FTDM_LOG_DEBUG, "%s:q921_dlsap management configuration done\n", span->name); + ftdm_log(FTDM_LOG_DEBUG, "%s:phy_psap configuration done\n", span->name); + + if (sngisdn_stack_cfg_q921_msap(span) != FTDM_SUCCESS) { + ftdm_log(FTDM_LOG_ERROR, "%s:q921_msap configuration failed\n", span->name); + return FTDM_FAIL; + } + ftdm_log(FTDM_LOG_DEBUG, "%s:q921_msap configuration done\n", span->name); + + if (sngisdn_stack_cfg_q921_dlsap(span, 0) != FTDM_SUCCESS) { + ftdm_log(FTDM_LOG_ERROR, "%s:q921_dlsap configuration failed\n", span->name); + return FTDM_FAIL; + } + ftdm_log(FTDM_LOG_DEBUG, "%s:q921_dlsap configuration done\n", span->name); + + if (span->trunk_type == FTDM_TRUNK_BRI_PTMP) { + if (sngisdn_stack_cfg_q921_dlsap(span, 1) != FTDM_SUCCESS) { + ftdm_log(FTDM_LOG_ERROR, "%s:q921_dlsap management configuration failed\n", span->name); + return FTDM_FAIL; + } + ftdm_log(FTDM_LOG_DEBUG, "%s:q921_dlsap management configuration done\n", span->name); + } } - if (sngisdn_stack_cfg_q931_dlsap(span) != FTDM_SUCCESS) { ftdm_log(FTDM_LOG_ERROR, "%s:q931_dlsap configuration failed\n", span->name); @@ -125,11 +127,13 @@ ftdm_status_t sngisdn_stack_cfg(ftdm_span_t *span) } ftdm_log(FTDM_LOG_DEBUG, "%s:q931_dlsap configuration done\n", span->name); - if (sngisdn_stack_cfg_q931_lce(span) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "%s:q931_lce configuration failed\n", span->name); - return FTDM_FAIL; + if (signal_data->dchan) { + if (sngisdn_stack_cfg_q931_lce(span) != FTDM_SUCCESS) { + ftdm_log(FTDM_LOG_ERROR, "%s:q931_lce configuration failed\n", span->name); + return FTDM_FAIL; + } + ftdm_log(FTDM_LOG_DEBUG, "%s:q931_lce configuration done\n", span->name); } - ftdm_log(FTDM_LOG_DEBUG, "%s:q931_lce configuration done\n", span->name); if (!g_sngisdn_data.ccs[signal_data->cc_id].config_done) { g_sngisdn_data.ccs[signal_data->cc_id].config_done = 1; @@ -216,7 +220,7 @@ ftdm_status_t sngisdn_stack_cfg_phy_psap(ftdm_span_t *span) cfg.hdr.entId.inst = S_INST; cfg.hdr.elmId.elmnt = STPSAP; - cfg.hdr.elmId.elmntInst1 = signal_data->dchan_id; + cfg.hdr.elmId.elmntInst1 = signal_data->link_id; if (!signal_data->dchan) { ftdm_log(FTDM_LOG_ERROR, "%s:No d-channels specified\n", span->name); @@ -242,7 +246,7 @@ ftdm_status_t sngisdn_stack_cfg_phy_psap(ftdm_span_t *span) return FTDM_FAIL; } - cfg.t.cfg.s.l1PSAP.spId = signal_data->dchan_id; + cfg.t.cfg.s.l1PSAP.spId = signal_data->link_id; if (sng_isdn_phy_config(&pst, &cfg)) { return FTDM_FAIL; @@ -316,7 +320,7 @@ ftdm_status_t sngisdn_stack_cfg_q921_msap(ftdm_span_t *span) cfg.hdr.entId.inst = S_INST; cfg.hdr.elmId.elmnt = STMSAP; - cfg.t.cfg.s.bdMSAP.lnkNmb = signal_data->dchan_id; + cfg.t.cfg.s.bdMSAP.lnkNmb = signal_data->link_id; cfg.t.cfg.s.bdMSAP.maxOutsFrms = 24; /* MAC window */ cfg.t.cfg.s.bdMSAP.tQUpperTrs = 32; /* Tx Queue Upper Threshold */ @@ -409,7 +413,7 @@ ftdm_status_t sngisdn_stack_cfg_q921_dlsap(ftdm_span_t *span, uint8_t management cfg.hdr.entId.inst = S_INST; cfg.hdr.elmId.elmnt = STDLSAP; - cfg.t.cfg.s.bdDLSAP.lnkNmb = signal_data->dchan_id; + cfg.t.cfg.s.bdDLSAP.lnkNmb = signal_data->link_id; cfg.t.cfg.s.bdDLSAP.n201 = 1028; /* n201 */ if (span->trunk_type == FTDM_TRUNK_BRI_PTMP || @@ -614,8 +618,8 @@ ftdm_status_t sngisdn_stack_cfg_q931_dlsap(ftdm_span_t *span) cfg.hdr.response.selector=0; - cfg.t.cfg.s.inDLSAP.sapId = signal_data->dchan_id; - cfg.t.cfg.s.inDLSAP.spId = signal_data->dchan_id; + cfg.t.cfg.s.inDLSAP.sapId = signal_data->link_id; + cfg.t.cfg.s.inDLSAP.spId = signal_data->link_id; cfg.t.cfg.s.inDLSAP.swtch = sng_isdn_stack_switchtype(signal_data->switchtype); @@ -630,11 +634,9 @@ ftdm_status_t sngisdn_stack_cfg_q931_dlsap(ftdm_span_t *span) } else { cfg.t.cfg.s.inDLSAP.facilityHandling = 0; } - - /* TODO : NFAS configuration */ - cfg.t.cfg.s.inDLSAP.nfasInt = FALSE; /* pass this later */ - - if (!cfg.t.cfg.s.inDLSAP.nfasInt) { + + if (!signal_data->nfas.trunk) { + cfg.t.cfg.s.inDLSAP.nfasInt = FALSE; cfg.t.cfg.s.inDLSAP.intId = 0; cfg.t.cfg.s.inDLSAP.sigInt = 0; cfg.t.cfg.s.inDLSAP.bupInt = 0; @@ -645,19 +647,55 @@ ftdm_status_t sngisdn_stack_cfg_q931_dlsap(ftdm_span_t *span) cfg.t.cfg.s.inDLSAP.ctldInt[i] = IN_INT_NOT_CFGD; } else { - /* Need to get these parameters from NFAS */ - cfg.t.cfg.s.inDLSAP.intId = 0; - cfg.t.cfg.s.inDLSAP.sigInt = 0; - cfg.t.cfg.s.inDLSAP.bupInt = 1; - cfg.t.cfg.s.inDLSAP.nmbNfasInt = 2; - cfg.t.cfg.s.inDLSAP.buIntPr = 1; + cfg.t.cfg.s.inDLSAP.nfasInt = TRUE; + cfg.t.cfg.s.inDLSAP.intId = signal_data->nfas.interface_id; for (i = 0; i < IN_MAX_NMB_INTRFS; i++) cfg.t.cfg.s.inDLSAP.ctldInt[i] = IN_INT_NOT_CFGD; - /* For primary and backup interfaces, need to initialize this array */ - cfg.t.cfg.s.inDLSAP.ctldInt[0] = 0; /* This is primary if for NFAS */ - cfg.t.cfg.s.inDLSAP.ctldInt[1] = 1; + switch (signal_data->nfas.sigchan) { + case SNGISDN_NFAS_DCHAN_PRIMARY: + cfg.t.cfg.s.inDLSAP.sigInt = signal_data->nfas.trunk->dchan->link_id; + cfg.t.cfg.s.inDLSAP.nmbNfasInt = signal_data->nfas.trunk->num_spans; + + if (signal_data->nfas.trunk->backup) { + cfg.t.cfg.s.inDLSAP.buIntPr = TRUE; + cfg.t.cfg.s.inDLSAP.bupInt = signal_data->nfas.trunk->backup->link_id; + } else { + cfg.t.cfg.s.inDLSAP.buIntPr = FALSE; + } + + for (i = 0; i < MAX_SPANS_PER_NFAS_LINK; i++) { + if (signal_data->nfas.trunk->spans[i]) { + cfg.t.cfg.s.inDLSAP.ctldInt[i] = signal_data->nfas.trunk->spans[i]->link_id; + } + } + + break; + case SNGISDN_NFAS_DCHAN_BACKUP: + cfg.t.cfg.s.inDLSAP.sigInt = signal_data->nfas.trunk->dchan->link_id; + cfg.t.cfg.s.inDLSAP.nmbNfasInt = signal_data->nfas.trunk->num_spans; + + if (signal_data->nfas.trunk->backup) { + cfg.t.cfg.s.inDLSAP.buIntPr = TRUE; + cfg.t.cfg.s.inDLSAP.bupInt = signal_data->nfas.trunk->backup->link_id; + } else { + cfg.t.cfg.s.inDLSAP.buIntPr = FALSE; + } + + for (i = 0; i < MAX_SPANS_PER_NFAS_LINK; i++) { + if (signal_data->nfas.trunk->spans[i]) { + cfg.t.cfg.s.inDLSAP.ctldInt[i] = signal_data->nfas.trunk->spans[i]->link_id; + } + } + + break; + case SNGISDN_NFAS_DCHAN_NONE: + cfg.t.cfg.s.inDLSAP.sigInt = signal_data->nfas.trunk->dchan->link_id; + cfg.t.cfg.s.inDLSAP.nmbNfasInt = 0; + + break; + } } cfg.t.cfg.s.inDLSAP.numRstInd = 255; @@ -903,13 +941,27 @@ ftdm_status_t sngisdn_stack_cfg_q931_dlsap(ftdm_span_t *span) break; case FTDM_TRUNK_T1: case FTDM_TRUNK_J1: - /* if NFAS, could be 0 if no signalling */ - cfg.t.cfg.s.inDLSAP.dChannelNum = 24; - cfg.t.cfg.s.inDLSAP.nmbBearChan = NUM_T1_CHANNELS_PER_SPAN; - cfg.t.cfg.s.inDLSAP.firstBChanNum = 1; + /* if NFAS, could be 0 if no signalling */ cfg.t.cfg.s.inDLSAP.callRefLen = 2; cfg.t.cfg.s.inDLSAP.teiAlloc = IN_STATIC; cfg.t.cfg.s.inDLSAP.intCfg = IN_INTCFG_PTPT; + cfg.t.cfg.s.inDLSAP.firstBChanNum = 1; + + if (signal_data->nfas.trunk) { + if (signal_data->nfas.sigchan == SNGISDN_NFAS_DCHAN_PRIMARY || + signal_data->nfas.sigchan == SNGISDN_NFAS_DCHAN_BACKUP) { + + cfg.t.cfg.s.inDLSAP.dChannelNum = 24; + cfg.t.cfg.s.inDLSAP.nmbBearChan = NUM_T1_CHANNELS_PER_SPAN - 1; + } else { + cfg.t.cfg.s.inDLSAP.dChannelNum = 0; + cfg.t.cfg.s.inDLSAP.nmbBearChan = NUM_T1_CHANNELS_PER_SPAN; + } + } else { + cfg.t.cfg.s.inDLSAP.dChannelNum = 24; + cfg.t.cfg.s.inDLSAP.nmbBearChan = NUM_T1_CHANNELS_PER_SPAN; + cfg.t.cfg.s.inDLSAP.firstBChanNum = 1; + } break; case FTDM_TRUNK_BRI: cfg.t.cfg.s.inDLSAP.dChannelNum = 0; /* Unused for BRI */ @@ -969,7 +1021,7 @@ ftdm_status_t sngisdn_stack_cfg_q931_lce(ftdm_span_t *span) cfg.hdr.response.selector=0; - cfg.t.cfg.s.inLCe.sapId = signal_data->dchan_id; + cfg.t.cfg.s.inLCe.sapId = signal_data->link_id; cfg.t.cfg.s.inLCe.lnkUpDwnInd = TRUE; @@ -990,13 +1042,13 @@ ftdm_status_t sngisdn_stack_cfg_q931_lce(ftdm_span_t *span) cfg.t.cfg.s.inLCe.t314.enb = FALSE; /* if segmentation enabled, set to TRUE */ cfg.t.cfg.s.inLCe.t314.val = 35; - cfg.t.cfg.s.inLCe.t332i.enb = FALSE; /* set to TRUE for NFAS */ - -#ifdef NFAS - cfg.t.cfg.s.inLCe.t332i.val = 35; -#else - cfg.t.cfg.s.inLCe.t332i.val = 0; -#endif + if (signal_data->nfas.trunk) { + cfg.t.cfg.s.inLCe.t332i.enb = TRUE; + cfg.t.cfg.s.inLCe.t332i.val = 35; + } else { + cfg.t.cfg.s.inLCe.t332i.enb = FALSE; + cfg.t.cfg.s.inLCe.t332i.val = 35; + } #if (ISDN_NI1 || ISDN_NT || ISDN_ATT) cfg.t.cfg.s.inLCe.tSpid.enb = TRUE; 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 2023f4c54c..1cc23ddb8d 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 @@ -55,10 +55,12 @@ ftdm_status_t sngisdn_stack_start(ftdm_span_t *span) { sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data; - - if (sngisdn_cntrl_q921(span, ABND_ENA, NOTUSED) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_CRIT, "%s:Failed to activate stack q921\n", span->name); - return FTDM_FAIL; + if (signal_data->dchan) { + if (sngisdn_cntrl_q921(span, ABND_ENA, NOTUSED) != FTDM_SUCCESS) { + ftdm_log(FTDM_LOG_CRIT, "%s:Failed to activate stack q921\n", span->name); + return FTDM_FAIL; + } + ftdm_log(FTDM_LOG_DEBUG, "%s:Stack q921 activated\n", span->name); } /* Try to find an alternative for this */ @@ -67,8 +69,7 @@ ftdm_status_t sngisdn_stack_start(ftdm_span_t *span) LdUiDatConReq when activated, and this requires the Mac SAP to be already bound first */ ftdm_sleep(500); - - ftdm_log(FTDM_LOG_DEBUG, "%s:Stack q921 activated\n", span->name); + if (!g_sngisdn_data.ccs[signal_data->cc_id].activation_done) { g_sngisdn_data.ccs[signal_data->cc_id].activation_done = 1; if (sngisdn_activate_cc(span) != FTDM_SUCCESS) { @@ -78,7 +79,6 @@ ftdm_status_t sngisdn_stack_start(ftdm_span_t *span) ftdm_log(FTDM_LOG_DEBUG, "%s:Stack CC activated\n", span->name); } - if (sngisdn_cntrl_q931(span, ABND_ENA, SAELMNT) != FTDM_SUCCESS) { ftdm_log(FTDM_LOG_CRIT, "%s:Failed to activate stack q931\n", span->name); return FTDM_FAIL; @@ -91,7 +91,11 @@ ftdm_status_t sngisdn_stack_start(ftdm_span_t *span) ftdm_status_t sngisdn_stack_stop(ftdm_span_t *span) { + sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data; /* Stop L1 first, so we do not receive any more frames */ + if (!signal_data->dchan) { + return FTDM_SUCCESS; + } if (sngisdn_deactivate_phy(span) != FTDM_SUCCESS) { ftdm_log(FTDM_LOG_CRIT, "%s:Failed to deactivate stack phy\n", span->name); return FTDM_FAIL; @@ -147,7 +151,7 @@ ftdm_status_t sngisdn_deactivate_phy(ftdm_span_t *span) cntrl.t.cntrl.action = AUBND_DIS; cntrl.t.cntrl.subAction = SAELMNT; - cntrl.t.cntrl.sapId = signal_data->dchan_id; + cntrl.t.cntrl.sapId = signal_data->link_id; if (sng_isdn_phy_cntrl(&pst, &cntrl)) { return FTDM_FAIL; @@ -182,7 +186,7 @@ ftdm_status_t sngisdn_wake_up_phy(ftdm_span_t *span) cntrl.t.cntrl.action = AENA; cntrl.t.cntrl.subAction = SAELMNT; - cntrl.t.cntrl.sapId = signal_data->dchan_id; + cntrl.t.cntrl.sapId = signal_data->link_id; if (sng_isdn_phy_cntrl(&pst, &cntrl)) { return FTDM_FAIL; @@ -226,33 +230,34 @@ ftdm_status_t sngisdn_activate_cc(ftdm_span_t *span) ftdm_status_t sngisdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t trace_opt) { - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data; + sngisdn_span_data_t *signal_data = sngisdn_dchan((sngisdn_span_data_t*)span->signal_data); + switch (trace_opt) { case SNGISDN_TRACE_DISABLE: if (sngisdn_test_trace_flag(signal_data, SNGISDN_TRACE_Q921)) { - ftdm_log(FTDM_LOG_INFO, "s%d Disabling q921 trace\n", signal_data->link_id); + ftdm_log(FTDM_LOG_INFO, "%s:Disabling q921 trace\n", signal_data->ftdm_span->name); sngisdn_clear_trace_flag(signal_data, SNGISDN_TRACE_Q921); - if (sngisdn_cntrl_q921(span, ADISIMM, SATRC) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "s%d Failed to disable q921 trace\n"); + if (sngisdn_cntrl_q921(signal_data->ftdm_span, ADISIMM, SATRC) != FTDM_SUCCESS) { + ftdm_log(FTDM_LOG_INFO, "%s:Failed to disable q921 trace\n", signal_data->ftdm_span->name); } } if (sngisdn_test_trace_flag(signal_data, SNGISDN_TRACE_Q931)) { - ftdm_log(FTDM_LOG_INFO, "s%d Disabling q931 trace\n", signal_data->link_id); + ftdm_log(FTDM_LOG_INFO, "%s:Disabling q921 trace\n", signal_data->ftdm_span->name); sngisdn_clear_trace_flag(signal_data, SNGISDN_TRACE_Q931); - if (sngisdn_cntrl_q931(span, ADISIMM, SATRC) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "s%d Failed to disable q931 trace\n"); + if (sngisdn_cntrl_q931(signal_data->ftdm_span, ADISIMM, SATRC) != FTDM_SUCCESS) { + ftdm_log(FTDM_LOG_INFO, "%s:Failed to disable q921 trace\n", signal_data->ftdm_span->name); } } break; case SNGISDN_TRACE_Q921: if (!sngisdn_test_trace_flag(signal_data, SNGISDN_TRACE_Q921)) { - ftdm_log(FTDM_LOG_INFO, "s%d Enabling q921 trace\n", signal_data->link_id); + ftdm_log(FTDM_LOG_INFO, "%s:Enabling q921 trace\n", signal_data->ftdm_span->name); sngisdn_set_trace_flag(signal_data, SNGISDN_TRACE_Q921); - if (sngisdn_cntrl_q921(span, AENA, SATRC) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "s%d Failed to enable q921 trace\n"); + if (sngisdn_cntrl_q921(signal_data->ftdm_span, AENA, SATRC) != FTDM_SUCCESS) { + ftdm_log(FTDM_LOG_INFO, "%s:Failed to enable q921 trace\n", signal_data->ftdm_span->name); } } break; @@ -261,8 +266,8 @@ ftdm_status_t sngisdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t trac ftdm_log(FTDM_LOG_INFO, "s%d Enabling q931 trace\n", signal_data->link_id); sngisdn_set_trace_flag(signal_data, SNGISDN_TRACE_Q931); - if (sngisdn_cntrl_q931(span, AENA, SATRC) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "s%d Failed to enable q931 trace\n"); + if (sngisdn_cntrl_q931(signal_data->ftdm_span, AENA, SATRC) != FTDM_SUCCESS) { + ftdm_log(FTDM_LOG_INFO, "%s:Failed to enable q931 trace\n", signal_data->ftdm_span->name); } } break; @@ -301,7 +306,7 @@ ftdm_status_t sngisdn_cntrl_q931(ftdm_span_t *span, uint8_t action, uint8_t suba cntrl.t.cntrl.trcLen = -1; /* Trace the entire message buffer */ } - cntrl.t.cntrl.sapId = signal_data->dchan_id; + cntrl.t.cntrl.sapId = signal_data->link_id; cntrl.t.cntrl.ces = 0; if(sng_isdn_q931_cntrl(&pst, &cntrl)) { @@ -342,11 +347,11 @@ ftdm_status_t sngisdn_cntrl_q921(ftdm_span_t *span, uint8_t action, uint8_t suba cntrl.t.cntrl.subAction = subaction; #if (SMBD_LMINT3 || BD_LMINT3) - cntrl.t.cntrl.lnkNmb = signal_data->dchan_id; + cntrl.t.cntrl.lnkNmb = signal_data->link_id; cntrl.t.cntrl.sapi = NOTUSED; cntrl.t.cntrl.tei = NOTUSED; #else /* _LMINT3 */ - cntrl.hdr.elmId.elmntInst1 = signal_data->dchan_id; + cntrl.hdr.elmId.elmntInst1 = signal_data->link_id; cntrl.hdr.elmId.elmntInst2 = NOTUSED; cntrl.hdr.elmId.elmntInst3 = NOTUSED; #endif /* _LMINT3 */ 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 0a34068359..15bff0390e 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 @@ -58,6 +58,19 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event) switch (ftdmchan->state) { case FTDM_CHANNEL_STATE_DOWN: /* Proper state to receive a SETUP */ + if (signal_data->nfas.trunk) { + ftdm_alarm_flag_t alarmflag = 0; + + ftdm_channel_get_alarms(ftdmchan, &alarmflag); + if (alarmflag) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_INFO, "Received SETUP but channel has physical layer alarm - rejecting\n"); + + ftdmchan->caller_data.hangup_cause = 0x2C; /* Channel requested not available */ + ftdm_sched_timer(signal_data->sched, "delayed_release", 1, sngisdn_delayed_release, (void*) sngisdn_info, NULL); + break; + } + } + if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INUSE) || ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) { @@ -1177,13 +1190,13 @@ void sngisdn_process_rst_cfm (sngisdn_event_data_t *sngisdn_event) uint8_t chan_no = 0; Rst *rstEvnt = &sngisdn_event->event.rstEvnt; - sngisdn_span_data_t *signal_data = g_sngisdn_data.dchans[dChan].spans[1]; + sngisdn_span_data_t *signal_data = g_sngisdn_data.spans[dChan]; if (!signal_data) { ftdm_log(FTDM_LOG_CRIT, "Received RESTART CFM on unconfigured span (suId:%d)\n", suId); return; } - - if (rstEvnt->rstInd.eh.pres == PRSNT_NODEF && rstEvnt->rstInd.rstClass.pres == PRSNT_NODEF) { + + if (rstEvnt->rstInd.eh.pres == PRSNT_NODEF && rstEvnt->rstInd.rstClass.pres == PRSNT_NODEF) { switch(rstEvnt->rstInd.rstClass.val) { case IN_CL_INDCHAN: /* Indicated b-channel */ if (rstEvnt->chanId.eh.pres) { @@ -1196,6 +1209,16 @@ void sngisdn_process_rst_cfm (sngisdn_event_data_t *sngisdn_event) chan_no = rstEvnt->chanId.chanNmbSlotMap.val[0]; } } + + if (signal_data->nfas.trunk) { + if (!rstEvnt->chanId.intIdent.pres) { + ftdm_log(FTDM_LOG_CRIT, "Failed to determine interface from RESTART\n"); + return; + } else if (signal_data->nfas.interface_id != rstEvnt->chanId.intIdent.val) { + /* This RESTART is for another interface */ + return; + } + } } if (!chan_no) { ftdm_log(FTDM_LOG_CRIT, "Failed to determine channel from RESTART\n"); @@ -1258,10 +1281,7 @@ void sngisdn_process_rst_ind (sngisdn_event_data_t *sngisdn_event) rstEvnt = &sngisdn_event->event.rstEvnt; - /* TODO: readjust this when NFAS is implemented as signal_data will not always be the first - * span for that d-channel */ - - signal_data = g_sngisdn_data.dchans[dChan].spans[1]; + signal_data = g_sngisdn_data.spans[dChan]; if (!signal_data) { ftdm_log(FTDM_LOG_CRIT, "Received RESTART IND on unconfigured span (suId:%d)\n", suId); @@ -1292,6 +1312,16 @@ void sngisdn_process_rst_ind (sngisdn_event_data_t *sngisdn_event) chan_no = rstEvnt->chanId.chanNmbSlotMap.val[0]; } } + + if (signal_data->nfas.trunk) { + if (!rstEvnt->chanId.intIdent.pres) { + ftdm_log(FTDM_LOG_CRIT, "Failed to determine interface from RESTART\n"); + return; + } else if (signal_data->nfas.interface_id != rstEvnt->chanId.intIdent.val) { + /* This RESTART is for another interface */ + return; + } + } } if (!chan_no) { ftdm_log(FTDM_LOG_CRIT, "Failed to determine channel from RESTART\n"); @@ -1300,7 +1330,7 @@ void sngisdn_process_rst_ind (sngisdn_event_data_t *sngisdn_event) break; case IN_CL_SNGINT: /* Single interface */ case IN_CL_ALLINT: /* All interfaces */ - /* In case restart class indicates all interfaces, we will duplicate + /* In case restart class indicates all interfaces, we will duplicated this event on each span associated to this d-channel in sngisdn_rcv_rst_cfm, so treat it as a single interface anyway */ chan_no = 0; 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 f528333634..20b0c86ca9 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 @@ -36,10 +36,10 @@ void sngisdn_snd_setup(ftdm_channel_t *ftdmchan) { - ConEvnt conEvnt; + ConEvnt conEvnt; sngisdn_chan_data_t *sngisdn_info = ftdmchan->call_data; sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; - ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_INVALID}; + ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_INVALID}; ftdm_assert((!sngisdn_info->suInstId && !sngisdn_info->spInstId), "Trying to call out, but call data was not cleared\n"); @@ -75,9 +75,9 @@ void sngisdn_snd_setup(ftdm_channel_t *ftdmchan) set_facility_ie(ftdmchan, &conEvnt.facilityStr); set_prog_ind_ie(ftdmchan, &conEvnt.progInd, prog_ind); - ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending SETUP (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces); + ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending SETUP (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, sngisdn_dchan(signal_data)->link_id, sngisdn_info->ces); - if (sng_isdn_con_request(signal_data->cc_id, sngisdn_info->suInstId, &conEvnt, signal_data->dchan_id, sngisdn_info->ces)) { + if (sng_isdn_con_request(signal_data->cc_id, sngisdn_info->suInstId, &conEvnt, sngisdn_dchan(signal_data)->link_id, sngisdn_info->ces)) { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused SETUP request\n"); } @@ -103,9 +103,9 @@ void sngisdn_snd_setup_ack(ftdm_channel_t *ftdmchan) - ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending SETUP ACK (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces); + ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending SETUP ACK (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, sngisdn_dchan(signal_data)->link_id, sngisdn_info->ces); - if(sng_isdn_con_status(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &cnStEvnt, MI_SETUPACK, signal_data->dchan_id, sngisdn_info->ces)) { + if(sng_isdn_con_status(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &cnStEvnt, MI_SETUPACK, sngisdn_dchan(signal_data)->link_id, sngisdn_info->ces)) { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused SETUP ACK request\n"); } return; @@ -135,9 +135,9 @@ void sngisdn_snd_con_complete(ftdm_channel_t *ftdmchan) set_chan_id_ie(ftdmchan, &cnStEvnt.chanId); } - ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending CONNECT COMPL (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces); + ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending CONNECT COMPL (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, sngisdn_dchan(signal_data)->link_id, sngisdn_info->ces); - if(sng_isdn_con_comp(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &cnStEvnt, signal_data->dchan_id, sngisdn_info->ces)) { + if(sng_isdn_con_comp(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &cnStEvnt, sngisdn_dchan(signal_data)->link_id, sngisdn_info->ces)) { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused CONNECT ACK request\n"); } return; @@ -171,9 +171,9 @@ void sngisdn_snd_proceed(ftdm_channel_t *ftdmchan, ftdm_sngisdn_progind_t prog_i set_prog_ind_ie(ftdmchan, &cnStEvnt.progInd, prog_ind); set_facility_ie(ftdmchan, &cnStEvnt.facilityStr); - ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending PROCEED (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces); + ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending PROCEED (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, sngisdn_dchan(signal_data)->link_id, sngisdn_info->ces); - if(sng_isdn_con_status(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &cnStEvnt, MI_CALLPROC, signal_data->dchan_id, sngisdn_info->ces)) { + if(sng_isdn_con_status(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &cnStEvnt, MI_CALLPROC, sngisdn_dchan(signal_data)->link_id, sngisdn_info->ces)) { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused PROCEED request\n"); } return; @@ -203,8 +203,8 @@ void sngisdn_snd_progress(ftdm_channel_t *ftdmchan, ftdm_sngisdn_progind_t prog_ set_prog_ind_ie(ftdmchan, &cnStEvnt.progInd, prog_ind); set_facility_ie(ftdmchan, &cnStEvnt.facilityStr); - ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending PROGRESS (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces); - if(sng_isdn_con_status(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId,&cnStEvnt, MI_PROGRESS, signal_data->dchan_id, sngisdn_info->ces)) { + ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending PROGRESS (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, sngisdn_dchan(signal_data)->link_id, sngisdn_info->ces); + if(sng_isdn_con_status(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId,&cnStEvnt, MI_PROGRESS, sngisdn_dchan(signal_data)->link_id, sngisdn_info->ces)) { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused PROGRESS request\n"); } return; @@ -229,9 +229,9 @@ void sngisdn_snd_alert(ftdm_channel_t *ftdmchan, ftdm_sngisdn_progind_t prog_ind set_prog_ind_ie(ftdmchan, &cnStEvnt.progInd, prog_ind); set_facility_ie(ftdmchan, &cnStEvnt.facilityStr); - ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending ALERT (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces); + ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending ALERT (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, sngisdn_dchan(signal_data)->link_id, sngisdn_info->ces); - if(sng_isdn_con_status(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId,&cnStEvnt, MI_ALERTING, signal_data->dchan_id, sngisdn_info->ces)) { + if(sng_isdn_con_status(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId,&cnStEvnt, MI_ALERTING, sngisdn_dchan(signal_data)->link_id, sngisdn_info->ces)) { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused ALERT request\n"); } return; @@ -265,8 +265,8 @@ void sngisdn_snd_connect(ftdm_channel_t *ftdmchan) set_prog_ind_ie(ftdmchan, &cnStEvnt.progInd, prog_ind); set_facility_ie(ftdmchan, &cnStEvnt.facilityStr); - ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending CONNECT (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces); - if (sng_isdn_con_response(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &cnStEvnt, signal_data->dchan_id, sngisdn_info->ces)) { + ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending CONNECT (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, sngisdn_dchan(signal_data)->link_id, sngisdn_info->ces); + if (sng_isdn_con_response(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &cnStEvnt, sngisdn_dchan(signal_data)->link_id, sngisdn_info->ces)) { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused CONNECT request\n"); } return; @@ -297,9 +297,9 @@ void sngisdn_snd_fac_req(ftdm_channel_t *ftdmchan) facEvnt.facElmt.facStr.val[1] = (uint8_t)facEvnt.facElmt.facStr.len; facEvnt.facElmt.facStr.len +=2; /* Need to include the size of identifier + len */ - ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending FACILITY (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces); + ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending FACILITY (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, sngisdn_dchan(signal_data)->link_id, sngisdn_info->ces); - if (sng_isdn_facility_request(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &facEvnt, MI_FACIL, signal_data->dchan_id, sngisdn_info->ces)) { + if (sng_isdn_facility_request(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &facEvnt, MI_FACIL, sngisdn_dchan(signal_data)->link_id, sngisdn_info->ces)) { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused FACILITY request\n"); } return; @@ -322,9 +322,9 @@ void sngisdn_snd_info_req(ftdm_channel_t *ftdmchan) 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, signal_data->dchan_id, sngisdn_info->ces); + 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); - if (sng_isdn_con_status(signal_data->cc_id, 0, 0, &cnStEvnt, MI_INFO, signal_data->dchan_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"); } return; @@ -348,9 +348,9 @@ void sngisdn_snd_notify_req(ftdm_channel_t *ftdmchan) set_not_ind_ie(ftdmchan, &cnStEvnt.notInd); - ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending NOTIFY (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces); + ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending NOTIFY (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, sngisdn_dchan(signal_data)->link_id, sngisdn_info->ces); - if(sng_isdn_con_status(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId,&cnStEvnt, MI_NOTIFY, signal_data->dchan_id, sngisdn_info->ces)) { + if(sng_isdn_con_status(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId,&cnStEvnt, MI_NOTIFY, sngisdn_dchan(signal_data)->link_id, sngisdn_info->ces)) { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused NOTIFY request\n"); } return; @@ -368,7 +368,7 @@ void sngisdn_snd_status_enq(ftdm_channel_t *ftdmchan) memset(&staEvnt, 0, sizeof(StaEvnt)); - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Sending Status ENQ on suId:%d suInstId:%u spInstId:%d dchan:%d ces:%d\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces); + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Sending Status ENQ on suId:%d suInstId:%u spInstId:%d dchan:%d ces:%d\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, sngisdn_dchan(signal_data)->link_id, sngisdn_info->ces); if (sng_isdn_status_request(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &staEvnt, MI_STATENQ)) { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused Status ENQ request\n"); } @@ -468,9 +468,9 @@ void sngisdn_snd_restart(ftdm_channel_t *ftdmchan) set_chan_id_ie(ftdmchan, &rstEvnt.chanId); set_restart_ind_ie(ftdmchan, &rstEvnt.rstInd); - ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending RESTART (suId:%d dchan:%d ces:%d)\n", signal_data->cc_id, signal_data->dchan_id, CES_MNGMNT); + ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending RESTART (suId:%d dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_dchan(signal_data)->link_id, CES_MNGMNT); - if (sng_isdn_restart_request(signal_data->cc_id, &rstEvnt, signal_data->dchan_id, CES_MNGMNT, IN_SND_RST)) { + if (sng_isdn_restart_request(signal_data->cc_id, &rstEvnt, sngisdn_dchan(signal_data)->link_id, CES_MNGMNT, IN_SND_RST)) { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused RESTART request\n"); } return; @@ -535,25 +535,26 @@ void sngisdn_snd_data(ftdm_channel_t *dchan, uint8_t *data, ftdm_size_t len) ftdm_log_chan(dchan, FTDM_LOG_CRIT, "\nL1 RX [%s] flags:%x\n", string, l1_frame.flags); } #endif - sng_isdn_data_ind(signal_data->dchan_id, &l1_frame); + sng_isdn_data_ind(signal_data->link_id, &l1_frame); } -void sngisdn_snd_event(ftdm_channel_t *dchan, ftdm_oob_event_t event) +void sngisdn_snd_event(sngisdn_span_data_t *signal_data, ftdm_oob_event_t event) { sng_l1_event_t l1_event; - sngisdn_span_data_t *signal_data = NULL; + + if (!signal_data->dchan) { + return; + } memset(&l1_event, 0, sizeof(l1_event)); - - - signal_data = (sngisdn_span_data_t*) dchan->span->signal_data; + switch(event) { case FTDM_OOB_ALARM_CLEAR: l1_event.type = SNG_L1EVENT_ALARM_OFF; - sng_isdn_event_ind(signal_data->dchan_id, &l1_event); + sng_isdn_event_ind(signal_data->link_id, &l1_event); break; case FTDM_OOB_ALARM_TRAP: l1_event.type = SNG_L1EVENT_ALARM_ON; - sng_isdn_event_ind(signal_data->dchan_id, &l1_event); + sng_isdn_event_ind(signal_data->link_id, &l1_event); break; default: /* We do not care about the other OOB events for now */ 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 c45bbf0874..17e8d54084 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 @@ -33,17 +33,19 @@ */ #include "ftmod_sangoma_isdn.h" +//static void sngisdn_rcv_q931_ind_span(sngisdn_span_data_t *signal_data, InMngmt *status); void sngisdn_rcv_con_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, ConEvnt *conEvnt, int16_t dChan, uint8_t ces) { uint8_t bchan_no = 0; + int8_t interface_id = -1; /* Specifies which interface for NFAS */ sngisdn_chan_data_t *sngisdn_info = NULL; sngisdn_event_data_t *sngisdn_event = NULL; ISDN_FUNC_TRACE_ENTER(__FUNCTION__); 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"); + ftdm_assert(g_sngisdn_data.spans[dChan], "Con Ind on unconfigured dchan\n"); if (conEvnt->chanId.eh.pres != PRSNT_NODEF) { /* TODO: Implement me */ @@ -58,19 +60,38 @@ void sngisdn_rcv_con_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, Co bchan_no = conEvnt->chanId.infoChanSel.val; } + if (conEvnt->chanId.intIdent.pres) { + interface_id = conEvnt->chanId.intIdent.val; + } + if (!bchan_no) { ftdm_log(FTDM_LOG_ERROR, "Failed to obtain b-channel number from SETUP message\n"); ISDN_FUNC_TRACE_EXIT(__FUNCTION__); return; } - if (g_sngisdn_data.dchans[dChan].channels[bchan_no] == NULL) { - ftdm_log(FTDM_LOG_ERROR, "Incoming call on unconfigured b-channel:%d\n", bchan_no); - ISDN_FUNC_TRACE_EXIT(__FUNCTION__); - return; + if (g_sngisdn_data.spans[dChan]->nfas.trunk) { + if (interface_id < 0) { + ftdm_log(FTDM_LOG_ERROR, "Interface ID not present on NFAS interface\n"); + ISDN_FUNC_TRACE_EXIT(__FUNCTION__); + return; + } else if (!g_sngisdn_data.spans[dChan]->nfas.trunk->spans[interface_id]) { + ftdm_log(FTDM_LOG_ERROR, "NFAS group:%s does not have logical interface %d\n", g_sngisdn_data.spans[dChan]->nfas.trunk->name, interface_id); + ISDN_FUNC_TRACE_EXIT(__FUNCTION__); + return; + } else { + sngisdn_info = g_sngisdn_data.spans[dChan]->nfas.trunk->spans[interface_id]->channels[bchan_no]; + } + } else { + if (g_sngisdn_data.spans[dChan]->channels[bchan_no] == NULL) { + ftdm_log(FTDM_LOG_ERROR, "Incoming call on unconfigured b-channel:%d\n", bchan_no); + ISDN_FUNC_TRACE_EXIT(__FUNCTION__); + return; + } + + sngisdn_info = g_sngisdn_data.spans[dChan]->channels[bchan_no]; } - - sngisdn_info = g_sngisdn_data.dchans[dChan].channels[bchan_no]; + ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received SETUP (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); @@ -103,7 +124,7 @@ void sngisdn_rcv_con_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, Cn ISDN_FUNC_TRACE_ENTER(__FUNCTION__); 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"); + ftdm_assert(g_sngisdn_data.spans[dChan] != 0, "Con Cfm on unconfigured dchan\n"); if (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); @@ -147,7 +168,7 @@ void sngisdn_rcv_cnst_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, C ISDN_FUNC_TRACE_ENTER(__FUNCTION__); 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"); + ftdm_assert(g_sngisdn_data.spans[dChan] != 0, "Cnst Ind on unconfigured dchan\n"); if (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); @@ -537,37 +558,41 @@ void sngisdn_rcv_sta_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, St void sngisdn_rcv_srv_ind (int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces) { - unsigned i; + sngisdn_span_data_t *signal_data; sngisdn_event_data_t *sngisdn_event = NULL; ISDN_FUNC_TRACE_ENTER(__FUNCTION__); ftdm_log(FTDM_LOG_INFO, "Received SERVICE IND (dChan:%d ces:%u)\n", dChan, ces); - - /* Enqueue the event to each span within the dChan */ - 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 != NULL, "Failed to allocate memory\n"); - memset(sngisdn_event, 0, sizeof(*sngisdn_event)); - sngisdn_event->event_id = SNGISDN_EVENT_SRV_IND; - sngisdn_event->suId = suId; - sngisdn_event->dChan = dChan; - sngisdn_event->ces = ces; - sngisdn_event->signal_data = signal_data; - - memcpy(&sngisdn_event->event.srvEvnt, srvEvnt, sizeof(*srvEvnt)); - ftdm_queue_enqueue((signal_data)->event_queue, sngisdn_event); + signal_data = g_sngisdn_data.spans[dChan]; + + if (signal_data->nfas.trunk) { + unsigned i; + for (i = 0; i < signal_data->nfas.trunk->num_spans; i++) { + sngisdn_span_data_t *my_signal_data = signal_data->nfas.trunk->spans[i]; + + sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); + 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; + sngisdn_event->suId = suId; + sngisdn_event->dChan = dChan; + sngisdn_event->ces = ces; + sngisdn_event->signal_data = my_signal_data; + memcpy(&sngisdn_event->event.srvEvnt, srvEvnt, sizeof(*srvEvnt)); + ftdm_queue_enqueue(my_signal_data->event_queue, sngisdn_event); + } + } else { + ftdm_queue_enqueue(signal_data->event_queue, sngisdn_event); } ISDN_FUNC_TRACE_EXIT(__FUNCTION__); } void sngisdn_rcv_srv_cfm (int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces) -{ - unsigned i; +{ sngisdn_span_data_t *signal_data = NULL; sngisdn_event_data_t *sngisdn_event = NULL; @@ -575,59 +600,65 @@ void sngisdn_rcv_srv_cfm (int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces ftdm_log(FTDM_LOG_INFO, "Received SERVICE CFM (dChan:%d ces:%u)\n", dChan, ces); - /* Enqueue the event to each span within the dChan */ - 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 != NULL, "Failed to allocate memory\n"); - memset(sngisdn_event, 0, sizeof(*sngisdn_event)); + signal_data = g_sngisdn_data.spans[dChan]; - sngisdn_event->event_id = SNGISDN_EVENT_SRV_CFM; - sngisdn_event->suId = suId; - sngisdn_event->dChan = dChan; - sngisdn_event->ces = ces; - sngisdn_event->signal_data = signal_data; + if (signal_data->nfas.trunk) { + unsigned i; + for (i = 0; i < signal_data->nfas.trunk->num_spans; i++) { + sngisdn_span_data_t *my_signal_data = signal_data->nfas.trunk->spans[i]; - memcpy(&sngisdn_event->event.srvEvnt, srvEvnt, sizeof(*srvEvnt)); - ftdm_queue_enqueue((signal_data)->event_queue, sngisdn_event); + sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); + 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; + sngisdn_event->suId = suId; + sngisdn_event->dChan = dChan; + sngisdn_event->ces = ces; + sngisdn_event->signal_data = my_signal_data; + memcpy(&sngisdn_event->event.srvEvnt, srvEvnt, sizeof(*srvEvnt)); + ftdm_queue_enqueue(my_signal_data->event_queue, sngisdn_event); + } + } else { + ftdm_queue_enqueue(signal_data->event_queue, sngisdn_event); } ISDN_FUNC_TRACE_EXIT(__FUNCTION__); } void sngisdn_rcv_rst_ind (int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces, uint8_t evntType) -{ - unsigned i; +{ sngisdn_span_data_t *signal_data = NULL; sngisdn_event_data_t *sngisdn_event = NULL; ISDN_FUNC_TRACE_ENTER(__FUNCTION__); ftdm_log(FTDM_LOG_INFO, "Received RESTART IND (dChan:%d ces:%u type:%u)\n", dChan, ces, evntType); - - /* Enqueue the event to each span within the dChan */ - 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 != NULL, "Failed to allocate memory\n"); - memset(sngisdn_event, 0, sizeof(*sngisdn_event)); + signal_data = g_sngisdn_data.spans[dChan]; - sngisdn_event->event_id = SNGISDN_EVENT_RST_IND; - sngisdn_event->suId = suId; - sngisdn_event->dChan = dChan; - sngisdn_event->ces = ces; - sngisdn_event->evntType = evntType; - sngisdn_event->signal_data = signal_data; + if (signal_data->nfas.trunk) { + unsigned i; + for (i = 0; i < signal_data->nfas.trunk->num_spans; i++) { + sngisdn_span_data_t *my_signal_data = signal_data->nfas.trunk->spans[i]; - memcpy(&sngisdn_event->event.rstEvnt, rstEvnt, sizeof(*rstEvnt)); + sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); + 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; + sngisdn_event->suId = suId; + sngisdn_event->dChan = dChan; + sngisdn_event->ces = ces; + sngisdn_event->signal_data = my_signal_data; + memcpy(&sngisdn_event->event.rstEvnt, rstEvnt, sizeof(*rstEvnt)); + ftdm_queue_enqueue(my_signal_data->event_queue, sngisdn_event); + } + } else { ftdm_queue_enqueue(signal_data->event_queue, sngisdn_event); } ISDN_FUNC_TRACE_EXIT(__FUNCTION__); } void sngisdn_rcv_rst_cfm (int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces, uint8_t evntType) -{ - unsigned i; +{ sngisdn_span_data_t *signal_data; sngisdn_event_data_t *sngisdn_event = NULL; @@ -636,22 +667,26 @@ void sngisdn_rcv_rst_cfm (int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces ftdm_log(FTDM_LOG_INFO, "Received RESTART CFM (dChan:%d ces:%u type:%u)\n", dChan, ces, evntType); - /* Enqueue the event to each span within the dChan */ - 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 != NULL, "Failed to allocate memory\n"); - memset(sngisdn_event, 0, sizeof(*sngisdn_event)); + signal_data = g_sngisdn_data.spans[dChan]; - sngisdn_event->event_id = SNGISDN_EVENT_RST_CFM; - sngisdn_event->suId = suId; - sngisdn_event->dChan = dChan; - sngisdn_event->ces = ces; - sngisdn_event->evntType = evntType; - sngisdn_event->signal_data = signal_data; + if (signal_data->nfas.trunk) { + unsigned i; + for (i = 0; i < signal_data->nfas.trunk->num_spans; i++) { + sngisdn_span_data_t *my_signal_data = signal_data->nfas.trunk->spans[i]; - memcpy(&sngisdn_event->event.rstEvnt, rstEvnt, sizeof(*rstEvnt)); - ftdm_queue_enqueue((signal_data)->event_queue, sngisdn_event); + sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); + 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; + sngisdn_event->suId = suId; + sngisdn_event->dChan = dChan; + sngisdn_event->ces = ces; + sngisdn_event->signal_data = my_signal_data; + memcpy(&sngisdn_event->event.rstEvnt, rstEvnt, sizeof(*rstEvnt)); + ftdm_queue_enqueue(my_signal_data->event_queue, sngisdn_event); + } + } else { + ftdm_queue_enqueue(signal_data->event_queue, sngisdn_event); } ISDN_FUNC_TRACE_EXIT(__FUNCTION__); } @@ -660,7 +695,7 @@ void sngisdn_rcv_rst_cfm (int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces void sngisdn_rcv_phy_ind(SuId suId, Reason reason) { if (reason != LL1_REASON_CON_REQ_FAIL) { - ftdm_log(FTDM_LOG_INFO, "[SNGISDN PHY] D-chan %d : %s\n", suId, DECODE_LL1_REASON(reason)); + ftdm_log(FTDM_LOG_DEBUG, "[SNGISDN PHY] D-chan %d : %s\n", suId, DECODE_LL1_REASON(reason)); } return; } @@ -669,7 +704,7 @@ void sngisdn_rcv_q921_ind(BdMngmt *status) { ftdm_span_t *ftdmspan; - sngisdn_span_data_t *signal_data = g_sngisdn_data.dchans[status->t.usta.lnkNmb].spans[1]; + sngisdn_span_data_t *signal_data = g_sngisdn_data.spans[status->t.usta.lnkNmb]; if (!signal_data) { ftdm_log(FTDM_LOG_INFO, "Received q921 status on unconfigured span (lnkNmb:%d)\n", status->t.usta.lnkNmb); @@ -722,8 +757,43 @@ void sngisdn_rcv_q921_ind(BdMngmt *status) } return; } + +#if 0 +static void sngisdn_rcv_q931_ind_span(sngisdn_span_data_t *signal_data, InMngmt *status) +{ + ftdm_span_t *ftdmspan = signal_data->ftdm_span; + uint32_t chan_no = status->t.usta.evntParm[2]; + + if (!signal_data) { + ftdm_log(FTDM_LOG_INFO, "Received q931 status on unconfigured span (lnkNmb:%d)\n", status->t.usta.suId); + return; + } + + ftdm_log(FTDM_LOG_INFO, "[SNGISDN Q931] s%d: %s: %s(%d): %s(%d)\n", + status->t.usta.suId, + DECODE_LCM_CATEGORY(status->t.usta.alarm.category), + DECODE_LCM_EVENT(status->t.usta.alarm.event), status->t.usta.alarm.event, + DECODE_LCM_CAUSE(status->t.usta.alarm.cause), status->t.usta.alarm.cause); + + if (chan_no) { + ftdm_channel_t *ftdmchan = ftdm_span_get_channel(ftdmspan, chan_no); + if (ftdmchan) { + sngisdn_set_chan_sig_status(ftdmchan, (status->t.usta.alarm.event == LCM_EVENT_UP) ? FTDM_SIG_STATE_UP : FTDM_SIG_STATE_DOWN); + sngisdn_set_chan_avail_rate(ftdmchan, (status->t.usta.alarm.event == LCM_EVENT_UP) ? SNGISDN_AVAIL_UP: SNGISDN_AVAIL_PWR_SAVING); + } else { + ftdm_log(FTDM_LOG_CRIT, "stack alarm event on invalid channel :%d\n", chan_no); + } + } else { + sngisdn_set_span_sig_status(ftdmspan, (status->t.usta.alarm.event == LCM_EVENT_UP) ? FTDM_SIG_STATE_UP : FTDM_SIG_STATE_DOWN); + sngisdn_set_span_avail_rate(ftdmspan, (status->t.usta.alarm.event == LCM_EVENT_UP) ? SNGISDN_AVAIL_UP: SNGISDN_AVAIL_PWR_SAVING); + } +} +#endif + void sngisdn_rcv_q931_ind(InMngmt *status) -{ +{ + sngisdn_span_data_t *signal_data = NULL; + ftdm_span_t *ftdmspan = NULL; #ifndef WIN32 if (status->t.usta.alarm.cause == 287) { sngisdn_get_memory_info(); @@ -731,47 +801,53 @@ void sngisdn_rcv_q931_ind(InMngmt *status) } #endif + signal_data = g_sngisdn_data.spans[status->t.usta.suId]; + if (!signal_data) { + ftdm_log(FTDM_LOG_INFO, "Received q931 status on unconfigured span (lnkNmb:%d)\n", status->t.usta.suId); + return; + } + + ftdmspan = signal_data->ftdm_span; + switch (status->t.usta.alarm.event) { case LCM_EVENT_UP: case LCM_EVENT_DOWN: { - ftdm_span_t *ftdmspan; - sngisdn_span_data_t *signal_data = g_sngisdn_data.dchans[status->t.usta.suId].spans[1]; - if (!signal_data) { - ftdm_log(FTDM_LOG_INFO, "Received q931 status on unconfigured span (lnkNmb:%d)\n", status->t.usta.suId); - return; - } - ftdmspan = signal_data->ftdm_span; - - if (status->t.usta.alarm.event == LCM_EVENT_UP) { - uint32_t chan_no = status->t.usta.evntParm[2]; - ftdm_log(FTDM_LOG_INFO, "[SNGISDN Q931] s%d: %s: %s(%d): %s(%d)\n", - status->t.usta.suId, - DECODE_LCM_CATEGORY(status->t.usta.alarm.category), - DECODE_LCM_EVENT(status->t.usta.alarm.event), status->t.usta.alarm.event, - DECODE_LCM_CAUSE(status->t.usta.alarm.cause), status->t.usta.alarm.cause); + int i; + sngisdn_nfas_data_t *nfas_data = NULL; + ftdm_log(FTDM_LOG_INFO, "[SNGISDN Q931] s%d: %s: %s(%d): %s(%d)\n", + status->t.usta.suId, + DECODE_LCM_CATEGORY(status->t.usta.alarm.category), + DECODE_LCM_EVENT(status->t.usta.alarm.event), status->t.usta.alarm.event, + DECODE_LCM_CAUSE(status->t.usta.alarm.cause), status->t.usta.alarm.cause); - if (chan_no) { - ftdm_channel_t *ftdmchan = ftdm_span_get_channel(ftdmspan, chan_no); - if (ftdmchan) { - sngisdn_set_chan_sig_status(ftdmchan, FTDM_SIG_STATE_UP); - sngisdn_set_chan_avail_rate(ftdmchan, SNGISDN_AVAIL_UP); - } else { - ftdm_log(FTDM_LOG_CRIT, "stack alarm event on invalid channel :%d\n", chan_no); + nfas_data = signal_data->nfas.trunk; + + if (nfas_data && status->t.usta.alarm.event == LCM_EVENT_UP) { + 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) { + + sngisdn_set_span_sig_status(nfas_data->spans[i]->ftdm_span, FTDM_SIG_STATE_UP); + sngisdn_set_span_avail_rate(nfas_data->spans[i]->ftdm_span, SNGISDN_AVAIL_UP); + } + } + } + + sngisdn_set_span_sig_status(ftdmspan, (status->t.usta.alarm.event == LCM_EVENT_UP) ? FTDM_SIG_STATE_UP : FTDM_SIG_STATE_DOWN); + sngisdn_set_span_avail_rate(ftdmspan, (status->t.usta.alarm.event == LCM_EVENT_UP) ? SNGISDN_AVAIL_UP: SNGISDN_AVAIL_PWR_SAVING); + + 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)) { + + 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) { + + sngisdn_set_span_sig_status(nfas_data->spans[i]->ftdm_span, FTDM_SIG_STATE_DOWN); + sngisdn_set_span_avail_rate(nfas_data->spans[i]->ftdm_span, SNGISDN_AVAIL_PWR_SAVING); + } } - } else { - sngisdn_set_span_sig_status(ftdmspan, FTDM_SIG_STATE_UP); - sngisdn_set_span_avail_rate(ftdmspan, SNGISDN_AVAIL_UP); } - } else { - ftdm_log(FTDM_LOG_WARNING, "[SNGISDN Q931] s%d: %s: %s(%d): %s(%d)\n", - status->t.usta.suId, - DECODE_LCM_CATEGORY(status->t.usta.alarm.category), - DECODE_LCM_EVENT(status->t.usta.alarm.event), status->t.usta.alarm.event, - DECODE_LCM_CAUSE(status->t.usta.alarm.cause), status->t.usta.alarm.cause); - - sngisdn_set_span_sig_status(ftdmspan, FTDM_SIG_STATE_DOWN); - sngisdn_set_span_avail_rate(ftdmspan, SNGISDN_AVAIL_PWR_SAVING); } } break; @@ -805,7 +881,7 @@ void sngisdn_rcv_q931_trace(InMngmt *trc, Buffer *mBuf) ftdm_trace_dir_t dir; uint8_t tdata[1000]; - sngisdn_span_data_t *signal_data = g_sngisdn_data.dchans[trc->t.trc.suId].spans[1]; + sngisdn_span_data_t *signal_data = g_sngisdn_data.spans[trc->t.trc.suId]; ftdm_assert(mBuf != NULLP, "Received a Q931 trace with no buffer"); mlen = ((SsMsgInfo*)(mBuf->b_rptr))->len; @@ -851,7 +927,7 @@ void sngisdn_rcv_q921_trace(BdMngmt *trc, Buffer *mBuf) ftdm_trace_dir_t dir; uint8_t tdata[1000]; - sngisdn_span_data_t *signal_data = g_sngisdn_data.dchans[trc->t.trc.lnkNmb].spans[1]; + sngisdn_span_data_t *signal_data = g_sngisdn_data.spans[trc->t.trc.lnkNmb]; if (trc->t.trc.evnt == TL2TMR) { return; @@ -900,7 +976,7 @@ int16_t sngisdn_rcv_l1_data_req(uint16_t spId, sng_l1_frame_t *l1_frame) { ftdm_status_t status; ftdm_wait_flag_t flags = FTDM_WRITE; - sngisdn_span_data_t *signal_data = g_sngisdn_data.dchans[spId].spans[1]; + sngisdn_span_data_t *signal_data = g_sngisdn_data.spans[spId]; ftdm_size_t length = l1_frame->len; ftdm_assert(signal_data, "Received Data request on unconfigured span\n"); @@ -952,7 +1028,7 @@ int16_t sngisdn_rcv_l1_data_req(uint16_t spId, sng_l1_frame_t *l1_frame) int16_t sngisdn_rcv_l1_cmd_req(uint16_t spId, sng_l1_cmd_t *l1_cmd) { - sngisdn_span_data_t *signal_data = g_sngisdn_data.dchans[spId].spans[1]; + sngisdn_span_data_t *signal_data = g_sngisdn_data.spans[spId]; ftdm_assert(signal_data, "Received Data request on unconfigured span\n"); switch(l1_cmd->type) { 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 254b3abbfb..737805c0cd 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 @@ -1061,11 +1061,12 @@ ftdm_status_t set_cause_ie(ftdm_channel_t *ftdmchan, CauseDgn *causeDgn) ftdm_status_t set_chan_id_ie(ftdm_channel_t *ftdmchan, ChanId *chanId) { + sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*)ftdmchan->call_data; if (!ftdmchan) { return FTDM_SUCCESS; } - + ftdm_set_flag(sngisdn_info, FLAG_SENT_CHAN_ID); chanId->eh.pres = PRSNT_NODEF; @@ -1084,6 +1085,12 @@ ftdm_status_t set_chan_id_ie(ftdm_channel_t *ftdmchan, ChanId *chanId) chanId->infoChanSel.pres = PRSNT_NODEF; chanId->infoChanSel.val = ftdmchan->physical_chan_id; } else { + if (signal_data->nfas.trunk) { + chanId->intIdentPres.val = IN_IIP_EXPLICIT; + chanId->intIdent.pres = PRSNT_NODEF; + chanId->intIdent.val = signal_data->nfas.interface_id; + } + chanId->intType.pres = PRSNT_NODEF; chanId->intType.val = IN_IT_OTHER; chanId->infoChanSel.pres = PRSNT_NODEF; @@ -1098,6 +1105,7 @@ ftdm_status_t set_chan_id_ie(ftdm_channel_t *ftdmchan, ChanId *chanId) chanId->chanNmbSlotMap.len = 1; chanId->chanNmbSlotMap.val[0] = ftdmchan->physical_chan_id; } + return FTDM_SUCCESS; } @@ -1217,6 +1225,23 @@ void sngisdn_delayed_setup(void *p_sngisdn_info) return; } +void sngisdn_delayed_release_nfas(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); + + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Sending delayed RELEASE (suId:%d suInstId:%u spInstId:%u)\n", + signal_data->cc_id, sngisdn_info->spInstId, sngisdn_info->suInstId); + + sngisdn_snd_release(ftdmchan, 0); + + ftdm_mutex_unlock(ftdmchan->mutex); + return; +} + void sngisdn_delayed_release(void *p_sngisdn_info) { sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*)p_sngisdn_info; @@ -1413,7 +1438,7 @@ ftdm_status_t sngisdn_show_l1_stats(ftdm_stream_handle_t *stream, ftdm_span_t *s sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data; memset(&sts, 0, sizeof(sts)); - sng_isdn_phy_stats(signal_data->link_id , &sts); + sng_isdn_phy_stats(sngisdn_dchan(signal_data)->link_id , &sts); stream->write_function(stream, "\n---------------------------------------------------------------------\n"); stream->write_function(stream, " Span:%s", span->name); @@ -1548,6 +1573,14 @@ void sngisdn_send_signal(sngisdn_chan_data_t *sngisdn_info, ftdm_signal_event_t ftdm_span_send_signal(ftdmchan->span, &sigev); } +sngisdn_span_data_t *sngisdn_dchan(sngisdn_span_data_t *signal_data) +{ + if (!signal_data->nfas.trunk) { + return signal_data; + } + return signal_data->nfas.trunk->dchan; +} + /* For Emacs: * Local Variables: From b0f6e0384d8e109b364cb714861d198bf697842d Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Mon, 3 Sep 2012 22:26:03 -0400 Subject: [PATCH 3/5] freetdm - ISDN:Fix for invalidating logical span id = 0 for nfas --- .../src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 45c6c9cc17..eedb677f2b 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 @@ -223,7 +223,7 @@ static ftdm_status_t parse_spanmap(const char *_spanmap, ftdm_span_t *span) } } - if (!name || logical_span_id < 0) { + if (!name) { ftdm_log(FTDM_LOG_ERROR, "Invalid spanmap syntax %s\n", _spanmap); ret = FTDM_FAIL; goto done; From e64e5516122030b8557d5a18841170a119d74082 Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Mon, 3 Sep 2012 23:30:49 -0400 Subject: [PATCH 4/5] Removed --- README.md | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 README.md diff --git a/README.md b/README.md deleted file mode 100644 index 828df27ffb..0000000000 --- a/README.md +++ /dev/null @@ -1,4 +0,0 @@ -freeswitch -========== - -Personal Copy of Freeswitch \ No newline at end of file From 8c9ddd95ed5381141d7ed54cd5570cfa241b9cf7 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Mon, 3 Sep 2012 22:39:25 -0500 Subject: [PATCH 5/5] tiff add missing file required by makefile.am --- libs/tiff-4.0.2/configure.gnu | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 libs/tiff-4.0.2/configure.gnu diff --git a/libs/tiff-4.0.2/configure.gnu b/libs/tiff-4.0.2/configure.gnu new file mode 100644 index 0000000000..c78238de46 --- /dev/null +++ b/libs/tiff-4.0.2/configure.gnu @@ -0,0 +1,4 @@ +#! /bin/sh +srcpath=$(dirname $0 2>/dev/null ) || srcpath="." +$srcpath/configure "$@" --disable-shared --with-pic +