OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "chromeos/network/network_state.h" | 5 #include "chromeos/network/network_state.h" |
6 | 6 |
7 #include "base/i18n/icu_encoding_detection.h" | |
8 #include "base/i18n/icu_string_conversions.h" | |
9 #include "base/json/json_writer.h" | |
10 #include "base/strings/string_number_conversions.h" | |
11 #include "base/strings/string_util.h" | |
12 #include "base/strings/stringprintf.h" | 7 #include "base/strings/stringprintf.h" |
13 #include "base/strings/utf_string_conversion_utils.h" | |
14 #include "chromeos/network/network_event_log.h" | 8 #include "chromeos/network/network_event_log.h" |
15 #include "chromeos/network/network_profile_handler.h" | 9 #include "chromeos/network/network_profile_handler.h" |
16 #include "chromeos/network/network_util.h" | 10 #include "chromeos/network/network_util.h" |
17 #include "chromeos/network/onc/onc_utils.h" | 11 #include "chromeos/network/onc/onc_utils.h" |
| 12 #include "chromeos/network/shill_property_util.h" |
18 #include "third_party/cros_system_api/dbus/service_constants.h" | 13 #include "third_party/cros_system_api/dbus/service_constants.h" |
19 | 14 |
20 namespace { | 15 namespace { |
21 | 16 |
22 const char kErrorUnknown[] = "Unknown"; | 17 const char kErrorUnknown[] = "Unknown"; |
23 | 18 |
24 bool ConvertListValueToStringVector(const base::ListValue& string_list, | 19 bool ConvertListValueToStringVector(const base::ListValue& string_list, |
25 std::vector<std::string>* result) { | 20 std::vector<std::string>* result) { |
26 for (size_t i = 0; i < string_list.GetSize(); ++i) { | 21 for (size_t i = 0; i < string_list.GetSize(); ++i) { |
27 std::string str; | 22 std::string str; |
28 if (!string_list.GetString(i, &str)) | 23 if (!string_list.GetString(i, &str)) |
29 return false; | 24 return false; |
30 result->push_back(str); | 25 result->push_back(str); |
31 } | 26 } |
32 return true; | 27 return true; |
33 } | 28 } |
34 | 29 |
35 // Replace non UTF8 characters in |str| with a replacement character. | |
36 std::string ValidateUTF8(const std::string& str) { | |
37 std::string result; | |
38 for (int32 index = 0; index < static_cast<int32>(str.size()); ++index) { | |
39 uint32 code_point_out; | |
40 bool is_unicode_char = base::ReadUnicodeCharacter(str.c_str(), str.size(), | |
41 &index, &code_point_out); | |
42 const uint32 kFirstNonControlChar = 0x20; | |
43 if (is_unicode_char && (code_point_out >= kFirstNonControlChar)) { | |
44 base::WriteUnicodeCharacter(code_point_out, &result); | |
45 } else { | |
46 const uint32 kReplacementChar = 0xFFFD; | |
47 // Puts kReplacementChar if character is a control character [0,0x20) | |
48 // or is not readable UTF8. | |
49 base::WriteUnicodeCharacter(kReplacementChar, &result); | |
50 } | |
51 } | |
52 return result; | |
53 } | |
54 | |
55 bool IsCaCertNssSet(const base::DictionaryValue& properties) { | 30 bool IsCaCertNssSet(const base::DictionaryValue& properties) { |
56 std::string ca_cert_nss; | 31 std::string ca_cert_nss; |
57 if (properties.GetStringWithoutPathExpansion(flimflam::kEapCaCertNssProperty, | 32 if (properties.GetStringWithoutPathExpansion(flimflam::kEapCaCertNssProperty, |
58 &ca_cert_nss) && | 33 &ca_cert_nss) && |
59 !ca_cert_nss.empty()) { | 34 !ca_cert_nss.empty()) { |
60 return true; | 35 return true; |
61 } | 36 } |
62 | 37 |
63 const base::DictionaryValue* provider = NULL; | 38 const base::DictionaryValue* provider = NULL; |
64 properties.GetDictionaryWithoutPathExpansion(flimflam::kProviderProperty, | 39 properties.GetDictionaryWithoutPathExpansion(flimflam::kProviderProperty, |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 // Warning: The DictionaryValue returned from | 152 // Warning: The DictionaryValue returned from |
178 // ReadDictionaryFromJson/JSONParser is an optimized derived class that | 153 // ReadDictionaryFromJson/JSONParser is an optimized derived class that |
179 // doesn't allow releasing ownership of nested values. A Swap in the wrong | 154 // doesn't allow releasing ownership of nested values. A Swap in the wrong |
180 // order leads to memory access errors. | 155 // order leads to memory access errors. |
181 proxy_config_.MergeDictionary(proxy_config_dict.get()); | 156 proxy_config_.MergeDictionary(proxy_config_dict.get()); |
182 } else { | 157 } else { |
183 NET_LOG_ERROR("Failed to parse " + key, path()); | 158 NET_LOG_ERROR("Failed to parse " + key, path()); |
184 } | 159 } |
185 return true; | 160 return true; |
186 } else if (key == flimflam::kUIDataProperty) { | 161 } else if (key == flimflam::kUIDataProperty) { |
187 if (!GetUIDataFromValue(value, &ui_data_)) { | 162 scoped_ptr<NetworkUIData> new_ui_data = |
| 163 shill_property_util::GetUIDataFromValue(value); |
| 164 if (!new_ui_data) { |
188 NET_LOG_ERROR("Failed to parse " + key, path()); | 165 NET_LOG_ERROR("Failed to parse " + key, path()); |
189 return false; | 166 return false; |
190 } | 167 } |
| 168 ui_data_ = *new_ui_data; |
191 return true; | 169 return true; |
192 } else if (key == flimflam::kNetworkTechnologyProperty) { | 170 } else if (key == flimflam::kNetworkTechnologyProperty) { |
193 return GetStringValue(key, value, &network_technology_); | 171 return GetStringValue(key, value, &network_technology_); |
194 } else if (key == flimflam::kDeviceProperty) { | 172 } else if (key == flimflam::kDeviceProperty) { |
195 return GetStringValue(key, value, &device_path_); | 173 return GetStringValue(key, value, &device_path_); |
196 } else if (key == flimflam::kGuidProperty) { | 174 } else if (key == flimflam::kGuidProperty) { |
197 return GetStringValue(key, value, &guid_); | 175 return GetStringValue(key, value, &guid_); |
198 } else if (key == flimflam::kProfileProperty) { | 176 } else if (key == flimflam::kProfileProperty) { |
199 return GetStringValue(key, value, &profile_path_); | 177 return GetStringValue(key, value, &profile_path_); |
200 } else if (key == shill::kActivateOverNonCellularNetworkProperty) { | 178 } else if (key == shill::kActivateOverNonCellularNetworkProperty) { |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
332 result += dns_servers_[i]; | 310 result += dns_servers_[i]; |
333 } | 311 } |
334 return result; | 312 return result; |
335 } | 313 } |
336 | 314 |
337 std::string NetworkState::GetNetmask() const { | 315 std::string NetworkState::GetNetmask() const { |
338 return network_util::PrefixLengthToNetmask(prefix_length_); | 316 return network_util::PrefixLengthToNetmask(prefix_length_); |
339 } | 317 } |
340 | 318 |
341 bool NetworkState::UpdateName(const base::DictionaryValue& properties) { | 319 bool NetworkState::UpdateName(const base::DictionaryValue& properties) { |
342 std::string updated_name = GetNameFromProperties(path(), properties); | 320 std::string updated_name = |
| 321 shill_property_util::GetNameFromProperties(path(), properties); |
343 if (updated_name != name()) { | 322 if (updated_name != name()) { |
344 set_name(updated_name); | 323 set_name(updated_name); |
345 return true; | 324 return true; |
346 } | 325 } |
347 return false; | 326 return false; |
348 } | 327 } |
349 | 328 |
350 // static | 329 // static |
351 std::string NetworkState::GetNameFromProperties( | |
352 const std::string& service_path, | |
353 const base::DictionaryValue& properties) { | |
354 std::string name, hex_ssid; | |
355 properties.GetStringWithoutPathExpansion(flimflam::kNameProperty, &name); | |
356 properties.GetStringWithoutPathExpansion(flimflam::kWifiHexSsid, &hex_ssid); | |
357 | |
358 if (hex_ssid.empty()) { | |
359 if (name.empty()) | |
360 return name; | |
361 // Validate name for UTF8. | |
362 std::string valid_ssid = ValidateUTF8(name); | |
363 if (valid_ssid != name) { | |
364 NET_LOG_DEBUG("GetNameFromProperties", base::StringPrintf( | |
365 "%s: UTF8: %s", service_path.c_str(), valid_ssid.c_str())); | |
366 } | |
367 return valid_ssid; | |
368 } | |
369 | |
370 std::string ssid; | |
371 std::vector<uint8> raw_ssid_bytes; | |
372 if (base::HexStringToBytes(hex_ssid, &raw_ssid_bytes)) { | |
373 ssid = std::string(raw_ssid_bytes.begin(), raw_ssid_bytes.end()); | |
374 NET_LOG_DEBUG("GetNameFromProperties", base::StringPrintf( | |
375 "%s: %s, SSID: %s", service_path.c_str(), | |
376 hex_ssid.c_str(), ssid.c_str())); | |
377 } else { | |
378 NET_LOG_ERROR("GetNameFromProperties", | |
379 base::StringPrintf("%s: Error processing: %s", | |
380 service_path.c_str(), hex_ssid.c_str())); | |
381 return name; | |
382 } | |
383 | |
384 if (IsStringUTF8(ssid)) { | |
385 if (ssid != name) { | |
386 NET_LOG_DEBUG("GetNameFromProperties", base::StringPrintf( | |
387 "%s: UTF8: %s", service_path.c_str(), ssid.c_str())); | |
388 } | |
389 return ssid; | |
390 } | |
391 | |
392 // Detect encoding and convert to UTF-8. | |
393 std::string country_code; | |
394 properties.GetStringWithoutPathExpansion( | |
395 flimflam::kCountryProperty, &country_code); | |
396 std::string encoding; | |
397 if (!base::DetectEncoding(ssid, &encoding)) { | |
398 // TODO(stevenjb): This is currently experimental. If we find a case where | |
399 // base::DetectEncoding() fails, we need to figure out whether we can use | |
400 // country_code with ConvertToUtf8(). crbug.com/233267. | |
401 encoding = country_code; | |
402 } | |
403 if (!encoding.empty()) { | |
404 std::string utf8_ssid; | |
405 if (base::ConvertToUtf8AndNormalize(ssid, encoding, &utf8_ssid)) { | |
406 if (utf8_ssid != name) { | |
407 NET_LOG_DEBUG("GetNameFromProperties", base::StringPrintf( | |
408 "%s: Encoding=%s: %s", service_path.c_str(), | |
409 encoding.c_str(), utf8_ssid.c_str())); | |
410 } | |
411 return utf8_ssid; | |
412 } | |
413 } | |
414 | |
415 // Unrecognized encoding. Only use raw bytes if name_ is empty. | |
416 NET_LOG_DEBUG("GetNameFromProperties", base::StringPrintf( | |
417 "%s: Unrecognized Encoding=%s: %s", service_path.c_str(), | |
418 encoding.c_str(), ssid.c_str())); | |
419 if (name.empty() && !ssid.empty()) | |
420 return ssid; | |
421 return name; | |
422 } | |
423 | |
424 // static | |
425 bool NetworkState::StateIsConnected(const std::string& connection_state) { | 330 bool NetworkState::StateIsConnected(const std::string& connection_state) { |
426 return (connection_state == flimflam::kStateReady || | 331 return (connection_state == flimflam::kStateReady || |
427 connection_state == flimflam::kStateOnline || | 332 connection_state == flimflam::kStateOnline || |
428 connection_state == flimflam::kStatePortal); | 333 connection_state == flimflam::kStatePortal); |
429 } | 334 } |
430 | 335 |
431 // static | 336 // static |
432 bool NetworkState::StateIsConnecting(const std::string& connection_state) { | 337 bool NetworkState::StateIsConnecting(const std::string& connection_state) { |
433 return (connection_state == flimflam::kStateAssociation || | 338 return (connection_state == flimflam::kStateAssociation || |
434 connection_state == flimflam::kStateConfiguration || | 339 connection_state == flimflam::kStateConfiguration || |
435 connection_state == flimflam::kStateCarrier); | 340 connection_state == flimflam::kStateCarrier); |
436 } | 341 } |
437 | 342 |
438 // static | 343 // static |
439 std::string NetworkState::IPConfigProperty(const char* key) { | 344 std::string NetworkState::IPConfigProperty(const char* key) { |
440 return base::StringPrintf("%s.%s", shill::kIPConfigProperty, key); | 345 return base::StringPrintf("%s.%s", shill::kIPConfigProperty, key); |
441 } | 346 } |
442 | 347 |
443 // static | |
444 bool NetworkState::GetUIDataFromValue(const base::Value& ui_data_value, | |
445 NetworkUIData* out) { | |
446 std::string ui_data_str; | |
447 if (!ui_data_value.GetAsString(&ui_data_str)) | |
448 return false; | |
449 if (ui_data_str.empty()) { | |
450 *out = NetworkUIData(); | |
451 return true; | |
452 } | |
453 scoped_ptr<base::DictionaryValue> ui_data_dict( | |
454 chromeos::onc::ReadDictionaryFromJson(ui_data_str)); | |
455 if (!ui_data_dict) | |
456 return false; | |
457 *out = NetworkUIData(*ui_data_dict); | |
458 return true; | |
459 } | |
460 | |
461 } // namespace chromeos | 348 } // namespace chromeos |
OLD | NEW |