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

Unified 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 side-by-side diff with in-line comments
Download patch
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;

Powered by Google App Engine
This is Rietveld 408576698