From a0f49e57059d59d8b3124554a16238c968f158c7 Mon Sep 17 00:00:00 2001 From: Jaehyun Kim Date: Mon, 20 Dec 2021 12:11:43 +0900 Subject: [PATCH] Start wifi roaming when better BSS is found If better BSS is found after roaming scan, roaming starts. Change-Id: I9812f3a0205021e1cecb9696ebc29947fd44dae4 Signed-off-by: Jaehyun Kim --- gsupplicant/gsupplicant.h | 22 ++++++ gsupplicant/supplicant.c | 63 ++++++++------- include/network.h | 2 + include/technology.h | 2 + packaging/connman.spec | 2 +- plugins/wifi.c | 198 ++++++++++++++++++++++++++++++++++++++++++---- src/main.c | 14 +++- src/main.conf | 8 +- src/network.c | 42 +++++++--- src/service.c | 67 ++++++++++++++-- src/technology.c | 37 +++++++++ 11 files changed, 392 insertions(+), 65 deletions(-) diff --git a/gsupplicant/gsupplicant.h b/gsupplicant/gsupplicant.h index 07786d9..e7c4e58 100755 --- a/gsupplicant/gsupplicant.h +++ b/gsupplicant/gsupplicant.h @@ -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, diff --git a/gsupplicant/supplicant.c b/gsupplicant/supplicant.c index 9d14c3c..00d183d 100755 --- a/gsupplicant/supplicant.c +++ b/gsupplicant/supplicant.c @@ -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); diff --git a/include/network.h b/include/network.h index 4548699..8ca5314 100755 --- a/include/network.h +++ b/include/network.h @@ -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); diff --git a/include/technology.h b/include/technology.h index d06678e..d47f566 100755 --- a/include/technology.h +++ b/include/technology.h @@ -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 diff --git a/packaging/connman.spec b/packaging/connman.spec index 3cb5a8f..bd8beb0 100644 --- a/packaging/connman.spec +++ b/packaging/connman.spec @@ -6,7 +6,7 @@ Name: connman Version: 1.38 -Release: 10 +Release: 11 License: GPL-2.0+ Summary: Connection Manager Url: http://connman.net diff --git a/plugins/wifi.c b/plugins/wifi.c index 6294a41..ba35f5f 100755 --- a/plugins/wifi.c +++ b/plugins/wifi.c @@ -83,8 +83,28 @@ #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); diff --git a/src/main.c b/src/main.c index 9a55dc5..772f7b8 100755 --- a/src/main.c +++ b/src/main.c @@ -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 diff --git a/src/main.conf b/src/main.conf index 6763d71..662af2b 100755 --- a/src/main.conf +++ b/src/main.conf @@ -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 diff --git a/src/network.c b/src/network.c index d72d40a..b1643e7 100755 --- a/src/network.c +++ b/src/network.c @@ -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; diff --git a/src/service.c b/src/service.c index 175f39d..d2f89d2 100755 --- a/src/service.c +++ b/src/service.c @@ -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(); diff --git a/src/technology.c b/src/technology.c index 4d48b12..f16ee38 100644 --- a/src/technology.c +++ b/src/technology.c @@ -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) -- 2.7.4