| // Copyright 2022 The ChromiumOS Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "shill/wifi/wifi_phy.h" |
| |
| #include <algorithm> |
| #include <iterator> |
| #include <vector> |
| |
| #include <base/test/mock_callback.h> |
| #include <gmock/gmock.h> |
| #include <gtest/gtest.h> |
| #include <net-base/attribute_list.h> |
| #include <net-base/mac_address.h> |
| #include <net-base/netlink_attribute.h> |
| #include <net-base/netlink_packet.h> |
| |
| #include "shill/mock_control.h" |
| #include "shill/mock_manager.h" |
| #include "shill/mock_metrics.h" |
| #include "shill/supplicant/wpa_supplicant.h" |
| #include "shill/test_event_dispatcher.h" |
| #include "shill/wifi/mock_hotspot_device.h" |
| #include "shill/wifi/mock_p2p_device.h" |
| #include "shill/wifi/mock_wake_on_wifi.h" |
| #include "shill/wifi/mock_wifi.h" |
| |
| using testing::_; |
| using ::testing::NiceMock; |
| using ::testing::Return; |
| using ::testing::StrictMock; |
| using ::testing::Test; |
| |
| namespace shill { |
| |
| namespace { |
| // NL80211_CMD_NEW_WIPHY message which indicates support for the following |
| // interface types: IBSS, managed, AP, monitor, P2P-client, P2P-GO, P2P-device. |
| const uint8_t kNewWiphyNlMsg_IfTypes[] = { |
| 0x6C, 0x00, 0x00, 0x00, 0x13, 0x00, 0x01, 0x00, 0x0D, 0x00, 0x00, 0x00, |
| 0x0D, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x02, 0x00, 0x70, 0x68, 0x79, 0x37, |
| 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x20, 0x00, 0x08, 0x00, 0x01, 0x00, |
| 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, |
| 0x08, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x06, 0x00, |
| 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, |
| 0x08, 0x00, 0x09, 0x00, 0x09, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0A, 0x00, |
| 0x0A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x2E, 0x00, 0x0F, 0x00, 0x00, 0x00}; |
| |
| // Bytes representing a NL80211_CMD_NEW_WIPHY message reporting the WiFi |
| // capabilities of a NIC with wiphy index |kWiFiPhyIndex| which supports |
| // operating bands with the frequencies specified in |
| // |kNewWiphyNlMsg_AllFrequencies|. |
| // Note that this message is marked as part of multi-message PHY dump so you |
| // need to signal to WiFiPhy the end of it via PhyDumpComplete() call. |
| const uint8_t kNewWiphyNlMsg[] = { |
| 0x38, 0x0C, 0x00, 0x00, 0x14, 0x00, 0x03, 0x00, 0x0D, 0x00, 0x00, 0x00, |
| 0x1D, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x02, 0x00, 0x70, 0x68, 0x79, 0x30, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x16, 0x00, 0xF8, 0x01, 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, |
| 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, 0x04, 0x03, 0x01, 0x00, |
| 0x70, 0x02, 0x01, 0x00, 0x14, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, |
| 0x3C, 0x14, 0x00, 0x00, 0x08, 0x00, 0x06, 0x00, 0xD0, 0x07, 0x00, 0x00, |
| 0x18, 0x00, 0x01, 0x00, 0x08, 0x00, 0x01, 0x00, 0x50, 0x14, 0x00, 0x00, |
| 0x04, 0x00, 0x03, 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, 0x1C, 0x00, 0x04, 0x00, 0x08, 0x00, 0x01, 0x00, |
| 0x8C, 0x14, 0x00, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, |
| 0x08, 0x00, 0x06, 0x00, 0xD0, 0x07, 0x00, 0x00, 0x1C, 0x00, 0x05, 0x00, |
| 0x08, 0x00, 0x01, 0x00, 0xA0, 0x14, 0x00, 0x00, 0x04, 0x00, 0x03, 0x00, |
| 0x04, 0x00, 0x05, 0x00, 0x08, 0x00, 0x06, 0x00, 0xD0, 0x07, 0x00, 0x00, |
| 0x1C, 0x00, 0x06, 0x00, 0x08, 0x00, 0x01, 0x00, 0xB4, 0x14, 0x00, 0x00, |
| 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 0x08, 0x00, 0x06, 0x00, |
| 0xD0, 0x07, 0x00, 0x00, 0x1C, 0x00, 0x07, 0x00, 0x08, 0x00, 0x01, 0x00, |
| 0xC8, 0x14, 0x00, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, |
| 0x08, 0x00, 0x06, 0x00, 0xD0, 0x07, 0x00, 0x00, 0x1C, 0x00, 0x08, 0x00, |
| 0x08, 0x00, 0x01, 0x00, 0x7C, 0x15, 0x00, 0x00, 0x04, 0x00, 0x03, 0x00, |
| 0x04, 0x00, 0x05, 0x00, 0x08, 0x00, 0x06, 0x00, 0xD0, 0x07, 0x00, 0x00, |
| 0x1C, 0x00, 0x09, 0x00, 0x08, 0x00, 0x01, 0x00, 0x90, 0x15, 0x00, 0x00, |
| 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 0x08, 0x00, 0x06, 0x00, |
| 0xD0, 0x07, 0x00, 0x00, 0x1C, 0x00, 0x0A, 0x00, 0x08, 0x00, 0x01, 0x00, |
| 0xA4, 0x15, 0x00, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, |
| 0x08, 0x00, 0x06, 0x00, 0xD0, 0x07, 0x00, 0x00, 0x1C, 0x00, 0x0B, 0x00, |
| 0x08, 0x00, 0x01, 0x00, 0xB8, 0x15, 0x00, 0x00, 0x04, 0x00, 0x03, 0x00, |
| 0x04, 0x00, 0x05, 0x00, 0x08, 0x00, 0x06, 0x00, 0xD0, 0x07, 0x00, 0x00, |
| 0x1C, 0x00, 0x0C, 0x00, 0x08, 0x00, 0x01, 0x00, 0xCC, 0x15, 0x00, 0x00, |
| 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 0x08, 0x00, 0x06, 0x00, |
| 0xD0, 0x07, 0x00, 0x00, 0x1C, 0x00, 0x0D, 0x00, 0x08, 0x00, 0x01, 0x00, |
| 0xE0, 0x15, 0x00, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, |
| 0x08, 0x00, 0x06, 0x00, 0xD0, 0x07, 0x00, 0x00, 0x1C, 0x00, 0x0E, 0x00, |
| 0x08, 0x00, 0x01, 0x00, 0xF4, 0x15, 0x00, 0x00, 0x04, 0x00, 0x03, 0x00, |
| 0x04, 0x00, 0x05, 0x00, 0x08, 0x00, 0x06, 0x00, 0xD0, 0x07, 0x00, 0x00, |
| 0x1C, 0x00, 0x0F, 0x00, 0x08, 0x00, 0x01, 0x00, 0x08, 0x16, 0x00, 0x00, |
| 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 0x08, 0x00, 0x06, 0x00, |
| 0xD0, 0x07, 0x00, 0x00, 0x1C, 0x00, 0x10, 0x00, 0x08, 0x00, 0x01, 0x00, |
| 0x1C, 0x16, 0x00, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, |
| 0x08, 0x00, 0x06, 0x00, 0xD0, 0x07, 0x00, 0x00, 0x1C, 0x00, 0x11, 0x00, |
| 0x08, 0x00, 0x01, 0x00, 0x30, 0x16, 0x00, 0x00, 0x04, 0x00, 0x03, 0x00, |
| 0x04, 0x00, 0x05, 0x00, 0x08, 0x00, 0x06, 0x00, 0xD0, 0x07, 0x00, 0x00, |
| 0x1C, 0x00, 0x12, 0x00, 0x08, 0x00, 0x01, 0x00, 0x44, 0x16, 0x00, 0x00, |
| 0x04, 0x00, 0x03, 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, |
| 0x18, 0x00, 0x14, 0x00, 0x08, 0x00, 0x01, 0x00, 0x85, 0x16, 0x00, 0x00, |
| 0x04, 0x00, 0x03, 0x00, 0x08, 0x00, 0x06, 0x00, 0xD0, 0x07, 0x00, 0x00, |
| 0x18, 0x00, 0x15, 0x00, 0x08, 0x00, 0x01, 0x00, 0x99, 0x16, 0x00, 0x00, |
| 0x04, 0x00, 0x03, 0x00, 0x08, 0x00, 0x06, 0x00, 0xD0, 0x07, 0x00, 0x00, |
| 0x18, 0x00, 0x16, 0x00, 0x08, 0x00, 0x01, 0x00, 0xAD, 0x16, 0x00, 0x00, |
| 0x04, 0x00, 0x03, 0x00, 0x08, 0x00, 0x06, 0x00, 0xD0, 0x07, 0x00, 0x00, |
| 0x18, 0x00, 0x17, 0x00, 0x08, 0x00, 0x01, 0x00, 0xC1, 0x16, 0x00, 0x00, |
| 0x04, 0x00, 0x03, 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, 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, |
| 0x44, 0x00, 0x20, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, |
| 0x08, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00, |
| 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, |
| 0x08, 0x00, 0x05, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x06, 0x00, |
| 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, |
| 0x08, 0x00, 0x09, 0x00, 0x09, 0x00, 0x00, 0x00, 0x05, 0x00, 0x2B, 0x00, |
| 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x2E, 0x00, 0x01, 0x00, 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, 0x06, 0x00, 0x38, 0x00, |
| 0xD1, 0x08, 0x00, 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, 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, 0x56, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x59, 0x00, |
| 0x00, 0x00, 0x00, 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, 0x04, 0x00, 0x66, 0x00, |
| 0x04, 0x00, 0x68, 0x00, 0x08, 0x00, 0x69, 0x00, 0x03, 0x00, 0x00, 0x00, |
| 0x08, 0x00, 0x6A, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x6C, 0x00, |
| 0x08, 0x00, 0x6F, 0x00, 0x88, 0x13, 0x00, 0x00, 0x08, 0x00, 0x71, 0x00, |
| 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x72, 0x00, 0x03, 0x00, 0x00, 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, 0x02, 0x00, 0x00, 0x08, 0x00, 0x00, |
| 0x08, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x79, 0x00, |
| 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x06, 0x00, 0x05, 0x00, 0x7B, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x05, 0x00, 0x85, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x8B, 0x00, |
| 0x04, 0x00, 0x8C, 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}; |
| |
| // In the above kNewWiphyNlMsg packet the following frequencies are present: |
| const WiFiPhy::Frequencies kNewWiphyNlMsg_AllFrequencies = { |
| {0, |
| { |
| {.value = 2412, |
| .attributes = {{NL80211_FREQUENCY_ATTR_MAX_TX_POWER, 1900}}}, |
| {.value = 2417, |
| .attributes = {{NL80211_FREQUENCY_ATTR_MAX_TX_POWER, 1900}}}, |
| {.value = 2422, |
| .attributes = {{NL80211_FREQUENCY_ATTR_MAX_TX_POWER, 1900}}}, |
| {.value = 2427, |
| .attributes = {{NL80211_FREQUENCY_ATTR_MAX_TX_POWER, 1900}}}, |
| {.value = 2432, |
| .attributes = {{NL80211_FREQUENCY_ATTR_MAX_TX_POWER, 1900}}}, |
| {.value = 2437, |
| .attributes = {{NL80211_FREQUENCY_ATTR_MAX_TX_POWER, 1900}}}, |
| {.value = 2442, |
| .attributes = {{NL80211_FREQUENCY_ATTR_MAX_TX_POWER, 1900}}}, |
| {.value = 2447, |
| .attributes = {{NL80211_FREQUENCY_ATTR_MAX_TX_POWER, 1900}}}, |
| {.value = 2452, |
| .attributes = {{NL80211_FREQUENCY_ATTR_MAX_TX_POWER, 1900}}}, |
| {.value = 2457, |
| .attributes = {{NL80211_FREQUENCY_ATTR_MAX_TX_POWER, 1900}}}, |
| {.value = 2462, |
| .attributes = {{NL80211_FREQUENCY_ATTR_MAX_TX_POWER, 1900}}}, |
| {.flags = 1 << NL80211_FREQUENCY_ATTR_NO_IR, |
| .value = 2467, |
| .attributes = {{NL80211_FREQUENCY_ATTR_MAX_TX_POWER, 1900}}}, |
| {.flags = 1 << NL80211_FREQUENCY_ATTR_NO_IR, |
| .value = 2472, |
| .attributes = {{NL80211_FREQUENCY_ATTR_MAX_TX_POWER, 1900}}}, |
| {.flags = 1 << NL80211_FREQUENCY_ATTR_NO_IR, |
| .value = 2484, |
| .attributes = {{NL80211_FREQUENCY_ATTR_MAX_TX_POWER, 2000}}}, |
| }}, |
| {1, |
| { |
| {.value = 5180, |
| .attributes = {{NL80211_FREQUENCY_ATTR_MAX_TX_POWER, 2000}}}, |
| {.flags = 1 << NL80211_FREQUENCY_ATTR_NO_IR, |
| .value = 5200, |
| .attributes = {{NL80211_FREQUENCY_ATTR_MAX_TX_POWER, 2000}}}, |
| {.value = 5220, |
| .attributes = {{NL80211_FREQUENCY_ATTR_MAX_TX_POWER, 2000}}}, |
| {.value = 5240, |
| .attributes = {{NL80211_FREQUENCY_ATTR_MAX_TX_POWER, 2000}}}, |
| {.flags = 1 << NL80211_FREQUENCY_ATTR_NO_IR | |
| 1 << NL80211_FREQUENCY_ATTR_RADAR, |
| .value = 5260, |
| .attributes = {{NL80211_FREQUENCY_ATTR_MAX_TX_POWER, 2000}}}, |
| {.flags = 1 << NL80211_FREQUENCY_ATTR_NO_IR | |
| 1 << NL80211_FREQUENCY_ATTR_RADAR, |
| .value = 5280, |
| .attributes = {{NL80211_FREQUENCY_ATTR_MAX_TX_POWER, 2000}}}, |
| {.flags = 1 << NL80211_FREQUENCY_ATTR_NO_IR | |
| 1 << NL80211_FREQUENCY_ATTR_RADAR, |
| .value = 5300, |
| .attributes = {{NL80211_FREQUENCY_ATTR_MAX_TX_POWER, 2000}}}, |
| {.flags = 1 << NL80211_FREQUENCY_ATTR_NO_IR | |
| 1 << NL80211_FREQUENCY_ATTR_RADAR, |
| .value = 5320, |
| .attributes = {{NL80211_FREQUENCY_ATTR_MAX_TX_POWER, 2000}}}, |
| {.flags = 1 << NL80211_FREQUENCY_ATTR_NO_IR | |
| 1 << NL80211_FREQUENCY_ATTR_RADAR, |
| .value = 5500, |
| .attributes = {{NL80211_FREQUENCY_ATTR_MAX_TX_POWER, 2000}}}, |
| {.flags = 1 << NL80211_FREQUENCY_ATTR_NO_IR | |
| 1 << NL80211_FREQUENCY_ATTR_RADAR, |
| .value = 5520, |
| .attributes = {{NL80211_FREQUENCY_ATTR_MAX_TX_POWER, 2000}}}, |
| {.flags = 1 << NL80211_FREQUENCY_ATTR_NO_IR | |
| 1 << NL80211_FREQUENCY_ATTR_RADAR, |
| .value = 5540, |
| .attributes = {{NL80211_FREQUENCY_ATTR_MAX_TX_POWER, 2000}}}, |
| {.flags = 1 << NL80211_FREQUENCY_ATTR_NO_IR | |
| 1 << NL80211_FREQUENCY_ATTR_RADAR, |
| .value = 5560, |
| .attributes = {{NL80211_FREQUENCY_ATTR_MAX_TX_POWER, 2000}}}, |
| {.flags = 1 << NL80211_FREQUENCY_ATTR_NO_IR | |
| 1 << NL80211_FREQUENCY_ATTR_RADAR, |
| .value = 5580, |
| .attributes = {{NL80211_FREQUENCY_ATTR_MAX_TX_POWER, 2000}}}, |
| {.flags = 1 << NL80211_FREQUENCY_ATTR_NO_IR | |
| 1 << NL80211_FREQUENCY_ATTR_RADAR, |
| .value = 5600, |
| .attributes = {{NL80211_FREQUENCY_ATTR_MAX_TX_POWER, 2000}}}, |
| {.flags = 1 << NL80211_FREQUENCY_ATTR_NO_IR | |
| 1 << NL80211_FREQUENCY_ATTR_RADAR, |
| .value = 5620, |
| .attributes = {{NL80211_FREQUENCY_ATTR_MAX_TX_POWER, 2000}}}, |
| {.flags = 1 << NL80211_FREQUENCY_ATTR_NO_IR | |
| 1 << NL80211_FREQUENCY_ATTR_RADAR, |
| .value = 5640, |
| .attributes = {{NL80211_FREQUENCY_ATTR_MAX_TX_POWER, 2000}}}, |
| {.flags = 1 << NL80211_FREQUENCY_ATTR_NO_IR | |
| 1 << NL80211_FREQUENCY_ATTR_RADAR, |
| .value = 5660, |
| .attributes = {{NL80211_FREQUENCY_ATTR_MAX_TX_POWER, 2000}}}, |
| {.flags = 1 << NL80211_FREQUENCY_ATTR_NO_IR | |
| 1 << NL80211_FREQUENCY_ATTR_RADAR, |
| .value = 5680, |
| .attributes = {{NL80211_FREQUENCY_ATTR_MAX_TX_POWER, 2000}}}, |
| {.flags = 1 << NL80211_FREQUENCY_ATTR_NO_IR | |
| 1 << NL80211_FREQUENCY_ATTR_RADAR, |
| .value = 5700, |
| .attributes = {{NL80211_FREQUENCY_ATTR_MAX_TX_POWER, 2000}}}, |
| {.value = 5745, |
| .attributes = {{NL80211_FREQUENCY_ATTR_MAX_TX_POWER, 2000}}}, |
| {.flags = 1 << NL80211_FREQUENCY_ATTR_NO_IR, |
| .value = 5765, |
| .attributes = {{NL80211_FREQUENCY_ATTR_MAX_TX_POWER, 2000}}}, |
| {.flags = 1 << NL80211_FREQUENCY_ATTR_NO_IR, |
| .value = 5785, |
| .attributes = {{NL80211_FREQUENCY_ATTR_MAX_TX_POWER, 2000}}}, |
| {.flags = 1 << NL80211_FREQUENCY_ATTR_NO_IR, |
| .value = 5805, |
| .attributes = {{NL80211_FREQUENCY_ATTR_MAX_TX_POWER, 2000}}}, |
| {.flags = 1 << NL80211_FREQUENCY_ATTR_NO_IR, |
| .value = 5825, |
| .attributes = {{NL80211_FREQUENCY_ATTR_MAX_TX_POWER, 2000}}}, |
| }}}; |
| |
| // Bytes representing a NL80211_CMD_NEW_WIPHY message which includes the |
| // attribute NL80211_ATTR_INTERFACE_COMBINATIONS. The combination in this |
| // message supports single channel on a single interface. The full combinations |
| // attribute of this message looks like this: |
| // |
| // valid interface combinations: |
| // * #{ P2P-client } <= 1, #{ managed, AP, P2P-GO } <= 1, #{ P2P-device } |
| // <= 1, total <= 3, #channels <= 1 |
| const uint8_t kNewSingleChannelNoAPSTAConcurrencyNlMsg[] = { |
| 0xac, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, |
| 0xf6, 0x31, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x02, 0x00, 0x70, 0x68, 0x79, 0x30, |
| 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x2e, 0x00, 0x01, 0x00, 0x00, 0x00, |
| 0x0c, 0x00, 0x79, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x06, 0x00, |
| 0x70, 0x00, 0x78, 0x00, 0x6c, 0x00, 0x01, 0x00, 0x48, 0x00, 0x01, 0x00, |
| 0x14, 0x00, 0x01, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, |
| 0x08, 0x00, 0x02, 0x00, 0x04, 0x00, 0x08, 0x00, 0x1c, 0x00, 0x02, 0x00, |
| 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x02, 0x00, |
| 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x09, 0x00, |
| 0x14, 0x00, 0x03, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, |
| 0x08, 0x00, 0x02, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x04, 0x00, |
| 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00, |
| 0x08, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x06, 0x00, |
| 0x00, 0x00, 0x00, 0x00}; |
| |
| // Bytes representing a NL80211_CMD_NEW_WIPHY message which includes the |
| // attribute NL80211_ATTR_INTERFACE_COMBINATIONS. The combination in this |
| // message supports single channel on a single interface. The full combinations |
| // attribute of this message looks like this: |
| // |
| // valid interface combinations: |
| // * #{ managed } <= 1, #{ AP, P2P-client, P2P-GO } <= 1, #{ P2P-device } |
| // <= 1, total <= 3, #channels <= 1 |
| const uint8_t kNewSingleChannelConcurrencyNlMsg[] = { |
| 0xac, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, |
| 0xf6, 0x31, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x02, 0x00, 0x70, 0x68, 0x79, 0x30, |
| 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x2e, 0x00, 0x01, 0x00, 0x00, 0x00, |
| 0x0c, 0x00, 0x79, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x06, 0x00, |
| 0x70, 0x00, 0x78, 0x00, 0x6c, 0x00, 0x01, 0x00, 0x48, 0x00, 0x01, 0x00, |
| 0x14, 0x00, 0x01, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, |
| 0x08, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x1c, 0x00, 0x02, 0x00, |
| 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x02, 0x00, |
| 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x08, 0x00, 0x04, 0x00, 0x09, 0x00, |
| 0x14, 0x00, 0x03, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, |
| 0x08, 0x00, 0x02, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x04, 0x00, |
| 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00, |
| 0x08, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x06, 0x00, |
| 0x00, 0x00, 0x00, 0x00}; |
| |
| // Bytes representing a NL80211_CMD_NEW_WIPHY message which includes the |
| // attribute NL80211_ATTR_INTERFACE_COMBINATIONS. The combination in this |
| // message supports multiple channels on multiple interfaces. The full |
| // combinations attribute of this message looks like this: |
| // |
| // valid interface combinations: |
| // * #{ managed } <= 2, #{ AP, P2P-client, P2P-GO } <= 2, #{ P2P-device } |
| // <= 1, total <= 4, #channels <= 1 |
| // * #{ managed } <= 2, #{ P2P-client } <= 2, #{ AP, P2P-GO } <= 1, |
| // #{ P2P-device } <= 1, total <= 4, #channels <= 2 |
| // * #{ managed } <= 1, #{ IBSS } <= 1, |
| // total <= 2, #channels <= 1 |
| |
| const uint8_t kNewMultiChannelConcurrencyNlMsg[] = { |
| 0x72, 0x01, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, |
| 0xf6, 0x31, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x02, 0x00, 0x70, 0x68, 0x79, 0x30, |
| 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x2e, 0x00, 0x01, 0x00, 0x00, 0x00, |
| 0x08, 0x00, 0x79, 0x00, 0x04, 0x00, 0x06, 0x00, 0x3c, 0x01, 0x78, 0x00, |
| 0x6c, 0x00, 0x01, 0x00, 0x48, 0x00, 0x01, 0x00, 0x14, 0x00, 0x01, 0x00, |
| 0x08, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, |
| 0x04, 0x00, 0x02, 0x00, 0x1c, 0x00, 0x02, 0x00, 0x08, 0x00, 0x01, 0x00, |
| 0x02, 0x00, 0x00, 0x00, 0x10, 0x00, 0x02, 0x00, 0x04, 0x00, 0x03, 0x00, |
| 0x04, 0x00, 0x08, 0x00, 0x04, 0x00, 0x09, 0x00, 0x14, 0x00, 0x03, 0x00, |
| 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, |
| 0x04, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, |
| 0x08, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x05, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x7c, 0x00, 0x02, 0x00, 0x58, 0x00, 0x01, 0x00, 0x14, 0x00, 0x01, 0x00, |
| 0x08, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, |
| 0x04, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x08, 0x00, 0x01, 0x00, |
| 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x04, 0x00, 0x08, 0x00, |
| 0x18, 0x00, 0x03, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, |
| 0x0c, 0x00, 0x02, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x09, 0x00, |
| 0x14, 0x00, 0x04, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, |
| 0x08, 0x00, 0x02, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x04, 0x00, |
| 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, |
| 0x08, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x06, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x03, 0x00, 0x2c, 0x00, 0x01, 0x00, |
| 0x14, 0x00, 0x01, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, |
| 0x08, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, |
| 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, |
| 0x04, 0x00, 0x01, 0x00, 0x08, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, |
| 0x08, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x05, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00}; |
| |
| uint32_t kWiFiPhyIndex = 0; |
| |
| // WiFi frequency constants |
| constexpr uint32_t kLBStartFreq = 2412; |
| constexpr uint32_t kChan11Freq = 2462; |
| constexpr uint32_t kHBStartFreq = 5160; |
| constexpr uint32_t kHBEndFreq = 5980; |
| |
| constexpr net_base::MacAddress kMacAddress0(0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff); |
| constexpr net_base::MacAddress kMacAddress1(0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa); |
| } // namespace |
| |
| class WiFiPhyTest : public ::testing::Test { |
| public: |
| WiFiPhyTest() |
| : manager_(&control_interface_, &dispatcher_, &metrics_), |
| wifi_phy_(kWiFiPhyIndex) {} |
| ~WiFiPhyTest() override = default; |
| |
| protected: |
| EventDispatcherForTest dispatcher_; |
| MockControl control_interface_; |
| NiceMock<MockMetrics> metrics_; |
| MockManager manager_; |
| WiFiPhy wifi_phy_; |
| StrictMock<base::MockRepeatingCallback<void(LocalDevice::DeviceEvent, |
| const LocalDevice*)>> |
| event_cb_; |
| |
| MockManager* manager() { return &manager_; } |
| |
| void AddWiFiDevice(WiFiConstRefPtr device) { |
| wifi_phy_.AddWiFiDevice(device); |
| } |
| |
| void DeleteWiFiDevice(WiFiConstRefPtr device) { |
| wifi_phy_.DeleteWiFiDevice(device->link_name()); |
| } |
| |
| bool HasWiFiDevice(WiFiConstRefPtr device) { |
| return base::Contains(wifi_phy_.wifi_devices_, device); |
| } |
| |
| void ChangeDeviceState(WiFiConstRefPtr device) { |
| wifi_phy_.WiFiDeviceStateChanged(device); |
| } |
| |
| void PhyDumpComplete() { wifi_phy_.PhyDumpComplete(); } |
| |
| void OnNewWiphy(const Nl80211Message& nl80211_message) { |
| wifi_phy_.OnNewWiphy(nl80211_message); |
| } |
| |
| void AddSupportedIface(nl80211_iftype iftype) { |
| wifi_phy_.supported_ifaces_.insert(iftype); |
| } |
| |
| bool SupportsIftype(nl80211_iftype iftype) { |
| return wifi_phy_.SupportsIftype(iftype); |
| } |
| |
| void ParseInterfaceTypes(const Nl80211Message& nl80211_message) { |
| wifi_phy_.ParseInterfaceTypes(nl80211_message); |
| } |
| |
| void ParseConcurrency(const Nl80211Message& nl80211_message) { |
| wifi_phy_.ParseConcurrency(nl80211_message); |
| } |
| |
| uint32_t SupportsConcurrency(std::multiset<nl80211_iftype> iface_types) { |
| return wifi_phy_.SupportsConcurrency(iface_types); |
| } |
| |
| WiFiPhy::RemovalCandidateSet GetAllCandidates( |
| std::vector<WiFiPhy::ConcurrentIface> ifaces) { |
| return WiFiPhy::GetAllCandidates(ifaces); |
| } |
| |
| std::optional<std::multiset<nl80211_iftype>> RequestNewIface( |
| nl80211_iftype desired_type, WiFiPhy::Priority priority) { |
| return wifi_phy_.RequestNewIface(desired_type, priority); |
| } |
| |
| void AddActiveIfaces(std::vector<WiFiPhy::ConcurrentIface> ifaces) { |
| for (auto iface : ifaces) { |
| switch (iface.iftype) { |
| case NL80211_IFTYPE_STATION: |
| MockWiFi* wifi_device; |
| wifi_device = new MockWiFi(&manager_, "wlan0", kMacAddress1, 0, |
| kWiFiPhyIndex, new MockWakeOnWiFi()); |
| wifi_device->SetPriority(iface.priority); |
| wifi_phy_.wifi_devices_.insert(wifi_device); |
| break; |
| case NL80211_IFTYPE_P2P_CLIENT: |
| wifi_phy_.wifi_local_devices_.insert(new MockP2PDevice( |
| &manager_, LocalDevice::IfaceType::kP2PClient, "wlan0", 0, 0, |
| iface.priority, event_cb_.Get())); |
| break; |
| case NL80211_IFTYPE_P2P_GO: |
| wifi_phy_.wifi_local_devices_.insert(new MockP2PDevice( |
| &manager_, LocalDevice::IfaceType::kP2PGO, "wlan0", 0, 0, |
| iface.priority, event_cb_.Get())); |
| break; |
| case NL80211_IFTYPE_AP: |
| wifi_phy_.wifi_local_devices_.insert( |
| new MockHotspotDevice(&manager_, "wlan0", "ap0", kMacAddress1, 0, |
| iface.priority, event_cb_.Get())); |
| break; |
| default: |
| FAIL() << "Tried to create unsupported device type: " << iface.iftype; |
| } |
| } |
| } |
| |
| void ClearActiveIfaces() { |
| wifi_phy_.wifi_devices_.clear(); |
| wifi_phy_.wifi_local_devices_.clear(); |
| } |
| |
| void AssertConcurrencySorted() { |
| auto current_comb = wifi_phy_.concurrency_combs_.begin(); |
| if (current_comb == wifi_phy_.concurrency_combs_.end()) { |
| return; |
| } |
| auto next_comb = ++wifi_phy_.concurrency_combs_.begin(); |
| while (next_comb != wifi_phy_.concurrency_combs_.end()) { |
| ASSERT_TRUE(current_comb->num_channels >= next_comb->num_channels); |
| current_comb++; |
| next_comb++; |
| } |
| } |
| |
| void AssertConcurrencyCombinationsAreEqual(ConcurrencyCombination lhs, |
| ConcurrencyCombination rhs) { |
| ASSERT_EQ(lhs.max_num, rhs.max_num); |
| ASSERT_EQ(lhs.num_channels, rhs.num_channels); |
| ASSERT_EQ(lhs.limits.size(), rhs.limits.size()); |
| |
| for (uint i = 0; i < lhs.limits.size(); i++) { |
| AssertIfaceLimitsAreEqual(lhs.limits[i], rhs.limits[i]); |
| } |
| } |
| |
| void AssertIfaceLimitsAreEqual(IfaceLimit lhs, IfaceLimit rhs) { |
| ASSERT_EQ(lhs.max, rhs.max); |
| ASSERT_EQ(lhs.iftypes.size(), rhs.iftypes.size()); |
| for (uint i = 0; i < lhs.iftypes.size(); i++) { |
| ASSERT_EQ(lhs.iftypes[i], rhs.iftypes[i]); |
| } |
| } |
| |
| void AssertPhyConcurrencyIsEqualTo(ConcurrencyCombinationSet combs) { |
| ASSERT_EQ(wifi_phy_.concurrency_combs_.size(), combs.size()); |
| auto lhs_iter = wifi_phy_.concurrency_combs_.begin(); |
| auto rhs_iter = combs.begin(); |
| while (lhs_iter != wifi_phy_.concurrency_combs_.end()) { |
| AssertConcurrencyCombinationsAreEqual(*lhs_iter, *rhs_iter); |
| lhs_iter++; |
| rhs_iter++; |
| } |
| } |
| |
| void AssertRemovalCandidateSetOrder( |
| WiFiPhy::RemovalCandidateSet candidates, |
| std::vector<WiFiPhy::RemovalCandidate> expected_order) { |
| ASSERT_EQ(candidates.size(), expected_order.size()); |
| uint32_t idx = 0; |
| for (auto candidate : candidates) { |
| ASSERT_EQ(candidate, expected_order[idx]); |
| idx++; |
| } |
| } |
| |
| void AssertApStaConcurrency(bool support) { |
| ASSERT_EQ(wifi_phy_.SupportAPSTAConcurrency(), support); |
| } |
| |
| struct ConcurrencyTestCase { |
| std::vector<WiFiPhy::ConcurrentIface> |
| present_ifaces; // Types already reserved. |
| WiFiPhy::ConcurrentIface new_iface; // Type to check. |
| std::optional<std::multiset<nl80211_iftype>> |
| expected_response; // Expected response from RequestNewIface. |
| }; |
| |
| void TestInterfaceCombinations(std::vector<ConcurrencyTestCase> test_cases, |
| ConcurrencyCombinationSet combs) { |
| wifi_phy_.concurrency_combs_ = combs; |
| for (auto tc : test_cases) { |
| AddActiveIfaces(tc.present_ifaces); |
| std::optional<std::multiset<nl80211_iftype>> response = |
| RequestNewIface(tc.new_iface.iftype, tc.new_iface.priority); |
| if (response != tc.expected_response) { |
| LOG(INFO) << "Present ifaces: "; |
| for (auto iface : tc.present_ifaces) { |
| LOG(INFO) << "\tType: " << iface.iftype |
| << ", Priority: " << iface.priority; |
| } |
| LOG(INFO) << "Requested iface: "; |
| LOG(INFO) << "\tType: " << tc.new_iface.iftype |
| << ", Priority: " << tc.new_iface.priority; |
| // Technically redundant with the above "if" statement, but the macro |
| // is useful for neat logging of a failed equality check. |
| EXPECT_EQ(response, tc.expected_response); |
| } |
| ClearActiveIfaces(); |
| } |
| } |
| |
| const WiFiPhy::Frequencies& frequencies() { return wifi_phy_.frequencies_; } |
| |
| void SetFrequencies(WiFiPhy::Frequencies& frequencies) { |
| wifi_phy_.frequencies_ = frequencies; |
| } |
| }; |
| |
| TEST_F(WiFiPhyTest, AddAndDeleteDevices) { |
| scoped_refptr<MockWiFi> device0 = new NiceMock<MockWiFi>( |
| &manager_, "null0", kMacAddress0, 0, kWiFiPhyIndex, new MockWakeOnWiFi()); |
| scoped_refptr<MockWiFi> device1 = new NiceMock<MockWiFi>( |
| &manager_, "null1", kMacAddress1, 0, kWiFiPhyIndex, new MockWakeOnWiFi()); |
| |
| EXPECT_FALSE(HasWiFiDevice(device0)); |
| EXPECT_FALSE(HasWiFiDevice(device1)); |
| |
| AddWiFiDevice(device0); |
| EXPECT_TRUE(HasWiFiDevice(device0)); |
| EXPECT_FALSE(HasWiFiDevice(device1)); |
| |
| AddWiFiDevice(device1); |
| EXPECT_TRUE(HasWiFiDevice(device0)); |
| EXPECT_TRUE(HasWiFiDevice(device1)); |
| |
| DeleteWiFiDevice(device0); |
| EXPECT_FALSE(HasWiFiDevice(device0)); |
| EXPECT_TRUE(HasWiFiDevice(device1)); |
| |
| DeleteWiFiDevice(device1); |
| EXPECT_FALSE(HasWiFiDevice(device0)); |
| EXPECT_FALSE(HasWiFiDevice(device1)); |
| } |
| |
| TEST_F(WiFiPhyTest, AddDeviceTwice) { |
| scoped_refptr<MockWiFi> device = new NiceMock<MockWiFi>( |
| &manager_, "null0", kMacAddress0, 0, kWiFiPhyIndex, new MockWakeOnWiFi()); |
| |
| AddWiFiDevice(device); |
| EXPECT_TRUE(HasWiFiDevice(device)); |
| |
| // Adding the same device a second time should be a no-op. |
| AddWiFiDevice(device); |
| EXPECT_TRUE(HasWiFiDevice(device)); |
| |
| // The device should be gone after one delete. |
| DeleteWiFiDevice(device); |
| EXPECT_FALSE(HasWiFiDevice(device)); |
| } |
| |
| TEST_F(WiFiPhyTest, DeleteDeviceTwice) { |
| scoped_refptr<MockWiFi> device = new NiceMock<MockWiFi>( |
| &manager_, "null0", kMacAddress0, 0, kWiFiPhyIndex, new MockWakeOnWiFi()); |
| |
| AddWiFiDevice(device); |
| EXPECT_TRUE(HasWiFiDevice(device)); |
| |
| DeleteWiFiDevice(device); |
| EXPECT_FALSE(HasWiFiDevice(device)); |
| |
| // Deleting a device a second time should be a no-op. |
| DeleteWiFiDevice(device); |
| EXPECT_FALSE(HasWiFiDevice(device)); |
| } |
| |
| TEST_F(WiFiPhyTest, OnNewWiphy_CheckFreqs) { |
| NewWiphyMessage msg; |
| net_base::NetlinkPacket packet(kNewWiphyNlMsg); |
| msg.InitFromPacketWithContext(&packet, Nl80211Message::Context()); |
| OnNewWiphy(msg); |
| PhyDumpComplete(); |
| EXPECT_EQ(kNewWiphyNlMsg_AllFrequencies, frequencies()); |
| } |
| |
| TEST_F(WiFiPhyTest, OnNewWiphy_KeepLastFreqs) { |
| NewWiphyMessage msg1; |
| net_base::NetlinkPacket packet1(kNewWiphyNlMsg); |
| msg1.InitFromPacketWithContext(&packet1, Nl80211Message::Context()); |
| |
| // Modify flags and attributes for the frequencies reported in the message. |
| net_base::AttributeListRefPtr bands_list; |
| EXPECT_TRUE(msg1.attributes()->GetNestedAttributeList( |
| NL80211_ATTR_WIPHY_BANDS, &bands_list)); |
| net_base::AttributeIdIterator bands_iter(*bands_list); |
| for (; !bands_iter.AtEnd(); bands_iter.Advance()) { |
| net_base::AttributeListRefPtr band_attrs; |
| if (bands_list->GetNestedAttributeList(bands_iter.GetId(), &band_attrs)) { |
| net_base::AttributeListRefPtr freqs_list; |
| if (!band_attrs->GetNestedAttributeList(NL80211_BAND_ATTR_FREQS, |
| &freqs_list)) { |
| continue; |
| } |
| net_base::AttributeIdIterator freqs_iter(*freqs_list); |
| for (; !freqs_iter.AtEnd(); freqs_iter.Advance()) { |
| net_base::AttributeListRefPtr freq_attrs; |
| if (freqs_list->GetNestedAttributeList(freqs_iter.GetId(), |
| &freq_attrs)) { |
| uint32_t value; |
| for (auto attr = net_base::AttributeIdIterator(*freq_attrs); |
| !attr.AtEnd(); attr.Advance()) { |
| if (attr.GetType() == net_base::NetlinkAttribute::kTypeFlag) { |
| freq_attrs->SetFlagAttributeValue(attr.GetId(), false); |
| } else { |
| EXPECT_EQ(attr.GetType(), net_base::NetlinkAttribute::kTypeU32); |
| if (attr.GetId() == NL80211_FREQUENCY_ATTR_FREQ) { |
| continue; |
| } |
| freq_attrs->GetU32AttributeValue(attr.GetId(), &value); |
| freq_attrs->SetU32AttributeValue(attr.GetId(), value ^ -1U); |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| EXPECT_NE(kNewWiphyNlMsg_AllFrequencies, frequencies()); |
| OnNewWiphy(msg1); |
| // Now parse the original packet and observe that the attributes get |
| // overwritten with proper values, each frequency is visible only once and the |
| // frequencies get "public" visibility. |
| NewWiphyMessage msg2; |
| net_base::NetlinkPacket packet2(kNewWiphyNlMsg); |
| msg2.InitFromPacketWithContext(&packet2, Nl80211Message::Context()); |
| OnNewWiphy(msg2); |
| PhyDumpComplete(); |
| EXPECT_EQ(kNewWiphyNlMsg_AllFrequencies, frequencies()); |
| } |
| |
| TEST_F(WiFiPhyTest, SupportsIftype) { |
| EXPECT_FALSE(SupportsIftype(NL80211_IFTYPE_AP)); |
| AddSupportedIface(NL80211_IFTYPE_AP); |
| EXPECT_TRUE(SupportsIftype(NL80211_IFTYPE_AP)); |
| } |
| |
| TEST_F(WiFiPhyTest, ParseInterfaceTypes) { |
| NewWiphyMessage msg; |
| net_base::NetlinkPacket packet(kNewWiphyNlMsg_IfTypes); |
| msg.InitFromPacketWithContext(&packet, Nl80211Message::Context()); |
| ParseInterfaceTypes(msg); |
| EXPECT_TRUE(SupportsIftype(NL80211_IFTYPE_ADHOC)); |
| EXPECT_TRUE(SupportsIftype(NL80211_IFTYPE_STATION)); |
| EXPECT_TRUE(SupportsIftype(NL80211_IFTYPE_AP)); |
| EXPECT_TRUE(SupportsIftype(NL80211_IFTYPE_MONITOR)); |
| EXPECT_TRUE(SupportsIftype(NL80211_IFTYPE_P2P_CLIENT)); |
| EXPECT_TRUE(SupportsIftype(NL80211_IFTYPE_P2P_GO)); |
| EXPECT_TRUE(SupportsIftype(NL80211_IFTYPE_P2P_DEVICE)); |
| EXPECT_FALSE(SupportsIftype(NL80211_IFTYPE_AP_VLAN)); |
| EXPECT_FALSE(SupportsIftype(NL80211_IFTYPE_WDS)); |
| EXPECT_FALSE(SupportsIftype(NL80211_IFTYPE_MESH_POINT)); |
| EXPECT_FALSE(SupportsIftype(NL80211_IFTYPE_OCB)); |
| EXPECT_FALSE(SupportsIftype(NL80211_IFTYPE_NAN)); |
| EXPECT_TRUE(wifi_phy_.SupportAPMode()); |
| EXPECT_TRUE(wifi_phy_.SupportP2PMode()); |
| } |
| |
| TEST_F(WiFiPhyTest, ParseNoAPSTAConcurrencySingleChannel) { |
| NewWiphyMessage msg; |
| net_base::NetlinkPacket packet(kNewSingleChannelNoAPSTAConcurrencyNlMsg); |
| msg.InitFromPacketWithContext(&packet, Nl80211Message::Context()); |
| ParseConcurrency(msg); |
| |
| // These values align with those from |
| // kNewSingleChannelNoAPSTAConcurrencyNlMsg. They must be declared inline |
| // because the |nl80211_iftype|s are C values which can't be instantiated |
| // outside a function context. |
| ConcurrencyCombinationSet SingleChannelNoAPSTAConcurrencyCombinations{ |
| (struct ConcurrencyCombination){ |
| .limits = {(struct IfaceLimit){.iftypes = {NL80211_IFTYPE_P2P_CLIENT}, |
| .max = 1}, |
| (struct IfaceLimit){ |
| .iftypes = {NL80211_IFTYPE_STATION, NL80211_IFTYPE_AP, |
| NL80211_IFTYPE_P2P_GO}, |
| .max = 1, |
| }, |
| (struct IfaceLimit){.iftypes = {NL80211_IFTYPE_P2P_DEVICE}, |
| .max = 1}}, |
| .max_num = 3, |
| .num_channels = 1}}; |
| AssertPhyConcurrencyIsEqualTo(SingleChannelNoAPSTAConcurrencyCombinations); |
| AssertApStaConcurrency(false); |
| } |
| |
| TEST_F(WiFiPhyTest, ParseConcurrencySingleChannel) { |
| NewWiphyMessage msg; |
| net_base::NetlinkPacket packet(kNewSingleChannelConcurrencyNlMsg); |
| msg.InitFromPacketWithContext(&packet, Nl80211Message::Context()); |
| ParseConcurrency(msg); |
| |
| // These values align with those from kNewSingleChannelConcurrencyNlMsg. They |
| // must be declared inline because the |nl80211_iftype|s are C values |
| // which can't be instantiated outside a function context. |
| ConcurrencyCombinationSet SingleChannelConcurrencyCombinations{( |
| struct ConcurrencyCombination){ |
| .limits = {(struct IfaceLimit){.iftypes = {NL80211_IFTYPE_STATION}, |
| .max = 1}, |
| (struct IfaceLimit){ |
| .iftypes = {NL80211_IFTYPE_AP, NL80211_IFTYPE_P2P_CLIENT, |
| NL80211_IFTYPE_P2P_GO}, |
| .max = 1, |
| }, |
| (struct IfaceLimit){.iftypes = {NL80211_IFTYPE_P2P_DEVICE}, |
| .max = 1}}, |
| .max_num = 3, |
| .num_channels = 1}}; |
| AssertPhyConcurrencyIsEqualTo(SingleChannelConcurrencyCombinations); |
| AssertApStaConcurrency(true); |
| } |
| |
| TEST_F(WiFiPhyTest, ParseConcurrencyMultiChannel) { |
| NewWiphyMessage msg; |
| net_base::NetlinkPacket packet(kNewMultiChannelConcurrencyNlMsg); |
| msg.InitFromPacketWithContext(&packet, Nl80211Message::Context()); |
| ParseConcurrency(msg); |
| AssertConcurrencySorted(); |
| |
| // These values align with those from kNewMultiChannelConcurrencyNlMsg. They |
| // must be declared inline because the |nl80211_iftype|s are C values |
| // which can't be instantiated outside a function context. |
| ConcurrencyCombinationSet MultiChannelConcurrencyCombinations{ |
| (struct ConcurrencyCombination){ |
| .limits = {(struct IfaceLimit){.iftypes = {NL80211_IFTYPE_STATION}, |
| .max = 2}, |
| (struct IfaceLimit){ |
| .iftypes = {NL80211_IFTYPE_AP, |
| NL80211_IFTYPE_P2P_CLIENT, |
| NL80211_IFTYPE_P2P_GO}, |
| .max = 2, |
| }, |
| (struct IfaceLimit){.iftypes = {NL80211_IFTYPE_P2P_DEVICE}, |
| .max = 1}}, |
| .max_num = 4, |
| .num_channels = 1}, |
| (struct ConcurrencyCombination){ |
| .limits = {(struct IfaceLimit){.iftypes = {NL80211_IFTYPE_STATION}, |
| .max = 2}, |
| (struct IfaceLimit){ |
| .iftypes = {NL80211_IFTYPE_P2P_CLIENT}, |
| .max = 2, |
| }, |
| (struct IfaceLimit){ |
| .iftypes = {NL80211_IFTYPE_AP, NL80211_IFTYPE_P2P_GO}, |
| .max = 1, |
| }, |
| (struct IfaceLimit){.iftypes = {NL80211_IFTYPE_P2P_DEVICE}, |
| .max = 1}}, |
| .max_num = 4, |
| .num_channels = 2}, |
| (struct ConcurrencyCombination){ |
| .limits = {(struct IfaceLimit){.iftypes = {NL80211_IFTYPE_STATION}, |
| .max = 1}, |
| (struct IfaceLimit){.iftypes = {NL80211_IFTYPE_ADHOC}, |
| .max = 1}}, |
| .max_num = 2, |
| .num_channels = 1}, |
| }; |
| AssertPhyConcurrencyIsEqualTo(MultiChannelConcurrencyCombinations); |
| AssertApStaConcurrency(true); |
| } |
| |
| TEST_F(WiFiPhyTest, SelectFrequency_Empty) { |
| WiFiPhy::Frequencies frequencies; |
| |
| WiFiBand band = WiFiBand::kLowBand; |
| auto freq = wifi_phy_.SelectFrequency(band); |
| EXPECT_FALSE(freq.has_value()); |
| band = WiFiBand::kHighBand; |
| freq = wifi_phy_.SelectFrequency(band); |
| EXPECT_FALSE(freq.has_value()); |
| band = WiFiBand::kAllBands; |
| freq = wifi_phy_.SelectFrequency(band); |
| EXPECT_FALSE(freq.has_value()); |
| } |
| |
| TEST_F(WiFiPhyTest, SelectFrequency_NoValidHB) { |
| WiFiPhy::Frequencies frequencies = { |
| {0, |
| { |
| {.value = 2412}, // Channel 1 |
| {.value = 2417}, // Channel 2 |
| {.value = 2422}, // Channel 3 |
| {.value = 2467}, // Channel 12 |
| {.value = 2472}, // Channel 13 |
| }}, |
| {1, |
| { |
| {.flags = 1 << NL80211_FREQUENCY_ATTR_NO_IR, .value = 5200}, |
| {.flags = 1 << NL80211_FREQUENCY_ATTR_RADAR, .value = 5300}, |
| }}}; |
| SetFrequencies(frequencies); |
| auto freq = wifi_phy_.SelectFrequency(WiFiBand::kAllBands); |
| EXPECT_TRUE(freq.has_value()); |
| EXPECT_GE(freq, kLBStartFreq); |
| EXPECT_LE(freq, kChan11Freq); // Should avoid channel greater than channel 11 |
| EXPECT_TRUE(base::Contains(frequencies[0], uint32_t(freq.value()), |
| [](auto& f) { return f.value; })); |
| } |
| |
| TEST_F(WiFiPhyTest, SelectFrequency_DualBandsAvailable) { |
| WiFiPhy::Frequencies frequencies = { |
| {0, |
| { |
| {.value = 2412}, // Channel 1 |
| {.value = 2417}, // Channel 2 |
| {.value = 2422}, // Channel 3 |
| {.value = 2467}, // Channel 12 |
| {.value = 2472}, // Channel 13 |
| }}, |
| {1, |
| { |
| {.value = 5180}, // Channel 36 |
| {.value = 5200}, // Channel 40 |
| {.value = 5220}, // Channel 44 |
| {.value = 5240}, // Channel 48 |
| {.flags = 1 << NL80211_FREQUENCY_ATTR_RADAR, |
| .value = 5260}, // Channel 52 |
| {.flags = 1 << NL80211_FREQUENCY_ATTR_RADAR, |
| .value = 5280}, // Channel 56 |
| {.flags = 1 << NL80211_FREQUENCY_ATTR_NO_IR, |
| .value = 5300}, // Channel 60 |
| {.flags = 1 << NL80211_FREQUENCY_ATTR_NO_IR, |
| .value = 5320}, // Channel 64 |
| {.flags = 1 << NL80211_FREQUENCY_ATTR_DISABLED, |
| .value = 5340}, // Channel 68 |
| {.flags = 1 << NL80211_FREQUENCY_ATTR_DISABLED, |
| .value = 5360}, // Channel 72 |
| }}}; |
| |
| SetFrequencies(frequencies); |
| WiFiBand band = WiFiBand::kLowBand; |
| auto freq = wifi_phy_.SelectFrequency(band); |
| EXPECT_TRUE(freq.has_value()); |
| EXPECT_GE(freq, kLBStartFreq); |
| EXPECT_LE(freq, kChan11Freq); // Should avoid channel greater than channel 11 |
| EXPECT_TRUE(base::Contains(frequencies[WiFiBandToNl(band)], |
| uint32_t(freq.value()), |
| [](auto& f) { return f.value; })); |
| |
| band = WiFiBand::kHighBand; |
| freq = wifi_phy_.SelectFrequency(band); |
| EXPECT_TRUE(freq.has_value()); |
| EXPECT_GE(freq, kHBStartFreq); |
| EXPECT_LE(freq, kHBEndFreq); |
| EXPECT_TRUE(base::Contains(frequencies[WiFiBandToNl(band)], |
| uint32_t(freq.value()), |
| [](auto& f) { return f.value; })); |
| |
| // For other preferences the selected frequency should be in 2.4 or 5GHz, |
| // however with a valid 5GHz frequency it should be preferred. |
| band = WiFiBand::kAllBands; |
| freq = wifi_phy_.SelectFrequency(band); |
| EXPECT_TRUE(freq.has_value()); |
| EXPECT_GE(freq, kHBStartFreq); |
| EXPECT_LE(freq, kHBEndFreq); |
| EXPECT_TRUE(base::Contains(frequencies[WiFiBandToNl(WiFiBand::kHighBand)], |
| uint32_t(freq.value()), |
| [](auto& f) { return f.value; })); |
| } |
| |
| TEST_F(WiFiPhyTest, ValidPriority) { |
| for (int i = 0; |
| i < static_cast<int32_t>(WiFiInterfacePriority::NUM_PRIORITIES); i++) { |
| EXPECT_TRUE(WiFiPhy::Priority(i).IsValid()) |
| << i << " should be a vaild priority"; |
| } |
| EXPECT_FALSE(WiFiPhy::Priority( |
| static_cast<int32_t>(WiFiInterfacePriority::NUM_PRIORITIES)) |
| .IsValid()) |
| << static_cast<int32_t>(WiFiInterfacePriority::NUM_PRIORITIES) |
| << " should be an invaild priority"; |
| EXPECT_FALSE(WiFiPhy::Priority(-1).IsValid()) |
| << -1 << " should be an invaild priority"; |
| } |
| |
| TEST_F(WiFiPhyTest, IfaceSorted) { |
| WiFiPhy::RemovalCandidate c = {}; |
| c.insert({NL80211_IFTYPE_STATION, WiFiPhy::Priority(0)}); |
| c.insert({NL80211_IFTYPE_STATION, WiFiPhy::Priority(4)}); |
| c.insert({NL80211_IFTYPE_STATION, WiFiPhy::Priority(3)}); |
| c.insert({NL80211_IFTYPE_STATION, WiFiPhy::Priority(2)}); |
| c.insert({NL80211_IFTYPE_STATION, WiFiPhy::Priority(5)}); |
| c.insert({NL80211_IFTYPE_STATION, WiFiPhy::Priority(5)}); |
| |
| auto iface = c.begin(); |
| auto iface_next = c.begin(); |
| iface_next++; |
| while (iface_next != c.end()) { |
| ASSERT_TRUE(iface->priority >= iface_next->priority); |
| iface++; |
| iface_next++; |
| } |
| } |
| |
| TEST_F(WiFiPhyTest, RemovalCandidateSet) { |
| // Empty candidate is most preferable. |
| std::vector<WiFiPhy::RemovalCandidate> expected_order = {}; |
| WiFiPhy::RemovalCandidate a = {}; |
| expected_order.push_back(a); |
| |
| // Less preferable than a because we have a additional interface. |
| WiFiPhy::RemovalCandidate b = {}; |
| b.insert({NL80211_IFTYPE_STATION, WiFiPhy::Priority(1)}); |
| expected_order.push_back(b); |
| |
| // Less preferable than a because we have a additional interface at the same |
| // priority. |
| WiFiPhy::RemovalCandidate c = {}; |
| c.insert({NL80211_IFTYPE_STATION, WiFiPhy::Priority(1)}); |
| c.insert({NL80211_IFTYPE_STATION, WiFiPhy::Priority(1)}); |
| expected_order.push_back(c); |
| |
| // Less preferable than c because despite having fewer interfaces, the |
| // existing interface is higher priority. |
| WiFiPhy::RemovalCandidate d = {}; |
| d.insert({NL80211_IFTYPE_STATION, WiFiPhy::Priority(2)}); |
| expected_order.push_back(d); |
| |
| // Less preferable than d because we have an extra entry at a lower |
| // priority than the maximum. |
| WiFiPhy::RemovalCandidate e = {}; |
| e.insert({NL80211_IFTYPE_STATION, WiFiPhy::Priority(1)}); |
| e.insert({NL80211_IFTYPE_STATION, WiFiPhy::Priority(2)}); |
| expected_order.push_back(e); |
| |
| // Less preferable than f because we have an extra entry at the highest |
| // priority. |
| WiFiPhy::RemovalCandidate f = {}; |
| f.insert({NL80211_IFTYPE_STATION, WiFiPhy::Priority(2)}); |
| f.insert({NL80211_IFTYPE_STATION, WiFiPhy::Priority(2)}); |
| expected_order.push_back(f); |
| |
| // Try inserting the candidates in the reverse of the expected order. |
| WiFiPhy::RemovalCandidateSet reverse_candidates = {}; |
| reverse_candidates.insert(f); |
| reverse_candidates.insert(e); |
| reverse_candidates.insert(d); |
| reverse_candidates.insert(c); |
| reverse_candidates.insert(b); |
| reverse_candidates.insert(a); |
| AssertRemovalCandidateSetOrder(reverse_candidates, expected_order); |
| |
| // Try inserting the candidates in the expected order. |
| WiFiPhy::RemovalCandidateSet ordered_candidates = {}; |
| ordered_candidates.insert(a); |
| ordered_candidates.insert(b); |
| ordered_candidates.insert(c); |
| ordered_candidates.insert(d); |
| ordered_candidates.insert(e); |
| ordered_candidates.insert(f); |
| AssertRemovalCandidateSetOrder(ordered_candidates, expected_order); |
| |
| // Try inserting the candidates in an arbitrary order. |
| WiFiPhy::RemovalCandidateSet arbitrary_candidates = {}; |
| arbitrary_candidates.insert(c); |
| arbitrary_candidates.insert(a); |
| arbitrary_candidates.insert(f); |
| arbitrary_candidates.insert(d); |
| arbitrary_candidates.insert(b); |
| arbitrary_candidates.insert(e); |
| AssertRemovalCandidateSetOrder(arbitrary_candidates, expected_order); |
| } |
| |
| TEST_F(WiFiPhyTest, SupportsConcurrency) { |
| // These values align with those from kNewMultiChannelConcurrencyNlMsg. They |
| // must be declared inline because the |nl80211_iftype|s are C values |
| // which can't be instantiated outside a function context. |
| |
| wifi_phy_.concurrency_combs_ = { |
| (struct ConcurrencyCombination){ |
| .limits = {(struct IfaceLimit){.iftypes = {NL80211_IFTYPE_STATION}, |
| .max = 2}, |
| (struct IfaceLimit){ |
| .iftypes = {NL80211_IFTYPE_AP, |
| NL80211_IFTYPE_P2P_CLIENT, |
| NL80211_IFTYPE_P2P_GO}, |
| .max = 2, |
| }, |
| (struct IfaceLimit){.iftypes = {NL80211_IFTYPE_P2P_DEVICE}, |
| .max = 1}}, |
| .max_num = 4, |
| .num_channels = 1}, |
| (struct ConcurrencyCombination){ |
| .limits = {(struct IfaceLimit){.iftypes = {NL80211_IFTYPE_STATION}, |
| .max = 1}, |
| (struct IfaceLimit){ |
| .iftypes = {NL80211_IFTYPE_P2P_CLIENT}, |
| .max = 2, |
| }, |
| (struct IfaceLimit){ |
| .iftypes = {NL80211_IFTYPE_AP, NL80211_IFTYPE_P2P_GO}, |
| .max = 1, |
| }, |
| (struct IfaceLimit){.iftypes = {NL80211_IFTYPE_P2P_DEVICE}, |
| .max = 1}}, |
| .max_num = 4, |
| .num_channels = 2}, |
| (struct ConcurrencyCombination){ |
| .limits = {(struct IfaceLimit){.iftypes = {NL80211_IFTYPE_STATION}, |
| .max = 1}, |
| (struct IfaceLimit){.iftypes = {NL80211_IFTYPE_ADHOC}, |
| .max = 1}}, |
| .max_num = 2, |
| .num_channels = 3}, |
| }; |
| |
| // Supported by all combs, so we should pick the comb with the most channels. |
| EXPECT_EQ(3, SupportsConcurrency({NL80211_IFTYPE_STATION})); |
| |
| // Supported by two combs, so we should pick the remaining comb with the most |
| // channels. |
| EXPECT_EQ(2, SupportsConcurrency({NL80211_IFTYPE_AP})); |
| EXPECT_EQ(2, |
| SupportsConcurrency({NL80211_IFTYPE_STATION, NL80211_IFTYPE_AP})); |
| EXPECT_EQ( |
| 2, SupportsConcurrency({NL80211_IFTYPE_STATION, NL80211_IFTYPE_P2P_CLIENT, |
| NL80211_IFTYPE_P2P_CLIENT})); |
| |
| // Supported by only the comb with fewest channels. |
| EXPECT_EQ( |
| 1, SupportsConcurrency({NL80211_IFTYPE_STATION, NL80211_IFTYPE_STATION})); |
| EXPECT_EQ(1, SupportsConcurrency({NL80211_IFTYPE_AP, NL80211_IFTYPE_AP})); |
| EXPECT_EQ( |
| 1, SupportsConcurrency({NL80211_IFTYPE_AP, NL80211_IFTYPE_AP, |
| NL80211_IFTYPE_STATION, NL80211_IFTYPE_STATION})); |
| |
| // Too many interfaces of a given type to be supported by any comb. |
| EXPECT_EQ(0, |
| SupportsConcurrency({NL80211_IFTYPE_STATION, NL80211_IFTYPE_STATION, |
| NL80211_IFTYPE_STATION})); |
| EXPECT_EQ(0, SupportsConcurrency({NL80211_IFTYPE_AP, NL80211_IFTYPE_AP, |
| NL80211_IFTYPE_P2P_CLIENT})); |
| |
| // All the interfaces are supported by individual limits, but too may total |
| // interfaces to fit inside max_num of any comb. |
| EXPECT_EQ(0, |
| SupportsConcurrency({NL80211_IFTYPE_AP, NL80211_IFTYPE_AP, |
| NL80211_IFTYPE_STATION, NL80211_IFTYPE_STATION, |
| NL80211_IFTYPE_P2P_DEVICE})); |
| } |
| |
| TEST_F(WiFiPhyTest, InterfaceCombinations_LowPriorityRequest) { |
| ConcurrencyCombinationSet combs = { |
| (struct ConcurrencyCombination){ |
| .limits = {(struct IfaceLimit){.iftypes = {NL80211_IFTYPE_STATION}, |
| .max = 2}, |
| (struct IfaceLimit){ |
| .iftypes = {NL80211_IFTYPE_P2P_CLIENT}, |
| .max = 2, |
| }, |
| (struct IfaceLimit){ |
| .iftypes = {NL80211_IFTYPE_AP, NL80211_IFTYPE_P2P_GO}, |
| .max = 1, |
| }, |
| (struct IfaceLimit){.iftypes = {NL80211_IFTYPE_P2P_DEVICE}, |
| .max = 1}}, |
| .max_num = 4, |
| .num_channels = 3}, |
| }; |
| |
| std::vector<ConcurrencyTestCase> test_cases = { |
| // 1 + 1 combinations. |
| |
| {{{NL80211_IFTYPE_STATION, WiFiPhy::Priority(5)}}, |
| {NL80211_IFTYPE_STATION, WiFiPhy::Priority(1)}, |
| std::multiset<nl80211_iftype>{}}, |
| {{{NL80211_IFTYPE_STATION, WiFiPhy::Priority(5)}}, |
| {NL80211_IFTYPE_P2P_GO, WiFiPhy::Priority(1)}, |
| std::multiset<nl80211_iftype>{}}, |
| {{{NL80211_IFTYPE_STATION, WiFiPhy::Priority(5)}}, |
| {NL80211_IFTYPE_AP, WiFiPhy::Priority(1)}, |
| std::multiset<nl80211_iftype>{}}, |
| {{{NL80211_IFTYPE_STATION, WiFiPhy::Priority(5)}}, |
| {NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(1)}, |
| std::multiset<nl80211_iftype>{}}, |
| |
| {{{NL80211_IFTYPE_AP, WiFiPhy::Priority(5)}}, |
| {NL80211_IFTYPE_STATION, WiFiPhy::Priority(1)}, |
| std::multiset<nl80211_iftype>{}}, |
| {{{NL80211_IFTYPE_AP, WiFiPhy::Priority(5)}}, |
| {NL80211_IFTYPE_P2P_GO, WiFiPhy::Priority(1)}, |
| std::nullopt}, |
| {{{NL80211_IFTYPE_AP, WiFiPhy::Priority(5)}}, |
| {NL80211_IFTYPE_AP, WiFiPhy::Priority(1)}, |
| std::nullopt}, |
| {{{NL80211_IFTYPE_AP, WiFiPhy::Priority(5)}}, |
| {NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(1)}, |
| std::multiset<nl80211_iftype>{}}, |
| |
| {{{NL80211_IFTYPE_P2P_GO, WiFiPhy::Priority(5)}}, |
| {NL80211_IFTYPE_STATION, WiFiPhy::Priority(1)}, |
| std::multiset<nl80211_iftype>{}}, |
| {{{NL80211_IFTYPE_P2P_GO, WiFiPhy::Priority(5)}}, |
| {NL80211_IFTYPE_P2P_GO, WiFiPhy::Priority(1)}, |
| std::nullopt}, |
| {{{NL80211_IFTYPE_P2P_GO, WiFiPhy::Priority(5)}}, |
| {NL80211_IFTYPE_AP, WiFiPhy::Priority(1)}, |
| std::nullopt}, |
| {{{NL80211_IFTYPE_P2P_GO, WiFiPhy::Priority(5)}}, |
| {NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(1)}, |
| std::multiset<nl80211_iftype>{}}, |
| |
| {{{NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(5)}}, |
| {NL80211_IFTYPE_STATION, WiFiPhy::Priority(1)}, |
| std::multiset<nl80211_iftype>{}}, |
| {{{NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(5)}}, |
| {NL80211_IFTYPE_P2P_GO, WiFiPhy::Priority(1)}, |
| std::multiset<nl80211_iftype>{}}, |
| {{{NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(5)}}, |
| {NL80211_IFTYPE_AP, WiFiPhy::Priority(1)}, |
| std::multiset<nl80211_iftype>{}}, |
| {{{NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(5)}}, |
| {NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(1)}, |
| std::multiset<nl80211_iftype>{}}, |
| |
| // 2 + 1 combinations. |
| {{{NL80211_IFTYPE_STATION, WiFiPhy::Priority(5)}, |
| {NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(5)}}, |
| {NL80211_IFTYPE_STATION, WiFiPhy::Priority(1)}, |
| std::multiset<nl80211_iftype>{}}, |
| {{{NL80211_IFTYPE_STATION, WiFiPhy::Priority(5)}, |
| {NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(5)}}, |
| {NL80211_IFTYPE_P2P_GO, WiFiPhy::Priority(1)}, |
| std::multiset<nl80211_iftype>{}}, |
| {{{NL80211_IFTYPE_STATION, WiFiPhy::Priority(5)}, |
| {NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(5)}}, |
| {NL80211_IFTYPE_AP, WiFiPhy::Priority(1)}, |
| std::multiset<nl80211_iftype>{}}, |
| {{{NL80211_IFTYPE_STATION, WiFiPhy::Priority(5)}, |
| {NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(5)}}, |
| {NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(1)}, |
| std::multiset<nl80211_iftype>{}}, |
| |
| {{{NL80211_IFTYPE_AP, WiFiPhy::Priority(5)}, |
| {NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(5)}}, |
| {NL80211_IFTYPE_STATION, WiFiPhy::Priority(1)}, |
| std::multiset<nl80211_iftype>{}}, |
| {{{NL80211_IFTYPE_AP, WiFiPhy::Priority(5)}, |
| {NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(5)}}, |
| {NL80211_IFTYPE_P2P_GO, WiFiPhy::Priority(1)}, |
| std::nullopt}, |
| {{{NL80211_IFTYPE_AP, WiFiPhy::Priority(5)}, |
| {NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(5)}}, |
| {NL80211_IFTYPE_AP, WiFiPhy::Priority(1)}, |
| std::nullopt}, |
| {{{NL80211_IFTYPE_AP, WiFiPhy::Priority(5)}, |
| {NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(5)}}, |
| {NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(1)}, |
| std::multiset<nl80211_iftype>{}}, |
| |
| {{{NL80211_IFTYPE_P2P_GO, WiFiPhy::Priority(5)}, |
| {NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(5)}}, |
| {NL80211_IFTYPE_STATION, WiFiPhy::Priority(1)}, |
| std::multiset<nl80211_iftype>{}}, |
| {{{NL80211_IFTYPE_P2P_GO, WiFiPhy::Priority(5)}, |
| {NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(5)}}, |
| {NL80211_IFTYPE_P2P_GO, WiFiPhy::Priority(1)}, |
| std::nullopt}, |
| {{{NL80211_IFTYPE_P2P_GO, WiFiPhy::Priority(5)}, |
| {NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(5)}}, |
| {NL80211_IFTYPE_AP, WiFiPhy::Priority(1)}, |
| std::nullopt}, |
| {{{NL80211_IFTYPE_P2P_GO, WiFiPhy::Priority(5)}, |
| {NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(5)}}, |
| {NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(1)}, |
| std::multiset<nl80211_iftype>{}}, |
| |
| {{{NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(5)}, |
| {NL80211_IFTYPE_AP, WiFiPhy::Priority(5)}}, |
| {NL80211_IFTYPE_STATION, WiFiPhy::Priority(1)}, |
| std::multiset<nl80211_iftype>{}}, |
| {{{NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(5)}, |
| {NL80211_IFTYPE_AP, WiFiPhy::Priority(5)}}, |
| {NL80211_IFTYPE_P2P_GO, WiFiPhy::Priority(1)}, |
| std::nullopt}, |
| {{{NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(5)}, |
| {NL80211_IFTYPE_AP, WiFiPhy::Priority(5)}}, |
| {NL80211_IFTYPE_AP, WiFiPhy::Priority(1)}, |
| std::nullopt}, |
| {{{NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(5)}, |
| {NL80211_IFTYPE_AP, WiFiPhy::Priority(5)}}, |
| {NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(1)}, |
| std::multiset<nl80211_iftype>{}}, |
| |
| {{{NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(5)}, |
| {NL80211_IFTYPE_P2P_GO, WiFiPhy::Priority(5)}}, |
| {NL80211_IFTYPE_STATION, WiFiPhy::Priority(1)}, |
| std::multiset<nl80211_iftype>{}}, |
| {{{NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(5)}, |
| {NL80211_IFTYPE_P2P_GO, WiFiPhy::Priority(5)}}, |
| {NL80211_IFTYPE_P2P_GO, WiFiPhy::Priority(1)}, |
| std::nullopt}, |
| {{{NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(5)}, |
| {NL80211_IFTYPE_P2P_GO, WiFiPhy::Priority(5)}}, |
| {NL80211_IFTYPE_AP, WiFiPhy::Priority(1)}, |
| std::nullopt}, |
| {{{NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(5)}, |
| {NL80211_IFTYPE_P2P_GO, WiFiPhy::Priority(5)}}, |
| {NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(1)}, |
| std::multiset<nl80211_iftype>{}}, |
| }; |
| |
| TestInterfaceCombinations(test_cases, combs); |
| } |
| |
| TEST_F(WiFiPhyTest, InterfaceCombinations_HighPriorityRequest) { |
| ConcurrencyCombinationSet combs = { |
| (struct ConcurrencyCombination){ |
| .limits = {(struct IfaceLimit){.iftypes = {NL80211_IFTYPE_STATION}, |
| .max = 2}, |
| (struct IfaceLimit){ |
| .iftypes = {NL80211_IFTYPE_P2P_CLIENT}, |
| .max = 2, |
| }, |
| (struct IfaceLimit){ |
| .iftypes = {NL80211_IFTYPE_AP, NL80211_IFTYPE_P2P_GO}, |
| .max = 1, |
| }, |
| (struct IfaceLimit){.iftypes = {NL80211_IFTYPE_P2P_DEVICE}, |
| .max = 1}}, |
| .max_num = 4, |
| .num_channels = 3}, |
| }; |
| |
| std::vector<ConcurrencyTestCase> test_cases = { |
| // 1 + 1 combinations. |
| |
| {{{NL80211_IFTYPE_STATION, WiFiPhy::Priority(1)}}, |
| {NL80211_IFTYPE_STATION, WiFiPhy::Priority(5)}, |
| std::multiset<nl80211_iftype>{}}, |
| {{{NL80211_IFTYPE_STATION, WiFiPhy::Priority(1)}}, |
| {NL80211_IFTYPE_P2P_GO, WiFiPhy::Priority(5)}, |
| std::multiset<nl80211_iftype>{}}, |
| {{{NL80211_IFTYPE_STATION, WiFiPhy::Priority(1)}}, |
| {NL80211_IFTYPE_AP, WiFiPhy::Priority(5)}, |
| std::multiset<nl80211_iftype>{}}, |
| {{{NL80211_IFTYPE_STATION, WiFiPhy::Priority(1)}}, |
| {NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(5)}, |
| std::multiset<nl80211_iftype>{}}, |
| |
| {{{NL80211_IFTYPE_AP, WiFiPhy::Priority(1)}}, |
| {NL80211_IFTYPE_STATION, WiFiPhy::Priority(5)}, |
| std::multiset<nl80211_iftype>{}}, |
| {{{NL80211_IFTYPE_AP, WiFiPhy::Priority(1)}}, |
| {NL80211_IFTYPE_P2P_GO, WiFiPhy::Priority(5)}, |
| std::multiset<nl80211_iftype>{NL80211_IFTYPE_AP}}, |
| {{{NL80211_IFTYPE_AP, WiFiPhy::Priority(1)}}, |
| {NL80211_IFTYPE_AP, WiFiPhy::Priority(5)}, |
| std::multiset<nl80211_iftype>{NL80211_IFTYPE_AP}}, |
| {{{NL80211_IFTYPE_AP, WiFiPhy::Priority(1)}}, |
| {NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(5)}, |
| std::multiset<nl80211_iftype>{}}, |
| |
| {{{NL80211_IFTYPE_P2P_GO, WiFiPhy::Priority(1)}}, |
| {NL80211_IFTYPE_STATION, WiFiPhy::Priority(5)}, |
| std::multiset<nl80211_iftype>{}}, |
| {{{NL80211_IFTYPE_P2P_GO, WiFiPhy::Priority(1)}}, |
| {NL80211_IFTYPE_P2P_GO, WiFiPhy::Priority(5)}, |
| std::multiset<nl80211_iftype>{NL80211_IFTYPE_P2P_GO}}, |
| {{{NL80211_IFTYPE_P2P_GO, WiFiPhy::Priority(1)}}, |
| {NL80211_IFTYPE_AP, WiFiPhy::Priority(5)}, |
| std::multiset<nl80211_iftype>{NL80211_IFTYPE_P2P_GO}}, |
| {{{NL80211_IFTYPE_P2P_GO, WiFiPhy::Priority(1)}}, |
| {NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(5)}, |
| std::multiset<nl80211_iftype>{}}, |
| |
| {{{NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(1)}}, |
| {NL80211_IFTYPE_STATION, WiFiPhy::Priority(5)}, |
| std::multiset<nl80211_iftype>{}}, |
| {{{NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(1)}}, |
| {NL80211_IFTYPE_P2P_GO, WiFiPhy::Priority(5)}, |
| std::multiset<nl80211_iftype>{}}, |
| {{{NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(1)}}, |
| {NL80211_IFTYPE_AP, WiFiPhy::Priority(5)}, |
| std::multiset<nl80211_iftype>{}}, |
| {{{NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(1)}}, |
| {NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(1)}, |
| std::multiset<nl80211_iftype>{}}, |
| |
| // 2 + 1 combinations. |
| {{{NL80211_IFTYPE_STATION, WiFiPhy::Priority(1)}, |
| {NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(1)}}, |
| {NL80211_IFTYPE_STATION, WiFiPhy::Priority(5)}, |
| std::multiset<nl80211_iftype>{}}, |
| {{{NL80211_IFTYPE_STATION, WiFiPhy::Priority(1)}, |
| {NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(1)}}, |
| {NL80211_IFTYPE_P2P_GO, WiFiPhy::Priority(5)}, |
| std::multiset<nl80211_iftype>{}}, |
| {{{NL80211_IFTYPE_STATION, WiFiPhy::Priority(1)}, |
| {NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(1)}}, |
| {NL80211_IFTYPE_AP, WiFiPhy::Priority(5)}, |
| std::multiset<nl80211_iftype>{}}, |
| {{{NL80211_IFTYPE_STATION, WiFiPhy::Priority(1)}, |
| {NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(1)}}, |
| {NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(5)}, |
| std::multiset<nl80211_iftype>{}}, |
| |
| {{{NL80211_IFTYPE_AP, WiFiPhy::Priority(1)}, |
| {NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(1)}}, |
| {NL80211_IFTYPE_STATION, WiFiPhy::Priority(5)}, |
| std::multiset<nl80211_iftype>{}}, |
| {{{NL80211_IFTYPE_AP, WiFiPhy::Priority(1)}, |
| {NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(1)}}, |
| {NL80211_IFTYPE_P2P_GO, WiFiPhy::Priority(5)}, |
| std::multiset<nl80211_iftype>{NL80211_IFTYPE_AP}}, |
| {{{NL80211_IFTYPE_AP, WiFiPhy::Priority(1)}, |
| {NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(1)}}, |
| {NL80211_IFTYPE_AP, WiFiPhy::Priority(5)}, |
| std::multiset<nl80211_iftype>{NL80211_IFTYPE_AP}}, |
| {{{NL80211_IFTYPE_AP, WiFiPhy::Priority(1)}, |
| {NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(1)}}, |
| {NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(5)}, |
| std::multiset<nl80211_iftype>{}}, |
| |
| {{{NL80211_IFTYPE_P2P_GO, WiFiPhy::Priority(1)}, |
| {NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(1)}}, |
| {NL80211_IFTYPE_STATION, WiFiPhy::Priority(5)}, |
| std::multiset<nl80211_iftype>{}}, |
| {{{NL80211_IFTYPE_P2P_GO, WiFiPhy::Priority(1)}, |
| {NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(1)}}, |
| {NL80211_IFTYPE_P2P_GO, WiFiPhy::Priority(5)}, |
| std::multiset<nl80211_iftype>{NL80211_IFTYPE_P2P_GO}}, |
| {{{NL80211_IFTYPE_P2P_GO, WiFiPhy::Priority(1)}, |
| {NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(1)}}, |
| {NL80211_IFTYPE_AP, WiFiPhy::Priority(5)}, |
| std::multiset<nl80211_iftype>{NL80211_IFTYPE_P2P_GO}}, |
| {{{NL80211_IFTYPE_P2P_GO, WiFiPhy::Priority(1)}, |
| {NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(1)}}, |
| {NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(5)}, |
| std::multiset<nl80211_iftype>{}}, |
| |
| {{{NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(1)}, |
| {NL80211_IFTYPE_AP, WiFiPhy::Priority(1)}}, |
| {NL80211_IFTYPE_STATION, WiFiPhy::Priority(5)}, |
| std::multiset<nl80211_iftype>{}}, |
| {{{NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(1)}, |
| {NL80211_IFTYPE_AP, WiFiPhy::Priority(1)}}, |
| {NL80211_IFTYPE_P2P_GO, WiFiPhy::Priority(5)}, |
| std::multiset<nl80211_iftype>{NL80211_IFTYPE_AP}}, |
| {{{NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(1)}, |
| {NL80211_IFTYPE_AP, WiFiPhy::Priority(1)}}, |
| {NL80211_IFTYPE_AP, WiFiPhy::Priority(5)}, |
| std::multiset<nl80211_iftype>{NL80211_IFTYPE_AP}}, |
| {{{NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(1)}, |
| {NL80211_IFTYPE_AP, WiFiPhy::Priority(1)}}, |
| {NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(5)}, |
| std::multiset<nl80211_iftype>{}}, |
| |
| {{{NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(1)}, |
| {NL80211_IFTYPE_P2P_GO, WiFiPhy::Priority(1)}}, |
| {NL80211_IFTYPE_STATION, WiFiPhy::Priority(5)}, |
| std::multiset<nl80211_iftype>{}}, |
| {{{NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(1)}, |
| {NL80211_IFTYPE_P2P_GO, WiFiPhy::Priority(1)}}, |
| {NL80211_IFTYPE_P2P_GO, WiFiPhy::Priority(5)}, |
| std::multiset<nl80211_iftype>{NL80211_IFTYPE_P2P_GO}}, |
| {{{NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(1)}, |
| {NL80211_IFTYPE_P2P_GO, WiFiPhy::Priority(1)}}, |
| {NL80211_IFTYPE_AP, WiFiPhy::Priority(5)}, |
| std::multiset<nl80211_iftype>{NL80211_IFTYPE_P2P_GO}}, |
| {{{NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(1)}, |
| {NL80211_IFTYPE_P2P_GO, WiFiPhy::Priority(1)}}, |
| {NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(5)}, |
| std::multiset<nl80211_iftype>{}}, |
| }; |
| |
| TestInterfaceCombinations(test_cases, combs); |
| } |
| |
| TEST_F(WiFiPhyTest, InterfaceCombinations_MultipleCombs) { |
| ConcurrencyCombinationSet combs = { |
| (struct ConcurrencyCombination){ |
| .limits = {(struct IfaceLimit){.iftypes = {NL80211_IFTYPE_STATION}, |
| .max = 1}, |
| (struct IfaceLimit){ |
| .iftypes = {NL80211_IFTYPE_AP, |
| NL80211_IFTYPE_P2P_CLIENT, |
| NL80211_IFTYPE_P2P_GO}, |
| .max = 2, |
| }, |
| (struct IfaceLimit){.iftypes = {NL80211_IFTYPE_P2P_DEVICE}, |
| .max = 1}}, |
| .max_num = 3, |
| .num_channels = 3}, |
| (struct ConcurrencyCombination){ |
| .limits = {(struct IfaceLimit){.iftypes = {NL80211_IFTYPE_STATION}, |
| .max = 2}, |
| (struct IfaceLimit){ |
| .iftypes = {NL80211_IFTYPE_P2P_CLIENT}, |
| .max = 2, |
| }, |
| (struct IfaceLimit){ |
| .iftypes = {NL80211_IFTYPE_AP, NL80211_IFTYPE_P2P_GO}, |
| .max = 1, |
| }, |
| (struct IfaceLimit){.iftypes = {NL80211_IFTYPE_P2P_DEVICE}, |
| .max = 1}}, |
| .max_num = 2, |
| .num_channels = 2}, |
| }; |
| |
| std::vector<ConcurrencyTestCase> test_cases = { |
| // Only possible using the first comb. |
| {{{NL80211_IFTYPE_AP, WiFiPhy::Priority(1)}, |
| {NL80211_IFTYPE_AP, WiFiPhy::Priority(1)}}, |
| {NL80211_IFTYPE_STATION, WiFiPhy::Priority(5)}, |
| std::multiset<nl80211_iftype>{}}, |
| {{{NL80211_IFTYPE_AP, WiFiPhy::Priority(5)}, |
| {NL80211_IFTYPE_AP, WiFiPhy::Priority(5)}}, |
| {NL80211_IFTYPE_STATION, WiFiPhy::Priority(1)}, |
| std::multiset<nl80211_iftype>{}}, |
| |
| // Only possible using the second comb. |
| {{{NL80211_IFTYPE_STATION, WiFiPhy::Priority(5)}}, |
| {NL80211_IFTYPE_STATION, WiFiPhy::Priority(1)}, |
| std::multiset<nl80211_iftype>{}}, |
| {{{NL80211_IFTYPE_STATION, WiFiPhy::Priority(1)}}, |
| {NL80211_IFTYPE_STATION, WiFiPhy::Priority(5)}, |
| std::multiset<nl80211_iftype>{}}, |
| |
| // The current configuration is only supported by the first comb, but the |
| // desired configuration is only supported by the second comb. |
| {{{NL80211_IFTYPE_AP, WiFiPhy::Priority(2)}, |
| {NL80211_IFTYPE_AP, WiFiPhy::Priority(2)}, |
| {NL80211_IFTYPE_STATION, WiFiPhy::Priority(5)}}, |
| {NL80211_IFTYPE_STATION, WiFiPhy::Priority(5)}, |
| std::multiset<nl80211_iftype>{NL80211_IFTYPE_AP, NL80211_IFTYPE_AP}}, |
| |
| // AP interface has higher priority, but we take it down because taking |
| // down the STA doesn't work. |
| {{{NL80211_IFTYPE_AP, WiFiPhy::Priority(2)}, |
| {NL80211_IFTYPE_AP, WiFiPhy::Priority(2)}, |
| {NL80211_IFTYPE_STATION, WiFiPhy::Priority(1)}}, |
| {NL80211_IFTYPE_P2P_CLIENT, WiFiPhy::Priority(5)}, |
| std::multiset<nl80211_iftype>{NL80211_IFTYPE_AP}}, |
| |
| // Take down 2 lower priority interfaces instead of 1 with higher |
| // priority. |
| {{{NL80211_IFTYPE_AP, WiFiPhy::Priority(2)}, |
| {NL80211_IFTYPE_AP, WiFiPhy::Priority(2)}, |
| {NL80211_IFTYPE_STATION, WiFiPhy::Priority(5)}}, |
| {NL80211_IFTYPE_STATION, WiFiPhy::Priority(5)}, |
| std::multiset<nl80211_iftype>{NL80211_IFTYPE_AP, NL80211_IFTYPE_AP}}, |
| |
| // Take down 1 interface instead of 2 with the same priority. |
| {{{NL80211_IFTYPE_AP, WiFiPhy::Priority(2)}, |
| {NL80211_IFTYPE_AP, WiFiPhy::Priority(2)}, |
| {NL80211_IFTYPE_STATION, WiFiPhy::Priority(2)}}, |
| {NL80211_IFTYPE_STATION, WiFiPhy::Priority(5)}, |
| std::multiset<nl80211_iftype>{NL80211_IFTYPE_STATION}}, |
| }; |
| |
| TestInterfaceCombinations(test_cases, combs); |
| } |
| |
| TEST_F(WiFiPhyTest, GetAllCandidates) { |
| WiFiPhy::ConcurrentIface a = {NL80211_IFTYPE_STATION, WiFiPhy::Priority(2)}; |
| WiFiPhy::ConcurrentIface b = {NL80211_IFTYPE_STATION, WiFiPhy::Priority(3)}; |
| WiFiPhy::ConcurrentIface c = {NL80211_IFTYPE_STATION, WiFiPhy::Priority(2)}; |
| WiFiPhy::ConcurrentIface d = {NL80211_IFTYPE_STATION, WiFiPhy::Priority(1)}; |
| |
| std::vector<WiFiPhy::ConcurrentIface> ifaces = {a, b, c, d}; |
| |
| WiFiPhy::RemovalCandidateSet candidates = GetAllCandidates(ifaces); |
| |
| std::vector<WiFiPhy::RemovalCandidate> expected_order; |
| expected_order.push_back({{}}); |
| expected_order.push_back({{d}}); |
| expected_order.push_back({{c}}); |
| expected_order.push_back({{a}}); |
| expected_order.push_back({{c}, {d}}); |
| expected_order.push_back({{a}, {d}}); |
| expected_order.push_back({{c}, {a}}); |
| expected_order.push_back({{c}, {a}, {d}}); |
| expected_order.push_back({{b}}); |
| expected_order.push_back({{d}, {b}}); |
| expected_order.push_back({{c}, {b}}); |
| expected_order.push_back({{a}, {b}}); |
| expected_order.push_back({{c}, {d}, {b}}); |
| expected_order.push_back({{a}, {d}, {b}}); |
| expected_order.push_back({{c}, {a}, {b}}); |
| expected_order.push_back({{c}, {a}, {d}, {b}}); |
| |
| AssertRemovalCandidateSetOrder(candidates, expected_order); |
| } |
| TEST_F(WiFiPhyTest, GetAllCandidates_empty) { |
| std::vector<WiFiPhy::ConcurrentIface> ifaces = {}; |
| WiFiPhy::RemovalCandidateSet candidates = GetAllCandidates(ifaces); |
| std::vector<WiFiPhy::RemovalCandidate> expected_order; |
| expected_order.push_back({{}}); |
| AssertRemovalCandidateSetOrder(candidates, expected_order); |
| } |
| |
| } // namespace shill |