Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(40)

Side by Side Diff: components/wifi/wifi_service_mac.mm

Issue 64683014: Mac OS X-specific implementation of Networking Private API. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Made networkingPrivateApi available on OS X. Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « components/wifi/wifi_service.cc ('k') | components/wifi/wifi_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2013 The Chromium 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
5 #include "components/wifi/wifi_service.h"
6
7 #include "base/bind.h"
8 #include "base/message_loop/message_loop.h"
9 #include "components/onc/onc_constants.h"
10
11 #import <CoreWLAN/CoreWLAN.h>
12
13 /*
14 @interface WLANListener : NSObject {
15 NSMutableArray* i_interfaces;
16 }
17 @end
18
19 @implementation WLANListener
20
21 -(void) listInterfaces
22 {
23 NSLog(@"listInterfaces");
24 [i_interfaces enumerateObjectsUsingBlock:^(
25 id obj,
26 NSUInteger idx,
27 BOOL *stop)
28 {
29 CWInterface *iface = obj;
30 NSLog( @"iface %@, SSID %@, BSSID %@", iface, iface.ssid, iface.bssid);
31 }];
32 }
33
34
35 -(void) handleInterfaceNotification:(NSNotification*) notification
36 {
37 NSLog(@"Notification Received");
38 [self listInterfaces];
39 }
40
41 - (void) monitorWifi
42 {
43 NSLog(@"monitorWifi");
44
45 [[NSNotificationCenter defaultCenter]
46 addObserver:self
47 selector:@selector(handleInterfaceNotification:)
48 name:CWModeDidChangeNotification
49 object:nil];
50 [[NSNotificationCenter defaultCenter]
51 addObserver:self
52 selector:@selector(handleInterfaceNotification:)
53 name:CWSSIDDidChangeNotification
54 object:nil];
55 [[NSNotificationCenter defaultCenter]
56 addObserver:self
57 selector:@selector(handleInterfaceNotification:)
58 name:CWBSSIDDidChangeNotification
59 object:nil];
60 [[NSNotificationCenter defaultCenter]
61 addObserver:self
62 selector:@selector(handleInterfaceNotification:)
63 name:CWCountryCodeDidChangeNotification
64 object:nil];
65 [[NSNotificationCenter defaultCenter]
66 addObserver:self
67 selector:@selector(handleInterfaceNotification:)
68 name:CWLinkDidChangeNotification
69 object:nil];
70 [[NSNotificationCenter defaultCenter]
71 addObserver:self
72 selector:@selector(handleInterfaceNotification:)
73 name:CWPowerDidChangeNotification
74 object:nil];
75
76 NSMutableArray* ifaces = [NSMutableArray new];
77 NSSet *wifiInterfaces = [CWInterface interfaceNames];
78 [wifiInterfaces enumerateObjectsUsingBlock:^(NSString *ifName, BOOL *stop)
79 {
80 CWInterface *iface = [CWInterface interfaceWithName:ifName];
81 if ( iface ) {
82 [ifaces addObject:iface];
83 }
84 }];
85 i_interfaces = ifaces;
86
87 [self listInterfaces];
88 }
89 @end
90 */
91 namespace wifi {
92
93 // Implementation of WiFiService for Windows.
94 class WiFiServiceImpl : public WiFiService, base::NonThreadSafe {
95 public:
96 WiFiServiceImpl();
97 virtual ~WiFiServiceImpl();
98
99 // WiFiService interface implementation.
100 virtual void Initialize(
101 scoped_refptr<base::SequencedTaskRunner> task_runner) OVERRIDE;
102
103 virtual void UnInitialize() OVERRIDE;
104
105 // Get Properties of network identified by |network_guid|. Populates
106 // |properties| on success, |error| on failure.
107 virtual void GetProperties(const std::string& network_guid,
108 DictionaryValue* properties,
109 std::string* error) OVERRIDE;
110
111 // Set Properties of network identified by |network_guid|. Populates |error|
112 // on failure.
113 virtual void SetProperties(const std::string& network_guid,
114 scoped_ptr<base::DictionaryValue> properties,
115 std::string* error) OVERRIDE;
116
117 // Get list of visible networks. Populates |network_list| on success.
118 virtual void GetVisibleNetworks(ListValue* network_list) OVERRIDE;
119
120 // Request network scan. Send |NetworkListChanged| event on completion.
121 virtual void RequestNetworkScan() OVERRIDE;
122
123 // Start connect to network identified by |network_guid|. Populates |error|
124 // on failure.
125 virtual void StartConnect(const std::string& network_guid,
126 std::string* error) OVERRIDE;
127
128 // Start disconnect from network identified by |network_guid|. Populates
129 // |error| on failure.
130 virtual void StartDisconnect(const std::string& network_guid,
131 std::string* error) OVERRIDE;
132
133 // Set observers to run when |NetworksChanged| and |NetworksListChanged|
134 // events needs to be sent. Notifications are posted on |message_loop_proxy|.
135 virtual void SetEventObservers(
136 scoped_refptr<base::MessageLoopProxy> message_loop_proxy,
137 const NetworkGuidListCallback& networks_changed_observer,
138 const NetworkGuidListCallback& network_list_changed_observer) OVERRIDE;
139
140 private:
141 // Check |nsError| and if is not |nil|, then store |error_name|
142 // into |error|.
143 bool CheckError(NSError* nsError,
144 const char* error_name,
145 std::string* error) const;
146
147 // Get |ssid| from unique |network_guid|.
148 NSString* SSIDFromGUID(const std::string& network_guid) const {
149 return [NSString stringWithUTF8String:network_guid.c_str()];
150 }
151
152 // Get unique |network_guid| string based on |ssid|.
153 std::string GUIDFromSSID(NSString* ssid) const {
154 if (ssid == nil)
155 return std::string();
156 return std::string([ssid UTF8String]);
157 }
158
159 // Populate |properties| from |network|.
160 void NetworkPropertiesFromCWNetwork(const CWNetwork* network,
161 NetworkProperties* properties) const;
162
163 // Convert |CWSecurityMode| into onc::wifi::k{WPA|WEP}* security constant.
164 std::string SecurityFromCWSecurityMode(CWSecurityMode security) const;
165
166 // Get the list of visible wireless networks. If |network_guid| is not empty,
167 // then only return that network.
168 NSError* GetVisibleNetworkList(const std::string& network_guid,
169 NetworkList* network_list);
170
171 // Sort networks, so connected/connecting is up front, then by type:
172 // Ethernet, WiFi, Cellular, VPN
173 static void SortNetworks(NetworkList* networks);
174
175 // Notify |network_list_changed_observer_| that list of visible networks has
176 // changed to |networks|.
177 void NotifyNetworkListChanged(const NetworkList& networks);
178
179 // Notify |networks_changed_observer_| that network |network_guid| status has
180 // changed.
181 void NotifyNetworkChanged(const std::string& network_guid);
182
183 CWInterface* interface_;
184 //WLANListener* listener_;
185
186 // Observer to get notified when network(s) have changed (e.g. connect).
187 NetworkGuidListCallback networks_changed_observer_;
188 // Observer to get notified when network list has changed (scan complete).
189 NetworkGuidListCallback network_list_changed_observer_;
190 // MessageLoopProxy to post events on UI thread.
191 scoped_refptr<base::MessageLoopProxy> message_loop_proxy_;
192 // Task runner for worker tasks.
193 scoped_refptr<base::SequencedTaskRunner> task_runner_;
194
195 // Temporary storage of network properties indexed by |network_guid|.
196 DictionaryValue network_properties_;
197 };
198
199 WiFiServiceImpl::WiFiServiceImpl() {
200 }
201
202 WiFiServiceImpl::~WiFiServiceImpl() {
203 }
204
205 void WiFiServiceImpl::Initialize(
206 scoped_refptr<base::SequencedTaskRunner> task_runner) {
207 task_runner_.swap(task_runner);
208 interface_ = [CWInterface interface];
209 //listener_ = [WLANListener new];
210 }
211
212 void WiFiServiceImpl::UnInitialize() {}
213
214 void WiFiServiceImpl::GetProperties(const std::string& network_guid,
215 DictionaryValue* properties,
216 std::string* error) {
217 NetworkList network;
218 NSError* nsError = GetVisibleNetworkList(network_guid, &network);
219 if (CheckError(nsError, "Error.GetProperties", error))
220 return;
221
222 if (!network.empty()) {
223 properties->Swap(network.front().ToValue(false).get());
224 } else {
225 *error = "Error.NotFound";
226 }
227 }
228
229 void WiFiServiceImpl::SetProperties(
230 const std::string& network_guid,
231 scoped_ptr<base::DictionaryValue> properties,
232 std::string* error) {
233 network_properties_.SetWithoutPathExpansion(network_guid,
234 properties.release());
235 }
236
237 void WiFiServiceImpl::GetVisibleNetworks(ListValue* network_list) {
238 NetworkList networks;
239 NSError* nsError = GetVisibleNetworkList(std::string(), &networks);
240 if (nsError == nil && !networks.empty()) {
241 SortNetworks(&networks);
242 for (WiFiService::NetworkList::const_iterator it = networks.begin();
243 it != networks.end();
244 ++it) {
245 scoped_ptr<DictionaryValue> network(it->ToValue(true));
246 network_list->Append(network.release());
247 }
248 }
249 }
250
251 void WiFiServiceImpl::RequestNetworkScan() {
252 NetworkList networks;
253 NSError* nsError = GetVisibleNetworkList(std::string(), &networks);
254 if (nsError == nil && !networks.empty()) {
255 NotifyNetworkListChanged(networks);
256 }
257 }
258
259 void WiFiServiceImpl::StartConnect(const std::string& network_guid,
260 std::string* error) {
261 NSError* nsError = nil;
262 NSSet* networks = [interface_
263 scanForNetworksWithName:SSIDFromGUID(network_guid)
264 error:&nsError];
265
266 if (CheckError(nsError, "Error.scanForNetworksWithName", error))
267 return;
268
269 CWNetwork* network = [networks anyObject];
270 if (network != nil) {
271 // Notify that currently connected network is being disconnected.
272 NotifyNetworkChanged(GUIDFromSSID([interface_ ssid]));
273 // Check whether WiFi Password is set in |network_properties_|
274 DictionaryValue* properties;
275 DictionaryValue* wifi;
276 std::string passphrase;
277 NSString* nsPassword = nil;
278 if (network_properties_.GetDictionaryWithoutPathExpansion(network_guid,
279 &properties) &&
280 properties->GetDictionary(onc::network_type::kWiFi, &wifi) &&
281 wifi->GetString(onc::wifi::kPassphrase, &passphrase)) {
282 nsPassword = [NSString stringWithUTF8String:passphrase.c_str()];
283 }
284
285 if ([interface_ associateToNetwork:network
286 password:nsPassword
287 error:&nsError]) {
288 NotifyNetworkChanged(network_guid);
289 } else {
290 [interface_ setPower:NO error:&nsError];
291 [interface_ setPower:YES error:&nsError];
292 if (CheckError(nsError, "Error.associateToNetwork", error))
293 return;
294 NotifyNetworkChanged(GUIDFromSSID([interface_ ssid]));
295 }
296 } else {
297 *error = "Error.NotFound";
298 }
299 }
300
301 void WiFiServiceImpl::StartDisconnect(const std::string& network_guid,
302 std::string* error) {
303 if (NSOrderedSame == [[interface_ ssid] compare:SSIDFromGUID(network_guid)]) {
304 [interface_ disassociate];
305 NotifyNetworkChanged(network_guid);
306 } else {
307 *error = "not-connected";
308 }
309 }
310
311 void WiFiServiceImpl::SetEventObservers(
312 scoped_refptr<base::MessageLoopProxy> message_loop_proxy,
313 const NetworkGuidListCallback& networks_changed_observer,
314 const NetworkGuidListCallback& network_list_changed_observer) {
315 message_loop_proxy_.swap(message_loop_proxy);
316 networks_changed_observer_ = networks_changed_observer;
317 network_list_changed_observer_ = network_list_changed_observer;
318 }
319
320 NSError* WiFiServiceImpl::GetVisibleNetworkList(const std::string& network_guid,
321 NetworkList* network_list) {
322
323 NSError* nsError = nil;
324 NSString* networkName = nil;
325
326 if (!network_guid.empty())
327 networkName = SSIDFromGUID(network_guid);
328
329 NSSet* networks = [interface_ scanForNetworksWithName:networkName
330 error:&nsError];
331 if (nsError != nil)
332 return nsError;
333
334 std::map<std::string, NetworkProperties&> network_guids;
335
336 CWNetwork* network;
337 for(network in networks) {
338 NetworkProperties network_properties;
339 NetworkPropertiesFromCWNetwork(network, &network_properties);
340
341 if (network_guids.find(network_properties.guid) == network_guids.end()) {
342 network_list->push_back(network_properties);
343 network_guids.insert(
344 std::pair<std::string, NetworkProperties&>(
345 network_properties.guid, network_list->back()));
346 } else {
347 NetworkProperties& existing = network_guids.at(network_properties.guid);
348 existing.frequency_set.insert(*network_properties.frequency_set.begin());
349 }
350 }
351 return nil;
352 }
353
354 bool WiFiServiceImpl::CheckError(NSError* nsError,
355 const char* error_name,
356 std::string* error) const {
357 if (nsError != nil) {
358 *error = error_name;
359 return true;
360 }
361 return false;
362 }
363
364 void WiFiServiceImpl::NetworkPropertiesFromCWNetwork(
365 const CWNetwork* network,
366 NetworkProperties* properties) const {
367
368 if (NSOrderedSame == [[network ssid] compare:[interface_ ssid]])
369 properties->connection_state = onc::connection_state::kConnected;
370 else
371 properties->connection_state = onc::connection_state::kNotConnected;
372
373 properties->ssid = [[network ssid] UTF8String];
374 properties->name = properties->ssid;
375 properties->guid = GUIDFromSSID([network ssid]);
376 properties->type = onc::network_type::kWiFi;
377
378 properties->bssid = [[network bssid] UTF8String];
379 if ([[network wlanChannel] channelBand] == kCWChannelBand2GHz)
380 properties->frequency = kFrequency2400;
381 else
382 properties->frequency = kFrequency5000;
383 properties->frequency_set.insert(properties->frequency);
384 properties->security =
385 SecurityFromCWSecurityMode([[network securityMode] intValue]);
386
387 properties->signal_strength = [[network rssi] intValue];
388 }
389
390 std::string WiFiServiceImpl::SecurityFromCWSecurityMode(
391 CWSecurityMode security) const {
392 switch (security) {
393 case kCWSecurityModeWPA_Enterprise:
394 case kCWSecurityModeWPA2_Enterprise:
395 return onc::wifi::kWPA_EAP;
396 case kCWSecurityModeWPA_PSK:
397 case kCWSecurityModeWPA2_PSK:
398 return onc::wifi::kWPA_PSK;
399 case kCWSecurityModeWEP:
400 return onc::wifi::kWEP_PSK;
401 case kCWSecurityModeOpen:
402 return onc::wifi::kNone;
403 // TODO(mef): Figure out correct mapping.
404 case kCWSecurityModeWPS:
405 case kCWSecurityModeDynamicWEP:
406 default:
407 return onc::wifi::kWPA_EAP;
408 }
409 return onc::wifi::kWPA_EAP;
410 }
411
412 void WiFiServiceImpl::SortNetworks(NetworkList* networks) {
413 networks->sort(NetworkProperties::OrderByType);
414 }
415
416 void WiFiServiceImpl::NotifyNetworkListChanged(const NetworkList& networks) {
417 if (network_list_changed_observer_.is_null())
418 return;
419
420 NetworkGuidList current_networks;
421 for (NetworkList::const_iterator it = networks.begin();
422 it != networks.end();
423 ++it) {
424 current_networks.push_back(it->guid);
425 }
426
427 message_loop_proxy_->PostTask(
428 FROM_HERE,
429 base::Bind(network_list_changed_observer_, current_networks));
430 }
431
432 void WiFiServiceImpl::NotifyNetworkChanged(const std::string& network_guid) {
433 if (networks_changed_observer_.is_null())
434 return;
435
436 DLOG(INFO) << "NotifyNetworkChanged: " << network_guid;
437 NetworkGuidList changed_networks(1, network_guid);
438 message_loop_proxy_->PostTask(
439 FROM_HERE,
440 base::Bind(networks_changed_observer_, changed_networks));
441 }
442
443 WiFiService* WiFiService::Create() { return new WiFiServiceImpl(); }
444
445 } // namespace wifi
OLDNEW
« no previous file with comments | « components/wifi/wifi_service.cc ('k') | components/wifi/wifi_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698