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

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

Powered by Google App Engine
This is Rietveld 408576698