Chromium Code Reviews| Index: chrome/utility/wifi/wifi_service_win.cc |
| diff --git a/chrome/utility/wifi/wifi_service_win.cc b/chrome/utility/wifi/wifi_service_win.cc |
| index d9de098143bf8db2845b44983f9dd782646d8256..1009442643b7b26ac614b862a5f5271c16c7a88d 100644 |
| --- a/chrome/utility/wifi/wifi_service_win.cc |
| +++ b/chrome/utility/wifi/wifi_service_win.cc |
| @@ -19,10 +19,10 @@ |
| namespace { |
| const char kWiFiServiceError[] = "Error.WiFiService"; |
| -const wchar_t kNwCategoryWizardRegKey[] = |
| - L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Network\\" |
| - L"NwCategoryWizard"; |
| -const wchar_t kNwCategoryWizardRegValue[] = L"Show"; |
| +const wchar_t kNwCategoryWizardRegKey[] = |
| + L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Network\\" |
| + L"NwCategoryWizard"; |
| +const wchar_t kNwCategoryWizardRegValue[] = L"Show"; |
| } // namespace |
| namespace wifi { |
| @@ -59,6 +59,7 @@ class WiFiServiceImpl : public WiFiService, base::NonThreadSafe { |
| virtual void RequestNetworkScan() OVERRIDE; |
| virtual void StartConnect(const std::string& network_guid, |
| + Frequency frequency, |
| const StringResultCallback& callback, |
| const ErrorCallback& error_callback) OVERRIDE; |
| @@ -179,12 +180,20 @@ class WiFiServiceImpl : public WiFiService, base::NonThreadSafe { |
| DWORD FindConnectedNetwork(std::string* connected_network_guid); |
| // Connect to network |network_guid| using previosly stored profile if exists, |
| - // or just network sid. |
| - DWORD Connect(const std::string& network_guid); |
| + // or just network sid. If |frequency| is not |kFrequencyUnknown| then |
| + // connects only to BSS which uses that frequency and returns |
| + // |ERROR_NOT_FOUND| if such BSS cannot be found. |
| + DWORD Connect(const std::string& network_guid, Frequency frequency); |
| // Disconnect from currently connected network if any. |
| DWORD Disconnect(); |
| + // Get DOT11_BSSID_LIST of desired BSSIDs to connect to |ssid| network on |
| + // given |frequency|. |
| + DWORD GetDesiredBssList(DOT11_SSID& ssid, |
| + Frequency frequency, |
| + scoped_ptr<DOT11_BSSID_LIST>* desired_list); |
| + |
| // Save temporary wireless profile for |network_guid|. |
| DWORD SaveTempProfile(const std::string& network_guid); |
| @@ -306,9 +315,10 @@ void WiFiServiceImpl::RequestNetworkScan() { |
| } |
| void WiFiServiceImpl::StartConnect(const std::string& network_guid, |
| + Frequency frequency, |
| const StringResultCallback& callback, |
| const ErrorCallback& error_callback) { |
| - DLOG(INFO) << "Start Connect: " << network_guid; |
| + DLOG(INFO) << "Start Connect: " << network_guid << " " << frequency << " MHz"; |
| DWORD error = EnsureInitialized(); |
| if (error == ERROR_SUCCESS) { |
| std::string connected_network_guid; |
| @@ -316,14 +326,14 @@ void WiFiServiceImpl::StartConnect(const std::string& network_guid, |
| if (error == ERROR_SUCCESS) { |
| // Connect only if network |network_guid| is not connected already. |
| if (network_guid != connected_network_guid) |
| - error = Connect(network_guid); |
| + error = Connect(network_guid, frequency); |
| if (error == ERROR_SUCCESS) { |
| - DisableNwCategoryWizard(); |
| callback.Run(network_guid); |
| // Notify that previously connected network has changed. |
| NotifyNetworkChanged(connected_network_guid); |
| // Start waiting for network connection state change. |
| if (!networks_changed_observer_.is_null()) { |
| + DisableNwCategoryWizard(); |
| // Disable automatic network change notifications as they get fired |
| // when network is just connected, but not yet accessible (doesn't |
| // have valid IP address). |
| @@ -376,6 +386,9 @@ void WiFiServiceImpl::OnWlanNotificationCallback( |
| void WiFiServiceImpl::OnWlanNotification( |
| PWLAN_NOTIFICATION_DATA wlan_notification_data) { |
| + if (!task_runner_) |
| + return; |
| + |
| switch (wlan_notification_data->NotificationCode) { |
| case wlan_notification_acm_disconnected: |
| case wlan_notification_acm_connection_complete: |
| @@ -496,7 +509,7 @@ DWORD WiFiServiceImpl::OpenClientHandle() { |
| DWORD service_version = 0; |
| // Open a handle to the service. |
| - error = ::WlanOpenHandle(1, NULL, &service_version, &client_); |
| + error = ::WlanOpenHandle(WLAN_API_VERSION, NULL, &service_version, &client_); |
| PWLAN_INTERFACE_INFO_LIST interface_list = NULL; |
| if (error == ERROR_SUCCESS) { |
| @@ -779,37 +792,123 @@ DWORD WiFiServiceImpl::FindConnectedNetwork( |
| return error; |
| } |
| -DWORD WiFiServiceImpl::Connect(const std::string& network_guid) { |
| +DWORD WiFiServiceImpl::GetDesiredBssList( |
| + DOT11_SSID& ssid, |
| + Frequency frequency, |
| + 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
|
| if (client_ == NULL) { |
| NOTREACHED(); |
| return ERROR_NOINTERFACE; |
| } |
| + desired_list->reset(); |
| + |
| + if (frequency == kFrequencyUnknown) |
| + return ERROR_SUCCESS; |
| + |
| DWORD error = ERROR_SUCCESS; |
| - base::string16 profile_name = ProfileNameFromGUID(network_guid); |
| + PWLAN_BSS_LIST bss_list = NULL; |
| - if (HaveProfile(network_guid)) { |
| - WLAN_CONNECTION_PARAMETERS wlan_params = { |
| - wlan_connection_mode_profile, |
| - profile_name.c_str(), |
| - NULL, |
| - NULL, |
| - dot11_BSS_type_any, |
| - 0}; |
| - error = ::WlanConnect(client_, &interface_guid_, &wlan_params, NULL); |
| - } else { |
| - // TODO(mef): wlan_connection_mode_discovery_unsecure is not available on |
| - // XP. If XP support is needed, then temporary profile will have to be |
| - // created. |
| - DOT11_SSID ssid = SSIDFromGUID(network_guid); |
| - WLAN_CONNECTION_PARAMETERS wlan_params = { |
| - wlan_connection_mode_discovery_unsecure, |
| - NULL, |
| - &ssid, |
| - NULL, |
| - dot11_BSS_type_infrastructure, |
| - 0}; |
| - error = ::WlanConnect(client_, &interface_guid_, &wlan_params, NULL); |
| + // TODO(mef): WlanGetNetworkBssList is not available on XP. If XP support is |
| + // needed, then different method of getting BSS (e.g. OID query) will have |
| + // to be used. |
| + error = ::WlanGetNetworkBssList(client_, |
| + &interface_guid_, |
| + NULL, |
| + dot11_BSS_type_any, |
| + FALSE, |
| + NULL, |
| + &bss_list); |
| + if (error == ERROR_SUCCESS && NULL != bss_list) { |
| + unsigned int best_quality = 0u; |
| + size_t best_index = 0; |
| + Frequency bss_frequency; |
| + |
| + // Go through bss_list and find best quality BSSID with matching frequency. |
| + for (size_t bss = 0; bss < bss_list->dwNumberOfItems; ++bss) { |
| + const WLAN_BSS_ENTRY& bss_entry(bss_list->wlanBssEntries[bss]); |
| + if (bss_entry.dot11Ssid.uSSIDLength != ssid.uSSIDLength || |
| + 0 != memcmp(bss_entry.dot11Ssid.ucSSID, |
| + ssid.ucSSID, |
| + bss_entry.dot11Ssid.uSSIDLength)) |
| + continue; |
| + |
| + if (bss_entry.ulChCenterFrequency < 3000000) |
| + bss_frequency = kFrequency2400; |
| + else |
| + bss_frequency = kFrequency5000; |
| + |
| + if (bss_frequency == frequency && |
| + bss_entry.uLinkQuality > best_quality) { |
| + best_quality = bss_entry.uLinkQuality; |
| + best_index = bss; |
| + } |
| + } |
| + |
| + // If any matching BSS were found, prepare the header. |
| + if (best_quality > 0) { |
| + const WLAN_BSS_ENTRY& bss_entry(bss_list->wlanBssEntries[best_index]); |
| + scoped_ptr<DOT11_BSSID_LIST> selected_list(new DOT11_BSSID_LIST); |
| + |
| + selected_list->Header.Revision = DOT11_BSSID_LIST_REVISION_1; |
| + selected_list->Header.Size = sizeof(DOT11_BSSID_LIST); |
| + selected_list->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; |
| + selected_list->uNumOfEntries = 1; |
| + selected_list->uTotalNumOfEntries = 1; |
| + std::copy(bss_entry.dot11Bssid, |
| + bss_entry.dot11Bssid+sizeof(bss_entry.dot11Bssid), |
| + selected_list->BSSIDs[0]); |
| + desired_list->swap(selected_list); |
| + DLOG(INFO) << "Quality: " << best_quality << " BSS: " |
| + << NetworkProperties::MacAddressAsString(bss_entry.dot11Bssid); |
| + } else { |
| + error = ERROR_NOT_FOUND; |
| + } |
| + } |
| + |
| + // clean up |
| + if (bss_list != NULL) { |
| + ::WlanFreeMemory(bss_list); |
| + } |
| + return error; |
| +} |
| + |
| + |
| +DWORD WiFiServiceImpl::Connect(const std::string& network_guid, |
| + Frequency frequency) { |
| + if (client_ == NULL) { |
| + NOTREACHED(); |
| + return ERROR_NOINTERFACE; |
| + } |
| + |
| + DWORD error = ERROR_SUCCESS; |
| + DOT11_SSID ssid = SSIDFromGUID(network_guid); |
| + scoped_ptr<DOT11_BSSID_LIST> desired_bss_list; |
| + error = GetDesiredBssList(ssid, frequency, &desired_bss_list); |
| + if (error == ERROR_SUCCESS) { |
| + if (HaveProfile(network_guid)) { |
| + base::string16 profile_name = ProfileNameFromGUID(network_guid); |
| + WLAN_CONNECTION_PARAMETERS wlan_params = { |
| + wlan_connection_mode_profile, |
| + profile_name.c_str(), |
| + NULL, |
| + desired_bss_list.get(), |
| + dot11_BSS_type_any, |
| + 0}; |
| + error = ::WlanConnect(client_, &interface_guid_, &wlan_params, NULL); |
| + } else { |
| + // TODO(mef): wlan_connection_mode_discovery_unsecure is not available on |
| + // XP. If XP support is needed, then temporary profile will have to be |
| + // created. |
| + WLAN_CONNECTION_PARAMETERS wlan_params = { |
| + wlan_connection_mode_discovery_unsecure, |
| + NULL, |
| + &ssid, |
| + desired_bss_list.get(), |
| + dot11_BSS_type_infrastructure, |
| + 0}; |
| + error = ::WlanConnect(client_, &interface_guid_, &wlan_params, NULL); |
| + } |
| } |
| return error; |