summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaehyun Kim <jeik01.kim@samsung.com>2021-12-20 12:11:43 +0900
committerJaehyun Kim <jeik01.kim@samsung.com>2021-12-28 22:21:51 +0900
commita0f49e57059d59d8b3124554a16238c968f158c7 (patch)
treef998d7344ec9da7e5b1e25d8a3f0613bfa5432d1
parentd4fbe50ed65c256d0592cd61496eda3e0bac5389 (diff)
downloadconnman-a0f49e57059d59d8b3124554a16238c968f158c7.tar.gz
connman-a0f49e57059d59d8b3124554a16238c968f158c7.tar.bz2
connman-a0f49e57059d59d8b3124554a16238c968f158c7.zip
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 <jeik01.kim@samsung.com>
-rwxr-xr-xgsupplicant/gsupplicant.h22
-rwxr-xr-xgsupplicant/supplicant.c63
-rwxr-xr-xinclude/network.h2
-rwxr-xr-xinclude/technology.h2
-rw-r--r--packaging/connman.spec2
-rwxr-xr-xplugins/wifi.c198
-rwxr-xr-xsrc/main.c14
-rwxr-xr-xsrc/main.conf8
-rwxr-xr-xsrc/network.c42
-rwxr-xr-xsrc/service.c67
-rw-r--r--src/technology.c37
11 files changed, 392 insertions, 65 deletions
diff --git a/gsupplicant/gsupplicant.h b/gsupplicant/gsupplicant.h
index 07786d90..e7c4e58b 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 9d14c3c7..00d183da 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 45486996..8ca53148 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 d06678e0..d47f5666 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 3cb5a8f4..bd8beb0d 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 6294a413..ba35f5f6 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 9a55dc55..772f7b89 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 6763d71b..662af2b2 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 d72d40a0..b1643e72 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 175f39d9..d2f89d2a 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 4d48b12c..f16ee389 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)