[Asterisk-code-review] res_mixmonitor: MixMonitorMute by MixMonitor ID (asterisk[certified/18.9])

Friendly Automation asteriskteam at digium.com
Mon Mar 20 09:23:50 CDT 2023


Friendly Automation has submitted this change. ( https://gerrit.asterisk.org/c/asterisk/+/19995 )

Change subject: res_mixmonitor: MixMonitorMute by MixMonitor ID
......................................................................

res_mixmonitor: MixMonitorMute by MixMonitor ID

While it is possible to create multiple mixmonitor instances
on a channel, it was not previously possible to mute individual
instances.

This change includes the ability to specify the MixMonitorID
when calling the manager action: MixMonitorMute.  This will
allow an individual MixMonitor instance to be muted via id.
This id can be stored as a channel variable using the 'i'
MixMonitor option.

As part of this change, if no MixMonitorID is specified in
the manager action MixMonitorMute, Asterisk will set the mute
flag on all MixMonitor spy-type audiohooks on the channel.
This is done via the new audiohook function:
ast_audiohook_set_mute_all.

ASTERISK-30464

Change-Id: Ibba8c7e750577aa1595a24b23316ef445245be98
---
M apps/app_mixmonitor.c
A doc/CHANGES-staging/app_mixmonitor_mute_by_id.txt
M include/asterisk/audiohook.h
M main/audiohook.c
4 files changed, 150 insertions(+), 8 deletions(-)

Approvals:
  George Joseph: Looks good to me, approved
  Friendly Automation: Approved for Submit




diff --git a/apps/app_mixmonitor.c b/apps/app_mixmonitor.c
index a0eb1db..95ecd71 100644
--- a/apps/app_mixmonitor.c
+++ b/apps/app_mixmonitor.c
@@ -1403,6 +1403,50 @@
 	return CLI_SUCCESS;
 }
 
+/*! \brief  Mute / unmute  an individual MixMonitor by id */
+static int mute_mixmonitor_instance(struct ast_channel *chan, const char *data,
+									enum ast_audiohook_flags flag, int clearmute)
+{
+	struct ast_datastore *datastore = NULL;
+	char *parse = "";
+	struct mixmonitor_ds *mixmonitor_ds;
+
+	AST_DECLARE_APP_ARGS(args,
+		AST_APP_ARG(mixmonid);
+	);
+
+	if (!ast_strlen_zero(data)) {
+		parse = ast_strdupa(data);
+	}
+
+	AST_STANDARD_APP_ARGS(args, parse);
+
+	ast_channel_lock(chan);
+
+	datastore = ast_channel_datastore_find(chan, &mixmonitor_ds_info,
+		S_OR(args.mixmonid, NULL));
+	if (!datastore) {
+		ast_channel_unlock(chan);
+		return -1;
+	}
+	mixmonitor_ds = datastore->data;
+
+	ast_mutex_lock(&mixmonitor_ds->lock);
+
+	if (mixmonitor_ds->audiohook) {
+		if (clearmute) {
+			ast_clear_flag(mixmonitor_ds->audiohook, flag);
+		} else {
+			ast_set_flag(mixmonitor_ds->audiohook, flag);
+		}
+	}
+
+	ast_mutex_unlock(&mixmonitor_ds->lock);
+	ast_channel_unlock(chan);
+
+	return 0;
+}
+
 /*! \brief  Mute / unmute  a MixMonitor channel */
 static int manager_mute_mixmonitor(struct mansession *s, const struct message *m)
 {
@@ -1411,7 +1455,8 @@
 	const char *id = astman_get_header(m, "ActionID");
 	const char *state = astman_get_header(m, "State");
 	const char *direction = astman_get_header(m,"Direction");
-	int clearmute = 1;
+	const char *mixmonitor_id = astman_get_header(m, "MixMonitorID");
+	int clearmute = 1, mutedcount = 0;
 	enum ast_audiohook_flags flag;
 	RAII_VAR(struct stasis_message *, stasis_message, NULL, ao2_cleanup);
 	RAII_VAR(struct ast_json *, stasis_message_blob, NULL, ast_json_unref);
@@ -1450,15 +1495,28 @@
 		return AMI_SUCCESS;
 	}
 
-	if (ast_audiohook_set_mute(c, mixmonitor_spy_type, flag, clearmute)) {
-		ast_channel_unref(c);
-		astman_send_error(s, m, "Cannot set mute flag");
-		return AMI_SUCCESS;
+	if (ast_strlen_zero(mixmonitor_id)) {
+		mutedcount = ast_audiohook_set_mute_all(c, mixmonitor_spy_type, flag, clearmute);
+		if (mutedcount < 0) {
+			ast_channel_unref(c);
+			astman_send_error(s, m, "Cannot set mute flag");
+			return AMI_SUCCESS;
+		}
+	} else {
+		if (mute_mixmonitor_instance(c, mixmonitor_id, flag, clearmute)) {
+			ast_channel_unref(c);
+			astman_send_error(s, m, "Cannot set mute flag");
+			return AMI_SUCCESS;
+		}
+		mutedcount = 1;
 	}
 
-	stasis_message_blob = ast_json_pack("{s: s, s: b}",
+
+	stasis_message_blob = ast_json_pack("{s: s, s: b, s: s, s: i}",
 		"direction", direction,
-		"state", ast_true(state));
+		"state", ast_true(state),
+		"mixmonitorid", mixmonitor_id,
+		"count", mutedcount);
 
 	stasis_message = ast_channel_blob_create_from_cache(ast_channel_uniqueid(c),
 		ast_channel_mixmonitor_mute_type(), stasis_message_blob);
diff --git a/doc/CHANGES-staging/app_mixmonitor_mute_by_id.txt b/doc/CHANGES-staging/app_mixmonitor_mute_by_id.txt
new file mode 100644
index 0000000..958a914
--- /dev/null
+++ b/doc/CHANGES-staging/app_mixmonitor_mute_by_id.txt
@@ -0,0 +1,17 @@
+Subject: app_mixmonitor
+Subject: audiohook
+Subject: manager
+
+It is now possible to specify the MixMonitorID when calling
+the manager action: MixMonitorMute.  This will allow an
+individual MixMonitor instance to be muted via ID.
+
+The MixMonitorID can be stored as a channel variable using
+the 'i' MixMonitor option and is returned upon creation if
+this option is used.
+
+As part of this change, if no MixMonitorID is specified in
+the manager action MixMonitorMute, Asterisk will set the mute
+flag on all MixMonitor audiohooks on the channel.  Previous
+behavior would set the flag on the first MixMonitor audiohook
+found.
diff --git a/include/asterisk/audiohook.h b/include/asterisk/audiohook.h
index a5d7e0c..e19c833 100644
--- a/include/asterisk/audiohook.h
+++ b/include/asterisk/audiohook.h
@@ -358,6 +358,16 @@
  */
 int ast_audiohook_set_mute(struct ast_channel *chan, const char *source, enum ast_audiohook_flags flag, int clear);
 
+/*! \brief Mute frames read from or written for all audiohooks on a channel
+ * \param chan Channel to muck with
+ * \param source Type of audiohooks
+ * \param flag which direction to set / clear
+ * \param clear set or clear muted frames on direction based on flag parameter
+ * \retval >=0 number of muted audiohooks
+ * \retval -1 failure
+ */
+int ast_audiohook_set_mute_all(struct ast_channel *chan, const char *source, enum ast_audiohook_flags flag, int clear);
+
 #if defined(__cplusplus) || defined(c_plusplus)
 }
 #endif
diff --git a/main/audiohook.c b/main/audiohook.c
index 59ea0fa..321a94d 100644
--- a/main/audiohook.c
+++ b/main/audiohook.c
@@ -34,12 +34,12 @@
 #include "asterisk/channel.h"
 #include "asterisk/utils.h"
 #include "asterisk/lock.h"
-#include "asterisk/linkedlists.h"
 #include "asterisk/audiohook.h"
 #include "asterisk/slinfactory.h"
 #include "asterisk/frame.h"
 #include "asterisk/translate.h"
 #include "asterisk/format_cache.h"
+#include "asterisk/test.h"
 
 #define AST_AUDIOHOOK_SYNC_TOLERANCE 100 /*!< Tolerance in milliseconds for audiohooks synchronization */
 #define AST_AUDIOHOOK_SMALL_QUEUE_TOLERANCE 100 /*!< When small queue is enabled, this is the maximum amount of audio that can remain queued at a time. */
@@ -1376,3 +1376,33 @@
 
 	return (audiohook ? 0 : -1);
 }
+
+int ast_audiohook_set_mute_all(struct ast_channel *chan, const char *source, enum ast_audiohook_flags flag, int clearmute)
+{
+	struct ast_audiohook *audiohook = NULL;
+	int count = 0;
+
+	ast_channel_lock(chan);
+
+	if (!ast_channel_audiohooks(chan)) {
+		return -1;
+	}
+
+	AST_LIST_TRAVERSE(&ast_channel_audiohooks(chan)->spy_list, audiohook, list) {
+		if (!strcasecmp(audiohook->source, source)) {
+			count++;
+			if (clearmute) {
+				ast_clear_flag(audiohook, flag);
+			} else {
+				ast_set_flag(audiohook, flag);
+			}
+		}
+	}
+
+	ast_test_suite_event_notify("AUDIOHOOK_GROUP_MUTE_TOGGLE", "Channel: %s\r\nSource: %s\r\nCount: %d\r\n",
+									ast_channel_name(chan), source, count);
+
+	ast_channel_unlock(chan);
+
+	return count;
+}

-- 
To view, visit https://gerrit.asterisk.org/c/asterisk/+/19995
To unsubscribe, or for help writing mail filters, visit https://gerrit.asterisk.org/settings

Gerrit-Project: asterisk
Gerrit-Branch: certified/18.9
Gerrit-Change-Id: Ibba8c7e750577aa1595a24b23316ef445245be98
Gerrit-Change-Number: 19995
Gerrit-PatchSet: 2
Gerrit-Owner: Michael Bradeen <mbradeen at sangoma.com>
Gerrit-Reviewer: Friendly Automation
Gerrit-Reviewer: George Joseph <gjoseph at digium.com>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20230320/d5184afc/attachment-0001.html>


More information about the asterisk-code-review mailing list