diff options
author | Richard Mudgett <rmudgett@digium.com> | 2012-09-27 22:25:34 +0000 |
---|---|---|
committer | Richard Mudgett <rmudgett@digium.com> | 2012-09-27 22:25:34 +0000 |
commit | 02ed1bd638e2c84f86c2456c3ef0d5b91bf96cf7 (patch) | |
tree | 75f1cc45f6353457904aac0a377dda383da0446f /apps/app_senddtmf.c | |
parent | 9f55e5e92808ad2fcc6c1ffcf53f1a06fe585c93 (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.c | 63 |
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; } |