// 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:
  typedef base::Callback<void(UsbModemSwitchOperation* operation, bool success)>
      CompletionCallback;

  // 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:
  typedef void (UsbModemSwitchOperation::*Task)();
  typedef void (UsbModemSwitchOperation::*UsbTransferCompletionHandler)(
      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();

  // 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 the special USB message(s) is sent to the mass storage
  // endpoint by SendMessageToMassStorageEndpoint().
  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_
