Added support to set and get IP configuration details. 98/186498/4
authorNiraj Kumar Goit <niraj.g@samsung.com>
Fri, 10 Aug 2018 03:34:23 +0000 (09:04 +0530)
committerSaurav Babu <saurav.babu@samsung.com>
Mon, 3 Sep 2018 06:11:57 +0000 (11:41 +0530)
Change-Id: I08320822454355853883991cad0d8b0ae58f5e36
Signed-off-by: Niraj Kumar Goit <niraj.g@samsung.com>
include/wifi-config.h
src/wifi-config.c

index 86002a0..dd871a1 100755 (executable)
@@ -34,6 +34,14 @@ extern "C" {
 #define WIFI_CONFIG_FAVORITE                   "Favorite"
 #define WIFI_CONFIG_AUTOCONNECT                "AutoConnect"
 #define WIFI_CONFIG_HIDDEN                             "Hidden"
+#define WIFI_CONFIG_IPV4_METHOD                        "IPv4.method"
+#define WIFI_CONFIG_IPV6_METHOD                        "IPv6.method"
+#define WIFI_CONFIG_IPV4_DNS_METHOD                    "Nameservers.IPv4method"
+#define WIFI_CONFIG_IPV6_DNS_METHOD                    "Nameservers.IPv6method"
+#define WIFI_CONFIG_IPV4_ADDRESS                       "IPv4.local_address"
+#define WIFI_CONFIG_IPV4_SUBNET_MASK                   "IPv4.netmask_prefixlen"
+#define WIFI_CONFIG_IPV4_GATEWAY_ADDRESS               "IPv4.gateway"
+#define WIFI_CONFIG_DNS_ADDRESS                        "Nameservers"
 #define WIFI_CONFIG_FAILURE                    "Failure"
 #define WIFI_CONFIG_PROXYADDRESS               "ProxyAddress"
 #define WIFI_CONFIG_PROXY_METHOD               "Proxy.Method"
index 2d9f5f8..4d82734 100755 (executable)
@@ -25,6 +25,9 @@
 #include <sys/stat.h>
 #include <glib.h>
 #include <unistd.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
 
 #include <vconf.h>
 
@@ -50,6 +53,8 @@
 #define WIFI_MAC_ADD_LENGTH            17
 #define WIFI_MAC_ADD_PATH              "/sys/class/net/wlan0/address"
 
+#define        NET_DNS_ADDR_MAX                2
+
 struct wifi_eap_config {
        gchar *anonymous_identity;
        gchar *ca_cert;
@@ -62,6 +67,17 @@ struct wifi_eap_config {
        gchar *subject_match;
 };
 
+typedef struct {
+       gchar *ip_address;
+       gchar *subnet_mask;
+       gchar *gateway_address;
+       gchar *dns_address[NET_DNS_ADDR_MAX];
+       int prefix_length;
+       int dns_count;
+       gchar *ip_type;
+       gchar *dns_type;
+} wifi_ip_info_s;
+
 struct wifi_config {
        gchar *name;
        gchar *ssid;
@@ -72,6 +88,7 @@ struct wifi_config {
        gchar *is_hidden;
        gchar *proxy_address;
        struct wifi_eap_config *eap_config;
+       wifi_ip_info_s *ip_info;
        gchar *last_error;
 };
 
@@ -99,6 +116,21 @@ static void __free_wifi_configuration(struct wifi_config *conf)
                g_free(conf->eap_config->subject_match);
                g_free(conf->eap_config);
        }
+
+       if (conf->ip_info) {
+               g_free(conf->ip_info->ip_type);
+               g_free(conf->ip_info->ip_address);
+               g_free(conf->ip_info->subnet_mask);
+               g_free(conf->ip_info->gateway_address);
+               g_free(conf->ip_info->dns_type);
+
+               int i = 0, count = conf->ip_info->dns_count;
+               while (i < count) {
+                       g_free(conf->ip_info->dns_address[i]);
+                       i++;
+               }
+               g_free(conf->ip_info);
+       }
        g_free(conf);
 }
 
@@ -313,6 +345,58 @@ static gboolean _load_configuration(const gchar *config_id, struct wifi_config *
                config->is_hidden = g_strdup("FALSE");
        DBG("is_hidden [%s]", config->is_hidden);
 
+       config->ip_info->ip_type = g_key_file_get_string(keyfile, group_name,
+                                                                         WIFI_CONFIG_IPV4_METHOD, NULL);
+       if (config->ip_info->ip_type)
+               DBG("IPv4.Method:%s", config->ip_info->ip_type);
+
+       config->ip_info->ip_address = g_key_file_get_string(keyfile, group_name,
+                                                                         WIFI_CONFIG_IPV4_ADDRESS, NULL);
+       if (config->ip_info->ip_address)
+               DBG("IPv4.Address:%s", config->ip_info->ip_address);
+
+       int prefix_len;
+       in_addr_t addr;
+       struct in_addr netmask;
+       char *mask;
+       prefix_len = g_key_file_get_integer(keyfile, group_name,
+                                                                         WIFI_CONFIG_IPV4_SUBNET_MASK, NULL);
+       addr = 0xffffffff << (32 - prefix_len);
+       netmask.s_addr = htonl(addr);
+       mask = inet_ntoa(netmask);
+       config->ip_info->subnet_mask = g_strdup(mask);
+       if (config->ip_info->subnet_mask)
+               DBG("IPv4.SubnetMask:%s", config->ip_info->subnet_mask);
+
+       config->ip_info->gateway_address = g_key_file_get_string(keyfile,
+                                                                group_name, WIFI_CONFIG_IPV4_GATEWAY_ADDRESS,
+                                                                NULL);
+       if (config->ip_info->gateway_address)
+               DBG("IPv4.gateway:%s", config->ip_info->gateway_address);
+
+       config->ip_info->dns_type = g_key_file_get_string(keyfile, group_name,
+                                                                         WIFI_CONFIG_IPV4_DNS_METHOD, NULL);
+       if (config->ip_info->dns_type)
+               DBG("DNS.IPv4Method:%s", config->ip_info->dns_type);
+
+       char **nameservers;
+       gsize length;
+       nameservers = g_key_file_get_string_list(keyfile, group_name,
+                                                 WIFI_CONFIG_DNS_ADDRESS, &length, NULL);
+       if (nameservers) {
+               if (length > 0) {
+                       config->ip_info->dns_count = length;
+                       int i = 0;
+                       while (i < NET_DNS_ADDR_MAX && nameservers[i]) {
+                               config->ip_info->dns_address[i] = g_strdup(nameservers[i]);
+                               DBG("DNSAddress[%d]:%s", i+1, config->ip_info->dns_address[i]);
+                               i += 1;
+                       }
+               }
+               g_strfreev(nameservers);
+       }
+
+
        if (g_strcmp0(config->security_type, WIFI_SECURITY_EAP) == 0) {
                config->eap_config->anonymous_identity = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_EAP_ANONYMOUS_IDENTITY, NULL);
                config->eap_config->ca_cert = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_EAP_CACERT, NULL);
@@ -963,9 +1047,11 @@ gboolean handle_load_configuration(Wifi *wifi, GDBusMethodInvocation *context,
        g_return_val_if_fail(wifi != NULL, TRUE);
 
        conf = g_new0(struct wifi_config, 1);
+       conf->ip_info = g_new0(wifi_ip_info_s, 1);
 
        ret = _load_configuration(config_id, conf);
        if (ret != TRUE) {
+               g_free(conf->ip_info);
                g_free(conf);
                ERR("Fail to _load_configuration");
                netconfig_error_no_profile(context);
@@ -982,23 +1068,65 @@ gboolean handle_load_configuration(Wifi *wifi, GDBusMethodInvocation *context,
        else
                g_variant_builder_add(b, "{sv}", WIFI_CONFIG_PROXYADDRESS, g_variant_new_string("NONE"));
 
+       if (conf->ip_info->ip_type != NULL)
+               g_variant_builder_add(b, "{sv}", WIFI_CONFIG_IPV4_METHOD, g_variant_new_string(conf->ip_info->ip_type));
+
+       if (conf->ip_info->ip_address != NULL)
+               g_variant_builder_add(b, "{sv}", WIFI_CONFIG_IPV4_ADDRESS, g_variant_new_string(conf->ip_info->ip_address));
+
+       if (conf->ip_info->subnet_mask != NULL)
+               g_variant_builder_add(b, "{sv}", WIFI_CONFIG_IPV4_SUBNET_MASK, g_variant_new_string(conf->ip_info->subnet_mask));
+
+       if (conf->ip_info->gateway_address != NULL)
+               g_variant_builder_add(b, "{sv}", WIFI_CONFIG_IPV4_GATEWAY_ADDRESS, g_variant_new_string(conf->ip_info->gateway_address));
+
+       if (conf->ip_info->dns_type != NULL)
+               g_variant_builder_add(b, "{sv}", WIFI_CONFIG_IPV4_DNS_METHOD, g_variant_new_string(conf->ip_info->dns_type));
+
+       int i = 0, count = conf->ip_info->dns_count;
+       while (i < count) {
+               if (conf->ip_info->dns_address[i] != NULL)
+                       g_variant_builder_add(b, "{sv}", WIFI_CONFIG_DNS_ADDRESS, g_variant_new_string(conf->ip_info->dns_address[i]));
+
+               i += 1;
+       }
+
        if (conf->last_error != NULL)
                g_variant_builder_add(b, "{sv}", WIFI_CONFIG_FAILURE, g_variant_new_string(conf->last_error));
        else
                g_variant_builder_add(b, "{sv}", WIFI_CONFIG_FAILURE, g_variant_new_string("ERROR_NONE"));
 
-       g_free(conf->proxy_address);
-       g_free(conf->last_error);
-       g_free(conf->name);
-       g_free(conf->security_type);
-       g_free(conf->is_hidden);
-       g_free(conf);
+       __free_wifi_configuration(conf);
 
        wifi_complete_load_configuration(wifi, context, g_variant_builder_end(b));
        g_variant_builder_unref(b);
        return TRUE;
 }
 
+static unsigned char __netconfig_convert_netmask_to_prefixlen(
+                                                         const char *netmask)
+{
+       unsigned char bits;
+       in_addr_t mask;
+       in_addr_t host;
+
+       if (!netmask)
+               return 32;
+
+       mask = inet_network(netmask);
+       host = ~mask;
+
+       /* a valid netmask must be 2^n - 1 */
+       if ((host & (host + 1)) != 0)
+               return -1;
+
+       bits = 0;
+       for (; mask; mask <<= 1)
+               ++bits;
+
+       return bits;
+}
+
 gboolean handle_save_configuration(Wifi *wifi, GDBusMethodInvocation *context,
                const gchar *config_id, GVariant *configuration)
 {
@@ -1009,6 +1137,7 @@ gboolean handle_save_configuration(Wifi *wifi, GDBusMethodInvocation *context,
        GVariant *value;
        gchar *field;
        gchar *group_name = NULL;
+       int order = 0;
 
        if ((wifi == NULL) || (config_id == NULL) || (configuration == NULL)) {
                ERR("Invalid parameter");
@@ -1017,6 +1146,7 @@ gboolean handle_save_configuration(Wifi *wifi, GDBusMethodInvocation *context,
        }
 
        conf = g_new0(struct wifi_config, 1);
+       conf->ip_info = g_new0(wifi_ip_info_s, 1);
 
        g_variant_get(configuration, "a{sv}", &iter);
        while (g_variant_iter_loop(iter, "{sv}", &field, &value)) {
@@ -1048,6 +1178,50 @@ gboolean handle_save_configuration(Wifi *wifi, GDBusMethodInvocation *context,
                        } else {
                                conf->is_hidden = NULL;
                        }
+               } else if (g_strcmp0(field, WIFI_CONFIG_IPV4_METHOD) == 0) {
+                       if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
+                               conf->ip_info->ip_type = g_strdup(g_variant_get_string(value, NULL));
+                               DBG("IP config type [%s]", conf->ip_info->ip_type);
+                       } else {
+                               conf->ip_info->ip_type = NULL;
+                       }
+               } else if (g_strcmp0(field, WIFI_CONFIG_IPV4_ADDRESS) == 0) {
+                       if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
+                               conf->ip_info->ip_address = g_strdup(g_variant_get_string(value, NULL));
+                               DBG("IP address [%s]", conf->ip_info->ip_address);
+                       } else {
+                               conf->ip_info->ip_address = NULL;
+                       }
+               } else if (g_strcmp0(field, WIFI_CONFIG_IPV4_SUBNET_MASK) == 0) {
+                       if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
+                               conf->ip_info->subnet_mask = g_strdup(g_variant_get_string(value, NULL));
+                               DBG("Subnet Mask [%s]", conf->ip_info->subnet_mask);
+                       } else {
+                               conf->ip_info->subnet_mask = NULL;
+                       }
+               } else if (g_strcmp0(field, WIFI_CONFIG_IPV4_GATEWAY_ADDRESS) == 0) {
+                       if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
+                               conf->ip_info->gateway_address = g_strdup(g_variant_get_string(value, NULL));
+                               DBG("Gateway address [%s]", conf->ip_info->gateway_address);
+                       } else {
+                               conf->ip_info->gateway_address = NULL;
+                       }
+               } else if (g_strcmp0(field, WIFI_CONFIG_IPV4_DNS_METHOD) == 0) {
+                       if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
+                               conf->ip_info->dns_type = g_strdup(g_variant_get_string(value, NULL));
+                               DBG("DNS config type [%s]", conf->ip_info->dns_type);
+                       } else {
+                               conf->ip_info->dns_type = NULL;
+                       }
+               } else if (g_strcmp0(field, WIFI_CONFIG_DNS_ADDRESS) == 0) {
+                       if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
+                               conf->ip_info->dns_address[order] = g_strdup(g_variant_get_string(value, NULL));
+                               DBG("DNS address [%s]", conf->ip_info->dns_address[order]);
+                               conf->ip_info->dns_count = order + 1;
+                               order++;
+                       } else {
+                               conf->ip_info->dns_address[order++] = NULL;
+                       }
                } else if (g_strcmp0(field, WIFI_CONFIG_PROXYADDRESS) == 0) {
                        if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
                                conf->proxy_address = g_strdup(g_variant_get_string(value, NULL));
@@ -1062,12 +1236,7 @@ gboolean handle_save_configuration(Wifi *wifi, GDBusMethodInvocation *context,
 
        ret = __get_group_name(WIFI_CONFIG_PREFIX, config_id, &group_name);
        if (ret != TRUE) {
-               g_free(conf->name);
-               g_free(conf->ssid);
-               g_free(conf->passphrase);
-               g_free(conf->is_hidden);
-               g_free(conf->proxy_address);
-               g_free(conf);
+               __free_wifi_configuration(conf);
                ERR("Fail to get_wifi_config_group_name");
                netconfig_error_fail_save_congifuration(context);
                return TRUE;
@@ -1107,6 +1276,39 @@ gboolean handle_save_configuration(Wifi *wifi, GDBusMethodInvocation *context,
                g_key_file_set_boolean(keyfile, group_name, WIFI_CONFIG_HIDDEN, hidden);
        }
 
+       if (conf->ip_info->ip_type != NULL)
+               g_key_file_set_string(keyfile, group_name,
+                       WIFI_CONFIG_IPV4_METHOD, conf->ip_info->ip_type);
+
+       if (conf->ip_info->ip_address != NULL)
+               g_key_file_set_string(keyfile, group_name,
+                       WIFI_CONFIG_IPV4_ADDRESS, conf->ip_info->ip_address);
+
+       if (conf->ip_info->subnet_mask != NULL) {
+               unsigned char prefix_len;
+               prefix_len = __netconfig_convert_netmask_to_prefixlen(
+                                                                 conf->ip_info->subnet_mask);
+               g_key_file_set_integer(keyfile, group_name,
+                                                WIFI_CONFIG_IPV4_SUBNET_MASK, prefix_len);
+       }
+
+       if (conf->ip_info->gateway_address != NULL)
+               g_key_file_set_string(keyfile, group_name,
+                       WIFI_CONFIG_IPV4_GATEWAY_ADDRESS, conf->ip_info->gateway_address);
+
+       if (conf->ip_info->dns_type != NULL)
+               g_key_file_set_string(keyfile, group_name,
+                       WIFI_CONFIG_IPV4_DNS_METHOD, conf->ip_info->dns_type);
+
+       int i = 0, count = conf->ip_info->dns_count;
+       while (i < count) {
+               if (conf->ip_info->dns_address[i] != NULL)
+                       g_key_file_set_string(keyfile, group_name, WIFI_CONFIG_DNS_ADDRESS,
+                                                                 conf->ip_info->dns_address[i]);
+
+               i += 1;
+       }
+
        ret = _save_configuration(config_id, keyfile);
        if (ret == TRUE) {
                INFO("Success to save configuration [%s]", config_id);
@@ -1118,12 +1320,7 @@ gboolean handle_save_configuration(Wifi *wifi, GDBusMethodInvocation *context,
 
        g_key_file_free(keyfile);
        g_free(group_name);
-       g_free(conf->name);
-       g_free(conf->ssid);
-       g_free(conf->passphrase);
-       g_free(conf->is_hidden);
-       g_free(conf->proxy_address);
-       g_free(conf);
+       __free_wifi_configuration(conf);
 
        g_variant_iter_free(iter);