Make it possible to change the minimum DTMF duration in asterisk.conf
authorOlle Johansson <oej@edvina.net>
Wed, 25 Apr 2012 09:32:21 +0000 (09:32 +0000)
committerOlle Johansson <oej@edvina.net>
Wed, 25 Apr 2012 09:32:21 +0000 (09:32 +0000)
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
configs/asterisk.conf.sample
include/asterisk/options.h
main/asterisk.c
main/channel.c

diff --git a/CHANGES b/CHANGES
index 067bd6c..1887148 100644 (file)
--- 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
 -------------------
index 44f3c1d..404ea30 100644 (file)
@@ -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.
index c411b3a..73fa42b 100644 (file)
@@ -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 */
index 31ce709..4eed6f2 100644 (file)
@@ -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;
index 7428dee..373d604 100644 (file)
@@ -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);
                                }