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

#ifndef SHILL_CELLULAR_CELLULAR_H_
#define SHILL_CELLULAR_CELLULAR_H_

#include <deque>
#include <map>
#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <unordered_map>
#include <vector>

#include <base/memory/weak_ptr.h>
#include <base/time/time.h>
#include <chromeos/patchpanel/dbus/client.h>
#include <gtest/gtest_prod.h>  // for FRIEND_TEST
#include <net-base/mac_address.h>
#include <net-base/network_config.h>
#include <net-base/netlink_sock_diag.h>
#include <net-base/process_manager.h>
#include <net-base/rtnl_listener.h>
#include <net-base/rtnl_message.h>

#include "shill/cellular/apn_list.h"
#include "shill/cellular/carrier_entitlement.h"
#include "shill/cellular/cellular_bearer.h"
#include "shill/cellular/dbus_objectmanager_proxy_interface.h"
#include "shill/cellular/mobile_operator_info.h"
#include "shill/cellular/power_opt.h"
#include "shill/device.h"
#include "shill/device_id.h"
#include "shill/network/network_manager.h"
#include "shill/network/network_monitor.h"
#include "shill/refptr_types.h"
#include "shill/rpc_task.h"
#include "shill/tethering_manager.h"

namespace shill {

class CellularCapability3gpp;
class Error;
class ExternalTask;
class PowerOpt;

class Cellular : public Device,
                 public RpcTaskDelegate,
                 public MobileOperatorInfo::Observer {
 public:
  enum class State {
    // Initial state. No Capability exists.
    kDisabled,
    // A Modem object and a corresponding Capability have been created but the
    // Modem has not started.
    kEnabled,
    // A Start request has been sent to the Modem.
    kModemStarting,
    // The Modem Start has completed.
    kModemStarted,
    // A Stop request has been sent to the Modem.
    kModemStopping,
    // The modem has registered with a network. A Cellular Service will be
    // created if necessary and associated with this Device.
    kRegistered,
    // The modem has connected to a network.
    kConnected,
    // The network interface is up.
    kLinked,
    // The modem is powered off.
    kPoweredOff,
  };

  // This enum must be kept in sync with ModemManager's MMModemState enum.
  enum ModemState {
    kModemStateFailed = -1,
    kModemStateUnknown = 0,
    kModemStateInitializing = 1,
    kModemStateLocked = 2,
    kModemStateDisabled = 3,
    kModemStateDisabling = 4,
    kModemStateEnabling = 5,
    kModemStateEnabled = 6,
    kModemStateSearching = 7,
    kModemStateRegistered = 8,
    kModemStateDisconnecting = 9,
    kModemStateConnecting = 10,
    kModemStateConnected = 11,
  };

  // Enum for SIM types
  enum SimType {
    kSimTypeUnknown = 0,
    kSimTypePsim = 1,
    kSimTypeEsim = 2,
  };

  // Used in Cellular and CellularCapability3gpp to store and pass properties
  // associated with a SIM Profile.
  struct SimProperties {
    size_t slot;
    std::string iccid;
    std::string eid;
    std::string operator_id;
    std::string spn;
    std::string imsi;
    std::string gid1;
    bool operator==(const SimProperties& other) const {
      return slot == other.slot && iccid == other.iccid && eid == other.eid &&
             operator_id == other.operator_id && spn == other.spn &&
             imsi == other.imsi && gid1 == other.gid1;
    }
  };

  // Static helper for logging.
  static std::string GetStateString(State state);
  static std::string GetModemStateString(ModemState modem_state);

  // Helper to build a fallback empty APN
  static Stringmap BuildFallbackEmptyApn(ApnList::ApnType apn_type);

  // |path| is the ModemManager.Modem DBus object path (e.g.,
  // "/org/freedesktop/ModemManager1/Modem/0"). |service| is the modem
  // mananager service name (e.g., /org/freedesktop/ModemManager1).
  Cellular(Manager* manager,
           const std::string& link_name,
           net_base::MacAddress mac_address,
           int interface_index,
           const std::string& service,
           const RpcIdentifier& path);
  Cellular(const Cellular&) = delete;
  Cellular& operator=(const Cellular&) = delete;

  ~Cellular() override;

  // Returns the legacy identifier used by GetStorageIdentifier for loading
  // entries from older profiles. TODO(b/181843251): Remove after M94.
  std::string GetLegacyEquipmentIdentifier() const;

  // Returns the Capability type if |capability_| has been created.
  std::string GetTechnologyFamily(Error* error);

  // Returns the device id as a string if it has been set.
  std::string GetDeviceId(Error* error);

  // Returns whether the device supports multiplexed data sessions
  bool GetMultiplexSupport();

  // Inherited from Device.
  Network* GetPrimaryNetwork() const override;
  bool Load(const StoreInterface* storage) override;
  bool Save(StoreInterface* storage) override;
  void Start(EnabledStateChangedCallback callback) override;
  void Stop(EnabledStateChangedCallback callback) override;
  bool IsUnderlyingDeviceEnabled() const override;
  void Scan(Error* error,
            const std::string& /*reason*/,
            bool /*is_dbus_call*/) override;
  void RegisterOnNetwork(const std::string& network_id,
                         ResultCallback callback) override;
  void RequirePin(const std::string& pin,
                  bool require,
                  ResultCallback callback) override;
  void EnterPin(const std::string& pin, ResultCallback callback) override;
  void UnblockPin(const std::string& unblock_code,
                  const std::string& pin,
                  ResultCallback callback) override;
  void ChangePin(const std::string& old_pin,
                 const std::string& new_pin,
                 ResultCallback callback) override;
  void Reset(ResultCallback callback) override;
  void DropConnection() override;
  void SetServiceState(Service::ConnectState state) override;
  void SetServiceFailure(Service::ConnectFailure failure_state) override;
  void SetServiceFailureSilent(Service::ConnectFailure failure_state) override;
  void OnConnected() override;
  void OnBeforeSuspend(ResultCallback callback) override;
  void OnAfterResume() override;
  void UpdateGeolocationObjects(
      std::vector<GeolocationInfo>* geolocation_infos) const override;

  // Network event handler
  void OnConnectionUpdated(int interface_index) override;

  // Performs the necessary steps to bring the service to the activated state,
  // once an online payment has been done.
  void CompleteActivation(Error* error);

  bool GetForceInitEpsBearerSettings();
  void SetForceInitEpsBearerSettings(bool force);

  // Cancel any pending connect request.
  void CancelPendingConnect();

  void OnScanStarted();
  void OnScanReply(const Stringmaps& found_networks, const Error& error);

  // Asynchronously queries capability for cellular location.
  void PollLocation();

  void HandleNewSignalQuality(uint32_t strength);

  // Processes a change in the modem registration state, possibly creating,
  // destroying or updating the CellularService.
  void HandleNewRegistrationState();

  // Called when the associated Modem object is destroyed.
  void OnModemDestroyed();

  void OnNetworkValidationResult(int interface_index,
                                 const NetworkMonitor::Result& result) override;

  // Returns true if |service| is connectable.
  bool GetConnectable(CellularService* service) const;

  // Asynchronously connects the modem to |service|. Changes the primary slot if
  // required. Populates |error| on failure, leaves it unchanged otherwise.
  virtual void Connect(CellularService* service, Error* error);

  // Asynchronously disconnects the modem from the current network and populates
  // |error| on failure, leaves it unchanged otherwise.
  virtual void Disconnect(Error* error, const char* reason);

  // Configures the attach APN in the modem.
  virtual void ConfigureAttachApn(bool user_triggered);

  // Called when the Modem object is created to set the initial properties.
  void SetInitialProperties(const InterfaceToProperties& properties);

  void OnModemStateChanged(ModemState new_state);

  // Returns true if ServiceOptionNotSubscribed error was reported
  // for this ICCID.
  bool IsSubscriptionErrorSeen();

  // Called to send detailed metrics for the last connection attempt.
  void NotifyDetailedCellularConnectionResult(const Error& error,
                                              ApnList::ApnType apn_type,
                                              const shill::Stringmap& apn_info);
  void NotifyNetworkValidationResult(
      std::map<std::string, std::string> apn_info,
      int portal_result,
      int portal_detection_count);

  // Is the underlying device in the process of activating?
  bool IsActivating() const;

  // Starts and stops scheduled location polls
  void StartLocationPolling();
  void StopLocationPolling();

  // Initiate PPP link. Called from capabilities.
  virtual void StartPPP(const std::string& serial_device);
  // Callback for |ppp_task_|.
  virtual void OnPPPDied(pid_t pid, int exit);

  // Implements RpcTaskDelegate, for |ppp_task_|.
  void GetLogin(std::string* user, std::string* password) override;
  void Notify(const std::string& reason,
              const std::map<std::string, std::string>& dict) override;

  // Register DBus Properties exposed by the Device interface of shill.
  void RegisterProperties();

  // |dbus_path| and |mac_address| may change if the associated Modem restarts.
  void UpdateModemProperties(const RpcIdentifier& dbus_path,
                             net_base::MacAddress mac_address);

  // Returns a unique identifier for a SIM Card. For physical cards this will be
  // the ICCID and there should only be one matching service. For eSIM cards,
  // this will be the eUICCID (eID) and there may be multiple services
  // associated with the card.
  const std::string& GetSimCardId() const;

  // Returns true if |sim_card_id| matches any available SIM cards.
  bool HasIccid(const std::string& iccid) const;

  // Sets the SIM properties and the primary SIM, and updates services and
  // state accordingly.
  void SetSimProperties(const std::vector<SimProperties>& slot_properties,
                        size_t primary_slot);

  // Verifies if the device is entitled to use the Hotspot feature.
  using EntitlementCheckResultCallback =
      base::OnceCallback<void(TetheringManager::EntitlementStatus)>;
  mockable void EntitlementCheck(EntitlementCheckResultCallback callback,
                                 bool experimental_tethering);

  // Returns true if the FW version supports tethering. Only FWs that were
  // fully validated will return true.
  mockable bool FirmwareSupportsTethering() {
    return firmware_supports_tethering_;
  }

  // Asynchronously acquires the Network to be used in tethering, which may be
  // the same one as used for default connection or a new one.
  using AcquireTetheringNetworkResultCallback =
      base::OnceCallback<void(Network* network, const Error& error)>;
  virtual void AcquireTetheringNetwork(
      TetheringManager::UpdateTimeoutCallback update_timeout_callback,
      AcquireTetheringNetworkResultCallback callback,
      TetheringManager::CellularUpstreamEventCallback tethering_event_callback,
      bool experimental_tethering);

  // Asynchronously releases the tethering network, if any. This may involve
  // disconnecting a PDN connection or a no-op in certain other cases.
  // If |network| is nullptr, this request will abort the ongoing tethering
  // network acquisition attempt.
  void ReleaseTetheringNetwork(Network* network, ResultCallback callback);

  // Public to ease testing tethering acquisition logic.
  enum class TetheringOperationType {
    // Connect/disconnect DUN as DEFAULT packet data network.
    // The kDisconnectDunAsDefaultPdn type is not returned by
    // GetTetheringOperationType(), it is only used to flag the ongoing
    // operation when releasing a tethering network that was acquired with a
    // previous kConnectDunAsDefaultPdn operation.
    kConnectDunAsDefaultPdn,
    kDisconnectDunAsDefaultPdn,
    // Connect/disconnect a multiplexed DUN packet data network.
    // The kDisconnectDunMultiplexed type is not returned by
    // GetTetheringOperationType(), it is only used to flag the ongoing
    // operation when releasing a tethering network that was acquired with a
    // previous kConnectDunMultiplexed operation.
    kConnectDunMultiplexed,
    kDisconnectDunMultiplexed,
    // The currently connected default network will be reused for tethering.
    kReuseDefaultPdn,
    // Used to report errors in GetTetheringOperationType()
    kFailed,
  };
  TetheringOperationType GetTetheringOperationType(bool experimental_tethering,
                                                   Error* error);

  // Takes the currently connected default PDN and reuses it for tethering
  // purposes, without bringing up any other PDN connection.
  // This is the operation run in AcquireTetheringNetwork() when the
  // GetTetheringOperationType() selection method returns kReuseDefaultPdn.
  void ReuseDefaultPdnForTethering(
      AcquireTetheringNetworkResultCallback callback);

  // Brings down the currently connected default PDN and connects a new PDN
  // using the DUN specific APN. The newly connected PDN is considered the
  // default PDN, i.e. even for non-tethered data.
  // This is the operation run in AcquireTetheringNetwork() when the
  // GetTetheringOperationType() selection method returns
  // kConnectDunAsDefaultPdn.
  void ConnectTetheringAsDefaultPdn(
      AcquireTetheringNetworkResultCallback callback);

  // Connects a new multiplexed PDN using the DUN specific APN.
  // This is the operation run in AcquireTetheringNetwork() when the
  // GetTetheringOperationType() selection method returns
  // kConnectDunMultiplexed.
  void ConnectMultiplexedTetheringPdn(
      AcquireTetheringNetworkResultCallback callback);

  // Called when an OTA profile update arrives from the network.
  void OnProfilesChanged();
  // Called when shill manager deregisters the device.
  void OnDeregistered() override;

  // Returns a list of APNs of type |apn_type| to try. The logic when using
  // SetApn and SetCustomApnList(APN UI revamp) differs. When using
  // |SetCustomApnList| and the user has set at least 1 APN , only custom APNs
  // will be included in the list, otherwise the logic is the same as |SetApn|.
  // The APNs returned when using |SetApn| are in the following order:
  // - the APN, if any, that was set by the user(for SetApn only)
  // - APNs that the modem reports as provisioned profiles
  // - the list of APNs found in the mobile broadband provider DB for the
  //   home provider associated with the current SIM
  // - the last APN that resulted in a successful connection attempt on the
  //   current network (if any)
  std::deque<Stringmap> BuildApnTryList(ApnList::ApnType apn_type) const;

  // Same as BuildApnTryList, but it only returns IA APNs.
  std::deque<Stringmap> BuildAttachApnTryList() const;
  // Same as BuildApnTryList, but it only returns DEFAULT APNs.
  std::deque<Stringmap> BuildDefaultApnTryList() const;
  // Same as BuildApnTryList, but it only returns DUN APNs.
  std::deque<Stringmap> BuildTetheringApnTryList() const;

  // Update the home provider. This information may be from the SIM or received
  // OTA.
  void UpdateHomeProvider();

  // Update the serving operator info.
  void UpdateServingOperator();

  // Implements MobileOperatorInfo::Observer:
  void OnOperatorChanged() override;

  const CellularServiceRefPtr& service() const { return service_; }
  MobileOperatorInfo* mobile_operator_info() const {
    return mobile_operator_info_.get();
  }
  PowerOpt* power_opt();
  State state() const { return state_; }
  ModemState modem_state() const { return modem_state_; }
  bool allow_roaming_property() const { return allow_roaming_; }

  bool StateIsConnected();
  bool StateIsRegistered();
  bool StateIsStarted();

  enum class ModemType {
    kUnknown,
    kL850GL,
    kFM101,
    kFM350,
    kOther,
  };

  // Enum for modem firmware maintenance revision.
  enum class ModemMR {
    kModemMRUnknown = 0,
    kModemMR1 = 1,
    kModemMR2 = 2,
    kModemMR3 = 3,
    kModemMR4 = 4,
    kModemMR5 = 5,
    kModemMR6 = 6,
    kModemMR7 = 7,
    kModemMR8 = 8,
  };

  bool IsModemFM101();
  bool IsModemFM350();
  bool IsModemL850GL();
  ModemMR GetModemFWRevision();
  std::string ModemTypeEnumToString(ModemType type);
  std::string ModemMREnumToString(ModemMR mr);
  ModemType modem_type() { return modem_type_; }

  bool ShouldForceInitEpsBearerSettings();
  // DBus property getters
  const std::string& dbus_service() const { return dbus_service_; }
  const RpcIdentifier& dbus_path() const { return dbus_path_; }
  const Stringmap& home_provider() const { return home_provider_; }
  bool scanning_supported() const { return scanning_supported_; }
  const std::string& eid() const { return eid_; }
  const std::string& esn() const { return esn_; }
  const std::string& firmware_revision() const { return firmware_revision_; }
  const std::string& hardware_revision() const { return hardware_revision_; }
  const DeviceId* device_id() const { return device_id_.get(); }
  const std::string& imei() const { return imei_; }
  const std::string& imsi() const { return imsi_; }
  const std::string& mdn() const { return mdn_; }
  const std::string& meid() const { return meid_; }
  const std::string& min() const { return min_; }
  const std::string& manufacturer() const { return manufacturer_; }
  const std::string& model_id() const { return model_id_; }
  const std::string& mm_plugin() const { return mm_plugin_; }
  bool scanning() const { return scanning_; }
  bool internal_device() const { return internal_device_; }

  const std::string& selected_network() const { return selected_network_; }
  const Stringmaps& found_networks() const { return found_networks_; }
  bool sim_present() const { return sim_present_; }
  const Stringmaps& apn_list() const { return apn_list_; }
  const std::string& iccid() const { return iccid_; }
  bool allow_roaming() const { return allow_roaming_; }
  bool policy_allow_roaming() const { return policy_allow_roaming_; }
  bool provider_requires_roaming() const { return provider_requires_roaming_; }
  bool use_attach_apn() const { return use_attach_apn_; }

  bool inhibited() const { return inhibited_; }
  const std::string& connect_pending_iccid() const {
    return connect_pending_iccid_;
  }

  void SetScanningSupported(bool scanning_supported);
  void SetEquipmentId(const std::string& equipment_id);
  void SetEsn(const std::string& esn);
  void SetFirmwareRevision(const std::string& firmware_revision);
  void SetHardwareRevision(const std::string& hardware_revision);
  void SetDeviceId(std::unique_ptr<DeviceId> device_id);
  void SetImei(const std::string& imei);
  void SetMdn(const std::string& mdn);
  void SetMeid(const std::string& meid);
  void SetMin(const std::string& min);
  void SetManufacturer(const std::string& manufacturer);
  void SetModelId(const std::string& model_id);
  void SetMMPlugin(const std::string& mm_plugin);
  void SetMaxActiveMultiplexedBearers(uint32_t max_multiplexed_bearers);

  void SetSelectedNetwork(const std::string& selected_network);
  void SetFoundNetworks(const Stringmaps& found_networks);
  void SetPrimaryMultiplexedInterface(const std::string& interface_name);
  void SetProviderRequiresRoaming(bool provider_requires_roaming);
  bool IsRoamingAllowed();
  void SetApnList(const Stringmaps& apn_list);

  // Sets a Service for testing. When set, Cellular does not create or destroy
  // the associated Service.
  void SetServiceForTesting(CellularServiceRefPtr service);
  void SetSelectedServiceForTesting(CellularServiceRefPtr service);

  void set_home_provider_for_testing(const Stringmap& home_provider) {
    home_provider_ = home_provider;
  }
  void set_mobile_operator_info_for_testing(
      MobileOperatorInfo* mobile_operator_info) {
    mobile_operator_info_.reset(mobile_operator_info);
  }
  void clear_found_networks_for_testing() { found_networks_.clear(); }
  CellularCapability3gpp* capability_for_testing() { return capability_.get(); }
  const KeyValueStores& sim_slot_info_for_testing() { return sim_slot_info_; }
  void set_modem_state_for_testing(ModemState state) { modem_state_ = state; }
  void set_eid_for_testing(const std::string& eid) { eid_ = eid; }
  void set_iccid_for_testing(const std::string& iccid) { iccid_ = iccid; }
  void set_state_for_testing(const State& state) { state_ = state; }
  void set_skip_establish_link_for_testing(bool on) {
    skip_establish_link_for_testing_ = on;
  }
  void set_default_pdn_apn_type_for_testing(ApnList::ApnType apn_type) {
    default_pdn_apn_type_ = apn_type;
  }

  enum class LinkState { kUnknown, kDown, kUp };
  void SetDefaultPdnForTesting(const RpcIdentifier& dbus_path,
                               std::unique_ptr<Network> network,
                               LinkState link_state);
  Network* default_pdn_for_testing() {
    return default_pdn_ ? default_pdn_->network() : nullptr;
  }
  void SetMultiplexedTetheringPdnForTesting(const RpcIdentifier& dbus_path,
                                            std::unique_ptr<Network> network,
                                            LinkState link_state);
  Network* multiplexed_tethering_pdn_for_testing() {
    return multiplexed_tethering_pdn_ ? multiplexed_tethering_pdn_->network()
                                      : nullptr;
  }
  void OnAcquireTetheringNetworkReady(
      AcquireTetheringNetworkResultCallback callback,
      Network* network,
      const Error& error);

  // Public to ease testing without real RTNL link events.
  void DefaultLinkDeleted();
  void DefaultLinkUp();
  void DefaultLinkDown();
  void MultiplexedTetheringLinkDeleted();
  void MultiplexedTetheringLinkUp();
  void MultiplexedTetheringLinkDown();

  // Delay before connecting to pending connect requests. This helps prevent
  // connect failures while the Modem is still starting up.
  static constexpr base::TimeDelta kPendingConnectDelay = base::Seconds(2);

 private:
  friend class CellularTest;
  friend class CellularServiceTest;
  friend class CellularServiceProviderTest;
  friend class ModemTest;
  FRIEND_TEST(CellularTest, AcquireTetheringNetwork_NoModem);
  FRIEND_TEST(CellularTest, ChangeServiceState);
  FRIEND_TEST(CellularTest, ChangeServiceStatePPP);
  FRIEND_TEST(CellularTest, CompareApns);
  FRIEND_TEST(CellularTest, CompareApnsFromStorage);
  FRIEND_TEST(CellularTest, CompareApnsFromApnList);
  FRIEND_TEST(CellularTest, CompareApns);
  FRIEND_TEST(CellularTest, CompareApnsFromStorage);
  FRIEND_TEST(CellularTest, CompareApnsFromApnList);
  FRIEND_TEST(CellularTest, CompareApns);
  FRIEND_TEST(CellularTest, CompareApnsFromStorage);
  FRIEND_TEST(CellularTest, CompareApnsFromApnList);
  FRIEND_TEST(CellularTest, Connect);
  FRIEND_TEST(CellularTest, ConnectFailure);
  FRIEND_TEST(CellularTest, ConnectWhileInhibited);
  FRIEND_TEST(CellularTest, DefaultLinkUpToDown);
  FRIEND_TEST(CellularTest, DefaultLinkUpToDownAlreadyDisconnecting);
  FRIEND_TEST(CellularTest, Disconnect);
  FRIEND_TEST(CellularTest, DisconnectFailure);
  FRIEND_TEST(CellularTest, DropConnection);
  FRIEND_TEST(CellularTest, DropConnectionPPP);
  FRIEND_TEST(CellularTest, EstablishLinkDHCP);
  FRIEND_TEST(CellularTest, EstablishLinkPPP);
  FRIEND_TEST(CellularTest, EstablishLinkStatic);
  FRIEND_TEST(CellularTest, EstablishLinkFailureNoBearer);
  FRIEND_TEST(CellularTest, EstablishLinkMultiplexDHCP);
  FRIEND_TEST(CellularTest, EstablishLinkMultiplexStatic);
  FRIEND_TEST(CellularTest, HomeProviderServingOperator);
  FRIEND_TEST(CellularTest, Notify);
  FRIEND_TEST(CellularTest, OnAfterResumeDisabledWantDisabled);
  FRIEND_TEST(CellularTest, OnAfterResumeDisabledWantEnabled);
  FRIEND_TEST(CellularTest, OnPPPDied);
  FRIEND_TEST(CellularTest, PendingConnect);
  FRIEND_TEST(CellularTest, PendingDisconnect);
  FRIEND_TEST(CellularTest, PPPConnectionFailedAfterAuth);
  FRIEND_TEST(CellularTest, PPPConnectionFailedBeforeAuth);
  FRIEND_TEST(CellularTest, PPPConnectionFailedDuringAuth);
  FRIEND_TEST(CellularTest, PPPConnectionFailedAfterConnect);
  FRIEND_TEST(CellularTest, RequiredApnExists);
  FRIEND_TEST(CellularTest, SetPolicyAllowRoaming);
  FRIEND_TEST(CellularTest, ShouldBringNetworkInterfaceDownAfterDisabled);
  FRIEND_TEST(CellularTest, StopPPPOnDisconnect);
  FRIEND_TEST(CellularTest, StorageIdentifier);
  FRIEND_TEST(CellularTest, StartPPP);
  FRIEND_TEST(CellularTest, StartPPPAfterEthernetUp);
  FRIEND_TEST(CellularTest, StartPPPAlreadyStarted);
  FRIEND_TEST(CellularTest, UpdateGeolocationObjects);
  // Names of properties in storage
  static const char kAllowRoaming[];
  static const char kPolicyAllowRoaming[];
  static const char kUseAttachApn[];

  // Modem Manufacturer Name
  static const char kQ6V5ModemManufacturerName[];

  // Modem driver remoteproc pattern
  static const char kQ6V5RemoteprocPattern[];

  // Modem driver sysfs base path
  static const char kQ6V5SysfsBasePath[];

  // Modem driver name
  static const char kQ6V5DriverName[];

  // Internal device storage identifier
  static const char kInternalStorageIdentifier[];

  // Time between stop and start of modem device
  static constexpr base::TimeDelta kModemResetTimeout = base::Seconds(1);

  // Time between asynchronous calls to ModemManager1's GetLocation()
  static constexpr base::TimeDelta kPollLocationInterval = base::Minutes(5);

  // Cleans up the APN try list removing invalid entries
  static void ValidateApnTryList(std::deque<Stringmap>& apn_try_list);

  enum class StopSteps {
    // Initial state.
    kStopModem,
    // The modem has been stopped.
    kModemStopped,
  };

  std::string DeviceStorageSuffix() const override;

  void CreateCapability();
  void DestroyCapability();

  void StartModem(EnabledStateChangedCallback callback);
  void StartModemCallback(EnabledStateChangedCallback callback,
                          const Error& error);
  void StopModemCallback(EnabledStateChangedCallback callback,
                         const Error& error);
  void DestroySockets();

  bool ShouldBringNetworkInterfaceDownAfterDisabled() const override;
  void BringNetworkInterfaceDown() override;

  void SetDbusPath(const shill::RpcIdentifier& dbus_path);
  void SetState(State state);
  void SetModemState(ModemState modem_state_state);
  void SetScanning(bool scanning);
  void SetScanningProperty(bool scanning);

  void OnEnabled();
  void OnConnecting();
  void OnDisconnected();
  void OnDisconnectFailed();
  void NotifyCellularConnectionResult(const Error& error,
                                      const std::string& iccid,
                                      bool is_user_triggered,
                                      ApnList::ApnType apn_type);
  std::vector<Metrics::DetailedCellularConnectionResult::APNType>
  ConnectionApnTypesToMetrics(ApnList::ApnType apn_type);
  // Invoked when the modem is connected to the cellular network to transition
  // to the network-connected state and bring the network interface up.
  void EstablishLink();
  // Invoked when the tethering multiplexed link may need to be setup.
  void EstablishMultiplexedTetheringLink();

  void LinkMsgHandler(const net_base::RTNLMessage& msg);

  void SetPrimarySimProperties(const SimProperties& properties);
  void SetSimSlotProperties(const std::vector<SimProperties>& slot_properties,
                            int primary_slot);

  void SetRegistered();

  // Creates or destroys services as required.
  void UpdateServices();

  // Creates and registers services for the available SIMs and sets
  // |service_| to the primary (active) service.
  void CreateServices();

  // Destroys all services and the connection, if any. This also eliminates any
  // circular references between this device and the associated service,
  // allowing eventual device destruction.
  void DestroyAllServices();

  // Drops connection but never through the |ppp_device_|, if there is any.
  void DropConnectionDefault();

  // Compares 2 APN configurations ignoring fields that are not connection
  // properties. This is needed since we add tags to the APN Stringmap to track
  // information related to each APN, but these properties are not used as
  // connection properties.
  bool CompareApns(const Stringmap& apn1, const Stringmap& apn2) const;

  bool IsRequiredByCarrierApn(const Stringmap& apn) const;
  bool RequiredApnExists(ApnList::ApnType apn_type) const;

  // Creates or updates services for secondary SIMs.
  void UpdateSecondaryServices();

  // HelpRegisterDerived*: Expose a property over RPC, with the name |name|.
  //
  // Reads of the property will be handled by invoking |get|.
  // Writes to the property will be handled by invoking |set|.
  // Clearing the property will be handled by PropertyStore.
  void HelpRegisterDerivedBool(std::string_view name,
                               bool (Cellular::*get)(Error* error),
                               bool (Cellular::*set)(const bool& value,
                                                     Error* error));
  void HelpRegisterConstDerivedString(
      std::string_view name, std::string (Cellular::*get)(Error* error));

  void OnConnectReply(ApnList::ApnType apn_type,
                      std::string iccid,
                      bool is_user_triggered,
                      const Error& error);
  void OnDisconnectReply(const Error& error);

  // DBus accessors
  bool GetPolicyAllowRoaming(Error* /*error*/);
  bool SetPolicyAllowRoaming(const bool& value, Error* error);
  bool GetInhibited(Error* /*error*/);
  bool SetInhibited(const bool& inhibited, Error* error);
  KeyValueStore GetSimLockStatus(Error* error);
  void SetSimPresent(bool sim_present);

  // TODO(b/277792069): Remove when Chrome removes the attach APN code.
  // DBUS accessors to read/modify the use of an Attach APN
  bool GetUseAttachApn(Error* /*error*/) { return true; }
  bool SetUseAttachApn(const bool& value, Error* error);

  // When shill terminates or ChromeOS suspends, this function is called to
  // disconnect from the cellular network.
  void StartTermination();

  // This method is invoked upon the completion of StartTermination().
  void OnTerminationCompleted(const Error& error);

  // This function does the final cleanup once a disconnect request terminates.
  // Returns true, if the device state is successfully changed.
  bool DisconnectCleanup();

  // Executed after the asynchronous CellularCapability3gpp::StartModem
  // call from OnAfterResume completes.
  static void LogRestartModemResult(const Error& error);

  // Handler to reset qcom-q6v5-mss based modems
  bool ResetQ6V5Modem();

  // Get reset path for Q6V5 modem
  base::FilePath GetQ6V5ModemResetPath();

  // Handler to check if modem is based on qcom-q6v5-mss
  bool IsQ6V5Modem();

  // Execute the next step to Stop cellular.
  void StopStep(EnabledStateChangedCallback callback,
                const Error& error_result);

  // Terminate the pppd process associated with this Device, and remove the
  // association between the PPPDevice and our CellularService. If this
  // Device is not using PPP, the method has no effect.
  void StopPPP();

  // Handlers for PPP events. Dispatched from Notify().
  void OnPPPAuthenticated();
  void OnPPPAuthenticating();
  void OnPPPConnected(const std::map<std::string, std::string>& params);

  bool ModemIsEnabledButNotRegistered();

  void SetPendingConnect(const std::string& iccid);
  void ConnectToPending();
  void ConnectToPendingAfterDelay();
  void ConnectToPendingFailed(Service::ConnectFailure failure);
  void ConnectToPendingCancel();

  void UpdateScanning();
  void GetLocationCallback(const std::string& gpp_lac_ci_string,
                           const Error& error);
  void PollLocationTask();

  void StartLinkListener();
  void StopLinkListener();

  void ResetCarrierEntitlement();
  void OnEntitlementCheckUpdated(CarrierEntitlement::Result result);
  void TriggerEntitlementCheckCallbacks(
      TetheringManager::EntitlementStatus result);

  void UpdateFirmwareSupportsTethering();
  // Single tethering operation context, whenever any connection setup is
  // required (i.e. not used when reusing the default network for tethering).
  struct TetheringOperationInfo {
    TetheringOperationType type;
    ResultCallback callback;
    ApnList::ApnType apn_type;
    std::deque<Stringmap> apn_try_list;
    bool apn_connected;
  };
  void CompleteTetheringOperation(const Error& error);
  void NotifyCellularConnectionResultInTetheringOperation(
      TetheringOperationType type, const Error& error);
  bool InitializeTetheringOperation(TetheringOperationType type,
                                    ResultCallback callback);
  void AbortTetheringOperation(const Error& error, ResultCallback callback);

  // Management of the DUN as DEFAULT tethering operation
  void DisconnectTetheringAsDefaultPdn(ResultCallback callback);
  void RunTetheringOperationDunAsDefault();
  void OnCapabilityDisconnectBeforeReconnectReply(const Error& error);
  void OnConnectTetheringAsDefaultPdnReply(
      AcquireTetheringNetworkResultCallback callback, const Error& error);

  // Helper to check whether a DUN as DEFAULT tethering operation is ongoing
  // (either connecting or disconnecting).
  bool IsTetheringOperationDunAsDefaultOngoing();

  // Management of the tethering-specific multiplexed network attempt
  void DisconnectMultiplexedTetheringPdn(ResultCallback callback);
  void RunDisconnectMultiplexedTetheringPdn();
  void OnCapabilityConnectMultiplexedTetheringReply(const Error& error);
  void OnCapabilityDisconnectMultiplexedTetheringReply(const Error& error);
  void OnConnectMultiplexedTetheringPdnReply(
      AcquireTetheringNetworkResultCallback callback, const Error& error);

  // Helpers to check whether a multiplexed DUN tethering operation is ongoing.
  bool IsTetheringOperationDunMultiplexedConnectOngoing();
  bool IsTetheringOperationDunMultiplexedDisconnectOngoing();

  State state_ = State::kDisabled;
  ModemState modem_state_ = kModemStateUnknown;

  // Nested network info associated to a single PDN connection in the cellular
  // device.
  class NetworkInfo {
   public:
    explicit NetworkInfo(NetworkManager* network_manager,
                         Cellular* cellular,
                         const RpcIdentifier& bearer_path,
                         int interface_index,
                         const std::string& interface_name);
    // Constructor for testing purposes only.
    explicit NetworkInfo(Cellular* cellular,
                         const RpcIdentifier& bearer_path,
                         std::unique_ptr<Network> network,
                         LinkState link_state);
    NetworkInfo(const NetworkInfo&) = delete;
    NetworkInfo& operator=(const NetworkInfo&) = delete;
    virtual ~NetworkInfo();

    Network* network() const { return network_.get(); }
    LinkState link_state() const { return link_state_; }
    void SetLinkState(LinkState link_state) { link_state_ = link_state; }

    bool Configure(const CellularBearer* bearer);
    void Start();
    void DestroySockets();

   private:
    std::string LoggingTag();

    Cellular* cellular_;
    RpcIdentifier bearer_path_;
    std::unique_ptr<Network> network_;
    LinkState link_state_ = LinkState::kUnknown;
    // Start options and network config only set after a successful
    // Configure() operation.
    Network::StartOptions start_opts_;
    std::optional<net_base::NetworkConfig> network_config_;
  };

  // Connection associated to the PDN with APN type "default". In Cellular
  // devices this will always be treated as primary network (e.g. when
  // returning a Network in GetPrimaryNetwork()).
  std::unique_ptr<NetworkInfo> default_pdn_;

  // The APN type of the default PDN will always be kDefault, unless we've
  // connected DUN as DEFAULT, in which case it will be kDun. It is required
  // to keep this value cached because we need to compare it with the connected
  // bearer reported by ModemManager. This variable cannot be part of the
  // |default_pdn_| struct, because it must outlive the creation and destruction
  // of the corresponding Network (e.g. when modem goes unregistered). It should
  // be considered a prerequisite to be be able to create the NetworkInfo, never
  // part of it.
  std::optional<ApnList::ApnType> default_pdn_apn_type_;

  // Connection associated to the PDN with APN type "dun".
  // Resetting this unique pointer will trigger a tethering network release
  // operation because the inner Network is stopped and TetheringManager will be
  // notified about it. We rely on this unique pointer being nullptr by the time
  // the tethering network release happens, which is something we cannot
  // guarantee if this were a std::optional (b/305685718).
  std::unique_ptr<NetworkInfo> multiplexed_tethering_pdn_;

  struct LocationInfo {
    std::string mcc;
    std::string mnc;
    std::string lac;
    std::string ci;
  };
  LocationInfo location_info_;

  // Network Operator info object. This object receives updates as we receive
  // information about the network operators from the SIM or OTA. In turn, it
  // sends out updates through its observer interface whenever the identity of
  // the network operator changes, or any other property of the operator
  // changes.
  std::unique_ptr<MobileOperatorInfo> mobile_operator_info_;

  // Tethering operation
  std::optional<TetheringOperationInfo> tethering_operation_;

  // ///////////////////////////////////////////////////////////////////////////
  // All DBus Properties exposed by the Cellular device.
  const std::string dbus_service_;  // org.*.ModemManager*
  RpcIdentifier dbus_path_;         // ModemManager.Modem
  // Used because we currently expose |dbus_path| as a string property.
  std::string dbus_path_str_;

  Stringmap home_provider_;

  bool scanning_supported_ = false;
  std::string equipment_id_;
  std::string esn_;
  std::string firmware_revision_;
  std::string hardware_revision_;
  std::unique_ptr<DeviceId> device_id_;
  ModemType modem_type_ = ModemType::kUnknown;
  std::string imei_;
  std::string manufacturer_;
  std::string mdn_;
  std::string meid_;
  std::string min_;
  std::string model_id_;
  std::string mm_plugin_;
  uint32_t max_multiplexed_bearers_ = 1;
  bool scanning_ = false;
  bool internal_device_ = false;
  bool polling_location_ = false;
  base::CancelableOnceClosure poll_location_task_;

  std::string selected_network_;
  Stringmaps found_networks_;
  uint16_t scan_interval_ = 0;
  Stringmaps apn_list_;
  std::string primary_multiplexed_interface_;

  // Primary SIM properties.
  std::string eid_;  // SIM eID, aka eUICCID
  std::string iccid_;
  std::string imsi_;
  bool sim_present_ = false;

  // vector of SimProperties, ordered by slot.
  std::vector<SimProperties> sim_slot_properties_;
  int primary_sim_slot_ = -1;
  // vector of KeyValueStore dictionaries, emitted as Device.SIMSlotInfo.
  KeyValueStores sim_slot_info_;

  // End of DBus properties.
  // ///////////////////////////////////////////////////////////////////////////

  std::unique_ptr<CellularCapability3gpp> capability_;
  std::optional<InterfaceToProperties> initial_properties_;
  std::unique_ptr<CarrierEntitlement> carrier_entitlement_;

  net_base::ProcessManager* process_manager_;

  // The active CellularService instance for this Device. This will always be
  // set to a valid service instance.
  CellularServiceRefPtr service_;
  // When set in tests, |service_| is not created or destroyed by Cellular.
  CellularServiceRefPtr service_for_testing_;

  // User preference to allow or disallow roaming before M92. Used as a default
  // until Chrome ties its roaming toggle to Service.AllowRoaming (b/184375691)
  bool allow_roaming_ = false;

  // If an operator has no home network, then set this flag. This overrides
  // all other roaming preferences, and allows roaming unconditionally.
  bool policy_allow_roaming_ = true;

  bool provider_requires_roaming_ = false;

  // Chrome flags to enable setting the attach APN from the host
  bool use_attach_apn_ = false;

  // Reflects the Device property indicating that the modem is inhibted. The
  // property is not persisted and is reset to false when the modem starts.
  bool inhibited_ = false;

  // Track whether a user initiated scan is in prgoress (initiated via ::Scan)
  bool proposed_scan_in_progress_ = false;

  // Flag indicating that a disconnect has been explicitly requested.
  bool explicit_disconnect_ = false;

  std::unique_ptr<ExternalTask> ppp_task_;
  VirtualDeviceRefPtr ppp_device_;
  bool is_ppp_authenticating_ = false;
  bool force_init_eps_bearer_settings_ = true;

  std::unique_ptr<net_base::NetlinkSockDiag> socket_destroyer_;

  // Used to keep scanning=true while the Modem is restarting.
  // TODO(b/177588333): Make Modem and/or the MM dbus API more robust.
  base::CancelableOnceClosure scanning_clear_callback_;

  // If a Connect request occurs while the Modem is busy, do not connect
  // immediately, instead set |connect_pending_iccid_|. The connect will occur
  // after a delay once Scanning is set to false.
  std::string connect_pending_iccid_;
  base::CancelableOnceClosure connect_pending_callback_;
  // Used to cancel a pending connect while waiting for Modem registration.
  base::CancelableOnceClosure connect_cancel_callback_;
  // Stores the callback passed in |EntitlementCheck| when an entitlement check
  // is requested to |CarrierEntitlement|.
  EntitlementCheckResultCallback entitlement_check_callback_;
  // Stores the callback passed in |AcquireTetheringNetwork| to notify the
  // caller of an event related to the tethering session.
  TetheringManager::CellularUpstreamEventCallback tethering_event_callback_;
  // Legacy device storage identifier, used for removing legacy entry.
  std::string legacy_storage_id_;

  // A Map containing the last connection results. ICCID is used as the key.
  std::unordered_map<std::string, Error::Type>
      last_cellular_connection_results_;

  // A Map to maintain if subscription error was seen before. ICCID is used as
  // the key.
  std::unordered_map<std::string, bool> subscription_error_seen_;

  // The current step of the Stop process.
  std::optional<StopSteps> stop_step_;

  // When set in tests, a connection attempt doesn't attempt link establishment
  bool skip_establish_link_for_testing_ = false;

  // If the modem FW version supports the hotspot feature.
  bool firmware_supports_tethering_ = true;
  std::unique_ptr<net_base::RTNLListener> link_listener_;

  base::WeakPtrFactory<Cellular> weak_ptr_factory_{this};
};

}  // namespace shill

#endif  // SHILL_CELLULAR_CELLULAR_H_
