| 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 72545d9df94cf983ec7be1852d5b74d07db1655e..d4f8d66dd597f578908b836c67174f5393f2472c 100644
|
| --- a/chrome/utility/wifi/wifi_service_win.cc
|
| +++ b/chrome/utility/wifi/wifi_service_win.cc
|
| @@ -43,86 +43,86 @@ const char kWlanOpenHandle[] = "WlanOpenHandle";
|
| const char kWlanRegisterNotification[] = "WlanRegisterNotification";
|
| const char kWlanSaveTemporaryProfile[] = "WlanSaveTemporaryProfile";
|
| const char kWlanScan[] = "WlanScan";
|
| -
|
| -// WlanApi function definitions
|
| -typedef DWORD (WINAPI* WlanConnectFunction)(
|
| - HANDLE hClientHandle,
|
| - CONST GUID *pInterfaceGuid,
|
| - CONST PWLAN_CONNECTION_PARAMETERS pConnectionParameters,
|
| - PVOID pReserved);
|
| -
|
| -typedef DWORD (WINAPI* WlanCloseHandleFunction)(
|
| - HANDLE hClientHandle,
|
| - PVOID pReserved);
|
| -
|
| -typedef DWORD (WINAPI* WlanDisconnectFunction)(
|
| - HANDLE hClientHandle,
|
| - CONST GUID *pInterfaceGuid,
|
| - PVOID pReserved);
|
| -
|
| -typedef DWORD (WINAPI* WlanEnumInterfacesFunction)(
|
| - HANDLE hClientHandle,
|
| - PVOID pReserved,
|
| - PWLAN_INTERFACE_INFO_LIST *ppInterfaceList);
|
| -
|
| -typedef VOID (WINAPI* WlanFreeMemoryFunction)(
|
| - _In_ PVOID pMemory);
|
| -
|
| -typedef DWORD (WINAPI* WlanGetAvailableNetworkListFunction)(
|
| - HANDLE hClientHandle,
|
| - CONST GUID *pInterfaceGuid,
|
| - DWORD dwFlags,
|
| - PVOID pReserved,
|
| - PWLAN_AVAILABLE_NETWORK_LIST *ppAvailableNetworkList);
|
| -
|
| -typedef DWORD (WINAPI* WlanGetNetworkBssListFunction)(
|
| - HANDLE hClientHandle,
|
| - const GUID* pInterfaceGuid,
|
| - const PDOT11_SSID pDot11Ssid,
|
| - DOT11_BSS_TYPE dot11BssType,
|
| - BOOL bSecurityEnabled,
|
| - PVOID pReserved,
|
| - PWLAN_BSS_LIST* ppWlanBssList);
|
| -
|
| -typedef DWORD (WINAPI* WlanGetProfileFunction)(
|
| - HANDLE hClientHandle,
|
| - CONST GUID *pInterfaceGuid,
|
| - LPCWSTR strProfileName,
|
| - PVOID pReserved,
|
| - LPWSTR *pstrProfileXml,
|
| - DWORD *pdwFlags,
|
| - DWORD *pdwGrantedAccess);
|
| -
|
| -typedef DWORD (WINAPI* WlanOpenHandleFunction)(
|
| - DWORD dwClientVersion,
|
| - PVOID pReserved,
|
| - PDWORD pdwNegotiatedVersion,
|
| - PHANDLE phClientHandle);
|
| -
|
| -typedef DWORD (WINAPI* WlanRegisterNotificationFunction)(
|
| - HANDLE hClientHandle,
|
| - DWORD dwNotifSource,
|
| - BOOL bIgnoreDuplicate,
|
| - WLAN_NOTIFICATION_CALLBACK funcCallback,
|
| - PVOID pCallbackContext,
|
| - PVOID pReserved,
|
| - PDWORD pdwPrevNotifSource);
|
| -
|
| -typedef DWORD (WINAPI* WlanSaveTemporaryProfileFunction)(
|
| - HANDLE hClientHandle,
|
| - CONST GUID* pInterfaceGuid,
|
| - LPCWSTR strProfileName,
|
| - LPCWSTR strAllUserProfileSecurity,
|
| - DWORD dwFlags,
|
| - BOOL bOverWrite,
|
| - PVOID pReserved);
|
| -
|
| -typedef DWORD (WINAPI* WlanScanFunction)(
|
| - HANDLE hClientHandle,
|
| - CONST GUID *pInterfaceGuid,
|
| - CONST PDOT11_SSID pDot11Ssid,
|
| - CONST PWLAN_RAW_DATA pIeData,
|
| - PVOID pReserved);
|
| +
|
| +// WlanApi function definitions
|
| +typedef DWORD (WINAPI* WlanConnectFunction)(
|
| + HANDLE hClientHandle,
|
| + CONST GUID *pInterfaceGuid,
|
| + CONST PWLAN_CONNECTION_PARAMETERS pConnectionParameters,
|
| + PVOID pReserved);
|
| +
|
| +typedef DWORD (WINAPI* WlanCloseHandleFunction)(
|
| + HANDLE hClientHandle,
|
| + PVOID pReserved);
|
| +
|
| +typedef DWORD (WINAPI* WlanDisconnectFunction)(
|
| + HANDLE hClientHandle,
|
| + CONST GUID *pInterfaceGuid,
|
| + PVOID pReserved);
|
| +
|
| +typedef DWORD (WINAPI* WlanEnumInterfacesFunction)(
|
| + HANDLE hClientHandle,
|
| + PVOID pReserved,
|
| + PWLAN_INTERFACE_INFO_LIST *ppInterfaceList);
|
| +
|
| +typedef VOID (WINAPI* WlanFreeMemoryFunction)(
|
| + _In_ PVOID pMemory);
|
| +
|
| +typedef DWORD (WINAPI* WlanGetAvailableNetworkListFunction)(
|
| + HANDLE hClientHandle,
|
| + CONST GUID *pInterfaceGuid,
|
| + DWORD dwFlags,
|
| + PVOID pReserved,
|
| + PWLAN_AVAILABLE_NETWORK_LIST *ppAvailableNetworkList);
|
| +
|
| +typedef DWORD (WINAPI* WlanGetNetworkBssListFunction)(
|
| + HANDLE hClientHandle,
|
| + const GUID* pInterfaceGuid,
|
| + const PDOT11_SSID pDot11Ssid,
|
| + DOT11_BSS_TYPE dot11BssType,
|
| + BOOL bSecurityEnabled,
|
| + PVOID pReserved,
|
| + PWLAN_BSS_LIST* ppWlanBssList);
|
| +
|
| +typedef DWORD (WINAPI* WlanGetProfileFunction)(
|
| + HANDLE hClientHandle,
|
| + CONST GUID *pInterfaceGuid,
|
| + LPCWSTR strProfileName,
|
| + PVOID pReserved,
|
| + LPWSTR *pstrProfileXml,
|
| + DWORD *pdwFlags,
|
| + DWORD *pdwGrantedAccess);
|
| +
|
| +typedef DWORD (WINAPI* WlanOpenHandleFunction)(
|
| + DWORD dwClientVersion,
|
| + PVOID pReserved,
|
| + PDWORD pdwNegotiatedVersion,
|
| + PHANDLE phClientHandle);
|
| +
|
| +typedef DWORD (WINAPI* WlanRegisterNotificationFunction)(
|
| + HANDLE hClientHandle,
|
| + DWORD dwNotifSource,
|
| + BOOL bIgnoreDuplicate,
|
| + WLAN_NOTIFICATION_CALLBACK funcCallback,
|
| + PVOID pCallbackContext,
|
| + PVOID pReserved,
|
| + PDWORD pdwPrevNotifSource);
|
| +
|
| +typedef DWORD (WINAPI* WlanSaveTemporaryProfileFunction)(
|
| + HANDLE hClientHandle,
|
| + CONST GUID* pInterfaceGuid,
|
| + LPCWSTR strProfileName,
|
| + LPCWSTR strAllUserProfileSecurity,
|
| + DWORD dwFlags,
|
| + BOOL bOverWrite,
|
| + PVOID pReserved);
|
| +
|
| +typedef DWORD (WINAPI* WlanScanFunction)(
|
| + HANDLE hClientHandle,
|
| + CONST GUID *pInterfaceGuid,
|
| + CONST PDOT11_SSID pDot11Ssid,
|
| + CONST PWLAN_RAW_DATA pIeData,
|
| + PVOID pReserved);
|
|
|
| } // namespace
|
|
|
| @@ -164,6 +164,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;
|
|
|
| @@ -283,12 +284,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);
|
|
|
| @@ -307,16 +316,16 @@ class WiFiServiceImpl : public WiFiService, base::NonThreadSafe {
|
| void NotifyNetworkChanged(const std::string& network_guid);
|
|
|
| // Load WlanApi.dll from SystemDirectory and get Api function pointers.
|
| - DWORD LoadWlanLibrary();
|
| - // Instance of WlanApi.dll.
|
| - HINSTANCE wlan_api_library_;
|
| + DWORD LoadWlanLibrary();
|
| + // Instance of WlanApi.dll.
|
| + HINSTANCE wlan_api_library_;
|
| // WlanApi function pointers
|
| - WlanConnectFunction WlanConnect_function_;
|
| - WlanCloseHandleFunction WlanCloseHandle_function_;
|
| - WlanDisconnectFunction WlanDisconnect_function_;
|
| - WlanEnumInterfacesFunction WlanEnumInterfaces_function_;
|
| - WlanFreeMemoryFunction WlanFreeMemory_function_;
|
| - WlanGetAvailableNetworkListFunction WlanGetAvailableNetworkList_function_;
|
| + WlanConnectFunction WlanConnect_function_;
|
| + WlanCloseHandleFunction WlanCloseHandle_function_;
|
| + WlanDisconnectFunction WlanDisconnect_function_;
|
| + WlanEnumInterfacesFunction WlanEnumInterfaces_function_;
|
| + WlanFreeMemoryFunction WlanFreeMemory_function_;
|
| + WlanGetAvailableNetworkListFunction WlanGetAvailableNetworkList_function_;
|
| // WlanGetNetworkBssList function may not be avaiable on Windows XP.
|
| WlanGetNetworkBssListFunction WlanGetNetworkBssList_function_;
|
| WlanGetProfileFunction WlanGetProfile_function_;
|
| @@ -456,9 +465,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;
|
| @@ -466,14 +476,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).
|
| @@ -642,82 +652,82 @@ void WiFiServiceImpl::SortNetworks(NetworkList* networks) {
|
| }
|
|
|
|
|
| -DWORD WiFiServiceImpl::LoadWlanLibrary() {
|
| - // Use an absolute path to load the DLL to avoid DLL preloading attacks.
|
| - base::FilePath path;
|
| - if (!PathService::Get(base::DIR_SYSTEM, &path)) {
|
| - DLOG(ERROR) << "Unable to get system path.";
|
| - return ERROR_NOT_FOUND;
|
| - }
|
| - wlan_api_library_ = ::LoadLibraryEx(path.Append(kWlanApiDll).value().c_str(),
|
| - NULL,
|
| - LOAD_WITH_ALTERED_SEARCH_PATH);
|
| - if (!wlan_api_library_) {
|
| - DLOG(ERROR) << "Unable to load WlanApi.dll.";
|
| - return ERROR_NOT_FOUND;
|
| - }
|
| -
|
| +DWORD WiFiServiceImpl::LoadWlanLibrary() {
|
| + // Use an absolute path to load the DLL to avoid DLL preloading attacks.
|
| + base::FilePath path;
|
| + if (!PathService::Get(base::DIR_SYSTEM, &path)) {
|
| + DLOG(ERROR) << "Unable to get system path.";
|
| + return ERROR_NOT_FOUND;
|
| + }
|
| + wlan_api_library_ = ::LoadLibraryEx(path.Append(kWlanApiDll).value().c_str(),
|
| + NULL,
|
| + LOAD_WITH_ALTERED_SEARCH_PATH);
|
| + if (!wlan_api_library_) {
|
| + DLOG(ERROR) << "Unable to load WlanApi.dll.";
|
| + return ERROR_NOT_FOUND;
|
| + }
|
| +
|
| // Initialize WlanApi function pointers
|
| - WlanConnect_function_ =
|
| - reinterpret_cast<WlanConnectFunction>(
|
| - ::GetProcAddress(wlan_api_library_, kWlanConnect));
|
| - WlanCloseHandle_function_ =
|
| - reinterpret_cast<WlanCloseHandleFunction>(
|
| - ::GetProcAddress(wlan_api_library_, kWlanCloseHandle));
|
| - WlanDisconnect_function_ =
|
| - reinterpret_cast<WlanDisconnectFunction>(
|
| - ::GetProcAddress(wlan_api_library_, kWlanDisconnect));
|
| - WlanEnumInterfaces_function_ =
|
| - reinterpret_cast<WlanEnumInterfacesFunction>(
|
| - ::GetProcAddress(wlan_api_library_, kWlanEnumInterfaces));
|
| - WlanFreeMemory_function_ =
|
| - reinterpret_cast<WlanFreeMemoryFunction>(
|
| - ::GetProcAddress(wlan_api_library_, kWlanFreeMemory));
|
| - WlanGetAvailableNetworkList_function_ =
|
| - reinterpret_cast<WlanGetAvailableNetworkListFunction>(
|
| - ::GetProcAddress(wlan_api_library_, kWlanGetAvailableNetworkList));
|
| - WlanGetNetworkBssList_function_ =
|
| - reinterpret_cast<WlanGetNetworkBssListFunction>(
|
| - ::GetProcAddress(wlan_api_library_, kWlanGetNetworkBssList));
|
| - WlanGetProfile_function_ =
|
| - reinterpret_cast<WlanGetProfileFunction>(
|
| - ::GetProcAddress(wlan_api_library_, kWlanGetProfile));
|
| - WlanOpenHandle_function_ =
|
| - reinterpret_cast<WlanOpenHandleFunction>(
|
| - ::GetProcAddress(wlan_api_library_, kWlanOpenHandle));
|
| - WlanRegisterNotification_function_ =
|
| - reinterpret_cast<WlanRegisterNotificationFunction>(
|
| - ::GetProcAddress(wlan_api_library_, kWlanRegisterNotification));
|
| - WlanSaveTemporaryProfile_function_ =
|
| - reinterpret_cast<WlanSaveTemporaryProfileFunction>(
|
| - ::GetProcAddress(wlan_api_library_, kWlanSaveTemporaryProfile));
|
| - WlanScan_function_ =
|
| - reinterpret_cast<WlanScanFunction>(
|
| - ::GetProcAddress(wlan_api_library_, kWlanScan));
|
| -
|
| - if (!WlanConnect_function_ ||
|
| - !WlanCloseHandle_function_ ||
|
| - !WlanDisconnect_function_ ||
|
| - !WlanEnumInterfaces_function_ ||
|
| - !WlanFreeMemory_function_ ||
|
| - !WlanGetAvailableNetworkList_function_ ||
|
| - !WlanGetProfile_function_ ||
|
| - !WlanOpenHandle_function_ ||
|
| - !WlanRegisterNotification_function_ ||
|
| - !WlanScan_function_) {
|
| - DLOG(ERROR) << "Unable to find required WlanApi function.";
|
| - FreeLibrary(wlan_api_library_);
|
| - wlan_api_library_ = NULL;
|
| - return ERROR_NOT_FOUND;
|
| - }
|
| -
|
| - // Some WlanApi functions may not be available on XP.
|
| - if (!WlanGetNetworkBssList_function_ ||
|
| - !WlanSaveTemporaryProfile_function_) {
|
| - DLOG(INFO) << "WlanApi function is not be available on XP.";
|
| - }
|
| -
|
| - return ERROR_SUCCESS;
|
| + WlanConnect_function_ =
|
| + reinterpret_cast<WlanConnectFunction>(
|
| + ::GetProcAddress(wlan_api_library_, kWlanConnect));
|
| + WlanCloseHandle_function_ =
|
| + reinterpret_cast<WlanCloseHandleFunction>(
|
| + ::GetProcAddress(wlan_api_library_, kWlanCloseHandle));
|
| + WlanDisconnect_function_ =
|
| + reinterpret_cast<WlanDisconnectFunction>(
|
| + ::GetProcAddress(wlan_api_library_, kWlanDisconnect));
|
| + WlanEnumInterfaces_function_ =
|
| + reinterpret_cast<WlanEnumInterfacesFunction>(
|
| + ::GetProcAddress(wlan_api_library_, kWlanEnumInterfaces));
|
| + WlanFreeMemory_function_ =
|
| + reinterpret_cast<WlanFreeMemoryFunction>(
|
| + ::GetProcAddress(wlan_api_library_, kWlanFreeMemory));
|
| + WlanGetAvailableNetworkList_function_ =
|
| + reinterpret_cast<WlanGetAvailableNetworkListFunction>(
|
| + ::GetProcAddress(wlan_api_library_, kWlanGetAvailableNetworkList));
|
| + WlanGetNetworkBssList_function_ =
|
| + reinterpret_cast<WlanGetNetworkBssListFunction>(
|
| + ::GetProcAddress(wlan_api_library_, kWlanGetNetworkBssList));
|
| + WlanGetProfile_function_ =
|
| + reinterpret_cast<WlanGetProfileFunction>(
|
| + ::GetProcAddress(wlan_api_library_, kWlanGetProfile));
|
| + WlanOpenHandle_function_ =
|
| + reinterpret_cast<WlanOpenHandleFunction>(
|
| + ::GetProcAddress(wlan_api_library_, kWlanOpenHandle));
|
| + WlanRegisterNotification_function_ =
|
| + reinterpret_cast<WlanRegisterNotificationFunction>(
|
| + ::GetProcAddress(wlan_api_library_, kWlanRegisterNotification));
|
| + WlanSaveTemporaryProfile_function_ =
|
| + reinterpret_cast<WlanSaveTemporaryProfileFunction>(
|
| + ::GetProcAddress(wlan_api_library_, kWlanSaveTemporaryProfile));
|
| + WlanScan_function_ =
|
| + reinterpret_cast<WlanScanFunction>(
|
| + ::GetProcAddress(wlan_api_library_, kWlanScan));
|
| +
|
| + if (!WlanConnect_function_ ||
|
| + !WlanCloseHandle_function_ ||
|
| + !WlanDisconnect_function_ ||
|
| + !WlanEnumInterfaces_function_ ||
|
| + !WlanFreeMemory_function_ ||
|
| + !WlanGetAvailableNetworkList_function_ ||
|
| + !WlanGetProfile_function_ ||
|
| + !WlanOpenHandle_function_ ||
|
| + !WlanRegisterNotification_function_ ||
|
| + !WlanScan_function_) {
|
| + DLOG(ERROR) << "Unable to find required WlanApi function.";
|
| + FreeLibrary(wlan_api_library_);
|
| + wlan_api_library_ = NULL;
|
| + return ERROR_NOT_FOUND;
|
| + }
|
| +
|
| + // Some WlanApi functions may not be available on XP.
|
| + if (!WlanGetNetworkBssList_function_ ||
|
| + !WlanSaveTemporaryProfile_function_) {
|
| + DLOG(INFO) << "WlanApi function is not be available on XP.";
|
| + }
|
| +
|
| + return ERROR_SUCCESS;
|
| }
|
|
|
| DWORD WiFiServiceImpl::OpenClientHandle() {
|
| @@ -1062,39 +1072,128 @@ 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) {
|
| if (client_ == NULL) {
|
| NOTREACHED();
|
| return ERROR_NOINTERFACE;
|
| }
|
|
|
| + desired_list->reset();
|
| +
|
| + if (frequency == kFrequencyAny)
|
| + return ERROR_SUCCESS;
|
| +
|
| + // 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.
|
| + if (!WlanGetNetworkBssList_function_)
|
| + return ERROR_NOT_SUPPORTED;
|
| +
|
| 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_function_(
|
| - 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_function_(
|
| - client_, &interface_guid_, &wlan_params, NULL);
|
| + error = WlanGetNetworkBssList_function_(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_function_(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_function_(
|
| + 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_function_(
|
| + client_, &interface_guid_, &wlan_params, NULL);
|
| + }
|
| }
|
|
|
| return error;
|
|
|