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 |