X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=plugins%2Fwifi.c;h=7c159963cd501ee4e8bf269216910bcb9a233673;hb=8bc9bcbb7e2faca54d135deb199b8844a4319c53;hp=c209da57844d075103e74b78d93e92e83b6a85a6;hpb=79ef996f2820cbaaa81d9200060f1bc537fce038;p=platform%2Fupstream%2Fconnman.git diff --git a/plugins/wifi.c b/plugins/wifi.c index c209da5..7c15996 100755 --- a/plugins/wifi.c +++ b/plugins/wifi.c @@ -59,11 +59,13 @@ #include +#include "src/shared/util.h" + #define CLEANUP_TIMEOUT 8 /* in seconds */ #define INACTIVE_TIMEOUT 12 /* in seconds */ #define FAVORITE_MAXIMUM_RETRIES 2 -#define BGSCAN_DEFAULT "simple:30:-45:300" +#define BGSCAN_DEFAULT "simple:30:-65:300" #define AUTOSCAN_EXPONENTIAL "exponential:3:300" #define AUTOSCAN_SINGLE "single:3" @@ -81,6 +83,29 @@ #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" +#define ROAM_SCAN_INTERVAL 60 /* 60 seconds */ #endif static struct connman_technology *wifi_technology = NULL; @@ -173,6 +198,9 @@ struct wifi_data { bool allow_full_scan; unsigned int automaxspeed_timeout; GSupplicantScanParams *hidden_scan_params; + unsigned int mac_policy; + unsigned int preassoc_mac_policy; + unsigned int mac_lifetime; #endif int disconnect_code; int assoc_code; @@ -2081,8 +2109,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, @@ -2092,7 +2169,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; @@ -2152,7 +2232,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; } @@ -2173,7 +2254,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); @@ -2204,8 +2286,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; @@ -2269,6 +2392,11 @@ static gboolean autoscan_timeout(gpointer data) autoscan = wifi->autoscan; +#if defined TIZEN_EXT + if (!autoscan) + return FALSE; +#endif + if (autoscan->interval <= 0) { interval = autoscan->base; goto set_interval; @@ -2390,6 +2518,18 @@ static void setup_autoscan(struct wifi_data *wifi) wifi->autoscan = parse_autoscan_params(AUTOSCAN_EXPONENTIAL); return; } +#if defined TIZEN_EXT + else { + if (wifi->autoscan) { + g_free(wifi->autoscan); + wifi->autoscan = NULL; + } + + DBG("BackgroundScanning is disabled"); + + return; + } +#else /* * On the contrary, if BackgroundScanning is disabled, update autoscan @@ -2413,6 +2553,7 @@ static void setup_autoscan(struct wifi_data *wifi) wifi->autoscan = parse_autoscan_params(AUTOSCAN_SINGLE); break; } +#endif } static void finalize_interface_creation(struct wifi_data *wifi) @@ -2476,6 +2617,11 @@ static int wifi_enable(struct connman_device *device) interface = connman_inet_ifname(index); ret = g_supplicant_interface_create(interface, driver, NULL, +#ifdef TIZEN_EXT + connman_device_get_mac_policy(device), + connman_device_get_preassoc_mac_policy(device), + connman_device_get_random_mac_lifetime(device), +#endif /* TIZEN_EXT */ interface_create_callback, wifi); g_free(interface); @@ -2601,7 +2747,7 @@ static int get_latest_connections(int max_ssids, g_key_file_free(keyfile); continue; } - g_time_val_from_iso8601(str, &modified); + util_iso8601_to_timeval(str, &modified); g_free(str); ssid = g_key_file_get_string(keyfile, @@ -2615,6 +2761,9 @@ static int get_latest_connections(int max_ssids, g_sequence_free(latest_list); g_key_file_free(keyfile); g_free(ssid); +#if defined TIZEN_EXT + g_strfreev(services); +#endif return -ENOMEM; } @@ -2937,6 +3086,99 @@ static int wifi_specific_scan(enum connman_service_type type, return ret; } + +static void wifi_mac_policy_callback(int result, + unsigned int policy, + void *user_data) +{ + struct connman_device *device = user_data; + + if (result == 0) + connman_device_mac_policy_notify(device, result, policy); + + connman_device_unref(device); +} + +int wifi_set_mac_policy(struct connman_device *device, unsigned int policy) +{ + struct wifi_data *wifi = connman_device_get_data(device); + int ret; + + if (!wifi) + return -EINVAL; + + connman_device_ref(device); + + ret = g_supplicant_interface_set_mac_policy(wifi->interface, + wifi_mac_policy_callback, + policy, device); + if (ret != 0) + connman_device_unref(device); + + return ret; +} + +static void wifi_preassoc_mac_policy_callback(int result, + unsigned int policy, + void *user_data) +{ + struct connman_device *device = user_data; + + if (result == 0) + connman_device_preassoc_mac_policy_notify(device, result, policy); + + connman_device_unref(device); +} + +int wifi_set_preassoc_mac_policy(struct connman_device *device, unsigned int policy) +{ + struct wifi_data *wifi = connman_device_get_data(device); + int ret; + + if (!wifi) + return -EINVAL; + + connman_device_ref(device); + + ret = g_supplicant_interface_set_preassoc_mac_policy(wifi->interface, + wifi_preassoc_mac_policy_callback, + policy, device); + if (ret != 0) + connman_device_unref(device); + + return ret; +} + +static void wifi_random_mac_lifetime_callback(int result, + unsigned int lifetime, + void *user_data) +{ + struct connman_device *device = user_data; + + if (result == 0) + connman_device_random_mac_lifetime_notify(device, result, lifetime); + + connman_device_unref(device); +} + +int wifi_set_random_mac_lifetime(struct connman_device *device, unsigned int lifetime) +{ + struct wifi_data *wifi = connman_device_get_data(device); + int ret; + + if (!wifi) + return -EINVAL; + + connman_device_ref(device); + + ret = g_supplicant_interface_set_random_mac_lifetime(wifi->interface, + wifi_random_mac_lifetime_callback, + lifetime, device); + if (ret != 0) + connman_device_unref(device); + + return ret; +} #endif #if defined TIZEN_EXT_WIFI_MESH @@ -2969,7 +3211,7 @@ static int mesh_scan(struct connman_device *device) wifi = connman_device_get_data(device); - if (!wifi->mesh_interface) + if (!wifi || !wifi->mesh_interface) return -ENOTSUP; mesh_info = wifi->mesh_info; @@ -3212,19 +3454,31 @@ static int wifi_scan(struct connman_device *device, connman_device_ref(device); reset_autoscan(device); - +#if defined TIZEN_EXT + /* + * When doing a full scan, stored hidden networks also need to be scanned + * so that we can autoconnect to them. + */ + if (params->force_full_scan) + ret = g_supplicant_interface_scan(wifi->interface, scan_params, + scan_callback_hidden, device); + else +#endif ret = g_supplicant_interface_scan(wifi->interface, scan_params, scan_callback, device); if (ret == 0) { connman_device_set_scanning(device, CONNMAN_SERVICE_TYPE_WIFI, true); #if defined TIZEN_EXT - /*To allow the Full Scan after ssid based scan, set the flag here - It is required because Tizen does not use the ConnMan specific - backgroung Scan feature.Tizen has added the BG Scan feature in - net-config. To sync with up ConnMan, we need to issue the Full Scan - after SSID specific scan.*/ - wifi->allow_full_scan = TRUE; + /* + * To allow the Full Scan after ssid based scan, set the flag here + * It is required because Tizen does not use the ConnMan specific + * backgroung Scan feature.Tizen has added the BG Scan feature in + * net-config. To sync with up ConnMan, we need to issue the Full Scan + * after SSID specific scan. + */ + if (!params->force_full_scan && !do_hidden) + wifi->allow_full_scan = TRUE; #endif } else { g_supplicant_free_scan_params(scan_params); @@ -3300,6 +3554,9 @@ static struct connman_device_driver wifi_ng_driver = { .set_regdom = wifi_set_regdom, #if defined TIZEN_EXT .specific_scan = wifi_specific_scan, + .set_mac_policy = wifi_set_mac_policy, + .set_preassoc_mac_policy = wifi_set_preassoc_mac_policy, + .set_random_mac_lifetime = wifi_set_random_mac_lifetime, #endif #if defined TIZEN_EXT_WIFI_MESH .abort_scan = mesh_abort_scan, @@ -3324,6 +3581,9 @@ static void system_killed(void) static int network_probe(struct connman_network *network) { +#if defined TIZEN_EXT + if (!simplified_log) +#endif DBG("network %p", network); return 0; @@ -3368,7 +3628,8 @@ static void connect_callback(int result, GSupplicantInterface *interface, DBG("network %p result %d", network, result); #if defined TIZEN_EXT - set_connman_bssid(RESET_BSSID, NULL); + const char *ifname = g_supplicant_interface_get_ifname(interface); + set_connman_bssid(RESET_BSSID, NULL, ifname); for (list = iface_list; list; list = list->next) { wifi = list->data; @@ -3381,6 +3642,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, @@ -3521,9 +3814,11 @@ static void ssid_init(GSupplicantSSID *ssid, struct connman_network *network) #endif #if defined TIZEN_EXT - if (set_connman_bssid(CHECK_BSSID, NULL) == 6) { + const char *ifname = connman_device_get_string( + connman_network_get_device(network), "Interface"); + if (set_connman_bssid(CHECK_BSSID, NULL, ifname) == 6) { ssid->bssid_for_connect_len = 6; - set_connman_bssid(GET_BSSID, (char *)ssid->bssid_for_connect); + set_connman_bssid(GET_BSSID, (char *)ssid->bssid_for_connect, ifname); DBG("BSSID : %02x:%02x:%02x:%02x:%02x:%02x", ssid->bssid_for_connect[0], ssid->bssid_for_connect[1], ssid->bssid_for_connect[2], ssid->bssid_for_connect[3], @@ -3539,8 +3834,8 @@ static void ssid_init(GSupplicantSSID *ssid, struct connman_network *network) * the user-specified bssid is tried only once at the beginning. * After that, the bssids in the list are tried in order. */ - if (set_connman_bssid(CHECK_BSSID, NULL) == 6) { - set_connman_bssid(RESET_BSSID, NULL); + if (set_connman_bssid(CHECK_BSSID, NULL, ifname) == 6) { + set_connman_bssid(RESET_BSSID, NULL, ifname); goto done; } @@ -3584,6 +3879,8 @@ done: if(g_strcmp0(ssid->eap, "fast") == 0) ssid->pac_file = g_strdup(WIFI_EAP_FAST_PAC_FILE); + + ssid->keymgmt = connman_network_get_keymgmt(network); #endif if (connman_setting_get_bool("BackgroundScanning")) @@ -3670,7 +3967,13 @@ found: return; } - if (wifi->network != wifi->pending_network) +#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; @@ -3817,12 +4120,21 @@ 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; + uint16_t freq = connman_network_get_frequency(network); if (result != 0) { DBG("Failed to get maxspeed from signalpoll !"); + connman_network_unref(network); return; } @@ -3830,12 +4142,36 @@ static void signalpoll_callback(int result, int maxspeed, int strength, if (strength > 100) strength = 100; - DBG("maxspeed = %d, strength = %d", maxspeed, strength); - if (network) { - connman_network_set_strength(network, (uint8_t)strength); - connman_network_set_maxspeed(network, maxspeed); - set_connection_mode(network, maxspeed); + 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); + + 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) + 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) + goto done; + + throw_wifi_scan(device, scan_callback); + connman_network_set_roam_scan_time(network, curr_time.tv_sec); } + +done: + connman_network_unref(network); } static int network_signalpoll(struct wifi_data *wifi) @@ -3846,6 +4182,8 @@ static int network_signalpoll(struct wifi_data *wifi) if (!wifi || !wifi->network) return -ENODEV; + wifi->network = connman_network_ref(wifi->network); + interface = wifi->interface; network = wifi->network; @@ -3867,6 +4205,10 @@ static gboolean autosignalpoll_timeout(gpointer data) if (ret < 0) { DBG("Fail to get max speed !!"); wifi->automaxspeed_timeout = 0; + + if (wifi->network) + connman_network_unref(wifi->network); + return FALSE; } @@ -3888,6 +4230,15 @@ static void interface_added(GSupplicantInterface *interface) { const char *ifname = g_supplicant_interface_get_ifname(interface); const char *driver = g_supplicant_interface_get_driver(interface); +#if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET + /* + * Note: If supplicant interface's driver is wired then skip it, + * because it meanti only for ethernet not Wi-Fi. + */ + if (!g_strcmp0("wired", g_supplicant_interface_get_driver(interface))) + return; +#endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */ + #if defined TIZEN_EXT bool is_5_0_ghz_supported = g_supplicant_interface_get_is_5_0_ghz_supported(interface); #endif @@ -3916,10 +4267,10 @@ static void interface_added(GSupplicantInterface *interface) connman_device_set_powered(wifi->device, true); #if defined TIZEN_EXT - connman_techonology_wifi_set_5ghz_supported(wifi_technology, is_5_0_ghz_supported); + connman_device_set_wifi_5ghz_supported(wifi->device, is_5_0_ghz_supported); /* Max number of SSIDs supported by wlan chipset that can be scanned */ int max_scan_ssids = g_supplicant_interface_get_max_scan_ssids(interface); - connman_techonology_set_max_scan_ssids(wifi_technology, max_scan_ssids); + connman_device_set_max_scan_ssids(wifi->device, max_scan_ssids); #endif } @@ -4162,6 +4513,15 @@ static void interface_state(GSupplicantInterface *interface) struct connman_device *device; struct wifi_data *wifi; GSupplicantState state = g_supplicant_interface_get_state(interface); +#if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET + /* + * Note: If supplicant interface's driver is wired then skip it, + * because it meanti only for ethernet not Wi-Fi. + */ + if (!g_strcmp0("wired", g_supplicant_interface_get_driver(interface))) + return; +#endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */ + bool wps; bool old_connected; @@ -4199,6 +4559,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); @@ -4287,9 +4654,21 @@ static void interface_state(GSupplicantInterface *interface) #if defined TIZEN_EXT if (handle_assoc_status_code(interface, wifi)) { - GSList *bssid_list = (GSList *)connman_network_get_bssid_list(network); + const char *group = connman_network_get_group(network); + GSupplicantNetwork *supplicant_network; + GSList *bssid_list = NULL; guint bssid_length = 0; + if (group) { + 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_update_assoc_reject(interface, supplicant_network); + } + + bssid_list = (GSList *)connman_network_get_bssid_list(network); if (bssid_list) bssid_length = g_slist_length(bssid_list); @@ -4414,6 +4793,15 @@ static void interface_removed(GSupplicantInterface *interface) { const char *ifname = g_supplicant_interface_get_ifname(interface); struct wifi_data *wifi; +#if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET + /* + * Note: If supplicant interface's driver is wired then skip it, + * because it meanti only for ethernet not Wi-Fi. + */ + if (!g_strcmp0("wired", g_supplicant_interface_get_driver(interface))) + return; +#endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */ + DBG("ifname %s", ifname); @@ -4482,6 +4870,15 @@ static void p2p_support(GSupplicantInterface *interface) { char dev_type[17] = {}; const char *hostname; +#if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET + /* + * Note: If supplicant interface's driver is wired then skip it, + * because it meanti only for ethernet not Wi-Fi. + */ + if (!g_strcmp0("wired", g_supplicant_interface_get_driver(interface))) + return; +#endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */ + DBG(""); @@ -4508,11 +4905,29 @@ static void p2p_support(GSupplicantInterface *interface) static void scan_started(GSupplicantInterface *interface) { +#if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET + /* + * Note: If supplicant interface's driver is wired then skip it, + * because it meanti only for ethernet not Wi-Fi. + */ + if (!g_strcmp0("wired", g_supplicant_interface_get_driver(interface))) + return; +#endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */ + DBG(""); } static void scan_finished(GSupplicantInterface *interface) { +#if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET + /* + * Note: If supplicant interface's driver is wired then skip it, + * because it meanti only for ethernet not Wi-Fi. + */ + if (!g_strcmp0("wired", g_supplicant_interface_get_driver(interface))) + return; +#endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */ + #if defined TIZEN_EXT struct wifi_data *wifi; bool is_associating = false; @@ -4549,6 +4964,15 @@ static void scan_finished(GSupplicantInterface *interface) static void ap_create_fail(GSupplicantInterface *interface) { +#if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET + /* + * Note: If supplicant interface's driver is wired then skip it, + * because it meanti only for ethernet not Wi-Fi. + */ + if (!g_strcmp0("wired", g_supplicant_interface_get_driver(interface))) + return; +#endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */ + struct wifi_data *wifi = g_supplicant_interface_get_data(interface); int ret; @@ -4679,6 +5103,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; @@ -4693,14 +5170,22 @@ static void network_added(GSupplicantNetwork *supplicant_network) bool wps_advertizing; #if defined TIZEN_EXT + bool owe_transition_mode; + 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 mode = g_supplicant_network_get_mode(supplicant_network); identifier = g_supplicant_network_get_identifier(supplicant_network); - +#if defined TIZEN_EXT + if (!simplified_log) +#endif DBG("%s", identifier); if (!g_strcmp0(mode, "adhoc")) @@ -4714,6 +5199,15 @@ static void network_added(GSupplicantNetwork *supplicant_network) #endif interface = g_supplicant_network_get_interface(supplicant_network); +#if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET + /* + * Note: If supplicant interface's driver is wired then skip it, + * because it meanti only for ethernet not Wi-Fi. + */ + if (!g_strcmp0("wired", g_supplicant_interface_get_driver(interface))) + return; +#endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */ + wifi = g_supplicant_interface_get_data(interface); name = g_supplicant_network_get_name(supplicant_network); security = g_supplicant_network_get_security(supplicant_network); @@ -4786,20 +5280,38 @@ 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); + connman_network_set_bool(network, "WiFi.TRANSITION_MODE", owe_transition_mode); + if (owe_transition_mode) { + transition_mode_ssid = (unsigned char *)g_supplicant_network_get_transition_mode_ssid(supplicant_network, &transition_mode_ssid_len); + connman_network_set_blob(network, "WiFi.TRANSITION_MODE_SSID", + transition_mode_ssid, transition_mode_ssid_len); + 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_keymgmt(network, keymgmt); connman_network_set_bool(network, "WiFi.HS20AP", g_supplicant_network_is_hs20AP(supplicant_network)); connman_network_set_bssid_list(network, (GSList *)g_supplicant_network_get_bssid_list(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)); #endif connman_network_set_available(network, true); connman_network_set_string(network, "WiFi.Mode", mode); @@ -4812,6 +5324,11 @@ static void network_added(GSupplicantNetwork *supplicant_network) connman_network_set_group(network, group); #if defined TIZEN_EXT + g_supplicant_network_set_last_connected_bssid(supplicant_network, + connman_network_get_last_connected_bssid(network)); +#endif + +#if defined TIZEN_EXT if (wifi_first_scan == true) found_with_first_scan = true; #endif @@ -4853,6 +5370,15 @@ static void network_removed(GSupplicantNetwork *network) #endif interface = g_supplicant_network_get_interface(network); +#if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET + /* + * Note: If supplicant interface's driver is wired then skip it, + * because it meanti only for ethernet not Wi-Fi. + */ + if (!g_strcmp0("wired", g_supplicant_interface_get_driver(interface))) + return; +#endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */ + wifi = g_supplicant_interface_get_data(interface); identifier = g_supplicant_network_get_identifier(network); name = g_supplicant_network_get_name(network); @@ -4903,11 +5429,25 @@ static void network_changed(GSupplicantNetwork *network, const char *property) #endif interface = g_supplicant_network_get_interface(network); +#if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET + /* + * Note: If supplicant interface's driver is wired then skip it, + * because it meanti only for ethernet not Wi-Fi. + */ + if (!g_strcmp0("wired", g_supplicant_interface_get_driver(interface))) + return; +#endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */ + wifi = g_supplicant_interface_get_data(interface); identifier = g_supplicant_network_get_identifier(network); name = g_supplicant_network_get_name(network); +#if defined TIZEN_EXT + if (!simplified_log) + DBG("name %s property %s", name, property); +#else DBG("name %s", name); +#endif if (!wifi) return; @@ -4947,7 +5487,40 @@ static void network_changed(GSupplicantNetwork *network, const char *property) connman_network_set_strength(connman_network, calculate_strength(network)); update_needed = true; - } else + } +#if defined TIZEN_EXT && defined TIZEN_EXT_INS + else if (g_str_equal(property, "LastConnectedBSSID")) { + const char *ident, *group; + char *service_ident; + bool need_save; + + ident = connman_device_get_ident(wifi->device); + group = connman_network_get_group(connman_network); + if (ident && group) { + service_ident = g_strdup_printf("%s_%s_%s", + __connman_network_get_type(connman_network), ident, group); + + need_save = connman_device_set_last_connected_ident(wifi->device, service_ident); + if (need_save) + connman_device_save_last_connected(wifi->device); + + g_free(service_ident); + } + + connman_network_set_last_connected_bssid(connman_network, + g_supplicant_network_get_last_connected_bssid(network)); + + update_needed = true; + } +#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)); + update_needed = true; + } +#endif + else update_needed = false; if (update_needed) @@ -4988,6 +5561,15 @@ static void network_associated(GSupplicantNetwork *network) interface = g_supplicant_network_get_interface(network); if (!interface) return; +#if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET + /* + * Note: If supplicant interface's driver is wired then skip it, + * because it meanti only for ethernet not Wi-Fi. + */ + if (!g_strcmp0("wired", g_supplicant_interface_get_driver(interface))) + return; +#endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */ + wifi = g_supplicant_interface_get_data(interface); if (!wifi) @@ -5006,7 +5588,22 @@ static void network_associated(GSupplicantNetwork *network) if (wifi->network) { if (wifi->network == connman_network) return; - +#if TIZEN_EXT + unsigned int ssid_len; + DBG("network1 ssid[%s] , OWE[%d],ssid[%s]", + (char *)connman_network_get_blob(wifi->network,"WiFi.SSID", &ssid_len), + connman_network_get_bool(wifi->network,"WiFi.TRANSITION_MODE"), + (char *)connman_network_get_blob(wifi->network,"WiFi.TRANSITION_MODE_SSID", &ssid_len)); + + DBG("network1 ssid[%s], OWE[%d], ssid[%s]", + (char *)connman_network_get_blob(connman_network,"WiFi.SSID",&ssid_len), + connman_network_get_bool(connman_network,"WiFi.TRANSITION_MODE"), + (char *)connman_network_get_blob(connman_network,"WiFi.TRANSITION_MODE_SSID", &ssid_len)); + if (connman_network_check_transition_mode(wifi->network, connman_network)) {//OWE trasition mode check + DBG("OWE transition mode is TRUE"); + return; + } +#endif /* * This should never happen, we got associated with * a network different than the one we were expecting. @@ -5034,6 +5631,15 @@ static void network_associated(GSupplicantNetwork *network) static void sta_authorized(GSupplicantInterface *interface, const char *addr) { +#if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET + /* + * Note: If supplicant interface's driver is wired then skip it, + * because it meanti only for ethernet not Wi-Fi. + */ + if (!g_strcmp0("wired", g_supplicant_interface_get_driver(interface))) + return; +#endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */ + struct wifi_data *wifi = g_supplicant_interface_get_data(interface); DBG("wifi %p station %s authorized", wifi, addr); @@ -5047,6 +5653,15 @@ static void sta_authorized(GSupplicantInterface *interface, static void sta_deauthorized(GSupplicantInterface *interface, const char *addr) { +#if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET + /* + * Note: If supplicant interface's driver is wired then skip it, + * because it meanti only for ethernet not Wi-Fi. + */ + if (!g_strcmp0("wired", g_supplicant_interface_get_driver(interface))) + return; +#endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */ + struct wifi_data *wifi = g_supplicant_interface_get_data(interface); DBG("wifi %p station %s deauthorized", wifi, addr); @@ -5282,6 +5897,15 @@ static void network_merged(GSupplicantNetwork *network) if (!interface) return; +#if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET + /* + * Note: If supplicant interface's driver is wired then skip it, + * because it meanti only for ethernet not Wi-Fi. + */ + if (!g_strcmp0("wired", g_supplicant_interface_get_driver(interface))) + return; +#endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */ + state = g_supplicant_interface_get_state(interface); if (state < G_SUPPLICANT_STATE_AUTHENTICATING) return; @@ -5339,17 +5963,60 @@ static void assoc_failed(void *user_data) struct connman_network *network = user_data; connman_network_set_associating(network, false); } + +static void scan_done(GSupplicantInterface *interface) +{ +#if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET + /* + * Note: If supplicant interface's driver is wired then skip it, + * because it meanti only for ethernet not Wi-Fi. + */ + if (!g_strcmp0("wired", g_supplicant_interface_get_driver(interface))) + return; +#endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */ + + GList *list; + int scan_type = CONNMAN_SCAN_TYPE_WPA_SUPPLICANT; + struct wifi_data *wifi; + bool scanning; + + for (list = iface_list; list; list = list->next) { + wifi = list->data; + + if (interface == wifi->interface) { + scanning = connman_device_get_scanning(wifi->device, + CONNMAN_SERVICE_TYPE_WIFI); + if (!scanning) + __connman_technology_notify_scan_done( + connman_device_get_string(wifi->device, "Interface"), scan_type); + break; + } + } +} #endif static void debug(const char *str) { +#if defined TIZEN_EXT + if (connman_setting_get_bool("ConnmanSupplicantDebug")) +#else if (getenv("CONNMAN_SUPPLICANT_DEBUG")) +#endif connman_debug("%s", str); } static void disconnect_reasoncode(GSupplicantInterface *interface, int reasoncode) { +#if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET + /* + * Note: If supplicant interface's driver is wired then skip it, + * because it meanti only for ethernet not Wi-Fi. + */ + if (!g_strcmp0("wired", g_supplicant_interface_get_driver(interface))) + return; +#endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */ + struct wifi_data *wifi = g_supplicant_interface_get_data(interface); if (wifi != NULL) { @@ -5359,6 +6026,15 @@ static void disconnect_reasoncode(GSupplicantInterface *interface, static void assoc_status_code(GSupplicantInterface *interface, int status_code) { +#if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET + /* + * Note: If supplicant interface's driver is wired then skip it, + * because it meanti only for ethernet not Wi-Fi. + */ + if (!g_strcmp0("wired", g_supplicant_interface_get_driver(interface))) + return; +#endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */ + struct wifi_data *wifi = g_supplicant_interface_get_data(interface); if (wifi != NULL) { @@ -5366,7 +6042,11 @@ static void assoc_status_code(GSupplicantInterface *interface, int status_code) } } +#if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET +static GSupplicantCallbacks callbacks = { +#else /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */ static const GSupplicantCallbacks callbacks = { +#endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */ .system_ready = system_ready, .system_killed = system_killed, .interface_added = interface_added, @@ -5388,8 +6068,9 @@ static const GSupplicantCallbacks callbacks = { .peer_request = peer_request, #if defined TIZEN_EXT .system_power_off = system_power_off, - .network_merged = network_merged, + .network_merged = network_merged, .assoc_failed = assoc_failed, + .scan_done = scan_done, #endif .debug = debug, .disconnect_reasoncode = disconnect_reasoncode, @@ -5537,6 +6218,9 @@ static void sta_remove_callback(int result, info->wifi->interface = NULL; g_supplicant_interface_create(info->ifname, driver, info->wifi->bridge, +#ifdef TIZEN_EXT + 0, 0, 60, +#endif /* TIZEN_EXT */ ap_create_callback, info); } @@ -5703,6 +6387,33 @@ 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 && defined TIZEN_EXT_INS +static void supp_ins_init(void) +{ + const char *string; + GSupplicantINSPreferredFreq preferred_freq; + + string = connman_option_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) + preferred_freq = G_SUPPLICANT_INS_PREFERRED_FREQ_24GHZ; + else + preferred_freq = G_SUPPLICANT_INS_PREFERRED_FREQ_UNKNOWN; + + g_supplicant_set_ins_settings(preferred_freq, + connman_setting_get_bool("INSLastConnectedBSSID"), + connman_setting_get_bool("INSAssocReject"), + connman_setting_get_bool("INSSignalBSSID"), + connman_setting_get_uint("INSPreferredFreqBSSIDScore"), + connman_setting_get_uint("INSLastConnectedBSSIDScore"), + connman_setting_get_uint("INSAssocRejectScore"), + connman_setting_get_int("INSSignalLevel3_5GHz"), + connman_setting_get_int("INSSignalLevel3_24GHz") + ); +} +#endif /* defined TIZEN_EXT && defined TIZEN_EXT_INS */ + static struct connman_technology_driver tech_driver = { .name = "wifi", .type = CONNMAN_SERVICE_TYPE_WIFI, @@ -5736,6 +6447,10 @@ static int wifi_init(void) #if defined TIZEN_EXT failed_bssids = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); #endif + +#if defined TIZEN_EXT && defined TIZEN_EXT_INS + supp_ins_init(); +#endif /* defined TIZEN_EXT && defined TIZEN_EXT_INS */ return 0; }