]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
A few changes:
authorAnthony Minessale <anthony.minessale@gmail.com>
Sat, 27 Jan 2007 16:23:33 +0000 (16:23 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Sat, 27 Jan 2007 16:23:33 +0000 (16:23 +0000)
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.

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@4066 d0543943-73ff-0310-b7d9-9358b9ac24b2

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

index 398226ddb7282283a09d7a96acc64b8ae5b56417..d70d8bc3e1e10f5230763d5dffd7fe0893ce0886 100644 (file)
@@ -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>
index 0215a53ba7aae3218e071c780907c91281e32772..569b168d8e29df9ce27c05784cd6d7e5718ee365 100644 (file)
@@ -900,7 +900,7 @@ typedef struct switch_media_bug switch_media_bug_t;
 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 @@ typedef switch_xml_t (*switch_xml_search_function_t)(char *section,
                                                                                                         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 */
index d359fdbdc46f9f0f8e2d4d62eee2d1f9976f946f..569ba1a02376b5e4c54d866983d54b9f5ba7fa59 100644 (file)
@@ -182,7 +182,7 @@ switch_mutex_unlock(obj->flag_mutex);
   \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
index 0a453daa63ec6bf23dcbc12f637c0b14542c9905..909eefe1e9eec05b74415ffba822862b80c061d8 100644 (file)
@@ -324,9 +324,10 @@ SWITCH_DECLARE(switch_xml_t) switch_xml_open_cfg(char *file_path, switch_xml_t *
 ///\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
index 9b20625166328e7143594901b67d171b14e0e10b..6c4d926c480bd2e155b7c24ec85221f05a9b19ac 100644 (file)
@@ -514,7 +514,7 @@ static switch_status_t enum_lookup(char *root, char *in, enum_record_t **results
 }
 
 
-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;
index c8bb93ee3fb898cce41354a52601072003815843..4f9a03176cdb826eeaad7052e5ec6e6cdbd12d2d 100644 (file)
@@ -83,7 +83,7 @@ static void load_config(void)
        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;
index 25808dc22e962b3fc651b1f7095d7f16a8a354bf..77c065bac5fd4d9607ed6450c249ec78c0435e49 100644 (file)
@@ -193,12 +193,12 @@ static int parse_exten(switch_core_session_t *session, switch_xml_t xexten, swit
        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 @@ static switch_caller_extension_t *dialplan_hunt(switch_core_session_t *session)
     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 @@ static switch_caller_extension_t *dialplan_hunt(switch_core_session_t *session)
     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);
index dbed6c8f4e1f23372dd8fcd9bce96bfff4f9b791..7d6c357c0492d70686691b9ee8f727a9595f50e6 100644 (file)
 
 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 @@ static switch_xml_t xml_url_fetch(char *section,
                                                                  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 @@ static switch_xml_t xml_url_fetch(char *section,
     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 @@ static switch_xml_t xml_url_fetch(char *section,
 
        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_loadable_module_interface_t xml_curl_module_interface = {
 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 @@ SWITCH_MOD_DECLARE(switch_status_t) switch_module_load(const switch_loadable_mod
 
        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;
     }
 
index dd379f0b7b8db1fa6b828a91e07b58136b47e27f..39148abe2593acd665a71eb721c06e922652f495 100644 (file)
@@ -2701,13 +2701,21 @@ static void switch_core_standard_on_ring(switch_core_session_t *session)
             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;
                     }
index a424b21e01a88a3a8ec2df67744c6b593ee0f3cb..45d2594dcdeb751abca0476fb74c7c390ce676f6 100644 (file)
@@ -93,6 +93,7 @@ char *SWITCH_XML_NIL[] = { NULL }; // empty, null terminated array of strings
 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 @@ SWITCH_DECLARE(switch_xml_section_t) switch_xml_parse_section_string(char *str)
        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 @@ SWITCH_DECLARE(switch_status_t) switch_xml_bind_search_function(switch_xml_searc
 
        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 @@ SWITCH_DECLARE(switch_status_t) switch_xml_locate(char *section,
                        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);