Merge "Add IEEE 802.11 protocol(b/g/n/a/ac) Modes of APs" into tizen accepted/tizen/unified/20181129.054222 submit/tizen/20181106.114249 submit/tizen/20181120.123835 submit/tizen/20181127.113629
authorJaehyun Kim <jeik01.kim@samsung.com>
Tue, 6 Nov 2018 10:38:29 +0000 (10:38 +0000)
committerGerrit Code Review <gerrit@review.ap-northeast-2.compute.internal>
Tue, 6 Nov 2018 10:38:29 +0000 (10:38 +0000)
gsupplicant/gsupplicant.h
gsupplicant/supplicant.c
include/network.h
plugins/wifi.c
src/connman.h
src/network.c
src/service.c

index 035789e..597fe75 100644 (file)
@@ -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 {
index e300f19..e7dfcb2 100644 (file)
 #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);
index 2c74299..6d067c5 100755 (executable)
@@ -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,
index 92e70f4..33425e0 100644 (file)
@@ -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
 }
 
index 905467e..610f63b 100644 (file)
@@ -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>
index 85eb0fd..b710368 100755 (executable)
@@ -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;
index ea61f32..777db8f 100644 (file)
@@ -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) {