OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | |
tbarzic
2014/01/08 23:06:23
the copyright header is out of date :P
mef
2014/01/09 22:41:46
Done.
| |
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 #import <netinet/in.h> | |
8 #import <CoreWLAN/CoreWLAN.h> | |
9 #import <SystemConfiguration/SystemConfiguration.h> | |
10 | |
11 #include "base/bind.h" | |
12 #include "base/mac/scoped_cftyperef.h" | |
13 #include "base/mac/scoped_nsautorelease_pool.h" | |
14 #include "base/mac/scoped_nsobject.h" | |
15 #include "base/message_loop/message_loop.h" | |
16 #include "base/strings/sys_string_conversions.h" | |
17 #include "components/onc/onc_constants.h" | |
18 | |
19 namespace { | |
20 // Declare notification names from the 10.7 SDK. | |
21 const char* kCWSSIDDidChangeNotification_chrome = | |
22 "com.apple.coreWLAN.notification.ssid"; | |
23 } // namespace | |
24 | |
25 #if !defined(MAC_OS_X_VERSION_10_7) || \ | |
26 MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 | |
27 | |
28 // Local definitions of API added in Mac OS X 10.7 | |
29 | |
30 @interface CWInterface (LionAPI) | |
31 - (BOOL)associateToNetwork:(CWNetwork*)network | |
32 password:(NSString*)password | |
33 error:(NSError**)error; | |
34 - (NSSet*)scanForNetworksWithName:(NSString*)networkName | |
35 error:(NSError**)error; | |
36 @end | |
37 | |
38 enum CWChannelBand { | |
39 kCWChannelBandUnknown = 0, | |
40 kCWChannelBand2GHz = 1, | |
41 kCWChannelBand5GHz = 2, | |
42 }; | |
43 | |
44 @interface CWChannel : NSObject | |
45 @property(readonly) CWChannelBand channelBand; | |
46 @end | |
47 | |
48 @interface CWNetwork (LionAPI) | |
49 @property(readonly) CWChannel* wlanChannel; | |
50 @end | |
51 | |
52 #endif // 10.7 | |
53 | |
54 namespace wifi { | |
55 | |
56 const char kErrorAssociateToNetwork[] = "Error.AssociateToNetwork"; | |
57 const char kErrorGetProperties[] = "Error.GetProperties"; | |
58 const char kErrorNotConnected[] = "Error.NotConnected"; | |
59 const char kErrorNotFound[] = "Error.NotFound"; | |
60 const char kErrorNotImplemented[] = "Error.NotImplemented"; | |
61 const char kErrorScanForNetworksWithName[] = "Error.ScanForNetworksWithName"; | |
62 | |
63 // Implementation of WiFiService for Mac OS X. | |
64 class WiFiServiceMac : public WiFiService { | |
65 public: | |
66 WiFiServiceMac(); | |
67 virtual ~WiFiServiceMac(); | |
68 | |
69 // WiFiService interface implementation. | |
70 virtual void Initialize( | |
71 scoped_refptr<base::SequencedTaskRunner> task_runner) OVERRIDE; | |
72 | |
73 virtual void UnInitialize() OVERRIDE; | |
74 | |
75 virtual void GetProperties(const std::string& network_guid, | |
76 base::DictionaryValue* properties, | |
77 std::string* error) OVERRIDE; | |
78 | |
79 virtual void GetManagedProperties(const std::string& network_guid, | |
80 base::DictionaryValue* managed_properties, | |
81 std::string* error) OVERRIDE; | |
82 | |
83 virtual void GetState(const std::string& network_guid, | |
84 base::DictionaryValue* properties, | |
85 std::string* error) OVERRIDE; | |
86 | |
87 virtual void SetProperties(const std::string& network_guid, | |
88 scoped_ptr<base::DictionaryValue> properties, | |
89 std::string* error) OVERRIDE; | |
90 | |
91 virtual void CreateNetwork(bool shared, | |
92 scoped_ptr<base::DictionaryValue> properties, | |
93 std::string* network_guid, | |
94 std::string* error) OVERRIDE; | |
95 | |
96 virtual void GetVisibleNetworks(const std::string& network_type, | |
97 base::ListValue* network_list) OVERRIDE; | |
98 | |
99 virtual void RequestNetworkScan() OVERRIDE; | |
100 | |
101 virtual void StartConnect(const std::string& network_guid, | |
102 std::string* error) OVERRIDE; | |
103 | |
104 virtual void StartDisconnect(const std::string& network_guid, | |
105 std::string* error) OVERRIDE; | |
106 | |
107 virtual void SetEventObservers( | |
108 scoped_refptr<base::MessageLoopProxy> message_loop_proxy, | |
109 const NetworkGuidListCallback& networks_changed_observer, | |
110 const NetworkGuidListCallback& network_list_changed_observer) OVERRIDE; | |
111 | |
112 private: | |
113 // Check |ns_error| and if is not |nil|, then store |error_name| | |
114 // into |error|. | |
115 bool CheckError(NSError* ns_error, | |
116 const char* error_name, | |
117 std::string* error) const; | |
118 | |
119 // Get |ssid| from unique |network_guid|. | |
120 NSString* SSIDFromGUID(const std::string& network_guid) const { | |
121 return base::SysUTF8ToNSString(network_guid); | |
122 } | |
123 | |
124 // Get unique |network_guid| string based on |ssid|. | |
125 std::string GUIDFromSSID(NSString* ssid) const { | |
126 return base::SysNSStringToUTF8(ssid); | |
127 } | |
128 | |
129 // Populate |properties| from |network|. | |
130 void NetworkPropertiesFromCWNetwork(const CWNetwork* network, | |
131 NetworkProperties* properties) const; | |
132 | |
133 // Convert |CWSecurityMode| into onc::wifi::k{WPA|WEP}* security constant. | |
134 std::string SecurityFromCWSecurityMode(CWSecurityMode security) const; | |
135 | |
136 // Wait up to |kMaxAttempts| with |kAttemptDelayMs| delay for connection | |
137 // to network with |network_guid|. Notify that |NetworkChanged| upon success. | |
138 void WaitForNetworkConnect(const std::string& network_guid, int attempt); | |
139 | |
140 // Get the list of visible wireless networks. If |network_guid| is not empty, | |
141 // then only return that network. | |
142 NSError* GetVisibleNetworkList(const std::string& network_guid, | |
143 NetworkList* network_list); | |
144 | |
145 // Handle notification from |wlan_observer_|; | |
tbarzic
2014/01/08 23:06:23
end comment with . instead of ;
Here and througho
mef
2014/01/09 22:41:46
Done.
| |
146 void OnWlanObserverNotification(); | |
147 | |
148 // Notify |network_list_changed_observer_| that list of visible networks has | |
149 // changed to |networks|. | |
150 void NotifyNetworkListChanged(const NetworkList& networks); | |
151 | |
152 // Notify |networks_changed_observer_| that network |network_guid| status has | |
153 // changed. | |
154 void NotifyNetworkChanged(const std::string& network_guid); | |
155 | |
156 // CoreWLAN.Framework bundle. | |
157 base::scoped_nsobject<NSBundle> bundle_; | |
158 // Default interface. | |
159 base::scoped_nsobject<CWInterface> interface_; | |
160 // WLAN Notifications observer. | |
161 base::scoped_nsobject<NSObject> wlan_observer_; | |
162 | |
163 // Observer to get notified when network(s) have changed (e.g. connect). | |
164 NetworkGuidListCallback networks_changed_observer_; | |
165 // Observer to get notified when network list has changed (scan complete). | |
166 NetworkGuidListCallback network_list_changed_observer_; | |
167 // MessageLoopProxy to post events on UI thread. | |
168 scoped_refptr<base::MessageLoopProxy> message_loop_proxy_; | |
169 // Task runner for worker tasks. | |
170 scoped_refptr<base::SequencedTaskRunner> task_runner_; | |
171 // Cache of network list collected by GetVisibleNetworks. | |
172 NetworkList networks_; | |
173 // Temporary storage of network properties indexed by |network_guid|. | |
174 base::DictionaryValue network_properties_; | |
175 // If |false|, then |networks_changed_observer_| is not notified. | |
176 bool enable_notify_network_changed_; | |
177 // Number of attempts to check that network has connected successfully. | |
178 static const int kConnectionCheckMaxAttempts = 200; | |
179 // Delay between attempts to check that network has connected successfully. | |
180 static const int kConnectionCheckAttemptDelayMs = 100; | |
181 }; | |
182 | |
183 WiFiServiceMac::WiFiServiceMac() : enable_notify_network_changed_(true) { | |
184 } | |
185 | |
186 WiFiServiceMac::~WiFiServiceMac() { | |
187 } | |
188 | |
189 void WiFiServiceMac::Initialize( | |
190 scoped_refptr<base::SequencedTaskRunner> task_runner) { | |
191 // As the WLAN api binding runs on its own thread, we need to provide our own | |
192 // auto release pool. It's simplest to do this as an automatic variable in | |
193 // each method that needs it, to ensure the scoping is correct and does not | |
194 // interfere with any other code using autorelease pools on the thread. | |
195 base::mac::ScopedNSAutoreleasePool auto_pool; | |
196 | |
197 task_runner_.swap(task_runner); | |
198 | |
199 bundle_.reset([[NSBundle alloc] | |
200 initWithPath:@"/System/Library/Frameworks/CoreWLAN.framework"]); | |
201 if (!bundle_) { | |
202 DVLOG(1) << "Failed to load the CoreWLAN framework bundle"; | |
203 return; | |
204 } | |
205 | |
206 Class cw_interface_class = [bundle_ classNamed:@"CWInterface"]; | |
207 interface_.reset([[cw_interface_class interface] retain]); | |
208 if (!bundle_) { | |
209 DVLOG(1) << "Failed to initialize default interface"; | |
210 return; | |
211 } | |
212 | |
213 } | |
214 | |
215 void WiFiServiceMac::UnInitialize() { | |
216 [[NSNotificationCenter defaultCenter] removeObserver:wlan_observer_]; | |
217 } | |
218 | |
219 void WiFiServiceMac::GetProperties(const std::string& network_guid, | |
220 base::DictionaryValue* properties, | |
221 std::string* error) { | |
222 base::mac::ScopedNSAutoreleasePool auto_pool; | |
223 | |
224 if (networks_.empty()) { | |
tbarzic
2014/01/08 23:06:23
I don't think this block is needed (at least if Re
mef
2014/01/09 22:41:46
Done.
| |
225 DVLOG(1) << "GetProperties"; | |
226 NSError* ns_error = GetVisibleNetworkList(std::string(), &networks_); | |
227 if (CheckError(ns_error, kErrorGetProperties, error)) | |
228 return; | |
229 } | |
230 | |
231 for (WiFiService::NetworkList::iterator it = networks_.begin(); | |
232 it != networks_.end(); | |
233 ++it) { | |
234 if (it->guid == network_guid) { | |
tbarzic
2014/01/08 23:06:23
the network's properties should probably be rescan
mef
2014/01/09 22:41:46
Done.
| |
235 bool is_connected = network_guid == GUIDFromSSID([interface_ ssid]); | |
236 it->connection_state = | |
237 is_connected ? onc::connection_state::kConnected : | |
238 onc::connection_state::kNotConnected; | |
239 scoped_ptr<base::DictionaryValue> network(it->ToValue(false)); | |
240 properties->Swap(network.get()); | |
241 DVLOG(1) << *properties; | |
242 return; | |
243 } | |
244 } | |
245 | |
246 *error = kErrorNotFound; | |
247 } | |
248 | |
249 void WiFiServiceMac::GetManagedProperties( | |
250 const std::string& network_guid, | |
251 base::DictionaryValue* managed_properties, | |
252 std::string* error) { | |
253 *error = kErrorNotImplemented; | |
254 } | |
255 | |
256 void WiFiServiceMac::GetState(const std::string& network_guid, | |
257 base::DictionaryValue* properties, | |
258 std::string* error) { | |
259 *error = kErrorNotImplemented; | |
260 } | |
261 | |
262 void WiFiServiceMac::SetProperties( | |
263 const std::string& network_guid, | |
264 scoped_ptr<base::DictionaryValue> properties, | |
265 std::string* error) { | |
266 base::mac::ScopedNSAutoreleasePool auto_pool; | |
267 network_properties_.SetWithoutPathExpansion(network_guid, | |
268 properties.release()); | |
269 } | |
270 | |
271 void WiFiServiceMac::CreateNetwork( | |
272 bool shared, | |
273 scoped_ptr<base::DictionaryValue> properties, | |
274 std::string* network_guid, | |
275 std::string* error) { | |
276 *error = kErrorNotImplemented; | |
277 } | |
278 | |
279 void WiFiServiceMac::GetVisibleNetworks(const std::string& network_type, | |
280 base::ListValue* network_list) { | |
281 if (!network_type.empty() && | |
282 network_type != onc::network_type::kAllTypes && | |
283 network_type != onc::network_type::kWiFi) { | |
284 return; | |
285 } | |
286 | |
287 base::mac::ScopedNSAutoreleasePool auto_pool; | |
288 | |
289 GetVisibleNetworkList(std::string(), &networks_); | |
290 | |
291 // Sort networks, so connected/connecting is up front. | |
292 networks_.sort(NetworkProperties::OrderByType); | |
293 | |
294 for (WiFiService::NetworkList::const_iterator it = networks_.begin(); | |
295 it != networks_.end(); | |
296 ++it) { | |
297 scoped_ptr<base::DictionaryValue> network(it->ToValue(true)); | |
298 network_list->Append(network.release()); | |
299 } | |
300 } | |
301 | |
302 void WiFiServiceMac::RequestNetworkScan() { | |
303 base::mac::ScopedNSAutoreleasePool auto_pool; | |
304 NetworkList networks; | |
305 | |
306 NSError* ns_error = GetVisibleNetworkList(std::string(), &networks); | |
307 if (ns_error == nil && !networks.empty()) { | |
308 NotifyNetworkListChanged(networks); | |
309 } | |
310 } | |
311 | |
312 void WiFiServiceMac::StartConnect(const std::string& network_guid, | |
313 std::string* error) { | |
314 base::mac::ScopedNSAutoreleasePool auto_pool; | |
315 NSError* ns_error = nil; | |
316 | |
317 DVLOG(1) << "*** StartConnect: " << network_guid; | |
318 // Remember previously connected network. | |
319 std::string connected_network_guid = GUIDFromSSID([interface_ ssid]); | |
320 // Check, whether desired network is already connected. | |
321 if (network_guid == connected_network_guid) { | |
322 NotifyNetworkChanged(connected_network_guid); | |
323 return; | |
324 } | |
325 | |
326 NSSet* networks = [interface_ | |
327 scanForNetworksWithName:SSIDFromGUID(network_guid) | |
328 error:&ns_error]; | |
329 | |
330 if (CheckError(ns_error, kErrorScanForNetworksWithName, error)) | |
331 return; | |
332 | |
333 CWNetwork* network = [networks anyObject]; | |
334 if (network == nil) { | |
335 *error = kErrorNotFound; | |
336 return; | |
337 } | |
338 | |
339 // Check whether WiFi Password is set in |network_properties_| | |
340 base::DictionaryValue* properties; | |
341 base::DictionaryValue* wifi; | |
342 std::string passphrase; | |
343 NSString* ns_password = nil; | |
344 if (network_properties_.GetDictionaryWithoutPathExpansion(network_guid, | |
345 &properties) && | |
346 properties->GetDictionary(onc::network_type::kWiFi, &wifi) && | |
347 wifi->GetString(onc::wifi::kPassphrase, &passphrase)) { | |
348 ns_password = base::SysUTF8ToNSString(passphrase); | |
349 } | |
350 | |
351 // Disable automatic network change notifications as they get fired | |
352 // when network is just connected, but not yet accessible (doesn't | |
353 // have valid IP address). | |
354 enable_notify_network_changed_ = false; | |
355 // Number of attempts to associate to network. | |
356 static const int kMaxAssociationAttempts = 3; | |
357 // Try to associate to network several times if timeout or PMK error occurs. | |
358 for (int i = 0; i < kMaxAssociationAttempts; ++i) { | |
359 // Nil out the PMK to prevent stale data from causing invalid PMK error | |
360 // (CoreWLANTypes -3924). | |
361 [interface_ setPairwiseMasterKey:nil error:&ns_error]; | |
362 if ([interface_ associateToNetwork:network | |
363 password:ns_password | |
364 error:&ns_error]) { | |
365 // Notify that previously connected network has changed. | |
366 NotifyNetworkChanged(connected_network_guid); | |
367 | |
368 // Start waiting for network connection state change. WaiForNetworkConnect | |
369 // is async and it'll reset enable_notify_network_changed_. | |
370 if (!networks_changed_observer_.is_null()) { | |
371 WaitForNetworkConnect(network_guid, 0); | |
372 return; | |
373 } | |
374 } else { | |
375 NSInteger error_code = [ns_error code]; | |
376 if (error_code != kCWTimeoutErr && error_code != kCWInvalidPMKErr) { | |
377 break; | |
378 } | |
379 } | |
380 } | |
381 enable_notify_network_changed_ = true; | |
382 CheckError(ns_error, kErrorAssociateToNetwork, error); | |
383 } | |
384 | |
385 void WiFiServiceMac::StartDisconnect(const std::string& network_guid, | |
386 std::string* error) { | |
387 base::mac::ScopedNSAutoreleasePool auto_pool; | |
388 DVLOG(1) << "*** StartDisconnect: " << network_guid; | |
389 | |
390 if (network_guid == GUIDFromSSID([interface_ ssid])) { | |
391 [interface_ disassociate]; | |
392 } else { | |
393 *error = kErrorNotConnected; | |
394 } | |
395 } | |
396 | |
397 void WiFiServiceMac::SetEventObservers( | |
398 scoped_refptr<base::MessageLoopProxy> message_loop_proxy, | |
399 const NetworkGuidListCallback& networks_changed_observer, | |
400 const NetworkGuidListCallback& network_list_changed_observer) { | |
401 base::mac::ScopedNSAutoreleasePool auto_pool; | |
402 message_loop_proxy_.swap(message_loop_proxy); | |
403 networks_changed_observer_ = networks_changed_observer; | |
404 network_list_changed_observer_ = network_list_changed_observer; | |
405 | |
406 // Subscribe to OS notifications. | |
407 wlan_observer_.reset([[NSNotificationCenter defaultCenter] | |
408 addObserverForName:base::SysUTF8ToNSString( | |
409 kCWSSIDDidChangeNotification_chrome) | |
410 object:nil | |
411 queue:nil | |
412 usingBlock:^(NSNotification* notification) { | |
413 task_runner_->PostTask( | |
414 FROM_HERE, | |
415 base::Bind(&WiFiServiceMac::OnWlanObserverNotification, | |
416 base::Unretained(this))); | |
417 }]); | |
418 } | |
419 | |
420 void WiFiServiceMac::WaitForNetworkConnect(const std::string& network_guid, | |
421 int attempt) { | |
422 // If network didn't get connected in |kMaxAttempts|, then restore automatic | |
423 // network change notifications and stop waiting. | |
424 if (attempt > kConnectionCheckMaxAttempts) { | |
425 DLOG(ERROR) << kConnectionCheckMaxAttempts | |
426 << " attempts exceeded waiting for connect to " | |
427 << network_guid; | |
428 // Restore previously suppressed notifications. | |
429 enable_notify_network_changed_ = true; | |
430 return; | |
431 } | |
432 | |
433 // Check whether WiFi network is reachable. | |
434 struct sockaddr_in local_wifi_address; | |
435 bzero(&local_wifi_address, sizeof(local_wifi_address)); | |
436 local_wifi_address.sin_len = sizeof(local_wifi_address); | |
437 local_wifi_address.sin_family = AF_INET; | |
438 local_wifi_address.sin_addr.s_addr = htonl(IN_LINKLOCALNETNUM); | |
439 | |
440 base::ScopedCFTypeRef<SCNetworkReachabilityRef> reachability( | |
441 SCNetworkReachabilityCreateWithAddress( | |
442 kCFAllocatorDefault, | |
443 reinterpret_cast<const struct sockaddr*>(&local_wifi_address))); | |
444 SCNetworkReachabilityFlags flags = 0u; | |
445 if (SCNetworkReachabilityGetFlags(reachability, &flags) && | |
446 (flags & kSCNetworkReachabilityFlagsReachable) && | |
447 (flags & kSCNetworkReachabilityFlagsIsDirect)) { | |
448 DVLOG(1) << "WiFi Connected, Reachable: " << network_guid; | |
449 // Restore previously suppressed notifications. | |
450 enable_notify_network_changed_ = true; | |
451 NotifyNetworkChanged(network_guid); | |
452 } else { | |
453 DVLOG(1) << "Attempt:" << attempt << ", reachability:" << flags; | |
454 // Continue waiting for network connection state change. | |
455 task_runner_->PostDelayedTask( | |
456 FROM_HERE, | |
457 base::Bind(&WiFiServiceMac::WaitForNetworkConnect, | |
458 base::Unretained(this), | |
459 network_guid, | |
460 ++attempt), | |
461 base::TimeDelta::FromMilliseconds(kConnectionCheckAttemptDelayMs)); | |
462 } | |
463 } | |
464 | |
465 | |
466 NSError* WiFiServiceMac::GetVisibleNetworkList(const std::string& network_guid, | |
tbarzic
2014/01/08 23:06:23
Instead of returning network_list here, why don't
mef
2014/01/09 22:41:46
Done.
| |
467 NetworkList* network_list) { | |
468 | |
469 NSError* ns_error = nil; | |
470 NSString* network_name = nil; | |
471 | |
472 DVLOG(1) << "<<< GetVisibleNetworkList: " << network_guid; | |
473 | |
474 if (!network_guid.empty()) | |
475 network_name = SSIDFromGUID(network_guid); | |
476 | |
477 NSSet* networks = [interface_ scanForNetworksWithName:network_name | |
478 error:&ns_error]; | |
479 if (ns_error != nil) | |
480 return ns_error; | |
481 | |
482 std::map<std::string, NetworkProperties*> network_properties_map; | |
483 | |
484 CWNetwork* network; | |
485 // There is one |network| per BSS in |networks|, so go through the set and | |
486 // combine them, paying attention to supported frequencies. | |
487 for (network in networks) { | |
tbarzic
2014/01/08 23:06:23
should network_list be cleared before the loop?
mef
2014/01/09 22:41:46
Done.
| |
488 NetworkProperties network_properties; | |
489 NetworkPropertiesFromCWNetwork(network, &network_properties); | |
490 | |
491 if (network_properties_map.find(network_properties.guid) == | |
492 network_properties_map.end()) { | |
493 network_list->push_back(network_properties); | |
494 network_properties_map[network_properties.guid] = &network_list->back(); | |
495 } else { | |
496 NetworkProperties* existing = network_properties_map.at( | |
497 network_properties.guid); | |
498 existing->frequency_set.insert(*network_properties.frequency_set.begin()); | |
499 } | |
500 } | |
501 DVLOG(1) << ">>> GetVisibleNetworkList: " << network_guid; | |
502 | |
503 return nil; | |
504 } | |
505 | |
506 bool WiFiServiceMac::CheckError(NSError* ns_error, | |
507 const char* error_name, | |
508 std::string* error) const { | |
509 if (ns_error != nil) { | |
510 DLOG(ERROR) << "*** Error:" << error_name << ":" << [ns_error code]; | |
511 *error = error_name; | |
512 return true; | |
513 } | |
514 return false; | |
515 } | |
516 | |
517 void WiFiServiceMac::NetworkPropertiesFromCWNetwork( | |
518 const CWNetwork* network, | |
519 NetworkProperties* properties) const { | |
520 | |
521 if ([[network ssid] compare:[interface_ ssid]] == NSOrderedSame) | |
522 properties->connection_state = onc::connection_state::kConnected; | |
523 else | |
524 properties->connection_state = onc::connection_state::kNotConnected; | |
525 | |
526 properties->ssid = base::SysNSStringToUTF8([network ssid]); | |
527 properties->name = properties->ssid; | |
528 properties->guid = GUIDFromSSID([network ssid]); | |
529 properties->type = onc::network_type::kWiFi; | |
530 | |
531 properties->bssid = base::SysNSStringToUTF8([network bssid]); | |
532 if ([[network wlanChannel] channelBand] == kCWChannelBand2GHz) | |
533 properties->frequency = kFrequency2400; | |
534 else | |
535 properties->frequency = kFrequency5000; | |
536 properties->frequency_set.insert(properties->frequency); | |
537 properties->security = SecurityFromCWSecurityMode( | |
538 static_cast<CWSecurityMode>([[network securityMode] intValue])); | |
539 | |
540 properties->signal_strength = [[network rssi] intValue]; | |
541 } | |
542 | |
543 std::string WiFiServiceMac::SecurityFromCWSecurityMode( | |
544 CWSecurityMode security) const { | |
545 switch (security) { | |
546 case kCWSecurityModeWPA_Enterprise: | |
547 case kCWSecurityModeWPA2_Enterprise: | |
548 return onc::wifi::kWPA_EAP; | |
549 case kCWSecurityModeWPA_PSK: | |
550 case kCWSecurityModeWPA2_PSK: | |
551 return onc::wifi::kWPA_PSK; | |
552 case kCWSecurityModeWEP: | |
553 return onc::wifi::kWEP_PSK; | |
554 case kCWSecurityModeOpen: | |
555 return onc::wifi::kNone; | |
556 // TODO(mef): Figure out correct mapping. | |
557 case kCWSecurityModeWPS: | |
558 case kCWSecurityModeDynamicWEP: | |
559 return onc::wifi::kWPA_EAP; | |
560 } | |
561 return onc::wifi::kWPA_EAP; | |
562 } | |
563 | |
564 void WiFiServiceMac::OnWlanObserverNotification() { | |
565 std::string connected_network_guid = GUIDFromSSID([interface_ ssid]); | |
566 DVLOG(1) << " *** Got Notification: " << connected_network_guid; | |
567 if (connected_network_guid.empty()) { | |
568 // Find previously connected network and notify that it is disconnected. | |
569 for (WiFiService::NetworkList::iterator it = networks_.begin(); | |
570 it != networks_.end(); | |
571 ++it) { | |
572 if (it->connection_state == onc::connection_state::kConnected) { | |
573 it->connection_state = onc::connection_state::kNotConnected; | |
574 NotifyNetworkChanged(it->guid); | |
575 } | |
576 } | |
577 } else { | |
578 NotifyNetworkChanged(connected_network_guid); | |
tbarzic
2014/01/08 23:06:23
You should make sure that networks_ contains the c
mef
2014/01/09 22:41:46
Done.
| |
579 } | |
580 } | |
581 | |
582 void WiFiServiceMac::NotifyNetworkListChanged(const NetworkList& networks) { | |
583 if (network_list_changed_observer_.is_null()) | |
584 return; | |
585 | |
586 NetworkGuidList current_networks; | |
587 for (NetworkList::const_iterator it = networks.begin(); | |
588 it != networks.end(); | |
589 ++it) { | |
590 current_networks.push_back(it->guid); | |
591 } | |
592 | |
593 message_loop_proxy_->PostTask( | |
594 FROM_HERE, | |
595 base::Bind(network_list_changed_observer_, current_networks)); | |
596 } | |
597 | |
598 void WiFiServiceMac::NotifyNetworkChanged(const std::string& network_guid) { | |
599 if (!enable_notify_network_changed_ || networks_changed_observer_.is_null()) | |
600 return; | |
601 | |
602 DVLOG(1) << "NotifyNetworkChanged: " << network_guid; | |
603 NetworkGuidList changed_networks(1, network_guid); | |
604 message_loop_proxy_->PostTask( | |
605 FROM_HERE, | |
606 base::Bind(networks_changed_observer_, changed_networks)); | |
607 } | |
608 | |
609 // static | |
610 WiFiService* WiFiService::Create() { return new WiFiServiceMac(); } | |
611 | |
612 } // namespace wifi | |
OLD | NEW |