From 55203ed0d72d28df807ea9f8d326e00cd77f5ee4 Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Fri, 10 Dec 2010 19:14:08 -0500 Subject: [PATCH 01/21] Support for call ID --- libs/freetdm/src/ftdm_io.c | 75 ++++++++++++++++++++++++++---- libs/freetdm/src/include/freetdm.h | 8 +++- 2 files changed, 72 insertions(+), 11 deletions(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index eaa25e3da5..78ae3d2b65 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -57,11 +57,14 @@ 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 int time_is_init = 0; @@ -235,6 +238,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 @@ -1896,8 +1903,6 @@ static ftdm_status_t ftdm_channel_reset(ftdm_channel_t *ftdmchan) 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)) { @@ -2483,6 +2488,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; @@ -2545,9 +2551,6 @@ FT_DECLARE(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_INUSE); ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND); ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_WINK); @@ -2587,7 +2590,8 @@ 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", @@ -2595,8 +2599,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_done(ftdm_channel_t *ftdmchan) } ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "channel done\n"); - - + memset(&ftdmchan->caller_data, 0, sizeof(ftdmchan->caller_data)); ftdm_mutex_unlock(ftdmchan->mutex); return FTDM_SUCCESS; @@ -5328,7 +5331,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 */ @@ -5347,6 +5350,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 +5380,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); @@ -5471,6 +5478,7 @@ static void ftdm_cpu_monitor_stop(void) FT_DECLARE(ftdm_status_t) ftdm_global_init(void) { + int i; memset(&globals, 0, sizeof(globals)); time_init(); @@ -5485,6 +5493,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 +5504,9 @@ 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; } + for(i=0;icall_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: diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h index 4ee6ff5f52..cc32d66bdd 100644 --- a/libs/freetdm/src/include/freetdm.h +++ b/libs/freetdm/src/include/freetdm.h @@ -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; /*! Date: Mon, 13 Dec 2010 11:29:38 -0500 Subject: [PATCH 02/21] removed unnecessary initialization --- libs/freetdm/src/ftdm_io.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 78ae3d2b65..8dd0a2de01 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -5478,7 +5478,6 @@ static void ftdm_cpu_monitor_stop(void) FT_DECLARE(ftdm_status_t) ftdm_global_init(void) { - int i; memset(&globals, 0, sizeof(globals)); time_init(); @@ -5504,9 +5503,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; } - for(i=0;i Date: Mon, 13 Dec 2010 16:27:51 -0500 Subject: [PATCH 03/21] freetdm: ftdm_r2 - fix stats --- libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index 9d94c6d088..9206493ad2 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -665,7 +665,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) @@ -1955,7 +1955,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), From 905fdcc2488dfa0b8cc8bb4d2f0f199704a943b8 Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Tue, 14 Dec 2010 11:23:47 -0500 Subject: [PATCH 04/21] freetdm: Support for channel restarts --- libs/freetdm/mod_freetdm/mod_freetdm.c | 22 ++ libs/freetdm/src/ftdm_io.c | 101 ++++---- libs/freetdm/src/ftdm_m3ua.c | 2 +- .../freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.c | 2 +- .../src/ftmod/ftmod_pritap/ftmod_pritap.c | 4 +- .../ftmod_sangoma_boost/ftmod_sangoma_boost.c | 8 +- .../ftmod_sangoma_isdn/ftmod_sangoma_isdn.c | 32 ++- .../ftmod_sangoma_isdn/ftmod_sangoma_isdn.h | 10 +- .../ftmod_sangoma_isdn_stack_hndl.c | 108 ++++++++- .../ftmod_sangoma_isdn_stack_out.c | 218 ++---------------- .../ftmod_sangoma_isdn_stack_rcv.c | 22 +- .../ftmod_sangoma_isdn_support.c | 104 ++++++++- libs/freetdm/src/include/freetdm.h | 9 + libs/freetdm/src/include/private/ftdm_core.h | 1 - libs/freetdm/src/include/private/ftdm_types.h | 3 +- 15 files changed, 367 insertions(+), 279 deletions(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index 38197bb2f0..26b84636ca 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -3922,6 +3922,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 \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); diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index e13d0196b8..deeb578c81 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -65,6 +65,8 @@ 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; @@ -1874,45 +1876,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; - } - - 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) { @@ -2462,6 +2425,21 @@ 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"); +#ifdef __WINDOWS__ + UNREFERENCED_PARAMETER(file); + UNREFERENCED_PARAMETER(func); + UNREFERENCED_PARAMETER(line); +#endif + + ftdm_channel_lock(ftdmchan); + ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_RESET, 0); + 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; @@ -2545,12 +2523,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); + 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); @@ -2591,17 +2570,47 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_done(ftdm_channel_t *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); } ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "channel done\n"); memset(&ftdmchan->caller_data, 0, sizeof(ftdmchan->caller_data)); - ftdm_mutex_unlock(ftdmchan->mutex); + 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_mutex_unlock(ftdmchan->mutex); return FTDM_SUCCESS; } @@ -2632,7 +2641,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_close(ftdm_channel_t **ftdmchan) 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 { diff --git a/libs/freetdm/src/ftdm_m3ua.c b/libs/freetdm/src/ftdm_m3ua.c index 1a6fe362e7..5a468d1378 100644 --- a/libs/freetdm/src/ftdm_m3ua.c +++ b/libs/freetdm/src/ftdm_m3ua.c @@ -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: diff --git a/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.c b/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.c index 6a8a4eb379..c6a0e5ff0e 100644 --- a/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.c +++ b/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.c @@ -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: diff --git a/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c b/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c index 220a96515b..b3b4f2a9dc 100644 --- a/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c +++ b/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c @@ -281,10 +281,10 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan) switch (ftdmchan->state) { case FTDM_CHANNEL_STATE_DOWN: { - ftdm_channel_done(ftdmchan); + ftdm_channel_close(ftdmchan); ftdmchan->call_data = NULL; - ftdm_channel_done(peerchan); + ftdm_channel_close(peerchan); peerchan->call_data = NULL; } break; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c index 50a01cc0ec..a196725d4e 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c @@ -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)); @@ -1106,7 +1106,7 @@ 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_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(ftdmchan); return; } ftdm_log(FTDM_LOG_DEBUG, "%d:%d starting loop\n", ftdmchan->span_id, ftdmchan->chan_id); @@ -1426,11 +1426,11 @@ 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_close(ftdmchan); } } break; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c index e20d3ae7e0..49e16ea12c 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c @@ -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, @@ -780,7 +792,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 +850,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 +879,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; @@ -1072,7 +1085,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 +1180,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; @@ -1210,7 +1224,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) { diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h index f15eff9200..4662d4e9bb 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h @@ -352,8 +352,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 +377,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); @@ -453,6 +457,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 +489,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); diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c index fb65d20cab..003227016d 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c @@ -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; @@ -285,6 +289,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 +308,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)); @@ -375,6 +385,9 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event) /* 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 +427,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; @@ -531,7 +547,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 +597,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: + /* User initiated reset, so they do not know about this call */ + break; default: ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Received RELEASE in an invalid state (%s)\n", ftdm_channel_state2str(ftdmchan->state)); @@ -1050,18 +1069,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_CRIT, "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 +1182,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; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c index 297c59c3b7..bb04f887ab 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c @@ -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) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c index af180d1f7c..4b04fb065e 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c @@ -630,8 +630,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 +726,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 +753,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; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c index 76d11d6d34..28768a1f09 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c @@ -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) { diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h index cc32d66bdd..a3cddadb81 100644 --- a/libs/freetdm/src/include/freetdm.h +++ b/libs/freetdm/src/include/freetdm.h @@ -702,6 +702,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)) @@ -741,6 +749,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 * diff --git a/libs/freetdm/src/include/private/ftdm_core.h b/libs/freetdm/src/include/private/ftdm_core.h index deabafd537..9222da3a42 100644 --- a/libs/freetdm/src/include/private/ftdm_core.h +++ b/libs/freetdm/src/include/private/ftdm_core.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); diff --git a/libs/freetdm/src/include/private/ftdm_types.h b/libs/freetdm/src/include/private/ftdm_types.h index 313044abc4..f03c060e5a 100644 --- a/libs/freetdm/src/include/private/ftdm_types.h +++ b/libs/freetdm/src/include/private/ftdm_types.h @@ -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 { From 56515c3a643eda32d8d527a215d4934e521e5e07 Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Tue, 14 Dec 2010 16:04:25 -0500 Subject: [PATCH 05/21] Minor change to allow skip states --- libs/freetdm/src/ftdm_io.c | 16 +++++++++------- .../ftmod_sangoma_isdn/ftmod_sangoma_isdn.c | 9 +++------ .../ftmod_sangoma_isdn_stack_hndl.c | 7 +++++-- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index deeb578c81..4bd0fdd33e 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -2379,14 +2379,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); diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c index 49e16ea12c..f8867d5fcf 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c @@ -704,12 +704,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; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c index 003227016d..bdd371704d 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c @@ -493,6 +493,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)); @@ -598,7 +601,7 @@ void sngisdn_process_rel_ind (sngisdn_event_data_t *sngisdn_event) } break; case FTDM_CHANNEL_STATE_RESET: - /* User initiated reset, so they do not know about this call */ + 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", @@ -1103,7 +1106,7 @@ void sngisdn_process_rst_cfm (sngisdn_event_data_t *sngisdn_event) } if (!rstEvnt->rstInd.eh.pres || !rstEvnt->rstInd.rstClass.pres) { - ftdm_log(FTDM_LOG_CRIT, "Receved RESTART, but Restart Indicator IE not present\n"); + ftdm_log(FTDM_LOG_DEBUG, "Receved RESTART, but Restart Indicator IE not present\n"); return; } From c6417fa2b389364f83e6bad6fdd4ff9f059b589e Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Tue, 14 Dec 2010 16:50:10 -0500 Subject: [PATCH 06/21] freetdm: ftmod_r2 - disable MF dump for forward calls on call accepted --- libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index 9206493ad2..6bec6b0cf7 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -585,6 +585,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 +609,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); } } From 1c01144c207d7462e93a6955a5cf129373e84df3 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Tue, 14 Dec 2010 16:55:40 -0500 Subject: [PATCH 07/21] freetdm: open all media dumps as binary. Fixes Windows corrupted cores. --- libs/freetdm/src/ftdm_io.c | 8 +++++--- libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c | 4 ++-- libs/freetdm/src/include/ftdm_declare.h | 2 ++ 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index e13d0196b8..2fa795344a 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -2715,7 +2715,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); } @@ -2731,7 +2732,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); } @@ -3376,7 +3378,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 { diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index 6bec6b0cf7..1549833571 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -568,14 +568,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); diff --git a/libs/freetdm/src/include/ftdm_declare.h b/libs/freetdm/src/include/ftdm_declare.h index 4aba703f28..5c57e01a70 100644 --- a/libs/freetdm/src/include/ftdm_declare.h +++ b/libs/freetdm/src/include/ftdm_declare.h @@ -158,12 +158,14 @@ typedef __int64 int64_t; typedef __int32 int32_t; typedef __int16 int16_t; typedef __int8 int8_t; +#define FTDM_O_BINARY O_BINARY #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_INVALID_SOCKET -1 typedef int ftdm_socket_t; #include From 3085523f568cad7c9cc720d1899783fd33128bb9 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Wed, 15 Dec 2010 09:56:27 -0500 Subject: [PATCH 08/21] freetdm: define special size formatting that actually works on Linux and Windows --- libs/freetdm/src/ftdm_io.c | 19 ++++++++++--------- libs/freetdm/src/include/ftdm_declare.h | 2 ++ 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 2fa795344a..fca3adc9ad 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -2801,10 +2801,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; @@ -2816,7 +2816,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); } @@ -2834,7 +2835,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; @@ -2846,7 +2847,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); } @@ -2879,7 +2880,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; @@ -3448,7 +3449,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); @@ -3461,7 +3462,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); } } @@ -4702,7 +4703,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'; diff --git a/libs/freetdm/src/include/ftdm_declare.h b/libs/freetdm/src/include/ftdm_declare.h index 5c57e01a70..bfec448253 100644 --- a/libs/freetdm/src/include/ftdm_declare.h +++ b/libs/freetdm/src/include/ftdm_declare.h @@ -159,6 +159,7 @@ 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 @@ -166,6 +167,7 @@ typedef __int8 int8_t; #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 From 102640ad7be96a2f23194cefbb1ca824416576dd Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Wed, 15 Dec 2010 11:45:50 -0500 Subject: [PATCH 09/21] freetdm: support for SIGEVENT_RING --- libs/freetdm/mod_freetdm/mod_freetdm.c | 1 + .../ftmod_sangoma_isdn/ftmod_sangoma_isdn.c | 25 +++++++++--- .../ftmod_sangoma_isdn/ftmod_sangoma_isdn.h | 6 ++- .../ftmod_sangoma_isdn_stack_hndl.c | 38 ++++++++++++++----- libs/freetdm/src/include/freetdm.h | 5 ++- 5 files changed, 56 insertions(+), 19 deletions(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index 26b84636ca..d8f98f1c61 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -2167,6 +2167,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); diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c index f8867d5fcf..48ddddce6b 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c @@ -215,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} }, { @@ -223,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, @@ -692,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: diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h index 4662d4e9bb..0c6c1c6eef 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h @@ -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; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c index bdd371704d..7e9e360c6d 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c @@ -278,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: @@ -364,21 +365,38 @@ 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: diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h index a3cddadb81..f8f69abc71 100644 --- a/libs/freetdm/src/include/freetdm.h +++ b/libs/freetdm/src/include/freetdm.h @@ -314,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 */ @@ -327,7 +328,7 @@ typedef enum { FTDM_SIGEVENT_FACILITY, /* !< In call facility event */ FTDM_SIGEVENT_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" From ea2b4774441a594e71ad921fe4721318fa200159 Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Wed, 15 Dec 2010 12:56:49 -0500 Subject: [PATCH 10/21] Freetdm:fix for ftdm_channel_close not always passed double-pointer --- libs/freetdm/src/ftdm_io.c | 12 +++--------- libs/freetdm/src/ftdm_m3ua.c | 2 +- libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.c | 2 +- libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c | 6 +++--- .../ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c | 8 +++++--- 5 files changed, 13 insertions(+), 17 deletions(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 4bd0fdd33e..eaf057e8a8 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -2430,14 +2430,9 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_send_msg(const char *file, const ch 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"); -#ifdef __WINDOWS__ - UNREFERENCED_PARAMETER(file); - UNREFERENCED_PARAMETER(func); - UNREFERENCED_PARAMETER(line); -#endif ftdm_channel_lock(ftdmchan); - ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_RESET, 0); + ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_RESET, 1); ftdm_channel_unlock(ftdmchan); return FTDM_SUCCESS; } @@ -2578,8 +2573,7 @@ static ftdm_status_t ftdm_channel_done(ftdm_channel_t *ftdmchan) ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "channel dropped data: txdrops = %d, rxdrops = %d\n", ftdmchan->txdrops, ftdmchan->rxdrops); } - - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "channel done\n"); + memset(&ftdmchan->caller_data, 0, sizeof(ftdmchan->caller_data)); ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_HOLD); @@ -2612,6 +2606,7 @@ static ftdm_status_t ftdm_channel_done(ftdm_channel_t *ftdmchan) 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; } @@ -2642,7 +2637,6 @@ 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_done(check); *ftdmchan = NULL; } diff --git a/libs/freetdm/src/ftdm_m3ua.c b/libs/freetdm/src/ftdm_m3ua.c index 5a468d1378..8d3e00213a 100644 --- a/libs/freetdm/src/ftdm_m3ua.c +++ b/libs/freetdm/src/ftdm_m3ua.c @@ -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_close(ftdmchan); + ftdm_channel_close(&ftdmchan); } break; case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: diff --git a/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.c b/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.c index c6a0e5ff0e..5b4ce7196a 100644 --- a/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.c +++ b/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.c @@ -1325,7 +1325,7 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan) } Q931ReleaseCRV(&isdn_data->q931, gen->CRV); } - ftdm_channel_close(ftdmchan); + ftdm_channel_close(&ftdmchan); } break; case FTDM_CHANNEL_STATE_PROGRESS: diff --git a/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c b/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c index b3b4f2a9dc..27fbe2139f 100644 --- a/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c +++ b/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c @@ -280,12 +280,12 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan) switch (ftdmchan->state) { case FTDM_CHANNEL_STATE_DOWN: - { - ftdm_channel_close(ftdmchan); + { ftdmchan->call_data = NULL; + ftdm_channel_close(&ftdmchan); - ftdm_channel_close(peerchan); peerchan->call_data = NULL; + ftdm_channel_close(&peerchan); } break; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c index a196725d4e..f59b3b8c4f 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c @@ -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_close(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_close(ftdmchan); + ftdm_channel_close(&toclose); return; } ftdm_log(FTDM_LOG_DEBUG, "%d:%d starting loop\n", ftdmchan->span_id, ftdmchan->chan_id); @@ -1430,7 +1431,8 @@ static __inline__ ftdm_status_t state_advance(ftdm_channel_t *ftdmchan) 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_close(ftdmchan); + ftdm_channel_t *toclose = ftdmchan; + ftdm_channel_close(&toclose); } } break; From dcdbeff9d80202ef8ab0c9a3aff73a09f407b53d Mon Sep 17 00:00:00 2001 From: Arnaldo Pereira Date: Wed, 15 Dec 2010 17:43:40 -0200 Subject: [PATCH 11/21] freetdm: ftmod_wanpipe - now receiving ftdm macros for channel polling, instead of using POLLPRI, etc., directly ftmod_r2 - also using ftdm macros for polling --- libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c | 10 +++------ .../src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c | 22 +++++++++++++++++-- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index 1549833571..10e0c4ac9f 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -1720,7 +1720,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); @@ -1732,16 +1732,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); diff --git a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c index e1b6658945..627ef7bb67 100644 --- a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c +++ b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c @@ -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; + + /* if the user specify which events to poll the channel for, we translate them from ftdm_wait_flag_t + * to events that either sangoma_waitfor_many() or poll() understands. if not, we poll for POLLPRI */ + if (poll_events) { + if (poll_events[j] & FTDM_READ) { + chan_events = POLLIN; + } + if (poll_events[j] & FTDM_WRITE) { + chan_events |= POLLOUT; + } + if (poll_events[j] & FTDM_EVENTS) { + chan_events |= POLLPRI; + } + } else { + chan_events = POLLPRI; + } + #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! */ From 20ba5da47991e2b00854ffb66985ce9388d412b2 Mon Sep 17 00:00:00 2001 From: Arnaldo Pereira Date: Wed, 15 Dec 2010 18:08:55 -0200 Subject: [PATCH 12/21] freetdm: ftmod_r2 - implemented set_channel_sig_status() --- libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c | 23 +++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index 10e0c4ac9f..6e78810b0c 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -449,6 +449,24 @@ 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, "Ignoring unknown sigstatus: %d\n", status); + return FTDM_FAIL; + } + return FTDM_SUCCESS; +} + /* always called from the monitor thread */ static void ftdm_r2_on_call_init(openr2_chan_t *r2chan) { @@ -1419,13 +1437,12 @@ 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_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; From bb8d901c4f437c57b1c349575d5d93eea4fb4203 Mon Sep 17 00:00:00 2001 From: Arnaldo Pereira Date: Wed, 15 Dec 2010 18:32:35 -0200 Subject: [PATCH 13/21] freetdm: ftmod_wanpipe - replaced some POLL macros by SANG_WAIT_OBJ_* --- libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c index 627ef7bb67..2db4326847 100644 --- a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c +++ b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c @@ -1053,20 +1053,20 @@ FIO_SPAN_POLL_EVENT_FUNCTION(wanpipe_poll_event) ftdm_channel_t *ftdmchan = span->channels[i]; uint32_t chan_events = 0; - /* if the user specify which events to poll the channel for, we translate them from ftdm_wait_flag_t - * to events that either sangoma_waitfor_many() or poll() understands. if not, we poll for POLLPRI */ + /* 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 = POLLIN; + chan_events = SANG_WAIT_OBJ_HAS_INPUT; } if (poll_events[j] & FTDM_WRITE) { - chan_events |= POLLOUT; + chan_events |= SANG_WAIT_OBJ_HAS_OUTPUT; } if (poll_events[j] & FTDM_EVENTS) { - chan_events |= POLLPRI; + chan_events |= SANG_WAIT_OBJ_HAS_EVENTS; } } else { - chan_events = POLLPRI; + chan_events = SANG_WAIT_OBJ_HAS_EVENTS; } #ifdef LIBSANGOMA_VERSION From 72f99898d2dc3dc3bdd7365d1c113462d4d139cb Mon Sep 17 00:00:00 2001 From: Arnaldo Pereira Date: Wed, 15 Dec 2010 18:48:49 -0200 Subject: [PATCH 14/21] freetdm: ftmod_r2 - updated warning message --- libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index 6e78810b0c..ef9201bbe6 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -461,7 +461,7 @@ static FIO_CHANNEL_SET_SIG_STATUS_FUNCTION(ftdm_r2_set_channel_sig_status) openr2_chan_set_idle(r2chan); break; default: - ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Ignoring unknown sigstatus: %d\n", status); + ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Cannot set signaling status to unknown value '%s'\n", status); return FTDM_FAIL; } return FTDM_SUCCESS; From dd345b913bcec51f247da22bba045a227e7db320 Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Wed, 15 Dec 2010 16:29:03 -0500 Subject: [PATCH 15/21] freetdm: Support for RAW traces --- libs/freetdm/src/ftdm_io.c | 8 +- libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c | 2 +- .../ftmod_sangoma_isdn/ftmod_sangoma_isdn.c | 14 +++- .../ftmod_sangoma_isdn/ftmod_sangoma_isdn.h | 9 ++- .../ftmod_sangoma_isdn_cfg.c | 4 + .../ftmod_sangoma_isdn_cntrl.c | 2 +- .../ftmod_sangoma_isdn_stack_rcv.c | 64 +++++++-------- .../ftmod_sangoma_isdn_trace.c | 79 ++++++++++++++++++- .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c | 4 +- .../ftmod_sangoma_ss7_handle.c | 4 +- .../ftmod_sangoma_ss7_main.c | 18 ++--- libs/freetdm/src/include/freetdm.h | 37 ++++++++- 12 files changed, 183 insertions(+), 62 deletions(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 6166c551f7..3fa763fe79 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -280,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) @@ -5292,6 +5295,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; } @@ -5299,8 +5303,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; @@ -5347,7 +5349,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 { diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index 1549833571..8c2fd51a64 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -255,7 +255,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)); } diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c index 48ddddce6b..bb29b4f4a5 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c @@ -976,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); @@ -986,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"); @@ -1210,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")) { @@ -1218,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 \n"); - } + } } if (!strcasecmp(argv[0], "l1_stats")) { ftdm_span_t *span; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h index 0c6c1c6eef..6a440e4f66 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h @@ -261,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]; @@ -427,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); diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c index cce10cc1dd..c979000223 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c @@ -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); } diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cntrl.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cntrl.c index 5060cb6bba..668b63006c 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cntrl.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cntrl.c @@ -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; } diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c index 4b04fb065e..3afdaa599e 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c @@ -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; @@ -777,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; @@ -788,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++; @@ -809,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; @@ -865,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; } diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_trace.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_trace.c index e5167164b3..c03976a1c2 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_trace.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_trace.c @@ -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; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c index 34cca80140..dc2d24f42a 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c @@ -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 */ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c index 7517ee42a0..dcfb7f79e0 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c @@ -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 */ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c index 5c171a9f6b..05a325b913 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c @@ -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 */ diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h index f8f69abc71..18da29f566 100644 --- a/libs/freetdm/src/include/freetdm.h +++ b/libs/freetdm/src/include/freetdm.h @@ -325,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, /*! Date: Wed, 15 Dec 2010 16:29:44 -0500 Subject: [PATCH 16/21] freetdm: Support for RAW traces --- libs/freetdm/mod_freetdm/mod_freetdm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index d8f98f1c61..6f6025ac36 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -2077,7 +2077,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)); } @@ -2183,7 +2183,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)); } From 53346e494876aaa5af9b9adf39e7f510cac938ad Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Wed, 15 Dec 2010 16:42:47 -0500 Subject: [PATCH 17/21] Freetdm: exposed channel availability rate to user --- libs/freetdm/src/ftdm_io.c | 12 ++++++++++++ libs/freetdm/src/include/freetdm.h | 8 ++++++++ 2 files changed, 20 insertions(+) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 3fa763fe79..1750d6d7d9 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -1702,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; diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h index 18da29f566..41bf819a1c 100644 --- a/libs/freetdm/src/include/freetdm.h +++ b/libs/freetdm/src/include/freetdm.h @@ -696,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)) From a082c9e913bb3d777d29e4692a8a6e8afcd552e2 Mon Sep 17 00:00:00 2001 From: Arnaldo Pereira Date: Thu, 16 Dec 2010 17:01:06 -0200 Subject: [PATCH 18/21] freetdm: ftmod_r2 - implemented ftdm_r2_get_span_sig_status() and ftdm_r2_set_span_sig_status() mod_freetdm - created sigstatus api command --- libs/freetdm/mod_freetdm/mod_freetdm.c | 78 +++++++++++++++++++++- libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c | 71 +++++++++++++++++++- 2 files changed, 147 insertions(+), 2 deletions(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index 38197bb2f0..daddc9abc1 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -3542,7 +3542,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 [] [] []\n"); + goto end; + } + if (!strcasecmp(argv[1], "get") && argc < 3) { + stream->write_function(stream, "-ERR sigstatus get usage: get \n"); + goto end; + } + if (!strcasecmp(argv[1], "set") && argc != 5) { + stream->write_function(stream, "-ERR sigstatus set usage: set |all \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 []\n"); goto end; diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index ef9201bbe6..b4e9e138cc 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -461,12 +461,79 @@ static FIO_CHANNEL_SET_SIG_STATUS_FUNCTION(ftdm_r2_set_channel_sig_status) openr2_chan_set_idle(r2chan); break; default: - ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Cannot set signaling status to unknown value '%s'\n", status); + ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Cannot set signaling status to unknown value '%d'\n", status); return FTDM_FAIL; } return FTDM_SUCCESS; } +static FIO_SPAN_GET_SIG_STATUS_FUNCTION(ftdm_r2_get_span_sig_status) +{ + ftdm_iterator_t *chaniter = NULL; + ftdm_iterator_t *citer = NULL; + uint32_t i; + + 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 (i = 1, citer = chaniter; citer; citer = ftdm_iterator_next(citer), i++) { + 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; + uint32_t i; + + /* 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 (i = 1, citer = chaniter; citer; citer = ftdm_iterator_next(citer), i++) { + 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_iterator_free(chaniter); + return FTDM_SUCCESS; +} + /* always called from the monitor thread */ static void ftdm_r2_on_call_init(openr2_chan_t *r2chan) { @@ -1441,6 +1508,8 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_r2_configure_span_signaling) 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; From 6b66a0516bcc4d7bd9461366ea7bf958b4ef9aeb Mon Sep 17 00:00:00 2001 From: Arnaldo Pereira Date: Thu, 16 Dec 2010 18:19:50 -0200 Subject: [PATCH 19/21] freetdm: ftmod_r2 - fixed infinite loop on span stop --- libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index d1b24da1b8..952b94b63f 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -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, @@ -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); @@ -1759,6 +1763,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 @@ -1781,7 +1788,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)); From 43dd86fb96f8a20b405df6f6fda932ad6cc2e017 Mon Sep 17 00:00:00 2001 From: Arnaldo Pereira Date: Thu, 16 Dec 2010 18:47:40 -0200 Subject: [PATCH 20/21] freetdm: ftmod_r2 - small code clean --- libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index 952b94b63f..9f35971abb 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -473,20 +473,16 @@ static FIO_CHANNEL_SET_SIG_STATUS_FUNCTION(ftdm_r2_set_channel_sig_status) static FIO_SPAN_GET_SIG_STATUS_FUNCTION(ftdm_r2_get_span_sig_status) { - ftdm_iterator_t *chaniter = NULL; ftdm_iterator_t *citer = NULL; - uint32_t i; - - chaniter = ftdm_span_get_chan_iterator(span, 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 (i = 1, citer = chaniter; citer; citer = ftdm_iterator_next(citer), i++) { + 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; @@ -501,7 +497,6 @@ 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; - uint32_t i; /* we either set the channels to BLOCK or IDLE */ switch(status) { @@ -523,7 +518,7 @@ static FIO_SPAN_SET_SIG_STATUS_FUNCTION(ftdm_r2_set_span_sig_status) return FTDM_FAIL; } /* iterate over all channels, setting them to the requested state */ - for (i = 1, citer = chaniter; citer; citer = ftdm_iterator_next(citer), i++) { + 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) { From a134136ee715f6b392ec8bf3c5b3e31af7953c18 Mon Sep 17 00:00:00 2001 From: Arnaldo Pereira Date: Thu, 16 Dec 2010 19:44:32 -0200 Subject: [PATCH 21/21] freetdm: ftmod_r2 - notify the core when we change the signaling status of a channel or span through the api --- libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index 9f35971abb..14eca429e8 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -468,6 +468,7 @@ static FIO_CHANNEL_SET_SIG_STATUS_FUNCTION(ftdm_r2_set_channel_sig_status) 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; } @@ -528,6 +529,7 @@ static FIO_SPAN_SET_SIG_STATUS_FUNCTION(ftdm_r2_set_span_sig_status) 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;