blob: 8e507a832f3d33447858d8ab024c238cedd07c22 [file] [log] [blame]
// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "shill/wifi/wifi.h"
#include <linux/if.h>
#include <linux/netlink.h> // Needs typedefs from sys/socket.h.
#include <netinet/ether.h>
#include <sys/socket.h>
#include <memory>
#include <set>
#include <string>
#include <utility>
#include <vector>
#include <base/check.h>
#include <base/files/file_util.h>
#include <base/memory/ref_counted.h>
#include <base/stl_util.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/string_split.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>
#include <chromeos/dbus/service_constants.h>
#include <patchpanel/proto_bindings/patchpanel_service.pb.h>
#include "shill/dhcp/mock_dhcp_config.h"
#include "shill/dhcp/mock_dhcp_provider.h"
#include "shill/error.h"
#include "shill/event_dispatcher.h"
#include "shill/geolocation_info.h"
#include "shill/ip_address_store.h"
#include "shill/key_value_store.h"
#include "shill/logging.h"
#include "shill/manager.h"
#include "shill/mock_adaptors.h"
#include "shill/mock_connection.h"
#include "shill/mock_control.h"
#include "shill/mock_device.h"
#include "shill/mock_device_info.h"
#include "shill/mock_eap_credentials.h"
#include "shill/mock_event_dispatcher.h"
#include "shill/mock_ipconfig.h"
#include "shill/mock_log.h"
#include "shill/mock_manager.h"
#include "shill/mock_metrics.h"
#include "shill/mock_power_manager.h"
#include "shill/mock_profile.h"
#include "shill/net/ieee80211.h"
#include "shill/net/ip_address.h"
#include "shill/net/mock_netlink_manager.h"
#include "shill/net/mock_rtnl_handler.h"
#include "shill/net/mock_time.h"
#include "shill/net/netlink_message_matchers.h"
#include "shill/net/netlink_packet.h"
#include "shill/net/nl80211_attribute.h"
#include "shill/net/nl80211_message.h"
#include "shill/property_store_test.h"
#include "shill/supplicant/mock_supplicant_bss_proxy.h"
#include "shill/supplicant/mock_supplicant_eap_state_handler.h"
#include "shill/supplicant/mock_supplicant_interface_proxy.h"
#include "shill/supplicant/mock_supplicant_network_proxy.h"
#include "shill/supplicant/mock_supplicant_process_proxy.h"
#include "shill/supplicant/supplicant_manager.h"
#include "shill/supplicant/wpa_supplicant.h"
#include "shill/technology.h"
#include "shill/test_event_dispatcher.h"
#include "shill/testing.h"
#include "shill/wifi/mock_wake_on_wifi.h"
#include "shill/wifi/mock_wifi_provider.h"
#include "shill/wifi/mock_wifi_service.h"
#include "shill/wifi/wake_on_wifi.h"
#include "shill/wifi/wifi_endpoint.h"
#include "shill/wifi/wifi_service.h"
using ::testing::_;
using ::testing::AnyNumber;
using ::testing::AtLeast;
using ::testing::ByMove;
using ::testing::ContainsRegex;
using ::testing::DoAll;
using ::testing::EndsWith;
using ::testing::HasSubstr;
using ::testing::InSequence;
using ::testing::Invoke;
using ::testing::InvokeWithoutArgs;
using ::testing::Mock;
using ::testing::NiceMock;
using ::testing::Ref;
using ::testing::Return;
using ::testing::ReturnRef;
using ::testing::SetArgPointee;
using ::testing::StrEq;
using ::testing::StrictMock;
using ::testing::Test;
namespace shill {
namespace {
const uint16_t kNl80211FamilyId = 0x13;
const uint16_t kRandomScanFrequency1 = 5600;
const uint16_t kRandomScanFrequency2 = 5560;
const uint16_t kRandomScanFrequency3 = 2422;
const int kInterfaceIndex = 1234;
// Bytes representing a NL80211_CMD_NEW_WIPHY message reporting the WiFi
// capabilities of a NIC with wiphy index |kNewWiphyNlMsg_WiphyIndex| which
// supports operating bands with the frequencies specified in
// |kNewWiphyNlMsg_UniqueFrequencies|.
const uint8_t kNewWiphyNlMsg[] = {
0x68, 0x0c, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0xf6, 0x31, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00,
0x02, 0x00, 0x00, 0x00, 0x09, 0x00, 0x02, 0x00, 0x70, 0x68, 0x79, 0x30,
0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x2e, 0x00, 0x01, 0x00, 0x00, 0x00,
0x05, 0x00, 0x3d, 0x00, 0x07, 0x00, 0x00, 0x00, 0x05, 0x00, 0x3e, 0x00,
0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x3f, 0x00, 0xff, 0xff, 0xff, 0xff,
0x08, 0x00, 0x40, 0x00, 0xff, 0xff, 0xff, 0xff, 0x05, 0x00, 0x59, 0x00,
0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x00, 0x00,
0x05, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x38, 0x00,
0xd1, 0x08, 0x00, 0x00, 0x06, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x85, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x68, 0x00,
0x04, 0x00, 0x8b, 0x00, 0x04, 0x00, 0x8c, 0x00, 0x18, 0x00, 0x39, 0x00,
0x01, 0xac, 0x0f, 0x00, 0x05, 0xac, 0x0f, 0x00, 0x02, 0xac, 0x0f, 0x00,
0x04, 0xac, 0x0f, 0x00, 0x06, 0xac, 0x0f, 0x00, 0x05, 0x00, 0x56, 0x00,
0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x66, 0x00, 0x08, 0x00, 0x71, 0x00,
0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x72, 0x00, 0x03, 0x00, 0x00, 0x00,
0x08, 0x00, 0x69, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x6a, 0x00,
0x03, 0x00, 0x00, 0x00, 0x24, 0x00, 0x20, 0x00, 0x04, 0x00, 0x01, 0x00,
0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00,
0x04, 0x00, 0x05, 0x00, 0x04, 0x00, 0x06, 0x00, 0x04, 0x00, 0x08, 0x00,
0x04, 0x00, 0x09, 0x00, 0x50, 0x05, 0x16, 0x00, 0xf8, 0x01, 0x00, 0x00,
0x14, 0x00, 0x03, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x04, 0x00,
0xef, 0x11, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x03, 0x00, 0x00, 0x00,
0x05, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0x28, 0x01, 0x01, 0x00,
0x14, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x6c, 0x09, 0x00, 0x00,
0x08, 0x00, 0x06, 0x00, 0x6c, 0x07, 0x00, 0x00, 0x14, 0x00, 0x01, 0x00,
0x08, 0x00, 0x01, 0x00, 0x71, 0x09, 0x00, 0x00, 0x08, 0x00, 0x06, 0x00,
0x6c, 0x07, 0x00, 0x00, 0x14, 0x00, 0x02, 0x00, 0x08, 0x00, 0x01, 0x00,
0x76, 0x09, 0x00, 0x00, 0x08, 0x00, 0x06, 0x00, 0x6c, 0x07, 0x00, 0x00,
0x14, 0x00, 0x03, 0x00, 0x08, 0x00, 0x01, 0x00, 0x7b, 0x09, 0x00, 0x00,
0x08, 0x00, 0x06, 0x00, 0x6c, 0x07, 0x00, 0x00, 0x14, 0x00, 0x04, 0x00,
0x08, 0x00, 0x01, 0x00, 0x80, 0x09, 0x00, 0x00, 0x08, 0x00, 0x06, 0x00,
0x6c, 0x07, 0x00, 0x00, 0x14, 0x00, 0x05, 0x00, 0x08, 0x00, 0x01, 0x00,
0x85, 0x09, 0x00, 0x00, 0x08, 0x00, 0x06, 0x00, 0x6c, 0x07, 0x00, 0x00,
0x14, 0x00, 0x06, 0x00, 0x08, 0x00, 0x01, 0x00, 0x8a, 0x09, 0x00, 0x00,
0x08, 0x00, 0x06, 0x00, 0x6c, 0x07, 0x00, 0x00, 0x14, 0x00, 0x07, 0x00,
0x08, 0x00, 0x01, 0x00, 0x8f, 0x09, 0x00, 0x00, 0x08, 0x00, 0x06, 0x00,
0x6c, 0x07, 0x00, 0x00, 0x14, 0x00, 0x08, 0x00, 0x08, 0x00, 0x01, 0x00,
0x94, 0x09, 0x00, 0x00, 0x08, 0x00, 0x06, 0x00, 0x6c, 0x07, 0x00, 0x00,
0x14, 0x00, 0x09, 0x00, 0x08, 0x00, 0x01, 0x00, 0x99, 0x09, 0x00, 0x00,
0x08, 0x00, 0x06, 0x00, 0x6c, 0x07, 0x00, 0x00, 0x14, 0x00, 0x0a, 0x00,
0x08, 0x00, 0x01, 0x00, 0x9e, 0x09, 0x00, 0x00, 0x08, 0x00, 0x06, 0x00,
0x6c, 0x07, 0x00, 0x00, 0x18, 0x00, 0x0b, 0x00, 0x08, 0x00, 0x01, 0x00,
0xa3, 0x09, 0x00, 0x00, 0x04, 0x00, 0x03, 0x00, 0x08, 0x00, 0x06, 0x00,
0x6c, 0x07, 0x00, 0x00, 0x18, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x01, 0x00,
0xa8, 0x09, 0x00, 0x00, 0x04, 0x00, 0x03, 0x00, 0x08, 0x00, 0x06, 0x00,
0x6c, 0x07, 0x00, 0x00, 0x18, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x01, 0x00,
0xb4, 0x09, 0x00, 0x00, 0x04, 0x00, 0x03, 0x00, 0x08, 0x00, 0x06, 0x00,
0xd0, 0x07, 0x00, 0x00, 0xa0, 0x00, 0x02, 0x00, 0x0c, 0x00, 0x00, 0x00,
0x08, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00,
0x08, 0x00, 0x01, 0x00, 0x14, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00,
0x10, 0x00, 0x02, 0x00, 0x08, 0x00, 0x01, 0x00, 0x37, 0x00, 0x00, 0x00,
0x04, 0x00, 0x02, 0x00, 0x10, 0x00, 0x03, 0x00, 0x08, 0x00, 0x01, 0x00,
0x6e, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x0c, 0x00, 0x04, 0x00,
0x08, 0x00, 0x01, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x05, 0x00,
0x08, 0x00, 0x01, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x06, 0x00,
0x08, 0x00, 0x01, 0x00, 0x78, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x07, 0x00,
0x08, 0x00, 0x01, 0x00, 0xb4, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x08, 0x00,
0x08, 0x00, 0x01, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x09, 0x00,
0x08, 0x00, 0x01, 0x00, 0x68, 0x01, 0x00, 0x00, 0x0c, 0x00, 0x0a, 0x00,
0x08, 0x00, 0x01, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x0c, 0x00, 0x0b, 0x00,
0x08, 0x00, 0x01, 0x00, 0x1c, 0x02, 0x00, 0x00, 0x54, 0x03, 0x01, 0x00,
0x14, 0x00, 0x03, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x04, 0x00,
0xef, 0x11, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x03, 0x00, 0x00, 0x00,
0x05, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0xc0, 0x02, 0x01, 0x00,
0x14, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x3c, 0x14, 0x00, 0x00,
0x08, 0x00, 0x06, 0x00, 0xd0, 0x07, 0x00, 0x00, 0x1c, 0x00, 0x01, 0x00,
0x08, 0x00, 0x01, 0x00, 0x50, 0x14, 0x00, 0x00, 0x04, 0x00, 0x03, 0x00,
0x04, 0x00, 0x04, 0x00, 0x08, 0x00, 0x06, 0x00, 0xd0, 0x07, 0x00, 0x00,
0x14, 0x00, 0x02, 0x00, 0x08, 0x00, 0x01, 0x00, 0x64, 0x14, 0x00, 0x00,
0x08, 0x00, 0x06, 0x00, 0xd0, 0x07, 0x00, 0x00, 0x14, 0x00, 0x03, 0x00,
0x08, 0x00, 0x01, 0x00, 0x78, 0x14, 0x00, 0x00, 0x08, 0x00, 0x06, 0x00,
0xd0, 0x07, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x08, 0x00, 0x01, 0x00,
0x8c, 0x14, 0x00, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00,
0x04, 0x00, 0x05, 0x00, 0x08, 0x00, 0x06, 0x00, 0xd0, 0x07, 0x00, 0x00,
0x20, 0x00, 0x05, 0x00, 0x08, 0x00, 0x01, 0x00, 0xa0, 0x14, 0x00, 0x00,
0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x05, 0x00,
0x08, 0x00, 0x06, 0x00, 0xd0, 0x07, 0x00, 0x00, 0x20, 0x00, 0x06, 0x00,
0x08, 0x00, 0x01, 0x00, 0xb4, 0x14, 0x00, 0x00, 0x04, 0x00, 0x03, 0x00,
0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x05, 0x00, 0x08, 0x00, 0x06, 0x00,
0xd0, 0x07, 0x00, 0x00, 0x20, 0x00, 0x07, 0x00, 0x08, 0x00, 0x01, 0x00,
0xc8, 0x14, 0x00, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00,
0x04, 0x00, 0x05, 0x00, 0x08, 0x00, 0x06, 0x00, 0xd0, 0x07, 0x00, 0x00,
0x20, 0x00, 0x08, 0x00, 0x08, 0x00, 0x01, 0x00, 0x7c, 0x15, 0x00, 0x00,
0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x05, 0x00,
0x08, 0x00, 0x06, 0x00, 0xd0, 0x07, 0x00, 0x00, 0x20, 0x00, 0x09, 0x00,
0x08, 0x00, 0x01, 0x00, 0x90, 0x15, 0x00, 0x00, 0x04, 0x00, 0x03, 0x00,
0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x05, 0x00, 0x08, 0x00, 0x06, 0x00,
0xd0, 0x07, 0x00, 0x00, 0x20, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x01, 0x00,
0xa4, 0x15, 0x00, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00,
0x04, 0x00, 0x05, 0x00, 0x08, 0x00, 0x06, 0x00, 0xd0, 0x07, 0x00, 0x00,
0x20, 0x00, 0x0b, 0x00, 0x08, 0x00, 0x01, 0x00, 0xb8, 0x15, 0x00, 0x00,
0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x05, 0x00,
0x08, 0x00, 0x06, 0x00, 0xd0, 0x07, 0x00, 0x00, 0x20, 0x00, 0x0c, 0x00,
0x08, 0x00, 0x01, 0x00, 0xcc, 0x15, 0x00, 0x00, 0x04, 0x00, 0x03, 0x00,
0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x05, 0x00, 0x08, 0x00, 0x06, 0x00,
0xd0, 0x07, 0x00, 0x00, 0x20, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x01, 0x00,
0xe0, 0x15, 0x00, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00,
0x04, 0x00, 0x05, 0x00, 0x08, 0x00, 0x06, 0x00, 0xd0, 0x07, 0x00, 0x00,
0x20, 0x00, 0x0e, 0x00, 0x08, 0x00, 0x01, 0x00, 0xf4, 0x15, 0x00, 0x00,
0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x05, 0x00,
0x08, 0x00, 0x06, 0x00, 0xd0, 0x07, 0x00, 0x00, 0x20, 0x00, 0x0f, 0x00,
0x08, 0x00, 0x01, 0x00, 0x08, 0x16, 0x00, 0x00, 0x04, 0x00, 0x03, 0x00,
0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x05, 0x00, 0x08, 0x00, 0x06, 0x00,
0xd0, 0x07, 0x00, 0x00, 0x20, 0x00, 0x10, 0x00, 0x08, 0x00, 0x01, 0x00,
0x1c, 0x16, 0x00, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00,
0x04, 0x00, 0x05, 0x00, 0x08, 0x00, 0x06, 0x00, 0xd0, 0x07, 0x00, 0x00,
0x20, 0x00, 0x11, 0x00, 0x08, 0x00, 0x01, 0x00, 0x30, 0x16, 0x00, 0x00,
0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x05, 0x00,
0x08, 0x00, 0x06, 0x00, 0xd0, 0x07, 0x00, 0x00, 0x20, 0x00, 0x12, 0x00,
0x08, 0x00, 0x01, 0x00, 0x44, 0x16, 0x00, 0x00, 0x04, 0x00, 0x03, 0x00,
0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x05, 0x00, 0x08, 0x00, 0x06, 0x00,
0xd0, 0x07, 0x00, 0x00, 0x14, 0x00, 0x13, 0x00, 0x08, 0x00, 0x01, 0x00,
0x71, 0x16, 0x00, 0x00, 0x08, 0x00, 0x06, 0x00, 0xd0, 0x07, 0x00, 0x00,
0x1c, 0x00, 0x14, 0x00, 0x08, 0x00, 0x01, 0x00, 0x85, 0x16, 0x00, 0x00,
0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, 0x08, 0x00, 0x06, 0x00,
0xd0, 0x07, 0x00, 0x00, 0x1c, 0x00, 0x15, 0x00, 0x08, 0x00, 0x01, 0x00,
0x99, 0x16, 0x00, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00,
0x08, 0x00, 0x06, 0x00, 0xd0, 0x07, 0x00, 0x00, 0x1c, 0x00, 0x16, 0x00,
0x08, 0x00, 0x01, 0x00, 0xad, 0x16, 0x00, 0x00, 0x04, 0x00, 0x03, 0x00,
0x04, 0x00, 0x04, 0x00, 0x08, 0x00, 0x06, 0x00, 0xd0, 0x07, 0x00, 0x00,
0x1c, 0x00, 0x17, 0x00, 0x08, 0x00, 0x01, 0x00, 0xc1, 0x16, 0x00, 0x00,
0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, 0x08, 0x00, 0x06, 0x00,
0xd0, 0x07, 0x00, 0x00, 0x64, 0x00, 0x02, 0x00, 0x0c, 0x00, 0x00, 0x00,
0x08, 0x00, 0x01, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00,
0x08, 0x00, 0x01, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x02, 0x00,
0x08, 0x00, 0x01, 0x00, 0x78, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x03, 0x00,
0x08, 0x00, 0x01, 0x00, 0xb4, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x04, 0x00,
0x08, 0x00, 0x01, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x05, 0x00,
0x08, 0x00, 0x01, 0x00, 0x68, 0x01, 0x00, 0x00, 0x0c, 0x00, 0x06, 0x00,
0x08, 0x00, 0x01, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x0c, 0x00, 0x07, 0x00,
0x08, 0x00, 0x01, 0x00, 0x1c, 0x02, 0x00, 0x00, 0xd4, 0x00, 0x32, 0x00,
0x08, 0x00, 0x01, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00, 0x0b, 0x00, 0x00, 0x00,
0x08, 0x00, 0x04, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x05, 0x00,
0x13, 0x00, 0x00, 0x00, 0x08, 0x00, 0x06, 0x00, 0x19, 0x00, 0x00, 0x00,
0x08, 0x00, 0x07, 0x00, 0x25, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00,
0x26, 0x00, 0x00, 0x00, 0x08, 0x00, 0x09, 0x00, 0x27, 0x00, 0x00, 0x00,
0x08, 0x00, 0x0a, 0x00, 0x28, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0b, 0x00,
0x2b, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0c, 0x00, 0x37, 0x00, 0x00, 0x00,
0x08, 0x00, 0x0d, 0x00, 0x39, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0e, 0x00,
0x3b, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0f, 0x00, 0x43, 0x00, 0x00, 0x00,
0x08, 0x00, 0x10, 0x00, 0x31, 0x00, 0x00, 0x00, 0x08, 0x00, 0x11, 0x00,
0x41, 0x00, 0x00, 0x00, 0x08, 0x00, 0x12, 0x00, 0x42, 0x00, 0x00, 0x00,
0x08, 0x00, 0x13, 0x00, 0x52, 0x00, 0x00, 0x00, 0x08, 0x00, 0x14, 0x00,
0x51, 0x00, 0x00, 0x00, 0x08, 0x00, 0x15, 0x00, 0x54, 0x00, 0x00, 0x00,
0x08, 0x00, 0x16, 0x00, 0x57, 0x00, 0x00, 0x00, 0x08, 0x00, 0x17, 0x00,
0x55, 0x00, 0x00, 0x00, 0x08, 0x00, 0x18, 0x00, 0x2d, 0x00, 0x00, 0x00,
0x08, 0x00, 0x19, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x08, 0x00, 0x1a, 0x00,
0x30, 0x00, 0x00, 0x00, 0x08, 0x00, 0x6f, 0x00, 0x88, 0x13, 0x00, 0x00,
0x04, 0x00, 0x6c, 0x00, 0xac, 0x03, 0x63, 0x00, 0x04, 0x00, 0x00, 0x00,
0x84, 0x00, 0x01, 0x00, 0x06, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00,
0x06, 0x00, 0x65, 0x00, 0x10, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00,
0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00, 0x30, 0x00, 0x00, 0x00,
0x06, 0x00, 0x65, 0x00, 0x40, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00,
0x50, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00, 0x60, 0x00, 0x00, 0x00,
0x06, 0x00, 0x65, 0x00, 0x70, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00,
0x80, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00, 0x90, 0x00, 0x00, 0x00,
0x06, 0x00, 0x65, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00,
0xb0, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00, 0xc0, 0x00, 0x00, 0x00,
0x06, 0x00, 0x65, 0x00, 0xd0, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00,
0xe0, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00, 0xf0, 0x00, 0x00, 0x00,
0x84, 0x00, 0x02, 0x00, 0x06, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00,
0x06, 0x00, 0x65, 0x00, 0x10, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00,
0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00, 0x30, 0x00, 0x00, 0x00,
0x06, 0x00, 0x65, 0x00, 0x40, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00,
0x50, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00, 0x60, 0x00, 0x00, 0x00,
0x06, 0x00, 0x65, 0x00, 0x70, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00,
0x80, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00, 0x90, 0x00, 0x00, 0x00,
0x06, 0x00, 0x65, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00,
0xb0, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00, 0xc0, 0x00, 0x00, 0x00,
0x06, 0x00, 0x65, 0x00, 0xd0, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00,
0xe0, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00, 0xf0, 0x00, 0x00, 0x00,
0x84, 0x00, 0x03, 0x00, 0x06, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00,
0x06, 0x00, 0x65, 0x00, 0x10, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00,
0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00, 0x30, 0x00, 0x00, 0x00,
0x06, 0x00, 0x65, 0x00, 0x40, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00,
0x50, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00, 0x60, 0x00, 0x00, 0x00,
0x06, 0x00, 0x65, 0x00, 0x70, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00,
0x80, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00, 0x90, 0x00, 0x00, 0x00,
0x06, 0x00, 0x65, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00,
0xb0, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00, 0xc0, 0x00, 0x00, 0x00,
0x06, 0x00, 0x65, 0x00, 0xd0, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00,
0xe0, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00, 0xf0, 0x00, 0x00, 0x00,
0x84, 0x00, 0x04, 0x00, 0x06, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00,
0x06, 0x00, 0x65, 0x00, 0x10, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00,
0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00, 0x30, 0x00, 0x00, 0x00,
0x06, 0x00, 0x65, 0x00, 0x40, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00,
0x50, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00, 0x60, 0x00, 0x00, 0x00,
0x06, 0x00, 0x65, 0x00, 0x70, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00,
0x80, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00, 0x90, 0x00, 0x00, 0x00,
0x06, 0x00, 0x65, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00,
0xb0, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00, 0xc0, 0x00, 0x00, 0x00,
0x06, 0x00, 0x65, 0x00, 0xd0, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00,
0xe0, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00, 0xf0, 0x00, 0x00, 0x00,
0x04, 0x00, 0x05, 0x00, 0x04, 0x00, 0x06, 0x00, 0x84, 0x00, 0x07, 0x00,
0x06, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00,
0x10, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00, 0x20, 0x00, 0x00, 0x00,
0x06, 0x00, 0x65, 0x00, 0x30, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00,
0x40, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00, 0x50, 0x00, 0x00, 0x00,
0x06, 0x00, 0x65, 0x00, 0x60, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00,
0x70, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00, 0x80, 0x00, 0x00, 0x00,
0x06, 0x00, 0x65, 0x00, 0x90, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00,
0xa0, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00, 0xb0, 0x00, 0x00, 0x00,
0x06, 0x00, 0x65, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00,
0xd0, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00, 0xe0, 0x00, 0x00, 0x00,
0x06, 0x00, 0x65, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x84, 0x00, 0x08, 0x00,
0x06, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00,
0x10, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00, 0x20, 0x00, 0x00, 0x00,
0x06, 0x00, 0x65, 0x00, 0x30, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00,
0x40, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00, 0x50, 0x00, 0x00, 0x00,
0x06, 0x00, 0x65, 0x00, 0x60, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00,
0x70, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00, 0x80, 0x00, 0x00, 0x00,
0x06, 0x00, 0x65, 0x00, 0x90, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00,
0xa0, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00, 0xb0, 0x00, 0x00, 0x00,
0x06, 0x00, 0x65, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00,
0xd0, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00, 0xe0, 0x00, 0x00, 0x00,
0x06, 0x00, 0x65, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x84, 0x00, 0x09, 0x00,
0x06, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00,
0x10, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00, 0x20, 0x00, 0x00, 0x00,
0x06, 0x00, 0x65, 0x00, 0x30, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00,
0x40, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00, 0x50, 0x00, 0x00, 0x00,
0x06, 0x00, 0x65, 0x00, 0x60, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00,
0x70, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00, 0x80, 0x00, 0x00, 0x00,
0x06, 0x00, 0x65, 0x00, 0x90, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00,
0xa0, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00, 0xb0, 0x00, 0x00, 0x00,
0x06, 0x00, 0x65, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00,
0xd0, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00, 0xe0, 0x00, 0x00, 0x00,
0x06, 0x00, 0x65, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x14, 0x01, 0x64, 0x00,
0x04, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x06, 0x00, 0x65, 0x00,
0xd0, 0x00, 0x00, 0x00, 0x14, 0x00, 0x02, 0x00, 0x06, 0x00, 0x65, 0x00,
0x40, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00, 0xd0, 0x00, 0x00, 0x00,
0x3c, 0x00, 0x03, 0x00, 0x06, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00,
0x06, 0x00, 0x65, 0x00, 0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00,
0x40, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00, 0xa0, 0x00, 0x00, 0x00,
0x06, 0x00, 0x65, 0x00, 0xb0, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00,
0xc0, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00, 0xd0, 0x00, 0x00, 0x00,
0x3c, 0x00, 0x04, 0x00, 0x06, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00,
0x06, 0x00, 0x65, 0x00, 0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00,
0x40, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00, 0xa0, 0x00, 0x00, 0x00,
0x06, 0x00, 0x65, 0x00, 0xb0, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00,
0xc0, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00, 0xd0, 0x00, 0x00, 0x00,
0x04, 0x00, 0x05, 0x00, 0x04, 0x00, 0x06, 0x00, 0x1c, 0x00, 0x07, 0x00,
0x06, 0x00, 0x65, 0x00, 0xb0, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00,
0xc0, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00, 0xd0, 0x00, 0x00, 0x00,
0x14, 0x00, 0x08, 0x00, 0x06, 0x00, 0x65, 0x00, 0x40, 0x00, 0x00, 0x00,
0x06, 0x00, 0x65, 0x00, 0xd0, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x09, 0x00,
0x06, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00,
0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00, 0x40, 0x00, 0x00, 0x00,
0x06, 0x00, 0x65, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00,
0xb0, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0x00, 0xc0, 0x00, 0x00, 0x00,
0x06, 0x00, 0x65, 0x00, 0xd0, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x79, 0x00,
0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x06, 0x00, 0x50, 0x00, 0x78, 0x00,
0x4c, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00, 0x1c, 0x00, 0x01, 0x00,
0x08, 0x00, 0x01, 0x00, 0x00, 0x08, 0x00, 0x00, 0x10, 0x00, 0x02, 0x00,
0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x05, 0x00, 0x04, 0x00, 0x08, 0x00,
0x18, 0x00, 0x02, 0x00, 0x08, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00,
0x0c, 0x00, 0x02, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x09, 0x00,
0x08, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x8f, 0x00, 0x03, 0x00, 0x00, 0x00,
0x1e, 0x00, 0x94, 0x00, 0x42, 0x08, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
const uint32_t kNewWiphyNlMsg_WiphyIndex = 2;
const int kNewWiphyNlMsg_Nl80211AttrWiphyOffset = 4;
const uint16_t kNewWiphyNlMsg_UniqueFrequencies[] = {
2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457,
2462, 2467, 2472, 2484, 5180, 5200, 5220, 5240, 5260, 5280,
5300, 5320, 5500, 5520, 5540, 5560, 5580, 5600, 5620, 5640,
5660, 5680, 5700, 5745, 5765, 5785, 5805, 5825};
const uint32_t kScanTriggerMsgWiphyIndex = 0;
const uint8_t kActiveScanTriggerNlMsg[] = {
0x44, 0x01, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x21, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00,
0x0c, 0x00, 0x99, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x08, 0x00, 0x2d, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0c, 0x01, 0x2c, 0x00,
0x08, 0x00, 0x00, 0x00, 0x6c, 0x09, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00,
0x71, 0x09, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x76, 0x09, 0x00, 0x00,
0x08, 0x00, 0x03, 0x00, 0x7b, 0x09, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00,
0x80, 0x09, 0x00, 0x00, 0x08, 0x00, 0x05, 0x00, 0x85, 0x09, 0x00, 0x00,
0x08, 0x00, 0x06, 0x00, 0x8a, 0x09, 0x00, 0x00, 0x08, 0x00, 0x07, 0x00,
0x8f, 0x09, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x94, 0x09, 0x00, 0x00,
0x08, 0x00, 0x09, 0x00, 0x99, 0x09, 0x00, 0x00, 0x08, 0x00, 0x0a, 0x00,
0x9e, 0x09, 0x00, 0x00, 0x08, 0x00, 0x0b, 0x00, 0x3c, 0x14, 0x00, 0x00,
0x08, 0x00, 0x0c, 0x00, 0x50, 0x14, 0x00, 0x00, 0x08, 0x00, 0x0d, 0x00,
0x64, 0x14, 0x00, 0x00, 0x08, 0x00, 0x0e, 0x00, 0x78, 0x14, 0x00, 0x00,
0x08, 0x00, 0x0f, 0x00, 0x8c, 0x14, 0x00, 0x00, 0x08, 0x00, 0x10, 0x00,
0xa0, 0x14, 0x00, 0x00, 0x08, 0x00, 0x11, 0x00, 0xb4, 0x14, 0x00, 0x00,
0x08, 0x00, 0x12, 0x00, 0xc8, 0x14, 0x00, 0x00, 0x08, 0x00, 0x13, 0x00,
0x7c, 0x15, 0x00, 0x00, 0x08, 0x00, 0x14, 0x00, 0x90, 0x15, 0x00, 0x00,
0x08, 0x00, 0x15, 0x00, 0xa4, 0x15, 0x00, 0x00, 0x08, 0x00, 0x16, 0x00,
0xb8, 0x15, 0x00, 0x00, 0x08, 0x00, 0x17, 0x00, 0xcc, 0x15, 0x00, 0x00,
0x08, 0x00, 0x18, 0x00, 0x1c, 0x16, 0x00, 0x00, 0x08, 0x00, 0x19, 0x00,
0x30, 0x16, 0x00, 0x00, 0x08, 0x00, 0x1a, 0x00, 0x44, 0x16, 0x00, 0x00,
0x08, 0x00, 0x1b, 0x00, 0x58, 0x16, 0x00, 0x00, 0x08, 0x00, 0x1c, 0x00,
0x71, 0x16, 0x00, 0x00, 0x08, 0x00, 0x1d, 0x00, 0x85, 0x16, 0x00, 0x00,
0x08, 0x00, 0x1e, 0x00, 0x99, 0x16, 0x00, 0x00, 0x08, 0x00, 0x1f, 0x00,
0xad, 0x16, 0x00, 0x00, 0x08, 0x00, 0x20, 0x00, 0xc1, 0x16, 0x00, 0x00};
const uint8_t kPassiveScanTriggerNlMsg[] = {
0x40, 0x01, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x21, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00,
0x0c, 0x00, 0x99, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x04, 0x00, 0x2d, 0x00, 0x0c, 0x01, 0x2c, 0x00, 0x08, 0x00, 0x00, 0x00,
0x6c, 0x09, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x71, 0x09, 0x00, 0x00,
0x08, 0x00, 0x02, 0x00, 0x76, 0x09, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00,
0x7b, 0x09, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x80, 0x09, 0x00, 0x00,
0x08, 0x00, 0x05, 0x00, 0x85, 0x09, 0x00, 0x00, 0x08, 0x00, 0x06, 0x00,
0x8a, 0x09, 0x00, 0x00, 0x08, 0x00, 0x07, 0x00, 0x8f, 0x09, 0x00, 0x00,
0x08, 0x00, 0x08, 0x00, 0x94, 0x09, 0x00, 0x00, 0x08, 0x00, 0x09, 0x00,
0x99, 0x09, 0x00, 0x00, 0x08, 0x00, 0x0a, 0x00, 0x9e, 0x09, 0x00, 0x00,
0x08, 0x00, 0x0b, 0x00, 0x3c, 0x14, 0x00, 0x00, 0x08, 0x00, 0x0c, 0x00,
0x50, 0x14, 0x00, 0x00, 0x08, 0x00, 0x0d, 0x00, 0x64, 0x14, 0x00, 0x00,
0x08, 0x00, 0x0e, 0x00, 0x78, 0x14, 0x00, 0x00, 0x08, 0x00, 0x0f, 0x00,
0x8c, 0x14, 0x00, 0x00, 0x08, 0x00, 0x10, 0x00, 0xa0, 0x14, 0x00, 0x00,
0x08, 0x00, 0x11, 0x00, 0xb4, 0x14, 0x00, 0x00, 0x08, 0x00, 0x12, 0x00,
0xc8, 0x14, 0x00, 0x00, 0x08, 0x00, 0x13, 0x00, 0x7c, 0x15, 0x00, 0x00,
0x08, 0x00, 0x14, 0x00, 0x90, 0x15, 0x00, 0x00, 0x08, 0x00, 0x15, 0x00,
0xa4, 0x15, 0x00, 0x00, 0x08, 0x00, 0x16, 0x00, 0xb8, 0x15, 0x00, 0x00,
0x08, 0x00, 0x17, 0x00, 0xcc, 0x15, 0x00, 0x00, 0x08, 0x00, 0x18, 0x00,
0x1c, 0x16, 0x00, 0x00, 0x08, 0x00, 0x19, 0x00, 0x30, 0x16, 0x00, 0x00,
0x08, 0x00, 0x1a, 0x00, 0x44, 0x16, 0x00, 0x00, 0x08, 0x00, 0x1b, 0x00,
0x58, 0x16, 0x00, 0x00, 0x08, 0x00, 0x1c, 0x00, 0x71, 0x16, 0x00, 0x00,
0x08, 0x00, 0x1d, 0x00, 0x85, 0x16, 0x00, 0x00, 0x08, 0x00, 0x1e, 0x00,
0x99, 0x16, 0x00, 0x00, 0x08, 0x00, 0x1f, 0x00, 0xad, 0x16, 0x00, 0x00,
0x08, 0x00, 0x20, 0x00, 0xc1, 0x16, 0x00, 0x00};
} // namespace
class WiFiPropertyTest : public PropertyStoreTest {
public:
WiFiPropertyTest()
: device_(new WiFi(manager(),
"wifi",
"",
kInterfaceIndex,
std::make_unique<MockWakeOnWiFi>())) {}
~WiFiPropertyTest() override = default;
protected:
MockMetrics metrics_;
MockNetlinkManager netlink_manager_;
WiFiRefPtr device_;
};
TEST_F(WiFiPropertyTest, Contains) {
EXPECT_TRUE(device_->store().Contains(kNameProperty));
EXPECT_FALSE(device_->store().Contains(""));
}
TEST_F(WiFiPropertyTest, SetProperty) {
{
Error error;
EXPECT_TRUE(device_->mutable_store()->SetAnyProperty(
kBgscanSignalThresholdProperty, PropertyStoreTest::kInt32V, &error));
}
{
Error error;
EXPECT_TRUE(device_->mutable_store()->SetAnyProperty(
kScanIntervalProperty, PropertyStoreTest::kUint16V, &error));
}
// Ensure that an attempt to write a R/O property returns InvalidArgs error.
{
Error error;
EXPECT_FALSE(device_->mutable_store()->SetAnyProperty(
kScanningProperty, PropertyStoreTest::kBoolV, &error));
ASSERT_TRUE(error.IsFailure());
EXPECT_EQ(Error::kInvalidArguments, error.type());
}
{
Error error;
EXPECT_TRUE(device_->mutable_store()->SetAnyProperty(
kBgscanMethodProperty,
brillo::Any(std::string(WPASupplicant::kNetworkBgscanMethodSimple)),
&error));
}
{
Error error;
EXPECT_FALSE(device_->mutable_store()->SetAnyProperty(
kBgscanMethodProperty,
brillo::Any(std::string("not a real scan method")), &error));
}
}
TEST_F(WiFiPropertyTest, BgscanMethodProperty) {
EXPECT_NE(WPASupplicant::kNetworkBgscanMethodLearn,
WiFi::kDefaultBgscanMethod);
EXPECT_TRUE(device_->bgscan_method_.empty());
std::string method;
Error unused_error;
EXPECT_TRUE(device_->store().GetStringProperty(kBgscanMethodProperty, &method,
&unused_error));
EXPECT_EQ(WiFi::kDefaultBgscanMethod, method);
EXPECT_EQ(WPASupplicant::kNetworkBgscanMethodSimple, method);
Error error;
EXPECT_TRUE(device_->mutable_store()->SetAnyProperty(
kBgscanMethodProperty,
brillo::Any(std::string(WPASupplicant::kNetworkBgscanMethodLearn)),
&error));
EXPECT_EQ(WPASupplicant::kNetworkBgscanMethodLearn, device_->bgscan_method_);
EXPECT_TRUE(device_->store().GetStringProperty(kBgscanMethodProperty, &method,
&unused_error));
EXPECT_EQ(WPASupplicant::kNetworkBgscanMethodLearn, method);
EXPECT_TRUE(
device_->mutable_store()->ClearProperty(kBgscanMethodProperty, &error));
EXPECT_TRUE(device_->store().GetStringProperty(kBgscanMethodProperty, &method,
&unused_error));
EXPECT_EQ(WiFi::kDefaultBgscanMethod, method);
EXPECT_TRUE(device_->bgscan_method_.empty());
}
MATCHER_P(EndpointMatch, endpoint, "") {
return arg->ssid() == endpoint->ssid() &&
arg->network_mode() == endpoint->network_mode() &&
arg->security_mode() == endpoint->security_mode();
}
class WiFiObjectTest : public ::testing::TestWithParam<std::string> {
public:
explicit WiFiObjectTest(std::unique_ptr<EventDispatcher> dispatcher)
: event_dispatcher_(std::move(dispatcher)),
manager_(&control_interface_, event_dispatcher_.get(), &metrics_),
power_manager_(new MockPowerManager(control_interface())),
device_info_(&manager_),
wifi_(new WiFi(&manager_,
kDeviceName,
kDeviceAddress,
kInterfaceIndex,
std::make_unique<MockWakeOnWiFi>())),
bss_counter_(0),
supplicant_process_proxy_(new NiceMock<MockSupplicantProcessProxy>()),
supplicant_bss_proxy_(new NiceMock<MockSupplicantBSSProxy>()),
dhcp_config_(new MockDHCPConfig(&control_interface_, kDeviceName)),
adaptor_(new DeviceMockAdaptor()),
eap_state_handler_(new NiceMock<MockSupplicantEAPStateHandler>()),
supplicant_interface_proxy_(
new NiceMock<MockSupplicantInterfaceProxy>()),
supplicant_network_proxy_(new NiceMock<MockSupplicantNetworkProxy>()) {
manager_.supplicant_manager()->set_proxy(supplicant_process_proxy_);
ON_CALL(*supplicant_process_proxy_, CreateInterface(_, _))
.WillByDefault(DoAll(SetArgPointee<1>(RpcIdentifier("/default/path")),
Return(true)));
ON_CALL(*supplicant_process_proxy_, GetInterface(_, _))
.WillByDefault(DoAll(SetArgPointee<1>(RpcIdentifier("/default/path")),
Return(true)));
ON_CALL(*supplicant_interface_proxy_, AddNetwork(_, _))
.WillByDefault(DoAll(SetArgPointee<1>(RpcIdentifier("/default/path")),
Return(true)));
ON_CALL(*supplicant_interface_proxy_, Disconnect())
.WillByDefault(Return(true));
ON_CALL(*supplicant_interface_proxy_, RemoveNetwork(_))
.WillByDefault(Return(true));
ON_CALL(*supplicant_interface_proxy_, Scan(_)).WillByDefault(Return(true));
ON_CALL(*supplicant_interface_proxy_, EnableMacAddressRandomization(_, _))
.WillByDefault(Return(true));
ON_CALL(*supplicant_interface_proxy_, DisableMacAddressRandomization())
.WillByDefault(Return(true));
ON_CALL(*supplicant_network_proxy_, SetEnabled(_))
.WillByDefault(Return(true));
ON_CALL(dhcp_provider_, CreateIPv4Config(_, _, _, _))
.WillByDefault(Return(dhcp_config_));
ON_CALL(*dhcp_config_, RequestIP()).WillByDefault(Return(true));
ON_CALL(*manager(), IsSuspending()).WillByDefault(Return(false));
ON_CALL(control_interface_, CreateSupplicantInterfaceProxy(_, _))
.WillByDefault(
Invoke(this, &WiFiObjectTest::CreateSupplicantInterfaceProxy));
ON_CALL(control_interface_, CreateSupplicantBSSProxy(_, _))
.WillByDefault(Invoke(this, &WiFiObjectTest::CreateSupplicantBSSProxy));
ON_CALL(control_interface_, CreateSupplicantNetworkProxy(_))
.WillByDefault(
Invoke(this, &WiFiObjectTest::CreateSupplicantNetworkProxy));
Nl80211Message::SetMessageType(kNl80211FamilyId);
// Transfers ownership.
wifi_->eap_state_handler_.reset(eap_state_handler_);
wifi_->provider_ = &wifi_provider_;
wifi_->time_ = &time_;
wifi_->netlink_manager_ = &netlink_manager_;
wifi_->adaptor_.reset(adaptor_); // Transfers ownership.
manager_.set_power_manager(power_manager_); // Transfers ownership.
// The following is only useful when a real |ScanSession| is used; it is
// ignored by |MockScanSession|.
wifi_->all_scan_frequencies_.insert(kRandomScanFrequency1);
wifi_->all_scan_frequencies_.insert(kRandomScanFrequency2);
wifi_->all_scan_frequencies_.insert(kRandomScanFrequency3);
wake_on_wifi_ = static_cast<MockWakeOnWiFi*>(wifi_->wake_on_wifi_.get());
}
void SetUp() override {
// EnableScopes... so that we can EXPECT_CALL for scoped log messages.
ScopeLogger::GetInstance()->EnableScopesByName("wifi");
ScopeLogger::GetInstance()->set_verbose_level(3);
static_cast<Device*>(wifi_.get())->rtnl_handler_ = &rtnl_handler_;
wifi_->set_dhcp_provider(&dhcp_provider_);
ON_CALL(manager_, device_info()).WillByDefault(Return(&device_info_));
EXPECT_CALL(manager_, UpdateEnabledTechnologies()).Times(AnyNumber());
EXPECT_CALL(*supplicant_bss_proxy_, Die()).Times(AnyNumber());
}
void TearDown() override {
EXPECT_CALL(*wifi_provider(), OnEndpointRemoved(_))
.WillRepeatedly(Return(nullptr));
wifi_->SelectService(nullptr);
if (supplicant_bss_proxy_) {
EXPECT_CALL(*supplicant_bss_proxy_, Die());
}
// must Stop WiFi instance, to clear its list of services.
// otherwise, the WiFi instance will not be deleted. (because
// services reference a WiFi instance, creating a cycle.)
wifi_->Stop(nullptr, ResultCallback());
wifi_->set_dhcp_provider(nullptr);
// Reset scope logging, to avoid interfering with other tests.
ScopeLogger::GetInstance()->EnableScopesByName("-wifi");
ScopeLogger::GetInstance()->set_verbose_level(0);
}
// Needs to be public since it is called via Invoke().
void StopWiFi() {
wifi_->SetEnabled(false); // Stop(nullptr, ResultCallback());
}
void ResetPendingService() { SetPendingService(nullptr); }
void SetScanState(WiFi::ScanState new_state,
WiFi::ScanMethod new_method,
const char* reason) {
wifi_->SetScanState(new_state, new_method, reason);
}
void VerifyScanState(WiFi::ScanState state, WiFi::ScanMethod method) const {
EXPECT_EQ(state, wifi_->scan_state_);
EXPECT_EQ(method, wifi_->scan_method_);
}
void PropertiesChanged(const KeyValueStore& props) {
wifi_->PropertiesChanged(props);
}
void SelectService(const WiFiServiceRefPtr& service) {
wifi_->SelectService(service);
}
protected:
using MockWiFiServiceRefPtr = scoped_refptr<MockWiFiService>;
// Simulate the course of events when the last endpoint of a service is
// removed.
class EndpointRemovalHandler {
public:
EndpointRemovalHandler(WiFiRefPtr wifi, const WiFiServiceRefPtr& service)
: wifi_(wifi), service_(service) {}
virtual ~EndpointRemovalHandler() = default;
WiFiServiceRefPtr OnEndpointRemoved(
const WiFiEndpointConstRefPtr& endpoint) {
wifi_->DisassociateFromService(service_);
return service_;
}
private:
WiFiRefPtr wifi_;
WiFiServiceRefPtr service_;
};
std::unique_ptr<EndpointRemovalHandler> MakeEndpointRemovalHandler(
const WiFiServiceRefPtr& service) {
return std::make_unique<EndpointRemovalHandler>(wifi_, service);
}
void CancelScanTimer() { wifi_->scan_timer_callback_.Cancel(); }
// This function creates a new endpoint. We synthesize new |path| and
// |bssid| values, since we don't really care what they are for unit tests.
// If "use_ssid" is true, we used the passed-in ssid, otherwise we create a
// synthesized value for it as well.
WiFiEndpointRefPtr MakeNewEndpoint(bool use_ssid,
std::string* ssid,
RpcIdentifier* path,
std::string* bssid) {
bss_counter_++;
if (!use_ssid) {
*ssid = base::StringPrintf("ssid%d", bss_counter_);
}
*path = RpcIdentifier(base::StringPrintf("/interface/bss%d", bss_counter_));
*bssid = base::StringPrintf("00:00:00:00:00:%02x", bss_counter_);
WiFiEndpointRefPtr endpoint = MakeEndpoint(*ssid, *bssid);
EXPECT_CALL(wifi_provider_, OnEndpointAdded(EndpointMatch(endpoint)))
.Times(1);
return endpoint;
}
WiFiEndpointRefPtr MakeEndpoint(const std::string& ssid,
const std::string& bssid) {
return MakeEndpointWithMode(ssid, bssid, kNetworkModeInfrastructure);
}
WiFiEndpointRefPtr MakeEndpointWithMode(const std::string& ssid,
const std::string& bssid,
const std::string& mode) {
return WiFiEndpoint::MakeOpenEndpoint(&control_interface_, nullptr, ssid,
bssid, mode, 0, 0);
}
MockWiFiServiceRefPtr MakeMockServiceWithSSID(std::vector<uint8_t> ssid,
const std::string& security) {
return new NiceMock<MockWiFiService>(&manager_, &wifi_provider_, ssid,
kModeManaged, security, false);
}
MockWiFiServiceRefPtr MakeMockService(const std::string& security) {
return MakeMockServiceWithSSID(std::vector<uint8_t>(1, 'a'), security);
}
RpcIdentifier MakeNewEndpointAndService(int16_t signal_strength,
uint16_t frequency,
WiFiEndpointRefPtr* endpoint_ptr,
MockWiFiServiceRefPtr* service_ptr) {
std::string ssid;
RpcIdentifier path;
std::string bssid;
WiFiEndpointRefPtr endpoint = MakeNewEndpoint(false, &ssid, &path, &bssid);
MockWiFiServiceRefPtr service =
MakeMockServiceWithSSID(endpoint->ssid(), endpoint->security_mode());
EXPECT_CALL(wifi_provider_, FindServiceForEndpoint(EndpointMatch(endpoint)))
.WillRepeatedly(Return(service));
ON_CALL(*service, GetEndpointCount()).WillByDefault(Return(1));
ReportBSS(path, ssid, bssid, signal_strength, frequency,
kNetworkModeInfrastructure);
if (service_ptr) {
*service_ptr = service;
}
if (endpoint_ptr) {
*endpoint_ptr = endpoint;
}
return path;
}
RpcIdentifier AddEndpointToService(WiFiServiceRefPtr service,
int16_t signal_strength,
uint16_t frequency,
WiFiEndpointRefPtr* endpoint_ptr) {
std::string ssid(service->ssid().begin(), service->ssid().end());
RpcIdentifier path;
std::string bssid;
WiFiEndpointRefPtr endpoint = MakeNewEndpoint(true, &ssid, &path, &bssid);
EXPECT_CALL(wifi_provider_, FindServiceForEndpoint(EndpointMatch(endpoint)))
.WillRepeatedly(Return(service));
ReportBSS(path, ssid, bssid, signal_strength, frequency,
kNetworkModeInfrastructure);
if (endpoint_ptr) {
*endpoint_ptr = endpoint;
}
return path;
}
void InitiateConnect(WiFiServiceRefPtr service) {
Error error;
wifi_->ConnectTo(service.get(), &error);
}
void InitiateDisconnect(WiFiServiceRefPtr service) {
wifi_->DisconnectFrom(service.get());
}
void InitiateDisconnectIfActive(WiFiServiceRefPtr service) {
wifi_->DisconnectFromIfActive(service.get());
}
MockWiFiServiceRefPtr SetupConnectingService(
const RpcIdentifier& network_path,
WiFiEndpointRefPtr* endpoint_ptr,
RpcIdentifier* bss_path_ptr) {
MockWiFiServiceRefPtr service;
WiFiEndpointRefPtr endpoint;
RpcIdentifier bss_path(
MakeNewEndpointAndService(0, 0, &endpoint, &service));
if (!network_path.value().empty()) {
EXPECT_CALL(*service, GetSupplicantConfigurationParameters());
EXPECT_CALL(*GetSupplicantInterfaceProxy(), AddNetwork(_, _))
.WillOnce(DoAll(SetArgPointee<1>(network_path), Return(true)));
EXPECT_CALL(*GetSupplicantInterfaceProxy(), SelectNetwork(network_path));
}
EXPECT_CALL(*service, SetState(Service::kStateAssociating));
InitiateConnect(service);
Mock::VerifyAndClearExpectations(service.get());
EXPECT_FALSE(GetPendingTimeout().IsCancelled());
if (endpoint_ptr) {
*endpoint_ptr = endpoint;
}
if (bss_path_ptr) {
*bss_path_ptr = bss_path;
}
return service;
}
MockWiFiServiceRefPtr SetupConnectedService(const RpcIdentifier& network_path,
WiFiEndpointRefPtr* endpoint_ptr,
RpcIdentifier* bss_path_ptr) {
WiFiEndpointRefPtr endpoint;
RpcIdentifier bss_path;
MockWiFiServiceRefPtr service =
SetupConnectingService(network_path, &endpoint, &bss_path);
if (endpoint_ptr) {
*endpoint_ptr = endpoint;
}
if (bss_path_ptr) {
*bss_path_ptr = bss_path;
}
EXPECT_CALL(*service, NotifyCurrentEndpoint(EndpointMatch(endpoint)));
ReportCurrentBSSChanged(bss_path);
EXPECT_TRUE(GetPendingTimeout().IsCancelled());
Mock::VerifyAndClearExpectations(service.get());
EXPECT_CALL(*service, SetState(Service::kStateConfiguring));
EXPECT_CALL(*service, ResetSuspectedCredentialFailures());
EXPECT_CALL(*dhcp_provider(), CreateIPv4Config(_, _, _, _))
.Times(AnyNumber());
EXPECT_CALL(*dhcp_config_, RequestIP()).Times(AnyNumber());
ReportStateChanged(WPASupplicant::kInterfaceStateCompleted);
Mock::VerifyAndClearExpectations(service.get());
EXPECT_EQ(service, GetCurrentService());
return service;
}
void FireScanTimer() { wifi_->ScanTimerHandler(); }
void TriggerScan() { wifi_->Scan(nullptr, __func__); }
const WiFiServiceRefPtr& GetCurrentService() {
return wifi_->current_service_;
}
void SetCurrentService(const WiFiServiceRefPtr& service) {
wifi_->current_service_ = service;
}
const WiFi::EndpointMap& GetEndpointMap() {
return wifi_->endpoint_by_rpcid_;
}
const WiFiServiceRefPtr& GetPendingService() {
return wifi_->pending_service_;
}
const base::CancelableClosure& GetPendingTimeout() {
return wifi_->pending_timeout_callback_;
}
const base::CancelableClosure& GetReconnectTimeoutCallback() {
return wifi_->reconnect_timeout_callback_;
}
const ServiceRefPtr& GetSelectedService() {
return wifi_->selected_service();
}
const RpcIdentifier& GetSupplicantBSS() { return wifi_->supplicant_bss_; }
void SetSupplicantBSS(const RpcIdentifier& bss) {
wifi_->supplicant_bss_ = bss;
}
int GetReconnectTimeoutSeconds() { return WiFi::kReconnectTimeoutSeconds; }
const base::CancelableClosure& GetScanTimer() {
return wifi_->scan_timer_callback_;
}
// note: the tests need the proxies referenced by WiFi (not the
// proxies instantiated by WiFiObjectTest), to ensure that WiFi
// sets up its proxies correctly.
MockSupplicantInterfaceProxy* GetSupplicantInterfaceProxyFromWiFi() {
return static_cast<MockSupplicantInterfaceProxy*>(
wifi_->supplicant_interface_proxy_.get());
}
// This function returns the supplicant interface proxy whether
// or not we have passed the instantiated object to the WiFi instance
// from WiFiObjectTest, so tests don't need to worry about when they
// set expectations relative to StartWiFi().
MockSupplicantInterfaceProxy* GetSupplicantInterfaceProxy() {
MockSupplicantInterfaceProxy* proxy = GetSupplicantInterfaceProxyFromWiFi();
return proxy ? proxy : supplicant_interface_proxy_.get();
}
const std::string& GetSupplicantState() { return wifi_->supplicant_state_; }
IEEE_80211::WiFiReasonCode GetSupplicantDisconnectReason() {
return wifi_->supplicant_disconnect_reason_;
}
void ClearCachedCredentials(const WiFiService* service) {
return wifi_->ClearCachedCredentials(service);
}
void NotifyEndpointChanged(const WiFiEndpointConstRefPtr& endpoint) {
wifi_->NotifyEndpointChanged(endpoint);
}
bool RemoveNetwork(const RpcIdentifier& network) {
return wifi_->RemoveNetwork(network);
}
KeyValueStore CreateBSSProperties(const std::string& ssid,
const std::string& bssid,
int16_t signal_strength,
uint16_t frequency,
const char* mode);
void RemoveBSS(const RpcIdentifier& bss_path);
void ReportBSS(const RpcIdentifier& bss_path,
const std::string& ssid,
const std::string& bssid,
int16_t signal_strength,
uint16_t frequency,
const char* mode);
void ReportIPConfigComplete() {
wifi_->OnIPConfigUpdated(dhcp_config_, true);
}
void ReportIPConfigCompleteGatewayArpReceived() {
wifi_->OnIPConfigUpdated(dhcp_config_, false);
}
// Calls the delayed version of the BSS methods.
void BSSAdded(const RpcIdentifier& bss_path,
const KeyValueStore& properties) {
wifi_->BSSAdded(bss_path, properties);
}
void BSSRemoved(const RpcIdentifier& bss_path) {
wifi_->BSSRemoved(bss_path);
}
void ReportIPv6ConfigComplete() { wifi_->OnIPv6ConfigUpdated(); }
void ReportIPConfigFailure() { wifi_->OnIPConfigFailure(); }
void ReportConnected() { wifi_->OnConnected(); }
void ReportSelectedServiceChanged(const ServiceRefPtr& old_service) {
wifi_->OnSelectedServiceChanged(old_service);
}
void ReportLinkUp() { wifi_->LinkEvent(IFF_LOWER_UP, IFF_LOWER_UP); }
void ScanDone(const bool& success) { wifi_->ScanDone(success); }
void ReportScanFailed() { wifi_->ScanFailedTask(); }
void ReportScanDone() { wifi_->ScanDoneTask(); }
void ReportCurrentBSSChanged(const RpcIdentifier& new_bss) {
wifi_->CurrentBSSChanged(new_bss);
}
void ReportStateChanged(const std::string& new_state) {
wifi_->StateChanged(new_state);
}
void ReportDisconnectReasonChanged(int32_t reason) {
wifi_->DisconnectReasonChanged(reason);
}
void ReportCurrentAuthModeChanged(const std::string& auth_mode) {
wifi_->CurrentAuthModeChanged(auth_mode);
}
void ReportWiFiDebugScopeChanged(bool enabled) {
wifi_->OnWiFiDebugScopeChanged(enabled);
}
void RequestStationInfo() { wifi_->RequestStationInfo(); }
void ReportReceivedStationInfo(const Nl80211Message& nl80211_message) {
wifi_->OnReceivedStationInfo(nl80211_message);
}
KeyValueStore GetLinkStatistics() {
return wifi_->GetLinkStatistics(nullptr);
}
void SetPendingService(const WiFiServiceRefPtr& service) {
wifi_->SetPendingService(service);
}
void SetServiceNetworkRpcId(const WiFiServiceRefPtr& service,
const RpcIdentifier& rpcid) {
wifi_->rpcid_by_service_[service.get()] = rpcid;
}
bool RpcIdByServiceIsEmpty() { return wifi_->rpcid_by_service_.empty(); }
bool SetScanInterval(uint16_t interval_seconds, Error* error) {
return wifi_->SetScanInterval(interval_seconds, error);
}
uint16_t GetScanInterval() { return wifi_->GetScanInterval(nullptr); }
void StartWiFi(bool supplicant_present) {
EXPECT_CALL(netlink_manager_,
SubscribeToEvents(Nl80211Message::kMessageTypeString,
NetlinkManager::kEventTypeConfig));
EXPECT_CALL(netlink_manager_,
SubscribeToEvents(Nl80211Message::kMessageTypeString,
NetlinkManager::kEventTypeScan));
EXPECT_CALL(netlink_manager_,
SubscribeToEvents(Nl80211Message::kMessageTypeString,
NetlinkManager::kEventTypeRegulatory));
EXPECT_CALL(netlink_manager_,
SubscribeToEvents(Nl80211Message::kMessageTypeString,
NetlinkManager::kEventTypeMlme));
EXPECT_CALL(netlink_manager_,
SendNl80211Message(
IsNl80211Command(kNl80211FamilyId, NL80211_CMD_GET_WIPHY),
_, _, _));
wifi_->supplicant_present_ = supplicant_present;
wifi_->SetEnabled(true); // Start(nullptr, ResultCallback());
if (supplicant_present)
// Mimic the callback from |supplicant_process_proxy_|.
wifi_->OnSupplicantPresence(true);
}
void StartWiFi() { StartWiFi(true); }
void OnAfterResume() {
if (wifi_->enabled_)
EXPECT_CALL(*wake_on_wifi_, OnAfterResume());
wifi_->OnAfterResume();
}
void OnBeforeSuspend() {
ResultCallback callback(
base::Bind(&WiFiObjectTest::SuspendCallback, base::Unretained(this)));
wifi_->OnBeforeSuspend(callback);
}
void OnDarkResume() {
ResultCallback callback(
base::Bind(&WiFiObjectTest::SuspendCallback, base::Unretained(this)));
wifi_->OnDarkResume(callback);
}
void RemoveSupplicantNetworks() { wifi_->RemoveSupplicantNetworks(); }
void InitiateScan() { wifi_->InitiateScan(); }
void InitiateScanInDarkResume(const WiFi::FreqSet& freqs) {
wifi_->InitiateScanInDarkResume(freqs);
}
void TriggerPassiveScan(const WiFi::FreqSet& freqs) {
wifi_->TriggerPassiveScan(freqs);
}
void OnSupplicantAppear() {
wifi_->OnSupplicantPresence(true);
EXPECT_TRUE(wifi_->supplicant_present_);
}
void OnSupplicantVanish() {
wifi_->OnSupplicantPresence(false);
EXPECT_FALSE(wifi_->supplicant_present_);
}
bool GetSupplicantPresent() { return wifi_->supplicant_present_; }
bool GetIsRoamingInProgress() { return wifi_->is_roaming_in_progress_; }
void SetIsRoamingInProgress(bool is_roaming_in_progress) {
wifi_->is_roaming_in_progress_ = is_roaming_in_progress;
}
void SetIPConfig(const IPConfigRefPtr& ipconfig) {
return wifi_->set_ipconfig(ipconfig);
}
bool SetBgscanMethod(const std::string& method) {
Error error;
return wifi_->mutable_store()->SetAnyProperty(kBgscanMethodProperty,
brillo::Any(method), &error);
}
void AppendBgscan(WiFiService* service, KeyValueStore* service_params) {
wifi_->AppendBgscan(service, service_params);
}
void ReportCertification(const KeyValueStore& properties) {
wifi_->CertificationTask(properties);
}
void ReportEAPEvent(const std::string& status, const std::string& parameter) {
wifi_->EAPEventTask(status, parameter);
}
void RestartFastScanAttempts() { wifi_->RestartFastScanAttempts(); }
void SetFastScansRemaining(int num) { wifi_->fast_scans_remaining_ = num; }
void StartReconnectTimer() { wifi_->StartReconnectTimer(); }
void StopReconnectTimer() { wifi_->StopReconnectTimer(); }
bool SuspectCredentials(const WiFiServiceRefPtr& service,
Service::ConnectFailure* failure) {
return wifi_->SuspectCredentials(service, failure);
}
void SetConnection(ConnectionRefPtr connection) {
wifi_->connection_ = connection;
}
void OnNeighborReachabilityEvent(
const IPAddress& ip_address,
patchpanel::NeighborReachabilityEventSignal::Role role,
patchpanel::NeighborReachabilityEventSignal::EventType event_type) {
wifi_->OnNeighborReachabilityEvent(ip_address, role, event_type);
}
MOCK_METHOD(void, ReliableLinkCallback, ());
void SetReliableLinkCallback() {
wifi_->reliable_link_callback_.Reset(base::Bind(
&WiFiObjectTest::ReliableLinkCallback, base::Unretained(this)));
}
bool ReliableLinkCallbackIsCancelled() {
return wifi_->reliable_link_callback_.IsCancelled();
}
// Used by tests for link status (L2 failure, reliability).
void SetupConnectionAndIPConfig(const std::string& ipv4_gateway_address) {
scoped_refptr<MockConnection> connection(new MockConnection(device_info()));
SetConnection(connection);
scoped_refptr<MockIPConfig> ipconfig(
new MockIPConfig(control_interface(), kDeviceName));
SetIPConfig(ipconfig);
// We use ReturnRef() below for this object so use `static` here.
static IPConfig::Properties ip_props;
ip_props.address_family = IPAddress::kFamilyIPv4;
ip_props.gateway = ipv4_gateway_address;
EXPECT_CALL(*ipconfig, properties()).WillRepeatedly(ReturnRef(ip_props));
}
bool SetBgscanShortInterval(const uint16_t& interval, Error* error) {
return wifi_->SetBgscanShortInterval(interval, error);
}
bool SetBgscanSignalThreshold(const int32_t& threshold, Error* error) {
return wifi_->SetBgscanSignalThreshold(threshold, error);
}
void TimeoutPendingConnection() { wifi_->PendingTimeoutHandler(); }
void OnNewWiphy(const Nl80211Message& new_wiphy_message) {
wifi_->OnNewWiphy(new_wiphy_message);
}
bool IsConnectedToCurrentService() {
return wifi_->IsConnectedToCurrentService();
}
MockControl* control_interface() { return &control_interface_; }
MockMetrics* metrics() { return &metrics_; }
MockManager* manager() { return &manager_; }
MockPowerManager* power_manager() { return power_manager_; }
MockDeviceInfo* device_info() { return &device_info_; }
MockDHCPProvider* dhcp_provider() { return &dhcp_provider_; }
const WiFiConstRefPtr wifi() const { return wifi_; }
MockWiFiProvider* wifi_provider() { return &wifi_provider_; }
void ReportConnectedToServiceAfterWake() {
wifi_->ReportConnectedToServiceAfterWake();
}
void StartScanTimer() { wifi_->StartScanTimer(); }
bool GetBroadcastProbeWasSkipped() {
return wifi_->broadcast_probe_was_skipped_;
}
bool ParseWiphyIndex(const Nl80211Message& nl80211_message) {
return wifi_->ParseWiphyIndex(nl80211_message);
}
uint32_t GetWiphyIndex() { return wifi_->wiphy_index_; }
void SetWiphyIndex(uint32_t index) { wifi_->wiphy_index_ = index; }
void ParseFeatureFlags(const Nl80211Message& nl80211_message) {
wifi_->ParseFeatureFlags(nl80211_message);
}
bool GetRandomMacSupported() { return wifi_->random_mac_supported_; }
void SetRandomMacSupported(bool supported) {
wifi_->random_mac_supported_ = supported;
}
bool GetRandomMacEnabled() { return wifi_->random_mac_enabled_; }
void SetRandomMacEnabled(bool enabled) {
Error error;
wifi_->SetRandomMacEnabled(enabled, &error);
}
std::vector<unsigned char> GetRandomMacMask() { return WiFi::kRandomMacMask; }
std::set<uint16_t>* GetAllScanFrequencies() {
return &wifi_->all_scan_frequencies_;
}
void HandleNetlinkBroadcast(const NetlinkMessage& netlink_message) {
wifi_->HandleNetlinkBroadcast(netlink_message);
}
bool ScanFailedCallbackIsCancelled() {
return wifi_->scan_failed_callback_.IsCancelled();
}
void SetWiFiEnabled(bool enabled) { wifi_->enabled_ = enabled; }
void OnGetReg(const Nl80211Message& msg) { wifi_->OnGetReg(msg); }
MOCK_METHOD(void, SuspendCallback, (const Error&));
// Reporting of MaxScanSSID capability can (in theory) behave in three ways:
// - failing D-Bus communication (provide optional arg with 'false')
// - having capabilities w/o MaxScanSSID (provide limit < 0)
// - having capabilities w/ MaxScanSSID (provide limit >= 0)
void SetInterfaceScanLimit(int limit, bool success = true) {
brillo::VariantDictionary caps{};
if (!success) {
EXPECT_CALL(*GetSupplicantInterfaceProxy(), GetCapabilities(_))
.WillOnce(Return(false));
} else {
if (limit >= 0)
caps[WPASupplicant::kInterfaceCapabilityMaxScanSSID] = limit;
EXPECT_CALL(*GetSupplicantInterfaceProxy(), GetCapabilities(_))
.WillOnce(
DoAll(SetArgPointee<0>(
KeyValueStore::ConvertFromVariantDictionary(caps)),
Return(true)));
}
}
std::unique_ptr<EventDispatcher> event_dispatcher_;
MockWakeOnWiFi* wake_on_wifi_; // Owned by |wifi_|.
NiceMock<MockRTNLHandler> rtnl_handler_;
MockTime time_;
MockNetlinkManager netlink_manager_;
private:
MockControl control_interface_;
MockMetrics metrics_;
MockManager manager_;
MockPowerManager* power_manager_; // Owned by |manager_|.
MockDeviceInfo device_info_;
WiFiRefPtr wifi_;
NiceMock<MockWiFiProvider> wifi_provider_;
int bss_counter_;
// protected fields interspersed between private fields, due to
// initialization order
protected:
static const char kDeviceName[];
static const char kDeviceAddress[];
static const char kNetworkModeAdHoc[];
static const char kNetworkModeInfrastructure[];
static const RpcIdentifier kBSSName;
static const char kSSIDName[];
MockSupplicantProcessProxy* supplicant_process_proxy_;
std::unique_ptr<MockSupplicantBSSProxy> supplicant_bss_proxy_;
MockDHCPProvider dhcp_provider_;
scoped_refptr<MockDHCPConfig> dhcp_config_;
// These pointers track mock objects owned by the WiFi device instance
// and manager so we can perform expectations against them.
DeviceMockAdaptor* adaptor_;
MockSupplicantEAPStateHandler* eap_state_handler_;
private:
std::unique_ptr<SupplicantInterfaceProxyInterface>
CreateSupplicantInterfaceProxy(SupplicantEventDelegateInterface* delegate,
const RpcIdentifier& object_path) {
CHECK(supplicant_interface_proxy_);
return std::move(supplicant_interface_proxy_);
}
std::unique_ptr<SupplicantNetworkProxyInterface> CreateSupplicantNetworkProxy(
const RpcIdentifier& object_path) {
return std::move(supplicant_network_proxy_);
}
std::unique_ptr<SupplicantBSSProxyInterface> CreateSupplicantBSSProxy(
WiFiEndpoint* wifi_endpoint, const RpcIdentifier& object_path) {
return std::move(supplicant_bss_proxy_);
}
std::unique_ptr<MockSupplicantInterfaceProxy> supplicant_interface_proxy_;
std::unique_ptr<MockSupplicantNetworkProxy> supplicant_network_proxy_;
};
const char WiFiObjectTest::kDeviceName[] = "wlan0";
const char WiFiObjectTest::kDeviceAddress[] = "000102030405";
const char WiFiObjectTest::kNetworkModeAdHoc[] = "ad-hoc";
const char WiFiObjectTest::kNetworkModeInfrastructure[] = "infrastructure";
const RpcIdentifier WiFiObjectTest::kBSSName("bss0");
const char WiFiObjectTest::kSSIDName[] = "ssid0";
void WiFiObjectTest::RemoveBSS(const RpcIdentifier& bss_path) {
wifi_->BSSRemovedTask(bss_path);
}
KeyValueStore WiFiObjectTest::CreateBSSProperties(const std::string& ssid,
const std::string& bssid,
int16_t signal_strength,
uint16_t frequency,
const char* mode) {
KeyValueStore bss_properties;
bss_properties.Set<std::vector<uint8_t>>(
"SSID", std::vector<uint8_t>(ssid.begin(), ssid.end()));
{
std::string bssid_nosep;
std::vector<uint8_t> bssid_bytes;
base::RemoveChars(bssid, ":", &bssid_nosep);
base::HexStringToBytes(bssid_nosep, &bssid_bytes);
bss_properties.Set<std::vector<uint8_t>>("BSSID", bssid_bytes);
}
bss_properties.Set<int16_t>(WPASupplicant::kBSSPropertySignal,
signal_strength);
bss_properties.Set<uint16_t>(WPASupplicant::kBSSPropertyFrequency, frequency);
bss_properties.Set<std::string>(WPASupplicant::kBSSPropertyMode, mode);
return bss_properties;
}
void WiFiObjectTest::ReportBSS(const RpcIdentifier& bss_path,
const std::string& ssid,
const std::string& bssid,
int16_t signal_strength,
uint16_t frequency,
const char* mode) {
wifi_->BSSAddedTask(
bss_path,
CreateBSSProperties(ssid, bssid, signal_strength, frequency, mode));
}
// Most of our tests involve using a real EventDispatcher object.
class WiFiMainTest : public WiFiObjectTest {
public:
WiFiMainTest() : WiFiObjectTest(std::make_unique<EventDispatcherForTest>()) {}
protected:
void StartScan(WiFi::ScanMethod method) {
VerifyScanState(WiFi::kScanIdle, WiFi::kScanMethodNone);
EXPECT_CALL(*adaptor_, EmitBoolChanged(kPoweredProperty, _))
.Times(AnyNumber());
ExpectScanStart(method, false);
StartWiFi();
event_dispatcher_->DispatchPendingEvents();
VerifyScanState(WiFi::kScanScanning, method);
}
MockWiFiServiceRefPtr AttemptConnection(WiFi::ScanMethod method,
WiFiEndpointRefPtr* endpoint,
RpcIdentifier* bss_path) {
WiFiEndpointRefPtr fake_endpoint;
if (!endpoint) {
endpoint = &fake_endpoint; // If caller doesn't care about endpoint.
}
RpcIdentifier fake_bss_path;
if (!bss_path) {
bss_path = &fake_bss_path; // If caller doesn't care about bss_path.
}
ExpectScanStop();
ExpectConnecting();
MockWiFiServiceRefPtr service =
SetupConnectingService(RpcIdentifier(""), endpoint, bss_path);
ReportScanDone();
event_dispatcher_->DispatchPendingEvents();
VerifyScanState(WiFi::kScanConnecting, method);
return service;
}
void ExpectScanStart(WiFi::ScanMethod method, bool is_continued) {
EXPECT_CALL(*GetSupplicantInterfaceProxy(), Scan(_));
if (!is_continued) {
EXPECT_CALL(*adaptor_, EmitBoolChanged(kScanningProperty, true));
EXPECT_CALL(*metrics(), NotifyDeviceScanStarted(_));
}
}
// Scanning can stop for any reason (including transitioning to connecting).
void ExpectScanStop() {
EXPECT_CALL(*adaptor_, EmitBoolChanged(kScanningProperty, false));
}
void ExpectConnecting() {
EXPECT_CALL(*metrics(), NotifyDeviceScanFinished(_));
EXPECT_CALL(*metrics(), NotifyDeviceConnectStarted(_));
}
void ExpectConnected() {
EXPECT_CALL(*metrics(), NotifyDeviceConnectFinished(_));
ExpectScanIdle();
}
void ExpectFoundNothing() {
EXPECT_CALL(*metrics(), NotifyDeviceScanFinished(_));
EXPECT_CALL(*metrics(), ResetConnectTimer(_));
ExpectScanIdle();
}
void ExpectScanIdle() {
EXPECT_CALL(*metrics(), ResetScanTimer(_));
EXPECT_CALL(*metrics(), ResetConnectTimer(_)).RetiresOnSaturation();
}
};
TEST_F(WiFiMainTest, ProxiesSetUpDuringStart) {
EXPECT_EQ(nullptr, GetSupplicantInterfaceProxyFromWiFi());
StartWiFi();
EXPECT_NE(nullptr, GetSupplicantInterfaceProxyFromWiFi());
}
TEST_F(WiFiMainTest, SupplicantPresent) {
EXPECT_FALSE(GetSupplicantPresent());
}
TEST_F(WiFiMainTest, OnSupplicantAppearStarted) {
EXPECT_EQ(nullptr, GetSupplicantInterfaceProxyFromWiFi());
StartWiFi(false); // No supplicant present.
EXPECT_EQ(nullptr, GetSupplicantInterfaceProxyFromWiFi());
EXPECT_CALL(*GetSupplicantInterfaceProxy(), RemoveAllNetworks());
EXPECT_CALL(*GetSupplicantInterfaceProxy(), FlushBSS(0));
EXPECT_CALL(*GetSupplicantInterfaceProxy(), SetFastReauth(false));
EXPECT_CALL(*GetSupplicantInterfaceProxy(), SetScanInterval(_));
OnSupplicantAppear();
EXPECT_NE(nullptr, GetSupplicantInterfaceProxyFromWiFi());
// If supplicant reappears while the device is started, the device should be
// restarted.
EXPECT_CALL(*manager(), DeregisterDevice(_));
EXPECT_CALL(*manager(), RegisterDevice(_));
OnSupplicantAppear();
}
TEST_F(WiFiMainTest, OnSupplicantAppearStopped) {
EXPECT_EQ(nullptr, GetSupplicantInterfaceProxyFromWiFi());
OnSupplicantAppear();
EXPECT_EQ(nullptr, GetSupplicantInterfaceProxyFromWiFi());
// If supplicant reappears while the device is stopped, the device should not
// be restarted.
EXPECT_CALL(*manager(), DeregisterDevice(_)).Times(0);
OnSupplicantAppear();
}
TEST_F(WiFiMainTest, OnSupplicantVanishStarted) {
EXPECT_EQ(nullptr, GetSupplicantInterfaceProxyFromWiFi());
StartWiFi();
EXPECT_NE(nullptr, GetSupplicantInterfaceProxyFromWiFi());
EXPECT_TRUE(GetSupplicantPresent());
EXPECT_CALL(*manager(), DeregisterDevice(_));
EXPECT_CALL(*manager(), RegisterDevice(_));
OnSupplicantVanish();
}
TEST_F(WiFiMainTest, OnSupplicantVanishStopped) {
OnSupplicantAppear();
EXPECT_TRUE(GetSupplicantPresent());
EXPECT_CALL(*manager(), DeregisterDevice(_)).Times(0);
OnSupplicantVanish();
}
TEST_F(WiFiMainTest, OnSupplicantVanishedWhileConnected) {
StartWiFi();
WiFiEndpointRefPtr endpoint;
WiFiServiceRefPtr service(
SetupConnectedService(RpcIdentifier(""), &endpoint, nullptr));
ScopedMockLog log;
EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
EXPECT_CALL(log, Log(logging::LOGGING_ERROR, _,
EndsWith("silently resetting current_service_.")));
EXPECT_CALL(*manager(), DeregisterDevice(_))
.WillOnce(InvokeWithoutArgs(this, &WiFiObjectTest::StopWiFi));
std::unique_ptr<EndpointRemovalHandler> handler =
MakeEndpointRemovalHandler(service);
EXPECT_CALL(*wifi_provider(), OnEndpointRemoved(EndpointMatch(endpoint)))
.WillOnce(
Invoke(handler.get(), &EndpointRemovalHandler::OnEndpointRemoved));
EXPECT_CALL(*GetSupplicantInterfaceProxy(), Disconnect()).Times(0);
EXPECT_CALL(*manager(), RegisterDevice(_));
OnSupplicantVanish();
EXPECT_EQ(nullptr, GetCurrentService());
}
TEST_F(WiFiMainTest, CleanStart) {
EXPECT_CALL(*supplicant_process_proxy_, CreateInterface(_, _));
EXPECT_CALL(*supplicant_process_proxy_, GetInterface(_, _))
.Times(AnyNumber())
.WillRepeatedly(Return(false));
EXPECT_TRUE(GetScanTimer().IsCancelled());
StartWiFi();
EXPECT_CALL(*GetSupplicantInterfaceProxy(), Scan(_));
event_dispatcher_->DispatchPendingEvents();
EXPECT_FALSE(GetScanTimer().IsCancelled());
}
TEST_F(WiFiMainTest, ClearCachedCredentials) {
StartWiFi();
RpcIdentifier network("/test/path");
WiFiServiceRefPtr service(SetupConnectedService(network, nullptr, nullptr));
EXPECT_CALL(*GetSupplicantInterfaceProxy(), RemoveNetwork(network));
ClearCachedCredentials(service.get());
}
TEST_F(WiFiMainTest, NotifyEndpointChanged) {
WiFiEndpointRefPtr endpoint = MakeEndpoint("ssid", "00:00:00:00:00:00");
EXPECT_CALL(*wifi_provider(), OnEndpointUpdated(EndpointMatch(endpoint)));
NotifyEndpointChanged(endpoint);
}
TEST_F(WiFiMainTest, RemoveNetwork) {
RpcIdentifier network("/test/path");
StartWiFi();
EXPECT_CALL(*GetSupplicantInterfaceProxy(), RemoveNetwork(network))
.WillOnce(Return(true));
EXPECT_TRUE(RemoveNetwork(network));
}
TEST_F(WiFiMainTest, UseArpGateway) {
StartWiFi();
// With no selected service.
EXPECT_TRUE(wifi()->ShouldUseArpGateway());
EXPECT_CALL(dhcp_provider_, CreateIPv4Config(kDeviceName, _, true, _))
.WillOnce(Return(dhcp_config_));
const_cast<WiFi*>(wifi().get())->AcquireIPConfig();
MockWiFiServiceRefPtr service = MakeMockService(kSecurityNone);
InitiateConnect(service);
// Selected service that does not have a static IP address.
EXPECT_CALL(*service, HasStaticIPAddress()).WillRepeatedly(Return(false));
EXPECT_TRUE(wifi()->ShouldUseArpGateway());
EXPECT_CALL(dhcp_provider_, CreateIPv4Config(kDeviceName, _, true, _))
.WillOnce(Return(dhcp_config_));
const_cast<WiFi*>(wifi().get())->AcquireIPConfig();
Mock::VerifyAndClearExpectations(service.get());
// Selected service that has a static IP address.
EXPECT_CALL(*service, HasStaticIPAddress()).WillRepeatedly(Return(true));
EXPECT_FALSE(wifi()->ShouldUseArpGateway());
EXPECT_CALL(dhcp_provider_, CreateIPv4Config(kDeviceName, _, false, _))
.WillOnce(Return(dhcp_config_));
const_cast<WiFi*>(wifi().get())->AcquireIPConfig();
}
TEST_F(WiFiMainTest, RemoveNetworkFailed) {
RpcIdentifier network("/test/path");
EXPECT_CALL(*GetSupplicantInterfaceProxy(), RemoveNetwork(network))
.WillRepeatedly(Return(false));
StartWiFi();
EXPECT_FALSE(RemoveNetwork(network));
}
TEST_F(WiFiMainTest, Restart) {
EXPECT_CALL(*supplicant_process_proxy_, CreateInterface(_, _))
.Times(AnyNumber())
.WillRepeatedly(Return(false));
EXPECT_CALL(*supplicant_process_proxy_, GetInterface(_, _));
EXPECT_CALL(*GetSupplicantInterfaceProxy(), Scan(_));
EXPECT_CALL(*metrics(), NotifyWiFiSupplicantSuccess(1));
StartWiFi();
event_dispatcher_->DispatchPendingEvents();
}
TEST_F(WiFiMainTest, StartClearsState) {
EXPECT_CALL(*GetSupplicantInterfaceProxy(), RemoveAllNetworks());
EXPECT_CALL(*GetSupplicantInterfaceProxy(), FlushBSS(_));
StartWiFi();
}
TEST_F(WiFiMainTest, NoScansWhileConnecting) {
// Setup 'connecting' state.
StartScan(WiFi::kScanMethodFull);
Mock::VerifyAndClearExpectations(GetSupplicantInterfaceProxy());
ExpectScanStop();
ExpectConnecting();
MockWiFiServiceRefPtr service = MakeMockService(kSecurityNone);
InitiateConnect(service);
VerifyScanState(WiFi::kScanConnecting, WiFi::kScanMethodFull);
// If we're connecting, we ignore scan requests and stay on channel.
EXPECT_CALL(*GetSupplicantInterfaceProxy(), Scan(_)).Times(0);
TriggerScan();
event_dispatcher_->DispatchPendingEvents();
Mock::VerifyAndClearExpectations(GetSupplicantInterfaceProxy());
Mock::VerifyAndClearExpectations(service.get());
// Terminate the scan.
ExpectFoundNothing();
TimeoutPendingConnection();
VerifyScanState(WiFi::kScanIdle, WiFi::kScanMethodNone);
// Start a fresh scan.
ExpectScanStart(WiFi::kScanMethodFull, false);
TriggerScan();
event_dispatcher_->DispatchPendingEvents();
Mock::VerifyAndClearExpectations(GetSupplicantInterfaceProxy());
Mock::VerifyAndClearExpectations(service.get());
// Similarly, ignore scans when our connected service is reconnecting.
ExpectScanStop();
ExpectScanIdle();
SetPendingService(nullptr);
SetCurrentService(service);
EXPECT_CALL(*service, IsConnecting()).WillOnce(Return(true));
EXPECT_CALL(*GetSupplicantInterfaceProxy(), Scan(_)).Times(0);
TriggerScan();
event_dispatcher_->DispatchPendingEvents();
Mock::VerifyAndClearExpectations(GetSupplicantInterfaceProxy());
Mock::VerifyAndClearExpectations(service.get());
// But otherwise we'll honor the request.
EXPECT_CALL(*service, IsConnecting())
.Times(AtLeast(2))
.WillRepeatedly(Return(false));
ExpectScanStart(WiFi::kScanMethodFull, false);
TriggerScan();
event_dispatcher_->DispatchPendingEvents();
Mock::VerifyAndClearExpectations(GetSupplicantInterfaceProxy());
Mock::VerifyAndClearExpectations(service.get());
// Silence messages from the destructor.
ExpectScanStop();
ExpectScanIdle();
}
TEST_F(WiFiMainTest, ResetScanStateWhenScanFailed) {
StartScan(WiFi::kScanMethodFull);
ExpectScanStop();
VerifyScanState(WiFi::kScanScanning, WiFi::kScanMethodFull);
ReportScanFailed();
VerifyScanState(WiFi::kScanIdle, WiFi::kScanMethodNone);
}
TEST_F(WiFiMainTest, ResumeStartsScanWhenIdle) {
EXPECT_CALL(*GetSupplicantInterfaceProxy(), Scan(_));
StartWiFi();
event_dispatcher_->DispatchPendingEvents();
Mock::VerifyAndClearExpectations(GetSupplicantInterfaceProxy());
ReportScanDone();
ASSERT_TRUE(wifi()->IsIdle());
EXPECT_CALL(*GetSupplicantInterfaceProxy(), Scan(_));
OnAfterResume();
event_dispatcher_->DispatchPendingEvents();
}
TEST_F(WiFiMainTest, ResumeDoesNotScanIfConnected) {
StartWiFi();
event_dispatcher_->DispatchPendingEvents();
Mock::VerifyAndClearExpectations(GetSupplicantInterfaceProxy());
ReportScanDone();
CancelScanTimer();
EXPECT_TRUE(GetScanTimer().IsCancelled());
ASSERT_TRUE(wifi()->IsIdle());
event_dispatcher_->DispatchPendingEvents();
SetupConnectedService(RpcIdentifier(""), nullptr, nullptr);
OnAfterResume();
EXPECT_FALSE(GetScanTimer().IsCancelled());
EXPECT_CALL(*GetSupplicantInterfaceProxy(), Scan(_)).Times(0);
event_dispatcher_->DispatchPendingEvents();
}
TEST_F(WiFiMainTest, SuspendDoesNotStartScan) {
EXPECT_CALL(*GetSupplicantInterfaceProxy(), Scan(_));
StartWiFi();
event_dispatcher_->DispatchPendingEvents();
Mock::VerifyAndClearExpectations(GetSupplicantInterfaceProxy());
ASSERT_TRUE(wifi()->IsIdle());
EXPECT_CALL(*GetSupplicantInterfaceProxy(), Scan(_)).Times(0);
OnBeforeSuspend();
event_dispatcher_->DispatchPendingEvents();
}
TEST_F(WiFiMainTest, ResumeDoesNotStartScanWhenNotIdle) {
EXPECT_CALL(*GetSupplicantInterfaceProxy(), Scan(_));
StartWiFi();
event_dispatcher_->DispatchPendingEvents();
Mock::VerifyAndClearExpectations(GetSupplicantInterfaceProxy());
WiFiServiceRefPtr service(
SetupConnectedService(RpcIdentifier(""), nullptr, nullptr));
EXPECT_FALSE(wifi()->IsIdle());
ScopedMockLog log;
EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
EXPECT_CALL(log, Log(_, _, EndsWith("already connecting or connected.")));
EXPECT_CALL(*GetSupplicantInterfaceProxy(), Scan(_)).Times(0);
OnAfterResume();
event_dispatcher_->DispatchPendingEvents();
}
TEST_F(WiFiMainTest, ResumeDoesNotStartScanWhenDisabled) {
EXPECT_CALL(*GetSupplicantInterfaceProxy(), Scan(_));
StartWiFi();
event_dispatcher_->DispatchPendingEvents();
Mock::VerifyAndClearExpectations(GetSupplicantInterfaceProxy());
EXPECT_CALL(*GetSupplicantInterfaceProxy(), Scan(_)).Times(0);
SetWiFiEnabled(false);
OnBeforeSuspend();
OnAfterResume();
event_dispatcher_->DispatchPendingEvents();
}
TEST_F(WiFiMainTest, ResumeWithCurrentService) {
StartWiFi();
SetupConnectedService(RpcIdentifier(""), nullptr, nullptr);
OnAfterResume();
Mock::VerifyAndClearExpectations(GetSupplicantInterfaceProxy());
}
TEST_F(WiFiMainTest, ScanResults) {
EXPECT_CALL(*wifi_provider(), OnEndpointAdded(_)).Times(3);
StartWiFi();
// Ad-hoc networks will be dropped.
ReportBSS(RpcIdentifier("bss0"), "ssid0", "00:00:00:00:00:00", 0, 0,
kNetworkModeAdHoc);
ReportBSS(RpcIdentifier("bss1"), "ssid1", "00:00:00:00:00:01", 1, 0,
kNetworkModeInfrastructure);
ReportBSS(RpcIdentifier("bss2"), "ssid2", "00:00:00:00:00:02", 2, 0,
kNetworkModeInfrastructure);
ReportBSS(RpcIdentifier("bss3"), "ssid3", "00:00:00:00:00:03", 3, 0,
kNetworkModeInfrastructure);
const uint16_t frequency = 2412;
ReportBSS(RpcIdentifier("bss4"), "ssid4", "00:00:00:00:00:04", 4, frequency,
kNetworkModeAdHoc);
const WiFi::EndpointMap& endpoints_by_rpcid = GetEndpointMap();
EXPECT_EQ(3, endpoints_by_rpcid.size());
for (const auto& endpoint : endpoints_by_rpcid) {
EXPECT_NE(kNetworkModeAdHoc, endpoint.second->network_mode());
EXPECT_NE(endpoint.second->bssid_string(), "00:00:00:00:00:00");
EXPECT_NE(endpoint.second->bssid_string(), "00:00:00:00:00:04");
}
}
TEST_F(WiFiMainTest, ScanCompleted) {
StartWiFi();
WiFiEndpointRefPtr ap0 = MakeEndpoint("ssid0", "00:00:00:00:00:00");
WiFiEndpointRefPtr ap1 = MakeEndpoint("ssid1", "00:00:00:00:00:01");
EXPECT_CALL(*wifi_provider(), OnEndpointAdded(EndpointMatch(ap0))).Times(1);
EXPECT_CALL(*wifi_provider(), OnEndpointAdded(EndpointMatch(ap1))).Times(1);
ReportBSS(RpcIdentifier("bss0"), ap0->ssid_string(), ap0->bssid_string(), 0,
0, kNetworkModeInfrastructure);
ReportBSS(RpcIdentifier("bss1"), ap1->ssid_string(), ap1->bssid_string(), 0,
0, kNetworkModeInfrastructure);
manager()->set_suppress_autoconnect(true);
ReportScanDone();
EXPECT_FALSE(manager()->suppress_autoconnect());
Mock::VerifyAndClearExpectations(wifi_provider());
EXPECT_CALL(*wifi_provider(), OnEndpointAdded(_)).Times(0);
// BSSes with SSIDs that start with nullptr should be filtered.
ReportBSS(RpcIdentifier("bss2"), std::string(1, 0), "00:00:00:00:00:02", 3, 0,
kNetworkModeInfrastructure);
// BSSes with empty SSIDs should be filtered.
ReportBSS(RpcIdentifier("bss2"), std::string(), "00:00:00:00:00:02", 3, 0,
kNetworkModeInfrastructure);
}
TEST_F(WiFiMainTest, LoneBSSRemovedWhileConnected) {
StartWiFi();
WiFiEndpointRefPtr endpoint;
RpcIdentifier bss_path;
WiFiServiceRefPtr service(
SetupConnectedService(RpcIdentifier(""), &endpoint, &bss_path));
std::unique_ptr<EndpointRemovalHandler> handler =
MakeEndpointRemovalHandler(service);
EXPECT_CALL(*wifi_provider(), OnEndpointRemoved(EndpointMatch(endpoint)))
.WillOnce(
Invoke(handler.get(), &EndpointRemovalHandler::OnEndpointRemoved));
EXPECT_CALL(*GetSupplicantInterfaceProxy(), Disconnect());
RemoveBSS(bss_path);
}
TEST_F(WiFiMainTest, GetCurrentEndpoint) {
StartWiFi();
WiFiEndpointRefPtr endpoint;
RpcIdentifier bss_path;
MockWiFiServiceRefPtr service(
SetupConnectedService(RpcIdentifier(""), &endpoint, &bss_path));
const WiFiEndpointConstRefPtr current_endpoint = wifi()->GetCurrentEndpoint();
EXPECT_NE(nullptr, current_endpoint);
EXPECT_EQ(current_endpoint->bssid_string(), endpoint->bssid_string());
}
TEST_F(WiFiMainTest, NonSolitaryBSSRemoved) {
StartWiFi();
WiFiEndpointRefPtr endpoint;
RpcIdentifier bss_path;
WiFiServiceRefPtr service(
SetupConnectedService(RpcIdentifier(""), &endpoint, &bss_path));
EXPECT_CALL(*wifi_provider(), OnEndpointRemoved(EndpointMatch(endpoint)))
.WillOnce(Return(nullptr));
EXPECT_CALL(*GetSupplicantInterfaceProxy(), Disconnect()).Times(0);
RemoveBSS(bss_path);
}
TEST_F(WiFiMainTest, ReconnectPreservesDBusPath) {
StartWiFi();
RpcIdentifier kPath("/test/path");
MockWiFiServiceRefPtr service(SetupConnectedService(kPath, nullptr, nullptr));
// Return the service to a connectable state.
EXPECT_CALL(*GetSupplicantInterfaceProxy(), Disconnect());
InitiateDisconnect(service);
Mock::VerifyAndClearExpectations(GetSupplicantInterfaceProxy());
// Complete the disconnection by reporting a BSS change.
ReportCurrentBSSChanged(RpcIdentifier(WPASupplicant::kCurrentBSSNull));
// A second connection attempt should remember the DBus path associated
// with this service, and should not request new configuration parameters.
EXPECT_CALL(*service, GetSupplicantConfigurationParameters()).Times(0);
EXPECT_CALL(*GetSupplicantInterfaceProxy(), AddNetwork(_, _)).Times(0);
EXPECT_CALL(*GetSupplicantInterfaceProxy(), SelectNetwork(kPath));
InitiateConnect(service);
}
TEST_F(WiFiMainTest, DisconnectPendingService) {
StartWiFi();
MockWiFiServiceRefPtr service(
SetupConnectingService(RpcIdentifier(""), nullptr, nullptr));
EXPECT_EQ(GetPendingService(), service);
EXPECT_CALL(*GetSupplicantInterfaceProxy(), Disconnect());
EXPECT_CALL(*service, SetFailure(_)).Times(0);
EXPECT_CALL(*service, SetState(Service::kStateIdle)).Times(AtLeast(1));
service->set_expecting_disconnect(true);
InitiateDisconnect(service);
Mock::VerifyAndClearExpectations(service.get());
EXPECT_EQ(nullptr, GetPendingService());
}
TEST_F(WiFiMainTest, DisconnectPendingServiceWithFailure) {
StartWiFi();
MockWiFiServiceRefPtr service(
SetupConnectingService(RpcIdentifier(""), nullptr, nullptr));
EXPECT_EQ(GetPendingService(), service);
EXPECT_CALL(*GetSupplicantInterfaceProxy(), Disconnect());
EXPECT_CALL(*service, ShouldIgnoreFailure()).WillOnce(Return(false));
EXPECT_CALL(*service, SetFailure(Service::kFailureUnknown));
EXPECT_CALL(*service, SetState(Service::kStateIdle)).Times(AtLeast(1));
InitiateDisconnect(service);
Mock::VerifyAndClearExpectations(service.get());
EXPECT_EQ(nullptr, GetPendingService());
}
TEST_F(WiFiMainTest, DisconnectPendingServiceWithOutOfRange) {
StartWiFi();
// Initiate connection with weak signal
MockWiFiServiceRefPtr service;
MakeNewEndpointAndService(-90, 0, nullptr, &service);
InitiateConnect(service);
EXPECT_EQ(GetPendingService(), service);
EXPECT_CALL(*GetSupplicantInterfaceProxy(), Disconnect());
EXPECT_CALL(*service, ShouldIgnoreFailure()).WillOnce(Return(false));
EXPECT_CALL(*service, SetFailure(Service::kFailureOutOfRange));
EXPECT_CALL(*service, SetState(Service::kStateIdle)).Times(AtLeast(1));
EXPECT_CALL(*service, SignalLevel()).WillRepeatedly(Return(-90));
ReportDisconnectReasonChanged(-IEEE_80211::kReasonCodeInactivity);
InitiateDisconnect(service);
Mock::VerifyAndClearExpectations(service.get());
EXPECT_EQ(nullptr, GetPendingService());
}
TEST_F(WiFiMainTest, DisconnectPendingServiceWithCurrent) {
StartWiFi();
MockWiFiServiceRefPtr service0(
SetupConnectedService(RpcIdentifier(""), nullptr, nullptr));
EXPECT_EQ(service0, GetCurrentService());
EXPECT_EQ(nullptr, GetPendingService());
// We don't explicitly call Disconnect() while transitioning to a new
// service. Instead, we use the side-effect of SelectNetwork (verified in
// SetupConnectingService).
EXPECT_CALL(*GetSupplicantInterfaceProxy(), Disconnect()).Times(0);
MockWiFiServiceRefPtr service1(
SetupConnectingService(RpcIdentifier("/new/path"), nullptr, nullptr));
Mock::VerifyAndClearExpectations(GetSupplicantInterfaceProxy());
EXPECT_EQ(service0, GetCurrentService());
EXPECT_EQ(service1, GetPendingService());
EXPECT_CALL(*service1, SetState(Service::kStateIdle)).Times(AtLeast(1));
EXPECT_CALL(*GetSupplicantInterfaceProxy(), Disconnect());
InitiateDisconnect(service1);
Mock::VerifyAndClearExpectations(service1.get());
// |current_service_| will be unchanged until supplicant signals
// that CurrentBSS has changed.
EXPECT_EQ(service0, GetCurrentService());
// |pending_service_| is updated immediately.
EXPECT_EQ(nullptr, GetPendingService());
EXPECT_TRUE(GetPendingTimeout().IsCancelled());
}
TEST_F(WiFiMainTest, DisconnectCurrentService) {
StartWiFi();
RpcIdentifier kPath("/fake/path");
MockWiFiServiceRefPtr service(SetupConnectedService(kPath, nullptr, nullptr));
EXPECT_CALL(*GetSupplicantInterfaceProxy(), Disconnect());
service->set_expecting_disconnect(true);
InitiateDisconnect(service);
// |current_service_| should not change until supplicant reports
// a BSS change.
EXPECT_EQ(service, GetCurrentService());
// Expect that the entry associated with this network will be disabled.
auto