diff --git a/bridges/bridge_builtin_features.c b/bridges/bridge_builtin_features.c index 671cfb9385..9f8143e455 100644 --- a/bridges/bridge_builtin_features.c +++ b/bridges/bridge_builtin_features.c @@ -53,6 +53,7 @@ #include "asterisk/mixmonitor.h" #include "asterisk/audiohook.h" #include "asterisk/causes.h" +#include "asterisk/beep.h" enum set_touch_variables_res { SET_TOUCH_SUCCESS, @@ -78,12 +79,13 @@ 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, int is_mixmonitor, char **touch_format, char **touch_monitor, char **touch_monitor_prefix, char **touch_monitor_beep) { enum set_touch_variables_res res = SET_TOUCH_UNSET; const char *var_format; const char *var_monitor; const char *var_prefix; + const char *var_beep; SCOPED_CHANNELLOCK(lock, chan); @@ -91,14 +93,17 @@ static enum set_touch_variables_res set_touch_variables(struct ast_channel *chan var_format = "TOUCH_MIXMONITOR_FORMAT"; var_monitor = "TOUCH_MIXMONITOR"; var_prefix = "TOUCH_MIXMONITOR_PREFIX"; + var_beep = "TOUCH_MIXMONITOR_BEEP"; } else { var_format = "TOUCH_MONITOR_FORMAT"; var_monitor = "TOUCH_MONITOR"; var_prefix = "TOUCH_MONITOR_PREFIX"; + var_beep = "TOUCH_MONITOR_BEEP"; } 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); + set_touch_variable(&res, chan, var_beep, touch_monitor_beep); return res; } @@ -141,20 +146,22 @@ static void start_automonitor(struct ast_bridge_channel *bridge_channel, struct char *touch_filename; size_t len; int x; + char beep_id[64] = ""; 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); + RAII_VAR(char *, touch_monitor_beep, NULL, ast_free); set_touch_res = set_touch_variables(bridge_channel->chan, 0, &touch_format, - &touch_monitor, &touch_monitor_prefix); + &touch_monitor, &touch_monitor_prefix, &touch_monitor_beep); 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); + &touch_monitor_prefix, &touch_monitor_beep); if (set_touch_res == SET_TOUCH_ALLOC_FAILURE) { return; } @@ -195,7 +202,28 @@ static void start_automonitor(struct ast_bridge_channel *bridge_channel, struct 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)) { + if (!ast_strlen_zero(touch_monitor_beep)) { + unsigned int interval = 15; + if (sscanf(touch_monitor_beep, "%30u", &interval) != 1) { + ast_log(LOG_WARNING, "Invalid interval '%s' for periodic beep. Using default of %u\n", + touch_monitor_beep, interval); + } + + if (interval > 0) { + if (interval < 5) { + interval = 5; + ast_log(LOG_WARNING, "Interval '%s' too small for periodic beep. Using minimum of %u\n", + touch_monitor_beep, interval); + } + + if (ast_beep_start(peer_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; + } + } + } + + if (ast_monitor_start(peer_chan, touch_format, touch_filename, 1, X_REC_IN | X_REC_OUT, beep_id)) { ast_verb(4, "AutoMonitor feature was tried by '%s' but monitor failed to start.\n", ast_channel_name(bridge_channel->chan)); return; @@ -322,7 +350,7 @@ static void stop_automixmonitor(struct ast_bridge_channel *bridge_channel, struc static void start_automixmonitor(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; + char *touch_filename, mix_options[32] = "b"; size_t len; int x; enum set_touch_variables_res set_touch_res; @@ -330,15 +358,16 @@ static void start_automixmonitor(struct ast_bridge_channel *bridge_channel, stru 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); + RAII_VAR(char *, touch_monitor_beep, NULL, ast_free); set_touch_res = set_touch_variables(bridge_channel->chan, 1, &touch_format, - &touch_monitor, &touch_monitor_prefix); + &touch_monitor, &touch_monitor_prefix, &touch_monitor_beep); 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, - &touch_monitor_prefix); + &touch_monitor_prefix, &touch_monitor_beep); if (set_touch_res == SET_TOUCH_ALLOC_FAILURE) { return; } @@ -381,7 +410,22 @@ static void start_automixmonitor(struct ast_bridge_channel *bridge_channel, stru ast_verb(4, "AutoMixMonitor used to record call. Filename: %s\n", touch_filename); - if (ast_start_mixmonitor(peer_chan, touch_filename, "b")) { + if (!ast_strlen_zero(touch_monitor_beep)) { + unsigned int interval = 15; + if (sscanf(touch_monitor_beep, "%30u", &interval) != 1) { + ast_log(LOG_WARNING, "Invalid interval '%s' for periodic beep. Using default of %u\n", + touch_monitor_beep, interval); + } + + if (interval < 5) { + interval = 5; + ast_log(LOG_WARNING, "Interval '%s' too small for periodic beep. Using minimum of %u\n", + touch_monitor_beep, interval); + } + snprintf(mix_options, sizeof(mix_options), "bB(%d)", interval); + } + + if (ast_start_mixmonitor(peer_chan, touch_filename, mix_options)) { ast_verb(4, "AutoMixMonitor feature was tried by '%s' but MixMonitor failed to start.\n", ast_channel_name(bridge_channel->chan)); diff --git a/doc/CHANGES-staging/bridge_builtin_features_beep_on_monitor.txt b/doc/CHANGES-staging/bridge_builtin_features_beep_on_monitor.txt new file mode 100644 index 0000000000..39bf9a72c0 --- /dev/null +++ b/doc/CHANGES-staging/bridge_builtin_features_beep_on_monitor.txt @@ -0,0 +1,12 @@ +Subject: bridge_builtin_features + +Add optional touch variable : TOUCH_MIXMONITOR_BEEP(interval) + +Setting TOUCH_MIXMONITOR_BEEP/TOUCH_MONITOR_BEEP to a valid +interval in seconds will result in a periodic beep being +played to the monitored channel upon MixMontior/Monitor +feature start. + +If an interval less than 5 seconds is specified, the interval +will default to 5 seconds. If the value is set to an invalid +interval, the default of 15 seconds will be used. diff --git a/funcs/func_periodic_hook.c b/funcs/func_periodic_hook.c index 3c7b93e6a7..ec4b9ba4de 100644 --- a/funcs/func_periodic_hook.c +++ b/funcs/func_periodic_hook.c @@ -40,6 +40,7 @@ #include "asterisk/pbx.h" #include "asterisk/app.h" #include "asterisk/audiohook.h" +#include "asterisk/test.h" #define AST_API_MODULE #include "asterisk/beep.h" @@ -343,6 +344,8 @@ static int hook_on(struct ast_channel *chan, const char *data, unsigned int hook ast_debug(1, "hook to %s@%s enabled on %s with interval of %u seconds\n", args.exten, args.context, ast_channel_name(chan), interval); + ast_test_suite_event_notify("PERIODIC_HOOK_ENABLED", "Exten: %s\r\nChannel: %s\r\nInterval: %u\r\n", + args.exten, ast_channel_name(chan), interval); return init_hook(chan, args.context, args.exten, interval, hook_id); } diff --git a/main/features_config.c b/main/features_config.c index ba2f905003..97ace55f41 100644 --- a/main/features_config.c +++ b/main/features_config.c @@ -199,6 +199,9 @@ channel variable or auto if the variable is not set. The timestamp is a UNIX timestamp. The suffix is either the value of the TOUCH_MONITOR channel variable or the callerID of the channels if the variable is not set. + To play a periodic beep while this call is being recorded, set the + TOUCH_MONITOR_BEEP to the interval in seconds. The interval will default + to 15 seconds if invalid. The minimum interval is 5 seconds. automixmon @@ -215,6 +218,9 @@ channel variable or auto if the variable is not set. The timestamp is a UNIX timestamp. The suffix is either the value of the TOUCH_MIXMONITOR channel variable or the callerID of the channels if the variable is not set. + To play a periodic beep while this call is being recorded, set the + TOUCH_MIXMONITOR_BEEP to the interval in seconds. The interval will default + to 15 seconds if invalid. The minimum interval is 5 seconds. automon