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

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

Powered by Google App Engine
This is Rietveld 408576698