network_state.cc revision effb81e5f8246d0db0270817048dc992db66e9fb
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 3// found in the LICENSE file. 4 5#include "chromeos/network/network_state.h" 6 7#include "base/strings/stringprintf.h" 8#include "base/values.h" 9#include "chromeos/network/network_event_log.h" 10#include "chromeos/network/network_profile_handler.h" 11#include "chromeos/network/network_util.h" 12#include "chromeos/network/shill_property_util.h" 13#include "third_party/cros_system_api/dbus/service_constants.h" 14 15namespace { 16 17const char kErrorUnknown[] = "Unknown"; 18 19bool ConvertListValueToStringVector(const base::ListValue& string_list, 20 std::vector<std::string>* result) { 21 for (size_t i = 0; i < string_list.GetSize(); ++i) { 22 std::string str; 23 if (!string_list.GetString(i, &str)) 24 return false; 25 result->push_back(str); 26 } 27 return true; 28} 29 30bool IsCaCertNssSet(const base::DictionaryValue& properties) { 31 std::string ca_cert_nss; 32 if (properties.GetStringWithoutPathExpansion(shill::kEapCaCertNssProperty, 33 &ca_cert_nss) && 34 !ca_cert_nss.empty()) { 35 return true; 36 } 37 38 const base::DictionaryValue* provider = NULL; 39 properties.GetDictionaryWithoutPathExpansion(shill::kProviderProperty, 40 &provider); 41 if (!provider) 42 return false; 43 if (provider->GetStringWithoutPathExpansion( 44 shill::kL2tpIpsecCaCertNssProperty, &ca_cert_nss) && 45 !ca_cert_nss.empty()) { 46 return true; 47 } 48 if (provider->GetStringWithoutPathExpansion( 49 shill::kOpenVPNCaCertNSSProperty, &ca_cert_nss) && 50 !ca_cert_nss.empty()) { 51 return true; 52 } 53 54 return false; 55} 56 57} // namespace 58 59namespace chromeos { 60 61NetworkState::NetworkState(const std::string& path) 62 : ManagedState(MANAGED_TYPE_NETWORK, path), 63 connectable_(false), 64 prefix_length_(0), 65 signal_strength_(0), 66 activate_over_non_cellular_networks_(false), 67 cellular_out_of_credits_(false), 68 has_ca_cert_nss_(false) { 69} 70 71NetworkState::~NetworkState() { 72} 73 74bool NetworkState::PropertyChanged(const std::string& key, 75 const base::Value& value) { 76 // Keep care that these properties are the same as in |GetProperties|. 77 if (ManagedStatePropertyChanged(key, value)) 78 return true; 79 if (key == shill::kSignalStrengthProperty) { 80 return GetIntegerValue(key, value, &signal_strength_); 81 } else if (key == shill::kStateProperty) { 82 return GetStringValue(key, value, &connection_state_); 83 } else if (key == shill::kConnectableProperty) { 84 return GetBooleanValue(key, value, &connectable_); 85 } else if (key == shill::kErrorProperty) { 86 if (!GetStringValue(key, value, &error_)) 87 return false; 88 if (ErrorIsValid(error_)) 89 last_error_ = error_; 90 else 91 error_.clear(); 92 return true; 93 } else if (key == IPConfigProperty(shill::kAddressProperty)) { 94 return GetStringValue(key, value, &ip_address_); 95 } else if (key == IPConfigProperty(shill::kGatewayProperty)) { 96 return GetStringValue(key, value, &gateway_); 97 } else if (key == IPConfigProperty(shill::kNameServersProperty)) { 98 const base::ListValue* dns_servers; 99 if (!value.GetAsList(&dns_servers)) 100 return false; 101 dns_servers_.clear(); 102 ConvertListValueToStringVector(*dns_servers, &dns_servers_); 103 return true; 104 } else if (key == IPConfigProperty(shill::kPrefixlenProperty)) { 105 return GetIntegerValue(key, value, &prefix_length_); 106 } else if (key == IPConfigProperty( 107 shill::kWebProxyAutoDiscoveryUrlProperty)) { 108 std::string url_string; 109 if (!GetStringValue(key, value, &url_string)) 110 return false; 111 if (url_string.empty()) { 112 web_proxy_auto_discovery_url_ = GURL(); 113 } else { 114 GURL gurl(url_string); 115 if (!gurl.is_valid()) { 116 web_proxy_auto_discovery_url_ = gurl; 117 } else { 118 NET_LOG_ERROR("Invalid WebProxyAutoDiscoveryUrl: " + url_string, 119 path()); 120 web_proxy_auto_discovery_url_ = GURL(); 121 } 122 } 123 return true; 124 } else if (key == shill::kActivationStateProperty) { 125 return GetStringValue(key, value, &activation_state_); 126 } else if (key == shill::kRoamingStateProperty) { 127 return GetStringValue(key, value, &roaming_); 128 } else if (key == shill::kSecurityProperty) { 129 return GetStringValue(key, value, &security_); 130 } else if (key == shill::kEapMethodProperty) { 131 return GetStringValue(key, value, &eap_method_); 132 } else if (key == shill::kUIDataProperty) { 133 scoped_ptr<NetworkUIData> new_ui_data = 134 shill_property_util::GetUIDataFromValue(value); 135 if (!new_ui_data) { 136 NET_LOG_ERROR("Failed to parse " + key, path()); 137 return false; 138 } 139 ui_data_ = *new_ui_data; 140 return true; 141 } else if (key == shill::kNetworkTechnologyProperty) { 142 return GetStringValue(key, value, &network_technology_); 143 } else if (key == shill::kDeviceProperty) { 144 return GetStringValue(key, value, &device_path_); 145 } else if (key == shill::kGuidProperty) { 146 return GetStringValue(key, value, &guid_); 147 } else if (key == shill::kProfileProperty) { 148 return GetStringValue(key, value, &profile_path_); 149 } else if (key == shill::kActivateOverNonCellularNetworkProperty) { 150 return GetBooleanValue(key, value, &activate_over_non_cellular_networks_); 151 } else if (key == shill::kOutOfCreditsProperty) { 152 return GetBooleanValue(key, value, &cellular_out_of_credits_); 153 } 154 return false; 155} 156 157bool NetworkState::InitialPropertiesReceived( 158 const base::DictionaryValue& properties) { 159 NET_LOG_DEBUG("InitialPropertiesReceived", path()); 160 bool changed = false; 161 if (!properties.HasKey(shill::kTypeProperty)) { 162 NET_LOG_ERROR("NetworkState has no type", 163 shill_property_util::GetNetworkIdFromProperties(properties)); 164 } else { 165 changed |= UpdateName(properties); 166 } 167 bool had_ca_cert_nss = has_ca_cert_nss_; 168 has_ca_cert_nss_ = IsCaCertNssSet(properties); 169 changed |= had_ca_cert_nss != has_ca_cert_nss_; 170 return changed; 171} 172 173void NetworkState::GetProperties(base::DictionaryValue* dictionary) const { 174 // Keep care that these properties are the same as in |PropertyChanged|. 175 dictionary->SetStringWithoutPathExpansion(shill::kNameProperty, name()); 176 dictionary->SetStringWithoutPathExpansion(shill::kTypeProperty, type()); 177 dictionary->SetIntegerWithoutPathExpansion(shill::kSignalStrengthProperty, 178 signal_strength_); 179 dictionary->SetStringWithoutPathExpansion(shill::kStateProperty, 180 connection_state_); 181 dictionary->SetBooleanWithoutPathExpansion(shill::kConnectableProperty, 182 connectable_); 183 184 dictionary->SetStringWithoutPathExpansion(shill::kErrorProperty, error_); 185 186 // IPConfig properties 187 base::DictionaryValue* ipconfig_properties = new base::DictionaryValue; 188 ipconfig_properties->SetStringWithoutPathExpansion(shill::kAddressProperty, 189 ip_address_); 190 ipconfig_properties->SetStringWithoutPathExpansion(shill::kGatewayProperty, 191 gateway_); 192 base::ListValue* name_servers = new base::ListValue; 193 name_servers->AppendStrings(dns_servers_); 194 ipconfig_properties->SetWithoutPathExpansion(shill::kNameServersProperty, 195 name_servers); 196 ipconfig_properties->SetStringWithoutPathExpansion( 197 shill::kWebProxyAutoDiscoveryUrlProperty, 198 web_proxy_auto_discovery_url_.spec()); 199 dictionary->SetWithoutPathExpansion(shill::kIPConfigProperty, 200 ipconfig_properties); 201 202 dictionary->SetStringWithoutPathExpansion(shill::kActivationStateProperty, 203 activation_state_); 204 dictionary->SetStringWithoutPathExpansion(shill::kRoamingStateProperty, 205 roaming_); 206 dictionary->SetStringWithoutPathExpansion(shill::kSecurityProperty, 207 security_); 208 dictionary->SetStringWithoutPathExpansion(shill::kEapMethodProperty, 209 eap_method_); 210 211 // ui_data_ (contains ONC source) is intentionally omitted. 212 213 dictionary->SetStringWithoutPathExpansion( 214 shill::kNetworkTechnologyProperty, 215 network_technology_); 216 dictionary->SetStringWithoutPathExpansion(shill::kDeviceProperty, 217 device_path_); 218 dictionary->SetStringWithoutPathExpansion(shill::kGuidProperty, guid_); 219 dictionary->SetStringWithoutPathExpansion(shill::kProfileProperty, 220 profile_path_); 221 dictionary->SetBooleanWithoutPathExpansion( 222 shill::kActivateOverNonCellularNetworkProperty, 223 activate_over_non_cellular_networks_); 224 dictionary->SetBooleanWithoutPathExpansion(shill::kOutOfCreditsProperty, 225 cellular_out_of_credits_); 226} 227 228bool NetworkState::RequiresActivation() const { 229 return (type() == shill::kTypeCellular && 230 activation_state() != shill::kActivationStateActivated && 231 activation_state() != shill::kActivationStateUnknown); 232} 233 234bool NetworkState::IsConnectedState() const { 235 return StateIsConnected(connection_state_); 236} 237 238bool NetworkState::IsConnectingState() const { 239 return StateIsConnecting(connection_state_); 240} 241 242bool NetworkState::IsPrivate() const { 243 return !profile_path_.empty() && 244 profile_path_ != NetworkProfileHandler::GetSharedProfilePath(); 245} 246 247std::string NetworkState::GetDnsServersAsString() const { 248 std::string result; 249 for (size_t i = 0; i < dns_servers_.size(); ++i) { 250 if (i != 0) 251 result += ","; 252 result += dns_servers_[i]; 253 } 254 return result; 255} 256 257std::string NetworkState::GetNetmask() const { 258 return network_util::PrefixLengthToNetmask(prefix_length_); 259} 260 261bool NetworkState::UpdateName(const base::DictionaryValue& properties) { 262 std::string updated_name = 263 shill_property_util::GetNameFromProperties(path(), properties); 264 if (updated_name != name()) { 265 set_name(updated_name); 266 return true; 267 } 268 return false; 269} 270 271// static 272bool NetworkState::StateIsConnected(const std::string& connection_state) { 273 return (connection_state == shill::kStateReady || 274 connection_state == shill::kStateOnline || 275 connection_state == shill::kStatePortal); 276} 277 278// static 279bool NetworkState::StateIsConnecting(const std::string& connection_state) { 280 return (connection_state == shill::kStateAssociation || 281 connection_state == shill::kStateConfiguration || 282 connection_state == shill::kStateCarrier); 283} 284 285// static 286bool NetworkState::ErrorIsValid(const std::string& error) { 287 // Shill uses "Unknown" to indicate an unset or cleared error state. 288 return !error.empty() && error != kErrorUnknown; 289} 290 291// static 292std::string NetworkState::IPConfigProperty(const char* key) { 293 return base::StringPrintf("%s.%s", shill::kIPConfigProperty, key); 294} 295 296} // namespace chromeos 297