diff options
author | Jaehyun Kim <jeik01.kim@samsung.com> | 2018-11-06 10:38:29 +0000 |
---|---|---|
committer | Gerrit Code Review <gerrit@review.ap-northeast-2.compute.internal> | 2018-11-06 10:38:29 +0000 |
commit | bf7dbf8354f076ec768ae24e61d6fb1e46c623af (patch) | |
tree | 69162a64189dd08a7d4198cd3aa03c047645b09d | |
parent | 271ae828d35c8814e18b3de80cb835513640c0db (diff) | |
parent | 3c5d316b64f60ee6fb7b2bb85c22fad385cb0f91 (diff) | |
download | connman-bf7dbf8354f076ec768ae24e61d6fb1e46c623af.tar.gz connman-bf7dbf8354f076ec768ae24e61d6fb1e46c623af.tar.bz2 connman-bf7dbf8354f076ec768ae24e61d6fb1e46c623af.zip |
Merge "Add IEEE 802.11 protocol(b/g/n/a/ac) Modes of APs" into tizensubmit/tizen/20181127.113629submit/tizen/20181120.123835submit/tizen/20181106.114249accepted/tizen/unified/20181129.054222
-rw-r--r-- | gsupplicant/gsupplicant.h | 11 | ||||
-rw-r--r-- | gsupplicant/supplicant.c | 116 | ||||
-rwxr-xr-x | include/network.h | 29 | ||||
-rw-r--r-- | plugins/wifi.c | 81 | ||||
-rw-r--r-- | src/connman.h | 1 | ||||
-rwxr-xr-x | src/network.c | 30 | ||||
-rw-r--r-- | src/service.c | 4 |
7 files changed, 271 insertions, 1 deletions
diff --git a/gsupplicant/gsupplicant.h b/gsupplicant/gsupplicant.h index 035789e5..597fe751 100644 --- a/gsupplicant/gsupplicant.h +++ b/gsupplicant/gsupplicant.h @@ -135,6 +135,16 @@ typedef enum { G_SUPPLICANT_EAP_KEYMGMT_CCKM, G_SUPPLICANT_EAP_KEYMGMT_OKC, } GSupplicantEapKeymgmt; + +typedef enum { + G_SUPPLICANT_MODE_IEEE80211_UNKNOWN, + G_SUPPLICANT_MODE_IEEE80211B, + G_SUPPLICANT_MODE_IEEE80211BG, + G_SUPPLICANT_MODE_IEEE80211BGN, + G_SUPPLICANT_MODE_IEEE80211A, + G_SUPPLICANT_MODE_IEEE80211AN, + G_SUPPLICANT_MODE_IEEE80211ANAC, +} GSupplicantPhy_mode; #endif typedef enum { @@ -458,6 +468,7 @@ void *g_supplicant_network_get_wifi_vsie(GSupplicantNetwork *network); const unsigned char *g_supplicant_network_get_countrycode(GSupplicantNetwork *network); void *g_supplicant_network_get_bssid_list(GSupplicantNetwork *network); +GSupplicantPhy_mode g_supplicant_network_get_phy_mode(GSupplicantNetwork *network); #endif struct _GSupplicantCallbacks { diff --git a/gsupplicant/supplicant.c b/gsupplicant/supplicant.c index e300f194..e7dfcb27 100644 --- a/gsupplicant/supplicant.c +++ b/gsupplicant/supplicant.c @@ -45,6 +45,10 @@ #define IEEE80211_CAP_PRIVACY 0x0010 #if defined TIZEN_EXT +#define WLAN_EID_HT_CAP 45 +#define WLAN_EID_VHT_CAP 191 +#define WLAN_EID_SUPP_RATES 1 +#define WLAN_EID_EXT_SUPP_RATES 50 #define COUNTRY_CODE_LENGTH 2 #endif @@ -246,6 +250,7 @@ struct g_supplicant_bss { GSList *vsie_list; dbus_bool_t hs20; unsigned char country_code[COUNTRY_CODE_LENGTH]; + GSupplicantPhy_mode phy_mode; #endif unsigned int wps_capabilities; #if defined TIZEN_EXT_WIFI_MESH @@ -277,6 +282,7 @@ struct _GSupplicantNetwork { unsigned int keymgmt; GSList *vsie_list; unsigned char country_code[COUNTRY_CODE_LENGTH]; + GSupplicantPhy_mode phy_mode; #endif }; @@ -1414,6 +1420,16 @@ dbus_bool_t g_supplicant_network_is_wps_advertizing(GSupplicantNetwork *network) return FALSE; } +#ifdef TIZEN_EXT +GSupplicantPhy_mode g_supplicant_network_get_phy_mode(GSupplicantNetwork *network) +{ + if (!network) + return G_SUPPLICANT_MODE_IEEE80211_UNKNOWN; + + return network->phy_mode; +} +#endif + GSupplicantInterface *g_supplicant_peer_get_interface(GSupplicantPeer *peer) { if (!peer) @@ -2022,6 +2038,7 @@ static int add_or_replace_bss_to_network(struct g_supplicant_bss *bss) network->isHS20AP = bss->hs20; memcpy(network->country_code, bss->country_code, COUNTRY_CODE_LENGTH); + network->phy_mode = bss->phy_mode; #endif SUPPLICANT_DBG("New network %s created", network->name); @@ -2204,6 +2221,50 @@ static unsigned int get_tlv(unsigned char *ie, unsigned int ie_size, return 0; } +#if defined TIZEN_EXT +static void get_bss_phy_mode(unsigned int max_rate, + unsigned int max_ext_rate, bool ht, bool vht, void *data) +{ + struct g_supplicant_bss *bss = data; + unsigned int freq = bss->frequency; + + /* Following conditions are used to determine + * IEEE 802.11 Protocol Modes:- + * + * 1. If “Supported rates” is only till 11 Mbps, + * and frequency is in 2.4GHz band, then protocol is 11B. + * 2. If “Supported rates” is till 54Mbps or + * “Extended supported rates” are present, + * and frequency is in 2.4GHz band, then protocol is 11G. + * 3. If “Supported rates” is only till 54 Mbps, + * frequency is in 5GHz band , then protocol is 11A. + * 4. If “HT capabilities” is supported , then protocol is 11N. + * 5. If “HT capabilities” & “VHT” is supported and + * frequency is in 5 GHz band, then protocol is 11AC. + * */ + + if (freq >= 2412 && freq <= 2484) { /* 2.4 Ghz Band */ + if (max_rate <= 11 && max_ext_rate <= 0 && !ht) + bss->phy_mode = G_SUPPLICANT_MODE_IEEE80211B; + else if ((max_rate <= 54 || max_ext_rate > 0) && !ht) + bss->phy_mode = G_SUPPLICANT_MODE_IEEE80211BG; + else if ((max_rate >= 54 || max_ext_rate > 0) && ht) + bss->phy_mode = G_SUPPLICANT_MODE_IEEE80211BGN; + else + bss->phy_mode = G_SUPPLICANT_MODE_UNKNOWN; + } else if (freq >= 5180 && freq <= 5825) { /* 5 Ghz Band */ + if (max_rate <= 54 && !ht) + bss->phy_mode = G_SUPPLICANT_MODE_IEEE80211A; + else if ((max_rate >= 54 || max_ext_rate > 0) && ht && !vht) + bss->phy_mode = G_SUPPLICANT_MODE_IEEE80211AN; + else if ((max_rate >= 54 || max_ext_rate > 0) && ht && vht) + bss->phy_mode = G_SUPPLICANT_MODE_IEEE80211ANAC; + else + bss->phy_mode = G_SUPPLICANT_MODE_UNKNOWN; + } +} +#endif + static void bss_process_ies(DBusMessageIter *iter, void *user_data) { struct g_supplicant_bss *bss = user_data; @@ -2212,6 +2273,15 @@ static void bss_process_ies(DBusMessageIter *iter, void *user_data) DBusMessageIter array; unsigned int value; int ie_len; +#if defined TIZEN_EXT + int r_len, j; + unsigned char *rates = NULL; + unsigned char *ext_rates = NULL; + unsigned int max_rate = 0; + unsigned int max_ext_rate = 0; + bool ht = false; + bool vht = false; +#endif #define WMM_WPA1_WPS_INFO 221 #define WPS_INFO_MIN_LEN 6 @@ -2264,6 +2334,44 @@ static void bss_process_ies(DBusMessageIter *iter, void *user_data) continue; } } + + if (ie[0] == WLAN_EID_HT_CAP && ie[1]) { + ht = true; + continue; + } + + if (ie[0] == WLAN_EID_VHT_CAP && ie[1]) { + vht = true; + continue; + } + + if (ie[0] == WLAN_EID_SUPP_RATES && ie[1]) { + r_len = ie[1]; + rates = g_malloc0(r_len); + if (!rates) + continue; + + for (j = 0; ie && j < r_len; j++) { + rates[j] = ((ie[j + 2] & 0x7f) * 500000)/1000000; + if (max_rate < rates[j]) + max_rate = rates[j]; + } + continue; + } + + if (ie[0] == WLAN_EID_EXT_SUPP_RATES && ie[1] > 0) { + r_len = ie[1]; + ext_rates = g_malloc0(r_len); + if (!ext_rates) + continue; + + for (j = 0; ie && j < r_len; j++) { + ext_rates[j] = ((ie[j + 2] & 0x7f) * 500000)/1000000; + if (max_ext_rate < ext_rates[j]) + max_ext_rate = ext_rates[j]; + } + continue; + } #endif if (ie[0] != WMM_WPA1_WPS_INFO || ie[1] < WPS_INFO_MIN_LEN || memcmp(ie+2, WPS_OUI, sizeof(WPS_OUI)) != 0) @@ -2299,6 +2407,13 @@ static void bss_process_ies(DBusMessageIter *iter, void *user_data) SUPPLICANT_DBG("WPS Methods 0x%x", bss->wps_capabilities); } +#ifdef TIZEN_EXT + get_bss_phy_mode(max_rate, max_ext_rate, ht, vht, user_data); + if (rates) + g_free(rates); + if (ext_rates) + g_free(ext_rates); +#endif } static void bss_compute_security(struct g_supplicant_bss *bss) @@ -3253,6 +3368,7 @@ static void signal_bss_changed(const char *path, DBusMessageIter *iter) supplicant_dbus_property_foreach(iter, bss_property, bss); #if defined TIZEN_EXT network->frequency = bss->frequency; + network->phy_mode = bss->phy_mode; #endif old_security = network->security; bss_compute_security(bss); diff --git a/include/network.h b/include/network.h index 2c742992..6d067c55 100755 --- a/include/network.h +++ b/include/network.h @@ -68,6 +68,29 @@ struct connman_bssids { uint16_t strength; uint16_t frequency; }; + +/* Backward compatible + * modes of available network */ +typedef enum { + IEEE80211_UNKNOWN, + IEEE80211_MODE_B, + IEEE80211_MODE_BG, + IEEE80211_MODE_BGN, + IEEE80211_MODE_A, + IEEE80211_MODE_AN, + IEEE80211_MODE_ANAC, +} ieee80211_modes_e; + +/* connection mode of connected network + * based on current linkspeed */ +typedef enum { + CONNECTION_MODE_IEEE80211_UNKNOWN, + CONNECTION_MODE_IEEE80211B, + CONNECTION_MODE_IEEE80211G, + CONNECTION_MODE_IEEE80211N, + CONNECTION_MODE_IEEE80211A, + CONNECTION_MODE_IEEE80211AC, +} connection_mode_e; #endif #define CONNMAN_NETWORK_PRIORITY_LOW -100 @@ -177,6 +200,12 @@ 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); +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); #endif int connman_network_set_name(struct connman_network *network, diff --git a/plugins/wifi.c b/plugins/wifi.c index 92e70f42..33425e02 100644 --- a/plugins/wifi.c +++ b/plugins/wifi.c @@ -3429,6 +3429,77 @@ static int network_disconnect(struct connman_network *network) #if defined TIZEN_EXT static unsigned int automaxspeed_timeout = 0; +static void set_connection_mode(struct connman_network *network, + int linkspeed) +{ + ieee80211_modes_e phy_mode; + connection_mode_e conn_mode; + + phy_mode = connman_network_get_phy_mode(network); + switch (phy_mode) { + case IEEE80211_MODE_B: + if (linkspeed > 0 && linkspeed <= 11) + conn_mode = CONNECTION_MODE_IEEE80211B; + else + conn_mode = CONNECTION_MODE_IEEE80211_UNKNOWN; + + break; + case IEEE80211_MODE_BG: + if (linkspeed > 0 && linkspeed <= 11) + conn_mode = CONNECTION_MODE_IEEE80211B; + else if (linkspeed > 11 && linkspeed <= 54) + conn_mode = CONNECTION_MODE_IEEE80211G; + else + conn_mode = CONNECTION_MODE_IEEE80211_UNKNOWN; + + break; + case IEEE80211_MODE_BGN: + if (linkspeed > 0 && linkspeed <= 11) + conn_mode = CONNECTION_MODE_IEEE80211B; + else if (linkspeed > 11 && linkspeed <= 54) + conn_mode = CONNECTION_MODE_IEEE80211G; + else if (linkspeed > 54 && linkspeed <= 450) + conn_mode = CONNECTION_MODE_IEEE80211N; + else + conn_mode = CONNECTION_MODE_IEEE80211_UNKNOWN; + + break; + case IEEE80211_MODE_A: + if (linkspeed > 0 && linkspeed <= 54) + conn_mode = CONNECTION_MODE_IEEE80211A; + else + conn_mode = CONNECTION_MODE_IEEE80211_UNKNOWN; + + break; + case IEEE80211_MODE_AN: + if (linkspeed > 0 && linkspeed <= 54) + conn_mode = CONNECTION_MODE_IEEE80211A; + else if (linkspeed > 54 && linkspeed <= 450) + conn_mode = CONNECTION_MODE_IEEE80211N; + else + conn_mode = CONNECTION_MODE_IEEE80211_UNKNOWN; + + break; + case IEEE80211_MODE_ANAC: + if (linkspeed > 0 && linkspeed <= 54) + conn_mode = CONNECTION_MODE_IEEE80211A; + else if (linkspeed > 54 && linkspeed <= 450) + conn_mode = CONNECTION_MODE_IEEE80211N; + else if (linkspeed > 450 && linkspeed <= 1300) + conn_mode = CONNECTION_MODE_IEEE80211AC; + else + conn_mode = CONNECTION_MODE_IEEE80211_UNKNOWN; + + break; + default: + conn_mode = CONNECTION_MODE_IEEE80211_UNKNOWN; + break; + } + + DBG("connection mode(%d)", conn_mode); + connman_network_set_connection_mode(network, conn_mode); +} + static void signalpoll_callback(int result, int maxspeed, void *user_data) { struct connman_network *network = user_data; @@ -3439,8 +3510,10 @@ static void signalpoll_callback(int result, int maxspeed, void *user_data) } DBG("maxspeed = %d", maxspeed); - if (network) + if (network) { connman_network_set_maxspeed(network, maxspeed); + set_connection_mode(network, maxspeed); + } } static int network_signalpoll(struct connman_network *network) @@ -4256,6 +4329,7 @@ static void network_added(GSupplicantNetwork *supplicant_network) #if defined TIZEN_EXT GSList *vsie_list = NULL; const unsigned char *country_code; + ieee80211_modes_e phy_mode; #endif mode = g_supplicant_network_get_mode(supplicant_network); @@ -4320,6 +4394,8 @@ static void network_added(GSupplicantNetwork *supplicant_network) DBG("vsie_list is NULL"); country_code = g_supplicant_network_get_countrycode(supplicant_network); connman_network_set_countrycode(network, country_code); + phy_mode = g_supplicant_network_get_phy_mode(supplicant_network); + connman_network_set_phy_mode(network, phy_mode); #endif connman_network_set_string(network, "WiFi.Security", security); connman_network_set_strength(network, @@ -4453,6 +4529,7 @@ static void network_changed(GSupplicantNetwork *network, const char *property) uint16_t frequency; bool wps; const unsigned char *country_code; + ieee80211_modes_e phy_mode; GSList *bssid_list; #endif @@ -4481,6 +4558,7 @@ static void network_changed(GSupplicantNetwork *network, const char *property) maxrate = g_supplicant_network_get_maxrate(network); frequency = g_supplicant_network_get_frequency(network); wps = g_supplicant_network_get_wps(network); + phy_mode = g_supplicant_network_get_phy_mode(network); connman_network_set_bssid(connman_network, bssid); connman_network_set_maxrate(connman_network, maxrate); @@ -4490,6 +4568,7 @@ static void network_changed(GSupplicantNetwork *network, const char *property) connman_network_set_countrycode(connman_network, country_code); bssid_list = (GSList *)g_supplicant_network_get_bssid_list(network); connman_network_set_bssid_list(connman_network, bssid_list); + connman_network_set_phy_mode(connman_network, phy_mode); #endif } diff --git a/src/connman.h b/src/connman.h index 905467e8..610f63bc 100644 --- a/src/connman.h +++ b/src/connman.h @@ -26,6 +26,7 @@ #define CONNMAN_API_SUBJECT_TO_CHANGE #if defined TIZEN_EXT #define WIFI_COUNTRY_CODE_LEN 2 +#define WIFI_PHY_MODE_LEN 18 #endif #include <connman/dbus.h> diff --git a/src/network.c b/src/network.c index 85eb0fdd..b7103683 100755 --- a/src/network.c +++ b/src/network.c @@ -122,6 +122,8 @@ struct connman_network { char *phase1; unsigned char country_code[WIFI_COUNTRY_CODE_LEN]; GSList *bssid_list; + ieee80211_modes_e phy_mode; + connection_mode_e connection_mode; #endif } wifi; @@ -2130,6 +2132,34 @@ int connman_network_set_bssid_list(struct connman_network *network, return 0; } +int connman_network_set_phy_mode(struct connman_network *network, + ieee80211_modes_e mode) +{ + DBG("network %p phy mode %d", network, mode); + network->wifi.phy_mode = mode; + + return 0; +} + +ieee80211_modes_e connman_network_get_phy_mode(struct connman_network *network) +{ + return network->wifi.phy_mode; +} + +int connman_network_set_connection_mode(struct connman_network *network, + connection_mode_e mode) +{ + DBG("network %p connection mode %d", network, mode); + network->wifi.connection_mode = mode; + + return 0; +} + +connection_mode_e connman_network_get_connection_mode(struct connman_network *network) +{ + return network->wifi.connection_mode; +} + void *connman_network_get_bssid_list(struct connman_network *network) { return network->wifi.bssid_list; diff --git a/src/service.c b/src/service.c index ea61f324..777db8f5 100644 --- a/src/service.c +++ b/src/service.c @@ -3262,6 +3262,7 @@ static void append_wifi_ext_info(DBusMessageIter *dict, char country_code_buff[WIFI_COUNTRY_CODE_LEN + 1] = {0,}; char *country_code_str = country_code_buff; unsigned char *country_code; + uint16_t connection_mode; ssid = connman_network_get_blob(network, "WiFi.SSID", &ssid_len); bssid = connman_network_get_bssid(network); @@ -3272,6 +3273,7 @@ static void append_wifi_ext_info(DBusMessageIter *dict, passpoint = connman_network_get_bool(network, "WiFi.HS20AP"); keymgmt = connman_network_get_keymgmt(network); country_code = connman_network_get_countrycode(network); + connection_mode = connman_network_get_connection_mode(network); snprintf(bssid_str, WIFI_BSSID_STR_LEN, "%02x:%02x:%02x:%02x:%02x:%02x", bssid[0], bssid[1], bssid[2], @@ -3299,6 +3301,8 @@ static void append_wifi_ext_info(DBusMessageIter *dict, DBUS_TYPE_UINT32, &keymgmt); connman_dbus_dict_append_basic(dict, "Country", DBUS_TYPE_STRING, &country_code_str); + connman_dbus_dict_append_basic(dict, "ConnMode", + DBUS_TYPE_UINT16, &connection_mode); str = connman_network_get_string(network, "WiFi.Security"); if (str != NULL && g_str_equal(str, "ieee8021x") == TRUE) { |