1 // 2 // Copyright (C) 2013 The Android Open Source Project 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 // 16 17 #include "shill/wifi/scan_session.h" 18 19 #include <errno.h> 20 21 #include <limits> 22 #include <memory> 23 #include <set> 24 #include <vector> 25 26 #include <base/memory/weak_ptr.h> 27 #include <gmock/gmock.h> 28 #include <gtest/gtest.h> 29 30 #include "shill/mock_event_dispatcher.h" 31 #include "shill/net/mock_netlink_manager.h" 32 #include "shill/net/netlink_manager.h" 33 #include "shill/net/netlink_message_matchers.h" 34 #include "shill/net/nl80211_message.h" 35 36 using std::set; 37 using std::vector; 38 using testing::_; 39 using testing::ContainerEq; 40 using testing::Test; 41 42 namespace shill { 43 44 static const uint16_t kExpectedFreq5640 = 5640; 45 static const uint16_t kExpectedFreq5600 = 5600; 46 static const uint16_t kExpectedFreq5580 = 5580; 47 static const uint16_t kExpectedFreq5560 = 5560; 48 static const uint16_t kExpectedFreq5620 = 5620; 49 50 static WiFiProvider::FrequencyCount kConnectedFrequencies[] = { 51 WiFiProvider::FrequencyCount(kExpectedFreq5640, 40), // 40th percentile. 52 WiFiProvider::FrequencyCount(kExpectedFreq5600, 25), // 65th percentile. 53 WiFiProvider::FrequencyCount(kExpectedFreq5580, 20), // 85th percentile. 54 WiFiProvider::FrequencyCount(kExpectedFreq5560, 10), // 95th percentile. 55 WiFiProvider::FrequencyCount(kExpectedFreq5620, 5) // 100th percentile. 56 }; 57 58 static const uint16_t kExpectedFreq2432 = 2432; 59 static const uint16_t kExpectedFreq2427 = 2427; 60 static const uint16_t kExpectedFreq2422 = 2422; 61 static const uint16_t kExpectedFreq2417 = 2417; 62 static const uint16_t kExpectedFreq2412 = 2412; 63 64 static uint16_t kUnconnectedFrequencies[] = { 65 kExpectedFreq2432, 66 kExpectedFreq2427, 67 kExpectedFreq2422, 68 kExpectedFreq2417, 69 kExpectedFreq2412 70 }; 71 72 static const uint16_t kNl80211FamilyId = 0x13; 73 74 class ScanSessionTest : public Test { 75 public: 76 // Test set of "all the other frequencies this device can support" in 77 // sorted order. 78 ScanSessionTest() : weak_ptr_factory_(this) { 79 WiFiProvider::FrequencyCountList default_connected_frequencies( 80 kConnectedFrequencies, 81 kConnectedFrequencies + arraysize(kConnectedFrequencies)); 82 83 set<uint16_t> default_unconnected_frequencies( 84 kUnconnectedFrequencies, 85 kUnconnectedFrequencies + arraysize(kUnconnectedFrequencies)); 86 87 BuildScanSession(default_connected_frequencies, 88 default_unconnected_frequencies); 89 } 90 91 void BuildScanSession(const WiFiProvider::FrequencyCountList 92 &connected_frequencies, 93 const std::set<uint16_t>& unconnected_frequencies) { 94 const int kArbitraryMinimum = 1; 95 const int kArbitraryMaximum = std::numeric_limits<int>::max(); 96 scan_session_.reset(new ScanSession(&netlink_manager_, 97 &dispatcher_, 98 connected_frequencies, 99 unconnected_frequencies, 100 0, 101 ScanSession::FractionList(), 102 kArbitraryMinimum, 103 kArbitraryMaximum, 104 Bind(&ScanSessionTest::OnScanError, 105 weak_ptr_factory_.GetWeakPtr()), 106 nullptr)); 107 } 108 109 virtual std::vector<uint16_t> GetScanFrequencies(float scan_fraction, 110 size_t min_frequencies, 111 size_t max_frequencies) { 112 return scan_session_->GetScanFrequencies(scan_fraction, min_frequencies, 113 max_frequencies); 114 } 115 ScanSession* scan_session() { return scan_session_.get(); } 116 117 void SetScanSize(size_t min_frequencies, size_t max_frequencies) { 118 scan_session_->min_frequencies_ = min_frequencies; 119 scan_session_->max_frequencies_ = max_frequencies; 120 } 121 122 size_t GetScanFrequencyCount() { 123 return arraysize(kConnectedFrequencies) + 124 arraysize(kUnconnectedFrequencies); 125 } 126 127 protected: 128 MOCK_METHOD0(OnScanError, void()); 129 MockNetlinkManager* netlink_manager() { return &netlink_manager_; } 130 MockEventDispatcher* dispatcher() { return &dispatcher_; } 131 132 MockEventDispatcher dispatcher_; 133 MockNetlinkManager netlink_manager_; 134 std::unique_ptr<ScanSession> scan_session_; 135 base::WeakPtrFactory<ScanSessionTest> weak_ptr_factory_; 136 }; 137 138 // Test that we can get a bunch of frequencies up to a specified fraction. 139 TEST_F(ScanSessionTest, Fraction) { 140 vector<uint16_t> result; 141 142 // Get the first 83% of the connected values. 143 { 144 vector<uint16_t> expected{kExpectedFreq5640, kExpectedFreq5600, 145 kExpectedFreq5580}; 146 result = GetScanFrequencies(.83, 1, std::numeric_limits<size_t>::max()); 147 EXPECT_THAT(result, ContainerEq(expected)); 148 EXPECT_TRUE(scan_session()->HasMoreFrequencies()); 149 } 150 151 // Get the next 4 values. 152 { 153 vector<uint16_t> expected{kExpectedFreq5560, kExpectedFreq5620, 154 kExpectedFreq2412, kExpectedFreq2417}; 155 result = GetScanFrequencies(ScanSession::kAllFrequencies, 1, 4); 156 EXPECT_THAT(result, ContainerEq(expected)); 157 EXPECT_TRUE(scan_session()->HasMoreFrequencies()); 158 } 159 160 // And, get the remaining list. 161 { 162 vector<uint16_t> expected{kExpectedFreq2422, kExpectedFreq2427, 163 kExpectedFreq2432}; 164 result = GetScanFrequencies(ScanSession::kAllFrequencies, 20, 165 std::numeric_limits<size_t>::max()); 166 EXPECT_THAT(result, ContainerEq(expected)); 167 EXPECT_FALSE(scan_session()->HasMoreFrequencies()); 168 } 169 } 170 171 // Test that we can get a bunch of frequencies up to a specified fraction, 172 // followed by another group up to a specified fraction. 173 TEST_F(ScanSessionTest, TwoFractions) { 174 vector<uint16_t> result; 175 176 // Get the first 60% of the connected values. 177 { 178 vector<uint16_t> expected{kExpectedFreq5640, kExpectedFreq5600}; 179 result = GetScanFrequencies(.60, 0, std::numeric_limits<size_t>::max()); 180 EXPECT_THAT(result, ContainerEq(expected)); 181 EXPECT_TRUE(scan_session()->HasMoreFrequencies()); 182 } 183 184 // Get the next 32% of the connected values. 185 { 186 vector<uint16_t> expected{kExpectedFreq5580, kExpectedFreq5560}; 187 result = GetScanFrequencies(.32, 0, std::numeric_limits<size_t>::max()); 188 EXPECT_THAT(result, ContainerEq(expected)); 189 EXPECT_TRUE(scan_session()->HasMoreFrequencies()); 190 } 191 192 // And, get the remaining list. 193 { 194 vector<uint16_t> expected{kExpectedFreq5620, kExpectedFreq2412, 195 kExpectedFreq2417, kExpectedFreq2422, kExpectedFreq2427, 196 kExpectedFreq2432}; 197 result = GetScanFrequencies(ScanSession::kAllFrequencies, 198 std::numeric_limits<size_t>::max(), 199 std::numeric_limits<size_t>::max()); 200 EXPECT_THAT(result, ContainerEq(expected)); 201 EXPECT_FALSE(scan_session()->HasMoreFrequencies()); 202 } 203 } 204 205 // Test that we can get a bunch of frequencies up to a minimum count, even 206 // when the requested fraction has already been reached. 207 TEST_F(ScanSessionTest, Min) { 208 vector<uint16_t> result; 209 210 // Get the first 3 previously seen values. 211 { 212 vector<uint16_t> expected{kExpectedFreq5640, kExpectedFreq5600, 213 kExpectedFreq5580}; 214 result = GetScanFrequencies(.30, 3, std::numeric_limits<size_t>::max()); 215 EXPECT_THAT(result, ContainerEq(expected)); 216 EXPECT_TRUE(scan_session()->HasMoreFrequencies()); 217 } 218 219 // Get the next value by requesting a minimum of 1. 220 { 221 vector<uint16_t> expected{kExpectedFreq5560}; 222 result = GetScanFrequencies(0.0, 1, std::numeric_limits<size_t>::max()); 223 EXPECT_THAT(result, ContainerEq(expected)); 224 EXPECT_TRUE(scan_session()->HasMoreFrequencies()); 225 } 226 227 // And, get the remaining list. 228 { 229 vector<uint16_t> expected{kExpectedFreq5620, kExpectedFreq2412, 230 kExpectedFreq2417, kExpectedFreq2422, kExpectedFreq2427, 231 kExpectedFreq2432}; 232 result = GetScanFrequencies(ScanSession::kAllFrequencies, 233 std::numeric_limits<size_t>::max(), 234 std::numeric_limits<size_t>::max()); 235 EXPECT_THAT(result, ContainerEq(expected)); 236 EXPECT_FALSE(scan_session()->HasMoreFrequencies()); 237 } 238 } 239 240 // Test that we can get up to a specified maximum number of frequencies. 241 TEST_F(ScanSessionTest, Max) { 242 vector<uint16_t> result; 243 244 // Get the first 7 values (crosses seen/unseen boundary). 245 { 246 vector<uint16_t> expected{kExpectedFreq5640, kExpectedFreq5600, 247 kExpectedFreq5580, kExpectedFreq5560, kExpectedFreq5620, 248 kExpectedFreq2412, kExpectedFreq2417}; 249 result = GetScanFrequencies(ScanSession::kAllFrequencies, 1, 7); 250 EXPECT_THAT(result, ContainerEq(expected)); 251 EXPECT_TRUE(scan_session()->HasMoreFrequencies()); 252 } 253 254 // And, get the remaining list. 255 { 256 vector<uint16_t> expected{kExpectedFreq2422, kExpectedFreq2427, 257 kExpectedFreq2432}; 258 result = GetScanFrequencies(ScanSession::kAllFrequencies, 20, 259 std::numeric_limits<size_t>::max()); 260 EXPECT_THAT(result, ContainerEq(expected)); 261 EXPECT_FALSE(scan_session()->HasMoreFrequencies()); 262 } 263 } 264 265 // Test that we can get exactly the seen frequencies and exactly the unseen 266 // ones. 267 TEST_F(ScanSessionTest, Exact) { 268 vector<uint16_t> result; 269 270 // Get the first 5 values -- exactly on the seen/unseen border. 271 { 272 vector<uint16_t> expected{kExpectedFreq5640, kExpectedFreq5600, 273 kExpectedFreq5580, kExpectedFreq5560, kExpectedFreq5620}; 274 result = GetScanFrequencies(ScanSession::kAllFrequencies, 5, 5); 275 EXPECT_THAT(result, ContainerEq(expected)); 276 EXPECT_TRUE(scan_session()->HasMoreFrequencies()); 277 } 278 279 // And, get the last 5. 280 { 281 vector<uint16_t> expected{kExpectedFreq2412, kExpectedFreq2417, 282 kExpectedFreq2422, kExpectedFreq2427, kExpectedFreq2432}; 283 result = GetScanFrequencies(ScanSession::kAllFrequencies, 5, 5); 284 EXPECT_THAT(result, ContainerEq(expected)); 285 EXPECT_FALSE(scan_session()->HasMoreFrequencies()); 286 } 287 } 288 289 // Test that we can get everything in one read. 290 TEST_F(ScanSessionTest, AllOneRead) { 291 vector<uint16_t> expected{kExpectedFreq5640, kExpectedFreq5600, 292 kExpectedFreq5580, kExpectedFreq5560, kExpectedFreq5620, 293 kExpectedFreq2412, kExpectedFreq2417, kExpectedFreq2422, 294 kExpectedFreq2427, kExpectedFreq2432}; 295 vector<uint16_t> result; 296 result = GetScanFrequencies(ScanSession::kAllFrequencies, 297 std::numeric_limits<size_t>::max(), 298 std::numeric_limits<size_t>::max()); 299 EXPECT_THAT(result, ContainerEq(expected)); 300 EXPECT_FALSE(scan_session()->HasMoreFrequencies()); 301 } 302 303 // Test that we can get all the previously seen frequencies (and only the 304 // previously seen frequencies) via the requested fraction. 305 TEST_F(ScanSessionTest, EverythingConnected) { 306 vector<uint16_t> result; 307 308 // Get the first 100% of the connected values. 309 { 310 vector<uint16_t> expected{kExpectedFreq5640, kExpectedFreq5600, 311 kExpectedFreq5580, kExpectedFreq5560, kExpectedFreq5620}; 312 result = GetScanFrequencies(1.0, 0, std::numeric_limits<size_t>::max()); 313 EXPECT_THAT(result, ContainerEq(expected)); 314 EXPECT_TRUE(scan_session()->HasMoreFrequencies()); 315 } 316 317 // And, get the remaining list. 318 { 319 vector<uint16_t> expected{kExpectedFreq2412, kExpectedFreq2417, 320 kExpectedFreq2422, kExpectedFreq2427, kExpectedFreq2432}; 321 result = GetScanFrequencies(ScanSession::kAllFrequencies, 322 std::numeric_limits<size_t>::max(), 323 std::numeric_limits<size_t>::max()); 324 EXPECT_THAT(result, ContainerEq(expected)); 325 EXPECT_FALSE(scan_session()->HasMoreFrequencies()); 326 } 327 } 328 329 TEST_F(ScanSessionTest, OnlyPreviouslySeen) { 330 // Build a scan session with only previously connected frequencies. 331 WiFiProvider::FrequencyCountList default_connected_frequencies( 332 kConnectedFrequencies, 333 kConnectedFrequencies + arraysize(kConnectedFrequencies)); 334 BuildScanSession(default_connected_frequencies, std::set<uint16_t>()); 335 336 // Get the first 100% of the connected values. 337 vector<uint16_t> expected{kExpectedFreq5640, kExpectedFreq5600, 338 kExpectedFreq5580, kExpectedFreq5560, kExpectedFreq5620}; 339 340 vector<uint16_t> result; 341 result = GetScanFrequencies(ScanSession::kAllFrequencies, 1, 342 std::numeric_limits<size_t>::max()); 343 EXPECT_THAT(result, ContainerEq(expected)); 344 EXPECT_FALSE(scan_session()->HasMoreFrequencies()); 345 result = GetScanFrequencies(ScanSession::kAllFrequencies, 346 std::numeric_limits<size_t>::max(), 347 std::numeric_limits<size_t>::max()); 348 EXPECT_TRUE(result.empty()); 349 } 350 351 // Verify that max works inside the list of connected frequencies. 352 TEST_F(ScanSessionTest, MaxAppliesToConnected) { 353 vector<uint16_t> result; 354 355 { 356 vector<uint16_t> expected{kExpectedFreq5640, kExpectedFreq5600, 357 kExpectedFreq5580}; 358 359 result = GetScanFrequencies(ScanSession::kAllFrequencies, 1, 3); 360 EXPECT_THAT(result, ContainerEq(expected)); 361 EXPECT_TRUE(scan_session()->HasMoreFrequencies()); 362 } 363 364 { 365 vector<uint16_t> expected{kExpectedFreq5560, kExpectedFreq5620, 366 kExpectedFreq2412}; 367 368 result = GetScanFrequencies(ScanSession::kAllFrequencies, 1, 3); 369 EXPECT_THAT(result, ContainerEq(expected)); 370 EXPECT_TRUE(scan_session()->HasMoreFrequencies()); 371 } 372 373 { 374 vector<uint16_t> expected{kExpectedFreq2417, kExpectedFreq2422, 375 kExpectedFreq2427}; 376 377 result = GetScanFrequencies(ScanSession::kAllFrequencies, 1, 3); 378 EXPECT_THAT(result, ContainerEq(expected)); 379 EXPECT_TRUE(scan_session()->HasMoreFrequencies()); 380 } 381 382 { 383 vector<uint16_t> expected{kExpectedFreq2432}; 384 385 result = GetScanFrequencies(ScanSession::kAllFrequencies, 1, 3); 386 EXPECT_THAT(result, ContainerEq(expected)); 387 EXPECT_FALSE(scan_session()->HasMoreFrequencies()); 388 } 389 } 390 391 // Test that we can get each value individually. 392 TEST_F(ScanSessionTest, IndividualReads) { 393 vector<uint16_t> result; 394 static const float kArbitraryFraction = 0.83; 395 396 { 397 vector<uint16_t> expected{kExpectedFreq5640}; 398 result = GetScanFrequencies(kArbitraryFraction, 1, 1); 399 EXPECT_THAT(result, ContainerEq(expected)); 400 EXPECT_TRUE(scan_session()->HasMoreFrequencies()); 401 } 402 { 403 vector<uint16_t> expected{kExpectedFreq5600}; 404 result = GetScanFrequencies(kArbitraryFraction, 1, 1); 405 EXPECT_THAT(result, ContainerEq(expected)); 406 EXPECT_TRUE(scan_session()->HasMoreFrequencies()); 407 } 408 { 409 vector<uint16_t> expected{kExpectedFreq5580}; 410 result = GetScanFrequencies(kArbitraryFraction, 1, 1); 411 EXPECT_THAT(result, ContainerEq(expected)); 412 EXPECT_TRUE(scan_session()->HasMoreFrequencies()); 413 } 414 { 415 vector<uint16_t> expected{kExpectedFreq5560}; 416 result = GetScanFrequencies(kArbitraryFraction, 1, 1); 417 EXPECT_THAT(result, ContainerEq(expected)); 418 EXPECT_TRUE(scan_session()->HasMoreFrequencies()); 419 } 420 { 421 vector<uint16_t> expected{kExpectedFreq5620}; 422 result = GetScanFrequencies(kArbitraryFraction, 1, 1); 423 EXPECT_THAT(result, ContainerEq(expected)); 424 EXPECT_TRUE(scan_session()->HasMoreFrequencies()); 425 } 426 { 427 vector<uint16_t> expected{kExpectedFreq2412}; 428 result = GetScanFrequencies(kArbitraryFraction, 1, 1); 429 EXPECT_THAT(result, ContainerEq(expected)); 430 EXPECT_TRUE(scan_session()->HasMoreFrequencies()); 431 } 432 { 433 vector<uint16_t> expected{kExpectedFreq2417}; 434 result = GetScanFrequencies(kArbitraryFraction, 1, 1); 435 EXPECT_THAT(result, ContainerEq(expected)); 436 EXPECT_TRUE(scan_session()->HasMoreFrequencies()); 437 } 438 { 439 vector<uint16_t> expected{kExpectedFreq2422}; 440 result = GetScanFrequencies(kArbitraryFraction, 1, 1); 441 EXPECT_THAT(result, ContainerEq(expected)); 442 EXPECT_TRUE(scan_session()->HasMoreFrequencies()); 443 } 444 { 445 vector<uint16_t> expected{kExpectedFreq2427}; 446 result = GetScanFrequencies(kArbitraryFraction, 1, 1); 447 EXPECT_THAT(result, ContainerEq(expected)); 448 EXPECT_TRUE(scan_session()->HasMoreFrequencies()); 449 } 450 { 451 vector<uint16_t> expected{kExpectedFreq2432}; 452 result = GetScanFrequencies(kArbitraryFraction, 1, 1); 453 EXPECT_THAT(result, ContainerEq(expected)); 454 EXPECT_FALSE(scan_session()->HasMoreFrequencies()); 455 } 456 } 457 458 TEST_F(ScanSessionTest, OnTriggerScanResponse) { 459 Nl80211Message::SetMessageType(kNl80211FamilyId); 460 461 EXPECT_CALL(*netlink_manager(), SendNl80211Message( 462 IsNl80211Command(kNl80211FamilyId, NL80211_CMD_TRIGGER_SCAN), _, _, _)); 463 scan_session()->InitiateScan(); 464 465 EXPECT_CALL(*this, OnScanError()); 466 NewScanResultsMessage not_supposed_to_get_this_message; 467 scan_session()->OnTriggerScanResponse(not_supposed_to_get_this_message); 468 } 469 470 TEST_F(ScanSessionTest, ExhaustFrequencies) { 471 // Set min & max scan frequency count to 1 so each scan will be of a single 472 // frequency. 473 SetScanSize(1, 1); 474 475 // Perform all the progressive scans until the frequencies are exhausted. 476 for (size_t i = 0; i < GetScanFrequencyCount(); ++i) { 477 EXPECT_TRUE(scan_session()->HasMoreFrequencies()); 478 EXPECT_CALL(*netlink_manager(), SendNl80211Message( 479 IsNl80211Command(kNl80211FamilyId, NL80211_CMD_TRIGGER_SCAN), _, _, _)); 480 scan_session()->InitiateScan(); 481 } 482 483 EXPECT_FALSE(scan_session()->HasMoreFrequencies()); 484 EXPECT_CALL(*netlink_manager(), SendNl80211Message( 485 IsNl80211Command(kNl80211FamilyId, NL80211_CMD_TRIGGER_SCAN), _, _, _)) 486 .Times(0); 487 scan_session()->InitiateScan(); 488 } 489 490 TEST_F(ScanSessionTest, OnError) { 491 Nl80211Message::SetMessageType(kNl80211FamilyId); 492 493 EXPECT_CALL(*netlink_manager(), SendNl80211Message( 494 IsNl80211Command(kNl80211FamilyId, NL80211_CMD_TRIGGER_SCAN), _, _, _)); 495 scan_session()->InitiateScan(); 496 497 EXPECT_CALL(*this, OnScanError()); 498 ErrorAckMessage error_message(-EINTR); 499 scan_session()->OnTriggerScanErrorResponse(NetlinkManager::kErrorFromKernel, 500 &error_message); 501 } 502 503 TEST_F(ScanSessionTest, EBusy) { 504 const size_t kSmallRetryNumber = 3; 505 Nl80211Message::SetMessageType(kNl80211FamilyId); 506 scan_session()->scan_tries_left_ = kSmallRetryNumber; 507 508 EXPECT_CALL(*netlink_manager(), SendNl80211Message( 509 IsNl80211Command(kNl80211FamilyId, NL80211_CMD_TRIGGER_SCAN), _, _, _)); 510 scan_session()->InitiateScan(); 511 512 ErrorAckMessage error_message(-EBUSY); 513 for (size_t i = 0; i < kSmallRetryNumber; ++i) { 514 EXPECT_CALL(*this, OnScanError()).Times(0); 515 EXPECT_CALL(*dispatcher(), PostDelayedTask(_, _)); 516 scan_session()->OnTriggerScanErrorResponse(NetlinkManager::kErrorFromKernel, 517 &error_message); 518 } 519 520 EXPECT_CALL(*this, OnScanError()); 521 scan_session()->OnTriggerScanErrorResponse(NetlinkManager::kErrorFromKernel, 522 &error_message); 523 } 524 525 TEST_F(ScanSessionTest, ScanHidden) { 526 scan_session_->AddSsid(ByteString("a", 1)); 527 EXPECT_CALL(netlink_manager_, 528 SendNl80211Message(HasHiddenSSID(kNl80211FamilyId), _, _, _)); 529 scan_session()->InitiateScan(); 530 } 531 532 TEST_F(ScanSessionTest, ScanNoHidden) { 533 EXPECT_CALL(netlink_manager_, 534 SendNl80211Message(HasNoHiddenSSID(kNl80211FamilyId), _, _, _)); 535 scan_session()->InitiateScan(); 536 } 537 538 } // namespace shill 539