OLD | NEW |
(Empty) | |
| 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 |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "chrome/utility/wifi/wifi_service.h" |
| 6 |
| 7 #include <iphlpapi.h> |
| 8 #include <objbase.h> |
| 9 #include <wlanapi.h> |
| 10 |
| 11 #include "base/bind.h" |
| 12 #include "base/memory/ref_counted.h" |
| 13 #include "base/message_loop/message_loop.h" |
| 14 #include "base/strings/string16.h" |
| 15 #include "base/strings/string_util.h" |
| 16 #include "base/strings/utf_string_conversions.h" |
| 17 |
| 18 // TODO(mef): Verify that wlanapi.dll is delay loaded. |
| 19 #pragma comment(lib, "Wlanapi.lib") |
| 20 |
| 21 class WiFiServiceImpl : public WiFiService { |
| 22 public: |
| 23 WiFiServiceImpl() : client_(NULL) { |
| 24 OpenClientHandle(); |
| 25 } |
| 26 |
| 27 virtual ~WiFiServiceImpl() { CloseClientHandle(); } |
| 28 |
| 29 virtual void GetProperties(const std::string& network_guid, |
| 30 const NetworkPropertiesCallback& callback, |
| 31 const ErrorCallback& error_callback) { |
| 32 DWORD error = CheckClientHandle(); |
| 33 |
| 34 if (error == ERROR_SUCCESS) { |
| 35 NetworkList network_list; |
| 36 error = GetVisibleNetworkList(&network_list); |
| 37 if (error == ERROR_SUCCESS && !network_list.empty()) { |
| 38 NetworkList::iterator it = FindNetwork(network_list, network_guid); |
| 39 if (it != network_list.end()) |
| 40 callback.Run(network_guid, *it); |
| 41 else |
| 42 error = ERROR_NOT_FOUND; |
| 43 } |
| 44 } |
| 45 |
| 46 CheckError(error_callback, "Error.DBusFailed", error); |
| 47 } |
| 48 |
| 49 virtual void GetState(const std::string& network_guid, |
| 50 const NetworkPropertiesCallback& callback, |
| 51 const ErrorCallback& error_callback) OVERRIDE {} |
| 52 |
| 53 virtual void GetManagedProperties( |
| 54 const std::string& network_guid, |
| 55 const DictionaryResultCallback& callback, |
| 56 const ErrorCallback& error_callback) OVERRIDE {} |
| 57 |
| 58 virtual void SetProperties(const std::string& network_guid, |
| 59 const base::DictionaryValue& properties, |
| 60 const StringResultCallback& callback, |
| 61 const ErrorCallback& error_callback) OVERRIDE {} |
| 62 |
| 63 virtual void GetVisibleNetworks( |
| 64 const NetworkListCallback& callback, |
| 65 const ErrorCallback& error_callback) OVERRIDE { |
| 66 DWORD error = CheckClientHandle(); |
| 67 |
| 68 if (error == ERROR_SUCCESS) { |
| 69 NetworkList network_list; |
| 70 error = GetVisibleNetworkList(&network_list); |
| 71 if (error == ERROR_SUCCESS && !network_list.empty()) { |
| 72 SortNetworks(network_list); |
| 73 callback.Run(network_list); |
| 74 } |
| 75 } |
| 76 |
| 77 CheckError(error_callback, "Error.DBusFailed", error); |
| 78 } |
| 79 |
| 80 virtual void RequestNetworkScan() OVERRIDE { |
| 81 DWORD error = CheckClientHandle(); |
| 82 if (error == ERROR_SUCCESS) { |
| 83 WlanScan(client_, &interface_guid_, NULL, NULL, NULL); |
| 84 } |
| 85 } |
| 86 |
| 87 virtual void StartConnect(const std::string& network_guid, |
| 88 const StringResultCallback& callback, |
| 89 const ErrorCallback& error_callback) OVERRIDE { |
| 90 DWORD error = CheckClientHandle(); |
| 91 if (error == ERROR_SUCCESS) { |
| 92 std::string connected_network_guid; |
| 93 error = SaveCurrentConnectedNetwork(&connected_network_guid); |
| 94 if (error == ERROR_SUCCESS) { |
| 95 error = Connect(network_guid); |
| 96 if (error == ERROR_SUCCESS) { |
| 97 callback.Run(network_guid); |
| 98 // Notify that previously connected network has changed. |
| 99 NotifyNetworkChanged(connected_network_guid); |
| 100 // Start waiting for network connection state change. |
| 101 if (!networks_changed_observer_.is_null()) |
| 102 WaitForNetworkConnect(network_guid, 0); |
| 103 } |
| 104 } |
| 105 } |
| 106 CheckError(error_callback, "Error.DBusFailed", error); |
| 107 } |
| 108 |
| 109 virtual void StartDisconnect(const std::string& network_guid, |
| 110 const StringResultCallback& callback, |
| 111 const ErrorCallback& error_callback) OVERRIDE { |
| 112 DWORD error = CheckClientHandle(); |
| 113 |
| 114 if (error == ERROR_SUCCESS) { |
| 115 std::string connected_network_guid; |
| 116 error = SaveCurrentConnectedNetwork(&connected_network_guid); |
| 117 if (error == ERROR_SUCCESS && network_guid == connected_network_guid) { |
| 118 error = Disconnect(); |
| 119 if (error == ERROR_SUCCESS) { |
| 120 callback.Run(network_guid); |
| 121 } |
| 122 } |
| 123 } |
| 124 CheckError(error_callback, "Error.DBusFailed", error); |
| 125 } |
| 126 |
| 127 virtual void SetNetworksChangedObserver( |
| 128 const NetworkGuidListCallback& observer) OVERRIDE { |
| 129 networks_changed_observer_ = observer; |
| 130 } |
| 131 |
| 132 virtual void SetNetworkListChangedObserver( |
| 133 const NetworkGuidListCallback& observer) OVERRIDE { |
| 134 network_list_changed_observer_ = observer; |
| 135 } |
| 136 |
| 137 private: |
| 138 static void __stdcall OnWlanNotificationCallback( |
| 139 PWLAN_NOTIFICATION_DATA wlan_notification_data, |
| 140 PVOID context) { |
| 141 WiFiServiceImpl* service = reinterpret_cast<WiFiServiceImpl*>(context); |
| 142 service->OnWlanNotification(wlan_notification_data); |
| 143 } |
| 144 |
| 145 void OnWlanNotification(PWLAN_NOTIFICATION_DATA wlan_notification_data) { |
| 146 PWLAN_CONNECTION_NOTIFICATION_DATA wlan_connection_data = |
| 147 reinterpret_cast<PWLAN_CONNECTION_NOTIFICATION_DATA>( |
| 148 wlan_notification_data->pData); |
| 149 |
| 150 switch (wlan_notification_data->NotificationCode) { |
| 151 case wlan_notification_acm_disconnected: |
| 152 case wlan_notification_acm_connection_complete: |
| 153 // TODO(mef): Figure out how to send notifications correctly from here. |
| 154 // NotifyNetworkChanged(GuidFromSsid(wlan_connection_data->dot11Ssid)); |
| 155 break; |
| 156 case wlan_notification_acm_connection_attempt_fail: |
| 157 break; |
| 158 case wlan_notification_acm_scan_complete: |
| 159 break; |
| 160 } |
| 161 } |
| 162 |
| 163 void WaitForNetworkConnect(const std::string& network_guid, int attempt) { |
| 164 if (attempt > kMaxAttempts) |
| 165 return; |
| 166 |
| 167 std::string connected_network_guid; |
| 168 DWORD error = FindConnectedNetwork(&connected_network_guid); |
| 169 if (network_guid == connected_network_guid) { |
| 170 // Reset DHCP to speed up the connection after Chromekey factory reset. |
| 171 error = ResetDHCP(); |
| 172 NotifyNetworkChanged(network_guid); |
| 173 } else { |
| 174 // Continue waiting for network connection state change. |
| 175 base::MessageLoop::current()->PostDelayedTask( |
| 176 FROM_HERE, |
| 177 base::Bind(&WiFiServiceImpl::WaitForNetworkConnect, |
| 178 base::Unretained(this), |
| 179 network_guid, |
| 180 ++attempt), |
| 181 base::TimeDelta::FromMilliseconds(kAttemptDelayMs)); |
| 182 } |
| 183 } |
| 184 |
| 185 bool CheckError(const ErrorCallback& error_callback, |
| 186 const std::string& error_name, |
| 187 DWORD error_code) { |
| 188 if (error_code != ERROR_SUCCESS) { |
| 189 scoped_ptr<base::DictionaryValue> error_data(new base::DictionaryValue); |
| 190 error_data->SetInteger("Win32ErrorCode", error_code); |
| 191 error_callback.Run(error_name, error_data.Pass()); |
| 192 return true; |
| 193 } |
| 194 return false; |
| 195 } |
| 196 |
| 197 NetworkList::iterator FindNetwork(NetworkList& networks, |
| 198 const std::string& network_guid) { |
| 199 for (NetworkList::iterator it = networks.begin(); it != networks.end(); |
| 200 ++it) { |
| 201 if (it->guid == network_guid) |
| 202 return it; |
| 203 } |
| 204 return networks.end(); |
| 205 } |
| 206 |
| 207 DWORD SaveCurrentConnectedNetwork(std::string* connected_network_guid) { |
| 208 // Find currently connected network. |
| 209 DWORD error = FindConnectedNetwork(connected_network_guid); |
| 210 if (error == ERROR_SUCCESS && !connected_network_guid->empty()) { |
| 211 if (error == ERROR_SUCCESS) { |
| 212 SaveTempProfile(*connected_network_guid); |
| 213 std::string profile_xml; |
| 214 error = GetProfile(*connected_network_guid, &profile_xml); |
| 215 if (error == ERROR_SUCCESS) { |
| 216 saved_profiles_xml_[*connected_network_guid] = profile_xml; |
| 217 } |
| 218 } |
| 219 } |
| 220 return error; |
| 221 } |
| 222 |
| 223 void SortNetworks(NetworkList& networks) { |
| 224 // Sort networks, so connected/connecting is up front, then by type: |
| 225 // Ethernet, WiFi, Cellular, VPN |
| 226 networks.sort(WiFiService::NetworkProperties::OrderByType); |
| 227 } |
| 228 |
| 229 // open a WLAN client handle |
| 230 DWORD OpenClientHandle() { |
| 231 CloseClientHandle(); |
| 232 |
| 233 DWORD error = ERROR_SUCCESS; |
| 234 DWORD service_version = 0; |
| 235 |
| 236 // open a handle to the service |
| 237 error = WlanOpenHandle(WLAN_API_VERSION, NULL, &service_version, &client_); |
| 238 |
| 239 PWLAN_INTERFACE_INFO_LIST pIntfList = NULL; |
| 240 UINT i = 0; |
| 241 |
| 242 if (error == ERROR_SUCCESS) { |
| 243 // enumerate wireless interfaces |
| 244 error = WlanEnumInterfaces(client_, NULL, &pIntfList); |
| 245 if (error == ERROR_SUCCESS) { |
| 246 if (pIntfList != NULL && pIntfList->dwNumberOfItems != 0) { |
| 247 // Use first interface. |
| 248 interface_guid_ = pIntfList->InterfaceInfo[0].InterfaceGuid; |
| 249 WlanRegisterNotification(client_, |
| 250 WLAN_NOTIFICATION_SOURCE_ALL, |
| 251 FALSE, |
| 252 OnWlanNotificationCallback, |
| 253 this, |
| 254 NULL, |
| 255 NULL); |
| 256 } else { |
| 257 error = ERROR_NOINTERFACE; |
| 258 } |
| 259 } |
| 260 // clean up |
| 261 if (pIntfList != NULL) |
| 262 WlanFreeMemory(pIntfList); |
| 263 } |
| 264 return error; |
| 265 } |
| 266 |
| 267 DWORD ResetDHCP() { |
| 268 IP_ADAPTER_INDEX_MAP adapter_index_map = {0}; |
| 269 DWORD error = FindAdapterIndexMapByGuid(interface_guid_, |
| 270 &adapter_index_map); |
| 271 if (error == ERROR_SUCCESS) { |
| 272 error = IpReleaseAddress(&adapter_index_map); |
| 273 if (error == ERROR_SUCCESS) { |
| 274 error = IpRenewAddress(&adapter_index_map); |
| 275 } |
| 276 } |
| 277 return error; |
| 278 } |
| 279 |
| 280 DWORD FindAdapterIndexMapByGuid(const GUID& interface_guid, |
| 281 IP_ADAPTER_INDEX_MAP* adapter_index_map) { |
| 282 string16 guid_string; |
| 283 const int kGUIDSize = 39; |
| 284 ::StringFromGUID2(interface_guid, WriteInto(&guid_string, kGUIDSize), |
| 285 kGUIDSize); |
| 286 |
| 287 ULONG buffer_length = 0; |
| 288 DWORD error = GetInterfaceInfo(NULL, &buffer_length); |
| 289 if (error == ERROR_INSUFFICIENT_BUFFER) { |
| 290 scoped_ptr<unsigned char[]> buffer(new unsigned char[buffer_length]); |
| 291 IP_INTERFACE_INFO* interface_info = |
| 292 reinterpret_cast<IP_INTERFACE_INFO*>(buffer.get()); |
| 293 error = GetInterfaceInfo(interface_info, &buffer_length); |
| 294 if (error == ERROR_SUCCESS) { |
| 295 for (long adapter = 0; adapter < interface_info->NumAdapters; |
| 296 ++adapter) { |
| 297 if (EndsWith(interface_info->Adapter[adapter].Name, guid_string, |
| 298 false)) { |
| 299 *adapter_index_map = interface_info->Adapter[adapter]; |
| 300 break; |
| 301 } |
| 302 } |
| 303 } |
| 304 } |
| 305 |
| 306 return error; |
| 307 } |
| 308 |
| 309 |
| 310 DWORD CheckClientHandle() { |
| 311 if (client_ != NULL) |
| 312 return ERROR_SUCCESS; |
| 313 return OpenClientHandle(); |
| 314 } |
| 315 |
| 316 DWORD CloseClientHandle() { |
| 317 DWORD error = ERROR_SUCCESS; |
| 318 if (client_ != NULL) { |
| 319 WlanCloseHandle(client_, NULL); |
| 320 client_ = NULL; |
| 321 } |
| 322 return error; |
| 323 } |
| 324 |
| 325 base::string16 ProfileNameFromGuid(const std::string& network_guid) const { |
| 326 return base::UTF8ToUTF16(network_guid); |
| 327 } |
| 328 |
| 329 DOT11_SSID SsidFromGuid(const std::string& network_guid) const { |
| 330 DOT11_SSID ssid = {0}; |
| 331 if (network_guid.length() <= DOT11_SSID_MAX_LENGTH) { |
| 332 ssid.uSSIDLength = network_guid.length(); |
| 333 strncpy(reinterpret_cast<char*>(ssid.ucSSID), |
| 334 network_guid.c_str(), |
| 335 ssid.uSSIDLength); |
| 336 } |
| 337 return ssid; |
| 338 } |
| 339 |
| 340 std::string GuidFromSsid(const DOT11_SSID& dot11Ssid) { |
| 341 return std::string(reinterpret_cast<const char*>(dot11Ssid.ucSSID), |
| 342 dot11Ssid.uSSIDLength); |
| 343 } |
| 344 |
| 345 std::string SsidFromWlan(const WLAN_AVAILABLE_NETWORK& wlan) { |
| 346 return GuidFromSsid(wlan.dot11Ssid); |
| 347 } |
| 348 |
| 349 |
| 350 std::string GuidFromWlan(const WLAN_AVAILABLE_NETWORK& wlan) { |
| 351 return SsidFromWlan(wlan); |
| 352 } |
| 353 |
| 354 WiFiService::Security SecurityFromDot11AuthAlg(DOT11_AUTH_ALGORITHM alg) { |
| 355 // TODO(mef): Figure out correct mapping. |
| 356 switch (alg) { |
| 357 case DOT11_AUTH_ALGO_RSNA: |
| 358 return kSecurityWPA; |
| 359 case DOT11_AUTH_ALGO_RSNA_PSK: |
| 360 return kSecurityWPA_PSK; |
| 361 case DOT11_AUTH_ALGO_80211_SHARED_KEY: |
| 362 return kSecurityWEP_PSK; |
| 363 case DOT11_AUTH_ALGO_80211_OPEN: |
| 364 return kSecurityNone; |
| 365 default: |
| 366 return kSecurityUnknown; |
| 367 } |
| 368 return kSecurityUnknown; |
| 369 } |
| 370 |
| 371 void NetworkPropertiesFromAvailableNetwork(const WLAN_AVAILABLE_NETWORK& wlan, |
| 372 const WLAN_BSS_LIST& wlan_bss_list, |
| 373 NetworkProperties* properties) { |
| 374 if (wlan.dwFlags & WLAN_AVAILABLE_NETWORK_CONNECTED) { |
| 375 properties->connection_state = WiFiService::kConnectionStateConnected; |
| 376 } else { |
| 377 properties->connection_state = WiFiService::kConnectionStateNotConnected; |
| 378 } |
| 379 |
| 380 properties->ssid = SsidFromWlan(wlan); |
| 381 properties->name = properties->ssid; |
| 382 properties->guid = GuidFromWlan(wlan); |
| 383 properties->type = WiFiService::kNetworkTypeWiFi; |
| 384 |
| 385 for (size_t bss = 0; bss < wlan_bss_list.dwNumberOfItems; ++bss) { |
| 386 const WLAN_BSS_ENTRY& bss_entry(wlan_bss_list.wlanBssEntries[bss]); |
| 387 if (bss_entry.dot11Ssid.uSSIDLength == wlan.dot11Ssid.uSSIDLength && |
| 388 0 == memcmp(bss_entry.dot11Ssid.ucSSID, |
| 389 wlan.dot11Ssid.ucSSID, |
| 390 bss_entry.dot11Ssid.uSSIDLength)) { |
| 391 if (bss_entry.ulChCenterFrequency < 3000000) |
| 392 properties->frequency = kFrequency2400; |
| 393 else |
| 394 properties->frequency = kFrequency5000; |
| 395 properties->frequency_list.push_back(properties->frequency); |
| 396 properties->bssid = WiFiService::NetworkProperties::MacAddressAsString( |
| 397 bss_entry.dot11Bssid); |
| 398 } |
| 399 } |
| 400 properties->frequency_list.sort(); |
| 401 properties->frequency_list.unique(); |
| 402 |
| 403 properties->security = |
| 404 SecurityFromDot11AuthAlg(wlan.dot11DefaultAuthAlgorithm); |
| 405 |
| 406 properties->signal_strength = wlan.wlanSignalQuality; |
| 407 } |
| 408 |
| 409 // get the list of visible wireless networks |
| 410 DWORD GetVisibleNetworkList(NetworkList* network_list) { |
| 411 DWORD error = ERROR_SUCCESS; |
| 412 |
| 413 if (client_ == NULL) { |
| 414 return ERROR_NOINTERFACE; |
| 415 } |
| 416 |
| 417 PWLAN_AVAILABLE_NETWORK_LIST pVList = NULL; |
| 418 PWLAN_BSS_LIST pWlanBssList = NULL; |
| 419 |
| 420 error = WlanGetAvailableNetworkList( |
| 421 client_, &interface_guid_, 0, NULL, &pVList); |
| 422 |
| 423 if (error == ERROR_SUCCESS && NULL != pVList) { |
| 424 error = WlanGetNetworkBssList(client_, |
| 425 &interface_guid_, |
| 426 NULL, |
| 427 dot11_BSS_type_any, |
| 428 FALSE, |
| 429 NULL, |
| 430 &pWlanBssList); |
| 431 if (error == ERROR_SUCCESS && NULL != pWlanBssList) { |
| 432 for (DWORD i = 0; i < pVList->dwNumberOfItems; ++i) { |
| 433 network_list->push_back(NetworkProperties()); |
| 434 NetworkPropertiesFromAvailableNetwork( |
| 435 pVList->Network[i], *pWlanBssList, &network_list->back()); |
| 436 } |
| 437 } |
| 438 } |
| 439 |
| 440 // clean up |
| 441 if (pVList != NULL) { |
| 442 WlanFreeMemory(pVList); |
| 443 } |
| 444 if (pWlanBssList != NULL) { |
| 445 WlanFreeMemory(pWlanBssList); |
| 446 } |
| 447 return error; |
| 448 } |
| 449 |
| 450 // Find currently connected network. |
| 451 DWORD FindConnectedNetwork(std::string* connected_network_guid) { |
| 452 DWORD error = ERROR_SUCCESS; |
| 453 |
| 454 if (client_ == NULL) { |
| 455 return ERROR_NOINTERFACE; |
| 456 } |
| 457 |
| 458 PWLAN_AVAILABLE_NETWORK_LIST pVList = NULL; |
| 459 |
| 460 error = WlanGetAvailableNetworkList( |
| 461 client_, &interface_guid_, 0, NULL, &pVList); |
| 462 |
| 463 if (error == ERROR_SUCCESS && NULL != pVList) { |
| 464 for (DWORD i = 0; i < pVList->dwNumberOfItems; ++i) { |
| 465 const WLAN_AVAILABLE_NETWORK& wlan = pVList->Network[i]; |
| 466 if (wlan.dwFlags & WLAN_AVAILABLE_NETWORK_CONNECTED) { |
| 467 *connected_network_guid = GuidFromWlan(wlan); |
| 468 break; |
| 469 } |
| 470 } |
| 471 } |
| 472 |
| 473 // clean up |
| 474 if (pVList != NULL) { |
| 475 WlanFreeMemory(pVList); |
| 476 } |
| 477 |
| 478 return error; |
| 479 } |
| 480 |
| 481 DWORD Connect(const std::string& network_guid) { |
| 482 DWORD error = ERROR_SUCCESS; |
| 483 |
| 484 if (client_ == NULL) { |
| 485 return ERROR_NOINTERFACE; |
| 486 } |
| 487 |
| 488 base::string16 profile_name = ProfileNameFromGuid(network_guid); |
| 489 |
| 490 if (HaveProfile(network_guid)) { |
| 491 WLAN_CONNECTION_PARAMETERS wlan_params = { |
| 492 wlan_connection_mode_profile, profile_name.c_str(), NULL, |
| 493 NULL, dot11_BSS_type_any, 0}; |
| 494 error = ::WlanConnect(client_, &interface_guid_, &wlan_params, NULL); |
| 495 } else { |
| 496 DOT11_SSID ssid = SsidFromGuid(network_guid); |
| 497 WLAN_CONNECTION_PARAMETERS wlan_params = { |
| 498 wlan_connection_mode_discovery_unsecure, NULL, &ssid, NULL, |
| 499 dot11_BSS_type_infrastructure, 0}; |
| 500 error = ::WlanConnect(client_, &interface_guid_, &wlan_params, NULL); |
| 501 } |
| 502 |
| 503 return error; |
| 504 } |
| 505 |
| 506 DWORD Disconnect() { |
| 507 DWORD error = ERROR_SUCCESS; |
| 508 |
| 509 if (client_ == NULL) { |
| 510 return ERROR_NOINTERFACE; |
| 511 } |
| 512 |
| 513 error = ::WlanDisconnect(client_, &interface_guid_, NULL); |
| 514 return error; |
| 515 } |
| 516 |
| 517 DWORD SaveTempProfile(const std::string& network_guid) { |
| 518 DWORD error = ERROR_SUCCESS; |
| 519 |
| 520 if (client_ == NULL) { |
| 521 return ERROR_NOINTERFACE; |
| 522 } |
| 523 |
| 524 base::string16 profile_name = ProfileNameFromGuid(network_guid); |
| 525 |
| 526 error = ::WlanSaveTemporaryProfile( |
| 527 client_, &interface_guid_, profile_name.c_str(), NULL, 0, true, NULL); |
| 528 return error; |
| 529 } |
| 530 |
| 531 DWORD GetProfile(const std::string& network_guid, std::string* profile_xml) { |
| 532 DWORD error = ERROR_SUCCESS; |
| 533 |
| 534 if (client_ == NULL) { |
| 535 return ERROR_NOINTERFACE; |
| 536 } |
| 537 |
| 538 base::string16 profile_name = ProfileNameFromGuid(network_guid); |
| 539 LPWSTR str_profile_xml = NULL; |
| 540 error = ::WlanGetProfile(client_, |
| 541 &interface_guid_, |
| 542 profile_name.c_str(), |
| 543 NULL, |
| 544 &str_profile_xml, |
| 545 NULL, |
| 546 NULL); |
| 547 |
| 548 if (error == ERROR_SUCCESS && str_profile_xml != NULL) { |
| 549 *profile_xml = base::UTF16ToUTF8(str_profile_xml); |
| 550 } |
| 551 // clean up |
| 552 if (str_profile_xml != NULL) { |
| 553 WlanFreeMemory(str_profile_xml); |
| 554 } |
| 555 |
| 556 return error; |
| 557 } |
| 558 |
| 559 bool HaveProfile(const std::string& network_guid) { |
| 560 DWORD error = ERROR_SUCCESS; |
| 561 std::string profile_xml; |
| 562 return GetProfile(network_guid, &profile_xml) == ERROR_SUCCESS; |
| 563 } |
| 564 |
| 565 void NotifyNetworkListChanged(const NetworkList& networks) { |
| 566 if (network_list_changed_observer_.is_null()) |
| 567 return; |
| 568 |
| 569 WiFiService::NetworkGuidList current_networks; |
| 570 for (WiFiService::NetworkList::const_iterator it = networks.begin(); |
| 571 it != networks.end(); |
| 572 ++it) { |
| 573 current_networks.push_back(it->guid); |
| 574 } |
| 575 network_list_changed_observer_.Run(current_networks); |
| 576 } |
| 577 |
| 578 void NotifyNetworkChanged(const std::string& network_guid) { |
| 579 WiFiService::NetworkGuidList changed_networks(1, network_guid); |
| 580 if (!networks_changed_observer_.is_null()) |
| 581 networks_changed_observer_.Run(changed_networks); |
| 582 } |
| 583 |
| 584 // Wlan Service Handle. |
| 585 HANDLE client_; |
| 586 // Wlan Interface Guid. |
| 587 GUID interface_guid_; |
| 588 // Preserved Wlan Profile Xml. |
| 589 std::map<std::string, std::string> saved_profiles_xml_; |
| 590 |
| 591 NetworkGuidListCallback networks_changed_observer_; |
| 592 NetworkGuidListCallback network_list_changed_observer_; |
| 593 |
| 594 static const int kMaxAttempts = 100; |
| 595 static const int kAttemptDelayMs = 100; |
| 596 }; |
| 597 |
| 598 WiFiService* WiFiService::CreateService() { return new WiFiServiceImpl(); } |
OLD | NEW |