Asterisk - The Open Source Telephony Project  18.5.0
Enumerations | Functions | Variables
bridge_builtin_features.c File Reference

Built in bridging features. More...

#include "asterisk.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "asterisk/module.h"
#include "asterisk/channel.h"
#include "asterisk/bridge.h"
#include "asterisk/bridge_technology.h"
#include "asterisk/frame.h"
#include "asterisk/file.h"
#include "asterisk/app.h"
#include "asterisk/astobj2.h"
#include "asterisk/pbx.h"
#include "asterisk/parking.h"
#include "asterisk/features_config.h"
#include "asterisk/monitor.h"
#include "asterisk/mixmonitor.h"
#include "asterisk/audiohook.h"
#include "asterisk/causes.h"
Include dependency graph for bridge_builtin_features.c:

Go to the source code of this file.

Enumerations

enum  set_touch_variables_res { SET_TOUCH_SUCCESS, SET_TOUCH_UNSET, SET_TOUCH_ALLOC_FAILURE }
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static int feature_automixmonitor (struct ast_bridge_channel *bridge_channel, void *hook_pvt)
 
static int feature_automonitor (struct ast_bridge_channel *bridge_channel, void *hook_pvt)
 
static int feature_hangup (struct ast_bridge_channel *bridge_channel, void *hook_pvt)
 Internal built in feature for hangup. More...
 
static int load_module (void)
 
static void set_touch_variable (enum set_touch_variables_res *res, struct ast_channel *chan, const char *var_name, char **touch)
 
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 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)
 
static void start_automonitor (struct ast_bridge_channel *bridge_channel, struct ast_channel *peer_chan, struct ast_features_general_config *features_cfg, const char *start_message)
 
static void stop_automixmonitor (struct ast_bridge_channel *bridge_channel, struct ast_channel *peer_chan, struct ast_features_general_config *features_cfg, const char *stop_message)
 
static void stop_automonitor (struct ast_bridge_channel *bridge_channel, struct ast_channel *peer_chan, struct ast_features_general_config *features_cfg, const char *stop_message)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Built in bridging features" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "30ef0c93b36035ec78c9cfd712d36d9b" , .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .optional_modules = "res_monitor", }
 
static const struct ast_module_infoast_module_info = &__mod_info
 

Detailed Description

Built in bridging features.

Author
Joshua Colp jcolp.nosp@m.@dig.nosp@m.ium.c.nosp@m.om

Definition in file bridge_builtin_features.c.

Enumeration Type Documentation

◆ set_touch_variables_res

Enumerator
SET_TOUCH_SUCCESS 
SET_TOUCH_UNSET 
SET_TOUCH_ALLOC_FAILURE 

Definition at line 57 of file bridge_builtin_features.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 529 of file bridge_builtin_features.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 529 of file bridge_builtin_features.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 529 of file bridge_builtin_features.c.

◆ feature_automixmonitor()

static int feature_automixmonitor ( struct ast_bridge_channel bridge_channel,
void *  hook_pvt 
)
static

Definition at line 408 of file bridge_builtin_features.c.

References ao2_cleanup, AST_AUDIOHOOK_TYPE_SPY, ast_bridge_channel_lock_bridge(), ast_bridge_channel_queue_playfile(), ast_bridge_peer_nolock(), ast_bridge_unlock, ast_channel_audiohook_count_by_source(), ast_channel_cleanup, ast_channel_lock, ast_channel_name(), ast_channel_unlock, ast_get_chan_features_general_config(), ast_strdupa, ast_strlen_zero, ast_verb, AUTO_MONITOR_START, AUTO_MONITOR_STOP, AUTO_MONITOR_TOGGLE, ast_bridge_channel::bridge, ast_bridge_channel::chan, mixmonitor_spy_type, NULL, options, pbx_builtin_getvar_helper(), RAII_VAR, S_OR, start_automixmonitor(), ast_bridge_features_automixmonitor::start_stop, and stop_automixmonitor().

Referenced by load_module().

409 {
410  static const char *mixmonitor_spy_type = "MixMonitor";
411  const char *stop_message;
412  const char *start_message;
413  struct ast_bridge_features_automixmonitor *options = hook_pvt;
415  int is_monitoring;
416 
417  RAII_VAR(struct ast_channel *, peer_chan, NULL, ast_channel_cleanup);
418  RAII_VAR(struct ast_features_general_config *, features_cfg, NULL, ao2_cleanup);
419 
420  ast_channel_lock(bridge_channel->chan);
421  features_cfg = ast_get_chan_features_general_config(bridge_channel->chan);
422  ast_channel_unlock(bridge_channel->chan);
423  ast_bridge_channel_lock_bridge(bridge_channel);
424  peer_chan = ast_bridge_peer_nolock(bridge_channel->bridge, bridge_channel->chan);
425  ast_bridge_unlock(bridge_channel->bridge);
426 
427  if (!peer_chan) {
428  ast_verb(4, "Cannot start AutoMixMonitor for %s - cannot determine peer in bridge.\n",
429  ast_channel_name(bridge_channel->chan));
430  if (features_cfg && !ast_strlen_zero(features_cfg->recordingfailsound)) {
431  ast_bridge_channel_queue_playfile(bridge_channel, NULL, features_cfg->recordingfailsound, NULL);
432  }
433  return 0;
434  }
435 
436  ast_channel_lock(bridge_channel->chan);
437  start_message = pbx_builtin_getvar_helper(bridge_channel->chan,
438  "TOUCH_MIXMONITOR_MESSAGE_START");
439  start_message = ast_strdupa(S_OR(start_message, ""));
440  stop_message = pbx_builtin_getvar_helper(bridge_channel->chan,
441  "TOUCH_MIXMONITOR_MESSAGE_STOP");
442  stop_message = ast_strdupa(S_OR(stop_message, ""));
443  ast_channel_unlock(bridge_channel->chan);
444 
445  is_monitoring =
446  0 < ast_channel_audiohook_count_by_source(peer_chan, mixmonitor_spy_type, AST_AUDIOHOOK_TYPE_SPY);
447  switch (start_stop) {
448  case AUTO_MONITOR_TOGGLE:
449  if (is_monitoring) {
450  stop_automixmonitor(bridge_channel, peer_chan, features_cfg, stop_message);
451  } else {
452  start_automixmonitor(bridge_channel, peer_chan, features_cfg, start_message);
453  }
454  return 0;
455  case AUTO_MONITOR_START:
456  if (!is_monitoring) {
457  start_automixmonitor(bridge_channel, peer_chan, features_cfg, start_message);
458  return 0;
459  }
460  ast_verb(4, "AutoMixMonitor already recording call.\n");
461  break;
462  case AUTO_MONITOR_STOP:
463  if (is_monitoring) {
464  stop_automixmonitor(bridge_channel, peer_chan, features_cfg, stop_message);
465  return 0;
466  }
467  ast_verb(4, "AutoMixMonitor already stopped on call.\n");
468  break;
469  }
470 
471  /*
472  * Fake start/stop to invoker so will think it did something but
473  * was already in that mode.
474  */
475  if (features_cfg && !ast_strlen_zero(features_cfg->courtesytone)) {
476  ast_bridge_channel_queue_playfile(bridge_channel, NULL, features_cfg->courtesytone, NULL);
477  }
478  if (is_monitoring) {
479  if (!ast_strlen_zero(start_message)) {
480  ast_bridge_channel_queue_playfile(bridge_channel, NULL, start_message, NULL);
481  }
482  } else {
483  if (!ast_strlen_zero(stop_message)) {
484  ast_bridge_channel_queue_playfile(bridge_channel, NULL, stop_message, NULL);
485  }
486  }
487  return 0;
488 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
Main Channel structure associated with a channel.
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)
struct ast_channel * ast_bridge_peer_nolock(struct ast_bridge *bridge, struct ast_channel *chan)
Get the channel&#39;s bridge peer only if the bridge is two-party.
Definition: bridge.c:4114
General features configuration items.
ast_bridge_features_monitor
#define NULL
Definition: resample.c:96
#define ast_verb(level,...)
Definition: logger.h:463
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.
#define ast_strlen_zero(foo)
Definition: strings.h:52
struct ast_features_general_config * ast_get_chan_features_general_config(struct ast_channel *chan)
Get the general configuration options for a channel.
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...
Definition: audiohook.c:1157
static const char *const mixmonitor_spy_type
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
#define ast_channel_cleanup(c)
Cleanup a channel reference.
Definition: channel.h:2992
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
static void stop_automixmonitor(struct ast_bridge_channel *bridge_channel, struct ast_channel *peer_chan, struct ast_features_general_config *features_cfg, const char *stop_message)
struct ast_channel * chan
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
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...
Definition: strings.h:79
const char * ast_channel_name(const struct ast_channel *chan)
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.
static struct test_options options
enum ast_bridge_features_monitor start_stop

◆ feature_automonitor()

static int feature_automonitor ( struct ast_bridge_channel bridge_channel,
void *  hook_pvt 
)
static

Definition at line 220 of file bridge_builtin_features.c.

References ao2_cleanup, ast_bridge_channel_lock_bridge(), ast_bridge_channel_queue_playfile(), ast_bridge_peer_nolock(), ast_bridge_unlock, ast_channel_cleanup, ast_channel_lock, ast_channel_monitor(), ast_channel_name(), ast_channel_unlock, ast_get_chan_features_general_config(), ast_strdupa, ast_strlen_zero, ast_verb, AUTO_MONITOR_START, AUTO_MONITOR_STOP, AUTO_MONITOR_TOGGLE, ast_bridge_channel::bridge, ast_bridge_channel::chan, NULL, options, pbx_builtin_getvar_helper(), RAII_VAR, S_OR, start_automonitor(), ast_bridge_features_automonitor::start_stop, and stop_automonitor().

Referenced by load_module().

221 {
222  const char *start_message;
223  const char *stop_message;
224  struct ast_bridge_features_automonitor *options = hook_pvt;
226  int is_monitoring;
227 
228  RAII_VAR(struct ast_channel *, peer_chan, NULL, ast_channel_cleanup);
229  RAII_VAR(struct ast_features_general_config *, features_cfg, NULL, ao2_cleanup);
230 
231  ast_channel_lock(bridge_channel->chan);
232  features_cfg = ast_get_chan_features_general_config(bridge_channel->chan);
233  ast_channel_unlock(bridge_channel->chan);
234  ast_bridge_channel_lock_bridge(bridge_channel);
235  peer_chan = ast_bridge_peer_nolock(bridge_channel->bridge, bridge_channel->chan);
236  ast_bridge_unlock(bridge_channel->bridge);
237 
238  if (!peer_chan) {
239  ast_verb(4, "Cannot start AutoMonitor for %s - can not determine peer in bridge.\n",
240  ast_channel_name(bridge_channel->chan));
241  if (features_cfg && !ast_strlen_zero(features_cfg->recordingfailsound)) {
242  ast_bridge_channel_queue_playfile(bridge_channel, NULL, features_cfg->recordingfailsound, NULL);
243  }
244  return 0;
245  }
246 
247  ast_channel_lock(bridge_channel->chan);
248  start_message = pbx_builtin_getvar_helper(bridge_channel->chan,
249  "TOUCH_MONITOR_MESSAGE_START");
250  start_message = ast_strdupa(S_OR(start_message, ""));
251  stop_message = pbx_builtin_getvar_helper(bridge_channel->chan,
252  "TOUCH_MONITOR_MESSAGE_STOP");
253  stop_message = ast_strdupa(S_OR(stop_message, ""));
254  ast_channel_unlock(bridge_channel->chan);
255 
256  is_monitoring = ast_channel_monitor(peer_chan) != NULL;
257  switch (start_stop) {
258  case AUTO_MONITOR_TOGGLE:
259  if (is_monitoring) {
260  stop_automonitor(bridge_channel, peer_chan, features_cfg, stop_message);
261  } else {
262  start_automonitor(bridge_channel, peer_chan, features_cfg, start_message);
263  }
264  return 0;
265  case AUTO_MONITOR_START:
266  if (!is_monitoring) {
267  start_automonitor(bridge_channel, peer_chan, features_cfg, start_message);
268  return 0;
269  }
270  ast_verb(4, "AutoMonitor already recording call.\n");
271  break;
272  case AUTO_MONITOR_STOP:
273  if (is_monitoring) {
274  stop_automonitor(bridge_channel, peer_chan, features_cfg, stop_message);
275  return 0;
276  }
277  ast_verb(4, "AutoMonitor already stopped on call.\n");
278  break;
279  }
280 
281  /*
282  * Fake start/stop to invoker so will think it did something but
283  * was already in that mode.
284  */
285  if (features_cfg && !ast_strlen_zero(features_cfg->courtesytone)) {
286  ast_bridge_channel_queue_playfile(bridge_channel, NULL, features_cfg->courtesytone, NULL);
287  }
288  if (is_monitoring) {
289  if (!ast_strlen_zero(start_message)) {
290  ast_bridge_channel_queue_playfile(bridge_channel, NULL, start_message, NULL);
291  }
292  } else {
293  if (!ast_strlen_zero(stop_message)) {
294  ast_bridge_channel_queue_playfile(bridge_channel, NULL, stop_message, NULL);
295  }
296  }
297  return 0;
298 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
Main Channel structure associated with a channel.
enum ast_bridge_features_monitor start_stop
struct ast_channel * ast_bridge_peer_nolock(struct ast_bridge *bridge, struct ast_channel *chan)
Get the channel&#39;s bridge peer only if the bridge is two-party.
Definition: bridge.c:4114
General features configuration items.
ast_bridge_features_monitor
#define NULL
Definition: resample.c:96
#define ast_verb(level,...)
Definition: logger.h:463
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.
#define ast_strlen_zero(foo)
Definition: strings.h:52
struct ast_features_general_config * ast_get_chan_features_general_config(struct ast_channel *chan)
Get the general configuration options for a channel.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
#define ast_channel_cleanup(c)
Cleanup a channel reference.
Definition: channel.h:2992
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
struct ast_channel * chan
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
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...
Definition: strings.h:79
const char * ast_channel_name(const struct ast_channel *chan)
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.
static void stop_automonitor(struct ast_bridge_channel *bridge_channel, struct ast_channel *peer_chan, struct ast_features_general_config *features_cfg, const char *stop_message)
static struct test_options options
struct ast_channel_monitor * ast_channel_monitor(const struct ast_channel *chan)
static void start_automonitor(struct ast_bridge_channel *bridge_channel, struct ast_channel *peer_chan, struct ast_features_general_config *features_cfg, const char *start_message)

◆ feature_hangup()

static int feature_hangup ( struct ast_bridge_channel bridge_channel,
void *  hook_pvt 
)
static

Internal built in feature for hangup.

Definition at line 491 of file bridge_builtin_features.c.

References ast_bridge_channel_leave_bridge(), AST_CAUSE_NORMAL_CLEARING, and BRIDGE_CHANNEL_STATE_END.

Referenced by load_module().

492 {
493  /*
494  * This is very simple, we simply change the state on the
495  * bridge_channel to force the channel out of the bridge and the
496  * core takes care of the rest.
497  */
500  return 0;
501 }
#define AST_CAUSE_NORMAL_CLEARING
Definition: causes.h:105
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).

◆ load_module()

static int load_module ( void  )
static

Definition at line 512 of file bridge_builtin_features.c.

References AST_BRIDGE_BUILTIN_AUTOMIXMON, AST_BRIDGE_BUILTIN_AUTOMON, AST_BRIDGE_BUILTIN_HANGUP, ast_bridge_features_register(), AST_MODFLAG_DEFAULT, AST_MODULE_INFO(), AST_MODULE_LOAD_SUCCESS, ast_module_shutdown_ref, AST_MODULE_SUPPORT_CORE, ASTERISK_GPL_KEY, feature_automixmonitor(), feature_automonitor(), feature_hangup(), NULL, ast_module_info::self, and unload_module().

513 {
517 
518  /* This module cannot be unloaded until shutdown */
520 
522 }
#define NULL
Definition: resample.c:96
struct ast_module * self
Definition: module.h:342
static int feature_hangup(struct ast_bridge_channel *bridge_channel, void *hook_pvt)
Internal built in feature for hangup.
#define ast_module_shutdown_ref(mod)
Prevent unload of the module before shutdown.
Definition: module.h:464
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.
Definition: bridge.c:3123
static int feature_automixmonitor(struct ast_bridge_channel *bridge_channel, void *hook_pvt)
static int feature_automonitor(struct ast_bridge_channel *bridge_channel, void *hook_pvt)

◆ set_touch_variable()

static void set_touch_variable ( enum set_touch_variables_res res,
struct ast_channel chan,
const char *  var_name,
char **  touch 
)
static

Definition at line 63 of file bridge_builtin_features.c.

References ast_strdup, ast_strlen_zero, pbx_builtin_getvar_helper(), SET_TOUCH_ALLOC_FAILURE, and SET_TOUCH_SUCCESS.

Referenced by set_touch_variables().

64 {
65  const char *c_touch;
66 
67  if (*res == SET_TOUCH_ALLOC_FAILURE) {
68  return;
69  }
70  c_touch = pbx_builtin_getvar_helper(chan, var_name);
71  if (!ast_strlen_zero(c_touch)) {
72  *touch = ast_strdup(c_touch);
73  if (!*touch) {
75  } else {
76  *res = SET_TOUCH_SUCCESS;
77  }
78  }
79 }
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
#define ast_strlen_zero(foo)
Definition: strings.h:52

◆ set_touch_variables()

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

Definition at line 81 of file bridge_builtin_features.c.

References lock, SCOPED_CHANNELLOCK, SET_TOUCH_UNSET, and set_touch_variable().

Referenced by start_automixmonitor(), and start_automonitor().

82 {
84  const char *var_format;
85  const char *var_monitor;
86  const char *var_prefix;
87 
88  SCOPED_CHANNELLOCK(lock, chan);
89 
90  if (is_mixmonitor) {
91  var_format = "TOUCH_MIXMONITOR_FORMAT";
92  var_monitor = "TOUCH_MIXMONITOR";
93  var_prefix = "TOUCH_MIXMONITOR_PREFIX";
94  } else {
95  var_format = "TOUCH_MONITOR_FORMAT";
96  var_monitor = "TOUCH_MONITOR";
97  var_prefix = "TOUCH_MONITOR_PREFIX";
98  }
99  set_touch_variable(&res, chan, var_format, touch_format);
100  set_touch_variable(&res, chan, var_monitor, touch_monitor);
101  set_touch_variable(&res, chan, var_prefix, touch_monitor_prefix);
102 
103  return res;
104 }
static void set_touch_variable(enum set_touch_variables_res *res, struct ast_channel *chan, const char *var_name, char **touch)
#define SCOPED_CHANNELLOCK(varname, chan)
scoped lock specialization for channels.
Definition: lock.h:617
ast_mutex_t lock
Definition: app_meetme.c:1091
set_touch_variables_res

◆ start_automixmonitor()

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 
)
static

Definition at line 323 of file bridge_builtin_features.c.

References ast_alloca, ast_bridge_channel_queue_playfile(), ast_bridge_channel_write_playfile(), ast_channel_caller(), ast_channel_name(), ast_free, ast_start_mixmonitor(), ast_strdupa, ast_strlen_zero, ast_verb, ast_bridge_channel::chan, ast_features_general_config::courtesytone, ast_party_caller::id, len(), NULL, ast_party_id::number, pbx_builtin_setvar_helper(), RAII_VAR, ast_features_general_config::recordingfailsound, S_COR, S_OR, SET_TOUCH_ALLOC_FAILURE, SET_TOUCH_SUCCESS, SET_TOUCH_UNSET, set_touch_variables(), ast_party_number::str, and ast_party_number::valid.

Referenced by feature_automixmonitor().

324 {
325  char *touch_filename;
326  size_t len;
327  int x;
328  enum set_touch_variables_res set_touch_res;
329 
330  RAII_VAR(char *, touch_format, NULL, ast_free);
331  RAII_VAR(char *, touch_monitor, NULL, ast_free);
332  RAII_VAR(char *, touch_monitor_prefix, NULL, ast_free);
333 
334  set_touch_res = set_touch_variables(bridge_channel->chan, 1, &touch_format,
335  &touch_monitor, &touch_monitor_prefix);
336  switch (set_touch_res) {
337  case SET_TOUCH_SUCCESS:
338  break;
339  case SET_TOUCH_UNSET:
340  set_touch_res = set_touch_variables(peer_chan, 1, &touch_format, &touch_monitor,
341  &touch_monitor_prefix);
342  if (set_touch_res == SET_TOUCH_ALLOC_FAILURE) {
343  return;
344  }
345  break;
347  return;
348  }
349 
350  if (!ast_strlen_zero(touch_monitor)) {
351  len = strlen(touch_monitor) + 50;
352  touch_filename = ast_alloca(len);
353  snprintf(touch_filename, len, "%s-%ld-%s.%s",
354  S_OR(touch_monitor_prefix, "auto"),
355  (long) time(NULL),
356  touch_monitor,
357  S_OR(touch_format, "wav"));
358  } else {
359  char *caller_chan_id;
360  char *peer_chan_id;
361 
362  caller_chan_id = ast_strdupa(S_COR(ast_channel_caller(bridge_channel->chan)->id.number.valid,
363  ast_channel_caller(bridge_channel->chan)->id.number.str, ast_channel_name(bridge_channel->chan)));
364  peer_chan_id = ast_strdupa(S_COR(ast_channel_caller(peer_chan)->id.number.valid,
365  ast_channel_caller(peer_chan)->id.number.str, ast_channel_name(peer_chan)));
366  len = strlen(caller_chan_id) + strlen(peer_chan_id) + 50;
367  touch_filename = ast_alloca(len);
368  snprintf(touch_filename, len, "%s-%ld-%s-%s.%s",
369  S_OR(touch_monitor_prefix, "auto"),
370  (long) time(NULL),
371  caller_chan_id,
372  peer_chan_id,
373  S_OR(touch_format, "wav"));
374  }
375 
376  for (x = 0; x < strlen(touch_filename); x++) {
377  if (touch_filename[x] == '/') {
378  touch_filename[x] = '-';
379  }
380  }
381 
382  ast_verb(4, "AutoMixMonitor used to record call. Filename: %s\n", touch_filename);
383 
384  if (ast_start_mixmonitor(peer_chan, touch_filename, "b")) {
385  ast_verb(4, "AutoMixMonitor feature was tried by '%s' but MixMonitor failed to start.\n",
386  ast_channel_name(bridge_channel->chan));
387 
388  if (features_cfg && !ast_strlen_zero(features_cfg->recordingfailsound)) {
389  ast_bridge_channel_queue_playfile(bridge_channel, NULL, features_cfg->recordingfailsound, NULL);
390  }
391  return;
392  }
393 
394  if (features_cfg && !ast_strlen_zero(features_cfg->courtesytone)) {
395  ast_bridge_channel_queue_playfile(bridge_channel, NULL, features_cfg->courtesytone, NULL);
396  ast_bridge_channel_write_playfile(bridge_channel, NULL, features_cfg->courtesytone, NULL);
397  }
398 
399  if (!ast_strlen_zero(start_message)) {
400  ast_bridge_channel_queue_playfile(bridge_channel, NULL, start_message, NULL);
401  ast_bridge_channel_write_playfile(bridge_channel, NULL, start_message, NULL);
402  }
403 
404  pbx_builtin_setvar_helper(bridge_channel->chan, "TOUCH_MIXMONITOR_OUTPUT", touch_filename);
405  pbx_builtin_setvar_helper(peer_chan, "TOUCH_MIXMONITOR_OUTPUT", touch_filename);
406 }
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
char * str
Subscriber phone number (Malloced)
Definition: channel.h:292
int ast_start_mixmonitor(struct ast_channel *chan, const char *filename, const char *options)
Start a mixmonitor on a channel with the given parameters.
Definition: mixmonitor.c:74
#define NULL
Definition: resample.c:96
#define ast_verb(level,...)
Definition: logger.h:463
#define ast_strlen_zero(foo)
Definition: strings.h:52
Number structure.
Definition: app_followme.c:154
struct ast_party_id id
Caller party ID.
Definition: channel.h:421
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:85
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:290
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.
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define ast_free(a)
Definition: astmm.h:182
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...
set_touch_variables_res
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)
struct ast_channel * chan
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
const char * ast_channel_name(const struct ast_channel *chan)
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.
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:298
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:343

◆ start_automonitor()

static void start_automonitor ( struct ast_bridge_channel bridge_channel,
struct ast_channel peer_chan,
struct ast_features_general_config features_cfg,
const char *  start_message 
)
static

Definition at line 139 of file bridge_builtin_features.c.

References ast_alloca, ast_bridge_channel_queue_playfile(), ast_bridge_channel_write_playfile(), ast_channel_caller(), ast_channel_name(), ast_free, ast_monitor_setjoinfiles(), ast_monitor_start(), ast_strdupa, ast_strlen_zero, ast_verb, ast_bridge_channel::chan, ast_features_general_config::courtesytone, ast_party_caller::id, len(), NULL, ast_party_id::number, pbx_builtin_setvar_helper(), RAII_VAR, S_COR, S_OR, SET_TOUCH_ALLOC_FAILURE, SET_TOUCH_SUCCESS, SET_TOUCH_UNSET, set_touch_variables(), ast_party_number::str, ast_party_number::valid, X_REC_IN, and X_REC_OUT.

Referenced by feature_automonitor().

140 {
141  char *touch_filename;
142  size_t len;
143  int x;
144  enum set_touch_variables_res set_touch_res;
145 
146  RAII_VAR(char *, touch_format, NULL, ast_free);
147  RAII_VAR(char *, touch_monitor, NULL, ast_free);
148  RAII_VAR(char *, touch_monitor_prefix, NULL, ast_free);
149 
150  set_touch_res = set_touch_variables(bridge_channel->chan, 0, &touch_format,
151  &touch_monitor, &touch_monitor_prefix);
152  switch (set_touch_res) {
153  case SET_TOUCH_SUCCESS:
154  break;
155  case SET_TOUCH_UNSET:
156  set_touch_res = set_touch_variables(peer_chan, 0, &touch_format, &touch_monitor,
157  &touch_monitor_prefix);
158  if (set_touch_res == SET_TOUCH_ALLOC_FAILURE) {
159  return;
160  }
161  break;
163  return;
164  }
165 
166  if (!ast_strlen_zero(touch_monitor)) {
167  len = strlen(touch_monitor) + 50;
168  touch_filename = ast_alloca(len);
169  snprintf(touch_filename, len, "%s-%ld-%s",
170  S_OR(touch_monitor_prefix, "auto"),
171  (long) time(NULL),
172  touch_monitor);
173  } else {
174  char *caller_chan_id;
175  char *peer_chan_id;
176 
177  caller_chan_id = ast_strdupa(S_COR(ast_channel_caller(bridge_channel->chan)->id.number.valid,
178  ast_channel_caller(bridge_channel->chan)->id.number.str, ast_channel_name(bridge_channel->chan)));
179  peer_chan_id = ast_strdupa(S_COR(ast_channel_caller(peer_chan)->id.number.valid,
180  ast_channel_caller(peer_chan)->id.number.str, ast_channel_name(peer_chan)));
181  len = strlen(caller_chan_id) + strlen(peer_chan_id) + 50;
182  touch_filename = ast_alloca(len);
183  snprintf(touch_filename, len, "%s-%ld-%s-%s",
184  S_OR(touch_monitor_prefix, "auto"),
185  (long) time(NULL),
186  caller_chan_id,
187  peer_chan_id);
188  }
189 
190  for (x = 0; x < strlen(touch_filename); x++) {
191  if (touch_filename[x] == '/') {
192  touch_filename[x] = '-';
193  }
194  }
195 
196  ast_verb(4, "AutoMonitor used to record call. Filename: %s\n", touch_filename);
197 
198  if (ast_monitor_start(peer_chan, touch_format, touch_filename, 1, X_REC_IN | X_REC_OUT, NULL)) {
199  ast_verb(4, "AutoMonitor feature was tried by '%s' but monitor failed to start.\n",
200  ast_channel_name(bridge_channel->chan));
201  return;
202  }
203 
204  ast_monitor_setjoinfiles(peer_chan, 1);
205 
206  if (features_cfg && !ast_strlen_zero(features_cfg->courtesytone)) {
207  ast_bridge_channel_queue_playfile(bridge_channel, NULL, features_cfg->courtesytone, NULL);
208  ast_bridge_channel_write_playfile(bridge_channel, NULL, features_cfg->courtesytone, NULL);
209  }
210 
211  if (!ast_strlen_zero(start_message)) {
212  ast_bridge_channel_queue_playfile(bridge_channel, NULL, start_message, NULL);
213  ast_bridge_channel_write_playfile(bridge_channel, NULL, start_message, NULL);
214  }
215 
216  pbx_builtin_setvar_helper(bridge_channel->chan, "TOUCH_MONITOR_OUTPUT", touch_filename);
217  pbx_builtin_setvar_helper(peer_chan, "TOUCH_MONITOR_OUTPUT", touch_filename);
218 }
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
#define X_REC_IN
Definition: monitor.h:30
char * str
Subscriber phone number (Malloced)
Definition: channel.h:292
#define NULL
Definition: resample.c:96
#define ast_verb(level,...)
Definition: logger.h:463
#define X_REC_OUT
Definition: monitor.h:31
#define ast_strlen_zero(foo)
Definition: strings.h:52
Number structure.
Definition: app_followme.c:154
struct ast_party_id id
Caller party ID.
Definition: channel.h:421
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
int AST_OPTIONAL_API_NAME() ast_monitor_start(struct ast_channel *chan, const char *format_spec, const char *fname_base, int need_lock, int stream_action, const char *beep_id)
Start monitoring a channel.
Definition: res_monitor.c:305
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:85
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:290
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.
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define ast_free(a)
Definition: astmm.h:182
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...
set_touch_variables_res
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)
struct ast_channel * chan
void AST_OPTIONAL_API_NAME() ast_monitor_setjoinfiles(struct ast_channel *chan, int turnon)
Definition: res_monitor.c:926
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
const char * ast_channel_name(const struct ast_channel *chan)
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.
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:298
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:343

◆ stop_automixmonitor()

static void stop_automixmonitor ( struct ast_bridge_channel bridge_channel,
struct ast_channel peer_chan,
struct ast_features_general_config features_cfg,
const char *  stop_message 
)
static

Definition at line 300 of file bridge_builtin_features.c.

References ast_bridge_channel_queue_playfile(), ast_bridge_channel_write_playfile(), ast_channel_name(), ast_stop_mixmonitor(), ast_strlen_zero, ast_verb, ast_bridge_channel::chan, ast_features_general_config::courtesytone, NULL, and ast_features_general_config::recordingfailsound.

Referenced by feature_automixmonitor().

301 {
302  ast_verb(4, "AutoMixMonitor used to stop recording call.\n");
303 
304  if (ast_stop_mixmonitor(peer_chan, NULL)) {
305  ast_verb(4, "Failed to stop AutoMixMonitor for %s.\n", ast_channel_name(bridge_channel->chan));
306  if (features_cfg && !(ast_strlen_zero(features_cfg->recordingfailsound))) {
307  ast_bridge_channel_queue_playfile(bridge_channel, NULL, features_cfg->recordingfailsound, NULL);
308  }
309  return;
310  }
311 
312  if (features_cfg && !ast_strlen_zero(features_cfg->courtesytone)) {
313  ast_bridge_channel_queue_playfile(bridge_channel, NULL, features_cfg->courtesytone, NULL);
314  ast_bridge_channel_write_playfile(bridge_channel, NULL, features_cfg->courtesytone, NULL);
315  }
316 
317  if (!ast_strlen_zero(stop_message)) {
318  ast_bridge_channel_queue_playfile(bridge_channel, NULL, stop_message, NULL);
319  ast_bridge_channel_write_playfile(bridge_channel, NULL, stop_message, NULL);
320  }
321 }
#define NULL
Definition: resample.c:96
#define ast_verb(level,...)
Definition: logger.h:463
#define ast_strlen_zero(foo)
Definition: strings.h:52
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.
Definition: mixmonitor.c:86
struct ast_channel * chan
const char * ast_channel_name(const struct ast_channel *chan)
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.

◆ stop_automonitor()

static void stop_automonitor ( struct ast_bridge_channel bridge_channel,
struct ast_channel peer_chan,
struct ast_features_general_config features_cfg,
const char *  stop_message 
)
static

Definition at line 106 of file bridge_builtin_features.c.

References ast_bridge_channel_queue_playfile(), ast_bridge_channel_write_playfile(), ast_channel_lock, ast_channel_monitor(), ast_channel_name(), ast_channel_unlock, ast_strlen_zero, ast_verb, ast_bridge_channel::chan, ast_features_general_config::courtesytone, NULL, ast_features_general_config::recordingfailsound, and stop.

Referenced by feature_automonitor().

107 {
108  ast_verb(4, "AutoMonitor used to stop recording call.\n");
109 
110  ast_channel_lock(peer_chan);
111  if (ast_channel_monitor(peer_chan)) {
112  if (ast_channel_monitor(peer_chan)->stop(peer_chan, 1)) {
113  ast_verb(4, "Cannot stop AutoMonitor for %s\n", ast_channel_name(bridge_channel->chan));
114  if (features_cfg && !(ast_strlen_zero(features_cfg->recordingfailsound))) {
115  ast_bridge_channel_queue_playfile(bridge_channel, NULL, features_cfg->recordingfailsound, NULL);
116  }
117  ast_channel_unlock(peer_chan);
118  return;
119  }
120  } else {
121  /* Something else removed the Monitor before we got to it. */
122  ast_channel_unlock(peer_chan);
123  return;
124  }
125 
126  ast_channel_unlock(peer_chan);
127 
128  if (features_cfg && !(ast_strlen_zero(features_cfg->courtesytone))) {
129  ast_bridge_channel_queue_playfile(bridge_channel, NULL, features_cfg->courtesytone, NULL);
130  ast_bridge_channel_write_playfile(bridge_channel, NULL, features_cfg->courtesytone, NULL);
131  }
132 
133  if (!ast_strlen_zero(stop_message)) {
134  ast_bridge_channel_queue_playfile(bridge_channel, NULL, stop_message, NULL);
135  ast_bridge_channel_write_playfile(bridge_channel, NULL, stop_message, NULL);
136  }
137 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
unsigned int stop
Definition: app_meetme.c:1096
#define NULL
Definition: resample.c:96
#define ast_verb(level,...)
Definition: logger.h:463
#define ast_strlen_zero(foo)
Definition: strings.h:52
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.
#define ast_channel_unlock(chan)
Definition: channel.h:2946
struct ast_channel * chan
const char * ast_channel_name(const struct ast_channel *chan)
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.
struct ast_channel_monitor * ast_channel_monitor(const struct ast_channel *chan)

◆ unload_module()

static int unload_module ( void  )
static

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Built in bridging features" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "30ef0c93b36035ec78c9cfd712d36d9b" , .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .optional_modules = "res_monitor", }
static

Definition at line 529 of file bridge_builtin_features.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 529 of file bridge_builtin_features.c.