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

Side by Side Diff: chrome/utility/wifi/wifi_service_win.cc

Issue 22295002: Base infrastructure for Networking Private API on Windows and Mac. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Sync up to r225168 Created 7 years, 2 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 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 "chrome/utility/wifi/wifi_service.h"
6
7 #include <iphlpapi.h>
8 #include <objbase.h>
9 #include <wlanapi.h>
10
11 #include "base/bind.h"
12 #include "base/memory/ref_counted.h"
13 #include "base/message_loop/message_loop.h"
14 #include "base/strings/string16.h"
15 #include "base/strings/string_util.h"
16 #include "base/strings/utf_string_conversions.h"
17
18 #pragma comment(lib, "wlanapi.lib")
19
20 // Implementation of WiFiService for Windows.
21 class WiFiServiceImpl : public WiFiService, base::NonThreadSafe {
22 public:
23 WiFiServiceImpl();
24 virtual ~WiFiServiceImpl();
25
26 // WiFiService interface implementation.
27
28 virtual void GetProperties(const std::string& network_guid,
29 const NetworkPropertiesCallback& callback,
30 const ErrorCallback& error_callback) OVERRIDE;
31
32 virtual void GetState(const std::string& network_guid,
33 const NetworkPropertiesCallback& callback,
34 const ErrorCallback& error_callback) OVERRIDE;
35
36 virtual void GetManagedProperties(
37 const std::string& network_guid,
38 const DictionaryResultCallback& callback,
39 const ErrorCallback& error_callback) OVERRIDE;
40
41 virtual void SetProperties(const std::string& network_guid,
42 const base::DictionaryValue& properties,
43 const StringResultCallback& callback,
44 const ErrorCallback& error_callback) OVERRIDE;
45
46 virtual void GetVisibleNetworks(
47 const NetworkListCallback& callback,
48 const ErrorCallback& error_callback) OVERRIDE;
49
50 virtual void RequestNetworkScan() OVERRIDE;
51
52 virtual void StartConnect(const std::string& network_guid,
53 const StringResultCallback& callback,
54 const ErrorCallback& error_callback) OVERRIDE;
55
56 virtual void StartDisconnect(const std::string& network_guid,
57 const StringResultCallback& callback,
58 const ErrorCallback& error_callback) OVERRIDE;
59
60 virtual void SetNetworksChangedObserver(
61 const NetworkGuidListCallback& observer) OVERRIDE;
62
63 virtual void SetNetworkListChangedObserver(
64 const NetworkGuidListCallback& observer) OVERRIDE;
65
66 private:
67 // Static callback for Windows WLAN_NOTIFICATION. Calls OnWlanNotification
68 // on WiFiServiceImpl passed back as |context|.
69 static void __stdcall OnWlanNotificationCallback(
70 PWLAN_NOTIFICATION_DATA wlan_notification_data,
71 PVOID context);
72
73 // Callback for Windows WLAN_NOTIFICATION. Called on random thread from
74 // OnWlanNotificationCallback. Handles network connectivity and scan complete
75 // notification and posts tasks to main thread.
76 void OnWlanNotification(PWLAN_NOTIFICATION_DATA wlan_notification_data);
77
78 // Handles NetworkScanComplete notification on main thread. Sends
79 // |NetworkListChanged| event with new list of visible networks.
80 void OnNetworkScanCompleteOnMainThread();
81
82 // Wait up to |kMaxAttempts| with |kAttemptDelayMs| delay for connection
83 // to network with |network_guid|. Reset DHCP and Notify that |NetworkChanged|
84 // upon success.
85 void WaitForNetworkConnect(const std::string& network_guid, int attempt);
86
87 // Check |error_code| and if is not |ERROR_SUCCESS|, then run |error_callback|
88 // with |error_name|.
89 bool CheckError(const ErrorCallback& error_callback,
90 const std::string& error_name,
91 DWORD error_code) const;
92
93 // Return |iterator| to network identified by |network_guid| in |networks|
94 // list.
95 NetworkList::const_iterator FindNetwork(
96 const NetworkList& networks,
97 const std::string& network_guid) const;
98
99 // Save currently connected network profile and return its
100 // |connected_network_guid|, so it can be re-connected later.
101 DWORD SaveCurrentConnectedNetwork(std::string* connected_network_guid);
102
103 // Sort networks, so connected/connecting is up front, then by type:
104 // Ethernet, WiFi, Cellular, VPN
105 static void SortNetworks(NetworkList* networks);
106
107 // Open a WLAN client handle, register for WLAN notifications.
108 DWORD OpenClientHandle();
109
110 // Reset DHCP on wireless adapter to speed up reconnect after chromecast
111 // device reset
112 DWORD ResetDHCP();
113
114 // Find |adapter_index_map| by |interface_guid| for DHCP reset.
115 DWORD FindAdapterIndexMapByGuid(const GUID& interface_guid,
116 IP_ADAPTER_INDEX_MAP* adapter_index_map);
117
118 // Ensure that |client_| handle is initialized.
119 DWORD EnsureInitialized();
120
121 // Close |client_| handle if it is open.
122 DWORD CloseClientHandle();
123
124 // Get |profile_name| from unique |network_guid|.
125 base::string16 ProfileNameFromGuid(const std::string& network_guid) const {
126 return base::UTF8ToUTF16(network_guid);
127 }
128
129 // Get |dot11Ssid| from unique |network_guid|.
130 DOT11_SSID SsidFromGuid(const std::string& network_guid) const;
131
132 // Get unique |network_guid| string based on |dot11Ssid|.
133 std::string GuidFromSsid(const DOT11_SSID& dot11Ssid) const {
134 return std::string(reinterpret_cast<const char*>(dot11Ssid.ucSSID),
135 dot11Ssid.uSSIDLength);
136 }
137
138 // Get network |ssid| string based on |wlan|.
139 std::string SsidFromWlan(const WLAN_AVAILABLE_NETWORK& wlan) const {
140 return GuidFromSsid(wlan.dot11Ssid);
141 }
142
143 // Get unique |network_guid| string based on |wlan|.
144 std::string GuidFromWlan(const WLAN_AVAILABLE_NETWORK& wlan) const {
145 return SsidFromWlan(wlan);
146 }
147
148 // Deduce |WiFiService::Security| from |alg|.
149 WiFiService::Security SecurityFromDot11AuthAlg(
150 DOT11_AUTH_ALGORITHM alg) const;
151
152 // Populate |properties| based on |wlan| and its corresponding bss info from
153 // |wlan_bss_list|.
154 void NetworkPropertiesFromAvailableNetwork(const WLAN_AVAILABLE_NETWORK& wlan,
155 const WLAN_BSS_LIST& wlan_bss_list,
156 NetworkProperties* properties);
157 // Get the list of visible wireless networks.
158 DWORD GetVisibleNetworkList(NetworkList* network_list);
159
160 // Find currently connected network if any. Populate |connected_network_guid|
161 // on success.
162 DWORD FindConnectedNetwork(std::string* connected_network_guid);
163
164 // Connect to network |network_guid| using previosly stored profile if exists,
165 // or just network sid.
166 DWORD Connect(const std::string& network_guid);
167
168 // Disconnect from currently connected network if any.
169 DWORD Disconnect();
170
171 // Save temporary wireless profile for |network_guid|.
172 DWORD SaveTempProfile(const std::string& network_guid);
173
174 // Get previously stored |profile_xml| for |network_guid|.
175 DWORD GetProfile(const std::string& network_guid, std::string* profile_xml);
176
177 // Return true if there is previously stored profile xml for |network_guid|.
178 bool HaveProfile(const std::string& network_guid);
179
180 // Notify |network_list_changed_observer_| that list of visible networks has
181 // changed to |networks|.
182 void NotifyNetworkListChanged(const NetworkList& networks);
183
184 // Notify |networks_changed_observer_| that network |network_guid| status has
185 // changed.
186 void NotifyNetworkChanged(const std::string& network_guid);
187
188 // Wlan Service Handle.
189 HANDLE client_;
190 // Wlan Interface Guid.
191 GUID interface_guid_;
192 // Preserved Wlan Profile Xml.
193 std::map<std::string, std::string> saved_profiles_xml_;
194 // Observer to get notified when network(s) have changed (e.g. connect).
195 NetworkGuidListCallback networks_changed_observer_;
196 // Observer to get notified when network list has changed (scan complete).
197 NetworkGuidListCallback network_list_changed_observer_;
198 // Task runner to post tasks on main thread.
199 scoped_refptr<base::TaskRunner> task_runner_;
200 // Number of attempts to check that network has connected successfully.
201 static const int kMaxAttempts = 100;
202 // Delay between attempts to check that network has connected successfully.
203 static const int kAttemptDelayMs = 100;
204
205 DISALLOW_COPY_AND_ASSIGN(WiFiServiceImpl);
206 };
207
208 WiFiServiceImpl::WiFiServiceImpl() : client_(NULL) {}
209
210 WiFiServiceImpl::~WiFiServiceImpl() { CloseClientHandle(); }
211
212 void WiFiServiceImpl::GetProperties(const std::string& network_guid,
213 const NetworkPropertiesCallback& callback,
214 const ErrorCallback& error_callback) {
215 DWORD error = EnsureInitialized();
216
217 if (error == ERROR_SUCCESS) {
218 NetworkList network_list;
219 error = GetVisibleNetworkList(&network_list);
220 if (error == ERROR_SUCCESS && !network_list.empty()) {
221 NetworkList::const_iterator it = FindNetwork(network_list, network_guid);
222 if (it != network_list.end())
223 callback.Run(network_guid, *it);
224 else
225 error = ERROR_NOT_FOUND;
226 }
227 }
228
229 CheckError(error_callback, "Error.DBusFailed", error);
230 }
231
232 void WiFiServiceImpl::GetState(const std::string& network_guid,
233 const NetworkPropertiesCallback& callback,
234 const ErrorCallback& error_callback) {}
235
236 void WiFiServiceImpl::GetManagedProperties(
237 const std::string& network_guid,
238 const DictionaryResultCallback& callback,
239 const ErrorCallback& error_callback) {}
240
241 void WiFiServiceImpl::SetProperties(const std::string& network_guid,
242 const base::DictionaryValue& properties,
243 const StringResultCallback& callback,
244 const ErrorCallback& error_callback) {}
245
246 void WiFiServiceImpl::GetVisibleNetworks(
247 const NetworkListCallback& callback,
248 const ErrorCallback& error_callback) {
249 DWORD error = EnsureInitialized();
250
251 if (error == ERROR_SUCCESS) {
252 NetworkList network_list;
253 error = GetVisibleNetworkList(&network_list);
254 if (error == ERROR_SUCCESS && !network_list.empty()) {
255 SortNetworks(&network_list);
256 callback.Run(network_list);
257 }
258 }
259
260 CheckError(error_callback, "Error.DBusFailed", error);
261 }
262
263 void WiFiServiceImpl::RequestNetworkScan() {
264 DWORD error = EnsureInitialized();
265 if (error == ERROR_SUCCESS) {
266 WlanScan(client_, &interface_guid_, NULL, NULL, NULL);
267 }
268 }
269
270 void WiFiServiceImpl::StartConnect(
271 const std::string& network_guid,
272 const StringResultCallback& callback,
273 const ErrorCallback& error_callback) {
274 DWORD error = EnsureInitialized();
275 if (error == ERROR_SUCCESS) {
276 std::string connected_network_guid;
277 error = SaveCurrentConnectedNetwork(&connected_network_guid);
278 if (error == ERROR_SUCCESS) {
279 error = Connect(network_guid);
280 if (error == ERROR_SUCCESS) {
281 callback.Run(network_guid);
282 // Notify that previously connected network has changed.
283 NotifyNetworkChanged(connected_network_guid);
284 // Start waiting for network connection state change.
285 if (!networks_changed_observer_.is_null())
286 WaitForNetworkConnect(network_guid, 0);
287 }
288 }
289 }
290 CheckError(error_callback, "Error.DBusFailed", error);
291 }
292
293 void WiFiServiceImpl::StartDisconnect(
294 const std::string& network_guid,
295 const StringResultCallback& callback,
296 const ErrorCallback& error_callback) {
297 DWORD error = EnsureInitialized();
298
299 if (error == ERROR_SUCCESS) {
300 std::string connected_network_guid;
301 error = SaveCurrentConnectedNetwork(&connected_network_guid);
302 if (error == ERROR_SUCCESS && network_guid == connected_network_guid) {
303 error = Disconnect();
304 if (error == ERROR_SUCCESS) {
305 callback.Run(network_guid);
306 }
307 }
308 }
309 CheckError(error_callback, "Error.DBusFailed", error);
310 }
311
312 void WiFiServiceImpl::SetNetworksChangedObserver(
313 const NetworkGuidListCallback& observer) {
314 networks_changed_observer_ = observer;
315 }
316
317 void WiFiServiceImpl::SetNetworkListChangedObserver(
318 const NetworkGuidListCallback& observer) {
319 network_list_changed_observer_ = observer;
320 }
321
322 void WiFiServiceImpl::OnWlanNotificationCallback(
323 PWLAN_NOTIFICATION_DATA wlan_notification_data,
324 PVOID context) {
325 WiFiServiceImpl* service = reinterpret_cast<WiFiServiceImpl*>(context);
326 service->OnWlanNotification(wlan_notification_data);
327 }
328
329 void WiFiServiceImpl::OnWlanNotification(
330 PWLAN_NOTIFICATION_DATA wlan_notification_data) {
331 PWLAN_CONNECTION_NOTIFICATION_DATA wlan_connection_data =
332 reinterpret_cast<PWLAN_CONNECTION_NOTIFICATION_DATA>(
333 wlan_notification_data->pData);
334
335 switch (wlan_notification_data->NotificationCode) {
336 case wlan_notification_acm_disconnected:
337 case wlan_notification_acm_connection_complete:
338 case wlan_notification_acm_connection_attempt_fail:
339 task_runner_->PostTask(
340 FROM_HERE,
341 base::Bind(&WiFiServiceImpl::NotifyNetworkChanged,
342 base::Unretained(this),
343 GuidFromSsid(wlan_connection_data->dot11Ssid)));
344 break;
345 case wlan_notification_acm_scan_complete:
346 task_runner_->PostTask(
347 FROM_HERE,
348 base::Bind(&WiFiServiceImpl::OnNetworkScanCompleteOnMainThread,
349 base::Unretained(this)));
350 break;
351 }
352 }
353
354 void WiFiServiceImpl::OnNetworkScanCompleteOnMainThread() {
355 NetworkList networks;
356 DWORD error = GetVisibleNetworkList(&networks);
357 if (error == ERROR_SUCCESS)
358 NotifyNetworkListChanged(networks);
359 }
360
361 void WiFiServiceImpl::WaitForNetworkConnect(const std::string& network_guid,
362 int attempt) {
363 if (attempt > kMaxAttempts)
364 return;
365
366 std::string connected_network_guid;
367 DWORD error = FindConnectedNetwork(&connected_network_guid);
368 if (network_guid == connected_network_guid) {
369 // Reset DHCP to speed up the connection after Chromekey factory reset.
370 error = ResetDHCP();
371 NotifyNetworkChanged(network_guid);
372 } else {
373 // Continue waiting for network connection state change.
374 base::MessageLoop::current()->PostDelayedTask(
375 FROM_HERE,
376 base::Bind(&WiFiServiceImpl::WaitForNetworkConnect,
377 base::Unretained(this),
378 network_guid,
379 ++attempt),
380 base::TimeDelta::FromMilliseconds(kAttemptDelayMs));
381 }
382 }
383
384 bool WiFiServiceImpl::CheckError(const ErrorCallback& error_callback,
385 const std::string& error_name,
386 DWORD error_code) const {
387 if (error_code != ERROR_SUCCESS) {
388 scoped_ptr<base::DictionaryValue> error_data(new base::DictionaryValue);
389 error_data->SetInteger("Win32ErrorCode", error_code);
390 error_callback.Run(error_name, error_data.Pass());
391 return true;
392 }
393 return false;
394 }
395
396 WiFiService::NetworkList::const_iterator WiFiServiceImpl::FindNetwork(
397 const WiFiService::NetworkList& networks,
398 const std::string& network_guid) const {
399 for (NetworkList::const_iterator it = networks.begin(); it != networks.end();
400 ++it) {
401 if (it->guid == network_guid)
402 return it;
403 }
404 return networks.end();
405 }
406
407 DWORD WiFiServiceImpl::SaveCurrentConnectedNetwork(
408 std::string* connected_network_guid) {
409 // Find currently connected network.
410 DWORD error = FindConnectedNetwork(connected_network_guid);
411 if (error == ERROR_SUCCESS && !connected_network_guid->empty()) {
412 if (error == ERROR_SUCCESS) {
413 SaveTempProfile(*connected_network_guid);
414 std::string profile_xml;
415 error = GetProfile(*connected_network_guid, &profile_xml);
416 if (error == ERROR_SUCCESS) {
417 saved_profiles_xml_[*connected_network_guid] = profile_xml;
418 }
419 }
420 }
421 return error;
422 }
423
424 void WiFiServiceImpl::SortNetworks(NetworkList* networks) {
425 networks->sort(WiFiService::NetworkProperties::OrderByType);
426 }
427
428 DWORD WiFiServiceImpl::OpenClientHandle() {
429 CloseClientHandle();
430
431 DWORD error = ERROR_SUCCESS;
432 DWORD service_version = 0;
433
434 // Open a handle to the service.
435 error = WlanOpenHandle(WLAN_API_VERSION, NULL, &service_version, &client_);
436
437 PWLAN_INTERFACE_INFO_LIST pIntfList = NULL;
438 if (error == ERROR_SUCCESS) {
439 // Enumerate wireless interfaces.
440 error = WlanEnumInterfaces(client_, NULL, &pIntfList);
441 if (error == ERROR_SUCCESS) {
442 if (pIntfList != NULL && pIntfList->dwNumberOfItems != 0) {
443 // Remember first interface.
444 interface_guid_ = pIntfList->InterfaceInfo[0].InterfaceGuid;
445 // Try to find connected interface.
446 for (DWORD itf = 0; itf < pIntfList->dwNumberOfItems; ++itf) {
447 if (pIntfList->InterfaceInfo[itf].isState ==
448 wlan_interface_state_connected) {
449 // Found connected interface, remember it!
450 interface_guid_ = pIntfList->InterfaceInfo[itf].InterfaceGuid;
451 break;
452 }
453 }
454 WlanRegisterNotification(client_,
455 WLAN_NOTIFICATION_SOURCE_ALL,
456 FALSE,
457 OnWlanNotificationCallback,
458 this,
459 NULL,
460 NULL);
461 } else {
462 error = ERROR_NOINTERFACE;
463 }
464 }
465 // Clean up.
466 if (pIntfList != NULL)
467 WlanFreeMemory(pIntfList);
468 }
469 return error;
470 }
471
472 DWORD WiFiServiceImpl::ResetDHCP() {
473 IP_ADAPTER_INDEX_MAP adapter_index_map = {0};
474 DWORD error =
475 FindAdapterIndexMapByGuid(interface_guid_, &adapter_index_map);
476 if (error == ERROR_SUCCESS) {
477 error = IpReleaseAddress(&adapter_index_map);
478 if (error == ERROR_SUCCESS) {
479 error = IpRenewAddress(&adapter_index_map);
480 }
481 }
482 return error;
483 }
484
485 DWORD WiFiServiceImpl::FindAdapterIndexMapByGuid(
486 const GUID& interface_guid,
487 IP_ADAPTER_INDEX_MAP* adapter_index_map) {
488 string16 guid_string;
489 const int kGUIDSize = 39;
490 ::StringFromGUID2(
491 interface_guid, WriteInto(&guid_string, kGUIDSize), kGUIDSize);
492
493 ULONG buffer_length = 0;
494 DWORD error = GetInterfaceInfo(NULL, &buffer_length);
495 if (error == ERROR_INSUFFICIENT_BUFFER) {
496 scoped_ptr<unsigned char[]> buffer(new unsigned char[buffer_length]);
497 IP_INTERFACE_INFO* interface_info =
498 reinterpret_cast<IP_INTERFACE_INFO*>(buffer.get());
499 error = GetInterfaceInfo(interface_info, &buffer_length);
500 if (error == ERROR_SUCCESS) {
501 for (long adapter = 0; adapter < interface_info->NumAdapters; ++adapter) {
502 if (EndsWith(
503 interface_info->Adapter[adapter].Name, guid_string, false)) {
504 *adapter_index_map = interface_info->Adapter[adapter];
505 break;
506 }
507 }
508 }
509 }
510 return error;
511 }
512
513 DWORD WiFiServiceImpl::EnsureInitialized() {
514 DCHECK(CalledOnValidThread());
515 if (task_runner_.get() == NULL)
516 task_runner_ = base::MessageLoopProxy::current();
517
518 if (client_ != NULL)
519 return ERROR_SUCCESS;
520 return OpenClientHandle();
521 }
522
523 DWORD WiFiServiceImpl::CloseClientHandle() {
524 DWORD error = ERROR_SUCCESS;
525 if (client_ != NULL) {
526 WlanCloseHandle(client_, NULL);
527 client_ = NULL;
528 }
529 return error;
530 }
531
532 DOT11_SSID WiFiServiceImpl::SsidFromGuid(
533 const std::string& network_guid) const {
534 DOT11_SSID ssid = {0};
535 if (network_guid.length() <= DOT11_SSID_MAX_LENGTH) {
536 ssid.uSSIDLength = network_guid.length();
537 strncpy(reinterpret_cast<char*>(ssid.ucSSID),
538 network_guid.c_str(),
539 ssid.uSSIDLength);
540 }
541 return ssid;
542 }
543
544 WiFiService::Security WiFiServiceImpl::SecurityFromDot11AuthAlg(
545 DOT11_AUTH_ALGORITHM alg) const {
546 // TODO(mef): Figure out correct mapping.
547 switch (alg) {
548 case DOT11_AUTH_ALGO_RSNA:
549 return kSecurityWPA;
550 case DOT11_AUTH_ALGO_RSNA_PSK:
551 return kSecurityWPA_PSK;
552 case DOT11_AUTH_ALGO_80211_SHARED_KEY:
553 return kSecurityWEP_PSK;
554 case DOT11_AUTH_ALGO_80211_OPEN:
555 return kSecurityNone;
556 default:
557 return kSecurityUnknown;
558 }
559 return kSecurityUnknown;
560 }
561
562 void WiFiServiceImpl::NetworkPropertiesFromAvailableNetwork(
563 const WLAN_AVAILABLE_NETWORK& wlan,
564 const WLAN_BSS_LIST& wlan_bss_list,
565 NetworkProperties* properties) {
566 if (wlan.dwFlags & WLAN_AVAILABLE_NETWORK_CONNECTED) {
567 properties->connection_state = WiFiService::kConnectionStateConnected;
568 } else {
569 properties->connection_state = WiFiService::kConnectionStateNotConnected;
570 }
571
572 properties->ssid = SsidFromWlan(wlan);
573 properties->name = properties->ssid;
574 properties->guid = GuidFromWlan(wlan);
575 properties->type = WiFiService::kNetworkTypeWiFi;
576
577 for (size_t bss = 0; bss < wlan_bss_list.dwNumberOfItems; ++bss) {
578 const WLAN_BSS_ENTRY& bss_entry(wlan_bss_list.wlanBssEntries[bss]);
579 if (bss_entry.dot11Ssid.uSSIDLength == wlan.dot11Ssid.uSSIDLength &&
580 0 == memcmp(bss_entry.dot11Ssid.ucSSID,
581 wlan.dot11Ssid.ucSSID,
582 bss_entry.dot11Ssid.uSSIDLength)) {
583 if (bss_entry.ulChCenterFrequency < 3000000)
584 properties->frequency = kFrequency2400;
585 else
586 properties->frequency = kFrequency5000;
587 properties->frequency_list.push_back(properties->frequency);
588 properties->bssid = WiFiService::NetworkProperties::MacAddressAsString(
589 bss_entry.dot11Bssid);
590 }
591 }
592 properties->frequency_list.sort();
593 properties->frequency_list.unique();
594 properties->security =
595 SecurityFromDot11AuthAlg(wlan.dot11DefaultAuthAlgorithm);
596 properties->signal_strength = wlan.wlanSignalQuality;
597 }
598
599 // Get the list of visible wireless networks
600 DWORD WiFiServiceImpl::GetVisibleNetworkList(NetworkList* network_list) {
601 DWORD error = ERROR_SUCCESS;
602
603 if (client_ == NULL) {
604 return ERROR_NOINTERFACE;
605 }
606
607 PWLAN_AVAILABLE_NETWORK_LIST pVList = NULL;
608 PWLAN_BSS_LIST pWlanBssList = NULL;
609
610 error = WlanGetAvailableNetworkList(
611 client_, &interface_guid_, 0, NULL, &pVList);
612
613 if (error == ERROR_SUCCESS && NULL != pVList) {
614 error = WlanGetNetworkBssList(client_,
615 &interface_guid_,
616 NULL,
617 dot11_BSS_type_any,
618 FALSE,
619 NULL,
620 &pWlanBssList);
621 if (error == ERROR_SUCCESS && NULL != pWlanBssList) {
622 for (DWORD i = 0; i < pVList->dwNumberOfItems; ++i) {
623 network_list->push_back(NetworkProperties());
624 NetworkPropertiesFromAvailableNetwork(
625 pVList->Network[i], *pWlanBssList, &network_list->back());
626 }
627 }
628 }
629
630 // clean up
631 if (pVList != NULL) {
632 WlanFreeMemory(pVList);
633 }
634 if (pWlanBssList != NULL) {
635 WlanFreeMemory(pWlanBssList);
636 }
637 return error;
638 }
639
640 // Find currently connected network.
641 DWORD WiFiServiceImpl::FindConnectedNetwork(
642 std::string* connected_network_guid) {
643 DWORD error = ERROR_SUCCESS;
644
645 if (client_ == NULL) {
646 return ERROR_NOINTERFACE;
647 }
648
649 PWLAN_AVAILABLE_NETWORK_LIST pVList = NULL;
650
651 error = WlanGetAvailableNetworkList(
652 client_, &interface_guid_, 0, NULL, &pVList);
653
654 if (error == ERROR_SUCCESS && NULL != pVList) {
655 for (DWORD i = 0; i < pVList->dwNumberOfItems; ++i) {
656 const WLAN_AVAILABLE_NETWORK& wlan = pVList->Network[i];
657 if (wlan.dwFlags & WLAN_AVAILABLE_NETWORK_CONNECTED) {
658 *connected_network_guid = GuidFromWlan(wlan);
659 break;
660 }
661 }
662 }
663
664 // clean up
665 if (pVList != NULL) {
666 WlanFreeMemory(pVList);
667 }
668
669 return error;
670 }
671
672 DWORD WiFiServiceImpl::Connect(const std::string& network_guid) {
673 DWORD error = ERROR_SUCCESS;
674
675 if (client_ == NULL) {
676 return ERROR_NOINTERFACE;
677 }
678
679 base::string16 profile_name = ProfileNameFromGuid(network_guid);
680
681 if (HaveProfile(network_guid)) {
682 WLAN_CONNECTION_PARAMETERS wlan_params = {
683 wlan_connection_mode_profile, profile_name.c_str(), NULL,
684 NULL, dot11_BSS_type_any, 0};
685 error = ::WlanConnect(client_, &interface_guid_, &wlan_params, NULL);
686 } else {
687 DOT11_SSID ssid = SsidFromGuid(network_guid);
688 WLAN_CONNECTION_PARAMETERS wlan_params = {
689 wlan_connection_mode_discovery_unsecure, NULL, &ssid, NULL,
690 dot11_BSS_type_infrastructure, 0};
691 error = ::WlanConnect(client_, &interface_guid_, &wlan_params, NULL);
692 }
693
694 return error;
695 }
696
697 DWORD WiFiServiceImpl::Disconnect() {
698 DWORD error = ERROR_SUCCESS;
699
700 if (client_ == NULL) {
701 return ERROR_NOINTERFACE;
702 }
703
704 error = ::WlanDisconnect(client_, &interface_guid_, NULL);
705 return error;
706 }
707
708 DWORD WiFiServiceImpl::SaveTempProfile(const std::string& network_guid) {
709 DWORD error = ERROR_SUCCESS;
710
711 if (client_ == NULL) {
712 return ERROR_NOINTERFACE;
713 }
714
715 base::string16 profile_name = ProfileNameFromGuid(network_guid);
716
717 error = ::WlanSaveTemporaryProfile(
718 client_, &interface_guid_, profile_name.c_str(), NULL, 0, true, NULL);
719 return error;
720 }
721
722 DWORD WiFiServiceImpl::GetProfile(const std::string& network_guid,
723 std::string* profile_xml) {
724 DWORD error = ERROR_SUCCESS;
725
726 if (client_ == NULL) {
727 return ERROR_NOINTERFACE;
728 }
729
730 base::string16 profile_name = ProfileNameFromGuid(network_guid);
731 LPWSTR str_profile_xml = NULL;
732 error = ::WlanGetProfile(client_,
733 &interface_guid_,
734 profile_name.c_str(),
735 NULL,
736 &str_profile_xml,
737 NULL,
738 NULL);
739
740 if (error == ERROR_SUCCESS && str_profile_xml != NULL) {
741 *profile_xml = base::UTF16ToUTF8(str_profile_xml);
742 }
743 // clean up
744 if (str_profile_xml != NULL) {
745 WlanFreeMemory(str_profile_xml);
746 }
747
748 return error;
749 }
750
751 bool WiFiServiceImpl::HaveProfile(const std::string& network_guid) {
752 DWORD error = ERROR_SUCCESS;
753 std::string profile_xml;
754 return GetProfile(network_guid, &profile_xml) == ERROR_SUCCESS;
755 }
756
757 void WiFiServiceImpl::NotifyNetworkListChanged(const NetworkList& networks) {
758 if (network_list_changed_observer_.is_null())
759 return;
760
761 WiFiService::NetworkGuidList current_networks;
762 for (WiFiService::NetworkList::const_iterator it = networks.begin();
763 it != networks.end();
764 ++it) {
765 current_networks.push_back(it->guid);
766 }
767 network_list_changed_observer_.Run(current_networks);
768 }
769
770 void WiFiServiceImpl::NotifyNetworkChanged(const std::string& network_guid) {
771 WiFiService::NetworkGuidList changed_networks(1, network_guid);
772 if (!networks_changed_observer_.is_null())
773 networks_changed_observer_.Run(changed_networks);
774 }
775
776 WiFiService* WiFiService::CreateService() { return new WiFiServiceImpl(); }
777
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698