diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c index 8ce0526f4d..8957790b3b 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, @@ -7008,6 +7020,30 @@ 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 = p->sig_pvt; + if (analog_p) { + ast_mutex_lock(&p->lock); + 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; + } + ast_mutex_unlock(&p->lock); + } else { + ast_log(LOG_WARNING, "%s only supported on analog channels\n", data); + *buf = '\0'; + res = -1; + } } else { *buf = '\0'; res = -1; @@ -7113,6 +7149,27 @@ 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 = p->sig_pvt; + if (!analog_p) { + ast_log(LOG_WARNING, "%s only supported on analog channels\n", data); + return -1; + } + ast_mutex_lock(&p->lock); + /* 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; } @@ -8996,6 +9053,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) { @@ -12779,6 +12843,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; @@ -13112,6 +13177,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; @@ -18308,6 +18374,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 76ee645c26..1abb8d6e48 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 6333351c0d..4affe264c3 100644 --- a/configs/samples/chan_dahdi.conf.sample +++ b/configs/samples/chan_dahdi.conf.sample @@ -1126,10 +1126,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 diff --git a/doc/CHANGES-staging/chan_dahdi_dialmode.txt b/doc/CHANGES-staging/chan_dahdi_dialmode.txt new file mode 100644 index 0000000000..2e77a29a70 --- /dev/null +++ b/doc/CHANGES-staging/chan_dahdi_dialmode.txt @@ -0,0 +1,10 @@ +Subject: chan_dahdi + +A "dialmode" option has been added which allows +specifying, on a per-channel basis, what methods +of subscriber dialing (pulse and/or tone) are +permitted. + +Additionally, this can be changed on a channel +at any point during a call using the CHANNEL +function.