summaryrefslogtreecommitdiff
path: root/apps/app_senddtmf.c
diff options
context:
space:
mode:
authorRichard Mudgett <rmudgett@digium.com>2012-09-27 22:25:34 +0000
committerRichard Mudgett <rmudgett@digium.com>2012-09-27 22:25:34 +0000
commit02ed1bd638e2c84f86c2456c3ef0d5b91bf96cf7 (patch)
tree75f1cc45f6353457904aac0a377dda383da0446f /apps/app_senddtmf.c
parent9f55e5e92808ad2fcc6c1ffcf53f1a06fe585c93 (diff)
Fix SendDTMF crash and channel reference leak using channel name parameter.
The SendDTMF channel name parameter has two issues. 1) Crashes if the channel name does not exist. 2) Leaks a channel reference if the channel is the current channel. Problem introduced by ASTERISK-15956. * Updated SendDTMF documentation. * Renamed app to senddtmf_name and tweaked the type. ........ Merged revisions 373945 from http://svn.asterisk.org/svn/asterisk/branches/1.8 ........ Merged revisions 373946 from http://svn.asterisk.org/svn/asterisk/branches/10 ........ Merged revisions 373954 from http://svn.asterisk.org/svn/asterisk/branches/11 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@373965 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'apps/app_senddtmf.c')
-rw-r--r--apps/app_senddtmf.c63
1 files changed, 37 insertions, 26 deletions
diff --git a/apps/app_senddtmf.c b/apps/app_senddtmf.c
index 5c8425a0f..e1e8ee92f 100644
--- a/apps/app_senddtmf.c
+++ b/apps/app_senddtmf.c
@@ -21,14 +21,14 @@
* \brief App to send DTMF digits
*
* \author Mark Spencer <markster@digium.com>
- *
+ *
* \ingroup applications
*/
/*** MODULEINFO
<support_level>core</support_level>
***/
-
+
#include "asterisk.h"
ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
@@ -46,7 +46,9 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
</synopsis>
<syntax>
<parameter name="digits" required="true">
- <para>List of digits 0-9,*#,abcd</para>
+ <para>List of digits 0-9,*#,a-d,A-D to send also w for a half second pause,
+ and f or F for a flash-hook if the channel supports
+ flash-hook.</para>
</parameter>
<parameter name="timeout_ms" required="false">
<para>Amount of time to wait in ms between tones. (defaults to .25s)</para>
@@ -54,13 +56,12 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
<parameter name="duration_ms" required="false">
<para>Duration of each digit</para>
</parameter>
- <parameter name="channel" required="false">
- <para>Channel where digits will be played</para>
- </parameter>
+ <parameter name="channel" required="false">
+ <para>Channel where digits will be played</para>
+ </parameter>
</syntax>
<description>
- <para>DTMF digits sent to a channel with half second pause</para>
- <para>It will pass all digits or terminate if it encounters an error.</para>
+ <para>It will send all digits or terminate if it encounters an error.</para>
</description>
<see-also>
<ref type="application">Read</ref>
@@ -84,14 +85,17 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
</description>
</manager>
***/
-static char *app = "SendDTMF";
+
+static const char senddtmf_name[] = "SendDTMF";
static int senddtmf_exec(struct ast_channel *chan, const char *vdata)
{
- int res = 0;
+ int res;
char *data;
int dinterval = 0, duration = 0;
- struct ast_channel *dchan;
+ struct ast_channel *chan_found = NULL;
+ struct ast_channel *chan_dest = chan;
+ struct ast_channel *chan_autoservice = NULL;
AST_DECLARE_APP_ARGS(args,
AST_APP_ARG(digits);
AST_APP_ARG(dinterval);
@@ -100,15 +104,17 @@ static int senddtmf_exec(struct ast_channel *chan, const char *vdata)
);
if (ast_strlen_zero(vdata)) {
- ast_log(LOG_WARNING, "SendDTMF requires an argument (digits or *#aAbBcCdD)\n");
+ ast_log(LOG_WARNING, "SendDTMF requires an argument\n");
return 0;
}
- dchan = chan;
-
data = ast_strdupa(vdata);
AST_STANDARD_APP_ARGS(args, data);
+ if (ast_strlen_zero(args.digits)) {
+ ast_log(LOG_WARNING, "The digits argument is required (0-9,*#,a-d,A-D,wfF)\n");
+ return 0;
+ }
if (!ast_strlen_zero(args.dinterval)) {
ast_app_parse_timelen(args.dinterval, &dinterval, TIMELEN_MILLISECONDS);
}
@@ -116,18 +122,23 @@ static int senddtmf_exec(struct ast_channel *chan, const char *vdata)
ast_app_parse_timelen(args.duration, &duration, TIMELEN_MILLISECONDS);
}
if (!ast_strlen_zero(args.channel)) {
- dchan = ast_channel_get_by_name(args.channel);
- }
- if (dchan != chan) {
- ast_autoservice_start(chan);
+ chan_found = ast_channel_get_by_name(args.channel);
+ if (!chan_found) {
+ ast_log(LOG_WARNING, "No such channel: %s\n", args.channel);
+ return 0;
+ }
+ chan_dest = chan_found;
+ if (chan_found != chan) {
+ chan_autoservice = chan;
+ }
}
- res = ast_dtmf_stream(dchan, NULL, args.digits, dinterval <= 0 ? 250 : dinterval, duration);
- if (dchan != chan) {
- ast_autoservice_stop(chan);
- ast_channel_unref(dchan);
+ res = ast_dtmf_stream(chan_dest, chan_autoservice, args.digits,
+ dinterval <= 0 ? 250 : dinterval, duration);
+ if (chan_found) {
+ ast_channel_unref(chan_found);
}
- return res;
+ return chan_autoservice ? 0 : res;
}
static int manager_play_dtmf(struct mansession *s, const struct message *m)
@@ -160,10 +171,10 @@ static int unload_module(void)
{
int res;
- res = ast_unregister_application(app);
+ res = ast_unregister_application(senddtmf_name);
res |= ast_manager_unregister("PlayDTMF");
- return res;
+ return res;
}
static int load_module(void)
@@ -171,7 +182,7 @@ static int load_module(void)
int res;
res = ast_manager_register_xml("PlayDTMF", EVENT_FLAG_CALL, manager_play_dtmf);
- res |= ast_register_application_xml(app, senddtmf_exec);
+ res |= ast_register_application_xml(senddtmf_name, senddtmf_exec);
return res;
}