freetdm: Add FTDM_COMMANDs to debug DTMF

This commit is contained in:
Moises Silva 2010-12-03 17:52:10 -05:00
parent 8b80661e40
commit 50f2686fa1
6 changed files with 68 additions and 24 deletions

View File

@ -59,3 +59,15 @@ trunk_type => E1
cas-channel => 1-15:1101 cas-channel => 1-15:1101
cas-channel => 17-31: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

View File

@ -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) ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session_t **sp)
{ {
switch_core_session_t *session = NULL; 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; return FTDM_FAIL;
} }
/* I guess we always want DTMF detection */
ftdm_enable_channel_dtmf(sigmsg->channel, NULL);
switch_core_session_add_stream(session, NULL); switch_core_session_add_stream(session, NULL);
tech_pvt = (private_t *) switch_core_session_alloc(session, sizeof(private_t)); 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; 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) static FIO_SIGNAL_CB_FUNCTION(on_fxo_signal)
{ {
switch_core_session_t *session = NULL; switch_core_session_t *session = NULL;
@ -2059,6 +2062,8 @@ static FIO_SIGNAL_CB_FUNCTION(on_r2_signal)
} }
break; break;
case FTDM_SIGEVENT_PROCEED:{} break;
default: default:
{ {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unhandled event %d from R2 for channel %d:%d\n", 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, "screening_ind", ftdm_screening2str(caller_data->screen));
ftdm_channel_add_var(sigmsg->channel, "presentation_ind", ftdm_presentation2str(caller_data->pres)); 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); return ftdm_channel_from_event(sigmsg, &session);
} }
break; break;

View File

@ -2537,9 +2537,9 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_done(ftdm_channel_t *ftdmchan)
ftdmchan->init_state = FTDM_CHANNEL_STATE_DOWN; ftdmchan->init_state = FTDM_CHANNEL_STATE_DOWN;
ftdmchan->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_INPUT_DUMP, NULL);
ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_OUTPUT_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)) { if (FTDM_IS_VOICE_CHANNEL(ftdmchan)) {
ftdm_sigmsg_t sigmsg; 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"); ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Failed to enable rx dump for DTMF debugging\n");
} }
ftdmchan->dtmfdbg.enabled = 1; ftdmchan->dtmfdbg.enabled = 1;
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Enabled DTMF debugging\n");
GOTO_STATUS(done, FTDM_SUCCESS); GOTO_STATUS(done, FTDM_SUCCESS);
} }
break; 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_FAIL);
} }
GOTO_STATUS(done, FTDM_SUCCESS); GOTO_STATUS(done, FTDM_SUCCESS);
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Disabled DTMF debugging\n");
} }
break; 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_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) { if (!ftdmchan->dtmfdbg.enabled) {
goto skipdebug; goto skipdebug;
@ -3319,6 +3321,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_queue_dtmf(ftdm_channel_t *ftdmchan, cons
} else { } else {
ftdmchan->dtmfdbg.closetimeout = DTMF_DEBUG_TIMEOUT; ftdmchan->dtmfdbg.closetimeout = DTMF_DEBUG_TIMEOUT;
ftdm_channel_command(ftdmchan, FTDM_COMMAND_DUMP_INPUT, ftdmchan->dtmfdbg.file); 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 { } else {
ftdmchan->dtmfdbg.closetimeout = DTMF_DEBUG_TIMEOUT; 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) 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; int currindex;
unsigned chan_index = 0;
ftdm_assert_return(span != NULL, FTDM_EINVAL, "span is null\n"); ftdm_assert_return(span != NULL, FTDM_EINVAL, "span is null\n");
ftdm_assert_return(chan_config != NULL, FTDM_EINVAL, "config 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; 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; return FTDM_SUCCESS;
} }
@ -4257,7 +4269,7 @@ static ftdm_status_t load_config(void)
ftdm_channel_config_t chan_config; ftdm_channel_config_t chan_config;
memset(&chan_config, 0, sizeof(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)) { if (!ftdm_config_open_file(&cfg, cfg_name)) {
return FTDM_FAIL; return FTDM_FAIL;
@ -4294,6 +4306,9 @@ static ftdm_status_t load_config(void)
if (ftdm_span_create(type, name, &span) == FTDM_SUCCESS) { 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); ftdm_log(FTDM_LOG_DEBUG, "created span %d (%s) of type %s\n", span->span_id, span->name, type);
d = 0; 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 { } else {
ftdm_log(FTDM_LOG_CRIT, "failure creating span of type %s\n", type); ftdm_log(FTDM_LOG_CRIT, "failure creating span of type %s\n", type);
span = NULL; span = NULL;
@ -4417,6 +4432,9 @@ static ftdm_status_t load_config(void)
if (sscanf(val, "%f", &(chan_config.rxgain)) != 1) { if (sscanf(val, "%f", &(chan_config.rxgain)) != 1) {
ftdm_log(FTDM_LOG_ERROR, "invalid rxgain: '%s'\n", val); 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")) { } else if (!strcasecmp(var, "group")) {
len = strlen(val); len = strlen(val);
if (len >= FTDM_MAX_NAME_STR_SZ) { 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: case FTDM_SIGEVENT_START:
{ {
ftdm_set_echocancel_call_begin(sigmsg->channel); 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 /* 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 * doing it during SIGEVENT_START, but now that flags are private they can't, wonder if

View File

@ -448,7 +448,6 @@ static void ftdm_r2_on_call_init(openr2_chan_t *r2chan, const char *logname)
r2call = R2CALL(ftdmchan); r2call = R2CALL(ftdmchan);
snprintf(r2call->logname, sizeof(r2call->logname), "%s", logname); 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 */ /* start io dump */
if (r2data->mf_dump_size) { 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) 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_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_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); 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);
}
} }
/* /*

View File

@ -351,6 +351,7 @@ typedef struct ftdm_channel_config {
ftdm_chan_type_t type; ftdm_chan_type_t type;
float rxgain; float rxgain;
float txgain; float txgain;
uint8_t debugdtmf;
} ftdm_channel_config_t; } ftdm_channel_config_t;
/*! /*!

View File

@ -355,6 +355,7 @@ typedef struct {
#define DTMF_DEBUG_TIMEOUT 250 #define DTMF_DEBUG_TIMEOUT 250
typedef struct { typedef struct {
uint8_t enabled; uint8_t enabled;
uint8_t requested;
FILE *file; FILE *file;
int32_t closetimeout; int32_t closetimeout;
ftdm_mutex_t *mutex; ftdm_mutex_t *mutex;