Home | History | Annotate | Download | only in shill
      1 //
      2 // Copyright (C) 2012 The Android Open Source Project
      3 //
      4 // Licensed under the Apache License, Version 2.0 (the "License");
      5 // you may not use this file except in compliance with the License.
      6 // You may obtain a copy of the License at
      7 //
      8 //      http://www.apache.org/licenses/LICENSE-2.0
      9 //
     10 // Unless required by applicable law or agreed to in writing, software
     11 // distributed under the License is distributed on an "AS IS" BASIS,
     12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 // See the License for the specific language governing permissions and
     14 // limitations under the License.
     15 //
     16 
     17 #include "shill/device.h"
     18 
     19 #include <errno.h>
     20 #include <netinet/in.h>
     21 #include <linux/if.h>  // NOLINT - Needs definitions from netinet/in.h
     22 #include <stdio.h>
     23 #include <string.h>
     24 #include <sys/param.h>
     25 #include <time.h>
     26 #include <unistd.h>
     27 
     28 #include <algorithm>
     29 #include <set>
     30 #include <string>
     31 #include <vector>
     32 
     33 #include <base/bind.h>
     34 #include <base/files/file_util.h>
     35 #include <base/memory/ref_counted.h>
     36 #include <base/stl_util.h>
     37 #include <base/strings/stringprintf.h>
     38 #include <base/strings/string_number_conversions.h>
     39 #include <base/strings/string_util.h>
     40 #if defined(__ANDROID__)
     41 #include <dbus/service_constants.h>
     42 #else
     43 #include <chromeos/dbus/service_constants.h>
     44 #endif  // __ANDROID__
     45 
     46 #include "shill/async_connection.h"
     47 #include "shill/connection.h"
     48 #include "shill/connection_tester.h"
     49 #include "shill/control_interface.h"
     50 #include "shill/dhcp/dhcp_config.h"
     51 #include "shill/dhcp/dhcp_provider.h"
     52 #include "shill/dhcp_properties.h"
     53 #include "shill/error.h"
     54 #include "shill/event_dispatcher.h"
     55 #include "shill/geolocation_info.h"
     56 #include "shill/http_proxy.h"
     57 #include "shill/icmp.h"
     58 #include "shill/ip_address_store.h"
     59 #include "shill/link_monitor.h"
     60 #include "shill/logging.h"
     61 #include "shill/manager.h"
     62 #include "shill/metrics.h"
     63 #include "shill/net/ip_address.h"
     64 #include "shill/net/ndisc.h"
     65 #include "shill/net/rtnl_handler.h"
     66 #include "shill/property_accessor.h"
     67 #include "shill/refptr_types.h"
     68 #include "shill/service.h"
     69 #include "shill/socket_info_reader.h"
     70 #include "shill/store_interface.h"
     71 #include "shill/technology.h"
     72 #include "shill/tethering.h"
     73 #include "shill/traffic_monitor.h"
     74 
     75 using base::Bind;
     76 using base::Callback;
     77 using base::FilePath;
     78 using base::StringPrintf;
     79 using std::set;
     80 using std::string;
     81 using std::vector;
     82 
     83 namespace shill {
     84 
     85 namespace Logging {
     86 static auto kModuleLogScope = ScopeLogger::kDevice;
     87 static string ObjectID(Device* d) { return d->GetRpcIdentifier(); }
     88 }
     89 
     90 // static
     91 const char Device::kIPFlagTemplate[] = "/proc/sys/net/%s/conf/%s/%s";
     92 // static
     93 const char Device::kIPFlagVersion4[] = "ipv4";
     94 // static
     95 const char Device::kIPFlagVersion6[] = "ipv6";
     96 // static
     97 const char Device::kIPFlagDisableIPv6[] = "disable_ipv6";
     98 // static
     99 const char Device::kIPFlagUseTempAddr[] = "use_tempaddr";
    100 // static
    101 const char Device::kIPFlagUseTempAddrUsedAndDefault[] = "2";
    102 // static
    103 const char Device::kIPFlagReversePathFilter[] = "rp_filter";
    104 // static
    105 const char Device::kIPFlagReversePathFilterEnabled[] = "1";
    106 // static
    107 const char Device::kIPFlagReversePathFilterLooseMode[] = "2";
    108 // static
    109 const char Device::kIPFlagArpAnnounce[] = "arp_announce";
    110 // static
    111 const char Device::kIPFlagArpAnnounceDefault[] = "0";
    112 // static
    113 const char Device::kIPFlagArpAnnounceBestLocal[] = "2";
    114 // static
    115 const char Device::kIPFlagArpIgnore[] = "arp_ignore";
    116 // static
    117 const char Device::kIPFlagArpIgnoreDefault[] = "0";
    118 // static
    119 const char Device::kIPFlagArpIgnoreLocalOnly[] = "1";
    120 // static
    121 const char Device::kStoragePowered[] = "Powered";
    122 // static
    123 const char Device::kStorageReceiveByteCount[] = "ReceiveByteCount";
    124 // static
    125 const char Device::kStorageTransmitByteCount[] = "TransmitByteCount";
    126 // static
    127 const char Device::kFallbackDnsTestHostname[] = "www.gstatic.com";
    128 // static
    129 const char* Device::kFallbackDnsServers[] = {
    130     "8.8.8.8",
    131     "8.8.4.4"
    132 };
    133 
    134 // static
    135 const int Device::kDNSTimeoutMilliseconds = 5000;
    136 const int Device::kLinkUnreliableThresholdSeconds = 60 * 60;
    137 const size_t Device::kHardwareAddressLength = 6U;
    138 
    139 Device::Device(ControlInterface* control_interface,
    140                EventDispatcher* dispatcher,
    141                Metrics* metrics,
    142                Manager* manager,
    143                const string& link_name,
    144                const string& address,
    145                int interface_index,
    146                Technology::Identifier technology)
    147     : enabled_(false),
    148       enabled_persistent_(true),
    149       enabled_pending_(enabled_),
    150       reconnect_(true),
    151       hardware_address_(address),
    152       interface_index_(interface_index),
    153       running_(false),
    154       link_name_(link_name),
    155       unique_id_(link_name),
    156       control_interface_(control_interface),
    157       dispatcher_(dispatcher),
    158       metrics_(metrics),
    159       manager_(manager),
    160       weak_ptr_factory_(this),
    161       adaptor_(control_interface->CreateDeviceAdaptor(this)),
    162       portal_detector_callback_(Bind(&Device::PortalDetectorCallback,
    163                                      weak_ptr_factory_.GetWeakPtr())),
    164       technology_(technology),
    165       portal_attempts_to_online_(0),
    166       receive_byte_offset_(0),
    167       transmit_byte_offset_(0),
    168       dhcp_provider_(DHCPProvider::GetInstance()),
    169       rtnl_handler_(RTNLHandler::GetInstance()),
    170       time_(Time::GetInstance()),
    171       last_link_monitor_failed_time_(0),
    172       connection_tester_callback_(Bind(&Device::ConnectionTesterCallback,
    173                                        weak_ptr_factory_.GetWeakPtr())),
    174       is_loose_routing_(false),
    175       is_multi_homed_(false),
    176       connection_diagnostics_callback_(
    177           Bind(&Device::ConnectionDiagnosticsCallback,
    178                weak_ptr_factory_.GetWeakPtr())) {
    179   store_.RegisterConstString(kAddressProperty, &hardware_address_);
    180 
    181   // kBgscanMethodProperty: Registered in WiFi
    182   // kBgscanShortIntervalProperty: Registered in WiFi
    183   // kBgscanSignalThresholdProperty: Registered in WiFi
    184 
    185   // kCellularAllowRoamingProperty: Registered in Cellular
    186   // kCarrierProperty: Registered in Cellular
    187   // kEsnProperty: Registered in Cellular
    188   // kHomeProviderProperty: Registered in Cellular
    189   // kImeiProperty: Registered in Cellular
    190   // kIccidProperty: Registered in Cellular
    191   // kImsiProperty: Registered in Cellular
    192   // kManufacturerProperty: Registered in Cellular
    193   // kMdnProperty: Registered in Cellular
    194   // kMeidProperty: Registered in Cellular
    195   // kMinProperty: Registered in Cellular
    196   // kModelIDProperty: Registered in Cellular
    197   // kFirmwareRevisionProperty: Registered in Cellular
    198   // kHardwareRevisionProperty: Registered in Cellular
    199   // kPRLVersionProperty: Registered in Cellular
    200   // kSIMLockStatusProperty: Registered in Cellular
    201   // kFoundNetworksProperty: Registered in Cellular
    202   // kDBusObjectProperty: Register in Cellular
    203 
    204   store_.RegisterConstString(kInterfaceProperty, &link_name_);
    205   HelpRegisterConstDerivedRpcIdentifier(
    206       kSelectedServiceProperty, &Device::GetSelectedServiceRpcIdentifier);
    207   HelpRegisterConstDerivedRpcIdentifiers(kIPConfigsProperty,
    208                                          &Device::AvailableIPConfigs);
    209   store_.RegisterConstString(kNameProperty, &link_name_);
    210   store_.RegisterConstBool(kPoweredProperty, &enabled_);
    211   HelpRegisterConstDerivedString(kTypeProperty,
    212                                  &Device::GetTechnologyString);
    213   HelpRegisterConstDerivedUint64(kLinkMonitorResponseTimeProperty,
    214                                  &Device::GetLinkMonitorResponseTime);
    215 
    216   // TODO(cmasone): Chrome doesn't use this...does anyone?
    217   // store_.RegisterConstBool(kReconnectProperty, &reconnect_);
    218 
    219   // TODO(cmasone): Figure out what shill concept maps to flimflam's "Network".
    220   // known_properties_.push_back(kNetworksProperty);
    221 
    222   // kRoamThresholdProperty: Registered in WiFi
    223   // kScanningProperty: Registered in WiFi, Cellular
    224   // kScanIntervalProperty: Registered in WiFi, Cellular
    225   // kWakeOnWiFiFeaturesEnabledProperty: Registered in WiFi
    226 
    227   if (manager_ && manager_->device_info()) {  // Unit tests may not have these.
    228     manager_->device_info()->GetByteCounts(
    229         interface_index_, &receive_byte_offset_, &transmit_byte_offset_);
    230     HelpRegisterConstDerivedUint64(kReceiveByteCountProperty,
    231                                    &Device::GetReceiveByteCountProperty);
    232     HelpRegisterConstDerivedUint64(kTransmitByteCountProperty,
    233                                    &Device::GetTransmitByteCountProperty);
    234   }
    235 
    236   LOG(INFO) << "Device created: " << link_name_
    237             << " index " << interface_index_;
    238 }
    239 
    240 Device::~Device() {
    241   LOG(INFO) << "Device destructed: " << link_name_
    242             << " index " << interface_index_;
    243 }
    244 
    245 void Device::Initialize() {
    246   SLOG(this, 2) << "Initialized";
    247   DisableArpFiltering();
    248   EnableReversePathFilter();
    249 }
    250 
    251 void Device::LinkEvent(unsigned flags, unsigned change) {
    252   SLOG(this, 2) << "Device " << link_name_
    253                 << std::showbase << std::hex
    254                 << " flags " << flags << " changed " << change
    255                 << std::dec << std::noshowbase;
    256 }
    257 
    258 void Device::Scan(ScanType scan_type, Error* error, const string& reason) {
    259   SLOG(this, 2) << __func__ << " [Device] on " << link_name() << " from "
    260                 << reason;
    261   Error::PopulateAndLog(FROM_HERE, error, Error::kNotSupported,
    262                         "Device doesn't support scan.");
    263 }
    264 
    265 void Device::SetSchedScan(bool enable, Error* error) {
    266   SLOG(this, 2) << __func__ << " [Device] on " << link_name();
    267   Error::PopulateAndLog(FROM_HERE, error, Error::kNotSupported,
    268                         "Device doesn't support scheduled scan.");
    269 }
    270 
    271 void Device::RegisterOnNetwork(const std::string& /*network_id*/, Error* error,
    272                                  const ResultCallback& /*callback*/) {
    273   Error::PopulateAndLog(FROM_HERE, error, Error::kNotSupported,
    274                         "Device doesn't support network registration.");
    275 }
    276 
    277 void Device::RequirePIN(
    278     const string& /*pin*/, bool /*require*/,
    279     Error* error, const ResultCallback& /*callback*/) {
    280   SLOG(this, 2) << __func__;
    281   Error::PopulateAndLog(FROM_HERE, error, Error::kNotSupported,
    282                         "Device doesn't support RequirePIN.");
    283 }
    284 
    285 void Device::EnterPIN(const string& /*pin*/,
    286                       Error* error, const ResultCallback& /*callback*/) {
    287   SLOG(this, 2) << __func__;
    288   Error::PopulateAndLog(FROM_HERE, error, Error::kNotSupported,
    289                         "Device doesn't support EnterPIN.");
    290 }
    291 
    292 void Device::UnblockPIN(const string& /*unblock_code*/,
    293                         const string& /*pin*/,
    294                         Error* error, const ResultCallback& /*callback*/) {
    295   SLOG(this, 2) << __func__;
    296   Error::PopulateAndLog(FROM_HERE, error, Error::kNotSupported,
    297                         "Device doesn't support UnblockPIN.");
    298 }
    299 
    300 void Device::ChangePIN(const string& /*old_pin*/,
    301                        const string& /*new_pin*/,
    302                        Error* error, const ResultCallback& /*callback*/) {
    303   SLOG(this, 2) << __func__;
    304   Error::PopulateAndLog(FROM_HERE, error, Error::kNotSupported,
    305                         "Device doesn't support ChangePIN.");
    306 }
    307 
    308 void Device::Reset(Error* error, const ResultCallback& /*callback*/) {
    309   SLOG(this, 2) << __func__;
    310   Error::PopulateAndLog(FROM_HERE, error, Error::kNotSupported,
    311                         "Device doesn't support Reset.");
    312 }
    313 
    314 void Device::SetCarrier(const string& /*carrier*/,
    315                         Error* error, const ResultCallback& /*callback*/) {
    316   SLOG(this, 2) << __func__;
    317   Error::PopulateAndLog(FROM_HERE, error, Error::kNotSupported,
    318                         "Device doesn't support SetCarrier.");
    319 }
    320 
    321 bool Device::IsIPv6Allowed() const {
    322   return true;
    323 }
    324 
    325 void Device::DisableIPv6() {
    326   SLOG(this, 2) << __func__;
    327   SetIPFlag(IPAddress::kFamilyIPv6, kIPFlagDisableIPv6, "1");
    328 }
    329 
    330 void Device::EnableIPv6() {
    331   SLOG(this, 2) << __func__;
    332   if (!IsIPv6Allowed()) {
    333     LOG(INFO) << "Skip enabling IPv6 on " << link_name_
    334               << " as it is not allowed.";
    335     return;
    336   }
    337   SetIPFlag(IPAddress::kFamilyIPv6, kIPFlagDisableIPv6, "0");
    338 }
    339 
    340 void Device::EnableIPv6Privacy() {
    341   SetIPFlag(IPAddress::kFamilyIPv6, kIPFlagUseTempAddr,
    342             kIPFlagUseTempAddrUsedAndDefault);
    343 }
    344 
    345 void Device::SetLooseRouting(bool is_loose_routing) {
    346   if (is_loose_routing == is_loose_routing_) {
    347     return;
    348   }
    349   is_loose_routing_ = is_loose_routing;
    350   if (is_multi_homed_) {
    351     // Nothing to do: loose routing is already enabled, and should remain so.
    352     return;
    353   }
    354   if (is_loose_routing) {
    355     DisableReversePathFilter();
    356   } else {
    357     EnableReversePathFilter();
    358   }
    359 }
    360 
    361 void Device::DisableReversePathFilter() {
    362   // TODO(pstew): Current kernel doesn't offer reverse-path filtering flag
    363   // for IPv6.  crbug.com/207193
    364   SetIPFlag(IPAddress::kFamilyIPv4, kIPFlagReversePathFilter,
    365             kIPFlagReversePathFilterLooseMode);
    366 }
    367 
    368 void Device::EnableReversePathFilter() {
    369   SetIPFlag(IPAddress::kFamilyIPv4, kIPFlagReversePathFilter,
    370             kIPFlagReversePathFilterEnabled);
    371 }
    372 
    373 void Device::SetIsMultiHomed(bool is_multi_homed) {
    374   if (is_multi_homed == is_multi_homed_) {
    375     return;
    376   }
    377   LOG(INFO) << "Device " << FriendlyName() << " multi-home state is now "
    378             << is_multi_homed;
    379   is_multi_homed_ = is_multi_homed;
    380   if (is_multi_homed) {
    381     EnableArpFiltering();
    382     if (!is_loose_routing_) {
    383       DisableReversePathFilter();
    384     }
    385   } else {
    386     DisableArpFiltering();
    387     if (!is_loose_routing_) {
    388       EnableReversePathFilter();
    389     }
    390   }
    391 }
    392 
    393 void Device::DisableArpFiltering() {
    394   SetIPFlag(IPAddress::kFamilyIPv4, kIPFlagArpAnnounce,
    395             kIPFlagArpAnnounceDefault);
    396   SetIPFlag(IPAddress::kFamilyIPv4, kIPFlagArpIgnore, kIPFlagArpIgnoreDefault);
    397 }
    398 
    399 void Device::EnableArpFiltering() {
    400   SetIPFlag(IPAddress::kFamilyIPv4, kIPFlagArpAnnounce,
    401             kIPFlagArpAnnounceBestLocal);
    402   SetIPFlag(IPAddress::kFamilyIPv4, kIPFlagArpIgnore,
    403             kIPFlagArpIgnoreLocalOnly);
    404 }
    405 
    406 bool Device::IsConnected() const {
    407   if (selected_service_)
    408     return selected_service_->IsConnected();
    409   return false;
    410 }
    411 
    412 bool Device::IsConnectedToService(const ServiceRefPtr& service) const {
    413   return service == selected_service_ && IsConnected();
    414 }
    415 
    416 bool Device::IsConnectedViaTether() const {
    417   if (!ipconfig_.get())
    418     return false;
    419 
    420   ByteArray vendor_encapsulated_options =
    421       ipconfig_->properties().vendor_encapsulated_options;
    422   size_t android_vendor_encapsulated_options_len =
    423       strlen(Tethering::kAndroidVendorEncapsulatedOptions);
    424 
    425   return (vendor_encapsulated_options.size() ==
    426           android_vendor_encapsulated_options_len) &&
    427       !memcmp(&vendor_encapsulated_options[0],
    428               Tethering::kAndroidVendorEncapsulatedOptions,
    429               vendor_encapsulated_options.size());
    430 }
    431 
    432 string Device::GetRpcIdentifier() const {
    433   return adaptor_->GetRpcIdentifier();
    434 }
    435 
    436 string Device::GetStorageIdentifier() const {
    437   string id = GetRpcIdentifier();
    438   ControlInterface::RpcIdToStorageId(&id);
    439   size_t needle = id.find('_');
    440   DLOG_IF(ERROR, needle == string::npos) << "No _ in storage id?!?!";
    441   id.replace(id.begin() + needle + 1, id.end(), hardware_address_);
    442   return id;
    443 }
    444 
    445 vector<GeolocationInfo> Device::GetGeolocationObjects() const {
    446   return vector<GeolocationInfo>();
    447 }
    448 
    449 string Device::GetTechnologyString(Error* /*error*/) {
    450   return Technology::NameFromIdentifier(technology());
    451 }
    452 
    453 const string& Device::FriendlyName() const {
    454   return link_name_;
    455 }
    456 
    457 const string& Device::UniqueName() const {
    458   return unique_id_;
    459 }
    460 
    461 bool Device::Load(StoreInterface* storage) {
    462   const string id = GetStorageIdentifier();
    463   if (!storage->ContainsGroup(id)) {
    464     SLOG(this, 2) << "Device is not available in the persistent store: " << id;
    465     return false;
    466   }
    467   enabled_persistent_ = true;
    468   storage->GetBool(id, kStoragePowered, &enabled_persistent_);
    469   uint64_t rx_byte_count = 0, tx_byte_count = 0;
    470 
    471   manager_->device_info()->GetByteCounts(
    472       interface_index_, &rx_byte_count, &tx_byte_count);
    473   // If there is a byte-count present in the profile, the return value
    474   // of Device::Get*ByteCount() should be the this stored value plus
    475   // whatever additional bytes we receive since time-of-load.  We
    476   // accomplish this by the subtractions below, which can validly
    477   // roll over "negative" in the subtractions below and in Get*ByteCount.
    478   uint64_t profile_byte_count;
    479   if (storage->GetUint64(id, kStorageReceiveByteCount, &profile_byte_count)) {
    480     receive_byte_offset_ = rx_byte_count - profile_byte_count;
    481   }
    482   if (storage->GetUint64(id, kStorageTransmitByteCount, &profile_byte_count)) {
    483     transmit_byte_offset_ = tx_byte_count - profile_byte_count;
    484   }
    485 
    486   return true;
    487 }
    488 
    489 bool Device::Save(StoreInterface* storage) {
    490   const string id = GetStorageIdentifier();
    491   storage->SetBool(id, kStoragePowered, enabled_persistent_);
    492   storage->SetUint64(id, kStorageReceiveByteCount, GetReceiveByteCount());
    493   storage->SetUint64(id, kStorageTransmitByteCount, GetTransmitByteCount());
    494   return true;
    495 }
    496 
    497 void Device::OnBeforeSuspend(const ResultCallback& callback) {
    498   // Nothing to be done in the general case, so immediately report success.
    499   callback.Run(Error(Error::kSuccess));
    500 }
    501 
    502 void Device::OnAfterResume() {
    503   RenewDHCPLease();
    504   if (link_monitor_) {
    505     SLOG(this, 3) << "Informing Link Monitor of resume.";
    506     link_monitor_->OnAfterResume();
    507   }
    508   // Resume from sleep, could be in different location now.
    509   // Ignore previous link monitor failures.
    510   if (selected_service_) {
    511     selected_service_->set_unreliable(false);
    512     reliable_link_callback_.Cancel();
    513   }
    514   last_link_monitor_failed_time_ = 0;
    515 }
    516 
    517 void Device::OnDarkResume(const ResultCallback& callback) {
    518   // Nothing to be done in the general case, so immediately report success.
    519   callback.Run(Error(Error::kSuccess));
    520 }
    521 
    522 void Device::DropConnection() {
    523   SLOG(this, 2) << __func__;
    524   DestroyIPConfig();
    525   SelectService(nullptr);
    526 }
    527 
    528 void Device::DestroyIPConfig() {
    529   DisableIPv6();
    530   bool ipconfig_changed = false;
    531   if (ipconfig_.get()) {
    532     ipconfig_->ReleaseIP(IPConfig::kReleaseReasonDisconnect);
    533     ipconfig_ = nullptr;
    534     ipconfig_changed = true;
    535   }
    536   if (ip6config_.get()) {
    537     StopIPv6DNSServerTimer();
    538     ip6config_ = nullptr;
    539     ipconfig_changed = true;
    540   }
    541   if (dhcpv6_config_.get()) {
    542     dhcpv6_config_->ReleaseIP(IPConfig::kReleaseReasonDisconnect);
    543     dhcpv6_config_ = nullptr;
    544     ipconfig_changed = true;
    545   }
    546   // Emit updated IP configs if there are any changes.
    547   if (ipconfig_changed) {
    548     UpdateIPConfigsProperty();
    549   }
    550   DestroyConnection();
    551 }
    552 
    553 void Device::OnIPv6AddressChanged() {
    554   IPAddress address(IPAddress::kFamilyIPv6);
    555   if (!manager_->device_info()->GetPrimaryIPv6Address(
    556           interface_index_, &address)) {
    557     if (ip6config_) {
    558       ip6config_ = nullptr;
    559       UpdateIPConfigsProperty();
    560     }
    561     return;
    562   }
    563 
    564   IPConfig::Properties properties;
    565   if (!address.IntoString(&properties.address)) {
    566     LOG(ERROR) << "Unable to convert IPv6 address into a string!";
    567     return;
    568   }
    569   properties.subnet_prefix = address.prefix();
    570 
    571   if (!ip6config_) {
    572     ip6config_ = new IPConfig(control_interface_, link_name_);
    573   } else if (properties.address == ip6config_->properties().address &&
    574              properties.subnet_prefix ==
    575                  ip6config_->properties().subnet_prefix) {
    576     SLOG(this, 2) << __func__ << " primary address for "
    577                   << link_name_ << " is unchanged.";
    578     return;
    579   }
    580 
    581   properties.address_family = IPAddress::kFamilyIPv6;
    582   properties.method = kTypeIPv6;
    583   // It is possible for device to receive DNS server notification before IP
    584   // address notification, so preserve the saved DNS server if it exist.
    585   properties.dns_servers = ip6config_->properties().dns_servers;
    586   PrependDNSServers(IPAddress::kFamilyIPv6, &properties.dns_servers);
    587   ip6config_->set_properties(properties);
    588   UpdateIPConfigsProperty();
    589   OnIPv6ConfigUpdated();
    590 }
    591 
    592 void Device::OnIPv6DnsServerAddressesChanged() {
    593   vector<IPAddress> server_addresses;
    594   uint32_t lifetime = 0;
    595 
    596   // Stop any existing timer.
    597   StopIPv6DNSServerTimer();
    598 
    599   if (!manager_->device_info()->GetIPv6DnsServerAddresses(
    600           interface_index_, &server_addresses, &lifetime)  || lifetime == 0) {
    601     IPv6DNSServerExpired();
    602     return;
    603   }
    604 
    605   vector<string> addresses_str;
    606   for (const auto& ip : server_addresses) {
    607     string address_str;
    608     if (!ip.IntoString(&address_str)) {
    609       LOG(ERROR) << "Unable to convert IPv6 address into a string!";
    610       IPv6DNSServerExpired();
    611       return;
    612     }
    613     addresses_str.push_back(address_str);
    614   }
    615 
    616   if (!ip6config_) {
    617     ip6config_ = new IPConfig(control_interface_, link_name_);
    618   }
    619 
    620   if (lifetime != ND_OPT_LIFETIME_INFINITY) {
    621     // Setup timer to monitor DNS server lifetime if not infinite lifetime.
    622     StartIPv6DNSServerTimer(lifetime);
    623     ip6config_->UpdateLeaseExpirationTime(lifetime);
    624   } else {
    625     ip6config_->ResetLeaseExpirationTime();
    626   }
    627 
    628   PrependDNSServers(IPAddress::kFamilyIPv6, &addresses_str);
    629 
    630   // Done if no change in server addresses.
    631   if (ip6config_->properties().dns_servers == addresses_str) {
    632     SLOG(this, 2) << __func__ << " IPv6 DNS server list for "
    633                   << link_name_ << " is unchanged.";
    634     return;
    635   }
    636 
    637   ip6config_->UpdateDNSServers(addresses_str);
    638   UpdateIPConfigsProperty();
    639   OnIPv6ConfigUpdated();
    640 }
    641 
    642 void Device::StartIPv6DNSServerTimer(uint32_t lifetime_seconds) {
    643   int64_t delay = static_cast<int64_t>(lifetime_seconds) * 1000;
    644   ipv6_dns_server_expired_callback_.Reset(
    645       base::Bind(&Device::IPv6DNSServerExpired, base::Unretained(this)));
    646   dispatcher_->PostDelayedTask(ipv6_dns_server_expired_callback_.callback(),
    647                                delay);
    648 }
    649 
    650 void Device::StopIPv6DNSServerTimer() {
    651   ipv6_dns_server_expired_callback_.Cancel();
    652 }
    653 
    654 void Device::IPv6DNSServerExpired() {
    655   if (!ip6config_) {
    656     return;
    657   }
    658   ip6config_->UpdateDNSServers(vector<string>());
    659   UpdateIPConfigsProperty();
    660 }
    661 
    662 void Device::StopAllActivities() {
    663   StopTrafficMonitor();
    664   StopPortalDetection();
    665   StopConnectivityTest();
    666   StopConnectionDiagnostics();
    667   StopLinkMonitor();
    668   StopDNSTest();
    669   StopIPv6DNSServerTimer();
    670 }
    671 
    672 void Device::AddWakeOnPacketConnection(const string& ip_endpoint,
    673                                        Error* error) {
    674   Error::PopulateAndLog(
    675       FROM_HERE, error, Error::kNotSupported,
    676       "AddWakeOnPacketConnection not implemented for " + link_name_ + ".");
    677   return;
    678 }
    679 
    680 void Device::RemoveWakeOnPacketConnection(const string& ip_endpoint,
    681                                           Error* error) {
    682   Error::PopulateAndLog(
    683       FROM_HERE, error, Error::kNotSupported,
    684       "RemoveWakeOnPacketConnection not implemented for " + link_name_ + ".");
    685   return;
    686 }
    687 
    688 void Device::RemoveAllWakeOnPacketConnections(Error* error) {
    689   Error::PopulateAndLog(
    690       FROM_HERE, error, Error::kNotSupported,
    691       "RemoveAllWakeOnPacketConnections not implemented for " + link_name_ +
    692           ".");
    693   return;
    694 }
    695 
    696 void Device::RenewDHCPLease() {
    697   LOG(INFO) << __func__;
    698 
    699   if (ipconfig_) {
    700     SLOG(this, 3) << "Renewing IPv4 Address";
    701     ipconfig_->RenewIP();
    702   }
    703   if (ip6config_) {
    704     SLOG(this, 3) << "Waiting for new IPv6 configuration";
    705     // Invalidate the old IPv6 configuration, will receive notifications
    706     // from kernel for new IPv6 configuration if there is one.
    707     StopIPv6DNSServerTimer();
    708     ip6config_ = nullptr;
    709     UpdateIPConfigsProperty();
    710   }
    711   if (dhcpv6_config_) {
    712     SLOG(this, 3) << "Renewing DHCPv6 lease";
    713     dhcpv6_config_->RenewIP();
    714   }
    715 }
    716 
    717 bool Device::ShouldUseArpGateway() const {
    718   return false;
    719 }
    720 
    721 bool Device::IsUsingStaticIP() const {
    722   if (!selected_service_) {
    723     return false;
    724   }
    725   return selected_service_->HasStaticIPAddress();
    726 }
    727 
    728 bool Device::IsUsingStaticNameServers() const {
    729   if (!selected_service_) {
    730     return false;
    731   }
    732   return selected_service_->HasStaticNameServers();
    733 }
    734 
    735 bool Device::AcquireIPConfig() {
    736   return AcquireIPConfigWithLeaseName(string());
    737 }
    738 
    739 bool Device::AcquireIPConfigWithLeaseName(const string& lease_name) {
    740   DestroyIPConfig();
    741   EnableIPv6();
    742   bool arp_gateway = manager_->GetArpGateway() && ShouldUseArpGateway();
    743   DHCPConfigRefPtr dhcp_config;
    744   if (selected_service_) {
    745     dhcp_config =
    746         dhcp_provider_->CreateIPv4Config(
    747             link_name_,
    748             lease_name,
    749             arp_gateway,
    750             *(DhcpProperties::Combine(
    751                 manager_->dhcp_properties(),
    752                 selected_service_->dhcp_properties())));
    753 
    754   } else {
    755     dhcp_config =
    756         dhcp_provider_->CreateIPv4Config(link_name_,
    757                                          lease_name,
    758                                          arp_gateway,
    759                                          manager_->dhcp_properties());
    760   }
    761   const int minimum_mtu = manager()->GetMinimumMTU();
    762   if (minimum_mtu != IPConfig::kUndefinedMTU) {
    763     dhcp_config->set_minimum_mtu(minimum_mtu);
    764   }
    765 
    766   ipconfig_ = dhcp_config;
    767   ipconfig_->RegisterUpdateCallback(Bind(&Device::OnIPConfigUpdated,
    768                                          weak_ptr_factory_.GetWeakPtr()));
    769   ipconfig_->RegisterFailureCallback(Bind(&Device::OnIPConfigFailed,
    770                                           weak_ptr_factory_.GetWeakPtr()));
    771   ipconfig_->RegisterRefreshCallback(Bind(&Device::OnIPConfigRefreshed,
    772                                           weak_ptr_factory_.GetWeakPtr()));
    773   ipconfig_->RegisterExpireCallback(Bind(&Device::OnIPConfigExpired,
    774                                          weak_ptr_factory_.GetWeakPtr()));
    775   dispatcher_->PostTask(Bind(&Device::ConfigureStaticIPTask,
    776                              weak_ptr_factory_.GetWeakPtr()));
    777   if (!ipconfig_->RequestIP()) {
    778     return false;
    779   }
    780 
    781 #ifndef DISABLE_DHCPV6
    782   // Only start DHCPv6 configuration instance only if DHCPv6 is enabled
    783   // for this device.
    784   if (manager_->IsDHCPv6EnabledForDevice(link_name_)) {
    785     return AcquireIPv6ConfigWithLeaseName(lease_name);
    786   }
    787 #endif  // DISABLE_DHCPV6
    788   return true;
    789 }
    790 
    791 #ifndef DISABLE_DHCPV6
    792 bool Device::AcquireIPv6ConfigWithLeaseName(const string& lease_name) {
    793   auto dhcpv6_config =
    794       dhcp_provider_->CreateIPv6Config(link_name_, lease_name);
    795   dhcpv6_config_ = dhcpv6_config;
    796   dhcpv6_config_->RegisterUpdateCallback(
    797       Bind(&Device::OnDHCPv6ConfigUpdated, weak_ptr_factory_.GetWeakPtr()));
    798   dhcpv6_config_->RegisterFailureCallback(
    799       Bind(&Device::OnDHCPv6ConfigFailed, weak_ptr_factory_.GetWeakPtr()));
    800   dhcpv6_config_->RegisterExpireCallback(
    801       Bind(&Device::OnDHCPv6ConfigExpired, weak_ptr_factory_.GetWeakPtr()));
    802   if (!dhcpv6_config_->RequestIP()) {
    803     return false;
    804   }
    805   return true;
    806 }
    807 #endif  // DISABLE_DHCPV6
    808 
    809 void Device::AssignIPConfig(const IPConfig::Properties& properties) {
    810   DestroyIPConfig();
    811   EnableIPv6();
    812   ipconfig_ = new IPConfig(control_interface_, link_name_);
    813   ipconfig_->set_properties(properties);
    814   dispatcher_->PostTask(Bind(&Device::OnIPConfigUpdated,
    815                              weak_ptr_factory_.GetWeakPtr(), ipconfig_, true));
    816 }
    817 
    818 void Device::DestroyIPConfigLease(const string& name) {
    819   dhcp_provider_->DestroyLease(name);
    820 }
    821 
    822 void Device::HelpRegisterConstDerivedString(
    823     const string& name,
    824     string(Device::*get)(Error* error)) {
    825   store_.RegisterDerivedString(
    826       name,
    827       StringAccessor(new CustomAccessor<Device, string>(this, get, nullptr)));
    828 }
    829 
    830 void Device::HelpRegisterConstDerivedRpcIdentifier(
    831     const string& name,
    832     RpcIdentifier(Device::*get)(Error* error)) {
    833   store_.RegisterDerivedRpcIdentifier(
    834       name,
    835       RpcIdentifierAccessor(
    836           new CustomAccessor<Device, RpcIdentifier>(this, get, nullptr)));
    837 }
    838 
    839 void Device::HelpRegisterConstDerivedRpcIdentifiers(
    840     const string& name,
    841     RpcIdentifiers(Device::*get)(Error*)) {
    842   store_.RegisterDerivedRpcIdentifiers(
    843       name,
    844       RpcIdentifiersAccessor(
    845           new CustomAccessor<Device, RpcIdentifiers>(this, get, nullptr)));
    846 }
    847 
    848 void Device::HelpRegisterConstDerivedUint64(
    849     const string& name,
    850     uint64_t(Device::*get)(Error*)) {
    851   store_.RegisterDerivedUint64(
    852       name,
    853       Uint64Accessor(
    854           new CustomAccessor<Device, uint64_t>(this, get, nullptr)));
    855 }
    856 
    857 void Device::ConnectionTesterCallback() {
    858   LOG(INFO) << "Device " << FriendlyName() << ": Completed Connectivity Test";
    859   return;
    860 }
    861 
    862 void Device::ConfigureStaticIPTask() {
    863   SLOG(this, 2) << __func__ << " selected_service " << selected_service_.get()
    864                 << " ipconfig " << ipconfig_.get();
    865 
    866   if (!selected_service_ || !ipconfig_) {
    867     return;
    868   }
    869 
    870   if (IsUsingStaticIP()) {
    871     SLOG(this, 2) << __func__ << " " << " configuring static IP parameters.";
    872     // If the parameters contain an IP address, apply them now and bring
    873     // the interface up.  When DHCP information arrives, it will supplement
    874     // the static information.
    875     OnIPConfigUpdated(ipconfig_, true);
    876   } else {
    877     // Either |ipconfig_| has just been created in AcquireIPConfig() or
    878     // we're being called by OnIPConfigRefreshed().  In either case a
    879     // DHCP client has been started, and will take care of calling
    880     // OnIPConfigUpdated() when it completes.
    881     SLOG(this, 2) << __func__ << " " << " no static IP address.";
    882   }
    883 }
    884 
    885 bool Device::IPConfigCompleted(const IPConfigRefPtr& ipconfig) {
    886   return ipconfig && !ipconfig->properties().address.empty() &&
    887       !ipconfig->properties().dns_servers.empty();
    888 }
    889 
    890 void Device::OnIPv6ConfigUpdated() {
    891   // Setup connection using IPv6 configuration only if the IPv6 configuration
    892   // is ready for connection (contained both IP address and DNS servers), and
    893   // there is no existing IPv4 connection. We always prefer IPv4
    894   // configuration over IPv6.
    895   if (IPConfigCompleted(ip6config_) &&
    896       (!connection_ || connection_->IsIPv6())) {
    897     SetupConnection(ip6config_);
    898   }
    899 }
    900 
    901 void Device::SetupConnection(const IPConfigRefPtr& ipconfig) {
    902   CreateConnection();
    903   connection_->UpdateFromIPConfig(ipconfig);
    904 
    905   // Report connection type.
    906   Metrics::NetworkConnectionIPType ip_type =
    907       connection_->IsIPv6() ? Metrics::kNetworkConnectionIPTypeIPv6
    908                             : Metrics::kNetworkConnectionIPTypeIPv4;
    909   metrics_->NotifyNetworkConnectionIPType(technology_, ip_type);
    910 
    911   // Report if device have IPv6 connectivity
    912   bool ipv6_connectivity = IPConfigCompleted(ip6config_);
    913   metrics_->NotifyIPv6ConnectivityStatus(technology_, ipv6_connectivity);
    914 
    915   // SetConnection must occur after the UpdateFromIPConfig so the
    916   // service can use the values derived from the connection.
    917   if (selected_service_) {
    918     selected_service_->SetConnection(connection_);
    919 
    920     // The service state change needs to happen last, so that at the
    921     // time we report the state change to the manager, the service
    922     // has its connection.
    923     SetServiceState(Service::kStateConnected);
    924     OnConnected();
    925     portal_attempts_to_online_ = 0;
    926 
    927     // Subtle: Start portal detection after transitioning the service
    928     // to the Connected state because this call may immediately transition
    929     // to the Online state.
    930     StartPortalDetection();
    931   }
    932 
    933   SetHostname(ipconfig->properties().accepted_hostname);
    934   StartLinkMonitor();
    935   StartTrafficMonitor();
    936 }
    937 
    938 bool Device::SetHostname(const std::string& hostname) {
    939   if (hostname.empty() || !manager()->ShouldAcceptHostnameFrom(link_name_)) {
    940     return false;
    941   }
    942 
    943   string fixed_hostname = hostname;
    944   if (fixed_hostname.length() > MAXHOSTNAMELEN) {
    945     auto truncate_length = fixed_hostname.find('.');
    946     if (truncate_length == string::npos || truncate_length > MAXHOSTNAMELEN) {
    947       truncate_length = MAXHOSTNAMELEN;
    948     }
    949     fixed_hostname.resize(truncate_length);
    950   }
    951 
    952   return manager_->device_info()->SetHostname(fixed_hostname);
    953 }
    954 
    955 void Device::PrependDNSServersIntoIPConfig(const IPConfigRefPtr& ipconfig) {
    956   const auto& properties = ipconfig->properties();
    957 
    958   vector<string> servers(properties.dns_servers.begin(),
    959                          properties.dns_servers.end());
    960   PrependDNSServers(properties.address_family, &servers);
    961   if (servers == properties.dns_servers) {
    962     // If the server list is the same after being augmented then there's no need
    963     // to update the config's list of servers.
    964     return;
    965   }
    966 
    967   ipconfig->UpdateDNSServers(servers);
    968 }
    969 
    970 void Device::PrependDNSServers(const IPAddress::Family family,
    971                                vector<string>* servers) {
    972   vector<string>output_servers =
    973       manager_->FilterPrependDNSServersByFamily(family);
    974 
    975   set<string> unique(output_servers.begin(), output_servers.end());
    976   for (const auto& server : *servers) {
    977     if (unique.find(server) == unique.end()) {
    978       output_servers.push_back(server);
    979       unique.insert(server);
    980     }
    981   }
    982   servers->swap(output_servers);
    983 }
    984 
    985 void Device::ConnectionDiagnosticsCallback(
    986       const std::string& connection_issue,
    987       const std::vector<ConnectionDiagnostics::Event>& diagnostic_events) {
    988   SLOG(this, 2) << "Device " << FriendlyName()
    989                 << ": Completed Connection diagnostics";
    990   // TODO(samueltan): add connection diagnostics metrics.
    991 }
    992 
    993 void Device::OnIPConfigUpdated(const IPConfigRefPtr& ipconfig,
    994                                bool /*new_lease_acquired*/) {
    995   SLOG(this, 2) << __func__;
    996   if (selected_service_) {
    997     ipconfig->ApplyStaticIPParameters(
    998         selected_service_->mutable_static_ip_parameters());
    999     if (IsUsingStaticIP()) {
   1000       // If we are using a statically configured IP address instead
   1001       // of a leased IP address, release any acquired lease so it may
   1002       // be used by others.  This allows us to merge other non-leased
   1003       // parameters (like DNS) when they're available from a DHCP server
   1004       // and not overridden by static parameters, but at the same time
   1005       // we avoid taking up a dynamic IP address the DHCP server could
   1006       // assign to someone else who might actually use it.
   1007       ipconfig->ReleaseIP(IPConfig::kReleaseReasonStaticIP);
   1008     }
   1009   }
   1010   if (!IsUsingStaticNameServers()) {
   1011     PrependDNSServersIntoIPConfig(ipconfig);
   1012   }
   1013   SetupConnection(ipconfig);
   1014   UpdateIPConfigsProperty();
   1015 }
   1016 
   1017 void Device::OnIPConfigFailed(const IPConfigRefPtr& ipconfig) {
   1018   SLOG(this, 2) << __func__;
   1019   // TODO(pstew): This logic gets yet more complex when multiple
   1020   // IPConfig types are run in parallel (e.g. DHCP and DHCP6)
   1021   if (selected_service_) {
   1022     if (IsUsingStaticIP()) {
   1023       // Consider three cases:
   1024       //
   1025       // 1. We're here because DHCP failed while starting up. There
   1026       //    are two subcases:
   1027       //    a. DHCP has failed, and Static IP config has _not yet_
   1028       //       completed. It's fine to do nothing, because we'll
   1029       //       apply the static config shortly.
   1030       //    b. DHCP has failed, and Static IP config has _already_
   1031       //       completed. It's fine to do nothing, because we can
   1032       //       continue to use the static config that's already
   1033       //       been applied.
   1034       //
   1035       // 2. We're here because a previously valid DHCP configuration
   1036       //    is no longer valid. There's still a static IP config,
   1037       //    because the condition in the if clause evaluated to true.
   1038       //    Furthermore, the static config includes an IP address for
   1039       //    us to use.
   1040       //
   1041       //    The current configuration may include some DHCP
   1042       //    parameters, overriden by any static parameters
   1043       //    provided. We continue to use this configuration, because
   1044       //    the only configuration element that is leased to us (IP
   1045       //    address) will be overriden by a static parameter.
   1046       return;
   1047     }
   1048   }
   1049 
   1050   ipconfig->ResetProperties();
   1051   UpdateIPConfigsProperty();
   1052 
   1053   // Fallback to IPv6 if possible.
   1054   if (IPConfigCompleted(ip6config_)) {
   1055     if (!connection_ || !connection_->IsIPv6()) {
   1056       // Setup IPv6 connection.
   1057       SetupConnection(ip6config_);
   1058     } else {
   1059       // Ignore IPv4 config failure, since IPv6 is up.
   1060     }
   1061     return;
   1062   }
   1063 
   1064   OnIPConfigFailure();
   1065   DestroyConnection();
   1066 }
   1067 
   1068 void Device::OnIPConfigRefreshed(const IPConfigRefPtr& ipconfig) {
   1069   // Clear the previously applied static IP parameters.
   1070   ipconfig->RestoreSavedIPParameters(
   1071       selected_service_->mutable_static_ip_parameters());
   1072 
   1073   dispatcher_->PostTask(Bind(&Device::ConfigureStaticIPTask,
   1074                              weak_ptr_factory_.GetWeakPtr()));
   1075 }
   1076 
   1077 void Device::OnIPConfigFailure() {
   1078   if (selected_service_) {
   1079     Error error;
   1080     selected_service_->DisconnectWithFailure(Service::kFailureDHCP,
   1081                                              &error,
   1082                                              __func__);
   1083   }
   1084 }
   1085 
   1086 void Device::OnIPConfigExpired(const IPConfigRefPtr& ipconfig) {
   1087   metrics()->SendToUMA(
   1088       metrics()->GetFullMetricName(
   1089           Metrics::kMetricExpiredLeaseLengthSecondsSuffix, technology()),
   1090       ipconfig->properties().lease_duration_seconds,
   1091       Metrics::kMetricExpiredLeaseLengthSecondsMin,
   1092       Metrics::kMetricExpiredLeaseLengthSecondsMax,
   1093       Metrics::kMetricExpiredLeaseLengthSecondsNumBuckets);
   1094 }
   1095 
   1096 void Device::OnDHCPv6ConfigUpdated(const IPConfigRefPtr& ipconfig,
   1097                                    bool /*new_lease_acquired*/) {
   1098   // Emit configuration update.
   1099   UpdateIPConfigsProperty();
   1100 }
   1101 
   1102 void Device::OnDHCPv6ConfigFailed(const IPConfigRefPtr& ipconfig) {
   1103   // Reset configuration data.
   1104   ipconfig->ResetProperties();
   1105   UpdateIPConfigsProperty();
   1106 }
   1107 
   1108 void Device::OnDHCPv6ConfigExpired(const IPConfigRefPtr& ipconfig) {
   1109   // Reset configuration data.
   1110   ipconfig->ResetProperties();
   1111   UpdateIPConfigsProperty();
   1112 }
   1113 
   1114 void Device::OnConnected() {
   1115   if (selected_service_->unreliable()) {
   1116     // Post a delayed task to reset link back to reliable if no link
   1117     // failure is detected in the next 5 minutes.
   1118     reliable_link_callback_.Reset(
   1119         base::Bind(&Device::OnReliableLink, base::Unretained(this)));
   1120     dispatcher_->PostDelayedTask(
   1121         reliable_link_callback_.callback(),
   1122         kLinkUnreliableThresholdSeconds * 1000);
   1123   }
   1124 }
   1125 
   1126 void Device::OnConnectionUpdated() {
   1127   if (selected_service_) {
   1128     manager_->UpdateService(selected_service_);
   1129   }
   1130 }
   1131 
   1132 void Device::CreateConnection() {
   1133   SLOG(this, 2) << __func__;
   1134   if (!connection_.get()) {
   1135     connection_ = new Connection(interface_index_,
   1136                                  link_name_,
   1137                                  technology_,
   1138                                  manager_->device_info(),
   1139                                  control_interface_);
   1140   }
   1141 }
   1142 
   1143 void Device::DestroyConnection() {
   1144   SLOG(this, 2) << __func__ << " on " << link_name_;
   1145   StopAllActivities();
   1146   if (selected_service_.get()) {
   1147     SLOG(this, 3) << "Clearing connection of service "
   1148                   << selected_service_->unique_name();
   1149     selected_service_->SetConnection(nullptr);
   1150   }
   1151   connection_ = nullptr;
   1152 }
   1153 
   1154 void Device::SelectService(const ServiceRefPtr& service) {
   1155   SLOG(this, 2) << __func__ << ": service "
   1156                 << (service ? service->unique_name() : "*reset*")
   1157                 << " on " << link_name_;
   1158 
   1159   if (selected_service_.get() == service.get()) {
   1160     // No change to |selected_service_|. Return early to avoid
   1161     // changing its state.
   1162     return;
   1163   }
   1164 
   1165   if (selected_service_.get()) {
   1166     if (selected_service_->state() != Service::kStateFailure) {
   1167       selected_service_->SetState(Service::kStateIdle);
   1168     }
   1169     // Just in case the Device subclass has not already done so, make
   1170     // sure the previously selected service has its connection removed.
   1171     selected_service_->SetConnection(nullptr);
   1172     // Reset link status for the previously selected service.
   1173     selected_service_->set_unreliable(false);
   1174     reliable_link_callback_.Cancel();
   1175     StopAllActivities();
   1176   }
   1177 
   1178   // Newly selected service (network), previous failures doesn't apply
   1179   // anymore.
   1180   last_link_monitor_failed_time_ = 0;
   1181 
   1182   selected_service_ = service;
   1183   adaptor_->EmitRpcIdentifierChanged(
   1184       kSelectedServiceProperty, GetSelectedServiceRpcIdentifier(nullptr));
   1185 }
   1186 
   1187 void Device::SetServiceState(Service::ConnectState state) {
   1188   if (selected_service_.get()) {
   1189     selected_service_->SetState(state);
   1190   }
   1191 }
   1192 
   1193 void Device::SetServiceFailure(Service::ConnectFailure failure_state) {
   1194   if (selected_service_.get()) {
   1195     selected_service_->SetFailure(failure_state);
   1196   }
   1197 }
   1198 
   1199 void Device::SetServiceFailureSilent(Service::ConnectFailure failure_state) {
   1200   if (selected_service_.get()) {
   1201     selected_service_->SetFailureSilent(failure_state);
   1202   }
   1203 }
   1204 
   1205 bool Device::SetIPFlag(IPAddress::Family family, const string& flag,
   1206                        const string& value) {
   1207   string ip_version;
   1208   if (family == IPAddress::kFamilyIPv4) {
   1209     ip_version = kIPFlagVersion4;
   1210   } else if (family == IPAddress::kFamilyIPv6) {
   1211     ip_version = kIPFlagVersion6;
   1212   } else {
   1213     NOTIMPLEMENTED();
   1214   }
   1215   FilePath flag_file(StringPrintf(kIPFlagTemplate, ip_version.c_str(),
   1216                                   link_name_.c_str(), flag.c_str()));
   1217   SLOG(this, 2) << "Writing " << value << " to flag file "
   1218                 << flag_file.value();
   1219   if (base::WriteFile(flag_file, value.c_str(), value.length()) != 1) {
   1220     string message = StringPrintf("IP flag write failed: %s to %s",
   1221                                   value.c_str(), flag_file.value().c_str());
   1222     if (!base::PathExists(flag_file) &&
   1223         ContainsValue(written_flags_, flag_file.value())) {
   1224       SLOG(this, 2) << message << " (device is no longer present?)";
   1225     } else {
   1226       LOG(ERROR) << message;
   1227     }
   1228     return false;
   1229   } else {
   1230     written_flags_.insert(flag_file.value());
   1231   }
   1232   return true;
   1233 }
   1234 
   1235 string Device::PerformTDLSOperation(const string& /* operation */,
   1236                                     const string& /* peer */,
   1237                                     Error* /* error */) {
   1238   return "";
   1239 }
   1240 
   1241 void Device::ResetByteCounters() {
   1242   manager_->device_info()->GetByteCounts(
   1243       interface_index_, &receive_byte_offset_, &transmit_byte_offset_);
   1244   manager_->UpdateDevice(this);
   1245 }
   1246 
   1247 bool Device::RestartPortalDetection() {
   1248   StopPortalDetection();
   1249   return StartPortalDetection();
   1250 }
   1251 
   1252 bool Device::RequestPortalDetection() {
   1253   if (!selected_service_) {
   1254     SLOG(this, 2) << FriendlyName()
   1255                   << ": No selected service, so no need for portal check.";
   1256     return false;
   1257   }
   1258 
   1259   if (!connection_.get()) {
   1260     SLOG(this, 2) << FriendlyName()
   1261                   << ": No connection, so no need for portal check.";
   1262     return false;
   1263   }
   1264 
   1265   if (selected_service_->state() != Service::kStatePortal) {
   1266     SLOG(this, 2) << FriendlyName()
   1267                   << ": Service is not in portal state.  "
   1268                   << "No need to start check.";
   1269     return false;
   1270   }
   1271 
   1272   if (!connection_->is_default()) {
   1273     SLOG(this, 2) << FriendlyName()
   1274                   << ": Service is not the default connection.  "
   1275                   << "Don't start check.";
   1276     return false;
   1277   }
   1278 
   1279   if (portal_detector_.get() && portal_detector_->IsInProgress()) {
   1280     SLOG(this, 2) << FriendlyName()
   1281                   << ": Portal detection is already running.";
   1282     return true;
   1283   }
   1284 
   1285   return StartPortalDetection();
   1286 }
   1287 
   1288 bool Device::StartPortalDetection() {
   1289   DCHECK(selected_service_);
   1290   if (selected_service_->IsPortalDetectionDisabled()) {
   1291     SLOG(this, 2) << "Service " << selected_service_->unique_name()
   1292                   << ": Portal detection is disabled; "
   1293                   << "marking service online.";
   1294     SetServiceConnectedState(Service::kStateOnline);
   1295     return false;
   1296   }
   1297 
   1298   if (selected_service_->IsPortalDetectionAuto() &&
   1299       !manager_->IsPortalDetectionEnabled(technology())) {
   1300     // If portal detection is disabled for this technology, immediately set
   1301     // the service state to "Online".
   1302     SLOG(this, 2) << "Device " << FriendlyName()
   1303                   << ": Portal detection is disabled; "
   1304                   << "marking service online.";
   1305     SetServiceConnectedState(Service::kStateOnline);
   1306     return false;
   1307   }
   1308 
   1309   if (selected_service_->HasProxyConfig()) {
   1310     // Services with HTTP proxy configurations should not be checked by the
   1311     // connection manager, since we don't have the ability to evaluate
   1312     // arbitrary proxy configs and their possible credentials.
   1313     SLOG(this, 2) << "Device " << FriendlyName()
   1314                   << ": Service has proxy config; marking it online.";
   1315     SetServiceConnectedState(Service::kStateOnline);
   1316     return false;
   1317   }
   1318 
   1319   portal_detector_.reset(new PortalDetector(connection_,
   1320                                             dispatcher_,
   1321                                             portal_detector_callback_));
   1322   if (!portal_detector_->Start(manager_->GetPortalCheckURL())) {
   1323     LOG(ERROR) << "Device " << FriendlyName()
   1324                << ": Portal detection failed to start: likely bad URL: "
   1325                << manager_->GetPortalCheckURL();
   1326     SetServiceConnectedState(Service::kStateOnline);
   1327     return false;
   1328   }
   1329 
   1330   SLOG(this, 2) << "Device " << FriendlyName()
   1331                 << ": Portal detection has started.";
   1332   return true;
   1333 }
   1334 
   1335 void Device::StopPortalDetection() {
   1336   SLOG(this, 2) << "Device " << FriendlyName()
   1337                 << ": Portal detection stopping.";
   1338   portal_detector_.reset();
   1339 }
   1340 
   1341 bool Device::StartConnectionDiagnosticsAfterPortalDetection(
   1342     const PortalDetector::Result& result) {
   1343   connection_diagnostics_.reset(new ConnectionDiagnostics(
   1344       connection_, dispatcher_, metrics_, manager_->device_info(),
   1345       connection_diagnostics_callback_));
   1346   if (!connection_diagnostics_->StartAfterPortalDetection(
   1347       manager_->GetPortalCheckURL(), result)) {
   1348     LOG(ERROR) << "Device " << FriendlyName()
   1349                << ": Connection diagnostics failed to start: likely bad URL: "
   1350                << manager_->GetPortalCheckURL();
   1351     connection_diagnostics_.reset();
   1352     return false;
   1353   }
   1354 
   1355   SLOG(this, 2) << "Device " << FriendlyName()
   1356                 << ": Connection diagnostics has started.";
   1357   return true;
   1358 }
   1359 
   1360 void Device::StopConnectionDiagnostics() {
   1361   SLOG(this, 2) << "Device " << FriendlyName()
   1362                 << ": Connection diagnostics stopping.";
   1363   connection_diagnostics_.reset();
   1364 }
   1365 
   1366 bool Device::StartConnectivityTest() {
   1367   LOG(INFO) << "Device " << FriendlyName() << " starting connectivity test.";
   1368 
   1369   connection_tester_.reset(new ConnectionTester(connection_,
   1370                                                 dispatcher_,
   1371                                                 connection_tester_callback_));
   1372   connection_tester_->Start();
   1373   return true;
   1374 }
   1375 
   1376 void Device::StopConnectivityTest() {
   1377   SLOG(this, 2) << "Device " << FriendlyName()
   1378                 << ": Connectivity test stopping.";
   1379   connection_tester_.reset();
   1380 }
   1381 
   1382 void Device::set_link_monitor(LinkMonitor* link_monitor) {
   1383   link_monitor_.reset(link_monitor);
   1384 }
   1385 
   1386 bool Device::StartLinkMonitor() {
   1387   if (!manager_->IsTechnologyLinkMonitorEnabled(technology())) {
   1388     SLOG(this, 2) << "Device " << FriendlyName()
   1389                   << ": Link Monitoring is disabled.";
   1390     return false;
   1391   }
   1392 
   1393   if (selected_service_ && selected_service_->link_monitor_disabled()) {
   1394     SLOG(this, 2) << "Device " << FriendlyName()
   1395                   << ": Link Monitoring is disabled for the selected service";
   1396     return false;
   1397   }
   1398 
   1399   if (!link_monitor()) {
   1400     set_link_monitor(
   1401       new LinkMonitor(
   1402           connection_, dispatcher_, metrics(), manager_->device_info(),
   1403           Bind(&Device::OnLinkMonitorFailure, weak_ptr_factory_.GetWeakPtr()),
   1404           Bind(&Device::OnLinkMonitorGatewayChange,
   1405                weak_ptr_factory_.GetWeakPtr())));
   1406   }
   1407 
   1408   SLOG(this, 2) << "Device " << FriendlyName()
   1409                 << ": Link Monitor starting.";
   1410   return link_monitor_->Start();
   1411 }
   1412 
   1413 void Device::StopLinkMonitor() {
   1414   SLOG(this, 2) << "Device " << FriendlyName()
   1415                 << ": Link Monitor stopping.";
   1416   link_monitor_.reset();
   1417 }
   1418 
   1419 void Device::OnUnreliableLink() {
   1420   SLOG(this, 2) << "Device " << FriendlyName()
   1421                 << ": Link is unreliable.";
   1422   selected_service_->set_unreliable(true);
   1423   reliable_link_callback_.Cancel();
   1424   metrics_->NotifyUnreliableLinkSignalStrength(
   1425       technology_, selected_service_->strength());
   1426 }
   1427 
   1428 void Device::OnReliableLink() {
   1429   SLOG(this, 2) << "Device " << FriendlyName()
   1430                 << ": Link is reliable.";
   1431   selected_service_->set_unreliable(false);
   1432   // TODO(zqiu): report signal strength to UMA.
   1433 }
   1434 
   1435 void Device::OnLinkMonitorFailure() {
   1436   SLOG(this, 2) << "Device " << FriendlyName()
   1437                 << ": Link Monitor indicates failure.";
   1438   if (!selected_service_) {
   1439     return;
   1440   }
   1441 
   1442   time_t now;
   1443   time_->GetSecondsBoottime(&now);
   1444 
   1445   if (last_link_monitor_failed_time_ != 0 &&
   1446       now - last_link_monitor_failed_time_ < kLinkUnreliableThresholdSeconds) {
   1447     OnUnreliableLink();
   1448   }
   1449   last_link_monitor_failed_time_ = now;
   1450 }
   1451 
   1452 void Device::OnLinkMonitorGatewayChange() {
   1453   string gateway_mac = link_monitor()->gateway_mac_address().HexEncode();
   1454   int connection_id = manager_->CalcConnectionId(
   1455       ipconfig_->properties().gateway, gateway_mac);
   1456 
   1457   CHECK(selected_service_);
   1458   selected_service_->set_connection_id(connection_id);
   1459 
   1460   manager_->ReportServicesOnSameNetwork(connection_id);
   1461 }
   1462 
   1463 bool Device::StartDNSTest(
   1464     const vector<string>& dns_servers,
   1465     bool retry_until_success,
   1466     const Callback<void(const DNSServerTester::Status)>& callback) {
   1467   if (dns_server_tester_.get()) {
   1468     LOG(ERROR) << FriendlyName() << ": "
   1469                << "Failed to start DNS Test: current test still running";
   1470     return false;
   1471   }
   1472 
   1473   dns_server_tester_.reset(new DNSServerTester(connection_,
   1474                                                dispatcher_,
   1475                                                dns_servers,
   1476                                                retry_until_success,
   1477                                                callback));
   1478   dns_server_tester_->Start();
   1479   return true;
   1480 }
   1481 
   1482 void Device::StopDNSTest() {
   1483   dns_server_tester_.reset();
   1484 }
   1485 
   1486 void Device::FallbackDNSResultCallback(const DNSServerTester::Status status) {
   1487   StopDNSTest();
   1488   int result = Metrics::kFallbackDNSTestResultFailure;
   1489   if (status == DNSServerTester::kStatusSuccess) {
   1490     result = Metrics::kFallbackDNSTestResultSuccess;
   1491 
   1492     // Switch to fallback DNS server if service is configured to allow DNS
   1493     // fallback.
   1494     CHECK(selected_service_);
   1495     if (selected_service_->is_dns_auto_fallback_allowed()) {
   1496       LOG(INFO) << "Device " << FriendlyName()
   1497                 << ": Switching to fallback DNS servers.";
   1498       // Save the DNS servers from ipconfig.
   1499       config_dns_servers_ = ipconfig_->properties().dns_servers;
   1500       SwitchDNSServers(vector<string>(std::begin(kFallbackDnsServers),
   1501                                       std::end(kFallbackDnsServers)));
   1502       // Start DNS test for configured DNS servers.
   1503       StartDNSTest(config_dns_servers_,
   1504                    true,
   1505                    Bind(&Device::ConfigDNSResultCallback,
   1506                         weak_ptr_factory_.GetWeakPtr()));
   1507     }
   1508   }
   1509   metrics()->NotifyFallbackDNSTestResult(technology_, result);
   1510 }
   1511 
   1512 void Device::ConfigDNSResultCallback(const DNSServerTester::Status status) {
   1513   StopDNSTest();
   1514   // DNS test failed to start due to internal error.
   1515   if (status == DNSServerTester::kStatusFailure) {
   1516     return;
   1517   }
   1518 
   1519   // Switch back to the configured DNS servers.
   1520   LOG(INFO) << "Device " << FriendlyName()
   1521             << ": Switching back to configured DNS servers.";
   1522   SwitchDNSServers(config_dns_servers_);
   1523 }
   1524 
   1525 void Device::SwitchDNSServers(const vector<string>& dns_servers) {
   1526   CHECK(ipconfig_);
   1527   CHECK(connection_);
   1528   // Push new DNS servers setting to the IP config object.
   1529   ipconfig_->UpdateDNSServers(dns_servers);
   1530   // Push new DNS servers setting to the current connection, so the resolver
   1531   // will be updated to use the new DNS servers.
   1532   connection_->UpdateDNSServers(dns_servers);
   1533   // Allow the service to notify Chrome of ipconfig changes.
   1534   selected_service_->NotifyIPConfigChanges();
   1535   // Restart the portal detection with the new DNS setting.
   1536   RestartPortalDetection();
   1537 }
   1538 
   1539 void Device::set_traffic_monitor(TrafficMonitor* traffic_monitor) {
   1540   traffic_monitor_.reset(traffic_monitor);
   1541 }
   1542 
   1543 bool Device::TimeToNextDHCPLeaseRenewal(uint32_t* result) {
   1544   if (!ipconfig() && !ip6config()) {
   1545     return false;
   1546   }
   1547   uint32_t time_to_ipv4_lease_expiry = UINT32_MAX;
   1548   uint32_t time_to_ipv6_lease_expiry = UINT32_MAX;
   1549   if (ipconfig()) {
   1550     ipconfig()->TimeToLeaseExpiry(&time_to_ipv4_lease_expiry);
   1551   }
   1552   if (ip6config()) {
   1553     ip6config()->TimeToLeaseExpiry(&time_to_ipv6_lease_expiry);
   1554   }
   1555   *result = std::min(time_to_ipv4_lease_expiry, time_to_ipv6_lease_expiry);
   1556   return true;
   1557 }
   1558 
   1559 bool Device::IsTrafficMonitorEnabled() const {
   1560   return false;
   1561 }
   1562 
   1563 void Device::StartTrafficMonitor() {
   1564   // Return if traffic monitor is not enabled for this device.
   1565   if (!IsTrafficMonitorEnabled()) {
   1566     return;
   1567   }
   1568 
   1569   SLOG(this, 2) << "Device " << FriendlyName()
   1570                 << ": Traffic Monitor starting.";
   1571   if (!traffic_monitor_.get()) {
   1572     traffic_monitor_.reset(new TrafficMonitor(this, dispatcher_));
   1573     traffic_monitor_->set_network_problem_detected_callback(
   1574         Bind(&Device::OnEncounterNetworkProblem,
   1575              weak_ptr_factory_.GetWeakPtr()));
   1576   }
   1577   traffic_monitor_->Start();
   1578 }
   1579 
   1580 void Device::StopTrafficMonitor() {
   1581   // Return if traffic monitor is not enabled for this device.
   1582   if (!IsTrafficMonitorEnabled()) {
   1583     return;
   1584   }
   1585 
   1586   if (traffic_monitor_.get()) {
   1587     SLOG(this, 2) << "Device " << FriendlyName()
   1588                   << ": Traffic Monitor stopping.";
   1589     traffic_monitor_->Stop();
   1590   }
   1591   traffic_monitor_.reset();
   1592 }
   1593 
   1594 void Device::OnEncounterNetworkProblem(int reason) {
   1595   int metric_code;
   1596   switch (reason) {
   1597     case TrafficMonitor::kNetworkProblemCongestedTxQueue:
   1598       metric_code = Metrics::kNetworkProblemCongestedTCPTxQueue;
   1599       break;
   1600     case TrafficMonitor::kNetworkProblemDNSFailure:
   1601       metric_code = Metrics::kNetworkProblemDNSFailure;
   1602       break;
   1603     default:
   1604       LOG(ERROR) << "Invalid network problem code: " << reason;
   1605       return;
   1606   }
   1607 
   1608   metrics()->NotifyNetworkProblemDetected(technology_, metric_code);
   1609   // Stop the traffic monitor, only report the first network problem detected
   1610   // on the connection for now.
   1611   StopTrafficMonitor();
   1612 }
   1613 
   1614 void Device::SetServiceConnectedState(Service::ConnectState state) {
   1615   DCHECK(selected_service_.get());
   1616 
   1617   if (!selected_service_.get()) {
   1618     LOG(ERROR) << FriendlyName() << ": "
   1619                << "Portal detection completed but no selected service exists!";
   1620     return;
   1621   }
   1622 
   1623   if (!selected_service_->IsConnected()) {
   1624     LOG(ERROR) << FriendlyName() << ": "
   1625                << "Portal detection completed but selected service "
   1626                << selected_service_->unique_name()
   1627                << " is in non-connected state.";
   1628     return;
   1629   }
   1630 
   1631   if (state == Service::kStatePortal && connection_->is_default() &&
   1632       manager_->GetPortalCheckInterval() != 0) {
   1633     CHECK(portal_detector_.get());
   1634     if (!portal_detector_->StartAfterDelay(
   1635             manager_->GetPortalCheckURL(),
   1636             manager_->GetPortalCheckInterval())) {
   1637       LOG(ERROR) << "Device " << FriendlyName()
   1638                  << ": Portal detection failed to restart: likely bad URL: "
   1639                  << manager_->GetPortalCheckURL();
   1640       SetServiceState(Service::kStateOnline);
   1641       portal_detector_.reset();
   1642       return;
   1643     }
   1644     SLOG(this, 2) << "Device " << FriendlyName()
   1645                   << ": Portal detection retrying.";
   1646   } else {
   1647     SLOG(this, 2) << "Device " << FriendlyName()
   1648                   << ": Portal will not retry.";
   1649     portal_detector_.reset();
   1650   }
   1651 
   1652   SetServiceState(state);
   1653 }
   1654 
   1655 void Device::PortalDetectorCallback(const PortalDetector::Result& result) {
   1656   if (!result.final) {
   1657     SLOG(this, 2) << "Device " << FriendlyName()
   1658                   << ": Received non-final status: "
   1659                   << ConnectivityTrial::StatusToString(
   1660                       result.trial_result.status);
   1661     return;
   1662   }
   1663 
   1664   SLOG(this, 2) << "Device " << FriendlyName()
   1665                 << ": Received final status: "
   1666                 << ConnectivityTrial::StatusToString(
   1667                     result.trial_result.status);
   1668 
   1669   portal_attempts_to_online_ += result.num_attempts;
   1670 
   1671   int portal_status = Metrics::PortalDetectionResultToEnum(result);
   1672   metrics()->SendEnumToUMA(
   1673       metrics()->GetFullMetricName(Metrics::kMetricPortalResultSuffix,
   1674                                    technology()),
   1675       portal_status,
   1676       Metrics::kPortalResultMax);
   1677 
   1678   if (result.trial_result.status == ConnectivityTrial::kStatusSuccess) {
   1679     SetServiceConnectedState(Service::kStateOnline);
   1680 
   1681     metrics()->SendToUMA(
   1682         metrics()->GetFullMetricName(
   1683             Metrics::kMetricPortalAttemptsToOnlineSuffix, technology()),
   1684         portal_attempts_to_online_,
   1685         Metrics::kMetricPortalAttemptsToOnlineMin,
   1686         Metrics::kMetricPortalAttemptsToOnlineMax,
   1687         Metrics::kMetricPortalAttemptsToOnlineNumBuckets);
   1688   } else {
   1689     // Set failure phase and status.
   1690     if (selected_service_.get()) {
   1691       selected_service_->SetPortalDetectionFailure(
   1692           ConnectivityTrial::PhaseToString(result.trial_result.phase),
   1693           ConnectivityTrial::StatusToString(result.trial_result.status));
   1694     }
   1695     SetServiceConnectedState(Service::kStatePortal);
   1696 
   1697     metrics()->SendToUMA(
   1698         metrics()->GetFullMetricName(
   1699             Metrics::kMetricPortalAttemptsSuffix, technology()),
   1700         result.num_attempts,
   1701         Metrics::kMetricPortalAttemptsMin,
   1702         Metrics::kMetricPortalAttemptsMax,
   1703         Metrics::kMetricPortalAttemptsNumBuckets);
   1704 
   1705     StartConnectionDiagnosticsAfterPortalDetection(result);
   1706 
   1707     // TODO(zqiu): Only support fallback DNS server for IPv4 for now.
   1708     if (connection_->IsIPv6()) {
   1709       return;
   1710     }
   1711 
   1712     // Perform fallback DNS test if the portal failure is DNS related.
   1713     // The test will send a  DNS request to Google's DNS server to determine
   1714     // if the DNS failure is due to bad DNS server settings.
   1715     if ((portal_status == Metrics::kPortalResultDNSFailure) ||
   1716         (portal_status == Metrics::kPortalResultDNSTimeout)) {
   1717       StartDNSTest(vector<string>(std::begin(kFallbackDnsServers),
   1718                                   std::end(kFallbackDnsServers)),
   1719                    false,
   1720                    Bind(&Device::FallbackDNSResultCallback,
   1721                         weak_ptr_factory_.GetWeakPtr()));
   1722     }
   1723   }
   1724 }
   1725 
   1726 string Device::GetSelectedServiceRpcIdentifier(Error* /*error*/) {
   1727   if (!selected_service_) {
   1728     return "/";
   1729   }
   1730   return selected_service_->GetRpcIdentifier();
   1731 }
   1732 
   1733 vector<string> Device::AvailableIPConfigs(Error* /*error*/) {
   1734   vector<string> ipconfigs;
   1735   if (ipconfig_) {
   1736     ipconfigs.push_back(ipconfig_->GetRpcIdentifier());
   1737   }
   1738   if (ip6config_) {
   1739     ipconfigs.push_back(ip6config_->GetRpcIdentifier());
   1740   }
   1741   if (dhcpv6_config_) {
   1742     ipconfigs.push_back(dhcpv6_config_->GetRpcIdentifier());
   1743   }
   1744   return ipconfigs;
   1745 }
   1746 
   1747 uint64_t Device::GetLinkMonitorResponseTime(Error* error) {
   1748   if (!link_monitor_.get()) {
   1749     // It is not strictly an error that the link monitor does not
   1750     // exist, but returning an error here allows the GetProperties
   1751     // call in our Adaptor to omit this parameter.
   1752     error->Populate(Error::kNotFound, "Device is not running LinkMonitor");
   1753     return 0;
   1754   }
   1755   return link_monitor_->GetResponseTimeMilliseconds();
   1756 }
   1757 
   1758 uint64_t Device::GetReceiveByteCount() {
   1759   uint64_t rx_byte_count = 0, tx_byte_count = 0;
   1760   manager_->device_info()->GetByteCounts(
   1761       interface_index_, &rx_byte_count, &tx_byte_count);
   1762   return rx_byte_count - receive_byte_offset_;
   1763 }
   1764 
   1765 uint64_t Device::GetTransmitByteCount() {
   1766   uint64_t rx_byte_count = 0, tx_byte_count = 0;
   1767   manager_->device_info()->GetByteCounts(
   1768       interface_index_, &rx_byte_count, &tx_byte_count);
   1769   return tx_byte_count - transmit_byte_offset_;
   1770 }
   1771 
   1772 uint64_t Device::GetReceiveByteCountProperty(Error* /*error*/) {
   1773   return GetReceiveByteCount();
   1774 }
   1775 
   1776 uint64_t Device::GetTransmitByteCountProperty(Error* /*error*/) {
   1777   return GetTransmitByteCount();
   1778 }
   1779 
   1780 bool Device::IsUnderlyingDeviceEnabled() const {
   1781   return false;
   1782 }
   1783 
   1784 // callback
   1785 void Device::OnEnabledStateChanged(const ResultCallback& callback,
   1786                                    const Error& error) {
   1787   SLOG(this, 2) << __func__
   1788                 << " (target: " << enabled_pending_ << ","
   1789                 << " success: " << error.IsSuccess() << ")"
   1790                 << " on " << link_name_;
   1791   if (error.IsSuccess()) {
   1792     enabled_ = enabled_pending_;
   1793     manager_->UpdateEnabledTechnologies();
   1794     adaptor_->EmitBoolChanged(kPoweredProperty, enabled_);
   1795   }
   1796   enabled_pending_ = enabled_;
   1797   if (!callback.is_null())
   1798     callback.Run(error);
   1799 }
   1800 
   1801 void Device::SetEnabled(bool enable) {
   1802   SLOG(this, 2) << __func__ << "(" << enable << ")";
   1803   Error error;
   1804   SetEnabledChecked(enable, false, &error, ResultCallback());
   1805 
   1806   // SetEnabledInternal might fail here if there is an unfinished enable or
   1807   // disable operation. Don't log error in this case, as this method is only
   1808   // called when the underlying device is already in the target state and the
   1809   // pending operation should eventually bring the device to the expected
   1810   // state.
   1811   LOG_IF(ERROR,
   1812          error.IsFailure() &&
   1813          !error.IsOngoing() &&
   1814          error.type() != Error::kInProgress)
   1815       << "Enabled failed, but no way to report the failure.";
   1816 }
   1817 
   1818 void Device::SetEnabledNonPersistent(bool enable,
   1819                                      Error* error,
   1820                                      const ResultCallback& callback) {
   1821   SetEnabledChecked(enable, false, error, callback);
   1822 }
   1823 
   1824 void Device::SetEnabledPersistent(bool enable,
   1825                                   Error* error,
   1826                                   const ResultCallback& callback) {
   1827   SetEnabledChecked(enable, true, error, callback);
   1828 }
   1829 
   1830 void Device::SetEnabledChecked(bool enable,
   1831                                bool persist,
   1832                                Error* error,
   1833                                const ResultCallback& callback) {
   1834   DCHECK(error);
   1835   SLOG(this, 2) << "Device " << link_name_ << " "
   1836                 << (enable ? "starting" : "stopping");
   1837   if (enable && manager_->IsTechnologyProhibited(technology())) {
   1838     error->Populate(Error::kPermissionDenied, "The " +
   1839                     Technology::NameFromIdentifier(technology()) +
   1840                     " technology is prohibited");
   1841     return;
   1842   }
   1843 
   1844   if (enable == enabled_) {
   1845     if (enable != enabled_pending_ && persist) {
   1846       // Return an error, as there is an ongoing operation to achieve the
   1847       // opposite.
   1848       Error::PopulateAndLog(
   1849           FROM_HERE, error, Error::kOperationFailed,
   1850           enable ? "Cannot enable while the device is disabling." :
   1851                    "Cannot disable while the device is enabling.");
   1852       return;
   1853     }
   1854     LOG(INFO) << "Already in desired enable state.";
   1855     error->Reset();
   1856     return;
   1857   }
   1858 
   1859   if (enabled_pending_ == enable) {
   1860     Error::PopulateAndLog(FROM_HERE, error, Error::kInProgress,
   1861                           "Enable operation already in progress");
   1862     return;
   1863   }
   1864 
   1865   if (persist) {
   1866     enabled_persistent_ = enable;
   1867     manager_->UpdateDevice(this);
   1868   }
   1869 
   1870   SetEnabledUnchecked(enable, error, callback);
   1871 }
   1872 
   1873 void Device::SetEnabledUnchecked(bool enable, Error* error,
   1874                                  const ResultCallback& on_enable_complete) {
   1875   enabled_pending_ = enable;
   1876   EnabledStateChangedCallback chained_callback =
   1877       Bind(&Device::OnEnabledStateChanged,
   1878            weak_ptr_factory_.GetWeakPtr(), on_enable_complete);
   1879   if (enable) {
   1880     running_ = true;
   1881     Start(error, chained_callback);
   1882   } else {
   1883     running_ = false;
   1884     DestroyIPConfig();         // breaks a reference cycle
   1885     SelectService(nullptr);    // breaks a reference cycle
   1886     rtnl_handler_->SetInterfaceFlags(interface_index(), 0, IFF_UP);
   1887     SLOG(this, 3) << "Device " << link_name_ << " ipconfig_ "
   1888                   << (ipconfig_ ? "is set." : "is not set.");
   1889     SLOG(this, 3) << "Device " << link_name_ << " ip6config_ "
   1890                   << (ip6config_ ? "is set." : "is not set.");
   1891     SLOG(this, 3) << "Device " << link_name_ << " connection_ "
   1892                   << (connection_ ? "is set." : "is not set.");
   1893     SLOG(this, 3) << "Device " << link_name_ << " selected_service_ "
   1894                   << (selected_service_ ? "is set." : "is not set.");
   1895     Stop(error, chained_callback);
   1896   }
   1897 }
   1898 
   1899 void Device::UpdateIPConfigsProperty() {
   1900   adaptor_->EmitRpcIdentifierArrayChanged(
   1901       kIPConfigsProperty, AvailableIPConfigs(nullptr));
   1902 }
   1903 
   1904 bool Device::ResolvePeerMacAddress(const string& input,
   1905                                    string* output,
   1906                                    Error* error) {
   1907   if (!MakeHardwareAddressFromString(input).empty()) {
   1908     // Input is already a MAC address.
   1909     *output = input;
   1910     return true;
   1911   }
   1912 
   1913   IPAddress ip_address(IPAddress::kFamilyIPv4);
   1914   if (!ip_address.SetAddressFromString(input)) {
   1915     Error::PopulateAndLog(FROM_HERE, error, Error::kInvalidArguments,
   1916                           "Peer is neither an IP Address nor a MAC address");
   1917     return false;
   1918   }
   1919 
   1920   // Peer address was specified as an IP address which we need to resolve.
   1921   const DeviceInfo* device_info = manager()->device_info();
   1922   if (!device_info->HasDirectConnectivityTo(interface_index_, ip_address)) {
   1923     Error::PopulateAndLog(FROM_HERE, error, Error::kInvalidArguments,
   1924                           "IP address is not local to this interface");
   1925     return false;
   1926   }
   1927 
   1928   ByteString mac_address;
   1929   if (device_info->GetMACAddressOfPeer(interface_index_,
   1930                                        ip_address,
   1931                                        &mac_address)) {
   1932     *output = MakeStringFromHardwareAddress(
   1933         vector<uint8_t>(mac_address.GetConstData(),
   1934                         mac_address.GetConstData() +
   1935                         mac_address.GetLength()));
   1936     SLOG(this, 2) << "ARP cache lookup returned peer: " << *output;
   1937     return true;
   1938   }
   1939 
   1940   if (!Icmp().TransmitEchoRequest(ip_address, 1, 1)) {
   1941     Error::PopulateAndLog(FROM_HERE, error, Error::kOperationFailed,
   1942                           "Failed to send ICMP request to peer to setup ARP");
   1943   } else {
   1944     // ARP request was transmitted successfully, address resolution is still
   1945     // pending.
   1946     error->Populate(Error::kInProgress,
   1947                     "Peer MAC address was not found in the ARP cache, "
   1948                     "but an ARP request was sent to find it.  "
   1949                     "Please try again.");
   1950   }
   1951   return false;
   1952 }
   1953 
   1954 // static
   1955 vector<uint8_t> Device::MakeHardwareAddressFromString(
   1956     const string& address_string) {
   1957   string address_nosep;
   1958   base::RemoveChars(address_string, ":", &address_nosep);
   1959   vector<uint8_t> address_bytes;
   1960   base::HexStringToBytes(address_nosep, &address_bytes);
   1961   if (address_bytes.size() != kHardwareAddressLength) {
   1962     return vector<uint8_t>();
   1963   }
   1964   return address_bytes;
   1965 }
   1966 
   1967 // static
   1968 string Device::MakeStringFromHardwareAddress(
   1969     const vector<uint8_t>& address_bytes) {
   1970   CHECK_EQ(kHardwareAddressLength, address_bytes.size());
   1971   return StringPrintf("%02x:%02x:%02x:%02x:%02x:%02x",
   1972                       address_bytes[0], address_bytes[1], address_bytes[2],
   1973                       address_bytes[3], address_bytes[4], address_bytes[5]);
   1974 }
   1975 
   1976 bool Device::RequestRoam(const std::string& addr, Error* error) {
   1977   return false;
   1978 }
   1979 
   1980 }  // namespace shill
   1981