aboutsummaryrefslogtreecommitdiffstats
path: root/res
diff options
context:
space:
mode:
authormmichelson <mmichelson@f38db490-d61c-443f-a65b-d21fe96a405b>2007-11-30 21:19:57 +0000
committermmichelson <mmichelson@f38db490-d61c-443f-a65b-d21fe96a405b>2007-11-30 21:19:57 +0000
commita7c0447e636acec7aae62d8e86c490ccee1d678f (patch)
tree978560a7d79aeafa387c5164bc30cb9b72770980 /res
parent7cfa10f05b13911f3595a3db8b058ee587dfd8d5 (diff)
Adding support for the "automixmonitor" dial and queue options.
This works in much the same way as the automonitor, except that instead of using the monitor app, it uses the mixmonitor app. By providing an 'x' or 'X' as a dial or queue option, a DTMF sequence may be entered (as defined in features.conf) to start the one-touch mixmonitor. This patch also introduces some new API calls to the audiohooks code for searching for an audiohook by type and for searching for a running audiohook by type. Big thanks to joetester for writing the initial patch, testing it and patiently waiting for it to be committed. (closes issue #10185, reported and patched by xmarksthespot) git-svn-id: http://svn.digium.com/svn/asterisk/trunk@90388 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'res')
-rw-r--r--res/res_features.c120
1 files changed, 120 insertions, 0 deletions
diff --git a/res/res_features.c b/res/res_features.c
index b483dbb00..3deb1bc6a 100644
--- a/res/res_features.c
+++ b/res/res_features.c
@@ -50,6 +50,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/adsi.h"
#include "asterisk/devicestate.h"
#include "asterisk/monitor.h"
+#include "asterisk/audiohook.h"
#define DEFAULT_PARK_TIME 45000
#define DEFAULT_TRANSFER_DIGIT_TIMEOUT 3000
@@ -151,6 +152,12 @@ static char *descrip2 = "Park(): "
static struct ast_app *monitor_app = NULL;
static int monitor_ok = 1;
+static struct ast_app *mixmonitor_app = NULL;
+static int mixmonitor_ok = 1;
+
+static struct ast_app *stopmixmonitor_app = NULL;
+static int stopmixmonitor_ok = 1;
+
struct parkeduser {
struct ast_channel *chan; /*!< Parking channel */
struct timeval start; /*!< Time the parking started */
@@ -717,6 +724,118 @@ static int builtin_automonitor(struct ast_channel *chan, struct ast_channel *pee
return -1;
}
+static int builtin_automixmonitor(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense, void *data)
+{
+ char *caller_chan_id = NULL, *callee_chan_id = NULL, *args = NULL, *touch_filename = NULL;
+ int x = 0;
+ size_t len;
+ struct ast_channel *caller_chan, *callee_chan;
+ const char *mixmonitor_spy_type = "MixMonitor";
+ int count = 0;
+
+ if (!mixmonitor_ok) {
+ ast_log(LOG_ERROR,"Cannot record the call. The mixmonitor application is disabled.\n");
+ return -1;
+ }
+
+ if (!(mixmonitor_app = pbx_findapp("MixMonitor"))) {
+ mixmonitor_ok = 0;
+ ast_log(LOG_ERROR,"Cannot record the call. The mixmonitor application is disabled.\n");
+ return -1;
+ }
+
+ set_peers(&caller_chan, &callee_chan, peer, chan, sense);
+
+ if (!ast_strlen_zero(courtesytone)) {
+ if (ast_autoservice_start(callee_chan))
+ return -1;
+ if (ast_stream_and_wait(caller_chan, courtesytone, "")) {
+ ast_log(LOG_WARNING, "Failed to play courtesy tone!\n");
+ ast_autoservice_stop(callee_chan);
+ return -1;
+ }
+ if (ast_autoservice_stop(callee_chan))
+ return -1;
+ }
+
+ ast_channel_lock(callee_chan);
+ count = ast_channel_audiohook_count_by_source(callee_chan, mixmonitor_spy_type, AST_AUDIOHOOK_TYPE_SPY);
+ ast_channel_unlock(callee_chan);
+
+ // This means a mixmonitor is attached to the channel, running or not is unknown.
+ if (count > 0) {
+
+ if (option_verbose > 3)
+ ast_verbose(VERBOSE_PREFIX_3 "User hit '%s' to stop recording call.\n", code);
+
+ //Make sure they are running
+ ast_channel_lock(callee_chan);
+ count = ast_channel_audiohook_count_by_source_running(callee_chan, mixmonitor_spy_type, AST_AUDIOHOOK_TYPE_SPY);
+ ast_channel_unlock(callee_chan);
+ if (count > 0) {
+ if (!stopmixmonitor_ok) {
+ ast_log(LOG_ERROR,"Cannot stop recording the call. The stopmixmonitor application is disabled.\n");
+ return -1;
+ }
+ if (!(stopmixmonitor_app = pbx_findapp("StopMixMonitor"))) {
+ stopmixmonitor_ok = 0;
+ ast_log(LOG_ERROR,"Cannot stop recording the call. The stopmixmonitor application is disabled.\n");
+ return -1;
+ } else {
+ pbx_exec(callee_chan, stopmixmonitor_app, "");
+ return FEATURE_RETURN_SUCCESS;
+ }
+ }
+
+ ast_log(LOG_WARNING,"Stopped MixMonitors are attached to the channel.\n");
+ }
+
+ if (caller_chan && callee_chan) {
+ const char *touch_format = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MIXMONITOR_FORMAT");
+ const char *touch_monitor = pbx_builtin_getvar_helper(caller_chan, "TOUCH_MIXMONITOR");
+
+ if (!touch_format)
+ touch_format = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MIXMONITOR_FORMAT");
+
+ if (!touch_monitor)
+ touch_monitor = pbx_builtin_getvar_helper(callee_chan, "TOUCH_MIXMONITOR");
+
+ if (touch_monitor) {
+ len = strlen(touch_monitor) + 50;
+ args = alloca(len);
+ touch_filename = alloca(len);
+ snprintf(touch_filename, len, "auto-%ld-%s", (long)time(NULL), touch_monitor);
+ snprintf(args, len, "%s.%s,b", touch_filename, (touch_format) ? touch_format : "wav");
+ } else {
+ caller_chan_id = ast_strdupa(S_OR(caller_chan->cid.cid_num, caller_chan->name));
+ callee_chan_id = ast_strdupa(S_OR(callee_chan->cid.cid_num, callee_chan->name));
+ len = strlen(caller_chan_id) + strlen(callee_chan_id) + 50;
+ args = alloca(len);
+ touch_filename = alloca(len);
+ snprintf(touch_filename, len, "auto-%ld-%s-%s", (long)time(NULL), caller_chan_id, callee_chan_id);
+ snprintf(args, len, "%s.%s,b", touch_filename, S_OR(touch_format, "wav"));
+ }
+
+ for( x = 0; x < strlen(args); x++) {
+ if (args[x] == '/')
+ args[x] = '-';
+ }
+
+ if (option_verbose > 3)
+ ast_verbose(VERBOSE_PREFIX_3 "User hit '%s' to record call. filename: %s\n", code, touch_filename);
+
+ pbx_exec(callee_chan, mixmonitor_app, args);
+ pbx_builtin_setvar_helper(callee_chan, "TOUCH_MIXMONITOR_OUTPUT", touch_filename);
+ pbx_builtin_setvar_helper(caller_chan, "TOUCH_MIXMONITOR_OUTPUT", touch_filename);
+ return FEATURE_RETURN_SUCCESS;
+
+ }
+
+ ast_log(LOG_NOTICE,"Cannot record the call. One or both channels have gone away.\n");
+ return -1;
+
+}
+
static int builtin_disconnect(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense, void *data)
{
ast_verb(4, "User hit '%s' to disconnect call.\n", code);
@@ -1136,6 +1255,7 @@ static struct ast_call_feature builtin_features[] =
{ AST_FEATURE_AUTOMON, "One Touch Monitor", "automon", "", "", builtin_automonitor, AST_FEATURE_FLAG_NEEDSDTMF, "" },
{ AST_FEATURE_DISCONNECT, "Disconnect Call", "disconnect", "*", "*", builtin_disconnect, AST_FEATURE_FLAG_NEEDSDTMF, "" },
{ AST_FEATURE_PARKCALL, "Park Call", "parkcall", "", "", builtin_parkcall, AST_FEATURE_FLAG_NEEDSDTMF, "" },
+ { AST_FEATURE_AUTOMIXMON, "One Touch MixMonitor", "automixmon", "", "", builtin_automixmonitor, AST_FEATURE_FLAG_NEEDSDTMF, "" },
};