From 00b8c314dc2cfb641494d413f4b00d90a10ecbeb Mon Sep 17 00:00:00 2001 From: Jaehyun Kim Date: Tue, 23 Aug 2022 02:15:07 +0900 Subject: [PATCH] Maintain connection status when wifi roaming When wifi roaming, the current connection status is maintained. If the network is changed, the connection status is reset. Change-Id: I2680030c849c712b7d7dc68f70397514484a7fc3 Signed-off-by: Jaehyun Kim --- gsupplicant/gsupplicant.h | 9 +- gsupplicant/supplicant.c | 63 ++++++++++--- include/network.h | 4 +- include/service.h | 3 +- packaging/connman.spec | 2 +- plugins/wifi.c | 219 +++++++++++++++++++++++++++++++++------------- src/dhcp.c | 29 +++++- src/network.c | 30 ++++++- src/service.c | 139 ++++++++++++++++++----------- 9 files changed, 366 insertions(+), 132 deletions(-) diff --git a/gsupplicant/gsupplicant.h b/gsupplicant/gsupplicant.h index ed07c1f..884c92e 100755 --- a/gsupplicant/gsupplicant.h +++ b/gsupplicant/gsupplicant.h @@ -281,6 +281,10 @@ struct _GSupplicantP2PServiceParams { typedef struct _GSupplicantP2PServiceParams GSupplicantP2PServiceParams; #if defined TIZEN_EXT +#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 WIFI_BSSID_LEN_MAX 6 struct g_connman_bssids { @@ -530,9 +534,10 @@ dbus_bool_t g_supplicant_network_get_transition_mode(GSupplicantNetwork *network const unsigned char *g_supplicant_network_get_transition_mode_bssid(GSupplicantNetwork *network); const void *g_supplicant_network_get_transition_mode_ssid(GSupplicantNetwork *network, unsigned int *transition_mode_ssid_len); +void g_supplicant_network_set_signal(GSupplicantNetwork *network, int signal); +void g_supplicant_network_set_bss_signal(GSupplicantNetwork *network, + int signal, int snr); -#endif -#if defined TIZEN_EXT void g_supplicant_network_set_last_connected_bssid(GSupplicantNetwork *network, const unsigned char *bssid); const unsigned char *g_supplicant_network_get_last_connected_bssid(GSupplicantNetwork *network); void g_supplicant_network_update_assoc_reject(GSupplicantInterface *interface, diff --git a/gsupplicant/supplicant.c b/gsupplicant/supplicant.c index 4bc5276..e457fef 100755 --- a/gsupplicant/supplicant.c +++ b/gsupplicant/supplicant.c @@ -1601,6 +1601,32 @@ dbus_int16_t g_supplicant_network_get_signal(GSupplicantNetwork *network) return network->signal; } +#if defined TIZEN_EXT +void g_supplicant_network_set_signal(GSupplicantNetwork *network, int signal) +{ + if (!network) + return; + + network->signal = (dbus_int16_t)signal; +} + +void g_supplicant_network_set_bss_signal(GSupplicantNetwork *network, + int signal, int snr) +{ + struct g_supplicant_bss *best_bss; + + if (!network) + return; + + best_bss = network->best_bss; + if (!best_bss) + return; + + best_bss->signal = (dbus_int16_t)signal; + best_bss->snr = (dbus_int16_t)snr; +} +#endif + dbus_uint16_t g_supplicant_network_get_frequency(GSupplicantNetwork *network) { if (!network) @@ -2631,7 +2657,7 @@ static bool update_best_bss(GSupplicantNetwork *network, #endif if (score_new > score_best) { - SUPPLICANT_DBG("new[" MACSTR "][%u] : best[" MACSTR "][%u]", + SUPPLICANT_DBG("new[" MACSTR "][%d] : best[" MACSTR "][%d]", MAC2STR(bss->bssid), score_new, MAC2STR(network->best_bss->bssid), score_best); @@ -3547,6 +3573,13 @@ static void interface_current_bss(GSupplicantInterface *interface, GSupplicantNetwork *network; struct g_supplicant_bss *bss; const char *path; +#if defined TIZEN_EXT + char bssid_buff1[WIFI_BSSID_STR_LEN] = {0,}; + char bssid_buff2[WIFI_BSSID_STR_LEN] = {0,}; + char *bssid_str1 = bssid_buff1; + char *bssid_str2 = bssid_buff2; + gboolean update = FALSE; +#endif dbus_message_iter_get_basic(iter, &path); if (g_strcmp0(path, "/") == 0) { @@ -3566,7 +3599,16 @@ static void interface_current_bss(GSupplicantInterface *interface, interface->current_network = network; #if defined TIZEN_EXT - SUPPLICANT_DBG("current network [%p]", interface->current_network); + snprintf(bssid_str1, WIFI_BSSID_STR_LEN, MACSTR, MAC2STR(bss->bssid)); + snprintf(bssid_str2, WIFI_BSSID_STR_LEN, MACSTR, MAC2STR(network->best_bss->bssid)); + + SUPPLICANT_DBG("current network [%p], Passed bss %s, best bss %s", + interface->current_network, bssid_str1, bssid_str2); + + if (network->frequency != bss->frequency) { + network->frequency = bss->frequency; + update = TRUE; + } #endif if (bss != network->best_bss) { @@ -3579,24 +3621,25 @@ 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); network->signal = bss->signal; callback_network_changed(network, "Signal"); - } #if defined TIZEN_EXT - else - callback_network_changed(network, ""); + update = FALSE; + } else { + update = TRUE; #endif + } } +#if defined TIZEN_EXT + if (update) + callback_network_changed(network, ""); +#endif + /* * wpa_s could notify about CurrentBSS in any state once * it got associated. It is not sure such notification will diff --git a/include/network.h b/include/network.h index 4d09dff..d637579 100755 --- a/include/network.h +++ b/include/network.h @@ -235,7 +235,7 @@ unsigned char *connman_network_get_countrycode(struct connman_network *network); int connman_network_set_bssid_list(struct connman_network *network, GSList *bssids); void *connman_network_get_bssid_list(struct connman_network *network); -#if defined TIZEN_EXT +unsigned int connman_network_get_max_bssid_count(struct connman_network *network); int connman_network_set_last_connected_bssid(struct connman_network *network, const unsigned char *bssid); unsigned char *connman_network_get_last_connected_bssid(struct connman_network *network); @@ -247,13 +247,13 @@ void connman_network_set_roam_scan_time(struct connman_network *network, __time_t roam_scan_time); 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); ieee80211_modes_e connman_network_get_phy_mode(struct connman_network *network); int connman_network_set_connection_mode(struct connman_network *network, connection_mode_e mode); connection_mode_e connman_network_get_connection_mode(struct connman_network *network); +int set_connected_dhcp(struct connman_network *network); #endif int connman_network_set_name(struct connman_network *network, diff --git a/include/service.h b/include/service.h index 041949f..3f4c58c 100755 --- a/include/service.h +++ b/include/service.h @@ -209,7 +209,8 @@ int connman_service_set_proxy(struct connman_service *service, const char *proxy, gboolean active); void connman_service_set_disconnection_requested(struct connman_service *service, - bool disconnection_requested); + bool disconnection_requested); +void connman_service_notify_reconnection(struct connman_service *service); #endif #if defined TIZEN_EXT diff --git a/packaging/connman.spec b/packaging/connman.spec index 3f73b7b..ba2c24c 100644 --- a/packaging/connman.spec +++ b/packaging/connman.spec @@ -6,7 +6,7 @@ Name: connman Version: 1.40 -Release: 1 +Release: 2 License: GPL-2.0+ Summary: Connection Manager Url: http://connman.net diff --git a/plugins/wifi.c b/plugins/wifi.c index 9bd11cb..4280c47 100755 --- a/plugins/wifi.c +++ b/plugins/wifi.c @@ -103,9 +103,6 @@ #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 @@ -2177,6 +2174,59 @@ static void scan_callback_hidden(int result, 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, @@ -2186,10 +2236,7 @@ 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; @@ -2306,46 +2353,8 @@ 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); - } + } else { + start_roaming(wifi); } done: @@ -2957,7 +2966,7 @@ static void specific_scan_callback(int result, GSupplicantInterface *interface, 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); @@ -2971,6 +2980,8 @@ static void specific_scan_callback(int result, GSupplicantInterface *interface, CONNMAN_SERVICE_TYPE_WIFI, false); connman_device_unref(device); } + + start_roaming(wifi); } static int wifi_specific_scan(enum connman_service_type type, @@ -3917,7 +3928,7 @@ done: 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); @@ -3993,6 +4004,12 @@ static void disconnect_callback(int result, GSupplicantInterface *interface, 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; @@ -4012,9 +4029,8 @@ found: } #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 @@ -4184,7 +4200,10 @@ static void signalpoll_callback(int result, int maxspeed, int strength, 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 !"); @@ -4192,30 +4211,44 @@ static void signalpoll_callback(int result, int maxspeed, int strength, 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) @@ -4574,6 +4607,65 @@ static bool handle_wifi_assoc_retry(struct connman_network *network, 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) @@ -4634,6 +4726,8 @@ 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); @@ -4647,7 +4741,9 @@ static void interface_state(GSupplicantInterface *interface) #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); @@ -4681,6 +4777,7 @@ static void interface_state(GSupplicantInterface *interface) } g_hash_table_remove_all(failed_bssids); + handle_wifi_roaming_complete(network); #else /* though it should be already stopped: */ stop_autoscan(device); @@ -4722,7 +4819,7 @@ static void interface_state(GSupplicantInterface *interface) 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; @@ -4787,7 +4884,7 @@ static void interface_state(GSupplicantInterface *interface) 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); } diff --git a/src/dhcp.c b/src/dhcp.c index 5cef038..7c446cf 100644 --- a/src/dhcp.c +++ b/src/dhcp.c @@ -285,6 +285,14 @@ static void no_lease_cb(GDHCPClient *dhcp_client, gpointer user_data) dhcp->ipv4ll_client); #if defined TIZEN_EXT + if (dhcp->network && + connman_network_get_bool(dhcp->network, "WiFi.RoamingDHCP")) { + connman_network_set_bool(dhcp->network, "WiFi.RoamingDHCP", false); + __connman_network_enable_ipconfig(dhcp->network, dhcp->ipconfig); + + return; + } + if (connman_setting_get_bool("EnableAutoIp") == false) { DBG("link-local address autoconfiguration is disabled."); if (dhcp->network) @@ -563,6 +571,17 @@ static void lease_available_cb(GDHCPClient *dhcp_client, gpointer user_data) __connman_service_notify_ipv4_configuration(service); } +#if defined TIZEN_EXT + if (connman_network_get_bool(dhcp->network, "WiFi.RoamingDHCP")) { + + if (ip_change) + connman_service_notify_reconnection( + connman_service_lookup_from_network(dhcp->network)); + + connman_network_set_bool(dhcp->network, "WiFi.RoamingDHCP", false); + } +#endif + if (ip_change) { __connman_ipconfig_set_local(dhcp->ipconfig, address); __connman_ipconfig_set_prefixlen(dhcp->ipconfig, prefixlen); @@ -829,9 +848,15 @@ int __connman_dhcp_start(struct connman_ipconfig *ipconfig, dhcp->user_data = user_data; #if defined TIZEN_EXT - DBG("Start DHCP with DHCPDISCOVER request"); + if (connman_network_get_bool(network, "WiFi.RoamingDHCP")) { + const char *last_addr = __connman_ipconfig_get_dhcp_address(ipconfig); - return g_dhcp_client_start(dhcp->dhcp_client, NULL); + DBG("Start DHCP with last address request"); + return g_dhcp_client_start(dhcp->dhcp_client, last_addr); + } else { + DBG("Start DHCP with DHCPDISCOVER request"); + return g_dhcp_client_start(dhcp->dhcp_client, NULL); + } #else return g_dhcp_client_start(dhcp->dhcp_client, last_addr); #endif diff --git a/src/network.c b/src/network.c index 3bf6299..8eb8c1e 100755 --- a/src/network.c +++ b/src/network.c @@ -147,9 +147,11 @@ struct connman_network { int transition_mode_ssid_len; unsigned char transition_mode_bssid[WIFI_BSSID_LEN_MAX]; bool roaming_progress; + bool roaming_dhcp; char *roaming_cur_bssid; char *roaming_dst_bssid; __time_t roam_scan_time; + unsigned int max_bssid_count; int snr; #endif } wifi; @@ -600,7 +602,11 @@ static void remove_dhcp_timeout(struct connman_network *network) } } +#if defined TIZEN_EXT +int set_connected_dhcp(struct connman_network *network) +#else static int set_connected_dhcp(struct connman_network *network) +#endif { struct connman_service *service; struct connman_ipconfig *ipconfig_ipv4; @@ -1415,6 +1421,9 @@ struct connman_network * connman_network_ref_debug(struct connman_network *network, const char *file, int line, const char *caller) { +#if defined TIZEN_EXT + if (!simplified_log) +#endif DBG("%p name %s ref %d by %s:%d:%s()", network, network->name, network->refcount + 1, file, line, caller); @@ -1432,6 +1441,9 @@ connman_network_ref_debug(struct connman_network *network, void connman_network_unref_debug(struct connman_network *network, const char *file, int line, const char *caller) { +#if defined TIZEN_EXT + if (!simplified_log) +#endif DBG("%p name %s ref %d by %s:%d:%s()", network, network->name, network->refcount - 1, file, line, caller); @@ -2380,9 +2392,6 @@ 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], @@ -2601,9 +2610,15 @@ unsigned char *connman_network_get_countrycode(struct connman_network *network) int connman_network_set_bssid_list(struct connman_network *network, GSList *bssids) { + unsigned int max_bssid_count; + g_slist_free_full(network->wifi.bssid_list, g_free); network->wifi.bssid_list = bssids; + max_bssid_count = g_slist_length(bssids); + if (network->wifi.max_bssid_count < max_bssid_count) + network->wifi.max_bssid_count = max_bssid_count; + return 0; } @@ -2641,6 +2656,11 @@ void *connman_network_get_bssid_list(struct connman_network *network) return network->wifi.bssid_list; } +unsigned int connman_network_get_max_bssid_count(struct connman_network *network) +{ + return network->wifi.max_bssid_count; +} + int connman_network_set_last_connected_bssid(struct connman_network *network, const unsigned char *bssid) { @@ -3034,6 +3054,8 @@ int connman_network_set_bool(struct connman_network *network, network->wifi.owe_transition_mode = value; else if (g_strcmp0(key, "WiFi.Roaming") == 0) network->wifi.roaming_progress = value; + else if (g_strcmp0(key, "WiFi.RoamingDHCP") == 0) + network->wifi.roaming_dhcp = value; else if (g_strcmp0(key, "WiFi.PMFRequired") == 0) network->wifi.pmf_required = value; #endif @@ -3068,6 +3090,8 @@ bool connman_network_get_bool(struct connman_network *network, return network->wifi.owe_transition_mode; else if (g_str_equal(key, "WiFi.Roaming")) return network->wifi.roaming_progress; + else if (g_str_equal(key, "WiFi.RoamingDHCP")) + return network->wifi.roaming_dhcp; else if (g_str_equal(key, "WiFi.PMFRequired")) return network->wifi.pmf_required; #endif diff --git a/src/service.c b/src/service.c index 794555e..356a218 100755 --- a/src/service.c +++ b/src/service.c @@ -3196,7 +3196,7 @@ static void disconnection_requested_changed(struct connman_service *service) } void connman_service_set_disconnection_requested(struct connman_service *service, - bool disconnection_requested) + bool disconnection_requested) { if (service == NULL) return; @@ -3204,6 +3204,47 @@ void connman_service_set_disconnection_requested(struct connman_service *service service->disconnection_requested = disconnection_requested; disconnection_requested_changed(service); } + +static void connman_service_emit_state(struct connman_service *service, + enum connman_service_state state) +{ + const char *str; + enum connman_service_state cur_state = service->state; + + if (service->state != state) + service->state = state; + + str = state2string(service->state); + if (!str) { + service->state = cur_state; + return; + } + + DBG(" %s, %s", str, service->path); + + connman_dbus_property_changed_basic(service->path, + CONNMAN_SERVICE_INTERFACE, "State", + DBUS_TYPE_STRING, &str); + + emit_state_changed_with_properties(service); + service->state = cur_state; +} + +void connman_service_notify_reconnection(struct connman_service *service) +{ + if (!service) + return; + + if (service->state != CONNMAN_SERVICE_STATE_READY && + service->state != CONNMAN_SERVICE_STATE_ONLINE) + return; + + connman_service_emit_state(service, CONNMAN_SERVICE_STATE_CONFIGURATION); + connman_service_emit_state(service, CONNMAN_SERVICE_STATE_READY); + + if (service->state == CONNMAN_SERVICE_STATE_ONLINE) + connman_service_emit_state(service, CONNMAN_SERVICE_STATE_ONLINE); +} #endif static void strength_changed(struct connman_service *service) @@ -9147,6 +9188,50 @@ static void set_priority_connected_service(void) #endif } } + +static void emit_wifi_roaming_failure(struct connman_service *service, + enum connman_service_state new_state) +{ + 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: + case CONNMAN_SERVICE_STATE_READY: + case CONNMAN_SERVICE_STATE_ONLINE: + 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 static const char *get_dbus_sender(struct connman_service *service) @@ -9353,6 +9438,8 @@ static int service_indicate_state(struct connman_service *service) proxy_changed(service); #if defined TIZEN_EXT } + + emit_wifi_roaming_failure(service, new_state); #endif /* @@ -9393,55 +9480,7 @@ 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; - } - } - } + emit_wifi_roaming_failure(service, new_state); #endif __connman_connection_update_gateway(); -- 2.7.4