From 7aa0c3c64bf90bbe32bd9b4f2ee8bf919fb0cdca Mon Sep 17 00:00:00 2001 From: Olle Johansson Date: Wed, 25 Apr 2012 09:32:21 +0000 Subject: [PATCH] Make it possible to change the minimum DTMF duration in asterisk.conf Asterisk has a setting for the minimum allowed DTMF. If we get shorter DTMF tones, these will be changed to the minimum on the outbound call leg. (closes issue ASTERISK-19772) Review: https://reviewboard.asterisk.org/r/1882/ Reported by: oej Tested by: oej Patches by: oej Thanks to the reviewers. 1.8 branch for this patch: agave-dtmf-duration-asterisk-conf-1.8 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@363558 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- CHANGES | 3 +++ configs/asterisk.conf.sample | 3 +++ include/asterisk/options.h | 1 + main/asterisk.c | 13 +++++++++++++ main/channel.c | 23 ++++++++++------------- 5 files changed, 30 insertions(+), 13 deletions(-) diff --git a/CHANGES b/CHANGES index 067bd6cbff..1887148c34 100644 --- a/CHANGES +++ b/CHANGES @@ -27,6 +27,9 @@ Core added to any log messages produced by those threads. Log messages can now be easily identified as involved with a certain call by looking at their call id. This feature can be disabled in logger.conf with the display_callids option. + * The minimum DTMF duration can now be configured in asterisk.conf + as "mindtmfduration". The default value is (as before) set to 80 ms. + (previously it was only available in source code) CLI Changes ------------------- diff --git a/configs/asterisk.conf.sample b/configs/asterisk.conf.sample index 44f3c1deae..404ea30dee 100644 --- a/configs/asterisk.conf.sample +++ b/configs/asterisk.conf.sample @@ -34,6 +34,9 @@ astsbindir => /usr/sbin ;autosystemname = yes ; Automatically set systemname to hostname, ; uses 'localhost' on failure, or systemname if ; set. +;mindtmfduration = 80 ; Set minimum DTMF duration in ms (default 80 ms) + ; If we get shorter DTMF messages, these will be + ; changed to the minimum duration ;maxcalls = 10 ; Maximum amount of calls allowed. ;maxload = 0.9 ; Asterisk stops accepting new calls if the ; load average exceed this limit. diff --git a/include/asterisk/options.h b/include/asterisk/options.h index c411b3aade..73fa42bcec 100644 --- a/include/asterisk/options.h +++ b/include/asterisk/options.h @@ -157,6 +157,7 @@ extern int option_verbose; extern int option_maxfiles; /*!< Max number of open file handles (files, sockets) */ extern int option_debug; /*!< Debugging */ extern int option_maxcalls; /*!< Maximum number of simultaneous channels */ +extern unsigned int option_dtmfminduration; /*!< Minimum duration of DTMF (channel.c) in ms */ extern double option_maxload; #if defined(HAVE_SYSINFO) extern long option_minmemfree; /*!< Minimum amount of free system memory - stop accepting calls if free memory falls below this watermark */ diff --git a/main/asterisk.c b/main/asterisk.c index 31ce709db4..4eed6f2430 100644 --- a/main/asterisk.c +++ b/main/asterisk.c @@ -157,6 +157,10 @@ int daemon(int, int); /* defined in libresolv of all places */ #define AST_MAX_CONNECTS 128 #define NUM_MSGS 64 +/*! Default minimum DTMF digit length - 80ms */ +#define AST_MIN_DTMF_DURATION 80 + + /*! \brief Welcome message when starting a CLI interface */ #define WELCOME_MESSAGE \ ast_verbose("Asterisk %s, Copyright (C) 1999 - 2012 Digium, Inc. and others.\n" \ @@ -182,6 +186,7 @@ int option_debug; /*!< Debug level */ double option_maxload; /*!< Max load avg on system */ int option_maxcalls; /*!< Max number of active calls */ int option_maxfiles; /*!< Max number of open file handles (files, sockets) */ +unsigned int option_dtmfminduration; /*!< Minimum duration of DTMF. */ #if defined(HAVE_SYSINFO) long option_minmemfree; /*!< Minimum amount of free system memory - stop accepting calls if free memory falls below this watermark */ #endif @@ -487,6 +492,7 @@ static char *handle_show_settings(struct ast_cli_entry *e, int cmd, struct ast_c ast_cli(a->fd, " Internal timing: %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_INTERNAL_TIMING) ? "Enabled" : "Disabled"); ast_cli(a->fd, " Transmit silence during rec: %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_TRANSMIT_SILENCE) ? "Enabled" : "Disabled"); ast_cli(a->fd, " Generic PLC: %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_GENERIC_PLC) ? "Enabled" : "Disabled"); + ast_cli(a->fd, " Min DTMF duration:: %u\n", option_dtmfminduration); ast_cli(a->fd, "\n* Subsystems\n"); ast_cli(a->fd, " -------------\n"); @@ -3057,6 +3063,9 @@ static void ast_readconfig(void) unsigned int keydir:1; } found = { 0, 0 }; + /* Set default value */ + option_dtmfminduration = AST_MIN_DTMF_DURATION; + if (ast_opt_override_config) { cfg = ast_config_load2(ast_config_AST_CONFIG_FILE, "" /* core, can't reload */, config_flags); if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) @@ -3193,6 +3202,10 @@ static void ast_readconfig(void) /* Enable internal timing */ } else if (!strcasecmp(v->name, "internal_timing")) { ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_INTERNAL_TIMING); + } else if (!strcasecmp(v->name, "mindtmfduration")) { + if (sscanf(v->value, "%30u", &option_dtmfminduration) != 1) { + option_dtmfminduration = AST_MIN_DTMF_DURATION; + } } else if (!strcasecmp(v->name, "maxcalls")) { if ((sscanf(v->value, "%30d", &option_maxcalls) != 1) || (option_maxcalls < 0)) { option_maxcalls = 0; diff --git a/main/channel.c b/main/channel.c index 7428dee5ae..373d6045de 100644 --- a/main/channel.c +++ b/main/channel.c @@ -104,9 +104,6 @@ AST_THREADSTORAGE(state2str_threadbuf); * 100ms */ #define AST_DEFAULT_EMULATE_DTMF_DURATION 100 -/*! Minimum allowed digit length - 80ms */ -#define AST_MIN_DTMF_DURATION 80 - /*! Minimum amount of time between the end of the last digit and the beginning * of a new one - 45ms */ #define AST_MIN_DTMF_GAP 45 @@ -3868,10 +3865,10 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio) ast_channel_dtmf_digit_to_emulate_set(chan, f->subclass.integer); ast_channel_dtmf_tv_set(chan, &tv); if (f->len) { - if (f->len > AST_MIN_DTMF_DURATION) + if (f->len > option_dtmfminduration) ast_channel_emulate_dtmf_duration_set(chan, f->len); else - ast_channel_emulate_dtmf_duration_set(chan, AST_MIN_DTMF_DURATION); + ast_channel_emulate_dtmf_duration_set(chan, option_dtmfminduration); } else ast_channel_emulate_dtmf_duration_set(chan, AST_DEFAULT_EMULATE_DTMF_DURATION); ast_log(LOG_DTMF, "DTMF begin emulation of '%c' with duration %u queued on %s\n", f->subclass.integer, ast_channel_emulate_dtmf_duration(chan), ast_channel_name(chan)); @@ -3895,31 +3892,31 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio) /* detect tones that were received on * the wire with durations shorter than - * AST_MIN_DTMF_DURATION and set f->len + * option_dtmfminduration and set f->len * to the actual duration of the DTMF * frames on the wire. This will cause * dtmf emulation to be triggered later * on. */ - if (ast_tvdiff_ms(now, *ast_channel_dtmf_tv(chan)) < AST_MIN_DTMF_DURATION) { + if (ast_tvdiff_ms(now, *ast_channel_dtmf_tv(chan)) < option_dtmfminduration) { f->len = ast_tvdiff_ms(now, *ast_channel_dtmf_tv(chan)); ast_log(LOG_DTMF, "DTMF end '%c' detected to have actual duration %ld on the wire, emulation will be triggered on %s\n", f->subclass.integer, f->len, ast_channel_name(chan)); } } else if (!f->len) { ast_log(LOG_DTMF, "DTMF end accepted without begin '%c' on %s\n", f->subclass.integer, ast_channel_name(chan)); - f->len = AST_MIN_DTMF_DURATION; + f->len = option_dtmfminduration; } - if (f->len < AST_MIN_DTMF_DURATION && !ast_test_flag(ast_channel_flags(chan), AST_FLAG_END_DTMF_ONLY)) { - ast_log(LOG_DTMF, "DTMF end '%c' has duration %ld but want minimum %d, emulating on %s\n", f->subclass.integer, f->len, AST_MIN_DTMF_DURATION, ast_channel_name(chan)); + if (f->len < option_dtmfminduration && !ast_test_flag(ast_channel_flags(chan), AST_FLAG_END_DTMF_ONLY)) { + ast_log(LOG_DTMF, "DTMF end '%c' has duration %ld but want minimum %d, emulating on %s\n", f->subclass.integer, f->len, option_dtmfminduration, ast_channel_name(chan)); ast_set_flag(ast_channel_flags(chan), AST_FLAG_EMULATE_DTMF); ast_channel_dtmf_digit_to_emulate_set(chan, f->subclass.integer); - ast_channel_emulate_dtmf_duration_set(chan, AST_MIN_DTMF_DURATION - f->len); + ast_channel_emulate_dtmf_duration_set(chan, option_dtmfminduration - f->len); ast_frfree(f); f = &ast_null_frame; } else { ast_log(LOG_DTMF, "DTMF end passthrough '%c' on %s\n", f->subclass.integer, ast_channel_name(chan)); - if (f->len < AST_MIN_DTMF_DURATION) { - f->len = AST_MIN_DTMF_DURATION; + if (f->len < option_dtmfminduration) { + f->len = option_dtmfminduration; } ast_channel_dtmf_tv_set(chan, &now); }