From 8dd33bc8ccd25a227285627101f28305510086c0 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Thu, 2 Dec 2010 18:35:48 -0500 Subject: [PATCH 1/8] freetdm: add channel commands to record and dump media --- libs/freetdm/src/ftdm_io.c | 320 +++++++++++++----- libs/freetdm/src/include/freetdm.h | 29 ++ libs/freetdm/src/include/private/ftdm_core.h | 26 +- libs/freetdm/src/include/private/ftdm_types.h | 1 + 4 files changed, 275 insertions(+), 101 deletions(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 3dd1aa9ece..92302c5071 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -86,6 +86,110 @@ FT_DECLARE(ftdm_time_t) ftdm_current_time_in_ms(void) #endif } +static void write_chan_io_dump(ftdm_channel_t *fchan, ftdm_io_dump_t *dump, char *dataptr, int dlen) +{ + int windex = dump->windex; + int avail = dump->size - windex; + + if (dlen > avail) { + int diff = dlen - avail; + + ftdm_assert(diff < dump->size, "Very small buffer or very big IO chunk!\n"); + + /* write only what we can and the rest at the beginning of the buffer */ + memcpy(&dump->buffer[windex], dataptr, avail); + memcpy(&dump->buffer[0], &dataptr[avail], diff); + windex = diff; + + ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "wrapping around dump buffer %p up to index %d\n\n", dump, windex); + dump->wrapped = 1; + } else { + memcpy(&dump->buffer[windex], dataptr, dlen); + windex += dlen; + } + + if (windex == dump->size) { + ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "wrapping around dump buffer %p\n", dump); + windex = 0; + dump->wrapped = 1; + } + + dump->windex = windex; +} + +static void dump_chan_io_to_file(ftdm_channel_t *fchan, ftdm_io_dump_t *dump, FILE *file) +{ + /* write the saved audio buffer */ + int rc = 0; + int towrite = dump->size - dump->windex; + if (dump->wrapped) { + rc = fwrite(&dump->buffer[dump->windex], 1, towrite, file); + if (rc != towrite) { + ftdm_log_chan(fchan, FTDM_LOG_ERROR, "only wrote %d out of %d bytes in DTMF debug buffer\n", rc, towrite); + } + } + if (dump->windex) { + towrite = dump->windex; + rc = fwrite(&dump->buffer[0], 1, towrite, file); + if (rc != towrite) { + ftdm_log_chan(fchan, FTDM_LOG_ERROR, "only wrote %d out of %d bytes in DTMF debug buffer\n", rc, towrite); + } + } + dump->windex = 0; + dump->wrapped = 0; +} + +static void stop_chan_io_dump(ftdm_io_dump_t *dump) +{ + if (!dump->buffer) { + return; + } + ftdm_safe_free(dump->buffer); + memset(dump, 0, sizeof(dump)); +} + +static int start_chan_io_dump(ftdm_channel_t *chan, ftdm_io_dump_t *dump, ftdm_size_t size) +{ + if (dump->buffer) { + ftdm_log_chan_msg(chan, FTDM_LOG_ERROR, "IO dump is already started\n"); + return -1; + } + memset(dump, 0, sizeof(*dump)); + dump->buffer = ftdm_malloc(size); + if (!dump->buffer) { + return -1; + } + dump->size = size; + return 0; +} + + +static void close_dtmf_debug_file(ftdm_channel_t *ftdmchan) +{ + if (ftdmchan->dtmfdbg.file) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "closing debug dtmf file\n"); + fclose(ftdmchan->dtmfdbg.file); + ftdmchan->dtmfdbg.file = NULL; + } +} + +static int disable_dtmf_debug(ftdm_channel_t *ftdmchan) +{ + if (!ftdmchan->dtmfdbg.enabled) { + return 0; + } + + if (!ftdmchan->rxdump.buffer) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "DTMF debug enabled but no rx dump?\n"); + return -1; + } + + close_dtmf_debug_file(ftdmchan); + stop_chan_io_dump(&ftdmchan->rxdump); + ftdmchan->dtmfdbg.enabled = 0; + return 0; +} + typedef struct { uint8_t enabled; uint8_t running; @@ -448,10 +552,6 @@ static ftdm_status_t ftdm_channel_destroy(ftdm_channel_t *ftdmchan) ftdm_sleep(500); } -#ifdef FTDM_DEBUG_DTMF - ftdm_mutex_destroy(&ftdmchan->dtmfdbg.mutex); -#endif - ftdm_mutex_lock(ftdmchan->pre_buffer_mutex); ftdm_buffer_destroy(&ftdmchan->pre_buffer); ftdm_mutex_unlock(ftdmchan->pre_buffer_mutex); @@ -870,9 +970,6 @@ FT_DECLARE(ftdm_status_t) ftdm_span_add_channel(ftdm_span_t *span, ftdm_socket_t ftdm_mutex_create(&new_chan->mutex); ftdm_mutex_create(&new_chan->pre_buffer_mutex); -#ifdef FTDM_DEBUG_DTMF - ftdm_mutex_create(&new_chan->dtmfdbg.mutex); -#endif ftdm_buffer_create(&new_chan->digit_buffer, 128, 128, 0); ftdm_buffer_create(&new_chan->gen_dtmf_buffer, 128, 128, 0); @@ -2355,23 +2452,6 @@ FT_DECLARE(ftdm_status_t) ftdm_span_get_sig_status(ftdm_span_t *span, ftdm_signa } } -#ifdef FTDM_DEBUG_DTMF -static void close_dtmf_debug(ftdm_channel_t *ftdmchan) -{ - ftdm_mutex_lock(ftdmchan->dtmfdbg.mutex); - - if (ftdmchan->dtmfdbg.file) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "closing debug dtmf file\n"); - fclose(ftdmchan->dtmfdbg.file); - ftdmchan->dtmfdbg.file = NULL; - } - ftdmchan->dtmfdbg.windex = 0; - ftdmchan->dtmfdbg.wrapped = 0; - - ftdm_mutex_unlock(ftdmchan->dtmfdbg.mutex); -} -#endif - static ftdm_status_t ftdm_channel_clear_vars(ftdm_channel_t *ftdmchan); FT_DECLARE(ftdm_status_t) ftdm_channel_done(ftdm_channel_t *ftdmchan) { @@ -2400,9 +2480,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_done(ftdm_channel_t *ftdmchan) ftdm_buffer_destroy(&ftdmchan->pre_buffer); ftdmchan->pre_buffer_size = 0; ftdm_mutex_unlock(ftdmchan->pre_buffer_mutex); -#ifdef FTDM_DEBUG_DTMF - close_dtmf_debug(ftdmchan); -#endif + disable_dtmf_debug(ftdmchan); ftdm_channel_clear_vars(ftdmchan); if (ftdmchan->hangup_timer) { ftdm_sched_cancel_timer(globals.timingsched, ftdmchan->hangup_timer); @@ -2411,7 +2489,8 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_done(ftdm_channel_t *ftdmchan) ftdmchan->init_state = FTDM_CHANNEL_STATE_DOWN; ftdmchan->state = FTDM_CHANNEL_STATE_DOWN; - ftdm_log(FTDM_LOG_DEBUG, "channel done %u:%u\n", ftdmchan->span_id, ftdmchan->chan_id); + stop_chan_io_dump(&ftdmchan->txdump); + stop_chan_io_dump(&ftdmchan->rxdump); if (FTDM_IS_VOICE_CHANNEL(ftdmchan)) { ftdm_sigmsg_t sigmsg; @@ -2423,6 +2502,8 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_done(ftdm_channel_t *ftdmchan) ftdm_span_send_signal(ftdmchan->span, &sigmsg); } + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "channel done\n"); + ftdm_mutex_unlock(ftdmchan->mutex); return FTDM_SUCCESS; @@ -2431,7 +2512,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_done(ftdm_channel_t *ftdmchan) FT_DECLARE(ftdm_status_t) ftdm_channel_use(ftdm_channel_t *ftdmchan) { - assert(ftdmchan != NULL); + ftdm_assert(ftdmchan != NULL, "Null channel\n"); ftdm_set_flag_locked(ftdmchan, FTDM_CHANNEL_INUSE); @@ -2505,8 +2586,8 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co { ftdm_status_t status = FTDM_FAIL; - assert(ftdmchan != NULL); - assert(ftdmchan->fio != NULL); + ftdm_assert_return(ftdmchan != NULL, FTDM_FAIL, "No channel\n"); + ftdm_assert_return(ftdmchan->fio != NULL, FTDM_FAIL, "No IO attached to channel\n"); ftdm_mutex_lock(ftdmchan->mutex); @@ -2533,7 +2614,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co break; case FTDM_COMMAND_TRACE_INPUT: { - char *path = (char *) obj; + char *path = FTDM_COMMAND_OBJ_CHAR_P; if (ftdmchan->fds[FTDM_READ_TRACE_INDEX] > 0) { close(ftdmchan->fds[FTDM_READ_TRACE_INDEX]); ftdmchan->fds[FTDM_READ_TRACE_INDEX] = -1; @@ -2576,6 +2657,109 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co GOTO_STATUS(done, FTDM_SUCCESS); } break; + + /*!< Enable DTMF debugging */ + case FTDM_COMMAND_ENABLE_DEBUG_DTMF: + { + if (ftdmchan->dtmfdbg.enabled) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Cannot enable debug DTMF again\n"); + GOTO_STATUS(done, FTDM_FAIL); + } + if (ftdmchan->rxdump.buffer) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Cannot debug DTMF if Rx dumping is already enabled\n"); + GOTO_STATUS(done, FTDM_FAIL); + } + if (start_chan_io_dump(ftdmchan, &ftdmchan->rxdump, FTDM_IO_DUMP_DEFAULT_BUFF_SIZE)) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Failed to enable rx dump for DTMF debugging\n"); + } + ftdmchan->dtmfdbg.enabled = 1; + GOTO_STATUS(done, FTDM_SUCCESS); + } + break; + + /*!< Disable DTMF debugging (if not disabled explicitly, it is disabled automatically when calls hangup) */ + case FTDM_COMMAND_DISABLE_DEBUG_DTMF: + { + if (!ftdmchan->dtmfdbg.enabled) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "DTMF debug is already disabled\n"); + GOTO_STATUS(done, FTDM_SUCCESS); + } + if (disable_dtmf_debug(ftdmchan)) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Failed to disable DTMF debug\n"); + GOTO_STATUS(done, FTDM_FAIL); + } + GOTO_STATUS(done, FTDM_SUCCESS); + } + break; + + /*!< Start dumping all input to a circular buffer. The size of the circular buffer can be specified, default used otherwise */ + case FTDM_COMMAND_ENABLE_INPUT_DUMP: + { + ftdm_size_t size = obj ? FTDM_COMMAND_OBJ_SIZE : FTDM_IO_DUMP_DEFAULT_BUFF_SIZE; + if (start_chan_io_dump(ftdmchan, &ftdmchan->rxdump, size)) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Failed to enable input dump\n"); + GOTO_STATUS(done, FTDM_FAIL); + } + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Enabled input dump with size %zd\n", size); + GOTO_STATUS(done, FTDM_SUCCESS); + } + break; + + /*!< Stop dumping all input to a circular buffer. */ + case FTDM_COMMAND_DISABLE_INPUT_DUMP: + { + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Disabled input dump of size %zd\n", ftdmchan->rxdump.size); + stop_chan_io_dump(&ftdmchan->rxdump); + GOTO_STATUS(done, FTDM_SUCCESS); + } + break; + + /*!< Start dumping all output to a circular buffer. The size of the circular buffer can be specified, default used otherwise */ + case FTDM_COMMAND_ENABLE_OUTPUT_DUMP: + { + ftdm_size_t size = obj ? FTDM_COMMAND_OBJ_SIZE : FTDM_IO_DUMP_DEFAULT_BUFF_SIZE; + if (start_chan_io_dump(ftdmchan, &ftdmchan->txdump, size)) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Failed to enable output dump\n"); + GOTO_STATUS(done, FTDM_FAIL); + } + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Enabled output dump with size %zd\n", size); + GOTO_STATUS(done, FTDM_SUCCESS); + } + break; + + /*!< Stop dumping all output to a circular buffer. */ + case FTDM_COMMAND_DISABLE_OUTPUT_DUMP: + { + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Disabled output dump of size %zd\n", ftdmchan->rxdump.size); + stop_chan_io_dump(&ftdmchan->txdump); + GOTO_STATUS(done, FTDM_SUCCESS); + } + break; + + /*!< Dump the current input circular buffer to the specified FILE* structure */ + case FTDM_COMMAND_DUMP_INPUT: + { + if (!obj) { + GOTO_STATUS(done, FTDM_FAIL); + } + dump_chan_io_to_file(ftdmchan, &ftdmchan->rxdump, obj); + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Dumped input of size %zd to file %p\n", ftdmchan->rxdump.size, obj); + GOTO_STATUS(done, FTDM_SUCCESS); + } + break; + + /*!< Dump the current output circular buffer to the specified FILE* structure */ + case FTDM_COMMAND_DUMP_OUTPUT: + { + if (!obj) { + 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); + GOTO_STATUS(done, FTDM_SUCCESS); + } + break; + case FTDM_COMMAND_SET_INTERVAL: { if (!ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_INTERVAL)) { @@ -3044,12 +3228,14 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_queue_dtmf(ftdm_channel_t *ftdmchan, cons ftdm_size_t wr = 0; const char *p; - assert(ftdmchan != NULL); + ftdm_assert_return(ftdmchan != NULL, FTDM_FAIL, "No channel\n"); ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Queuing DTMF %s\n", dtmf); -#ifdef FTDM_DEBUG_DTMF - ftdm_mutex_lock(ftdmchan->dtmfdbg.mutex); + if (!ftdmchan->dtmfdbg.enabled) { + goto skipdebug; + } + if (!ftdmchan->dtmfdbg.file) { struct tm currtime; time_t currsec; @@ -3062,37 +3248,18 @@ 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, "w"); if (!ftdmchan->dtmfdbg.file) { ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "failed to open debug dtmf file %s\n", dfile); } else { - /* write the saved audio buffer */ - int rc = 0; - int towrite = sizeof(ftdmchan->dtmfdbg.buffer) - ftdmchan->dtmfdbg.windex; - - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "created debug DTMF file %s\n", dfile); ftdmchan->dtmfdbg.closetimeout = DTMF_DEBUG_TIMEOUT; - if (ftdmchan->dtmfdbg.wrapped) { - rc = fwrite(&ftdmchan->dtmfdbg.buffer[ftdmchan->dtmfdbg.windex], 1, towrite, ftdmchan->dtmfdbg.file); - if (rc != towrite) { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "only wrote %d out of %d bytes in DTMF debug buffer\n", rc, towrite); - } - } - if (ftdmchan->dtmfdbg.windex) { - towrite = ftdmchan->dtmfdbg.windex; - rc = fwrite(&ftdmchan->dtmfdbg.buffer[0], 1, towrite, ftdmchan->dtmfdbg.file); - if (rc != towrite) { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "only wrote %d out of %d bytes in DTMF debug buffer\n", rc, towrite); - } - } - ftdmchan->dtmfdbg.windex = 0; - ftdmchan->dtmfdbg.wrapped = 0; + ftdm_channel_command(ftdmchan, FTDM_COMMAND_DUMP_INPUT, ftdmchan->dtmfdbg.file); } } else { - ftdmchan->dtmfdbg.closetimeout = DTMF_DEBUG_TIMEOUT; + ftdmchan->dtmfdbg.closetimeout = DTMF_DEBUG_TIMEOUT; } - ftdm_mutex_unlock(ftdmchan->dtmfdbg.mutex); -#endif + +skipdebug: if (ftdmchan->pre_buffer) { ftdm_buffer_zero(ftdmchan->pre_buffer); @@ -3146,7 +3313,6 @@ static FIO_WRITE_FUNCTION(ftdm_raw_write) return ftdmchan->fio->write(ftdmchan, data, datalen); } - static FIO_READ_FUNCTION(ftdm_raw_read) { ftdm_status_t status = ftdmchan->fio->read(ftdmchan, data, datalen); @@ -3161,48 +3327,24 @@ static FIO_READ_FUNCTION(ftdm_raw_read) ftdmchan->span->sig_read(ftdmchan, data, *datalen); } -#ifdef FTDM_DEBUG_DTMF if (status == FTDM_SUCCESS) { int dlen = (int) *datalen; int rc = 0; - ftdm_mutex_lock(ftdmchan->dtmfdbg.mutex); - if (!ftdmchan->dtmfdbg.file) { - /* no file yet, write to our circular buffer */ - int windex = ftdmchan->dtmfdbg.windex; - int avail = sizeof(ftdmchan->dtmfdbg.buffer) - windex; - char *dataptr = data; - if (dlen > avail) { - int diff = dlen - avail; - /* write only what we can and the rest at the beginning of the buffer */ - memcpy(&ftdmchan->dtmfdbg.buffer[windex], dataptr, avail); - memcpy(&ftdmchan->dtmfdbg.buffer[0], &dataptr[avail], diff); - windex = diff; - /*ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "wrapping around dtmf read buffer up to index %d\n\n", windex);*/ - ftdmchan->dtmfdbg.wrapped = 1; - } else { - memcpy(&ftdmchan->dtmfdbg.buffer[windex], dataptr, dlen); - windex += dlen; - } - if (windex == sizeof(ftdmchan->dtmfdbg.buffer)) { - /*ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "wrapping around dtmf read buffer\n");*/ - windex = 0; - ftdmchan->dtmfdbg.wrapped = 1; - } - ftdmchan->dtmfdbg.windex = windex; - } else { + write_chan_io_dump(ftdmchan, &ftdmchan->rxdump, data, dlen); + + /* if dtmf debug is enabled and initialized, write there too */ + if (ftdmchan->dtmfdbg.file) { rc = fwrite(data, 1, dlen, ftdmchan->dtmfdbg.file); if (rc != dlen) { ftdm_log(FTDM_LOG_WARNING, "DTMF debugger wrote only %d out of %d bytes: %s\n", rc, datalen, strerror(errno)); } ftdmchan->dtmfdbg.closetimeout--; if (!ftdmchan->dtmfdbg.closetimeout) { - close_dtmf_debug(ftdmchan); + close_dtmf_debug_file(ftdmchan); } } - ftdm_mutex_unlock(ftdmchan->dtmfdbg.mutex); } -#endif return status; } diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h index 45254e817f..1adbaa819a 100644 --- a/libs/freetdm/src/include/freetdm.h +++ b/libs/freetdm/src/include/freetdm.h @@ -431,9 +431,38 @@ typedef enum { FTDM_COMMAND_WINK, FTDM_COMMAND_ENABLE_PROGRESS_DETECT, FTDM_COMMAND_DISABLE_PROGRESS_DETECT, + + /*!< Start tracing input and output from channel to the given file */ FTDM_COMMAND_TRACE_INPUT, FTDM_COMMAND_TRACE_OUTPUT, + + /*!< Stop both Input and Output trace, closing the files */ FTDM_COMMAND_TRACE_END_ALL, + + /*!< Enable DTMF debugging */ + FTDM_COMMAND_ENABLE_DEBUG_DTMF, + + /*!< Disable DTMF debugging (if not disabled explicitly, it is disabled automatically when calls hangup) */ + FTDM_COMMAND_DISABLE_DEBUG_DTMF, + + /*!< Start dumping all input to a circular buffer. The size of the circular buffer can be specified, default used otherwise */ + FTDM_COMMAND_ENABLE_INPUT_DUMP, + + /*!< Stop dumping all input to a circular buffer. */ + FTDM_COMMAND_DISABLE_INPUT_DUMP, + + /*!< Start dumping all output to a circular buffer. The size of the circular buffer can be specified, default used otherwise */ + FTDM_COMMAND_ENABLE_OUTPUT_DUMP, + + /*!< Stop dumping all output to a circular buffer. */ + FTDM_COMMAND_DISABLE_OUTPUT_DUMP, + + /*!< Dump the current input circular buffer to the specified FILE* structure */ + FTDM_COMMAND_DUMP_INPUT, + + /*!< Dump the current output circular buffer to the specified FILE* structure */ + FTDM_COMMAND_DUMP_OUTPUT, + FTDM_COMMAND_ENABLE_CALLERID_DETECT, FTDM_COMMAND_DISABLE_CALLERID_DETECT, FTDM_COMMAND_ENABLE_ECHOCANCEL, diff --git a/libs/freetdm/src/include/private/ftdm_core.h b/libs/freetdm/src/include/private/ftdm_core.h index 7683ec7145..04458adda1 100644 --- a/libs/freetdm/src/include/private/ftdm_core.h +++ b/libs/freetdm/src/include/private/ftdm_core.h @@ -342,21 +342,23 @@ typedef enum { FTDM_TYPE_CHANNEL } ftdm_data_type_t; -#ifdef FTDM_DEBUG_DTMF -/* number of bytes for the circular buffer (5 seconds worth of audio) */ -#define DTMF_DEBUG_SIZE 8 * 5000 -/* number of 20ms cycles before timeout and close the debug dtmf file (5 seconds) */ -#define DTMF_DEBUG_TIMEOUT 250 +/* number of bytes for the IO dump circular buffer (5 seconds worth of audio by default) */ +#define FTDM_IO_DUMP_DEFAULT_BUFF_SIZE 8 * 5000 typedef struct { - FILE *file; - char buffer[DTMF_DEBUG_SIZE]; + char *buffer; + ftdm_size_t size; int windex; int wrapped; - int closetimeout; +} ftdm_io_dump_t; + +/* number of interval cycles before timeout and close the debug dtmf file (5 seconds if interval is 20) */ +#define DTMF_DEBUG_TIMEOUT 250 +typedef struct { + uint8_t enabled; + FILE *file; + int32_t closetimeout; ftdm_mutex_t *mutex; } ftdm_dtmf_debug_t; -#endif - typedef struct { const char *file; @@ -471,9 +473,9 @@ struct ftdm_channel { void *user_private; ftdm_timer_id_t hangup_timer; ftdm_channel_iostats_t iostats; -#ifdef FTDM_DEBUG_DTMF ftdm_dtmf_debug_t dtmfdbg; -#endif + ftdm_io_dump_t rxdump; + ftdm_io_dump_t txdump; }; struct ftdm_span { diff --git a/libs/freetdm/src/include/private/ftdm_types.h b/libs/freetdm/src/include/private/ftdm_types.h index f265cb1a3d..db1428c962 100644 --- a/libs/freetdm/src/include/private/ftdm_types.h +++ b/libs/freetdm/src/include/private/ftdm_types.h @@ -58,6 +58,7 @@ typedef int ftdm_filehandle_t; extern "C" { #endif +#define FTDM_COMMAND_OBJ_SIZE *((ftdm_size_t *)obj) #define FTDM_COMMAND_OBJ_INT *((int *)obj) #define FTDM_COMMAND_OBJ_CHAR_P (char *)obj #define FTDM_COMMAND_OBJ_FLOAT *(float *)obj From b156f4d03f6d3a65a59fe7d6f0217fca2c8fdf60 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Fri, 3 Dec 2010 14:13:43 -0500 Subject: [PATCH 2/8] freetdm: do not write to io dump if is not enabled --- libs/freetdm/src/ftdm_io.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index c43d694dee..495be78ff1 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -91,6 +91,10 @@ static void write_chan_io_dump(ftdm_channel_t *fchan, ftdm_io_dump_t *dump, char int windex = dump->windex; int avail = dump->size - windex; + if (!dump->buffer) { + return; + } + if (dlen > avail) { int diff = dlen - avail; From 9cf15ac04b6f47ced2e6be14690301f73bbb76e8 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Fri, 3 Dec 2010 16:50:03 -0500 Subject: [PATCH 3/8] freetdm: add MF dumping support to ftmod_r2 improve sample configuration documentation for MFC-R2 --- libs/freetdm/conf/freetdm.conf | 14 ++ libs/freetdm/conf/freetdm.conf.xml | 256 +++++++++++++++++---- libs/freetdm/src/ftdm_io.c | 33 ++- libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c | 108 ++++++--- 4 files changed, 331 insertions(+), 80 deletions(-) diff --git a/libs/freetdm/conf/freetdm.conf b/libs/freetdm/conf/freetdm.conf index bbaf1e3687..a657320448 100644 --- a/libs/freetdm/conf/freetdm.conf +++ b/libs/freetdm/conf/freetdm.conf @@ -45,3 +45,17 @@ fxs-channel => 1 number => 2 fxo-channel => 3 +; MFC-R2 typical span configuration + +; MFC-R2 with wanpipe (Sangoma) +[span wanpipe myWanpipeSpan] +trunk_type => E1 +cas-channel => 1-15:1101 +cas-channel => 17-31:1101 + +; MFC-R2 with Zaptel/DAHDI +[span zt myWanpipeSpan] +trunk_type => E1 +cas-channel => 1-15:1101 +cas-channel => 17-31:1101 + diff --git a/libs/freetdm/conf/freetdm.conf.xml b/libs/freetdm/conf/freetdm.conf.xml index 986074dffb..63a3ea62cd 100644 --- a/libs/freetdm/conf/freetdm.conf.xml +++ b/libs/freetdm/conf/freetdm.conf.xml @@ -1,52 +1,220 @@ + - - - - - - + + + + + + + - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index c43d694dee..d2ad2498a0 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -91,6 +91,10 @@ static void write_chan_io_dump(ftdm_channel_t *fchan, ftdm_io_dump_t *dump, char int windex = dump->windex; int avail = dump->size - windex; + if (!dump->buffer) { + return; + } + if (dlen > avail) { int diff = dlen - avail; @@ -101,7 +105,7 @@ static void write_chan_io_dump(ftdm_channel_t *fchan, ftdm_io_dump_t *dump, char memcpy(&dump->buffer[0], &dataptr[avail], diff); windex = diff; - ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "wrapping around dump buffer %p up to index %d\n\n", dump, windex); + /*ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "wrapping around dump buffer %p up to index %d\n\n", dump, windex);*/ dump->wrapped = 1; } else { memcpy(&dump->buffer[windex], dataptr, dlen); @@ -109,7 +113,7 @@ static void write_chan_io_dump(ftdm_channel_t *fchan, ftdm_io_dump_t *dump, char } if (windex == dump->size) { - ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "wrapping around dump buffer %p\n", dump); + /*ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "wrapping around dump buffer %p\n", dump);*/ windex = 0; dump->wrapped = 1; } @@ -2525,7 +2529,6 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_done(ftdm_channel_t *ftdmchan) ftdm_buffer_destroy(&ftdmchan->pre_buffer); ftdmchan->pre_buffer_size = 0; ftdm_mutex_unlock(ftdmchan->pre_buffer_mutex); - disable_dtmf_debug(ftdmchan); ftdm_channel_clear_vars(ftdmchan); if (ftdmchan->hangup_timer) { ftdm_sched_cancel_timer(globals.timingsched, ftdmchan->hangup_timer); @@ -2534,8 +2537,9 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_done(ftdm_channel_t *ftdmchan) ftdmchan->init_state = FTDM_CHANNEL_STATE_DOWN; ftdmchan->state = FTDM_CHANNEL_STATE_DOWN; - stop_chan_io_dump(&ftdmchan->txdump); - stop_chan_io_dump(&ftdmchan->rxdump); + ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_INPUT_DUMP, NULL); + ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_OUTPUT_DUMP, NULL); + ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_DEBUG_DTMF, NULL); if (FTDM_IS_VOICE_CHANNEL(ftdmchan)) { ftdm_sigmsg_t sigmsg; @@ -2741,6 +2745,10 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co case FTDM_COMMAND_ENABLE_INPUT_DUMP: { ftdm_size_t size = obj ? FTDM_COMMAND_OBJ_SIZE : FTDM_IO_DUMP_DEFAULT_BUFF_SIZE; + if (ftdmchan->rxdump.buffer) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Input dump is already enabled\n"); + GOTO_STATUS(done, FTDM_FAIL); + } if (start_chan_io_dump(ftdmchan, &ftdmchan->rxdump, size)) { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Failed to enable input dump\n"); GOTO_STATUS(done, FTDM_FAIL); @@ -2753,6 +2761,10 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co /*!< Stop dumping all input to a circular buffer. */ case FTDM_COMMAND_DISABLE_INPUT_DUMP: { + if (!ftdmchan->rxdump.buffer) { + 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); stop_chan_io_dump(&ftdmchan->rxdump); GOTO_STATUS(done, FTDM_SUCCESS); @@ -2763,6 +2775,10 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co case FTDM_COMMAND_ENABLE_OUTPUT_DUMP: { ftdm_size_t size = obj ? FTDM_COMMAND_OBJ_SIZE : FTDM_IO_DUMP_DEFAULT_BUFF_SIZE; + if (ftdmchan->txdump.buffer) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Output dump is already enabled\n"); + GOTO_STATUS(done, FTDM_FAIL); + } if (start_chan_io_dump(ftdmchan, &ftdmchan->txdump, size)) { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Failed to enable output dump\n"); GOTO_STATUS(done, FTDM_FAIL); @@ -2775,6 +2791,10 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co /*!< Stop dumping all output to a circular buffer. */ case FTDM_COMMAND_DISABLE_OUTPUT_DUMP: { + if (!ftdmchan->txdump.buffer) { + 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); stop_chan_io_dump(&ftdmchan->txdump); GOTO_STATUS(done, FTDM_SUCCESS); @@ -3349,12 +3369,13 @@ skipdebug: static FIO_WRITE_FUNCTION(ftdm_raw_write) { + int dlen = (int) *datalen; if (ftdmchan->fds[FTDM_WRITE_TRACE_INDEX] > -1) { - int dlen = (int) *datalen; 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); } } + write_chan_io_dump(ftdmchan, &ftdmchan->txdump, data, dlen); return ftdmchan->fio->write(ftdmchan, data, datalen); } diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index 5a36f05e8e..9ece036245 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -68,6 +68,7 @@ typedef struct ftdm_r2_call_t { ftdm_channel_state_t chanstate; ftdm_size_t dnis_index; ftdm_size_t ani_index; + char logname[255]; char name[10]; unsigned long txdrops; } ftdm_r2_call_t; @@ -88,13 +89,13 @@ typedef struct ft_r2_conf_s { int32_t max_dnis; int32_t mfback_timeout; int32_t metering_pulse_timeout; + int32_t mf_dump_size; /* booleans */ int immediate_accept; int skip_category; int get_ani_first; int call_files; - int mf_files; int double_answer; int charge_calls; int forced_release; @@ -117,6 +118,8 @@ typedef struct ftdm_r2_data_s { int forced_release:1; /* whether accept the call when offered, or wait until the user decides to accept */ int accept_on_offer:1; + /* Size of multi-frequency (or any media) dumps used during protocol errors */ + int32_t mf_dump_size; /* max time spent in ms doing real work in a single loop */ int32_t jobmax; /* Total number of loops performed so far */ @@ -125,6 +128,8 @@ typedef struct ftdm_r2_data_s { uint64_t loops[11]; /* LWP */ uint32_t monitor_thread_id; + /* Logging directory */ + char logdir[512]; } ftdm_r2_data_t; /* one element per span will be stored in g_mod_data_hash global var to keep track of them @@ -409,10 +414,11 @@ static FIO_CHANNEL_GET_SIG_STATUS_FUNCTION(ftdm_r2_get_channel_sig_status) } /* always called from the monitor thread */ -static void ftdm_r2_on_call_init(openr2_chan_t *r2chan) +static void ftdm_r2_on_call_init(openr2_chan_t *r2chan, const char *logname) { ftdm_r2_call_t *r2call; 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, "Received request to start call\n"); @@ -441,12 +447,16 @@ static void ftdm_r2_on_call_init(openr2_chan_t *r2chan) ft_r2_clean_call(ftdmchan->call_data); r2call = R2CALL(ftdmchan); - if (ftdmchan->state == FTDM_CHANNEL_STATE_DOWN) { - R2CALL(ftdmchan)->chanstate = FTDM_CHANNEL_STATE_DOWN; - } else { - R2CALL(ftdmchan)->chanstate = FTDM_CHANNEL_STATE_DIALING; + snprintf(r2call->logname, sizeof(r2call->logname), "%s", logname); + ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Set logname for call to %s\n", r2call->logname); + + /* start io dump */ + if (r2data->mf_dump_size) { + ftdm_channel_command(ftdmchan, FTDM_COMMAND_ENABLE_INPUT_DUMP, &r2data->mf_dump_size); + ftdm_channel_command(ftdmchan, FTDM_COMMAND_ENABLE_OUTPUT_DUMP, &r2data->mf_dump_size); } + R2CALL(ftdmchan)->chanstate = FTDM_CHANNEL_STATE_DOWN; ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_COLLECT); } @@ -484,6 +494,32 @@ static void clear_accept_pending(ftdm_channel_t *fchan) } } +static void dump_mf(openr2_chan_t *r2chan) +{ + char dfile[512]; + FILE *f = NULL; + ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan); + ftdm_r2_data_t *r2data = ftdmchan->span->signal_data; + if (r2data->mf_dump_size) { + char *logname = R2CALL(ftdmchan)->logname; + + 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"); + 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"); + 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); + } +} + 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); @@ -493,6 +529,7 @@ static void ftdm_r2_on_call_accepted(openr2_chan_t *r2chan, openr2_call_mode_t m /* at this point the MF signaling has ended and there is no point on keep reading */ openr2_chan_disable_read(r2chan); + R2CALL(ftdmchan)->accepted = 1; if (OR2_DIR_BACKWARD == openr2_chan_get_direction(r2chan)) { @@ -579,7 +616,7 @@ static void ftdm_r2_on_protocol_error(openr2_chan_t *r2chan, openr2_protocol_err return; } - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Protocol error\n"); + dump_mf(r2chan); clear_accept_pending(ftdmchan); @@ -1042,24 +1079,28 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_r2_configure_span_signaling) /* .variant */ OR2_VAR_ITU, /* .category */ OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER, /* .loglevel */ OR2_LOG_ERROR | OR2_LOG_WARNING, - /* .logdir */ (char *)"/usr/local/freeswitch/log/", /* FIXME: get PREFIX variable */ +#ifdef WIN32 + /* .logdir */ (char *)"c:\\", +#else + /* .logdir */ (char *)"/tmp", +#endif /* .advanced_protocol_file */ NULL, /* .max_ani */ 10, /* .max_dnis */ 4, /* .mfback_timeout */ -1, /* .metering_pulse_timeout */ -1, + /* .mf_dump_size */ 0, /* .immediate_accept */ -1, /* .skip_category */ -1, /* .get_ani_first */ -1, /* .call_files */ 0, - /* .mf_files */ 0, /* .double_answer */ -1, /* .charge_calls */ -1, /* .forced_release */ -1, /* .allow_collect_calls */ -1 }; - assert(sig_cb != NULL); + ftdm_assert_return(sig_cb != NULL, FTDM_FAIL, "No signaling cb provided\n"); if (span->signal_type) { snprintf(span->last_error, sizeof(span->last_error), "Span is already configured for signalling."); @@ -1119,6 +1160,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_r2_configure_span_signaling) continue; } log_level = val; + ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %s with loglevel %s\n", span->name, val); } else if (!strcasecmp(var, "advanced_protocol_file")) { if (!val) { break; @@ -1128,46 +1170,51 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_r2_configure_span_signaling) continue; } r2conf.advanced_protocol_file = (char *)val; - ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %d with advanced protocol file %s\n", span->span_id, val); + ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %s with advanced protocol file %s\n", span->name, val); + } else if (!strcasecmp(var, "mf_dump_size")) { + r2conf.mf_dump_size = atoi(val); + if (r2conf.mf_dump_size < 0) { + r2conf.mf_dump_size = FTDM_IO_DUMP_DEFAULT_BUFF_SIZE; + ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %s with default mf_dumps = %d bytes\n", span->name, r2conf.mf_dump_size); + } else { + ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %s with mf_dump_size = %d bytes\n", span->name, r2conf.mf_dump_size); + } } else if (!strcasecmp(var, "allow_collect_calls")) { r2conf.allow_collect_calls = ftdm_true(val); - ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %d with allow collect calls max ani = %d\n", span->span_id, r2conf.allow_collect_calls); + ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %s with allow collect calls max ani = %d\n", span->name, r2conf.allow_collect_calls); } else if (!strcasecmp(var, "double_answer")) { r2conf.double_answer = ftdm_true(val); - ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %d with double answer = %d\n", span->span_id, r2conf.double_answer); + ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %s with double answer = %d\n", span->name, r2conf.double_answer); } else if (!strcasecmp(var, "immediate_accept")) { r2conf.immediate_accept = ftdm_true(val); - ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %d with immediate accept = %d\n", span->span_id, r2conf.immediate_accept); + ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %s with immediate accept = %d\n", span->name, r2conf.immediate_accept); } else if (!strcasecmp(var, "skip_category")) { r2conf.skip_category = ftdm_true(val); - ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %d with skip category = %d\n", span->span_id, r2conf.skip_category); + ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %s with skip category = %d\n", span->name, r2conf.skip_category); } else if (!strcasecmp(var, "forced_release")) { r2conf.forced_release = ftdm_true(val); - ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %d with forced release = %d\n", span->span_id, r2conf.forced_release); + ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %s with forced release = %d\n", span->name, r2conf.forced_release); } else if (!strcasecmp(var, "charge_calls")) { r2conf.charge_calls = ftdm_true(val); - ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %d with charge calls = %d\n", span->span_id, r2conf.charge_calls); + ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %s with charge calls = %d\n", span->name, r2conf.charge_calls); } else if (!strcasecmp(var, "get_ani_first")) { r2conf.get_ani_first = ftdm_true(val); - ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %d with get ani first = %d\n", span->span_id, r2conf.get_ani_first); + ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %s with get ani first = %d\n", span->name, r2conf.get_ani_first); } else if (!strcasecmp(var, "call_files")) { r2conf.call_files = ftdm_true(val); - ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %d with call files = %d\n", span->span_id, r2conf.call_files); - } else if (!strcasecmp(var, "mf_files")) { - r2conf.mf_files = ftdm_true(val); - ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %d with mf files = %d\n", span->span_id, r2conf.mf_files); + ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %s with call files = %d\n", span->name, r2conf.call_files); } else if (!strcasecmp(var, "mfback_timeout")) { r2conf.mfback_timeout = atoi(val); - ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %d with MF backward timeout = %dms\n", span->span_id, r2conf.mfback_timeout); + ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %s with MF backward timeout = %dms\n", span->name, r2conf.mfback_timeout); } else if (!strcasecmp(var, "metering_pulse_timeout")) { r2conf.metering_pulse_timeout = atoi(val); - ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %d with metering pulse timeout = %dms\n", span->span_id, r2conf.metering_pulse_timeout); + ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %s with metering pulse timeout = %dms\n", span->name, r2conf.metering_pulse_timeout); } else if (!strcasecmp(var, "max_ani")) { r2conf.max_ani = atoi(val); - ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %d with max ani = %d\n", span->span_id, r2conf.max_ani); + ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %s with max ani = %d\n", span->name, r2conf.max_ani); } else if (!strcasecmp(var, "max_dnis")) { r2conf.max_dnis = atoi(val); - ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %d with max dnis = %d\n", span->span_id, r2conf.max_dnis); + ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %s with max dnis = %d\n", span->name, r2conf.max_dnis); } else { snprintf(span->last_error, sizeof(span->last_error), "Unknown R2 parameter [%s]", var); return FTDM_FAIL; @@ -1211,10 +1258,10 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_r2_configure_span_signaling) openr2_context_set_double_answer(r2data->r2context, r2conf.double_answer); openr2_context_set_immediate_accept(r2data->r2context, r2conf.immediate_accept); - if (r2conf.logdir && r2conf.logdir[0]) { - ftdm_log(FTDM_LOG_DEBUG, "Setting openr2 for span %s logdir to %s\n", span->name, r2conf.logdir); - openr2_context_set_log_directory(r2data->r2context, r2conf.logdir); - } + ftdm_log(FTDM_LOG_DEBUG, "Setting span %s logdir to %s\n", span->name, r2conf.logdir); + openr2_context_set_log_directory(r2data->r2context, r2conf.logdir); + snprintf(r2data->logdir, sizeof(r2data->logdir), "%s", r2conf.logdir); + if (r2conf.advanced_protocol_file) { openr2_context_configure_from_advanced_file(r2data->r2context, r2conf.advanced_protocol_file); } @@ -1252,6 +1299,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_r2_configure_span_signaling) hashtable_insert(spanpvt->r2calls, (void *)r2call->name, r2call, HASHTABLE_FLAG_FREE_VALUE); } + r2data->mf_dump_size = r2conf.mf_dump_size; r2data->flags = 0; spanpvt->r2context = r2data->r2context; From 50f2686fa1532158cb12d8b8f60dc04060f7ac53 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Fri, 3 Dec 2010 17:52:10 -0500 Subject: [PATCH 4/8] freetdm: Add FTDM_COMMANDs to debug DTMF --- libs/freetdm/conf/freetdm.conf | 12 ++++++ libs/freetdm/mod_freetdm/mod_freetdm.c | 43 +++++++++++--------- libs/freetdm/src/ftdm_io.c | 27 ++++++++++-- libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c | 8 +++- libs/freetdm/src/include/freetdm.h | 1 + libs/freetdm/src/include/private/ftdm_core.h | 1 + 6 files changed, 68 insertions(+), 24 deletions(-) diff --git a/libs/freetdm/conf/freetdm.conf b/libs/freetdm/conf/freetdm.conf index a657320448..2f9643dedd 100644 --- a/libs/freetdm/conf/freetdm.conf +++ b/libs/freetdm/conf/freetdm.conf @@ -59,3 +59,15 @@ trunk_type => E1 cas-channel => 1-15:1101 cas-channel => 17-31:1101 +; generic channel parameters +; this parameters are accepted by any type of span/channel +; remember that for generic channel parameters only channels +; below the parameter within the span will be affected + +; Channel audio gain +; rxgain => 0.0 +; txgain => 0.0 + +; Whether to perform media dumps for DTMF debugging +; debugdtmf => yes + diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index 13a165433a..ca16e8bc71 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -1417,6 +1417,24 @@ fail: } +static void ftdm_enable_channel_dtmf(ftdm_channel_t *fchan, switch_channel_t *channel) +{ + if (channel) { + const char *var; + if ((var = switch_channel_get_variable(channel, "freetdm_disable_dtmf"))) { + if (switch_true(var)) { + ftdm_channel_command(fchan, FTDM_COMMAND_DISABLE_DTMF_DETECT, NULL); + ftdm_log(FTDM_LOG_INFO, "DTMF detection disabled in channel %d:%d\n", ftdm_channel_get_span_id(fchan), ftdm_channel_get_id(fchan)); + return; + } + } + /* the variable is not present or has a negative value then proceed to enable DTMF ... */ + } + if (ftdm_channel_command(fchan, FTDM_COMMAND_ENABLE_DTMF_DETECT, NULL) != FTDM_SUCCESS) { + ftdm_log(FTDM_LOG_ERROR, "Failed to enable DTMF detection in channel %d:%d\n", ftdm_channel_get_span_id(fchan), ftdm_channel_get_id(fchan)); + } +} + ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session_t **sp) { switch_core_session_t *session = NULL; @@ -1440,6 +1458,9 @@ ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session return FTDM_FAIL; } + /* I guess we always want DTMF detection */ + ftdm_enable_channel_dtmf(sigmsg->channel, NULL); + switch_core_session_add_stream(session, NULL); tech_pvt = (private_t *) switch_core_session_alloc(session, sizeof(private_t)); @@ -1633,24 +1654,6 @@ static FIO_SIGNAL_CB_FUNCTION(on_common_signal) return FTDM_BREAK; } -static void ftdm_enable_channel_dtmf(ftdm_channel_t *fchan, switch_channel_t *channel) -{ - if (channel) { - const char *var; - if ((var = switch_channel_get_variable(channel, "freetdm_disable_dtmf"))) { - if (switch_true(var)) { - ftdm_channel_command(fchan, FTDM_COMMAND_DISABLE_DTMF_DETECT, NULL); - ftdm_log(FTDM_LOG_INFO, "DTMF detection disabled in channel %d:%d\n", ftdm_channel_get_span_id(fchan), ftdm_channel_get_id(fchan)); - return; - } - } - /* the variable is not present or has a negative value then proceed to enable DTMF ... */ - } - if (ftdm_channel_command(fchan, FTDM_COMMAND_ENABLE_DTMF_DETECT, NULL) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "Failed to enable DTMF detection in channel %d:%d\n", ftdm_channel_get_span_id(fchan), ftdm_channel_get_id(fchan)); - } -} - static FIO_SIGNAL_CB_FUNCTION(on_fxo_signal) { switch_core_session_t *session = NULL; @@ -2059,6 +2062,8 @@ static FIO_SIGNAL_CB_FUNCTION(on_r2_signal) } break; + case FTDM_SIGEVENT_PROCEED:{} break; + default: { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unhandled event %d from R2 for channel %d:%d\n", @@ -2092,8 +2097,6 @@ static FIO_SIGNAL_CB_FUNCTION(on_clear_channel_signal) { ftdm_channel_add_var(sigmsg->channel, "screening_ind", ftdm_screening2str(caller_data->screen)); ftdm_channel_add_var(sigmsg->channel, "presentation_ind", ftdm_presentation2str(caller_data->pres)); - - ftdm_enable_channel_dtmf(sigmsg->channel, NULL); return ftdm_channel_from_event(sigmsg, &session); } break; diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index d2ad2498a0..52555f1177 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -2537,9 +2537,9 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_done(ftdm_channel_t *ftdmchan) ftdmchan->init_state = FTDM_CHANNEL_STATE_DOWN; ftdmchan->state = FTDM_CHANNEL_STATE_DOWN; + ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_DEBUG_DTMF, NULL); ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_INPUT_DUMP, NULL); ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_OUTPUT_DUMP, NULL); - ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_DEBUG_DTMF, NULL); if (FTDM_IS_VOICE_CHANNEL(ftdmchan)) { ftdm_sigmsg_t sigmsg; @@ -2722,6 +2722,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Failed to enable rx dump for DTMF debugging\n"); } ftdmchan->dtmfdbg.enabled = 1; + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Enabled DTMF debugging\n"); GOTO_STATUS(done, FTDM_SUCCESS); } break; @@ -2738,6 +2739,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co GOTO_STATUS(done, FTDM_FAIL); } GOTO_STATUS(done, FTDM_SUCCESS); + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Disabled DTMF debugging\n"); } break; @@ -3295,7 +3297,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_queue_dtmf(ftdm_channel_t *ftdmchan, cons ftdm_assert_return(ftdmchan != NULL, FTDM_FAIL, "No channel\n"); - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Queuing DTMF %s\n", dtmf); + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Queuing DTMF %s (debug = %d)\n", dtmf, ftdmchan->dtmfdbg.enabled); if (!ftdmchan->dtmfdbg.enabled) { goto skipdebug; @@ -3319,6 +3321,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_queue_dtmf(ftdm_channel_t *ftdmchan, cons } else { ftdmchan->dtmfdbg.closetimeout = DTMF_DEBUG_TIMEOUT; ftdm_channel_command(ftdmchan, FTDM_COMMAND_DUMP_INPUT, ftdmchan->dtmfdbg.file); + ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Dumped initial DTMF output to %s\n", dfile); } } else { ftdmchan->dtmfdbg.closetimeout = DTMF_DEBUG_TIMEOUT; @@ -4206,6 +4209,7 @@ static ftdm_status_t ftdm_set_channels_alarms(ftdm_span_t *span, int currindex) FT_DECLARE(ftdm_status_t) ftdm_configure_span_channels(ftdm_span_t *span, const char* str, ftdm_channel_config_t *chan_config, unsigned *configured) { int currindex; + unsigned chan_index = 0; ftdm_assert_return(span != NULL, FTDM_EINVAL, "span is null\n"); ftdm_assert_return(chan_config != NULL, FTDM_EINVAL, "config is null\n"); @@ -4239,6 +4243,14 @@ FT_DECLARE(ftdm_status_t) ftdm_configure_span_channels(ftdm_span_t *span, const return FTDM_FAIL; } + if (chan_config->debugdtmf) { + for (chan_index = currindex+1; chan_index <= span->chan_count; chan_index++) { + if (!FTDM_IS_VOICE_CHANNEL(span->channels[chan_index])) { + continue; + } + span->channels[chan_index]->dtmfdbg.requested = 1; + } + } return FTDM_SUCCESS; } @@ -4257,7 +4269,7 @@ static ftdm_status_t load_config(void) ftdm_channel_config_t chan_config; memset(&chan_config, 0, sizeof(chan_config)); - sprintf(chan_config.group_name,"default"); + sprintf(chan_config.group_name, "__default"); if (!ftdm_config_open_file(&cfg, cfg_name)) { return FTDM_FAIL; @@ -4294,6 +4306,9 @@ static ftdm_status_t load_config(void) if (ftdm_span_create(type, name, &span) == FTDM_SUCCESS) { ftdm_log(FTDM_LOG_DEBUG, "created span %d (%s) of type %s\n", span->span_id, span->name, type); d = 0; + /* it is confusing that parameters from one span affect others, so let's clear them */ + memset(&chan_config, 0, sizeof(chan_config)); + sprintf(chan_config.group_name, "__default"); } else { ftdm_log(FTDM_LOG_CRIT, "failure creating span of type %s\n", type); span = NULL; @@ -4417,6 +4432,9 @@ static ftdm_status_t load_config(void) if (sscanf(val, "%f", &(chan_config.rxgain)) != 1) { ftdm_log(FTDM_LOG_ERROR, "invalid rxgain: '%s'\n", val); } + } else if (!strcasecmp(var, "debugdtmf")) { + chan_config.debugdtmf = ftdm_true(val); + ftdm_log(FTDM_LOG_DEBUG, "Setting debugdtmf to '%s'\n", chan_config.debugdtmf ? "yes" : "no"); } else if (!strcasecmp(var, "group")) { len = strlen(val); if (len >= FTDM_MAX_NAME_STR_SZ) { @@ -5068,6 +5086,9 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t case FTDM_SIGEVENT_START: { ftdm_set_echocancel_call_begin(sigmsg->channel); + if (sigmsg->channel->dtmfdbg.requested) { + ftdm_channel_command(sigmsg->channel, FTDM_COMMAND_ENABLE_DEBUG_DTMF, NULL); + } /* when cleaning up the public API I added this because mod_freetdm.c on_fxs_signal was * doing it during SIGEVENT_START, but now that flags are private they can't, wonder if diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index 9ece036245..b503919396 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -448,7 +448,6 @@ static void ftdm_r2_on_call_init(openr2_chan_t *r2chan, const char *logname) r2call = R2CALL(ftdmchan); snprintf(r2call->logname, sizeof(r2call->logname), "%s", logname); - ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Set logname for call to %s\n", r2call->logname); /* start io dump */ if (r2data->mf_dump_size) { @@ -464,9 +463,16 @@ static void ftdm_r2_on_call_init(openr2_chan_t *r2chan, const char *logname) static void ftdm_r2_on_call_offered(openr2_chan_t *r2chan, const char *ani, const char *dnis, openr2_calling_party_category_t category) { ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan); + ftdm_r2_data_t *r2data = ftdmchan->span->signal_data; ftdm_log_chan(ftdmchan, FTDM_LOG_NOTICE, "Call offered with ANI = %s, DNIS = %s, Category = (%d)\n", ani, dnis, category); ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING); + + /* 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); + } } /* diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h index 76db25c9ae..41e7f50ed8 100644 --- a/libs/freetdm/src/include/freetdm.h +++ b/libs/freetdm/src/include/freetdm.h @@ -351,6 +351,7 @@ typedef struct ftdm_channel_config { ftdm_chan_type_t type; float rxgain; float txgain; + uint8_t debugdtmf; } ftdm_channel_config_t; /*! diff --git a/libs/freetdm/src/include/private/ftdm_core.h b/libs/freetdm/src/include/private/ftdm_core.h index 04458adda1..f1058d8e48 100644 --- a/libs/freetdm/src/include/private/ftdm_core.h +++ b/libs/freetdm/src/include/private/ftdm_core.h @@ -355,6 +355,7 @@ typedef struct { #define DTMF_DEBUG_TIMEOUT 250 typedef struct { uint8_t enabled; + uint8_t requested; FILE *file; int32_t closetimeout; ftdm_mutex_t *mutex; From 6e05e90caf09721a55deccff5f80ae8ad5a78a11 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Fri, 3 Dec 2010 17:54:24 -0500 Subject: [PATCH 5/8] freetdm: reduce log severity --- libs/freetdm/src/ftdm_io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 52555f1177..b70eea7128 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -3321,7 +3321,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_queue_dtmf(ftdm_channel_t *ftdmchan, cons } else { ftdmchan->dtmfdbg.closetimeout = DTMF_DEBUG_TIMEOUT; ftdm_channel_command(ftdmchan, FTDM_COMMAND_DUMP_INPUT, ftdmchan->dtmfdbg.file); - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Dumped initial DTMF output to %s\n", dfile); + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Dumped initial DTMF output to %s\n", dfile); } } else { ftdmchan->dtmfdbg.closetimeout = DTMF_DEBUG_TIMEOUT; From 3284c76150b383ba9b690c8519b75e6a5719cbfd Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Mon, 6 Dec 2010 07:22:16 -0500 Subject: [PATCH 6/8] freetdm: remove DEBUG_DTMF macros from build --- libs/freetdm/Makefile.am | 4 ---- libs/freetdm/configure.ac | 11 ----------- 2 files changed, 15 deletions(-) diff --git a/libs/freetdm/Makefile.am b/libs/freetdm/Makefile.am index bc92e1db58..af26f7f2af 100644 --- a/libs/freetdm/Makefile.am +++ b/libs/freetdm/Makefile.am @@ -55,10 +55,6 @@ COMPILE = $(CC) $(FTDM_CFLAGS) LTCOMPILE = $(LIBTOOL) --mode=compile --tag=CC $(COMPILE) LINK = $(LIBTOOL) --mode=link --tag=CC $(CC) $(FTDM_CFLAGS) $(LDFLAGS) -o $@ -if WANT_DEBUGDTMF -FTDM_CFLAGS += -DFTDM_DEBUG_DTMF -endif - # # GNU pkgconfig file diff --git a/libs/freetdm/configure.ac b/libs/freetdm/configure.ac index 6b9287d791..592dfd82a3 100644 --- a/libs/freetdm/configure.ac +++ b/libs/freetdm/configure.ac @@ -167,17 +167,6 @@ AC_ARG_WITH([pritap], HAVE_PRITAP="${enable_pritap}" AM_CONDITIONAL([HAVE_PRITAP],[test "${enable_pritap}" = "yes"]) -# debug dtmf? -AC_ARG_WITH([debugdtmf], - [AS_HELP_STRING([--with-debugdtmf], [Debug DTMF])], - [case "${withval}" in - no) enable_debugdtmf="no" ;; - *) enable_debugdtmf="yes" ;; - esac], - [enable_debugdtmf="no"] -) -AM_CONDITIONAL([WANT_DEBUGDTMF], [test "${enable_debugdtmf}" = "yes"]) - ## # OpenR2 stack # From c05cae9f0a005a5bf43bbfe131ac5d82338935ee Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Mon, 6 Dec 2010 07:26:04 -0500 Subject: [PATCH 7/8] freetdm: use ftdm_status_t as return code for io dump and debug dtmf functions --- libs/freetdm/src/ftdm_io.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index b70eea7128..1f91463dd9 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -152,19 +152,19 @@ static void stop_chan_io_dump(ftdm_io_dump_t *dump) memset(dump, 0, sizeof(dump)); } -static int start_chan_io_dump(ftdm_channel_t *chan, ftdm_io_dump_t *dump, ftdm_size_t size) +static ftdm_status_t start_chan_io_dump(ftdm_channel_t *chan, ftdm_io_dump_t *dump, ftdm_size_t size) { if (dump->buffer) { ftdm_log_chan_msg(chan, FTDM_LOG_ERROR, "IO dump is already started\n"); - return -1; + return FTDM_FAIL; } memset(dump, 0, sizeof(*dump)); dump->buffer = ftdm_malloc(size); if (!dump->buffer) { - return -1; + return FTDM_FAIL; } dump->size = size; - return 0; + return FTDM_SUCCESS; } @@ -177,21 +177,21 @@ static void close_dtmf_debug_file(ftdm_channel_t *ftdmchan) } } -static int disable_dtmf_debug(ftdm_channel_t *ftdmchan) +static ftdm_status_t disable_dtmf_debug(ftdm_channel_t *ftdmchan) { if (!ftdmchan->dtmfdbg.enabled) { - return 0; + return FTDM_SUCCESS; } if (!ftdmchan->rxdump.buffer) { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "DTMF debug enabled but no rx dump?\n"); - return -1; + return FTDM_FAIL; } close_dtmf_debug_file(ftdmchan); stop_chan_io_dump(&ftdmchan->rxdump); ftdmchan->dtmfdbg.enabled = 0; - return 0; + return FTDM_SUCCESS; } typedef struct { @@ -2718,8 +2718,9 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Cannot debug DTMF if Rx dumping is already enabled\n"); GOTO_STATUS(done, FTDM_FAIL); } - if (start_chan_io_dump(ftdmchan, &ftdmchan->rxdump, FTDM_IO_DUMP_DEFAULT_BUFF_SIZE)) { + if (start_chan_io_dump(ftdmchan, &ftdmchan->rxdump, FTDM_IO_DUMP_DEFAULT_BUFF_SIZE) != FTDM_SUCCESS) { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Failed to enable rx dump for DTMF debugging\n"); + GOTO_STATUS(done, FTDM_FAIL); } ftdmchan->dtmfdbg.enabled = 1; ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Enabled DTMF debugging\n"); @@ -2734,7 +2735,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "DTMF debug is already disabled\n"); GOTO_STATUS(done, FTDM_SUCCESS); } - if (disable_dtmf_debug(ftdmchan)) { + if (disable_dtmf_debug(ftdmchan) != FTDM_SUCCESS) { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Failed to disable DTMF debug\n"); GOTO_STATUS(done, FTDM_FAIL); } @@ -2751,7 +2752,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Input dump is already enabled\n"); GOTO_STATUS(done, FTDM_FAIL); } - if (start_chan_io_dump(ftdmchan, &ftdmchan->rxdump, size)) { + if (start_chan_io_dump(ftdmchan, &ftdmchan->rxdump, size) != FTDM_SUCCESS) { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Failed to enable input dump\n"); GOTO_STATUS(done, FTDM_FAIL); } @@ -2781,7 +2782,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Output dump is already enabled\n"); GOTO_STATUS(done, FTDM_FAIL); } - if (start_chan_io_dump(ftdmchan, &ftdmchan->txdump, size)) { + if (start_chan_io_dump(ftdmchan, &ftdmchan->txdump, size) != FTDM_SUCCESS) { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Failed to enable output dump\n"); GOTO_STATUS(done, FTDM_FAIL); } From e37ce444dddf2764d40c22a35983edb7c55ce94f Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Mon, 6 Dec 2010 07:30:37 -0500 Subject: [PATCH 8/8] freetdm: fix ftmod_r2 debug 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 b503919396..e7e4ad68d3 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -1181,7 +1181,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_r2_configure_span_signaling) r2conf.mf_dump_size = atoi(val); if (r2conf.mf_dump_size < 0) { r2conf.mf_dump_size = FTDM_IO_DUMP_DEFAULT_BUFF_SIZE; - ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %s with default mf_dumps = %d bytes\n", span->name, r2conf.mf_dump_size); + ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %s with default mf_dump_size = %d bytes\n", span->name, r2conf.mf_dump_size); } else { ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %s with mf_dump_size = %d bytes\n", span->name, r2conf.mf_dump_size); }