X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=plugins%2Fwifi.c;h=7a8eccce4f4b907e5598455dfe298a02c1f325ad;hb=78968dd624e95b9e5f8280464c2613e0e920d8cf;hp=821681627f51c690a6d1c070fa6d95ee2baad9b8;hpb=7ef7e96fc2f3eb620fffb6f277339214efe83747;p=platform%2Fupstream%2Fconnman.git diff --git a/plugins/wifi.c b/plugins/wifi.c index 8216816..7a8eccc 100755 --- a/plugins/wifi.c +++ b/plugins/wifi.c @@ -49,7 +49,6 @@ #include #include #include -#include #include #include #include @@ -68,12 +67,14 @@ #define BGSCAN_DEFAULT "simple:30:-65:300" #define AUTOSCAN_EXPONENTIAL "exponential:3:300" #define AUTOSCAN_SINGLE "single:3" +#define SCAN_MAX_DURATION 10 #define P2P_FIND_TIMEOUT 30 #define P2P_CONNECTION_TIMEOUT 100 #define P2P_LISTEN_PERIOD 500 #define P2P_LISTEN_INTERVAL 2000 +#define ASSOC_STATUS_AUTH_TIMEOUT 16 #define ASSOC_STATUS_NO_CLIENT 17 #if defined TIZEN_EXT #define LOAD_SHAPING_MAX_RETRIES 7 @@ -83,6 +84,26 @@ #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 ROAM_SCAN_INTERVAL 60 /* 60 seconds */ #endif static struct connman_technology *wifi_technology = NULL; @@ -187,6 +208,11 @@ struct wifi_data { #endif }; +struct disconnect_data { + struct wifi_data *wifi; + struct connman_network *network; +}; + #if defined TIZEN_EXT #include "connman.h" #include "dbus.h" @@ -200,7 +226,6 @@ static GHashTable *failed_bssids = NULL; static unsigned char buff_bssid[WIFI_BSSID_LEN_MAX] = { 0, }; #endif - static GList *iface_list = NULL; static GList *pending_wifi_device = NULL; @@ -1130,15 +1155,23 @@ static GSupplicantP2PServiceParams *fill_in_peer_service_params( if (version > 0) { params->version = version; - params->service = g_memdup(spec, spec_length); + if (spec_length > 0) { + params->service = g_malloc(spec_length); + memcpy(params->service, spec, spec_length); + } } else if (query_length > 0 && spec_length > 0) { - params->query = g_memdup(query, query_length); + params->query = g_malloc(query_length); + memcpy(params->query, query, query_length); params->query_length = query_length; - params->response = g_memdup(spec, spec_length); + params->response = g_malloc(spec_length); + memcpy(params->response, spec, spec_length); params->response_length = spec_length; } else { - params->wfd_ies = g_memdup(spec, spec_length); + if (spec_length > 0) { + params->wfd_ies = g_malloc(spec_length); + memcpy(params->wfd_ies, spec, spec_length); + } params->wfd_ies_length = spec_length; } @@ -1410,14 +1443,15 @@ static void wifi_newlink(unsigned flags, unsigned change, void *user_data) } if ((wifi->flags & IFF_LOWER_UP) != (flags & IFF_LOWER_UP)) { - if (flags & IFF_LOWER_UP) { + if (flags & IFF_LOWER_UP) DBG("carrier on"); - - handle_tethering(wifi); - } else + else DBG("carrier off"); } + if (flags & IFF_LOWER_UP) + handle_tethering(wifi); + wifi->flags = flags; } @@ -1973,11 +2007,14 @@ static int get_hidden_connections_params(struct wifi_data *wifi, scan_params->num_ssids = i; scan_params->ssids = g_slist_reverse(scan_params->ssids); - scan_params->freqs = g_memdup(orig_params->freqs, - sizeof(uint16_t) * orig_params->num_freqs); - if (!scan_params->freqs) + if (orig_params->num_freqs <= 0) goto err; + scan_params->freqs = + g_malloc(sizeof(uint16_t) * orig_params->num_freqs); + memcpy(scan_params->freqs, orig_params->freqs, + sizeof(uint16_t) *orig_params->num_freqs); + scan_params->num_freqs = orig_params->num_freqs; } else @@ -2086,8 +2123,110 @@ 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); + +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, @@ -2157,7 +2296,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; } @@ -2178,7 +2318,8 @@ static void scan_callback(int result, GSupplicantInterface *interface, /* On error, let's recall scan_callback, which will cleanup */ return scan_callback(ret, interface, user_data); } - } + } else + wifi->allow_full_scan = false; #endif scanning = connman_device_get_scanning(device, CONNMAN_SERVICE_TYPE_WIFI); @@ -2205,12 +2346,18 @@ static void scan_callback(int result, GSupplicantInterface *interface, connman_device_unref(device); #if defined TIZEN_EXT - if (wifi && wifi->scan_pending_network && result != -EIO) { + if (!wifi) + goto done; + + if (wifi->scan_pending_network && result != -EIO) { network_connect(wifi->scan_pending_network); wifi->scan_pending_network = NULL; connman_network_set_connecting(wifi->network); + } else { + start_roaming(wifi); } +done: if (is_wifi_notifier_registered != true && wifi_first_scan == true && found_with_first_scan == true) { wifi_first_scan = false; @@ -2463,6 +2610,8 @@ static void interface_create_callback(int result, void *user_data) { struct wifi_data *wifi = user_data; + char *bgscan_range_max; + long value; DBG("result %d ifname %s, wifi %p", result, g_supplicant_interface_get_ifname(interface), @@ -2478,6 +2627,24 @@ static void interface_create_callback(int result, wifi->interface_ready = true; finalize_interface_creation(wifi); } + + /* + * Set the BSS expiration age to match the long scanning + * interval to avoid the loss of unconnected networks between + * two scans. + */ + bgscan_range_max = strrchr(BGSCAN_DEFAULT, ':'); + if (!bgscan_range_max || strlen(bgscan_range_max) < 1) + return; + + value = strtol(bgscan_range_max + 1, NULL, 10); + if (value <= 0 || errno == ERANGE) + return; + + if (g_supplicant_interface_set_bss_expiration_age(interface, + value + SCAN_MAX_DURATION) < 0) { + connman_warn("Failed to set bss expiration age"); + } } static int wifi_enable(struct connman_device *device) @@ -2485,7 +2652,7 @@ static int wifi_enable(struct connman_device *device) struct wifi_data *wifi = connman_device_get_data(device); int index; char *interface; - const char *driver = connman_option_get_string("wifi"); + const char *driver = connman_setting_get_string("wifi"); int ret; DBG("device %p %p", device, wifi); @@ -2799,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); @@ -2813,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, @@ -3524,6 +3693,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, @@ -3727,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); @@ -3784,11 +3985,13 @@ static int network_connect(struct connman_network *network) static void disconnect_callback(int result, GSupplicantInterface *interface, void *user_data) { + struct disconnect_data *dd = user_data; + struct connman_network *network = dd->network; #if defined TIZEN_EXT GList *list; - struct wifi_data *wifi; - struct connman_network *network = user_data; + struct wifi_data *wifi = NULL; + g_free(dd); DBG("network %p result %d", network, result); for (list = iface_list; list; list = list->next) { @@ -3801,27 +4004,46 @@ static void disconnect_callback(int result, GSupplicantInterface *interface, goto found; } + if (wifi && network == wifi->pending_network) + wifi->pending_network = NULL; + /* wifi_data may be invalid because wifi is already disabled */ return; found: #else - struct wifi_data *wifi = user_data; + struct wifi_data *wifi = dd->wifi; + g_free(dd); #endif - DBG("result %d supplicant interface %p wifi %p", - result, interface, wifi); + DBG("result %d supplicant interface %p wifi %p networks: current %p " + "pending %p disconnected %p", result, interface, wifi, + wifi->network, wifi->pending_network, network); if (result == -ECONNABORTED) { DBG("wifi interface no longer available"); return; } - if (wifi->network && wifi->network != wifi->pending_network) - connman_network_set_connected(wifi->network, false); - wifi->network = NULL; +#if defined TIZEN_EXT + if (g_slist_find(wifi->networks, network) && + wifi->network != wifi->pending_network) +#else + if (g_slist_find(wifi->networks, network)) +#endif + connman_network_set_connected(network, false); wifi->disconnecting = false; + + if (network != wifi->network) { + if (network == wifi->pending_network) + wifi->pending_network = NULL; + DBG("current wifi network has changed since disconnection"); + return; + } + + wifi->network = NULL; + wifi->connected = false; if (wifi->pending_network) { @@ -3835,6 +4057,7 @@ found: static int network_disconnect(struct connman_network *network) { struct connman_device *device = connman_network_get_device(network); + struct disconnect_data *dd; struct wifi_data *wifi; int err; #if defined TIZEN_EXT @@ -3877,16 +4100,16 @@ static int network_disconnect(struct connman_network *network) wifi->disconnecting = true; -#if defined TIZEN_EXT - err = g_supplicant_interface_disconnect(wifi->interface, - disconnect_callback, network); -#else - err = g_supplicant_interface_disconnect(wifi->interface, - disconnect_callback, wifi); -#endif + dd = g_malloc0(sizeof(*dd)); + dd->wifi = wifi; + dd->network = network; - if (err < 0) + err = g_supplicant_interface_disconnect(wifi->interface, + disconnect_callback, dd); + if (err < 0) { wifi->disconnecting = false; + g_free(dd); + } return err; } @@ -3964,9 +4187,20 @@ static void set_connection_mode(struct connman_network *network, } static void signalpoll_callback(int result, int maxspeed, int strength, - void *user_data) -{ + int snr, void *user_data) +{ + char bssid_buff[WIFI_BSSID_STR_LEN] = {0,}; + char *bssid_str = bssid_buff; + unsigned char *bssid; + struct timespec curr_time = {0}; + __time_t roam_scan_time; + const char *interface = NULL; + struct connman_device *device; struct connman_network *network = user_data; + GSupplicantNetwork *supplicant_network; + struct wifi_data *wifi = NULL; + 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 !"); @@ -3974,16 +4208,54 @@ 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 && wifi) { + 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("maxspeed = %d, strength = %d", maxspeed, strength); + 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 (device && need_bss_transition(freq, snr, strength)) { + + interface = connman_device_get_string(device, "Interface"); + __connman_technology_notify_roaming_state(interface, "required", bssid_str, NULL); + + if (connman_setting_get_bool("WifiRoamingScan") == false) + goto done; + + throw_wifi_scan(device, scan_callback); + connman_network_set_roam_scan_time(network, curr_time.tv_sec); + } + +done: connman_network_unref(network); } @@ -4021,6 +4293,7 @@ static gboolean autosignalpoll_timeout(gpointer data) if (wifi->network) connman_network_unref(wifi->network); + return FALSE; } @@ -4150,6 +4423,7 @@ static bool handle_wps_completion(GSupplicantInterface *interface, if (wps) { const unsigned char *ssid, *wps_ssid; unsigned int ssid_len, wps_ssid_len; + struct disconnect_data *dd; const char *wps_key; /* Checking if we got associated with requested @@ -4162,16 +4436,16 @@ static bool handle_wps_completion(GSupplicantInterface *interface, if (!wps_ssid || wps_ssid_len != ssid_len || memcmp(ssid, wps_ssid, ssid_len) != 0) { + dd = g_malloc0(sizeof(*dd)); + dd->wifi = wifi; + dd->network = network; + connman_network_set_associating(network, false); -#if defined TIZEN_EXT g_supplicant_interface_disconnect(wifi->interface, - disconnect_callback, wifi->network); - + disconnect_callback, dd); +#if defined TIZEN_EXT connman_network_set_bool(network, "WiFi.UseWPS", false); connman_network_set_string(network, "WiFi.PinWPS", NULL); -#else - g_supplicant_interface_disconnect(wifi->interface, - disconnect_callback, wifi); #endif return false; } @@ -4214,10 +4488,12 @@ static bool handle_wps_completion(GSupplicantInterface *interface, static bool handle_assoc_status_code(GSupplicantInterface *interface, struct wifi_data *wifi) { - if (wifi->state == G_SUPPLICANT_STATE_ASSOCIATING && #if defined TIZEN_EXT - wifi->assoc_code > 0 && + if ((wifi->state == G_SUPPLICANT_STATE_ASSOCIATING || + wifi->state == G_SUPPLICANT_STATE_AUTHENTICATING || + wifi->state == G_SUPPLICANT_STATE_ASSOCIATED) && #else + if (wifi->state == G_SUPPLICANT_STATE_ASSOCIATING && wifi->assoc_code == ASSOC_STATUS_NO_CLIENT && #endif wifi->load_shaping_retries < LOAD_SHAPING_MAX_RETRIES) { @@ -4232,10 +4508,10 @@ static bool handle_4way_handshake_failure(GSupplicantInterface *interface, struct connman_network *network, struct wifi_data *wifi) { -#if defined TIZEN_EXT - const char *security; struct connman_service *service; +#if defined TIZEN_EXT + const char *security; if (wifi->connected) return false; @@ -4252,9 +4528,9 @@ static bool handle_4way_handshake_failure(GSupplicantInterface *interface, if (wifi->state != G_SUPPLICANT_STATE_4WAY_HANDSHAKE) return false; #else - struct connman_service *service; - - if (wifi->state != G_SUPPLICANT_STATE_4WAY_HANDSHAKE) + if ((wifi->state != G_SUPPLICANT_STATE_4WAY_HANDSHAKE) && + !((wifi->state == G_SUPPLICANT_STATE_ASSOCIATING) && + (wifi->assoc_code == ASSOC_STATUS_AUTH_TIMEOUT))) return false; if (wifi->connected) @@ -4290,7 +4566,8 @@ static bool handle_wifi_assoc_retry(struct connman_network *network, return false; } - if (wifi->state != G_SUPPLICANT_STATE_ASSOCIATING && + if (wifi->state != G_SUPPLICANT_STATE_AUTHENTICATING && + wifi->state != G_SUPPLICANT_STATE_ASSOCIATING && wifi->state != G_SUPPLICANT_STATE_ASSOCIATED) { wifi->assoc_retry_count = 0; return false; @@ -4310,13 +4587,82 @@ static bool handle_wifi_assoc_retry(struct connman_network *network, * however QA team recommends that the invalid-key error * might be better to display for user experience. */ - connman_network_set_error(network, CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL); + switch (wifi->state) { + case G_SUPPLICANT_STATE_AUTHENTICATING: + connman_network_set_error(network, CONNMAN_NETWORK_ERROR_AUTHENTICATE_FAIL); + break; + case G_SUPPLICANT_STATE_ASSOCIATED: + connman_network_set_error(network, CONNMAN_NETWORK_ERROR_INVALID_KEY); + break; + default: + connman_network_set_error(network, CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL); + break; + } return 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) @@ -4371,6 +4717,15 @@ 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!!"); + } + + if (!connman_network_get_bool(wifi->network, "WiFi.Roaming")) +#endif if (wifi->connected) connman_network_set_connected(network, false); @@ -4383,7 +4738,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); @@ -4417,6 +4774,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); @@ -4458,7 +4816,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; @@ -4468,7 +4826,7 @@ static void interface_state(GSupplicantInterface *interface) supplicant_network = g_supplicant_interface_get_network(interface, group); connman_network_set_assoc_reject_table(network, - g_supplicant_network_get_assoc_reject_table(supplicant_network)); + g_supplicant_network_clone_assoc_reject_table(supplicant_network)); g_supplicant_network_update_assoc_reject(interface, supplicant_network); } @@ -4501,9 +4859,10 @@ static void interface_state(GSupplicantInterface *interface) /* See table 8-36 Reason codes in IEEE Std 802.11 */ switch (wifi->disconnect_code) { +#if defined TIZEN_EXT case 1: /* Unspecified reason */ /* Let's assume it's because we got blocked */ - +#endif case 6: /* Class 2 frame received from nonauthenticated STA */ connman_network_set_error(network, CONNMAN_NETWORK_ERROR_BLOCKED); @@ -4522,7 +4881,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); } @@ -4908,6 +5267,59 @@ static void mesh_peer_removed(GSupplicantNetwork *supplicant_network) } #endif + +#if defined TIZEN_EXT +static GSList *get_supported_security_list(unsigned int keymgmt, + bool owe_transition_mode, + GSupplicantNetwork *supplicant_network) +{ + GSList *sec_list = NULL; + dbus_bool_t privacy = g_supplicant_network_get_privacy(supplicant_network); + const char *enc_mode = g_supplicant_network_get_enc_mode(supplicant_network); + + if (keymgmt & + (G_SUPPLICANT_KEYMGMT_WPA_EAP | + G_SUPPLICANT_KEYMGMT_WPA_EAP_256)) + sec_list = g_slist_prepend (sec_list, "ieee8021x"); + else if (keymgmt & G_SUPPLICANT_KEYMGMT_WPA_FT_EAP) + sec_list = g_slist_prepend (sec_list, "ft_ieee8021x"); + + if (sec_list) + return sec_list; + + if (keymgmt & + (G_SUPPLICANT_KEYMGMT_WPA_PSK | + G_SUPPLICANT_KEYMGMT_WPA_PSK_256)) { + if (!g_strcmp0(enc_mode, "aes")) + sec_list = g_slist_prepend (sec_list, "rsn"); + else if (!g_strcmp0(enc_mode, "tkip")) + sec_list = g_slist_prepend (sec_list, "psk"); + else if (!g_strcmp0(enc_mode, "mixed")) { + sec_list = g_slist_prepend (sec_list, "psk"); + sec_list = g_slist_prepend (sec_list, "rsn"); + } + } else if (keymgmt & G_SUPPLICANT_KEYMGMT_WPA_FT_PSK) + sec_list = g_slist_prepend (sec_list, "ft_psk"); + + if (keymgmt & G_SUPPLICANT_KEYMGMT_SAE) + sec_list = g_slist_prepend (sec_list, "sae"); + if (keymgmt & G_SUPPLICANT_KEYMGMT_OWE || owe_transition_mode) + sec_list = g_slist_prepend (sec_list, "owe"); + if (keymgmt & G_SUPPLICANT_KEYMGMT_DPP) + sec_list = g_slist_prepend (sec_list, "dpp"); + + if (sec_list) + return sec_list; + + if (privacy) + sec_list = g_slist_prepend (sec_list, "wep"); + else + sec_list = g_slist_prepend (sec_list, "none"); + + return sec_list; +} +#endif + static void network_added(GSupplicantNetwork *supplicant_network) { struct connman_network *network; @@ -4926,7 +5338,9 @@ static void network_added(GSupplicantNetwork *supplicant_network) const unsigned char *transition_mode_ssid; const unsigned char *transition_mode_bssid; unsigned int transition_mode_ssid_len; + unsigned int keymgmt; GSList *vsie_list = NULL; + GSList *sec_list = NULL; const unsigned char *country_code; ieee80211_modes_e phy_mode; #endif @@ -5030,6 +5444,7 @@ static void network_added(GSupplicantNetwork *supplicant_network) g_supplicant_network_get_frequency(supplicant_network)); #if defined TIZEN_EXT + keymgmt = g_supplicant_network_get_keymgmt(supplicant_network); connman_network_set_bssid(network, g_supplicant_network_get_bssid(supplicant_network)); owe_transition_mode = (bool)g_supplicant_network_get_transition_mode(supplicant_network); @@ -5041,14 +5456,20 @@ static void network_added(GSupplicantNetwork *supplicant_network) transition_mode_bssid = g_supplicant_network_get_transition_mode_bssid(supplicant_network); connman_network_set_transition_mode_bssid(network, transition_mode_bssid); } + + sec_list = get_supported_security_list(keymgmt, + owe_transition_mode, supplicant_network); + + connman_network_set_sec_list(network, sec_list); connman_network_set_maxrate(network, g_supplicant_network_get_maxrate(supplicant_network)); connman_network_set_enc_mode(network, g_supplicant_network_get_enc_mode(supplicant_network)); connman_network_set_rsn_mode(network, g_supplicant_network_get_rsn_mode(supplicant_network)); - connman_network_set_keymgmt(network, - g_supplicant_network_get_keymgmt(supplicant_network)); + connman_network_set_bool(network, "WiFi.PMFRequired", + (bool)g_supplicant_network_is_pmf_required(supplicant_network)); + connman_network_set_keymgmt(network, keymgmt); connman_network_set_bool(network, "WiFi.HS20AP", g_supplicant_network_is_hs20AP(supplicant_network)); connman_network_set_bssid_list(network, @@ -5056,7 +5477,7 @@ static void network_added(GSupplicantNetwork *supplicant_network) connman_network_set_last_connected_bssid(network, g_supplicant_network_get_last_connected_bssid(supplicant_network)); connman_network_set_assoc_reject_table(network, - g_supplicant_network_get_assoc_reject_table(supplicant_network)); + g_supplicant_network_clone_assoc_reject_table(supplicant_network)); #endif connman_network_set_available(network, true); connman_network_set_string(network, "WiFi.Mode", mode); @@ -5233,7 +5654,7 @@ static void network_changed(GSupplicantNetwork *network, const char *property) calculate_strength(network)); update_needed = true; } -#if defined TIZEN_EXT +#if defined TIZEN_EXT && defined TIZEN_EXT_INS else if (g_str_equal(property, "LastConnectedBSSID")) { const char *ident, *group; char *service_ident; @@ -5256,9 +5677,12 @@ static void network_changed(GSupplicantNetwork *network, const char *property) g_supplicant_network_get_last_connected_bssid(network)); update_needed = true; - } else if (g_str_equal(property, "UpdateAssocReject")) { + } +#endif /* defined TIZEN_EXT && defined TIZEN_EXT_INS */ +#if defined TIZEN_EXT + else if (g_str_equal(property, "UpdateAssocReject")) { connman_network_set_assoc_reject_table(connman_network, - g_supplicant_network_get_assoc_reject_table(network)); + g_supplicant_network_clone_assoc_reject_table(network)); update_needed = true; } #endif @@ -5937,7 +6361,7 @@ static void sta_remove_callback(int result, void *user_data) { struct wifi_tethering_info *info = user_data; - const char *driver = connman_option_get_string("wifi"); + const char *driver = connman_setting_get_string("wifi"); DBG("ifname %s result %d ", info->ifname, result); @@ -6129,13 +6553,13 @@ static int tech_set_regdom(struct connman_technology *technology, const char *al return g_supplicant_set_country(alpha2, regdom_callback, NULL); } -#if defined TIZEN_EXT +#if defined TIZEN_EXT && defined TIZEN_EXT_INS static void supp_ins_init(void) { const char *string; GSupplicantINSPreferredFreq preferred_freq; - string = connman_option_get_string("INSPreferredFreqBSSID"); + string = connman_setting_get_string("INSPreferredFreqBSSID"); if (g_strcmp0(string, "5GHz") == 0) preferred_freq = G_SUPPLICANT_INS_PREFERRED_FREQ_5GHZ; else if (g_strcmp0(string, "2.4GHz") == 0) @@ -6154,7 +6578,7 @@ static void supp_ins_init(void) connman_setting_get_int("INSSignalLevel3_24GHz") ); } -#endif +#endif /* defined TIZEN_EXT && defined TIZEN_EXT_INS */ static struct connman_technology_driver tech_driver = { .name = "wifi", @@ -6190,9 +6614,9 @@ static int wifi_init(void) failed_bssids = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); #endif -#if defined TIZEN_EXT +#if defined TIZEN_EXT && defined TIZEN_EXT_INS supp_ins_init(); -#endif +#endif /* defined TIZEN_EXT && defined TIZEN_EXT_INS */ return 0; }