Merge remote branch 'smgorig/master'
This commit is contained in:
commit
55757c4f77
|
@ -3451,7 +3451,10 @@ void dump_chan(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t *stre
|
|||
const char *chan_type;
|
||||
const char *state;
|
||||
const char *last_state;
|
||||
const char *uuid = NULL;
|
||||
char sessionid[255];
|
||||
float txgain, rxgain;
|
||||
switch_core_session_t *session = NULL;
|
||||
ftdm_alarm_flag_t alarmflag;
|
||||
ftdm_caller_data_t *caller_data;
|
||||
ftdm_channel_t *ftdmchan;
|
||||
|
@ -3461,6 +3464,7 @@ void dump_chan(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t *stre
|
|||
return;
|
||||
}
|
||||
|
||||
strcpy(sessionid, "(none)");
|
||||
ftdmchan = ftdm_span_get_channel(span, chan_id);
|
||||
span_id = ftdm_span_get_id(span);
|
||||
|
||||
|
@ -3475,6 +3479,16 @@ void dump_chan(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t *stre
|
|||
ftdm_channel_get_sig_status(ftdmchan, &sigstatus);
|
||||
ftdm_channel_get_alarms(ftdmchan, &alarmflag);
|
||||
|
||||
uuid = ftdm_channel_get_uuid(ftdmchan, 0);
|
||||
if (!zstr(uuid)) {
|
||||
if (!(session = switch_core_session_locate(uuid))) {
|
||||
snprintf(sessionid, sizeof(sessionid), "%s (dead)", uuid);
|
||||
} else {
|
||||
snprintf(sessionid, sizeof(sessionid), "%s", uuid);
|
||||
switch_core_session_rwunlock(session);
|
||||
}
|
||||
}
|
||||
|
||||
stream->write_function(stream,
|
||||
"span_id: %u\n"
|
||||
"chan_id: %u\n"
|
||||
|
@ -3494,7 +3508,8 @@ void dump_chan(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t *stre
|
|||
"aniII: %s\n"
|
||||
"dnis: %s\n"
|
||||
"rdnis: %s\n"
|
||||
"cause: %s\n\n",
|
||||
"cause: %s\n"
|
||||
"session: %s\n\n",
|
||||
span_id,
|
||||
chan_id,
|
||||
phspan_id,
|
||||
|
@ -3513,7 +3528,8 @@ void dump_chan(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t *stre
|
|||
caller_data->aniII,
|
||||
caller_data->dnis.digits,
|
||||
caller_data->rdnis.digits,
|
||||
switch_channel_cause2str(caller_data->hangup_cause));
|
||||
switch_channel_cause2str(caller_data->hangup_cause),
|
||||
sessionid);
|
||||
}
|
||||
|
||||
void dump_chan_xml(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t *stream)
|
||||
|
@ -3660,7 +3676,12 @@ SWITCH_STANDARD_API(ft_function)
|
|||
if(chan_id > ftdm_span_get_chan_count(span)) {
|
||||
stream->write_function(stream, "-ERR invalid channel\n");
|
||||
} else {
|
||||
char *dbgstr = NULL;
|
||||
ftdm_channel_t *fchan = ftdm_span_get_channel(span, chan_id);
|
||||
dump_chan(span, chan_id, stream);
|
||||
dbgstr = ftdm_channel_get_history_str(fchan);
|
||||
stream->write_function(stream, "%s\n", dbgstr);
|
||||
ftdm_free(dbgstr);
|
||||
}
|
||||
} else {
|
||||
stream->write_function(stream, "+OK\n");
|
||||
|
@ -3989,7 +4010,7 @@ SWITCH_STANDARD_API(ft_function)
|
|||
|
||||
if (rply) {
|
||||
stream->write_function(stream, "%s", rply);
|
||||
free(rply);
|
||||
ftdm_free(rply);
|
||||
} else {
|
||||
stream->write_function(stream, "-ERR Usage: %s\n", FT_SYNTAX);
|
||||
}
|
||||
|
@ -4074,7 +4095,9 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_freetdm_load)
|
|||
|
||||
ftdm_global_set_logger(ftdm_logger);
|
||||
|
||||
ftdm_cpu_monitor_disable();
|
||||
ftdm_global_set_mod_directory(SWITCH_GLOBAL_dirs.mod_dir);
|
||||
|
||||
ftdm_global_set_config_directory(SWITCH_GLOBAL_dirs.conf_dir);
|
||||
|
||||
if (ftdm_global_init() != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "Error loading FreeTDM\n");
|
||||
|
|
|
@ -37,6 +37,27 @@
|
|||
|
||||
#include "private/ftdm_core.h"
|
||||
|
||||
#ifndef FTDM_MOD_DIR
|
||||
#define FTDM_MOD_DIR "."
|
||||
#endif
|
||||
|
||||
#define FTDM_MAX_CONF_DIR 512
|
||||
|
||||
static char g_ftdm_config_dir[FTDM_MAX_CONF_DIR] = FTDM_CONFIG_DIR;
|
||||
static char g_ftdm_mod_dir[FTDM_MAX_CONF_DIR] = FTDM_MOD_DIR;
|
||||
|
||||
FT_DECLARE(void) ftdm_global_set_mod_directory(const char *path)
|
||||
{
|
||||
snprintf(g_ftdm_mod_dir, sizeof(g_ftdm_mod_dir), "%s", path);
|
||||
ftdm_log(FTDM_LOG_DEBUG, "New mod directory: %s\n", g_ftdm_mod_dir);
|
||||
}
|
||||
|
||||
FT_DECLARE(void) ftdm_global_set_config_directory(const char *path)
|
||||
{
|
||||
snprintf(g_ftdm_config_dir, sizeof(g_ftdm_config_dir), "%s", path);
|
||||
ftdm_log(FTDM_LOG_DEBUG, "New config directory: %s\n", g_ftdm_config_dir);
|
||||
}
|
||||
|
||||
int ftdm_config_open_file(ftdm_config_t *cfg, const char *file_path)
|
||||
{
|
||||
FILE *f;
|
||||
|
@ -46,7 +67,7 @@ int ftdm_config_open_file(ftdm_config_t *cfg, const char *file_path)
|
|||
if (file_path[0] == '/') {
|
||||
path = file_path;
|
||||
} else {
|
||||
snprintf(path_buf, sizeof(path_buf), "%s%s%s", FTDM_CONFIG_DIR, FTDM_PATH_SEPARATOR, file_path);
|
||||
snprintf(path_buf, sizeof(path_buf), "%s%s%s", g_ftdm_config_dir, FTDM_PATH_SEPARATOR, file_path);
|
||||
path = path_buf;
|
||||
}
|
||||
|
||||
|
@ -64,7 +85,7 @@ int ftdm_config_open_file(ftdm_config_t *cfg, const char *file_path)
|
|||
int last = -1;
|
||||
char *var, *val;
|
||||
|
||||
snprintf(path_buf, sizeof(path_buf), "%s%sfreetdm.conf", FTDM_CONFIG_DIR, FTDM_PATH_SEPARATOR);
|
||||
snprintf(path_buf, sizeof(path_buf), "%s%sfreetdm.conf", g_ftdm_config_dir, FTDM_PATH_SEPARATOR);
|
||||
path = path_buf;
|
||||
|
||||
if ((f = fopen(path, "r")) == 0) {
|
||||
|
@ -268,13 +289,24 @@ FT_DECLARE(ftdm_status_t) ftdm_conf_node_create(const char *name, ftdm_conf_node
|
|||
if (parent) {
|
||||
/* store who my parent is */
|
||||
newnode->parent = parent;
|
||||
/* save any siblings */
|
||||
sibling = parent->child;
|
||||
/* as a newborn I am first */
|
||||
parent->child = newnode;
|
||||
if (sibling) {
|
||||
/* store a pointer to my next sibling */
|
||||
newnode->next = sibling;
|
||||
|
||||
/* arrange them in FIFO order (newnode should be last) */
|
||||
if (!parent->child) {
|
||||
/* we're the first node being added */
|
||||
parent->child = newnode;
|
||||
} else {
|
||||
if (!parent->last) {
|
||||
/* we're the second node being added */
|
||||
parent->last = newnode;
|
||||
parent->child->next = newnode;
|
||||
newnode->prev = parent->child;
|
||||
} else {
|
||||
/* we're the third or Nth node to be added */
|
||||
sibling = parent->last;
|
||||
sibling->next = newnode;
|
||||
parent->last = newnode;
|
||||
newnode->prev = sibling;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -318,6 +350,26 @@ FT_DECLARE(ftdm_status_t) ftdm_conf_node_destroy(ftdm_conf_node_t *node)
|
|||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
FT_DECLARE(char *) ftdm_build_dso_path(const char *name, char *path, ftdm_size_t len)
|
||||
{
|
||||
#ifdef WIN32
|
||||
const char *ext = ".dll";
|
||||
//const char *EXT = ".DLL";
|
||||
#elif defined (MACOSX) || defined (DARWIN)
|
||||
const char *ext = ".dylib";
|
||||
//const char *EXT = ".DYLIB";
|
||||
#else
|
||||
const char *ext = ".so";
|
||||
//const char *EXT = ".SO";
|
||||
#endif
|
||||
if (*name == *FTDM_PATH_SEPARATOR) {
|
||||
snprintf(path, len, "%s%s", name, ext);
|
||||
} else {
|
||||
snprintf(path, len, "%s%s%s%s", g_ftdm_mod_dir, FTDM_PATH_SEPARATOR, name, ext);
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
* mode:c
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
#endif
|
||||
#include "ftdm_cpu_monitor.h"
|
||||
|
||||
#define FORCE_HANGUP_TIMER 3000
|
||||
#define SPAN_PENDING_CHANS_QUEUE_SIZE 1000
|
||||
#define SPAN_PENDING_SIGNALS_QUEUE_SIZE 1000
|
||||
#define FTDM_READ_TRACE_INDEX 0
|
||||
|
@ -85,6 +86,7 @@ FT_DECLARE(ftdm_time_t) ftdm_current_time_in_ms(void)
|
|||
}
|
||||
|
||||
typedef struct {
|
||||
uint8_t enabled;
|
||||
uint8_t running;
|
||||
uint8_t alarm;
|
||||
uint32_t interval;
|
||||
|
@ -102,6 +104,7 @@ static struct {
|
|||
ftdm_mutex_t *mutex;
|
||||
ftdm_mutex_t *span_mutex;
|
||||
ftdm_mutex_t *group_mutex;
|
||||
ftdm_sched_t *timingsched;
|
||||
uint32_t span_index;
|
||||
uint32_t group_index;
|
||||
uint32_t running;
|
||||
|
@ -110,8 +113,6 @@ static struct {
|
|||
cpu_monitor_t cpu_monitor;
|
||||
} globals;
|
||||
|
||||
static uint8_t ftdm_cpu_monitor_disabled = 0;
|
||||
|
||||
enum ftdm_enum_cpu_alarm_action_flags
|
||||
{
|
||||
FTDM_CPU_ALARM_ACTION_WARN = (1 << 0),
|
||||
|
@ -1291,6 +1292,16 @@ end:
|
|||
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;
|
||||
ftdmchan->history[ftdmchan->hindex].file = file;
|
||||
ftdmchan->history[ftdmchan->hindex].func = func;
|
||||
ftdmchan->history[ftdmchan->hindex].line = line;
|
||||
ftdmchan->history[ftdmchan->hindex].state = ftdmchan->state;
|
||||
ftdmchan->history[ftdmchan->hindex].last_state = ftdmchan->last_state;
|
||||
ftdmchan->history[ftdmchan->hindex].time = ftdm_current_time_in_ms();
|
||||
ftdmchan->hindex++;
|
||||
if (ftdmchan->hindex == ftdm_array_len(ftdmchan->history)) {
|
||||
ftdmchan->hindex = 0;
|
||||
}
|
||||
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE);
|
||||
|
||||
ftdm_mutex_lock(ftdmchan->span->mutex);
|
||||
|
@ -2002,6 +2013,9 @@ static ftdm_status_t call_hangup(ftdm_channel_t *chan, const char *file, const c
|
|||
/* make user's life easier, and just ignore double hangup requests */
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
if (chan->hangup_timer) {
|
||||
ftdm_sched_cancel_timer(globals.timingsched, chan->hangup_timer);
|
||||
}
|
||||
ftdm_channel_set_state(file, func, line, chan, FTDM_CHANNEL_STATE_HANGUP, 1);
|
||||
} else {
|
||||
/* the signaling stack did not touch the state,
|
||||
|
@ -2283,6 +2297,9 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_done(ftdm_channel_t *ftdmchan)
|
|||
close_dtmf_debug(ftdmchan);
|
||||
#endif
|
||||
ftdm_channel_clear_vars(ftdmchan);
|
||||
if (ftdmchan->hangup_timer) {
|
||||
ftdm_sched_cancel_timer(globals.timingsched, ftdmchan->hangup_timer);
|
||||
}
|
||||
|
||||
ftdmchan->init_state = FTDM_CHANNEL_STATE_DOWN;
|
||||
ftdmchan->state = FTDM_CHANNEL_STATE_DOWN;
|
||||
|
@ -3671,6 +3688,102 @@ static struct {
|
|||
ftdm_io_interface_t *pika_interface;
|
||||
} interfaces;
|
||||
|
||||
static void print_channels_by_state(ftdm_stream_handle_t *stream, ftdm_channel_state_t state, int not, int *count)
|
||||
{
|
||||
ftdm_hash_iterator_t *i = NULL;
|
||||
ftdm_span_t *span;
|
||||
ftdm_channel_t *fchan = NULL;
|
||||
ftdm_iterator_t *citer = NULL;
|
||||
ftdm_iterator_t *curr = NULL;
|
||||
const void *key = NULL;
|
||||
void *val = NULL;
|
||||
|
||||
*count = 0;
|
||||
|
||||
ftdm_mutex_lock(globals.mutex);
|
||||
|
||||
for (i = hashtable_first(globals.span_hash); i; i = hashtable_next(i)) {
|
||||
hashtable_this(i, &key, NULL, &val);
|
||||
if (!key || !val) {
|
||||
break;
|
||||
}
|
||||
span = val;
|
||||
citer = ftdm_span_get_chan_iterator(span, NULL);
|
||||
if (!citer) {
|
||||
continue;
|
||||
}
|
||||
for (curr = citer ; curr; curr = ftdm_iterator_next(curr)) {
|
||||
fchan = ftdm_iterator_current(curr);
|
||||
if (not && (fchan->state != state)) {
|
||||
stream->write_function(stream, "[s%dc%d][%d:%d] in state %s\n",
|
||||
fchan->span_id, fchan->chan_id,
|
||||
fchan->physical_span_id, fchan->physical_chan_id, ftdm_channel_state2str(fchan->state));
|
||||
(*count)++;
|
||||
} else if (!not && (fchan->state == state)) {
|
||||
stream->write_function(stream, "[s%dc%d][%d:%d] in state %s\n",
|
||||
fchan->span_id, fchan->chan_id,
|
||||
fchan->physical_span_id, fchan->physical_chan_id, ftdm_channel_state2str(fchan->state));
|
||||
(*count)++;
|
||||
}
|
||||
}
|
||||
ftdm_iterator_free(citer);
|
||||
}
|
||||
|
||||
ftdm_mutex_unlock(globals.mutex);
|
||||
}
|
||||
|
||||
static char *handle_core_command(const char *cmd)
|
||||
{
|
||||
char *mycmd = NULL;
|
||||
int argc = 0;
|
||||
int count = 0;
|
||||
int not = 0;
|
||||
char *argv[10] = { 0 };
|
||||
char *state = NULL;
|
||||
ftdm_channel_state_t i = FTDM_CHANNEL_STATE_INVALID;
|
||||
ftdm_stream_handle_t stream = { 0 };
|
||||
|
||||
FTDM_STANDARD_STREAM(stream);
|
||||
|
||||
if (cmd) {
|
||||
mycmd = ftdm_strdup(cmd);
|
||||
argc = ftdm_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
|
||||
} else {
|
||||
stream.write_function(&stream, "invalid core command\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!strcasecmp(argv[0], "state")) {
|
||||
if (argc < 2) {
|
||||
stream.write_function(&stream, "core state command requires an argument\n");
|
||||
goto done;
|
||||
}
|
||||
state = argv[1];
|
||||
if (argv[1][0] == '!') {
|
||||
not = 1;
|
||||
state++;
|
||||
}
|
||||
for (i = FTDM_CHANNEL_STATE_DOWN; i < FTDM_CHANNEL_STATE_INVALID; i++) {
|
||||
if (!strcasecmp(state, ftdm_channel_state2str(i))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == FTDM_CHANNEL_STATE_INVALID) {
|
||||
stream.write_function(&stream, "invalid state %s\n", state);
|
||||
goto done;
|
||||
}
|
||||
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 {
|
||||
stream.write_function(&stream, "invalid core command %s\n", argv[0]);
|
||||
}
|
||||
|
||||
done:
|
||||
ftdm_safe_free(mycmd);
|
||||
|
||||
return stream.data;
|
||||
}
|
||||
|
||||
FT_DECLARE(char *) ftdm_api_execute(const char *cmd)
|
||||
{
|
||||
ftdm_io_interface_t *fio = NULL;
|
||||
|
@ -3686,6 +3799,10 @@ FT_DECLARE(char *) ftdm_api_execute(const char *cmd)
|
|||
|
||||
type = dup;
|
||||
|
||||
if (!strcasecmp(type, "core")) {
|
||||
return handle_core_command(cmd);
|
||||
}
|
||||
|
||||
ftdm_mutex_lock(globals.mutex);
|
||||
if (!(fio = (ftdm_io_interface_t *) hashtable_search(globals.interface_hash, (void *)type))) {
|
||||
ftdm_load_module_assume(type);
|
||||
|
@ -3986,7 +4103,14 @@ static ftdm_status_t load_config(void)
|
|||
ftdm_log(FTDM_LOG_ERROR, "unknown span variable '%s'\n", var);
|
||||
}
|
||||
} else if (!strncasecmp(cfg.category, "general", 7)) {
|
||||
if (!strncasecmp(var, "cpu_monitoring_interval", sizeof("cpu_monitoring_interval")-1)) {
|
||||
if (!strncasecmp(var, "cpu_monitor", sizeof("cpu_monitor")-1)) {
|
||||
if (!strncasecmp(val, "yes", 3)) {
|
||||
globals.cpu_monitor.enabled = 1;
|
||||
if (!globals.cpu_monitor.alarm_action_flags) {
|
||||
globals.cpu_monitor.alarm_action_flags |= FTDM_CPU_ALARM_ACTION_WARN;
|
||||
}
|
||||
}
|
||||
} else if (!strncasecmp(var, "cpu_monitoring_interval", sizeof("cpu_monitoring_interval")-1)) {
|
||||
if (atoi(val) > 0) {
|
||||
globals.cpu_monitor.interval = atoi(val);
|
||||
} else {
|
||||
|
@ -4065,27 +4189,6 @@ static ftdm_status_t process_module_config(ftdm_io_interface_t *fio)
|
|||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
FT_DECLARE(char *) ftdm_build_dso_path(const char *name, char *path, ftdm_size_t len)
|
||||
{
|
||||
#ifdef WIN32
|
||||
const char *ext = ".dll";
|
||||
//const char *EXT = ".DLL";
|
||||
#define FTDM_MOD_DIR "." //todo
|
||||
#elif defined (MACOSX) || defined (DARWIN)
|
||||
const char *ext = ".dylib";
|
||||
//const char *EXT = ".DYLIB";
|
||||
#else
|
||||
const char *ext = ".so";
|
||||
//const char *EXT = ".SO";
|
||||
#endif
|
||||
if (*name == *FTDM_PATH_SEPARATOR) {
|
||||
snprintf(path, len, "%s%s", name, ext);
|
||||
} else {
|
||||
snprintf(path, len, "%s%s%s%s", FTDM_MOD_DIR, FTDM_PATH_SEPARATOR, name, ext);
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
FT_DECLARE(ftdm_status_t) ftdm_global_add_io_interface(ftdm_io_interface_t *interface1)
|
||||
{
|
||||
ftdm_status_t ret = FTDM_SUCCESS;
|
||||
|
@ -4601,6 +4704,21 @@ FT_DECLARE(ftdm_status_t) ftdm_span_trigger_signals(const ftdm_span_t *span)
|
|||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static void execute_safety_hangup(void *data)
|
||||
{
|
||||
ftdm_channel_t *fchan = 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);
|
||||
call_hangup(fchan, __FILE__, __FUNCTION__, __LINE__);
|
||||
} else {
|
||||
ftdm_log_chan(fchan, FTDM_LOG_CRIT, "Not performing safety hangup, channel state is %s\n", ftdm_channel_state2str(fchan->state));
|
||||
}
|
||||
ftdm_channel_unlock(fchan);
|
||||
}
|
||||
|
||||
FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t *sigmsg)
|
||||
{
|
||||
if (sigmsg->channel) {
|
||||
|
@ -4634,6 +4752,11 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t
|
|||
ftdm_log_chan_msg(sigmsg->channel, FTDM_LOG_DEBUG, "Ignoring SIGEVENT_STOP since user already requested hangup\n");
|
||||
goto done;
|
||||
}
|
||||
if (sigmsg->channel->state == FTDM_CHANNEL_STATE_TERMINATING) {
|
||||
ftdm_log_chan_msg(sigmsg->channel, FTDM_LOG_DEBUG, "Scheduling safety hangup timer\n");
|
||||
/* if the user does not move us to hangup in 2 seconds, we will do it ourselves */
|
||||
ftdm_sched_timer(globals.timingsched, "safety-hangup", FORCE_HANGUP_TIMER, execute_safety_hangup, sigmsg->channel, &sigmsg->channel->hangup_timer);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -4732,12 +4855,6 @@ static void ftdm_cpu_monitor_stop(void)
|
|||
ftdm_interrupt_destroy(&globals.cpu_monitor.interrupt);
|
||||
}
|
||||
|
||||
FT_DECLARE(void) ftdm_cpu_monitor_disable(void)
|
||||
{
|
||||
ftdm_cpu_monitor_disabled = 1;
|
||||
}
|
||||
|
||||
|
||||
FT_DECLARE(ftdm_status_t) ftdm_global_init(void)
|
||||
{
|
||||
memset(&globals, 0, sizeof(globals));
|
||||
|
@ -4755,6 +4872,14 @@ FT_DECLARE(ftdm_status_t) ftdm_global_init(void)
|
|||
ftdm_mutex_create(&globals.span_mutex);
|
||||
ftdm_mutex_create(&globals.group_mutex);
|
||||
ftdm_sched_global_init();
|
||||
if (ftdm_sched_create(&globals.timingsched, "freetdm-master") != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Failed to create master timing schedule context\n");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
if (ftdm_sched_free_run(globals.timingsched) != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Failed to run master timing schedule context\n");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
globals.running = 1;
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
@ -4771,8 +4896,9 @@ FT_DECLARE(ftdm_status_t) ftdm_global_configuration(void)
|
|||
|
||||
ftdm_log(FTDM_LOG_NOTICE, "Modules configured: %d \n", modcount);
|
||||
|
||||
globals.cpu_monitor.enabled = 0;
|
||||
globals.cpu_monitor.interval = 1000;
|
||||
globals.cpu_monitor.alarm_action_flags = FTDM_CPU_ALARM_ACTION_WARN | FTDM_CPU_ALARM_ACTION_REJECT;
|
||||
globals.cpu_monitor.alarm_action_flags = 0;
|
||||
globals.cpu_monitor.set_alarm_threshold = 80;
|
||||
globals.cpu_monitor.reset_alarm_threshold = 70;
|
||||
|
||||
|
@ -4782,7 +4908,12 @@ FT_DECLARE(ftdm_status_t) ftdm_global_configuration(void)
|
|||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
if (!ftdm_cpu_monitor_disabled) {
|
||||
if (globals.cpu_monitor.enabled) {
|
||||
ftdm_log(FTDM_LOG_INFO, "CPU Monitor is running interval:%d lo-thres:%d hi-thres:%d\n",
|
||||
globals.cpu_monitor.interval,
|
||||
globals.cpu_monitor.set_alarm_threshold,
|
||||
globals.cpu_monitor.reset_alarm_threshold);
|
||||
|
||||
if (ftdm_cpu_monitor_start() != FTDM_SUCCESS) {
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
@ -4807,6 +4938,8 @@ FT_DECLARE(ftdm_status_t) ftdm_global_destroy(void)
|
|||
|
||||
globals.running = 0;
|
||||
|
||||
ftdm_sched_destroy(&globals.timingsched);
|
||||
|
||||
ftdm_cpu_monitor_stop();
|
||||
|
||||
globals.span_index = 0;
|
||||
|
@ -5175,6 +5308,42 @@ FT_DECLARE(char *) ftdm_strndup(const char *str, ftdm_size_t inlen)
|
|||
return new;
|
||||
}
|
||||
|
||||
FT_DECLARE(char *) ftdm_channel_get_history_str(const ftdm_channel_t *fchan)
|
||||
{
|
||||
char func[255];
|
||||
char line[255];
|
||||
char states[255];
|
||||
uint8_t i = 0;
|
||||
|
||||
ftdm_stream_handle_t stream = { 0 };
|
||||
FTDM_STANDARD_STREAM(stream);
|
||||
if (!fchan->history[0].file) {
|
||||
stream.write_function(&stream, "-- No state history --\n");
|
||||
return stream.data;
|
||||
}
|
||||
|
||||
stream.write_function(&stream, "%-30.30s %-30.30s %s", "-- States --", "-- Function --", "-- Location --\n");
|
||||
|
||||
for (i = fchan->hindex; i < ftdm_array_len(fchan->history); i++) {
|
||||
if (!fchan->history[i].file) {
|
||||
break;
|
||||
}
|
||||
snprintf(states, sizeof(states), "%-5.15s => %-5.15s", ftdm_channel_state2str(fchan->history[i].last_state), ftdm_channel_state2str(fchan->history[i].state));
|
||||
snprintf(func, sizeof(func), "[%s]", fchan->history[i].func);
|
||||
snprintf(line, sizeof(func), "[%s:%d]", fchan->history[i].file, fchan->history[i].line);
|
||||
stream.write_function(&stream, "%-30.30s %-30.30s %s\n", states, func, line);
|
||||
}
|
||||
|
||||
for (i = 0; i < fchan->hindex; i++) {
|
||||
snprintf(states, sizeof(states), "%-5.15s => %-5.15s", ftdm_channel_state2str(fchan->history[i].last_state), ftdm_channel_state2str(fchan->history[i].state));
|
||||
snprintf(func, sizeof(func), "[%s]", fchan->history[i].func);
|
||||
snprintf(line, sizeof(func), "[%s:%d]", fchan->history[i].file, fchan->history[i].line);
|
||||
stream.write_function(&stream, "%-30.30s %-30.30s %s\n", states, func, line);
|
||||
}
|
||||
|
||||
return stream.data;
|
||||
}
|
||||
|
||||
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
|
|
|
@ -34,6 +34,8 @@
|
|||
|
||||
#include "private/ftdm_core.h"
|
||||
|
||||
typedef struct ftdm_timer ftdm_timer_t;
|
||||
|
||||
static struct {
|
||||
ftdm_sched_t *freeruns;
|
||||
ftdm_mutex_t *mutex;
|
||||
|
@ -42,6 +44,7 @@ static struct {
|
|||
|
||||
struct ftdm_sched {
|
||||
char name[80];
|
||||
ftdm_timer_id_t currid;
|
||||
ftdm_mutex_t *mutex;
|
||||
ftdm_timer_t *timers;
|
||||
int freerun;
|
||||
|
@ -51,6 +54,7 @@ struct ftdm_sched {
|
|||
|
||||
struct ftdm_timer {
|
||||
char name[80];
|
||||
ftdm_timer_id_t id;
|
||||
#ifdef __linux__
|
||||
struct timeval time;
|
||||
#endif
|
||||
|
@ -191,6 +195,7 @@ FT_DECLARE(ftdm_status_t) ftdm_sched_create(ftdm_sched_t **sched, const char *na
|
|||
}
|
||||
|
||||
ftdm_set_string(newsched->name, name);
|
||||
newsched->currid = 1;
|
||||
|
||||
*sched = newsched;
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Created schedule %s\n", name);
|
||||
|
@ -219,12 +224,13 @@ FT_DECLARE(ftdm_status_t) ftdm_sched_run(ftdm_sched_t *sched)
|
|||
int rc = -1;
|
||||
void *data;
|
||||
struct timeval now;
|
||||
|
||||
ftdm_assert_return(sched != NULL, FTDM_EINVAL, "sched is null!\n");
|
||||
|
||||
ftdm_mutex_lock(sched->mutex);
|
||||
|
||||
tryagain:
|
||||
|
||||
ftdm_mutex_lock(sched->mutex);
|
||||
|
||||
rc = gettimeofday(&now, NULL);
|
||||
if (rc == -1) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "Failed to retrieve time of day\n");
|
||||
|
@ -257,11 +263,16 @@ tryagain:
|
|||
runtimer->prev->next = runtimer->next;
|
||||
}
|
||||
|
||||
runtimer->id = 0;
|
||||
ftdm_safe_free(runtimer);
|
||||
|
||||
/* avoid deadlocks by releasing the sched lock before triggering callbacks */
|
||||
ftdm_mutex_unlock(sched->mutex);
|
||||
|
||||
callback(data);
|
||||
/* after calling a callback we must start the scanning again since the
|
||||
* callback may have added or cancelled timers to the linked list */
|
||||
* callback or some other thread may have added or cancelled timers to
|
||||
* the linked list */
|
||||
goto tryagain;
|
||||
}
|
||||
}
|
||||
|
@ -283,7 +294,7 @@ done:
|
|||
}
|
||||
|
||||
FT_DECLARE(ftdm_status_t) ftdm_sched_timer(ftdm_sched_t *sched, const char *name,
|
||||
int ms, ftdm_sched_callback_t callback, void *data, ftdm_timer_t **timer)
|
||||
int ms, ftdm_sched_callback_t callback, void *data, ftdm_timer_id_t *timerid)
|
||||
{
|
||||
ftdm_status_t status = FTDM_FAIL;
|
||||
#ifdef __linux__
|
||||
|
@ -296,8 +307,8 @@ FT_DECLARE(ftdm_status_t) ftdm_sched_timer(ftdm_sched_t *sched, const char *name
|
|||
ftdm_assert_return(callback != NULL, FTDM_EINVAL, "sched callback is null!\n");
|
||||
ftdm_assert_return(ms > 0, FTDM_EINVAL, "milliseconds must be bigger than 0!\n");
|
||||
|
||||
if (timer) {
|
||||
*timer = NULL;
|
||||
if (timerid) {
|
||||
*timerid = 0;
|
||||
}
|
||||
|
||||
rc = gettimeofday(&now, NULL);
|
||||
|
@ -312,6 +323,15 @@ FT_DECLARE(ftdm_status_t) ftdm_sched_timer(ftdm_sched_t *sched, const char *name
|
|||
if (!newtimer) {
|
||||
goto done;
|
||||
}
|
||||
newtimer->id = sched->currid;
|
||||
sched->currid++;
|
||||
if (!sched->currid) {
|
||||
ftdm_log(FTDM_LOG_NOTICE, "Timer id wrap around for sched %s\n", sched->name);
|
||||
/* we do not want currid to be zero since is an invalid id
|
||||
* TODO: check that currid does not exists already in the context, it'd be insane
|
||||
* though, having a timer to live all that time */
|
||||
sched->currid++;
|
||||
}
|
||||
|
||||
ftdm_set_string(newtimer->name, name);
|
||||
newtimer->callback = callback;
|
||||
|
@ -332,9 +352,10 @@ FT_DECLARE(ftdm_status_t) ftdm_sched_timer(ftdm_sched_t *sched, const char *name
|
|||
sched->timers = newtimer;
|
||||
}
|
||||
|
||||
if (timer) {
|
||||
*timer = newtimer;
|
||||
if (timerid) {
|
||||
*timerid = newtimer->id;
|
||||
}
|
||||
|
||||
status = FTDM_SUCCESS;
|
||||
done:
|
||||
|
||||
|
@ -418,53 +439,37 @@ done:
|
|||
return status;
|
||||
}
|
||||
|
||||
FT_DECLARE(ftdm_status_t) ftdm_sched_cancel_timer(ftdm_sched_t *sched, ftdm_timer_t **intimer)
|
||||
FT_DECLARE(ftdm_status_t) ftdm_sched_cancel_timer(ftdm_sched_t *sched, ftdm_timer_id_t timerid)
|
||||
{
|
||||
ftdm_status_t status = FTDM_FAIL;
|
||||
ftdm_timer_t *timer;
|
||||
|
||||
ftdm_assert_return(sched != NULL, FTDM_EINVAL, "sched is null!\n");
|
||||
ftdm_assert_return(intimer != NULL, FTDM_EINVAL, "timer is null!\n");
|
||||
ftdm_assert_return(*intimer != NULL, FTDM_EINVAL, "timer is null!\n");
|
||||
|
||||
if (!timerid) {
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
ftdm_mutex_lock(sched->mutex);
|
||||
|
||||
/* special case where the cancelled timer is the head */
|
||||
if (*intimer == sched->timers) {
|
||||
timer = *intimer;
|
||||
/* the timer next is the new head (even if that means the new head will be NULL)*/
|
||||
sched->timers = timer->next;
|
||||
/* if there is a new head, clean its prev member */
|
||||
if (sched->timers) {
|
||||
sched->timers->prev = NULL;
|
||||
}
|
||||
/* free the old head */
|
||||
ftdm_safe_free(timer);
|
||||
status = FTDM_SUCCESS;
|
||||
*intimer = NULL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* look for the timer and destroy it (we know now that is not head, se we start at the next member after head) */
|
||||
for (timer = sched->timers->next; timer; timer = timer->next) {
|
||||
if (timer == *intimer) {
|
||||
/* look for the timer and destroy it */
|
||||
for (timer = sched->timers; timer; timer = timer->next) {
|
||||
if (timer->id == timerid) {
|
||||
if (timer == sched->timers) {
|
||||
/* it's the head timer, put a new head */
|
||||
sched->timers = timer->next;
|
||||
}
|
||||
if (timer->prev) {
|
||||
timer->prev->next = timer->next;
|
||||
}
|
||||
if (timer->next) {
|
||||
timer->next->prev = timer->prev;
|
||||
}
|
||||
ftdm_log(FTDM_LOG_DEBUG, "cancelled timer %s\n", timer->name);
|
||||
ftdm_safe_free(timer);
|
||||
status = FTDM_SUCCESS;
|
||||
*intimer = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
done:
|
||||
if (status == FTDM_FAIL) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "Could not find timer %s to cancel it\n", (*intimer)->name);
|
||||
}
|
||||
|
||||
ftdm_mutex_unlock(sched->mutex);
|
||||
|
||||
|
|
|
@ -156,7 +156,7 @@ typedef struct sngisdn_chan_data {
|
|||
|
||||
uint8_t globalFlg;
|
||||
sngisdn_glare_data_t glare;
|
||||
ftdm_timer_t *timers[SNGISDN_NUM_TIMERS];
|
||||
ftdm_timer_id_t timers[SNGISDN_NUM_TIMERS];
|
||||
} sngisdn_chan_data_t;
|
||||
|
||||
/* Span specific data */
|
||||
|
|
|
@ -611,6 +611,7 @@ ftdm_status_t sng_isdn_stack_cfg_q931_dlsap(ftdm_span_t *span)
|
|||
|
||||
cfg.hdr.response.selector=0;
|
||||
|
||||
|
||||
cfg.t.cfg.s.inDLSAP.sapId = signal_data->link_id;
|
||||
cfg.t.cfg.s.inDLSAP.spId = signal_data->link_id;
|
||||
cfg.t.cfg.s.inDLSAP.swtch = sng_isdn_stack_switchtype(signal_data->switchtype);
|
||||
|
|
|
@ -131,14 +131,12 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
|
|||
}
|
||||
|
||||
|
||||
if (conEvnt->facilityStr.eh.pres) {
|
||||
if (signal_data->facility == SNGISDN_OPT_TRUE && conEvnt->facilityStr.eh.pres) {
|
||||
/* Verify whether the Caller Name will come in a subsequent FACILITY message */
|
||||
uint16_t ret_val;
|
||||
uint8_t facility_str[255];
|
||||
char retrieved_str[255];
|
||||
memcpy(facility_str, (uint8_t*)&conEvnt->facilityStr.facilityStr.val, conEvnt->facilityStr.facilityStr.len);
|
||||
|
||||
ret_val = sng_isdn_retrieve_facility_caller_name(facility_str, conEvnt->facilityStr.facilityStr.len, retrieved_str);
|
||||
ret_val = sng_isdn_retrieve_facility_caller_name(conEvnt->facilityStr.facilityStr.val, conEvnt->facilityStr.facilityStr.len, retrieved_str);
|
||||
/*
|
||||
return values for "sng_isdn_retrieve_facility_information_following":
|
||||
If there will be no information following, or fails to decode IE, returns -1
|
||||
|
@ -151,7 +149,8 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
|
|||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_GET_CALLERID);
|
||||
/* Launch timer in case we never get a FACILITY msg */
|
||||
if (signal_data->facility_timeout) {
|
||||
ftdm_sched_timer(signal_data->sched, "facility_timeout", signal_data->facility_timeout, sngisdn_facility_timeout, (void*) sngisdn_info, &sngisdn_info->timers[SNGISDN_TIMER_FACILITY]);
|
||||
ftdm_sched_timer(signal_data->sched, "facility_timeout", signal_data->facility_timeout,
|
||||
sngisdn_facility_timeout, (void*) sngisdn_info, &sngisdn_info->timers[SNGISDN_TIMER_FACILITY]);
|
||||
}
|
||||
break;
|
||||
} else if (ret_val == 0) {
|
||||
|
@ -702,14 +701,23 @@ void sngisdn_process_fac_ind (sngisdn_event_data_t *sngisdn_event)
|
|||
case FTDM_CHANNEL_STATE_GET_CALLERID:
|
||||
/* Update the caller ID Name */
|
||||
if (facEvnt->facElmt.facStr.pres) {
|
||||
uint8_t facility_str[255];
|
||||
memcpy(facility_str, (uint8_t*)&facEvnt->facElmt.facStr.val, facEvnt->facElmt.facStr.len);
|
||||
char retrieved_str[255];
|
||||
if (sng_isdn_retrieve_facility_caller_name(facility_str, facEvnt->facElmt.facStr.len, retrieved_str) != FTDM_SUCCESS) {
|
||||
|
||||
/* return values for "sng_isdn_retrieve_facility_information_following":
|
||||
If there will be no information following, or fails to decode IE, returns -1
|
||||
If there will be no information following, but current FACILITY IE contains a caller name, returns 0
|
||||
If there will be information following, returns 1
|
||||
*/
|
||||
|
||||
if (sng_isdn_retrieve_facility_caller_name(&facEvnt->facElmt.facStr.val[2], facEvnt->facElmt.facStr.len, retrieved_str) == 0) {
|
||||
strcpy(ftdmchan->caller_data.cid_name, retrieved_str);
|
||||
} else {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Failed to retrieve Caller Name from Facility IE\n");
|
||||
}
|
||||
/* Cancel facility timeout */
|
||||
ftdm_sched_cancel_timer(signal_data->sched, &sngisdn_info->timers[SNGISDN_TIMER_FACILITY]);
|
||||
if (signal_data->facility_timeout) {
|
||||
/* Cancel facility timeout */
|
||||
ftdm_sched_cancel_timer(signal_data->sched, sngisdn_info->timers[SNGISDN_TIMER_FACILITY]);
|
||||
}
|
||||
}
|
||||
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING);
|
||||
|
@ -884,6 +892,22 @@ void sngisdn_process_sta_cfm (sngisdn_event_data_t *sngisdn_event)
|
|||
break;
|
||||
}
|
||||
break;
|
||||
case 9: /* Remote switch is in "Incoming call proceeding" state */
|
||||
switch (ftdmchan->state) {
|
||||
case FTDM_CHANNEL_STATE_PROGRESS:
|
||||
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
|
||||
case FTDM_CHANNEL_STATE_GET_CALLERID:
|
||||
/* Do nothing */
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_UP:
|
||||
/* Remote switch missed our CONNECT message, re-send */
|
||||
ftdm_sched_timer(((sngisdn_span_data_t*)ftdmchan->span->signal_data)->sched, "delayed_connect", 1, sngisdn_delayed_connect, (void*) sngisdn_info, NULL);
|
||||
break;
|
||||
default:
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle incompatible state. remote call state:%d our state:%s\n", call_state, ftdm_channel_state2str(ftdmchan->state));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 10: /* Remote switch is in active state */
|
||||
switch (ftdmchan->state) {
|
||||
case FTDM_CHANNEL_STATE_UP:
|
||||
|
@ -899,17 +923,6 @@ void sngisdn_process_sta_cfm (sngisdn_event_data_t *sngisdn_event)
|
|||
break;
|
||||
}
|
||||
break;
|
||||
case 9:
|
||||
switch (ftdmchan->state) {
|
||||
case FTDM_CHANNEL_STATE_PROGRESS:
|
||||
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
|
||||
/* Do nothing */
|
||||
break;
|
||||
default:
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle incompatible state. remote call state:%d our state:%s\n", call_state, ftdm_channel_state2str(ftdmchan->state));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 22:
|
||||
switch (ftdmchan->state) {
|
||||
case FTDM_CHANNEL_STATE_UP:
|
||||
|
|
|
@ -1506,6 +1506,10 @@ static ftdm_status_t handle_tx_cgb(ftdm_stream_handle_t *stream, int span, int c
|
|||
sngss7_span_data_t *sngss7_span;
|
||||
int byte = 0;
|
||||
int bit = 0;
|
||||
ftdm_sigmsg_t sigev;
|
||||
|
||||
memset (&sigev, 0, sizeof (sigev));
|
||||
|
||||
|
||||
if (range > 31) {
|
||||
stream->write_function(stream, "Invalid range value %d", range);
|
||||
|
@ -1531,6 +1535,14 @@ static ftdm_status_t handle_tx_cgb(ftdm_stream_handle_t *stream, int span, int c
|
|||
/* throw the grp maint. block flag */
|
||||
sngss7_set_flag(sngss7_info, FLAG_GRP_MN_BLOCK_TX);
|
||||
|
||||
/* bring the sig status down */
|
||||
sigev.chan_id = ftdmchan->chan_id;
|
||||
sigev.span_id = ftdmchan->span_id;
|
||||
sigev.channel = ftdmchan;
|
||||
sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
|
||||
sigev.sigstatus = FTDM_SIG_STATE_DOWN;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
|
||||
/* if this is the first channel in the range */
|
||||
if (ftdmchan->physical_chan_id == chan) {
|
||||
/* attach the cgb information */
|
||||
|
@ -1575,6 +1587,10 @@ static ftdm_status_t handle_tx_cgu(ftdm_stream_handle_t *stream, int span, int c
|
|||
sngss7_span_data_t *sngss7_span;
|
||||
int byte = 0;
|
||||
int bit = 0;
|
||||
ftdm_sigmsg_t sigev;
|
||||
|
||||
memset (&sigev, 0, sizeof (sigev));
|
||||
|
||||
|
||||
if (range > 31) {
|
||||
stream->write_function(stream, "Invalid range value %d", range);
|
||||
|
@ -1600,6 +1616,14 @@ static ftdm_status_t handle_tx_cgu(ftdm_stream_handle_t *stream, int span, int c
|
|||
/* throw the grp maint. block flag */
|
||||
sngss7_clear_flag(sngss7_info, FLAG_GRP_MN_BLOCK_TX);
|
||||
|
||||
/* bring the sig status up */
|
||||
sigev.chan_id = ftdmchan->chan_id;
|
||||
sigev.span_id = ftdmchan->span_id;
|
||||
sigev.channel = ftdmchan;
|
||||
sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
|
||||
sigev.sigstatus = FTDM_SIG_STATE_UP;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
|
||||
/* if this is the first channel in the range */
|
||||
if (ftdmchan->physical_chan_id == chan) {
|
||||
/* attach the cgb information */
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -496,6 +496,12 @@ void handle_sng_isup_alarm(Pst *pst, SiMngmt *sta)
|
|||
/* initalize the msg variable to NULLs */
|
||||
memset(&msg[0], '\0', sizeof(&msg));
|
||||
|
||||
/* if the event is REMOTE/LOCAL we don't need to print these */
|
||||
if ((sta->t.usta.alarm.event == LSI_EVENT_REMOTE) ||
|
||||
(sta->t.usta.alarm.event == LSI_EVENT_LOCAL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* point p to the first spot in msg */
|
||||
p = &msg[0];
|
||||
|
@ -728,6 +734,8 @@ void handle_sng_isup_alarm(Pst *pst, SiMngmt *sta)
|
|||
DECODE_LSI_EVENT(sta->t.usta.alarm.event),
|
||||
DECODE_LSI_CAUSE(sta->t.usta.alarm.cause));
|
||||
|
||||
return;
|
||||
|
||||
} /* handle_isup_alarm */
|
||||
|
||||
/******************************************************************************/
|
||||
|
|
|
@ -454,9 +454,9 @@ static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_ev
|
|||
/******************************************************************************/
|
||||
static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
||||
{
|
||||
ftdm_sigmsg_t sigev;
|
||||
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
||||
int i = 0;
|
||||
ftdm_sigmsg_t sigev;
|
||||
|
||||
memset (&sigev, 0, sizeof (sigev));
|
||||
|
||||
|
@ -493,7 +493,7 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
|||
/*now go to the RING state */
|
||||
ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_RING);
|
||||
|
||||
} else if (i > g_ftdm_sngss7_data.min_digits) {
|
||||
} else if (i >= g_ftdm_sngss7_data.min_digits) {
|
||||
SS7_DEBUG_CHAN(ftdmchan, "Received %d digits (min digits = %d)\n", i, g_ftdm_sngss7_data.min_digits);
|
||||
|
||||
/*now go to the RING state */
|
||||
|
@ -511,7 +511,7 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
|||
sngss7_info->t35.beat,
|
||||
sngss7_info->t35.callback,
|
||||
&sngss7_info->t35,
|
||||
&sngss7_info->t35.heartbeat_timer)) {
|
||||
&sngss7_info->t35.hb_timer_id)) {
|
||||
|
||||
SS7_ERROR ("Unable to schedule timer, hanging up call!\n");
|
||||
|
||||
|
@ -536,8 +536,8 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
|||
}
|
||||
|
||||
/* kill t35 if active */
|
||||
if (sngss7_info->t35.heartbeat_timer) {
|
||||
ftdm_sched_cancel_timer (sngss7_info->t35.sched,&sngss7_info->t35.heartbeat_timer);
|
||||
if (sngss7_info->t35.hb_timer_id) {
|
||||
ftdm_sched_cancel_timer (sngss7_info->t35.sched, sngss7_info->t35.hb_timer_id);
|
||||
}
|
||||
|
||||
SS7_DEBUG_CHAN(ftdmchan, "Sending incoming call from %s to %s to FTDM core\n",
|
||||
|
@ -788,14 +788,24 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
|||
!(sngss7_test_flag (sngss7_info, FLAG_GRP_RESET_TX)) &&
|
||||
!(sngss7_test_flag (sngss7_info, FLAG_GRP_RESET_RX))) {
|
||||
|
||||
/* check if the sig status is down, and bring it up if it isn't */
|
||||
if (!ftdm_test_flag (ftdmchan, FTDM_CHANNEL_SIG_UP)) {
|
||||
SS7_DEBUG_CHAN(ftdmchan,"All reset flags cleared %s\n", "");
|
||||
/* all flags are down so we can bring up the sig status */
|
||||
sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
|
||||
sigev.sigstatus = FTDM_SIG_STATE_UP;
|
||||
ftdm_span_send_signal (ftdmchan->span, &sigev);
|
||||
}
|
||||
/* now check if there is an active block */
|
||||
if (!(sngss7_test_flag(sngss7_info, FLAG_CKT_LC_BLOCK_RX)) &&
|
||||
!(sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) &&
|
||||
!(sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_TX)) &&
|
||||
!(sngss7_test_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX)) &&
|
||||
!(sngss7_test_flag(sngss7_info, FLAG_GRP_HW_BLOCK_TX)) &&
|
||||
!(sngss7_test_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX)) &&
|
||||
!(sngss7_test_flag(sngss7_info, FLAG_GRP_MN_BLOCK_TX))) {
|
||||
|
||||
/* check if the sig status is down, and bring it up if it isn't */
|
||||
if (!ftdm_test_flag (ftdmchan, FTDM_CHANNEL_SIG_UP)) {
|
||||
SS7_DEBUG_CHAN(ftdmchan,"All reset flags cleared %s\n", "");
|
||||
/* all flags are down so we can bring up the sig status */
|
||||
sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
|
||||
sigev.sigstatus = FTDM_SIG_STATE_UP;
|
||||
ftdm_span_send_signal (ftdmchan->span, &sigev);
|
||||
} /* if (!ftdm_test_flag (ftdmchan, FTDM_CHANNEL_SIG_UP)) */
|
||||
} /* if !blocked */
|
||||
} else {
|
||||
|
||||
SS7_DEBUG_CHAN(ftdmchan,"Reset flags present (0x%X)\n", sngss7_info->flags);
|
||||
|
@ -806,8 +816,8 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
|||
} /* if ((ftdmchan->last_state == FTDM_CHANNEL_STATE_RESTART) */
|
||||
|
||||
/* check if t35 is active */
|
||||
if (sngss7_info->t35.heartbeat_timer) {
|
||||
ftdm_sched_cancel_timer (sngss7_info->t35.sched, &sngss7_info->t35.heartbeat_timer);
|
||||
if (sngss7_info->t35.hb_timer_id) {
|
||||
ftdm_sched_cancel_timer (sngss7_info->t35.sched, sngss7_info->t35.hb_timer_id);
|
||||
}
|
||||
|
||||
/* clear all of the call specific data store in the channel structure */
|
||||
|
@ -993,6 +1003,11 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
|||
if (sngss7_test_flag (sngss7_info, FLAG_CKT_MN_BLOCK_RX)) {
|
||||
SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_MN_BLOCK_RX flag %s\n", "");
|
||||
|
||||
/* bring the sig status down */
|
||||
sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
|
||||
sigev.sigstatus = FTDM_SIG_STATE_DOWN;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
|
||||
/* send a BLA */
|
||||
ft_to_sngss7_bla (ftdmchan);
|
||||
|
||||
|
@ -1006,6 +1021,11 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
|||
/* clear the unblock flag */
|
||||
sngss7_clear_flag (sngss7_info, FLAG_CKT_MN_UNBLK_RX);
|
||||
|
||||
/* bring the sig status up */
|
||||
sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
|
||||
sigev.sigstatus = FTDM_SIG_STATE_UP;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
|
||||
/* send a uba */
|
||||
ft_to_sngss7_uba (ftdmchan);
|
||||
|
||||
|
@ -1017,6 +1037,11 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
|||
if (sngss7_test_flag (sngss7_info, FLAG_CKT_MN_BLOCK_TX)) {
|
||||
SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_MN_BLOCK_TX flag %s\n", "");
|
||||
|
||||
/* bring the sig status down */
|
||||
sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
|
||||
sigev.sigstatus = FTDM_SIG_STATE_DOWN;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
|
||||
/* send a blo */
|
||||
ft_to_sngss7_blo (ftdmchan);
|
||||
|
||||
|
@ -1030,6 +1055,11 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
|||
/* clear the unblock flag */
|
||||
sngss7_clear_flag (sngss7_info, FLAG_CKT_MN_UNBLK_TX);
|
||||
|
||||
/* bring the sig status up */
|
||||
sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
|
||||
sigev.sigstatus = FTDM_SIG_STATE_UP;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
|
||||
/* send a ubl */
|
||||
ft_to_sngss7_ubl (ftdmchan);
|
||||
|
||||
|
@ -1403,6 +1433,9 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_ss7_span_config)
|
|||
static FIO_SIG_LOAD_FUNCTION(ftdm_sangoma_ss7_init)
|
||||
{
|
||||
/*this function is called by the FT-core to load the signaling module */
|
||||
uint32_t major = 0;
|
||||
uint32_t minor = 0;
|
||||
uint32_t build = 0;
|
||||
|
||||
ftdm_log (FTDM_LOG_INFO, "Loading ftmod_sangoma_ss7...\n");
|
||||
|
||||
|
@ -1452,6 +1485,10 @@ static FIO_SIG_LOAD_FUNCTION(ftdm_sangoma_ss7_init)
|
|||
/* initalize sng_ss7 library */
|
||||
sng_isup_init (&sng_event);
|
||||
|
||||
/* print the version of the library being used */
|
||||
sng_isup_version(&major, &minor, &build);
|
||||
SS7_INFO("Loaded LibSng-SS7 %d.%d.%d\n", major, minor, build);
|
||||
|
||||
/* crash on assert fail */
|
||||
ftdm_global_set_crash_policy (FTDM_CRASH_ON_ASSERT);
|
||||
|
||||
|
|
|
@ -316,7 +316,7 @@ typedef struct ftdm_sngss7_data {
|
|||
}ftdm_sngss7_data_t;
|
||||
|
||||
typedef struct sngss7_timer_data {
|
||||
ftdm_timer_t *heartbeat_timer;
|
||||
ftdm_timer_id_t hb_timer_id;
|
||||
int beat;
|
||||
int counter;
|
||||
ftdm_sched_callback_t callback;
|
||||
|
|
|
@ -199,7 +199,8 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan)
|
|||
&iam,
|
||||
0);
|
||||
|
||||
SS7_INFO_CHAN(ftdmchan,"Tx IAM clg = \"%s\", cld = \"%s\"\n",
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx IAM clg = \"%s\", cld = \"%s\"\n",
|
||||
sngss7_info->circuit->cic,
|
||||
ftdmchan->caller_data.cid_num.digits,
|
||||
ftdmchan->caller_data.dnis.digits);
|
||||
|
||||
|
@ -250,7 +251,7 @@ void ft_to_sngss7_acm (ftdm_channel_t * ftdmchan)
|
|||
&acm,
|
||||
ADDRCMPLT);
|
||||
|
||||
SS7_MSG_TRACE(ftdmchan, sngss7_info, "Tx ACM\n");
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx ACM\n", sngss7_info->circuit->cic);
|
||||
|
||||
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
|
||||
return;
|
||||
|
@ -274,7 +275,7 @@ void ft_to_sngss7_anm (ftdm_channel_t * ftdmchan)
|
|||
&anm,
|
||||
5);
|
||||
|
||||
SS7_MSG_TRACE(ftdmchan, sngss7_info, "Tx ANM\n");
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx ANM\n", sngss7_info->circuit->cic);
|
||||
|
||||
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
|
||||
return;
|
||||
|
@ -307,7 +308,9 @@ void ft_to_sngss7_rel (ftdm_channel_t * ftdmchan)
|
|||
sngss7_info->circuit->id,
|
||||
&rel);
|
||||
|
||||
SS7_MSG_TRACE(ftdmchan, sngss7_info, "Tx REL\n");
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx REL cause=%d \n",
|
||||
sngss7_info->circuit->cic,
|
||||
ftdmchan->caller_data.hangup_cause );
|
||||
|
||||
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
|
||||
return;
|
||||
|
@ -330,7 +333,7 @@ void ft_to_sngss7_rlc (ftdm_channel_t * ftdmchan)
|
|||
sngss7_info->circuit->id,
|
||||
&rlc);
|
||||
|
||||
SS7_MSG_TRACE(ftdmchan, sngss7_info, "Tx RLC\n");
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx RLC\n", sngss7_info->circuit->cic);
|
||||
|
||||
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
|
||||
return;
|
||||
|
@ -351,7 +354,7 @@ void ft_to_sngss7_rsc (ftdm_channel_t * ftdmchan)
|
|||
SIT_STA_CIRRESREQ,
|
||||
NULL);
|
||||
|
||||
SS7_MSG_TRACE(ftdmchan, sngss7_info, "Tx RSC\n");
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx RSC\n", sngss7_info->circuit->cic);
|
||||
|
||||
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
|
||||
return;
|
||||
|
@ -372,7 +375,7 @@ void ft_to_sngss7_rsca (ftdm_channel_t * ftdmchan)
|
|||
SIT_STA_CIRRESRSP,
|
||||
NULL);
|
||||
|
||||
SS7_MSG_TRACE(ftdmchan, sngss7_info, "Tx RSC-RLC\n");
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx RSC-RLC\n", sngss7_info->circuit->cic);
|
||||
|
||||
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
|
||||
return;
|
||||
|
@ -393,7 +396,7 @@ void ft_to_sngss7_blo (ftdm_channel_t * ftdmchan)
|
|||
SIT_STA_CIRBLOREQ,
|
||||
NULL);
|
||||
|
||||
SS7_MSG_TRACE(ftdmchan, sngss7_info, "Tx BLO\n");
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx BLO\n", sngss7_info->circuit->cic);
|
||||
|
||||
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
|
||||
return;
|
||||
|
@ -414,7 +417,7 @@ void ft_to_sngss7_bla (ftdm_channel_t * ftdmchan)
|
|||
SIT_STA_CIRBLORSP,
|
||||
NULL);
|
||||
|
||||
SS7_MSG_TRACE(ftdmchan, sngss7_info, "Tx BLA\n");
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx BLA\n", sngss7_info->circuit->cic);
|
||||
|
||||
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
|
||||
return;
|
||||
|
@ -436,7 +439,7 @@ ft_to_sngss7_ubl (ftdm_channel_t * ftdmchan)
|
|||
SIT_STA_CIRUBLREQ,
|
||||
NULL);
|
||||
|
||||
SS7_MSG_TRACE(ftdmchan, sngss7_info, "Tx UBL\n");
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx UBL\n", sngss7_info->circuit->cic);
|
||||
|
||||
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
|
||||
return;
|
||||
|
@ -457,7 +460,7 @@ void ft_to_sngss7_uba (ftdm_channel_t * ftdmchan)
|
|||
SIT_STA_CIRUBLRSP,
|
||||
NULL);
|
||||
|
||||
SS7_MSG_TRACE(ftdmchan, sngss7_info, "Tx UBA\n");
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx UBA\n", sngss7_info->circuit->cic);
|
||||
|
||||
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
|
||||
return;
|
||||
|
@ -478,7 +481,7 @@ void ft_to_sngss7_lpa (ftdm_channel_t * ftdmchan)
|
|||
SIT_STA_LOOPBACKACK,
|
||||
NULL);
|
||||
|
||||
SS7_MSG_TRACE(ftdmchan, sngss7_info, "Tx LPA\n");
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx LPA\n", sngss7_info->circuit->cic);
|
||||
|
||||
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
|
||||
return;
|
||||
|
@ -519,7 +522,8 @@ void ft_to_sngss7_gra (ftdm_channel_t * ftdmchan)
|
|||
SIT_STA_GRSRSP,
|
||||
&gra);
|
||||
|
||||
SS7_INFO_CHAN(ftdmchan, "Tx GRA (%d:%d)\n",
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx GRA (%d:%d)\n",
|
||||
sngss7_info->circuit->cic,
|
||||
sngss7_info->circuit->cic,
|
||||
(sngss7_info->circuit->cic + sngss7_span->rx_grs.range));
|
||||
|
||||
|
@ -551,7 +555,8 @@ void ft_to_sngss7_grs (ftdm_channel_t * ftdmchan)
|
|||
SIT_STA_GRSREQ,
|
||||
&grs);
|
||||
|
||||
SS7_INFO_CHAN(ftdmchan, "Tx GRS (%d:%d)\n",
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx GRS (%d:%d)\n",
|
||||
sngss7_info->circuit->cic,
|
||||
sngss7_info->circuit->cic,
|
||||
(sngss7_info->circuit->cic + sngss7_span->tx_grs.range));
|
||||
|
||||
|
@ -596,7 +601,8 @@ void ft_to_sngss7_cgba(ftdm_channel_t * ftdmchan)
|
|||
SIT_STA_CGBRSP,
|
||||
&cgba);
|
||||
|
||||
SS7_INFO_CHAN(ftdmchan, "Tx CGBA (%d:%d)\n",
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx CGBA (%d:%d)\n",
|
||||
sngss7_info->circuit->cic,
|
||||
sngss7_info->circuit->cic,
|
||||
(sngss7_info->circuit->cic + sngss7_span->rx_cgb.range));
|
||||
|
||||
|
@ -644,7 +650,8 @@ void ft_to_sngss7_cgua(ftdm_channel_t * ftdmchan)
|
|||
SIT_STA_CGURSP,
|
||||
&cgua);
|
||||
|
||||
SS7_INFO_CHAN(ftdmchan, "Tx CGUA (%d:%d)\n",
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx CGUA (%d:%d)\n",
|
||||
sngss7_info->circuit->cic,
|
||||
sngss7_info->circuit->cic,
|
||||
(sngss7_info->circuit->cic + sngss7_span->rx_cgu.range));
|
||||
|
||||
|
@ -693,7 +700,8 @@ void ft_to_sngss7_cgb(ftdm_channel_t * ftdmchan)
|
|||
SIT_STA_CGBREQ,
|
||||
&cgb);
|
||||
|
||||
SS7_INFO_CHAN(ftdmchan, "Tx CGB (%d:%d)\n",
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx CGB (%d:%d)\n",
|
||||
sngss7_info->circuit->cic,
|
||||
sngss7_info->circuit->cic,
|
||||
(sngss7_info->circuit->cic + sngss7_span->tx_cgb.range));
|
||||
|
||||
|
@ -742,7 +750,8 @@ void ft_to_sngss7_cgu(ftdm_channel_t * ftdmchan)
|
|||
SIT_STA_CGUREQ,
|
||||
&cgu);
|
||||
|
||||
SS7_INFO_CHAN(ftdmchan, "Tx CGU (%d:%d)\n",
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx CGU (%d:%d)\n",
|
||||
sngss7_info->circuit->cic,
|
||||
sngss7_info->circuit->cic,
|
||||
(sngss7_info->circuit->cic + sngss7_span->tx_cgu.range));
|
||||
|
||||
|
|
|
@ -464,7 +464,7 @@ ftdm_status_t check_if_rx_grs_processed(ftdm_span_t *ftdmspan)
|
|||
/* extract the channel in question */
|
||||
if (extract_chan_data(i, &sngss7_info, &ftdmchan)) {
|
||||
SS7_ERROR("Failed to extract channel data for circuit = %d!\n", i);
|
||||
SS7_ASSERT;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* lock the channel */
|
||||
|
@ -476,61 +476,61 @@ ftdm_status_t check_if_rx_grs_processed(ftdm_span_t *ftdmspan)
|
|||
if (!sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX_DN)) {
|
||||
/* this channel is still resetting...do nothing */
|
||||
goto GRS_UNLOCK_ALL;
|
||||
} /* if (!sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX_DN)) */
|
||||
} else {
|
||||
/* state change pending */
|
||||
goto GRS_UNLOCK_ALL;
|
||||
}
|
||||
} /* for ( i = circuit; i < (circuit + range + 1); i++) */
|
||||
} /* if (!sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX_DN)) */
|
||||
} else {
|
||||
/* state change pending */
|
||||
goto GRS_UNLOCK_ALL;
|
||||
}
|
||||
} /* for ( i = circuit; i < (circuit + range + 1); i++) */
|
||||
|
||||
SS7_DEBUG("All circuits out of reset for GRS: circuit=%d, range=%d\n",
|
||||
sngss7_span->rx_grs.circuit,
|
||||
sngss7_span->rx_grs.range);
|
||||
SS7_DEBUG("All circuits out of reset for GRS: circuit=%d, range=%d\n",
|
||||
sngss7_span->rx_grs.circuit,
|
||||
sngss7_span->rx_grs.range);
|
||||
|
||||
/* check all the circuits in the range to see if they are done resetting */
|
||||
for ( i = sngss7_span->rx_grs.circuit; i < (sngss7_span->rx_grs.circuit + sngss7_span->rx_grs.range + 1); i++) {
|
||||
/* check all the circuits in the range to see if they are done resetting */
|
||||
for ( i = sngss7_span->rx_grs.circuit; i < (sngss7_span->rx_grs.circuit + sngss7_span->rx_grs.range + 1); i++) {
|
||||
|
||||
/* extract the channel in question */
|
||||
if (extract_chan_data(i, &sngss7_info, &ftdmchan)) {
|
||||
SS7_ERROR("Failed to extract channel data for circuit = %d!\n",i);
|
||||
SS7_ASSERT;
|
||||
}
|
||||
/* extract the channel in question */
|
||||
if (extract_chan_data(i, &sngss7_info, &ftdmchan)) {
|
||||
SS7_ERROR("Failed to extract channel data for circuit = %d!\n",i);
|
||||
SS7_ASSERT;
|
||||
}
|
||||
|
||||
/* throw the GRP reset flag complete flag */
|
||||
sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_RX_CMPLT);
|
||||
/* throw the GRP reset flag complete flag */
|
||||
sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_RX_CMPLT);
|
||||
|
||||
/* move the channel to the down state */
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
|
||||
/* move the channel to the down state */
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
|
||||
|
||||
/* update the status map if the ckt is in blocked state */
|
||||
if ((sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) ||
|
||||
(sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_TX)) ||
|
||||
(sngss7_test_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX)) ||
|
||||
(sngss7_test_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX))) {
|
||||
/* update the status map if the ckt is in blocked state */
|
||||
if ((sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) ||
|
||||
(sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_TX)) ||
|
||||
(sngss7_test_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX)) ||
|
||||
(sngss7_test_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX))) {
|
||||
|
||||
sngss7_span->rx_grs.status[byte] = (sngss7_span->rx_grs.status[byte] | (1 << bit));
|
||||
} /* if blocked */
|
||||
sngss7_span->rx_grs.status[byte] = (sngss7_span->rx_grs.status[byte] | (1 << bit));
|
||||
} /* if blocked */
|
||||
|
||||
/* update the bit and byte counter*/
|
||||
bit ++;
|
||||
if (bit == 8) {
|
||||
byte++;
|
||||
bit = 0;
|
||||
}
|
||||
} /* for ( i = circuit; i < (circuit + range + 1); i++) */
|
||||
/* update the bit and byte counter*/
|
||||
bit ++;
|
||||
if (bit == 8) {
|
||||
byte++;
|
||||
bit = 0;
|
||||
}
|
||||
} /* for ( i = circuit; i < (circuit + range + 1); i++) */
|
||||
|
||||
GRS_UNLOCK_ALL:
|
||||
for ( i = sngss7_span->rx_grs.circuit; i < (sngss7_span->rx_grs.circuit + sngss7_span->rx_grs.range + 1); i++) {
|
||||
/* extract the channel in question */
|
||||
if (extract_chan_data(i, &sngss7_info, &ftdmchan)) {
|
||||
SS7_ERROR("Failed to extract channel data for circuit = %d!\n", i);
|
||||
SS7_ASSERT;
|
||||
}
|
||||
|
||||
/* unlock the channel */
|
||||
ftdm_mutex_unlock(ftdmchan->mutex);
|
||||
for ( i = sngss7_span->rx_grs.circuit; i < (sngss7_span->rx_grs.circuit + sngss7_span->rx_grs.range + 1); i++) {
|
||||
/* extract the channel in question */
|
||||
if (extract_chan_data(i, &sngss7_info, &ftdmchan)) {
|
||||
SS7_ERROR("Failed to extract channel data for circuit = %d!\n", i);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* unlock the channel */
|
||||
ftdm_mutex_unlock(ftdmchan->mutex);
|
||||
}
|
||||
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -64,7 +64,7 @@ void handle_isup_t35(void *userdata)
|
|||
sngss7_set_flag(sngss7_info, FLAG_LOCAL_REL);
|
||||
|
||||
/* hang up on timer expiry */
|
||||
ftdmchan->caller_data.hangup_cause = 102;
|
||||
ftdmchan->caller_data.hangup_cause = 28;
|
||||
|
||||
/* end the call */
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_CANCEL);
|
||||
|
|
|
@ -1277,7 +1277,13 @@ FT_DECLARE(const char *) ftdm_channel_get_state_str(const ftdm_channel_t *channe
|
|||
/*! \brief For display debugging purposes you can display this string which describes the last channel internal state */
|
||||
FT_DECLARE(const char *) ftdm_channel_get_last_state_str(const ftdm_channel_t *channel);
|
||||
|
||||
/*! \brief For display debugging purposes you can display this string which describes the last channel internal state */
|
||||
/*! \brief For display debugging purposes you can display this string which describes the history of the channel
|
||||
* \param The channel
|
||||
* \return History string for the channel. You must free the string with ftdm_free
|
||||
*/
|
||||
FT_DECLARE(char *) ftdm_channel_get_history_str(const ftdm_channel_t *channel);
|
||||
|
||||
/*! \brief Initialize channel state for an outgoing call */
|
||||
FT_DECLARE(ftdm_status_t) ftdm_channel_init(ftdm_channel_t *ftdmchan);
|
||||
|
||||
/*! \brief Initialize the library */
|
||||
|
@ -1301,6 +1307,12 @@ FT_DECLARE(void) ftdm_global_set_logger(ftdm_logger_t logger);
|
|||
/*! \brief Set the default logger level */
|
||||
FT_DECLARE(void) ftdm_global_set_default_logger(int level);
|
||||
|
||||
/*! \brief Set the directory to look for modules */
|
||||
FT_DECLARE(void) ftdm_global_set_mod_directory(const char *path);
|
||||
|
||||
/*! \brief Set the directory to look for configs */
|
||||
FT_DECLARE(void) ftdm_global_set_config_directory(const char *path);
|
||||
|
||||
/*! \brief Check if the FTDM library is initialized and running */
|
||||
FT_DECLARE(ftdm_bool_t) ftdm_running(void);
|
||||
|
||||
|
|
|
@ -356,6 +356,15 @@ typedef struct {
|
|||
} ftdm_dtmf_debug_t;
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
const char *file;
|
||||
const char *func;
|
||||
int line;
|
||||
ftdm_channel_state_t state;
|
||||
ftdm_channel_state_t last_state;
|
||||
ftdm_time_t time;
|
||||
} ftdm_channel_history_entry_t;
|
||||
|
||||
/* 2^8 table size, one for each byte (sample) value */
|
||||
#define FTDM_GAINS_TABLE_SIZE 256
|
||||
struct ftdm_channel {
|
||||
|
@ -381,6 +390,8 @@ struct ftdm_channel {
|
|||
ftdm_channel_state_t state;
|
||||
ftdm_channel_state_t last_state;
|
||||
ftdm_channel_state_t init_state;
|
||||
ftdm_channel_history_entry_t history[10];
|
||||
uint8_t hindex;
|
||||
ftdm_mutex_t *mutex;
|
||||
teletone_dtmf_detect_state_t dtmf_detect;
|
||||
uint32_t buffer_delay;
|
||||
|
@ -425,6 +436,7 @@ struct ftdm_channel {
|
|||
float txgain;
|
||||
int availability_rate;
|
||||
void *user_private;
|
||||
ftdm_timer_id_t hangup_timer;
|
||||
#ifdef FTDM_DEBUG_DTMF
|
||||
ftdm_dtmf_debug_t dtmfdbg;
|
||||
#endif
|
||||
|
|
|
@ -44,8 +44,8 @@ extern "C" {
|
|||
#define FTDM_MICROSECONDS_PER_SECOND 1000000
|
||||
|
||||
typedef struct ftdm_sched ftdm_sched_t;
|
||||
typedef struct ftdm_timer ftdm_timer_t;
|
||||
typedef void (*ftdm_sched_callback_t)(void *data);
|
||||
typedef uint64_t ftdm_timer_id_t;
|
||||
|
||||
/*! \brief Create a new scheduling context */
|
||||
FT_DECLARE(ftdm_status_t) ftdm_sched_create(ftdm_sched_t **sched, const char *name);
|
||||
|
@ -62,18 +62,22 @@ FT_DECLARE(ftdm_status_t) ftdm_sched_free_run(ftdm_sched_t *sched);
|
|||
* \param name Timer name, typically unique but is not required to be unique, any null terminated string is fine (required)
|
||||
* \param callback The callback to call upon timer expiration (required)
|
||||
* \param data Optional data to pass to the callback
|
||||
* \param timer The timer that was created, it can be NULL if you dont care,
|
||||
* but you need this if you want to be able to cancel the timer with ftdm_sched_cancel_timer
|
||||
* \param timer Timer id pointer to store the id of the newly created timer. It can be null
|
||||
* if you do not need to know the id, but you need this if you want to be able
|
||||
* to cancel the timer with ftdm_sched_cancel_timer
|
||||
*/
|
||||
FT_DECLARE(ftdm_status_t) ftdm_sched_timer(ftdm_sched_t *sched, const char *name,
|
||||
int ms, ftdm_sched_callback_t callback, void *data, ftdm_timer_t **timer);
|
||||
int ms, ftdm_sched_callback_t callback, void *data, ftdm_timer_id_t *timer);
|
||||
|
||||
/*!
|
||||
* \brief Cancel the timer
|
||||
* Note that there is a race between cancelling and triggering a timer.
|
||||
* By the time you call this function the timer may be about to be triggered.
|
||||
* This is specially true with timers in free run schedule.
|
||||
* \param sched The scheduling context (required)
|
||||
* \param timer The timer to cancel (required)
|
||||
*/
|
||||
FT_DECLARE(ftdm_status_t) ftdm_sched_cancel_timer(ftdm_sched_t *sched, ftdm_timer_t **timer);
|
||||
FT_DECLARE(ftdm_status_t) ftdm_sched_cancel_timer(ftdm_sched_t *sched, ftdm_timer_id_t timer);
|
||||
|
||||
/*! \brief Destroy the context and all of the scheduled timers in it */
|
||||
FT_DECLARE(ftdm_status_t) ftdm_sched_destroy(ftdm_sched_t **sched);
|
||||
|
|
|
@ -322,9 +322,15 @@ struct ftdm_conf_node {
|
|||
/* first node child */
|
||||
struct ftdm_conf_node *child;
|
||||
|
||||
/* last node child */
|
||||
struct ftdm_conf_node *last;
|
||||
|
||||
/* next node sibling */
|
||||
struct ftdm_conf_node *next;
|
||||
|
||||
/* prev node sibling */
|
||||
struct ftdm_conf_node *prev;
|
||||
|
||||
/* my parent if any */
|
||||
struct ftdm_conf_node *parent;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue