Bug fix of HE cap parsing for HE device capability am: d057297e3a

Original change: https://googleplex-android-review.googlesource.com/c/platform/system/connectivity/wificond/+/11818901

Change-Id: I6379aed93aedbec2b662b2128074c2e0a7f72e19
diff --git a/net/netlink_utils.cpp b/net/netlink_utils.cpp
index 2b31f6a..c31249d 100644
--- a/net/netlink_utils.cpp
+++ b/net/netlink_utils.cpp
@@ -64,7 +64,9 @@
 constexpr uint8_t kMaxStreams = 8;
 constexpr uint8_t kVht160MhzBitMask = 0x4;
 constexpr uint8_t kVht80p80MhzBitMask = 0x8;
-constexpr uint8_t kHeCapPhyNumByte = 11;
+// Some old Linux kernel versions set it to 9.
+// 9 is OK because only 1st byte is used
+constexpr uint8_t kHeCapPhyNumByte = 9; // Should be 11
 constexpr uint8_t kHe160MhzBitMask = 0x8;
 constexpr uint8_t kHe80p80MhzBitMask = 0x10;
 
@@ -447,16 +449,33 @@
     NL80211NestedAttr iftype_data_attr(0);
     if (band.GetAttribute(NL80211_BAND_ATTR_IFTYPE_DATA,
         &iftype_data_attr)) {
-      if (iftype_data_attr.HasAttribute(NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY)) {
-        out_band_info->is_80211ax_supported = true;
-      }
+      ParseIfTypeDataAttributes(iftype_data_attr, out_band_info);
     }
-    ParsePhyCapabilities(band, out_band_info);
+    ParseHtVhtPhyCapabilities(band, out_band_info);
   }
 
   return true;
 }
 
+void NetlinkUtils::ParseIfTypeDataAttributes(
+    const NL80211NestedAttr& iftype_data_attr,
+    BandInfo* out_band_info) {
+  vector<NL80211NestedAttr> attrs;
+  if (!iftype_data_attr.GetListOfNestedAttributes(&attrs) || attrs.empty()) {
+    LOG(ERROR) << "Failed to get the list of attributes under iftype_data_attr";
+    return;
+  }
+  NL80211NestedAttr attr = attrs[0];
+  if (attr.HasAttribute(NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY)) {
+    out_band_info->is_80211ax_supported = true;
+    ParseHeCapPhyAttribute(attr, out_band_info);
+  }
+  if (attr.HasAttribute(NL80211_BAND_IFTYPE_ATTR_HE_CAP_MCS_SET)) {
+    ParseHeMcsSetAttribute(attr, out_band_info);
+  }
+  return;
+}
+
 void NetlinkUtils::handleBandFreqAttributes(const NL80211NestedAttr& freqs_attr,
                                             BandInfo* out_band_info) {
   vector<NL80211NestedAttr> freqs;
@@ -509,13 +528,11 @@
   }
 }
 
-void NetlinkUtils::ParsePhyCapabilities(const NL80211NestedAttr& band,
-                                        BandInfo* out_band_info) {
+void NetlinkUtils::ParseHtVhtPhyCapabilities(const NL80211NestedAttr& band,
+                                             BandInfo* out_band_info) {
   ParseHtMcsSetAttribute(band, out_band_info);
   ParseVhtMcsSetAttribute(band, out_band_info);
-  ParseHeMcsSetAttribute(band, out_band_info);
   ParseVhtCapAttribute(band, out_band_info);
-  ParseHeCapAttribute(band, out_band_info);
 }
 
 void NetlinkUtils::ParseHtMcsSetAttribute(const NL80211NestedAttr& band,
@@ -578,16 +595,13 @@
                                            max_rx_streams_vht);
 }
 
-void NetlinkUtils::ParseHeMcsSetAttribute(const NL80211NestedAttr& band,
+void NetlinkUtils::ParseHeMcsSetAttribute(const NL80211NestedAttr& attribute,
                                           BandInfo* out_band_info) {
-  NL80211NestedAttr iftype_data_attr(0);
-  if (!band.GetAttribute(NL80211_BAND_ATTR_IFTYPE_DATA, &iftype_data_attr)) {
-    return;
-  }
   vector<uint8_t> he_mcs_set;
-  if (!iftype_data_attr.GetAttributeValue(
+  if (!attribute.GetAttributeValue(
       NL80211_BAND_IFTYPE_ATTR_HE_CAP_MCS_SET,
       &he_mcs_set)) {
+    LOG(ERROR) << " HE MCS set is not found ";
     return;
   }
   if (he_mcs_set.size() < kHeMcsSetNumByteMin) {
@@ -631,18 +645,17 @@
   if (vht_cap & kVht80p80MhzBitMask) {
     out_band_info->is_80p80_mhz_supported = true;
   }
+
 }
 
-void NetlinkUtils::ParseHeCapAttribute(const NL80211NestedAttr& band,
-                                       BandInfo* out_band_info) {
-  NL80211NestedAttr iftype_data_attr(0);
-  if (!band.GetAttribute(NL80211_BAND_ATTR_IFTYPE_DATA, &iftype_data_attr)) {
-    return;
-  }
+void NetlinkUtils::ParseHeCapPhyAttribute(const NL80211NestedAttr& attribute,
+                                          BandInfo* out_band_info) {
+
   vector<uint8_t> he_cap_phy;
-  if (!iftype_data_attr.GetAttributeValue(
+  if (!attribute.GetAttributeValue(
       NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY,
       &he_cap_phy)) {
+    LOG(ERROR) << " HE CAP PHY is not found";
     return;
   }
 
diff --git a/net/netlink_utils.h b/net/netlink_utils.h
index d214f94..df92e7d 100644
--- a/net/netlink_utils.h
+++ b/net/netlink_utils.h
@@ -297,21 +297,23 @@
       WiphyFeatures* out_wiphy_features);
   bool ParseBandInfo(const NL80211Packet* const packet,
                      BandInfo* out_band_info);
-  void ParsePhyCapabilities(const NL80211NestedAttr& band,
-                            BandInfo* out_band_info);
+  void ParseIfTypeDataAttributes(const NL80211NestedAttr& iftype_data_attr,
+                                 BandInfo* out_band_info);
+  void ParseHtVhtPhyCapabilities(const NL80211NestedAttr& band,
+                                 BandInfo* out_band_info);
   void ParseHtMcsSetAttribute(const NL80211NestedAttr& band,
                               BandInfo* out_band_info);
   void ParseVhtMcsSetAttribute(const NL80211NestedAttr& band,
                                BandInfo* out_band_info);
-  void ParseHeMcsSetAttribute(const NL80211NestedAttr& band,
+  void ParseHeMcsSetAttribute(const NL80211NestedAttr& attribute,
                               BandInfo* out_band_info);
   std::pair<uint32_t, uint32_t> ParseHtMcsSet(
       const std::vector<uint8_t>& ht_mcs_set);
   uint32_t ParseMcsMap(uint16_t mcs_map);
   void ParseVhtCapAttribute(const NL80211NestedAttr& band,
                             BandInfo* out_band_info);
-  void ParseHeCapAttribute(const NL80211NestedAttr& band,
-                           BandInfo* out_band_info);
+  void ParseHeCapPhyAttribute(const NL80211NestedAttr& attribute,
+                              BandInfo* out_band_info);
 
   bool ParseScanCapabilities(const NL80211Packet* const packet,
                              ScanCapabilities* out_scan_capabilities);
diff --git a/tests/netlink_utils_unittest.cpp b/tests/netlink_utils_unittest.cpp
index 316eea4..986f3b2 100644
--- a/tests/netlink_utils_unittest.cpp
+++ b/tests/netlink_utils_unittest.cpp
@@ -161,13 +161,16 @@
 
 NL80211NestedAttr GenerateBandsAttributeForIfTypeData() {
   NL80211NestedAttr if_type_data(NL80211_BAND_ATTR_IFTYPE_DATA);
+
+  NL80211NestedAttr if_type_data1(1);
   std::vector<uint8_t> he_cap_phy(kHeCapPhy, kHeCapPhy + sizeof(kHeCapPhy));
   std::vector<uint8_t> he_mcs_set(kHeMcsSet, kHeMcsSet + sizeof(kHeMcsSet));
 
-  if_type_data.AddAttribute(NL80211Attr<std::vector<uint8_t>>(
+  if_type_data1.AddAttribute(NL80211Attr<std::vector<uint8_t>>(
       NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY, he_cap_phy));
-  if_type_data.AddAttribute(NL80211Attr<std::vector<uint8_t>>(
+  if_type_data1.AddAttribute(NL80211Attr<std::vector<uint8_t>>(
       NL80211_BAND_IFTYPE_ATTR_HE_CAP_MCS_SET, he_mcs_set));
+  if_type_data.AddAttribute(if_type_data1);
   return if_type_data;
 }