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;
}