summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaehyun Kim <jeik01.kim@samsung.com>2018-11-06 10:38:29 +0000
committerGerrit Code Review <gerrit@review.ap-northeast-2.compute.internal>2018-11-06 10:38:29 +0000
commitbf7dbf8354f076ec768ae24e61d6fb1e46c623af (patch)
tree69162a64189dd08a7d4198cd3aa03c047645b09d
parent271ae828d35c8814e18b3de80cb835513640c0db (diff)
parent3c5d316b64f60ee6fb7b2bb85c22fad385cb0f91 (diff)
downloadconnman-bf7dbf8354f076ec768ae24e61d6fb1e46c623af.tar.gz
connman-bf7dbf8354f076ec768ae24e61d6fb1e46c623af.tar.bz2
connman-bf7dbf8354f076ec768ae24e61d6fb1e46c623af.zip
-rw-r--r--gsupplicant/gsupplicant.h11
-rw-r--r--gsupplicant/supplicant.c116
-rwxr-xr-xinclude/network.h29
-rw-r--r--plugins/wifi.c81
-rw-r--r--src/connman.h1
-rwxr-xr-xsrc/network.c30
-rw-r--r--src/service.c4
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) {