Support PSK_SHA256 for ieee80211w
[platform/upstream/connman.git] / gsupplicant / supplicant.c
index c727c07..8996d2d 100755 (executable)
@@ -54,7 +54,6 @@
 #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
@@ -123,6 +122,7 @@ static struct strvalmap keymgmt_map[] = {
        { "wps",                G_SUPPLICANT_KEYMGMT_WPS                },
 #if defined TIZEN_EXT
        { "sae",                G_SUPPLICANT_KEYMGMT_SAE                },
+       { "ft-sae",             G_SUPPLICANT_KEYMGMT_FT_SAE             },
        { "owe",                G_SUPPLICANT_KEYMGMT_OWE                },
        { "dpp",                G_SUPPLICANT_KEYMGMT_DPP                },
 #endif
@@ -175,7 +175,7 @@ static struct strvalmap mode_capa_map[] = {
        { }
 };
 
-#if defined TIZEN_EXT
+#if defined TIZEN_EXT && defined TIZEN_EXT_INS
 struct _GSupplicantINSSettings {
        GSupplicantINSPreferredFreq preferred_freq_bssid;
        unsigned int preferred_freq_bssid_score;
@@ -189,7 +189,9 @@ struct _GSupplicantINSSettings {
 };
 
 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
 };
@@ -304,6 +306,9 @@ 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;
+       dbus_bool_t psk_sha256;
 #endif
        unsigned int wps_capabilities;
 #if defined TIZEN_EXT
@@ -314,6 +319,7 @@ struct g_supplicant_bss {
        unsigned int transition_mode_ssid_len;
        unsigned char transition_mode_bssid[6];
        unsigned char transition_mode_ssid[32];
+       dbus_bool_t pmf_required;
 #endif
 };
 
@@ -343,6 +349,7 @@ struct _GSupplicantNetwork {
        unsigned char country_code[COUNTRY_CODE_LENGTH];
        GSupplicantPhy_mode phy_mode;
        dbus_bool_t owe_transition_mode;
+       dbus_bool_t privacy;
        unsigned int transition_mode_ssid_len;
        unsigned char transition_mode_bssid[6];
        unsigned char transition_mode_ssid[32];
@@ -432,21 +439,6 @@ struct interface_scan_data {
 };
 
 #if defined TIZEN_EXT
-struct g_connman_bssids {
-       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;
-#endif
-       int ins_score;
-};
-
 struct update_bssid_data {
        GSupplicantNetwork *network;
        unsigned char last_connected_bssid[WIFI_BSSID_LEN_MAX];
@@ -548,6 +540,8 @@ static const char *security2string(GSupplicantSecurity security)
        case G_SUPPLICANT_SECURITY_IEEE8021X:
                return "ieee8021x";
 #if defined TIZEN_EXT
+       case G_SUPPLICANT_SECURITY_PSK_SHA256:
+               return "psk_sha256";
        case G_SUPPLICANT_SECURITY_FT_PSK:
                return "ft_psk";
        case G_SUPPLICANT_SECURITY_FT_IEEE8021X:
@@ -677,6 +671,10 @@ static int store_network_information(GSupplicantInterface * interface,
 
        if ((ssid->security == G_SUPPLICANT_SECURITY_WEP ||
                ssid->security == G_SUPPLICANT_SECURITY_PSK ||
+#if defined TIZEN_EXT
+               ssid->security == G_SUPPLICANT_SECURITY_SAE ||
+               ssid->security == G_SUPPLICANT_SECURITY_PSK_SHA256 ||
+#endif
                ssid->security == G_SUPPLICANT_SECURITY_NONE) &&
                ssid->passphrase) {
                interface->network_info.passphrase = g_strdup(ssid->passphrase);
@@ -1429,6 +1427,14 @@ bool g_supplicant_interface_get_is_5_0_ghz_supported(GSupplicantInterface *inter
 
        return interface->is_5_0_Ghz_supported;
 }
+
+unsigned char *g_supplicant_interface_get_add_network_bssid(GSupplicantInterface *interface)
+{
+       if (!interface)
+               return NULL;
+
+       return (unsigned char *)interface->add_network_bssid;
+}
 #endif
 
 const char *g_supplicant_interface_get_driver(GSupplicantInterface *interface)
@@ -1600,6 +1606,32 @@ dbus_int16_t g_supplicant_network_get_signal(GSupplicantNetwork *network)
        return network->signal;
 }
 
+#if defined TIZEN_EXT
+void g_supplicant_network_set_signal(GSupplicantNetwork *network, int signal)
+{
+       if (!network)
+               return;
+
+       network->signal = (dbus_int16_t)signal;
+}
+
+void g_supplicant_network_set_bss_signal(GSupplicantNetwork *network,
+               int signal, int snr)
+{
+       struct g_supplicant_bss *best_bss;
+
+       if (!network)
+               return;
+
+       best_bss = network->best_bss;
+       if (!best_bss)
+               return;
+
+       best_bss->signal = (dbus_int16_t)signal;
+       best_bss->snr = (dbus_int16_t)snr;
+}
+#endif
+
 dbus_uint16_t g_supplicant_network_get_frequency(GSupplicantNetwork *network)
 {
        if (!network)
@@ -1742,12 +1774,20 @@ const char *g_supplicant_network_get_phase2(GSupplicantNetwork *network)
 
 unsigned int g_supplicant_network_get_keymgmt(GSupplicantNetwork *network)
 {
-       if (network == NULL)
+       if (!network)
                return 0;
 
        return network->keymgmt;
 }
 
+dbus_bool_t g_supplicant_network_get_privacy(GSupplicantNetwork *network)
+{
+       if (!network)
+               return FALSE;
+
+       return network->privacy;
+}
+
 const unsigned char *g_supplicant_network_get_countrycode(GSupplicantNetwork
                                                          *network)
 {
@@ -1756,6 +1796,14 @@ const unsigned char *g_supplicant_network_get_countrycode(GSupplicantNetwork
 
        return network->country_code;
 }
+
+dbus_bool_t g_supplicant_network_is_pmf_required(GSupplicantNetwork *network)
+{
+       if (!network)
+               return 0;
+
+       return network->best_bss->pmf_required;
+}
 #endif
 
 const unsigned char *g_supplicant_peer_get_widi_ies(GSupplicantPeer *peer,
@@ -1851,6 +1899,7 @@ 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)
@@ -1859,7 +1908,6 @@ dbus_bool_t g_supplicant_network_get_transition_mode(GSupplicantNetwork *network
        return network->owe_transition_mode;
 }
 
-
 const unsigned char *g_supplicant_network_get_transition_mode_bssid(GSupplicantNetwork *network)
 {
        if (network == NULL)
@@ -1894,12 +1942,11 @@ const char *g_supplicant_network_get_enc_mode(GSupplicantNetwork *network)
                return NULL;
 
        if (network->best_bss->security == G_SUPPLICANT_SECURITY_PSK ||
-#if defined TIZEN_EXT
-           network->best_bss->security == G_SUPPLICANT_SECURITY_SAE ||
-           network->best_bss->security == G_SUPPLICANT_SECURITY_OWE ||
-           network->best_bss->security == G_SUPPLICANT_SECURITY_DPP ||
-#endif /* TIZEN_EXT */
-           network->best_bss->security == G_SUPPLICANT_SECURITY_IEEE8021X) {
+                       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_PSK_SHA256 ||
+                       network->best_bss->security == G_SUPPLICANT_SECURITY_IEEE8021X) {
                unsigned int pairwise;
 
                pairwise = network->best_bss->rsn_pairwise |
@@ -1926,12 +1973,9 @@ bool g_supplicant_network_get_rsn_mode(GSupplicantNetwork *network)
        if (network == NULL || network->best_bss == NULL)
                return 0;
 
-#if defined TIZEN_EXT
-       if (network->best_bss->security == G_SUPPLICANT_SECURITY_SAE ||
-                       network->best_bss->security == G_SUPPLICANT_SECURITY_OWE ||
+       if (network->best_bss->security == G_SUPPLICANT_SECURITY_OWE ||
                        network->best_bss->security == G_SUPPLICANT_SECURITY_DPP)
                return false;
-#endif /* TIZEN_EXT */
 
        if (network->best_bss->rsn_selected) {
                const char *mode = g_supplicant_network_get_enc_mode(network);
@@ -1997,6 +2041,7 @@ static gchar *convert_bssid_to_str(unsigned char *bssid)
        return g_string_free(bssid_str, FALSE);
 }
 
+#if defined TIZEN_EXT_INS
 static void count_assoc_reject(gpointer data, gpointer user_data)
 {
        time_t assoc_reject_time = GPOINTER_TO_INT(data);
@@ -2110,8 +2155,22 @@ static int calculate_score_strength(dbus_int16_t strength)
        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;
+}
+
 static int calculate_score(bool is_last_connected, uint16_t assoc_reject_cnt,
-               dbus_int16_t strength, dbus_uint16_t frequency)
+               dbus_uint16_t frequency, dbus_int16_t strength,
+               dbus_int16_t snr, dbus_uint32_t est_throughput)
 {
        int score = 0;
 
@@ -2119,9 +2178,12 @@ static int calculate_score(bool is_last_connected, uint16_t assoc_reject_cnt,
        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);
 
        return score;
 }
+#endif
 
 static void update_bssid_list(gpointer key, gpointer value, gpointer user_data)
 {
@@ -2141,21 +2203,24 @@ static void update_bssid_list(gpointer key, gpointer value, gpointer user_data)
                        bssids->strength = 100;
 
                bssids->frequency = bss->frequency;
+               bssids->score_snr = (int)bss->snr;
 
+#if defined TIZEN_EXT_INS
                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(bssids->strength);
-#endif
+               bssids->score_strength = calculate_score_strength(bss->signal);
+               bssids->score_est_throughput = calculate_score_est_throughput(bss->est_throughput);
 
                bssids->ins_score = calculate_score(bssids->is_last_connected,
-                       bssids->assoc_reject_cnt, bssids->frequency, bss->signal);
-
+                       bssids->assoc_reject_cnt, bssids->frequency, bss->signal,
+                       bss->snr, bss->est_throughput);
+#else
+               bssids->ins_score = bss->signal;
+#endif
                bssid_data->bssid_list = g_slist_append(bssid_data->bssid_list, bssids);
        } else
                SUPPLICANT_DBG("Failed to allocate memory");
@@ -2172,6 +2237,13 @@ static gint cmp_bss(gconstpointer a, gconstpointer b)
        if (entry_a->ins_score < entry_b->ins_score)
                return 1;
 
+       if (entry_a->ins_score == entry_b->ins_score) {
+               if (entry_a->strength >= entry_b->strength)
+                       return -1;
+               else
+                       return 1;
+       }
+
        return 0;
 }
 
@@ -2180,11 +2252,16 @@ 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,
+       GSupplicantNetwork *network = (GSupplicantNetwork *) user_data;
+
+       if (!bssids || !network)
+               return;
+
+       SUPPLICANT_DBG("ssid [%-20s] bssid[" MACSTR "] total[%2d] freq[%2d] "
+                       "last_conn[%2d] assoc_reject[%2d] strength[%2d] rssi[%2d]",
+                       network->ssid, MAC2STR(bssids->bssid), bssids->ins_score,
                        bssids->score_frequency, bssids->score_last_connected_bssid,
-                       bssids->score_assoc_reject, bssids->score_strength);
+                       bssids->score_assoc_reject, bssids->score_strength, bssids->strength - 120);
 }
 #endif
 
@@ -2203,7 +2280,7 @@ void *g_supplicant_network_get_bssid_list(GSupplicantNetwork *network)
        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);
+       g_slist_foreach(bssid_data.bssid_list, print_bssid_sort, (gpointer)network);
 #endif
 
        return bssid_data.bssid_list;
@@ -2282,6 +2359,43 @@ GSupplicantNetwork *g_supplicant_interface_get_network(GSupplicantInterface *int
 
        return g_hash_table_lookup(interface->network_table, group);
 }
+
+static void copy_assoc_reject(gpointer key, gpointer value, gpointer user_data)
+{
+       struct assoc_reject_data *cloned_assoc_data;
+       struct assoc_reject_data *assoc_data = value;
+       GHashTable *cloned_assoc_reject_table = user_data;
+
+       if (assoc_data && cloned_assoc_reject_table) {
+               cloned_assoc_data = g_try_new0(struct assoc_reject_data, 1);
+               if (!cloned_assoc_data)
+                       return;
+
+               cloned_assoc_data->bssid = g_strdup(assoc_data->bssid);
+               cloned_assoc_data->reject_time_list = g_slist_copy(assoc_data->reject_time_list);
+               g_hash_table_insert(cloned_assoc_reject_table,
+                                       cloned_assoc_data->bssid, cloned_assoc_data);
+       }
+}
+
+GHashTable *g_supplicant_network_clone_assoc_reject_table(GSupplicantNetwork *network)
+{
+       GHashTable *cloned_assoc_reject_table;
+
+       if (!network)
+               return NULL;
+
+       GHashTable *assoc_reject_table = g_supplicant_network_get_assoc_reject_table(network);
+       if (!assoc_reject_table)
+               return NULL;
+
+       cloned_assoc_reject_table = g_hash_table_new_full(g_str_hash, g_str_equal,
+                                                               NULL, remove_assoc_data);
+       g_hash_table_foreach(assoc_reject_table, copy_assoc_reject, cloned_assoc_reject_table);
+
+       return cloned_assoc_reject_table;
+}
+
 #endif
 
 static void merge_network(GSupplicantNetwork *network)
@@ -2512,7 +2626,14 @@ static char *create_group(struct g_supplicant_bss *bss)
        if (mode)
                g_string_append_printf(str, "_%s", mode);
 
+#if defined TIZEN_EXT
+       if (bss->security == G_SUPPLICANT_SECURITY_PSK_SHA256)
+               security = "psk";
+       else
+               security = security2string(bss->security);
+#else
        security = security2string(bss->security);
+#endif
        if (security)
                g_string_append_printf(str, "_%s", security);
 
@@ -2522,6 +2643,12 @@ static char *create_group(struct g_supplicant_bss *bss)
 static void update_network_with_best_bss(GSupplicantNetwork *network,
                struct g_supplicant_bss *best_bss)
 {
+       /*
+        * Do not change best BSS if we are connected.
+        */
+       if (network->interface->state == G_SUPPLICANT_STATE_COMPLETED)
+               return;
+
        network->signal = best_bss->signal;
        network->frequency = best_bss->frequency;
        network->best_bss = best_bss;
@@ -2538,18 +2665,24 @@ static bool update_best_bss(GSupplicantNetwork *network,
                return true;
        }
 
+#if defined TIZEN_EXT_INS
        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->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->frequency, network->best_bss->signal,
+               network->best_bss->snr, network->best_bss->est_throughput);
+#else
+       score_new = bss->signal;
+       score_best = network->best_bss->signal;
+#endif
 
        if (score_new > score_best) {
-               SUPPLICANT_DBG("new[" MACSTR "][%u] : best[" MACSTR "][%u]",
+               SUPPLICANT_DBG("new[" MACSTR "][%d] : best[" MACSTR "][%d]",
                        MAC2STR(bss->bssid), score_new,
                        MAC2STR(network->best_bss->bssid), score_best);
 
@@ -2613,6 +2746,7 @@ static int add_or_replace_bss_to_network(struct g_supplicant_bss *bss)
 
 #if defined TIZEN_EXT
        network->owe_transition_mode = bss->owe_transition_mode;
+       network->privacy = bss->privacy;
        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);
 
@@ -2892,6 +3026,7 @@ static void bss_process_ies(DBusMessageIter *iter, void *user_data)
        unsigned char *ext_rates = NULL;
        unsigned int max_rate = 0;
        unsigned int max_ext_rate = 0;
+       unsigned int offset = 0;
        bool ht = false;
        bool vht = false;
 #endif
@@ -2909,6 +3044,8 @@ static void bss_process_ies(DBusMessageIter *iter, void *user_data)
 #if defined TIZEN_EXT
 #define VENDOR_SPECIFIC_INFO 0xDD
 #define WLAN_EID_COUNTRY 7
+#define WLAN_EID_RSN_INFO 48
+#define RSN_CAPABILITY_MFP_REQ (1 << 6)
 #endif
 
        dbus_message_iter_recurse(iter, &array);
@@ -2926,7 +3063,7 @@ static void bss_process_ies(DBusMessageIter *iter, void *user_data)
                unsigned char *vsie;
                int vsie_len = 0;
 
-               if(ie[0] == VENDOR_SPECIFIC_INFO && memcmp(ie+2, OWE_WFA_OUI, sizeof(OWE_WFA_OUI)) == 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");
 
 /*
@@ -2956,7 +3093,7 @@ static void bss_process_ies(DBusMessageIter *iter, void *user_data)
                        continue;
                }
 
-               if(ie[0] == VENDOR_SPECIFIC_INFO && memcmp(ie+2, WPS_OUI, sizeof(WPS_OUI)) != 0) {
+               if (ie[0] == VENDOR_SPECIFIC_INFO && memcmp(ie+2, WPS_OUI, sizeof(WPS_OUI)) != 0) {
 
                        if (!simplified_log)
                                SUPPLICANT_DBG("IE: match vendor specific data");
@@ -2972,7 +3109,7 @@ static void bss_process_ies(DBusMessageIter *iter, void *user_data)
                        continue;
                }
 
-               if(ie[0] == WLAN_EID_COUNTRY && ie[1] >= 2) {
+               if (ie[0] == WLAN_EID_COUNTRY && ie[1] >= 2) {
                        /* Add country code only if it is a valid alphabet */
                        if (ie[2] >= 65 && ie[2] <= 90 && ie[3] >= 65 && ie[3] <= 90) {
                                memcpy(bss->country_code, ie+2, COUNTRY_CODE_LENGTH);
@@ -3017,6 +3154,18 @@ static void bss_process_ies(DBusMessageIter *iter, void *user_data)
                        }
                        continue;
                }
+
+               if (ie[0] == WLAN_EID_RSN_INFO && ie[1] >= 20) {
+                       r_len = ie[1];
+                       offset = 10 + ie[8] * 4;
+                       offset += ie[offset] * 4 + 2;
+
+                       if (offset <= r_len + 1 &&
+                                       (ie[offset] & RSN_CAPABILITY_MFP_REQ) != 0)
+                               bss->pmf_required = TRUE;
+
+                       continue;
+               }
 #endif
                if (ie[0] != WMM_WPA1_WPS_INFO || ie[1] < WPS_INFO_MIN_LEN ||
                        memcmp(ie+2, WPS_OUI, sizeof(WPS_OUI)) != 0)
@@ -3078,7 +3227,7 @@ static void bss_compute_security(struct g_supplicant_bss *bss)
 #if defined TIZEN_EXT
        if (bss->keymgmt &
                        (G_SUPPLICANT_KEYMGMT_WPA_EAP |
-                                       G_SUPPLICANT_KEYMGMT_WPA_EAP_256))
+                               G_SUPPLICANT_KEYMGMT_WPA_EAP_256))
                bss->ieee8021x = TRUE;
        else if (bss->keymgmt & G_SUPPLICANT_KEYMGMT_WPA_FT_EAP)
                bss->ft_ieee8021x = TRUE;
@@ -3092,8 +3241,13 @@ static void bss_compute_security(struct g_supplicant_bss *bss)
 
 #if defined TIZEN_EXT
        if (bss->keymgmt &
+                       G_SUPPLICANT_KEYMGMT_WPA_PSK_256) {
+               bss->psk_sha256 = TRUE;
+       }
+
+       if (bss->keymgmt &
                        (G_SUPPLICANT_KEYMGMT_WPA_PSK |
-                                       G_SUPPLICANT_KEYMGMT_WPA_PSK_256))
+                               G_SUPPLICANT_KEYMGMT_WPA_PSK_256))
                bss->psk = TRUE;
        else if (bss->keymgmt & G_SUPPLICANT_KEYMGMT_WPA_FT_PSK)
                bss->ft_psk = TRUE;
@@ -3106,7 +3260,8 @@ static void bss_compute_security(struct g_supplicant_bss *bss)
 #endif
 
 #if defined TIZEN_EXT
-       if (bss->keymgmt & G_SUPPLICANT_KEYMGMT_SAE)
+       if (bss->keymgmt & G_SUPPLICANT_KEYMGMT_SAE |
+                       bss->keymgmt & G_SUPPLICANT_KEYMGMT_FT_SAE)
                bss->sae = TRUE;
        if (bss->keymgmt & G_SUPPLICANT_KEYMGMT_OWE)
                bss->owe = TRUE;
@@ -3117,16 +3272,18 @@ static void bss_compute_security(struct g_supplicant_bss *bss)
        if (bss->ieee8021x)
                bss->security = G_SUPPLICANT_SECURITY_IEEE8021X;
 #if defined TIZEN_EXT
+       else if (bss->ft_ieee8021x)
+               bss->security = G_SUPPLICANT_SECURITY_IEEE8021X;
        else if (bss->sae)
                bss->security = G_SUPPLICANT_SECURITY_SAE;
+       else if (bss->psk_sha256)
+               bss->security = G_SUPPLICANT_SECURITY_PSK_SHA256;
 #endif
        else if (bss->psk)
                bss->security = G_SUPPLICANT_SECURITY_PSK;
 #if defined TIZEN_EXT
        else if (bss->ft_psk)
                bss->security = G_SUPPLICANT_SECURITY_FT_PSK;
-       else if (bss->ft_ieee8021x == TRUE)
-               bss->security = G_SUPPLICANT_SECURITY_IEEE8021X;
        else if (bss->owe || bss->owe_transition_mode)
                bss->security = G_SUPPLICANT_SECURITY_OWE;
        else if (bss->dpp)
@@ -3240,6 +3397,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);
@@ -3438,6 +3606,13 @@ static void interface_current_bss(GSupplicantInterface *interface,
        GSupplicantNetwork *network;
        struct g_supplicant_bss *bss;
        const char *path;
+#if defined TIZEN_EXT
+       char bssid_buff1[WIFI_BSSID_STR_LEN] = {0,};
+       char bssid_buff2[WIFI_BSSID_STR_LEN] = {0,};
+       char *bssid_str1 = bssid_buff1;
+       char *bssid_str2 = bssid_buff2;
+       gboolean update = FALSE;
+#endif
 
        dbus_message_iter_get_basic(iter, &path);
        if (g_strcmp0(path, "/") == 0) {
@@ -3457,7 +3632,16 @@ static void interface_current_bss(GSupplicantInterface *interface,
 
        interface->current_network = network;
 #if defined TIZEN_EXT
-       SUPPLICANT_DBG("current network [%p]", interface->current_network);
+       snprintf(bssid_str1, WIFI_BSSID_STR_LEN, MACSTR, MAC2STR(bss->bssid));
+       snprintf(bssid_str2, WIFI_BSSID_STR_LEN, MACSTR, MAC2STR(network->best_bss->bssid));
+
+       SUPPLICANT_DBG("current network [%p], Passed bss %s, best bss %s",
+                       interface->current_network, bssid_str1, bssid_str2);
+
+       if (network->frequency != bss->frequency) {
+               network->frequency = bss->frequency;
+               update = TRUE;
+       }
 #endif
 
        if (bss != network->best_bss) {
@@ -3476,9 +3660,19 @@ static void interface_current_bss(GSupplicantInterface *interface,
 
                        network->signal = bss->signal;
                        callback_network_changed(network, "Signal");
+#if defined TIZEN_EXT
+                       update = FALSE;
+               } else {
+                       update = TRUE;
+#endif
                }
        }
 
+#if defined TIZEN_EXT
+       if (update)
+               callback_network_changed(network, "");
+#endif
+
        /*
         * wpa_s could notify about CurrentBSS in any state once
         * it got associated. It is not sure such notification will
@@ -4243,8 +4437,10 @@ static void signal_bss_changed(const char *path, DBusMessageIter *iter)
        supplicant_dbus_property_foreach(iter, bss_property, bss);
 
 #if defined TIZEN_EXT
-       network->frequency = bss->frequency;
-       network->phy_mode = bss->phy_mode;
+       if (network->interface->state != G_SUPPLICANT_STATE_COMPLETED) {
+               network->frequency = bss->frequency;
+               network->phy_mode = bss->phy_mode;
+       }
 #endif
        old_security = network->security;
        bss_compute_security(bss);
@@ -5361,7 +5557,7 @@ static void country_result(const char *error,
                regdom->callback(result, regdom->alpha2,
                                        (void *) regdom->user_data);
 
-       dbus_free(regdom);
+       g_free(regdom);
 }
 
 static void country_params(DBusMessageIter *iter, void *user_data)
@@ -5625,7 +5821,7 @@ static void interface_create_result(const char *error,
        SUPPLICANT_DBG("");
 
        if (error) {
-               g_message("error %s", error);
+               g_warning("error %s", error);
                err = -EIO;
                goto done;
        }
@@ -6390,6 +6586,7 @@ static void interface_signalpoll_result(const char *error,
        int err = 0;
        dbus_int32_t maxspeed = 0;
        dbus_int32_t strength = 0;
+       dbus_int32_t snr = 0;
        DBusMessageIter sub_iter, dict;
 
        if (error) {
@@ -6398,7 +6595,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);
 
@@ -6421,6 +6623,10 @@ static void interface_signalpoll_result(const char *error,
                                dbus_message_iter_get_basic(&value, &strength);
                                SUPPLICANT_DBG("Strength = %d", strength);
                                break;
+                       } else if (g_strcmp0(key, "SNR") == 0) {
+                               dbus_message_iter_get_basic(&value, &snr);
+                               SUPPLICANT_DBG("SNR = %d", snr);
+                               break;
                        }
                }
                dbus_message_iter_next(&dict);
@@ -6428,7 +6634,7 @@ static void interface_signalpoll_result(const char *error,
 
 out:
        if(data->callback)
-               data->callback(err, maxspeed, strength, data->user_data);
+               data->callback(err, maxspeed, strength, snr, data->user_data);
 
        g_free(data->path);
        dbus_free(data);
@@ -6767,10 +6973,8 @@ static void add_network_security_tls(DBusMessageIter *dict,
        if (!ssid->private_key_path)
                return;
 
-#if !defined TIZEN_EXT
        if (!ssid->private_key_passphrase)
                return;
-#endif
 
        if (ssid->ca_cert_path)
                supplicant_dbus_dict_append_basic(dict, "ca_cert",
@@ -6779,11 +6983,9 @@ static void add_network_security_tls(DBusMessageIter *dict,
        supplicant_dbus_dict_append_basic(dict, "private_key",
                                                DBUS_TYPE_STRING,
                                                &ssid->private_key_path);
-#if !defined TIZEN_EXT
        supplicant_dbus_dict_append_basic(dict, "private_key_passwd",
                                                DBUS_TYPE_STRING,
                                                &ssid->private_key_passphrase);
-#endif
        supplicant_dbus_dict_append_basic(dict, "client_cert",
                                                DBUS_TYPE_STRING,
                                                &ssid->client_cert_path);
@@ -7082,6 +7284,7 @@ static void add_network_ieee80211w(DBusMessageIter *dict, GSupplicantSSID *ssid)
 {
        if (ssid->security != G_SUPPLICANT_SECURITY_SAE
                        && ssid->security != G_SUPPLICANT_SECURITY_OWE
+                       && ssid->security != G_SUPPLICANT_SECURITY_PSK_SHA256
                        && ssid->security != G_SUPPLICANT_SECURITY_DPP)
                return;
 
@@ -7171,7 +7374,14 @@ static void add_network_security(DBusMessageIter *dict, GSupplicantSSID *ssid)
                add_network_security_ciphers(dict, ssid);
                break;
        case G_SUPPLICANT_SECURITY_PSK:
+#if defined TIZEN_EXT
+               if (ssid->keymgmt & G_SUPPLICANT_KEYMGMT_WPA_FT_PSK)
+                       key_mgmt = "FT-PSK WPA-PSK";
+               else
+                       key_mgmt = "WPA-PSK";
+#else
                key_mgmt = "WPA-PSK";
+#endif
                add_network_security_psk(dict, ssid);
                add_network_security_ciphers(dict, ssid);
                add_network_security_proto(dict, ssid);
@@ -7183,6 +7393,15 @@ static void add_network_security(DBusMessageIter *dict, GSupplicantSSID *ssid)
                add_network_security_proto(dict, ssid);
                break;
 #if defined TIZEN_EXT
+       case G_SUPPLICANT_SECURITY_PSK_SHA256:
+               if (ssid->keymgmt & G_SUPPLICANT_KEYMGMT_WPA_PSK)
+                       key_mgmt = "WPA-PSK-SHA256 WPA-PSK";
+               else
+                       key_mgmt = "WPA-PSK-SHA256";
+               add_network_security_psk(dict, ssid);
+               add_network_security_ciphers(dict, ssid);
+               add_network_security_proto(dict, ssid);
+               break;
        case G_SUPPLICANT_SECURITY_FT_PSK:
                key_mgmt = "FT-PSK";
                add_network_security_psk(dict, ssid);
@@ -7196,8 +7415,13 @@ static void add_network_security(DBusMessageIter *dict, GSupplicantSSID *ssid)
                add_network_security_proto(dict, ssid);
                break;
        case G_SUPPLICANT_SECURITY_SAE:
-               if (ssid->keymgmt & G_SUPPLICANT_KEYMGMT_WPA_PSK)
-                       key_mgmt = "SAE WPA-PSK"; // WFA (WPA3 & WPA2 Mixed -> WPA2 only)
+               if (ssid->keymgmt & G_SUPPLICANT_KEYMGMT_FT_SAE) {
+                       if (ssid->keymgmt & G_SUPPLICANT_KEYMGMT_SAE)
+                               key_mgmt = "FT-SAE SAE";
+                       else
+                               key_mgmt = "FT-SAE";
+               } else if (ssid->keymgmt & G_SUPPLICANT_KEYMGMT_WPA_PSK)
+                       key_mgmt = "SAE WPA-PSK";
                else
                        key_mgmt = "SAE";
                add_network_security_psk(dict, ssid);
@@ -7458,6 +7682,12 @@ static void decryption_request_reply(DBusPendingCall *call,
                goto done;
        }
 
+       if (!g_str_has_prefix(data->interface->path, "/")) {
+               SUPPLICANT_DBG("Invalid path %s", data->interface->path);
+               ret = -EINVAL;
+               goto done;
+       }
+
        if (dbus_message_iter_init(reply, &args) == FALSE) {
                SUPPLICANT_DBG("dbus_message_iter_init() failed");
                ret = -EINVAL;
@@ -7795,7 +8025,7 @@ int g_supplicant_interface_connect(GSupplicantInterface *interface,
                                        interface_add_network_result, data,
                                        interface);
                }
-        }
+       }
 
        if (ret < 0) {
                g_free(data->path);
@@ -8000,6 +8230,49 @@ int g_supplicant_interface_disconnect(GSupplicantInterface *interface,
        return ret;
 }
 
+#if defined TIZEN_EXT
+void g_supplicant_interface_remove_network(GSupplicantInterface *interface,
+                               GSupplicantSSID *ssid)
+{
+       struct interface_data *data;
+       int ret;
+
+       SUPPLICANT_DBG("");
+
+       if (!interface)
+               return;
+
+       if (interface->network_path == NULL)
+               return;
+
+       if (!interface->network_info.ssid)
+               return;
+
+       if (memcmp(interface->network_info.ssid, ssid->ssid, ssid->ssid_len))
+               return;
+
+       if (interface->network_info.security != ssid->security)
+               return;
+
+       data = dbus_malloc0(sizeof(*data));
+       if (!data)
+               return;
+
+       data->interface = interface;
+       data->path = g_strdup(interface->path);
+
+       ret = supplicant_dbus_method_call(interface->path,
+                       SUPPLICANT_INTERFACE ".Interface", "RemoveNetwork",
+                       network_remove_params, network_remove_result, data,
+                       interface);
+
+       if (ret < 0) {
+               g_free(data->path);
+               dbus_free(data);
+       }
+}
+#endif
+
 static void interface_p2p_find_result(const char *error,
                                        DBusMessageIter *iter, void *user_data)
 {
@@ -8499,7 +8772,7 @@ static void invoke_introspect_method(void)
        dbus_message_unref(message);
 }
 
-#if defined TIZEN_EXT
+#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,
@@ -8525,7 +8798,7 @@ void g_supplicant_set_ins_settings(GSupplicantINSPreferredFreq preferred_freq_bs
        SUPPLICANT_DBG("signal_level3_5ghz [%d]", signal_level3_5ghz);
        SUPPLICANT_DBG("signal_level3_24ghz [%d]", signal_level3_24ghz);
 }
-#endif
+#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)