blob: 4822d6fa2a12d1e8e21df1daa76e187d2eb4cd72 [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chromeos/network/device_state.h"
#include <memory>
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/stringprintf.h"
#include "base/values.h"
#include "chromeos/network/network_event_log.h"
#include "chromeos/network/shill_property_util.h"
#include "third_party/cros_system_api/dbus/service_constants.h"
namespace chromeos {
DeviceState::DeviceState(const std::string& path)
: ManagedState(MANAGED_TYPE_DEVICE, path),
allow_roaming_(false),
provider_requires_roaming_(false),
support_network_scan_(false),
scanning_(false),
sim_retries_left_(0),
sim_present_(true),
eap_authentication_completed_(false) {}
DeviceState::~DeviceState() = default;
bool DeviceState::PropertyChanged(const std::string& key,
const base::Value& value) {
// All property values get stored in |properties_|.
properties_.SetKey(key, value.Clone());
if (ManagedStatePropertyChanged(key, value))
return true;
if (key == shill::kAddressProperty) {
return GetStringValue(key, value, &mac_address_);
} else if (key == shill::kScanningProperty) {
return GetBooleanValue(key, value, &scanning_);
} else if (key == shill::kSupportNetworkScanProperty) {
return GetBooleanValue(key, value, &support_network_scan_);
} else if (key == shill::kCellularAllowRoamingProperty) {
return GetBooleanValue(key, value, &allow_roaming_);
} else if (key == shill::kProviderRequiresRoamingProperty) {
return GetBooleanValue(key, value, &provider_requires_roaming_);
} else if (key == shill::kHomeProviderProperty) {
if (!value.is_dict()) {
operator_name_.clear();
country_code_.clear();
return true;
}
const base::Value* operator_name = value.FindKey(shill::kOperatorNameKey);
if (operator_name)
operator_name_ = operator_name->GetString();
if (operator_name_.empty()) {
const base::Value* operator_code = value.FindKey(shill::kOperatorCodeKey);
operator_name_ = operator_code ? operator_code->GetString() : "";
}
const base::Value* country_code = value.FindKey(shill::kOperatorCountryKey);
country_code_ = country_code ? country_code->GetString() : "";
} else if (key == shill::kTechnologyFamilyProperty) {
return GetStringValue(key, value, &technology_family_);
} else if (key == shill::kCarrierProperty) {
return GetStringValue(key, value, &carrier_);
} else if (key == shill::kFoundNetworksProperty) {
const base::ListValue* list = nullptr;
if (!value.GetAsList(&list))
return false;
CellularScanResults parsed_results;
if (!network_util::ParseCellularScanResults(*list, &parsed_results))
return false;
scan_results_.swap(parsed_results);
return true;
} else if (key == shill::kSIMLockStatusProperty) {
const base::DictionaryValue* dict = nullptr;
if (!value.GetAsDictionary(&dict))
return false;
// Set default values for SIM properties.
sim_lock_type_.erase();
sim_retries_left_ = 0;
sim_lock_enabled_ = false;
const base::Value* out_value = nullptr;
if (dict->GetWithoutPathExpansion(shill::kSIMLockTypeProperty,
&out_value)) {
GetStringValue(shill::kSIMLockTypeProperty, *out_value, &sim_lock_type_);
}
if (dict->GetWithoutPathExpansion(shill::kSIMLockRetriesLeftProperty,
&out_value)) {
GetIntegerValue(shill::kSIMLockRetriesLeftProperty, *out_value,
&sim_retries_left_);
}
if (dict->GetWithoutPathExpansion(shill::kSIMLockEnabledProperty,
&out_value)) {
GetBooleanValue(shill::kSIMLockEnabledProperty, *out_value,
&sim_lock_enabled_);
}
return true;
} else if (key == shill::kMeidProperty) {
return GetStringValue(key, value, &meid_);
} else if (key == shill::kImeiProperty) {
return GetStringValue(key, value, &imei_);
} else if (key == shill::kIccidProperty) {
return GetStringValue(key, value, &iccid_);
} else if (key == shill::kMdnProperty) {
return GetStringValue(key, value, &mdn_);
} else if (key == shill::kSIMPresentProperty) {
return GetBooleanValue(key, value, &sim_present_);
} else if (key == shill::kEapAuthenticationCompletedProperty) {
return GetBooleanValue(key, value, &eap_authentication_completed_);
} else if (key == shill::kIPConfigsProperty) {
// If kIPConfigsProperty changes, clear any previous ip_configs_.
// ShillPropertyhandler will request the IPConfig objects which will trigger
// calls to IPConfigPropertiesChanged.
ip_configs_.Clear();
return false; // No actual state change.
}
return false;
}
void DeviceState::IPConfigPropertiesChanged(const std::string& ip_config_path,
const base::Value& properties) {
NET_LOG(EVENT) << "IPConfig for: " << path()
<< " Changed: " << ip_config_path;
ip_configs_.SetKey(ip_config_path, properties.Clone());
}
std::string DeviceState::GetName() const {
if (!operator_name_.empty())
return operator_name_;
return name();
}
std::string DeviceState::GetIpAddressByType(const std::string& type) const {
for (base::DictionaryValue::Iterator iter(ip_configs_); !iter.IsAtEnd();
iter.Advance()) {
const base::DictionaryValue* ip_config;
if (!iter.value().GetAsDictionary(&ip_config))
continue;
std::string ip_config_method;
if (!ip_config->GetString(shill::kMethodProperty, &ip_config_method))
continue;
if (type == ip_config_method ||
(type == shill::kTypeIPv4 && ip_config_method == shill::kTypeDHCP) ||
(type == shill::kTypeIPv6 && ip_config_method == shill::kTypeDHCP6)) {
std::string address;
if (!ip_config->GetString(shill::kAddressProperty, &address))
continue;
return address;
}
}
return std::string();
}
bool DeviceState::IsSimAbsent() const {
return technology_family_ != shill::kTechnologyFamilyCdma && !sim_present_;
}
bool DeviceState::IsSimLocked() const {
if (technology_family_ == shill::kTechnologyFamilyCdma || !sim_present_)
return false;
return sim_lock_type_ == shill::kSIMLockPin ||
sim_lock_type_ == shill::kSIMLockPuk;
}
} // namespace chromeos