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 32using std::string; 33 34namespace apmanager { 35 36// static 37const char Config::kHostapdConfigKeyBridgeInterface[] = "bridge"; 38const char Config::kHostapdConfigKeyChannel[] = "channel"; 39const char Config::kHostapdConfigKeyControlInterface[] = "ctrl_interface"; 40const char Config::kHostapdConfigKeyControlInterfaceGroup[] = 41 "ctrl_interface_group"; 42const char Config::kHostapdConfigKeyDriver[] = "driver"; 43const char Config::kHostapdConfigKeyFragmThreshold[] = "fragm_threshold"; 44const char Config::kHostapdConfigKeyHTCapability[] = "ht_capab"; 45const char Config::kHostapdConfigKeyHwMode[] = "hw_mode"; 46const char Config::kHostapdConfigKeyIeee80211ac[] = "ieee80211ac"; 47const char Config::kHostapdConfigKeyIeee80211n[] = "ieee80211n"; 48const char Config::kHostapdConfigKeyIgnoreBroadcastSsid[] = 49 "ignore_broadcast_ssid"; 50const char Config::kHostapdConfigKeyInterface[] = "interface"; 51const char Config::kHostapdConfigKeyRsnPairwise[] = "rsn_pairwise"; 52const char Config::kHostapdConfigKeyRtsThreshold[] = "rts_threshold"; 53const char Config::kHostapdConfigKeySsid[] = "ssid"; 54const char Config::kHostapdConfigKeyWepDefaultKey[] = "wep_default_key"; 55const char Config::kHostapdConfigKeyWepKey0[] = "wep_key0"; 56const char Config::kHostapdConfigKeyWpa[] = "wpa"; 57const char Config::kHostapdConfigKeyWpaKeyMgmt[] = "wpa_key_mgmt"; 58const char Config::kHostapdConfigKeyWpaPassphrase[] = "wpa_passphrase"; 59 60const char Config::kHostapdHwMode80211a[] = "a"; 61const char Config::kHostapdHwMode80211b[] = "b"; 62const char Config::kHostapdHwMode80211g[] = "g"; 63 64// static 65const uint16_t Config::kPropertyDefaultChannel = 6; 66const uint16_t Config::kPropertyDefaultServerAddressIndex = 0; 67const bool Config::kPropertyDefaultHiddenNetwork = false; 68 69// static 70const char Config::kHostapdDefaultDriver[] = "nl80211"; 71const char Config::kHostapdDefaultRsnPairwise[] = "CCMP"; 72const char Config::kHostapdDefaultWpaKeyMgmt[] = "WPA-PSK"; 73// Fragmentation threshold: disabled. 74const int Config::kHostapdDefaultFragmThreshold = 2346; 75// RTS threshold: disabled. 76const int Config::kHostapdDefaultRtsThreshold = 2347; 77 78// static 79const uint16_t Config::kBand24GHzChannelLow = 1; 80const uint16_t Config::kBand24GHzChannelHigh = 13; 81const uint32_t Config::kBand24GHzBaseFrequency = 2412; 82const uint16_t Config::kBand5GHzChannelLow = 34; 83const uint16_t Config::kBand5GHzChannelHigh = 165; 84const uint16_t Config::kBand5GHzBaseFrequency = 5170; 85 86// static 87const int Config::kSsidMinLength = 1; 88const int Config::kSsidMaxLength = 32; 89const int Config::kPassphraseMinLength = 8; 90const int Config::kPassphraseMaxLength = 63; 91 92Config::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 107Config::~Config() {} 108 109// static. 110bool 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 123bool 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 136bool 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 149bool 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 164bool 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 178bool 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 190bool 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 202bool 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 270bool 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 278bool 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 286void Config::SetSsid(const string& ssid) { 287 adaptor_->SetSsid(ssid); 288} 289 290string Config::GetSsid() const { 291 return adaptor_->GetSsid(); 292} 293 294void Config::SetInterfaceName(const std::string& interface_name) { 295 adaptor_->SetInterfaceName(interface_name); 296} 297 298string Config::GetInterfaceName() const { 299 return adaptor_->GetInterfaceName(); 300} 301 302void Config::SetSecurityMode(const std::string& mode) { 303 adaptor_->SetSecurityMode(mode); 304} 305 306string Config::GetSecurityMode() const { 307 return adaptor_->GetSecurityMode(); 308} 309 310void Config::SetPassphrase(const std::string& passphrase) { 311 adaptor_->SetPassphrase(passphrase); 312} 313 314string Config::GetPassphrase() const { 315 return adaptor_->GetPassphrase(); 316} 317 318void Config::SetHwMode(const std::string& hw_mode) { 319 adaptor_->SetHwMode(hw_mode); 320} 321 322string Config::GetHwMode() const { 323 return adaptor_->GetHwMode(); 324} 325 326void Config::SetOperationMode(const std::string& op_mode) { 327 adaptor_->SetOperationMode(op_mode); 328} 329 330string Config::GetOperationMode() const { 331 return adaptor_->GetOperationMode(); 332} 333 334void Config::SetChannel(uint16_t channel) { 335 adaptor_->SetChannel(channel); 336} 337 338uint16_t Config::GetChannel() const { 339 return adaptor_->GetChannel(); 340} 341 342void Config::SetHiddenNetwork(bool hidden_network) { 343 adaptor_->SetHiddenNetwork(hidden_network); 344} 345 346bool Config::GetHiddenNetwork() const { 347 return adaptor_->GetHiddenNetwork(); 348} 349 350void Config::SetBridgeInterface(const std::string& interface_name) { 351 adaptor_->SetBridgeInterface(interface_name); 352} 353 354string Config::GetBridgeInterface() const { 355 return adaptor_->GetBridgeInterface(); 356} 357 358void Config::SetServerAddressIndex(uint16_t index) { 359 adaptor_->SetServerAddressIndex(index); 360} 361 362uint16_t Config::GetServerAddressIndex() const { 363 return adaptor_->GetServerAddressIndex(); 364} 365 366void Config::SetFullDeviceControl(bool full_control) { 367 adaptor_->SetFullDeviceControl(full_control); 368} 369 370bool Config::GetFullDeviceControl() const { 371 return adaptor_->GetFullDeviceControl(); 372} 373 374bool 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 428bool 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 448bool 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 491bool 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