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;