Create device_data if not found it before use
[platform/core/connectivity/net-config.git] / src / wifi-config.c
index 6901e6c..8600990 100755 (executable)
@@ -35,6 +35,7 @@
 #include "util.h"
 #include "neterror.h"
 #include "wifi-config.h"
+#include "wifi-state.h"
 #include "netsupplicant.h"
 #include "wifi-key-encryption.h"
 
 #define WIFI_SECURITY_WEP              "wep"
 #define WIFI_SECURITY_WPA_PSK  "psk"
 #define WIFI_SECURITY_EAP              "ieee8021x"
+#define WIFI_SECURITY_SAE              "sae"
 
 #define WIFI_CONFIG_PREFIX      "wifi_"
 #define MAC_ADDRESS_LENGTH             12
 #define WIFI_PREFIX_LENGTH             MAC_ADDRESS_LENGTH + 6  /* wifi_485a3f2f506a_ */
 #define PROFILE_PREFIX_LENGTH  WIFI_PREFIX_LENGTH + 21 /* /net/connman/service/wifi_485a3f2f506a_ */
 
-#define WIFI_MAC_ADD_LENGTH            17
-#define WIFI_MAC_ADD_PATH              "/sys/class/net/wlan0/address"
-
 #define        NET_DNS_ADDR_MAX                2
 
+#define MAX_WIFI_PROFILES              200
+
 struct wifi_eap_config {
        gchar *anonymous_identity;
        gchar *ca_cert;
@@ -86,9 +87,11 @@ struct wifi_config {
        gboolean favorite;
        gboolean autoconnect;
        gchar *is_hidden;
+       gboolean is_created;
        gchar *proxy_address;
        struct wifi_eap_config *eap_config;
        wifi_ip_info_s *ip_info;
+       guint frequency;
        gchar *last_error;
 };
 
@@ -135,42 +138,41 @@ static void __free_wifi_configuration(struct wifi_config *conf)
        g_free(conf);
 }
 
-static gboolean __get_mac_address(gchar **mac_address)
+static gboolean __get_mac_address(const gchar *interface_name, gchar **mac_address)
 {
+       FILE *fp = NULL;
+       char buf[WIFI_MAC_ADDR_LENGTH + 1];
+       char path[WIFI_MAC_PATH_LENGTH];
        gchar *tmp_mac = NULL;
        gchar *tmp = NULL;
        gchar mac[13] = { 0, };
        gint i = 0, j = 0;
 
-       if (TIZEN_TV) {
-               FILE *fp = NULL;
-               char buf[WIFI_MAC_ADD_LENGTH + 1];
-               if (0 == access(WIFI_MAC_ADD_PATH, F_OK))
-                       fp = fopen(WIFI_MAC_ADD_PATH, "r");
+       snprintf(path, WIFI_MAC_PATH_LENGTH, WIFI_MAC_ADDR_PATH, interface_name);
 
-               if (fp == NULL) {
-                       ERR("Failed to open file %s\n", WIFI_MAC_ADD_PATH);
-                       *mac_address = NULL;
-                       return FALSE;
-               }
+       if (0 == access(path, F_OK))
+               fp = fopen(path, "r");
 
+       if (fp) {
                if (fgets(buf, sizeof(buf), fp) == NULL) {
-                       ERR("Failed to get MAC info from %s\n", WIFI_MAC_ADD_PATH);
+                       ERR("Failed to get MAC info from %s\n", path);
                        *mac_address = NULL;
                        fclose(fp);
                        return FALSE;
                }
-               tmp_mac = (gchar *)malloc(WIFI_MAC_ADD_LENGTH + 1);
+               tmp_mac = (gchar *)malloc(WIFI_MAC_ADDR_LENGTH + 1);
                if (tmp_mac == NULL) {
                        ERR("malloc() failed");
                        *mac_address = NULL;
                        fclose(fp);
                        return FALSE;
                }
-               memset(tmp_mac, 0, WIFI_MAC_ADD_LENGTH + 1);
-               g_strlcpy(tmp_mac, buf, WIFI_MAC_ADD_LENGTH + 1);
+               memset(tmp_mac, 0, WIFI_MAC_ADDR_LENGTH + 1);
+               g_strlcpy(tmp_mac, buf, WIFI_MAC_ADDR_LENGTH + 1);
                fclose(fp);
        } else {
+               ERR("Failed to open file %s\n", path);
+
                tmp_mac = vconf_get_str(VCONFKEY_WIFI_BSSID_ADDRESS);
                if (tmp_mac == NULL) {
                        ERR("vconf_get_str(WIFI_BSSID_ADDRESS) Failed");
@@ -178,6 +180,7 @@ static gboolean __get_mac_address(gchar **mac_address)
                        return FALSE;
                }
        }
+
        tmp = g_ascii_strdown(tmp_mac, (gssize)strlen(tmp_mac));
        free(tmp_mac);
        while (tmp && tmp[i]) {
@@ -192,13 +195,14 @@ static gboolean __get_mac_address(gchar **mac_address)
        return TRUE;
 }
 
-static gboolean __get_group_name(const gchar *prefix, const gchar *config_id, gchar **group_name)
+gboolean wifi_config_get_group_name(const gchar *prefix,
+               const gchar *interface_name, const gchar *config_id, gchar **group_name)
 {
        gchar *mac_address = NULL;
        gchar *g_name = NULL;
        gboolean ret = FALSE;
 
-       ret = __get_mac_address(&mac_address);
+       ret = __get_mac_address(interface_name, &mac_address);
        if ((ret != TRUE) || (strlen(mac_address) == 0)) {
                ERR("Cannot get WIFI MAC address");
                g_free(mac_address);
@@ -229,6 +233,8 @@ static gboolean __get_security_type(const gchar *config_id, gchar **type)
                *type = g_strdup(WIFI_SECURITY_WPA_PSK);
        } else if (g_str_has_suffix(config_id, WIFI_SECURITY_EAP) == TRUE) {
                *type = g_strdup(WIFI_SECURITY_EAP);
+       } else if (g_str_has_suffix(config_id, WIFI_SECURITY_SAE) == TRUE) {
+               *type = g_strdup(WIFI_SECURITY_SAE);
        } else {
                *type = NULL;
                return FALSE;
@@ -282,16 +288,37 @@ static gboolean __remove_file(const gchar *pathname, const gchar *filename)
        return ret;
 }
 
+static gboolean __remove_all_files(const gchar *pathname)
+{
+       DIR *dir_ptr = NULL;
+       struct dirent *file = NULL;
+
+       if ((dir_ptr = opendir(pathname)) == NULL)
+               return TRUE;
+
+       while ((file = readdir(dir_ptr)) != NULL) {
+               if (strncmp(file->d_name, ".", 1) == 0 || strncmp(file->d_name, "..", 2) == 0)
+                       continue;
+
+               if (__remove_file(pathname, file->d_name) != TRUE) {
+                       ERR("Cannot remove [%s/%s]", pathname, file->d_name);
+                       closedir(dir_ptr);
+
+                       return FALSE;
+               }
+       }
+
+       closedir(dir_ptr);
+
+       return TRUE;
+}
+
 static gboolean __remove_configuration(const gchar *pathname)
 {
        int ret = 0;
 
-       if (__remove_file(pathname, "settings") != TRUE) {
-               ERR("Cannot remove [%s/settings]", pathname);
-               return FALSE;
-       }
-       if (__remove_file(pathname, "data") != TRUE) {
-               ERR("Cannot remove [%s/data]", pathname);
+       if (__remove_all_files(pathname) != TRUE) {
+               ERR("Cannot remove [%s] directory", pathname);
                return FALSE;
        }
 
@@ -300,18 +327,19 @@ static gboolean __remove_configuration(const gchar *pathname)
                ERR("Cannot remove [%s]", pathname);
                return FALSE;
        }
-
        return TRUE;
 }
 
-static gboolean _load_configuration(const gchar *config_id, struct wifi_config *config)
+static gboolean _load_configuration(const gchar *interface_name,
+               const gchar *config_id, struct wifi_config *config)
 {
        GKeyFile *keyfile;
        gchar *group_name;
        gboolean hidden = FALSE;
        gboolean ret = FALSE;
 
-       ret = __get_group_name(WIFI_CONFIG_PREFIX, config_id, &group_name);
+       ret = wifi_config_get_group_name(WIFI_CONFIG_PREFIX,
+                       interface_name, config_id, &group_name);
        if (ret != TRUE) {
                ERR("Fail to get_wifi_config_group_name");
                return FALSE;
@@ -327,6 +355,13 @@ static gboolean _load_configuration(const gchar *config_id, struct wifi_config *
        config->name = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_NAME, NULL);
        DBG("name [%s]", config->name);
 
+       if (config->name == NULL) {
+               ERR("Fail to get Name of [%s]", group_name);
+               g_key_file_free(keyfile);
+               g_free(group_name);
+               return FALSE;
+       }
+
        __get_security_type(config_id, &config->security_type);
        if (config->security_type == NULL) {
                ERR("Fail to _get_security_type");
@@ -336,6 +371,9 @@ static gboolean _load_configuration(const gchar *config_id, struct wifi_config *
        }
        DBG("security_type [%s]", config->security_type);
 
+       config->passphrase = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_PASSPHRASE, NULL);
+       DBG("passphrase []");
+
        config->proxy_address = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_PROXY_SERVER, NULL);
        if (config->proxy_address)
                DBG("proxy_address [%s]", config->proxy_address);
@@ -347,8 +385,11 @@ 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->frequency = g_key_file_get_integer(keyfile, group_name, WIFI_CONFIG_FREQUENCY, NULL);
+       if (config->frequency)
+               DBG("Frequency [%d]", config->frequency);
+
        if (config->ip_info) {
-               GError *error = NULL;
                config->ip_info->ip_type = g_key_file_get_string(keyfile, group_name,
                                WIFI_CONFIG_IPV4_METHOD, NULL);
                if (config->ip_info->ip_type)
@@ -363,16 +404,19 @@ static gboolean _load_configuration(const gchar *config_id, struct wifi_config *
                in_addr_t addr;
                struct in_addr netmask;
                char *mask;
+               GError *error = NULL;
                prefix_len = g_key_file_get_integer(keyfile, group_name,
                                WIFI_CONFIG_IPV4_SUBNET_MASK, &error);
                if (error != NULL) {
                        DBG("g_key_file_get_integer failed error[%d: %s]", error->code, error->message);
                        g_error_free(error);
                } else {
-                       addr = 0xffffffff << (32 - prefix_len);
-                       netmask.s_addr = htonl(addr);
-                       mask = inet_ntoa(netmask);
-                       config->ip_info->subnet_mask = g_strdup(mask);
+                       if (prefix_len > 0 && prefix_len < 32) {
+                               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);
                }
@@ -447,14 +491,16 @@ static gboolean _load_configuration(const gchar *config_id, struct wifi_config *
        return TRUE;
 }
 
-static gboolean _save_configuration(const gchar *config_id, GKeyFile *keyfile)
+gboolean wifi_config_save_configuration(const gchar *interface_name,
+               const gchar *config_id, GKeyFile *keyfile)
 {
        gchar *dir;
        gchar *path;
        gchar *group_name;
        gboolean ret = FALSE;
 
-       ret = __get_group_name(WIFI_CONFIG_PREFIX, config_id, &group_name);
+       ret = wifi_config_get_group_name(WIFI_CONFIG_PREFIX,
+                       interface_name, config_id, &group_name);
        if (ret != TRUE) {
                ERR("Fail to get_wifi_config_group_name");
                return FALSE;
@@ -486,13 +532,14 @@ static gboolean _save_configuration(const gchar *config_id, GKeyFile *keyfile)
        return TRUE;
 }
 
-static gboolean _remove_configuration(const gchar *config_id)
+static gboolean _remove_configuration(const gchar *interface_name, const gchar *config_id)
 {
        gboolean ret = FALSE;
        gchar *dir;
        gchar *group_name;
 
-       ret = __get_group_name(WIFI_CONFIG_PREFIX, config_id, &group_name);
+       ret = wifi_config_get_group_name(WIFI_CONFIG_PREFIX,
+                       interface_name, config_id, &group_name);
        if (ret != TRUE) {
                ERR("Fail to get_wifi_config_group_name");
                return FALSE;
@@ -518,13 +565,15 @@ static gboolean _remove_configuration(const gchar *config_id)
 }
 
 
-static gboolean _set_field(const gchar *config_id, const gchar *key, const gchar *value)
+static gboolean _set_field(const gchar *interface_name,
+               const gchar *config_id, const gchar *key, const gchar *value)
 {
        gboolean ret = TRUE;
        GKeyFile *keyfile;
        gchar *group_name;
 
-       ret = __get_group_name(WIFI_CONFIG_PREFIX, config_id, &group_name);
+       ret = wifi_config_get_group_name(WIFI_CONFIG_PREFIX,
+                       interface_name, config_id, &group_name);
        if (ret != TRUE) {
                ERR("Fail to get_wifi_config_group_name");
                return FALSE;
@@ -568,7 +617,7 @@ static gboolean _set_field(const gchar *config_id, const gchar *key, const gchar
                ret = FALSE;
        }
 
-       _save_configuration(config_id, keyfile);
+       wifi_config_save_configuration(interface_name, config_id, keyfile);
 
        g_key_file_free(keyfile);
        g_free(group_name);
@@ -576,7 +625,8 @@ static gboolean _set_field(const gchar *config_id, const gchar *key, const gchar
        return ret;
 }
 
-static gboolean _get_field(const gchar *config_id, const gchar *key, gchar **value)
+static gboolean _get_field(const gchar *interface_name,
+               const gchar *config_id, const gchar *key, gchar **value)
 {
        GKeyFile *keyfile;
        gchar *group_name;
@@ -584,7 +634,8 @@ static gboolean _get_field(const gchar *config_id, const gchar *key, gchar **val
        gboolean hidden = FALSE;
        gboolean ret = FALSE;
 
-       ret = __get_group_name(WIFI_CONFIG_PREFIX, config_id, &group_name);
+       ret = wifi_config_get_group_name(WIFI_CONFIG_PREFIX,
+                       interface_name, config_id, &group_name);
        if (ret != TRUE) {
                ERR("Fail to get_wifi_config_group_name");
                return FALSE;
@@ -642,7 +693,7 @@ static gboolean _get_field(const gchar *config_id, const gchar *key, gchar **val
        return TRUE;
 }
 
-static GSList *_get_list(void)
+static GSList *_get_list(const char *mac_addr)
 {
        GSList *list = NULL;
        struct dirent *dp = NULL;
@@ -659,9 +710,15 @@ static GSList *_get_list(void)
                                strncmp(dp->d_name, WIFI_CONFIG_PREFIX, strlen(WIFI_CONFIG_PREFIX)) != 0) {
                        continue;
                }
-               gchar *config_id = g_strdup(dp->d_name + WIFI_PREFIX_LENGTH);
-               list = g_slist_append(list, g_strdup(config_id));
-               g_free(config_id);
+
+               DBG("%s", dp->d_name);
+
+               if (netconfig_check_mac_address(dp->d_name, mac_addr)) {
+                       gchar *config_id = g_strdup(dp->d_name + WIFI_PREFIX_LENGTH);
+                       DBG("%s", config_id);
+                       list = g_slist_append(list, g_strdup(config_id));
+                       g_free(config_id);
+               }
        }
        closedir(dir);
 
@@ -685,11 +742,12 @@ gboolean wifi_config_get_config_id(const gchar *service_profile, gchar **config_
        return ret;
 }
 
-gboolean wifi_config_remove_configuration(const gchar *config_id)
+gboolean wifi_config_remove_configuration(const gchar *interface_name,
+               const gchar *config_id)
 {
        gboolean ret = FALSE;
 
-       ret = _remove_configuration(config_id);
+       ret = _remove_configuration(interface_name, config_id);
 
        return ret;
 }
@@ -812,7 +870,7 @@ static int __netconfig_unpack_ay_malloc(unsigned char **dst, GVariantIter *iter)
        return length;
 }
 
-gboolean _add_vsie(int frame_id, const char* vsie)
+gboolean _add_vsie(const char *interface_name, int frame_id, const char* vsie)
 {
        GVariant *params = NULL;
        GVariant *message = NULL;
@@ -856,8 +914,7 @@ gboolean _add_vsie(int frame_id, const char* vsie)
        params = g_variant_new("(iay)", frame_id, bytearray_builder);
        g_variant_builder_unref(bytearray_builder);
 
-       if_path = netconfig_wifi_get_supplicant_interface();
-
+       if_path = netconfig_wifi_get_supplicant_interface_path(interface_name);
        if (if_path == NULL) {
                ERR("Fail to get wpa_supplicant DBus path");
                g_free(bytearray);
@@ -880,7 +937,7 @@ gboolean _add_vsie(int frame_id, const char* vsie)
        return TRUE;
 }
 
-gboolean _get_vsie(int frame_id, char **vsie)
+gboolean _get_vsie(const char *interface_name, int frame_id, char **vsie)
 {
        GVariant *params = NULL;
        GVariant *message = NULL;
@@ -891,7 +948,7 @@ gboolean _get_vsie(int frame_id, char **vsie)
                return FALSE;
        }
 
-       if_path = netconfig_wifi_get_supplicant_interface();
+       if_path = netconfig_wifi_get_supplicant_interface_path(interface_name);
        if (if_path == NULL) {
                ERR("Fail to get wpa_supplicant DBus path");
                return FALSE;
@@ -940,7 +997,7 @@ gboolean _get_vsie(int frame_id, char **vsie)
 
 }
 
-gboolean _remove_vsie(int frame_id, const char *vsie)
+gboolean _remove_vsie(const char *interface_name, int frame_id, const char *vsie)
 {
        GVariant *params = NULL;
        GVariant *message = NULL;
@@ -984,7 +1041,7 @@ gboolean _remove_vsie(int frame_id, const char *vsie)
        params = g_variant_new("(iay)", frame_id, bytearray_builder);
        g_variant_builder_unref(bytearray_builder);
 
-       if_path = netconfig_wifi_get_supplicant_interface();
+       if_path = netconfig_wifi_get_supplicant_interface_path(interface_name);
        if (if_path == NULL) {
                ERR("Fail to get wpa_supplicant DBus path");
                g_free(bytearray);
@@ -1008,16 +1065,26 @@ gboolean _remove_vsie(int frame_id, const char *vsie)
 }
 
 /* dbus method */
-gboolean handle_get_config_ids(Wifi *wifi, GDBusMethodInvocation *context)
+gboolean handle_get_config_ids(Wifi *wifi, GDBusMethodInvocation *context,
+               const gchar *ifname)
 {
        guint i = 0;
        GSList *config_ids = NULL;
        guint length;
        gchar **result = NULL;
+       const gchar *mac_addr = NULL;
 
        g_return_val_if_fail(wifi != NULL, TRUE);
 
-       config_ids = _get_list();
+       mac_addr = wifi_state_get_mac_address(ifname);
+       if (!mac_addr) {
+               ERR("Fail to get mac-address");
+               netconfig_error_no_profile(context);
+               return TRUE;
+       }
+
+       DBG("%s", mac_addr);
+       config_ids = _get_list(mac_addr);
        if (config_ids == NULL) {
                ERR("Fail to get config list");
                netconfig_error_no_profile(context);
@@ -1047,7 +1114,7 @@ gboolean handle_get_config_ids(Wifi *wifi, GDBusMethodInvocation *context)
 }
 
 gboolean handle_load_configuration(Wifi *wifi, GDBusMethodInvocation *context,
-               const gchar *config_id)
+               const gchar *ifname, const gchar *config_id)
 {
        gboolean ret = FALSE;
        GVariantBuilder *b = NULL;
@@ -1058,7 +1125,7 @@ gboolean handle_load_configuration(Wifi *wifi, GDBusMethodInvocation *context,
        conf = g_new0(struct wifi_config, 1);
        conf->ip_info = g_new0(wifi_ip_info_s, 1);
 
-       ret = _load_configuration(config_id, conf);
+       ret = _load_configuration(ifname, config_id, conf);
        if (ret != TRUE) {
                g_free(conf->ip_info);
                g_free(conf);
@@ -1070,7 +1137,9 @@ gboolean handle_load_configuration(Wifi *wifi, GDBusMethodInvocation *context,
        b = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
        g_variant_builder_add(b, "{sv}", WIFI_CONFIG_NAME, g_variant_new_string(conf->name));
        g_variant_builder_add(b, "{sv}", WIFI_CONFIG_SECURITY_TYPE, g_variant_new_string(conf->security_type));
+       g_variant_builder_add(b, "{sv}", WIFI_CONFIG_PASSPHRASE, g_variant_new_string(conf->passphrase));
        g_variant_builder_add(b, "{sv}", WIFI_CONFIG_HIDDEN, g_variant_new_string(conf->is_hidden));
+       g_variant_builder_add(b, "{sv}", WIFI_CONFIG_FREQUENCY, g_variant_new_int32(conf->frequency));
 
        if (conf->proxy_address != NULL)
                g_variant_builder_add(b, "{sv}", WIFI_CONFIG_PROXYADDRESS, g_variant_new_string(conf->proxy_address));
@@ -1110,6 +1179,8 @@ gboolean handle_load_configuration(Wifi *wifi, GDBusMethodInvocation *context,
 
        __free_wifi_configuration(conf);
 
+       INFO("Success to load configuration [%s:%s]", ifname, config_id);
+
        wifi_complete_load_configuration(wifi, context, g_variant_builder_end(b));
        g_variant_builder_unref(b);
        return TRUE;
@@ -1140,7 +1211,7 @@ static unsigned char __netconfig_convert_netmask_to_prefixlen(
 }
 
 gboolean handle_save_configuration(Wifi *wifi, GDBusMethodInvocation *context,
-               const gchar *config_id, GVariant *configuration)
+               const gchar *ifname, const gchar *config_id, GVariant *configuration)
 {
        gboolean ret = FALSE;
        struct wifi_config *conf = NULL;
@@ -1190,6 +1261,20 @@ gboolean handle_save_configuration(Wifi *wifi, GDBusMethodInvocation *context,
                        } else {
                                conf->is_hidden = NULL;
                        }
+               } else if (g_strcmp0(field, WIFI_CONFIG_FREQUENCY) == 0) {
+                       if (g_variant_is_of_type(value, G_VARIANT_TYPE_UINT32)) {
+                               conf->frequency = g_variant_get_uint32(value);
+                               DBG("frequency [%d]", conf->frequency);
+                       } else {
+                               conf->frequency = 0;
+                       }
+               } else if (g_strcmp0(field, WIFI_CONFIG_CREATED) == 0) {
+                       if (g_variant_is_of_type(value, G_VARIANT_TYPE_BOOLEAN)) {
+                               conf->is_created = g_variant_get_boolean(value);
+                               DBG("is_created [%d]", conf->is_created);
+                       } else {
+                               conf->is_created = FALSE;
+                       }
                } 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));
@@ -1253,7 +1338,8 @@ gboolean handle_save_configuration(Wifi *wifi, GDBusMethodInvocation *context,
        conf->favorite = TRUE;
        conf->autoconnect = TRUE;
 
-       ret = __get_group_name(WIFI_CONFIG_PREFIX, config_id, &group_name);
+       ret = wifi_config_get_group_name(WIFI_CONFIG_PREFIX,
+                       ifname, config_id, &group_name);
        if (ret != TRUE) {
                __free_wifi_configuration(conf);
                ERR("Fail to get_wifi_config_group_name");
@@ -1267,7 +1353,11 @@ gboolean handle_save_configuration(Wifi *wifi, GDBusMethodInvocation *context,
 
        if (conf->passphrase != NULL) {
                gchar *enc_data = NULL;
-               enc_data = _netconfig_encrypt_passphrase(conf->passphrase);
+
+               if (conf->is_created == true)
+                       enc_data = _netconfig_encrypt_passphrase(conf->passphrase);
+               else
+                       enc_data = g_strdup(conf->passphrase);
 
                if (!enc_data) {
                        ERR("Failed to encrypt the passphrase");
@@ -1282,6 +1372,32 @@ gboolean handle_save_configuration(Wifi *wifi, GDBusMethodInvocation *context,
        g_key_file_set_boolean(keyfile, group_name, WIFI_CONFIG_FAVORITE, conf->favorite);
        g_key_file_set_boolean(keyfile, group_name, WIFI_CONFIG_AUTOCONNECT, conf->autoconnect);
 
+#if GLIB_CHECK_VERSION(2,62,0)
+       gint64 real_time = 0;
+       GDateTime *dt_real_time = NULL;
+
+       real_time = g_get_real_time();
+       dt_real_time = g_date_time_new_from_unix_utc(real_time);
+       if (dt_real_time) {
+               gchar *str = g_date_time_format_iso8601(dt_real_time);
+               g_date_time_unref(dt_real_time);
+               if (str) {
+                       g_key_file_set_string(keyfile, group_name,
+                                             WIFI_CONFIG_MODIFIED, str);
+                       g_free(str);
+               }
+       }
+#else /* GLIB_CHECK_VERSION(2,62,0) */
+       GTimeVal modified;
+       g_get_current_time(&modified);
+       gchar *str = g_time_val_to_iso8601(&modified);
+       if (str) {
+               g_key_file_set_string(keyfile, group_name,
+                                     WIFI_CONFIG_MODIFIED, str);
+               g_free(str);
+       }
+#endif /* GLIB_CHECK_VERSION(2,62,0) */
+
        /* Optional field */
        if (conf->proxy_address != NULL) {
                g_key_file_set_string(keyfile, group_name, WIFI_CONFIG_PROXY_METHOD, "manual");
@@ -1295,6 +1411,10 @@ gboolean handle_save_configuration(Wifi *wifi, GDBusMethodInvocation *context,
                g_key_file_set_boolean(keyfile, group_name, WIFI_CONFIG_HIDDEN, hidden);
        }
 
+       if (conf->frequency > 0)
+               g_key_file_set_integer(keyfile, group_name,
+                       WIFI_CONFIG_FREQUENCY, conf->frequency);
+
        if (conf->ip_info->ip_type != NULL)
                g_key_file_set_string(keyfile, group_name,
                        WIFI_CONFIG_IPV4_METHOD, conf->ip_info->ip_type);
@@ -1306,9 +1426,10 @@ gboolean handle_save_configuration(Wifi *wifi, GDBusMethodInvocation *context,
        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);
+                               conf->ip_info->subnet_mask);
+               if (prefix_len > 0 && prefix_len < 32)
+                       g_key_file_set_integer(keyfile, group_name,
+                                       WIFI_CONFIG_IPV4_SUBNET_MASK, prefix_len);
        }
 
        if (conf->ip_info->prefix_length > 0)
@@ -1332,10 +1453,25 @@ gboolean handle_save_configuration(Wifi *wifi, GDBusMethodInvocation *context,
                i += 1;
        }
 
-       ret = _save_configuration(config_id, keyfile);
+       ret = wifi_config_save_configuration(ifname, config_id, keyfile);
        if (ret == TRUE) {
                INFO("Success to save configuration [%s]", config_id);
                wifi_complete_save_configuration(wifi, context);
+               char *file;
+               if (get_files_count(CONNMAN_STORAGE) > MAX_WIFI_PROFILES) {
+                       file = get_least_recently_profile(CONNMAN_STORAGE);
+                       if (file) {
+                               gchar *profileName = g_strdup_printf(CONNMAN_STORAGE "/%s", file);
+                               INFO("least modified file:  %s", profileName);
+                               if (profileName) {
+                                       if (__remove_configuration(profileName) != TRUE)
+                                               DBG("Failed to remove profile: [%s]", profileName);
+                               } else
+                                       ERR("Profile: [%s] does not exist", file);
+
+                               g_free(profileName);
+                       }
+               }
        } else {
                INFO("Fail to save configuration [%s]", config_id);
                netconfig_error_dbus_method_return(context, NETCONFIG_ERROR_INTERNAL, "FailSaveConfiguration");
@@ -1351,7 +1487,7 @@ gboolean handle_save_configuration(Wifi *wifi, GDBusMethodInvocation *context,
 }
 
 gboolean handle_load_eap_configuration(Wifi *wifi, GDBusMethodInvocation *context,
-               const gchar *config_id)
+               const gchar *ifname, const gchar *config_id)
 {
        gboolean ret = FALSE;
        GVariantBuilder *b = NULL;
@@ -1363,7 +1499,7 @@ gboolean handle_load_eap_configuration(Wifi *wifi, GDBusMethodInvocation *contex
        conf->eap_config = g_new0(struct wifi_eap_config, 1);
        conf->ip_info = g_new0(wifi_ip_info_s, 1);
 
-       ret = _load_configuration(config_id, conf);
+       ret = _load_configuration(ifname, config_id, conf);
        if (ret != TRUE) {
                g_free(conf->eap_config);
                g_free(conf->ip_info);
@@ -1377,6 +1513,8 @@ gboolean handle_load_eap_configuration(Wifi *wifi, GDBusMethodInvocation *contex
        g_variant_builder_add(b, "{sv}", WIFI_CONFIG_NAME, g_variant_new_string(conf->name));
        g_variant_builder_add(b, "{sv}", WIFI_CONFIG_SECURITY_TYPE, g_variant_new_string(conf->security_type));
        g_variant_builder_add(b, "{sv}", WIFI_CONFIG_HIDDEN, g_variant_new_string(conf->is_hidden));
+       g_variant_builder_add(b, "{sv}", WIFI_CONFIG_FREQUENCY, g_variant_new_int32(conf->frequency));
+
        if (conf->proxy_address != NULL)
                g_variant_builder_add(b, "{sv}", WIFI_CONFIG_PROXYADDRESS, g_variant_new_string(conf->proxy_address));
        else
@@ -1442,7 +1580,7 @@ gboolean handle_load_eap_configuration(Wifi *wifi, GDBusMethodInvocation *contex
 }
 
 gboolean handle_save_eap_configuration(Wifi *wifi, GDBusMethodInvocation *context,
-               const gchar *config_id, GVariant *configuration)
+               const gchar *ifname, const gchar *config_id, GVariant *configuration)
 {
        gboolean ret = FALSE;
        struct wifi_config *conf = NULL;
@@ -1491,6 +1629,20 @@ gboolean handle_save_eap_configuration(Wifi *wifi, GDBusMethodInvocation *contex
                        } else {
                                conf->is_hidden = NULL;
                        }
+               } else if (g_strcmp0(field, WIFI_CONFIG_FREQUENCY) == 0) {
+                       if (g_variant_is_of_type(value, G_VARIANT_TYPE_UINT32)) {
+                               conf->frequency = g_variant_get_uint32(value);
+                               DBG("frequency [%d]", conf->frequency);
+                       } else {
+                               conf->frequency = 0;
+                       }
+               } else if (g_strcmp0(field, WIFI_CONFIG_CREATED) == 0) {
+                       if (g_variant_is_of_type(value, G_VARIANT_TYPE_BOOLEAN)) {
+                               conf->is_created = g_variant_get_boolean(value);
+                               DBG("is_created [%d]", conf->is_created);
+                       } else {
+                               conf->is_created = FALSE;
+                       }
                } 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));
@@ -1566,7 +1718,8 @@ gboolean handle_save_eap_configuration(Wifi *wifi, GDBusMethodInvocation *contex
        conf->favorite = TRUE;
        conf->autoconnect = TRUE;
 
-       ret = __get_group_name(WIFI_CONFIG_PREFIX, config_id, &group_name);
+       ret = wifi_config_get_group_name(WIFI_CONFIG_PREFIX,
+                       ifname, config_id, &group_name);
        if (ret != TRUE) {
                __free_wifi_configuration(conf);
                ERR("Fail to get_wifi_config_group_name");
@@ -1579,7 +1732,11 @@ gboolean handle_save_eap_configuration(Wifi *wifi, GDBusMethodInvocation *contex
 
        if (conf->passphrase != NULL) {
                gchar *enc_data = NULL;
-               enc_data = _netconfig_encrypt_passphrase(conf->passphrase);
+
+               if (conf->is_created == true)
+                       enc_data = _netconfig_encrypt_passphrase(conf->passphrase);
+               else
+                       enc_data = g_strdup(conf->passphrase);
 
                if (!enc_data) {
                        ERR("Failed to encrypt the passphrase");
@@ -1606,6 +1763,10 @@ gboolean handle_save_eap_configuration(Wifi *wifi, GDBusMethodInvocation *contex
                g_key_file_set_boolean(keyfile, group_name, WIFI_CONFIG_HIDDEN, hidden);
        }
 
+       if (conf->frequency > 0)
+               g_key_file_set_integer(keyfile, group_name,
+                       WIFI_CONFIG_FREQUENCY, conf->frequency);
+
        if (conf->eap_config->anonymous_identity != NULL)
                g_key_file_set_string(keyfile, group_name,
                        WIFI_CONFIG_EAP_ANONYMOUS_IDENTITY, conf->eap_config->anonymous_identity);
@@ -1642,7 +1803,7 @@ gboolean handle_save_eap_configuration(Wifi *wifi, GDBusMethodInvocation *contex
                g_key_file_set_string(keyfile, group_name,
                        WIFI_CONFIG_EAP_SUBJECT_MATCH, conf->eap_config->subject_match);
 
-       ret = _save_configuration(config_id, keyfile);
+       ret = wifi_config_save_configuration(ifname, config_id, keyfile);
        if (ret == TRUE) {
                INFO("Success to save eap configuration [%s]", config_id);
                wifi_complete_save_eap_configuration(wifi, context);
@@ -1660,7 +1821,8 @@ gboolean handle_save_eap_configuration(Wifi *wifi, GDBusMethodInvocation *contex
        return TRUE;
 }
 
-gboolean handle_remove_configuration(Wifi *wifi, GDBusMethodInvocation *context, const gchar *config_id)
+gboolean handle_remove_configuration(Wifi *wifi, GDBusMethodInvocation *context,
+                       const gchar *ifname, const gchar *config_id)
 {
        gboolean ret = FALSE;
 
@@ -1670,7 +1832,7 @@ gboolean handle_remove_configuration(Wifi *wifi, GDBusMethodInvocation *context,
                return TRUE;
        }
 
-       ret = _remove_configuration(config_id);
+       ret = _remove_configuration(ifname, config_id);
        if (ret != TRUE) {
                /* no configuration or error */
                ERR("No [%s] configuration", config_id);
@@ -1703,7 +1865,7 @@ gboolean handle_remove_configuration(Wifi *wifi, GDBusMethodInvocation *context,
  * Proxy.Servers=trst.com:8888; (O)
  */
 gboolean handle_set_config_field(Wifi *wifi, GDBusMethodInvocation *context,
-               const gchar *config_id, const gchar *key, const gchar *value)
+               const gchar *ifname, const gchar *config_id, const gchar *key, const gchar *value)
 {
        gboolean ret = FALSE;
        gchar *keyfile_key = NULL;
@@ -1712,10 +1874,10 @@ gboolean handle_set_config_field(Wifi *wifi, GDBusMethodInvocation *context,
        g_return_val_if_fail(config_id != NULL, TRUE);
        g_return_val_if_fail(key != NULL, TRUE);
 
-       DBG("Key[%s] Value[%d]", key, value);
+       DBG("Key[%s] Value[%s]", key, value);
 
        if (g_strcmp0(key, WIFI_CONFIG_PROXYADDRESS) == 0) {
-               ret = _set_field(config_id, WIFI_CONFIG_PROXY_METHOD, "manual");
+               ret = _set_field(ifname, config_id, WIFI_CONFIG_PROXY_METHOD, "manual");
                if (!ret) {
                        ERR("Fail to [%s]set_wifi_config_field(%s/manual)", config_id, WIFI_CONFIG_PROXY_METHOD);
                        netconfig_error_invalid_parameter(context);
@@ -1746,7 +1908,7 @@ gboolean handle_set_config_field(Wifi *wifi, GDBusMethodInvocation *context,
                return TRUE;
        }
 
-       ret = _set_field(config_id, keyfile_key, (const gchar *)value);
+       ret = _set_field(ifname, config_id, keyfile_key, (const gchar *)value);
        if (!ret) {
                ERR("Fail to [%s]set_wifi_config_field(%s/%s)", config_id, key, value);
        }
@@ -1758,7 +1920,8 @@ gboolean handle_set_config_field(Wifi *wifi, GDBusMethodInvocation *context,
        return TRUE;
 }
 
-gboolean handle_get_config_passphrase(Wifi *wifi, GDBusMethodInvocation *context, const gchar *config_id)
+gboolean handle_get_config_passphrase(Wifi *wifi, GDBusMethodInvocation *context,
+                       const gchar *ifname, const gchar *config_id)
 {
        gboolean ret = FALSE;
        gchar *passphrase = NULL;
@@ -1769,7 +1932,7 @@ gboolean handle_get_config_passphrase(Wifi *wifi, GDBusMethodInvocation *context
                return TRUE;
        }
 
-       ret = _get_field(config_id, WIFI_CONFIG_PASSPHRASE, &passphrase);
+       ret = _get_field(ifname, config_id, WIFI_CONFIG_PASSPHRASE, &passphrase);
        if (!ret) {
                ERR("Fail to [%s] _get_field(%s)", config_id, WIFI_CONFIG_PASSPHRASE);
                netconfig_error_dbus_method_return(context, NETCONFIG_ERROR_INTERNAL, "OperationFailed");
@@ -1783,7 +1946,7 @@ gboolean handle_get_config_passphrase(Wifi *wifi, GDBusMethodInvocation *context
 }
 
 gboolean handle_add_vsie(Wifi *wifi, GDBusMethodInvocation *context,
-               int frame_id, const gchar *vsie)
+               const gchar *ifname, int frame_id, const gchar *vsie)
 {
        DBG("Frame ID: [%d] VSIE: [%s]", frame_id, vsie);
 
@@ -1792,7 +1955,7 @@ gboolean handle_add_vsie(Wifi *wifi, GDBusMethodInvocation *context,
 
        gboolean ret = FALSE;
 
-       ret = _add_vsie(frame_id, vsie);
+       ret = _add_vsie(ifname, frame_id, vsie);
        if (!ret) {
                DBG("Failed to add vsie: %s", vsie);
                netconfig_error_dbus_method_return(context, NETCONFIG_ERROR_INTERNAL, "OperationFailed");
@@ -1804,7 +1967,7 @@ gboolean handle_add_vsie(Wifi *wifi, GDBusMethodInvocation *context,
 }
 
 gboolean handle_get_vsie(Wifi *wifi, GDBusMethodInvocation *context,
-               int frame_id)
+               const gchar *ifname, int frame_id)
 {
        DBG("Frame ID: [%d]", frame_id);
 
@@ -1813,7 +1976,7 @@ gboolean handle_get_vsie(Wifi *wifi, GDBusMethodInvocation *context,
        gboolean ret = FALSE;
        gchar *vsie = NULL;
 
-       ret = _get_vsie(frame_id, &vsie);
+       ret = _get_vsie(ifname, frame_id, &vsie);
        if (!ret) {
                DBG("Failed to get vsie for frame:[%d]", frame_id);
                netconfig_error_dbus_method_return(context, NETCONFIG_ERROR_INTERNAL, "OperationFailed");
@@ -1827,7 +1990,7 @@ gboolean handle_get_vsie(Wifi *wifi, GDBusMethodInvocation *context,
 }
 
 gboolean handle_remove_vsie(Wifi *wifi, GDBusMethodInvocation *context,
-               int frame_id, const gchar *vsie)
+               const gchar *ifname, int frame_id, const gchar *vsie)
 {
        DBG("Frame ID: [%d] VSIE: [%s]", frame_id, vsie);
 
@@ -1836,7 +1999,7 @@ gboolean handle_remove_vsie(Wifi *wifi, GDBusMethodInvocation *context,
 
        gboolean ret = FALSE;
 
-       ret = _remove_vsie(frame_id, vsie);
+       ret = _remove_vsie(ifname, frame_id, vsie);
        if (!ret) {
                DBG("Failed to remove vsie: %s", vsie);
                netconfig_error_dbus_method_return(context, NETCONFIG_ERROR_INTERNAL, "OperationFailed");