blob: ef8620f2d5cf2bf3d71b6a620e5fd62bc8cc569f [file] [log] [blame]
// Copyright 2014 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "apmanager/config.h"
#include <base/strings/stringprintf.h>
#include <chromeos/dbus/service_constants.h>
using chromeos::dbus_utils::AsyncEventSequencer;
using chromeos::dbus_utils::ExportedObjectManager;
using chromeos::ErrorPtr;
using std::string;
namespace apmanager {
// static
const char Config::kHostapdConfigKeyBridgeInterface[] = "bridge";
const char Config::kHostapdConfigKeyChannel[] = "channel";
const char Config::kHostapdConfigKeyControlInterface[] = "ctrl_interface";
const char Config::kHostapdConfigKeyDriver[] = "driver";
const char Config::kHostapdConfigKeyFragmThreshold[] = "fragm_threshold";
const char Config::kHostapdConfigKeyHwMode[] = "hw_mode";
const char Config::kHostapdConfigKeyIeee80211ac[] = "ieee80211ac";
const char Config::kHostapdConfigKeyIeee80211n[] = "ieee80211n";
const char Config::kHostapdConfigKeyIgnoreBroadcastSsid[] =
"ignore_broadcast_ssid";
const char Config::kHostapdConfigKeyInterface[] = "interface";
const char Config::kHostapdConfigKeyRsnPairwise[] = "rsn_pairwise";
const char Config::kHostapdConfigKeyRtsThreshold[] = "rts_threshold";
const char Config::kHostapdConfigKeySsid[] = "ssid";
const char Config::kHostapdConfigKeyWepDefaultKey[] = "wep_default_key";
const char Config::kHostapdConfigKeyWepKey0[] = "wep_key0";
const char Config::kHostapdConfigKeyWpa[] = "wpa";
const char Config::kHostapdConfigKeyWpaKeyMgmt[] = "wpa_key_mgmt";
const char Config::kHostapdConfigKeyWpaPassphrase[] = "wpa_passphrase";
const char Config::kHostapdHwMode80211a[] = "a";
const char Config::kHostapdHwMode80211b[] = "b";
const char Config::kHostapdHwMode80211g[] = "g";
// static
const uint16_t Config::kPropertyDefaultChannel = 6;
const uint16_t Config::kPropertyDefaultServerAddressIndex = 0;
const bool Config::kPropertyDefaultHiddenNetwork = false;
// static
const char Config::kHostapdDefaultDriver[] = "nl80211";
const char Config::kHostapdDefaultRsnPairwise[] = "CCMP";
const char Config::kHostapdDefaultWpaKeyMgmt[] = "WPA-PSK";
// Fragmentation threshold: disabled.
const int Config::kHostapdDefaultFragmThreshold = 2346;
// RTS threshold: disabled.
const int Config::kHostapdDefaultRtsThreshold = 2347;
Config::Config(const string& service_path)
: org::chromium::apmanager::ConfigAdaptor(this),
dbus_path_(dbus::ObjectPath(
base::StringPrintf("%s/config", service_path.c_str()))) {
// Initialize default configuration values.
SetSecurityMode(kSecurityModeNone);
SetHwMode(kHwMode80211g);
SetOperationMode(kOperationModeServer);
SetServerAddressIndex(kPropertyDefaultServerAddressIndex);
SetChannel(kPropertyDefaultChannel);
SetHiddenNetwork(kPropertyDefaultHiddenNetwork);
}
Config::~Config() {}
void Config::RegisterAsync(ExportedObjectManager* object_manager,
AsyncEventSequencer* sequencer) {
CHECK(!dbus_object_) << "Already registered";
dbus_object_.reset(
new chromeos::dbus_utils::DBusObject(
object_manager,
object_manager ? object_manager->GetBus() : nullptr,
dbus_path_));
RegisterWithDBusObject(dbus_object_.get());
dbus_object_->RegisterAsync(
sequencer->GetHandler("Config.RegisterAsync() failed.", true));
}
bool Config::GenerateConfigFile(ErrorPtr* error, string* config_str) {
// SSID.
string ssid = GetSsid();
if (ssid.empty()) {
chromeos::Error::AddTo(
error, FROM_HERE, chromeos::errors::dbus::kDomain, kConfigError,
"SSID not specified");
return false;
}
base::StringAppendF(
config_str, "%s=%s\n", kHostapdConfigKeySsid, ssid.c_str());
// Channel.
base::StringAppendF(
config_str, "%s=%d\n", kHostapdConfigKeyChannel, GetChannel());
// Hardware mode.
if (!AppendHwMode(error, config_str)) {
return false;
}
// Interface.
if (!AppendInterface(error, config_str)) {
return false;
}
// Security mode configurations.
if (!AppendSecurityMode(error, config_str)) {
return false;
}
// Hostapd default configurations.
if (!AppendHostapdDefaults(error, config_str)) {
return false;
}
return true;
}
bool Config::AppendHwMode(ErrorPtr* error, std::string* config_str) {
string hw_mode = GetHwMode();
string hostapd_hw_mode;
if (hw_mode == kHwMode80211a) {
hostapd_hw_mode = kHostapdHwMode80211a;
} else if (hw_mode == kHwMode80211b) {
hostapd_hw_mode = kHostapdHwMode80211b;
} else if (hw_mode == kHwMode80211g) {
hostapd_hw_mode = kHostapdHwMode80211g;
} else if (hw_mode == kHwMode80211n) {
// Use 802.11a for 5GHz channel and 802.11g for 2.4GHz channel
if (GetChannel() >= 34) {
hostapd_hw_mode = kHostapdHwMode80211a;
} else {
hostapd_hw_mode = kHostapdHwMode80211g;
}
base::StringAppendF(config_str, "%s=1\n", kHostapdConfigKeyIeee80211n);
// TODO(zqiu): Determine HT Capabilities based on the interface PHY's
// capababilites.
} else if (hw_mode == kHwMode80211ac) {
if (GetChannel() >= 34) {
hostapd_hw_mode = kHostapdHwMode80211a;
} else {
hostapd_hw_mode = kHostapdHwMode80211g;
}
base::StringAppendF(config_str, "%s=1\n", kHostapdConfigKeyIeee80211ac);
// TODO(zqiu): Determine VHT Capabilities based on the interface PHY's
// capababilites.
} else {
chromeos::Error::AddToPrintf(
error, FROM_HERE, chromeos::errors::dbus::kDomain, kConfigError,
"Invalid hardware mode: %s", hw_mode.c_str());
return false;
}
base::StringAppendF(
config_str, "%s=%s\n", kHostapdConfigKeyHwMode, hostapd_hw_mode.c_str());
return true;
}
bool Config::AppendHostapdDefaults(ErrorPtr* error,
std::string* config_str) {
// Driver: NL80211.
base::StringAppendF(
config_str, "%s=%s\n", kHostapdConfigKeyDriver, kHostapdDefaultDriver);
// Fragmentation threshold: disabled.
base::StringAppendF(config_str,
"%s=%d\n",
kHostapdConfigKeyFragmThreshold,
kHostapdDefaultFragmThreshold);
// RTS threshold: disabled.
base::StringAppendF(config_str,
"%s=%d\n",
kHostapdConfigKeyRtsThreshold,
kHostapdDefaultRtsThreshold);
return true;
}
bool Config::AppendInterface(ErrorPtr* error,
std::string* config_str) {
string interface = GetInterfaceName();
if (interface.empty()) {
// TODO(zqiu): Ask manager for available ap mode interface.
return false;
}
base::StringAppendF(
config_str, "%s=%s\n", kHostapdConfigKeyInterface, interface.c_str());
return true;
}
bool Config::AppendSecurityMode(ErrorPtr* error,
std::string* config_str) {
string security_mode = GetSecurityMode();
if (security_mode == kSecurityModeNone) {
// Nothing need to be done for open network.
return true;
}
if (security_mode == kSecurityModeRSN) {
string passphrase = GetPassphrase();
if (passphrase.empty()) {
chromeos::Error::AddToPrintf(
error, FROM_HERE, chromeos::errors::dbus::kDomain, kConfigError,
"Passphrase not set for security mode: %s", security_mode.c_str());
return false;
}
base::StringAppendF(config_str, "%s=2\n", kHostapdConfigKeyWpa);
base::StringAppendF(config_str,
"%s=%s\n",
kHostapdConfigKeyRsnPairwise,
kHostapdDefaultRsnPairwise);
base::StringAppendF(config_str,
"%s=%s\n",
kHostapdConfigKeyWpaKeyMgmt,
kHostapdDefaultWpaKeyMgmt);
base::StringAppendF(config_str,
"%s=%s\n",
kHostapdConfigKeyWpaPassphrase,
passphrase.c_str());
return true;
}
chromeos::Error::AddToPrintf(
error, FROM_HERE, chromeos::errors::dbus::kDomain, kConfigError,
"Invalid security mode: %s", security_mode.c_str());
return false;
}
} // namespace apmanager