[Freeswitch-svn] [commit] r4066 - in freeswitch/trunk: conf src src/include src/mod/applications/mod_enum src/mod/dialplans/mod_dialplan_directory src/mod/dialplans/mod_dialplan_xml src/mod/xml_int/mod_xml_curl

Freeswitch SVN anthm at freeswitch.org
Sat Jan 27 11:23:34 EST 2007


Author: anthm
Date: Sat Jan 27 11:23:33 2007
New Revision: 4066

Modified:
   freeswitch/trunk/conf/xml_curl.conf.xml
   freeswitch/trunk/src/include/switch_types.h
   freeswitch/trunk/src/include/switch_utils.h
   freeswitch/trunk/src/include/switch_xml.h
   freeswitch/trunk/src/mod/applications/mod_enum/mod_enum.c
   freeswitch/trunk/src/mod/dialplans/mod_dialplan_directory/mod_dialplan_directory.c
   freeswitch/trunk/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c
   freeswitch/trunk/src/mod/xml_int/mod_xml_curl/mod_xml_curl.c
   freeswitch/trunk/src/switch_core.c
   freeswitch/trunk/src/switch_xml.c

Log:
A few changes:

1) The xml_curl now has a more enterprise config where it can have more than 1
   url configured so you could have failover. (*note the syntax change*)

2) dialplan modules now take an extra arguement making it possible to pass runtime params to
   them.  This is now used in mod_dialplan_xml to allow an alternate file path to be specified.

   dialplans were already stackable meaning you can configure a sofia profile, for example,
   to use enum followed by the default XML dialplan.

   e.g. <param name="dialplan" value="enum,XML"/>

   From now on, you can also specify :param after each dialplan name to allow param
   to be passed to the module.  mod_dialplan_xml uses this param as a way to override
   where it looks for the dialplan making it possible to stack mutiple calls to the XML dialplan.

   e.g. <param name="dialplan" value="XML:/some/xml/file.xml,XML"/>

   With this you can search the local file file.xml first and if there is still no match
   the hunt will move on to the standard XML using the onboard XML registry and or the external
   gateways.

   *NOTE* this alternate path does not use the external bindings but it does parse the #includes etc.



Modified: freeswitch/trunk/conf/xml_curl.conf.xml
==============================================================================
--- freeswitch/trunk/conf/xml_curl.conf.xml	(original)
+++ freeswitch/trunk/conf/xml_curl.conf.xml	Sat Jan 27 11:23:33 2007
@@ -1,11 +1,13 @@
 <configuration name="xml_curl.conf" description="cURL XML Gateway">
-  <settings>
-    <!-- The url to a gateway cgi that can generate xml similar to
-	 what's in this file only on-the-fly (leave it commented if you dont
-	 need it) -->
-    <!-- one or more |-delim of configuration|directory|dialplan -->
-    <!--<param name="gateway-url" value="http://www.mydomain.com/test.cgi" bindings="dialplan"/>-->
-    <!-- set this to provide authentication credentials to the server -->
-    <!--<param name="gateway-credentials" value="muser:mypass"/>-->
-  </settings>
+  <bindings>
+    <binding name="example">
+      <!-- The url to a gateway cgi that can generate xml similar to
+	   what's in this file only on-the-fly (leave it commented if you dont
+	   need it) -->
+      <!-- one or more |-delim of configuration|directory|dialplan -->
+      <param name="gateway-url" value="http://www.mydomain.com/test.cgi" bindings="dialplan"/>
+      <!-- set this to provide authentication credentials to the server -->
+      <!--<param name="gateway-credentials" value="muser:mypass"/>-->
+    </binding>
+  </bindings>
 </configuration>

Modified: freeswitch/trunk/src/include/switch_types.h
==============================================================================
--- freeswitch/trunk/src/include/switch_types.h	(original)
+++ freeswitch/trunk/src/include/switch_types.h	Sat Jan 27 11:23:33 2007
@@ -900,7 +900,7 @@
 typedef void (*switch_media_bug_callback_t)(switch_media_bug_t *, void *, switch_abc_type_t);
 typedef void (*switch_application_function_t)(switch_core_session_t *, char *);
 typedef void (*switch_event_callback_t)(switch_event_t *);
-typedef switch_caller_extension_t *(*switch_dialplan_hunt_function_t)(switch_core_session_t *);
+typedef switch_caller_extension_t *(*switch_dialplan_hunt_function_t)(switch_core_session_t *, void *);
 typedef switch_status_t (*switch_state_handler_t)(switch_core_session_t *);
 typedef switch_status_t (*switch_outgoing_channel_hook_t)(switch_core_session_t *, switch_caller_profile_t *, switch_core_session_t *);
 typedef switch_status_t (*switch_answer_channel_hook_t)(switch_core_session_t *);
@@ -945,7 +945,8 @@
 													 char *tag_name,
 													 char *key_name,
 													 char *key_value,
-													 char *params);
+													 char *params,
+                                                     void *user_data);
 
 /* things we don't deserve to know about */
 /*! \brief A channel */

Modified: freeswitch/trunk/src/include/switch_utils.h
==============================================================================
--- freeswitch/trunk/src/include/switch_utils.h	(original)
+++ freeswitch/trunk/src/include/switch_utils.h	Sat Jan 27 11:23:33 2007
@@ -182,7 +182,7 @@
   \param s the string to test
   \return true value if the string is NULL or zero length
 */
-#define switch_strlen_zero(s) (s && *s != '\0') ? 0 : 1
+#define switch_strlen_zero(s) (!s || *s == '\0')
 
 /*!
   \brief Wait a desired number of microseconds and yield the CPU

Modified: freeswitch/trunk/src/include/switch_xml.h
==============================================================================
--- freeswitch/trunk/src/include/switch_xml.h	(original)
+++ freeswitch/trunk/src/include/switch_xml.h	Sat Jan 27 11:23:33 2007
@@ -324,9 +324,10 @@
 ///\brief bind a search function to an external gateway
 ///\param function the search function to bind
 ///\param sections a bitmask of sections you wil service
+///\param user_data a pointer to private data to be used during the callback
 ///\return SWITCH_STATUS_SUCCESS if successful
 ///\note gateway functions will be executed in the order they were binded until a success is found else the root registry will be used
-SWITCH_DECLARE(switch_status_t) switch_xml_bind_search_function(switch_xml_search_function_t function, switch_xml_section_t sections);
+SWITCH_DECLARE(switch_status_t) switch_xml_bind_search_function(switch_xml_search_function_t function, switch_xml_section_t sections, void *user_data);
 
 ///\brief parse a string for a list of sections
 ///\param str a | delimited list of section names

Modified: freeswitch/trunk/src/mod/applications/mod_enum/mod_enum.c
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_enum/mod_enum.c	(original)
+++ freeswitch/trunk/src/mod/applications/mod_enum/mod_enum.c	Sat Jan 27 11:23:33 2007
@@ -514,7 +514,7 @@
 }
 
 
-static switch_caller_extension_t *enum_dialplan_hunt(switch_core_session_t *session)
+static switch_caller_extension_t *enum_dialplan_hunt(switch_core_session_t *session, void *arg)
 {
 	switch_caller_extension_t *extension = NULL;
 	switch_caller_profile_t *caller_profile;

Modified: freeswitch/trunk/src/mod/dialplans/mod_dialplan_directory/mod_dialplan_directory.c
==============================================================================
--- freeswitch/trunk/src/mod/dialplans/mod_dialplan_directory/mod_dialplan_directory.c	(original)
+++ freeswitch/trunk/src/mod/dialplans/mod_dialplan_directory/mod_dialplan_directory.c	Sat Jan 27 11:23:33 2007
@@ -83,7 +83,7 @@
 	switch_xml_free(xml);
 }
 
-static switch_caller_extension_t *directory_dialplan_hunt(switch_core_session_t *session)
+static switch_caller_extension_t *directory_dialplan_hunt(switch_core_session_t *session, void *arg)
 {
 	switch_caller_profile_t *caller_profile;
 	switch_caller_extension_t *extension = NULL;

Modified: freeswitch/trunk/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c
==============================================================================
--- freeswitch/trunk/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c	(original)
+++ freeswitch/trunk/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c	Sat Jan 27 11:23:33 2007
@@ -193,12 +193,12 @@
 	return proceed;
 }
 
-static switch_caller_extension_t *dialplan_hunt(switch_core_session_t *session)
+static switch_caller_extension_t *dialplan_hunt(switch_core_session_t *session, void *arg)
 {
 	switch_caller_profile_t *caller_profile;
 	switch_caller_extension_t *extension = NULL;
 	switch_channel_t *channel;
-	switch_xml_t cfg, xml, xcontext, xexten;
+	switch_xml_t alt_root = NULL, cfg, xml, xcontext, xexten;
 	char *context = NULL;
     switch_stream_handle_t stream = {0};
     switch_size_t encode_len = 1024, new_len = 0;
@@ -206,6 +206,7 @@
     char *prof[11] = {0}, *prof_names[11] = {0}, *e = NULL;
     switch_hash_index_t *hi;
     uint32_t x = 0;
+    char *alt_path = (char *) arg;
 
 	channel = switch_core_session_get_channel(session);
 	if ((caller_profile = switch_channel_get_caller_profile(channel))) {
@@ -296,11 +297,28 @@
     if (e && *e == '&') {
         *e = '\0';
     }
+
+    if (!switch_strlen_zero(alt_path)) {
+        switch_xml_t conf = NULL, tag = NULL;
+        if (!(alt_root = switch_xml_parse_file(alt_path))) {
+            switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of [%s] failed\n", alt_path);
+            return NULL;
+        }
         
-	if (switch_xml_locate("dialplan", NULL, NULL, NULL, &xml, &cfg, stream.data) != SWITCH_STATUS_SUCCESS) {
-		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of dialplan failed\n");
-		return NULL;
-	}
+		if ((conf = switch_xml_find_child(alt_root, "section", "name", "dialplan")) && 
+			(tag = switch_xml_find_child(conf, "dialplan", NULL, NULL))) {
+            switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Getting dialplan from alternate path: %s\n", alt_path);
+            xml = alt_root;
+            cfg = tag;
+        } else {
+            switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of dialplan failed\n");
+            return NULL;
+        }
+    } else if (switch_xml_locate("dialplan", NULL, NULL, NULL, &xml, &cfg, stream.data) != SWITCH_STATUS_SUCCESS) {
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of dialplan failed\n");
+        return NULL;
+    }
+    
 	
     switch_safe_free(stream.data);
     switch_safe_free(encode_buf);

Modified: freeswitch/trunk/src/mod/xml_int/mod_xml_curl/mod_xml_curl.c
==============================================================================
--- freeswitch/trunk/src/mod/xml_int/mod_xml_curl/mod_xml_curl.c	(original)
+++ freeswitch/trunk/src/mod/xml_int/mod_xml_curl/mod_xml_curl.c	Sat Jan 27 11:23:33 2007
@@ -33,15 +33,13 @@
 
 static const char modname[] = "mod_xml_curl";
 
-static struct {
+struct xml_binding {
 	char *url;
 	char *bindings;
     char *cred;
-} globals;
+};
 
-SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_url, globals.url);
-SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_bindings, globals.bindings);
-SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_cred, globals.cred);
+typedef struct xml_binding xml_binding_t;
 
 struct config_data {
 	char *name;
@@ -62,7 +60,8 @@
 								  char *tag_name,
 								  char *key_name,
 								  char *key_value,
-								  char *params)
+								  char *params,
+                                  void *user_data)
 {
 	char filename[512] = "";
 	CURL *curl_handle = NULL;
@@ -71,6 +70,22 @@
     char *data = NULL;
 	switch_uuid_t uuid;
 	char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1];
+    xml_binding_t *binding = (xml_binding_t *) user_data;
+    char *file_url;
+
+    if (!binding) {
+        return NULL;
+    }
+
+    if (file_url = strstr(binding->url, "file:")) {
+        file_url += 5;
+     
+        if (!(xml = switch_xml_parse_file(file_url))) {
+            switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Parsing Result!\n");
+        }
+   
+        return xml;
+    }
 
     if (!(data = switch_mprintf("section=%s&tag_name=%s&key_name=%s&key_value=%s%s%s", 
                                 section,
@@ -88,20 +103,20 @@
 
 	snprintf(filename, sizeof(filename), "%s%s.tmp.xml", SWITCH_GLOBAL_dirs.temp_dir, uuid_str);
 	curl_handle = curl_easy_init();
-	if (!strncasecmp(globals.url, "https", 5)) {
+	if (!strncasecmp(binding->url, "https", 5)) {
 		curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0);
 		curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0);
 	}
 		
 	config_data.name = filename;
 	if ((config_data.fd = open(filename, O_CREAT | O_RDWR | O_TRUNC)) > -1) {
-        if (!switch_strlen_zero(globals.cred)) {
+        if (!switch_strlen_zero(binding->cred)) {
             curl_easy_setopt(curl_handle, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
-            curl_easy_setopt(curl_handle, CURLOPT_USERPWD, globals.cred);
+            curl_easy_setopt(curl_handle, CURLOPT_USERPWD, binding->cred);
         }
         curl_easy_setopt(curl_handle, CURLOPT_POST, 1);
         curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, data);
-		curl_easy_setopt(curl_handle, CURLOPT_URL, globals.url);
+		curl_easy_setopt(curl_handle, CURLOPT_URL, binding->url);
 		curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, file_callback);
 		curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&config_data);
 		curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "freeswitch-xml/1.0");
@@ -140,31 +155,71 @@
 static switch_status_t do_config(void) 
 {
 	char *cf = "xml_curl.conf";
-	switch_xml_t cfg, xml, settings, param;
+	switch_xml_t cfg, xml, bindings_tag, binding_tag, param;
+    xml_binding_t *binding = NULL;
+    int x = 0;
 
 	if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of %s failed\n", cf);
 		return SWITCH_STATUS_TERM;
 	}
 
-	if ((settings = switch_xml_child(cfg, "settings"))) {
-		for (param = switch_xml_child(settings, "param"); param; param = param->next) {
+	if (!(bindings_tag = switch_xml_child(cfg, "bindings"))) {
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing <bindings> tag!\n");
+        return SWITCH_STATUS_FALSE;
+    }
+
+	for (binding_tag = switch_xml_child(bindings_tag, "binding"); binding_tag; binding_tag = binding_tag->next) {
+        char *bname = (char *) switch_xml_attr_soft(binding_tag, "name");
+        char *url = NULL;
+        char *bind_cred = NULL;
+        char *bind_mask = NULL;
+
+		for (param = switch_xml_child(binding_tag, "param"); param; param = param->next) {
 			char *var = (char *) switch_xml_attr_soft(param, "name");
 			char *val = (char *) switch_xml_attr_soft(param, "value");
-
             if (!strcasecmp(var, "gateway-url")) {
-				char *bindings = (char *) switch_xml_attr_soft(param, "bindings");
-				set_global_bindings(bindings);
-				set_global_url(val);
+				bind_mask = (char *) switch_xml_attr_soft(param, "bindings");
+                if (val) {
+                    url = val;
+                }
 			} else if (!strcasecmp(var, "gateway-credentials")) {
-                set_global_cred(val);
+                bind_cred = var;
             }
 		}
+        
+        if (!url) {
+            switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Binding has no url!\n");
+            continue;
+        }
+
+        if (!(binding = malloc(sizeof(*binding)))) {
+            return SWITCH_STATUS_FALSE;
+        }
+        memset(binding, 0, sizeof(*binding));
+
+        binding->url = strdup(url);
+
+        if (bind_mask) {
+            binding->bindings = strdup(bind_mask);
+        }
+
+        if (bind_cred) {
+            binding->cred = strdup(bind_cred);
+        }
+        
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Binding [%s] XML Fetch Function [%s] [%s]\n", 
+                          switch_strlen_zero(bname) ? "N/A" : bname,
+                          binding->url,
+                          binding->bindings ? binding->bindings : "all");
+		switch_xml_bind_search_function(xml_url_fetch, switch_xml_parse_section_string(binding->bindings), binding);
+        x++;
+        binding = NULL;
 	}
 
 	switch_xml_free(xml);
 
-	return globals.url ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
+	return x ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
 }
 
 
@@ -175,10 +230,7 @@
 
 	if (do_config() == SWITCH_STATUS_SUCCESS) {
         curl_global_init(CURL_GLOBAL_ALL);
-		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Binding XML Fetch Function [%s] [%s]\n", 
-                          globals.url, globals.bindings ? globals.bindings : "all");
-		switch_xml_bind_search_function(xml_url_fetch, switch_xml_parse_section_string(globals.bindings));
-	} else {
+    } else {
         return SWITCH_STATUS_FALSE;
     }
 

Modified: freeswitch/trunk/src/switch_core.c
==============================================================================
--- freeswitch/trunk/src/switch_core.c	(original)
+++ freeswitch/trunk/src/switch_core.c	Sat Jan 27 11:23:33 2007
@@ -2701,13 +2701,21 @@
             if ((dpstr = switch_core_session_strdup(session, caller_profile->dialplan))) {
                 argc = switch_separate_string(dpstr, ',', dp, (sizeof(dp) / sizeof(dp[0]))); 
                 for (x = 0; x < argc; x++) {
-                    if (!(dialplan_interface = switch_loadable_module_get_dialplan_interface(dp[x]))) {
+                    char *dpname = dp[x];
+                    char *dparg = NULL;
+
+                    if (dpname) {
+                        if ((dparg = strchr(dpname, ':'))) {
+                            *dparg++ = '\0';
+                        }
+                    }
+                    if (!(dialplan_interface = switch_loadable_module_get_dialplan_interface(dpname))) {
                         continue;
                     }
 
                     count++;
 
-                    if ((extension = dialplan_interface->hunt_function(session)) != 0) {
+                    if ((extension = dialplan_interface->hunt_function(session, dparg)) != 0) {
                         switch_channel_set_caller_extension(session->channel, extension);
                         return;
                     }

Modified: freeswitch/trunk/src/switch_xml.c
==============================================================================
--- freeswitch/trunk/src/switch_xml.c	(original)
+++ freeswitch/trunk/src/switch_xml.c	Sat Jan 27 11:23:33 2007
@@ -93,6 +93,7 @@
 struct switch_xml_binding {
 	switch_xml_search_function_t function;
 	switch_xml_section_t sections;
+    void *user_data;
 	struct switch_xml_binding *next;
 };
 
@@ -141,7 +142,7 @@
 	return sections;
 }
 
-SWITCH_DECLARE(switch_status_t) switch_xml_bind_search_function(switch_xml_search_function_t function, switch_xml_section_t sections)
+SWITCH_DECLARE(switch_status_t) switch_xml_bind_search_function(switch_xml_search_function_t function, switch_xml_section_t sections, void *user_data)
 {
 	switch_xml_binding_t *binding = NULL, *ptr = NULL;
 	assert(function != NULL);
@@ -152,6 +153,7 @@
 
 	binding->function = function;
 	binding->sections = sections;
+    binding->user_data = user_data;
 
 	switch_mutex_lock(XML_LOCK);
 	for (ptr = BINDINGS; ptr && ptr->next; ptr = ptr->next);
@@ -1020,7 +1022,7 @@
 			continue;
 		}
 
-		if ((xml = binding->function(section, tag_name, key_name, key_value, params))) {
+		if ((xml = binding->function(section, tag_name, key_name, key_value, params, binding->user_data))) {
 			const char *err = NULL;
 			
 			err = switch_xml_error(xml);



More information about the Freeswitch-svn mailing list