// 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 <string>

#include <base/basictypes.h>
#include <base/callback.h>
#include <base/cancelable_callback.h>
#include <base/compiler_specific.h>
#include <base/memory/scoped_ptr.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 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 endpoint_address,
                               const uint8* 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.
  virtual void OnUsbDeviceAdded(const std::string& sys_path,
                                uint8 bus_number,
                                uint8 device_address,
                                uint16 vendor_id,
                                uint16 product_id) OVERRIDE;
  virtual void OnUsbDeviceRemoved(const std::string& sys_path) OVERRIDE;

  Context* const context_;
  scoped_ptr<UsbModemSwitchContext> switch_context_;
  scoped_ptr<UsbDevice> device_;
  CompletionCallback completion_callback_;
  bool interface_claimed_;
  uint8 interface_number_;
  uint8 in_endpoint_address_;
  uint8 out_endpoint_address_;
  int message_index_;
  int num_usb_messages_;
  scoped_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_
