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)
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.
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_LOAD_ORDER , .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 = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, }
static struct ast_module_infoast_module_info = &__mod_info


Detailed Description

Built in bridging features.

Author:
Joshua Colp <jcolp@digium.com>

Definition in file bridge_builtin_features.c.


Enumeration Type Documentation

Enumerator:
SET_TOUCH_SUCCESS 
SET_TOUCH_UNSET 
SET_TOUCH_ALLOC_FAILURE 

Definition at line 58 of file bridge_builtin_features.c.

00058                              {
00059    SET_TOUCH_SUCCESS,
00060    SET_TOUCH_UNSET,
00061    SET_TOUCH_ALLOC_FAILURE,
00062 };


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 521 of file bridge_builtin_features.c.

static void __unreg_module ( void   )  [static]

Definition at line 521 of file bridge_builtin_features.c.

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

Definition at line 405 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, pbx_builtin_getvar_helper(), RAII_VAR, S_OR, start_automixmonitor(), ast_bridge_features_automixmonitor::start_stop, and stop_automixmonitor().

Referenced by load_module().

00406 {
00407    static const char *mixmonitor_spy_type = "MixMonitor";
00408    const char *stop_message;
00409    const char *start_message;
00410    struct ast_bridge_features_automixmonitor *options = hook_pvt;
00411    enum ast_bridge_features_monitor start_stop = options ? options->start_stop : AUTO_MONITOR_TOGGLE;
00412    int is_monitoring;
00413 
00414    RAII_VAR(struct ast_channel *, peer_chan, NULL, ast_channel_cleanup);
00415    RAII_VAR(struct ast_features_general_config *, features_cfg, NULL, ao2_cleanup);
00416 
00417    ast_channel_lock(bridge_channel->chan);
00418    features_cfg = ast_get_chan_features_general_config(bridge_channel->chan);
00419    ast_channel_unlock(bridge_channel->chan);
00420    ast_bridge_channel_lock_bridge(bridge_channel);
00421    peer_chan = ast_bridge_peer_nolock(bridge_channel->bridge, bridge_channel->chan);
00422    ast_bridge_unlock(bridge_channel->bridge);
00423 
00424    if (!peer_chan) {
00425       ast_verb(4, "Cannot start AutoMixMonitor for %s - cannot determine peer in bridge.\n",
00426          ast_channel_name(bridge_channel->chan));
00427       if (features_cfg && !ast_strlen_zero(features_cfg->recordingfailsound)) {
00428          ast_bridge_channel_queue_playfile(bridge_channel, NULL, features_cfg->recordingfailsound, NULL);
00429       }
00430       return 0;
00431    }
00432 
00433    ast_channel_lock(bridge_channel->chan);
00434    start_message = pbx_builtin_getvar_helper(bridge_channel->chan,
00435       "TOUCH_MIXMONITOR_MESSAGE_START");
00436    start_message = ast_strdupa(S_OR(start_message, ""));
00437    stop_message = pbx_builtin_getvar_helper(bridge_channel->chan,
00438       "TOUCH_MIXMONITOR_MESSAGE_STOP");
00439    stop_message = ast_strdupa(S_OR(stop_message, ""));
00440    ast_channel_unlock(bridge_channel->chan);
00441 
00442    is_monitoring =
00443       0 < ast_channel_audiohook_count_by_source(peer_chan, mixmonitor_spy_type, AST_AUDIOHOOK_TYPE_SPY);
00444    switch (start_stop) {
00445    case AUTO_MONITOR_TOGGLE:
00446       if (is_monitoring) {
00447          stop_automixmonitor(bridge_channel, peer_chan, features_cfg, stop_message);
00448       } else {
00449          start_automixmonitor(bridge_channel, peer_chan, features_cfg, start_message);
00450       }
00451       return 0;
00452    case AUTO_MONITOR_START:
00453       if (!is_monitoring) {
00454          start_automixmonitor(bridge_channel, peer_chan, features_cfg, start_message);
00455          return 0;
00456       }
00457       ast_verb(4, "AutoMixMonitor already recording call.\n");
00458       break;
00459    case AUTO_MONITOR_STOP:
00460       if (is_monitoring) {
00461          stop_automixmonitor(bridge_channel, peer_chan, features_cfg, stop_message);
00462          return 0;
00463       }
00464       ast_verb(4, "AutoMixMonitor already stopped on call.\n");
00465       break;
00466    }
00467 
00468    /*
00469     * Fake start/stop to invoker so will think it did something but
00470     * was already in that mode.
00471     */
00472    if (features_cfg && !ast_strlen_zero(features_cfg->courtesytone)) {
00473       ast_bridge_channel_queue_playfile(bridge_channel, NULL, features_cfg->courtesytone, NULL);
00474    }
00475    if (is_monitoring) {
00476       if (!ast_strlen_zero(start_message)) {
00477          ast_bridge_channel_queue_playfile(bridge_channel, NULL, start_message, NULL);
00478       }
00479    } else {
00480       if (!ast_strlen_zero(stop_message)) {
00481          ast_bridge_channel_queue_playfile(bridge_channel, NULL, stop_message, NULL);
00482       }
00483    }
00484    return 0;
00485 }

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

Definition at line 218 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, pbx_builtin_getvar_helper(), RAII_VAR, S_OR, start_automonitor(), ast_bridge_features_automonitor::start_stop, and stop_automonitor().

Referenced by load_module().

00219 {
00220    const char *start_message;
00221    const char *stop_message;
00222    struct ast_bridge_features_automonitor *options = hook_pvt;
00223    enum ast_bridge_features_monitor start_stop = options ? options->start_stop : AUTO_MONITOR_TOGGLE;
00224    int is_monitoring;
00225 
00226    RAII_VAR(struct ast_channel *, peer_chan, NULL, ast_channel_cleanup);
00227    RAII_VAR(struct ast_features_general_config *, features_cfg, NULL, ao2_cleanup);
00228 
00229    ast_channel_lock(bridge_channel->chan);
00230    features_cfg = ast_get_chan_features_general_config(bridge_channel->chan);
00231    ast_channel_unlock(bridge_channel->chan);
00232    ast_bridge_channel_lock_bridge(bridge_channel);
00233    peer_chan = ast_bridge_peer_nolock(bridge_channel->bridge, bridge_channel->chan);
00234    ast_bridge_unlock(bridge_channel->bridge);
00235 
00236    if (!peer_chan) {
00237       ast_verb(4, "Cannot start AutoMonitor for %s - can not determine peer in bridge.\n",
00238          ast_channel_name(bridge_channel->chan));
00239       if (features_cfg && !ast_strlen_zero(features_cfg->recordingfailsound)) {
00240          ast_bridge_channel_queue_playfile(bridge_channel, NULL, features_cfg->recordingfailsound, NULL);
00241       }
00242       return 0;
00243    }
00244 
00245    ast_channel_lock(bridge_channel->chan);
00246    start_message = pbx_builtin_getvar_helper(bridge_channel->chan,
00247       "TOUCH_MONITOR_MESSAGE_START");
00248    start_message = ast_strdupa(S_OR(start_message, ""));
00249    stop_message = pbx_builtin_getvar_helper(bridge_channel->chan,
00250       "TOUCH_MONITOR_MESSAGE_STOP");
00251    stop_message = ast_strdupa(S_OR(stop_message, ""));
00252    ast_channel_unlock(bridge_channel->chan);
00253 
00254    is_monitoring = ast_channel_monitor(peer_chan) != NULL;
00255    switch (start_stop) {
00256    case AUTO_MONITOR_TOGGLE:
00257       if (is_monitoring) {
00258          stop_automonitor(bridge_channel, peer_chan, features_cfg, stop_message);
00259       } else {
00260          start_automonitor(bridge_channel, peer_chan, features_cfg, start_message);
00261       }
00262       return 0;
00263    case AUTO_MONITOR_START:
00264       if (!is_monitoring) {
00265          start_automonitor(bridge_channel, peer_chan, features_cfg, start_message);
00266          return 0;
00267       }
00268       ast_verb(4, "AutoMonitor already recording call.\n");
00269       break;
00270    case AUTO_MONITOR_STOP:
00271       if (is_monitoring) {
00272          stop_automonitor(bridge_channel, peer_chan, features_cfg, stop_message);
00273          return 0;
00274       }
00275       ast_verb(4, "AutoMonitor already stopped on call.\n");
00276       break;
00277    }
00278 
00279    /*
00280     * Fake start/stop to invoker so will think it did something but
00281     * was already in that mode.
00282     */
00283    if (features_cfg && !ast_strlen_zero(features_cfg->courtesytone)) {
00284       ast_bridge_channel_queue_playfile(bridge_channel, NULL, features_cfg->courtesytone, NULL);
00285    }
00286    if (is_monitoring) {
00287       if (!ast_strlen_zero(start_message)) {
00288          ast_bridge_channel_queue_playfile(bridge_channel, NULL, start_message, NULL);
00289       }
00290    } else {
00291       if (!ast_strlen_zero(stop_message)) {
00292          ast_bridge_channel_queue_playfile(bridge_channel, NULL, stop_message, NULL);
00293       }
00294    }
00295    return 0;
00296 }

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

Internal built in feature for hangup.

Definition at line 488 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().

00489 {
00490    /*
00491     * This is very simple, we simply change the state on the
00492     * bridge_channel to force the channel out of the bridge and the
00493     * core takes care of the rest.
00494     */
00495    ast_bridge_channel_leave_bridge(bridge_channel, BRIDGE_CHANNEL_STATE_END,
00496       AST_CAUSE_NORMAL_CLEARING);
00497    return 0;
00498 }

static int load_module ( void   )  [static]

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 64 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().

00065 {
00066    const char *c_touch;
00067 
00068    if (*res == SET_TOUCH_ALLOC_FAILURE) {
00069       return;
00070    }
00071    c_touch = pbx_builtin_getvar_helper(chan, var_name);
00072    if (!ast_strlen_zero(c_touch)) {
00073       *touch = ast_strdup(c_touch);
00074       if (!*touch) {
00075          *res = SET_TOUCH_ALLOC_FAILURE;
00076       } else {
00077          *res = SET_TOUCH_SUCCESS;
00078       }
00079    }
00080 }

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 82 of file bridge_builtin_features.c.

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

Referenced by start_automixmonitor(), and start_automonitor().

00083 {
00084    enum set_touch_variables_res res = SET_TOUCH_UNSET;
00085    const char *var_format;
00086    const char *var_monitor;
00087    const char *var_prefix;
00088 
00089    SCOPED_CHANNELLOCK(lock, chan);
00090 
00091    if (is_mixmonitor) {
00092       var_format = "TOUCH_MIXMONITOR_FORMAT";
00093       var_monitor = "TOUCH_MIXMONITOR";
00094       var_prefix = "TOUCH_MIXMONITOR_PREFIX";
00095    } else {
00096       var_format = "TOUCH_MONITOR_FORMAT";
00097       var_monitor = "TOUCH_MONITOR";
00098       var_prefix = "TOUCH_MONITOR_PREFIX";
00099    }
00100    set_touch_variable(&res, chan, var_format, touch_format);
00101    set_touch_variable(&res, chan, var_monitor, touch_monitor);
00102    set_touch_variable(&res, chan, var_prefix, touch_monitor_prefix);
00103 
00104    return res;
00105 }

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 321 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().

00322 {
00323    char *touch_filename;
00324    size_t len;
00325    int x;
00326    enum set_touch_variables_res set_touch_res;
00327 
00328    RAII_VAR(char *, touch_format, NULL, ast_free);
00329    RAII_VAR(char *, touch_monitor, NULL, ast_free);
00330    RAII_VAR(char *, touch_monitor_prefix, NULL, ast_free);
00331 
00332    set_touch_res = set_touch_variables(bridge_channel->chan, 1, &touch_format,
00333       &touch_monitor, &touch_monitor_prefix);
00334    switch (set_touch_res) {
00335    case SET_TOUCH_SUCCESS:
00336       break;
00337    case SET_TOUCH_UNSET:
00338       set_touch_res = set_touch_variables(peer_chan, 1, &touch_format, &touch_monitor,
00339          &touch_monitor_prefix);
00340       if (set_touch_res == SET_TOUCH_ALLOC_FAILURE) {
00341          return;
00342       }
00343       break;
00344    case SET_TOUCH_ALLOC_FAILURE:
00345       return;
00346    }
00347 
00348    if (!ast_strlen_zero(touch_monitor)) {
00349       len = strlen(touch_monitor) + 50;
00350       touch_filename = ast_alloca(len);
00351       snprintf(touch_filename, len, "%s-%ld-%s.%s",
00352          S_OR(touch_monitor_prefix, "auto"),
00353          (long) time(NULL),
00354          touch_monitor,
00355          S_OR(touch_format, "wav"));
00356    } else {
00357       char *caller_chan_id;
00358       char *peer_chan_id;
00359 
00360       caller_chan_id = ast_strdupa(S_COR(ast_channel_caller(bridge_channel->chan)->id.number.valid,
00361          ast_channel_caller(bridge_channel->chan)->id.number.str, ast_channel_name(bridge_channel->chan)));
00362       peer_chan_id = ast_strdupa(S_COR(ast_channel_caller(peer_chan)->id.number.valid,
00363          ast_channel_caller(peer_chan)->id.number.str, ast_channel_name(peer_chan)));
00364       len = strlen(caller_chan_id) + strlen(peer_chan_id) + 50;
00365       touch_filename = ast_alloca(len);
00366       snprintf(touch_filename, len, "%s-%ld-%s-%s.%s",
00367          S_OR(touch_monitor_prefix, "auto"),
00368          (long) time(NULL),
00369          caller_chan_id,
00370          peer_chan_id,
00371          S_OR(touch_format, "wav"));
00372    }
00373 
00374    for (x = 0; x < strlen(touch_filename); x++) {
00375       if (touch_filename[x] == '/') {
00376          touch_filename[x] = '-';
00377       }
00378    }
00379 
00380    ast_verb(4, "AutoMixMonitor used to record call. Filename: %s\n", touch_filename);
00381 
00382    if (ast_start_mixmonitor(peer_chan, touch_filename, "b")) {
00383       ast_verb(4, "AutoMixMonitor feature was tried by '%s' but MixMonitor failed to start.\n",
00384          ast_channel_name(bridge_channel->chan));
00385 
00386       if (features_cfg && !ast_strlen_zero(features_cfg->recordingfailsound)) {
00387          ast_bridge_channel_queue_playfile(bridge_channel, NULL, features_cfg->recordingfailsound, NULL);
00388       }
00389       return;
00390    }
00391 
00392    if (features_cfg && !ast_strlen_zero(features_cfg->courtesytone)) {
00393       ast_bridge_channel_queue_playfile(bridge_channel, NULL, features_cfg->courtesytone, NULL);
00394       ast_bridge_channel_write_playfile(bridge_channel, NULL, features_cfg->courtesytone, NULL);
00395    }
00396 
00397    if (!ast_strlen_zero(start_message)) {
00398       ast_bridge_channel_queue_playfile(bridge_channel, NULL, start_message, NULL);
00399       ast_bridge_channel_write_playfile(bridge_channel, NULL, start_message, NULL);
00400    }
00401 
00402    pbx_builtin_setvar_helper(peer_chan, "TOUCH_MIXMONITOR_OUTPUT", touch_filename);
00403 }

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 140 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_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().

00141 {
00142    char *touch_filename;
00143    size_t len;
00144    int x;
00145    enum set_touch_variables_res set_touch_res;
00146 
00147    RAII_VAR(char *, touch_format, NULL, ast_free);
00148    RAII_VAR(char *, touch_monitor, NULL, ast_free);
00149    RAII_VAR(char *, touch_monitor_prefix, NULL, ast_free);
00150 
00151    set_touch_res = set_touch_variables(bridge_channel->chan, 0, &touch_format,
00152       &touch_monitor, &touch_monitor_prefix);
00153    switch (set_touch_res) {
00154    case SET_TOUCH_SUCCESS:
00155       break;
00156    case SET_TOUCH_UNSET:
00157       set_touch_res = set_touch_variables(peer_chan, 0, &touch_format, &touch_monitor,
00158          &touch_monitor_prefix);
00159       if (set_touch_res == SET_TOUCH_ALLOC_FAILURE) {
00160          return;
00161       }
00162       break;
00163    case SET_TOUCH_ALLOC_FAILURE:
00164       return;
00165    }
00166 
00167    if (!ast_strlen_zero(touch_monitor)) {
00168       len = strlen(touch_monitor) + 50;
00169       touch_filename = ast_alloca(len);
00170       snprintf(touch_filename, len, "%s-%ld-%s",
00171          S_OR(touch_monitor_prefix, "auto"),
00172          (long) time(NULL),
00173          touch_monitor);
00174    } else {
00175       char *caller_chan_id;
00176       char *peer_chan_id;
00177 
00178       caller_chan_id = ast_strdupa(S_COR(ast_channel_caller(bridge_channel->chan)->id.number.valid,
00179          ast_channel_caller(bridge_channel->chan)->id.number.str, ast_channel_name(bridge_channel->chan)));
00180       peer_chan_id = ast_strdupa(S_COR(ast_channel_caller(peer_chan)->id.number.valid,
00181          ast_channel_caller(peer_chan)->id.number.str, ast_channel_name(peer_chan)));
00182       len = strlen(caller_chan_id) + strlen(peer_chan_id) + 50;
00183       touch_filename = ast_alloca(len);
00184       snprintf(touch_filename, len, "%s-%ld-%s-%s",
00185          S_OR(touch_monitor_prefix, "auto"),
00186          (long) time(NULL),
00187          caller_chan_id,
00188          peer_chan_id);
00189    }
00190 
00191    for (x = 0; x < strlen(touch_filename); x++) {
00192       if (touch_filename[x] == '/') {
00193          touch_filename[x] = '-';
00194       }
00195    }
00196 
00197    ast_verb(4, "AutoMonitor used to record call. Filename: %s\n", touch_filename);
00198 
00199    if (ast_monitor_start(peer_chan, touch_format, touch_filename, 1, X_REC_IN | X_REC_OUT, NULL)) {
00200       ast_verb(4, "AutoMonitor feature was tried by '%s' but monitor failed to start.\n",
00201          ast_channel_name(bridge_channel->chan));
00202       return;
00203    }
00204 
00205    if (features_cfg && !ast_strlen_zero(features_cfg->courtesytone)) {
00206       ast_bridge_channel_queue_playfile(bridge_channel, NULL, features_cfg->courtesytone, NULL);
00207       ast_bridge_channel_write_playfile(bridge_channel, NULL, features_cfg->courtesytone, NULL);
00208    }
00209 
00210    if (!ast_strlen_zero(start_message)) {
00211       ast_bridge_channel_queue_playfile(bridge_channel, NULL, start_message, NULL);
00212       ast_bridge_channel_write_playfile(bridge_channel, NULL, start_message, NULL);
00213    }
00214 
00215    pbx_builtin_setvar_helper(peer_chan, "TOUCH_MONITOR_OUTPUT", touch_filename);
00216 }

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 298 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().

00299 {
00300    ast_verb(4, "AutoMixMonitor used to stop recording call.\n");
00301 
00302    if (ast_stop_mixmonitor(peer_chan, NULL)) {
00303       ast_verb(4, "Failed to stop AutoMixMonitor for %s.\n", ast_channel_name(bridge_channel->chan));
00304       if (features_cfg && !(ast_strlen_zero(features_cfg->recordingfailsound))) {
00305          ast_bridge_channel_queue_playfile(bridge_channel, NULL, features_cfg->recordingfailsound, NULL);
00306       }
00307       return;
00308    }
00309 
00310    if (features_cfg && !ast_strlen_zero(features_cfg->courtesytone)) {
00311       ast_bridge_channel_queue_playfile(bridge_channel, NULL, features_cfg->courtesytone, NULL);
00312       ast_bridge_channel_write_playfile(bridge_channel, NULL, features_cfg->courtesytone, NULL);
00313    }
00314 
00315    if (!ast_strlen_zero(stop_message)) {
00316       ast_bridge_channel_queue_playfile(bridge_channel, NULL, stop_message, NULL);
00317       ast_bridge_channel_write_playfile(bridge_channel, NULL, stop_message, NULL);
00318    }
00319 }

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 107 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().

00108 {
00109    ast_verb(4, "AutoMonitor used to stop recording call.\n");
00110 
00111    ast_channel_lock(peer_chan);
00112    if (ast_channel_monitor(peer_chan)) {
00113       if (ast_channel_monitor(peer_chan)->stop(peer_chan, 1)) {
00114          ast_verb(4, "Cannot stop AutoMonitor for %s\n", ast_channel_name(bridge_channel->chan));
00115          if (features_cfg && !(ast_strlen_zero(features_cfg->recordingfailsound))) {
00116             ast_bridge_channel_queue_playfile(bridge_channel, NULL, features_cfg->recordingfailsound, NULL);
00117          }
00118          ast_channel_unlock(peer_chan);
00119          return;
00120       }
00121    } else {
00122       /* Something else removed the Monitor before we got to it. */
00123       ast_channel_unlock(peer_chan);
00124       return;
00125    }
00126 
00127    ast_channel_unlock(peer_chan);
00128 
00129    if (features_cfg && !(ast_strlen_zero(features_cfg->courtesytone))) {
00130       ast_bridge_channel_queue_playfile(bridge_channel, NULL, features_cfg->courtesytone, NULL);
00131       ast_bridge_channel_write_playfile(bridge_channel, NULL, features_cfg->courtesytone, NULL);
00132    }
00133 
00134    if (!ast_strlen_zero(stop_message)) {
00135       ast_bridge_channel_queue_playfile(bridge_channel, NULL, stop_message, NULL);
00136       ast_bridge_channel_write_playfile(bridge_channel, NULL, stop_message, NULL);
00137    }
00138 }

static int unload_module ( void   )  [static]


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .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 = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, } [static]

Definition at line 521 of file bridge_builtin_features.c.

Definition at line 521 of file bridge_builtin_features.c.


Generated on Thu Apr 16 06:29:09 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6