<p>Michael Bradeen has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/19605">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">res_monitor: Remove deprecated module.<br><br>ASTERISK-30303<br><br>Change-Id: I0462caefb4f9544e2e2baa23c498858310b52d50<br>---<br>M apps/Makefile<br>M apps/app_queue.c<br>M bridges/bridge_builtin_features.c<br>M channels/Makefile<br>A doc/UPGRADE-staging/res_monitor_removal.txt<br>M include/asterisk/bridge_features.h<br>M include/asterisk/doxygen/architecture.h<br>D include/asterisk/monitor.h<br>M main/asterisk.dynamics<br>M menuselect/example_menuselect-tree<br>M menuselect/test/menuselect-tree<br>M pbx/Makefile<br>D res/res_monitor.c<br>D res/res_monitor.exports.in<br>14 files changed, 20 insertions(+), 1,359 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/05/19605/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/apps/Makefile b/apps/Makefile</span><br><span>index 02b705d..50b3fcc 100644</span><br><span>--- a/apps/Makefile</span><br><span>+++ b/apps/Makefile</span><br><span>@@ -58,6 +58,6 @@</span><br><span> app_while.o: _ASTCFLAGS+=$(AST_NO_FORMAT_TRUNCATION)</span><br><span> </span><br><span> ifneq ($(findstring $(OSARCH), mingw32 cygwin ),)</span><br><span style="color: hsl(0, 100%, 40%);">-  LIBS+= -lres_ael_share.so -lres_monitor.so -lres_speech.so</span><br><span style="color: hsl(120, 100%, 40%);">+  LIBS+= -lres_ael_share.so -lres_speech.so</span><br><span>   LIBS+= -lres_smdi.so</span><br><span> endif</span><br><span>diff --git a/apps/app_queue.c b/apps/app_queue.c</span><br><span>index 288c0ff..7030166 100644</span><br><span>--- a/apps/app_queue.c</span><br><span>+++ b/apps/app_queue.c</span><br><span>@@ -41,7 +41,6 @@</span><br><span>  *    - Position announcement</span><br><span>  *    - Abandoned/completed call counters</span><br><span>  *    - Failout timer passed as optional app parameter</span><br><span style="color: hsl(0, 100%, 40%);">- *    - Optional monitoring of calls, started when call is answered</span><br><span>  *</span><br><span>  * Patch Version 1.07 2003-12-24 01</span><br><span>  *</span><br><span>@@ -63,7 +62,6 @@</span><br><span>  */</span><br><span> </span><br><span> /*** MODULEINFO</span><br><span style="color: hsl(0, 100%, 40%);">-        <use type="module">res_monitor</use></span><br><span>   <support_level>core</support_level></span><br><span>  ***/</span><br><span> </span><br><span>@@ -88,7 +86,6 @@</span><br><span> #include "asterisk/cli.h"</span><br><span> #include "asterisk/manager.h"</span><br><span> #include "asterisk/config.h"</span><br><span style="color: hsl(0, 100%, 40%);">-#include "asterisk/monitor.h"</span><br><span> #include "asterisk/utils.h"</span><br><span> #include "asterisk/causes.h"</span><br><span> #include "asterisk/astdb.h"</span><br><span>@@ -222,14 +219,6 @@</span><br><span>                                       <option name="T"></span><br><span>                                            <para>Allow the <emphasis>calling</emphasis> user to transfer the call.</para></span><br><span>                                       </option></span><br><span style="color: hsl(0, 100%, 40%);">-                                 <option name="w"></span><br><span style="color: hsl(0, 100%, 40%);">-                                               <para>Allow the <emphasis>called</emphasis> user to write the conversation to</span><br><span style="color: hsl(0, 100%, 40%);">-                                         disk via Monitor.</para></span><br><span style="color: hsl(0, 100%, 40%);">-                                  </option></span><br><span style="color: hsl(0, 100%, 40%);">-                                 <option name="W"></span><br><span style="color: hsl(0, 100%, 40%);">-                                               <para>Allow the <emphasis>calling</emphasis> user to write the conversation to</span><br><span style="color: hsl(0, 100%, 40%);">-                                                disk via Monitor.</para></span><br><span style="color: hsl(0, 100%, 40%);">-                                  </option></span><br><span>                                      <option name="x"></span><br><span>                                            <para>Allow the <emphasis>called</emphasis> user to write the conversation</span><br><span>                                                 to disk via MixMonitor.</para></span><br><span>@@ -1868,7 +1857,6 @@</span><br><span>         int servicelevel;                   /*!< seconds setting for servicelevel*/</span><br><span>       int callscompletedinsl;             /*!< Number of calls answered with servicelevel*/</span><br><span>     char monfmt[8];                     /*!< Format to use when recording calls */</span><br><span style="color: hsl(0, 100%, 40%);">-       int montype;                        /*!< Monitor type  Monitor vs. MixMonitor */</span><br><span>  int count;                          /*!< How many entries */</span><br><span>      int maxlen;                         /*!< Max number of entries */</span><br><span>         int wrapuptime;                     /*!< Wrapup Time */</span><br><span>@@ -2972,7 +2960,6 @@</span><br><span>   q->setqueuevar = 0;</span><br><span>       q->setqueueentryvar = 0;</span><br><span>  q->autofill = autofill_default;</span><br><span style="color: hsl(0, 100%, 40%);">-      q->montype = montype_default;</span><br><span>     q->monfmt[0] = '\0';</span><br><span>      q->reportholdtime = 0;</span><br><span>    q->wrapuptime = 0;</span><br><span>@@ -3456,10 +3443,6 @@</span><br><span>               }</span><br><span>    } else if (!strcasecmp(param, "autofill")) {</span><br><span>               q->autofill = ast_true(val);</span><br><span style="color: hsl(0, 100%, 40%);">- } else if (!strcasecmp(param, "monitor-type")) {</span><br><span style="color: hsl(0, 100%, 40%);">-              if (!strcasecmp(val, "mixmonitor")) {</span><br><span style="color: hsl(0, 100%, 40%);">-                 q->montype = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-              }</span><br><span>    } else if (!strcasecmp(param, "autopause")) {</span><br><span>              q->autopause = autopause2int(val);</span><br><span>        } else if (!strcasecmp(param, "autopausedelay")) {</span><br><span>@@ -6934,7 +6917,6 @@</span><br><span>         char oldcontext[AST_MAX_CONTEXT]="";</span><br><span>       char queuename[256]="";</span><br><span>    struct ast_channel *peer;</span><br><span style="color: hsl(0, 100%, 40%);">-       struct ast_channel *which;</span><br><span>   struct callattempt *lpeer;</span><br><span>   struct member *member;</span><br><span>       struct ast_app *application;</span><br><span>@@ -6950,7 +6932,6 @@</span><br><span>         char *macroexec = NULL;</span><br><span>      char *gosubexec = NULL;</span><br><span>      const char *monitorfilename;</span><br><span style="color: hsl(0, 100%, 40%);">-    char tmpid[256];</span><br><span>     int forwardsallowed = 1;</span><br><span>     int block_connected_line = 0;</span><br><span>        struct ao2_iterator memi;</span><br><span>@@ -6959,7 +6940,6 @@</span><br><span>    time_t starttime;</span><br><span> </span><br><span>        memset(&bridge_config, 0, sizeof(bridge_config));</span><br><span style="color: hsl(0, 100%, 40%);">-   tmpid[0] = 0;</span><br><span>        time(&now);</span><br><span> </span><br><span>  /* If we've already exceeded our timeout, then just stop</span><br><span>@@ -7280,32 +7260,7 @@</span><br><span> </span><br><span>            /* Begin Monitoring */</span><br><span>               if (*qe->parent->monfmt) {</span><br><span style="color: hsl(0, 100%, 40%);">-                        if (!qe->parent->montype) {</span><br><span style="color: hsl(0, 100%, 40%);">-                               const char *monexec;</span><br><span style="color: hsl(0, 100%, 40%);">-                            ast_debug(1, "Starting Monitor as requested.\n");</span><br><span style="color: hsl(0, 100%, 40%);">-                             ast_channel_lock(qe->chan);</span><br><span style="color: hsl(0, 100%, 40%);">-                          if ((monexec = pbx_builtin_getvar_helper(qe->chan, "MONITOR_EXEC")) || pbx_builtin_getvar_helper(qe->chan, "MONITOR_EXEC_ARGS")) {</span><br><span style="color: hsl(0, 100%, 40%);">-                                    which = qe->chan;</span><br><span style="color: hsl(0, 100%, 40%);">-                                    monexec = monexec ? ast_strdupa(monexec) : NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-                                } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                                        which = peer;</span><br><span style="color: hsl(0, 100%, 40%);">-                           }</span><br><span style="color: hsl(0, 100%, 40%);">-                               ast_channel_unlock(qe->chan);</span><br><span style="color: hsl(0, 100%, 40%);">-                                if (monitorfilename) {</span><br><span style="color: hsl(0, 100%, 40%);">-                                  ast_monitor_start(which, qe->parent->monfmt, monitorfilename, 1, X_REC_IN | X_REC_OUT, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-                             } else if (qe->chan) {</span><br><span style="color: hsl(0, 100%, 40%);">-                                       ast_monitor_start(which, qe->parent->monfmt, ast_channel_uniqueid(qe->chan), 1, X_REC_IN | X_REC_OUT, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-                           } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                                        /* Last ditch effort -- no channel, make up something */</span><br><span style="color: hsl(0, 100%, 40%);">-                                        snprintf(tmpid, sizeof(tmpid), "chan-%lx", (unsigned long)ast_random());</span><br><span style="color: hsl(0, 100%, 40%);">-                                      ast_monitor_start(which, qe->parent->monfmt, tmpid, 1, X_REC_IN | X_REC_OUT, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-                               }</span><br><span style="color: hsl(0, 100%, 40%);">-                               if (!ast_strlen_zero(monexec)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                                        ast_monitor_setjoinfiles(which, 1);</span><br><span style="color: hsl(0, 100%, 40%);">-                             }</span><br><span style="color: hsl(0, 100%, 40%);">-                       } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                                setup_mixmonitor(qe, monitorfilename);</span><br><span style="color: hsl(0, 100%, 40%);">-                  }</span><br><span style="color: hsl(120, 100%, 40%);">+                     setup_mixmonitor(qe, monitorfilename);</span><br><span>               }</span><br><span>            /* Drop out of the queue at this point, to prepare for next caller */</span><br><span>                leave_queue(qe);</span><br><span>@@ -11847,5 +11802,4 @@</span><br><span>   .unload = unload_module,</span><br><span>     .reload = reload,</span><br><span>    .load_pri = AST_MODPRI_DEVSTATE_CONSUMER,</span><br><span style="color: hsl(0, 100%, 40%);">-       .optional_modules = "res_monitor",</span><br><span> );</span><br><span>diff --git a/bridges/bridge_builtin_features.c b/bridges/bridge_builtin_features.c</span><br><span>index 671cfb9..e6c84ab 100644</span><br><span>--- a/bridges/bridge_builtin_features.c</span><br><span>+++ b/bridges/bridge_builtin_features.c</span><br><span>@@ -26,7 +26,6 @@</span><br><span>  */</span><br><span> </span><br><span> /*** MODULEINFO</span><br><span style="color: hsl(0, 100%, 40%);">-   <use type="module">res_monitor</use></span><br><span>   <support_level>core</support_level></span><br><span>  ***/</span><br><span> </span><br><span>@@ -49,7 +48,6 @@</span><br><span> #include "asterisk/pbx.h"</span><br><span> #include "asterisk/parking.h"</span><br><span> #include "asterisk/features_config.h"</span><br><span style="color: hsl(0, 100%, 40%);">-#include "asterisk/monitor.h"</span><br><span> #include "asterisk/mixmonitor.h"</span><br><span> #include "asterisk/audiohook.h"</span><br><span> #include "asterisk/causes.h"</span><br><span>@@ -103,199 +101,6 @@</span><br><span>    return res;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static void stop_automonitor(struct ast_bridge_channel *bridge_channel, struct ast_channel *peer_chan, struct ast_features_general_config *features_cfg, const char *stop_message)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- ast_verb(4, "AutoMonitor used to stop recording call.\n");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    ast_channel_lock(peer_chan);</span><br><span style="color: hsl(0, 100%, 40%);">-    if (ast_channel_monitor(peer_chan)) {</span><br><span style="color: hsl(0, 100%, 40%);">-           if (ast_channel_monitor(peer_chan)->stop(peer_chan, 1)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                    ast_verb(4, "Cannot stop AutoMonitor for %s\n", ast_channel_name(bridge_channel->chan));</span><br><span style="color: hsl(0, 100%, 40%);">-                   if (features_cfg && !(ast_strlen_zero(features_cfg->recordingfailsound))) {</span><br><span style="color: hsl(0, 100%, 40%);">-                          ast_bridge_channel_queue_playfile(bridge_channel, NULL, features_cfg->recordingfailsound, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-                     }</span><br><span style="color: hsl(0, 100%, 40%);">-                       ast_channel_unlock(peer_chan);</span><br><span style="color: hsl(0, 100%, 40%);">-                  return;</span><br><span style="color: hsl(0, 100%, 40%);">-         }</span><br><span style="color: hsl(0, 100%, 40%);">-       } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                /* Something else removed the Monitor before we got to it. */</span><br><span style="color: hsl(0, 100%, 40%);">-           ast_channel_unlock(peer_chan);</span><br><span style="color: hsl(0, 100%, 40%);">-          return;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       ast_channel_unlock(peer_chan);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  if (features_cfg && !(ast_strlen_zero(features_cfg->courtesytone))) {</span><br><span style="color: hsl(0, 100%, 40%);">-                ast_bridge_channel_queue_playfile(bridge_channel, NULL, features_cfg->courtesytone, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-           ast_bridge_channel_write_playfile(bridge_channel, NULL, features_cfg->courtesytone, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-   }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (!ast_strlen_zero(stop_message)) {</span><br><span style="color: hsl(0, 100%, 40%);">-           ast_bridge_channel_queue_playfile(bridge_channel, NULL, stop_message, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-            ast_bridge_channel_write_playfile(bridge_channel, NULL, stop_message, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-    }</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void start_automonitor(struct ast_bridge_channel *bridge_channel, struct ast_channel *peer_chan, struct ast_features_general_config *features_cfg, const char *start_message)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- char *touch_filename;</span><br><span style="color: hsl(0, 100%, 40%);">-   size_t len;</span><br><span style="color: hsl(0, 100%, 40%);">-     int x;</span><br><span style="color: hsl(0, 100%, 40%);">-  enum set_touch_variables_res set_touch_res;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     RAII_VAR(char *, touch_format, NULL, ast_free);</span><br><span style="color: hsl(0, 100%, 40%);">- RAII_VAR(char *, touch_monitor, NULL, ast_free);</span><br><span style="color: hsl(0, 100%, 40%);">-        RAII_VAR(char *, touch_monitor_prefix, NULL, ast_free);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- set_touch_res = set_touch_variables(bridge_channel->chan, 0, &touch_format,</span><br><span style="color: hsl(0, 100%, 40%);">-              &touch_monitor, &touch_monitor_prefix);</span><br><span style="color: hsl(0, 100%, 40%);">- switch (set_touch_res) {</span><br><span style="color: hsl(0, 100%, 40%);">-        case SET_TOUCH_SUCCESS:</span><br><span style="color: hsl(0, 100%, 40%);">-         break;</span><br><span style="color: hsl(0, 100%, 40%);">-  case SET_TOUCH_UNSET:</span><br><span style="color: hsl(0, 100%, 40%);">-           set_touch_res = set_touch_variables(peer_chan, 0, &touch_format, &touch_monitor,</span><br><span style="color: hsl(0, 100%, 40%);">-                        &touch_monitor_prefix);</span><br><span style="color: hsl(0, 100%, 40%);">-             if (set_touch_res == SET_TOUCH_ALLOC_FAILURE) {</span><br><span style="color: hsl(0, 100%, 40%);">-                 return;</span><br><span style="color: hsl(0, 100%, 40%);">-         }</span><br><span style="color: hsl(0, 100%, 40%);">-               break;</span><br><span style="color: hsl(0, 100%, 40%);">-  case SET_TOUCH_ALLOC_FAILURE:</span><br><span style="color: hsl(0, 100%, 40%);">-           return;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (!ast_strlen_zero(touch_monitor)) {</span><br><span style="color: hsl(0, 100%, 40%);">-          len = strlen(touch_monitor) + 50;</span><br><span style="color: hsl(0, 100%, 40%);">-               touch_filename = ast_alloca(len);</span><br><span style="color: hsl(0, 100%, 40%);">-               snprintf(touch_filename, len, "%s-%ld-%s",</span><br><span style="color: hsl(0, 100%, 40%);">-                    S_OR(touch_monitor_prefix, "auto"),</span><br><span style="color: hsl(0, 100%, 40%);">-                   (long) time(NULL),</span><br><span style="color: hsl(0, 100%, 40%);">-                      touch_monitor);</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                char *caller_chan_id;</span><br><span style="color: hsl(0, 100%, 40%);">-           char *peer_chan_id;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-             caller_chan_id = ast_strdupa(S_COR(ast_channel_caller(bridge_channel->chan)->id.number.valid,</span><br><span style="color: hsl(0, 100%, 40%);">-                     ast_channel_caller(bridge_channel->chan)->id.number.str, ast_channel_name(bridge_channel->chan)));</span><br><span style="color: hsl(0, 100%, 40%);">-             peer_chan_id = ast_strdupa(S_COR(ast_channel_caller(peer_chan)->id.number.valid,</span><br><span style="color: hsl(0, 100%, 40%);">-                     ast_channel_caller(peer_chan)->id.number.str, ast_channel_name(peer_chan)));</span><br><span style="color: hsl(0, 100%, 40%);">-         len = strlen(caller_chan_id) + strlen(peer_chan_id) + 50;</span><br><span style="color: hsl(0, 100%, 40%);">-               touch_filename = ast_alloca(len);</span><br><span style="color: hsl(0, 100%, 40%);">-               snprintf(touch_filename, len, "%s-%ld-%s-%s",</span><br><span style="color: hsl(0, 100%, 40%);">-                 S_OR(touch_monitor_prefix, "auto"),</span><br><span style="color: hsl(0, 100%, 40%);">-                   (long) time(NULL),</span><br><span style="color: hsl(0, 100%, 40%);">-                      caller_chan_id,</span><br><span style="color: hsl(0, 100%, 40%);">-                 peer_chan_id);</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       for (x = 0; x < strlen(touch_filename); x++) {</span><br><span style="color: hsl(0, 100%, 40%);">-               if (touch_filename[x] == '/') {</span><br><span style="color: hsl(0, 100%, 40%);">-                 touch_filename[x] = '-';</span><br><span style="color: hsl(0, 100%, 40%);">-                }</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       ast_verb(4, "AutoMonitor used to record call. Filename: %s\n", touch_filename);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (ast_monitor_start(peer_chan, touch_format, touch_filename, 1, X_REC_IN | X_REC_OUT, NULL)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                ast_verb(4, "AutoMonitor feature was tried by '%s' but monitor failed to start.\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                   ast_channel_name(bridge_channel->chan));</span><br><span style="color: hsl(0, 100%, 40%);">-             return;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       ast_monitor_setjoinfiles(peer_chan, 1);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (features_cfg && !ast_strlen_zero(features_cfg->courtesytone)) {</span><br><span style="color: hsl(0, 100%, 40%);">-          ast_bridge_channel_queue_playfile(bridge_channel, NULL, features_cfg->courtesytone, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-           ast_bridge_channel_write_playfile(bridge_channel, NULL, features_cfg->courtesytone, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-   }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (!ast_strlen_zero(start_message)) {</span><br><span style="color: hsl(0, 100%, 40%);">-          ast_bridge_channel_queue_playfile(bridge_channel, NULL, start_message, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-           ast_bridge_channel_write_playfile(bridge_channel, NULL, start_message, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-   }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       pbx_builtin_setvar_helper(bridge_channel->chan, "TOUCH_MONITOR_OUTPUT", touch_filename);</span><br><span style="color: hsl(0, 100%, 40%);">-   pbx_builtin_setvar_helper(peer_chan, "TOUCH_MONITOR_OUTPUT", touch_filename);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int feature_automonitor(struct ast_bridge_channel *bridge_channel, void *hook_pvt)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      const char *start_message;</span><br><span style="color: hsl(0, 100%, 40%);">-      const char *stop_message;</span><br><span style="color: hsl(0, 100%, 40%);">-       struct ast_bridge_features_automonitor *options = hook_pvt;</span><br><span style="color: hsl(0, 100%, 40%);">-     enum ast_bridge_features_monitor start_stop = options ? options->start_stop : AUTO_MONITOR_TOGGLE;</span><br><span style="color: hsl(0, 100%, 40%);">-   int is_monitoring;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      RAII_VAR(struct ast_channel *, peer_chan, NULL, ast_channel_cleanup);</span><br><span style="color: hsl(0, 100%, 40%);">-   RAII_VAR(struct ast_features_general_config *, features_cfg, NULL, ao2_cleanup);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        ast_channel_lock(bridge_channel->chan);</span><br><span style="color: hsl(0, 100%, 40%);">-      features_cfg = ast_get_chan_features_general_config(bridge_channel->chan);</span><br><span style="color: hsl(0, 100%, 40%);">-   ast_channel_unlock(bridge_channel->chan);</span><br><span style="color: hsl(0, 100%, 40%);">-    ast_bridge_channel_lock_bridge(bridge_channel);</span><br><span style="color: hsl(0, 100%, 40%);">- peer_chan = ast_bridge_peer_nolock(bridge_channel->bridge, bridge_channel->chan);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_bridge_unlock(bridge_channel->bridge);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   if (!peer_chan) {</span><br><span style="color: hsl(0, 100%, 40%);">-               ast_verb(4, "Cannot start AutoMonitor for %s - can not determine peer in bridge.\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                  ast_channel_name(bridge_channel->chan));</span><br><span style="color: hsl(0, 100%, 40%);">-             if (features_cfg && !ast_strlen_zero(features_cfg->recordingfailsound)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                    ast_bridge_channel_queue_playfile(bridge_channel, NULL, features_cfg->recordingfailsound, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-             }</span><br><span style="color: hsl(0, 100%, 40%);">-               return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       ast_channel_lock(bridge_channel->chan);</span><br><span style="color: hsl(0, 100%, 40%);">-      start_message = pbx_builtin_getvar_helper(bridge_channel->chan,</span><br><span style="color: hsl(0, 100%, 40%);">-              "TOUCH_MONITOR_MESSAGE_START");</span><br><span style="color: hsl(0, 100%, 40%);">-       start_message = ast_strdupa(S_OR(start_message, ""));</span><br><span style="color: hsl(0, 100%, 40%);">- stop_message = pbx_builtin_getvar_helper(bridge_channel->chan,</span><br><span style="color: hsl(0, 100%, 40%);">-               "TOUCH_MONITOR_MESSAGE_STOP");</span><br><span style="color: hsl(0, 100%, 40%);">-        stop_message = ast_strdupa(S_OR(stop_message, ""));</span><br><span style="color: hsl(0, 100%, 40%);">-   ast_channel_unlock(bridge_channel->chan);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    is_monitoring = ast_channel_monitor(peer_chan) != NULL;</span><br><span style="color: hsl(0, 100%, 40%);">- switch (start_stop) {</span><br><span style="color: hsl(0, 100%, 40%);">-   case AUTO_MONITOR_TOGGLE:</span><br><span style="color: hsl(0, 100%, 40%);">-               if (is_monitoring) {</span><br><span style="color: hsl(0, 100%, 40%);">-                    stop_automonitor(bridge_channel, peer_chan, features_cfg, stop_message);</span><br><span style="color: hsl(0, 100%, 40%);">-                } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                        start_automonitor(bridge_channel, peer_chan, features_cfg, start_message);</span><br><span style="color: hsl(0, 100%, 40%);">-              }</span><br><span style="color: hsl(0, 100%, 40%);">-               return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-       case AUTO_MONITOR_START:</span><br><span style="color: hsl(0, 100%, 40%);">-                if (!is_monitoring) {</span><br><span style="color: hsl(0, 100%, 40%);">-                   start_automonitor(bridge_channel, peer_chan, features_cfg, start_message);</span><br><span style="color: hsl(0, 100%, 40%);">-                      return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-               }</span><br><span style="color: hsl(0, 100%, 40%);">-               ast_verb(4, "AutoMonitor already recording call.\n");</span><br><span style="color: hsl(0, 100%, 40%);">-         break;</span><br><span style="color: hsl(0, 100%, 40%);">-  case AUTO_MONITOR_STOP:</span><br><span style="color: hsl(0, 100%, 40%);">-         if (is_monitoring) {</span><br><span style="color: hsl(0, 100%, 40%);">-                    stop_automonitor(bridge_channel, peer_chan, features_cfg, stop_message);</span><br><span style="color: hsl(0, 100%, 40%);">-                        return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-               }</span><br><span style="color: hsl(0, 100%, 40%);">-               ast_verb(4, "AutoMonitor already stopped on call.\n");</span><br><span style="color: hsl(0, 100%, 40%);">-                break;</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       /*</span><br><span style="color: hsl(0, 100%, 40%);">-       * Fake start/stop to invoker so will think it did something but</span><br><span style="color: hsl(0, 100%, 40%);">-         * was already in that mode.</span><br><span style="color: hsl(0, 100%, 40%);">-     */</span><br><span style="color: hsl(0, 100%, 40%);">-     if (features_cfg && !ast_strlen_zero(features_cfg->courtesytone)) {</span><br><span style="color: hsl(0, 100%, 40%);">-          ast_bridge_channel_queue_playfile(bridge_channel, NULL, features_cfg->courtesytone, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-   }</span><br><span style="color: hsl(0, 100%, 40%);">-       if (is_monitoring) {</span><br><span style="color: hsl(0, 100%, 40%);">-            if (!ast_strlen_zero(start_message)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                  ast_bridge_channel_queue_playfile(bridge_channel, NULL, start_message, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-           }</span><br><span style="color: hsl(0, 100%, 40%);">-       } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                if (!ast_strlen_zero(stop_message)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                   ast_bridge_channel_queue_playfile(bridge_channel, NULL, stop_message, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-            }</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-       return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span> </span><br><span> static void stop_automixmonitor(struct ast_bridge_channel *bridge_channel, struct ast_channel *peer_chan, struct ast_features_general_config *features_cfg, const char *stop_message)</span><br><span> {</span><br><span>@@ -503,7 +308,6 @@</span><br><span> static int unload_module(void)</span><br><span> {</span><br><span>    ast_bridge_features_unregister(AST_BRIDGE_BUILTIN_HANGUP);</span><br><span style="color: hsl(0, 100%, 40%);">-      ast_bridge_features_unregister(AST_BRIDGE_BUILTIN_AUTOMON);</span><br><span>  ast_bridge_features_unregister(AST_BRIDGE_BUILTIN_AUTOMIXMON);</span><br><span> </span><br><span>   return 0;</span><br><span>@@ -512,7 +316,6 @@</span><br><span> static int load_module(void)</span><br><span> {</span><br><span>         ast_bridge_features_register(AST_BRIDGE_BUILTIN_HANGUP, feature_hangup, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-  ast_bridge_features_register(AST_BRIDGE_BUILTIN_AUTOMON, feature_automonitor, NULL);</span><br><span>         ast_bridge_features_register(AST_BRIDGE_BUILTIN_AUTOMIXMON, feature_automixmonitor, NULL);</span><br><span> </span><br><span>       /* This module cannot be unloaded until shutdown */</span><br><span>@@ -525,5 +328,4 @@</span><br><span>    .support_level = AST_MODULE_SUPPORT_CORE,</span><br><span>    .load = load_module,</span><br><span>         .unload = unload_module,</span><br><span style="color: hsl(0, 100%, 40%);">-        .optional_modules = "res_monitor",</span><br><span> );</span><br><span>diff --git a/channels/Makefile b/channels/Makefile</span><br><span>index 0af82d9..706aa51 100644</span><br><span>--- a/channels/Makefile</span><br><span>+++ b/channels/Makefile</span><br><span>@@ -19,10 +19,6 @@</span><br><span> </span><br><span> include $(ASTTOPDIR)/Makefile.moddir_rules</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-ifneq ($(findstring $(OSARCH), mingw32 cygwin ),)</span><br><span style="color: hsl(0, 100%, 40%);">-  LIBS+= -lres_monitor.so</span><br><span style="color: hsl(0, 100%, 40%);">-endif</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> $(call MOD_ADD_C,chan_iax2,$(wildcard iax2/*.c))</span><br><span> iax2/parser.o: _ASTCFLAGS+=$(call get_menuselect_cflags,MALLOC_DEBUG)</span><br><span> </span><br><span>diff --git a/doc/UPGRADE-staging/res_monitor_removal.txt b/doc/UPGRADE-staging/res_monitor_removal.txt</span><br><span>new file mode 100644</span><br><span>index 0000000..81b39a7</span><br><span>--- /dev/null</span><br><span>+++ b/doc/UPGRADE-staging/res_monitor_removal.txt</span><br><span>@@ -0,0 +1,6 @@</span><br><span style="color: hsl(120, 100%, 40%);">+Subject: res_monitor</span><br><span style="color: hsl(120, 100%, 40%);">+Master-Only: True</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+This module was deprecated in Asterisk 16</span><br><span style="color: hsl(120, 100%, 40%);">+and is now being removed in accordance with</span><br><span style="color: hsl(120, 100%, 40%);">+the Asterisk Module Deprecation policy.</span><br><span>diff --git a/include/asterisk/bridge_features.h b/include/asterisk/bridge_features.h</span><br><span>index 39fb80f..b167d9d 100644</span><br><span>--- a/include/asterisk/bridge_features.h</span><br><span>+++ b/include/asterisk/bridge_features.h</span><br><span>@@ -313,11 +313,6 @@</span><br><span>        AUTO_MONITOR_STOP,</span><br><span> };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-struct ast_bridge_features_automonitor {</span><br><span style="color: hsl(0, 100%, 40%);">-    /*! Start/Stop behavior. */</span><br><span style="color: hsl(0, 100%, 40%);">-     enum ast_bridge_features_monitor start_stop;</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> struct ast_bridge_features_automixmonitor {</span><br><span>        /*! Start/Stop behavior. */</span><br><span>  enum ast_bridge_features_monitor start_stop;</span><br><span>diff --git a/include/asterisk/doxygen/architecture.h b/include/asterisk/doxygen/architecture.h</span><br><span>index 780b64f..64a6e2e 100644</span><br><span>--- a/include/asterisk/doxygen/architecture.h</span><br><span>+++ b/include/asterisk/doxygen/architecture.h</span><br><span>@@ -185,7 +185,6 @@</span><br><span>  - res_crypto.c</span><br><span>  - res_curl.c</span><br><span>  - res_xmpp.c</span><br><span style="color: hsl(0, 100%, 40%);">- - res_monitor.c</span><br><span>  - res_smdi.c</span><br><span>  - res_speech.c</span><br><span>    - provides a speech recognition engine interface.</span><br><span>diff --git a/include/asterisk/monitor.h b/include/asterisk/monitor.h</span><br><span>deleted file mode 100644</span><br><span>index 377cb62..0000000</span><br><span>--- a/include/asterisk/monitor.h</span><br><span>+++ /dev/null</span><br><span>@@ -1,66 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-/*</span><br><span style="color: hsl(0, 100%, 40%);">- * Asterisk -- An open source telephony toolkit.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * Copyright (C) 1999 - 2005, Digium, Inc.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * Mark Spencer <markster@digium.com></span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * See http://www.asterisk.org for more information about</span><br><span style="color: hsl(0, 100%, 40%);">- * the Asterisk project. Please do not directly contact</span><br><span style="color: hsl(0, 100%, 40%);">- * any of the maintainers of this project for assistance;</span><br><span style="color: hsl(0, 100%, 40%);">- * the project provides a web site, mailing lists and IRC</span><br><span style="color: hsl(0, 100%, 40%);">- * channels for your use.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * This program is free software, distributed under the terms of</span><br><span style="color: hsl(0, 100%, 40%);">- * the GNU General Public License Version 2. See the LICENSE file</span><br><span style="color: hsl(0, 100%, 40%);">- * at the top of the source tree.</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/*! \file</span><br><span style="color: hsl(0, 100%, 40%);">- * \brief Channel monitoring</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#ifndef _ASTERISK_MONITOR_H</span><br><span style="color: hsl(0, 100%, 40%);">-#define _ASTERISK_MONITOR_H</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include "asterisk/channel.h"</span><br><span style="color: hsl(0, 100%, 40%);">-#include "asterisk/optional_api.h"</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Streams recording control */</span><br><span style="color: hsl(0, 100%, 40%);">-#define X_REC_IN    1</span><br><span style="color: hsl(0, 100%, 40%);">-#define X_REC_OUT      2</span><br><span style="color: hsl(0, 100%, 40%);">-#define X_JOIN         4</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Start monitoring a channel */</span><br><span style="color: hsl(0, 100%, 40%);">-AST_OPTIONAL_API(int, ast_monitor_start,</span><br><span style="color: hsl(0, 100%, 40%);">-                (struct ast_channel *chan, const char *format_spec,</span><br><span style="color: hsl(0, 100%, 40%);">-              const char *fname_base, int need_lock, int stream_action,</span><br><span style="color: hsl(0, 100%, 40%);">-               const char *beep_id),</span><br><span style="color: hsl(0, 100%, 40%);">-          { return -1; });</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Stop monitoring a channel */</span><br><span style="color: hsl(0, 100%, 40%);">-AST_OPTIONAL_API(int, ast_monitor_stop,</span><br><span style="color: hsl(0, 100%, 40%);">-          (struct ast_channel *chan, int need_lock),</span><br><span style="color: hsl(0, 100%, 40%);">-              { return -1; });</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Change monitoring filename of a channel */</span><br><span style="color: hsl(0, 100%, 40%);">-AST_OPTIONAL_API(int, ast_monitor_change_fname,</span><br><span style="color: hsl(0, 100%, 40%);">-            (struct ast_channel *chan, const char *fname_base,</span><br><span style="color: hsl(0, 100%, 40%);">-               int need_lock),</span><br><span style="color: hsl(0, 100%, 40%);">-                { return -1; });</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-AST_OPTIONAL_API(void, ast_monitor_setjoinfiles,</span><br><span style="color: hsl(0, 100%, 40%);">-                (struct ast_channel *chan, int turnon),</span><br><span style="color: hsl(0, 100%, 40%);">-                 { return; });</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Pause monitoring of a channel */</span><br><span style="color: hsl(0, 100%, 40%);">-AST_OPTIONAL_API(int, ast_monitor_pause,</span><br><span style="color: hsl(0, 100%, 40%);">-                (struct ast_channel *chan),</span><br><span style="color: hsl(0, 100%, 40%);">-             { return -1; });</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Unpause monitoring of a channel */</span><br><span style="color: hsl(0, 100%, 40%);">-AST_OPTIONAL_API(int, ast_monitor_unpause,</span><br><span style="color: hsl(0, 100%, 40%);">-                 (struct ast_channel *chan),</span><br><span style="color: hsl(0, 100%, 40%);">-             { return -1; });</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#endif /* _ASTERISK_MONITOR_H */</span><br><span>diff --git a/main/asterisk.dynamics b/main/asterisk.dynamics</span><br><span>index 1c4b1b1..b03e272 100644</span><br><span>--- a/main/asterisk.dynamics</span><br><span>+++ b/main/asterisk.dynamics</span><br><span>@@ -4,7 +4,6 @@</span><br><span>     *ast_beep_*;</span><br><span>         *ast_pktccops_*;</span><br><span>     *ast_smdi_*;</span><br><span style="color: hsl(0, 100%, 40%);">-    *ast_monitor_*;</span><br><span>      *ast_key_get;</span><br><span>        *ast_check_signature;</span><br><span>        *ast_check_signature_bin;</span><br><span>diff --git a/menuselect/example_menuselect-tree b/menuselect/example_menuselect-tree</span><br><span>index 0b703e6..8837d77 100644</span><br><span>--- a/menuselect/example_menuselect-tree</span><br><span>+++ b/menuselect/example_menuselect-tree</span><br><span>@@ -366,8 +366,6 @@</span><br><span>                 <member name="res_jabber" displayname="AJI - Asterisk JABBER Interface" remove_on_change="res/res_jabber.o res/res_jabber.so"></span><br><span>   <depend>iksemel</depend></span><br><span>                 </member></span><br><span style="color: hsl(0, 100%, 40%);">-         <member name="res_monitor" displayname="Call Monitoring Resource" remove_on_change="res/res_monitor.o res/res_monitor.so"></span><br><span style="color: hsl(0, 100%, 40%);">-          </member></span><br><span>              <member name="res_musiconhold" displayname="Music On Hold Resource" remove_on_change="res/res_musiconhold.o res/res_musiconhold.so"></span><br><span>     <conflict>win32</conflict></span><br><span>               </member></span><br><span>diff --git a/menuselect/test/menuselect-tree b/menuselect/test/menuselect-tree</span><br><span>index 3710278..f24334e 100644</span><br><span>--- a/menuselect/test/menuselect-tree</span><br><span>+++ b/menuselect/test/menuselect-tree</span><br><span>@@ -103,7 +103,6 @@</span><br><span> <member name="app_privacy" displayname="Require phone number to be entered, if no CallerID sent" remove_on_change="apps/app_privacy.o apps/app_privacy.so"></span><br><span> </member></span><br><span> <member name="app_queue" displayname="True Call Queueing" remove_on_change="apps/app_queue.o apps/app_queue.so"></span><br><span style="color: hsl(0, 100%, 40%);">-    <depend>res_monitor</depend></span><br><span> </member></span><br><span> <member name="app_read" displayname="Read Variable Application" remove_on_change="apps/app_read.o apps/app_read.so"></span><br><span> </member></span><br><span>@@ -465,8 +464,6 @@</span><br><span> </member></span><br><span> <member name="res_limit" displayname="Resource limits" remove_on_change="res/res_limit.o res/res_limit.so"></span><br><span> </member></span><br><span style="color: hsl(0, 100%, 40%);">-<member name="res_monitor" displayname="Call Monitoring Resource" remove_on_change="res/res_monitor.o res/res_monitor.so"></span><br><span style="color: hsl(0, 100%, 40%);">-</member></span><br><span> <member name="res_musiconhold" displayname="Music On Hold Resource" remove_on_change="res/res_musiconhold.o res/res_musiconhold.so"></span><br><span>   <conflict>win32</conflict></span><br><span>       <use>dahdi</use></span><br><span>diff --git a/pbx/Makefile b/pbx/Makefile</span><br><span>index 3ef49d1..9350ece 100644</span><br><span>--- a/pbx/Makefile</span><br><span>+++ b/pbx/Makefile</span><br><span>@@ -20,7 +20,7 @@</span><br><span> include $(ASTTOPDIR)/Makefile.moddir_rules</span><br><span> </span><br><span> ifneq ($(findstring $(OSARCH), mingw32 cygwin ),)</span><br><span style="color: hsl(0, 100%, 40%);">-  LIBS+= -lres_ael_share.so -lres_monitor.so</span><br><span style="color: hsl(120, 100%, 40%);">+  LIBS+= -lres_ael_share.so</span><br><span> endif</span><br><span> </span><br><span> $(call MOD_ADD_C,pbx_dundi,dundi-parser.c)</span><br><span>diff --git a/res/res_monitor.c b/res/res_monitor.c</span><br><span>deleted file mode 100644</span><br><span>index 1264ad0..0000000</span><br><span>--- a/res/res_monitor.c</span><br><span>+++ /dev/null</span><br><span>@@ -1,1019 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-/*</span><br><span style="color: hsl(0, 100%, 40%);">- * Asterisk -- An open source telephony toolkit.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * Copyright (C) 1999 - 2005, Digium, Inc.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * Mark Spencer <markster@digium.com></span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * See http://www.asterisk.org for more information about</span><br><span style="color: hsl(0, 100%, 40%);">- * the Asterisk project. Please do not directly contact</span><br><span style="color: hsl(0, 100%, 40%);">- * any of the maintainers of this project for assistance;</span><br><span style="color: hsl(0, 100%, 40%);">- * the project provides a web site, mailing lists and IRC</span><br><span style="color: hsl(0, 100%, 40%);">- * channels for your use.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * This program is free software, distributed under the terms of</span><br><span style="color: hsl(0, 100%, 40%);">- * the GNU General Public License Version 2. See the LICENSE file</span><br><span style="color: hsl(0, 100%, 40%);">- * at the top of the source tree.</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/*! \file</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * \brief PBX channel monitoring</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * \author Mark Spencer <markster@digium.com></span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/*** MODULEINFO</span><br><span style="color: hsl(0, 100%, 40%);">-       <use type="module">func_periodic_hook</use></span><br><span style="color: hsl(0, 100%, 40%);">-       <defaultenabled>no</defaultenabled></span><br><span style="color: hsl(0, 100%, 40%);">- <support_level>deprecated</support_level></span><br><span style="color: hsl(0, 100%, 40%);">-   <replacement>app_mixmonitor</replacement></span><br><span style="color: hsl(0, 100%, 40%);">-   <deprecated_in>16</deprecated_in></span><br><span style="color: hsl(0, 100%, 40%);">-   <removed_in>21</removed_in></span><br><span style="color: hsl(0, 100%, 40%);">- ***/</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include "asterisk.h"</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include <sys/stat.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <libgen.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include "asterisk/paths.h"    /* use ast_config_AST_MONITOR_DIR */</span><br><span style="color: hsl(0, 100%, 40%);">-#include "asterisk/lock.h"</span><br><span style="color: hsl(0, 100%, 40%);">-#include "asterisk/channel.h"</span><br><span style="color: hsl(0, 100%, 40%);">-#include "asterisk/file.h"</span><br><span style="color: hsl(0, 100%, 40%);">-#include "asterisk/pbx.h"</span><br><span style="color: hsl(0, 100%, 40%);">-#include "asterisk/module.h"</span><br><span style="color: hsl(0, 100%, 40%);">-#include "asterisk/cli.h"</span><br><span style="color: hsl(0, 100%, 40%);">-#include "asterisk/manager.h"</span><br><span style="color: hsl(0, 100%, 40%);">-#include "asterisk/stasis.h"</span><br><span style="color: hsl(0, 100%, 40%);">-#include "asterisk/stasis_channels.h"</span><br><span style="color: hsl(0, 100%, 40%);">-#define AST_API_MODULE</span><br><span style="color: hsl(0, 100%, 40%);">-#include "asterisk/monitor.h"</span><br><span style="color: hsl(0, 100%, 40%);">-#undef AST_API_MODULE</span><br><span style="color: hsl(0, 100%, 40%);">-#include "asterisk/app.h"</span><br><span style="color: hsl(0, 100%, 40%);">-#include "asterisk/utils.h"</span><br><span style="color: hsl(0, 100%, 40%);">-#include "asterisk/config.h"</span><br><span style="color: hsl(0, 100%, 40%);">-#include "asterisk/options.h"</span><br><span style="color: hsl(0, 100%, 40%);">-#include "asterisk/beep.h"</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/*** DOCUMENTATION</span><br><span style="color: hsl(0, 100%, 40%);">-        <application name="Monitor" language="en_US"></span><br><span style="color: hsl(0, 100%, 40%);">-         <synopsis></span><br><span style="color: hsl(0, 100%, 40%);">-                        Monitor a channel.</span><br><span style="color: hsl(0, 100%, 40%);">-              </synopsis></span><br><span style="color: hsl(0, 100%, 40%);">-               <syntax></span><br><span style="color: hsl(0, 100%, 40%);">-                  <parameter name="file_format" argsep=":"></span><br><span style="color: hsl(0, 100%, 40%);">-                             <argument name="file_format" required="true"></span><br><span style="color: hsl(0, 100%, 40%);">-                                 <para>Optional.  If not set, defaults to <literal>wav</literal></para></span><br><span style="color: hsl(0, 100%, 40%);">-                          </argument></span><br><span style="color: hsl(0, 100%, 40%);">-                               <argument name="urlbase" /></span><br><span style="color: hsl(0, 100%, 40%);">-                     </parameter></span><br><span style="color: hsl(0, 100%, 40%);">-                      <parameter name="fname_base"></span><br><span style="color: hsl(0, 100%, 40%);">-                           <para>If set, changes the filename used to the one specified.</para></span><br><span style="color: hsl(0, 100%, 40%);">-                        </parameter></span><br><span style="color: hsl(0, 100%, 40%);">-                      <parameter name="options"></span><br><span style="color: hsl(0, 100%, 40%);">-                              <optionlist></span><br><span style="color: hsl(0, 100%, 40%);">-                                      <option name="m"></span><br><span style="color: hsl(0, 100%, 40%);">-                                               <para>When the recording ends mix the two leg files into one and</span><br><span style="color: hsl(0, 100%, 40%);">-                                          delete the two leg files. If the variable <variable>MONITOR_EXEC</variable></span><br><span style="color: hsl(0, 100%, 40%);">-                                         is set, the application referenced in it will be executed instead of</span><br><span style="color: hsl(0, 100%, 40%);">-                                            soxmix/sox and the raw leg files will NOT be deleted automatically.</span><br><span style="color: hsl(0, 100%, 40%);">-                                             soxmix/sox or <variable>MONITOR_EXEC</variable> is handed 3 arguments,</span><br><span style="color: hsl(0, 100%, 40%);">-                                              the two leg files and a target mixed file name which is the same as</span><br><span style="color: hsl(0, 100%, 40%);">-                                             the leg file names only without the in/out designator.</para></span><br><span style="color: hsl(0, 100%, 40%);">-                                             <para>If <variable>MONITOR_EXEC_ARGS</variable> is set, the contents</span><br><span style="color: hsl(0, 100%, 40%);">-                                          will be passed on as additional arguments to <variable>MONITOR_EXEC</variable>.</span><br><span style="color: hsl(0, 100%, 40%);">-                                             Both <variable>MONITOR_EXEC</variable> and the Mix flag can be set from the</span><br><span style="color: hsl(0, 100%, 40%);">-                                         administrator interface.</para></span><br><span style="color: hsl(0, 100%, 40%);">-                                           <warning><para>Do not use untrusted strings such as</span><br><span style="color: hsl(0, 100%, 40%);">-                                         <variable>CALLERID(num)</variable> or <variable>CALLERID(name)</variable></span><br><span style="color: hsl(0, 100%, 40%);">-                                               as part of <variable>MONITOR_EXEC</variable> or</span><br><span style="color: hsl(0, 100%, 40%);">-                                             <variable>MONITOR_EXEC_ARGS</variable>.  You risk a command injection</span><br><span style="color: hsl(0, 100%, 40%);">-                                               attack executing arbitrary commands if the untrusted strings aren't</span><br><span style="color: hsl(0, 100%, 40%);">-                                         filtered to remove dangerous characters.  See function</span><br><span style="color: hsl(0, 100%, 40%);">-                                          <variable>FILTER()</variable>.</para></warning></span><br><span style="color: hsl(0, 100%, 40%);">-                                 </option></span><br><span style="color: hsl(0, 100%, 40%);">-                                 <option name="b"></span><br><span style="color: hsl(0, 100%, 40%);">-                                               <para>Don't begin recording unless a call is bridged to another channel.</para></span><br><span style="color: hsl(0, 100%, 40%);">-                                 </option></span><br><span style="color: hsl(0, 100%, 40%);">-                                 <option name="B"></span><br><span style="color: hsl(0, 100%, 40%);">-                                               <para>Play a periodic beep while this call is being recorded.</para></span><br><span style="color: hsl(0, 100%, 40%);">-                                                <argument name="interval"><para>Interval, in seconds. Default is 15.</para></argument></span><br><span style="color: hsl(0, 100%, 40%);">-                                        </option></span><br><span style="color: hsl(0, 100%, 40%);">-                                 <option name="i"></span><br><span style="color: hsl(0, 100%, 40%);">-                                               <para>Skip recording of input stream (disables <literal>m</literal> option).</para></span><br><span style="color: hsl(0, 100%, 40%);">-                                     </option></span><br><span style="color: hsl(0, 100%, 40%);">-                                 <option name="o"></span><br><span style="color: hsl(0, 100%, 40%);">-                                               <para>Skip recording of output stream (disables <literal>m</literal> option).</para></span><br><span style="color: hsl(0, 100%, 40%);">-                                    </option></span><br><span style="color: hsl(0, 100%, 40%);">-                         </optionlist></span><br><span style="color: hsl(0, 100%, 40%);">-                     </parameter></span><br><span style="color: hsl(0, 100%, 40%);">-              </syntax></span><br><span style="color: hsl(0, 100%, 40%);">-         <description></span><br><span style="color: hsl(0, 100%, 40%);">-                     <para>Used to start monitoring a channel. The channel's input and output</span><br><span style="color: hsl(0, 100%, 40%);">-                      voice packets are logged to files until the channel hangs up or</span><br><span style="color: hsl(0, 100%, 40%);">-                 monitoring is stopped by the StopMonitor application.</para></span><br><span style="color: hsl(0, 100%, 40%);">-                      <para>By default, files are stored to <filename>/var/spool/asterisk/monitor/</filename>.</span><br><span style="color: hsl(0, 100%, 40%);">-                      Returns <literal>-1</literal> if monitor files can't be opened or if the channel is</span><br><span style="color: hsl(0, 100%, 40%);">-                     already monitored, otherwise <literal>0</literal>.</para></span><br><span style="color: hsl(0, 100%, 40%);">-             </description></span><br><span style="color: hsl(0, 100%, 40%);">-            <see-also></span><br><span style="color: hsl(0, 100%, 40%);">-                        <ref type="application">StopMonitor</ref></span><br><span style="color: hsl(0, 100%, 40%);">-         </see-also></span><br><span style="color: hsl(0, 100%, 40%);">-       </application></span><br><span style="color: hsl(0, 100%, 40%);">-    <application name="StopMonitor" language="en_US"></span><br><span style="color: hsl(0, 100%, 40%);">-             <synopsis></span><br><span style="color: hsl(0, 100%, 40%);">-                        Stop monitoring a channel.</span><br><span style="color: hsl(0, 100%, 40%);">-              </synopsis></span><br><span style="color: hsl(0, 100%, 40%);">-               <syntax /></span><br><span style="color: hsl(0, 100%, 40%);">-                <description></span><br><span style="color: hsl(0, 100%, 40%);">-                     <para>Stops monitoring a channel. Has no effect if the channel is not monitored.</para></span><br><span style="color: hsl(0, 100%, 40%);">-             </description></span><br><span style="color: hsl(0, 100%, 40%);">-    </application></span><br><span style="color: hsl(0, 100%, 40%);">-    <application name="ChangeMonitor" language="en_US"></span><br><span style="color: hsl(0, 100%, 40%);">-           <synopsis></span><br><span style="color: hsl(0, 100%, 40%);">-                        Change monitoring filename of a channel.</span><br><span style="color: hsl(0, 100%, 40%);">-                </synopsis></span><br><span style="color: hsl(0, 100%, 40%);">-               <syntax></span><br><span style="color: hsl(0, 100%, 40%);">-                  <parameter name="filename_base" required="true"></span><br><span style="color: hsl(0, 100%, 40%);">-                              <para>The new filename base to use for monitoring this channel.</para></span><br><span style="color: hsl(0, 100%, 40%);">-                      </parameter></span><br><span style="color: hsl(0, 100%, 40%);">-              </syntax></span><br><span style="color: hsl(0, 100%, 40%);">-         <description></span><br><span style="color: hsl(0, 100%, 40%);">-                     <para>Changes monitoring filename of a channel. Has no effect if the</span><br><span style="color: hsl(0, 100%, 40%);">-                      channel is not monitored.</para></span><br><span style="color: hsl(0, 100%, 40%);">-          </description></span><br><span style="color: hsl(0, 100%, 40%);">-    </application></span><br><span style="color: hsl(0, 100%, 40%);">-    <application name="PauseMonitor" language="en_US"></span><br><span style="color: hsl(0, 100%, 40%);">-            <synopsis></span><br><span style="color: hsl(0, 100%, 40%);">-                        Pause monitoring of a channel.</span><br><span style="color: hsl(0, 100%, 40%);">-          </synopsis></span><br><span style="color: hsl(0, 100%, 40%);">-               <syntax /></span><br><span style="color: hsl(0, 100%, 40%);">-                <description></span><br><span style="color: hsl(0, 100%, 40%);">-                     <para>Pauses monitoring of a channel until it is re-enabled by a call to UnpauseMonitor.</para></span><br><span style="color: hsl(0, 100%, 40%);">-             </description></span><br><span style="color: hsl(0, 100%, 40%);">-            <see-also></span><br><span style="color: hsl(0, 100%, 40%);">-                        <ref type="application">UnpauseMonitor</ref></span><br><span style="color: hsl(0, 100%, 40%);">-              </see-also></span><br><span style="color: hsl(0, 100%, 40%);">-       </application></span><br><span style="color: hsl(0, 100%, 40%);">-    <application name="UnpauseMonitor" language="en_US"></span><br><span style="color: hsl(0, 100%, 40%);">-          <synopsis></span><br><span style="color: hsl(0, 100%, 40%);">-                        Unpause monitoring of a channel.</span><br><span style="color: hsl(0, 100%, 40%);">-                </synopsis></span><br><span style="color: hsl(0, 100%, 40%);">-               <syntax /></span><br><span style="color: hsl(0, 100%, 40%);">-                <description></span><br><span style="color: hsl(0, 100%, 40%);">-                     <para>Unpauses monitoring of a channel on which monitoring had</span><br><span style="color: hsl(0, 100%, 40%);">-                    previously been paused with PauseMonitor.</para></span><br><span style="color: hsl(0, 100%, 40%);">-          </description></span><br><span style="color: hsl(0, 100%, 40%);">-            <see-also></span><br><span style="color: hsl(0, 100%, 40%);">-                        <ref type="application">PauseMonitor</ref></span><br><span style="color: hsl(0, 100%, 40%);">-                </see-also></span><br><span style="color: hsl(0, 100%, 40%);">-       </application></span><br><span style="color: hsl(0, 100%, 40%);">-    <manager name="Monitor" language="en_US"></span><br><span style="color: hsl(0, 100%, 40%);">-             <synopsis></span><br><span style="color: hsl(0, 100%, 40%);">-                        Monitor a channel.</span><br><span style="color: hsl(0, 100%, 40%);">-              </synopsis></span><br><span style="color: hsl(0, 100%, 40%);">-               <syntax></span><br><span style="color: hsl(0, 100%, 40%);">-                  <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" /></span><br><span style="color: hsl(0, 100%, 40%);">-                     <parameter name="Channel" required="true"></span><br><span style="color: hsl(0, 100%, 40%);">-                            <para>Used to specify the channel to record.</para></span><br><span style="color: hsl(0, 100%, 40%);">-                 </parameter></span><br><span style="color: hsl(0, 100%, 40%);">-                      <parameter name="File"></span><br><span style="color: hsl(0, 100%, 40%);">-                         <para>Is the name of the file created in the monitor spool directory.</span><br><span style="color: hsl(0, 100%, 40%);">-                             Defaults to the same name as the channel (with slashes replaced with dashes).</para></span><br><span style="color: hsl(0, 100%, 40%);">-                      </parameter></span><br><span style="color: hsl(0, 100%, 40%);">-                      <parameter name="Format"></span><br><span style="color: hsl(0, 100%, 40%);">-                               <para>Is the audio recording format. Defaults to <literal>wav</literal>.</para></span><br><span style="color: hsl(0, 100%, 40%);">-                 </parameter></span><br><span style="color: hsl(0, 100%, 40%);">-                      <parameter name="Mix"></span><br><span style="color: hsl(0, 100%, 40%);">-                          <para>Boolean parameter as to whether to mix the input and output channels</span><br><span style="color: hsl(0, 100%, 40%);">-                                together after the recording is finished.</para></span><br><span style="color: hsl(0, 100%, 40%);">-                  </parameter></span><br><span style="color: hsl(0, 100%, 40%);">-              </syntax></span><br><span style="color: hsl(0, 100%, 40%);">-         <description></span><br><span style="color: hsl(0, 100%, 40%);">-                     <para>This action may be used to record the audio on a</span><br><span style="color: hsl(0, 100%, 40%);">-                    specified channel.</para></span><br><span style="color: hsl(0, 100%, 40%);">-         </description></span><br><span style="color: hsl(0, 100%, 40%);">-    </manager></span><br><span style="color: hsl(0, 100%, 40%);">-        <manager name="StopMonitor" language="en_US"></span><br><span style="color: hsl(0, 100%, 40%);">-         <synopsis></span><br><span style="color: hsl(0, 100%, 40%);">-                        Stop monitoring a channel.</span><br><span style="color: hsl(0, 100%, 40%);">-              </synopsis></span><br><span style="color: hsl(0, 100%, 40%);">-               <syntax></span><br><span style="color: hsl(0, 100%, 40%);">-                  <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" /></span><br><span style="color: hsl(0, 100%, 40%);">-                     <parameter name="Channel" required="true"></span><br><span style="color: hsl(0, 100%, 40%);">-                            <para>The name of the channel monitored.</para></span><br><span style="color: hsl(0, 100%, 40%);">-                     </parameter></span><br><span style="color: hsl(0, 100%, 40%);">-              </syntax></span><br><span style="color: hsl(0, 100%, 40%);">-         <description></span><br><span style="color: hsl(0, 100%, 40%);">-                     <para>This action may be used to end a previously started 'Monitor' action.</para></span><br><span style="color: hsl(0, 100%, 40%);">-          </description></span><br><span style="color: hsl(0, 100%, 40%);">-    </manager></span><br><span style="color: hsl(0, 100%, 40%);">-        <manager name="ChangeMonitor" language="en_US"></span><br><span style="color: hsl(0, 100%, 40%);">-               <synopsis></span><br><span style="color: hsl(0, 100%, 40%);">-                        Change monitoring filename of a channel.</span><br><span style="color: hsl(0, 100%, 40%);">-                </synopsis></span><br><span style="color: hsl(0, 100%, 40%);">-               <syntax></span><br><span style="color: hsl(0, 100%, 40%);">-                  <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" /></span><br><span style="color: hsl(0, 100%, 40%);">-                     <parameter name="Channel" required="true"></span><br><span style="color: hsl(0, 100%, 40%);">-                            <para>Used to specify the channel to record.</para></span><br><span style="color: hsl(0, 100%, 40%);">-                 </parameter></span><br><span style="color: hsl(0, 100%, 40%);">-                      <parameter name="File" required="true"></span><br><span style="color: hsl(0, 100%, 40%);">-                               <para>Is the new name of the file created in the</span><br><span style="color: hsl(0, 100%, 40%);">-                          monitor spool directory.</para></span><br><span style="color: hsl(0, 100%, 40%);">-                   </parameter></span><br><span style="color: hsl(0, 100%, 40%);">-              </syntax></span><br><span style="color: hsl(0, 100%, 40%);">-         <description></span><br><span style="color: hsl(0, 100%, 40%);">-                     <para>This action may be used to change the file</span><br><span style="color: hsl(0, 100%, 40%);">-                  started by a previous 'Monitor' action.</para></span><br><span style="color: hsl(0, 100%, 40%);">-            </description></span><br><span style="color: hsl(0, 100%, 40%);">-    </manager></span><br><span style="color: hsl(0, 100%, 40%);">-        <manager name="PauseMonitor" language="en_US"></span><br><span style="color: hsl(0, 100%, 40%);">-                <synopsis></span><br><span style="color: hsl(0, 100%, 40%);">-                        Pause monitoring of a channel.</span><br><span style="color: hsl(0, 100%, 40%);">-          </synopsis></span><br><span style="color: hsl(0, 100%, 40%);">-               <syntax></span><br><span style="color: hsl(0, 100%, 40%);">-                  <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" /></span><br><span style="color: hsl(0, 100%, 40%);">-                     <parameter name="Channel" required="true"></span><br><span style="color: hsl(0, 100%, 40%);">-                            <para>Used to specify the channel to record.</para></span><br><span style="color: hsl(0, 100%, 40%);">-                 </parameter></span><br><span style="color: hsl(0, 100%, 40%);">-              </syntax></span><br><span style="color: hsl(0, 100%, 40%);">-         <description></span><br><span style="color: hsl(0, 100%, 40%);">-                     <para>This action may be used to temporarily stop the</span><br><span style="color: hsl(0, 100%, 40%);">-                     recording of a channel.</para></span><br><span style="color: hsl(0, 100%, 40%);">-            </description></span><br><span style="color: hsl(0, 100%, 40%);">-    </manager></span><br><span style="color: hsl(0, 100%, 40%);">-        <manager name="UnpauseMonitor" language="en_US"></span><br><span style="color: hsl(0, 100%, 40%);">-              <synopsis></span><br><span style="color: hsl(0, 100%, 40%);">-                        Unpause monitoring of a channel.</span><br><span style="color: hsl(0, 100%, 40%);">-                </synopsis></span><br><span style="color: hsl(0, 100%, 40%);">-               <syntax></span><br><span style="color: hsl(0, 100%, 40%);">-                  <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" /></span><br><span style="color: hsl(0, 100%, 40%);">-                     <parameter name="Channel" required="true"></span><br><span style="color: hsl(0, 100%, 40%);">-                            <para>Used to specify the channel to record.</para></span><br><span style="color: hsl(0, 100%, 40%);">-                 </parameter></span><br><span style="color: hsl(0, 100%, 40%);">-              </syntax></span><br><span style="color: hsl(0, 100%, 40%);">-         <description></span><br><span style="color: hsl(0, 100%, 40%);">-                     <para>This action may be used to re-enable recording</span><br><span style="color: hsl(0, 100%, 40%);">-                      of a channel after calling PauseMonitor.</para></span><br><span style="color: hsl(0, 100%, 40%);">-           </description></span><br><span style="color: hsl(0, 100%, 40%);">-    </manager></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- ***/</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-AST_MUTEX_DEFINE_STATIC(monitorlock);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#define LOCK_IF_NEEDED(lock, needed) do { \</span><br><span style="color: hsl(0, 100%, 40%);">-   if (needed) \</span><br><span style="color: hsl(0, 100%, 40%);">-           ast_channel_lock(lock); \</span><br><span style="color: hsl(0, 100%, 40%);">-       } while(0)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#define UNLOCK_IF_NEEDED(lock, needed) do { \</span><br><span style="color: hsl(0, 100%, 40%);">- if (needed) \</span><br><span style="color: hsl(0, 100%, 40%);">-           ast_channel_unlock(lock); \</span><br><span style="color: hsl(0, 100%, 40%);">-     } while (0)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static unsigned long seq = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/*!</span><br><span style="color: hsl(0, 100%, 40%);">- * \brief Change state of monitored channel</span><br><span style="color: hsl(0, 100%, 40%);">- * \param chan</span><br><span style="color: hsl(0, 100%, 40%);">- * \param state monitor state</span><br><span style="color: hsl(0, 100%, 40%);">- * \retval 0 on success.</span><br><span style="color: hsl(0, 100%, 40%);">- * \retval -1 on failure.</span><br><span style="color: hsl(0, 100%, 40%);">-*/</span><br><span style="color: hsl(0, 100%, 40%);">-static int ast_monitor_set_state(struct ast_channel *chan, int state)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      LOCK_IF_NEEDED(chan, 1);</span><br><span style="color: hsl(0, 100%, 40%);">-        if (!ast_channel_monitor(chan)) {</span><br><span style="color: hsl(0, 100%, 40%);">-               UNLOCK_IF_NEEDED(chan, 1);</span><br><span style="color: hsl(0, 100%, 40%);">-              return -1;</span><br><span style="color: hsl(0, 100%, 40%);">-      }</span><br><span style="color: hsl(0, 100%, 40%);">-       ast_channel_monitor(chan)->state = state;</span><br><span style="color: hsl(0, 100%, 40%);">-    UNLOCK_IF_NEEDED(chan, 1);</span><br><span style="color: hsl(0, 100%, 40%);">-      return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/*! \brief Start monitoring a channel</span><br><span style="color: hsl(0, 100%, 40%);">- * \param chan ast_channel struct to record</span><br><span style="color: hsl(0, 100%, 40%);">- * \param format_spec file format to use for recording</span><br><span style="color: hsl(0, 100%, 40%);">- * \param fname_base filename base to record to</span><br><span style="color: hsl(0, 100%, 40%);">- * \param need_lock whether to lock the channel mutex</span><br><span style="color: hsl(0, 100%, 40%);">- * \param stream_action whether to record the input and/or output streams.  X_REC_IN | X_REC_OUT is most often used</span><br><span style="color: hsl(0, 100%, 40%);">- * \param beep_id</span><br><span style="color: hsl(0, 100%, 40%);">- * Creates the file to record, if no format is specified it assumes WAV</span><br><span style="color: hsl(0, 100%, 40%);">- * It also sets channel variable __MONITORED=yes</span><br><span style="color: hsl(0, 100%, 40%);">- * \retval 0 on success</span><br><span style="color: hsl(0, 100%, 40%);">- * \retval -1 on failure</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">-int AST_OPTIONAL_API_NAME(ast_monitor_start)(struct ast_channel *chan, const char *format_spec,</span><br><span style="color: hsl(0, 100%, 40%);">-                                             const char *fname_base, int need_lock, int stream_action,</span><br><span style="color: hsl(0, 100%, 40%);">-                                       const char *beep_id)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      int res = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-    RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  LOCK_IF_NEEDED(chan, need_lock);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        if (!(ast_channel_monitor(chan))) {</span><br><span style="color: hsl(0, 100%, 40%);">-             struct ast_channel_monitor *monitor;</span><br><span style="color: hsl(0, 100%, 40%);">-            char *channel_name, *p;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-         /* Create monitoring directory if needed */</span><br><span style="color: hsl(0, 100%, 40%);">-             ast_mkdir(ast_config_AST_MONITOR_DIR, 0777);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-            if (!(monitor = ast_calloc(1, sizeof(*monitor)))) {</span><br><span style="color: hsl(0, 100%, 40%);">-                     UNLOCK_IF_NEEDED(chan, need_lock);</span><br><span style="color: hsl(0, 100%, 40%);">-                      return -1;</span><br><span style="color: hsl(0, 100%, 40%);">-              }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-               if (!ast_strlen_zero(beep_id)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                        ast_copy_string(monitor->beep_id, beep_id, sizeof(monitor->beep_id));</span><br><span style="color: hsl(0, 100%, 40%);">-             }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-               /* Determine file names */</span><br><span style="color: hsl(0, 100%, 40%);">-              if (!ast_strlen_zero(fname_base)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                     int directory = strchr(fname_base, '/') ? 1 : 0;</span><br><span style="color: hsl(0, 100%, 40%);">-                        const char *absolute = *fname_base == '/' ? "" : ast_config_AST_MONITOR_DIR;</span><br><span style="color: hsl(0, 100%, 40%);">-                  const char *absolute_suffix = *fname_base == '/' ? "" : "/";</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                        snprintf(monitor->read_filename, FILENAME_MAX, "%s%s%s-in",</span><br><span style="color: hsl(0, 100%, 40%);">-                                                absolute, absolute_suffix, fname_base);</span><br><span style="color: hsl(0, 100%, 40%);">-                 snprintf(monitor->write_filename, FILENAME_MAX, "%s%s%s-out",</span><br><span style="color: hsl(0, 100%, 40%);">-                                              absolute, absolute_suffix, fname_base);</span><br><span style="color: hsl(0, 100%, 40%);">-                 snprintf(monitor->filename_base, FILENAME_MAX, "%s%s%s",</span><br><span style="color: hsl(0, 100%, 40%);">-                                           absolute, absolute_suffix, fname_base);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                 /* try creating the directory just in case it doesn't exist */</span><br><span style="color: hsl(0, 100%, 40%);">-                      if (directory) {</span><br><span style="color: hsl(0, 100%, 40%);">-                                char *name = ast_strdupa(monitor->filename_base);</span><br><span style="color: hsl(0, 100%, 40%);">-                            ast_mkdir(dirname(name), 0777);</span><br><span style="color: hsl(0, 100%, 40%);">-                 }</span><br><span style="color: hsl(0, 100%, 40%);">-               } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                        ast_mutex_lock(&monitorlock);</span><br><span style="color: hsl(0, 100%, 40%);">-                       snprintf(monitor->read_filename, FILENAME_MAX, "%s/audio-in-%lu",</span><br><span style="color: hsl(0, 100%, 40%);">-                                          ast_config_AST_MONITOR_DIR, seq);</span><br><span style="color: hsl(0, 100%, 40%);">-                       snprintf(monitor->write_filename, FILENAME_MAX, "%s/audio-out-%lu",</span><br><span style="color: hsl(0, 100%, 40%);">-                                                ast_config_AST_MONITOR_DIR, seq);</span><br><span style="color: hsl(0, 100%, 40%);">-                       seq++;</span><br><span style="color: hsl(0, 100%, 40%);">-                  ast_mutex_unlock(&monitorlock);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                     /* Replace all '/' chars from the channel name with '-' chars. */</span><br><span style="color: hsl(0, 100%, 40%);">-                       channel_name = ast_strdupa(ast_channel_name(chan));</span><br><span style="color: hsl(0, 100%, 40%);">-                     for (p = channel_name; (p = strchr(p, '/')); ) {</span><br><span style="color: hsl(0, 100%, 40%);">-                                *p = '-';</span><br><span style="color: hsl(0, 100%, 40%);">-                       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                       snprintf(monitor->filename_base, FILENAME_MAX, "%s/%d-%s",</span><br><span style="color: hsl(0, 100%, 40%);">-                                  ast_config_AST_MONITOR_DIR, (int)time(NULL), channel_name);</span><br><span style="color: hsl(0, 100%, 40%);">-                    monitor->filename_changed = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-               }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-               monitor->stop = ast_monitor_stop;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-            /* Determine file format */</span><br><span style="color: hsl(0, 100%, 40%);">-             if (!ast_strlen_zero(format_spec)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                    monitor->format = ast_strdup(format_spec);</span><br><span style="color: hsl(0, 100%, 40%);">-           } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                        monitor->format = ast_strdup("wav");</span><br><span style="color: hsl(0, 100%, 40%);">-               }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-               /* open files */</span><br><span style="color: hsl(0, 100%, 40%);">-                if (stream_action & X_REC_IN) {</span><br><span style="color: hsl(0, 100%, 40%);">-                     if (ast_fileexists(monitor->read_filename, NULL, NULL) > 0)</span><br><span style="color: hsl(0, 100%, 40%);">-                               ast_filedelete(monitor->read_filename, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-                        if (!(monitor->read_stream = ast_writefile(monitor->read_filename,</span><br><span style="color: hsl(0, 100%, 40%);">-                                                        monitor->format, NULL,</span><br><span style="color: hsl(0, 100%, 40%);">-                                                       O_CREAT|O_TRUNC|O_WRONLY, 0, AST_FILE_MODE))) {</span><br><span style="color: hsl(0, 100%, 40%);">-                         ast_log(LOG_WARNING, "Could not create file %s\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                                                    monitor->read_filename);</span><br><span style="color: hsl(0, 100%, 40%);">-                             ast_free(monitor);</span><br><span style="color: hsl(0, 100%, 40%);">-                              UNLOCK_IF_NEEDED(chan, need_lock);</span><br><span style="color: hsl(0, 100%, 40%);">-                              return -1;</span><br><span style="color: hsl(0, 100%, 40%);">-                      }</span><br><span style="color: hsl(0, 100%, 40%);">-               } else</span><br><span style="color: hsl(0, 100%, 40%);">-                  monitor->read_stream = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-         if (stream_action & X_REC_OUT) {</span><br><span style="color: hsl(0, 100%, 40%);">-                    if (ast_fileexists(monitor->write_filename, NULL, NULL) > 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                            ast_filedelete(monitor->write_filename, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-                       }</span><br><span style="color: hsl(0, 100%, 40%);">-                       if (!(monitor->write_stream = ast_writefile(monitor->write_filename,</span><br><span style="color: hsl(0, 100%, 40%);">-                                                      monitor->format, NULL,</span><br><span style="color: hsl(0, 100%, 40%);">-                                                       O_CREAT|O_TRUNC|O_WRONLY, 0, AST_FILE_MODE))) {</span><br><span style="color: hsl(0, 100%, 40%);">-                         ast_log(LOG_WARNING, "Could not create file %s\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                                                    monitor->write_filename);</span><br><span style="color: hsl(0, 100%, 40%);">-                            if (monitor->read_stream) {</span><br><span style="color: hsl(0, 100%, 40%);">-                                  ast_closestream(monitor->read_stream);</span><br><span style="color: hsl(0, 100%, 40%);">-                               }</span><br><span style="color: hsl(0, 100%, 40%);">-                               ast_free(monitor);</span><br><span style="color: hsl(0, 100%, 40%);">-                              UNLOCK_IF_NEEDED(chan, need_lock);</span><br><span style="color: hsl(0, 100%, 40%);">-                              return -1;</span><br><span style="color: hsl(0, 100%, 40%);">-                      }</span><br><span style="color: hsl(0, 100%, 40%);">-               } else</span><br><span style="color: hsl(0, 100%, 40%);">-                  monitor->write_stream = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                ast_channel_insmpl_set(chan, 0);</span><br><span style="color: hsl(0, 100%, 40%);">-                ast_channel_outsmpl_set(chan, 0);</span><br><span style="color: hsl(0, 100%, 40%);">-               ast_channel_monitor_set(chan, monitor);</span><br><span style="color: hsl(0, 100%, 40%);">-         ast_monitor_set_state(chan, AST_MONITOR_RUNNING);</span><br><span style="color: hsl(0, 100%, 40%);">-               /* so we know this call has been monitored in case we need to bill for it or something */</span><br><span style="color: hsl(0, 100%, 40%);">-               pbx_builtin_setvar_helper(chan, "__MONITORED","true");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-              message = ast_channel_blob_create_from_cache(ast_channel_uniqueid(chan),</span><br><span style="color: hsl(0, 100%, 40%);">-                                ast_channel_monitor_start_type(),</span><br><span style="color: hsl(0, 100%, 40%);">-                               NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-          if (message) {</span><br><span style="color: hsl(0, 100%, 40%);">-                  stasis_publish(ast_channel_topic(chan), message);</span><br><span style="color: hsl(0, 100%, 40%);">-               }</span><br><span style="color: hsl(0, 100%, 40%);">-       } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                ast_debug(1,"Cannot start monitoring %s, already monitored\n", ast_channel_name(chan));</span><br><span style="color: hsl(0, 100%, 40%);">-               res = -1;</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       UNLOCK_IF_NEEDED(chan, need_lock);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      return res;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/*!</span><br><span style="color: hsl(0, 100%, 40%);">- * \brief Get audio format.</span><br><span style="color: hsl(0, 100%, 40%);">- * \param format recording format.</span><br><span style="color: hsl(0, 100%, 40%);">- * The file format extensions that Asterisk uses are not all the same as that</span><br><span style="color: hsl(0, 100%, 40%);">- * which soxmix expects.  This function ensures that the format used as the</span><br><span style="color: hsl(0, 100%, 40%);">- * extension on the filename is something soxmix will understand.</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">-static const char *get_soxmix_format(const char *format)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-       const char *res = format;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (!strcasecmp(format,"ulaw"))</span><br><span style="color: hsl(0, 100%, 40%);">-               res = "ul";</span><br><span style="color: hsl(0, 100%, 40%);">-   if (!strcasecmp(format,"alaw"))</span><br><span style="color: hsl(0, 100%, 40%);">-               res = "al";</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   return res;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/*!</span><br><span style="color: hsl(0, 100%, 40%);">- * \brief Stop monitoring channel</span><br><span style="color: hsl(0, 100%, 40%);">- * \param chan</span><br><span style="color: hsl(0, 100%, 40%);">- * \param need_lock</span><br><span style="color: hsl(0, 100%, 40%);">- * Stop the recording, close any open streams, mix in/out channels if required</span><br><span style="color: hsl(0, 100%, 40%);">- * \retval 0 Always</span><br><span style="color: hsl(0, 100%, 40%);">-*/</span><br><span style="color: hsl(0, 100%, 40%);">-int AST_OPTIONAL_API_NAME(ast_monitor_stop)(struct ast_channel *chan, int need_lock)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-       int delfiles = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-       RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  LOCK_IF_NEEDED(chan, need_lock);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        if (ast_channel_monitor(chan)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                RAII_VAR(struct ast_str *, tmp, ast_str_create(1024), ast_free);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                if (ast_channel_monitor(chan)->read_stream) {</span><br><span style="color: hsl(0, 100%, 40%);">-                        ast_closestream(ast_channel_monitor(chan)->read_stream);</span><br><span style="color: hsl(0, 100%, 40%);">-             }</span><br><span style="color: hsl(0, 100%, 40%);">-               if (ast_channel_monitor(chan)->write_stream) {</span><br><span style="color: hsl(0, 100%, 40%);">-                       ast_closestream(ast_channel_monitor(chan)->write_stream);</span><br><span style="color: hsl(0, 100%, 40%);">-            }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-               if (tmp && ast_channel_monitor(chan)->filename_changed && !ast_strlen_zero(ast_channel_monitor(chan)->filename_base)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                   if (ast_fileexists(ast_channel_monitor(chan)->read_filename,NULL,NULL) > 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                             ast_str_set(&tmp, 0, "%s-in", ast_channel_monitor(chan)->filename_base);</span><br><span style="color: hsl(0, 100%, 40%);">-                               if (ast_fileexists(ast_str_buffer(tmp), NULL, NULL) > 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                                   ast_filedelete(ast_str_buffer(tmp), NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-                              }</span><br><span style="color: hsl(0, 100%, 40%);">-                               ast_filerename(ast_channel_monitor(chan)->read_filename, ast_str_buffer(tmp), ast_channel_monitor(chan)->format);</span><br><span style="color: hsl(0, 100%, 40%);">-                 } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                                ast_log(LOG_WARNING, "File %s not found\n", ast_channel_monitor(chan)->read_filename);</span><br><span style="color: hsl(0, 100%, 40%);">-                     }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                       if (tmp && ast_fileexists(ast_channel_monitor(chan)->write_filename,NULL,NULL) > 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                             ast_str_set(&tmp, 0, "%s-out", ast_channel_monitor(chan)->filename_base);</span><br><span style="color: hsl(0, 100%, 40%);">-                              if (ast_fileexists(ast_str_buffer(tmp), NULL, NULL) > 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                                   ast_filedelete(ast_str_buffer(tmp), NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-                              }</span><br><span style="color: hsl(0, 100%, 40%);">-                               ast_filerename(ast_channel_monitor(chan)->write_filename, ast_str_buffer(tmp), ast_channel_monitor(chan)->format);</span><br><span style="color: hsl(0, 100%, 40%);">-                        } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                                ast_log(LOG_WARNING, "File %s not found\n", ast_channel_monitor(chan)->write_filename);</span><br><span style="color: hsl(0, 100%, 40%);">-                    }</span><br><span style="color: hsl(0, 100%, 40%);">-               }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-               if (tmp && ast_channel_monitor(chan)->joinfiles && !ast_strlen_zero(ast_channel_monitor(chan)->filename_base)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                  const char *format = !strcasecmp(ast_channel_monitor(chan)->format,"wav49") ? "WAV" : ast_channel_monitor(chan)->format;</span><br><span style="color: hsl(0, 100%, 40%);">-                      char *fname_base = ast_channel_monitor(chan)->filename_base;</span><br><span style="color: hsl(0, 100%, 40%);">-                 const char *execute, *execute_args;</span><br><span style="color: hsl(0, 100%, 40%);">-                     /* at this point, fname_base really is the full path */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                 /* Set the execute application */</span><br><span style="color: hsl(0, 100%, 40%);">-                       execute = pbx_builtin_getvar_helper(chan, "MONITOR_EXEC");</span><br><span style="color: hsl(0, 100%, 40%);">-                    if (ast_strlen_zero(execute)) {</span><br><span style="color: hsl(0, 100%, 40%);">-#ifdef HAVE_SOXMIX</span><br><span style="color: hsl(0, 100%, 40%);">-                               execute = "nice -n 19 soxmix";</span><br><span style="color: hsl(0, 100%, 40%);">-#else</span><br><span style="color: hsl(0, 100%, 40%);">-                           execute = "nice -n 19 sox -m";</span><br><span style="color: hsl(0, 100%, 40%);">-#endif</span><br><span style="color: hsl(0, 100%, 40%);">-                          format = get_soxmix_format(format);</span><br><span style="color: hsl(0, 100%, 40%);">-                             delfiles = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-                   }</span><br><span style="color: hsl(0, 100%, 40%);">-                       execute_args = pbx_builtin_getvar_helper(chan, "MONITOR_EXEC_ARGS");</span><br><span style="color: hsl(0, 100%, 40%);">-                  if (ast_strlen_zero(execute_args)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                            execute_args = "";</span><br><span style="color: hsl(0, 100%, 40%);">-                    }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                       ast_str_set(&tmp, 0, delfiles ? "( " : "");</span><br><span style="color: hsl(0, 100%, 40%);">-                     ast_str_append(&tmp, 0, "%s \"%s-in.%s\" \"%s-out.%s\" \"%s.%s\" %s &",</span><br><span style="color: hsl(0, 100%, 40%);">-                         execute, fname_base, format, fname_base, format, fname_base, format,execute_args);</span><br><span style="color: hsl(0, 100%, 40%);">-                      if (delfiles) {</span><br><span style="color: hsl(0, 100%, 40%);">-                         /* remove legs when done mixing */</span><br><span style="color: hsl(0, 100%, 40%);">-                              ast_str_append(&tmp, 0, "& rm -f \"%s-\"* ) &", fname_base);</span><br><span style="color: hsl(0, 100%, 40%);">-                    }</span><br><span style="color: hsl(0, 100%, 40%);">-                       ast_debug(1,"monitor executing %s\n", ast_str_buffer(tmp));</span><br><span style="color: hsl(0, 100%, 40%);">-                   if (ast_safe_system(ast_str_buffer(tmp)) == -1)</span><br><span style="color: hsl(0, 100%, 40%);">-                         ast_log(LOG_WARNING, "Execute of %s failed.\n", ast_str_buffer(tmp));</span><br><span style="color: hsl(0, 100%, 40%);">-         }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-               if (!ast_strlen_zero(ast_channel_monitor(chan)->beep_id)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                  ast_beep_stop(chan, ast_channel_monitor(chan)->beep_id);</span><br><span style="color: hsl(0, 100%, 40%);">-             }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-               ast_free(ast_channel_monitor(chan)->format);</span><br><span style="color: hsl(0, 100%, 40%);">-         ast_free(ast_channel_monitor(chan));</span><br><span style="color: hsl(0, 100%, 40%);">-            ast_channel_monitor_set(chan, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-            message = ast_channel_blob_create_from_cache(ast_channel_uniqueid(chan),</span><br><span style="color: hsl(0, 100%, 40%);">-                                ast_channel_monitor_stop_type(),</span><br><span style="color: hsl(0, 100%, 40%);">-                                NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-          if (message) {</span><br><span style="color: hsl(0, 100%, 40%);">-                  stasis_publish(ast_channel_topic(chan), message);</span><br><span style="color: hsl(0, 100%, 40%);">-               }</span><br><span style="color: hsl(0, 100%, 40%);">-               pbx_builtin_setvar_helper(chan, "MONITORED", NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-   }</span><br><span style="color: hsl(0, 100%, 40%);">-       pbx_builtin_setvar_helper(chan, "AUTO_MONITOR", NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        UNLOCK_IF_NEEDED(chan, need_lock);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/*! \brief Pause monitoring of channel */</span><br><span style="color: hsl(0, 100%, 40%);">-int AST_OPTIONAL_API_NAME(ast_monitor_pause)(struct ast_channel *chan)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      return ast_monitor_set_state(chan, AST_MONITOR_PAUSED);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/*! \brief Unpause monitoring of channel */</span><br><span style="color: hsl(0, 100%, 40%);">-int AST_OPTIONAL_API_NAME(ast_monitor_unpause)(struct ast_channel *chan)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-    return ast_monitor_set_state(chan, AST_MONITOR_RUNNING);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/*! \brief Wrapper for ast_monitor_pause */</span><br><span style="color: hsl(0, 100%, 40%);">-static int pause_monitor_exec(struct ast_channel *chan, const char *data)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-  return ast_monitor_pause(chan);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/*! \brief Wrapper for ast_monitor_unpause */</span><br><span style="color: hsl(0, 100%, 40%);">-static int unpause_monitor_exec(struct ast_channel *chan, const char *data)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-       return ast_monitor_unpause(chan);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/*!</span><br><span style="color: hsl(0, 100%, 40%);">- * \brief Change monitored filename of channel</span><br><span style="color: hsl(0, 100%, 40%);">- * \param chan</span><br><span style="color: hsl(0, 100%, 40%);">- * \param fname_base new filename</span><br><span style="color: hsl(0, 100%, 40%);">- * \param need_lock</span><br><span style="color: hsl(0, 100%, 40%);">- * \retval 0 on success.</span><br><span style="color: hsl(0, 100%, 40%);">- * \retval -1 on failure.</span><br><span style="color: hsl(0, 100%, 40%);">-*/</span><br><span style="color: hsl(0, 100%, 40%);">-int AST_OPTIONAL_API_NAME(ast_monitor_change_fname)(struct ast_channel *chan, const char *fname_base, int need_lock)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-   if (ast_strlen_zero(fname_base)) {</span><br><span style="color: hsl(0, 100%, 40%);">-              ast_log(LOG_WARNING, "Cannot change monitor filename of channel %s to null\n", ast_channel_name(chan));</span><br><span style="color: hsl(0, 100%, 40%);">-               return -1;</span><br><span style="color: hsl(0, 100%, 40%);">-      }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       LOCK_IF_NEEDED(chan, need_lock);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        if (ast_channel_monitor(chan)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                int directory = strchr(fname_base, '/') ? 1 : 0;</span><br><span style="color: hsl(0, 100%, 40%);">-                const char *absolute = *fname_base == '/' ? "" : ast_config_AST_MONITOR_DIR;</span><br><span style="color: hsl(0, 100%, 40%);">-          const char *absolute_suffix = *fname_base == '/' ? "" : "/";</span><br><span style="color: hsl(0, 100%, 40%);">-                char tmpstring[sizeof(ast_channel_monitor(chan)->filename_base)] = "";</span><br><span style="color: hsl(0, 100%, 40%);">-             int i, fd[2] = { -1, -1 }, doexit = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-          /* before continuing, see if we're trying to rename the file to itself... */</span><br><span style="color: hsl(0, 100%, 40%);">-                snprintf(tmpstring, sizeof(tmpstring), "%s%s%s", absolute, absolute_suffix, fname_base);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-              /* try creating the directory just in case it doesn't exist */</span><br><span style="color: hsl(0, 100%, 40%);">-              if (directory) {</span><br><span style="color: hsl(0, 100%, 40%);">-                        char *name = ast_strdupa(tmpstring);</span><br><span style="color: hsl(0, 100%, 40%);">-                    ast_mkdir(dirname(name), 0777);</span><br><span style="color: hsl(0, 100%, 40%);">-         }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-               /*!</span><br><span style="color: hsl(0, 100%, 40%);">-              * \note We cannot just compare filenames, due to symlinks, relative</span><br><span style="color: hsl(0, 100%, 40%);">-             * paths, and other possible filesystem issues.  We could use</span><br><span style="color: hsl(0, 100%, 40%);">-            * realpath(3), but its use is discouraged.  However, if we try to</span><br><span style="color: hsl(0, 100%, 40%);">-               * create the same file from two different paths, the second will</span><br><span style="color: hsl(0, 100%, 40%);">-                * fail, and so we have our notification that the filenames point to</span><br><span style="color: hsl(0, 100%, 40%);">-             * the same path.</span><br><span style="color: hsl(0, 100%, 40%);">-                *</span><br><span style="color: hsl(0, 100%, 40%);">-               * Remember, also, that we're using the basename of the file (i.e.</span><br><span style="color: hsl(0, 100%, 40%);">-           * the file without the format suffix), so it does not already exist</span><br><span style="color: hsl(0, 100%, 40%);">-             * and we aren't interfering with the recording itself.</span><br><span style="color: hsl(0, 100%, 40%);">-              */</span><br><span style="color: hsl(0, 100%, 40%);">-             ast_debug(2, "comparing tmpstring %s to filename_base %s\n", tmpstring, ast_channel_monitor(chan)->filename_base);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-         if ((fd[0] = open(tmpstring, O_CREAT | O_WRONLY, 0644)) < 0 ||</span><br><span style="color: hsl(0, 100%, 40%);">-                       (fd[1] = open(ast_channel_monitor(chan)->filename_base, O_CREAT | O_EXCL | O_WRONLY, 0644)) < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                        if (fd[0] < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                             ast_log(LOG_ERROR, "Unable to compare filenames: %s\n", strerror(errno));</span><br><span style="color: hsl(0, 100%, 40%);">-                     } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                                ast_debug(2, "No need to rename monitor filename to itself\n");</span><br><span style="color: hsl(0, 100%, 40%);">-                       }</span><br><span style="color: hsl(0, 100%, 40%);">-                       doexit = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-             }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-               /* Cleanup temporary files */</span><br><span style="color: hsl(0, 100%, 40%);">-           for (i = 0; i < 2; i++) {</span><br><span style="color: hsl(0, 100%, 40%);">-                    if (fd[i] >= 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                            while (close(fd[i]) < 0 && errno == EINTR);</span><br><span style="color: hsl(0, 100%, 40%);">-                  }</span><br><span style="color: hsl(0, 100%, 40%);">-               }</span><br><span style="color: hsl(0, 100%, 40%);">-               unlink(tmpstring);</span><br><span style="color: hsl(0, 100%, 40%);">-              /* if previous monitor file existed in a subdirectory, the directory will not be removed */</span><br><span style="color: hsl(0, 100%, 40%);">-             unlink(ast_channel_monitor(chan)->filename_base);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-            if (doexit) {</span><br><span style="color: hsl(0, 100%, 40%);">-                   UNLOCK_IF_NEEDED(chan, need_lock);</span><br><span style="color: hsl(0, 100%, 40%);">-                      return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-               }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-               ast_copy_string(ast_channel_monitor(chan)->filename_base, tmpstring, sizeof(ast_channel_monitor(chan)->filename_base));</span><br><span style="color: hsl(0, 100%, 40%);">-           ast_channel_monitor(chan)->filename_changed = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-     } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                ast_log(LOG_WARNING, "Cannot change monitor filename of channel %s to %s, monitoring not started\n", ast_channel_name(chan), fname_base);</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       UNLOCK_IF_NEEDED(chan, need_lock);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-enum {</span><br><span style="color: hsl(0, 100%, 40%);">-        MON_FLAG_BRIDGED =  (1 << 0),</span><br><span style="color: hsl(0, 100%, 40%);">-     MON_FLAG_MIX =      (1 << 1),</span><br><span style="color: hsl(0, 100%, 40%);">-     MON_FLAG_DROP_IN =  (1 << 2),</span><br><span style="color: hsl(0, 100%, 40%);">-     MON_FLAG_DROP_OUT = (1 << 3),</span><br><span style="color: hsl(0, 100%, 40%);">-     MON_FLAG_BEEP =     (1 << 4),</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-enum {</span><br><span style="color: hsl(0, 100%, 40%);">-     OPT_ARG_BEEP_INTERVAL,</span><br><span style="color: hsl(0, 100%, 40%);">-  OPT_ARG_ARRAY_SIZE,     /* Always last element of the enum */</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-AST_APP_OPTIONS(monitor_opts, {</span><br><span style="color: hsl(0, 100%, 40%);">-  AST_APP_OPTION('b', MON_FLAG_BRIDGED),</span><br><span style="color: hsl(0, 100%, 40%);">-  AST_APP_OPTION('m', MON_FLAG_MIX),</span><br><span style="color: hsl(0, 100%, 40%);">-      AST_APP_OPTION('i', MON_FLAG_DROP_IN),</span><br><span style="color: hsl(0, 100%, 40%);">-  AST_APP_OPTION('o', MON_FLAG_DROP_OUT),</span><br><span style="color: hsl(0, 100%, 40%);">- AST_APP_OPTION_ARG('B', MON_FLAG_BEEP, OPT_ARG_BEEP_INTERVAL),</span><br><span style="color: hsl(0, 100%, 40%);">-});</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/*!</span><br><span style="color: hsl(0, 100%, 40%);">- * \brief Start monitor</span><br><span style="color: hsl(0, 100%, 40%);">- * \param chan</span><br><span style="color: hsl(0, 100%, 40%);">- * \param data arguments passed fname|options</span><br><span style="color: hsl(0, 100%, 40%);">- * \retval 0 on success.</span><br><span style="color: hsl(0, 100%, 40%);">- * \retval -1 on failure.</span><br><span style="color: hsl(0, 100%, 40%);">-*/</span><br><span style="color: hsl(0, 100%, 40%);">-static int start_monitor_exec(struct ast_channel *chan, const char *data)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-     char *arg;</span><br><span style="color: hsl(0, 100%, 40%);">-      char *options;</span><br><span style="color: hsl(0, 100%, 40%);">-  char *delay;</span><br><span style="color: hsl(0, 100%, 40%);">-    char *urlprefix = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">- char tmp[256];</span><br><span style="color: hsl(0, 100%, 40%);">-  int stream_action = X_REC_IN | X_REC_OUT;</span><br><span style="color: hsl(0, 100%, 40%);">-       int joinfiles = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-      int res = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-    char *parse;</span><br><span style="color: hsl(0, 100%, 40%);">-    struct ast_flags flags = { 0 };</span><br><span style="color: hsl(0, 100%, 40%);">- char *opts[OPT_ARG_ARRAY_SIZE] = { NULL, };</span><br><span style="color: hsl(0, 100%, 40%);">-     char beep_id[64] = "";</span><br><span style="color: hsl(0, 100%, 40%);">-        AST_DECLARE_APP_ARGS(args,</span><br><span style="color: hsl(0, 100%, 40%);">-              AST_APP_ARG(format);</span><br><span style="color: hsl(0, 100%, 40%);">-            AST_APP_ARG(fname_base);</span><br><span style="color: hsl(0, 100%, 40%);">-                AST_APP_ARG(options);</span><br><span style="color: hsl(0, 100%, 40%);">-   );</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      /* Parse arguments. */</span><br><span style="color: hsl(0, 100%, 40%);">-  if (ast_strlen_zero(data)) {</span><br><span style="color: hsl(0, 100%, 40%);">-            ast_log(LOG_ERROR, "Monitor requires an argument\n");</span><br><span style="color: hsl(0, 100%, 40%);">-         return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       parse = ast_strdupa(data);</span><br><span style="color: hsl(0, 100%, 40%);">-      AST_STANDARD_APP_ARGS(args, parse);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     if (!ast_strlen_zero(args.options)) {</span><br><span style="color: hsl(0, 100%, 40%);">-           ast_app_parse_options(monitor_opts, &flags, opts, args.options);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-            if (ast_test_flag(&flags, MON_FLAG_MIX)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                  stream_action |= X_JOIN;</span><br><span style="color: hsl(0, 100%, 40%);">-                }</span><br><span style="color: hsl(0, 100%, 40%);">-               if (ast_test_flag(&flags, MON_FLAG_DROP_IN)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                      stream_action &= ~X_REC_IN;</span><br><span style="color: hsl(0, 100%, 40%);">-         }</span><br><span style="color: hsl(0, 100%, 40%);">-               if (ast_test_flag(&flags, MON_FLAG_DROP_OUT)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                     stream_action &= ~X_REC_OUT;</span><br><span style="color: hsl(0, 100%, 40%);">-                }</span><br><span style="color: hsl(0, 100%, 40%);">-               if (ast_test_flag(&flags, MON_FLAG_BEEP)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                 const char *interval_str = S_OR(opts[OPT_ARG_BEEP_INTERVAL], "15");</span><br><span style="color: hsl(0, 100%, 40%);">-                   unsigned int interval = 15;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                     if (sscanf(interval_str, "%30u", &interval) != 1) {</span><br><span style="color: hsl(0, 100%, 40%);">-                               ast_log(LOG_WARNING, "Invalid interval '%s' for periodic beep. Using default of %u\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                                                interval_str, interval);</span><br><span style="color: hsl(0, 100%, 40%);">-                        }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                       if (ast_beep_start(chan, interval, beep_id, sizeof(beep_id))) {</span><br><span style="color: hsl(0, 100%, 40%);">-                         ast_log(LOG_WARNING, "Unable to enable periodic beep, please ensure func_periodic_hook is loaded.\n");</span><br><span style="color: hsl(0, 100%, 40%);">-                                return -1;</span><br><span style="color: hsl(0, 100%, 40%);">-                      }</span><br><span style="color: hsl(0, 100%, 40%);">-               }</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       arg = strchr(args.format, ':');</span><br><span style="color: hsl(0, 100%, 40%);">- if (arg) {</span><br><span style="color: hsl(0, 100%, 40%);">-              *arg++ = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-             urlprefix = arg;</span><br><span style="color: hsl(0, 100%, 40%);">-        }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (!ast_strlen_zero(urlprefix) && !ast_strlen_zero(args.fname_base)) {</span><br><span style="color: hsl(0, 100%, 40%);">-         snprintf(tmp, sizeof(tmp), "%s/%s.%s", urlprefix, args.fname_base,</span><br><span style="color: hsl(0, 100%, 40%);">-                    ((strcmp(args.format, "gsm")) ? "wav" : "gsm"));</span><br><span style="color: hsl(0, 100%, 40%);">-          ast_channel_lock(chan);</span><br><span style="color: hsl(0, 100%, 40%);">-         ast_cdr_setuserfield(ast_channel_name(chan), tmp);</span><br><span style="color: hsl(0, 100%, 40%);">-              ast_channel_unlock(chan);</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-       if (ast_test_flag(&flags, MON_FLAG_BRIDGED)) {</span><br><span style="color: hsl(0, 100%, 40%);">-              /* We must remove the "b" option if listed.  In principle none of</span><br><span style="color: hsl(0, 100%, 40%);">-                the following could give NULL results, but we check just to</span><br><span style="color: hsl(0, 100%, 40%);">-             be pedantic. Reconstructing with checks for 'm' option does not</span><br><span style="color: hsl(0, 100%, 40%);">-                 work if we end up adding more options than 'm' in the future. */</span><br><span style="color: hsl(0, 100%, 40%);">-             delay = ast_strdupa(data);</span><br><span style="color: hsl(0, 100%, 40%);">-              options = strrchr(delay, ',');</span><br><span style="color: hsl(0, 100%, 40%);">-          if (options) {</span><br><span style="color: hsl(0, 100%, 40%);">-                  arg = strchr(options, 'b');</span><br><span style="color: hsl(0, 100%, 40%);">-                     if (arg) {</span><br><span style="color: hsl(0, 100%, 40%);">-                              *arg = 'X';</span><br><span style="color: hsl(0, 100%, 40%);">-                             pbx_builtin_setvar_helper(chan,"AUTO_MONITOR", delay);</span><br><span style="color: hsl(0, 100%, 40%);">-                        }</span><br><span style="color: hsl(0, 100%, 40%);">-               }</span><br><span style="color: hsl(0, 100%, 40%);">-               return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       res = ast_monitor_start(chan, args.format, args.fname_base, 1, stream_action, beep_id);</span><br><span style="color: hsl(0, 100%, 40%);">- if (res < 0)</span><br><span style="color: hsl(0, 100%, 40%);">-         res = ast_monitor_change_fname(chan, args.fname_base, 1);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (stream_action & X_JOIN) {</span><br><span style="color: hsl(0, 100%, 40%);">-               if ((stream_action & X_REC_IN) && (stream_action & X_REC_OUT))</span><br><span style="color: hsl(0, 100%, 40%);">-                  joinfiles = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-          else</span><br><span style="color: hsl(0, 100%, 40%);">-                    ast_log(LOG_WARNING, "Won't mix streams unless both input and output streams are recorded\n");</span><br><span style="color: hsl(0, 100%, 40%);">-    }</span><br><span style="color: hsl(0, 100%, 40%);">-       ast_monitor_setjoinfiles(chan, joinfiles);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      return res;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/*! \brief Wrapper function \see ast_monitor_stop */</span><br><span style="color: hsl(0, 100%, 40%);">-static int stop_monitor_exec(struct ast_channel *chan, const char *data)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-       return ast_monitor_stop(chan, 1);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/*! \brief Wrapper function \see ast_monitor_change_fname */</span><br><span style="color: hsl(0, 100%, 40%);">-static int change_monitor_exec(struct ast_channel *chan, const char *data)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-       return ast_monitor_change_fname(chan, data, 1);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/*! \brief Start monitoring a channel by manager connection */</span><br><span style="color: hsl(0, 100%, 40%);">-static int start_monitor_action(struct mansession *s, const struct message *m)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-   struct ast_channel *c = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-   const char *name = astman_get_header(m, "Channel");</span><br><span style="color: hsl(0, 100%, 40%);">-   const char *fname = astman_get_header(m, "File");</span><br><span style="color: hsl(0, 100%, 40%);">-     const char *format = astman_get_header(m, "Format");</span><br><span style="color: hsl(0, 100%, 40%);">-  const char *mix = astman_get_header(m, "Mix");</span><br><span style="color: hsl(0, 100%, 40%);">-        char *d;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        if (ast_strlen_zero(name)) {</span><br><span style="color: hsl(0, 100%, 40%);">-            astman_send_error(s, m, "No channel specified");</span><br><span style="color: hsl(0, 100%, 40%);">-              return AMI_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (!(c = ast_channel_get_by_name(name))) {</span><br><span style="color: hsl(0, 100%, 40%);">-             astman_send_error(s, m, "No such channel");</span><br><span style="color: hsl(0, 100%, 40%);">-           return AMI_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (ast_strlen_zero(fname)) {</span><br><span style="color: hsl(0, 100%, 40%);">-           /* No filename specified, default to the channel name. */</span><br><span style="color: hsl(0, 100%, 40%);">-               ast_channel_lock(c);</span><br><span style="color: hsl(0, 100%, 40%);">-            fname = ast_strdupa(ast_channel_name(c));</span><br><span style="color: hsl(0, 100%, 40%);">-               ast_channel_unlock(c);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-          /* Replace all '/' chars from the channel name with '-' chars. */</span><br><span style="color: hsl(0, 100%, 40%);">-               for (d = (char *) fname; (d = strchr(d, '/')); ) {</span><br><span style="color: hsl(0, 100%, 40%);">-                      *d = '-';</span><br><span style="color: hsl(0, 100%, 40%);">-               }</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (ast_monitor_start(c, format, fname, 1, X_REC_IN | X_REC_OUT, NULL)) {</span><br><span style="color: hsl(0, 100%, 40%);">-               if (ast_monitor_change_fname(c, fname, 1)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                    astman_send_error(s, m, "Could not start monitoring channel");</span><br><span style="color: hsl(0, 100%, 40%);">-                        c = ast_channel_unref(c);</span><br><span style="color: hsl(0, 100%, 40%);">-                       return AMI_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">-             }</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (ast_true(mix)) {</span><br><span style="color: hsl(0, 100%, 40%);">-            ast_channel_lock(c);</span><br><span style="color: hsl(0, 100%, 40%);">-            ast_monitor_setjoinfiles(c, 1);</span><br><span style="color: hsl(0, 100%, 40%);">-         ast_channel_unlock(c);</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       c = ast_channel_unref(c);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       astman_send_ack(s, m, "Started monitoring channel");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  return AMI_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/*! \brief Stop monitoring a channel by manager connection */</span><br><span style="color: hsl(0, 100%, 40%);">-static int stop_monitor_action(struct mansession *s, const struct message *m)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- struct ast_channel *c = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-   const char *name = astman_get_header(m, "Channel");</span><br><span style="color: hsl(0, 100%, 40%);">-   int res;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        if (ast_strlen_zero(name)) {</span><br><span style="color: hsl(0, 100%, 40%);">-            astman_send_error(s, m, "No channel specified");</span><br><span style="color: hsl(0, 100%, 40%);">-              return AMI_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (!(c = ast_channel_get_by_name(name))) {</span><br><span style="color: hsl(0, 100%, 40%);">-             astman_send_error(s, m, "No such channel");</span><br><span style="color: hsl(0, 100%, 40%);">-           return AMI_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       res = ast_monitor_stop(c, 1);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   c = ast_channel_unref(c);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (res) {</span><br><span style="color: hsl(0, 100%, 40%);">-              astman_send_error(s, m, "Could not stop monitoring channel");</span><br><span style="color: hsl(0, 100%, 40%);">-         return AMI_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       astman_send_ack(s, m, "Stopped monitoring channel");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  return AMI_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/*! \brief Change filename of a monitored channel by manager connection */</span><br><span style="color: hsl(0, 100%, 40%);">-static int change_monitor_action(struct mansession *s, const struct message *m)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-  struct ast_channel *c = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-   const char *name = astman_get_header(m, "Channel");</span><br><span style="color: hsl(0, 100%, 40%);">-   const char *fname = astman_get_header(m, "File");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     if (ast_strlen_zero(name)) {</span><br><span style="color: hsl(0, 100%, 40%);">-            astman_send_error(s, m, "No channel specified");</span><br><span style="color: hsl(0, 100%, 40%);">-              return AMI_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (ast_strlen_zero(fname)) {</span><br><span style="color: hsl(0, 100%, 40%);">-           astman_send_error(s, m, "No filename specified");</span><br><span style="color: hsl(0, 100%, 40%);">-             return AMI_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (!(c = ast_channel_get_by_name(name))) {</span><br><span style="color: hsl(0, 100%, 40%);">-             astman_send_error(s, m, "No such channel");</span><br><span style="color: hsl(0, 100%, 40%);">-           return AMI_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (ast_monitor_change_fname(c, fname, 1)) {</span><br><span style="color: hsl(0, 100%, 40%);">-            c = ast_channel_unref(c);</span><br><span style="color: hsl(0, 100%, 40%);">-               astman_send_error(s, m, "Could not change monitored filename of channel");</span><br><span style="color: hsl(0, 100%, 40%);">-            return AMI_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       c = ast_channel_unref(c);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       astman_send_ack(s, m, "Changed monitor filename");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    return AMI_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-void AST_OPTIONAL_API_NAME(ast_monitor_setjoinfiles)(struct ast_channel *chan, int turnon)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- if (ast_channel_monitor(chan))</span><br><span style="color: hsl(0, 100%, 40%);">-          ast_channel_monitor(chan)->joinfiles = turnon;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-enum MONITOR_PAUSING_ACTION</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-  MONITOR_ACTION_PAUSE,</span><br><span style="color: hsl(0, 100%, 40%);">-   MONITOR_ACTION_UNPAUSE</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int do_pause_or_unpause(struct mansession *s, const struct message *m, int action)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      struct ast_channel *c = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-   const char *name = astman_get_header(m, "Channel");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   if (ast_strlen_zero(name)) {</span><br><span style="color: hsl(0, 100%, 40%);">-            astman_send_error(s, m, "No channel specified");</span><br><span style="color: hsl(0, 100%, 40%);">-              return AMI_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (!(c = ast_channel_get_by_name(name))) {</span><br><span style="color: hsl(0, 100%, 40%);">-             astman_send_error(s, m, "No such channel");</span><br><span style="color: hsl(0, 100%, 40%);">-           return AMI_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (action == MONITOR_ACTION_PAUSE) {</span><br><span style="color: hsl(0, 100%, 40%);">-           ast_monitor_pause(c);</span><br><span style="color: hsl(0, 100%, 40%);">-   } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                ast_monitor_unpause(c);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       c = ast_channel_unref(c);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       astman_send_ack(s, m, (action == MONITOR_ACTION_PAUSE ? "Paused monitoring of the channel" : "Unpaused monitoring of the channel"));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        return AMI_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int pause_monitor_action(struct mansession *s, const struct message *m)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-     return do_pause_or_unpause(s, m, MONITOR_ACTION_PAUSE);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int unpause_monitor_action(struct mansession *s, const struct message *m)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-       return do_pause_or_unpause(s, m, MONITOR_ACTION_UNPAUSE);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int load_module(void)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- ast_register_application_xml("Monitor", start_monitor_exec);</span><br><span style="color: hsl(0, 100%, 40%);">-  ast_register_application_xml("StopMonitor", stop_monitor_exec);</span><br><span style="color: hsl(0, 100%, 40%);">-       ast_register_application_xml("ChangeMonitor", change_monitor_exec);</span><br><span style="color: hsl(0, 100%, 40%);">-   ast_register_application_xml("PauseMonitor", pause_monitor_exec);</span><br><span style="color: hsl(0, 100%, 40%);">-     ast_register_application_xml("UnpauseMonitor", unpause_monitor_exec);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_manager_register_xml("Monitor", EVENT_FLAG_CALL, start_monitor_action);</span><br><span style="color: hsl(0, 100%, 40%);">-   ast_manager_register_xml("StopMonitor", EVENT_FLAG_CALL, stop_monitor_action);</span><br><span style="color: hsl(0, 100%, 40%);">-        ast_manager_register_xml("ChangeMonitor", EVENT_FLAG_CALL, change_monitor_action);</span><br><span style="color: hsl(0, 100%, 40%);">-    ast_manager_register_xml("PauseMonitor", EVENT_FLAG_CALL, pause_monitor_action);</span><br><span style="color: hsl(0, 100%, 40%);">-      ast_manager_register_xml("UnpauseMonitor", EVENT_FLAG_CALL, unpause_monitor_action);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  return AST_MODULE_LOAD_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int unload_module(void)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- ast_unregister_application("Monitor");</span><br><span style="color: hsl(0, 100%, 40%);">-        ast_unregister_application("StopMonitor");</span><br><span style="color: hsl(0, 100%, 40%);">-    ast_unregister_application("ChangeMonitor");</span><br><span style="color: hsl(0, 100%, 40%);">-  ast_unregister_application("PauseMonitor");</span><br><span style="color: hsl(0, 100%, 40%);">-   ast_unregister_application("UnpauseMonitor");</span><br><span style="color: hsl(0, 100%, 40%);">- ast_manager_unregister("Monitor");</span><br><span style="color: hsl(0, 100%, 40%);">-    ast_manager_unregister("StopMonitor");</span><br><span style="color: hsl(0, 100%, 40%);">-        ast_manager_unregister("ChangeMonitor");</span><br><span style="color: hsl(0, 100%, 40%);">-      ast_manager_unregister("PauseMonitor");</span><br><span style="color: hsl(0, 100%, 40%);">-       ast_manager_unregister("UnpauseMonitor");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* usecount semantics need to be defined */</span><br><span style="color: hsl(0, 100%, 40%);">-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER, "Call Monitoring Resource",</span><br><span style="color: hsl(0, 100%, 40%);">-       .support_level = AST_MODULE_SUPPORT_DEPRECATED,</span><br><span style="color: hsl(0, 100%, 40%);">- .load = load_module,</span><br><span style="color: hsl(0, 100%, 40%);">-    .unload = unload_module,</span><br><span style="color: hsl(0, 100%, 40%);">-        .load_pri = AST_MODPRI_CHANNEL_DEPEND,</span><br><span style="color: hsl(0, 100%, 40%);">-  .optional_modules = "func_periodic_hook",</span><br><span style="color: hsl(0, 100%, 40%);">-);</span><br><span>diff --git a/res/res_monitor.exports.in b/res/res_monitor.exports.in</span><br><span>deleted file mode 100644</span><br><span>index 4a40724..0000000</span><br><span>--- a/res/res_monitor.exports.in</span><br><span>+++ /dev/null</span><br><span>@@ -1,11 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- global:</span><br><span style="color: hsl(0, 100%, 40%);">-         LINKER_SYMBOL_PREFIX*ast_monitor_change_fname;</span><br><span style="color: hsl(0, 100%, 40%);">-          LINKER_SYMBOL_PREFIX*ast_monitor_pause;</span><br><span style="color: hsl(0, 100%, 40%);">-         LINKER_SYMBOL_PREFIX*ast_monitor_setjoinfiles;</span><br><span style="color: hsl(0, 100%, 40%);">-          LINKER_SYMBOL_PREFIX*ast_monitor_start;</span><br><span style="color: hsl(0, 100%, 40%);">-         LINKER_SYMBOL_PREFIX*ast_monitor_stop;</span><br><span style="color: hsl(0, 100%, 40%);">-          LINKER_SYMBOL_PREFIX*ast_monitor_unpause;</span><br><span style="color: hsl(0, 100%, 40%);">-       local:</span><br><span style="color: hsl(0, 100%, 40%);">-          *;</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/19605">change 19605</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/+/19605"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I0462caefb4f9544e2e2baa23c498858310b52d50 </div>
<div style="display:none"> Gerrit-Change-Number: 19605 </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>