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