]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Merged revisions 373946 via svnmerge from
authorAutomerge script <automerge@asterisk.org>
Thu, 27 Sep 2012 22:21:54 +0000 (22:21 +0000)
committerAutomerge script <automerge@asterisk.org>
Thu, 27 Sep 2012 22:21:54 +0000 (22:21 +0000)
file:///srv/subversion/repos/asterisk/branches/10

................
  r373946 | rmudgett | 2012-09-27 17:12:47 -0500 (Thu, 27 Sep 2012) | 14 lines

  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-digiumphones@373964 65c4cc65-6c06-0410-ace0-fbb531ad65f3

apps/app_senddtmf.c

index 5c8425a0f3428df93bc33c6d66f2b992bcc6bfd0..e1e8ee92f0435a17e8da2bea1911dc8e351a8b3b 100644 (file)
  * \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;
 }