Merged revisions 310587 via svnmerge from
authorJonathan Rose <jrose@digium.com>
Mon, 14 Mar 2011 15:40:43 +0000 (15:40 +0000)
committerJonathan Rose <jrose@digium.com>
Mon, 14 Mar 2011 15:40:43 +0000 (15:40 +0000)
https://origsvn.digium.com/svn/asterisk/branches/1.8

................
  r310587 | jrose | 2011-03-14 10:27:57 -0500 (Mon, 14 Mar 2011) | 15 lines

  Merged revisions 310585 via svnmerge from
  https://origsvn.digium.com/svn/asterisk/branches/1.6.2

  ........
    r310585 | jrose | 2011-03-14 08:56:22 -0500 (Mon, 14 Mar 2011) | 8 lines

    Adds 'p' as an option to func_volume.  When it is on, the old behavior with DTMF controlling volume adjustment will be enforced.
    When it is off, DTMF will not be processed by the function.

    Programmed by Jonathan Rose
    Reviewed by David Vossel, Leif Madsen, and Russell Bryant

    http://reviewboard.digium.internal/r/93/
  ........
................

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@310588 65c4cc65-6c06-0410-ace0-fbb531ad65f3

funcs/func_volume.c

index e94a4ed..938fbba 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Asterisk -- An open source telephony toolkit.
  *
 /*
  * Asterisk -- An open source telephony toolkit.
  *
- * Copyright (C) 2007, Digium, Inc.
+ * Copyright (C) 2011, Digium, Inc.
  *
  * Joshua Colp <jcolp@digium.com> 
  *
  *
  * Joshua Colp <jcolp@digium.com> 
  *
@@ -35,6 +35,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/pbx.h"
 #include "asterisk/utils.h"
 #include "asterisk/audiohook.h"
 #include "asterisk/pbx.h"
 #include "asterisk/utils.h"
 #include "asterisk/audiohook.h"
+#include "asterisk/app.h"
 
 /*** DOCUMENTATION
        <function name="VOLUME" language="en_US">
 
 /*** DOCUMENTATION
        <function name="VOLUME" language="en_US">
@@ -45,6 +46,13 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
                        <parameter name="direction" required="true">
                                <para>Must be <literal>TX</literal> or <literal>RX</literal>.</para>
                        </parameter>
                        <parameter name="direction" required="true">
                                <para>Must be <literal>TX</literal> or <literal>RX</literal>.</para>
                        </parameter>
+                       <parameter name="options">
+                               <optionlist>
+                                       <option name="p">
+                                               <para>Enable DTMF volume control</para>
+                                       </option>
+                               </optionlist>
+                       </parameter>
                </syntax>
                <description>
                        <para>The VOLUME function can be used to increase or decrease the <literal>tx</literal> or
                </syntax>
                <description>
                        <para>The VOLUME function can be used to increase or decrease the <literal>tx</literal> or
@@ -52,6 +60,8 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
                        <para>For example:</para>
                        <para>Set(VOLUME(TX)=3)</para>
                        <para>Set(VOLUME(RX)=2)</para>
                        <para>For example:</para>
                        <para>Set(VOLUME(TX)=3)</para>
                        <para>Set(VOLUME(RX)=2)</para>
+                       <para>Set(VOLUME(TX,p)=3)</para>
+                       <para>Set(VOLUME(RX,p)=3></para>
                </description>
        </function>
  ***/
                </description>
        </function>
  ***/
@@ -60,8 +70,17 @@ struct volume_information {
        struct ast_audiohook audiohook;
        int tx_gain;
        int rx_gain;
        struct ast_audiohook audiohook;
        int tx_gain;
        int rx_gain;
+       unsigned int flags;
+};
+
+enum volume_flags {
+       VOLUMEFLAG_CHANGE = (1 << 1),
 };
 
 };
 
+AST_APP_OPTIONS(volume_opts, {
+       AST_APP_OPTION('p', VOLUMEFLAG_CHANGE),
+});
+
 static void destroy_callback(void *data)
 {
        struct volume_information *vi = data;
 static void destroy_callback(void *data)
 {
        struct volume_information *vi = data;
@@ -96,18 +115,23 @@ static int volume_callback(struct ast_audiohook *audiohook, struct ast_channel *
        vi = datastore->data;
 
        /* If this is DTMF then allow them to increase/decrease the gains */
        vi = datastore->data;
 
        /* If this is DTMF then allow them to increase/decrease the gains */
-       if (frame->frametype == AST_FRAME_DTMF) {
-               /* Only use DTMF coming from the source... not going to it */
-               if (direction != AST_AUDIOHOOK_DIRECTION_READ)
-                       return 0;
-               if (frame->subclass.integer == '*') {
-                       vi->tx_gain += 1;
-                       vi->rx_gain += 1;
-               } else if (frame->subclass.integer == '#') {
-                       vi->tx_gain -= 1;
-                       vi->rx_gain -= 1;
+       if (ast_test_flag(vi, VOLUMEFLAG_CHANGE)) {
+               if (frame->frametype == AST_FRAME_DTMF) {
+                       /* Only use DTMF coming from the source... not going to it */
+                       if (direction != AST_AUDIOHOOK_DIRECTION_READ)
+                               return 0; 
+                       if (frame->subclass.integer == '*') {
+                               vi->tx_gain += 1;
+                               vi->rx_gain += 1;
+                       } else if (frame->subclass.integer == '#') {
+                               vi->tx_gain -= 1;
+                               vi->rx_gain -= 1;
+                       }
                }
                }
-       } else if (frame->frametype == AST_FRAME_VOICE) {
+       }
+
+       
+       if (frame->frametype == AST_FRAME_VOICE) {
                /* Based on direction of frame grab the gain, and confirm it is applicable */
                if (!(gain = (direction == AST_AUDIOHOOK_DIRECTION_READ) ? &vi->rx_gain : &vi->tx_gain) || !*gain)
                        return 0;
                /* Based on direction of frame grab the gain, and confirm it is applicable */
                if (!(gain = (direction == AST_AUDIOHOOK_DIRECTION_READ) ? &vi->rx_gain : &vi->tx_gain) || !*gain)
                        return 0;
@@ -124,7 +148,18 @@ static int volume_write(struct ast_channel *chan, const char *cmd, char *data, c
        struct volume_information *vi = NULL;
        int is_new = 0;
 
        struct volume_information *vi = NULL;
        int is_new = 0;
 
+       /* Separate options from argument */
+       
+       AST_DECLARE_APP_ARGS(args,
+               AST_APP_ARG(direction);
+               AST_APP_ARG(options);
+       );
+       
+       AST_STANDARD_APP_ARGS(args, data);
+
+       ast_channel_lock(chan);
        if (!(datastore = ast_channel_datastore_find(chan, &volume_datastore, NULL))) {
        if (!(datastore = ast_channel_datastore_find(chan, &volume_datastore, NULL))) {
+               ast_channel_unlock(chan);
                /* Allocate a new datastore to hold the reference to this volume and audiohook information */
                if (!(datastore = ast_datastore_alloc(&volume_datastore, NULL)))
                        return 0;
                /* Allocate a new datastore to hold the reference to this volume and audiohook information */
                if (!(datastore = ast_datastore_alloc(&volume_datastore, NULL)))
                        return 0;
@@ -137,21 +172,42 @@ static int volume_write(struct ast_channel *chan, const char *cmd, char *data, c
                ast_set_flag(&vi->audiohook, AST_AUDIOHOOK_WANTS_DTMF);
                is_new = 1;
        } else {
                ast_set_flag(&vi->audiohook, AST_AUDIOHOOK_WANTS_DTMF);
                is_new = 1;
        } else {
+               ast_channel_unlock(chan);
                vi = datastore->data;
        }
 
        /* Adjust gain on volume information structure */
                vi = datastore->data;
        }
 
        /* Adjust gain on volume information structure */
-       if (!strcasecmp(data, "tx"))
-               vi->tx_gain = atoi(value);
-       else if (!strcasecmp(data, "rx"))
+       if (ast_strlen_zero(args.direction)) {
+               ast_log(LOG_ERROR, "Direction must be specified for VOLUME function\n");
+               return -1;
+       }
+
+       if (!strcasecmp(args.direction, "tx")) { 
+               vi->tx_gain = atoi(value); 
+       } else if (!strcasecmp(args.direction, "rx")) {
                vi->rx_gain = atoi(value);
                vi->rx_gain = atoi(value);
+       } else {
+               ast_log(LOG_ERROR, "Direction must be either RX or TX\n");
+       }
 
        if (is_new) {
                datastore->data = vi;
 
        if (is_new) {
                datastore->data = vi;
+               ast_channel_lock(chan);
                ast_channel_datastore_add(chan, datastore);
                ast_channel_datastore_add(chan, datastore);
+               ast_channel_unlock(chan);
                ast_audiohook_attach(chan, &vi->audiohook);
        }
 
                ast_audiohook_attach(chan, &vi->audiohook);
        }
 
+       /* Add Option data to struct */
+       
+       if (!ast_strlen_zero(args.options)) {
+               struct ast_flags flags = { 0 };
+               ast_app_parse_options(volume_opts, &flags, &data, args.options);
+               vi->flags = flags.flags;
+       } else { 
+               vi->flags = 0; 
+       }
+
        return 0;
 }
 
        return 0;
 }