#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"
#define ROAM_SCAN_INTERVAL 60 /* 60 seconds */
#endif
GSupplicantInterface *interface, void *user_data);
static int network_disconnect(struct connman_network *network);
+
+static void start_roaming(struct wifi_data *wifi)
+{
+ bool roaming_ap_found = false;
+ GSList *bssid_list = NULL;
+
+ if (!wifi || !wifi->network)
+ return;
+
+ if (connman_setting_get_bool("WifiRoaming")) {
+ struct connman_network *network = wifi->network;
+ bssid_list = connman_network_get_bssid_list(network);
+
+ if (g_slist_length(bssid_list) <= 1)
+ return;
+
+ if (!connman_network_get_connected(network))
+ return;
+
+ if (connman_network_get_bool(network, "WiFi.Roaming"))
+ return;
+
+ if (!need_bss_transition(
+ connman_network_get_frequency(network),
+ connman_network_get_snr(network),
+ connman_network_get_strength(network)))
+ return;
+
+ 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(network);
+ snprintf(bssid_str, WIFI_BSSID_STR_LEN, MACSTR, MAC2STR(bssid));
+ connman_network_set_string(network,
+ "WiFi.RoamingCurBSSID", bssid_str);
+
+ network_disconnect(network);
+ wifi->pending_network = network;
+ connman_network_set_bool(network, "WiFi.Roaming", true);
+ }
+ }
+}
+
#endif
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;
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);
- }
+ } else {
+ start_roaming(wifi);
}
done:
struct wifi_data *wifi = connman_device_get_data(device);
bool scanning;
- DBG("result %d wifi %p", result, wifi);
+ DBG("result %d device %p wifi %p", result, device, wifi);
if (wifi && wifi->scan_params) {
g_supplicant_free_scan_params(wifi->scan_params);
CONNMAN_SERVICE_TYPE_WIFI, false);
connman_device_unref(device);
}
+
+ start_roaming(wifi);
}
static int wifi_specific_scan(enum connman_service_type type,
connman_network_get_string(network, "WiFi.KeymgmtType"));
ssid->phase1 = connman_network_get_string(network, "WiFi.Phase1");
- if(g_strcmp0(ssid->eap, "fast") == 0)
+ if (g_strcmp0(ssid->eap, "fast") == 0)
ssid->pac_file = g_strdup(WIFI_EAP_FAST_PAC_FILE);
ssid->keymgmt = connman_network_get_keymgmt(network);
goto found;
}
+ if (connman_network_get_bool(wifi->network, "WiFi.Roaming"))
+ connman_network_set_bool(wifi->network, "WiFi.Roaming", false);
+
+ if (network == wifi->pending_network)
+ wifi->pending_network = NULL;
+
/* wifi_data may be invalid because wifi is already disabled */
return;
}
#if defined TIZEN_EXT
- if (wifi->network &&
- (wifi->network != wifi->pending_network ||
- connman_network_get_bool(wifi->network, "WiFi.Roaming")))
+ if (g_slist_find(wifi->networks, network) &&
+ wifi->network != wifi->pending_network)
#else
if (g_slist_find(wifi->networks, network))
#endif
const char *interface = NULL;
struct connman_device *device;
struct connman_network *network = user_data;
+ GSupplicantNetwork *supplicant_network;
+ struct wifi_data *wifi;
uint16_t freq = connman_network_get_frequency(network);
+ const char *group = connman_network_get_group(network);
if (result != 0) {
DBG("Failed to get maxspeed from signalpoll !");
return;
}
+ device = connman_network_get_device(network);
+ if (device)
+ wifi = connman_device_get_data(device);
+
+ if (group) {
+ supplicant_network = g_supplicant_interface_get_network(wifi->interface, group);
+ if (supplicant_network) {
+ g_supplicant_network_set_signal(supplicant_network, strength);
+ g_supplicant_network_set_bss_signal(supplicant_network, strength, snr);
+ }
+ }
+
strength += 120;
if (strength > 100)
strength = 100;
- DBG("freq = %u, maxspeed = %d, strength = %d, snr = %d", freq, maxspeed, strength, snr);
+ bssid = connman_network_get_bssid(network);
+ snprintf(bssid_str, WIFI_BSSID_STR_LEN, MACSTR, MAC2STR(bssid));
+
+ DBG("network %p, bssid %s, freq %u, maxspeed %d, strength %d, snr %d",
+ network, bssid_str, 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);
+ if (connman_network_get_max_bssid_count(network) <= 1)
+ goto done;
+
clock_gettime(CLOCK_MONOTONIC, &curr_time);
roam_scan_time = connman_network_get_roam_scan_time(network);
if (curr_time.tv_sec <= roam_scan_time + ROAM_SCAN_INTERVAL)
goto done;
- if (need_bss_transition(freq, snr, strength)) {
- device = connman_network_get_device(network);
- if (!device)
- goto done;
+ if (device && need_bss_transition(freq, snr, strength)) {
interface = connman_device_get_string(device, "Interface");
- bssid = connman_network_get_bssid(network);
- 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 true;
}
+
+static void handle_wifi_roaming_complete(struct connman_network *network)
+{
+ const char *cur_bssid;
+ const char *dst_bssid;
+ const char *ifname;
+ struct connman_device *device;
+ struct connman_service *service;
+ struct connman_ipconfig *ipconfig_ipv4;
+ enum connman_ipconfig_type type;
+ enum connman_ipconfig_method method;
+
+ if (!connman_setting_get_bool("WifiRoaming") ||
+ !connman_network_get_bool(network, "WiFi.Roaming"))
+ return;
+
+ device = connman_network_get_device(network);
+ if (device) {
+ ifname = connman_device_get_string(device, "Interface");
+ cur_bssid = connman_network_get_string(network,
+ "WiFi.RoamingCurBSSID");
+ dst_bssid = connman_network_get_string(network,
+ "WiFi.RoamingDstBSSID");
+ }
+
+ if (device && ifname && cur_bssid && dst_bssid) {
+ __connman_technology_notify_roaming_state(ifname,
+ "success", cur_bssid, dst_bssid);
+ connman_network_set_bool(network,
+ "WiFi.Roaming", false);
+ connman_network_set_string(network,
+ "WiFi.RoamingCurBSSID", NULL);
+ connman_network_set_string(network,
+ "WiFi.RoamingDstBSSID", NULL);
+
+ service = connman_service_lookup_from_network(network);
+ if (!service)
+ return;
+
+ ipconfig_ipv4 = __connman_service_get_ip4config(service);
+ if (!ipconfig_ipv4) {
+ connman_error("Service has no IPv4 configuration");
+ return;
+ }
+
+ type = __connman_ipconfig_get_config_type(ipconfig_ipv4);
+ if (type != CONNMAN_IPCONFIG_TYPE_IPV4)
+ return;
+
+ method = __connman_ipconfig_get_method(ipconfig_ipv4);
+ if (method != CONNMAN_IPCONFIG_METHOD_DHCP)
+ return;
+
+ connman_network_set_bool(network, "WiFi.RoamingDHCP", true);
+
+ if (set_connected_dhcp(network) != 0)
+ connman_network_set_bool(network, "WiFi.RoamingDHCP", false);
+ }
+}
#endif
static void interface_state(GSupplicantInterface *interface)
wifi->automaxspeed_timeout = 0;
DBG("Remove signalpoll timer!!");
}
+
+ if (!connman_network_get_bool(wifi->network, "WiFi.Roaming"))
#endif
if (wifi->connected)
connman_network_set_connected(network, false);
#else
stop_autoscan(device);
#endif
-
+#if defined TIZEN_EXT
+ if (!connman_network_get_bool(wifi->network, "WiFi.Roaming"))
+#endif
if (!wifi->connected)
connman_network_set_associating(network, true);
}
g_hash_table_remove_all(failed_bssids);
+ handle_wifi_roaming_complete(network);
#else
/* though it should be already stopped: */
stop_autoscan(device);
break;
#if defined TIZEN_EXT
- if (handle_assoc_status_code(interface, wifi)) {
+ if (!wifi->connected && handle_assoc_status_code(interface, wifi)) {
const char *group = connman_network_get_group(network);
GSupplicantNetwork *supplicant_network;
GSList *bssid_list = NULL;
break;
}
- if(wifi->disconnect_code > 0){
+ if (wifi->disconnect_code > 0){
DBG("Set disconnect reason code(%d)", wifi->disconnect_code);
connman_network_set_disconnect_reason(network, wifi->disconnect_code);
}