[asterisk-commits] russell: trunk r412427 - in /trunk: ./ apps/ bridges/ funcs/ include/asterisk...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Apr 15 18:21:32 CDT 2014


Author: russell
Date: Tue Apr 15 18:21:19 2014
New Revision: 412427

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=412427
Log:
(mix)monitor: Add options to enable a periodic beep

Add an option to enable a periodic beep to be played into a call if it
is being recorded.  If enabled, it uses the PERIODIC_HOOK() function
internally to play the 'beep' prompt into the call at a specified
interval.  This option is provided for both Monitor() and
MixMonitor().

Review: https://reviewboard.asterisk.org/r/3424/

Added:
    trunk/include/asterisk/beep.h   (with props)
Modified:
    trunk/CHANGES
    trunk/apps/app_mixmonitor.c
    trunk/apps/app_queue.c
    trunk/bridges/bridge_builtin_features.c
    trunk/funcs/func_periodic_hook.c
    trunk/include/asterisk/monitor.h
    trunk/res/res_monitor.c

Modified: trunk/CHANGES
URL: http://svnview.digium.com/svn/asterisk/trunk/CHANGES?view=diff&rev=412427&r1=412426&r2=412427
==============================================================================
--- trunk/CHANGES (original)
+++ trunk/CHANGES Tue Apr 15 18:21:19 2014
@@ -16,6 +16,8 @@
 --------------------------
  * Record application now has an option 'o' which allows 0 to act as an exit
    key setting the RECORD_STATUS variable to 'OPERATOR' instead of 'DTMF'
+ * Monitor() - A new option, B(), has been added that will turn on a periodic
+   beep while the call is being recorded.
 
 Functions
 --------------------------
@@ -85,6 +87,8 @@
 -------------------------
  * A new function, MIXMONITOR, has been added to allow access to individual
    instances of MixMonitor on a channel.
+ * A new option, B(), has been added that will turn on a periodic beep while the
+   call is being recorded.
 
 
 Channel Drivers

Modified: trunk/apps/app_mixmonitor.c
URL: http://svnview.digium.com/svn/asterisk/trunk/apps/app_mixmonitor.c?view=diff&rev=412427&r1=412426&r2=412427
==============================================================================
--- trunk/apps/app_mixmonitor.c (original)
+++ trunk/apps/app_mixmonitor.c Tue Apr 15 18:21:19 2014
@@ -57,6 +57,7 @@
 #include "asterisk/linkedlists.h"
 #include "asterisk/test.h"
 #include "asterisk/mixmonitor.h"
+#include "asterisk/beep.h"
 
 /*** DOCUMENTATION
 	<application name="MixMonitor" language="en_US">
@@ -82,6 +83,10 @@
 						<note><para>If you utilize this option inside a Local channel, you must make sure the Local
 						channel is not optimized away. To do this, be sure to call your Local channel with the
 						<literal>/n</literal> option. For example: Dial(Local/start at mycontext/n)</para></note>
+					</option>
+					<option name="B">
+						<para>Play a periodic beep while this call is being recorded.</para>
+						<argument name="interval"><para>Interval, in seconds. Default is 15.</para></argument>
 					</option>
 					<option name="v">
 						<para>Adjust the <emphasis>heard</emphasis> volume by a factor of <replaceable>x</replaceable>
@@ -319,6 +324,7 @@
 	MUXFLAG_COMBINED = (1 << 8),
 	MUXFLAG_UID = (1 << 9),
 	MUXFLAG_VMRECIPIENTS = (1 << 10),
+	MUXFLAG_BEEP = (1 << 11),
 };
 
 enum mixmonitor_args {
@@ -329,12 +335,14 @@
 	OPT_ARG_READNAME,
 	OPT_ARG_UID,
 	OPT_ARG_VMRECIPIENTS,
+	OPT_ARG_BEEP_INTERVAL,
 	OPT_ARG_ARRAY_SIZE,	/* Always last element of the enum */
 };
 
 AST_APP_OPTIONS(mixmonitor_opts, {
 	AST_APP_OPTION('a', MUXFLAG_APPEND),
 	AST_APP_OPTION('b', MUXFLAG_BRIDGED),
+	AST_APP_OPTION_ARG('B', MUXFLAG_BEEP, OPT_ARG_BEEP_INTERVAL),
 	AST_APP_OPTION_ARG('v', MUXFLAG_READVOLUME, OPT_ARG_READVOLUME),
 	AST_APP_OPTION_ARG('V', MUXFLAG_WRITEVOLUME, OPT_ARG_WRITEVOLUME),
 	AST_APP_OPTION_ARG('W', MUXFLAG_VOLUME, OPT_ARG_VOLUME),
@@ -361,6 +369,7 @@
 
 	unsigned int samp_rate;
 	char *filename;
+	char *beep_id;
 };
 
 /*!
@@ -405,6 +414,7 @@
 	mixmonitor_ds->audiohook = NULL;
 	mixmonitor_ds->destruction_ok = 1;
 	ast_free(mixmonitor_ds->filename);
+	ast_free(mixmonitor_ds->beep_id);
 	ast_cond_signal(&mixmonitor_ds->destruction_condition);
 	ast_mutex_unlock(&mixmonitor_ds->lock);
 }
@@ -772,7 +782,7 @@
 	return NULL;
 }
 
-static int setup_mixmonitor_ds(struct mixmonitor *mixmonitor, struct ast_channel *chan, char **datastore_id)
+static int setup_mixmonitor_ds(struct mixmonitor *mixmonitor, struct ast_channel *chan, char **datastore_id, const char *beep_id)
 {
 	struct ast_datastore *datastore = NULL;
 	struct mixmonitor_ds *mixmonitor_ds;
@@ -799,6 +809,9 @@
 	mixmonitor_ds->samp_rate = 8000;
 	mixmonitor_ds->audiohook = &mixmonitor->audiohook;
 	mixmonitor_ds->filename = ast_strdup(mixmonitor->filename);
+	if (!ast_strlen_zero(beep_id)) {
+		mixmonitor_ds->beep_id = ast_strdup(beep_id);
+	}
 	datastore->data = mixmonitor_ds;
 
 	ast_channel_lock(chan);
@@ -813,7 +826,7 @@
 				  unsigned int flags, int readvol, int writevol,
 				  const char *post_process, const char *filename_write,
 				  char *filename_read, const char *uid_channel_var,
-				  const char *recipients)
+				  const char *recipients, const char *beep_id)
 {
 	pthread_t thread;
 	struct mixmonitor *mixmonitor;
@@ -872,7 +885,7 @@
 		mixmonitor->filename_read = ast_strdup(filename_read);
 	}
 
-	if (setup_mixmonitor_ds(mixmonitor, chan, &datastore_id)) {
+	if (setup_mixmonitor_ds(mixmonitor, chan, &datastore_id, beep_id)) {
 		ast_autochan_destroy(mixmonitor->autochan);
 		mixmonitor_free(mixmonitor);
 		ast_free(datastore_id);
@@ -973,6 +986,7 @@
 	char *filename_write = NULL;
 	char filename_buffer[1024] = "";
 	char *uid_channel_var = NULL;
+	char beep_id[64] = "";
 
 	struct ast_flags flags = { 0 };
 	char *recipients = NULL;
@@ -1045,6 +1059,21 @@
 
 		if (ast_test_flag(&flags, MUXFLAG_UID)) {
 			uid_channel_var = opts[OPT_ARG_UID];
+		}
+
+		if (ast_test_flag(&flags, MUXFLAG_BEEP)) {
+			const char *interval_str = S_OR(opts[OPT_ARG_BEEP_INTERVAL], "15");
+			unsigned int interval = 15;
+
+			if (sscanf(interval_str, "%30u", &interval) != 1) {
+				ast_log(LOG_WARNING, "Invalid interval '%s' for periodic beep. Using default of %u\n",
+						interval_str, interval);
+			}
+
+			if (ast_beep_start(chan, interval, beep_id, sizeof(beep_id))) {
+				ast_log(LOG_WARNING, "Unable to enable periodic beep, please ensure func_periodic_hook is loaded.\n");
+				return -1;
+			}
 		}
 	}
 	/* If there are no file writing arguments/options for the mix monitor, send a warning message and return -1 */
@@ -1072,7 +1101,8 @@
 			filename_write,
 			filename_read,
 			uid_channel_var,
-			recipients)) {
+			recipients,
+			beep_id)) {
 		ast_module_unref(ast_module_info->self);
 	}
 
@@ -1084,6 +1114,7 @@
 	struct ast_datastore *datastore = NULL;
 	char *parse = "";
 	struct mixmonitor_ds *mixmonitor_ds;
+	const char *beep_id = NULL;
 
 	AST_DECLARE_APP_ARGS(args,
 		AST_APP_ARG(mixmonid);
@@ -1123,6 +1154,10 @@
 		mixmonitor_ds->audiohook = NULL;
 	}
 
+	if (!ast_strlen_zero(mixmonitor_ds->beep_id)) {
+		beep_id = ast_strdupa(mixmonitor_ds->beep_id);
+	}
+
 	ast_mutex_unlock(&mixmonitor_ds->lock);
 
 	/* Remove the datastore so the monitor thread can exit */
@@ -1130,6 +1165,10 @@
 		ast_datastore_free(datastore);
 	}
 	ast_channel_unlock(chan);
+
+	if (!ast_strlen_zero(beep_id)) {
+		ast_beep_stop(chan, beep_id);
+	}
 
 	return 0;
 }

Modified: trunk/apps/app_queue.c
URL: http://svnview.digium.com/svn/asterisk/trunk/apps/app_queue.c?view=diff&rev=412427&r1=412426&r2=412427
==============================================================================
--- trunk/apps/app_queue.c (original)
+++ trunk/apps/app_queue.c Tue Apr 15 18:21:19 2014
@@ -6562,13 +6562,13 @@
 				}
 				ast_channel_unlock(qe->chan);
 				if (monitorfilename) {
-					ast_monitor_start(which, qe->parent->monfmt, monitorfilename, 1, X_REC_IN | X_REC_OUT);
+					ast_monitor_start(which, qe->parent->monfmt, monitorfilename, 1, X_REC_IN | X_REC_OUT, NULL);
 				} else if (qe->chan) {
-					ast_monitor_start(which, qe->parent->monfmt, ast_channel_uniqueid(qe->chan), 1, X_REC_IN | X_REC_OUT);
+					ast_monitor_start(which, qe->parent->monfmt, ast_channel_uniqueid(qe->chan), 1, X_REC_IN | X_REC_OUT, NULL);
 				} else {
 					/* Last ditch effort -- no channel, make up something */
 					snprintf(tmpid, sizeof(tmpid), "chan-%lx", ast_random());
-					ast_monitor_start(which, qe->parent->monfmt, tmpid, 1, X_REC_IN | X_REC_OUT);
+					ast_monitor_start(which, qe->parent->monfmt, tmpid, 1, X_REC_IN | X_REC_OUT, NULL);
 				}
 				if (!ast_strlen_zero(monexec)) {
 					ast_monitor_setjoinfiles(which, 1);

Modified: trunk/bridges/bridge_builtin_features.c
URL: http://svnview.digium.com/svn/asterisk/trunk/bridges/bridge_builtin_features.c?view=diff&rev=412427&r1=412426&r2=412427
==============================================================================
--- trunk/bridges/bridge_builtin_features.c (original)
+++ trunk/bridges/bridge_builtin_features.c Tue Apr 15 18:21:19 2014
@@ -196,7 +196,7 @@
 
 	ast_verb(3, "AutoMonitor used to record call. Filename: %s\n", touch_filename);
 
-	if (ast_monitor_start(peer_chan, touch_format, touch_filename, 1, X_REC_IN | X_REC_OUT)) {
+	if (ast_monitor_start(peer_chan, touch_format, touch_filename, 1, X_REC_IN | X_REC_OUT, NULL)) {
 		ast_verb(3, "automon feature was tried by '%s' but monitor failed to start.\n",
 			ast_channel_name(bridge_channel->chan));
 		return;

Modified: trunk/funcs/func_periodic_hook.c
URL: http://svnview.digium.com/svn/asterisk/trunk/funcs/func_periodic_hook.c?view=diff&rev=412427&r1=412426&r2=412427
==============================================================================
--- trunk/funcs/func_periodic_hook.c (original)
+++ trunk/funcs/func_periodic_hook.c Tue Apr 15 18:21:19 2014
@@ -42,6 +42,8 @@
 #include "asterisk/pbx.h"
 #include "asterisk/app.h"
 #include "asterisk/audiohook.h"
+#define AST_API_MODULE
+#include "asterisk/beep.h"
 
 /*** DOCUMENTATION
 	<function name="PERIODIC_HOOK" language="en_US">
@@ -93,6 +95,8 @@
 static const char exten_name[] = "hook";
 static const char full_exten_name[] = "hook at __func_periodic_hook_context__";
 
+static const char beep_exten[] = "beep";
+
 /*!
  * \brief Last used hook ID
  *
@@ -485,9 +489,35 @@
 	ast_add_extension(context_name, 1, exten_name, 6, "", "",
 			"ChanSpy", "${ChannelToSpy},qEB", NULL, AST_MODULE);
 
+	res = ast_add_extension(context_name, 1, beep_exten, 1, "", "",
+			"Answer", "", NULL, AST_MODULE);
+	res |= ast_add_extension(context_name, 1, beep_exten, 2, "", "",
+			"Playback", "beep", NULL, AST_MODULE);
+
 	res = ast_custom_function_register_escalating(&hook_function, AST_CFE_BOTH);
 
 	return res ? AST_MODULE_LOAD_DECLINE : AST_MODULE_LOAD_SUCCESS;
 }
 
+int AST_OPTIONAL_API_NAME(ast_beep_start)(struct ast_channel *chan,
+		unsigned int interval, char *beep_id, size_t len)
+{
+	char args[AST_MAX_EXTENSION + AST_MAX_CONTEXT + 32];
+
+	snprintf(args, sizeof(args), "%s,%s,%u",
+			context_name, beep_exten, interval);
+
+	if (hook_read(chan, NULL, args, beep_id, len)) {
+		ast_log(LOG_WARNING, "Failed to enable periodic beep.\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+int AST_OPTIONAL_API_NAME(ast_beep_stop)(struct ast_channel *chan, const char *beep_id)
+{
+	return hook_write(chan, NULL, (char *) beep_id, "off");
+}
+
 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Periodic dialplan hooks.");

Added: trunk/include/asterisk/beep.h
URL: http://svnview.digium.com/svn/asterisk/trunk/include/asterisk/beep.h?view=auto&rev=412427
==============================================================================
--- trunk/include/asterisk/beep.h (added)
+++ trunk/include/asterisk/beep.h Tue Apr 15 18:21:19 2014
@@ -1,0 +1,45 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2014, Russell Bryant
+ *
+ * Russell Bryant <russell at russellbryant.net>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*!
+ * \file
+ * \brief Periodic beeps into the audio of a call
+ */
+
+#ifndef _ASTERISK_BEEP_H
+#define _ASTERISK_BEEP_H
+
+#include "asterisk/optional_api.h"
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+AST_OPTIONAL_API(int, ast_beep_start,
+		(struct ast_channel *chan, unsigned int interval, char *beep_id, size_t len),
+		{ return -1; });
+
+AST_OPTIONAL_API(int, ast_beep_stop,
+		(struct ast_channel *chan, const char *beep_id),
+		{ return -1; });
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ASTERISK_BEEP_H */

Propchange: trunk/include/asterisk/beep.h
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: trunk/include/asterisk/beep.h
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: trunk/include/asterisk/beep.h
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: trunk/include/asterisk/monitor.h
URL: http://svnview.digium.com/svn/asterisk/trunk/include/asterisk/monitor.h?view=diff&rev=412427&r1=412426&r2=412427
==============================================================================
--- trunk/include/asterisk/monitor.h (original)
+++ trunk/include/asterisk/monitor.h Tue Apr 15 18:21:19 2014
@@ -43,6 +43,7 @@
 	char read_filename[FILENAME_MAX];
 	char write_filename[FILENAME_MAX];
 	char filename_base[FILENAME_MAX];
+	char beep_id[64];
 	int filename_changed;
 	char *format;
 	int joinfiles;
@@ -53,7 +54,8 @@
 /* Start monitoring a channel */
 AST_OPTIONAL_API(int, ast_monitor_start,
 		 (struct ast_channel *chan, const char *format_spec,
-		  const char *fname_base, int need_lock, int stream_action),
+		  const char *fname_base, int need_lock, int stream_action,
+		  const char *beep_id),
 		 { return -1; });
 
 /* Stop monitoring a channel */

Modified: trunk/res/res_monitor.c
URL: http://svnview.digium.com/svn/asterisk/trunk/res/res_monitor.c?view=diff&rev=412427&r1=412426&r2=412427
==============================================================================
--- trunk/res/res_monitor.c (original)
+++ trunk/res/res_monitor.c Tue Apr 15 18:21:19 2014
@@ -50,6 +50,7 @@
 #include "asterisk/utils.h"
 #include "asterisk/config.h"
 #include "asterisk/options.h"
+#include "asterisk/beep.h"
 
 /*** DOCUMENTATION
 	<application name="Monitor" language="en_US">
@@ -83,6 +84,10 @@
 					</option>
 					<option name="b">
 						<para>Don't begin recording unless a call is bridged to another channel.</para>
+					</option>
+					<option name="B">
+						<para>Play a periodic beep while this call is being recorded.</para>
+						<argument name="interval"><para>Interval, in seconds. Default is 15.</para></argument>
 					</option>
 					<option name="i">
 						<para>Skip recording of input stream (disables <literal>m</literal> option).</para>
@@ -290,7 +295,8 @@
  * \retval -1 on failure
  */
 int AST_OPTIONAL_API_NAME(ast_monitor_start)(struct ast_channel *chan, const char *format_spec,
-					     const char *fname_base, int need_lock, int stream_action)
+					     const char *fname_base, int need_lock, int stream_action,
+					     const char *beep_id)
 {
 	int res = 0;
 	RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
@@ -307,6 +313,10 @@
 		if (!(monitor = ast_calloc(1, sizeof(*monitor)))) {
 			UNLOCK_IF_NEEDED(chan, need_lock);
 			return -1;
+		}
+
+		if (!ast_strlen_zero(beep_id)) {
+			ast_copy_string(monitor->beep_id, beep_id, sizeof(monitor->beep_id));
 		}
 
 		/* Determine file names */
@@ -511,7 +521,11 @@
 			if (ast_safe_system(tmp) == -1)
 				ast_log(LOG_WARNING, "Execute of %s failed.\n",tmp);
 		}
-		
+
+		if (!ast_strlen_zero(ast_channel_monitor(chan)->beep_id)) {
+			ast_beep_stop(chan, ast_channel_monitor(chan)->beep_id);
+		}
+
 		ast_free(ast_channel_monitor(chan)->format);
 		ast_free(ast_channel_monitor(chan));
 		ast_channel_monitor_set(chan, NULL);
@@ -644,6 +658,12 @@
 	MON_FLAG_MIX =      (1 << 1),
 	MON_FLAG_DROP_IN =  (1 << 2),
 	MON_FLAG_DROP_OUT = (1 << 3),
+	MON_FLAG_BEEP =     (1 << 4),
+};
+
+enum {
+	OPT_ARG_BEEP_INTERVAL,
+	OPT_ARG_ARRAY_SIZE,	/* Always last element of the enum */
 };
 
 AST_APP_OPTIONS(monitor_opts, {
@@ -651,6 +671,7 @@
 	AST_APP_OPTION('m', MON_FLAG_MIX),
 	AST_APP_OPTION('i', MON_FLAG_DROP_IN),
 	AST_APP_OPTION('o', MON_FLAG_DROP_OUT),
+	AST_APP_OPTION_ARG('B', MON_FLAG_BEEP, OPT_ARG_BEEP_INTERVAL),
 });
 
 /*!
@@ -672,6 +693,8 @@
 	int res = 0;
 	char *parse;
 	struct ast_flags flags = { 0 };
+	char *opts[OPT_ARG_ARRAY_SIZE] = { NULL, };
+	char beep_id[64] = "";
 	AST_DECLARE_APP_ARGS(args,
 		AST_APP_ARG(format);
 		AST_APP_ARG(fname_base);
@@ -688,7 +711,7 @@
 	AST_STANDARD_APP_ARGS(args, parse);
 
 	if (!ast_strlen_zero(args.options)) {
-		ast_app_parse_options(monitor_opts, &flags, NULL, args.options);
+		ast_app_parse_options(monitor_opts, &flags, opts, args.options);
 
 		if (ast_test_flag(&flags, MON_FLAG_MIX)) {
 			stream_action |= X_JOIN;
@@ -698,6 +721,20 @@
 		}
 		if (ast_test_flag(&flags, MON_FLAG_DROP_OUT)) {
 			stream_action &= ~X_REC_OUT;
+		}
+		if (ast_test_flag(&flags, MON_FLAG_BEEP)) {
+			const char *interval_str = S_OR(opts[OPT_ARG_BEEP_INTERVAL], "15");
+			unsigned int interval = 15;
+
+			if (sscanf(interval_str, "%30u", &interval) != 1) {
+				ast_log(LOG_WARNING, "Invalid interval '%s' for periodic beep. Using default of %u\n",
+						interval_str, interval);
+			}
+
+			if (ast_beep_start(chan, interval, beep_id, sizeof(beep_id))) {
+				ast_log(LOG_WARNING, "Unable to enable periodic beep, please ensure func_periodic_hook is loaded.\n");
+				return -1;
+			}
 		}
 	}
 
@@ -731,7 +768,7 @@
 		return 0;
 	}
 
-	res = ast_monitor_start(chan, args.format, args.fname_base, 1, stream_action);
+	res = ast_monitor_start(chan, args.format, args.fname_base, 1, stream_action, beep_id);
 	if (res < 0)
 		res = ast_monitor_change_fname(chan, args.fname_base, 1);
 
@@ -790,7 +827,7 @@
 		}
 	}
 
-	if (ast_monitor_start(c, format, fname, 1, X_REC_IN | X_REC_OUT)) {
+	if (ast_monitor_start(c, format, fname, 1, X_REC_IN | X_REC_OUT, NULL)) {
 		if (ast_monitor_change_fname(c, fname, 1)) {
 			astman_send_error(s, m, "Could not start monitoring channel");
 			c = ast_channel_unref(c);




More information about the asterisk-commits mailing list