All pastes #1845714 Raw Edit

clueless

public diff v1 · immutable
#1845714 ·published 2010-03-19 14:23 UTC
rendered paste body
Index: apps/app_mixmonitor.c===================================================================--- apps/app_mixmonitor.c	(revision 253530)+++ apps/app_mixmonitor.c	(working copy)@@ -46,6 +46,7 @@ #include "asterisk/app.h" #include "asterisk/channel.h" #include "asterisk/autochan.h"+#include "asterisk/manager.h"  /*** DOCUMENTATION 	<application name="MixMonitor" language="en_US">@@ -124,7 +125,41 @@ 			<ref type="application">MixMonitor</ref> 		</see-also> 	</application>-		+	<manager name="MuteMixMonitor" language="en_US">+		<synopsis>+			Mute a Mixmonitor recording.+		</synopsis>+		<syntax>+			<xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />+			<parameter name="Channel" required="true">+				<para>Used to specify the channel to mute.</para>+			</parameter>+			<parameter name="Direction">+				<para>Which part of the recording to mute:  read, write or both (from channel, to channel or both channels).</para>+			</parameter>+		</syntax>+		<description>+			<para>This action may be used to mute a MixMonitor recording.</para>+		</description>+	</manager>+	<manager name="UnmuteMixMonitor" language="en_US">+		<synopsis>+			Unmute a Mixmonitor recording.+		</synopsis>+		<syntax>+			<xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />+			<parameter name="Channel" required="true">+				<para>Used to specify the channel to unmute.</para>+			</parameter>+			<parameter name="Direction">+				<para>Which part of the recording to unmute:  read, write or both (from channel, to channel or both channels).</para>+			</parameter>+		</syntax>+		<description>+			<para>This action may be used to unmute a MixMonitor recording.</para>+		</description>+	</manager>+  ***/  #define get_volfactor(x) x ? ((x > 0) ? (1 << x) : ((1 << abs(x)) * -1)) : 0@@ -605,6 +640,75 @@ 	return CLI_SUCCESS; } +/*! \brief  Mute / unmute  a MixMonitor channel */+static int mute_mixmonitor(struct mansession *s, const struct message *m, int muteflag)+{+	struct ast_channel *c = NULL;++	const char *name = astman_get_header(m, "Channel");+	const char *id = astman_get_header(m, "ActionID");+	const char *direction = astman_get_header(m,"Direction");++	enum ast_audiohook_flags flag;++	if (ast_strlen_zero(direction)) {+		astman_send_error(s, m, "No direction specified. Must be read, write or both");+		return AMI_SUCCESS;+	}++	if (!strcasecmp(direction, "read")) {+		flag = AST_AUDIOHOOK_MUTE_READ;+	} else  if (!strcasecmp(direction, "write")) {+		flag = AST_AUDIOHOOK_MUTE_WRITE;+	} else  if (!strcasecmp(direction, "both")) {+		flag = AST_AUDIOHOOK_MUTE_READ | AST_AUDIOHOOK_MUTE_WRITE;+	} else {+		astman_send_error(s, m, "Invalid direction specified. Must be read, write or both");+		return AMI_SUCCESS;+	}++	if (ast_strlen_zero(name)) {+		astman_send_error(s, m, "No channel specified");+		return AMI_SUCCESS;+	}++	c = ast_channel_get_by_name(name);++	if (!c) {+		astman_send_error(s, m, "No such channel");+		return AMI_SUCCESS;+	}++	if (!ast_audiohook_set_mute(c, mixmonitor_spy_type, flag, muteflag)) {+		astman_send_error(s, m, "Cannot set mute flag");+		return AMI_SUCCESS;+	}++	astman_append(s, "Response: Success\r\n");++	if (!ast_strlen_zero(id)) {+		astman_append(s, "ActionID: %s\r\n", id);+	}++	astman_append(s, "\r\n");++	c = ast_channel_unref(c);++	return AMI_SUCCESS;+}++/*! \brief  Unmute a MixMonitor channel */+static int manager_unmute_mixmonitor(struct mansession *s, const struct message *m)+{+	return mute_mixmonitor(s, m, 1);+}++/*! \brief  Mute a MixMonitor channel */+static int manager_mute_mixmonitor(struct mansession *s, const struct message *m)+{+	return mute_mixmonitor(s, m, 0);+}+ static struct ast_cli_entry cli_mixmonitor[] = { 	AST_CLI_DEFINE(handle_cli_mixmonitor, "Execute a MixMonitor command") };@@ -616,6 +720,8 @@ 	ast_cli_unregister_multiple(cli_mixmonitor, ARRAY_LEN(cli_mixmonitor)); 	res = ast_unregister_application(stop_app); 	res |= ast_unregister_application(app);+	res |= ast_manager_unregister("MuteMixMonitor");+	res |= ast_manager_unregister("UnmuteMixMonitor"); 	 	return res; }@@ -627,6 +733,8 @@ 	ast_cli_register_multiple(cli_mixmonitor, ARRAY_LEN(cli_mixmonitor)); 	res = ast_register_application_xml(app, mixmonitor_exec); 	res |= ast_register_application_xml(stop_app, stop_mixmonitor_exec);+	res |= ast_manager_register_xml("UnmuteMixMonitor", 0, manager_unmute_mixmonitor);+	res |= ast_manager_register_xml("MuteMixMonitor", 0, manager_mute_mixmonitor);  	return res; }Index: include/asterisk/frame.h===================================================================--- include/asterisk/frame.h	(revision 253530)+++ include/asterisk/frame.h	(working copy)@@ -720,6 +720,11 @@ 	} } +/*!+ * \brief Clear all audio samples from an ast_frame.+ */+static inline void ast_frame_clear(struct ast_frame *frame);+ #if defined(__cplusplus) || defined(c_plusplus) } #endifIndex: include/asterisk/audiohook.h===================================================================--- include/asterisk/audiohook.h	(revision 253530)+++ include/asterisk/audiohook.h	(working copy)@@ -62,6 +62,8 @@ 	 * slinfactories. We will flush the factories if they contain too many samples. 	 */ 	AST_AUDIOHOOK_SMALL_QUEUE = (1 << 3),+	AST_AUDIOHOOK_MUTE_READ = (1 << 4),     /*!< audiohook should be mute frames read */+	AST_AUDIOHOOK_MUTE_WRITE = (1 << 5),    /*!< audiohook should be mute frames written */ };  #define AST_AUDIOHOOK_SYNC_TOLERANCE 100 /*< Tolerance in milliseconds for audiohooks synchronization */@@ -277,6 +279,16 @@  */ int ast_audiohook_volume_adjust(struct ast_channel *chan, enum ast_audiohook_direction direction, int volume); +/*! \brief Mute frames read from or written to a channel+ * \param chan Channel to muck with+ * \param source Type of audiohook+ * \param flag which flag to set / clear+ * \param clear set or clear+ * \retval 0 success+ * \retval -1 failure+ */+int ast_audiohook_set_mute(struct ast_channel *chan, const char *source, enum ast_audiohook_flags flag, int clear);+ #if defined(__cplusplus) || defined(c_plusplus) } #endifIndex: main/frame.c===================================================================--- main/frame.c	(revision 253530)+++ main/frame.c	(working copy)@@ -1587,3 +1587,15 @@  	return 0; }++int ast_frame_clear(struct ast_frame *frame)+{+	struct ast_frame *next;++	for (next = AST_LIST_NEXT(frame, frame_list);+		 frame;+		 frame = next, next = frame ? AST_LIST_NEXT(frame, frame_list) : NULL) {+		memset(frame->data.ptr, 0, frame->datalen);+	}+	return 0;+}Index: main/audiohook.c===================================================================--- main/audiohook.c	(revision 253530)+++ main/audiohook.c	(working copy)@@ -127,7 +127,12 @@ 	int our_factory_ms; 	int other_factory_samples; 	int other_factory_ms;+	int muteme = 0; +	/* define buffer for zero data, and buffer to store original data in */+	void *mutedbuf = NULL;+	void *originalbuf = NULL;+ 	/* Update last feeding time to be current */ 	*rwtime = ast_tvnow(); @@ -151,6 +156,17 @@ 		ast_slinfactory_flush(other_factory); 	} +	/* swap frame data for zeros if mute is required */+	if ((ast_test_flag(audiohook, AST_AUDIOHOOK_MUTE_READ) && (direction == AST_AUDIOHOOK_DIRECTION_READ)) ||+		(ast_test_flag(audiohook, AST_AUDIOHOOK_MUTE_WRITE) && (direction == AST_AUDIOHOOK_DIRECTION_WRITE)) ||+		(ast_test_flag(audiohook, AST_AUDIOHOOK_MUTE_READ | AST_AUDIOHOOK_MUTE_WRITE) == (AST_AUDIOHOOK_MUTE_READ | AST_AUDIOHOOK_MUTE_WRITE))) {+			muteme = 1;+	}++	if (muteme && frame->datalen > 0) {+		ast_frame_clear(frame);+	}+ 	/* Write frame out to respective factory */ 	ast_slinfactory_feed(factory, frame); @@ -1001,3 +1017,37 @@  	return 0; }++/*! \brief Mute frames read from or written to a channel+ * \param chan Channel to muck with+ * \param source Type of audiohook+ * \param flag which flag to set / clear+ * \param clear set or clear+ * \return Returns 0 on success, -1 on failure+ */+int ast_audiohook_set_mute(struct ast_channel *chan, const char *source, enum ast_audiohook_flags flag, int clear)+{+	struct ast_audiohook *audiohook = NULL;++	ast_channel_lock(chan);++	/* Ensure the channel has audiohooks on it */+	if (!chan->audiohooks) {+		ast_channel_unlock(chan);+		return -1;+	}++	audiohook = find_audiohook_by_source(chan->audiohooks, source);++	if (audiohook) {+		if (clear) {+			ast_clear_flag(audiohook, flag);+		} else {+			ast_set_flag(audiohook, flag);+		}+	}++	ast_channel_unlock(chan);++	return (audiohook ? 0 : -1);+}Index: res/res_mutestream.c===================================================================--- res/res_mutestream.c	(revision 253530)+++ res/res_mutestream.c	(working copy)@@ -116,19 +116,6 @@ 	.destroy = destroy_callback }; -/*! \brief Wipe out all audio samples from an ast_frame. Clean it. */-static void ast_frame_clear(struct ast_frame *frame)-{-	struct ast_frame *next;--	for (next = AST_LIST_NEXT(frame, frame_list);-		frame;-		frame = next, next = frame ? AST_LIST_NEXT(frame, frame_list) : NULL) {-		memset(frame->data.ptr, 0, frame->datalen);-        }-}-- /*! \brief The callback from the audiohook subsystem. We basically get a frame to have fun with */ static int mute_callback(struct ast_audiohook *audiohook, struct ast_channel *chan, struct ast_frame *frame, enum ast_audiohook_direction direction) {