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 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
157 const base::DictionaryValue& properties, | 157 const base::DictionaryValue& properties, |
158 const StringResultCallback& callback, | 158 const StringResultCallback& callback, |
159 const ErrorCallback& error_callback) OVERRIDE; | 159 const ErrorCallback& error_callback) OVERRIDE; |
160 | 160 |
161 virtual void GetVisibleNetworks(const NetworkListCallback& callback, | 161 virtual void GetVisibleNetworks(const NetworkListCallback& callback, |
162 const ErrorCallback& error_callback) OVERRIDE; | 162 const ErrorCallback& error_callback) OVERRIDE; |
163 | 163 |
164 virtual void RequestNetworkScan() OVERRIDE; | 164 virtual void RequestNetworkScan() OVERRIDE; |
165 | 165 |
166 virtual void StartConnect(const std::string& network_guid, | 166 virtual void StartConnect(const std::string& network_guid, |
| 167 Frequency frequency, |
167 const StringResultCallback& callback, | 168 const StringResultCallback& callback, |
168 const ErrorCallback& error_callback) OVERRIDE; | 169 const ErrorCallback& error_callback) OVERRIDE; |
169 | 170 |
170 virtual void StartDisconnect(const std::string& network_guid, | 171 virtual void StartDisconnect(const std::string& network_guid, |
171 const StringResultCallback& callback, | 172 const StringResultCallback& callback, |
172 const ErrorCallback& error_callback) OVERRIDE; | 173 const ErrorCallback& error_callback) OVERRIDE; |
173 | 174 |
174 virtual void SetNetworksChangedObserver( | 175 virtual void SetNetworksChangedObserver( |
175 const NetworkGuidListCallback& observer) OVERRIDE; | 176 const NetworkGuidListCallback& observer) OVERRIDE; |
176 | 177 |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
276 NetworkProperties* properties); | 277 NetworkProperties* properties); |
277 | 278 |
278 // Get the list of visible wireless networks. | 279 // Get the list of visible wireless networks. |
279 DWORD GetVisibleNetworkList(NetworkList* network_list); | 280 DWORD GetVisibleNetworkList(NetworkList* network_list); |
280 | 281 |
281 // Find currently connected network if any. Populate |connected_network_guid| | 282 // Find currently connected network if any. Populate |connected_network_guid| |
282 // on success. | 283 // on success. |
283 DWORD FindConnectedNetwork(std::string* connected_network_guid); | 284 DWORD FindConnectedNetwork(std::string* connected_network_guid); |
284 | 285 |
285 // Connect to network |network_guid| using previosly stored profile if exists, | 286 // Connect to network |network_guid| using previosly stored profile if exists, |
286 // or just network sid. | 287 // or just network sid. If |frequency| is not |kFrequencyUnknown| then |
287 DWORD Connect(const std::string& network_guid); | 288 // connects only to BSS which uses that frequency and returns |
| 289 // |ERROR_NOT_FOUND| if such BSS cannot be found. |
| 290 DWORD Connect(const std::string& network_guid, Frequency frequency); |
288 | 291 |
289 // Disconnect from currently connected network if any. | 292 // Disconnect from currently connected network if any. |
290 DWORD Disconnect(); | 293 DWORD Disconnect(); |
291 | 294 |
| 295 // Get DOT11_BSSID_LIST of desired BSSIDs to connect to |ssid| network on |
| 296 // given |frequency|. |
| 297 DWORD GetDesiredBssList(DOT11_SSID& ssid, |
| 298 Frequency frequency, |
| 299 scoped_ptr<DOT11_BSSID_LIST>* desired_list); |
| 300 |
292 // Save temporary wireless profile for |network_guid|. | 301 // Save temporary wireless profile for |network_guid|. |
293 DWORD SaveTempProfile(const std::string& network_guid); | 302 DWORD SaveTempProfile(const std::string& network_guid); |
294 | 303 |
295 // Get previously stored |profile_xml| for |network_guid|. | 304 // Get previously stored |profile_xml| for |network_guid|. |
296 DWORD GetProfile(const std::string& network_guid, std::string* profile_xml); | 305 DWORD GetProfile(const std::string& network_guid, std::string* profile_xml); |
297 | 306 |
298 // Return true if there is previously stored profile xml for |network_guid|. | 307 // Return true if there is previously stored profile xml for |network_guid|. |
299 bool HaveProfile(const std::string& network_guid); | 308 bool HaveProfile(const std::string& network_guid); |
300 | 309 |
301 // Notify |network_list_changed_observer_| that list of visible networks has | 310 // Notify |network_list_changed_observer_| that list of visible networks has |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
449 } | 458 } |
450 | 459 |
451 void WiFiServiceImpl::RequestNetworkScan() { | 460 void WiFiServiceImpl::RequestNetworkScan() { |
452 DWORD error = EnsureInitialized(); | 461 DWORD error = EnsureInitialized(); |
453 if (error == ERROR_SUCCESS) { | 462 if (error == ERROR_SUCCESS) { |
454 WlanScan_function_(client_, &interface_guid_, NULL, NULL, NULL); | 463 WlanScan_function_(client_, &interface_guid_, NULL, NULL, NULL); |
455 } | 464 } |
456 } | 465 } |
457 | 466 |
458 void WiFiServiceImpl::StartConnect(const std::string& network_guid, | 467 void WiFiServiceImpl::StartConnect(const std::string& network_guid, |
| 468 Frequency frequency, |
459 const StringResultCallback& callback, | 469 const StringResultCallback& callback, |
460 const ErrorCallback& error_callback) { | 470 const ErrorCallback& error_callback) { |
461 DLOG(INFO) << "Start Connect: " << network_guid; | 471 DLOG(INFO) << "Start Connect: " << network_guid << " " << frequency << " MHz"; |
462 DWORD error = EnsureInitialized(); | 472 DWORD error = EnsureInitialized(); |
463 if (error == ERROR_SUCCESS) { | 473 if (error == ERROR_SUCCESS) { |
464 std::string connected_network_guid; | 474 std::string connected_network_guid; |
465 error = SaveCurrentConnectedNetwork(&connected_network_guid); | 475 error = SaveCurrentConnectedNetwork(&connected_network_guid); |
466 if (error == ERROR_SUCCESS) { | 476 if (error == ERROR_SUCCESS) { |
467 // Connect only if network |network_guid| is not connected already. | 477 // Connect only if network |network_guid| is not connected already. |
468 if (network_guid != connected_network_guid) | 478 if (network_guid != connected_network_guid) |
469 error = Connect(network_guid); | 479 error = Connect(network_guid, frequency); |
470 if (error == ERROR_SUCCESS) { | 480 if (error == ERROR_SUCCESS) { |
471 DisableNwCategoryWizard(); | |
472 callback.Run(network_guid); | 481 callback.Run(network_guid); |
473 // Notify that previously connected network has changed. | 482 // Notify that previously connected network has changed. |
474 NotifyNetworkChanged(connected_network_guid); | 483 NotifyNetworkChanged(connected_network_guid); |
475 // Start waiting for network connection state change. | 484 // Start waiting for network connection state change. |
476 if (!networks_changed_observer_.is_null()) { | 485 if (!networks_changed_observer_.is_null()) { |
| 486 DisableNwCategoryWizard(); |
477 // Disable automatic network change notifications as they get fired | 487 // Disable automatic network change notifications as they get fired |
478 // when network is just connected, but not yet accessible (doesn't | 488 // when network is just connected, but not yet accessible (doesn't |
479 // have valid IP address). | 489 // have valid IP address). |
480 enable_notify_network_changed_ = false; | 490 enable_notify_network_changed_ = false; |
481 WaitForNetworkConnect(network_guid, 0); | 491 WaitForNetworkConnect(network_guid, 0); |
482 return; | 492 return; |
483 } | 493 } |
484 } | 494 } |
485 } | 495 } |
486 } | 496 } |
(...skipping 568 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1055 } | 1065 } |
1056 | 1066 |
1057 // clean up | 1067 // clean up |
1058 if (available_network_list != NULL) { | 1068 if (available_network_list != NULL) { |
1059 WlanFreeMemory_function_(available_network_list); | 1069 WlanFreeMemory_function_(available_network_list); |
1060 } | 1070 } |
1061 | 1071 |
1062 return error; | 1072 return error; |
1063 } | 1073 } |
1064 | 1074 |
1065 DWORD WiFiServiceImpl::Connect(const std::string& network_guid) { | 1075 DWORD WiFiServiceImpl::GetDesiredBssList( |
| 1076 DOT11_SSID& ssid, |
| 1077 Frequency frequency, |
| 1078 scoped_ptr<DOT11_BSSID_LIST>* desired_list) { |
| 1079 if (client_ == NULL) { |
| 1080 NOTREACHED(); |
| 1081 return ERROR_NOINTERFACE; |
| 1082 } |
| 1083 |
| 1084 desired_list->reset(); |
| 1085 |
| 1086 if (frequency == kFrequencyAny) |
| 1087 return ERROR_SUCCESS; |
| 1088 |
| 1089 // TODO(mef): WlanGetNetworkBssList is not available on XP. If XP support is |
| 1090 // needed, then different method of getting BSS (e.g. OID query) will have |
| 1091 // to be used. |
| 1092 if (!WlanGetNetworkBssList_function_) |
| 1093 return ERROR_NOT_SUPPORTED; |
| 1094 |
| 1095 DWORD error = ERROR_SUCCESS; |
| 1096 PWLAN_BSS_LIST bss_list = NULL; |
| 1097 |
| 1098 error = WlanGetNetworkBssList_function_(client_, |
| 1099 &interface_guid_, |
| 1100 NULL, |
| 1101 dot11_BSS_type_any, |
| 1102 FALSE, |
| 1103 NULL, |
| 1104 &bss_list); |
| 1105 if (error == ERROR_SUCCESS && NULL != bss_list) { |
| 1106 unsigned int best_quality = 0u; |
| 1107 size_t best_index = 0; |
| 1108 Frequency bss_frequency; |
| 1109 |
| 1110 // Go through bss_list and find best quality BSSID with matching frequency. |
| 1111 for (size_t bss = 0; bss < bss_list->dwNumberOfItems; ++bss) { |
| 1112 const WLAN_BSS_ENTRY& bss_entry(bss_list->wlanBssEntries[bss]); |
| 1113 if (bss_entry.dot11Ssid.uSSIDLength != ssid.uSSIDLength || |
| 1114 0 != memcmp(bss_entry.dot11Ssid.ucSSID, |
| 1115 ssid.ucSSID, |
| 1116 bss_entry.dot11Ssid.uSSIDLength)) |
| 1117 continue; |
| 1118 |
| 1119 if (bss_entry.ulChCenterFrequency < 3000000) |
| 1120 bss_frequency = kFrequency2400; |
| 1121 else |
| 1122 bss_frequency = kFrequency5000; |
| 1123 |
| 1124 if (bss_frequency == frequency && |
| 1125 bss_entry.uLinkQuality > best_quality) { |
| 1126 best_quality = bss_entry.uLinkQuality; |
| 1127 best_index = bss; |
| 1128 } |
| 1129 } |
| 1130 |
| 1131 // If any matching BSS were found, prepare the header. |
| 1132 if (best_quality > 0) { |
| 1133 const WLAN_BSS_ENTRY& bss_entry(bss_list->wlanBssEntries[best_index]); |
| 1134 scoped_ptr<DOT11_BSSID_LIST> selected_list(new DOT11_BSSID_LIST); |
| 1135 |
| 1136 selected_list->Header.Revision = DOT11_BSSID_LIST_REVISION_1; |
| 1137 selected_list->Header.Size = sizeof(DOT11_BSSID_LIST); |
| 1138 selected_list->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; |
| 1139 selected_list->uNumOfEntries = 1; |
| 1140 selected_list->uTotalNumOfEntries = 1; |
| 1141 std::copy(bss_entry.dot11Bssid, |
| 1142 bss_entry.dot11Bssid+sizeof(bss_entry.dot11Bssid), |
| 1143 selected_list->BSSIDs[0]); |
| 1144 desired_list->swap(selected_list); |
| 1145 DLOG(INFO) << "Quality: " << best_quality << " BSS: " |
| 1146 << NetworkProperties::MacAddressAsString(bss_entry.dot11Bssid); |
| 1147 } else { |
| 1148 error = ERROR_NOT_FOUND; |
| 1149 } |
| 1150 } |
| 1151 |
| 1152 // clean up |
| 1153 if (bss_list != NULL) { |
| 1154 WlanFreeMemory_function_(bss_list); |
| 1155 } |
| 1156 return error; |
| 1157 } |
| 1158 |
| 1159 |
| 1160 DWORD WiFiServiceImpl::Connect(const std::string& network_guid, |
| 1161 Frequency frequency) { |
1066 if (client_ == NULL) { | 1162 if (client_ == NULL) { |
1067 NOTREACHED(); | 1163 NOTREACHED(); |
1068 return ERROR_NOINTERFACE; | 1164 return ERROR_NOINTERFACE; |
1069 } | 1165 } |
1070 | 1166 |
1071 DWORD error = ERROR_SUCCESS; | 1167 DWORD error = ERROR_SUCCESS; |
1072 base::string16 profile_name = ProfileNameFromGUID(network_guid); | 1168 DOT11_SSID ssid = SSIDFromGUID(network_guid); |
1073 | 1169 scoped_ptr<DOT11_BSSID_LIST> desired_bss_list; |
1074 if (HaveProfile(network_guid)) { | 1170 error = GetDesiredBssList(ssid, frequency, &desired_bss_list); |
1075 WLAN_CONNECTION_PARAMETERS wlan_params = { | 1171 if (error == ERROR_SUCCESS) { |
1076 wlan_connection_mode_profile, | 1172 if (HaveProfile(network_guid)) { |
1077 profile_name.c_str(), | 1173 base::string16 profile_name = ProfileNameFromGUID(network_guid); |
1078 NULL, | 1174 WLAN_CONNECTION_PARAMETERS wlan_params = { |
1079 NULL, | 1175 wlan_connection_mode_profile, |
1080 dot11_BSS_type_any, | 1176 profile_name.c_str(), |
1081 0}; | 1177 NULL, |
1082 error = WlanConnect_function_( | 1178 desired_bss_list.get(), |
1083 client_, &interface_guid_, &wlan_params, NULL); | 1179 dot11_BSS_type_any, |
1084 } else { | 1180 0}; |
1085 // TODO(mef): wlan_connection_mode_discovery_unsecure is not available on | 1181 error = WlanConnect_function_( |
1086 // XP. If XP support is needed, then temporary profile will have to be | 1182 client_, &interface_guid_, &wlan_params, NULL); |
1087 // created. | 1183 } else { |
1088 DOT11_SSID ssid = SSIDFromGUID(network_guid); | 1184 // TODO(mef): wlan_connection_mode_discovery_unsecure is not available on |
1089 WLAN_CONNECTION_PARAMETERS wlan_params = { | 1185 // XP. If XP support is needed, then temporary profile will have to be |
1090 wlan_connection_mode_discovery_unsecure, | 1186 // created. |
1091 NULL, | 1187 WLAN_CONNECTION_PARAMETERS wlan_params = { |
1092 &ssid, | 1188 wlan_connection_mode_discovery_unsecure, |
1093 NULL, | 1189 NULL, |
1094 dot11_BSS_type_infrastructure, | 1190 &ssid, |
1095 0}; | 1191 desired_bss_list.get(), |
1096 error = WlanConnect_function_( | 1192 dot11_BSS_type_infrastructure, |
1097 client_, &interface_guid_, &wlan_params, NULL); | 1193 0}; |
| 1194 error = WlanConnect_function_( |
| 1195 client_, &interface_guid_, &wlan_params, NULL); |
| 1196 } |
1098 } | 1197 } |
1099 | 1198 |
1100 return error; | 1199 return error; |
1101 } | 1200 } |
1102 | 1201 |
1103 DWORD WiFiServiceImpl::Disconnect() { | 1202 DWORD WiFiServiceImpl::Disconnect() { |
1104 if (client_ == NULL) { | 1203 if (client_ == NULL) { |
1105 NOTREACHED(); | 1204 NOTREACHED(); |
1106 return ERROR_NOINTERFACE; | 1205 return ERROR_NOINTERFACE; |
1107 } | 1206 } |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1188 if (enable_notify_network_changed_ && !networks_changed_observer_.is_null()) { | 1287 if (enable_notify_network_changed_ && !networks_changed_observer_.is_null()) { |
1189 DLOG(INFO) << "NotifyNetworkChanged: " << network_guid; | 1288 DLOG(INFO) << "NotifyNetworkChanged: " << network_guid; |
1190 NetworkGuidList changed_networks(1, network_guid); | 1289 NetworkGuidList changed_networks(1, network_guid); |
1191 networks_changed_observer_.Run(changed_networks); | 1290 networks_changed_observer_.Run(changed_networks); |
1192 } | 1291 } |
1193 } | 1292 } |
1194 | 1293 |
1195 WiFiService* WiFiService::CreateService() { return new WiFiServiceImpl(); } | 1294 WiFiService* WiFiService::CreateService() { return new WiFiServiceImpl(); } |
1196 | 1295 |
1197 } // namespace wifi | 1296 } // namespace wifi |
OLD | NEW |