Merge remote branch 'smgorig/master'

This commit is contained in:
Moises Silva 2010-09-18 22:35:17 -04:00
commit 7d84351de9
26 changed files with 2965 additions and 902 deletions

View File

@ -1404,6 +1404,7 @@ ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session
private_t *tech_pvt = NULL;
switch_channel_t *channel = NULL;
ftdm_iterator_t *iter = NULL;
ftdm_iterator_t *curr = NULL;
const char *var_name = NULL;
const char *var_value = NULL;
uint32_t spanid, chanid;
@ -1515,13 +1516,14 @@ ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session
switch_channel_set_variable_printf(channel, "freetdm_custom_call_data", "%s", channel_caller_data->raw_data);
}
/* Add any channel variable to the dial plan */
iter = ftdm_channel_get_var_iterator(sigmsg->channel);
for ( ; iter; iter = ftdm_iterator_next(iter)) {
ftdm_channel_get_current_var(iter, &var_name, &var_value);
iter = ftdm_channel_get_var_iterator(sigmsg->channel, NULL);
for (curr = iter ; curr; curr = ftdm_iterator_next(curr)) {
ftdm_channel_get_current_var(curr, &var_name, &var_value);
snprintf(name, sizeof(name), FREETDM_VAR_PREFIX "%s", var_name);
switch_channel_set_variable_printf(channel, name, "%s", var_value);
}
ftdm_iterator_free(iter);
switch_channel_set_state(channel, CS_INIT);
if (switch_core_session_thread_launch(session) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error spawning thread\n");
@ -2180,9 +2182,8 @@ static void ftdm_logger(const char *file, const char *func, int line, int level,
if (switch_vasprintf(&data, fmt, ap) != -1) {
switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, (char *)func, line, NULL, level, "%s", data);
free(data);
}
if (data) free(data);
va_end(ap);
}
@ -2371,6 +2372,121 @@ static int add_profile_parameters(switch_xml_t cfg, const char *profname, ftdm_c
return paramindex;
}
static void parse_bri_pri_spans(switch_xml_t cfg, switch_xml_t spans)
{
switch_xml_t myspan, param;
for (myspan = switch_xml_child(spans, "span"); myspan; myspan = myspan->next) {
ftdm_status_t zstatus = FTDM_FAIL;
const char *context = "default";
const char *dialplan = "XML";
ftdm_conf_parameter_t spanparameters[30];
char *id = (char *) switch_xml_attr(myspan, "id");
char *name = (char *) switch_xml_attr(myspan, "name");
char *configname = (char *) switch_xml_attr(myspan, "cfgprofile");
ftdm_span_t *span = NULL;
uint32_t span_id = 0;
unsigned paramindex = 0;
if (!name && !id) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "sangoma isdn span missing required attribute 'id' or 'name', skipping ...\n");
continue;
}
if (name) {
zstatus = ftdm_span_find_by_name(name, &span);
} else {
if (switch_is_number(id)) {
span_id = atoi(id);
zstatus = ftdm_span_find(span_id, &span);
}
if (zstatus != FTDM_SUCCESS) {
zstatus = ftdm_span_find_by_name(id, &span);
}
}
if (zstatus != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_ERROR, "Error finding FreeTDM span id:%s name:%s\n", switch_str_nil(id), switch_str_nil(name));
continue;
}
if (!span_id) {
span_id = ftdm_span_get_id(span);
}
memset(spanparameters, 0, sizeof(spanparameters));
paramindex = 0;
if (configname) {
paramindex = add_profile_parameters(cfg, configname, spanparameters, ftdm_array_len(spanparameters));
if (paramindex) {
ftdm_log(FTDM_LOG_DEBUG, "Added %d parameters from profile %s for span %d\n", paramindex, configname, span_id);
}
}
/* some defaults first */
SPAN_CONFIG[span_id].limit_backend = "hash";
SPAN_CONFIG[span_id].limit_reset_event = FTDM_LIMIT_RESET_ON_TIMEOUT;
for (param = switch_xml_child(myspan, "param"); param; param = param->next) {
char *var = (char *) switch_xml_attr_soft(param, "name");
char *val = (char *) switch_xml_attr_soft(param, "value");
if (ftdm_array_len(spanparameters) == paramindex) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Too many parameters for ss7 span, ignoring any parameter after %s\n", var);
break;
}
if (!strcasecmp(var, "context")) {
context = val;
} else if (!strcasecmp(var, "dialplan")) {
dialplan = val;
} else if (!strcasecmp(var, "call_limit_backend")) {
SPAN_CONFIG[span_id].limit_backend = val;
ftdm_log(FTDM_LOG_DEBUG, "Using limit backend %s for span %d\n", SPAN_CONFIG[span_id].limit_backend, span_id);
} else if (!strcasecmp(var, "call_limit_rate")) {
int calls;
int seconds;
if (sscanf(val, "%d/%d", &calls, &seconds) != 2) {
ftdm_log(FTDM_LOG_ERROR, "Invalid %s parameter, format example: 3/1 for 3 calls per second\n", var);
} else {
if (calls < 1 || seconds < 1) {
ftdm_log(FTDM_LOG_ERROR, "Invalid %s parameter value, minimum call limit must be 1 per second\n", var);
} else {
SPAN_CONFIG[span_id].limit_calls = calls;
SPAN_CONFIG[span_id].limit_seconds = seconds;
}
}
} else if (!strcasecmp(var, "call_limit_reset_event")) {
if (!strcasecmp(val, "answer")) {
SPAN_CONFIG[span_id].limit_reset_event = FTDM_LIMIT_RESET_ON_ANSWER;
} else {
ftdm_log(FTDM_LOG_ERROR, "Invalid %s parameter value, only accepted event is 'answer'\n", var);
}
} else {
spanparameters[paramindex].var = var;
spanparameters[paramindex].val = val;
paramindex++;
}
}
if (ftdm_configure_span_signaling(span,
"sangoma_isdn",
on_clear_channel_signal,
spanparameters) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_ERROR, "Error configuring Sangoma ISDN FreeTDM span %d\n", span_id);
continue;
}
SPAN_CONFIG[span_id].span = span;
switch_copy_string(SPAN_CONFIG[span_id].context, context, sizeof(SPAN_CONFIG[span_id].context));
switch_copy_string(SPAN_CONFIG[span_id].dialplan, dialplan, sizeof(SPAN_CONFIG[span_id].dialplan));
switch_copy_string(SPAN_CONFIG[span_id].type, "Sangoma (ISDN)", sizeof(SPAN_CONFIG[span_id].type));
ftdm_log(FTDM_LOG_DEBUG, "Configured Sangoma ISDN FreeTDM span %d\n", span_id);
ftdm_span_start(span);
}
}
static switch_status_t load_config(void)
{
const char *cf = "freetdm.conf";
@ -2381,7 +2497,8 @@ static switch_status_t load_config(void)
unsigned boosti = 0;
unsigned int i = 0;
ftdm_channel_t *fchan = NULL;
unsigned int chancount = 0;
ftdm_iterator_t *chaniter = NULL;
ftdm_iterator_t *curr = NULL;
memset(boost_spans, 0, sizeof(boost_spans));
memset(&globals, 0, sizeof(globals));
@ -2410,116 +2527,12 @@ static switch_status_t load_config(void)
}
}
if ((spans = switch_xml_child(cfg, "sangoma_pri_spans")) || (spans = switch_xml_child(cfg, "sangoma_bri_spans"))) {
for (myspan = switch_xml_child(spans, "span"); myspan; myspan = myspan->next) {
ftdm_status_t zstatus = FTDM_FAIL;
const char *context = "default";
const char *dialplan = "XML";
ftdm_conf_parameter_t spanparameters[30];
char *id = (char *) switch_xml_attr(myspan, "id");
char *name = (char *) switch_xml_attr(myspan, "name");
char *configname = (char *) switch_xml_attr(myspan, "cfgprofile");
ftdm_span_t *span = NULL;
uint32_t span_id = 0;
unsigned paramindex = 0;
if ((spans = switch_xml_child(cfg, "sangoma_pri_spans"))) {
parse_bri_pri_spans(cfg, spans);
}
if (!name && !id) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "sangoma isdn span missing required attribute 'id' or 'name', skipping ...\n");
continue;
}
if (name) {
zstatus = ftdm_span_find_by_name(name, &span);
} else {
if (switch_is_number(id)) {
span_id = atoi(id);
zstatus = ftdm_span_find(span_id, &span);
}
if (zstatus != FTDM_SUCCESS) {
zstatus = ftdm_span_find_by_name(id, &span);
}
}
if (zstatus != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_ERROR, "Error finding FreeTDM span id:%s name:%s\n", switch_str_nil(id), switch_str_nil(name));
continue;
}
if (!span_id) {
span_id = ftdm_span_get_id(span);
}
memset(spanparameters, 0, sizeof(spanparameters));
paramindex = 0;
if (configname) {
paramindex = add_profile_parameters(cfg, configname, spanparameters, ftdm_array_len(spanparameters));
if (paramindex) {
ftdm_log(FTDM_LOG_DEBUG, "Added %d parameters from profile %s for span %d\n", paramindex, configname, span_id);
}
}
/* some defaults first */
SPAN_CONFIG[span_id].limit_backend = "hash";
SPAN_CONFIG[span_id].limit_reset_event = FTDM_LIMIT_RESET_ON_TIMEOUT;
for (param = switch_xml_child(myspan, "param"); param; param = param->next) {
char *var = (char *) switch_xml_attr_soft(param, "name");
char *val = (char *) switch_xml_attr_soft(param, "value");
if (ftdm_array_len(spanparameters) == paramindex) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Too many parameters for ss7 span, ignoring any parameter after %s\n", var);
break;
}
if (!strcasecmp(var, "context")) {
context = val;
} else if (!strcasecmp(var, "dialplan")) {
dialplan = val;
} else if (!strcasecmp(var, "call_limit_backend")) {
SPAN_CONFIG[span_id].limit_backend = val;
ftdm_log(FTDM_LOG_DEBUG, "Using limit backend %s for span %d\n", SPAN_CONFIG[span_id].limit_backend, span_id);
} else if (!strcasecmp(var, "call_limit_rate")) {
int calls;
int seconds;
if (sscanf(val, "%d/%d", &calls, &seconds) != 2) {
ftdm_log(FTDM_LOG_ERROR, "Invalid %s parameter, format example: 3/1 for 3 calls per second\n", var);
} else {
if (calls < 1 || seconds < 1) {
ftdm_log(FTDM_LOG_ERROR, "Invalid %s parameter value, minimum call limit must be 1 per second\n", var);
} else {
SPAN_CONFIG[span_id].limit_calls = calls;
SPAN_CONFIG[span_id].limit_seconds = seconds;
}
}
} else if (!strcasecmp(var, "call_limit_reset_event")) {
if (!strcasecmp(val, "answer")) {
SPAN_CONFIG[span_id].limit_reset_event = FTDM_LIMIT_RESET_ON_ANSWER;
} else {
ftdm_log(FTDM_LOG_ERROR, "Invalid %s parameter value, only accepted event is 'answer'\n", var);
}
} else {
spanparameters[paramindex].var = var;
spanparameters[paramindex].val = val;
paramindex++;
}
}
if (ftdm_configure_span_signaling(span,
"sangoma_isdn",
on_clear_channel_signal,
spanparameters) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_ERROR, "Error configuring Sangoma ISDN FreeTDM span %d\n", span_id);
continue;
}
SPAN_CONFIG[span_id].span = span;
switch_copy_string(SPAN_CONFIG[span_id].context, context, sizeof(SPAN_CONFIG[span_id].context));
switch_copy_string(SPAN_CONFIG[span_id].dialplan, dialplan, sizeof(SPAN_CONFIG[span_id].dialplan));
switch_copy_string(SPAN_CONFIG[span_id].type, "Sangoma (ISDN)", sizeof(SPAN_CONFIG[span_id].type));
ftdm_log(FTDM_LOG_DEBUG, "Configured Sangoma ISDN FreeTDM span %d\n", span_id);
ftdm_span_start(span);
}
if ((spans = switch_xml_child(cfg, "sangoma_bri_spans"))) {
parse_bri_pri_spans(cfg, spans);
}
switch_core_hash_init(&globals.ss7_configs, module_pool);
@ -2769,11 +2782,13 @@ static switch_status_t load_config(void)
switch_set_string(SPAN_CONFIG[span_id].dialplan, dialplan);
SPAN_CONFIG[span_id].analog_options = analog_options | globals.analog_options;
chancount = ftdm_span_get_chan_count(span);
for (i = 1; i <= chancount; i++) {
fchan = ftdm_span_get_channel(span, i);
chaniter = ftdm_span_get_chan_iterator(span, NULL);
curr = chaniter;
for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
fchan = ftdm_iterator_current(curr);
ftdm_channel_set_private(fchan, &SPAN_CONFIG[span_id].pvts[i]);
}
ftdm_iterator_free(chaniter);
if (dial_regex) {
switch_set_string(SPAN_CONFIG[span_id].dial_regex, dial_regex);
@ -3581,6 +3596,8 @@ SWITCH_STANDARD_API(ft_function)
{
char *mycmd = NULL, *argv[10] = { 0 };
int argc = 0;
ftdm_iterator_t *chaniter = NULL;
ftdm_iterator_t *curr = NULL;
if (!zstr(cmd) && (mycmd = strdup(cmd))) {
argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
@ -3626,11 +3643,11 @@ SWITCH_STANDARD_API(ft_function)
dump_chan_xml(span, chan_id, stream);
}
} else {
uint32_t j;
uint32_t ccount = ftdm_span_get_chan_count(span);
for (j = 1; j <= ccount; j++) {
dump_chan_xml(span, j, stream);
chaniter = ftdm_span_get_chan_iterator(span, NULL);
for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
dump_chan_xml(span, ftdm_channel_get_id(ftdm_iterator_current(curr)), stream);
}
ftdm_iterator_free(chaniter);
}
}
@ -3646,12 +3663,12 @@ SWITCH_STANDARD_API(ft_function)
dump_chan(span, chan_id, stream);
}
} else {
uint32_t j;
uint32_t ccount = ftdm_span_get_chan_count(span);
stream->write_function(stream, "+OK\n");
for (j = 1; j <= ccount; j++) {
dump_chan(span, j, stream);
chaniter = ftdm_span_get_chan_iterator(span, NULL);
for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
dump_chan(span, ftdm_channel_get_id(ftdm_iterator_current(curr)), stream);
}
ftdm_iterator_free(chaniter);
}
}

View File

@ -463,6 +463,7 @@ static ftdm_status_t ftdm_span_destroy(ftdm_span_t *span)
status = FTDM_FAIL;
}
ftdm_safe_free(span->type);
ftdm_safe_free(span->name);
ftdm_safe_free(span->dtmf_hangup);
}
@ -536,7 +537,7 @@ static void ftdm_span_add(ftdm_span_t *span)
} else {
globals.spans = span;
}
hashtable_insert(globals.span_hash, (void *)span->name, span, HASHTABLE_FLAG_NONE);
hashtable_insert(globals.span_hash, (void *)span->name, span, HASHTABLE_FLAG_FREE_VALUE);
ftdm_mutex_unlock(globals.span_mutex);
}
@ -3524,16 +3525,56 @@ done:
return var;
}
FT_DECLARE(ftdm_iterator_t *) ftdm_channel_get_var_iterator(const ftdm_channel_t *ftdmchan)
static ftdm_iterator_t *get_iterator(ftdm_iterator_type_t type, ftdm_iterator_t *iter)
{
ftdm_hash_iterator_t *iter = NULL;
int allocated = 0;
if (iter) {
if (iter->type != type) {
ftdm_log(FTDM_LOG_ERROR, "Cannot switch iterator types\n");
return NULL;
}
allocated = iter->allocated;
memset(iter, 0, sizeof(*iter));
iter->type = type;
iter->allocated = allocated;
return iter;
}
iter = ftdm_calloc(1, sizeof(*iter));
if (!iter) {
return NULL;
}
iter->type = type;
iter->allocated = 1;
return iter;
}
FT_DECLARE(ftdm_iterator_t *) ftdm_channel_get_var_iterator(const ftdm_channel_t *ftdmchan, ftdm_iterator_t *iter)
{
ftdm_hash_iterator_t *hashiter = NULL;
ftdm_channel_lock(ftdmchan);
iter = ftdmchan->variable_hash == NULL ? NULL : hashtable_first(ftdmchan->variable_hash);
hashiter = ftdmchan->variable_hash == NULL ? NULL : hashtable_first(ftdmchan->variable_hash);
ftdm_channel_unlock(ftdmchan);
if (hashiter == NULL) {
return NULL;
}
if (!(iter = get_iterator(FTDM_ITERATOR_VARS, iter))) {
return NULL;
}
iter->pvt.hashiter = hashiter;
return iter;
}
FT_DECLARE(ftdm_iterator_t *) ftdm_span_get_chan_iterator(const ftdm_span_t *span, ftdm_iterator_t *iter)
{
if (!(iter = get_iterator(FTDM_ITERATOR_CHANS, iter))) {
return NULL;
}
iter->pvt.chaniter.index = 1;
iter->pvt.chaniter.span = span;
return iter;
}
@ -3545,11 +3586,9 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_get_current_var(ftdm_iterator_t *iter, co
*var_name = NULL;
*var_val = NULL;
if (!iter) {
return FTDM_FAIL;
}
ftdm_assert_return(iter && (iter->type == FTDM_ITERATOR_VARS) && iter->pvt.hashiter, FTDM_FAIL, "Cannot get variable from invalid iterator!\n");
hashtable_this(iter, &key, NULL, &val);
hashtable_this(iter->pvt.hashiter, &key, NULL, &val);
*var_name = key;
*var_val = val;
@ -3559,10 +3598,73 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_get_current_var(ftdm_iterator_t *iter, co
FT_DECLARE(ftdm_iterator_t *) ftdm_iterator_next(ftdm_iterator_t *iter)
{
if (!iter) {
return NULL;
ftdm_assert_return(iter && iter->type, NULL, "Invalid iterator\n");
switch (iter->type) {
case FTDM_ITERATOR_VARS:
if (!iter->pvt.hashiter) {
return NULL;
}
iter->pvt.hashiter = hashtable_next(iter->pvt.hashiter);
if (!iter->pvt.hashiter) {
return NULL;
}
return iter;
case FTDM_ITERATOR_CHANS:
ftdm_assert_return(iter->pvt.chaniter.index, NULL, "channel iterator index cannot be zero!\n");
if (iter->pvt.chaniter.index == iter->pvt.chaniter.span->chan_count) {
return NULL;
}
iter->pvt.chaniter.index++;
return iter;
default:
break;
}
return hashtable_next(iter);
ftdm_assert_return(0, NULL, "Unknown iterator type\n");
return NULL;
}
FT_DECLARE(void *) ftdm_iterator_current(ftdm_iterator_t *iter)
{
const void *key = NULL;
void *val = NULL;
ftdm_assert_return(iter && iter->type, NULL, "Invalid iterator\n");
switch (iter->type) {
case FTDM_ITERATOR_VARS:
hashtable_this(iter->pvt.hashiter, &key, NULL, &val);
/* I decided to return the key instead of the value since the value can be retrieved using the key */
return (void *)key;
case FTDM_ITERATOR_CHANS:
ftdm_assert_return(iter->pvt.chaniter.index, NULL, "channel iterator index cannot be zero!\n");
ftdm_assert_return(iter->pvt.chaniter.index <= iter->pvt.chaniter.span->chan_count, NULL, "channel iterator index bigger than span chan count!\n");
return iter->pvt.chaniter.span->channels[iter->pvt.chaniter.index];
default:
break;
}
ftdm_assert_return(0, NULL, "Unknown iterator type\n");
return NULL;
}
FT_DECLARE(ftdm_status_t) ftdm_iterator_free(ftdm_iterator_t *iter)
{
/* it's valid to pass a NULL iterator, do not return failure */
if (!iter) {
return FTDM_SUCCESS;
}
if (!iter->allocated) {
memset(iter, 0, sizeof(*iter));
return FTDM_SUCCESS;
}
ftdm_assert_return(iter->type, FTDM_FAIL, "Cannot free invalid iterator\n");
ftdm_safe_free(iter);
return FTDM_SUCCESS;
}
static struct {
@ -4744,11 +4846,13 @@ FT_DECLARE(ftdm_status_t) ftdm_global_destroy(void)
ftdm_mutex_lock(globals.mutex);
hashtable_destroy(globals.interface_hash);
hashtable_destroy(globals.module_hash);
hashtable_destroy(globals.module_hash);
hashtable_destroy(globals.span_hash);
hashtable_destroy(globals.group_hash);
ftdm_mutex_unlock(globals.mutex);
ftdm_mutex_destroy(&globals.mutex);
ftdm_mutex_destroy(&globals.span_mutex);
ftdm_mutex_destroy(&globals.group_mutex);
memset(&globals, 0, sizeof(globals));
return FTDM_SUCCESS;

View File

@ -189,7 +189,8 @@ ftdm_state_map_t sangoma_isdn_state_map = {
ZSD_OUTBOUND,
ZSM_UNACCEPTABLE,
{FTDM_CHANNEL_STATE_DIALING, FTDM_END},
{FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_DOWN, FTDM_END}
{FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS,
FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_DOWN, FTDM_END}
},
{
ZSD_OUTBOUND,
@ -471,10 +472,7 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan)
case FTDM_CHANNEL_STATE_RING: /* incoming call request */
{
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Sending incoming call from %s to %s to FTDM core\n", ftdmchan->caller_data.ani.digits, ftdmchan->caller_data.dnis.digits);
ftdm_channel_add_var(ftdmchan, "isdn_specific_var", "1");
ftdm_channel_add_var(ftdmchan, "isdn_crap", "morecrap");
ftdm_channel_add_var(ftdmchan, "isdn_stuff", "s");
ftdm_channel_add_var(ftdmchan, "isdn_d", "asdsadasdasdsad");
/* we have enough information to inform FTDM of the call*/
sigev.event_id = FTDM_SIGEVENT_START;
ftdm_span_send_signal(ftdmchan->span, &sigev);
@ -558,6 +556,9 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan)
/* We are hangup local call because there was a glare, we are waiting for a
RELEASE on this call, before we can process the saved call */
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Waiting for RELEASE on hungup glared call\n");
} else if (sngisdn_test_flag(sngisdn_info, FLAG_SEND_DISC)) {
/* Remote side sent a PROGRESS message, but cause indicates disconnect or T310 expired*/
sngisdn_snd_disconnect(ftdmchan);
} else {
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Hanging up call upon local request!\n");
@ -568,16 +569,15 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan)
if (ftdmchan->last_state == FTDM_CHANNEL_STATE_RING ||
ftdmchan->last_state == FTDM_CHANNEL_STATE_DIALING) {
sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT);
sngisdn_snd_release(ftdmchan, 0);
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP)) {
sng_isdn_set_avail_rate(ftdmchan->span, SNGISDN_AVAIL_DOWN);
}
sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT);
sngisdn_snd_release(ftdmchan, 0);
} else {
sngisdn_snd_disconnect(ftdmchan);
}
}
/* now go to the HANGUP complete state */
@ -691,7 +691,7 @@ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(ftdm_sangoma_isdn_outgoing_call)
return status;
}
static FIO_CHANNEL_GET_SIG_STATUS_FUNCTION(ftdm_sangoma_isdn_get_sig_status)
static FIO_CHANNEL_GET_SIG_STATUS_FUNCTION(ftdm_sangoma_isdn_get_chan_sig_status)
{
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP)) {
*status = FTDM_SIG_STATE_UP;
@ -702,17 +702,34 @@ static FIO_CHANNEL_GET_SIG_STATUS_FUNCTION(ftdm_sangoma_isdn_get_sig_status)
return FTDM_SUCCESS;
}
static FIO_CHANNEL_SET_SIG_STATUS_FUNCTION(ftdm_sangoma_isdn_set_sig_status)
static FIO_CHANNEL_SET_SIG_STATUS_FUNCTION(ftdm_sangoma_isdn_set_chan_sig_status)
{
ftdm_log(FTDM_LOG_ERROR,"Cannot set channel status in this module\n");
return FTDM_NOTIMPL;
}
static FIO_SPAN_GET_SIG_STATUS_FUNCTION(ftdm_sangoma_isdn_get_span_sig_status)
{
if (ftdm_test_flag(span->channels[1], FTDM_CHANNEL_SIG_UP)) {
*status = FTDM_SIG_STATE_UP;
} else {
*status = FTDM_SIG_STATE_DOWN;
}
return FTDM_SUCCESS;
}
static FIO_SPAN_SET_SIG_STATUS_FUNCTION(ftdm_sangoma_isdn_set_span_sig_status)
{
ftdm_log(FTDM_LOG_ERROR,"Cannot set span status in this module\n");
return FTDM_NOTIMPL;
}
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_activate(span) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_CRIT, "Failed to activate span %s\n", span->name);
if (sng_isdn_stack_start(span) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_CRIT, "Failed to start span %s\n", span->name);
return FTDM_FAIL;
}
/* clear the monitor thread stop flag */
@ -731,7 +748,8 @@ static ftdm_status_t ftdm_sangoma_isdn_start(ftdm_span_t *span)
static ftdm_status_t ftdm_sangoma_isdn_stop(ftdm_span_t *span)
{
unsigned i;
ftdm_iterator_t *chaniter = NULL;
ftdm_iterator_t *curr = NULL;
ftdm_log(FTDM_LOG_INFO, "Stopping span %s\n", span->name);
/* throw the STOP_THREAD flag to signal monitor thread stop */
@ -743,11 +761,19 @@ static ftdm_status_t ftdm_sangoma_isdn_stop(ftdm_span_t *span)
ftdm_sleep(10);
}
/* FIXME: deconfigure any links, attached to this span */
/* TODO: Use Moy's channel Iterator when its implemented */
for (i=1;i<=span->chan_count;i++) {
ftdm_safe_free(span->channels[i]->call_data);
if (sng_isdn_stack_stop(span) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_CRIT, "Failed to stop span %s\n", span->name);
}
chaniter = ftdm_span_get_chan_iterator(span, NULL);
for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
ftdm_safe_free(((ftdm_channel_t*)ftdm_iterator_current(curr))->call_data);
((ftdm_channel_t*)ftdm_iterator_current(curr))->call_data = NULL;
}
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_safe_free(span->signal_data);
ftdm_log(FTDM_LOG_DEBUG, "Finished stopping span %s\n", span->name);
@ -757,6 +783,9 @@ static ftdm_status_t ftdm_sangoma_isdn_stop(ftdm_span_t *span)
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;
ftdm_log(FTDM_LOG_INFO, "Configuring ftmod_sangoma_isdn span = %s\n", span->name);
@ -764,13 +793,15 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_isdn_span_config)
span_data = ftdm_calloc(1, sizeof(sngisdn_span_data_t));
span_data->ftdm_span = span;
span->signal_data = span_data;
unsigned i;
for (i=1;i <= span->chan_count; i++) {
chaniter = ftdm_span_get_chan_iterator(span, NULL);
for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
sngisdn_chan_data_t *chan_data = ftdm_calloc(1, sizeof(sngisdn_chan_data_t));
chan_data->ftdmchan = span->channels[i];
span->channels[i]->call_data = chan_data;
chan_data->ftdmchan = ((ftdm_channel_t*)ftdm_iterator_current(curr));
((ftdm_channel_t*)ftdm_iterator_current(curr))->call_data = chan_data;
}
ftdm_iterator_free(chaniter);
if (ftmod_isdn_parse_cfg(ftdm_parameters, span) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_ERROR, "Failed to parse configuration\n");
@ -789,8 +820,10 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_isdn_span_config)
span->outgoing_call = ftdm_sangoma_isdn_outgoing_call;
span->channel_request = NULL;
span->signal_cb = sig_cb;
span->get_channel_sig_status = ftdm_sangoma_isdn_get_sig_status;
span->set_channel_sig_status = ftdm_sangoma_isdn_set_sig_status;
span->get_channel_sig_status = ftdm_sangoma_isdn_get_chan_sig_status;
span->set_channel_sig_status = ftdm_sangoma_isdn_set_chan_sig_status;
span->get_span_sig_status = ftdm_sangoma_isdn_get_span_sig_status;
span->set_span_sig_status = ftdm_sangoma_isdn_set_span_sig_status;
span->state_map = &sangoma_isdn_state_map;
ftdm_set_flag(span, FTDM_SPAN_USE_CHAN_QUEUE);
ftdm_set_flag(span, FTDM_SPAN_USE_SIGNALS_QUEUE);
@ -852,7 +885,7 @@ static FIO_SIG_LOAD_FUNCTION(ftdm_sangoma_isdn_init)
for(i=1;i<=MAX_VARIANTS;i++) {
ftdm_mutex_create(&g_sngisdn_data.ccs[i].mutex);
}
/* initalize sng_isdn library */
sng_isdn_init(&g_sngisdn_event_interface);
return FTDM_SUCCESS;
@ -920,16 +953,35 @@ static FIO_API_FUNCTION(ftdm_sangoma_isdn_api)
if (!strcasecmp(argv[0], "l1_stats")) {
ftdm_span_t *span;
if (argc < 2) {
ftdm_log(FTDM_LOG_ERROR, "Usage: ftdm sangoma_isdn l1_stats <span name>\n");
stream->write_function(stream, "Usage: ftdm sangoma_isdn l1_stats <span name>\n");
status = FTDM_FAIL;
goto done;
}
status = ftdm_span_find_by_name(argv[1], &span);
if (FTDM_SUCCESS != status) {
stream->write_function(stream, "-ERR failed to find span by name %s\n", argv[2]);
stream->write_function(stream, "-ERR failed to find span with name %s\n", argv[1]);
/* Return SUCCESS because we do not want to print the general FTDM usage list */
status = FTDM_SUCCESS;
goto done;
}
/* TODO: implement PHY stats */
sngisdn_print_phy_stats(stream, span);
}
if (!strcasecmp(argv[0], "show_spans")) {
ftdm_span_t *span = NULL;
if (argc == 2) {
status = ftdm_span_find_by_name(argv[1], &span);
if (FTDM_SUCCESS != status) {
stream->write_function(stream, "-ERR failed to find span with name %s\n", argv[1]);
/* Return SUCCESS because we do not want to print the general FTDM usage list */
status = FTDM_SUCCESS;
goto done;
}
sngisdn_print_span(stream, span);
status = FTDM_SUCCESS;
goto done;
}
sngisdn_print_spans(stream);
}
if (!strcasecmp(argv[0], "check_ids")) {
sngisdn_check_free_ids();

View File

@ -68,6 +68,7 @@ typedef enum {
FLAG_GLARE = (1 << 6),
FLAG_DELAYED_REL = (1 << 7),
FLAG_SENT_PROCEED = (1 << 8),
FLAG_SEND_DISC = (1 << 9),
} sngisdn_flag_t;
@ -127,6 +128,13 @@ typedef enum {
SNGISDN_EVENT_RST_IND,
} ftdm_sngisdn_event_id_t;
/* Only timers that can be cancelled are listed here */
#define SNGISDN_NUM_TIMERS 1
/* Increase NUM_TIMERS as number of ftdm_sngisdn_timer_t increases */
typedef enum {
SNGISDN_TIMER_FACILITY = 0,
} ftdm_sngisdn_timer_t;
typedef struct sngisdn_glare_data {
int16_t suId;
uint32_t suInstId;
@ -148,6 +156,7 @@ typedef struct sngisdn_chan_data {
uint8_t globalFlg;
sngisdn_glare_data_t glare;
ftdm_timer_t *timers[SNGISDN_NUM_TIMERS];
} sngisdn_chan_data_t;
/* Span specific data */
@ -165,6 +174,7 @@ typedef struct sngisdn_span_data {
uint8_t overlap_dial;
uint8_t setup_arb;
uint8_t facility;
int8_t facility_timeout;
ftdm_sched_t *sched;
ftdm_queue_t *event_queue;
} sngisdn_span_data_t;
@ -223,8 +233,8 @@ typedef struct sngisdn_cc {
ftdm_trunk_type_t trunktype;
uint32_t last_suInstId;
ftdm_mutex_t *mutex;
sngisdn_chan_data_t *active_spInstIds[MAX_INSTID];
sngisdn_chan_data_t *active_suInstIds[MAX_INSTID];
sngisdn_chan_data_t *active_spInstIds[MAX_INSTID+1];
sngisdn_chan_data_t *active_suInstIds[MAX_INSTID+1];
}sngisdn_cc_t;
/* Global sngisdn data */
@ -233,7 +243,8 @@ typedef struct ftdm_sngisdn_data {
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];
sngisdn_dchan_data_t dchans[MAX_L1_LINKS+1];
sngisdn_span_data_t *spans[MAX_L1_LINKS+1]; /* spans are indexed by link_id */
}ftdm_sngisdn_data_t;
@ -349,12 +360,16 @@ void sngisdn_set_span_sig_status(ftdm_span_t *ftdmspan, ftdm_signaling_status_t
void sngisdn_delayed_release(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);
/* Stack management functions */
ftdm_status_t sng_isdn_stack_cfg(ftdm_span_t *span);
ftdm_status_t sng_isdn_stack_activate(ftdm_span_t *span);
ftdm_status_t sng_isdn_stack_start(ftdm_span_t *span);
ftdm_status_t sng_isdn_stack_stop(ftdm_span_t *span);
void sngisdn_print_phy_stats(ftdm_stream_handle_t *stream, ftdm_span_t *span);
void sngisdn_print_spans(ftdm_stream_handle_t *stream);
void sngisdn_print_span(ftdm_stream_handle_t *stream, ftdm_span_t *span);
#endif /* __FTMOD_SNG_ISDN_H__ */

View File

@ -62,7 +62,8 @@ ftdm_status_t parse_switchtype(const char* switch_name, ftdm_span_t *span)
}
break;
case FTDM_TRUNK_E1:
if (!strcasecmp(switch_name, "euroisdn") || strcasecmp(switch_name, "etsi")) {
if (!strcasecmp(switch_name, "euroisdn") ||
!strcasecmp(switch_name, "etsi")) {
signal_data->switchtype = SNGISDN_SWITCH_EUROISDN;
} else if (!strcasecmp(switch_name, "qsig")) {
signal_data->switchtype = SNGISDN_SWITCH_QSIG;
@ -116,6 +117,8 @@ ftdm_status_t parse_switchtype(const char* switch_name, ftdm_span_t *span)
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\n", span->name, signal_data->cc_id, signal_data->dchan_id, signal_data->span_id);
@ -163,6 +166,7 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_
signal_data->overlap_dial = SNGISDN_OPT_DEFAULT;
signal_data->setup_arb = SNGISDN_OPT_DEFAULT;
signal_data->link_id = span->span_id;
span->default_caller_data.bearer_capability = IN_ITC_SPEECH;
/* Cannot set default bearer_layer1 yet, as we do not know the switchtype */
@ -249,11 +253,16 @@ 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, "facility-timeout")) {
signal_data->facility_timeout = atoi(val);
if (signal_data->facility_timeout < 0) {
signal_data->facility_timeout = 0;
}
} else {
ftdm_log(FTDM_LOG_WARNING, "Ignoring unknown parameter %s\n", ftdm_parameters[paramindex].var);
}
}
signal_data->link_id = span->span_id;
if (signal_data->switchtype == SNGISDN_SWITCH_INVALID) {
ftdm_log(FTDM_LOG_ERROR, "%s: switchtype not specified", span->name);
return FTDM_FAIL;

View File

@ -35,7 +35,6 @@
#include "ftmod_sangoma_isdn.h"
void sngisdn_set_chan_sig_status(ftdm_channel_t *ftdmchan, ftdm_signaling_status_t status);
void sngisdn_set_chan_sig_status(ftdm_channel_t *ftdmchan, ftdm_signaling_status_t status)
@ -53,23 +52,21 @@ void sngisdn_set_chan_sig_status(ftdm_channel_t *ftdmchan, ftdm_signaling_status
return;
}
void sngisdn_set_span_sig_status(ftdm_span_t *span, ftdm_signaling_status_t status)
{
ftdm_iterator_t *chaniter = NULL;
ftdm_iterator_t *curr = NULL;
void sngisdn_set_span_sig_status(ftdm_span_t *ftdmspan, ftdm_signaling_status_t status)
{
unsigned i;
/* TODO: use channel iterator once it is implemented */
for (i=1;i<=ftdmspan->chan_count;i++) {
sngisdn_set_chan_sig_status(ftdmspan->channels[i], status);
chaniter = ftdm_span_get_chan_iterator(span, NULL);
for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
sngisdn_set_chan_sig_status(((ftdm_channel_t*)ftdm_iterator_current(curr)), status);
}
ftdm_iterator_free(chaniter);
return;
}
/* For Emacs:
* Local Variables:
* mode:c

View File

@ -656,8 +656,7 @@ ftdm_status_t sng_isdn_stack_cfg_q931_dlsap(ftdm_span_t *span)
cfg.t.cfg.s.inDLSAP.ctldInt[1] = 1;
}
cfg.t.cfg.s.inDLSAP.numRstInd = 255;
cfg.t.cfg.s.inDLSAP.ackOpt = TRUE;
cfg.t.cfg.s.inDLSAP.numRstInd = 255;
cfg.t.cfg.s.inDLSAP.relOpt = TRUE;
#ifdef ISDN_SRV
cfg.t.cfg.s.inDLSAP.bcas = FALSE;
@ -666,16 +665,19 @@ ftdm_status_t sng_isdn_stack_cfg_q931_dlsap(ftdm_span_t *span)
#endif /* ISDN_SRV */
if (signal_data->signalling == SNGISDN_SIGNALING_NET) {
cfg.t.cfg.s.inDLSAP.ackOpt = TRUE;
cfg.t.cfg.s.inDLSAP.intType = NETWORK;
cfg.t.cfg.s.inDLSAP.clrGlr = FALSE; /* in case of glare, do not clear local call */
cfg.t.cfg.s.inDLSAP.statEnqOpt = TRUE;
if (span->trunk_type == FTDM_TRUNK_BRI ||
span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
if (signal_data->switchtype == SNGISDN_SWITCH_EUROISDN ||
signal_data->switchtype == SNGISDN_SWITCH_INSNET) {
cfg.t.cfg.s.inDLSAP.rstOpt = FALSE;
} else {
cfg.t.cfg.s.inDLSAP.rstOpt = TRUE;
}
} else {
cfg.t.cfg.s.inDLSAP.ackOpt = FALSE;
cfg.t.cfg.s.inDLSAP.intType = USER;
cfg.t.cfg.s.inDLSAP.clrGlr = TRUE; /* in case of glare, clear local call */
cfg.t.cfg.s.inDLSAP.statEnqOpt = FALSE;

View File

@ -38,8 +38,8 @@
void stack_resp_hdr_init(Header *hdr);
ftdm_status_t sng_isdn_activate_phy(ftdm_span_t *span);
ftdm_status_t sng_isdn_activate_q921(ftdm_span_t *span);
ftdm_status_t sng_isdn_activate_q931(ftdm_span_t *span);
ftdm_status_t sng_isdn_deactivate_phy(ftdm_span_t *span);
ftdm_status_t sng_isdn_activate_cc(ftdm_span_t *span);
ftdm_status_t sng_isdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t trace_opt);
@ -52,14 +52,23 @@ extern ftdm_sngisdn_data_t g_sngisdn_data;
ftdm_status_t sng_isdn_stack_stop(ftdm_span_t *span);
ftdm_status_t sng_isdn_stack_activate(ftdm_span_t *span)
ftdm_status_t sng_isdn_stack_start(ftdm_span_t *span)
{
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
if (sng_isdn_activate_q921(span) != FTDM_SUCCESS) {
if (sng_isdn_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;
}
/* Try to find an alternative for this */
/* LAPD will call LdUiDatBndCfm before it received a LdLiMacBndCfm from L1,
so we need to give some time before activating q931, as q931 will send a
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;
@ -70,7 +79,8 @@ ftdm_status_t sng_isdn_stack_activate(ftdm_span_t *span)
ftdm_log(FTDM_LOG_DEBUG, "%s:Stack CC activated\n", span->name);
}
if (sng_isdn_activate_q931(span) != FTDM_SUCCESS) {
if (sng_isdn_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;
}
@ -80,50 +90,72 @@ ftdm_status_t sng_isdn_stack_activate(ftdm_span_t *span)
return FTDM_SUCCESS;
}
ftdm_status_t sng_isdn_stack_stop(ftdm_span_t *span)
ftdm_status_t sng_isdn_stack_stop(ftdm_span_t *span)
{
/* Stop L1 first, so we do not receive any more frames */
if (sng_isdn_deactivate_phy(span) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_CRIT, "%s:Failed to deactivate stack phy\n", span->name);
return FTDM_FAIL;
}
if (sng_isdn_cntrl_q931(span, AUBND_DIS, SAELMNT) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_CRIT, "%s:Failed to deactivate stack q931\n", span->name);
return FTDM_FAIL;
}
if (sng_isdn_cntrl_q921(span, AUBND_DIS, SAELMNT) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_CRIT, "%s:Failed to deactivate stack q921\n", span->name);
return FTDM_FAIL;
}
ftdm_log(FTDM_LOG_INFO, "%s:Signalling stopped\n", span->name);
return FTDM_SUCCESS;
}
ftdm_status_t sng_isdn_activate_phy(ftdm_span_t *span)
{
/* There is no need to start phy, as it will Q921 will send a activate request to phy when it starts */
return FTDM_SUCCESS;
}
ftdm_status_t sng_isdn_deactivate_phy(ftdm_span_t *span)
{
L1Mngmt cntrl;
Pst pst;
Pst pst;
ftdm_log(FTDM_LOG_ERROR, "%s:PHY control not implemented\n", span->name);
return FTDM_SUCCESS;
/* TODO: phy cntrl not implemented yet */
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
sng_isdn_phy_cntrl(&pst, &cntrl);
/* initalize the post structure */
stack_pst_init(&pst);
/* insert the destination Entity */
pst.dstEnt = ENTL1;
/* initalize the control structure */
memset(&cntrl, 0, sizeof(cntrl));
/* initalize the control header */
stack_hdr_init(&cntrl.hdr);
cntrl.hdr.msgType = TCNTRL; /* configuration */
cntrl.hdr.entId.ent = ENTL1; /* entity */
cntrl.hdr.entId.inst = S_INST; /* instance */
cntrl.hdr.elmId.elmnt = STTSAP; /* SAP Specific cntrl */
cntrl.t.cntrl.action = AUBND_DIS;
cntrl.t.cntrl.subAction = SAELMNT;
cntrl.t.cntrl.sapId = signal_data->link_id;
if (sng_isdn_phy_cntrl(&pst, &cntrl)) {
return FTDM_FAIL;
}
return FTDM_SUCCESS;
}
ftdm_status_t sng_isdn_activate_q921(ftdm_span_t *span)
{
ftdm_status_t status;
status = sng_isdn_cntrl_q921(span, ABND_ENA, NOTUSED);
/* Try to find an alternative for this */
/* LAPD will call LdUiDatBndCfm before it received a LdLiMacBndCfm from L1,
so we need to give some time before activating q931, as q931 will send a
LdUiDatConReq when activated, and this requires the Mac SAP to be already
bound first */
if (status == FTDM_SUCCESS) {
ftdm_sleep(500);
}
return status;
}
ftdm_status_t sng_isdn_activate_q931(ftdm_span_t *span)
{
/* TODO: remove this function later, just call sng_isdn_cntrl_q931 directly */
return sng_isdn_cntrl_q931(span, ABND_ENA, SAELMNT);
}
ftdm_status_t sng_isdn_activate_cc(ftdm_span_t *span)
{
CcMngmt cntrl;;
@ -167,7 +199,7 @@ ftdm_status_t sng_isdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t tra
ftdm_log(FTDM_LOG_INFO, "s%d Disabling q921 trace\n", signal_data->link_id);
sngisdn_clear_trace_flag(signal_data, SNGISDN_TRACE_Q921);
if (sng_isdn_cntrl_q921(span, ADISIMM, SAELMNT) != FTDM_SUCCESS) {
if (sng_isdn_cntrl_q921(span, ADISIMM, SATRC) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_ERROR, "s%d Failed to disable q921 trace\n");
}
}

View File

@ -78,14 +78,13 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
}
sngisdn_info->suInstId = get_unique_suInstId(suId);
sngisdn_info->spInstId = spInstId;
sngisdn_info->spInstId = spInstId;
/* 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);
}
}
ftdm_mutex_lock(g_sngisdn_data.ccs[suId].mutex);
g_sngisdn_data.ccs[suId].active_suInstIds[sngisdn_info->suInstId] = sngisdn_info;
@ -105,7 +104,15 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_TEMPORARY_FAILURE;
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_CANCEL);
break;
}
}
#if 0
/* Export ftdmchan variables here if we need to */
ftdm_channel_add_var(ftdmchan, "isdn_specific_var", "1");
ftdm_channel_add_var(ftdmchan, "isdn_crap", "morecrap");
ftdm_channel_add_var(ftdmchan, "isdn_stuff", "s");
ftdm_channel_add_var(ftdmchan, "isdn_d", "asdsadasdasdsad");
#endif
/* Fill in call information */
cpy_calling_num_from_stack(&ftdmchan->caller_data, &conEvnt->cgPtyNmb);
cpy_called_num_from_stack(&ftdmchan->caller_data, &conEvnt->cdPtyNmb);
@ -142,6 +149,10 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
if (ret_val == 1) {
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Expecting Caller name in FACILITY\n");
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_GET_CALLERID);
/* Launch timer in case we never get a FACILITY msg */
if (signal_data->facility_timeout) {
ftdm_sched_timer(signal_data->sched, "facility_timeout", signal_data->facility_timeout, sngisdn_facility_timeout, (void*) sngisdn_info, &sngisdn_info->timers[SNGISDN_TIMER_FACILITY]);
}
break;
} else if (ret_val == 0) {
strcpy(ftdmchan->caller_data.cid_name, retrieved_str);
@ -263,6 +274,9 @@ void sngisdn_process_con_cfm (sngisdn_event_data_t *sngisdn_event)
/* This is the only valid state we should get a CONNECT ACK on */
/* 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 */
break;
default:
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Processing CONNECT/CONNECT ACK in an invalid state (%s)\n", ftdm_channel_state2str(ftdmchan->state));
@ -289,6 +303,8 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event)
sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
CnStEvnt *cnStEvnt = &sngisdn_event->event.cnStEvnt;
ftdm_assert(!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE), "State change flag pending\n");
@ -302,19 +318,49 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event)
suId, suInstId, spInstId, ces);
switch(evntType) {
case MI_PROGRESS:
if (signal_data->switchtype == SNGISDN_SWITCH_NI2 &&
cnStEvnt->causeDgn[0].eh.pres && cnStEvnt->causeDgn[0].causeVal.pres) {
switch(cnStEvnt->causeDgn[0].causeVal.val) {
case 17: /* User Busy */
case 18: /* No User responding */
case 19: /* User alerting, no answer */
case 21: /* Call rejected, the called party does not with to accept this call */
case 27: /* Destination out of order */
case 31: /* Normal, unspecified */
case 34: /* Circuit/Channel congestion */
case 41: /* Temporary failure */
case 42: /* Switching equipment is experiencing a period of high traffic */
case 47: /* Resource unavailable */
case 58: /* Bearer Capability not available */
case 63: /* Service or option not available */
case 65: /* Bearer Cap not implemented, not supported */
case 79: /* Service or option not implemented, unspecified */
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Cause requires disconnect (cause:%d)\n", cnStEvnt->causeDgn[0].causeVal.val);
ftdmchan->caller_data.hangup_cause = cnStEvnt->causeDgn[0].causeVal.val;
sngisdn_set_flag(sngisdn_info, FLAG_SEND_DISC);
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
goto sngisdn_process_cnst_ind_end;
}
}
/* fall-through */
case MI_ALERTING:
case MI_CALLPROC:
case MI_PROGRESS:
switch(ftdmchan->state) {
case FTDM_CHANNEL_STATE_DIALING:
if (evntType == MI_PROGRESS) {
case FTDM_CHANNEL_STATE_DIALING:
if (evntType == MI_PROGRESS ||
(cnStEvnt->progInd.eh.pres && cnStEvnt->progInd.progDesc.val == IN_PD_IBAVAIL)) {
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
} else {
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS);
}
break;
case FTDM_CHANNEL_STATE_PROGRESS:
if (evntType == MI_PROGRESS) {
if (evntType == MI_PROGRESS ||
(cnStEvnt->progInd.eh.pres && cnStEvnt->progInd.progDesc.val == IN_PD_IBAVAIL)) {
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
}
break;
@ -371,6 +417,7 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event)
break;
}
sngisdn_process_cnst_ind_end:
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
return;
}
@ -638,12 +685,14 @@ void sngisdn_process_flc_ind (sngisdn_event_data_t *sngisdn_event)
void sngisdn_process_fac_ind (sngisdn_event_data_t *sngisdn_event)
{
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
int16_t suId = sngisdn_event->suId;
uint32_t suInstId = sngisdn_event->suInstId;
uint32_t spInstId = sngisdn_event->spInstId;
sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
FacEvnt *facEvnt = &sngisdn_event->event.facEvnt;
@ -659,10 +708,16 @@ void sngisdn_process_fac_ind (sngisdn_event_data_t *sngisdn_event)
if (sng_isdn_retrieve_facility_caller_name(facility_str, facEvnt->facElmt.facStr.len, retrieved_str) != FTDM_SUCCESS) {
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Failed to retrieve Caller Name from Facility IE\n");
}
/* Cancel facility timeout */
ftdm_sched_cancel_timer(signal_data->sched, &sngisdn_info->timers[SNGISDN_TIMER_FACILITY]);
}
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING);
break;
case FTDM_CHANNEL_STATE_RING:
/* We received the caller ID Name in FACILITY, but its too late, facility-timeout already occurred */
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "FACILITY received, but we already proceeded with call\n");
break;
default:
/* We do not support other FACILITY types for now, so do nothing */
break;
@ -794,6 +849,14 @@ void sngisdn_process_sta_cfm (sngisdn_event_data_t *sngisdn_event)
break;
case 3:
switch (ftdmchan->state) {
case FTDM_CHANNEL_STATE_PROGRESS:
/* T310 timer has expired */
ftdmchan->caller_data.hangup_cause = staEvnt->causeDgn[0].causeVal.val;
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "T310 Timer expired, hanging up call\n");
sngisdn_set_flag(sngisdn_info, FLAG_SEND_DISC);
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
break;
case FTDM_CHANNEL_STATE_UP:
/* Remote side is still waiting for our CONNECT message */
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {

View File

@ -409,7 +409,7 @@ void sngisdn_snd_connect(ftdm_channel_t *ftdmchan)
sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) {
if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) {
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending CONNECT, but no call data, aborting (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);
sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT);
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
@ -450,6 +450,14 @@ void sngisdn_snd_connect(ftdm_channel_t *ftdmchan)
cnStEvnt.chanId.chanNmbSlotMap.len = 1;
cnStEvnt.chanId.chanNmbSlotMap.val[0] = ftdmchan->physical_chan_id;
}
cnStEvnt.progInd.eh.pres = PRSNT_NODEF;
cnStEvnt.progInd.location.pres = PRSNT_NODEF;
cnStEvnt.progInd.location.val = IN_LOC_USER;
cnStEvnt.progInd.codeStand0.pres = PRSNT_NODEF;
cnStEvnt.progInd.codeStand0.val = IN_CSTD_CCITT;
cnStEvnt.progInd.progDesc.pres = PRSNT_NODEF;
cnStEvnt.progInd.progDesc.val = IN_PD_NOTETEISDN; /* Not end-to-end ISDN */
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)) {

View File

@ -45,8 +45,8 @@ void sngisdn_rcv_con_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, Co
{
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
uint8_t bchan_no = 0;
sngisdn_chan_data_t *sngisdn_info;
sngisdn_event_data_t *sngisdn_event;
sngisdn_chan_data_t *sngisdn_info = NULL;
sngisdn_event_data_t *sngisdn_event = NULL;
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");
@ -96,7 +96,7 @@ void sngisdn_rcv_con_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, Co
ftdm_mutex_unlock(g_sngisdn_data.ccs[suId].mutex);
memcpy(&sngisdn_event->event.conEvnt, conEvnt, sizeof(*conEvnt));
ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event);
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
}
@ -104,8 +104,8 @@ void sngisdn_rcv_con_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, Co
void sngisdn_rcv_con_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, CnStEvnt *cnStEvnt, int16_t dChan, uint8_t ces)
{
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
sngisdn_chan_data_t *sngisdn_info;
sngisdn_event_data_t *sngisdn_event;
sngisdn_chan_data_t *sngisdn_info = NULL;
sngisdn_event_data_t *sngisdn_event = NULL;
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");
@ -118,6 +118,7 @@ void sngisdn_rcv_con_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, Cn
if (!sngisdn_info->spInstId) {
ftdm_mutex_lock(g_sngisdn_data.ccs[suId].mutex);
sngisdn_info->spInstId = spInstId;
g_sngisdn_data.ccs[suId].active_spInstIds[spInstId] = sngisdn_info;
ftdm_mutex_unlock(g_sngisdn_data.ccs[suId].mutex);
@ -146,8 +147,8 @@ void sngisdn_rcv_con_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, Cn
void sngisdn_rcv_cnst_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, CnStEvnt *cnStEvnt, uint8_t evntType, int16_t dChan, uint8_t ces)
{
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
sngisdn_chan_data_t *sngisdn_info;
sngisdn_event_data_t *sngisdn_event;
sngisdn_chan_data_t *sngisdn_info = NULL;
sngisdn_event_data_t *sngisdn_event = NULL;
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");
@ -160,6 +161,7 @@ void sngisdn_rcv_cnst_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, C
if (!sngisdn_info->spInstId) {
ftdm_mutex_lock(g_sngisdn_data.ccs[suId].mutex);
sngisdn_info->spInstId = spInstId;
g_sngisdn_data.ccs[suId].active_spInstIds[spInstId] = sngisdn_info;
ftdm_mutex_unlock(g_sngisdn_data.ccs[suId].mutex);
@ -188,15 +190,15 @@ void sngisdn_rcv_cnst_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, C
memcpy(&sngisdn_event->event.cnStEvnt, cnStEvnt, sizeof(*cnStEvnt));
ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event);
ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event);
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
}
void sngisdn_rcv_disc_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, DiscEvnt *discEvnt)
{
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
sngisdn_chan_data_t *sngisdn_info;
sngisdn_event_data_t *sngisdn_event;
sngisdn_chan_data_t *sngisdn_info = NULL;
sngisdn_event_data_t *sngisdn_event = NULL;
ftdm_assert(spInstId != 0, "Received DISCONNECT with invalid id");
@ -207,13 +209,6 @@ void sngisdn_rcv_disc_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, D
ftdm_assert(0, "Inconsistent call states\n");
return;
}
if (!sngisdn_info->spInstId) {
ftdm_mutex_lock(g_sngisdn_data.ccs[suId].mutex);
sngisdn_info->spInstId = spInstId;
g_sngisdn_data.ccs[suId].active_spInstIds[spInstId] = sngisdn_info;
ftdm_mutex_unlock(g_sngisdn_data.ccs[suId].mutex);
}
ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received DISCONNECT (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
@ -229,7 +224,7 @@ void sngisdn_rcv_disc_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, D
memcpy(&sngisdn_event->event.discEvnt, discEvnt, sizeof(*discEvnt));
ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event);
ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event);
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
}
@ -237,21 +232,22 @@ void sngisdn_rcv_disc_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, D
void sngisdn_rcv_rel_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, RelEvnt *relEvnt)
{
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
sngisdn_chan_data_t *sngisdn_info;
sngisdn_event_data_t *sngisdn_event;
sngisdn_chan_data_t *sngisdn_info = NULL;
sngisdn_event_data_t *sngisdn_event = NULL;
if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
!(suInstId && 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);
ftdm_assert(0, "Inconsistent call states\n");
/* It seems that Trillium has a bug where they sometimes send release twice on a call, so do not crash on these for now */
/* ftdm_assert(0, "Inconsistent call states\n"); */
return;
}
ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received RELEASE/RELEASE COMPLETE (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event));
ftdm_assert(sngisdn_event, "Failed to allocate memory\n");
ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n");
memset(sngisdn_event, 0, sizeof(*sngisdn_event));
sngisdn_event->event_id = SNGISDN_EVENT_REL_IND;
@ -270,7 +266,7 @@ void sngisdn_rcv_dat_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, In
{
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
sngisdn_chan_data_t *sngisdn_info;
sngisdn_event_data_t *sngisdn_event;
sngisdn_event_data_t *sngisdn_event = NULL;
if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
!(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) {
@ -283,7 +279,7 @@ void sngisdn_rcv_dat_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, In
ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received DATA IND suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId);
sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event));
ftdm_assert(sngisdn_event, "Failed to allocate memory\n");
ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n");
memset(sngisdn_event, 0, sizeof(*sngisdn_event));
sngisdn_event->event_id = SNGISDN_EVENT_DAT_IND;
@ -302,7 +298,7 @@ void sngisdn_rcv_sshl_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, S
{
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
sngisdn_chan_data_t *sngisdn_info;
sngisdn_event_data_t *sngisdn_event;
sngisdn_event_data_t *sngisdn_event = NULL;
if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
!(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) {
@ -315,7 +311,7 @@ void sngisdn_rcv_sshl_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, S
ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received SSHL IND (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event));
ftdm_assert(sngisdn_event, "Failed to allocate memory\n");
ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n");
memset(sngisdn_event, 0, sizeof(*sngisdn_event));
sngisdn_event->event_id = SNGISDN_EVENT_SSHL_IND;
@ -335,7 +331,7 @@ void sngisdn_rcv_sshl_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, S
{
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
sngisdn_chan_data_t *sngisdn_info;
sngisdn_event_data_t *sngisdn_event;
sngisdn_event_data_t *sngisdn_event = NULL;
if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
!(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) {
@ -348,7 +344,7 @@ void sngisdn_rcv_sshl_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, S
ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received SSHL CFM (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event));
ftdm_assert(sngisdn_event, "Failed to allocate memory\n");
ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n");
memset(sngisdn_event, 0, sizeof(*sngisdn_event));
sngisdn_event->event_id = SNGISDN_EVENT_SSHL_CFM;
@ -360,14 +356,14 @@ void sngisdn_rcv_sshl_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, S
memcpy(&sngisdn_event->event.ssHlEvnt, ssHlEvnt, sizeof(*ssHlEvnt));
ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event);
ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event);
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
}
void sngisdn_rcv_rmrt_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, RmRtEvnt *rmRtEvnt, uint8_t action)
{
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
sngisdn_chan_data_t *sngisdn_info;
sngisdn_event_data_t *sngisdn_event;
sngisdn_event_data_t *sngisdn_event = NULL;
if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
!(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) {
@ -380,7 +376,7 @@ void sngisdn_rcv_rmrt_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, R
ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received RMRT IND (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event));
ftdm_assert(sngisdn_event, "Failed to allocate memory\n");
ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n");
memset(sngisdn_event, 0, sizeof(*sngisdn_event));
sngisdn_event->event_id = SNGISDN_EVENT_RMRT_IND;
@ -392,7 +388,7 @@ void sngisdn_rcv_rmrt_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, R
memcpy(&sngisdn_event->event.rmRtEvnt, rmRtEvnt, sizeof(*rmRtEvnt));
ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event);
ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event);
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
}
@ -400,7 +396,7 @@ void sngisdn_rcv_rmrt_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, R
{
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
sngisdn_chan_data_t *sngisdn_info;
sngisdn_event_data_t *sngisdn_event;
sngisdn_event_data_t *sngisdn_event = NULL;
if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
!(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) {
@ -413,7 +409,7 @@ void sngisdn_rcv_rmrt_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, R
ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received RESUME/RETRIEVE CFM (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event));
ftdm_assert(sngisdn_event, "Failed to allocate memory\n");
ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n");
memset(sngisdn_event, 0, sizeof(*sngisdn_event));
sngisdn_event->event_id = SNGISDN_EVENT_RMRT_CFM;
@ -425,7 +421,7 @@ void sngisdn_rcv_rmrt_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, R
memcpy(&sngisdn_event->event.rmRtEvnt, rmRtEvnt, sizeof(*rmRtEvnt));
ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event);
ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event);
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
}
@ -433,7 +429,7 @@ void sngisdn_rcv_flc_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, St
{
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
sngisdn_chan_data_t *sngisdn_info;
sngisdn_event_data_t *sngisdn_event;
sngisdn_event_data_t *sngisdn_event = NULL;
if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
!(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) {
@ -446,7 +442,7 @@ void sngisdn_rcv_flc_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, St
ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received FLOW CONTROL IND (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event));
ftdm_assert(sngisdn_event, "Failed to allocate memory\n");
ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n");
memset(sngisdn_event, 0, sizeof(*sngisdn_event));
sngisdn_event->event_id = SNGISDN_EVENT_FLC_IND;
@ -457,7 +453,7 @@ void sngisdn_rcv_flc_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, St
memcpy(&sngisdn_event->event.staEvnt, staEvnt, sizeof(*staEvnt));
ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event);
ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event);
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
}
@ -466,7 +462,7 @@ void sngisdn_rcv_fac_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, Fa
{
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
sngisdn_chan_data_t *sngisdn_info;
sngisdn_event_data_t *sngisdn_event;
sngisdn_event_data_t *sngisdn_event = NULL;
if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
!(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) {
@ -478,7 +474,7 @@ void sngisdn_rcv_fac_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, Fa
ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received FACILITY IND (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event));
ftdm_assert(sngisdn_event, "Failed to allocate memory\n");
ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n");
memset(sngisdn_event, 0, sizeof(*sngisdn_event));
sngisdn_event->event_id = SNGISDN_EVENT_FAC_IND;
@ -499,7 +495,7 @@ void sngisdn_rcv_sta_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, St
{
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
sngisdn_chan_data_t *sngisdn_info;
sngisdn_event_data_t *sngisdn_event;
sngisdn_event_data_t *sngisdn_event = NULL;
if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
!(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) {
@ -512,7 +508,7 @@ void sngisdn_rcv_sta_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, St
ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received STATUS CONFIRM (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event));
ftdm_assert(sngisdn_event, "Failed to allocate memory\n");
ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n");
memset(sngisdn_event, 0, sizeof(*sngisdn_event));
sngisdn_event->event_id = SNGISDN_EVENT_STA_CFM;
@ -532,7 +528,7 @@ void sngisdn_rcv_srv_ind (int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
unsigned i;
sngisdn_span_data_t *signal_data;
sngisdn_event_data_t *sngisdn_event;
sngisdn_event_data_t *sngisdn_event = NULL;
ftdm_log(FTDM_LOG_INFO, "Received SERVICE IND (dChan:%d ces:%u)\n", dChan, ces);
@ -540,7 +536,7 @@ void sngisdn_rcv_srv_ind (int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces
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, "Failed to allocate memory\n");
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;
@ -550,7 +546,7 @@ void sngisdn_rcv_srv_ind (int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces
sngisdn_event->signal_data = signal_data;
memcpy(&sngisdn_event->event.srvEvnt, srvEvnt, sizeof(*srvEvnt));
ftdm_queue_enqueue((signal_data)->event_queue, sngisdn_event);
ftdm_queue_enqueue((signal_data)->event_queue, sngisdn_event);
}
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
}
@ -560,8 +556,8 @@ void sngisdn_rcv_srv_cfm (int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces
{
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
unsigned i;
sngisdn_span_data_t *signal_data;
sngisdn_event_data_t *sngisdn_event;
sngisdn_span_data_t *signal_data = NULL;
sngisdn_event_data_t *sngisdn_event = NULL;
ftdm_log(FTDM_LOG_INFO, "Received SERVICE CFM (dChan:%d ces:%u)\n", dChan, ces);
@ -569,7 +565,7 @@ void sngisdn_rcv_srv_cfm (int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces
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, "Failed to allocate memory\n");
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;
@ -588,16 +584,17 @@ void sngisdn_rcv_rst_ind (int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces
{
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
unsigned i;
sngisdn_span_data_t *signal_data;
sngisdn_event_data_t *sngisdn_event;
sngisdn_span_data_t *signal_data = NULL;
sngisdn_event_data_t *sngisdn_event = NULL;
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, "Failed to allocate memory\n");
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;
@ -618,7 +615,7 @@ void sngisdn_rcv_rst_cfm (int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
unsigned i;
sngisdn_span_data_t *signal_data;
sngisdn_event_data_t *sngisdn_event;
sngisdn_event_data_t *sngisdn_event = NULL;
ftdm_log(FTDM_LOG_INFO, "Received RESTART CFM (dChan:%d ces:%u type:%u)\n", dChan, ces, evntType);
@ -626,7 +623,7 @@ void sngisdn_rcv_rst_cfm (int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces
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, "Failed to allocate memory\n");
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;
@ -645,30 +642,24 @@ 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)
{
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
if (reason != LL1_REASON_CON_REQ_FAIL) {
ftdm_log(FTDM_LOG_INFO, "[SNGISDN PHY] D-chan %d : %s\n", suId, DECODE_LL1_REASON(reason));
}
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
return;
}
void sngisdn_rcv_q921_ind(BdMngmt *status)
{
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
unsigned j,k;
ftdm_span_t *ftdmspan = NULL;
for(j=1;j<=g_sngisdn_data.num_dchan;j++) {
for(k=1;k<=g_sngisdn_data.dchans[j].num_spans;k++) {
if (g_sngisdn_data.dchans[j].spans[k]->link_id == status->t.usta.lnkNmb) {
ftdmspan = (ftdm_span_t*)g_sngisdn_data.dchans[j].spans[k]->ftdm_span;
}
}
{
ftdm_span_t *ftdmspan;
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);
return;
}
if (ftdmspan == NULL) {
ftdm_log(FTDM_LOG_WARNING, "Received q921 status on unconfigured span (lnkNmb:%d)\n", status->t.usta.lnkNmb);
ftdmspan = signal_data->ftdm_span;
if (!ftdmspan) {
ftdm_log(FTDM_LOG_INFO, "Received q921 status on unconfigured span (lnkNmb:%d)\n", status->t.usta.lnkNmb);
return;
}
@ -699,69 +690,56 @@ void sngisdn_rcv_q921_ind(BdMngmt *status)
}
break;
}
ISDN_FUNC_TRACE_EXIT(__FUNCTION__)
return;
}
void sngisdn_rcv_q931_ind(InMngmt *status)
{
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
ftdm_span_t *ftdmspan = NULL;
{
if (status->t.usta.alarm.cause == 287) {
get_memory_info();
return;
}
switch (status->t.usta.alarm.category) {
case (LCM_CATEGORY_INTERFACE):
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);
/* clean this up later */
switch (status->t.usta.alarm.event) {
case LCM_EVENT_UP:
case LCM_EVENT_DOWN:
{
unsigned j,k;
for(j=1;j<=g_sngisdn_data.num_dchan;j++) {
for(k=1;k<=g_sngisdn_data.dchans[j].num_spans;k++) {
if (g_sngisdn_data.dchans[j].spans[k]->link_id == status->t.usta.suId) {
ftdmspan = (ftdm_span_t*)g_sngisdn_data.dchans[j].spans[k]->ftdm_span;
}
}
}
if (ftdmspan == NULL) {
ftdm_log(FTDM_LOG_CRIT, "Received q931 LCM EVENT on unconfigured span (suId:%u)\n", status->t.usta.suId);
return;
}
if (status->t.usta.alarm.event == LCM_EVENT_UP) {
sngisdn_set_span_sig_status(ftdmspan, FTDM_SIG_STATE_UP);
sng_isdn_set_avail_rate(ftdmspan, SNGISDN_AVAIL_UP);
} else {
sngisdn_set_span_sig_status(ftdmspan, FTDM_SIG_STATE_DOWN);
sng_isdn_set_avail_rate(ftdmspan, SNGISDN_AVAIL_PWR_SAVING);
}
}
break;
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.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);
return;
}
break;
ftdmspan = signal_data->ftdm_span;
if (status->t.usta.alarm.event == LCM_EVENT_UP) {
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);
sngisdn_set_span_sig_status(ftdmspan, FTDM_SIG_STATE_UP);
sng_isdn_set_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);
sng_isdn_set_avail_rate(ftdmspan, SNGISDN_AVAIL_PWR_SAVING);
}
}
break;
default:
ftdm_log(FTDM_LOG_DEBUG, "[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);
break;
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);
}
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
return;
}
@ -907,12 +885,13 @@ void sngisdn_rcv_sng_log(uint8_t level, char *fmt,...)
break;
case SNG_LOGLEVEL_CRIT:
ftdm_log(FTDM_LOG_CRIT, "sng_isdn->%s", data);
/*ftdm_assert(0, "Got an error from stack");*/
/* ftdm_assert(0, "Got an error from stack"); */
break;
default:
ftdm_log(FTDM_LOG_INFO, "sng_isdn->%s", data);
break;
}
ftdm_safe_free(data);
return;
}

View File

@ -73,8 +73,10 @@ void __inline__ clear_call_glare_data(sngisdn_chan_data_t *sngisdn_info)
sngisdn_info->glare.suInstId, sngisdn_info->glare.spInstId,
sngisdn_info->suInstId, sngisdn_info->spInstId);
ftdm_mutex_lock(g_sngisdn_data.ccs[sngisdn_info->glare.suId].mutex);
g_sngisdn_data.ccs[sngisdn_info->glare.suId].active_spInstIds[sngisdn_info->glare.spInstId]=NULL;
ftdm_mutex_lock(g_sngisdn_data.ccs[sngisdn_info->glare.suId].mutex);
if (sngisdn_info->glare.spInstId != sngisdn_info->spInstId) {
g_sngisdn_data.ccs[sngisdn_info->glare.suId].active_spInstIds[sngisdn_info->glare.spInstId]=NULL;
}
g_sngisdn_data.ccs[sngisdn_info->glare.suId].active_suInstIds[sngisdn_info->glare.suInstId]=NULL;
ftdm_mutex_unlock(g_sngisdn_data.ccs[sngisdn_info->glare.suId].mutex);
@ -132,16 +134,22 @@ ftdm_status_t __inline__ get_ftdmchan_by_spInstId(uint8_t cc_id, uint32_t spInst
return FTDM_SUCCESS;
}
ftdm_status_t sng_isdn_set_avail_rate(ftdm_span_t *ftdmspan, sngisdn_avail_t avail)
ftdm_status_t sng_isdn_set_avail_rate(ftdm_span_t *span, sngisdn_avail_t avail)
{
unsigned i;
if (ftdmspan->trunk_type == FTDM_TRUNK_BRI ||
ftdmspan->trunk_type == FTDM_TRUNK_BRI_PTMP) {
if (span->trunk_type == FTDM_TRUNK_BRI ||
span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
for(i=1; i<=ftdmspan->chan_count; i++) {
ftdm_log_chan(ftdmspan->channels[i], FTDM_LOG_DEBUG, "Setting availability rate to:%d\n", avail);
ftdmspan->channels[i]->availability_rate = avail;
ftdm_iterator_t *chaniter = NULL;
ftdm_iterator_t *curr = NULL;
chaniter = ftdm_span_get_chan_iterator(span, NULL);
for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
ftdm_log_chan(((ftdm_channel_t*)ftdm_iterator_current(curr)), FTDM_LOG_DEBUG, "Setting availability rate to:%d\n", avail);
((ftdm_channel_t*)ftdm_iterator_current(curr))->availability_rate = avail;
}
ftdm_iterator_free(chaniter);
}
return FTDM_SUCCESS;
}
@ -427,6 +435,24 @@ void sngisdn_delayed_disconnect(void* p_sngisdn_info)
return;
}
void sngisdn_facility_timeout(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);
if (ftdmchan->state == FTDM_CHANNEL_STATE_GET_CALLERID) {
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Facility timeout reached proceeding with call (suId:%d suInstId:%u spInstId:%u)\n",
signal_data->cc_id, sngisdn_info->spInstId, sngisdn_info->suInstId);
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING);
}
ftdm_mutex_unlock(ftdmchan->mutex);
return;
}
ftdm_status_t sngisdn_check_free_ids(void)
{
unsigned i;
@ -534,6 +560,77 @@ ftdm_user_layer1_prot_t sngisdn_get_usrInfoLyr1Prot_from_user(uint8_t layer1_pro
return FTDM_USER_LAYER1_PROT_ULAW;
}
void sngisdn_print_phy_stats(ftdm_stream_handle_t *stream, ftdm_span_t *span)
{
L1Mngmt sts;
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);
stream->write_function(stream, "\n---------------------------------------------------------------------\n");
stream->write_function(stream, " Span:%s", span->name);
stream->write_function(stream, "\n---------------------------------------------------------------------\n");
stream->write_function(stream, " Performance Counters");
stream->write_function(stream, "\n---------------------------------------------------------------------\n");
stream->write_function(stream, "RX Packets:\t%u\tTX Packets:\t%u\tEvents:%u\n", sts.t.sts.rx_packets, sts.t.sts.tx_packets, sts.t.sts.rx_events);
stream->write_function(stream, "RX Bytes:\t%u\tTX Bytes:\t%u\n\n", sts.t.sts.rx_bytes, sts.t.sts.tx_bytes);
stream->write_function(stream, "TX Queue:\t%u/%u\tRX Queue:\t%u/%u\tEvents Queue:\t%u/%u\n",
sts.t.sts.num_frames_in_tx_queue,sts.t.sts.tx_queue_len,
sts.t.sts.num_frames_in_rx_queue, sts.t.sts.rx_queue_len,
sts.t.sts.rx_events_in_queue, sts.t.sts.event_queue_len);
stream->write_function(stream, "\n---------------------------------------------------------------------\n");
stream->write_function(stream, " Errors");
stream->write_function(stream, "\n---------------------------------------------------------------------\n");
stream->write_function(stream, "RX Errors:\t%u\tTX Errors:\t%u\n", sts.t.sts.rx_errors, sts.t.sts.tx_errors);
stream->write_function(stream, "RX Dropped:\t%u\tTX Dropped:\t%u\tEvents Dropped:\t%u\n", sts.t.sts.rx_dropped, sts.t.sts.tx_dropped,sts.t.sts.rx_events_dropped);
stream->write_function(stream, "\n---------------------------------------------------------------------\n");
stream->write_function(stream, " RX Errors Details");
stream->write_function(stream, "\n---------------------------------------------------------------------\n");
stream->write_function(stream, "CRC:\t\t%u\tFrame:\t\t%u\tOverruns:\t%u\n", sts.t.sts.rx_crc_errors, sts.t.sts.rx_frame_errors, sts.t.sts.rx_over_errors);
stream->write_function(stream, "Fifo:\t\t%u\tAborts:\t\t%u\tMissed:\t\t%u\n", sts.t.sts.rx_fifo_errors, sts.t.sts.rx_hdlc_abort_counter, sts.t.sts.rx_missed_errors);
stream->write_function(stream, "Length:\t\t%u\n", sts.t.sts.rx_length_errors);
stream->write_function(stream, "\n---------------------------------------------------------------------\n");
stream->write_function(stream, " TX Errors Details");
stream->write_function(stream, "\n---------------------------------------------------------------------\n");
stream->write_function(stream, "Aborted:\t%u\tFifo:\t\t%u\tCarrier:\t%u\n", sts.t.sts.tx_aborted_errors, sts.t.sts.tx_fifo_errors, sts.t.sts.tx_carrier_errors);
return;
}
void sngisdn_print_span(ftdm_stream_handle_t *stream, ftdm_span_t *span)
{
ftdm_signaling_status_t sigstatus;
ftdm_alarm_flag_t alarmbits;
ftdm_channel_t *fchan;
alarmbits = FTDM_ALARM_NONE;
fchan = ftdm_span_get_channel(span, 1);
if (fchan) {
ftdm_channel_get_alarms(fchan, &alarmbits);
}
ftdm_span_get_sig_status(span, &sigstatus);
stream->write_function(stream, "span:%s physical:%s signalling:%s\n",
span->name, alarmbits ? "ALARMED" : "OK",
ftdm_signaling_status2str(sigstatus));
return;
}
void sngisdn_print_spans(ftdm_stream_handle_t *stream)
{
int i;
for(i=1;i<=MAX_L1_LINKS;i++) {
if (g_sngisdn_data.spans[i]) {
sngisdn_print_span(stream, g_sngisdn_data.spans[i]->ftdm_span);
}
}
return;
}
/* For Emacs:
* Local Variables:
* mode:c

View File

@ -213,7 +213,7 @@ int ft_to_sngss7_cfg_all(void)
SS7_CRITICAL("MTP3 ROUTE %d configuration FAILED!\n", x);
SS7_ASSERT
} else {
SS7_INFO("MTP3 ROUTE %d configuration DONE!\n");
SS7_INFO("MTP3 ROUTE %d configuration DONE!\n",x);
}
/* set the CONFIGURED flag */
@ -229,7 +229,7 @@ int ft_to_sngss7_cfg_all(void)
SS7_CRITICAL("MTP3 ROUTE 0 configuration FAILED!\n");
SS7_ASSERT
} else {
SS7_INFO("MTP3 ROUTE %d configuration DONE!\n");
SS7_INFO("MTP3 ROUTE 0 configuration DONE!\n");
}
/* set the CONFIGURED flag */
@ -444,8 +444,8 @@ int ftmod_ss7_mtp3_gen_config(void)
cfg.t.cfg.s.snGen.tmr.t21.enb = TRUE; /* t21 - waiting to restart traffic routed through adjacent SP */
cfg.t.cfg.s.snGen.tmr.t21.val = 650;
# if (SS7_ANS92 || SS7_ANS88 || SS7_ANS96 || defined(TDS_ROLL_UPGRADE_SUPPORT))
cfg.t.cfg.s.snGen.t26.enb = TRUE; /* t26 - waiting to repeat traffic restart waiting message for ANSI */
cfg.t.cfg.s.snGen.t26.val = 600;
cfg.t.cfg.s.snGen.tmr.t26.enb = TRUE; /* t26 - waiting to repeat traffic restart waiting message for ANSI */
cfg.t.cfg.s.snGen.tmr.t26.val = 600;
# endif
#endif
@ -644,7 +644,7 @@ int ftmod_ss7_mtp2_dlsap_config(int id)
cfg.t.cfg.s.sdDLSAP.memMac.region = S_REG; /* memory region and pool id for MAC */
cfg.t.cfg.s.sdDLSAP.memMac.pool = S_POOL;
cfg.t.cfg.s.sdDLSAP.maxOutsFrms = MAX_SD_OUTSTANDING; /* maximum outstanding frames */
cfg.t.cfg.s.sdDLSAP.errType = SD_ERR_NRM;
cfg.t.cfg.s.sdDLSAP.errType = k->mtp2.errorType;
cfg.t.cfg.s.sdDLSAP.t1.enb = TRUE; /* timer 1 - Alignment Ready Timer */
cfg.t.cfg.s.sdDLSAP.t1.val = k->mtp2.t1;
cfg.t.cfg.s.sdDLSAP.t2.enb = TRUE; /* timer 2 - Not Aligned Timer */
@ -744,10 +744,6 @@ int ftmod_ss7_mtp3_dlsap_config(int id)
cfg.t.cfg.s.snDLSAP.msgPrior = 0; /* management message priority */
cfg.t.cfg.s.snDLSAP.lnkType = k->mtp3.linkType; /* link type ANSI, ITU, BICI or CHINA */
cfg.t.cfg.s.snDLSAP.upSwtch = k->mtp3.switchType; /* user part switch type */
# if (SS7_ANS92 || SS7_ANS88 || SS7_ANS96 || SS7_CHINA)
cfg.t.cfg.s.snDLSAP.l2Type = LSN_MTP2_56KBPS; /* layer 2 type - 56kbps MTP2 link, 1.536Mbps MTP2 link or QSAAL link */
cfg.t.cfg.s.snDLSAP.isCLink = FALSE; /* identifies if the link is a C type link.Required to check if sls has to be rotated.*/
# endif
cfg.t.cfg.s.snDLSAP.maxSLTtry = MAX_SLTM_RETRIES; /* maximun times to retry SLTM */
cfg.t.cfg.s.snDLSAP.p0QLen = 32; /* size of the priority 0 Q */
cfg.t.cfg.s.snDLSAP.p1QLen = 32; /* size of the priority 1 Q */
@ -775,17 +771,46 @@ int ftmod_ss7_mtp3_dlsap_config(int id)
cfg.t.cfg.s.snDLSAP.selector = 0; /* lower layer selector */
cfg.t.cfg.s.snDLSAP.mem.region = S_REG; /* memory region id */
cfg.t.cfg.s.snDLSAP.mem.pool = S_POOL; /* memory pool id */
#if( SS7_ANS92 || SS7_ANS88 || SS7_ANS96 || SS7_CHINA )
cfg.t.cfg.s.snDLSAP.dpcLen = DPC24; /* dpc length 24 bits */
#else
cfg.t.cfg.s.snDLSAP.dpcLen = DPC14; /* dpc length 14 bits */
#endif
cfg.t.cfg.s.snDLSAP.spId = k->mtp3.mtp2Id ;/* service provider id */
#if (SS7_ITU88 || SS7_CHINA || SS7_TTC || SS7_NTT || SS7_BICI )
cfg.t.cfg.s.snDLSAP.flushContFlag = FALSE; /* flush continue handling */
#else
cfg.t.cfg.s.snDLSAP.flushContFlag = TRUE; /* flush continue handling */
#endif
switch (k->mtp3.linkType) {
/**************************************************************************/
case (LSN_SW_ANS):
case (LSN_SW_ANS96):
case (LSN_SW_CHINA):
cfg.t.cfg.s.snDLSAP.dpcLen = DPC24; /* dpc length 24 bits */
cfg.t.cfg.s.snDLSAP.l2Type = LSN_MTP2_56KBPS; /* layer 2 type - 56kbps MTP2 link, 1.536Mbps MTP2 link or QSAAL link */
cfg.t.cfg.s.snDLSAP.isCLink = FALSE; /* identifies if the link is a C type link.Required to check if sls has to be rotated.*/
break;
/**************************************************************************/
case (LSN_SW_ITU):
cfg.t.cfg.s.snDLSAP.dpcLen = DPC14; /* dpc length 14 bits */
break;
/**************************************************************************/
default:
cfg.t.cfg.s.snDLSAP.dpcLen = DPC14; /* dpc length 14 bits */
break;
/**************************************************************************/
} /* switch (k->mtp3.linkType) */
switch (k->mtp3.linkType) {
/**************************************************************************/
case (LSN_SW_ANS):
case (LSN_SW_ANS96):
cfg.t.cfg.s.snDLSAP.flushContFlag = TRUE; /* flush continue handling */
break;
/**************************************************************************/
case (LSN_SW_ITU):
case (LSN_SW_CHINA):
cfg.t.cfg.s.snDLSAP.flushContFlag = FALSE; /* flush continue handling */
break;
/**************************************************************************/
default:
cfg.t.cfg.s.snDLSAP.flushContFlag = FALSE; /* flush continue handling */
break;
/**************************************************************************/
} /* switch (k->mtp3.linkType) */
cfg.t.cfg.s.snDLSAP.tmr.t1.enb = TRUE; /* t1 - delay to avoid missequencing on changeover */
cfg.t.cfg.s.snDLSAP.tmr.t1.val = k->mtp3.t1;
cfg.t.cfg.s.snDLSAP.tmr.t2.enb = TRUE; /* t2 - waiting for changeover ack */
@ -900,7 +925,7 @@ int ftmod_ss7_mtp3_linkset_config(int id)
{
Pst pst;
SnMngmt cfg;
U16 c;
int c;
sng_link_set_t *k = &g_ftdm_sngss7_data.cfg.mtpLinkSet[id];
/* initalize the post structure */
@ -927,12 +952,13 @@ int ftmod_ss7_mtp3_linkset_config(int id)
cfg.t.cfg.s.snLnkSet.lnkSetType = k->linkType; /* link type */
cfg.t.cfg.s.snLnkSet.adjDpc = k->apc; /* adjacent DPC */
cfg.t.cfg.s.snLnkSet.nmbActLnkReqd = k->minActive; /* minimum number of active links */
cfg.t.cfg.s.snLnkSet.nmbCmbLnkSet = 1; /* number of combined link sets */
for (c = 0; c < LSN_MAXCMBLNK; c++) {
cfg.t.cfg.s.snLnkSet.cmbLnkSet[c].cmbLnkSetId = c+1;
cfg.t.cfg.s.snLnkSet.nmbCmbLnkSet = k->numLinks; /* number of combined link sets */
for(c = 0; c < k->numLinks;c++) {
cfg.t.cfg.s.snLnkSet.cmbLnkSet[c].cmbLnkSetId = k->links[c];
cfg.t.cfg.s.snLnkSet.cmbLnkSet[c].lnkSetPrior = 0;
}
return(sng_cfg_mtp3(&pst, &cfg));
}
@ -1209,12 +1235,12 @@ int ftmod_ss7_isup_ckt_config(int id)
cfg.t.cfg.s.siCir.typeCntrl = k->typeCntrl; /* type of control */
cfg.t.cfg.s.siCir.contReq = FALSE; /* continuity check required */
#if (SI_218_COMP || SS7_ANS88 || SS7_ANS92 || SS7_ANS95 || SS7_BELL)
cfg.t.cfg.s.siCir.firstCic =; /* First cic in the circuit group */
cfg.t.cfg.s.siCir.numCir =; /* Number of circuits in the circuit group */
cfg.t.cfg.s.siCir.firstCic = 1; /* First cic in the circuit group */
cfg.t.cfg.s.siCir.numCir = 24; /* Number of circuits in the circuit group */
cfg.t.cfg.s.siCir.nonSS7Con = TRUE; /* connecting to non SS7 network */
cfg.t.cfg.s.siCir.outTrkGrpN =; /* outgoing trunk group number (For EXM) */
cfg.t.cfg.s.siCir.cvrTrkClli =; /* Trunk Group number (For CVR validation) */
cfg.t.cfg.s.siCir.clli =; /* common language location identifier */
cfg.t.cfg.s.siCir.outTrkGrpN.length = 0; /* outgoing trunk group number (For EXM) */
cfg.t.cfg.s.siCir.cvrTrkClli.length = 0; /* Trunk Group number (For CVR validation) */
cfg.t.cfg.s.siCir.clli.length = 0; /* common language location identifier */
#endif
cfg.t.cfg.s.siCir.cirTmr.t3.enb = TRUE; /* t3 timer - overload received */
cfg.t.cfg.s.siCir.cirTmr.t3.val = k->t3;

View File

@ -48,8 +48,6 @@ static ftdm_status_t handle_print_usuage(ftdm_stream_handle_t *stream);
static ftdm_status_t handle_set_function_trace(ftdm_stream_handle_t *stream, int on, int level);
static ftdm_status_t handle_set_message_trace(ftdm_stream_handle_t *stream, int on, int level);
static ftdm_status_t handle_set_blocks(ftdm_stream_handle_t *stream, int span, int chan, int verbose);
static ftdm_status_t handle_set_unblks(ftdm_stream_handle_t *stream, int span, int chan, int verbose);
static ftdm_status_t handle_set_inhibit(ftdm_stream_handle_t *stream, char *name);
static ftdm_status_t handle_set_uninhibit(ftdm_stream_handle_t *stream, char *name);
@ -63,6 +61,21 @@ static ftdm_status_t handle_show_status(ftdm_stream_handle_t *stream, int span,
static ftdm_status_t handle_tx_rsc(ftdm_stream_handle_t *stream, int span, int chan, int verbose);
static ftdm_status_t handle_tx_grs(ftdm_stream_handle_t *stream, int span, int chan, int range, int verbose);
static ftdm_status_t handle_tx_blo(ftdm_stream_handle_t *stream, int span, int chan, int verbose);
static ftdm_status_t handle_tx_ubl(ftdm_stream_handle_t *stream, int span, int chan, int verbose);
static ftdm_status_t handle_tx_cgb(ftdm_stream_handle_t *stream, int span, int chan, int range, int verbose);
static ftdm_status_t handle_tx_cgu(ftdm_stream_handle_t *stream, int span, int chan, int range, int verbose);
static ftdm_status_t handle_activate_link(ftdm_stream_handle_t *stream, char *name);
static ftdm_status_t handle_deactivate_link(ftdm_stream_handle_t *stream, char *name);
static ftdm_status_t handle_activate_linkset(ftdm_stream_handle_t *stream, char *name);
static ftdm_status_t handle_deactivate_linkset(ftdm_stream_handle_t *stream, char *name);
static ftdm_status_t handle_tx_lpo(ftdm_stream_handle_t *stream, char *name);
static ftdm_status_t handle_tx_lpr(ftdm_stream_handle_t *stream, char *name);
static ftdm_status_t handle_status_link(ftdm_stream_handle_t *stream, char *name);
static ftdm_status_t handle_status_linkset(ftdm_stream_handle_t *stream, char *name);
@ -282,20 +295,12 @@ ftdm_status_t ftdm_sngss7_handle_cli_cmd(ftdm_stream_handle_t *stream, const cha
/**********************************************************************/
}
/**************************************************************************/
} else if (!strcasecmp(argv[c], "block")) {
} else if (!strcasecmp(argv[c], "inhibit")) {
/**************************************************************************/
if (check_arg_count(argc, 2)) goto handle_cli_error_argc;
c++;
if (!strcasecmp(argv[c], "span")) {
/**********************************************************************/
if (check_arg_count(argc, 5)) goto handle_cli_error_argc;
if (extract_span_chan(argv, c, &span, &chan)) goto handle_cli_error_span_chan;
handle_set_blocks(stream, span, chan, verbose);
/**********************************************************************/
} else if (!strcasecmp(argv[c], "link")) {
if (!strcasecmp(argv[c], "link")) {
/**********************************************************************/
if (check_arg_count(argc, 3)) goto handle_cli_error_argc;
c++;
@ -309,7 +314,26 @@ ftdm_status_t ftdm_sngss7_handle_cli_cmd(ftdm_stream_handle_t *stream, const cha
/**********************************************************************/
}
/**************************************************************************/
} else if (!strcasecmp(argv[c], "unblock")) {
} else if (!strcasecmp(argv[c], "uninhibit")) {
/**************************************************************************/
if (check_arg_count(argc, 2)) goto handle_cli_error_argc;
c++;
if (!strcasecmp(argv[c], "link")) {
/**********************************************************************/
if (check_arg_count(argc, 3)) goto handle_cli_error_argc;
c++;
handle_set_uninhibit(stream, argv[c]);
/**********************************************************************/
} else {
/**********************************************************************/
stream->write_function(stream, "Unknown \"unblock\" command\n");
goto handle_cli_error;
/**********************************************************************/
}
/**************************************************************************/
} else if (!strcasecmp(argv[c], "blo")) {
/**************************************************************************/
if (check_arg_count(argc, 2)) goto handle_cli_error_argc;
c++;
@ -320,18 +344,101 @@ ftdm_status_t ftdm_sngss7_handle_cli_cmd(ftdm_stream_handle_t *stream, const cha
if (extract_span_chan(argv, c, &span, &chan)) goto handle_cli_error_span_chan;
handle_set_unblks(stream, span, chan, verbose);
/**********************************************************************/
} else if (!strcasecmp(argv[c], "link")) {
/**********************************************************************/
if (check_arg_count(argc, 3)) goto handle_cli_error_argc;
c++;
handle_set_uninhibit(stream, argv[c]);
handle_tx_blo(stream, span, chan, verbose);
/**********************************************************************/
} else {
/**********************************************************************/
stream->write_function(stream, "Unknown \"unblock\" command\n");
stream->write_function(stream, "Unknown \"block\" command\n");
goto handle_cli_error;
/**********************************************************************/
}
/**************************************************************************/
} else if (!strcasecmp(argv[c], "ubl")) {
/**************************************************************************/
if (check_arg_count(argc, 2)) goto handle_cli_error_argc;
c++;
if (!strcasecmp(argv[c], "span")) {
/**********************************************************************/
if (check_arg_count(argc, 5)) goto handle_cli_error_argc;
if (extract_span_chan(argv, c, &span, &chan)) goto handle_cli_error_span_chan;
handle_tx_ubl(stream, span, chan, verbose);
/**********************************************************************/
} else {
/**********************************************************************/
stream->write_function(stream, "Unknown \"ubl\" command\n");
goto handle_cli_error;
/**********************************************************************/
}
/**************************************************************************/
} else if (!strcasecmp(argv[c], "cgb")) {
/**************************************************************************/
if (check_arg_count(argc, 2)) goto handle_cli_error_argc;
c++;
if (!strcasecmp(argv[c], "span")) {
/**********************************************************************/
if (check_arg_count(argc, 5)) goto handle_cli_error_argc;
if (extract_span_chan(argv, c, &span, &chan)) goto handle_cli_error_span_chan;
c = c + 4;
if (check_arg_count(argc, 7)) goto handle_cli_error_argc;
if (!strcasecmp(argv[c], "range")) {
/******************************************************************/
c++;
range = atoi(argv[c]);
/******************************************************************/
} else {
/******************************************************************/
stream->write_function(stream, "Unknown \"cgb range\" command\n");
goto handle_cli_error;
/******************************************************************/
}
handle_tx_cgb(stream, span, chan, range, verbose);
/**********************************************************************/
} else {
/**********************************************************************/
stream->write_function(stream, "Unknown \"cgb\" command\n");
goto handle_cli_error;
/**********************************************************************/
}
/**************************************************************************/
} else if (!strcasecmp(argv[c], "cgu")) {
/**************************************************************************/
if (check_arg_count(argc, 2)) goto handle_cli_error_argc;
c++;
if (!strcasecmp(argv[c], "span")) {
/**********************************************************************/
if (check_arg_count(argc, 5)) goto handle_cli_error_argc;
if (extract_span_chan(argv, c, &span, &chan)) goto handle_cli_error_span_chan;
c = c + 4;
if (check_arg_count(argc, 7)) goto handle_cli_error_argc;
if (!strcasecmp(argv[c], "range")) {
/******************************************************************/
c++;
range = atoi(argv[c]);
/******************************************************************/
} else {
/******************************************************************/
stream->write_function(stream, "Unknown \"cgu range\" command\n");
goto handle_cli_error;
/******************************************************************/
}
handle_tx_cgu(stream, span, chan, range, verbose);
/**********************************************************************/
} else {
/**********************************************************************/
stream->write_function(stream, "Unknown \"cgu\" command\n");
goto handle_cli_error;
/**********************************************************************/
}
@ -389,7 +496,97 @@ ftdm_status_t ftdm_sngss7_handle_cli_cmd(ftdm_stream_handle_t *stream, const cha
stream->write_function(stream, "Unknown \"grs\" command\n");
goto handle_cli_error;
/**********************************************************************/
}
}
/**************************************************************************/
} else if (!strcasecmp(argv[c], "lpo")) {
/**************************************************************************/
if (check_arg_count(argc, 2)) goto handle_cli_error_argc;
c++;
if (!strcasecmp(argv[c], "link")) {
/**********************************************************************/
if (check_arg_count(argc, 3)) goto handle_cli_error_argc;
c++;
handle_tx_lpo(stream, argv[c]);
/**********************************************************************/
} else {
/**********************************************************************/
stream->write_function(stream, "Unknown \"lpo\" command\n");
goto handle_cli_error;
/**********************************************************************/
}
/**************************************************************************/
} else if (!strcasecmp(argv[c], "lpr")) {
/**************************************************************************/
if (check_arg_count(argc, 2)) goto handle_cli_error_argc;
c++;
if (!strcasecmp(argv[c], "link")) {
/**********************************************************************/
if (check_arg_count(argc, 3)) goto handle_cli_error_argc;
c++;
handle_tx_lpr(stream, argv[c]);
/**********************************************************************/
} else {
/**********************************************************************/
stream->write_function(stream, "Unknown \"lpr\" command\n");
goto handle_cli_error;
/**********************************************************************/
}
/**************************************************************************/
} else if (!strcasecmp(argv[c], "activate")) {
/**************************************************************************/
if (check_arg_count(argc, 2)) goto handle_cli_error_argc;
c++;
if (!strcasecmp(argv[c], "link")) {
/**********************************************************************/
if (check_arg_count(argc, 3)) goto handle_cli_error_argc;
c++;
handle_activate_link(stream, argv[c]);
/**********************************************************************/
}else if (!strcasecmp(argv[c], "linkset")) {
/**********************************************************************/
if (check_arg_count(argc, 3)) goto handle_cli_error_argc;
c++;
handle_activate_linkset(stream, argv[c]);
/**********************************************************************/
} else {
/**********************************************************************/
stream->write_function(stream, "Unknown \"activate\" command\n");
goto handle_cli_error;
/**********************************************************************/
}
/**************************************************************************/
} else if (!strcasecmp(argv[c], "deactivate")) {
/**************************************************************************/
if (check_arg_count(argc, 2)) goto handle_cli_error_argc;
c++;
if (!strcasecmp(argv[c], "link")) {
/**********************************************************************/
if (check_arg_count(argc, 3)) goto handle_cli_error_argc;
c++;
handle_deactivate_link(stream, argv[c]);
/**********************************************************************/
}else if (!strcasecmp(argv[c], "linkset")) {
/**********************************************************************/
if (check_arg_count(argc, 3)) goto handle_cli_error_argc;
c++;
handle_deactivate_linkset(stream, argv[c]);
/**********************************************************************/
} else {
/**********************************************************************/
stream->write_function(stream, "Unknown \"deactivate\" command\n");
goto handle_cli_error;
/**********************************************************************/
}
/**************************************************************************/
} else {
/**************************************************************************/
@ -433,10 +630,22 @@ static ftdm_status_t handle_print_usuage(ftdm_stream_handle_t *stream)
stream->write_function(stream, "ftdm ss7 show inreset span X chan Y\n");
stream->write_function(stream, "\n");
stream->write_function(stream, "Ftmod_sangoma_ss7 circuit control:\n");
stream->write_function(stream, "ftdm ss7 block span X chan Y\n");
stream->write_function(stream, "ftdm ss7 unblk span X chan Y\n");
stream->write_function(stream, "ftdm ss7 blo span X chan Y\n");
stream->write_function(stream, "ftdm ss7 ubl span X chan Y\n");
stream->write_function(stream, "ftdm ss7 rsc span X chan Y\n");
stream->write_function(stream, "ftdm ss7 grs span X chan Y range Z\n");
stream->write_function(stream, "ftdm ss7 cgb span X chan Y range Z\n");
stream->write_function(stream, "ftdm ss7 cgu span X chan Y range Z\n");
stream->write_function(stream, "\n");
stream->write_function(stream, "Ftmod_sangoma_ss7 link control:\n");
stream->write_function(stream, "ftdm ss7 inhibit link X\n");
stream->write_function(stream, "ftdm ss7 uninhibit link X\n");
stream->write_function(stream, "ftdm ss7 activate link X\n");
stream->write_function(stream, "ftdm ss7 deactivate link X\n");
stream->write_function(stream, "ftdm ss7 activate linkset X\n");
stream->write_function(stream, "ftdm ss7 deactivate linkset X\n");
stream->write_function(stream, "ftdm ss7 lpo link X\n");
stream->write_function(stream, "ftdm ss7 lpr link X\n");
stream->write_function(stream, "\n");
return FTDM_SUCCESS;
@ -811,87 +1020,100 @@ static ftdm_status_t handle_show_blocks(ftdm_stream_handle_t *stream, int span,
/******************************************************************************/
static ftdm_status_t handle_show_status(ftdm_stream_handle_t *stream, int span, int chan, int verbose)
{
int x;
sngss7_chan_data_t *ss7_info;
ftdm_channel_t *ftdmchan;
int lspan;
int lchan;
ftdm_signaling_status_t sigstatus = FTDM_SIG_STATE_DOWN;
int x;
sngss7_chan_data_t *ss7_info;
ftdm_channel_t *ftdmchan;
int lspan;
int lchan;
ftdm_signaling_status_t sigstatus = FTDM_SIG_STATE_DOWN;
sng_isup_ckt_t *ckt;
x=1;
while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) {
if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) {
ss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj;
ftdmchan = ss7_info->ftdmchan;
/* extract the circuit to make it easier to work with */
ckt = &g_ftdm_sngss7_data.cfg.isupCkt[x];
/* if span == 0 then all spans should be printed */
if (span == 0) {
lspan = ftdmchan->physical_span_id;
lspan = ckt->span;
} else {
lspan = span;
}
/* if chan == 0 then all chans should be printed */
if (chan == 0) {
lchan = ftdmchan->physical_chan_id;
lchan = ckt->chan;
} else {
lchan = chan;
}
if ((ftdmchan->physical_span_id == lspan) && (ftdmchan->physical_chan_id == lchan)) {
/* grab the signaling_status */
ftdm_channel_get_sig_status(ftdmchan, &sigstatus);
/* check if this circuit is one of the circuits we're interested in */
if ((ckt->span == lspan) && (ckt->chan == lchan)) {
if (ckt->type == HOLE) {
stream->write_function(stream, "span=%2d|chan=%2d|cic=%4d|NOT USED\n",
ckt->span,
ckt->chan,
ckt->cic);
} else if (ckt->type == SIG) {
stream->write_function(stream, "span=%2d|chan=%2d|cic=%4d|SIGNALING LINK\n",
ckt->span,
ckt->chan,
ckt->cic);
} else {
ss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj;
ftdmchan = ss7_info->ftdmchan;
stream->write_function(stream, "span=%2d|chan=%2d|cic=%4d|sig_status=%s|state=%s|",
ftdmchan->physical_span_id,
ftdmchan->physical_chan_id,
ss7_info->circuit->cic,
ftdm_signaling_status2str(sigstatus),
ftdm_channel_state2str(ftdmchan->state));
if((sngss7_test_flag(ss7_info, FLAG_CKT_MN_BLOCK_TX)) || (sngss7_test_flag(ss7_info, FLAG_GRP_MN_BLOCK_TX))) {
stream->write_function(stream, "l_mn=Y|");
}else {
stream->write_function(stream, "l_mn=N|");
}
if((sngss7_test_flag(ss7_info, FLAG_CKT_MN_BLOCK_RX)) || (sngss7_test_flag(ss7_info, FLAG_GRP_MN_BLOCK_RX))) {
stream->write_function(stream, "r_mn=Y|");
}else {
stream->write_function(stream, "r_mn=N|");
}
if(sngss7_test_flag(ss7_info, FLAG_GRP_HW_BLOCK_TX)) {
stream->write_function(stream, "l_hw=Y|");
}else {
stream->write_function(stream, "l_hw=N|");
}
if(sngss7_test_flag(ss7_info, FLAG_GRP_HW_BLOCK_RX)) {
stream->write_function(stream, "r_hw=Y|");
}else {
stream->write_function(stream, "r_hw=N|");
}
if(sngss7_test_flag(ss7_info, FLAG_CKT_LC_BLOCK_RX)) {
stream->write_function(stream, "l_mngmt=Y|");
}else {
stream->write_function(stream, "l_mngmt=N|");
}
if(sngss7_test_flag(ss7_info, FLAG_CKT_UCIC_BLOCK)) {
stream->write_function(stream, "l_ucic=Y|");
}else {
stream->write_function(stream, "l_ucic=N|");
}
stream->write_function(stream, "flags=0x%X",ss7_info->flags);
stream->write_function(stream, "\n");
/* grab the signaling_status */
ftdm_channel_get_sig_status(ftdmchan, &sigstatus);
stream->write_function(stream, "span=%2d|chan=%2d|cic=%4d|sig_status=%s|state=%s|",
ckt->span,
ckt->chan,
ckt->cic,
ftdm_signaling_status2str(sigstatus),
ftdm_channel_state2str(ftdmchan->state));
if((sngss7_test_flag(ss7_info, FLAG_CKT_MN_BLOCK_TX)) || (sngss7_test_flag(ss7_info, FLAG_GRP_MN_BLOCK_TX))) {
stream->write_function(stream, "l_mn=Y|");
}else {
stream->write_function(stream, "l_mn=N|");
}
if((sngss7_test_flag(ss7_info, FLAG_CKT_MN_BLOCK_RX)) || (sngss7_test_flag(ss7_info, FLAG_GRP_MN_BLOCK_RX))) {
stream->write_function(stream, "r_mn=Y|");
}else {
stream->write_function(stream, "r_mn=N|");
}
if(sngss7_test_flag(ss7_info, FLAG_GRP_HW_BLOCK_TX)) {
stream->write_function(stream, "l_hw=Y|");
}else {
stream->write_function(stream, "l_hw=N|");
}
if(sngss7_test_flag(ss7_info, FLAG_GRP_HW_BLOCK_RX)) {
stream->write_function(stream, "r_hw=Y|");
}else {
stream->write_function(stream, "r_hw=N|");
}
if(sngss7_test_flag(ss7_info, FLAG_CKT_LC_BLOCK_RX)) {
stream->write_function(stream, "l_mngmt=Y|");
}else {
stream->write_function(stream, "l_mngmt=N|");
}
if(sngss7_test_flag(ss7_info, FLAG_CKT_UCIC_BLOCK)) {
stream->write_function(stream, "l_ucic=Y|");
}else {
stream->write_function(stream, "l_ucic=N|");
}
stream->write_function(stream, "flags=0x%X",ss7_info->flags);
stream->write_function(stream, "\n");
} /* if ( hole, sig, voice) */
} /* if ( span and chan) */
} /* if ( cic != 0) */
/* go the next circuit */
x++;
} /* while (g_ftdm_sngss7_data.cfg.isupCkt[x]id != 0) */
@ -899,7 +1121,7 @@ static ftdm_status_t handle_show_status(ftdm_stream_handle_t *stream, int span,
return FTDM_SUCCESS;
}
/******************************************************************************/
static ftdm_status_t handle_set_blocks(ftdm_stream_handle_t *stream, int span, int chan, int verbose)
static ftdm_status_t handle_tx_blo(ftdm_stream_handle_t *stream, int span, int chan, int verbose)
{
int x;
sngss7_chan_data_t *ss7_info;
@ -960,7 +1182,7 @@ static ftdm_status_t handle_set_blocks(ftdm_stream_handle_t *stream, int span, i
}
/******************************************************************************/
static ftdm_status_t handle_set_unblks(ftdm_stream_handle_t *stream, int span, int chan, int verbose)
static ftdm_status_t handle_tx_ubl(ftdm_stream_handle_t *stream, int span, int chan, int verbose)
{
int x;
sngss7_chan_data_t *ss7_info;
@ -1154,17 +1376,17 @@ static ftdm_status_t handle_set_uninhibit(ftdm_stream_handle_t *stream, char *na
/******************************************************************************/
static ftdm_status_t handle_tx_rsc(ftdm_stream_handle_t *stream, int span, int chan, int verbose)
{
int x;
sngss7_chan_data_t *ss7_info;
ftdm_channel_t *ftdmchan;
int lspan;
int lchan;
int x;
sngss7_chan_data_t *sngss7_info;
ftdm_channel_t *ftdmchan;
int lspan;
int lchan;
x=1;
while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) {
if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) {
ss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj;
ftdmchan = ss7_info->ftdmchan;
sngss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj;
ftdmchan = sngss7_info->ftdmchan;
/* if span == 0 then all spans should be printed */
if (span == 0) {
@ -1181,27 +1403,31 @@ static ftdm_status_t handle_tx_rsc(ftdm_stream_handle_t *stream, int span, int c
}
if ((ftdmchan->physical_span_id == lspan) && (ftdmchan->physical_chan_id == lchan)) {
/* now that we have the right channel...put a lock on it so no-one else can use it */
/* lock the channel */
ftdm_mutex_lock(ftdmchan->mutex);
/* check if there is a pending state change|give it a bit to clear */
if (check_for_state_change(ftdmchan)) {
SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", ss7_info->circuit->cic);
SS7_ASSERT;
} else {
/* throw the ckt block flag */
sngss7_set_flag(ss7_info, FLAG_RESET_TX);
/* throw the reset flag */
sngss7_set_flag(sngss7_info, FLAG_RESET_TX);
/* set the channel to suspended state */
switch (ftdmchan->state) {
/**************************************************************************/
case FTDM_CHANNEL_STATE_RESTART:
/* go to idle so that we can redo the restart state*/
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_IDLE);
break;
/**************************************************************************/
default:
/* set the state of the channel to restart...the rest is done by the chan monitor */
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
break;
/**************************************************************************/
}
/* unlock the channel again before we exit */
ftdm_mutex_unlock(ftdmchan->mutex);
} /* if ( span and chan) */
} /* if ( cic != 0) */
} /* if ( cic == voice) */
/* go the next circuit */
x++;
@ -1270,6 +1496,331 @@ static ftdm_status_t handle_tx_grs(ftdm_stream_handle_t *stream, int span, int c
return FTDM_SUCCESS;
}
/******************************************************************************/
static ftdm_status_t handle_tx_cgb(ftdm_stream_handle_t *stream, int span, int chan, int range, int verbose)
{
int x;
sngss7_chan_data_t *sngss7_info;
ftdm_channel_t *ftdmchan;
ftdm_channel_t *main_chan = NULL;
sngss7_span_data_t *sngss7_span;
int byte = 0;
int bit = 0;
if (range > 31) {
stream->write_function(stream, "Invalid range value %d", range);
return FTDM_SUCCESS;
}
x=1;
while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) {
if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) {
/* extract the channel and span info for this circuit */
sngss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj;
ftdmchan = sngss7_info->ftdmchan;
sngss7_span = ftdmchan->span->mod_data;
/* check if this circuit is part of the block */
if ((ftdmchan->physical_span_id == span) &&
((ftdmchan->physical_chan_id >= chan) && (ftdmchan->physical_chan_id < (chan+range)))) {
/* now that we have the right channel...put a lock on it so no-one else can use it */
ftdm_mutex_lock(ftdmchan->mutex);
/* throw the grp maint. block flag */
sngss7_set_flag(sngss7_info, FLAG_GRP_MN_BLOCK_TX);
/* if this is the first channel in the range */
if (ftdmchan->physical_chan_id == chan) {
/* attach the cgb information */
main_chan = ftdmchan;
sngss7_span->tx_cgb.circuit = sngss7_info->circuit->id;
sngss7_span->tx_cgb.range = range-1;
sngss7_span->tx_cgb.type = 0; /* maintenace block */
} /* if (ftdmchan->physical_chan_id == chan) */
/* update the status field */
sngss7_span->tx_cgb.status[byte] = (sngss7_span->tx_cgb.status[byte] | (1 << bit));
/* update the bit and byte counter*/
bit ++;
if (bit == 8) {
byte++;
bit = 0;
}
/* unlock the channel again before we exit */
ftdm_mutex_unlock(ftdmchan->mutex);
} /* if ( span and chan) */
} /* if ( cic == voice) */
/* go the next circuit */
x++;
} /* while (g_ftdm_sngss7_data.cfg.isupCkt[x]id != 0) */
/* send the circuit group block */
ft_to_sngss7_cgb(main_chan);
return FTDM_SUCCESS;
}
/******************************************************************************/
static ftdm_status_t handle_tx_cgu(ftdm_stream_handle_t *stream, int span, int chan, int range, int verbose)
{
int x;
sngss7_chan_data_t *sngss7_info;
ftdm_channel_t *ftdmchan;
ftdm_channel_t *main_chan = NULL;
sngss7_span_data_t *sngss7_span;
int byte = 0;
int bit = 0;
if (range > 31) {
stream->write_function(stream, "Invalid range value %d", range);
return FTDM_SUCCESS;
}
x=1;
while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) {
if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) {
/* extract the channel and span info for this circuit */
sngss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj;
ftdmchan = sngss7_info->ftdmchan;
sngss7_span = ftdmchan->span->mod_data;
/* check if this circuit is part of the block */
if ((ftdmchan->physical_span_id == span) &&
((ftdmchan->physical_chan_id >= chan) && (ftdmchan->physical_chan_id < (chan+range)))) {
/* now that we have the right channel...put a lock on it so no-one else can use it */
ftdm_mutex_lock(ftdmchan->mutex);
/* throw the grp maint. block flag */
sngss7_clear_flag(sngss7_info, FLAG_GRP_MN_BLOCK_TX);
/* if this is the first channel in the range */
if (ftdmchan->physical_chan_id == chan) {
/* attach the cgb information */
main_chan = ftdmchan;
sngss7_span->tx_cgu.circuit = sngss7_info->circuit->id;
sngss7_span->tx_cgu.range = range-1;
sngss7_span->tx_cgu.type = 0; /* maintenace block */
} /* if (ftdmchan->physical_chan_id == chan) */
/* update the status field */
sngss7_span->tx_cgu.status[byte] = (sngss7_span->tx_cgu.status[byte] | (1 << bit));
/* update the bit and byte counter*/
bit ++;
if (bit == 8) {
byte++;
bit = 0;
}
/* unlock the channel again before we exit */
ftdm_mutex_unlock(ftdmchan->mutex);
} /* if ( span and chan) */
} /* if ( cic == voice) */
/* go the next circuit */
x++;
} /* while (g_ftdm_sngss7_data.cfg.isupCkt[x]id != 0) */
/* send the circuit group block */
ft_to_sngss7_cgu(main_chan);
return FTDM_SUCCESS;
}
/******************************************************************************/
static ftdm_status_t handle_activate_link(ftdm_stream_handle_t *stream, char *name)
{
int x = 0;
/* find the link request by it's name */
x = 1;
while(g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) {
if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtpLink[x].name, name)) {
/* send the uninhibit request */
if (ftmod_ss7_activate_mtplink(x)) {
stream->write_function(stream, "Failed to activate link=%s\n", name);
return FTDM_FAIL;
}
/* print the new status of the link */
handle_status_link(stream, &name[0]);
goto success;
}
/* move to the next link */
x++;
} /* while (id != 0) */
stream->write_function(stream, "Could not find link=%s\n", name);
success:
return FTDM_SUCCESS;
}
/******************************************************************************/
static ftdm_status_t handle_deactivate_link(ftdm_stream_handle_t *stream, char *name)
{
int x = 0;
/* find the link request by it's name */
x = 1;
while(g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) {
if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtpLink[x].name, name)) {
/* send the deactivate request */
if (ftmod_ss7_deactivate2_mtplink(x)) {
stream->write_function(stream, "Failed to deactivate link=%s\n", name);
return FTDM_FAIL;
}
/* print the new status of the link */
handle_status_link(stream, &name[0]);
goto success;
}
/* move to the next link */
x++;
} /* while (id != 0) */
stream->write_function(stream, "Could not find link=%s\n", name);
success:
return FTDM_SUCCESS;
}
/******************************************************************************/
static ftdm_status_t handle_activate_linkset(ftdm_stream_handle_t *stream, char *name)
{
int x = 0;
/* find the linkset request by it's name */
x = 1;
while(g_ftdm_sngss7_data.cfg.mtpLinkSet[x].id != 0) {
if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtpLinkSet[x].name, name)) {
/* send the activate request */
if (ftmod_ss7_activate_mtplinkSet(x)) {
stream->write_function(stream, "Failed to activate linkset=%s\n", name);
return FTDM_FAIL;
}
/* print the new status of the linkset */
handle_status_linkset(stream, &name[0]);
goto success;
}
/* move to the next linkset */
x++;
} /* while (id != 0) */
stream->write_function(stream, "Could not find linkset=%s\n", name);
success:
return FTDM_SUCCESS;
}
/******************************************************************************/
static ftdm_status_t handle_deactivate_linkset(ftdm_stream_handle_t *stream, char *name)
{
int x = 0;
/* find the linkset request by it's name */
x = 1;
while(g_ftdm_sngss7_data.cfg.mtpLinkSet[x].id != 0) {
if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtpLinkSet[x].name, name)) {
/* send the deactivate request */
if (ftmod_ss7_deactivate2_mtplinkSet(x)) {
stream->write_function(stream, "Failed to deactivate linkset=%s\n", name);
return FTDM_FAIL;
}
/* print the new status of the linkset */
handle_status_linkset(stream, &name[0]);
goto success;
}
/* move to the next linkset */
x++;
} /* while (id != 0) */
stream->write_function(stream, "Could not find linkset=%s\n", name);
success:
return FTDM_SUCCESS;
}
/******************************************************************************/
static ftdm_status_t handle_tx_lpo(ftdm_stream_handle_t *stream, char *name)
{
int x = 0;
/* find the link request by it's name */
x = 1;
while(g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) {
if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtpLink[x].name, name)) {
/* send the uninhibit request */
if (ftmod_ss7_lpo_mtplink(x)) {
stream->write_function(stream, "Failed set LPO link=%s\n", name);
return FTDM_FAIL;
}
/* print the new status of the link */
handle_status_link(stream, &name[0]);
goto success;
}
/* move to the next link */
x++;
} /* while (id != 0) */
stream->write_function(stream, "Could not find link=%s\n", name);
success:
return FTDM_SUCCESS;
}
/******************************************************************************/
static ftdm_status_t handle_tx_lpr(ftdm_stream_handle_t *stream, char *name)
{
int x = 0;
/* find the link request by it's name */
x = 1;
while(g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) {
if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtpLink[x].name, name)) {
/* send the uninhibit request */
if (ftmod_ss7_lpr_mtplink(x)) {
stream->write_function(stream, "Failed set LPR link=%s\n", name);
return FTDM_FAIL;
}
/* print the new status of the link */
handle_status_link(stream, &name[0]);
goto success;
}
/* move to the next link */
x++;
} /* while (id != 0) */
stream->write_function(stream, "Could not find link=%s\n", name);
success:
return FTDM_SUCCESS;
}
/******************************************************************************/
static ftdm_status_t extract_span_chan(char *argv[10], int pos, int *span, int *chan)
{

View File

@ -50,6 +50,17 @@ static int ftmod_ss7_enable_mtpLinkSet(int lnkSetId);
int ftmod_ss7_inhibit_mtplink(uint32_t id);
int ftmod_ss7_uninhibit_mtplink(uint32_t id);
int ftmod_ss7_activate_mtplink(uint32_t id);
int ftmod_ss7_deactivate_mtplink(uint32_t id);
int ftmod_ss7_deactivate2_mtplink(uint32_t id);
int ftmod_ss7_activate_mtplinkSet(uint32_t id);
int ftmod_ss7_deactivate_mtplinkSet(uint32_t id);
int ftmod_ss7_deactivate2_mtplinkSet(uint32_t id);
int ftmod_ss7_lpo_mtplink(uint32_t id);
int ftmod_ss7_lpr_mtplink(uint32_t id);
/******************************************************************************/
/* FUNCTIONS ******************************************************************/
@ -271,6 +282,248 @@ int ftmod_ss7_uninhibit_mtplink(uint32_t id)
return (sng_cntrl_mtp3(&pst, &cntrl));
}
/******************************************************************************/
int ftmod_ss7_activate_mtplink(uint32_t id)
{
SnMngmt cntrl;
Pst pst;
/* initalize the post structure */
smPstInit(&pst);
/* insert the destination Entity */
pst.dstEnt = ENTSN;
/* initalize the control structure */
memset(&cntrl, 0x0, sizeof(SnMngmt));
/* initalize the control header */
smHdrInit(&cntrl.hdr);
cntrl.hdr.msgType = TCNTRL; /* this is a control request */
cntrl.hdr.entId.ent = ENTSN;
cntrl.hdr.entId.inst = S_INST;
cntrl.hdr.elmId.elmnt = STDLSAP;
cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtpLink[id].id;
cntrl.t.cntrl.action = AENA; /* Activate */
cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */
return (sng_cntrl_mtp3(&pst, &cntrl));
}
/******************************************************************************/
int ftmod_ss7_deactivate_mtplink(uint32_t id)
{
SnMngmt cntrl;
Pst pst;
/* initalize the post structure */
smPstInit(&pst);
/* insert the destination Entity */
pst.dstEnt = ENTSN;
/* initalize the control structure */
memset(&cntrl, 0x0, sizeof(SnMngmt));
/* initalize the control header */
smHdrInit(&cntrl.hdr);
cntrl.hdr.msgType = TCNTRL; /* this is a control request */
cntrl.hdr.entId.ent = ENTSN;
cntrl.hdr.entId.inst = S_INST;
cntrl.hdr.elmId.elmnt = STDLSAP;
cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtpLink[id].id;
cntrl.t.cntrl.action = ADISIMM; /* Deactivate */
cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */
return (sng_cntrl_mtp3(&pst, &cntrl));
}
/******************************************************************************/
int ftmod_ss7_deactivate2_mtplink(uint32_t id)
{
SnMngmt cntrl;
Pst pst;
/* initalize the post structure */
smPstInit(&pst);
/* insert the destination Entity */
pst.dstEnt = ENTSN;
/* initalize the control structure */
memset(&cntrl, 0x0, sizeof(SnMngmt));
/* initalize the control header */
smHdrInit(&cntrl.hdr);
cntrl.hdr.msgType = TCNTRL; /* this is a control request */
cntrl.hdr.entId.ent = ENTSN;
cntrl.hdr.entId.inst = S_INST;
cntrl.hdr.elmId.elmnt = STDLSAP;
cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtpLink[id].id;
cntrl.t.cntrl.action = ADISIMM_L2; /* Deactivate...layer 2 only */
cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */
return (sng_cntrl_mtp3(&pst, &cntrl));
}
/******************************************************************************/
int ftmod_ss7_activate_mtplinkSet(uint32_t id)
{
SnMngmt cntrl;
Pst pst;
/* initalize the post structure */
smPstInit(&pst);
/* insert the destination Entity */
pst.dstEnt = ENTSN;
/* initalize the control structure */
memset(&cntrl, 0x0, sizeof(SnMngmt));
/* initalize the control header */
smHdrInit(&cntrl.hdr);
cntrl.hdr.msgType = TCNTRL; /* this is a control request */
cntrl.hdr.entId.ent = ENTSN;
cntrl.hdr.entId.inst = S_INST;
cntrl.hdr.elmId.elmnt = STLNKSET;
cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtpLinkSet[id].id;
cntrl.t.cntrl.action = AACTLNKSET; /* Activate */
cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */
return (sng_cntrl_mtp3(&pst, &cntrl));
}
/******************************************************************************/
int ftmod_ss7_deactivate_mtplinkSet(uint32_t id)
{
SnMngmt cntrl;
Pst pst;
/* initalize the post structure */
smPstInit(&pst);
/* insert the destination Entity */
pst.dstEnt = ENTSN;
/* initalize the control structure */
memset(&cntrl, 0x0, sizeof(SnMngmt));
/* initalize the control header */
smHdrInit(&cntrl.hdr);
cntrl.hdr.msgType = TCNTRL; /* this is a control request */
cntrl.hdr.entId.ent = ENTSN;
cntrl.hdr.entId.inst = S_INST;
cntrl.hdr.elmId.elmnt = STLNKSET;
cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtpLinkSet[id].id;
cntrl.t.cntrl.action = ADEACTLNKSET; /* Activate */
cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */
return (sng_cntrl_mtp3(&pst, &cntrl));
}
/******************************************************************************/
int ftmod_ss7_deactivate2_mtplinkSet(uint32_t id)
{
SnMngmt cntrl;
Pst pst;
/* initalize the post structure */
smPstInit(&pst);
/* insert the destination Entity */
pst.dstEnt = ENTSN;
/* initalize the control structure */
memset(&cntrl, 0x0, sizeof(SnMngmt));
/* initalize the control header */
smHdrInit(&cntrl.hdr);
cntrl.hdr.msgType = TCNTRL; /* this is a control request */
cntrl.hdr.entId.ent = ENTSN;
cntrl.hdr.entId.inst = S_INST;
cntrl.hdr.elmId.elmnt = STLNKSET;
cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtpLinkSet[id].id;
cntrl.t.cntrl.action = ADEACTLNKSET_L2; /* Activate */
cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */
return (sng_cntrl_mtp3(&pst, &cntrl));
}
/******************************************************************************/
int ftmod_ss7_lpo_mtplink(uint32_t id)
{
SnMngmt cntrl;
Pst pst;
/* initalize the post structure */
smPstInit(&pst);
/* insert the destination Entity */
pst.dstEnt = ENTSN;
/* initalize the control structure */
memset(&cntrl, 0x0, sizeof(SnMngmt));
/* initalize the control header */
smHdrInit(&cntrl.hdr);
cntrl.hdr.msgType = TCNTRL; /* this is a control request */
cntrl.hdr.entId.ent = ENTSN;
cntrl.hdr.entId.inst = S_INST;
cntrl.hdr.elmId.elmnt = STDLSAP;
cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtpLink[id].id;
cntrl.t.cntrl.action = ACTION_LPO; /* Activate */
cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */
return (sng_cntrl_mtp3(&pst, &cntrl));
}
/******************************************************************************/
int ftmod_ss7_lpr_mtplink(uint32_t id)
{
SnMngmt cntrl;
Pst pst;
/* initalize the post structure */
smPstInit(&pst);
/* insert the destination Entity */
pst.dstEnt = ENTSN;
/* initalize the control structure */
memset(&cntrl, 0x0, sizeof(SnMngmt));
/* initalize the control header */
smHdrInit(&cntrl.hdr);
cntrl.hdr.msgType = TCNTRL; /* this is a control request */
cntrl.hdr.entId.ent = ENTSN;
cntrl.hdr.entId.inst = S_INST;
cntrl.hdr.elmId.elmnt = STDLSAP;
cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtpLink[id].id;
cntrl.t.cntrl.action = ACTION_LPR; /* Activate */
cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */
return (sng_cntrl_mtp3(&pst, &cntrl));
}
/******************************************************************************/
/******************************************************************************/
/* For Emacs:
* Local Variables:

View File

@ -71,6 +71,8 @@ ftdm_status_t handle_ubl_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circ
ftdm_status_t handle_local_blk(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
ftdm_status_t handle_local_ubl(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
ftdm_status_t handle_ucic(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
ftdm_status_t handle_cgb_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
ftdm_status_t handle_cgu_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
/******************************************************************************/
/* FUNCTIONS ******************************************************************/
@ -80,6 +82,9 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
sngss7_chan_data_t *sngss7_info = NULL;
ftdm_channel_t *ftdmchan = NULL;
char nadi[2];
memset(nadi, '\0', sizeof(nadi));
/* get the ftdmchan and ss7_chan_data from the circuit */
if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
@ -210,7 +215,8 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
}
/* add any special variables for the dialplan */
/*ftdm_channel_add_var(ftdmchan, "ss7_stuff", "s");*/
sprintf(nadi, "%d", siConEvnt->cgPtyNum.natAddrInd.val);
ftdm_channel_add_var(ftdmchan, "ss7_nadi", nadi);
/* set the state of the channel to collecting...the rest is done by the chan monitor */
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_COLLECT);
@ -898,12 +904,12 @@ ftdm_status_t handle_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
/**************************************************************************/
case SIT_STA_CGBREQ: /* CGB request */
SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CGB\n");
SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType));
handle_cgb_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt);
break;
/**************************************************************************/
case SIT_STA_CGUREQ: /* CGU request */
SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CGU\n");
SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType));
handle_cgu_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt);
break;
/**************************************************************************/
case SIT_STA_CGQRYREQ: /* circuit group query request */
@ -913,12 +919,12 @@ ftdm_status_t handle_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
/**************************************************************************/
case SIT_STA_CGBRSP: /* mntc. oriented CGB response */
SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx mntc CGB\n");
SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType));
/*handle_cgb_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt);*/
break;
/**************************************************************************/
case SIT_STA_CGURSP: /* mntc. oriented CGU response */
SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx mntc CGU\n");
SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType));
/*SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType));*/
break;
/**************************************************************************/
case SIT_STA_GRSREQ: /* circuit group reset request */
@ -1012,13 +1018,13 @@ ftdm_status_t handle_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
break;
/**************************************************************************/
case SIT_STA_CGBINFOIND: /* circuit grp blking ind , no resp req */
SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CGB no resp req\n");
SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType));
/*SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CGB no resp req\n");*/
/* handle_cgb_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt);*/
break;
/**************************************************************************/
case SIT_STA_LMCQMINFOREQ: /* when LM requests ckt grp query */
SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx LM CQM\n");
SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType));
// SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType));
break;
/**************************************************************************/
case SIT_STA_CIRLOCGRS: /* group reset initiated locally by the software */
@ -1121,21 +1127,10 @@ ftdm_status_t handle_pause(uint32_t suInstId, uint32_t spInstId, uint32_t circui
/* lock the channel */
ftdm_mutex_lock(ftdmchan->mutex);
/* check if there is a pending state change, give it a bit to clear */
if (check_for_state_change(ftdmchan)) {
SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic);
ftdm_mutex_unlock(ftdmchan->mutex);
i++;
SS7_ASSERT;
};
/* check if the circuit is fully started */
if (ftdm_test_flag(ftdmchan->span, FTDM_SPAN_IN_THREAD)) {
/* set the pause flag on the channel */
sngss7_set_flag(sngss7_info, FLAG_INFID_PAUSED);
/* set the statet o SUSPENDED to bring the sig status down */
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED);
}
/* unlock the channel again before we exit */
@ -1183,14 +1178,6 @@ ftdm_status_t handle_resume(uint32_t suInstId, uint32_t spInstId, uint32_t circu
/* lock the channel */
ftdm_mutex_lock(ftdmchan->mutex);
/* check if there is a pending state change, give it a bit to clear */
if (check_for_state_change(ftdmchan)) {
SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic);
ftdm_mutex_unlock(ftdmchan->mutex);
i++;
SS7_ASSERT;
};
/* only resume if we are paused */
if (sngss7_test_flag(sngss7_info, FLAG_INFID_PAUSED)) {
/* set the resume flag on the channel */
@ -1198,9 +1185,6 @@ ftdm_status_t handle_resume(uint32_t suInstId, uint32_t spInstId, uint32_t circu
/* clear the paused flag */
sngss7_clear_flag(sngss7_info, FLAG_INFID_PAUSED);
/* set the statet to SUSPENDED to bring the sig status up */
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED);
}
/* unlock the channel again before we exit */
@ -1713,6 +1697,7 @@ ftdm_status_t handle_grs_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ
/* loop over the cics starting from circuit until range+1 */
for (x = circuit; x < (circuit + range + 1); x++) {
if (g_ftdm_sngss7_data.cfg.isupCkt[x].type != VOICE) continue;
/* grab the circuit in question */
if (extract_chan_data(x, &sngss7_info, &ftdmchan)) {
SS7_ERROR("Failed to extract channel data for circuit = %d!\n", x);
@ -1989,6 +1974,267 @@ ftdm_status_t handle_ucic(uint32_t suInstId, uint32_t spInstId, uint32_t circuit
return FTDM_SUCCESS;
}
/******************************************************************************/
ftdm_status_t handle_cgb_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt)
{
SS7_FUNC_TRACE_ENTER(__FUNCTION__);
sngss7_chan_data_t *sngss7_info = NULL;
sngss7_span_data_t *sngss7_span = NULL;
ftdm_channel_t *ftdmchan = NULL;
int range;
uint8_t status[255];
int blockType = 0;
int byte = 0;
int bit = 0;
int x;
memset(&status[0], '\0', sizeof(status));
/* get the ftdmchan and ss7_chan_data from the circuit */
if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
return FTDM_FAIL;
}
/* grab the span info */
sngss7_span = ftdmchan->span->mod_data;
/* figure out what type of block needs to be applied */
if ((siStaEvnt->cgsmti.eh.pres == PRSNT_NODEF) && (siStaEvnt->cgsmti.typeInd.pres == PRSNT_NODEF)) {
blockType = siStaEvnt->cgsmti.typeInd.val;
} else {
SS7_ERROR("Received CGB with no circuit group supervision value on CIC = %d\n", sngss7_info->circuit->cic);
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
return FTDM_FAIL;
}
/* pull out the range value */
if ((siStaEvnt->rangStat.eh.pres == PRSNT_NODEF) && (siStaEvnt->rangStat.range.pres == PRSNT_NODEF)) {
range = siStaEvnt->rangStat.range.val;
} else {
SS7_ERROR("Received CGB with no range value on CIC = %d\n", sngss7_info->circuit->cic);
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
return FTDM_FAIL;
}
/* pull out the status field */
if ((siStaEvnt->rangStat.eh.pres == PRSNT_NODEF) && (siStaEvnt->rangStat.status.pres == PRSNT_NODEF)) {
for (x = 0; x < siStaEvnt->rangStat.status.len; x++) {
status[x] = siStaEvnt->rangStat.status.val[x];
}
} else {
SS7_ERROR("Received CGB with no status value on CIC = %d\n", sngss7_info->circuit->cic);
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
return FTDM_FAIL;
}
/* save the circuit, range and status */
sngss7_span->rx_cgb.circuit = circuit;
sngss7_span->rx_cgb.range = range;
sngss7_span->rx_cgb.type = blockType;
for (x = 0; x < siStaEvnt->rangStat.status.len; x++) {
sngss7_span->rx_cgb.status[x] = status[x];
}
/* loop over the cics starting from circuit until range+1 */
for (x = circuit; x < (circuit + range + 1); x++) {
if (g_ftdm_sngss7_data.cfg.isupCkt[x].type != VOICE) continue;
/* grab the circuit in question */
if (extract_chan_data(x, &sngss7_info, &ftdmchan)) {
SS7_ERROR("Failed to extract channel data for circuit = %d!\n", x);
break;
}
/* now that we have the right channel...put a lock on it so no-one else can use it */
ftdm_mutex_lock(ftdmchan->mutex);
/* check if there is a pending state change, give it a bit to clear */
if (check_for_state_change(ftdmchan)) {
SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic);
ftdm_mutex_unlock(ftdmchan->mutex);
SS7_ASSERT;
};
#if 0
SS7_ERROR("KONRAD -> circuit=%d, byte=%d, bit=%d, status[byte]=%d, math=%d\n",
x,
byte,
bit,
status[byte],
(status[byte] & (1 << bit)));
#endif
if (status[byte] & (1 << bit)) {
switch (blockType) {
/**********************************************************************/
case 0: /* maintenance oriented */
sngss7_set_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX);
break;
/**********************************************************************/
case 1: /* hardware failure oriented */
sngss7_set_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX);
break;
/**********************************************************************/
case 2: /* reserved for national use */
break;
/**********************************************************************/
default:
break;
/**********************************************************************/
} /* switch (blockType) */
}
/* unlock the channel again before we exit */
ftdm_mutex_unlock(ftdmchan->mutex);
/* update the bit and byte counter*/
bit ++;
if (bit == 8) {
byte++;
bit = 0;
}
} /* for (x = circuit; x < (circuit + range + 1); x++) */
/* get the ftdmchan and ss7_chan_data from the circuit */
if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
return FTDM_FAIL;
}
ft_to_sngss7_cgba(ftdmchan);
return FTDM_SUCCESS;
}
/******************************************************************************/
ftdm_status_t handle_cgu_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt)
{
SS7_FUNC_TRACE_ENTER(__FUNCTION__);
sngss7_chan_data_t *sngss7_info = NULL;
sngss7_span_data_t *sngss7_span = NULL;
ftdm_channel_t *ftdmchan = NULL;
int range;
uint8_t status[255];
int blockType = 0;
int byte = 0;
int bit = 0;
int x;
memset(&status[0], '\0', sizeof(status));
/* get the ftdmchan and ss7_chan_data from the circuit */
if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
return FTDM_FAIL;
}
/* grab the span info */
sngss7_span = ftdmchan->span->mod_data;
/* figure out what type of block needs to be applied */
if ((siStaEvnt->cgsmti.eh.pres == PRSNT_NODEF) && (siStaEvnt->cgsmti.typeInd.pres == PRSNT_NODEF)) {
blockType = siStaEvnt->cgsmti.typeInd.val;
} else {
SS7_ERROR("Received CGB with no circuit group supervision value on CIC = %d\n", sngss7_info->circuit->cic);
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
return FTDM_FAIL;
}
/* pull out the range value */
if ((siStaEvnt->rangStat.eh.pres == PRSNT_NODEF) && (siStaEvnt->rangStat.range.pres == PRSNT_NODEF)) {
range = siStaEvnt->rangStat.range.val;
} else {
SS7_ERROR("Received CGB with no range value on CIC = %d\n", sngss7_info->circuit->cic);
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
return FTDM_FAIL;
}
/* pull out the status field */
if ((siStaEvnt->rangStat.eh.pres == PRSNT_NODEF) && (siStaEvnt->rangStat.status.pres == PRSNT_NODEF)) {
for (x = 0; x < siStaEvnt->rangStat.status.len; x++) {
status[x] = siStaEvnt->rangStat.status.val[x];
}
} else {
SS7_ERROR("Received CGB with no status value on CIC = %d\n", sngss7_info->circuit->cic);
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
return FTDM_FAIL;
}
/* save the circuit, range and status */
sngss7_span->rx_cgu.circuit = circuit;
sngss7_span->rx_cgu.range = range;
sngss7_span->rx_cgu.type = blockType;
for (x = 0; x < siStaEvnt->rangStat.status.len; x++) {
sngss7_span->rx_cgu.status[x] = status[x];
}
/* loop over the cics starting from circuit until range+1 */
for (x = circuit; x < (circuit + range + 1); x++) {
if (g_ftdm_sngss7_data.cfg.isupCkt[x].type != VOICE) continue;
/* grab the circuit in question */
if (extract_chan_data(x, &sngss7_info, &ftdmchan)) {
SS7_ERROR("Failed to extract channel data for circuit = %d!\n", x);
break;
}
/* now that we have the right channel...put a lock on it so no-one else can use it */
ftdm_mutex_lock(ftdmchan->mutex);
/* check if there is a pending state change, give it a bit to clear */
if (check_for_state_change(ftdmchan)) {
SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic);
ftdm_mutex_unlock(ftdmchan->mutex);
SS7_ASSERT;
};
if (status[byte] & (1 << bit)) {
switch (blockType) {
/**********************************************************************/
case 0: /* maintenance oriented */
sngss7_clear_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX);
break;
/**********************************************************************/
case 1: /* hardware failure oriented */
sngss7_clear_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX);
break;
/**********************************************************************/
case 2: /* reserved for national use */
break;
/**********************************************************************/
default:
break;
/**********************************************************************/
} /* switch (blockType) */
} /* */
/* unlock the channel again before we exit */
ftdm_mutex_unlock(ftdmchan->mutex);
/* update the bit and byte counter*/
bit ++;
if (bit == 8) {
byte++;
bit = 0;
}
} /* for (x = circuit; x < (circuit + range + 1); x++) */
/* get the ftdmchan and ss7_chan_data from the circuit */
if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
return FTDM_FAIL;
}
ft_to_sngss7_cgua(ftdmchan);
return FTDM_SUCCESS;
}
/******************************************************************************/
/* For Emacs:

View File

@ -109,6 +109,10 @@ void handle_sng_mtp1_alarm(Pst *pst, L1Mngmt *sta)
/******************************************************************************/
void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta)
{
char buf[50];
int x = 1;
memset(buf, '\0', sizeof(buf));
switch (sta->t.usta.alarm.category) {
/**************************************************************************/
@ -126,23 +130,39 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta)
case (LSD_EVENT_REMOTE_CONG_END):
case (LSD_EVENT_RX_REMOTE_SIPO):
/* find the name for the sap in question */
x = 1;
while (g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) {
if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == sta->t.usta.evntParm[0]) {
break;
}
x++;
}
if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == 0) {
sprintf(buf, "[SAPID:%d]", sta->t.usta.evntParm[0]);
} else {
sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtpLink[x].name);
}
switch (sta->t.usta.alarm.cause) {
/******************************************************************/
case (LCM_CAUSE_UNKNOWN):
ftdm_log(FTDM_LOG_ERROR,"[MTP2][SAPID:%d] %s\n",
sta->t.usta.evntParm[0],
ftdm_log(FTDM_LOG_ERROR,"[MTP2]%s %s\n",
buf,
DECODE_LSD_EVENT(sta->t.usta.alarm.event));
break;
/******************************************************************/
case (LCM_CAUSE_MGMT_INITIATED):
ftdm_log(FTDM_LOG_ERROR,"[MTP2][SAPID:%d][MGMT] %s\n",
sta->t.usta.evntParm[0],
ftdm_log(FTDM_LOG_ERROR,"[MTP2]%s[MGMT] %s\n",
buf,
DECODE_LSD_EVENT(sta->t.usta.alarm.event));
break;
/******************************************************************/
default:
ftdm_log(FTDM_LOG_ERROR,"[MTP2][SAPID:%d] %s (***unknown cause***)\n",
sta->t.usta.evntParm[0],
ftdm_log(FTDM_LOG_ERROR,"[MTP2]%s %s (***unknown cause***)\n",
buf,
DECODE_LSD_EVENT(sta->t.usta.alarm.event));
break;
/******************************************************************/
@ -150,23 +170,71 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta)
break;
/**********************************************************************/
case (LSD_EVENT_PROT_ERR):
ftdm_log(FTDM_LOG_ERROR,"[MTP2][SAPID:%d] %s : %s\n",
sta->t.usta.evntParm[0],
/* find the name for the sap in question */
x = 1;
while (g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) {
if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == sta->t.usta.evntParm[0]) {
break;
}
x++;
}
if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == 0) {
sprintf(buf, "[SAPID:%d]", sta->t.usta.evntParm[0]);
} else {
sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtpLink[x].name);
}
ftdm_log(FTDM_LOG_ERROR,"[MTP2]%s %s : %s\n",
buf,
DECODE_LSD_EVENT(sta->t.usta.alarm.event),
DECODE_LSD_CAUSE(sta->t.usta.alarm.cause));
break;
/**********************************************************************/
case (LSD_EVENT_ALIGN_LOST):
ftdm_log(FTDM_LOG_ERROR,"[MTP2][SAPID:%d] %s : %s\n",
sta->t.usta.evntParm[0],
/* find the name for the sap in question */
x = 1;
while (g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) {
if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == sta->t.usta.evntParm[0]) {
break;
}
x++;
}
if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == 0) {
sprintf(buf, "[SAPID:%d]", sta->t.usta.evntParm[0]);
} else {
sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtpLink[x].name);
}
ftdm_log(FTDM_LOG_ERROR,"[MTP2]%s %s : %s\n",
buf,
DECODE_LSD_EVENT(sta->t.usta.alarm.event),
DECODE_DISC_REASON(sta->t.usta.evntParm[1]));
break;
/**********************************************************************/
case (LSD_EVENT_RTB_FULL):
case (LSD_EVENT_RTB_FULL_OVER):
ftdm_log(FTDM_LOG_ERROR,"[MTP2][SAPID:%d] %s : RTB Queue Len(%d)|Oldest BSN(%d)|Tx Queue Len(%d)|Outstanding Frames(%d)\n",
sta->t.usta.evntParm[0],
/* find the name for the sap in question */
x = 1;
while (g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) {
if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == sta->t.usta.evntParm[0]) {
break;
}
x++;
}
if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == 0) {
sprintf(buf, "[SAPID:%d]", sta->t.usta.evntParm[0]);
} else {
sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtpLink[x].name);
}
ftdm_log(FTDM_LOG_ERROR,"[MTP2]%s %s : RTB Queue Len(%d)|Oldest BSN(%d)|Tx Queue Len(%d)|Outstanding Frames(%d)\n",
buf,
DECODE_LSD_EVENT(sta->t.usta.alarm.event),
sta->t.usta.evntParm[1],
sta->t.usta.evntParm[2],
@ -175,15 +243,47 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta)
break;
/**********************************************************************/
case (LSD_EVENT_NEG_ACK):
ftdm_log(FTDM_LOG_ERROR,"[MTP2][SAPID:%d] %s : RTB Queue Len(%d)\n",
sta->t.usta.evntParm[0],
/* find the name for the sap in question */
x = 1;
while (g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) {
if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == sta->t.usta.evntParm[0]) {
break;
}
x++;
}
if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == 0) {
sprintf(buf, "[SAPID:%d]", sta->t.usta.evntParm[0]);
} else {
sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtpLink[x].name);
}
ftdm_log(FTDM_LOG_ERROR,"[MTP2]%s %s : RTB Queue Len(%d)\n",
buf,
DECODE_LSD_EVENT(sta->t.usta.alarm.event),
sta->t.usta.evntParm[1]);
break;
/**********************************************************************/
case (LSD_EVENT_DAT_CFM_SDT):
ftdm_log(FTDM_LOG_ERROR,"[MTP2][SAPID:%d] %s : %d\n",
sta->t.usta.evntParm[0],
/* find the name for the sap in question */
x = 1;
while (g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) {
if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == sta->t.usta.evntParm[0]) {
break;
}
x++;
}
if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == 0) {
sprintf(buf, "[SAPID:%d]", sta->t.usta.evntParm[0]);
} else {
sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtpLink[x].name);
}
ftdm_log(FTDM_LOG_ERROR,"[MTP2]%s %s : %d\n",
buf,
DECODE_LSD_EVENT(sta->t.usta.alarm.event),
DECODE_DISC_REASON(sta->t.usta.evntParm[1]));
break;
@ -251,15 +351,35 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta)
/******************************************************************************/
void handle_sng_mtp3_alarm(Pst *pst, SnMngmt *sta)
{
char buf[50];
int x = 1;
memset(buf, '\0', sizeof(buf));
switch (sta->hdr.elmId.elmnt) {
/**************************************************************************/
case (STDLSAP):
/* find the name for the sap in question */
x = 1;
while (g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) {
if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == sta->hdr.elmId.elmntInst1) {
break;
}
x++;
}
if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == 0) {
sprintf(buf, "[SAPID:%d]", sta->hdr.elmId.elmntInst1);
} else {
sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtpLink[x].name);
}
switch (sta->t.usta.alarm.event) {
/**********************************************************************/
case (LSN_EVENT_INV_OPC_OTHER_END):
ftdm_log(FTDM_LOG_ERROR,"[MTP3][SAPID:%d] %s : %s : OPC(0x%X%X%X%X)\n",
sta->hdr.elmId.elmntInst1,
ftdm_log(FTDM_LOG_ERROR,"[MTP3]%s %s : %s : OPC(0x%X%X%X%X)\n",
buf,
DECODE_LSN_EVENT(sta->t.usta.alarm.event),
DECODE_LSN_CAUSE(sta->t.usta.alarm.cause),
sta->t.usta.evntParm[3],
@ -269,16 +389,16 @@ void handle_sng_mtp3_alarm(Pst *pst, SnMngmt *sta)
break;
/**********************************************************************/
case (LSN_EVENT_INV_SLC_OTHER_END):
ftdm_log(FTDM_LOG_ERROR,"[MTP3][SAPID:%d] %s : %s : SLC(%d)\n",
sta->hdr.elmId.elmntInst1,
ftdm_log(FTDM_LOG_ERROR,"[MTP3]%s %s : %s : SLC(%d)\n",
buf,
DECODE_LSN_EVENT(sta->t.usta.alarm.event),
DECODE_LSN_CAUSE(sta->t.usta.alarm.cause),
sta->t.usta.evntParm[0]);
break;
/**********************************************************************/
default:
ftdm_log(FTDM_LOG_ERROR,"[MTP3][SAPID:%d] %s(%d) : %s(%d)\n",
sta->hdr.elmId.elmntInst1,
ftdm_log(FTDM_LOG_ERROR,"[MTP3]%s %s(%d) : %s(%d)\n",
buf,
DECODE_LSN_EVENT(sta->t.usta.alarm.event),
sta->t.usta.alarm.event,
DECODE_LSN_CAUSE(sta->t.usta.alarm.cause),
@ -303,13 +423,53 @@ void handle_sng_mtp3_alarm(Pst *pst, SnMngmt *sta)
break;
/**************************************************************************/
case (STROUT):
ftdm_log(FTDM_LOG_ERROR,"[MTP3][DPC:0x%d%d%d%d] %s : %s\n",
sta->t.usta.evntParm[0],
sta->t.usta.evntParm[1],
sta->t.usta.evntParm[2],
sta->t.usta.evntParm[3],
DECODE_LSN_EVENT(sta->t.usta.alarm.event),
DECODE_LSN_CAUSE(sta->t.usta.alarm.cause));
switch (sta->t.usta.alarm.event) {
/**********************************************************************/
case (LSN_EVENT_RX_TRANSFER_MSG):
switch (sta->t.usta.evntParm[5]) {
/******************************************************************/
case (0x23):
ftdm_log(FTDM_LOG_INFO,"[MTP3] Rx SNM TFC\n");
break;
/******************************************************************/
case (0x34):
ftdm_log(FTDM_LOG_INFO,"[MTP3] Rx SNM TFR\n");
break;
/******************************************************************/
case (0x54):
ftdm_log(FTDM_LOG_INFO,"[MTP3] Rx SNM TFA\n");
break;
/******************************************************************/
case (0x14):
ftdm_log(FTDM_LOG_INFO,"[MTP3] Rx SNM TFP\n");
break;
/******************************************************************/
case (0x24):
ftdm_log(FTDM_LOG_INFO,"[MTP3] Rx SNM TFP (cluster)\n");
break;
/******************************************************************/
case (0x64):
ftdm_log(FTDM_LOG_INFO,"[MTP3] Rx SNM TFA (cluster)\n");
break;
/******************************************************************/
case (0x44):
ftdm_log(FTDM_LOG_INFO,"[MTP3] Rx SNM TFR (cluster)\n");
break;
/******************************************************************/
} /* switch (sta->t.usta.evntParm[5]) */
break;
/**********************************************************************/
default:
ftdm_log(FTDM_LOG_ERROR,"[MTP3][DPC:0x%d%d%d%d] %s : %s\n",
sta->t.usta.evntParm[0],
sta->t.usta.evntParm[1],
sta->t.usta.evntParm[2],
sta->t.usta.evntParm[3],
DECODE_LSN_EVENT(sta->t.usta.alarm.event),
DECODE_LSN_CAUSE(sta->t.usta.alarm.cause));
break;
/**********************************************************************/
} /* switch (sta->t.usta.alarm.event) */
break;
/**************************************************************************/
default:

View File

@ -272,10 +272,8 @@ static void *ftdm_sangoma_ss7_run(ftdm_thread_t * me, void *obj)
ftdm_interrupt_t *ftdm_sangoma_ss7_int[2];
ftdm_span_t *ftdmspan = (ftdm_span_t *) obj;
ftdm_channel_t *ftdmchan = NULL;
sngss7_chan_data_t *sngss7_info = NULL;
sngss7_event_data_t *sngss7_event = NULL;
sngss7_span_data_t *sngss7_span = (sngss7_span_data_t *)ftdmspan->mod_data;
int i;
ftdm_log (FTDM_LOG_INFO, "ftmod_sangoma_ss7 monitor thread for span=%u started.\n", ftdmspan->span_id);
@ -344,73 +342,14 @@ static void *ftdm_sangoma_ss7_run(ftdm_thread_t * me, void *obj)
/**********************************************************************/
} /* switch ((ftdm_interrupt_wait(ftdm_sangoma_ss7_int, 100))) */
/* extract the span data structure */
sngss7_span = (sngss7_span_data_t *)ftdmspan->mod_data;
/* check if there is a GRS being processed on the span */
if (sngss7_span->rx_grs.range > 0) {
ftdm_log(FTDM_LOG_DEBUG, "Found Rx GRS on span %d...checking circuits\n", ftdmspan->span_id);
/*SS7_DEBUG("Found Rx GRS on span %d...checking circuits\n", ftdmspan->span_id);*/
/* check if the rx_grs has cleared */
check_if_rx_grs_processed(ftdmspan);
} /* if (sngss7_span->rx_grs.range > 0) */
/* check all the circuits in the range to see if they are done resetting */
for ( i = sngss7_span->rx_grs.circuit; i < (sngss7_span->rx_grs.circuit + sngss7_span->rx_grs.range + 1); i++) {
/* extract the channel in question */
if (extract_chan_data(i, &sngss7_info, &ftdmchan)) {
SS7_ERROR("Failed to extract channel data for circuit = %d!\n", i);
SS7_ASSERT;
}
/* lock the channel */
ftdm_mutex_lock(ftdmchan->mutex);
/* check if there is a state change pending on the channel */
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
/* check the state to the GRP_RESET_RX_DN flag */
if (!sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX_DN)) {
/* this channel is still resetting...do nothing */
goto GRS_UNLOCK_ALL;
} /* if (!sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX_DN)) */
} else {
/* state change pending */
goto GRS_UNLOCK_ALL;
}
} /* for ( i = circuit; i < (circuit + range + 1); i++) */
SS7_DEBUG("All circuits out of reset for GRS: circuit=%d, range=%d\n",
sngss7_span->rx_grs.circuit,
sngss7_span->rx_grs.range);
/* check all the circuits in the range to see if they are done resetting */
for ( i = sngss7_span->rx_grs.circuit; i < (sngss7_span->rx_grs.circuit + sngss7_span->rx_grs.range + 1); i++) {
/* extract the channel in question */
if (extract_chan_data(i, &sngss7_info, &ftdmchan)) {
SS7_ERROR("Failed to extract channel data for circuit = %d!\n",i);
SS7_ASSERT;
}
/* throw the GRP reset flag complete flag */
sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_RX_CMPLT);
/* move the channel to the down state */
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
} /* for ( i = circuit; i < (circuit + range + 1); i++) */
GRS_UNLOCK_ALL:
for ( i = sngss7_span->rx_grs.circuit; i < (sngss7_span->rx_grs.circuit + sngss7_span->rx_grs.range + 1); i++) {
/* extract the channel in question */
if (extract_chan_data(i, &sngss7_info, &ftdmchan)) {
SS7_ERROR("Failed to extract channel data for circuit = %d!\n", i);
SS7_ASSERT;
}
/* unlock the channel */
ftdm_mutex_unlock(ftdmchan->mutex);
}
} /* if (ftdmspan->grs.range > 0) */
/* check each channel on the span to see if there is an un-procressed SUS/RES flag */
check_for_res_sus_flag(ftdmspan);
} /* master while loop */
/* clear the IN_THREAD flag so that we know the thread is done */
@ -544,14 +483,17 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
i++;
}
/* check if the end of pulsing character has arrived or the right number of digits */
if (ftdmchan->caller_data.dnis.digits[i] == 0xF) {
/* check if the end of pulsing (ST) character has arrived or the right number of digits */
if (ftdmchan->caller_data.dnis.digits[i-1] == 'F') {
SS7_DEBUG_CHAN(ftdmchan, "Received the end of pulsing character %s\n", "");
/* remove the ST */
ftdmchan->caller_data.dnis.digits[i-1] = '\0';
/*now go to the RING state */
ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_RING);
} else if (i >= g_ftdm_sngss7_data.min_digits) {
} else if (i > g_ftdm_sngss7_data.min_digits) {
SS7_DEBUG_CHAN(ftdmchan, "Received %d digits (min digits = %d)\n", i, g_ftdm_sngss7_data.min_digits);
/*now go to the RING state */
@ -1012,30 +954,41 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
SS7_DEBUG_CHAN(ftdmchan,"Current flags: 0x%X\n", sngss7_info->flags);
/**********************************************************************/
if (sngss7_test_flag (sngss7_info, FLAG_INFID_PAUSED)) {
SS7_DEBUG_CHAN(ftdmchan, "Processing PAUSE flag %s\n", "");
/* bring the channel signaling status to down */
sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
sigev.sigstatus = FTDM_SIG_STATE_DOWN;
ftdm_span_send_signal (ftdmchan->span, &sigev);
if (sngss7_test_flag(sngss7_info, FLAG_INFID_RESUME)) {
/* check the last state and return to it to allow the call to finish */
goto suspend_goto_last;
}
if (sngss7_test_flag (sngss7_info, FLAG_INFID_RESUME)) {
SS7_DEBUG_CHAN(ftdmchan, "Processing RESUME flag %s\n", "");
/* the reset flag is set for the first channel in the span at handle_resume */
/* clear the resume flag */
/* clear the RESUME flag */
sngss7_clear_flag(sngss7_info, FLAG_INFID_RESUME);
/* go to restart state */
goto suspend_goto_last;
}
/* if there are any resets present */
if ((sngss7_test_flag (sngss7_info, FLAG_RESET_TX)) ||
(sngss7_test_flag (sngss7_info, FLAG_RESET_RX)) ||
(sngss7_test_flag (sngss7_info, FLAG_GRP_RESET_TX)) ||
(sngss7_test_flag (sngss7_info, FLAG_GRP_RESET_RX))) {
/* go back to the reset state */
goto suspend_goto_restart;
} else {
/* bring the sig status back up */
sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
sigev.sigstatus = FTDM_SIG_STATE_UP;
ftdm_span_send_signal(ftdmchan->span, &sigev);
}
/* go back to the last state */
goto suspend_goto_last;
} /* if (sngss7_test_flag(sngss7_info, FLAG_INFID_RESUME)) */
if (sngss7_test_flag(sngss7_info, FLAG_INFID_PAUSED)) {
/* bring the sig status down */
sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
sigev.sigstatus = FTDM_SIG_STATE_DOWN;
ftdm_span_send_signal(ftdmchan->span, &sigev);
/* go back to the last state */
goto suspend_goto_last;
} /* if (sngss7_test_flag(sngss7_info, FLAG_INFID_PAUSED)) { */
/**********************************************************************/
if (sngss7_test_flag (sngss7_info, FLAG_CKT_MN_BLOCK_RX)) {
SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_MN_BLOCK_RX flag %s\n", "");
@ -1304,6 +1257,7 @@ static ftdm_status_t ftdm_sangoma_ss7_start(ftdm_span_t * span)
for (x = 1; x < (span->chan_count + 1); x++) {
/* extract the channel structure and sngss7 channel data */
ftdmchan = span->channels[x];
if (ftdmchan->call_data == NULL) continue;
sngss7_info = ftdmchan->call_data;
sngss7_span = ftdmchan->span->mod_data;
@ -1312,7 +1266,7 @@ static ftdm_status_t ftdm_sangoma_ss7_start(ftdm_span_t * span)
/* throw the pause flag */
sngss7_set_flag(sngss7_info, FLAG_INFID_PAUSED);
#if 0
/* throw the grp reset flag */
sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX);
if (x == 1) {
@ -1320,7 +1274,10 @@ static ftdm_status_t ftdm_sangoma_ss7_start(ftdm_span_t * span)
sngss7_span->tx_grs.circuit = sngss7_info->circuit->id;
sngss7_span->tx_grs.range = span->chan_count -1;
}
#else
/* throw the channel into reset */
sngss7_set_flag(sngss7_info, FLAG_RESET_TX);
#endif
/* throw the channel to suspend */
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED);
@ -1454,6 +1411,8 @@ static FIO_SIG_LOAD_FUNCTION(ftdm_sangoma_ss7_init)
sngss7_id = 0;
cmbLinkSetId = 1;
/* initalize the global gen_config flag */
g_ftdm_sngss7_data.gen_config = 0;

View File

@ -139,7 +139,6 @@ typedef struct sng_mtp_link {
uint32_t t23;
uint32_t t24;
uint32_t t25;
uint32_t t26;
uint32_t t27;
uint32_t t28;
uint32_t t29;
@ -163,6 +162,8 @@ typedef struct sng_link_set {
uint32_t flags;
uint32_t apc;
uint32_t linkType;
uint32_t switchType;
uint32_t ssf;
uint32_t minActive;
uint32_t numLinks;
uint32_t links[16];
@ -174,9 +175,11 @@ typedef struct sng_route {
uint32_t flags;
uint32_t dpc;
uint32_t cmbLinkSetId;
uint32_t linkSetId;
uint32_t linkType;
uint32_t switchType;
uint32_t ssf;
uint32_t nwId;
uint32_t isSTP;
uint32_t t6;
uint32_t t8;
@ -188,6 +191,7 @@ typedef struct sng_route {
uint32_t t19;
uint32_t t21;
uint32_t t25;
uint32_t t26;
} sng_route_t;
typedef struct sng_isup_intf {
@ -329,6 +333,8 @@ typedef struct sngss7_glare_data {
typedef struct sngss7_group_data {
uint32_t circuit;
uint32_t range;
uint8_t status[255];
uint8_t type;
}sngss7_group_data_t;
typedef struct sngss7_chan_data {
@ -348,6 +354,10 @@ typedef struct sngss7_span_data {
ftdm_sched_t *sched;
sngss7_group_data_t rx_grs;
sngss7_group_data_t tx_grs;
sngss7_group_data_t rx_cgb;
sngss7_group_data_t tx_cgb;
sngss7_group_data_t rx_cgu;
sngss7_group_data_t tx_cgu;
ftdm_queue_t *event_queue;
}sngss7_span_data_t;
@ -376,8 +386,8 @@ typedef struct sngss7_event_data
typedef enum {
FLAG_RESET_RX = (1 << 0),
FLAG_RESET_TX = (1 << 1),
FLAG_RESET_RX = (1 << 0),
FLAG_RESET_TX = (1 << 1),
FLAG_RESET_SENT = (1 << 2),
FLAG_RESET_TX_RSP = (1 << 3),
FLAG_GRP_RESET_RX = (1 << 4),
@ -387,27 +397,25 @@ typedef enum {
FLAG_GRP_RESET_TX = (1 << 8),
FLAG_GRP_RESET_SENT = (1 << 9),
FLAG_GRP_RESET_TX_RSP = (1 << 10),
FLAG_REMOTE_REL = (1 << 11),
FLAG_LOCAL_REL = (1 << 12),
FLAG_GLARE = (1 << 13),
FLAG_INFID_RESUME = (1 << 14),
FLAG_INFID_PAUSED = (1 << 15),
FLAG_REMOTE_REL = (1 << 11),
FLAG_LOCAL_REL = (1 << 12),
FLAG_GLARE = (1 << 13),
FLAG_INFID_RESUME = (1 << 14),
FLAG_INFID_PAUSED = (1 << 15),
FLAG_CKT_UCIC_BLOCK = (1 << 16),
FLAG_CKT_UCIC_UNBLK = (1 << 17),
FLAG_CKT_LC_BLOCK_RX = (1 << 18),
FLAG_CKT_LC_UNBLK_RX = (1 << 19),
FLAG_CKT_MN_BLOCK_RX = (1 << 20),
FLAG_CKT_MN_BLOCK_TX = (1 << 21),
FLAG_CKT_MN_UNBLK_RX = (1 << 22),
FLAG_CKT_MN_UNBLK_RX = (1 << 21),
FLAG_CKT_MN_BLOCK_TX = (1 << 22),
FLAG_CKT_MN_UNBLK_TX = (1 << 23),
FLAG_GRP_HW_BLOCK_RX = (1 << 24),
FLAG_GRP_HW_BLOCK_TX = (1 << 25),
FLAG_GRP_MN_BLOCK_RX = (1 << 26),
FLAG_GRP_MN_BLOCK_TX = (1 << 27),
FLAG_GRP_HW_UNBLK_RX = (1 << 28),
FLAG_GRP_HW_UNBLK_TX = (1 << 29),
FLAG_GRP_MN_UNBLK_RX = (1 << 30),
FLAG_GRP_MN_UNBLK_TX = (1 << 31)
FLAG_GRP_HW_UNBLK_TX = (1 << 28),
FLAG_GRP_MN_UNBLK_TX = (1 << 29)
} flag_t;
/******************************************************************************/
@ -415,6 +423,7 @@ typedef enum {
extern ftdm_sngss7_data_t g_ftdm_sngss7_data;
extern uint32_t sngss7_id;
extern ftdm_sched_t *sngss7_sched;
extern int cmbLinkSetId;
/******************************************************************************/
/* PROTOTYPES *****************************************************************/
@ -445,6 +454,14 @@ int ftmod_ss7_cc_isap_config(int id);
int ftmod_ss7_inhibit_mtplink(uint32_t id);
int ftmod_ss7_uninhibit_mtplink(uint32_t id);
int ftmod_ss7_activate_mtplink(uint32_t id);
int ftmod_ss7_deactivate_mtplink(uint32_t id);
int ftmod_ss7_deactivate2_mtplink(uint32_t id);
int ftmod_ss7_activate_mtplinkSet(uint32_t id);
int ftmod_ss7_deactivate_mtplinkSet(uint32_t id);
int ftmod_ss7_deactivate2_mtplinkSet(uint32_t id);
int ftmod_ss7_lpo_mtplink(uint32_t id);
int ftmod_ss7_lpr_mtplink(uint32_t id);
int ftmod_ss7_mtplink_sta(uint32_t id, SnMngmt *cfm);
int ftmod_ss7_mtplinkSet_sta(uint32_t id, SnMngmt *cfm);
@ -465,6 +482,10 @@ void ft_to_sngss7_uba(ftdm_channel_t *ftdmchan);
void ft_to_sngss7_lpa(ftdm_channel_t *ftdmchan);
void ft_to_sngss7_gra(ftdm_channel_t *ftdmchan);
void ft_to_sngss7_grs(ftdm_channel_t *ftdmchan);
void ft_to_sngss7_cgba(ftdm_channel_t * ftdmchan);
void ft_to_sngss7_cgua(ftdm_channel_t * ftdmchan);
void ft_to_sngss7_cgb(ftdm_channel_t * ftdmchan);
void ft_to_sngss7_cgu(ftdm_channel_t * ftdmchan);
void sngss7_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
void sngss7_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt);
@ -524,6 +545,9 @@ int ftmod_ss7_parse_xml(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *spa
void handle_isup_t35(void *userdata);
ftdm_status_t ftdm_sngss7_handle_cli_cmd(ftdm_stream_handle_t *stream, const char *data);
ftdm_status_t check_if_rx_grs_processed(ftdm_span_t *ftdmspan);
ftdm_status_t check_for_res_sus_flag(ftdm_span_t *ftdmspan);
/******************************************************************************/
/* MACROS *********************************************************************/

View File

@ -42,24 +42,30 @@
/******************************************************************************/
/* PROTOTYPES *****************************************************************/
void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan);
void ft_to_sngss7_acm (ftdm_channel_t * ftdmchan);
void ft_to_sngss7_anm (ftdm_channel_t * ftdmchan);
void ft_to_sngss7_rel (ftdm_channel_t * ftdmchan);
void ft_to_sngss7_rlc (ftdm_channel_t * ftdmchan);
void ft_to_sngss7_iam(ftdm_channel_t * ftdmchan);
void ft_to_sngss7_acm(ftdm_channel_t * ftdmchan);
void ft_to_sngss7_anm(ftdm_channel_t * ftdmchan);
void ft_to_sngss7_rel(ftdm_channel_t * ftdmchan);
void ft_to_sngss7_rlc(ftdm_channel_t * ftdmchan);
void ft_to_sngss7_rsc (ftdm_channel_t * ftdmchan);
void ft_to_sngss7_rsca (ftdm_channel_t * ftdmchan);
void ft_to_sngss7_rsc(ftdm_channel_t * ftdmchan);
void ft_to_sngss7_rsca(ftdm_channel_t * ftdmchan);
void ft_to_sngss7_blo (ftdm_channel_t * ftdmchan);
void ft_to_sngss7_bla (ftdm_channel_t * ftdmchan);
void ft_to_sngss7_ubl (ftdm_channel_t * ftdmchan);
void ft_to_sngss7_uba (ftdm_channel_t * ftdmchan);
void ft_to_sngss7_blo(ftdm_channel_t * ftdmchan);
void ft_to_sngss7_bla(ftdm_channel_t * ftdmchan);
void ft_to_sngss7_ubl(ftdm_channel_t * ftdmchan);
void ft_to_sngss7_uba(ftdm_channel_t * ftdmchan);
void ft_to_sngss7_lpa (ftdm_channel_t * ftdmchan);
void ft_to_sngss7_lpa(ftdm_channel_t * ftdmchan);
void ft_to_sngss7_gra (ftdm_channel_t * ftdmchan);
void ft_to_sngss7_grs (ftdm_channel_t * ftdmchan);
void ft_to_sngss7_gra(ftdm_channel_t * ftdmchan);
void ft_to_sngss7_grs(ftdm_channel_t * ftdmchan);
void ft_to_sngss7_cgb(ftdm_channel_t * ftdmchan);
void ft_to_sngss7_cgu(ftdm_channel_t * ftdmchan);
void ft_to_sngss7_cgba(ftdm_channel_t * ftdmchan);
void ft_to_sngss7_cgua(ftdm_channel_t * ftdmchan);
/******************************************************************************/
/* FUNCTIONS ******************************************************************/
@ -67,8 +73,9 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan)
{
SS7_FUNC_TRACE_ENTER (__FUNCTION__);
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;;
SiConEvnt iam;
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;;
const char *nadi = NULL;
SiConEvnt iam;
sngss7_info->suInstId = get_unique_id ();
sngss7_info->spInstId = 0;
@ -98,7 +105,7 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan)
iam.fwdCallInd.isdnUsrPrtInd.pres = PRSNT_NODEF;
iam.fwdCallInd.isdnUsrPrtInd.val = ISUP_USED;
iam.fwdCallInd.isdnUsrPrtPrfInd.pres = PRSNT_NODEF;
iam.fwdCallInd.isdnUsrPrtPrfInd.val = PREF_REQAW;
iam.fwdCallInd.isdnUsrPrtPrfInd.val = PREF_PREFAW;
iam.fwdCallInd.isdnAccInd.pres = PRSNT_NODEF;
iam.fwdCallInd.isdnAccInd.val = ISDNACC_ISDN;
iam.fwdCallInd.sccpMethInd.pres = PRSNT_NODEF;
@ -113,21 +120,88 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan)
iam.txMedReq.eh.pres = PRSNT_NODEF;
iam.txMedReq.trMedReq.pres = PRSNT_NODEF;
iam.txMedReq.trMedReq.val = ftdmchan->caller_data.bearer_capability;
if ((g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId].switchType == LSI_SW_ANS88) ||
(g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId].switchType == LSI_SW_ANS92) ||
(g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId].switchType == LSI_SW_ANS95)) {
/* include only if we're running ANSI */
iam.fwdCallInd.transCallNInd.pres = PRSNT_NODEF;
iam.fwdCallInd.transCallNInd.val = 0x0;
iam.usrServInfoA.eh.pres = PRSNT_NODEF;
iam.usrServInfoA.infoTranCap.pres = PRSNT_NODEF;
switch (ftdmchan->caller_data.bearer_capability) {
/**********************************************************************/
case (FTDM_BEARER_CAP_SPEECH):
iam.usrServInfoA.infoTranCap.val = 0x0; /* speech as per ATIS-1000113.3.2005 */
break;
/**********************************************************************/
case (FTDM_BEARER_CAP_64K_UNRESTRICTED):
iam.usrServInfoA.infoTranCap.val = 0x8; /* unrestricted digital as per ATIS-1000113.3.2005 */
break;
/**********************************************************************/
case (FTDM_BEARER_CAP_3_1KHZ_AUDIO):
iam.usrServInfoA.infoTranCap.val = 0x10; /* 3.1kHz audio as per ATIS-1000113.3.2005 */
break;
/**********************************************************************/
default:
SS7_ERROR_CHAN(ftdmchan, "Unknown Bearer capability falling back to speech%s\n", " ");
iam.usrServInfoA.infoTranCap.val = 0x0; /* speech as per ATIS-1000113.3.2005 */
break;
/**********************************************************************/
} /* switch (ftdmchan->caller_data.bearer_capability) */
iam.usrServInfoA.cdeStand.pres = PRSNT_NODEF;
iam.usrServInfoA.cdeStand.val = 0x0; /* ITU-T standardized coding */
iam.usrServInfoA.tranMode.pres = PRSNT_NODEF;
iam.usrServInfoA.tranMode.val = 0x0; /* circuit mode */
iam.usrServInfoA.infoTranRate0.pres = PRSNT_NODEF;
iam.usrServInfoA.infoTranRate0.val = 0x10; /* 64kbps origination to destination */
iam.usrServInfoA.infoTranRate1.pres = PRSNT_NODEF;
iam.usrServInfoA.infoTranRate1.val = 0x10; /* 64kbps destination to origination */
iam.usrServInfoA.chanStruct.pres = PRSNT_NODEF;
iam.usrServInfoA.chanStruct.val = 0x1; /* 8kHz integrity */
iam.usrServInfoA.config.pres = PRSNT_NODEF;
iam.usrServInfoA.config.val = 0x0; /* point to point configuration */
iam.usrServInfoA.establish.pres = PRSNT_NODEF;
iam.usrServInfoA.establish.val = 0x0; /* on demand */
iam.usrServInfoA.symmetry.pres = PRSNT_NODEF;
iam.usrServInfoA.symmetry.val = 0x0; /* bi-directional symmetric */
iam.usrServInfoA.usrInfLyr1Prot.pres = PRSNT_NODEF;
iam.usrServInfoA.usrInfLyr1Prot.val = 0x2; /* G.711 ulaw */
iam.usrServInfoA.rateMultiplier.pres = PRSNT_NODEF;
iam.usrServInfoA.rateMultiplier.val = 0x1; /* 1x rate multipler */
} /* if ANSI */
/* copy down the called number information */
copy_cdPtyNum_to_sngss7 (&ftdmchan->caller_data, &iam.cdPtyNum);
/* copy down the calling number information */
copy_cgPtyNum_to_sngss7 (&ftdmchan->caller_data, &iam.cgPtyNum);
copy_cgPtyNum_to_sngss7 (&ftdmchan->caller_data, &iam.cgPtyNum);
/* check if the user would like a custom NADI value for the calling Pty Num */
nadi = ftdm_channel_get_var(ftdmchan, "ss7_nadi");
if ((nadi != NULL) && (*nadi)) {
SS7_DEBUG_CHAN(ftdmchan,"Found user supplied NADI value \"%s\"\n", nadi);
iam.cgPtyNum.natAddrInd.val = atoi(nadi);
} else {
SS7_DEBUG_CHAN(ftdmchan,"No user supplied NADI value found, using \"3\" %s\n", " ");
iam.cgPtyNum.natAddrInd.val = 0x03;
}
sng_cc_con_request (sngss7_info->spId,
sngss7_info->suInstId,
sngss7_info->spInstId,
sngss7_info->circuit->id,
&iam,
0);
SS7_MSG_TRACE(ftdmchan, sngss7_info, "Tx IAM\n");
SS7_INFO_CHAN(ftdmchan,"Tx IAM clg = \"%s\", cld = \"%s\"\n",
ftdmchan->caller_data.cid_num.digits,
ftdmchan->caller_data.dnis.digits);
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
return;
@ -144,29 +218,29 @@ void ft_to_sngss7_acm (ftdm_channel_t * ftdmchan)
memset (&acm, 0x0, sizeof (acm));
/* fill in the needed information for the ACM */
acm.bckCallInd.eh.pres = PRSNT_NODEF;
acm.bckCallInd.chrgInd.pres = PRSNT_NODEF;
acm.bckCallInd.chrgInd.val = 0x00;
acm.bckCallInd.cadPtyStatInd.pres = PRSNT_NODEF;
acm.bckCallInd.cadPtyStatInd.val = 0x01;
acm.bckCallInd.cadPtyCatInd.pres = PRSNT_NODEF;
acm.bckCallInd.cadPtyCatInd.val = 0x00;
acm.bckCallInd.end2EndMethInd.pres = PRSNT_NODEF;
acm.bckCallInd.end2EndMethInd.val = 0x00;
acm.bckCallInd.intInd.pres = PRSNT_NODEF;
acm.bckCallInd.intInd.val = 0x00;
acm.bckCallInd.end2EndInfoInd.pres = PRSNT_NODEF;
acm.bckCallInd.end2EndInfoInd.val = 0x00;
acm.bckCallInd.isdnUsrPrtInd.pres = PRSNT_NODEF;
acm.bckCallInd.isdnUsrPrtInd.val = 0x0;
acm.bckCallInd.holdInd.pres = PRSNT_NODEF;
acm.bckCallInd.holdInd.val = 0x00;
acm.bckCallInd.isdnAccInd.pres = PRSNT_NODEF;
acm.bckCallInd.isdnAccInd.val = 0x0;
acm.bckCallInd.echoCtrlDevInd.pres = PRSNT_NODEF;
acm.bckCallInd.echoCtrlDevInd.val = 0x0;
acm.bckCallInd.sccpMethInd.pres = PRSNT_NODEF;
acm.bckCallInd.sccpMethInd.val = 0x00;
acm.bckCallInd.eh.pres = PRSNT_NODEF;
acm.bckCallInd.chrgInd.pres = PRSNT_NODEF;
acm.bckCallInd.chrgInd.val = CHRG_CHRG;
acm.bckCallInd.cadPtyStatInd.pres = PRSNT_NODEF;
acm.bckCallInd.cadPtyStatInd.val = 0x01;
acm.bckCallInd.cadPtyCatInd.pres = PRSNT_NODEF;
acm.bckCallInd.cadPtyCatInd.val = CADCAT_ORDSUBS;
acm.bckCallInd.end2EndMethInd.pres = PRSNT_NODEF;
acm.bckCallInd.end2EndMethInd.val = E2EMTH_NOMETH;
acm.bckCallInd.intInd.pres = PRSNT_NODEF;
acm.bckCallInd.intInd.val = INTIND_NOINTW;
acm.bckCallInd.end2EndInfoInd.pres = PRSNT_NODEF;
acm.bckCallInd.end2EndInfoInd.val = E2EINF_NOINFO;
acm.bckCallInd.isdnUsrPrtInd.pres = PRSNT_NODEF;
acm.bckCallInd.isdnUsrPrtInd.val = ISUP_USED;
acm.bckCallInd.holdInd.pres = PRSNT_NODEF;
acm.bckCallInd.holdInd.val = HOLD_NOTREQD;
acm.bckCallInd.isdnAccInd.pres = PRSNT_NODEF;
acm.bckCallInd.isdnAccInd.val = ISDNACC_NONISDN;
acm.bckCallInd.echoCtrlDevInd.pres = PRSNT_NODEF;
acm.bckCallInd.echoCtrlDevInd.val = 0x1; /* ec device present */
acm.bckCallInd.sccpMethInd.pres = PRSNT_NODEF;
acm.bckCallInd.sccpMethInd.val = SCCPMTH_NOIND;
/* send the ACM request to LibSngSS7 */
sng_cc_con_status (1,
@ -463,7 +537,7 @@ void ft_to_sngss7_grs (ftdm_channel_t * ftdmchan)
SiStaEvnt grs;
memset (&grs, 0x0, sizeof (grs));
memset (&grs, 0x0, sizeof(grs));
grs.rangStat.eh.pres = PRSNT_NODEF;
grs.rangStat.range.pres = PRSNT_NODEF;
@ -485,6 +559,201 @@ void ft_to_sngss7_grs (ftdm_channel_t * ftdmchan)
return;
}
/******************************************************************************/
void ft_to_sngss7_cgba(ftdm_channel_t * ftdmchan)
{
SS7_FUNC_TRACE_ENTER (__FUNCTION__);
sngss7_span_data_t *sngss7_span = ftdmchan->span->mod_data;
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
int x = 0;
SiStaEvnt cgba;
memset (&cgba, 0x0, sizeof(cgba));
/* fill in the circuit group supervisory message */
cgba.cgsmti.eh.pres = PRSNT_NODEF;
cgba.cgsmti.typeInd.pres = PRSNT_NODEF;
cgba.cgsmti.typeInd.val = sngss7_span->rx_cgb.type;
cgba.rangStat.eh.pres = PRSNT_NODEF;
/* fill in the range */
cgba.rangStat.range.pres = PRSNT_NODEF;
cgba.rangStat.range.val = sngss7_span->rx_cgb.range;
/* fill in the status */
cgba.rangStat.status.pres = PRSNT_NODEF;
cgba.rangStat.status.len = ((sngss7_span->rx_cgb.range + 1) >> 3) + (((sngss7_span->rx_cgb.range + 1) & 0x07) ? 1 : 0);
for(x = 0; x < cgba.rangStat.status.len; x++){
cgba.rangStat.status.val[x] = sngss7_span->rx_cgb.status[x];
}
sng_cc_sta_request (1,
0,
0,
sngss7_span->rx_cgb.circuit,
0,
SIT_STA_CGBRSP,
&cgba);
SS7_INFO_CHAN(ftdmchan, "Tx CGBA (%d:%d)\n",
sngss7_info->circuit->cic,
(sngss7_info->circuit->cic + sngss7_span->rx_cgb.range));
/* clean out the saved data */
memset(&sngss7_span->rx_cgb, 0x0, sizeof(sngss7_group_data_t));
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
return;
}
/******************************************************************************/
void ft_to_sngss7_cgua(ftdm_channel_t * ftdmchan)
{
SS7_FUNC_TRACE_ENTER (__FUNCTION__);
sngss7_span_data_t *sngss7_span = ftdmchan->span->mod_data;
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
int x = 0;
SiStaEvnt cgua;
memset (&cgua, 0x0, sizeof(cgua));
/* fill in the circuit group supervisory message */
cgua.cgsmti.eh.pres = PRSNT_NODEF;
cgua.cgsmti.typeInd.pres = PRSNT_NODEF;
cgua.cgsmti.typeInd.val = sngss7_span->rx_cgu.type;
cgua.rangStat.eh.pres = PRSNT_NODEF;
/* fill in the range */
cgua.rangStat.range.pres = PRSNT_NODEF;
cgua.rangStat.range.val = sngss7_span->rx_cgu.range;
/* fill in the status */
cgua.rangStat.status.pres = PRSNT_NODEF;
cgua.rangStat.status.len = ((sngss7_span->rx_cgu.range + 1) >> 3) + (((sngss7_span->rx_cgu.range + 1) & 0x07) ? 1 : 0);
for(x = 0; x < cgua.rangStat.status.len; x++){
cgua.rangStat.status.val[x] = sngss7_span->rx_cgu.status[x];
}
sng_cc_sta_request (1,
0,
0,
sngss7_span->rx_cgu.circuit,
0,
SIT_STA_CGURSP,
&cgua);
SS7_INFO_CHAN(ftdmchan, "Tx CGUA (%d:%d)\n",
sngss7_info->circuit->cic,
(sngss7_info->circuit->cic + sngss7_span->rx_cgu.range));
/* clean out the saved data */
memset(&sngss7_span->rx_cgu, 0x0, sizeof(sngss7_group_data_t));
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
return;
}
/******************************************************************************/
void ft_to_sngss7_cgb(ftdm_channel_t * ftdmchan)
{
SS7_FUNC_TRACE_ENTER (__FUNCTION__);
sngss7_span_data_t *sngss7_span = ftdmchan->span->mod_data;
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
SiStaEvnt cgb;
int x = 0;
memset (&cgb, 0x0, sizeof(cgb));
/* fill in the circuit group supervisory message */
cgb.cgsmti.eh.pres = PRSNT_NODEF;
cgb.cgsmti.typeInd.pres = PRSNT_NODEF;
cgb.cgsmti.typeInd.val = sngss7_span->tx_cgb.type;
/* fill in the range */
cgb.rangStat.eh.pres = PRSNT_NODEF;
cgb.rangStat.range.pres = PRSNT_NODEF;
cgb.rangStat.range.val = sngss7_span->tx_cgb.range;
/* fill in the status */
cgb.rangStat.status.pres = PRSNT_NODEF;
cgb.rangStat.status.len = ((sngss7_span->tx_cgb.range + 1) >> 3) + (((sngss7_span->tx_cgb.range + 1) & 0x07) ? 1 : 0);
for(x = 0; x < cgb.rangStat.status.len; x++){
cgb.rangStat.status.val[x] = sngss7_span->tx_cgb.status[x];
}
sng_cc_sta_request (1,
0,
0,
sngss7_span->tx_cgb.circuit,
0,
SIT_STA_CGBREQ,
&cgb);
SS7_INFO_CHAN(ftdmchan, "Tx CGB (%d:%d)\n",
sngss7_info->circuit->cic,
(sngss7_info->circuit->cic + sngss7_span->tx_cgb.range));
/* clean out the saved data */
memset(&sngss7_span->tx_cgb, 0x0, sizeof(sngss7_group_data_t));
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
return;
}
/******************************************************************************/
void ft_to_sngss7_cgu(ftdm_channel_t * ftdmchan)
{
SS7_FUNC_TRACE_ENTER (__FUNCTION__);
sngss7_span_data_t *sngss7_span = ftdmchan->span->mod_data;
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
SiStaEvnt cgu;
int x = 0;
memset (&cgu, 0x0, sizeof(cgu));
/* fill in the circuit group supervisory message */
cgu.cgsmti.eh.pres = PRSNT_NODEF;
cgu.cgsmti.typeInd.pres = PRSNT_NODEF;
cgu.cgsmti.typeInd.val = sngss7_span->tx_cgu.type;
/* fill in the range */
cgu.rangStat.eh.pres = PRSNT_NODEF;
cgu.rangStat.range.pres = PRSNT_NODEF;
cgu.rangStat.range.val = sngss7_span->tx_cgu.range;
/* fill in the status */
cgu.rangStat.status.pres = PRSNT_NODEF;
cgu.rangStat.status.len = ((sngss7_span->tx_cgu.range + 1) >> 3) + (((sngss7_span->tx_cgu.range + 1) & 0x07) ? 1 : 0);
for(x = 0; x < cgu.rangStat.status.len; x++){
cgu.rangStat.status.val[x] = sngss7_span->tx_cgu.status[x];
}
sng_cc_sta_request (1,
0,
0,
sngss7_span->tx_cgu.circuit,
0,
SIT_STA_CGUREQ,
&cgu);
SS7_INFO_CHAN(ftdmchan, "Tx CGU (%d:%d)\n",
sngss7_info->circuit->cic,
(sngss7_info->circuit->cic + sngss7_span->tx_cgu.range));
/* clean out the saved data */
memset(&sngss7_span->tx_cgu, 0x0, sizeof(sngss7_group_data_t));
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
return;
}
/******************************************************************************/
/* For Emacs:
* Local Variables:

View File

@ -68,7 +68,7 @@ int ftmod_ss7_mtplinkSet_sta(uint32_t id, SnMngmt *cfm)
sta.hdr.elmId.elmnt = STLNKSET;
sta.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtpLinkSet[id].id;
sta.hdr.elmId.elmntInst2 = 1;
sta.hdr.elmId.elmntInst2 = g_ftdm_sngss7_data.cfg.mtpLinkSet[id].links[0];
return(sng_sta_mtp3(&sta, cfm));
}

View File

@ -57,6 +57,8 @@ unsigned long get_unique_id(void);
ftdm_status_t extract_chan_data(uint32_t circuit, sngss7_chan_data_t **sngss7_info, ftdm_channel_t **ftdmchan);
ftdm_status_t check_if_rx_grs_processed(ftdm_span_t *ftdmspan);
ftdm_status_t check_for_res_sus_flag(ftdm_span_t *ftdmspan);
/******************************************************************************/
/* FUNCTIONS ******************************************************************/
@ -72,9 +74,10 @@ uint8_t copy_cgPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum)
int k;
int j;
int flag;
int odd;
char tmp[2];
unsigned char lower;
unsigned char upper;
uint8_t lower;
uint8_t upper;
/**************************************************************************/
cgPtyNum->eh.pres = PRSNT_NODEF;
@ -104,81 +107,73 @@ uint8_t copy_cgPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum)
k = 0;
j = 0;
flag = 0;
odd = 0;
upper = 0x0;
lower = 0x0;
while (1) {
/* grab a digit from the ftdm digits */
tmp[0] = ftdm->cid_num.digits[k];
/* check if the digit is a number and that is not null */
while (!(isdigit(tmp[0])) && (tmp[0] != '\0')) {
/* move on to the next value */
k++;
tmp[0] = ftdm->cid_num.digits[k];
} /* while(!(isdigit(tmp))) */
/* check if tmp is null or a digit */
if (tmp[0] != '\0') {
if (isdigit(tmp[0])) {
lower = atoi(&tmp[0]);
/* push it into the lower nibble */
lower = atoi(&tmp[0]);
/* move to the next digit */
k++;
/* grab a digit from the ftdm digits */
tmp[0] = ftdm->cid_num.digits[k];
/* check if the digit is a number and that is not null */
while (!(isdigit(tmp[0])) && (tmp[0] != '\0')) {
k++;
tmp[0] = ftdm->cid_num.digits[k];
} else {
while (!(isdigit(tmp[0])) && (tmp[0] != '\0')) {
k++;
tmp[0] = ftdm->cid_num.digits[k];
} /* while(!(isdigit(tmp))) */
} /* while(!(isdigit(tmp))) */
if (tmp[0] != '\0') {
lower = atoi(&tmp[0]);
k++;
tmp[0] = ftdm->cid_num.digits[k];
} else {
flag = 1;
lower = 0xf;
} /* if (tmp != '\0') */
} /* (isdigit(tmp)) */
} else {
flag = 1;
lower = 0xf;
} /* if (tmp != '\0') */
tmp[0] = ftdm->cid_num.digits[k];
if (tmp[0] != '\0') {
if (isdigit(tmp[0])) {
/* check if tmp is null or a digit */
if (tmp[0] != '\0') {
/* push the digit into the upper nibble */
upper = (atoi(&tmp[0])) << 4;
} else {
while (!(isdigit(tmp[0])) && (tmp[0] != '\0')) {
k++;
tmp[0] = ftdm->cid_num.digits[k];
} /* while(!(isdigit(tmp))) */
if (tmp[0] != '\0') {
upper = (atoi(&tmp[0])) << 4;
k++;
} else {
flag = 1;
upper = 0xf;
} /* if (tmp != '\0') */
} /* if (isdigit(tmp)) */
} else {
if (flag == 1) {
/* there is no upper ... fill in 0 */
upper = 0x0;
} else {
/* throw the odd flag */
odd = 1;
/* throw the end flag */
flag = 1;
upper = 0xf;
} /* if (flag == 1) */
} /* if (tmp != '\0') */
} /* if (tmp != '\0') */
} else {
/* keep the odd flag down */
odd = 0;
/* throw the flag */
flag = 1;
}
/* push the digits into the trillium structure */
cgPtyNum->addrSig.val[j] = upper | lower;
/* increment the trillium pointer */
j++;
if (flag) {
break;
} else {
k++;
}
/* if the flag is up we're through all the digits */
if (flag) break;
/* move to the next digit */
k++;
} /* while(1) */
cgPtyNum->addrSig.len = j;
/**************************************************************************/
cgPtyNum->oddEven.pres = PRSNT_NODEF;
cgPtyNum->oddEven.val = ((cgPtyNum->addrSig.val[j] >> 4) == 0x0 ) ? 0x01 : 0x00;
cgPtyNum->oddEven.val = odd;
/**************************************************************************/
return 0;
}
@ -196,9 +191,10 @@ uint8_t copy_cdPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCdPtyNum *cdPtyNum)
int k;
int j;
int flag;
int odd;
char tmp[2];
unsigned char lower;
unsigned char upper;
uint8_t lower;
uint8_t upper;
/**************************************************************************/
cdPtyNum->eh.pres = PRSNT_NODEF;
@ -217,77 +213,74 @@ uint8_t copy_cdPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCdPtyNum *cdPtyNum)
/* atoi will search through memory starting from the pointer it is given until
* it finds the \0...since tmp is on the stack it will start going through the
* possibly causing corruption. Hard code a \0 to prevent this
*/
*/ /* dnis */
tmp[1] = '\0';
k = 0;
j = 0;
flag = 0;
odd = 0;
upper = 0x0;
lower = 0x0;
while (1) {
/* grab a digit from the ftdm digits */
tmp[0] = ftdm->dnis.digits[k];
/* check if the digit is a number and that is not null */
while (!(isdigit(tmp[0])) && (tmp[0] != '\0')) {
/* move on to the next value */
k++;
tmp[0] = ftdm->dnis.digits[k];
} /* while(!(isdigit(tmp))) */
/* check if tmp is null or a digit */
if (tmp[0] != '\0') {
if (isdigit(tmp[0])) {
lower = atoi(&tmp[0]);
/* push it into the lower nibble */
lower = atoi(&tmp[0]);
/* move to the next digit */
k++;
/* grab a digit from the ftdm digits */
tmp[0] = ftdm->dnis.digits[k];
/* check if the digit is a number and that is not null */
while (!(isdigit(tmp[0])) && (tmp[0] != '\0')) {
k++;
tmp[0] = ftdm->dnis.digits[k];
} else {
while (!(isdigit(tmp[0])) && (tmp[0] != '\0')) {
k++;
tmp[0] = ftdm->dnis.digits[k];
} /* while(!(isdigit(tmp))) */
} /* while(!(isdigit(tmp))) */
if (tmp[0] != '\0') {
lower = atoi(&tmp[0]);
k++;
tmp[0] = ftdm->dnis.digits[k];
} else {
flag = 1;
lower = 0xf;
} /* if (tmp != '\0') */
} /* (isdigit(tmp)) */
} else {
flag = 1;
lower = 0xf;
} /* if (tmp != '\0') */
tmp[0] = ftdm->dnis.digits[k];
if (tmp[0] != '\0') {
if (isdigit(tmp[0])) {
/* check if tmp is null or a digit */
if (tmp[0] != '\0') {
/* push the digit into the upper nibble */
upper = (atoi(&tmp[0])) << 4;
} else {
while (!(isdigit(tmp[0])) && (tmp[0] != '\0')) {
k++;
tmp[0] = ftdm->dnis.digits[k];
} /* while(!(isdigit(tmp))) */
if (tmp[0] != '\0') {
upper = (atoi(&tmp[0])) << 4;
k++;
} else {
flag = 1;
upper = 0xf;
} /* if (tmp != '\0') */
} /* if (isdigit(tmp)) */
} else {
if (flag == 1) {
upper = 0x0;
} else {
/* there is no upper ... fill in ST */
upper = 0xF;
/* throw the odd flag */
odd = 1;
/* throw the end flag */
flag = 1;
upper = 0xf;
} /* if (flag == 1) */
} /* if (tmp != '\0') */
} /* if (tmp != '\0') */
} else {
/* keep the odd flag down */
odd = 1;
/* need to add the ST */
lower = 0xF;
upper = 0x0;
/* throw the flag */
flag = 1;
}
/* push the digits into the trillium structure */
cdPtyNum->addrSig.val[j] = upper | lower;
/* increment the trillium pointer */
j++;
if (flag) {
break;
} else {
k++;
}
/* if the flag is up we're through all the digits */
if (flag) break;
/* move to the next digit */
k++;
} /* while(1) */
cdPtyNum->addrSig.len = j;
@ -295,7 +288,7 @@ uint8_t copy_cdPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCdPtyNum *cdPtyNum)
/**************************************************************************/
cdPtyNum->oddEven.pres = PRSNT_NODEF;
cdPtyNum->oddEven.val = ((cdPtyNum->addrSig.val[j] >> 4) == 0x0 ) ? 0x01 : 0x00;
cdPtyNum->oddEven.val = odd;
/**************************************************************************/
return 0;
@ -313,9 +306,9 @@ uint8_t copy_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven)
j = 0;
for (i = 0; i < str.len; i++) {
sprintf(&ftdm[j], "%d", (str.val[i] & 0x0F));
sprintf(&ftdm[j], "%X", (str.val[i] & 0x0F));
j++;
sprintf(&ftdm[j], "%d", ((str.val[i] & 0xF0) >> 4));
sprintf(&ftdm[j], "%X", ((str.val[i] & 0xF0) >> 4));
j++;
}
@ -325,6 +318,8 @@ uint8_t copy_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven)
} else {
ftdm[j] = '\0';
}
} else {
SS7_ERROR("Asked to copy tknStr that is not present!\n");
return 1;
@ -451,6 +446,149 @@ unsigned long get_unique_id(void)
}
/******************************************************************************/
ftdm_status_t check_if_rx_grs_processed(ftdm_span_t *ftdmspan)
{
ftdm_channel_t *ftdmchan = NULL;
sngss7_chan_data_t *sngss7_info = NULL;
sngss7_span_data_t *sngss7_span = (sngss7_span_data_t *)ftdmspan->mod_data;
int i;
int byte = 0;
int bit = 0;
ftdm_log(FTDM_LOG_DEBUG, "Found Rx GRS on span %d...checking circuits\n", ftdmspan->span_id);
/* check all the circuits in the range to see if they are done resetting */
for ( i = sngss7_span->rx_grs.circuit; i < (sngss7_span->rx_grs.circuit + sngss7_span->rx_grs.range + 1); i++) {
/* extract the channel in question */
if (extract_chan_data(i, &sngss7_info, &ftdmchan)) {
SS7_ERROR("Failed to extract channel data for circuit = %d!\n", i);
SS7_ASSERT;
}
/* lock the channel */
ftdm_mutex_lock(ftdmchan->mutex);
/* check if there is a state change pending on the channel */
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
/* check the state to the GRP_RESET_RX_DN flag */
if (!sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX_DN)) {
/* this channel is still resetting...do nothing */
goto GRS_UNLOCK_ALL;
} /* if (!sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX_DN)) */
} else {
/* state change pending */
goto GRS_UNLOCK_ALL;
}
} /* for ( i = circuit; i < (circuit + range + 1); i++) */
SS7_DEBUG("All circuits out of reset for GRS: circuit=%d, range=%d\n",
sngss7_span->rx_grs.circuit,
sngss7_span->rx_grs.range);
/* check all the circuits in the range to see if they are done resetting */
for ( i = sngss7_span->rx_grs.circuit; i < (sngss7_span->rx_grs.circuit + sngss7_span->rx_grs.range + 1); i++) {
/* extract the channel in question */
if (extract_chan_data(i, &sngss7_info, &ftdmchan)) {
SS7_ERROR("Failed to extract channel data for circuit = %d!\n",i);
SS7_ASSERT;
}
/* throw the GRP reset flag complete flag */
sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_RX_CMPLT);
/* move the channel to the down state */
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
/* update the status map if the ckt is in blocked state */
if ((sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) ||
(sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_TX)) ||
(sngss7_test_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX)) ||
(sngss7_test_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX))) {
sngss7_span->rx_grs.status[byte] = (sngss7_span->rx_grs.status[byte] | (1 << bit));
} /* if blocked */
/* update the bit and byte counter*/
bit ++;
if (bit == 8) {
byte++;
bit = 0;
}
} /* for ( i = circuit; i < (circuit + range + 1); i++) */
GRS_UNLOCK_ALL:
for ( i = sngss7_span->rx_grs.circuit; i < (sngss7_span->rx_grs.circuit + sngss7_span->rx_grs.range + 1); i++) {
/* extract the channel in question */
if (extract_chan_data(i, &sngss7_info, &ftdmchan)) {
SS7_ERROR("Failed to extract channel data for circuit = %d!\n", i);
SS7_ASSERT;
}
/* unlock the channel */
ftdm_mutex_unlock(ftdmchan->mutex);
}
return FTDM_SUCCESS;
}
/******************************************************************************/
ftdm_status_t check_for_res_sus_flag(ftdm_span_t *ftdmspan)
{
ftdm_channel_t *ftdmchan = NULL;
sngss7_chan_data_t *sngss7_info = NULL;
ftdm_sigmsg_t sigev;
int x;
for (x = 1; x < (ftdmspan->chan_count + 1); x++) {
/* extract the channel structure and sngss7 channel data */
ftdmchan = ftdmspan->channels[x];
/* if the call data is NULL move on */
if (ftdmchan->call_data == NULL) continue;
sngss7_info = ftdmchan->call_data;
/* lock the channel */
ftdm_mutex_lock(ftdmchan->mutex);
memset (&sigev, 0, sizeof (sigev));
sigev.chan_id = ftdmchan->chan_id;
sigev.span_id = ftdmchan->span_id;
sigev.channel = ftdmchan;
/* if we have the PAUSED flag and the sig status is still UP */
if ((sngss7_test_flag(sngss7_info, FLAG_INFID_PAUSED)) &&
(ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP))) {
/* throw the channel into SUSPENDED to process the flag */
/* after doing this once the sig status will be down */
ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED);
}
/* if the RESUME flag is up go to SUSPENDED to process the flag */
/* after doing this the flag will be cleared */
if (sngss7_test_flag(sngss7_info, FLAG_INFID_RESUME)) {
ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED);
}
/* unlock the channel */
ftdm_mutex_unlock(ftdmchan->mutex);
} /* for (x = 1; x < (span->chan_count + 1); x++) */
/* signal the core that sig events are queued for processing */
ftdm_span_trigger_signals(ftdmspan);
return FTDM_SUCCESS;
}
/******************************************************************************/
/******************************************************************************/
/* For Emacs:

View File

@ -46,6 +46,8 @@ typedef struct sng_timeslot
int gap;
int hole;
}sng_timeslot_t;
int cmbLinkSetId;
/******************************************************************************/
/* PROTOTYPES *****************************************************************/
@ -343,11 +345,11 @@ static int ftmod_ss7_parse_mtp_linkset(ftdm_conf_node_t *mtp_linkset)
/**********************************************************************/
} else if (!strcasecmp(parm->var, "apc")) {
mtpLinkSet.apc = atoi(parm->val);
SS7_DEBUG("\tFoundmtpLinkSet->apc = %d\n", mtpLinkSet.apc);
SS7_DEBUG("\tFound mtpLinkSet->apc = %d\n", mtpLinkSet.apc);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "minActive")) {
mtpLinkSet.minActive = atoi(parm->val);
SS7_DEBUG("\tFoundmtpLinkSet->minActive = %d\n", mtpLinkSet.minActive);
SS7_DEBUG("\tFound mtpLinkSet->minActive = %d\n", mtpLinkSet.minActive);
/**********************************************************************/
} else {
SS7_ERROR("\tFound an invalid parameter \"%s\"!\n", parm->val);
@ -385,8 +387,6 @@ static int ftmod_ss7_parse_mtp_linkset(ftdm_conf_node_t *mtp_linkset)
if (count < 1 || count > 15 ) {
SS7_ERROR("Invalid number of mtp_links found (%d)\n", count);
return FTDM_FAIL;
} else {
mtpLinkSet.numLinks = count;
}
/* now we need to see if this linkset exists already or not and grab an Id */
@ -418,8 +418,7 @@ static int ftmod_ss7_parse_mtp_linkset(ftdm_conf_node_t *mtp_linkset)
mtpLink[i].mtp3.apc = mtpLinkSet.apc;
mtpLink[i].mtp3.linkSetId = mtpLinkSet.id;
/* fill in the mtplink structure */
mtpLinkSet.links[count] = ftmod_ss7_fill_in_mtpLink(&mtpLink[i]);
ftmod_ss7_fill_in_mtpLink(&mtpLink[i]);
/* increment the links counter */
count++;
@ -428,6 +427,10 @@ static int ftmod_ss7_parse_mtp_linkset(ftdm_conf_node_t *mtp_linkset)
i++;
}
mtpLinkSet.linkType = mtpLink[0].mtp3.linkType;
mtpLinkSet.switchType = mtpLink[0].mtp3.switchType;
mtpLinkSet.ssf = mtpLink[0].mtp3.ssf;
ftmod_ss7_fill_in_mtpLinkSet(&mtpLinkSet);
return FTDM_SUCCESS;
@ -497,27 +500,27 @@ static int ftmod_ss7_parse_mtp_link(ftdm_conf_node_t *mtp_link, sng_mtp_link_t *
if (!strcasecmp(parm->val, "itu92")) {
mtpLink->mtp2.linkType = LSD_SW_ITU92;
mtpLink->mtp3.linkType = LSN_SW_ITU;
SS7_DEBUG("\tFoundmtpLink->linkType = \"ITU92\"\n");
SS7_DEBUG("\tFound mtpLink->linkType = \"ITU92\"\n");
} else if (!strcasecmp(parm->val, "itu88")) {
mtpLink->mtp2.linkType = LSD_SW_ITU88;
mtpLink->mtp3.linkType = LSN_SW_ITU;
SS7_DEBUG("\tFoundmtpLink->linkType = \"ITU88\"\n");
SS7_DEBUG("\tFound mtpLink->linkType = \"ITU88\"\n");
} else if (!strcasecmp(parm->val, "ansi96")) {
mtpLink->mtp2.linkType = LSD_SW_ANSI92;
mtpLink->mtp3.linkType = LSN_SW_ANS96;
SS7_DEBUG("\tFoundmtpLink->linkType = \"ANSI96\"\n");
SS7_DEBUG("\tFound mtpLink->linkType = \"ANSI96\"\n");
} else if (!strcasecmp(parm->val, "ansi92")) {
mtpLink->mtp2.linkType = LSD_SW_ANSI92;
mtpLink->mtp3.linkType = LSN_SW_ANS;
SS7_DEBUG("\tFoundmtpLink->linkType = \"ANSI92\"\n");
SS7_DEBUG("\tFound mtpLink->linkType = \"ANSI92\"\n");
} else if (!strcasecmp(parm->val, "ansi88")) {
mtpLink->mtp2.linkType = LSD_SW_ANSI88;
mtpLink->mtp3.linkType = LSN_SW_ANS;
SS7_DEBUG("\tFoundmtpLink->linkType = \"ANSI88\"\n");
SS7_DEBUG("\tFound mtpLink->linkType = \"ANSI88\"\n");
} else if (!strcasecmp(parm->val, "etsi")) {
mtpLink->mtp2.linkType = LSD_SW_ITU92;
mtpLink->mtp3.linkType = LSN_SW_ITU;
SS7_DEBUG("\tFoundmtpLink->linkType = \"ETSI\"\n");
SS7_DEBUG("\tFound mtpLink->linkType = \"ETSI\"\n");
} else {
SS7_ERROR("\tFound an invalid linktype of \"%s\"!\n", parm->val);
return FTDM_FAIL;
@ -526,31 +529,40 @@ static int ftmod_ss7_parse_mtp_link(ftdm_conf_node_t *mtp_link, sng_mtp_link_t *
} else if (!strcasecmp(parm->var, "switchType")) {
if (!strcasecmp(parm->val, "itu97")) {
mtpLink->mtp3.switchType = LSI_SW_ITU97;
SS7_DEBUG("\tFoundmtpLink->switchType = \"ITU97\"\n");
SS7_DEBUG("\tFound mtpLink->switchType = \"ITU97\"\n");
} else if (!strcasecmp(parm->val, "itu88")) {
mtpLink->mtp3.switchType = LSI_SW_ITU;
SS7_DEBUG("\tFoundmtpLink->switchType = \"ITU88\"\n");
SS7_DEBUG("\tFound mtpLink->switchType = \"ITU88\"\n");
} else if (!strcasecmp(parm->val, "itu92")) {
mtpLink->mtp3.switchType = LSI_SW_ITU;
SS7_DEBUG("\tFoundmtpLink->switchType = \"ITU92\"\n");
SS7_DEBUG("\tFound mtpLink->switchType = \"ITU92\"\n");
} else if (!strcasecmp(parm->val, "itu00")) {
mtpLink->mtp3.switchType = LSI_SW_ITU2000;
SS7_DEBUG("\tFoundmtpLink->switchType = \"ITU00\"\n");
SS7_DEBUG("\tFound mtpLink->switchType = \"ITU00\"\n");
} else if (!strcasecmp(parm->val, "ETSIV2")) {
mtpLink->mtp3.switchType = LSI_SW_ETSI;
SS7_DEBUG("\tFoundmtpLink->switchType = \"ETSIV2\"\n");
SS7_DEBUG("\tFound mtpLink->switchType = \"ETSIV2\"\n");
} else if (!strcasecmp(parm->val, "ETSIV3")) {
mtpLink->mtp3.switchType = LSI_SW_ETSIV3;
SS7_DEBUG("\tFoundmtpLink->switchType = \"ETSIV3\"\n");
SS7_DEBUG("\tFound mtpLink->switchType = \"ETSIV3\"\n");
} else if (!strcasecmp(parm->val, "UK")) {
mtpLink->mtp3.switchType = LSI_SW_UK;
SS7_DEBUG("\tFoundmtpLink->switchType = \"UK\"\n");
SS7_DEBUG("\tFound mtpLink->switchType = \"UK\"\n");
} else if (!strcasecmp(parm->val, "RUSSIA")) {
mtpLink->mtp3.switchType = LSI_SW_RUSSIA;
SS7_DEBUG("\tFoundmtpLink->switchType = \"RUSSIA\"\n");
SS7_DEBUG("\tFound mtpLink->switchType = \"RUSSIA\"\n");
} else if (!strcasecmp(parm->val, "INDIA")) {
mtpLink->mtp3.switchType = LSI_SW_INDIA;
SS7_DEBUG("\tFoundmtpLink->switchType = \"INDIA\"\n");
SS7_DEBUG("\tFound mtpLink->switchType = \"INDIA\"\n");
} else if (!strcasecmp(parm->val, "ansi88")) {
mtpLink->mtp3.switchType = LSI_SW_ANS88;
SS7_DEBUG("\tFound mtpLink->switchType = \"ANSI88\"\n");
} else if (!strcasecmp(parm->val, "ansi92")) {
mtpLink->mtp3.switchType = LSI_SW_ANS92;
SS7_DEBUG("\tFound mtpLink->switchType = \"ANSI92\"\n");
} else if (!strcasecmp(parm->val, "ansi95")) {
mtpLink->mtp3.switchType = LSI_SW_ANS95;
SS7_DEBUG("\tFound mtpLink->switchType = \"ANSI95\"\n");
} else {
SS7_ERROR("\tFound an invalid linktype of \"%s\"!\n", parm->val);
return FTDM_FAIL;
@ -568,7 +580,7 @@ static int ftmod_ss7_parse_mtp_link(ftdm_conf_node_t *mtp_link, sng_mtp_link_t *
/**********************************************************************/
} else if (!strcasecmp(parm->var, "slc")) {
mtpLink->mtp3.slc = atoi(parm->val);
SS7_DEBUG("\tFoundmtpLink->slc = \"%d\"\n",mtpLink->mtp3.slc);
SS7_DEBUG("\tFound mtpLink->slc = \"%d\"\n",mtpLink->mtp3.slc);
/**********************************************************************/
} else {
SS7_ERROR("\tFound an invalid parameter \"%s\"!\n", parm->val);
@ -649,14 +661,17 @@ static int ftmod_ss7_parse_mtp_route(ftdm_conf_node_t *mtp_route)
/* check if the name matches */
if (!strcasecmp((char *)g_ftdm_sngss7_data.cfg.mtpLinkSet[x].name, parm->val)) {
/* grab the mtpLink id value first*/
int id = g_ftdm_sngss7_data.cfg.mtpLinkSet[x].links[0];
/* now, harvest the required infomormation from the global structure */
mtpRoute.linkType = g_ftdm_sngss7_data.cfg.mtpLink[id].mtp3.linkType;
mtpRoute.switchType = g_ftdm_sngss7_data.cfg.mtpLink[id].mtp3.switchType;
mtpRoute.ssf = g_ftdm_sngss7_data.cfg.mtpLink[id].mtp3.ssf;
mtpRoute.cmbLinkSetId = g_ftdm_sngss7_data.cfg.mtpLinkSet[x].id;
mtpRoute.linkType = g_ftdm_sngss7_data.cfg.mtpLinkSet[x].linkType;
mtpRoute.switchType = g_ftdm_sngss7_data.cfg.mtpLinkSet[x].switchType;
mtpRoute.ssf = g_ftdm_sngss7_data.cfg.mtpLinkSet[x].ssf;
mtpRoute.linkSetId = g_ftdm_sngss7_data.cfg.mtpLinkSet[x].id;
cmbLinkSetId++;
mtpRoute.cmbLinkSetId = cmbLinkSetId;
/* update the linkset with the new cmbLinkSet value */
g_ftdm_sngss7_data.cfg.mtpLinkSet[x].numLinks++;
g_ftdm_sngss7_data.cfg.mtpLinkSet[x].links[g_ftdm_sngss7_data.cfg.mtpLinkSet[x].numLinks-1] = mtpRoute.cmbLinkSetId;
break;
}
x++;
@ -692,9 +707,11 @@ static int ftmod_ss7_parse_mtp_route(ftdm_conf_node_t *mtp_route)
parm = parm + 1;
}
ftmod_ss7_fill_in_nsap(&mtpRoute);
ftmod_ss7_fill_in_mtp3_route(&mtpRoute);
ftmod_ss7_fill_in_nsap(&mtpRoute);
return FTDM_SUCCESS;
}
@ -738,7 +755,6 @@ static int ftmod_ss7_parse_isup_interface(ftdm_conf_node_t *isup_interface)
int num_parms = isup_interface->n_parameters;
int i;
int linkSetId;
int linkId;
memset(&sng_isup, 0x0, sizeof(sng_isup));
memset(&sng_isap, 0x0, sizeof(sng_isap));
@ -772,36 +788,25 @@ static int ftmod_ss7_parse_isup_interface(ftdm_conf_node_t *isup_interface)
/* check if the name matches */
if (!strcasecmp((char *)g_ftdm_sngss7_data.cfg.mtpRoute[x].name, parm->val)) {
/* now, harvest the required information from the global structure */
sng_isup.mtpRouteId = g_ftdm_sngss7_data.cfg.mtpRoute[x].id;
sng_isup.dpc = g_ftdm_sngss7_data.cfg.mtpRoute[x].dpc;
sng_isup.switchType = g_ftdm_sngss7_data.cfg.mtpRoute[x].switchType;
sng_isap.switchType = g_ftdm_sngss7_data.cfg.mtpRoute[x].switchType;
/* find the nwID from the nsap */
int y = 1;
while (g_ftdm_sngss7_data.cfg.nsap[y].id != 0) {
if ((g_ftdm_sngss7_data.cfg.nsap[y].linkType == g_ftdm_sngss7_data.cfg.mtpRoute[x].linkType) &&
(g_ftdm_sngss7_data.cfg.nsap[y].switchType == g_ftdm_sngss7_data.cfg.mtpRoute[x].switchType) &&
(g_ftdm_sngss7_data.cfg.nsap[y].ssf == g_ftdm_sngss7_data.cfg.mtpRoute[x].ssf)) {
/* find the NSAP corresponding to this switchType and SSF */
int z = 1;
while (g_ftdm_sngss7_data.cfg.nsap[z].id != 0) {
if ((g_ftdm_sngss7_data.cfg.nsap[z].linkType == g_ftdm_sngss7_data.cfg.mtpRoute[x].linkType) &&
(g_ftdm_sngss7_data.cfg.nsap[z].switchType == g_ftdm_sngss7_data.cfg.mtpRoute[x].switchType) &&
(g_ftdm_sngss7_data.cfg.nsap[z].ssf == g_ftdm_sngss7_data.cfg.mtpRoute[x].ssf)) {
sng_isup.nwId = g_ftdm_sngss7_data.cfg.nsap[z].nwId;
/* we have a match so break out of this loop */
break;
}
/* move on to the next one */
y++;
} /* while (g_ftdm_sngss7_data.cfg.mtp3_isup[y].id != 0) */
/* check how we exited the last while loop */
if (g_ftdm_sngss7_data.cfg.nsap[y].id == 0) {
SS7_ERROR("\tFailed to find the nwID for = \"%s\"!\n", parm->val);
return FTDM_FAIL;
} else {
sng_isup.nwId = g_ftdm_sngss7_data.cfg.nsap[y].nwId;
z++;
}
break;
}
x++;
@ -846,10 +851,15 @@ static int ftmod_ss7_parse_isup_interface(ftdm_conf_node_t *isup_interface)
}
/* trickle down the SPC to all sub entities */
linkSetId = g_ftdm_sngss7_data.cfg.mtpRoute[sng_isup.mtpRouteId].cmbLinkSetId;
for (i = 0; i < g_ftdm_sngss7_data.cfg.mtpLinkSet[linkSetId].numLinks; i ++) {
linkId = g_ftdm_sngss7_data.cfg.mtpLinkSet[linkSetId].links[i];
g_ftdm_sngss7_data.cfg.mtpLink[linkId].mtp3.spc = g_ftdm_sngss7_data.cfg.spc;
linkSetId = g_ftdm_sngss7_data.cfg.mtpRoute[sng_isup.mtpRouteId].linkSetId;
i = 1;
while (g_ftdm_sngss7_data.cfg.mtpLink[i].id != 0) {
if (g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.linkSetId == linkSetId) {
g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.spc = g_ftdm_sngss7_data.cfg.spc;
}
i++;
}
ftmod_ss7_fill_in_isap(&sng_isap);
@ -858,8 +868,6 @@ static int ftmod_ss7_parse_isup_interface(ftdm_conf_node_t *isup_interface)
ftmod_ss7_fill_in_isup_interface(&sng_isup);
g_ftdm_sngss7_data.cfg.isap[sng_isap.id].spId = sng_isup.id;
return FTDM_SUCCESS;
}
@ -957,7 +965,7 @@ static int ftmod_ss7_fill_in_mtpLink(sng_mtp_link_t *mtpLink)
if ( mtpLink->mtp2.t7 != 0 ) {
g_ftdm_sngss7_data.cfg.mtpLink[i].mtp2.t7 = mtpLink->mtp2.t7;
}else {
g_ftdm_sngss7_data.cfg.mtpLink[i].mtp2.t7 = 20;
g_ftdm_sngss7_data.cfg.mtpLink[i].mtp2.t7 = 40;
}
if (mtpLink->mtp3.t1 != 0) {
@ -1057,21 +1065,19 @@ static int ftmod_ss7_fill_in_mtpLink(sng_mtp_link_t *mtpLink)
/******************************************************************************/
static int ftmod_ss7_fill_in_mtpLinkSet(sng_link_set_t *mtpLinkSet)
{
int count;
int i = mtpLinkSet->id;
strcpy((char *)g_ftdm_sngss7_data.cfg.mtpLinkSet[i].name, (char *)mtpLinkSet->name);
g_ftdm_sngss7_data.cfg.mtpLinkSet[i].id = mtpLinkSet->id;
g_ftdm_sngss7_data.cfg.mtpLinkSet[i].apc = mtpLinkSet->apc;
g_ftdm_sngss7_data.cfg.mtpLinkSet[i].linkType = g_ftdm_sngss7_data.cfg.mtpLink[1].mtp3.linkType; /* KONRAD FIX ME */
g_ftdm_sngss7_data.cfg.mtpLinkSet[i].linkType = mtpLinkSet->linkType;
g_ftdm_sngss7_data.cfg.mtpLinkSet[i].switchType = mtpLinkSet->switchType;
g_ftdm_sngss7_data.cfg.mtpLinkSet[i].ssf = mtpLinkSet->ssf;
/* these values are filled in as we find routes and start allocating cmbLinkSetIds */
g_ftdm_sngss7_data.cfg.mtpLinkSet[i].minActive = mtpLinkSet->minActive;
g_ftdm_sngss7_data.cfg.mtpLinkSet[i].numLinks = mtpLinkSet->numLinks;
for (count = 0; count < mtpLinkSet->numLinks; count++) {
g_ftdm_sngss7_data.cfg.mtpLinkSet[i].links[count] = mtpLinkSet->links[count];
}
g_ftdm_sngss7_data.cfg.mtpLinkSet[i].numLinks = 0;
return 0;
}
@ -1083,8 +1089,7 @@ static int ftmod_ss7_fill_in_mtp3_route(sng_route_t *mtp3_route)
/* go through all the existing routes and see if we find a match */
i = 1;
while (g_ftdm_sngss7_data.cfg.mtpRoute[i].id != 0) {
if (g_ftdm_sngss7_data.cfg.mtpRoute[i].dpc == mtp3_route->dpc) {
if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtpRoute[i].name, mtp3_route->name)) {
/* we have a match so break out of this loop */
break;
}
@ -1106,8 +1111,10 @@ static int ftmod_ss7_fill_in_mtp3_route(sng_route_t *mtp3_route)
g_ftdm_sngss7_data.cfg.mtpRoute[i].dpc = mtp3_route->dpc;
g_ftdm_sngss7_data.cfg.mtpRoute[i].linkType = mtp3_route->linkType;
g_ftdm_sngss7_data.cfg.mtpRoute[i].switchType = mtp3_route->switchType;
g_ftdm_sngss7_data.cfg.mtpRoute[i].cmbLinkSetId = 1; /* mtp3_route->cmbLinkSetId;*/
g_ftdm_sngss7_data.cfg.mtpRoute[i].cmbLinkSetId = mtp3_route->cmbLinkSetId;
g_ftdm_sngss7_data.cfg.mtpRoute[i].isSTP = mtp3_route->isSTP;
g_ftdm_sngss7_data.cfg.mtpRoute[i].nwId = mtp3_route->nwId;
g_ftdm_sngss7_data.cfg.mtpRoute[i].linkSetId = mtp3_route->linkSetId;
g_ftdm_sngss7_data.cfg.mtpRoute[i].ssf = mtp3_route->ssf;
if (mtp3_route->t6 != 0) {
g_ftdm_sngss7_data.cfg.mtpRoute[i].t6 = mtp3_route->t6;
@ -1159,6 +1166,11 @@ static int ftmod_ss7_fill_in_mtp3_route(sng_route_t *mtp3_route)
} else {
g_ftdm_sngss7_data.cfg.mtpRoute[i].t25 = 100;
}
if (mtp3_route->t26 != 0) {
g_ftdm_sngss7_data.cfg.mtpRoute[i].t26 = mtp3_route->t26;
} else {
g_ftdm_sngss7_data.cfg.mtpRoute[i].t26 = 100;
}
return 0;
}
@ -1184,15 +1196,17 @@ static int ftmod_ss7_fill_in_nsap(sng_route_t *mtp3_route)
if (g_ftdm_sngss7_data.cfg.nsap[i].id == 0) {
g_ftdm_sngss7_data.cfg.nsap[i].id = i;
mtp3_route->nwId = i;
SS7_DEBUG("found new mtp3_isup interface, id is = %d\n", g_ftdm_sngss7_data.cfg.nsap[i].id);
} else {
g_ftdm_sngss7_data.cfg.nsap[i].id = i;
mtp3_route->nwId = i;
SS7_DEBUG("found existing mtp3_isup interface, id is = %d\n", g_ftdm_sngss7_data.cfg.nsap[i].id);
}
g_ftdm_sngss7_data.cfg.nsap[i].spId = g_ftdm_sngss7_data.cfg.nsap[i].id;
g_ftdm_sngss7_data.cfg.nsap[i].suId = g_ftdm_sngss7_data.cfg.nsap[i].id;
g_ftdm_sngss7_data.cfg.nsap[i].nwId = g_ftdm_sngss7_data.cfg.nsap[i].id;
g_ftdm_sngss7_data.cfg.nsap[i].nwId = mtp3_route->nwId;
g_ftdm_sngss7_data.cfg.nsap[i].linkType = mtp3_route->linkType;
g_ftdm_sngss7_data.cfg.nsap[i].switchType = mtp3_route->switchType;
g_ftdm_sngss7_data.cfg.nsap[i].ssf = mtp3_route->ssf;
@ -1208,7 +1222,7 @@ static int ftmod_ss7_fill_in_isup_interface(sng_isup_inf_t *sng_isup)
/* go through all the existing interfaces and see if we find a match */
i = 1;
while (g_ftdm_sngss7_data.cfg.isupIntf[i].id != 0) {
if (g_ftdm_sngss7_data.cfg.isupIntf[i].nwId == sng_isup->nwId) {
if (!strcasecmp(g_ftdm_sngss7_data.cfg.isupIntf[i].name, sng_isup->name)) {
/* we have a match so break out of this loop */
break;
@ -1381,7 +1395,8 @@ static int ftmod_ss7_fill_in_isap(sng_isap_t *sng_isap)
}
g_ftdm_sngss7_data.cfg.isap[i].id = sng_isap->id;
g_ftdm_sngss7_data.cfg.isap[i].suId = 1; /*KONRAD FIX ME */
g_ftdm_sngss7_data.cfg.isap[i].suId = sng_isap->id;
g_ftdm_sngss7_data.cfg.isap[i].spId = sng_isap->id;
g_ftdm_sngss7_data.cfg.isap[i].switchType = sng_isap->switchType;
g_ftdm_sngss7_data.cfg.isap[i].ssf = sng_isap->ssf;
@ -1458,7 +1473,7 @@ static int ftmod_ss7_fill_in_isap(sng_isap_t *sng_isap)
if (sng_isap->tex != 0) {
g_ftdm_sngss7_data.cfg.isap[i].tex = sng_isap->tex;
} else {
g_ftdm_sngss7_data.cfg.isap[i].tex = 10;
g_ftdm_sngss7_data.cfg.isap[i].tex = 1000;
}
if (sng_isap->tcrm != 0) {
g_ftdm_sngss7_data.cfg.isap[i].tcrm = sng_isap->tcrm;
@ -1499,7 +1514,9 @@ static int ftmod_ss7_fill_in_self_route(int spc, int linkType, int switchType, i
SS7_DEBUG("found existing mtp3 self route\n");
return FTDM_SUCCESS;
} else {
SS7_ERROR("found new mtp3 self route but it does not much the route already configured\n");
SS7_ERROR("found new mtp3 self route but it does not match the route already configured (dpc=%d:spc=%d)\n",
g_ftdm_sngss7_data.cfg.mtpRoute[0].dpc,
spc);
return FTDM_FAIL;
}
@ -1583,11 +1600,10 @@ static int ftmod_ss7_fill_in_circuits(char *ch_map, int cicbase, int typeCntrl,
g_ftdm_sngss7_data.cfg.isupCkt[x].chan = count;
if (timeslot.siglink) {
g_ftdm_sngss7_data.cfg.isupCkt[x].type = SIG;
} else if (timeslot.hole) {
g_ftdm_sngss7_data.cfg.isupCkt[x].type = HOLE;
} else {
g_ftdm_sngss7_data.cfg.isupCkt[x].type = VOICE;
g_ftdm_sngss7_data.cfg.isupCkt[x].type = HOLE;
}
if (timeslot.channel) {
g_ftdm_sngss7_data.cfg.isupCkt[x].cic = cicbase;
cicbase++;
@ -1608,6 +1624,10 @@ static int ftmod_ss7_fill_in_circuits(char *ch_map, int cicbase, int typeCntrl,
g_ftdm_sngss7_data.cfg.isupCkt[x].obj = ss7_info;
} /* if (g_ftdm_sngss7_data.cfg.isupCkt[x].id == 0) */
/* increment the span channel count */
count++;
} else { /* if ((timeslot.siglink) || (timeslot.gap)) */
/* find the ftdm the channel structure for this channel*/
i = 1;

View File

@ -386,7 +386,7 @@ typedef struct ftdm_conf_parameter {
} ftdm_conf_parameter_t;
/*! \brief Opaque general purpose iterator */
typedef void ftdm_iterator_t;
typedef struct ftdm_iterator ftdm_iterator_t;
/*! \brief Channel commands that can be executed through ftdm_channel_command() */
typedef enum {
@ -1032,8 +1032,19 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_add_var(ftdm_channel_t *ftdmchan, const c
FT_DECLARE(const char *) ftdm_channel_get_var(ftdm_channel_t *ftdmchan, const char *var_name);
/*! \brief Get an iterator to iterate over the channel variables
* \note The iterator pointer returned is only valid while the channel is open and it'll be destroyed when the channel is closed. */
FT_DECLARE(ftdm_iterator_t *) ftdm_channel_get_var_iterator(const ftdm_channel_t *ftdmchan);
* \param ftdmchan The channel structure containing the variables
* \param iter Optional iterator. You can reuse an old iterator (not previously freed) to avoid the extra allocation of a new iterator.
* \note The iterator pointer returned is only valid while the channel is open and it'll be destroyed when the channel is closed.
* This iterator is completely non-thread safe, if you are adding variables or removing variables while iterating
* results are unpredictable
*/
FT_DECLARE(ftdm_iterator_t *) ftdm_channel_get_var_iterator(const ftdm_channel_t *ftdmchan, ftdm_iterator_t *iter);
/*! \brief Get iterator current value (depends on the iterator type)
* \note Channel iterators return a pointer to ftdm_channel_t
* Variable iterators return a pointer to the variable name (not the variable value)
*/
FT_DECLARE(void *) ftdm_iterator_current(ftdm_iterator_t *iter);
/*! \brief Get variable name and value for the current iterator position */
FT_DECLARE(ftdm_status_t) ftdm_channel_get_current_var(ftdm_iterator_t *iter, const char **var_name, const char **var_val);
@ -1041,6 +1052,11 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_get_current_var(ftdm_iterator_t *iter, co
/*! \brief Advance iterator */
FT_DECLARE(ftdm_iterator_t *) ftdm_iterator_next(ftdm_iterator_t *iter);
/*! \brief Free iterator
* \note You must free an iterator after using it unless you plan to reuse it
*/
FT_DECLARE(ftdm_status_t) ftdm_iterator_free(ftdm_iterator_t *iter);
/*! \brief Get the span pointer associated to the channel */
FT_DECLARE(ftdm_span_t *) ftdm_channel_get_span(const ftdm_channel_t *ftdmchan);
@ -1144,6 +1160,12 @@ FT_DECLARE(uint32_t) ftdm_span_get_id(const ftdm_span_t *span);
/*! \brief Get the span name */
FT_DECLARE(const char *) ftdm_span_get_name(const ftdm_span_t *span);
/*! \brief Get iterator for the span channels
* \param span The span containing the channels
* \param iter Optional iterator. You can reuse an old iterator (not previously freed) to avoid the extra allocation of a new iterator.
*/
FT_DECLARE(ftdm_iterator_t *) ftdm_span_get_chan_iterator(const ftdm_span_t *span, ftdm_iterator_t *iter);
/*!
* \brief Execute a text command. The text command output will be returned and must be free'd
*

View File

@ -619,6 +619,9 @@ FT_DECLARE(ftdm_status_t) ftdm_span_trigger_signals(const ftdm_span_t *span);
#define ftdm_log_chan(fchan, level, format, ...) ftdm_log(level, "[s%dc%d][%d:%d] " format, fchan->span_id, fchan->chan_id, fchan->physical_span_id, fchan->physical_chan_id, __VA_ARGS__)
#define ftdm_log_chan_msg(fchan, level, msg) ftdm_log(level, "[s%dc%d][%d:%d] " msg, fchan->span_id, fchan->chan_id, fchan->physical_span_id, fchan->physical_chan_id)
#define ftdm_span_lock(span) ftdm_mutex_lock(span->mutex)
#define ftdm_span_unlock(span) ftdm_mutex_unlock(span->mutex)
FT_DECLARE_DATA extern const char *FTDM_LEVEL_NAMES[9];
static __inline__ void ftdm_abort(void)

View File

@ -366,6 +366,23 @@ typedef ftdm_status_t (*ftdm_span_start_t)(ftdm_span_t *span);
typedef ftdm_status_t (*ftdm_span_stop_t)(ftdm_span_t *span);
typedef ftdm_status_t (*ftdm_channel_sig_read_t)(ftdm_channel_t *ftdmchan, void *data, ftdm_size_t size);
typedef enum {
FTDM_ITERATOR_VARS = 1,
FTDM_ITERATOR_CHANS,
} ftdm_iterator_type_t;
struct ftdm_iterator {
ftdm_iterator_type_t type;
unsigned int allocated:1;
union {
struct {
int32_t index;
const ftdm_span_t *span;
} chaniter;
ftdm_hash_iterator_t *hashiter;
} pvt;
};
#ifdef __cplusplus
}
#endif