aboutsummaryrefslogtreecommitdiffstats
path: root/res/res_features.c
diff options
context:
space:
mode:
Diffstat (limited to 'res/res_features.c')
-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, "" },
};