Skip to content

Commit 9a99924

Browse files
committed
chan_dahdi: Add dialmode option for FXS lines.
Currently, both pulse and tone dialing are always enabled on all FXS lines, with no way of disabling one or the other. In some circumstances, it is desirable or necessary to disable one of these, and this behavior can be problematic. A new "dialmode" option is added which allows setting the methods to support on a per channel basis for FXS (FXO signalled lines). The four options are "both", "pulse", "dtmf"/"tone", and "none". Additionally, integration with the CHANNEL function is added so that this setting can be updated for a channel during a call. Resolves: #35 ASTERISK-29992 UserNote: 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.
1 parent 1b95f6e commit 9a99924

File tree

5 files changed

+107
-4
lines changed

5 files changed

+107
-4
lines changed

channels/chan_dahdi.c

+81
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,17 @@
261261
completely disabled)</para>
262262
<para> <literal>voice</literal> Voice mode (returns from FAX mode, reverting the changes that were made)</para>
263263
</enum>
264+
<enum name="dialmode">
265+
<para>R/W Pulse and tone dialing mode of the channel.</para>
266+
<para>If set, overrides the setting in <literal>chan_dahdi.conf</literal> for that channel.</para>
267+
<enumlist>
268+
<enum name="both" />
269+
<enum name="pulse" />
270+
<enum name="dtmf" />
271+
<enum name="tone" />
272+
<enum name="none" />
273+
</enumlist>
274+
</enum>
264275
</enumlist>
265276
</info>
266277
<info name="Dial_Resource" language="en_US" tech="DAHDI">
@@ -1034,6 +1045,7 @@ static struct dahdi_chan_conf dahdi_chan_conf_default(void)
10341045
.mohsuggest = "",
10351046
.parkinglot = "",
10361047
.transfertobusy = 1,
1048+
.dialmode = 0,
10371049

10381050
.ani_info_digits = 2,
10391051
.ani_wink_time = 1000,
@@ -7009,6 +7021,32 @@ static int dahdi_func_read(struct ast_channel *chan, const char *function, char
70097021
}
70107022
ast_mutex_unlock(&p->lock);
70117023
#endif /* defined(HAVE_PRI) */
7024+
} else if (!strcasecmp(data, "dialmode")) {
7025+
struct analog_pvt *analog_p;
7026+
ast_mutex_lock(&p->lock);
7027+
analog_p = p->sig_pvt;
7028+
/* Hardcode p->radio and p->oprmode as 0 since we're using this to check for analogness, not the handler */
7029+
if (dahdi_analog_lib_handles(p->sig, 0, 0) && analog_p) {
7030+
switch (analog_p->dialmode) {
7031+
case ANALOG_DIALMODE_BOTH:
7032+
ast_copy_string(buf, "both", len);
7033+
break;
7034+
case ANALOG_DIALMODE_PULSE:
7035+
ast_copy_string(buf, "pulse", len);
7036+
break;
7037+
case ANALOG_DIALMODE_DTMF:
7038+
ast_copy_string(buf, "dtmf", len);
7039+
break;
7040+
case ANALOG_DIALMODE_NONE:
7041+
ast_copy_string(buf, "none", len);
7042+
break;
7043+
}
7044+
} else {
7045+
ast_log(LOG_WARNING, "%s only supported on analog channels\n", data);
7046+
*buf = '\0';
7047+
res = -1;
7048+
}
7049+
ast_mutex_unlock(&p->lock);
70127050
} else {
70137051
*buf = '\0';
70147052
res = -1;
@@ -7114,6 +7152,30 @@ static int dahdi_func_write(struct ast_channel *chan, const char *function, char
71147152
ast_log(LOG_WARNING, "Unsupported value '%s' provided for '%s' item.\n", value, data);
71157153
res = -1;
71167154
}
7155+
} else if (!strcasecmp(data, "dialmode")) {
7156+
struct analog_pvt *analog_p;
7157+
7158+
ast_mutex_lock(&p->lock);
7159+
analog_p = p->sig_pvt;
7160+
if (!dahdi_analog_lib_handles(p->sig, 0, 0) || !analog_p) {
7161+
ast_log(LOG_WARNING, "%s only supported on analog channels\n", data);
7162+
ast_mutex_unlock(&p->lock);
7163+
return -1;
7164+
}
7165+
/* analog pvt is used for pulse dialing, so update both */
7166+
if (!strcasecmp(value, "pulse")) {
7167+
p->dialmode = analog_p->dialmode = ANALOG_DIALMODE_PULSE;
7168+
} else if (!strcasecmp(value, "dtmf") || !strcasecmp(value, "tone")) {
7169+
p->dialmode = analog_p->dialmode = ANALOG_DIALMODE_DTMF;
7170+
} else if (!strcasecmp(value, "none")) {
7171+
p->dialmode = analog_p->dialmode = ANALOG_DIALMODE_NONE;
7172+
} else if (!strcasecmp(value, "both")) {
7173+
p->dialmode = analog_p->dialmode = ANALOG_DIALMODE_BOTH;
7174+
} else {
7175+
ast_log(LOG_WARNING, "'%s' is an invalid setting for %s\n", value, data);
7176+
res = -1;
7177+
}
7178+
ast_mutex_unlock(&p->lock);
71177179
} else {
71187180
res = -1;
71197181
}
@@ -8997,6 +9059,13 @@ static struct ast_frame *dahdi_read(struct ast_channel *ast)
89979059
} else {
89989060
dahdi_handle_dtmf(ast, idx, &f);
89999061
}
9062+
if (!(p->dialmode == ANALOG_DIALMODE_BOTH || p->dialmode == ANALOG_DIALMODE_DTMF)) {
9063+
if (f->frametype == AST_FRAME_DTMF_END) { /* only show this message when the key is let go of */
9064+
ast_debug(1, "Dropping DTMF digit '%c' because tone dialing is disabled\n", f->subclass.integer);
9065+
}
9066+
f->frametype = AST_FRAME_NULL;
9067+
f->subclass.integer = 0;
9068+
}
90009069
break;
90019070
case AST_FRAME_VOICE:
90029071
if (p->cidspill || p->cid_suppress_expire) {
@@ -12780,6 +12849,7 @@ static struct dahdi_pvt *mkintf(int channel, const struct dahdi_chan_conf *conf,
1278012849
#endif
1278112850
tmp->immediate = conf->chan.immediate;
1278212851
tmp->transfertobusy = conf->chan.transfertobusy;
12852+
tmp->dialmode = conf->chan.dialmode;
1278312853
if (chan_sig & __DAHDI_SIG_FXS) {
1278412854
tmp->mwimonitor_fsk = conf->chan.mwimonitor_fsk;
1278512855
tmp->mwimonitor_neon = conf->chan.mwimonitor_neon;
@@ -13113,6 +13183,7 @@ static struct dahdi_pvt *mkintf(int channel, const struct dahdi_chan_conf *conf,
1311313183
analog_p->threewaycalling = conf->chan.threewaycalling;
1311413184
analog_p->transfer = conf->chan.transfer;
1311513185
analog_p->transfertobusy = conf->chan.transfertobusy;
13186+
analog_p->dialmode = conf->chan.dialmode;
1311613187
analog_p->use_callerid = tmp->use_callerid;
1311713188
analog_p->usedistinctiveringdetection = tmp->usedistinctiveringdetection;
1311813189
analog_p->use_smdi = tmp->use_smdi;
@@ -18314,6 +18385,16 @@ static int process_dahdi(struct dahdi_chan_conf *confp, const char *cat, struct
1831418385
confp->chan.immediate = ast_true(v->value);
1831518386
} else if (!strcasecmp(v->name, "transfertobusy")) {
1831618387
confp->chan.transfertobusy = ast_true(v->value);
18388+
} else if (!strcasecmp(v->name, "dialmode")) {
18389+
if (!strcasecmp(v->value, "pulse")) {
18390+
confp->chan.dialmode = ANALOG_DIALMODE_PULSE;
18391+
} else if (!strcasecmp(v->value, "dtmf") || !strcasecmp(v->value, "tone")) {
18392+
confp->chan.dialmode = ANALOG_DIALMODE_DTMF;
18393+
} else if (!strcasecmp(v->value, "none")) {
18394+
confp->chan.dialmode = ANALOG_DIALMODE_NONE;
18395+
} else {
18396+
confp->chan.dialmode = ANALOG_DIALMODE_BOTH;
18397+
}
1831718398
} else if (!strcasecmp(v->name, "mwimonitor")) {
1831818399
confp->chan.mwimonitor_neon = 0;
1831918400
confp->chan.mwimonitor_fsk = 0;

channels/chan_dahdi.h

+1
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ struct dahdi_pvt {
146146
* \note Set to a couple of nonzero values but it is only tested like a boolean.
147147
*/
148148
int radio;
149+
int dialmode; /*!< Dialing Modes Allowed (Pulse/Tone) */
149150
int outsigmod; /*!< Outbound Signalling style (modifier) */
150151
int oprmode; /*!< "Operator Services" mode */
151152
struct dahdi_pvt *oprpeer; /*!< "Operator Services" peer tech_pvt ptr */

channels/sig_analog.c

+7-3
Original file line numberDiff line numberDiff line change
@@ -2775,9 +2775,13 @@ static struct ast_frame *__analog_handle_event(struct analog_pvt *p, struct ast_
27752775
analog_set_pulsedial(p, (res & ANALOG_EVENT_PULSEDIGIT) ? 1 : 0);
27762776
ast_debug(1, "Detected %sdigit '%c'\n", (res & ANALOG_EVENT_PULSEDIGIT) ? "pulse ": "", res & 0xff);
27772777
analog_confmute(p, 0);
2778-
p->subs[idx].f.frametype = AST_FRAME_DTMF_END;
2779-
p->subs[idx].f.subclass.integer = res & 0xff;
2780-
analog_handle_dtmf(p, ast, idx, &f);
2778+
if (p->dialmode == ANALOG_DIALMODE_BOTH || p->dialmode == ANALOG_DIALMODE_PULSE) {
2779+
p->subs[idx].f.frametype = AST_FRAME_DTMF_END;
2780+
p->subs[idx].f.subclass.integer = res & 0xff;
2781+
analog_handle_dtmf(p, ast, idx, &f);
2782+
} else {
2783+
ast_debug(1, "Dropping pulse digit '%c' because pulse dialing disabled on channel %d\n", res & 0xff, p->channel);
2784+
}
27812785
return f;
27822786
}
27832787

channels/sig_analog.h

+8
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,13 @@ enum analog_dsp_digitmode {
116116
ANALOG_DIGITMODE_MF,
117117
};
118118

119+
enum analog_dialmode {
120+
ANALOG_DIALMODE_BOTH = 0,
121+
ANALOG_DIALMODE_PULSE,
122+
ANALOG_DIALMODE_DTMF,
123+
ANALOG_DIALMODE_NONE,
124+
};
125+
119126
enum analog_cid_start {
120127
ANALOG_CID_START_POLARITY = 1,
121128
ANALOG_CID_START_POLARITY_IN,
@@ -308,6 +315,7 @@ struct analog_pvt {
308315
int channel; /*!< Channel Number */
309316

310317
enum analog_sigtype outsigmod;
318+
enum analog_dialmode dialmode; /*!< Which of pulse and/or tone dialing to support */
311319
int echotraining;
312320
int cid_signalling; /*!< Asterisk callerid type we're using */
313321
int polarityonanswerdelay;

configs/samples/chan_dahdi.conf.sample

+10-1
Original file line numberDiff line numberDiff line change
@@ -1131,10 +1131,19 @@ pickupgroup=1
11311131
;
11321132
; For FXO (FXS signalled) devices, whether to use pulse dial instead of DTMF
11331133
; Pulse digits from phones (FXS devices, FXO signalling) are always
1134-
; detected.
1134+
; detected, unless the dialmode setting has been changed from the default.
11351135
;
11361136
;pulsedial=yes
11371137
;
1138+
; For FXS (FXO signalled) devices, the dialing modes to support for the channel.
1139+
; By default, both pulse and tone (DTMF) dialing are always detected.
1140+
; May be set to "pulse" if you only want to allow pulse dialing on a line.
1141+
; May be set to "dtmf" or "tone" to only allow tone dialing on a line.
1142+
; May be set to "none" to prevent dialing entirely.
1143+
; You can also change this during a call using the CHANNEL function in the dialplan.
1144+
;
1145+
;dialmode=both
1146+
;
11381147
; For fax detection, uncomment one of the following lines. The default is *OFF*
11391148
;
11401149
;faxdetect=both

0 commit comments

Comments
 (0)