Merged latest FreeTDM code from Sangoma's repo
Merge remote branch 'smgfs/master' Conflicts: build/modules.conf.in configure.in libs/esl/fs_cli.c libs/freetdm/mod_freetdm/mod_freetdm.c libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c src/include/switch_types.h src/mod/applications/mod_commands/mod_commands.c src/mod/applications/mod_spandsp/mod_spandsp.c src/mod/endpoints/mod_opal/mod_opal.cpp src/mod/endpoints/mod_opal/mod_opal.h src/mod/endpoints/mod_sofia/mod_sofia.h src/mod/endpoints/mod_sofia/rtp.c src/switch.c src/switch_core.c src/switch_rtp.c
This commit is contained in:
commit
4340c4d74c
|
@ -214,6 +214,8 @@ ftmod_sangoma_ss7_la_SOURCES = \
|
|||
$(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sta.c \
|
||||
$(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sts.c \
|
||||
$(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c \
|
||||
$(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_m2ua_xml.c \
|
||||
$(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_m2ua.c \
|
||||
$(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_relay.c
|
||||
|
||||
ftmod_sangoma_ss7_la_CFLAGS = $(FTDM_CFLAGS) $(AM_CFLAGS) -D_GNU_SOURCE
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
SS7 Native Bridge
|
||||
|
||||
Native bridge is enabled on 2 conditions:
|
||||
|
||||
* The SIP header FreeTDM-TransUUID is set in the originating leg and matches a freetdm channel
|
||||
* The variable freetdm_native_sigbridge is true and the originating leg is also a freetdm channel
|
||||
|
||||
Some coding rules apply to this feature:
|
||||
|
||||
- Each channel is responsible for clearning its own peer_data and event queue
|
||||
at the end of the call (when moving to DOWN state)
|
||||
|
||||
- Each channel dequeues messages only from its own queue and enqueues messages
|
||||
in the peer's queue, with the only exception being messages received before
|
||||
the bridge is stablished (IAM for sure and possible SAM messages) because
|
||||
if the bridge is not yet stablished the messages must be queued by the channel
|
||||
in its own queue temporarily until the bridge is ready
|
||||
|
||||
- When the bridge is ready it is the responsibility of the incoming channel to
|
||||
move the messages that stored temporarily in its own queue to the bridged peer queue
|
||||
|
||||
- During hangup, each channel is responsible for moving itself to DOWN. The procedure
|
||||
however differs slightly depending on the hangup conditions
|
||||
|
||||
If the user requests hangup (ie, FreeSWITCH) the request will be noted by setting the
|
||||
FTDM_CHANNEL_USER_HANGUP flag but will not be processed yet because call control is
|
||||
driven only by the link messages (so no hangup from ESL or command line allowed)
|
||||
|
||||
When REL message comes, the channel receiving it must move to TERMINATING state and:
|
||||
|
||||
- If the user has not hangup yet (FTDM_CHANNEL_USER_HANGUP flag not set) then
|
||||
notify the user via SIGEVENT_STOP and wait for the user to move to HANGUP
|
||||
state by calling ftdm_channel_call_hangup() before sending RLC
|
||||
|
||||
- If the user did hangup already (FTDM_CHANNEL_USER_HANGUP flag is set) then
|
||||
skip user notification and move to HANGUP state directly where the RLC message
|
||||
will be sent
|
||||
|
||||
- On HANGUP state the RLC is sent and the channel is moved to DOWN, final state
|
||||
The peer channel will forward the REL message and wait for RLC from the network, when
|
||||
RLC is received the channel can move straight to DOWN itself because the peer channel
|
||||
is completing its own shutdown procedure when it received the REL message
|
||||
|
|
@ -4,6 +4,7 @@ BASE=../../..
|
|||
FT_DIR=..
|
||||
VERBOSE=1
|
||||
FTLA=$(FT_DIR)/libfreetdm.la
|
||||
LOCAL_OBJS=tdm.o
|
||||
LOCAL_CFLAGS=-I$(FT_DIR)/src/include -I$(FT_DIR)/src/isdn/include $(FT_CFLAGS)
|
||||
LOCAL_LDFLAGS=-L$(FT_DIR) -lfreetdm
|
||||
include $(BASE)/build/modmake.rules
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,712 @@
|
|||
/*
|
||||
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
|
||||
*
|
||||
* Version: MPL 1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Mathieu Rene <mrene@avgs.ca>
|
||||
*
|
||||
* tdm.c -- FreeTDM Controllable Channel Module
|
||||
*
|
||||
*/
|
||||
|
||||
#include <switch.h>
|
||||
#include "freetdm.h"
|
||||
|
||||
void ctdm_init(switch_loadable_module_interface_t *module_interface);
|
||||
|
||||
/* Parameters */
|
||||
|
||||
#define kSPAN_ID "span"
|
||||
#define kCHAN_ID "chan"
|
||||
#define kSPAN_NAME "span_name"
|
||||
#define kPREBUFFER_LEN "prebuffer_len"
|
||||
#define kECHOCANCEL "echo_cancel"
|
||||
|
||||
|
||||
static struct {
|
||||
switch_memory_pool_t *pool;
|
||||
switch_endpoint_interface_t *endpoint_interface;
|
||||
} ctdm;
|
||||
|
||||
typedef struct {
|
||||
int span_id;
|
||||
int chan_id;
|
||||
ftdm_channel_t *ftdm_channel;
|
||||
switch_core_session_t *session;
|
||||
switch_codec_t read_codec, write_codec;
|
||||
switch_frame_t read_frame;
|
||||
int prebuffer_len;
|
||||
|
||||
unsigned char databuf[SWITCH_RECOMMENDED_BUFFER_SIZE];
|
||||
} ctdm_private_t;
|
||||
|
||||
static switch_status_t channel_on_init(switch_core_session_t *session);
|
||||
static switch_status_t channel_on_destroy(switch_core_session_t *session);
|
||||
static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event,
|
||||
switch_caller_profile_t *outbound_profile,
|
||||
switch_core_session_t **new_session,
|
||||
switch_memory_pool_t **pool,
|
||||
switch_originate_flag_t flags, switch_call_cause_t *cancel_cause);
|
||||
static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id);
|
||||
static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id);
|
||||
static switch_status_t channel_receive_message(switch_core_session_t *session, switch_core_session_message_t *msg);
|
||||
static switch_status_t channel_receive_event(switch_core_session_t *session, switch_event_t *event);
|
||||
static switch_status_t channel_send_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf);
|
||||
|
||||
|
||||
static ftdm_status_t ctdm_span_prepare(ftdm_span_t *span);
|
||||
|
||||
switch_state_handler_table_t ctdm_state_handlers = {
|
||||
.on_init = channel_on_init,
|
||||
.on_destroy = channel_on_destroy
|
||||
};
|
||||
|
||||
switch_io_routines_t ctdm_io_routines = {
|
||||
.send_dtmf = channel_send_dtmf,
|
||||
.outgoing_channel = channel_outgoing_channel,
|
||||
.read_frame = channel_read_frame,
|
||||
.write_frame = channel_write_frame,
|
||||
.receive_message = channel_receive_message,
|
||||
.receive_event = channel_receive_event
|
||||
};
|
||||
|
||||
static void ctdm_report_alarms(ftdm_channel_t *channel)
|
||||
{
|
||||
switch_event_t *event = NULL;
|
||||
ftdm_alarm_flag_t alarmflag = 0;
|
||||
|
||||
if (switch_event_create(&event, SWITCH_EVENT_TRAP) != SWITCH_STATUS_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "failed to create alarms events\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (ftdm_channel_get_alarms(channel, &alarmflag) != FTDM_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to retrieve alarms %s:%d\n", ftdm_channel_get_span_name(channel), ftdm_channel_get_id(channel));
|
||||
return;
|
||||
}
|
||||
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "span-name", "%s", ftdm_channel_get_span_name(channel));
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "span-number", "%d", ftdm_channel_get_span_id(channel));
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "chan-number", "%d", ftdm_channel_get_id(channel));
|
||||
|
||||
if (alarmflag) {
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "condition", "ftdm-alarm-trap");
|
||||
} else {
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "condition", "ftdm-alarm-clear");
|
||||
}
|
||||
|
||||
if (alarmflag & FTDM_ALARM_RED) {
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "red");
|
||||
}
|
||||
if (alarmflag & FTDM_ALARM_YELLOW) {
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "yellow");
|
||||
}
|
||||
if (alarmflag & FTDM_ALARM_RAI) {
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "rai");
|
||||
}
|
||||
if (alarmflag & FTDM_ALARM_BLUE) {
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "blue");
|
||||
}
|
||||
if (alarmflag & FTDM_ALARM_AIS) {
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "ais");
|
||||
}
|
||||
if (alarmflag & FTDM_ALARM_GENERAL) {
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "general");
|
||||
}
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Reporting [%s] alarms for %s:%d\n",
|
||||
(alarmflag?"ftdm-alarm-trap":"ftdm-alarm-clear"), ftdm_channel_get_span_name(channel), ftdm_channel_get_id(channel));
|
||||
|
||||
switch_event_fire(&event);
|
||||
return;
|
||||
}
|
||||
|
||||
static ftdm_channel_t *ctdm_get_channel_from_event(switch_event_t *event, ftdm_span_t *span)
|
||||
{
|
||||
uint32_t chan_id = 0;
|
||||
const char *chan_number = NULL;
|
||||
|
||||
chan_number = switch_event_get_header(event, "chan-number");
|
||||
|
||||
if (zstr(chan_number)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No channel number specified\n");
|
||||
return NULL;
|
||||
}
|
||||
chan_id = atoi(chan_number);
|
||||
if (!chan_id) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid channel number:%s\n", chan_number);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ftdm_span_get_channel_ph(span, chan_id);
|
||||
}
|
||||
|
||||
|
||||
static void ctdm_event_handler(switch_event_t *event)
|
||||
{
|
||||
ftdm_status_t status = FTDM_FAIL;
|
||||
switch(event->event_id) {
|
||||
case SWITCH_EVENT_TRAP:
|
||||
{
|
||||
ftdm_span_t *span = NULL;
|
||||
ftdm_channel_t *channel = NULL;
|
||||
const char *span_name = NULL;
|
||||
|
||||
const char *cond = switch_event_get_header(event, "condition");
|
||||
const char *command = switch_event_get_header(event, "command");
|
||||
if (zstr(cond)) {
|
||||
return;
|
||||
}
|
||||
|
||||
span_name = switch_event_get_header(event, "span-name");
|
||||
|
||||
if (ftdm_span_find_by_name(span_name, &span) != FTDM_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot find span [%s]\n", span_name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcmp(cond, "mg-tdm-prepare")) {
|
||||
status = ctdm_span_prepare(span);
|
||||
if (status == FTDM_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s:prepared successfully\n", span_name);
|
||||
} else if (status != FTDM_EINVAL) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s:Failed to prepare span\n", span_name);
|
||||
}
|
||||
} else if (!strcmp(cond, "mg-tdm-check")) {
|
||||
channel = ctdm_get_channel_from_event(event, span);
|
||||
if (!channel) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find channel\n");
|
||||
return;
|
||||
}
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Requesting alarm status for %s:%d\n",
|
||||
ftdm_channel_get_span_name(channel), ftdm_channel_get_id(channel));
|
||||
|
||||
ctdm_report_alarms(channel);
|
||||
} else if (!strcmp(cond, "mg-tdm-dtmfremoval")) {
|
||||
uint8_t enable = 0;
|
||||
channel = ctdm_get_channel_from_event(event, span);
|
||||
if (!channel) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find channel\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (zstr(command)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s:No command specified for mg-tdm-dtmfremoval\n", span_name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcmp(command, "enable")) {
|
||||
enable = 1;
|
||||
}
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s DTMF-removal for %s:%d\n",
|
||||
enable ? "Enabling" : "Disabling", ftdm_channel_get_span_name(channel), ftdm_channel_get_id(channel));
|
||||
|
||||
ftdm_channel_command(channel, enable ? FTDM_COMMAND_ENABLE_DTMF_REMOVAL : FTDM_COMMAND_DISABLE_DTMF_REMOVAL, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void ctdm_init(switch_loadable_module_interface_t *module_interface)
|
||||
{
|
||||
switch_endpoint_interface_t *endpoint_interface;
|
||||
ctdm.pool = module_interface->pool;
|
||||
endpoint_interface = switch_loadable_module_create_interface(module_interface, SWITCH_ENDPOINT_INTERFACE);
|
||||
endpoint_interface->interface_name = "tdm";
|
||||
endpoint_interface->io_routines = &ctdm_io_routines;
|
||||
endpoint_interface->state_handler = &ctdm_state_handlers;
|
||||
ctdm.endpoint_interface = endpoint_interface;
|
||||
|
||||
switch_event_bind("mod_freetdm", SWITCH_EVENT_TRAP, SWITCH_EVENT_SUBCLASS_ANY, ctdm_event_handler, NULL);
|
||||
}
|
||||
|
||||
static FIO_SIGNAL_CB_FUNCTION(on_signal_cb)
|
||||
{
|
||||
uint32_t chanid, spanid;
|
||||
switch_event_t *event = NULL;
|
||||
ftdm_alarm_flag_t alarmbits = FTDM_ALARM_NONE;
|
||||
|
||||
chanid = ftdm_channel_get_id(sigmsg->channel);
|
||||
spanid = ftdm_channel_get_span_id(sigmsg->channel);
|
||||
|
||||
switch(sigmsg->event_id) {
|
||||
case FTDM_SIGEVENT_ALARM_CLEAR:
|
||||
case FTDM_SIGEVENT_ALARM_TRAP:
|
||||
{
|
||||
if (ftdm_channel_get_alarms(sigmsg->channel, &alarmbits) != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "failed to retrieve alarms\n");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
if (switch_event_create(&event, SWITCH_EVENT_TRAP) != SWITCH_STATUS_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "failed to create alarms events\n");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
if (sigmsg->event_id == FTDM_SIGEVENT_ALARM_CLEAR) {
|
||||
ftdm_log(FTDM_LOG_NOTICE, "Alarm cleared on channel %d:%d\n", spanid, chanid);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "condition", "ftdm-alarm-clear");
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_NOTICE, "Alarm raised on channel %d:%d\n", spanid, chanid);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "condition", "ftdm-alarm-trap");
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unhandled event %d\n", sigmsg->event_id);
|
||||
break;
|
||||
}
|
||||
|
||||
if (event) {
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "span-name", "%s", ftdm_channel_get_span_name(sigmsg->channel));
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "span-number", "%d", ftdm_channel_get_span_id(sigmsg->channel));
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "chan-number", "%d", ftdm_channel_get_id(sigmsg->channel));
|
||||
|
||||
if (alarmbits & FTDM_ALARM_RED) {
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "red");
|
||||
}
|
||||
if (alarmbits & FTDM_ALARM_YELLOW) {
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "yellow");
|
||||
}
|
||||
if (alarmbits & FTDM_ALARM_RAI) {
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "rai");
|
||||
}
|
||||
if (alarmbits & FTDM_ALARM_BLUE) {
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "blue");
|
||||
}
|
||||
if (alarmbits & FTDM_ALARM_AIS) {
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "ais");
|
||||
}
|
||||
if (alarmbits & FTDM_ALARM_GENERAL) {
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "general");
|
||||
}
|
||||
|
||||
switch_event_fire(&event);
|
||||
}
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
static ftdm_status_t ctdm_span_prepare(ftdm_span_t *span)
|
||||
{
|
||||
if (ftdm_span_register_signal_cb(span, on_signal_cb) != FTDM_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register signal CB\n");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
return ftdm_span_start(span);
|
||||
}
|
||||
|
||||
static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event,
|
||||
switch_caller_profile_t *outbound_profile,
|
||||
switch_core_session_t **new_session,
|
||||
switch_memory_pool_t **pool,
|
||||
switch_originate_flag_t flags, switch_call_cause_t *cancel_cause)
|
||||
{
|
||||
const char *szchanid = switch_event_get_header(var_event, kCHAN_ID),
|
||||
*span_name = switch_event_get_header(var_event, kSPAN_NAME),
|
||||
*szprebuffer_len = switch_event_get_header(var_event, kPREBUFFER_LEN);
|
||||
int chan_id;
|
||||
int span_id;
|
||||
switch_caller_profile_t *caller_profile;
|
||||
ftdm_span_t *span;
|
||||
ftdm_channel_t *chan;
|
||||
switch_channel_t *channel;
|
||||
char name[128];
|
||||
const char *dname;
|
||||
ftdm_codec_t codec;
|
||||
uint32_t interval;
|
||||
ctdm_private_t *tech_pvt = NULL;
|
||||
|
||||
if (zstr(szchanid) || zstr(span_name)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Both ["kSPAN_ID"] and ["kCHAN_ID"] have to be set.\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
chan_id = atoi(szchanid);
|
||||
|
||||
if (ftdm_span_find_by_name(span_name, &span) == FTDM_SUCCESS) {
|
||||
span_id = ftdm_span_get_id(span);
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot find span [%s]\n", span_name);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!(*new_session = switch_core_session_request(ctdm.endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, 0, pool))) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't request session.\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
channel = switch_core_session_get_channel(*new_session);
|
||||
|
||||
if (ftdm_channel_open_ph(span_id, chan_id, &chan) != FTDM_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't open span or channel.\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
span = ftdm_channel_get_span(chan);
|
||||
|
||||
tech_pvt = switch_core_session_alloc(*new_session, sizeof *tech_pvt);
|
||||
tech_pvt->chan_id = chan_id;
|
||||
tech_pvt->span_id = span_id;
|
||||
tech_pvt->ftdm_channel = chan;
|
||||
tech_pvt->session = *new_session;
|
||||
tech_pvt->read_frame.buflen = sizeof(tech_pvt->databuf);
|
||||
tech_pvt->read_frame.data = tech_pvt->databuf;
|
||||
tech_pvt->prebuffer_len = zstr(szprebuffer_len) ? 0 : atoi(szprebuffer_len);
|
||||
switch_core_session_set_private(*new_session, tech_pvt);
|
||||
|
||||
|
||||
caller_profile = switch_caller_profile_clone(*new_session, outbound_profile);
|
||||
switch_channel_set_caller_profile(channel, caller_profile);
|
||||
|
||||
snprintf(name, sizeof(name), "tdm/%d:%d", span_id, chan_id);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Connect outbound channel %s\n", name);
|
||||
switch_channel_set_name(channel, name);
|
||||
|
||||
switch_channel_set_state(channel, CS_INIT);
|
||||
|
||||
if (FTDM_SUCCESS != ftdm_channel_command(chan, FTDM_COMMAND_GET_CODEC, &codec)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to retrieve channel codec.\n");
|
||||
return SWITCH_STATUS_GENERR;
|
||||
}
|
||||
|
||||
if (FTDM_SUCCESS != ftdm_channel_command(chan, FTDM_COMMAND_GET_INTERVAL, &interval)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to retrieve channel interval.\n");
|
||||
return SWITCH_STATUS_GENERR;
|
||||
}
|
||||
|
||||
if (FTDM_SUCCESS != ftdm_channel_command(chan, FTDM_COMMAND_SET_PRE_BUFFER_SIZE, &tech_pvt->prebuffer_len)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to set channel pre buffer size.\n");
|
||||
return SWITCH_STATUS_GENERR;
|
||||
}
|
||||
|
||||
if (FTDM_SUCCESS != ftdm_channel_command(tech_pvt->ftdm_channel, FTDM_COMMAND_ENABLE_ECHOCANCEL, NULL)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to set enable echo cancellation.\n");
|
||||
}
|
||||
|
||||
switch(codec) {
|
||||
case FTDM_CODEC_ULAW:
|
||||
{
|
||||
dname = "PCMU";
|
||||
}
|
||||
break;
|
||||
case FTDM_CODEC_ALAW:
|
||||
{
|
||||
dname = "PCMA";
|
||||
}
|
||||
break;
|
||||
case FTDM_CODEC_SLIN:
|
||||
{
|
||||
dname = "L16";
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid codec value retrieved from channel, codec value: %d\n", codec);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (switch_core_codec_init(&tech_pvt->read_codec,
|
||||
dname,
|
||||
NULL,
|
||||
8000,
|
||||
interval,
|
||||
1,
|
||||
SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
|
||||
NULL, switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n");
|
||||
goto fail;
|
||||
} else {
|
||||
if (switch_core_codec_init(&tech_pvt->write_codec,
|
||||
dname,
|
||||
NULL,
|
||||
8000,
|
||||
interval,
|
||||
1,
|
||||
SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
|
||||
NULL, switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n");
|
||||
switch_core_codec_destroy(&tech_pvt->read_codec);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
if (switch_core_session_set_read_codec(*new_session, &tech_pvt->read_codec) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't set read codec?\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (switch_core_session_set_write_codec(*new_session, &tech_pvt->write_codec) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't set write codec?\n");
|
||||
}
|
||||
|
||||
if (switch_core_session_thread_launch(*new_session) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't start session thread.\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
switch_channel_mark_answered(channel);
|
||||
|
||||
return SWITCH_CAUSE_SUCCESS;
|
||||
|
||||
fail:
|
||||
|
||||
if (tech_pvt) {
|
||||
if (tech_pvt->ftdm_channel) {
|
||||
ftdm_channel_close(&tech_pvt->ftdm_channel);
|
||||
}
|
||||
|
||||
if (tech_pvt->read_codec.implementation) {
|
||||
switch_core_codec_destroy(&tech_pvt->read_codec);
|
||||
}
|
||||
|
||||
if (tech_pvt->write_codec.implementation) {
|
||||
switch_core_codec_destroy(&tech_pvt->write_codec);
|
||||
}
|
||||
}
|
||||
|
||||
if (*new_session) {
|
||||
switch_core_session_destroy(new_session);
|
||||
}
|
||||
return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
|
||||
}
|
||||
|
||||
static switch_status_t channel_on_init(switch_core_session_t *session)
|
||||
{
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
|
||||
switch_channel_set_state(channel, CS_CONSUME_MEDIA);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static switch_status_t channel_on_destroy(switch_core_session_t *session)
|
||||
{
|
||||
ctdm_private_t *tech_pvt = switch_core_session_get_private(session);
|
||||
|
||||
if ((tech_pvt = switch_core_session_get_private(session))) {
|
||||
|
||||
if (FTDM_SUCCESS != ftdm_channel_command(tech_pvt->ftdm_channel, FTDM_COMMAND_ENABLE_ECHOCANCEL, NULL)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to enable echo cancellation.\n");
|
||||
}
|
||||
|
||||
if (tech_pvt->read_codec.implementation) {
|
||||
switch_core_codec_destroy(&tech_pvt->read_codec);
|
||||
}
|
||||
|
||||
if (tech_pvt->write_codec.implementation) {
|
||||
switch_core_codec_destroy(&tech_pvt->write_codec);
|
||||
}
|
||||
|
||||
ftdm_channel_close(&tech_pvt->ftdm_channel);
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id)
|
||||
{
|
||||
ftdm_wait_flag_t wflags = FTDM_READ;
|
||||
ftdm_status_t status;
|
||||
ctdm_private_t *tech_pvt;
|
||||
const char *name;
|
||||
switch_channel_t *channel;
|
||||
int chunk;
|
||||
uint32_t span_id, chan_id;
|
||||
ftdm_size_t len;
|
||||
char dtmf[128] = "";
|
||||
|
||||
channel = switch_core_session_get_channel(session);
|
||||
assert(channel != NULL);
|
||||
|
||||
tech_pvt = switch_core_session_get_private(session);
|
||||
assert(tech_pvt != NULL);
|
||||
|
||||
name = switch_channel_get_name(channel);
|
||||
|
||||
top:
|
||||
wflags = FTDM_READ;
|
||||
chunk = ftdm_channel_get_io_interval(tech_pvt->ftdm_channel) * 2;
|
||||
status = ftdm_channel_wait(tech_pvt->ftdm_channel, &wflags, chunk);
|
||||
|
||||
|
||||
span_id = ftdm_channel_get_span_id(tech_pvt->ftdm_channel);
|
||||
chan_id = ftdm_channel_get_id(tech_pvt->ftdm_channel);
|
||||
|
||||
if (status == FTDM_FAIL) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to read from channel %s device %d:%d!\n", name, span_id, chan_id);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (status == FTDM_TIMEOUT) {
|
||||
goto top;
|
||||
}
|
||||
|
||||
if (!(wflags & FTDM_READ)) {
|
||||
goto top;
|
||||
}
|
||||
|
||||
len = tech_pvt->read_frame.buflen;
|
||||
if (ftdm_channel_read(tech_pvt->ftdm_channel, tech_pvt->read_frame.data, &len) != FTDM_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to read from channel %s device %d:%d!\n", name, span_id, chan_id);
|
||||
}
|
||||
|
||||
*frame = &tech_pvt->read_frame;
|
||||
tech_pvt->read_frame.datalen = (uint32_t)len;
|
||||
tech_pvt->read_frame.samples = tech_pvt->read_frame.datalen;
|
||||
tech_pvt->read_frame.codec = &tech_pvt->read_codec;
|
||||
|
||||
if (ftdm_channel_get_codec(tech_pvt->ftdm_channel) == FTDM_CODEC_SLIN) {
|
||||
tech_pvt->read_frame.samples /= 2;
|
||||
}
|
||||
|
||||
while (ftdm_channel_dequeue_dtmf(tech_pvt->ftdm_channel, dtmf, sizeof(dtmf))) {
|
||||
switch_dtmf_t _dtmf = { 0, switch_core_default_dtmf_duration(0) };
|
||||
char *p;
|
||||
for (p = dtmf; p && *p; p++) {
|
||||
if (is_dtmf(*p)) {
|
||||
_dtmf.digit = *p;
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Queuing DTMF [%c] in channel %s device %d:%d\n", *p, name, span_id, chan_id);
|
||||
switch_channel_queue_dtmf(channel, &_dtmf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
|
||||
fail:
|
||||
return SWITCH_STATUS_GENERR;
|
||||
}
|
||||
|
||||
static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id)
|
||||
{
|
||||
ftdm_wait_flag_t wflags = FTDM_WRITE;
|
||||
ctdm_private_t *tech_pvt;
|
||||
const char *name;
|
||||
switch_channel_t *channel;
|
||||
uint32_t span_id, chan_id;
|
||||
ftdm_size_t len;
|
||||
unsigned char data[SWITCH_RECOMMENDED_BUFFER_SIZE] = {0};
|
||||
|
||||
channel = switch_core_session_get_channel(session);
|
||||
assert(channel != NULL);
|
||||
|
||||
tech_pvt = switch_core_session_get_private(session);
|
||||
assert(tech_pvt != NULL);
|
||||
|
||||
span_id = ftdm_channel_get_span_id(tech_pvt->ftdm_channel);
|
||||
chan_id = ftdm_channel_get_id(tech_pvt->ftdm_channel);
|
||||
|
||||
name = switch_channel_get_name(channel);
|
||||
|
||||
if (switch_test_flag(frame, SFF_CNG)) {
|
||||
frame->data = data;
|
||||
frame->buflen = sizeof(data);
|
||||
if ((frame->datalen = tech_pvt->write_codec.implementation->encoded_bytes_per_packet) > frame->buflen) {
|
||||
goto fail;
|
||||
}
|
||||
memset(data, 255, frame->datalen);
|
||||
}
|
||||
|
||||
wflags = FTDM_WRITE;
|
||||
ftdm_channel_wait(tech_pvt->ftdm_channel, &wflags, ftdm_channel_get_io_interval(tech_pvt->ftdm_channel) * 10);
|
||||
|
||||
if (!(wflags & FTDM_WRITE)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Dropping frame! (write not ready) in channel %s device %d:%d!\n", name, span_id, chan_id);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
len = frame->datalen;
|
||||
if (ftdm_channel_write(tech_pvt->ftdm_channel, frame->data, frame->buflen, &len) != FTDM_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Failed to write to channel %s device %d:%d!\n", name, span_id, chan_id);
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
|
||||
fail:
|
||||
return SWITCH_STATUS_GENERR;
|
||||
}
|
||||
|
||||
static switch_status_t channel_send_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf)
|
||||
{
|
||||
ctdm_private_t *tech_pvt = NULL;
|
||||
char tmp[2] = "";
|
||||
|
||||
tech_pvt = switch_core_session_get_private(session);
|
||||
assert(tech_pvt != NULL);
|
||||
|
||||
tmp[0] = dtmf->digit;
|
||||
ftdm_channel_command(tech_pvt->ftdm_channel, FTDM_COMMAND_SEND_DTMF, tmp);
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static switch_status_t channel_receive_message(switch_core_session_t *session, switch_core_session_message_t *msg)
|
||||
{
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static switch_status_t channel_receive_event(switch_core_session_t *session, switch_event_t *event)
|
||||
{
|
||||
const char *command = switch_event_get_header(event, "command");
|
||||
ctdm_private_t *tech_pvt = switch_core_session_get_private(session);
|
||||
|
||||
if (!zstr(command)) {
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "FreeTDM received %s command \n",command);
|
||||
|
||||
if (!strcasecmp(command, kPREBUFFER_LEN)) {
|
||||
const char *szval = switch_event_get_header(event, kPREBUFFER_LEN);
|
||||
int val = !zstr(szval) ? atoi(szval) : 0;
|
||||
|
||||
if (tech_pvt->prebuffer_len == val) {
|
||||
tech_pvt->prebuffer_len = val;
|
||||
if (FTDM_SUCCESS != ftdm_channel_command(tech_pvt->ftdm_channel, FTDM_COMMAND_SET_PRE_BUFFER_SIZE, &tech_pvt->prebuffer_len)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to set channel pre buffer size.\n");
|
||||
return SWITCH_STATUS_GENERR;
|
||||
}
|
||||
}
|
||||
} else if (!strcasecmp(command, kECHOCANCEL)) {
|
||||
const char *szval = switch_event_get_header(event, kECHOCANCEL);
|
||||
int enabled = !!switch_true(szval);
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "FreeTDM sending echo cancel [%s] command \n",enabled ? "enable" : "disable");
|
||||
|
||||
if (FTDM_SUCCESS != ftdm_channel_command(tech_pvt->ftdm_channel, enabled ? FTDM_COMMAND_ENABLE_ECHOCANCEL : FTDM_COMMAND_DISABLE_ECHOCANCEL, NULL)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to %s echo cancellation.\n", enabled ? "enable" : "disable");
|
||||
}
|
||||
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "FreeTDM received unknown command [%s] \n",command);
|
||||
}
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
|
@ -36,10 +36,10 @@
|
|||
* David Yat Sin <dyatsin@sangoma.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include "private/ftdm_core.h"
|
||||
#include <stdarg.h>
|
||||
#include <ctype.h>
|
||||
#ifdef WIN32
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
@ -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
|
||||
|
@ -64,11 +62,78 @@ struct tm *localtime_r(const time_t *clock, struct tm *result);
|
|||
ftdm_time_t time_last_throttle_log = 0;
|
||||
ftdm_time_t time_current_throttle_log = 0;
|
||||
|
||||
typedef struct val_str {
|
||||
const char *str;
|
||||
unsigned long long val;
|
||||
} val_str_t;
|
||||
|
||||
static val_str_t channel_flag_strs[] = {
|
||||
{ "configured" , FTDM_CHANNEL_CONFIGURED},
|
||||
{ "ready", FTDM_CHANNEL_READY},
|
||||
{ "open", FTDM_CHANNEL_OPEN},
|
||||
{ "dtmf-detect", FTDM_CHANNEL_DTMF_DETECT},
|
||||
{ "suppress-dtmf", FTDM_CHANNEL_SUPRESS_DTMF},
|
||||
{ "transcode", FTDM_CHANNEL_TRANSCODE},
|
||||
{ "buffer", FTDM_CHANNEL_BUFFER},
|
||||
{ "in-thread", FTDM_CHANNEL_INTHREAD},
|
||||
{ "wink", FTDM_CHANNEL_WINK},
|
||||
{ "flash", FTDM_CHANNEL_FLASH},
|
||||
{ "state-change", FTDM_CHANNEL_STATE_CHANGE},
|
||||
{ "hold", FTDM_CHANNEL_HOLD},
|
||||
{ "in-use", FTDM_CHANNEL_INUSE},
|
||||
{ "off-hook", FTDM_CHANNEL_OFFHOOK},
|
||||
{ "ringing", FTDM_CHANNEL_RINGING},
|
||||
{ "progress-detect", FTDM_CHANNEL_PROGRESS_DETECT},
|
||||
{ "callerid-detect", FTDM_CHANNEL_CALLERID_DETECT},
|
||||
{ "outbound", FTDM_CHANNEL_OUTBOUND},
|
||||
{ "suspended", FTDM_CHANNEL_SUSPENDED},
|
||||
{ "3-way", FTDM_CHANNEL_3WAY},
|
||||
{ "progress", FTDM_CHANNEL_PROGRESS},
|
||||
{ "media", FTDM_CHANNEL_MEDIA},
|
||||
{ "answered", FTDM_CHANNEL_ANSWERED},
|
||||
{ "mute", FTDM_CHANNEL_MUTE},
|
||||
{ "use-rx-gain", FTDM_CHANNEL_USE_RX_GAIN},
|
||||
{ "use-tx-gain", FTDM_CHANNEL_USE_TX_GAIN},
|
||||
{ "in-alarm", FTDM_CHANNEL_IN_ALARM},
|
||||
{ "sig-up", FTDM_CHANNEL_SIG_UP},
|
||||
{ "user-hangup", FTDM_CHANNEL_USER_HANGUP},
|
||||
{ "rx-disabled", FTDM_CHANNEL_RX_DISABLED},
|
||||
{ "tx-disabled", FTDM_CHANNEL_TX_DISABLED},
|
||||
{ "call-started", FTDM_CHANNEL_CALL_STARTED},
|
||||
{ "non-block", FTDM_CHANNEL_NONBLOCK},
|
||||
{ "ind-ack-pending", FTDM_CHANNEL_IND_ACK_PENDING},
|
||||
{ "blocking", FTDM_CHANNEL_BLOCKING},
|
||||
{ "media", FTDM_CHANNEL_DIGITAL_MEDIA},
|
||||
{ "native-sigbridge", FTDM_CHANNEL_NATIVE_SIGBRIDGE},
|
||||
{ "invalid", FTDM_CHANNEL_MAX_FLAG},
|
||||
};
|
||||
|
||||
static val_str_t span_flag_strs[] = {
|
||||
{ "configured", FTDM_SPAN_CONFIGURED},
|
||||
{ "started", FTDM_SPAN_STARTED},
|
||||
{ "state-change", FTDM_SPAN_STATE_CHANGE},
|
||||
{ "suspended", FTDM_SPAN_SUSPENDED},
|
||||
{ "in-thread", FTDM_SPAN_IN_THREAD},
|
||||
{ "stop-thread", FTDM_SPAN_STOP_THREAD},
|
||||
{ "use-chan-queue", FTDM_SPAN_USE_CHAN_QUEUE},
|
||||
{ "suggest-chan-id", FTDM_SPAN_SUGGEST_CHAN_ID},
|
||||
{ "use-av-rate", FTDM_SPAN_USE_AV_RATE},
|
||||
{ "power-saving", FTDM_SPAN_PWR_SAVING},
|
||||
{ "signals-queue", FTDM_SPAN_USE_SIGNALS_QUEUE},
|
||||
{ "proceed-state", FTDM_SPAN_USE_PROCEED_STATE},
|
||||
{ "skip-state", FTDM_SPAN_USE_SKIP_STATES},
|
||||
{ "non-stoppable", FTDM_SPAN_NON_STOPPABLE},
|
||||
{ "use-transfer", FTDM_SPAN_USE_TRANSFER},
|
||||
};
|
||||
|
||||
static ftdm_status_t ftdm_call_set_call_id(ftdm_channel_t *fchan, ftdm_caller_data_t *caller_data);
|
||||
static ftdm_status_t ftdm_call_clear_call_id(ftdm_caller_data_t *caller_data);
|
||||
static ftdm_status_t ftdm_channel_done(ftdm_channel_t *ftdmchan);
|
||||
static ftdm_status_t ftdm_channel_sig_indicate(ftdm_channel_t *ftdmchan, ftdm_channel_indication_t indication, ftdm_usrmsg_t *usrmsg);
|
||||
|
||||
static const char *ftdm_val2str(unsigned long long val, val_str_t *val_str_table, ftdm_size_t array_size, const char *default_str);
|
||||
static unsigned long long ftdm_str2val(const char *str, val_str_t *val_str_table, ftdm_size_t array_size, unsigned long long default_val);
|
||||
|
||||
|
||||
static int time_is_init = 0;
|
||||
|
||||
|
@ -171,7 +236,7 @@ static void stop_chan_io_dump(ftdm_io_dump_t *dump)
|
|||
return;
|
||||
}
|
||||
ftdm_safe_free(dump->buffer);
|
||||
memset(dump, 0, sizeof(dump));
|
||||
memset(dump, 0, sizeof(*dump));
|
||||
}
|
||||
|
||||
static ftdm_status_t start_chan_io_dump(ftdm_channel_t *chan, ftdm_io_dump_t *dump, ftdm_size_t size)
|
||||
|
@ -223,7 +288,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;
|
||||
|
||||
|
@ -1413,6 +1478,16 @@ FT_DECLARE(ftdm_status_t) ftdm_group_channel_use_count(ftdm_group_t *group, uint
|
|||
|
||||
static __inline__ int chan_is_avail(ftdm_channel_t *check)
|
||||
{
|
||||
if ((check->span->signal_type == FTDM_SIGTYPE_M2UA) ||
|
||||
(check->span->signal_type == FTDM_SIGTYPE_NONE)) {
|
||||
if (!ftdm_test_flag(check, FTDM_CHANNEL_READY) ||
|
||||
ftdm_test_flag(check, FTDM_CHANNEL_INUSE) ||
|
||||
ftdm_test_flag(check, FTDM_CHANNEL_SUSPENDED) ||
|
||||
ftdm_test_flag(check, FTDM_CHANNEL_IN_ALARM) ||
|
||||
check->state != FTDM_CHANNEL_STATE_DOWN) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if (!ftdm_test_flag(check, FTDM_CHANNEL_READY) ||
|
||||
!ftdm_test_flag(check, FTDM_CHANNEL_SIG_UP) ||
|
||||
ftdm_test_flag(check, FTDM_CHANNEL_INUSE) ||
|
||||
|
@ -1421,6 +1496,7 @@ static __inline__ int chan_is_avail(ftdm_channel_t *check)
|
|||
check->state != FTDM_CHANNEL_STATE_DOWN) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1825,7 +1901,7 @@ done:
|
|||
return status;
|
||||
}
|
||||
|
||||
static ftdm_status_t _ftdm_channel_open(uint32_t span_id, uint32_t chan_id, ftdm_channel_t **ftdmchan)
|
||||
static ftdm_status_t _ftdm_channel_open(uint32_t span_id, uint32_t chan_id, ftdm_channel_t **ftdmchan, uint8_t physical)
|
||||
{
|
||||
ftdm_channel_t *check = NULL;
|
||||
ftdm_span_t *span = NULL;
|
||||
|
@ -1854,6 +1930,37 @@ static ftdm_status_t _ftdm_channel_open(uint32_t span_id, uint32_t chan_id, ftdm
|
|||
goto done;
|
||||
}
|
||||
|
||||
if (physical) { /* Open by physical */
|
||||
ftdm_channel_t *fchan = NULL;
|
||||
ftdm_iterator_t *citer = NULL;
|
||||
ftdm_iterator_t *curr = NULL;
|
||||
|
||||
if (chan_id < 1) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "Invalid physical channel %d to open in span %d\n", chan_id, span_id);
|
||||
status = FTDM_FAIL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
citer = ftdm_span_get_chan_iterator(span, NULL);
|
||||
if (!citer) {
|
||||
status = ENOMEM;
|
||||
goto done;
|
||||
}
|
||||
|
||||
for (curr = citer ; curr; curr = ftdm_iterator_next(curr)) {
|
||||
fchan = ftdm_iterator_current(curr);
|
||||
if (fchan->physical_chan_id == chan_id) {
|
||||
check = fchan;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ftdm_iterator_free(citer);
|
||||
if (!check) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Wow, no physical channel %d in span %d\n", chan_id, span_id);
|
||||
goto done;
|
||||
}
|
||||
} else { /* Open by logical */
|
||||
if (chan_id < 1 || chan_id > span->chan_count) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "Invalid channel %d to open in span %d\n", chan_id, span_id);
|
||||
goto done;
|
||||
|
@ -1863,6 +1970,7 @@ static ftdm_status_t _ftdm_channel_open(uint32_t span_id, uint32_t chan_id, ftdm
|
|||
ftdm_log(FTDM_LOG_CRIT, "Wow, no channel %d in span %d\n", chan_id, span_id);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
ftdm_channel_lock(check);
|
||||
|
||||
|
@ -1932,7 +2040,18 @@ done:
|
|||
FT_DECLARE(ftdm_status_t) ftdm_channel_open(uint32_t span_id, uint32_t chan_id, ftdm_channel_t **ftdmchan)
|
||||
{
|
||||
ftdm_status_t status;
|
||||
status = _ftdm_channel_open(span_id, chan_id, ftdmchan);
|
||||
status = _ftdm_channel_open(span_id, chan_id, ftdmchan, 0);
|
||||
if (status == FTDM_SUCCESS) {
|
||||
ftdm_channel_t *fchan = *ftdmchan;
|
||||
ftdm_channel_unlock(fchan);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
FT_DECLARE(ftdm_status_t) ftdm_channel_open_ph(uint32_t span_id, uint32_t chan_id, ftdm_channel_t **ftdmchan)
|
||||
{
|
||||
ftdm_status_t status;
|
||||
status = _ftdm_channel_open(span_id, chan_id, ftdmchan, 1);
|
||||
if (status == FTDM_SUCCESS) {
|
||||
ftdm_channel_t *fchan = *ftdmchan;
|
||||
ftdm_channel_unlock(fchan);
|
||||
|
@ -2229,6 +2348,15 @@ static ftdm_status_t _ftdm_channel_call_hangup_nl(const char *file, const char *
|
|||
{
|
||||
ftdm_status_t status = FTDM_SUCCESS;
|
||||
|
||||
/* In native sigbridge mode we ignore hangup requests from the user and hangup only when the signaling module decides it */
|
||||
if (ftdm_test_flag(chan, FTDM_CHANNEL_NATIVE_SIGBRIDGE) && chan->state != FTDM_CHANNEL_STATE_TERMINATING) {
|
||||
|
||||
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));
|
||||
ftdm_set_flag(chan, FTDM_CHANNEL_USER_HANGUP);
|
||||
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 */
|
||||
|
@ -2255,6 +2383,8 @@ static ftdm_status_t _ftdm_channel_call_hangup_nl(const char *file, const char *
|
|||
ftdm_channel_close(&chan);
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -2313,6 +2443,39 @@ FT_DECLARE(ftdm_channel_t *) ftdm_span_get_channel(const ftdm_span_t *span, uint
|
|||
return chan;
|
||||
}
|
||||
|
||||
FT_DECLARE(ftdm_channel_t *) ftdm_span_get_channel_ph(const ftdm_span_t *span, uint32_t chanid)
|
||||
{
|
||||
ftdm_channel_t *chan = NULL;
|
||||
ftdm_channel_t *fchan = NULL;
|
||||
ftdm_iterator_t *citer = NULL;
|
||||
ftdm_iterator_t *curr = NULL;
|
||||
|
||||
ftdm_mutex_lock(span->mutex);
|
||||
if (chanid == 0) {
|
||||
ftdm_mutex_unlock(span->mutex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
citer = ftdm_span_get_chan_iterator(span, NULL);
|
||||
if (!citer) {
|
||||
ftdm_mutex_unlock(span->mutex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (curr = citer ; curr; curr = ftdm_iterator_next(curr)) {
|
||||
fchan = ftdm_iterator_current(curr);
|
||||
if (fchan->physical_chan_id == chanid) {
|
||||
chan = fchan;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ftdm_iterator_free(citer);
|
||||
|
||||
ftdm_mutex_unlock(span->mutex);
|
||||
return chan;
|
||||
}
|
||||
|
||||
FT_DECLARE(uint32_t) ftdm_span_get_chan_count(const ftdm_span_t *span)
|
||||
{
|
||||
uint32_t count;
|
||||
|
@ -2350,6 +2513,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),
|
||||
|
@ -2450,10 +2622,56 @@ 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;
|
||||
|
||||
if (!string_id) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "Cannot parse NULL channel id string\n");
|
||||
status = FTDM_EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
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");
|
||||
|
@ -2489,6 +2707,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) {
|
||||
|
@ -2544,7 +2772,7 @@ FT_DECLARE(ftdm_status_t) _ftdm_call_place(const char *file, const char *func, i
|
|||
status = _ftdm_channel_open_by_group(hunting->mode_data.group.group_id,
|
||||
hunting->mode_data.group.direction, caller_data, &fchan);
|
||||
} else if (hunting->mode == FTDM_HUNT_CHAN) {
|
||||
status = _ftdm_channel_open(hunting->mode_data.chan.span_id, hunting->mode_data.chan.chan_id, &fchan);
|
||||
status = _ftdm_channel_open(hunting->mode_data.chan.span_id, hunting->mode_data.chan.chan_id, &fchan, 0);
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_ERROR, "Cannot make outbound call with invalid hunting mode %d\n", hunting->mode);
|
||||
return FTDM_EINVAL;
|
||||
|
@ -2692,6 +2920,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;
|
||||
|
@ -4291,7 +4520,7 @@ static struct {
|
|||
ftdm_io_interface_t *pika_interface;
|
||||
} interfaces;
|
||||
|
||||
static void print_channels_by_flag(ftdm_stream_handle_t *stream, int32_t flagval, int not, int *count)
|
||||
static void print_channels_by_flag(ftdm_stream_handle_t *stream, ftdm_span_t *inspan, uint32_t inchan_id, int32_t flagval, int not, int *count)
|
||||
{
|
||||
ftdm_hash_iterator_t *i = NULL;
|
||||
ftdm_span_t *span;
|
||||
|
@ -4301,11 +4530,54 @@ static void print_channels_by_flag(ftdm_stream_handle_t *stream, int32_t flagval
|
|||
const void *key = NULL;
|
||||
void *val = NULL;
|
||||
uint32_t flag = (1 << flagval);
|
||||
int mycount = 0;
|
||||
|
||||
*count = 0;
|
||||
|
||||
ftdm_mutex_lock(globals.mutex);
|
||||
|
||||
if (inspan) {
|
||||
citer = ftdm_span_get_chan_iterator(inspan, NULL);
|
||||
if (!citer) {
|
||||
goto end;
|
||||
}
|
||||
for (curr = citer ; curr; curr = ftdm_iterator_next(curr)) {
|
||||
fchan = ftdm_iterator_current(curr);
|
||||
if (!inchan_id || inchan_id == fchan->chan_id) {
|
||||
if (not) {
|
||||
if (!ftdm_test_flag(fchan, flag)) {
|
||||
stream->write_function(stream, "[s%dc%d][%d:%d] flag !%d(!%s) ON \n",
|
||||
fchan->span_id, fchan->chan_id,
|
||||
fchan->physical_span_id, fchan->physical_chan_id,
|
||||
flagval, ftdm_val2str(flag, channel_flag_strs, ftdm_array_len(channel_flag_strs), "invalid"));
|
||||
|
||||
mycount++;
|
||||
} else {
|
||||
stream->write_function(stream, "[s%dc%d][%d:%d] flag !%d(!%s) OFF \n",
|
||||
fchan->span_id, fchan->chan_id,
|
||||
fchan->physical_span_id, fchan->physical_chan_id,
|
||||
flagval, ftdm_val2str(flag, channel_flag_strs, ftdm_array_len(channel_flag_strs), "invalid"));
|
||||
}
|
||||
} else {
|
||||
if (ftdm_test_flag(fchan, flag)) {
|
||||
stream->write_function(stream, "[s%dc%d][%d:%d] flag %d(%s) ON\n",
|
||||
fchan->span_id, fchan->chan_id,
|
||||
fchan->physical_span_id, fchan->physical_chan_id,
|
||||
flagval, ftdm_val2str(flag, channel_flag_strs, ftdm_array_len(channel_flag_strs), "invalid"));
|
||||
|
||||
mycount++;
|
||||
} else {
|
||||
stream->write_function(stream, "[s%dc%d][%d:%d] flag %d(%s) OFF \n",
|
||||
fchan->span_id, fchan->chan_id,
|
||||
fchan->physical_span_id, fchan->physical_chan_id,
|
||||
flagval, ftdm_val2str(flag, channel_flag_strs, ftdm_array_len(channel_flag_strs), "invalid"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ftdm_iterator_free(citer);
|
||||
|
||||
} else {
|
||||
for (i = hashtable_first(globals.span_hash); i; i = hashtable_next(i)) {
|
||||
hashtable_this(i, &key, NULL, &val);
|
||||
if (!key || !val) {
|
||||
|
@ -4319,22 +4591,86 @@ static void print_channels_by_flag(ftdm_stream_handle_t *stream, int32_t flagval
|
|||
for (curr = citer ; curr; curr = ftdm_iterator_next(curr)) {
|
||||
fchan = ftdm_iterator_current(curr);
|
||||
if (not && !ftdm_test_flag(fchan, flag)) {
|
||||
stream->write_function(stream, "[s%dc%d][%d:%d] has not flag %d\n",
|
||||
stream->write_function(stream, "[s%dc%d][%d:%d] flag !%d(!%s)\n",
|
||||
fchan->span_id, fchan->chan_id,
|
||||
fchan->physical_span_id, fchan->physical_chan_id,
|
||||
flagval);
|
||||
(*count)++;
|
||||
flagval, ftdm_val2str(flag, channel_flag_strs, ftdm_array_len(channel_flag_strs), "invalid"));
|
||||
mycount++;
|
||||
} else if (!not && ftdm_test_flag(fchan, flag)) {
|
||||
stream->write_function(stream, "[s%dc%d][%d:%d] has flag %d\n",
|
||||
stream->write_function(stream, "[s%dc%d][%d:%d] flag %d(%s)\n",
|
||||
fchan->span_id, fchan->chan_id,
|
||||
fchan->physical_span_id, fchan->physical_chan_id,
|
||||
flagval);
|
||||
(*count)++;
|
||||
flagval, ftdm_val2str(flag, channel_flag_strs, ftdm_array_len(channel_flag_strs), "invalid"));
|
||||
mycount++;
|
||||
}
|
||||
}
|
||||
ftdm_iterator_free(citer);
|
||||
}
|
||||
}
|
||||
*count = mycount;
|
||||
end:
|
||||
ftdm_mutex_unlock(globals.mutex);
|
||||
}
|
||||
|
||||
static void print_spans_by_flag(ftdm_stream_handle_t *stream, ftdm_span_t *inspan, int32_t flagval, int not, int *count)
|
||||
{
|
||||
ftdm_hash_iterator_t *i = NULL;
|
||||
ftdm_span_t *span;
|
||||
const void *key = NULL;
|
||||
void *val = NULL;
|
||||
uint32_t flag = (1 << flagval);
|
||||
int mycount = 0;
|
||||
|
||||
*count = 0;
|
||||
|
||||
ftdm_mutex_lock(globals.mutex);
|
||||
|
||||
if (inspan) {
|
||||
if (not) {
|
||||
if (!ftdm_test_flag(inspan, flag)) {
|
||||
stream->write_function(stream, "[s%d] flag !%d(!%s) ON \n",
|
||||
inspan->span_id,
|
||||
flagval, ftdm_val2str(flag, span_flag_strs, ftdm_array_len(span_flag_strs), "invalid"));
|
||||
|
||||
mycount++;
|
||||
} else {
|
||||
stream->write_function(stream, "[s%d] flag !%d(!%s) OFF \n",
|
||||
inspan->span_id,
|
||||
flagval, ftdm_val2str(flag, span_flag_strs, ftdm_array_len(span_flag_strs), "invalid"));
|
||||
}
|
||||
} else {
|
||||
if (ftdm_test_flag(inspan, flag)) {
|
||||
stream->write_function(stream, "[s%d] flag %d(%s) ON \n",
|
||||
inspan->span_id,
|
||||
flagval, ftdm_val2str(flag, span_flag_strs, ftdm_array_len(span_flag_strs), "invalid"));
|
||||
mycount++;
|
||||
} else {
|
||||
stream->write_function(stream, "[s%d] flag %d(%s) OFF \n",
|
||||
inspan->span_id,
|
||||
flagval, ftdm_val2str(flag, span_flag_strs, ftdm_array_len(span_flag_strs), "invalid"));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i = hashtable_first(globals.span_hash); i; i = hashtable_next(i)) {
|
||||
hashtable_this(i, &key, NULL, &val);
|
||||
if (!key || !val) {
|
||||
break;
|
||||
}
|
||||
span = val;
|
||||
if (not && !ftdm_test_flag(span, flag)) {
|
||||
stream->write_function(stream, "[s%d] flag !%d(!%s)\n",
|
||||
span->span_id,
|
||||
flagval, ftdm_val2str(flag, span_flag_strs, ftdm_array_len(span_flag_strs), "invalid"));
|
||||
mycount++;
|
||||
} else if (!not && ftdm_test_flag(span, flag)) {
|
||||
stream->write_function(stream, "[s%d] flag %d(%s)\n",
|
||||
span->span_id,
|
||||
flagval, ftdm_val2str(flag, span_flag_strs, ftdm_array_len(span_flag_strs), "invalid"));
|
||||
mycount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
*count = mycount;
|
||||
ftdm_mutex_unlock(globals.mutex);
|
||||
}
|
||||
|
||||
|
@ -4386,12 +4722,52 @@ static void print_core_usage(ftdm_stream_handle_t *stream)
|
|||
{
|
||||
stream->write_function(stream,
|
||||
"--------------------------------------------------------------------------------\n"
|
||||
"ftdm core state [!]<state_name> - List all channels in or not in the given state\n"
|
||||
"ftdm core flag <flag-int-value> - List all channels with the given flag value set\n"
|
||||
"ftdm core state [!]<state-name> - List all channels in or not in the given state\n"
|
||||
"ftdm core flag [!]<flag-int-value|flag-name> [<span_id|span_name>] [<chan_id>] - List all channels with the given flag value set\n"
|
||||
"ftdm core spanflag [!]<flag-int-value|flag-name> [<span_id|span_name>] - List all spans with the given span flag value set\n"
|
||||
"ftdm core calls - List all known calls to the FreeTDM core\n"
|
||||
"--------------------------------------------------------------------------------\n");
|
||||
}
|
||||
|
||||
|
||||
static unsigned long long ftdm_str2val(const char *str, val_str_t *val_str_table, ftdm_size_t array_size, unsigned long long default_val)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < array_size; i++) {
|
||||
if (!strcasecmp(val_str_table[i].str, str)) {
|
||||
return val_str_table[i].val;
|
||||
}
|
||||
}
|
||||
return default_val;
|
||||
}
|
||||
|
||||
static const char *ftdm_val2str(unsigned long long val, val_str_t *val_str_table, ftdm_size_t array_size, const char *default_str)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < array_size; i++) {
|
||||
if (val_str_table[i].val == val) {
|
||||
return val_str_table[i].str;
|
||||
}
|
||||
}
|
||||
return default_str;
|
||||
}
|
||||
|
||||
static void print_channel_flag_values(ftdm_stream_handle_t *stream)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < ftdm_array_len(channel_flag_strs); i++) {
|
||||
stream->write_function(stream, "%s\n", channel_flag_strs[i].str);
|
||||
}
|
||||
}
|
||||
|
||||
static void print_span_flag_values(ftdm_stream_handle_t *stream)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < ftdm_array_len(span_flag_strs); i++) {
|
||||
stream->write_function(stream, "%s\n", span_flag_strs[i].str);
|
||||
}
|
||||
}
|
||||
|
||||
static char *handle_core_command(const char *cmd)
|
||||
{
|
||||
char *mycmd = NULL;
|
||||
|
@ -4401,11 +4777,12 @@ static char *handle_core_command(const char *cmd)
|
|||
char *argv[10] = { 0 };
|
||||
char *state = NULL;
|
||||
char *flag = NULL;
|
||||
uint32_t flagval = 0;
|
||||
unsigned long long flagval = 0;
|
||||
uint32_t current_call_id = 0;
|
||||
ftdm_caller_data_t *calldata = NULL;
|
||||
ftdm_channel_t *fchan = NULL;
|
||||
ftdm_channel_state_t i = FTDM_CHANNEL_STATE_INVALID;
|
||||
ftdm_span_t *fspan = NULL;
|
||||
ftdm_stream_handle_t stream = { 0 };
|
||||
|
||||
FTDM_STANDARD_STREAM(stream);
|
||||
|
@ -4446,6 +4823,7 @@ static char *handle_core_command(const char *cmd)
|
|||
print_channels_by_state(&stream, i, not, &count);
|
||||
stream.write_function(&stream, "\nTotal channels %s %s: %d\n", not ? "not in state" : "in state", ftdm_channel_state2str(i), count);
|
||||
} else if (!strcasecmp(argv[0], "flag")) {
|
||||
uint32_t chan_id = 0;
|
||||
if (argc < 2) {
|
||||
stream.write_function(&stream, "core flag command requires an argument\n");
|
||||
print_core_usage(&stream);
|
||||
|
@ -4456,9 +4834,77 @@ static char *handle_core_command(const char *cmd)
|
|||
not = 1;
|
||||
flag++;
|
||||
}
|
||||
|
||||
if (isalpha(flag[0])) {
|
||||
flagval = ftdm_str2val(flag, channel_flag_strs, ftdm_array_len(channel_flag_strs), FTDM_CHANNEL_MAX_FLAG);
|
||||
if (flagval == FTDM_CHANNEL_MAX_FLAG) {
|
||||
stream.write_function(&stream, "\nInvalid channel flag value. Possible channel flags\n");
|
||||
print_channel_flag_values(&stream);
|
||||
goto done;
|
||||
}
|
||||
flagval = flagval >> 1;
|
||||
} else {
|
||||
flagval = atoi(flag);
|
||||
print_channels_by_flag(&stream, flagval, not, &count);
|
||||
}
|
||||
|
||||
/* Specific span specified */
|
||||
if (argv[2]) {
|
||||
ftdm_span_find_by_name(argv[2], &fspan);
|
||||
if (!fspan) {
|
||||
stream.write_function(&stream, "-ERR span:%s not found\n", argv[2]);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
/* Specific channel specified */
|
||||
if (argv[3]) {
|
||||
chan_id = atoi(argv[3]);
|
||||
if (chan_id >= ftdm_span_get_chan_count(fspan)) {
|
||||
stream.write_function(&stream, "-ERR invalid channel %d\n", chan_id);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
print_channels_by_flag(&stream, fspan, chan_id, flagval, not, &count);
|
||||
stream.write_function(&stream, "\nTotal channels %s %d: %d\n", not ? "without flag" : "with flag", flagval, count);
|
||||
} else if (!strcasecmp(argv[0], "spanflag")) {
|
||||
if (argc < 2) {
|
||||
stream.write_function(&stream, "core spanflag command requires an argument\n");
|
||||
print_core_usage(&stream);
|
||||
goto done;
|
||||
}
|
||||
|
||||
flag = argv[1];
|
||||
if (argv[1][0] == '!') {
|
||||
not = 1;
|
||||
flag++;
|
||||
}
|
||||
|
||||
if (isalpha(flag[0])) {
|
||||
flagval = ftdm_str2val(flag, span_flag_strs, ftdm_array_len(span_flag_strs), FTDM_SPAN_MAX_FLAG);
|
||||
if (flagval == FTDM_SPAN_MAX_FLAG) {
|
||||
stream.write_function(&stream, "\nInvalid span flag value. Possible span flags\n");
|
||||
print_span_flag_values(&stream);
|
||||
goto done;
|
||||
}
|
||||
flagval = flagval >> 1;
|
||||
} else {
|
||||
flagval = atoi(flag);
|
||||
}
|
||||
|
||||
/* Specific span specified */
|
||||
if (argv[2]) {
|
||||
ftdm_span_find_by_name(argv[2], &fspan);
|
||||
if (!fspan) {
|
||||
stream.write_function(&stream, "-ERR span:%s not found\n", argv[2]);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
print_spans_by_flag(&stream, fspan, flagval, not, &count);
|
||||
if (!fspan) {
|
||||
stream.write_function(&stream, "\nTotal spans %s %d: %d\n", not ? "without flag" : "with flag", flagval, count);
|
||||
}
|
||||
} else if (!strcasecmp(argv[0], "calls")) {
|
||||
ftdm_mutex_lock(globals.call_id_mutex);
|
||||
current_call_id = globals.last_call_id;
|
||||
|
@ -4923,14 +5369,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);
|
||||
|
@ -5298,16 +5745,68 @@ FT_DECLARE(ftdm_status_t) ftdm_configure_span_signaling(ftdm_span_t *span, const
|
|||
return status;
|
||||
}
|
||||
|
||||
static void *ftdm_span_service_events(ftdm_thread_t *me, void *obj)
|
||||
{
|
||||
int i;
|
||||
unsigned waitms;
|
||||
ftdm_event_t *event;
|
||||
ftdm_status_t status = FTDM_SUCCESS;
|
||||
ftdm_span_t *span = (ftdm_span_t*) obj;
|
||||
short *poll_events = ftdm_malloc(sizeof(short) * span->chan_count);
|
||||
|
||||
memset(poll_events, 0, sizeof(short) * span->chan_count);
|
||||
|
||||
for(i = 1; i <= span->chan_count; i++) {
|
||||
poll_events[i] |= FTDM_EVENTS;
|
||||
}
|
||||
|
||||
while (ftdm_running() && !(ftdm_test_flag(span, FTDM_SPAN_STOP_THREAD))) {
|
||||
waitms = 1000;
|
||||
status = ftdm_span_poll_event(span, waitms, poll_events);
|
||||
switch (status) {
|
||||
case FTDM_FAIL:
|
||||
ftdm_log(FTDM_LOG_CRIT, "%s:Failed to poll span for events\n", span->name);
|
||||
break;
|
||||
case FTDM_TIMEOUT:
|
||||
break;
|
||||
case FTDM_SUCCESS:
|
||||
/* Check if there are any channels that have events available */
|
||||
while (ftdm_span_next_event(span, &event) == FTDM_SUCCESS);
|
||||
break;
|
||||
default:
|
||||
ftdm_log(FTDM_LOG_CRIT, "%s:Unhandled IO event\n", span->name);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FT_DECLARE(ftdm_status_t) ftdm_span_register_signal_cb(ftdm_span_t *span, fio_signal_cb_t sig_cb)
|
||||
{
|
||||
span->signal_cb = sig_cb;
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
FT_DECLARE(ftdm_status_t) ftdm_span_start(ftdm_span_t *span)
|
||||
{
|
||||
ftdm_status_t status = FTDM_FAIL;
|
||||
|
||||
ftdm_mutex_lock(span->mutex);
|
||||
|
||||
if (ftdm_test_flag(span, FTDM_SPAN_STARTED)) {
|
||||
status = FTDM_EINVAL;
|
||||
goto done;
|
||||
}
|
||||
if (span->signal_type == FTDM_SIGTYPE_NONE) {
|
||||
/* If there is no signalling component, start a thread to poll events */
|
||||
status = ftdm_thread_create_detached(ftdm_span_service_events, span);
|
||||
if (status != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_CRIT,"Failed to start span event monitor thread!\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
//ftdm_report_initial_channels_alarms(span);
|
||||
ftdm_set_flag_locked(span, FTDM_SPAN_STARTED);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!span->start) {
|
||||
status = FTDM_ENOSYS;
|
||||
|
@ -5331,7 +5830,6 @@ FT_DECLARE(ftdm_status_t) ftdm_span_start(ftdm_span_t *span)
|
|||
if (status == FTDM_SUCCESS) {
|
||||
ftdm_set_flag_locked(span, FTDM_SPAN_STARTED);
|
||||
}
|
||||
|
||||
done:
|
||||
ftdm_mutex_unlock(span->mutex);
|
||||
return status;
|
||||
|
@ -5516,8 +6014,10 @@ FT_DECLARE(ftdm_status_t) ftdm_group_create(ftdm_group_t **group, const char *na
|
|||
|
||||
static ftdm_status_t ftdm_span_trigger_signal(const ftdm_span_t *span, ftdm_sigmsg_t *sigmsg)
|
||||
{
|
||||
ftdm_status_t status = span->signal_cb(sigmsg);
|
||||
return status;
|
||||
if (!span->signal_cb) {
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
return span->signal_cb(sigmsg);
|
||||
}
|
||||
|
||||
static ftdm_status_t ftdm_span_queue_signal(const ftdm_span_t *span, ftdm_sigmsg_t *sigmsg)
|
||||
|
@ -5551,7 +6051,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));
|
||||
|
@ -5682,28 +6182,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;
|
||||
}
|
||||
}
|
||||
|
@ -5712,7 +6216,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
|
||||
|
@ -5814,8 +6322,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;
|
||||
|
@ -5824,10 +6332,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;
|
||||
|
|
|
@ -48,9 +48,26 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_complete_state(const char *file, const c
|
|||
ftdm_time_t diff = 0;
|
||||
ftdm_channel_state_t state = fchan->state;
|
||||
|
||||
#if 0
|
||||
/* I could not perform this sanity check without more disruptive changes. Ideally we should check here if the signaling module completing the state
|
||||
executed a state processor (called ftdm_channel_advance_states() which call fchan->span->state_processor(fchan)) for the state. That is just a
|
||||
sanity check, as in the past we had at least one bug where the signaling module set the state and then accidentally changed the state to a new one
|
||||
without calling ftdm_channel_advance_states(), meaning the state processor for the first state was not executed and that lead to unexpected behavior.
|
||||
|
||||
If we want to be able to perform this kind of sanity check it would be nice to add a new state status (FTDM_STATE_STATUS_PROCESSING), the function
|
||||
ftdm_channel_advance_states() would set the state_status to PROCESSING and then the check below for STATUS_NEW would be valid. Currently is not
|
||||
valid because the signaling module may be completing the state at the end of the state_processor callback and therefore the state will still be
|
||||
in STATUS_NEW, and is perfectly valid ... */
|
||||
|
||||
if (fchan->state_status == FTDM_STATE_STATUS_NEW) {
|
||||
ftdm_log_chan_ex(fchan, file, func, line, FTDM_LOG_LEVEL_CRIT,
|
||||
"Asking to complete state change from %s to %s in %llums, but the state is still unprocessed (this might be a bug!)\n",
|
||||
ftdm_channel_state2str(fchan->last_state), ftdm_channel_state2str(state), diff);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (fchan->state_status == FTDM_STATE_STATUS_COMPLETED) {
|
||||
ftdm_assert_return(!ftdm_test_flag(fchan, FTDM_CHANNEL_STATE_CHANGE), FTDM_FAIL,
|
||||
"State change flag set but state is not completed\n");
|
||||
ftdm_assert_return(!ftdm_test_flag(fchan, FTDM_CHANNEL_STATE_CHANGE), FTDM_FAIL, "State change flag set but state is already completed\n");
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -87,6 +104,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 +280,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 +374,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;
|
||||
|
|
|
@ -288,6 +288,7 @@ typedef struct sngisdn_span_data {
|
|||
uint8_t force_sending_complete;
|
||||
uint8_t cid_name_method;
|
||||
uint8_t send_cid_name;
|
||||
uint8_t send_connect_ack;
|
||||
|
||||
int32_t timer_t301;
|
||||
int32_t timer_t302;
|
||||
|
@ -305,7 +306,6 @@ typedef struct sngisdn_span_data {
|
|||
int32_t timer_t318;
|
||||
int32_t timer_t319;
|
||||
int32_t timer_t322;
|
||||
|
||||
char* local_numbers[SNGISDN_NUM_LOCAL_NUMBERS];
|
||||
ftdm_timer_id_t timers[SNGISDN_NUM_SPAN_TIMERS];
|
||||
ftdm_sched_t *sched;
|
||||
|
|
|
@ -433,6 +433,7 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_
|
|||
|
||||
signal_data->cid_name_method = SNGISDN_CID_NAME_AUTO;
|
||||
signal_data->send_cid_name = SNGISDN_OPT_DEFAULT;
|
||||
signal_data->send_connect_ack = SNGISDN_OPT_DEFAULT;
|
||||
|
||||
span->default_caller_data.dnis.plan = FTDM_NPI_INVALID;
|
||||
span->default_caller_data.dnis.type = FTDM_TON_INVALID;
|
||||
|
@ -615,6 +616,8 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_
|
|||
parse_timer(val, &signal_data->timer_t322);
|
||||
} else if (!strcasecmp(var, "trunkgroup")) {
|
||||
/* Do nothing, we already parsed this parameter */
|
||||
} else if (!strcasecmp(var, "send-connect-ack")) {
|
||||
parse_yesno(var, val, &signal_data->send_connect_ack);
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_WARNING, "Ignoring unknown parameter %s\n", ftdm_parameters[paramindex].var);
|
||||
}
|
||||
|
|
|
@ -738,6 +738,14 @@ ftdm_status_t sngisdn_stack_cfg_q931_dlsap(ftdm_span_t *span)
|
|||
}
|
||||
}
|
||||
|
||||
if (signal_data->send_connect_ack != SNGISDN_OPT_DEFAULT) {
|
||||
if (signal_data->send_connect_ack == SNGISDN_OPT_TRUE) {
|
||||
cfg.t.cfg.s.inDLSAP.ackOpt = TRUE;
|
||||
} else {
|
||||
cfg.t.cfg.s.inDLSAP.ackOpt = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Override the restart options if user selected that option */
|
||||
if (signal_data->restart_opt != SNGISDN_OPT_DEFAULT) {
|
||||
if (signal_data->restart_opt == SNGISDN_OPT_TRUE) {
|
||||
|
|
|
@ -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,
|
||||
|
@ -207,30 +209,22 @@ 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;
|
||||
} /* 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);
|
||||
if(SNG_SS7_OPR_MODE_M2UA_SG == g_ftdm_operating_mode){
|
||||
if(FTDM_SUCCESS != ftmod_ss7_m2ua_init()){
|
||||
ftdm_log (FTDM_LOG_ERROR, "ftmod_ss7_m2ua_init FAILED \n");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
/* set the SNGSS7_CONFIGURED flag */
|
||||
g_ftdm_sngss7_data.cfg.relay[x].flags |= SNGSS7_CONFIGURED;
|
||||
} /* if !SNGSS7_CONFIGURED */
|
||||
x++;
|
||||
} /* while (x < (MAX_RELAY_CHANNELS)) */
|
||||
g_ftdm_sngss7_data.gen_config = SNG_GEN_CFG_STATUS_DONE;
|
||||
|
||||
} /* if (!(g_ftdm_sngss7_data.gen_config)) */
|
||||
|
||||
|
||||
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,6 +266,8 @@ int ft_to_sngss7_cfg_all(void)
|
|||
x++;
|
||||
} /* while (x < (MAX_MTP_LINKS+1)) */
|
||||
|
||||
/* no configs above mtp2 for relay */
|
||||
if (g_ftdm_sngss7_data.cfg.procId == 1) {
|
||||
x = 1;
|
||||
while (x < (MAX_MTP_LINKS)) {
|
||||
/* check if this link has been configured already */
|
||||
|
@ -293,6 +289,8 @@ int ft_to_sngss7_cfg_all(void)
|
|||
x++;
|
||||
} /* while (x < (MAX_MTP_LINKS+1)) */
|
||||
|
||||
/* in M2UA_SG mode there will not be any MTP3 layer */
|
||||
if(SNG_SS7_OPR_MODE_M2UA_SG != g_ftdm_operating_mode){
|
||||
x = 1;
|
||||
while (x < (MAX_NSAPS)) {
|
||||
/* check if this link has been configured already */
|
||||
|
@ -321,7 +319,10 @@ int ft_to_sngss7_cfg_all(void)
|
|||
|
||||
x++;
|
||||
} /* while (x < (MAX_NSAPS)) */
|
||||
}
|
||||
|
||||
/* in M2UA_SG mode there will not be any MTP3 layer */
|
||||
if(SNG_SS7_OPR_MODE_M2UA_SG != g_ftdm_operating_mode){
|
||||
x = 1;
|
||||
while (x < (MAX_MTP_LINKSETS+1)) {
|
||||
/* check if this link has been configured already */
|
||||
|
@ -341,7 +342,10 @@ int ft_to_sngss7_cfg_all(void)
|
|||
|
||||
x++;
|
||||
} /* while (x < (MAX_MTP_LINKSETS+1)) */
|
||||
}
|
||||
|
||||
/* in M2UA_SG mode there will not be any MTP3 layer */
|
||||
if(SNG_SS7_OPR_MODE_M2UA_SG != g_ftdm_operating_mode){
|
||||
x = 1;
|
||||
while (x < (MAX_MTP_ROUTES+1)) {
|
||||
/* check if this link has been configured already */
|
||||
|
@ -361,6 +365,7 @@ int ft_to_sngss7_cfg_all(void)
|
|||
|
||||
x++;
|
||||
} /* while (x < (MAX_MTP_ROUTES+1)) */
|
||||
}
|
||||
|
||||
x = 1;
|
||||
while (x < (MAX_ISAPS)) {
|
||||
|
@ -408,6 +413,11 @@ int ft_to_sngss7_cfg_all(void)
|
|||
|
||||
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))) {
|
||||
|
@ -425,6 +435,33 @@ int ft_to_sngss7_cfg_all(void)
|
|||
|
||||
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("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(SNG_SS7_OPR_MODE_M2UA_SG == g_ftdm_operating_mode){
|
||||
return ftmod_ss7_m2ua_cfg();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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 ******************************************************************/
|
||||
|
@ -104,6 +76,7 @@ int ft_to_sngss7_activate_all(void)
|
|||
x++;
|
||||
} /* while (x < (MAX_ISAPS)) */
|
||||
|
||||
if(SNG_SS7_OPR_MODE_M2UA_SG != g_ftdm_operating_mode){
|
||||
x = 1;
|
||||
while (x < (MAX_NSAPS)) {
|
||||
/* check if this link has already been actived */
|
||||
|
@ -145,6 +118,11 @@ int ft_to_sngss7_activate_all(void)
|
|||
x++;
|
||||
} /* while (x < (MAX_MTP_LINKSETS+1)) */
|
||||
}
|
||||
}
|
||||
|
||||
if(SNG_SS7_OPR_MODE_M2UA_SG == g_ftdm_operating_mode){
|
||||
return ftmod_ss7_m2ua_start();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -779,7 +757,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 */
|
||||
|
||||
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 +796,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 */
|
||||
|
||||
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 +840,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 +868,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 */
|
||||
|
||||
if (wait == FTDM_TRUE) {
|
||||
return (sng_cntrl_isup(&pst, &cntrl));
|
||||
} else {
|
||||
return (sng_cntrl_isup_nowait(&pst, &cntrl));
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
* Contributors:
|
||||
*
|
||||
* Ricardo Barroetaveña <rbarroetavena@anura.com.ar>
|
||||
* James Zhang <jzhang@sangoma.com>
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -87,6 +88,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 +100,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,12 +123,25 @@ 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 */
|
||||
}
|
||||
|
||||
sngss7_clear_ckt_flag(sngss7_info, FLAG_INR_TX);
|
||||
sngss7_clear_ckt_flag(sngss7_info, FLAG_INR_SENT);
|
||||
sngss7_clear_ckt_flag(sngss7_info, FLAG_INR_RX);
|
||||
sngss7_clear_ckt_flag(sngss7_info, FLAG_INR_RX_DN);
|
||||
sngss7_clear_ckt_flag(sngss7_info, FLAG_INF_TX);
|
||||
sngss7_clear_ckt_flag(sngss7_info, FLAG_INF_SENT);
|
||||
sngss7_clear_ckt_flag(sngss7_info, FLAG_INF_RX);
|
||||
sngss7_clear_ckt_flag(sngss7_info, FLAG_INF_RX_DN);
|
||||
sngss7_clear_ckt_flag(sngss7_info, FLAG_FULL_NUMBER);
|
||||
|
||||
/* check whether the ftdm channel is in a state to accept a call */
|
||||
switch (ftdmchan->state) {
|
||||
/**************************************************************************/
|
||||
|
@ -167,6 +185,12 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
|
|||
/* fill in ANI */
|
||||
ftdm_set_string(ftdmchan->caller_data.ani.digits, ftdmchan->caller_data.cid_num.digits);
|
||||
}
|
||||
else {
|
||||
if (g_ftdm_sngss7_data.cfg.force_inr) {
|
||||
sngss7_set_ckt_flag(sngss7_info, FLAG_INR_TX);
|
||||
sngss7_clear_ckt_flag(sngss7_info, FLAG_INR_SENT);
|
||||
}
|
||||
}
|
||||
|
||||
if (siConEvnt->cgPtyNum.scrnInd.pres) {
|
||||
/* fill in the screening indication value */
|
||||
|
@ -178,6 +202,11 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
|
|||
ftdmchan->caller_data.pres = siConEvnt->cgPtyNum.presRest.val;
|
||||
}
|
||||
} else {
|
||||
if (g_ftdm_sngss7_data.cfg.force_inr) {
|
||||
sngss7_set_ckt_flag(sngss7_info, FLAG_INR_TX);
|
||||
sngss7_clear_ckt_flag(sngss7_info, FLAG_INR_SENT);
|
||||
}
|
||||
|
||||
SS7_INFO_CHAN(ftdmchan,"No Calling party (ANI) information in IAM!%s\n", " ");
|
||||
}
|
||||
|
||||
|
@ -192,12 +221,16 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
|
|||
} else {
|
||||
SS7_INFO_CHAN(ftdmchan,"No Called party (DNIS) information in IAM!%s\n", " ");
|
||||
}
|
||||
|
||||
copy_NatureOfConnection_from_sngss7(ftdmchan, &siConEvnt->natConInd);
|
||||
copy_fwdCallInd_hex_from_sngss7(ftdmchan, &siConEvnt->fwdCallInd);
|
||||
copy_access_transport_from_sngss7(ftdmchan, &siConEvnt->accTrnspt);
|
||||
copy_ocn_from_sngss7(ftdmchan, &siConEvnt->origCdNum);
|
||||
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 +246,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 +277,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) {
|
||||
|
@ -309,23 +340,25 @@ handle_glare:
|
|||
/* setup the hangup cause */
|
||||
ftdmchan->caller_data.hangup_cause = 34; /* Circuit Congrestion */
|
||||
|
||||
/* this is a remote hangup request */
|
||||
sngss7_set_ckt_flag(sngss7_info, FLAG_REMOTE_REL);
|
||||
|
||||
/* move the state of the channel to Terminating to end the call */
|
||||
/* move the state of the channel to Terminating to end the call
|
||||
in TERMINATING state, the release cause is set to REMOTE_REL
|
||||
in any means. So we don't have to set the release reason here.
|
||||
*/
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
|
||||
} /* if (!(sngss7_test_ckt_flag(sngss7_info, FLAG_GLARE))) */
|
||||
}
|
||||
break;
|
||||
/**************************************************************************/
|
||||
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);
|
||||
/* 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);
|
||||
|
||||
/* move the state of the channel to RESTART to force a reset */
|
||||
/* go to RESTART */
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
|
||||
|
||||
}
|
||||
break;
|
||||
/**************************************************************************/
|
||||
} /* switch (ftdmchan->state) */
|
||||
|
@ -345,6 +378,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)) {
|
||||
SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
|
||||
|
@ -389,11 +424,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);
|
||||
}
|
||||
break;
|
||||
/**********************************************************************/
|
||||
} /* switch (ftdmchan->state) */
|
||||
|
@ -422,10 +460,26 @@ ftdm_status_t handle_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circ
|
|||
/**************************************************************************/
|
||||
case (INFORMATION):
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx INF\n", sngss7_info->circuit->cic);
|
||||
|
||||
SS7_DEBUG_CHAN (ftdmchan, "Cancelling T.39 timer %s\n", " ");
|
||||
/* check if t39 is active */
|
||||
if (sngss7_info->t39.hb_timer_id) {
|
||||
ftdm_sched_cancel_timer (sngss7_info->t39.sched, sngss7_info->t39.hb_timer_id);
|
||||
SS7_DEBUG_CHAN (ftdmchan, "T.39 timer has been cancelled upon receiving INF message %s\n", " ");
|
||||
}
|
||||
|
||||
sngss7_set_ckt_flag(sngss7_info, FLAG_INF_RX_DN);
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_IDLE);
|
||||
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case (INFORMATREQ):
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx INR\n", sngss7_info->circuit->cic);
|
||||
|
||||
ft_to_sngss7_inf(ftdmchan, siCnStEvnt);
|
||||
|
||||
sngss7_set_ckt_flag(sngss7_info, FLAG_INR_RX);
|
||||
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case (SUBSADDR):
|
||||
|
@ -600,6 +654,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)) {
|
||||
SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
|
||||
|
@ -651,10 +707,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);
|
||||
}
|
||||
|
||||
break;
|
||||
/**************************************************************************/
|
||||
|
@ -675,6 +734,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)) {
|
||||
SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
|
||||
|
@ -750,6 +811,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 +837,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 */
|
||||
/* go to RESTART */
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
|
||||
}
|
||||
break;
|
||||
/**************************************************************************/
|
||||
} /* switch (ftdmchan->state) */
|
||||
|
@ -797,6 +866,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)) {
|
||||
SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
|
||||
|
@ -848,6 +919,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)) {
|
||||
SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
|
||||
|
@ -875,6 +948,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)) {
|
||||
SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
|
||||
|
@ -902,6 +977,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)) {
|
||||
SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
|
||||
|
@ -929,6 +1006,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)) {
|
||||
SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
|
||||
|
@ -956,6 +1035,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)) {
|
||||
SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
|
||||
|
@ -983,6 +1064,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)) {
|
||||
SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
|
||||
|
@ -1007,6 +1090,8 @@ ftdm_status_t handle_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
|
|||
{
|
||||
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)) {
|
||||
SS7_ERROR("[CIC:%d]Rx %s but circuit is not active yet, skipping!\n",
|
||||
|
@ -1098,11 +1183,12 @@ ftdm_status_t handle_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
|
|||
break;
|
||||
/**************************************************************************/
|
||||
case SIT_STA_CGBRSP: /* mntc. oriented CGB response */
|
||||
/*handle_cgb_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt);*/
|
||||
SS7_INFO(" Rx CGBA \n");
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case SIT_STA_CGURSP: /* mntc. oriented CGU response */
|
||||
/*SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType));*/
|
||||
SS7_INFO(" Rx CGUA \n");
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case SIT_STA_GRSREQ: /* circuit group reset request */
|
||||
|
@ -1207,6 +1293,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) {
|
||||
SS7_ERROR("[CIC:%d]Rx %s on non-voice CIC\n",
|
||||
|
@ -1235,6 +1323,7 @@ ftdm_status_t handle_reattempt(uint32_t suInstId, uint32_t spInstId, uint32_t ci
|
|||
/* the glare flag is already up so it was caught ... do nothing */
|
||||
SS7_DEBUG_CHAN(ftdmchan, "Glare flag is already up...nothing to do!%s\n", " ");
|
||||
} else {
|
||||
int bHangup = 0;
|
||||
SS7_DEBUG_CHAN(ftdmchan, "Glare flag is not up yet...indicating glare from reattempt!%s\n", " ");
|
||||
/* glare, throw the flag */
|
||||
sngss7_set_ckt_flag(sngss7_info, FLAG_GLARE);
|
||||
|
@ -1242,15 +1331,46 @@ ftdm_status_t handle_reattempt(uint32_t suInstId, uint32_t spInstId, uint32_t ci
|
|||
/* clear any existing glare data from the channel */
|
||||
memset(&sngss7_info->glare, 0x0, sizeof(sngss7_glare_data_t));
|
||||
|
||||
if (g_ftdm_sngss7_data.cfg.glareResolution == SNGSS7_GLARE_DOWN) {
|
||||
/* If I'm in DOWN mode, I will always hangup my call. */
|
||||
bHangup = 1;
|
||||
}
|
||||
else if (g_ftdm_sngss7_data.cfg.glareResolution == SNGSS7_GLARE_PC) {
|
||||
/* I'm in PointCode mode.
|
||||
Case 1: My point code is higher than the other side.
|
||||
If the CIC number is even, I'm trying to control.
|
||||
If the CIC number is odd, I'll hangup my call and back off.
|
||||
Case 2: My point code is lower than the other side.
|
||||
If the CIC number is odd, I'm trying to control.
|
||||
If the CIC number is even, I'll hangup my call and back off.
|
||||
*/
|
||||
if( g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId].spc > g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId].dpc )
|
||||
{
|
||||
if ((sngss7_info->circuit->cic % 2) == 1 ) {
|
||||
bHangup = 1;
|
||||
}
|
||||
} else {
|
||||
if( (sngss7_info->circuit->cic % 2) == 0 ) {
|
||||
bHangup = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* If I'm in CONTROL mode, I will not hangup my call. */
|
||||
bHangup = 0;
|
||||
}
|
||||
|
||||
if (bHangup) {
|
||||
/* setup the hangup cause */
|
||||
ftdmchan->caller_data.hangup_cause = 34; /* Circuit Congrestion */
|
||||
|
||||
/* this is a remote hangup request */
|
||||
sngss7_set_ckt_flag(sngss7_info, FLAG_REMOTE_REL);
|
||||
|
||||
/* move the state of the channel to Terminating to end the call */
|
||||
/* move the state of the channel to Terminating to end the call
|
||||
in TERMINATING state, the release cause is set to REMOTE_REL
|
||||
in any means. So we don't have to set the release reason here.
|
||||
*/
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
|
||||
}
|
||||
}
|
||||
|
||||
/* unlock the channel again before we exit */
|
||||
ftdm_mutex_unlock(ftdmchan->mutex);
|
||||
|
@ -1269,6 +1389,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;
|
||||
|
||||
|
@ -1334,6 +1456,8 @@ ftdm_status_t handle_resume(uint32_t suInstId, uint32_t spInstId, uint32_t circu
|
|||
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;
|
||||
|
||||
|
@ -1398,6 +1522,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) {
|
||||
SS7_ERROR("[CIC:%d]Rx %s on non-voice CIC\n",
|
||||
|
@ -1453,6 +1579,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) {
|
||||
SS7_ERROR("[CIC:%d]Rx %s on non-voice CIC\n",
|
||||
|
@ -1498,6 +1626,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) {
|
||||
SS7_ERROR("[CIC:%d]Rx %s on non-voice CIC\n",
|
||||
|
@ -1566,6 +1696,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) {
|
||||
SS7_ERROR("[CIC:%d]Rx %s on non-voice CIC\n",
|
||||
|
@ -1597,6 +1729,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);
|
||||
|
@ -1616,6 +1749,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) {
|
||||
SS7_ERROR("[CIC:%d]Rx %s on non-voice CIC\n",
|
||||
|
@ -1657,6 +1792,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) {
|
||||
SS7_ERROR("[CIC:%d]Rx %s on non-voice CIC\n",
|
||||
|
@ -1745,6 +1882,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) {
|
||||
SS7_ERROR("[CIC:%d]Rx %s on non-voice CIC\n",
|
||||
|
@ -1784,6 +1923,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;
|
||||
/**************************************************************************/
|
||||
|
@ -1804,6 +1944,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) {
|
||||
SS7_ERROR("[CIC:%d]Rx %s on non-voice CIC\n",
|
||||
|
@ -1862,6 +2004,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) {
|
||||
SS7_ERROR("[CIC:%d]Rx %s on non-voice CIC\n",
|
||||
|
@ -1917,7 +2061,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;
|
||||
/**********************************************************************/
|
||||
|
@ -1952,6 +2096,8 @@ ftdm_status_t handle_grs_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ
|
|||
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) {
|
||||
SS7_ERROR("[CIC:%d]Rx %s on non-voice CIC\n",
|
||||
|
@ -2009,6 +2155,8 @@ ftdm_status_t handle_grs_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circ
|
|||
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) {
|
||||
SS7_ERROR("[CIC:%d]Rx %s on non-voice CIC\n",
|
||||
|
@ -2073,6 +2221,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) {
|
||||
SS7_ERROR("[CIC:%d]Rx %s on non-voice CIC\n",
|
||||
|
@ -2123,6 +2273,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) {
|
||||
SS7_ERROR("[CIC:%d]Rx %s on non-voice CIC\n",
|
||||
|
@ -2177,6 +2329,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 +2368,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 +2382,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 */
|
||||
|
@ -2257,6 +2413,9 @@ ftdm_status_t handle_cgb_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ
|
|||
int byte = 0;
|
||||
int bit = 0;
|
||||
int x;
|
||||
int loop_range=0;
|
||||
|
||||
ftdm_running_return(FTDM_FAIL);
|
||||
|
||||
memset(&status[0], '\0', sizeof(status));
|
||||
|
||||
|
@ -2321,27 +2480,17 @@ ftdm_status_t handle_cgb_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ
|
|||
}
|
||||
|
||||
/* loop over the cics starting from circuit until range+1 */
|
||||
for (x = circuit; x < (circuit + range + 1); x++) {
|
||||
/* confirm this is a voice channel */
|
||||
if (g_ftdm_sngss7_data.cfg.isupCkt[x].type != SNG_CKT_VOICE) continue;
|
||||
|
||||
/* grab the circuit in question */
|
||||
loop_range = circuit + range + 1;
|
||||
x = circuit;
|
||||
while( x < loop_range ) {
|
||||
if (g_ftdm_sngss7_data.cfg.isupCkt[x].type != SNG_CKT_VOICE) {
|
||||
loop_range++;
|
||||
}
|
||||
else {
|
||||
if (extract_chan_data(x, &sngss7_info, &ftdmchan)) {
|
||||
SS7_ERROR("Failed to extract channel data for circuit = %d!\n", x);
|
||||
break;
|
||||
}
|
||||
|
||||
/* lock the channel */
|
||||
} else {
|
||||
ftdm_mutex_lock(ftdmchan->mutex);
|
||||
|
||||
#if 0
|
||||
SS7_ERROR("KONRAD -> circuit=%d, byte=%d, bit=%d, status[byte]=%d, math=%d\n",
|
||||
x,
|
||||
byte,
|
||||
bit,
|
||||
status[byte],
|
||||
(status[byte] & (1 << bit)));
|
||||
#endif
|
||||
if (status[byte] & (1 << bit)) {
|
||||
switch (blockType) {
|
||||
/**********************************************************************/
|
||||
|
@ -2359,12 +2508,14 @@ ftdm_status_t handle_cgb_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ
|
|||
default:
|
||||
break;
|
||||
/**********************************************************************/
|
||||
} /* switch (blockType) */
|
||||
}
|
||||
}
|
||||
|
||||
/* bring the sig status down */
|
||||
sngss7_set_sig_status(sngss7_info, FTDM_SIG_STATE_DOWN);
|
||||
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED);
|
||||
|
||||
/* unlock the channel again before we exit */
|
||||
ftdm_mutex_unlock(ftdmchan->mutex);
|
||||
|
||||
|
@ -2374,8 +2525,11 @@ ftdm_status_t handle_cgb_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ
|
|||
byte++;
|
||||
bit = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
x++;
|
||||
}
|
||||
|
||||
} /* for (x = circuit; x < (circuit + range + 1); x++) */
|
||||
|
||||
/* get the ftdmchan and ss7_chan_data from the circuit */
|
||||
if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
|
||||
|
@ -2403,8 +2557,11 @@ ftdm_status_t handle_cgu_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ
|
|||
int byte = 0;
|
||||
int bit = 0;
|
||||
int x;
|
||||
int loop_range=0;
|
||||
ftdm_sigmsg_t sigev;
|
||||
|
||||
ftdm_running_return(FTDM_FAIL);
|
||||
|
||||
memset(&sigev, 0, sizeof (sigev));
|
||||
memset(&status[0], '\0', sizeof(status));
|
||||
|
||||
|
@ -2470,15 +2627,16 @@ ftdm_status_t handle_cgu_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ
|
|||
}
|
||||
|
||||
/* loop over the cics starting from circuit until range+1 */
|
||||
for (x = circuit; x < (circuit + range + 1); x++) {
|
||||
if (g_ftdm_sngss7_data.cfg.isupCkt[x].type != SNG_CKT_VOICE) continue;
|
||||
/* grab the circuit in question */
|
||||
loop_range = circuit + range + 1;
|
||||
x = circuit;
|
||||
while( x < loop_range ) {
|
||||
if (g_ftdm_sngss7_data.cfg.isupCkt[x].type != SNG_CKT_VOICE) {
|
||||
loop_range++;
|
||||
} else {
|
||||
if (extract_chan_data(x, &sngss7_info, &ftdmchan)) {
|
||||
SS7_ERROR("Failed to extract channel data for circuit = %d!\n", x);
|
||||
break;
|
||||
}
|
||||
|
||||
/* lock the channel */
|
||||
else {
|
||||
ftdm_mutex_lock(ftdmchan->mutex);
|
||||
|
||||
if (status[byte] & (1 << bit)) {
|
||||
|
@ -2508,9 +2666,11 @@ ftdm_status_t handle_cgu_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ
|
|||
sigev.channel = ftdmchan;
|
||||
|
||||
/* bring the sig status down */
|
||||
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_set_state(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED);
|
||||
ftdm_mutex_unlock(ftdmchan->mutex);
|
||||
|
||||
/* update the bit and byte counter*/
|
||||
|
@ -2519,8 +2679,10 @@ ftdm_status_t handle_cgu_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ
|
|||
byte++;
|
||||
bit = 0;
|
||||
}
|
||||
|
||||
} /* for (x = circuit; x < (circuit + range + 1); x++) */
|
||||
}
|
||||
}
|
||||
x++;
|
||||
}
|
||||
|
||||
/* get the ftdmchan and ss7_chan_data from the circuit */
|
||||
if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
|
||||
|
@ -2542,6 +2704,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) {
|
||||
SS7_ERROR("[CIC:%d]Rx %s on non-voice CIC\n",
|
||||
|
|
|
@ -81,6 +81,7 @@ void sngss7_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiCo
|
|||
|
||||
/* initalize the sngss7_event */
|
||||
sngss7_event = ftdm_malloc(sizeof(*sngss7_event));
|
||||
|
||||
if (sngss7_event == NULL) {
|
||||
SS7_ERROR("Failed to allocate memory for sngss7_event!\n");
|
||||
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
|
|
|
@ -114,6 +114,7 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta)
|
|||
{
|
||||
char buf[50];
|
||||
int x = 1;
|
||||
int log_level = FTDM_LOG_LEVEL_DEBUG;
|
||||
|
||||
memset(buf, '\0', sizeof(buf));
|
||||
|
||||
|
@ -158,11 +159,22 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta)
|
|||
break;
|
||||
case (LCM_CAUSE_UNKNOWN):
|
||||
default:
|
||||
ftdm_log(FTDM_LOG_DEBUG,"[MTP2]%s cause:%s event:%s\n",
|
||||
{
|
||||
if ((LSD_EVENT_ALIGN_LOST == sta->t.usta.alarm.event) ||
|
||||
(LSD_EVENT_PROT_ST_DN == sta->t.usta.alarm.event)) {
|
||||
log_level = FTDM_LOG_LEVEL_WARNING;
|
||||
} else if ((LSD_EVENT_LINK_ALIGNED == sta->t.usta.alarm.event) ||
|
||||
(LSD_EVENT_PROT_ST_UP == sta->t.usta.alarm.event)){
|
||||
log_level = FTDM_LOG_LEVEL_INFO;
|
||||
} else {
|
||||
log_level = FTDM_LOG_LEVEL_WARNING;
|
||||
}
|
||||
ftdm_log(FTDM_PRE, log_level,"[MTP2]%s cause:%s event:%s\n",
|
||||
buf,
|
||||
DECODE_LCM_CAUSE(sta->t.usta.alarm.cause),
|
||||
DECODE_LSD_EVENT(sta->t.usta.alarm.event));
|
||||
break;
|
||||
}
|
||||
/******************************************************************/
|
||||
} /* switch (sta->t.usta.alarm.cause) */
|
||||
break;
|
||||
|
@ -184,7 +196,7 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta)
|
|||
sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtp2Link[x].name);
|
||||
}
|
||||
|
||||
ftdm_log(FTDM_LOG_ERROR,"[MTP2]%s %s : %s\n",
|
||||
ftdm_log(FTDM_LOG_WARNING,"[MTP2]%s %s : %s\n",
|
||||
buf,
|
||||
DECODE_LSD_EVENT(sta->t.usta.alarm.event),
|
||||
DECODE_LSD_CAUSE(sta->t.usta.alarm.cause));
|
||||
|
@ -207,7 +219,7 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta)
|
|||
sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtp2Link[x].name);
|
||||
}
|
||||
|
||||
ftdm_log(FTDM_LOG_DEBUG,"[MTP2]%s %s : %s\n",
|
||||
ftdm_log(FTDM_LOG_WARNING,"[MTP2]%s %s : %s\n",
|
||||
buf,
|
||||
DECODE_LSD_EVENT(sta->t.usta.alarm.event),
|
||||
DECODE_DISC_REASON(sta->t.usta.evntParm[1]));
|
||||
|
@ -231,7 +243,7 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta)
|
|||
sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtp2Link[x].name);
|
||||
}
|
||||
|
||||
ftdm_log(FTDM_LOG_ERROR,"[MTP2]%s %s : RTB Queue Len(%d)|Oldest BSN(%d)|Tx Queue Len(%d)|Outstanding Frames(%d)\n",
|
||||
ftdm_log(FTDM_LOG_WARNING,"[MTP2]%s %s : RTB Queue Len(%d)|Oldest BSN(%d)|Tx Queue Len(%d)|Outstanding Frames(%d)\n",
|
||||
buf,
|
||||
DECODE_LSD_EVENT(sta->t.usta.alarm.event),
|
||||
sta->t.usta.evntParm[1],
|
||||
|
@ -257,7 +269,7 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta)
|
|||
sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtp2Link[x].name);
|
||||
}
|
||||
|
||||
ftdm_log(FTDM_LOG_ERROR,"[MTP2]%s %s : RTB Queue Len(%d)\n",
|
||||
ftdm_log(FTDM_LOG_WARNING,"[MTP2]%s %s : RTB Queue Len(%d)\n",
|
||||
buf,
|
||||
DECODE_LSD_EVENT(sta->t.usta.alarm.event),
|
||||
sta->t.usta.evntParm[1]);
|
||||
|
@ -280,7 +292,7 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta)
|
|||
sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtp2Link[x].name);
|
||||
}
|
||||
|
||||
ftdm_log(FTDM_LOG_ERROR,"[MTP2]%s %s : %s\n",
|
||||
ftdm_log(FTDM_LOG_WARNING,"[MTP2]%s %s : %d\n",
|
||||
buf,
|
||||
DECODE_LSD_EVENT(sta->t.usta.alarm.event),
|
||||
DECODE_DISC_REASON(sta->t.usta.evntParm[1]));
|
||||
|
@ -288,7 +300,7 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta)
|
|||
/**********************************************************************/
|
||||
case (LCM_EVENT_UI_INV_EVT):
|
||||
case (LCM_EVENT_LI_INV_EVT):
|
||||
ftdm_log(FTDM_LOG_ERROR,"[MTP2] %s(%d) : %s(%d) : Primitive (%d)\n",
|
||||
ftdm_log(FTDM_LOG_WARNING,"[MTP2] %s(%d) : %s(%d) : Primitive (%d)\n",
|
||||
DECODE_LSD_EVENT(sta->t.usta.alarm.event),
|
||||
sta->t.usta.alarm.event,
|
||||
DECODE_LCM_CAUSE(sta->t.usta.alarm.cause),
|
||||
|
@ -302,14 +314,14 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta)
|
|||
/******************************************************************/
|
||||
case (LCM_CAUSE_UNKNOWN):
|
||||
case (LCM_CAUSE_SWVER_NAVAIL):
|
||||
ftdm_log(FTDM_LOG_ERROR,"[MTP2] %s : %s : Event (%d)\n",
|
||||
ftdm_log(FTDM_LOG_WARNING,"[MTP2] %s : %s : Event (%d)\n",
|
||||
DECODE_LSD_EVENT(sta->t.usta.alarm.event),
|
||||
DECODE_LCM_CAUSE(sta->t.usta.alarm.cause),
|
||||
sta->t.usta.evntParm[0]);
|
||||
break;
|
||||
/******************************************************************/
|
||||
case (LCM_CAUSE_DECODE_ERR):
|
||||
ftdm_log(FTDM_LOG_ERROR,"[MTP2] %s : %s : Primitive (%d)|Version (%d)\n",
|
||||
ftdm_log(FTDM_LOG_WARNING,"[MTP2] %s : %s : Primitive (%d)|Version (%d)\n",
|
||||
DECODE_LSD_EVENT(sta->t.usta.alarm.event),
|
||||
DECODE_LCM_CAUSE(sta->t.usta.alarm.cause),
|
||||
sta->t.usta.evntParm[0],
|
||||
|
@ -317,7 +329,7 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta)
|
|||
break;
|
||||
/******************************************************************/
|
||||
default:
|
||||
ftdm_log(FTDM_LOG_ERROR,"[MTP2] %s(%d) : %s(%d)\n",
|
||||
ftdm_log(FTDM_LOG_WARNING,"[MTP2] %s(%d) : %s(%d)\n",
|
||||
DECODE_LSD_EVENT(sta->t.usta.alarm.event),
|
||||
sta->t.usta.alarm.event,
|
||||
DECODE_LSD_CAUSE(sta->t.usta.alarm.cause),
|
||||
|
@ -328,7 +340,7 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta)
|
|||
break;
|
||||
/**********************************************************************/
|
||||
default:
|
||||
ftdm_log(FTDM_LOG_ERROR,"[MTP2] %s(%d) : %s(%d)\n",
|
||||
ftdm_log(FTDM_LOG_WARNING,"[MTP2] %s(%d) : %s(%d)\n",
|
||||
DECODE_LSD_EVENT(sta->t.usta.alarm.event),
|
||||
sta->t.usta.alarm.event,
|
||||
DECODE_LSD_CAUSE(sta->t.usta.alarm.cause),
|
||||
|
@ -381,7 +393,7 @@ void handle_sng_mtp3_alarm(Pst *pst, SnMngmt *sta)
|
|||
/**********************************************************************/
|
||||
case (LSN_EVENT_INV_OPC_OTHER_END):
|
||||
|
||||
ftdm_log(FTDM_LOG_ERROR,"[MTP3]%s %s : %s : OPC(0x%X%X%X%X)\n",
|
||||
ftdm_log(FTDM_LOG_WARNING,"[MTP3]%s %s : %s : OPC(0x%X%X%X%X)\n",
|
||||
buf,
|
||||
DECODE_LSN_EVENT(sta->t.usta.alarm.event),
|
||||
DECODE_LSN_CAUSE(sta->t.usta.alarm.cause),
|
||||
|
@ -392,7 +404,7 @@ void handle_sng_mtp3_alarm(Pst *pst, SnMngmt *sta)
|
|||
break;
|
||||
/**********************************************************************/
|
||||
case (LSN_EVENT_INV_SLC_OTHER_END):
|
||||
ftdm_log(FTDM_LOG_ERROR,"[MTP3]%s %s : %s : SLC(%d)\n",
|
||||
ftdm_log(FTDM_LOG_WARNING,"[MTP3]%s %s : %s : SLC(%d)\n",
|
||||
buf,
|
||||
DECODE_LSN_EVENT(sta->t.usta.alarm.event),
|
||||
DECODE_LSN_CAUSE(sta->t.usta.alarm.cause),
|
||||
|
@ -400,7 +412,7 @@ void handle_sng_mtp3_alarm(Pst *pst, SnMngmt *sta)
|
|||
break;
|
||||
/**********************************************************************/
|
||||
default:
|
||||
ftdm_log(FTDM_LOG_DEBUG,"[MTP3]%s %s(%d) : %s(%d)\n",
|
||||
ftdm_log(FTDM_LOG_WARNING,"[MTP3]%s %s(%d) : %s(%d)\n",
|
||||
buf,
|
||||
DECODE_LSN_EVENT(sta->t.usta.alarm.event),
|
||||
sta->t.usta.alarm.event,
|
||||
|
@ -412,7 +424,7 @@ void handle_sng_mtp3_alarm(Pst *pst, SnMngmt *sta)
|
|||
break;
|
||||
/**************************************************************************/
|
||||
case (STNSAP):
|
||||
ftdm_log(FTDM_LOG_ERROR,"[MTP3][SAPID:%d] %s : %s\n",
|
||||
ftdm_log(FTDM_LOG_WARNING,"[MTP3][SAPID:%d] %s : %s\n",
|
||||
sta->hdr.elmId.elmntInst1,
|
||||
DECODE_LSN_EVENT(sta->t.usta.alarm.event),
|
||||
DECODE_LSN_CAUSE(sta->t.usta.alarm.cause));
|
||||
|
@ -463,7 +475,7 @@ void handle_sng_mtp3_alarm(Pst *pst, SnMngmt *sta)
|
|||
break;
|
||||
/**********************************************************************/
|
||||
default:
|
||||
ftdm_log(FTDM_LOG_ERROR,"[MTP3][DPC:0x%X%X%X%X] %s : %s\n",
|
||||
ftdm_log(FTDM_LOG_WARNING,"[MTP3][DPC:0x%X%X%X%X] %s : %s\n",
|
||||
sta->t.usta.evntParm[0],
|
||||
sta->t.usta.evntParm[1],
|
||||
sta->t.usta.evntParm[2],
|
||||
|
@ -733,7 +745,7 @@ void handle_sng_isup_alarm(Pst *pst, SiMngmt *sta)
|
|||
} /* switch (sta->t.usta.dgn.dgnVal[x].t.type) */
|
||||
} /* for (x = 0; x < 5; x++) */
|
||||
|
||||
ftdm_log(FTDM_LOG_ERROR,"%s %s : %s\n",
|
||||
ftdm_log(FTDM_LOG_WARNING,"%s %s : %s\n",
|
||||
msg,
|
||||
DECODE_LSI_EVENT(sta->t.usta.alarm.event),
|
||||
DECODE_LSI_CAUSE(sta->t.usta.alarm.cause));
|
||||
|
@ -759,7 +771,7 @@ void handle_sng_relay_alarm(Pst *pst, RyMngmt *sta)
|
|||
switch (sta->hdr.elmId.elmnt) {
|
||||
/**************************************************************************/
|
||||
case (LRY_USTA_ERR): /* ERROR */
|
||||
ftdm_log(FTDM_LOG_ERROR,"[RELAY] Error: tx procId %d: err procId %d: channel %d: seq %s: reason %s\n",
|
||||
ftdm_log(FTDM_LOG_WARNING,"[RELAY] Error: tx procId %d: err procId %d: channel %d: seq %s: reason %s\n",
|
||||
sta->t.usta.s.ryErrUsta.sendPid,
|
||||
sta->t.usta.s.ryErrUsta.errPid,
|
||||
sta->t.usta.s.ryErrUsta.id,
|
||||
|
@ -783,7 +795,7 @@ void handle_sng_relay_alarm(Pst *pst, RyMngmt *sta)
|
|||
break;
|
||||
/**************************************************************************/
|
||||
case (LRY_USTA_CNG): /* Congestion */
|
||||
ftdm_log(FTDM_LOG_ERROR,"[RELAY] Congestion: tx procId %d: rem procId %d: channel %d: %s\n",
|
||||
ftdm_log(FTDM_LOG_WARNING,"[RELAY] Congestion: tx procId %d: rem procId %d: channel %d: %s\n",
|
||||
sta->t.usta.s.ryCongUsta.sendPid,
|
||||
sta->t.usta.s.ryCongUsta.remPid,
|
||||
sta->t.usta.s.ryCongUsta.id,
|
||||
|
@ -791,7 +803,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);
|
||||
|
||||
|
@ -801,7 +813,7 @@ void handle_sng_relay_alarm(Pst *pst, RyMngmt *sta)
|
|||
break;
|
||||
/**************************************************************************/
|
||||
case (LRY_USTA_DN): /* channel down */
|
||||
ftdm_log(FTDM_LOG_ERROR,"[RELAY] Channel DOWN: tx procId %d: channel %d\n",
|
||||
ftdm_log(FTDM_LOG_WARNING,"[RELAY] Channel DOWN: tx procId %d: channel %d\n",
|
||||
sta->t.usta.s.ryUpUsta.sendPid,
|
||||
sta->t.usta.s.ryUpUsta.id);
|
||||
|
||||
|
@ -810,6 +822,11 @@ void handle_sng_relay_alarm(Pst *pst, RyMngmt *sta)
|
|||
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case (LRY_USTA_TCP_CONN_FAILED):
|
||||
ftdm_log(FTDM_LOG_WARNING,"[RELAY] TCP connection failed \n" );
|
||||
|
||||
break;
|
||||
/**************************************************************************/
|
||||
default:
|
||||
ftdm_log(FTDM_LOG_ERROR,"Unknown Relay Alram\n");
|
||||
break;
|
||||
|
@ -819,6 +836,311 @@ void handle_sng_relay_alarm(Pst *pst, RyMngmt *sta)
|
|||
return;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
void handle_sng_m2ua_alarm(Pst *pst, MwMgmt *sta)
|
||||
{
|
||||
/* To print the general information */
|
||||
ftdm_log(FTDM_LOG_INFO, "Recieved a status indication from M2UA layer \n\n");
|
||||
ftdm_log(FTDM_LOG_INFO," Category = %d , event = %d , cause = %d\n",
|
||||
sta->t.usta.alarm.category, sta->t.usta.alarm.event, sta->t.usta.alarm.cause);
|
||||
|
||||
|
||||
/* To print the affected element value */
|
||||
switch(sta->hdr.elmId.elmnt)
|
||||
{
|
||||
case STMWDLSAP:
|
||||
{
|
||||
ftdm_log(FTDM_LOG_INFO," STMWDLSAP: with lnkNmb (%d) \n\n",
|
||||
sta->t.usta.s.lnkNmb);
|
||||
break;
|
||||
}
|
||||
case STMWSCTSAP:
|
||||
{
|
||||
ftdm_log(FTDM_LOG_INFO," STMWSCTSAP: suId (%d) \n\n",
|
||||
sta->t.usta.s.suId);
|
||||
break;
|
||||
}
|
||||
case STMWPEER:
|
||||
{
|
||||
ftdm_log(FTDM_LOG_INFO," STMWPEER: peerId (%d) \n\n",
|
||||
sta->t.usta.s.peerId);
|
||||
break;
|
||||
}
|
||||
case STMWCLUSTER:
|
||||
{
|
||||
ftdm_log(FTDM_LOG_INFO," STMWCLUSTER: clusterId (%d) \n\n",
|
||||
sta->t.usta.s.peerId);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
ftdm_log(FTDM_LOG_ERROR, "[MW_USTA]: Invalid element \n\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* To print the event specific information */
|
||||
switch(sta->t.usta.alarm.event)
|
||||
{
|
||||
case LMW_EVENT_TERM_OK:
|
||||
{
|
||||
ftdm_log(FTDM_LOG_INFO," M2UA : LMW_EVENT_TERM_OK: Association Terminated with PeerId[%d] \n",sta->t.usta.s.peerId);
|
||||
break;
|
||||
}
|
||||
case LMW_EVENT_ENDPOPEN_OK:
|
||||
{
|
||||
ftdm_log(FTDM_LOG_INFO," M2UA : LMW_EVENT_ENDPOPEN_OK: \n");
|
||||
break;
|
||||
}
|
||||
case LMW_EVENT_ESTABLISH_OK:
|
||||
{
|
||||
ftdm_log(FTDM_LOG_INFO," M2UA : LMW_EVENT_ESTABLISH_OK Event raised on peerId[%d]\n",sta->t.usta.s.peerId);
|
||||
break;
|
||||
}
|
||||
case LMW_EVENT_ESTABLISH_FAIL:
|
||||
{
|
||||
ftdm_log(FTDM_LOG_INFO," M2UA : LMW_EVENT_ESTABLISH_FAIL Event raised on peerId[%d]\n",sta->t.usta.s.peerId);
|
||||
break;
|
||||
}
|
||||
case LMW_EVENT_ASPM:
|
||||
{
|
||||
ftdm_log(FTDM_LOG_INFO," M2UA : LMW_EVENT_ASPM Event raised with peerId (%d), aspId (%d),"
|
||||
" msgType (%d)\n\n",sta->t.usta.s.peerId,
|
||||
sta->t.usta.t.aspm.msgType);
|
||||
break;
|
||||
}
|
||||
case LMW_EVENT_CLUSTER:
|
||||
{
|
||||
ftdm_log(FTDM_LOG_INFO," M2UA : LMW_EVENT_CLUSTER Event raised on clusterId (%d), state (%d)\n\n",
|
||||
sta->t.usta.s.clusterId, sta->t.usta.t.cluster.state);
|
||||
|
||||
break;
|
||||
}
|
||||
case LMW_EVENT_NOTIFY:
|
||||
{
|
||||
ftdm_log(FTDM_LOG_INFO," M2UA : LMW_EVENT_NOTIFY: peerId (%d), aspId (%d), ntfy status type (%d),"
|
||||
" ntfy status id (%d)\n\n", sta->t.usta.s.peerId,
|
||||
sta->t.usta.t.ntfy.aspId, sta->t.usta.t.ntfy.stType,
|
||||
sta->t.usta.t.ntfy.stId);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case LMW_EVENT_M2UA_PROTO_ERROR:
|
||||
{
|
||||
ftdm_log(FTDM_LOG_ERROR, " M2UA : LMW_EVENT_M2UA_PROTO_ERROR with errorCode (%d)\n\n",
|
||||
sta->t.usta.t.error.errCode);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
} /* handle_sng_m2ua_alarm */
|
||||
|
||||
/******************************************************************************/
|
||||
void handle_sng_nif_alarm(Pst *pst, NwMgmt *sta)
|
||||
{
|
||||
/* To print the general information */
|
||||
ftdm_log(FTDM_LOG_INFO," Recieved a status indication from NIF layer\n");
|
||||
ftdm_log(FTDM_LOG_INFO," Category = %d , event = %d , cause = %d\n", sta->t.usta.alarm.category,
|
||||
sta->t.usta.alarm.event, sta->t.usta.alarm.cause);
|
||||
|
||||
switch(sta->hdr.elmId.elmnt)
|
||||
{
|
||||
case STNWDLSAP:
|
||||
{
|
||||
ftdm_log(FTDM_LOG_INFO," Recieved STNWDLSAP status indication for suId (%d) \n", sta->t.usta.suId);
|
||||
switch(sta->t.usta.alarm.event)
|
||||
{
|
||||
case LCM_EVENT_LI_INV_EVT:
|
||||
{
|
||||
switch(sta->t.usta.alarm.cause)
|
||||
{
|
||||
case LCM_CAUSE_INV_SAP:
|
||||
{
|
||||
ftdm_log(FTDM_LOG_ERROR, " LCM_CAUSE_INV_SAP Alarm \n");
|
||||
break;
|
||||
}
|
||||
case LCM_CAUSE_INV_STATE:
|
||||
{
|
||||
ftdm_log(FTDM_LOG_ERROR, " LCM_CAUSE_INV_STATE Alarm \n");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case LCM_EVENT_BND_OK:
|
||||
{
|
||||
ftdm_log(FTDM_LOG_INFO," NIF: LCM_EVENT_BND_OK Alarm \n");
|
||||
break;
|
||||
}
|
||||
case LCM_EVENT_BND_FAIL:
|
||||
{
|
||||
ftdm_log(FTDM_LOG_INFO," NIF: LCM_EVENT_BND_FAIL Alarm \n");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} /* handle_sng_nif_alarm */
|
||||
|
||||
/******************************************************************************/
|
||||
void handle_sng_tucl_alarm(Pst *pst, HiMngmt *sta)
|
||||
{
|
||||
/* To print the general information */
|
||||
ftdm_log(FTDM_LOG_INFO, "Recieved a status indication from TUCL layer \n\n");
|
||||
ftdm_log(FTDM_LOG_INFO, " Category = %d , event = %d , cause = %d\n",
|
||||
sta->t.usta.alarm.category,
|
||||
sta->t.usta.alarm.event, sta->t.usta.alarm.cause);
|
||||
|
||||
switch(sta->t.usta.alarm.event)
|
||||
{
|
||||
case LCM_EVENT_INV_EVT:
|
||||
{
|
||||
ftdm_log(FTDM_LOG_INFO," [HI_USTA]: LCM_EVENT_INV_EVT with type (%d)\n\n",
|
||||
sta->t.usta.info.type);
|
||||
break;
|
||||
}
|
||||
case LHI_EVENT_BNDREQ:
|
||||
{
|
||||
ftdm_log(FTDM_LOG_INFO," [HI_USTA]: LHI_EVENT_BNDREQ with type (%d) spId (%d)\n\n",
|
||||
sta->t.usta.info.type, sta->t.usta.info.spId);
|
||||
break;
|
||||
}
|
||||
case LHI_EVENT_SERVOPENREQ:
|
||||
case LHI_EVENT_DATREQ:
|
||||
case LHI_EVENT_UDATREQ:
|
||||
case LHI_EVENT_CONREQ:
|
||||
case LHI_EVENT_DISCREQ:
|
||||
#if(defined(HI_TLS) && defined(HI_TCP_TLS))
|
||||
case LHI_EVENT_TLS_ESTREQ:
|
||||
#endif
|
||||
{
|
||||
ftdm_log(FTDM_LOG_INFO," [HI_USTA]: partype (%d) type(%d)\n\n",
|
||||
sta->t.usta.info.inf.parType, sta->t.usta.info.type);
|
||||
break;
|
||||
}
|
||||
case LCM_EVENT_DMEM_ALLOC_FAIL:
|
||||
case LCM_EVENT_SMEM_ALLOC_FAIL:
|
||||
{
|
||||
ftdm_log(FTDM_LOG_ERROR," [HI_USTA]: MEM_ALLOC_FAIL with region(%d) pool (%d) type(%d)\n\n",
|
||||
sta->t.usta.info.inf.mem.region, sta->t.usta.info.inf.mem.pool,
|
||||
sta->t.usta.info.type);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
} /* handle_sng_tucl_alarm */
|
||||
|
||||
/******************************************************************************/
|
||||
void handle_sng_sctp_alarm(Pst *pst, SbMgmt *sta)
|
||||
{
|
||||
ftdm_log(FTDM_LOG_INFO, "Recieved a status indication from SCTP layer \n\n");
|
||||
ftdm_log(FTDM_LOG_INFO," Category = %d , event = %d , cause = %d "
|
||||
" [SB_USTA]: sapId (%d) and swtch (%d)\n",
|
||||
sta->t.usta.alarm.category,
|
||||
sta->t.usta.alarm.event, sta->t.usta.alarm.cause,
|
||||
sta->t.usta.sapId, sta->t.usta.swtch);
|
||||
|
||||
switch(sta->t.usta.alarm.category)
|
||||
{
|
||||
case LCM_CATEGORY_INTERFACE:
|
||||
{
|
||||
switch(sta->t.usta.alarm.cause)
|
||||
{
|
||||
case LCM_CAUSE_INV_SPID:
|
||||
{
|
||||
ftdm_log(FTDM_LOG_ERROR, "SCTP : LCM_CAUSE_INV_SPID Alarm \n");
|
||||
break;
|
||||
}
|
||||
case LCM_CAUSE_SWVER_NAVAIL:
|
||||
{
|
||||
ftdm_log(FTDM_LOG_ERROR, "SCTP : LCM_CAUSE_SWVER_NAVAIL Alarm\n");
|
||||
break;
|
||||
}
|
||||
case LCM_CAUSE_INV_PAR_VAL:
|
||||
{
|
||||
ftdm_log(FTDM_LOG_ERROR, "SCTP : LCM_CAUSE_INV_PAR_VAL Alarm\n");
|
||||
break;
|
||||
}
|
||||
case LCM_CAUSE_INV_SUID:
|
||||
{
|
||||
ftdm_log(FTDM_LOG_ERROR, "SCTP : LCM_CAUSE_INV_SUID Alarm\n");
|
||||
break;
|
||||
}
|
||||
case LCM_CAUSE_INV_SAP:
|
||||
{
|
||||
ftdm_log(FTDM_LOG_ERROR, "SCTP : LCM_CAUSE_INV_SAP Alarm\n");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case LCM_CATEGORY_RESOURCE:
|
||||
{
|
||||
switch(sta->t.usta.alarm.cause)
|
||||
{
|
||||
case LCM_CAUSE_MEM_ALLOC_FAIL:
|
||||
{
|
||||
ftdm_log(FTDM_LOG_ERROR, "SCTP : LCM_CAUSE_MEM_ALLOC_FAIL Alarm \n");
|
||||
break;
|
||||
}
|
||||
case LSB_CAUSE_NUM_ADDR_EXCEED:
|
||||
{
|
||||
ftdm_log(FTDM_LOG_ERROR, "SCTP : LSB_CAUSE_NUM_ADDR_EXCEED Alarm\n");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case LCM_CATEGORY_PROTOCOL:
|
||||
{
|
||||
switch(sta->t.usta.alarm.cause)
|
||||
{
|
||||
case LSB_CAUSE_PATH_FAILURE:
|
||||
{
|
||||
ftdm_log(FTDM_LOG_ERROR, "SCTP : LSB_CAUSE_PATH_FAILURE Alarm \n");
|
||||
break;
|
||||
}
|
||||
case LSB_CAUSE_PATH_ACTIVE:
|
||||
{
|
||||
ftdm_log(FTDM_LOG_ERROR, "SCTP : LSB_CAUSE_PATH_ACTIVE Alarm \n");
|
||||
break;
|
||||
}
|
||||
case LSB_CAUSE_UNRSLVD_ADDR:
|
||||
{
|
||||
ftdm_log(FTDM_LOG_ERROR, "SCTP : LSB_CAUSE_UNRSLVD_ADDR Alarm \n");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
} /* handle_sng_sctp_alarm */
|
||||
/******************************************************************************/
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
* Copyright (c) 2012, Kapil Gupta <kgupta@sangoma.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the original author; nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
* Contributors:
|
||||
*
|
||||
*/
|
||||
/******************************************************************************/
|
||||
#ifndef __FTMOD_SNG_SS7_M2UA_H__
|
||||
#define __FTMOD_SNG_SS7_M2UA_H__
|
||||
/******************************************************************************/
|
||||
#include "private/ftdm_core.h"
|
||||
|
||||
#define MAX_NAME_LEN 25
|
||||
|
||||
typedef struct sng_nif_cfg{
|
||||
char name[MAX_NAME_LEN];
|
||||
uint32_t flags;
|
||||
uint32_t id;
|
||||
uint32_t m2uaLnkNmb;
|
||||
uint32_t mtp2LnkNmb;
|
||||
}sng_nif_cfg_t;
|
||||
|
||||
typedef enum{
|
||||
SNG_M2UA_NODE_TYPE_SGP = 1, /* type SG */
|
||||
SNG_M2UA_NODE_TYPE_ASP = 2, /* type ASP */
|
||||
}sng_m2ua_node_types_e;
|
||||
|
||||
typedef struct sng_m2ua_cfg{
|
||||
char name[MAX_NAME_LEN];
|
||||
uint32_t flags;
|
||||
uint32_t id; /* ID */
|
||||
uint32_t iid; /* ID */
|
||||
uint8_t nodeType; /*Node Type SG/ASP */
|
||||
uint8_t end_point_opened; /* flag to check is end-point already opened */
|
||||
uint16_t clusterId; /* idx to m2ua_cluster profile */
|
||||
}sng_m2ua_cfg_t;
|
||||
|
||||
typedef struct sng_m2ua_peer_cfg{
|
||||
char name[MAX_NAME_LEN];
|
||||
uint32_t flags;
|
||||
uint32_t id; /* ID */
|
||||
uint8_t aspIdFlag; /* Flag used to indicate whether include the ASP ID in the ASP UP message */
|
||||
uint16_t selfAspId; /* Self ASP ID. ASP identifier for this ASP node if the aspIdFlag is TRUE. */
|
||||
uint32_t numDestAddr; /* Number of destination address defined */
|
||||
uint16_t sctpId; /* idx to sctp profile */
|
||||
uint16_t port;
|
||||
uint32_t destAddrList[SCT_MAX_NET_ADDRS+1]; /* Destination adddress list */
|
||||
uint16_t locOutStrms; /*Number of outgoing streams supported by this association*/
|
||||
int init_sctp_assoc; /* flag to tell if we need to initiate SCTP association */
|
||||
}sng_m2ua_peer_cfg_t;
|
||||
|
||||
typedef enum{
|
||||
SNG_M2UA_LOAD_SHARE_ALGO_RR = 0x1, /* Round Robin Mode*/
|
||||
SNG_M2UA_LOAD_SHARE_ALGO_LS = 0x2, /* Link Specified */
|
||||
SNG_M2UA_LOAD_SHARE_ALGO_CS = 0x3, /* Customer Specified */
|
||||
}sng_m2ua_load_share_algo_types_e;
|
||||
|
||||
|
||||
/* Possible values of Traffic mode */
|
||||
typedef enum{
|
||||
SNG_M2UA_TRF_MODE_OVERRIDE = 0x1, /* Override Mode */
|
||||
SNG_M2UA_TRF_MODE_LOADSHARE = 0x2, /* Loadshare Mode */
|
||||
SNG_M2UA_TRF_MODE_BROADCAST = 0x3, /* Broadcast Mode */
|
||||
SNG_M2UA_TRF_MODE_ANY = 0x0, /* ANY Mode */
|
||||
}sng_m2ua_traffic_mode_types_e;
|
||||
|
||||
typedef struct sng_m2ua_cluster_cfg{
|
||||
char name[MAX_NAME_LEN];
|
||||
uint32_t flags;
|
||||
uint32_t id; /* ID */
|
||||
uint32_t sct_sap_id; /* Internal - sct_sap_id */
|
||||
uint8_t trfMode; /* Traffic mode. This parameter defines the mode in which this m2ua cluster is supposed to work */
|
||||
uint8_t loadShareAlgo; /* This parameter defines the M2UA load share algorithm which is used to distribute the traffic */
|
||||
uint16_t numOfPeers; /* idx to m2ua_peer profile */
|
||||
uint16_t peerIdLst[MW_MAX_NUM_OF_PEER]; /* idx to m2ua_peer profile */
|
||||
}sng_m2ua_cluster_cfg_t;
|
||||
|
||||
typedef struct sng_m2ua_gbl_cfg{
|
||||
sng_nif_cfg_t nif[MW_MAX_NUM_OF_INTF+1];
|
||||
sng_m2ua_cfg_t m2ua[MW_MAX_NUM_OF_INTF+1];
|
||||
sng_m2ua_peer_cfg_t m2ua_peer[MW_MAX_NUM_OF_PEER+1];
|
||||
sng_m2ua_cluster_cfg_t m2ua_clus[MW_MAX_NUM_OF_CLUSTER+1];
|
||||
}sng_m2ua_gbl_cfg_t;
|
||||
|
||||
/* m2ua xml parsing APIs */
|
||||
int ftmod_ss7_parse_nif_interfaces(ftdm_conf_node_t *nif_interfaces);
|
||||
int ftmod_ss7_parse_m2ua_interfaces(ftdm_conf_node_t *m2ua_interfaces);
|
||||
int ftmod_ss7_parse_m2ua_peer_interfaces(ftdm_conf_node_t *m2ua_peer_interfaces);
|
||||
int ftmod_ss7_parse_m2ua_clust_interfaces(ftdm_conf_node_t *m2ua_clust_interfaces);
|
||||
int ftmod_ss7_parse_sctp_links(ftdm_conf_node_t *node);
|
||||
uint32_t iptoul(const char *ip);
|
||||
|
||||
int ftmod_ss7_m2ua_start(void);
|
||||
void ftmod_ss7_m2ua_free(void);
|
||||
|
||||
ftdm_status_t ftmod_ss7_m2ua_cfg(void);
|
||||
ftdm_status_t ftmod_ss7_m2ua_init(void);
|
||||
|
||||
int ftmod_sctp_ssta_req(int elemt, int id, SbMgmt* cfm);
|
||||
int ftmod_m2ua_ssta_req(int elemt, int id, MwMgmt* cfm);
|
||||
int ftmod_nif_ssta_req(int elemt, int id, NwMgmt* cfm);
|
||||
void ftmod_ss7_enable_m2ua_sg_logging(void);
|
||||
void ftmod_ss7_disable_m2ua_sg_logging(void);
|
||||
|
||||
|
||||
#endif /*__FTMOD_SNG_SS7_M2UA_H__*/
|
|
@ -0,0 +1,690 @@
|
|||
/*
|
||||
* Copyright (c) 2012, Kapil Gupta <kgupta@sangoma.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the original author; nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
* Contributors:
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/* INCLUDE ********************************************************************/
|
||||
#include "ftmod_sangoma_ss7_main.h"
|
||||
/******************************************************************************/
|
||||
|
||||
/* DEFINES ********************************************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
static int ftmod_ss7_parse_nif_interface(ftdm_conf_node_t *nif_interface);
|
||||
static int ftmod_ss7_parse_m2ua_interface(ftdm_conf_node_t *m2ua_interface);
|
||||
static int ftmod_ss7_parse_m2ua_peer_interface(ftdm_conf_node_t *m2ua_peer_interface);
|
||||
static int ftmod_ss7_parse_m2ua_clust_interface(ftdm_conf_node_t *m2ua_clust_interface);
|
||||
static int ftmod_ss7_fill_in_nif_interface(sng_nif_cfg_t *nif_iface);
|
||||
static int ftmod_ss7_fill_in_m2ua_interface(sng_m2ua_cfg_t *m2ua_iface);
|
||||
static int ftmod_ss7_fill_in_m2ua_peer_interface(sng_m2ua_peer_cfg_t *m2ua_peer_face);
|
||||
static int ftmod_ss7_fill_in_m2ua_clust_interface(sng_m2ua_cluster_cfg_t *m2ua_cluster_face);
|
||||
|
||||
static int ftmod_ss7_parse_sctp_link(ftdm_conf_node_t *node);
|
||||
|
||||
/******************************************************************************/
|
||||
int ftmod_ss7_parse_nif_interfaces(ftdm_conf_node_t *nif_interfaces)
|
||||
{
|
||||
ftdm_conf_node_t *nif_interface = NULL;
|
||||
|
||||
/* confirm that we are looking at sng_nif_interfaces */
|
||||
if (strcasecmp(nif_interfaces->name, "sng_nif_interfaces")) {
|
||||
SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"sng_nif_interfaces\"!\n",nif_interfaces->name);
|
||||
return FTDM_FAIL;
|
||||
} else {
|
||||
SS7_DEBUG("Parsing \"nif_interfaces\"...\n");
|
||||
}
|
||||
|
||||
/* extract the isup_interfaces */
|
||||
nif_interface = nif_interfaces->child;
|
||||
|
||||
while (nif_interface != NULL) {
|
||||
/* parse the found mtp_route */
|
||||
if (ftmod_ss7_parse_nif_interface(nif_interface)) {
|
||||
SS7_ERROR("Failed to parse \"nif_interface\"\n");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
/* go to the next nif_interface */
|
||||
nif_interface = nif_interface->next;
|
||||
}
|
||||
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
static int ftmod_ss7_parse_nif_interface(ftdm_conf_node_t *nif_interface)
|
||||
{
|
||||
sng_nif_cfg_t sng_nif;
|
||||
ftdm_conf_parameter_t *parm = nif_interface->parameters;
|
||||
int num_parms = nif_interface->n_parameters;
|
||||
int i;
|
||||
|
||||
/* initalize the nif intf and isap structure */
|
||||
memset(&sng_nif, 0x0, sizeof(sng_nif));
|
||||
|
||||
if(!nif_interface){
|
||||
SS7_ERROR("ftmod_ss7_parse_nif_interface: Null XML Node pointer \n");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
/* confirm that we are looking at an nif_interface */
|
||||
if (strcasecmp(nif_interface->name, "sng_nif_interface")) {
|
||||
SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"nif_interface\"!\n",nif_interface->name);
|
||||
return FTDM_FAIL;
|
||||
} else {
|
||||
SS7_DEBUG("Parsing \"nif_interface\"...\n");
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; i < num_parms; i++) {
|
||||
/**************************************************************************/
|
||||
|
||||
/* try to match the parameter to what we expect */
|
||||
if (!strcasecmp(parm->var, "name")) {
|
||||
/**********************************************************************/
|
||||
strcpy((char *)sng_nif.name, parm->val);
|
||||
SS7_DEBUG("Found an nif_interface named = %s\n", sng_nif.name);
|
||||
/**********************************************************************/
|
||||
} else if (!strcasecmp(parm->var, "id")) {
|
||||
/**********************************************************************/
|
||||
sng_nif.id = atoi(parm->val);
|
||||
SS7_DEBUG("Found an nif id = %d\n", sng_nif.id);
|
||||
/**********************************************************************/
|
||||
} else if (!strcasecmp(parm->var, "m2ua-interface-id")) {
|
||||
/**********************************************************************/
|
||||
sng_nif.m2uaLnkNmb = atoi(parm->val);
|
||||
SS7_DEBUG("Found an nif m2ua-interface-id = %d\n", sng_nif.m2uaLnkNmb);
|
||||
/**********************************************************************/
|
||||
} else if (!strcasecmp(parm->var, "mtp2-interface-id")) {
|
||||
/**********************************************************************/
|
||||
sng_nif.mtp2LnkNmb=atoi(parm->val);
|
||||
|
||||
SS7_DEBUG("Found an nif mtp2-interface-id = %d\n", sng_nif.mtp2LnkNmb);
|
||||
/**********************************************************************/
|
||||
} else {
|
||||
/**********************************************************************/
|
||||
SS7_ERROR("Found an invalid parameter %s!\n", parm->var);
|
||||
return FTDM_FAIL;
|
||||
/**********************************************************************/
|
||||
}
|
||||
|
||||
/* move to the next parameter */
|
||||
parm = parm + 1;
|
||||
/**************************************************************************/
|
||||
} /* for (i = 0; i < num_parms; i++) */
|
||||
|
||||
/* fill in the nif interface */
|
||||
ftmod_ss7_fill_in_nif_interface(&sng_nif);
|
||||
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
/******************************************************************************/
|
||||
static int ftmod_ss7_fill_in_nif_interface(sng_nif_cfg_t *nif_iface)
|
||||
{
|
||||
int i = nif_iface->id;
|
||||
|
||||
strncpy((char *)g_ftdm_sngss7_data.cfg.g_m2ua_cfg.nif[i].name, (char *)nif_iface->name, MAX_NAME_LEN-1);
|
||||
|
||||
g_ftdm_sngss7_data.cfg.g_m2ua_cfg.nif[i].id = nif_iface->id;
|
||||
g_ftdm_sngss7_data.cfg.g_m2ua_cfg.nif[i].m2uaLnkNmb = nif_iface->m2uaLnkNmb;
|
||||
g_ftdm_sngss7_data.cfg.g_m2ua_cfg.nif[i].mtp2LnkNmb = nif_iface->mtp2LnkNmb;
|
||||
|
||||
sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_NIF_PRESENT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
int ftmod_ss7_parse_m2ua_interfaces(ftdm_conf_node_t *m2ua_interfaces)
|
||||
{
|
||||
ftdm_conf_node_t *m2ua_interface = NULL;
|
||||
|
||||
/* confirm that we are looking at sng_m2ua_interfaces */
|
||||
if (strcasecmp(m2ua_interfaces->name, "sng_m2ua_interfaces")) {
|
||||
SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"m2ua_nif_interfaces\"!\n",m2ua_interfaces->name);
|
||||
return FTDM_FAIL;
|
||||
} else {
|
||||
SS7_DEBUG("Parsing \"m2ua_interfaces\"...\n");
|
||||
}
|
||||
|
||||
/* extract the isup_interfaces */
|
||||
m2ua_interface = m2ua_interfaces->child;
|
||||
|
||||
while (m2ua_interface != NULL) {
|
||||
/* parse the found mtp_route */
|
||||
if (ftmod_ss7_parse_m2ua_interface(m2ua_interface)) {
|
||||
SS7_ERROR("Failed to parse \"m2ua_interface\"\n");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
/* go to the next m2ua_interface */
|
||||
m2ua_interface = m2ua_interface->next;
|
||||
}
|
||||
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
static int ftmod_ss7_parse_m2ua_interface(ftdm_conf_node_t *m2ua_interface)
|
||||
{
|
||||
sng_m2ua_cfg_t sng_m2ua;
|
||||
ftdm_conf_parameter_t *parm = m2ua_interface->parameters;
|
||||
int num_parms = m2ua_interface->n_parameters;
|
||||
int i;
|
||||
|
||||
/* initalize the m2ua intf */
|
||||
memset(&sng_m2ua, 0x0, sizeof(sng_m2ua));
|
||||
|
||||
if(!m2ua_interface){
|
||||
SS7_ERROR("ftmod_ss7_parse_m2ua_interface: Null XML Node pointer \n");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
/* confirm that we are looking at an nif_interface */
|
||||
if (strcasecmp(m2ua_interface->name, "sng_m2ua_interface")) {
|
||||
SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"m2ua_interface\"!\n",m2ua_interface->name);
|
||||
return FTDM_FAIL;
|
||||
} else {
|
||||
SS7_DEBUG("Parsing \"m2ua_interface\"...\n");
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; i < num_parms; i++) {
|
||||
/**************************************************************************/
|
||||
|
||||
/* try to match the parameter to what we expect */
|
||||
if (!strcasecmp(parm->var, "name")) {
|
||||
/**********************************************************************/
|
||||
strcpy((char *)sng_m2ua.name, parm->val);
|
||||
SS7_DEBUG("Found an m2ua_interface named = %s\n", sng_m2ua.name);
|
||||
/**********************************************************************/
|
||||
} else if (!strcasecmp(parm->var, "id")) {
|
||||
/**********************************************************************/
|
||||
sng_m2ua.id = atoi(parm->val);
|
||||
SS7_DEBUG("Found an m2ua id = %d\n", sng_m2ua.id);
|
||||
/**********************************************************************/
|
||||
} else if (!strcasecmp(parm->var, "m2ua-cluster-interface-id")) {
|
||||
/**********************************************************************/
|
||||
sng_m2ua.clusterId=atoi(parm->val);
|
||||
|
||||
SS7_DEBUG("Found an m2ua cluster_id = %d\n", sng_m2ua.clusterId);
|
||||
/**********************************************************************/
|
||||
} else if (!strcasecmp(parm->var, "interface-identifier")) {
|
||||
/**********************************************************************/
|
||||
sng_m2ua.iid=atoi(parm->val);
|
||||
|
||||
SS7_DEBUG("Found an m2ua interface-identifier = %d\n", sng_m2ua.iid);
|
||||
/**********************************************************************/
|
||||
} else {
|
||||
/**********************************************************************/
|
||||
SS7_ERROR("Found an invalid parameter %s!\n", parm->var);
|
||||
return FTDM_FAIL;
|
||||
/**********************************************************************/
|
||||
}
|
||||
|
||||
/* move to the next parameter */
|
||||
parm = parm + 1;
|
||||
/**************************************************************************/
|
||||
} /* for (i = 0; i < num_parms; i++) */
|
||||
|
||||
sng_m2ua.nodeType = SNG_M2UA_NODE_TYPE_SGP;
|
||||
|
||||
/* fill in the nif interface */
|
||||
ftmod_ss7_fill_in_m2ua_interface(&sng_m2ua);
|
||||
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
/******************************************************************************/
|
||||
static int ftmod_ss7_fill_in_m2ua_interface(sng_m2ua_cfg_t *m2ua_iface)
|
||||
{
|
||||
int i = m2ua_iface->id;
|
||||
|
||||
strncpy((char *)g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua[i].name, (char *)m2ua_iface->name, MAX_NAME_LEN-1);
|
||||
|
||||
g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua[i].id = m2ua_iface->id;
|
||||
g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua[i].nodeType = m2ua_iface->nodeType;
|
||||
g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua[i].clusterId = m2ua_iface->clusterId;
|
||||
g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua[i].iid = m2ua_iface->iid;
|
||||
sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_M2UA_PRESENT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
int ftmod_ss7_parse_m2ua_peer_interfaces(ftdm_conf_node_t *m2ua_peer_interfaces)
|
||||
{
|
||||
ftdm_conf_node_t *m2ua_peer_interface = NULL;
|
||||
|
||||
/* confirm that we are looking at m2ua_peer_interfaces */
|
||||
if (strcasecmp(m2ua_peer_interfaces->name, "sng_m2ua_peer_interfaces")) {
|
||||
SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"m2ua_peer_interfaces\"!\n",m2ua_peer_interfaces->name);
|
||||
return FTDM_FAIL;
|
||||
} else {
|
||||
SS7_DEBUG("Parsing \"m2ua_peer_interfaces\"...\n");
|
||||
}
|
||||
|
||||
/* extract the m2ua_peer_interfaces */
|
||||
m2ua_peer_interface = m2ua_peer_interfaces->child;
|
||||
|
||||
while (m2ua_peer_interface != NULL) {
|
||||
/* parse the found mtp_route */
|
||||
if (ftmod_ss7_parse_m2ua_peer_interface(m2ua_peer_interface)) {
|
||||
SS7_ERROR("Failed to parse \"m2ua_peer_interface\"\n");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
/* go to the next m2ua_peer_interface */
|
||||
m2ua_peer_interface = m2ua_peer_interface->next;
|
||||
}
|
||||
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
static int ftmod_ss7_parse_m2ua_peer_interface(ftdm_conf_node_t *m2ua_peer_interface)
|
||||
{
|
||||
sng_m2ua_peer_cfg_t sng_m2ua_peer;
|
||||
ftdm_conf_parameter_t *parm = m2ua_peer_interface->parameters;
|
||||
int num_parms = m2ua_peer_interface->n_parameters;
|
||||
int i;
|
||||
|
||||
/* initalize the m2ua intf */
|
||||
memset(&sng_m2ua_peer, 0x0, sizeof(sng_m2ua_peer));
|
||||
|
||||
if(!m2ua_peer_interface){
|
||||
SS7_ERROR("ftmod_ss7_parse_m2ua_peer_interface: Null XML Node pointer \n");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
/* confirm that we are looking at an m2ua_peer_interface */
|
||||
if (strcasecmp(m2ua_peer_interface->name, "sng_m2ua_peer_interface")) {
|
||||
SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"m2ua_peer_interface\"!\n",m2ua_peer_interface->name);
|
||||
return FTDM_FAIL;
|
||||
} else {
|
||||
SS7_DEBUG("Parsing \"m2ua_peer_interface\"...\n");
|
||||
}
|
||||
|
||||
for (i = 0; i < num_parms; i++) {
|
||||
/**************************************************************************/
|
||||
|
||||
/* try to match the parameter to what we expect */
|
||||
if (!strcasecmp(parm->var, "name")) {
|
||||
/**********************************************************************/
|
||||
strcpy((char *)sng_m2ua_peer.name, parm->val);
|
||||
SS7_DEBUG("Found an sng_m2ua_peer named = %s\n", sng_m2ua_peer.name);
|
||||
/**********************************************************************/
|
||||
} else if (!strcasecmp(parm->var, "id")) {
|
||||
/**********************************************************************/
|
||||
sng_m2ua_peer.id = atoi(parm->val);
|
||||
SS7_DEBUG("Found an sng_m2ua_peer id = %d\n", sng_m2ua_peer.id);
|
||||
/**********************************************************************/
|
||||
} else if (!strcasecmp(parm->var, "include-asp-identifier")) {
|
||||
/**********************************************************************/
|
||||
if(!strcasecmp(parm->val, "TRUE")){
|
||||
sng_m2ua_peer.aspIdFlag = 0x01;
|
||||
} else if(!strcasecmp(parm->val, "FALSE")){
|
||||
sng_m2ua_peer.aspIdFlag = 0x00;
|
||||
} else {
|
||||
SS7_ERROR("Found an invalid aspIdFlag Parameter Value[%s]\n", parm->val);
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
SS7_DEBUG("Found an sng_m2ua_peer aspIdFlag = %d\n", sng_m2ua_peer.aspIdFlag);
|
||||
/**********************************************************************/
|
||||
} else if (!strcasecmp(parm->var, "asp-identifier")) {
|
||||
/**********************************************************************/
|
||||
sng_m2ua_peer.selfAspId=atoi(parm->val);
|
||||
|
||||
SS7_DEBUG("Found an sng_m2ua_peer self_asp_id = %d\n", sng_m2ua_peer.selfAspId);
|
||||
/**********************************************************************/
|
||||
} else if (!strcasecmp(parm->var, "sctp-interface-id")) {
|
||||
/**********************************************************************/
|
||||
sng_m2ua_peer.sctpId = atoi(parm->val);
|
||||
|
||||
SS7_DEBUG("Found an sng_m2ua_peer sctp_id = %d\n", sng_m2ua_peer.sctpId);
|
||||
/**********************************************************************/
|
||||
} else if (!strcasecmp(parm->var, "destination-port")) {
|
||||
/**********************************************************************/
|
||||
sng_m2ua_peer.port = atoi(parm->val);
|
||||
|
||||
SS7_DEBUG("Found an sng_m2ua_peer port = %d\n", sng_m2ua_peer.port);
|
||||
/**********************************************************************/
|
||||
} else if (!strcasecmp(parm->var, "address")) {
|
||||
/**********************************************************************/
|
||||
if (sng_m2ua_peer.numDestAddr < SCT_MAX_NET_ADDRS) {
|
||||
sng_m2ua_peer.destAddrList[sng_m2ua_peer.numDestAddr] = iptoul (parm->val);
|
||||
sng_m2ua_peer.numDestAddr++;
|
||||
SS7_DEBUG("sng_m2ua_peer - Parsing with dest IP Address = %s \n", parm->val);
|
||||
} else {
|
||||
SS7_ERROR("sng_m2ua_peer - too many dest address configured. dropping %s \n", parm->val);
|
||||
}
|
||||
/**********************************************************************/
|
||||
} else if (!strcasecmp(parm->var, "number-of-outgoing-streams")) {
|
||||
/**********************************************************************/
|
||||
sng_m2ua_peer.locOutStrms=atoi(parm->val);
|
||||
|
||||
SS7_DEBUG("Found an sng_m2ua_peer number-of-outgoing-streams = %d\n", sng_m2ua_peer.locOutStrms);
|
||||
/**********************************************************************/
|
||||
} else if (!strcasecmp(parm->var, "init-sctp-association")) {
|
||||
/**********************************************************************/
|
||||
if(!strcasecmp(parm->val, "TRUE")){
|
||||
sng_m2ua_peer.init_sctp_assoc = 0x01;
|
||||
} else if(!strcasecmp(parm->val, "FALSE")){
|
||||
sng_m2ua_peer.init_sctp_assoc = 0x00;
|
||||
} else {
|
||||
SS7_ERROR("Found an invalid init_sctp_assoc Parameter Value[%s]\n", parm->val);
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
SS7_DEBUG("Found an sng_m2ua_peer init_sctp_assoc = %d\n", sng_m2ua_peer.init_sctp_assoc);
|
||||
/**********************************************************************/
|
||||
} else {
|
||||
/**********************************************************************/
|
||||
SS7_ERROR("Found an invalid parameter %s!\n", parm->var);
|
||||
return FTDM_FAIL;
|
||||
/**********************************************************************/
|
||||
}
|
||||
|
||||
/* move to the next parameter */
|
||||
parm = parm + 1;
|
||||
/**************************************************************************/
|
||||
} /* for (i = 0; i < num_parms; i++) */
|
||||
|
||||
/* fill in the sng_m2ua_peer interface */
|
||||
ftmod_ss7_fill_in_m2ua_peer_interface(&sng_m2ua_peer);
|
||||
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
/******************************************************************************/
|
||||
static int ftmod_ss7_fill_in_m2ua_peer_interface(sng_m2ua_peer_cfg_t *m2ua_peer_iface)
|
||||
{
|
||||
int k = 0x00;
|
||||
int i = m2ua_peer_iface->id;
|
||||
|
||||
strncpy((char *)g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_peer[i].name, (char *)m2ua_peer_iface->name, MAX_NAME_LEN-1);
|
||||
|
||||
g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_peer[i].id = m2ua_peer_iface->id;
|
||||
g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_peer[i].aspIdFlag = m2ua_peer_iface->aspIdFlag;
|
||||
g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_peer[i].selfAspId = m2ua_peer_iface->selfAspId;
|
||||
g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_peer[i].locOutStrms = m2ua_peer_iface->locOutStrms;
|
||||
g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_peer[i].numDestAddr = m2ua_peer_iface->numDestAddr;
|
||||
g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_peer[i].sctpId = m2ua_peer_iface->sctpId;
|
||||
g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_peer[i].port = m2ua_peer_iface->port;
|
||||
g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_peer[i].init_sctp_assoc = m2ua_peer_iface->init_sctp_assoc;
|
||||
for (k=0; k<m2ua_peer_iface->numDestAddr; k++) {
|
||||
g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_peer[i].destAddrList[k] = m2ua_peer_iface->destAddrList[k];
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
int ftmod_ss7_parse_m2ua_clust_interfaces(ftdm_conf_node_t *m2ua_cluster_interfaces)
|
||||
{
|
||||
ftdm_conf_node_t *m2ua_cluster_interface = NULL;
|
||||
|
||||
/* confirm that we are looking at m2ua_cluster_interfaces */
|
||||
if (strcasecmp(m2ua_cluster_interfaces->name, "sng_m2ua_cluster_interfaces")) {
|
||||
SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"m2ua_cluster_interfaces\"!\n",m2ua_cluster_interfaces->name);
|
||||
return FTDM_FAIL;
|
||||
} else {
|
||||
SS7_DEBUG("Parsing \"m2ua_cluster_interfaces\"...\n");
|
||||
}
|
||||
|
||||
/* extract the m2ua_cluster_interfaces */
|
||||
m2ua_cluster_interface = m2ua_cluster_interfaces->child;
|
||||
|
||||
while (m2ua_cluster_interface != NULL) {
|
||||
/* parse the found m2ua_cluster_interface */
|
||||
if (ftmod_ss7_parse_m2ua_clust_interface(m2ua_cluster_interface)) {
|
||||
SS7_ERROR("Failed to parse \"m2ua_cluster_interface\"\n");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
/* go to the next m2ua_cluster_interface */
|
||||
m2ua_cluster_interface = m2ua_cluster_interface->next;
|
||||
}
|
||||
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
static int ftmod_ss7_parse_m2ua_clust_interface(ftdm_conf_node_t *m2ua_cluster_interface)
|
||||
{
|
||||
sng_m2ua_cluster_cfg_t sng_m2ua_cluster;
|
||||
ftdm_conf_parameter_t *parm = m2ua_cluster_interface->parameters;
|
||||
int num_parms = m2ua_cluster_interface->n_parameters;
|
||||
int i;
|
||||
|
||||
/* initalize the m2ua_cluster_interface */
|
||||
memset(&sng_m2ua_cluster, 0x0, sizeof(sng_m2ua_cluster));
|
||||
|
||||
if (!m2ua_cluster_interface){
|
||||
SS7_ERROR("ftmod_ss7_parse_m2ua_clust_interface - NULL XML Node pointer \n");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
/* confirm that we are looking at an m2ua_cluster_interface */
|
||||
if (strcasecmp(m2ua_cluster_interface->name, "sng_m2ua_cluster_interface")) {
|
||||
SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"m2ua_cluster_interface\"!\n",m2ua_cluster_interface->name);
|
||||
return FTDM_FAIL;
|
||||
} else {
|
||||
SS7_DEBUG("Parsing \"m2ua_cluster_interface\"...\n");
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; i < num_parms; i++) {
|
||||
/**************************************************************************/
|
||||
|
||||
/* try to match the parameter to what we expect */
|
||||
if (!strcasecmp(parm->var, "name")) {
|
||||
/**********************************************************************/
|
||||
strcpy((char *)sng_m2ua_cluster.name, parm->val);
|
||||
SS7_DEBUG("Found an sng_m2ua_cluster named = %s\n", sng_m2ua_cluster.name);
|
||||
/**********************************************************************/
|
||||
} else if (!strcasecmp(parm->var, "id")) {
|
||||
/**********************************************************************/
|
||||
sng_m2ua_cluster.id = atoi(parm->val);
|
||||
SS7_DEBUG("Found an sng_m2ua_cluster id = %d\n", sng_m2ua_cluster.id);
|
||||
/**********************************************************************/
|
||||
} else if (!strcasecmp(parm->var, "traffic-mode")) {
|
||||
/**********************************************************************/
|
||||
if(!strcasecmp(parm->val, "loadshare")){
|
||||
sng_m2ua_cluster.trfMode = SNG_M2UA_TRF_MODE_LOADSHARE;
|
||||
} else if(!strcasecmp(parm->val, "override")){
|
||||
sng_m2ua_cluster.trfMode = SNG_M2UA_TRF_MODE_OVERRIDE;
|
||||
} else if(!strcasecmp(parm->val, "broadcast")){
|
||||
sng_m2ua_cluster.trfMode = SNG_M2UA_TRF_MODE_BROADCAST;
|
||||
} else {
|
||||
SS7_ERROR("Found an invalid trfMode Parameter Value[%s]..adding default one[ANY]\n", parm->val);
|
||||
sng_m2ua_cluster.trfMode = SNG_M2UA_TRF_MODE_ANY;
|
||||
}
|
||||
SS7_DEBUG("Found an sng_m2ua_cluster.trfMode = %d\n", sng_m2ua_cluster.trfMode);
|
||||
/**********************************************************************/
|
||||
} else if (!strcasecmp(parm->var, "load-share-algorithm")) {
|
||||
/**********************************************************************/
|
||||
if(!strcasecmp(parm->val, "roundrobin")){
|
||||
sng_m2ua_cluster.loadShareAlgo = SNG_M2UA_LOAD_SHARE_ALGO_RR;
|
||||
} else if(!strcasecmp(parm->val, "linkspecified")){
|
||||
sng_m2ua_cluster.loadShareAlgo = SNG_M2UA_LOAD_SHARE_ALGO_LS;
|
||||
} else if(!strcasecmp(parm->val, "customerspecified")){
|
||||
sng_m2ua_cluster.loadShareAlgo = SNG_M2UA_LOAD_SHARE_ALGO_CS;
|
||||
} else {
|
||||
SS7_ERROR("Found an invalid loadShareAlgo Parameter Value[%s]\n", parm->val);
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
SS7_DEBUG("Found an sng_m2ua_cluster.loadShareAlgo = %d\n", sng_m2ua_cluster.loadShareAlgo);
|
||||
/**********************************************************************/
|
||||
} else if (!strcasecmp(parm->var, "m2ua-peer-interface-id")) {
|
||||
/**********************************************************************/
|
||||
if(sng_m2ua_cluster.numOfPeers < MW_MAX_NUM_OF_PEER) {
|
||||
sng_m2ua_cluster.peerIdLst[sng_m2ua_cluster.numOfPeers] = atoi(parm->val);
|
||||
SS7_DEBUG("Found an sng_m2ua_cluster peerId[%d], Total numOfPeers[%d] \n",
|
||||
sng_m2ua_cluster.peerIdLst[sng_m2ua_cluster.numOfPeers],
|
||||
sng_m2ua_cluster.numOfPeers+1);
|
||||
sng_m2ua_cluster.numOfPeers++;
|
||||
}else{
|
||||
SS7_ERROR("Peer List excedding max[%d] limit \n", MW_MAX_NUM_OF_PEER);
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
/**********************************************************************/
|
||||
} else {
|
||||
/**********************************************************************/
|
||||
SS7_ERROR("Found an invalid parameter %s!\n", parm->var);
|
||||
return FTDM_FAIL;
|
||||
/**********************************************************************/
|
||||
}
|
||||
|
||||
/* move to the next parameter */
|
||||
parm = parm + 1;
|
||||
/**************************************************************************/
|
||||
} /* for (i = 0; i < num_parms; i++) */
|
||||
|
||||
/* fill in the sng_m2ua_peer interface */
|
||||
ftmod_ss7_fill_in_m2ua_clust_interface(&sng_m2ua_cluster);
|
||||
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
/******************************************************************************/
|
||||
static int ftmod_ss7_fill_in_m2ua_clust_interface(sng_m2ua_cluster_cfg_t *m2ua_cluster_iface)
|
||||
{
|
||||
int k = 0x00;
|
||||
int i = m2ua_cluster_iface->id;
|
||||
|
||||
strncpy((char *)g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_clus[i].name, (char *)m2ua_cluster_iface->name, MAX_NAME_LEN-1);
|
||||
|
||||
g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_clus[i].id = m2ua_cluster_iface->id;
|
||||
g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_clus[i].trfMode = m2ua_cluster_iface->trfMode;
|
||||
g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_clus[i].loadShareAlgo = m2ua_cluster_iface->loadShareAlgo;
|
||||
g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_clus[i].numOfPeers = m2ua_cluster_iface->numOfPeers;
|
||||
for(k=0;k<m2ua_cluster_iface->numOfPeers;k++){
|
||||
g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_clus[i].peerIdLst[k] = m2ua_cluster_iface->peerIdLst[k];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
int ftmod_ss7_parse_sctp_links(ftdm_conf_node_t *node)
|
||||
{
|
||||
ftdm_conf_node_t *node_sctp_link = NULL;
|
||||
|
||||
if (!node)
|
||||
return FTDM_FAIL;
|
||||
|
||||
if (strcasecmp(node->name, "sng_sctp_interfaces")) {
|
||||
SS7_ERROR("SCTP - We're looking at <%s>...but we're supposed to be looking at <sng_sctp_interfaces>!\n", node->name);
|
||||
return FTDM_FAIL;
|
||||
} else {
|
||||
SS7_DEBUG("SCTP - Parsing <sng_sctp_interface> configurations\n");
|
||||
}
|
||||
|
||||
for (node_sctp_link = node->child; node_sctp_link != NULL; node_sctp_link = node_sctp_link->next) {
|
||||
if (ftmod_ss7_parse_sctp_link(node_sctp_link) != FTDM_SUCCESS) {
|
||||
SS7_ERROR("SCTP - Failed to parse <node_sctp_link>. \n");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
static int ftmod_ss7_parse_sctp_link(ftdm_conf_node_t *node)
|
||||
{
|
||||
ftdm_conf_parameter_t *param = NULL;
|
||||
int num_params = 0;
|
||||
int i=0;
|
||||
|
||||
if (!node){
|
||||
SS7_ERROR("SCTP - NULL XML Node pointer \n");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
param = node->parameters;
|
||||
num_params = node->n_parameters;
|
||||
|
||||
sng_sctp_link_t t_link;
|
||||
memset (&t_link, 0, sizeof(sng_sctp_link_t));
|
||||
|
||||
if (strcasecmp(node->name, "sng_sctp_interface")) {
|
||||
SS7_ERROR("SCTP - We're looking at <%s>...but we're supposed to be looking at <sng_sctp_interface>!\n", node->name);
|
||||
return FTDM_FAIL;
|
||||
} else {
|
||||
SS7_DEBUG("SCTP - Parsing <sng_sctp_interface> configurations\n");
|
||||
}
|
||||
|
||||
for (i=0; i<num_params; i++, param++) {
|
||||
if (!strcasecmp(param->var, "name")) {
|
||||
int n_strlen = strlen(param->val);
|
||||
strncpy((char*)t_link.name, param->val, (n_strlen>MAX_NAME_LEN)?MAX_NAME_LEN:n_strlen);
|
||||
SS7_DEBUG("SCTP - Parsing <sng_sctp_interface> with name = %s\n", param->val);
|
||||
}
|
||||
else if (!strcasecmp(param->var, "id")) {
|
||||
t_link.id = atoi(param->val);
|
||||
SS7_DEBUG("SCTP - Parsing <sng_sctp_interface> with id = %s\n", param->val);
|
||||
}
|
||||
else if (!strcasecmp(param->var, "address")) {
|
||||
if (t_link.numSrcAddr < SCT_MAX_NET_ADDRS) {
|
||||
t_link.srcAddrList[t_link.numSrcAddr+1] = iptoul (param->val);
|
||||
t_link.numSrcAddr++;
|
||||
SS7_DEBUG("SCTP - Parsing <sng_sctp_interface> with source IP Address = %s\n", param->val);
|
||||
} else {
|
||||
SS7_ERROR("SCTP - too many source address configured. dropping %s \n", param->val);
|
||||
}
|
||||
} else if (!strcasecmp(param->var, "source-port")) {
|
||||
t_link.port = atoi(param->val);
|
||||
SS7_DEBUG("SCTP - Parsing <sng_sctp_interface> with port = %s\n", param->val);
|
||||
}
|
||||
else {
|
||||
SS7_ERROR("SCTP - Found an unknown parameter <%s>. Skipping it.\n", param->var);
|
||||
}
|
||||
}
|
||||
|
||||
g_ftdm_sngss7_data.cfg.sctpCfg.linkCfg[t_link.id].id = t_link.id;
|
||||
g_ftdm_sngss7_data.cfg.sctpCfg.linkCfg[t_link.id].port = t_link.port;
|
||||
strncpy((char*)g_ftdm_sngss7_data.cfg.sctpCfg.linkCfg[t_link.id].name, t_link.name, strlen(t_link.name) );
|
||||
g_ftdm_sngss7_data.cfg.sctpCfg.linkCfg[t_link.id].numSrcAddr = t_link.numSrcAddr;
|
||||
for (i=1; i<=t_link.numSrcAddr; i++) {
|
||||
g_ftdm_sngss7_data.cfg.sctpCfg.linkCfg[t_link.id].srcAddrList[i] = t_link.srcAddrList[i];
|
||||
}
|
||||
|
||||
sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_SCTP_PRESENT);
|
||||
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
/******************************************************************************/
|
File diff suppressed because it is too large
Load Diff
|
@ -29,6 +29,12 @@
|
|||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
* Contributors:
|
||||
*
|
||||
* James Zhang <jzhang@sangoma.com>
|
||||
*
|
||||
*/
|
||||
/******************************************************************************/
|
||||
#ifndef __FTMOD_SNG_SS7_H__
|
||||
|
@ -46,17 +52,20 @@
|
|||
#include "private/ftdm_core.h"
|
||||
|
||||
#include "sng_ss7/sng_ss7.h"
|
||||
#include "ftmod_sangoma_ss7_m2ua.h"
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
/* DEFINES ********************************************************************/
|
||||
#define MAX_NAME_LEN 25
|
||||
#define MAX_PATH 4096
|
||||
|
||||
#define MAX_CIC_LENGTH 5
|
||||
#define MAX_CIC_MAP_LENGTH 1000
|
||||
#define MAX_SCTP_LINK 100
|
||||
|
||||
#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 +73,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 +99,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 +138,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];
|
||||
|
@ -176,6 +203,21 @@ typedef struct sng_mtp2_link {
|
|||
uint32_t t7;
|
||||
} sng_mtp2_link_t;
|
||||
|
||||
/* defining glare handling methods:
|
||||
SNGSS7_GLARE_PC:
|
||||
higher PointCode controls even number CIC
|
||||
lower PointCode controls odd number CIC
|
||||
SNGSS7_GLARE_DOWN:
|
||||
always give control to the other side
|
||||
SNGSS7_GLARE_CONTROL:
|
||||
always trying to control
|
||||
*/
|
||||
typedef enum {
|
||||
SNGSS7_GLARE_PC = 0,
|
||||
SNGSS7_GLARE_DOWN,
|
||||
SNGSS7_GLARE_CONTROL
|
||||
} sng_glare_resolution;
|
||||
|
||||
typedef struct sng_mtp3_link {
|
||||
char name[MAX_NAME_LEN];
|
||||
uint32_t flags;
|
||||
|
@ -328,6 +370,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 +382,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;
|
||||
|
@ -351,6 +397,7 @@ typedef struct sng_isup_ckt {
|
|||
uint16_t t16;
|
||||
uint16_t t17;
|
||||
uint32_t t35;
|
||||
uint32_t t39;
|
||||
uint16_t tval;
|
||||
} sng_isup_ckt_t;
|
||||
|
||||
|
@ -404,11 +451,34 @@ typedef struct sng_relay {
|
|||
uint32_t procId;
|
||||
} sng_relay_t;
|
||||
|
||||
/**********************************************
|
||||
sctp structures and data definitions
|
||||
**********************************************/
|
||||
|
||||
typedef struct sng_sctp_gen_cfg {
|
||||
} sng_sctp_gen_cfg_t;
|
||||
|
||||
typedef struct sng_sctp_link {
|
||||
char name[MAX_NAME_LEN];
|
||||
uint32_t flags;
|
||||
uint32_t id;
|
||||
uint32_t port;
|
||||
uint32_t numSrcAddr;
|
||||
uint32_t srcAddrList[SCT_MAX_NET_ADDRS+1];
|
||||
} sng_sctp_link_t;
|
||||
|
||||
typedef struct sng_sctp_cfg {
|
||||
sng_sctp_gen_cfg_t genCfg;
|
||||
sng_sctp_link_t linkCfg[MAX_SCTP_LINK+1];
|
||||
} sng_sctp_cfg_t;
|
||||
|
||||
|
||||
|
||||
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];
|
||||
|
@ -421,6 +491,10 @@ typedef struct sng_ss7_cfg {
|
|||
sng_isup_ckt_t isupCkt[10000]; /* KONRAD - only need 2000 ( and 0-1000 aren't used) since other servers are registerd else where */
|
||||
sng_nsap_t nsap[MAX_NSAPS+1];
|
||||
sng_isap_t isap[MAX_ISAPS+1];
|
||||
sng_glare_resolution glareResolution;
|
||||
uint32_t force_inr;
|
||||
sng_m2ua_gbl_cfg_t g_m2ua_cfg;
|
||||
sng_sctp_cfg_t sctpCfg;
|
||||
} sng_ss7_cfg_t;
|
||||
|
||||
typedef struct ftdm_sngss7_data {
|
||||
|
@ -433,6 +507,14 @@ typedef struct ftdm_sngss7_data {
|
|||
fio_signal_cb_t sig_cb;
|
||||
} ftdm_sngss7_data_t;
|
||||
|
||||
typedef enum{
|
||||
SNG_SS7_OPR_MODE_NONE,
|
||||
SNG_SS7_OPR_MODE_M2UA_SG,
|
||||
SNG_SS7_OPR_MODE_ISUP,
|
||||
}ftdm_sngss7_operating_modes_e;
|
||||
|
||||
typedef ftdm_sngss7_operating_modes_e ftdm_sngss7_opr_mode;
|
||||
|
||||
typedef struct sngss7_timer_data {
|
||||
ftdm_timer_id_t hb_timer_id;
|
||||
int beat;
|
||||
|
@ -472,10 +554,14 @@ typedef struct sngss7_chan_data {
|
|||
sngss7_glare_data_t glare;
|
||||
sngss7_timer_data_t t35;
|
||||
sngss7_timer_data_t t10;
|
||||
sngss7_timer_data_t t39;
|
||||
sngss7_group_data_t rx_grs;
|
||||
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;
|
||||
uint8_t peer_event_transfer_cnt;
|
||||
} sngss7_chan_data_t;
|
||||
|
||||
#define SNGSS7_RX_GRS_PENDING (1 << 0)
|
||||
|
@ -533,6 +619,18 @@ 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_INR_TX = (1 << 20),
|
||||
FLAG_INR_SENT = (1 << 21),
|
||||
FLAG_INR_RX = (1 << 22),
|
||||
FLAG_INR_RX_DN = (1 << 23),
|
||||
FLAG_INF_TX = (1 << 24),
|
||||
FLAG_INF_SENT = (1 << 25),
|
||||
FLAG_INF_RX = (1 << 26),
|
||||
FLAG_INF_RX_DN = (1 << 27),
|
||||
FLAG_FULL_NUMBER = (1 << 28),
|
||||
FLAG_RELAY_DOWN = (1 << 30),
|
||||
FLAG_CKT_RECONFIG = (1 << 31)
|
||||
} sng_ckt_flag_t;
|
||||
|
@ -541,20 +639,28 @@ 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", \
|
||||
"INF_RESUME", \
|
||||
"INF_PAUSED", \
|
||||
"TX_ACM_SENT" \
|
||||
"TX_INR" \
|
||||
"INR_SENT" \
|
||||
"RX_INR" \
|
||||
"RX_INR_DN" \
|
||||
"TX_INF" \
|
||||
"INF SENT" \
|
||||
"RX_INF" \
|
||||
"RX_INF_DN" \
|
||||
"RELAY_DOWN", \
|
||||
"CKT_RECONFIG"
|
||||
FTDM_STR2ENUM_P(ftmod_ss7_ckt_state2flag, ftmod_ss7_ckt_flag2str, sng_ckt_flag_t)
|
||||
|
@ -588,7 +694,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 \
|
||||
|
@ -652,11 +758,27 @@ typedef enum {
|
|||
|
||||
SNGSS7_CC_PRESENT = (1 << 12),
|
||||
SNGSS7_CC_STARTED = (1 << 13),
|
||||
|
||||
SNGSS7_TUCL_PRESENT = (1 << 14),
|
||||
SNGSS7_TUCL_STARTED = (1 << 15),
|
||||
|
||||
SNGSS7_SCTP_PRESENT = (1 << 16),
|
||||
SNGSS7_SCTP_STARTED = (1 << 17),
|
||||
|
||||
SNGSS7_M2UA_PRESENT = (1 << 18),
|
||||
SNGSS7_M2UA_STARTED = (1 << 19),
|
||||
SNGSS7_M2UA_EP_OPENED = (1 << 20),
|
||||
SNGSS7_M2UA_INIT_ASSOC_DONE = (1 << 21),
|
||||
|
||||
SNGSS7_NIF_PRESENT = (1 << 22),
|
||||
SNGSS7_NIF_STARTED = (1 << 23),
|
||||
|
||||
} sng_task_flag_t;
|
||||
/******************************************************************************/
|
||||
|
||||
/* GLOBALS ********************************************************************/
|
||||
extern ftdm_sngss7_data_t g_ftdm_sngss7_data;
|
||||
extern ftdm_sngss7_opr_mode g_ftdm_operating_mode;
|
||||
extern sng_ssf_type_t sng_ssf_type_map[];
|
||||
extern sng_switch_type_t sng_switch_type_map[];
|
||||
extern sng_link_type_t sng_link_type_map[];
|
||||
|
@ -679,6 +801,10 @@ void handle_sng_mtp3_alarm(Pst *pst, SnMngmt *sta);
|
|||
void handle_sng_isup_alarm(Pst *pst, SiMngmt *sta);
|
||||
void handle_sng_cc_alarm(Pst *pst, CcMngmt *sta);
|
||||
void handle_sng_relay_alarm(Pst *pst, RyMngmt *sta);
|
||||
void handle_sng_m2ua_alarm(Pst *pst, MwMgmt *sta);
|
||||
void handle_sng_nif_alarm(Pst *pst, NwMgmt *sta);
|
||||
void handle_sng_tucl_alarm(Pst *pst, HiMngmt *sta);
|
||||
void handle_sng_sctp_alarm(Pst *pst, SbMgmt *sta);
|
||||
|
||||
/* in ftmod_sangoma_ss7_relay.c */
|
||||
ftdm_status_t handle_relay_connect(RyMngmt *sta);
|
||||
|
@ -731,7 +857,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);
|
||||
|
||||
|
||||
|
@ -767,6 +895,9 @@ void ft_to_sngss7_cgb(ftdm_channel_t * ftdmchan);
|
|||
void ft_to_sngss7_cgu(ftdm_channel_t * ftdmchan);
|
||||
void ft_to_sngss7_itx (ftdm_channel_t * ftdmchan);
|
||||
void ft_to_sngss7_txa (ftdm_channel_t * ftdmchan);
|
||||
void ft_to_sngss7_inr(ftdm_channel_t * ftdmchan);
|
||||
void ft_to_sngss7_inf(ftdm_channel_t *ftdmchan, SiCnStEvnt *inr);
|
||||
|
||||
|
||||
|
||||
/* in ftmod_sangoma_ss7_in.c */
|
||||
|
@ -835,15 +966,27 @@ 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_ocn_to_sngss7(ftdm_channel_t *ftdmchan, SiOrigCdNum *origCdNum);
|
||||
ftdm_status_t copy_ocn_from_sngss7(ftdm_channel_t *ftdmchan, SiOrigCdNum *origCdNum);
|
||||
|
||||
ftdm_status_t copy_access_transport_from_sngss7(ftdm_channel_t *ftdmchan, SiAccTrnspt *accTrnspt);
|
||||
ftdm_status_t copy_access_transport_to_sngss7(ftdm_channel_t *ftdmchan, SiAccTrnspt *accTrnspt);
|
||||
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);
|
||||
ftdm_status_t copy_cgPtyCat_from_sngss7(ftdm_channel_t *ftdmchan, SiCgPtyCat *cgPtyCat);
|
||||
ftdm_status_t copy_accTrnspt_to_sngss7(ftdm_channel_t *ftdmchan, SiAccTrnspt *accTrnspt);
|
||||
ftdm_status_t copy_natConInd_to_sngss7(ftdm_channel_t *ftdmchan, SiNatConInd *natConInd);
|
||||
ftdm_status_t copy_fwdCallInd_hex_from_sngss7(ftdm_channel_t *ftdmchan, SiFwdCallInd *fwdCallInd);
|
||||
ftdm_status_t copy_fwdCallInd_to_sngss7(ftdm_channel_t *ftdmchan, SiFwdCallInd *fwdCallInd);
|
||||
ftdm_status_t copy_txMedReq_to_sngss7(ftdm_channel_t *ftdmchan, SiTxMedReq *txMedReq);
|
||||
ftdm_status_t copy_usrServInfoA_to_sngss7(ftdm_channel_t *ftdmchan, SiUsrServInfo *usrServInfoA);
|
||||
ftdm_status_t copy_NatureOfConnection_from_sngss7(ftdm_channel_t *ftdmchan, SiNatConInd *natConInd );
|
||||
ftdm_status_t copy_NatureOfConnection_to_sngss7(ftdm_channel_t *ftdmchan, SiNatConInd *natConInd);
|
||||
|
||||
ftdm_status_t copy_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven);
|
||||
ftdm_status_t append_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven);
|
||||
|
@ -889,6 +1032,8 @@ ftdm_status_t sngss7_add_raw_data(sngss7_chan_data_t *sngss7_info, uint8_t* data
|
|||
/* in ftmod_sangoma_ss7_timers.c */
|
||||
void handle_isup_t35(void *userdata);
|
||||
void handle_isup_t10(void *userdata);
|
||||
void handle_isup_t39(void *userdata);
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
@ -910,9 +1055,9 @@ if (ftdmchan->state == new_state) { \
|
|||
#define SS7_INFO_CHAN(fchan, msg, args...) ftdm_log_chan(fchan, FTDM_LOG_INFO, msg , ##args)
|
||||
#define SS7_WARN_CHAN(fchan, msg, args...) ftdm_log_chan(fchan, FTDM_LOG_WARNING, msg , ##args)
|
||||
#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)
|
||||
#define SS7_CRIT_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 +1184,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__)
|
||||
|
|
|
@ -44,8 +44,11 @@
|
|||
/* FUNCTIONS ******************************************************************/
|
||||
void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan)
|
||||
{
|
||||
const char *var = NULL;
|
||||
SiConEvnt iam;
|
||||
ftdm_bool_t native_going_up = FTDM_FALSE;
|
||||
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;;
|
||||
sngss7_event_data_t *event_clone = NULL;
|
||||
|
||||
SS7_FUNC_TRACE_ENTER (__FUNCTION__);
|
||||
|
||||
|
@ -55,9 +58,113 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan)
|
|||
|
||||
memset (&iam, 0x0, sizeof (iam));
|
||||
|
||||
if (sngss7_info->circuit->transparent_iam &&
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_NATIVE_SIGBRIDGE)) {
|
||||
ftdm_span_t *peer_span = NULL;
|
||||
ftdm_channel_t *peer_chan = NULL;
|
||||
sngss7_chan_data_t *peer_info = NULL;
|
||||
|
||||
var = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "sigbridge_peer");
|
||||
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);
|
||||
|
||||
/* retrieve only first message from the others guys queue (must be IAM) */
|
||||
event_clone = ftdm_queue_dequeue(peer_info->event_queue);
|
||||
|
||||
/* make each one of us aware of the native bridge */
|
||||
peer_info->peer_data = sngss7_info;
|
||||
sngss7_info->peer_data = peer_info;
|
||||
|
||||
/* Go to up until release comes, note that state processing is done different and much simpler when there is a peer,
|
||||
We can't go to UP state right away yet though, so do not set the state to UP here, wait until the end of this function
|
||||
because moving from one state to another causes the ftdmchan->usrmsg structure to be wiped
|
||||
and we still need those variables for further IAM processing */
|
||||
native_going_up = FTDM_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_NATIVE_SIGBRIDGE)) {
|
||||
if (!event_clone) {
|
||||
SS7_ERROR_CHAN(ftdmchan, "No IAM 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);
|
||||
}
|
||||
|
||||
if (iam.origCdNum.eh.pres != PRSNT_NODEF) {
|
||||
/* Original Called Number */
|
||||
copy_ocn_to_sngss7(ftdmchan, &iam.origCdNum);
|
||||
}
|
||||
copy_access_transport_to_sngss7(ftdmchan, &iam.accTrnspt);
|
||||
}
|
||||
} 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);
|
||||
|
||||
/* Original Called Number */
|
||||
copy_ocn_to_sngss7(ftdmchan, &iam.origCdNum);
|
||||
|
||||
copy_access_transport_to_sngss7(ftdmchan, &iam.accTrnspt);
|
||||
|
||||
copy_NatureOfConnection_to_sngss7(ftdmchan, &iam.natConInd);
|
||||
} else {
|
||||
/* Nature of Connection Indicators */
|
||||
copy_natConInd_to_sngss7(ftdmchan, &iam.natConInd);
|
||||
|
@ -79,6 +186,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 +198,30 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan)
|
|||
/* Redirecting Number */
|
||||
copy_redirgNum_to_sngss7(ftdmchan, &iam.redirgNum);
|
||||
|
||||
/* Access Transport */
|
||||
/* Redirecting Information */
|
||||
copy_redirgInfo_to_sngss7(ftdmchan, &iam.redirInfo);
|
||||
|
||||
/* Original Called Number */
|
||||
copy_ocn_to_sngss7(ftdmchan, &iam.origCdNum);
|
||||
|
||||
/* Access Transport - old implementation, taking from channel variable of ss7_clg_subaddr */
|
||||
copy_accTrnspt_to_sngss7(ftdmchan, &iam.accTrnspt);
|
||||
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx IAM clg = \"%s\" (NADI=%d), cld = \"%s\" (NADI=%d)\n",
|
||||
/* Access Transport - taking from channel variable of ss7_access_transport_urlenc.
|
||||
This will overwirte the IE value set be above old implementation.
|
||||
*/
|
||||
copy_access_transport_to_sngss7(ftdmchan, &iam.accTrnspt);
|
||||
|
||||
copy_NatureOfConnection_to_sngss7(ftdmchan, &iam.natConInd);
|
||||
|
||||
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,
|
||||
|
@ -106,16 +231,124 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan)
|
|||
&iam,
|
||||
0);
|
||||
|
||||
if (native_going_up) {
|
||||
/*
|
||||
Note that this function (ft_to_sngss7_iam) is run within the main SS7 processing loop in
|
||||
response to the DIALING state handler, we can set the state to UP here and that will
|
||||
implicitly complete the DIALING state, but we *MUST* also advance the state handler
|
||||
right away for a native bridge, otherwise, the processing state function (ftdm_sangoma_ss7_process_state_change)
|
||||
will complete the state without having executed the handler for FTDM_CHANNEL_STATE_UP, and we won't notify
|
||||
the user sending FTDM_SIGEVENT_UP which can cause the application to misbehave (ie, no audio) */
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_UP);
|
||||
ftdm_channel_advance_states(ftdmchan);
|
||||
}
|
||||
|
||||
ftdm_safe_free(event_clone);
|
||||
|
||||
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
void ft_to_sngss7_inf(ftdm_channel_t *ftdmchan, SiCnStEvnt *inr)
|
||||
{
|
||||
SiCnStEvnt evnt;
|
||||
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
||||
|
||||
memset (&evnt, 0x0, sizeof (evnt));
|
||||
|
||||
evnt.infoInd.eh.pres = PRSNT_NODEF;
|
||||
evnt.infoInd.cgPtyAddrRespInd.pres = PRSNT_NODEF;
|
||||
evnt.infoInd.cgPtyCatRespInd.pres = PRSNT_NODEF;
|
||||
|
||||
evnt.infoInd.chrgInfoRespInd.pres = PRSNT_NODEF;
|
||||
evnt.infoInd.chrgInfoRespInd.val = 0;
|
||||
evnt.infoInd.solInfoInd.pres = PRSNT_NODEF;
|
||||
evnt.infoInd.solInfoInd.val = 0;
|
||||
evnt.infoInd.holdProvInd.pres = PRSNT_NODEF;
|
||||
evnt.infoInd.holdProvInd.val = 0;
|
||||
evnt.infoInd.spare.pres = PRSNT_NODEF;
|
||||
evnt.infoInd.spare.val = 0;
|
||||
|
||||
if (inr->infoReqInd.eh.pres == PRSNT_NODEF) {
|
||||
if ((inr->infoReqInd.holdingInd.pres == PRSNT_NODEF) && (inr->infoReqInd.holdingInd.val == HOLD_REQ)) {
|
||||
SS7_DEBUG_CHAN(ftdmchan,"[CIC:%d]Received INR requesting holding information. Holding is not supported in INF.\n", sngss7_info->circuit->cic);
|
||||
}
|
||||
if ((inr->infoReqInd.chrgInfoReqInd.pres == PRSNT_NODEF) && (inr->infoReqInd.chrgInfoReqInd.val == CHRGINFO_REQ)) {
|
||||
SS7_DEBUG_CHAN(ftdmchan,"[CIC:%d]Received INR requesting charging information. Charging is not supported in INF.\n", sngss7_info->circuit->cic);
|
||||
}
|
||||
if ((inr->infoReqInd.malCaIdReqInd.pres == PRSNT_NODEF) && (inr->infoReqInd.malCaIdReqInd.val == CHRGINFO_REQ)) {
|
||||
SS7_DEBUG_CHAN(ftdmchan,"[CIC:%d]Received INR requesting malicious call id. Malicious call id is not supported in INF.\n", sngss7_info->circuit->cic);
|
||||
}
|
||||
|
||||
if ((inr->infoReqInd.cgPtyAdReqInd.pres == PRSNT_NODEF) && (inr->infoReqInd.cgPtyAdReqInd.val == CGPRTYADDREQ_REQ)) {
|
||||
evnt.infoInd.cgPtyAddrRespInd.val=CGPRTYADDRESP_INCL;
|
||||
copy_cgPtyNum_to_sngss7 (ftdmchan, &evnt.cgPtyNum);
|
||||
} else {
|
||||
evnt.infoInd.cgPtyAddrRespInd.val=CGPRTYADDRESP_NOTINCL;
|
||||
}
|
||||
|
||||
if ((inr->infoReqInd.cgPtyCatReqInd.pres == PRSNT_NODEF) && (inr->infoReqInd.cgPtyCatReqInd.val == CGPRTYCATREQ_REQ)) {
|
||||
evnt.infoInd.cgPtyCatRespInd.val = CGPRTYCATRESP_INCL;
|
||||
copy_cgPtyCat_to_sngss7 (ftdmchan, &evnt.cgPtyCat);
|
||||
} else {
|
||||
evnt.infoInd.cgPtyCatRespInd.val = CGPRTYCATRESP_NOTINCL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
SS7_DEBUG_CHAN(ftdmchan,"[CIC:%d]Received INR with no information request. Sending back default INF.\n", sngss7_info->circuit->cic);
|
||||
}
|
||||
|
||||
sng_cc_inf(1,
|
||||
sngss7_info->suInstId,
|
||||
sngss7_info->spInstId,
|
||||
sngss7_info->circuit->id,
|
||||
&evnt,
|
||||
INFORMATION);
|
||||
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx INF\n", sngss7_info->circuit->cic);
|
||||
|
||||
}
|
||||
|
||||
void ft_to_sngss7_inr(ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
SiCnStEvnt evnt;
|
||||
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
||||
|
||||
memset (&evnt, 0x0, sizeof (evnt));
|
||||
|
||||
evnt.infoReqInd.eh.pres = PRSNT_NODEF;
|
||||
evnt.infoReqInd.cgPtyAdReqInd.pres = PRSNT_NODEF;
|
||||
evnt.infoReqInd.cgPtyAdReqInd.val=CGPRTYADDREQ_REQ;
|
||||
|
||||
evnt.infoReqInd.holdingInd.pres = PRSNT_NODEF;
|
||||
evnt.infoReqInd.holdingInd.val = HOLD_REQ;
|
||||
|
||||
evnt.infoReqInd.cgPtyCatReqInd.pres = PRSNT_NODEF;
|
||||
evnt.infoReqInd.cgPtyCatReqInd.val = CGPRTYCATREQ_REQ;
|
||||
|
||||
evnt.infoReqInd.chrgInfoReqInd.pres = PRSNT_NODEF;
|
||||
evnt.infoReqInd.chrgInfoReqInd.val = CHRGINFO_REQ;
|
||||
|
||||
evnt.infoReqInd.malCaIdReqInd.pres = PRSNT_NODEF;
|
||||
evnt.infoReqInd.malCaIdReqInd.val = MLBG_INFOREQ;
|
||||
|
||||
sng_cc_inr(1,
|
||||
sngss7_info->suInstId,
|
||||
sngss7_info->spInstId,
|
||||
sngss7_info->circuit->id,
|
||||
&evnt,
|
||||
INFORMATREQ);
|
||||
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx INR\n", sngss7_info->circuit->cic);
|
||||
}
|
||||
|
||||
void ft_to_sngss7_acm (ftdm_channel_t * ftdmchan)
|
||||
{
|
||||
SS7_FUNC_TRACE_ENTER (__FUNCTION__);
|
||||
|
||||
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
||||
SiCnStEvnt acm;
|
||||
const char *backwardInd = NULL;
|
||||
|
||||
memset (&acm, 0x0, sizeof (acm));
|
||||
|
||||
|
@ -133,8 +366,16 @@ void ft_to_sngss7_acm (ftdm_channel_t * ftdmchan)
|
|||
acm.bckCallInd.intInd.val = INTIND_NOINTW;
|
||||
acm.bckCallInd.end2EndInfoInd.pres = PRSNT_NODEF;
|
||||
acm.bckCallInd.end2EndInfoInd.val = E2EINF_NOINFO;
|
||||
|
||||
acm.bckCallInd.isdnUsrPrtInd.pres = PRSNT_NODEF;
|
||||
acm.bckCallInd.isdnUsrPrtInd.val = ISUP_NOTUSED;
|
||||
backwardInd = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "acm_bi_iup");
|
||||
if (!ftdm_strlen_zero(backwardInd)) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Found user supplied backward indicator ISDN user part indicator ACM, value \"%s\"\n", backwardInd);
|
||||
if (atoi(backwardInd) != 0 ) {
|
||||
acm.bckCallInd.isdnUsrPrtInd.val = ISUP_USED;
|
||||
}
|
||||
}
|
||||
acm.bckCallInd.holdInd.pres = PRSNT_NODEF;
|
||||
acm.bckCallInd.holdInd.val = HOLD_NOTREQD;
|
||||
acm.bckCallInd.isdnAccInd.pres = PRSNT_NODEF;
|
||||
|
@ -241,6 +482,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 +492,15 @@ void ft_to_sngss7_rel (ftdm_channel_t * ftdmchan)
|
|||
|
||||
rel.causeDgn.eh.pres = PRSNT_NODEF;
|
||||
rel.causeDgn.location.pres = PRSNT_NODEF;
|
||||
|
||||
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;
|
||||
|
@ -518,8 +768,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__);
|
||||
|
|
|
@ -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,12 +64,10 @@ 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! */
|
||||
}
|
||||
}
|
||||
return FTDM_SUCCESS;
|
||||
} else if (sng_relay->type == LRY_CT_TCP_SERVER) {
|
||||
ftmod_ss7_enable_grp_mtp3Link(sta->t.usta.s.ryUpUsta.id);
|
||||
|
@ -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:
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -49,7 +49,7 @@
|
|||
/******************************************************************************/
|
||||
|
||||
/* PROTOTYPES *****************************************************************/
|
||||
void handle_isup_t35(void *userdata);
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
@ -76,10 +76,13 @@ void handle_isup_t35(void *userdata)
|
|||
/* end the call */
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_CANCEL);
|
||||
|
||||
/* kill t10 if active */
|
||||
/* kill t10 t39 if active */
|
||||
if (sngss7_info->t10.hb_timer_id) {
|
||||
ftdm_sched_cancel_timer (sngss7_info->t10.sched, sngss7_info->t10.hb_timer_id);
|
||||
}
|
||||
if (sngss7_info->t39.hb_timer_id) {
|
||||
ftdm_sched_cancel_timer (sngss7_info->t39.sched, sngss7_info->t39.hb_timer_id);
|
||||
}
|
||||
|
||||
/*unlock*/
|
||||
ftdm_channel_unlock(ftdmchan);
|
||||
|
@ -109,6 +112,42 @@ void handle_isup_t10(void *userdata)
|
|||
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
}
|
||||
|
||||
void handle_isup_t39(void *userdata)
|
||||
{
|
||||
SS7_FUNC_TRACE_ENTER(__FUNCTION__);
|
||||
|
||||
sngss7_timer_data_t *timer = userdata;
|
||||
sngss7_chan_data_t *sngss7_info = timer->sngss7_info;
|
||||
ftdm_channel_t *ftdmchan = sngss7_info->ftdmchan;
|
||||
|
||||
/* now that we have the right channel...put a lock on it so no-one else can use it */
|
||||
ftdm_channel_lock(ftdmchan);
|
||||
|
||||
/* Q.764 2.2.5 Address incomplete (T35 expiry action is hangup with cause 28 according to Table A.1/Q.764) */
|
||||
SS7_ERROR("[Call-Control] Timer 39 expired on CIC = %d\n", sngss7_info->circuit->cic);
|
||||
|
||||
/* set the flag to indicate this hangup is started from the local side */
|
||||
sngss7_set_ckt_flag(sngss7_info, FLAG_LOCAL_REL);
|
||||
|
||||
/* hang up on timer expiry */
|
||||
ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_INVALID_NUMBER_FORMAT;
|
||||
|
||||
/* end the call */
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_CANCEL);
|
||||
|
||||
/* kill t10 t35 if active */
|
||||
if (sngss7_info->t10.hb_timer_id) {
|
||||
ftdm_sched_cancel_timer (sngss7_info->t10.sched, sngss7_info->t10.hb_timer_id);
|
||||
}
|
||||
if (sngss7_info->t35.hb_timer_id) {
|
||||
ftdm_sched_cancel_timer (sngss7_info->t35.sched, sngss7_info->t35.hb_timer_id);
|
||||
}
|
||||
|
||||
/*unlock*/
|
||||
ftdm_channel_unlock(ftdmchan);
|
||||
|
||||
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
}
|
||||
/******************************************************************************/
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
|
|
|
@ -29,6 +29,12 @@
|
|||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
* Contributors:
|
||||
*
|
||||
* James Zhang <jzhang@sangoma.com>
|
||||
*
|
||||
*/
|
||||
|
||||
/* INCLUDE ********************************************************************/
|
||||
|
@ -124,9 +130,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;
|
||||
|
@ -136,6 +146,7 @@ typedef struct sng_ccSpan
|
|||
uint32_t t16;
|
||||
uint32_t t17;
|
||||
uint32_t t35;
|
||||
uint32_t t39;
|
||||
uint32_t tval;
|
||||
} sng_ccSpan_t;
|
||||
|
||||
|
@ -187,18 +198,20 @@ static int ftmod_ss7_fill_in_self_route(int spc, int linkType, int switchType, i
|
|||
static int ftmod_ss7_fill_in_circuits(sng_span_t *sngSpan);
|
||||
|
||||
static int ftmod_ss7_next_timeslot(char *ch_map, sng_timeslot_t *timeslot);
|
||||
static void ftmod_ss7_set_glare_resolution (const char *method);
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
int ftmod_ss7_parse_xml(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *span)
|
||||
{
|
||||
sng_route_t self_route;
|
||||
sng_span_t sngSpan;
|
||||
int i = 0;
|
||||
const char *var = NULL;
|
||||
const char *val = NULL;
|
||||
ftdm_conf_node_t *ptr = NULL;
|
||||
sng_route_t self_route;
|
||||
sng_span_t sngSpan;
|
||||
|
||||
/* clean out the isup ckt */
|
||||
memset(&sngSpan, 0x0, sizeof(sngSpan));
|
||||
|
@ -206,11 +219,31 @@ int ftmod_ss7_parse_xml(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *spa
|
|||
/* clean out the self route */
|
||||
memset(&self_route, 0x0, sizeof(self_route));
|
||||
|
||||
var = ftdm_parameters[i].var;
|
||||
val = ftdm_parameters[i].val;
|
||||
|
||||
g_ftdm_operating_mode = SNG_SS7_OPR_MODE_ISUP;
|
||||
|
||||
/* confirm that the first parameter is the "operating-mode" */
|
||||
if(!strcasecmp(var, "operating-mode")){
|
||||
if(!strcasecmp(val, "ISUP")) {
|
||||
g_ftdm_operating_mode = SNG_SS7_OPR_MODE_ISUP;
|
||||
}
|
||||
else if(!strcasecmp(val, "M2UA_SG")) {
|
||||
g_ftdm_operating_mode = SNG_SS7_OPR_MODE_M2UA_SG;
|
||||
} else {
|
||||
SS7_DEBUG("Operating mode not specified, defaulting to ISUP\n");
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
var = ftdm_parameters[i].var;
|
||||
val = ftdm_parameters[i].val;
|
||||
ptr = (ftdm_conf_node_t *)ftdm_parameters[i].ptr;
|
||||
|
||||
/* confirm that the first parameter is the "confnode" */
|
||||
/* confirm that the 2nd parameter is the "confnode" */
|
||||
if (!strcasecmp(var, "confnode")) {
|
||||
/* parse the confnode and fill in the global libsng_ss7 config structure */
|
||||
if (ftmod_ss7_parse_sng_isup(ptr)) {
|
||||
|
@ -225,28 +258,20 @@ int ftmod_ss7_parse_xml(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *spa
|
|||
}
|
||||
|
||||
i++;
|
||||
while (ftdm_parameters[i].var != NULL) {
|
||||
/**************************************************************************/
|
||||
|
||||
while (ftdm_parameters[i].var != NULL) {
|
||||
var = ftdm_parameters[i].var;
|
||||
val = ftdm_parameters[i].val;
|
||||
|
||||
if (!strcasecmp(var, "dialplan")) {
|
||||
/**********************************************************************/
|
||||
/* don't care for now */
|
||||
/**********************************************************************/
|
||||
} else if (!strcasecmp(var, "context")) {
|
||||
/**********************************************************************/
|
||||
/* don't care for now */
|
||||
/**********************************************************************/
|
||||
} else if (!strcasecmp(var, "ccSpanId")) {
|
||||
/**********************************************************************/
|
||||
} else if (!strcasecmp(var, "span-id") || !strcasecmp(var, "ccSpanId")) {
|
||||
sngSpan.ccSpanId = atoi(val);
|
||||
SS7_DEBUG("Found an ccSpanId = %d\n",sngSpan.ccSpanId);
|
||||
/**********************************************************************/
|
||||
} else {
|
||||
SS7_ERROR("Unknown parameter found =\"%s\"...ignoring it!\n", var);
|
||||
/**********************************************************************/
|
||||
}
|
||||
|
||||
i++;
|
||||
|
@ -255,11 +280,13 @@ int ftmod_ss7_parse_xml(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *spa
|
|||
/* fill the pointer to span into isupCkt */
|
||||
sngSpan.span = span;
|
||||
|
||||
if(SNG_SS7_OPR_MODE_ISUP == g_ftdm_operating_mode){
|
||||
/* setup the circuits structure */
|
||||
if(ftmod_ss7_fill_in_circuits(&sngSpan)) {
|
||||
SS7_ERROR("Failed to fill in circuits structure!\n");
|
||||
goto ftmod_ss7_parse_xml_error;
|
||||
}
|
||||
}
|
||||
|
||||
return FTDM_SUCCESS;
|
||||
|
||||
|
@ -280,6 +307,11 @@ static int ftmod_ss7_parse_sng_isup(ftdm_conf_node_t *sng_isup)
|
|||
ftdm_conf_node_t *isup_interfaces = NULL;
|
||||
ftdm_conf_node_t *cc_spans = NULL;
|
||||
ftdm_conf_node_t *tmp_node = NULL;
|
||||
ftdm_conf_node_t *nif_ifaces = NULL;
|
||||
ftdm_conf_node_t *m2ua_ifaces = NULL;
|
||||
ftdm_conf_node_t *m2ua_peer_ifaces = NULL;
|
||||
ftdm_conf_node_t *m2ua_clust_ifaces = NULL;
|
||||
ftdm_conf_node_t *sctp_ifaces = NULL;
|
||||
|
||||
/* confirm that we are looking at sng_isup */
|
||||
if (strcasecmp(sng_isup->name, "sng_isup")) {
|
||||
|
@ -385,6 +417,56 @@ static int ftmod_ss7_parse_sng_isup(ftdm_conf_node_t *sng_isup)
|
|||
return FTDM_FAIL;
|
||||
}
|
||||
/**********************************************************************/
|
||||
} else if (!strcasecmp(tmp_node->name, "sng_nif_interfaces")) {
|
||||
/**********************************************************************/
|
||||
if (nif_ifaces == NULL) {
|
||||
nif_ifaces = tmp_node;
|
||||
SS7_DEBUG("Found a \"sng_nif_interfaces\" section!\n");
|
||||
} else {
|
||||
SS7_ERROR("Found a second \"sng_nif_interfaces\" section\n!");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
/**********************************************************************/
|
||||
} else if (!strcasecmp(tmp_node->name, "sng_m2ua_interfaces")) {
|
||||
/**********************************************************************/
|
||||
if (m2ua_ifaces == NULL) {
|
||||
m2ua_ifaces = tmp_node;
|
||||
SS7_DEBUG("Found a \"sng_m2ua_interfaces\" section!\n");
|
||||
} else {
|
||||
SS7_ERROR("Found a second \"sng_m2ua_interfaces\" section\n!");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
/**********************************************************************/
|
||||
} else if (!strcasecmp(tmp_node->name, "sng_m2ua_peer_interfaces")) {
|
||||
/**********************************************************************/
|
||||
if (m2ua_peer_ifaces == NULL) {
|
||||
m2ua_peer_ifaces = tmp_node;
|
||||
SS7_DEBUG("Found a \"sng_m2ua_peer_interfaces\" section!\n");
|
||||
} else {
|
||||
SS7_ERROR("Found a second \"sng_m2ua_peer_interfaces\" section\n!");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
/**********************************************************************/
|
||||
} else if (!strcasecmp(tmp_node->name, "sng_m2ua_cluster_interfaces")) {
|
||||
/**********************************************************************/
|
||||
if (m2ua_clust_ifaces == NULL) {
|
||||
m2ua_clust_ifaces = tmp_node;
|
||||
SS7_DEBUG("Found a \"sng_m2ua_cluster_interfaces\" section!\n");
|
||||
} else {
|
||||
SS7_ERROR("Found a second \"sng_m2ua_peer_interfaces\" section\n!");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
/**********************************************************************/
|
||||
} else if (!strcasecmp(tmp_node->name, "sng_sctp_interfaces")) {
|
||||
/**********************************************************************/
|
||||
if (sctp_ifaces == NULL) {
|
||||
sctp_ifaces = tmp_node;
|
||||
SS7_DEBUG("Found a <sng_sctp_interfaces> section!\n");
|
||||
} else {
|
||||
SS7_ERROR("Found a second <sng_sctp_interfaces> section!\n");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
/**********************************************************************/
|
||||
} else {
|
||||
/**********************************************************************/
|
||||
SS7_ERROR("\tFound an unknown section \"%s\"!\n", tmp_node->name);
|
||||
|
@ -417,7 +499,12 @@ static int ftmod_ss7_parse_sng_isup(ftdm_conf_node_t *sng_isup)
|
|||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
if (ftmod_ss7_parse_mtp3_links(mtp3_links)) {
|
||||
|
||||
switch(g_ftdm_operating_mode)
|
||||
{
|
||||
case SNG_SS7_OPR_MODE_ISUP:
|
||||
{
|
||||
if (mtp3_links && ftmod_ss7_parse_mtp3_links(mtp3_links)) {
|
||||
SS7_ERROR("Failed to parse \"mtp3_links\"!\n");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
@ -432,19 +519,72 @@ static int ftmod_ss7_parse_sng_isup(ftdm_conf_node_t *sng_isup)
|
|||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
if (ftmod_ss7_parse_isup_interfaces(isup_interfaces)) {
|
||||
if (isup_interfaces && ftmod_ss7_parse_isup_interfaces(isup_interfaces)) {
|
||||
SS7_ERROR("Failed to parse \"isup_interfaces\"!\n");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
if (ftmod_ss7_parse_cc_spans(cc_spans)) {
|
||||
if (cc_spans && ftmod_ss7_parse_cc_spans(cc_spans)) {
|
||||
SS7_ERROR("Failed to parse \"cc_spans\"!\n");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SNG_SS7_OPR_MODE_M2UA_SG:
|
||||
{
|
||||
if (ftmod_ss7_parse_sctp_links(sctp_ifaces) != FTDM_SUCCESS) {
|
||||
SS7_ERROR("Failed to parse <sctp_links>!\n");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
if (nif_ifaces && ftmod_ss7_parse_nif_interfaces(nif_ifaces)) {
|
||||
SS7_ERROR("Failed to parse \"nif_ifaces\"!\n");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
if (m2ua_ifaces && ftmod_ss7_parse_m2ua_interfaces(m2ua_ifaces)) {
|
||||
SS7_ERROR("Failed to parse \"m2ua_ifaces\"!\n");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
if (m2ua_peer_ifaces && ftmod_ss7_parse_m2ua_peer_interfaces(m2ua_peer_ifaces)) {
|
||||
SS7_ERROR("Failed to parse \"m2ua_peer_ifaces\"!\n");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
if (m2ua_clust_ifaces && ftmod_ss7_parse_m2ua_clust_interfaces(m2ua_clust_ifaces)) {
|
||||
SS7_ERROR("Failed to parse \"m2ua_clust_ifaces\"!\n");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
SS7_ERROR("Invalid operating mode[%d]\n",g_ftdm_operating_mode);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
static void ftmod_ss7_set_glare_resolution (const char *method)
|
||||
{
|
||||
sng_glare_resolution iMethod=SNGSS7_GLARE_PC;
|
||||
if (!method || (strlen (method) <=0) ) {
|
||||
SS7_ERROR( "Wrong glare resolution parameter, using default. \n" );
|
||||
} else {
|
||||
if (!strcasecmp( method, "PointCode")) {
|
||||
iMethod = SNGSS7_GLARE_PC;
|
||||
} else if (!strcasecmp( method, "Down")) {
|
||||
iMethod = SNGSS7_GLARE_DOWN;
|
||||
} else if (!strcasecmp( method, "Control")) {
|
||||
iMethod = SNGSS7_GLARE_CONTROL;
|
||||
} else {
|
||||
SS7_ERROR( "Wrong glare resolution parameter, using default. \n" );
|
||||
iMethod = SNGSS7_GLARE_PC;
|
||||
}
|
||||
}
|
||||
g_ftdm_sngss7_data.cfg.glareResolution = iMethod;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
static int ftmod_ss7_parse_sng_gen(ftdm_conf_node_t *sng_gen)
|
||||
{
|
||||
|
@ -452,31 +592,41 @@ 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;
|
||||
g_ftdm_sngss7_data.cfg.force_inr = 0;
|
||||
|
||||
/* extract all the information from the parameters */
|
||||
for (i = 0; i < num_parms; i++) {
|
||||
/**************************************************************************/
|
||||
|
||||
if (!strcasecmp(parm->var, "procId")) {
|
||||
/**********************************************************************/
|
||||
g_ftdm_sngss7_data.cfg.procId = atoi(parm->val);
|
||||
SS7_DEBUG("Found a procId = %d\n", g_ftdm_sngss7_data.cfg.procId);
|
||||
/**********************************************************************/
|
||||
} 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");
|
||||
}
|
||||
else if (!strcasecmp(parm->var, "license")) {
|
||||
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);
|
||||
/**********************************************************************/
|
||||
} else if (!strcasecmp(parm->var, "transparent_iam_max_size")) {
|
||||
}
|
||||
else if (!strcasecmp(parm->var, "transparent_iam_max_size")) {
|
||||
g_ftdm_sngss7_data.cfg.transparent_iam_max_size = atoi(parm->val);
|
||||
SS7_DEBUG("Found a transparent_iam max size = %d\n", g_ftdm_sngss7_data.cfg.transparent_iam_max_size);
|
||||
}
|
||||
else if (!strcasecmp(parm->var, "glare-reso")) {
|
||||
ftmod_ss7_set_glare_resolution (parm->val);
|
||||
SS7_DEBUG("Found glare resolution configuration = %d %s\n", g_ftdm_sngss7_data.cfg.glareResolution, parm->val );
|
||||
}
|
||||
else if (!strcasecmp(parm->var, "force-inr")) {
|
||||
if (ftdm_true(parm->val)) {
|
||||
g_ftdm_sngss7_data.cfg.force_inr = 1;
|
||||
} else {
|
||||
/**********************************************************************/
|
||||
g_ftdm_sngss7_data.cfg.force_inr = 0;
|
||||
}
|
||||
SS7_DEBUG("Found INR force configuration = %s\n", parm->val );
|
||||
}
|
||||
else {
|
||||
SS7_ERROR("Found an invalid parameter \"%s\"!\n", parm->val);
|
||||
return FTDM_FAIL;
|
||||
/**********************************************************************/
|
||||
}
|
||||
|
||||
/* move to the next parmeter */
|
||||
|
@ -1845,12 +1995,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 +2011,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 +2064,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 +2115,12 @@ 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);
|
||||
/**********************************************************************/
|
||||
} else if (!strcasecmp(parm->var, "lpa_on_cot")) {
|
||||
/**********************************************************************/
|
||||
if (*parm->val == '1') {
|
||||
|
@ -2002,6 +2177,11 @@ static int ftmod_ss7_parse_cc_span(ftdm_conf_node_t *cc_span)
|
|||
sng_ccSpan.t35 = atoi(parm->val);
|
||||
SS7_DEBUG("Found isup t35 = %d\n",sng_ccSpan.t35);
|
||||
/**********************************************************************/
|
||||
} else if (!strcasecmp(parm->var, "isup.t39")) {
|
||||
/**********************************************************************/
|
||||
sng_ccSpan.t39 = atoi(parm->val);
|
||||
SS7_DEBUG("Found isup t39 = %d\n",sng_ccSpan.t39);
|
||||
/**********************************************************************/
|
||||
} else if (!strcasecmp(parm->var, "isup.tval")) {
|
||||
/**********************************************************************/
|
||||
sng_ccSpan.tval = atoi(parm->val);
|
||||
|
@ -2035,6 +2215,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;
|
||||
|
@ -2723,7 +2908,7 @@ static int ftmod_ss7_fill_in_isap(sng_isap_t *sng_isap)
|
|||
if (sng_isap->t1 != 0) {
|
||||
g_ftdm_sngss7_data.cfg.isap[i].t1 = sng_isap->t1;
|
||||
} else {
|
||||
g_ftdm_sngss7_data.cfg.isap[i].t1 = 200;
|
||||
g_ftdm_sngss7_data.cfg.isap[i].t1 = 150;
|
||||
}
|
||||
if (sng_isap->t2 != 0) {
|
||||
g_ftdm_sngss7_data.cfg.isap[i].t2 = sng_isap->t2;
|
||||
|
@ -2738,17 +2923,17 @@ static int ftmod_ss7_fill_in_isap(sng_isap_t *sng_isap)
|
|||
if (sng_isap->t6 != 0) {
|
||||
g_ftdm_sngss7_data.cfg.isap[i].t6 = sng_isap->t6;
|
||||
} else {
|
||||
g_ftdm_sngss7_data.cfg.isap[i].t6 = 200;
|
||||
g_ftdm_sngss7_data.cfg.isap[i].t6 = 600;
|
||||
}
|
||||
if (sng_isap->t7 != 0) {
|
||||
g_ftdm_sngss7_data.cfg.isap[i].t7 = sng_isap->t7;
|
||||
} else {
|
||||
g_ftdm_sngss7_data.cfg.isap[i].t7 = 250;
|
||||
g_ftdm_sngss7_data.cfg.isap[i].t7 = 200;
|
||||
}
|
||||
if (sng_isap->t8 != 0) {
|
||||
g_ftdm_sngss7_data.cfg.isap[i].t8 = sng_isap->t8;
|
||||
} else {
|
||||
g_ftdm_sngss7_data.cfg.isap[i].t8 = 120;
|
||||
g_ftdm_sngss7_data.cfg.isap[i].t8 = 100;
|
||||
}
|
||||
if (sng_isap->t9 != 0) {
|
||||
g_ftdm_sngss7_data.cfg.isap[i].t9 = sng_isap->t9;
|
||||
|
@ -2863,7 +3048,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 +3057,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 +3070,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;
|
||||
|
@ -2920,11 +3108,15 @@ static int ftmod_ss7_fill_in_ccSpan(sng_ccSpan_t *ccSpan)
|
|||
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].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].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;
|
||||
|
@ -2972,6 +3164,12 @@ static int ftmod_ss7_fill_in_ccSpan(sng_ccSpan_t *ccSpan)
|
|||
} else {
|
||||
g_ftdm_sngss7_data.cfg.isupCkt[x].t35 = ccSpan->t35;
|
||||
}
|
||||
if (ccSpan->t39 == 0) {
|
||||
g_ftdm_sngss7_data.cfg.isupCkt[x].t39 = 120;
|
||||
} else {
|
||||
g_ftdm_sngss7_data.cfg.isupCkt[x].t39 = ccSpan->t39;
|
||||
}
|
||||
|
||||
if (ccSpan->tval == 0) {
|
||||
g_ftdm_sngss7_data.cfg.isupCkt[x].tval = 10;
|
||||
} else {
|
||||
|
@ -3076,6 +3274,13 @@ static int ftmod_ss7_fill_in_circuits(sng_span_t *sngSpan)
|
|||
ss7_info->t10.callback = handle_isup_t10;
|
||||
ss7_info->t10.sngss7_info = ss7_info;
|
||||
|
||||
/* prepare the timer structures */
|
||||
ss7_info->t39.sched = ((sngss7_span_data_t *)(ftdmspan->signal_data))->sched;
|
||||
ss7_info->t39.counter = 1;
|
||||
ss7_info->t39.beat = (isupCkt->t39) * 100; /* beat is in ms, t39 is in 100ms */
|
||||
ss7_info->t39.callback = handle_isup_t39;
|
||||
ss7_info->t39.sngss7_info = ss7_info;
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
} /* for (i == 1; i < ftdmspan->chan_count; i++) */
|
||||
|
|
|
@ -764,6 +764,28 @@ static FIO_COMMAND_FUNCTION(wanpipe_command)
|
|||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Disabled DTMF events\n");
|
||||
#else
|
||||
return FTDM_NOTIMPL;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case FTDM_COMMAND_ENABLE_DTMF_REMOVAL:
|
||||
{
|
||||
#ifdef WP_API_FEATURE_LIBSNG_HWEC
|
||||
int return_code = 0;
|
||||
err = sangoma_hwec_set_hwdtmf_removal(ftdmchan->sockfd, ftdmchan->physical_chan_id, &return_code, 1, 0);
|
||||
if (return_code) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Wanpipe failed to Disable HW-DTMF removal\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case FTDM_COMMAND_DISABLE_DTMF_REMOVAL:
|
||||
{
|
||||
#ifdef WP_API_FEATURE_LIBSNG_HWEC
|
||||
int return_code = 0;
|
||||
err = sangoma_hwec_set_hwdtmf_removal(ftdmchan->sockfd, ftdmchan->physical_chan_id, &return_code, 0, 0);
|
||||
if (return_code) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Wanpipe failed to Disable HW-DTMF removal\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -40,7 +40,6 @@
|
|||
#ifndef FREETDM_H
|
||||
#define FREETDM_H
|
||||
|
||||
|
||||
#include "ftdm_declare.h"
|
||||
#include "ftdm_call_utils.h"
|
||||
|
||||
|
@ -368,6 +367,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*/
|
||||
|
@ -754,6 +754,10 @@ typedef enum {
|
|||
/*!< Enable/disable IO stats in the channel */
|
||||
FTDM_COMMAND_SWITCH_IOSTATS = 60,
|
||||
|
||||
/*!< Enable/disable DTMF removal */
|
||||
FTDM_COMMAND_ENABLE_DTMF_REMOVAL = 61,
|
||||
FTDM_COMMAND_DISABLE_DTMF_REMOVAL = 62,
|
||||
|
||||
FTDM_COMMAND_COUNT,
|
||||
} ftdm_command_t;
|
||||
|
||||
|
@ -1395,7 +1399,7 @@ FT_DECLARE(uint32_t) ftdm_group_get_id(const ftdm_group_t *group);
|
|||
* Only use ftdm_channel_close if there is no call (incoming or outgoing) in the channel
|
||||
*
|
||||
* \param span_id The span id the channel belongs to
|
||||
* \param chan_id Channel id of the channel you want to open
|
||||
* \param chan_id Logical channel id of the channel you want to open
|
||||
* \param ftdmchan Pointer to store the channel once is open
|
||||
*
|
||||
* \retval FTDM_SUCCESS success (the channel was found and is available)
|
||||
|
@ -1403,6 +1407,23 @@ FT_DECLARE(uint32_t) ftdm_group_get_id(const ftdm_group_t *group);
|
|||
*/
|
||||
FT_DECLARE(ftdm_status_t) ftdm_channel_open(uint32_t span_id, uint32_t chan_id, ftdm_channel_t **ftdmchan);
|
||||
|
||||
/*!
|
||||
* \brief Open a channel specifying the span id and physical chan id (required before placing a call on the channel)
|
||||
*
|
||||
* \warning Try using ftdm_call_place instead if you plan to place a call after opening the channel
|
||||
*
|
||||
* \note You must call ftdm_channel_close() or ftdm_channel_call_hangup() to release the channel afterwards
|
||||
* Only use ftdm_channel_close if there is no call (incoming or outgoing) in the channel
|
||||
*
|
||||
* \param span_id The span id the channel belongs to
|
||||
* \param chan_id Physical channel id of the channel you want to open
|
||||
* \param ftdmchan Pointer to store the channel once is open
|
||||
*
|
||||
* \retval FTDM_SUCCESS success (the channel was found and is available)
|
||||
* \retval FTDM_FAIL failure (channel was not found or not available)
|
||||
*/
|
||||
FT_DECLARE(ftdm_status_t) ftdm_channel_open_ph(uint32_t span_id, uint32_t chan_id, ftdm_channel_t **ftdmchan);
|
||||
|
||||
/*!
|
||||
* \brief Hunts and opens a channel specifying the span id only
|
||||
*
|
||||
|
@ -1640,6 +1661,17 @@ FT_DECLARE(ftdm_status_t) ftdm_configure_span(ftdm_span_t *span, const char *typ
|
|||
*/
|
||||
FT_DECLARE(ftdm_status_t) ftdm_configure_span_signaling(ftdm_span_t *span, const char *type, fio_signal_cb_t sig_cb, ftdm_conf_parameter_t *parameters);
|
||||
|
||||
/*!
|
||||
* \brief Register callback to listen for incoming events
|
||||
* \note This function should only be used when there is no signalling module
|
||||
* \param span The span to register to
|
||||
* \param sig_cb The callback that the signaling stack will use to notify about events
|
||||
*
|
||||
* \retval FTDM_SUCCESS success
|
||||
* \retval FTDM_FAIL failure
|
||||
*/
|
||||
FT_DECLARE(ftdm_status_t) ftdm_span_register_signal_cb(ftdm_span_t *span, fio_signal_cb_t sig_cb);
|
||||
|
||||
/*!
|
||||
* \brief Start the span signaling (must call ftdm_configure_span_signaling first)
|
||||
*
|
||||
|
@ -1655,7 +1687,6 @@ FT_DECLARE(ftdm_status_t) ftdm_configure_span_signaling(ftdm_span_t *span, const
|
|||
*/
|
||||
FT_DECLARE(ftdm_status_t) ftdm_span_start(ftdm_span_t *span);
|
||||
|
||||
|
||||
/*!
|
||||
* \brief Stop the span signaling (must call ftdm_span_start first)
|
||||
* \note certain signalings (boost signaling) does not support granular span start/stop
|
||||
|
@ -1796,15 +1827,25 @@ FT_DECLARE(ftdm_trunk_mode_t) ftdm_span_get_trunk_mode(const ftdm_span_t *span);
|
|||
FT_DECLARE(const char *) ftdm_span_get_trunk_mode_str(const ftdm_span_t *span);
|
||||
|
||||
/*!
|
||||
* \brief Return the channel identified by the provided id
|
||||
* \brief Return the channel identified by the provided logical id
|
||||
*
|
||||
* \param span The span where the channel belongs
|
||||
* \param chanid The channel id within the span
|
||||
* \param chanid The logical channel id within the span
|
||||
*
|
||||
* \return The channel pointer if found, NULL otherwise
|
||||
*/
|
||||
FT_DECLARE(ftdm_channel_t *) ftdm_span_get_channel(const ftdm_span_t *span, uint32_t chanid);
|
||||
|
||||
/*!
|
||||
* \brief Return the channel identified by the provided physical id
|
||||
*
|
||||
* \param span The span where the channel belongs
|
||||
* \param chanid The physical channel id within the span
|
||||
*
|
||||
* \return The channel pointer if found, NULL otherwise
|
||||
*/
|
||||
FT_DECLARE(ftdm_channel_t *) ftdm_span_get_channel_ph(const ftdm_span_t *span, uint32_t chanid);
|
||||
|
||||
/*! \brief Return the channel count number for the given span */
|
||||
FT_DECLARE(uint32_t) ftdm_span_get_chan_count(const ftdm_span_t *span);
|
||||
|
||||
|
|
|
@ -126,6 +126,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)
|
||||
|
@ -473,6 +476,7 @@ struct ftdm_channel {
|
|||
int32_t txdrops;
|
||||
int32_t rxdrops;
|
||||
ftdm_usrmsg_t *usrmsg;
|
||||
ftdm_time_t last_state_change_time;
|
||||
};
|
||||
|
||||
struct ftdm_span {
|
||||
|
@ -690,6 +694,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
|
||||
*/
|
||||
|
|
|
@ -162,6 +162,7 @@ typedef enum {
|
|||
FTDM_SIGTYPE_ANALOG,
|
||||
FTDM_SIGTYPE_SANGOMABOOST,
|
||||
FTDM_SIGTYPE_M3UA,
|
||||
FTDM_SIGTYPE_M2UA,
|
||||
FTDM_SIGTYPE_R2,
|
||||
FTDM_SIGTYPE_SS7,
|
||||
FTDM_SIGTYPE_GSM
|
||||
|
@ -198,6 +199,8 @@ typedef enum {
|
|||
FTDM_SPAN_NON_STOPPABLE = (1 << 13),
|
||||
/* If this flag is set, then this span supports TRANSFER state */
|
||||
FTDM_SPAN_USE_TRANSFER = (1 << 14),
|
||||
/* This is the last flag, no more flags bigger than this */
|
||||
FTDM_SPAN_MAX_FLAG = (1 << 15),
|
||||
} ftdm_span_flag_t;
|
||||
|
||||
/*! \brief Channel supported features */
|
||||
|
@ -266,6 +269,12 @@ 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)
|
||||
|
||||
/*!< This no more flags after this flag */
|
||||
#define FTDM_CHANNEL_MAX_FLAG (1ULL << 38)
|
||||
/*!<When adding a new flag, need to update ftdm_io.c:channel_flag_strs */
|
||||
|
||||
#include "ftdm_state.h"
|
||||
|
||||
|
|
Loading…
Reference in New Issue