freetdm: Add FTDM_COMMANDs to debug DTMF
This commit is contained in:
parent
8b80661e40
commit
50f2686fa1
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue