[asterisk-commits] kmoore: branch kmoore/stasis-bridging-channel_events r386452 - in /team/kmoor...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed Apr 24 15:07:46 CDT 2013
Author: kmoore
Date: Wed Apr 24 15:07:42 2013
New Revision: 386452
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=386452
Log:
Multiple revisions 386353,386377,386400-386401,386410,386422
........
r386353 | root | 2013-04-23 14:17:23 -0500 (Tue, 23 Apr 2013) | 7 lines
Fix some bad whitespace
This crept in with the RESTful HTTP interface merge.
........
Merged revisions 386352 from file:///srv/subversion/repos/asterisk/trunk
........
r386377 | root | 2013-04-23 16:17:20 -0500 (Tue, 23 Apr 2013) | 12 lines
confbridge: Make search the conference bridges container using OBJ_KEY.
* Make confbridge config parsing user profile, bridge profile, and menu
container hash/cmp functions correctly check the OBJ_POINTER, OBJ_KEY, and
OBJ_PARTIAL_KEY flags.
* Made confbridge load_module()/unload_module() free all resources on
failure conditions.
........
Merged revisions 386375 from file:///srv/subversion/repos/asterisk/trunk
........
r386400 | rmudgett | 2013-04-23 17:46:42 -0500 (Tue, 23 Apr 2013) | 2 lines
Make the bridge custom_play function a typdef that also takes a bridge_channel pointer.
........
r386401 | mmichelson | 2013-04-23 17:56:53 -0500 (Tue, 23 Apr 2013) | 3 lines
Add a function to get the channels belonging to a bridge.
........
r386410 | rmudgett | 2013-04-23 19:10:24 -0500 (Tue, 23 Apr 2013) | 4 lines
* Make container of ast_bridge_peers() searchable by OBJ_PARTIAL_KEY and not have a lock.
* Add ast_bridge_peers_nolock().
........
r386422 | rmudgett | 2013-04-24 12:08:30 -0500 (Wed, 24 Apr 2013) | 4 lines
* Make bridge_channel_push() return a failure status.
* Remove the can_push bridge method. It was not that useful.
........
Merged revisions 386353,386377,386400-386401,386410,386422 from http://svn.asterisk.org/svn/asterisk/team/group/bridge_construction
Modified:
team/kmoore/stasis-bridging-channel_events/ (props changed)
team/kmoore/stasis-bridging-channel_events/apps/app_confbridge.c
team/kmoore/stasis-bridging-channel_events/apps/confbridge/conf_config_parser.c
team/kmoore/stasis-bridging-channel_events/include/asterisk/bridging.h
team/kmoore/stasis-bridging-channel_events/main/bridging.c
team/kmoore/stasis-bridging-channel_events/res/res_stasis.c
Propchange: team/kmoore/stasis-bridging-channel_events/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Wed Apr 24 15:07:42 2013
@@ -1,1 +1,1 @@
-/team/group/bridge_construction:1-386332
+/team/group/bridge_construction:1-386451
Modified: team/kmoore/stasis-bridging-channel_events/apps/app_confbridge.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/stasis-bridging-channel_events/apps/app_confbridge.c?view=diff&rev=386452&r1=386451&r2=386452
==============================================================================
--- team/kmoore/stasis-bridging-channel_events/apps/app_confbridge.c (original)
+++ team/kmoore/stasis-bridging-channel_events/apps/app_confbridge.c Wed Apr 24 15:07:42 2013
@@ -317,14 +317,47 @@
static int conference_bridge_hash_cb(const void *obj, const int flags)
{
const struct confbridge_conference *conference = obj;
- return ast_str_case_hash(conference->name);
+ const char *name = obj;
+ int hash;
+
+ switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
+ default:
+ case OBJ_POINTER:
+ name = conference->name;
+ /* Fall through */
+ case OBJ_KEY:
+ hash = ast_str_case_hash(name);
+ break;
+ case OBJ_PARTIAL_KEY:
+ /* Should never happen in hash callback. */
+ ast_assert(0);
+ hash = 0;
+ break;
+ }
+ return hash;
}
/*! \brief Comparison function used for conference bridges container */
static int conference_bridge_cmp_cb(void *obj, void *arg, int flags)
{
- const struct confbridge_conference *conference0 = obj, *conference1 = arg;
- return (!strcasecmp(conference0->name, conference1->name) ? CMP_MATCH | CMP_STOP : 0);
+ const struct confbridge_conference *left = obj;
+ const struct confbridge_conference *right = arg;
+ const char *right_name = arg;
+ int cmp;
+
+ switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
+ default:
+ case OBJ_POINTER:
+ right_name = right->name;
+ /* Fall through */
+ case OBJ_KEY:
+ cmp = strcasecmp(left->name, right_name);
+ break;
+ case OBJ_PARTIAL_KEY:
+ cmp = strncasecmp(left->name, right_name, strlen(right_name));
+ break;
+ }
+ return cmp ? 0 : CMP_MATCH;
}
const char *conf_get_sound(enum conf_sounds sound, struct bridge_profile_sounds *custom_sounds)
@@ -1241,12 +1274,9 @@
*/
static struct confbridge_conference *join_conference_bridge(const char *conference_name, struct confbridge_user *user)
{
- struct confbridge_conference *conference = NULL;
+ struct confbridge_conference *conference;
struct post_join_action *action;
- struct confbridge_conference tmp;
int max_members_reached = 0;
-
- ast_copy_string(tmp.name, conference_name, sizeof(tmp.name));
/* We explictly lock the conference bridges container ourselves so that other callers can not create duplicate conferences at the same */
ao2_lock(conference_bridges);
@@ -1254,8 +1284,7 @@
ast_debug(1, "Trying to find conference bridge '%s'\n", conference_name);
/* Attempt to find an existing conference bridge */
- conference = ao2_find(conference_bridges, &tmp, OBJ_POINTER);
-
+ conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
if (conference && conference->b_profile.max_members) {
max_members_reached = conference->b_profile.max_members > conference->activeusers ? 0 : 1;
}
@@ -2231,7 +2260,7 @@
static char *complete_confbridge_name(const char *line, const char *word, int pos, int state)
{
int which = 0;
- struct confbridge_conference *conference = NULL;
+ struct confbridge_conference *conference;
char *res = NULL;
int wordlen = strlen(word);
struct ao2_iterator iter;
@@ -2250,17 +2279,15 @@
return res;
}
-static char *complete_confbridge_participant(const char *bridge_name, const char *line, const char *word, int pos, int state)
+static char *complete_confbridge_participant(const char *conference_name, const char *line, const char *word, int pos, int state)
{
int which = 0;
RAII_VAR(struct confbridge_conference *, conference, NULL, ao2_cleanup);
- struct confbridge_conference tmp;
struct confbridge_user *user;
char *res = NULL;
int wordlen = strlen(word);
- ast_copy_string(tmp.name, bridge_name, sizeof(tmp.name));
- conference = ao2_find(conference_bridges, &tmp, OBJ_POINTER);
+ conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
if (!conference) {
return NULL;
}
@@ -2286,8 +2313,7 @@
static char *handle_cli_confbridge_kick(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
- struct confbridge_conference *conference = NULL;
- struct confbridge_conference tmp;
+ struct confbridge_conference *conference;
switch (cmd) {
case CLI_INIT:
@@ -2310,8 +2336,7 @@
return CLI_SHOWUSAGE;
}
- ast_copy_string(tmp.name, a->argv[2], sizeof(tmp.name));
- conference = ao2_find(conference_bridges, &tmp, OBJ_POINTER);
+ conference = ao2_find(conference_bridges, a->argv[2], OBJ_KEY);
if (!conference) {
ast_cli(a->fd, "No conference bridge named '%s' found!\n", a->argv[2]);
return CLI_SUCCESS;
@@ -2401,10 +2426,8 @@
if (a->argc == 3) {
struct confbridge_user *user;
- struct confbridge_conference tmp;
-
- ast_copy_string(tmp.name, a->argv[2], sizeof(tmp.name));
- conference = ao2_find(conference_bridges, &tmp, OBJ_POINTER);
+
+ conference = ao2_find(conference_bridges, a->argv[2], OBJ_KEY);
if (!conference) {
ast_cli(a->fd, "No conference bridge named '%s' found!\n", a->argv[2]);
return CLI_SUCCESS;
@@ -2434,12 +2457,10 @@
*/
static int generic_lock_unlock_helper(int lock, const char *conference_name)
{
- struct confbridge_conference *conference = NULL;
- struct confbridge_conference tmp;
+ struct confbridge_conference *conference;
int res = 0;
- ast_copy_string(tmp.name, conference_name, sizeof(tmp.name));
- conference = ao2_find(conference_bridges, &tmp, OBJ_POINTER);
+ conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
if (!conference) {
return -1;
}
@@ -2461,12 +2482,11 @@
*/
static int generic_mute_unmute_helper(int mute, const char *conference_name, const char *chan_name)
{
- struct confbridge_conference *conference = NULL;
- struct confbridge_conference tmp;
- struct confbridge_user *user = NULL;
+ struct confbridge_conference *conference;
+ struct confbridge_user *user;
int res = 0;
- ast_copy_string(tmp.name, conference_name, sizeof(tmp.name));
- conference = ao2_find(conference_bridges, &tmp, OBJ_POINTER);
+
+ conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
if (!conference) {
return -1;
}
@@ -2613,8 +2633,7 @@
static char *handle_cli_confbridge_start_record(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
const char *rec_file = NULL;
- struct confbridge_conference *conference = NULL;
- struct confbridge_conference tmp;
+ struct confbridge_conference *conference;
switch (cmd) {
case CLI_INIT:
@@ -2639,8 +2658,7 @@
rec_file = a->argv[4];
}
- ast_copy_string(tmp.name, a->argv[3], sizeof(tmp.name));
- conference = ao2_find(conference_bridges, &tmp, OBJ_POINTER);
+ conference = ao2_find(conference_bridges, a->argv[3], OBJ_KEY);
if (!conference) {
ast_cli(a->fd, "Conference not found.\n");
return CLI_FAILURE;
@@ -2671,8 +2689,7 @@
static char *handle_cli_confbridge_stop_record(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
- struct confbridge_conference *conference = NULL;
- struct confbridge_conference tmp;
+ struct confbridge_conference *conference;
int ret;
switch (cmd) {
@@ -2692,8 +2709,7 @@
return CLI_SHOWUSAGE;
}
- ast_copy_string(tmp.name, a->argv[3], sizeof(tmp.name));
- conference = ao2_find(conference_bridges, &tmp, OBJ_POINTER);
+ conference = ao2_find(conference_bridges, a->argv[3], OBJ_KEY);
if (!conference) {
ast_cli(a->fd, "Conference not found.\n");
return CLI_SUCCESS;
@@ -2760,7 +2776,6 @@
const char *conference_name = astman_get_header(m, "Conference");
struct confbridge_user *user;
struct confbridge_conference *conference;
- struct confbridge_conference tmp;
char id_text[80];
int total = 0;
@@ -2776,8 +2791,7 @@
astman_send_error(s, m, "No active conferences.");
return 0;
}
- ast_copy_string(tmp.name, conference_name, sizeof(tmp.name));
- conference = ao2_find(conference_bridges, &tmp, OBJ_POINTER);
+ conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
if (!conference) {
astman_send_error(s, m, "No Conference by that name found.");
return 0;
@@ -2810,7 +2824,7 @@
static int action_confbridgelistrooms(struct mansession *s, const struct message *m)
{
const char *actionid = astman_get_header(m, "ActionID");
- struct confbridge_conference *conference = NULL;
+ struct confbridge_conference *conference;
struct ao2_iterator iter;
char id_text[512] = "";
int totalitems = 0;
@@ -2936,8 +2950,7 @@
{
const char *conference_name = astman_get_header(m, "Conference");
const char *channel = astman_get_header(m, "Channel");
- struct confbridge_conference *conference = NULL;
- struct confbridge_conference tmp;
+ struct confbridge_conference *conference;
int found = 0;
if (ast_strlen_zero(conference_name)) {
@@ -2949,8 +2962,7 @@
return 0;
}
- ast_copy_string(tmp.name, conference_name, sizeof(tmp.name));
- conference = ao2_find(conference_bridges, &tmp, OBJ_POINTER);
+ conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
if (!conference) {
astman_send_error(s, m, "No Conference by that name found.");
return 0;
@@ -2971,8 +2983,7 @@
{
const char *conference_name = astman_get_header(m, "Conference");
const char *recordfile = astman_get_header(m, "RecordFile");
- struct confbridge_conference *conference = NULL;
- struct confbridge_conference tmp;
+ struct confbridge_conference *conference;
if (ast_strlen_zero(conference_name)) {
astman_send_error(s, m, "No Conference name provided.");
@@ -2983,8 +2994,7 @@
return 0;
}
- ast_copy_string(tmp.name, conference_name, sizeof(tmp.name));
- conference = ao2_find(conference_bridges, &tmp, OBJ_POINTER);
+ conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
if (!conference) {
astman_send_error(s, m, "No Conference by that name found.");
return 0;
@@ -3017,8 +3027,7 @@
static int action_confbridgestoprecord(struct mansession *s, const struct message *m)
{
const char *conference_name = astman_get_header(m, "Conference");
- struct confbridge_conference *conference = NULL;
- struct confbridge_conference tmp;
+ struct confbridge_conference *conference;
if (ast_strlen_zero(conference_name)) {
astman_send_error(s, m, "No Conference name provided.");
@@ -3029,8 +3038,7 @@
return 0;
}
- ast_copy_string(tmp.name, conference_name, sizeof(tmp.name));
- conference = ao2_find(conference_bridges, &tmp, OBJ_POINTER);
+ conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
if (!conference) {
astman_send_error(s, m, "No Conference by that name found.");
return 0;
@@ -3054,9 +3062,8 @@
{
const char *conference_name = astman_get_header(m, "Conference");
const char *channel = astman_get_header(m, "Channel");
- struct confbridge_user *user = NULL;
- struct confbridge_conference *conference = NULL;
- struct confbridge_conference tmp;
+ struct confbridge_user *user;
+ struct confbridge_conference *conference;
if (ast_strlen_zero(conference_name)) {
astman_send_error(s, m, "No Conference name provided.");
@@ -3071,8 +3078,7 @@
return 0;
}
- ast_copy_string(tmp.name, conference_name, sizeof(tmp.name));
- conference = ao2_find(conference_bridges, &tmp, OBJ_POINTER);
+ conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
if (!conference) {
astman_send_error(s, m, "No Conference by that name found.");
return 0;
@@ -3101,10 +3107,9 @@
static int func_confbridge_info(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
{
- char *parse = NULL;
- struct confbridge_conference *conference = NULL;
- struct confbridge_user *user = NULL;
- struct confbridge_conference tmp;
+ char *parse;
+ struct confbridge_conference *conference;
+ struct confbridge_user *user;
int count = 0;
AST_DECLARE_APP_ARGS(args,
AST_APP_ARG(type);
@@ -3120,12 +3125,7 @@
if (ast_strlen_zero(args.confno) || ast_strlen_zero(args.type)) {
return -1;
}
- if (!ao2_container_count(conference_bridges)) {
- snprintf(buf, len, "0");
- return 0;
- }
- ast_copy_string(tmp.name, args.confno, sizeof(tmp.name));
- conference = ao2_find(conference_bridges, &tmp, OBJ_POINTER);
+ conference = ao2_find(conference_bridges, args.confno, OBJ_KEY);
if (!conference) {
snprintf(buf, len, "0");
return 0;
@@ -3216,33 +3216,34 @@
/*! \brief Called when module is being unloaded */
static int unload_module(void)
{
- int res = ast_unregister_application(app);
+ ast_unregister_application(app);
ast_custom_function_unregister(&confbridge_function);
ast_custom_function_unregister(&confbridge_info_function);
- ast_cli_unregister_multiple(cli_confbridge, sizeof(cli_confbridge) / sizeof(struct ast_cli_entry));
+ ast_cli_unregister_multiple(cli_confbridge, ARRAY_LEN(cli_confbridge));
+
+ ast_manager_unregister("ConfbridgeList");
+ ast_manager_unregister("ConfbridgeListRooms");
+ ast_manager_unregister("ConfbridgeMute");
+ ast_manager_unregister("ConfbridgeUnmute");
+ ast_manager_unregister("ConfbridgeKick");
+ ast_manager_unregister("ConfbridgeUnlock");
+ ast_manager_unregister("ConfbridgeLock");
+ ast_manager_unregister("ConfbridgeStartRecord");
+ ast_manager_unregister("ConfbridgeStopRecord");
+ ast_manager_unregister("ConfbridgeSetSingleVideoSrc");
/* Get rid of the conference bridges container. Since we only allow dynamic ones none will be active. */
- ao2_ref(conference_bridges, -1);
+ ao2_cleanup(conference_bridges);
+ conference_bridges = NULL;
conf_destroy_config();
ast_channel_unregister(&record_tech);
record_tech.capabilities = ast_format_cap_destroy(record_tech.capabilities);
- res |= ast_manager_unregister("ConfbridgeList");
- res |= ast_manager_unregister("ConfbridgeListRooms");
- res |= ast_manager_unregister("ConfbridgeMute");
- res |= ast_manager_unregister("ConfbridgeUnmute");
- res |= ast_manager_unregister("ConfbridgeKick");
- res |= ast_manager_unregister("ConfbridgeUnlock");
- res |= ast_manager_unregister("ConfbridgeLock");
- res |= ast_manager_unregister("ConfbridgeStartRecord");
- res |= ast_manager_unregister("ConfbridgeStopRecord");
- res |= ast_manager_unregister("ConfbridgeSetSingleVideoSrc");
-
- return res;
+ return 0;
}
/*!
@@ -3263,30 +3264,33 @@
ast_log(LOG_ERROR, "Unable to load config. Not loading module.\n");
return AST_MODULE_LOAD_DECLINE;
}
- if ((ast_custom_function_register(&confbridge_function))) {
- return AST_MODULE_LOAD_FAILURE;
- }
- if ((ast_custom_function_register(&confbridge_info_function))) {
- return AST_MODULE_LOAD_FAILURE;
- }
+
if (!(record_tech.capabilities = ast_format_cap_alloc())) {
+ unload_module();
return AST_MODULE_LOAD_FAILURE;
}
ast_format_cap_add_all(record_tech.capabilities);
if (ast_channel_register(&record_tech)) {
ast_log(LOG_ERROR, "Unable to register ConfBridge recorder.\n");
+ unload_module();
return AST_MODULE_LOAD_FAILURE;
}
+
/* Create a container to hold the conference bridges */
- if (!(conference_bridges = ao2_container_alloc(CONFERENCE_BRIDGE_BUCKETS, conference_bridge_hash_cb, conference_bridge_cmp_cb))) {
+ conference_bridges = ao2_container_alloc(CONFERENCE_BRIDGE_BUCKETS,
+ conference_bridge_hash_cb, conference_bridge_cmp_cb);
+ if (!conference_bridges) {
+ unload_module();
return AST_MODULE_LOAD_FAILURE;
}
- if (ast_register_application_xml(app, confbridge_exec)) {
- ao2_ref(conference_bridges, -1);
- return AST_MODULE_LOAD_FAILURE;
- }
-
- res |= ast_cli_register_multiple(cli_confbridge, sizeof(cli_confbridge) / sizeof(struct ast_cli_entry));
+
+ res |= ast_register_application_xml(app, confbridge_exec);
+
+ res |= ast_custom_function_register(&confbridge_function);
+ res |= ast_custom_function_register(&confbridge_info_function);
+
+ res |= ast_cli_register_multiple(cli_confbridge, ARRAY_LEN(cli_confbridge));
+
res |= ast_manager_register_xml("ConfbridgeList", EVENT_FLAG_REPORTING, action_confbridgelist);
res |= ast_manager_register_xml("ConfbridgeListRooms", EVENT_FLAG_REPORTING, action_confbridgelistrooms);
res |= ast_manager_register_xml("ConfbridgeMute", EVENT_FLAG_CALL, action_confbridgemute);
@@ -3298,6 +3302,7 @@
res |= ast_manager_register_xml("ConfbridgeStopRecord", EVENT_FLAG_CALL, action_confbridgestoprecord);
res |= ast_manager_register_xml("ConfbridgeSetSingleVideoSrc", EVENT_FLAG_CALL, action_confbridgesetsinglevideosrc);
if (res) {
+ unload_module();
return AST_MODULE_LOAD_FAILURE;
}
Modified: team/kmoore/stasis-bridging-channel_events/apps/confbridge/conf_config_parser.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/stasis-bridging-channel_events/apps/confbridge/conf_config_parser.c?view=diff&rev=386452&r1=386451&r2=386452
==============================================================================
--- team/kmoore/stasis-bridging-channel_events/apps/confbridge/conf_config_parser.c (original)
+++ team/kmoore/stasis-bridging-channel_events/apps/confbridge/conf_config_parser.c Wed Apr 24 15:07:42 2013
@@ -648,32 +648,95 @@
/*! bridge profile container functions */
static int bridge_cmp_cb(void *obj, void *arg, int flags)
{
- const struct bridge_profile *entry1 = obj, *entry2 = arg;
- const char *name = arg;
- return (!strcasecmp(entry1->name, flags & OBJ_KEY ? name : entry2->name)) ?
- CMP_MATCH | CMP_STOP : 0;
-}
+ const struct bridge_profile *left = obj;
+ const struct bridge_profile *right = arg;
+ const char *right_name = arg;
+ int cmp;
+
+ switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
+ default:
+ case OBJ_POINTER:
+ right_name = right->name;
+ /* Fall through */
+ case OBJ_KEY:
+ cmp = strcasecmp(left->name, right_name);
+ break;
+ case OBJ_PARTIAL_KEY:
+ cmp = strncasecmp(left->name, right_name, strlen(right_name));
+ break;
+ }
+ return cmp ? 0 : CMP_MATCH;
+}
+
static int bridge_hash_cb(const void *obj, const int flags)
{
const struct bridge_profile *b_profile = obj;
const char *name = obj;
- return ast_str_case_hash(flags & OBJ_KEY ? name : b_profile->name);
+ int hash;
+
+ switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
+ default:
+ case OBJ_POINTER:
+ name = b_profile->name;
+ /* Fall through */
+ case OBJ_KEY:
+ hash = ast_str_case_hash(name);
+ break;
+ case OBJ_PARTIAL_KEY:
+ /* Should never happen in hash callback. */
+ ast_assert(0);
+ hash = 0;
+ break;
+ }
+ return hash;
}
/*! menu container functions */
static int menu_cmp_cb(void *obj, void *arg, int flags)
{
- const struct conf_menu *entry1 = obj, *entry2 = arg;
- const char *name = arg;
- return (!strcasecmp(entry1->name, flags & OBJ_KEY ? name : entry2->name)) ?
- CMP_MATCH | CMP_STOP : 0;
-}
+ const struct conf_menu *left = obj;
+ const struct conf_menu *right = arg;
+ const char *right_name = arg;
+ int cmp;
+
+ switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
+ default:
+ case OBJ_POINTER:
+ right_name = right->name;
+ /* Fall through */
+ case OBJ_KEY:
+ cmp = strcasecmp(left->name, right_name);
+ break;
+ case OBJ_PARTIAL_KEY:
+ cmp = strncasecmp(left->name, right_name, strlen(right_name));
+ break;
+ }
+ return cmp ? 0 : CMP_MATCH;
+}
+
static int menu_hash_cb(const void *obj, const int flags)
{
const struct conf_menu *menu = obj;
const char *name = obj;
- return ast_str_case_hash(flags & OBJ_KEY ? name : menu->name);
-}
+ int hash;
+
+ switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
+ default:
+ case OBJ_POINTER:
+ name = menu->name;
+ /* Fall through */
+ case OBJ_KEY:
+ hash = ast_str_case_hash(name);
+ break;
+ case OBJ_PARTIAL_KEY:
+ /* Should never happen in hash callback. */
+ ast_assert(0);
+ hash = 0;
+ break;
+ }
+ return hash;
+}
+
static void menu_destructor(void *obj)
{
struct conf_menu *menu = obj;
@@ -688,16 +751,47 @@
/*! User profile container functions */
static int user_cmp_cb(void *obj, void *arg, int flags)
{
- const struct user_profile *entry1 = obj, *entry2 = arg;
- const char *name = arg;
- return (!strcasecmp(entry1->name, flags & OBJ_KEY ? name : entry2->name)) ?
- CMP_MATCH | CMP_STOP : 0;
-}
+ const struct user_profile *left = obj;
+ const struct user_profile *right = arg;
+ const char *right_name = arg;
+ int cmp;
+
+ switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
+ default:
+ case OBJ_POINTER:
+ right_name = right->name;
+ /* Fall through */
+ case OBJ_KEY:
+ cmp = strcasecmp(left->name, right_name);
+ break;
+ case OBJ_PARTIAL_KEY:
+ cmp = strncasecmp(left->name, right_name, strlen(right_name));
+ break;
+ }
+ return cmp ? 0 : CMP_MATCH;
+}
+
static int user_hash_cb(const void *obj, const int flags)
{
const struct user_profile *u_profile = obj;
const char *name = obj;
- return ast_str_case_hash(flags & OBJ_KEY ? name : u_profile->name);
+ int hash;
+
+ switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
+ default:
+ case OBJ_POINTER:
+ name = u_profile->name;
+ /* Fall through */
+ case OBJ_KEY:
+ hash = ast_str_case_hash(name);
+ break;
+ case OBJ_PARTIAL_KEY:
+ /* Should never happen in hash callback. */
+ ast_assert(0);
+ hash = 0;
+ break;
+ }
+ return hash;
}
/*! Bridge Profile Sounds functions */
Modified: team/kmoore/stasis-bridging-channel_events/include/asterisk/bridging.h
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/stasis-bridging-channel_events/include/asterisk/bridging.h?view=diff&rev=386452&r1=386451&r2=386452
==============================================================================
--- team/kmoore/stasis-bridging-channel_events/include/asterisk/bridging.h (original)
+++ team/kmoore/stasis-bridging-channel_events/include/asterisk/bridging.h Wed Apr 24 15:07:42 2013
@@ -296,19 +296,6 @@
typedef void (*ast_bridge_dissolving_fn)(struct ast_bridge *self);
/*!
- * \brief Can this channel be pushed into the bridge.
- *
- * \param self Bridge to operate upon.
- * \param bridge_channel Bridge channel wanting to push.
- * \param swap Bridge channel to swap places with if not NULL.
- *
- * \note On entry, self is already locked.
- *
- * \retval TRUE if can push this channel into the bridge.
- */
-typedef int (*ast_bridge_can_push_channel_fn)(struct ast_bridge *self, struct ast_bridge_channel *bridge_channel, struct ast_bridge_channel *swap);
-
-/*!
* \brief Push this channel into the bridge.
*
* \param self Bridge to operate upon.
@@ -323,8 +310,8 @@
*
* \note On entry, self is already locked.
*
- * \retval 0 on success
- * \retval -1 on failure
+ * \retval 0 on success.
+ * \retval -1 on failure. The channel did not get pushed.
*/
typedef int (*ast_bridge_push_channel_fn)(struct ast_bridge *self, struct ast_bridge_channel *bridge_channel, struct ast_bridge_channel *swap);
@@ -374,8 +361,6 @@
ast_bridge_destructor_fn destroy;
/*! The bridge is being dissolved. Remove any references to the bridge. */
ast_bridge_dissolving_fn dissolving;
- /*! TRUE if can push the bridge channel into the bridge. */
- ast_bridge_can_push_channel_fn can_push;
/*! Push the bridge channel into the bridge. */
ast_bridge_push_channel_fn push;
/*! Pull the bridge channel from the bridge. */
@@ -1096,6 +1081,16 @@
void ast_bridge_channel_queue_app(struct ast_bridge_channel *bridge_channel, const char *app_name, const char *app_args, const char *moh_class);
/*!
+ * \brief Custom interpretation of the playfile name.
+ *
+ * \param bridge_channel Which channel to play the file on
+ * \param playfile Sound filename to play.
+ *
+ * \return Nothing
+ */
+typedef void (*ast_bridge_custom_play_fn)(struct ast_bridge_channel *bridge_channel, const char *playfile);
+
+/*!
* \brief Play a file on the bridge channel.
* \since 12.0.0
*
@@ -1110,7 +1105,7 @@
*
* \return Nothing
*/
-void ast_bridge_channel_playfile(struct ast_bridge_channel *bridge_channel, void (*custom_play)(const char *playfile), const char *playfile, const char *moh_class);
+void ast_bridge_channel_playfile(struct ast_bridge_channel *bridge_channel, ast_bridge_custom_play_fn custom_play, const char *playfile, const char *moh_class);
/*!
* \brief Write a bridge action play file frame into the bridge.
@@ -1127,7 +1122,7 @@
*
* \return Nothing
*/
-void ast_bridge_channel_write_playfile(struct ast_bridge_channel *bridge_channel, void (*custom_play)(const char *playfile), const char *playfile, const char *moh_class);
+void 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);
/*!
* \brief Queue a bridge action play file frame onto the bridge channel.
@@ -1144,7 +1139,7 @@
*
* \return Nothing
*/
-void ast_bridge_channel_queue_playfile(struct ast_bridge_channel *bridge_channel, void (*custom_play)(const char *playfile), const char *playfile, const char *moh_class);
+void 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);
/*!
* \brief Restore the formats of a bridge channel's channel to how they were before bridge_channel_join
@@ -1306,6 +1301,31 @@
*/
void ast_after_bridge_goto_discard(struct ast_channel *chan);
+/*!
+ * \brief Get a container of all channels in the bridge
+ * \since 12.0.0
+ *
+ * \param bridge The bridge which is already locked.
+ *
+ * \retval NULL Failed to create container
+ * \retval non-NULL Container of channels in the bridge
+ */
+struct ao2_container *ast_bridge_peers_nolock(struct ast_bridge *bridge);
+
+/*!
+ * \brief Get a container of all channels in the bridge
+ * \since 12.0.0
+ *
+ * \param bridge The bridge
+ *
+ * \note The returned container is a snapshot of channels in the
+ * bridge when called.
+ *
+ * \retval NULL Failed to create container
+ * \retval non-NULL Container of channels in the bridge
+ */
+struct ao2_container *ast_bridge_peers(struct ast_bridge *bridge);
+
#if defined(__cplusplus) || defined(c_plusplus)
}
#endif
Modified: team/kmoore/stasis-bridging-channel_events/main/bridging.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/stasis-bridging-channel_events/main/bridging.c?view=diff&rev=386452&r1=386451&r2=386452
==============================================================================
--- team/kmoore/stasis-bridging-channel_events/main/bridging.c (original)
+++ team/kmoore/stasis-bridging-channel_events/main/bridging.c Wed Apr 24 15:07:42 2013
@@ -537,36 +537,18 @@
*
* \note On entry, bridge_channel->bridge is already locked.
*
- * \return Nothing
- */
-static void bridge_channel_push(struct ast_bridge_channel *bridge_channel)
+ * \retval 0 on success.
+ * \retval -1 on failure. The channel did not get pushed.
+ */
+static int bridge_channel_push(struct ast_bridge_channel *bridge_channel)
{
struct ast_bridge *bridge = bridge_channel->bridge;
struct ast_bridge_channel *swap;
- int chan_leaving;
ast_assert(!bridge_channel->in_bridge);
swap = find_bridge_channel(bridge, bridge_channel->swap);
bridge_channel->swap = NULL;
-
- chan_leaving = bridge->dissolved
- || !bridge->v_table->can_push(bridge, bridge_channel, swap);
-
- ast_bridge_channel_lock(bridge_channel);
- if (chan_leaving) {
- /*
- * Force out channel being pushed into a dissolved bridge or it
- * is not allowed into the bridge.
- */
- ast_bridge_change_state_nolock(bridge_channel, AST_BRIDGE_CHANNEL_STATE_HANGUP);
- }
- chan_leaving = bridge_channel->state != AST_BRIDGE_CHANNEL_STATE_WAIT;
- ast_bridge_channel_unlock(bridge_channel);
- if (chan_leaving) {
- /* Don't push a channel in the process of leaving. */
- return;
- }
if (swap) {
ast_debug(1, "Bridge %s: pushing %p(%s) by swapping with %p(%s)\n",
@@ -578,11 +560,12 @@
}
/* Add channel to the bridge */
- if (bridge->v_table->push(bridge, bridge_channel, swap)) {
- ast_log(LOG_ERROR, "Bridge %s: failed to push channel %s into bridge\n",
- bridge->uniqueid, ast_channel_name(bridge_channel->chan));
- ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_HANGUP);
- return;
+ if (bridge->dissolved
+ || bridge_channel->state != AST_BRIDGE_CHANNEL_STATE_WAIT
+ || bridge->v_table->push(bridge, bridge_channel, swap)) {
+ ast_debug(1, "Bridge %s: pushing %p(%s) into bridge failed\n",
+ bridge->uniqueid, bridge_channel, ast_channel_name(bridge_channel->chan));
+ return -1;
}
bridge_channel->in_bridge = 1;
bridge_channel->just_joined = 1;
@@ -598,6 +581,7 @@
bridge->reconfigured = 1;
ast_bridge_publish_enter(bridge, bridge_channel->chan);
+ return 0;
}
/*! \brief Internal function to handle DTMF from a channel */
@@ -827,7 +811,7 @@
bridge_channel, app_name, app_args, moh_class);
}
-void ast_bridge_channel_playfile(struct ast_bridge_channel *bridge_channel, void (*custom_play)(const char *playfile), const char *playfile, const char *moh_class)
+void ast_bridge_channel_playfile(struct ast_bridge_channel *bridge_channel, ast_bridge_custom_play_fn custom_play, const char *playfile, const char *moh_class)
{
if (moh_class) {
if (ast_strlen_zero(moh_class)) {
@@ -839,7 +823,7 @@
}
}
if (custom_play) {
- custom_play(playfile);
+ custom_play(bridge_channel, playfile);
} else {
ast_stream_and_wait(bridge_channel->chan, playfile, AST_DIGIT_NONE);
}
@@ -862,7 +846,7 @@
struct bridge_playfile {
/*! Call this function to play the playfile. (NULL if normal sound file to play) */
- void (*custom_play)(const char *playfile);
+ ast_bridge_custom_play_fn custom_play;
/*! Offset into playfile[] where the MOH class name starts. (zero if no MOH)*/
int moh_offset;
/*! Filename to play. */
@@ -886,7 +870,7 @@
}
static void payload_helper_playfile(ast_bridge_channel_post_action_data post_it,
- struct ast_bridge_channel *bridge_channel, void (*custom_play)(const char *playfile), const char *playfile, const char *moh_class)
+ struct ast_bridge_channel *bridge_channel, ast_bridge_custom_play_fn custom_play, const char *playfile, const char *moh_class)
{
struct bridge_playfile *payload;
size_t len_name = strlen(playfile) + 1;
@@ -905,13 +889,13 @@
post_it(bridge_channel, AST_BRIDGE_ACTION_PLAY_FILE, payload, len_payload);
}
-void ast_bridge_channel_write_playfile(struct ast_bridge_channel *bridge_channel, void (*custom_play)(const char *playfile), const char *playfile, const char *moh_class)
+void 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)
{
payload_helper_playfile(ast_bridge_channel_write_action_data,
bridge_channel, custom_play, playfile, moh_class);
}
-void ast_bridge_channel_queue_playfile(struct ast_bridge_channel *bridge_channel, void (*custom_play)(const char *playfile), const char *playfile, const char *moh_class)
+void 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)
{
payload_helper_playfile(ast_bridge_channel_queue_action_data,
bridge_channel, custom_play, playfile, moh_class);
@@ -1228,7 +1212,6 @@
|| !v_table->name
|| !v_table->destroy
|| !v_table->dissolving
- || !v_table->can_push
|| !v_table->push
|| !v_table->pull
|| !v_table->notify_masquerade) {
@@ -1325,25 +1308,6 @@
/*!
* \internal
- * \brief ast_bridge base can_push method.
- * \since 12.0.0
- *
- * \param self Bridge to operate upon.
- * \param bridge_channel Bridge channel wanting to push.
- * \param swap Bridge channel to swap places with if not NULL.
- *
- * \note On entry, self is already locked.
- * \note Stub because of nothing to do.
- *
- * \retval TRUE if can push this channel into the bridge.
- */
-static int bridge_base_can_push(struct ast_bridge *self, struct ast_bridge_channel *bridge_channel, struct ast_bridge_channel *swap)
-{
- return 1;
-}
-
-/*!
- * \internal
* \brief ast_bridge base push method.
* \since 12.0.0
*
@@ -1400,7 +1364,6 @@
.name = "base",
.destroy = bridge_base_destroy,
.dissolving = bridge_base_dissolving,
- .can_push = bridge_base_can_push,
.push = bridge_base_push,
.pull = bridge_base_pull,
.notify_masquerade = bridge_base_notify_masquerade,
@@ -2337,7 +2300,9 @@
bridge_channel->bridge->callid = ast_read_threadstorage_callid();
}
- bridge_channel_push(bridge_channel);
+ if (bridge_channel_push(bridge_channel)) {
+ ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_HANGUP);
+ }
bridge_reconfigured(bridge_channel->bridge);
if (bridge_channel->state == AST_BRIDGE_CHANNEL_STATE_WAIT) {
@@ -3120,7 +3085,9 @@
ast_bridge_channel_unlock(bridge_channel);
ao2_ref(src_bridge, -1);
- bridge_channel_push(bridge_channel);
+ if (bridge_channel_push(bridge_channel)) {
+ ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_HANGUP);
+ }
}
bridge_reconfigured(dst_bridge);
bridge_reconfigured(src_bridge);
@@ -4189,6 +4156,80 @@
ast_bridge_unlock(bridge);
}
+static int channel_hash(const void *obj, int flags)
+{
+ const struct ast_channel *chan = obj;
+ const char *name = obj;
+ int hash;
+
+ switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
+ default:
+ case OBJ_POINTER:
+ name = ast_channel_name(chan);
+ /* Fall through */
+ case OBJ_KEY:
+ hash = ast_str_hash(name);
+ break;
+ case OBJ_PARTIAL_KEY:
+ /* Should never happen in hash callback. */
+ ast_assert(0);
+ hash = 0;
+ break;
+ }
+ return hash;
+}
+
+static int channel_cmp(void *obj, void *arg, int flags)
+{
+ const struct ast_channel *left = obj;
+ const struct ast_channel *right = arg;
+ const char *right_name = arg;
+ int cmp;
+
+ switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
+ default:
+ case OBJ_POINTER:
+ right_name = ast_channel_name(right);
+ /* Fall through */
+ case OBJ_KEY:
+ cmp = strcmp(ast_channel_name(left), right_name);
+ break;
+ case OBJ_PARTIAL_KEY:
+ cmp = strncmp(ast_channel_name(left), right_name, strlen(right_name));
+ break;
+ }
+ return cmp ? 0 : CMP_MATCH;
+}
+
+struct ao2_container *ast_bridge_peers_nolock(struct ast_bridge *bridge)
+{
+ struct ao2_container *channels;
+ struct ast_bridge_channel *iter;
+
+ channels = ao2_container_alloc_options(AO2_ALLOC_OPT_LOCK_NOLOCK,
+ 13, channel_hash, channel_cmp);
+ if (!channels) {
+ return NULL;
+ }
+
+ AST_LIST_TRAVERSE(&bridge->channels, iter, entry) {
+ ao2_link(channels, iter->chan);
+ }
+
+ return channels;
+}
+
+struct ao2_container *ast_bridge_peers(struct ast_bridge *bridge)
+{
+ struct ao2_container *channels;
+
+ ast_bridge_lock(bridge);
+ channels = ast_bridge_peers_nolock(bridge);
+ ast_bridge_unlock(bridge);
+
+ return channels;
+}
+
/*!
* \internal
* \brief Service the bridge manager request.
Modified: team/kmoore/stasis-bridging-channel_events/res/res_stasis.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/stasis-bridging-channel_events/res/res_stasis.c?view=diff&rev=386452&r1=386451&r2=386452
==============================================================================
--- team/kmoore/stasis-bridging-channel_events/res/res_stasis.c (original)
+++ team/kmoore/stasis-bridging-channel_events/res/res_stasis.c Wed Apr 24 15:07:42 2013
@@ -291,10 +291,10 @@
static void *exec_command(struct stasis_app_control *control,
struct stasis_app_command *command)
{
- ao2_lock(control);
+ ao2_lock(control);
ao2_ref(command, +1);
ao2_link(control->command_queue, command);
- ao2_unlock(control);
+ ao2_unlock(control);
return wait_for_command(command);
}
@@ -353,12 +353,12 @@
*/
static int control_continue_test_and_reset(struct stasis_app_control *control)
{
- int r;
- SCOPED_AO2LOCK(lock, control);
-
- r = control->continue_to_dialplan;
- control->continue_to_dialplan = 0;
- return r;
+ int r;
+ SCOPED_AO2LOCK(lock, control);
+
+ r = control->continue_to_dialplan;
+ control->continue_to_dialplan = 0;
+ return r;
}
void stasis_app_control_continue(struct stasis_app_control *control)
@@ -751,7 +751,7 @@
struct ao2_iterator i;
void *obj;
- SCOPED_AO2LOCK(lock, control);
+ SCOPED_AO2LOCK(lock, control);
i = ao2_iterator_init(control->command_queue, AO2_ITERATOR_UNLINK);
More information about the asterisk-commits
mailing list