blob: 12d9e59aa4c2e3ee343595321e8e414d574ccad8 [file] [log] [blame]
mukesh agrawalb54601c2011-06-07 17:39:22 -07001// Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
2// 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 agrawal6e277772011-09-29 15:04:23 -070014#include "shill/wpa_supplicant.h"
15
16using std::map;
17using std::set;
mukesh agrawalb54601c2011-06-07 17:39:22 -070018using std::string;
mukesh agrawal6e277772011-09-29 15:04:23 -070019using std::vector;
mukesh agrawalb54601c2011-06-07 17:39:22 -070020
21namespace shill {
22
mukesh agrawalb54601c2011-06-07 17:39:22 -070023WiFiEndpoint::WiFiEndpoint(
mukesh agrawal6e277772011-09-29 15:04:23 -070024 const map<string, ::DBus::Variant> &properties) {
mukesh agrawalb54601c2011-06-07 17:39:22 -070025 // XXX will segfault on missing properties
26 ssid_ =
mukesh agrawal6e277772011-09-29 15:04:23 -070027 properties.find(wpa_supplicant::kBSSPropertySSID)->second.
mukesh agrawalb54601c2011-06-07 17:39:22 -070028 operator std::vector<uint8_t>();
29 bssid_ =
mukesh agrawal6e277772011-09-29 15:04:23 -070030 properties.find(wpa_supplicant::kBSSPropertyBSSID)->second.
mukesh agrawalb54601c2011-06-07 17:39:22 -070031 operator std::vector<uint8_t>();
32 signal_strength_ =
mukesh agrawal15908392011-11-16 18:29:25 +000033 properties.find(wpa_supplicant::kBSSPropertySignal)->second.
34 reader().get_int16();
Chris Masone092df3e2011-08-22 09:41:39 -070035 network_mode_ = ParseMode(
mukesh agrawal6e277772011-09-29 15:04:23 -070036 properties.find(wpa_supplicant::kBSSPropertyMode)->second);
37 security_mode_ = ParseSecurity(properties);
mukesh agrawalb54601c2011-06-07 17:39:22 -070038
Chris Masone092df3e2011-08-22 09:41:39 -070039 if (network_mode_.empty()) {
mukesh agrawalb54601c2011-06-07 17:39:22 -070040 // XXX log error?
41 }
42
43 ssid_string_ = string(ssid_.begin(), ssid_.end());
44 ssid_hex_ = base::HexEncode(&(*ssid_.begin()), ssid_.size());
45 bssid_string_ = StringPrintf("%02x:%02x:%02x:%02x:%02x:%02x",
46 bssid_[0], bssid_[1], bssid_[2],
47 bssid_[3], bssid_[4], bssid_[5]);
48 bssid_hex_ = base::HexEncode(&(*bssid_.begin()), bssid_.size());
49}
50
51WiFiEndpoint::~WiFiEndpoint() {}
52
Chris Masone092df3e2011-08-22 09:41:39 -070053// static
54uint32_t WiFiEndpoint::ModeStringToUint(const std::string &mode_string) {
55 if (mode_string == flimflam::kModeManaged)
mukesh agrawal6e277772011-09-29 15:04:23 -070056 return wpa_supplicant::kNetworkModeInfrastructureInt;
Chris Masone092df3e2011-08-22 09:41:39 -070057 else if (mode_string == flimflam::kModeAdhoc)
mukesh agrawal6e277772011-09-29 15:04:23 -070058 return wpa_supplicant::kNetworkModeAdHocInt;
Chris Masone092df3e2011-08-22 09:41:39 -070059 else
60 NOTIMPLEMENTED() << "Shill dos not support " << mode_string
61 << " mode at this time.";
62 return 0;
63}
64
mukesh agrawal6e277772011-09-29 15:04:23 -070065const vector<uint8_t> &WiFiEndpoint::ssid() const {
mukesh agrawalb54601c2011-06-07 17:39:22 -070066 return ssid_;
67}
68
69const string &WiFiEndpoint::ssid_string() const {
70 return ssid_string_;
71}
72
73const string &WiFiEndpoint::ssid_hex() const {
74 return ssid_hex_;
75}
76
77const string &WiFiEndpoint::bssid_string() const {
78 return bssid_string_;
79}
80
81const string &WiFiEndpoint::bssid_hex() const {
82 return bssid_hex_;
83}
84
85int16_t WiFiEndpoint::signal_strength() const {
86 return signal_strength_;
87}
88
Chris Masone092df3e2011-08-22 09:41:39 -070089const string &WiFiEndpoint::network_mode() const {
mukesh agrawal6e277772011-09-29 15:04:23 -070090 return network_mode_;
91}
92
93const string &WiFiEndpoint::security_mode() const {
94 return security_mode_;
mukesh agrawalb54601c2011-06-07 17:39:22 -070095}
96
Chris Masone092df3e2011-08-22 09:41:39 -070097// static
mukesh agrawal8a3188d2011-12-01 20:56:44 +000098WiFiEndpoint *WiFiEndpoint::MakeOpenEndpoint(
99 const string &ssid, const string &bssid) {
100 map <string, ::DBus::Variant> args;
101 ::DBus::MessageIter writer;
102
103 writer = args[wpa_supplicant::kBSSPropertySSID].writer();
104 writer << vector<uint8_t>(ssid.begin(), ssid.end());
105
106 string bssid_nosep;
107 RemoveChars(bssid, ":", &bssid_nosep);
108 vector<uint8_t> bssid_bytes;
109 base::HexStringToBytes(bssid_nosep, &bssid_bytes);
110 writer = args[wpa_supplicant::kBSSPropertyBSSID].writer();
111 writer << bssid_bytes;
112
113 args[wpa_supplicant::kBSSPropertySignal].writer().append_int16(0);
114 args[wpa_supplicant::kBSSPropertyMode].writer().append_string(
115 wpa_supplicant::kNetworkModeInfrastructure);
116 // We indicate this is an open BSS by leaving out all security properties.
117
118 return new WiFiEndpoint(args);
119}
120
121// static
mukesh agrawal6e277772011-09-29 15:04:23 -0700122const char *WiFiEndpoint::ParseMode(const string &mode_string) {
123 if (mode_string == wpa_supplicant::kNetworkModeInfrastructure) {
Chris Masone092df3e2011-08-22 09:41:39 -0700124 return flimflam::kModeManaged;
mukesh agrawal6e277772011-09-29 15:04:23 -0700125 } else if (mode_string == wpa_supplicant::kNetworkModeAdHoc) {
Chris Masone092df3e2011-08-22 09:41:39 -0700126 return flimflam::kModeAdhoc;
mukesh agrawal6e277772011-09-29 15:04:23 -0700127 } else if (mode_string == wpa_supplicant::kNetworkModeAccessPoint) {
Chris Masone092df3e2011-08-22 09:41:39 -0700128 NOTREACHED() << "Shill does not support AP mode at this time.";
129 return NULL;
mukesh agrawalb54601c2011-06-07 17:39:22 -0700130 } else {
Chris Masone092df3e2011-08-22 09:41:39 -0700131 NOTREACHED() << "Unknown WiFi endpoint mode!";
132 return NULL;
mukesh agrawalb54601c2011-06-07 17:39:22 -0700133 }
134}
135
mukesh agrawal6e277772011-09-29 15:04:23 -0700136// static
137const char *WiFiEndpoint::ParseSecurity(
138 const map<string, ::DBus::Variant> &properties) {
139 set<KeyManagement> rsn_key_management_methods;
140 if (ContainsKey(properties, wpa_supplicant::kPropertyRSN)) {
141 // TODO(quiche): check type before casting
142 const map<string, ::DBus::Variant> rsn_properties(
143 properties.find(wpa_supplicant::kPropertyRSN)->second.
144 operator map<string, ::DBus::Variant>());
145 ParseKeyManagementMethods(rsn_properties, &rsn_key_management_methods);
146 }
147
148 set<KeyManagement> wpa_key_management_methods;
149 if (ContainsKey(properties, wpa_supplicant::kPropertyWPA)) {
mukesh agrawal165e6142011-11-22 02:22:56 +0000150 // TODO(quiche): check type before casting
mukesh agrawal6e277772011-09-29 15:04:23 -0700151 const map<string, ::DBus::Variant> rsn_properties(
152 properties.find(wpa_supplicant::kPropertyWPA)->second.
153 operator map<string, ::DBus::Variant>());
154 ParseKeyManagementMethods(rsn_properties, &wpa_key_management_methods);
155 }
156
157 bool wep_privacy = false;
158 if (ContainsKey(properties, wpa_supplicant::kPropertyPrivacy)) {
159 wep_privacy = properties.find(wpa_supplicant::kPropertyPrivacy)->second.
160 reader().get_bool();
161 }
162
163 if (ContainsKey(rsn_key_management_methods, kKeyManagement802_1x) ||
164 ContainsKey(wpa_key_management_methods, kKeyManagement802_1x)) {
165 return flimflam::kSecurity8021x;
166 } else if (ContainsKey(rsn_key_management_methods, kKeyManagementPSK)) {
167 return flimflam::kSecurityRsn;
168 } else if (ContainsKey(wpa_key_management_methods, kKeyManagementPSK)) {
169 return flimflam::kSecurityWpa;
170 } else if (wep_privacy) {
171 return flimflam::kSecurityWep;
172 } else {
173 return flimflam::kSecurityNone;
174 }
175}
176
177// static
178void WiFiEndpoint::ParseKeyManagementMethods(
179 const map<string, ::DBus::Variant> &security_method_properties,
180 set<KeyManagement> *key_management_methods) {
181 if (!ContainsKey(security_method_properties,
182 wpa_supplicant::kSecurityMethodPropertyKeyManagement)) {
183 return;
184 }
185
186 // TODO(quiche): check type before cast
187 const vector<string> key_management_vec =
188 security_method_properties.
189 find(wpa_supplicant::kSecurityMethodPropertyKeyManagement)->second.
190 operator vector<string>();
191 for (vector<string>::const_iterator it = key_management_vec.begin();
192 it != key_management_vec.end();
193 ++it) {
194 if (EndsWith(*it, wpa_supplicant::kKeyManagementMethodSuffixEAP, true)) {
195 key_management_methods->insert(kKeyManagement802_1x);
196 } else if (
197 EndsWith(*it, wpa_supplicant::kKeyManagementMethodSuffixPSK, true)) {
198 key_management_methods->insert(kKeyManagementPSK);
199 }
200 }
201}
202
mukesh agrawalb54601c2011-06-07 17:39:22 -0700203} // namespace shill