[Freeswitch-svn] [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-svn mailing list