// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SHILL_DEVICE_H_
#define SHILL_DEVICE_H_

#include <memory>
#include <set>
#include <string>
#include <vector>

#include <base/macros.h>
#include <base/memory/ref_counted.h>
#include <base/memory/weak_ptr.h>
#include <gtest/gtest_prod.h>  // for FRIEND_TEST

#include "shill/adaptor_interfaces.h"
#include "shill/callbacks.h"
#include "shill/connection_diagnostics.h"
#include "shill/dns_server_tester.h"
#include "shill/event_dispatcher.h"
#include "shill/geolocation_info.h"
#include "shill/ipconfig.h"
#include "shill/net/ip_address.h"
#include "shill/net/shill_time.h"
#include "shill/portal_detector.h"
#include "shill/property_store.h"
#include "shill/refptr_types.h"
#include "shill/routing_table.h"
#include "shill/service.h"
#include "shill/technology.h"

namespace shill {

class ControlInterface;
class DHCPProvider;
class DeviceAdaptorInterface;
class Error;
class EventDispatcher;
class LinkMonitor;
class Manager;
class Metrics;
class RTNLHandler;
class TrafficMonitor;

// Device superclass.  Individual network interfaces types will inherit from
// this class.
class Device : public base::RefCounted<Device> {
 public:
  // A constructor for the Device object
  Device(ControlInterface* control_interface,
         EventDispatcher* dispatcher,
         Metrics* metrics,
         Manager* manager,
         const std::string& link_name,
         const std::string& address,
         int interface_index,
         Technology::Identifier technology);

  // Initialize type-specific network interface properties.
  virtual void Initialize();

  // Enable or disable the device. This is a convenience method for
  // cases where we want to SetEnabledNonPersistent, but don't care
  // about the results.
  virtual void SetEnabled(bool enable);
  // Enable or disable the device. Unlike SetEnabledPersistent, it does not
  // save the setting in the profile.
  //
  // TODO(quiche): Replace both of the next two methods with calls to
  // SetEnabledChecked.
  virtual void SetEnabledNonPersistent(bool enable,
                                       Error* error,
                                       const ResultCallback& callback);
  // Enable or disable the device, and save the setting in the profile.
  // The setting is persisted before the enable or disable operation
  // starts, so that even if it fails, the user's intent is still recorded
  // for the next time shill restarts.
  virtual void SetEnabledPersistent(bool enable,
                                    Error* error,
                                    const ResultCallback& callback);
  // Enable or disable the Device, depending on |enable|.
  // Save the new setting to the profile, if |persist| is true.
  // Report synchronous errors using |error|, and asynchronous completion
  // with |callback|.
  virtual void SetEnabledChecked(bool enable,
                                 bool persist,
                                 Error* error,
                                 const ResultCallback& callback);
  // Similar to SetEnabledChecked, but without sanity checking, and
  // without saving the new value of |enable| to the profile. If you
  // are sane (i.e. not Cellular), you should use
  // SetEnabledChecked instead.
  virtual void SetEnabledUnchecked(bool enable,
                                   Error* error,
                                   const ResultCallback& callback);

  // Returns true if the underlying device reports that it is already enabled.
  // Used when the device is registered with the Manager, so that shill can
  // sync its state/ with the true state of the device. The default is to
  // report false.
  virtual bool IsUnderlyingDeviceEnabled() const;

  virtual void LinkEvent(unsigned flags, unsigned change);

  // The default implementation sets |error| to kNotSupported.
  virtual void Scan(Error* error, const std::string& reason);
  // The default implementation sets |error| to kNotSupported.
  virtual void SetSchedScan(bool enable, Error* error);
  virtual void RegisterOnNetwork(const std::string& network_id, Error* error,
                                 const ResultCallback& callback);
  virtual void RequirePIN(const std::string& pin, bool require,
                          Error* error, const ResultCallback& callback);
  virtual void EnterPIN(const std::string& pin,
                        Error* error, const ResultCallback& callback);
  virtual void UnblockPIN(const std::string& unblock_code,
                          const std::string& pin,
                          Error* error, const ResultCallback& callback);
  virtual void ChangePIN(const std::string& old_pin,
                         const std::string& new_pin,
                         Error* error, const ResultCallback& callback);
  virtual void Reset(Error* error, const ResultCallback& callback);

  virtual void SetCarrier(const std::string& carrier,
                          Error* error, const ResultCallback& callback);

  // Returns true if IPv6 is allowed and should be enabled when the device
  // tries to acquire an IP configuration. The default implementation allows
  // IPv6, which can be overridden by a derived class.
  virtual bool IsIPv6Allowed() const;

  virtual void DisableIPv6();
  virtual void EnableIPv6();
  virtual void EnableIPv6Privacy();

  // Returns true if the selected service on the device (if any) is connected.
  // Returns false if there is no selected service, or if the selected service
  // is not connected.
  bool IsConnected() const;

  // Called by Device so that subclasses can run hooks on the selected service
  // getting an IP.  Subclasses should call up to the parent first.
  virtual void OnConnected();

  // Called by the Connection so that the Device can update the service sorting
  // after one connection is bound to another.
  virtual void OnConnectionUpdated();

  // Returns true if the selected service on the device (if any) is connected
  // and matches the passed-in argument |service|.  Returns false if there is
  // no connected service, or if it does not match |service|.
  virtual bool IsConnectedToService(const ServiceRefPtr& service) const;

  // Returns true if the DHCP parameters provided indicate that we are tethered
  // to a mobile device.
  virtual bool IsConnectedViaTether() const;

  // Restart the portal detection process on a connected device.  This is
  // useful if the properties on the connected service have changed in a
  // way that may affect the decision to run portal detection at all.
  // Returns true if portal detection was started.
  virtual bool RestartPortalDetection();

  // Called by the manager to start a single connectivity test.  This is used to
  // log connection state triggered by a user feedback log request.
  virtual bool StartConnectivityTest();

  // Get receive and transmit byte counters.
  virtual uint64_t GetReceiveByteCount();
  virtual uint64_t GetTransmitByteCount();

  // Perform a TDLS |operation| on the underlying device, with respect
  // to a given |peer|.  The string returned is empty for any operation
  // other than kTDLSOperationStatus, which returns the state of the
  // TDLS link with |peer|.  This method is only valid for WiFi devices,
  // but needs to be declared here since it is part of the Device RPC
  // API.
  virtual std::string PerformTDLSOperation(const std::string& operation,
                                           const std::string& peer,
                                           Error* error);

  // Reset the persisted byte counters associated with the device.
  void ResetByteCounters();

  // Requests that portal detection be done, if this device has the default
  // connection.  Returns true if portal detection was started.
  virtual bool RequestPortalDetection();

  std::string GetRpcIdentifier() const;
  virtual std::string GetStorageIdentifier() const;

  // Returns a list of Geolocation objects. Each object is multiple
  // key-value pairs representing one entity that can be used for
  // Geolocation.
  virtual std::vector<GeolocationInfo> GetGeolocationObjects() const;

  // Enable or disable this interface to receive packets even if it is not
  // the default connection.  This is useful in limited situations such as
  // during portal detection.
  virtual void SetLooseRouting(bool is_loose_routing);

  // Blackhole outgoing traffic using the specified source address for a certain
  // amount of time.
  virtual void BlackholeAddress(IPAddress address, base::TimeDelta lifetime);

  // Enable or disable same-net multi-home support for this interface.  When
  // enabled, ARP filtering is enabled in order to avoid the "ARP Flux"
  // effect where peers may end up with inaccurate IP address mappings due to
  // the default Linux ARP transmit / reply behavior.  See
  // http://linux-ip.net/html/ether-arp.html for more details on this effect.
  virtual void SetIsMultiHomed(bool is_multi_homed);

  // Used for devices that are managed by an entity other than shill.
  // If true, shill will not attempt to change the device's IP
  // address, subnet mask, broadcast address, or manipulate the interface
  // state.  This setting is disabled by default.
  virtual void SetFixedIpParams(bool fixed_ip_params);

  const std::string& address() const { return hardware_address_; }
  const std::string& link_name() const { return link_name_; }
  int interface_index() const { return interface_index_; }
  virtual const ConnectionRefPtr& connection() const { return connection_; }
  bool enabled() const { return enabled_; }
  bool enabled_persistent() const { return enabled_persistent_; }
  virtual Technology::Identifier technology() const { return technology_; }
  std::string GetTechnologyString(Error* error);

  virtual const IPConfigRefPtr& ipconfig() const { return ipconfig_; }
  virtual const IPConfigRefPtr& ip6config() const { return ip6config_; }
  virtual const IPConfigRefPtr& dhcpv6_config() const { return dhcpv6_config_; }
  void set_ipconfig(const IPConfigRefPtr& config) { ipconfig_ = config; }

  // Returns a string that is guaranteed to uniquely identify this Device
  // instance.
  const std::string& UniqueName() const;

  PropertyStore* mutable_store() { return &store_; }
  const PropertyStore& store() const { return store_; }
  RTNLHandler* rtnl_handler() { return rtnl_handler_; }
  bool running() const { return running_; }

  EventDispatcher* dispatcher() const { return dispatcher_; }

  // Load configuration for the device from |storage|.  This may include
  // instantiating non-visible services for which configuration has been
  // stored.
  virtual bool Load(StoreInterface* storage);

  // Save configuration for the device to |storage|.
  virtual bool Save(StoreInterface* storage);

  void set_dhcp_provider(DHCPProvider* provider) { dhcp_provider_ = provider; }

  DeviceAdaptorInterface* adaptor() const { return adaptor_.get(); }

  // Suspend event handler. Called by Manager before the system
  // suspends. This handler, along with any other suspend handlers,
  // will have Manager::kTerminationActionsTimeoutMilliseconds to
  // execute before the system enters the suspend state. |callback|
  // must be invoked after all synchronous and/or asynchronous actions
  // this function performs complete. Code that needs to run on exit should use
  // Manager::AddTerminationAction, rather than OnBeforeSuspend.
  //
  // The default implementation invokes the |callback| immediately, since
  // there is nothing to be done in the general case.
  virtual void OnBeforeSuspend(const ResultCallback& callback);

  // Resume event handler. Called by Manager as the system resumes.
  // The base class implementation takes care of renewing a DHCP lease
  // (if necessary). Derived classes may implement any technology
  // specific requirements by overriding, but should include a call to
  // the base class implementation.
  virtual void OnAfterResume();

  // This method is invoked when the system resumes from suspend temporarily in
  // the "dark resume" state. The system will reenter suspend in
  // Manager::kTerminationActionsTimeoutMilliseconds. |callback| must be invoked
  // after all synchronous and/or asynchronous actions this function performs
  // and/or posts complete.
  //
  // The default implementation invokes the |callback| immediately, since
  // there is nothing to be done in the general case.
  virtual void OnDarkResume(const ResultCallback& callback);

  // Destroy the lease, if any, with this |name|.
  // Called by the service during Unload() as part of the cleanup sequence.
  virtual void DestroyIPConfigLease(const std::string& name);

  // Called by DeviceInfo when the kernel adds or removes a globally-scoped
  // IPv6 address from this interface.
  virtual void OnIPv6AddressChanged();

  // Called by DeviceInfo when the kernel receives a update for IPv6 DNS server
  // addresses from this interface.
  virtual void OnIPv6DnsServerAddressesChanged();

  // Called when link becomes unreliable (multiple link monitor failures
  // detected in short period of time).
  virtual void OnUnreliableLink();

  // Called when link becomes reliable (no link failures in a predefined period
  // of time).
  virtual void OnReliableLink();

  // Program a rule into the NIC to wake the system from suspend upon receiving
  // packets from |ip_endpoint|. |error| indicates the result of the
  // operation.
  virtual void AddWakeOnPacketConnection(const std::string& ip_endpoint,
                                         Error* error);
  // Programs the NIC to wake on every packet of IP protocol type belonging to
  // |packet_types|. |error| indicates the result of the operation.
  virtual void AddWakeOnPacketOfTypes(
      const std::vector<std::string>& packet_types, Error* error);
  // Removes a rule previously programmed into the NIC to wake the system from
  // suspend upon receiving packets from |ip_endpoint|. |error| indicates the
  // result of the operation.
  virtual void RemoveWakeOnPacketConnection(const std::string& ip_endpoint,
                                            Error* error);
  // Removes a rule previously programmed  to wake on every packet of IP
  // protocol type belonging to |packet_types|.
  // |error| indicates the result of the operation.
  virtual void RemoveWakeOnPacketOfTypes(
      const std::vector<std::string>& packet_types, Error* error);
  // Removes all wake-on-packet rules programmed into the NIC. |error| indicates
  // the result of the operation.
  virtual void RemoveAllWakeOnPacketConnections(Error* error);

  // Initiate renewal of existing DHCP lease.
  void RenewDHCPLease();

  // Resolve the |input| string into a MAC address for a peer local to this
  // device. This could be a trivial operation if the |input| is already a MAC
  // address, or could involve an ARP table lookup.  Returns true and populates
  // |output| if the resolution completes, otherwise returns false and
  // populates |error|.
  virtual bool ResolvePeerMacAddress(const std::string& input,
                                     std::string* output,
                                     Error* error);

  // Creates a byte vector from a colon-separated hardware address string.
  static std::vector<uint8_t> MakeHardwareAddressFromString(
      const std::string& address_string);

  // Creates a colon-separated hardware address string from a byte vector.
  static std::string MakeStringFromHardwareAddress(
      const std::vector<uint8_t>& address_data);

  // Request the WiFi device to roam to AP with |addr|.
  // This call will send Roam command to wpa_supplicant.
  virtual bool RequestRoam(const std::string& addr, Error* error);

  const ServiceRefPtr& selected_service() const { return selected_service_; }

  // Drops the current connection and the selected service, if any.  Does not
  // change the state of the previously selected service.
  virtual void ResetConnection();

  // If the status of browser traffic blackholing changed, this will restart
  // the active connection with the right setting.
  virtual void RefreshIPConfig();

 protected:
  friend class base::RefCounted<Device>;
  friend class DeviceHealthCheckerTest;
  FRIEND_TEST(CellularServiceTest, IsAutoConnectable);
  FRIEND_TEST(CellularTest, ModemStateChangeDisable);
  FRIEND_TEST(CellularTest, UseNoArpGateway);
  FRIEND_TEST(DevicePortalDetectionTest, PortalIntervalIsZero);
  FRIEND_TEST(DevicePortalDetectionTest, RequestStartConnectivityTest);
  FRIEND_TEST(DevicePortalDetectionTest, RestartPortalDetection);
  FRIEND_TEST(DeviceTest, AcquireIPConfigWithoutSelectedService);
  FRIEND_TEST(DeviceTest, AcquireIPConfigWithSelectedService);
  FRIEND_TEST(DeviceTest, AvailableIPConfigs);
  FRIEND_TEST(DeviceTest, DestroyIPConfig);
  FRIEND_TEST(DeviceTest, DestroyIPConfigNULL);
  FRIEND_TEST(DeviceTest, ConfigWithMinimumMTU);
  FRIEND_TEST(DeviceTest, EnableIPv6);
  FRIEND_TEST(DeviceTest, GetProperties);
  FRIEND_TEST(DeviceTest, IPConfigUpdatedFailureWithIPv6Config);
  FRIEND_TEST(DeviceTest, IPConfigUpdatedFailureWithIPv6Connection);
  FRIEND_TEST(DeviceTest, IsConnectedViaTether);
  FRIEND_TEST(DeviceTest, LinkMonitorFailure);
  FRIEND_TEST(DeviceTest, Load);
  FRIEND_TEST(DeviceTest, OnDHCPv6ConfigExpired);
  FRIEND_TEST(DeviceTest, OnDHCPv6ConfigFailed);
  FRIEND_TEST(DeviceTest, OnDHCPv6ConfigUpdated);
  FRIEND_TEST(DeviceTest, OnIPv6AddressChanged);
  FRIEND_TEST(DeviceTest, OnIPv6ConfigurationCompleted);
  FRIEND_TEST(DeviceTest, OnIPv6DnsServerAddressesChanged);
  FRIEND_TEST(DeviceTest,
              OnIPv6DnsServerAddressesChanged_LeaseExpirationUpdated);
  FRIEND_TEST(DeviceTest, PrependIPv4DNSServers);
  FRIEND_TEST(DeviceTest, PrependIPv6DNSServers);
  FRIEND_TEST(DeviceTest, ResetConnection);
  FRIEND_TEST(DeviceTest, Save);
  FRIEND_TEST(DeviceTest, SelectedService);
  FRIEND_TEST(DeviceTest, SetEnabledNonPersistent);
  FRIEND_TEST(DeviceTest, SetEnabledPersistent);
  FRIEND_TEST(DeviceTest, ShouldUseArpGateway);
  FRIEND_TEST(DeviceTest, Start);
  FRIEND_TEST(DeviceTest, Stop);
  FRIEND_TEST(DeviceTest, StopWithFixedIpParams);
  FRIEND_TEST(DeviceTest, StopWithNetworkInterfaceDisabledAfterward);
  FRIEND_TEST(ManagerTest, ConnectedTechnologies);
  FRIEND_TEST(ManagerTest, DefaultTechnology);
  FRIEND_TEST(ManagerTest, DeviceRegistrationAndStart);
  FRIEND_TEST(ManagerTest, GetEnabledDeviceWithTechnology);
  FRIEND_TEST(ManagerTest, SetEnabledStateForTechnology);
  FRIEND_TEST(ManagerTest, GetEnabledDeviceByLinkName);
  FRIEND_TEST(WiFiMainTest, UseArpGateway);
  FRIEND_TEST(WiMaxTest, ConnectTimeout);
  FRIEND_TEST(WiMaxTest, UseNoArpGateway);

  virtual ~Device();

  // Each device must implement this method to do the work needed to
  // enable the device to operate for establishing network connections.
  // The |error| argument, if not nullptr,
  // will refer to an Error that starts out with the value
  // Error::kOperationInitiated. This reflects the assumption that
  // enable (and disable) operations will usually be non-blocking,
  // and their completion will be indicated by means of an asynchronous
  // reply sometime later. There are two circumstances in which a
  // device's Start() method may overwrite |error|:
  //
  // 1. If an early failure is detected, such that the non-blocking
  //    part of the operation never takes place, then |error| should
  //    be set to the appropriate value corresponding to the type
  //    of failure. This is the "immediate failure" case.
  // 2. If the device is enabled without performing any non-blocking
  //    steps, then |error| should be Reset, i.e., its value set
  //    to Error::kSuccess. This is the "immediate success" case.
  //
  // In these two cases, because completion is immediate, |callback|
  // is not used. If neither of these two conditions holds, then |error|
  // should not be modified, and |callback| should be passed to the
  // method that will initiate the non-blocking operation.
  virtual void Start(Error* error,
                     const EnabledStateChangedCallback& callback) = 0;

  // Each device must implement this method to do the work needed to
  // disable the device, i.e., clear any running state, and make the
  // device no longer capable of establishing network connections.
  // The discussion for Start() regarding the use of |error| and
  // |callback| apply to Stop() as well.
  virtual void Stop(Error* error,
                    const EnabledStateChangedCallback& callback) = 0;

  // Returns true if the associated network interface should be brought down
  // after the device is disabled, or false if that should be done before the
  // device is disabled.
  virtual bool ShouldBringNetworkInterfaceDownAfterDisabled() const;

  // The EnabledStateChangedCallback that gets passed to the device's
  // Start() and Stop() methods is bound to this method. |callback|
  // is the callback that was passed to SetEnabled().
  void OnEnabledStateChanged(const ResultCallback& callback,
                             const Error& error);

  // Drops the currently selected service along with its IP configuration and
  // connection, if any.
  virtual void DropConnection();

  // If there's an IP configuration in |ipconfig_|, releases the IP address and
  // destroys the configuration instance.
  void DestroyIPConfig();

  // Creates a new DHCP IP configuration instance, stores it in |ipconfig_| and
  // requests a new IP configuration.  Saves the DHCP lease to the generic
  // lease filename based on the interface name.  Registers a callback to
  // IPConfigUpdatedCallback on IP configuration changes. Returns true if the IP
  // request was successfully sent.
  bool AcquireIPConfig();

  // Creates a new DHCP IP configuration instance, stores it in |ipconfig_| and
  // requests a new IP configuration.  Saves the DHCP lease to a filename
  // based on the passed-in |lease_name|.  Registers a callback to
  // IPConfigUpdatedCallback on IP configuration changes. Returns true if the IP
  // request was successfully sent.
  bool AcquireIPConfigWithLeaseName(const std::string& lease_name);

#ifndef DISABLE_DHCPV6
  // Creates a new DHCPv6 configuration instances, stores it in
  // |dhcpv6_config_| and requests a new configuration.  Saves the DHCPv6
  // lease to a filename based on the passed-in |lease_name|.
  // The acquired configurations will not be used to setup a connection
  // for the device.
  bool AcquireIPv6ConfigWithLeaseName(const std::string& lease_name);
#endif

  // Assigns the IP configuration |properties| to |ipconfig_|.
  void AssignIPConfig(const IPConfig::Properties& properties);

  // Callback invoked on successful IP configuration updates.
  virtual void OnIPConfigUpdated(const IPConfigRefPtr& ipconfig,
                                 bool new_lease_acquired);

  // Called when IPv6 configuration changes.
  virtual void OnIPv6ConfigUpdated();

  // Callback invoked on IP configuration failures.
  void OnIPConfigFailed(const IPConfigRefPtr& ipconfig);

  // Callback invoked when "Refresh" is invoked on an IPConfig.  This usually
  // signals a change in static IP parameters.
  void OnIPConfigRefreshed(const IPConfigRefPtr& ipconfig);

  // Callback invoked when an IPConfig restarts due to lease expiry.  This
  // is advisory, since an "Updated" or "Failed" signal is guaranteed to
  // follow.
  void OnIPConfigExpired(const IPConfigRefPtr& ipconfig);

  // Called by Device so that subclasses can run hooks on the selected service
  // failing to get an IP.  The default implementation disconnects the selected
  // service with Service::kFailureDHCP.
  virtual void OnIPConfigFailure();

  // Callback invoked on successful DHCPv6 configuration updates.
  void OnDHCPv6ConfigUpdated(const IPConfigRefPtr& ipconfig,
                             bool new_lease_acquired);

  // Callback invoked on DHCPv6 configuration failures.
  void OnDHCPv6ConfigFailed(const IPConfigRefPtr& ipconfig);

  // Callback invoked when an DHCPv6Config restarts due to lease expiry.  This
  // is advisory, since an "Updated" or "Failed" signal is guaranteed to
  // follow.
  void OnDHCPv6ConfigExpired(const IPConfigRefPtr& ipconfig);

  // Maintain connection state (Routes, IP Addresses and DNS) in the OS.
  void CreateConnection();

  // Remove connection state
  void DestroyConnection();

  // Selects a service to be "current" -- i.e. link-state or configuration
  // events that happen to the device are attributed to this service.
  void SelectService(const ServiceRefPtr& service);

  // Set the state of the |selected_service_|.
  virtual void SetServiceState(Service::ConnectState state);

  // Set the failure of the selected service (implicitly sets the state to
  // "failure").
  virtual void SetServiceFailure(Service::ConnectFailure failure_state);

  // Records the failure mode and time of the selected service, and
  // sets the Service state of the selected service to "Idle".
  // Avoids showing a failure mole in the UI.
  virtual void SetServiceFailureSilent(Service::ConnectFailure failure_state);

  // Called by the Portal Detector whenever a trial completes.  Device
  // subclasses that choose unique mappings from portal results to connected
  // states can override this method in order to do so.
  virtual void PortalDetectorCallback(const PortalDetector::Result& result);

  // Initiate portal detection, if enabled for this device type.
  bool StartPortalDetection();

  // Stop portal detection if it is running.
  void StopPortalDetection();

  // Initiate connection diagnostics with the |result| from a completed portal
  // detection attempt.
  virtual bool StartConnectionDiagnosticsAfterPortalDetection(
      const PortalDetector::Result& result);

  // Stop connection diagnostics if it is running.
  void StopConnectionDiagnostics();

  // Stop connectivity tester if it exists.
  void StopConnectivityTest();

  // Initiate link monitoring, if enabled for this device type.
  bool StartLinkMonitor();

  // Stop link monitoring if it is running.
  void StopLinkMonitor();

  // Respond to a LinkMonitor failure in a Device-specific manner.
  virtual void OnLinkMonitorFailure();

  // Respond to a LinkMonitor gateway's MAC address found/change event.
  virtual void OnLinkMonitorGatewayChange();

  // Returns true if traffic monitor is enabled on this device. The default
  // implementation will return false, which can be overridden by a derived
  // class.
  virtual bool IsTrafficMonitorEnabled() const;

  // Initiates traffic monitoring on the device if traffic monitor is enabled.
  void StartTrafficMonitor();

  // Stops traffic monitoring on the device if traffic monitor is enabled.
  void StopTrafficMonitor();

  // Start DNS test for the given servers. When retry_until_success is set,
  // callback will only be invoke when the test succeed or the test failed to
  // start (internal error). This function will return false if there is a test
  // that's already running, and true otherwise.
  virtual bool StartDNSTest(
      const std::vector<std::string>& dns_servers,
      const bool retry_until_success,
      const base::Callback<void(const DnsServerTester::Status)>& callback);
  // Stop DNS test if one is running.
  virtual void StopDNSTest();

  // Timer function for monitoring IPv6 DNS server's lifetime.
  void StartIPv6DNSServerTimer(uint32_t lifetime_seconds);
  void StopIPv6DNSServerTimer();

  // Stop all monitoring/testing activities on this device. Called when tearing
  // down or changing network connection on the device.
  void StopAllActivities();

  // Called by the Traffic Monitor when it detects a network problem. Device
  // subclasses that want to roam to a different network when encountering
  // network problems can override this method in order to do so. The parent
  // implementation handles the metric reporting of the network problem.
  virtual void OnEncounterNetworkProblem(int reason);

  // Set the state of the selected service, with checks to make sure
  // the service is already in a connected state before doing so.
  void SetServiceConnectedState(Service::ConnectState state);

  // Specifies whether an ARP gateway should be used for the
  // device technology.
  virtual bool ShouldUseArpGateway() const;

  // Indicates if the selected service is configured with a static IP address.
  bool IsUsingStaticIP() const;

  // Indicates if the selected service is configured with static nameservers.
  bool IsUsingStaticNameServers() const;

  void HelpRegisterConstDerivedString(
      const std::string& name,
      std::string(Device::*get)(Error*));

  void HelpRegisterConstDerivedRpcIdentifier(
      const std::string& name,
      RpcIdentifier(Device::*get)(Error*));

  void HelpRegisterConstDerivedRpcIdentifiers(
      const std::string& name,
      RpcIdentifiers(Device::*get)(Error*));

  void HelpRegisterConstDerivedUint64(
      const std::string& name,
      uint64_t(Device::*get)(Error*));

  // Called by the ConnectionTester whenever a connectivity test completes.
  virtual void ConnectionTesterCallback(const PortalDetector::Result& result);

  // Property getters reserved for subclasses
  ControlInterface* control_interface() const { return control_interface_; }
  Metrics* metrics() const { return metrics_; }
  Manager* manager() const { return manager_; }
  const LinkMonitor* link_monitor() const { return link_monitor_.get(); }
  void set_link_monitor(LinkMonitor* link_monitor);
  bool fixed_ip_params() const { return fixed_ip_params_; }

  // Use for unit test.
  void set_traffic_monitor_for_test(
      std::unique_ptr<TrafficMonitor> traffic_monitor);

  // Calculates the time (in seconds) till a DHCP lease is due for renewal,
  // and stores this value in |result|. Returns false is there is no upcoming
  // DHCP lease renewal, true otherwise.
  bool TimeToNextDHCPLeaseRenewal(uint32_t* result);

 private:
  friend class CellularCapabilityClassicTest;
  friend class CellularTest;
  friend class DeviceAdaptorInterface;
  friend class DeviceByteCountTest;
  friend class DevicePortalDetectionTest;
  friend class DeviceTest;
  friend class EthernetTest;
  friend class OpenVPNDriverTest;
  friend class TestDevice;
  friend class VirtualDeviceTest;
  friend class WiFiObjectTest;

  static const char kIPFlagDisableIPv6[];
  static const char kIPFlagAcceptRouterAdvertisements[];
  static const char kStoragePowered[];
  static const char kStorageReceiveByteCount[];
  static const char kStorageTransmitByteCount[];

  // Brings the associated network interface down unless |fixed_ip_params_| is
  // true, which indicates that the interface state shouldn't be changed.
  void BringNetworkInterfaceDown();

  // Configure static IP address parameters if the service provides them.
  void ConfigureStaticIPTask();

  // Right now, Devices reference IPConfigs directly when persisted to disk
  // It's not clear that this makes sense long-term, but that's how it is now.
  // This call generates a string in the right format for this persisting.
  // |suffix| is injected into the storage identifier used for the configs.
  std::string SerializeIPConfigs(const std::string& suffix);

  // Set an IP configuration flag on the device. |family| should be "ipv6" or
  // "ipv4". |flag| should be the name of the flag to be set and |value| is
  // what this flag should be set to. Overridden by unit tests to pretend
  // writing to procfs.
  virtual bool SetIPFlag(IPAddress::Family family,
                         const std::string& flag,
                         const std::string& value);

  // Request the removal of reverse-path filtering for this interface.
  // This will allow packets destined for this interface to be accepted,
  // even if this is not the default route for such a packet to arrive.
  void DisableReversePathFilter();

  // Request reverse-path filtering for this interface.
  void EnableReversePathFilter();

  // Disable ARP filtering on the device.  The interface will exhibit the
  // default Linux behavior -- incoming ARP requests are responded to by all
  // interfaces.  Outgoing ARP requests can contain any local address.
  void DisableArpFiltering();

  // Enable ARP filtering on the device.  Incoming ARP requests are responded
  // to only by the interface(s) owning the address.  Outgoing ARP requests
  // will contain the best local address for the target.
  void EnableArpFiltering();

  std::string GetSelectedServiceRpcIdentifier(Error* error);
  std::vector<std::string> AvailableIPConfigs(Error* error);

  // Get the LinkMonitor's average response time.
  uint64_t GetLinkMonitorResponseTime(Error* error);

  // Get receive and transmit byte counters. These methods simply wrap
  // GetReceiveByteCount and GetTransmitByteCount in order to be used by
  // HelpRegisterConstDerivedUint64.
  uint64_t GetReceiveByteCountProperty(Error* error);
  uint64_t GetTransmitByteCountProperty(Error* error);

  // Emit a property change signal for the "IPConfigs" property of this device.
  void UpdateIPConfigsProperty();

  // Called by DNS server tester when the fallback DNS servers test completes.
  void FallbackDNSResultCallback(const DnsServerTester::Status status);

  // Called by DNS server tester when the configured DNS servers test completes.
  void ConfigDNSResultCallback(const DnsServerTester::Status status);

  // Update DNS setting with the given DNS servers for the current connection.
  void SwitchDNSServers(const std::vector<std::string>& dns_servers);

  // Called when the lifetime for IPv6 DNS server expires.
  void IPv6DNSServerExpired();

  // Return true if given IP configuration contain both IP address and DNS
  // servers. Hence, ready to be used for network connection.
  bool IPConfigCompleted(const IPConfigRefPtr& ipconfig);

  // Setup network connection with given IP configuration, and start portal
  // detection on that connection.
  void SetupConnection(const IPConfigRefPtr& ipconfig);

  // Set the system hostname to |hostname| if this device is configured to
  // do so.  If |hostname| is too long, truncate this parameter to fit within
  // the maximum hostname size.
  bool SetHostname(const std::string& hostname);

  // Prepend the Manager's configured list of DNS servers into |ipconfig|
  // ensuring that only DNS servers of the same address family as |ipconfig| are
  // included in the final list.
  void PrependDNSServersIntoIPConfig(const IPConfigRefPtr& ipconfig);

  // Mutate |servers| to include the Manager's prepended list of DNS servers for
  // |family|.  On return, it is guaranteed that there are no duplicate entries
  // in |servers|.
  void PrependDNSServers(const IPAddress::Family family,
                         std::vector<std::string>* servers);

  // Called by |connection_diagnostics| after diagnostics have finished.
  void ConnectionDiagnosticsCallback(
      const std::string& connection_issue,
      const std::vector<ConnectionDiagnostics::Event>& diagnostic_events);

  // |enabled_persistent_| is the value of the Powered property, as
  // read from the profile. If it is not found in the profile, it
  // defaults to true. |enabled_| reflects the real-time state of
  // the device, i.e., enabled or disabled. |enabled_pending_| reflects
  // the target state of the device while an enable or disable operation
  // is occurring.
  //
  // Some typical sequences for these state variables are shown below.
  //
  // Shill starts up, profile has been read:
  //  |enabled_persistent_|=true   |enabled_|=false   |enabled_pending_|=false
  //
  // Shill acts on the value of |enabled_persistent_|, calls SetEnabled(true):
  //  |enabled_persistent_|=true   |enabled_|=false   |enabled_pending_|=true
  //
  // SetEnabled completes successfully, device is enabled:
  //  |enabled_persistent_|=true   |enabled_|=true    |enabled_pending_|=true
  //
  // User presses "Disable" button, SetEnabled(false) is called:
  //  |enabled_persistent_|=false   |enabled_|=true    |enabled_pending_|=false
  //
  // SetEnabled completes successfully, device is disabled:
  //  |enabled_persistent_|=false   |enabled_|=false    |enabled_pending_|=false
  bool enabled_;
  bool enabled_persistent_;
  bool enabled_pending_;

  // Other properties
  const std::string hardware_address_;

  PropertyStore store_;

  const int interface_index_;
  bool running_;  // indicates whether the device is actually in operation
  const std::string link_name_;
  ControlInterface* control_interface_;
  EventDispatcher* dispatcher_;
  Metrics* metrics_;
  Manager* manager_;
  IPConfigRefPtr ipconfig_;
  IPConfigRefPtr ip6config_;
  IPConfigRefPtr dhcpv6_config_;
  ConnectionRefPtr connection_;
  base::WeakPtrFactory<Device> weak_ptr_factory_;
  std::unique_ptr<DeviceAdaptorInterface> adaptor_;
  std::unique_ptr<PortalDetector> portal_detector_;
  std::unique_ptr<LinkMonitor> link_monitor_;
  // Used for verifying whether DNS server is functional.
  std::unique_ptr<DnsServerTester> dns_server_tester_;
  // Callback to invoke when IPv6 DNS servers lifetime expired.
  base::CancelableClosure ipv6_dns_server_expired_callback_;
  std::unique_ptr<TrafficMonitor> traffic_monitor_;
  // DNS servers obtained from ipconfig (either from DHCP or static config)
  // that are not working.
  std::vector<std::string> config_dns_servers_;
  Technology::Identifier technology_;
  // The number of portal detection attempts from Connected to Online state.
  // This includes all failure/timeout attempts and the final successful
  // attempt.
  int portal_attempts_to_online_;

  int portal_check_interval_seconds_;

  // Keep track of the offset between the interface-reported byte counters
  // and our persisted value.
  uint64_t receive_byte_offset_;
  uint64_t transmit_byte_offset_;

  // Maintain a reference to the connected / connecting service
  ServiceRefPtr selected_service_;

  // Cache singleton pointers for performance and test purposes.
  DHCPProvider* dhcp_provider_;
  RoutingTable* routing_table_;
  RTNLHandler* rtnl_handler_;

  std::unique_ptr<TimeoutSet<IPAddress>> blackhole_addrs_;

  // Time when link monitor last failed.
  Time* time_;
  time_t last_link_monitor_failed_time_;
  // Callback to invoke when link becomes reliable again after it was previously
  // unreliable.
  base::CancelableClosure reliable_link_callback_;

  std::unique_ptr<PortalDetector> connection_tester_;
  base::Callback<void()> connection_tester_callback_;

  // Track whether packets from non-optimal routes will be accepted by this
  // device.  This is referred to as "loose mode" (see RFC3704).
  bool is_loose_routing_;

  // Track the current same-net multi-home state.
  bool is_multi_homed_;

  // If true, IP parameters should not be modified.
  bool fixed_ip_params_;

  // Remember which flag files were previously successfully written.
  std::set<std::string> written_flags_;

  std::unique_ptr<ConnectionDiagnostics> connection_diagnostics_;

  DISALLOW_COPY_AND_ASSIGN(Device);
};

}  // namespace shill

#endif  // SHILL_DEVICE_H_
