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

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

Issue 32193015: WlanConnect to BSS with given frequency. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: GetDesiredBssidList now selects one BSSID with best quality. 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
1 // Copyright 2013 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/utility/wifi/wifi_service.h" 5 #include "chrome/utility/wifi/wifi_service.h"
6 6
7 #include <iphlpapi.h> 7 #include <iphlpapi.h>
8 #include <objbase.h> 8 #include <objbase.h>
9 #include <wlanapi.h> 9 #include <wlanapi.h>
10 10
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 const base::DictionaryValue& properties, 52 const base::DictionaryValue& properties,
53 const StringResultCallback& callback, 53 const StringResultCallback& callback,
54 const ErrorCallback& error_callback) OVERRIDE; 54 const ErrorCallback& error_callback) OVERRIDE;
55 55
56 virtual void GetVisibleNetworks(const NetworkListCallback& callback, 56 virtual void GetVisibleNetworks(const NetworkListCallback& callback,
57 const ErrorCallback& error_callback) OVERRIDE; 57 const ErrorCallback& error_callback) OVERRIDE;
58 58
59 virtual void RequestNetworkScan() OVERRIDE; 59 virtual void RequestNetworkScan() OVERRIDE;
60 60
61 virtual void StartConnect(const std::string& network_guid, 61 virtual void StartConnect(const std::string& network_guid,
62 Frequency frequency,
62 const StringResultCallback& callback, 63 const StringResultCallback& callback,
63 const ErrorCallback& error_callback) OVERRIDE; 64 const ErrorCallback& error_callback) OVERRIDE;
64 65
65 virtual void StartDisconnect(const std::string& network_guid, 66 virtual void StartDisconnect(const std::string& network_guid,
66 const StringResultCallback& callback, 67 const StringResultCallback& callback,
67 const ErrorCallback& error_callback) OVERRIDE; 68 const ErrorCallback& error_callback) OVERRIDE;
68 69
69 virtual void SetNetworksChangedObserver( 70 virtual void SetNetworksChangedObserver(
70 const NetworkGuidListCallback& observer) OVERRIDE; 71 const NetworkGuidListCallback& observer) OVERRIDE;
71 72
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 NetworkProperties* properties); 173 NetworkProperties* properties);
173 174
174 // Get the list of visible wireless networks. 175 // Get the list of visible wireless networks.
175 DWORD GetVisibleNetworkList(NetworkList* network_list); 176 DWORD GetVisibleNetworkList(NetworkList* network_list);
176 177
177 // Find currently connected network if any. Populate |connected_network_guid| 178 // Find currently connected network if any. Populate |connected_network_guid|
178 // on success. 179 // on success.
179 DWORD FindConnectedNetwork(std::string* connected_network_guid); 180 DWORD FindConnectedNetwork(std::string* connected_network_guid);
180 181
181 // Connect to network |network_guid| using previosly stored profile if exists, 182 // Connect to network |network_guid| using previosly stored profile if exists,
182 // or just network sid. 183 // or just network sid. If |frequency| is not |kFrequencyUnknown| then
183 DWORD Connect(const std::string& network_guid); 184 // connects only to BSS which uses that frequency and returns
185 // |ERROR_NOT_FOUND| if such BSS cannot be found.
186 DWORD Connect(const std::string& network_guid, Frequency frequency);
184 187
185 // Disconnect from currently connected network if any. 188 // Disconnect from currently connected network if any.
186 DWORD Disconnect(); 189 DWORD Disconnect();
187 190
191 // Get DOT11_BSSID_LIST of desired BSSIDs to connect to |ssid| network on
192 // given |frequency|.
193 DWORD GetDesiredBssList(DOT11_SSID& ssid,
194 Frequency frequency,
195 scoped_ptr<DOT11_BSSID_LIST>* desired_list);
196
188 // Save temporary wireless profile for |network_guid|. 197 // Save temporary wireless profile for |network_guid|.
189 DWORD SaveTempProfile(const std::string& network_guid); 198 DWORD SaveTempProfile(const std::string& network_guid);
190 199
191 // Get previously stored |profile_xml| for |network_guid|. 200 // Get previously stored |profile_xml| for |network_guid|.
192 DWORD GetProfile(const std::string& network_guid, std::string* profile_xml); 201 DWORD GetProfile(const std::string& network_guid, std::string* profile_xml);
193 202
194 // Return true if there is previously stored profile xml for |network_guid|. 203 // Return true if there is previously stored profile xml for |network_guid|.
195 bool HaveProfile(const std::string& network_guid); 204 bool HaveProfile(const std::string& network_guid);
196 205
197 // Notify |network_list_changed_observer_| that list of visible networks has 206 // Notify |network_list_changed_observer_| that list of visible networks has
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
299 } 308 }
300 309
301 void WiFiServiceImpl::RequestNetworkScan() { 310 void WiFiServiceImpl::RequestNetworkScan() {
302 DWORD error = EnsureInitialized(); 311 DWORD error = EnsureInitialized();
303 if (error == ERROR_SUCCESS) { 312 if (error == ERROR_SUCCESS) {
304 WlanScan(client_, &interface_guid_, NULL, NULL, NULL); 313 WlanScan(client_, &interface_guid_, NULL, NULL, NULL);
305 } 314 }
306 } 315 }
307 316
308 void WiFiServiceImpl::StartConnect(const std::string& network_guid, 317 void WiFiServiceImpl::StartConnect(const std::string& network_guid,
318 Frequency frequency,
309 const StringResultCallback& callback, 319 const StringResultCallback& callback,
310 const ErrorCallback& error_callback) { 320 const ErrorCallback& error_callback) {
311 DLOG(INFO) << "Start Connect: " << network_guid; 321 DLOG(INFO) << "Start Connect: " << network_guid << " " << frequency << " MHz";
312 DWORD error = EnsureInitialized(); 322 DWORD error = EnsureInitialized();
313 if (error == ERROR_SUCCESS) { 323 if (error == ERROR_SUCCESS) {
314 std::string connected_network_guid; 324 std::string connected_network_guid;
315 error = SaveCurrentConnectedNetwork(&connected_network_guid); 325 error = SaveCurrentConnectedNetwork(&connected_network_guid);
316 if (error == ERROR_SUCCESS) { 326 if (error == ERROR_SUCCESS) {
317 // Connect only if network |network_guid| is not connected already. 327 // Connect only if network |network_guid| is not connected already.
318 if (network_guid != connected_network_guid) 328 if (network_guid != connected_network_guid)
319 error = Connect(network_guid); 329 error = Connect(network_guid, frequency);
320 if (error == ERROR_SUCCESS) { 330 if (error == ERROR_SUCCESS) {
321 DisableNwCategoryWizard();
322 callback.Run(network_guid); 331 callback.Run(network_guid);
323 // Notify that previously connected network has changed. 332 // Notify that previously connected network has changed.
324 NotifyNetworkChanged(connected_network_guid); 333 NotifyNetworkChanged(connected_network_guid);
325 // Start waiting for network connection state change. 334 // Start waiting for network connection state change.
326 if (!networks_changed_observer_.is_null()) { 335 if (!networks_changed_observer_.is_null()) {
336 DisableNwCategoryWizard();
327 // Disable automatic network change notifications as they get fired 337 // Disable automatic network change notifications as they get fired
328 // when network is just connected, but not yet accessible (doesn't 338 // when network is just connected, but not yet accessible (doesn't
329 // have valid IP address). 339 // have valid IP address).
330 enable_notify_network_changed_ = false; 340 enable_notify_network_changed_ = false;
331 WaitForNetworkConnect(network_guid, 0); 341 WaitForNetworkConnect(network_guid, 0);
332 return; 342 return;
333 } 343 }
334 } 344 }
335 } 345 }
336 } 346 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 379
370 void WiFiServiceImpl::OnWlanNotificationCallback( 380 void WiFiServiceImpl::OnWlanNotificationCallback(
371 PWLAN_NOTIFICATION_DATA wlan_notification_data, 381 PWLAN_NOTIFICATION_DATA wlan_notification_data,
372 PVOID context) { 382 PVOID context) {
373 WiFiServiceImpl* service = reinterpret_cast<WiFiServiceImpl*>(context); 383 WiFiServiceImpl* service = reinterpret_cast<WiFiServiceImpl*>(context);
374 service->OnWlanNotification(wlan_notification_data); 384 service->OnWlanNotification(wlan_notification_data);
375 } 385 }
376 386
377 void WiFiServiceImpl::OnWlanNotification( 387 void WiFiServiceImpl::OnWlanNotification(
378 PWLAN_NOTIFICATION_DATA wlan_notification_data) { 388 PWLAN_NOTIFICATION_DATA wlan_notification_data) {
389 if (!task_runner_)
390 return;
391
379 switch (wlan_notification_data->NotificationCode) { 392 switch (wlan_notification_data->NotificationCode) {
380 case wlan_notification_acm_disconnected: 393 case wlan_notification_acm_disconnected:
381 case wlan_notification_acm_connection_complete: 394 case wlan_notification_acm_connection_complete:
382 case wlan_notification_acm_connection_attempt_fail: { 395 case wlan_notification_acm_connection_attempt_fail: {
383 PWLAN_CONNECTION_NOTIFICATION_DATA wlan_connection_data = 396 PWLAN_CONNECTION_NOTIFICATION_DATA wlan_connection_data =
384 reinterpret_cast<PWLAN_CONNECTION_NOTIFICATION_DATA>( 397 reinterpret_cast<PWLAN_CONNECTION_NOTIFICATION_DATA>(
385 wlan_notification_data->pData); 398 wlan_notification_data->pData);
386 task_runner_->PostTask( 399 task_runner_->PostTask(
387 FROM_HERE, 400 FROM_HERE,
388 base::Bind(&WiFiServiceImpl::NotifyNetworkChanged, 401 base::Bind(&WiFiServiceImpl::NotifyNetworkChanged,
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
489 networks->sort(NetworkProperties::OrderByType); 502 networks->sort(NetworkProperties::OrderByType);
490 } 503 }
491 504
492 DWORD WiFiServiceImpl::OpenClientHandle() { 505 DWORD WiFiServiceImpl::OpenClientHandle() {
493 CloseClientHandle(); 506 CloseClientHandle();
494 507
495 DWORD error = ERROR_SUCCESS; 508 DWORD error = ERROR_SUCCESS;
496 DWORD service_version = 0; 509 DWORD service_version = 0;
497 510
498 // Open a handle to the service. 511 // Open a handle to the service.
499 error = ::WlanOpenHandle(1, NULL, &service_version, &client_); 512 error = ::WlanOpenHandle(WLAN_API_VERSION, NULL, &service_version, &client_);
500 513
501 PWLAN_INTERFACE_INFO_LIST interface_list = NULL; 514 PWLAN_INTERFACE_INFO_LIST interface_list = NULL;
502 if (error == ERROR_SUCCESS) { 515 if (error == ERROR_SUCCESS) {
503 // Enumerate wireless interfaces. 516 // Enumerate wireless interfaces.
504 error = ::WlanEnumInterfaces(client_, NULL, &interface_list); 517 error = ::WlanEnumInterfaces(client_, NULL, &interface_list);
505 if (error == ERROR_SUCCESS) { 518 if (error == ERROR_SUCCESS) {
506 if (interface_list != NULL && interface_list->dwNumberOfItems != 0) { 519 if (interface_list != NULL && interface_list->dwNumberOfItems != 0) {
507 // Remember first interface just in case if none are connected. 520 // Remember first interface just in case if none are connected.
508 interface_guid_ = interface_list->InterfaceInfo[0].InterfaceGuid; 521 interface_guid_ = interface_list->InterfaceInfo[0].InterfaceGuid;
509 // Try to find a connected interface. 522 // Try to find a connected interface.
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
772 } 785 }
773 786
774 // clean up 787 // clean up
775 if (available_network_list != NULL) { 788 if (available_network_list != NULL) {
776 ::WlanFreeMemory(available_network_list); 789 ::WlanFreeMemory(available_network_list);
777 } 790 }
778 791
779 return error; 792 return error;
780 } 793 }
781 794
782 DWORD WiFiServiceImpl::Connect(const std::string& network_guid) { 795 DWORD WiFiServiceImpl::GetDesiredBssList(
796 DOT11_SSID& ssid,
797 Frequency frequency,
798 scoped_ptr<DOT11_BSSID_LIST>* desired_list) {
afontan 2013/10/24 18:18:20 I think you should consider adding hidden networks
mef 2013/10/24 19:13:54 Sounds good. I'll keep this CL going as placeholde
799 if (client_ == NULL) {
800 NOTREACHED();
801 return ERROR_NOINTERFACE;
802 }
803
804 desired_list->reset();
805
806 if (frequency == kFrequencyUnknown)
807 return ERROR_SUCCESS;
808
809 DWORD error = ERROR_SUCCESS;
810 PWLAN_BSS_LIST bss_list = NULL;
811
812 // TODO(mef): WlanGetNetworkBssList is not available on XP. If XP support is
813 // needed, then different method of getting BSS (e.g. OID query) will have
814 // to be used.
815 error = ::WlanGetNetworkBssList(client_,
816 &interface_guid_,
817 NULL,
818 dot11_BSS_type_any,
819 FALSE,
820 NULL,
821 &bss_list);
822 if (error == ERROR_SUCCESS && NULL != bss_list) {
823 unsigned int best_quality = 0u;
824 size_t best_index = 0;
825 Frequency bss_frequency;
826
827 // Go through bss_list and find best quality BSSID with matching frequency.
828 for (size_t bss = 0; bss < bss_list->dwNumberOfItems; ++bss) {
829 const WLAN_BSS_ENTRY& bss_entry(bss_list->wlanBssEntries[bss]);
830 if (bss_entry.dot11Ssid.uSSIDLength != ssid.uSSIDLength ||
831 0 != memcmp(bss_entry.dot11Ssid.ucSSID,
832 ssid.ucSSID,
833 bss_entry.dot11Ssid.uSSIDLength))
834 continue;
835
836 if (bss_entry.ulChCenterFrequency < 3000000)
837 bss_frequency = kFrequency2400;
838 else
839 bss_frequency = kFrequency5000;
840
841 if (bss_frequency == frequency &&
842 bss_entry.uLinkQuality > best_quality) {
843 best_quality = bss_entry.uLinkQuality;
844 best_index = bss;
845 }
846 }
847
848 // If any matching BSS were found, prepare the header.
849 if (best_quality > 0) {
850 const WLAN_BSS_ENTRY& bss_entry(bss_list->wlanBssEntries[best_index]);
851 scoped_ptr<DOT11_BSSID_LIST> selected_list(new DOT11_BSSID_LIST);
852
853 selected_list->Header.Revision = DOT11_BSSID_LIST_REVISION_1;
854 selected_list->Header.Size = sizeof(DOT11_BSSID_LIST);
855 selected_list->Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
856 selected_list->uNumOfEntries = 1;
857 selected_list->uTotalNumOfEntries = 1;
858 std::copy(bss_entry.dot11Bssid,
859 bss_entry.dot11Bssid+sizeof(bss_entry.dot11Bssid),
860 selected_list->BSSIDs[0]);
861 desired_list->swap(selected_list);
862 DLOG(INFO) << "Quality: " << best_quality << " BSS: "
863 << NetworkProperties::MacAddressAsString(bss_entry.dot11Bssid);
864 } else {
865 error = ERROR_NOT_FOUND;
866 }
867 }
868
869 // clean up
870 if (bss_list != NULL) {
871 ::WlanFreeMemory(bss_list);
872 }
873 return error;
874 }
875
876
877 DWORD WiFiServiceImpl::Connect(const std::string& network_guid,
878 Frequency frequency) {
783 if (client_ == NULL) { 879 if (client_ == NULL) {
784 NOTREACHED(); 880 NOTREACHED();
785 return ERROR_NOINTERFACE; 881 return ERROR_NOINTERFACE;
786 } 882 }
787 883
788 DWORD error = ERROR_SUCCESS; 884 DWORD error = ERROR_SUCCESS;
789 base::string16 profile_name = ProfileNameFromGUID(network_guid); 885 DOT11_SSID ssid = SSIDFromGUID(network_guid);
790 886 scoped_ptr<DOT11_BSSID_LIST> desired_bss_list;
791 if (HaveProfile(network_guid)) { 887 error = GetDesiredBssList(ssid, frequency, &desired_bss_list);
792 WLAN_CONNECTION_PARAMETERS wlan_params = { 888 if (error == ERROR_SUCCESS) {
793 wlan_connection_mode_profile, 889 if (HaveProfile(network_guid)) {
794 profile_name.c_str(), 890 base::string16 profile_name = ProfileNameFromGUID(network_guid);
795 NULL, 891 WLAN_CONNECTION_PARAMETERS wlan_params = {
796 NULL, 892 wlan_connection_mode_profile,
797 dot11_BSS_type_any, 893 profile_name.c_str(),
798 0}; 894 NULL,
799 error = ::WlanConnect(client_, &interface_guid_, &wlan_params, NULL); 895 desired_bss_list.get(),
800 } else { 896 dot11_BSS_type_any,
801 // TODO(mef): wlan_connection_mode_discovery_unsecure is not available on 897 0};
802 // XP. If XP support is needed, then temporary profile will have to be 898 error = ::WlanConnect(client_, &interface_guid_, &wlan_params, NULL);
803 // created. 899 } else {
804 DOT11_SSID ssid = SSIDFromGUID(network_guid); 900 // TODO(mef): wlan_connection_mode_discovery_unsecure is not available on
805 WLAN_CONNECTION_PARAMETERS wlan_params = { 901 // XP. If XP support is needed, then temporary profile will have to be
806 wlan_connection_mode_discovery_unsecure, 902 // created.
807 NULL, 903 WLAN_CONNECTION_PARAMETERS wlan_params = {
808 &ssid, 904 wlan_connection_mode_discovery_unsecure,
809 NULL, 905 NULL,
810 dot11_BSS_type_infrastructure, 906 &ssid,
811 0}; 907 desired_bss_list.get(),
812 error = ::WlanConnect(client_, &interface_guid_, &wlan_params, NULL); 908 dot11_BSS_type_infrastructure,
909 0};
910 error = ::WlanConnect(client_, &interface_guid_, &wlan_params, NULL);
911 }
813 } 912 }
814 913
815 return error; 914 return error;
816 } 915 }
817 916
818 DWORD WiFiServiceImpl::Disconnect() { 917 DWORD WiFiServiceImpl::Disconnect() {
819 if (client_ == NULL) { 918 if (client_ == NULL) {
820 NOTREACHED(); 919 NOTREACHED();
821 return ERROR_NOINTERFACE; 920 return ERROR_NOINTERFACE;
822 } 921 }
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
899 if (enable_notify_network_changed_ && !networks_changed_observer_.is_null()) { 998 if (enable_notify_network_changed_ && !networks_changed_observer_.is_null()) {
900 DLOG(INFO) << "NotifyNetworkChanged: " << network_guid; 999 DLOG(INFO) << "NotifyNetworkChanged: " << network_guid;
901 NetworkGuidList changed_networks(1, network_guid); 1000 NetworkGuidList changed_networks(1, network_guid);
902 networks_changed_observer_.Run(changed_networks); 1001 networks_changed_observer_.Run(changed_networks);
903 } 1002 }
904 } 1003 }
905 1004
906 WiFiService* WiFiService::CreateService() { return new WiFiServiceImpl(); } 1005 WiFiService* WiFiService::CreateService() { return new WiFiServiceImpl(); }
907 1006
908 } // namespace wifi 1007 } // namespace wifi
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698