[svn-commits] twilson: branch twilson/config_work r362148 - in /team/twilson/config_work: a...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Sun Apr 15 20:34:57 CDT 2012


Author: twilson
Date: Sun Apr 15 20:34:52 2012
New Revision: 362148

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=362148
Log:
Rework some stuff after convert udptl to use the new stuff

1) Instead of all varargs being converted to field offsets, allow
   non-fieldset varargs as well for things like passing default
   min/max ranges for integer options, etc.

2) Fix compiling when an object being configured doesn't have
   any stringfields

3) Add changes to udptl using new API

4) Improve the int/uint parsing to be able to use ranges and defaults


Modified:
    team/twilson/config_work/apps/app_skel.c
    team/twilson/config_work/include/asterisk/config.h
    team/twilson/config_work/include/asterisk/config_options.h
    team/twilson/config_work/main/config.c
    team/twilson/config_work/main/config_options.c
    team/twilson/config_work/main/udptl.c

Modified: team/twilson/config_work/apps/app_skel.c
URL: http://svnview.digium.com/svn/asterisk/team/twilson/config_work/apps/app_skel.c?view=diff&rev=362148&r1=362147&r2=362148
==============================================================================
--- team/twilson/config_work/apps/app_skel.c (original)
+++ team/twilson/config_work/apps/app_skel.c Sun Apr 15 20:34:52 2012
@@ -511,18 +511,18 @@
 	aco_type_register(&cfg_info, priv_type);
 
 	/* General Options */
-	aco_option_register(cfg_info.opts, "foo", global_type, "booya", OPT_STRINGFIELD_T, struct skel_global_config, 0, foo);
-	aco_option_register(cfg_info.opts, "bar", global_type, NULL, OPT_STRINGFIELD_T, struct skel_global_config, 0, bar);
-	aco_option_register(cfg_info.opts, "baz", global_type, NULL, OPT_STRINGFIELD_T, struct skel_global_config, 0, baz);
-	aco_option_register(cfg_info.opts, "blah", global_type, NULL, OPT_BOOL_T, struct skel_global_config, 1, blah);
-	aco_option_register(cfg_info.opts, "bindaddr", global_type, "0.0.0.0:1234", OPT_SOCKADDR_T, struct skel_global_config, PARSE_PORT_REQUIRE, bindaddr);
+	aco_option_register(&cfg_info, "foo", global_type, "booya", OPT_STRINGFIELD_T, 0, STRFLDSET(struct skel_global_config, foo));
+	aco_option_register(&cfg_info, "bar", global_type, NULL, OPT_STRINGFIELD_T, 0, STRFLDSET(struct skel_global_config, bar));
+	aco_option_register(&cfg_info, "baz", global_type, NULL, OPT_STRINGFIELD_T, 0, STRFLDSET(struct skel_global_config, baz));
+	aco_option_register(&cfg_info, "blah", global_type, NULL, OPT_BOOL_T, 1, FLDSET(struct skel_global_config, blah));
+	aco_option_register(&cfg_info, "bindaddr", global_type, "0.0.0.0:1234", OPT_SOCKADDR_T, PARSE_PORT_REQUIRE, FLDSET(struct skel_global_config, bindaddr));
 
 	/* Private Options */
-	aco_option_register(cfg_info.opts, "description", priv_type, NULL, OPT_STRINGFIELD_T, struct skel_pvt_config, 0, description);
-	aco_option_register(cfg_info.opts, "allow", priv_type, "ulaw,alaw", OPT_CODEC_T, struct skel_pvt_config, 1, prefs, caps);
-	aco_option_register(cfg_info.opts, "permit", priv_type, NULL, OPT_ACL_T, struct skel_pvt_config, 1, permit);
-	aco_option_register_custom(cfg_info.opts, "bit1", priv_type, "yes", custom_bitfield_handler, 0);
-	aco_option_register_custom(cfg_info.opts, "bit2", priv_type, "no", custom_bitfield_handler, 0);
+	aco_option_register(&cfg_info, "description", priv_type, NULL, OPT_STRINGFIELD_T, 0, STRFLDSET(struct skel_pvt_config, description));
+	aco_option_register(&cfg_info, "allow", priv_type, "ulaw,alaw", OPT_CODEC_T, 1, FLDSET(struct skel_pvt_config, prefs, caps));
+	aco_option_register(&cfg_info, "permit", priv_type, NULL, OPT_ACL_T, 1, FLDSET(struct skel_pvt_config, permit));
+	aco_option_register_custom(&cfg_info, "bit1", priv_type, "yes", custom_bitfield_handler, 0);
+	aco_option_register_custom(&cfg_info, "bit2", priv_type, "no", custom_bitfield_handler, 0);
 
 	ast_mutex_lock(&reload_lock);
 	if (aco_process_config(&cfg_info, 0)) {
@@ -536,12 +536,7 @@
 		AST_MODULE_LOAD_DECLINE : AST_MODULE_LOAD_SUCCESS;
 
 error:
-	if (cfg_info.opts) {
-		ao2_ref(cfg_info.opts, -1);
-	}
-	if (cfg_info.objs) {
-		ao2_ref(cfg_info.objs, -1);
-	}
+	aco_info_destroy(&cfg_info);
 	return AST_MODULE_LOAD_DECLINE;
 }
 

Modified: team/twilson/config_work/include/asterisk/config.h
URL: http://svnview.digium.com/svn/asterisk/team/twilson/config_work/include/asterisk/config.h?view=diff&rev=362148&r1=362147&r2=362148
==============================================================================
--- team/twilson/config_work/include/asterisk/config.h (original)
+++ team/twilson/config_work/include/asterisk/config.h Sun Apr 15 20:34:52 2012
@@ -644,8 +644,9 @@
 	 * the range (inclusive). An error is returned if the value
 	 * is outside or inside the range, respectively.
 	 */
-	PARSE_IN_RANGE =	0x0020,	/* accept values inside a range */
-	PARSE_OUT_RANGE =	0x0040,	/* accept values outside a range */
+	PARSE_IN_RANGE =       0x0020, /* accept values inside a range */
+	PARSE_OUT_RANGE =      0x0040, /* accept values outside a range */
+	PARSE_RANGE_DEFAULTS = 0x0080, /* default to range min/max on range error */
 
 	/* Port handling, for ast_sockaddr. accept/ignore/require/forbid
 	 * port number after the hostname or address.
@@ -681,11 +682,13 @@
  *	ast_parse_arg("22345", PARSE_INT32|PARSE_IN_RANGE|PARSE_DEFAULT,
  *		&a, 9999, 10, 100);
  *              returns 1, a = 9999
- *      ast_parse_arg("22345ssf", PARSE_UINT32|PARSE_IN_RANGE, &b, 10, 100);
+ *  ast_parse_arg("22345ssf", PARSE_UINT32|PARSE_IN_RANGE, &b, 10, 100);
  *		returns 1, b unchanged
- *      ast_parse_arg("www.foo.biz:44", PARSE_INADDR, &sa);
+ *	ast_parse_arg("12", PARSE_UINT32|PARSE_IN_RANGE|PARSE_RANGE_DEFAULTS, &a, 1, 10);
+ *	    returns 1, a = 10
+ *  ast_parse_arg("www.foo.biz:44", PARSE_INADDR, &sa);
  *		returns 0, sa contains address and port
- *      ast_parse_arg("www.foo.biz", PARSE_INADDR|PARSE_PORT_REQUIRE, &sa);
+ *  ast_parse_arg("www.foo.biz", PARSE_INADDR|PARSE_PORT_REQUIRE, &sa);
  *		returns 1 because port is missing, sa contains address
  */
 int ast_parse_arg(const char *arg, enum ast_parse_flags flags,

Modified: team/twilson/config_work/include/asterisk/config_options.h
URL: http://svnview.digium.com/svn/asterisk/team/twilson/config_work/include/asterisk/config_options.h?view=diff&rev=362148&r1=362147&r2=362148
==============================================================================
--- team/twilson/config_work/include/asterisk/config_options.h (original)
+++ team/twilson/config_work/include/asterisk/config_options.h Sun Apr 15 20:34:52 2012
@@ -181,7 +181,7 @@
 	const char *default_val, enum aco_option_type type, aco_option_handler handler, unsigned int flags, size_t argc, ...);
 
 /* \brief Register a config option
- * \param container The container to store the registered option in
+ * \param info A pointer to the aco_info struct
  * \param name The name of the option
  * \param obj An option object which holds type info about what is being configured
  * \param default_val The default value of the option in the same format as defined in a config file
@@ -191,19 +191,16 @@
  *
  * \returns An option on success, NULL on failure
  */
-#define aco_option_register(container, name, obj, default_val, opt_type, struct_type, flags, ...) {\
+#define aco_option_register(info, name, obj, default_val, opt_type, flags, ...) {\
 	struct aco_option *__opt; \
-	__opt = opt_type == OPT_STRINGFIELD_T ? \
-		__aco_option_build(name, obj, default_val, opt_type, NULL, flags, ARGMAP(offsetof, struct_type, __VA_ARGS__, __field_mgr_pool, __field_mgr)) : \
-		__aco_option_build(name, obj, default_val, opt_type, NULL, flags, ARGMAP(offsetof, struct_type, __VA_ARGS__)); \
-	if (__opt) { \
-		ao2_link(container, __opt); \
+	if ((__opt = __aco_option_build(name, obj, default_val, opt_type, NULL, flags, VA_NARGS(__VA_ARGS__), __VA_ARGS__))){ \
+		ao2_link((info)->opts, __opt); \
 		ao2_ref(__opt, -1); \
 	} \
 }
 
 /* \brief Register a config option
- * \param container The container to store the registered option in
+ * \param info A pointer to the aco_info struct
  * \param name The name of the option
  * \param obj An option object which holds type info about what is being configured
  * \param default_val The default value of the option in the same format as defined in a config file
@@ -212,10 +209,10 @@
  *
  * \returns An option on success, NULL on failure
  */
-#define aco_option_register_custom(container, name, obj, default_val, handler, flags) { \
+#define aco_option_register_custom(info, name, obj, default_val, handler, flags) { \
 	struct aco_option *__opt = __aco_option_build(name, obj, default_val, OPT_CUSTOM_T, handler, flags, 0); \
 	if (__opt) { \
-		ao2_link(container, __opt); \
+		ao2_link((info)->opts, __opt); \
 		ao2_ref(__opt, -1); \
 	} \
 }
@@ -280,6 +277,15 @@
 #define VA_NARGS(...) VA_NARGS1(__VA_ARGS__, 8, 7, 6, 5, 4, 3, 2, 1, 0)
 #define VA_NARGS1(_1, _2, _3, _4, _5, _6, _7, _8, N, ...) N
 
+#define FLDSET(type, ...) FLDSET1(type, ##__VA_ARGS__)
+#define FLDSET1(type, ...) POP(ARGIFY(ARGMAP(offsetof, type, ##__VA_ARGS__)))
+
+#define STRFLDSET(type, ...) FLDSET(type, __VA_ARGS__, __field_mgr_pool, __field_mgr)
+
+#define POP(...) POP1(__VA_ARGS__)
+#define POP1(x, ...) __VA_ARGS__
+
+
 #if defined(__cplusplus) || defined(c_plusplus)
 }
 #endif

Modified: team/twilson/config_work/main/config.c
URL: http://svnview.digium.com/svn/asterisk/team/twilson/config_work/main/config.c?view=diff&rev=362148&r1=362147&r2=362148
==============================================================================
--- team/twilson/config_work/main/config.c (original)
+++ team/twilson/config_work/main/config.c Sun Apr 15 20:34:52 2012
@@ -2638,6 +2638,13 @@
 		}
 		x = strtol(arg, NULL, 0);
 		error = (x < low) || (x > high);
+		if (flags & PARSE_RANGE_DEFAULTS) {
+			if (x < low) {
+				def = low;
+			} else if (x > high) {
+				def = high;
+			}
+		}
 		if (flags & PARSE_OUT_RANGE)
 			error = !error;
 		if (result)
@@ -2664,6 +2671,13 @@
 		}
 		x = strtoul(arg, NULL, 0);
 		error = (x < low) || (x > high);
+		if (flags & PARSE_RANGE_DEFAULTS) {
+			if (x < low) {
+				def = low;
+			} else if (x > high) {
+				def = high;
+			}
+		}
 		if (flags & PARSE_OUT_RANGE)
 			error = !error;
 		if (result)

Modified: team/twilson/config_work/main/config_options.c
URL: http://svnview.digium.com/svn/asterisk/team/twilson/config_work/main/config_options.c?view=diff&rev=362148&r1=362147&r2=362148
==============================================================================
--- team/twilson/config_work/main/config_options.c (original)
+++ team/twilson/config_work/main/config_options.c Sun Apr 15 20:34:52 2012
@@ -483,6 +483,8 @@
 		return -1;
 	}
 	if (!(info->objs = aco_type_container_new())) {
+		ao2_ref(info->opts, -1);
+		info->opts = NULL;
 		return -1;
 	}
 	return 0;
@@ -530,6 +532,7 @@
 		}
 		if (opt->handler(opt, var, obj)) {
 			ao2_ref(opt, -1);
+			ast_log(LOG_NOTICE, "Unable to set default for %s, %s=%s\n", context, var->name, var->value);
 			return -1;
 		}
 		ao2_ref(opt, -1);
@@ -673,15 +676,56 @@
 }
 
 /* default config option handlers */
-
 int ast_config_option_int_fn(const struct aco_option *opt, struct ast_variable *var, void *obj) {
 	int *field = (int *)(obj + opt->args[0]);
-	return ast_parse_arg(var->value, PARSE_INT32 | opt->flags, field);
+	unsigned int flags = PARSE_INT32 | opt->flags;
+	int res = 0;
+	if (opt->flags & PARSE_IN_RANGE) {
+		res = opt->flags & PARSE_DEFAULT ?
+			ast_parse_arg(var->value, flags, field, (int) opt->args[1], (int) opt->args[2], opt->args[3]) :
+			ast_parse_arg(var->value, flags, field, (int) opt->args[1], (int) opt->args[2]);
+		if (res) {
+			if (opt->flags & PARSE_RANGE_DEFAULTS) {
+				ast_log(LOG_WARNING, "Failed to set %s=%s. Set to  %d instead due to range limit (%d, %d)\n", var->name, var->value, *field, (int) opt->args[1], (int) opt->args[2]);
+				res = 0;
+			} else if (opt->flags & PARSE_DEFAULT) {
+				ast_log(LOG_WARNING, "Failed to set %s=%s, Set to default value %d instead.\n", var->name, var->value, *field);
+				res = 0;
+			}
+		}
+	} else if ((opt->flags & PARSE_DEFAULT) && ast_parse_arg(var->value, flags, field, (int) opt->args[1])) {
+		ast_log(LOG_WARNING, "Attempted to set %s=%s, but set it to %d instead due to default)\n", var->name, var->value, *field);
+	} else {
+		res = ast_parse_arg(var->value, flags, field);
+	}
+
+	return res;
 }
 
 int ast_config_option_uint_fn(const struct aco_option *opt, struct ast_variable *var, void *obj) {
 	unsigned int *field = (unsigned int *)(obj + opt->args[0]);
-	return ast_parse_arg(var->value, PARSE_UINT32 | opt->flags, field);
+	unsigned int flags = PARSE_INT32 | opt->flags;
+	int res = 0;
+	if (opt->flags & PARSE_IN_RANGE) {
+		res = opt->flags & PARSE_DEFAULT ?
+			ast_parse_arg(var->value, flags, field, (unsigned int) opt->args[1], (unsigned int) opt->args[2], opt->args[3]) :
+			ast_parse_arg(var->value, flags, field, (unsigned int) opt->args[1], (unsigned int) opt->args[2]);
+		if (res) {
+			if (opt->flags & PARSE_RANGE_DEFAULTS) {
+				ast_log(LOG_WARNING, "Failed to set %s=%s. Set to  %d instead due to range limit (%d, %d)\n", var->name, var->value, *field, (int) opt->args[1], (int) opt->args[2]);
+				res = 0;
+			} else if (opt->flags & PARSE_DEFAULT) {
+				ast_log(LOG_WARNING, "Failed to set %s=%s, Set to default value %d instead.\n", var->name, var->value, *field);
+				res = 0;
+			}
+		}
+	} else if ((opt->flags & PARSE_DEFAULT) && ast_parse_arg(var->value, flags, field, (unsigned int) opt->args[1])) {
+		ast_log(LOG_WARNING, "Attempted to set %s=%s, but set it to %u instead due to default)\n", var->name, var->value, *field);
+	} else {
+		res = ast_parse_arg(var->value, flags, field);
+	}
+
+	return res;
 }
 
 int ast_config_option_double_fn(const struct aco_option *opt, struct ast_variable *var, void *obj) {

Modified: team/twilson/config_work/main/udptl.c
URL: http://svnview.digium.com/svn/asterisk/team/twilson/config_work/main/udptl.c?view=diff&rev=362148&r1=362147&r2=362148
==============================================================================
--- team/twilson/config_work/main/udptl.c (original)
+++ team/twilson/config_work/main/udptl.c Sun Apr 15 20:34:52 2012
@@ -61,7 +61,7 @@
 #include "asterisk/frame.h"
 #include "asterisk/channel.h"
 #include "asterisk/acl.h"
-#include "asterisk/config.h"
+#include "asterisk/config_options.h"
 #include "asterisk/lock.h"
 #include "asterisk/utils.h"
 #include "asterisk/netsock2.h"
@@ -82,16 +82,11 @@
 #define DEFAULT_UDPTLSTART 4000
 #define DEFAULT_UDPTLEND 4999
 
-static int udptlstart = DEFAULT_UDPTLSTART;
-static int udptlend = DEFAULT_UDPTLEND;
+#define STR(x) STR1(x)
+#define STR1(x) #x
+
 static int udptldebug;	                    /*!< Are we debugging? */
 static struct ast_sockaddr udptldebugaddr;   /*!< Debug packets to/from this host */
-#ifdef SO_NO_CHECK
-static int nochecksums;
-#endif
-static int udptlfecentries;
-static int udptlfecspan;
-static int use_even_ports;
 
 #define LOCAL_FAX_MAX_DATAGRAM      1400
 #define DEFAULT_FAX_MAX_DATAGRAM    400
@@ -181,6 +176,34 @@
 };
 
 static AST_RWLIST_HEAD_STATIC(protos, ast_udptl_protocol);
+
+struct udptl_global_options {
+	unsigned int start;
+	unsigned int end;
+	unsigned int fecentries;
+	unsigned int fecspan;
+	unsigned int nochecksums; /* Can't use bitfield because it is passed by address */
+	unsigned int use_even_ports;
+};
+
+AST_MUTEX_DEFINE_STATIC(reload_lock);
+
+static int udptl_apply_config(void);
+
+struct aco_info cfg_info = {
+	.module = AST_MODULE,
+	.filename = "udptl.conf",
+	.apply_config = udptl_apply_config,
+};
+
+enum {
+	UDPTL_GENERAL = 0,
+
+	/* Must be last */
+	UDPTL_NUM_GLOBALS,
+} global_opt_type;
+
+static AO2_GLOBAL_OBJ_STATIC(globals, UDPTL_NUM_GLOBALS);
 
 static inline int udptl_debug_test_addr(const struct ast_sockaddr *addr)
 {
@@ -922,12 +945,19 @@
 	int startplace;
 	int i;
 	long int flags;
-
-	if (!(udptl = ast_calloc(1, sizeof(*udptl))))
+	RAII_VAR(struct udptl_global_options *, opts, ao2_global_obj_ref(globals, UDPTL_GENERAL), ao2_cleanup);
+
+	if (!opts) {
+		ast_log(LOG_ERROR, "Could not access global udptl options!\n");
 		return NULL;
-
-	udptl->error_correction_span = udptlfecspan;
-	udptl->error_correction_entries = udptlfecentries;
+	}
+
+	if (!(udptl = ast_calloc(1, sizeof(*udptl)))) {
+		return NULL;
+	}
+
+	udptl->error_correction_span = opts->fecspan;
+	udptl->error_correction_entries = opts->fecentries;
 
 	udptl->far_max_datagram = -1;
 	udptl->far_max_ifp = -1;
@@ -947,13 +977,15 @@
 	}
 	flags = fcntl(udptl->fd, F_GETFL);
 	fcntl(udptl->fd, F_SETFL, flags | O_NONBLOCK);
+
 #ifdef SO_NO_CHECK
-	if (nochecksums)
-		setsockopt(udptl->fd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
+	if (opts->nochecksums)
+		setsockopt(udptl->fd, SOL_SOCKET, SO_NO_CHECK, &opts->nochecksums, sizeof(opts->nochecksums));
 #endif
+
 	/* Find us a place */
-	x = (udptlstart == udptlend) ? udptlstart : (ast_random() % (udptlend - udptlstart)) + udptlstart;
-	if (use_even_ports && (x & 1)) {
+	x = (opts->start == opts->end) ? opts->start : (ast_random() % (opts->end - opts->start)) + opts->start;
+	if (opts->use_even_ports && (x & 1)) {
 		++x;
 	}
 	startplace = x;
@@ -969,13 +1001,13 @@
 			ast_free(udptl);
 			return NULL;
 		}
-		if (use_even_ports) {
+		if (opts->use_even_ports) {
 			x += 2;
 		} else {
 			++x;
 		}
-		if (x > udptlend)
-			x = udptlstart;
+		if (x > opts->end)
+			x = opts->start;
 		if (x == startplace) {
 			ast_log(LOG_WARNING, "No UDPTL ports remaining\n");
 			close(udptl->fd);
@@ -989,6 +1021,7 @@
 		udptl->io = io;
 		udptl->ioid = ast_io_add(udptl->io, udptl->fd, udptlread, AST_IO_IN, udptl);
 	}
+
 	return udptl;
 }
 
@@ -1303,109 +1336,109 @@
 	return CLI_SUCCESS;
 }
 
+static char *handle_cli_show_config(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+	RAII_VAR(struct udptl_global_options *, opts, NULL, ao2_cleanup);
+
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "udptl show config";
+		e->usage =
+			"Usage: udptl show config\n"
+			"       Dispaly udptl configuration options\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
+
+	if (!(opts = ao2_global_obj_ref(globals, UDPTL_GENERAL))) {
+		return CLI_FAILURE;
+	}
+
+	ast_cli(a->fd, "UDPTL Global options\n");
+	ast_cli(a->fd, "--------------------\n");
+	ast_cli(a->fd, "udptlstart:      %u\n", opts->start);
+	ast_cli(a->fd, "udptlend:        %u\n", opts->end);
+	ast_cli(a->fd, "udptlfecentries: %u\n", opts->fecentries);
+	ast_cli(a->fd, "udptlfecspan:    %u\n", opts->fecspan);
+	ast_cli(a->fd, "use_even_ports:  %s\n", AST_CLI_YESNO(opts->use_even_ports));
+	ast_cli(a->fd, "udptlchecksums: %s\n", AST_CLI_YESNO(!opts->nochecksums));
+
+	return CLI_SUCCESS;
+}
 
 static struct ast_cli_entry cli_udptl[] = {
-	AST_CLI_DEFINE(handle_cli_udptl_set_debug, "Enable/Disable UDPTL debugging")
+	AST_CLI_DEFINE(handle_cli_udptl_set_debug, "Enable/Disable UDPTL debugging"),
+	AST_CLI_DEFINE(handle_cli_show_config, "Show UDPTL config options"),
 };
 
+static void *udptl_cfg_alloc(const char *unused)
+{
+	struct udptl_global_options *opts;
+
+	if (!(opts = ao2_alloc(sizeof(*opts), NULL))) {
+		return NULL;
+	}
+
+	return opts;
+}
+
+static int removed_options_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
+{
+	if (!strcasecmp(var->name, "t38faxudpec")) {
+		ast_log(LOG_WARNING, "t38faxudpec in udptl.conf is no longer supported; use the t38pt_udptl configuration option in sip.conf instead.\n");
+	} else if (!strcasecmp(var->name, "t38faxmaxdatagram")) {
+		ast_log(LOG_WARNING, "t38faxmaxdatagram in udptl.conf is no longer supported; value is now supplied by T.38 applications.\n");
+	}
+	return 0;
+}
+
 static void __ast_udptl_reload(int reload)
 {
-	struct ast_config *cfg;
-	const char *s;
-	struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
-
-	cfg = ast_config_load2("udptl.conf", "udptl", config_flags);
-	if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) {
-		return;
-	}
-
-	udptlstart = DEFAULT_UDPTLSTART;
-	udptlend = DEFAULT_UDPTLEND;
-	udptlfecentries = 0;
-	udptlfecspan = 0;
-	use_even_ports = 0;
-
-	if (cfg) {
-		if ((s = ast_variable_retrieve(cfg, "general", "udptlstart"))) {
-			udptlstart = atoi(s);
-			if (udptlstart < 1024) {
-				ast_log(LOG_WARNING, "Ports under 1024 are not allowed for T.38.\n");
-				udptlstart = 1024;
-			}
-			if (udptlstart > 65535) {
-				ast_log(LOG_WARNING, "Ports over 65535 are invalid.\n");
-				udptlstart = 65535;
-			}
-		}
-		if ((s = ast_variable_retrieve(cfg, "general", "udptlend"))) {
-			udptlend = atoi(s);
-			if (udptlend < 1024) {
-				ast_log(LOG_WARNING, "Ports under 1024 are not allowed for T.38.\n");
-				udptlend = 1024;
-			}
-			if (udptlend > 65535) {
-				ast_log(LOG_WARNING, "Ports over 65535 are invalid.\n");
-				udptlend = 65535;
-			}
-		}
-		if ((s = ast_variable_retrieve(cfg, "general", "udptlchecksums"))) {
-#ifdef SO_NO_CHECK
-			if (ast_false(s))
-				nochecksums = 1;
-			else
-				nochecksums = 0;
-#else
-			if (ast_false(s))
-				ast_log(LOG_WARNING, "Disabling UDPTL checksums is not supported on this operating system!\n");
+	ast_mutex_lock(&reload_lock);
+	if (aco_process_config(&cfg_info, 0)) {
+		ast_log(LOG_WARNING, "Could not reload udptl config\n");
+	}
+	ast_mutex_unlock(&reload_lock);
+}
+
+static int udptl_apply_config(void) {
+	RAII_VAR(struct udptl_global_options *, new_global, aco_info_new_global_get(&cfg_info, "global"), ao2_cleanup);
+
+	if (!new_global) {
+		return -1;
+	}
+
+#ifndef SO_NO_CHECK
+	if (new_global->nochecksums) {
+		ast_log(LOG_WARNING, "Disabling UDPTL checksums is not supported on this operating system!\n");
+		new_global->nochecksums = 0;
+	}
 #endif
-		}
-		if ((s = ast_variable_retrieve(cfg, "general", "T38FaxUdpEC"))) {
-			ast_log(LOG_WARNING, "T38FaxUdpEC in udptl.conf is no longer supported; use the t38pt_udptl configuration option in sip.conf instead.\n");
-		}
-		if ((s = ast_variable_retrieve(cfg, "general", "T38FaxMaxDatagram"))) {
-			ast_log(LOG_WARNING, "T38FaxMaxDatagram in udptl.conf is no longer supported; value is now supplied by T.38 applications.\n");
-		}
-		if ((s = ast_variable_retrieve(cfg, "general", "UDPTLFECEntries"))) {
-			udptlfecentries = atoi(s);
-			if (udptlfecentries < 1) {
-				ast_log(LOG_WARNING, "Too small UDPTLFECEntries value.  Defaulting to 1.\n");
-				udptlfecentries = 1;
-			}
-			if (udptlfecentries > MAX_FEC_ENTRIES) {
-				ast_log(LOG_WARNING, "Too large UDPTLFECEntries value.  Defaulting to %d.\n", MAX_FEC_ENTRIES);
-				udptlfecentries = MAX_FEC_ENTRIES;
-			}
-		}
-		if ((s = ast_variable_retrieve(cfg, "general", "UDPTLFECSpan"))) {
-			udptlfecspan = atoi(s);
-			if (udptlfecspan < 1) {
-				ast_log(LOG_WARNING, "Too small UDPTLFECSpan value.  Defaulting to 1.\n");
-				udptlfecspan = 1;
-			}
-			if (udptlfecspan > MAX_FEC_SPAN) {
-				ast_log(LOG_WARNING, "Too large UDPTLFECSpan value.  Defaulting to %d.\n", MAX_FEC_SPAN);
-				udptlfecspan = MAX_FEC_SPAN;
-			}
-		}
-		if ((s = ast_variable_retrieve(cfg, "general", "use_even_ports"))) {
-			use_even_ports = ast_true(s);
-		}
-		ast_config_destroy(cfg);
-	}
-	if (use_even_ports && (udptlstart & 1)) {
-		++udptlstart;
-		ast_log(LOG_NOTICE, "Odd numbered udptlstart specified but use_even_ports enabled. udptlstart is now %d\n", udptlstart);
-	}
-	if (udptlstart > udptlend) {
-		ast_log(LOG_WARNING, "Unreasonable values for UDPTL start/end ports; defaulting to %d-%d.\n", DEFAULT_UDPTLSTART, DEFAULT_UDPTLEND);
-		udptlstart = DEFAULT_UDPTLSTART;
-		udptlend = DEFAULT_UDPTLEND;
-	}
-	if (use_even_ports && (udptlend & 1)) {
-		--udptlend;
-		ast_log(LOG_NOTICE, "Odd numbered udptlend specified but use_even_ports enabled. udptlend is now %d\n", udptlend);
-	}
-	ast_verb(2, "UDPTL allocating from port range %d -> %d\n", udptlstart, udptlend);
+
+	/* Fix up any global config values that we can handle before replacing the config */
+	if (new_global->use_even_ports && (new_global->start & 1)) {
+		++new_global->start;
+		ast_log(LOG_NOTICE, "Odd numbered udptlstart specified but use_even_ports enabled. udptlstart is now %d\n", new_global->start);
+	}
+	if (new_global->start > new_global->end) {
+		ast_log(LOG_WARNING, "Unreasonable values for UDPTL start/end ports; defaulting to %s-%s.\n", STR(DEFAULT_UDPTLSTART), STR(DEFAULT_UDPTLEND));
+		new_global->start = DEFAULT_UDPTLSTART;
+		new_global->end = DEFAULT_UDPTLEND;
+	}
+	if (new_global->use_even_ports && (new_global->end & 1)) {
+		--new_global->end;
+		ast_log(LOG_NOTICE, "Odd numbered udptlend specified but use_even_ports enabled. udptlend is now %d\n", new_global->end);
+	}
+
+	/* Replace existing config */
+	if (ao2_global_obj_replace_unref(globals, UDPTL_GENERAL, new_global)) {
+		ast_verb(2, "UDPTL allocating from port range %d -> %d via reload\n", new_global->start, new_global->end);
+	} else {
+		ast_verb(2, "UDPTL allocating from port range %d -> %d via intial load\n", new_global->start, new_global->end);
+	}
+
+	return 0;
 }
 
 int ast_udptl_reload(void)
@@ -1416,6 +1449,48 @@
 
 void ast_udptl_init(void)
 {
+	RAII_VAR(struct aco_type *, global_type, NULL, ao2_cleanup);
+
+	if (aco_info_init(&cfg_info)) {
+		return;
+	}
+
+	if (!(global_type = aco_type_global_alloc("global", CONTEXT_ALLOW, "general", udptl_cfg_alloc))) {
+		aco_info_destroy(&cfg_info);
+		return;
+	}
+
+	if (aco_type_register(&cfg_info, global_type)) {
+		aco_info_destroy(&cfg_info);
+		return;
+	}
+
+	aco_option_register(&cfg_info, "udptlstart", global_type, STR(DEFAULT_UDPTLSTART),
+		OPT_UINT_T, PARSE_IN_RANGE | PARSE_DEFAULT,
+		FLDSET(struct udptl_global_options, start), DEFAULT_UDPTLSTART, 1024, 65535);
+
+	aco_option_register(&cfg_info, "udptlend", global_type, STR(DEFAULT_UDPTLEND),
+		OPT_UINT_T, PARSE_IN_RANGE | PARSE_DEFAULT,
+		FLDSET(struct udptl_global_options, end), DEFAULT_UDPTLEND, 1024, 65535);
+
+	aco_option_register(&cfg_info, "udptlfecentries", global_type, NULL,
+		OPT_UINT_T, PARSE_IN_RANGE | PARSE_RANGE_DEFAULTS,
+		FLDSET(struct udptl_global_options, fecentries), 1, MAX_FEC_ENTRIES);
+
+	aco_option_register(&cfg_info, "udptlfecspan", global_type, NULL,
+		OPT_UINT_T, PARSE_IN_RANGE | PARSE_RANGE_DEFAULTS,
+		FLDSET(struct udptl_global_options, fecspan), 1, MAX_FEC_SPAN);
+
+	aco_option_register(&cfg_info, "udptlchecksums", global_type, "yes",
+		OPT_BOOL_T, 0, FLDSET(struct udptl_global_options, nochecksums));
+
+	aco_option_register(&cfg_info, "use_even_ports", global_type, "no",
+		OPT_BOOL_T, 1, FLDSET(struct udptl_global_options, use_even_ports));
+
+	aco_option_register_custom(&cfg_info, "t38faxudpec", global_type, NULL, removed_options_handler, 0);
+	aco_option_register_custom(&cfg_info, "t38faxmaxdatagram", global_type, NULL, removed_options_handler, 0);
+
 	ast_cli_register_multiple(cli_udptl, ARRAY_LEN(cli_udptl));
+
 	__ast_udptl_reload(0);
 }




More information about the svn-commits mailing list