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 if (ErrorIsValid(error_
))
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
);
105 NET_LOG_ERROR("Failed to parse " + key
, path());
108 ui_data_
= *new_ui_data
;
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_
);
126 bool 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
));
135 // Ensure that the network has a valid name.
136 changed
|= UpdateName(properties
);
138 // Set the has_ca_cert_nss_ property.
139 bool had_ca_cert_nss
= has_ca_cert_nss_
;
140 has_ca_cert_nss_
= IsCaCertNssSet(properties
);
141 changed
|= had_ca_cert_nss
!= has_ca_cert_nss_
;
143 // By convention, all visible WiFi networks have a SignalStrength > 0.
144 if (type() == shill::kTypeWifi
) {
145 if (signal_strength_
<= 0)
146 signal_strength_
= 1;
152 void NetworkState::GetStateProperties(base::DictionaryValue
* dictionary
) const {
153 ManagedState::GetStateProperties(dictionary
);
155 // Properties shared by all types.
156 dictionary
->SetStringWithoutPathExpansion(shill::kGuidProperty
, guid());
157 dictionary
->SetStringWithoutPathExpansion(shill::kStateProperty
,
159 dictionary
->SetStringWithoutPathExpansion(shill::kSecurityProperty
,
161 if (!error().empty())
162 dictionary
->SetStringWithoutPathExpansion(shill::kErrorProperty
, error());
164 if (!NetworkTypePattern::Wireless().MatchesType(type()))
167 // Wireless properties
168 dictionary
->SetBooleanWithoutPathExpansion(shill::kConnectableProperty
,
170 dictionary
->SetIntegerWithoutPathExpansion(shill::kSignalStrengthProperty
,
174 if (NetworkTypePattern::WiFi().MatchesType(type())) {
175 dictionary
->SetStringWithoutPathExpansion(shill::kEapMethodProperty
,
180 if (NetworkTypePattern::Mobile().MatchesType(type())) {
181 dictionary
->SetStringWithoutPathExpansion(
182 shill::kNetworkTechnologyProperty
,
183 network_technology());
184 dictionary
->SetStringWithoutPathExpansion(shill::kActivationStateProperty
,
186 dictionary
->SetStringWithoutPathExpansion(shill::kRoamingStateProperty
,
188 dictionary
->SetBooleanWithoutPathExpansion(shill::kOutOfCreditsProperty
,
189 cellular_out_of_credits());
193 void NetworkState::IPConfigPropertiesChanged(
194 const base::DictionaryValue
& properties
) {
195 for (base::DictionaryValue::Iterator
iter(properties
);
196 !iter
.IsAtEnd(); iter
.Advance()) {
197 std::string key
= iter
.key();
198 const base::Value
& value
= iter
.value();
200 if (key
== shill::kAddressProperty
) {
201 GetStringValue(key
, value
, &ip_address_
);
202 } else if (key
== shill::kGatewayProperty
) {
203 GetStringValue(key
, value
, &gateway_
);
204 } else if (key
== shill::kNameServersProperty
) {
205 const base::ListValue
* dns_servers
;
206 if (value
.GetAsList(&dns_servers
)) {
207 dns_servers_
.clear();
208 ConvertListValueToStringVector(*dns_servers
, &dns_servers_
);
210 } else if (key
== shill::kPrefixlenProperty
) {
211 GetIntegerValue(key
, value
, &prefix_length_
);
212 } else if (key
== shill::kWebProxyAutoDiscoveryUrlProperty
) {
213 std::string url_string
;
214 if (GetStringValue(key
, value
, &url_string
)) {
215 if (url_string
.empty()) {
216 web_proxy_auto_discovery_url_
= GURL();
218 GURL
gurl(url_string
);
219 if (gurl
.is_valid()) {
220 web_proxy_auto_discovery_url_
= gurl
;
222 NET_LOG_ERROR("Invalid WebProxyAutoDiscoveryUrl: " + url_string
,
224 web_proxy_auto_discovery_url_
= GURL();
232 bool NetworkState::RequiresActivation() const {
233 return (type() == shill::kTypeCellular
&&
234 activation_state() != shill::kActivationStateActivated
&&
235 activation_state() != shill::kActivationStateUnknown
);
238 bool NetworkState::IsConnectedState() const {
239 return StateIsConnected(connection_state_
);
242 bool NetworkState::IsConnectingState() const {
243 return StateIsConnecting(connection_state_
);
246 bool NetworkState::IsPrivate() const {
247 return !profile_path_
.empty() &&
248 profile_path_
!= NetworkProfileHandler::GetSharedProfilePath();
251 std::string
NetworkState::GetDnsServersAsString() const {
253 for (size_t i
= 0; i
< dns_servers_
.size(); ++i
) {
256 result
+= dns_servers_
[i
];
261 std::string
NetworkState::GetNetmask() const {
262 return network_util::PrefixLengthToNetmask(prefix_length_
);
265 void NetworkState::SetGuid(const std::string
& guid
) {
269 bool NetworkState::UpdateName(const base::DictionaryValue
& properties
) {
270 std::string updated_name
=
271 shill_property_util::GetNameFromProperties(path(), properties
);
272 if (updated_name
!= name()) {
273 set_name(updated_name
);
280 bool NetworkState::StateIsConnected(const std::string
& connection_state
) {
281 return (connection_state
== shill::kStateReady
||
282 connection_state
== shill::kStateOnline
||
283 connection_state
== shill::kStatePortal
);
287 bool NetworkState::StateIsConnecting(const std::string
& connection_state
) {
288 return (connection_state
== shill::kStateAssociation
||
289 connection_state
== shill::kStateConfiguration
||
290 connection_state
== shill::kStateCarrier
);
294 bool NetworkState::ErrorIsValid(const std::string
& error
) {
295 // Shill uses "Unknown" to indicate an unset or cleared error state.
296 return !error
.empty() && error
!= kErrorUnknown
;
299 } // namespace chromeos