// Copyright 2017 The Fuchsia 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 GARNET_DRIVERS_BLUETOOTH_LIB_HCI_TRANSPORT_H_
#define GARNET_DRIVERS_BLUETOOTH_LIB_HCI_TRANSPORT_H_

#include <atomic>
#include <memory>
#include <thread>

#include <lib/async/cpp/wait.h>
#include <lib/async/dispatcher.h>
#include <lib/async-loop/cpp/loop.h>

#include "garnet/drivers/bluetooth/lib/hci/acl_data_channel.h"
#include "garnet/drivers/bluetooth/lib/hci/command_channel.h"
#include "lib/fxl/macros.h"
#include "lib/fxl/memory/ref_counted.h"
#include "lib/fxl/memory/ref_ptr.h"
#include "lib/fxl/memory/weak_ptr.h"
#include "lib/fxl/synchronization/thread_checker.h"

namespace btlib {
namespace hci {

class DeviceWrapper;

// Represents the HCI transport layer. This object owns the HCI command, ACL,
// and SCO channels and provides the necessary control-flow mechanisms to send
// and receive HCI packets from the underlying Bluetooth controller.
//
// Transport expects to be initialized and shut down (via Initialize() and
// ShutDown()) on the same thread. ShutDown() MUST be called to guarantee clean
// up.
//
// TODO(armansito): This object has become too heavy-weight. I think it will be
// cleaner to have CommandChannel and ACLDataChannel each be owned directly by
// the main and L2CAP domains. Transport should go away as part of the HCI layer
// clean up (and also NET-388).
class Transport final : public fxl::RefCountedThreadSafe<Transport> {
 public:
  static fxl::RefPtr<Transport> Create(
      std::unique_ptr<DeviceWrapper> hci_device);

  // Initializes the HCI command channel and starts the I/O event loop.
  // I/O events are run on the dispatcher given, or a new I/O thread
  // is started if one is not given.
  //
  // The ACLDataChannel will be left uninitialized. The ACLDataChannel must be
  // initialized after available data buffer information has been obtained from
  // the controller (via HCI_Read_Buffer_Size and HCI_LE_Read_Buffer_Size).
  //
  // This method is NOT thread-safe! Care must be taken such that the public
  // methods of this class and those of the individual channel classes are not
  // called in a manner that would race with the execution of Initialize().
  bool Initialize(async_dispatcher_t* dispatcher = nullptr);

  // Initializes the ACL data channel with the given parameters. Returns false
  // if an error occurs during initialization. Initialize() must have been
  // called successfully prior to calling this method.
  bool InitializeACLDataChannel(const DataBufferInfo& bredr_buffer_info,
                                const DataBufferInfo& le_buffer_info);

  // Cleans up all transport channels, stops the I/O event loop, and joins the
  // I/O thread. Once a Transport has been shut down, it cannot be
  // re-initialized.
  //
  // NOTE: Care must be taken such that this method is not called from a thread
  // that would race with a call to Initialize(). ShutDown() is not thread-safe;
  // Initialize(), InitializeACLDataChannel(), and ShutDown() MUST be called on
  // the same thread.
  void ShutDown();

  // Returns true if this Transport has been fully initialized and running.
  bool IsInitialized() const;

  // Returns a pointer to the HCI command and event flow control handler.
  CommandChannel* command_channel() const { return command_channel_.get(); }

  // Returns a pointer to the HCI ACL data flow control handler.
  ACLDataChannel* acl_data_channel() const { return acl_data_channel_.get(); }

  // Returns the I/O thread dispatcher. If this is called when this Transport
  // instance is not initialized, the return value will be nullptr.
  async_dispatcher_t*  io_dispatcher() const {
    return io_dispatcher_;
  }

  // Set a callback that should be invoked when any one of the underlying
  // channels gets closed for any reason (e.g. the HCI device has disappeared)
  // and the dispatcher on which the callback should be posted.
  //
  // When this callback is called the channels will be in an invalid state and
  // packet processing is no longer guaranteed to work. It is the responsibility
  // of the callback implementation to clean up this Transport instance by
  // calling ShutDown() and/or deleting it.
  void SetTransportClosedCallback(fit::closure callback,
                                  async_dispatcher_t* dispatcher);

 private:
  FRIEND_REF_COUNTED_THREAD_SAFE(Transport);

  explicit Transport(std::unique_ptr<DeviceWrapper> hci_device);
  ~Transport();

  // Channel closed callback.
  void OnChannelClosed(async_dispatcher_t* dispatcher,
                       async::WaitBase* wait,
                       zx_status_t status,
                       const zx_packet_signal_t* signal);
  using Waiter = async::WaitMethod<Transport, &Transport::OnChannelClosed>;

  // Sets up a wait to watch for |channel| to close and calls OnChannelClosed
  void WatchChannelClosed(const zx::channel& channel, Waiter& wait);

  // Notifies the closed callback.
  void NotifyClosedCallback();

  // Used to assert that certain public functions are only called on the
  // creation thread.
  fxl::ThreadChecker thread_checker_;

  // The Bluetooth HCI device file descriptor.
  std::unique_ptr<DeviceWrapper> hci_device_;

  // The state of the initialization sequence.
  std::atomic_bool is_initialized_;

  // The loop that performs all HCI I/O operations. This is initialized with its
  // own separate thread.
  std::unique_ptr<async::Loop> io_loop_;

  // async::Waits for the command and ACL channels
  Waiter cmd_channel_wait_{this};
  Waiter acl_channel_wait_{this};

  // The dispatcher used for posting tasks on the HCI transport I/O thread.
  async_dispatcher_t* io_dispatcher_;

  // The ACL data flow control handler.
  std::unique_ptr<ACLDataChannel> acl_data_channel_;

  // The HCI command and event flow control handler.
  std::unique_ptr<CommandChannel> command_channel_;

  // Callback invoked when the transport is closed (due to a channel error) and
  // its dispatcher.
  fit::closure closed_cb_;
  async_dispatcher_t* closed_cb_dispatcher_;

  FXL_DISALLOW_COPY_AND_ASSIGN(Transport);
};

}  // namespace hci
}  // namespace btlib

#endif  // GARNET_DRIVERS_BLUETOOTH_LIB_HCI_TRANSPORT_H_
