Fix unintentional reconnection on disconnect request
[platform/upstream/connman.git] / gsupplicant / supplicant.c
index e457fef..723f2cf 100755 (executable)
@@ -122,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
@@ -174,7 +175,7 @@ static struct strvalmap mode_capa_map[] = {
        { }
 };
 
-#if defined TIZEN_EXT && defined TIZEN_EXT_INS
+#if defined TIZEN_EXT
 struct _GSupplicantINSSettings {
        GSupplicantINSPreferredFreq preferred_freq_bssid;
        unsigned int preferred_freq_bssid_score;
@@ -188,13 +189,11 @@ 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
 };
-#endif
+#endif /* defined TIZEN_EXT */
 
 static GHashTable *interface_table;
 static GHashTable *bss_mapping;
@@ -264,6 +263,7 @@ struct _GSupplicantInterface {
        struct added_network_information network_info;
 #if defined TIZEN_EXT
        dbus_bool_t is_5_0_Ghz_supported;
+       dbus_bool_t is_6_0_Ghz_supported;
        int disconnect_reason;
 #endif
 #if defined TIZEN_EXT
@@ -307,6 +307,7 @@ struct g_supplicant_bss {
        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
@@ -538,6 +539,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:
@@ -669,6 +672,7 @@ static int store_network_information(GSupplicantInterface * interface,
                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) {
@@ -1307,6 +1311,11 @@ static void interface_capability(const char *key, DBusMessageIter *iter,
 
                dbus_message_iter_get_basic(iter, &is_5_0_Ghz_supported);
                interface->is_5_0_Ghz_supported = is_5_0_Ghz_supported;
+       } else if (g_strcmp0(key, "Is6GhzSupported") == 0) {
+               dbus_bool_t is_6_0_Ghz_supported;
+
+               dbus_message_iter_get_basic(iter, &is_6_0_Ghz_supported);
+               interface->is_6_0_Ghz_supported = is_6_0_Ghz_supported;
 #endif
        } else
                SUPPLICANT_DBG("key %s type %c",
@@ -1418,11 +1427,19 @@ const char *g_supplicant_interface_get_ifname(GSupplicantInterface *interface)
 bool g_supplicant_interface_get_is_5_0_ghz_supported(GSupplicantInterface *interface)
 {
        if (!interface)
-               return NULL;
+               return false;
 
        return interface->is_5_0_Ghz_supported;
 }
 
+bool g_supplicant_interface_get_is_6_0_ghz_supported(GSupplicantInterface *interface)
+{
+       if (!interface)
+               return false;
+
+       return interface->is_6_0_Ghz_supported;
+}
+
 unsigned char *g_supplicant_interface_get_add_network_bssid(GSupplicantInterface *interface)
 {
        if (!interface)
@@ -1568,7 +1585,7 @@ const char *g_supplicant_network_get_path(GSupplicantNetwork *network)
 const char *g_supplicant_network_get_mode(GSupplicantNetwork *network)
 {
        if (!network)
-               return G_SUPPLICANT_MODE_UNKNOWN;
+               return NULL;
 
        return mode2string(network->mode);
 }
@@ -1576,7 +1593,7 @@ const char *g_supplicant_network_get_mode(GSupplicantNetwork *network)
 const char *g_supplicant_network_get_security(GSupplicantNetwork *network)
 {
        if (!network)
-               return G_SUPPLICANT_SECURITY_UNKNOWN;
+               return NULL;
 
        return security2string(network->security);
 }
@@ -1794,8 +1811,8 @@ const unsigned char *g_supplicant_network_get_countrycode(GSupplicantNetwork
 
 dbus_bool_t g_supplicant_network_is_pmf_required(GSupplicantNetwork *network)
 {
-       if (!network)
-               return 0;
+       if (!network || !network->best_bss)
+               return FALSE;
 
        return network->best_bss->pmf_required;
 }
@@ -1940,6 +1957,7 @@ const char *g_supplicant_network_get_enc_mode(GSupplicantNetwork *network)
                        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;
 
@@ -2035,7 +2053,6 @@ 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);
@@ -2177,7 +2194,6 @@ static int calculate_score(bool is_last_connected, uint16_t assoc_reject_cnt,
 
        return score;
 }
-#endif
 
 static void update_bssid_list(gpointer key, gpointer value, gpointer user_data)
 {
@@ -2197,24 +2213,26 @@ static void update_bssid_list(gpointer key, gpointer value, gpointer user_data)
                        bssids->strength = 100;
 
                bssids->frequency = bss->frequency;
+               bssids->est_throughput = bss->est_throughput;
                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 (TIZEN_INS_ENABLED) {
+                       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);
 
-               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_est_throughput = calculate_score_est_throughput(bss->est_throughput);
+                       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_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,
+                                       bss->snr, bss->est_throughput);
+               } else {
+                       bssids->ins_score = bss->signal;
+               }
 
-               bssids->ins_score = calculate_score(bssids->is_last_connected,
-                       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");
@@ -2231,21 +2249,31 @@ 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;
 }
 
-#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,
+       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
 
 void *g_supplicant_network_get_bssid_list(GSupplicantNetwork *network)
 {
@@ -2261,9 +2289,8 @@ 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);
-#endif
+       if (TIZEN_INS_ENABLED && !simplified_log)
+               g_slist_foreach(bssid_data.bssid_list, print_bssid_sort, (gpointer)network);
 
        return bssid_data.bssid_list;
 }
@@ -2333,15 +2360,6 @@ GHashTable *g_supplicant_network_get_assoc_reject_table(GSupplicantNetwork *netw
        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);
-}
-
 static void copy_assoc_reject(gpointer key, gpointer value, gpointer user_data)
 {
        struct assoc_reject_data *cloned_assoc_data;
@@ -2378,7 +2396,15 @@ GHashTable *g_supplicant_network_clone_assoc_reject_table(GSupplicantNetwork *ne
        return cloned_assoc_reject_table;
 }
 
-#endif
+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 /* defined TIZEN_EXT */
 
 static void merge_network(GSupplicantNetwork *network)
 {
@@ -2431,8 +2457,16 @@ static void merge_network(GSupplicantNetwork *network)
                g_string_append_printf(str, "_mesh");
 #endif
 
+#if defined TIZEN_EXT
        if (g_strcmp0(key_mgmt, "WPA-PSK") == 0)
                g_string_append_printf(str, "_psk");
+       else if (g_strcmp0(key_mgmt, "SAE") == 0)
+               g_string_append_printf(str, "_sae");
+#else
+       if ((g_strcmp0(key_mgmt, "WPA-PSK") == 0) ||
+           (g_strcmp0(key_mgmt, "SAE") == 0))
+               g_string_append_printf(str, "_psk");
+#endif
 #if defined TIZEN_EXT
        else if (g_strcmp0(key_mgmt, "WPA-EAP") == 0)
                g_string_append_printf(str, "_ieee8021x");
@@ -2608,7 +2642,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);
 
@@ -2621,11 +2662,12 @@ static void update_network_with_best_bss(GSupplicantNetwork *network,
        /*
         * Do not change best BSS if we are connected.
         */
-       if (network->interface->state == G_SUPPLICANT_STATE_COMPLETED)
+       if (network->interface->state == G_SUPPLICANT_STATE_COMPLETED && network->best_bss)
                return;
 
        network->signal = best_bss->signal;
        network->frequency = best_bss->frequency;
+       network->phy_mode = best_bss->phy_mode;
        network->best_bss = best_bss;
 }
 
@@ -2640,21 +2682,21 @@ 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->snr, bss->est_throughput);
+       if (TIZEN_INS_ENABLED) {
+               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);
-#else
-       score_new = bss->signal;
-       score_best = network->best_bss->signal;
-#endif
+               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);
+       } else {
+               score_new = bss->signal;
+               score_best = network->best_bss->signal;
+       }
 
        if (score_new > score_best) {
                SUPPLICANT_DBG("new[" MACSTR "][%d] : best[" MACSTR "][%d]",
@@ -2708,6 +2750,7 @@ static int add_or_replace_bss_to_network(struct g_supplicant_bss *bss)
        network->name = create_name(bss->ssid, bss->ssid_len);
        network->mode = bss->mode;
        network->security = bss->security;
+       network->keymgmt = bss->keymgmt;
        network->ssid_len = bss->ssid_len;
        memcpy(network->ssid, bss->ssid, bss->ssid_len);
        network->signal = bss->signal;
@@ -3197,12 +3240,13 @@ static void bss_compute_security(struct g_supplicant_bss *bss)
 #if defined TIZEN_EXT
        bss->ft_ieee8021x = FALSE;
        bss->ft_psk = FALSE;
+       GSupplicantInterface *interface = bss->interface;
 #endif
 
 #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;
@@ -3216,8 +3260,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;
@@ -3230,7 +3279,9 @@ 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 |
+                               G_SUPPLICANT_KEYMGMT_FT_SAE))
                bss->sae = TRUE;
        if (bss->keymgmt & G_SUPPLICANT_KEYMGMT_OWE)
                bss->owe = TRUE;
@@ -3243,8 +3294,15 @@ static void bss_compute_security(struct g_supplicant_bss *bss)
 #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->sae) {
+               if (!bss->psk)
+                       bss->security = G_SUPPLICANT_SECURITY_SAE;
+               else if (interface->keymgmt_capa & G_SUPPLICANT_KEYMGMT_SAE)
+                       bss->security = G_SUPPLICANT_SECURITY_SAE;
+               else
+                       bss->security = G_SUPPLICANT_SECURITY_PSK;
+       } else if (bss->psk_sha256)
+               bss->security = G_SUPPLICANT_SECURITY_PSK_SHA256;
 #endif
        else if (bss->psk)
                bss->security = G_SUPPLICANT_SECURITY_PSK;
@@ -3489,6 +3547,8 @@ static void update_signal(gpointer key, gpointer value,
        if (!network->best_bss || (network->best_bss == bss)) {
                if (bss->signal > network->signal) {
                        network->signal = bss->signal;
+                       network->frequency = bss->frequency;
+                       network->phy_mode = bss->phy_mode;
                        network->best_bss = bss;
                }
                return;
@@ -3565,7 +3625,7 @@ static void remove_timer_for_last_connected(GSupplicantInterface *interface)
                }
        }
 }
-#endif
+#endif /* defined TIZEN_EXT */
 
 static void interface_current_bss(GSupplicantInterface *interface,
                                                DBusMessageIter *iter)
@@ -3574,10 +3634,10 @@ static void interface_current_bss(GSupplicantInterface *interface,
        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;
+       char curr_bssid_buff[WIFI_BSSID_STR_LEN] = {0,};
+       char best_bssid_buff[WIFI_BSSID_STR_LEN] = {0,};
+       char *curr_bssid_str = curr_bssid_buff;
+       char *best_bssid_str = best_bssid_buff;
        gboolean update = FALSE;
 #endif
 
@@ -3599,14 +3659,15 @@ static void interface_current_bss(GSupplicantInterface *interface,
 
        interface->current_network = network;
 #if defined TIZEN_EXT
-       snprintf(bssid_str1, WIFI_BSSID_STR_LEN, MACSTR, MAC2STR(bss->bssid));
-       snprintf(bssid_str2, WIFI_BSSID_STR_LEN, MACSTR, MAC2STR(network->best_bss->bssid));
+       snprintf(curr_bssid_str, WIFI_BSSID_STR_LEN, MACSTR, MAC2STR(bss->bssid));
+       snprintf(best_bssid_str, 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);
+                       interface->current_network, curr_bssid_str, best_bssid_str);
 
        if (network->frequency != bss->frequency) {
                network->frequency = bss->frequency;
+               network->phy_mode = bss->phy_mode;
                update = TRUE;
        }
 #endif
@@ -3662,7 +3723,8 @@ static void interface_current_bss(GSupplicantInterface *interface,
        case G_SUPPLICANT_STATE_COMPLETED:
                callback_network_associated(network);
 #if defined TIZEN_EXT
-               add_timer_for_last_connected(interface);
+               if (TIZEN_INS_ENABLED)
+                       add_timer_for_last_connected(interface);
 #endif
                break;
        }
@@ -3821,15 +3883,17 @@ static void interface_property(const char *key, DBusMessageIter *iter,
                                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;
+               if (TIZEN_INS_ENABLED) {
+                       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) {
@@ -4298,10 +4362,20 @@ 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)
+gpointer copy_vsie_list(gconstpointer src, gpointer data)
 {
-       return g_strdup(src);
+       unsigned char *str = (unsigned char *)src;
+       unsigned char *vsie;
+       vsie = g_try_malloc0(str[1]+2);
+
+       if (vsie)
+               memcpy(vsie, str, str[1]+2);
+       else
+               SUPPLICANT_DBG("Failed to allocate memory");
+
+       return vsie;
 }
 #endif
 
@@ -4404,7 +4478,8 @@ static void signal_bss_changed(const char *path, DBusMessageIter *iter)
        supplicant_dbus_property_foreach(iter, bss_property, bss);
 
 #if defined TIZEN_EXT
-       if (network->interface->state != G_SUPPLICANT_STATE_COMPLETED) {
+       if (network->interface->state != G_SUPPLICANT_STATE_COMPLETED &&
+                       bss == network->best_bss) {
                network->frequency = bss->frequency;
                network->phy_mode = bss->phy_mode;
        }
@@ -6554,6 +6629,7 @@ static void interface_signalpoll_result(const char *error,
        dbus_int32_t maxspeed = 0;
        dbus_int32_t strength = 0;
        dbus_int32_t snr = 0;
+       dbus_uint32_t est_throughput = 0;
        DBusMessageIter sub_iter, dict;
 
        if (error) {
@@ -6585,23 +6661,27 @@ static void interface_signalpoll_result(const char *error,
                        if (g_strcmp0(key, "linkspeed") == 0) {
                                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;
                        } else if (g_strcmp0(key, "SNR") == 0) {
                                dbus_message_iter_get_basic(&value, &snr);
                                SUPPLICANT_DBG("SNR = %d", snr);
-                               break;
                        }
+                       break;
+               case DBUS_TYPE_UINT32:
+                       if (g_strcmp0(key, "est_throughput") == 0) {
+                               dbus_message_iter_get_basic(&value, &est_throughput);
+                               SUPPLICANT_DBG("est_throughput = %u", est_throughput);
+                       }
+                       break;
                }
                dbus_message_iter_next(&dict);
        }
 
 out:
        if(data->callback)
-               data->callback(err, maxspeed, strength, snr, data->user_data);
+               data->callback(err, maxspeed, strength, snr, data->user_data, est_throughput);
 
        g_free(data->path);
        dbus_free(data);
@@ -6694,10 +6774,14 @@ 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);
+       if (data->ssid->is_passphrase_alloc)
+               g_free((char *)data->ssid->passphrase);
+       if (data->ssid->is_connector_alloc)
+               g_free((char *)data->ssid->connector);
+       if (data->ssid->is_c_sign_key_alloc)
+               g_free((char *)data->ssid->c_sign_key);
+       if (data->ssid->is_net_access_key_alloc)
+               g_free((char *)data->ssid->net_access_key);
 #endif
        g_free(data->ssid);
        dbus_free(data);
@@ -6786,10 +6870,14 @@ error:
        g_free(data->path);
 #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);
+       if (data->ssid->is_passphrase_alloc)
+               g_free((char *)data->ssid->passphrase);
+       if (data->ssid->is_connector_alloc)
+               g_free((char *)data->ssid->connector);
+       if (data->ssid->is_c_sign_key_alloc)
+               g_free((char *)data->ssid->c_sign_key);
+       if (data->ssid->is_net_access_key_alloc)
+               g_free((char *)data->ssid->net_access_key);
 #endif
        g_free(data->ssid);
        g_free(data);
@@ -7247,17 +7335,6 @@ static void add_network_security_proto(DBusMessageIter *dict,
 }
 
 #if defined TIZEN_EXT
-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_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) {
@@ -7323,8 +7400,16 @@ static void add_network_security_net_access_key(DBusMessageIter *dict, GSupplica
 
 #endif
 
+static void add_network_ieee80211w(DBusMessageIter *dict, GSupplicantSSID *ssid,
+                                  GSupplicantMfpOptions ieee80211w)
+{
+       supplicant_dbus_dict_append_basic(dict, "ieee80211w", DBUS_TYPE_UINT32,
+                                         &ieee80211w);
+}
+
 static void add_network_security(DBusMessageIter *dict, GSupplicantSSID *ssid)
 {
+       GSupplicantMfpOptions ieee80211w;
        char *key_mgmt;
 
        switch (ssid->security) {
@@ -7340,7 +7425,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);
@@ -7352,6 +7444,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);
@@ -7365,11 +7466,24 @@ 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)
-               else
-                       key_mgmt = "SAE";
+               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";
+                       ieee80211w = G_SUPPLICANT_MFP_OPTIONAL;
+                       } else {
+                               key_mgmt = "SAE";
+                               ieee80211w = G_SUPPLICANT_MFP_REQUIRED;
+                       }
+                       add_network_ieee80211w(dict, ssid, ieee80211w);
+               }
                add_network_security_psk(dict, ssid);
+               add_network_security_ciphers(dict, ssid);
+               add_network_security_proto(dict, ssid);
                break;
        case G_SUPPLICANT_SECURITY_OWE:
                key_mgmt = "OWE";
@@ -7442,10 +7556,6 @@ static void interface_add_network_params(DBusMessageIter *iter, void *user_data)
 
        add_network_security(&dict, ssid);
 
-#if defined TIZEN_EXT
-       add_network_ieee80211w(&dict, ssid);
-#endif
-
        supplicant_dbus_dict_append_fixed_array(&dict, "ssid",
                                        DBUS_TYPE_BYTE, &ssid->ssid,
                                                ssid->ssid_len);
@@ -7600,6 +7710,7 @@ static void crypt_method_call_cancel(void)
        }
 
        g_free(decrypt_request_data.data->path);
+       g_free(decrypt_request_data.data->ssid->ssid);
        g_free(decrypt_request_data.data->ssid);
        dbus_free(decrypt_request_data.data);
        decrypt_request_data.data = NULL;
@@ -7617,6 +7728,11 @@ static void decryption_request_reply(DBusPendingCall *call,
 
        SUPPLICANT_DBG("");
 
+       if (!decrypt_request_data.data) {
+               SUPPLICANT_DBG("decryption request is canceled");
+               return;
+       }
+
        reply = dbus_pending_call_steal_reply(call);
 
        dbus_error_init(&error);
@@ -7627,6 +7743,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;
@@ -7635,6 +7757,7 @@ static void decryption_request_reply(DBusPendingCall *call,
 
        dbus_message_iter_get_basic(&args, &out_data);
        data->ssid->passphrase = g_strdup((const gchar *)out_data);
+       data->ssid->is_passphrase_alloc = true;
 
        ret = supplicant_dbus_method_call(data->interface->path,
                SUPPLICANT_INTERFACE ".Interface", "AddNetwork",
@@ -7648,10 +7771,14 @@ 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);
+               if (data->ssid->is_passphrase_alloc)
+                       g_free((char *)data->ssid->passphrase);
+               if (data->ssid->is_connector_alloc)
+                       g_free((char *)data->ssid->connector);
+               if (data->ssid->is_c_sign_key_alloc)
+                       g_free((char *)data->ssid->c_sign_key);
+               if (data->ssid->is_net_access_key_alloc)
+                       g_free((char *)data->ssid->net_access_key);
                g_free(data->ssid);
                dbus_free(data);
        }
@@ -7757,14 +7884,17 @@ static void decrypt_conf_obj_reply(DBusPendingCall *call,
                        if (g_strcmp0(key, "connector") == 0) {
                                dbus_message_iter_get_basic(&value, &out_data);
                                data->ssid->connector = g_strdup((const gchar *)out_data);
+                               data->ssid->is_connector_alloc = true;
                                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);
+                               data->ssid->is_c_sign_key_alloc = true;
                                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);
+                               data->ssid->is_net_access_key_alloc = true;
                                SUPPLICANT_DBG("net_access_key %s", data->ssid->net_access_key);
                        }
                }
@@ -7783,9 +7913,12 @@ done:
                callback_assoc_failed(decrypt_request_data.data->user_data);
                g_free(data->path);
                g_free(data->ssid->ssid);
-               g_free((char *)data->ssid->connector);
-               g_free((char *)data->ssid->c_sign_key);
-               g_free((char *)data->ssid->net_access_key);
+               if (data->ssid->is_connector_alloc)
+                       g_free((char *)data->ssid->connector);
+               if (data->ssid->is_c_sign_key_alloc)
+                       g_free((char *)data->ssid->c_sign_key);
+               if (data->ssid->is_net_access_key_alloc)
+                       g_free((char *)data->ssid->net_access_key);
                g_free(data->ssid);
                dbus_free(data);
        }
@@ -8122,9 +8255,15 @@ static void interface_disconnect_result(const char *error,
        }
 }
 
+#if defined TIZEN_EXT
+int g_supplicant_interface_disconnect(GSupplicantInterface *interface,
+                                       GSupplicantInterfaceCallback callback,
+                                       void *user_data, void *connman_network)
+#else
 int g_supplicant_interface_disconnect(GSupplicantInterface *interface,
                                        GSupplicantInterfaceCallback callback,
                                                        void *user_data)
+#endif
 {
        struct interface_data *data;
        int ret;
@@ -8139,7 +8278,7 @@ int g_supplicant_interface_disconnect(GSupplicantInterface *interface,
 #if defined TIZEN_EXT
        if (decrypt_request_data.pending_call &&
                        decrypt_request_data.data &&
-                       decrypt_request_data.data->user_data == user_data) {
+                       decrypt_request_data.data->user_data == connman_network) {
 
                callback_assoc_failed(decrypt_request_data.data->user_data);
                crypt_method_call_cancel();
@@ -8169,6 +8308,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)
 {
@@ -8668,7 +8850,7 @@ static void invoke_introspect_method(void)
        dbus_message_unref(message);
 }
 
-#if defined TIZEN_EXT && defined TIZEN_EXT_INS
+#if defined TIZEN_EXT
 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,
@@ -8694,7 +8876,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 /* defined TIZEN_EXT && defined TIZEN_EXT_INS */
+#endif /* defined TIZEN_EXT */
 
 #if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET
 void g_supplicant_register_eap_callback(g_supplicant_eap_callback cb)