Home | History | Annotate | Download | only in network
      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 
     15 namespace {
     16 
     17 const char kErrorUnknown[] = "Unknown";
     18 
     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) {
     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 
     30 bool 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 
     59 namespace chromeos {
     60 
     61 NetworkState::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 
     71 NetworkState::~NetworkState() {
     72 }
     73 
     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))
     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     return true;
     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))
     99       return false;
    100     dns_servers_.clear();
    101     ConvertListValueToStringVector(*dns_servers, &dns_servers_);
    102     return true;
    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))
    109       return false;
    110     if (url_string.empty()) {
    111       web_proxy_auto_discovery_url_ = GURL();
    112     } else {
    113       GURL gurl(url_string);
    114       if (!gurl.is_valid()) {
    115         web_proxy_auto_discovery_url_ = gurl;
    116       } else {
    117         NET_LOG_ERROR("Invalid WebProxyAutoDiscoveryUrl: " + url_string,
    118                       path());
    119         web_proxy_auto_discovery_url_ = GURL();
    120       }
    121     }
    122     return true;
    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);
    134     if (!new_ui_data) {
    135       NET_LOG_ERROR("Failed to parse " + key, path());
    136       return false;
    137     }
    138     ui_data_ = *new_ui_data;
    139     return true;
    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_);
    152   }
    153   return false;
    154 }
    155 
    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_;
    163   return changed;
    164 }
    165 
    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,
    171                                              signal_strength_);
    172   dictionary->SetStringWithoutPathExpansion(shill::kStateProperty,
    173                                             connection_state_);
    174   dictionary->SetBooleanWithoutPathExpansion(shill::kConnectableProperty,
    175                                              connectable_);
    176 
    177   dictionary->SetStringWithoutPathExpansion(shill::kErrorProperty, error_);
    178 
    179   // IPConfig properties
    180   base::DictionaryValue* ipconfig_properties = new base::DictionaryValue;
    181   ipconfig_properties->SetStringWithoutPathExpansion(shill::kAddressProperty,
    182                                                      ip_address_);
    183   ipconfig_properties->SetStringWithoutPathExpansion(shill::kGatewayProperty,
    184                                                      gateway_);
    185   base::ListValue* name_servers = new base::ListValue;
    186   name_servers->AppendStrings(dns_servers_);
    187   ipconfig_properties->SetWithoutPathExpansion(shill::kNameServersProperty,
    188                                                name_servers);
    189   ipconfig_properties->SetStringWithoutPathExpansion(
    190       shill::kWebProxyAutoDiscoveryUrlProperty,
    191       web_proxy_auto_discovery_url_.spec());
    192   dictionary->SetWithoutPathExpansion(shill::kIPConfigProperty,
    193                                       ipconfig_properties);
    194 
    195   dictionary->SetStringWithoutPathExpansion(shill::kActivationStateProperty,
    196                                             activation_state_);
    197   dictionary->SetStringWithoutPathExpansion(shill::kRoamingStateProperty,
    198                                             roaming_);
    199   dictionary->SetStringWithoutPathExpansion(shill::kSecurityProperty,
    200                                             security_);
    201   dictionary->SetStringWithoutPathExpansion(shill::kEapMethodProperty,
    202                                             eap_method_);
    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,
    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 
    223 bool NetworkState::RequiresActivation() const {
    224   return (type() == shill::kTypeCellular &&
    225           activation_state() != shill::kActivationStateActivated &&
    226           activation_state() != shill::kActivationStateUnknown);
    227 }
    228 
    229 bool NetworkState::IsConnectedState() const {
    230   return StateIsConnected(connection_state_);
    231 }
    232 
    233 bool NetworkState::IsConnectingState() const {
    234   return StateIsConnecting(connection_state_);
    235 }
    236 
    237 bool NetworkState::IsPrivate() const {
    238   return !profile_path_.empty() &&
    239       profile_path_ != NetworkProfileHandler::kSharedProfilePath;
    240 }
    241 
    242 std::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 
    252 std::string NetworkState::GetNetmask() const {
    253   return network_util::PrefixLengthToNetmask(prefix_length_);
    254 }
    255 
    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);
    261     return true;
    262   }
    263   return false;
    264 }
    265 
    266 // static
    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);
    271 }
    272 
    273 // static
    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);
    278 }
    279 
    280 // static
    281 std::string NetworkState::IPConfigProperty(const char* key) {
    282   return base::StringPrintf("%s.%s", shill::kIPConfigProperty, key);
    283 }
    284 
    285 }  // namespace chromeos
    286