Start wifi roaming when better BSS is found 82/268282/4
authorJaehyun Kim <jeik01.kim@samsung.com>
Mon, 20 Dec 2021 03:11:43 +0000 (12:11 +0900)
committerJaehyun Kim <jeik01.kim@samsung.com>
Tue, 28 Dec 2021 13:21:51 +0000 (22:21 +0900)
If better BSS is found after roaming scan, roaming starts.

Change-Id: I9812f3a0205021e1cecb9696ebc29947fd44dae4
Signed-off-by: Jaehyun Kim <jeik01.kim@samsung.com>
gsupplicant/gsupplicant.h
gsupplicant/supplicant.c
include/network.h
include/technology.h
packaging/connman.spec
plugins/wifi.c
src/main.c
src/main.conf
src/network.c
src/service.c
src/technology.c

index 07786d9..e7c4e58 100755 (executable)
@@ -280,6 +280,27 @@ struct _GSupplicantP2PServiceParams {
 
 typedef struct _GSupplicantP2PServiceParams GSupplicantP2PServiceParams;
 
+#if defined TIZEN_EXT
+#define WIFI_BSSID_LEN_MAX 6
+
+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;
+       int score_snr;
+#if defined TIZEN_EXT_INS
+       int score_last_connected_bssid;
+       int score_assoc_reject;
+       int score_frequency;
+       int score_strength;
+       int score_est_throughput;
+#endif
+       int ins_score;
+};
+#endif
+
 /* global API */
 typedef void (*GSupplicantCountryCallback) (int result,
                                                const char *alpha2,
@@ -383,6 +404,7 @@ void *g_supplicant_interface_get_data(GSupplicantInterface *interface);
 const char *g_supplicant_interface_get_ifname(GSupplicantInterface *interface);
 #if defined TIZEN_EXT
 bool g_supplicant_interface_get_is_5_0_ghz_supported(GSupplicantInterface *interface);
+unsigned char *g_supplicant_interface_get_add_network_bssid(GSupplicantInterface *interface);
 
 typedef void (*GSupplicantMacPolicyCallback) (int result, unsigned int policy, void *user_data);
 int g_supplicant_interface_set_mac_policy(GSupplicantInterface *interface,
index 9d14c3c..00d183d 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
@@ -437,23 +436,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;
-       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];
@@ -1436,6 +1418,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)
@@ -1909,10 +1899,10 @@ 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) {
+                       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;
 
                pairwise = network->best_bss->rsn_pairwise |
@@ -2133,7 +2123,6 @@ static int calculate_score_est_throughput(dbus_uint32_t est_throughput)
 
        return score;
 }
-#endif
 
 static int calculate_score(bool is_last_connected, uint16_t assoc_reject_cnt,
                dbus_uint16_t frequency, dbus_int16_t strength,
@@ -2150,6 +2139,7 @@ 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)
 {
@@ -2169,6 +2159,7 @@ 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);
@@ -2178,7 +2169,6 @@ static void update_bssid_list(gpointer key, gpointer value, gpointer user_data)
                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);
 
                bssids->ins_score = calculate_score(bssids->is_last_connected,
@@ -2553,6 +2543,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;
@@ -3155,6 +3151,8 @@ 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;
 #endif
@@ -3163,8 +3161,6 @@ static void bss_compute_security(struct g_supplicant_bss *bss)
 #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)
@@ -3519,6 +3515,11 @@ static void interface_current_bss(GSupplicantInterface *interface,
 
                network->best_bss = bss;
 
+#if defined TIZEN_EXT
+               if (network->frequency != bss->frequency)
+                       network->frequency = bss->frequency;
+#endif
+
                if (network->signal != bss->signal) {
                        SUPPLICANT_DBG("New network signal %d dBm",
                                                bss->signal);
@@ -3526,6 +3527,10 @@ static void interface_current_bss(GSupplicantInterface *interface,
                        network->signal = bss->signal;
                        callback_network_changed(network, "Signal");
                }
+#if defined TIZEN_EXT
+               else
+                       callback_network_changed(network, "");
+#endif
        }
 
        /*
@@ -4292,8 +4297,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);
index 4548699..8ca5314 100755 (executable)
@@ -241,6 +241,8 @@ unsigned char *connman_network_get_last_connected_bssid(struct connman_network *
 void connman_network_set_assoc_reject_table(struct connman_network *network,
                GHashTable *assoc_reject_table);
 GHashTable *connman_network_get_assoc_reject_table(struct connman_network *network);
+int connman_network_get_snr(struct connman_network *network);
+void connman_network_set_snr(struct connman_network *network, int snr);
 #endif
 int connman_network_set_phy_mode(struct connman_network *network,
                                ieee80211_modes_e mode);
index d06678e..d47f566 100755 (executable)
@@ -94,6 +94,8 @@ const char *connman_techonology_get_path(enum connman_service_type type);
 void __connman_technology_notify_scan_done(const char *ifname, int val);
 void __connman_technology_append_interfaces(DBusMessageIter *array,
                                enum connman_service_type type, const char *ifname);
+void __connman_technology_notify_roaming_state(const char *ifname,
+               const char *state, const char *cur_bssid, const char *dst_bssid);
 #endif
 
 #ifdef __cplusplus
index 3cb5a8f..bd8beb0 100644 (file)
@@ -6,7 +6,7 @@
 
 Name:           connman
 Version:        1.38
-Release:        10
+Release:        11
 License:        GPL-2.0+
 Summary:        Connection Manager
 Url:            http://connman.net
index 6294a41..ba35f5f 100755 (executable)
 
 #if defined TIZEN_EXT
 #define WIFI_EAP_FAST_PAC_FILE         "/var/lib/wifi/wifi.pac"        /* path of Pac file for EAP-FAST */
+
+       /* Wi-Fi Signal Strength (for 2.4G (dB))
+        * Excellent :     ~ -63
+        * Good      : -64 ~ -74
+        * Weak      : -75 ~ -82
+        * Very weak : -83 ~ -88
+        * No signal : -89 ~
+        *
+        * Wi-Fi Signal Strength (for 5G (dB))
+        * Excellent :     ~ -67
+        * Good      : -68 ~ -76
+        * Weak      : -77 ~ -82
+        * Very weak : -83 ~ -88
+        * No signal : -89 ~
+        */
 #define RSSI_LEVEL_2_5G  -77
 #define RSSI_LEVEL_2_24G -75
+#define RSSI_LEVEL_3_5G  -68
+#define RSSI_LEVEL_3_24G -64
+#define WIFI_BSSID_STR_LEN 18
+#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
+#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
 #endif
 
 static struct connman_technology *wifi_technology = NULL;
@@ -2088,8 +2108,57 @@ static void service_state_changed(struct connman_service *service,
        }
 }
 
+static gboolean need_bss_transition(uint16_t freq, int snr, int strength)
+{
+       /*
+        * Since bssid->strength is a positive value,
+        * it need to be changed to its original value.
+        */
+       int signal = strength - 120;
+
+       /*
+        * If the currently connected AP matches the following conditions,
+        * scan for BSS transition is started.
+        *   - SNR is less than 20 or RSSI level is less than 3
+        */
+       if (snr < 20 && snr != 0)
+               return TRUE;
+       else if (freq > 4900 && signal <= RSSI_LEVEL_2_5G)
+               return TRUE;
+       else if (freq <= 4900 && signal <= RSSI_LEVEL_2_24G)
+               return TRUE;
+
+       return FALSE;
+}
+
+static gboolean check_bss_condition(uint16_t freq, int snr, uint16_t strength)
+{
+       /*
+        * Since bssid->strength is a positive value,
+        * it need to be changed to its original value.
+        */
+       int signal = strength - 120;
+
+       /*
+        * If the AP that matches the following conditions exists in the SCAN result,
+        * BSS transition is started.
+        *   - SNR is 25 or more and RSSI level is greater than 3
+        */
+       if (snr < 25 && snr != 0)
+               return FALSE;
+
+       if (freq > 4900 && signal > RSSI_LEVEL_3_5G)
+               return TRUE;
+       else if (freq <= 4900 && signal > RSSI_LEVEL_3_24G)
+               return TRUE;
+
+       return FALSE;
+}
+
 static void scan_callback_hidden(int result,
                        GSupplicantInterface *interface, void *user_data);
+
+static int network_disconnect(struct connman_network *network);
 #endif
 
 static void scan_callback(int result, GSupplicantInterface *interface,
@@ -2099,7 +2168,10 @@ static void scan_callback(int result, GSupplicantInterface *interface,
        struct wifi_data *wifi = connman_device_get_data(device);
        bool scanning;
 #if defined TIZEN_EXT
+       bool roaming_needed = false;
+       bool roaming_ap_found = false;
        GSList *list = NULL;
+       GSList *bssid_list = NULL;
        bool favorite_exists = false;
        struct connman_network *network = NULL;
        struct connman_service *service = NULL;
@@ -2159,7 +2231,8 @@ static void scan_callback(int result, GSupplicantInterface *interface,
                        if (service != NULL &&
                                (connman_service_get_favorite(service) == true) &&
                                (connman_service_get_autoconnect(service) == true)) {
-                               DBG("Favorite service exists [%s]", connman_network_get_string(network, "Name"));
+                               DBG("Favorite service exists [%s]",
+                                               connman_network_get_string(network, "Name"));
                                favorite_exists = true;
                                break;
                        }
@@ -2212,8 +2285,49 @@ static void scan_callback(int result, GSupplicantInterface *interface,
                network_connect(wifi->scan_pending_network);
                wifi->scan_pending_network = NULL;
                connman_network_set_connecting(wifi->network);
+       } else if (connman_setting_get_bool("WifiRoaming") && wifi->network) {
+               bssid_list = connman_network_get_bssid_list(wifi->network);
+
+               if (g_slist_length(bssid_list) <= 1)
+                       goto done;
+
+               if (!connman_network_get_connected(wifi->network))
+                       goto done;
+
+               if (connman_network_get_bool(wifi->network, "WiFi.Roaming"))
+                       goto done;
+
+               if (!need_bss_transition(
+                               connman_network_get_frequency(wifi->network),
+                               connman_network_get_snr(wifi->network),
+                               connman_network_get_strength(wifi->network)))
+                       goto done;
+
+               for (bssid_list; bssid_list; bssid_list = bssid_list->next) {
+                       struct g_connman_bssids *bssid = bssid_list->data;
+
+                       if (check_bss_condition(bssid->frequency,
+                                       bssid->score_snr, bssid->strength))
+                               roaming_ap_found = true;
+               }
+
+               if (roaming_ap_found) {
+                       char bssid_buff[WIFI_BSSID_STR_LEN] = {0,};
+                       char *bssid_str = bssid_buff;
+                       unsigned char *bssid;
+
+                       bssid = connman_network_get_bssid(wifi->network);
+                       snprintf(bssid_str, WIFI_BSSID_STR_LEN, MACSTR, MAC2STR(bssid));
+                       connman_network_set_string(wifi->network,
+                                       "WiFi.RoamingCurBSSID", bssid_str);
+
+                       network_disconnect(wifi->network);
+                       wifi->pending_network = wifi->network;
+                       connman_network_set_bool(wifi->network, "WiFi.Roaming", true);
+               }
        }
 
+done:
        if (is_wifi_notifier_registered != true &&
                        wifi_first_scan == true && found_with_first_scan == true) {
                wifi_first_scan = false;
@@ -3527,6 +3641,38 @@ static void connect_callback(int result, GSupplicantInterface *interface,
        return;
 
 found:
+       if (connman_network_get_bool(network, "WiFi.Roaming")) {
+               if (result < 0 ) {
+                       connman_network_set_bool(network, "WiFi.Roaming", false);
+                       connman_network_set_string(network,
+                                       "WiFi.RoamingCurBSSID", NULL);
+               } else {
+                       char bssid_buff[WIFI_BSSID_STR_LEN] = {0,};
+                       char *bssid_str = bssid_buff;
+                       unsigned char *bssid;
+                       const char *cur_bssid;
+
+                       bssid = g_supplicant_interface_get_add_network_bssid(interface);
+                       if (!bssid) {
+                               connman_network_set_bool(network, "WiFi.Roaming", false);
+                               connman_network_set_string(network,
+                                               "WiFi.RoamingCurBSSID", NULL);
+                       } else {
+                               snprintf(bssid_str,
+                                               WIFI_BSSID_STR_LEN,
+                                               MACSTR, MAC2STR(bssid));
+
+                               connman_network_set_string(network,
+                                               "WiFi.RoamingDstBSSID", bssid_str);
+
+                               cur_bssid = connman_network_get_string(network,
+                                               "WiFi.RoamingCurBSSID");
+
+                               __connman_technology_notify_roaming_state(ifname,
+                                               "started", cur_bssid, bssid_str);
+                       }
+               }
+       }
 #endif
        if (result == -ENOKEY) {
                connman_network_set_error(network,
@@ -3820,7 +3966,13 @@ found:
                return;
        }
 
+#if defined TIZEN_EXT
+       if (wifi->network &&
+                       (wifi->network != wifi->pending_network ||
+                       connman_network_get_bool(wifi->network, "WiFi.Roaming")))
+#else
        if (wifi->network && wifi->network != wifi->pending_network)
+#endif
                connman_network_set_connected(wifi->network, false);
        wifi->network = NULL;
 
@@ -3969,6 +4121,11 @@ static void set_connection_mode(struct connman_network *network,
 static void signalpoll_callback(int result, int maxspeed, int strength,
                                int snr, void *user_data)
 {
+       char bssid_buff[WIFI_BSSID_STR_LEN] = {0,};
+       char *bssid_str = bssid_buff;
+       unsigned char *bssid;
+       const char *interface = NULL;
+       struct connman_device *device;
        struct connman_network *network = user_data;
        uint16_t freq = connman_network_get_frequency(network);
 
@@ -3982,31 +4139,30 @@ static void signalpoll_callback(int result, int maxspeed, int strength,
        if (strength > 100)
                strength = 100;
 
-       DBG("maxspeed = %d, strength = %d, snr = %d", maxspeed, strength, snr);
+       DBG("freq = %u, maxspeed = %d, strength = %d, snr = %d", freq, maxspeed, strength, snr);
 
        connman_network_set_strength(network, (uint8_t)strength);
+       connman_network_set_snr(network, snr);
        connman_network_set_maxspeed(network, maxspeed);
        set_connection_mode(network, maxspeed);
 
-       connman_network_unref(network);
+       bssid = connman_network_get_bssid(network);
+       device = connman_network_get_device(network);
 
-       /* If SNR is less than 20 or RSSI level is less than 3,
-        * scan for BSS transition is started.
-        * */
-       if (connman_setting_get_bool("WifiRoamingScan") == false)
-               return;
+       if (device)
+               interface = connman_device_get_string(device, "Interface");
 
-       if (snr < 20 && snr != 0)
-               goto scan;
-       else if (freq > 4900 && strength <= RSSI_LEVEL_2_5G)
-               goto scan;
-       else if (freq <= 4900 && strength <= RSSI_LEVEL_2_24G)
-               goto scan;
+       connman_network_unref(network);
 
-       return;
+       if (need_bss_transition(freq, snr, strength)) {
+               snprintf(bssid_str, WIFI_BSSID_STR_LEN, MACSTR, MAC2STR(bssid));
+               __connman_technology_notify_roaming_state(interface, "required", bssid_str, NULL);
+
+               if (connman_setting_get_bool("WifiRoamingScan") == false)
+                       return;
 
-scan:
-       throw_wifi_scan(connman_network_get_device(network), scan_callback);
+               throw_wifi_scan(device, scan_callback);
+       }
 }
 
 static int network_signalpoll(struct wifi_data *wifi)
@@ -4043,6 +4199,7 @@ static gboolean autosignalpoll_timeout(gpointer data)
 
                if (wifi->network)
                        connman_network_unref(wifi->network);
+
                return FALSE;
        }
 
@@ -4393,6 +4550,13 @@ static void interface_state(GSupplicantInterface *interface)
 
        switch (state) {
        case G_SUPPLICANT_STATE_SCANNING:
+#if defined TIZEN_EXT
+               if (wifi->automaxspeed_timeout != 0) {
+                       g_source_remove(wifi->automaxspeed_timeout);
+                       wifi->automaxspeed_timeout = 0;
+                       DBG("Remove signalpoll timer!!");
+               }
+#endif
                if (wifi->connected)
                        connman_network_set_connected(network, false);
 
index 9a55dc5..772f7b8 100755 (executable)
@@ -109,6 +109,7 @@ static struct {
        bool dlog_log;
        bool simple_log;
        bool wifi_roam_scan;
+       bool wifi_roam;
 #endif
 } connman_settings  = {
        .bg_scan = true,
@@ -142,7 +143,8 @@ static struct {
        .file_log = true,
        .dlog_log = true,
        .simple_log = true,
-       .wifi_roam_scan = true,
+       .wifi_roam_scan = false,
+       .wifi_roam = false,
 #endif
 };
 
@@ -234,6 +236,7 @@ static struct {
 #define CONF_CONNMAN_DLOG_LOG           "DlogLogging"
 #define CONF_CONNMAN_SIMPLIFIED_LOG     "SimplifiedLog"
 #define CONF_CONNMAN_WIFI_ROAM_SCAN     "WifiRoamingScan"
+#define CONF_CONNMAN_WIFI_ROAM          "WifiRoaming"
 #endif
 
 #if defined TIZEN_EXT
@@ -296,6 +299,7 @@ static const char *supported_options[] = {
        CONF_CONNMAN_DLOG_LOG,
        CONF_CONNMAN_SIMPLIFIED_LOG,
        CONF_CONNMAN_WIFI_ROAM_SCAN,
+       CONF_CONNMAN_WIFI_ROAM,
 #endif
        NULL
 };
@@ -707,6 +711,11 @@ static void check_Tizen_configuration(GKeyFile *config)
        if (!error)
                connman_settings.wifi_roam_scan = boolean;
 
+       boolean = __connman_config_get_bool(config, "General",
+                       CONF_CONNMAN_WIFI_ROAM, &error);
+       if (!error)
+               connman_settings.wifi_roam = boolean;
+
        g_clear_error(&error);
 
        check_Tizen_INS_configuration(config);
@@ -1196,6 +1205,9 @@ bool connman_setting_get_bool(const char *key)
 
        if (g_str_equal(key, CONF_CONNMAN_WIFI_ROAM_SCAN))
                return connman_settings.wifi_roam_scan;
+
+       if (g_str_equal(key, CONF_CONNMAN_WIFI_ROAM))
+               return connman_settings.wifi_roam;
 #endif
 
 #if defined TIZEN_EXT
index 6763d71..662af2b 100755 (executable)
@@ -186,9 +186,15 @@ SimplifiedLog = true
 DefaultWifiInterface = wlan0
 
 # Allow ConnMan to start scan for wifi roaming when SNR and signal are weakened
-# Default value is true.
+# Default value is false.
 WifiRoamingScan = true
 
+# Allow ConnMan to start wifi roaming when SNR and signal are weakened
+# and there is another BSS in better condition.
+# Default value is false.
+WifiRoaming = true
+
+
 [INS]
 # INS(Intelligent Network Selection) configuration: BSSID Selection.
 INSPreferredFreqBSSID = 5GHz
index d72d40a..b1643e7 100755 (executable)
@@ -145,6 +145,10 @@ struct connman_network {
                void *transition_mode_ssid;
                int transition_mode_ssid_len;
                unsigned char transition_mode_bssid[WIFI_BSSID_LEN_MAX];
+               bool roaming_progress;
+               char *roaming_cur_bssid;
+               char *roaming_dst_bssid;
+               int snr;
 #endif
        } wifi;
 
@@ -2347,6 +2351,9 @@ int connman_network_set_bssid(struct connman_network *network,
        if (bssid == NULL)
                return -EINVAL;
 
+       if (network->connected)
+               return -EPERM;
+
        if (!simplified_log)
                DBG("network %p bssid %02x:%02x:%02x:%02x:%02x:%02x", network,
                                bssid[0], bssid[1], bssid[2],
@@ -2643,6 +2650,16 @@ GHashTable *connman_network_get_assoc_reject_table(struct connman_network *netwo
 
        return network->wifi.assoc_reject_table;
 }
+
+int connman_network_get_snr(struct connman_network *network)
+{
+       return network->wifi.snr;
+}
+
+void connman_network_set_snr(struct connman_network *network, int snr)
+{
+       network->wifi.snr = snr;
+}
 #endif
 
 int connman_network_set_nameservers(struct connman_network *network,
@@ -2852,6 +2869,12 @@ int connman_network_set_string(struct connman_network *network,
        } else if (g_str_equal(key, "WiFi.NetAccessKey")) {
                g_free(network->wifi.net_access_key);
                network->wifi.net_access_key = g_strdup(value);
+       } else if (g_str_equal(key, "WiFi.RoamingCurBSSID")) {
+               g_free(network->wifi.roaming_cur_bssid);
+               network->wifi.roaming_cur_bssid = g_strdup(value);
+       } else if (g_str_equal(key, "WiFi.RoamingDstBSSID")) {
+               g_free(network->wifi.roaming_dst_bssid);
+               network->wifi.roaming_dst_bssid = g_strdup(value);
 #endif
        } else {
                return -EINVAL;
@@ -2879,15 +2902,7 @@ const char *connman_network_get_string(struct connman_network *network,
        else if (g_str_equal(key, "WiFi.Mode"))
                return network->wifi.mode;
        else if (g_str_equal(key, "WiFi.Security"))
-#if defined TIZEN_EXT
-               if (network->wifi.rsn_mode != true ||
-                   g_str_equal(network->wifi.security, "ieee8021x"))
-                       return network->wifi.security;
-               else
-                       return "rsn";
-#else
                return network->wifi.security;
-#endif
        else if (g_str_equal(key, "WiFi.Passphrase"))
                return network->wifi.passphrase;
        else if (g_str_equal(key, "WiFi.EAP"))
@@ -2925,6 +2940,10 @@ const char *connman_network_get_string(struct connman_network *network,
                return network->wifi.c_sign_key;
        else if (g_str_equal(key, "WiFi.NetAccessKey"))
                return network->wifi.net_access_key;
+       else if (g_str_equal(key, "WiFi.RoamingCurBSSID"))
+               return network->wifi.roaming_cur_bssid;
+       else if (g_str_equal(key, "WiFi.RoamingDstBSSID"))
+               return network->wifi.roaming_dst_bssid;
 #endif
 
        return NULL;
@@ -2956,6 +2975,9 @@ int connman_network_set_bool(struct connman_network *network,
                network->wifi.isHS20AP = value;
        else if (g_strcmp0(key, "WiFi.TRANSITION_MODE") == 0)
                network->wifi.owe_transition_mode = value;
+       else if (g_strcmp0(key, "WiFi.Roaming") == 0) {
+               network->wifi.roaming_progress = value;
+       }
 #endif
 
        return -EINVAL;
@@ -2984,8 +3006,10 @@ bool connman_network_get_bool(struct connman_network *network,
                return network->default_internet;
        else if (g_str_equal(key, "WiFi.HS20AP"))
                return network->wifi.isHS20AP;
-       else if (g_strcmp0(key, "WiFi.TRANSITION_MODE"))
+       else if (g_str_equal(key, "WiFi.TRANSITION_MODE"))
                return network->wifi.owe_transition_mode;
+       else if (g_str_equal(key, "WiFi.Roaming"))
+               return network->wifi.roaming_progress;
 #endif
 
        return false;
index 175f39d..d2f89d2 100755 (executable)
@@ -7958,14 +7958,16 @@ static int calculate_score_last_connected(struct connman_service *service)
        last_connected_ident = connman_device_get_last_connected_ident(device);
        frequency = connman_network_get_frequency(service->network);
 
-       if (g_strcmp0(last_connected_ident, service->identifier) == 0 &&
-               (((frequency >= FREQ_RANGE_24GHZ_CHANNEL_1 &&
-               frequency <= FREQ_RANGE_24GHZ_CHANNEL_14) &&
-               service->strength >= ins_settings.signal_level3_24ghz) ||
-               ((frequency >= FREQ_RANGE_5GHZ_CHANNEL_32 &&
-               frequency <= FREQ_RANGE_5GHZ_CHANNEL_165) &&
-               service->strength >= ins_settings.signal_level3_5ghz))) {
-               score += ins_settings.last_connected_score;
+       if (ins_settings.last_connected) {
+               if (g_strcmp0(last_connected_ident, service->identifier) == 0 &&
+                               (((frequency >= FREQ_RANGE_24GHZ_CHANNEL_1 &&
+                               frequency <= FREQ_RANGE_24GHZ_CHANNEL_14) &&
+                               service->strength >= ins_settings.signal_level3_24ghz) ||
+                               ((frequency >= FREQ_RANGE_5GHZ_CHANNEL_32 &&
+                               frequency <= FREQ_RANGE_5GHZ_CHANNEL_165) &&
+                               service->strength >= ins_settings.signal_level3_5ghz))) {
+                       score += ins_settings.last_connected_score;
+               }
        }
 
        return score;
@@ -9237,6 +9239,55 @@ static int service_indicate_state(struct connman_service *service)
 #else
        __connman_service_connect_default(service);
 #endif
+       /* Update Wi-Fi Roaming result */
+       if (connman_setting_get_bool("WifiRoaming") &&
+                       connman_network_get_bool(service->network, "WiFi.Roaming")) {
+               const char *cur_bssid;
+               const char *dst_bssid;
+               const char *ifname;
+               struct connman_device *device;
+
+               device = connman_network_get_device(service->network);
+               if (device) {
+                       ifname = connman_device_get_string(device, "Interface");
+                       cur_bssid = connman_network_get_string(service->network,
+                                               "WiFi.RoamingCurBSSID");
+                       dst_bssid = connman_network_get_string(service->network,
+                                               "WiFi.RoamingDstBSSID");
+               }
+
+               if (device && ifname && cur_bssid && dst_bssid) {
+                       switch(new_state) {
+                       case CONNMAN_SERVICE_STATE_UNKNOWN:
+                       case CONNMAN_SERVICE_STATE_ASSOCIATION:
+                       case CONNMAN_SERVICE_STATE_CONFIGURATION:
+                               break;
+                       case CONNMAN_SERVICE_STATE_READY:
+                       case CONNMAN_SERVICE_STATE_ONLINE:
+                               __connman_technology_notify_roaming_state(ifname,
+                                               "success", cur_bssid, dst_bssid);
+                               connman_network_set_bool(service->network,
+                                               "WiFi.Roaming", false);
+                               connman_network_set_string(service->network,
+                                               "WiFi.RoamingCurBSSID", NULL);
+                               connman_network_set_string(service->network,
+                                               "WiFi.RoamingDstBSSID", NULL);
+                               break;
+                       case CONNMAN_SERVICE_STATE_DISCONNECT:
+                       case CONNMAN_SERVICE_STATE_FAILURE:
+                       case CONNMAN_SERVICE_STATE_IDLE:
+                               __connman_technology_notify_roaming_state(ifname,
+                                               "failure", cur_bssid, dst_bssid);
+                               connman_network_set_bool(service->network,
+                                               "WiFi.Roaming", false);
+                               connman_network_set_string(service->network,
+                                               "WiFi.RoamingCurBSSID", NULL);
+                               connman_network_set_string(service->network,
+                                               "WiFi.RoamingDstBSSID", NULL);
+                               break;
+                       }
+               }
+       }
 #endif
 
        __connman_connection_update_gateway();
index 4d48b12..f16ee38 100644 (file)
@@ -1663,6 +1663,43 @@ static void __connman_technology_notify_device_detected(
 
        DBG("Successfuly sent DeviceDetected signal");
 }
+
+void __connman_technology_notify_roaming_state(const char *ifname,
+               const char *state, const char *cur_bssid, const char *dst_bssid)
+{
+       DBG("");
+       DBusMessage *signal;
+       DBusMessageIter array, dict;
+
+       signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
+                       CONNMAN_MANAGER_INTERFACE, "RoamingStateChanged");
+       if (!signal)
+               return;
+
+       dbus_message_iter_init_append(signal, &array);
+
+       connman_dbus_dict_open(&array, &dict);
+
+       if (ifname)
+               connman_dbus_dict_append_basic(&dict, "Interface",
+                                       DBUS_TYPE_STRING, &ifname);
+       if (state)
+               connman_dbus_dict_append_basic(&dict, "State",
+                                       DBUS_TYPE_STRING, &state);
+       if (cur_bssid)
+               connman_dbus_dict_append_basic(&dict, "ConnectedBSSID",
+                                       DBUS_TYPE_STRING, &cur_bssid);
+       if (dst_bssid)
+               connman_dbus_dict_append_basic(&dict, "TargetBSSID",
+                                       DBUS_TYPE_STRING, &dst_bssid);
+
+       connman_dbus_dict_close(&array, &dict);
+
+       dbus_connection_send(connection, signal, NULL);
+       dbus_message_unref(signal);
+
+       DBG("Successfully sent Roaming State Changed signal");
+}
 #endif
 
 void __connman_technology_scan_started(struct connman_device *device)