[Asterisk-code-review] chan dahdi: Configurable dialed digit timeouts (asterisk[master])

Joshua Colp asteriskteam at digium.com
Thu May 3 12:07:14 CDT 2018


Joshua Colp has submitted this change and it was merged. ( https://gerrit.asterisk.org/8637 )

Change subject: chan_dahdi: Configurable dialed digit timeouts
......................................................................

chan_dahdi: Configurable dialed digit timeouts

Analog phones dial overlap dialing and it is chan_dahdi's job to read the
numbers.  It has three timeout constants that this commit converts to
channel-level configuration options:

* firstdigit_timeout: Default time (ms) to detect first digit

* interdigit_timeout: Default time (ms) to detect following digits

* matchdigit_timeout: Default time (ms) to wait in case of ambiguous
match.  This happens when the dialed digits match a number in the current
context but are also the prefix of another number.

Change-Id: Ib728fa900a4f6ae56d1ed810aba61b6593fb7213
---
M CHANGES
M UPGRADE.txt
M channels/chan_dahdi.c
M channels/chan_dahdi.h
M channels/sig_analog.c
M channels/sig_analog.h
M configs/samples/chan_dahdi.conf.sample
7 files changed, 118 insertions(+), 29 deletions(-)

Approvals:
  Matthew Fredrickson: Looks good to me, approved
  Joshua Colp: Approved for Submit



diff --git a/CHANGES b/CHANGES
index 19c8f86..7b67f8d 100644
--- a/CHANGES
+++ b/CHANGES
@@ -45,6 +45,11 @@
    headers be retrieved from the REFER message and made accessible to the
    dialplan in the hash TRANSFER_DATA.
 
+chan_dahdi
+------------------
+ * Timeouts for reading digits from analog phones are now configurable in
+   chan_dahdi.conf: firstdigit_timeout, interdigit_timeout, matchdigit_timeout.
+
 AMI
 ------------------
  * The ContactStatus and Status fields for the manager events ContactStatus
diff --git a/UPGRADE.txt b/UPGRADE.txt
index 108c10a..154a9b7 100644
--- a/UPGRADE.txt
+++ b/UPGRADE.txt
@@ -50,6 +50,10 @@
    MALLOC_DEBUG and vice versa.  Third-party pre-compiled modules no longer
    need to have a special build with it enabled.
 
+chan_dahdi:
+ - Timeouts for reading digits from analog phones are now configurable in
+   chan_dahdi.conf: firstdigit_timeout, interdigit_timeout, matchdigit_timeout.
+
 cdr_syslog:
  - The cdr_syslog module is now deprecated and by default it is no longer
    built.
diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c
index 37e2774..7c54cf3 100644
--- a/channels/chan_dahdi.c
+++ b/channels/chan_dahdi.c
@@ -615,15 +615,6 @@
 static char pridebugfilename[1024] = "";
 #endif
 
-/*! \brief Wait up to 16 seconds for first digit (FXO logic) */
-static int firstdigittimeout = 16000;
-
-/*! \brief How long to wait for following digits (FXO logic) */
-static int gendigittimeout = 8000;
-
-/*! \brief How long to wait for an extra digit, if there is an ambiguous match */
-static int matchdigittimeout = 3000;
-
 /*! \brief Protect the interface list (of dahdi_pvt's) */
 AST_MUTEX_DEFINE_STATIC(iflock);
 
@@ -977,6 +968,9 @@
 			.buf_no = numbufs,
 			.usefaxbuffers = 0,
 			.cc_params = ast_cc_config_params_init(),
+			.firstdigit_timeout = ANALOG_FIRST_DIGIT_TIMEOUT,
+			.interdigit_timeout = ANALOG_INTER_DIGIT_TIMEOUT,
+			.matchdigit_timeout = ANALOG_MATCH_DIGIT_TIMEOUT,
 		},
 		.timing = {
 			.prewinktime = -1,
@@ -3326,6 +3320,19 @@
 	}
 }
 
+#define gen_pvt_field_callback(type, field) \
+	static type my_get_##field(void *pvt) \
+	{ \
+		struct dahdi_pvt *p = pvt; \
+		return p->field; \
+	}
+
+gen_pvt_field_callback(int, firstdigit_timeout);
+gen_pvt_field_callback(int, interdigit_timeout);
+gen_pvt_field_callback(int, matchdigit_timeout);
+
+#undef gen_pvt_field_callback
+
 struct analog_callback analog_callbacks =
 {
 	.play_tone = my_play_tone,
@@ -3394,6 +3401,9 @@
 	.answer_polarityswitch = my_answer_polarityswitch,
 	.hangup_polarityswitch = my_hangup_polarityswitch,
 	.have_progressdetect = my_have_progressdetect,
+	.get_firstdigit_timeout = my_get_firstdigit_timeout,
+	.get_matchdigit_timeout = my_get_matchdigit_timeout,
+	.get_interdigit_timeout = my_get_interdigit_timeout,
 };
 
 /*! Round robin search locations. */
@@ -9555,9 +9565,9 @@
 				dtmfbuf[len] = '\0';
 				while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, ast_channel_context(chan), dtmfbuf, 1, p->cid_num)) {
 					if (ast_exists_extension(chan, ast_channel_context(chan), dtmfbuf, 1, p->cid_num)) {
-						timeout = matchdigittimeout;
+						timeout = p->matchdigit_timeout;
 					} else {
-						timeout = gendigittimeout;
+						timeout = p->interdigit_timeout;
 					}
 					res = ast_waitfordigit(chan, timeout);
 					if (res < 0) {
@@ -9725,7 +9735,7 @@
 	case SIG_FXOGS:
 	case SIG_FXOKS:
 		/* Read the first digit */
-		timeout = firstdigittimeout;
+		timeout = p->firstdigit_timeout;
 		/* If starting a threeway call, never timeout on the first digit so someone
 		   can use flash-hook as a "hold" feature */
 		if (p->subs[SUB_THREEWAY].owner)
@@ -9800,8 +9810,8 @@
 					}
 				} else {
 					/* It's a match, but they just typed a digit, and there is an ambiguous match,
-					   so just set the timeout to matchdigittimeout and wait some more */
-					timeout = matchdigittimeout;
+					   so just set the timeout to matchdigit_timeout and wait some more */
+					timeout = p->matchdigit_timeout;
 				}
 			} else if (res == 0) {
 				ast_debug(1, "not enough digits (and no ambiguous match)...\n");
@@ -9821,7 +9831,7 @@
 				len = 0;
 				ioctl(p->subs[idx].dfd,DAHDI_CONFDIAG,&len);
 				memset(exten, 0, sizeof(exten));
-				timeout = firstdigittimeout;
+				timeout = p->firstdigit_timeout;
 
 			} else if (!strcmp(exten, pickupexten)) {
 				/* Scan all channels and see if there are any
@@ -9866,7 +9876,7 @@
 				}
 				len = 0;
 				memset(exten, 0, sizeof(exten));
-				timeout = firstdigittimeout;
+				timeout = p->firstdigit_timeout;
 			} else if (p->callreturn && !strcmp(exten, "*69")) {
 				res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL);
 				break;
@@ -9938,7 +9948,7 @@
 				}
 				len = 0;
 				memset(exten, 0, sizeof(exten));
-				timeout = firstdigittimeout;
+				timeout = p->firstdigit_timeout;
 			} else if (!strcmp(exten, "*0")) {
 				struct ast_channel *nbridge =
 					p->subs[SUB_THREEWAY].owner;
@@ -9986,7 +9996,7 @@
 				break;
 			}
 			if (!timeout)
-				timeout = gendigittimeout;
+				timeout = p->interdigit_timeout;
 			if (len && !ast_ignore_pattern(ast_channel_context(chan), exten))
 				tone_zone_play_tone(p->subs[idx].dfd, -1);
 		}
@@ -12501,6 +12511,9 @@
 		tmp->waitfordialtone = conf->chan.waitfordialtone;
 		tmp->dialtone_detect = conf->chan.dialtone_detect;
 		tmp->faxdetect_timeout = conf->chan.faxdetect_timeout;
+		tmp->firstdigit_timeout = conf->chan.firstdigit_timeout;
+		tmp->interdigit_timeout = conf->chan.interdigit_timeout;
+		tmp->matchdigit_timeout = conf->chan.matchdigit_timeout;
 		tmp->cancallforward = conf->chan.cancallforward;
 		tmp->dtmfrelax = conf->chan.dtmfrelax;
 		tmp->callwaiting = tmp->permcallwaiting;
@@ -17713,6 +17726,21 @@
 			if (sscanf(v->value, "%30u", &confp->chan.faxdetect_timeout) != 1) {
 				confp->chan.faxdetect_timeout = 0;
 			}
+		} else if (!strcasecmp(v->name, "firstdigit_timeout")) {
+			if (sscanf(v->value, "%30d", &confp->chan.firstdigit_timeout) != 1
+				|| confp->chan.firstdigit_timeout <= 0) {
+				confp->chan.firstdigit_timeout = ANALOG_FIRST_DIGIT_TIMEOUT;
+			}
+		} else if (!strcasecmp(v->name, "interdigit_timeout")) {
+			if (sscanf(v->value, "%30d", &confp->chan.interdigit_timeout) != 1
+				|| confp->chan.interdigit_timeout <= 0) {
+				confp->chan.interdigit_timeout = ANALOG_INTER_DIGIT_TIMEOUT;
+			}
+		} else if (!strcasecmp(v->name, "matchdigit_timeout")) {
+			if (sscanf(v->value, "%30d", &confp->chan.matchdigit_timeout) != 1
+				|| confp->chan.matchdigit_timeout <= 0) {
+				confp->chan.matchdigit_timeout = ANALOG_MATCH_DIGIT_TIMEOUT;
+			}
 		} else if (!strcasecmp(v->name, "echocancel")) {
 			process_echocancel(confp, v->value, v->lineno);
 		} else if (!strcasecmp(v->name, "echotraining")) {
diff --git a/channels/chan_dahdi.h b/channels/chan_dahdi.h
index ab5c1eb..c22ed01 100644
--- a/channels/chan_dahdi.h
+++ b/channels/chan_dahdi.h
@@ -617,6 +617,21 @@
 	 * \note Set from the "faxdetect_timeout" value read in from chan_dahdi.conf
 	 */
 	unsigned int faxdetect_timeout;
+	/*!
+	 * \brief Time (ms) to detect first digit (in an analog phone)
+	 * \note Set from the "firstdigit_timeout" value read in from chan_dahdi.conf
+	 */
+	int firstdigit_timeout;
+	/*!
+	 * \brief Time (ms) to detect following digits (in an analog phone)
+	 * \note Set from the "interdigit_timeout" value read in from chan_dahdi.conf
+	 */
+	int interdigit_timeout;
+	/*!
+	 * \brief Time (ms) to wait, in case of ambiguous match (in an analog phone)
+	 * \note Set from the "matchdigit_timeout" value read in from chan_dahdi.conf
+	 */
+	int matchdigit_timeout;
 	struct timeval waitingfordt;			/*!< Time we started waiting for dialtone */
 	struct timeval flashtime;			/*!< Last flash-hook time */
 	/*! \brief Opaque DSP configuration structure. */
diff --git a/channels/sig_analog.c b/channels/sig_analog.c
index 110942c..53f9fb2 100644
--- a/channels/sig_analog.c
+++ b/channels/sig_analog.c
@@ -62,9 +62,6 @@
 #define POLARITY_IDLE 0
 #define POLARITY_REV    1
 #define MIN_MS_SINCE_FLASH			( (2000) )	/*!< 2000 ms */
-static int analog_matchdigittimeout = 3000;
-static int analog_gendigittimeout = 8000;
-static int analog_firstdigittimeout = 16000;
 static char analog_defaultcic[64] = "";
 static char analog_defaultozz[64] = "";
 
@@ -218,6 +215,21 @@
 	/* Don't have progress detection. */
 	return 0;
 }
+
+#define gen_analog_field_callback(type, callback_name, def_value) \
+	static type analog_get_##callback_name(struct analog_pvt *p) \
+	{ \
+		if (!analog_callbacks.get_##callback_name) { \
+			return def_value; \
+		} \
+		return analog_callbacks.get_##callback_name(p->chan_pvt); \
+	}
+
+gen_analog_field_callback(int, firstdigit_timeout, ANALOG_FIRST_DIGIT_TIMEOUT);
+gen_analog_field_callback(int, interdigit_timeout, ANALOG_INTER_DIGIT_TIMEOUT);
+gen_analog_field_callback(int, matchdigit_timeout, ANALOG_MATCH_DIGIT_TIMEOUT);
+
+#undef gen_analog_field_callback
 
 enum analog_cid_start analog_str_to_cidstart(const char *value)
 {
@@ -1886,9 +1898,9 @@
 				dtmfbuf[len] = '\0';
 				while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, ast_channel_context(chan), dtmfbuf, 1, p->cid_num)) {
 					if (ast_exists_extension(chan, ast_channel_context(chan), dtmfbuf, 1, p->cid_num)) {
-						timeout = analog_matchdigittimeout;
+						timeout = analog_get_matchdigit_timeout(p);
 					} else {
-						timeout = analog_gendigittimeout;
+						timeout = analog_get_interdigit_timeout(p);
 					}
 					res = ast_waitfordigit(chan, timeout);
 					if (res < 0) {
@@ -2074,7 +2086,7 @@
 	case ANALOG_SIG_FXOGS:
 	case ANALOG_SIG_FXOKS:
 		/* Read the first digit */
-		timeout = analog_firstdigittimeout;
+		timeout = analog_get_firstdigit_timeout(p);
 		/* If starting a threeway call, never timeout on the first digit so someone
 		   can use flash-hook as a "hold" feature */
 		if (p->subs[ANALOG_SUB_THREEWAY].owner) {
@@ -2155,7 +2167,7 @@
 				} else {
 					/* It's a match, but they just typed a digit, and there is an ambiguous match,
 					   so just set the timeout to analog_matchdigittimeout and wait some more */
-					timeout = analog_matchdigittimeout;
+					timeout = analog_get_matchdigit_timeout(p);
 				}
 			} else if (res == 0) {
 				ast_debug(1, "not enough digits (and no ambiguous match)...\n");
@@ -2174,7 +2186,7 @@
 				}
 				len = 0;
 				memset(exten, 0, sizeof(exten));
-				timeout = analog_firstdigittimeout;
+				timeout = analog_get_firstdigit_timeout(p);
 
 			} else if (!strcmp(exten, pickupexten)) {
 				/* Scan all channels and see if there are any
@@ -2219,7 +2231,7 @@
 				}
 				len = 0;
 				memset(exten, 0, sizeof(exten));
-				timeout = analog_firstdigittimeout;
+				timeout = analog_get_firstdigit_timeout(p);
 			} else if (p->callreturn && !strcmp(exten, "*69")) {
 				res = 0;
 				if (!ast_strlen_zero(p->lastcid_num)) {
@@ -2305,7 +2317,7 @@
 				}
 				len = 0;
 				memset(exten, 0, sizeof(exten));
-				timeout = analog_firstdigittimeout;
+				timeout = analog_get_firstdigit_timeout(p);
 			} else if (!strcmp(exten, "*0")) {
 				struct ast_channel *nbridge = p->subs[ANALOG_SUB_THREEWAY].owner;
 				struct analog_pvt *pbridge = NULL;
@@ -2348,7 +2360,7 @@
 				break;
 			}
 			if (!timeout) {
-				timeout = analog_gendigittimeout;
+				timeout = analog_get_interdigit_timeout(p);
 			}
 			if (len && !ast_ignore_pattern(ast_channel_context(chan), exten)) {
 				analog_play_tone(p, idx, -1);
diff --git a/channels/sig_analog.h b/channels/sig_analog.h
index 42e00c0..3b9dcf5 100644
--- a/channels/sig_analog.h
+++ b/channels/sig_analog.h
@@ -34,6 +34,13 @@
 #define READ_SIZE 160
 #define RING_PATTERNS 3
 
+/*! \brief Default time (ms) to detect first digit */
+#define ANALOG_FIRST_DIGIT_TIMEOUT	16000
+/*! \brief Default time (ms) to detect following digits */
+#define ANALOG_INTER_DIGIT_TIMEOUT	8000
+/*! \brief Default time (ms) to wait, in case of ambiguous match */
+#define ANALOG_MATCH_DIGIT_TIMEOUT	3000
+
 /* Signalling types supported */
 enum analog_sigtype {
 	ANALOG_SIG_NONE = -1,
@@ -237,6 +244,9 @@
 
 	const char *(* const get_orig_dialstring)(void *pvt);
 	int (* const have_progressdetect)(void *pvt);
+	int (* const get_firstdigit_timeout)(void *pvt);
+	int (* const get_interdigit_timeout)(void *pvt);
+	int (* const get_matchdigit_timeout)(void *pvt);
 };
 
 /*! Global analog callbacks to the upper layer. */
diff --git a/configs/samples/chan_dahdi.conf.sample b/configs/samples/chan_dahdi.conf.sample
index 3c5e18d..d24c22b 100644
--- a/configs/samples/chan_dahdi.conf.sample
+++ b/configs/samples/chan_dahdi.conf.sample
@@ -1137,6 +1137,21 @@
 ;
 ;faxbuffers=>6,full
 ;
+; When FXO signalling (FXS device, e.g. analog phone) is used, overlap dialing
+; is typically used. Asterisk has several configurable (per-channel) timeouts
+; to know how long to wait for the next digit. All the values are in
+; milliseconds.
+; * firstdigit_timeout: a longer timeout before any digit is dialed.
+;   By default: 16 seconds.
+; * interdigit_timeout: timeout for next digits, if the current number dialed
+;   does not match a number in the current context. Default: 8 seconds.
+; * matchdigit_timeout: timeout for next digits, if the current number dialed
+;   matches a number in the current context. Default: 3 seconds.
+;
+;firstdigit_timeout=16000
+;interdigit_timeout=8000
+;matchdigit_timeout=3000
+;
 ; Configure the default number of DAHDI buffers and the transmit policy to use.
 ; This can be used to eliminate data drops when scheduling jitter prevents
 ; Asterisk from writing to a DAHDI channel regularly. Most users will probably

-- 
To view, visit https://gerrit.asterisk.org/8637
To unsubscribe, visit https://gerrit.asterisk.org/settings

Gerrit-Project: asterisk
Gerrit-Branch: master
Gerrit-MessageType: merged
Gerrit-Change-Id: Ib728fa900a4f6ae56d1ed810aba61b6593fb7213
Gerrit-Change-Number: 8637
Gerrit-PatchSet: 4
Gerrit-Owner: Tzafrir Cohen <tzafrir.cohen at xorcom.com>
Gerrit-Reviewer: Jenkins2
Gerrit-Reviewer: Joshua Colp <jcolp at digium.com>
Gerrit-Reviewer: Matthew Fredrickson <creslin at digium.com>
Gerrit-Reviewer: Oron Peled <oron.peled at xorcom.com>
Gerrit-Reviewer: Richard Mudgett <rmudgett at digium.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20180503/df1d953d/attachment-0001.html>


More information about the asterisk-code-review mailing list