You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
973 lines
39 KiB
973 lines
39 KiB
/*
|
|
* Copyright (C) 2016, The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include <array>
|
|
#include <memory>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include <linux/netlink.h>
|
|
|
|
#include <gtest/gtest.h>
|
|
|
|
#include "wificond/net/kernel-header-latest/nl80211.h"
|
|
#include "wificond/net/netlink_utils.h"
|
|
#include "wificond/tests/mock_netlink_manager.h"
|
|
|
|
using std::string;
|
|
using std::unique_ptr;
|
|
using std::vector;
|
|
using testing::DoAll;
|
|
using testing::NiceMock;
|
|
using testing::Return;
|
|
using testing::_;
|
|
|
|
namespace android {
|
|
namespace wificond {
|
|
|
|
namespace {
|
|
|
|
constexpr uint8_t kFakeMaxNumScanSSIDs = 10;
|
|
constexpr uint8_t kFakeMaxNumSchedScanSSIDs = 16;
|
|
constexpr uint8_t kFakeMaxMatchSets = 18;
|
|
constexpr uint8_t kFakeMaxNumScanPlans = 8;
|
|
constexpr uint8_t kFakeMaxScanPlanIntervals = 80;
|
|
constexpr uint8_t kFakeMaxScanPlanIterations = 10;
|
|
constexpr uint16_t kFakeFamilyId = 14;
|
|
constexpr uint32_t kFakeFrequency1 = 2412;
|
|
constexpr uint32_t kFakeFrequency2 = 2437;
|
|
constexpr uint32_t kFakeFrequency3 = 2484;
|
|
constexpr uint32_t kFakeFrequency4 = 5200;
|
|
constexpr uint32_t kFakeFrequency5 = 5400;
|
|
constexpr uint32_t kFakeFrequency6 = 5600;
|
|
// 802.11p channel which is not valid for wifi usage.
|
|
constexpr uint32_t kFakeInvalidFrequency = 5950;
|
|
constexpr uint32_t kFakeSequenceNumber = 162;
|
|
constexpr uint32_t kFakeProtocolFeatures = 0x02;
|
|
constexpr uint16_t kFakeWiphyIndex = 8;
|
|
constexpr uint16_t kFakeWiphyIndex1 = 10;
|
|
constexpr uint64_t kFakeCookie = 42;
|
|
constexpr int kFakeErrorCode = EIO;
|
|
constexpr int32_t kFakeMcs = 5;
|
|
constexpr bool kFakeSupportsRandomMacOneshotScan = true;
|
|
constexpr bool kFakeSupportsRandomMacSchedScan = false;
|
|
const char kFakeInterfaceName[] = "testif0";
|
|
const char kFakeCountryCode[] = "US";
|
|
const uint32_t kFakeInterfaceIndex = 34;
|
|
const uint32_t kFakeInterfaceIndex1 = 36;
|
|
const std::array<uint8_t, ETH_ALEN> kFakeInterfaceMacAddress = {0x45, 0x54, 0xad, 0x67, 0x98, 0xf6};
|
|
const std::array<uint8_t, ETH_ALEN> kFakeInterfaceMacAddress1 = {0x05, 0x04, 0xef, 0x27, 0x12, 0xff};
|
|
const uint8_t kFakeExtFeaturesForLowSpanScan[] = {0x0, 0x0, 0x40};
|
|
const uint8_t kFakeExtFeaturesForLowPowerScan[] = {0x0, 0x0, 0x80};
|
|
const uint8_t kFakeExtFeaturesForHighAccuracy[] = {0x0, 0x0, 0x0, 0x1};
|
|
const uint8_t kFakeExtFeaturesForAllScanType[] = {0x0, 0x0, 0xC0, 0x1};
|
|
const uint8_t kFakeFrame[] = {0x00, 0x01, 0x02, 0x03};
|
|
constexpr bool k11nSupported = true;
|
|
constexpr bool k11acSupported = true;
|
|
constexpr bool k11axSupported = true;
|
|
constexpr uint8_t kMaxTxStreams = 4;
|
|
constexpr uint8_t kMaxRxStreams = 5;
|
|
constexpr bool k160MHzSupported = true;
|
|
constexpr bool k80p80MHzSupported = false;
|
|
const uint8_t kHtMcsSet[] = {0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
|
0x0, 0x0, 0x0, 0x0, 0xf, 0x0, 0x0, 0x0};
|
|
const uint8_t kVhtMcsSet[] = {0xaa, 0xfe, 0xff, 0xff, 0xaa, 0xff, 0xff, 0xff};
|
|
const uint8_t kHeMcsSet[] = {0xaa, 0xfe, 0xaa, 0xff};
|
|
const uint8_t kVhtCap[] = {0x4, 0x0, 0x0, 0x0};
|
|
const uint8_t kHeCapPhy[] = {0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
|
|
|
|
// Currently, control messages are only created by the kernel and sent to us.
|
|
// Therefore NL80211Packet doesn't have corresponding constructor.
|
|
// For test we manually create control messages using this helper function.
|
|
NL80211Packet CreateControlMessageError(int error_code) {
|
|
vector<uint8_t> data;
|
|
data.resize(NLMSG_HDRLEN + NLA_ALIGN(sizeof(int)), 0);
|
|
// Initialize length field.
|
|
nlmsghdr* nl_header = reinterpret_cast<nlmsghdr*>(data.data());
|
|
nl_header->nlmsg_len = data.size();
|
|
nl_header->nlmsg_type = NLMSG_ERROR;
|
|
nl_header->nlmsg_seq = kFakeSequenceNumber;
|
|
nl_header->nlmsg_pid = getpid();
|
|
int* error_field = reinterpret_cast<int*>(data.data() + NLMSG_HDRLEN);
|
|
*error_field = -error_code;
|
|
|
|
return NL80211Packet(data);
|
|
}
|
|
|
|
NL80211Packet CreateControlMessageAck() {
|
|
return CreateControlMessageError(0);
|
|
}
|
|
|
|
void AppendScanCapabilitiesAttributes(NL80211Packet* packet,
|
|
bool supports_scan_plan) {
|
|
packet->AddAttribute(NL80211Attr<uint8_t>(NL80211_ATTR_MAX_NUM_SCAN_SSIDS,
|
|
kFakeMaxNumScanSSIDs));
|
|
packet->AddAttribute(NL80211Attr<uint8_t>(
|
|
NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS,
|
|
kFakeMaxNumSchedScanSSIDs));
|
|
packet->AddAttribute(NL80211Attr<uint8_t>(NL80211_ATTR_MAX_MATCH_SETS,
|
|
kFakeMaxMatchSets));
|
|
if (supports_scan_plan) {
|
|
packet->AddAttribute(NL80211Attr<uint32_t>(
|
|
NL80211_ATTR_MAX_NUM_SCHED_SCAN_PLANS,
|
|
kFakeMaxNumScanPlans));
|
|
packet->AddAttribute(NL80211Attr<uint32_t>(
|
|
NL80211_ATTR_MAX_SCAN_PLAN_INTERVAL,
|
|
kFakeMaxScanPlanIntervals));
|
|
packet->AddAttribute(NL80211Attr<uint32_t>(
|
|
NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS,
|
|
kFakeMaxScanPlanIterations));
|
|
}
|
|
}
|
|
|
|
|
|
NL80211Attr<std::vector<uint8_t>> GenerateBandsAttributeForHtCapa() {
|
|
std::vector<uint8_t> ht_cap(2, 0);
|
|
return NL80211Attr<std::vector<uint8_t>>(NL80211_BAND_ATTR_HT_CAPA,
|
|
ht_cap);
|
|
}
|
|
|
|
|
|
NL80211Attr<std::vector<uint8_t>> GenerateBandsAttributeForVhtCapa() {
|
|
std::vector<uint8_t> vht_cap(kVhtCap, kVhtCap + sizeof(kVhtCap));
|
|
return NL80211Attr<std::vector<uint8_t>>(NL80211_BAND_ATTR_VHT_CAPA,
|
|
vht_cap);
|
|
}
|
|
|
|
NL80211Attr<std::vector<uint8_t>> GenerateBandsAttributeForHtMcsSet() {
|
|
std::vector<uint8_t> ht_mcs_set(kHtMcsSet, kHtMcsSet + sizeof(kHtMcsSet));
|
|
return NL80211Attr<std::vector<uint8_t>>(NL80211_BAND_ATTR_HT_MCS_SET,
|
|
ht_mcs_set);
|
|
}
|
|
|
|
NL80211Attr<std::vector<uint8_t>> GenerateBandsAttributeForVhtMcsSet() {
|
|
std::vector<uint8_t> vht_mcs_set(kVhtMcsSet, kVhtMcsSet + sizeof(kVhtMcsSet));
|
|
return NL80211Attr<std::vector<uint8_t>>(NL80211_BAND_ATTR_VHT_MCS_SET,
|
|
vht_mcs_set);
|
|
}
|
|
|
|
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_data1.AddAttribute(NL80211Attr<std::vector<uint8_t>>(
|
|
NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY, he_cap_phy));
|
|
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;
|
|
}
|
|
|
|
void AppendBandPhyAttributes(NL80211NestedAttr* band_attr) {
|
|
band_attr->AddAttribute(GenerateBandsAttributeForHtCapa());
|
|
band_attr->AddAttribute(GenerateBandsAttributeForHtMcsSet());
|
|
band_attr->AddAttribute(GenerateBandsAttributeForVhtCapa());
|
|
band_attr->AddAttribute(GenerateBandsAttributeForVhtMcsSet());
|
|
|
|
band_attr->AddAttribute(GenerateBandsAttributeForIfTypeData());
|
|
}
|
|
|
|
NL80211NestedAttr GenerateBandsAttributeFor2g() {
|
|
NL80211NestedAttr freq_2g_1(1);
|
|
NL80211NestedAttr freq_2g_2(2);
|
|
NL80211NestedAttr freq_2g_3(3);
|
|
freq_2g_1.AddAttribute(NL80211Attr<uint32_t>(NL80211_FREQUENCY_ATTR_FREQ,
|
|
kFakeFrequency1));
|
|
freq_2g_2.AddAttribute(NL80211Attr<uint32_t>(NL80211_FREQUENCY_ATTR_FREQ,
|
|
kFakeFrequency2));
|
|
freq_2g_3.AddAttribute(NL80211Attr<uint32_t>(NL80211_FREQUENCY_ATTR_FREQ,
|
|
kFakeFrequency3));
|
|
|
|
NL80211NestedAttr band_2g_freqs(NL80211_BAND_ATTR_FREQS);
|
|
band_2g_freqs.AddAttribute(freq_2g_1);
|
|
band_2g_freqs.AddAttribute(freq_2g_2);
|
|
band_2g_freqs.AddAttribute(freq_2g_3);
|
|
|
|
NL80211NestedAttr band_2g_attr(1);
|
|
band_2g_attr.AddAttribute(band_2g_freqs);
|
|
AppendBandPhyAttributes(&band_2g_attr);
|
|
|
|
NL80211NestedAttr band_attr(NL80211_ATTR_WIPHY_BANDS);
|
|
band_attr.AddAttribute(band_2g_attr);
|
|
return band_attr;
|
|
}
|
|
|
|
NL80211NestedAttr GenerateBandsAttributeFor5gAndDfs() {
|
|
NL80211NestedAttr freq_5g_1(4);
|
|
NL80211NestedAttr freq_5g_2(5);
|
|
NL80211NestedAttr freq_5g_3(6);
|
|
NL80211NestedAttr freq_dfs_1(7);
|
|
freq_5g_1.AddAttribute(NL80211Attr<uint32_t>(NL80211_FREQUENCY_ATTR_FREQ,
|
|
kFakeFrequency4));
|
|
freq_5g_2.AddAttribute(NL80211Attr<uint32_t>(NL80211_FREQUENCY_ATTR_FREQ,
|
|
kFakeFrequency5));
|
|
// This channel is passive only.
|
|
freq_5g_2.AddFlagAttribute(NL80211_FREQUENCY_ATTR_NO_IR);
|
|
|
|
// This channel is not valid for wifi usage.
|
|
// We should not include it in the parse result.
|
|
freq_5g_3.AddAttribute(NL80211Attr<uint32_t>(NL80211_FREQUENCY_ATTR_FREQ,
|
|
kFakeInvalidFrequency));
|
|
|
|
// DFS frequency.
|
|
freq_dfs_1.AddAttribute(NL80211Attr<uint32_t>(NL80211_FREQUENCY_ATTR_FREQ,
|
|
kFakeFrequency6));
|
|
freq_dfs_1.AddAttribute(NL80211Attr<uint32_t>(
|
|
NL80211_FREQUENCY_ATTR_DFS_STATE,
|
|
NL80211_DFS_USABLE));
|
|
|
|
NL80211NestedAttr band_5g_freqs(NL80211_BAND_ATTR_FREQS);
|
|
band_5g_freqs.AddAttribute(freq_5g_1);
|
|
band_5g_freqs.AddAttribute(freq_5g_2);
|
|
band_5g_freqs.AddAttribute(freq_5g_3);
|
|
band_5g_freqs.AddAttribute(freq_dfs_1);
|
|
|
|
NL80211NestedAttr band_5g_attr(1);
|
|
band_5g_attr.AddAttribute(band_5g_freqs);
|
|
AppendBandPhyAttributes(&band_5g_attr);
|
|
|
|
NL80211NestedAttr band_attr(NL80211_ATTR_WIPHY_BANDS);
|
|
band_attr.AddAttribute(band_5g_attr);
|
|
return band_attr;
|
|
}
|
|
|
|
void AppendBandInfoAttributes(NL80211Packet* packet) {
|
|
NL80211NestedAttr attr_2g = GenerateBandsAttributeFor2g();
|
|
NL80211NestedAttr attr_5g_and_dfs = GenerateBandsAttributeFor5gAndDfs();
|
|
attr_2g.Merge(attr_5g_and_dfs);
|
|
|
|
packet->AddAttribute(attr_2g);
|
|
}
|
|
|
|
void AppendWiphyFeaturesAttributes(NL80211Packet* packet) {
|
|
uint32_t wiphy_features = 0;
|
|
if (kFakeSupportsRandomMacOneshotScan) {
|
|
wiphy_features |= NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
|
|
}
|
|
if (kFakeSupportsRandomMacSchedScan) {
|
|
wiphy_features |= NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR;
|
|
}
|
|
packet->AddAttribute(
|
|
NL80211Attr<uint32_t>(NL80211_ATTR_FEATURE_FLAGS, wiphy_features));
|
|
}
|
|
|
|
void AppendWiphyExtFeaturesAttributes(NL80211Packet* packet,
|
|
bool support_low_span,
|
|
bool support_low_power,
|
|
bool support_high_accuracy,
|
|
bool support_all) {
|
|
ASSERT_LE(support_low_span + support_low_power + support_high_accuracy, 1);
|
|
std::vector<uint8_t> ext_feature_flags_bytes;
|
|
if (support_low_span) {
|
|
ext_feature_flags_bytes =
|
|
std::vector<uint8_t>(kFakeExtFeaturesForLowSpanScan,
|
|
kFakeExtFeaturesForLowSpanScan +
|
|
sizeof(kFakeExtFeaturesForLowSpanScan));
|
|
} else if (support_low_power) {
|
|
ext_feature_flags_bytes =
|
|
std::vector<uint8_t>(kFakeExtFeaturesForLowPowerScan,
|
|
kFakeExtFeaturesForLowPowerScan +
|
|
sizeof(kFakeExtFeaturesForLowPowerScan));
|
|
} else if (support_high_accuracy) {
|
|
ext_feature_flags_bytes =
|
|
std::vector<uint8_t>(kFakeExtFeaturesForHighAccuracy,
|
|
kFakeExtFeaturesForHighAccuracy +
|
|
sizeof(kFakeExtFeaturesForHighAccuracy));
|
|
} else if (support_all) {
|
|
ext_feature_flags_bytes =
|
|
std::vector<uint8_t>(kFakeExtFeaturesForAllScanType,
|
|
kFakeExtFeaturesForAllScanType +
|
|
sizeof(kFakeExtFeaturesForAllScanType));
|
|
}
|
|
packet->AddAttribute(
|
|
NL80211Attr<std::vector<uint8_t>>(NL80211_ATTR_EXT_FEATURES,
|
|
ext_feature_flags_bytes));
|
|
}
|
|
|
|
void VerifyScanCapabilities(const ScanCapabilities& scan_capabilities,
|
|
bool supports_scan_plan) {
|
|
EXPECT_EQ(scan_capabilities.max_num_scan_ssids,
|
|
kFakeMaxNumScanSSIDs);
|
|
EXPECT_EQ(scan_capabilities.max_num_sched_scan_ssids,
|
|
kFakeMaxNumSchedScanSSIDs);
|
|
EXPECT_EQ(scan_capabilities.max_match_sets,
|
|
kFakeMaxMatchSets);
|
|
if (supports_scan_plan) {
|
|
EXPECT_EQ(scan_capabilities.max_num_scan_plans,
|
|
kFakeMaxNumScanPlans);
|
|
EXPECT_EQ(scan_capabilities.max_scan_plan_interval,
|
|
kFakeMaxScanPlanIntervals);
|
|
EXPECT_EQ(scan_capabilities.max_scan_plan_iterations,
|
|
kFakeMaxScanPlanIterations);
|
|
} else {
|
|
EXPECT_EQ(scan_capabilities.max_num_scan_plans, (unsigned int) 0);
|
|
EXPECT_EQ(scan_capabilities.max_scan_plan_interval, (unsigned int) 0);
|
|
EXPECT_EQ(scan_capabilities.max_scan_plan_iterations, (unsigned int) 0);
|
|
}
|
|
}
|
|
|
|
void VerifyBandInfo(const BandInfo& band_info) {
|
|
vector<uint32_t> band_2g_expected = {kFakeFrequency1,
|
|
kFakeFrequency2, kFakeFrequency3};
|
|
vector<uint32_t> band_5g_expected = {kFakeFrequency4};
|
|
// Frequency5 is doesn't belong to a DFS channel. However, our convetion
|
|
// requires us to return any passive only channels in DFS band.
|
|
vector<uint32_t> band_dfs_expected = {kFakeFrequency5, kFakeFrequency6};
|
|
EXPECT_EQ(band_info.band_2g, band_2g_expected);
|
|
EXPECT_EQ(band_info.band_5g, band_5g_expected);
|
|
EXPECT_EQ(band_info.band_dfs, band_dfs_expected);
|
|
EXPECT_EQ(band_info.is_80211n_supported, k11nSupported);
|
|
EXPECT_EQ(band_info.is_80211ac_supported, k11acSupported);
|
|
EXPECT_EQ(band_info.is_80211ax_supported, k11axSupported);
|
|
EXPECT_EQ(band_info.is_160_mhz_supported, k160MHzSupported);
|
|
EXPECT_EQ(band_info.is_80p80_mhz_supported, k80p80MHzSupported);
|
|
EXPECT_EQ(band_info.max_tx_streams, kMaxTxStreams);
|
|
EXPECT_EQ(band_info.max_rx_streams, kMaxRxStreams);
|
|
}
|
|
|
|
void VerifyWiphyFeatures(const WiphyFeatures& wiphy_features) {
|
|
EXPECT_TRUE(wiphy_features.supports_random_mac_oneshot_scan);
|
|
EXPECT_FALSE(wiphy_features.supports_random_mac_sched_scan);
|
|
}
|
|
|
|
} // namespace
|
|
|
|
// This mocks the behavior of SendMessageAndGetResponses(), which returns a
|
|
// vector of NL80211Packet using passed in pointer.
|
|
ACTION_P(MakeupResponse, response) {
|
|
// arg1 is the second parameter: vector<unique_ptr<const NL80211Packet>>* responses.
|
|
for (auto& pkt : response) {
|
|
arg1->push_back(unique_ptr<NL80211Packet>(new NL80211Packet(pkt)));
|
|
}
|
|
}
|
|
|
|
class NetlinkUtilsTest : public ::testing::Test {
|
|
protected:
|
|
std::unique_ptr<NiceMock<MockNetlinkManager>> netlink_manager_;
|
|
std::unique_ptr<NetlinkUtils> netlink_utils_;
|
|
|
|
virtual void SetUp() {
|
|
netlink_manager_.reset(new NiceMock<MockNetlinkManager>());
|
|
netlink_utils_.reset(new NetlinkUtils(netlink_manager_.get()));
|
|
|
|
ON_CALL(*netlink_manager_,
|
|
GetSequenceNumber()).WillByDefault(Return(kFakeSequenceNumber));
|
|
ON_CALL(*netlink_manager_,
|
|
GetFamilyId()).WillByDefault(Return(kFakeFamilyId));
|
|
}
|
|
|
|
void SetSplitWiphyDumpSupported(bool supported) {
|
|
netlink_utils_->supports_split_wiphy_dump_ = supported;
|
|
}
|
|
|
|
};
|
|
|
|
TEST_F(NetlinkUtilsTest, CanGetWiphyIndex) {
|
|
NL80211Packet new_wiphy(
|
|
netlink_manager_->GetFamilyId(),
|
|
NL80211_CMD_NEW_WIPHY,
|
|
netlink_manager_->GetSequenceNumber(),
|
|
getpid());
|
|
// Insert wiphy_index attribute.
|
|
NL80211Attr<uint32_t> wiphy_index_attr(NL80211_ATTR_WIPHY, kFakeWiphyIndex);
|
|
new_wiphy.AddAttribute(wiphy_index_attr);
|
|
// Mock a valid response from kernel.
|
|
vector<NL80211Packet> response = {new_wiphy};
|
|
|
|
EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
|
|
WillOnce(DoAll(MakeupResponse(response), Return(true)));
|
|
|
|
uint32_t wiphy_index;
|
|
EXPECT_TRUE(netlink_utils_->GetWiphyIndex(&wiphy_index));
|
|
EXPECT_EQ(kFakeWiphyIndex, wiphy_index);
|
|
}
|
|
|
|
TEST_F(NetlinkUtilsTest, CanHandleGetWiphyIndexError) {
|
|
// Mock an error response from kernel.
|
|
vector<NL80211Packet> response = {CreateControlMessageError(kFakeErrorCode)};
|
|
|
|
EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
|
|
WillOnce(DoAll(MakeupResponse(response), Return(true)));
|
|
|
|
uint32_t wiphy_index;
|
|
EXPECT_FALSE(netlink_utils_->GetWiphyIndex(&wiphy_index));
|
|
}
|
|
|
|
TEST_F(NetlinkUtilsTest, CanSetIntrerfaceMode) {
|
|
// Mock a ACK response from kernel.
|
|
vector<NL80211Packet> response = {CreateControlMessageAck()};
|
|
|
|
EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
|
|
WillOnce(DoAll(MakeupResponse(response), Return(true)));
|
|
|
|
EXPECT_TRUE(netlink_utils_->SetInterfaceMode(kFakeInterfaceIndex,
|
|
NetlinkUtils::STATION_MODE));
|
|
}
|
|
|
|
TEST_F(NetlinkUtilsTest, CanHandleSetIntrerfaceModeError) {
|
|
// Mock an error response from kernel.
|
|
vector<NL80211Packet> response = {CreateControlMessageError(kFakeErrorCode)};
|
|
|
|
EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
|
|
WillOnce(DoAll(MakeupResponse(response), Return(true)));
|
|
|
|
EXPECT_FALSE(netlink_utils_->SetInterfaceMode(kFakeInterfaceIndex,
|
|
NetlinkUtils::STATION_MODE));
|
|
}
|
|
|
|
TEST_F(NetlinkUtilsTest, CanGetInterfaces) {
|
|
NL80211Packet new_interface(
|
|
netlink_manager_->GetFamilyId(),
|
|
NL80211_CMD_NEW_INTERFACE,
|
|
netlink_manager_->GetSequenceNumber(),
|
|
getpid());
|
|
// Insert interface name attribute.
|
|
NL80211Attr<string> if_name_attr(NL80211_ATTR_IFNAME, string(kFakeInterfaceName));
|
|
new_interface.AddAttribute(if_name_attr);
|
|
// Insert interface index attribute.
|
|
NL80211Attr<uint32_t> if_index_attr(NL80211_ATTR_IFINDEX, kFakeInterfaceIndex);
|
|
new_interface.AddAttribute(if_index_attr);
|
|
// Insert mac address attribute.
|
|
std::array<uint8_t, ETH_ALEN> if_mac_addr = kFakeInterfaceMacAddress;
|
|
NL80211Attr<std::array<uint8_t, ETH_ALEN>> if_mac_attr(NL80211_ATTR_MAC, if_mac_addr);
|
|
new_interface.AddAttribute(if_mac_attr);
|
|
|
|
// Mock a valid response from kernel.
|
|
vector<NL80211Packet> response = {new_interface};
|
|
|
|
EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
|
|
WillOnce(DoAll(MakeupResponse(response), Return(true)));
|
|
|
|
vector<InterfaceInfo> interfaces;
|
|
EXPECT_TRUE(netlink_utils_->GetInterfaces(kFakeWiphyIndex, &interfaces));
|
|
EXPECT_TRUE(interfaces.size() == 1);
|
|
EXPECT_EQ(kFakeInterfaceIndex, interfaces[0].if_index);
|
|
EXPECT_EQ(kFakeWiphyIndex, interfaces[0].wiphy_index);
|
|
EXPECT_EQ(string(kFakeInterfaceName), interfaces[0].name);
|
|
EXPECT_EQ(if_mac_addr, interfaces[0].mac_address);
|
|
}
|
|
|
|
TEST_F(NetlinkUtilsTest, SkipsPseudoDevicesWhenGetInterfaces) {
|
|
// This might be a psuedo p2p interface without any interface index/name
|
|
// attributes.
|
|
NL80211Packet psuedo_interface(
|
|
netlink_manager_->GetFamilyId(),
|
|
NL80211_CMD_NEW_INTERFACE,
|
|
netlink_manager_->GetSequenceNumber(),
|
|
getpid());
|
|
psuedo_interface.AddAttribute(NL80211Attr<uint64_t>(
|
|
NL80211_ATTR_WDEV, 0));
|
|
|
|
// This is a regular client interface.
|
|
NL80211Packet expected_interface(
|
|
netlink_manager_->GetFamilyId(),
|
|
NL80211_CMD_NEW_INTERFACE,
|
|
netlink_manager_->GetSequenceNumber(),
|
|
getpid());
|
|
expected_interface.AddAttribute(NL80211Attr<string>(
|
|
NL80211_ATTR_IFNAME, string(kFakeInterfaceName)));
|
|
expected_interface.AddAttribute(NL80211Attr<uint32_t>(
|
|
NL80211_ATTR_IFINDEX, kFakeInterfaceIndex));
|
|
std::array<uint8_t, ETH_ALEN> if_mac_addr = kFakeInterfaceMacAddress;
|
|
expected_interface.AddAttribute(
|
|
NL80211Attr<std::array<uint8_t, ETH_ALEN>>(NL80211_ATTR_MAC, if_mac_addr));
|
|
|
|
// Kernel can send us the pseduo interface packet first
|
|
vector<NL80211Packet> response = {psuedo_interface, expected_interface};
|
|
|
|
EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
|
|
WillOnce(DoAll(MakeupResponse(response), Return(true)));
|
|
|
|
vector<InterfaceInfo> interfaces;
|
|
EXPECT_TRUE(netlink_utils_->GetInterfaces(kFakeWiphyIndex, &interfaces));
|
|
EXPECT_TRUE(interfaces.size() == 1);
|
|
EXPECT_EQ(kFakeInterfaceIndex, interfaces[0].if_index);
|
|
EXPECT_EQ(kFakeWiphyIndex, interfaces[0].wiphy_index);
|
|
EXPECT_EQ(string(kFakeInterfaceName), interfaces[0].name);
|
|
EXPECT_EQ(if_mac_addr, interfaces[0].mac_address);
|
|
}
|
|
|
|
TEST_F(NetlinkUtilsTest, HandleP2p0WhenGetInterfaces) {
|
|
NL80211Packet new_interface(
|
|
netlink_manager_->GetFamilyId(),
|
|
NL80211_CMD_NEW_INTERFACE,
|
|
netlink_manager_->GetSequenceNumber(),
|
|
getpid());
|
|
// Insert interface name attribute.
|
|
NL80211Attr<string> if_name_attr(NL80211_ATTR_IFNAME, string(kFakeInterfaceName));
|
|
new_interface.AddAttribute(if_name_attr);
|
|
// Insert interface index attribute.
|
|
new_interface.AddAttribute(
|
|
NL80211Attr<uint32_t>(NL80211_ATTR_IFINDEX, kFakeInterfaceIndex));
|
|
// Insert mac address attribute.
|
|
std::array<uint8_t, ETH_ALEN> if_mac_addr = kFakeInterfaceMacAddress;
|
|
new_interface.AddAttribute(
|
|
NL80211Attr<std::array<uint8_t, ETH_ALEN>>(NL80211_ATTR_MAC, if_mac_addr));
|
|
|
|
// Create a new interface packet for p2p0.
|
|
NL80211Packet new_interface_p2p0(
|
|
netlink_manager_->GetFamilyId(),
|
|
NL80211_CMD_NEW_INTERFACE,
|
|
netlink_manager_->GetSequenceNumber(),
|
|
getpid());
|
|
|
|
// Insert interface name attribute.
|
|
new_interface_p2p0.AddAttribute(
|
|
NL80211Attr<string>(NL80211_ATTR_IFNAME, "p2p0"));
|
|
// Insert interface index attribute.
|
|
new_interface_p2p0.AddAttribute(
|
|
NL80211Attr<uint32_t>(NL80211_ATTR_IFINDEX, kFakeInterfaceIndex1));
|
|
// Insert mac address attribute.
|
|
std::array<uint8_t, ETH_ALEN> if_mac_addr_p2p = kFakeInterfaceMacAddress1;
|
|
new_interface_p2p0.AddAttribute(
|
|
NL80211Attr<std::array<uint8_t, ETH_ALEN>>(NL80211_ATTR_MAC, if_mac_addr_p2p));
|
|
|
|
// Mock response from kernel, including 2 interfaces.
|
|
vector<NL80211Packet> response = {new_interface_p2p0, new_interface};
|
|
|
|
EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
|
|
WillOnce(DoAll(MakeupResponse(response), Return(true)));
|
|
|
|
vector<InterfaceInfo> interfaces;
|
|
EXPECT_TRUE(netlink_utils_->GetInterfaces(kFakeWiphyIndex, &interfaces));
|
|
EXPECT_TRUE(interfaces.size() == 2);
|
|
|
|
EXPECT_EQ(kFakeInterfaceIndex1, interfaces[0].if_index);
|
|
EXPECT_EQ(kFakeWiphyIndex, interfaces[0].wiphy_index);
|
|
EXPECT_EQ(string("p2p0"), interfaces[0].name);
|
|
EXPECT_EQ(if_mac_addr_p2p, interfaces[0].mac_address);
|
|
|
|
EXPECT_EQ(kFakeInterfaceIndex, interfaces[1].if_index);
|
|
EXPECT_EQ(kFakeWiphyIndex, interfaces[1].wiphy_index);
|
|
EXPECT_EQ(string(kFakeInterfaceName), interfaces[1].name);
|
|
EXPECT_EQ(if_mac_addr, interfaces[1].mac_address);
|
|
}
|
|
|
|
TEST_F(NetlinkUtilsTest, CanHandleGetInterfacesError) {
|
|
// Mock an error response from kernel.
|
|
vector<NL80211Packet> response = {CreateControlMessageError(kFakeErrorCode)};
|
|
|
|
EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
|
|
WillOnce(DoAll(MakeupResponse(response), Return(true)));
|
|
|
|
vector<InterfaceInfo> interfaces;
|
|
EXPECT_FALSE(netlink_utils_->GetInterfaces(kFakeWiphyIndex, &interfaces));
|
|
}
|
|
|
|
TEST_F(NetlinkUtilsTest, CanGetWiphyInfo) {
|
|
SetSplitWiphyDumpSupported(false);
|
|
NL80211Packet new_wiphy(
|
|
netlink_manager_->GetFamilyId(),
|
|
NL80211_CMD_NEW_WIPHY,
|
|
netlink_manager_->GetSequenceNumber(),
|
|
getpid());
|
|
new_wiphy.AddAttribute(NL80211Attr<uint32_t>(NL80211_ATTR_WIPHY,
|
|
kFakeWiphyIndex));
|
|
AppendBandInfoAttributes(&new_wiphy);
|
|
AppendScanCapabilitiesAttributes(&new_wiphy, true);
|
|
AppendWiphyFeaturesAttributes(&new_wiphy);
|
|
vector<NL80211Packet> get_wiphy_response = {new_wiphy};
|
|
|
|
EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
|
|
WillOnce(DoAll(MakeupResponse(get_wiphy_response), Return(true)));
|
|
|
|
BandInfo band_info;
|
|
ScanCapabilities scan_capabilities;
|
|
WiphyFeatures wiphy_features;
|
|
EXPECT_TRUE(netlink_utils_->GetWiphyInfo(kFakeWiphyIndex,
|
|
&band_info,
|
|
&scan_capabilities,
|
|
&wiphy_features));
|
|
VerifyBandInfo(band_info);
|
|
VerifyScanCapabilities(scan_capabilities, true);
|
|
VerifyWiphyFeatures(wiphy_features);
|
|
EXPECT_FALSE(wiphy_features.supports_low_span_oneshot_scan);
|
|
EXPECT_FALSE(wiphy_features.supports_low_power_oneshot_scan);
|
|
EXPECT_FALSE(wiphy_features.supports_high_accuracy_oneshot_scan);
|
|
}
|
|
|
|
TEST_F(NetlinkUtilsTest, CanGetWiphyInfoWithNoDbsParam) {
|
|
SetSplitWiphyDumpSupported(false);
|
|
NL80211Packet new_wiphy(
|
|
netlink_manager_->GetFamilyId(),
|
|
NL80211_CMD_NEW_WIPHY,
|
|
netlink_manager_->GetSequenceNumber(),
|
|
getpid());
|
|
new_wiphy.AddAttribute(NL80211Attr<uint32_t>(NL80211_ATTR_WIPHY,
|
|
kFakeWiphyIndex));
|
|
AppendBandInfoAttributes(&new_wiphy);
|
|
AppendScanCapabilitiesAttributes(&new_wiphy, false);
|
|
AppendWiphyFeaturesAttributes(&new_wiphy);
|
|
AppendWiphyExtFeaturesAttributes(&new_wiphy, false, false, false, false);
|
|
vector<NL80211Packet> get_wiphy_response = {new_wiphy};
|
|
|
|
EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
|
|
WillOnce(DoAll(MakeupResponse(get_wiphy_response), Return(true)));
|
|
|
|
BandInfo band_info;
|
|
ScanCapabilities scan_capabilities;
|
|
WiphyFeatures wiphy_features;
|
|
EXPECT_TRUE(netlink_utils_->GetWiphyInfo(kFakeWiphyIndex,
|
|
&band_info,
|
|
&scan_capabilities,
|
|
&wiphy_features));
|
|
VerifyBandInfo(band_info);
|
|
VerifyScanCapabilities(scan_capabilities, false);
|
|
VerifyWiphyFeatures(wiphy_features);
|
|
EXPECT_FALSE(wiphy_features.supports_low_span_oneshot_scan);
|
|
EXPECT_FALSE(wiphy_features.supports_low_power_oneshot_scan);
|
|
EXPECT_FALSE(wiphy_features.supports_high_accuracy_oneshot_scan);
|
|
}
|
|
|
|
TEST_F(NetlinkUtilsTest, CanGetWiphyInfoWithLowSpanScan) {
|
|
SetSplitWiphyDumpSupported(false);
|
|
NL80211Packet new_wiphy(
|
|
netlink_manager_->GetFamilyId(),
|
|
NL80211_CMD_NEW_WIPHY,
|
|
netlink_manager_->GetSequenceNumber(),
|
|
getpid());
|
|
new_wiphy.AddAttribute(NL80211Attr<uint32_t>(NL80211_ATTR_WIPHY,
|
|
kFakeWiphyIndex));
|
|
AppendBandInfoAttributes(&new_wiphy);
|
|
AppendScanCapabilitiesAttributes(&new_wiphy, false);
|
|
AppendWiphyFeaturesAttributes(&new_wiphy);
|
|
AppendWiphyExtFeaturesAttributes(&new_wiphy, true, false, false, false);
|
|
vector<NL80211Packet> get_wiphy_response = {new_wiphy};
|
|
|
|
EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
|
|
WillOnce(DoAll(MakeupResponse(get_wiphy_response), Return(true)));
|
|
|
|
BandInfo band_info;
|
|
ScanCapabilities scan_capabilities;
|
|
WiphyFeatures wiphy_features;
|
|
EXPECT_TRUE(netlink_utils_->GetWiphyInfo(kFakeWiphyIndex,
|
|
&band_info,
|
|
&scan_capabilities,
|
|
&wiphy_features));
|
|
VerifyBandInfo(band_info);
|
|
VerifyScanCapabilities(scan_capabilities, false);
|
|
VerifyWiphyFeatures(wiphy_features);
|
|
EXPECT_TRUE(wiphy_features.supports_low_span_oneshot_scan);
|
|
EXPECT_FALSE(wiphy_features.supports_low_power_oneshot_scan);
|
|
EXPECT_FALSE(wiphy_features.supports_high_accuracy_oneshot_scan);
|
|
}
|
|
|
|
TEST_F(NetlinkUtilsTest, CanGetWiphyInfoWithLowPowerScan) {
|
|
SetSplitWiphyDumpSupported(false);
|
|
NL80211Packet new_wiphy(
|
|
netlink_manager_->GetFamilyId(),
|
|
NL80211_CMD_NEW_WIPHY,
|
|
netlink_manager_->GetSequenceNumber(),
|
|
getpid());
|
|
new_wiphy.AddAttribute(NL80211Attr<uint32_t>(NL80211_ATTR_WIPHY,
|
|
kFakeWiphyIndex));
|
|
AppendBandInfoAttributes(&new_wiphy);
|
|
AppendScanCapabilitiesAttributes(&new_wiphy, false);
|
|
AppendWiphyFeaturesAttributes(&new_wiphy);
|
|
AppendWiphyExtFeaturesAttributes(&new_wiphy, false, true, false, false);
|
|
vector<NL80211Packet> get_wiphy_response = {new_wiphy};
|
|
|
|
EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
|
|
WillOnce(DoAll(MakeupResponse(get_wiphy_response), Return(true)));
|
|
|
|
BandInfo band_info;
|
|
ScanCapabilities scan_capabilities;
|
|
WiphyFeatures wiphy_features;
|
|
EXPECT_TRUE(netlink_utils_->GetWiphyInfo(kFakeWiphyIndex,
|
|
&band_info,
|
|
&scan_capabilities,
|
|
&wiphy_features));
|
|
VerifyBandInfo(band_info);
|
|
VerifyScanCapabilities(scan_capabilities, false);
|
|
VerifyWiphyFeatures(wiphy_features);
|
|
EXPECT_FALSE(wiphy_features.supports_low_span_oneshot_scan);
|
|
EXPECT_TRUE(wiphy_features.supports_low_power_oneshot_scan);
|
|
EXPECT_FALSE(wiphy_features.supports_high_accuracy_oneshot_scan);
|
|
}
|
|
|
|
TEST_F(NetlinkUtilsTest, CanGetWiphyInfoWithHighAccuracyScan) {
|
|
SetSplitWiphyDumpSupported(false);
|
|
NL80211Packet new_wiphy(
|
|
netlink_manager_->GetFamilyId(),
|
|
NL80211_CMD_NEW_WIPHY,
|
|
netlink_manager_->GetSequenceNumber(),
|
|
getpid());
|
|
new_wiphy.AddAttribute(NL80211Attr<uint32_t>(NL80211_ATTR_WIPHY,
|
|
kFakeWiphyIndex));
|
|
AppendBandInfoAttributes(&new_wiphy);
|
|
AppendScanCapabilitiesAttributes(&new_wiphy, false);
|
|
AppendWiphyFeaturesAttributes(&new_wiphy);
|
|
AppendWiphyExtFeaturesAttributes(&new_wiphy, false, false, true, false);
|
|
vector<NL80211Packet> get_wiphy_response = {new_wiphy};
|
|
|
|
EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
|
|
WillOnce(DoAll(MakeupResponse(get_wiphy_response), Return(true)));
|
|
|
|
BandInfo band_info;
|
|
ScanCapabilities scan_capabilities;
|
|
WiphyFeatures wiphy_features;
|
|
EXPECT_TRUE(netlink_utils_->GetWiphyInfo(kFakeWiphyIndex,
|
|
&band_info,
|
|
&scan_capabilities,
|
|
&wiphy_features));
|
|
VerifyBandInfo(band_info);
|
|
VerifyScanCapabilities(scan_capabilities, false);
|
|
VerifyWiphyFeatures(wiphy_features);
|
|
EXPECT_FALSE(wiphy_features.supports_low_span_oneshot_scan);
|
|
EXPECT_FALSE(wiphy_features.supports_low_power_oneshot_scan);
|
|
EXPECT_TRUE(wiphy_features.supports_high_accuracy_oneshot_scan);
|
|
}
|
|
|
|
TEST_F(NetlinkUtilsTest, CanGetWiphyInfoWithAllDbsParams) {
|
|
SetSplitWiphyDumpSupported(false);
|
|
NL80211Packet new_wiphy(
|
|
netlink_manager_->GetFamilyId(),
|
|
NL80211_CMD_NEW_WIPHY,
|
|
netlink_manager_->GetSequenceNumber(),
|
|
getpid());
|
|
new_wiphy.AddAttribute(NL80211Attr<uint32_t>(NL80211_ATTR_WIPHY,
|
|
kFakeWiphyIndex));
|
|
AppendBandInfoAttributes(&new_wiphy);
|
|
AppendScanCapabilitiesAttributes(&new_wiphy, false);
|
|
AppendWiphyFeaturesAttributes(&new_wiphy);
|
|
AppendWiphyExtFeaturesAttributes(&new_wiphy, false, false, false, true);
|
|
vector<NL80211Packet> get_wiphy_response = {new_wiphy};
|
|
|
|
EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
|
|
WillOnce(DoAll(MakeupResponse(get_wiphy_response), Return(true)));
|
|
|
|
BandInfo band_info;
|
|
ScanCapabilities scan_capabilities;
|
|
WiphyFeatures wiphy_features;
|
|
EXPECT_TRUE(netlink_utils_->GetWiphyInfo(kFakeWiphyIndex,
|
|
&band_info,
|
|
&scan_capabilities,
|
|
&wiphy_features));
|
|
VerifyBandInfo(band_info);
|
|
VerifyScanCapabilities(scan_capabilities, false);
|
|
VerifyWiphyFeatures(wiphy_features);
|
|
EXPECT_TRUE(wiphy_features.supports_low_span_oneshot_scan);
|
|
EXPECT_TRUE(wiphy_features.supports_low_power_oneshot_scan);
|
|
EXPECT_TRUE(wiphy_features.supports_high_accuracy_oneshot_scan);
|
|
}
|
|
|
|
TEST_F(NetlinkUtilsTest, CanGetWiphyInfoScanPlanNotSupported) {
|
|
SetSplitWiphyDumpSupported(false);
|
|
NL80211Packet new_wiphy(
|
|
netlink_manager_->GetFamilyId(),
|
|
NL80211_CMD_NEW_WIPHY,
|
|
netlink_manager_->GetSequenceNumber(),
|
|
getpid());
|
|
new_wiphy.AddAttribute(NL80211Attr<uint32_t>(NL80211_ATTR_WIPHY,
|
|
kFakeWiphyIndex));
|
|
AppendBandInfoAttributes(&new_wiphy);
|
|
AppendScanCapabilitiesAttributes(&new_wiphy, false);
|
|
AppendWiphyFeaturesAttributes(&new_wiphy);
|
|
vector<NL80211Packet> get_wiphy_response = {new_wiphy};
|
|
|
|
EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
|
|
WillOnce(DoAll(MakeupResponse(get_wiphy_response), Return(true)));
|
|
|
|
BandInfo band_info;
|
|
ScanCapabilities scan_capabilities;
|
|
WiphyFeatures wiphy_features;
|
|
EXPECT_TRUE(netlink_utils_->GetWiphyInfo(kFakeWiphyIndex,
|
|
&band_info,
|
|
&scan_capabilities,
|
|
&wiphy_features));
|
|
VerifyBandInfo(band_info);
|
|
VerifyScanCapabilities(scan_capabilities, false);
|
|
VerifyWiphyFeatures(wiphy_features);
|
|
}
|
|
|
|
TEST_F(NetlinkUtilsTest, CanGetWiphyInfoSplitDump) {
|
|
SetSplitWiphyDumpSupported(true);
|
|
|
|
NL80211Packet new_wiphy_packet1(
|
|
netlink_manager_->GetFamilyId(),
|
|
NL80211_CMD_NEW_WIPHY,
|
|
netlink_manager_->GetSequenceNumber(),
|
|
getpid());
|
|
new_wiphy_packet1.AddAttribute(NL80211Attr<uint32_t>(NL80211_ATTR_WIPHY,
|
|
kFakeWiphyIndex));
|
|
new_wiphy_packet1.AddAttribute(GenerateBandsAttributeFor5gAndDfs());
|
|
|
|
NL80211Packet new_wiphy_packet2(
|
|
netlink_manager_->GetFamilyId(),
|
|
NL80211_CMD_NEW_WIPHY,
|
|
netlink_manager_->GetSequenceNumber(),
|
|
getpid());
|
|
new_wiphy_packet2.AddAttribute(NL80211Attr<uint32_t>(NL80211_ATTR_WIPHY,
|
|
kFakeWiphyIndex));
|
|
new_wiphy_packet2.AddAttribute(GenerateBandsAttributeFor2g());
|
|
AppendScanCapabilitiesAttributes(&new_wiphy_packet2, false);
|
|
AppendWiphyFeaturesAttributes(&new_wiphy_packet2);
|
|
|
|
// Insert a packet for wiphy with index kFakeWiphyIndex1.
|
|
// This is unrelated and should be ingnored by |GetWiphyInfo|.
|
|
NL80211Packet new_wiphy_packet3(
|
|
netlink_manager_->GetFamilyId(),
|
|
NL80211_CMD_NEW_WIPHY,
|
|
netlink_manager_->GetSequenceNumber(),
|
|
getpid());
|
|
new_wiphy_packet3.AddAttribute(NL80211Attr<uint32_t>(NL80211_ATTR_WIPHY,
|
|
kFakeWiphyIndex1));
|
|
AppendBandInfoAttributes(&new_wiphy_packet3);
|
|
|
|
vector<NL80211Packet> get_wiphy_response =
|
|
{new_wiphy_packet1, new_wiphy_packet2, new_wiphy_packet3};
|
|
|
|
EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
|
|
WillOnce(DoAll(MakeupResponse(get_wiphy_response), Return(true)));
|
|
|
|
BandInfo band_info;
|
|
ScanCapabilities scan_capabilities;
|
|
WiphyFeatures wiphy_features;
|
|
EXPECT_TRUE(netlink_utils_->GetWiphyInfo(kFakeWiphyIndex,
|
|
&band_info,
|
|
&scan_capabilities,
|
|
&wiphy_features));
|
|
VerifyBandInfo(band_info);
|
|
VerifyScanCapabilities(scan_capabilities, false);
|
|
VerifyWiphyFeatures(wiphy_features);
|
|
}
|
|
|
|
|
|
TEST_F(NetlinkUtilsTest, CanHandleGetWiphyInfoError) {
|
|
SetSplitWiphyDumpSupported(false);
|
|
|
|
// Mock an error response from kernel.
|
|
vector<NL80211Packet> get_wiphy_response = {CreateControlMessageError(kFakeErrorCode)};
|
|
|
|
EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
|
|
WillOnce(DoAll(MakeupResponse(get_wiphy_response), Return(true)));
|
|
|
|
BandInfo band_info;
|
|
ScanCapabilities scan_capabilities;
|
|
WiphyFeatures wiphy_features;
|
|
EXPECT_FALSE(netlink_utils_->GetWiphyInfo(kFakeWiphyIndex,
|
|
&band_info,
|
|
&scan_capabilities,
|
|
&wiphy_features));
|
|
}
|
|
|
|
TEST_F(NetlinkUtilsTest, CanGetProtocolFeatures) {
|
|
// There is no specification for the response packet id for
|
|
// NL80211_CMD_GET_PROTOCOL_FEATURES.
|
|
// Still use NL80211_CMD_GET_PROTOCOL_FEATURES here.
|
|
NL80211Packet get_features_response(
|
|
netlink_manager_->GetFamilyId(),
|
|
NL80211_CMD_GET_PROTOCOL_FEATURES,
|
|
netlink_manager_->GetSequenceNumber(),
|
|
getpid());
|
|
get_features_response.AddAttribute(
|
|
NL80211Attr<uint32_t>(NL80211_ATTR_PROTOCOL_FEATURES,
|
|
kFakeProtocolFeatures));
|
|
vector<NL80211Packet> response = {get_features_response};
|
|
|
|
EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
|
|
WillOnce(DoAll(MakeupResponse(response), Return(true)));
|
|
|
|
uint32_t features;
|
|
EXPECT_TRUE(netlink_utils_->GetProtocolFeatures(&features));
|
|
EXPECT_EQ(kFakeProtocolFeatures, features);
|
|
}
|
|
|
|
TEST_F(NetlinkUtilsTest, CanHandleGetProtocolFeaturesError) {
|
|
// Mock an error response from kernel.
|
|
vector<NL80211Packet> response = {CreateControlMessageError(kFakeErrorCode)};
|
|
|
|
EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
|
|
WillOnce(DoAll(MakeupResponse(response), Return(true)));
|
|
|
|
uint32_t features_ignored;
|
|
EXPECT_FALSE(netlink_utils_->GetProtocolFeatures(&features_ignored));
|
|
}
|
|
|
|
TEST_F(NetlinkUtilsTest, CanGetCountryCode) {
|
|
// There is no specification for the response packet id for
|
|
// NL80211_CMD_GET_REG.
|
|
// Still use NL80211_CMD_GET_REG here.
|
|
NL80211Packet get_country_code_response(
|
|
netlink_manager_->GetFamilyId(),
|
|
NL80211_CMD_GET_REG,
|
|
netlink_manager_->GetSequenceNumber(),
|
|
getpid());
|
|
get_country_code_response.AddAttribute(
|
|
NL80211Attr<string>(NL80211_ATTR_REG_ALPHA2,
|
|
kFakeCountryCode));
|
|
vector<NL80211Packet> response = {get_country_code_response};
|
|
|
|
EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
|
|
WillOnce(DoAll(MakeupResponse(response), Return(true)));
|
|
|
|
string country_code;
|
|
EXPECT_TRUE(netlink_utils_->GetCountryCode(&country_code));
|
|
EXPECT_EQ(kFakeCountryCode, country_code);
|
|
}
|
|
|
|
TEST_F(NetlinkUtilsTest, CanHandleGetCountryCodeError) {
|
|
// Mock an error response from kernel.
|
|
vector<NL80211Packet> response = {CreateControlMessageError(kFakeErrorCode)};
|
|
|
|
EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
|
|
WillOnce(DoAll(MakeupResponse(response), Return(true)));
|
|
|
|
string country_code_ignored;
|
|
EXPECT_FALSE(netlink_utils_->GetCountryCode(&country_code_ignored));
|
|
}
|
|
|
|
TEST_F(NetlinkUtilsTest, CanSendMgmtFrame) {
|
|
// There is no specification for the response packet id for
|
|
// NL80211_CMD_FRAME.
|
|
// Still use NL80211_CMD_FRAME here.
|
|
NL80211Packet send_mgmt_frame_response(
|
|
netlink_manager_->GetFamilyId(),
|
|
NL80211_CMD_FRAME,
|
|
netlink_manager_->GetSequenceNumber(),
|
|
getpid());
|
|
send_mgmt_frame_response.AddAttribute(
|
|
NL80211Attr<uint64_t>(NL80211_ATTR_COOKIE, kFakeCookie));
|
|
vector<NL80211Packet> response = {send_mgmt_frame_response};
|
|
|
|
EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _))
|
|
.WillOnce(DoAll(MakeupResponse(response), Return(true)));
|
|
|
|
uint64_t cookie;
|
|
EXPECT_TRUE(netlink_utils_->SendMgmtFrame(kFakeInterfaceIndex,
|
|
vector<uint8_t>(std::begin(kFakeFrame), std::end(kFakeFrame)),
|
|
kFakeMcs, &cookie));
|
|
EXPECT_EQ(kFakeCookie, cookie);
|
|
}
|
|
|
|
TEST_F(NetlinkUtilsTest, CanHandleSendMgmtFrameError) {
|
|
// Mock an error response from kernel.
|
|
vector<NL80211Packet> response = {CreateControlMessageError(kFakeErrorCode)};
|
|
EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
|
|
WillOnce(DoAll(MakeupResponse(response), Return(true)));
|
|
|
|
uint64_t cookie_ignored;
|
|
EXPECT_FALSE(netlink_utils_->SendMgmtFrame(kFakeInterfaceIndex,
|
|
vector<uint8_t>(std::begin(kFakeFrame), std::end(kFakeFrame)),
|
|
kFakeMcs, &cookie_ignored));
|
|
}
|
|
|
|
} // namespace wificond
|
|
} // namespace android
|