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