37 #include <sys/types.h>
50 #include "asterisk/features_config.h"
56 enum set_touch_variables_res {
59 SET_TOUCH_ALLOC_FAILURE,
62 static void set_touch_variable(
enum set_touch_variables_res *res,
struct ast_channel *chan,
const char *var_name,
char **touch)
66 if (*res == SET_TOUCH_ALLOC_FAILURE) {
70 if (!ast_strlen_zero(c_touch)) {
73 *res = SET_TOUCH_ALLOC_FAILURE;
75 *res = SET_TOUCH_SUCCESS;
80 static enum set_touch_variables_res set_touch_variables(
struct ast_channel *chan,
char **touch_format,
char **touch_monitor,
char **touch_monitor_prefix,
char **touch_monitor_beep)
82 enum set_touch_variables_res res = SET_TOUCH_UNSET;
83 const char *var_format;
84 const char *var_monitor;
85 const char *var_prefix;
90 var_format =
"TOUCH_MIXMONITOR_FORMAT";
91 var_monitor =
"TOUCH_MIXMONITOR";
92 var_prefix =
"TOUCH_MIXMONITOR_PREFIX";
93 var_beep =
"TOUCH_MIXMONITOR_BEEP";
95 set_touch_variable(&res, chan, var_format, touch_format);
96 set_touch_variable(&res, chan, var_monitor, touch_monitor);
97 set_touch_variable(&res, chan, var_prefix, touch_monitor_prefix);
98 set_touch_variable(&res, chan, var_beep, touch_monitor_beep);
106 ast_verb(4,
"AutoMixMonitor used to stop recording call.\n");
109 ast_verb(4,
"Failed to stop AutoMixMonitor for %s.\n", ast_channel_name(bridge_channel->
chan));
116 if (features_cfg && !ast_strlen_zero(features_cfg->
courtesytone)) {
121 if (!ast_strlen_zero(stop_message)) {
129 char *touch_filename, mix_options[32] =
"b";
132 enum set_touch_variables_res set_touch_res;
134 RAII_VAR(
char *, touch_format, NULL, ast_free);
135 RAII_VAR(
char *, touch_monitor, NULL, ast_free);
136 RAII_VAR(
char *, touch_monitor_prefix, NULL, ast_free);
137 RAII_VAR(
char *, touch_monitor_beep, NULL, ast_free);
139 set_touch_res = set_touch_variables(bridge_channel->
chan, &touch_format,
140 &touch_monitor, &touch_monitor_prefix, &touch_monitor_beep);
141 switch (set_touch_res) {
142 case SET_TOUCH_SUCCESS:
144 case SET_TOUCH_UNSET:
145 set_touch_res = set_touch_variables(peer_chan, &touch_format, &touch_monitor,
146 &touch_monitor_prefix, &touch_monitor_beep);
147 if (set_touch_res == SET_TOUCH_ALLOC_FAILURE) {
151 case SET_TOUCH_ALLOC_FAILURE:
155 if (!ast_strlen_zero(touch_monitor)) {
156 len = strlen(touch_monitor) + 50;
158 snprintf(touch_filename, len,
"%s-%ld-%s.%s",
159 S_OR(touch_monitor_prefix,
"auto"),
162 S_OR(touch_format,
"wav"));
164 char *caller_chan_id;
168 ast_channel_caller(bridge_channel->
chan)->
id.
number.
str, ast_channel_name(bridge_channel->
chan)));
170 ast_channel_caller(peer_chan)->
id.
number.str, ast_channel_name(peer_chan)));
171 len = strlen(caller_chan_id) + strlen(peer_chan_id) + 50;
173 snprintf(touch_filename, len,
"%s-%ld-%s-%s.%s",
174 S_OR(touch_monitor_prefix,
"auto"),
178 S_OR(touch_format,
"wav"));
181 for (x = 0; x < strlen(touch_filename); x++) {
182 if (touch_filename[x] ==
'/') {
183 touch_filename[x] =
'-';
187 ast_verb(4,
"AutoMixMonitor used to record call. Filename: %s\n", touch_filename);
189 if (!ast_strlen_zero(touch_monitor_beep)) {
190 unsigned int interval = 15;
191 if (sscanf(touch_monitor_beep,
"%30u", &interval) != 1) {
192 ast_log(LOG_WARNING,
"Invalid interval '%s' for periodic beep. Using default of %u\n",
193 touch_monitor_beep, interval);
198 ast_log(LOG_WARNING,
"Interval '%s' too small for periodic beep. Using minimum of %u\n",
199 touch_monitor_beep, interval);
201 snprintf(mix_options,
sizeof(mix_options),
"bB(%d)", interval);
205 ast_verb(4,
"AutoMixMonitor feature was tried by '%s' but MixMonitor failed to start.\n",
206 ast_channel_name(bridge_channel->
chan));
214 if (features_cfg && !ast_strlen_zero(features_cfg->
courtesytone)) {
219 if (!ast_strlen_zero(start_message)) {
228 static int feature_automixmonitor(
struct ast_bridge_channel *bridge_channel,
void *hook_pvt)
230 static const char *mixmonitor_spy_type =
"MixMonitor";
231 const char *stop_message;
232 const char *start_message;
240 ast_channel_lock(bridge_channel->
chan);
241 features_cfg = ast_get_chan_features_general_config(bridge_channel->
chan);
242 ast_channel_unlock(bridge_channel->
chan);
248 ast_verb(4,
"Cannot start AutoMixMonitor for %s - cannot determine peer in bridge.\n",
249 ast_channel_name(bridge_channel->
chan));
256 ast_channel_lock(bridge_channel->
chan);
258 "TOUCH_MIXMONITOR_MESSAGE_START");
261 "TOUCH_MIXMONITOR_MESSAGE_STOP");
263 ast_channel_unlock(bridge_channel->
chan);
267 switch (start_stop) {
270 stop_automixmonitor(bridge_channel, peer_chan, features_cfg, stop_message);
272 start_automixmonitor(bridge_channel, peer_chan, features_cfg, start_message);
276 if (!is_monitoring) {
277 start_automixmonitor(bridge_channel, peer_chan, features_cfg, start_message);
280 ast_verb(4,
"AutoMixMonitor already recording call.\n");
284 stop_automixmonitor(bridge_channel, peer_chan, features_cfg, stop_message);
287 ast_verb(4,
"AutoMixMonitor already stopped on call.\n");
295 if (features_cfg && !ast_strlen_zero(features_cfg->
courtesytone)) {
299 if (!ast_strlen_zero(start_message)) {
303 if (!ast_strlen_zero(stop_message)) {
319 AST_CAUSE_NORMAL_CLEARING);
323 static int unload_module(
void)
331 static int load_module(
void)
342 AST_MODULE_INFO(
ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT,
"Built in bridging features",
343 .support_level = AST_MODULE_SUPPORT_CORE,
345 .unload = unload_module,
Main Channel structure associated with a channel.
char * str
Subscriber phone number (Malloced)
Asterisk main include file. File version handling, generic pbx functions.
struct ast_channel * ast_bridge_peer_nolock(struct ast_bridge *bridge, struct ast_channel *chan)
Get the channel's bridge peer only if the bridge is two-party.
General features configuration items.
ast_bridge_features_monitor
int ast_start_mixmonitor(struct ast_channel *chan, const char *filename, const char *options)
Start a mixmonitor on a channel with the given parameters.
#define ast_strdup(str)
A wrapper for strdup()
Generic File Format Support. Should be included by clients of the file handling routines. File service providers should instead include mod_format.h.
Periodic beeps into the audio of a call.
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
struct ast_bridge * bridge
Bridge this channel is participating in.
int ast_bridge_features_unregister(enum ast_bridge_builtin_feature feature)
Unregister a handler for a built in feature.
const ast_string_field courtesytone
struct ast_party_id id
Caller party ID.
int ast_channel_audiohook_count_by_source(struct ast_channel *chan, const char *source, enum ast_audiohook_type type)
Find out how many audiohooks from a certain source exist on a given channel, regardless of status...
#define SCOPED_CHANNELLOCK(varname, chan)
scoped lock specialization for channels.
General Asterisk PBX channel definitions.
static int feature_hangup(struct ast_bridge_channel *bridge_channel, void *hook_pvt)
Internal built in feature for hangup.
#define ast_strdupa(s)
duplicate a string in memory from the stack
#define ast_channel_cleanup(c)
Cleanup a channel reference.
Asterisk internal frame definitions.
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Core PBX routines and definitions.
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
int ast_bridge_channel_write_playfile(struct ast_bridge_channel *bridge_channel, ast_bridge_custom_play_fn custom_play, const char *playfile, const char *moh_class)
Write a bridge action play file frame into the bridge.
int ast_stop_mixmonitor(struct ast_channel *chan, const char *mixmon_id)
Stop a mixmonitor on a channel with the given parameters.
#define ast_module_shutdown_ref(mod)
Prevent unload of the module before shutdown.
int ast_bridge_features_register(enum ast_bridge_builtin_feature feature, ast_bridge_hook_callback callback, const char *dtmf)
Register a handler for a built in feature.
void ast_bridge_channel_leave_bridge(struct ast_bridge_channel *bridge_channel, enum bridge_channel_state new_state, int cause)
Set bridge channel state to leave bridge (if not leaving already).
#define ast_bridge_unlock(bridge)
Unlock the bridge.
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
const ast_string_field recordingfailsound
struct ast_channel * chan
Structure that contains information regarding a channel in a bridge.
void ast_bridge_channel_lock_bridge(struct ast_bridge_channel *bridge_channel)
Lock the bridge associated with the bridge channel.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
int ast_bridge_channel_queue_playfile(struct ast_bridge_channel *bridge_channel, ast_bridge_custom_play_fn custom_play, const char *playfile, const char *moh_class)
Queue a bridge action play file frame onto the bridge channel.
Internal Asterisk hangup causes.
loadable MixMonitor functionality
#define ASTERISK_GPL_KEY
The text the key() function should return.
Asterisk module definitions.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
enum ast_bridge_features_monitor start_stop
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
unsigned char valid
TRUE if the number information is valid/present.
struct ast_party_number number
Subscriber phone number.