Merge branch 'releases.3.4.experimental_head' into releases.3.5

This commit is contained in:
Moises Silva 2012-01-31 17:17:25 -05:00
commit 541aa551c7
19 changed files with 1963 additions and 427 deletions

View File

@ -13,7 +13,7 @@ cpu_monitoring_interval => 1000
cpu_set_alarm_threshold => 80
; At what CPU percentage stop the CPU alarm
cpu_reset_alarm_threshold => 70
cpu_clear_alarm_threshold => 70
; Which action to take when the CPU alarm is raised
; it can be warn and/or reject calls

View File

@ -124,6 +124,8 @@ struct private_object {
ftdm_channel_t *ftdmchan;
uint32_t write_error;
uint32_t read_error;
char network_peer_uuid[SWITCH_UUID_FORMATTED_LENGTH + 1];
};
/* private data attached to FTDM channels (only FXS for now) */
@ -574,6 +576,34 @@ static switch_status_t channel_on_hangup(switch_core_session_t *session)
}
#endif
name = switch_channel_get_name(channel);
span_id = tech_pvt->ftdmchan ? ftdm_channel_get_span_id(tech_pvt->ftdmchan) : 0;
chan_id = tech_pvt->ftdmchan ? ftdm_channel_get_id(tech_pvt->ftdmchan) : 0;
/* Now verify the device is still attached to this call :-)
* Sometimes the FS core takes too long (more than 3 seconds) in calling
* channel_on_hangup() and the FreeTDM core decides to take the brute
* force approach and hangup and detach themselves from the call. Later
* when FS finally comes around, we might end up hanging up the device
* attached to another call, this verification avoids that. */
uuid = switch_core_session_get_uuid(session);
tokencnt = ftdm_channel_get_token_count(tech_pvt->ftdmchan);
for (t = 0; t < tokencnt; t++) {
token = ftdm_channel_get_token(tech_pvt->ftdmchan, t);
if (!zstr(token) && !strcasecmp(uuid, token)) {
uuid_found = 1;
break;
}
}
if (!uuid_found) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Device [%d:%d] is no longer attached to %s. Nothing to do.\n", span_id, chan_id, name);
goto end;
}
ftdm_channel_clear_token(tech_pvt->ftdmchan, switch_core_session_get_uuid(session));
chantype = ftdm_channel_get_type(tech_pvt->ftdmchan);
@ -598,11 +628,20 @@ static switch_status_t channel_on_hangup(switch_core_session_t *session)
case FTDM_CHAN_TYPE_CAS:
case FTDM_CHAN_TYPE_B:
{
const char *var = NULL;
ftdm_call_cause_t hcause = switch_channel_get_cause_q850(channel);
if (hcause < 1 || hcause > 127) {
hcause = FTDM_CAUSE_DESTINATION_OUT_OF_ORDER;
}
ftdm_channel_call_hangup_with_cause(tech_pvt->ftdmchan, hcause);
var = switch_channel_get_variable(channel, "ss7_rel_loc");
if (var) {
ftdm_usrmsg_t usrmsg;
memset(&usrmsg, 0, sizeof(ftdm_usrmsg_t));
ftdm_usrmsg_add_var(&usrmsg, "ss7_rel_loc", var);
ftdm_channel_call_hangup_with_cause_ex(tech_pvt->ftdmchan, hcause, &usrmsg);
} else {
ftdm_channel_call_hangup_with_cause(tech_pvt->ftdmchan, hcause);
}
}
break;
default:
@ -1276,10 +1315,15 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
int argc = 0;
const char *var;
const char *dest_num = NULL, *callerid_num = NULL;
const char *network_peer_uuid = NULL;
char sigbridge_peer[255];
switch_channel_t *peer_chan = NULL;
switch_channel_t *our_chan = NULL;
ftdm_hunting_scheme_t hunting;
ftdm_usrmsg_t usrmsg;
memset(&usrmsg, 0, sizeof(ftdm_usrmsg_t));
memset(sigbridge_peer, 0, sizeof(sigbridge_peer));
if (!outbound_profile) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing caller profile\n");
@ -1366,6 +1410,9 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
if (session && globals.sip_headers) {
switch_channel_t *channel = switch_core_session_get_channel(session);
const char *sipvar;
network_peer_uuid = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-TransUUID");
sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-CallerName");
if (sipvar) {
ftdm_set_string(caller_data.cid_name, sipvar);
@ -1407,6 +1454,11 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
ftdm_set_string(caller_data.dnis.digits, sipvar);
}
sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-LOC");
if (sipvar) {
ftdm_set_string(caller_data.loc.digits, sipvar);
}
sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-DNIS-TON");
if (sipvar) {
caller_data.dnis.type = (uint8_t)atoi(sipvar);
@ -1420,7 +1472,7 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
/* Used by ftmod_sangoma_ss7 only */
sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-DNIS-NADI");
if (sipvar) {
ftdm_usrmsg_add_var(&usrmsg, "ss7_clg_nadi", sipvar);
ftdm_usrmsg_add_var(&usrmsg, "ss7_cld_nadi", sipvar);
}
sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-RDNIS");
@ -1503,6 +1555,24 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
if (sipvar) {
ftdm_usrmsg_add_var(&usrmsg, "ss7_iam", sipvar);
}
/* redirection information */
sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-RDINF-Indicator");
if (sipvar) {
ftdm_usrmsg_add_var(&usrmsg, "ss7_rdinfo_indicator", sipvar);
}
sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-RDINF-OrigReason");
if (sipvar) {
ftdm_usrmsg_add_var(&usrmsg, "ss7_rdinfo_orig", sipvar);
}
sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-RDINF-Count");
if (sipvar) {
ftdm_usrmsg_add_var(&usrmsg, "ss7_rdinfo_count", sipvar);
}
sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-RDINF-Reason");
if (sipvar) {
ftdm_usrmsg_add_var(&usrmsg, "ss7_rdinfo_reason", sipvar);
}
}
if (switch_test_flag(outbound_profile, SWITCH_CPF_SCREEN)) {
@ -1513,6 +1583,10 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
caller_data.pres = FTDM_PRES_RESTRICTED;
}
if ((var = channel_get_variable(session, var_event, "freetdm_iam_fwd_ind_isdn_access_ind"))) {
ftdm_usrmsg_add_var(&usrmsg, "iam_fwd_ind_isdn_access_ind", var);
}
if ((var = channel_get_variable(session, var_event, "freetdm_bearer_capability"))) {
caller_data.bearer_capability = (uint8_t)atoi(var);
}
@ -1599,6 +1673,25 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
goto fail;
}
our_chan = switch_core_session_get_channel(*new_session);
if (network_peer_uuid) {
switch_core_session_t *network_peer = switch_core_session_locate(network_peer_uuid);
if (network_peer) {
const char *my_uuid = switch_core_session_get_uuid(*new_session);
private_t *peer_private = switch_core_session_get_private(network_peer);
switch_set_string(tech_pvt->network_peer_uuid, network_peer_uuid);
switch_set_string(peer_private->network_peer_uuid, my_uuid);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Session %s is network-bridged with %s\n",
my_uuid, network_peer_uuid);
snprintf(sigbridge_peer, sizeof(sigbridge_peer), "%u:%u",
ftdm_channel_get_span_id(peer_private->ftdmchan), ftdm_channel_get_id(peer_private->ftdmchan));
switch_core_session_rwunlock(network_peer);
}
}
caller_profile = switch_caller_profile_clone(*new_session, outbound_profile);
caller_profile->destination_number = switch_core_strdup(caller_profile->pool, switch_str_nil(dest_num));
caller_profile->caller_id_number = switch_core_strdup(caller_profile->pool, switch_str_nil(callerid_num));
@ -1610,6 +1703,21 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
hunt_data.tech_pvt = tech_pvt;
caller_data.priv = &hunt_data;
if (session
&& (var = channel_get_variable(session, var_event, FREETDM_VAR_PREFIX "native_sigbridge"))
&& switch_true(var)
&& switch_core_session_compare(*new_session, session)) {
private_t *peer_pvt = switch_core_session_get_private(session);
snprintf(sigbridge_peer, sizeof(sigbridge_peer), "%u:%u",
ftdm_channel_get_span_id(peer_pvt->ftdmchan), ftdm_channel_get_id(peer_pvt->ftdmchan));
}
if (session && !zstr(sigbridge_peer)) {
peer_chan = switch_core_session_get_channel(session);
ftdm_usrmsg_add_var(&usrmsg, "sigbridge_peer", sigbridge_peer);
}
if ((status = ftdm_call_place_ex(&caller_data, &hunting, &usrmsg)) != FTDM_SUCCESS) {
if (tech_pvt->read_codec.implementation) {
switch_core_codec_destroy(&tech_pvt->read_codec);
@ -1627,6 +1735,12 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
goto fail;
}
if (our_chan && peer_chan) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO,
"Bridging native signaling of channel %s to channel %s\n",
switch_channel_get_name(peer_chan), switch_channel_get_name(our_chan));
}
return SWITCH_CAUSE_SUCCESS;
}
@ -1753,6 +1867,7 @@ ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session
if (globals.sip_headers) {
switch_channel_set_variable(channel, "sip_h_X-FreeTDM-SpanName", ftdm_channel_get_span_name(sigmsg->channel));
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-TransUUID", "%s",switch_core_session_get_uuid(session));
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-SpanNumber", "%d", spanid);
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-ChanNumber", "%d", chanid);
@ -1772,54 +1887,80 @@ ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-RDNIS-NADI", "%d", channel_caller_data->rdnis.type);
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-RDNIS-Plan", "%d", channel_caller_data->rdnis.plan);
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-CPC", "%s", ftdm_calling_party_category2str(channel_caller_data->cpc));
var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_rdinfo_indicator");
if (!ftdm_strlen_zero(var_value)) {
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-RDINF-Indicator", "%s", var_value);
}
var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_rdinfo_orig");
if (!ftdm_strlen_zero(var_value)) {
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-RDINF-OrigReason", "%s", var_value);
}
var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_rdinfo_count");
if (!ftdm_strlen_zero(var_value)) {
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-RDINF-Count", "%s", var_value);
}
var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_rdinfo_reason");
if (!ftdm_strlen_zero(var_value)) {
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-RDINF-Reason", "%s", var_value);
}
var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_clg_nadi");
if (!ftdm_strlen_zero(var_value)) {
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-NADI", "%d", var_value);
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-NADI", "%s", var_value);
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-ANI-NADI", "%s", var_value);
}
var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_cld_nadi");
if (!ftdm_strlen_zero(var_value)) {
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-DNIS-NADI", "%s", var_value);
}
var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_rdnis_screen_ind");
if (!ftdm_strlen_zero(var_value)) {
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-RDNIS-Screen", "%d", var_value);
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-RDNIS-Screen", "%s", var_value);
}
var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_rdnis_pres_ind");
if (!ftdm_strlen_zero(var_value)) {
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-RDNIS-Presentation", "%d", channel_caller_data->rdnis.plan);
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-RDNIS-Presentation", "%s", var_value);
}
var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_gn_digits");
if (!ftdm_strlen_zero(var_value)) {
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-GN", "%d", var_value);
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-GN", "%s", var_value);
var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_gn_numqual");
if (!ftdm_strlen_zero(var_value)) {
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-GN-NumQual", "%d", var_value);
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-GN-NumQual", "%s", var_value);
}
var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_gn_nadi");
if (!ftdm_strlen_zero(var_value)) {
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-GN-NADI", "%d", var_value);
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-GN-NADI", "%s", var_value);
}
var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_gn_screen_ind");
if (!ftdm_strlen_zero(var_value)) {
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-GN-Screen", "%d", var_value);
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-GN-Screen", "%s", var_value);
}
var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_gn_pres_ind");
if (!ftdm_strlen_zero(var_value)) {
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-GN-Presentation", "%d", var_value);
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-GN-Presentation", "%s", var_value);
}
var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_gn_npi");
if (!ftdm_strlen_zero(var_value)) {
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-GN-Plan", "%d", var_value);
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-GN-Plan", "%s", var_value);
}
var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_gn_num_inc_ind");
if (!ftdm_strlen_zero(var_value)) {
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-GN-NumInComp", "%d", var_value);
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-GN-NumInComp", "%s", var_value);
}
} /* End - var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_gn_digits"); */
@ -1841,6 +1982,27 @@ ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session
if (!ftdm_strlen_zero(var_value)) {
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-OPC", "%s", var_value);
}
var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_loc_digits");
if (!ftdm_strlen_zero(var_value)) {
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-LOC", "%s", var_value);
}
var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_loc_screen_ind");
if (!ftdm_strlen_zero(var_value)) {
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-LOC-Screen", "%s", var_value);
}
var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_loc_pres_ind");
if (!ftdm_strlen_zero(var_value)) {
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-LOC-Presentation", "%s", var_value);
}
var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_loc_nadi");
printf ( "ss7_loc_nadi = %s \n " , var_value );
if (!ftdm_strlen_zero(var_value)) {
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-LOC-NADI", "%s", var_value);
}
}
/* Add any call variable to the dial plan */

View File

@ -52,9 +52,7 @@
struct tm *localtime_r(const time_t *clock, struct tm *result);
#endif
#define FORCE_HANGUP_TIMER 3000
#define SPAN_PENDING_CHANS_QUEUE_SIZE 1000
#define SPAN_PENDING_SIGNALS_QUEUE_SIZE 1000
#define FORCE_HANGUP_TIMER 30000
#define FTDM_READ_TRACE_INDEX 0
#define FTDM_WRITE_TRACE_INDEX 1
#define MAX_CALLIDS 6000
@ -223,7 +221,7 @@ typedef struct {
uint32_t interval;
uint8_t alarm_action_flags;
uint8_t set_alarm_threshold;
uint8_t reset_alarm_threshold;
uint8_t clear_alarm_threshold;
ftdm_interrupt_t *interrupt;
} cpu_monitor_t;
@ -2205,6 +2203,12 @@ static ftdm_status_t _ftdm_channel_call_hangup_nl(const char *file, const char *
{
ftdm_status_t status = FTDM_SUCCESS;
if (ftdm_test_flag(chan, FTDM_CHANNEL_NATIVE_SIGBRIDGE)) {
ftdm_log_chan_ex(chan, file, func, line, FTDM_LOG_LEVEL_DEBUG,
"Ignoring hangup in channel in state %s (native bridge enabled)\n", ftdm_channel_state2str(chan->state));
goto done;
}
if (chan->state != FTDM_CHANNEL_STATE_DOWN) {
if (chan->state == FTDM_CHANNEL_STATE_HANGUP) {
/* make user's life easier, and just ignore double hangup requests */
@ -2231,6 +2235,8 @@ static ftdm_status_t _ftdm_channel_call_hangup_nl(const char *file, const char *
ftdm_channel_close(&chan);
}
}
done:
return status;
}
@ -2326,6 +2332,15 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_indicate(const char *file, const ch
ftdm_channel_lock(ftdmchan);
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_NATIVE_SIGBRIDGE)) {
ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_DEBUG,
"Ignoring indication %s in channel in state %s (native bridge enabled)\n",
ftdm_channel_indication2str(indication),
ftdm_channel_state2str(ftdmchan->state));
status = FTDM_SUCCESS;
goto done;
}
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_IND_ACK_PENDING)) {
ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_WARNING, "Cannot indicate %s in channel with indication %s still pending in state %s\n",
ftdm_channel_indication2str(indication),
@ -2426,10 +2441,50 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_reset(const char *file, const char *func
return FTDM_SUCCESS;
}
FT_DECLARE(ftdm_status_t) ftdm_get_channel_from_string(const char *string_id, ftdm_span_t **out_span, ftdm_channel_t **out_channel)
{
ftdm_status_t status = FTDM_SUCCESS;
int rc = 0;
ftdm_span_t *span = NULL;
ftdm_channel_t *ftdmchan = NULL;
unsigned span_id = 0;
unsigned chan_id = 0;
*out_span = NULL;
*out_channel = NULL;
rc = sscanf(string_id, "%u:%u", &span_id, &chan_id);
if (rc != 2) {
ftdm_log(FTDM_LOG_ERROR, "Failed to parse channel id string '%s'\n", string_id);
status = FTDM_EINVAL;
goto done;
}
status = ftdm_span_find(span_id, &span);
if (status != FTDM_SUCCESS || !span) {
ftdm_log(FTDM_LOG_ERROR, "Failed to find span for channel id string '%s'\n", string_id);
status = FTDM_EINVAL;
goto done;
}
if (chan_id > (FTDM_MAX_CHANNELS_SPAN+1) || !(ftdmchan = span->channels[chan_id])) {
ftdm_log(FTDM_LOG_ERROR, "Invalid channel id string '%s'\n", string_id);
status = FTDM_EINVAL;
goto done;
}
status = FTDM_SUCCESS;
*out_span = span;
*out_channel = ftdmchan;
done:
return status;
}
/* this function MUST be called with the channel lock held with lock recursivity of 1 exactly,
* and the caller must be aware we might unlock the channel for a brief period of time and then lock it again */
static ftdm_status_t _ftdm_channel_call_place_nl(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan, ftdm_usrmsg_t *usrmsg)
{
const char *var = NULL;
ftdm_status_t status = FTDM_FAIL;
ftdm_assert_return(ftdmchan != NULL, FTDM_FAIL, "null channel");
@ -2465,6 +2520,16 @@ static ftdm_status_t _ftdm_channel_call_place_nl(const char *file, const char *f
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_CALL_STARTED);
ftdm_call_set_call_id(ftdmchan, &ftdmchan->caller_data);
var = ftdm_usrmsg_get_var(usrmsg, "sigbridge_peer");
if (var) {
ftdm_span_t *peer_span = NULL;
ftdm_channel_t *peer_chan = NULL;
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_NATIVE_SIGBRIDGE);
ftdm_get_channel_from_string(var, &peer_span, &peer_chan);
if (peer_chan) {
ftdm_set_flag(peer_chan, FTDM_CHANNEL_NATIVE_SIGBRIDGE);
}
}
/* if the signaling stack left the channel in state down on success, is expecting us to move to DIALING */
if (ftdmchan->state == FTDM_CHANNEL_STATE_DOWN) {
@ -2668,6 +2733,7 @@ static ftdm_status_t ftdm_channel_done(ftdm_channel_t *ftdmchan)
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_ANSWERED);
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_USER_HANGUP);
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_DIGITAL_MEDIA);
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_NATIVE_SIGBRIDGE);
ftdm_mutex_lock(ftdmchan->pre_buffer_mutex);
ftdm_buffer_destroy(&ftdmchan->pre_buffer);
ftdmchan->pre_buffer_size = 0;
@ -4853,14 +4919,15 @@ static ftdm_status_t load_config(void)
} else {
ftdm_log(FTDM_LOG_ERROR, "Invalid cpu alarm set threshold %s\n", val);
}
} else if (!strncasecmp(var, "cpu_reset_alarm_threshold", sizeof("cpu_reset_alarm_threshold")-1)) {
} else if (!strncasecmp(var, "cpu_reset_alarm_threshold", sizeof("cpu_reset_alarm_threshold")-1) ||
!strncasecmp(var, "cpu_clear_alarm_threshold", sizeof("cpu_clear_alarm_threshold")-1)) {
intparam = atoi(val);
if (intparam > 0 && intparam < 100) {
globals.cpu_monitor.reset_alarm_threshold = (uint8_t)intparam;
if (globals.cpu_monitor.reset_alarm_threshold > globals.cpu_monitor.set_alarm_threshold) {
globals.cpu_monitor.reset_alarm_threshold = globals.cpu_monitor.set_alarm_threshold - 10;
ftdm_log(FTDM_LOG_ERROR, "Cpu alarm reset threshold must be lower than set threshold"
", setting threshold to %d\n", globals.cpu_monitor.reset_alarm_threshold);
globals.cpu_monitor.clear_alarm_threshold = (uint8_t)intparam;
if (globals.cpu_monitor.clear_alarm_threshold > globals.cpu_monitor.set_alarm_threshold) {
globals.cpu_monitor.clear_alarm_threshold = globals.cpu_monitor.set_alarm_threshold - 10;
ftdm_log(FTDM_LOG_ERROR, "Cpu alarm clear threshold must be lower than set threshold, "
"setting clear threshold to %d\n", globals.cpu_monitor.clear_alarm_threshold);
}
} else {
ftdm_log(FTDM_LOG_ERROR, "Invalid cpu alarm reset threshold %s\n", val);
@ -5473,7 +5540,7 @@ static void execute_safety_hangup(void *data)
ftdm_channel_lock(fchan);
fchan->hangup_timer = 0;
if (fchan->state == FTDM_CHANNEL_STATE_TERMINATING) {
ftdm_log_chan(fchan, FTDM_LOG_CRIT, "Forcing hangup since the user did not confirmed our hangup after %dms\n", FORCE_HANGUP_TIMER);
ftdm_log_chan(fchan, FTDM_LOG_WARNING, "Forcing hangup since the user did not confirmed our hangup after %dms\n", FORCE_HANGUP_TIMER);
_ftdm_channel_call_hangup_nl(__FILE__, __FUNCTION__, __LINE__, fchan, NULL);
} else {
ftdm_log_chan(fchan, FTDM_LOG_CRIT, "Not performing safety hangup, channel state is %s\n", ftdm_channel_state2str(fchan->state));
@ -5604,28 +5671,32 @@ static void *ftdm_cpu_monitor_run(ftdm_thread_t *me, void *obj)
{
cpu_monitor_t *monitor = (cpu_monitor_t *)obj;
struct ftdm_cpu_monitor_stats *cpu_stats = ftdm_new_cpu_monitor();
ftdm_log(FTDM_LOG_DEBUG, "CPU monitor thread is now running\n");
if (!cpu_stats) {
return NULL;
goto done;
}
monitor->running = 1;
while(ftdm_running()) {
double time;
if (ftdm_cpu_get_system_idle_time(cpu_stats, &time)) {
while (ftdm_running()) {
double idle_time = 0.0;
int cpu_usage = 0;
if (ftdm_cpu_get_system_idle_time(cpu_stats, &idle_time)) {
break;
}
cpu_usage = (int)(100 - idle_time);
if (monitor->alarm) {
if ((int)time >= (100 - monitor->set_alarm_threshold)) {
ftdm_log(FTDM_LOG_DEBUG, "CPU alarm OFF (idle:%d)\n", (int) time);
if (cpu_usage <= monitor->clear_alarm_threshold) {
ftdm_log(FTDM_LOG_DEBUG, "CPU alarm is now OFF (cpu usage: %d)\n", cpu_usage);
monitor->alarm = 0;
}
if (monitor->alarm_action_flags & FTDM_CPU_ALARM_ACTION_WARN) {
ftdm_log(FTDM_LOG_WARNING, "CPU alarm is ON (cpu usage:%d)\n", (int) (100-time));
} else if (monitor->alarm_action_flags & FTDM_CPU_ALARM_ACTION_WARN) {
ftdm_log(FTDM_LOG_WARNING, "CPU alarm is still ON (cpu usage: %d)\n", cpu_usage);
}
} else {
if ((int)time <= (100-monitor->reset_alarm_threshold)) {
ftdm_log(FTDM_LOG_DEBUG, "CPU alarm ON (idle:%d)\n", (int) time);
if (cpu_usage >= monitor->set_alarm_threshold) {
ftdm_log(FTDM_LOG_WARNING, "CPU alarm is now ON (cpu usage: %d)\n", cpu_usage);
monitor->alarm = 1;
}
}
@ -5634,7 +5705,11 @@ static void *ftdm_cpu_monitor_run(ftdm_thread_t *me, void *obj)
ftdm_delete_cpu_monitor(cpu_stats);
monitor->running = 0;
done:
ftdm_log(FTDM_LOG_DEBUG, "CPU monitor thread is now terminating\n");
return NULL;
#ifdef __WINDOWS__
UNREFERENCED_PARAMETER(me);
#endif
@ -5736,8 +5811,8 @@ FT_DECLARE(ftdm_status_t) ftdm_global_configuration(void)
globals.cpu_monitor.enabled = 0;
globals.cpu_monitor.interval = 1000;
globals.cpu_monitor.alarm_action_flags = 0;
globals.cpu_monitor.set_alarm_threshold = 80;
globals.cpu_monitor.reset_alarm_threshold = 70;
globals.cpu_monitor.set_alarm_threshold = 92;
globals.cpu_monitor.clear_alarm_threshold = 82;
if (load_config() != FTDM_SUCCESS) {
globals.running = 0;
@ -5746,10 +5821,10 @@ FT_DECLARE(ftdm_status_t) ftdm_global_configuration(void)
}
if (globals.cpu_monitor.enabled) {
ftdm_log(FTDM_LOG_INFO, "CPU Monitor is running interval:%d lo-thres:%d hi-thres:%d\n",
ftdm_log(FTDM_LOG_INFO, "CPU Monitor is running interval:%d set-thres:%d clear-thres:%d\n",
globals.cpu_monitor.interval,
globals.cpu_monitor.set_alarm_threshold,
globals.cpu_monitor.reset_alarm_threshold);
globals.cpu_monitor.clear_alarm_threshold);
if (ftdm_cpu_monitor_start() != FTDM_SUCCESS) {
return FTDM_FAIL;

View File

@ -87,6 +87,7 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_complete_state(const char *file, const c
ftdm_assert(!fchan->history[hindex].end_time, "End time should be zero!\n");
fchan->history[hindex].end_time = ftdm_current_time_in_ms();
fchan->last_state_change_time = ftdm_current_time_in_ms();
fchan->state_status = FTDM_STATE_STATUS_COMPLETED;
@ -262,6 +263,9 @@ static ftdm_status_t ftdm_core_set_state(const char *file, const char *func, int
}
}
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_NATIVE_SIGBRIDGE)) {
goto perform_state_change;
}
if (ftdmchan->span->state_map) {
ok = ftdm_parse_state_map(ftdmchan, state, ftdmchan->span->state_map);
@ -353,6 +357,8 @@ end:
goto done;
}
perform_state_change:
ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_DEBUG, "Changed state from %s to %s\n", ftdm_channel_state2str(ftdmchan->state), ftdm_channel_state2str(state));
ftdmchan->last_state = ftdmchan->state;
ftdmchan->state = state;

View File

@ -77,7 +77,9 @@ int ft_to_sngss7_cfg_all(void)
int ret = 0;
/* check if we have done gen_config already */
if (!(g_ftdm_sngss7_data.gen_config)) {
if (g_ftdm_sngss7_data.gen_config == SNG_GEN_CFG_STATUS_INIT) {
/* update the global gen_config so we don't do it again */
g_ftdm_sngss7_data.gen_config = SNG_GEN_CFG_STATUS_PENDING;
/* start of by checking if the license and sig file are valid */
if (sng_validate_license(g_ftdm_sngss7_data.cfg.license,
@ -92,7 +94,7 @@ int ft_to_sngss7_cfg_all(void)
/* set the desired procID value */
sng_set_procId((uint16_t)g_ftdm_sngss7_data.cfg.procId);
}
/* start up the stack manager */
if (sng_isup_init_sm()) {
SS7_CRITICAL("Failed to start Stack Manager\n");
@ -207,30 +209,15 @@ int ft_to_sngss7_cfg_all(void)
}
} /* if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP2)) */
/* update the global gen_config so we don't do it again */
g_ftdm_sngss7_data.gen_config = 1;
g_ftdm_sngss7_data.gen_config = SNG_GEN_CFG_STATUS_DONE;
} /* if (!(g_ftdm_sngss7_data.gen_config)) */
/* go through all the relays channels and configure it */
x = 1;
while (x < (MAX_RELAY_CHANNELS)) {
/* check if this relay channel has been configured already */
if ((g_ftdm_sngss7_data.cfg.relay[x].id != 0) &&
(!(g_ftdm_sngss7_data.cfg.relay[x].flags & SNGSS7_CONFIGURED))) {
/* send the specific configuration */
if (ftmod_ss7_relay_chan_config(x)) {
SS7_CRITICAL("Relay Channel %d configuration FAILED!\n", x);
return 1;
} else {
SS7_INFO("Relay Channel %d configuration DONE!\n", x);
}
/* set the SNGSS7_CONFIGURED flag */
g_ftdm_sngss7_data.cfg.relay[x].flags |= SNGSS7_CONFIGURED;
} /* if !SNGSS7_CONFIGURED */
x++;
} /* while (x < (MAX_RELAY_CHANNELS)) */
if (g_ftdm_sngss7_data.gen_config != SNG_GEN_CFG_STATUS_DONE) {
SS7_CRITICAL("General configuration FAILED!\n");
return 1;
}
x = 1;
while (x < (MAX_MTP_LINKS)) {
@ -272,160 +259,189 @@ int ft_to_sngss7_cfg_all(void)
x++;
} /* while (x < (MAX_MTP_LINKS+1)) */
x = 1;
while (x < (MAX_MTP_LINKS)) {
/* check if this link has been configured already */
if ((g_ftdm_sngss7_data.cfg.mtp3Link[x].id != 0) &&
(!(g_ftdm_sngss7_data.cfg.mtp3Link[x].flags & SNGSS7_CONFIGURED))) {
/* configure mtp3 */
if (ftmod_ss7_mtp3_dlsap_config(x)) {
SS7_CRITICAL("MTP3 DLSAP %d configuration FAILED!\n", x);
return 1;;
} else {
SS7_INFO("MTP3 DLSAP %d configuration DONE!\n", x);
}
/* set the SNGSS7_CONFIGURED flag */
g_ftdm_sngss7_data.cfg.mtp3Link[x].flags |= SNGSS7_CONFIGURED;
}
x++;
} /* while (x < (MAX_MTP_LINKS+1)) */
x = 1;
while (x < (MAX_NSAPS)) {
/* check if this link has been configured already */
if ((g_ftdm_sngss7_data.cfg.nsap[x].id != 0) &&
(!(g_ftdm_sngss7_data.cfg.nsap[x].flags & SNGSS7_CONFIGURED))) {
ret = ftmod_ss7_mtp3_nsap_config(x);
if (ret) {
SS7_CRITICAL("MTP3 NSAP %d configuration FAILED!(%s)\n", x, DECODE_LCM_REASON(ret));
return 1;
} else {
SS7_INFO("MTP3 NSAP %d configuration DONE!\n", x);
}
ret = ftmod_ss7_isup_nsap_config(x);
if (ret) {
SS7_CRITICAL("ISUP NSAP %d configuration FAILED!(%s)\n", x, DECODE_LCM_REASON(ret));
return 1;
} else {
SS7_INFO("ISUP NSAP %d configuration DONE!\n", x);
}
/* set the SNGSS7_CONFIGURED flag */
g_ftdm_sngss7_data.cfg.nsap[x].flags |= SNGSS7_CONFIGURED;
} /* if !SNGSS7_CONFIGURED */
x++;
} /* while (x < (MAX_NSAPS)) */
x = 1;
while (x < (MAX_MTP_LINKSETS+1)) {
/* check if this link has been configured already */
if ((g_ftdm_sngss7_data.cfg.mtpLinkSet[x].id != 0) &&
(!(g_ftdm_sngss7_data.cfg.mtpLinkSet[x].flags & SNGSS7_CONFIGURED))) {
if (ftmod_ss7_mtp3_linkset_config(x)) {
SS7_CRITICAL("MTP3 LINKSET %d configuration FAILED!\n", x);
return 1;
} else {
SS7_INFO("MTP3 LINKSET %d configuration DONE!\n", x);
}
/* set the SNGSS7_CONFIGURED flag */
g_ftdm_sngss7_data.cfg.mtpLinkSet[x].flags |= SNGSS7_CONFIGURED;
} /* if !SNGSS7_CONFIGURED */
x++;
} /* while (x < (MAX_MTP_LINKSETS+1)) */
x = 1;
while (x < (MAX_MTP_ROUTES+1)) {
/* check if this link has been configured already */
if ((g_ftdm_sngss7_data.cfg.mtpRoute[x].id != 0) &&
(!(g_ftdm_sngss7_data.cfg.mtpRoute[x].flags & SNGSS7_CONFIGURED))) {
if (ftmod_ss7_mtp3_route_config(x)) {
SS7_CRITICAL("MTP3 ROUTE %d configuration FAILED!\n", x);
return 1;
} else {
SS7_INFO("MTP3 ROUTE %d configuration DONE!\n",x);
}
/* set the SNGSS7_CONFIGURED flag */
g_ftdm_sngss7_data.cfg.mtpRoute[x].flags |= SNGSS7_CONFIGURED;
} /* if !SNGSS7_CONFIGURED */
x++;
} /* while (x < (MAX_MTP_ROUTES+1)) */
x = 1;
while (x < (MAX_ISAPS)) {
/* check if this link has been configured already */
if ((g_ftdm_sngss7_data.cfg.isap[x].id != 0) &&
(!(g_ftdm_sngss7_data.cfg.isap[x].flags & SNGSS7_CONFIGURED))) {
if (ftmod_ss7_isup_isap_config(x)) {
SS7_CRITICAL("ISUP ISAP %d configuration FAILED!\n", x);
return 1;
} else {
SS7_INFO("ISUP ISAP %d configuration DONE!\n", x);
}
/* set the SNGSS7_CONFIGURED flag */
g_ftdm_sngss7_data.cfg.isap[x].flags |= SNGSS7_CONFIGURED;
} /* if !SNGSS7_CONFIGURED */
x++;
} /* while (x < (MAX_ISAPS)) */
if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_ISUP_STARTED)) {
/* no configs above mtp2 for relay */
if (g_ftdm_sngss7_data.cfg.procId == 1) {
x = 1;
while (x < (MAX_ISUP_INFS)) {
while (x < (MAX_MTP_LINKS)) {
/* check if this link has been configured already */
if ((g_ftdm_sngss7_data.cfg.isupIntf[x].id != 0) &&
(!(g_ftdm_sngss7_data.cfg.isupIntf[x].flags & SNGSS7_CONFIGURED))) {
if (ftmod_ss7_isup_intf_config(x)) {
SS7_CRITICAL("ISUP INTF %d configuration FAILED!\n", x);
if ((g_ftdm_sngss7_data.cfg.mtp3Link[x].id != 0) &&
(!(g_ftdm_sngss7_data.cfg.mtp3Link[x].flags & SNGSS7_CONFIGURED))) {
/* configure mtp3 */
if (ftmod_ss7_mtp3_dlsap_config(x)) {
SS7_CRITICAL("MTP3 DLSAP %d configuration FAILED!\n", x);
return 1;;
} else {
SS7_INFO("MTP3 DLSAP %d configuration DONE!\n", x);
}
/* set the SNGSS7_CONFIGURED flag */
g_ftdm_sngss7_data.cfg.mtp3Link[x].flags |= SNGSS7_CONFIGURED;
}
x++;
} /* while (x < (MAX_MTP_LINKS+1)) */
x = 1;
while (x < (MAX_NSAPS)) {
/* check if this link has been configured already */
if ((g_ftdm_sngss7_data.cfg.nsap[x].id != 0) &&
(!(g_ftdm_sngss7_data.cfg.nsap[x].flags & SNGSS7_CONFIGURED))) {
ret = ftmod_ss7_mtp3_nsap_config(x);
if (ret) {
SS7_CRITICAL("MTP3 NSAP %d configuration FAILED!(%s)\n", x, DECODE_LCM_REASON(ret));
return 1;
} else {
SS7_INFO("ISUP INTF %d configuration DONE!\n", x);
/* set the interface to paused */
sngss7_set_flag(&g_ftdm_sngss7_data.cfg.isupIntf[x], SNGSS7_PAUSED);
SS7_INFO("MTP3 NSAP %d configuration DONE!\n", x);
}
ret = ftmod_ss7_isup_nsap_config(x);
if (ret) {
SS7_CRITICAL("ISUP NSAP %d configuration FAILED!(%s)\n", x, DECODE_LCM_REASON(ret));
return 1;
} else {
SS7_INFO("ISUP NSAP %d configuration DONE!\n", x);
}
/* set the SNGSS7_CONFIGURED flag */
g_ftdm_sngss7_data.cfg.isupIntf[x].flags |= SNGSS7_CONFIGURED;
g_ftdm_sngss7_data.cfg.nsap[x].flags |= SNGSS7_CONFIGURED;
} /* if !SNGSS7_CONFIGURED */
x++;
} /* while (x < (MAX_ISUP_INFS)) */
} /* if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_ISUP)) */
} /* while (x < (MAX_NSAPS)) */
x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1;
while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) {
/* check if this link has been configured already */
if ((g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) &&
(!(g_ftdm_sngss7_data.cfg.isupCkt[x].flags & SNGSS7_CONFIGURED))) {
x = 1;
while (x < (MAX_MTP_LINKSETS+1)) {
/* check if this link has been configured already */
if ((g_ftdm_sngss7_data.cfg.mtpLinkSet[x].id != 0) &&
(!(g_ftdm_sngss7_data.cfg.mtpLinkSet[x].flags & SNGSS7_CONFIGURED))) {
if (ftmod_ss7_isup_ckt_config(x)) {
SS7_CRITICAL("ISUP CKT %d configuration FAILED!\n", x);
if (ftmod_ss7_mtp3_linkset_config(x)) {
SS7_CRITICAL("MTP3 LINKSET %d configuration FAILED!\n", x);
return 1;
} else {
SS7_INFO("MTP3 LINKSET %d configuration DONE!\n", x);
}
/* set the SNGSS7_CONFIGURED flag */
g_ftdm_sngss7_data.cfg.mtpLinkSet[x].flags |= SNGSS7_CONFIGURED;
} /* if !SNGSS7_CONFIGURED */
x++;
} /* while (x < (MAX_MTP_LINKSETS+1)) */
x = 1;
while (x < (MAX_MTP_ROUTES+1)) {
/* check if this link has been configured already */
if ((g_ftdm_sngss7_data.cfg.mtpRoute[x].id != 0) &&
(!(g_ftdm_sngss7_data.cfg.mtpRoute[x].flags & SNGSS7_CONFIGURED))) {
if (ftmod_ss7_mtp3_route_config(x)) {
SS7_CRITICAL("MTP3 ROUTE %d configuration FAILED!\n", x);
return 1;
} else {
SS7_INFO("MTP3 ROUTE %d configuration DONE!\n",x);
}
/* set the SNGSS7_CONFIGURED flag */
g_ftdm_sngss7_data.cfg.mtpRoute[x].flags |= SNGSS7_CONFIGURED;
} /* if !SNGSS7_CONFIGURED */
x++;
} /* while (x < (MAX_MTP_ROUTES+1)) */
x = 1;
while (x < (MAX_ISAPS)) {
/* check if this link has been configured already */
if ((g_ftdm_sngss7_data.cfg.isap[x].id != 0) &&
(!(g_ftdm_sngss7_data.cfg.isap[x].flags & SNGSS7_CONFIGURED))) {
if (ftmod_ss7_isup_isap_config(x)) {
SS7_CRITICAL("ISUP ISAP %d configuration FAILED!\n", x);
return 1;
} else {
SS7_INFO("ISUP ISAP %d configuration DONE!\n", x);
}
/* set the SNGSS7_CONFIGURED flag */
g_ftdm_sngss7_data.cfg.isap[x].flags |= SNGSS7_CONFIGURED;
} /* if !SNGSS7_CONFIGURED */
x++;
} /* while (x < (MAX_ISAPS)) */
if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_ISUP_STARTED)) {
x = 1;
while (x < (MAX_ISUP_INFS)) {
/* check if this link has been configured already */
if ((g_ftdm_sngss7_data.cfg.isupIntf[x].id != 0) &&
(!(g_ftdm_sngss7_data.cfg.isupIntf[x].flags & SNGSS7_CONFIGURED))) {
if (ftmod_ss7_isup_intf_config(x)) {
SS7_CRITICAL("ISUP INTF %d configuration FAILED!\n", x);
return 1;
} else {
SS7_INFO("ISUP INTF %d configuration DONE!\n", x);
/* set the interface to paused */
sngss7_set_flag(&g_ftdm_sngss7_data.cfg.isupIntf[x], SNGSS7_PAUSED);
}
/* set the SNGSS7_CONFIGURED flag */
g_ftdm_sngss7_data.cfg.isupIntf[x].flags |= SNGSS7_CONFIGURED;
} /* if !SNGSS7_CONFIGURED */
x++;
} /* while (x < (MAX_ISUP_INFS)) */
} /* if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_ISUP)) */
x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1;
while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) {
if (g_ftdm_sngss7_data.cfg.procId > 1) {
break;
}
/* check if this link has been configured already */
if ((g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) &&
(!(g_ftdm_sngss7_data.cfg.isupCkt[x].flags & SNGSS7_CONFIGURED))) {
if (ftmod_ss7_isup_ckt_config(x)) {
SS7_CRITICAL("ISUP CKT %d configuration FAILED!\n", x);
return 1;
} else {
SS7_INFO("ISUP CKT %d configuration DONE!\n", x);
}
/* set the SNGSS7_CONFIGURED flag */
g_ftdm_sngss7_data.cfg.isupCkt[x].flags |= SNGSS7_CONFIGURED;
} /* if !SNGSS7_CONFIGURED */
x++;
} /* while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) */
}
/* go through all the relays channels and configure it */
x = 1;
while (x < (MAX_RELAY_CHANNELS)) {
/* check if this relay channel has been configured already */
if ((g_ftdm_sngss7_data.cfg.relay[x].id != 0) &&
(!(g_ftdm_sngss7_data.cfg.relay[x].flags & SNGSS7_CONFIGURED))) {
/* send the specific configuration */
if (ftmod_ss7_relay_chan_config(x)) {
SS7_CRITICAL("Relay Channel %d configuration FAILED!\n", x);
return 1;
} else {
SS7_INFO("ISUP CKT %d configuration DONE!\n", x);
SS7_INFO("Relay Channel %d configuration DONE!\n", x);
}
/* set the SNGSS7_CONFIGURED flag */
g_ftdm_sngss7_data.cfg.isupCkt[x].flags |= SNGSS7_CONFIGURED;
g_ftdm_sngss7_data.cfg.relay[x].flags |= SNGSS7_CONFIGURED;
} /* if !SNGSS7_CONFIGURED */
x++;
} /* while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) */
} /* while (x < (MAX_RELAY_CHANNELS)) */
return 0;
}

View File

@ -460,7 +460,6 @@ ftdm_status_t ftdm_sngss7_handle_cli_cmd(ftdm_stream_handle_t *stream, const cha
}
/**************************************************************************/
} else if (!strcasecmp(argv[c], "blo")) {
/**************************************************************************/
if (check_arg_count(argc, 2)) goto handle_cli_error_argc;
c++;
@ -1632,7 +1631,9 @@ static ftdm_status_t handle_tx_rsc(ftdm_stream_handle_t *stream, int span, int c
ftdm_mutex_lock(ftdmchan->mutex);
/* throw the reset flag */
sngss7_set_ckt_flag(sngss7_info, FLAG_RESET_TX);
sngss7_set_ckt_flag (sngss7_info, FLAG_LOCAL_REL);
sngss7_clear_ckt_flag (sngss7_info, FLAG_REMOTE_REL);
sngss7_tx_reset_restart(sngss7_info);
switch (ftdmchan->state) {
/**************************************************************************/

View File

@ -48,35 +48,7 @@ static int ftmod_ss7_enable_isap(int suId);
static int ftmod_ss7_enable_nsap(int suId);
static int ftmod_ss7_enable_mtpLinkSet(int lnkSetId);
int ftmod_ss7_inhibit_mtp3link(uint32_t id);
int ftmod_ss7_uninhibit_mtp3link(uint32_t id);
int ftmod_ss7_bind_mtp3link(uint32_t id);
int ftmod_ss7_unbind_mtp3link(uint32_t id);
int ftmod_ss7_activate_mtp3link(uint32_t id);
int ftmod_ss7_deactivate_mtp3link(uint32_t id);
int ftmod_ss7_deactivate2_mtp3link(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_mtp3link(uint32_t id);
int ftmod_ss7_lpr_mtp3link(uint32_t id);
int ftmod_ss7_shutdown_isup(void);
int ftmod_ss7_shutdown_mtp3(void);
int ftmod_ss7_shutdown_mtp2(void);
int ftmod_ss7_shutdown_relay(void);
int ftmod_ss7_disable_relay_channel(uint32_t chanId);
int ftmod_ss7_disable_grp_mtp3Link(uint32_t procId);
int ftmod_ss7_enable_grp_mtp3Link(uint32_t procId);
int ftmod_ss7_disable_grp_mtp2Link(uint32_t procId);
int ftmod_ss7_block_isup_ckt(uint32_t cktId);
int ftmod_ss7_unblock_isup_ckt(uint32_t cktId);
/******************************************************************************/
/* FUNCTIONS ******************************************************************/
@ -779,7 +751,14 @@ int ftmod_ss7_disable_grp_mtp3Link(uint32_t procId)
cntrl.t.cntrl.action = AUBND_DIS; /* disable and unbind */
cntrl.t.cntrl.subAction = SAGR_DSTPROCID; /* specificed element */
return (sng_cntrl_mtp3(&pst, &cntrl));
if (g_ftdm_sngss7_data.cfg.procId == procId) {
SS7_DEBUG("Executing MTP3 cntrl command local pid =%i\n",procId);
return (sng_cntrl_mtp3(&pst, &cntrl));
} else {
SS7_WARN("Executing MTP3 cntrl command different local=%i target=%i\n",
g_ftdm_sngss7_data.cfg.procId,procId);
return (sng_cntrl_mtp3_nowait(&pst, &cntrl));
}
}
@ -811,7 +790,14 @@ int ftmod_ss7_enable_grp_mtp3Link(uint32_t procId)
cntrl.t.cntrl.action = ABND_ENA; /* bind and enable */
cntrl.t.cntrl.subAction = SAGR_DSTPROCID; /* specificed element */
return (sng_cntrl_mtp3(&pst, &cntrl));
if (g_ftdm_sngss7_data.cfg.procId == procId) {
SS7_DEBUG("Executing MTP3 cntrl command local pid =%i\n",procId);
return (sng_cntrl_mtp3(&pst, &cntrl));
} else {
SS7_WARN("Executing MTP3 cntrl command different local=%i target=%i\n",
g_ftdm_sngss7_data.cfg.procId,procId);
return (sng_cntrl_mtp3_nowait(&pst, &cntrl));
}
}
@ -848,7 +834,7 @@ int ftmod_ss7_disable_grp_mtp2Link(uint32_t procId)
}
/******************************************************************************/
int ftmod_ss7_block_isup_ckt(uint32_t cktId)
int __ftmod_ss7_block_isup_ckt(uint32_t cktId, ftdm_bool_t wait)
{
SiMngmt cntrl;
Pst pst;
@ -876,7 +862,11 @@ int ftmod_ss7_block_isup_ckt(uint32_t cktId)
cntrl.t.cntrl.action = ADISIMM; /* block via BLO */
cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */
return (sng_cntrl_isup(&pst, &cntrl));
if (wait == FTDM_TRUE) {
return (sng_cntrl_isup(&pst, &cntrl));
} else {
return (sng_cntrl_isup_nowait(&pst, &cntrl));
}
}
/******************************************************************************/

View File

@ -87,6 +87,8 @@ ftdm_status_t handle_olm_msg(uint32_t suInstId, uint32_t spInstId, uint32_t circ
/* FUNCTIONS ******************************************************************/
#define ftdm_running_return(var) if (!ftdm_running()) { SS7_ERROR("Error: ftdm_running is not set! Ignoring\n"); return var; }
ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt)
{
SS7_FUNC_TRACE_ENTER(__FUNCTION__);
@ -97,6 +99,8 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
memset(var, '\0', sizeof(var));
ftdm_running_return(FTDM_FAIL);
/* 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);
@ -118,8 +122,11 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
/* as per Q.764, 2.8.2.3 xiv ... remove the block from this channel */
sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX);
sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX_DN);
sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX);
sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX_DN);
sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX);
sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX_DN);
/* KONRAD FIX ME : check in case there is a ckt and grp block */
}
@ -194,10 +201,11 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
}
copy_redirgNum_from_sngss7(ftdmchan, &siConEvnt->redirgNum);
copy_redirgInfo_from_sngss7(ftdmchan, &siConEvnt->redirInfo);
copy_genNmb_from_sngss7(ftdmchan, &siConEvnt->genNmb);
copy_cgPtyCat_from_sngss7(ftdmchan, &siConEvnt->cgPtyCat);
copy_cdPtyNum_from_sngss7(ftdmchan, &siConEvnt->cdPtyNum);
/* fill in the TMR/bearer capability */
if (siConEvnt->txMedReq.eh.pres) {
@ -213,9 +221,6 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
sprintf(var, "%d", siConEvnt->cgPtyNum.natAddrInd.val);
sngss7_add_var(sngss7_info, "ss7_clg_nadi", var);
sprintf(var, "%d", siConEvnt->cdPtyNum.natAddrInd.val);
sngss7_add_var(sngss7_info, "ss7_cld_nadi", var);
/* Retrieve the Location Number if present (see ITU Q.763, 3.30) */
if (siConEvnt->cgPtyNum1.eh.pres) {
if (siConEvnt->cgPtyNum1.addrSig.pres) {
@ -247,7 +252,8 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
sprintf(var, "%d", sngss7_info->circuit->cic);
sngss7_add_var(sngss7_info, "ss7_cic", var);
sprintf(var, "%d", g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId].spc );
sprintf(var, "%d", g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId].dpc );
sngss7_add_var(sngss7_info, "ss7_opc", var);
if (siConEvnt->callRef.callId.pres) {
@ -320,12 +326,14 @@ handle_glare:
default: /* should not have gotten an IAM while in this state */
SS7_ERROR_CHAN(ftdmchan, "Got IAM on channel in invalid state(%s)...reset!\n", ftdm_channel_state2str (ftdmchan->state));
/* reset the cic */
sngss7_set_ckt_flag(sngss7_info, FLAG_RESET_TX);
/* move the state of the channel to RESTART to force a reset */
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
/* throw the TX reset flag */
if (!sngss7_tx_reset_status_pending(sngss7_info)) {
sngss7_tx_reset_restart(sngss7_info);
sngss7_set_ckt_flag (sngss7_info, FLAG_REMOTE_REL);
/* go to RESTART */
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
}
break;
/**************************************************************************/
} /* switch (ftdmchan->state) */
@ -344,6 +352,8 @@ ftdm_status_t handle_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circ
sngss7_chan_data_t *sngss7_info ;
ftdm_channel_t *ftdmchan;
ftdm_running_return(FTDM_FAIL);
/* get the ftdmchan and ss7_chan_data from the circuit */
if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
@ -389,11 +399,14 @@ ftdm_status_t handle_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circ
SS7_ERROR_CHAN(ftdmchan, "RX ACM in invalid state :%s...resetting CIC\n",
ftdm_channel_state2str (ftdmchan->state));
/* reset the cic */
sngss7_set_ckt_flag(sngss7_info, FLAG_RESET_TX);
/* throw the TX reset flag */
if (!sngss7_tx_reset_status_pending(sngss7_info)) {
sngss7_tx_reset_restart(sngss7_info);
sngss7_set_ckt_flag (sngss7_info, FLAG_REMOTE_REL);
/* go to RESTART */
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
/* go to RESTART */
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
}
break;
/**********************************************************************/
} /* switch (ftdmchan->state) */
@ -599,6 +612,8 @@ ftdm_status_t handle_con_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circ
sngss7_chan_data_t *sngss7_info ;
ftdm_channel_t *ftdmchan;
ftdm_running_return(FTDM_FAIL);
/* get the ftdmchan and ss7_chan_data from the circuit */
if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
@ -651,10 +666,13 @@ ftdm_status_t handle_con_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circ
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx ANM/CON\n", sngss7_info->circuit->cic);
/* throw the TX reset flag */
sngss7_set_ckt_flag(sngss7_info, FLAG_GRP_RESET_TX);
if (!sngss7_tx_reset_status_pending(sngss7_info)) {
sngss7_tx_reset_restart(sngss7_info);
sngss7_set_ckt_flag (sngss7_info, FLAG_REMOTE_REL);
/* go to RESTART */
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
/* go to RESTART */
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
}
break;
/**************************************************************************/
@ -674,6 +692,8 @@ ftdm_status_t handle_rel_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
sngss7_chan_data_t *sngss7_info ;
ftdm_channel_t *ftdmchan;
ftdm_running_return(FTDM_FAIL);
/* get the ftdmchan and ss7_chan_data from the circuit */
if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
@ -750,6 +770,10 @@ ftdm_status_t handle_rel_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
/* send out the release complete */
ft_to_sngss7_rlc (ftdmchan);
} else {
SS7_DEBUG_CHAN(ftdmchan, "Collision of REL messages - resetting state.\n", " ");
ft_to_sngss7_rlc (ftdmchan);
goto rel_ind_reset;
}
break;
/**************************************************************************/
@ -772,11 +796,15 @@ ftdm_status_t handle_rel_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
/**************************************************************************/
default:
/* throw the reset flag */
sngss7_set_ckt_flag(sngss7_info, FLAG_RESET_RX);
rel_ind_reset:
/* throw the TX reset flag */
if (!sngss7_tx_reset_status_pending(sngss7_info)) {
sngss7_set_ckt_flag (sngss7_info, FLAG_REMOTE_REL);
sngss7_tx_reset_restart(sngss7_info);
/* set the state to RESTART */
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
/* go to RESTART */
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
}
break;
/**************************************************************************/
} /* switch (ftdmchan->state) */
@ -796,6 +824,8 @@ ftdm_status_t handle_rel_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circ
sngss7_chan_data_t *sngss7_info ;
ftdm_channel_t *ftdmchan;
ftdm_running_return(FTDM_FAIL);
/* get the ftdmchan and ss7_chan_data from the circuit */
if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
@ -847,6 +877,8 @@ ftdm_status_t handle_dat_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
sngss7_chan_data_t *sngss7_info ;
ftdm_channel_t *ftdmchan;
ftdm_running_return(FTDM_FAIL);
/* get the ftdmchan and ss7_chan_data from the circuit */
if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
@ -874,6 +906,8 @@ ftdm_status_t handle_fac_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
sngss7_chan_data_t *sngss7_info ;
ftdm_channel_t *ftdmchan;
ftdm_running_return(FTDM_FAIL);
/* get the ftdmchan and ss7_chan_data from the circuit */
if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
@ -901,6 +935,8 @@ ftdm_status_t handle_fac_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circ
sngss7_chan_data_t *sngss7_info ;
ftdm_channel_t *ftdmchan;
ftdm_running_return(FTDM_FAIL);
/* get the ftdmchan and ss7_chan_data from the circuit */
if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
@ -928,6 +964,8 @@ ftdm_status_t handle_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t cir
sngss7_chan_data_t *sngss7_info ;
ftdm_channel_t *ftdmchan;
ftdm_running_return(FTDM_FAIL);
/* get the ftdmchan and ss7_chan_data from the circuit */
if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
@ -955,6 +993,8 @@ ftdm_status_t handle_susp_ind(uint32_t suInstId, uint32_t spInstId, uint32_t cir
sngss7_chan_data_t *sngss7_info ;
ftdm_channel_t *ftdmchan;
ftdm_running_return(FTDM_FAIL);
/* get the ftdmchan and ss7_chan_data from the circuit */
if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
@ -982,6 +1022,8 @@ ftdm_status_t handle_resm_ind(uint32_t suInstId, uint32_t spInstId, uint32_t cir
sngss7_chan_data_t *sngss7_info ;
ftdm_channel_t *ftdmchan;
ftdm_running_return(FTDM_FAIL);
/* get the ftdmchan and ss7_chan_data from the circuit */
if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
@ -1006,6 +1048,8 @@ ftdm_status_t handle_resm_ind(uint32_t suInstId, uint32_t spInstId, uint32_t cir
ftdm_status_t handle_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt)
{
SS7_FUNC_TRACE_ENTER(__FUNCTION__);
ftdm_running_return(FTDM_FAIL);
/* confirm that the circuit is active on our side otherwise move to the next circuit */
if (!sngss7_test_flag(&g_ftdm_sngss7_data.cfg.isupCkt[circuit], SNGSS7_ACTIVE)) {
@ -1206,6 +1250,8 @@ ftdm_status_t handle_reattempt(uint32_t suInstId, uint32_t spInstId, uint32_t ci
sngss7_chan_data_t *sngss7_info = NULL;
ftdm_channel_t *ftdmchan = NULL;
ftdm_running_return(FTDM_FAIL);
/* confirm that the circuit is voice channel */
if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) {
@ -1269,6 +1315,8 @@ ftdm_status_t handle_pause(uint32_t suInstId, uint32_t spInstId, uint32_t circui
int infId;
int i;
ftdm_running_return(FTDM_FAIL);
/* extract the affected infId from the circuit structure */
infId = g_ftdm_sngss7_data.cfg.isupCkt[circuit].infId;
@ -1333,6 +1381,8 @@ ftdm_status_t handle_resume(uint32_t suInstId, uint32_t spInstId, uint32_t circu
ftdm_channel_t *ftdmchan = NULL;
int infId;
int i;
ftdm_running_return(FTDM_FAIL);
/* extract the affect infId from the circuit structure */
infId = g_ftdm_sngss7_data.cfg.isupCkt[circuit].infId;
@ -1397,6 +1447,8 @@ ftdm_status_t handle_cot_start(uint32_t suInstId, uint32_t spInstId, uint32_t ci
sngss7_chan_data_t *sngss7_info = NULL;
ftdm_channel_t *ftdmchan = NULL;
ftdm_running_return(FTDM_FAIL);
/* confirm that the circuit is voice channel */
if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) {
@ -1452,6 +1504,8 @@ ftdm_status_t handle_cot_stop(uint32_t suInstId, uint32_t spInstId, uint32_t cir
sngss7_chan_data_t *sngss7_info = NULL;
ftdm_channel_t *ftdmchan = NULL;
ftdm_running_return(FTDM_FAIL);
/* confirm that the circuit is voice channel */
if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) {
@ -1497,6 +1551,8 @@ ftdm_status_t handle_cot(uint32_t suInstId, uint32_t spInstId, uint32_t circuit,
sngss7_chan_data_t *sngss7_info = NULL;
ftdm_channel_t *ftdmchan = NULL;
ftdm_running_return(FTDM_FAIL);
/* confirm that the circuit is voice channel */
if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) {
@ -1565,6 +1621,8 @@ ftdm_status_t handle_blo_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ
sngss7_chan_data_t *sngss7_info = NULL;
ftdm_channel_t *ftdmchan = NULL;
ftdm_running_return(FTDM_FAIL);
/* confirm that the circuit is voice channel */
if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) {
@ -1597,6 +1655,7 @@ ftdm_status_t handle_blo_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ
/* throw the ckt block flag */
sngss7_set_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX);
sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX_DN);
/* set the channel to suspended state */
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED);
@ -1615,6 +1674,8 @@ ftdm_status_t handle_blo_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circ
sngss7_chan_data_t *sngss7_info = NULL;
ftdm_channel_t *ftdmchan = NULL;
ftdm_running_return(FTDM_FAIL);
/* confirm that the circuit is voice channel */
if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) {
@ -1656,6 +1717,8 @@ ftdm_status_t handle_ubl_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ
sngss7_chan_data_t *sngss7_info = NULL;
ftdm_channel_t *ftdmchan = NULL;
ftdm_running_return(FTDM_FAIL);
/* confirm that the circuit is voice channel */
if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) {
@ -1744,6 +1807,8 @@ ftdm_status_t handle_rsc_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ
sngss7_chan_data_t *sngss7_info = NULL;
ftdm_channel_t *ftdmchan = NULL;
ftdm_running_return(FTDM_FAIL);
/* confirm that the circuit is voice channel */
if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) {
@ -1784,6 +1849,7 @@ ftdm_status_t handle_rsc_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ
default:
/* set the state of the channel to restart...the rest is done by the chan monitor */
sngss7_set_ckt_flag(sngss7_info, FLAG_REMOTE_REL);
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
break;
/**************************************************************************/
@ -1803,6 +1869,8 @@ ftdm_status_t handle_local_rsc_req(uint32_t suInstId, uint32_t spInstId, uint32_
sngss7_chan_data_t *sngss7_info = NULL;
ftdm_channel_t *ftdmchan = NULL;
ftdm_running_return(FTDM_FAIL);
/* confirm that the circuit is voice channel */
if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) {
@ -1861,6 +1929,8 @@ ftdm_status_t handle_rsc_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circ
sngss7_chan_data_t *sngss7_info = NULL;
ftdm_channel_t *ftdmchan = NULL;
ftdm_running_return(FTDM_FAIL);
/* confirm that the circuit is voice channel */
if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) {
@ -1917,7 +1987,7 @@ ftdm_status_t handle_rsc_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circ
sngss7_set_ckt_flag(sngss7_info, FLAG_RESET_TX_RSP);
/* go to DOWN */
/*ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN);*/
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
break;
/**********************************************************************/
@ -1951,6 +2021,8 @@ ftdm_status_t handle_grs_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ
ftdm_channel_t *ftdmchan = NULL;
sngss7_span_data_t *sngss7_span = NULL;
int range = 0;
ftdm_running_return(FTDM_FAIL);
/* confirm that the circuit is voice channel */
if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) {
@ -2008,6 +2080,8 @@ ftdm_status_t handle_grs_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circ
ftdm_channel_t *ftdmchan = NULL;
sngss7_span_data_t *sngss7_span = NULL;
int range = 0;
ftdm_running_return(FTDM_FAIL);
/* confirm that the circuit is voice channel */
if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) {
@ -2072,6 +2146,8 @@ ftdm_status_t handle_local_blk(uint32_t suInstId, uint32_t spInstId, uint32_t ci
sngss7_chan_data_t *sngss7_info = NULL;
ftdm_channel_t *ftdmchan = NULL;
ftdm_running_return(FTDM_FAIL);
/* confirm that the circuit is voice channel */
if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) {
@ -2122,6 +2198,8 @@ ftdm_status_t handle_local_ubl(uint32_t suInstId, uint32_t spInstId, uint32_t ci
sngss7_chan_data_t *sngss7_info = NULL;
ftdm_channel_t *ftdmchan = NULL;
ftdm_running_return(FTDM_FAIL);
/* confirm that the circuit is voice channel */
if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) {
@ -2177,6 +2255,7 @@ ftdm_status_t handle_ucic(uint32_t suInstId, uint32_t spInstId, uint32_t circuit
sngss7_span_data_t *sngss7_span = NULL;
ftdm_channel_t *ftdmchan = NULL;
ftdm_running_return(FTDM_FAIL);
/* confirm that the circuit is voice channel */
if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) {
@ -2215,6 +2294,8 @@ ftdm_status_t handle_ucic(uint32_t suInstId, uint32_t spInstId, uint32_t circuit
cinfo->ucic.range = cinfo->tx_grs.range;
ftdm_set_flag(sngss7_span, SNGSS7_UCIC_PENDING);
SS7_WARN("Set span SNGSS7_UCIC_PENDING for ISUP circuit = %d!\n", circuit);
ftdm_channel_unlock(fchan);
goto done;
@ -2227,6 +2308,7 @@ ftdm_status_t handle_ucic(uint32_t suInstId, uint32_t spInstId, uint32_t circuit
ftdm_mutex_lock(ftdmchan->mutex);
/* throw the ckt block flag */
SS7_DEBUG("Set FLAG_CKT_UCIC_BLOCK for ISUP circuit = %d!\n", circuit);
sngss7_set_ckt_blk_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK);
/* set the channel to suspended state */
@ -2258,6 +2340,8 @@ ftdm_status_t handle_cgb_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ
int bit = 0;
int x;
ftdm_running_return(FTDM_FAIL);
memset(&status[0], '\0', sizeof(status));
/* confirm that the circuit is voice channel */
@ -2404,6 +2488,8 @@ ftdm_status_t handle_cgu_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ
int bit = 0;
int x;
ftdm_sigmsg_t sigev;
ftdm_running_return(FTDM_FAIL);
memset(&sigev, 0, sizeof (sigev));
memset(&status[0], '\0', sizeof(status));
@ -2508,7 +2594,9 @@ ftdm_status_t handle_cgu_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ
sigev.channel = ftdmchan;
/* bring the sig status down */
sngss7_set_sig_status(sngss7_info, FTDM_SIG_STATE_UP);
if (sngss7_channel_status_clear(sngss7_info)) {
sngss7_set_sig_status(sngss7_info, FTDM_SIG_STATE_UP);
}
/* unlock the channel again before we exit */
ftdm_mutex_unlock(ftdmchan->mutex);
@ -2541,6 +2629,8 @@ ftdm_status_t handle_olm_msg(uint32_t suInstId, uint32_t spInstId, uint32_t circ
sngss7_chan_data_t *sngss7_info = NULL;
ftdm_channel_t *ftdmchan = NULL;
ftdm_running_return(FTDM_FAIL);
/* confirm that the circuit is voice channel */
if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) {

View File

@ -791,7 +791,7 @@ void handle_sng_relay_alarm(Pst *pst, RyMngmt *sta)
break;
/**************************************************************************/
case (LRY_USTA_UP): /* channel up */
ftdm_log(FTDM_LOG_ERROR,"[RELAY] Channel UP: tx procId %d: channel %d\n",
ftdm_log(FTDM_LOG_INFO,"[RELAY] Channel UP: tx procId %d: channel %d\n",
sta->t.usta.s.ryUpUsta.sendPid,
sta->t.usta.s.ryUpUsta.id);
@ -810,6 +810,11 @@ void handle_sng_relay_alarm(Pst *pst, RyMngmt *sta)
break;
/**************************************************************************/
case (LRY_USTA_TCP_CONN_FAILED):
ftdm_log(FTDM_LOG_ERROR,"[RELAY] TCP connection failed \n" );
break;
/**************************************************************************/
default:
ftdm_log(FTDM_LOG_ERROR,"Unknown Relay Alram\n");
break;

View File

@ -51,12 +51,13 @@
/* DEFINES ********************************************************************/
#define MAX_NAME_LEN 25
#define MAX_PATH 4096
#define MAX_CIC_LENGTH 5
#define MAX_CIC_MAP_LENGTH 1000
#define SNGSS7_EVENT_QUEUE_SIZE 100
#define SNGSS7_PEER_CHANS_QUEUE_SIZE 100
#define SNGSS7_CHAN_EVENT_QUEUE_SIZE 100
#define MAX_SIZEOF_SUBADDR_IE 24 /* as per Q931 4.5.9 */
@ -64,6 +65,14 @@
(switchtype == LSI_SW_ANS92) || \
(switchtype == LSI_SW_ANS95)
#define sngss7_flush_queue(queue) \
do { \
void *__queue_data = NULL; \
while ((__queue_data = ftdm_queue_dequeue(queue))) { \
ftdm_safe_free(__queue_data); \
} \
} while (0)
typedef struct ftdm2trillium {
uint8_t ftdm_val;
uint8_t trillium_val;
@ -82,8 +91,12 @@ typedef enum {
SNGSS7_STA_IND_EVENT,
SNGSS7_SUSP_IND_EVENT,
SNGSS7_RESM_IND_EVENT,
SNGSS7_SSP_STA_CFM_EVENT
SNGSS7_SSP_STA_CFM_EVENT,
SNGSS7_INVALID_EVENT,
} sng_event_type_t;
#define SNG_EVENT_TYPE_STRINGS "CON_IND", "CON_CFM", "CON_STA", "REL_IND", "REL_CFM", "DAT_IND", "FAC_IND", \
"FAC_CFM", "UMSG_IND", "STA_IND", "SUSP_IND", "RESM_IND", "SSP_STA_CFM", "INVALID"
FTDM_STR2ENUM_P(ftdm_str2sngss7_event, ftdm_sngss7_event2str, sng_event_type_t)
typedef enum {
SNG_BIT_A = (1 << 0),
@ -117,6 +130,12 @@ typedef enum {
SNG_CALLING = 2
} sng_addr_type_t;
typedef enum {
SNG_GEN_CFG_STATUS_INIT = 0,
SNG_GEN_CFG_STATUS_PENDING = 1,
SNG_GEN_CFG_STATUS_DONE = 2
} nsg_gen_cfg_type_t;
typedef struct sng_mtp2_error_type {
int init;
char sng_type[MAX_NAME_LEN];
@ -328,6 +347,7 @@ typedef struct sng_isup_ckt {
uint32_t clg_nadi;
uint32_t cld_nadi;
uint8_t rdnis_nadi;
uint32_t loc_nadi;
/* Generic Number defaults */
uint8_t gn_nmbqual; /* Number Qualifier */
@ -339,8 +359,11 @@ typedef struct sng_isup_ckt {
/* END - Generic Number defaults */
uint32_t min_digits;
uint8_t itx_auto_reply;
uint32_t transparent_iam_max_size;
uint8_t transparent_iam;
uint8_t cpg_on_progress_media;
uint8_t cpg_on_progress;
uint8_t itx_auto_reply;
void *obj;
uint16_t t3;
uint32_t t10;
@ -407,8 +430,8 @@ typedef struct sng_relay {
typedef struct sng_ss7_cfg {
uint32_t spc;
uint32_t procId;
char license[MAX_PATH];
char signature[MAX_PATH];
char license[MAX_SNGSS7_PATH];
char signature[MAX_SNGSS7_PATH];
uint32_t transparent_iam_max_size;
uint32_t flags;
sng_relay_t relay[MAX_RELAY_CHANNELS+1];
@ -476,6 +499,8 @@ typedef struct sngss7_chan_data {
sngss7_group_data_t rx_gra;
sngss7_group_data_t tx_grs;
sngss7_group_data_t ucic;
ftdm_queue_t *event_queue;
struct sngss7_chan_data *peer_data;
} sngss7_chan_data_t;
#define SNGSS7_RX_GRS_PENDING (1 << 0)
@ -489,6 +514,7 @@ typedef struct sngss7_span_data {
sngss7_group_data_t rx_cgu;
sngss7_group_data_t tx_cgu;
ftdm_queue_t *event_queue;
ftdm_queue_t *peer_chans;
} sngss7_span_data_t;
typedef struct sngss7_event_data
@ -533,6 +559,9 @@ typedef enum {
FLAG_INFID_RESUME = (1 << 14),
FLAG_INFID_PAUSED = (1 << 15),
FLAG_SENT_ACM = (1 << 16),
FLAG_SENT_CPG = (1 << 17),
FLAG_SUS_RECVD = (1 << 18),
FLAG_T6_CANCELED = (1 << 19),
FLAG_RELAY_DOWN = (1 << 30),
FLAG_CKT_RECONFIG = (1 << 31)
} sng_ckt_flag_t;
@ -541,14 +570,14 @@ typedef enum {
"RX_RSC", \
"TX_RSC", \
"TX_RSC_REQ_SENT", \
"TX_RSC_RSP_RECIEVED", \
"TX_RSC_RSP_RECEIVED", \
"RX_GRS", \
"RX_GRS_DONE", \
"RX_GRS_CMPLT", \
"GRS_BASE", \
"TX_GRS", \
"TX_GRS_REQ_SENT", \
"TX_GRS_RSP_RECIEVED", \
"TX_GRS_RSP_RECEIVED", \
"REMOTE_REL", \
"LOCAL_REL", \
"GLARE", \
@ -588,7 +617,7 @@ typedef enum {
FLAG_GRP_HW_UNBLK_TX = (1 << 24),
FLAG_GRP_HW_UNBLK_TX_DN = (1 << 25),
FLAG_GRP_MN_UNBLK_TX = (1 << 26),
FLAG_GRP_MN_UNBLK_TX_DN = (1 << 27)
FLAG_GRP_MN_UNBLK_TX_DN = (1 << 27),
} sng_ckt_block_flag_t;
#define BLK_FLAGS_STRING \
@ -731,7 +760,9 @@ int ftmod_ss7_enable_grp_mtp3Link(uint32_t procId);
int ftmod_ss7_disable_grp_mtp2Link(uint32_t procId);
int ftmod_ss7_block_isup_ckt(uint32_t cktId);
#define ftmod_ss7_block_isup_ckt(x) __ftmod_ss7_block_isup_ckt(x,FTDM_TRUE)
#define ftmod_ss7_block_isup_ckt_nowait(x) __ftmod_ss7_block_isup_ckt(x,FTDM_FALSE)
int __ftmod_ss7_block_isup_ckt(uint32_t cktId, ftdm_bool_t wait);
int ftmod_ss7_unblock_isup_ckt(uint32_t cktId);
@ -835,6 +866,11 @@ ftdm_status_t copy_cdPtyNum_from_sngss7(ftdm_channel_t *ftdmchan, SiCdPtyNum *cd
ftdm_status_t copy_cdPtyNum_to_sngss7(ftdm_channel_t *ftdmchan, SiCdPtyNum *cdPtyNum);
ftdm_status_t copy_redirgNum_to_sngss7(ftdm_channel_t *ftdmchan, SiRedirNum *redirgNum);
ftdm_status_t copy_redirgNum_from_sngss7(ftdm_channel_t *ftdmchan, SiRedirNum *redirgNum);
ftdm_status_t copy_redirgInfo_from_sngss7(ftdm_channel_t *ftdmchan, SiRedirInfo *redirInfo);
ftdm_status_t copy_redirgInfo_to_sngss7(ftdm_channel_t *ftdmchan, SiRedirInfo *redirInfo);
ftdm_status_t copy_locPtyNum_to_sngss7(ftdm_channel_t *ftdmchan, SiCgPtyNum *locPtyNum);
ftdm_status_t copy_locPtyNum_from_sngss7(ftdm_channel_t *ftdmchan, SiCgPtyNum *locPtyNum);
ftdm_status_t copy_genNmb_to_sngss7(ftdm_channel_t *ftdmchan, SiGenNum *genNmb);
ftdm_status_t copy_genNmb_from_sngss7(ftdm_channel_t *ftdmchan, SiGenNum *genNmb);
ftdm_status_t copy_cgPtyCat_to_sngss7(ftdm_channel_t *ftdmchan, SiCgPtyCat *cgPtyCat);
@ -912,7 +948,7 @@ if (ftdmchan->state == new_state) { \
#define SS7_ERROR_CHAN(fchan, msg, args...) ftdm_log_chan(fchan, FTDM_LOG_ERROR, msg , ##args)
#define SS7_CTRIT_CHAN(fchan, msg, args...) ftdm_log_chan(fchan, FTDM_LOG_CRIT, msg , ##args)
#ifdef KONRAD_DEVEL
#ifdef SS7_CODE_DEVEL
#define SS7_DEVEL_DEBUG(a,...) ftdm_log(FTDM_LOG_DEBUG,a,##__VA_ARGS__ );
#else
#define SS7_DEVEL_DEBUG(a,...)
@ -1039,6 +1075,40 @@ if (ftdmchan->state == new_state) { \
#define sngss7_clear_options(obj, option) ((obj)->options &= ~(option))
#define sngss7_set_options(obj, option) ((obj)->options |= (option))
#define sngss7_tx_block_status_clear(obj) (!sngss7_test_ckt_blk_flag(obj, (FLAG_CKT_MN_BLOCK_TX | \
FLAG_CKT_MN_BLOCK_TX_DN | \
FLAG_GRP_MN_BLOCK_TX | \
FLAG_GRP_MN_BLOCK_TX_DN | \
FLAG_GRP_HW_BLOCK_TX | \
FLAG_GRP_HW_BLOCK_TX_DN | \
FLAG_GRP_HW_UNBLK_TX | \
FLAG_CKT_MN_UNBLK_TX )))
#define sngss7_block_status_clear(obj) (obj->blk_flags == 0)
#define sngss7_reset_status_clear(obj) (!sngss7_test_ckt_flag(obj, (FLAG_RESET_TX | \
FLAG_RESET_RX | \
FLAG_GRP_RESET_TX | \
FLAG_GRP_RESET_RX )))
#define sngss7_tx_reset_sent(obj) ((sngss7_test_ckt_flag(obj, (FLAG_RESET_TX)) && \
sngss7_test_ckt_flag(obj, (FLAG_RESET_SENT))) || \
(sngss7_test_ckt_flag(obj, (FLAG_GRP_RESET_TX)) && \
sngss7_test_ckt_flag(obj, (FLAG_GRP_RESET_SENT))))
#define sngss7_tx_reset_status_pending(obj) (sngss7_test_ckt_flag(obj, (FLAG_RESET_TX)) || sngss7_test_ckt_flag(obj, (FLAG_GRP_RESET_TX)))
#define sngss7_channel_status_clear(obj) ((sngss7_block_status_clear(obj)) && \
(sngss7_reset_status_clear(obj)) && \
(!sngss7_test_ckt_flag((obj),FLAG_INFID_PAUSED)))
#define sngss7_tx_reset_restart(obj) do { clear_tx_grs_flags((obj)); \
clear_tx_grs_data((obj)); \
clear_tx_rsc_flags((obj)); \
sngss7_set_ckt_flag((obj), (FLAG_RESET_TX)); \
} while (0);
#ifdef SMG_RELAY_DBG
#define SS7_RELAY_DBG(a,...) printf(a"\n", ##__VA_ARGS__)

View File

@ -44,6 +44,7 @@
/* FUNCTIONS ******************************************************************/
void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan)
{
const char *var = NULL;
SiConEvnt iam;
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;;
@ -55,9 +56,104 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan)
memset (&iam, 0x0, sizeof (iam));
if (sngss7_info->circuit->transparent_iam &&
var = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "sigbridge_peer");
if (!ftdm_strlen_zero(var)) {
ftdm_span_t *peer_span = NULL;
ftdm_channel_t *peer_chan = NULL;
sngss7_chan_data_t *peer_info = NULL;
ftdm_get_channel_from_string(var, &peer_span, &peer_chan);
if (!peer_chan) {
SS7_ERROR_CHAN(ftdmchan, "Failed to find sigbridge peer from string '%s'\n", var);
} else {
if (peer_span->signal_type != FTDM_SIGTYPE_SS7) {
SS7_ERROR_CHAN(ftdmchan, "Peer channel '%s' has different signaling type %d'\n",
var, peer_span->signal_type);
} else {
peer_info = peer_chan->call_data;
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Starting native bridge with peer CIC %d\n",
sngss7_info->circuit->cic, peer_info->circuit->cic);
/* make each one of us aware of the native bridge */
peer_info->peer_data = sngss7_info;
sngss7_info->peer_data = peer_info;
/* flush our own queue */
sngss7_flush_queue(sngss7_info->event_queue);
/* go up until release comes, note that state processing is done different and much simpler when there is a peer */
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_UP);
ftdm_channel_advance_states(ftdmchan);
}
}
}
if (sngss7_info->peer_data) {
sngss7_span_data_t *span_data = ftdmchan->span->signal_data;
sngss7_event_data_t *event_clone = ftdm_queue_dequeue(sngss7_info->peer_data->event_queue);
/* Retrieve IAM from our peer */
if (!event_clone) {
SS7_ERROR_CHAN(ftdmchan, "No event clone in peer queue!%s\n", "");
} else if (event_clone->event_id != SNGSS7_CON_IND_EVENT) {
/* first message in the queue should ALWAYS be an IAM */
SS7_ERROR_CHAN(ftdmchan, "Invalid initial peer message type '%d'\n", event_clone->event_id);
} else {
ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx IAM (Bridged, dialing %s)\n", sngss7_info->circuit->cic, caller_data->dnis.digits);
/* copy original incoming IAM */
memcpy(&iam, &event_clone->event.siConEvnt, sizeof(iam));
/* Change DNIS to whatever was specified, do not change NADI or anything else! */
copy_tknStr_to_sngss7(caller_data->dnis.digits, &iam.cdPtyNum.addrSig, &iam.cdPtyNum.oddEven);
/* SPIROU certification hack
If the IAM already contain RDINF, just increment the count and set the RDNIS digits
otherwise, honor RDNIS and RDINF stuff coming from the user */
if (iam.redirInfo.eh.pres == PRSNT_NODEF) {
const char *val = NULL;
if (iam.redirInfo.redirCnt.pres) {
iam.redirInfo.redirCnt.val++;
SS7_DEBUG_CHAN(ftdmchan,"[CIC:%d]Tx IAM (Bridged), redirect count incremented = %d\n", sngss7_info->circuit->cic, iam.redirInfo.redirCnt.val);
}
val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_rdnis_digits");
if (!ftdm_strlen_zero(val)) {
SS7_DEBUG_CHAN(ftdmchan,"[CIC:%d]Tx IAM (Bridged), found user supplied RDNIS digits = %s\n", sngss7_info->circuit->cic, val);
copy_tknStr_to_sngss7((char*)val, &iam.redirgNum.addrSig, &iam.redirgNum.oddEven);
} else {
SS7_DEBUG_CHAN(ftdmchan,"[CIC:%d]Tx IAM (Bridged), not found user supplied RDNIS digits\n", sngss7_info->circuit->cic);
}
} else {
SS7_DEBUG_CHAN(ftdmchan,"[CIC:%d]Tx IAM (Bridged), redirect info not present, attempting to copy user supplied values\n", sngss7_info->circuit->cic);
/* Redirecting Number */
copy_redirgNum_to_sngss7(ftdmchan, &iam.redirgNum);
/* Redirecting Information */
copy_redirgInfo_to_sngss7(ftdmchan, &iam.redirInfo);
}
}
/* since this is the first time we dequeue an event from the peer, make sure our main thread process any other events,
this will trigger the interrupt in our span peer_chans queue which will wake up our main thread if it is sleeping */
ftdm_queue_enqueue(span_data->peer_chans, sngss7_info->peer_data->ftdmchan);
} else if (sngss7_info->circuit->transparent_iam &&
sngss7_retrieve_iam(ftdmchan, &iam) == FTDM_SUCCESS) {
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx IAM (Transparent)\n", sngss7_info->circuit->cic);
/* Called Number information */
copy_cdPtyNum_to_sngss7(ftdmchan, &iam.cdPtyNum);
/* Redirecting Number */
copy_redirgNum_to_sngss7(ftdmchan, &iam.redirgNum);
/* Redirecting Information */
copy_redirgInfo_to_sngss7(ftdmchan, &iam.redirInfo);
/* Location Number information */
copy_locPtyNum_to_sngss7(ftdmchan, &iam.cgPtyNum1);
/* Forward Call Indicators */
copy_fwdCallInd_to_sngss7(ftdmchan, &iam.fwdCallInd);
} else {
/* Nature of Connection Indicators */
copy_natConInd_to_sngss7(ftdmchan, &iam.natConInd);
@ -79,6 +175,9 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan)
/* Calling Number information */
copy_cgPtyNum_to_sngss7(ftdmchan, &iam.cgPtyNum);
/* Location Number information */
copy_locPtyNum_to_sngss7(ftdmchan, &iam.cgPtyNum1);
/* Generic Number information */
copy_genNmb_to_sngss7(ftdmchan, &iam.genNmb);
@ -88,15 +187,21 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan)
/* Redirecting Number */
copy_redirgNum_to_sngss7(ftdmchan, &iam.redirgNum);
/* Redirecting Information */
copy_redirgInfo_to_sngss7(ftdmchan, &iam.redirInfo);
/* Access Transport */
copy_accTrnspt_to_sngss7(ftdmchan, &iam.accTrnspt);
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx IAM clg = \"%s\" (NADI=%d), cld = \"%s\" (NADI=%d)\n",
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx IAM clg = \"%s\" (NADI=%d), cld = \"%s\" (NADI=%d), loc = %s (NADI=%d)\n",
sngss7_info->circuit->cic,
ftdmchan->caller_data.cid_num.digits,
iam.cgPtyNum.natAddrInd.val,
ftdmchan->caller_data.dnis.digits,
iam.cdPtyNum.natAddrInd.val);
iam.cdPtyNum.natAddrInd.val,
ftdmchan->caller_data.loc.digits,
iam.cgPtyNum1.natAddrInd.val);
}
sng_cc_con_request (sngss7_info->spId,
@ -241,6 +346,7 @@ void ft_to_sngss7_anm (ftdm_channel_t * ftdmchan)
/******************************************************************************/
void ft_to_sngss7_rel (ftdm_channel_t * ftdmchan)
{
const char *loc_ind = NULL;
SS7_FUNC_TRACE_ENTER (__FUNCTION__);
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
@ -250,7 +356,15 @@ void ft_to_sngss7_rel (ftdm_channel_t * ftdmchan)
rel.causeDgn.eh.pres = PRSNT_NODEF;
rel.causeDgn.location.pres = PRSNT_NODEF;
rel.causeDgn.location.val = 0x01;
loc_ind = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_rel_loc");
if (!ftdm_strlen_zero(loc_ind)) {
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Found user supplied location indicator in REL, value \"%s\"\n", loc_ind);
rel.causeDgn.location.val = atoi(loc_ind);
} else {
rel.causeDgn.location.val = 0x01;
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "No user supplied location indicator in REL, using 0x01\"%s\"\n", "");
}
rel.causeDgn.cdeStand.pres = PRSNT_NODEF;
rel.causeDgn.cdeStand.val = 0x00;
rel.causeDgn.recommend.pres = NOTPRSNT;
@ -260,10 +374,10 @@ void ft_to_sngss7_rel (ftdm_channel_t * ftdmchan)
/* send the REL request to LibSngSS7 */
sng_cc_rel_request (1,
sngss7_info->suInstId,
sngss7_info->spInstId,
sngss7_info->circuit->id,
&rel);
sngss7_info->suInstId,
sngss7_info->spInstId,
sngss7_info->circuit->id,
&rel);
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx REL cause=%d \n",
sngss7_info->circuit->cic,
@ -518,8 +632,6 @@ void ft_to_sngss7_grs (ftdm_channel_t *fchan)
cinfo->circuit->cic,
(cinfo->circuit->cic + cinfo->tx_grs.range));
memset(&cinfo->tx_grs, 0, sizeof(cinfo->tx_grs));
sngss7_set_ckt_flag(cinfo, FLAG_GRP_RESET_SENT);
SS7_FUNC_TRACE_EXIT (__FUNCTION__);

View File

@ -42,8 +42,6 @@
/******************************************************************************/
/* PROTOTYPES *****************************************************************/
ftdm_status_t handle_relay_connect(RyMngmt *sta);
ftdm_status_t handle_relay_disconnect(RyMngmt *sta);
/*static ftdm_status_t enable_all_ckts_for_relay(void);*/
static ftdm_status_t reconfig_all_ckts_for_relay(void);
@ -66,11 +64,9 @@ ftdm_status_t handle_relay_connect(RyMngmt *sta)
SS7_INFO("Relay Channel %d connection UP\n", sng_relay->id);
if (sng_relay->type == LRY_CT_TCP_CLIENT) {
if (!sngss7_test_flag(sng_relay, SNGSS7_RELAY_INIT)) {
if (reconfig_all_ckts_for_relay()) {
SS7_ERROR("Failed to reconfigure ISUP Ckts!\n");
/* we're done....this is very bad! */
}
if (reconfig_all_ckts_for_relay()) {
SS7_ERROR("Failed to reconfigure ISUP Ckts!\n");
/* we're done....this is very bad! */
}
return FTDM_SUCCESS;
} else if (sng_relay->type == LRY_CT_TCP_SERVER) {
@ -84,23 +80,24 @@ ftdm_status_t handle_relay_connect(RyMngmt *sta)
/******************************************************************************/
ftdm_status_t handle_relay_disconnect_on_error(RyMngmt *sta)
{
SS7_DEBUG("SS7 relay disconnect on error\n");
/* check which procId is in error, if it is 1, disable the ckts */
if (sta->t.usta.s.ryErrUsta.errPid == 1 ) {
/* we've lost the server, bring down the mtp2 links */
disble_all_mtp2_sigs_for_relay();
/* we've lost the server, bring the sig status down on all ckts */
disable_all_ckts_for_relay();
/* we've lost the server, bring down the mtp2 links */
disble_all_mtp2_sigs_for_relay();
}
/* check if the channel is a server, means we just lost a MGW */
if (g_ftdm_sngss7_data.cfg.relay[sta->t.usta.s.ryErrUsta.errPid].type == LRY_CT_TCP_SERVER) {
/* we've lost the client, bring down all mtp3 links for this procId */
disable_all_sigs_for_relay(sta->t.usta.s.ryErrUsta.errPid);
/* we've lost the client, bring down all the ckts for this procId */
block_all_ckts_for_relay(sta->t.usta.s.ryErrUsta.errPid);
/* we've lost the client, bring down all mtp3 links for this procId */
disable_all_sigs_for_relay(sta->t.usta.s.ryErrUsta.errPid);
}
return FTDM_SUCCESS;
@ -110,6 +107,8 @@ ftdm_status_t handle_relay_disconnect_on_error(RyMngmt *sta)
ftdm_status_t handle_relay_disconnect_on_down(RyMngmt *sta)
{
SS7_DEBUG("SS7 relay disconnect on down\n");
/* check if the channel is a server, means we just lost a MGW */
if (g_ftdm_sngss7_data.cfg.relay[sta->t.usta.s.ryUpUsta.id].type == LRY_CT_TCP_SERVER) {
block_all_ckts_for_relay(sta->t.usta.s.ryUpUsta.id);
@ -248,7 +247,7 @@ ftdm_status_t block_all_ckts_for_relay(uint32_t procId)
if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == SNG_CKT_VOICE) {
/* send a block request via stack manager */
ret = ftmod_ss7_block_isup_ckt(g_ftdm_sngss7_data.cfg.isupCkt[x].id);
ret = ftmod_ss7_block_isup_ckt_nowait(g_ftdm_sngss7_data.cfg.isupCkt[x].id);
if (ret) {
SS7_INFO("Successfully BLOcked CIC:%d(ckt:%d) due to Relay failure\n",
g_ftdm_sngss7_data.cfg.isupCkt[x].cic,
@ -331,6 +330,7 @@ static ftdm_status_t unblock_all_ckts_for_relay(uint32_t procId)
}
#endif
/******************************************************************************/
/* For Emacs:
* Local Variables:

View File

@ -193,7 +193,16 @@ ftdm_status_t copy_cgPtyNum_to_sngss7(ftdm_channel_t *ftdmchan, SiCgPtyNum *cgPt
ftdm_status_t copy_cdPtyNum_from_sngss7(ftdm_channel_t *ftdmchan, SiCdPtyNum *cdPtyNum)
{
/* TODO: Implement me */
char var[FTDM_DIGITS_LIMIT];
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
if (cdPtyNum->eh.pres == PRSNT_NODEF &&
cdPtyNum->natAddrInd.pres == PRSNT_NODEF) {
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Called Party Number NADI %d\n", cdPtyNum->natAddrInd.val);
sprintf(var, "%d", cdPtyNum->natAddrInd.val);
sngss7_add_var(sngss7_info, "ss7_cld_nadi", var);
}
return FTDM_SUCCESS;
}
@ -225,6 +234,67 @@ ftdm_status_t copy_cdPtyNum_to_sngss7(ftdm_channel_t *ftdmchan, SiCdPtyNum *cdPt
return copy_tknStr_to_sngss7(caller_data->dnis.digits, &cdPtyNum->addrSig, &cdPtyNum->oddEven);
}
ftdm_status_t copy_locPtyNum_from_sngss7(ftdm_channel_t *ftdmchan, SiCgPtyNum *locPtyNum)
{
return FTDM_SUCCESS;
}
ftdm_status_t copy_locPtyNum_to_sngss7(ftdm_channel_t *ftdmchan, SiCgPtyNum *locPtyNum)
{
const char *val = NULL;
const char *loc_nadi = NULL;
int pres_val = PRSNT_NODEF;
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
if (!strcasecmp(caller_data->loc.digits, "NULL")) {
pres_val = NOTPRSNT;
}
locPtyNum->eh.pres = pres_val;
locPtyNum->natAddrInd.pres = pres_val;
locPtyNum->natAddrInd.val = g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].loc_nadi;
locPtyNum->scrnInd.pres = pres_val;
val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_loc_screen_ind");
if (!ftdm_strlen_zero(val)) {
locPtyNum->scrnInd.val = atoi(val);
} else {
locPtyNum->scrnInd.val = caller_data->screen;
}
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Location Reference Code Screening Ind %d\n", locPtyNum->scrnInd.val);
locPtyNum->presRest.pres = pres_val;
val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_pres_ind");
if (!ftdm_strlen_zero(val)) {
locPtyNum->presRest.val = atoi(val);
} else {
locPtyNum->presRest.val = caller_data->pres;
}
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Calling Party Number Presentation Ind %d\n", locPtyNum->presRest.val);
locPtyNum->numPlan.pres = pres_val;
locPtyNum->numPlan.val = 0x01;
locPtyNum->niInd.pres = pres_val;
locPtyNum->niInd.val = 0x00;
/* check if the user would like a custom NADI value for the Location Reference */
loc_nadi = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_loc_nadi");
if (!ftdm_strlen_zero(loc_nadi)) {
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Found user supplied Location Reference NADI value \"%s\"\n", loc_nadi);
locPtyNum->natAddrInd.val = atoi(loc_nadi);
} else {
locPtyNum->natAddrInd.val = g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].loc_nadi;
locPtyNum->natAddrInd.val = 0x03;
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "No user supplied NADI value found for LOC, using \"%d\"\n", locPtyNum->natAddrInd.val);
}
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Location Reference Presentation Ind %d\n", locPtyNum->presRest.val);
return copy_tknStr_to_sngss7(caller_data->loc.digits, &locPtyNum->addrSig, &locPtyNum->oddEven);
}
ftdm_status_t copy_genNmb_to_sngss7(ftdm_channel_t *ftdmchan, SiGenNum *genNmb)
{
const char *val = NULL;
@ -319,7 +389,7 @@ ftdm_status_t copy_genNmb_from_sngss7(ftdm_channel_t *ftdmchan, SiGenNum *genNmb
if (genNmb->nmbQual.pres == PRSNT_NODEF) {
snprintf(val, sizeof(val), "%d", genNmb->nmbQual.val);
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Generic Number \"number qualifier\" \n", val);
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Generic Number \"number qualifier\" \"%s\" \n", val);
sngss7_add_var(sngss7_info, "ss7_gn_numqual", val);
}
@ -374,6 +444,13 @@ ftdm_status_t copy_redirgNum_to_sngss7(ftdm_channel_t *ftdmchan, SiRedirNum *red
return FTDM_FAIL;
}
} else {
val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_rdnis_pres_ind");
if (!ftdm_strlen_zero(val)) {
redirgNum->presRest.val = atoi(val);
}
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Redirecting Number Address Presentation Restricted Ind:%d\n", redirgNum->presRest.val);
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "No user supplied Redirection Number\n");
return FTDM_SUCCESS;
}
@ -474,6 +551,94 @@ ftdm_status_t copy_redirgNum_from_sngss7(ftdm_channel_t *ftdmchan, SiRedirNum *r
return FTDM_SUCCESS;
}
ftdm_status_t copy_redirgInfo_from_sngss7(ftdm_channel_t *ftdmchan, SiRedirInfo *redirInfo)
{
char val[20];
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
if (redirInfo->eh.pres != PRSNT_NODEF ) {
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "No Redirecting Information available\n");
return FTDM_SUCCESS;
}
if (redirInfo->redirInd.pres == PRSNT_NODEF) {
snprintf(val, sizeof(val), "%d", redirInfo->redirInd.val);
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Redirection Information - redirection indicator:%s\n", val);
sngss7_add_var(sngss7_info, "ss7_rdinfo_indicator", val);
}
if (redirInfo->origRedirReas.pres == PRSNT_NODEF) {
snprintf(val, sizeof(val), "%d", redirInfo->origRedirReas.val);
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Redirection Information - original redirection reason:%s\n", val);
sngss7_add_var(sngss7_info, "ss7_rdinfo_orig", val);
}
if (redirInfo->redirCnt.pres == PRSNT_NODEF) {
snprintf(val, sizeof(val), "%d", redirInfo->redirCnt.val);
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Redirection Information - redirection count:%s\n", val);
sngss7_add_var(sngss7_info, "ss7_rdinfo_count", val);
}
if (redirInfo->redirReas.pres == PRSNT_NODEF) {
snprintf(val, sizeof(val), "%d", redirInfo->redirReas.val);
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Redirection Information - redirection reason:%s\n", val);
sngss7_add_var(sngss7_info, "ss7_rdinfo_reason", val);
}
return FTDM_SUCCESS;
}
ftdm_status_t copy_redirgInfo_to_sngss7(ftdm_channel_t *ftdmchan, SiRedirInfo *redirInfo)
{
const char* val = NULL;
int bProceed = 0;
val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_rdinfo_indicator");
if (!ftdm_strlen_zero(val)) {
redirInfo->redirInd.val = atoi(val);
redirInfo->redirInd.pres = 1;
bProceed = 1;
} else {
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "No user supplied Redirection Information on Redirection Indicator\n");
}
val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_rdinfo_orig");
if (!ftdm_strlen_zero(val)) {
redirInfo->origRedirReas.val = atoi(val);
redirInfo->origRedirReas.pres = 1;
bProceed = 1;
} else {
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "No user supplied Redirection Information on Original Reasons\n");
}
val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_rdinfo_count");
if (!ftdm_strlen_zero(val)) {
redirInfo->redirCnt.val = atoi(val);
redirInfo->redirCnt.pres= 1;
bProceed = 1;
} else {
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "No user supplied Redirection Information on Redirection Count\n");
}
val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_rdinfo_reason");
if (!ftdm_strlen_zero(val)) {
redirInfo->redirReas.val = atoi(val);
redirInfo->redirReas.pres = 1;
bProceed = 1;
} else {
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "No user supplied Redirection Information on Redirection Reasons\n");
}
if( bProceed == 1 ) {
redirInfo->eh.pres = PRSNT_NODEF;
} else {
redirInfo->eh.pres = NOTPRSNT;
}
return FTDM_SUCCESS;
}
ftdm_status_t copy_cgPtyCat_to_sngss7(ftdm_channel_t *ftdmchan, SiCgPtyCat *cgPtyCat)
{
ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
@ -600,6 +765,8 @@ ftdm_status_t copy_natConInd_to_sngss7(ftdm_channel_t *ftdmchan, SiNatConInd *na
ftdm_status_t copy_fwdCallInd_to_sngss7(ftdm_channel_t *ftdmchan, SiFwdCallInd *fwdCallInd)
{
const char *val = NULL;
int acc_val = ISDNACC_ISDN;
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
fwdCallInd->eh.pres = PRSNT_NODEF;
@ -616,7 +783,13 @@ ftdm_status_t copy_fwdCallInd_to_sngss7(ftdm_channel_t *ftdmchan, SiFwdCallInd *
fwdCallInd->isdnUsrPrtPrfInd.pres = PRSNT_NODEF;
fwdCallInd->isdnUsrPrtPrfInd.val = PREF_PREFAW;
fwdCallInd->isdnAccInd.pres = PRSNT_NODEF;
fwdCallInd->isdnAccInd.val = ISDNACC_ISDN;
val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "iam_fwd_ind_isdn_access_ind");
if (!ftdm_strlen_zero(val)) {
acc_val = (int)atoi(val);
}
fwdCallInd->isdnAccInd.val = acc_val;
fwdCallInd->sccpMethInd.pres = PRSNT_NODEF;
fwdCallInd->sccpMethInd.val = SCCPMTH_NOIND;
@ -866,11 +1039,6 @@ int check_for_state_change(ftdm_channel_t *ftdmchan)
/******************************************************************************/
ftdm_status_t extract_chan_data(uint32_t circuit, sngss7_chan_data_t **sngss7_info, ftdm_channel_t **ftdmchan)
{
if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].obj == NULL) {
SS7_ERROR("sngss7_info is Null for circuit #%d\n", circuit);
return FTDM_FAIL;
}
if (!g_ftdm_sngss7_data.cfg.isupCkt[circuit].obj) {
SS7_ERROR("No ss7 info for circuit #%d\n", circuit);
return FTDM_FAIL;
@ -879,10 +1047,21 @@ ftdm_status_t extract_chan_data(uint32_t circuit, sngss7_chan_data_t **sngss7_in
*sngss7_info = g_ftdm_sngss7_data.cfg.isupCkt[circuit].obj;
if (!(*sngss7_info)->ftdmchan) {
SS7_ERROR("No channel for circuit #%d\n", circuit);
SS7_ERROR("No ftdmchan for circuit #%d\n", circuit);
return FTDM_FAIL;
}
if (!(*sngss7_info)->ftdmchan->span) {
SS7_CRITICAL("ftdmchan->span = NULL for circuit #%d\n",circuit);
return FTDM_FAIL;
}
if (!(*sngss7_info)->ftdmchan->span->signal_data) {
SS7_CRITICAL("ftdmchan->span->signal_data = NULL for circuit #%d\n",circuit);
return FTDM_FAIL;
}
*ftdmchan = (*sngss7_info)->ftdmchan;
return FTDM_SUCCESS;
}
@ -1366,7 +1545,7 @@ ftdm_status_t process_span_ucic(ftdm_span_t *ftdmspan)
/* lock the channel */
ftdm_channel_lock(ftdmchan);
SS7_INFO_CHAN(ftdmchan, "[CIC:%d]Rx UCIC\n", sngss7_info->circuit->cic);
SS7_INFO_CHAN(ftdmchan, "[CIC:%d]Rx Span UCIC\n", sngss7_info->circuit->cic);
/* clear up any pending state changes */
while (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
@ -1881,6 +2060,7 @@ ftdm_status_t check_status_of_all_isup_intf(void)
if (ftmod_ss7_isup_intf_sta(sngss7_intf->id, &status)) {
SS7_ERROR("Failed to get status of ISUP intf %d\n", sngss7_intf->id);
sngss7_set_flag(sngss7_intf, SNGSS7_PAUSED);
continue;
}
@ -2035,6 +2215,55 @@ void sngss7_set_sig_status(sngss7_chan_data_t *sngss7_info, ftdm_signaling_statu
return;
}
#if 0
ftdm_status_t check_for_invalid_states(ftdm_channel_t *ftmchan)
{
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
if (!sngss7_info) {
SS7_WARN_CHAN(ftdmchan, "Found ftdmchan with no sig module data!%s\n", " ");
return FTDM_FAIL;
}
if (sngss7_test_flag(sngss7_intf, SNGSS7_PAUSED)) {
return FTDM_SUCCESS;
}
switch (ftdmchan->state) {
case UP:
case DOWN:
return FTDM_SUCCESS;
default:
if ((ftdm_current_time_in_ms() - ftdmchan->last_state_change_time) > 30000) {
SS7_WARN_CHAN(ftdmchan, "Circuite in state=%s too long - resetting!%s\n",
ftdm_channel_state2str(ftdmchan->state));
ftdm_channel_lock(ftdmchan);
if (sngss7_channel_status_clear(sngss7_info)) {
sngss7_tx_reset_restart(sngss7_info);
if (ftdmchan->state == FTDM_CHANNEL_STATE_RESTART) {
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED);
} else {
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
}
} else {
}
ftdm_channel_unlock(ftdmchan);
}
}
return FTDM_SUCCESS;
}
#endif
/******************************************************************************/
ftdm_status_t check_for_reconfig_flag(ftdm_span_t *ftdmspan)
{
@ -2047,6 +2276,7 @@ ftdm_status_t check_for_reconfig_flag(ftdm_span_t *ftdmspan)
uint8_t bits_ef = 0;
int x;
int ret;
ret=0;
for (x = 1; x < (ftdmspan->chan_count + 1); x++) {
/**************************************************************************/
@ -2071,12 +2301,12 @@ ftdm_status_t check_for_reconfig_flag(ftdm_span_t *ftdmspan)
/* check if the interface is paused or resumed */
if (sngss7_test_flag(sngss7_intf, SNGSS7_PAUSED)) {
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "ISUP intf %d is PAUSED\n", sngss7_intf->id);
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Circuit set to PAUSED %s\n"," ");
/* throw the pause flag */
sngss7_clear_ckt_flag(sngss7_info, FLAG_INFID_RESUME);
sngss7_set_ckt_flag(sngss7_info, FLAG_INFID_PAUSED);
} else {
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "ISUP intf %d is RESUMED\n", sngss7_intf->id);
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Circuit set to RESUMED %s\n"," ");
/* throw the resume flag */
sngss7_clear_ckt_flag(sngss7_info, FLAG_INFID_PAUSED);
sngss7_set_ckt_flag(sngss7_info, FLAG_INFID_RESUME);
@ -2084,7 +2314,11 @@ ftdm_status_t check_for_reconfig_flag(ftdm_span_t *ftdmspan)
/* query for the status of the ckt */
if (ftmod_ss7_isup_ckt_sta(sngss7_info->circuit->id, &state)) {
SS7_ERROR("Failed to read isup ckt = %d status\n", sngss7_info->circuit->id);
/* NC: Circuit statistic failed: does not exist. Must re-configure circuit
Reset the circuit CONFIGURED flag so that RESUME will reconfigure
this circuit. */
sngss7_info->circuit->flags &= ~SNGSS7_CONFIGURED;
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR,"Failed to read isup ckt = %d status\n", sngss7_info->circuit->id);
continue;
}
@ -2092,10 +2326,20 @@ ftdm_status_t check_for_reconfig_flag(ftdm_span_t *ftdmspan)
bits_ab = (state & (SNG_BIT_A + SNG_BIT_B)) >> 0;
bits_cd = (state & (SNG_BIT_C + SNG_BIT_D)) >> 2;
bits_ef = (state & (SNG_BIT_E + SNG_BIT_F)) >> 4;
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Circuit state=0x%X ab=0x%X cd=0x%X ef=0x%X\n",state,bits_ab,bits_cd,bits_ef);
if (bits_cd == 0x0) {
/* check if circuit is UCIC or transient */
if (bits_ab == 0x3) {
SS7_INFO("ISUP CKT %d re-configuration pending!\n", x);
sngss7_info->circuit->flags &= ~SNGSS7_CONFIGURED;
SS7_STATE_CHANGE(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED);
/* NC: The code below should be deleted. Its here for hitorical
reason. The RESUME code will reconfigure the channel since
the CONFIGURED flag has been reset */
#if 0
/* bit a and bit b are set, unequipped */
ret = ftmod_ss7_isup_ckt_config(sngss7_info->circuit->id);
if (ret) {
@ -2118,8 +2362,22 @@ ftdm_status_t check_for_reconfig_flag(ftdm_span_t *ftdmspan)
/* unlock the channel */
ftdm_mutex_unlock(ftdmchan->mutex);
#endif
} /* if (bits_ab == 0x3) */
} else { /* if (bits_ab == 0x3) */
/* The stack status is not blocked. However this is possible if
the circuit state was UP. So even though Master sent out the BLO
the status command is not showing it.
As a kudge. We will try to send out an UBL even though the status
indicates that there is no BLO. */
if (!sngss7_test_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_TX)) {
sngss7_set_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_UNBLK_TX);
/* set the channel to suspended state */
SS7_STATE_CHANGE(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED);
}
}
} else {
/* check the maintenance block status in bits A and B */
switch (bits_ab) {
@ -2129,16 +2387,27 @@ ftdm_status_t check_for_reconfig_flag(ftdm_span_t *ftdmspan)
break;
/**************************************************************************/
case (1):
/* locally blocked */
sngss7_set_ckt_blk_flag(sngss7_info, FLAG_CKT_LC_BLOCK_RX);
/* The stack status is Blocked. Check if the block was sent
by user via console. If the block was not sent by user then, it
was sent out by Master due to relay down.
Therefore send out the unblock to clear it */
if (!sngss7_test_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_TX)) {
sngss7_set_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_UNBLK_TX);
/* set the channel to suspended state */
SS7_STATE_CHANGE(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED);
}
/* Only locally blocked, thus remove a remote block */
sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX);
sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX_DN);
/* set the channel to suspended state */
SS7_STATE_CHANGE(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED);
break;
/**************************************************************************/
case (2):
/* remotely blocked */
sngss7_set_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX);
sngss7_set_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX_DN);
/* set the channel to suspended state */
SS7_STATE_CHANGE(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED);
@ -2146,8 +2415,11 @@ ftdm_status_t check_for_reconfig_flag(ftdm_span_t *ftdmspan)
/**************************************************************************/
case (3):
/* both locally and remotely blocked */
sngss7_set_ckt_blk_flag(sngss7_info, FLAG_CKT_LC_BLOCK_RX);
if (!sngss7_test_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_TX)) {
sngss7_set_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_UNBLK_TX);
}
sngss7_set_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX);
sngss7_set_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX_DN);
/* set the channel to suspended state */
SS7_STATE_CHANGE(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED);
@ -2199,7 +2471,7 @@ ftdm_status_t check_for_reconfig_flag(ftdm_span_t *ftdmspan)
/* clear the re-config flag ... no matter what */
sngss7_clear_ckt_flag(sngss7_info, FLAG_CKT_RECONFIG);
} /* if ((sngss7_test_ckt_flag(sngss7_info, FLAG_CKT_RECONFIG)) */
}
} /* for (x = 1; x < (span->chan_count + 1); x++) */
return FTDM_SUCCESS;
@ -2470,8 +2742,9 @@ ftdm_status_t sngss7_save_iam(ftdm_channel_t *ftdmchan, SiConEvnt *siConEvnt)
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "IAM variable length:%d\n", strlen(url_encoded_iam));
if (strlen(url_encoded_iam) > g_ftdm_sngss7_data.cfg.transparent_iam_max_size) {
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "IAM variable length exceeds max size (len:%d max:%d) \n", strlen(url_encoded_iam), g_ftdm_sngss7_data.cfg.transparent_iam_max_size);
if (strlen(url_encoded_iam) > sngss7_info->circuit->transparent_iam_max_size) {
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "IAM variable length exceeds max size (len:%d max:%d) \n",
strlen(url_encoded_iam), sngss7_info->circuit->transparent_iam_max_size);
ret_val = FTDM_FAIL;
goto done;
}

View File

@ -124,9 +124,13 @@ typedef struct sng_ccSpan
uint32_t clg_nadi;
uint32_t cld_nadi;
uint32_t rdnis_nadi;
uint32_t loc_nadi;
uint32_t min_digits;
uint8_t itx_auto_reply;
uint32_t transparent_iam_max_size;
uint8_t transparent_iam;
uint8_t cpg_on_progress_media;
uint8_t cpg_on_progress;
uint8_t itx_auto_reply;
uint32_t t3;
uint32_t t10;
uint32_t t12;
@ -191,6 +195,7 @@ static int ftmod_ss7_next_timeslot(char *ch_map, sng_timeslot_t *timeslot);
/******************************************************************************/
/* FUNCTIONS ******************************************************************/
int ftmod_ss7_parse_xml(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *span)
{
int i = 0;
@ -200,6 +205,7 @@ int ftmod_ss7_parse_xml(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *spa
sng_route_t self_route;
sng_span_t sngSpan;
/* clean out the isup ckt */
memset(&sngSpan, 0x0, sizeof(sngSpan));
@ -452,6 +458,9 @@ static int ftmod_ss7_parse_sng_gen(ftdm_conf_node_t *sng_gen)
int num_parms = sng_gen->n_parameters;
int i = 0;
/* Set the transparent_iam_max_size to default value */
g_ftdm_sngss7_data.cfg.transparent_iam_max_size=800;
/* extract all the information from the parameters */
for (i = 0; i < num_parms; i++) {
/**************************************************************************/
@ -463,9 +472,8 @@ static int ftmod_ss7_parse_sng_gen(ftdm_conf_node_t *sng_gen)
/**********************************************************************/
} else if (!strcasecmp(parm->var, "license")) {
/**********************************************************************/
strcpy(g_ftdm_sngss7_data.cfg.license, parm->val);
strcpy(g_ftdm_sngss7_data.cfg.signature, parm->val);
strcat(g_ftdm_sngss7_data.cfg.signature, ".sig");
ftdm_set_string(g_ftdm_sngss7_data.cfg.license, parm->val);
snprintf(g_ftdm_sngss7_data.cfg.signature, sizeof(g_ftdm_sngss7_data.cfg.signature), "%s.sig", parm->val);
SS7_DEBUG("Found license file = %s\n", g_ftdm_sngss7_data.cfg.license);
SS7_DEBUG("Found signature file = %s\n", g_ftdm_sngss7_data.cfg.signature);
/**********************************************************************/
@ -1845,12 +1853,14 @@ static int ftmod_ss7_parse_cc_span(ftdm_conf_node_t *cc_span)
int flag_clg_nadi = 0;
int flag_cld_nadi = 0;
int flag_rdnis_nadi = 0;
int flag_loc_nadi = 0;
int i;
int ret;
/* initalize the ccSpan structure */
memset(&sng_ccSpan, 0x0, sizeof(sng_ccSpan));
/* confirm that we are looking at an mtp_link */
if (strcasecmp(cc_span->name, "cc_span")) {
SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"cc_span\"!\n",cc_span->name);
@ -1859,6 +1869,14 @@ static int ftmod_ss7_parse_cc_span(ftdm_conf_node_t *cc_span)
SS7_DEBUG("Parsing \"cc_span\"...\n");
}
/* Backward compatible.
* If cpg_on_progress_media is not in the config file
* default the cpg on progress_media to TRUE */
sng_ccSpan.cpg_on_progress_media=FTDM_TRUE;
/* If transparent_iam_max_size is not set in cc spans
* use the global value */
sng_ccSpan.transparent_iam_max_size=g_ftdm_sngss7_data.cfg.transparent_iam_max_size;
for (i = 0; i < num_parms; i++) {
/**************************************************************************/
@ -1904,6 +1922,15 @@ static int ftmod_ss7_parse_cc_span(ftdm_conf_node_t *cc_span)
sng_ccSpan.transparent_iam = ftdm_true(parm->val);
SS7_DEBUG("Found transparent_iam %d\n", sng_ccSpan.transparent_iam);
#endif
} else if (!strcasecmp(parm->var, "transparent_iam_max_size")) {
sng_ccSpan.transparent_iam_max_size = atoi(parm->val);
SS7_DEBUG("Found transparent_iam_max_size %d\n", sng_ccSpan.transparent_iam_max_size);
} else if (!strcasecmp(parm->var, "cpg_on_progress_media")) {
sng_ccSpan.cpg_on_progress_media = ftdm_true(parm->val);
SS7_DEBUG("Found cpg_on_progress_media %d\n", sng_ccSpan.cpg_on_progress_media);
} else if (!strcasecmp(parm->var, "cpg_on_progress")) {
sng_ccSpan.cpg_on_progress = ftdm_true(parm->val);
SS7_DEBUG("Found cpg_on_progress %d\n", sng_ccSpan.cpg_on_progress);
} else if (!strcasecmp(parm->var, "cicbase")) {
/**********************************************************************/
sng_ccSpan.cicbase = atoi(parm->val);
@ -1946,6 +1973,14 @@ static int ftmod_ss7_parse_cc_span(ftdm_conf_node_t *cc_span)
SS7_DEBUG("Invalid parm->value for obci_bita option\n");
}
/**********************************************************************/
} else if (!strcasecmp(parm->var, "loc_nadi")) {
/* add location reference number */
flag_loc_nadi = 1;
sng_ccSpan.loc_nadi = atoi(parm->val);
SS7_DEBUG("Found default LOC_NADI parm->value = %d\n", sng_ccSpan.loc_nadi);
printf( " --- jz: we got loc nadi from XML, val = %d \n" , sng_ccSpan.loc_nadi);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "lpa_on_cot")) {
/**********************************************************************/
if (*parm->val == '1') {
@ -2035,6 +2070,11 @@ static int ftmod_ss7_parse_cc_span(ftdm_conf_node_t *cc_span)
sng_ccSpan.rdnis_nadi = 0x03;
}
if (!flag_loc_nadi) {
/* default the nadi value to national */
sng_ccSpan.loc_nadi = 0x03;
}
/* pull up the SSF and Switchtype from the isup interface */
sng_ccSpan.ssf = g_ftdm_sngss7_data.cfg.isupIntf[sng_ccSpan.isupInf].ssf;
sng_ccSpan.switchType = g_ftdm_sngss7_data.cfg.isupIntf[sng_ccSpan.isupInf].switchType;
@ -2863,7 +2903,7 @@ static int ftmod_ss7_fill_in_ccSpan(sng_ccSpan_t *ccSpan)
(g_ftdm_sngss7_data.cfg.isupCkt[x].chan == count)) {
/* we are processing a circuit that already exists */
SS7_DEBUG("Found an existing circuit %d, ccSpanId=%d, chan%d\n",
SS7_DEVEL_DEBUG("Found an existing circuit %d, ccSpanId=%d, chan%d\n",
x,
ccSpan->id,
count);
@ -2872,7 +2912,7 @@ static int ftmod_ss7_fill_in_ccSpan(sng_ccSpan_t *ccSpan)
flag = 1;
/* not supporting reconfig at this time */
SS7_DEBUG("Not supporting ckt reconfig at this time!\n");
SS7_DEVEL_DEBUG("Not supporting ckt reconfig at this time!\n");
goto move_along;
} else {
/* this is not the droid you are looking for */
@ -2885,6 +2925,9 @@ static int ftmod_ss7_fill_in_ccSpan(sng_ccSpan_t *ccSpan)
/* prepare the global info sturcture */
ss7_info = ftdm_calloc(1, sizeof(sngss7_chan_data_t));
ss7_info->ftdmchan = NULL;
if (ftdm_queue_create(&ss7_info->event_queue, SNGSS7_CHAN_EVENT_QUEUE_SIZE) != FTDM_SUCCESS) {
SS7_CRITICAL("Failed to create ss7 cic event queue\n");
}
ss7_info->circuit = &g_ftdm_sngss7_data.cfg.isupCkt[x];
g_ftdm_sngss7_data.cfg.isupCkt[x].obj = ss7_info;
@ -2919,12 +2962,16 @@ static int ftmod_ss7_fill_in_ccSpan(sng_ccSpan_t *ccSpan)
g_ftdm_sngss7_data.cfg.isupCkt[x].ssf = ccSpan->ssf;
g_ftdm_sngss7_data.cfg.isupCkt[x].cld_nadi = ccSpan->cld_nadi;
g_ftdm_sngss7_data.cfg.isupCkt[x].clg_nadi = ccSpan->clg_nadi;
g_ftdm_sngss7_data.cfg.isupCkt[x].rdnis_nadi = ccSpan->rdnis_nadi;
g_ftdm_sngss7_data.cfg.isupCkt[x].rdnis_nadi = ccSpan->rdnis_nadi;
g_ftdm_sngss7_data.cfg.isupCkt[x].loc_nadi = ccSpan->loc_nadi;
g_ftdm_sngss7_data.cfg.isupCkt[x].options = ccSpan->options;
g_ftdm_sngss7_data.cfg.isupCkt[x].switchType = ccSpan->switchType;
g_ftdm_sngss7_data.cfg.isupCkt[x].min_digits = ccSpan->min_digits;
g_ftdm_sngss7_data.cfg.isupCkt[x].itx_auto_reply = ccSpan->itx_auto_reply;
g_ftdm_sngss7_data.cfg.isupCkt[x].transparent_iam = ccSpan->transparent_iam;
g_ftdm_sngss7_data.cfg.isupCkt[x].switchType = ccSpan->switchType;
g_ftdm_sngss7_data.cfg.isupCkt[x].min_digits = ccSpan->min_digits;
g_ftdm_sngss7_data.cfg.isupCkt[x].itx_auto_reply = ccSpan->itx_auto_reply;
g_ftdm_sngss7_data.cfg.isupCkt[x].transparent_iam = ccSpan->transparent_iam;
g_ftdm_sngss7_data.cfg.isupCkt[x].transparent_iam_max_size = ccSpan->transparent_iam_max_size;
g_ftdm_sngss7_data.cfg.isupCkt[x].cpg_on_progress_media = ccSpan->cpg_on_progress_media;
g_ftdm_sngss7_data.cfg.isupCkt[x].cpg_on_progress = ccSpan->cpg_on_progress;
if (ccSpan->t3 == 0) {
g_ftdm_sngss7_data.cfg.isupCkt[x].t3 = 1200;

View File

@ -351,6 +351,7 @@ typedef struct ftdm_caller_data {
ftdm_number_t ani; /*!< ANI (Automatic Number Identification) */
ftdm_number_t dnis; /*!< DNIS (Dialed Number Identification Service) */
ftdm_number_t rdnis; /*!< RDNIS (Redirected Dialed Number Identification Service) */
ftdm_number_t loc; /*!< LOC (Location Reference Code) */
char aniII[FTDM_DIGITS_LIMIT]; /*! ANI II */
uint8_t screen; /*!< Screening */
uint8_t pres; /*!< Presentation*/

View File

@ -130,6 +130,9 @@
extern "C" {
#endif
#define SPAN_PENDING_CHANS_QUEUE_SIZE 1000
#define SPAN_PENDING_SIGNALS_QUEUE_SIZE 1000
#define GOTO_STATUS(label,st) status = st; goto label ;
#define ftdm_copy_string(x,y,z) strncpy(x, y, z - 1)
@ -475,6 +478,7 @@ struct ftdm_channel {
int32_t txdrops;
int32_t rxdrops;
ftdm_usrmsg_t *usrmsg;
ftdm_time_t last_state_change_time;
};
struct ftdm_span {
@ -691,6 +695,9 @@ FT_DECLARE(ftdm_status_t) ftdm_sigmsg_remove_var(ftdm_sigmsg_t *sigmsg, const ch
*/
FT_DECLARE(ftdm_status_t) ftdm_sigmsg_set_raw_data(ftdm_sigmsg_t *sigmsg, void *data, ftdm_size_t datalen);
/*! \brief Retrieve a span and channel data structure from a string in the format 'span_id:chan_id'*/
FT_DECLARE(ftdm_status_t) ftdm_get_channel_from_string(const char *string_id, ftdm_span_t **out_span, ftdm_channel_t **out_channel);
/*!
\brief Assert condition
*/

View File

@ -265,6 +265,8 @@ typedef enum {
#define FTDM_CHANNEL_BLOCKING (1ULL << 35)
/*!< Media is digital */
#define FTDM_CHANNEL_DIGITAL_MEDIA (1ULL << 36)
/*!< Native signaling bridge is enabled */
#define FTDM_CHANNEL_NATIVE_SIGBRIDGE (1ULL << 37)
#include "ftdm_state.h"

View File

@ -48,7 +48,7 @@
#include "private/switch_core_pvt.h"
/* pid filename: Stores the process id of the freeswitch process */
#define PIDFILE "netborder-ss7.pid"
#define PIDFILE "nsg.pid"
static char *pfile = PIDFILE;
static int system_ready = 0;
@ -919,7 +919,9 @@ int main(int argc, char *argv[])
if (switch_core_init_and_modload(flags, nc ? SWITCH_FALSE : SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) {
fprintf(stderr, "Failed to initialize modules: %s\n", err);
return 1;
/* 65 is EX_DATAERR (see sysexits.h), meaning some input from the user failed, some init scripts use
* this to tell when fs fails to start due to configuration error */
return 65;
}
if (switch_file_open(&fd, pid_path, SWITCH_FOPEN_READ, SWITCH_FPROT_UREAD | SWITCH_FPROT_UWRITE, pool) == SWITCH_STATUS_SUCCESS) {