<p>Michael Bradeen has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/19969">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">res_mixmonitor: MixMonitorMute by MixMonitor ID<br><br>While it is possible to create multiple mixmonitor instances<br>on a channel, it was not previously possible to mute individual<br>instances.<br><br>This change includes the ability to specify the MixMonitorID<br>when calling the manager action: MixMonitorMute. This will<br>allow an individual MixMonitor instance to be muted via id.<br>This id can be stored as a channel variable using the 'i'<br>MixMonitor option.<br><br>As part of this change, if no MixMonitorID is specified in<br>the manager action MixMonitorMute, Asterisk will set the mute<br>flag on all MixMonitor spy-type audiohooks on the channel.<br>This is done via the new audiohook function:<br>ast_audiohook_set_mute_all.<br><br>ASTERISK-30464<br><br>Change-Id: Ibba8c7e750577aa1595a24b23316ef445245be98<br>---<br>M apps/app_mixmonitor.c<br>A doc/CHANGES-staging/app_mixmonitor_mute_by_id.txt<br>M include/asterisk/audiohook.h<br>M main/audiohook.c<br>4 files changed, 153 insertions(+), 8 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/69/19969/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/apps/app_mixmonitor.c b/apps/app_mixmonitor.c</span><br><span>index 1592c40..2ef2651 100644</span><br><span>--- a/apps/app_mixmonitor.c</span><br><span>+++ b/apps/app_mixmonitor.c</span><br><span>@@ -1447,6 +1447,50 @@</span><br><span> return CLI_SUCCESS;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*! \brief Mute / unmute an individual MixMonitor by id */</span><br><span style="color: hsl(120, 100%, 40%);">+static int mute_mixmonitor_instance(struct ast_channel *chan, const char *data,</span><br><span style="color: hsl(120, 100%, 40%);">+ enum ast_audiohook_flags flag, int clearmute)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ast_datastore *datastore = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+ char *parse = "";</span><br><span style="color: hsl(120, 100%, 40%);">+ struct mixmonitor_ds *mixmonitor_ds;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ AST_DECLARE_APP_ARGS(args,</span><br><span style="color: hsl(120, 100%, 40%);">+ AST_APP_ARG(mixmonid);</span><br><span style="color: hsl(120, 100%, 40%);">+ );</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!ast_strlen_zero(data)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ parse = ast_strdupa(data);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ AST_STANDARD_APP_ARGS(args, parse);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_channel_lock(chan);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ datastore = ast_channel_datastore_find(chan, &mixmonitor_ds_info,</span><br><span style="color: hsl(120, 100%, 40%);">+ S_OR(args.mixmonid, NULL));</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!datastore) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_channel_unlock(chan);</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ mixmonitor_ds = datastore->data;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_mutex_lock(&mixmonitor_ds->lock);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (mixmonitor_ds->audiohook) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (clearmute) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_clear_flag(mixmonitor_ds->audiohook, flag);</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_set_flag(mixmonitor_ds->audiohook, flag);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_mutex_unlock(&mixmonitor_ds->lock);</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_channel_unlock(chan);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*! \brief Mute / unmute a MixMonitor channel */</span><br><span> static int manager_mute_mixmonitor(struct mansession *s, const struct message *m)</span><br><span> {</span><br><span>@@ -1455,7 +1499,8 @@</span><br><span> const char *id = astman_get_header(m, "ActionID");</span><br><span> const char *state = astman_get_header(m, "State");</span><br><span> const char *direction = astman_get_header(m,"Direction");</span><br><span style="color: hsl(0, 100%, 40%);">- int clearmute = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *mixmonitor_id = astman_get_header(m, "MixMonitorID");</span><br><span style="color: hsl(120, 100%, 40%);">+ int clearmute = 1, mutedcount = 0;</span><br><span> enum ast_audiohook_flags flag;</span><br><span> RAII_VAR(struct stasis_message *, stasis_message, NULL, ao2_cleanup);</span><br><span> RAII_VAR(struct ast_json *, stasis_message_blob, NULL, ast_json_unref);</span><br><span>@@ -1494,15 +1539,29 @@</span><br><span> return AMI_SUCCESS;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- if (ast_audiohook_set_mute(c, mixmonitor_spy_type, flag, clearmute)) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_channel_unref(c);</span><br><span style="color: hsl(0, 100%, 40%);">- astman_send_error(s, m, "Cannot set mute flag");</span><br><span style="color: hsl(0, 100%, 40%);">- return AMI_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ast_strlen_zero(mixmonitor_id)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ mutedcount = ast_audiohook_set_mute_all(c, mixmonitor_spy_type, flag, clearmute);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (mutedcount<0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_channel_unref(c);</span><br><span style="color: hsl(120, 100%, 40%);">+ astman_send_error(s, m, "Cannot set mute flag");</span><br><span style="color: hsl(120, 100%, 40%);">+ return AMI_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ else{</span><br><span style="color: hsl(120, 100%, 40%);">+ if (mute_mixmonitor_instance(c, mixmonitor_id, flag, clearmute)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_channel_unref(c);</span><br><span style="color: hsl(120, 100%, 40%);">+ astman_send_error(s, m, "Cannot set mute flag");</span><br><span style="color: hsl(120, 100%, 40%);">+ return AMI_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ mutedcount = 1;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- stasis_message_blob = ast_json_pack("{s: s, s: b}",</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ stasis_message_blob = ast_json_pack("{s: s, s: b, s: s, s: i}",</span><br><span> "direction", direction,</span><br><span style="color: hsl(0, 100%, 40%);">- "state", ast_true(state));</span><br><span style="color: hsl(120, 100%, 40%);">+ "state", ast_true(state),</span><br><span style="color: hsl(120, 100%, 40%);">+ "mixmonitorid", mixmonitor_id,</span><br><span style="color: hsl(120, 100%, 40%);">+ "count", mutedcount);</span><br><span> </span><br><span> stasis_message = ast_channel_blob_create_from_cache(ast_channel_uniqueid(c),</span><br><span> ast_channel_mixmonitor_mute_type(), stasis_message_blob);</span><br><span>diff --git a/doc/CHANGES-staging/app_mixmonitor_mute_by_id.txt b/doc/CHANGES-staging/app_mixmonitor_mute_by_id.txt</span><br><span>new file mode 100644</span><br><span>index 0000000..99e7d3d</span><br><span>--- /dev/null</span><br><span>+++ b/doc/CHANGES-staging/app_mixmonitor_mute_by_id.txt</span><br><span>@@ -0,0 +1,19 @@</span><br><span style="color: hsl(120, 100%, 40%);">+Subject: app_mixmonitor</span><br><span style="color: hsl(120, 100%, 40%);">+Subject: audiohook</span><br><span style="color: hsl(120, 100%, 40%);">+Subject: manager</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+While it is possible to create multiple mixmonitor instances</span><br><span style="color: hsl(120, 100%, 40%);">+on a channel, it was not previously possible to mute individual</span><br><span style="color: hsl(120, 100%, 40%);">+instances.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+This change includes the ability to specify the MixMonitorID</span><br><span style="color: hsl(120, 100%, 40%);">+when calling the manager action: MixMonitorMute. This will</span><br><span style="color: hsl(120, 100%, 40%);">+allow an individual MixMonitor instance to be muted via id.</span><br><span style="color: hsl(120, 100%, 40%);">+This id can be stored as a channel variable using the 'i'</span><br><span style="color: hsl(120, 100%, 40%);">+MixMonitor option.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+As part of this change, if no MixMonitorID is specified in</span><br><span style="color: hsl(120, 100%, 40%);">+the manager action MixMonitorMute, Asterisk will set the mute</span><br><span style="color: hsl(120, 100%, 40%);">+flag on all MixMonitor spy-type audiohooks on the channel.</span><br><span style="color: hsl(120, 100%, 40%);">+This is done via the new audiohook function:</span><br><span style="color: hsl(120, 100%, 40%);">+ast_audiohook_set_mute_all.</span><br><span>diff --git a/include/asterisk/audiohook.h b/include/asterisk/audiohook.h</span><br><span>index a5d7e0c..e19c833 100644</span><br><span>--- a/include/asterisk/audiohook.h</span><br><span>+++ b/include/asterisk/audiohook.h</span><br><span>@@ -358,6 +358,16 @@</span><br><span> */</span><br><span> int ast_audiohook_set_mute(struct ast_channel *chan, const char *source, enum ast_audiohook_flags flag, int clear);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*! \brief Mute frames read from or written for all audiohooks on a channel</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param chan Channel to muck with</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param source Type of audiohooks</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param flag which direction to set / clear</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param clear set or clear muted frames on direction based on flag parameter</span><br><span style="color: hsl(120, 100%, 40%);">+ * \retval >=0 number of muted audiohooks</span><br><span style="color: hsl(120, 100%, 40%);">+ * \retval -1 failure</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int ast_audiohook_set_mute_all(struct ast_channel *chan, const char *source, enum ast_audiohook_flags flag, int clear);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #if defined(__cplusplus) || defined(c_plusplus)</span><br><span> }</span><br><span> #endif</span><br><span>diff --git a/main/audiohook.c b/main/audiohook.c</span><br><span>index 3154ede..102c0d0 100644</span><br><span>--- a/main/audiohook.c</span><br><span>+++ b/main/audiohook.c</span><br><span>@@ -34,12 +34,12 @@</span><br><span> #include "asterisk/channel.h"</span><br><span> #include "asterisk/utils.h"</span><br><span> #include "asterisk/lock.h"</span><br><span style="color: hsl(0, 100%, 40%);">-#include "asterisk/linkedlists.h"</span><br><span> #include "asterisk/audiohook.h"</span><br><span> #include "asterisk/slinfactory.h"</span><br><span> #include "asterisk/frame.h"</span><br><span> #include "asterisk/translate.h"</span><br><span> #include "asterisk/format_cache.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk/test.h"</span><br><span> </span><br><span> #define AST_AUDIOHOOK_SYNC_TOLERANCE 100 /*!< Tolerance in milliseconds for audiohooks synchronization */</span><br><span> #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. */</span><br><span>@@ -1376,3 +1376,33 @@</span><br><span> </span><br><span> return (audiohook ? 0 : -1);</span><br><span> }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int ast_audiohook_set_mute_all(struct ast_channel *chan, const char *source, enum ast_audiohook_flags flag, int clearmute)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ast_audiohook *audiohook = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+ int count = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_channel_lock(chan);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!ast_channel_audiohooks(chan)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ AST_LIST_TRAVERSE(&ast_channel_audiohooks(chan)->spy_list, audiohook, list) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!strcasecmp(audiohook->source, source)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ count++;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (clearmute) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_clear_flag(audiohook, flag);</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_set_flag(audiohook, flag);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_test_suite_event_notify("AUDIOHOOK_GROUP_MUTE_TOGGLE", "Channel: %s\r\nSource: %s\r\nCount: %d\r\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_channel_name(chan), source, count);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_channel_unlock(chan);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return count;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/19969">change 19969</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/c/asterisk/+/19969"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 18 </div>
<div style="display:none"> Gerrit-Change-Id: Ibba8c7e750577aa1595a24b23316ef445245be98 </div>
<div style="display:none"> Gerrit-Change-Number: 19969 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Michael Bradeen <mbradeen@sangoma.com> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>