// Copyright (c) 2013 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 MIST_USB_MODEM_SWITCH_OPERATION_H_
#define MIST_USB_MODEM_SWITCH_OPERATION_H_

#include <stdint.h>

#include <memory>
#include <string>

#include <base/callback.h>
#include <base/cancelable_callback.h>
#include <base/macros.h>
#include <base/memory/weak_ptr.h>
#include <base/time/time.h>

#include "mist/usb_device_event_observer.h"

namespace mist {

class Context;
class UsbBulkTransfer;
class UsbDevice;
class UsbModemInfo;
class UsbModemSwitchContext;
class UsbTransfer;

// A USB modem switch operation for switching a USB modem into the modem mode.
// The whole operation involves the following tasks:
// 1. Open the USB modem device. If the modem has a USB configuration that
//    exposes a MBIM interface, select that configuration and complete the
//    switch operation. Otherwise, find and claim the mass storage interface of
//    the mdoem.
// 2. Initiate a bulk output transfer of a (or multiple) special USB message(s)
//    to the mass storage endpoint of the modem.
// 3. On some modems, a bulk input transfer from the mass storage endpoint of
//    the modem is expected after completing each bulk output transfer.
// 4. Once the transfer of the last message completes, the modem is expected to
//    disconnect from the USB bus and then reconnect to the bus after it has
//    been switched to the modem mode.
//
// As mist may run multiple modem switch operations concurrently, in order to
// maximize the overall concurrency, the modem switch operation is broken up
// into the aforementioned tasks and each task is scheduled to execute in the
// message loop via EventDispatcher.
class UsbModemSwitchOperation
    : public base::SupportsWeakPtr<UsbModemSwitchOperation>,
      public UsbDeviceEventObserver {
 public:
  using CompletionCallback =
      base::Callback<void(UsbModemSwitchOperation* operation, bool success)>;

  // Constructs a UsbModemSwitchOperation object by taking a raw pointer to a
  // Context object as |context| and a raw pointer to a UsbModemSwitchContext
  // object as |switch_context| that contains information about the device to
  // be switched to the modem mode. The ownership of |context| is not
  // transferred, and thus it should outlive this object. The ownership of
  // |switch_context| is transferred.
  UsbModemSwitchOperation(Context* context,
                          UsbModemSwitchContext* switch_context);

  ~UsbModemSwitchOperation();

  // Starts the modem switch operation. Upon the completion of the operation,
  // the completion callback |completion_callback| is invoked with the status
  // of the operation.
  void Start(const CompletionCallback& completion_callback);

  // Cancels the modem switch operation and closes any open device. It is a
  // no-op if the operation has not been started by Start().
  void Cancel();

 private:
  using Task = void (UsbModemSwitchOperation::*)();
  using UsbTransferCompletionHandler =
      void (UsbModemSwitchOperation::*)(UsbTransfer* transfer);

  // Schedules the specified |task| in the message loop for execution. At most
  // one pending task is allowed, so any pending task previously scheduled by
  // ScheduleTask() or ScheduleDelayedTask() is cancelled before |task| is
  // scheduled.
  void ScheduleTask(Task task);

  // Schedules the specified |task| in the message loop for execution after the
  // specified |delay|. At most one pending task is allowed, so any pending
  // task previously scheduled by ScheduleTask() or ScheduleDelayedTask() is
  // cancelled before |task| is scheduled.
  void ScheduleDelayedTask(Task task, const base::TimeDelta& delay);

  // Completes the operation, which invokes the completion callback with the
  // status of the operation as |success|. The completion callback may delete
  // this object, so this object should not be accessed after this method
  // returns.
  void Complete(bool success);

  // Detaches all the kernel drivers associated with the interfaces of the
  // currently active USB configuration. Continues to detach other kernel
  // drivers if it fails to detach any driver.
  void DetachAllKernelDrivers();

  // Returns the value of the USB configuration at which the device exposes a
  // MBIM interface, or kUsbConfigurationValueInvalid if no MBIM interface is
  // found.
  int GetMBIMConfigurationValue();

  // Sets the USB configuration of the device to |configuration|. Returns true
  // on success.
  bool SetConfiguration(int configuration);

  // Closes the device.
  void CloseDevice();

  // Opens the device. If the device has a USB configuration that exposes a MBIM
  // interface, selects that configuration and completes the switch operation.
  // Otherwise, finds and claims the mass storage interface on the device.
  void OpenDeviceAndSelectInterface();

  // Clears the halt condition on the endpoint at |endpoint_address|. Returns
  // true on success.
  bool ClearHalt(uint8_t endpoint_address);

  // Sends a special USB message to the mass storage endpoint of the device.
  void SendMessageToMassStorageEndpoint();

  // Receives a USB message from the mass storage endpoint of the device.
  void ReceiveMessageFromMassStorageEndpoint();

  // Creates and submits a USB bulk transfer to the specified |endpoint_address|
  // on the device. |length| specifies the size of the transfer in bytes. For a
  // host-to-device transfer, |data| should point to a buffer containing
  // |length| bytes of data to be transferred. For a device-to-host transfer,
  // |data| is not used and thus ignored. |completion_handler| will be invoked
  // upon the completion of the transfer.
  void InitiateUsbBulkTransfer(uint8_t endpoint_address,
                               const uint8_t* data,
                               int length,
                               UsbTransferCompletionHandler completion_handler);

  // Schedules the invocation of SendMessageToMassStorageEndpoint() on the next
  // USB message to be sent to the mass storage endpoint of the device, or when
  // there is no more message to send, schedule the wait for the device to
  // reconnect.
  void ScheduleNextMessageToMassStorageEndpoint();

  // Starts waiting for the device to reconnect to the USB bus.
  void StartWaitingForDeviceToReconnect();

  // Invoked upon the completion of the last USB bulk transfer submitted by
  // SendMessageToMassStorageEndpoint().
  void OnSendMessageCompleted(UsbTransfer* transfer);

  // Invoked upon the completion of the last USB bulk transfer submitted by
  // ReceiveMessageFromMassStorageEndpoint().
  void OnReceiveMessageCompleted(UsbTransfer* transfer);

  // Invoked when this switcher times out waiting for the device to reconnect
  // to the bus, after a specified period time since
  // StartWaitingForDeviceToReconnect() is invoked.
  void OnReconnectTimeout();

  // Implements UsbDeviceEventObserver.
  void OnUsbDeviceAdded(const std::string& sys_path,
                        uint8_t bus_number,
                        uint8_t device_address,
                        uint16_t vendor_id,
                        uint16_t product_id) override;
  void OnUsbDeviceRemoved(const std::string& sys_path) override;

  Context* const context_;
  std::unique_ptr<UsbModemSwitchContext> switch_context_;
  std::unique_ptr<UsbDevice> device_;
  CompletionCallback completion_callback_;
  bool interface_claimed_;
  uint8_t interface_number_;
  uint8_t in_endpoint_address_;
  uint8_t out_endpoint_address_;
  int message_index_;
  int num_usb_messages_;
  std::unique_ptr<UsbBulkTransfer> bulk_transfer_;
  base::CancelableClosure pending_task_;
  base::CancelableClosure reconnect_timeout_callback_;

  DISALLOW_COPY_AND_ASSIGN(UsbModemSwitchOperation);
};

}  // namespace mist

#endif  // MIST_USB_MODEM_SWITCH_OPERATION_H_
