bridge_roles.c File Reference

Channel Bridging Roles API. More...

#include "asterisk.h"
#include <signal.h>
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/datastore.h"
#include "asterisk/linkedlists.h"
#include "asterisk/bridge.h"
#include "asterisk/bridge_roles.h"
#include "asterisk/stringfields.h"

Include dependency graph for bridge_roles.c:

Go to the source code of this file.

Data Structures

struct  bridge_role
struct  bridge_role_option
struct  bridge_roles_datastore

Functions

void ast_bridge_channel_clear_roles (struct ast_bridge_channel *bridge_channel)
 Clear all roles from a bridge_channel's role list.
int ast_bridge_channel_establish_roles (struct ast_bridge_channel *bridge_channel)
 Clone the roles from a bridge_channel's attached ast_channel onto the bridge_channel's role list.
const char * ast_bridge_channel_get_role_option (struct ast_bridge_channel *bridge_channel, const char *role_name, const char *option)
 Retrieve the value of a requested role option from a bridge channel.
int ast_bridge_channel_has_role (struct ast_bridge_channel *bridge_channel, const char *role_name)
 Check to see if a bridge channel inherited a specific role from its channel.
int ast_channel_add_bridge_role (struct ast_channel *chan, const char *role_name)
 Adds a bridge role to a channel.
void ast_channel_clear_bridge_roles (struct ast_channel *chan)
 Removes all bridge roles currently on a channel.
const char * ast_channel_get_role_option (struct ast_channel *channel, const char *role_name, const char *option)
 Retrieve the value of a requested role option from a channel.
int ast_channel_has_role (struct ast_channel *channel, const char *role_name)
 Check if a role exists on a channel.
void ast_channel_remove_bridge_role (struct ast_channel *chan, const char *role_name)
 Removes a bridge role from a channel.
int ast_channel_set_bridge_role_option (struct ast_channel *channel, const char *role_name, const char *option, const char *value)
 Set a role option on a channel.
static void bridge_role_datastore_destroy (void *data)
static void bridge_role_destroy (struct bridge_role *role)
static struct
bridge_roles_datastore
fetch_bridge_roles_datastore (struct ast_channel *chan)
static struct
bridge_roles_datastore
fetch_or_create_bridge_roles_datastore (struct ast_channel *chan)
static struct bridge_roleget_role_from_channel (struct ast_channel *channel, const char *role_name)
static struct bridge_roleget_role_from_datastore (struct bridge_roles_datastore *roles_datastore, const char *role_name)
static struct bridge_role_optionget_role_option (struct bridge_role *role, const char *option)
static int setup_bridge_role (struct bridge_roles_datastore *roles_datastore, const char *role_name)
static int setup_bridge_role_option (struct bridge_role *role, const char *option, const char *value)
static struct
bridge_roles_datastore
setup_bridge_roles_datastore (struct ast_channel *chan)

Variables

static struct ast_datastore_info bridge_role_info


Detailed Description

Channel Bridging Roles API.

Author:
Jonathan Rose <jrose@digium.com>

Definition in file bridge_roles.c.


Function Documentation

void ast_bridge_channel_clear_roles ( struct ast_bridge_channel bridge_channel  ) 

Clear all roles from a bridge_channel's role list.

Parameters:
bridge_channel the bridge channel that we are scrubbing
If roles are already established on a bridge channel, ast_bridge_channel_establish_roles will fail unconditionally without changing any roles. In order to update a bridge channel's roles, they must first be cleared from the bridge channel using this function.

Note:
ast_bridge_channel_clear_roles also serves as the destructor for the role list of a bridge channel.

Definition at line 493 of file bridge_roles.c.

References bridge_role_datastore_destroy(), ast_bridge_channel::bridge_roles, and NULL.

Referenced by agent_alert(), ast_bridge_channel_establish_roles(), and bridge_channel_internal_pull().

00494 {
00495    if (bridge_channel->bridge_roles) {
00496       bridge_role_datastore_destroy(bridge_channel->bridge_roles);
00497       bridge_channel->bridge_roles = NULL;
00498    }
00499 }

int ast_bridge_channel_establish_roles ( struct ast_bridge_channel bridge_channel  ) 

Clone the roles from a bridge_channel's attached ast_channel onto the bridge_channel's role list.

Parameters:
bridge_channel The bridge channel that we are preparing
Return values:
0 on success
-1 on failure
This function should always be called when the bridge_channel binds to an ast_channel at some point before the bridge_channel joins or is imparted onto a bridge. Failure to do so will result in an empty role list. While the list remains established, changes to roles on the ast_channel will not propogate to the bridge channel and roles can not be re-established on the bridge channel without first clearing the roles with ast_bridge_roles_bridge_channel_clear_roles.

Definition at line 445 of file bridge_roles.c.

References ast_bridge_channel_clear_roles(), ast_calloc, ast_debug, AST_LIST_LAST, AST_LIST_TRAVERSE, ast_bridge_channel::bridge_roles, ast_bridge_channel::chan, fetch_bridge_roles_datastore(), NULL, bridge_role_option::option, bridge_role::options, bridge_role::role, bridge_roles_datastore::role_list, setup_bridge_role(), setup_bridge_role_option(), and bridge_role_option::value.

Referenced by agent_alert(), and bridge_channel_internal_push().

00446 {
00447    struct bridge_roles_datastore *roles_datastore;
00448    struct bridge_role *role = NULL;
00449    struct bridge_role_option *role_option;
00450 
00451    if (!bridge_channel->chan) {
00452       ast_debug(2, "Attempted to set roles on a bridge channel that has no associated channel. That's a bad idea.\n");
00453       return -1;
00454    }
00455 
00456    if (bridge_channel->bridge_roles) {
00457       ast_debug(2, "Attempted to reset roles while roles were already established. Purge existing roles first.\n");
00458       return -1;
00459    }
00460 
00461    roles_datastore = fetch_bridge_roles_datastore(bridge_channel->chan);
00462    if (!roles_datastore) {
00463       /* No roles to establish. */
00464       return 0;
00465    }
00466 
00467    if (!(bridge_channel->bridge_roles = ast_calloc(1, sizeof(*bridge_channel->bridge_roles)))) {
00468       return -1;
00469    }
00470 
00471    AST_LIST_TRAVERSE(&roles_datastore->role_list, role, list) {
00472       struct bridge_role *this_role_copy;
00473 
00474       if (setup_bridge_role(bridge_channel->bridge_roles, role->role)) {
00475          /* We need to abandon the copy because we couldn't setup a role */
00476          ast_bridge_channel_clear_roles(bridge_channel);
00477          return -1;
00478       }
00479       this_role_copy = AST_LIST_LAST(&bridge_channel->bridge_roles->role_list);
00480 
00481       AST_LIST_TRAVERSE(&role->options, role_option, list) {
00482          if (setup_bridge_role_option(this_role_copy, role_option->option, role_option->value)) {
00483             /* We need to abandon the copy because we couldn't setup a role option */
00484             ast_bridge_channel_clear_roles(bridge_channel);
00485             return -1;
00486          }
00487       }
00488    }
00489 
00490    return 0;
00491 }

const char* ast_bridge_channel_get_role_option ( struct ast_bridge_channel bridge_channel,
const char *  role_name,
const char *  option 
)

Retrieve the value of a requested role option from a bridge channel.

Parameters:
bridge_channel The bridge channel we are retrieving the option from
role_name Name of the role the option will be retrieved from
option Name of the option we are retrieving the value of
Return values:
NULL If either the role does not exist on the bridge_channel or the role does exist but the option has not been set
The value of the option
Note:
See ast_channel_set_role_option note about the need to call ast_bridge_channel_establish_roles.

The returned character pointer is only valid as long as the bridge_channel is guaranteed to be alive and hasn't had ast_bridge_channel_clear_roles called against it (as this will free all roles and role options in the bridge channel). If you need this value after one of these destruction events occurs, you must make a local copy while it is still valid.

Definition at line 425 of file bridge_roles.c.

References ast_bridge_channel::bridge_roles, get_role_from_datastore(), get_role_option(), NULL, bridge_role::role, and bridge_role_option::value.

Referenced by bridge_parking_push(), participant_entertainment_start(), and participant_idle_mode_setup().

00426 {
00427    struct bridge_role *role;
00428    struct bridge_role_option *role_option = NULL;
00429 
00430    if (!bridge_channel->bridge_roles) {
00431       return NULL;
00432    }
00433 
00434    role = get_role_from_datastore(bridge_channel->bridge_roles, role_name);
00435 
00436    if (!role) {
00437       return NULL;
00438    }
00439 
00440    role_option = get_role_option(role, option);
00441 
00442    return role_option ? role_option->value : NULL;
00443 }

int ast_bridge_channel_has_role ( struct ast_bridge_channel bridge_channel,
const char *  role_name 
)

Check to see if a bridge channel inherited a specific role from its channel.

Parameters:
bridge_channel The bridge channel being checked
role_name Name of the role being checked
Return values:
0 The bridge channel does not have the requested role
1 The bridge channel does have the requested role
Note:
Before a bridge_channel can effectively check roles against a bridge, ast_bridge_channel_establish_roles should be called on the bridge_channel so that roles and their respective role options can be copied from the channel datastore into the bridge_channel roles list. Otherwise this function will just return 0 because the list will be NULL.

Definition at line 416 of file bridge_roles.c.

References ast_bridge_channel::bridge_roles, and get_role_from_datastore().

Referenced by bridge_parking_push(), and holding_bridge_join().

00417 {
00418    if (!bridge_channel->bridge_roles) {
00419       return 0;
00420    }
00421 
00422    return get_role_from_datastore(bridge_channel->bridge_roles, role_name) ? 1 : 0;
00423 }

int ast_channel_add_bridge_role ( struct ast_channel chan,
const char *  role_name 
)

Adds a bridge role to a channel.

Parameters:
chan Acquirer of the requested role
role_name Name of the role being attached
Return values:
0 on success
-1 on failure

Definition at line 315 of file bridge_roles.c.

References ast_channel_name(), ast_debug, ast_log, fetch_or_create_bridge_roles_datastore(), get_role_from_datastore(), LOG_WARNING, and setup_bridge_role().

Referenced by add_transferer_role(), announce_request(), bridge_agent_hold_push(), bridge_stasis_push(), media_request_helper(), parking_channel_set_roles(), process_options(), rec_request(), and stasis_app_control_add_role().

00316 {
00317    struct bridge_roles_datastore *roles_datastore = fetch_or_create_bridge_roles_datastore(chan);
00318 
00319    if (!roles_datastore) {
00320       ast_log(LOG_WARNING, "Unable to set up bridge role datastore on channel %s\n", ast_channel_name(chan));
00321       return -1;
00322    }
00323 
00324    /* Check to make sure we aren't adding a redundant role */
00325    if (get_role_from_datastore(roles_datastore, role_name)) {
00326       ast_debug(2, "Bridge role %s is already applied to the channel %s\n", role_name, ast_channel_name(chan));
00327       return 0;
00328    }
00329 
00330    /* It wasn't already there, so we can just finish setting it up now. */
00331    return setup_bridge_role(roles_datastore, role_name);
00332 }

void ast_channel_clear_bridge_roles ( struct ast_channel chan  ) 

Removes all bridge roles currently on a channel.

Parameters:
chan Channel the roles are being removed from

Definition at line 358 of file bridge_roles.c.

References ast_channel_name(), ast_debug, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, bridge_role_destroy(), fetch_bridge_roles_datastore(), bridge_role::role, and bridge_roles_datastore::role_list.

Referenced by bridge_stasis_pull(), and stasis_app_control_clear_roles().

00359 {
00360    struct bridge_roles_datastore *roles_datastore = fetch_bridge_roles_datastore(chan);
00361    struct bridge_role *role;
00362 
00363    if (!roles_datastore) {
00364       /* The roles datastore didn't already exist, so there is no need to remove any roles */
00365       ast_debug(2, "Roles did not exist on channel %s\n", ast_channel_name(chan));
00366       return;
00367    }
00368 
00369    AST_LIST_TRAVERSE_SAFE_BEGIN(&roles_datastore->role_list, role, list) {
00370       ast_debug(2, "Removing bridge role %s from channel %s\n", role->role, ast_channel_name(chan));
00371       AST_LIST_REMOVE_CURRENT(list);
00372       bridge_role_destroy(role);
00373    }
00374    AST_LIST_TRAVERSE_SAFE_END;
00375 }

const char* ast_channel_get_role_option ( struct ast_channel channel,
const char *  role_name,
const char *  option 
)

Retrieve the value of a requested role option from a channel.

Parameters:
channel The channel to retrieve the requested option from
role_name The role to which the option belongs
option The name of the option to retrieve
Return values:
NULL The option does not exist
non-NULL The value of the option
This is an alternative to ast_bridge_channel_get_role_option that is useful if bridge roles have not yet been esstablished on a channel's bridge_channel. A possible example of when this could be used is in a bridge v_table's push() callback.

Definition at line 401 of file bridge_roles.c.

References get_role_from_channel(), get_role_option(), NULL, bridge_role::role, and bridge_role_option::value.

Referenced by bridge_personality_atxfer_push().

00402 {
00403    struct bridge_role *role;
00404    struct bridge_role_option *role_option;
00405 
00406    role = get_role_from_channel(channel, role_name);
00407    if (!role) {
00408       return NULL;
00409    }
00410 
00411    role_option = get_role_option(role, option);
00412 
00413    return role_option ? role_option->value : NULL;
00414 }

int ast_channel_has_role ( struct ast_channel channel,
const char *  role_name 
)

Check if a role exists on a channel.

Parameters:
channel The channel to check
role_name The name of the role to search for
Return values:
0 The requested role does not exist on the channel
1 The requested role exists on the channel
This is an alternative to ast_bridge_channel_has_role that is useful if bridge roles have not yet been established on a channel's bridge_channel. A possible example of when this could be used is in a bridge v_table's push() callback.

Definition at line 396 of file bridge_roles.c.

References get_role_from_channel().

Referenced by bridge_personality_atxfer_push(), bridge_stasis_push(), and handle_hangup().

00397 {
00398    return get_role_from_channel(channel, role_name) ? 1 : 0;
00399 }

void ast_channel_remove_bridge_role ( struct ast_channel chan,
const char *  role_name 
)

Removes a bridge role from a channel.

Parameters:
chan Channel the role is being removed from
role_name Name of the role being removed

Definition at line 334 of file bridge_roles.c.

References ast_channel_name(), ast_debug, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, bridge_role_destroy(), fetch_bridge_roles_datastore(), bridge_role::role, and bridge_roles_datastore::role_list.

Referenced by attended_transfer_properties_shutdown(), bridge_agent_hold_pull(), and bridge_agent_hold_push().

00335 {
00336    struct bridge_roles_datastore *roles_datastore = fetch_bridge_roles_datastore(chan);
00337    struct bridge_role *role;
00338 
00339    if (!roles_datastore) {
00340       /* The roles datastore didn't already exist, so there is no need to remove a role */
00341       ast_debug(2, "Role %s did not exist on channel %s\n", role_name, ast_channel_name(chan));
00342       return;
00343    }
00344 
00345    AST_LIST_TRAVERSE_SAFE_BEGIN(&roles_datastore->role_list, role, list) {
00346       if (!strcmp(role->role, role_name)) {
00347          ast_debug(2, "Removing bridge role %s from channel %s\n", role_name, ast_channel_name(chan));
00348          AST_LIST_REMOVE_CURRENT(list);
00349          bridge_role_destroy(role);
00350          return;
00351       }
00352    }
00353    AST_LIST_TRAVERSE_SAFE_END;
00354 
00355    ast_debug(2, "Role %s did not exist on channel %s\n", role_name, ast_channel_name(chan));
00356 }

int ast_channel_set_bridge_role_option ( struct ast_channel channel,
const char *  role_name,
const char *  option,
const char *  value 
)

Set a role option on a channel.

Parameters:
channel Channel receiving the role option
role_name Role the role option is applied to
option Name of the option
value Value of the option
0 on success
Return values:
-1 on failure

Definition at line 377 of file bridge_roles.c.

References ast_string_field_set, get_role_from_channel(), get_role_option(), bridge_role::role, and setup_bridge_role_option().

Referenced by add_transferer_role(), agent_alert(), apply_option_entertainment(), apply_option_moh(), bridge_agent_hold_push(), bridge_stasis_push(), and parking_channel_set_roles().

00378 {
00379    struct bridge_role *role = get_role_from_channel(channel, role_name);
00380    struct bridge_role_option *role_option;
00381 
00382    if (!role) {
00383       return -1;
00384    }
00385 
00386    role_option = get_role_option(role, option);
00387 
00388    if (role_option) {
00389       ast_string_field_set(role_option, value, value);
00390       return 0;
00391    }
00392 
00393    return setup_bridge_role_option(role, option, value);
00394 }

static void bridge_role_datastore_destroy ( void *  data  )  [static]

Definition at line 92 of file bridge_roles.c.

References ast_free, AST_LIST_REMOVE_HEAD, bridge_role_destroy(), bridge_role::role, and bridge_roles_datastore::role_list.

Referenced by ast_bridge_channel_clear_roles().

00093 {
00094    struct bridge_roles_datastore *roles_datastore = data;
00095    struct bridge_role *role;
00096 
00097    while ((role = AST_LIST_REMOVE_HEAD(&roles_datastore->role_list, list))) {
00098       bridge_role_destroy(role);
00099    }
00100 
00101    ast_free(roles_datastore);
00102 }

static void bridge_role_destroy ( struct bridge_role role  )  [static]

Definition at line 73 of file bridge_roles.c.

References ast_free, AST_LIST_REMOVE_HEAD, and ast_string_field_free_memory.

Referenced by ast_channel_clear_bridge_roles(), ast_channel_remove_bridge_role(), and bridge_role_datastore_destroy().

00074 {
00075    struct bridge_role_option *role_option;
00076    while ((role_option = AST_LIST_REMOVE_HEAD(&role->options, list))) {
00077       ast_string_field_free_memory(role_option);
00078       ast_free(role_option);
00079    }
00080    ast_free(role);
00081 }

static struct bridge_roles_datastore* fetch_bridge_roles_datastore ( struct ast_channel chan  )  [static, read]

Definition at line 148 of file bridge_roles.c.

References ast_channel_datastore_find(), ast_channel_lock, ast_channel_unlock, ast_datastore::data, and NULL.

Referenced by ast_bridge_channel_establish_roles(), ast_channel_clear_bridge_roles(), ast_channel_remove_bridge_role(), fetch_or_create_bridge_roles_datastore(), and get_role_from_channel().

00149 {
00150    struct ast_datastore *datastore = NULL;
00151 
00152    ast_channel_lock(chan);
00153    if (!(datastore = ast_channel_datastore_find(chan, &bridge_role_info, NULL))) {
00154       ast_channel_unlock(chan);
00155       return NULL;
00156    }
00157    ast_channel_unlock(chan);
00158 
00159    return datastore->data;
00160 }

static struct bridge_roles_datastore* fetch_or_create_bridge_roles_datastore ( struct ast_channel chan  )  [static, read]

Definition at line 172 of file bridge_roles.c.

References ast_channel_lock, ast_channel_unlock, fetch_bridge_roles_datastore(), and setup_bridge_roles_datastore().

Referenced by ast_channel_add_bridge_role().

00173 {
00174    struct bridge_roles_datastore *roles_datastore;
00175 
00176    ast_channel_lock(chan);
00177    roles_datastore = fetch_bridge_roles_datastore(chan);
00178    if (!roles_datastore) {
00179       roles_datastore = setup_bridge_roles_datastore(chan);
00180    }
00181    ast_channel_unlock(chan);
00182 
00183    return roles_datastore;
00184 }

static struct bridge_role* get_role_from_channel ( struct ast_channel channel,
const char *  role_name 
) [static, read]

Definition at line 221 of file bridge_roles.c.

References fetch_bridge_roles_datastore(), get_role_from_datastore(), and NULL.

Referenced by ast_channel_get_role_option(), ast_channel_has_role(), and ast_channel_set_bridge_role_option().

00222 {
00223    struct bridge_roles_datastore *roles_datastore = fetch_bridge_roles_datastore(channel);
00224    return roles_datastore ? get_role_from_datastore(roles_datastore, role_name) : NULL;
00225 }

static struct bridge_role* get_role_from_datastore ( struct bridge_roles_datastore roles_datastore,
const char *  role_name 
) [static, read]

Definition at line 197 of file bridge_roles.c.

References AST_LIST_TRAVERSE, NULL, bridge_role::role, and bridge_roles_datastore::role_list.

Referenced by ast_bridge_channel_get_role_option(), ast_bridge_channel_has_role(), ast_channel_add_bridge_role(), and get_role_from_channel().

00198 {
00199    struct bridge_role *role;
00200 
00201    AST_LIST_TRAVERSE(&roles_datastore->role_list, role, list) {
00202       if (!strcmp(role->role, role_name)) {
00203          return role;
00204       }
00205    }
00206 
00207    return NULL;
00208 }

static struct bridge_role_option* get_role_option ( struct bridge_role role,
const char *  option 
) [static, read]

Definition at line 238 of file bridge_roles.c.

References AST_LIST_TRAVERSE, NULL, bridge_role_option::option, and bridge_role::options.

Referenced by ast_bridge_channel_get_role_option(), ast_channel_get_role_option(), and ast_channel_set_bridge_role_option().

00239 {
00240    struct bridge_role_option *role_option = NULL;
00241    AST_LIST_TRAVERSE(&role->options, role_option, list) {
00242       if (!strcmp(role_option->option, option)) {
00243          return role_option;
00244       }
00245    }
00246    return NULL;
00247 }

static int setup_bridge_role ( struct bridge_roles_datastore roles_datastore,
const char *  role_name 
) [static]

Definition at line 260 of file bridge_roles.c.

References ast_calloc, ast_copy_string(), ast_debug, AST_LIST_INSERT_TAIL, bridge_role::role, and bridge_roles_datastore::role_list.

Referenced by ast_bridge_channel_establish_roles(), and ast_channel_add_bridge_role().

00261 {
00262    struct bridge_role *role;
00263    role = ast_calloc(1, sizeof(*role));
00264 
00265    if (!role) {
00266       return -1;
00267    }
00268 
00269    ast_copy_string(role->role, role_name, sizeof(role->role));
00270 
00271    AST_LIST_INSERT_TAIL(&roles_datastore->role_list, role, list);
00272    ast_debug(3, "Set role '%s'\n", role_name);
00273 
00274    return 0;
00275 }

static int setup_bridge_role_option ( struct bridge_role role,
const char *  option,
const char *  value 
) [static]

Definition at line 289 of file bridge_roles.c.

References ast_calloc, ast_free, AST_LIST_INSERT_TAIL, ast_string_field_init, ast_string_field_set, and bridge_role::options.

Referenced by ast_bridge_channel_establish_roles(), and ast_channel_set_bridge_role_option().

00290 {
00291    struct bridge_role_option *role_option;
00292 
00293    if (!value) {
00294       value = "";
00295    }
00296 
00297    role_option = ast_calloc(1, sizeof(*role_option));
00298    if (!role_option) {
00299       return -1;
00300    }
00301 
00302    if (ast_string_field_init(role_option, 32)) {
00303       ast_free(role_option);
00304       return -1;
00305    }
00306 
00307    ast_string_field_set(role_option, option, option);
00308    ast_string_field_set(role_option, value, value);
00309 
00310    AST_LIST_INSERT_TAIL(&role->options, role_option, list);
00311 
00312    return 0;
00313 }

static struct bridge_roles_datastore* setup_bridge_roles_datastore ( struct ast_channel chan  )  [static, read]

Definition at line 119 of file bridge_roles.c.

References ast_calloc, ast_channel_datastore_add(), ast_datastore_alloc, ast_datastore_free(), ast_datastore::data, and NULL.

Referenced by fetch_or_create_bridge_roles_datastore().

00120 {
00121    struct ast_datastore *datastore = NULL;
00122    struct bridge_roles_datastore *roles_datastore = NULL;
00123 
00124    if (!(datastore = ast_datastore_alloc(&bridge_role_info, NULL))) {
00125       return NULL;
00126    }
00127 
00128    if (!(roles_datastore = ast_calloc(1, sizeof(*roles_datastore)))) {
00129       ast_datastore_free(datastore);
00130       return NULL;
00131    }
00132 
00133    datastore->data = roles_datastore;
00134    ast_channel_datastore_add(chan, datastore);
00135    return roles_datastore;
00136 }


Variable Documentation

Initial value:

 {
   .type = "bridge roles",
   .destroy = bridge_role_datastore_destroy,
}

Definition at line 104 of file bridge_roles.c.


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