network_state.cc revision 010d83a9304c5a91596085d917d248abff47903a
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 == shill::kActivationStateProperty) { 94 return GetStringValue(key, value, &activation_state_); 95 } else if (key == shill::kRoamingStateProperty) { 96 return GetStringValue(key, value, &roaming_); 97 } else if (key == shill::kSecurityProperty) { 98 return GetStringValue(key, value, &security_); 99 } else if (key == shill::kEapMethodProperty) { 100 return GetStringValue(key, value, &eap_method_); 101 } else if (key == shill::kUIDataProperty) { 102 scoped_ptr<NetworkUIData> new_ui_data = 103 shill_property_util::GetUIDataFromValue(value); 104 if (!new_ui_data) { 105 NET_LOG_ERROR("Failed to parse " + key, path()); 106 return false; 107 } 108 ui_data_ = *new_ui_data; 109 return true; 110 } else if (key == shill::kNetworkTechnologyProperty) { 111 return GetStringValue(key, value, &network_technology_); 112 } else if (key == shill::kDeviceProperty) { 113 return GetStringValue(key, value, &device_path_); 114 } else if (key == shill::kGuidProperty) { 115 return GetStringValue(key, value, &guid_); 116 } else if (key == shill::kProfileProperty) { 117 return GetStringValue(key, value, &profile_path_); 118 } else if (key == shill::kActivateOverNonCellularNetworkProperty) { 119 return GetBooleanValue(key, value, &activate_over_non_cellular_networks_); 120 } else if (key == shill::kOutOfCreditsProperty) { 121 return GetBooleanValue(key, value, &cellular_out_of_credits_); 122 } 123 return false; 124} 125 126bool NetworkState::InitialPropertiesReceived( 127 const base::DictionaryValue& properties) { 128 NET_LOG_DEBUG("InitialPropertiesReceived", path()); 129 bool changed = false; 130 if (!properties.HasKey(shill::kTypeProperty)) { 131 NET_LOG_ERROR("NetworkState has no type", 132 shill_property_util::GetNetworkIdFromProperties(properties)); 133 } else { 134 changed |= UpdateName(properties); 135 } 136 bool had_ca_cert_nss = has_ca_cert_nss_; 137 has_ca_cert_nss_ = IsCaCertNssSet(properties); 138 changed |= had_ca_cert_nss != has_ca_cert_nss_; 139 return changed; 140} 141 142void NetworkState::GetStateProperties(base::DictionaryValue* dictionary) const { 143 ManagedState::GetStateProperties(dictionary); 144 145 // Properties shared by all types. 146 dictionary->SetStringWithoutPathExpansion(shill::kGuidProperty, guid()); 147 dictionary->SetStringWithoutPathExpansion(shill::kStateProperty, 148 connection_state()); 149 dictionary->SetStringWithoutPathExpansion(shill::kSecurityProperty, 150 security()); 151 if (!error().empty()) 152 dictionary->SetStringWithoutPathExpansion(shill::kErrorProperty, error()); 153 154 if (!NetworkTypePattern::Wireless().MatchesType(type())) 155 return; 156 157 // Wireless properties 158 dictionary->SetBooleanWithoutPathExpansion(shill::kConnectableProperty, 159 connectable()); 160 dictionary->SetIntegerWithoutPathExpansion(shill::kSignalStrengthProperty, 161 signal_strength()); 162 163 // Wifi properties 164 if (NetworkTypePattern::WiFi().MatchesType(type())) { 165 dictionary->SetStringWithoutPathExpansion(shill::kEapMethodProperty, 166 eap_method()); 167 } 168 169 // Mobile properties 170 if (NetworkTypePattern::Mobile().MatchesType(type())) { 171 dictionary->SetStringWithoutPathExpansion( 172 shill::kNetworkTechnologyProperty, 173 network_technology()); 174 dictionary->SetStringWithoutPathExpansion(shill::kActivationStateProperty, 175 activation_state()); 176 dictionary->SetStringWithoutPathExpansion(shill::kRoamingStateProperty, 177 roaming()); 178 dictionary->SetBooleanWithoutPathExpansion(shill::kOutOfCreditsProperty, 179 cellular_out_of_credits()); 180 } 181} 182 183void NetworkState::IPConfigPropertiesChanged( 184 const base::DictionaryValue& properties) { 185 for (base::DictionaryValue::Iterator iter(properties); 186 !iter.IsAtEnd(); iter.Advance()) { 187 std::string key = iter.key(); 188 const base::Value& value = iter.value(); 189 190 if (key == shill::kAddressProperty) { 191 GetStringValue(key, value, &ip_address_); 192 } else if (key == shill::kGatewayProperty) { 193 GetStringValue(key, value, &gateway_); 194 } else if (key == shill::kNameServersProperty) { 195 const base::ListValue* dns_servers; 196 if (value.GetAsList(&dns_servers)) { 197 dns_servers_.clear(); 198 ConvertListValueToStringVector(*dns_servers, &dns_servers_); 199 } 200 } else if (key == shill::kPrefixlenProperty) { 201 GetIntegerValue(key, value, &prefix_length_); 202 } else if (key == shill::kWebProxyAutoDiscoveryUrlProperty) { 203 std::string url_string; 204 if (GetStringValue(key, value, &url_string)) { 205 if (url_string.empty()) { 206 web_proxy_auto_discovery_url_ = GURL(); 207 } else { 208 GURL gurl(url_string); 209 if (gurl.is_valid()) { 210 web_proxy_auto_discovery_url_ = gurl; 211 } else { 212 NET_LOG_ERROR("Invalid WebProxyAutoDiscoveryUrl: " + url_string, 213 path()); 214 web_proxy_auto_discovery_url_ = GURL(); 215 } 216 } 217 } 218 } 219 } 220} 221 222bool NetworkState::RequiresActivation() const { 223 return (type() == shill::kTypeCellular && 224 activation_state() != shill::kActivationStateActivated && 225 activation_state() != shill::kActivationStateUnknown); 226} 227 228bool NetworkState::IsConnectedState() const { 229 return StateIsConnected(connection_state_); 230} 231 232bool NetworkState::IsConnectingState() const { 233 return StateIsConnecting(connection_state_); 234} 235 236bool NetworkState::IsPrivate() const { 237 return !profile_path_.empty() && 238 profile_path_ != NetworkProfileHandler::GetSharedProfilePath(); 239} 240 241std::string NetworkState::GetDnsServersAsString() const { 242 std::string result; 243 for (size_t i = 0; i < dns_servers_.size(); ++i) { 244 if (i != 0) 245 result += ","; 246 result += dns_servers_[i]; 247 } 248 return result; 249} 250 251std::string NetworkState::GetNetmask() const { 252 return network_util::PrefixLengthToNetmask(prefix_length_); 253} 254 255bool NetworkState::UpdateName(const base::DictionaryValue& properties) { 256 std::string updated_name = 257 shill_property_util::GetNameFromProperties(path(), properties); 258 if (updated_name != name()) { 259 set_name(updated_name); 260 return true; 261 } 262 return false; 263} 264 265// static 266bool NetworkState::StateIsConnected(const std::string& connection_state) { 267 return (connection_state == shill::kStateReady || 268 connection_state == shill::kStateOnline || 269 connection_state == shill::kStatePortal); 270} 271 272// static 273bool NetworkState::StateIsConnecting(const std::string& connection_state) { 274 return (connection_state == shill::kStateAssociation || 275 connection_state == shill::kStateConfiguration || 276 connection_state == shill::kStateCarrier); 277} 278 279// static 280bool NetworkState::ErrorIsValid(const std::string& error) { 281 // Shill uses "Unknown" to indicate an unset or cleared error state. 282 return !error.empty() && error != kErrorUnknown; 283} 284 285} // namespace chromeos 286