| // 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 |