• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
Config(Manager * manager,int service_identifier)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 
~Config()107 Config::~Config() {}
108 
109 // static.
GetFrequencyFromChannel(uint16_t channel,uint32_t * freq)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 
ValidateSsid(Error * error,const string & value)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 
ValidateSecurityMode(Error * error,const string & value)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 
ValidatePassphrase(Error * error,const string & value)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 
ValidateHwMode(Error * error,const string & value)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 
ValidateOperationMode(Error * error,const string & value)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 
ValidateChannel(Error * error,const uint16_t & value)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 
GenerateConfigFile(Error * error,string * config_str)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 
ClaimDevice()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 
ReleaseDevice()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 
SetSsid(const string & ssid)286 void Config::SetSsid(const string& ssid) {
287   adaptor_->SetSsid(ssid);
288 }
289 
GetSsid() const290 string Config::GetSsid() const {
291   return adaptor_->GetSsid();
292 }
293 
SetInterfaceName(const std::string & interface_name)294 void Config::SetInterfaceName(const std::string& interface_name) {
295   adaptor_->SetInterfaceName(interface_name);
296 }
297 
GetInterfaceName() const298 string Config::GetInterfaceName() const {
299   return adaptor_->GetInterfaceName();
300 }
301 
SetSecurityMode(const std::string & mode)302 void Config::SetSecurityMode(const std::string& mode) {
303   adaptor_->SetSecurityMode(mode);
304 }
305 
GetSecurityMode() const306 string Config::GetSecurityMode() const {
307   return adaptor_->GetSecurityMode();
308 }
309 
SetPassphrase(const std::string & passphrase)310 void Config::SetPassphrase(const std::string& passphrase) {
311   adaptor_->SetPassphrase(passphrase);
312 }
313 
GetPassphrase() const314 string Config::GetPassphrase() const {
315   return adaptor_->GetPassphrase();
316 }
317 
SetHwMode(const std::string & hw_mode)318 void Config::SetHwMode(const std::string& hw_mode) {
319   adaptor_->SetHwMode(hw_mode);
320 }
321 
GetHwMode() const322 string Config::GetHwMode() const {
323   return adaptor_->GetHwMode();
324 }
325 
SetOperationMode(const std::string & op_mode)326 void Config::SetOperationMode(const std::string& op_mode) {
327   adaptor_->SetOperationMode(op_mode);
328 }
329 
GetOperationMode() const330 string Config::GetOperationMode() const {
331   return adaptor_->GetOperationMode();
332 }
333 
SetChannel(uint16_t channel)334 void Config::SetChannel(uint16_t channel) {
335   adaptor_->SetChannel(channel);
336 }
337 
GetChannel() const338 uint16_t Config::GetChannel() const {
339   return adaptor_->GetChannel();
340 }
341 
SetHiddenNetwork(bool hidden_network)342 void Config::SetHiddenNetwork(bool hidden_network) {
343   adaptor_->SetHiddenNetwork(hidden_network);
344 }
345 
GetHiddenNetwork() const346 bool Config::GetHiddenNetwork() const {
347   return adaptor_->GetHiddenNetwork();
348 }
349 
SetBridgeInterface(const std::string & interface_name)350 void Config::SetBridgeInterface(const std::string& interface_name) {
351   adaptor_->SetBridgeInterface(interface_name);
352 }
353 
GetBridgeInterface() const354 string Config::GetBridgeInterface() const {
355   return adaptor_->GetBridgeInterface();
356 }
357 
SetServerAddressIndex(uint16_t index)358 void Config::SetServerAddressIndex(uint16_t index) {
359   adaptor_->SetServerAddressIndex(index);
360 }
361 
GetServerAddressIndex() const362 uint16_t Config::GetServerAddressIndex() const {
363   return adaptor_->GetServerAddressIndex();
364 }
365 
SetFullDeviceControl(bool full_control)366 void Config::SetFullDeviceControl(bool full_control) {
367   adaptor_->SetFullDeviceControl(full_control);
368 }
369 
GetFullDeviceControl() const370 bool Config::GetFullDeviceControl() const {
371   return adaptor_->GetFullDeviceControl();
372 }
373 
AppendHwMode(Error * error,string * config_str)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 
AppendHostapdDefaults(Error * error,string * config_str)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 
AppendInterface(Error * error,string * config_str)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 
AppendSecurityMode(Error * error,string * config_str)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