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

Powered by Google App Engine
This is Rietveld 408576698