parent
6e14d6f5b2
commit
c91d81a483
|
@ -726,7 +726,7 @@ static FIO_SPAN_SET_SIG_STATUS_FUNCTION(ftdm_sangoma_isdn_set_span_sig_status)
|
|||
}
|
||||
|
||||
static ftdm_status_t ftdm_sangoma_isdn_start(ftdm_span_t *span)
|
||||
{
|
||||
{
|
||||
ftdm_log(FTDM_LOG_INFO,"Starting span %s:%u.\n",span->name,span->span_id);
|
||||
if (sng_isdn_stack_start(span) != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Failed to start span %s\n", span->name);
|
||||
|
@ -747,9 +747,11 @@ static ftdm_status_t ftdm_sangoma_isdn_start(ftdm_span_t *span)
|
|||
}
|
||||
|
||||
static ftdm_status_t ftdm_sangoma_isdn_stop(ftdm_span_t *span)
|
||||
{
|
||||
{
|
||||
ftdm_iterator_t *chaniter = NULL;
|
||||
ftdm_iterator_t *curr = NULL;
|
||||
unsigned i;
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data;
|
||||
ftdm_log(FTDM_LOG_INFO, "Stopping span %s\n", span->name);
|
||||
|
||||
/* throw the STOP_THREAD flag to signal monitor thread stop */
|
||||
|
@ -772,8 +774,13 @@ static ftdm_status_t ftdm_sangoma_isdn_stop(ftdm_span_t *span)
|
|||
}
|
||||
ftdm_iterator_free(chaniter);
|
||||
|
||||
ftdm_sched_destroy(&((sngisdn_span_data_t*)span->signal_data)->sched);
|
||||
ftdm_queue_destroy(&((sngisdn_span_data_t*)span->signal_data)->event_queue);
|
||||
ftdm_sched_destroy(&signal_data->sched);
|
||||
ftdm_queue_destroy(&signal_data->event_queue);
|
||||
for (i = 0 ; i < signal_data->num_local_numbers ; i++) {
|
||||
if (signal_data->local_numbers[i] != NULL) {
|
||||
ftdm_safe_free(signal_data->local_numbers[i]);
|
||||
}
|
||||
}
|
||||
ftdm_safe_free(span->signal_data);
|
||||
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Finished stopping span %s\n", span->name);
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
#define NUM_BRI_CHANNELS_PER_SPAN 2
|
||||
#define SNGISDN_EVENT_QUEUE_SIZE 100
|
||||
#define SNGISDN_EVENT_POLL_RATE 100
|
||||
#define SNGISDN_NUM_LOCAL_NUMBERS 8
|
||||
|
||||
/* TODO: rename all *_cc_* to *_an_* */
|
||||
|
||||
|
@ -161,7 +162,7 @@ typedef struct sngisdn_chan_data {
|
|||
|
||||
/* Span specific data */
|
||||
typedef struct sngisdn_span_data {
|
||||
ftdm_span_t *ftdm_span;
|
||||
ftdm_span_t *ftdm_span;
|
||||
uint8_t link_id;
|
||||
uint8_t switchtype;
|
||||
uint8_t signalling; /* SNGISDN_SIGNALING_CPE or SNGISDN_SIGNALING_NET */
|
||||
|
@ -175,7 +176,9 @@ typedef struct sngisdn_span_data {
|
|||
uint8_t setup_arb;
|
||||
uint8_t facility;
|
||||
int8_t facility_timeout;
|
||||
ftdm_sched_t *sched;
|
||||
uint8_t num_local_numbers;
|
||||
char* local_numbers[SNGISDN_NUM_LOCAL_NUMBERS];
|
||||
ftdm_sched_t *sched;
|
||||
ftdm_queue_t *event_queue;
|
||||
} sngisdn_span_data_t;
|
||||
|
||||
|
|
|
@ -36,9 +36,23 @@
|
|||
|
||||
ftdm_status_t parse_switchtype(const char* switch_name, ftdm_span_t *span);
|
||||
ftdm_status_t parse_signalling(const char* signalling, ftdm_span_t *span);
|
||||
ftdm_status_t add_local_number(const char* val, ftdm_span_t *span);
|
||||
|
||||
extern ftdm_sngisdn_data_t g_sngisdn_data;
|
||||
|
||||
ftdm_status_t add_local_number(const char* val, ftdm_span_t *span)
|
||||
{
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data;
|
||||
|
||||
if (signal_data->num_local_numbers >= SNGISDN_NUM_LOCAL_NUMBERS) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "%s: Maximum number of local-numbers exceeded (max:%d)\n", span->name, SNGISDN_NUM_LOCAL_NUMBERS);
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
signal_data->local_numbers[signal_data->num_local_numbers++] = ftdm_strdup(val);
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
ftdm_status_t parse_switchtype(const char* switch_name, ftdm_span_t *span)
|
||||
{
|
||||
unsigned i;
|
||||
|
@ -253,6 +267,10 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_
|
|||
ftdm_span_set_bearer_capability(val, &span->default_caller_data.bearer_capability);
|
||||
} else if (!strcasecmp(var, "outbound-bearer_layer1")) {
|
||||
ftdm_span_set_bearer_layer1(val, &span->default_caller_data.bearer_layer1);
|
||||
} else if (!strcasecmp(var, "local-number")) {
|
||||
if (add_local_number(val, span) != FTDM_SUCCESS) {
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
} else if (!strcasecmp(var, "facility-timeout")) {
|
||||
signal_data->facility_timeout = atoi(val);
|
||||
if (signal_data->facility_timeout < 0) {
|
||||
|
|
|
@ -43,7 +43,7 @@ extern ftdm_status_t cpy_calling_name_from_stack(ftdm_caller_data_t *ftdm, Displ
|
|||
void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
|
||||
{
|
||||
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
|
||||
|
||||
unsigned i;
|
||||
int16_t suId = sngisdn_event->suId;
|
||||
uint32_t suInstId = sngisdn_event->suInstId;
|
||||
uint32_t spInstId = sngisdn_event->spInstId;
|
||||
|
@ -57,7 +57,7 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
|
|||
ftdm_assert(!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE), "State change flag pending\n");
|
||||
|
||||
ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
|
||||
|
||||
|
||||
switch (ftdmchan->state) {
|
||||
case FTDM_CHANNEL_STATE_DOWN: /* Proper state to receive a SETUP */
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INUSE) ||
|
||||
|
@ -80,11 +80,35 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
|
|||
sngisdn_info->suInstId = get_unique_suInstId(suId);
|
||||
sngisdn_info->spInstId = spInstId;
|
||||
|
||||
if (conEvnt->cdPtyNmb.eh.pres && signal_data->num_local_numbers) {
|
||||
uint8_t local_number_matched = 0;
|
||||
for (i = 0 ; i < signal_data->num_local_numbers ; i++) {
|
||||
if (!strcmp(signal_data->local_numbers[i], (char*)conEvnt->cdPtyNmb.nmbDigits.val)) {
|
||||
local_number_matched++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!local_number_matched) {
|
||||
ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received SETUP, but local-number %s does not match - ignoring\n", conEvnt->cdPtyNmb.nmbDigits.val);
|
||||
/* Special case to tell the stack to clear all internal resources about this call. We will no receive any event for this call after sending disconnect request */
|
||||
ftdmchan->caller_data.hangup_cause = IN_CCNORTTODEST;
|
||||
ftdm_sched_timer(signal_data->sched, "delayed_disconnect", 1, sngisdn_delayed_disconnect, (void*) sngisdn_info, NULL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* If this is a glared call that was previously saved, we moved
|
||||
all the info to the current call, so clear the glared saved data */
|
||||
if (sngisdn_info->glare.spInstId == spInstId) {
|
||||
clear_call_glare_data(sngisdn_info);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (ftdmchan->span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
|
||||
if (signal_data->signalling == SNGISDN_SIGNALING_NET) {
|
||||
sngisdn_info->ces = ces;
|
||||
}
|
||||
}
|
||||
|
||||
ftdm_mutex_lock(g_sngisdn_data.ccs[suId].mutex);
|
||||
g_sngisdn_data.ccs[suId].active_suInstIds[sngisdn_info->suInstId] = sngisdn_info;
|
||||
|
@ -92,11 +116,6 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
|
|||
|
||||
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND);
|
||||
|
||||
if (ftdmchan->span->trunk_type == FTDM_TRUNK_BRI_PTMP &&
|
||||
signal_data->signalling == SNGISDN_SIGNALING_NET) {
|
||||
sngisdn_info->ces = ces;
|
||||
}
|
||||
|
||||
/* try to open the channel */
|
||||
if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "Failed to open channel");
|
||||
|
@ -122,14 +141,13 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
|
|||
ftdmchan->caller_data.bearer_layer1 = sngisdn_get_infoTranCap_from_stack(conEvnt->bearCap[0].usrInfoLyr1Prot.val);
|
||||
ftdmchan->caller_data.bearer_capability = sngisdn_get_infoTranCap_from_stack(conEvnt->bearCap[0].infoTranCap.val);
|
||||
}
|
||||
|
||||
|
||||
if (signal_data->switchtype == SNGISDN_SWITCH_NI2) {
|
||||
if (conEvnt->shift11.eh.pres && conEvnt->ni2OctStr.eh.pres) {
|
||||
if (conEvnt->ni2OctStr.str.len == 4 && conEvnt->ni2OctStr.str.val[0] == 0x37) {
|
||||
snprintf(ftdmchan->caller_data.aniII, 5, "%.2d", conEvnt->ni2OctStr.str.val[3]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (signal_data->facility == SNGISDN_OPT_TRUE && conEvnt->facilityStr.eh.pres) {
|
||||
/* Verify whether the Caller Name will come in a subsequent FACILITY message */
|
||||
|
@ -260,6 +278,10 @@ void sngisdn_process_con_cfm (sngisdn_event_data_t *sngisdn_event)
|
|||
case FTDM_CHANNEL_STATE_DIALING:
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_UP);
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
|
||||
case FTDM_CHANNEL_STATE_HANGUP:
|
||||
/* Race condition, we just hung up the call - ignore this message */
|
||||
break;
|
||||
default:
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Processing CONNECT/CONNECT ACK in an invalid state (%s)\n", ftdm_channel_state2str(ftdmchan->state));
|
||||
|
||||
|
@ -274,7 +296,7 @@ void sngisdn_process_con_cfm (sngisdn_event_data_t *sngisdn_event)
|
|||
/* do nothing */
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
|
||||
/* We just hung up an incoming call right after we sent a CONNECT so ignore this message */
|
||||
/* Race condition, We just hung up an incoming call right after we sent a CONNECT - ignore this message */
|
||||
break;
|
||||
default:
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Processing CONNECT/CONNECT ACK in an invalid state (%s)\n", ftdm_channel_state2str(ftdmchan->state));
|
||||
|
@ -923,6 +945,16 @@ void sngisdn_process_sta_cfm (sngisdn_event_data_t *sngisdn_event)
|
|||
break;
|
||||
}
|
||||
break;
|
||||
case 12: /* We received a disconnect indication */
|
||||
switch (ftdmchan->state) {
|
||||
case FTDM_CHANNEL_STATE_TERMINATING:
|
||||
/* We are already waiting for user app to handle the disconnect, do nothing */
|
||||
break;
|
||||
default:
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle incompatible state. remote call state:%d our state:%s\n", call_state, ftdm_channel_state2str(ftdmchan->state));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 22:
|
||||
switch (ftdmchan->state) {
|
||||
case FTDM_CHANNEL_STATE_UP:
|
||||
|
|
|
@ -706,7 +706,7 @@ void sngisdn_rcv_q931_ind(InMngmt *status)
|
|||
ftdm_span_t *ftdmspan;
|
||||
sngisdn_span_data_t *signal_data = g_sngisdn_data.spans[status->t.usta.suId];
|
||||
if (!signal_data) {
|
||||
ftdm_log(FTDM_LOG_INFO, "Received q921 status on unconfigured span (lnkNmb:%d)\n", status->t.usta.suId);
|
||||
ftdm_log(FTDM_LOG_INFO, "Received q931 status on unconfigured span (lnkNmb:%d)\n", status->t.usta.suId);
|
||||
return;
|
||||
}
|
||||
ftdmspan = signal_data->ftdm_span;
|
||||
|
|
|
@ -424,11 +424,15 @@ void sngisdn_delayed_disconnect(void* p_sngisdn_info)
|
|||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
|
||||
|
||||
ftdm_mutex_lock(ftdmchan->mutex);
|
||||
if (ftdmchan->state != FTDM_CHANNEL_STATE_DOWN) {
|
||||
if (ftdmchan->caller_data.hangup_cause == IN_CCNORTTODEST || ftdmchan->state != FTDM_CHANNEL_STATE_DOWN) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Sending delayed DISCONNECT (suId:%d suInstId:%u spInstId:%u)\n",
|
||||
signal_data->cc_id, sngisdn_info->glare.spInstId, sngisdn_info->glare.suInstId);
|
||||
|
||||
sngisdn_snd_disconnect(ftdmchan);
|
||||
if (ftdmchan->caller_data.hangup_cause == IN_CCNORTTODEST) {
|
||||
ftdm_channel_t *close_chan = ftdmchan;
|
||||
ftdm_channel_close(&close_chan);
|
||||
}
|
||||
}
|
||||
|
||||
ftdm_mutex_unlock(ftdmchan->mutex);
|
||||
|
|
Loading…
Reference in New Issue