forked from Mirrors/freeswitch
Merge branch 'releases.3.4' into releases.3.4.experimental_head
Conflicts: libs/freetdm/mod_freetdm/mod_freetdm.c
This commit is contained in:
commit
cafff50005
@ -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) */
|
||||
@ -626,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:
|
||||
@ -1304,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");
|
||||
@ -1394,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);
|
||||
@ -1564,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);
|
||||
}
|
||||
@ -1650,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));
|
||||
@ -1661,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);
|
||||
@ -1678,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;
|
||||
}
|
||||
|
||||
@ -1804,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);
|
||||
|
||||
|
@ -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
|
||||
@ -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) {
|
||||
@ -2666,6 +2731,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;
|
||||
@ -5465,7 +5531,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_NOTICE, "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));
|
||||
|
@ -263,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);
|
||||
@ -354,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;
|
||||
|
@ -77,9 +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 = 1;
|
||||
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,
|
||||
@ -209,13 +209,12 @@ int ft_to_sngss7_cfg_all(void)
|
||||
}
|
||||
} /* if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP2)) */
|
||||
|
||||
g_ftdm_sngss7_data.gen_config = 2;
|
||||
g_ftdm_sngss7_data.gen_config = SNG_GEN_CFG_STATUS_DONE;
|
||||
|
||||
} /* if (!(g_ftdm_sngss7_data.gen_config)) */
|
||||
|
||||
|
||||
/* FIXME: Please change number 2 to an ENUM that is more explanatory */
|
||||
if (g_ftdm_sngss7_data.gen_config != 2) {
|
||||
if (g_ftdm_sngss7_data.gen_config != SNG_GEN_CFG_STATUS_DONE) {
|
||||
SS7_CRITICAL("General configuration FAILED!\n");
|
||||
return 1;
|
||||
}
|
||||
|
@ -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++;
|
||||
|
||||
|
@ -252,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) {
|
||||
|
@ -55,6 +55,7 @@ ftdm_sngss7_data_t g_ftdm_sngss7_data;
|
||||
/* PROTOTYPES *****************************************************************/
|
||||
static void *ftdm_sangoma_ss7_run (ftdm_thread_t * me, void *obj);
|
||||
static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_event);
|
||||
static void ftdm_sangoma_ss7_process_peer_stack_event (ftdm_channel_t *ftdmchan, sngss7_event_data_t *sngss7_event);
|
||||
|
||||
static ftdm_status_t ftdm_sangoma_ss7_stop (ftdm_span_t * span);
|
||||
static ftdm_status_t ftdm_sangoma_ss7_start (ftdm_span_t * span);
|
||||
@ -338,9 +339,10 @@ static void handle_hw_alarm(ftdm_event_t *e)
|
||||
/* MONITIOR THREADS ***********************************************************/
|
||||
static void *ftdm_sangoma_ss7_run(ftdm_thread_t * me, void *obj)
|
||||
{
|
||||
ftdm_interrupt_t *ftdm_sangoma_ss7_int[2];
|
||||
ftdm_interrupt_t *ftdm_sangoma_ss7_int[3];
|
||||
ftdm_span_t *ftdmspan = (ftdm_span_t *) obj;
|
||||
ftdm_channel_t *ftdmchan = NULL;
|
||||
ftdm_channel_t *peerchan = NULL;
|
||||
ftdm_event_t *event = NULL;
|
||||
sngss7_event_data_t *sngss7_event = NULL;
|
||||
sngss7_span_data_t *sngss7_span = (sngss7_span_data_t *)ftdmspan->signal_data;
|
||||
@ -365,6 +367,12 @@ static void *ftdm_sangoma_ss7_run(ftdm_thread_t * me, void *obj)
|
||||
goto ftdm_sangoma_ss7_run_exit;
|
||||
}
|
||||
|
||||
/* get an interrupt queue for this span for peer channel events */
|
||||
if (ftdm_queue_get_interrupt (sngss7_span->peer_chans, &ftdm_sangoma_ss7_int[2]) != FTDM_SUCCESS) {
|
||||
SS7_CRITICAL ("Failed to get a ftdm_interrupt for span = %d for peer channel events queue!\n", ftdmspan->span_id);
|
||||
goto ftdm_sangoma_ss7_run_exit;
|
||||
}
|
||||
|
||||
while (ftdm_running () && !(ftdm_test_flag (ftdmspan, FTDM_SPAN_STOP_THREAD))) {
|
||||
int x = 0;
|
||||
if (b_alarm_test) {
|
||||
@ -395,7 +403,7 @@ static void *ftdm_sangoma_ss7_run(ftdm_thread_t * me, void *obj)
|
||||
}
|
||||
|
||||
/* check the channel state queue for an event*/
|
||||
switch ((ftdm_interrupt_multiple_wait(ftdm_sangoma_ss7_int, 2, 100))) {
|
||||
switch ((ftdm_interrupt_multiple_wait(ftdm_sangoma_ss7_int, ftdm_array_len(ftdm_sangoma_ss7_int), 100))) {
|
||||
/**********************************************************************/
|
||||
case FTDM_SUCCESS: /* process all pending state changes */
|
||||
|
||||
@ -412,6 +420,31 @@ static void *ftdm_sangoma_ss7_run(ftdm_thread_t * me, void *obj)
|
||||
ftdm_mutex_unlock (ftdmchan->mutex);
|
||||
}
|
||||
|
||||
/* clean out all peer pending channel events */
|
||||
while ((peerchan = ftdm_queue_dequeue (sngss7_span->peer_chans))) {
|
||||
/* note that the channels being dequeued here may not belong to this span
|
||||
they may belong to just about any other span that one of our channels
|
||||
happens to be bridged to */
|
||||
sngss7_chan_data_t *peer_info = peerchan->call_data;
|
||||
sngss7_chan_data_t *chan_info = peer_info->peer_data;
|
||||
ftdmchan = chan_info->ftdmchan;
|
||||
|
||||
/*
|
||||
if there is any state changes at all, those will be done in the opposite channel
|
||||
to peerchan (where the original event was received), therefore we must lock ftdmchan,
|
||||
but do not need to lock peerchan as we only read its event queue, which is already
|
||||
locked when dequeueing */
|
||||
ftdm_channel_lock(ftdmchan);
|
||||
|
||||
/* clean out all pending stack events in the peer channel */
|
||||
while ((sngss7_event = ftdm_queue_dequeue(peer_info->event_queue))) {
|
||||
ftdm_sangoma_ss7_process_peer_stack_event(ftdmchan, sngss7_event);
|
||||
ftdm_safe_free(sngss7_event);
|
||||
}
|
||||
|
||||
ftdm_channel_unlock(ftdmchan);
|
||||
}
|
||||
|
||||
/* clean out all pending stack events */
|
||||
while ((sngss7_event = ftdm_queue_dequeue(sngss7_span->event_queue))) {
|
||||
ftdm_sangoma_ss7_process_stack_event(sngss7_event);
|
||||
@ -511,6 +544,8 @@ static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_ev
|
||||
{
|
||||
sngss7_chan_data_t *sngss7_info = NULL;
|
||||
ftdm_channel_t *ftdmchan = NULL;
|
||||
sngss7_event_data_t *event_clone = NULL;
|
||||
int clone_event = 0;
|
||||
|
||||
/* get the ftdmchan and ss7_chan_data from the circuit */
|
||||
if (extract_chan_data(sngss7_event->circuit, &sngss7_info, &ftdmchan)) {
|
||||
@ -524,6 +559,84 @@ static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_ev
|
||||
/* while there's a state change present on this channel process it */
|
||||
ftdm_channel_advance_states(ftdmchan);
|
||||
|
||||
if (sngss7_event->event_id == SNGSS7_CON_IND_EVENT) {
|
||||
/* this is the first event in a call, flush the event queue */
|
||||
sngss7_flush_queue(sngss7_info->event_queue);
|
||||
/* clear the peer if any */
|
||||
sngss7_info->peer_data = NULL;
|
||||
clone_event++;
|
||||
}
|
||||
|
||||
/* if the call has already started and the event is not a release confirmation, clone the event */
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_CALL_STARTED) &&
|
||||
sngss7_event->event_id != SNGSS7_REL_CFM_EVENT) {
|
||||
clone_event++;
|
||||
}
|
||||
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_NATIVE_SIGBRIDGE)) {
|
||||
|
||||
if (sngss7_event->event_id == SNGSS7_SUSP_IND_EVENT) {
|
||||
sngss7_set_ckt_flag(sngss7_info, FLAG_SUS_RECVD);
|
||||
sngss7_clear_ckt_flag(sngss7_info, FLAG_T6_CANCELED);
|
||||
}
|
||||
|
||||
if (sngss7_test_ckt_flag(sngss7_info, FLAG_SUS_RECVD) &&
|
||||
!sngss7_test_ckt_flag(sngss7_info, FLAG_T6_CANCELED)) {
|
||||
if (sng_cancel_isup_tmr(sngss7_info->suInstId, ISUP_T6i) == RFAILED ) {
|
||||
SS7_ERROR_CHAN(ftdmchan,"[CIC:%d]could not stop timer T6 \n", sngss7_info->circuit->cic);
|
||||
} else {
|
||||
sngss7_set_ckt_flag(sngss7_info, FLAG_T6_CANCELED);
|
||||
SS7_ERROR_CHAN(ftdmchan,"[CIC:%d] isup timer T6 has been cancelled. \n", sngss7_info->circuit->cic);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* clone the event and save it for later usage, we do not clone RLC messages */
|
||||
if (clone_event) {
|
||||
event_clone = ftdm_calloc(1, sizeof(*sngss7_event));
|
||||
if (event_clone) {
|
||||
memcpy(event_clone, sngss7_event, sizeof(*sngss7_event));
|
||||
ftdm_queue_enqueue(sngss7_info->event_queue, event_clone);
|
||||
if (sngss7_info->peer_data) {
|
||||
sngss7_span_data_t *sngss7_peer_span = (sngss7_span_data_t *)sngss7_info->peer_data->ftdmchan->span->signal_data;
|
||||
/* we already have a peer attached, wake him up */
|
||||
ftdm_queue_enqueue(sngss7_peer_span->peer_chans, sngss7_info->ftdmchan);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* we could test for sngss7_info->peer_data too, bit this flag is set earlier, the earlier we know the better */
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_NATIVE_SIGBRIDGE)) {
|
||||
/* most messages are simply relayed in sig bridge mode, except for hangup which requires state changing */
|
||||
switch (sngss7_event->event_id) {
|
||||
case SNGSS7_REL_IND_EVENT:
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
|
||||
break;
|
||||
case SNGSS7_REL_CFM_EVENT:
|
||||
{
|
||||
ftdm_channel_t *peer_chan = sngss7_info->peer_data->ftdmchan;
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
|
||||
if (peer_chan) {
|
||||
/* we need to unlock our chan or we risk deadlock */
|
||||
ftdm_channel_advance_states(ftdmchan);
|
||||
ftdm_channel_unlock(ftdmchan);
|
||||
|
||||
ftdm_channel_lock(peer_chan);
|
||||
if (peer_chan->state != FTDM_CHANNEL_STATE_DOWN) {
|
||||
ftdm_set_state(peer_chan, FTDM_CHANNEL_STATE_DOWN);
|
||||
}
|
||||
ftdm_channel_unlock(peer_chan);
|
||||
|
||||
ftdm_channel_lock(ftdmchan);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* figure out the type of event and send it to the right handler */
|
||||
switch (sngss7_event->event_id) {
|
||||
/**************************************************************************/
|
||||
@ -576,6 +689,7 @@ static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_ev
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case (SNGSS7_SSP_STA_CFM_EVENT):
|
||||
SS7_ERROR("dazed and confused ... hu?!\n");
|
||||
break;
|
||||
/**************************************************************************/
|
||||
default:
|
||||
@ -584,6 +698,7 @@ static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_ev
|
||||
/**************************************************************************/
|
||||
}
|
||||
|
||||
done:
|
||||
/* while there's a state change present on this channel process it */
|
||||
ftdm_channel_advance_states(ftdmchan);
|
||||
|
||||
@ -592,8 +707,337 @@ static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_ev
|
||||
|
||||
}
|
||||
|
||||
FTDM_ENUM_NAMES(SNG_EVENT_TYPE_NAMES, SNG_EVENT_TYPE_STRINGS)
|
||||
FTDM_STR2ENUM(ftdm_str2sngss7_event, ftdm_sngss7_event2str, sng_event_type_t, SNG_EVENT_TYPE_NAMES, SNGSS7_INVALID_EVENT)
|
||||
static void ftdm_sangoma_ss7_process_peer_stack_event (ftdm_channel_t *ftdmchan, sngss7_event_data_t *sngss7_event)
|
||||
{
|
||||
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
||||
|
||||
if (ftdmchan->state < FTDM_CHANNEL_STATE_UP && ftdmchan->state != FTDM_CHANNEL_STATE_DOWN) {
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_UP);
|
||||
ftdm_channel_advance_states(ftdmchan);
|
||||
}
|
||||
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Receiving message %s from bridged peer (our state = %s)\n",
|
||||
sngss7_info->circuit->cic, ftdm_sngss7_event2str(sngss7_event->event_id), ftdm_channel_state2str(ftdmchan->state));
|
||||
|
||||
switch (sngss7_event->event_id) {
|
||||
|
||||
case (SNGSS7_CON_IND_EVENT):
|
||||
SS7_ERROR_CHAN(ftdmchan,"[CIC:%d]Rx IAM while bridged??\n", sngss7_info->circuit->cic);
|
||||
break;
|
||||
|
||||
case (SNGSS7_CON_CFM_EVENT):
|
||||
/* send the ANM request to LibSngSS7 */
|
||||
sng_cc_con_response(1,
|
||||
sngss7_info->suInstId,
|
||||
sngss7_info->spInstId,
|
||||
sngss7_info->circuit->id,
|
||||
&sngss7_event->event.siConEvnt,
|
||||
5);
|
||||
|
||||
SS7_INFO_CHAN(ftdmchan, "[CIC:%d]Tx peer ANM\n", sngss7_info->circuit->cic);
|
||||
break;
|
||||
|
||||
case (SNGSS7_CON_STA_EVENT):
|
||||
switch (sngss7_event->evntType) {
|
||||
/**************************************************************************/
|
||||
case (ADDRCMPLT):
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer ACM\n", sngss7_info->circuit->cic);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case (MODIFY):
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer MODIFY\n", sngss7_info->circuit->cic);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case (MODCMPLT):
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer MODIFY-COMPLETE\n", sngss7_info->circuit->cic);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case (MODREJ):
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer MODIFY-REJECT\n", sngss7_info->circuit->cic);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case (PROGRESS):
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer CPG\n", sngss7_info->circuit->cic);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case (FRWDTRSFR):
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer FOT\n", sngss7_info->circuit->cic);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case (INFORMATION):
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer INF\n", sngss7_info->circuit->cic);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case (INFORMATREQ):
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer INR\n", sngss7_info->circuit->cic);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case (SUBSADDR):
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer SAM\n", sngss7_info->circuit->cic);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case (EXIT):
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer EXIT\n", sngss7_info->circuit->cic);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case (NETRESMGT):
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer NRM\n", sngss7_info->circuit->cic);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case (IDENTREQ):
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer IDR\n", sngss7_info->circuit->cic);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case (IDENTRSP):
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer IRS\n", sngss7_info->circuit->cic);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case (MALCLLPRNT):
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer MALICIOUS CALL\n", sngss7_info->circuit->cic);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case (CHARGE):
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer CRG\n", sngss7_info->circuit->cic);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case (TRFFCHGE):
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer CRG-TARIFF\n", sngss7_info->circuit->cic);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case (CHARGEACK):
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer CRG-ACK\n", sngss7_info->circuit->cic);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case (CALLOFFMSG):
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer CALL-OFFER\n", sngss7_info->circuit->cic);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case (LOOPPRVNT):
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer LOP\n", sngss7_info->circuit->cic);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case (TECT_TIMEOUT):
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer ECT-Timeout\n", sngss7_info->circuit->cic);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case (RINGSEND):
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer RINGING-SEND\n", sngss7_info->circuit->cic);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case (CALLCLEAR):
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer CALL-LINE Clear\n", sngss7_info->circuit->cic);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case (PRERELEASE):
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer PRI\n", sngss7_info->circuit->cic);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case (APPTRANSPORT):
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer APM\n", sngss7_info->circuit->cic);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case (OPERATOR):
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer OPERATOR\n", sngss7_info->circuit->cic);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case (METPULSE):
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer METERING-PULSE\n", sngss7_info->circuit->cic);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case (CLGPTCLR):
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer CALLING_PARTY_CLEAR\n", sngss7_info->circuit->cic);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case (SUBDIRNUM):
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer SUB-DIR\n", sngss7_info->circuit->cic);
|
||||
break;
|
||||
#ifdef SANGOMA_SPIROU
|
||||
case (CHARGE_ACK):
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer TXA\n", sngss7_info->circuit->cic);
|
||||
break;
|
||||
case (CHARGE_UNIT):
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer ITX\n", sngss7_info->circuit->cic);
|
||||
break;
|
||||
#endif
|
||||
/**************************************************************************/
|
||||
default:
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer Unknown Msg %d\n", sngss7_info->circuit->cic, sngss7_event->evntType);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
}
|
||||
sng_cc_con_status (1,
|
||||
sngss7_info->suInstId,
|
||||
sngss7_info->spInstId,
|
||||
sngss7_info->circuit->id,
|
||||
&sngss7_event->event.siCnStEvnt,
|
||||
sngss7_event->evntType);
|
||||
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case (SNGSS7_REL_IND_EVENT):
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer REL cause=%d\n", sngss7_info->circuit->cic, sngss7_event->event.siRelEvnt.causeDgn.causeVal.val);
|
||||
|
||||
//handle_rel_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, &sngss7_event->event.siRelEvnt);
|
||||
sng_cc_rel_request (1,
|
||||
sngss7_info->suInstId,
|
||||
sngss7_info->spInstId,
|
||||
sngss7_info->circuit->id,
|
||||
&sngss7_event->event.siRelEvnt);
|
||||
break;
|
||||
|
||||
/**************************************************************************/
|
||||
case (SNGSS7_REL_CFM_EVENT):
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer RLC\n", sngss7_info->circuit->cic);
|
||||
sng_cc_rel_response (1,
|
||||
sngss7_info->suInstId,
|
||||
sngss7_info->spInstId,
|
||||
sngss7_info->circuit->id,
|
||||
&sngss7_event->event.siRelEvnt);
|
||||
//handle_rel_cfm(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, &sngss7_event->event.siRelEvnt);
|
||||
break;
|
||||
|
||||
/**************************************************************************/
|
||||
case (SNGSS7_DAT_IND_EVENT):
|
||||
//handle_dat_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, &sngss7_event->event.siInfoEvnt);
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer %s\n", sngss7_info->circuit->cic, ftdm_sngss7_event2str(sngss7_event->event_id));
|
||||
sng_cc_dat_request(1,
|
||||
sngss7_info->suInstId,
|
||||
sngss7_info->spInstId,
|
||||
sngss7_info->circuit->id,
|
||||
&sngss7_event->event.siInfoEvnt);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case (SNGSS7_FAC_IND_EVENT):
|
||||
//handle_fac_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, sngss7_event->evntType,
|
||||
//&sngss7_event->event.siFacEvnt);
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer %s -> %d\n", sngss7_info->circuit->cic,
|
||||
ftdm_sngss7_event2str(sngss7_event->event_id), sngss7_event->evntType);
|
||||
sng_cc_fac_request(1,
|
||||
sngss7_info->suInstId,
|
||||
sngss7_info->spInstId,
|
||||
sngss7_info->circuit->id,
|
||||
sngss7_event->evntType,
|
||||
&sngss7_event->event.siFacEvnt);
|
||||
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case (SNGSS7_FAC_CFM_EVENT):
|
||||
//handle_fac_cfm(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit,
|
||||
//sngss7_event->evntType, &sngss7_event->event.siFacEvnt);
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer %s -> %d\n", sngss7_info->circuit->cic,
|
||||
ftdm_sngss7_event2str(sngss7_event->event_id), sngss7_event->evntType);
|
||||
sng_cc_fac_response(1,
|
||||
sngss7_info->suInstId,
|
||||
sngss7_info->spInstId,
|
||||
sngss7_info->circuit->id,
|
||||
sngss7_event->evntType,
|
||||
&sngss7_event->event.siFacEvnt);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case (SNGSS7_UMSG_IND_EVENT):
|
||||
//handle_umsg_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit);
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer %s\n", sngss7_info->circuit->cic, ftdm_sngss7_event2str(sngss7_event->event_id));
|
||||
sng_cc_umsg_request (1,
|
||||
sngss7_info->suInstId,
|
||||
sngss7_info->spInstId,
|
||||
sngss7_info->circuit->id);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case (SNGSS7_STA_IND_EVENT):
|
||||
//handle_sta_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, sngss7_event->globalFlg, sngss7_event->evntType, &sngss7_event->event.siStaEvnt);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case (SNGSS7_SUSP_IND_EVENT):
|
||||
//handle_susp_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, &sngss7_event->event.siSuspEvnt);
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer %s\n", sngss7_info->circuit->cic, ftdm_sngss7_event2str(sngss7_event->event_id));
|
||||
sng_cc_susp_request (1,
|
||||
sngss7_info->suInstId,
|
||||
sngss7_info->spInstId,
|
||||
sngss7_info->circuit->id,
|
||||
&sngss7_event->event.siSuspEvnt);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case (SNGSS7_RESM_IND_EVENT):
|
||||
//handle_resm_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, &sngss7_event->event.siResmEvnt);
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer %s\n", sngss7_info->circuit->cic, ftdm_sngss7_event2str(sngss7_event->event_id));
|
||||
sng_cc_resm_request(1,
|
||||
sngss7_info->suInstId,
|
||||
sngss7_info->spInstId,
|
||||
sngss7_info->circuit->id,
|
||||
&sngss7_event->event.siResmEvnt);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case (SNGSS7_SSP_STA_CFM_EVENT):
|
||||
SS7_CRITICAL("dazed and confused ... hu?!\n");
|
||||
break;
|
||||
/**************************************************************************/
|
||||
default:
|
||||
SS7_ERROR("Failed to relay unknown event id %d!\n", sngss7_event->event_id);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
}
|
||||
|
||||
if ((sngss7_event->event_id == SNGSS7_SUSP_IND_EVENT)) {
|
||||
sngss7_set_ckt_flag(sngss7_info, FLAG_SUS_RECVD);
|
||||
}
|
||||
|
||||
if (sngss7_test_ckt_flag(sngss7_info, FLAG_SUS_RECVD) &&
|
||||
!sngss7_test_ckt_flag(sngss7_info, FLAG_T6_CANCELED)) {
|
||||
if (sng_cancel_isup_tmr(sngss7_info->suInstId, ISUP_T6i) == RFAILED ) {
|
||||
SS7_ERROR_CHAN(ftdmchan,"[CIC:%d]could not stop timer T6 \n", sngss7_info->circuit->cic);
|
||||
} else {
|
||||
sngss7_set_ckt_flag(sngss7_info, FLAG_T6_CANCELED);
|
||||
SS7_ERROR_CHAN(ftdmchan,"[CIC:%d] isup timer T6 has been cancelled. \n", sngss7_info->circuit->cic);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static ftdm_status_t ftdm_sangoma_ss7_native_bridge_state_change(ftdm_channel_t *ftdmchan);
|
||||
static ftdm_status_t ftdm_sangoma_ss7_native_bridge_state_change(ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
||||
|
||||
ftdm_channel_complete_state(ftdmchan);
|
||||
|
||||
switch (ftdmchan->state) {
|
||||
|
||||
case FTDM_CHANNEL_STATE_DOWN:
|
||||
{
|
||||
ftdm_channel_t *close_chan = ftdmchan;
|
||||
sngss7_clear_ckt_flag(sngss7_info, FLAG_SUS_RECVD);
|
||||
sngss7_clear_ckt_flag(sngss7_info, FLAG_T6_CANCELED);
|
||||
sngss7_flush_queue(sngss7_info->event_queue);
|
||||
ftdm_channel_close (&close_chan);
|
||||
}
|
||||
break;
|
||||
|
||||
case FTDM_CHANNEL_STATE_UP:
|
||||
{
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
|
||||
sngss7_send_signal(sngss7_info, FTDM_SIGEVENT_UP);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case FTDM_CHANNEL_STATE_TERMINATING:
|
||||
{
|
||||
ft_to_sngss7_rlc(ftdmchan);
|
||||
/* when receiving REL we move to TERMINATING and notify the user that the bridge is ending */
|
||||
sngss7_send_signal(sngss7_info, FTDM_SIGEVENT_STOP);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
||||
ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
||||
sng_isup_inf_t *isup_intf = NULL;
|
||||
@ -605,6 +1049,13 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
||||
sngss7_info->ckt_flags,
|
||||
sngss7_info->blk_flags);
|
||||
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_NATIVE_SIGBRIDGE)) {
|
||||
/* DIALING is the only state we process normally when doing an outgoing call that is natively bridged */
|
||||
if (ftdmchan->state != FTDM_CHANNEL_STATE_DIALING) {
|
||||
return ftdm_sangoma_ss7_native_bridge_state_change(ftdmchan);
|
||||
}
|
||||
sngss7_info->peer_data = NULL;
|
||||
}
|
||||
|
||||
/*check what state we are supposed to be in */
|
||||
switch (ftdmchan->state) {
|
||||
@ -1058,8 +1509,22 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
||||
|
||||
if (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_OPEN)) {
|
||||
ftdm_channel_t *close_chan = ftdmchan;
|
||||
|
||||
/* detach native bridging if needed (only the outbound leg is responsible for that)
|
||||
Inbound leg was responsible of flushing its queue of events, but peer attach/detach
|
||||
is left as an outbound leg responsibility
|
||||
*/
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
|
||||
sngss7_chan_data_t *peer_info = sngss7_info->peer_data;
|
||||
sngss7_info->peer_data = NULL;
|
||||
if (peer_info) {
|
||||
peer_info->peer_data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* close the channel */
|
||||
SS7_DEBUG_CHAN(ftdmchan,"FTDM Channel Close %s\n", "");
|
||||
sngss7_flush_queue(sngss7_info->event_queue);
|
||||
ftdm_channel_close (&close_chan);
|
||||
}
|
||||
|
||||
@ -1653,8 +2118,10 @@ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(ftdm_sangoma_ss7_outgoing_call)
|
||||
|
||||
/* check if the channel sig state is UP */
|
||||
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP)) {
|
||||
SS7_ERROR_CHAN(ftdmchan, "Requested channel sig state is down, cancelling call!%s\n", " ");
|
||||
goto outgoing_fail;
|
||||
SS7_ERROR_CHAN(ftdmchan, "Requested channel sig state is down, skipping channell!%s\n", " ");
|
||||
/* Sig state will be down due to a block.
|
||||
Right action is to hunt for another call */
|
||||
goto outgoing_break;
|
||||
}
|
||||
|
||||
/* check if there is a remote block */
|
||||
@ -1679,6 +2146,14 @@ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(ftdm_sangoma_ss7_outgoing_call)
|
||||
goto outgoing_break;
|
||||
}
|
||||
|
||||
|
||||
/* This is a gracefull stack resource check.
|
||||
Removing this function will cause unpredictable
|
||||
ungracefule errors. */
|
||||
if (sng_cc_resource_check()) {
|
||||
goto outgoing_fail;
|
||||
}
|
||||
|
||||
/* check the state of the channel */
|
||||
switch (ftdmchan->state){
|
||||
/**************************************************************************/
|
||||
@ -1873,7 +2348,6 @@ static ftdm_status_t ftdm_sangoma_ss7_stop(ftdm_span_t * span)
|
||||
static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_ss7_span_config)
|
||||
{
|
||||
sngss7_span_data_t *ss7_span_info;
|
||||
int sngss7_retry_cnt=5;
|
||||
|
||||
ftdm_log (FTDM_LOG_INFO, "Configuring ftmod_sangoma_ss7 span = %s(%d)...\n",
|
||||
span->name,
|
||||
@ -1900,6 +2374,12 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_ss7_span_config)
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
/* create an peer channel queue for this span */
|
||||
if ((ftdm_queue_create(&(ss7_span_info)->peer_chans, SNGSS7_PEER_CHANS_QUEUE_SIZE)) != FTDM_SUCCESS) {
|
||||
SS7_CRITICAL("Unable to create peer chans queue!\n");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
/*setup the span structure with the info so far */
|
||||
g_ftdm_sngss7_data.sig_cb = sig_cb;
|
||||
span->start = ftdm_sangoma_ss7_start;
|
||||
@ -1923,20 +2403,14 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_ss7_span_config)
|
||||
/* parse the configuration and apply to the global config structure */
|
||||
if (ftmod_ss7_parse_xml(ftdm_parameters, span)) {
|
||||
ftdm_log (FTDM_LOG_CRIT, "Failed to parse configuration!\n");
|
||||
ftdm_sleep (1000);
|
||||
ftdm_sleep (100);
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
/* configure libsngss7 */
|
||||
try_cfg_again:
|
||||
if (ft_to_sngss7_cfg_all()) {
|
||||
if (sngss7_retry_cnt--) {
|
||||
ftdm_sleep (500);
|
||||
ftdm_log (FTDM_LOG_DEBUG, "Failed to configure LibSngSS7 - retrying!\n");
|
||||
goto try_cfg_again;
|
||||
}
|
||||
ftdm_log (FTDM_LOG_CRIT, "Failed to configure LibSngSS7!\n");
|
||||
ftdm_sleep (1000);
|
||||
ftdm_sleep (100);
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
|
@ -56,6 +56,8 @@
|
||||
#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 */
|
||||
|
||||
@ -63,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;
|
||||
@ -81,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),
|
||||
@ -116,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];
|
||||
@ -479,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)
|
||||
@ -492,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
|
||||
@ -537,6 +560,8 @@ typedef enum {
|
||||
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;
|
||||
@ -592,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 \
|
||||
|
@ -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);
|
||||
@ -250,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;
|
||||
@ -259,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;
|
||||
@ -269,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,
|
||||
|
@ -243,15 +243,20 @@ ftdm_status_t copy_locPtyNum_to_sngss7(ftdm_channel_t *ftdmchan, SiCgPtyNum *loc
|
||||
{
|
||||
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;
|
||||
|
||||
locPtyNum->eh.pres = PRSNT_NODEF;
|
||||
locPtyNum->natAddrInd.pres = PRSNT_NODEF;
|
||||
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 = PRSNT_NODEF;
|
||||
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);
|
||||
@ -260,7 +265,7 @@ ftdm_status_t copy_locPtyNum_to_sngss7(ftdm_channel_t *ftdmchan, SiCgPtyNum *loc
|
||||
}
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Location Reference Code Screening Ind %d\n", locPtyNum->scrnInd.val);
|
||||
|
||||
locPtyNum->presRest.pres = PRSNT_NODEF;
|
||||
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);
|
||||
@ -269,10 +274,10 @@ ftdm_status_t copy_locPtyNum_to_sngss7(ftdm_channel_t *ftdmchan, SiCgPtyNum *loc
|
||||
}
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Calling Party Number Presentation Ind %d\n", locPtyNum->presRest.val);
|
||||
|
||||
locPtyNum->numPlan.pres = PRSNT_NODEF;
|
||||
locPtyNum->numPlan.pres = pres_val;
|
||||
locPtyNum->numPlan.val = 0x01;
|
||||
|
||||
locPtyNum->niInd.pres = PRSNT_NODEF;
|
||||
locPtyNum->niInd.pres = pres_val;
|
||||
locPtyNum->niInd.val = 0x00;
|
||||
|
||||
/* check if the user would like a custom NADI value for the Location Reference */
|
||||
@ -439,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;
|
||||
}
|
||||
@ -585,6 +597,7 @@ ftdm_status_t copy_redirgInfo_to_sngss7(ftdm_channel_t *ftdmchan, SiRedirInfo *r
|
||||
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");
|
||||
@ -593,6 +606,7 @@ ftdm_status_t copy_redirgInfo_to_sngss7(ftdm_channel_t *ftdmchan, SiRedirInfo *r
|
||||
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");
|
||||
@ -601,6 +615,7 @@ ftdm_status_t copy_redirgInfo_to_sngss7(ftdm_channel_t *ftdmchan, SiRedirInfo *r
|
||||
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");
|
||||
@ -609,6 +624,7 @@ ftdm_status_t copy_redirgInfo_to_sngss7(ftdm_channel_t *ftdmchan, SiRedirInfo *r
|
||||
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");
|
||||
@ -749,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;
|
||||
@ -765,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;
|
||||
|
||||
|
@ -1923,7 +1923,7 @@ static int ftmod_ss7_parse_cc_span(ftdm_conf_node_t *cc_span)
|
||||
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 = ftdm_true(parm->val);
|
||||
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);
|
||||
@ -2925,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;
|
||||
|
@ -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)
|
||||
@ -686,6 +689,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
|
||||
*/
|
||||
|
@ -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"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user