165b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang/*
265b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang * Copyright (C) 2016, The Android Open Source Project
365b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang *
465b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang * Licensed under the Apache License, Version 2.0 (the "License");
565b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang * you may not use this file except in compliance with the License.
665b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang * You may obtain a copy of the License at
765b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang *
865b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang *     http://www.apache.org/licenses/LICENSE-2.0
965b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang *
1065b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang * Unless required by applicable law or agreed to in writing, software
1165b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang * distributed under the License is distributed on an "AS IS" BASIS,
1265b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1365b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang * See the License for the specific language governing permissions and
1465b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang * limitations under the License.
1565b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang */
1665b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang
1765b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang#include <functional>
1865b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang#include <memory>
1965b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang#include <vector>
2065b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang
2165b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang#include <linux/netlink.h>
2265b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang
2365b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang#include <gtest/gtest.h>
2465b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang
259d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius#include "android/net/wifi/IWifiScannerImpl.h"
264a10da1c100160f2ab357e108bfd602e4421bdb1Roshan Pius#include "wificond/net/kernel-header-latest/nl80211.h"
2765b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang#include "wificond/scanning/scan_result.h"
2865b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang#include "wificond/scanning/scan_utils.h"
2965b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang#include "wificond/tests/mock_netlink_manager.h"
3065b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang
3165b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wangusing std::bind;
3265b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wangusing std::placeholders::_1;
3365b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wangusing std::placeholders::_2;
3465b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wangusing std::unique_ptr;
3565b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wangusing std::vector;
36dfbe7e4e12824527fac840391f31d2b4a4578e3eNingyuan Wangusing testing::AllOf;
3765b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wangusing testing::Invoke;
3865b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wangusing testing::NiceMock;
39dfbe7e4e12824527fac840391f31d2b4a4578e3eNingyuan Wangusing testing::Not;
4065b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wangusing testing::Return;
4165b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wangusing testing::_;
4265b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang
439d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Piususing android::net::wifi::IWifiScannerImpl;
4465b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wangusing com::android::server::wifi::wificond::NativeScanResult;
4565b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang
4665b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wangnamespace android {
4765b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wangnamespace wificond {
4865b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang
4965b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wangnamespace {
5065b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang
5165b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wangconstexpr uint32_t kFakeInterfaceIndex = 12;
5265b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wangconstexpr uint32_t kFakeScheduledScanIntervalMs = 20000;
5365b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wangconstexpr uint32_t kFakeSequenceNumber = 1984;
5465b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wangconstexpr int kFakeErrorCode = EIO;
55c6ecdf8ea59f7de47edfd6161f059b8ab45d1f8fNingyuan Wangconstexpr int32_t kFake2gRssiThreshold = -80;
56c6ecdf8ea59f7de47edfd6161f059b8ab45d1f8fNingyuan Wangconstexpr int32_t kFake5gRssiThreshold = -77;
5713b4064f889935091b0d55bbb056ec143972a9a4Ningyuan Wangconstexpr bool kFakeUseRandomMAC = true;
589d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Piusconstexpr bool kFakeRequestLowPower = true;
599d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Piusconstexpr int kFakeScanType = IWifiScannerImpl::SCAN_TYPE_LOW_SPAN;
6065b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang
6165b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang// Currently, control messages are only created by the kernel and sent to us.
6265b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang// Therefore NL80211Packet doesn't have corresponding constructor.
6365b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang// For test we manually create control messages using this helper function.
6465b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan WangNL80211Packet CreateControlMessageError(int error_code) {
6565b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang  vector<uint8_t> data;
6665b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang  data.resize(NLMSG_HDRLEN + NLA_ALIGN(sizeof(int)), 0);
6765b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang  // Initialize length field.
6865b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang  nlmsghdr* nl_header = reinterpret_cast<nlmsghdr*>(data.data());
6965b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang  nl_header->nlmsg_len = data.size();
7065b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang  nl_header->nlmsg_type = NLMSG_ERROR;
7165b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang  nl_header->nlmsg_seq = kFakeSequenceNumber;
7265b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang  nl_header->nlmsg_pid = getpid();
7365b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang  int* error_field = reinterpret_cast<int*>(data.data() + NLMSG_HDRLEN);
7465b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang  *error_field = -error_code;
7565b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang
7665b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang  return NL80211Packet(data);
7765b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang}
7865b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang
7965b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan WangNL80211Packet CreateControlMessageAck() {
8065b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang  return CreateControlMessageError(0);
8165b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang}
8265b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang
8365b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang// This is a helper function to mock the behavior of NetlinkManager::
8465b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang// SendMessageAndGetResponses() when we expect a single packet response.
8565b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang// |request_message| and |response| are mapped to existing parameters of
8665b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang// SendMessageAndGetResponses().
8765b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang// |mock_response| and |mock_return value| are additional parameters used
8865b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang// for specifying expected results,
8965b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wangbool AppendMessageAndReturn(
9065b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang    NL80211Packet& mock_response,
9165b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang    bool mock_return_value,
9265b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang    const NL80211Packet& request_message,
9365b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang    vector<std::unique_ptr<const NL80211Packet>>* response) {
9465b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang  response->push_back(std::make_unique<NL80211Packet>(mock_response));
9565b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang  return mock_return_value;
9665b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang}
9765b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang
9865b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang}  // namespace
9965b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang
10065b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wangclass ScanUtilsTest : public ::testing::Test {
10165b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang protected:
10265b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang  virtual void SetUp() {
10365b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang    ON_CALL(netlink_manager_,
10465b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang            SendMessageAndGetResponses(_, _)).WillByDefault(Return(true));
10565b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang  }
10665b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang
10765b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang  NiceMock<MockNetlinkManager> netlink_manager_;
10865b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang  ScanUtils scan_utils_{&netlink_manager_};
10965b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang};
11065b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang
11165b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan WangMATCHER_P(DoesNL80211PacketMatchCommand, command,
11265b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang          "Check if the netlink packet matches |command|") {
11365b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang  return arg.GetCommand() == command;
11465b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang}
11565b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang
116dfbe7e4e12824527fac840391f31d2b4a4578e3eNingyuan WangMATCHER_P(DoesNL80211PacketHaveAttribute, attr,
117dfbe7e4e12824527fac840391f31d2b4a4578e3eNingyuan Wang          "Check if the netlink packet has atttribute |attr|") {
118dfbe7e4e12824527fac840391f31d2b4a4578e3eNingyuan Wang  return arg.HasAttribute(attr);
119dfbe7e4e12824527fac840391f31d2b4a4578e3eNingyuan Wang}
120dfbe7e4e12824527fac840391f31d2b4a4578e3eNingyuan Wang
1219d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan PiusMATCHER_P2(DoesNL80211PacketHaveAttributeWithUint32Value, attr, expected_value,
1229d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius           "Check if the netlink packet has atttribute |attr| with "
1239d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius           "|expected_value|") {
1249d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius  uint32_t actual_value;
1259d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius  if (!arg.GetAttributeValue(attr, &actual_value)) {
1269d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius    return false;
1279d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius  }
1289d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius  return actual_value == expected_value;
1299d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius}
1309d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius
13165b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan WangTEST_F(ScanUtilsTest, CanGetScanResult) {
13265b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang  vector<NativeScanResult> scan_results;
13365b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang  EXPECT_CALL(
13465b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang      netlink_manager_,
13565b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang      SendMessageAndGetResponses(
13665b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang          DoesNL80211PacketMatchCommand(NL80211_CMD_GET_SCAN), _));
13765b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang
13865b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang  // We don't use EXPECT_TRUE here because we need to mock a complete
13965b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang  // response for NL80211_CMD_GET_SCAN to satisfy the parsing code called
14065b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang  // by GetScanResult.
14165b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang  // TODO(b/34231002): Mock response for NL80211_CMD_GET_SCAN.
14265b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang  // TODO(b/34231420): Add validation of interface index.
14365b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang  scan_utils_.GetScanResult(kFakeInterfaceIndex, &scan_results);
14465b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang}
14565b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang
14665b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan WangTEST_F(ScanUtilsTest, CanSendScanRequest) {
14765b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang  NL80211Packet response = CreateControlMessageAck();
14865b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang  EXPECT_CALL(
14965b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang      netlink_manager_,
15065b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang      SendMessageAndGetResponses(
15165b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang          DoesNL80211PacketMatchCommand(NL80211_CMD_TRIGGER_SCAN), _)).
15265b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang              WillOnce(Invoke(bind(
15365b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang                  AppendMessageAndReturn, response, true, _1, _2)));
15465b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang
155793978cb7f2f227f1ab28135caeb75dd4ed48e6cNingyuan Wang  int errno_ignored;
1569d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius  EXPECT_TRUE(scan_utils_.Scan(kFakeInterfaceIndex, kFakeUseRandomMAC,
1579d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius                               kFakeScanType, {}, {}, &errno_ignored));
15865b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang  // TODO(b/34231420): Add validation of requested scan ssids, threshold,
15965b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang  // and frequencies.
16065b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang}
16165b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang
1629d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan PiusTEST_F(ScanUtilsTest, CanSendScanRequestWithRandomAddr) {
1639d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius  NL80211Packet response = CreateControlMessageAck();
1649d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius  EXPECT_CALL(
1659d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius      netlink_manager_,
1669d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius      SendMessageAndGetResponses(
1679d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius           AllOf(
1689d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius               DoesNL80211PacketMatchCommand(NL80211_CMD_TRIGGER_SCAN),
1699d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius               DoesNL80211PacketHaveAttributeWithUint32Value(
1709d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius                   NL80211_ATTR_SCAN_FLAGS, NL80211_SCAN_FLAG_RANDOM_ADDR)),
1719d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius           _)).
1729d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius      WillOnce(Invoke(bind(AppendMessageAndReturn, response, true, _1, _2)));
1739d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius
1749d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius  int errno_ignored;
1759d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius  EXPECT_TRUE(scan_utils_.Scan(kFakeInterfaceIndex, true,
1769d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius                               IWifiScannerImpl::SCAN_TYPE_DEFAULT,
1779d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius                               {}, {}, &errno_ignored));
1789d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius}
1799d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius
1809d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan PiusTEST_F(ScanUtilsTest, CanSendScanRequestForLowSpanScan) {
1819d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius  NL80211Packet response = CreateControlMessageAck();
1829d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius  EXPECT_CALL(
1839d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius      netlink_manager_,
1849d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius      SendMessageAndGetResponses(
1859d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius           AllOf(
1869d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius               DoesNL80211PacketMatchCommand(NL80211_CMD_TRIGGER_SCAN),
1879d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius               DoesNL80211PacketHaveAttributeWithUint32Value(
1889d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius                   NL80211_ATTR_SCAN_FLAGS, NL80211_SCAN_FLAG_LOW_SPAN)),
1899d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius           _)).
1909d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius      WillOnce(Invoke(bind(AppendMessageAndReturn, response, true, _1, _2)));
1919d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius
1929d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius  int errno_ignored;
1939d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius  EXPECT_TRUE(scan_utils_.Scan(kFakeInterfaceIndex, false,
1949d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius                               IWifiScannerImpl::SCAN_TYPE_LOW_SPAN,
1959d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius                               {}, {}, &errno_ignored));
1969d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius}
1979d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius
1989d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan PiusTEST_F(ScanUtilsTest, CanSendScanRequestForLowPowerScan) {
1999d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius  NL80211Packet response = CreateControlMessageAck();
2009d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius  EXPECT_CALL(
2019d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius      netlink_manager_,
2029d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius      SendMessageAndGetResponses(
2039d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius           AllOf(
2049d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius               DoesNL80211PacketMatchCommand(NL80211_CMD_TRIGGER_SCAN),
2059d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius               DoesNL80211PacketHaveAttributeWithUint32Value(
2069d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius                   NL80211_ATTR_SCAN_FLAGS, NL80211_SCAN_FLAG_LOW_POWER)),
2079d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius           _)).
2089d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius      WillOnce(Invoke(bind(AppendMessageAndReturn, response, true, _1, _2)));
2099d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius
2109d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius  int errno_ignored;
2119d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius  EXPECT_TRUE(scan_utils_.Scan(kFakeInterfaceIndex, false,
2129d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius                               IWifiScannerImpl::SCAN_TYPE_LOW_POWER,
2139d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius                               {}, {}, &errno_ignored));
2149d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius}
2159d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius
2169d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan PiusTEST_F(ScanUtilsTest, CanSendScanRequestForHighAccuracyScan) {
2179d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius  NL80211Packet response = CreateControlMessageAck();
2189d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius  EXPECT_CALL(
2199d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius      netlink_manager_,
2209d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius      SendMessageAndGetResponses(
2219d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius           AllOf(
2229d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius               DoesNL80211PacketMatchCommand(NL80211_CMD_TRIGGER_SCAN),
2239d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius               DoesNL80211PacketHaveAttributeWithUint32Value(
2249d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius                   NL80211_ATTR_SCAN_FLAGS, NL80211_SCAN_FLAG_HIGH_ACCURACY)),
2259d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius           _)).
2269d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius      WillOnce(Invoke(bind(AppendMessageAndReturn, response, true, _1, _2)));
2279d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius
2289d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius  int errno_ignored;
2299d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius  EXPECT_TRUE(scan_utils_.Scan(kFakeInterfaceIndex, false,
2309d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius                               IWifiScannerImpl::SCAN_TYPE_HIGH_ACCURACY,
2319d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius                               {}, {}, &errno_ignored));
2329d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius}
2339d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius
2349d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan PiusTEST_F(ScanUtilsTest, CanSendScanRequestForHighAccuracyScanWithRandomAddr) {
2359d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius  NL80211Packet response = CreateControlMessageAck();
2369d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius  EXPECT_CALL(
2379d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius      netlink_manager_,
2389d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius      SendMessageAndGetResponses(
2399d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius           AllOf(
2409d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius               DoesNL80211PacketMatchCommand(NL80211_CMD_TRIGGER_SCAN),
2419d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius               DoesNL80211PacketHaveAttributeWithUint32Value(
2429d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius                   NL80211_ATTR_SCAN_FLAGS,
2439d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius                   static_cast<uint32_t>(NL80211_SCAN_FLAG_RANDOM_ADDR |
2449d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius                                         NL80211_SCAN_FLAG_HIGH_ACCURACY))),
2459d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius           _)).
2469d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius      WillOnce(Invoke(bind(AppendMessageAndReturn, response, true, _1, _2)));
2479d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius
2489d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius  int errno_ignored;
2499d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius  EXPECT_TRUE(scan_utils_.Scan(kFakeInterfaceIndex, true,
2509d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius                               IWifiScannerImpl::SCAN_TYPE_HIGH_ACCURACY,
2519d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius                               {}, {}, &errno_ignored));
2529d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius}
2539d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius
25465b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan WangTEST_F(ScanUtilsTest, CanHandleScanRequestFailure) {
25565b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang  NL80211Packet response = CreateControlMessageError(kFakeErrorCode);
25665b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang  EXPECT_CALL(
25765b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang      netlink_manager_,
25865b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang      SendMessageAndGetResponses(
25965b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang          DoesNL80211PacketMatchCommand(NL80211_CMD_TRIGGER_SCAN), _)).
26065b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang              WillOnce(Invoke(bind(
26165b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang                  AppendMessageAndReturn, response, true, _1, _2)));
262793978cb7f2f227f1ab28135caeb75dd4ed48e6cNingyuan Wang  int error_code;
2639d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius  EXPECT_FALSE(scan_utils_.Scan(kFakeInterfaceIndex, kFakeUseRandomMAC,
2649d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius                               kFakeScanType, {}, {}, &error_code));
265793978cb7f2f227f1ab28135caeb75dd4ed48e6cNingyuan Wang  EXPECT_EQ(kFakeErrorCode, error_code);
26665b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang}
26765b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang
26865b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan WangTEST_F(ScanUtilsTest, CanSendSchedScanRequest) {
26965b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang  NL80211Packet response = CreateControlMessageAck();
27065b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang  EXPECT_CALL(
27165b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang      netlink_manager_,
27265b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang       SendMessageAndGetResponses(
27365b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang           DoesNL80211PacketMatchCommand(NL80211_CMD_START_SCHED_SCAN), _)).
27465b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang              WillOnce(Invoke(bind(
27565b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang                  AppendMessageAndReturn, response, true, _1, _2)));
276793978cb7f2f227f1ab28135caeb75dd4ed48e6cNingyuan Wang  int errno_ignored;
27765b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang  EXPECT_TRUE(scan_utils_.StartScheduledScan(
27865b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang      kFakeInterfaceIndex,
279dfbe7e4e12824527fac840391f31d2b4a4578e3eNingyuan Wang      SchedScanIntervalSetting(),
280c6ecdf8ea59f7de47edfd6161f059b8ab45d1f8fNingyuan Wang      kFake2gRssiThreshold, kFake5gRssiThreshold,
2819d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius      kFakeUseRandomMAC, kFakeRequestLowPower, {}, {}, {}, &errno_ignored));
28265b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang  // TODO(b/34231420): Add validation of requested scan ssids, threshold,
28365b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang  // and frequencies.
28465b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang}
28565b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang
28665b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan WangTEST_F(ScanUtilsTest, CanHandleSchedScanRequestFailure) {
28765b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang  NL80211Packet response = CreateControlMessageError(kFakeErrorCode);
28865b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang  EXPECT_CALL(
28965b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang      netlink_manager_,
29065b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang       SendMessageAndGetResponses(
29165b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang           DoesNL80211PacketMatchCommand(NL80211_CMD_START_SCHED_SCAN), _)).
29265b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang              WillOnce(Invoke(bind(
29365b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang                  AppendMessageAndReturn, response, true, _1, _2)));
294793978cb7f2f227f1ab28135caeb75dd4ed48e6cNingyuan Wang  int error_code;
29565b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang  EXPECT_FALSE(scan_utils_.StartScheduledScan(
29665b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang      kFakeInterfaceIndex,
297dfbe7e4e12824527fac840391f31d2b4a4578e3eNingyuan Wang      SchedScanIntervalSetting(),
298c6ecdf8ea59f7de47edfd6161f059b8ab45d1f8fNingyuan Wang      kFake2gRssiThreshold, kFake5gRssiThreshold,
2999d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius      kFakeUseRandomMAC, kFakeRequestLowPower, {}, {}, {}, &error_code));
300793978cb7f2f227f1ab28135caeb75dd4ed48e6cNingyuan Wang  EXPECT_EQ(kFakeErrorCode, error_code);
30165b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang}
30265b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang
3039d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan PiusTEST_F(ScanUtilsTest, CanSendSchedScanRequestForLowPowerScan) {
3049d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius  NL80211Packet response = CreateControlMessageAck();
3059d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius  EXPECT_CALL(
3069d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius      netlink_manager_,
3079d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius       SendMessageAndGetResponses(
3089d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius           AllOf(
3099d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius               DoesNL80211PacketMatchCommand(NL80211_CMD_START_SCHED_SCAN),
3109d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius               DoesNL80211PacketHaveAttributeWithUint32Value(
3119d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius                   NL80211_ATTR_SCAN_FLAGS, NL80211_SCAN_FLAG_LOW_POWER)),
3129d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius           _));
3139d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius  int errno_ignored;
3149d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius  scan_utils_.StartScheduledScan(
3159d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius      kFakeInterfaceIndex,
3169d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius      SchedScanIntervalSetting(),
3179d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius      kFake2gRssiThreshold, kFake5gRssiThreshold,
3189d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius      false, true, {}, {}, {}, &errno_ignored);
3199d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius}
3209d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius
321dfbe7e4e12824527fac840391f31d2b4a4578e3eNingyuan WangTEST_F(ScanUtilsTest, CanSpecifyScanPlansForSchedScanRequest) {
322dfbe7e4e12824527fac840391f31d2b4a4578e3eNingyuan Wang  EXPECT_CALL(
323dfbe7e4e12824527fac840391f31d2b4a4578e3eNingyuan Wang      netlink_manager_,
324dfbe7e4e12824527fac840391f31d2b4a4578e3eNingyuan Wang       SendMessageAndGetResponses(
325dfbe7e4e12824527fac840391f31d2b4a4578e3eNingyuan Wang           AllOf(
326dfbe7e4e12824527fac840391f31d2b4a4578e3eNingyuan Wang               DoesNL80211PacketMatchCommand(NL80211_CMD_START_SCHED_SCAN),
327dfbe7e4e12824527fac840391f31d2b4a4578e3eNingyuan Wang               DoesNL80211PacketHaveAttribute(NL80211_ATTR_SCHED_SCAN_PLANS),
328dfbe7e4e12824527fac840391f31d2b4a4578e3eNingyuan Wang               Not(DoesNL80211PacketHaveAttribute(
329dfbe7e4e12824527fac840391f31d2b4a4578e3eNingyuan Wang                   NL80211_ATTR_SCHED_SCAN_INTERVAL))),
330dfbe7e4e12824527fac840391f31d2b4a4578e3eNingyuan Wang           _));
331dfbe7e4e12824527fac840391f31d2b4a4578e3eNingyuan Wang  int errno_ignored;
332dfbe7e4e12824527fac840391f31d2b4a4578e3eNingyuan Wang  SchedScanIntervalSetting interval_setting{
333dfbe7e4e12824527fac840391f31d2b4a4578e3eNingyuan Wang      {{kFakeScheduledScanIntervalMs, 10 /* repeated times */}},
334dfbe7e4e12824527fac840391f31d2b4a4578e3eNingyuan Wang      kFakeScheduledScanIntervalMs * 3 /* interval for infinite scans */};
335dfbe7e4e12824527fac840391f31d2b4a4578e3eNingyuan Wang
336dfbe7e4e12824527fac840391f31d2b4a4578e3eNingyuan Wang  scan_utils_.StartScheduledScan(
337dfbe7e4e12824527fac840391f31d2b4a4578e3eNingyuan Wang      kFakeInterfaceIndex,
338dfbe7e4e12824527fac840391f31d2b4a4578e3eNingyuan Wang      interval_setting,
339c6ecdf8ea59f7de47edfd6161f059b8ab45d1f8fNingyuan Wang      kFake2gRssiThreshold, kFake5gRssiThreshold,
3409d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius      kFakeUseRandomMAC, kFakeRequestLowPower, {}, {}, {}, &errno_ignored);
341dfbe7e4e12824527fac840391f31d2b4a4578e3eNingyuan Wang}
342dfbe7e4e12824527fac840391f31d2b4a4578e3eNingyuan Wang
343dfbe7e4e12824527fac840391f31d2b4a4578e3eNingyuan WangTEST_F(ScanUtilsTest, CanSpecifySingleIntervalForSchedScanRequest) {
344dfbe7e4e12824527fac840391f31d2b4a4578e3eNingyuan Wang  EXPECT_CALL(
345dfbe7e4e12824527fac840391f31d2b4a4578e3eNingyuan Wang      netlink_manager_,
346dfbe7e4e12824527fac840391f31d2b4a4578e3eNingyuan Wang       SendMessageAndGetResponses(
347dfbe7e4e12824527fac840391f31d2b4a4578e3eNingyuan Wang           AllOf(
348dfbe7e4e12824527fac840391f31d2b4a4578e3eNingyuan Wang               DoesNL80211PacketMatchCommand(NL80211_CMD_START_SCHED_SCAN),
349dfbe7e4e12824527fac840391f31d2b4a4578e3eNingyuan Wang               DoesNL80211PacketHaveAttribute(NL80211_ATTR_SCHED_SCAN_INTERVAL),
350dfbe7e4e12824527fac840391f31d2b4a4578e3eNingyuan Wang               Not(DoesNL80211PacketHaveAttribute(
351dfbe7e4e12824527fac840391f31d2b4a4578e3eNingyuan Wang                   NL80211_ATTR_SCHED_SCAN_PLANS))),
352dfbe7e4e12824527fac840391f31d2b4a4578e3eNingyuan Wang           _));
353dfbe7e4e12824527fac840391f31d2b4a4578e3eNingyuan Wang  int errno_ignored;
354dfbe7e4e12824527fac840391f31d2b4a4578e3eNingyuan Wang  SchedScanIntervalSetting interval_setting{{}, kFakeScheduledScanIntervalMs};
355dfbe7e4e12824527fac840391f31d2b4a4578e3eNingyuan Wang
356dfbe7e4e12824527fac840391f31d2b4a4578e3eNingyuan Wang  scan_utils_.StartScheduledScan(
357dfbe7e4e12824527fac840391f31d2b4a4578e3eNingyuan Wang      kFakeInterfaceIndex,
358dfbe7e4e12824527fac840391f31d2b4a4578e3eNingyuan Wang      interval_setting,
359c6ecdf8ea59f7de47edfd6161f059b8ab45d1f8fNingyuan Wang      kFake2gRssiThreshold, kFake5gRssiThreshold,
3609d096b2f0027b91e5eed40c0e2482d238cdf7c8aRoshan Pius      kFakeUseRandomMAC, kFakeRequestLowPower, {}, {}, {}, &errno_ignored);
361dfbe7e4e12824527fac840391f31d2b4a4578e3eNingyuan Wang}
362dfbe7e4e12824527fac840391f31d2b4a4578e3eNingyuan Wang
3631aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan WangTEST_F(ScanUtilsTest, CanPrioritizeLastSeenSinceBootNetlinkAttribute) {
3641aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang  constexpr uint64_t kLastSeenTimestampNanoSeconds = 123456;
3651aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang  constexpr uint64_t kBssTsfTimestampMicroSeconds = 654321;
3661aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang  NL80211NestedAttr bss(NL80211_ATTR_BSS);
3671aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang  bss.AddAttribute(
3681aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang      NL80211Attr<uint64_t>(NL80211_BSS_LAST_SEEN_BOOTTIME,
3691aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang                            kLastSeenTimestampNanoSeconds));
3701aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang  bss.AddAttribute(
3711aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang      NL80211Attr<uint64_t>(NL80211_BSS_TSF, kBssTsfTimestampMicroSeconds));
3721aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang  uint64_t timestamp_microseconds;
3731aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang  EXPECT_TRUE(scan_utils_.GetBssTimestampForTesting(
3741aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang      bss, &timestamp_microseconds));
3751aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang  EXPECT_EQ(kLastSeenTimestampNanoSeconds/1000, timestamp_microseconds);
3761aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang}
3771aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang
3781aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan WangTEST_F(ScanUtilsTest, CanHandleMissingLastSeenSinceBootNetlinkAttribute) {
3791aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang  constexpr uint64_t kBssTsfTimestampMicroSeconds = 654321;
3801aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang  NL80211NestedAttr bss(NL80211_ATTR_BSS);
3811aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang  bss.AddAttribute(
3821aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang      NL80211Attr<uint64_t>(NL80211_BSS_TSF, kBssTsfTimestampMicroSeconds));
3831aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang  uint64_t timestamp_microseconds;
3841aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang  EXPECT_TRUE(scan_utils_.GetBssTimestampForTesting(
3851aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang      bss, &timestamp_microseconds));
3861aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang  EXPECT_EQ(kBssTsfTimestampMicroSeconds, timestamp_microseconds);
3871aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang}
3881aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang
3891aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang// Probe TSF is newer.
3901aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan WangTEST_F(ScanUtilsTest, CanPickMostRecentTimestampBetweenBetweenProbeAndBeacon1) {
3911aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang  constexpr uint64_t kBssBeaconTsfTimestampMicroSeconds = 654321;
3921aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang  constexpr uint64_t kBssTsfTimestampMicroSeconds =
3931aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang      kBssBeaconTsfTimestampMicroSeconds + 2000;
3941aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang  NL80211NestedAttr bss(NL80211_ATTR_BSS);
3951aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang  bss.AddAttribute(
3961aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang      NL80211Attr<uint64_t>(NL80211_BSS_BEACON_TSF,
3971aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang                            kBssBeaconTsfTimestampMicroSeconds));
3981aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang  bss.AddAttribute(
3991aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang      NL80211Attr<uint64_t>(NL80211_BSS_TSF, kBssTsfTimestampMicroSeconds));
4001aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang  uint64_t timestamp_microseconds;
4011aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang  EXPECT_TRUE(scan_utils_.GetBssTimestampForTesting(
4021aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang      bss, &timestamp_microseconds));
4031aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang  EXPECT_EQ(kBssTsfTimestampMicroSeconds, timestamp_microseconds);
4041aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang}
4051aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang
4061aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang// Beacon TSF is newer.
4071aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan WangTEST_F(ScanUtilsTest, CanPickMostRecentTimestampBetweenBetweenProbeAndBeacon2) {
4081aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang  constexpr uint64_t kBssTsfTimestampMicroSeconds = 654321;
4091aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang  constexpr uint64_t kBssBeaconTsfTimestampMicroSeconds =
4101aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang      kBssTsfTimestampMicroSeconds + 2000;
4111aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang  NL80211NestedAttr bss(NL80211_ATTR_BSS);
4121aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang  bss.AddAttribute(
4131aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang      NL80211Attr<uint64_t>(NL80211_BSS_BEACON_TSF,
4141aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang                            kBssBeaconTsfTimestampMicroSeconds));
4151aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang  bss.AddAttribute(
4161aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang      NL80211Attr<uint64_t>(NL80211_BSS_TSF, kBssTsfTimestampMicroSeconds));
4171aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang  uint64_t timestamp_microseconds;
4181aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang  EXPECT_TRUE(scan_utils_.GetBssTimestampForTesting(
4191aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang      bss, &timestamp_microseconds));
4201aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang  EXPECT_EQ(kBssBeaconTsfTimestampMicroSeconds, timestamp_microseconds);
4211aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang}
4221aadd2c3781ee882e77dae2f4dc38fe3574fdca7Ningyuan Wang
42365b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang}  // namespace wificond
42465b365fe4b6a99f9dab98515c1b96bd725cb56a8Ningyuan Wang}  // namespace android
425