blob: 01d5a427e16832eb04c84b66030fe9a5cf7cb48c [file] [log] [blame]
Thieu Lee41a72d2012-02-06 20:46:51 +00001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
mukesh agrawalb54601c2011-06-07 17:39:22 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Chris Masone092df3e2011-08-22 09:41:39 -07005#include "shill/wifi_endpoint.h"
6
7#include <base/logging.h>
mukesh agrawal6e277772011-09-29 15:04:23 -07008#include <base/stl_util-inl.h>
mukesh agrawalb54601c2011-06-07 17:39:22 -07009#include <base/stringprintf.h>
10#include <base/string_number_conversions.h>
mukesh agrawal6e277772011-09-29 15:04:23 -070011#include <base/string_util.h>
Chris Masone092df3e2011-08-22 09:41:39 -070012#include <chromeos/dbus/service_constants.h>
mukesh agrawalb54601c2011-06-07 17:39:22 -070013
mukesh agrawal16bc1b82012-02-09 18:38:26 -080014#include "shill/wifi.h"
mukesh agrawal6e277772011-09-29 15:04:23 -070015#include "shill/wpa_supplicant.h"
16
17using std::map;
18using std::set;
mukesh agrawalb54601c2011-06-07 17:39:22 -070019using std::string;
mukesh agrawal6e277772011-09-29 15:04:23 -070020using std::vector;
mukesh agrawalb54601c2011-06-07 17:39:22 -070021
22namespace shill {
23
mukesh agrawalb54601c2011-06-07 17:39:22 -070024WiFiEndpoint::WiFiEndpoint(
Thieu Lee41a72d2012-02-06 20:46:51 +000025 const map<string, ::DBus::Variant> &properties)
26 : frequency_(0) {
mukesh agrawalb54601c2011-06-07 17:39:22 -070027 // XXX will segfault on missing properties
28 ssid_ =
mukesh agrawal6e277772011-09-29 15:04:23 -070029 properties.find(wpa_supplicant::kBSSPropertySSID)->second.
mukesh agrawalb54601c2011-06-07 17:39:22 -070030 operator std::vector<uint8_t>();
31 bssid_ =
mukesh agrawal6e277772011-09-29 15:04:23 -070032 properties.find(wpa_supplicant::kBSSPropertyBSSID)->second.
mukesh agrawalb54601c2011-06-07 17:39:22 -070033 operator std::vector<uint8_t>();
34 signal_strength_ =
mukesh agrawal15908392011-11-16 18:29:25 +000035 properties.find(wpa_supplicant::kBSSPropertySignal)->second.
36 reader().get_int16();
Thieu Lee41a72d2012-02-06 20:46:51 +000037 map<string, ::DBus::Variant>::const_iterator it =
38 properties.find(wpa_supplicant::kBSSPropertyFrequency);
39 if (it != properties.end())
40 frequency_ = it->second.reader().get_uint16();
Chris Masone092df3e2011-08-22 09:41:39 -070041 network_mode_ = ParseMode(
mukesh agrawal6e277772011-09-29 15:04:23 -070042 properties.find(wpa_supplicant::kBSSPropertyMode)->second);
43 security_mode_ = ParseSecurity(properties);
mukesh agrawalb54601c2011-06-07 17:39:22 -070044
Chris Masone092df3e2011-08-22 09:41:39 -070045 if (network_mode_.empty()) {
mukesh agrawalb54601c2011-06-07 17:39:22 -070046 // XXX log error?
47 }
48
49 ssid_string_ = string(ssid_.begin(), ssid_.end());
mukesh agrawal16bc1b82012-02-09 18:38:26 -080050 WiFi::SanitizeSSID(&ssid_string_);
mukesh agrawalb54601c2011-06-07 17:39:22 -070051 ssid_hex_ = base::HexEncode(&(*ssid_.begin()), ssid_.size());
52 bssid_string_ = StringPrintf("%02x:%02x:%02x:%02x:%02x:%02x",
53 bssid_[0], bssid_[1], bssid_[2],
54 bssid_[3], bssid_[4], bssid_[5]);
55 bssid_hex_ = base::HexEncode(&(*bssid_.begin()), bssid_.size());
56}
57
58WiFiEndpoint::~WiFiEndpoint() {}
59
Chris Masone092df3e2011-08-22 09:41:39 -070060// static
61uint32_t WiFiEndpoint::ModeStringToUint(const std::string &mode_string) {
62 if (mode_string == flimflam::kModeManaged)
mukesh agrawal6e277772011-09-29 15:04:23 -070063 return wpa_supplicant::kNetworkModeInfrastructureInt;
Chris Masone092df3e2011-08-22 09:41:39 -070064 else if (mode_string == flimflam::kModeAdhoc)
mukesh agrawal6e277772011-09-29 15:04:23 -070065 return wpa_supplicant::kNetworkModeAdHocInt;
Chris Masone092df3e2011-08-22 09:41:39 -070066 else
67 NOTIMPLEMENTED() << "Shill dos not support " << mode_string
68 << " mode at this time.";
69 return 0;
70}
71
mukesh agrawal6e277772011-09-29 15:04:23 -070072const vector<uint8_t> &WiFiEndpoint::ssid() const {
mukesh agrawalb54601c2011-06-07 17:39:22 -070073 return ssid_;
74}
75
76const string &WiFiEndpoint::ssid_string() const {
77 return ssid_string_;
78}
79
80const string &WiFiEndpoint::ssid_hex() const {
81 return ssid_hex_;
82}
83
84const string &WiFiEndpoint::bssid_string() const {
85 return bssid_string_;
86}
87
88const string &WiFiEndpoint::bssid_hex() const {
89 return bssid_hex_;
90}
91
92int16_t WiFiEndpoint::signal_strength() const {
93 return signal_strength_;
94}
95
Thieu Lee41a72d2012-02-06 20:46:51 +000096uint16 WiFiEndpoint::frequency() const {
97 return frequency_;
98}
99
Chris Masone092df3e2011-08-22 09:41:39 -0700100const string &WiFiEndpoint::network_mode() const {
mukesh agrawal6e277772011-09-29 15:04:23 -0700101 return network_mode_;
102}
103
104const string &WiFiEndpoint::security_mode() const {
105 return security_mode_;
mukesh agrawalb54601c2011-06-07 17:39:22 -0700106}
107
Chris Masone092df3e2011-08-22 09:41:39 -0700108// static
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000109WiFiEndpoint *WiFiEndpoint::MakeOpenEndpoint(
110 const string &ssid, const string &bssid) {
111 map <string, ::DBus::Variant> args;
112 ::DBus::MessageIter writer;
113
114 writer = args[wpa_supplicant::kBSSPropertySSID].writer();
115 writer << vector<uint8_t>(ssid.begin(), ssid.end());
116
117 string bssid_nosep;
118 RemoveChars(bssid, ":", &bssid_nosep);
119 vector<uint8_t> bssid_bytes;
120 base::HexStringToBytes(bssid_nosep, &bssid_bytes);
121 writer = args[wpa_supplicant::kBSSPropertyBSSID].writer();
122 writer << bssid_bytes;
123
124 args[wpa_supplicant::kBSSPropertySignal].writer().append_int16(0);
125 args[wpa_supplicant::kBSSPropertyMode].writer().append_string(
126 wpa_supplicant::kNetworkModeInfrastructure);
127 // We indicate this is an open BSS by leaving out all security properties.
128
129 return new WiFiEndpoint(args);
130}
131
132// static
mukesh agrawal6e277772011-09-29 15:04:23 -0700133const char *WiFiEndpoint::ParseMode(const string &mode_string) {
134 if (mode_string == wpa_supplicant::kNetworkModeInfrastructure) {
Chris Masone092df3e2011-08-22 09:41:39 -0700135 return flimflam::kModeManaged;
mukesh agrawal6e277772011-09-29 15:04:23 -0700136 } else if (mode_string == wpa_supplicant::kNetworkModeAdHoc) {
Chris Masone092df3e2011-08-22 09:41:39 -0700137 return flimflam::kModeAdhoc;
mukesh agrawal6e277772011-09-29 15:04:23 -0700138 } else if (mode_string == wpa_supplicant::kNetworkModeAccessPoint) {
Chris Masone092df3e2011-08-22 09:41:39 -0700139 NOTREACHED() << "Shill does not support AP mode at this time.";
140 return NULL;
mukesh agrawalb54601c2011-06-07 17:39:22 -0700141 } else {
Chris Masone092df3e2011-08-22 09:41:39 -0700142 NOTREACHED() << "Unknown WiFi endpoint mode!";
143 return NULL;
mukesh agrawalb54601c2011-06-07 17:39:22 -0700144 }
145}
146
mukesh agrawal6e277772011-09-29 15:04:23 -0700147// static
148const char *WiFiEndpoint::ParseSecurity(
149 const map<string, ::DBus::Variant> &properties) {
150 set<KeyManagement> rsn_key_management_methods;
151 if (ContainsKey(properties, wpa_supplicant::kPropertyRSN)) {
152 // TODO(quiche): check type before casting
153 const map<string, ::DBus::Variant> rsn_properties(
154 properties.find(wpa_supplicant::kPropertyRSN)->second.
155 operator map<string, ::DBus::Variant>());
156 ParseKeyManagementMethods(rsn_properties, &rsn_key_management_methods);
157 }
158
159 set<KeyManagement> wpa_key_management_methods;
160 if (ContainsKey(properties, wpa_supplicant::kPropertyWPA)) {
mukesh agrawal165e6142011-11-22 02:22:56 +0000161 // TODO(quiche): check type before casting
mukesh agrawal6e277772011-09-29 15:04:23 -0700162 const map<string, ::DBus::Variant> rsn_properties(
163 properties.find(wpa_supplicant::kPropertyWPA)->second.
164 operator map<string, ::DBus::Variant>());
165 ParseKeyManagementMethods(rsn_properties, &wpa_key_management_methods);
166 }
167
168 bool wep_privacy = false;
169 if (ContainsKey(properties, wpa_supplicant::kPropertyPrivacy)) {
170 wep_privacy = properties.find(wpa_supplicant::kPropertyPrivacy)->second.
171 reader().get_bool();
172 }
173
174 if (ContainsKey(rsn_key_management_methods, kKeyManagement802_1x) ||
175 ContainsKey(wpa_key_management_methods, kKeyManagement802_1x)) {
176 return flimflam::kSecurity8021x;
177 } else if (ContainsKey(rsn_key_management_methods, kKeyManagementPSK)) {
178 return flimflam::kSecurityRsn;
179 } else if (ContainsKey(wpa_key_management_methods, kKeyManagementPSK)) {
180 return flimflam::kSecurityWpa;
181 } else if (wep_privacy) {
182 return flimflam::kSecurityWep;
183 } else {
184 return flimflam::kSecurityNone;
185 }
186}
187
188// static
189void WiFiEndpoint::ParseKeyManagementMethods(
190 const map<string, ::DBus::Variant> &security_method_properties,
191 set<KeyManagement> *key_management_methods) {
192 if (!ContainsKey(security_method_properties,
193 wpa_supplicant::kSecurityMethodPropertyKeyManagement)) {
194 return;
195 }
196
197 // TODO(quiche): check type before cast
198 const vector<string> key_management_vec =
199 security_method_properties.
200 find(wpa_supplicant::kSecurityMethodPropertyKeyManagement)->second.
201 operator vector<string>();
202 for (vector<string>::const_iterator it = key_management_vec.begin();
203 it != key_management_vec.end();
204 ++it) {
205 if (EndsWith(*it, wpa_supplicant::kKeyManagementMethodSuffixEAP, true)) {
206 key_management_methods->insert(kKeyManagement802_1x);
207 } else if (
208 EndsWith(*it, wpa_supplicant::kKeyManagementMethodSuffixPSK, true)) {
209 key_management_methods->insert(kKeyManagementPSK);
210 }
211 }
212}
213
mukesh agrawalb54601c2011-06-07 17:39:22 -0700214} // namespace shill