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

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: Explicitly track connected_network_guid and use it to notify network disconnect. Created 6 years, 11 months 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
OLDNEW
(Empty)
1 // Copyright 2014 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 #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_nsobject.h"
14 #include "base/message_loop/message_loop.h"
15 #include "base/strings/sys_string_conversions.h"
16 #include "components/onc/onc_constants.h"
17 #include "content/public/browser/browser_thread.h"
18 #include "net/base/network_change_notifier.h"
19
20 #if !defined(MAC_OS_X_VERSION_10_7) || \
21 MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7
22
23 // Local definitions of API added in Mac OS X 10.7
24
25 @interface CWInterface (LionAPI)
26 - (BOOL)associateToNetwork:(CWNetwork*)network
27 password:(NSString*)password
28 error:(NSError**)error;
29 - (NSSet*)scanForNetworksWithName:(NSString*)networkName
30 error:(NSError**)error;
31 @end
32
33 enum CWChannelBand {
34 kCWChannelBandUnknown = 0,
35 kCWChannelBand2GHz = 1,
36 kCWChannelBand5GHz = 2,
37 };
38
39 @interface CWChannel : NSObject
40 @property(readonly) CWChannelBand channelBand;
41 @end
42
43 @interface CWNetwork (LionAPI)
44 @property(readonly) CWChannel* wlanChannel;
45 @end
46
47 #endif // 10.7
48
49 namespace wifi {
50
51 const char kErrorAssociateToNetwork[] = "Error.AssociateToNetwork";
52 const char kErrorInvalidData[] = "Error.InvalidData";
53 const char kErrorNotConnected[] = "Error.NotConnected";
54 const char kErrorNotFound[] = "Error.NotFound";
55 const char kErrorNotImplemented[] = "Error.NotImplemented";
56 const char kErrorScanForNetworksWithName[] = "Error.ScanForNetworksWithName";
57
58 // Implementation of WiFiService for Mac OS X.
59 class WiFiServiceMac : public WiFiService {
60
Robert Sesek 2014/01/27 18:06:56 nit: extra blank line
mef 2014/01/27 19:44:38 Done.
61 // Detect network changes by subscribing NetworkChangeNotifier notifications
62 // on IO thread. Posts |on_network_changed_| to worker pool using
63 // |task_runner_|.
64 class NetworkChangeDetector
65 : public base::RefCountedThreadSafe<
66 NetworkChangeDetector, content::BrowserThread::DeleteOnIOThread>,
67 net::NetworkChangeNotifier::NetworkChangeObserver {
68 public:
69 NetworkChangeDetector(const base::Closure& on_network_changed,
70 scoped_refptr<base::SequencedTaskRunner> task_runner)
71 : on_network_changed_(on_network_changed), task_runner_(task_runner) {
72 }
73
74 void StartOnIOThread() {
75 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
76 net::NetworkChangeNotifier::AddNetworkChangeObserver(this);
77 }
78
79 void StopOnIOThread() {
80 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
81 net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this);
82 }
83
84 private:
85 friend struct content::BrowserThread::DeleteOnThread<
86 content::BrowserThread::IO>;
87 friend class base::DeleteHelper<NetworkChangeDetector>;
88
89 virtual ~NetworkChangeDetector() {
90 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
91 }
92
93 // Handle NetworkChanged notification and post it to worker pool.
94 virtual void OnNetworkChanged(
95 net::NetworkChangeNotifier::ConnectionType type) OVERRIDE {
96 DVLOG(1) << "Received OnNetworkChanged Notification";
97 if (!on_network_changed_.is_null()) {
98 task_runner_->PostTask(FROM_HERE, on_network_changed_);
99 }
100 }
101
102 // Task to post on worker pool when notification is received.
103 const base::Closure on_network_changed_;
104 // Task runner for worker tasks.
105 scoped_refptr<base::SequencedTaskRunner> task_runner_;
106 };
107
108 public:
109 WiFiServiceMac();
110 virtual ~WiFiServiceMac();
111
112 // WiFiService interface implementation.
113 virtual void Initialize(
114 scoped_refptr<base::SequencedTaskRunner> task_runner) OVERRIDE;
115
116 virtual void UnInitialize() OVERRIDE;
117
118 virtual void GetProperties(const std::string& network_guid,
119 base::DictionaryValue* properties,
120 std::string* error) OVERRIDE;
121
122 virtual void GetManagedProperties(const std::string& network_guid,
123 base::DictionaryValue* managed_properties,
124 std::string* error) OVERRIDE;
125
126 virtual void GetState(const std::string& network_guid,
127 base::DictionaryValue* properties,
128 std::string* error) OVERRIDE;
129
130 virtual void SetProperties(const std::string& network_guid,
131 scoped_ptr<base::DictionaryValue> properties,
132 std::string* error) OVERRIDE;
133
134 virtual void CreateNetwork(bool shared,
135 scoped_ptr<base::DictionaryValue> properties,
136 std::string* network_guid,
137 std::string* error) OVERRIDE;
138
139 virtual void GetVisibleNetworks(const std::string& network_type,
140 base::ListValue* network_list) OVERRIDE;
141
142 virtual void RequestNetworkScan() OVERRIDE;
143
144 virtual void StartConnect(const std::string& network_guid,
145 std::string* error) OVERRIDE;
146
147 virtual void StartDisconnect(const std::string& network_guid,
148 std::string* error) OVERRIDE;
149
150 virtual void SetEventObservers(
151 scoped_refptr<base::MessageLoopProxy> message_loop_proxy,
152 const NetworkGuidListCallback& networks_changed_observer,
153 const NetworkGuidListCallback& network_list_changed_observer) OVERRIDE;
154
155 private:
156 // Checks |ns_error| and if is not |nil|, then stores |error_name|
157 // into |error|.
158 bool CheckError(NSError* ns_error,
159 const char* error_name,
160 std::string* error) const;
161
162 // Gets |ssid| from unique |network_guid|.
163 NSString* SSIDFromGUID(const std::string& network_guid) const {
164 return base::SysUTF8ToNSString(network_guid);
165 }
166
167 // Gets unique |network_guid| string based on |ssid|.
168 std::string GUIDFromSSID(NSString* ssid) const {
169 return base::SysNSStringToUTF8(ssid);
170 }
171
172 // Populates |properties| from |network|.
173 void NetworkPropertiesFromCWNetwork(const CWNetwork* network,
174 NetworkProperties* properties) const;
175
176 // Convert s|CWSecurityMode| into onc::wifi::k{WPA|WEP}* security constant.
Robert Sesek 2014/01/27 18:06:56 nit: ^T[ s]
mef 2014/01/27 19:44:38 Done.
177 std::string SecurityFromCWSecurityMode(CWSecurityMode security) const;
178
179 // Waits up to |kMaxAttempts| with |kAttemptDelayMs| delay for connection to
180 // network with |network_guid|. Notifies that |NetworkChanged| upon success.
181 void WaitForNetworkConnect(const std::string& network_guid, int attempt);
182
183 // Gets current |onc::connection_state| for given |network_guid|.
184 std::string GetNetworkConnectionState(const std::string& network_guid) const;
185
186 // Updates |networks_| with the list of visible wireless networks.
187 void UpdateNetworks();
188
189 // Find network by |network_guid| and return iterator to its entry in
190 // |networks_|.
191 NetworkList::iterator FindNetwork(const std::string& network_guid);
192
193 // Handles notification from |wlan_observer_|.
194 void OnWlanObserverNotification();
195
196 // Notifies |network_list_changed_observer_| that list of visible networks has
197 // changed to |networks|.
198 void NotifyNetworkListChanged(const NetworkList& networks);
199
200 // Notifies |networks_changed_observer_| that network |network_guid|
201 // connection state has changed.
202 void NotifyNetworkChanged(const std::string& network_guid);
203
204 // Default interface.
205 base::scoped_nsobject<CWInterface> interface_;
206 // WLAN Notifications observer. |this| doesn't own this reference.
207 id wlan_observer_;
208 // Detects Network Changes. Registered, notified and deleted on IO thread.
209 scoped_refptr<NetworkChangeDetector> network_change_detector_;
210
211 // Observer to get notified when network(s) have changed (e.g. connect).
212 NetworkGuidListCallback networks_changed_observer_;
213 // Observer to get notified when network list has changed (scan complete).
214 NetworkGuidListCallback network_list_changed_observer_;
215 // MessageLoopProxy to post events on UI thread.
216 scoped_refptr<base::MessageLoopProxy> message_loop_proxy_;
217 // Task runner for worker tasks.
218 scoped_refptr<base::SequencedTaskRunner> task_runner_;
219 // Cache of network list collected by GetVisibleNetworks.
220 NetworkList networks_;
221 // Guid of last known connected network.
222 std::string connected_network_guid_;
223 // Temporary storage of network properties indexed by |network_guid|.
224 base::DictionaryValue network_properties_;
225 // Use WeakPtrs for callbacks from |network_change_detector_|.
226 base::WeakPtrFactory<WiFiServiceMac> weak_factory_;
227 // Number of attempts to check that network has connected successfully.
228 static const int kConnectionCheckMaxAttempts = 200;
229 // Delay between attempts to check that network has connected successfully.
230 static const int kConnectionCheckAttemptDelayMs = 100;
231 };
232
233 WiFiServiceMac::WiFiServiceMac() : wlan_observer_(nil), weak_factory_(this) {
234 }
235
236 WiFiServiceMac::~WiFiServiceMac() {
237 }
238
239 void WiFiServiceMac::Initialize(
240 scoped_refptr<base::SequencedTaskRunner> task_runner) {
241 task_runner_.swap(task_runner);
242 interface_.reset([[CWInterface interface] retain]);
243 if (!interface_) {
244 DVLOG(1) << "Failed to initialize default interface.";
245 return;
246 }
247
248 if (![interface_
249 respondsToSelector:@selector(associateToNetwork:password:error:)]) {
250 DVLOG(1) << "CWInterface does not support associateToNetwork.";
251 interface_.reset();
252 return;
253 }
254
255 // Subscribe to NetworkChange notifications.
256 if (!network_change_detector_) {
257 network_change_detector_ = new NetworkChangeDetector(
258 base::Bind(&WiFiServiceMac::OnWlanObserverNotification,
259 weak_factory_.GetWeakPtr()),
260 task_runner_);
261 content::BrowserThread::PostTask(
262 content::BrowserThread::IO,
263 FROM_HERE,
264 base::Bind(&NetworkChangeDetector::StartOnIOThread,
265 network_change_detector_));
266 }
267 }
268
269 void WiFiServiceMac::UnInitialize() {
270 if (wlan_observer_)
271 [[NSNotificationCenter defaultCenter] removeObserver:wlan_observer_];
272 interface_.reset();
273 // Unsubscribe from NetworkChange notifications.
274 if (network_change_detector_) {
275 content::BrowserThread::PostTask(
276 content::BrowserThread::IO,
277 FROM_HERE,
278 base::Bind(&NetworkChangeDetector::StopOnIOThread,
279 network_change_detector_));
280 network_change_detector_ = NULL;
281 }
282 }
283
284 void WiFiServiceMac::GetProperties(const std::string& network_guid,
285 base::DictionaryValue* properties,
286 std::string* error) {
287 NetworkList::iterator it = FindNetwork(network_guid);
288 if (it == networks_.end()) {
289 DVLOG(1) << "Network not found:" << network_guid;
290 *error = kErrorNotFound;
291 return;
292 }
293
294 it->connection_state = GetNetworkConnectionState(network_guid);
295 scoped_ptr<base::DictionaryValue> network(it->ToValue(false));
296 properties->Swap(network.get());
297 DVLOG(1) << *properties;
298 }
299
300 void WiFiServiceMac::GetManagedProperties(
301 const std::string& network_guid,
302 base::DictionaryValue* managed_properties,
303 std::string* error) {
304 *error = kErrorNotImplemented;
305 }
306
307 void WiFiServiceMac::GetState(const std::string& network_guid,
308 base::DictionaryValue* properties,
309 std::string* error) {
310 *error = kErrorNotImplemented;
311 }
312
313 void WiFiServiceMac::SetProperties(
314 const std::string& network_guid,
315 scoped_ptr<base::DictionaryValue> properties,
316 std::string* error) {
317 network_properties_.SetWithoutPathExpansion(network_guid,
318 properties.release());
319 }
320
321 void WiFiServiceMac::CreateNetwork(
322 bool shared,
323 scoped_ptr<base::DictionaryValue> properties,
324 std::string* network_guid,
325 std::string* error) {
326 WiFiService::NetworkProperties network_properties;
327 if (!network_properties.UpdateFromValue(*properties)) {
328 *error = kErrorInvalidData;
329 return;
330 }
331
332 std::string guid = network_properties.ssid;
333 if (FindNetwork(guid) != networks_.end()) {
334 *error = kErrorInvalidData;
335 return;
336 }
337 network_properties_.SetWithoutPathExpansion(guid,
338 properties.release());
339 *network_guid = guid;
340 }
341
342 void WiFiServiceMac::GetVisibleNetworks(const std::string& network_type,
343 base::ListValue* network_list) {
344 if (!network_type.empty() &&
345 network_type != onc::network_type::kAllTypes &&
346 network_type != onc::network_type::kWiFi) {
347 return;
348 }
349
350 if (networks_.empty())
351 UpdateNetworks();
352
353 for (WiFiService::NetworkList::const_iterator it = networks_.begin();
354 it != networks_.end();
355 ++it) {
356 scoped_ptr<base::DictionaryValue> network(it->ToValue(true));
357 network_list->Append(network.release());
358 }
359 }
360
361 void WiFiServiceMac::RequestNetworkScan() {
362 DVLOG(1) << "*** RequestNetworkScan";
363 UpdateNetworks();
364 }
365
366 void WiFiServiceMac::StartConnect(const std::string& network_guid,
367 std::string* error) {
368 NSError* ns_error = nil;
369
370 DVLOG(1) << "*** StartConnect: " << network_guid;
371 // Remember previously connected network.
372 std::string connected_network_guid = GUIDFromSSID([interface_ ssid]);
373 // Check whether desired network is already connected.
374 if (network_guid == connected_network_guid) {
375 NotifyNetworkChanged(connected_network_guid);
376 return;
377 }
378
379 NSSet* networks = [interface_
380 scanForNetworksWithName:SSIDFromGUID(network_guid)
381 error:&ns_error];
382
383 if (CheckError(ns_error, kErrorScanForNetworksWithName, error))
384 return;
385
386 CWNetwork* network = [networks anyObject];
387 if (network == nil) {
388 // System can't find the network, remove it from the |networks_| and notify
389 // observers.
390 NetworkList::iterator it = FindNetwork(connected_network_guid);
391 if (it != networks_.end()) {
392 networks_.erase(it);
393 // Notify observers that list has changed.
394 NotifyNetworkListChanged(networks_);
395 }
396
397 *error = kErrorNotFound;
398 return;
399 }
400
401 // Check whether WiFi Password is set in |network_properties_|.
402 base::DictionaryValue* properties;
403 base::DictionaryValue* wifi;
404 std::string passphrase;
405 NSString* ns_password = nil;
406 if (network_properties_.GetDictionaryWithoutPathExpansion(network_guid,
407 &properties) &&
408 properties->GetDictionary(onc::network_type::kWiFi, &wifi) &&
409 wifi->GetString(onc::wifi::kPassphrase, &passphrase)) {
410 ns_password = base::SysUTF8ToNSString(passphrase);
411 }
412
413 // Number of attempts to associate to network.
414 static const int kMaxAssociationAttempts = 3;
415 // Try to associate to network several times if timeout or PMK error occurs.
416 for (int i = 0; i < kMaxAssociationAttempts; ++i) {
417 // Nil out the PMK to prevent stale data from causing invalid PMK error
418 // (CoreWLANTypes -3924).
419 [interface_ setPairwiseMasterKey:nil error:&ns_error];
420 if (![interface_ associateToNetwork:network
421 password:ns_password
422 error:&ns_error]) {
423 NSInteger error_code = [ns_error code];
424 if (error_code != kCWTimeoutErr && error_code != kCWInvalidPMKErr) {
425 break;
426 }
427 }
428 }
429 CheckError(ns_error, kErrorAssociateToNetwork, error);
430 }
431
432 void WiFiServiceMac::StartDisconnect(const std::string& network_guid,
433 std::string* error) {
434 DVLOG(1) << "*** StartDisconnect: " << network_guid;
435
436 if (network_guid == GUIDFromSSID([interface_ ssid])) {
437 // Power-cycle the interface to disconnect from current network and connect
438 // to default network.
439 NSError* ns_error = nil;
440 [interface_ setPower:NO error:&ns_error];
441 CheckError(ns_error, kErrorAssociateToNetwork, error);
442 [interface_ setPower:YES error:&ns_error];
443 CheckError(ns_error, kErrorAssociateToNetwork, error);
444 } else {
445 *error = kErrorNotConnected;
446 }
447 }
448
449 void WiFiServiceMac::SetEventObservers(
450 scoped_refptr<base::MessageLoopProxy> message_loop_proxy,
451 const NetworkGuidListCallback& networks_changed_observer,
452 const NetworkGuidListCallback& network_list_changed_observer) {
453 message_loop_proxy_.swap(message_loop_proxy);
454 networks_changed_observer_ = networks_changed_observer;
455 network_list_changed_observer_ = network_list_changed_observer;
456
457 // Remove previous OS notifications observer.
458 if (wlan_observer_) {
459 [[NSNotificationCenter defaultCenter] removeObserver:wlan_observer_];
460 wlan_observer_ = nil;
461 }
462
463 // Subscribe to OS notifications.
464 if (!networks_changed_observer_.is_null()) {
465 void (^ns_observer) (NSNotification* notification) =
466 ^(NSNotification* notification) {
467 DVLOG(1) << "Received CWSSIDDidChangeNotification";
468 task_runner_->PostTask(
469 FROM_HERE,
470 base::Bind(&WiFiServiceMac::OnWlanObserverNotification,
471 base::Unretained(this)));
472 };
473
474 wlan_observer_ = [[NSNotificationCenter defaultCenter]
475 addObserverForName:CWSSIDDidChangeNotification
476 object:nil
477 queue:nil
478 usingBlock:ns_observer];
479 }
480
Robert Sesek 2014/01/27 18:06:56 nit: remove blank line
mef 2014/01/27 19:44:38 Done.
481 }
482
483 void WiFiServiceMac::WaitForNetworkConnect(const std::string& network_guid,
484 int attempt) {
485 return;
486 // If network didn't get connected in |kMaxAttempts|, then stop waiting.
487 if (attempt > kConnectionCheckMaxAttempts) {
488 DLOG(ERROR) << kConnectionCheckMaxAttempts
489 << " attempts exceeded waiting for connect to "
490 << network_guid;
491 return;
492 }
493
494 if (GetNetworkConnectionState(network_guid) ==
495 onc::connection_state::kConnected) {
496 DVLOG(1) << "WiFi Connected, Reachable: " << network_guid;
497 NotifyNetworkChanged(network_guid);
498 } else {
499 // Continue waiting for network connection state change.
500 task_runner_->PostDelayedTask(
501 FROM_HERE,
502 base::Bind(&WiFiServiceMac::WaitForNetworkConnect,
503 base::Unretained(this),
504 network_guid,
505 ++attempt),
506 base::TimeDelta::FromMilliseconds(kConnectionCheckAttemptDelayMs));
507 }
508 }
509
510 std::string WiFiServiceMac::GetNetworkConnectionState(
511 const std::string& network_guid) const {
512 if (network_guid != GUIDFromSSID([interface_ ssid]))
513 return onc::connection_state::kNotConnected;
514
515 // Check whether WiFi network is reachable.
516 struct sockaddr_in local_wifi_address;
517 bzero(&local_wifi_address, sizeof(local_wifi_address));
518 local_wifi_address.sin_len = sizeof(local_wifi_address);
519 local_wifi_address.sin_family = AF_INET;
520 local_wifi_address.sin_addr.s_addr = htonl(IN_LINKLOCALNETNUM);
521 base::ScopedCFTypeRef<SCNetworkReachabilityRef> reachability(
522 SCNetworkReachabilityCreateWithAddress(
523 kCFAllocatorDefault,
524 reinterpret_cast<const struct sockaddr*>(&local_wifi_address)));
525 SCNetworkReachabilityFlags flags = 0u;
526 if (SCNetworkReachabilityGetFlags(reachability, &flags) &&
527 (flags & kSCNetworkReachabilityFlagsReachable) &&
528 (flags & kSCNetworkReachabilityFlagsIsDirect)) {
529 // Network is reachable, report is as |kConnected|.
530 return onc::connection_state::kConnected;
531 }
532 // Network is not reachable yet, so it must be |kConnecting|.
533 return onc::connection_state::kConnecting;
534 }
535
536 void WiFiServiceMac::UpdateNetworks() {
537 NSError* ns_error = nil;
538 NSSet* cw_networks = [interface_ scanForNetworksWithName:nil
539 error:&ns_error];
540
541 if (ns_error != nil)
542 return;
543
544 std::map<std::string, NetworkProperties*> network_properties_map;
545 networks_.clear();
546
547 // There is one |cw_network| per BSS in |cw_networks|, so go through the set
548 // and combine them, paying attention to supported frequencies.
549 for (CWNetwork* cw_network in cw_networks) {
550 NetworkProperties network_properties;
551 NetworkPropertiesFromCWNetwork(cw_network, &network_properties);
552
553 if (network_properties_map.find(network_properties.guid) ==
554 network_properties_map.end()) {
555 networks_.push_back(network_properties);
556 network_properties_map[network_properties.guid] = &networks_.back();
557 } else {
558 NetworkProperties* existing = network_properties_map.at(
559 network_properties.guid);
560 existing->frequency_set.insert(*network_properties.frequency_set.begin());
561 }
562 }
563 // Sort networks, so connected/connecting is up front.
564 networks_.sort(NetworkProperties::OrderByType);
565 // Notify observers that list has changed.
566 NotifyNetworkListChanged(networks_);
567 }
568
569 bool WiFiServiceMac::CheckError(NSError* ns_error,
570 const char* error_name,
571 std::string* error) const {
572 if (ns_error != nil) {
573 DLOG(ERROR) << "*** Error:" << error_name << ":" << [ns_error code];
574 *error = error_name;
575 return true;
576 }
577 return false;
578 }
579
580 void WiFiServiceMac::NetworkPropertiesFromCWNetwork(
581 const CWNetwork* network,
582 NetworkProperties* properties) const {
583 std::string network_guid = GUIDFromSSID([network ssid]);
584
585 properties->connection_state = GetNetworkConnectionState(network_guid);
586 properties->ssid = base::SysNSStringToUTF8([network ssid]);
587 properties->name = properties->ssid;
588 properties->guid = network_guid;
589 properties->type = onc::network_type::kWiFi;
590
591 properties->bssid = base::SysNSStringToUTF8([network bssid]);
592 if ([[network wlanChannel] channelBand] == kCWChannelBand2GHz)
593 properties->frequency = kFrequency2400;
594 else
595 properties->frequency = kFrequency5000;
596 properties->frequency_set.insert(properties->frequency);
597 properties->security = SecurityFromCWSecurityMode(
598 static_cast<CWSecurityMode>([[network securityMode] intValue]));
599
600 properties->signal_strength = [[network rssi] intValue];
601 }
602
603 std::string WiFiServiceMac::SecurityFromCWSecurityMode(
604 CWSecurityMode security) const {
605 switch (security) {
606 case kCWSecurityModeWPA_Enterprise:
607 case kCWSecurityModeWPA2_Enterprise:
608 return onc::wifi::kWPA_EAP;
609 case kCWSecurityModeWPA_PSK:
610 case kCWSecurityModeWPA2_PSK:
611 return onc::wifi::kWPA_PSK;
612 case kCWSecurityModeWEP:
613 return onc::wifi::kWEP_PSK;
614 case kCWSecurityModeOpen:
615 return onc::wifi::kNone;
616 // TODO(mef): Figure out correct mapping.
617 case kCWSecurityModeWPS:
618 case kCWSecurityModeDynamicWEP:
619 return onc::wifi::kWPA_EAP;
620 }
621 return onc::wifi::kWPA_EAP;
622 }
623
624 WiFiService::NetworkList::iterator WiFiServiceMac::FindNetwork(
625 const std::string& network_guid) {
626 for (NetworkList::iterator it = networks_.begin();
627 it != networks_.end();
628 ++it) {
629 if (it->guid == network_guid)
630 return it;
631 }
632 return networks_.end();
633 }
634
635 void WiFiServiceMac::OnWlanObserverNotification() {
636 std::string connected_network_guid = GUIDFromSSID([interface_ ssid]);
637 DVLOG(1) << " *** Got Notification: " << connected_network_guid;
638 // There are 2 notifications for every network switch:
tbarzic 2014/01/27 20:17:24 remove this comment, looks like it turned out to b
mef 2014/01/27 23:08:27 Done.
639 // 1. When old WLAN is disconnected, |connected_network_guid| is empty.
640 // 2. When new WLAN is connected, |connected_network_guid| is new network
641 // guid.
642 // Connected network has changed, mark previous one disconnected.
643 if (connected_network_guid != connected_network_guid_) {
644 // Update connection_state of newly connected network.
645 NetworkList::iterator it = FindNetwork(connected_network_guid_);
646 if (it != networks_.end()) {
647 it->connection_state = onc::connection_state::kNotConnected;
tbarzic 2014/01/27 20:17:24 indent-=2
mef 2014/01/27 23:08:27 Done.
648 }
649 NotifyNetworkChanged(connected_network_guid_);
tbarzic 2014/01/27 20:17:24 this should be called only if (it != networks_.end
mef 2014/01/27 23:08:27 Done.
650 connected_network_guid_ = connected_network_guid;
651 }
652
653 if (!connected_network_guid.empty()) {
654 // Update connection_state of newly connected network.
655 NetworkList::iterator it = FindNetwork(connected_network_guid);
656 if (it != networks_.end()) {
657 it->connection_state = GetNetworkConnectionState(connected_network_guid);
658 } else {
659 // Can't find |connected_network_guid| in |networks_|, try to update it.
660 UpdateNetworks();
661 }
662 // Notify that network is connecting.
663 NotifyNetworkChanged(connected_network_guid);
664 // Start waiting for network connection to complete.
665 // Don't wait as network change notification should be sent by detector.
666 //if (!networks_changed_observer_.is_null())
667 // WaitForNetworkConnect(connected_network_guid, 0);
668 }
669 }
670
671 void WiFiServiceMac::NotifyNetworkListChanged(const NetworkList& networks) {
672 if (network_list_changed_observer_.is_null())
673 return;
674
675 NetworkGuidList current_networks;
676 for (NetworkList::const_iterator it = networks.begin();
677 it != networks.end();
678 ++it) {
679 current_networks.push_back(it->guid);
680 }
681
682 message_loop_proxy_->PostTask(
683 FROM_HERE,
684 base::Bind(network_list_changed_observer_, current_networks));
685 }
686
687 void WiFiServiceMac::NotifyNetworkChanged(const std::string& network_guid) {
688 if (networks_changed_observer_.is_null())
689 return;
690
691 DVLOG(1) << "NotifyNetworkChanged: " << network_guid;
692 NetworkGuidList changed_networks(1, network_guid);
693 message_loop_proxy_->PostTask(
694 FROM_HERE,
695 base::Bind(networks_changed_observer_, changed_networks));
696 }
697
698 // static
699 WiFiService* WiFiService::Create() { return new WiFiServiceMac(); }
700
701 } // namespace wifi
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698