[svn-commits] dvossel: branch dvossel/hd_confbridge r309214 - in /team/dvossel/hd_confbridg...

SVN commits to the Digium repositories svn-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 svn-commits mailing list