Merge remote branch 'smgfs/master'
This commit is contained in:
commit
6e24e8e67b
|
@ -2078,7 +2078,7 @@ static FIO_SIGNAL_CB_FUNCTION(on_r2_signal)
|
|||
|
||||
case FTDM_SIGEVENT_SIGSTATUS_CHANGED:
|
||||
{
|
||||
ftdm_signaling_status_t sigstatus = sigmsg->raw_data ? *((ftdm_signaling_status_t*)(sigmsg->raw_data)) : sigmsg->sigstatus;
|
||||
ftdm_signaling_status_t sigstatus = sigmsg->raw_data ? *((ftdm_signaling_status_t*)(sigmsg->raw_data)) : sigmsg->ev_data.sigstatus.status;
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%d:%d signalling changed to: %s\n",
|
||||
spanid, chanid, ftdm_signaling_status2str(sigstatus));
|
||||
}
|
||||
|
@ -2168,6 +2168,7 @@ static FIO_SIGNAL_CB_FUNCTION(on_clear_channel_signal)
|
|||
}
|
||||
break;
|
||||
case FTDM_SIGEVENT_PROGRESS:
|
||||
case FTDM_SIGEVENT_RINGING:
|
||||
{
|
||||
if ((session = ftdm_channel_get_session(sigmsg->channel, 0))) {
|
||||
channel = switch_core_session_get_channel(session);
|
||||
|
@ -2183,7 +2184,7 @@ static FIO_SIGNAL_CB_FUNCTION(on_clear_channel_signal)
|
|||
break;
|
||||
case FTDM_SIGEVENT_SIGSTATUS_CHANGED:
|
||||
{
|
||||
ftdm_signaling_status_t sigstatus = sigmsg->raw_data ? *((ftdm_signaling_status_t*)(sigmsg->raw_data)) : sigmsg->sigstatus;
|
||||
ftdm_signaling_status_t sigstatus = sigmsg->raw_data ? *((ftdm_signaling_status_t*)(sigmsg->raw_data)) : sigmsg->ev_data.sigstatus.status;
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%d:%d signalling changed to :%s\n",
|
||||
spanid, chanid, ftdm_signaling_status2str(sigstatus));
|
||||
}
|
||||
|
@ -3543,7 +3544,83 @@ SWITCH_STANDARD_API(ft_function)
|
|||
goto end;
|
||||
}
|
||||
|
||||
if (!strcasecmp(argv[0], "dump")) {
|
||||
if (!strcasecmp(argv[0], "sigstatus")) {
|
||||
ftdm_span_t *span = NULL;
|
||||
ftdm_signaling_status_t sigstatus;
|
||||
|
||||
if (argc < 3) {
|
||||
stream->write_function(stream, "-ERR Usage: ftdm sigstatus get|set [<span_id>] [<channel>] [<sigstatus>]\n");
|
||||
goto end;
|
||||
}
|
||||
if (!strcasecmp(argv[1], "get") && argc < 3) {
|
||||
stream->write_function(stream, "-ERR sigstatus get usage: get <span_id>\n");
|
||||
goto end;
|
||||
}
|
||||
if (!strcasecmp(argv[1], "set") && argc != 5) {
|
||||
stream->write_function(stream, "-ERR sigstatus set usage: set <span_id> <channel>|all <sigstatus>\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
ftdm_span_find_by_name(argv[2], &span);
|
||||
if (!span) {
|
||||
stream->write_function(stream, "-ERR invalid span\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!strcasecmp(argv[1], "get")) {
|
||||
if (argc == 4) {
|
||||
uint32_t chan_id = atol(argv[3]);
|
||||
ftdm_channel_t *fchan = ftdm_span_get_channel(span, chan_id);
|
||||
if (!fchan) {
|
||||
stream->write_function(stream, "-ERR failed to get channel id '%d'\n", chan_id);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if ((FTDM_SUCCESS == ftdm_channel_get_sig_status(fchan, &sigstatus))) {
|
||||
stream->write_function(stream, "channel %d signaling status: %s\n", chan_id, ftdm_signaling_status2str(sigstatus));
|
||||
} else {
|
||||
stream->write_function(stream, "-ERR failed to get channel sigstatus\n");
|
||||
}
|
||||
goto end;
|
||||
} else {
|
||||
if ((FTDM_SUCCESS == ftdm_span_get_sig_status(span, &sigstatus))) {
|
||||
stream->write_function(stream, "signaling_status: %s\n", ftdm_signaling_status2str(sigstatus));
|
||||
} else {
|
||||
stream->write_function(stream, "-ERR failed to read span status: %s\n", ftdm_span_get_last_error(span));
|
||||
}
|
||||
}
|
||||
goto end;
|
||||
}
|
||||
if (!strcasecmp(argv[1], "set")) {
|
||||
sigstatus = ftdm_str2ftdm_signaling_status(argv[4]);
|
||||
|
||||
if (!strcasecmp(argv[3], "all")) {
|
||||
if ((FTDM_SUCCESS == ftdm_span_set_sig_status(span, sigstatus))) {
|
||||
stream->write_function(stream, "Signaling status of all channels from span %s set to %s\n",
|
||||
ftdm_span_get_name(span), ftdm_signaling_status2str(sigstatus));
|
||||
} else {
|
||||
stream->write_function(stream, "-ERR failed to set span sigstatus to '%s'\n", ftdm_signaling_status2str(sigstatus));
|
||||
}
|
||||
goto end;
|
||||
} else {
|
||||
uint32_t chan_id = atol(argv[3]);
|
||||
ftdm_channel_t *fchan = ftdm_span_get_channel(span, chan_id);
|
||||
if (!fchan) {
|
||||
stream->write_function(stream, "-ERR failed to get channel id '%d'\n", chan_id);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if ((FTDM_SUCCESS == ftdm_channel_set_sig_status(fchan, sigstatus))) {
|
||||
stream->write_function(stream, "Signaling status of channel %d set to %s\n", chan_id,
|
||||
ftdm_signaling_status2str(sigstatus));
|
||||
} else {
|
||||
stream->write_function(stream, "-ERR failed to set span sigstatus to '%s'\n", ftdm_signaling_status2str(sigstatus));
|
||||
}
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (!strcasecmp(argv[0], "dump")) {
|
||||
if (argc < 2) {
|
||||
stream->write_function(stream, "-ERR Usage: ftdm dump <span_id> [<chan_id>]\n");
|
||||
goto end;
|
||||
|
@ -3923,6 +4000,28 @@ SWITCH_STANDARD_API(ft_function)
|
|||
}
|
||||
}
|
||||
stream->write_function(stream, "+OK gains set to Rx %f and Tx %f\n", rxgain, txgain);
|
||||
} else if (!strcasecmp(argv[0], "restart")) {
|
||||
uint32_t chan_id = 0;
|
||||
ftdm_channel_t *chan;
|
||||
ftdm_span_t *span = NULL;
|
||||
if (argc < 3) {
|
||||
stream->write_function(stream, "-ERR Usage: ftdm restart <span_id> <chan_id>\n");
|
||||
goto end;
|
||||
}
|
||||
ftdm_span_find_by_name(argv[1], &span);
|
||||
if (!span) {
|
||||
stream->write_function(stream, "-ERR invalid span\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
chan_id = atoi(argv[2]);
|
||||
chan = ftdm_span_get_channel(span, chan_id);
|
||||
if (!chan) {
|
||||
stream->write_function(stream, "-ERR Could not find chan\n");
|
||||
goto end;
|
||||
}
|
||||
stream->write_function(stream, "Resetting channel %s:%s\n", argv[2], argv[3]);
|
||||
ftdm_channel_reset(chan);
|
||||
} else {
|
||||
|
||||
char *rply = ftdm_api_execute(cmd);
|
||||
|
|
|
@ -57,11 +57,16 @@ struct tm *localtime_r(const time_t *clock, struct tm *result);
|
|||
#define SPAN_PENDING_SIGNALS_QUEUE_SIZE 1000
|
||||
#define FTDM_READ_TRACE_INDEX 0
|
||||
#define FTDM_WRITE_TRACE_INDEX 1
|
||||
#define MAX_CALLIDS 6000
|
||||
|
||||
ftdm_time_t time_last_throttle_log = 0;
|
||||
ftdm_time_t time_current_throttle_log = 0;
|
||||
|
||||
static ftdm_iterator_t *get_iterator(ftdm_iterator_type_t type, ftdm_iterator_t *iter);
|
||||
static ftdm_status_t ftdm_call_set_call_id(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_clear_vars(ftdm_channel_t *ftdmchan);
|
||||
static ftdm_status_t ftdm_channel_done(ftdm_channel_t *ftdmchan);
|
||||
|
||||
static int time_is_init = 0;
|
||||
|
||||
|
@ -235,6 +240,10 @@ static struct {
|
|||
ftdm_span_t *spans;
|
||||
ftdm_group_t *groups;
|
||||
cpu_monitor_t cpu_monitor;
|
||||
|
||||
ftdm_caller_data_t *call_ids[MAX_CALLIDS+1];
|
||||
ftdm_mutex_t *call_id_mutex;
|
||||
uint32_t last_call_id;
|
||||
} globals;
|
||||
|
||||
enum ftdm_enum_cpu_alarm_action_flags
|
||||
|
@ -271,6 +280,9 @@ FTDM_STR2ENUM(ftdm_str2ftdm_chan_type, ftdm_chan_type2str, ftdm_chan_type_t, CHA
|
|||
FTDM_ENUM_NAMES(SIGNALING_STATUS_NAMES, SIGSTATUS_STRINGS)
|
||||
FTDM_STR2ENUM(ftdm_str2ftdm_signaling_status, ftdm_signaling_status2str, ftdm_signaling_status_t, SIGNALING_STATUS_NAMES, FTDM_SIG_STATE_INVALID)
|
||||
|
||||
FTDM_ENUM_NAMES(TRACE_DIR_NAMES, TRACE_DIR_STRINGS)
|
||||
FTDM_STR2ENUM(ftdm_str2ftdm_trace_dir, ftdm_trace_dir2str, ftdm_trace_dir_t, TRACE_DIR_NAMES, FTDM_TRACE_INVALID)
|
||||
|
||||
FTDM_ENUM_NAMES(TON_NAMES, TON_STRINGS)
|
||||
FTDM_STR2ENUM(ftdm_str2ftdm_ton, ftdm_ton2str, ftdm_ton_t, TON_NAMES, FTDM_TON_INVALID)
|
||||
|
||||
|
@ -1690,6 +1702,18 @@ static ftdm_status_t __inline__ get_best_rated(ftdm_channel_t **fchan, ftdm_chan
|
|||
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
FT_DECLARE(int) ftdm_channel_get_availability(ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
int availability = -1;
|
||||
ftdm_channel_lock(ftdmchan);
|
||||
if (ftdm_test_flag(ftdmchan->span, FTDM_SPAN_USE_AV_RATE)) {
|
||||
availability = ftdmchan->availability_rate;
|
||||
}
|
||||
ftdm_channel_unlock(ftdmchan);
|
||||
return availability;
|
||||
}
|
||||
|
||||
FT_DECLARE(ftdm_status_t) ftdm_channel_open_by_group(uint32_t group_id, ftdm_direction_t direction, ftdm_caller_data_t *caller_data, ftdm_channel_t **ftdmchan)
|
||||
{
|
||||
ftdm_status_t status = FTDM_FAIL;
|
||||
|
@ -1867,47 +1891,6 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_open_by_span(uint32_t span_id, ftdm_direc
|
|||
return status;
|
||||
}
|
||||
|
||||
static ftdm_status_t ftdm_channel_reset(ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_OPEN);
|
||||
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_DTMF_DETECT);
|
||||
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_SUPRESS_DTMF);
|
||||
ftdm_channel_done(ftdmchan);
|
||||
ftdm_clear_flag_locked(ftdmchan, FTDM_CHANNEL_HOLD);
|
||||
|
||||
memset(ftdmchan->tokens, 0, sizeof(ftdmchan->tokens));
|
||||
ftdmchan->token_count = 0;
|
||||
|
||||
ftdm_channel_flush_dtmf(ftdmchan);
|
||||
|
||||
if (ftdmchan->gen_dtmf_buffer) {
|
||||
ftdm_buffer_zero(ftdmchan->gen_dtmf_buffer);
|
||||
}
|
||||
|
||||
if (ftdmchan->digit_buffer) {
|
||||
ftdm_buffer_zero(ftdmchan->digit_buffer);
|
||||
}
|
||||
|
||||
if (!ftdmchan->dtmf_on) {
|
||||
ftdmchan->dtmf_on = FTDM_DEFAULT_DTMF_ON;
|
||||
}
|
||||
|
||||
if (!ftdmchan->dtmf_off) {
|
||||
ftdmchan->dtmf_off = FTDM_DEFAULT_DTMF_OFF;
|
||||
}
|
||||
|
||||
ftdm_call_clear_vars(&ftdmchan->caller_data);
|
||||
|
||||
memset(ftdmchan->dtmf_hangup_buf, '\0', ftdmchan->span->dtmf_hangup_len);
|
||||
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_TRANSCODE)) {
|
||||
ftdmchan->effective_codec = ftdmchan->native_codec;
|
||||
ftdmchan->packet_len = ftdmchan->native_interval * (ftdmchan->effective_codec == FTDM_CODEC_SLIN ? 16 : 8);
|
||||
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_TRANSCODE);
|
||||
}
|
||||
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
FT_DECLARE(ftdm_status_t) ftdm_channel_init(ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
|
@ -2411,14 +2394,16 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_indicate(const char *file, const ch
|
|||
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_PROGRESS);
|
||||
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_MEDIA);
|
||||
} else {
|
||||
if (ftdmchan->state < FTDM_CHANNEL_STATE_PROGRESS) {
|
||||
ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROGRESS, 1);
|
||||
}
|
||||
if (!ftdm_test_flag(ftdmchan->span, FTDM_SPAN_USE_SKIP_STATES)) {
|
||||
if (ftdmchan->state < FTDM_CHANNEL_STATE_PROGRESS) {
|
||||
ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROGRESS, 1);
|
||||
}
|
||||
|
||||
/* set state unlocks the channel so we need to re-confirm that the channel hasn't gone to hell */
|
||||
if (ftdmchan->state == FTDM_CHANNEL_STATE_TERMINATING) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Ignoring answer because the call has moved to TERMINATING while we're moving to PROGRESS\n");
|
||||
goto done;
|
||||
/* set state unlocks the channel so we need to re-confirm that the channel hasn't gone to hell */
|
||||
if (ftdmchan->state == FTDM_CHANNEL_STATE_TERMINATING) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Ignoring answer because the call has moved to TERMINATING while we're moving to PROGRESS\n");
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, 1);
|
||||
|
@ -2457,6 +2442,16 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_send_msg(const char *file, const ch
|
|||
return status;
|
||||
}
|
||||
|
||||
FT_DECLARE(ftdm_status_t) _ftdm_channel_reset(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
ftdm_assert_return(ftdmchan != NULL, FTDM_FAIL, "null channel");
|
||||
|
||||
ftdm_channel_lock(ftdmchan);
|
||||
ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_RESET, 1);
|
||||
ftdm_channel_unlock(ftdmchan);
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
FT_DECLARE(ftdm_status_t) _ftdm_channel_call_place(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
ftdm_status_t status = FTDM_FAIL;
|
||||
|
@ -2483,6 +2478,7 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_place(const char *file, const char
|
|||
|
||||
ftdm_wait_for_flag_cleared(ftdmchan, FTDM_CHANNEL_STATE_CHANGE, 100);
|
||||
|
||||
ftdm_call_set_call_id(&ftdmchan->caller_data);
|
||||
ftdm_channel_unlock(ftdmchan);
|
||||
|
||||
return status;
|
||||
|
@ -2539,15 +2535,13 @@ FT_DECLARE(ftdm_status_t) ftdm_span_get_sig_status(ftdm_span_t *span, ftdm_signa
|
|||
}
|
||||
}
|
||||
|
||||
static ftdm_status_t ftdm_channel_clear_vars(ftdm_channel_t *ftdmchan);
|
||||
FT_DECLARE(ftdm_status_t) ftdm_channel_done(ftdm_channel_t *ftdmchan)
|
||||
static ftdm_status_t ftdm_channel_done(ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
ftdm_assert_return(ftdmchan != NULL, FTDM_FAIL, "Null channel can't be done!\n");
|
||||
|
||||
ftdm_mutex_lock(ftdmchan->mutex);
|
||||
|
||||
memset(&ftdmchan->caller_data, 0, sizeof(ftdmchan->caller_data));
|
||||
|
||||
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_OPEN);
|
||||
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_DTMF_DETECT);
|
||||
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_SUPRESS_DTMF);
|
||||
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_INUSE);
|
||||
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND);
|
||||
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_WINK);
|
||||
|
@ -2587,18 +2581,48 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_done(ftdm_channel_t *ftdmchan)
|
|||
sigmsg.channel = ftdmchan;
|
||||
sigmsg.event_id = FTDM_SIGEVENT_RELEASED;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigmsg);
|
||||
ftdm_call_clear_call_id(&ftdmchan->caller_data);
|
||||
}
|
||||
|
||||
if (ftdmchan->txdrops || ftdmchan->rxdrops) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "channel dropped data: txdrops = %d, rxdrops = %d\n",
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "channel dropped data: txdrops = %d, rxdrops = %d\n",
|
||||
ftdmchan->txdrops, ftdmchan->rxdrops);
|
||||
}
|
||||
|
||||
memset(&ftdmchan->caller_data, 0, sizeof(ftdmchan->caller_data));
|
||||
|
||||
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_HOLD);
|
||||
|
||||
memset(ftdmchan->tokens, 0, sizeof(ftdmchan->tokens));
|
||||
ftdmchan->token_count = 0;
|
||||
|
||||
ftdm_channel_flush_dtmf(ftdmchan);
|
||||
|
||||
if (ftdmchan->gen_dtmf_buffer) {
|
||||
ftdm_buffer_zero(ftdmchan->gen_dtmf_buffer);
|
||||
}
|
||||
|
||||
if (ftdmchan->digit_buffer) {
|
||||
ftdm_buffer_zero(ftdmchan->digit_buffer);
|
||||
}
|
||||
|
||||
if (!ftdmchan->dtmf_on) {
|
||||
ftdmchan->dtmf_on = FTDM_DEFAULT_DTMF_ON;
|
||||
}
|
||||
|
||||
if (!ftdmchan->dtmf_off) {
|
||||
ftdmchan->dtmf_off = FTDM_DEFAULT_DTMF_OFF;
|
||||
}
|
||||
|
||||
memset(ftdmchan->dtmf_hangup_buf, '\0', ftdmchan->span->dtmf_hangup_len);
|
||||
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_TRANSCODE)) {
|
||||
ftdmchan->effective_codec = ftdmchan->native_codec;
|
||||
ftdmchan->packet_len = ftdmchan->native_interval * (ftdmchan->effective_codec == FTDM_CODEC_SLIN ? 16 : 8);
|
||||
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_TRANSCODE);
|
||||
}
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "channel done\n");
|
||||
|
||||
|
||||
ftdm_mutex_unlock(ftdmchan->mutex);
|
||||
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -2628,8 +2652,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_close(ftdm_channel_t **ftdmchan)
|
|||
if (ftdm_test_flag(check, FTDM_CHANNEL_OPEN)) {
|
||||
status = check->fio->close(check);
|
||||
if (status == FTDM_SUCCESS) {
|
||||
ftdm_clear_flag(check, FTDM_CHANNEL_INUSE);
|
||||
ftdm_channel_reset(check);
|
||||
ftdm_channel_done(check);
|
||||
*ftdmchan = NULL;
|
||||
}
|
||||
} else {
|
||||
|
@ -2712,7 +2735,8 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co
|
|||
close(ftdmchan->fds[FTDM_READ_TRACE_INDEX]);
|
||||
ftdmchan->fds[FTDM_READ_TRACE_INDEX] = -1;
|
||||
}
|
||||
if ((ftdmchan->fds[FTDM_READ_TRACE_INDEX] = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)) > -1) {
|
||||
if ((ftdmchan->fds[FTDM_READ_TRACE_INDEX] = open(path, O_WRONLY | O_CREAT | O_TRUNC
|
||||
| FTDM_O_BINARY, S_IRUSR | S_IWUSR)) > -1) {
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Tracing channel %u:%u input to [%s]\n", ftdmchan->span_id, ftdmchan->chan_id, path);
|
||||
GOTO_STATUS(done, FTDM_SUCCESS);
|
||||
}
|
||||
|
@ -2728,7 +2752,8 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co
|
|||
close(ftdmchan->fds[FTDM_WRITE_TRACE_INDEX]);
|
||||
ftdmchan->fds[FTDM_WRITE_TRACE_INDEX] = -1;
|
||||
}
|
||||
if ((ftdmchan->fds[FTDM_WRITE_TRACE_INDEX] = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)) > -1) {
|
||||
if ((ftdmchan->fds[FTDM_WRITE_TRACE_INDEX] = open(path, O_WRONLY | O_CREAT | O_TRUNC
|
||||
| FTDM_O_BINARY, S_IRUSR | S_IWUSR)) > -1) {
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Tracing channel %u:%u output to [%s]\n", ftdmchan->span_id, ftdmchan->chan_id, path);
|
||||
GOTO_STATUS(done, FTDM_SUCCESS);
|
||||
}
|
||||
|
@ -2796,10 +2821,10 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co
|
|||
GOTO_STATUS(done, FTDM_FAIL);
|
||||
}
|
||||
if (start_chan_io_dump(ftdmchan, &ftdmchan->rxdump, size) != FTDM_SUCCESS) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failed to enable input dump of size %zd\n", size);
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failed to enable input dump of size %"FTDM_SIZE_FMT"\n", size);
|
||||
GOTO_STATUS(done, FTDM_FAIL);
|
||||
}
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Enabled input dump with size %zd\n", size);
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Enabled input dump with size %"FTDM_SIZE_FMT"\n", size);
|
||||
GOTO_STATUS(done, FTDM_SUCCESS);
|
||||
}
|
||||
break;
|
||||
|
@ -2811,7 +2836,8 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co
|
|||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "No need to disable input dump\n");
|
||||
GOTO_STATUS(done, FTDM_SUCCESS);
|
||||
}
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Disabled input dump of size %zd\n", ftdmchan->rxdump.size);
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Disabled input dump of size %"FTDM_SIZE_FMT"\n",
|
||||
ftdmchan->rxdump.size);
|
||||
stop_chan_io_dump(&ftdmchan->rxdump);
|
||||
GOTO_STATUS(done, FTDM_SUCCESS);
|
||||
}
|
||||
|
@ -2829,7 +2855,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co
|
|||
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failed to enable output dump of size %d\n", size);
|
||||
GOTO_STATUS(done, FTDM_FAIL);
|
||||
}
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Enabled output dump with size %zd\n", size);
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Enabled output dump with size %"FTDM_SIZE_FMT"\n", size);
|
||||
GOTO_STATUS(done, FTDM_SUCCESS);
|
||||
}
|
||||
break;
|
||||
|
@ -2841,7 +2867,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co
|
|||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "No need to disable output dump\n");
|
||||
GOTO_STATUS(done, FTDM_SUCCESS);
|
||||
}
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Disabled output dump of size %zd\n", ftdmchan->rxdump.size);
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Disabled output dump of size %"FTDM_SIZE_FMT"\n", ftdmchan->rxdump.size);
|
||||
stop_chan_io_dump(&ftdmchan->txdump);
|
||||
GOTO_STATUS(done, FTDM_SUCCESS);
|
||||
}
|
||||
|
@ -2874,7 +2900,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co
|
|||
GOTO_STATUS(done, FTDM_FAIL);
|
||||
}
|
||||
dump_chan_io_to_file(ftdmchan, &ftdmchan->txdump, obj);
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Dumped input of size %zd to file %p\n", ftdmchan->txdump.size, obj);
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Dumped input of size %"FTDM_SIZE_FMT" to file %p\n", ftdmchan->txdump.size, obj);
|
||||
GOTO_STATUS(done, FTDM_SUCCESS);
|
||||
}
|
||||
break;
|
||||
|
@ -3373,7 +3399,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_queue_dtmf(ftdm_channel_t *ftdmchan, cons
|
|||
ftdmchan->span_id, ftdmchan->chan_id,
|
||||
currtime.tm_year-100, currtime.tm_mon+1, currtime.tm_mday,
|
||||
currtime.tm_hour, currtime.tm_min, currtime.tm_sec, ftdmchan->native_codec == FTDM_CODEC_ULAW ? "ulaw" : ftdmchan->native_codec == FTDM_CODEC_ALAW ? "alaw" : "sln");
|
||||
ftdmchan->dtmfdbg.file = fopen(dfile, "w");
|
||||
ftdmchan->dtmfdbg.file = fopen(dfile, "wb");
|
||||
if (!ftdmchan->dtmfdbg.file) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "failed to open debug dtmf file %s\n", dfile);
|
||||
} else {
|
||||
|
@ -3443,7 +3469,7 @@ static FIO_WRITE_FUNCTION(ftdm_raw_write)
|
|||
}
|
||||
if (ftdmchan->fds[FTDM_WRITE_TRACE_INDEX] > -1) {
|
||||
if ((write(ftdmchan->fds[FTDM_WRITE_TRACE_INDEX], data, dlen)) != dlen) {
|
||||
ftdm_log(FTDM_LOG_WARNING, "Raw output trace failed to write all of the %zd bytes\n", dlen);
|
||||
ftdm_log(FTDM_LOG_WARNING, "Raw output trace failed to write all of the %"FTDM_SIZE_FMT" bytes\n", dlen);
|
||||
}
|
||||
}
|
||||
write_chan_io_dump(&ftdmchan->txdump, data, dlen);
|
||||
|
@ -3456,7 +3482,7 @@ static FIO_READ_FUNCTION(ftdm_raw_read)
|
|||
if (status == FTDM_SUCCESS && ftdmchan->fds[FTDM_READ_TRACE_INDEX] > -1) {
|
||||
ftdm_size_t dlen = *datalen;
|
||||
if ((ftdm_size_t)write(ftdmchan->fds[FTDM_READ_TRACE_INDEX], data, (int)dlen) != dlen) {
|
||||
ftdm_log(FTDM_LOG_WARNING, "Raw input trace failed to write all of the %zd bytes\n", dlen);
|
||||
ftdm_log(FTDM_LOG_WARNING, "Raw input trace failed to write all of the %"FTDM_SIZE_FMT" bytes\n", dlen);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4697,7 +4723,7 @@ static ftdm_status_t load_config(void)
|
|||
len = strlen(val);
|
||||
if (len >= FTDM_MAX_NAME_STR_SZ) {
|
||||
len = FTDM_MAX_NAME_STR_SZ - 1;
|
||||
ftdm_log(FTDM_LOG_WARNING, "Truncating group name %s to %zd length\n", val, len);
|
||||
ftdm_log(FTDM_LOG_WARNING, "Truncating group name %s to %"FTDM_SIZE_FMT" length\n", val, len);
|
||||
}
|
||||
memcpy(chan_config.group_name, val, len);
|
||||
chan_config.group_name[len] = '\0';
|
||||
|
@ -5281,6 +5307,7 @@ static ftdm_status_t ftdm_span_trigger_signal(const ftdm_span_t *span, ftdm_sigm
|
|||
if (sigmsg->channel) {
|
||||
ftdm_call_clear_data(&(sigmsg->channel->caller_data));
|
||||
}
|
||||
ftdm_safe_free(sigmsg->raw_data);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -5288,8 +5315,6 @@ static ftdm_status_t ftdm_span_queue_signal(const ftdm_span_t *span, ftdm_sigmsg
|
|||
{
|
||||
ftdm_sigmsg_t *new_sigmsg = NULL;
|
||||
|
||||
ftdm_assert_return((sigmsg->raw_data == NULL), FTDM_FAIL, "No raw data should be used with asynchronous notification\n");
|
||||
|
||||
new_sigmsg = ftdm_calloc(1, sizeof(*sigmsg));
|
||||
if (!new_sigmsg) {
|
||||
return FTDM_FAIL;
|
||||
|
@ -5328,7 +5353,7 @@ static void execute_safety_hangup(void *data)
|
|||
FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t *sigmsg)
|
||||
{
|
||||
if (sigmsg->channel) {
|
||||
ftdm_mutex_lock(sigmsg->channel->mutex);
|
||||
ftdm_mutex_lock(sigmsg->channel->mutex);
|
||||
}
|
||||
|
||||
/* some core things to do on special events */
|
||||
|
@ -5336,7 +5361,7 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t
|
|||
|
||||
case FTDM_SIGEVENT_SIGSTATUS_CHANGED:
|
||||
{
|
||||
ftdm_signaling_status_t sigstatus = ftdm_test_flag(span, FTDM_SPAN_USE_SIGNALS_QUEUE) ? sigmsg->sigstatus : *((ftdm_signaling_status_t*)(sigmsg->raw_data));
|
||||
ftdm_signaling_status_t sigstatus = ftdm_test_flag(span, FTDM_SPAN_USE_SIGNALS_QUEUE) ? sigmsg->ev_data.sigstatus.status : *((ftdm_signaling_status_t*)(sigmsg->raw_data));
|
||||
if (sigstatus == FTDM_SIG_STATE_UP) {
|
||||
ftdm_set_flag(sigmsg->channel, FTDM_CHANNEL_SIG_UP);
|
||||
} else {
|
||||
|
@ -5347,6 +5372,7 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t
|
|||
|
||||
case FTDM_SIGEVENT_START:
|
||||
{
|
||||
ftdm_call_set_call_id(&sigmsg->channel->caller_data);
|
||||
ftdm_set_echocancel_call_begin(sigmsg->channel);
|
||||
if (sigmsg->channel->dtmfdbg.requested) {
|
||||
ftdm_channel_command(sigmsg->channel, FTDM_COMMAND_ENABLE_DEBUG_DTMF, NULL);
|
||||
|
@ -5376,7 +5402,10 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t
|
|||
break;
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (sigmsg->channel) {
|
||||
sigmsg->call_id = sigmsg->channel->caller_data.call_id;
|
||||
}
|
||||
/* if the signaling module uses a queue for signaling notifications, then enqueue it */
|
||||
if (ftdm_test_flag(span, FTDM_SPAN_USE_SIGNALS_QUEUE)) {
|
||||
ftdm_span_queue_signal(span, sigmsg);
|
||||
|
@ -5485,6 +5514,8 @@ FT_DECLARE(ftdm_status_t) ftdm_global_init(void)
|
|||
ftdm_mutex_create(&globals.mutex);
|
||||
ftdm_mutex_create(&globals.span_mutex);
|
||||
ftdm_mutex_create(&globals.group_mutex);
|
||||
ftdm_mutex_create(&globals.call_id_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");
|
||||
|
@ -5494,6 +5525,7 @@ FT_DECLARE(ftdm_status_t) ftdm_global_init(void)
|
|||
ftdm_log(FTDM_LOG_CRIT, "Failed to run master timing schedule context\n");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
globals.running = 1;
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
@ -5597,6 +5629,7 @@ FT_DECLARE(ftdm_status_t) ftdm_global_destroy(void)
|
|||
ftdm_mutex_destroy(&globals.mutex);
|
||||
ftdm_mutex_destroy(&globals.span_mutex);
|
||||
ftdm_mutex_destroy(&globals.group_mutex);
|
||||
ftdm_mutex_destroy(&globals.call_id_mutex);
|
||||
|
||||
memset(&globals, 0, sizeof(globals));
|
||||
return FTDM_SUCCESS;
|
||||
|
@ -5955,6 +5988,47 @@ FT_DECLARE(char *) ftdm_channel_get_history_str(const ftdm_channel_t *fchan)
|
|||
return stream.data;
|
||||
}
|
||||
|
||||
static ftdm_status_t ftdm_call_set_call_id(ftdm_caller_data_t *caller_data)
|
||||
{
|
||||
uint32_t current_call_id;
|
||||
ftdm_assert_return(!caller_data->call_id, FTDM_FAIL, "Overwriting non-cleared call-id");
|
||||
|
||||
ftdm_mutex_lock(globals.call_id_mutex);
|
||||
current_call_id = globals.last_call_id;
|
||||
|
||||
do {
|
||||
if (++current_call_id > MAX_CALLIDS) {
|
||||
current_call_id = 1;
|
||||
}
|
||||
if (globals.call_ids[current_call_id] != NULL) {
|
||||
continue;
|
||||
}
|
||||
} while (0);
|
||||
|
||||
globals.last_call_id = current_call_id;
|
||||
caller_data->call_id = current_call_id;
|
||||
|
||||
globals.call_ids[current_call_id] = caller_data;
|
||||
ftdm_mutex_unlock(globals.call_id_mutex);
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
static ftdm_status_t ftdm_call_clear_call_id(ftdm_caller_data_t *caller_data)
|
||||
{
|
||||
ftdm_assert_return((caller_data->call_id && caller_data->call_id <= MAX_CALLIDS), FTDM_FAIL, "Clearing call with invalid call-id\n");
|
||||
ftdm_mutex_lock(globals.call_id_mutex);
|
||||
if (globals.call_ids[caller_data->call_id]) {
|
||||
caller_data->call_id = 0;
|
||||
globals.call_ids[caller_data->call_id] = NULL;
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_CRIT, "call-id did not exist %u\n", caller_data->call_id);
|
||||
}
|
||||
ftdm_mutex_unlock(globals.call_id_mutex);
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
|
|
|
@ -156,7 +156,7 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
|
|||
release_request_id((m3ua_request_id_t)ftdmchan->extra_id);
|
||||
ftdmchan->extra_id = 0;
|
||||
}
|
||||
ftdm_channel_done(ftdmchan);
|
||||
ftdm_channel_close(&ftdmchan);
|
||||
}
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
|
||||
|
|
|
@ -1325,7 +1325,7 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
|
|||
}
|
||||
Q931ReleaseCRV(&isdn_data->q931, gen->CRV);
|
||||
}
|
||||
ftdm_channel_done(ftdmchan);
|
||||
ftdm_channel_close(&ftdmchan);
|
||||
}
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_PROGRESS:
|
||||
|
|
|
@ -280,12 +280,12 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
|
|||
|
||||
switch (ftdmchan->state) {
|
||||
case FTDM_CHANNEL_STATE_DOWN:
|
||||
{
|
||||
ftdm_channel_done(ftdmchan);
|
||||
{
|
||||
ftdmchan->call_data = NULL;
|
||||
ftdm_channel_close(&ftdmchan);
|
||||
|
||||
ftdm_channel_done(peerchan);
|
||||
peerchan->call_data = NULL;
|
||||
ftdm_channel_close(&peerchan);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -55,10 +55,13 @@ static int32_t g_thread_count = 0;
|
|||
|
||||
typedef int openr2_call_status_t;
|
||||
|
||||
/* when the users kills a span we clear this flag to kill the signaling thread */
|
||||
/* when the user stops a span, we clear FTDM_R2_SPAN_STARTED, so that the signaling thread
|
||||
* knows it must stop, and we wait for FTDM_R2_RUNNING to be clear, which tells us the
|
||||
* signaling thread is done. */
|
||||
/* FIXME: what about the calls that are already up-and-running? */
|
||||
typedef enum {
|
||||
FTDM_R2_RUNNING = (1 << 0),
|
||||
FTDM_R2_SPAN_STARTED = (1 << 1),
|
||||
} ftdm_r2_flag_t;
|
||||
|
||||
/* private call information stored in ftdmchan->call_data void* ptr,
|
||||
|
@ -255,7 +258,7 @@ static void ftdm_r2_set_chan_sig_status(ftdm_channel_t *ftdmchan, ftdm_signaling
|
|||
sig.span_id = ftdmchan->span_id;
|
||||
sig.channel = ftdmchan;
|
||||
sig.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
|
||||
sig.sigstatus = status;
|
||||
sig.ev_data.sigstatus.status = status;
|
||||
if (ftdm_span_send_signal(ftdmchan->span, &sig) != FTDM_SUCCESS) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failed to change channel status to %s\n", ftdm_signaling_status2str(status));
|
||||
}
|
||||
|
@ -424,13 +427,14 @@ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(r2_outgoing_call)
|
|||
static ftdm_status_t ftdm_r2_start(ftdm_span_t *span)
|
||||
{
|
||||
ftdm_r2_data_t *r2_data = span->signal_data;
|
||||
ftdm_set_flag(r2_data, FTDM_R2_RUNNING);
|
||||
ftdm_set_flag(r2_data, FTDM_R2_SPAN_STARTED);
|
||||
return ftdm_thread_create_detached(ftdm_r2_run, span);
|
||||
}
|
||||
|
||||
static ftdm_status_t ftdm_r2_stop(ftdm_span_t *span)
|
||||
{
|
||||
ftdm_r2_data_t *r2_data = span->signal_data;
|
||||
ftdm_clear_flag(r2_data, FTDM_R2_SPAN_STARTED);
|
||||
while (ftdm_test_flag(r2_data, FTDM_R2_RUNNING)) {
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Waiting for R2 span %s\n", span->name);
|
||||
ftdm_sleep(100);
|
||||
|
@ -449,6 +453,88 @@ static FIO_CHANNEL_GET_SIG_STATUS_FUNCTION(ftdm_r2_get_channel_sig_status)
|
|||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
static FIO_CHANNEL_SET_SIG_STATUS_FUNCTION(ftdm_r2_set_channel_sig_status)
|
||||
{
|
||||
openr2_chan_t *r2chan = R2CALL(ftdmchan)->r2chan;
|
||||
switch(status) {
|
||||
case FTDM_SIG_STATE_DOWN:
|
||||
case FTDM_SIG_STATE_SUSPENDED:
|
||||
openr2_chan_set_blocked(r2chan);
|
||||
break;
|
||||
case FTDM_SIG_STATE_UP:
|
||||
openr2_chan_set_idle(r2chan);
|
||||
break;
|
||||
default:
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Cannot set signaling status to unknown value '%d'\n", status);
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
ftdm_r2_set_chan_sig_status(ftdmchan, status);
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
static FIO_SPAN_GET_SIG_STATUS_FUNCTION(ftdm_r2_get_span_sig_status)
|
||||
{
|
||||
ftdm_iterator_t *citer = NULL;
|
||||
ftdm_iterator_t *chaniter = ftdm_span_get_chan_iterator(span, NULL);
|
||||
if (!chaniter) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Failed to allocate channel iterator for span %s!\n", span->name);
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
/* if ALL channels are non-idle, report SUSPENDED. UP otherwise. */
|
||||
*status = FTDM_SIG_STATE_SUSPENDED;
|
||||
for (citer = chaniter; citer; citer = ftdm_iterator_next(citer)) {
|
||||
ftdm_channel_t *fchan = ftdm_iterator_current(citer);
|
||||
if (ftdm_test_flag(fchan, FTDM_CHANNEL_SIG_UP)) {
|
||||
*status = FTDM_SIG_STATE_UP;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ftdm_iterator_free(chaniter);
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
static FIO_SPAN_SET_SIG_STATUS_FUNCTION(ftdm_r2_set_span_sig_status)
|
||||
{
|
||||
ftdm_iterator_t *chaniter = NULL;
|
||||
ftdm_iterator_t *citer = NULL;
|
||||
uint32_t span_opr = -1;
|
||||
|
||||
/* we either set the channels to BLOCK or IDLE */
|
||||
switch(status) {
|
||||
case FTDM_SIG_STATE_DOWN:
|
||||
case FTDM_SIG_STATE_SUSPENDED:
|
||||
span_opr = 0;
|
||||
break;
|
||||
case FTDM_SIG_STATE_UP:
|
||||
span_opr = 1;
|
||||
break;
|
||||
default:
|
||||
ftdm_log(FTDM_LOG_WARNING, "Cannot set signaling status to unknown value '%d'\n", status);
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
chaniter = ftdm_span_get_chan_iterator(span, NULL);
|
||||
if (!chaniter) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Failed to allocate channel iterator for span %s!\n", span->name);
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
/* iterate over all channels, setting them to the requested state */
|
||||
for (citer = chaniter; citer; citer = ftdm_iterator_next(citer)) {
|
||||
ftdm_channel_t *fchan = ftdm_iterator_current(citer);
|
||||
openr2_chan_t *r2chan = R2CALL(fchan)->r2chan;
|
||||
if (span_opr == 0) {
|
||||
openr2_chan_set_blocked(r2chan);
|
||||
ftdm_log_chan_msg(fchan, FTDM_LOG_NOTICE, "Channel blocked\n");
|
||||
} else {
|
||||
openr2_chan_set_idle(r2chan);
|
||||
ftdm_log_chan_msg(fchan, FTDM_LOG_NOTICE, "Channel idle\n");
|
||||
}
|
||||
ftdm_r2_set_chan_sig_status(fchan, status);
|
||||
}
|
||||
ftdm_iterator_free(chaniter);
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
/* always called from the monitor thread */
|
||||
static void ftdm_r2_on_call_init(openr2_chan_t *r2chan)
|
||||
{
|
||||
|
@ -568,14 +654,14 @@ static void dump_mf(openr2_chan_t *r2chan)
|
|||
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Dumping IO output in prefix %s\n", logname);
|
||||
snprintf(dfile, sizeof(dfile), logname ? "%s.s%dc%d.input.alaw" : "%s/s%dc%d.input.alaw",
|
||||
logname ? logname : r2data->logdir, ftdmchan->span_id, ftdmchan->chan_id);
|
||||
f = fopen(dfile, "w");
|
||||
f = fopen(dfile, "wb");
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Dumping IO input in file %s\n", dfile);
|
||||
ftdm_channel_command(ftdmchan, FTDM_COMMAND_DUMP_INPUT, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(dfile, sizeof(dfile), logname ? "%s.s%dc%d.output.alaw" : "%s/s%dc%d.output.alaw",
|
||||
logname ? logname : r2data->logdir, ftdmchan->span_id, ftdmchan->chan_id);
|
||||
f = fopen(dfile, "w");
|
||||
f = fopen(dfile, "wb");
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Dumping IO output in file %s\n", dfile);
|
||||
ftdm_channel_command(ftdmchan, FTDM_COMMAND_DUMP_OUTPUT, f);
|
||||
fclose(f);
|
||||
|
@ -585,6 +671,8 @@ static void dump_mf(openr2_chan_t *r2chan)
|
|||
static void ftdm_r2_on_call_accepted(openr2_chan_t *r2chan, openr2_call_mode_t mode)
|
||||
{
|
||||
ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan);
|
||||
ftdm_r2_data_t *r2data = ftdmchan->span->signal_data;
|
||||
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_NOTICE, "Call accepted\n");
|
||||
|
||||
clear_accept_pending(ftdmchan);
|
||||
|
@ -607,6 +695,11 @@ static void ftdm_r2_on_call_accepted(openr2_chan_t *r2chan, openr2_call_mode_t m
|
|||
return;
|
||||
}
|
||||
} else {
|
||||
/* nothing went wrong during call setup, MF has ended, we can and must disable the MF dump */
|
||||
if (r2data->mf_dump_size) {
|
||||
ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_INPUT_DUMP, NULL);
|
||||
ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_OUTPUT_DUMP, NULL);
|
||||
}
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
|
||||
}
|
||||
}
|
||||
|
@ -665,7 +758,7 @@ static void ftdm_r2_on_call_read(openr2_chan_t *r2chan, const unsigned char *buf
|
|||
static void ftdm_r2_on_hardware_alarm(openr2_chan_t *r2chan, int alarm)
|
||||
{
|
||||
ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan);
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Alarm notification: %d\n", alarm);
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Alarm notification: %d\n", alarm);
|
||||
}
|
||||
|
||||
static void ftdm_r2_on_os_error(openr2_chan_t *r2chan, int errorcode)
|
||||
|
@ -1412,13 +1505,14 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_r2_configure_span_signaling)
|
|||
span->sig_read = NULL;
|
||||
span->sig_write = NULL;
|
||||
|
||||
/* let the core set the states, we just read them */
|
||||
span->get_channel_sig_status = ftdm_r2_get_channel_sig_status;
|
||||
|
||||
span->signal_cb = sig_cb;
|
||||
span->signal_type = FTDM_SIGTYPE_R2;
|
||||
span->signal_data = r2data;
|
||||
span->outgoing_call = r2_outgoing_call;
|
||||
span->get_span_sig_status = ftdm_r2_get_span_sig_status;
|
||||
span->set_span_sig_status = ftdm_r2_set_span_sig_status;
|
||||
span->get_channel_sig_status = ftdm_r2_get_channel_sig_status;
|
||||
span->set_channel_sig_status = ftdm_r2_set_channel_sig_status;
|
||||
|
||||
span->state_map = &r2_state_map;
|
||||
|
||||
|
@ -1666,6 +1760,9 @@ static void *ftdm_r2_run(ftdm_thread_t *me, void *obj)
|
|||
uint32_t txqueue_size = 4;
|
||||
short *poll_events = ftdm_malloc(sizeof(short) * span->chan_count);
|
||||
|
||||
/* as long as this thread is running, this flag is set */
|
||||
ftdm_set_flag(r2data, FTDM_R2_RUNNING);
|
||||
|
||||
#ifdef __linux__
|
||||
r2data->monitor_thread_id = syscall(SYS_gettid);
|
||||
#endif
|
||||
|
@ -1688,7 +1785,7 @@ static void *ftdm_r2_run(ftdm_thread_t *me, void *obj)
|
|||
|
||||
memset(&start, 0, sizeof(start));
|
||||
memset(&end, 0, sizeof(end));
|
||||
while (ftdm_running() && ftdm_test_flag(r2data, FTDM_R2_RUNNING)) {
|
||||
while (ftdm_running() && ftdm_test_flag(r2data, FTDM_R2_SPAN_STARTED)) {
|
||||
res = gettimeofday(&end, NULL);
|
||||
if (res) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Failure gettimeofday [%s]\n", strerror(errno));
|
||||
|
@ -1713,7 +1810,7 @@ static void *ftdm_r2_run(ftdm_thread_t *me, void *obj)
|
|||
|
||||
/* deliver the actual channel events to the user now without any channel locking */
|
||||
ftdm_span_trigger_signals(span);
|
||||
#ifndef WIN32
|
||||
|
||||
/* figure out what event to poll each channel for. POLLPRI when the channel is down,
|
||||
* POLLPRI|POLLIN|POLLOUT otherwise */
|
||||
memset(poll_events, 0, sizeof(short)*span->chan_count);
|
||||
|
@ -1725,16 +1822,12 @@ static void *ftdm_r2_run(ftdm_thread_t *me, void *obj)
|
|||
for (i = 0; citer; citer = ftdm_iterator_next(citer), i++) {
|
||||
ftdmchan = ftdm_iterator_current(citer);
|
||||
r2chan = R2CALL(ftdmchan)->r2chan;
|
||||
poll_events[i] = POLLPRI;
|
||||
poll_events[i] = FTDM_EVENTS;
|
||||
if (openr2_chan_get_read_enabled(r2chan)) {
|
||||
poll_events[i] |= POLLIN;
|
||||
poll_events[i] |= FTDM_READ;
|
||||
}
|
||||
}
|
||||
|
||||
status = ftdm_span_poll_event(span, waitms, poll_events);
|
||||
#else
|
||||
status = ftdm_span_poll_event(span, waitms, NULL);
|
||||
#endif
|
||||
|
||||
/* run any span timers */
|
||||
ftdm_sched_run(r2data->sched);
|
||||
|
@ -1955,7 +2048,7 @@ static FIO_API_FUNCTION(ftdm_r2_api)
|
|||
"Max DNIS: %d\n"
|
||||
"ANI First: %s\n"
|
||||
"Immediate Accept: %s\n"
|
||||
"Job Thread: %lu\n"
|
||||
"Job Thread: %u\n"
|
||||
"Job Max ms: %d\n"
|
||||
"Job Loops: %lu\n",
|
||||
openr2_proto_get_variant_string(r2variant),
|
||||
|
|
|
@ -839,7 +839,7 @@ static void handle_call_released(ftdm_span_t *span, sangomabc_connection_t *mcon
|
|||
if ((ftdmchan = find_ftdmchan(span, event, 1))) {
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Releasing completely chan s%dc%d\n", BOOST_EVENT_SPAN(mcon->sigmod, event),
|
||||
BOOST_EVENT_CHAN(mcon->sigmod, event));
|
||||
ftdm_channel_done(ftdmchan);
|
||||
ftdm_channel_close(&ftdmchan);
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Odd, We could not find chan: s%dc%d to release the call completely!!\n",
|
||||
BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event));
|
||||
|
@ -1105,8 +1105,9 @@ static void handle_call_loop_start(ftdm_span_t *span, sangomabc_connection_t *mc
|
|||
|
||||
ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_IN_LOOP, res);
|
||||
if (res != FTDM_SUCCESS) {
|
||||
ftdm_channel_t *toclose = ftdmchan;
|
||||
ftdm_log(FTDM_LOG_CRIT, "yay, could not set the state of the channel to IN_LOOP, loop will fail\n");
|
||||
ftdm_channel_done(ftdmchan);
|
||||
ftdm_channel_close(&toclose);
|
||||
return;
|
||||
}
|
||||
ftdm_log(FTDM_LOG_DEBUG, "%d:%d starting loop\n", ftdmchan->span_id, ftdmchan->chan_id);
|
||||
|
@ -1426,11 +1427,12 @@ static __inline__ ftdm_status_t state_advance(ftdm_channel_t *ftdmchan)
|
|||
ftdmchan->sflags = 0;
|
||||
memset(ftdmchan->call_data, 0, sizeof(sangoma_boost_call_t));
|
||||
if (sangoma_boost_data->sigmod && call_stopped_ack_sent) {
|
||||
/* we dont want to call ftdm_channel_done just yet until call released is received */
|
||||
/* we dont want to call ftdm_channel_close just yet until call released is received */
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Waiting for call release confirmation before declaring chan %d:%d as available \n",
|
||||
ftdmchan->span_id, ftdmchan->chan_id);
|
||||
} else {
|
||||
ftdm_channel_done(ftdmchan);
|
||||
ftdm_channel_t *toclose = ftdmchan;
|
||||
ftdm_channel_close(&toclose);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -65,7 +65,13 @@ ftdm_state_map_t sangoma_isdn_state_map = {
|
|||
ZSD_INBOUND,
|
||||
ZSM_UNACCEPTABLE,
|
||||
{FTDM_ANY_STATE, FTDM_END},
|
||||
{FTDM_CHANNEL_STATE_RESTART, FTDM_CHANNEL_STATE_SUSPENDED, FTDM_END}
|
||||
{FTDM_CHANNEL_STATE_RESET, FTDM_CHANNEL_STATE_RESTART, FTDM_END}
|
||||
},
|
||||
{
|
||||
ZSD_INBOUND,
|
||||
ZSM_UNACCEPTABLE,
|
||||
{FTDM_CHANNEL_STATE_RESET, FTDM_END},
|
||||
{FTDM_CHANNEL_STATE_DOWN, FTDM_END}
|
||||
},
|
||||
{
|
||||
ZSD_INBOUND,
|
||||
|
@ -170,7 +176,13 @@ ftdm_state_map_t sangoma_isdn_state_map = {
|
|||
ZSD_OUTBOUND,
|
||||
ZSM_UNACCEPTABLE,
|
||||
{FTDM_ANY_STATE, FTDM_END},
|
||||
{FTDM_CHANNEL_STATE_RESTART, FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END}
|
||||
{FTDM_CHANNEL_STATE_RESET, FTDM_CHANNEL_STATE_RESTART, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END}
|
||||
},
|
||||
{
|
||||
ZSD_OUTBOUND,
|
||||
ZSM_UNACCEPTABLE,
|
||||
{FTDM_CHANNEL_STATE_RESET, FTDM_END},
|
||||
{FTDM_CHANNEL_STATE_DOWN, FTDM_END}
|
||||
},
|
||||
{
|
||||
ZSD_OUTBOUND,
|
||||
|
@ -203,7 +215,7 @@ ftdm_state_map_t sangoma_isdn_state_map = {
|
|||
ZSM_UNACCEPTABLE,
|
||||
{FTDM_CHANNEL_STATE_DIALING, FTDM_END},
|
||||
{FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP,
|
||||
FTDM_CHANNEL_STATE_PROCEED, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP,
|
||||
FTDM_CHANNEL_STATE_PROCEED, FTDM_CHANNEL_STATE_RINGING, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP,
|
||||
FTDM_CHANNEL_STATE_DOWN, FTDM_END}
|
||||
},
|
||||
{
|
||||
|
@ -211,14 +223,20 @@ ftdm_state_map_t sangoma_isdn_state_map = {
|
|||
ZSM_UNACCEPTABLE,
|
||||
{FTDM_CHANNEL_STATE_PROCEED, FTDM_END},
|
||||
{FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP,
|
||||
FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_END},
|
||||
},
|
||||
FTDM_CHANNEL_STATE_RINGING, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_END},
|
||||
},
|
||||
{
|
||||
ZSD_OUTBOUND,
|
||||
ZSM_UNACCEPTABLE,
|
||||
{FTDM_CHANNEL_STATE_PROGRESS, FTDM_END},
|
||||
{FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_END},
|
||||
},
|
||||
{
|
||||
ZSD_OUTBOUND,
|
||||
ZSM_UNACCEPTABLE,
|
||||
{FTDM_CHANNEL_STATE_RINGING, FTDM_END},
|
||||
{FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_END},
|
||||
},
|
||||
{
|
||||
ZSD_OUTBOUND,
|
||||
ZSM_UNACCEPTABLE,
|
||||
|
@ -680,8 +698,17 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan)
|
|||
break;
|
||||
case FTDM_CHANNEL_STATE_RINGING:
|
||||
{
|
||||
ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_NETE_ISDN};
|
||||
sngisdn_snd_alert(ftdmchan, prog_ind);
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
|
||||
/* OUTBOUND...so we were told by the line of this so notify the user */
|
||||
sigev.event_id = FTDM_SIGEVENT_RINGING;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
if (sngisdn_test_flag(sngisdn_info, FLAG_MEDIA_READY)) {
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
|
||||
}
|
||||
} else {
|
||||
ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_NETE_ISDN};
|
||||
sngisdn_snd_alert(ftdmchan, prog_ind);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_PROGRESS:
|
||||
|
@ -692,12 +719,9 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan)
|
|||
sigev.event_id = FTDM_SIGEVENT_PROGRESS;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
} else {
|
||||
/* If we already sent a PROCEED before, do not send a PROGRESS as there is nothing to indicate to the remote switch */
|
||||
if (ftdmchan->last_state != FTDM_CHANNEL_STATE_PROCEED) {
|
||||
/* Send a progress message, indicating: Call is not end-to-end ISDN, further call progress may be available */
|
||||
ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_NETE_ISDN};
|
||||
sngisdn_snd_progress(ftdmchan, prog_ind);
|
||||
}
|
||||
/* Send a progress message, indicating: Call is not end-to-end ISDN, further call progress may be available */
|
||||
ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_NETE_ISDN};
|
||||
sngisdn_snd_progress(ftdmchan, prog_ind);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -780,7 +804,7 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan)
|
|||
sngisdn_snd_release(ftdmchan, 0);
|
||||
|
||||
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP)) {
|
||||
sngisdn_set_avail_rate(ftdmchan->span, SNGISDN_AVAIL_DOWN);
|
||||
sngisdn_set_span_avail_rate(ftdmchan->span, SNGISDN_AVAIL_DOWN);
|
||||
}
|
||||
} else {
|
||||
sngisdn_snd_disconnect(ftdmchan);
|
||||
|
@ -838,6 +862,11 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan)
|
|||
/* IMPLEMENT ME */
|
||||
}
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_RESET:
|
||||
{
|
||||
sngisdn_snd_restart(ftdmchan);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "unsupported sngisdn_rcvd state %s\n", ftdm_channel_state2str(ftdmchan->state));
|
||||
|
@ -862,10 +891,6 @@ static FIO_CHANNEL_SEND_MSG_FUNCTION(ftdm_sangoma_isdn_send_msg)
|
|||
ftdm_status_t status = FTDM_FAIL;
|
||||
|
||||
switch (sigmsg->event_id) {
|
||||
case FTDM_SIGEVENT_RESTART:
|
||||
/* TODO: Send a channel restart here */
|
||||
/* Implement me */
|
||||
break;
|
||||
case FTDM_SIGEVENT_FACILITY:
|
||||
sngisdn_snd_fac_req(ftdmchan);
|
||||
break;
|
||||
|
@ -951,7 +976,8 @@ static FIO_SPAN_SET_SIG_STATUS_FUNCTION(ftdm_sangoma_isdn_set_span_sig_status)
|
|||
}
|
||||
|
||||
static ftdm_status_t ftdm_sangoma_isdn_start(ftdm_span_t *span)
|
||||
{
|
||||
{
|
||||
sngisdn_span_data_t *signal_data = span->signal_data;
|
||||
ftdm_log(FTDM_LOG_INFO,"Starting span %s:%u.\n",span->name,span->span_id);
|
||||
if (sngisdn_stack_start(span) != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Failed to start span %s\n", span->name);
|
||||
|
@ -961,6 +987,14 @@ static ftdm_status_t ftdm_sangoma_isdn_start(ftdm_span_t *span)
|
|||
ftdm_clear_flag(span, FTDM_SPAN_STOP_THREAD);
|
||||
ftdm_clear_flag(span, FTDM_SPAN_IN_THREAD);
|
||||
|
||||
if (signal_data->raw_trace_q921 == SNGISDN_OPT_TRUE) {
|
||||
sngisdn_activate_trace(span, SNGISDN_TRACE_Q921);
|
||||
}
|
||||
|
||||
if (signal_data->raw_trace_q931 == SNGISDN_OPT_TRUE) {
|
||||
sngisdn_activate_trace(span, SNGISDN_TRACE_Q931);
|
||||
}
|
||||
|
||||
/*start the span monitor thread*/
|
||||
if (ftdm_thread_create_detached(ftdm_sangoma_isdn_run, span) != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_CRIT,"Failed to start Sangoma ISDN Span Monitor Thread!\n");
|
||||
|
@ -1072,7 +1106,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_isdn_span_config)
|
|||
if (span->trunk_type == FTDM_TRUNK_BRI_PTMP ||
|
||||
span->trunk_type == FTDM_TRUNK_BRI) {
|
||||
|
||||
sngisdn_set_avail_rate(span, SNGISDN_AVAIL_PWR_SAVING);
|
||||
sngisdn_set_span_avail_rate(span, SNGISDN_AVAIL_PWR_SAVING);
|
||||
}
|
||||
|
||||
/* Initialize scheduling context */
|
||||
|
@ -1167,6 +1201,7 @@ static FIO_API_FUNCTION(ftdm_sangoma_isdn_api)
|
|||
goto done;
|
||||
}
|
||||
|
||||
/* TODO: Move functions to table + function pointers */
|
||||
if (!strcasecmp(argv[0], "trace")) {
|
||||
char *trace_opt;
|
||||
|
||||
|
@ -1184,6 +1219,7 @@ static FIO_API_FUNCTION(ftdm_sangoma_isdn_api)
|
|||
stream->write_function(stream, "-ERR failed to find span by name %s\n", argv[2]);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!strcasecmp(trace_opt, "q921")) {
|
||||
sngisdn_activate_trace(span, SNGISDN_TRACE_Q921);
|
||||
} else if (!strcasecmp(trace_opt, "q931")) {
|
||||
|
@ -1192,7 +1228,7 @@ static FIO_API_FUNCTION(ftdm_sangoma_isdn_api)
|
|||
sngisdn_activate_trace(span, SNGISDN_TRACE_DISABLE);
|
||||
} else {
|
||||
stream->write_function(stream, "-ERR invalid trace option <q921|q931> <span name>\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!strcasecmp(argv[0], "l1_stats")) {
|
||||
ftdm_span_t *span;
|
||||
|
@ -1210,7 +1246,7 @@ static FIO_API_FUNCTION(ftdm_sangoma_isdn_api)
|
|||
}
|
||||
sngisdn_print_phy_stats(stream, span);
|
||||
}
|
||||
|
||||
|
||||
if (!strcasecmp(argv[0], "show_spans")) {
|
||||
ftdm_span_t *span = NULL;
|
||||
if (argc == 2) {
|
||||
|
|
|
@ -101,9 +101,11 @@ typedef enum {
|
|||
FLAG_GLARE = (1 << 6),
|
||||
FLAG_DELAYED_REL = (1 << 7),
|
||||
FLAG_SENT_PROCEED = (1 << 8),
|
||||
FLAG_SEND_DISC = (1 << 9),
|
||||
FLAG_SEND_DISC = (1 << 9),
|
||||
/* Used for BRI only, flag is set after we request line CONNECTED */
|
||||
FLAG_ACTIVATING = (1 << 10),
|
||||
FLAG_ACTIVATING = (1 << 10),
|
||||
/* Used when we receive an ALERT msg + inband tones ready */
|
||||
FLAG_MEDIA_READY = (1 << 11),
|
||||
} sngisdn_flag_t;
|
||||
|
||||
|
||||
|
@ -259,6 +261,8 @@ typedef struct sngisdn_span_data {
|
|||
int8_t facility_timeout;
|
||||
uint8_t num_local_numbers;
|
||||
uint8_t ignore_cause_value;
|
||||
uint8_t raw_trace_q931;
|
||||
uint8_t raw_trace_q921;
|
||||
uint8_t timer_t3;
|
||||
uint8_t restart_opt;
|
||||
char* local_numbers[SNGISDN_NUM_LOCAL_NUMBERS];
|
||||
|
@ -352,8 +356,11 @@ void clear_call_glare_data(sngisdn_chan_data_t *sngisdn_info);
|
|||
ftdm_status_t get_ftdmchan_by_suInstId(int16_t cc_id, uint32_t suInstId, sngisdn_chan_data_t **sngisdn_data);
|
||||
ftdm_status_t get_ftdmchan_by_spInstId(int16_t cc_id, uint32_t spInstId, sngisdn_chan_data_t **sngisdn_data);
|
||||
|
||||
ftdm_status_t sngisdn_set_span_avail_rate(ftdm_span_t *span, sngisdn_avail_t avail);
|
||||
ftdm_status_t sngisdn_set_chan_avail_rate(ftdm_channel_t *chan, sngisdn_avail_t avail);
|
||||
void sngisdn_set_span_sig_status(ftdm_span_t *ftdmspan, ftdm_signaling_status_t status);
|
||||
void sngisdn_set_chan_sig_status(ftdm_channel_t *ftdmchan, ftdm_signaling_status_t status);
|
||||
|
||||
ftdm_status_t sngisdn_set_avail_rate(ftdm_span_t *span, sngisdn_avail_t avail);
|
||||
ftdm_status_t sngisdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t trace_opt);
|
||||
|
||||
|
||||
|
@ -374,6 +381,7 @@ void sngisdn_snd_con_complete(ftdm_channel_t *ftdmchan);
|
|||
void sngisdn_snd_fac_req(ftdm_channel_t *ftdmchan);
|
||||
void sngisdn_snd_info_req(ftdm_channel_t *ftdmchan);
|
||||
void sngisdn_snd_status_enq(ftdm_channel_t *ftdmchan);
|
||||
void sngisdn_snd_restart(ftdm_channel_t *ftdmchan);
|
||||
void sngisdn_snd_data(ftdm_channel_t *dchan, uint8_t *data, ftdm_size_t len);
|
||||
void sngisdn_snd_event(ftdm_channel_t *dchan, ftdm_oob_event_t event);
|
||||
|
||||
|
@ -421,8 +429,11 @@ void sngisdn_process_rst_ind (sngisdn_event_data_t *sngisdn_event);
|
|||
void sngisdn_rcv_phy_ind(SuId suId, Reason reason);
|
||||
void sngisdn_rcv_q921_ind(BdMngmt *status);
|
||||
|
||||
void sngisdn_trace_q921(char* str, uint8_t* data, uint32_t data_len);
|
||||
void sngisdn_trace_q931(char* str, uint8_t* data, uint32_t data_len);
|
||||
void sngisdn_trace_interpreted_q921(sngisdn_span_data_t *signal_data, ftdm_trace_dir_t dir, uint8_t *data, uint32_t data_len);
|
||||
void sngisdn_trace_interpreted_q931(sngisdn_span_data_t *signal_data, ftdm_trace_dir_t dir, uint8_t *data, uint32_t data_len);
|
||||
void sngisdn_trace_raw_q921(sngisdn_span_data_t *signal_data, ftdm_trace_dir_t dir, uint8_t *data, uint32_t data_len);
|
||||
void sngisdn_trace_raw_q931(sngisdn_span_data_t *signal_data, ftdm_trace_dir_t dir, uint8_t *data, uint32_t data_len);
|
||||
|
||||
void get_memory_info(void);
|
||||
|
||||
ftdm_status_t sng_isdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t trace_opt);
|
||||
|
@ -453,6 +464,9 @@ ftdm_status_t set_redir_num(ftdm_channel_t *ftdmchan, RedirNmb *redirNmb);
|
|||
ftdm_status_t set_calling_name(ftdm_channel_t *ftdmchan, ConEvnt *conEvnt);
|
||||
ftdm_status_t set_calling_subaddr(ftdm_channel_t *ftdmchan, CgPtySad *cgPtySad);
|
||||
ftdm_status_t set_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd, ftdm_sngisdn_progind_t prog_ind);
|
||||
ftdm_status_t set_bear_cap_ie(ftdm_channel_t *ftdmchan, BearCap *bearCap);
|
||||
ftdm_status_t set_chan_id_ie(ftdm_channel_t *ftdmchan, ChanId *chanId);
|
||||
ftdm_status_t set_restart_ind_ie(ftdm_channel_t *ftdmchan, RstInd *rstInd);
|
||||
ftdm_status_t set_facility_ie(ftdm_channel_t *ftdmchan, FacilityStr *facilityStr);
|
||||
ftdm_status_t set_facility_ie_str(ftdm_channel_t *ftdmchan, uint8_t *data, uint8_t *data_len);
|
||||
|
||||
|
@ -482,7 +496,6 @@ static __inline__ void sngisdn_set_flag(sngisdn_chan_data_t *sngisdn_info, sngis
|
|||
|
||||
|
||||
void handle_sng_log(uint8_t level, char *fmt,...);
|
||||
void sngisdn_set_span_sig_status(ftdm_span_t *ftdmspan, ftdm_signaling_status_t status);
|
||||
void sngisdn_delayed_setup(void* p_sngisdn_info);
|
||||
void sngisdn_delayed_release(void* p_sngisdn_info);
|
||||
void sngisdn_delayed_connect(void* p_sngisdn_info);
|
||||
|
|
|
@ -296,6 +296,10 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_
|
|||
parse_yesno(var, val, &signal_data->facility_ie_decode);
|
||||
} else if (!strcasecmp(var, "ignore-cause-value")) {
|
||||
parse_yesno(var, val, &signal_data->ignore_cause_value);
|
||||
} else if (!strcasecmp(var, "q931-raw-trace")) {
|
||||
parse_yesno(var, val, &signal_data->raw_trace_q931);
|
||||
} else if (!strcasecmp(var, "q921-raw-trace")) {
|
||||
parse_yesno(var, val, &signal_data->raw_trace_q921);
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_WARNING, "Ignoring unknown parameter %s\n", ftdm_parameters[paramindex].var);
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ void sngisdn_set_chan_sig_status(ftdm_channel_t *ftdmchan, ftdm_signaling_status
|
|||
sig.span_id = ftdmchan->span_id;
|
||||
sig.channel = ftdmchan;
|
||||
sig.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
|
||||
sig.sigstatus = status;
|
||||
sig.ev_data.sigstatus.status = status;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sig);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -33,7 +33,8 @@
|
|||
*/
|
||||
|
||||
#include "ftmod_sangoma_isdn.h"
|
||||
ftdm_status_t sngisdn_cause_val_requires_disconnect(ftdm_channel_t *ftdmchan, CauseDgn *causeDgn);
|
||||
static ftdm_status_t sngisdn_cause_val_requires_disconnect(ftdm_channel_t *ftdmchan, CauseDgn *causeDgn);
|
||||
static void sngisdn_process_restart_confirm(ftdm_channel_t *ftdmchan);
|
||||
|
||||
/* Remote side transmit a SETUP */
|
||||
void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
|
||||
|
@ -232,6 +233,9 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
|
|||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
|
||||
}
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_RESET:
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n");
|
||||
break;
|
||||
default:
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Processing SETUP in an invalid state (%s)\n", ftdm_channel_state2str(ftdmchan->state));
|
||||
break;
|
||||
|
@ -274,6 +278,7 @@ void sngisdn_process_con_cfm (sngisdn_event_data_t *sngisdn_event)
|
|||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
|
||||
switch(ftdmchan->state) {
|
||||
case FTDM_CHANNEL_STATE_PROCEED:
|
||||
case FTDM_CHANNEL_STATE_RINGING:
|
||||
case FTDM_CHANNEL_STATE_PROGRESS:
|
||||
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
|
||||
case FTDM_CHANNEL_STATE_DIALING:
|
||||
|
@ -285,6 +290,9 @@ void sngisdn_process_con_cfm (sngisdn_event_data_t *sngisdn_event)
|
|||
case FTDM_CHANNEL_STATE_HANGUP:
|
||||
/* Race condition, we just hung up the call - ignore this message */
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_RESET:
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n");
|
||||
break;
|
||||
default:
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Processing CONNECT/CONNECT ACK in an invalid state (%s)\n", ftdm_channel_state2str(ftdmchan->state));
|
||||
|
||||
|
@ -301,6 +309,9 @@ void sngisdn_process_con_cfm (sngisdn_event_data_t *sngisdn_event)
|
|||
case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
|
||||
/* Race condition, We just hung up an incoming call right after we sent a CONNECT - ignore this message */
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_RESET:
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n");
|
||||
break;
|
||||
default:
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Processing CONNECT/CONNECT ACK in an invalid state (%s)\n", ftdm_channel_state2str(ftdmchan->state));
|
||||
|
||||
|
@ -354,27 +365,47 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event)
|
|||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
|
||||
goto sngisdn_process_cnst_ind_end;
|
||||
}
|
||||
|
||||
|
||||
switch(ftdmchan->state) {
|
||||
case FTDM_CHANNEL_STATE_DIALING:
|
||||
case FTDM_CHANNEL_STATE_PROCEED:
|
||||
if (cnStEvnt->progInd.eh.pres && cnStEvnt->progInd.progDesc.val == IN_PD_IBAVAIL) {
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
|
||||
} else if (evntType == MI_CALLPROC) {
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROCEED);
|
||||
} else {
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS);
|
||||
}
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_PROGRESS:
|
||||
case FTDM_CHANNEL_STATE_RINGING:
|
||||
if (cnStEvnt->progInd.eh.pres && cnStEvnt->progInd.progDesc.val == IN_PD_IBAVAIL) {
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
|
||||
sngisdn_set_flag(sngisdn_info, FLAG_MEDIA_READY);
|
||||
}
|
||||
switch (evntType) {
|
||||
case MI_CALLPROC:
|
||||
if (ftdmchan->state == FTDM_CHANNEL_STATE_DIALING) {
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROCEED);
|
||||
}
|
||||
break;
|
||||
case MI_ALERTING:
|
||||
if (ftdmchan->state == FTDM_CHANNEL_STATE_PROCEED) {
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RINGING);
|
||||
}
|
||||
break;
|
||||
case MI_PROGRESS:
|
||||
if (sngisdn_test_flag(sngisdn_info, FLAG_MEDIA_READY)) {
|
||||
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
|
||||
} else if (ftdmchan->state != FTDM_CHANNEL_STATE_PROGRESS) {
|
||||
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* We should never reach this section !*/
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle this event %d\n", evntType);
|
||||
}
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
|
||||
/* We are already in progress media, we can't go to any higher state except up */
|
||||
/* Do nothing */
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_RESET:
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n");
|
||||
break;
|
||||
default:
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Processing ALERT/PROCEED/PROGRESS in an invalid state (%s)\n", ftdm_channel_state2str(ftdmchan->state));
|
||||
|
||||
|
@ -414,6 +445,9 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event)
|
|||
case FTDM_CHANNEL_STATE_UP:
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Receiving more digits %s, but we already proceeded with call\n", cnStEvnt->cdPtyNmb.nmbDigits.val);
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_RESET:
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n");
|
||||
break;
|
||||
default:
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "\n", suId, suInstId, spInstId);
|
||||
break;
|
||||
|
@ -477,6 +511,9 @@ void sngisdn_process_disc_ind (sngisdn_event_data_t *sngisdn_event)
|
|||
/* This is a race condition. We just sent a DISCONNECT, on this channel */
|
||||
/* Do nothing */
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_RESET:
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n");
|
||||
break;
|
||||
default:
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Received DISCONNECT in an invalid state (%s)\n",
|
||||
ftdm_channel_state2str(ftdmchan->state));
|
||||
|
@ -531,7 +568,7 @@ void sngisdn_process_rel_ind (sngisdn_event_data_t *sngisdn_event)
|
|||
case FTDM_CHANNEL_STATE_DIALING:
|
||||
/* Remote side rejected our SETUP message on outbound call */
|
||||
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP)) {
|
||||
sngisdn_set_avail_rate(ftdmchan->span, SNGISDN_AVAIL_DOWN);
|
||||
sngisdn_set_span_avail_rate(ftdmchan->span, SNGISDN_AVAIL_DOWN);
|
||||
}
|
||||
/* fall-through */
|
||||
case FTDM_CHANNEL_STATE_PROCEED:
|
||||
|
@ -581,6 +618,9 @@ void sngisdn_process_rel_ind (sngisdn_event_data_t *sngisdn_event)
|
|||
/* set abort flag so that we do not transmit another release complete on this channel once FS core is done */
|
||||
}
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_RESET:
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n");
|
||||
break;
|
||||
default:
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Received RELEASE in an invalid state (%s)\n",
|
||||
ftdm_channel_state2str(ftdmchan->state));
|
||||
|
@ -1050,18 +1090,91 @@ void sngisdn_process_srv_cfm (sngisdn_event_data_t *sngisdn_event)
|
|||
return;
|
||||
}
|
||||
|
||||
static void sngisdn_process_restart_confirm(ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
switch (ftdmchan->state) {
|
||||
case FTDM_CHANNEL_STATE_RESET:
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_DOWN:
|
||||
/* Do nothing */
|
||||
break;
|
||||
default:
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Received RESTART CFM in an invalid state (%s)\n",
|
||||
ftdm_channel_state2str(ftdmchan->state));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void sngisdn_process_rst_cfm (sngisdn_event_data_t *sngisdn_event)
|
||||
{
|
||||
int16_t suId = sngisdn_event->suId;
|
||||
int16_t dChan = sngisdn_event->dChan;
|
||||
uint8_t ces = sngisdn_event->ces;
|
||||
uint8_t evntType = sngisdn_event->evntType;
|
||||
|
||||
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
|
||||
|
||||
/* Function does not require any info from ssHlEvnt struct for now */
|
||||
/*Rst *rstEvnt = &sngisdn_event->event.rstEvnt;*/
|
||||
uint8_t chan_no = 0;
|
||||
Rst *rstEvnt = &sngisdn_event->event.rstEvnt;
|
||||
|
||||
sngisdn_span_data_t *signal_data = g_sngisdn_data.dchans[dChan].spans[1];
|
||||
if (!signal_data) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Received RESTART on unconfigured span (suId:%d)\n", suId);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!rstEvnt->rstInd.eh.pres || !rstEvnt->rstInd.rstClass.pres) {
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Receved RESTART, but Restart Indicator IE not present\n");
|
||||
return;
|
||||
}
|
||||
|
||||
switch(rstEvnt->rstInd.rstClass.val) {
|
||||
case IN_CL_INDCHAN: /* Indicated b-channel */
|
||||
if (rstEvnt->chanId.eh.pres) {
|
||||
if (rstEvnt->chanId.intType.val == IN_IT_BASIC) {
|
||||
if (rstEvnt->chanId.infoChanSel.pres == PRSNT_NODEF) {
|
||||
chan_no = rstEvnt->chanId.infoChanSel.val;
|
||||
}
|
||||
} else if (rstEvnt->chanId.intType.val == IN_IT_OTHER) {
|
||||
if (rstEvnt->chanId.chanNmbSlotMap.pres == PRSNT_NODEF) {
|
||||
chan_no = rstEvnt->chanId.chanNmbSlotMap.val[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!chan_no) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Failed to determine channel from RESTART\n");
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case IN_CL_SNGINT: /* Single interface */
|
||||
case IN_CL_ALLINT: /* All interfaces */
|
||||
/* In case restart class indicates all interfaces, we will duplicate
|
||||
this event on each span associated to this d-channel in sngisdn_rcv_rst_cfm,
|
||||
so treat it as a single interface anyway */
|
||||
break;
|
||||
default:
|
||||
ftdm_log(FTDM_LOG_CRIT, "Invalid restart indicator class:%d\n", rstEvnt->rstInd.rstClass.val);
|
||||
return;
|
||||
}
|
||||
|
||||
if (chan_no) { /* For a single channel */
|
||||
if (chan_no > ftdm_span_get_chan_count(signal_data->ftdm_span)) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Received RESTART on invalid channel:%d\n", chan_no);
|
||||
} else {
|
||||
ftdm_channel_t *ftdmchan = ftdm_span_get_channel(signal_data->ftdm_span, chan_no);
|
||||
sngisdn_process_restart_confirm(ftdmchan);
|
||||
}
|
||||
} else { /* for all channels */
|
||||
ftdm_iterator_t *chaniter = NULL;
|
||||
ftdm_iterator_t *curr = NULL;
|
||||
|
||||
chaniter = ftdm_span_get_chan_iterator(signal_data->ftdm_span, NULL);
|
||||
for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
|
||||
sngisdn_process_restart_confirm((ftdm_channel_t*)ftdm_iterator_current(curr));
|
||||
}
|
||||
ftdm_iterator_free(chaniter);
|
||||
}
|
||||
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Processing RESTART CFM (suId:%u dChan:%d ces:%d type:%d)\n", suId, dChan, ces, evntType);
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
|
@ -1090,7 +1203,7 @@ void sngisdn_process_rst_ind (sngisdn_event_data_t *sngisdn_event)
|
|||
return;
|
||||
}
|
||||
|
||||
ftdm_status_t sngisdn_cause_val_requires_disconnect(ftdm_channel_t *ftdmchan, CauseDgn *causeDgn)
|
||||
static ftdm_status_t sngisdn_cause_val_requires_disconnect(ftdm_channel_t *ftdmchan, CauseDgn *causeDgn)
|
||||
{
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
|
||||
|
||||
|
|
|
@ -51,72 +51,6 @@ void sngisdn_snd_setup(ftdm_channel_t *ftdmchan)
|
|||
ftdm_mutex_unlock(g_sngisdn_data.ccs[signal_data->cc_id].mutex);
|
||||
|
||||
memset(&conEvnt, 0, sizeof(conEvnt));
|
||||
|
||||
conEvnt.bearCap[0].eh.pres = PRSNT_NODEF;
|
||||
conEvnt.bearCap[0].infoTranCap.pres = PRSNT_NODEF;
|
||||
conEvnt.bearCap[0].infoTranCap.val = sngisdn_get_infoTranCap_from_user(ftdmchan->caller_data.bearer_capability);
|
||||
|
||||
conEvnt.bearCap[0].codeStand0.pres = PRSNT_NODEF;
|
||||
conEvnt.bearCap[0].codeStand0.val = IN_CSTD_CCITT;
|
||||
conEvnt.bearCap[0].infoTranRate0.pres = PRSNT_NODEF;
|
||||
conEvnt.bearCap[0].infoTranRate0.val = IN_ITR_64KBIT;
|
||||
conEvnt.bearCap[0].tranMode.pres = PRSNT_NODEF;
|
||||
conEvnt.bearCap[0].tranMode.val = IN_TM_CIRCUIT;
|
||||
|
||||
conEvnt.chanId.eh.pres = PRSNT_NODEF;
|
||||
conEvnt.chanId.prefExc.pres = PRSNT_NODEF;
|
||||
conEvnt.chanId.prefExc.val = IN_PE_EXCLSVE;
|
||||
conEvnt.chanId.dChanInd.pres = PRSNT_NODEF;
|
||||
conEvnt.chanId.dChanInd.val = IN_DSI_NOTDCHAN;
|
||||
conEvnt.chanId.intIdentPres.pres = PRSNT_NODEF;
|
||||
conEvnt.chanId.intIdentPres.val = IN_IIP_IMPLICIT;
|
||||
conEvnt.chanId.intIdent.pres = NOTPRSNT;
|
||||
|
||||
if (ftdmchan->span->trunk_type == FTDM_TRUNK_BRI ||
|
||||
ftdmchan->span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
|
||||
/* Trillium stack rejests lyr1Ident on BRI, but Netbricks always sends it.
|
||||
Check with Trillium if this ever causes calls to fail in the field */
|
||||
|
||||
/* BRI only params */
|
||||
conEvnt.chanId.intType.pres = PRSNT_NODEF;
|
||||
conEvnt.chanId.intType.val = IN_IT_BASIC;
|
||||
conEvnt.chanId.infoChanSel.pres = PRSNT_NODEF;
|
||||
conEvnt.chanId.infoChanSel.val = ftdmchan->physical_chan_id;
|
||||
} else {
|
||||
/* PRI only params */
|
||||
conEvnt.bearCap[0].usrInfoLyr1Prot.pres = PRSNT_NODEF;
|
||||
conEvnt.bearCap[0].usrInfoLyr1Prot.val = sngisdn_get_usrInfoLyr1Prot_from_user(ftdmchan->caller_data.bearer_layer1);
|
||||
|
||||
if (signal_data->switchtype == SNGISDN_SWITCH_EUROISDN &&
|
||||
conEvnt.bearCap[0].usrInfoLyr1Prot.val == IN_UIL1_G711ULAW) {
|
||||
|
||||
/* We are bridging a call from T1 */
|
||||
conEvnt.bearCap[0].usrInfoLyr1Prot.val = IN_UIL1_G711ALAW;
|
||||
|
||||
} else if (conEvnt.bearCap[0].usrInfoLyr1Prot.val == IN_UIL1_G711ALAW) {
|
||||
|
||||
/* We are bridging a call from E1 */
|
||||
conEvnt.bearCap[0].usrInfoLyr1Prot.val = IN_UIL1_G711ULAW;
|
||||
}
|
||||
|
||||
conEvnt.bearCap[0].lyr1Ident.pres = PRSNT_NODEF;
|
||||
conEvnt.bearCap[0].lyr1Ident.val = IN_L1_IDENT;
|
||||
|
||||
conEvnt.chanId.intType.pres = PRSNT_NODEF;
|
||||
conEvnt.chanId.intType.val = IN_IT_OTHER;
|
||||
conEvnt.chanId.infoChanSel.pres = PRSNT_NODEF;
|
||||
conEvnt.chanId.infoChanSel.val = IN_ICS_B1CHAN;
|
||||
conEvnt.chanId.chanMapType.pres = PRSNT_NODEF;
|
||||
conEvnt.chanId.chanMapType.val = IN_CMT_BCHAN;
|
||||
conEvnt.chanId.nmbMap.pres = PRSNT_NODEF;
|
||||
conEvnt.chanId.nmbMap.val = IN_NM_CHNNMB;
|
||||
conEvnt.chanId.codeStand1.pres = PRSNT_NODEF;
|
||||
conEvnt.chanId.codeStand1.val = IN_CSTD_CCITT;
|
||||
conEvnt.chanId.chanNmbSlotMap.pres = PRSNT_NODEF;
|
||||
conEvnt.chanId.chanNmbSlotMap.len = 1;
|
||||
conEvnt.chanId.chanNmbSlotMap.val[0] = ftdmchan->physical_chan_id;
|
||||
}
|
||||
|
||||
if (signal_data->switchtype == SNGISDN_SWITCH_EUROISDN) {
|
||||
conEvnt.sndCmplt.eh.pres = PRSNT_NODEF;
|
||||
}
|
||||
|
@ -126,6 +60,8 @@ void sngisdn_snd_setup(ftdm_channel_t *ftdmchan)
|
|||
}
|
||||
ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Outgoing call: Called No:[%s] Calling No:[%s]\n", ftdmchan->caller_data.dnis.digits, ftdmchan->caller_data.cid_num.digits);
|
||||
|
||||
set_chan_id_ie(ftdmchan, &conEvnt.chanId);
|
||||
set_bear_cap_ie(ftdmchan, &conEvnt.bearCap[0]);
|
||||
set_called_num(ftdmchan, &conEvnt.cdPtyNmb);
|
||||
set_calling_num(ftdmchan, &conEvnt.cgPtyNmb);
|
||||
set_calling_num2(ftdmchan, &conEvnt.cgPtyNmb2);
|
||||
|
@ -161,38 +97,7 @@ void sngisdn_snd_setup_ack(ftdm_channel_t *ftdmchan)
|
|||
|
||||
memset(&cnStEvnt, 0, sizeof(cnStEvnt));
|
||||
|
||||
cnStEvnt.chanId.eh.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.prefExc.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.prefExc.val = IN_PE_EXCLSVE;
|
||||
cnStEvnt.chanId.dChanInd.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.dChanInd.val = IN_DSI_NOTDCHAN;
|
||||
cnStEvnt.chanId.intIdentPres.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.intIdentPres.val = IN_IIP_IMPLICIT;
|
||||
|
||||
|
||||
if (ftdmchan->span->trunk_type == FTDM_TRUNK_BRI ||
|
||||
ftdmchan->span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
|
||||
|
||||
/* BRI only params */
|
||||
cnStEvnt.chanId.intType.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.intType.val = IN_IT_BASIC;
|
||||
cnStEvnt.chanId.infoChanSel.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.infoChanSel.val = ftdmchan->physical_chan_id;
|
||||
} else {
|
||||
cnStEvnt.chanId.intType.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.intType.val = IN_IT_OTHER;
|
||||
cnStEvnt.chanId.infoChanSel.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.infoChanSel.val = IN_ICS_B1CHAN;
|
||||
cnStEvnt.chanId.chanMapType.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.chanMapType.val = IN_CMT_BCHAN;
|
||||
cnStEvnt.chanId.nmbMap.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.nmbMap.val = IN_NM_CHNNMB;
|
||||
cnStEvnt.chanId.codeStand1.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.codeStand1.val = IN_CSTD_CCITT;
|
||||
cnStEvnt.chanId.chanNmbSlotMap.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.chanNmbSlotMap.len = 1;
|
||||
cnStEvnt.chanId.chanNmbSlotMap.val[0] = ftdmchan->physical_chan_id;
|
||||
}
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending SETUP ACK (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces);
|
||||
|
||||
|
@ -221,38 +126,7 @@ void sngisdn_snd_con_complete(ftdm_channel_t *ftdmchan)
|
|||
|
||||
memset(&cnStEvnt, 0, sizeof(cnStEvnt));
|
||||
|
||||
cnStEvnt.chanId.eh.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.prefExc.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.prefExc.val = IN_PE_EXCLSVE;
|
||||
cnStEvnt.chanId.dChanInd.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.dChanInd.val = IN_DSI_NOTDCHAN;
|
||||
cnStEvnt.chanId.intIdentPres.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.intIdentPres.val = IN_IIP_IMPLICIT;
|
||||
|
||||
if (ftdmchan->span->trunk_type == FTDM_TRUNK_BRI ||
|
||||
ftdmchan->span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
|
||||
|
||||
/* BRI only params */
|
||||
cnStEvnt.chanId.intType.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.intType.val = IN_IT_BASIC;
|
||||
cnStEvnt.chanId.infoChanSel.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.infoChanSel.val = ftdmchan->physical_chan_id;
|
||||
} else {
|
||||
cnStEvnt.chanId.intType.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.intType.val = IN_IT_OTHER;
|
||||
cnStEvnt.chanId.infoChanSel.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.infoChanSel.val = IN_ICS_B1CHAN;
|
||||
cnStEvnt.chanId.chanMapType.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.chanMapType.val = IN_CMT_BCHAN;
|
||||
cnStEvnt.chanId.nmbMap.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.nmbMap.val = IN_NM_CHNNMB;
|
||||
cnStEvnt.chanId.codeStand1.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.codeStand1.val = IN_CSTD_CCITT;
|
||||
cnStEvnt.chanId.chanNmbSlotMap.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.chanNmbSlotMap.len = 1;
|
||||
cnStEvnt.chanId.chanNmbSlotMap.val[0] = ftdmchan->physical_chan_id;
|
||||
}
|
||||
|
||||
set_chan_id_ie(ftdmchan, &cnStEvnt.chanId);
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending CONNECT COMPL (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces);
|
||||
|
||||
|
@ -277,41 +151,11 @@ void sngisdn_snd_proceed(ftdm_channel_t *ftdmchan, ftdm_sngisdn_progind_t prog_i
|
|||
}
|
||||
|
||||
memset(&cnStEvnt, 0, sizeof(cnStEvnt));
|
||||
|
||||
cnStEvnt.chanId.eh.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.prefExc.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.prefExc.val = IN_PE_EXCLSVE;
|
||||
cnStEvnt.chanId.dChanInd.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.dChanInd.val = IN_DSI_NOTDCHAN;
|
||||
cnStEvnt.chanId.intIdentPres.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.intIdentPres.val = IN_IIP_IMPLICIT;
|
||||
|
||||
if (ftdmchan->span->trunk_type == FTDM_TRUNK_BRI ||
|
||||
ftdmchan->span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
|
||||
|
||||
/* BRI only params */
|
||||
cnStEvnt.chanId.intType.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.intType.val = IN_IT_BASIC;
|
||||
cnStEvnt.chanId.infoChanSel.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.infoChanSel.val = ftdmchan->physical_chan_id;
|
||||
} else {
|
||||
cnStEvnt.chanId.intType.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.intType.val = IN_IT_OTHER;
|
||||
cnStEvnt.chanId.infoChanSel.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.infoChanSel.val = IN_ICS_B1CHAN;
|
||||
cnStEvnt.chanId.chanMapType.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.chanMapType.val = IN_CMT_BCHAN;
|
||||
cnStEvnt.chanId.nmbMap.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.nmbMap.val = IN_NM_CHNNMB;
|
||||
cnStEvnt.chanId.codeStand1.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.codeStand1.val = IN_CSTD_CCITT;
|
||||
cnStEvnt.chanId.chanNmbSlotMap.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.chanNmbSlotMap.len = 1;
|
||||
cnStEvnt.chanId.chanNmbSlotMap.val[0] = ftdmchan->physical_chan_id;
|
||||
}
|
||||
|
||||
set_chan_id_ie(ftdmchan, &cnStEvnt.chanId);
|
||||
set_prog_ind_ie(ftdmchan, &cnStEvnt.progInd, prog_ind);
|
||||
set_facility_ie(ftdmchan, &cnStEvnt.facilityStr);
|
||||
|
||||
ftdm_call_clear_data(&ftdmchan->caller_data);
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending PROCEED (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces);
|
||||
|
@ -397,39 +241,8 @@ void sngisdn_snd_connect(ftdm_channel_t *ftdmchan)
|
|||
}
|
||||
|
||||
memset(&cnStEvnt, 0, sizeof(cnStEvnt));
|
||||
|
||||
cnStEvnt.chanId.eh.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.prefExc.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.prefExc.val = IN_PE_EXCLSVE;
|
||||
cnStEvnt.chanId.dChanInd.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.dChanInd.val = IN_DSI_NOTDCHAN;
|
||||
cnStEvnt.chanId.intIdentPres.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.intIdentPres.val = IN_IIP_IMPLICIT;
|
||||
|
||||
if (ftdmchan->span->trunk_type == FTDM_TRUNK_BRI ||
|
||||
ftdmchan->span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
|
||||
|
||||
/* BRI only params */
|
||||
cnStEvnt.chanId.intType.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.intType.val = IN_IT_BASIC;
|
||||
cnStEvnt.chanId.infoChanSel.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.infoChanSel.val = ftdmchan->physical_chan_id;
|
||||
} else {
|
||||
cnStEvnt.chanId.intType.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.intType.val = IN_IT_OTHER;
|
||||
cnStEvnt.chanId.infoChanSel.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.infoChanSel.val = IN_ICS_B1CHAN;
|
||||
cnStEvnt.chanId.chanMapType.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.chanMapType.val = IN_CMT_BCHAN;
|
||||
cnStEvnt.chanId.nmbMap.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.nmbMap.val = IN_NM_CHNNMB;
|
||||
cnStEvnt.chanId.codeStand1.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.codeStand1.val = IN_CSTD_CCITT;
|
||||
cnStEvnt.chanId.chanNmbSlotMap.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.chanNmbSlotMap.len = 1;
|
||||
cnStEvnt.chanId.chanNmbSlotMap.val[0] = ftdmchan->physical_chan_id;
|
||||
}
|
||||
|
||||
set_chan_id_ie(ftdmchan, &cnStEvnt.chanId);
|
||||
set_prog_ind_ie(ftdmchan, &cnStEvnt.progInd, prog_ind);
|
||||
set_facility_ie(ftdmchan, &cnStEvnt.facilityStr);
|
||||
ftdm_call_clear_data(&ftdmchan->caller_data);
|
||||
|
@ -563,6 +376,7 @@ void sngisdn_snd_disconnect(ftdm_channel_t *ftdmchan)
|
|||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void sngisdn_snd_release(ftdm_channel_t *ftdmchan, uint8_t glare)
|
||||
{
|
||||
RelEvnt relEvnt;
|
||||
|
@ -618,6 +432,24 @@ void sngisdn_snd_release(ftdm_channel_t *ftdmchan, uint8_t glare)
|
|||
return;
|
||||
}
|
||||
|
||||
void sngisdn_snd_restart(ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
Rst rstEvnt;
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
|
||||
|
||||
memset(&rstEvnt, 0, sizeof(rstEvnt));
|
||||
|
||||
set_chan_id_ie(ftdmchan, &rstEvnt.chanId);
|
||||
set_restart_ind_ie(ftdmchan, &rstEvnt.rstInd);
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending RESTART (suId:%d dchan:%d ces:%d)\n", signal_data->cc_id, signal_data->dchan_id, CES_MNGMNT);
|
||||
|
||||
if (sng_isdn_restart_request(signal_data->cc_id, &rstEvnt, signal_data->dchan_id, CES_MNGMNT, IN_SND_RST)) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused RESTART request\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* We received an incoming frame on the d-channel, send data to the stack */
|
||||
void sngisdn_snd_data(ftdm_channel_t *dchan, uint8_t *data, ftdm_size_t len)
|
||||
|
|
|
@ -34,9 +34,6 @@
|
|||
|
||||
#include "ftmod_sangoma_isdn.h"
|
||||
|
||||
#define MAX_DECODE_STR_LEN 2000
|
||||
|
||||
|
||||
void sngisdn_rcv_con_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, ConEvnt *conEvnt, int16_t dChan, uint8_t ces)
|
||||
{
|
||||
uint8_t bchan_no = 0;
|
||||
|
@ -630,8 +627,9 @@ void sngisdn_rcv_rst_cfm (int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces
|
|||
|
||||
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
|
||||
|
||||
|
||||
ftdm_log(FTDM_LOG_INFO, "Received RESTART CFM (dChan:%d ces:%u type:%u)\n", dChan, ces, evntType);
|
||||
|
||||
|
||||
/* Enqueue the event to each span within the dChan */
|
||||
for(i=1; i<=g_sngisdn_data.dchans[dChan].num_spans; i++) {
|
||||
signal_data = g_sngisdn_data.dchans[dChan].spans[i];
|
||||
|
@ -725,14 +723,25 @@ void sngisdn_rcv_q931_ind(InMngmt *status)
|
|||
ftdmspan = signal_data->ftdm_span;
|
||||
|
||||
if (status->t.usta.alarm.event == LCM_EVENT_UP) {
|
||||
uint32_t chan_no = status->t.usta.evntParm[2];
|
||||
ftdm_log(FTDM_LOG_INFO, "[SNGISDN Q931] s%d: %s: %s(%d): %s(%d)\n",
|
||||
status->t.usta.suId,
|
||||
DECODE_LCM_CATEGORY(status->t.usta.alarm.category),
|
||||
DECODE_LCM_EVENT(status->t.usta.alarm.event), status->t.usta.alarm.event,
|
||||
DECODE_LCM_CAUSE(status->t.usta.alarm.cause), status->t.usta.alarm.cause);
|
||||
|
||||
sngisdn_set_span_sig_status(ftdmspan, FTDM_SIG_STATE_UP);
|
||||
sngisdn_set_avail_rate(ftdmspan, SNGISDN_AVAIL_UP);
|
||||
|
||||
if (chan_no) {
|
||||
ftdm_channel_t *ftdmchan = ftdm_span_get_channel(ftdmspan, chan_no);
|
||||
if (ftdmchan) {
|
||||
sngisdn_set_chan_sig_status(ftdmchan, FTDM_SIG_STATE_UP);
|
||||
sngisdn_set_chan_avail_rate(ftdmchan, SNGISDN_AVAIL_UP);
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_CRIT, "stack alarm event on invalid channel :%d\n", chan_no);
|
||||
}
|
||||
} else {
|
||||
sngisdn_set_span_sig_status(ftdmspan, FTDM_SIG_STATE_UP);
|
||||
sngisdn_set_span_avail_rate(ftdmspan, SNGISDN_AVAIL_UP);
|
||||
}
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_WARNING, "[SNGISDN Q931] s%d: %s: %s(%d): %s(%d)\n",
|
||||
status->t.usta.suId,
|
||||
|
@ -741,7 +750,7 @@ void sngisdn_rcv_q931_ind(InMngmt *status)
|
|||
DECODE_LCM_CAUSE(status->t.usta.alarm.cause), status->t.usta.alarm.cause);
|
||||
|
||||
sngisdn_set_span_sig_status(ftdmspan, FTDM_SIG_STATE_DOWN);
|
||||
sngisdn_set_avail_rate(ftdmspan, SNGISDN_AVAIL_PWR_SAVING);
|
||||
sngisdn_set_span_avail_rate(ftdmspan, SNGISDN_AVAIL_PWR_SAVING);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -765,9 +774,6 @@ void sngisdn_rcv_cc_ind(CcMngmt *status)
|
|||
return;
|
||||
}
|
||||
|
||||
#define Q931_TRC_EVENT(event) (event == TL3PKTTX)?"TX": \
|
||||
(event == TL3PKTRX)?"RX":"UNKNOWN"
|
||||
|
||||
void sngisdn_rcv_q931_trace(InMngmt *trc, Buffer *mBuf)
|
||||
{
|
||||
MsgLen mlen;
|
||||
|
@ -776,13 +782,20 @@ void sngisdn_rcv_q931_trace(InMngmt *trc, Buffer *mBuf)
|
|||
Buffer *tmp;
|
||||
Data *cptr;
|
||||
uint8_t data;
|
||||
ftdm_trace_dir_t dir;
|
||||
uint8_t tdata[1000];
|
||||
char *data_str = ftdm_calloc(1,MAX_DECODE_STR_LEN); /* TODO Find a proper size */
|
||||
|
||||
sngisdn_span_data_t *signal_data = g_sngisdn_data.spans[trc->t.trc.suId];
|
||||
|
||||
ftdm_assert(mBuf != NULLP, "Received a Q931 trace with no buffer");
|
||||
mlen = ((SsMsgInfo*)(mBuf->b_rptr))->len;
|
||||
|
||||
if (mlen != 0) {
|
||||
|
||||
if (trc->t.trc.evnt == TL3PKTTX) {
|
||||
dir = FTDM_TRACE_OUTGOING;
|
||||
} else {
|
||||
dir = FTDM_TRACE_INCOMING;
|
||||
}
|
||||
|
||||
if (mlen) {
|
||||
tmp = mBuf->b_cont;
|
||||
cptr = tmp->b_rptr;
|
||||
data = *cptr++;
|
||||
|
@ -797,41 +810,40 @@ void sngisdn_rcv_q931_trace(InMngmt *trc, Buffer *mBuf)
|
|||
}
|
||||
data = *cptr++;
|
||||
}
|
||||
|
||||
sngisdn_trace_q931(data_str, tdata, mlen);
|
||||
ftdm_log(FTDM_LOG_INFO, "[SNGISDN Q931] s%d FRAME %s:%s\n", trc->t.trc.suId, Q931_TRC_EVENT(trc->t.trc.evnt), data_str);
|
||||
if (signal_data->raw_trace_q931 == SNGISDN_OPT_TRUE) {
|
||||
sngisdn_trace_raw_q931(signal_data, dir, tdata, mlen);
|
||||
} else {
|
||||
sngisdn_trace_interpreted_q931(signal_data, dir, tdata, mlen);
|
||||
}
|
||||
}
|
||||
|
||||
ftdm_safe_free(data_str);
|
||||
/* We do not need to free mBuf in this case because stack does it */
|
||||
/* SPutMsg(mBuf); */
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
#define Q921_TRC_EVENT(event) (event == TL2FRMRX)?"RX": \
|
||||
(event == TL2FRMTX)?"TX": \
|
||||
(event == TL2TMR)?"TMR EXPIRED":"UNKNOWN"
|
||||
|
||||
void sngisdn_rcv_q921_trace(BdMngmt *trc, Buffer *mBuf)
|
||||
{
|
||||
MsgLen mlen;
|
||||
Buffer *tmp;
|
||||
MsgLen i;
|
||||
int16_t j;
|
||||
Buffer *tmp;
|
||||
Data *cptr;
|
||||
uint8_t data;
|
||||
uint8_t tdata[16];
|
||||
char *data_str = ftdm_calloc(1,200); /* TODO Find a proper size */
|
||||
|
||||
ftdm_trace_dir_t dir;
|
||||
uint8_t tdata[1000];
|
||||
sngisdn_span_data_t *signal_data = g_sngisdn_data.spans[trc->t.trc.lnkNmb];
|
||||
|
||||
if (trc->t.trc.evnt == TL2TMR) {
|
||||
goto end_of_trace;
|
||||
return;
|
||||
}
|
||||
|
||||
if (trc->t.trc.evnt == TL2FRMTX) {
|
||||
dir = FTDM_TRACE_OUTGOING;
|
||||
} else {
|
||||
dir = FTDM_TRACE_INCOMING;
|
||||
}
|
||||
|
||||
ftdm_assert(mBuf != NULLP, "Received a Q921 trace with no buffer");
|
||||
mlen = ((SsMsgInfo*)(mBuf->b_rptr))->len;
|
||||
|
||||
if (mlen != 0) {
|
||||
tmp = mBuf->b_cont;
|
||||
cptr = tmp->b_rptr;
|
||||
|
@ -853,12 +865,12 @@ void sngisdn_rcv_q921_trace(BdMngmt *trc, Buffer *mBuf)
|
|||
}
|
||||
|
||||
}
|
||||
sngisdn_trace_q921(data_str, tdata, mlen);
|
||||
ftdm_log(FTDM_LOG_INFO, "[SNGISDN Q921] s%d FRAME %s:%s\n", trc->t.trc.lnkNmb, Q921_TRC_EVENT(trc->t.trc.evnt), data_str);
|
||||
if (signal_data->raw_trace_q921 == SNGISDN_OPT_TRUE) {
|
||||
sngisdn_trace_raw_q921(signal_data, dir, tdata, mlen);
|
||||
} else {
|
||||
sngisdn_trace_interpreted_q921(signal_data, dir, tdata, mlen);
|
||||
}
|
||||
}
|
||||
end_of_trace:
|
||||
ftdm_safe_free(data_str);
|
||||
SPutMsg(mBuf);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -136,19 +136,25 @@ ftdm_status_t get_ftdmchan_by_spInstId(int16_t cc_id, uint32_t spInstId, sngisdn
|
|||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
ftdm_status_t sngisdn_set_avail_rate(ftdm_span_t *span, sngisdn_avail_t avail)
|
||||
ftdm_status_t sngisdn_set_chan_avail_rate(ftdm_channel_t *chan, sngisdn_avail_t avail)
|
||||
{
|
||||
if (span->trunk_type == FTDM_TRUNK_BRI ||
|
||||
span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
|
||||
if (FTDM_SPAN_IS_BRI(chan->span)) {
|
||||
ftdm_log_chan(chan, FTDM_LOG_DEBUG, "Setting availability rate to:%d\n", avail);
|
||||
chan->availability_rate = avail;
|
||||
}
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
ftdm_status_t sngisdn_set_span_avail_rate(ftdm_span_t *span, sngisdn_avail_t avail)
|
||||
{
|
||||
if (FTDM_SPAN_IS_BRI(span)) {
|
||||
ftdm_iterator_t *chaniter = NULL;
|
||||
ftdm_iterator_t *curr = NULL;
|
||||
|
||||
|
||||
chaniter = ftdm_span_get_chan_iterator(span, NULL);
|
||||
for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
|
||||
ftdm_log_chan(((ftdm_channel_t*)ftdm_iterator_current(curr)), FTDM_LOG_DEBUG, "Setting availability rate to:%d\n", avail);
|
||||
((ftdm_channel_t*)ftdm_iterator_current(curr))->availability_rate = avail;
|
||||
sngisdn_set_chan_avail_rate(((ftdm_channel_t*)ftdm_iterator_current(curr)), avail);
|
||||
}
|
||||
ftdm_iterator_free(chaniter);
|
||||
}
|
||||
|
@ -676,7 +682,6 @@ ftdm_status_t set_calling_subaddr(ftdm_channel_t *ftdmchan, CgPtySad *cgPtySad)
|
|||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
ftdm_status_t set_facility_ie(ftdm_channel_t *ftdmchan, FacilityStr *facilityStr)
|
||||
{
|
||||
ftdm_status_t status;
|
||||
|
@ -789,6 +794,93 @@ ftdm_status_t set_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd, ftdm_s
|
|||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
ftdm_status_t set_chan_id_ie(ftdm_channel_t *ftdmchan, ChanId *chanId)
|
||||
{
|
||||
if (!ftdmchan) {
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
chanId->eh.pres = PRSNT_NODEF;
|
||||
chanId->prefExc.pres = PRSNT_NODEF;
|
||||
chanId->prefExc.val = IN_PE_EXCLSVE;
|
||||
chanId->dChanInd.pres = PRSNT_NODEF;
|
||||
chanId->dChanInd.val = IN_DSI_NOTDCHAN;
|
||||
chanId->intIdentPres.pres = PRSNT_NODEF;
|
||||
chanId->intIdentPres.val = IN_IIP_IMPLICIT;
|
||||
|
||||
if (ftdmchan->span->trunk_type == FTDM_TRUNK_BRI ||
|
||||
ftdmchan->span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
|
||||
|
||||
/* BRI only params */
|
||||
chanId->intType.pres = PRSNT_NODEF;
|
||||
chanId->intType.val = IN_IT_BASIC;
|
||||
chanId->infoChanSel.pres = PRSNT_NODEF;
|
||||
chanId->infoChanSel.val = ftdmchan->physical_chan_id;
|
||||
} else {
|
||||
chanId->intType.pres = PRSNT_NODEF;
|
||||
chanId->intType.val = IN_IT_OTHER;
|
||||
chanId->infoChanSel.pres = PRSNT_NODEF;
|
||||
chanId->infoChanSel.val = IN_ICS_B1CHAN;
|
||||
chanId->chanMapType.pres = PRSNT_NODEF;
|
||||
chanId->chanMapType.val = IN_CMT_BCHAN;
|
||||
chanId->nmbMap.pres = PRSNT_NODEF;
|
||||
chanId->nmbMap.val = IN_NM_CHNNMB;
|
||||
chanId->codeStand1.pres = PRSNT_NODEF;
|
||||
chanId->codeStand1.val = IN_CSTD_CCITT;
|
||||
chanId->chanNmbSlotMap.pres = PRSNT_NODEF;
|
||||
chanId->chanNmbSlotMap.len = 1;
|
||||
chanId->chanNmbSlotMap.val[0] = ftdmchan->physical_chan_id;
|
||||
}
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
ftdm_status_t set_bear_cap_ie(ftdm_channel_t *ftdmchan, BearCap *bearCap)
|
||||
{
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
|
||||
|
||||
bearCap->eh.pres = PRSNT_NODEF;
|
||||
bearCap->infoTranCap.pres = PRSNT_NODEF;
|
||||
bearCap->infoTranCap.val = sngisdn_get_infoTranCap_from_user(ftdmchan->caller_data.bearer_capability);
|
||||
|
||||
bearCap->codeStand0.pres = PRSNT_NODEF;
|
||||
bearCap->codeStand0.val = IN_CSTD_CCITT;
|
||||
bearCap->infoTranRate0.pres = PRSNT_NODEF;
|
||||
bearCap->infoTranRate0.val = IN_ITR_64KBIT;
|
||||
bearCap->tranMode.pres = PRSNT_NODEF;
|
||||
bearCap->tranMode.val = IN_TM_CIRCUIT;
|
||||
|
||||
if (!FTDM_SPAN_IS_BRI(ftdmchan->span)) {
|
||||
/* Trillium stack rejests lyr1Ident on BRI, but Netbricks always sends it.
|
||||
Check with Trillium if this ever causes calls to fail in the field */
|
||||
|
||||
/* PRI only params */
|
||||
bearCap->usrInfoLyr1Prot.pres = PRSNT_NODEF;
|
||||
bearCap->usrInfoLyr1Prot.val = sngisdn_get_usrInfoLyr1Prot_from_user(ftdmchan->caller_data.bearer_layer1);
|
||||
|
||||
if (signal_data->switchtype == SNGISDN_SWITCH_EUROISDN &&
|
||||
bearCap->usrInfoLyr1Prot.val == IN_UIL1_G711ULAW) {
|
||||
|
||||
/* We are bridging a call from T1 */
|
||||
bearCap->usrInfoLyr1Prot.val = IN_UIL1_G711ALAW;
|
||||
|
||||
} else if (bearCap->usrInfoLyr1Prot.val == IN_UIL1_G711ALAW) {
|
||||
|
||||
/* We are bridging a call from E1 */
|
||||
bearCap->usrInfoLyr1Prot.val = IN_UIL1_G711ULAW;
|
||||
}
|
||||
|
||||
bearCap->lyr1Ident.pres = PRSNT_NODEF;
|
||||
bearCap->lyr1Ident.val = IN_L1_IDENT;
|
||||
}
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
ftdm_status_t set_restart_ind_ie(ftdm_channel_t *ftdmchan, RstInd *rstInd)
|
||||
{
|
||||
rstInd->eh.pres = PRSNT_NODEF;
|
||||
rstInd->rstClass.pres = PRSNT_NODEF;
|
||||
rstInd->rstClass.val = IN_CL_INDCHAN;
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
void sngisdn_t3_timeout(void* p_sngisdn_info)
|
||||
{
|
||||
|
|
|
@ -36,14 +36,15 @@
|
|||
#include "ftmod_sangoma_isdn_trace.h"
|
||||
|
||||
#define OCTET(x) (ieData[x-1] & 0xFF)
|
||||
#define MAX_DECODE_STR_LEN 2000
|
||||
|
||||
void print_hex_dump(char* str, uint32_t *str_len, uint8_t* data, uint32_t index_start, uint32_t index_end);
|
||||
void sngisdn_trace_q921(char* str, uint8_t* data, uint32_t data_len);
|
||||
void sngisdn_trace_q931(char* str, uint8_t* data, uint32_t data_len);
|
||||
uint32_t sngisdn_decode_ie(char *str, uint32_t *str_len, uint8_t current_codeset, uint8_t *data, uint16_t index_start);
|
||||
|
||||
uint8_t get_bits(uint8_t octet, uint8_t bitLo, uint8_t bitHi);
|
||||
char* get_code_2_str(int code, struct code2str *pCodeTable);
|
||||
void sngisdn_decode_q921(char* str, uint8_t* data, uint32_t data_len);
|
||||
void sngisdn_decode_q931(char* str, uint8_t* data, uint32_t data_len);
|
||||
|
||||
char* get_code_2_str(int code, struct code2str *pCodeTable)
|
||||
{
|
||||
|
@ -97,7 +98,42 @@ uint8_t get_bits(uint8_t octet, uint8_t bitLo, uint8_t bitHi)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void sngisdn_trace_q921(char* str, uint8_t* data, uint32_t data_len)
|
||||
void sngisdn_trace_interpreted_q921(sngisdn_span_data_t *signal_data, ftdm_trace_dir_t dir, uint8_t *data, uint32_t data_len)
|
||||
{
|
||||
char *data_str = ftdm_calloc(1,200); /* TODO Find a proper size */
|
||||
sngisdn_decode_q921(data_str, data, data_len);
|
||||
ftdm_log(FTDM_LOG_INFO, "[SNGISDN Q921] s%d FRAME %s:%s\n", signal_data->ftdm_span->name, ftdm_trace_dir2str(dir), data_str);
|
||||
ftdm_safe_free(data_str);
|
||||
}
|
||||
|
||||
void sngisdn_trace_raw_q921(sngisdn_span_data_t *signal_data, ftdm_trace_dir_t dir, uint8_t *data, uint32_t data_len)
|
||||
{
|
||||
uint8_t *raw_data;
|
||||
ftdm_sigmsg_t sigev;
|
||||
|
||||
memset(&sigev, 0, sizeof(sigev));
|
||||
|
||||
sigev.span_id = signal_data->ftdm_span->span_id;
|
||||
sigev.chan_id = signal_data->dchan->chan_id;
|
||||
sigev.channel = signal_data->dchan;
|
||||
sigev.event_id = FTDM_SIGEVENT_TRACE_RAW;
|
||||
|
||||
sigev.ev_data.logevent.dir = dir;
|
||||
sigev.ev_data.logevent.level = 2;
|
||||
|
||||
/* TODO: Map trace to call ID here */
|
||||
sigev.call_id = 0;
|
||||
|
||||
raw_data = ftdm_malloc(data_len);
|
||||
ftdm_assert(raw_data, "Failed to malloc");
|
||||
|
||||
memcpy(raw_data, data, data_len);
|
||||
sigev.raw_data = raw_data;
|
||||
sigev.raw_data_len = data_len;
|
||||
ftdm_span_send_signal(signal_data->ftdm_span, &sigev);
|
||||
}
|
||||
|
||||
void sngisdn_decode_q921(char* str, uint8_t* data, uint32_t data_len)
|
||||
{
|
||||
int str_len;
|
||||
uint32_t i;
|
||||
|
@ -169,7 +205,42 @@ void sngisdn_trace_q921(char* str, uint8_t* data, uint32_t data_len)
|
|||
return;
|
||||
}
|
||||
|
||||
void sngisdn_trace_q931(char* str, uint8_t* data, uint32_t data_len)
|
||||
|
||||
void sngisdn_trace_interpreted_q931(sngisdn_span_data_t *signal_data, ftdm_trace_dir_t dir, uint8_t *data, uint32_t data_len)
|
||||
{
|
||||
char *data_str = ftdm_calloc(1,MAX_DECODE_STR_LEN); /* TODO Find a proper size */
|
||||
sngisdn_decode_q931(data_str, data, data_len);
|
||||
ftdm_log(FTDM_LOG_INFO, "[SNGISDN Q931] %s FRAME %s:%s\n", signal_data->ftdm_span->name, ftdm_trace_dir2str(dir), data_str);
|
||||
ftdm_safe_free(data_str);
|
||||
}
|
||||
|
||||
void sngisdn_trace_raw_q931(sngisdn_span_data_t *signal_data, ftdm_trace_dir_t dir, uint8_t *data, uint32_t data_len)
|
||||
{
|
||||
uint8_t *raw_data;
|
||||
ftdm_sigmsg_t sigev;
|
||||
|
||||
memset(&sigev, 0, sizeof(sigev));
|
||||
|
||||
sigev.span_id = signal_data->ftdm_span->span_id;
|
||||
sigev.chan_id = signal_data->dchan->chan_id;
|
||||
sigev.channel = signal_data->dchan;
|
||||
sigev.event_id = FTDM_SIGEVENT_TRACE_RAW;
|
||||
|
||||
sigev.ev_data.logevent.dir = dir;
|
||||
sigev.ev_data.logevent.level = 3;
|
||||
|
||||
/* TODO: Map trace to call ID here */
|
||||
|
||||
raw_data = ftdm_malloc(data_len);
|
||||
ftdm_assert(raw_data, "Failed to malloc");
|
||||
|
||||
memcpy(raw_data, data, data_len);
|
||||
sigev.raw_data = raw_data;
|
||||
sigev.raw_data_len = data_len;
|
||||
ftdm_span_send_signal(signal_data->ftdm_span, &sigev);
|
||||
}
|
||||
|
||||
void sngisdn_decode_q931(char* str, uint8_t* data, uint32_t data_len)
|
||||
{
|
||||
uint32_t str_len;
|
||||
uint8_t prot_disc, callRefFlag;
|
||||
|
|
|
@ -1589,7 +1589,7 @@ static ftdm_status_t handle_tx_cgb(ftdm_stream_handle_t *stream, int span, int c
|
|||
sigev.span_id = ftdmchan->span_id;
|
||||
sigev.channel = ftdmchan;
|
||||
sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
|
||||
sigev.sigstatus = FTDM_SIG_STATE_DOWN;
|
||||
sigev.ev_data.sigstatus.status = FTDM_SIG_STATE_DOWN;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
|
||||
/* if this is the first channel in the range */
|
||||
|
@ -1689,7 +1689,7 @@ static ftdm_status_t handle_tx_cgu(ftdm_stream_handle_t *stream, int span, int c
|
|||
sigev.span_id = ftdmchan->span_id;
|
||||
sigev.channel = ftdmchan;
|
||||
sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
|
||||
sigev.sigstatus = FTDM_SIG_STATE_UP;
|
||||
sigev.ev_data.sigstatus.status = FTDM_SIG_STATE_UP;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
|
||||
/* if this is the first channel in the range */
|
||||
|
|
|
@ -2004,7 +2004,7 @@ ftdm_status_t handle_cgb_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ
|
|||
|
||||
/* bring the sig status down */
|
||||
sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
|
||||
sigev.sigstatus = FTDM_SIG_STATE_DOWN;
|
||||
sigev.ev_data.sigstatus.status = FTDM_SIG_STATE_DOWN;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
|
||||
/* unlock the channel again before we exit */
|
||||
|
@ -2135,7 +2135,7 @@ ftdm_status_t handle_cgu_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ
|
|||
|
||||
/* bring the sig status down */
|
||||
sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
|
||||
sigev.sigstatus = FTDM_SIG_STATE_UP;
|
||||
sigev.ev_data.sigstatus.status = FTDM_SIG_STATE_UP;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
|
||||
/* unlock the channel again before we exit */
|
||||
|
|
|
@ -841,7 +841,7 @@ void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
|||
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;
|
||||
sigev.ev_data.sigstatus.status = FTDM_SIG_STATE_UP;
|
||||
ftdm_span_send_signal (ftdmchan->span, &sigev);
|
||||
} /* if (!ftdm_test_flag (ftdmchan, FTDM_CHANNEL_SIG_UP)) */
|
||||
} /* if !blocked */
|
||||
|
@ -949,7 +949,7 @@ void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
|||
/* if the sig_status is up...bring it down */
|
||||
if (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_SIG_UP)) {
|
||||
sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
|
||||
sigev.sigstatus = FTDM_SIG_STATE_DOWN;
|
||||
sigev.ev_data.sigstatus.status = FTDM_SIG_STATE_DOWN;
|
||||
ftdm_span_send_signal (ftdmchan->span, &sigev);
|
||||
}
|
||||
|
||||
|
@ -1033,7 +1033,7 @@ void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
|||
|
||||
/* bring the sig status back up */
|
||||
sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
|
||||
sigev.sigstatus = FTDM_SIG_STATE_UP;
|
||||
sigev.ev_data.sigstatus.status = FTDM_SIG_STATE_UP;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
}
|
||||
|
||||
|
@ -1046,7 +1046,7 @@ void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
|||
|
||||
/* bring the sig status down */
|
||||
sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
|
||||
sigev.sigstatus = FTDM_SIG_STATE_DOWN;
|
||||
sigev.ev_data.sigstatus.status = FTDM_SIG_STATE_DOWN;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
|
||||
/* go back to the last state */
|
||||
|
@ -1058,7 +1058,7 @@ void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
|||
|
||||
/* bring the sig status down */
|
||||
sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
|
||||
sigev.sigstatus = FTDM_SIG_STATE_DOWN;
|
||||
sigev.ev_data.sigstatus.status = FTDM_SIG_STATE_DOWN;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
|
||||
/* send a BLA */
|
||||
|
@ -1076,7 +1076,7 @@ void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
|||
|
||||
/* bring the sig status up */
|
||||
sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
|
||||
sigev.sigstatus = FTDM_SIG_STATE_UP;
|
||||
sigev.ev_data.sigstatus.status = FTDM_SIG_STATE_UP;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
|
||||
/* send a uba */
|
||||
|
@ -1092,7 +1092,7 @@ void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
|||
|
||||
/* bring the sig status down */
|
||||
sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
|
||||
sigev.sigstatus = FTDM_SIG_STATE_DOWN;
|
||||
sigev.ev_data.sigstatus.status = FTDM_SIG_STATE_DOWN;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
|
||||
/* send a blo */
|
||||
|
@ -1110,7 +1110,7 @@ void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
|||
|
||||
/* bring the sig status up */
|
||||
sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
|
||||
sigev.sigstatus = FTDM_SIG_STATE_UP;
|
||||
sigev.ev_data.sigstatus.status = FTDM_SIG_STATE_UP;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
|
||||
/* send a ubl */
|
||||
|
@ -1149,7 +1149,7 @@ void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
|||
|
||||
/* bring the channel signaling status to down */
|
||||
sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
|
||||
sigev.sigstatus = FTDM_SIG_STATE_DOWN;
|
||||
sigev.ev_data.sigstatus.status = FTDM_SIG_STATE_DOWN;
|
||||
ftdm_span_send_signal (ftdmchan->span, &sigev);
|
||||
|
||||
/* remove any reset flags */
|
||||
|
|
|
@ -1051,16 +1051,34 @@ FIO_SPAN_POLL_EVENT_FUNCTION(wanpipe_poll_event)
|
|||
|
||||
for(i = 1; i <= span->chan_count; i++) {
|
||||
ftdm_channel_t *ftdmchan = span->channels[i];
|
||||
uint32_t chan_events = 0;
|
||||
|
||||
/* translate events from ftdm to libsnagoma. if the user don't specify which events to poll the
|
||||
* channel for, we just use SANG_WAIT_OBJ_HAS_EVENTS */
|
||||
if (poll_events) {
|
||||
if (poll_events[j] & FTDM_READ) {
|
||||
chan_events = SANG_WAIT_OBJ_HAS_INPUT;
|
||||
}
|
||||
if (poll_events[j] & FTDM_WRITE) {
|
||||
chan_events |= SANG_WAIT_OBJ_HAS_OUTPUT;
|
||||
}
|
||||
if (poll_events[j] & FTDM_EVENTS) {
|
||||
chan_events |= SANG_WAIT_OBJ_HAS_EVENTS;
|
||||
}
|
||||
} else {
|
||||
chan_events = SANG_WAIT_OBJ_HAS_EVENTS;
|
||||
}
|
||||
|
||||
#ifdef LIBSANGOMA_VERSION
|
||||
if (!ftdmchan->io_data) {
|
||||
continue; /* should never happen but happens when shutting down */
|
||||
}
|
||||
pfds[j] = ftdmchan->io_data;
|
||||
inflags[j] = poll_events ? poll_events[j] : POLLPRI;
|
||||
inflags[j] = chan_events;
|
||||
#else
|
||||
memset(&pfds[j], 0, sizeof(pfds[j]));
|
||||
pfds[j].fd = span->channels[i]->sockfd;
|
||||
pfds[j].events = poll_events ? poll_events[j] : POLLPRI;
|
||||
pfds[j].events = chan_events;
|
||||
#endif
|
||||
|
||||
/* The driver probably should be able to do this wink/flash/ringing by itself this is sort of a hack to make it work! */
|
||||
|
|
|
@ -295,6 +295,11 @@ typedef struct ftdm_caller_data {
|
|||
/* user information layer 1 protocol */
|
||||
ftdm_user_layer1_prot_t bearer_layer1;
|
||||
ftdm_variable_container_t variables; /*!<variables attached to this call */
|
||||
/* We need call_id inside caller_data for the user to be able to retrieve
|
||||
* the call_id when ftdm_channel_call_place is called. This is the only time
|
||||
* that the user can use caller_data.call_id to obtain the call_id. The user
|
||||
* should use the call_id from sigmsg otherwise */
|
||||
uint32_t call_id; /*!< Unique call ID for this call */
|
||||
} ftdm_caller_data_t;
|
||||
|
||||
/*! \brief Tone type */
|
||||
|
@ -309,7 +314,8 @@ typedef enum {
|
|||
FTDM_SIGEVENT_RELEASED, /*!< Channel is completely released and available */
|
||||
FTDM_SIGEVENT_UP, /*!< Outgoing call has been answered */
|
||||
FTDM_SIGEVENT_FLASH, /*!< Flash event (typically on-hook/off-hook for analog devices) */
|
||||
FTDM_SIGEVENT_PROCEED, /*!< Outgoing call got a response */
|
||||
FTDM_SIGEVENT_PROCEED, /*!< Outgoing call got a response */
|
||||
FTDM_SIGEVENT_RINGING, /*!< Remote side is in ringing state */
|
||||
FTDM_SIGEVENT_PROGRESS, /*!< Outgoing call is making progress */
|
||||
FTDM_SIGEVENT_PROGRESS_MEDIA, /*!< Outgoing call is making progress and there is media available */
|
||||
FTDM_SIGEVENT_ALARM_TRAP, /*!< Hardware alarm ON */
|
||||
|
@ -319,12 +325,14 @@ typedef enum {
|
|||
FTDM_SIGEVENT_RESTART, /*!< Restart has been requested. Typically you hangup your call resources here */
|
||||
FTDM_SIGEVENT_SIGSTATUS_CHANGED, /*!< Signaling protocol status changed (ie: D-chan up), see new status in raw_data ftdm_sigmsg_t member */
|
||||
FTDM_SIGEVENT_COLLISION, /*!< Outgoing call was dropped because an incoming call arrived at the same time */
|
||||
FTDM_SIGEVENT_FACILITY, /* !< In call facility event */
|
||||
FTDM_SIGEVENT_INVALID
|
||||
FTDM_SIGEVENT_FACILITY, /*!< In call facility event */
|
||||
FTDM_SIGEVENT_TRACE, /*!<Interpreted trace event */
|
||||
FTDM_SIGEVENT_TRACE_RAW, /*!<Raw trace event */
|
||||
FTDM_SIGEVENT_INVALID, /*!<Invalid */
|
||||
} ftdm_signal_event_t;
|
||||
#define SIGNAL_STRINGS "START", "STOP", "RELEASED", "UP", "FLASH", "PROCEED", "PROGRESS", \
|
||||
#define SIGNAL_STRINGS "START", "STOP", "RELEASED", "UP", "FLASH", "PROCEED", "RINGING", "PROGRESS", \
|
||||
"PROGRESS_MEDIA", "ALARM_TRAP", "ALARM_CLEAR", \
|
||||
"COLLECTED_DIGIT", "ADD_CALL", "RESTART", "SIGSTATUS_CHANGED", "COLLISION", "MSG", "INVALID"
|
||||
"COLLECTED_DIGIT", "ADD_CALL", "RESTART", "SIGSTATUS_CHANGED", "COLLISION", "FACILITY", "TRACE", "TRACE_RAW", "INVALID"
|
||||
|
||||
/*! \brief Move from string to ftdm_signal_event_t and viceversa */
|
||||
FTDM_STR2ENUM_P(ftdm_str2ftdm_signal_event, ftdm_signal_event2str, ftdm_signal_event_t)
|
||||
|
@ -375,15 +383,43 @@ typedef enum {
|
|||
/*! \brief Move from string to ftdm_signaling_status_t and viceversa */
|
||||
FTDM_STR2ENUM_P(ftdm_str2ftdm_signaling_status, ftdm_signaling_status2str, ftdm_signaling_status_t)
|
||||
|
||||
|
||||
typedef struct {
|
||||
ftdm_signaling_status_t status;
|
||||
} ftdm_event_sigstatus_t;
|
||||
|
||||
typedef enum {
|
||||
/* This is an received frame */
|
||||
FTDM_TRACE_INCOMING,
|
||||
/* This is a transmitted frame */
|
||||
FTDM_TRACE_OUTGOING,
|
||||
/* Invalid */
|
||||
FTDM_TRACE_INVALID,
|
||||
} ftdm_trace_dir_t;
|
||||
#define TRACE_DIR_STRINGS "INCOMING", "OUTGOING", "INVALID"
|
||||
|
||||
/*! \brief Move string to ftdm_trace_dir_t and viceversa */
|
||||
FTDM_STR2ENUM_P(ftdm_str2ftdm_trace_dir, ftdm_trace_dir2str, ftdm_trace_dir_t)
|
||||
|
||||
typedef struct {
|
||||
/* Direction - incoming or outgoing */
|
||||
ftdm_trace_dir_t dir;
|
||||
uint8_t level; /* 1 for phy layer, 2 for q921/mtp2, 3 for q931/mtp3 */
|
||||
} ftdm_event_trace_t;
|
||||
|
||||
/*! \brief Generic signaling message */
|
||||
struct ftdm_sigmsg {
|
||||
ftdm_signal_event_t event_id; /*!< The type of message */
|
||||
ftdm_channel_t *channel; /*!< Related channel */
|
||||
uint32_t chan_id; /*!< easy access to chan id */
|
||||
uint32_t span_id; /*!< easy access to span_id */
|
||||
ftdm_signaling_status_t sigstatus; /*!< Signaling status (valid if event_id is FTDM_SIGEVENT_SIGSTATUS_CHANGED) */
|
||||
void *raw_data; /*!< Message specific data if any */
|
||||
uint32_t raw_data_len; /*!< Data len in case is needed */
|
||||
uint32_t call_id; /*!< unique call id for this call */
|
||||
union {
|
||||
ftdm_event_sigstatus_t sigstatus; /*!< valid if event_id is FTDM_SIGEVENT_SIGSTATUS_CHANGED */
|
||||
ftdm_event_trace_t logevent; /*!< valid if event_id is FTDM_SIGEVENT_TRACE or FTDM_SIGEVENT_TRACE_RAW */
|
||||
}ev_data;
|
||||
};
|
||||
|
||||
/*! \brief Crash policy
|
||||
|
@ -660,6 +696,14 @@ typedef enum {
|
|||
/*! \brief Override the default queue handler */
|
||||
FT_DECLARE(ftdm_status_t) ftdm_global_set_queue_handler(ftdm_queue_handler_t *handler);
|
||||
|
||||
/*! \brief Return the availability rate for a channel
|
||||
* \param ftdmchan Channel to get the availability from
|
||||
*
|
||||
* \retval > 0 if availability is supported
|
||||
* \retval -1 if availability is not supported
|
||||
*/
|
||||
FT_DECLARE(int) ftdm_channel_get_availability(ftdm_channel_t *ftdmchan);
|
||||
|
||||
/*! \brief Answer call */
|
||||
#define ftdm_channel_call_answer(ftdmchan) _ftdm_channel_call_answer(__FILE__, __FUNCTION__, __LINE__, (ftdmchan))
|
||||
|
||||
|
@ -696,6 +740,14 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_hangup(const char *file, const char
|
|||
/*! \brief Hangup the call with cause recording the source code point where it was called (see ftdm_channel_call_hangup_with_cause for an easy to use macro) */
|
||||
FT_DECLARE(ftdm_status_t) _ftdm_channel_call_hangup_with_cause(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan, ftdm_call_cause_t);
|
||||
|
||||
/*! \brief Reset the channel */
|
||||
#define ftdm_channel_reset(ftdmchan) _ftdm_channel_reset(__FILE__, __FUNCTION__, __LINE__, (ftdmchan))
|
||||
|
||||
/*! \brief Reset the channel (see _ftdm_channel_reset for an easy to use macro)
|
||||
* \note if there was a call on this channel, call will be cleared without any notifications to the user
|
||||
*/
|
||||
FT_DECLARE(ftdm_status_t) _ftdm_channel_reset(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan);
|
||||
|
||||
/*! \brief Put a call on hold (if supported by the signaling stack) */
|
||||
#define ftdm_channel_call_hold(ftdmchan) _ftdm_channel_call_hold(__FILE__, __FUNCTION__, __LINE__, (ftdmchan))
|
||||
|
||||
|
@ -735,6 +787,7 @@ FT_DECLARE(ftdm_status_t) ftdm_span_set_sig_status(ftdm_span_t *span, ftdm_signa
|
|||
/*! \brief Get span signaling status (ie: whether protocol layer is up or down) */
|
||||
FT_DECLARE(ftdm_status_t) ftdm_span_get_sig_status(ftdm_span_t *span, ftdm_signaling_status_t *status);
|
||||
|
||||
|
||||
/*!
|
||||
* \brief Set user private data in the channel
|
||||
*
|
||||
|
|
|
@ -158,12 +158,16 @@ typedef __int64 int64_t;
|
|||
typedef __int32 int32_t;
|
||||
typedef __int16 int16_t;
|
||||
typedef __int8 int8_t;
|
||||
#define FTDM_O_BINARY O_BINARY
|
||||
#define FTDM_SIZE_FMT "Id"
|
||||
#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
|
||||
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64
|
||||
#else
|
||||
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL
|
||||
#endif /* _MSC_VER */
|
||||
#else /* __WINDOWS__ */
|
||||
#define FTDM_O_BINARY 0
|
||||
#define FTDM_SIZE_FMT "zd"
|
||||
#define FTDM_INVALID_SOCKET -1
|
||||
typedef int ftdm_socket_t;
|
||||
#include <stdio.h>
|
||||
|
|
|
@ -599,7 +599,6 @@ FT_DECLARE(void) ftdm_channel_rotate_tokens(ftdm_channel_t *ftdmchan);
|
|||
FT_DECLARE(int) ftdm_load_module(const char *name);
|
||||
FT_DECLARE(int) ftdm_load_module_assume(const char *name);
|
||||
FT_DECLARE(int) ftdm_vasprintf(char **ret, const char *fmt, va_list ap);
|
||||
FT_DECLARE(ftdm_status_t) ftdm_channel_done(ftdm_channel_t *ftdmchan);
|
||||
|
||||
FT_DECLARE(ftdm_status_t) ftdm_span_close_all(void);
|
||||
FT_DECLARE(ftdm_status_t) ftdm_channel_open_chan(ftdm_channel_t *ftdmchan);
|
||||
|
|
|
@ -228,12 +228,13 @@ typedef enum {
|
|||
FTDM_CHANNEL_STATE_HANGUP,
|
||||
FTDM_CHANNEL_STATE_HANGUP_COMPLETE,
|
||||
FTDM_CHANNEL_STATE_IN_LOOP,
|
||||
FTDM_CHANNEL_STATE_RESET,
|
||||
FTDM_CHANNEL_STATE_INVALID
|
||||
} ftdm_channel_state_t;
|
||||
#define CHANNEL_STATE_STRINGS "DOWN", "HOLD", "SUSPENDED", "DIALTONE", "COLLECT", \
|
||||
"RING", "RINGING", "BUSY", "ATTN", "GENRING", "DIALING", "GET_CALLERID", "CALLWAITING", \
|
||||
"RESTART", "PROCEED", "PROGRESS", "PROGRESS_MEDIA", "UP", "IDLE", "TERMINATING", "CANCEL", \
|
||||
"HANGUP", "HANGUP_COMPLETE", "IN_LOOP", "INVALID"
|
||||
"HANGUP", "HANGUP_COMPLETE", "IN_LOOP", "RESET", "INVALID"
|
||||
FTDM_STR2ENUM_P(ftdm_str2ftdm_channel_state, ftdm_channel_state2str, ftdm_channel_state_t)
|
||||
|
||||
typedef enum {
|
||||
|
|
Loading…
Reference in New Issue