---
 include/ipconfig.h |   35 +++
 src/connman.h      |    7 +
 src/ipconfig.c     |  805 ++++++++++++++++++++++++++++++++++++++++++++++++----
 3 files changed, 796 insertions(+), 51 deletions(-)

diff --git a/include/ipconfig.h b/include/ipconfig.h
index 28a3d6a..16843ca 100644
--- a/include/ipconfig.h
+++ b/include/ipconfig.h
@@ -26,6 +26,8 @@
 extern "C" {
 #endif
 
+#include <stdint.h>
+
 /**
  * SECTION:ipconfig
  * @title: IP configuration premitives
@@ -49,6 +51,31 @@ void connman_ipaddress_clear(struct connman_ipaddress 
*ipaddress);
 void connman_ipaddress_copy(struct connman_ipaddress *ipaddress,
                                        struct connman_ipaddress *source);
 
+struct connman_manual_proxy {
+       char *http;
+       uint16_t http_port;
+       char *https;
+       uint16_t https_port;
+       char *ftp;
+       uint16_t ftp_port;
+       char *socks;
+       uint16_t socks_port;
+       char *rtsp;
+       uint16_t rtsp_port;
+       GSList *ignore;
+};
+
+struct connman_manual_proxy *connman_manual_proxy_alloc(void);
+void connman_manual_proxy_free(struct connman_manual_proxy *proxy);
+int connman_manual_proxy_set(struct connman_manual_proxy *proxy,
+                       const char *http, uint16_t http_port, const char *https,
+                       uint16_t https_port, const char *ftp, uint16_t ftp_port,
+                       const char *socks, uint16_t socks_port, const char 
*rtsp,
+                       uint16_t rtsp_port, const GSList *ignore);
+void connman_manual_proxy_clear(struct connman_manual_proxy *proxy);
+void connman_manual_proxy_copy(struct connman_manual_proxy *proxy,
+                                       struct connman_manual_proxy *source);
+
 enum connman_ipconfig_type {
        CONNMAN_IPCONFIG_TYPE_UNKNOWN = 0,
        CONNMAN_IPCONFIG_TYPE_IPV4    = 1,
@@ -63,6 +90,14 @@ enum connman_ipconfig_method {
        CONNMAN_IPCONFIG_METHOD_DHCP    = 4,
 };
 
+enum connman_ipconfig_proxy_method {
+       CONNMAN_IPCONFIG_PROXY_METHOD_UNKNOWN     = 0,
+       CONNMAN_IPCONFIG_PROXY_METHOD_DIRECT      = 1,
+       CONNMAN_IPCONFIG_PROXY_METHOD_AUTO        = 2,
+       CONNMAN_IPCONFIG_PROXY_METHOD_MANUAL      = 3,
+       CONNMAN_IPCONFIG_PROXY_METHOD_AUTO_CONFIG = 4,
+};
+
 struct connman_ipconfig;
 
 struct connman_ipconfig_ops {
diff --git a/src/connman.h b/src/connman.h
index 55e72ec..6f3e1a9 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -251,6 +251,13 @@ int __connman_ipconfig_clear_address(struct 
connman_ipconfig *ipconfig);
 int __connman_ipconfig_set_proxy_autoconfig(struct connman_ipconfig *ipconfig,
                                                        const char *url);
 const char *__connman_ipconfig_get_proxy_autoconfig(struct connman_ipconfig 
*ipconfig);
+int __connman_ipconfig_set_proxy_auto(struct connman_ipconfig *ipconfig,
+                                     const char *url);
+const char *__connman_ipconfig_get_proxy_auto(struct connman_ipconfig 
*ipconfig);
+int __connman_ipconfig_set_proxy_manual(struct connman_ipconfig *ipconfig,
+                                       struct connman_manual_proxy 
*manual_proxy);
+const struct connman_manual_proxy *__connman_ipconfig_get_proxy_manual(
+    struct connman_ipconfig *ipconfig);
 
 int __connman_ipconfig_load(struct connman_ipconfig *ipconfig,
                GKeyFile *keyfile, const char *identifier, const char *prefix);
diff --git a/src/ipconfig.c b/src/ipconfig.c
index 0a7eb8b..fd559be 100644
--- a/src/ipconfig.c
+++ b/src/ipconfig.c
@@ -52,6 +52,10 @@ struct connman_ipconfig {
        struct connman_ipaddress *system;
 
        struct connman_ipconfig *ipv6;
+
+       enum connman_ipconfig_proxy_method proxy;
+       char *pac;
+       struct connman_manual_proxy *manual_proxy;
 };
 
 struct connman_ipdevice {
@@ -74,7 +78,6 @@ struct connman_ipdevice {
        char *ipv4_gateway;
        char *ipv6_gateway;
 
-       char *proxy;
        char *pac;
 
        struct connman_ipconfig *config;
@@ -231,6 +234,170 @@ void connman_ipaddress_copy(struct connman_ipaddress 
*ipaddress,
        ipaddress->gateway = g_strdup(source->gateway);
 }
 
+struct connman_manual_proxy *connman_manual_proxy_alloc(void)
+{
+       return g_try_new0(struct connman_manual_proxy, 1);
+}
+
+void connman_manual_proxy_free(struct connman_manual_proxy *proxy)
+{
+       connman_manual_proxy_clear(proxy);
+
+       g_free(proxy);
+}
+
+static int update_proxy(char **host, uint16_t *port,
+                       const char *new_host, uint16_t new_port)
+{
+       int num_proxies = 0;
+
+       DBG("");
+
+       if (new_host != NULL) {
+               /* Proxy host update requested */
+               if (new_host[0]) {
+                       num_proxies++;
+                       if (new_port)
+                               *port = new_port;
+
+                       if (*port) {
+                               /* Update proxy only if port is valid */
+                               g_free(*host);
+                               *host = g_strdup(new_host);
+                       }
+               } else {
+                       /* Empty proxy, clear settings */
+                       g_free(*host);
+                       *host = NULL;
+                       *port = 0;
+               }
+       }
+
+       if (*host != NULL) {
+               /* Update port if new one is valid */
+               num_proxies++;
+
+               if (new_port)
+                       *port = new_port;
+       }
+
+       return num_proxies;
+}
+
+static void free_manual_proxy_ignore(GSList *ignore)
+{
+       GSList *list;
+
+       for (list = ignore; list; list = list->next) {
+               g_free(list->data);
+               list->data = NULL;
+       }
+
+       g_slist_free(ignore);
+}
+
+static GSList *copy_manual_proxy_ignore(const GSList *source)
+{
+       GSList *list;
+       GSList *ignore = NULL;
+
+       DBG("");
+
+       if (source == NULL)
+               return NULL;
+
+       for (list = (GSList *) source; list; list = list->next)
+               ignore = g_slist_append(ignore,
+                                       g_strdup((char *) list->data));
+
+       return ignore;
+}
+
+int connman_manual_proxy_set(struct connman_manual_proxy *proxy,
+                       const char *http, uint16_t http_port, const char *https,
+                       uint16_t https_port, const char *ftp, uint16_t ftp_port,
+                       const char *socks, uint16_t socks_port, const char 
*rtsp,
+                       uint16_t rtsp_port, const GSList *ignore)
+{
+       int num_proxies = 0;
+
+       if (proxy == NULL)
+               return -EINVAL;
+
+       DBG("proxy %p/%s:%d/%s:%d/%s:%d/%s:%d/%s:%d/%p", proxy, http,
+               http_port, https, https_port, ftp, ftp_port, socks,
+               socks_port, rtsp, rtsp_port, ignore);
+
+       num_proxies += update_proxy(&proxy->http, &proxy->http_port, http,
+                               http_port);
+       num_proxies += update_proxy(&proxy->https, &proxy->https_port, https,
+                               https_port);
+       num_proxies += update_proxy(&proxy->ftp, &proxy->ftp_port, ftp,
+                               ftp_port);
+       num_proxies += update_proxy(&proxy->socks, &proxy->socks_port, socks,
+                               socks_port);
+       num_proxies += update_proxy(&proxy->rtsp, &proxy->rtsp_port, rtsp,
+                               rtsp_port);
+
+       if (ignore) {
+               free_manual_proxy_ignore(proxy->ignore);
+               proxy->ignore = NULL;
+
+               if (ignore && ignore->data && ((char *)(ignore->data))[0]) {
+                       DBG("setting ignore list");
+                       proxy->ignore = copy_manual_proxy_ignore(ignore);
+                       num_proxies++;
+               }
+       }
+
+       if (num_proxies == 0)
+               return -EINVAL;
+
+       return 0;
+}
+
+void connman_manual_proxy_clear(struct connman_manual_proxy *proxy)
+{
+       if (proxy == NULL)
+               return;
+
+       g_free(proxy->http);
+       g_free(proxy->https);
+       g_free(proxy->ftp);
+       g_free(proxy->socks);
+       g_free(proxy->rtsp);
+
+       free_manual_proxy_ignore(proxy->ignore);
+
+       memset(proxy, 0, sizeof(struct connman_manual_proxy));
+}
+
+void connman_manual_proxy_copy(struct connman_manual_proxy *proxy,
+                                       struct connman_manual_proxy *source)
+{
+       if (proxy == NULL || source == NULL)
+               return;
+
+       connman_manual_proxy_clear(proxy);
+
+       proxy->http = g_strdup(source->http);
+       proxy->http_port = source->http_port;
+
+       proxy->https = g_strdup(source->https);
+       proxy->https_port = source->https_port;
+
+       proxy->ftp = g_strdup(source->ftp);
+       proxy->ftp_port = source->ftp_port;
+
+       proxy->socks = g_strdup(source->socks);
+       proxy->socks_port = source->socks_port;
+
+       proxy->rtsp = g_strdup(source->rtsp);
+       proxy->rtsp_port = source->rtsp_port;
+
+       proxy->ignore = copy_manual_proxy_ignore(source->ignore);
+}
+
 static void free_address_list(struct connman_ipdevice *ipdevice)
 {
        GSList *list;
@@ -305,7 +472,6 @@ static void free_ipdevice(gpointer data)
        free_address_list(ipdevice);
        g_free(ipdevice->ipv4_gateway);
        g_free(ipdevice->ipv6_gateway);
-       g_free(ipdevice->proxy);
        g_free(ipdevice->pac);
 
        g_free(ipdevice->address);
@@ -1210,6 +1376,8 @@ int __connman_ipconfig_set_proxy_autoconfig(struct 
connman_ipconfig *ipconfig,
        g_free(ipdevice->pac);
        ipdevice->pac = g_strdup(url);
 
+       ipconfig->proxy = CONNMAN_IPCONFIG_PROXY_METHOD_AUTO_CONFIG;
+
        return 0;
 }
 
@@ -1219,7 +1387,8 @@ const char 
*__connman_ipconfig_get_proxy_autoconfig(struct connman_ipconfig *ipc
 
        DBG("ipconfig %p", ipconfig);
 
-       if (ipconfig == NULL || ipconfig->index < 0)
+       if (ipconfig == NULL || ipconfig->index < 0 ||
+               ipconfig->proxy != CONNMAN_IPCONFIG_PROXY_METHOD_AUTO_CONFIG)
                return NULL;
 
        ipdevice = g_hash_table_lookup(ipdevice_hash,
@@ -1230,6 +1399,76 @@ const char 
*__connman_ipconfig_get_proxy_autoconfig(struct connman_ipconfig *ipc
        return ipdevice->pac;
 }
 
+int __connman_ipconfig_set_proxy_auto(struct connman_ipconfig *ipconfig,
+                                     const char *url)
+{
+       DBG("ipconfig %p", ipconfig);
+
+       if (ipconfig == NULL)
+               return -ENODEV;
+
+       g_free(ipconfig->pac);
+       ipconfig->pac = g_strdup(url);
+
+       return 0;
+}
+
+const char *__connman_ipconfig_get_proxy_auto(struct connman_ipconfig 
*ipconfig)
+{
+       DBG("ipconfig %p", ipconfig);
+
+       if (ipconfig == NULL)
+               return NULL;
+
+       return ipconfig->pac;
+}
+
+int __connman_ipconfig_set_proxy_manual(struct connman_ipconfig *ipconfig,
+                                       struct connman_manual_proxy 
*manual_proxy)
+{
+       DBG("ipconfig %p", ipconfig);
+
+       if (ipconfig == NULL)
+               return -ENODEV;
+
+       if (manual_proxy == NULL) {
+               connman_manual_proxy_free(ipconfig->manual_proxy);
+               ipconfig->manual_proxy = NULL;
+       } else {
+               if (ipconfig->manual_proxy == NULL)
+                       ipconfig->manual_proxy = connman_manual_proxy_alloc();
+
+               if (connman_manual_proxy_set(ipconfig->manual_proxy,
+                                               manual_proxy->http,
+                                               manual_proxy->http_port,
+                                               manual_proxy->https,
+                                               manual_proxy->https_port,
+                                               manual_proxy->ftp,
+                                               manual_proxy->ftp_port,
+                                               manual_proxy->socks,
+                                               manual_proxy->socks_port,
+                                               manual_proxy->rtsp,
+                                               manual_proxy->rtsp_port,
+                                               manual_proxy->ignore) != 0) {
+                       connman_manual_proxy_free(ipconfig->manual_proxy);
+                       ipconfig->manual_proxy = NULL;
+               }
+       }
+
+       return 0;
+}
+
+const struct connman_manual_proxy *__connman_ipconfig_get_proxy_manual(
+       struct connman_ipconfig *ipconfig)
+{
+       DBG("ipconfig %p", ipconfig);
+
+       if (ipconfig == NULL)
+               return NULL;
+
+       return ipconfig->manual_proxy;
+}
+
 int __connman_ipconfig_enable(struct connman_ipconfig *ipconfig)
 {
        struct connman_ipdevice *ipdevice;
@@ -1603,72 +1842,198 @@ int __connman_ipconfig_set_config(struct 
connman_ipconfig *ipconfig,
        return 0;
 }
 
-void __connman_ipconfig_append_proxy(struct connman_ipconfig *ipconfig,
-                                                       DBusMessageIter *iter)
+static const char *proxymethod2string(enum connman_ipconfig_proxy_method 
method)
 {
-       struct connman_ipdevice *ipdevice;
-       const char *method = "direct";
-
-       ipdevice = g_hash_table_lookup(ipdevice_hash,
-                                        GINT_TO_POINTER(ipconfig->index));
-       if (ipdevice == NULL)
-               goto done;
+       switch(method) {
+       case CONNMAN_IPCONFIG_PROXY_METHOD_DIRECT:
+               return "direct";
+       case CONNMAN_IPCONFIG_PROXY_METHOD_AUTO:
+               return "auto";
+       case CONNMAN_IPCONFIG_PROXY_METHOD_MANUAL:
+               return "manual";
+       case CONNMAN_IPCONFIG_PROXY_METHOD_AUTO_CONFIG:
+               return "auto-config";
+       default:
+               break;
+       }
 
-       if (ipdevice->pac == NULL)
-               goto done;
+       return NULL;
+}
 
-       method = "auto-config";
+static void append_ignore_list(DBusMessageIter *iter, void *user_data)
+{
+       GSList *proxy_ignore = user_data;
+       GSList *list;
 
-       connman_dbus_dict_append_basic(iter, "URL",
-                                       DBUS_TYPE_STRING, &ipdevice->pac);
+       DBG("");
 
-done:
-       connman_dbus_dict_append_basic(iter, "Method",
-                                               DBUS_TYPE_STRING, &method);
+       for (list = proxy_ignore; list; list = list->next) {
+               if (list->data)
+                       dbus_message_iter_append_basic(iter,
+                                               DBUS_TYPE_STRING, 
+                                               &list->data);
+       }
 }
 
-void __connman_ipconfig_append_proxyconfig(struct connman_ipconfig *ipconfig,
-                                                       DBusMessageIter *iter)
+static void ipconfig_append_proxy(struct connman_ipconfig *ipconfig,
+                               DBusMessageIter *iter,
+                               enum connman_ipconfig_proxy_method def_method)
 {
        struct connman_ipdevice *ipdevice;
-       const char *method = "auto";
+       struct connman_manual_proxy *manual_proxy;
+       const char *method = proxymethod2string(def_method);
 
-       ipdevice = g_hash_table_lookup(ipdevice_hash,
+       DBG("");
+
+       switch (ipconfig->proxy) {
+       case CONNMAN_IPCONFIG_PROXY_METHOD_MANUAL:
+               if (ipconfig->manual_proxy == NULL)
+                       goto done;
+
+               manual_proxy = ipconfig->manual_proxy;
+
+               if (manual_proxy->http != NULL) {
+                       connman_dbus_dict_append_basic(iter, "Http",
+                                               DBUS_TYPE_STRING,
+                                               &ipconfig->manual_proxy->http);
+
+                       connman_dbus_dict_append_basic(iter, "HttpPort",
+                                               DBUS_TYPE_UINT16,
+                                               &manual_proxy->http_port);
+               }
+
+               if (manual_proxy->https != NULL) {
+                       connman_dbus_dict_append_basic(iter, "Https",
+                                               DBUS_TYPE_STRING,
+                                               &manual_proxy->https);
+
+                       connman_dbus_dict_append_basic(iter, "HttpsPort",
+                                               DBUS_TYPE_UINT16,
+                                               &manual_proxy->https_port);
+               }
+
+               if (manual_proxy->ftp != NULL) {
+                       connman_dbus_dict_append_basic(iter, "Ftp",
+                                               DBUS_TYPE_STRING,
+                                               &manual_proxy->ftp);
+
+                       connman_dbus_dict_append_basic(iter, "FtpPort",
+                                               DBUS_TYPE_UINT16,
+                                               &manual_proxy->ftp_port);
+               }
+
+               if (manual_proxy->socks != NULL) {
+                       connman_dbus_dict_append_basic(iter, "Socks",
+                                               DBUS_TYPE_STRING,
+                                               &manual_proxy->socks);
+
+                       connman_dbus_dict_append_basic(iter, "SocksPort",
+                                               DBUS_TYPE_UINT16,
+                                               &manual_proxy->socks_port);
+               }
+
+               if (manual_proxy->rtsp != NULL) {
+                       connman_dbus_dict_append_basic(iter, "Rtsp",
+                                               DBUS_TYPE_STRING,
+                                               &manual_proxy->rtsp);
+
+                       connman_dbus_dict_append_basic(iter, "RtspPort",
+                                               DBUS_TYPE_UINT16,
+                                               &manual_proxy->rtsp_port);
+               }
+
+               if (manual_proxy->ignore != NULL)
+                       connman_dbus_dict_append_array(iter, "Ignore",
+                                               DBUS_TYPE_STRING,
+                                               append_ignore_list,
+                                               manual_proxy->ignore);
+
+               break;
+       case CONNMAN_IPCONFIG_PROXY_METHOD_AUTO:
+               if (ipconfig->pac == NULL)
+                       goto done;
+
+               connman_dbus_dict_append_basic(iter, "URL",
+                                       DBUS_TYPE_STRING,
+                                       &ipconfig->pac);
+
+               break;
+       case CONNMAN_IPCONFIG_PROXY_METHOD_AUTO_CONFIG:
+               ipdevice = g_hash_table_lookup(ipdevice_hash,
                                        GINT_TO_POINTER(ipconfig->index));
-       if (ipdevice == NULL)
-               goto done;
+               if (ipdevice == NULL)
+                       goto done;
 
-       if (ipdevice->proxy == NULL)
+               if (ipdevice->pac == NULL)
+                       goto done;
+
+               connman_dbus_dict_append_basic(iter, "URL",
+                                       DBUS_TYPE_STRING,
+                                       &ipdevice->pac);
+
+               break;
+       default:
                goto done;
+       }
 
-       method = ipdevice->proxy;
+       method = proxymethod2string(ipconfig->proxy);
 
 done:
        connman_dbus_dict_append_basic(iter, "Method",
-                                               DBUS_TYPE_STRING, &method);
+                                       DBUS_TYPE_STRING, &method);
+}
+
+void __connman_ipconfig_append_proxy(struct connman_ipconfig *ipconfig,
+                                                       DBusMessageIter *iter)
+{
+       DBG("");
+
+       ipconfig_append_proxy(ipconfig, iter,
+                       CONNMAN_IPCONFIG_PROXY_METHOD_DIRECT);
+}
+
+void __connman_ipconfig_append_proxyconfig(struct connman_ipconfig *ipconfig,
+                                                       DBusMessageIter *iter)
+{
+       DBG("");
+
+       ipconfig_append_proxy(ipconfig, iter,
+                       CONNMAN_IPCONFIG_PROXY_METHOD_AUTO);
+}
+
+static enum connman_ipconfig_proxy_method string2proxymethod(const char 
*method)
+{
+       if (!g_strcmp0(method, "direct"))
+               return CONNMAN_IPCONFIG_PROXY_METHOD_DIRECT;
+       else if (!g_strcmp0(method, "auto"))
+               return CONNMAN_IPCONFIG_PROXY_METHOD_AUTO;
+       else if (!g_strcmp0(method, "manual"))
+               return CONNMAN_IPCONFIG_PROXY_METHOD_MANUAL;
+       else if (!g_strcmp0(method, "auto-config"))
+               return CONNMAN_IPCONFIG_PROXY_METHOD_AUTO_CONFIG;
+       else
+               return CONNMAN_IPCONFIG_PROXY_METHOD_UNKNOWN;
 }
 
 int __connman_ipconfig_set_proxyconfig(struct connman_ipconfig *ipconfig,
                                                        DBusMessageIter *array)
 {
-       struct connman_ipdevice *ipdevice;
        DBusMessageIter dict;
-       const char *method;
+       enum connman_ipconfig_proxy_method method;
+       char *url = NULL;
+       struct connman_manual_proxy *manual = connman_manual_proxy_alloc();
 
        DBG("ipconfig %p", ipconfig);
 
-       ipdevice = g_hash_table_lookup(ipdevice_hash,
-                                       GINT_TO_POINTER(ipconfig->index));
-       if (ipdevice == NULL)
-               return -ENXIO;
-
        if (dbus_message_iter_get_arg_type(array) != DBUS_TYPE_ARRAY)
                return -EINVAL;
 
+       method = CONNMAN_IPCONFIG_PROXY_METHOD_UNKNOWN;
+
        dbus_message_iter_recurse(array, &dict);
 
        while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
-               DBusMessageIter entry;
+               DBusMessageIter entry, variant;
                const char *key;
                int type;
 
@@ -1680,31 +2045,138 @@ int __connman_ipconfig_set_proxyconfig(struct 
connman_ipconfig *ipconfig,
                dbus_message_iter_get_basic(&entry, &key);
                dbus_message_iter_next(&entry);
 
-               type = dbus_message_iter_get_arg_type(&entry);
+               if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_VARIANT)
+                       return -EINVAL;
+               
+               dbus_message_iter_recurse(&entry, &variant);
+               type = dbus_message_iter_get_arg_type(&variant);
 
                if (g_str_equal(key, "Method") == TRUE) {
+                       const char *str;
+
+                       if (type != DBUS_TYPE_STRING)
+                               return -EINVAL;
+
+                       dbus_message_iter_get_basic(&variant, &str);
+                       method = string2proxymethod(str);
+                       DBG("got method %s", str);
+               } else if (g_str_equal(key, "URL") == TRUE) {
+                       if (type != DBUS_TYPE_STRING)
+                               return -EINVAL;
+
+                       dbus_message_iter_get_basic(&variant, &url);
+                       DBG("got URL %s", url);
+               } else if (g_str_equal(key, "Http") == TRUE) {
+                       if (type != DBUS_TYPE_STRING)
+                               return -EINVAL;
+
+                       dbus_message_iter_get_basic(&variant, &manual->http);
+                       DBG("got Http %s", manual->http);
+               } else if (g_str_equal(key, "HttpPort") == TRUE) {
+                       if (type != DBUS_TYPE_UINT16)
+                               return -EINVAL;
+
+                       dbus_message_iter_get_basic(&variant,
+                                               &manual->http_port);
+                       DBG("got HttpPort %u", manual->http_port);
+               } else if (g_str_equal(key, "Https") == TRUE) {
                        if (type != DBUS_TYPE_STRING)
                                return -EINVAL;
 
-                       dbus_message_iter_get_basic(&entry, &method);
-                       if (strlen(method) == 0)
-                               method = NULL;
+                       dbus_message_iter_get_basic(&variant, &manual->https);
+                       DBG("got Https %s", manual->https);
+               } else if (g_str_equal(key, "HttpsPort") == TRUE) {
+                       if (type != DBUS_TYPE_UINT16)
+                               return -EINVAL;
+
+                       dbus_message_iter_get_basic(&variant,
+                                               &manual->https_port);
+                       DBG("got HttpsPort %u", manual->https_port);
+               } else if (g_str_equal(key, "Ftp") == TRUE) {
+                       if (type != DBUS_TYPE_STRING)
+                               return -EINVAL;
+
+                       dbus_message_iter_get_basic(&variant, &manual->ftp);
+                       DBG("got Ftp %s", manual->ftp);
+               } else if (g_str_equal(key, "FtpPort") == TRUE) {
+                       if (type != DBUS_TYPE_UINT16)
+                               return -EINVAL;
+
+                       dbus_message_iter_get_basic(&variant,
+                                               &manual->ftp_port);
+                       DBG("got FtpPort %u", manual->ftp_port);
+               } else if (g_str_equal(key, "Socks") == TRUE) {
+                       if (type != DBUS_TYPE_STRING)
+                               return -EINVAL;
+
+                       dbus_message_iter_get_basic(&variant, &manual->socks);
+                       DBG("got Socks %s", manual->socks);
+               } else if (g_str_equal(key, "SocksPort") == TRUE) {
+                       if (type != DBUS_TYPE_UINT16)
+                               return -EINVAL;
+
+                       dbus_message_iter_get_basic(&variant,
+                                               &manual->socks_port);
+                       DBG("got SocksPort %u", manual->socks_port);
+               } else if (g_str_equal(key, "Rtsp") == TRUE) {
+                       if (type != DBUS_TYPE_STRING)
+                               return -EINVAL;
+
+                       dbus_message_iter_get_basic(&variant, &manual->rtsp);
+                       DBG("got Rtsp %s", manual->rtsp);
+               } else if (g_str_equal(key, "RtspPort") == TRUE) {
+                       if (type != DBUS_TYPE_UINT16)
+                               return -EINVAL;
+
+                       dbus_message_iter_get_basic(&variant,
+                                               &manual->rtsp_port);
+                       DBG("got RtspPort %u", manual->rtsp_port);
+               } else if (g_str_equal(key, "Ignore") == TRUE) {
+                       DBusMessageIter str_array;
+
+                       if (type != DBUS_TYPE_ARRAY)
+                               return -EINVAL;
+
+                       dbus_message_iter_recurse(&variant, &str_array);
+
+                       while (dbus_message_iter_get_arg_type(&str_array) ==
+                               DBUS_TYPE_STRING) {
+                               char *val = NULL;
+
+                               dbus_message_iter_get_basic(&str_array, &val);
+                               manual->ignore = g_slist_append(manual->ignore,
+                                                               g_strdup(val));
+
+                               dbus_message_iter_next(&str_array);
+                               DBG("got Ignore value %s", val);
+                       }
                }
 
                dbus_message_iter_next(&dict);
        }
 
-       DBG("method %s", method);
+       DBG("method is %s", proxymethod2string(method));
 
-       if (method == NULL)
-               return -EINVAL;
+       switch (method) {
+       case CONNMAN_IPCONFIG_PROXY_METHOD_DIRECT:
+               break;
+       case CONNMAN_IPCONFIG_PROXY_METHOD_AUTO:
+               __connman_ipconfig_set_proxy_auto(ipconfig, url);
+               break;
+       case CONNMAN_IPCONFIG_PROXY_METHOD_MANUAL:
+               __connman_ipconfig_set_proxy_manual(ipconfig, manual);
 
-       if (g_str_equal(method, "auto") == FALSE &&
-                               g_str_equal(method, "direct") == FALSE)
+               /* Since we provided const char for string attributes */
+               free_manual_proxy_ignore(manual->ignore);
+               g_free(manual);
+
+               break;
+       case CONNMAN_IPCONFIG_PROXY_METHOD_AUTO_CONFIG:
+       default:
                return -EINVAL;
+       }
 
-       g_free(ipdevice->proxy);
-       ipdevice->proxy = g_strdup(method);
+       ipconfig->proxy = method;
 
        return 0;
 }
@@ -1741,8 +2213,21 @@ int __connman_ipconfig_load(struct connman_ipconfig 
*ipconfig,
 {
        const char *method;
        char *key;
-
-       DBG("ipconfig %p identifier %s", ipconfig, identifier);
+       char *http = NULL;
+       uint16_t http_port = 0;
+       char *https = NULL;
+       uint16_t https_port = 0;
+       char *ftp = NULL;
+       uint16_t ftp_port = 0;
+       char *socks = NULL;
+       uint16_t socks_port = 0;
+       char *rtsp = NULL;
+       uint16_t rtsp_port = 0;
+       char **ignore_list = NULL;
+       gsize list_size = 0;
+       GSList *ignore = NULL;
+
+       DBG("ipconfig %p identifier %s prefix %s", ipconfig, identifier, 
prefix);
 
        key = g_strdup_printf("%smethod", prefix);
        method = g_key_file_get_string(keyfile, identifier, key, NULL);
@@ -1780,16 +2265,115 @@ int __connman_ipconfig_load(struct connman_ipconfig 
*ipconfig,
                                keyfile, identifier, key, NULL);
        g_free(key);
 
+       key = g_strdup_printf("%sproxy", prefix);
+       method = g_key_file_get_string(keyfile, identifier, key, NULL);
+       if (method == NULL)
+               ipconfig->proxy = CONNMAN_IPCONFIG_PROXY_METHOD_DIRECT;
+       else
+               ipconfig->proxy = string2proxymethod(method);
+       g_free(key);
+
+       key = g_strdup_printf("%spac", prefix);
+       ipconfig->pac = g_key_file_get_string(keyfile, identifier, key, NULL);
+       g_free(key);
+
+       key = g_strdup_printf("%shttp", prefix);
+       http = g_key_file_get_string(keyfile, identifier, key, NULL);
+       g_free(key);
+
+       if (http != NULL) {
+               key = g_strdup_printf("%shttp_port", prefix);
+               http_port = g_key_file_get_integer(keyfile, identifier,
+                                               key, NULL);
+               g_free(key);
+       }
+
+       key = g_strdup_printf("%shttps", prefix);
+       https = g_key_file_get_string(keyfile, identifier, key, NULL);
+       g_free(key);
+
+       if (https != NULL) {
+               key = g_strdup_printf("%shttps_port", prefix);
+               https_port = g_key_file_get_integer(keyfile, identifier,
+                                               key, NULL);
+               g_free(key);
+       }
+
+       key = g_strdup_printf("%sftp", prefix);
+       ftp = g_key_file_get_string(keyfile, identifier, key, NULL);
+       g_free(key);
+
+       if (ftp != NULL) {
+               key = g_strdup_printf("%sftp_port", prefix);
+               ftp_port = g_key_file_get_integer(keyfile, identifier,
+                                               key, NULL);
+               g_free(key);
+       }
+
+       key = g_strdup_printf("%ssocks", prefix);
+       socks = g_key_file_get_string(keyfile, identifier, key, NULL);
+       g_free(key);
+
+       if (socks != NULL) {
+               key = g_strdup_printf("%ssocks_port", prefix);
+               socks_port = g_key_file_get_integer(keyfile, identifier,
+                                               key, NULL);
+               g_free(key);
+       }
+
+       key = g_strdup_printf("%srtsp", prefix);
+       rtsp = g_key_file_get_string(keyfile, identifier, key, NULL);
+       g_free(key);
+
+       if (rtsp != NULL) {
+               key = g_strdup_printf("%srtsp_port", prefix);
+               rtsp_port = g_key_file_get_integer(keyfile, identifier,
+                                               key, NULL);
+               g_free(key);
+       }
+
+       key = g_strdup_printf("%signore", prefix);
+       ignore_list = g_key_file_get_string_list(keyfile, identifier, key,
+                                               &list_size, NULL);
+       g_free(key);
+
+       if (ignore_list != NULL && list_size > 0) {
+               int i;
+
+               ignore = g_slist_alloc();
+               if (ignore != NULL) {
+                       for (i = 0; i < list_size; i++)
+                               ignore = g_slist_append(ignore,
+                                               ignore_list[list_size]);
+               }
+
+       }
+
+       ipconfig->manual_proxy = connman_manual_proxy_alloc();
+       if (ipconfig->manual_proxy != NULL) {
+               if (connman_manual_proxy_set(ipconfig->manual_proxy, http,
+                                               http_port, https, https_port,
+                                               ftp, ftp_port, socks,
+                                               socks_port, rtsp, rtsp_port,
+                                               ignore) != 0) {
+                       connman_manual_proxy_free(ipconfig->manual_proxy);
+                       ipconfig->manual_proxy = NULL;
+               }
+       }
+
+       g_strfreev(ignore_list);
+
        return 0;
 }
 
 int __connman_ipconfig_save(struct connman_ipconfig *ipconfig,
                GKeyFile *keyfile, const char *identifier, const char *prefix)
 {
+       enum connman_ipconfig_proxy_method proxy;
        const char *method;
        char *key;
 
-       DBG("ipconfig %p identifier %s", ipconfig, identifier);
+       DBG("ipconfig %p identifier %s prefix %s", ipconfig, identifier, 
prefix);
 
        method = __connman_ipconfig_method2string(ipconfig->method);
 
@@ -1826,6 +2410,125 @@ int __connman_ipconfig_save(struct connman_ipconfig 
*ipconfig,
                        key, ipconfig->address->gateway);
        g_free(key);
 
+       proxy = ipconfig->proxy;
+       if (proxy == CONNMAN_IPCONFIG_PROXY_METHOD_AUTO_CONFIG)
+               proxy = CONNMAN_IPCONFIG_PROXY_METHOD_DIRECT;
+
+       method = proxymethod2string(proxy);
+
+       if (method != NULL)
+       {
+           key = g_strdup_printf("%sproxy", prefix);
+           g_key_file_set_string(keyfile, identifier, key,
+                                 method);
+           g_free(key);
+       }
+
+       if (ipconfig->pac != NULL) {
+               key = g_strdup_printf("%spac", prefix);
+               g_key_file_set_string(keyfile, identifier, key,
+                               ipconfig->pac);
+               g_free(key);
+       }
+
+       if (ipconfig->manual_proxy != NULL) {
+               if (ipconfig->manual_proxy->http != NULL) {
+                       key = g_strdup_printf("%shttp", prefix);
+                       g_key_file_set_string(keyfile, identifier, key,
+                                       ipconfig->manual_proxy->http);
+                       g_free(key);
+
+                       key = g_strdup_printf("%shttp_port", prefix);
+                       g_key_file_set_integer(keyfile, identifier, key,
+                                       ipconfig->manual_proxy->http_port);
+                       g_free(key);
+               }
+
+               if (ipconfig->manual_proxy->https != NULL) {
+                       key = g_strdup_printf("%shttps", prefix);
+                       g_key_file_set_string(keyfile, identifier, key,
+                                       ipconfig->manual_proxy->https);
+                       g_free(key);
+
+                       key = g_strdup_printf("%shttps_port", prefix);
+                       g_key_file_set_integer(keyfile, identifier, key,
+                                       ipconfig->manual_proxy->https_port);
+                       g_free(key);
+               }
+
+               if (ipconfig->manual_proxy->ftp != NULL) {
+                       key = g_strdup_printf("%sftp", prefix);
+                       g_key_file_set_string(keyfile, identifier, key,
+                                       ipconfig->manual_proxy->ftp);
+                       g_free(key);
+
+                       key = g_strdup_printf("%sftp_port", prefix);
+                       g_key_file_set_integer(keyfile, identifier, key,
+                                       ipconfig->manual_proxy->ftp_port);
+                       g_free(key);
+               }
+
+               if (ipconfig->manual_proxy->socks != NULL) {
+                       key = g_strdup_printf("%ssocks", prefix);
+                       g_key_file_set_string(keyfile, identifier, key,
+                                       ipconfig->manual_proxy->socks);
+                       g_free(key);
+
+                       key = g_strdup_printf("%ssocks_port", prefix);
+                       g_key_file_set_integer(keyfile, identifier, key,
+                                       ipconfig->manual_proxy->socks_port);
+                       g_free(key);
+               }
+
+               if (ipconfig->manual_proxy->rtsp != NULL) {
+                       key = g_strdup_printf("%srtsp", prefix);
+                       g_key_file_set_string(keyfile, identifier, key,
+                                       ipconfig->manual_proxy->rtsp);
+                       g_free(key);
+
+                       key = g_strdup_printf("%srtsp_port", prefix);
+                       g_key_file_set_integer(keyfile, identifier, key,
+                                       ipconfig->manual_proxy->rtsp_port);
+                       g_free(key);
+               }
+
+               if (ipconfig->manual_proxy->ignore != NULL) {
+                       char **str_list = NULL;
+                       char **list_realloc = NULL;
+                       int list_size = 0;
+                       GSList *list;
+
+                       key = g_strdup_printf("%signore", prefix);
+
+                       for (list = ipconfig->manual_proxy->ignore; list;
+                               list = list->next) {
+                               list_realloc = g_try_realloc(str_list,
+                                                       list_size+1 *
+                                                       sizeof(char *));
+
+                               if (list_realloc == NULL) {
+                                       g_free(str_list);
+                                       str_list = NULL;
+                                       break;
+                               }
+
+                               str_list = list_realloc;
+                               str_list[list_size] = (char *) list->data;
+                               list_size++;
+                       }
+
+                       if (str_list != NULL) {
+                               key = g_strdup_printf("%signore", prefix);
+
+                               g_key_file_set_string_list(keyfile, identifier,
+                                                       key, (const char **)
+                                                       str_list, list_size);
+                               g_free(key);
+                               g_free(str_list);
+                       }
+               }
+       }
+
        return 0;
 }
 
-- 
1.7.1

_______________________________________________
connman mailing list
[email protected]
http://lists.connman.net/listinfo/connman

Reply via email to