[asterisk-commits] dvossel: branch dvossel/hd_confbridge r309214 - in /team/dvossel/hd_confbridg...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Tue Mar 1 17:04:41 CST 2011
Author: dvossel
Date: Tue Mar 1 17:04:37 2011
New Revision: 309214
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=309214
Log:
Introduction of the ConfBridge config parser.
Added:
team/dvossel/hd_confbridge/apps/confbridge/
team/dvossel/hd_confbridge/apps/confbridge/conf_config_parser.c (with props)
team/dvossel/hd_confbridge/apps/confbridge/include/
team/dvossel/hd_confbridge/apps/confbridge/include/confbridge.h (with props)
team/dvossel/hd_confbridge/configs/confbridge.conf.sample (with props)
Modified:
team/dvossel/hd_confbridge/apps/Makefile
team/dvossel/hd_confbridge/apps/app_confbridge.c
Modified: team/dvossel/hd_confbridge/apps/Makefile
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/hd_confbridge/apps/Makefile?view=diff&rev=309214&r1=309213&r2=309214
==============================================================================
--- team/dvossel/hd_confbridge/apps/Makefile (original)
+++ team/dvossel/hd_confbridge/apps/Makefile Tue Mar 1 17:04:37 2011
@@ -27,6 +27,13 @@
include $(ASTTOPDIR)/Makefile.moddir_rules
+clean::
+ $(MAKE)
+ rm -f confbridge/*.o confbridge/*.i
+
+$(if $(filter app_confbridge,$(EMBEDDED_MODS)),modules.link,app_confbridge.so): $(subst .c,.o,$(wildcard confbridge/*.c))
+$(subst .c,.o,$(wildcard confbridge/*.c)): _ASTCFLAGS+=$(call MOD_ASTCFLAGS,app_confbridge)
+
ifneq ($(findstring $(OSARCH), mingw32 cygwin ),)
LIBS+= -lres_features.so -lres_ael_share.so -lres_monitor.so -lres_speech.so
LIBS+= -lres_smdi.so
Modified: team/dvossel/hd_confbridge/apps/app_confbridge.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/hd_confbridge/apps/app_confbridge.c?view=diff&rev=309214&r1=309213&r2=309214
==============================================================================
--- team/dvossel/hd_confbridge/apps/app_confbridge.c (original)
+++ team/dvossel/hd_confbridge/apps/app_confbridge.c Tue Mar 1 17:04:37 2011
@@ -38,18 +38,19 @@
#include "asterisk/cli.h"
#include "asterisk/file.h"
-#include "asterisk/logger.h"
#include "asterisk/channel.h"
+#include "asterisk/pbx.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/lock.h"
-#include "asterisk/app.h"
#include "asterisk/bridging.h"
#include "asterisk/musiconhold.h"
#include "asterisk/say.h"
#include "asterisk/audiohook.h"
#include "asterisk/astobj2.h"
-
+#include "confbridge/include/confbridge.h"
+
+//todohere redo all this documentation
/*** DOCUMENTATION
<application name="ConfBridge" language="en_US">
<synopsis>
@@ -115,24 +116,6 @@
static const char app[] = "ConfBridge";
-enum {
- OPTION_ADMIN = (1 << 0), /*!< Set if the caller is an administrator */
- OPTION_MENU = (1 << 1), /*!< Set if the caller should have access to the conference bridge IVR menu */
- OPTION_MUSICONHOLD = (1 << 2), /*!< Set if music on hold should be played if nobody else is in the conference bridge */
- OPTION_NOONLYPERSON = (1 << 3), /*!< Set if the "you are currently the only person in this conference" sound file should not be played */
- OPTION_STARTMUTED = (1 << 4), /*!< Set if the caller should be initially set muted */
- OPTION_ANNOUNCEUSERCOUNT = (1 << 5), /*!< Set if the number of users should be announced to the caller */
- OPTION_MARKEDUSER = (1 << 6), /*!< Set if the caller is a marked user */
- OPTION_WAITMARKED = (1 << 7), /*!< Set if the conference must wait for a marked user before starting */
- OPTION_QUIET = (1 << 8), /*!< Set if no audio prompts should be played */
-};
-
-enum {
- OPTION_MUSICONHOLD_CLASS, /*!< If the 'M' option is set, the music on hold class to play */
- /*This must be the last element */
- OPTION_ARRAY_SIZE,
-};
-
AST_APP_OPTIONS(app_opts,{
AST_APP_OPTION('A', OPTION_MARKEDUSER),
AST_APP_OPTION('a', OPTION_ADMIN),
@@ -145,34 +128,8 @@
AST_APP_OPTION('q', OPTION_QUIET),
});
-/* Maximum length of a conference bridge name */
-#define MAX_CONF_NAME 32
-
/* Number of buckets our conference bridges container can have */
#define CONFERENCE_BRIDGE_BUCKETS 53
-
-/*! \brief The structure that represents a conference bridge */
-struct conference_bridge {
- char name[MAX_CONF_NAME]; /*!< Name of the conference bridge */
- struct ast_bridge *bridge; /*!< Bridge structure doing the mixing */
- unsigned int users; /*!< Number of users present */
- unsigned int markedusers; /*!< Number of marked users present */
- unsigned int locked:1; /*!< Is this conference bridge locked? */
- AST_LIST_HEAD_NOLOCK(, conference_bridge_user) users_list; /*!< List of users participating in the conference bridge */
- struct ast_channel *playback_chan; /*!< Channel used for playback into the conference bridge */
- ast_mutex_t playback_lock; /*!< Lock used for playback channel */
-};
-
-/*! \brief The structure that represents a conference bridge user */
-struct conference_bridge_user {
- struct conference_bridge *conference_bridge; /*!< Conference bridge they are participating in */
- struct ast_channel *chan; /*!< Asterisk channel participating */
- struct ast_flags flags; /*!< Flags passed in when the application was called */
- char *opt_args[OPTION_ARRAY_SIZE]; /*!< Arguments to options passed when application was called */
- struct ast_bridge_features features; /*!< Bridge features structure */
- unsigned int kicked:1; /*!< User has been kicked from the conference */
- AST_LIST_ENTRY(conference_bridge_user) list; /*!< Linked list information */
-};
/*! \brief Container to hold all conference bridges in progress */
static struct ao2_container *conference_bridges;
@@ -488,7 +445,7 @@
* \param conference_bridge_user The conference bridge user structure
*
*/
-static void leave_conference_bridge(struct conference_bridge *conference_bridge, struct conference_bridge_user *conference_bridge_user)
+static void leave_conference_bridge(struct conference_bridge *conference_bridge, struct conference_bridge_user *conference_bridge_user)
{
ao2_lock(conference_bridge);
@@ -824,7 +781,6 @@
static char *handle_cli_confbridge_kick(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
-
struct conference_bridge *bridge = NULL;
struct conference_bridge tmp;
struct conference_bridge_user *participant = NULL;
@@ -919,33 +875,7 @@
ao2_lock(bridge);
AST_LIST_TRAVERSE(&bridge->users_list, participant, list) {
ast_cli(a->fd, "%-32s ", participant->chan->name);
- if (ast_test_flag(&participant->flags, OPTION_MARKEDUSER)) {
- ast_cli(a->fd, "A");
- }
- if (ast_test_flag(&participant->flags, OPTION_ADMIN)) {
- ast_cli(a->fd, "a");
- }
- if (ast_test_flag(&participant->flags, OPTION_ANNOUNCEUSERCOUNT)) {
- ast_cli(a->fd, "c");
- }
- if (ast_test_flag(&participant->flags, OPTION_MENU)) {
- ast_cli(a->fd, "m");
- }
- if (ast_test_flag(&participant->flags, OPTION_MUSICONHOLD)) {
- ast_cli(a->fd, "M(%s)", participant->opt_args[OPTION_MUSICONHOLD_CLASS]);
- }
- if (ast_test_flag(&participant->flags, OPTION_NOONLYPERSON)) {
- ast_cli(a->fd, "1");
- }
- if (ast_test_flag(&participant->flags, OPTION_STARTMUTED)) {
- ast_cli(a->fd, "s");
- }
- if (ast_test_flag(&participant->flags, OPTION_WAITMARKED)) {
- ast_cli(a->fd, "w");
- }
- if (ast_test_flag(&participant->flags, OPTION_QUIET)) {
- ast_cli(a->fd, "q");
- }
+ //todohere tell more about each channel in the bridge
ast_cli(a->fd, "\n");
}
ao2_unlock(bridge);
@@ -971,6 +901,8 @@
/* Get rid of the conference bridges container. Since we only allow dynamic ones none will be active. */
ao2_ref(conference_bridges, -1);
+ conf_destroy_config();
+
return res;
}
@@ -989,11 +921,18 @@
ast_cli_register_multiple(cli_confbridge, sizeof(cli_confbridge) / sizeof(struct ast_cli_entry));
+ conf_load_config(0);
return AST_MODULE_LOAD_SUCCESS;
+}
+
+static int reload(void)
+{
+ return conf_load_config(1);
}
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Conference Bridge Application",
.load = load_module,
.unload = unload_module,
+ .reload = reload,
.load_pri = AST_MODPRI_DEVSTATE_PROVIDER,
);
Added: team/dvossel/hd_confbridge/apps/confbridge/conf_config_parser.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/hd_confbridge/apps/confbridge/conf_config_parser.c?view=auto&rev=309214
==============================================================================
--- team/dvossel/hd_confbridge/apps/confbridge/conf_config_parser.c (added)
+++ team/dvossel/hd_confbridge/apps/confbridge/conf_config_parser.c Tue Mar 1 17:04:37 2011
@@ -1,0 +1,504 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2011, Digium, Inc.
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+#include "asterisk/logger.h"
+#include "asterisk/config.h"
+#include "include/confbridge.h"
+#include "asterisk/astobj2.h"
+#include "asterisk/cli.h"
+
+#define CONF_CONFIG "confbridge.conf"
+
+static struct ao2_container *user_profiles;
+static struct ao2_container *bridge_profiles;
+static struct ao2_container *menus;
+
+/*! bridge profile container functions */
+static int bridge_cmp_cb(void *obj, void *arg, int flags)
+{
+ struct bridge_profile *entry1 = obj;
+ struct bridge_profile *entry2 = arg;
+ return (!strcasecmp(entry1->name, entry2->name)) ? CMP_MATCH | CMP_STOP : 0;
+}
+static int bridge_hash_cb(const void *obj, const int flags)
+{
+ const struct bridge_profile *b_profile = obj;
+ return ast_str_hash(b_profile->name);
+}
+static int bridge_mark_delme_cb(void *obj, void *arg, int flag)
+{
+ struct bridge_profile *entry = obj;
+ entry->delme = 1;
+ return 0;
+}
+static int match_bridge_delme_cb(void *obj, void *arg, int flag)
+{
+ struct bridge_profile *entry = obj;
+ return entry->delme ? CMP_MATCH : 0;
+}
+
+/*! menu container functions */
+static int menu_cmp_cb(void *obj, void *arg, int flags)
+{
+ struct conf_menu *entry1 = obj;
+ struct conf_menu *entry2 = arg;
+ return (!strcasecmp(entry1->name, entry2->name)) ? CMP_MATCH | CMP_STOP : 0;
+}
+static int menu_hash_cb(const void *obj, const int flags)
+{
+ const struct conf_menu *menu = obj;
+ return ast_str_hash(menu->name);
+}
+static int menu_mark_delme_cb(void *obj, void *arg, int flag)
+{
+ struct conf_menu *entry = obj;
+ entry->delme = 1;
+ return 0;
+}
+static int match_menu_delme_cb(void *obj, void *arg, int flag)
+{
+ struct conf_menu *entry = obj;
+ return entry->delme ? CMP_MATCH : 0;
+}
+
+/*! User profile container functions */
+static int user_cmp_cb(void *obj, void *arg, int flags)
+{
+ struct user_profile *entry1 = obj;
+ struct user_profile *entry2 = arg;
+ return (!strcasecmp(entry1->name, entry2->name)) ? CMP_MATCH | CMP_STOP : 0;
+}
+static int user_hash_cb(const void *obj, const int flags)
+{
+ const struct user_profile *u_profile = obj;
+ return ast_str_hash(u_profile->name);
+}
+static int user_mark_delme_cb(void *obj, void *arg, int flag)
+{
+ struct user_profile *entry = obj;
+ entry->delme = 1;
+ return 0;
+}
+static int match_user_delme_cb(void *obj, void *arg, int flag)
+{
+ struct user_profile *entry = obj;
+ return entry->delme ? CMP_MATCH : 0;
+}
+
+/*!
+ * \brief Parse the bridge profile options
+ */
+static int parse_bridge(const char *cat, struct ast_config *cfg)
+{
+ struct ast_variable *var;
+ struct bridge_profile tmp;
+ struct bridge_profile *b_profile;
+
+ ast_copy_string(tmp.name, cat, sizeof(tmp.name));
+ if ((b_profile = ao2_find(bridge_profiles, &tmp, OBJ_POINTER))) {
+ b_profile->delme = 0;
+ } else if ((b_profile = ao2_alloc(sizeof(*b_profile), NULL))) {
+ ast_copy_string(b_profile->name, cat, sizeof(b_profile->name));
+ ao2_link(bridge_profiles, b_profile);
+ } else {
+ ao2_unlock(b_profile);
+ return -1;
+ }
+
+ ao2_lock(b_profile);
+ /* set defaults */
+ b_profile->internal_sample_rate = 0;
+
+ for (var = ast_variable_browse(cfg, cat); var; var = var->next) {
+ if (!strcasecmp(var->name, "internal_sample_rate")) {
+ if (!strcasecmp(var->value, "auto")) {
+ b_profile->internal_sample_rate = 0;
+ } else if (sscanf(var->value, "%30u", &b_profile->internal_sample_rate) != 1) {
+ ast_log(LOG_WARNING, "internal_sample_rate '%s' at line %d of %s is not supported.\n",
+ var->value, var->lineno, CONF_CONFIG);
+ }
+ } else if (!strcasecmp(var->name, "type")) {
+ continue;
+ } else {
+ ast_log(LOG_WARNING, "Unknown option '%s' at line %d of %s is not supported.\n",
+ var->name, var->lineno, CONF_CONFIG);
+ }
+ }
+ ao2_unlock(b_profile);
+
+ ao2_ref(b_profile, -1);
+ return 0;
+}
+
+static int parse_user(const char *cat, struct ast_config *cfg)
+{
+ struct ast_variable *var;
+ struct user_profile tmp;
+ struct user_profile *u_profile;
+
+ ast_copy_string(tmp.name, cat, sizeof(tmp.name));
+ if ((u_profile = ao2_find(user_profiles, &tmp, OBJ_POINTER))) {
+ u_profile->delme = 0;
+ } else if ((u_profile = ao2_alloc(sizeof(*u_profile), NULL))) {
+ ast_copy_string(u_profile->name, cat, sizeof(u_profile->name));
+ ao2_link(user_profiles, u_profile);
+ } else {
+ ao2_unlock(u_profile);
+ return -1;
+ }
+
+ ao2_lock(u_profile);
+ /* set defaults */
+ //todohere put default settings
+ for (var = ast_variable_browse(cfg, cat); var; var = var->next) {
+ if (!strcasecmp(var->name, "type")) {
+ continue;
+ } else {
+ ast_log(LOG_WARNING, "Unknown option '%s' at line %d of %s is not supported.\n",
+ var->name, var->lineno, CONF_CONFIG);
+ }
+ }
+ ao2_unlock(u_profile);
+
+ ao2_ref(u_profile, -1);
+ return 0;
+}
+
+static int parse_menu(const char *cat, struct ast_config *cfg)
+{
+ struct ast_variable *var;
+ struct conf_menu tmp;
+ struct conf_menu *menu;
+
+ ast_copy_string(tmp.name, cat, sizeof(tmp.name));
+ if ((menu = ao2_find(menus, &tmp, OBJ_POINTER))) {
+ menu->delme = 0;
+ } else if ((menu = ao2_alloc(sizeof(*menu), NULL))) {
+ ast_copy_string(menu->name, cat, sizeof(menu->name));
+ ao2_link(menus, menu);
+ } else {
+ ao2_unlock(menu);
+ return -1;
+ }
+
+ ao2_lock(menu);
+ /* set defaults */
+ //todohere put default settings
+ for (var = ast_variable_browse(cfg, cat); var; var = var->next) {
+ if (!strcasecmp(var->name, "type")) {
+ continue;
+ } else {
+ ast_log(LOG_WARNING, "Unknown option '%s' at line %d of %s is not supported.\n",
+ var->name, var->lineno, CONF_CONFIG);
+ }
+ }
+ ao2_unlock(menu);
+
+ ao2_ref(menu, -1);
+ return 0;
+}
+
+static char *complete_user_profile_name(const char *line, const char *word, int pos, int state)
+{
+ int which = 0;
+ char *res = NULL;
+ int wordlen = strlen(word);
+ struct ao2_iterator i;
+ struct user_profile *u_profile = NULL;
+
+ i = ao2_iterator_init(user_profiles, 0);
+ while ((u_profile = ao2_iterator_next(&i))) {
+ if (!strncasecmp(u_profile->name, word, wordlen) && ++which > state) {
+ res = ast_strdup(u_profile->name);
+ ao2_ref(u_profile, -1);
+ break;
+ }
+ ao2_ref(u_profile, -1);
+ }
+ ao2_iterator_destroy(&i);
+
+ return res;
+}
+static char *handle_cli_confbridge_list_user_profiles(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+ const struct user_profile *u_profile = NULL;
+
+ switch (cmd) {
+ case CLI_INIT:
+ e->command = "confbridge show profile user";
+ e->usage =
+ "Usage confbridge show profile user [<profile name>]\n";
+ return NULL;
+ case CLI_GENERATE:
+ if (a->pos == 4) {
+ return complete_user_profile_name(a->line, a->word, a->pos, a->n);
+ }
+ return NULL;
+ }
+
+ if (a->argc != 5) {
+ return CLI_SHOWUSAGE;
+ }
+
+ if (!(u_profile = conf_find_user_profile(a->argv[4]))) {
+ ast_cli(a->fd, "No conference user profile named '%s' found!\n", a->argv[4]);
+ return CLI_SUCCESS;
+ }
+
+ ast_cli(a->fd,"Name: %s\n", u_profile->name);
+ ast_cli(a->fd,"\n");
+
+ ao2_ref((struct user_profile *) u_profile, -1);
+ return CLI_SUCCESS;
+}
+
+static char *complete_bridge_profile_name(const char *line, const char *word, int pos, int state)
+{
+ int which = 0;
+ char *res = NULL;
+ int wordlen = strlen(word);
+ struct ao2_iterator i;
+ struct bridge_profile *b_profile = NULL;
+
+ i = ao2_iterator_init(bridge_profiles, 0);
+ while ((b_profile = ao2_iterator_next(&i))) {
+ if (!strncasecmp(b_profile->name, word, wordlen) && ++which > state) {
+ res = ast_strdup(b_profile->name);
+ ao2_ref(b_profile, -1);
+ break;
+ }
+ ao2_ref(b_profile, -1);
+ }
+ ao2_iterator_destroy(&i);
+
+ return res;
+}
+static char *handle_cli_confbridge_list_bridge_profiles(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+ const struct bridge_profile *b_profile = NULL;
+ char tmp[64];
+
+ switch (cmd) {
+ case CLI_INIT:
+ e->command = "confbridge show profile bridge";
+ e->usage =
+ "Usage confbridge show profile bridge [<profile name>]\n";
+ return NULL;
+ case CLI_GENERATE:
+ if (a->pos == 4) {
+ return complete_bridge_profile_name(a->line, a->word, a->pos, a->n);
+ }
+ return NULL;
+ }
+
+ if (a->argc != 5) {
+ return CLI_SHOWUSAGE;
+ }
+
+ if (!(b_profile = conf_find_bridge_profile(a->argv[4]))) {
+ ast_cli(a->fd, "No conference bridge profile named '%s' found!\n", a->argv[4]);
+ return CLI_SUCCESS;
+ }
+
+ ast_cli(a->fd,"Name: %s\n", b_profile->name);
+ if (b_profile->internal_sample_rate) {
+ snprintf(tmp, sizeof(tmp), "%d", b_profile->internal_sample_rate);
+ } else {
+ snprintf(tmp, sizeof(tmp), "auto");
+ }
+ ast_cli(a->fd,"Internal Sample Rate: %s\n", tmp);
+ ast_cli(a->fd,"\n");
+
+ ao2_ref((struct bridge_profile *) b_profile, -1);
+ return CLI_SUCCESS;
+}
+
+static char *complete_menu_name(const char *line, const char *word, int pos, int state)
+{
+ int which = 0;
+ char *res = NULL;
+ int wordlen = strlen(word);
+ struct ao2_iterator i;
+ struct conf_menu *menu = NULL;
+
+ i = ao2_iterator_init(menus, 0);
+ while ((menu = ao2_iterator_next(&i))) {
+ if (!strncasecmp(menu->name, word, wordlen) && ++which > state) {
+ res = ast_strdup(menu->name);
+ ao2_ref(menu, -1);
+ break;
+ }
+ ao2_ref(menu, -1);
+ }
+ ao2_iterator_destroy(&i);
+
+ return res;
+}
+static char *handle_cli_confbridge_list_menus(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+ const struct conf_menu *menu = NULL;
+
+ switch (cmd) {
+ case CLI_INIT:
+ e->command = "confbridge show menu";
+ e->usage =
+ "Usage confbridge show menu [<menu name>]\n";
+ return NULL;
+ case CLI_GENERATE:
+ if (a->pos == 3) {
+ return complete_menu_name(a->line, a->word, a->pos, a->n);
+ }
+ return NULL;
+ }
+
+ if (a->argc != 4) {
+ return CLI_SHOWUSAGE;
+ }
+
+ if (!(menu = conf_find_menu(a->argv[3]))) {
+ ast_cli(a->fd, "No conference menu named '%s' found!\n", a->argv[3]);
+ return CLI_SUCCESS;
+ }
+ ast_cli(a->fd,"Name: %s\n", menu->name);
+ ast_cli(a->fd,"\n");
+
+ ao2_ref((struct conf_menu *) menu, -1);
+ return CLI_SUCCESS;
+}
+
+static struct ast_cli_entry cli_confbridge_parser[] = {
+ AST_CLI_DEFINE(handle_cli_confbridge_list_user_profiles, "List conference user profiles."),
+ AST_CLI_DEFINE(handle_cli_confbridge_list_bridge_profiles, "List conference bridge profiles."),
+ AST_CLI_DEFINE(handle_cli_confbridge_list_menus, "List conference menus"),
+};
+
+static int conf_parse_init(void)
+{
+ if (!(user_profiles = ao2_container_alloc(283, user_hash_cb, user_cmp_cb))) {
+ conf_destroy_config();
+ return -1;
+ }
+
+ if (!(bridge_profiles = ao2_container_alloc(283, bridge_hash_cb, bridge_cmp_cb))) {
+ conf_destroy_config();
+ return -1;
+ }
+
+ if (!(menus = ao2_container_alloc(283, menu_hash_cb, menu_cmp_cb))) {
+ conf_destroy_config();
+ return -1;
+ }
+
+ ast_cli_register_multiple(cli_confbridge_parser, ARRAY_LEN(cli_confbridge_parser));
+
+ return 0;
+}
+
+void conf_destroy_config()
+{
+ if (user_profiles) {
+ ao2_ref(user_profiles, -1);
+ user_profiles = NULL;
+ }
+ if (bridge_profiles) {
+ ao2_ref(bridge_profiles, -1);
+ bridge_profiles = NULL;
+ }
+
+ if (menus) {
+ ao2_ref(menus, -1);
+ menus = NULL;
+ }
+ ast_cli_unregister_multiple(cli_confbridge_parser, sizeof(cli_confbridge_parser) / sizeof(struct ast_cli_entry));
+}
+
+static void remove_all_delme(void)
+{
+ ao2_callback(user_profiles, OBJ_NODATA | OBJ_MULTIPLE | OBJ_UNLINK, match_user_delme_cb, NULL);
+ ao2_callback(bridge_profiles, OBJ_NODATA | OBJ_MULTIPLE | OBJ_UNLINK, match_bridge_delme_cb, NULL);
+ ao2_callback(menus, OBJ_NODATA | OBJ_MULTIPLE | OBJ_UNLINK, match_menu_delme_cb, NULL);
+}
+
+static void mark_all_delme(void)
+{
+ ao2_callback(user_profiles, OBJ_NODATA | OBJ_MULTIPLE, user_mark_delme_cb, NULL);
+ ao2_callback(bridge_profiles, OBJ_NODATA | OBJ_MULTIPLE, bridge_mark_delme_cb, NULL);
+ ao2_callback(menus, OBJ_NODATA | OBJ_MULTIPLE, menu_mark_delme_cb, NULL);
+}
+
+int conf_load_config(int reload)
+{
+ struct ast_flags config_flags = { 0, };
+ struct ast_config *cfg = ast_config_load(CONF_CONFIG, config_flags);
+ const char *type = NULL;
+ char *cat = NULL;
+
+ if (!reload) {
+ conf_parse_init();
+ }
+
+ if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEINVALID) {
+ return 0;
+ }
+
+ mark_all_delme();
+
+ while ((cat = ast_category_browse(cfg, cat))) {
+ if (!(type = (ast_variable_retrieve(cfg, cat, "type")))) {
+ continue;
+ }
+ if (!strcasecmp(type, "bridge")) {
+ parse_bridge(cat, cfg);
+ } else if (!strcasecmp(type, "user")) {
+ parse_user(cat, cfg);
+ } else if (!strcasecmp(type, "menu")) {
+ parse_menu(cat, cfg);
+ } else {
+ continue;
+ }
+ }
+
+ remove_all_delme();
+
+ return 0;
+}
+
+const struct user_profile *conf_find_user_profile(const char *user_profile_name)
+{
+ struct user_profile tmp;
+ ast_copy_string(tmp.name, user_profile_name, sizeof(tmp.name));
+
+ return ao2_find(user_profiles, &tmp, OBJ_POINTER);
+
+}
+const struct bridge_profile *conf_find_bridge_profile(const char *bridge_profile_name)
+{
+ struct bridge_profile tmp;
+ ast_copy_string(tmp.name, bridge_profile_name, sizeof(tmp.name));
+
+ return ao2_find(bridge_profiles, &tmp, OBJ_POINTER);
+}
+
+const struct conf_menu *conf_find_menu(const char *menu_name)
+{
+ struct conf_menu tmp;
+ ast_copy_string(tmp.name, menu_name, sizeof(tmp.name));
+
+ return ao2_find(menus, &tmp, OBJ_POINTER);
+}
Propchange: team/dvossel/hd_confbridge/apps/confbridge/conf_config_parser.c
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: team/dvossel/hd_confbridge/apps/confbridge/conf_config_parser.c
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Propchange: team/dvossel/hd_confbridge/apps/confbridge/conf_config_parser.c
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: team/dvossel/hd_confbridge/apps/confbridge/include/confbridge.h
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/hd_confbridge/apps/confbridge/include/confbridge.h?view=auto&rev=309214
==============================================================================
--- team/dvossel/hd_confbridge/apps/confbridge/include/confbridge.h (added)
+++ team/dvossel/hd_confbridge/apps/confbridge/include/confbridge.h Tue Mar 1 17:04:37 2011
@@ -1,0 +1,130 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2011, Digium, Inc.
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+
+#ifndef _CONFBRIDGE_H
+#define _CONFBRIDGE_H
+
+#include "asterisk.h"
+#include "asterisk/app.h"
+#include "asterisk/logger.h"
+#include "asterisk/linkedlists.h"
+#include "asterisk/channel.h"
+#include "asterisk/bridging.h"
+/* Maximum length of a conference bridge name */
+#define MAX_CONF_NAME 32
+
+
+enum user_profile_flags {
+ OPTION_ADMIN = (1 << 0), /*!< Set if the caller is an administrator */
+ OPTION_MENU = (1 << 1), /*!< Set if the caller should have access to the conference bridge IVR menu */
+ OPTION_MUSICONHOLD = (1 << 2), /*!< Set if music on hold should be played if nobody else is in the conference bridge */
+ OPTION_NOONLYPERSON = (1 << 3), /*!< Set if the "you are currently the only person in this conference" sound file should not be played */
+ OPTION_STARTMUTED = (1 << 4), /*!< Set if the caller should be initially set muted */
+ OPTION_ANNOUNCEUSERCOUNT = (1 << 5), /*!< Set if the number of users should be announced to the caller */
+ OPTION_MARKEDUSER = (1 << 6), /*!< Set if the caller is a marked user */
+ OPTION_WAITMARKED = (1 << 7), /*!< Set if the conference must wait for a marked user before starting */
+ OPTION_QUIET = (1 << 8), /*!< Set if no audio prompts should be played */
+};
+
+struct conf_menu {
+ char name[64];
+ int delme;
+};
+
+struct user_profile {
+ char name[64];
+ enum user_profile_flags flags;
+ int volume;
+ int delme;
+};
+
+struct bridge_profile {
+ char name[64];
+ unsigned int internal_sample_rate; /*!< The internal sample rate of the bridge. 0 when set to auto adjust mode. */
+ int delme;
+};
+
+enum {//todohere this must move or go away somewhere
+ OPTION_MUSICONHOLD_CLASS, /*!< If the 'M' option is set, the music on hold class to play */
+ /*This must be the last element */
+ OPTION_ARRAY_SIZE,
+};
+
+/*! \brief The structure that represents a conference bridge */
+struct conference_bridge {
+ char name[MAX_CONF_NAME]; /*!< Name of the conference bridge */
+ struct ast_bridge *bridge; /*!< Bridge structure doing the mixing */
+ const struct bridge_profile *b_profile; /*!< The Bridge Configuration Profile */
+ unsigned int users; /*!< Number of users present */
+ unsigned int markedusers; /*!< Number of marked users present */
+ unsigned int locked:1; /*!< Is this conference bridge locked? */
+ AST_LIST_HEAD_NOLOCK(, conference_bridge_user) users_list; /*!< List of users participating in the conference bridge */
+ struct ast_channel *playback_chan; /*!< Channel used for playback into the conference bridge */
+ ast_mutex_t playback_lock; /*!< Lock used for playback channel */
+};
+
+/*! \brief The structure that represents a conference bridge user */
+struct conference_bridge_user {
+ struct conference_bridge *conference_bridge; /*!< Conference bridge they are participating in */
+ const struct bridge_profile *u_profile; /*!< The User Configuration Profile */
+ struct ast_channel *chan; /*!< Asterisk channel participating */
+ struct ast_flags flags; /*!< Flags passed in when the application was called */ //todohere this must go away
+ char *opt_args[OPTION_ARRAY_SIZE]; /*!< Arguments to options passed when application was called */
+ struct ast_bridge_features features; /*!< Bridge features structure */
+ unsigned int kicked:1; /*!< User has been kicked from the conference */
+ AST_LIST_ENTRY(conference_bridge_user) list; /*!< Linked list information */
+};
+
+/*! \brief load confbridge.conf file */
+int conf_load_config(int reload);
+
+/*! \brief destroy the information loaded from the confbridge.conf file*/
+void conf_destroy_config(void);
+
+/*!
+ * \brief find a user profile given a user profile's name.
+ *
+ * \note User profile is an AO2 object and must have ref count
+ * decremented after being found.
+ *
+ * \retval user profile on success
+ * \retval NULL on failure
+ */
+const struct user_profile *conf_find_user_profile(const char *user_profile_name);
+
+/*!
+ * \brief find a bridge profile given a bridge profile's name.
+ *
+ * \note Bridge profile is an AO2 object and must have ref count
+ * decremented after being found.
+ *
+ * \retval Bridge profile on success
+ * \retval NULL on failure
+ */
+const struct bridge_profile *conf_find_bridge_profile(const char *bridge_profile_name);
+
+/*!
+ * \brief find a conference DTMF menu given the menu's name
+ *
+ * \note The conference menu is an AO2 object and must have ref count
+ * decremented after being found.
+ *
+ * \retval menu on success
+ * \retval NULL on failure
+ */
+const struct conf_menu *conf_find_menu(const char *menu_name);
+#endif
Propchange: team/dvossel/hd_confbridge/apps/confbridge/include/confbridge.h
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: team/dvossel/hd_confbridge/apps/confbridge/include/confbridge.h
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Propchange: team/dvossel/hd_confbridge/apps/confbridge/include/confbridge.h
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: team/dvossel/hd_confbridge/configs/confbridge.conf.sample
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/hd_confbridge/configs/confbridge.conf.sample?view=auto&rev=309214
==============================================================================
--- team/dvossel/hd_confbridge/configs/confbridge.conf.sample (added)
+++ team/dvossel/hd_confbridge/configs/confbridge.conf.sample Tue Mar 1 17:04:37 2011
@@ -1,0 +1,18 @@
+[general]
+; The general section of this config
+; is not currently used, but reserved
+; for future use.
+
+; The default_user, default_bridge, and default_menu
+; sections are applied automatically to all ConfBridge
+; instances invoked without a user, bridge, or menu argument.
+[default_user]
+type=user
+
+[default_bridge]
+type=bridge
+internal_sample_rate=auto
+
+[default_menu]
+type=menu
+
Propchange: team/dvossel/hd_confbridge/configs/confbridge.conf.sample
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: team/dvossel/hd_confbridge/configs/confbridge.conf.sample
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Propchange: team/dvossel/hd_confbridge/configs/confbridge.conf.sample
------------------------------------------------------------------------------
svn:mime-type = text/plain
More information about the asterisk-commits
mailing list