Improve support of Multiple same SSIDs including band steering. 85/206585/3 accepted/tizen/unified/20190611.110358 submit/tizen/20190611.082034
authorJaehyun Kim <jeik01.kim@samsung.com>
Tue, 21 May 2019 13:08:20 +0000 (22:08 +0900)
committerJaehyun Kim <jeik01.kim@samsung.com>
Tue, 11 Jun 2019 07:27:31 +0000 (07:27 +0000)
1. Supports up to 8 BSSIDs per each SSID
2. Attempt to connect only once per each BSSID
3. Sorted by signal strength and try to connect in sorted order
4. Sets the correct frequency for each bssid.

Change-Id: I668fff29f2df99b2e5f637a39b5c70da84f8ee1c
Signed-off-by: Jaehyun Kim <jeik01.kim@samsung.com>
gsupplicant/supplicant.c
include/network.h
plugins/wifi.c
src/network.c

index 1c0e64198b41aa51e71a2866c1fb12723d7a3dba..a017e732b2c876a282439f1b308097fe3583e668 100644 (file)
@@ -1743,6 +1743,20 @@ static void update_bssid_list(gpointer key, gpointer value, gpointer user_data)
                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->strength > entry_b->strength)
+               return -1;
+
+       if (entry_a->strength < entry_b->strength)
+               return 1;
+
+       return 0;
+}
+
 void *g_supplicant_network_get_bssid_list(GSupplicantNetwork *network)
 {
        GSList *bssid_list = NULL;
@@ -1751,6 +1765,7 @@ void *g_supplicant_network_get_bssid_list(GSupplicantNetwork *network)
                return NULL;
 
        g_hash_table_foreach(network->bss_table, update_bssid_list, &bssid_list);
+       bssid_list = g_slist_sort(bssid_list, cmp_bss);
 
        return bssid_list;
 }
index c4c73051a011a760b92cbab591059022c56c7f7e..dc9e6e9cf23c50b91fb318f5d43db6fa76801c2f 100755 (executable)
@@ -212,8 +212,6 @@ ieee80211_modes_e connman_network_get_phy_mode(struct connman_network *network);
 int connman_network_set_connection_mode(struct connman_network *network,
                                connection_mode_e mode);
 connection_mode_e connman_network_get_connection_mode(struct connman_network *network);
-int connman_network_set_last_bssid(struct connman_network *network, const char *bssid);
-char *connman_network_get_last_bssid(struct connman_network *network);
 #endif
 
 int connman_network_set_name(struct connman_network *network,
index f176653463519c18f6e3d6fcd613a67e73ab03a3..54380cc927bc2b1318f2aeefb1255b3208bd25e2 100644 (file)
 #define P2P_LISTEN_INTERVAL 2000
 
 #define ASSOC_STATUS_NO_CLIENT 17
+#if defined TIZEN_EXT
+#define LOAD_SHAPING_MAX_RETRIES 7
+#else
 #define LOAD_SHAPING_MAX_RETRIES 3
+#endif
 
 #if defined TIZEN_EXT
 #define WIFI_EAP_FAST_PAC_FILE         "/var/lib/wifi/wifi.pac"        /* path of Pac file for EAP-FAST */
@@ -179,6 +183,7 @@ struct wifi_data {
 static gboolean wifi_first_scan = false;
 static gboolean found_with_first_scan = false;
 static gboolean is_wifi_notifier_registered = false;
+static GHashTable *failed_bssids = NULL;
 #endif
 
 
@@ -3261,8 +3266,29 @@ static void ssid_init(GSupplicantSSID *ssid, struct connman_network *network)
        ssid->pin_wps = connman_network_get_string(network, "WiFi.PinWPS");
 
 #if defined TIZEN_EXT
+       if (set_connman_bssid(CHECK_BSSID, NULL) == 6) {
+               ssid->bssid_for_connect_len = 6;
+               set_connman_bssid(GET_BSSID, (char *)ssid->bssid_for_connect);
+               DBG("BSSID : %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 {
+               ssid->freq = connman_network_get_frequency(network);
+       }
+
        GSList *bssid_list = (GSList *)connman_network_get_bssid_list(network);
        if (bssid_list && g_slist_length(bssid_list) > 1) {
+
+               /* If there are more than one bssid,
+                * the user-specified bssid is tried only once at the beginning.
+                * After that, the bssids in the list are tried in order.
+                */
+               if (set_connman_bssid(CHECK_BSSID, NULL) == 6) {
+                       set_connman_bssid(RESET_BSSID, NULL);
+                       goto done;
+               }
+
                GSList *list;
                char buff[MAC_ADDRESS_LENGTH];
                for (list = bssid_list; list; list = list->next) {
@@ -3273,38 +3299,35 @@ static void ssid_init(GSupplicantSSID *ssid, struct connman_network *network)
                                        bssids->bssid[3], bssids->bssid[4], bssids->bssid[5]);
                        buff[MAC_ADDRESS_LENGTH - 1] = '\0';
 
-                       char *last_bssid = connman_network_get_last_bssid(network);
+                       gchar *curr_bssids = g_strdup((const gchar *)buff);
 
-                       if (strcmp(last_bssid, buff) == 0) {
-                               DBG("last_bssid match, try next bssid");
+                       if (g_hash_table_contains(failed_bssids, curr_bssids)) {
+                               DBG("bssid match, try next bssid");
+                               g_free(curr_bssids);
                                continue;
                        } else {
-                               connman_network_set_last_bssid(network, buff);
+                               g_hash_table_add(failed_bssids, curr_bssids);
 
                                ssid->bssid = &(bssids->bssid[0]);
+                               ssid->freq = (unsigned int)bssids->frequency;
                                break;
                        }
                }
+
+               if (!list) {
+                       ssid->bssid = connman_network_get_bssid(network);
+                       g_hash_table_remove_all(failed_bssids);
+               }
        } else
                ssid->bssid = connman_network_get_bssid(network);
 
+done:
        ssid->eap_keymgmt = network_eap_keymgmt(
                        connman_network_get_string(network, "WiFi.KeymgmtType"));
        ssid->phase1 = connman_network_get_string(network, "WiFi.Phase1");
 
        if(g_strcmp0(ssid->eap, "fast") == 0)
                ssid->pac_file = g_strdup(WIFI_EAP_FAST_PAC_FILE);
-
-       if (set_connman_bssid(CHECK_BSSID, NULL) == 6) {
-               ssid->bssid_for_connect_len = 6;
-               set_connman_bssid(GET_BSSID, (char *)ssid->bssid_for_connect);
-               DBG("BSSID : %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 {
-               ssid->freq = connman_network_get_frequency(network);
-       }
 #endif
 
        if (connman_setting_get_bool("BackgroundScanning"))
@@ -3955,6 +3978,8 @@ static void interface_state(GSupplicantInterface *interface)
                        else
                                wifi->automaxspeed_timeout = g_timeout_add_seconds(30, autosignalpoll_timeout, wifi);
                }
+
+               g_hash_table_remove_all(failed_bssids);
 #else
                /* though it should be already stopped: */
                stop_autoscan(device);
@@ -3996,9 +4021,21 @@ static void interface_state(GSupplicantInterface *interface)
 
 #if defined TIZEN_EXT
                if (handle_assoc_status_code(interface, wifi)) {
-                       network_connect(network);
-                       break;
+                       GSList *bssid_list = (GSList *)connman_network_get_bssid_list(network);
+                       guint bssid_length = 0;
+
+                       if (bssid_list)
+                               bssid_length = g_slist_length(bssid_list);
+
+                       if (bssid_length > 1 && bssid_length > g_hash_table_size(failed_bssids)) {
+                               network_connect(network);
+                               break;
+                       }
+
+                       wifi->load_shaping_retries = 0;
                }
+
+               g_hash_table_remove_all(failed_bssids);
 #else
                if (handle_assoc_status_code(interface, wifi))
                        break;
@@ -5380,6 +5417,9 @@ static int wifi_init(void)
                return err;
        }
 
+#if defined TIZEN_EXT
+       failed_bssids = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
+#endif
        return 0;
 }
 
@@ -5392,6 +5432,10 @@ static void wifi_exit(void)
        g_supplicant_unregister(&callbacks);
 
        connman_network_driver_unregister(&network_driver);
+
+#if defined TIZEN_EXT
+       g_hash_table_unref(failed_bssids);
+#endif
 }
 
 CONNMAN_PLUGIN_DEFINE(wifi, "WiFi interface plugin", VERSION,
index 9933b723a6c429afb03a62ba322ae050591a1d71..4a53bba324bee666b69acd90b0679bf53328ffde 100755 (executable)
@@ -102,7 +102,6 @@ struct connman_network {
 #if defined TIZEN_EXT
                char encryption_mode[WIFI_ENCYPTION_MODE_LEN_MAX];
                unsigned char bssid[WIFI_BSSID_LEN_MAX];
-               char last_bssid[MAC_ADDRESS_LENGTH];
                unsigned int maxrate;
                int maxspeed;
                bool isHS20AP;
@@ -1580,11 +1579,6 @@ int connman_network_set_connected(struct connman_network *network,
                network, network->connected, connected, network->connecting,
                network->associating);
 
-#if defined TIZEN_EXT
-       /* reset last connect request bssid */
-       connman_network_set_last_bssid(network, NULL);
-#endif
-
        if ((network->connecting || network->associating) &&
                                                        !connected) {
                connman_network_set_error(network,
@@ -1976,23 +1970,6 @@ unsigned char *connman_network_get_bssid(struct connman_network *network)
        return (unsigned char *)network->wifi.bssid;
 }
 
-int connman_network_set_last_bssid(struct connman_network *network,
-                               const char *bssid)
-{
-       if (bssid == NULL) {
-               memset(network->wifi.last_bssid, '\0', sizeof(network->wifi.last_bssid));
-               return -EINVAL;
-       }
-       strncpy(network->wifi.last_bssid, bssid, MAC_ADDRESS_LENGTH - 1);
-
-       return 0;
-}
-
-char *connman_network_get_last_bssid(struct connman_network *network)
-{
-       return (char *)network->wifi.last_bssid;
-}
-
 int connman_network_set_maxspeed(struct connman_network *network,
                                 int maxspeed)
 {