diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c
index 5607eb01b7..e49a7996a9 100644
--- a/channels/chan_dahdi.c
+++ b/channels/chan_dahdi.c
@@ -261,6 +261,17 @@
completely disabled)
voice Voice mode (returns from FAX mode, reverting the changes that were made)
+
+ R/W Pulse and tone dialing mode of the channel.
+ If set, overrides the setting in chan_dahdi.conf for that channel.
+
+
+
+
+
+
+
+
@@ -1034,6 +1045,7 @@ static struct dahdi_chan_conf dahdi_chan_conf_default(void)
.mohsuggest = "",
.parkinglot = "",
.transfertobusy = 1,
+ .dialmode = 0,
.ani_info_digits = 2,
.ani_wink_time = 1000,
@@ -7009,6 +7021,32 @@ static int dahdi_func_read(struct ast_channel *chan, const char *function, char
}
ast_mutex_unlock(&p->lock);
#endif /* defined(HAVE_PRI) */
+ } else if (!strcasecmp(data, "dialmode")) {
+ struct analog_pvt *analog_p;
+ ast_mutex_lock(&p->lock);
+ analog_p = p->sig_pvt;
+ /* Hardcode p->radio and p->oprmode as 0 since we're using this to check for analogness, not the handler */
+ if (dahdi_analog_lib_handles(p->sig, 0, 0) && analog_p) {
+ switch (analog_p->dialmode) {
+ case ANALOG_DIALMODE_BOTH:
+ ast_copy_string(buf, "both", len);
+ break;
+ case ANALOG_DIALMODE_PULSE:
+ ast_copy_string(buf, "pulse", len);
+ break;
+ case ANALOG_DIALMODE_DTMF:
+ ast_copy_string(buf, "dtmf", len);
+ break;
+ case ANALOG_DIALMODE_NONE:
+ ast_copy_string(buf, "none", len);
+ break;
+ }
+ } else {
+ ast_log(LOG_WARNING, "%s only supported on analog channels\n", data);
+ *buf = '\0';
+ res = -1;
+ }
+ ast_mutex_unlock(&p->lock);
} else {
*buf = '\0';
res = -1;
@@ -7114,6 +7152,30 @@ static int dahdi_func_write(struct ast_channel *chan, const char *function, char
ast_log(LOG_WARNING, "Unsupported value '%s' provided for '%s' item.\n", value, data);
res = -1;
}
+ } else if (!strcasecmp(data, "dialmode")) {
+ struct analog_pvt *analog_p;
+
+ ast_mutex_lock(&p->lock);
+ analog_p = p->sig_pvt;
+ if (!dahdi_analog_lib_handles(p->sig, 0, 0) || !analog_p) {
+ ast_log(LOG_WARNING, "%s only supported on analog channels\n", data);
+ ast_mutex_unlock(&p->lock);
+ return -1;
+ }
+ /* analog pvt is used for pulse dialing, so update both */
+ if (!strcasecmp(value, "pulse")) {
+ p->dialmode = analog_p->dialmode = ANALOG_DIALMODE_PULSE;
+ } else if (!strcasecmp(value, "dtmf") || !strcasecmp(value, "tone")) {
+ p->dialmode = analog_p->dialmode = ANALOG_DIALMODE_DTMF;
+ } else if (!strcasecmp(value, "none")) {
+ p->dialmode = analog_p->dialmode = ANALOG_DIALMODE_NONE;
+ } else if (!strcasecmp(value, "both")) {
+ p->dialmode = analog_p->dialmode = ANALOG_DIALMODE_BOTH;
+ } else {
+ ast_log(LOG_WARNING, "'%s' is an invalid setting for %s\n", value, data);
+ res = -1;
+ }
+ ast_mutex_unlock(&p->lock);
} else {
res = -1;
}
@@ -8997,6 +9059,13 @@ static struct ast_frame *dahdi_read(struct ast_channel *ast)
} else {
dahdi_handle_dtmf(ast, idx, &f);
}
+ if (!(p->dialmode == ANALOG_DIALMODE_BOTH || p->dialmode == ANALOG_DIALMODE_DTMF)) {
+ if (f->frametype == AST_FRAME_DTMF_END) { /* only show this message when the key is let go of */
+ ast_debug(1, "Dropping DTMF digit '%c' because tone dialing is disabled\n", f->subclass.integer);
+ }
+ f->frametype = AST_FRAME_NULL;
+ f->subclass.integer = 0;
+ }
break;
case AST_FRAME_VOICE:
if (p->cidspill || p->cid_suppress_expire) {
@@ -12780,6 +12849,7 @@ static struct dahdi_pvt *mkintf(int channel, const struct dahdi_chan_conf *conf,
#endif
tmp->immediate = conf->chan.immediate;
tmp->transfertobusy = conf->chan.transfertobusy;
+ tmp->dialmode = conf->chan.dialmode;
if (chan_sig & __DAHDI_SIG_FXS) {
tmp->mwimonitor_fsk = conf->chan.mwimonitor_fsk;
tmp->mwimonitor_neon = conf->chan.mwimonitor_neon;
@@ -13113,6 +13183,7 @@ static struct dahdi_pvt *mkintf(int channel, const struct dahdi_chan_conf *conf,
analog_p->threewaycalling = conf->chan.threewaycalling;
analog_p->transfer = conf->chan.transfer;
analog_p->transfertobusy = conf->chan.transfertobusy;
+ analog_p->dialmode = conf->chan.dialmode;
analog_p->use_callerid = tmp->use_callerid;
analog_p->usedistinctiveringdetection = tmp->usedistinctiveringdetection;
analog_p->use_smdi = tmp->use_smdi;
@@ -18314,6 +18385,16 @@ static int process_dahdi(struct dahdi_chan_conf *confp, const char *cat, struct
confp->chan.immediate = ast_true(v->value);
} else if (!strcasecmp(v->name, "transfertobusy")) {
confp->chan.transfertobusy = ast_true(v->value);
+ } else if (!strcasecmp(v->name, "dialmode")) {
+ if (!strcasecmp(v->value, "pulse")) {
+ confp->chan.dialmode = ANALOG_DIALMODE_PULSE;
+ } else if (!strcasecmp(v->value, "dtmf") || !strcasecmp(v->value, "tone")) {
+ confp->chan.dialmode = ANALOG_DIALMODE_DTMF;
+ } else if (!strcasecmp(v->value, "none")) {
+ confp->chan.dialmode = ANALOG_DIALMODE_NONE;
+ } else {
+ confp->chan.dialmode = ANALOG_DIALMODE_BOTH;
+ }
} else if (!strcasecmp(v->name, "mwimonitor")) {
confp->chan.mwimonitor_neon = 0;
confp->chan.mwimonitor_fsk = 0;
diff --git a/channels/chan_dahdi.h b/channels/chan_dahdi.h
index de813f21bf..8f16687528 100644
--- a/channels/chan_dahdi.h
+++ b/channels/chan_dahdi.h
@@ -146,6 +146,7 @@ struct dahdi_pvt {
* \note Set to a couple of nonzero values but it is only tested like a boolean.
*/
int radio;
+ int dialmode; /*!< Dialing Modes Allowed (Pulse/Tone) */
int outsigmod; /*!< Outbound Signalling style (modifier) */
int oprmode; /*!< "Operator Services" mode */
struct dahdi_pvt *oprpeer; /*!< "Operator Services" peer tech_pvt ptr */
diff --git a/channels/sig_analog.c b/channels/sig_analog.c
index b694a96082..5ae96d9418 100644
--- a/channels/sig_analog.c
+++ b/channels/sig_analog.c
@@ -2775,9 +2775,13 @@ static struct ast_frame *__analog_handle_event(struct analog_pvt *p, struct ast_
analog_set_pulsedial(p, (res & ANALOG_EVENT_PULSEDIGIT) ? 1 : 0);
ast_debug(1, "Detected %sdigit '%c'\n", (res & ANALOG_EVENT_PULSEDIGIT) ? "pulse ": "", res & 0xff);
analog_confmute(p, 0);
- p->subs[idx].f.frametype = AST_FRAME_DTMF_END;
- p->subs[idx].f.subclass.integer = res & 0xff;
- analog_handle_dtmf(p, ast, idx, &f);
+ if (p->dialmode == ANALOG_DIALMODE_BOTH || p->dialmode == ANALOG_DIALMODE_PULSE) {
+ p->subs[idx].f.frametype = AST_FRAME_DTMF_END;
+ p->subs[idx].f.subclass.integer = res & 0xff;
+ analog_handle_dtmf(p, ast, idx, &f);
+ } else {
+ ast_debug(1, "Dropping pulse digit '%c' because pulse dialing disabled on channel %d\n", res & 0xff, p->channel);
+ }
return f;
}
diff --git a/channels/sig_analog.h b/channels/sig_analog.h
index 7e9acda55c..07e1cdd2aa 100644
--- a/channels/sig_analog.h
+++ b/channels/sig_analog.h
@@ -116,6 +116,13 @@ enum analog_dsp_digitmode {
ANALOG_DIGITMODE_MF,
};
+enum analog_dialmode {
+ ANALOG_DIALMODE_BOTH = 0,
+ ANALOG_DIALMODE_PULSE,
+ ANALOG_DIALMODE_DTMF,
+ ANALOG_DIALMODE_NONE,
+};
+
enum analog_cid_start {
ANALOG_CID_START_POLARITY = 1,
ANALOG_CID_START_POLARITY_IN,
@@ -308,6 +315,7 @@ struct analog_pvt {
int channel; /*!< Channel Number */
enum analog_sigtype outsigmod;
+ enum analog_dialmode dialmode; /*!< Which of pulse and/or tone dialing to support */
int echotraining;
int cid_signalling; /*!< Asterisk callerid type we're using */
int polarityonanswerdelay;
diff --git a/configs/samples/chan_dahdi.conf.sample b/configs/samples/chan_dahdi.conf.sample
index 6b29549750..c54f482566 100644
--- a/configs/samples/chan_dahdi.conf.sample
+++ b/configs/samples/chan_dahdi.conf.sample
@@ -1131,10 +1131,19 @@ pickupgroup=1
;
; For FXO (FXS signalled) devices, whether to use pulse dial instead of DTMF
; Pulse digits from phones (FXS devices, FXO signalling) are always
-; detected.
+; detected, unless the dialmode setting has been changed from the default.
;
;pulsedial=yes
;
+; For FXS (FXO signalled) devices, the dialing modes to support for the channel.
+; By default, both pulse and tone (DTMF) dialing are always detected.
+; May be set to "pulse" if you only want to allow pulse dialing on a line.
+; May be set to "dtmf" or "tone" to only allow tone dialing on a line.
+; May be set to "none" to prevent dialing entirely.
+; You can also change this during a call using the CHANNEL function in the dialplan.
+;
+;dialmode=both
+;
; For fax detection, uncomment one of the following lines. The default is *OFF*
;
;faxdetect=both