summaryrefslogtreecommitdiff
path: root/channels/chan_dahdi.c
diff options
context:
space:
mode:
authorKevin P. Fleming <kpfleming@digium.com>2009-06-16 21:10:15 +0000
committerKevin P. Fleming <kpfleming@digium.com>2009-06-16 21:10:15 +0000
commitf1dc620467d9b218ad5041b6416bb030aec9c68c (patch)
treeb922d4113cce5ce50a4adcda3b8bcf400ab25b47 /channels/chan_dahdi.c
parent5b2939916fe602bb9dfd2ff6c5d40a594b3bd768 (diff)
Enable applications to enable/disable digit and tone detection.
Some applications (notably app_fax) do not need digit detection nor FAX tone detection while they are running, and if Asterisk is using software DSPs to provide the detection, this consumes extra CPU cycles that could be better spent on the actual application. This patch allows applications to query and control the state of digit and tone detection on a channel, and modifies app_fax to disable them while the FAX operations are occurring (and re-enable digit detection afterwards). git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@201139 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'channels/chan_dahdi.c')
-rw-r--r--channels/chan_dahdi.c122
1 files changed, 89 insertions, 33 deletions
diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c
index 3567aa9e9..bd11e51ea 100644
--- a/channels/chan_dahdi.c
+++ b/channels/chan_dahdi.c
@@ -1507,6 +1507,7 @@ static struct ast_frame *dahdi_exception(struct ast_channel *ast);
static int dahdi_indicate(struct ast_channel *chan, int condition, const void *data, size_t datalen);
static int dahdi_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
static int dahdi_setoption(struct ast_channel *chan, int option, void *data, int datalen);
+static int dahdi_queryoption(struct ast_channel *chan, int option, void *data, int *datalen);
static int dahdi_func_read(struct ast_channel *chan, const char *function, char *data, char *buf, size_t len);
static int handle_init_event(struct dahdi_pvt *i, int event);
static int dahdi_func_write(struct ast_channel *chan, const char *function, char *data, const char *value);
@@ -1529,6 +1530,7 @@ static const struct ast_channel_tech dahdi_tech = {
.indicate = dahdi_indicate,
.fixup = dahdi_fixup,
.setoption = dahdi_setoption,
+ .queryoption = dahdi_queryoption,
.func_channel_read = dahdi_func_read,
.func_channel_write = dahdi_func_write,
};
@@ -5890,6 +5892,66 @@ static int dahdi_answer(struct ast_channel *ast)
return res;
}
+static void disable_dtmf_detect(struct dahdi_pvt *p)
+{
+ int val = 0;
+
+ p->ignoredtmf = 1;
+
+ ioctl(p->subs[SUB_REAL].dfd, DAHDI_TONEDETECT, &val);
+
+ if (!p->hardwaredtmf && p->dsp) {
+ p->dsp_features &= ~DSP_FEATURE_DIGIT_DETECT;
+ ast_dsp_set_features(p->dsp, p->dsp_features);
+ }
+}
+
+static void enable_dtmf_detect(struct dahdi_pvt *p)
+{
+ int val = DAHDI_TONEDETECT_ON | DAHDI_TONEDETECT_MUTE;
+
+ if (p->channel == CHAN_PSEUDO)
+ return;
+
+ p->ignoredtmf = 0;
+
+ ioctl(p->subs[SUB_REAL].dfd, DAHDI_TONEDETECT, &val);
+
+ if (!p->hardwaredtmf && p->dsp) {
+ p->dsp_features |= DSP_FEATURE_DIGIT_DETECT;
+ ast_dsp_set_features(p->dsp, p->dsp_features);
+ }
+}
+
+static int dahdi_queryoption(struct ast_channel *chan, int option, void *data, int *datalen)
+{
+ char *cp;
+ struct dahdi_pvt *p = chan->tech_pvt;
+
+ /* all supported options require data */
+ if (!data || (*datalen < 1)) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ switch (option) {
+ case AST_OPTION_DIGIT_DETECT:
+ cp = (char *) data;
+ *cp = p->ignoredtmf ? 0 : 1;
+ ast_debug(1, "Reporting digit detection %sabled on %s\n", *cp ? "en" : "dis", chan->name);
+ break;
+ case AST_OPTION_FAX_DETECT:
+ cp = (char *) data;
+ *cp = (p->callprogress & CALLPROGRESS_FAX) ? 0 : 1;
+ ast_debug(1, "Reporting fax tone detection %sabled on %s\n", *cp ? "en" : "dis", chan->name);
+ break;
+ }
+
+ errno = 0;
+
+ return 0;
+}
+
static int dahdi_setoption(struct ast_channel *chan, int option, void *data, int datalen)
{
char *cp;
@@ -6072,6 +6134,29 @@ static int dahdi_setoption(struct ast_channel *chan, int option, void *data, int
dahdi_disable_ec(p);
}
break;
+ case AST_OPTION_DIGIT_DETECT:
+ cp = (char *) data;
+ ast_debug(1, "%sabling digit detection on %s\n", *cp ? "En" : "Dis", chan->name);
+ if (*cp) {
+ enable_dtmf_detect(p);
+ } else {
+ disable_dtmf_detect(p);
+ }
+ break;
+ case AST_OPTION_FAX_DETECT:
+ cp = (char *) data;
+ if (p->dsp) {
+ ast_debug(1, "%sabling fax tone detection on %s\n", *cp ? "En" : "Dis", chan->name);
+ if (*cp) {
+ p->callprogress |= CALLPROGRESS_FAX;
+ p->dsp_features |= DSP_FEATURE_FAX_DETECT;
+ } else {
+ p->callprogress &= ~CALLPROGRESS_FAX;
+ p->dsp_features &= ~DSP_FEATURE_FAX_DETECT;
+ }
+ ast_dsp_set_features(p->dsp, p->dsp_features);
+ }
+ break;
default:
return -1;
}
@@ -6279,39 +6364,6 @@ static void dahdi_link(struct dahdi_pvt *slave, struct dahdi_pvt *master) {
ast_debug(1, "Making %d slave to master %d at %d\n", slave->channel, master->channel, x);
}
-static void disable_dtmf_detect(struct dahdi_pvt *p)
-{
- int val;
-
- p->ignoredtmf = 1;
-
- val = 0;
- ioctl(p->subs[SUB_REAL].dfd, DAHDI_TONEDETECT, &val);
-
- if (!p->hardwaredtmf && p->dsp) {
- p->dsp_features &= ~DSP_FEATURE_DIGIT_DETECT;
- ast_dsp_set_features(p->dsp, p->dsp_features);
- }
-}
-
-static void enable_dtmf_detect(struct dahdi_pvt *p)
-{
- int val;
-
- if (p->channel == CHAN_PSEUDO)
- return;
-
- p->ignoredtmf = 0;
-
- val = DAHDI_TONEDETECT_ON | DAHDI_TONEDETECT_MUTE;
- ioctl(p->subs[SUB_REAL].dfd, DAHDI_TONEDETECT, &val);
-
- if (!p->hardwaredtmf && p->dsp) {
- p->dsp_features |= DSP_FEATURE_DIGIT_DETECT;
- ast_dsp_set_features(p->dsp, p->dsp_features);
- }
-}
-
static enum ast_bridge_result dahdi_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms)
{
struct ast_channel *who;
@@ -6814,6 +6866,10 @@ static void dahdi_handle_dtmfup(struct ast_channel *ast, int idx, struct ast_fra
}
}
p->faxhandled = 1;
+ p->callprogress &= ~CALLPROGRESS_FAX;
+ p->dsp_features &= ~DSP_FEATURE_FAX_DETECT;
+ ast_dsp_set_features(p->dsp, p->dsp_features);
+ ast_debug(1, "Disabling FAX tone detection on %s after tone received\n", ast->name);
if (strcmp(ast->exten, "fax")) {
const char *target_context = S_OR(ast->macrocontext, ast->context);