Merge "Add dbus method for getting wifi passphrase" into tizen
[platform/core/connectivity/net-config.git] / src / wifi-config.c
index 680246d..99c6903 100755 (executable)
@@ -28,6 +28,7 @@
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
+#include <sys/time.h>
 
 #include <vconf.h>
 
@@ -35,6 +36,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
@@ -87,12 +87,12 @@ struct wifi_config {
        gchar *security_type;
        gboolean favorite;
        gboolean autoconnect;
-       GTimeVal modified;
        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;
 };
 
@@ -139,42 +139,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");
@@ -182,6 +181,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]) {
@@ -196,13 +196,14 @@ static gboolean __get_mac_address(gchar **mac_address)
        return TRUE;
 }
 
-gboolean wifi_config_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);
@@ -233,6 +234,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;
@@ -286,16 +289,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;
        }
 
@@ -307,14 +331,16 @@ static gboolean __remove_configuration(const gchar *pathname)
        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 = wifi_config_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;
@@ -330,6 +356,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");
@@ -353,8 +386,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)
@@ -369,6 +405,7 @@ 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) {
@@ -455,14 +492,16 @@ static gboolean _load_configuration(const gchar *config_id, struct wifi_config *
        return TRUE;
 }
 
-gboolean wifi_config_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 = wifi_config_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;
@@ -494,13 +533,14 @@ gboolean wifi_config_save_configuration(const gchar *config_id, GKeyFile *keyfil
        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 = wifi_config_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;
@@ -511,9 +551,10 @@ static gboolean _remove_configuration(const gchar *config_id)
                if (__remove_configuration(dir) != TRUE) {
                        ERR("[%s] is existed, but cannot remove", dir);
                        ret = FALSE;
+               } else {
+                       INFO("Success to remove [%s]", dir);
+                       ret = TRUE;
                }
-               INFO("Success to remove [%s]", dir);
-               ret = TRUE;
        } else {
                ERR("[%s] is not existed", dir);
                ret = FALSE;
@@ -526,13 +567,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 = wifi_config_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;
@@ -576,7 +619,7 @@ static gboolean _set_field(const gchar *config_id, const gchar *key, const gchar
                ret = FALSE;
        }
 
-       wifi_config_save_configuration(config_id, keyfile);
+       wifi_config_save_configuration(interface_name, config_id, keyfile);
 
        g_key_file_free(keyfile);
        g_free(group_name);
@@ -584,7 +627,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;
@@ -592,7 +636,8 @@ static gboolean _get_field(const gchar *config_id, const gchar *key, gchar **val
        gboolean hidden = FALSE;
        gboolean ret = FALSE;
 
-       ret = wifi_config_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;
@@ -609,7 +654,14 @@ static gboolean _get_field(const gchar *config_id, const gchar *key, gchar **val
        if (g_strcmp0(key, WIFI_CONFIG_NAME) == 0) {
                val = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_NAME, NULL);
        } else if (g_strcmp0(key, WIFI_CONFIG_PASSPHRASE) == 0) {
-               val = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_PASSPHRASE, NULL);
+               gchar *enc_pass = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_PASSPHRASE, NULL);
+               if (enc_pass) {
+                       val = _netconfig_decrypt_passphrase(enc_pass);
+                       g_free(enc_pass);
+
+                       if (!val)
+                               ERR("Failed to decrypt the passphrase");
+               }
        } else if (g_strcmp0(key, WIFI_CONFIG_PROXY_SERVER) == 0) {
                val = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_PROXY_SERVER, NULL);
        } else if (g_strcmp0(key, WIFI_CONFIG_HIDDEN) == 0) {
@@ -650,7 +702,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;
@@ -667,9 +719,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);
 
@@ -693,11 +751,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;
 }
@@ -820,7 +879,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;
@@ -864,8 +923,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);
@@ -888,7 +946,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;
@@ -899,7 +957,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;
@@ -948,7 +1006,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;
@@ -992,7 +1050,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);
@@ -1016,16 +1074,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);
@@ -1055,7 +1123,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;
@@ -1066,7 +1134,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);
@@ -1080,6 +1148,7 @@ gboolean handle_load_configuration(Wifi *wifi, GDBusMethodInvocation *context,
        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_uint32(conf->frequency));
 
        if (conf->proxy_address != NULL)
                g_variant_builder_add(b, "{sv}", WIFI_CONFIG_PROXYADDRESS, g_variant_new_string(conf->proxy_address));
@@ -1119,6 +1188,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;
@@ -1149,7 +1220,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;
@@ -1159,6 +1230,8 @@ gboolean handle_save_configuration(Wifi *wifi, GDBusMethodInvocation *context,
        gchar *field;
        gchar *group_name = NULL;
        int order = 0;
+       int rv;
+       struct timeval modified_time;
 
        if ((wifi == NULL) || (config_id == NULL) || (configuration == NULL)) {
                ERR("Invalid parameter");
@@ -1199,6 +1272,13 @@ 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);
@@ -1269,7 +1349,8 @@ gboolean handle_save_configuration(Wifi *wifi, GDBusMethodInvocation *context,
        conf->favorite = TRUE;
        conf->autoconnect = TRUE;
 
-       ret = wifi_config_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");
@@ -1301,12 +1382,22 @@ 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);
-       g_get_current_time(&conf->modified);
-       gchar *str = g_time_val_to_iso8601(&conf->modified);
-       if (str) {
-               g_key_file_set_string(keyfile, group_name,
-                               WIFI_CONFIG_MODIFIED, str);
-               g_free(str);
+
+       rv = gettimeofday(&modified_time, NULL);
+       if (!rv) {
+               struct tm modified_tm;
+               char time_buf[255];
+               time_t modified_t = modified_time.tv_sec;
+
+               if (localtime_r(&modified_t, &modified_tm)) {
+                       if (strftime(time_buf, sizeof(time_buf), "%FT%TZ", &modified_tm)) {
+                               field = g_strdup(time_buf);
+                               if (field) {
+                                       g_key_file_set_string(keyfile, group_name, WIFI_CONFIG_MODIFIED, field);
+                                       g_free(field);
+                               }
+                       }
+               }
        }
 
        /* Optional field */
@@ -1322,6 +1413,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);
@@ -1360,7 +1455,7 @@ gboolean handle_save_configuration(Wifi *wifi, GDBusMethodInvocation *context,
                i += 1;
        }
 
-       ret = wifi_config_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);
@@ -1394,7 +1489,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;
@@ -1406,7 +1501,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);
@@ -1420,6 +1515,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_uint32(conf->frequency));
+
        if (conf->proxy_address != NULL)
                g_variant_builder_add(b, "{sv}", WIFI_CONFIG_PROXYADDRESS, g_variant_new_string(conf->proxy_address));
        else
@@ -1485,7 +1582,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;
@@ -1534,6 +1631,13 @@ 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);
@@ -1616,7 +1720,8 @@ gboolean handle_save_eap_configuration(Wifi *wifi, GDBusMethodInvocation *contex
        conf->favorite = TRUE;
        conf->autoconnect = TRUE;
 
-       ret = wifi_config_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");
@@ -1660,6 +1765,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);
@@ -1696,7 +1805,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 = wifi_config_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);
@@ -1714,7 +1823,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;
 
@@ -1724,7 +1834,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);
@@ -1736,6 +1846,52 @@ gboolean handle_remove_configuration(Wifi *wifi, GDBusMethodInvocation *context,
        return TRUE;
 }
 
+gboolean handle_reset_wifi_config(Wifi *wifi, GDBusMethodInvocation *context)
+{
+       DIR *dir_ptr = NULL;
+       struct dirent *file = NULL;
+       struct stat buf;
+       char dir_name[512] = { 0, };
+       char file_name[1024] = { 0, };
+
+       g_return_val_if_fail(wifi != NULL, TRUE);
+
+       DBG("Try to remove connman Wi-Fi config files...");
+
+       if ((dir_ptr = opendir(CONNMAN_STORAGE)) != NULL) {
+               while ((file = readdir(dir_ptr)) != NULL) {
+                       if (strncmp(file->d_name, ".", 1) == 0 || strncmp(file->d_name, "..", 2) == 0 ||
+                                       strncmp(file->d_name, WIFI_CONFIG_PREFIX, strlen(WIFI_CONFIG_PREFIX)) != 0) {
+                               continue;
+                       }
+
+                       snprintf(dir_name, 512, CONNMAN_STORAGE"/%s", file->d_name);
+
+                       if (lstat(dir_name, &buf) == -1)
+                               continue;
+
+                       DBG("Remove wifi config: %s", file->d_name);
+
+                       if (S_ISDIR(buf.st_mode)) {
+                               memset(file_name, 0, 1024);
+                               snprintf(file_name, 1024, "%s/data", dir_name);
+                               unlink(file_name);
+                               memset(file_name, 0, 1024);
+                               snprintf(file_name, 1024, "%s/settings", dir_name);
+                               unlink(file_name);
+                       }
+                       rmdir(dir_name);
+               }
+
+               closedir(dir_ptr);
+               sync();
+       }
+
+       wifi_complete_reset_wifi_config(wifi, context);
+
+       return TRUE;
+}
+
 /* config field key / value */
 /*
  * [wifi_macaddress_config_id]
@@ -1757,7 +1913,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;
@@ -1769,7 +1925,7 @@ gboolean handle_set_config_field(Wifi *wifi, GDBusMethodInvocation *context,
        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);
@@ -1800,7 +1956,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);
        }
@@ -1812,18 +1968,19 @@ 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;
 
-       if ((wifi == NULL) || (config_id == NULL)) {
+       if ((wifi == NULL) || (ifname == NULL) || (config_id == NULL)) {
                ERR("Invalid parameter");
                netconfig_error_invalid_parameter(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");
@@ -1837,7 +1994,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);
 
@@ -1846,7 +2003,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");
@@ -1858,7 +2015,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);
 
@@ -1867,7 +2024,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");
@@ -1881,7 +2038,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);
 
@@ -1890,7 +2047,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");