res_monitor: Remove deprecated module. master
authorMike Bradeen <mbradeen@sangoma.com>
Sat, 19 Nov 2022 01:24:38 +0000 (18:24 -0700)
committerGeorge Joseph <gjoseph@digium.com>
Fri, 13 Jan 2023 14:32:33 +0000 (08:32 -0600)
ASTERISK-30303

Change-Id: I0462caefb4f9544e2e2baa23c498858310b52d50

36 files changed:
README-SERIOUSLY.bestpractices.md
apps/Makefile
apps/app_meetme.c
apps/app_mixmonitor.c
apps/app_queue.c
bridges/bridge_builtin_features.c
channels/Makefile
configs/samples/features.conf.sample
configs/samples/queues.conf.sample
configs/samples/stasis.conf.sample
doc/UPGRADE-staging/res_monitor_removal.txt [new file with mode: 0644]
include/asterisk/bridge_features.h
include/asterisk/channel.h
include/asterisk/doxygen/architecture.h
include/asterisk/features_config.h
include/asterisk/monitor.h [deleted file]
include/asterisk/stasis_channels.h
main/asterisk.dynamics
main/bridge_basic.c
main/bridge_channel.c
main/channel.c
main/channel_internal_api.c
main/features.c
main/features_config.c
main/manager_channels.c
main/stasis.c
main/stasis_channels.c
menuselect/example_menuselect-tree
menuselect/test/menuselect-tree
pbx/Makefile
pbx/ael/ael-test/ael-test2/apptest.ael2
pbx/ael/ael-test/ael-test4/apptest.ael2
pbx/ael/ael-test/ael-test5/extensions.ael
pbx/ael/ael-test/ael-test6/extensions.ael
res/res_monitor.c [deleted file]
res/res_monitor.exports.in [deleted file]

index f021f9d..fa4b0a6 100644 (file)
@@ -83,10 +83,10 @@ the FILTER() dialplan function.
 
 The CALLERID(num) and CALLERID(name) values are other commonly used values that
 are sources of data potentially supplied by outside sources.  If you use these
-values as parameters to the System(), MixMonitor(), or Monitor() applications
-or the SHELL() dialplan function, you can allow injection of arbitrary operating
-system command execution.  The FILTER() dialplan function is available to remove
-dangerous characters from untrusted strings to block the command injection.
+values as parameters to the System() or MixMonitor() applications or the SHELL()
+dialplan function, you can allow injection of arbitrary operating system command
+execution.  The FILTER() dialplan function is available to remove dangerous
+characters from untrusted strings to block the command injection.
 
 
 ### Strict Pattern Matching
index 02b705d..50b3fcc 100644 (file)
@@ -58,6 +58,6 @@ app_voicemail_imap.o: _ASTCFLAGS+=$(AST_NO_FORMAT_TRUNCATION) -DIMAP_STORAGE
 app_while.o: _ASTCFLAGS+=$(AST_NO_FORMAT_TRUNCATION)
 
 ifneq ($(findstring $(OSARCH), mingw32 cygwin ),)
-  LIBS+= -lres_ael_share.so -lres_monitor.so -lres_speech.so
+  LIBS+= -lres_ael_share.so -lres_speech.so
   LIBS+= -lres_smdi.so
 endif
index 812b817..0d5bdc2 100644 (file)
@@ -3678,7 +3678,7 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, struc
                ast_func_write(chan, "DENOISE(rx)", "on");
        }
 
-       retrydahdi = (strcasecmp(ast_channel_tech(chan)->type, "DAHDI") || (ast_channel_audiohooks(chan) || ast_channel_monitor(chan)) ? 1 : 0);
+       retrydahdi = (strcasecmp(ast_channel_tech(chan)->type, "DAHDI") || (ast_channel_audiohooks(chan)) ? 1 : 0);
        user->dahdichannel = !retrydahdi;
 
  dahdiretry:
@@ -4196,14 +4196,14 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, struc
                        if (c) {
                                char dtmfstr[2] = "";
 
-                               if (ast_channel_fd(c, 0) != origfd || (user->dahdichannel && (ast_channel_audiohooks(c) || ast_channel_monitor(c)))) {
+                               if (ast_channel_fd(c, 0) != origfd || (user->dahdichannel && ast_channel_audiohooks(c))) {
                                        if (using_pseudo) {
                                                /* Kill old pseudo */
                                                close(fd);
                                                using_pseudo = 0;
                                        }
                                        ast_debug(1, "Ooh, something swapped out under us, starting over\n");
-                                       retrydahdi = (strcasecmp(ast_channel_tech(c)->type, "DAHDI") || (ast_channel_audiohooks(c) || ast_channel_monitor(c)) ? 1 : 0);
+                                       retrydahdi = (strcasecmp(ast_channel_tech(c)->type, "DAHDI") || ast_channel_audiohooks(c) ? 1 : 0);
                                        user->dahdichannel = !retrydahdi;
                                        goto dahdiretry;
                                }
index 3ce1a76..332e9b8 100644 (file)
                        function <variable>FILTER()</variable>.</para></warning>
                </description>
                <see-also>
-                       <ref type="application">Monitor</ref>
                        <ref type="application">StopMixMonitor</ref>
-                       <ref type="application">PauseMonitor</ref>
-                       <ref type="application">UnpauseMonitor</ref>
                        <ref type="function">AUDIOHOOK_INHERIT</ref>
                </see-also>
        </application>
index 4b6b72b..c5b7d10 100644 (file)
@@ -41,7 +41,6 @@
  *    - Position announcement
  *    - Abandoned/completed call counters
  *    - Failout timer passed as optional app parameter
- *    - Optional monitoring of calls, started when call is answered
  *
  * Patch Version 1.07 2003-12-24 01
  *
@@ -63,7 +62,6 @@
  */
 
 /*** MODULEINFO
-       <use type="module">res_monitor</use>
        <support_level>core</support_level>
  ***/
 
@@ -88,7 +86,6 @@
 #include "asterisk/cli.h"
 #include "asterisk/manager.h"
 #include "asterisk/config.h"
-#include "asterisk/monitor.h"
 #include "asterisk/utils.h"
 #include "asterisk/causes.h"
 #include "asterisk/astdb.h"
                                        <option name="T">
                                                <para>Allow the <emphasis>calling</emphasis> user to transfer the call.</para>
                                        </option>
-                                       <option name="w">
-                                               <para>Allow the <emphasis>called</emphasis> user to write the conversation to
-                                               disk via Monitor.</para>
-                                       </option>
-                                       <option name="W">
-                                               <para>Allow the <emphasis>calling</emphasis> user to write the conversation to
-                                               disk via Monitor.</para>
-                                       </option>
                                        <option name="x">
                                                <para>Allow the <emphasis>called</emphasis> user to write the conversation
                                                to disk via MixMonitor.</para>
@@ -1862,7 +1851,6 @@ struct call_queue {
        int servicelevel;                   /*!< seconds setting for servicelevel*/
        int callscompletedinsl;             /*!< Number of calls answered with servicelevel*/
        char monfmt[8];                     /*!< Format to use when recording calls */
-       int montype;                        /*!< Monitor type  Monitor vs. MixMonitor */
        int count;                          /*!< How many entries */
        int maxlen;                         /*!< Max number of entries */
        int wrapuptime;                     /*!< Wrapup Time */
@@ -2966,7 +2954,6 @@ static void init_queue(struct call_queue *q)
        q->setqueuevar = 0;
        q->setqueueentryvar = 0;
        q->autofill = autofill_default;
-       q->montype = montype_default;
        q->monfmt[0] = '\0';
        q->reportholdtime = 0;
        q->wrapuptime = 0;
@@ -3448,10 +3435,6 @@ static void queue_set_param(struct call_queue *q, const char *param, const char
                }
        } else if (!strcasecmp(param, "autofill")) {
                q->autofill = ast_true(val);
-       } else if (!strcasecmp(param, "monitor-type")) {
-               if (!strcasecmp(val, "mixmonitor")) {
-                       q->montype = 1;
-               }
        } else if (!strcasecmp(param, "autopause")) {
                q->autopause = autopause2int(val);
        } else if (!strcasecmp(param, "autopausedelay")) {
@@ -6907,7 +6890,6 @@ static int try_calling(struct queue_ent *qe, struct ast_flags opts, char **opt_a
        char oldcontext[AST_MAX_CONTEXT]="";
        char queuename[256]="";
        struct ast_channel *peer;
-       struct ast_channel *which;
        struct callattempt *lpeer;
        struct member *member;
        struct ast_app *application;
@@ -6922,7 +6904,6 @@ static int try_calling(struct queue_ent *qe, struct ast_flags opts, char **opt_a
        char *agiexec = NULL;
        char *gosubexec = NULL;
        const char *monitorfilename;
-       char tmpid[256];
        int forwardsallowed = 1;
        int block_connected_line = 0;
        struct ao2_iterator memi;
@@ -6931,7 +6912,6 @@ static int try_calling(struct queue_ent *qe, struct ast_flags opts, char **opt_a
        time_t starttime;
 
        memset(&bridge_config, 0, sizeof(bridge_config));
-       tmpid[0] = 0;
        time(&now);
 
        /* If we've already exceeded our timeout, then just stop
@@ -7252,32 +7232,7 @@ static int try_calling(struct queue_ent *qe, struct ast_flags opts, char **opt_a
 
                /* Begin Monitoring */
                if (*qe->parent->monfmt) {
-                       if (!qe->parent->montype) {
-                               const char *monexec;
-                               ast_debug(1, "Starting Monitor as requested.\n");
-                               ast_channel_lock(qe->chan);
-                               if ((monexec = pbx_builtin_getvar_helper(qe->chan, "MONITOR_EXEC")) || pbx_builtin_getvar_helper(qe->chan, "MONITOR_EXEC_ARGS")) {
-                                       which = qe->chan;
-                                       monexec = monexec ? ast_strdupa(monexec) : NULL;
-                               } else {
-                                       which = peer;
-                               }
-                               ast_channel_unlock(qe->chan);
-                               if (monitorfilename) {
-                                       ast_monitor_start(which, qe->parent->monfmt, monitorfilename, 1, X_REC_IN | X_REC_OUT, NULL);
-                               } else if (qe->chan) {
-                                       ast_monitor_start(which, qe->parent->monfmt, ast_channel_uniqueid(qe->chan), 1, X_REC_IN | X_REC_OUT, NULL);
-                               } else {
-                                       /* Last ditch effort -- no channel, make up something */
-                                       snprintf(tmpid, sizeof(tmpid), "chan-%lx", (unsigned long)ast_random());
-                                       ast_monitor_start(which, qe->parent->monfmt, tmpid, 1, X_REC_IN | X_REC_OUT, NULL);
-                               }
-                               if (!ast_strlen_zero(monexec)) {
-                                       ast_monitor_setjoinfiles(which, 1);
-                               }
-                       } else {
-                               setup_mixmonitor(qe, monitorfilename);
-                       }
+                       setup_mixmonitor(qe, monitorfilename);
                }
                /* Drop out of the queue at this point, to prepare for next caller */
                leave_queue(qe);
@@ -11802,5 +11757,4 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "True Call Queueing",
        .unload = unload_module,
        .reload = reload,
        .load_pri = AST_MODPRI_DEVSTATE_CONSUMER,
-       .optional_modules = "res_monitor",
 );
index 671cfb9..2aaa2e8 100644 (file)
@@ -26,7 +26,6 @@
  */
 
 /*** MODULEINFO
-       <use type="module">res_monitor</use>
        <support_level>core</support_level>
  ***/
 
@@ -49,7 +48,6 @@
 #include "asterisk/pbx.h"
 #include "asterisk/parking.h"
 #include "asterisk/features_config.h"
-#include "asterisk/monitor.h"
 #include "asterisk/mixmonitor.h"
 #include "asterisk/audiohook.h"
 #include "asterisk/causes.h"
@@ -78,7 +76,7 @@ static void set_touch_variable(enum set_touch_variables_res *res, struct ast_cha
        }
 }
 
-static enum set_touch_variables_res set_touch_variables(struct ast_channel *chan, int is_mixmonitor, char **touch_format, char **touch_monitor, char **touch_monitor_prefix)
+static enum set_touch_variables_res set_touch_variables(struct ast_channel *chan, char **touch_format, char **touch_monitor, char **touch_monitor_prefix)
 {
        enum set_touch_variables_res res = SET_TOUCH_UNSET;
        const char *var_format;
@@ -87,15 +85,10 @@ static enum set_touch_variables_res set_touch_variables(struct ast_channel *chan
 
        SCOPED_CHANNELLOCK(lock, chan);
 
-       if (is_mixmonitor) {
-               var_format = "TOUCH_MIXMONITOR_FORMAT";
-               var_monitor = "TOUCH_MIXMONITOR";
-               var_prefix = "TOUCH_MIXMONITOR_PREFIX";
-       } else {
-               var_format = "TOUCH_MONITOR_FORMAT";
-               var_monitor = "TOUCH_MONITOR";
-               var_prefix = "TOUCH_MONITOR_PREFIX";
-       }
+       var_format = "TOUCH_MIXMONITOR_FORMAT";
+       var_monitor = "TOUCH_MIXMONITOR";
+       var_prefix = "TOUCH_MIXMONITOR_PREFIX";
+
        set_touch_variable(&res, chan, var_format, touch_format);
        set_touch_variable(&res, chan, var_monitor, touch_monitor);
        set_touch_variable(&res, chan, var_prefix, touch_monitor_prefix);
@@ -103,199 +96,6 @@ static enum set_touch_variables_res set_touch_variables(struct ast_channel *chan
        return res;
 }
 
-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)
-{
-       ast_verb(4, "AutoMonitor used to stop recording call.\n");
-
-       ast_channel_lock(peer_chan);
-       if (ast_channel_monitor(peer_chan)) {
-               if (ast_channel_monitor(peer_chan)->stop(peer_chan, 1)) {
-                       ast_verb(4, "Cannot stop AutoMonitor for %s\n", ast_channel_name(bridge_channel->chan));
-                       if (features_cfg && !(ast_strlen_zero(features_cfg->recordingfailsound))) {
-                               ast_bridge_channel_queue_playfile(bridge_channel, NULL, features_cfg->recordingfailsound, NULL);
-                       }
-                       ast_channel_unlock(peer_chan);
-                       return;
-               }
-       } else {
-               /* Something else removed the Monitor before we got to it. */
-               ast_channel_unlock(peer_chan);
-               return;
-       }
-
-       ast_channel_unlock(peer_chan);
-
-       if (features_cfg && !(ast_strlen_zero(features_cfg->courtesytone))) {
-               ast_bridge_channel_queue_playfile(bridge_channel, NULL, features_cfg->courtesytone, NULL);
-               ast_bridge_channel_write_playfile(bridge_channel, NULL, features_cfg->courtesytone, NULL);
-       }
-
-       if (!ast_strlen_zero(stop_message)) {
-               ast_bridge_channel_queue_playfile(bridge_channel, NULL, stop_message, NULL);
-               ast_bridge_channel_write_playfile(bridge_channel, NULL, stop_message, NULL);
-       }
-}
-
-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)
-{
-       char *touch_filename;
-       size_t len;
-       int x;
-       enum set_touch_variables_res set_touch_res;
-
-       RAII_VAR(char *, touch_format, NULL, ast_free);
-       RAII_VAR(char *, touch_monitor, NULL, ast_free);
-       RAII_VAR(char *, touch_monitor_prefix, NULL, ast_free);
-
-       set_touch_res = set_touch_variables(bridge_channel->chan, 0, &touch_format,
-               &touch_monitor, &touch_monitor_prefix);
-       switch (set_touch_res) {
-       case SET_TOUCH_SUCCESS:
-               break;
-       case SET_TOUCH_UNSET:
-               set_touch_res = set_touch_variables(peer_chan, 0, &touch_format, &touch_monitor,
-                       &touch_monitor_prefix);
-               if (set_touch_res == SET_TOUCH_ALLOC_FAILURE) {
-                       return;
-               }
-               break;
-       case SET_TOUCH_ALLOC_FAILURE:
-               return;
-       }
-
-       if (!ast_strlen_zero(touch_monitor)) {
-               len = strlen(touch_monitor) + 50;
-               touch_filename = ast_alloca(len);
-               snprintf(touch_filename, len, "%s-%ld-%s",
-                       S_OR(touch_monitor_prefix, "auto"),
-                       (long) time(NULL),
-                       touch_monitor);
-       } else {
-               char *caller_chan_id;
-               char *peer_chan_id;
-
-               caller_chan_id = ast_strdupa(S_COR(ast_channel_caller(bridge_channel->chan)->id.number.valid,
-                       ast_channel_caller(bridge_channel->chan)->id.number.str, ast_channel_name(bridge_channel->chan)));
-               peer_chan_id = ast_strdupa(S_COR(ast_channel_caller(peer_chan)->id.number.valid,
-                       ast_channel_caller(peer_chan)->id.number.str, ast_channel_name(peer_chan)));
-               len = strlen(caller_chan_id) + strlen(peer_chan_id) + 50;
-               touch_filename = ast_alloca(len);
-               snprintf(touch_filename, len, "%s-%ld-%s-%s",
-                       S_OR(touch_monitor_prefix, "auto"),
-                       (long) time(NULL),
-                       caller_chan_id,
-                       peer_chan_id);
-       }
-
-       for (x = 0; x < strlen(touch_filename); x++) {
-               if (touch_filename[x] == '/') {
-                       touch_filename[x] = '-';
-               }
-       }
-
-       ast_verb(4, "AutoMonitor used to record call. Filename: %s\n", touch_filename);
-
-       if (ast_monitor_start(peer_chan, touch_format, touch_filename, 1, X_REC_IN | X_REC_OUT, NULL)) {
-               ast_verb(4, "AutoMonitor feature was tried by '%s' but monitor failed to start.\n",
-                       ast_channel_name(bridge_channel->chan));
-               return;
-       }
-
-       ast_monitor_setjoinfiles(peer_chan, 1);
-
-       if (features_cfg && !ast_strlen_zero(features_cfg->courtesytone)) {
-               ast_bridge_channel_queue_playfile(bridge_channel, NULL, features_cfg->courtesytone, NULL);
-               ast_bridge_channel_write_playfile(bridge_channel, NULL, features_cfg->courtesytone, NULL);
-       }
-
-       if (!ast_strlen_zero(start_message)) {
-               ast_bridge_channel_queue_playfile(bridge_channel, NULL, start_message, NULL);
-               ast_bridge_channel_write_playfile(bridge_channel, NULL, start_message, NULL);
-       }
-
-       pbx_builtin_setvar_helper(bridge_channel->chan, "TOUCH_MONITOR_OUTPUT", touch_filename);
-       pbx_builtin_setvar_helper(peer_chan, "TOUCH_MONITOR_OUTPUT", touch_filename);
-}
-
-static int feature_automonitor(struct ast_bridge_channel *bridge_channel, void *hook_pvt)
-{
-       const char *start_message;
-       const char *stop_message;
-       struct ast_bridge_features_automonitor *options = hook_pvt;
-       enum ast_bridge_features_monitor start_stop = options ? options->start_stop : AUTO_MONITOR_TOGGLE;
-       int is_monitoring;
-
-       RAII_VAR(struct ast_channel *, peer_chan, NULL, ast_channel_cleanup);
-       RAII_VAR(struct ast_features_general_config *, features_cfg, NULL, ao2_cleanup);
-
-       ast_channel_lock(bridge_channel->chan);
-       features_cfg = ast_get_chan_features_general_config(bridge_channel->chan);
-       ast_channel_unlock(bridge_channel->chan);
-       ast_bridge_channel_lock_bridge(bridge_channel);
-       peer_chan = ast_bridge_peer_nolock(bridge_channel->bridge, bridge_channel->chan);
-       ast_bridge_unlock(bridge_channel->bridge);
-
-       if (!peer_chan) {
-               ast_verb(4, "Cannot start AutoMonitor for %s - can not determine peer in bridge.\n",
-                       ast_channel_name(bridge_channel->chan));
-               if (features_cfg && !ast_strlen_zero(features_cfg->recordingfailsound)) {
-                       ast_bridge_channel_queue_playfile(bridge_channel, NULL, features_cfg->recordingfailsound, NULL);
-               }
-               return 0;
-       }
-
-       ast_channel_lock(bridge_channel->chan);
-       start_message = pbx_builtin_getvar_helper(bridge_channel->chan,
-               "TOUCH_MONITOR_MESSAGE_START");
-       start_message = ast_strdupa(S_OR(start_message, ""));
-       stop_message = pbx_builtin_getvar_helper(bridge_channel->chan,
-               "TOUCH_MONITOR_MESSAGE_STOP");
-       stop_message = ast_strdupa(S_OR(stop_message, ""));
-       ast_channel_unlock(bridge_channel->chan);
-
-       is_monitoring = ast_channel_monitor(peer_chan) != NULL;
-       switch (start_stop) {
-       case AUTO_MONITOR_TOGGLE:
-               if (is_monitoring) {
-                       stop_automonitor(bridge_channel, peer_chan, features_cfg, stop_message);
-               } else {
-                       start_automonitor(bridge_channel, peer_chan, features_cfg, start_message);
-               }
-               return 0;
-       case AUTO_MONITOR_START:
-               if (!is_monitoring) {
-                       start_automonitor(bridge_channel, peer_chan, features_cfg, start_message);
-                       return 0;
-               }
-               ast_verb(4, "AutoMonitor already recording call.\n");
-               break;
-       case AUTO_MONITOR_STOP:
-               if (is_monitoring) {
-                       stop_automonitor(bridge_channel, peer_chan, features_cfg, stop_message);
-                       return 0;
-               }
-               ast_verb(4, "AutoMonitor already stopped on call.\n");
-               break;
-       }
-
-       /*
-        * Fake start/stop to invoker so will think it did something but
-        * was already in that mode.
-        */
-       if (features_cfg && !ast_strlen_zero(features_cfg->courtesytone)) {
-               ast_bridge_channel_queue_playfile(bridge_channel, NULL, features_cfg->courtesytone, NULL);
-       }
-       if (is_monitoring) {
-               if (!ast_strlen_zero(start_message)) {
-                       ast_bridge_channel_queue_playfile(bridge_channel, NULL, start_message, NULL);
-               }
-       } else {
-               if (!ast_strlen_zero(stop_message)) {
-                       ast_bridge_channel_queue_playfile(bridge_channel, NULL, stop_message, NULL);
-               }
-       }
-       return 0;
-}
 
 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)
 {
@@ -331,13 +131,13 @@ static void start_automixmonitor(struct ast_bridge_channel *bridge_channel, stru
        RAII_VAR(char *, touch_monitor, NULL, ast_free);
        RAII_VAR(char *, touch_monitor_prefix, NULL, ast_free);
 
-       set_touch_res = set_touch_variables(bridge_channel->chan, 1, &touch_format,
+       set_touch_res = set_touch_variables(bridge_channel->chan, &touch_format,
                &touch_monitor, &touch_monitor_prefix);
        switch (set_touch_res) {
        case SET_TOUCH_SUCCESS:
                break;
        case SET_TOUCH_UNSET:
-               set_touch_res = set_touch_variables(peer_chan, 1, &touch_format, &touch_monitor,
+               set_touch_res = set_touch_variables(peer_chan, &touch_format, &touch_monitor,
                        &touch_monitor_prefix);
                if (set_touch_res == SET_TOUCH_ALLOC_FAILURE) {
                        return;
@@ -503,7 +303,6 @@ static int feature_hangup(struct ast_bridge_channel *bridge_channel, void *hook_
 static int unload_module(void)
 {
        ast_bridge_features_unregister(AST_BRIDGE_BUILTIN_HANGUP);
-       ast_bridge_features_unregister(AST_BRIDGE_BUILTIN_AUTOMON);
        ast_bridge_features_unregister(AST_BRIDGE_BUILTIN_AUTOMIXMON);
 
        return 0;
@@ -512,7 +311,6 @@ static int unload_module(void)
 static int load_module(void)
 {
        ast_bridge_features_register(AST_BRIDGE_BUILTIN_HANGUP, feature_hangup, NULL);
-       ast_bridge_features_register(AST_BRIDGE_BUILTIN_AUTOMON, feature_automonitor, NULL);
        ast_bridge_features_register(AST_BRIDGE_BUILTIN_AUTOMIXMON, feature_automixmonitor, NULL);
 
        /* This module cannot be unloaded until shutdown */
@@ -525,5 +323,4 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Built in bridging featur
        .support_level = AST_MODULE_SUPPORT_CORE,
        .load = load_module,
        .unload = unload_module,
-       .optional_modules = "res_monitor",
 );
index 2d243d2..0f8d132 100644 (file)
@@ -19,10 +19,6 @@ all: _all
 
 include $(ASTTOPDIR)/Makefile.moddir_rules
 
-ifneq ($(findstring $(OSARCH), mingw32 cygwin ),)
-  LIBS+= -lres_monitor.so
-endif
-
 $(call MOD_ADD_C,chan_iax2,$(wildcard iax2/*.c))
 iax2/parser.o: _ASTCFLAGS+=$(call get_menuselect_cflags,MALLOC_DEBUG)
 
index 3284326..ba2f481 100644 (file)
@@ -1,5 +1,5 @@
 ;
-; Sample Call Features (transfer, monitor/mixmonitor, etc) configuration
+; Sample Call Features (transfer, mixmonitor, etc) configuration
 ;
 
 ; Note: From Asterisk 12 - All parking lot configuration is now done in res_parking.conf
@@ -18,7 +18,7 @@
 ;pickupfailsound = beeperr      ; to indicate that the pickup failed (default: no sound)
 ;featuredigittimeout = 1000     ; Max time (ms) between digits for
                                 ; feature activation  (default is 1000 ms)
-;recordingfailsound = beeperr   ; indicates that a one-touch monitor or one-touch mixmonitor feature failed
+;recordingfailsound = beeperr   ; indicates that a one-touch mixmonitor feature failed
                                 ; to be applied to the call. (default: no sound)
 ;atxfernoanswertimeout = 15     ; Timeout for answer on attended transfer default is 15 seconds.
 ;atxferdropcall = no            ; If someone does an attended transfer, then hangs up before the transfer
@@ -45,7 +45,6 @@
 [featuremap]
 ;blindxfer => #1                ; Blind transfer  (default is #) -- Make sure to set the T and/or t option in the Dial() or Queue() app call!
 ;disconnect => *0               ; Disconnect  (default is *) -- Make sure to set the H and/or h option in the Dial() or Queue() app call!
-;automon => *1                  ; One Touch Record a.k.a. Touch Monitor -- Make sure to set the W and/or w option in the Dial() or Queue() app call!
 ;atxfer => *2                   ; Attended transfer  -- Make sure to set the T and/or t option in the Dial() or Queue()  app call!
 ;parkcall => #72                ; Park call (one step parking)  -- Make sure to set the K and/or k option in the Dial() app call!
 ;automixmon => *3               ; One Touch Record a.k.a. Touch MixMonitor -- Make sure to set the X and/or x option in the Dial() or Queue() app call!
 ; Set arbitrary channel variables, based upon CALLERID number (Note that the application
 ; argument contains commas)
 ;retrieveinfo => #8,peer,Set(ARRAY(CDR(mark),CDR(name))=${ODBC_FOO(${CALLERID(num)})})
-;
-;pauseMonitor   => #1,self/callee,Pausemonitor     ;Allow the callee to pause monitoring
-;                                                  ;on their channel
-;unpauseMonitor => #3,self/callee,UnPauseMonitor   ;Allow the callee to unpause monitoring
-;                                                  ;on their channel
 
 ; Dynamic Feature Groups:
 ;   Dynamic feature groups are groupings of features defined in [applicationmap]
 ; example:
 ; [myGroupName]         ; defines the group named myGroupName
 ; testfeature => #9     ; associates testfeature with the group and the keycode '#9'.
-; pauseMonitor =>       ; associates pauseMonitor with the group and uses the keycode specified
+; retrieveinfo =>       ; associates retrieveinfo with the group and uses the keycode specified
 ;                       ; in the [applicationmap].
index ab13084..3b2c18b 100644 (file)
@@ -28,16 +28,9 @@ persistentmembers = yes
 ;autofill = no
 ;
 ; Monitor Type
-;    By setting monitor-type = MixMonitor, when specifying monitor-format
-;    to enable recording of queue member conversations, app_queue will
-;    now use the new MixMonitor application instead of Monitor so
-;    the concept of "joining/mixing" the in/out files now goes away
-;    when this is enabled. You can set the default type for all queues
-;    here, and then also change monitor-type for individual queues within
-;    queue by using the same configuration parameter within a queue
-;    configuration block. If you do not specify or comment out this option,
-;    it will default to the old 'Monitor' behavior to keep backward
-;    compatibility.
+;    monitor-type = MixMonitor is the only currently supported option.
+;    As MixMonitor mixes the audio by default, "joining/mixing" the in/out
+;    files is not necissary.
 ;
 monitor-type = MixMonitor
 ;
@@ -370,7 +363,7 @@ monitor-type = MixMonitor
 ; The announcements will be played in the order in which they are defined. After
 ; playing the last announcement, the announcements begin again from the beginning.
 ;
-; Calls may be recorded using Asterisk's monitor/MixMonitor resource
+; Calls may be recorded using Asterisk's MixMonitor resource.
 ; This can be enabled from within the Queue application, starting recording
 ; when the call is actually picked up; thus, only successful calls are
 ; recorded, and you are not recording while people are listening to MOH.
@@ -387,13 +380,9 @@ monitor-type = MixMonitor
 ; monitor-format = gsm|wav|wav49
 ;
 ; Monitor Type
-;    By setting monitor-type = MixMonitor, when specifying monitor-format
-;    to enable recording of queue member conversations, app_queue will
-;    now use the new MixMonitor application instead of Monitor so
-;    the concept of "joining/mixing" the in/out files now goes away
-;    when this is enabled. If you do not specify or comment out this option,
-;    it will default to the old 'Monitor' behavior to keep backward
-;    compatibility.
+;    monitor-type = MixMonitor is the only currently supported option.
+;    As MixMonitor mixes the audio by default, "joining/mixing" the in/out
+;    files is not necissary.
 ;
 ; monitor-type = MixMonitor
 ;
@@ -408,21 +397,15 @@ monitor-type = MixMonitor
 ; You can specify a post recording command to be executed after the end of
 ; recording by calling (from the dialplan)
 ;
-;   Set(MONITOR_EXEC=mv /var/spool/asterisk/monitor/^{MONITOR_FILENAME} /tmp/^{MONITOR_FILENAME})
-;
-; or
-;
 ;   Set(MONITOR_EXEC=mv /var/spool/asterisk/monitor/^{MIXMONITOR_FILENAME} /tmp/^{MIXMONITOR_FILENAME})
 ;
-; If you choose to use the latter, you will not be able to switch the monitor-type back to Monitor
-; without changing this in the dialplan.
 ;
 ;
 ; The command specified within the contents of MONITOR_EXEC will be executed when
 ; the recording is over. Any strings matching ^{X} will be unescaped to ${X} and
 ; all variables will be evaluated just prior to recording being started.
 ;
-; The contents of MONITOR_FILENAME will also be unescaped from ^{X} to ${X} and
+; The contents of MIXMONITOR_FILENAME will also be unescaped from ^{X} to ${X} and
 ; all variables will be evaluated just prior to recording being started.
 ;
 ; ---------------------- Queue Empty Options ----------------------------------
index b62d1c6..508f7de 100644 (file)
@@ -63,8 +63,6 @@
 ; decline=ast_channel_hangup_handler_type
 ; decline=ast_channel_moh_start_type
 ; decline=ast_channel_moh_stop_type
-; decline=ast_channel_monitor_start_type
-; decline=ast_channel_monitor_stop_type
 ; decline=ast_channel_mixmonitor_start_type
 ; decline=ast_channel_mixmonitor_stop_type
 ; decline=ast_channel_agent_login_type
diff --git a/doc/UPGRADE-staging/res_monitor_removal.txt b/doc/UPGRADE-staging/res_monitor_removal.txt
new file mode 100644 (file)
index 0000000..b5c7eee
--- /dev/null
@@ -0,0 +1,13 @@
+Subject: res_monitor
+Master-Only: True
+
+This module was deprecated in Asterisk 16
+and is now being removed in accordance with
+the Asterisk Module Deprecation policy.
+
+This also removes the 'w' and 'W' options
+for app_queue.
+
+MixMonitor should be default and only option
+for all settings that previously used either
+Monitor or MixMonitor.
index 39fb80f..385a2b4 100644 (file)
@@ -91,12 +91,6 @@ enum ast_bridge_builtin_feature {
         */
        AST_BRIDGE_BUILTIN_PARKCALL,
        /*!
-        * DTMF one-touch-record toggle using Monitor app.
-        *
-        * \note Only valid on two party bridges.
-        */
-       AST_BRIDGE_BUILTIN_AUTOMON,
-       /*!
         * DTMF one-touch-record toggle using MixMonitor app.
         *
         * \note Only valid on two party bridges.
@@ -305,19 +299,14 @@ struct ast_bridge_features_attended_transfer {
 };
 
 enum ast_bridge_features_monitor {
-       /*! Toggle start/stop of Monitor/MixMonitor. */
+       /*! Toggle start/stop of MixMonitor. */
        AUTO_MONITOR_TOGGLE,
-       /*! Start Monitor/MixMonitor if not already started. */
+       /*! Start MixMonitor if not already started. */
        AUTO_MONITOR_START,
-       /*! Stop Monitor/MixMonitor if not already stopped. */
+       /*! Stop MixMonitor if not already stopped. */
        AUTO_MONITOR_STOP,
 };
 
-struct ast_bridge_features_automonitor {
-       /*! Start/Stop behavior. */
-       enum ast_bridge_features_monitor start_stop;
-};
-
 struct ast_bridge_features_automixmonitor {
        /*! Start/Stop behavior. */
        enum ast_bridge_features_monitor start_stop;
index 50f8e3a..2b67bc6 100644 (file)
@@ -4033,21 +4033,6 @@ enum AST_MONITORING_STATE {
        AST_MONITOR_PAUSED
 };
 
-/*! Responsible for channel monitoring data */
-struct ast_channel_monitor {
-       struct ast_filestream *read_stream;
-       struct ast_filestream *write_stream;
-       char read_filename[FILENAME_MAX];
-       char write_filename[FILENAME_MAX];
-       char filename_base[FILENAME_MAX];
-       char beep_id[64];
-       int filename_changed;
-       char *format;
-       int joinfiles;
-       enum AST_MONITORING_STATE state;
-       int (*stop)(struct ast_channel *chan, int need_lock);
-};
-
 /* ACCESSOR FUNCTIONS */
 
 #define DECLARE_STRINGFIELD_SETTERS_FOR(field) \
@@ -4168,8 +4153,6 @@ struct ast_channel *ast_channel_masq(const struct ast_channel *chan);
 void ast_channel_masq_set(struct ast_channel *chan, struct ast_channel *value);
 struct ast_channel *ast_channel_masqr(const struct ast_channel *chan);
 void ast_channel_masqr_set(struct ast_channel *chan, struct ast_channel *value);
-struct ast_channel_monitor *ast_channel_monitor(const struct ast_channel *chan);
-void ast_channel_monitor_set(struct ast_channel *chan, struct ast_channel_monitor *value);
 struct ast_filestream *ast_channel_stream(const struct ast_channel *chan);
 void ast_channel_stream_set(struct ast_channel *chan, struct ast_filestream *value);
 struct ast_filestream *ast_channel_vstream(const struct ast_channel *chan);
index 302edd8..5c01ae1 100644 (file)
@@ -185,7 +185,6 @@ Some examples of modules that provide C APIs (potentially among other things) ar
  - res_crypto.c
  - res_curl.c
  - res_xmpp.c
- - res_monitor.c
  - res_smdi.c
  - res_speech.c
    - provides a speech recognition engine interface.
index 336454b..0aa0318 100644 (file)
@@ -28,9 +28,9 @@ struct ast_channel;
  */
 struct ast_features_general_config {
        AST_DECLARE_STRING_FIELDS(
-               /*! Sound played when automon or automixmon features are used */
+               /*! Sound played when automixmon features are used */
                AST_STRING_FIELD(courtesytone);
-               /*! Sound played when automon or automixmon features fail when used */
+               /*! Sound played when automixmon features fail when used */
                AST_STRING_FIELD(recordingfailsound);
        );
        /*! Milliseconds allowed between digit presses when entering feature code */
@@ -170,8 +170,6 @@ struct ast_featuremap_config {
                AST_STRING_FIELD(blindxfer);
                /*! Disconnect DTMF code */
                AST_STRING_FIELD(disconnect);
-               /*! Automon DTMF code */
-               AST_STRING_FIELD(automon);
                /*! Attended Transfer DTMF code */
                AST_STRING_FIELD(atxfer);
                /*! One-touch parking DTMF code */
diff --git a/include/asterisk/monitor.h b/include/asterisk/monitor.h
deleted file mode 100644 (file)
index 377cb62..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, Digium, Inc.
- *
- * Mark Spencer <markster@digium.com>
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- * \brief Channel monitoring
- */
-
-#ifndef _ASTERISK_MONITOR_H
-#define _ASTERISK_MONITOR_H
-
-#include "asterisk/channel.h"
-#include "asterisk/optional_api.h"
-
-/* Streams recording control */
-#define X_REC_IN       1
-#define X_REC_OUT      2
-#define X_JOIN         4
-
-/* Start monitoring a channel */
-AST_OPTIONAL_API(int, ast_monitor_start,
-                (struct ast_channel *chan, const char *format_spec,
-                 const char *fname_base, int need_lock, int stream_action,
-                 const char *beep_id),
-                { return -1; });
-
-/* Stop monitoring a channel */
-AST_OPTIONAL_API(int, ast_monitor_stop,
-                (struct ast_channel *chan, int need_lock),
-                { return -1; });
-
-/* Change monitoring filename of a channel */
-AST_OPTIONAL_API(int, ast_monitor_change_fname,
-                (struct ast_channel *chan, const char *fname_base,
-                 int need_lock),
-                { return -1; });
-
-AST_OPTIONAL_API(void, ast_monitor_setjoinfiles,
-                (struct ast_channel *chan, int turnon),
-                { return; });
-
-/* Pause monitoring of a channel */
-AST_OPTIONAL_API(int, ast_monitor_pause,
-                (struct ast_channel *chan),
-                { return -1; });
-
-/* Unpause monitoring of a channel */
-AST_OPTIONAL_API(int, ast_monitor_unpause,
-                (struct ast_channel *chan),
-                { return -1; });
-
-#endif /* _ASTERISK_MONITOR_H */
index d9ae9e8..728e0ff 100644 (file)
@@ -585,22 +585,6 @@ struct stasis_message_type *ast_channel_fax_type(void);
 struct stasis_message_type *ast_channel_hangup_handler_type(void);
 
 /*!
- * \since 12
- * \brief Message type for starting monitor on a channel
- *
- * \return A stasis message type
- */
-struct stasis_message_type *ast_channel_monitor_start_type(void);
-
-/*!
- * \since 12
- * \brief Message type for stopping monitor on a channel
- *
- * \return A stasis message type
- */
-struct stasis_message_type *ast_channel_monitor_stop_type(void);
-
-/*!
  * \since 18
  * \brief Message type for starting mixmonitor on a channel
  *
index a134e2a..cfbff72 100644 (file)
@@ -3,7 +3,6 @@
        *ast_agi_*;
        *ast_beep_*;
        *ast_smdi_*;
-       *ast_monitor_*;
        *ast_key_get;
        *ast_check_signature;
        *ast_check_signature_bin;
index 9f83f7d..115f6a3 100644 (file)
@@ -414,7 +414,6 @@ static int setup_bridge_features_builtin(struct ast_bridge_features *features, s
        res |= builtin_features_helper(features, chan, flags, AST_FEATURE_REDIRECT, "atxfer", AST_BRIDGE_BUILTIN_ATTENDEDTRANSFER);
        res |= builtin_features_helper(features, chan, flags, AST_FEATURE_DISCONNECT, "disconnect", AST_BRIDGE_BUILTIN_HANGUP);
        res |= builtin_features_helper(features, chan, flags, AST_FEATURE_PARKCALL, "parkcall", AST_BRIDGE_BUILTIN_PARKCALL);
-       res |= builtin_features_helper(features, chan, flags, AST_FEATURE_AUTOMON, "automon", AST_BRIDGE_BUILTIN_AUTOMON);
        res |= builtin_features_helper(features, chan, flags, AST_FEATURE_AUTOMIXMON, "automixmon", AST_BRIDGE_BUILTIN_AUTOMIXMON);
 
        return res ? -1 : 0;
index 7f00050..4aebb01 100644 (file)
@@ -1626,8 +1626,6 @@ static void testsuite_notify_feature_success(struct ast_channel *chan, const cha
                        feature = "atxfer";
                } else if (!strcmp(dtmf, featuremap->disconnect)) {
                        feature = "disconnect";
-               } else if (!strcmp(dtmf, featuremap->automon)) {
-                       feature = "automon";
                } else if (!strcmp(dtmf, featuremap->automixmon)) {
                        feature = "automixmon";
                } else if (!strcmp(dtmf, featuremap->parkcall)) {
index 7c2acd7..844cea8 100644 (file)
@@ -2195,11 +2195,6 @@ static void ast_channel_destructor(void *obj)
 
        ast_debug(1, "Channel %p '%s' destroying\n", chan, ast_channel_name(chan));
 
-       /* Stop monitoring */
-       if (ast_channel_monitor(chan)) {
-               ast_channel_monitor(chan)->stop(chan, 0);
-       }
-
        /* If there is native format music-on-hold state, free it */
        if (ast_channel_music_state(chan)) {
                ast_moh_cleanup(chan);
@@ -2516,15 +2511,13 @@ void ast_set_hangupsource(struct ast_channel *chan, const char *source, int forc
 
 int ast_channel_has_audio_frame_or_monitor(struct ast_channel *chan)
 {
-       return ast_channel_monitor(chan)
-               || !ast_audiohook_write_list_empty(ast_channel_audiohooks(chan))
+       return !ast_audiohook_write_list_empty(ast_channel_audiohooks(chan))
                || !ast_framehook_list_contains_no_active(ast_channel_framehooks(chan));
 }
 
 int ast_channel_has_hook_requiring_audio(struct ast_channel *chan)
 {
-       return ast_channel_monitor(chan)
-               || !ast_audiohook_write_list_empty(ast_channel_audiohooks(chan))
+       return !ast_audiohook_write_list_empty(ast_channel_audiohooks(chan))
                || !ast_framehook_list_contains_no_active_of_type(ast_channel_framehooks(chan), AST_FRAME_VOICE);
 }
 
@@ -4164,40 +4157,6 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio, int
                                }
                        }
 
-                       if (ast_channel_monitor(chan) && ast_channel_monitor(chan)->read_stream) {
-                               /* XXX what does this do ? */
-#ifndef MONITOR_CONSTANT_DELAY
-                               int jump = ast_channel_outsmpl(chan) - ast_channel_insmpl(chan) - 4 * f->samples;
-                               if (jump >= 0) {
-                                       jump = calc_monitor_jump((ast_channel_outsmpl(chan) - ast_channel_insmpl(chan)),
-                                               ast_format_get_sample_rate(f->subclass.format),
-                                               ast_format_get_sample_rate(ast_channel_monitor(chan)->read_stream->fmt->format));
-                                       if (ast_seekstream(ast_channel_monitor(chan)->read_stream, jump, SEEK_FORCECUR) == -1) {
-                                               ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
-                                       }
-                                       ast_channel_insmpl_set(chan, ast_channel_insmpl(chan) + (ast_channel_outsmpl(chan) - ast_channel_insmpl(chan)) + f->samples);
-                               } else {
-                                       ast_channel_insmpl_set(chan, ast_channel_insmpl(chan) + f->samples);
-                               }
-#else
-                               int jump = calc_monitor_jump((ast_channel_outsmpl(chan) - ast_channel_insmpl(chan)),
-                                       ast_format_get_sample_rate(f->subclass.format),
-                                       ast_format_get_sample_rate(ast_channel_monitor(chan)->read_stream->fmt->format));
-                               if (jump - MONITOR_DELAY >= 0) {
-                                       if (ast_seekstream(ast_channel_monitor(chan)->read_stream, jump - f->samples, SEEK_FORCECUR) == -1) {
-                                               ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
-                                       }
-                                       ast_channel_insmpl(chan) += ast_channel_outsmpl(chan) - ast_channel_insmpl(chan);
-                               } else {
-                                       ast_channel_insmpl(chan) += f->samples;
-                               }
-#endif
-                               if (ast_channel_monitor(chan)->state == AST_MONITOR_RUNNING) {
-                                       if (ast_writestream(ast_channel_monitor(chan)->read_stream, f) < 0)
-                                               ast_log(LOG_WARNING, "Failed to write data to channel monitor read stream\n");
-                               }
-                       }
-
                        if (ast_channel_readtrans(chan)
                                && ast_format_cmp(f->subclass.format, ast_channel_rawreadformat(chan)) == AST_FORMAT_CMP_EQUAL) {
                                f = ast_translate(ast_channel_readtrans(chan), f, 1);
@@ -5440,48 +5399,6 @@ int ast_write_stream(struct ast_channel *chan, int stream_num, struct ast_frame
                        }
                }
 
-               /* If Monitor is running on this channel, then we have to write frames out there too */
-               /* the translator on chan->writetrans may have returned multiple frames
-                  from the single frame we passed in; if so, feed each one of them to the
-                  monitor */
-               if ((stream == default_stream) && ast_channel_monitor(chan) && ast_channel_monitor(chan)->write_stream) {
-                       struct ast_frame *cur;
-
-                       for (cur = f; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
-                       /* XXX must explain this code */
-#ifndef MONITOR_CONSTANT_DELAY
-                               int jump = ast_channel_insmpl(chan) - ast_channel_outsmpl(chan) - 4 * cur->samples;
-                               if (jump >= 0) {
-                                       jump = calc_monitor_jump((ast_channel_insmpl(chan) - ast_channel_outsmpl(chan)),
-                                                                ast_format_get_sample_rate(f->subclass.format),
-                                                                ast_format_get_sample_rate(ast_channel_monitor(chan)->write_stream->fmt->format));
-                                       if (ast_seekstream(ast_channel_monitor(chan)->write_stream, jump, SEEK_FORCECUR) == -1) {
-                                               ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
-                                       }
-                                       ast_channel_outsmpl_set(chan, ast_channel_outsmpl(chan) + (ast_channel_insmpl(chan) - ast_channel_outsmpl(chan)) + cur->samples);
-                               } else {
-                                       ast_channel_outsmpl_set(chan, ast_channel_outsmpl(chan) + cur->samples);
-                               }
-#else
-                               int jump = calc_monitor_jump((ast_channel_insmpl(chan) - ast_channel_outsmpl(chan)),
-                                                            ast_format_get_sample_rate(f->subclass.format),
-                                                            ast_format_get_sample_rate(ast_channel_monitor(chan)->write_stream->fmt->format));
-                               if (jump - MONITOR_DELAY >= 0) {
-                                       if (ast_seekstream(ast_channel_monitor(chan)->write_stream, jump - cur->samples, SEEK_FORCECUR) == -1) {
-                                               ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
-                                       }
-                                       ast_channel_outsmpl_set(chan, ast_channel_outsmpl(chan) + ast_channel_insmpl(chan) - ast_channel_outsmpl(chan));
-                               } else {
-                                       ast_channel_outsmpl_set(chan, ast_channel_outsmpl(chan) + cur->samples);
-                               }
-#endif
-                               if (ast_channel_monitor(chan)->state == AST_MONITOR_RUNNING) {
-                                       if (ast_writestream(ast_channel_monitor(chan)->write_stream, cur) < 0)
-                                               ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n");
-                               }
-                       }
-               }
-
                /* the translator on chan->writetrans may have returned multiple frames
                   from the single frame we passed in; if so, feed each one of them to the
                   channel, freeing each one after it has been written */
@@ -7130,11 +7047,6 @@ static void channel_do_masquerade(struct ast_channel *original, struct ast_chann
                }
        }
 
-       /* Update the type. */
-       t_pvt = ast_channel_monitor(original);
-       ast_channel_monitor_set(original, ast_channel_monitor(clonechan));
-       ast_channel_monitor_set(clonechan, t_pvt);
-
        /* Keep the same language.  */
        ast_channel_language_set(original, ast_channel_language(clonechan));
 
index 2a33001..8776696 100644 (file)
@@ -94,7 +94,6 @@ struct ast_channel {
        struct ast_cdr *cdr;                            /*!< Call Detail Record */
        struct ast_tone_zone *zone;                     /*!< Tone zone as set in indications.conf or
                                                         *   in the CHANNEL dialplan function */
-       struct ast_channel_monitor *monitor;            /*!< Channel monitoring */
        ast_callid callid;                      /*!< Bound call identifier pointer */
        struct ao2_container *dialed_causes;            /*!< Contains tech-specific and Asterisk cause data from dialed channels */
 
@@ -604,14 +603,6 @@ void ast_channel_masqr_set(struct ast_channel *chan, struct ast_channel *value)
 {
        chan->masqr = value;
 }
-struct ast_channel_monitor *ast_channel_monitor(const struct ast_channel *chan)
-{
-       return chan->monitor;
-}
-void ast_channel_monitor_set(struct ast_channel *chan, struct ast_channel_monitor *value)
-{
-       chan->monitor = value;
-}
 struct ast_filestream *ast_channel_stream(const struct ast_channel *chan)
 {
        return chan->stream;
index edde702..466f602 100644 (file)
@@ -480,41 +480,6 @@ static void bridge_config_set_limits(struct ast_bridge_config *config, struct as
 
 /*!
  * \internal
- * \brief Check if Monitor needs to be started on a channel.
- * \since 12.0.0
- *
- * \param chan The bridge considers this channel the caller.
- * \param peer The bridge considers this channel the callee.
- */
-static void bridge_check_monitor(struct ast_channel *chan, struct ast_channel *peer)
-{
-       const char *value;
-       const char *monitor_args = NULL;
-       struct ast_channel *monitor_chan = NULL;
-
-       ast_channel_lock(chan);
-       value = pbx_builtin_getvar_helper(chan, "AUTO_MONITOR");
-       if (!ast_strlen_zero(value)) {
-               monitor_args = ast_strdupa(value);
-               monitor_chan = chan;
-       }
-       ast_channel_unlock(chan);
-       if (!monitor_chan) {
-               ast_channel_lock(peer);
-               value = pbx_builtin_getvar_helper(peer, "AUTO_MONITOR");
-               if (!ast_strlen_zero(value)) {
-                       monitor_args = ast_strdupa(value);
-                       monitor_chan = peer;
-               }
-               ast_channel_unlock(peer);
-       }
-       if (monitor_chan) {
-               ast_pbx_exec_application(monitor_chan, "Monitor", monitor_args);
-       }
-}
-
-/*!
- * \internal
  * \brief Send the peer channel on its way on bridge start failure.
  * \since 12.0.0
  *
@@ -550,8 +515,6 @@ static int pre_bridge_setup(struct ast_channel *chan, struct ast_channel *peer,
                ast_indicate(peer, AST_CONTROL_RINGING);
        }
 
-       bridge_check_monitor(chan, peer);
-
        set_config_flags(chan, config);
 
        /* Answer if need be */
index ba2f905..2144999 100644 (file)
                                        <synopsis>Milliseconds allowed between digit presses when entering a feature code.</synopsis>
                                </configOption>
                                <configOption name="courtesytone">
-                                       <synopsis>Sound to play when automon or automixmon is activated</synopsis>
+                                       <synopsis>Sound to play when automixmon is activated</synopsis>
                                </configOption>
                                <configOption name="recordingfailsound">
-                                       <synopsis>Sound to play when automon or automixmon is attempted but fails to start</synopsis>
+                                       <synopsis>Sound to play when automixmon is attempted but fails to start</synopsis>
                                </configOption>
                                <configOption name="transferdigittimeout" default="3">
                                        <synopsis>Seconds allowed between digit presses when dialing a transfer destination</synopsis>
                                                is used. The call is parked in the next available space in the parking lot.</para>
                                        </description>
                                </configOption>
-                               <configOption name="automon">
-                                       <synopsis>DTMF sequence to start or stop Monitor on a call</synopsis>
-                                       <description>
-                                               <para>This will cause the channel that pressed the DTMF sequence
-                                               to be monitored by the <literal>Monitor</literal> application. The
-                                               format for the recording is determined by the <replaceable>TOUCH_MONITOR_FORMAT</replaceable>
-                                               channel variable. If this variable is not specified, then <literal>wav</literal> is the
-                                               default. The filename is constructed in the following manner:</para>
-                                               <para>    prefix-timestamp-suffix.fmt</para>
-                                               <para>where prefix is either the value of the <replaceable>TOUCH_MONITOR_PREFIX</replaceable>
-                                               channel variable or <literal>auto</literal> if the variable is not set. The timestamp
-                                               is a UNIX timestamp. The suffix is either the value of the <replaceable>TOUCH_MONITOR</replaceable>
-                                               channel variable or the callerID of the channels if the variable is not set.</para>
-                                       </description>
-                                       <see-also><ref type="configOption">automixmon</ref></see-also>
-                               </configOption>
                                <configOption name="automixmon">
                                        <synopsis>DTMF sequence to start or stop MixMonitor on a call</synopsis>
                                        <description>
                                                is a UNIX timestamp. The suffix is either the value of the <replaceable>TOUCH_MIXMONITOR</replaceable>
                                                channel variable or the callerID of the channels if the variable is not set.</para>
                                        </description>
-                                       <see-also><ref type="configOption">automon</ref></see-also>
                                </configOption>
                        </configObject>
                        <configObject name="applicationmap">
                                <enumlist>
                                        <enum name="atxfer"><para>Attended Transfer</para></enum>
                                        <enum name="blindxfer"><para>Blind Transfer</para></enum>
-                                       <enum name="automon"><para>Auto Monitor</para></enum>
                                        <enum name="disconnect"><para>Call Disconnect</para></enum>
                                        <enum name="parkcall"><para>Park Call</para></enum>
                                        <enum name="automixmon"><para>Auto MixMonitor</para></enum>
@@ -1013,8 +995,6 @@ static int featuremap_set(struct ast_featuremap_config *featuremap, const char *
                ast_string_field_set(featuremap, blindxfer, value);
        } else if (!strcasecmp(name, "disconnect")) {
                ast_string_field_set(featuremap, disconnect, value);
-       } else if (!strcasecmp(name, "automon")) {
-               ast_string_field_set(featuremap, automon, value);
        } else if (!strcasecmp(name, "atxfer")) {
                ast_string_field_set(featuremap, atxfer, value);
        } else if (!strcasecmp(name, "automixmon")) {
@@ -1038,8 +1018,6 @@ static int featuremap_get(struct ast_featuremap_config *featuremap, const char *
                ast_copy_string(buf, featuremap->blindxfer, len);
        } else if (!strcasecmp(field, "disconnect")) {
                ast_copy_string(buf, featuremap->disconnect, len);
-       } else if (!strcasecmp(field, "automon")) {
-               ast_copy_string(buf, featuremap->automon, len);
        } else if (!strcasecmp(field, "atxfer")) {
                ast_copy_string(buf, featuremap->atxfer, len);
        } else if (!strcasecmp(field, "automixmon")) {
@@ -1857,8 +1835,6 @@ static int load_config(void)
                        DEFAULT_FEATUREMAP_BLINDXFER, featuremap_handler, 0);
        aco_option_register_custom(&cfg_info, "disconnect", ACO_EXACT, featuremap_options,
                        DEFAULT_FEATUREMAP_DISCONNECT, featuremap_handler, 0);
-       aco_option_register_custom(&cfg_info, "automon", ACO_EXACT, featuremap_options,
-                       DEFAULT_FEATUREMAP_AUTOMON, featuremap_handler, 0);
        aco_option_register_custom(&cfg_info, "atxfer", ACO_EXACT, featuremap_options,
                        DEFAULT_FEATUREMAP_ATXFER, featuremap_handler, 0);
        aco_option_register_custom(&cfg_info, "parkcall", ACO_EXACT, featuremap_options,
@@ -1957,7 +1933,6 @@ static char *handle_feature_show(struct ast_cli_entry *e, int cmd, struct ast_cl
        ast_cli(a->fd, HFS_FORMAT, "Pickup", DEFAULT_PICKUPEXTEN, cfg->global->pickup->pickupexten);
        ast_cli(a->fd, HFS_FORMAT, "Blind Transfer", DEFAULT_FEATUREMAP_BLINDXFER, cfg->featuremap->blindxfer);
        ast_cli(a->fd, HFS_FORMAT, "Attended Transfer", DEFAULT_FEATUREMAP_ATXFER, cfg->featuremap->atxfer);
-       ast_cli(a->fd, HFS_FORMAT, "One Touch Monitor", DEFAULT_FEATUREMAP_AUTOMON, cfg->featuremap->automon);
        ast_cli(a->fd, HFS_FORMAT, "Disconnect Call", DEFAULT_FEATUREMAP_DISCONNECT, cfg->featuremap->disconnect);
        ast_cli(a->fd, HFS_FORMAT, "Park Call", DEFAULT_FEATUREMAP_PARKCALL, cfg->featuremap->parkcall);
        ast_cli(a->fd, HFS_FORMAT, "One Touch MixMonitor", DEFAULT_FEATUREMAP_AUTOMIXMON, cfg->featuremap->automixmon);
index 8af3465..9aa980d 100644 (file)
                        </see-also>
                </managerEventInstance>
        </managerEvent>
-       <managerEvent language="en_US" name="MonitorStart">
-               <managerEventInstance class="EVENT_FLAG_CALL">
-                       <synopsis>Raised when monitoring has started on a channel.</synopsis>
-                       <syntax>
-                               <channel_snapshot/>
-                       </syntax>
-                       <see-also>
-                               <ref type="managerEvent">MonitorStop</ref>
-                               <ref type="application">Monitor</ref>
-                               <ref type="manager">Monitor</ref>
-                       </see-also>
-               </managerEventInstance>
-       </managerEvent>
-       <managerEvent language="en_US" name="MonitorStop">
-               <managerEventInstance class="EVENT_FLAG_CALL">
-               <synopsis>Raised when monitoring has stopped on a channel.</synopsis>
-               <syntax>
-                       <channel_snapshot/>
-               </syntax>
-               <see-also>
-                       <ref type="managerEvent">MonitorStart</ref>
-                       <ref type="application">StopMonitor</ref>
-                       <ref type="manager">StopMonitor</ref>
-               </see-also>
-               </managerEventInstance>
-       </managerEvent>
 ***/
 
 /*! \brief The \ref stasis subscription returned by the forwarding of the channel topic
@@ -1160,22 +1134,6 @@ static void channel_moh_stop_cb(void *data, struct stasis_subscription *sub,
        publish_basic_channel_event("MusicOnHoldStop", EVENT_FLAG_CALL, payload->snapshot);
 }
 
-static void channel_monitor_start_cb(void *data, struct stasis_subscription *sub,
-               struct stasis_message *message)
-{
-       struct ast_channel_blob *payload = stasis_message_data(message);
-
-       publish_basic_channel_event("MonitorStart", EVENT_FLAG_CALL, payload->snapshot);
-}
-
-static void channel_monitor_stop_cb(void *data, struct stasis_subscription *sub,
-               struct stasis_message *message)
-{
-       struct ast_channel_blob *payload = stasis_message_data(message);
-
-       publish_basic_channel_event("MonitorStop", EVENT_FLAG_CALL, payload->snapshot);
-}
-
 static void channel_mixmonitor_start_cb(void *data, struct stasis_subscription *sub,
                struct stasis_message *message)
 {
@@ -1427,13 +1385,6 @@ int manager_channels_init(void)
                ast_channel_moh_stop_type(), channel_moh_stop_cb, NULL);
 
        ret |= stasis_message_router_add(message_router,
-               ast_channel_monitor_start_type(), channel_monitor_start_cb,
-               NULL);
-
-       ret |= stasis_message_router_add(message_router,
-               ast_channel_monitor_stop_type(), channel_monitor_stop_cb, NULL);
-
-       ret |= stasis_message_router_add(message_router,
                ast_channel_mixmonitor_start_type(), channel_mixmonitor_start_cb, NULL);
 
        ret |= stasis_message_router_add(message_router,
index a7cc7e2..0715e4a 100644 (file)
                                                        <enum name="ast_channel_hangup_handler_type" />
                                                        <enum name="ast_channel_moh_start_type" />
                                                        <enum name="ast_channel_moh_stop_type" />
-                                                       <enum name="ast_channel_monitor_start_type" />
-                                                       <enum name="ast_channel_monitor_stop_type" />
                                                        <enum name="ast_channel_mixmonitor_start_type" />
                                                        <enum name="ast_channel_mixmonitor_stop_type" />
                                                        <enum name="ast_channel_mixmonitor_mute_type" />
index d373f6a..f796c0a 100644 (file)
@@ -1611,8 +1611,6 @@ STASIS_MESSAGE_TYPE_DEFN(ast_channel_fax_type);
 STASIS_MESSAGE_TYPE_DEFN(ast_channel_hangup_handler_type);
 STASIS_MESSAGE_TYPE_DEFN(ast_channel_moh_start_type);
 STASIS_MESSAGE_TYPE_DEFN(ast_channel_moh_stop_type);
-STASIS_MESSAGE_TYPE_DEFN(ast_channel_monitor_start_type);
-STASIS_MESSAGE_TYPE_DEFN(ast_channel_monitor_stop_type);
 STASIS_MESSAGE_TYPE_DEFN(ast_channel_mixmonitor_start_type);
 STASIS_MESSAGE_TYPE_DEFN(ast_channel_mixmonitor_stop_type);
 STASIS_MESSAGE_TYPE_DEFN(ast_channel_mixmonitor_mute_type);
@@ -1659,8 +1657,6 @@ static void stasis_channels_cleanup(void)
        STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_hangup_handler_type);
        STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_moh_start_type);
        STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_moh_stop_type);
-       STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_monitor_start_type);
-       STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_monitor_stop_type);
        STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_mixmonitor_start_type);
        STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_mixmonitor_stop_type);
        STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_mixmonitor_mute_type);
@@ -1714,8 +1710,6 @@ int ast_stasis_channels_init(void)
        res |= STASIS_MESSAGE_TYPE_INIT(ast_channel_hangup_handler_type);
        res |= STASIS_MESSAGE_TYPE_INIT(ast_channel_moh_start_type);
        res |= STASIS_MESSAGE_TYPE_INIT(ast_channel_moh_stop_type);
-       res |= STASIS_MESSAGE_TYPE_INIT(ast_channel_monitor_start_type);
-       res |= STASIS_MESSAGE_TYPE_INIT(ast_channel_monitor_stop_type);
        res |= STASIS_MESSAGE_TYPE_INIT(ast_channel_mixmonitor_start_type);
        res |= STASIS_MESSAGE_TYPE_INIT(ast_channel_mixmonitor_stop_type);
        res |= STASIS_MESSAGE_TYPE_INIT(ast_channel_mixmonitor_mute_type);
index 93a70f0..9bc389a 100644 (file)
                <member name="res_jabber" displayname="AJI - Asterisk JABBER Interface" remove_on_change="res/res_jabber.o res/res_jabber.so">
        <depend>iksemel</depend>
                </member>
-               <member name="res_monitor" displayname="Call Monitoring Resource" remove_on_change="res/res_monitor.o res/res_monitor.so">
-               </member>
                <member name="res_musiconhold" displayname="Music On Hold Resource" remove_on_change="res/res_musiconhold.o res/res_musiconhold.so">
        <conflict>win32</conflict>
                </member>
index 7bbb73f..690bf66 100644 (file)
@@ -97,7 +97,6 @@
 <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">
 </member>
 <member name="app_queue" displayname="True Call Queueing" remove_on_change="apps/app_queue.o apps/app_queue.so">
-       <depend>res_monitor</depend>
 </member>
 <member name="app_read" displayname="Read Variable Application" remove_on_change="apps/app_read.o apps/app_read.so">
 </member>
 </member>
 <member name="res_limit" displayname="Resource limits" remove_on_change="res/res_limit.o res/res_limit.so">
 </member>
-<member name="res_monitor" displayname="Call Monitoring Resource" remove_on_change="res/res_monitor.o res/res_monitor.so">
-</member>
 <member name="res_musiconhold" displayname="Music On Hold Resource" remove_on_change="res/res_musiconhold.o res/res_musiconhold.so">
        <conflict>win32</conflict>
        <use>dahdi</use>
index 3ef49d1..9350ece 100644 (file)
@@ -20,7 +20,7 @@ all: _all
 include $(ASTTOPDIR)/Makefile.moddir_rules
 
 ifneq ($(findstring $(OSARCH), mingw32 cygwin ),)
-  LIBS+= -lres_ael_share.so -lres_monitor.so
+  LIBS+= -lres_ael_share.so
 endif
 
 $(call MOD_ADD_C,pbx_dundi,dundi-parser.c)
index 9114c5c..9645e76 100644 (file)
@@ -65,7 +65,6 @@
        MeetMeCount(5555,var);
        Milliwatt();
        MixMonitor(filename,abv()V()W(),command);
-       Monitor(file.fmt,base,mb);
        MP3Player(location);
        MusicOnHold(class);
        NBScat();
index 9114c5c..9645e76 100644 (file)
@@ -65,7 +65,6 @@
        MeetMeCount(5555,var);
        Milliwatt();
        MixMonitor(filename,abv()V()W(),command);
-       Monitor(file.fmt,base,mb);
        MP3Player(location);
        MusicOnHold(class);
        NBScat();
index 6057957..927e2db 100644 (file)
@@ -425,7 +425,6 @@ context apps-include {
                app-idblock;
                app-helpdesk;
                app-dictate;
-               app-set-monitor;
        };
 };
 
@@ -485,21 +484,6 @@ context app-calltrace-perform {
        };
 };
 
-context app-set-monitor {
-       *50 => {
-               Realtime(call_info,exten,${CALLERIDNUM:5},mon_set_);
-               if ("${mon_set_monitor}" = "YES") {
-                       RealtimeUpdate(call_info,exten,${CALLERIDNUM:5},monitor|);
-                       System(/usr/local/bin/db_update.sh call_info monitor '' exten ${CALLERIDNUM:5} &);
-               } else {
-                       RealtimeUpdate(call_info,exten,${CALLERIDNUM:5},monitor,YES);
-                       System(/usr/local/bin/db_update.sh call_info monitor YES exten ${CALLERIDNUM:5} &);
-               };
-               NoOp(${mon_set_monitor});
-               Hangup;
-       };
-};
-
 context app-dnd {
        *78 => {
                Answer;
index 7f759f2..797fe33 100644 (file)
@@ -421,7 +421,6 @@ context apps-include {
                app-idblock;
                app-helpdesk;
                app-dictate;
-               app-set-monitor;
        };
 };
 
@@ -481,21 +480,6 @@ context app-calltrace-perform {
        };
 };
 
-context app-set-monitor {
-       *50 => {
-               Realtime(call_info|exten|${CALLERIDNUM:5}|mon_set_);
-               if ("${mon_set_monitor}" = "YES") {
-                       RealtimeUpdate(call_info|exten|${CALLERIDNUM:5}|monitor|);
-                       System(/usr/local/bin/db_update.sh call_info monitor '' exten ${CALLERIDNUM:5} &);
-               } else {
-                       RealtimeUpdate(call_info|exten|${CALLERIDNUM:5}|monitor|YES);
-                       System(/usr/local/bin/db_update.sh call_info monitor YES exten ${CALLERIDNUM:5} &);
-               };
-               NoOp(${mon_set_monitor});
-               Hangup;
-       };
-};
-
 context app-dnd {
        *78 => {
                Answer;
diff --git a/res/res_monitor.c b/res/res_monitor.c
deleted file mode 100644 (file)
index 1264ad0..0000000
+++ /dev/null
@@ -1,1019 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, Digium, Inc.
- *
- * Mark Spencer <markster@digium.com>
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief PBX channel monitoring
- *
- * \author Mark Spencer <markster@digium.com>
- */
-
-/*** MODULEINFO
-       <use type="module">func_periodic_hook</use>
-       <defaultenabled>no</defaultenabled>
-       <support_level>deprecated</support_level>
-       <replacement>app_mixmonitor</replacement>
-       <deprecated_in>16</deprecated_in>
-       <removed_in>21</removed_in>
- ***/
-
-#include "asterisk.h"
-
-#include <sys/stat.h>
-#include <libgen.h>
-
-#include "asterisk/paths.h"    /* use ast_config_AST_MONITOR_DIR */
-#include "asterisk/lock.h"
-#include "asterisk/channel.h"
-#include "asterisk/file.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/cli.h"
-#include "asterisk/manager.h"
-#include "asterisk/stasis.h"
-#include "asterisk/stasis_channels.h"
-#define AST_API_MODULE
-#include "asterisk/monitor.h"
-#undef AST_API_MODULE
-#include "asterisk/app.h"
-#include "asterisk/utils.h"
-#include "asterisk/config.h"
-#include "asterisk/options.h"
-#include "asterisk/beep.h"
-
-/*** DOCUMENTATION
-       <application name="Monitor" language="en_US">
-               <synopsis>
-                       Monitor a channel.
-               </synopsis>
-               <syntax>
-                       <parameter name="file_format" argsep=":">
-                               <argument name="file_format" required="true">
-                                       <para>Optional.  If not set, defaults to <literal>wav</literal></para>
-                               </argument>
-                               <argument name="urlbase" />
-                       </parameter>
-                       <parameter name="fname_base">
-                               <para>If set, changes the filename used to the one specified.</para>
-                       </parameter>
-                       <parameter name="options">
-                               <optionlist>
-                                       <option name="m">
-                                               <para>When the recording ends mix the two leg files into one and
-                                               delete the two leg files. If the variable <variable>MONITOR_EXEC</variable>
-                                               is set, the application referenced in it will be executed instead of
-                                               soxmix/sox and the raw leg files will NOT be deleted automatically.
-                                               soxmix/sox or <variable>MONITOR_EXEC</variable> is handed 3 arguments,
-                                               the two leg files and a target mixed file name which is the same as
-                                               the leg file names only without the in/out designator.</para>
-                                               <para>If <variable>MONITOR_EXEC_ARGS</variable> is set, the contents
-                                               will be passed on as additional arguments to <variable>MONITOR_EXEC</variable>.
-                                               Both <variable>MONITOR_EXEC</variable> and the Mix flag can be set from the
-                                               administrator interface.</para>
-                                               <warning><para>Do not use untrusted strings such as
-                                               <variable>CALLERID(num)</variable> or <variable>CALLERID(name)</variable>
-                                               as part of <variable>MONITOR_EXEC</variable> or
-                                               <variable>MONITOR_EXEC_ARGS</variable>.  You risk a command injection
-                                               attack executing arbitrary commands if the untrusted strings aren't
-                                               filtered to remove dangerous characters.  See function
-                                               <variable>FILTER()</variable>.</para></warning>
-                                       </option>
-                                       <option name="b">
-                                               <para>Don't begin recording unless a call is bridged to another channel.</para>
-                                       </option>
-                                       <option name="B">
-                                               <para>Play a periodic beep while this call is being recorded.</para>
-                                               <argument name="interval"><para>Interval, in seconds. Default is 15.</para></argument>
-                                       </option>
-                                       <option name="i">
-                                               <para>Skip recording of input stream (disables <literal>m</literal> option).</para>
-                                       </option>
-                                       <option name="o">
-                                               <para>Skip recording of output stream (disables <literal>m</literal> option).</para>
-                                       </option>
-                               </optionlist>
-                       </parameter>
-               </syntax>
-               <description>
-                       <para>Used to start monitoring a channel. The channel's input and output
-                       voice packets are logged to files until the channel hangs up or
-                       monitoring is stopped by the StopMonitor application.</para>
-                       <para>By default, files are stored to <filename>/var/spool/asterisk/monitor/</filename>.
-                       Returns <literal>-1</literal> if monitor files can't be opened or if the channel is
-                       already monitored, otherwise <literal>0</literal>.</para>
-               </description>
-               <see-also>
-                       <ref type="application">StopMonitor</ref>
-               </see-also>
-       </application>
-       <application name="StopMonitor" language="en_US">
-               <synopsis>
-                       Stop monitoring a channel.
-               </synopsis>
-               <syntax />
-               <description>
-                       <para>Stops monitoring a channel. Has no effect if the channel is not monitored.</para>
-               </description>
-       </application>
-       <application name="ChangeMonitor" language="en_US">
-               <synopsis>
-                       Change monitoring filename of a channel.
-               </synopsis>
-               <syntax>
-                       <parameter name="filename_base" required="true">
-                               <para>The new filename base to use for monitoring this channel.</para>
-                       </parameter>
-               </syntax>
-               <description>
-                       <para>Changes monitoring filename of a channel. Has no effect if the
-                       channel is not monitored.</para>
-               </description>
-       </application>
-       <application name="PauseMonitor" language="en_US">
-               <synopsis>
-                       Pause monitoring of a channel.
-               </synopsis>
-               <syntax />
-               <description>
-                       <para>Pauses monitoring of a channel until it is re-enabled by a call to UnpauseMonitor.</para>
-               </description>
-               <see-also>
-                       <ref type="application">UnpauseMonitor</ref>
-               </see-also>
-       </application>
-       <application name="UnpauseMonitor" language="en_US">
-               <synopsis>
-                       Unpause monitoring of a channel.
-               </synopsis>
-               <syntax />
-               <description>
-                       <para>Unpauses monitoring of a channel on which monitoring had
-                       previously been paused with PauseMonitor.</para>
-               </description>
-               <see-also>
-                       <ref type="application">PauseMonitor</ref>
-               </see-also>
-       </application>
-       <manager name="Monitor" language="en_US">
-               <synopsis>
-                       Monitor a channel.
-               </synopsis>
-               <syntax>
-                       <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
-                       <parameter name="Channel" required="true">
-                               <para>Used to specify the channel to record.</para>
-                       </parameter>
-                       <parameter name="File">
-                               <para>Is the name of the file created in the monitor spool directory.
-                               Defaults to the same name as the channel (with slashes replaced with dashes).</para>
-                       </parameter>
-                       <parameter name="Format">
-                               <para>Is the audio recording format. Defaults to <literal>wav</literal>.</para>
-                       </parameter>
-                       <parameter name="Mix">
-                               <para>Boolean parameter as to whether to mix the input and output channels
-                               together after the recording is finished.</para>
-                       </parameter>
-               </syntax>
-               <description>
-                       <para>This action may be used to record the audio on a
-                       specified channel.</para>
-               </description>
-       </manager>
-       <manager name="StopMonitor" language="en_US">
-               <synopsis>
-                       Stop monitoring a channel.
-               </synopsis>
-               <syntax>
-                       <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
-                       <parameter name="Channel" required="true">
-                               <para>The name of the channel monitored.</para>
-                       </parameter>
-               </syntax>
-               <description>
-                       <para>This action may be used to end a previously started 'Monitor' action.</para>
-               </description>
-       </manager>
-       <manager name="ChangeMonitor" language="en_US">
-               <synopsis>
-                       Change monitoring filename of a channel.
-               </synopsis>
-               <syntax>
-                       <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
-                       <parameter name="Channel" required="true">
-                               <para>Used to specify the channel to record.</para>
-                       </parameter>
-                       <parameter name="File" required="true">
-                               <para>Is the new name of the file created in the
-                               monitor spool directory.</para>
-                       </parameter>
-               </syntax>
-               <description>
-                       <para>This action may be used to change the file
-                       started by a previous 'Monitor' action.</para>
-               </description>
-       </manager>
-       <manager name="PauseMonitor" language="en_US">
-               <synopsis>
-                       Pause monitoring of a channel.
-               </synopsis>
-               <syntax>
-                       <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
-                       <parameter name="Channel" required="true">
-                               <para>Used to specify the channel to record.</para>
-                       </parameter>
-               </syntax>
-               <description>
-                       <para>This action may be used to temporarily stop the
-                       recording of a channel.</para>
-               </description>
-       </manager>
-       <manager name="UnpauseMonitor" language="en_US">
-               <synopsis>
-                       Unpause monitoring of a channel.
-               </synopsis>
-               <syntax>
-                       <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
-                       <parameter name="Channel" required="true">
-                               <para>Used to specify the channel to record.</para>
-                       </parameter>
-               </syntax>
-               <description>
-                       <para>This action may be used to re-enable recording
-                       of a channel after calling PauseMonitor.</para>
-               </description>
-       </manager>
-
- ***/
-
-AST_MUTEX_DEFINE_STATIC(monitorlock);
-
-#define LOCK_IF_NEEDED(lock, needed) do { \
-       if (needed) \
-               ast_channel_lock(lock); \
-       } while(0)
-
-#define UNLOCK_IF_NEEDED(lock, needed) do { \
-       if (needed) \
-               ast_channel_unlock(lock); \
-       } while (0)
-
-static unsigned long seq = 0;
-
-/*!
- * \brief Change state of monitored channel
- * \param chan
- * \param state monitor state
- * \retval 0 on success.
- * \retval -1 on failure.
-*/
-static int ast_monitor_set_state(struct ast_channel *chan, int state)
-{
-       LOCK_IF_NEEDED(chan, 1);
-       if (!ast_channel_monitor(chan)) {
-               UNLOCK_IF_NEEDED(chan, 1);
-               return -1;
-       }
-       ast_channel_monitor(chan)->state = state;
-       UNLOCK_IF_NEEDED(chan, 1);
-       return 0;
-}
-
-/*! \brief Start monitoring a channel
- * \param chan ast_channel struct to record
- * \param format_spec file format to use for recording
- * \param fname_base filename base to record to
- * \param need_lock whether to lock the channel mutex
- * \param stream_action whether to record the input and/or output streams.  X_REC_IN | X_REC_OUT is most often used
- * \param beep_id
- * Creates the file to record, if no format is specified it assumes WAV
- * It also sets channel variable __MONITORED=yes
- * \retval 0 on success
- * \retval -1 on failure
- */
-int AST_OPTIONAL_API_NAME(ast_monitor_start)(struct ast_channel *chan, const char *format_spec,
-                                            const char *fname_base, int need_lock, int stream_action,
-                                            const char *beep_id)
-{
-       int res = 0;
-       RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
-
-       LOCK_IF_NEEDED(chan, need_lock);
-
-       if (!(ast_channel_monitor(chan))) {
-               struct ast_channel_monitor *monitor;
-               char *channel_name, *p;
-
-               /* Create monitoring directory if needed */
-               ast_mkdir(ast_config_AST_MONITOR_DIR, 0777);
-
-               if (!(monitor = ast_calloc(1, sizeof(*monitor)))) {
-                       UNLOCK_IF_NEEDED(chan, need_lock);
-                       return -1;
-               }
-
-               if (!ast_strlen_zero(beep_id)) {
-                       ast_copy_string(monitor->beep_id, beep_id, sizeof(monitor->beep_id));
-               }
-
-               /* Determine file names */
-               if (!ast_strlen_zero(fname_base)) {
-                       int directory = strchr(fname_base, '/') ? 1 : 0;
-                       const char *absolute = *fname_base == '/' ? "" : ast_config_AST_MONITOR_DIR;
-                       const char *absolute_suffix = *fname_base == '/' ? "" : "/";
-
-                       snprintf(monitor->read_filename, FILENAME_MAX, "%s%s%s-in",
-                                               absolute, absolute_suffix, fname_base);
-                       snprintf(monitor->write_filename, FILENAME_MAX, "%s%s%s-out",
-                                               absolute, absolute_suffix, fname_base);
-                       snprintf(monitor->filename_base, FILENAME_MAX, "%s%s%s",
-                                               absolute, absolute_suffix, fname_base);
-
-                       /* try creating the directory just in case it doesn't exist */
-                       if (directory) {
-                               char *name = ast_strdupa(monitor->filename_base);
-                               ast_mkdir(dirname(name), 0777);
-                       }
-               } else {
-                       ast_mutex_lock(&monitorlock);
-                       snprintf(monitor->read_filename, FILENAME_MAX, "%s/audio-in-%lu",
-                                               ast_config_AST_MONITOR_DIR, seq);
-                       snprintf(monitor->write_filename, FILENAME_MAX, "%s/audio-out-%lu",
-                                               ast_config_AST_MONITOR_DIR, seq);
-                       seq++;
-                       ast_mutex_unlock(&monitorlock);
-
-                       /* Replace all '/' chars from the channel name with '-' chars. */
-                       channel_name = ast_strdupa(ast_channel_name(chan));
-                       for (p = channel_name; (p = strchr(p, '/')); ) {
-                               *p = '-';
-                       }
-
-                       snprintf(monitor->filename_base, FILENAME_MAX, "%s/%d-%s",
-                                        ast_config_AST_MONITOR_DIR, (int)time(NULL), channel_name);
-                       monitor->filename_changed = 1;
-               }
-
-               monitor->stop = ast_monitor_stop;
-
-               /* Determine file format */
-               if (!ast_strlen_zero(format_spec)) {
-                       monitor->format = ast_strdup(format_spec);
-               } else {
-                       monitor->format = ast_strdup("wav");
-               }
-
-               /* open files */
-               if (stream_action & X_REC_IN) {
-                       if (ast_fileexists(monitor->read_filename, NULL, NULL) > 0)
-                               ast_filedelete(monitor->read_filename, NULL);
-                       if (!(monitor->read_stream = ast_writefile(monitor->read_filename,
-                                                       monitor->format, NULL,
-                                                       O_CREAT|O_TRUNC|O_WRONLY, 0, AST_FILE_MODE))) {
-                               ast_log(LOG_WARNING, "Could not create file %s\n",
-                                                       monitor->read_filename);
-                               ast_free(monitor);
-                               UNLOCK_IF_NEEDED(chan, need_lock);
-                               return -1;
-                       }
-               } else
-                       monitor->read_stream = NULL;
-
-               if (stream_action & X_REC_OUT) {
-                       if (ast_fileexists(monitor->write_filename, NULL, NULL) > 0) {
-                               ast_filedelete(monitor->write_filename, NULL);
-                       }
-                       if (!(monitor->write_stream = ast_writefile(monitor->write_filename,
-                                                       monitor->format, NULL,
-                                                       O_CREAT|O_TRUNC|O_WRONLY, 0, AST_FILE_MODE))) {
-                               ast_log(LOG_WARNING, "Could not create file %s\n",
-                                                       monitor->write_filename);
-                               if (monitor->read_stream) {
-                                       ast_closestream(monitor->read_stream);
-                               }
-                               ast_free(monitor);
-                               UNLOCK_IF_NEEDED(chan, need_lock);
-                               return -1;
-                       }
-               } else
-                       monitor->write_stream = NULL;
-
-               ast_channel_insmpl_set(chan, 0);
-               ast_channel_outsmpl_set(chan, 0);
-               ast_channel_monitor_set(chan, monitor);
-               ast_monitor_set_state(chan, AST_MONITOR_RUNNING);
-               /* so we know this call has been monitored in case we need to bill for it or something */
-               pbx_builtin_setvar_helper(chan, "__MONITORED","true");
-
-               message = ast_channel_blob_create_from_cache(ast_channel_uniqueid(chan),
-                               ast_channel_monitor_start_type(),
-                               NULL);
-               if (message) {
-                       stasis_publish(ast_channel_topic(chan), message);
-               }
-       } else {
-               ast_debug(1,"Cannot start monitoring %s, already monitored\n", ast_channel_name(chan));
-               res = -1;
-       }
-
-       UNLOCK_IF_NEEDED(chan, need_lock);
-
-       return res;
-}
-
-/*!
- * \brief Get audio format.
- * \param format recording format.
- * The file format extensions that Asterisk uses are not all the same as that
- * which soxmix expects.  This function ensures that the format used as the
- * extension on the filename is something soxmix will understand.
- */
-static const char *get_soxmix_format(const char *format)
-{
-       const char *res = format;
-
-       if (!strcasecmp(format,"ulaw"))
-               res = "ul";
-       if (!strcasecmp(format,"alaw"))
-               res = "al";
-
-       return res;
-}
-
-/*!
- * \brief Stop monitoring channel
- * \param chan
- * \param need_lock
- * Stop the recording, close any open streams, mix in/out channels if required
- * \retval 0 Always
-*/
-int AST_OPTIONAL_API_NAME(ast_monitor_stop)(struct ast_channel *chan, int need_lock)
-{
-       int delfiles = 0;
-       RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
-
-       LOCK_IF_NEEDED(chan, need_lock);
-
-       if (ast_channel_monitor(chan)) {
-               RAII_VAR(struct ast_str *, tmp, ast_str_create(1024), ast_free);
-
-               if (ast_channel_monitor(chan)->read_stream) {
-                       ast_closestream(ast_channel_monitor(chan)->read_stream);
-               }
-               if (ast_channel_monitor(chan)->write_stream) {
-                       ast_closestream(ast_channel_monitor(chan)->write_stream);
-               }
-
-               if (tmp && ast_channel_monitor(chan)->filename_changed && !ast_strlen_zero(ast_channel_monitor(chan)->filename_base)) {
-                       if (ast_fileexists(ast_channel_monitor(chan)->read_filename,NULL,NULL) > 0) {
-                               ast_str_set(&tmp, 0, "%s-in", ast_channel_monitor(chan)->filename_base);
-                               if (ast_fileexists(ast_str_buffer(tmp), NULL, NULL) > 0) {
-                                       ast_filedelete(ast_str_buffer(tmp), NULL);
-                               }
-                               ast_filerename(ast_channel_monitor(chan)->read_filename, ast_str_buffer(tmp), ast_channel_monitor(chan)->format);
-                       } else {
-                               ast_log(LOG_WARNING, "File %s not found\n", ast_channel_monitor(chan)->read_filename);
-                       }
-
-                       if (tmp && ast_fileexists(ast_channel_monitor(chan)->write_filename,NULL,NULL) > 0) {
-                               ast_str_set(&tmp, 0, "%s-out", ast_channel_monitor(chan)->filename_base);
-                               if (ast_fileexists(ast_str_buffer(tmp), NULL, NULL) > 0) {
-                                       ast_filedelete(ast_str_buffer(tmp), NULL);
-                               }
-                               ast_filerename(ast_channel_monitor(chan)->write_filename, ast_str_buffer(tmp), ast_channel_monitor(chan)->format);
-                       } else {
-                               ast_log(LOG_WARNING, "File %s not found\n", ast_channel_monitor(chan)->write_filename);
-                       }
-               }
-
-               if (tmp && ast_channel_monitor(chan)->joinfiles && !ast_strlen_zero(ast_channel_monitor(chan)->filename_base)) {
-                       const char *format = !strcasecmp(ast_channel_monitor(chan)->format,"wav49") ? "WAV" : ast_channel_monitor(chan)->format;
-                       char *fname_base = ast_channel_monitor(chan)->filename_base;
-                       const char *execute, *execute_args;
-                       /* at this point, fname_base really is the full path */
-
-                       /* Set the execute application */
-                       execute = pbx_builtin_getvar_helper(chan, "MONITOR_EXEC");
-                       if (ast_strlen_zero(execute)) {
-#ifdef HAVE_SOXMIX
-                               execute = "nice -n 19 soxmix";
-#else
-                               execute = "nice -n 19 sox -m";
-#endif
-                               format = get_soxmix_format(format);
-                               delfiles = 1;
-                       }
-                       execute_args = pbx_builtin_getvar_helper(chan, "MONITOR_EXEC_ARGS");
-                       if (ast_strlen_zero(execute_args)) {
-                               execute_args = "";
-                       }
-
-                       ast_str_set(&tmp, 0, delfiles ? "( " : "");
-                       ast_str_append(&tmp, 0, "%s \"%s-in.%s\" \"%s-out.%s\" \"%s.%s\" %s &",
-                               execute, fname_base, format, fname_base, format, fname_base, format,execute_args);
-                       if (delfiles) {
-                               /* remove legs when done mixing */
-                               ast_str_append(&tmp, 0, "& rm -f \"%s-\"* ) &", fname_base);
-                       }
-                       ast_debug(1,"monitor executing %s\n", ast_str_buffer(tmp));
-                       if (ast_safe_system(ast_str_buffer(tmp)) == -1)
-                               ast_log(LOG_WARNING, "Execute of %s failed.\n", ast_str_buffer(tmp));
-               }
-
-               if (!ast_strlen_zero(ast_channel_monitor(chan)->beep_id)) {
-                       ast_beep_stop(chan, ast_channel_monitor(chan)->beep_id);
-               }
-
-               ast_free(ast_channel_monitor(chan)->format);
-               ast_free(ast_channel_monitor(chan));
-               ast_channel_monitor_set(chan, NULL);
-
-               message = ast_channel_blob_create_from_cache(ast_channel_uniqueid(chan),
-                               ast_channel_monitor_stop_type(),
-                               NULL);
-               if (message) {
-                       stasis_publish(ast_channel_topic(chan), message);
-               }
-               pbx_builtin_setvar_helper(chan, "MONITORED", NULL);
-       }
-       pbx_builtin_setvar_helper(chan, "AUTO_MONITOR", NULL);
-
-       UNLOCK_IF_NEEDED(chan, need_lock);
-
-       return 0;
-}
-
-
-/*! \brief Pause monitoring of channel */
-int AST_OPTIONAL_API_NAME(ast_monitor_pause)(struct ast_channel *chan)
-{
-       return ast_monitor_set_state(chan, AST_MONITOR_PAUSED);
-}
-
-/*! \brief Unpause monitoring of channel */
-int AST_OPTIONAL_API_NAME(ast_monitor_unpause)(struct ast_channel *chan)
-{
-       return ast_monitor_set_state(chan, AST_MONITOR_RUNNING);
-}
-
-/*! \brief Wrapper for ast_monitor_pause */
-static int pause_monitor_exec(struct ast_channel *chan, const char *data)
-{
-       return ast_monitor_pause(chan);
-}
-
-/*! \brief Wrapper for ast_monitor_unpause */
-static int unpause_monitor_exec(struct ast_channel *chan, const char *data)
-{
-       return ast_monitor_unpause(chan);
-}
-
-/*!
- * \brief Change monitored filename of channel
- * \param chan
- * \param fname_base new filename
- * \param need_lock
- * \retval 0 on success.
- * \retval -1 on failure.
-*/
-int AST_OPTIONAL_API_NAME(ast_monitor_change_fname)(struct ast_channel *chan, const char *fname_base, int need_lock)
-{
-       if (ast_strlen_zero(fname_base)) {
-               ast_log(LOG_WARNING, "Cannot change monitor filename of channel %s to null\n", ast_channel_name(chan));
-               return -1;
-       }
-
-       LOCK_IF_NEEDED(chan, need_lock);
-
-       if (ast_channel_monitor(chan)) {
-               int directory = strchr(fname_base, '/') ? 1 : 0;
-               const char *absolute = *fname_base == '/' ? "" : ast_config_AST_MONITOR_DIR;
-               const char *absolute_suffix = *fname_base == '/' ? "" : "/";
-               char tmpstring[sizeof(ast_channel_monitor(chan)->filename_base)] = "";
-               int i, fd[2] = { -1, -1 }, doexit = 0;
-
-               /* before continuing, see if we're trying to rename the file to itself... */
-               snprintf(tmpstring, sizeof(tmpstring), "%s%s%s", absolute, absolute_suffix, fname_base);
-
-               /* try creating the directory just in case it doesn't exist */
-               if (directory) {
-                       char *name = ast_strdupa(tmpstring);
-                       ast_mkdir(dirname(name), 0777);
-               }
-
-               /*!
-                * \note We cannot just compare filenames, due to symlinks, relative
-                * paths, and other possible filesystem issues.  We could use
-                * realpath(3), but its use is discouraged.  However, if we try to
-                * create the same file from two different paths, the second will
-                * fail, and so we have our notification that the filenames point to
-                * the same path.
-                *
-                * Remember, also, that we're using the basename of the file (i.e.
-                * the file without the format suffix), so it does not already exist
-                * and we aren't interfering with the recording itself.
-                */
-               ast_debug(2, "comparing tmpstring %s to filename_base %s\n", tmpstring, ast_channel_monitor(chan)->filename_base);
-
-               if ((fd[0] = open(tmpstring, O_CREAT | O_WRONLY, 0644)) < 0 ||
-                       (fd[1] = open(ast_channel_monitor(chan)->filename_base, O_CREAT | O_EXCL | O_WRONLY, 0644)) < 0) {
-                       if (fd[0] < 0) {
-                               ast_log(LOG_ERROR, "Unable to compare filenames: %s\n", strerror(errno));
-                       } else {
-                               ast_debug(2, "No need to rename monitor filename to itself\n");
-                       }
-                       doexit = 1;
-               }
-
-               /* Cleanup temporary files */
-               for (i = 0; i < 2; i++) {
-                       if (fd[i] >= 0) {
-                               while (close(fd[i]) < 0 && errno == EINTR);
-                       }
-               }
-               unlink(tmpstring);
-               /* if previous monitor file existed in a subdirectory, the directory will not be removed */
-               unlink(ast_channel_monitor(chan)->filename_base);
-
-               if (doexit) {
-                       UNLOCK_IF_NEEDED(chan, need_lock);
-                       return 0;
-               }
-
-               ast_copy_string(ast_channel_monitor(chan)->filename_base, tmpstring, sizeof(ast_channel_monitor(chan)->filename_base));
-               ast_channel_monitor(chan)->filename_changed = 1;
-       } else {
-               ast_log(LOG_WARNING, "Cannot change monitor filename of channel %s to %s, monitoring not started\n", ast_channel_name(chan), fname_base);
-       }
-
-       UNLOCK_IF_NEEDED(chan, need_lock);
-
-       return 0;
-}
-
-enum {
-       MON_FLAG_BRIDGED =  (1 << 0),
-       MON_FLAG_MIX =      (1 << 1),
-       MON_FLAG_DROP_IN =  (1 << 2),
-       MON_FLAG_DROP_OUT = (1 << 3),
-       MON_FLAG_BEEP =     (1 << 4),
-};
-
-enum {
-       OPT_ARG_BEEP_INTERVAL,
-       OPT_ARG_ARRAY_SIZE,     /* Always last element of the enum */
-};
-
-AST_APP_OPTIONS(monitor_opts, {
-       AST_APP_OPTION('b', MON_FLAG_BRIDGED),
-       AST_APP_OPTION('m', MON_FLAG_MIX),
-       AST_APP_OPTION('i', MON_FLAG_DROP_IN),
-       AST_APP_OPTION('o', MON_FLAG_DROP_OUT),
-       AST_APP_OPTION_ARG('B', MON_FLAG_BEEP, OPT_ARG_BEEP_INTERVAL),
-});
-
-/*!
- * \brief Start monitor
- * \param chan
- * \param data arguments passed fname|options
- * \retval 0 on success.
- * \retval -1 on failure.
-*/
-static int start_monitor_exec(struct ast_channel *chan, const char *data)
-{
-       char *arg;
-       char *options;
-       char *delay;
-       char *urlprefix = NULL;
-       char tmp[256];
-       int stream_action = X_REC_IN | X_REC_OUT;
-       int joinfiles = 0;
-       int res = 0;
-       char *parse;
-       struct ast_flags flags = { 0 };
-       char *opts[OPT_ARG_ARRAY_SIZE] = { NULL, };
-       char beep_id[64] = "";
-       AST_DECLARE_APP_ARGS(args,
-               AST_APP_ARG(format);
-               AST_APP_ARG(fname_base);
-               AST_APP_ARG(options);
-       );
-
-       /* Parse arguments. */
-       if (ast_strlen_zero(data)) {
-               ast_log(LOG_ERROR, "Monitor requires an argument\n");
-               return 0;
-       }
-
-       parse = ast_strdupa(data);
-       AST_STANDARD_APP_ARGS(args, parse);
-
-       if (!ast_strlen_zero(args.options)) {
-               ast_app_parse_options(monitor_opts, &flags, opts, args.options);
-
-               if (ast_test_flag(&flags, MON_FLAG_MIX)) {
-                       stream_action |= X_JOIN;
-               }
-               if (ast_test_flag(&flags, MON_FLAG_DROP_IN)) {
-                       stream_action &= ~X_REC_IN;
-               }
-               if (ast_test_flag(&flags, MON_FLAG_DROP_OUT)) {
-                       stream_action &= ~X_REC_OUT;
-               }
-               if (ast_test_flag(&flags, MON_FLAG_BEEP)) {
-                       const char *interval_str = S_OR(opts[OPT_ARG_BEEP_INTERVAL], "15");
-                       unsigned int interval = 15;
-
-                       if (sscanf(interval_str, "%30u", &interval) != 1) {
-                               ast_log(LOG_WARNING, "Invalid interval '%s' for periodic beep. Using default of %u\n",
-                                               interval_str, interval);
-                       }
-
-                       if (ast_beep_start(chan, interval, beep_id, sizeof(beep_id))) {
-                               ast_log(LOG_WARNING, "Unable to enable periodic beep, please ensure func_periodic_hook is loaded.\n");
-                               return -1;
-                       }
-               }
-       }
-
-       arg = strchr(args.format, ':');
-       if (arg) {
-               *arg++ = 0;
-               urlprefix = arg;
-       }
-
-       if (!ast_strlen_zero(urlprefix) && !ast_strlen_zero(args.fname_base)) {
-               snprintf(tmp, sizeof(tmp), "%s/%s.%s", urlprefix, args.fname_base,
-                       ((strcmp(args.format, "gsm")) ? "wav" : "gsm"));
-               ast_channel_lock(chan);
-               ast_cdr_setuserfield(ast_channel_name(chan), tmp);
-               ast_channel_unlock(chan);
-       }
-       if (ast_test_flag(&flags, MON_FLAG_BRIDGED)) {
-               /* We must remove the "b" option if listed.  In principle none of
-                  the following could give NULL results, but we check just to
-                  be pedantic. Reconstructing with checks for 'm' option does not
-                  work if we end up adding more options than 'm' in the future. */
-               delay = ast_strdupa(data);
-               options = strrchr(delay, ',');
-               if (options) {
-                       arg = strchr(options, 'b');
-                       if (arg) {
-                               *arg = 'X';
-                               pbx_builtin_setvar_helper(chan,"AUTO_MONITOR", delay);
-                       }
-               }
-               return 0;
-       }
-
-       res = ast_monitor_start(chan, args.format, args.fname_base, 1, stream_action, beep_id);
-       if (res < 0)
-               res = ast_monitor_change_fname(chan, args.fname_base, 1);
-
-       if (stream_action & X_JOIN) {
-               if ((stream_action & X_REC_IN) && (stream_action & X_REC_OUT))
-                       joinfiles = 1;
-               else
-                       ast_log(LOG_WARNING, "Won't mix streams unless both input and output streams are recorded\n");
-       }
-       ast_monitor_setjoinfiles(chan, joinfiles);
-
-       return res;
-}
-
-/*! \brief Wrapper function \see ast_monitor_stop */
-static int stop_monitor_exec(struct ast_channel *chan, const char *data)
-{
-       return ast_monitor_stop(chan, 1);
-}
-
-/*! \brief Wrapper function \see ast_monitor_change_fname */
-static int change_monitor_exec(struct ast_channel *chan, const char *data)
-{
-       return ast_monitor_change_fname(chan, data, 1);
-}
-
-/*! \brief Start monitoring a channel by manager connection */
-static int start_monitor_action(struct mansession *s, const struct message *m)
-{
-       struct ast_channel *c = NULL;
-       const char *name = astman_get_header(m, "Channel");
-       const char *fname = astman_get_header(m, "File");
-       const char *format = astman_get_header(m, "Format");
-       const char *mix = astman_get_header(m, "Mix");
-       char *d;
-
-       if (ast_strlen_zero(name)) {
-               astman_send_error(s, m, "No channel specified");
-               return AMI_SUCCESS;
-       }
-
-       if (!(c = ast_channel_get_by_name(name))) {
-               astman_send_error(s, m, "No such channel");
-               return AMI_SUCCESS;
-       }
-
-       if (ast_strlen_zero(fname)) {
-               /* No filename specified, default to the channel name. */
-               ast_channel_lock(c);
-               fname = ast_strdupa(ast_channel_name(c));
-               ast_channel_unlock(c);
-
-               /* Replace all '/' chars from the channel name with '-' chars. */
-               for (d = (char *) fname; (d = strchr(d, '/')); ) {
-                       *d = '-';
-               }
-       }
-
-       if (ast_monitor_start(c, format, fname, 1, X_REC_IN | X_REC_OUT, NULL)) {
-               if (ast_monitor_change_fname(c, fname, 1)) {
-                       astman_send_error(s, m, "Could not start monitoring channel");
-                       c = ast_channel_unref(c);
-                       return AMI_SUCCESS;
-               }
-       }
-
-       if (ast_true(mix)) {
-               ast_channel_lock(c);
-               ast_monitor_setjoinfiles(c, 1);
-               ast_channel_unlock(c);
-       }
-
-       c = ast_channel_unref(c);
-
-       astman_send_ack(s, m, "Started monitoring channel");
-
-       return AMI_SUCCESS;
-}
-
-/*! \brief Stop monitoring a channel by manager connection */
-static int stop_monitor_action(struct mansession *s, const struct message *m)
-{
-       struct ast_channel *c = NULL;
-       const char *name = astman_get_header(m, "Channel");
-       int res;
-
-       if (ast_strlen_zero(name)) {
-               astman_send_error(s, m, "No channel specified");
-               return AMI_SUCCESS;
-       }
-
-       if (!(c = ast_channel_get_by_name(name))) {
-               astman_send_error(s, m, "No such channel");
-               return AMI_SUCCESS;
-       }
-
-       res = ast_monitor_stop(c, 1);
-
-       c = ast_channel_unref(c);
-
-       if (res) {
-               astman_send_error(s, m, "Could not stop monitoring channel");
-               return AMI_SUCCESS;
-       }
-
-       astman_send_ack(s, m, "Stopped monitoring channel");
-
-       return AMI_SUCCESS;
-}
-
-/*! \brief Change filename of a monitored channel by manager connection */
-static int change_monitor_action(struct mansession *s, const struct message *m)
-{
-       struct ast_channel *c = NULL;
-       const char *name = astman_get_header(m, "Channel");
-       const char *fname = astman_get_header(m, "File");
-
-       if (ast_strlen_zero(name)) {
-               astman_send_error(s, m, "No channel specified");
-               return AMI_SUCCESS;
-       }
-
-       if (ast_strlen_zero(fname)) {
-               astman_send_error(s, m, "No filename specified");
-               return AMI_SUCCESS;
-       }
-
-       if (!(c = ast_channel_get_by_name(name))) {
-               astman_send_error(s, m, "No such channel");
-               return AMI_SUCCESS;
-       }
-
-       if (ast_monitor_change_fname(c, fname, 1)) {
-               c = ast_channel_unref(c);
-               astman_send_error(s, m, "Could not change monitored filename of channel");
-               return AMI_SUCCESS;
-       }
-
-       c = ast_channel_unref(c);
-
-       astman_send_ack(s, m, "Changed monitor filename");
-
-       return AMI_SUCCESS;
-}
-
-void AST_OPTIONAL_API_NAME(ast_monitor_setjoinfiles)(struct ast_channel *chan, int turnon)
-{
-       if (ast_channel_monitor(chan))
-               ast_channel_monitor(chan)->joinfiles = turnon;
-}
-
-enum MONITOR_PAUSING_ACTION
-{
-       MONITOR_ACTION_PAUSE,
-       MONITOR_ACTION_UNPAUSE
-};
-
-static int do_pause_or_unpause(struct mansession *s, const struct message *m, int action)
-{
-       struct ast_channel *c = NULL;
-       const char *name = astman_get_header(m, "Channel");
-
-       if (ast_strlen_zero(name)) {
-               astman_send_error(s, m, "No channel specified");
-               return AMI_SUCCESS;
-       }
-
-       if (!(c = ast_channel_get_by_name(name))) {
-               astman_send_error(s, m, "No such channel");
-               return AMI_SUCCESS;
-       }
-
-       if (action == MONITOR_ACTION_PAUSE) {
-               ast_monitor_pause(c);
-       } else {
-               ast_monitor_unpause(c);
-       }
-
-       c = ast_channel_unref(c);
-
-       astman_send_ack(s, m, (action == MONITOR_ACTION_PAUSE ? "Paused monitoring of the channel" : "Unpaused monitoring of the channel"));
-
-       return AMI_SUCCESS;
-}
-
-static int pause_monitor_action(struct mansession *s, const struct message *m)
-{
-       return do_pause_or_unpause(s, m, MONITOR_ACTION_PAUSE);
-}
-
-static int unpause_monitor_action(struct mansession *s, const struct message *m)
-{
-       return do_pause_or_unpause(s, m, MONITOR_ACTION_UNPAUSE);
-}
-
-static int load_module(void)
-{
-       ast_register_application_xml("Monitor", start_monitor_exec);
-       ast_register_application_xml("StopMonitor", stop_monitor_exec);
-       ast_register_application_xml("ChangeMonitor", change_monitor_exec);
-       ast_register_application_xml("PauseMonitor", pause_monitor_exec);
-       ast_register_application_xml("UnpauseMonitor", unpause_monitor_exec);
-       ast_manager_register_xml("Monitor", EVENT_FLAG_CALL, start_monitor_action);
-       ast_manager_register_xml("StopMonitor", EVENT_FLAG_CALL, stop_monitor_action);
-       ast_manager_register_xml("ChangeMonitor", EVENT_FLAG_CALL, change_monitor_action);
-       ast_manager_register_xml("PauseMonitor", EVENT_FLAG_CALL, pause_monitor_action);
-       ast_manager_register_xml("UnpauseMonitor", EVENT_FLAG_CALL, unpause_monitor_action);
-
-       return AST_MODULE_LOAD_SUCCESS;
-}
-
-static int unload_module(void)
-{
-       ast_unregister_application("Monitor");
-       ast_unregister_application("StopMonitor");
-       ast_unregister_application("ChangeMonitor");
-       ast_unregister_application("PauseMonitor");
-       ast_unregister_application("UnpauseMonitor");
-       ast_manager_unregister("Monitor");
-       ast_manager_unregister("StopMonitor");
-       ast_manager_unregister("ChangeMonitor");
-       ast_manager_unregister("PauseMonitor");
-       ast_manager_unregister("UnpauseMonitor");
-
-       return 0;
-}
-
-/* usecount semantics need to be defined */
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER, "Call Monitoring Resource",
-       .support_level = AST_MODULE_SUPPORT_DEPRECATED,
-       .load = load_module,
-       .unload = unload_module,
-       .load_pri = AST_MODPRI_CHANNEL_DEPEND,
-       .optional_modules = "func_periodic_hook",
-);
diff --git a/res/res_monitor.exports.in b/res/res_monitor.exports.in
deleted file mode 100644 (file)
index 4a40724..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-{
-       global:
-               LINKER_SYMBOL_PREFIX*ast_monitor_change_fname;
-               LINKER_SYMBOL_PREFIX*ast_monitor_pause;
-               LINKER_SYMBOL_PREFIX*ast_monitor_setjoinfiles;
-               LINKER_SYMBOL_PREFIX*ast_monitor_start;
-               LINKER_SYMBOL_PREFIX*ast_monitor_stop;
-               LINKER_SYMBOL_PREFIX*ast_monitor_unpause;
-       local:
-               *;
-};