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/config.h"
     18 
     19 #include <base/strings/stringprintf.h>
     20 
     21 #if !defined(__ANDROID__)
     22 #include <chromeos/dbus/service_constants.h>
     23 #else
     24 #include <dbus/apmanager/dbus-constants.h>
     25 #endif  // __ANDROID__
     26 
     27 #include "apmanager/error.h"
     28 #include "apmanager/daemon.h"
     29 #include "apmanager/device.h"
     30 #include "apmanager/manager.h"
     31 
     32 using std::string;
     33 
     34 namespace apmanager {
     35 
     36 // static
     37 const char Config::kHostapdConfigKeyBridgeInterface[] = "bridge";
     38 const char Config::kHostapdConfigKeyChannel[] = "channel";
     39 const char Config::kHostapdConfigKeyControlInterface[] = "ctrl_interface";
     40 const char Config::kHostapdConfigKeyControlInterfaceGroup[] =
     41     "ctrl_interface_group";
     42 const char Config::kHostapdConfigKeyDriver[] = "driver";
     43 const char Config::kHostapdConfigKeyFragmThreshold[] = "fragm_threshold";
     44 const char Config::kHostapdConfigKeyHTCapability[] = "ht_capab";
     45 const char Config::kHostapdConfigKeyHwMode[] = "hw_mode";
     46 const char Config::kHostapdConfigKeyIeee80211ac[] = "ieee80211ac";
     47 const char Config::kHostapdConfigKeyIeee80211n[] = "ieee80211n";
     48 const char Config::kHostapdConfigKeyIgnoreBroadcastSsid[] =
     49     "ignore_broadcast_ssid";
     50 const char Config::kHostapdConfigKeyInterface[] = "interface";
     51 const char Config::kHostapdConfigKeyRsnPairwise[] = "rsn_pairwise";
     52 const char Config::kHostapdConfigKeyRtsThreshold[] = "rts_threshold";
     53 const char Config::kHostapdConfigKeySsid[] = "ssid";
     54 const char Config::kHostapdConfigKeyWepDefaultKey[] = "wep_default_key";
     55 const char Config::kHostapdConfigKeyWepKey0[] = "wep_key0";
     56 const char Config::kHostapdConfigKeyWpa[] = "wpa";
     57 const char Config::kHostapdConfigKeyWpaKeyMgmt[] = "wpa_key_mgmt";
     58 const char Config::kHostapdConfigKeyWpaPassphrase[] = "wpa_passphrase";
     59 
     60 const char Config::kHostapdHwMode80211a[] = "a";
     61 const char Config::kHostapdHwMode80211b[] = "b";
     62 const char Config::kHostapdHwMode80211g[] = "g";
     63 
     64 // static
     65 const uint16_t Config::kPropertyDefaultChannel = 6;
     66 const uint16_t Config::kPropertyDefaultServerAddressIndex = 0;
     67 const bool Config::kPropertyDefaultHiddenNetwork = false;
     68 
     69 // static
     70 const char Config::kHostapdDefaultDriver[] = "nl80211";
     71 const char Config::kHostapdDefaultRsnPairwise[] = "CCMP";
     72 const char Config::kHostapdDefaultWpaKeyMgmt[] = "WPA-PSK";
     73 // Fragmentation threshold: disabled.
     74 const int Config::kHostapdDefaultFragmThreshold = 2346;
     75 // RTS threshold: disabled.
     76 const int Config::kHostapdDefaultRtsThreshold = 2347;
     77 
     78 // static
     79 const uint16_t Config::kBand24GHzChannelLow = 1;
     80 const uint16_t Config::kBand24GHzChannelHigh = 13;
     81 const uint32_t Config::kBand24GHzBaseFrequency = 2412;
     82 const uint16_t Config::kBand5GHzChannelLow = 34;
     83 const uint16_t Config::kBand5GHzChannelHigh = 165;
     84 const uint16_t Config::kBand5GHzBaseFrequency = 5170;
     85 
     86 // static
     87 const int Config::kSsidMinLength = 1;
     88 const int Config::kSsidMaxLength = 32;
     89 const int Config::kPassphraseMinLength = 8;
     90 const int Config::kPassphraseMaxLength = 63;
     91 
     92 Config::Config(Manager* manager, int service_identifier)
     93     : manager_(manager),
     94       adaptor_(
     95           manager->control_interface()->CreateConfigAdaptor(
     96               this, service_identifier)) {
     97   // Initialize default configuration values.
     98   SetSecurityMode(kSecurityModeNone);
     99   SetHwMode(kHwMode80211g);
    100   SetOperationMode(kOperationModeServer);
    101   SetServerAddressIndex(kPropertyDefaultServerAddressIndex);
    102   SetChannel(kPropertyDefaultChannel);
    103   SetHiddenNetwork(kPropertyDefaultHiddenNetwork);
    104   SetFullDeviceControl(true);
    105 }
    106 
    107 Config::~Config() {}
    108 
    109 // static.
    110 bool Config::GetFrequencyFromChannel(uint16_t channel, uint32_t* freq) {
    111   bool ret_value = true;
    112   if (channel >= kBand24GHzChannelLow && channel <= kBand24GHzChannelHigh) {
    113     *freq = kBand24GHzBaseFrequency + (channel - kBand24GHzChannelLow) * 5;
    114   } else if (channel >= kBand5GHzChannelLow &&
    115              channel <= kBand5GHzChannelHigh) {
    116     *freq = kBand5GHzBaseFrequency + (channel - kBand5GHzChannelLow) * 5;
    117   } else {
    118     ret_value = false;
    119   }
    120   return ret_value;
    121 }
    122 
    123 bool Config::ValidateSsid(Error* error, const string& value) {
    124   if (value.length() < kSsidMinLength || value.length() > kSsidMaxLength) {
    125     Error::PopulateAndLog(
    126         error,
    127         Error::kInvalidArguments,
    128         base::StringPrintf("SSID must contain between %d and %d characters",
    129                            kSsidMinLength, kSsidMaxLength),
    130         FROM_HERE);
    131     return false;
    132   }
    133   return true;
    134 }
    135 
    136 bool Config::ValidateSecurityMode(Error* error, const string& value) {
    137   if (value != kSecurityModeNone && value != kSecurityModeRSN) {
    138     Error::PopulateAndLog(
    139         error,
    140         Error::kInvalidArguments,
    141         base::StringPrintf("Invalid/unsupported security mode [%s]",
    142                            value.c_str()),
    143         FROM_HERE);
    144     return false;
    145   }
    146   return true;
    147 }
    148 
    149 bool Config::ValidatePassphrase(Error* error, const string& value) {
    150   if (value.length() < kPassphraseMinLength ||
    151       value.length() > kPassphraseMaxLength) {
    152     Error::PopulateAndLog(
    153         error,
    154         Error::kInvalidArguments,
    155         base::StringPrintf("Passphrase must contain between %d and %d characters",
    156                            kPassphraseMinLength, kPassphraseMaxLength),
    157         FROM_HERE);
    158 
    159     return false;
    160   }
    161   return true;
    162 }
    163 
    164 bool Config::ValidateHwMode(Error* error, const string& value) {
    165   if (value != kHwMode80211a && value != kHwMode80211b &&
    166       value != kHwMode80211g && value != kHwMode80211n &&
    167       value != kHwMode80211ac) {
    168     Error::PopulateAndLog(
    169         error,
    170         Error::kInvalidArguments,
    171         base::StringPrintf("Invalid HW mode [%s]", value.c_str()),
    172         FROM_HERE);
    173     return false;
    174   }
    175   return true;
    176 }
    177 
    178 bool Config::ValidateOperationMode(Error* error, const string& value) {
    179   if (value != kOperationModeServer && value != kOperationModeBridge) {
    180     Error::PopulateAndLog(
    181         error,
    182         Error::kInvalidArguments,
    183         base::StringPrintf("Invalid operation mode [%s]", value.c_str()),
    184         FROM_HERE);
    185     return false;
    186   }
    187   return true;
    188 }
    189 
    190 bool Config::ValidateChannel(Error* error, const uint16_t& value) {
    191   if ((value >= kBand24GHzChannelLow && value <= kBand24GHzChannelHigh) ||
    192       (value >= kBand5GHzChannelLow && value <= kBand5GHzChannelHigh)) {
    193     return true;
    194   }
    195   Error::PopulateAndLog(error,
    196                         Error::kInvalidArguments,
    197                         base::StringPrintf("Invalid channel [%d]", value),
    198                         FROM_HERE);
    199   return false;
    200 }
    201 
    202 bool Config::GenerateConfigFile(Error* error, string* config_str) {
    203   // SSID.
    204   string ssid = GetSsid();
    205   if (ssid.empty()) {
    206     Error::PopulateAndLog(error,
    207                           Error::kInvalidConfiguration,
    208                           "SSID not specified",
    209                           FROM_HERE);
    210     return false;
    211   }
    212   base::StringAppendF(
    213       config_str, "%s=%s\n", kHostapdConfigKeySsid, ssid.c_str());
    214 
    215   // Bridge interface is required for bridge mode operation.
    216   if (GetOperationMode() == kOperationModeBridge) {
    217     if (GetBridgeInterface().empty()) {
    218       Error::PopulateAndLog(
    219           error,
    220           Error::kInvalidConfiguration,
    221           "Bridge interface not specified, required for bridge mode",
    222           FROM_HERE);
    223       return false;
    224     }
    225     base::StringAppendF(config_str,
    226                         "%s=%s\n",
    227                         kHostapdConfigKeyBridgeInterface,
    228                         GetBridgeInterface().c_str());
    229   }
    230 
    231   // Channel.
    232   base::StringAppendF(
    233       config_str, "%s=%d\n", kHostapdConfigKeyChannel, GetChannel());
    234 
    235   // Interface.
    236   if (!AppendInterface(error, config_str)) {
    237     return false;
    238   }
    239 
    240   // Hardware mode.
    241   if (!AppendHwMode(error, config_str)) {
    242     return false;
    243   }
    244 
    245   // Security mode configurations.
    246   if (!AppendSecurityMode(error, config_str)) {
    247     return false;
    248   }
    249 
    250   // Control interface.
    251   if (!control_interface_.empty()) {
    252     base::StringAppendF(config_str,
    253                         "%s=%s\n",
    254                         kHostapdConfigKeyControlInterface,
    255                         control_interface_.c_str());
    256     base::StringAppendF(config_str,
    257                         "%s=%s\n",
    258                         kHostapdConfigKeyControlInterfaceGroup,
    259                         Daemon::kAPManagerGroupName);
    260   }
    261 
    262   // Hostapd default configurations.
    263   if (!AppendHostapdDefaults(error, config_str)) {
    264     return false;
    265   }
    266 
    267   return true;
    268 }
    269 
    270 bool Config::ClaimDevice() {
    271   if (!device_) {
    272     LOG(ERROR) << "Failed to claim device: device doesn't exist.";
    273     return false;
    274   }
    275   return device_->ClaimDevice(GetFullDeviceControl());
    276 }
    277 
    278 bool Config::ReleaseDevice() {
    279   if (!device_) {
    280     LOG(ERROR) << "Failed to release device: device doesn't exist.";
    281     return false;
    282   }
    283   return device_->ReleaseDevice();
    284 }
    285 
    286 void Config::SetSsid(const string& ssid) {
    287   adaptor_->SetSsid(ssid);
    288 }
    289 
    290 string Config::GetSsid() const {
    291   return adaptor_->GetSsid();
    292 }
    293 
    294 void Config::SetInterfaceName(const std::string& interface_name) {
    295   adaptor_->SetInterfaceName(interface_name);
    296 }
    297 
    298 string Config::GetInterfaceName() const {
    299   return adaptor_->GetInterfaceName();
    300 }
    301 
    302 void Config::SetSecurityMode(const std::string& mode) {
    303   adaptor_->SetSecurityMode(mode);
    304 }
    305 
    306 string Config::GetSecurityMode() const {
    307   return adaptor_->GetSecurityMode();
    308 }
    309 
    310 void Config::SetPassphrase(const std::string& passphrase) {
    311   adaptor_->SetPassphrase(passphrase);
    312 }
    313 
    314 string Config::GetPassphrase() const {
    315   return adaptor_->GetPassphrase();
    316 }
    317 
    318 void Config::SetHwMode(const std::string& hw_mode) {
    319   adaptor_->SetHwMode(hw_mode);
    320 }
    321 
    322 string Config::GetHwMode() const {
    323   return adaptor_->GetHwMode();
    324 }
    325 
    326 void Config::SetOperationMode(const std::string& op_mode) {
    327   adaptor_->SetOperationMode(op_mode);
    328 }
    329 
    330 string Config::GetOperationMode() const {
    331   return adaptor_->GetOperationMode();
    332 }
    333 
    334 void Config::SetChannel(uint16_t channel) {
    335   adaptor_->SetChannel(channel);
    336 }
    337 
    338 uint16_t Config::GetChannel() const {
    339   return adaptor_->GetChannel();
    340 }
    341 
    342 void Config::SetHiddenNetwork(bool hidden_network) {
    343   adaptor_->SetHiddenNetwork(hidden_network);
    344 }
    345 
    346 bool Config::GetHiddenNetwork() const {
    347   return adaptor_->GetHiddenNetwork();
    348 }
    349 
    350 void Config::SetBridgeInterface(const std::string& interface_name) {
    351   adaptor_->SetBridgeInterface(interface_name);
    352 }
    353 
    354 string Config::GetBridgeInterface() const {
    355   return adaptor_->GetBridgeInterface();
    356 }
    357 
    358 void Config::SetServerAddressIndex(uint16_t index) {
    359   adaptor_->SetServerAddressIndex(index);
    360 }
    361 
    362 uint16_t Config::GetServerAddressIndex() const {
    363   return adaptor_->GetServerAddressIndex();
    364 }
    365 
    366 void Config::SetFullDeviceControl(bool full_control) {
    367   adaptor_->SetFullDeviceControl(full_control);
    368 }
    369 
    370 bool Config::GetFullDeviceControl() const {
    371   return adaptor_->GetFullDeviceControl();
    372 }
    373 
    374 bool Config::AppendHwMode(Error* error, string* config_str) {
    375   string hw_mode = GetHwMode();
    376   string hostapd_hw_mode;
    377   if (hw_mode == kHwMode80211a) {
    378     hostapd_hw_mode = kHostapdHwMode80211a;
    379   } else if (hw_mode == kHwMode80211b) {
    380     hostapd_hw_mode = kHostapdHwMode80211b;
    381   } else if (hw_mode == kHwMode80211g) {
    382     hostapd_hw_mode = kHostapdHwMode80211g;
    383   } else if (hw_mode == kHwMode80211n) {
    384     // Use 802.11a for 5GHz channel and 802.11g for 2.4GHz channel
    385     if (GetChannel() >= 34) {
    386       hostapd_hw_mode = kHostapdHwMode80211a;
    387     } else {
    388       hostapd_hw_mode = kHostapdHwMode80211g;
    389     }
    390     base::StringAppendF(config_str, "%s=1\n", kHostapdConfigKeyIeee80211n);
    391 
    392     // Get HT Capability.
    393     string ht_cap;
    394     if (!device_->GetHTCapability(GetChannel(), &ht_cap)) {
    395       Error::PopulateAndLog(error,
    396                             Error::kInvalidConfiguration,
    397                             "Failed to get HT Capability",
    398                             FROM_HERE);
    399       return false;
    400     }
    401     base::StringAppendF(config_str, "%s=%s\n",
    402                         kHostapdConfigKeyHTCapability,
    403                         ht_cap.c_str());
    404   } else if (hw_mode == kHwMode80211ac) {
    405     if (GetChannel() >= 34) {
    406       hostapd_hw_mode = kHostapdHwMode80211a;
    407     } else {
    408       hostapd_hw_mode = kHostapdHwMode80211g;
    409     }
    410     base::StringAppendF(config_str, "%s=1\n", kHostapdConfigKeyIeee80211ac);
    411 
    412     // TODO(zqiu): Determine VHT Capabilities based on the interface PHY's
    413     // capababilites.
    414   } else {
    415     Error::PopulateAndLog(
    416         error,
    417         Error::kInvalidConfiguration,
    418         base::StringPrintf("Invalid hardware mode: %s", hw_mode.c_str()),
    419         FROM_HERE);
    420     return false;
    421   }
    422 
    423   base::StringAppendF(
    424       config_str, "%s=%s\n", kHostapdConfigKeyHwMode, hostapd_hw_mode.c_str());
    425   return true;
    426 }
    427 
    428 bool Config::AppendHostapdDefaults(Error* error, string* config_str) {
    429   // Driver: NL80211.
    430   base::StringAppendF(
    431       config_str, "%s=%s\n", kHostapdConfigKeyDriver, kHostapdDefaultDriver);
    432 
    433   // Fragmentation threshold: disabled.
    434   base::StringAppendF(config_str,
    435                       "%s=%d\n",
    436                       kHostapdConfigKeyFragmThreshold,
    437                       kHostapdDefaultFragmThreshold);
    438 
    439   // RTS threshold: disabled.
    440   base::StringAppendF(config_str,
    441                       "%s=%d\n",
    442                       kHostapdConfigKeyRtsThreshold,
    443                       kHostapdDefaultRtsThreshold);
    444 
    445   return true;
    446 }
    447 
    448 bool Config::AppendInterface(Error* error, string* config_str) {
    449   string interface = GetInterfaceName();
    450   if (interface.empty()) {
    451     // Ask manager for unused ap capable device.
    452     device_ = manager_->GetAvailableDevice();
    453     if (!device_) {
    454       Error::PopulateAndLog(
    455           error, Error::kInternalError, "No device available", FROM_HERE);
    456       return false;
    457     }
    458   } else {
    459     device_ = manager_->GetDeviceFromInterfaceName(interface);
    460     if (!device_) {
    461       Error::PopulateAndLog(
    462           error,
    463           Error::kInvalidConfiguration,
    464           base::StringPrintf(
    465               "Unable to find device for the specified interface [%s]",
    466               interface.c_str()),
    467           FROM_HERE);
    468       return false;
    469     }
    470     if (device_->GetInUse()) {
    471       Error::PopulateAndLog(
    472           error,
    473           Error::kInvalidConfiguration,
    474           base::StringPrintf("Device [%s] for interface [%s] already in use",
    475                              device_->GetDeviceName().c_str(),
    476                              interface.c_str()),
    477           FROM_HERE);
    478       return false;
    479     }
    480   }
    481 
    482   // Use the preferred AP interface from the device.
    483   selected_interface_ = device_->GetPreferredApInterface();
    484   base::StringAppendF(config_str,
    485                       "%s=%s\n",
    486                       kHostapdConfigKeyInterface,
    487                       selected_interface_.c_str());
    488   return true;
    489 }
    490 
    491 bool Config::AppendSecurityMode(Error* error, string* config_str) {
    492   string security_mode = GetSecurityMode();
    493   if (security_mode == kSecurityModeNone) {
    494     // Nothing need to be done for open network.
    495     return true;
    496   }
    497 
    498   if (security_mode == kSecurityModeRSN) {
    499     string passphrase = GetPassphrase();
    500     if (passphrase.empty()) {
    501       Error::PopulateAndLog(
    502           error,
    503           Error::kInvalidConfiguration,
    504           base::StringPrintf("Passphrase not set for security mode: %s",
    505                              security_mode.c_str()),
    506           FROM_HERE);
    507       return false;
    508     }
    509 
    510     base::StringAppendF(config_str, "%s=2\n", kHostapdConfigKeyWpa);
    511     base::StringAppendF(config_str,
    512                         "%s=%s\n",
    513                         kHostapdConfigKeyRsnPairwise,
    514                         kHostapdDefaultRsnPairwise);
    515     base::StringAppendF(config_str,
    516                         "%s=%s\n",
    517                         kHostapdConfigKeyWpaKeyMgmt,
    518                         kHostapdDefaultWpaKeyMgmt);
    519     base::StringAppendF(config_str,
    520                         "%s=%s\n",
    521                         kHostapdConfigKeyWpaPassphrase,
    522                         passphrase.c_str());
    523     return true;
    524   }
    525 
    526   Error::PopulateAndLog(
    527       error,
    528       Error::kInvalidConfiguration,
    529       base::StringPrintf("Invalid security mode: %s", security_mode.c_str()),
    530       FROM_HERE);
    531   return false;
    532 }
    533 
    534 }  // namespace apmanager
    535