Home | History | Annotate | Download | only in apmanager
      1 //
      2 // Copyright (C) 2014 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 "apmanager/device.h"
     18 
     19 #include <string>
     20 #include <vector>
     21 
     22 #include <base/strings/stringprintf.h>
     23 #include <gmock/gmock.h>
     24 #include <gtest/gtest.h>
     25 #include <shill/net/ieee80211.h>
     26 #include <shill/net/nl80211_attribute.h>
     27 #include <shill/net/nl80211_message.h>
     28 
     29 #include "apmanager/fake_device_adaptor.h"
     30 #include "apmanager/mock_control.h"
     31 #include "apmanager/mock_manager.h"
     32 
     33 using ::testing::_;
     34 using ::testing::Mock;
     35 using ::testing::ReturnNew;
     36 using std::vector;
     37 
     38 namespace apmanager {
     39 
     40 namespace {
     41 
     42 const char kDeviceName[] = "phy0";
     43 const Device::WiFiInterface kApModeInterface0 = {
     44     "uap0", kDeviceName, 1, NL80211_IFTYPE_AP
     45 };
     46 const Device::WiFiInterface kApModeInterface1 = {
     47     "uap1", kDeviceName, 2, NL80211_IFTYPE_AP
     48 };
     49 const Device::WiFiInterface kManagedModeInterface0 = {
     50     "wlan0", kDeviceName, 3, NL80211_IFTYPE_STATION
     51 };
     52 const Device::WiFiInterface kManagedModeInterface1 = {
     53     "wlan1", kDeviceName, 4, NL80211_IFTYPE_STATION
     54 };
     55 const Device::WiFiInterface kMonitorModeInterface = {
     56     "monitor0", kDeviceName, 5, NL80211_IFTYPE_MONITOR
     57 };
     58 
     59 }  // namespace
     60 
     61 class DeviceTest : public testing::Test {
     62  public:
     63   DeviceTest() : manager_(&control_interface_) {
     64     ON_CALL(control_interface_, CreateDeviceAdaptorRaw())
     65         .WillByDefault(ReturnNew<FakeDeviceAdaptor>());
     66     device_ = new Device(&manager_, kDeviceName, 0);
     67   }
     68 
     69   void VerifyInterfaceList(
     70       const vector<Device::WiFiInterface>& interface_list) {
     71     EXPECT_EQ(interface_list.size(), device_->interface_list_.size());
     72     for (size_t i = 0; i < interface_list.size(); i++) {
     73       EXPECT_TRUE(interface_list[i].Equals(device_->interface_list_[i]));
     74     }
     75   }
     76 
     77   void VerifyPreferredApInterface(const std::string& interface_name) {
     78     EXPECT_EQ(interface_name, device_->GetPreferredApInterface());
     79   }
     80 
     81   void AddWiphyBandAttribute(shill::AttributeListRefPtr wiphy_bands,
     82                              const std::string& band_name,
     83                              int band_id,
     84                              std::vector<uint32_t> frequency_list,
     85                              uint16_t ht_cap_mask) {
     86     // Band attribute.
     87     shill::AttributeListRefPtr wiphy_band;
     88     wiphy_bands->CreateNestedAttribute(band_id, band_name.c_str());
     89     wiphy_bands->GetNestedAttributeList(band_id, &wiphy_band);
     90     // Frequencies attribute.
     91     shill::AttributeListRefPtr frequencies;
     92     wiphy_band->CreateNestedAttribute(NL80211_BAND_ATTR_FREQS,
     93                                       "NL80211_BAND_ATTR_FREQS");
     94     wiphy_band->GetNestedAttributeList(NL80211_BAND_ATTR_FREQS,
     95                                        &frequencies);
     96     // Frequency attribute.
     97     for (size_t i = 0; i < frequency_list.size(); i++) {
     98       shill::AttributeListRefPtr frequency;
     99       frequencies->CreateNestedAttribute(
    100           i, base::StringPrintf("Frequency %d", frequency_list[i]).c_str());
    101       frequencies->GetNestedAttributeList(i, &frequency);
    102       frequency->CreateU32Attribute(NL80211_FREQUENCY_ATTR_FREQ,
    103                                     "NL80211_FREQUENCY_ATTR_FREQ");
    104       frequency->SetU32AttributeValue(NL80211_FREQUENCY_ATTR_FREQ,
    105                                       frequency_list[i]);
    106       frequencies->SetNestedAttributeHasAValue(i);
    107     }
    108     wiphy_band->SetNestedAttributeHasAValue(NL80211_BAND_ATTR_FREQS);
    109 
    110     // HT Capability attribute.
    111     wiphy_band->CreateU16Attribute(NL80211_BAND_ATTR_HT_CAPA,
    112                                    "NL80211_BAND_ATTR_HT_CAPA");
    113     wiphy_band->SetU16AttributeValue(NL80211_BAND_ATTR_HT_CAPA, ht_cap_mask);
    114 
    115     wiphy_bands->SetNestedAttributeHasAValue(band_id);
    116   }
    117 
    118   void EnableApModeSupport() {
    119     device_->supports_ap_mode_ = true;
    120   }
    121 
    122   void VerifyApModeSupport(bool supports_ap_mode) {
    123     EXPECT_EQ(supports_ap_mode, device_->supports_ap_mode_);
    124   }
    125 
    126   void VerifyFrequencyList(int band_id, std::vector<uint32_t> frequency_list) {
    127     EXPECT_EQ(frequency_list, device_->band_capability_[band_id].frequencies);
    128   }
    129 
    130  protected:
    131   MockControl control_interface_;
    132   MockManager manager_;
    133   scoped_refptr<Device> device_;
    134 };
    135 
    136 TEST_F(DeviceTest, RegisterInterface) {
    137   vector<Device::WiFiInterface> interface_list;
    138   interface_list.push_back(kApModeInterface0);
    139   interface_list.push_back(kManagedModeInterface0);
    140   interface_list.push_back(kMonitorModeInterface);
    141 
    142   device_->RegisterInterface(kApModeInterface0);
    143   device_->RegisterInterface(kManagedModeInterface0);
    144   device_->RegisterInterface(kMonitorModeInterface);
    145 
    146   // Verify result interface list.
    147   VerifyInterfaceList(interface_list);
    148 }
    149 
    150 TEST_F(DeviceTest, DeregisterInterface) {
    151   vector<Device::WiFiInterface> interface_list;
    152   interface_list.push_back(kApModeInterface0);
    153   interface_list.push_back(kManagedModeInterface0);
    154 
    155   // Register all interfaces, then deregister monitor0 and wlan1 interfaces.
    156   device_->RegisterInterface(kApModeInterface0);
    157   device_->RegisterInterface(kMonitorModeInterface);
    158   device_->RegisterInterface(kManagedModeInterface0);
    159   device_->RegisterInterface(kManagedModeInterface1);
    160   device_->DeregisterInterface(kMonitorModeInterface);
    161   device_->DeregisterInterface(kManagedModeInterface1);
    162 
    163   // Verify result interface list.
    164   VerifyInterfaceList(interface_list);
    165 }
    166 
    167 TEST_F(DeviceTest, PreferredAPInterface) {
    168   EnableApModeSupport();
    169 
    170   // Register a monitor mode interface, no preferred AP mode interface.
    171   device_->RegisterInterface(kMonitorModeInterface);
    172   VerifyPreferredApInterface("");
    173 
    174   // Register a managed mode interface, should be set to preferred AP interface.
    175   device_->RegisterInterface(kManagedModeInterface0);
    176   VerifyPreferredApInterface(kManagedModeInterface0.iface_name);
    177 
    178   // Register a ap mode interface, should be set to preferred AP interface.
    179   device_->RegisterInterface(kApModeInterface0);
    180   VerifyPreferredApInterface(kApModeInterface0.iface_name);
    181 
    182   // Register another ap mode interface "uap1" and managed mode interface
    183   // "wlan1", preferred AP interface should still be set to the first detected
    184   // ap mode interface "uap0".
    185   device_->RegisterInterface(kApModeInterface1);
    186   device_->RegisterInterface(kManagedModeInterface1);
    187   VerifyPreferredApInterface(kApModeInterface0.iface_name);
    188 
    189   // Deregister the first ap mode interface, preferred AP interface should be
    190   // set to the second ap mode interface.
    191   device_->DeregisterInterface(kApModeInterface0);
    192   VerifyPreferredApInterface(kApModeInterface1.iface_name);
    193 
    194   // Deregister the second ap mode interface, preferred AP interface should be
    195   // set the first managed mode interface.
    196   device_->DeregisterInterface(kApModeInterface1);
    197   VerifyPreferredApInterface(kManagedModeInterface0.iface_name);
    198 
    199   // Deregister the first managed mode interface, preferred AP interface
    200   // should be set to the second managed mode interface.
    201   device_->DeregisterInterface(kManagedModeInterface0);
    202   VerifyPreferredApInterface(kManagedModeInterface1.iface_name);
    203 
    204   // Deregister the second managed mode interface, preferred AP interface
    205   // should be set to empty string.
    206   device_->DeregisterInterface(kManagedModeInterface1);
    207   VerifyPreferredApInterface("");
    208 }
    209 
    210 TEST_F(DeviceTest, DeviceWithoutAPModeSupport) {
    211   // AP mode support is not enabled for the device, so no preferred AP
    212   // mode interface.
    213   device_->RegisterInterface(kApModeInterface0);
    214   VerifyPreferredApInterface("");
    215 }
    216 
    217 TEST_F(DeviceTest, ParseWiphyCapability) {
    218   shill::NewWiphyMessage message;
    219 
    220   // Supported interface types attribute.
    221   message.attributes()->CreateNestedAttribute(
    222       NL80211_ATTR_SUPPORTED_IFTYPES, "NL80211_ATTR_SUPPORTED_IFTYPES");
    223   shill::AttributeListRefPtr supported_iftypes;
    224   message.attributes()->GetNestedAttributeList(
    225       NL80211_ATTR_SUPPORTED_IFTYPES, &supported_iftypes);
    226   // Add support for AP mode interface.
    227   supported_iftypes->CreateFlagAttribute(
    228       NL80211_IFTYPE_AP, "NL80211_IFTYPE_AP");
    229   supported_iftypes->SetFlagAttributeValue(NL80211_IFTYPE_AP, true);
    230   message.attributes()->SetNestedAttributeHasAValue(
    231       NL80211_ATTR_SUPPORTED_IFTYPES);
    232 
    233   // Wiphy bands attribute.
    234   message.attributes()->CreateNestedAttribute(
    235       NL80211_ATTR_WIPHY_BANDS, "NL80211_ATTR_WIPHY_BANDS");
    236   shill::AttributeListRefPtr wiphy_bands;
    237   message.attributes()->GetNestedAttributeList(
    238       NL80211_ATTR_WIPHY_BANDS, &wiphy_bands);
    239 
    240   // 2.4GHz band capability.
    241   const uint32_t kBand24GHzFrequencies[] = {
    242       2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462, 2467};
    243   const uint16_t kBand24GHzHTCapMask = shill::IEEE_80211::kHTCapMaskLdpcCoding |
    244                                        shill::IEEE_80211::kHTCapMaskGrnFld |
    245                                        shill::IEEE_80211::kHTCapMaskSgi20;
    246   std::vector<uint32_t> band_24ghz_freq_list(
    247       kBand24GHzFrequencies,
    248       kBand24GHzFrequencies + sizeof(kBand24GHzFrequencies) /
    249           sizeof(kBand24GHzFrequencies[0]));
    250   AddWiphyBandAttribute(
    251       wiphy_bands, "2.4GHz band", 0, band_24ghz_freq_list,
    252       kBand24GHzHTCapMask);
    253 
    254   // 5GHz band capability.
    255   const uint32_t kBand5GHzFrequencies[] = {
    256       5180, 5190, 5200, 5210, 5220, 5230, 5240, 5260, 5280, 5300, 5320};
    257   const uint16_t kBand5GHzHTCapMask =
    258       shill::IEEE_80211::kHTCapMaskLdpcCoding |
    259       shill::IEEE_80211::kHTCapMaskSupWidth2040 |
    260       shill::IEEE_80211::kHTCapMaskGrnFld |
    261       shill::IEEE_80211::kHTCapMaskSgi20 |
    262       shill::IEEE_80211::kHTCapMaskSgi40;
    263   std::vector<uint32_t> band_5ghz_freq_list(
    264       kBand5GHzFrequencies,
    265       kBand5GHzFrequencies + sizeof(kBand5GHzFrequencies) /
    266           sizeof(kBand5GHzFrequencies[0]));
    267   AddWiphyBandAttribute(
    268       wiphy_bands, "5GHz band", 1, band_5ghz_freq_list, kBand5GHzHTCapMask);
    269 
    270   message.attributes()->SetNestedAttributeHasAValue(NL80211_ATTR_WIPHY_BANDS);
    271 
    272   device_->ParseWiphyCapability(message);
    273 
    274   // Verify AP mode support.
    275   VerifyApModeSupport(true);
    276 
    277   // Verify frequency list for both bands.
    278   VerifyFrequencyList(0, band_24ghz_freq_list);
    279   VerifyFrequencyList(1, band_5ghz_freq_list);
    280 
    281   // Verify HT Capablity for 2.4GHz band.
    282   const char kBand24GHzHTCapability[] = "[LDPC SMPS-STATIC GF SHORT-GI-20]";
    283   std::string band_24ghz_cap;
    284   EXPECT_TRUE(device_->GetHTCapability(6, &band_24ghz_cap));
    285   EXPECT_EQ(kBand24GHzHTCapability, band_24ghz_cap);
    286 
    287   // Verify HT Capablity for 5GHz band.
    288   const char kBand5GHzHTCapability[] =
    289       "[LDPC HT40+ SMPS-STATIC GF SHORT-GI-20 SHORT-GI-40]";
    290   std::string band_5ghz_cap;
    291   EXPECT_TRUE(device_->GetHTCapability(36, &band_5ghz_cap));
    292   EXPECT_EQ(kBand5GHzHTCapability, band_5ghz_cap);
    293 }
    294 
    295 TEST_F(DeviceTest, ClaimAndReleaseDeviceWithFullControl) {
    296   EnableApModeSupport();
    297 
    298   // Register multiple interfaces.
    299   device_->RegisterInterface(kApModeInterface1);
    300   device_->RegisterInterface(kManagedModeInterface1);
    301 
    302   // Claim the device should claim all interfaces registered on this device..
    303   EXPECT_CALL(manager_, ClaimInterface(kApModeInterface1.iface_name)).Times(1);
    304   EXPECT_CALL(manager_,
    305               ClaimInterface(kManagedModeInterface1.iface_name)).Times(1);
    306   EXPECT_TRUE(device_->ClaimDevice(true));
    307   Mock::VerifyAndClearExpectations(&manager_);
    308 
    309   // Claim the device when it is already claimed.
    310   EXPECT_CALL(manager_, ClaimInterface(_)).Times(0);
    311   EXPECT_FALSE(device_->ClaimDevice(true));
    312   Mock::VerifyAndClearExpectations(&manager_);
    313 
    314   // Release the device should release all interfaces registered on this device.
    315   EXPECT_CALL(manager_,
    316               ReleaseInterface(kApModeInterface1.iface_name)).Times(1);
    317   EXPECT_CALL(manager_,
    318               ReleaseInterface(kManagedModeInterface1.iface_name)).Times(1);
    319   EXPECT_TRUE(device_->ReleaseDevice());
    320   Mock::VerifyAndClearExpectations(&manager_);
    321 
    322   // Release the device when it is not claimed.
    323   EXPECT_CALL(manager_, ReleaseInterface(_)).Times(0);
    324   EXPECT_FALSE(device_->ReleaseDevice());
    325   Mock::VerifyAndClearExpectations(&manager_);
    326 }
    327 
    328 TEST_F(DeviceTest, ClaimAndReleaseDeviceWithoutFullControl) {
    329   EnableApModeSupport();
    330 
    331   // Register multiple interfaces.
    332   device_->RegisterInterface(kApModeInterface1);
    333   device_->RegisterInterface(kManagedModeInterface1);
    334 
    335   // Claim the device should only claim the preferred AP interface registered
    336   // on this device.
    337   EXPECT_CALL(manager_, ClaimInterface(kApModeInterface1.iface_name)).Times(1);
    338   EXPECT_CALL(manager_,
    339               ClaimInterface(kManagedModeInterface1.iface_name)).Times(0);
    340   EXPECT_TRUE(device_->ClaimDevice(false));
    341   Mock::VerifyAndClearExpectations(&manager_);
    342 
    343   // Claim the device when it is already claimed.
    344   EXPECT_CALL(manager_, ClaimInterface(_)).Times(0);
    345   EXPECT_FALSE(device_->ClaimDevice(false));
    346   Mock::VerifyAndClearExpectations(&manager_);
    347 
    348   // Release the device should release the preferred AP interface registered
    349   // on this device.
    350   EXPECT_CALL(manager_,
    351               ReleaseInterface(kApModeInterface1.iface_name)).Times(1);
    352   EXPECT_CALL(manager_,
    353               ReleaseInterface(kManagedModeInterface1.iface_name)).Times(0);
    354   EXPECT_TRUE(device_->ReleaseDevice());
    355   Mock::VerifyAndClearExpectations(&manager_);
    356 
    357   // Release the device when it is not claimed.
    358   EXPECT_CALL(manager_, ReleaseInterface(_)).Times(0);
    359   EXPECT_FALSE(device_->ReleaseDevice());
    360   Mock::VerifyAndClearExpectations(&manager_);
    361 }
    362 
    363 }  // namespace apmanager
    364