Index: b/include/asterisk/options.h
===================================================================
--- a/include/asterisk/options.h
+++ b/include/asterisk/options.h
@@ -191,6 +191,9 @@ extern int option_debug;		/*!< Debugging
 extern int option_trace;		/*!< Debugging */
 extern int ast_option_maxcalls;		/*!< Maximum number of simultaneous channels */
 extern unsigned int option_dtmfminduration;	/*!< Minimum duration of DTMF (channel.c) in ms */
+extern unsigned int option_dtmfmaxduration;	/*!< Maximum duration of DTMF (channel.c) in ms */
+
+
 extern double ast_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: b/main/channel.c
===================================================================
--- a/main/channel.c
+++ b/main/channel.c
@@ -3929,10 +3929,13 @@ static struct ast_frame *__ast_read(stru
 					ast_channel_dtmf_digit_to_emulate_set(chan, f->subclass.integer);
 					ast_channel_dtmf_tv_set(chan, &tv);
 					if (f->len) {
-						if (f->len > option_dtmfminduration)
-							ast_channel_emulate_dtmf_duration_set(chan, f->len);
-						else
+						if (f->len < option_dtmfminduration) {
 							ast_channel_emulate_dtmf_duration_set(chan, option_dtmfminduration);
+						} else if (f->len > option_dtmfmaxduration) {
+							ast_channel_emulate_dtmf_duration_set(chan, option_dtmfmaxduration);
+						} else {
+							ast_channel_emulate_dtmf_duration_set(chan, f->len);
+						}
 					} 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));
Index: b/configs/samples/asterisk.conf.sample
===================================================================
--- a/configs/samples/asterisk.conf.sample
+++ b/configs/samples/asterisk.conf.sample
@@ -39,6 +39,12 @@ astsbindir => /usr/sbin
 ;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
+;maxdtmfduration = 2000	; Set maximum DTMF duration in ms (default 2000 ms)
+				; If we receive DTMF packet (INFO or RTP) requiring
+				; longer DTMF signal, signal length is shortened to
+				; this length
+				; If set lower than mindtmfduration, it is corrected
+				; to mindtmfduration value
 ;maxcalls = 10			; Maximum amount of calls allowed.
 ;maxload = 0.9			; Asterisk stops accepting new calls if the
 				; load average exceed this limit.
Index: b/main/options.c
===================================================================
--- a/main/options.c
+++ b/main/options.c
@@ -48,6 +48,8 @@
 /*! Default minimum DTMF digit length - 80ms */
 #define AST_MIN_DTMF_DURATION 80
 
+/*! Default maximum DTMF digit length - 2000ms */
+#define AST_MAX_DTMF_DURATION 2000
 #define DEFAULT_MONITOR_DIR DEFAULT_SPOOL_DIR "/monitor"
 #define DEFAULT_RECORDING_DIR DEFAULT_SPOOL_DIR "/recording"
 
@@ -81,6 +83,8 @@ int ast_option_maxcalls;
 int ast_option_maxfiles;
 /*! Minimum duration of DTMF. */
 unsigned int option_dtmfminduration = AST_MIN_DTMF_DURATION;
+/*! Maximum duration of DTMF. */
+unsigned int option_dtmfmaxduration = AST_MAX_DTMF_DURATION;
 #if defined(HAVE_SYSINFO)
 /*! Minimum amount of free system memory - stop accepting calls if free memory falls below this watermark */
 long option_minmemfree;
@@ -381,6 +385,10 @@ void load_asterisk_conf(void)
 		} else if (!strcasecmp(v->name, "rtp_pt_dynamic")) {
 			ast_parse_arg(v->value, PARSE_UINT32|PARSE_IN_RANGE,
 			              &ast_option_rtpptdynamic, 0, AST_RTP_PT_FIRST_DYNAMIC);
+		} else if (!strcasecmp(v->name, "maxdtmfduration")) {
+			if (sscanf(v->value, "%30u", &option_dtmfmaxduration) != 1) {
+				option_dtmfmaxduration = AST_MAX_DTMF_DURATION;
+			}
 		} else if (!strcasecmp(v->name, "maxcalls")) {
 			if ((sscanf(v->value, "%30d", &ast_option_maxcalls) != 1) || (ast_option_maxcalls < 0)) {
 				ast_option_maxcalls = 0;
@@ -476,6 +484,11 @@ void load_asterisk_conf(void)
 			ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_SOUNDS_SEARCH_CUSTOM);
 		}
 	}
+
+	if (option_dtmfmaxduration < option_dtmfminduration) {
+		option_dtmfmaxduration = option_dtmfminduration;
+	}
+
 	if (!ast_opt_remote) {
 		pbx_live_dangerously(live_dangerously);
 		astman_live_dangerously(live_dangerously);
Index: b/main/asterisk.c
===================================================================
--- a/main/asterisk.c
+++ b/main/asterisk.c
@@ -561,6 +561,7 @@ static char *handle_show_settings(struct
 	ast_cli(a->fd, "  Hide Msg Chan AMI events:    %s\n", ast_opt_hide_messaging_ami_events ? "Enabled" : "Disabled");
 	ast_cli(a->fd, "  Sounds search custom dir:    %s\n", ast_opt_sounds_search_custom ? "Enabled" : "Disabled");
 	ast_cli(a->fd, "  Min DTMF duration::          %u\n", option_dtmfminduration);
+	ast_cli(a->fd, "  Max DTMF duration::          %u\n", option_dtmfmaxduration);
 #if !defined(LOW_MEMORY)
 	ast_cli(a->fd, "  Cache media frames:          %s\n", ast_opt_cache_media_frames ? "Enabled" : "Disabled");
 #endif
