From: Richard Mudgett Date: Thu, 27 Sep 2012 22:12:47 +0000 (+0000) Subject: Fix SendDTMF crash and channel reference leak using channel name parameter. X-Git-Tag: 10.10.0-rc1~23 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=efb9b8eabc1bda052176ebcfac230c5ca389a3e3;p=thirdparty%2Fasterisk.git 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 git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/10@373946 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- diff --git a/apps/app_senddtmf.c b/apps/app_senddtmf.c index 5c8425a0f3..e1e8ee92f0 100644 --- a/apps/app_senddtmf.c +++ b/apps/app_senddtmf.c @@ -21,14 +21,14 @@ * \brief App to send DTMF digits * * \author Mark Spencer - * + * * \ingroup applications */ /*** MODULEINFO core ***/ - + #include "asterisk.h" ASTERISK_FILE_VERSION(__FILE__, "$Revision$") @@ -46,7 +46,9 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") - List of digits 0-9,*#,abcd + 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. Amount of time to wait in ms between tones. (defaults to .25s) @@ -54,13 +56,12 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") Duration of each digit - - Channel where digits will be played - + + Channel where digits will be played + - DTMF digits sent to a channel with half second pause - It will pass all digits or terminate if it encounters an error. + It will send all digits or terminate if it encounters an error. Read @@ -84,14 +85,17 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") ***/ -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; }