diff options
Diffstat (limited to 'res/res_features.c')
-rw-r--r-- | res/res_features.c | 120 |
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, "" }, }; |