Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |