[asterisk-commits] mmichelson: branch mmichelson/features_config r389533 - in /team/mmichelson/f...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed May 22 16:00:49 CDT 2013


Author: mmichelson
Date: Wed May 22 16:00:44 2013
New Revision: 389533

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=389533
Log:
Move features configuration to its own file.

This helps to reduce the size of features.c some and it also
gives a more accurate look at what outside files will need
to be accessing in order to get necessary configuration.


Added:
    team/mmichelson/features_config/include/asterisk/features_config.h   (with props)
    team/mmichelson/features_config/main/features_config.c   (with props)
Modified:
    team/mmichelson/features_config/include/asterisk/features.h
    team/mmichelson/features_config/main/features.c

Modified: team/mmichelson/features_config/include/asterisk/features.h
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/features_config/include/asterisk/features.h?view=diff&rev=389533&r1=389532&r2=389533
==============================================================================
--- team/mmichelson/features_config/include/asterisk/features.h (original)
+++ team/mmichelson/features_config/include/asterisk/features.h Wed May 22 16:00:44 2013
@@ -251,108 +251,6 @@
 */
 struct ast_call_feature *ast_find_call_feature(const char *name);
 
-
-/*!
- * \brief General features configuration items
- */
-struct ast_features_general_config {
-	/*! Milliseconds allowed between digit presses when entering feature code */
-	unsigned int featuredigittimeout;
-};
-
-/*!
- * \brief Get the general configuration options
- *
- * The returned value has its reference count incremented.
- */
-struct ast_features_general_config *ast_get_features_general_config(void);
-
-/*!
- * \brief Get the general configuration options for a channel
- *
- * \note The channel should be locked before calling this function.
- * \note The returned value has its reference count incremented.
- *
- * \param chan The channel to get configuration options for
- * \retval NULL Failed to get configuration
- * \retval non-NULL The general features configuration
- */
-struct ast_features_general_config *ast_get_chan_features_general_config(struct ast_channel *chan);
-
-/*!
- * \brief Feature configuration relating to transfers
- */
-struct ast_features_xfer_config {
-	AST_DECLARE_STRING_FIELDS (
-		/*! Sound to play to transferee when transfer succeeds */
-		AST_STRING_FIELD(xfersound);
-		/*! Sound to play to transferee when transfer fails */
-		AST_STRING_FIELD(xferfailsound);
-	);
-	/*! Milliseconds allowed between digit presses when dialing transfer destination */
-	unsigned int transferdigittimeout;
-	/*! Milliseconds to wait for the transfer target to answer a transferred call */
-	unsigned int atxfernoanswertimeout;
-	/*! Milliseconds to wait before attempting to re-dial the transfer target */
-	unsigned int atxferloopdelay;
-	/*! Number of times to re-attempt dialing the transfer target */
-	unsigned int atxfercallbackretries;
-	/*! Determines if the call is dropped on attended transfer failure */
-	unsigned int atxferdropcall;
-};
-
-/*!
- * \brief Get the transfer configuration options
- *
- * The returned value has its reference count incremented
- */
-struct ast_features_xfer_config *ast_get_features_xfer_config(void);
-
-/*!
- * \brief Get the transfer configuration options for a channel
- *
- * \note The channel should be locked before calling this function.
- * \note The returned value has its reference count incremented.
- *
- * \param chan The channel to get configuration options for
- * \retval NULL Failed to get configuration
- * \retval non-NULL The transfer features configuration
- */
-struct ast_features_xfer_config *ast_get_chan_features_xfer_config(struct ast_channel *chan);
-
-/*!
- * \brief Configuration relating to call pickup
- */
-struct ast_features_pickup_config {
-	AST_DECLARE_STRING_FIELDS (
-		/*! Digit sequence to press to pick up a ringing call */
-		AST_STRING_FIELD(pickupexten);
-		/*! Sound to play to picker when pickup succeeds */
-		AST_STRING_FIELD(pickupsound);
-		/*! Sound to play to picker when pickup fails */
-		AST_STRING_FIELD(pickupfailsound);
-	);
-};
-
-/*!
- * \brief Get the pickup configuration options
- *
- * The returned value has its reference count incremented
- */
-struct ast_features_pickup_config *ast_get_features_pickup_config(void);
-
-/*!
- * \brief Get the pickup configuration options for a channel
- *
- * \note The channel should be locked before calling this function.
- * \note The returned value has its reference count incremented.
- *
- * \param chan The channel to get configuration options for
- * \retval NULL Failed to get configuration
- * \retval non-NULL The pickup features configuration
- */
-struct ast_features_pickup_config *ast_get_chan_features_pickup_config(struct ast_channel *chan);
-
 void ast_rdlock_call_features(void);
 void ast_unlock_call_features(void);
 

Added: team/mmichelson/features_config/include/asterisk/features_config.h
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/features_config/include/asterisk/features_config.h?view=auto&rev=389533
==============================================================================
--- team/mmichelson/features_config/include/asterisk/features_config.h (added)
+++ team/mmichelson/features_config/include/asterisk/features_config.h Wed May 22 16:00:44 2013
@@ -1,0 +1,168 @@
+/*
+* Asterisk -- An open source telephony toolkit.
+*
+* Copyright (C) 2013, Digium, Inc.
+*
+* Mark Michelson <mmichelson at digium.com>
+*
+* 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 _FEATURES_CONFIG_H
+#define _FEATURES_CONFIG_H
+
+#include "asterisk/stringfields.h"
+
+struct ast_channel;
+
+/*!
+ * \brief General features configuration items
+ */
+struct ast_features_general_config {
+	/*! Milliseconds allowed between digit presses when entering feature code */
+	unsigned int featuredigittimeout;
+};
+
+/*!
+ * \brief Get the general configuration options for a channel
+ *
+ * \note The channel should be locked before calling this function.
+ * \note The returned value has its reference count incremented.
+ *
+ * If no channel is provided, then the global features configuration is returned.
+ *
+ * \param chan The channel to get configuration options for
+ * \retval NULL Failed to get configuration
+ * \retval non-NULL The general features configuration
+ */
+struct ast_features_general_config *ast_get_chan_features_general_config(struct ast_channel *chan);
+
+/*!
+ * \brief Feature configuration relating to transfers
+ */
+struct ast_features_xfer_config {
+	AST_DECLARE_STRING_FIELDS (
+		/*! Sound to play to transferee when transfer succeeds */
+		AST_STRING_FIELD(xfersound);
+		/*! Sound to play to transferee when transfer fails */
+		AST_STRING_FIELD(xferfailsound);
+	);
+	/*! Milliseconds allowed between digit presses when dialing transfer destination */
+	unsigned int transferdigittimeout;
+	/*! Milliseconds to wait for the transfer target to answer a transferred call */
+	unsigned int atxfernoanswertimeout;
+	/*! Milliseconds to wait before attempting to re-dial the transfer target */
+	unsigned int atxferloopdelay;
+	/*! Number of times to re-attempt dialing the transfer target */
+	unsigned int atxfercallbackretries;
+	/*! Determines if the call is dropped on attended transfer failure */
+	unsigned int atxferdropcall;
+};
+
+/*!
+ * \brief Get the transfer configuration options for a channel
+ *
+ * \note The channel should be locked before calling this function.
+ * \note The returned value has its reference count incremented.
+ *
+ * If no channel is provided, then the global transfer configuration is returned.
+ *
+ * \param chan The channel to get configuration options for
+ * \retval NULL Failed to get configuration
+ * \retval non-NULL The transfer features configuration
+ */
+struct ast_features_xfer_config *ast_get_chan_features_xfer_config(struct ast_channel *chan);
+
+/*!
+ * \brief Configuration relating to call pickup
+ */
+struct ast_features_pickup_config {
+	AST_DECLARE_STRING_FIELDS (
+		/*! Digit sequence to press to pick up a ringing call */
+		AST_STRING_FIELD(pickupexten);
+		/*! Sound to play to picker when pickup succeeds */
+		AST_STRING_FIELD(pickupsound);
+		/*! Sound to play to picker when pickup fails */
+		AST_STRING_FIELD(pickupfailsound);
+	);
+};
+
+/*!
+ * \brief Get the pickup configuration options for a channel
+ *
+ * \note The channel should be locked before calling this function.
+ * \note The returned value has its reference count incremented.
+ *
+ * If no channel is provided, then the global pickup configuration is returned.
+ *
+ * \param chan The channel to get configuration options for
+ * \retval NULL Failed to get configuration
+ * \retval non-NULL The pickup features configuration
+ */
+struct ast_features_pickup_config *ast_get_chan_features_pickup_config(struct ast_channel *chan);
+
+/*!
+ * \brief Configuration for the builtin features
+ */
+struct ast_featuremap_config {
+	AST_DECLARE_STRING_FIELDS (
+		/*! Blind transfer DTMF code */
+		AST_STRING_FIELD(blindxfer);
+		/*! Disconnect DTMF code */
+		AST_STRING_FIELD(disconnect);
+		/*! Automon DTMF code */
+		AST_STRING_FIELD(automon);
+		/*! Attended Transfer DTMF code */
+		AST_STRING_FIELD(atxfer);
+		/*! One-touch parking DTMF code */
+		AST_STRING_FIELD(parkcall);
+		/*! Automixmon DTMF code */
+		AST_STRING_FIELD(automixmon);
+	);
+};
+
+/*!
+ * \brief Get the featuremap configuration options for a channel
+ *
+ * \note The channel should be locked before calling this function.
+ * \note The returned value has its reference count incremented.
+ *
+ * If no channel is provided, then the global featuremap configuration is returned.
+ *
+ * \param chan The channel to get configuration options for
+ * \retval NULL Failed to get configuration
+ * \retval non-NULL The pickup features configuration
+ */
+struct ast_featuremap_config *ast_get_chan_featuremap_config(struct ast_channel *chan);
+
+/*!
+ * \brief Get the DTMF code for a builtin feature
+ *
+ * \note The channel should be locked before calling this function
+ *
+ * If no channel is provided, then the global setting for the option is returned.
+ *
+ * \param chan The channel to get the option from
+ * \param feature The short name of the feature (as it appears in features.conf)
+ * \param[out] buf The buffer to write the DTMF value into
+ * \param size The size of the buffer in bytes
+ * \retval 0 Success
+ * \retval non-zero Unrecognized builtin feature name
+ */
+int ast_get_builtin_feature(struct ast_channel *chan, const char *feature, char *buf, size_t len);
+
+void ast_features_config_shutdown(void);
+
+int ast_features_config_reload(void);
+
+int ast_features_config_init(void);
+
+#endif // _FEATURES_CONFIG_H

Propchange: team/mmichelson/features_config/include/asterisk/features_config.h
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: team/mmichelson/features_config/include/asterisk/features_config.h
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: team/mmichelson/features_config/include/asterisk/features_config.h
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: team/mmichelson/features_config/main/features.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/features_config/main/features.c?view=diff&rev=389533&r1=389532&r2=389533
==============================================================================
--- team/mmichelson/features_config/main/features.c (original)
+++ team/mmichelson/features_config/main/features.c Wed May 22 16:00:44 2013
@@ -74,7 +74,7 @@
 #include "asterisk/test.h"
 #include "asterisk/bridging.h"
 #include "asterisk/bridging_basic.h"
-#include "asterisk/config_options.h"
+#include "asterisk/features_config.h"
 
 /*
  * Party A - transferee
@@ -662,399 +662,6 @@
 	struct ast_flags peer_features;
 };
 
-struct features_global_config {
-	struct ast_features_general_config *general;
-	struct ast_features_xfer_config *xfer;
-	struct ast_features_pickup_config *pickup;
-};
-
-struct features_featuremap {
-	AST_DECLARE_STRING_FIELDS (
-		AST_STRING_FIELD(blindxfer);
-		AST_STRING_FIELD(disconnect);
-		AST_STRING_FIELD(automon);
-		AST_STRING_FIELD(atxfer);
-		AST_STRING_FIELD(parkcall);
-		AST_STRING_FIELD(automixmon);
-	);
-};
-
-struct features_applicationmap {
-	/* XXX STUB */
-};
-
-struct features_config {
-	struct features_global_config *global;
-	struct features_featuremap *featuremap;
-	struct features_applicationmap *applicationmap;
-};
-
-static struct aco_type global_option = {
-	.type = ACO_GLOBAL,
-	.name = "globals",
-	.category_match = ACO_WHITELIST,
-	.category = "^general$",
-	.item_offset = offsetof(struct features_config, global),
-};
-
-static struct aco_type featuremap_option = {
-	.type = ACO_GLOBAL,
-	.name = "featuremap",
-	.category_match = ACO_WHITELIST,
-	.category = "^featuremap$",
-	.item_offset = offsetof(struct features_config, featuremap),
-};
-
-static struct aco_type applicationmap_option = {
-	.type = ACO_GLOBAL,
-	.name = "applicationmap",
-	.category_match = ACO_WHITELIST,
-	.category = "^applicationmap$",
-	.item_offset = offsetof(struct features_config, applicationmap),
-};
-
-struct aco_type *global_options[] = ACO_TYPES(&global_option);
-struct aco_type *featuremap_options[] = ACO_TYPES(&featuremap_option);
-struct aco_type *applicationmap_options[] = ACO_TYPES(&applicationmap_option);
-
-struct aco_file features_conf = {
-	.filename = "features.conf",
-	.types = ACO_TYPES(&global_option, &featuremap_option, &applicationmap_option),
-};
-
-AO2_GLOBAL_OBJ_STATIC(globals);
-
-static void features_config_destructor(void *obj)
-{
-	struct features_config *cfg = obj;
-
-	ao2_cleanup(cfg->global);
-	ao2_cleanup(cfg->featuremap);
-	ao2_cleanup(cfg->applicationmap);
-}
-
-static void featuremap_config_destructor(void *obj)
-{
-	struct features_featuremap *cfg = obj;
-
-	ast_string_field_free_memory(cfg);
-}
-
-static void applicationmap_config_destructor (void *obj)
-{
-	/* XXX STUB */
-}
-
-static void global_config_destructor(void *obj)
-{
-	struct features_global_config *cfg = obj;
-
-	ao2_cleanup(cfg->general);
-	ao2_cleanup(cfg->xfer);
-	ao2_cleanup(cfg->pickup);
-}
-
-static void xfer_destructor(void *obj)
-{
-	struct ast_features_xfer_config *cfg = obj;
-
-	ast_string_field_free_memory(cfg);
-}
-
-static void pickup_destructor(void *obj)
-{
-	struct ast_features_pickup_config *cfg = obj;
-
-	ast_string_field_free_memory(cfg);
-}
-
-static struct features_global_config *global_config_alloc(void)
-{
-	RAII_VAR(struct features_global_config *, cfg, NULL, ao2_cleanup);
-
-	cfg = ao2_alloc(sizeof(*cfg), global_config_destructor);
-	if (!cfg) {
-		return NULL;
-	}
-
-	cfg->general = ao2_alloc(sizeof(*cfg->general), NULL);
-	if (!cfg->general) {
-		return NULL;
-	}
-
-	cfg->xfer = ao2_alloc(sizeof(*cfg->xfer), xfer_destructor);
-	if (!cfg->xfer || ast_string_field_init(cfg->xfer, 32)) {
-		return NULL;
-	}
-
-	cfg->pickup = ao2_alloc(sizeof(*cfg->pickup), pickup_destructor);
-	if (!cfg->pickup || ast_string_field_init(cfg->pickup, 32)) {
-		return NULL;
-	}
-
-	ao2_ref(cfg, +1);
-	return cfg;
-}
-
-static void *features_config_alloc(void)
-{
-	RAII_VAR(struct features_config *, cfg, NULL, ao2_cleanup);
-
-	cfg = ao2_alloc(sizeof(*cfg), features_config_destructor);
-	if (!cfg) {
-		return NULL;
-	}
-
-	cfg->global = global_config_alloc();;
-	if (!cfg->global) {
-		return NULL;
-	}
-
-	cfg->featuremap = ao2_alloc(sizeof(*cfg->featuremap), featuremap_config_destructor);
-	if (!cfg->featuremap || ast_string_field_init(cfg->featuremap, 32)) {
-		return NULL;
-	}
-
-	cfg->applicationmap = ao2_alloc(sizeof(*cfg->applicationmap),
-			applicationmap_config_destructor);
-	if (!cfg->applicationmap) {
-		return NULL;
-	}
-
-	ao2_ref(cfg, +1);
-	return cfg;
-}
-
-static void general_copy(struct ast_features_general_config *dest, const struct ast_features_general_config *src)
-{
-	*dest = *src;
-}
-
-static void xfer_copy(struct ast_features_xfer_config *dest, const struct ast_features_xfer_config *src)
-{
-	ast_string_fields_copy(dest, src);
-	dest->transferdigittimeout = src->transferdigittimeout;
-	dest->atxfernoanswertimeout = src->atxfernoanswertimeout;
-	dest->atxferloopdelay = src->atxferloopdelay;
-	dest->atxfercallbackretries = src->atxfercallbackretries;
-	dest->atxferdropcall = src->atxferdropcall;
-}
-
-static void pickup_copy(struct ast_features_pickup_config *dest, const struct ast_features_pickup_config *src)
-{
-	ast_string_fields_copy(dest, src);
-}
-
-static void global_copy(struct features_global_config *dest, const struct features_global_config *src)
-{
-	general_copy(dest->general, src->general);
-	xfer_copy(dest->xfer, src->xfer);
-	pickup_copy(dest->pickup, src->pickup);
-}
-
-static void featuremap_copy(struct features_featuremap *dest, const struct features_featuremap *src)
-{
-	ast_string_fields_copy(dest, src);
-}
-
-static void applicationmap_copy(struct features_applicationmap *dest, const struct features_applicationmap *src)
-{
-	/* XXX STUB */
-}
-
-static void features_copy(struct features_config *dest, const struct features_config *src)
-{
-	global_copy(dest->global, src->global);
-	featuremap_copy(dest->featuremap, src->featuremap);
-	applicationmap_copy(dest->applicationmap, src->applicationmap);
-}
-
-static struct features_config *features_config_dup(const struct features_config *orig)
-{
-	struct features_config *dup;
-
-	dup = features_config_alloc();
-	if (!dup) {
-		return NULL;
-	}
-
-	features_copy(dup, orig);
-
-	return dup;
-}
-
-static int general_set(struct ast_features_general_config *general, const char *name,
-		const char *value)
-{
-	int res = 0;
-
-	if (!strcasecmp(name, "featuredigittimeout")) {
-		res = ast_parse_arg(value, PARSE_INT32, &general->featuredigittimeout);
-	} else {
-		/* Unrecognized option */
-		res = -1;
-	}
-
-	return res;
-}
-
-static int general_get(struct ast_features_general_config *general, const char *field,
-		char *buf, size_t len)
-{
-	int res = 0;
-
-	if (!strcasecmp(field, "featuredigittimeout")) {
-		snprintf(buf, len, "%u", general->featuredigittimeout);
-	} else {
-		/* Unrecognized option */
-		res = -1;
-	}
-
-	return res;
-}
-
-static int xfer_set(struct ast_features_xfer_config *xfer, const char *name,
-		const char *value)
-{
-	int res = 0;
-
-	if (!strcasecmp(name, "transferdigittimeout")) {
-		res = ast_parse_arg(value, PARSE_INT32, &xfer->transferdigittimeout);
-	} else if (!strcasecmp(name, "atxfernoanswertimeout")) {
-		res = ast_parse_arg(value, PARSE_INT32, &xfer->atxfernoanswertimeout);
-	} else if (!strcasecmp(name, "atxferloopdelay")) {
-		res = ast_parse_arg(value, PARSE_INT32, &xfer->atxferloopdelay);
-	} else if (!strcasecmp(name, "atxfercallbackretries")) {
-		res = ast_parse_arg(value, PARSE_INT32, &xfer->atxfercallbackretries);
-	} else if (!strcasecmp(name, "atxferdropcall")) {
-		xfer->atxferdropcall = ast_true(value);
-	} else if (!strcasecmp(name, "xfersound")) {
-		ast_string_field_set(xfer, xfersound, value);
-	} else if (!strcasecmp(name, "xferfailsound")) {
-		ast_string_field_set(xfer, xferfailsound, value);
-	} else {
-		/* Unrecognized option */
-		res = -1;
-	}
-	
-	return res;
-}
-
-static int xfer_get(struct ast_features_xfer_config *xfer, const char *field,
-		char *buf, size_t len)
-{
-	int res = 0;
-
-	if (!strcasecmp(field, "transferdigittimeout")) {
-		snprintf(buf, len, "%u", xfer->transferdigittimeout);
-	} else if (!strcasecmp(field, "atxfernoanswertimeout")) {
-		snprintf(buf, len, "%u", xfer->atxfernoanswertimeout);
-	} else if (!strcasecmp(field, "atxferloopdelay")) {
-		snprintf(buf, len, "%u", xfer->atxferloopdelay);
-	} else if (!strcasecmp(field, "atxfercallbackretries")) {
-		snprintf(buf, len, "%u", xfer->atxfercallbackretries);
-	} else if (!strcasecmp(field, "atxferdropcall")) {
-		snprintf(buf, len, "%u", xfer->atxferdropcall);
-	} else if (!strcasecmp(field, "xfersound")) {
-		ast_copy_string(buf, xfer->xfersound, len);
-	} else if (!strcasecmp(field, "xferfailsound")) {
-		ast_copy_string(buf, xfer->xferfailsound, len);
-	} else {
-		/* Unrecognized option */
-		res = -1;
-	}
-
-	return res;
-}
-
-static int pickup_set(struct ast_features_pickup_config *pickup, const char *name,
-		const char *value)
-{
-	int res = 0;
-
-	if (!strcasecmp(name, "pickupsound")) {
-		ast_string_field_set(pickup, pickupsound, value);
-	} else if (!strcasecmp(name, "pickupfailsound")) {
-		ast_string_field_set(pickup, pickupfailsound, value);
-	} else if (!strcasecmp(name, "pickupexten")) {
-		ast_string_field_set(pickup, pickupexten, value);
-	} else {
-		/* Unrecognized option */
-		res = -1;
-	}
-	
-	return res;
-}
-
-static int pickup_get(struct ast_features_pickup_config *pickup, const char *field,
-		char *buf, size_t len)
-{
-	int res = 0;
-
-	if (!strcasecmp(field, "pickupsound")) {
-		ast_copy_string(buf, pickup->pickupsound, len);
-	} else if (!strcasecmp(field, "pickupfailsound")) {
-		ast_copy_string(buf, pickup->pickupfailsound, len);
-	} else if (!strcasecmp(field, "pickupexten")) {
-		ast_copy_string(buf, pickup->pickupexten, len);
-	} else {
-		/* Unrecognized option */
-		res = -1;
-	}
-
-	return res;
-}
-
-static int featuremap_set(struct features_featuremap *featuremap, const char *name,
-		const char *value)
-{
-	int res = 0;
-
-	if (!strcasecmp(name, "blindxfer")) {
-		ast_string_field_set(featuremap, blindxfer, value);
-	} else if (!strcasecmp(name, "disconnect")) {
-		ast_string_field_set(featuremap, disconnect, value);
-	} else if (!strcasecmp(name, "automon")) {
-		ast_string_field_set(featuremap, automon, value);
-	} else if (!strcasecmp(name, "atxfer")) {
-		ast_string_field_set(featuremap, atxfer, value);
-	} else if (!strcasecmp(name, "automixmon")) {
-		ast_string_field_set(featuremap, atxfer, value);
-	} else {
-		/* Unrecognized option */
-		res = -1;
-	}
-	
-	return res;
-}
-
-static int featuremap_get(struct features_featuremap *featuremap, const char *field,
-		char *buf, size_t len)
-{
-	int res = 0;
-
-	if (!strcasecmp(field, "blindxfer")) {
-		ast_copy_string(buf, featuremap->blindxfer, len);
-	} else if (!strcasecmp(field, "disconnect")) {
-		ast_copy_string(buf, featuremap->disconnect, len);
-	} else if (!strcasecmp(field, "automon")) {
-		ast_copy_string(buf, featuremap->automon, len);
-	} else if (!strcasecmp(field, "atxfer")) {
-		ast_copy_string(buf, featuremap->atxfer, len);
-	} else if (!strcasecmp(field, "automixmon")) {
-		ast_copy_string(buf, featuremap->automixmon, len);
-	} else {
-		/* Unrecognized option */
-		res = -1;
-	}
-	
-	return res;
-}
-
-CONFIG_INFO_CORE("features", cfg_info, globals, features_config_alloc,
-	.files = ACO_FILES(&features_conf),
-);
-
 #if defined(ATXFER_NULL_TECH)
 /*!
  * \internal
@@ -3535,82 +3142,6 @@
 	return find_dynamic_feature(name);
 }
 
-static void feature_ds_destroy(void *data)
-{
-	struct features_config *cfg = data;
-	ao2_cleanup(cfg);
-}
-
-static void *feature_ds_duplicate(void *data)
-{
-	struct features_config *old_cfg = data;
-
-	return features_config_dup(old_cfg);
-}
-
-static const struct ast_datastore_info feature_ds_info = {
-	.type = "FEATURE",
-	.destroy = feature_ds_destroy,
-	.duplicate = feature_ds_duplicate,
-};
-
-/*!
- * \internal
- * \brief Find or create feature datastore on a channel
- *
- * \pre chan is locked
- *
- * \return the data on the FEATURE datastore, or NULL on error
- */
-static struct features_config *get_feature_ds(struct ast_channel *chan)
-{
-	RAII_VAR(struct features_config *, orig, NULL, ao2_cleanup);
-	struct features_config *cfg;
-	struct ast_datastore *ds;
-
-	if ((ds = ast_channel_datastore_find(chan, &feature_ds_info, NULL))) {
-		cfg = ds->data;
-		ao2_ref(cfg, +1);
-		return cfg;
-	}
-
-	orig = ao2_global_obj_ref(globals);
-	if (!orig) {
-		return NULL;
-	}
-
-	cfg = features_config_dup(orig);
-	if (!cfg) {
-		return NULL;
-	}
-
-	if (!(ds = ast_datastore_alloc(&feature_ds_info, NULL))) {
-		ao2_cleanup(cfg);
-		return NULL;
-	}
-
-	/* Give the datastore a reference to the config */
-	ao2_ref(cfg, +1);
-	ds->data = cfg;
-
-	ast_channel_datastore_add(chan, ds);
-
-	return cfg;
-}
-
-static struct ast_datastore *get_feature_chan_ds(struct ast_channel *chan)
-{
-	struct ast_datastore *ds;
-
-	if (!(ds = ast_channel_datastore_find(chan, &feature_ds_info, NULL))) {
-		/* Hasn't been created yet.  Trigger creation. */
-		RAII_VAR(struct features_config *, cfg, get_feature_ds(chan), ao2_cleanup);
-		ds = ast_channel_datastore_find(chan, &feature_ds_info, NULL);
-	}
-
-	return ds;
-}
-
 /*!
  * \internal
  * \brief Get the extension for a given builtin feature
@@ -3623,15 +3154,9 @@
 static int builtin_feature_get_exten(struct ast_channel *chan, const char *feature_name,
 		char *buf, size_t len)
 {
-	RAII_VAR(struct features_config *, cfg, NULL, ao2_cleanup);
 	SCOPED_CHANNELLOCK(lock, chan);
-	
-	cfg = get_feature_ds(chan);
-	if (!cfg) {
-		return -1;
-	}
-
-	return featuremap_get(cfg->featuremap, feature_name, buf, len);
+
+	return ast_get_builtin_feature(chan, feature_name, buf, len);
 }
 
 /*!
@@ -6718,199 +6243,6 @@
 	return 0;
 }
 
-struct ast_features_general_config *ast_get_features_general_config(void)
-{
-	RAII_VAR(struct features_config *, cfg, ao2_global_obj_ref(globals), ao2_cleanup);
-
-	if (!cfg) {
-		return NULL;
-	}
-
-	ast_assert(cfg->global && cfg->global->general);
-
-	ao2_ref(cfg->global->general, +1);
-	return cfg->global->general;
-}
-
-struct ast_features_general_config *ast_get_chan_features_general_config(struct ast_channel *chan)
-{
-	RAII_VAR(struct features_config *, cfg, get_feature_ds(chan), ao2_cleanup);
-
-	if (!cfg) {
-		return NULL;
-	}
-
-	ast_assert(cfg->global && cfg->global->general);
-
-	ao2_ref(cfg->global->general, +1);
-	return cfg->global->general;
-}
-
-struct ast_features_xfer_config *ast_get_features_xfer_config(void)
-{
-	RAII_VAR(struct features_config *, cfg, ao2_global_obj_ref(globals), ao2_cleanup);
-
-	if (!cfg) {
-		return NULL;
-	}
-
-	ast_assert(cfg->global && cfg->global->xfer);
-
-	ao2_ref(cfg->global->xfer, +1);
-	return cfg->global->xfer;
-}
-
-struct ast_features_xfer_config *ast_get_chan_features_xfer_config(struct ast_channel *chan)
-{
-	RAII_VAR(struct features_config *, cfg, get_feature_ds(chan), ao2_cleanup);
-
-	if (!cfg) {
-		return NULL;
-	}
-
-	ast_assert(cfg->global && cfg->global->xfer);
-
-	ao2_ref(cfg->global->xfer, +1);
-	return cfg->global->xfer;
-}
-
-struct ast_features_pickup_config *ast_get_features_pickup_config(void)
-{
-	RAII_VAR(struct features_config *, cfg, ao2_global_obj_ref(globals), ao2_cleanup);
-
-	if (!cfg) {
-		return NULL;
-	}
-
-	ast_assert(cfg->global && cfg->global->pickup);
-
-	ao2_ref(cfg->global->pickup, +1);
-	return cfg->global->pickup;
-}
-
-struct ast_features_pickup_config *ast_get_chan_features_pickup_config(struct ast_channel *chan)
-{
-	RAII_VAR(struct features_config *, cfg, get_feature_ds(chan), ao2_cleanup);
-
-	if (!cfg) {
-		return NULL;
-	}
-
-	ast_assert(cfg->global && cfg->global->pickup);
-
-	ao2_ref(cfg->global->pickup, +1);
-	return cfg->global->pickup;
-}
-
-static int applicationmap_handler(const struct aco_option *opt,
-		struct ast_variable *var, void *obj)
-{
-	/* XXX STUB */
-	return 0;
-}
-
-static int general_handler(const struct aco_option *opt,
-		struct ast_variable *var, void *obj)
-{
-	struct features_global_config *global = obj;
-	struct ast_features_general_config *general = global->general;
-	
-	return general_set(general, var->name, var->value);
-}
-
-static int xfer_handler(const struct aco_option *opt,
-		struct ast_variable *var, void *obj)
-{
-	struct features_global_config *global = obj;
-	struct ast_features_xfer_config *xfer = global->xfer;
-
-	return xfer_set(xfer, var->name, var->value);
-}
-
-static int pickup_handler(const struct aco_option *opt,
-		struct ast_variable *var, void *obj)
-{
-	struct features_global_config *global = obj;
-	struct ast_features_pickup_config *pickup = global->pickup;
-
-	return pickup_set(pickup, var->name, var->value);
-}
-
-static int featuremap_handler(const struct aco_option *opt,
-		struct ast_variable *var, void *obj)
-{
-	struct features_featuremap *featuremap = obj;
-
-	return featuremap_set(featuremap, var->name, var->value);
-}
-
-static int really_load_config(int reload)
-{
-	if (!reload && aco_info_init(&cfg_info)) {
-		ast_log(LOG_ERROR, "Unable to initialize configuration info for features\n");
-		return -1;
-	}
-
-	aco_option_register_custom(&cfg_info, "featuredigittimeout", ACO_EXACT, global_options,
-			__stringify(DEFAULT_FEATURE_DIGIT_TIMEOUT), general_handler, 0);
-
-	aco_option_register_custom(&cfg_info, "transferdigittimeout", ACO_EXACT, global_options,
-			__stringify(DEFAULT_TRANSFER_DIGIT_TIMEOUT), xfer_handler, 0)
-	aco_option_register_custom(&cfg_info, "atxfernoanswertimeout", ACO_EXACT, global_options,
-			__stringify(DEFAULT_NOANSWER_TIMEOUT_ATTENDED_TRANSFER), xfer_handler, 0);
-	aco_option_register_custom(&cfg_info, "atxferdropcall", ACO_EXACT, global_options,
-			__stringify(DEFAULT_ATXFER_DROP_CALL), xfer_handler, 0);
-	aco_option_register_custom(&cfg_info, "atxferloopdelay", ACO_EXACT, global_options,
-			__stringify(DEFAULT_ATXFER_LOOP_DELAY), xfer_handler, 0);
-	aco_option_register_custom(&cfg_info, "atxfercallbackretries", ACO_EXACT, global_options,
-			__stringify(DEFAULT_ATXFER_CALLBACK_RETRIES), xfer_handler, 0);
-	aco_option_register_custom(&cfg_info, "xfersound", ACO_EXACT, global_options,
-			"beep", xfer_handler, 0);
-	aco_option_register_custom(&cfg_info, "xferfailsound", ACO_EXACT, global_options,
-			"beeperr", xfer_handler, 0);
-
-	aco_option_register_custom(&cfg_info, "pickupexten", ACO_EXACT, global_options,
-			"*8", pickup_handler, 0);
-	aco_option_register_custom(&cfg_info, "pickupsound", ACO_EXACT, global_options,
-			"", pickup_handler, 0);
-	aco_option_register_custom(&cfg_info, "pickupfailsound", ACO_EXACT, global_options,
-			"", pickup_handler, 0);
-
-	aco_option_register_custom(&cfg_info, "blindxfer", ACO_EXACT, featuremap_options,
-			"#", featuremap_handler, 0);
-	aco_option_register_custom(&cfg_info, "disconnect", ACO_EXACT, featuremap_options,
-			"*", featuremap_handler, 0);
-	aco_option_register_custom(&cfg_info, "automon", ACO_EXACT, featuremap_options,
-			"", featuremap_handler, 0);
-	aco_option_register_custom(&cfg_info, "atxfer", ACO_EXACT, featuremap_options,
-			"", featuremap_handler, 0);
-	aco_option_register_custom(&cfg_info, "parkcall", ACO_EXACT, featuremap_options,
-			"", featuremap_handler, 0);
-	aco_option_register_custom(&cfg_info, "automixmon", ACO_EXACT, featuremap_options,
-			"", featuremap_handler, 0);
-	
-	/* XXX This regex may need to be more specific */
-	aco_option_register_custom(&cfg_info, "^.*$", ACO_REGEX, applicationmap_options,
-			"", applicationmap_handler, 0);
-
-#if 0
-	/* XXX This regex may need to be more specific */
-	aco_option_register_custom(&cfg_info, "^.*$", ACO_REGEX, dynamicfeaturemap_options,
-			"", dynamic_feature_handler, 0);
-#endif
-
-	if (aco_process_config(&cfg_info, 0) == ACO_PROCESS_ERROR) {
-		ast_log(LOG_ERROR, "Failed to process features.conf configuration!\n");
-		if (!reload) {
-			aco_info_destroy(&cfg_info);
-			ao2_global_obj_release(globals);
-		}
-		return -1;
-	}
-
-	return 0;
-}
-
 static int load_config(int reload)
 {
 	struct ast_flags config_flags = {
@@ -7078,7 +6410,7 @@
 	}
 
 	res = load_config(1);
-	res = really_load_config(1);
+	res = ast_features_config_reload();
 	ast_mutex_unlock(&features_reload_lock);
 
 	return res;
@@ -8492,120 +7824,11 @@
 }
 #endif	/* defined(TEST_FRAMEWORK) */
 
-static int feature_read(struct ast_channel *chan, const char *cmd, char *data,
-	       char *buf, size_t len)
-{
-	int res;
-	RAII_VAR(struct features_config *, cfg, NULL, ao2_cleanup);
-	SCOPED_CHANNELLOCK(lock, chan);
-
-	if (!strcasecmp(data, "inherit")) {
-		struct ast_datastore *ds = get_feature_chan_ds(chan);
-		unsigned int inherit = ds ? ds->inheritance : 0;
-
-		snprintf(buf, len, "%s", inherit ? "yes" : "no");
-		return 0;
-	}
-
-	cfg = get_feature_ds(chan);
-	if (!cfg) {
-		return -1;
-	}
-
-	res = general_get(cfg->global->general, data, buf, len) &&
-		xfer_get(cfg->global->xfer, data, buf, len) &&
-		pickup_get(cfg->global->pickup, data, buf, len);
-
-	if (res) {
-		ast_log(LOG_WARNING, "Invalid argument '%s' to FEATURE()\n", data);
-	}
-
-	return res;
-}
-
-static int feature_write(struct ast_channel *chan, const char *cmd, char *data,
-		const char *value)
-{
-	int res;
-	RAII_VAR(struct features_config *, cfg, NULL, ao2_cleanup);
-	SCOPED_CHANNELLOCK(lock, chan);
-
-	if (!strcasecmp(data, "inherit")) {
-		struct ast_datastore *ds = get_feature_chan_ds(chan);
-		if (ds) {
-			ds->inheritance = ast_true(value) ? DATASTORE_INHERIT_FOREVER : 0;
-		}
-		return 0;
-	}
-
-	if (!(cfg = get_feature_ds(chan))) {
-		return -1;
-	}
-
-	res = general_set(cfg->global->general, data, value) &&
-		xfer_set(cfg->global->xfer, data, value) &&
-		pickup_set(cfg->global->pickup, data, value);
-
-	if (res) {
-		ast_log(LOG_WARNING, "Invalid argument '%s' to FEATURE()\n", data);
-	}
-
-	return res;
-}
-
-static int featuremap_read(struct ast_channel *chan, const char *cmd, char *data,
-	       char *buf, size_t len)
-{
-	int res;
-
-	res = builtin_feature_get_exten(chan, data, buf, len);
-
-	if (res) {
-		ast_log(LOG_WARNING, "Invalid argument '%s' to FEATUREMAP()\n", data);
-	}
-
-	return res;
-}
-
-static int featuremap_write(struct ast_channel *chan, const char *cmd, char *data,
-		const char *value)
-{
-	int res;
-	RAII_VAR(struct features_config *, cfg, NULL, ao2_cleanup);
-	SCOPED_CHANNELLOCK(lock, chan);
-
-	if (!(cfg = get_feature_ds(chan))) {
-		return -1;
-	}
-
-	res = featuremap_set(cfg->featuremap, data, value);
-	if (res) {
-		ast_log(LOG_WARNING, "Invalid argument '%s' to FEATUREMAP()\n", data);
-		return -1;
-	}
-
-	return 0;
-}
-
-static struct ast_custom_function feature_function = {
-	.name = "FEATURE",
-	.read = feature_read,
-	.write = feature_write
-};
-
-static struct ast_custom_function featuremap_function = {
-	.name = "FEATUREMAP",
-	.read = featuremap_read,
-	.write = featuremap_write
-};
-
 /*! \internal \brief Clean up resources on Asterisk shutdown */
 static void features_shutdown(void)
 {
 	ast_cli_unregister_multiple(cli_features, ARRAY_LEN(cli_features));
 	ast_devstate_prov_del("Park");
-	ast_custom_function_unregister(&featuremap_function);
-	ast_custom_function_unregister(&feature_function);
 	ast_manager_unregister("Bridge");
 	ast_manager_unregister("Park");
 
@@ -8627,7 +7850,7 @@
 		return -1;
 	}
 
-	res = really_load_config(0);
+	res = ast_features_config_init();
 	if (res) {
 		return res;
 	}
@@ -8640,8 +7863,6 @@
 		ast_manager_register_xml_core("Park", EVENT_FLAG_CALL, manager_park);
 		ast_manager_register_xml_core("Bridge", EVENT_FLAG_CALL, action_bridge);
 	}
-	res |= __ast_custom_function_register(&feature_function, NULL);
-	res |= __ast_custom_function_register(&featuremap_function, NULL);
 
 	res |= ast_devstate_prov_add("Park", metermaidstate);
 #if defined(TEST_FRAMEWORK)

Added: team/mmichelson/features_config/main/features_config.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/features_config/main/features_config.c?view=auto&rev=389533
==============================================================================
--- team/mmichelson/features_config/main/features_config.c (added)
+++ team/mmichelson/features_config/main/features_config.c Wed May 22 16:00:44 2013
@@ -1,0 +1,847 @@
+/*
+* Asterisk -- An open source telephony toolkit.
+*
+* Copyright (C) 2013, Digium, Inc.
+*
+* Mark Michelson <mmichelson at digium.com>
+*
+* 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"
+
+#include "asterisk/features_config.h"
+#include "asterisk/config_options.h"
+#include "asterisk/datastore.h"
+#include "asterisk/channel.h"
+#include "asterisk/pbx.h"
+
+struct features_global_config {
+	struct ast_features_general_config *general;
+	struct ast_features_xfer_config *xfer;
+	struct ast_features_pickup_config *pickup;
+};
+
+struct features_applicationmap {
+	/* XXX STUB */
+};
+
+struct features_config {
+	struct features_global_config *global;
+	struct ast_featuremap_config *featuremap;
+	struct features_applicationmap *applicationmap;
+};
+
+static struct aco_type global_option = {
+	.type = ACO_GLOBAL,
+	.name = "globals",
+	.category_match = ACO_WHITELIST,
+	.category = "^general$",
+	.item_offset = offsetof(struct features_config, global),
+};
+
+static struct aco_type featuremap_option = {
+	.type = ACO_GLOBAL,
+	.name = "featuremap",
+	.category_match = ACO_WHITELIST,
+	.category = "^featuremap$",
+	.item_offset = offsetof(struct features_config, featuremap),
+};
+
+static struct aco_type applicationmap_option = {
+	.type = ACO_GLOBAL,
+	.name = "applicationmap",
+	.category_match = ACO_WHITELIST,
+	.category = "^applicationmap$",
+	.item_offset = offsetof(struct features_config, applicationmap),
+};
+
+struct aco_type *global_options[] = ACO_TYPES(&global_option);
+struct aco_type *featuremap_options[] = ACO_TYPES(&featuremap_option);
+struct aco_type *applicationmap_options[] = ACO_TYPES(&applicationmap_option);
+
+struct aco_file features_conf = {
+	.filename = "features.conf",
+	.types = ACO_TYPES(&global_option, &featuremap_option, &applicationmap_option),
+};
+
+AO2_GLOBAL_OBJ_STATIC(globals);
+
+static void features_config_destructor(void *obj)
+{
+	struct features_config *cfg = obj;
+
+	ao2_cleanup(cfg->global);
+	ao2_cleanup(cfg->featuremap);
+	ao2_cleanup(cfg->applicationmap);
+}
+
+static void featuremap_config_destructor(void *obj)
+{
+	struct ast_featuremap_config *cfg = obj;
+
+	ast_string_field_free_memory(cfg);
+}
+
+static void applicationmap_config_destructor (void *obj)
+{
+	/* XXX STUB */
+}
+
+static void global_config_destructor(void *obj)
+{
+	struct features_global_config *cfg = obj;
+
+	ao2_cleanup(cfg->general);
+	ao2_cleanup(cfg->xfer);
+	ao2_cleanup(cfg->pickup);
+}
+
+static void xfer_destructor(void *obj)
+{
+	struct ast_features_xfer_config *cfg = obj;
+
+	ast_string_field_free_memory(cfg);
+}
+
+static void pickup_destructor(void *obj)
+{
+	struct ast_features_pickup_config *cfg = obj;
+
+	ast_string_field_free_memory(cfg);
+}
+
+static struct features_global_config *global_config_alloc(void)
+{
+	RAII_VAR(struct features_global_config *, cfg, NULL, ao2_cleanup);
+
+	cfg = ao2_alloc(sizeof(*cfg), global_config_destructor);
+	if (!cfg) {
+		return NULL;
+	}
+
+	cfg->general = ao2_alloc(sizeof(*cfg->general), NULL);
+	if (!cfg->general) {
+		return NULL;
+	}
+
+	cfg->xfer = ao2_alloc(sizeof(*cfg->xfer), xfer_destructor);
+	if (!cfg->xfer || ast_string_field_init(cfg->xfer, 32)) {
+		return NULL;
+	}
+
+	cfg->pickup = ao2_alloc(sizeof(*cfg->pickup), pickup_destructor);
+	if (!cfg->pickup || ast_string_field_init(cfg->pickup, 32)) {
+		return NULL;
+	}
+
+	ao2_ref(cfg, +1);
+	return cfg;
+}
+
+static void *features_config_alloc(void)
+{
+	RAII_VAR(struct features_config *, cfg, NULL, ao2_cleanup);
+

[... 707 lines stripped ...]



More information about the asterisk-commits mailing list