Merge branch 'master' of git.freeswitch.org:freeswitch

This commit is contained in:
Steve Underwood 2012-09-04 12:12:11 +08:00
commit ce82b7b927
12 changed files with 759 additions and 325 deletions

View File

@ -1917,10 +1917,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");
}
}
@ -2525,7 +2523,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));
}

View File

@ -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;
}
}

View File

@ -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);
@ -554,6 +575,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);
@ -565,6 +587,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);

View File

@ -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, 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) {
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);
}

View File

@ -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)) {

View File

@ -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;
@ -905,13 +943,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 */
@ -971,7 +1023,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;
if (span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
/* Stack will send Restart CFM's each time link is established (TEI negotiated),
@ -998,13 +1050,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;

View File

@ -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", signal_data->link_id);
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", signal_data->link_id);
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", signal_data->link_id);
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", signal_data->link_id);
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 */

View File

@ -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) {
@ -1183,7 +1196,7 @@ 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;
@ -1211,6 +1224,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");
@ -1273,10 +1296,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);
@ -1307,6 +1327,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");
@ -1315,7 +1345,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;

View File

@ -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");
@ -76,9 +76,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");
}
@ -104,9 +104,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;
@ -136,9 +136,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;
@ -172,9 +172,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;
@ -204,8 +204,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;
@ -230,9 +230,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;
@ -266,8 +266,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;
@ -298,9 +298,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;
@ -323,9 +323,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;
@ -349,9 +349,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;
@ -369,7 +369,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");
}
@ -469,9 +469,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;
@ -536,25 +536,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 */

View File

@ -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) {

View File

@ -1081,11 +1081,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;
@ -1104,6 +1105,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;
@ -1118,6 +1125,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;
}
@ -1237,6 +1245,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;
@ -1433,7 +1458,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);
@ -1568,6 +1593,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:

View File

@ -0,0 +1,4 @@
#! /bin/sh
srcpath=$(dirname $0 2>/dev/null ) || srcpath="."
$srcpath/configure "$@" --disable-shared --with-pic