app_bridgewait.c File Reference

Application to place the channel into a holding Bridge. More...

#include "asterisk.h"
#include "asterisk/file.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/features.h"
#include "asterisk/say.h"
#include "asterisk/lock.h"
#include "asterisk/utils.h"
#include "asterisk/app.h"
#include "asterisk/bridge.h"
#include "asterisk/musiconhold.h"
#include "asterisk/astobj2.h"
#include "asterisk/causes.h"

Include dependency graph for app_bridgewait.c:

Go to the source code of this file.

Data Structures

struct  wait_bridge_wrapper

Defines

#define APP_NAME   "BridgeWait"
#define DEFAULT_BRIDGE_NAME   "default"

Enumerations

enum  bridgewait_args { OPT_ARG_ENTERTAINMENT, OPT_ARG_MOHCLASS, OPT_ARG_TIMEOUT, OPT_ARG_ARRAY_SIZE }
enum  bridgewait_flags { MUXFLAG_MOHCLASS = (1 << 0), MUXFLAG_ENTERTAINMENT = (1 << 1), MUXFLAG_TIMEOUT = (1 << 2) }
enum  wait_bridge_roles { ROLE_PARTICIPANT = 0, ROLE_ANNOUNCER, ROLE_INVALID }

Functions

static void __reg_module (void)
static void __unreg_module (void)
static int apply_option_entertainment (struct ast_channel *chan, const char *entertainment_arg)
static int apply_option_moh (struct ast_channel *chan, const char *class_arg)
static int apply_option_timeout (struct ast_bridge_features *features, char *duration_arg)
static int bridgewait_exec (struct ast_channel *chan, const char *data)
static int bridgewait_timeout_callback (struct ast_bridge_channel *bridge_channel, void *hook_pvt)
static struct wait_bridge_wrapperget_wait_bridge_wrapper (const char *bridge_name)
static int load_module (void)
static int process_options (struct ast_channel *chan, struct ast_flags *flags, char **opts, struct ast_bridge_features *features, enum wait_bridge_roles role)
static int unload_module (void)
static enum wait_bridge_roles validate_role (const char *role)
static int wait_bridge_hash_fn (const void *obj, const int flags)
static int wait_bridge_sort_fn (const void *obj_left, const void *obj_right, const int flags)
static struct wait_bridge_wrapperwait_bridge_wrapper_alloc (const char *bridge_name, struct ast_bridge *bridge)
static void wait_bridge_wrapper_destructor (void *obj)
static struct wait_bridge_wrapperwait_bridge_wrapper_find_by_name (const char *bridge_name)
static void wait_wrapper_removal (struct wait_bridge_wrapper *wrapper)

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Place the channel into a holding bridge application" , .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
static struct ast_app_option bridgewait_opts [128] = { [ 'e' ] = { .flag = MUXFLAG_ENTERTAINMENT , .arg_index = OPT_ARG_ENTERTAINMENT + 1 }, [ 'm' ] = { .flag = MUXFLAG_MOHCLASS , .arg_index = OPT_ARG_MOHCLASS + 1 }, [ 'S' ] = { .flag = MUXFLAG_TIMEOUT , .arg_index = OPT_ARG_TIMEOUT + 1 },}
static struct ao2_containerwait_bridge_wrappers


Detailed Description

Application to place the channel into a holding Bridge.

Author:
Jonathan Rose <jrose@digium.com>

Definition in file app_bridgewait.c.


Define Documentation

#define APP_NAME   "BridgeWait"

Definition at line 118 of file app_bridgewait.c.

Referenced by get_wait_bridge_wrapper(), load_module(), and unload_module().

#define DEFAULT_BRIDGE_NAME   "default"

Definition at line 119 of file app_bridgewait.c.

Referenced by bridgewait_exec().


Enumeration Type Documentation

Enumerator:
OPT_ARG_ENTERTAINMENT 
OPT_ARG_MOHCLASS 
OPT_ARG_TIMEOUT 
OPT_ARG_ARRAY_SIZE 

Definition at line 193 of file app_bridgewait.c.

00193                      {
00194    OPT_ARG_ENTERTAINMENT,
00195    OPT_ARG_MOHCLASS,
00196    OPT_ARG_TIMEOUT,
00197    OPT_ARG_ARRAY_SIZE, /* Always the last element of the enum */
00198 };

Enumerator:
MUXFLAG_MOHCLASS 
MUXFLAG_ENTERTAINMENT 
MUXFLAG_TIMEOUT 

Definition at line 187 of file app_bridgewait.c.

00187                       {
00188    MUXFLAG_MOHCLASS = (1 << 0),
00189    MUXFLAG_ENTERTAINMENT = (1 << 1),
00190    MUXFLAG_TIMEOUT = (1 << 2),
00191 };

Enumerator:
ROLE_PARTICIPANT 
ROLE_ANNOUNCER 
ROLE_INVALID 

Definition at line 264 of file app_bridgewait.c.

00264                        {
00265    ROLE_PARTICIPANT = 0,
00266    ROLE_ANNOUNCER,
00267    ROLE_INVALID,
00268 };


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 514 of file app_bridgewait.c.

static void __unreg_module ( void   )  [static]

Definition at line 514 of file app_bridgewait.c.

static int apply_option_entertainment ( struct ast_channel chan,
const char *  entertainment_arg 
) [static]

Definition at line 243 of file app_bridgewait.c.

References ast_channel_set_bridge_role_option(), ast_log, and LOG_ERROR.

Referenced by process_options().

00244 {
00245    char entertainment = entertainment_arg[0];
00246 
00247    switch (entertainment) {
00248    case 'm':
00249       return ast_channel_set_bridge_role_option(chan, "holding_participant", "idle_mode", "musiconhold");
00250    case 'r':
00251       return ast_channel_set_bridge_role_option(chan, "holding_participant", "idle_mode", "ringing");
00252    case 's':
00253       return ast_channel_set_bridge_role_option(chan, "holding_participant", "idle_mode", "silence");
00254    case 'h':
00255       return ast_channel_set_bridge_role_option(chan, "holding_participant", "idle_mode", "hold");
00256    case 'n':
00257       return ast_channel_set_bridge_role_option(chan, "holding_participant", "idle_mode", "none");
00258    default:
00259       ast_log(LOG_ERROR, "Invalid argument for BridgeWait entertainment '%s'\n", entertainment_arg);
00260       return -1;
00261    }
00262 }

static int apply_option_moh ( struct ast_channel chan,
const char *  class_arg 
) [static]

Definition at line 238 of file app_bridgewait.c.

References ast_channel_set_bridge_role_option().

Referenced by process_options().

00239 {
00240    return ast_channel_set_bridge_role_option(chan, "holding_participant", "moh_class", class_arg);
00241 }

static int apply_option_timeout ( struct ast_bridge_features features,
char *  duration_arg 
) [static]

Definition at line 214 of file app_bridgewait.c.

References AST_BRIDGE_HOOK_REMOVE_ON_PULL, ast_bridge_interval_hook(), ast_log, ast_strlen_zero, bridgewait_timeout_callback(), LOG_ERROR, and NULL.

Referenced by park_app_parse_data(), and process_options().

00215 {
00216    unsigned int duration;
00217 
00218    if (ast_strlen_zero(duration_arg)) {
00219       ast_log(LOG_ERROR, "Timeout option 'S': No value provided.\n");
00220       return -1;
00221    }
00222    if (sscanf(duration_arg, "%u", &duration) != 1 || duration == 0) {
00223       ast_log(LOG_ERROR, "Timeout option 'S': Invalid value provided '%s'.\n",
00224          duration_arg);
00225       return -1;
00226    }
00227 
00228    duration *= 1000;
00229    if (ast_bridge_interval_hook(features, 0, duration, bridgewait_timeout_callback,
00230       NULL, NULL, AST_BRIDGE_HOOK_REMOVE_ON_PULL)) {
00231       ast_log(LOG_ERROR, "Timeout option 'S': Could not create timer.\n");
00232       return -1;
00233    }
00234 
00235    return 0;
00236 }

static int bridgewait_exec ( struct ast_channel chan,
const char *  data 
) [static]

Definition at line 418 of file app_bridgewait.c.

References args, ast_answer(), AST_APP_ARG, ast_app_parse_options(), ast_bridge_features_cleanup(), ast_bridge_features_init(), ast_bridge_join(), ast_channel_name(), ast_check_hangup_locked(), AST_DECLARE_APP_ARGS, ast_log, AST_STANDARD_APP_ARGS, AST_STATE_UP, ast_strdupa, ast_strlen_zero, ast_verb, wait_bridge_wrapper::bridge, bridgewait_opts, DEFAULT_BRIDGE_NAME, get_wait_bridge_wrapper(), LOG_ERROR, LOG_WARNING, name, NULL, OPT_ARG_ARRAY_SIZE, parse(), process_options(), ROLE_INVALID, ROLE_PARTICIPANT, ast_bridge::uniqueid, validate_role(), and wait_wrapper_removal().

Referenced by load_module().

00419 {
00420    char *bridge_name = DEFAULT_BRIDGE_NAME;
00421    struct ast_bridge_features chan_features;
00422    struct ast_flags flags = { 0 };
00423    char *parse;
00424    enum wait_bridge_roles role = ROLE_PARTICIPANT;
00425    char *opts[OPT_ARG_ARRAY_SIZE] = { NULL, };
00426    struct wait_bridge_wrapper *bridge_wrapper;
00427    int res;
00428 
00429    AST_DECLARE_APP_ARGS(args,
00430       AST_APP_ARG(name);
00431       AST_APP_ARG(role);
00432       AST_APP_ARG(options);
00433       AST_APP_ARG(other);     /* Any remaining unused arguments */
00434    );
00435 
00436    parse = ast_strdupa(data);
00437    AST_STANDARD_APP_ARGS(args, parse);
00438 
00439    if (!ast_strlen_zero(args.name)) {
00440       bridge_name = args.name;
00441    }
00442 
00443    if (!ast_strlen_zero(args.role)) {
00444       role = validate_role(args.role);
00445       if (role == ROLE_INVALID) {
00446          ast_log(LOG_ERROR, "Requested waiting bridge role '%s' is invalid.\n", args.role);
00447          return -1;
00448       }
00449    }
00450 
00451    if (ast_bridge_features_init(&chan_features)) {
00452       ast_bridge_features_cleanup(&chan_features);
00453       ast_log(LOG_ERROR, "'%s' failed to enter the waiting bridge - could not set up channel features\n",
00454          ast_channel_name(chan));
00455       return -1;
00456    }
00457 
00458    if (args.options) {
00459       ast_app_parse_options(bridgewait_opts, &flags, opts, args.options);
00460    }
00461 
00462    /* Answer the channel if needed */
00463    if (ast_channel_state(chan) != AST_STATE_UP) {
00464       ast_answer(chan);
00465    }
00466 
00467    if (process_options(chan, &flags, opts, &chan_features, role)) {
00468       ast_bridge_features_cleanup(&chan_features);
00469       return -1;
00470    }
00471 
00472    bridge_wrapper = get_wait_bridge_wrapper(bridge_name);
00473    if (!bridge_wrapper) {
00474       ast_log(LOG_WARNING, "Failed to find or create waiting bridge '%s' for '%s'.\n", bridge_name, ast_channel_name(chan));
00475       ast_bridge_features_cleanup(&chan_features);
00476       return -1;
00477    }
00478 
00479    ast_verb(3, "%s is entering waiting bridge %s:%s\n", ast_channel_name(chan), bridge_name, bridge_wrapper->bridge->uniqueid);
00480    res = ast_bridge_join(bridge_wrapper->bridge, chan, NULL, &chan_features, NULL, 0);
00481    wait_wrapper_removal(bridge_wrapper);
00482    ast_bridge_features_cleanup(&chan_features);
00483 
00484    if (res) {
00485       /* For the lifetime of the bridge wrapper the bridge itself will be valid, if an error occurs it is because
00486        * of extreme situations.
00487        */
00488       ast_log(LOG_WARNING, "Failed to join waiting bridge '%s' for '%s'.\n", bridge_name, ast_channel_name(chan));
00489    }
00490 
00491    return (res || ast_check_hangup_locked(chan)) ? -1 : 0;
00492 }

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

Definition at line 206 of file app_bridgewait.c.

References ast_bridge_channel_leave_bridge(), AST_CAUSE_NORMAL_CLEARING, ast_channel_name(), ast_verb, BRIDGE_CHANNEL_STATE_END, and ast_bridge_channel::chan.

Referenced by apply_option_timeout().

00207 {
00208    ast_verb(3, "Channel %s timed out.\n", ast_channel_name(bridge_channel->chan));
00209    ast_bridge_channel_leave_bridge(bridge_channel, BRIDGE_CHANNEL_STATE_END,
00210       AST_CAUSE_NORMAL_CLEARING);
00211    return -1;
00212 }

static struct wait_bridge_wrapper* get_wait_bridge_wrapper ( const char *  bridge_name  )  [static, read]

Definition at line 343 of file app_bridgewait.c.

References APP_NAME, ast_bridge_base_new(), AST_BRIDGE_CAPABILITY_HOLDING, AST_BRIDGE_FLAG_MERGE_INHIBIT_FROM, AST_BRIDGE_FLAG_MERGE_INHIBIT_TO, AST_BRIDGE_FLAG_SWAP_INHIBIT_FROM, AST_BRIDGE_FLAG_SWAP_INHIBIT_TO, AST_BRIDGE_FLAG_TRANSFER_PROHIBITED, lock, NULL, SCOPED_AO2LOCK, wait_bridge_wrapper_alloc(), and wait_bridge_wrapper_find_by_name().

Referenced by bridgewait_exec().

00344 {
00345    struct wait_bridge_wrapper * wrapper;
00346    struct ast_bridge *bridge = NULL;
00347 
00348    SCOPED_AO2LOCK(lock, wait_bridge_wrappers);
00349 
00350    if ((wrapper = wait_bridge_wrapper_find_by_name(bridge_name))) {
00351       return wrapper;
00352    }
00353 
00354    /*
00355     * Holding bridges can allow local channel move/swap
00356     * optimization to the bridge.  However, we cannot allow it for
00357     * this holding bridge because the call will lose the channel
00358     * roles and dialplan location as a result.
00359     */
00360    bridge = ast_bridge_base_new(AST_BRIDGE_CAPABILITY_HOLDING,
00361       AST_BRIDGE_FLAG_MERGE_INHIBIT_TO | AST_BRIDGE_FLAG_MERGE_INHIBIT_FROM
00362       | AST_BRIDGE_FLAG_SWAP_INHIBIT_TO | AST_BRIDGE_FLAG_SWAP_INHIBIT_FROM
00363       | AST_BRIDGE_FLAG_TRANSFER_PROHIBITED, APP_NAME, bridge_name, NULL);
00364 
00365    if (!bridge) {
00366       return NULL;
00367    }
00368 
00369    /* The bridge reference is unconditionally passed. */
00370    return wait_bridge_wrapper_alloc(bridge_name, bridge);
00371 }

static int load_module ( void   )  [static]

static int process_options ( struct ast_channel chan,
struct ast_flags flags,
char **  opts,
struct ast_bridge_features features,
enum wait_bridge_roles  role 
) [static]

Definition at line 270 of file app_bridgewait.c.

References apply_option_entertainment(), apply_option_moh(), apply_option_timeout(), ast_assert, ast_channel_add_bridge_role(), ast_test_flag, MUXFLAG_ENTERTAINMENT, MUXFLAG_MOHCLASS, MUXFLAG_TIMEOUT, OPT_ARG_ENTERTAINMENT, OPT_ARG_MOHCLASS, OPT_ARG_TIMEOUT, ROLE_ANNOUNCER, ROLE_INVALID, and ROLE_PARTICIPANT.

Referenced by bridgewait_exec().

00271 {
00272    if (ast_test_flag(flags, MUXFLAG_TIMEOUT)) {
00273       if (apply_option_timeout(features, opts[OPT_ARG_TIMEOUT])) {
00274          return -1;
00275       }
00276    }
00277 
00278    switch (role) {
00279    case ROLE_PARTICIPANT:
00280       if (ast_channel_add_bridge_role(chan, "holding_participant")) {
00281          return -1;
00282       }
00283 
00284       if (ast_test_flag(flags, MUXFLAG_MOHCLASS)) {
00285          if (apply_option_moh(chan, opts[OPT_ARG_MOHCLASS])) {
00286             return -1;
00287          }
00288       }
00289 
00290       if (ast_test_flag(flags, MUXFLAG_ENTERTAINMENT)) {
00291          if (apply_option_entertainment(chan, opts[OPT_ARG_ENTERTAINMENT])) {
00292             return -1;
00293          }
00294       }
00295 
00296       break;
00297    case ROLE_ANNOUNCER:
00298       if (ast_channel_add_bridge_role(chan, "announcer")) {
00299          return -1;
00300       }
00301       break;
00302    case ROLE_INVALID:
00303       ast_assert(0);
00304       return -1;
00305    }
00306 
00307    return 0;
00308 }

static int unload_module ( void   )  [static]

Definition at line 494 of file app_bridgewait.c.

References ao2_cleanup, APP_NAME, and ast_unregister_application().

00495 {
00496    ao2_cleanup(wait_bridge_wrappers);
00497 
00498    return ast_unregister_application(APP_NAME);
00499 }

static enum wait_bridge_roles validate_role ( const char *  role  )  [static]

Definition at line 407 of file app_bridgewait.c.

References ROLE_ANNOUNCER, ROLE_INVALID, and ROLE_PARTICIPANT.

Referenced by bridgewait_exec().

00408 {
00409    if (!strcmp(role, "participant")) {
00410       return ROLE_PARTICIPANT;
00411    } else if (!strcmp(role, "announcer")) {
00412       return ROLE_ANNOUNCER;
00413    } else {
00414       return ROLE_INVALID;
00415    }
00416 }

static int wait_bridge_hash_fn ( const void *  obj,
const int  flags 
) [static]

Definition at line 142 of file app_bridgewait.c.

References ast_assert, ast_str_hash(), wait_bridge_wrapper::name, OBJ_KEY, OBJ_PARTIAL_KEY, and OBJ_POINTER.

Referenced by load_module().

00143 {
00144    const struct wait_bridge_wrapper *entry;
00145    const char *key;
00146 
00147    switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
00148    case OBJ_KEY:
00149       key = obj;
00150       return ast_str_hash(key);
00151    case OBJ_POINTER:
00152       entry = obj;
00153       return ast_str_hash(entry->name);
00154    default:
00155       /* Hash can only work on something with a full key. */
00156       ast_assert(0);
00157       return 0;
00158    }
00159 }

static int wait_bridge_sort_fn ( const void *  obj_left,
const void *  obj_right,
const int  flags 
) [static]

Definition at line 161 of file app_bridgewait.c.

References ast_assert, wait_bridge_wrapper::name, OBJ_KEY, OBJ_PARTIAL_KEY, and OBJ_POINTER.

Referenced by load_module().

00162 {
00163    const struct wait_bridge_wrapper *left = obj_left;
00164    const struct wait_bridge_wrapper *right = obj_right;
00165    const char *right_key = obj_right;
00166    int cmp;
00167 
00168    switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
00169    case OBJ_POINTER:
00170       right_key = right->name;
00171       /* Fall through */
00172    case OBJ_KEY:
00173       cmp = strcmp(left->name, right_key);
00174       break;
00175    case OBJ_PARTIAL_KEY:
00176       cmp = strncmp(left->name, right_key, strlen(right_key));
00177       break;
00178    default:
00179       /* Sort can only work on something with a full or partial key. */
00180       ast_assert(0);
00181       cmp = 0;
00182       break;
00183    }
00184    return cmp;
00185 }

static struct wait_bridge_wrapper* wait_bridge_wrapper_alloc ( const char *  bridge_name,
struct ast_bridge bridge 
) [static, read]

Definition at line 321 of file app_bridgewait.c.

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ao2_cleanup, ao2_link, ast_bridge_destroy(), wait_bridge_wrapper::bridge, wait_bridge_wrapper::name, NULL, and wait_bridge_wrapper_destructor().

Referenced by get_wait_bridge_wrapper().

00322 {
00323    struct wait_bridge_wrapper *bridge_wrapper;
00324 
00325    bridge_wrapper = ao2_alloc_options(sizeof(*bridge_wrapper) + strlen(bridge_name) + 1,
00326       wait_bridge_wrapper_destructor, AO2_ALLOC_OPT_LOCK_NOLOCK);
00327    if (!bridge_wrapper) {
00328       ast_bridge_destroy(bridge, 0);
00329       return NULL;
00330    }
00331 
00332    strcpy(bridge_wrapper->name, bridge_name);
00333    bridge_wrapper->bridge = bridge;
00334 
00335    if (!ao2_link(wait_bridge_wrappers, bridge_wrapper)) {
00336       ao2_cleanup(bridge_wrapper);
00337       return NULL;
00338    }
00339 
00340    return bridge_wrapper;
00341 }

static void wait_bridge_wrapper_destructor ( void *  obj  )  [static]

Definition at line 128 of file app_bridgewait.c.

References ast_bridge_destroy(), and wait_bridge_wrapper::bridge.

Referenced by wait_bridge_wrapper_alloc().

00129 {
00130    struct wait_bridge_wrapper *wrapper = obj;
00131 
00132    if (wrapper->bridge) {
00133       ast_bridge_destroy(wrapper->bridge, 0);
00134    }
00135 }

static struct wait_bridge_wrapper* wait_bridge_wrapper_find_by_name ( const char *  bridge_name  )  [static, read]

Definition at line 137 of file app_bridgewait.c.

References ao2_find, and OBJ_KEY.

Referenced by get_wait_bridge_wrapper().

00138 {
00139    return ao2_find(wait_bridge_wrappers, bridge_name, OBJ_KEY);
00140 }

static void wait_wrapper_removal ( struct wait_bridge_wrapper wrapper  )  [static]

Definition at line 380 of file app_bridgewait.c.

References ao2_cleanup, ao2_lock, ao2_ref, ao2_unlink, and ao2_unlock.

Referenced by bridgewait_exec().

00381 {
00382    if (!wrapper) {
00383       return;
00384    }
00385 
00386    ao2_lock(wait_bridge_wrappers);
00387    if (ao2_ref(wrapper, 0) == 2) {
00388       /* Either we have the only real reference or else wrapper isn't in the container anyway. */
00389       ao2_unlink(wait_bridge_wrappers, wrapper);
00390    }
00391    ao2_unlock(wait_bridge_wrappers);
00392 
00393    ao2_cleanup(wrapper);
00394 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Place the channel into a holding bridge application" , .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 514 of file app_bridgewait.c.

Definition at line 514 of file app_bridgewait.c.

struct ast_app_option bridgewait_opts[128] = { [ 'e' ] = { .flag = MUXFLAG_ENTERTAINMENT , .arg_index = OPT_ARG_ENTERTAINMENT + 1 }, [ 'm' ] = { .flag = MUXFLAG_MOHCLASS , .arg_index = OPT_ARG_MOHCLASS + 1 }, [ 'S' ] = { .flag = MUXFLAG_TIMEOUT , .arg_index = OPT_ARG_TIMEOUT + 1 },} [static]

Definition at line 204 of file app_bridgewait.c.

Referenced by bridgewait_exec().

Definition at line 121 of file app_bridgewait.c.


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