return false;
}
-bool ScanUtils::StartFullScan(uint32_t interface_index) {
+bool ScanUtils::StartFullScan(uint32_t interface_index,
+ bool request_random_mac) {
// Using empty SSID for a wildcard scan.
vector<vector<uint8_t>> ssids{vector<uint8_t>{0}};
- return Scan(interface_index, ssids, vector<uint32_t>());
+ return Scan(interface_index, request_random_mac, ssids, vector<uint32_t>());
}
bool ScanUtils::Scan(uint32_t interface_index,
+ bool request_random_mac,
const vector<vector<uint8_t>>& ssids,
const vector<uint32_t>& freqs) {
NL80211Packet trigger_scan(
trigger_scan.AddAttribute(freqs_attr);
}
+ if (request_random_mac) {
+ trigger_scan.AddAttribute(
+ NL80211Attr<uint32_t>(NL80211_ATTR_SCAN_FLAGS,
+ NL80211_SCAN_FLAG_RANDOM_ADDR));
+ }
// We are receiving an ERROR/ACK message instead of the actual
// scan results here, so it is OK to expect a timely response because
// kernel is supposed to send the ERROR/ACK back before the scan starts.
uint32_t interface_index,
uint32_t interval_ms,
int32_t rssi_threshold,
+ bool request_random_mac,
const std::vector<std::vector<uint8_t>>& scan_ssids,
const std::vector<std::vector<uint8_t>>& match_ssids,
const std::vector<uint32_t>& freqs) {
start_sched_scan.AddAttribute(
NL80211Attr<uint32_t>(NL80211_ATTR_SCHED_SCAN_INTERVAL, interval_ms));
start_sched_scan.AddAttribute(scan_match_attr);
+ if (request_random_mac) {
+ start_sched_scan.AddAttribute(
+ NL80211Attr<uint32_t>(NL80211_ATTR_SCAN_FLAGS,
+ NL80211_SCAN_FLAG_RANDOM_ADDR));
+ }
vector<unique_ptr<const NL80211Packet>> response;
if (!netlink_manager_->SendMessageAndGetAck(start_sched_scan)) {
// Start a full scan on interface with index |interface_index|.
// This will scan for all ssids and frequencies.
+ // |request_random_mac| is used for asking device/driver to use a random MAC
+ // address during scan.
+ // This flag should only be set if kernel supports this feature as
+ // |supports_random_mac_oneshot_scan| indicates.
// Returns true on success.
- virtual bool StartFullScan(uint32_t interface_index);
+ virtual bool StartFullScan(uint32_t interface_index, bool request_random_mac);
// Send scan request to kernel for interface with index |interface_index|.
+ // |request_random_mac| is used for asking device/driver to use a random MAC
+ // address during scan.
+ // This flag should only be set if kernel supports this feature as
+ // |supports_random_mac_oneshot_scan| indicates.
// |ssids| is a vector of ssids we request to scan, which mostly is used
// for hidden networks.
// If |ssids| is an empty vector, it will do a passive scan.
// If |freqs| is an empty vector, it will scan all supported frequencies.
// Returns true on success.
virtual bool Scan(uint32_t interface_index,
+ bool request_random_mac,
const std::vector<std::vector<uint8_t>>& ssids,
const std::vector<uint32_t>& freqs);
// |rssi_threshold| is the minimum RSSI threshold value as a filter.
// |scan_ssids| is a vector of ssids we request to scan, which is mostly
// used for hidden networks.
+ // |request_random_mac| is used for asking device/driver to use a random MAC
+ // address during scan.
+ // This flag should only be set if kernel supports this feature as
+ // as |supports_random_mac_sched_scan| indicates.
// If |scan_ssids| is an empty vector, it will do a passive scan.
// If |scan_ssids| contains an empty string, it will a scan for all ssids.
// |freqs| is a vector of frequencies we request to scan.
uint32_t interface_index,
uint32_t interval_ms,
int32_t rssi_threshold,
+ bool request_random_mac,
const std::vector<std::vector<uint8_t>>& scan_ssids,
const std::vector<std::vector<uint8_t>>& match_ssids,
const std::vector<uint32_t>& freqs);
if (!CheckIsValid()) {
return Status::ok();
}
+
+ bool random_mac = wiphy_features_.supports_random_mac_oneshot_scan;
+
if (scan_settings.is_full_scan_) {
- if (!scan_utils_->StartFullScan(interface_index_)) {
+ if (!scan_utils_->StartFullScan(interface_index_, random_mac)) {
*out_success = false;
return Status::ok();
}
freqs.push_back(channel.frequency_);
}
- if (!scan_utils_->Scan(interface_index_, ssids, freqs)) {
+ if (!scan_utils_->Scan(interface_index_, random_mac, ssids, freqs)) {
*out_success = false;
LOG(ERROR) << "Failed to start a scan";
return Status::ok();
MockScanUtils(NetlinkManager* netlink_manager);
~MockScanUtils() override = default;
- MOCK_METHOD1(StartFullScan, bool(
- uint32_t interface_index));
+ MOCK_METHOD2(StartFullScan, bool(
+ uint32_t interface_index,
+ bool random_mac));
MOCK_METHOD2(GetScanResult, bool(
uint32_t interface_index,
std::vector<::com::android::server::wifi::wificond::NativeScanResult>* out_scan_results));
- MOCK_METHOD3(Scan, bool(
+ MOCK_METHOD4(Scan, bool(
uint32_t interface_index,
+ bool random_mac,
const std::vector<std::vector<uint8_t>>& ssids,
const std::vector<uint32_t>& freqs));
constexpr uint32_t kFakeSequenceNumber = 1984;
constexpr int kFakeErrorCode = EIO;
constexpr int32_t kFakeRssiThreshold = -80;
+constexpr bool kFakeUseRandomMAC = true;
// Currently, control messages are only created by the kernel and sent to us.
// Therefore NL80211Packet doesn't have corresponding constructor.
WillOnce(Invoke(bind(
AppendMessageAndReturn, response, true, _1, _2)));
- EXPECT_TRUE(scan_utils_.Scan(kFakeInterfaceIndex, {}, {}));
+ EXPECT_TRUE(scan_utils_.Scan(kFakeInterfaceIndex, kFakeUseRandomMAC, {}, {}));
// TODO(b/34231420): Add validation of requested scan ssids, threshold,
// and frequencies.
}
DoesNL80211PacketMatchCommand(NL80211_CMD_TRIGGER_SCAN), _)).
WillOnce(Invoke(bind(
AppendMessageAndReturn, response, true, _1, _2)));
- EXPECT_FALSE(scan_utils_.Scan(kFakeInterfaceIndex, {}, {}));
+ EXPECT_FALSE(scan_utils_.Scan(kFakeInterfaceIndex, kFakeUseRandomMAC, {}, {}));
}
TEST_F(ScanUtilsTest, CanSendSchedScanRequest) {
AppendMessageAndReturn, response, true, _1, _2)));
EXPECT_TRUE(scan_utils_.StartScheduledScan(
kFakeInterfaceIndex,
- kFakeScheduledScanIntervalMs, kFakeRssiThreshold, {}, {}, {}));
+ kFakeScheduledScanIntervalMs,
+ kFakeRssiThreshold, kFakeUseRandomMAC, {}, {}, {}));
// TODO(b/34231420): Add validation of requested scan ssids, threshold,
// and frequencies.
}
AppendMessageAndReturn, response, true, _1, _2)));
EXPECT_FALSE(scan_utils_.StartScheduledScan(
kFakeInterfaceIndex,
- kFakeScheduledScanIntervalMs, kFakeRssiThreshold, {}, {}, {}));
+ kFakeScheduledScanIntervalMs,
+ kFakeRssiThreshold, kFakeUseRandomMAC, {}, {}, {}));
}
TEST_F(ScanUtilsTest, CanSendFullScanRequest) {
DoesNL80211PacketMatchCommand(NL80211_CMD_TRIGGER_SCAN), _)).
WillOnce(Invoke(bind(
AppendMessageAndReturn, response, true, _1, _2)));
- EXPECT_TRUE(scan_utils_.StartFullScan(kFakeInterfaceIndex));
+ EXPECT_TRUE(scan_utils_.StartFullScan(kFakeInterfaceIndex, kFakeUseRandomMAC));
}
TEST_F(ScanUtilsTest, CanHandleFullScanRequestFailure) {
DoesNL80211PacketMatchCommand(NL80211_CMD_TRIGGER_SCAN), _)).
WillOnce(Invoke(bind(
AppendMessageAndReturn, response, true, _1, _2)));
- EXPECT_FALSE(scan_utils_.StartFullScan(kFakeInterfaceIndex));
+ EXPECT_FALSE(scan_utils_.StartFullScan(kFakeInterfaceIndex, kFakeUseRandomMAC));
}
} // namespace wificond