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.
5 #include "chromeos/network/network_state.h"
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"
17 const char kErrorUnknown[] = "Unknown";
19 bool ConvertListValueToStringVector(const base::ListValue& string_list,
20 std::vector<std::string>* result) {
21 for (size_t i = 0; i < string_list.GetSize(); ++i) {
23 if (!string_list.GetString(i, &str))
25 result->push_back(str);
30 bool IsCaCertNssSet(const base::DictionaryValue& properties) {
31 std::string ca_cert_nss;
32 if (properties.GetStringWithoutPathExpansion(shill::kEapCaCertNssProperty,
34 !ca_cert_nss.empty()) {
38 const base::DictionaryValue* provider = NULL;
39 properties.GetDictionaryWithoutPathExpansion(shill::kProviderProperty,
43 if (provider->GetStringWithoutPathExpansion(
44 shill::kL2tpIpsecCaCertNssProperty, &ca_cert_nss) &&
45 !ca_cert_nss.empty()) {
48 if (provider->GetStringWithoutPathExpansion(
49 shill::kOpenVPNCaCertNSSProperty, &ca_cert_nss) &&
50 !ca_cert_nss.empty()) {
61 NetworkState::NetworkState(const std::string& path)
62 : ManagedState(MANAGED_TYPE_NETWORK, path),
66 activate_over_non_cellular_networks_(false),
67 cellular_out_of_credits_(false),
68 has_ca_cert_nss_(false) {
71 NetworkState::~NetworkState() {
74 bool 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))
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_))
88 // Shill uses "Unknown" to indicate an unset error state.
89 if (error_ == kErrorUnknown)
92 } else if (key == IPConfigProperty(shill::kAddressProperty)) {
93 return GetStringValue(key, value, &ip_address_);
94 } else if (key == IPConfigProperty(shill::kGatewayProperty)) {
95 return GetStringValue(key, value, &gateway_);
96 } else if (key == IPConfigProperty(shill::kNameServersProperty)) {
97 const base::ListValue* dns_servers;
98 if (!value.GetAsList(&dns_servers))
100 dns_servers_.clear();
101 ConvertListValueToStringVector(*dns_servers, &dns_servers_);
103 } else if (key == IPConfigProperty(shill::kPrefixlenProperty)) {
104 return GetIntegerValue(key, value, &prefix_length_);
105 } else if (key == IPConfigProperty(
106 shill::kWebProxyAutoDiscoveryUrlProperty)) {
107 std::string url_string;
108 if (!GetStringValue(key, value, &url_string))
110 if (url_string.empty()) {
111 web_proxy_auto_discovery_url_ = GURL();
113 GURL gurl(url_string);
114 if (!gurl.is_valid()) {
115 web_proxy_auto_discovery_url_ = gurl;
117 NET_LOG_ERROR("Invalid WebProxyAutoDiscoveryUrl: " + url_string,
119 web_proxy_auto_discovery_url_ = GURL();
123 } else if (key == shill::kActivationStateProperty) {
124 return GetStringValue(key, value, &activation_state_);
125 } else if (key == shill::kRoamingStateProperty) {
126 return GetStringValue(key, value, &roaming_);
127 } else if (key == shill::kSecurityProperty) {
128 return GetStringValue(key, value, &security_);
129 } else if (key == shill::kEapMethodProperty) {
130 return GetStringValue(key, value, &eap_method_);
131 } else if (key == shill::kUIDataProperty) {
132 scoped_ptr<NetworkUIData> new_ui_data =
133 shill_property_util::GetUIDataFromValue(value);
135 NET_LOG_ERROR("Failed to parse " + key, path());
138 ui_data_ = *new_ui_data;
140 } else if (key == shill::kNetworkTechnologyProperty) {
141 return GetStringValue(key, value, &network_technology_);
142 } else if (key == shill::kDeviceProperty) {
143 return GetStringValue(key, value, &device_path_);
144 } else if (key == shill::kGuidProperty) {
145 return GetStringValue(key, value, &guid_);
146 } else if (key == shill::kProfileProperty) {
147 return GetStringValue(key, value, &profile_path_);
148 } else if (key == shill::kActivateOverNonCellularNetworkProperty) {
149 return GetBooleanValue(key, value, &activate_over_non_cellular_networks_);
150 } else if (key == shill::kOutOfCreditsProperty) {
151 return GetBooleanValue(key, value, &cellular_out_of_credits_);
156 bool NetworkState::InitialPropertiesReceived(
157 const base::DictionaryValue& properties) {
158 NET_LOG_DEBUG("InitialPropertiesReceived", path());
159 bool changed = UpdateName(properties);
160 bool had_ca_cert_nss = has_ca_cert_nss_;
161 has_ca_cert_nss_ = IsCaCertNssSet(properties);
162 changed |= had_ca_cert_nss != has_ca_cert_nss_;
166 void NetworkState::GetProperties(base::DictionaryValue* dictionary) const {
167 // Keep care that these properties are the same as in |PropertyChanged|.
168 dictionary->SetStringWithoutPathExpansion(shill::kNameProperty, name());
169 dictionary->SetStringWithoutPathExpansion(shill::kTypeProperty, type());
170 dictionary->SetIntegerWithoutPathExpansion(shill::kSignalStrengthProperty,
172 dictionary->SetStringWithoutPathExpansion(shill::kStateProperty,
174 dictionary->SetBooleanWithoutPathExpansion(shill::kConnectableProperty,
177 dictionary->SetStringWithoutPathExpansion(shill::kErrorProperty, error_);
179 // IPConfig properties
180 base::DictionaryValue* ipconfig_properties = new base::DictionaryValue;
181 ipconfig_properties->SetStringWithoutPathExpansion(shill::kAddressProperty,
183 ipconfig_properties->SetStringWithoutPathExpansion(shill::kGatewayProperty,
185 base::ListValue* name_servers = new base::ListValue;
186 name_servers->AppendStrings(dns_servers_);
187 ipconfig_properties->SetWithoutPathExpansion(shill::kNameServersProperty,
189 ipconfig_properties->SetStringWithoutPathExpansion(
190 shill::kWebProxyAutoDiscoveryUrlProperty,
191 web_proxy_auto_discovery_url_.spec());
192 dictionary->SetWithoutPathExpansion(shill::kIPConfigProperty,
193 ipconfig_properties);
195 dictionary->SetStringWithoutPathExpansion(shill::kActivationStateProperty,
197 dictionary->SetStringWithoutPathExpansion(shill::kRoamingStateProperty,
199 dictionary->SetStringWithoutPathExpansion(shill::kSecurityProperty,
201 dictionary->SetStringWithoutPathExpansion(shill::kEapMethodProperty,
203 // Proxy config and ONC source are intentionally omitted: These properties are
204 // placed in NetworkState to transition ProxyConfigServiceImpl from
205 // NetworkLibrary to the new network stack. The networking extension API
206 // shouldn't depend on this member. Once ManagedNetworkConfigurationHandler
207 // is used instead of NetworkLibrary, we can remove them again.
208 dictionary->SetStringWithoutPathExpansion(
209 shill::kNetworkTechnologyProperty,
210 network_technology_);
211 dictionary->SetStringWithoutPathExpansion(shill::kDeviceProperty,
213 dictionary->SetStringWithoutPathExpansion(shill::kGuidProperty, guid_);
214 dictionary->SetStringWithoutPathExpansion(shill::kProfileProperty,
216 dictionary->SetBooleanWithoutPathExpansion(
217 shill::kActivateOverNonCellularNetworkProperty,
218 activate_over_non_cellular_networks_);
219 dictionary->SetBooleanWithoutPathExpansion(shill::kOutOfCreditsProperty,
220 cellular_out_of_credits_);
223 bool NetworkState::RequiresActivation() const {
224 return (type() == shill::kTypeCellular &&
225 activation_state() != shill::kActivationStateActivated &&
226 activation_state() != shill::kActivationStateUnknown);
229 bool NetworkState::IsConnectedState() const {
230 return StateIsConnected(connection_state_);
233 bool NetworkState::IsConnectingState() const {
234 return StateIsConnecting(connection_state_);
237 bool NetworkState::IsPrivate() const {
238 return !profile_path_.empty() &&
239 profile_path_ != NetworkProfileHandler::kSharedProfilePath;
242 std::string NetworkState::GetDnsServersAsString() const {
244 for (size_t i = 0; i < dns_servers_.size(); ++i) {
247 result += dns_servers_[i];
252 std::string NetworkState::GetNetmask() const {
253 return network_util::PrefixLengthToNetmask(prefix_length_);
256 bool 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);
267 bool NetworkState::StateIsConnected(const std::string& connection_state) {
268 return (connection_state == shill::kStateReady ||
269 connection_state == shill::kStateOnline ||
270 connection_state == shill::kStatePortal);
274 bool NetworkState::StateIsConnecting(const std::string& connection_state) {
275 return (connection_state == shill::kStateAssociation ||
276 connection_state == shill::kStateConfiguration ||
277 connection_state == shill::kStateCarrier);
281 std::string NetworkState::IPConfigProperty(const char* key) {
282 return base::StringPrintf("%s.%s", shill::kIPConfigProperty, key);
285 } // namespace chromeos