blob: ebc38a7ce3edfaad7a799416f7b7f3bdddee51be [file] [log] [blame]
Peter Qiufb39ba42014-11-21 09:09:59 -08001// Copyright 2014 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "apmanager/device.h"
6
7#include <string>
8#include <vector>
9
Peter Qiu8e785b92014-11-24 10:01:08 -080010#include <base/strings/stringprintf.h>
Peter Qiufb39ba42014-11-21 09:09:59 -080011#include <gmock/gmock.h>
12#include <gtest/gtest.h>
Peter Qiu8e785b92014-11-24 10:01:08 -080013#include <shill/net/ieee80211.h>
14#include <shill/net/nl80211_attribute.h>
15#include <shill/net/nl80211_message.h>
Peter Qiufb39ba42014-11-21 09:09:59 -080016
Peter Qiu7e0ffcf2014-12-02 12:53:27 -080017#include "apmanager/mock_manager.h"
18
19using ::testing::_;
20using ::testing::Mock;
Peter Qiufb39ba42014-11-21 09:09:59 -080021using std::vector;
22
23namespace apmanager {
24
25namespace {
26
27const char kDeviceName[] = "phy0";
28const Device::WiFiInterface kApModeInterface0 = {
29 "uap0", kDeviceName, 1, NL80211_IFTYPE_AP
30};
31const Device::WiFiInterface kApModeInterface1 = {
32 "uap1", kDeviceName, 2, NL80211_IFTYPE_AP
33};
34const Device::WiFiInterface kManagedModeInterface0 = {
35 "wlan0", kDeviceName, 3, NL80211_IFTYPE_STATION
36};
37const Device::WiFiInterface kManagedModeInterface1 = {
38 "wlan1", kDeviceName, 4, NL80211_IFTYPE_STATION
39};
40const Device::WiFiInterface kMonitorModeInterface = {
41 "monitor0", kDeviceName, 5, NL80211_IFTYPE_MONITOR
42};
43
44} // namespace
45
46class DeviceTest : public testing::Test {
47 public:
Peter Qiu7e0ffcf2014-12-02 12:53:27 -080048 DeviceTest() : device_(new Device(&manager_, kDeviceName)) {}
Peter Qiufb39ba42014-11-21 09:09:59 -080049
50 void VerifyInterfaceList(
51 const vector<Device::WiFiInterface>& interface_list) {
52 EXPECT_EQ(interface_list.size(), device_->interface_list_.size());
53 for (size_t i = 0; i < interface_list.size(); i++) {
54 EXPECT_TRUE(interface_list[i].Equals(device_->interface_list_[i]));
55 }
56 }
57
58 void VerifyPreferredApInterface(const std::string& interface_name) {
59 EXPECT_EQ(interface_name, device_->GetPreferredApInterface());
60 }
61
Peter Qiu8e785b92014-11-24 10:01:08 -080062 void AddWiphyBandAttribute(shill::AttributeListRefPtr wiphy_bands,
63 const std::string& band_name,
64 int band_id,
65 std::vector<uint32_t> frequency_list,
66 uint16_t ht_cap_mask) {
67 // Band attribute.
68 shill::AttributeListRefPtr wiphy_band;
69 wiphy_bands->CreateNestedAttribute(band_id, band_name.c_str());
70 wiphy_bands->GetNestedAttributeList(band_id, &wiphy_band);
71 // Frequencies attribute.
72 shill::AttributeListRefPtr frequencies;
73 wiphy_band->CreateNestedAttribute(NL80211_BAND_ATTR_FREQS,
74 "NL80211_BAND_ATTR_FREQS");
75 wiphy_band->GetNestedAttributeList(NL80211_BAND_ATTR_FREQS,
76 &frequencies);
77 // Frequency attribute.
78 for (size_t i = 0; i < frequency_list.size(); i++) {
79 shill::AttributeListRefPtr frequency;
80 frequencies->CreateNestedAttribute(
81 i, base::StringPrintf("Frequency %d", frequency_list[i]).c_str());
82 frequencies->GetNestedAttributeList(i, &frequency);
83 frequency->CreateU32Attribute(NL80211_FREQUENCY_ATTR_FREQ,
84 "NL80211_FREQUENCY_ATTR_FREQ");
85 frequency->SetU32AttributeValue(NL80211_FREQUENCY_ATTR_FREQ,
86 frequency_list[i]);
87 frequencies->SetNestedAttributeHasAValue(i);
88 }
89 wiphy_band->SetNestedAttributeHasAValue(NL80211_BAND_ATTR_FREQS);
90
91 // HT Capability attribute.
92 wiphy_band->CreateU16Attribute(NL80211_BAND_ATTR_HT_CAPA,
93 "NL80211_BAND_ATTR_HT_CAPA");
94 wiphy_band->SetU16AttributeValue(NL80211_BAND_ATTR_HT_CAPA, ht_cap_mask);
95
96 wiphy_bands->SetNestedAttributeHasAValue(band_id);
97 }
98
99 void VerifyFrequencyList(int band_id, std::vector<uint32_t> frequency_list) {
100 EXPECT_EQ(frequency_list, device_->band_capability_[band_id].frequencies);
101 }
102
Peter Qiufb39ba42014-11-21 09:09:59 -0800103 protected:
Peter Qiu7e0ffcf2014-12-02 12:53:27 -0800104 MockManager manager_;
Peter Qiufb39ba42014-11-21 09:09:59 -0800105 scoped_refptr<Device> device_;
106};
107
108TEST_F(DeviceTest, RegisterInterface) {
109 vector<Device::WiFiInterface> interface_list;
110 interface_list.push_back(kApModeInterface0);
111 interface_list.push_back(kManagedModeInterface0);
112 interface_list.push_back(kMonitorModeInterface);
113
114 device_->RegisterInterface(kApModeInterface0);
115 device_->RegisterInterface(kManagedModeInterface0);
116 device_->RegisterInterface(kMonitorModeInterface);
117
118 // Verify result interface list.
119 VerifyInterfaceList(interface_list);
120}
121
122TEST_F(DeviceTest, DeregisterInterface) {
123 vector<Device::WiFiInterface> interface_list;
124 interface_list.push_back(kApModeInterface0);
125 interface_list.push_back(kManagedModeInterface0);
126
127 // Register all interfaces, then deregister monitor0 and wlan1 interfaces.
128 device_->RegisterInterface(kApModeInterface0);
129 device_->RegisterInterface(kMonitorModeInterface);
130 device_->RegisterInterface(kManagedModeInterface0);
131 device_->RegisterInterface(kManagedModeInterface1);
132 device_->DeregisterInterface(kMonitorModeInterface);
133 device_->DeregisterInterface(kManagedModeInterface1);
134
135 // Verify result interface list.
136 VerifyInterfaceList(interface_list);
137}
138
139TEST_F(DeviceTest, PreferredAPInterface) {
140 // Register a monitor mode interface, no preferred AP mode interface.
141 device_->RegisterInterface(kMonitorModeInterface);
142 VerifyPreferredApInterface("");
143
144 // Register a managed mode interface, should be set to preferred AP interface.
145 device_->RegisterInterface(kManagedModeInterface0);
146 VerifyPreferredApInterface(kManagedModeInterface0.iface_name);
147
148 // Register a ap mode interface, should be set to preferred AP interface.
149 device_->RegisterInterface(kApModeInterface0);
150 VerifyPreferredApInterface(kApModeInterface0.iface_name);
151
152 // Register another ap mode interface "uap1" and managed mode interface
153 // "wlan1", preferred AP interface should still be set to the first detected
154 // ap mode interface "uap0".
155 device_->RegisterInterface(kApModeInterface1);
156 device_->RegisterInterface(kManagedModeInterface1);
157 VerifyPreferredApInterface(kApModeInterface0.iface_name);
158
159 // Deregister the first ap mode interface, preferred AP interface should be
160 // set to the second ap mode interface.
161 device_->DeregisterInterface(kApModeInterface0);
162 VerifyPreferredApInterface(kApModeInterface1.iface_name);
163
164 // Deregister the second ap mode interface, preferred AP interface should be
165 // set the first managed mode interface.
166 device_->DeregisterInterface(kApModeInterface1);
167 VerifyPreferredApInterface(kManagedModeInterface0.iface_name);
168
169 // Deregister the first managed mode interface, preferred AP interface
170 // should be set to the second managed mode interface.
171 device_->DeregisterInterface(kManagedModeInterface0);
172 VerifyPreferredApInterface(kManagedModeInterface1.iface_name);
173
174 // Deregister the second managed mode interface, preferred AP interface
175 // should be set to empty string.
176 device_->DeregisterInterface(kManagedModeInterface1);
177 VerifyPreferredApInterface("");
178}
179
Peter Qiu8e785b92014-11-24 10:01:08 -0800180TEST_F(DeviceTest, ParseHTCapability) {
181 shill::NewWiphyMessage message;
182 message.attributes()->CreateNestedAttribute(
183 NL80211_ATTR_WIPHY_BANDS, "NL80211_ATTR_WIPHY_BANDS");
184 shill::AttributeListRefPtr wiphy_bands;
185 message.attributes()->GetNestedAttributeList(
186 NL80211_ATTR_WIPHY_BANDS, &wiphy_bands);
187
188 // 2.4GHz band capability.
189 const uint32_t kBand24GHzFrequencies[] = {
190 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462, 2467};
191 const uint16_t kBand24GHzHTCapMask = shill::IEEE_80211::kHTCapMaskLdpcCoding |
192 shill::IEEE_80211::kHTCapMaskGrnFld |
193 shill::IEEE_80211::kHTCapMaskSgi20;
194 std::vector<uint32_t> band_24ghz_freq_list(
195 kBand24GHzFrequencies,
196 kBand24GHzFrequencies + sizeof(kBand24GHzFrequencies) /
197 sizeof(kBand24GHzFrequencies[0]));
198 AddWiphyBandAttribute(
199 wiphy_bands, "2.4GHz band", 0, band_24ghz_freq_list,
200 kBand24GHzHTCapMask);
201
202 // 5GHz band capability.
203 const uint32_t kBand5GHzFrequencies[] = {
204 5180, 5190, 5200, 5210, 5220, 5230, 5240, 5260, 5280, 5300, 5320};
205 const uint16_t kBand5GHzHTCapMask =
206 shill::IEEE_80211::kHTCapMaskLdpcCoding |
207 shill::IEEE_80211::kHTCapMaskSupWidth2040 |
208 shill::IEEE_80211::kHTCapMaskGrnFld |
209 shill::IEEE_80211::kHTCapMaskSgi20 |
210 shill::IEEE_80211::kHTCapMaskSgi40;
211 std::vector<uint32_t> band_5ghz_freq_list(
212 kBand5GHzFrequencies,
213 kBand5GHzFrequencies + sizeof(kBand5GHzFrequencies) /
214 sizeof(kBand5GHzFrequencies[0]));
215 AddWiphyBandAttribute(
216 wiphy_bands, "5GHz band", 1, band_5ghz_freq_list, kBand5GHzHTCapMask);
217
218 message.attributes()->SetNestedAttributeHasAValue(NL80211_ATTR_WIPHY_BANDS);
219
220 device_->ParseWiphyCapability(message);
221
222 // Verify frequency list for both bands.
223 VerifyFrequencyList(0, band_24ghz_freq_list);
224 VerifyFrequencyList(1, band_5ghz_freq_list);
225
226 // Verify HT Capablity for 2.4GHz band.
227 const char kBand24GHzHTCapability[] = "[LDPC SMPS-STATIC GF SHORT-GI-20]";
228 std::string band_24ghz_cap;
229 EXPECT_TRUE(device_->GetHTCapability(6, &band_24ghz_cap));
230 EXPECT_EQ(kBand24GHzHTCapability, band_24ghz_cap);
231
232 // Verify HT Capablity for 5GHz band.
233 const char kBand5GHzHTCapability[] =
234 "[LDPC HT40+ SMPS-STATIC GF SHORT-GI-20 SHORT-GI-40]";
235 std::string band_5ghz_cap;
236 EXPECT_TRUE(device_->GetHTCapability(36, &band_5ghz_cap));
237 EXPECT_EQ(kBand5GHzHTCapability, band_5ghz_cap);
238}
239
Peter Qiu7e0ffcf2014-12-02 12:53:27 -0800240TEST_F(DeviceTest, ClaimAndReleaseDevice) {
241 // Register multiple interfaces.
242 device_->RegisterInterface(kApModeInterface1);
243 device_->RegisterInterface(kManagedModeInterface1);
244
245 // Claim the device should claim all interfaces registered on this device.
246 EXPECT_CALL(manager_, ClaimInterface(kApModeInterface1.iface_name)).Times(1);
247 EXPECT_CALL(manager_,
248 ClaimInterface(kManagedModeInterface1.iface_name)).Times(1);
249 EXPECT_TRUE(device_->ClaimDevice());
250 Mock::VerifyAndClearExpectations(&manager_);
251
252 // Claim the device when it is already claimed.
253 EXPECT_CALL(manager_, ClaimInterface(_)).Times(0);
254 EXPECT_FALSE(device_->ClaimDevice());
255 Mock::VerifyAndClearExpectations(&manager_);
256
257 // Release the device should release all interfaces registered on this device.
258 EXPECT_CALL(manager_,
259 ReleaseInterface(kApModeInterface1.iface_name)).Times(1);
260 EXPECT_CALL(manager_,
261 ReleaseInterface(kManagedModeInterface1.iface_name)).Times(1);
262 EXPECT_TRUE(device_->ReleaseDevice());
263 Mock::VerifyAndClearExpectations(&manager_);
264
265 // Release the device when it is not claimed.
266 EXPECT_CALL(manager_, ReleaseInterface(_)).Times(0);
267 EXPECT_FALSE(device_->ReleaseDevice());
268 Mock::VerifyAndClearExpectations(&manager_);
269}
270
Peter Qiufb39ba42014-11-21 09:09:59 -0800271} // namespace apmanager