Merge "Fix an incorrect value being used for signal score calculation" into tizen
[platform/upstream/connman.git] / gsupplicant / supplicant.c
old mode 100644 (file)
new mode 100755 (executable)
index e7dfcb2..fe1b21f
 #include "dbus.h"
 #include "gsupplicant.h"
 
+#if defined TIZEN_EXT
+#include "setting.h"
+#endif
+
 #define IEEE80211_CAP_ESS      0x0001
 #define IEEE80211_CAP_IBSS     0x0002
 #define IEEE80211_CAP_PRIVACY  0x0010
 #define WLAN_EID_SUPP_RATES 1
 #define WLAN_EID_EXT_SUPP_RATES 50
 #define COUNTRY_CODE_LENGTH    2
+#define WIFI_BSSID_LEN_MAX 6
+#endif
+
+#if defined TIZEN_EXT
+#define LAST_CONNECTED_TIMEOUT       (5 * 60)
+#define ASSOC_REJECT_TIMEOUT         10
+#define FREQ_RANGE_24GHZ_CHANNEL_1   2412
+#define FREQ_RANGE_24GHZ_CHANNEL_14  2484
+#define FREQ_RANGE_5GHZ_CHANNEL_32   5160
+#define FREQ_RANGE_5GHZ_CHANNEL_165  5825
+
+#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
+#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
 #endif
 
 #define BSS_UNKNOWN_STRENGTH    -90
 
 static DBusConnection *connection;
 
+#if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET
+static GSupplicantCallbacks *callbacks_pointer;
+#else /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */
 static const GSupplicantCallbacks *callbacks_pointer;
+#endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */
 
 static dbus_bool_t system_available = FALSE;
 static dbus_bool_t system_ready = FALSE;
@@ -100,8 +121,10 @@ static struct strvalmap keymgmt_map[] = {
        { "wpa-eap",            G_SUPPLICANT_KEYMGMT_WPA_EAP    },
        { "wpa-eap-sha256",     G_SUPPLICANT_KEYMGMT_WPA_EAP_256        },
        { "wps",                G_SUPPLICANT_KEYMGMT_WPS                },
-#if defined TIZEN_EXT_WIFI_MESH
+#if defined TIZEN_EXT
        { "sae",                G_SUPPLICANT_KEYMGMT_SAE                },
+       { "owe",                G_SUPPLICANT_KEYMGMT_OWE                },
+       { "dpp",                G_SUPPLICANT_KEYMGMT_DPP                },
 #endif
        { }
 };
@@ -152,6 +175,28 @@ static struct strvalmap mode_capa_map[] = {
        { }
 };
 
+#if defined TIZEN_EXT && defined TIZEN_EXT_INS
+struct _GSupplicantINSSettings {
+       GSupplicantINSPreferredFreq preferred_freq_bssid;
+       unsigned int preferred_freq_bssid_score;
+       bool last_connected_bssid;
+       unsigned int last_connected_bssid_score;
+       bool assoc_reject;
+       unsigned int assoc_reject_score;
+       bool signal_bssid;
+       int signal_level3_5ghz;
+       int signal_level3_24ghz;
+};
+
+static struct _GSupplicantINSSettings ins_settings;
+#endif /* defined TIZEN_EXT && defined TIZEN_EXT_INS */
+
+#if defined TIZEN_EXT
+static unsigned char invalid_bssid[WIFI_BSSID_LEN_MAX] = {
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+#endif
+
 static GHashTable *interface_table;
 static GHashTable *bss_mapping;
 static GHashTable *peer_mapping;
@@ -170,6 +215,11 @@ struct added_network_information {
        GSupplicantSecurity security;
        char * passphrase;
        char * private_passphrase;
+#if defined TIZEN_EXT
+       char *connector;
+       char *c_sign_key;
+       char *net_access_key;
+#endif
 };
 
 #if defined TIZEN_EXT_WIFI_MESH
@@ -214,8 +264,13 @@ struct _GSupplicantInterface {
        GSupplicantNetwork *current_network;
        struct added_network_information network_info;
 #if defined TIZEN_EXT
+       dbus_bool_t is_5_0_Ghz_supported;
        int disconnect_reason;
 #endif
+#if defined TIZEN_EXT
+       unsigned char add_network_bssid[WIFI_BSSID_LEN_MAX];
+       unsigned char connected_bssid[WIFI_BSSID_LEN_MAX];
+#endif
 #if defined TIZEN_EXT_WIFI_MESH
        bool mesh_support;
        struct _GSupplicantMeshGroupInfo group_info;
@@ -251,10 +306,18 @@ struct g_supplicant_bss {
        dbus_bool_t hs20;
        unsigned char country_code[COUNTRY_CODE_LENGTH];
        GSupplicantPhy_mode phy_mode;
+       dbus_int16_t snr;
+       dbus_uint32_t est_throughput;
 #endif
        unsigned int wps_capabilities;
-#if defined TIZEN_EXT_WIFI_MESH
+#if defined TIZEN_EXT
        dbus_bool_t sae;
+       dbus_bool_t owe;
+       dbus_bool_t dpp;
+       dbus_bool_t owe_transition_mode;
+       unsigned int transition_mode_ssid_len;
+       unsigned char transition_mode_bssid[6];
+       unsigned char transition_mode_ssid[32];
 #endif
 };
 
@@ -283,6 +346,12 @@ struct _GSupplicantNetwork {
        GSList *vsie_list;
        unsigned char country_code[COUNTRY_CODE_LENGTH];
        GSupplicantPhy_mode phy_mode;
+       dbus_bool_t owe_transition_mode;
+       unsigned int transition_mode_ssid_len;
+       unsigned char transition_mode_bssid[6];
+       unsigned char transition_mode_ssid[32];
+       unsigned char last_connected_bssid[WIFI_BSSID_LEN_MAX];
+       GHashTable *assoc_reject_table;
 #endif
 };
 
@@ -333,6 +402,11 @@ struct interface_create_data {
        char *ifname;
        char *driver;
        char *bridge;
+#if defined TIZEN_EXT
+       unsigned int mac_addr;
+       unsigned int preassoc_mac_addr;
+       unsigned int random_mac_lifetime;
+#endif /* TIZEN_EXT */
 #if defined TIZEN_EXT_WIFI_MESH
        char *parent_ifname;
        bool is_mesh_interface;
@@ -363,10 +437,41 @@ struct interface_scan_data {
 
 #if defined TIZEN_EXT
 struct g_connman_bssids {
-       char bssid[18];
+       unsigned char bssid[WIFI_BSSID_LEN_MAX];
        uint16_t strength;
        uint16_t frequency;
+       uint16_t assoc_reject_cnt;
+       bool is_last_connected;
+#if defined TIZEN_EXT_INS
+       int score_last_connected_bssid;
+       int score_assoc_reject;
+       int score_frequency;
+       int score_strength;
+       int score_snr;
+       int score_est_throughput;
+#endif
+       int ins_score;
+};
+
+struct update_bssid_data {
+       GSupplicantNetwork *network;
+       unsigned char last_connected_bssid[WIFI_BSSID_LEN_MAX];
+       GHashTable *assoc_reject_table;
+       GSList *bssid_list;
+};
+
+struct assoc_reject_data {
+       char *bssid;
+       GSList *reject_time_list;
 };
+
+struct assoc_count_data {
+       time_t ref_time;
+       int assoc_count;
+};
+
+static unsigned int last_connected_bss_timeout = 0;
+static bool simplified_log = true;
 #endif
 
 static int network_remove(struct interface_data *data);
@@ -453,10 +558,12 @@ static const char *security2string(GSupplicantSecurity security)
                return "ft_psk";
        case G_SUPPLICANT_SECURITY_FT_IEEE8021X:
                return "ft_ieee8021x";
-#endif
-#if defined TIZEN_EXT_WIFI_MESH
        case G_SUPPLICANT_SECURITY_SAE:
                return "sae";
+       case G_SUPPLICANT_SECURITY_OWE:
+               return "owe";
+       case G_SUPPLICANT_SECURITY_DPP:
+               return "dpp";
 #endif
        }
 
@@ -520,6 +627,23 @@ static bool compare_network_parameters(GSupplicantInterface *interface,
                return FALSE;
        }
 
+#if defined TIZEN_EXT
+       if (interface->network_info.connector &&
+                       g_strcmp0(interface->network_info.connector,
+                               ssid->connector) != 0) {
+               return FALSE;
+       }
+       if (interface->network_info.c_sign_key &&
+                       g_strcmp0(interface->network_info.c_sign_key,
+                               ssid->c_sign_key) != 0) {
+               return FALSE;
+       }
+       if (interface->network_info.net_access_key &&
+                       g_strcmp0(interface->network_info.net_access_key,
+                               ssid->net_access_key) != 0) {
+               return FALSE;
+       }
+#endif
        return TRUE;
 }
 
@@ -528,9 +652,19 @@ static void remove_network_information(GSupplicantInterface * interface)
        g_free(interface->network_info.ssid);
        g_free(interface->network_info.passphrase);
        g_free(interface->network_info.private_passphrase);
+#if defined TIZEN_EXT
+       g_free(interface->network_info.connector);
+       g_free(interface->network_info.c_sign_key);
+       g_free(interface->network_info.net_access_key);
+#endif
        interface->network_info.ssid = NULL;
        interface->network_info.passphrase = NULL;
        interface->network_info.private_passphrase = NULL;
+#if defined TIZEN_EXT
+       interface->network_info.connector = NULL;
+       interface->network_info.c_sign_key = NULL;
+       interface->network_info.net_access_key = NULL;
+#endif
 }
 
 static int store_network_information(GSupplicantInterface * interface,
@@ -738,6 +872,17 @@ static void callback_assoc_failed(void *user_data)
 
        callbacks_pointer->assoc_failed(user_data);
 }
+
+static void callback_scan_done(GSupplicantInterface *interface)
+{
+       if (!callbacks_pointer)
+               return;
+
+       if (!callbacks_pointer->scan_done)
+               return;
+
+       callbacks_pointer->scan_done(interface);
+}
 #endif
 
 static void callback_network_changed(GSupplicantNetwork *network,
@@ -763,6 +908,43 @@ static void callback_network_associated(GSupplicantNetwork *network)
        callbacks_pointer->network_associated(network);
 }
 
+static void callback_sta_authorized(GSupplicantInterface *interface,
+                                       const char *addr)
+{
+       if (!callbacks_pointer)
+               return;
+
+       if (!callbacks_pointer->sta_authorized)
+               return;
+
+       callbacks_pointer->sta_authorized(interface, addr);
+}
+
+static void callback_sta_deauthorized(GSupplicantInterface *interface,
+                                       const char *addr)
+{
+       if (!callbacks_pointer)
+               return;
+
+       if (!callbacks_pointer->sta_deauthorized)
+               return;
+
+       callbacks_pointer->sta_deauthorized(interface, addr);
+}
+
+#if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET
+static void callback_eap(GSupplicantInterface *interface, bool status)
+{
+       if (!callbacks_pointer)
+               return;
+
+       if (!callbacks_pointer->eap)
+               return;
+
+       callbacks_pointer->eap(interface, status);
+}
+#endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */
+
 static void callback_peer_found(GSupplicantPeer *peer)
 {
        if (!callbacks_pointer)
@@ -896,6 +1078,9 @@ static void remove_network(gpointer data)
        callback_network_removed(network);
 
        g_hash_table_destroy(network->config_table);
+#if defined TIZEN_EXT
+       g_hash_table_destroy(network->assoc_reject_table);
+#endif
 
        g_free(network->path);
        g_free(network->group);
@@ -916,6 +1101,8 @@ static void remove_bss(gpointer data)
 {
        struct g_supplicant_bss *bss = data;
 
+       supplicant_dbus_property_call_cancel_all(bss);
+
        g_free(bss->path);
 #if defined TIZEN_EXT
        g_slist_free_full(bss->vsie_list, g_free);
@@ -946,11 +1133,25 @@ static void remove_peer(gpointer data)
        g_free(peer);
 }
 
+#if defined TIZEN_EXT
+static void remove_assoc_data(gpointer data)
+{
+       struct assoc_reject_data *assoc_data = data;
+
+       g_free(assoc_data->bssid);
+       g_slist_free(assoc_data->reject_time_list);
+
+       g_free(assoc_data);
+}
+#endif
+
 static void debug_strvalmap(const char *label, struct strvalmap *map,
                                                        unsigned int val)
 {
        int i;
-
+#if defined TIZEN_EXT
+       if (!simplified_log)
+#endif
        for (i = 0; map[i].str; i++) {
                if (val & map[i].val)
                        SUPPLICANT_DBG("%s: %s", label, map[i].str);
@@ -1113,12 +1314,36 @@ static void interface_capability(const char *key, DBusMessageIter *iter,
                if (max_scan_ssid < 2)
                        max_scan_ssid = 0;
                interface->max_scan_ssids = max_scan_ssid;
+#if defined TIZEN_EXT
+       } else if (g_strcmp0(key, "Is5GhzSupported") == 0) {
+               dbus_bool_t is_5_0_Ghz_supported;
 
+               dbus_message_iter_get_basic(iter, &is_5_0_Ghz_supported);
+               interface->is_5_0_Ghz_supported = is_5_0_Ghz_supported;
+#endif
        } else
                SUPPLICANT_DBG("key %s type %c",
                                key, dbus_message_iter_get_arg_type(iter));
 }
 
+static void set_bss_expiration_age(DBusMessageIter *iter, void *user_data)
+{
+       unsigned int bss_expiration_age = GPOINTER_TO_UINT(user_data);
+
+       dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32,
+                               &bss_expiration_age);
+}
+
+int g_supplicant_interface_set_bss_expiration_age(GSupplicantInterface *interface,
+                                       unsigned int bss_expiration_age)
+{
+       return supplicant_dbus_property_set(interface->path,
+                                      SUPPLICANT_INTERFACE ".Interface",
+                                      "BSSExpireAge", DBUS_TYPE_UINT32_AS_STRING,
+                                      set_bss_expiration_age, NULL,
+                                      GUINT_TO_POINTER(bss_expiration_age), NULL);
+}
+
 struct set_apscan_data
 {
        unsigned int ap_scan;
@@ -1202,6 +1427,16 @@ const char *g_supplicant_interface_get_ifname(GSupplicantInterface *interface)
        return interface->ifname;
 }
 
+#if defined TIZEN_EXT
+bool g_supplicant_interface_get_is_5_0_ghz_supported(GSupplicantInterface *interface)
+{
+       if (!interface)
+               return NULL;
+
+       return interface->is_5_0_Ghz_supported;
+}
+#endif
+
 const char *g_supplicant_interface_get_driver(GSupplicantInterface *interface)
 {
        if (!interface)
@@ -1623,6 +1858,34 @@ const unsigned char *g_supplicant_network_get_bssid(GSupplicantNetwork *network)
        return (const unsigned char *)network->best_bss->bssid;
 }
 
+dbus_bool_t g_supplicant_network_get_transition_mode(GSupplicantNetwork *network)
+{
+       if (network == NULL)
+               return FALSE;
+
+       return network->owe_transition_mode;
+}
+
+const unsigned char *g_supplicant_network_get_transition_mode_bssid(GSupplicantNetwork *network)
+{
+       if (network == NULL)
+               return NULL;
+
+       return (const unsigned char *)network->transition_mode_bssid;
+}
+
+const void *g_supplicant_network_get_transition_mode_ssid(GSupplicantNetwork *network,
+                                               unsigned int *transition_mode_ssid_len)
+{
+       if (!network) {
+               *transition_mode_ssid_len = 0;
+               return NULL;
+       }
+
+       *transition_mode_ssid_len = network->transition_mode_ssid_len;
+       return network->transition_mode_ssid;
+}
+
 unsigned int g_supplicant_network_get_maxrate(GSupplicantNetwork *network)
 {
        if (network == NULL || network->best_bss == NULL)
@@ -1637,6 +1900,9 @@ const char *g_supplicant_network_get_enc_mode(GSupplicantNetwork *network)
                return NULL;
 
        if (network->best_bss->security == G_SUPPLICANT_SECURITY_PSK ||
+           network->best_bss->security == G_SUPPLICANT_SECURITY_SAE ||
+           network->best_bss->security == G_SUPPLICANT_SECURITY_OWE ||
+           network->best_bss->security == G_SUPPLICANT_SECURITY_DPP ||
            network->best_bss->security == G_SUPPLICANT_SECURITY_IEEE8021X) {
                unsigned int pairwise;
 
@@ -1664,6 +1930,11 @@ bool g_supplicant_network_get_rsn_mode(GSupplicantNetwork *network)
        if (network == NULL || network->best_bss == NULL)
                return 0;
 
+       if (network->best_bss->security == G_SUPPLICANT_SECURITY_SAE ||
+                       network->best_bss->security == G_SUPPLICANT_SECURITY_OWE ||
+                       network->best_bss->security == G_SUPPLICANT_SECURITY_DPP)
+               return false;
+
        if (network->best_bss->rsn_selected) {
                const char *mode = g_supplicant_network_get_enc_mode(network);
                if (g_strcmp0(mode, "aes") == 0 ||
@@ -1702,159 +1973,454 @@ void *g_supplicant_network_get_wifi_vsie(GSupplicantNetwork *network)
        return vsie_list;
 }
 
-static void update_bssid_list(gpointer key, gpointer value, gpointer user_data)
+static bool compare_bssid(unsigned char *bssid_a, unsigned char *bssid_b)
 {
-       struct g_supplicant_bss *bss = value;
-       struct g_connman_bssids *bssids = NULL;
-       char buff[18];
-       GSList **list = (GSList **)user_data;
+       if (!memcmp(bssid_a, bssid_b, WIFI_BSSID_LEN_MAX))
+               return true;
 
-       bssids = (struct g_connman_bssids *)g_try_malloc0(sizeof(struct g_connman_bssids));
+       return false;
+}
 
-       if (bssids) {
-               g_snprintf(buff, 18, "%02x:%02x:%02x:%02x:%02x:%02x",
-                               bss->bssid[0], bss->bssid[1], bss->bssid[2], bss->bssid[3],
-                               bss->bssid[4], bss->bssid[5]);
+static gchar *convert_bssid_to_str(unsigned char *bssid)
+{
+       GString *bssid_str;
+       unsigned int i;
 
-               memcpy(bssids->bssid, buff, 18);
-               bssids->bssid[17] = '\0';
-               bssids->strength = bss->signal;
-               bssids->strength += 120;
+       bssid_str = g_string_sized_new(18);
+       if (!bssid_str)
+               return NULL;
 
-               if (bssids->strength > 100)
-                       bssids->strength = 100;
+       for (i = 0; i < WIFI_BSSID_LEN_MAX; i++) {
+               g_string_append_printf(bssid_str, "%02x", bssid[i]);
+               if (i < WIFI_BSSID_LEN_MAX - 1)
+                       g_string_append(bssid_str, ":");
+       }
 
-               bssids->frequency = bss->frequency;
-               *list = g_slist_append(*list, bssids);
-       } else
-               SUPPLICANT_DBG("Failed to allocate memory");
+       return g_string_free(bssid_str, FALSE);
 }
 
-void *g_supplicant_network_get_bssid_list(GSupplicantNetwork *network)
+static void count_assoc_reject(gpointer data, gpointer user_data)
 {
-       GSList *bssid_list = NULL;
-
-       if (g_hash_table_size(network->bss_table) < 1)
-               return NULL;
-
-       g_hash_table_foreach(network->bss_table, update_bssid_list, &bssid_list);
+       time_t assoc_reject_time = GPOINTER_TO_INT(data);
+       struct assoc_count_data *assoc_count = user_data;
 
-       return bssid_list;
+       if (assoc_reject_time > assoc_count->ref_time)
+               assoc_count->assoc_count++;
 }
-#endif
 
-static void merge_network(GSupplicantNetwork *network)
+static uint16_t get_assoc_reject_cnt(GHashTable *assoc_reject_table, unsigned char *bssid)
 {
-       GString *str;
-       const char *ssid, *mode, *key_mgmt;
-#if defined TIZEN_EXT
-       const char *isHS20AP;
-       const char *eap, *identity, *phase2;
-#endif
-       unsigned int i, ssid_len;
-       char *group;
+       gchar *bssid_str;
+       struct assoc_reject_data *assoc_data;
+       struct assoc_count_data assoc_count;
+       time_t curr_time;
+       struct tm* timeinfo;
 
-       ssid = g_hash_table_lookup(network->config_table, "ssid");
-       mode = g_hash_table_lookup(network->config_table, "mode");
-       key_mgmt = g_hash_table_lookup(network->config_table, "key_mgmt");
-#if defined TIZEN_EXT
-       isHS20AP = g_hash_table_lookup(network->config_table, "isHS20AP");
-       eap = g_hash_table_lookup(network->config_table, "eap");
-       identity = g_hash_table_lookup(network->config_table, "identity");
-       phase2 = g_hash_table_lookup(network->config_table, "phase2");
-#endif
+       if (g_hash_table_size(assoc_reject_table) < 1)
+               return 0;
 
-       SUPPLICANT_DBG("ssid %s mode %s", ssid, mode);
+       if (!bssid)
+               return 0;
 
-       if (ssid)
-               ssid_len = strlen(ssid);
-       else
-               ssid_len = 0;
+       if (!memcmp(bssid, invalid_bssid, WIFI_BSSID_LEN_MAX))
+               return 0;
 
-       str = g_string_sized_new((ssid_len * 2) + 24);
-       if (!str)
-               return;
+       bssid_str = convert_bssid_to_str(bssid);
+       if (!bssid_str)
+               return 0;
 
-       for (i = 0; i < ssid_len; i++)
-#if defined TIZEN_EXT
-       {
-               if (ssid[i] != '"')
-#endif
-               g_string_append_printf(str, "%02x", ssid[i]);
-#if defined TIZEN_EXT
+       assoc_data = g_hash_table_lookup(assoc_reject_table, bssid_str);
+       if (!assoc_data) {
+               g_free(bssid_str);
+               return 0;
        }
-#endif
 
-       if (g_strcmp0(mode, "0") == 0)
-               g_string_append_printf(str, "_managed");
-       else if (g_strcmp0(mode, "1") == 0)
-               g_string_append_printf(str, "_adhoc");
-#if defined TIZEN_EXT_WIFI_MESH
-       else if (g_strcmp0(mode, "5") == 0)
-               g_string_append_printf(str, "_mesh");
-#endif
+       if (g_slist_length(assoc_data->reject_time_list) < 1) {
+               g_free(bssid_str);
+               return 0;
+       }
 
-       if (g_strcmp0(key_mgmt, "WPA-PSK") == 0)
-               g_string_append_printf(str, "_psk");
-#if defined TIZEN_EXT
-       else if (g_strcmp0(key_mgmt, "WPA-EAP") == 0)
-               g_string_append_printf(str, "_ieee8021x");
-       else
-               g_string_append_printf(str, "_none");
-#endif
+       /* Only events that occur within one hour are appened. */
+       curr_time = time(NULL);
+       timeinfo = localtime(&curr_time);
+       timeinfo->tm_hour -= 1;
 
-       group = g_string_free(str, FALSE);
+       assoc_count.ref_time = mktime(timeinfo);
+       assoc_count.assoc_count = 0;
 
-       SUPPLICANT_DBG("%s", group);
+       g_slist_foreach(assoc_data->reject_time_list, count_assoc_reject, &assoc_count);
 
-#if defined TIZEN_EXT
-       if (g_strcmp0(isHS20AP, "1") == 0) {
-               network->isHS20AP = 1;
-               if (network->eap)
-                       g_free(network->eap);
-               network->eap = g_strdup(eap);
+       g_free(bssid_str);
+       return assoc_count.assoc_count;
+}
 
-               if (network->identity)
-                       g_free(network->identity);
-               network->identity = g_strdup(identity);
+#if defined TIZEN_EXT_INS
+static int calculate_score_last_connected_bssid(bool is_last_connected)
+{
+       int score = 0;
 
-               if (network->phase2)
-                       g_free(network->phase2);
-               network->phase2 = g_strdup(phase2);
-       } else
-               network->isHS20AP = 0;
+       if (ins_settings.last_connected_bssid) {
+               if (is_last_connected)
+                       score += ins_settings.last_connected_bssid_score;
+       }
 
-       network->group = g_strdup(group);
-       callback_network_merged(network);
-       g_free(network->group);
-#endif
+       return score;
+}
 
-       g_free(group);
+static int calculate_score_assoc_reject(uint16_t assoc_reject_cnt)
+{
+       int score = 0;
 
-       g_hash_table_destroy(network->config_table);
+       if (ins_settings.assoc_reject)
+               score -= (assoc_reject_cnt * ins_settings.assoc_reject_score);
 
-       g_free(network->path);
-       g_free(network);
+       return score;
 }
 
-static void network_property(const char *key, DBusMessageIter *iter,
-                                                       void *user_data)
+static int calculate_score_frequency(dbus_int16_t strength, dbus_uint16_t frequency)
 {
-       GSupplicantNetwork *network = user_data;
+       int score = 0;
 
-       if (!network->interface)
-               return;
+       switch (ins_settings.preferred_freq_bssid) {
+       case G_SUPPLICANT_INS_PREFERRED_FREQ_24GHZ:
+               if ((frequency >= FREQ_RANGE_24GHZ_CHANNEL_1 &&
+                       frequency <= FREQ_RANGE_24GHZ_CHANNEL_14) &&
+                       (strength > ins_settings.signal_level3_24ghz))
+                       score += ins_settings.preferred_freq_bssid_score;
 
-       if (!key) {
-               merge_network(network);
-               return;
+               break;
+       case G_SUPPLICANT_INS_PREFERRED_FREQ_5GHZ:
+               if ((frequency >= FREQ_RANGE_5GHZ_CHANNEL_32 &&
+                       frequency <= FREQ_RANGE_5GHZ_CHANNEL_165) &&
+                       (strength > ins_settings.signal_level3_5ghz))
+                       score += ins_settings.preferred_freq_bssid_score;
+
+               break;
+       default:
+               break;
        }
 
-       if (g_strcmp0(key, "Enabled") == 0) {
-               dbus_bool_t enabled = FALSE;
+       return score;
+}
 
-               dbus_message_iter_get_basic(iter, &enabled);
-       } else if (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_STRING) {
+static int calculate_score_strength(dbus_int16_t strength)
+{
+       int score = 0;
+
+       if (ins_settings.signal_bssid)
+               score += (((strength > -60) ? -60 : strength) + 85);
+
+       return score;
+}
+
+static int calculate_score_est_throughput(dbus_uint32_t est_throughput)
+{
+       int score = 0;
+
+       if (est_throughput >= 10000)
+               score = est_throughput / 10000;
+
+       if (score > 40)
+               score = 40;
+
+       return score;
+}
+#endif
+
+static int calculate_score(bool is_last_connected, uint16_t assoc_reject_cnt,
+               dbus_uint16_t frequency, dbus_int16_t strength,
+               dbus_int16_t snr, dbus_uint32_t est_throughput)
+{
+       int score = 0;
+
+#if defined TIZEN_EXT_INS
+       score += calculate_score_last_connected_bssid(is_last_connected);
+       score += calculate_score_assoc_reject(assoc_reject_cnt);
+       score += calculate_score_frequency(strength, frequency);
+       score += calculate_score_strength(strength);
+       score += (int)snr;
+       score += calculate_score_est_throughput(est_throughput);
+#endif
+
+       return score;
+}
+
+static void update_bssid_list(gpointer key, gpointer value, gpointer user_data)
+{
+       struct g_supplicant_bss *bss = value;
+       struct g_connman_bssids *bssids = NULL;
+       struct update_bssid_data *bssid_data = (struct update_bssid_data *)user_data;
+
+       bssids = (struct g_connman_bssids *)g_try_malloc0(sizeof(struct g_connman_bssids));
+
+       if (bssids) {
+               memcpy(bssids->bssid, bss->bssid, WIFI_BSSID_LEN_MAX);
+
+               bssids->strength = bss->signal;
+               bssids->strength += 120;
+
+               if (bssids->strength > 100)
+                       bssids->strength = 100;
+
+               bssids->frequency = bss->frequency;
+
+               bssids->assoc_reject_cnt = get_assoc_reject_cnt(bssid_data->assoc_reject_table, bssids->bssid);
+
+               bssids->is_last_connected = compare_bssid(bssids->bssid, bssid_data->last_connected_bssid);
+
+#if defined TIZEN_EXT_INS
+               bssids->score_last_connected_bssid = calculate_score_last_connected_bssid(bssids->is_last_connected);
+               bssids->score_assoc_reject = calculate_score_assoc_reject(bssids->assoc_reject_cnt);
+               bssids->score_frequency = calculate_score_frequency(bss->signal, bssids->frequency);
+               bssids->score_strength = calculate_score_strength(bss->signal);
+               bssids->score_snr = (int)bss->snr;
+               bssids->score_est_throughput = calculate_score_est_throughput(bss->est_throughput);
+#endif
+
+               bssids->ins_score = calculate_score(bssids->is_last_connected,
+                       bssids->assoc_reject_cnt, bssids->frequency, bss->signal,
+                       bss->snr, bss->est_throughput);
+
+               bssid_data->bssid_list = g_slist_append(bssid_data->bssid_list, bssids);
+       } else
+               SUPPLICANT_DBG("Failed to allocate memory");
+}
+
+static gint cmp_bss(gconstpointer a, gconstpointer b)
+{
+       struct g_connman_bssids *entry_a = (struct g_connman_bssids *)a;
+       struct g_connman_bssids *entry_b = (struct g_connman_bssids *)b;
+
+       if (entry_a->ins_score > entry_b->ins_score)
+               return -1;
+
+       if (entry_a->ins_score < entry_b->ins_score)
+               return 1;
+
+       return 0;
+}
+
+#if defined TIZEN_EXT_INS
+static void print_bssid_sort(gpointer data, gpointer user_data)
+{
+       struct g_connman_bssids *bssids = data;
+
+       SUPPLICANT_DBG("bssid[" MACSTR "] total[%2d] freq[%2d] "
+                       "last_conn[%2d] assoc_reject[%2d] strength[%2d]",
+                       MAC2STR(bssids->bssid), bssids->ins_score,
+                       bssids->score_frequency, bssids->score_last_connected_bssid,
+                       bssids->score_assoc_reject, bssids->score_strength);
+}
+#endif
+
+void *g_supplicant_network_get_bssid_list(GSupplicantNetwork *network)
+{
+       struct update_bssid_data bssid_data;
+
+       if (g_hash_table_size(network->bss_table) < 1)
+               return NULL;
+
+       bssid_data.network = network;
+       memset(&bssid_data, 0, sizeof(bssid_data));
+       memcpy(bssid_data.last_connected_bssid, network->last_connected_bssid, WIFI_BSSID_LEN_MAX);
+       bssid_data.assoc_reject_table = network->assoc_reject_table;
+
+       g_hash_table_foreach(network->bss_table, update_bssid_list, &bssid_data);
+       bssid_data.bssid_list = g_slist_sort(bssid_data.bssid_list, cmp_bss);
+#if defined TIZEN_EXT_INS
+       g_slist_foreach(bssid_data.bssid_list, print_bssid_sort, NULL);
+#endif
+
+       return bssid_data.bssid_list;
+}
+
+void g_supplicant_network_set_last_connected_bssid(GSupplicantNetwork *network, const unsigned char *bssid)
+{
+       if (!bssid)
+               return;
+
+       if (!memcmp(bssid, invalid_bssid, WIFI_BSSID_LEN_MAX))
+               return;
+
+       memcpy(network->last_connected_bssid, bssid, WIFI_BSSID_LEN_MAX);
+
+       SUPPLICANT_DBG("last connected bssid [" MACSTR "]", MAC2STR(bssid));
+}
+
+const unsigned char *g_supplicant_network_get_last_connected_bssid(GSupplicantNetwork *network)
+{
+       if (network == NULL)
+               return NULL;
+
+       return (const unsigned char *)network->last_connected_bssid;
+}
+
+void g_supplicant_network_update_assoc_reject(GSupplicantInterface *interface,
+               GSupplicantNetwork *network)
+{
+       struct assoc_reject_data *assoc_data;
+       gchar *bssid_str;
+       time_t curr_time;
+
+       if (!network)
+               return;
+
+       bssid_str = convert_bssid_to_str(interface->add_network_bssid);
+       if (!bssid_str)
+               return;
+
+       assoc_data = g_hash_table_lookup(network->assoc_reject_table, bssid_str);
+       if (!assoc_data) {
+               assoc_data = g_try_new0(struct assoc_reject_data, 1);
+               if (!assoc_data) {
+                       g_free(bssid_str);
+                       return;
+               }
+
+               assoc_data->bssid = g_strdup(bssid_str);
+               g_hash_table_insert(network->assoc_reject_table, assoc_data->bssid, assoc_data);
+       }
+
+       curr_time = time(NULL);
+       assoc_data->reject_time_list = g_slist_append(assoc_data->reject_time_list, GINT_TO_POINTER(curr_time));
+
+       SUPPLICANT_DBG("bssid [%s] time [%u]", bssid_str, curr_time);
+
+       g_free(bssid_str);
+
+       callback_network_changed(network, "UpdateAssocReject");
+}
+
+GHashTable *g_supplicant_network_get_assoc_reject_table(GSupplicantNetwork *network)
+{
+       if (!network)
+               return NULL;
+
+       return network->assoc_reject_table;
+}
+
+GSupplicantNetwork *g_supplicant_interface_get_network(GSupplicantInterface *interface,
+               const char *group)
+{
+       if (!interface)
+               return NULL;
+
+       return g_hash_table_lookup(interface->network_table, group);
+}
+#endif
+
+static void merge_network(GSupplicantNetwork *network)
+{
+       GString *str;
+       const char *ssid, *mode, *key_mgmt;
+#if defined TIZEN_EXT
+       const char *isHS20AP;
+       const char *eap, *identity, *phase2;
+#endif
+       unsigned int i, ssid_len;
+       char *group;
+
+       ssid = g_hash_table_lookup(network->config_table, "ssid");
+       mode = g_hash_table_lookup(network->config_table, "mode");
+       key_mgmt = g_hash_table_lookup(network->config_table, "key_mgmt");
+#if defined TIZEN_EXT
+       isHS20AP = g_hash_table_lookup(network->config_table, "isHS20AP");
+       eap = g_hash_table_lookup(network->config_table, "eap");
+       identity = g_hash_table_lookup(network->config_table, "identity");
+       phase2 = g_hash_table_lookup(network->config_table, "phase2");
+#endif
+
+       SUPPLICANT_DBG("ssid %s mode %s", ssid, mode);
+
+       if (ssid)
+               ssid_len = strlen(ssid);
+       else
+               ssid_len = 0;
+
+       str = g_string_sized_new((ssid_len * 2) + 24);
+       if (!str)
+               return;
+
+       for (i = 0; i < ssid_len; i++)
+#if defined TIZEN_EXT
+       {
+               if (ssid[i] != '"')
+#endif
+               g_string_append_printf(str, "%02x", ssid[i]);
+#if defined TIZEN_EXT
+       }
+#endif
+
+       if (g_strcmp0(mode, "0") == 0)
+               g_string_append_printf(str, "_managed");
+       else if (g_strcmp0(mode, "1") == 0)
+               g_string_append_printf(str, "_adhoc");
+#if defined TIZEN_EXT_WIFI_MESH
+       else if (g_strcmp0(mode, "5") == 0)
+               g_string_append_printf(str, "_mesh");
+#endif
+
+       if (g_strcmp0(key_mgmt, "WPA-PSK") == 0)
+               g_string_append_printf(str, "_psk");
+#if defined TIZEN_EXT
+       else if (g_strcmp0(key_mgmt, "WPA-EAP") == 0)
+               g_string_append_printf(str, "_ieee8021x");
+       else
+               g_string_append_printf(str, "_none");
+#endif
+
+       group = g_string_free(str, FALSE);
+
+       SUPPLICANT_DBG("%s", group);
+
+#if defined TIZEN_EXT
+       if (g_strcmp0(isHS20AP, "1") == 0) {
+               network->isHS20AP = 1;
+               if (network->eap)
+                       g_free(network->eap);
+               network->eap = g_strdup(eap);
+
+               if (network->identity)
+                       g_free(network->identity);
+               network->identity = g_strdup(identity);
+
+               if (network->phase2)
+                       g_free(network->phase2);
+               network->phase2 = g_strdup(phase2);
+       } else
+               network->isHS20AP = 0;
+
+       network->group = g_strdup(group);
+       callback_network_merged(network);
+       g_free(network->group);
+#endif
+
+       g_free(group);
+
+       g_hash_table_destroy(network->config_table);
+
+       g_free(network->path);
+       g_free(network);
+}
+
+static void network_property(const char *key, DBusMessageIter *iter,
+                                                       void *user_data)
+{
+       GSupplicantNetwork *network = user_data;
+
+       if (!network->interface)
+               return;
+
+       if (!key) {
+               merge_network(network);
+               return;
+       }
+
+       if (g_strcmp0(key, "Enabled") == 0) {
+               dbus_bool_t enabled = FALSE;
+
+               dbus_message_iter_get_basic(iter, &enabled);
+       } else if (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_STRING) {
                const char *str = NULL;
 
                dbus_message_iter_get_basic(iter, &str);
@@ -1908,7 +2474,6 @@ static void interface_network_added(DBusMessageIter *iter, void *user_data)
 static void interface_network_removed(DBusMessageIter *iter, void *user_data)
 {
        SUPPLICANT_DBG("");
-       return;
 }
 
 static char *create_name(unsigned char *ssid, int ssid_len)
@@ -1978,12 +2543,58 @@ static char *create_group(struct g_supplicant_bss *bss)
 
        return g_string_free(str, FALSE);
 }
+#if defined TIZEN_EXT
+static void update_network_with_best_bss(GSupplicantNetwork *network,
+               struct g_supplicant_bss *best_bss)
+{
+       network->signal = best_bss->signal;
+       network->frequency = best_bss->frequency;
+       network->best_bss = best_bss;
+}
+
+static bool update_best_bss(GSupplicantNetwork *network,
+               struct g_supplicant_bss *bss, struct g_supplicant_bss *best_bss)
+{
+       int score_new;
+       int score_best;
+
+       if (network->best_bss == NULL) {
+               update_network_with_best_bss(network, bss);
+               return true;
+       }
+
+       score_new = calculate_score(
+               compare_bssid(bss->bssid, network->last_connected_bssid),
+               get_assoc_reject_cnt(network->assoc_reject_table, bss->bssid),
+               bss->frequency, bss->signal, bss->snr, bss->est_throughput);
 
+       score_best = calculate_score(
+               compare_bssid(network->best_bss->bssid, network->last_connected_bssid),
+               get_assoc_reject_cnt(network->assoc_reject_table, network->best_bss->bssid),
+               network->best_bss->frequency, network->best_bss->signal,
+               network->best_bss->snr, network->best_bss->est_throughput);
+
+       if (score_new > score_best) {
+               SUPPLICANT_DBG("new[" MACSTR "][%u] : best[" MACSTR "][%u]",
+                       MAC2STR(bss->bssid), score_new,
+                       MAC2STR(network->best_bss->bssid), score_best);
+
+               update_network_with_best_bss(network, bss);
+
+               SUPPLICANT_DBG("Update best BSS for %s", network->name);
+
+               return true;
+       }
+
+       return false;
+}
+#endif
 static int add_or_replace_bss_to_network(struct g_supplicant_bss *bss)
 {
        GSupplicantInterface *interface = bss->interface;
        GSupplicantNetwork *network;
        char *group;
+       bool is_new_network;
 
        group = create_group(bss);
        SUPPLICANT_DBG("New group created: %s", group);
@@ -1995,10 +2606,13 @@ static int add_or_replace_bss_to_network(struct g_supplicant_bss *bss)
        if (network) {
                g_free(group);
                SUPPLICANT_DBG("Network %s already exist", network->name);
+               is_new_network = false;
 
                goto done;
        }
 
+       is_new_network = true;
+
        network = g_try_new0(GSupplicantNetwork, 1);
        if (!network) {
                g_free(group);
@@ -2018,7 +2632,16 @@ static int add_or_replace_bss_to_network(struct g_supplicant_bss *bss)
        network->frequency = bss->frequency;
        network->best_bss = bss;
 
+       if ((bss->keymgmt & G_SUPPLICANT_KEYMGMT_WPS) != 0) {
+               network->wps = TRUE;
+               network->wps_capabilities = bss->wps_capabilities;
+       }
+
 #if defined TIZEN_EXT
+       network->owe_transition_mode = bss->owe_transition_mode;
+       memcpy(network->transition_mode_ssid, bss->transition_mode_ssid, bss->transition_mode_ssid_len);
+       memcpy(network->transition_mode_bssid, bss->transition_mode_bssid, WIFI_BSSID_LEN_MAX);
+
        network->keymgmt = bss->keymgmt;
 
        if (g_slist_length(bss->vsie_list) > 0) {
@@ -2049,6 +2672,11 @@ static int add_or_replace_bss_to_network(struct g_supplicant_bss *bss)
        network->config_table = g_hash_table_new_full(g_str_hash, g_str_equal,
                                                        g_free, g_free);
 
+#if defined TIZEN_EXT
+       network->assoc_reject_table = g_hash_table_new_full(g_str_hash, g_str_equal,
+                                                       NULL, remove_assoc_data);
+#endif
+
        g_hash_table_replace(interface->network_table,
                                                network->group, network);
 
@@ -2058,19 +2686,29 @@ done:
        /* We update network's WPS properties if only bss provides WPS. */
        if ((bss->keymgmt & G_SUPPLICANT_KEYMGMT_WPS) != 0) {
                network->wps = TRUE;
-               network->wps_capabilities |= bss->wps_capabilities;
+               network->wps_capabilities = bss->wps_capabilities;
+
+               if (!is_new_network)
+                       callback_network_changed(network, "WPSCapabilities");
        }
 
        /*
         * Do not change best BSS if we are connected. It will be done through
         * CurrentBSS property in case of misalignment with wpa_s or roaming.
         */
+#if defined TIZEN_EXT
+       if (network != interface->current_network) {
+               if (update_best_bss(network, bss, network->best_bss))
+                       callback_network_changed(network, "Signal");
+       }
+#else
        if (network != interface->current_network &&
                                bss->signal > network->signal) {
                network->signal = bss->signal;
                network->best_bss = bss;
                callback_network_changed(network, "Signal");
        }
+#endif
 
        g_hash_table_replace(interface->bss_mapping, bss->path, network);
        g_hash_table_replace(network->bss_table, bss->path, bss);
@@ -2274,6 +2912,7 @@ static void bss_process_ies(DBusMessageIter *iter, void *user_data)
        unsigned int value;
        int ie_len;
 #if defined TIZEN_EXT
+       const unsigned char OWE_WFA_OUI[] = { 0x50, 0x6f, 0x9a, 0x1c };
        int r_len, j;
        unsigned char *rates = NULL;
        unsigned char *ext_rates = NULL;
@@ -2306,15 +2945,47 @@ static void bss_process_ies(DBusMessageIter *iter, void *user_data)
 
        bss->wps_capabilities = 0;
        bss->keymgmt = 0;
-       memset(bss->country_code, 0, COUNTRY_CODE_LENGTH);
 
        for (ie_end = ie + ie_len; ie < ie_end && ie + ie[1] + 1 <= ie_end;
                                                        ie += ie[1] + 2) {
 #if defined TIZEN_EXT
                unsigned char *vsie;
                int vsie_len = 0;
+
+               if(ie[0] == VENDOR_SPECIFIC_INFO && memcmp(ie+2, OWE_WFA_OUI, sizeof(OWE_WFA_OUI)) == 0) {
+                       SUPPLICANT_DBG("IE: match vendor specific data : OWE Transition Mode");
+
+/*
+               Tag: Vendor Specific: Wi-Fi Alliance: OWE Transition Mode
+                       Tag Number: Vendor Specific (221)    -> ie[0]
+                       Tag length: 26                       -> ie[1]
+                       OUI: 50:6f:9a (Wi-Fi Alliance)       -> ie[2]
+                       Vendor Specific OUI Type: 28         -> ie[5]
+                       BSSID: 92:fd:f0:20:2b:09             -> ie[6]
+                       SSID length: 15                      -> ie[12]
+                       SSID: Wi-Fi-5.2.3-owe                -> ie[13]
+
+0000   dd 1a 50 6f 9a 1c 92 fd f0 20 2b 09 0f 57 69 2d   ..Po..... +..Wi-
+0010   46 69 2d 35 2e 32 2e 33 2d 6f 77 65               Fi-5.2.3-owe
+
+*/
+                       bss->owe_transition_mode = TRUE;
+                       if (ie[1] >= 11) { // Tag length is at least up to ssid length position.
+                               memcpy(bss->transition_mode_bssid, ie+6, WIFI_BSSID_LEN_MAX);
+                               if (ie[12] > 0 && ie[12] < 32) {
+                                       memcpy(bss->transition_mode_ssid, ie+13, ie[12]);
+                                       bss->transition_mode_ssid_len = ie[12];
+                               } else
+                                       bss->transition_mode_ssid_len = 0;
+                       } else
+                               bss->owe_transition_mode = FALSE;
+                       continue;
+               }
+
                if(ie[0] == VENDOR_SPECIFIC_INFO && memcmp(ie+2, WPS_OUI, sizeof(WPS_OUI)) != 0) {
-                       SUPPLICANT_DBG("IE: match vendor specific data");
+
+                       if (!simplified_log)
+                               SUPPLICANT_DBG("IE: match vendor specific data");
 
                        vsie_len = ie[1]+2;     // tag number size(1), tag length size(1)
                        vsie = (unsigned char *)g_try_malloc0(vsie_len);
@@ -2460,13 +3131,21 @@ static void bss_compute_security(struct g_supplicant_bss *bss)
                bss->psk = TRUE;
 #endif
 
-#if defined TIZEN_EXT_WIFI_MESH
+#if defined TIZEN_EXT
        if (bss->keymgmt & G_SUPPLICANT_KEYMGMT_SAE)
                bss->sae = TRUE;
+       if (bss->keymgmt & G_SUPPLICANT_KEYMGMT_OWE)
+               bss->owe = TRUE;
+       if (bss->keymgmt & G_SUPPLICANT_KEYMGMT_DPP)
+               bss->dpp = TRUE;
 #endif
 
        if (bss->ieee8021x)
                bss->security = G_SUPPLICANT_SECURITY_IEEE8021X;
+#if defined TIZEN_EXT
+       else if (bss->sae)
+               bss->security = G_SUPPLICANT_SECURITY_SAE;
+#endif
        else if (bss->psk)
                bss->security = G_SUPPLICANT_SECURITY_PSK;
 #if defined TIZEN_EXT
@@ -2474,10 +3153,10 @@ static void bss_compute_security(struct g_supplicant_bss *bss)
                bss->security = G_SUPPLICANT_SECURITY_FT_PSK;
        else if (bss->ft_ieee8021x == TRUE)
                bss->security = G_SUPPLICANT_SECURITY_IEEE8021X;
-#endif
-#if defined TIZEN_EXT_WIFI_MESH
-       else if (bss->sae)
-               bss->security = G_SUPPLICANT_SECURITY_SAE;
+       else if (bss->owe || bss->owe_transition_mode)
+               bss->security = G_SUPPLICANT_SECURITY_OWE;
+       else if (bss->dpp)
+               bss->security = G_SUPPLICANT_SECURITY_DPP;
 #endif
        else if (bss->privacy)
                bss->security = G_SUPPLICANT_SECURITY_WEP;
@@ -2493,7 +3172,9 @@ static void bss_property(const char *key, DBusMessageIter *iter,
 
        if (!bss->interface)
                return;
-
+#if defined TIZEN_EXT
+       if (!simplified_log)
+#endif
        SUPPLICANT_DBG("key %s", key);
 
        if (!key)
@@ -2585,6 +3266,17 @@ static void bss_property(const char *key, DBusMessageIter *iter,
                dbus_bool_t hs20 = FALSE;
                dbus_message_iter_get_basic(iter, &hs20);
                bss->hs20 = hs20;
+       } else if (g_strcmp0(key, "SNR") == 0) {
+               dbus_int16_t snr = 0;
+
+               dbus_message_iter_get_basic(iter, &snr);
+               bss->snr = snr;
+       } else if (g_strcmp0(key, "EstThroughput") == 0) {
+               dbus_uint32_t est_throughput = 0;
+
+               dbus_message_iter_get_basic(iter, &est_throughput);
+               if (est_throughput != 0)
+                       bss->est_throughput = est_throughput;
 #endif
        } else if (g_strcmp0(key, "IEs") == 0)
                bss_process_ies(iter, bss);
@@ -2600,7 +3292,9 @@ static struct g_supplicant_bss *interface_bss_added(DBusMessageIter *iter,
        GSupplicantNetwork *network;
        struct g_supplicant_bss *bss;
        const char *path = NULL;
-
+#if defined TIZEN_EXT
+       if (!simplified_log)
+#endif
        SUPPLICANT_DBG("");
 
        dbus_message_iter_get_basic(iter, &path);
@@ -2609,7 +3303,9 @@ static struct g_supplicant_bss *interface_bss_added(DBusMessageIter *iter,
 
        if (g_strcmp0(path, "/") == 0)
                return NULL;
-
+#if defined TIZEN_EXT
+       if (!simplified_log)
+#endif
        SUPPLICANT_DBG("%s", path);
 
        network = g_hash_table_lookup(interface->bss_mapping, path);
@@ -2634,7 +3330,9 @@ static void interface_bss_added_with_keys(DBusMessageIter *iter,
                                                void *user_data)
 {
        struct g_supplicant_bss *bss;
-
+#if defined TIZEN_EXT
+       if (!simplified_log)
+#endif
        SUPPLICANT_DBG("");
 
        bss = interface_bss_added(iter, user_data);
@@ -2644,7 +3342,15 @@ static void interface_bss_added_with_keys(DBusMessageIter *iter,
        dbus_message_iter_next(iter);
 
        if (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_INVALID)
+#if defined TIZEN_EXT
+       {
+               g_free(bss->path);
+               g_free(bss);
+               return;
+       }
+#else
                return;
+#endif
 
        supplicant_dbus_property_foreach(iter, bss_property, bss);
 
@@ -2657,7 +3363,9 @@ static void interface_bss_added_without_keys(DBusMessageIter *iter,
                                                void *user_data)
 {
        struct g_supplicant_bss *bss;
-
+#if defined TIZEN_EXT
+       if (!simplified_log)
+#endif
        SUPPLICANT_DBG("");
 
        bss = interface_bss_added(iter, user_data);
@@ -2666,7 +3374,7 @@ static void interface_bss_added_without_keys(DBusMessageIter *iter,
 
        supplicant_dbus_property_get_all(bss->path,
                                        SUPPLICANT_INTERFACE ".BSS",
-                                       bss_property, bss, NULL);
+                                       bss_property, bss, bss);
 
        bss_compute_security(bss);
        if (add_or_replace_bss_to_network(bss) < 0)
@@ -2679,10 +3387,22 @@ static void update_signal(gpointer key, gpointer value,
        struct g_supplicant_bss *bss = value;
        GSupplicantNetwork *network = user_data;
 
+#if defined TIZEN_EXT
+       if (!network->best_bss || (network->best_bss == bss)) {
+               if (bss->signal > network->signal) {
+                       network->signal = bss->signal;
+                       network->best_bss = bss;
+               }
+               return;
+       }
+
+       update_best_bss(network, bss, network->best_bss);
+#else
        if (bss->signal > network->signal) {
                network->signal = bss->signal;
                network->best_bss = bss;
        }
+#endif
 }
 
 static void update_network_signal(GSupplicantNetwork *network)
@@ -2696,6 +3416,59 @@ static void update_network_signal(GSupplicantNetwork *network)
        SUPPLICANT_DBG("New network signal %d", network->signal);
 }
 
+#if defined TIZEN_EXT
+static gboolean last_connected_timeout(gpointer data)
+{
+       GSupplicantInterface *interface = data;
+       GSupplicantNetwork *current_network = interface->current_network;
+
+       SUPPLICANT_DBG("Timeout last connected bss");
+
+       if (current_network && current_network->best_bss) {
+               if (compare_bssid(current_network->best_bss->bssid, interface->connected_bssid)) {
+                       g_supplicant_network_set_last_connected_bssid(current_network, interface->connected_bssid);
+                       callback_network_changed(current_network, "LastConnectedBSSID");
+               }
+       }
+
+       last_connected_bss_timeout = 0;
+       return FALSE;
+}
+
+static void add_timer_for_last_connected(GSupplicantInterface *interface)
+{
+       GSupplicantNetwork *current_network = interface->current_network;
+
+       if (interface->state == G_SUPPLICANT_STATE_COMPLETED) {
+               if (current_network) {
+                       struct g_supplicant_bss *best_bss = current_network->best_bss;
+
+                       memcpy(interface->connected_bssid, best_bss->bssid, WIFI_BSSID_LEN_MAX);
+
+                       if (last_connected_bss_timeout)
+                               g_source_remove(last_connected_bss_timeout);
+
+                       last_connected_bss_timeout = g_timeout_add_seconds(LAST_CONNECTED_TIMEOUT,
+                               last_connected_timeout, interface);
+
+                       SUPPLICANT_DBG("Add timer for last connected bssid [" MACSTR "]",
+                                       MAC2STR(best_bss->bssid));
+               }
+       }
+}
+
+static void remove_timer_for_last_connected(GSupplicantInterface *interface)
+{
+       if (interface->state == G_SUPPLICANT_STATE_DISCONNECTED) {
+               if (last_connected_bss_timeout != 0) {
+                       g_source_remove(last_connected_bss_timeout);
+                       last_connected_bss_timeout = 0;
+                       SUPPLICANT_DBG("Remove timer for last connected bss");
+               }
+       }
+}
+#endif
+
 static void interface_current_bss(GSupplicantInterface *interface,
                                                DBusMessageIter *iter)
 {
@@ -2720,6 +3493,9 @@ static void interface_current_bss(GSupplicantInterface *interface,
                return;
 
        interface->current_network = network;
+#if defined TIZEN_EXT
+       SUPPLICANT_DBG("current network [%p]", interface->current_network);
+#endif
 
        if (bss != network->best_bss) {
                /*
@@ -2761,6 +3537,9 @@ static void interface_current_bss(GSupplicantInterface *interface,
        case G_SUPPLICANT_STATE_GROUP_HANDSHAKE:
        case G_SUPPLICANT_STATE_COMPLETED:
                callback_network_associated(network);
+#if defined TIZEN_EXT
+               add_timer_for_last_connected(interface);
+#endif
                break;
        }
 }
@@ -2771,6 +3550,7 @@ static void interface_bss_removed(DBusMessageIter *iter, void *user_data)
        GSupplicantNetwork *network;
        struct g_supplicant_bss *bss = NULL;
        const char *path = NULL;
+       bool is_current_network_bss = false;
 
        dbus_message_iter_get_basic(iter, &path);
        if (!path)
@@ -2784,6 +3564,7 @@ static void interface_bss_removed(DBusMessageIter *iter, void *user_data)
        if (network->best_bss == bss) {
                network->best_bss = NULL;
                network->signal = BSS_UNKNOWN_STRENGTH;
+               is_current_network_bss = true;
        }
 
        g_hash_table_remove(bss_mapping, path);
@@ -2793,8 +3574,16 @@ static void interface_bss_removed(DBusMessageIter *iter, void *user_data)
 
        update_network_signal(network);
 
-       if (g_hash_table_size(network->bss_table) == 0)
+       if (g_hash_table_size(network->bss_table) == 0) {
                g_hash_table_remove(interface->network_table, network->group);
+       } else {
+               if (is_current_network_bss && network->best_bss)
+#if defined TIZEN_EXT
+                       callback_network_changed(network, "CheckMultiBssidConnect");
+#else
+                       callback_network_changed(network, "");
+#endif
+       }
 }
 
 static void set_config_methods(DBusMessageIter *iter, void *user_data)
@@ -2809,7 +3598,9 @@ static void wps_property(const char *key, DBusMessageIter *iter,
 
        if (!interface)
                return;
-
+#if defined TIZEN_EXT
+       if (!simplified_log)
+#endif
        SUPPLICANT_DBG("key: %s", key);
 
        if (g_strcmp0(key, "ConfigMethods") == 0) {
@@ -2832,6 +3623,21 @@ static void wps_property(const char *key, DBusMessageIter *iter,
 
 }
 
+#if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET
+void g_supplicant_replace_config_file(const char *ifname, const char *config_file)
+{
+       if (!ifname)
+              return;
+
+       if (!config_file)
+               return;
+
+       SUPPLICANT_DBG("New {%s, %s}", ifname, config_file);
+       g_hash_table_replace(config_file_table,
+                       g_strdup(ifname), g_strdup(config_file));
+}
+#endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */
+
 static void interface_property(const char *key, DBusMessageIter *iter,
                                                        void *user_data)
 {
@@ -2839,7 +3645,9 @@ static void interface_property(const char *key, DBusMessageIter *iter,
 
        if (!interface)
                return;
-
+#if defined TIZEN_EXT
+       if (!simplified_log)
+#endif
        SUPPLICANT_DBG("%s", key);
 
        if (!key) {
@@ -2888,7 +3696,18 @@ static void interface_property(const char *key, DBusMessageIter *iter,
                                interface->state = string2state(str);
                                callback_interface_state(interface);
                        }
-
+#if defined TIZEN_EXT
+               switch (interface->state) {
+               case G_SUPPLICANT_STATE_COMPLETED:
+                       add_timer_for_last_connected(interface);
+                       break;
+               case G_SUPPLICANT_STATE_DISCONNECTED:
+                       remove_timer_for_last_connected(interface);
+                       break;
+               default:
+                       break;
+               }
+#endif
                if (interface->ap_create_in_progress) {
                        if (interface->state == G_SUPPLICANT_STATE_DISCONNECTED)
                                callback_ap_create_fail(interface);
@@ -2973,12 +3792,18 @@ static void interface_property(const char *key, DBusMessageIter *iter,
                if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_INVALID) {
                        dbus_message_iter_get_basic(iter, &reason_code);
                        callback_disconnect_reason_code(interface, reason_code);
+#if defined TIZEN_EXT
+                       SUPPLICANT_DBG("reason code (%d)", reason_code);
+#endif
                }
        } else if (g_strcmp0(key, "AssocStatusCode") == 0) {
                int status_code;
                if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_INVALID) {
                        dbus_message_iter_get_basic(iter, &status_code);
                        callback_assoc_status_code(interface, status_code);
+#if defined TIZEN_EXT
+                       SUPPLICANT_DBG("status code (%d)", status_code);
+#endif
                }
        } else {
                SUPPLICANT_DBG("key %s type %c",
@@ -3016,7 +3841,8 @@ static void scan_bss_data(const char *key, DBusMessageIter *iter,
 
 /*Fixed : stucking in scanning state when scan failed*/
 #if defined TIZEN_EXT
-               GSupplicantInterfaceCallback scan_callback;
+       GSupplicantInterfaceCallback scan_callback;
+       SUPPLICANT_DBG("");
 #endif
 
        if (iter)
@@ -3024,14 +3850,15 @@ static void scan_bss_data(const char *key, DBusMessageIter *iter,
                                                interface);
 
 #if defined TIZEN_EXT
-               scan_callback = interface->scan_callback;
+       scan_callback = interface->scan_callback;
+       callback_scan_done(interface);
 #endif
 
        if (interface->scan_callback)
                interface->scan_callback(0, interface, interface->scan_data);
 
 #if defined TIZEN_EXT
-               if (interface->scan_callback == scan_callback) {
+       if (interface->scan_callback == scan_callback) {
 #endif
        interface->scan_callback = NULL;
        interface->scan_data = NULL;
@@ -3245,7 +4072,9 @@ static void signal_interface_removed(const char *path, DBusMessageIter *iter)
 static void signal_interface_changed(const char *path, DBusMessageIter *iter)
 {
        GSupplicantInterface *interface;
-
+#if defined TIZEN_EXT
+       if (!simplified_log)
+#endif
        SUPPLICANT_DBG("");
 
        interface = g_hash_table_lookup(interface_table, path);
@@ -3295,7 +4124,9 @@ static void signal_scan_done(const char *path, DBusMessageIter *iter)
 static void signal_bss_added(const char *path, DBusMessageIter *iter)
 {
        GSupplicantInterface *interface;
-
+#if defined TIZEN_EXT
+       if (!simplified_log)
+#endif
        SUPPLICANT_DBG("");
 
        interface = g_hash_table_lookup(interface_table, path);
@@ -3343,14 +4174,95 @@ static void signal_network_removed(const char *path, DBusMessageIter *iter)
 
        interface_network_removed(iter, interface);
 }
+#if defined TIZEN_EXT
+void *copy_vsie_list(gconstpointer src, gpointer data)
+{
+       return g_strdup(src);
+}
+#endif
+
+
+static void signal_sta_authorized(const char *path, DBusMessageIter *iter)
+{
+       GSupplicantInterface *interface;
+       const char *addr = NULL;
+
+       SUPPLICANT_DBG("");
+
+       interface = g_hash_table_lookup(interface_table, path);
+       if (!interface)
+               return;
+
+       dbus_message_iter_get_basic(iter, &addr);
+       if (!addr)
+               return;
+
+       callback_sta_authorized(interface, addr);
+}
+
+static void signal_sta_deauthorized(const char *path, DBusMessageIter *iter)
+{
+       GSupplicantInterface *interface;
+       const char *addr = NULL;
+
+       SUPPLICANT_DBG("");
+
+       interface = g_hash_table_lookup(interface_table, path);
+       if (!interface)
+               return;
+
+       dbus_message_iter_get_basic(iter, &addr);
+       if (!addr)
+               return;
+
+       callback_sta_deauthorized(interface, addr);
+}
+
+#if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET
+static void signal_eap(const char *path, DBusMessageIter *iter)
+{
+       GSupplicantInterface *interface;
+       const char *str = NULL;
+
+       SUPPLICANT_DBG("EAPOL_DEBUG callback eap signal");
+
+       interface = g_hash_table_lookup(interface_table, path);
+       if (!interface)
+               return;
+
+       // TODO: Identify EAP fail condition, currently timeout is used for failure.
+
+       dbus_message_iter_get_basic(iter, &str);
+       if (!str)
+               return;
+
+       if (g_strcmp0("completion", str))
+               return;
+
+       dbus_message_iter_next(iter);
+
+       dbus_message_iter_get_basic(iter, &str);
+       if (!str)
+               return;
+
+       if (!g_strcmp0("success", str))
+               callback_eap(interface, true);
+       else
+               callback_eap(interface, false);
+}
+#endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */
 
 static void signal_bss_changed(const char *path, DBusMessageIter *iter)
 {
        GSupplicantInterface *interface;
        GSupplicantNetwork *network;
        GSupplicantSecurity old_security;
+       unsigned int old_wps_capabilities;
        struct g_supplicant_bss *bss;
 
+#if defined TIZEN_EXT
+       if (!simplified_log)
+#endif
        SUPPLICANT_DBG("");
 
        interface = g_hash_table_lookup(bss_mapping, path);
@@ -3366,6 +4278,7 @@ static void signal_bss_changed(const char *path, DBusMessageIter *iter)
                return;
 
        supplicant_dbus_property_foreach(iter, bss_property, bss);
+
 #if defined TIZEN_EXT
        network->frequency = bss->frequency;
        network->phy_mode = bss->phy_mode;
@@ -3376,18 +4289,18 @@ static void signal_bss_changed(const char *path, DBusMessageIter *iter)
        if (old_security != bss->security) {
                struct g_supplicant_bss *new_bss;
 
-               SUPPLICANT_DBG("New network security for %s", bss->ssid);
+               SUPPLICANT_DBG("New network security for %s with path %s",
+                              bss->ssid, bss->path);
 
-               /* Security change policy:
-                * - we first copy the current bss into a new one with
-                * its own pointer (path)
-                * - we remove the current bss related network which will
-                * tell the plugin about such removal. This is done due
-                * to the fact that a security change means a group change
-                * so a complete network change.
-                * (current bss becomes invalid as well)
-                * - we add the new bss: it adds new network and tell the
-                * plugin about it. */
+               /*
+                * Security change policy:
+                * - We first copy the current bss into a new one with
+                *   its own pointer (path)
+                * - Clear the old bss pointer and remove the network completely
+                *   if there are no more BSSs in the bss table.
+                * - The new bss will be added either to an existing network
+                *   or an additional network will be created
+                */
 
                new_bss = g_try_new0(struct g_supplicant_bss, 1);
                if (!new_bss)
@@ -3396,21 +4309,44 @@ static void signal_bss_changed(const char *path, DBusMessageIter *iter)
                memcpy(new_bss, bss, sizeof(struct g_supplicant_bss));
                new_bss->path = g_strdup(bss->path);
 #if defined TIZEN_EXT
-               new_bss->vsie_list = NULL;
+               new_bss->vsie_list = g_slist_copy_deep(bss->vsie_list, copy_vsie_list, NULL);
 #endif
 
-               g_hash_table_remove(interface->network_table, network->group);
+               if (network->best_bss == bss) {
+                       network->best_bss = NULL;
+                       network->signal = BSS_UNKNOWN_STRENGTH;
+               }
+
+               g_hash_table_remove(bss_mapping, path);
+
+               g_hash_table_remove(interface->bss_mapping, path);
+               g_hash_table_remove(network->bss_table, path);
+
+               update_network_signal(network);
+
+               if (g_hash_table_size(network->bss_table) == 0)
+                       g_hash_table_remove(interface->network_table,
+                                           network->group);
 
                if (add_or_replace_bss_to_network(new_bss) < 0) {
-                       /* Remove entries in hash tables to handle the
-                        * failure in add_or_replace_bss_to_network
+                       /*
+                        * Prevent a memory leak on failure in
+                        * add_or_replace_bss_to_network
                         */
-                       g_hash_table_remove(bss_mapping, path);
-                       g_hash_table_remove(interface->bss_mapping, path);
-                       g_hash_table_remove(network->bss_table, path);
+                       SUPPLICANT_DBG("Failed to add bss %s to network table",
+                                      new_bss->path);
+                       g_free(new_bss->path);
+                       g_free(new_bss);
                }
 
-               return;
+               return;
+       }
+
+       old_wps_capabilities = network->wps_capabilities;
+
+       if (old_wps_capabilities != bss->wps_capabilities) {
+               network->wps_capabilities = bss->wps_capabilities;
+               callback_network_changed(network, "WPSCapabilities");
        }
 
 #if defined TIZEN_EXT
@@ -3439,22 +4375,28 @@ static void signal_bss_changed(const char *path, DBusMessageIter *iter)
         * If the new signal is lower than the SSID signal, we need
         * to check for the new maximum.
         */
-       if (bss->signal < network->signal) {
-               if (bss != network->best_bss)
-#ifndef TIZEN_EXT
-                       return;
-#else
-               {
+#if defined TIZEN_EXT
+       if (!update_best_bss(network, bss, network->best_bss)) {
+               if (bss != network->best_bss) {
                        callback_network_changed(network, "");
                        return;
                }
-#endif
+
+               network->signal = bss->signal;
+               update_network_signal(network);
+       }
+#else
+       if (bss->signal < network->signal) {
+               if (bss != network->best_bss)
+                       return;
+
                network->signal = bss->signal;
                update_network_signal(network);
        } else {
                network->signal = bss->signal;
                network->best_bss = bss;
        }
+#endif
 
        SUPPLICANT_DBG("New network signal for %s %d dBm", network->ssid,
                        network->signal);
@@ -3550,7 +4492,7 @@ static void signal_wps_event(const char *path, DBusMessageIter *iter)
 
        if (g_strcmp0(name, "success") == 0)
                interface->wps_state = G_SUPPLICANT_WPS_STATE_SUCCESS;
-       else if (g_strcmp0(name, "failed") == 0)
+       else if (g_strcmp0(name, "fail") == 0)
                interface->wps_state = G_SUPPLICANT_WPS_STATE_FAIL;
        else
                interface->wps_state = G_SUPPLICANT_WPS_STATE_UNKNOWN;
@@ -3586,56 +4528,6 @@ static void signal_power_off(const char *path, DBusMessageIter *iter)
 }
 #endif
 
-static void signal_station_connected(const char *path, DBusMessageIter *iter)
-{
-       GSupplicantInterface *interface;
-       const char *sta_mac = NULL;
-
-       SUPPLICANT_DBG("path %s %s", path, SUPPLICANT_PATH);
-
-       if (callbacks_pointer->add_station == NULL)
-               return;
-
-       if (g_strcmp0(path, "/") == 0)
-               return;
-
-       interface = g_hash_table_lookup(interface_table, path);
-       if (interface == NULL)
-               return;
-
-       dbus_message_iter_get_basic(iter, &sta_mac);
-       if (sta_mac == NULL)
-               return;
-
-       SUPPLICANT_DBG("New station %s connected", sta_mac);
-       callbacks_pointer->add_station(sta_mac);
-}
-
-static void signal_station_disconnected(const char *path, DBusMessageIter *iter)
-{
-       GSupplicantInterface *interface;
-       const char *sta_mac = NULL;
-
-       SUPPLICANT_DBG("path %s %s", path, SUPPLICANT_PATH);
-
-       if (callbacks_pointer->remove_station == NULL)
-               return;
-
-       if (g_strcmp0(path, "/") == 0)
-               return;
-
-       interface = g_hash_table_lookup(interface_table, path);
-       if (interface == NULL)
-               return;
-
-       dbus_message_iter_get_basic(iter, &sta_mac);
-       if (sta_mac == NULL)
-               return;
-
-       SUPPLICANT_DBG("Station %s disconnected", sta_mac);
-       callbacks_pointer->remove_station(sta_mac);
-}
-
 static void create_peer_identifier(GSupplicantPeer *peer)
 {
        const unsigned char test[ETH_ALEN] = {};
@@ -4403,6 +5295,8 @@ static struct {
        { SUPPLICANT_INTERFACE ".Interface", "BSSRemoved",        signal_bss_removed       },
        { SUPPLICANT_INTERFACE ".Interface", "NetworkAdded",      signal_network_added     },
        { SUPPLICANT_INTERFACE ".Interface", "NetworkRemoved",    signal_network_removed   },
+       { SUPPLICANT_INTERFACE ".Interface", "StaAuthorized",     signal_sta_authorized    },
+       { SUPPLICANT_INTERFACE ".Interface", "StaDeauthorized",   signal_sta_deauthorized  },
 
        { SUPPLICANT_INTERFACE ".BSS", "PropertiesChanged", signal_bss_changed   },
 
@@ -4412,9 +5306,6 @@ static struct {
        { "org.tizen.system.deviced.PowerOff", "ChangeState", signal_power_off },
 #endif
 
-       { SUPPLICANT_INTERFACE".Interface", "StaAuthorized", signal_station_connected      },
-       { SUPPLICANT_INTERFACE".Interface", "StaDeauthorized", signal_station_disconnected },
-
        { SUPPLICANT_INTERFACE ".Interface.P2PDevice", "DeviceFound", signal_peer_found },
        { SUPPLICANT_INTERFACE ".Interface.P2PDevice", "DeviceLost",  signal_peer_lost  },
 
@@ -4439,6 +5330,10 @@ static struct {
                signal_mesh_peer_disconnected },
 #endif
 
+#if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET
+       { SUPPLICANT_INTERFACE ".Interface", "EAP", signal_eap },
+#endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */
+
        { }
 };
 
@@ -4503,7 +5398,7 @@ static void country_result(const char *error,
                regdom->callback(result, regdom->alpha2,
                                        (void *) regdom->user_data);
 
-       g_free(regdom);
+       dbus_free(regdom);
 }
 
 static void country_params(DBusMessageIter *iter, void *user_data)
@@ -4767,7 +5662,7 @@ static void interface_create_result(const char *error,
        SUPPLICANT_DBG("");
 
        if (error) {
-               g_warning("error %s", error);
+               g_message("error %s", error);
                err = -EIO;
                goto done;
        }
@@ -4835,6 +5730,19 @@ static void interface_create_params(DBusMessageIter *iter, void *user_data)
                                        DBUS_TYPE_STRING, &config_file);
        }
 
+#ifdef TIZEN_EXT
+       if (data->driver && g_strstr_len(data->driver, strlen(data->driver), "nl80211")) {
+               supplicant_dbus_dict_append_basic(&dict, "MacAddr",
+                               DBUS_TYPE_UINT32, &data->mac_addr);
+
+               supplicant_dbus_dict_append_basic(&dict, "PreassocMacAddr",
+                               DBUS_TYPE_UINT32, &data->preassoc_mac_addr);
+
+               supplicant_dbus_dict_append_basic(&dict, "RandAddrLifetime",
+                               DBUS_TYPE_UINT32, &data->random_mac_lifetime);
+       }
+#endif /* TIZEN_EXT */
+
 #if defined TIZEN_EXT_WIFI_MESH
        if (data->is_mesh_interface) {
                if (data->parent_ifname)
@@ -4849,6 +5757,53 @@ static void interface_create_params(DBusMessageIter *iter, void *user_data)
        supplicant_dbus_dict_close(iter, &dict);
 }
 
+#if defined TIZEN_EXT
+static void interface_get_state(const char *key, DBusMessageIter *iter,
+               void *user_data)
+{
+       struct interface_create_data *data = user_data;
+       GSupplicantInterface *interface = NULL;
+       const char *str = NULL;
+
+       SUPPLICANT_DBG("key[%s]", key);
+
+       if (!data) {
+               SUPPLICANT_DBG("data is NULL");
+               return;
+       }
+
+       interface = data->interface;
+       if (!interface) {
+               SUPPLICANT_DBG("interface is NULL");
+               return;
+       }
+
+       if (iter)
+               dbus_message_iter_get_basic(iter, &str);
+
+       if (str) {
+               if (string2state(str) != interface->state)
+                       interface->state = string2state(str);
+       }
+
+       if (interface->state == G_SUPPLICANT_STATE_DISABLED)
+               interface->ready = FALSE;
+       else
+               interface->ready = TRUE;
+
+       SUPPLICANT_DBG("state %s (%d)", str, interface->state);
+
+       if (data->callback) {
+               data->callback(0, interface, data->user_data);
+#if defined TIZEN_EXT_WIFI_MESH
+               callback_mesh_support(interface);
+#endif
+       }
+
+       interface_create_data_free(data);
+}
+#endif
+
 static void interface_get_result(const char *error,
                                DBusMessageIter *iter, void *user_data)
 {
@@ -4857,6 +5812,9 @@ static void interface_get_result(const char *error,
        const char *path = NULL;
        int err;
 
+#if defined TIZEN_EXT
+       if (!simplified_log)
+#endif
        SUPPLICANT_DBG("");
 
        if (error) {
@@ -4876,6 +5834,16 @@ static void interface_get_result(const char *error,
                goto done;
        }
 
+#if defined TIZEN_EXT
+       data->interface = interface;
+       err = supplicant_dbus_property_get(path,
+                       SUPPLICANT_INTERFACE ".Interface",
+                       "State", interface_get_state, data, NULL);
+
+       if (err == 0)
+               return;
+#endif
+
        if (data->callback) {
                data->callback(0, interface, data->user_data);
 #if !defined TIZEN_EXT
@@ -4917,7 +5885,9 @@ done:
 static void interface_get_params(DBusMessageIter *iter, void *user_data)
 {
        struct interface_create_data *data = user_data;
-
+#if defined TIZEN_EXT
+       if (!simplified_log)
+#endif
        SUPPLICANT_DBG("");
 
        dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &data->ifname);
@@ -4969,7 +5939,7 @@ struct interface_mesh_peer_data {
 };
 
 static void interface_mesh_change_peer_params(DBusMessageIter *iter,
-                                                                                  void *user_data)
+                                               void *user_data)
 {
        struct interface_mesh_peer_data *data = user_data;
 
@@ -5036,6 +6006,11 @@ int g_supplicant_interface_mesh_peer_change_status(
 
 int g_supplicant_interface_create(const char *ifname, const char *driver,
                                        const char *bridge,
+#ifdef TIZEN_EXT
+                                       unsigned int mac_policy,
+                                       unsigned int preassoc_mac_policy,
+                                       unsigned int random_mac_lifetime,
+#endif /* TIZEN_EXT */
                                        GSupplicantInterfaceCallback callback,
                                                        void *user_data)
 {
@@ -5058,6 +6033,11 @@ int g_supplicant_interface_create(const char *ifname, const char *driver,
        data->driver = g_strdup(driver);
        data->bridge = g_strdup(bridge);
        data->callback = callback;
+#ifdef TIZEN_EXT
+       data->mac_addr = mac_policy;
+       data->preassoc_mac_addr = preassoc_mac_policy;
+       data->random_mac_lifetime = random_mac_lifetime;
+#endif /* TIZEN_EXT */
        data->user_data = user_data;
 
        ret = supplicant_dbus_method_call(SUPPLICANT_PATH,
@@ -5113,7 +6093,6 @@ static void interface_remove_params(DBusMessageIter *iter, void *user_data)
                                                        &data->interface->path);
 }
 
-
 int g_supplicant_interface_remove(GSupplicantInterface *interface,
                        GSupplicantInterfaceCallback callback,
                                                        void *user_data)
@@ -5291,14 +6270,16 @@ static void interface_scan_params(DBusMessageIter *iter, void *user_data)
                                        DBUS_TYPE_STRING, &type);
 
 #if defined TIZEN_EXT
-               SUPPLICANT_DBG("[specific_scan] num_ssids %d", data->scan_params->num_ssids);
-               if (data->scan_params->num_ssids != 0)
+               SUPPLICANT_DBG("[specific_scan] num_ssids %d",
+                              data->scan_params->num_ssids);
 #endif
-                       supplicant_dbus_dict_append_array(&dict, "SSIDs",
-                                               DBUS_TYPE_STRING,
-                                               append_ssids,
-                                               data->scan_params);
 
+               if (data->scan_params->ssids) {
+                       supplicant_dbus_dict_append_array(&dict, "SSIDs",
+                                                       DBUS_TYPE_STRING,
+                                                       append_ssids,
+                                                       data->scan_params);
+               }
                supplicant_add_scan_frequency(&dict, add_scan_frequencies,
                                                data->scan_params);
        } else
@@ -5445,6 +6426,7 @@ static void interface_signalpoll_result(const char *error,
        struct interface_signalpoll_data *data = user_data;
        int err = 0;
        dbus_int32_t maxspeed = 0;
+       dbus_int32_t strength = 0;
        DBusMessageIter sub_iter, dict;
 
        if (error) {
@@ -5453,7 +6435,12 @@ static void interface_signalpoll_result(const char *error,
                goto out;
        }
 
-       dbus_message_iter_get_arg_type(iter);
+       if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_VARIANT) {
+               err = -EINVAL;
+               SUPPLICANT_DBG("invalid reply");
+               goto out;
+       }
+
        dbus_message_iter_recurse(iter, &sub_iter);
        dbus_message_iter_recurse(&sub_iter, &dict);
 
@@ -5472,6 +6459,10 @@ static void interface_signalpoll_result(const char *error,
                                dbus_message_iter_get_basic(&value, &maxspeed);
                                SUPPLICANT_DBG("linkspeed = %d", maxspeed);
                                break;
+                       } else if (g_strcmp0(key, "rssi") == 0) {
+                               dbus_message_iter_get_basic(&value, &strength);
+                               SUPPLICANT_DBG("Strength = %d", strength);
+                               break;
                        }
                }
                dbus_message_iter_next(&dict);
@@ -5479,7 +6470,7 @@ static void interface_signalpoll_result(const char *error,
 
 out:
        if(data->callback)
-               data->callback(err, maxspeed, data->user_data);
+               data->callback(err, maxspeed, strength, data->user_data);
 
        g_free(data->path);
        dbus_free(data);
@@ -5573,6 +6564,9 @@ static void interface_select_network_result(const char *error,
 #if defined TIZEN_EXT
        g_free(data->ssid->ssid);
        g_free((char *)data->ssid->passphrase);
+       g_free((char *)data->ssid->connector);
+       g_free((char *)data->ssid->c_sign_key);
+       g_free((char *)data->ssid->net_access_key);
 #endif
        g_free(data->ssid);
        dbus_free(data);
@@ -5662,6 +6656,9 @@ error:
 #if defined TIZEN_EXT
        g_free(data->ssid->ssid);
        g_free((char *)data->ssid->passphrase);
+       g_free((char *)data->ssid->connector);
+       g_free((char *)data->ssid->c_sign_key);
+       g_free((char *)data->ssid->net_access_key);
 #endif
        g_free(data->ssid);
        g_free(data);
@@ -5881,7 +6878,9 @@ static void add_network_security_peap(DBusMessageIter *dict,
 
        }
 
-       if (g_str_has_prefix(ssid->phase2_auth, "EAP-")) {
+       if(g_strcmp0(ssid->phase2_auth, "GTC") == 0 && g_strcmp0(ssid->eap, "ttls") == 0)
+               phase2_auth = g_strdup_printf("autheap=%s", ssid->phase2_auth);
+       else if (g_str_has_prefix(ssid->phase2_auth, "EAP-")) {
                phase2_auth = g_strdup_printf("autheap=%s",
                                        ssid->phase2_auth + strlen("EAP-"));
        } else
@@ -6120,15 +7119,81 @@ static void add_network_security_proto(DBusMessageIter *dict,
        g_free(proto);
 }
 
-#if defined TIZEN_EXT_WIFI_MESH
+#if defined TIZEN_EXT
 static void add_network_ieee80211w(DBusMessageIter *dict, GSupplicantSSID *ssid)
 {
-       if (ssid->security != G_SUPPLICANT_SECURITY_SAE)
+       if (ssid->security != G_SUPPLICANT_SECURITY_SAE
+                       && ssid->security != G_SUPPLICANT_SECURITY_OWE
+                       && ssid->security != G_SUPPLICANT_SECURITY_DPP)
                return;
 
        supplicant_dbus_dict_append_basic(dict, "ieee80211w", DBUS_TYPE_UINT32,
                                          &ssid->ieee80211w);
 }
+
+static void add_network_security_connector(DBusMessageIter *dict, GSupplicantSSID *ssid)
+{
+       if (ssid->connector && strlen(ssid->connector) > 0) {
+               const char *key = "dpp_connector";
+
+               supplicant_dbus_dict_append_basic(dict,
+                               key, DBUS_TYPE_STRING,
+                               &ssid->connector);
+       }
+}
+
+static size_t convert_hexstr_to_bin(const char *hex_str, unsigned char **bin)
+{
+       unsigned char *bin_res = NULL;
+       unsigned int i, j, hex;
+       size_t hex_str_len;
+
+       if (!hex_str || strlen(hex_str) == 0)
+               return 0;
+
+       hex_str_len = strlen(hex_str);
+       bin_res = g_try_malloc0(hex_str_len / 2);
+       if (!bin_res)
+               return 0;
+
+       j = 0;
+       for (i = 0; i < hex_str_len; i+=2) {
+               sscanf(hex_str + i, "%02x", &hex);
+               bin_res[j++] = hex;
+       }
+
+       *bin = bin_res;
+       return hex_str_len / 2;
+}
+
+static void add_network_security_c_sign_key(DBusMessageIter *dict, GSupplicantSSID *ssid)
+{
+       if (ssid->c_sign_key && strlen(ssid->c_sign_key) > 0) {
+               const char *key = "dpp_csign";
+               unsigned char *bin_csign = NULL;
+               size_t bin_csign_len = convert_hexstr_to_bin(ssid->c_sign_key, &bin_csign);
+               if  (bin_csign_len != 0)
+                       supplicant_dbus_dict_append_fixed_array(dict,
+                                       key, DBUS_TYPE_BYTE,
+                                       &bin_csign, bin_csign_len);
+               g_free(bin_csign);
+       }
+}
+
+static void add_network_security_net_access_key(DBusMessageIter *dict, GSupplicantSSID *ssid)
+{
+       if (ssid->net_access_key && strlen(ssid->net_access_key) > 0) {
+               const char *key = "dpp_netaccesskey";
+               unsigned char *bin_netaccesskey = NULL;
+               size_t bin_netaccesskey_len = convert_hexstr_to_bin(ssid->net_access_key, &bin_netaccesskey);
+               if  (bin_netaccesskey_len != 0)
+                       supplicant_dbus_dict_append_fixed_array(dict,
+                                       key, DBUS_TYPE_BYTE,
+                                       &bin_netaccesskey, bin_netaccesskey_len);
+               g_free(bin_netaccesskey);
+       }
+}
+
 #endif
 
 static void add_network_security(DBusMessageIter *dict, GSupplicantSSID *ssid)
@@ -6172,12 +7237,24 @@ static void add_network_security(DBusMessageIter *dict, GSupplicantSSID *ssid)
                add_network_security_ciphers(dict, ssid);
                add_network_security_proto(dict, ssid);
                break;
-#endif
-#if defined TIZEN_EXT_WIFI_MESH
        case G_SUPPLICANT_SECURITY_SAE:
-               key_mgmt = "SAE";
+               if (ssid->keymgmt & G_SUPPLICANT_KEYMGMT_WPA_PSK)
+                       key_mgmt = "SAE WPA-PSK"; // WFA (WPA3 & WPA2 Mixed -> WPA2 only)
+               else
+                       key_mgmt = "SAE";
                add_network_security_psk(dict, ssid);
                break;
+       case G_SUPPLICANT_SECURITY_OWE:
+               key_mgmt = "OWE";
+               add_network_security_ciphers(dict, ssid);
+               add_network_security_proto(dict, ssid);
+               break;
+       case G_SUPPLICANT_SECURITY_DPP:
+               key_mgmt = "DPP";
+               add_network_security_connector(dict, ssid);
+               add_network_security_c_sign_key(dict, ssid);
+               add_network_security_net_access_key(dict, ssid);
+               break;
 #endif
        }
 
@@ -6216,6 +7293,9 @@ static void interface_add_network_params(DBusMessageIter *iter, void *user_data)
        DBusMessageIter dict;
        struct interface_connect_data *data = user_data;
        GSupplicantSSID *ssid = data->ssid;
+#if defined TIZEN_EXT
+       GSupplicantInterface *interface = data->interface;
+#endif
 
        supplicant_dbus_dict_open(iter, &dict);
 
@@ -6235,7 +7315,7 @@ static void interface_add_network_params(DBusMessageIter *iter, void *user_data)
 
        add_network_security(&dict, ssid);
 
-#if defined TIZEN_EXT_WIFI_MESH
+#if defined TIZEN_EXT
        add_network_ieee80211w(&dict, ssid);
 #endif
 
@@ -6243,12 +7323,12 @@ static void interface_add_network_params(DBusMessageIter *iter, void *user_data)
                                        DBUS_TYPE_BYTE, &ssid->ssid,
                                                ssid->ssid_len);
 
-       supplicant_dbus_dict_append_basic(&dict, "ignore_broadcast_ssid",
-                                       DBUS_TYPE_INT32,
-                                       &ssid->ignore_broadcast_ssid);
-
 #if defined TIZEN_EXT
-       if (ssid->bssid) {
+       bool owe_transition_mode = FALSE;
+       if ((ssid->security == G_SUPPLICANT_SECURITY_OWE) && !(ssid->keymgmt & G_SUPPLICANT_KEYMGMT_OWE))
+               owe_transition_mode = TRUE;
+
+       if (ssid->bssid && !owe_transition_mode) {
                char *bssid = NULL;
                bssid = g_try_malloc0(18);
                if (bssid == NULL) {
@@ -6257,14 +7337,15 @@ static void interface_add_network_params(DBusMessageIter *iter, void *user_data)
                        return;
                }
 
-               if (ssid->bssid_for_connect_len)
-                       snprintf(bssid, 18, "%02x:%02x:%02x:%02x:%02x:%02x",
-                                       ssid->bssid_for_connect[0], ssid->bssid_for_connect[1], ssid->bssid_for_connect[2],
-                                       ssid->bssid_for_connect[3], ssid->bssid_for_connect[4], ssid->bssid_for_connect[5]);
-               else
-                       snprintf(bssid, 18, "%02x:%02x:%02x:%02x:%02x:%02x",
-                                       ssid->bssid[0], ssid->bssid[1], ssid->bssid[2],
-                                       ssid->bssid[3], ssid->bssid[4], ssid->bssid[5]);
+               if (ssid->bssid_for_connect_len) {
+                       snprintf(bssid, 18, MACSTR, MAC2STR(ssid->bssid_for_connect));
+                       memcpy(interface->add_network_bssid, ssid->bssid_for_connect, WIFI_BSSID_LEN_MAX);
+               } else {
+                       snprintf(bssid, 18, MACSTR, MAC2STR(ssid->bssid));
+                       memcpy(interface->add_network_bssid, ssid->bssid, WIFI_BSSID_LEN_MAX);
+               }
+
+               SUPPLICANT_DBG("bssid [" MACSTR "]", MAC2STR(interface->add_network_bssid));
 
                supplicant_dbus_dict_append_basic(&dict, "bssid",
                                        DBUS_TYPE_STRING, &bssid);
@@ -6343,6 +7424,7 @@ static void wps_start(const char *error, DBusMessageIter *iter, void *user_data)
                dbus_free(data);
                return;
        }
+
 #if defined TIZEN_EXT
        GSupplicantSSID *ssid = data->ssid;
        if (ssid->pin_wps != NULL) {
@@ -6362,70 +7444,205 @@ static void wps_start(const char *error, DBusMessageIter *iter, void *user_data)
 
 static void wps_process_credentials(DBusMessageIter *iter, void *user_data)
 {
-       dbus_bool_t credentials = TRUE;
+       dbus_bool_t credentials = TRUE;
+
+       SUPPLICANT_DBG("");
+
+       dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &credentials);
+}
+
+
+#if defined TIZEN_EXT
+#define NETCONFIG_SERVICE "net.netconfig"
+#define NETCONFIG_WIFI_PATH "/net/netconfig/wifi"
+#define NETCONFIG_WIFI_INTERFACE NETCONFIG_SERVICE ".wifi"
+
+struct dec_method_call_data {
+       struct interface_connect_data *data;
+       DBusPendingCall *pending_call;
+};
+
+static struct dec_method_call_data decrypt_request_data;
+
+static void crypt_method_call_cancel(void)
+{
+       if (decrypt_request_data.pending_call) {
+               dbus_pending_call_cancel(decrypt_request_data.pending_call);
+               dbus_pending_call_unref(decrypt_request_data.pending_call);
+               decrypt_request_data.pending_call = NULL;
+       }
+
+       g_free(decrypt_request_data.data->path);
+       g_free(decrypt_request_data.data->ssid);
+       dbus_free(decrypt_request_data.data);
+       decrypt_request_data.data = NULL;
+}
+
+static void decryption_request_reply(DBusPendingCall *call,
+                                               void *user_data)
+{
+       DBusMessage *reply;
+       DBusError error;
+       DBusMessageIter args;
+       char *out_data;
+       int ret;
+       struct interface_connect_data *data = user_data;
+
+       SUPPLICANT_DBG("");
+
+       reply = dbus_pending_call_steal_reply(call);
+
+       dbus_error_init(&error);
+       if (dbus_set_error_from_message(&error, reply)) {
+               SUPPLICANT_DBG("decryption_request_reply() %s %s", error.name, error.message);
+               dbus_error_free(&error);
+               ret = -EINVAL;
+               goto done;
+       }
+
+       if (dbus_message_iter_init(reply, &args) == FALSE) {
+               SUPPLICANT_DBG("dbus_message_iter_init() failed");
+               ret = -EINVAL;
+               goto done;
+       }
+
+       dbus_message_iter_get_basic(&args, &out_data);
+       data->ssid->passphrase = g_strdup((const gchar *)out_data);
+
+       ret = supplicant_dbus_method_call(data->interface->path,
+               SUPPLICANT_INTERFACE ".Interface", "AddNetwork",
+               interface_add_network_params,
+               interface_add_network_result, data,
+               data->interface);
+
+done:
+       if (ret < 0) {
+               SUPPLICANT_DBG("AddNetwork failed %d", ret);
+               callback_assoc_failed(decrypt_request_data.data->user_data);
+               g_free(data->path);
+               g_free(data->ssid->ssid);
+               g_free((char *)data->ssid->passphrase);
+               g_free((char *)data->ssid->connector);
+               g_free((char *)data->ssid->c_sign_key);
+               g_free((char *)data->ssid->net_access_key);
+               g_free(data->ssid);
+               dbus_free(data);
+       }
+
+       dbus_message_unref(reply);
+       dbus_pending_call_unref(call);
+
+       decrypt_request_data.pending_call = NULL;
+       decrypt_request_data.data = NULL;
+}
+
+static int send_decryption_request(const char *passphrase,
+                       struct interface_connect_data *data)
+{
+       DBusMessage *msg = NULL;
+       DBusPendingCall *call;
 
-       SUPPLICANT_DBG("");
+       SUPPLICANT_DBG("Decryption request");
 
-       dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &credentials);
-}
+       if (!passphrase) {
+               SUPPLICANT_DBG("Invalid parameter");
+               return -EINVAL;
+       }
 
+       if (!connection)
+               return -EINVAL;
 
-#if defined TIZEN_EXT
-#define NETCONFIG_SERVICE "net.netconfig"
-#define NETCONFIG_WIFI_PATH "/net/netconfig/wifi"
-#define NETCONFIG_WIFI_INTERFACE NETCONFIG_SERVICE ".wifi"
+       msg = dbus_message_new_method_call(NETCONFIG_SERVICE, NETCONFIG_WIFI_PATH,
+                       NETCONFIG_WIFI_INTERFACE, "DecryptPassphrase");
+       if (!msg)
+               return -EINVAL;
 
-struct dec_method_call_data {
-       struct interface_connect_data *data;
-       DBusPendingCall *pending_call;
-};
+#if defined TIZEN_EXT
+       if (!dbus_message_append_args(msg, DBUS_TYPE_STRING, &passphrase,
+                                                       DBUS_TYPE_INVALID)) {
+               SUPPLICANT_DBG("Could not fulfill decryption request");
+               return -ENOMEM;
+       }
+#else
+       dbus_message_append_args(msg, DBUS_TYPE_STRING, &passphrase,
+                                                       DBUS_TYPE_INVALID);
+#endif
 
-static struct dec_method_call_data decrypt_request_data;
+       if (!dbus_connection_send_with_reply(connection, msg,
+                               &call, DBUS_TIMEOUT_USE_DEFAULT)) {
+               dbus_message_unref(msg);
+               return -EIO;
+       }
 
-static void crypt_method_call_cancel(void)
-{
-       if (decrypt_request_data.pending_call) {
-               dbus_pending_call_cancel(decrypt_request_data.pending_call);
-               dbus_pending_call_unref(decrypt_request_data.pending_call);
-               decrypt_request_data.pending_call = NULL;
+       if (!call) {
+               dbus_message_unref(msg);
+               return -EIO;
        }
 
-       g_free(decrypt_request_data.data->path);
-       g_free(decrypt_request_data.data->ssid);
-       dbus_free(decrypt_request_data.data);
-       decrypt_request_data.data = NULL;
+       decrypt_request_data.pending_call = call;
+       decrypt_request_data.data = data;
+
+       dbus_pending_call_set_notify(call, decryption_request_reply, data, NULL);
+       dbus_message_unref(msg);
+
+       SUPPLICANT_DBG("Decryption request succeeded");
+
+       return 0;
 }
 
-static void decryption_request_reply(DBusPendingCall *call,
+static void decrypt_conf_obj_reply(DBusPendingCall *call,
                                                void *user_data)
 {
        DBusMessage *reply;
        DBusError error;
-       DBusMessageIter args;
+       DBusMessageIter iter, dict;
        char *out_data;
        int ret;
        struct interface_connect_data *data = user_data;
 
-       SUPPLICANT_DBG("");
-
        reply = dbus_pending_call_steal_reply(call);
 
        dbus_error_init(&error);
        if (dbus_set_error_from_message(&error, reply)) {
-               SUPPLICANT_DBG("decryption_request_reply() %s %s", error.name, error.message);
+               SUPPLICANT_DBG("decryption_conf_obj_reply() %s %s", error.name, error.message);
                dbus_error_free(&error);
                ret = -EINVAL;
                goto done;
        }
 
-       if (dbus_message_iter_init(reply, &args) == FALSE) {
+       if (dbus_message_iter_init(reply, &iter) == FALSE) {
                SUPPLICANT_DBG("dbus_message_iter_init() failed");
                ret = -EINVAL;
                goto done;
        }
 
-       dbus_message_iter_get_basic(&args, &out_data);
-       data->ssid->passphrase = g_strdup((const gchar *)out_data);
+       dbus_message_iter_recurse(&iter, &dict);
+
+       while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
+               DBusMessageIter entry, value;
+               const char *key;
+
+               dbus_message_iter_recurse(&dict, &entry);
+               dbus_message_iter_get_basic(&entry, &key);
+               dbus_message_iter_next(&entry);
+               dbus_message_iter_recurse(&entry, &value);
+               if (dbus_message_iter_get_arg_type(&value) == DBUS_TYPE_STRING) {
+                       if (g_strcmp0(key, "connector") == 0) {
+                               dbus_message_iter_get_basic(&value, &out_data);
+                               data->ssid->connector = g_strdup((const gchar *)out_data);
+                               SUPPLICANT_DBG("connector %s", data->ssid->connector);
+                       } else if (g_strcmp0(key, "c_sign_key") == 0) {
+                               dbus_message_iter_get_basic(&value, &out_data);
+                               data->ssid->c_sign_key = g_strdup((const gchar *)out_data);
+                               SUPPLICANT_DBG("c_sign_key %s", data->ssid->c_sign_key);
+                       } else if (g_strcmp0(key, "net_access_key") == 0) {
+                               dbus_message_iter_get_basic(&value, &out_data);
+                               data->ssid->net_access_key = g_strdup((const gchar *)out_data);
+                               SUPPLICANT_DBG("net_access_key %s", data->ssid->net_access_key);
+                       }
+               }
+               dbus_message_iter_next(&dict);
+       }
 
        ret = supplicant_dbus_method_call(data->interface->path,
                SUPPLICANT_INTERFACE ".Interface", "AddNetwork",
@@ -6439,7 +7656,9 @@ done:
                callback_assoc_failed(decrypt_request_data.data->user_data);
                g_free(data->path);
                g_free(data->ssid->ssid);
-               g_free((char *)data->ssid->passphrase);
+               g_free((char *)data->ssid->connector);
+               g_free((char *)data->ssid->c_sign_key);
+               g_free((char *)data->ssid->net_access_key);
                g_free(data->ssid);
                dbus_free(data);
        }
@@ -6451,15 +7670,15 @@ done:
        decrypt_request_data.data = NULL;
 }
 
-static int send_decryption_request(const char *passphrase,
+static int send_decryption_conf_obj_request(GSupplicantSSID *ssid,
                        struct interface_connect_data *data)
 {
        DBusMessage *msg = NULL;
        DBusPendingCall *call;
 
-       SUPPLICANT_DBG("Decryption request");
+       SUPPLICANT_DBG("Decryption configuration object request");
 
-       if (!passphrase) {
+       if (!ssid) {
                SUPPLICANT_DBG("Invalid parameter");
                return -EINVAL;
        }
@@ -6468,11 +7687,15 @@ static int send_decryption_request(const char *passphrase,
                return -EINVAL;
 
        msg = dbus_message_new_method_call(NETCONFIG_SERVICE, NETCONFIG_WIFI_PATH,
-                       NETCONFIG_WIFI_INTERFACE, "DecryptPassphrase");
+                       NETCONFIG_WIFI_INTERFACE, "DecryptConfObj");
        if (!msg)
                return -EINVAL;
 
-       dbus_message_append_args(msg, DBUS_TYPE_STRING, &passphrase,
+       dbus_message_append_args(msg, DBUS_TYPE_STRING, &ssid->connector,
+                                                       DBUS_TYPE_INVALID);
+       dbus_message_append_args(msg, DBUS_TYPE_STRING, &ssid->c_sign_key,
+                                                       DBUS_TYPE_INVALID);
+       dbus_message_append_args(msg, DBUS_TYPE_STRING, &ssid->net_access_key,
                                                        DBUS_TYPE_INVALID);
 
        if (!dbus_connection_send_with_reply(connection, msg,
@@ -6489,13 +7712,23 @@ static int send_decryption_request(const char *passphrase,
        decrypt_request_data.pending_call = call;
        decrypt_request_data.data = data;
 
-       dbus_pending_call_set_notify(call, decryption_request_reply, data, NULL);
+       dbus_pending_call_set_notify(call, decrypt_conf_obj_reply, data, NULL);
        dbus_message_unref(msg);
 
-       SUPPLICANT_DBG("Decryption request succeeded");
+       SUPPLICANT_DBG("Decrypt Conf Obj request succeeded");
 
        return 0;
 }
+
+static bool is_valid_config_object(GSupplicantSSID *ssid)
+{
+       return ((ssid->connector &&
+                       g_strcmp0(ssid->connector, "") != 0) &&
+                       (ssid->c_sign_key &&
+                       g_strcmp0(ssid->c_sign_key, "") != 0) &&
+                       (ssid->net_access_key &&
+                       g_strcmp0(ssid->net_access_key, "") != 0));
+}
 #endif
 
 int g_supplicant_interface_connect(GSupplicantInterface *interface,
@@ -6580,7 +7813,7 @@ int g_supplicant_interface_connect(GSupplicantInterface *interface,
                        intf_data->user_data = user_data;
                        intf_data->network_remove_in_progress = TRUE;
                        network_remove(intf_data);
-               } else
+               } else {
 #if defined TIZEN_EXT
                        if (ssid->passphrase &&
                            g_strcmp0(ssid->passphrase, "") != 0 &&
@@ -6591,13 +7824,19 @@ int g_supplicant_interface_connect(GSupplicantInterface *interface,
                                ret = send_decryption_request(ssid->passphrase, data);
                                if (ret < 0)
                                        SUPPLICANT_DBG("Decryption request failed %d", ret);
+                       } else if (is_valid_config_object(ssid)) {
+                               ret = send_decryption_conf_obj_request(ssid, data);
+                               if (ret < 0)
+                                       SUPPLICANT_DBG("Decryption Conf Obj request failed %d", ret);
+
                        } else
 #endif
-                               ret = supplicant_dbus_method_call(interface->path,
-                                               SUPPLICANT_INTERFACE ".Interface", "AddNetwork",
-                                               interface_add_network_params,
-                                               interface_add_network_result, data,
-                                               interface);
+                       ret = supplicant_dbus_method_call(interface->path,
+                                       SUPPLICANT_INTERFACE ".Interface", "AddNetwork",
+                                       interface_add_network_params,
+                                       interface_add_network_result, data,
+                                       interface);
+               }
        }
 
        if (ret < 0) {
@@ -6655,6 +7894,14 @@ static void network_remove_result(const char *error,
                                g_free(connect_data->path);
                                dbus_free(connect_data);
                        }
+               } else if (is_valid_config_object(data->ssid)) {
+                       ret = send_decryption_conf_obj_request(data->ssid, connect_data);
+                       if (ret < 0) {
+                               SUPPLICANT_DBG("Decryption Conf Obj request failed %d", ret);
+                               g_free(connect_data->ssid);
+                               g_free(connect_data->path);
+                               dbus_free(connect_data);
+                       }
                } else
 #endif
                supplicant_dbus_method_call(data->interface->path,
@@ -7247,6 +8494,7 @@ int g_supplicant_set_widi_ies(GSupplicantP2PServiceParams *p2p_service_params,
        return -EINPROGRESS;
 }
 
+
 static const char *g_supplicant_rule0 = "type=signal,"
                                        "path=" DBUS_PATH_DBUS ","
                                        "sender=" DBUS_SERVICE_DBUS ","
@@ -7293,7 +8541,65 @@ static void invoke_introspect_method(void)
        dbus_message_unref(message);
 }
 
+#if defined TIZEN_EXT && defined TIZEN_EXT_INS
+void g_supplicant_set_ins_settings(GSupplicantINSPreferredFreq preferred_freq_bssid,
+               bool last_connected_bssid, bool assoc_reject, bool signal_bssid,
+               unsigned int preferred_freq_bssid_score, unsigned int last_connected_bssid_score,
+               unsigned int assoc_reject_score, int signal_level3_5ghz, int signal_level3_24ghz)
+{
+       ins_settings.preferred_freq_bssid = preferred_freq_bssid;
+       ins_settings.last_connected_bssid = last_connected_bssid;
+       ins_settings.assoc_reject = assoc_reject;
+       ins_settings.signal_bssid = signal_bssid;
+       ins_settings.preferred_freq_bssid_score = preferred_freq_bssid_score;
+       ins_settings.last_connected_bssid_score = last_connected_bssid_score;
+       ins_settings.assoc_reject_score = assoc_reject_score;
+       ins_settings.signal_level3_5ghz = signal_level3_5ghz;
+       ins_settings.signal_level3_24ghz = signal_level3_24ghz;
+
+       SUPPLICANT_DBG("preferred_freq_bssid [%s]", preferred_freq_bssid ? "true" : "false");
+       SUPPLICANT_DBG("preferred_freq_bssid_score [%d]", preferred_freq_bssid_score);
+       SUPPLICANT_DBG("last_connected_bssid [%s]", last_connected_bssid ? "true" : "false");
+       SUPPLICANT_DBG("last_connected_bssid_score [%d]", last_connected_bssid_score);
+       SUPPLICANT_DBG("assoc_reject [%s]", assoc_reject ? "true" : "false");
+       SUPPLICANT_DBG("assoc_reject_score [%d]", assoc_reject_score);
+       SUPPLICANT_DBG("signal_bssid [%s]", signal_bssid ? "true" : "false");
+       SUPPLICANT_DBG("signal_level3_5ghz [%d]", signal_level3_5ghz);
+       SUPPLICANT_DBG("signal_level3_24ghz [%d]", signal_level3_24ghz);
+}
+#endif /* defined TIZEN_EXT && defined TIZEN_EXT_INS */
+
+#if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET
+void g_supplicant_register_eap_callback(g_supplicant_eap_callback cb)
+{
+       SUPPLICANT_DBG("g_supplicant_register_eap_callback %p", cb);
+
+       if (!callbacks_pointer) {
+               SUPPLICANT_DBG("callbacks_pointer is NULL");
+               return;
+       }
+
+       callbacks_pointer->eap = cb;
+}
+
+void g_supplicant_unregister_eap_callback(void)
+{
+       SUPPLICANT_DBG("g_supplicant_unregister_eap_callback");
+
+       if (!callbacks_pointer) {
+               SUPPLICANT_DBG("callbacks_pointer is NULL");
+               return;
+       }
+
+       callbacks_pointer->eap = NULL;
+}
+#endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */
+
+#if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET
+int g_supplicant_register(GSupplicantCallbacks *callbacks)
+#else /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */
 int g_supplicant_register(const GSupplicantCallbacks *callbacks)
+#endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */
 {
        connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
        if (!connection)
@@ -7305,7 +8611,9 @@ int g_supplicant_register(const GSupplicantCallbacks *callbacks)
                connection = NULL;
                return -EIO;
        }
-
+#if defined TIZEN_EXT
+       simplified_log = connman_setting_get_bool("SimplifiedLog");
+#endif
        callbacks_pointer = callbacks;
        eap_methods = 0;
 
@@ -7355,6 +8663,7 @@ int g_supplicant_register(const GSupplicantCallbacks *callbacks)
        } else
                invoke_introspect_method();
 
+       SUPPLICANT_DBG("supplicant dbus setup completed");
        return 0;
 }
 
@@ -7443,3 +8752,176 @@ void g_supplicant_unregister(const GSupplicantCallbacks *callbacks)
        callbacks_pointer = NULL;
        eap_methods = 0;
 }
+
+#ifdef TIZEN_EXT
+struct supplicant_mac_policy {
+       GSupplicantMacPolicyCallback callback;
+       dbus_uint32_t policy;
+       const void *user_data;
+};
+
+static void mac_policy_result(const char *error,
+                               DBusMessageIter *iter, void *user_data)
+{
+       struct supplicant_mac_policy *data = user_data;
+       int result = 0;
+
+       if (!user_data)
+               return;
+
+       if (error) {
+               SUPPLICANT_DBG("Mac policy setting failure %s", error);
+               result = -EINVAL;
+       }
+
+       if (data->callback)
+               data->callback(result, data->policy,
+                                       (void *) data->user_data);
+
+       dbus_free(data);
+}
+
+static void mac_policy_params(DBusMessageIter *iter, void *user_data)
+{
+       struct supplicant_mac_policy *data = user_data;
+
+       dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &(data->policy));
+}
+
+int g_supplicant_interface_set_mac_policy(GSupplicantInterface *interface,
+                                       GSupplicantMacPolicyCallback callback,
+                                                       unsigned int policy,
+                                                       void *user_data)
+{
+       struct supplicant_mac_policy *data = NULL;
+       int ret;
+
+       if (!system_available)
+               return -EFAULT;
+
+       if (!interface)
+               return -EINVAL;
+
+       data = dbus_malloc0(sizeof(*data));
+       if (!data)
+               return -ENOMEM;
+
+       data->callback = callback;
+       data->policy = policy;
+       data->user_data = user_data;
+
+       ret =  supplicant_dbus_property_set(interface->path,
+                               SUPPLICANT_INTERFACE ".Interface",
+                               "MacAddr", DBUS_TYPE_INT32_AS_STRING,
+                               mac_policy_params, mac_policy_result, data, NULL);
+       if (ret < 0) {
+               SUPPLICANT_DBG("Unable to set MacAddr configuration");
+               dbus_free(data);
+       }
+
+       return ret;
+}
+
+int g_supplicant_interface_set_preassoc_mac_policy(GSupplicantInterface *interface,
+                                       GSupplicantMacPolicyCallback callback,
+                                                       unsigned int policy,
+                                                       void *user_data)
+{
+       struct supplicant_mac_policy *data;
+       int ret;
+
+       if (!system_available)
+               return -EFAULT;
+
+       if (!interface)
+               return -EINVAL;
+
+       data = dbus_malloc0(sizeof(*data));
+       if (!data)
+               return -ENOMEM;
+
+       data->callback = callback;
+       data->policy = policy;
+       data->user_data = user_data;
+
+       ret =  supplicant_dbus_property_set(interface->path,
+                               SUPPLICANT_INTERFACE ".Interface",
+                               "PreassocMacAddr", DBUS_TYPE_INT32_AS_STRING,
+                               mac_policy_params, mac_policy_result, data, NULL);
+       if (ret < 0) {
+               SUPPLICANT_DBG("Unable to set PreassocMacAddr configuration");
+               dbus_free(data);
+       }
+
+       return ret;
+}
+
+struct supplicant_random_mac_lifetime {
+       GSupplicantRandomMaclifetimeCallback callback;
+       dbus_uint32_t lifetime;
+       const void *user_data;
+};
+
+static void random_mac_lifetime_result(const char *error,
+                               DBusMessageIter *iter, void *user_data)
+{
+       struct supplicant_random_mac_lifetime *data = user_data;
+       int result = 0;
+
+       if (!user_data)
+               return;
+
+       if (error) {
+               SUPPLICANT_DBG("Random Mac lifetime setting failure %s", error);
+               result = -EINVAL;
+       }
+
+       if (data->callback)
+               data->callback(result, data->lifetime,
+                                       (void *) data->user_data);
+
+       dbus_free(data);
+}
+
+static void random_mac_lifetime_params(DBusMessageIter *iter, void *user_data)
+{
+       struct supplicant_random_mac_lifetime *data = user_data;
+
+       dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32, &(data->lifetime));
+}
+
+int g_supplicant_interface_set_random_mac_lifetime(GSupplicantInterface *interface,
+                                       GSupplicantRandomMaclifetimeCallback callback,
+                                                       unsigned int lifetime,
+                                                       void *user_data)
+{
+       struct supplicant_random_mac_lifetime *data;
+       int ret;
+
+       if (!system_available)
+               return -EFAULT;
+
+       if (!interface)
+               return -EINVAL;
+
+       data = dbus_malloc0(sizeof(*data));
+       if (!data)
+               return -ENOMEM;
+
+       data->callback = callback;
+       data->lifetime = lifetime;
+       data->user_data = user_data;
+
+       ret =  supplicant_dbus_property_set(interface->path,
+                               SUPPLICANT_INTERFACE ".Interface",
+                               "RandAddrLifetime", DBUS_TYPE_UINT32_AS_STRING,
+                               random_mac_lifetime_params, random_mac_lifetime_result,
+                               data, NULL);
+       if (ret < 0) {
+               SUPPLICANT_DBG("Unable to set RandAddrLifetime configuration");
+               dbus_free(data);
+       }
+
+       return ret;
+}
+#endif