[Freeswitch-trunk] [commit] r12459 - in freeswitch/trunk/src: . include mod/applications/mod_skel
FreeSWITCH SVN
mrene at freeswitch.org
Thu Mar 5 07:03:29 PST 2009
Author: mrene
Date: Thu Mar 5 09:03:29 2009
New Revision: 12459
Log:
Integer (min,max) and string (regex) validation options added, mod_skel is my new playground
Added:
freeswitch/trunk/src/mod/applications/mod_skel/Makefile
Modified:
freeswitch/trunk/src/include/switch_xml_config.h
freeswitch/trunk/src/mod/applications/mod_skel/mod_skel.c
freeswitch/trunk/src/switch_xml_config.c
Modified: freeswitch/trunk/src/include/switch_xml_config.h
==============================================================================
--- freeswitch/trunk/src/include/switch_xml_config.h (original)
+++ freeswitch/trunk/src/include/switch_xml_config.h Thu Mar 5 09:03:29 2009
@@ -37,7 +37,7 @@
typedef enum {
SWITCH_CONFIG_INT, /*< (ptr=int* default=int data=NULL) Integer */
SWITCH_CONFIG_STRING, /*< (ptr=[char* or char ** (for alloc)] default=char* data=switch_xml_config_string_options_t*) Zero-terminated C-string */
- SWITCH_CONFIG_YESNO, /*< (ptr=switch_bool_t* default=switch_bool_t data=NULL) Yes and no */
+ SWITCH_CONFIG_BOOL, /*< (ptr=switch_bool_t* default=switch_bool_t data=NULL) Yes and no */
SWITCH_CONFIG_CUSTOM, /*< (ptr=<custom function data> default=<custom function data> data=switch_xml_config_callback_t) Custom, get value through function pointer */
SWITCH_CONFIG_ENUM, /*< (ptr=int* default=int data=switch_xml_config_enum_item_t*) */
SWITCH_CONFIG_FLAG, /*< (ptr=int32_t* default=switch_bool_t data=int (flag index) */
@@ -55,8 +55,16 @@
typedef struct {
switch_memory_pool_t *pool; /*< If set, the string will be allocated on the pool (unless the length param is > 0, then you misread this file)*/
switch_size_t length; /*< Length of the char array, or 0 if memory has to be allocated dynamically*/
+ char *validation_regex; /*< Enforce validation using this regular expression */
} switch_xml_config_string_options_t;
+typedef struct {
+ switch_bool_t enforce_min;
+ int min;
+ switch_bool_t enforce_max;
+ int max;
+} switch_xml_config_int_options_t;
+
struct switch_xml_config_item;
typedef struct switch_xml_config_item switch_xml_config_item_t;
@@ -73,12 +81,11 @@
void *defaultvalue; /*< Default value */
void *data; /*< Custom data (depending on the type) */
switch_xml_config_callback_t function; /*< Callback to be called after the var is parsed */
- void *functiondata; /*< Custom data passed to the callback */
} ;
-#define SWITCH_CONFIG_ITEM(_key, _type, _reloadable, _ptr, _defaultvalue, _data) { _key, _type, _reloadable, _ptr, _defaultvalue, _data, NULL, NULL }
-#define SWITCH_CONFIG_ITEM_CALLBACK(_key, _type, _reloadable, _ptr, _defaultvalue, _data, _functiondata) { _key, _type, _reloadable, _ptr, _defaultvalue, _data, _functiondata }
+#define SWITCH_CONFIG_ITEM(_key, _type, _reloadable, _ptr, _defaultvalue, _data) { _key, _type, _reloadable, _ptr, _defaultvalue, _data, NULL }
+#define SWITCH_CONFIG_ITEM_CALLBACK(_key, _type, _reloadable, _ptr, _defaultvalue, _data, _functiondata) { _key, _type, _reloadable, _ptr, _defaultvalue, _functiondata, _data }
#define SWITCH_CONFIG_ITEM_END() { NULL, SWITCH_CONFIG_LAST, 0, NULL ,NULL, NULL, NULL }
/*!
Added: freeswitch/trunk/src/mod/applications/mod_skel/Makefile
==============================================================================
--- (empty file)
+++ freeswitch/trunk/src/mod/applications/mod_skel/Makefile Thu Mar 5 09:03:29 2009
@@ -0,0 +1,2 @@
+BASE=../../../..
+include $(BASE)/build/modmake.rules
\ No newline at end of file
Modified: freeswitch/trunk/src/mod/applications/mod_skel/mod_skel.c
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_skel/mod_skel.c (original)
+++ freeswitch/trunk/src/mod/applications/mod_skel/mod_skel.c Thu Mar 5 09:03:29 2009
@@ -33,22 +33,105 @@
#include <switch.h>
/* Prototypes */
-//SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_skel_shutdown);
-//SWITCH_MODULE_RUNTIME_FUNCTION(mod_skel_runtime);
+SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_skel_shutdown);
+SWITCH_MODULE_RUNTIME_FUNCTION(mod_skel_runtime);
SWITCH_MODULE_LOAD_FUNCTION(mod_skel_load);
/* SWITCH_MODULE_DEFINITION(name, load, shutdown, runtime)
* Defines a switch_loadable_module_function_table_t and a static const char[] modname
*/
-SWITCH_MODULE_DEFINITION(mod_skel, mod_skel_load, NULL, NULL);
+SWITCH_MODULE_DEFINITION(mod_skel, mod_skel_load, mod_skel_shutdown, NULL);
+
+typedef enum {
+ CODEC_NEGOTIATION_GREEDY = 1,
+ CODEC_NEGOTIATION_GENEROUS = 2,
+ CODEC_NEGOTIATION_EVIL = 3
+} codec_negotiation_t;
+
+static struct {
+ char *codec_negotiation_str;
+ codec_negotiation_t codec_negotiation;
+ switch_bool_t sip_trace;
+ int integer;
+} globals;
+
+static switch_status_t config_callback_siptrace(switch_xml_config_item_t *data, switch_bool_t changed)
+{
+ switch_bool_t value = *(switch_bool_t*)data->ptr;
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "In siptrace callback: value %s changed %s\n",
+ value ? "true" : "false", changed ? "true" : "false");
+
+ /*
+ if (changed) {
+ nua_set_params(((sofia_profile_t*)data->functiondata)->nua, TPTAG_LOG(value), TAG_END());
+ }
+ */
+
+ return SWITCH_STATUS_SUCCESS;
+}
+
+static switch_status_t do_config(switch_bool_t reload)
+{
+ switch_xml_t cfg, xml, settings;
+ switch_xml_config_string_options_t config_opt_codec_negotiation = { NULL, 0, "greedy|generous|evil" };
+ /* enforce_min, min, enforce_max, max */
+ switch_xml_config_int_options_t config_opt_integer = { SWITCH_TRUE, 0, SWITCH_TRUE, 10 };
+ switch_xml_config_enum_item_t config_opt_codec_negotiation_enum[] = {
+ { "greedy", CODEC_NEGOTIATION_GREEDY },
+ { "generous", CODEC_NEGOTIATION_GENEROUS },
+ { "evil", CODEC_NEGOTIATION_EVIL },
+ { NULL, 0 }
+ };
+
+ switch_xml_config_item_t instructions[] = {
+ /* parameter name type reloadable pointer default value options structure */
+ SWITCH_CONFIG_ITEM("codec-negotiation-str", SWITCH_CONFIG_STRING, SWITCH_TRUE, &globals.codec_negotiation_str, "greedy", &config_opt_codec_negotiation),
+ SWITCH_CONFIG_ITEM("codec-negotiation", SWITCH_CONFIG_ENUM, SWITCH_TRUE, &globals.codec_negotiation, (void*)CODEC_NEGOTIATION_GREEDY, &config_opt_codec_negotiation_enum),
+ SWITCH_CONFIG_ITEM_CALLBACK("sip-trace", SWITCH_CONFIG_BOOL, SWITCH_TRUE, &globals.sip_trace, (void*)SWITCH_FALSE, config_callback_siptrace, NULL ),
+ SWITCH_CONFIG_ITEM("integer", SWITCH_CONFIG_INT, SWITCH_FALSE, &globals.integer, (void*)100, &config_opt_integer),
+ SWITCH_CONFIG_ITEM_END()
+ };
+
+ memset(&globals, 0, sizeof(globals));
+
+ if (!(xml = switch_xml_open_cfg("skel.conf", &cfg, NULL))) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not open skel.conf\n");
+ return SWITCH_STATUS_FALSE;
+ }
+
+ if ((settings = switch_xml_child(cfg, "settings"))) {
+ if (switch_xml_config_parse(switch_xml_child(settings, "param"), 0, instructions) == SWITCH_STATUS_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE,"Config parsed ok!\n");
+ return SWITCH_STATUS_SUCCESS;
+ }
+ }
+
+ if (cfg) {
+ switch_xml_free(cfg);
+ }
+
+ return SWITCH_STATUS_SUCCESS;
+}
+
+SWITCH_STANDARD_API(skel_function)
+{
+ stream->write_function(stream, "+OK Reloading\n");
+ do_config(SWITCH_TRUE);
+ return SWITCH_STATUS_SUCCESS;
+}
/* Macro expands to: switch_status_t mod_skel_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool) */
SWITCH_MODULE_LOAD_FUNCTION(mod_skel_load)
{
+ switch_api_interface_t *api_interface;
/* connect my internal structure to the blank pointer passed to me */
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Hello World!\n");
+
+ do_config(SWITCH_FALSE);
+
+ SWITCH_ADD_API(api_interface, "skel", "Skel API", skel_function, "syntax");
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS;
@@ -56,12 +139,12 @@
/*
Called when the system shuts down
- Macro expands to: switch_status_t mod_skel_shutdown()
+ Macro expands to: switch_status_t mod_skel_shutdown() */
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_skel_shutdown)
{
return SWITCH_STATUS_SUCCESS;
}
-*/
+
/*
If it exists, this is called in it's own thread when the module-load completes
@@ -85,5 +168,5 @@
* c-basic-offset:4
* End:
* For VIM:
- * vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
+ * vim:set softtabstop=4 shiftwidth=4 tabstop=4
*/
Modified: freeswitch/trunk/src/switch_xml_config.c
==============================================================================
--- freeswitch/trunk/src/switch_xml_config.c (original)
+++ freeswitch/trunk/src/switch_xml_config.c Thu Mar 5 09:03:29 2009
@@ -30,8 +30,6 @@
*
*/
-#define SWITCH_XML_CONFIG_TEST
-
#include <switch.h>
SWITCH_DECLARE(switch_status_t) switch_xml_config_parse(switch_xml_t xml, int reload, switch_xml_config_item_t *instructions)
@@ -62,6 +60,7 @@
switch(item->type) {
case SWITCH_CONFIG_INT:
{
+ switch_xml_config_int_options_t *int_options = (switch_xml_config_int_options_t*)item->data;
int *dest = (int*)item->ptr;
int intval;
if (value) {
@@ -69,9 +68,26 @@
intval = atoi(value);
} else {
intval = (int)(intptr_t)item->defaultvalue;
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid value [%s] for parameter [%s] setting default [%d]\n",
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid value [%s] for parameter [%s], setting default [%d]\n",
value, item->key, intval);
}
+
+ if (int_options) {
+ /* Enforce validation options */
+ if ((int_options->enforce_min && !(intval > int_options->min)) ||
+ (int_options->enforce_max && !(intval < int_options->max))) {
+ /* Validation failed, set default */
+ intval = (int)(intptr_t)item->defaultvalue;
+ /* Then complain */
+ if (int_options->enforce_min && int_options->enforce_max) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid value [%s] for parameter [%s], should be between [%d] and [%d], setting default [%d]\n",
+ value, item->key, int_options->min, int_options->max, intval);
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid value [%s] for parameter [%s], should be %s [%d], setting default [%d]\n",
+ value, item->key, int_options->enforce_min ? "at least" : "at max", int_options->enforce_min ? int_options->min : int_options->max, intval);
+ }
+ }
+ }
} else {
intval = (int)(intptr_t)item->defaultvalue;
}
@@ -85,40 +101,74 @@
case SWITCH_CONFIG_STRING:
{
switch_xml_config_string_options_t *string_options = (switch_xml_config_string_options_t*)item->data;
-
- if (string_options->length > 0) {
- const char *newstring = NULL;
- /* We have a preallocated buffer */
- char *dest = (char*)item->ptr;
- if (value) {
- newstring = value;
- } else if (item->defaultvalue) {
- newstring = item->defaultvalue;
- }
-
- if (newstring && strncasecmp(dest, newstring, string_options->length)) {
- switch_copy_string(dest, newstring, string_options->length);
+ const char *newstring = NULL;
+
+ if (!string_options) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing mandatory switch_xml_config_string_options_t structure for parameter [%s], skipping!\n",
+ item->key);
+ continue;
+ }
+
+ /* Perform validation */
+ if (value) {
+ if (!switch_strlen_zero(string_options->validation_regex)) {
+ if (switch_regex_match(value, string_options->validation_regex) == SWITCH_STATUS_SUCCESS) {
+ newstring = value; /* Regex match, accept value*/
+ } else {
+ newstring = (char*)item->defaultvalue; /* Regex failed */
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid value [%s] for parameter [%s], setting default [%s]\n",
+ value, item->key, newstring);
+ }
+ } else {
+ newstring = value; /* No validation */
}
} else {
- char **dest = (char**)item->ptr;
- const char *newstring = value ? value : (char*)item->defaultvalue;
+ newstring = (char*)item->defaultvalue;
+ }
+
+
+ if (newstring) {
+ if (string_options->length > 0) {
+ /* We have a preallocated buffer */
+ char *dest = (char*)item->ptr;
- if (newstring && strcasecmp(*dest, newstring)) {
- if (string_options->pool) {
- *dest = switch_core_strdup(string_options->pool, newstring);
- } else {
- switch_safe_free(*dest);
- *dest = strdup(newstring);
+ if (strncasecmp(dest, newstring, string_options->length)) {
+ switch_copy_string(dest, newstring, string_options->length);
+ changed = SWITCH_TRUE;
+ }
+ } else {
+ char **dest = (char**)item->ptr;
+
+ if (strcasecmp(*dest, newstring)) {
+ if (string_options->pool) {
+ *dest = switch_core_strdup(string_options->pool, newstring);
+ } else {
+ switch_safe_free(*dest);
+ *dest = strdup(newstring);
+ }
+ changed = SWITCH_TRUE;
}
- changed = SWITCH_TRUE;
}
}
}
break;
- case SWITCH_CONFIG_YESNO:
+ case SWITCH_CONFIG_BOOL:
{
switch_bool_t *dest = (switch_bool_t*)item->ptr;
- switch_bool_t newval = value ? !!switch_true(value) : (switch_bool_t)(intptr_t)item->defaultvalue;
+ switch_bool_t newval = SWITCH_FALSE;
+
+ if (value && switch_true(value)) {
+ newval = SWITCH_TRUE;
+ } else if (value && switch_false(value)) {
+ newval = SWITCH_FALSE;
+ } else if (value) {
+ /* Value isnt true or false */
+ newval = (switch_bool_t)(intptr_t)item->defaultvalue;
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid value [%s] for parameter [%s], setting default [%s]\n",
+ value, item->key, newval ? "true" : "false");
+ } else {
+ newval = (switch_bool_t)(intptr_t)item->defaultvalue;
+ }
if (*dest != newval) {
*dest = newval;
@@ -231,8 +281,8 @@
{
char *cf = "test.conf";
switch_xml_t cfg, xml, settings;
- switch_xml_config_string_options_t config_opt_stringalloc = { NULL, 0 }; /* No pool, use strdup */
- switch_xml_config_string_options_t config_opt_buffer = { NULL, 50 }; /* No pool, use current var as buffer */
+ switch_xml_config_string_options_t config_opt_stringalloc = { NULL, 0, NULL }; /* No pool, use strdup, no regex */
+ switch_xml_config_string_options_t config_opt_buffer = { NULL, 50, NULL }; /* No pool, use current var as buffer, no regex */
switch_xml_config_enum_item_t enumm_options[] = {
{ "test1", MYENUM_TEST1 },
{ "test2", MYENUM_TEST2 },
More information about the Freeswitch-trunk
mailing list