// 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 SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_L2CAP_CHANNEL_MANAGER_H_
#define SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_L2CAP_CHANNEL_MANAGER_H_

#include <lib/async/dispatcher.h>
#include <zircon/compiler.h>

#include <memory>
#include <mutex>
#include <unordered_map>

#include <fbl/macros.h>
#include <trace/event.h>

#include "src/connectivity/bluetooth/core/bt-host/hci/acl_data_channel.h"
#include "src/connectivity/bluetooth/core/bt-host/hci/acl_data_packet.h"
#include "src/connectivity/bluetooth/core/bt-host/hci/connection.h"
#include "src/connectivity/bluetooth/core/bt-host/hci/hci.h"
#include "src/connectivity/bluetooth/core/bt-host/l2cap/channel.h"
#include "src/connectivity/bluetooth/core/bt-host/l2cap/l2cap.h"
#include "src/connectivity/bluetooth/core/bt-host/l2cap/le_signaling_channel.h"
#include "src/connectivity/bluetooth/core/bt-host/l2cap/types.h"
#include "src/lib/fxl/synchronization/thread_checker.h"

namespace bt {

namespace hci {
class Transport;
}  // namespace hci

namespace l2cap {

namespace internal {
class LogicalLink;
}  // namespace internal

// ChannelManager implements the "Channel Manager" control block of L2CAP. In
// particular:
//
//   * It acts as a routing table for incoming ACL data by directing packets to
//     the appropriate internal logical link handler;
//
//   * Manages priority based scheduling.
//
//   * Provides an API surface for L2CAP channel creation and logical link
//     management bound to a single creation thread.
//
// There can be a single instance of ChannelManager for a HCI transport.
//
// THREAD-SAFETY:
//
// This object is not thread safe. Construction/destruction must happen on the
// thread where this is used.
class ChannelManager final {
 public:
  using LinkErrorCallback = fit::closure;

  // Used to schedule a series of packets on the link type |ll_type| to be transmitted to the
  // controller's ACL endpoint. All the packets in each invocation must be transmitted contiguously
  // and in order. This will be called on the thread which the ChannelManager object is created, up
  // to the object's duration.
  using SendAclCallback =
      fit::function<bool(LinkedList<hci::ACLDataPacket> packets, ChannelId channel_id,
                         hci::ACLDataChannel::PacketPriority priority)>;

  // Used to drop stale queued ACL data packets for which |predicate| returns true (eg. when a
  // channel is closed). Queued ACL data packets are those that were sent with |SendAclCallback| but
  // not have not yet been transmitted to the controller.
  using DropQueuedAclCallback = fit::function<void(hci::ACLPacketPredicate predicate)>;

  // Creates L2CAP state for logical links and channels.
  //
  // |max_acl_payload_size| and |max_le_payload_size| are the "maximum size[s] of HCI ACL (excluding
  // header) Data Packets... sent from the Host to the Controller" (Core v5.0 Vol 2, Part E, Section
  // 4.1) used for fragmenting outbound data. Data that is fragmented will be passed contiguously as
  // invocations of |send_packets_cb|.
  //
  // State changes are processed on |l2cap_dispatcher|.
  ChannelManager(size_t max_acl_payload_size, size_t max_le_payload_size,
                 SendAclCallback send_acl_cb, DropQueuedAclCallback filter_acl_cb,
                 async_dispatcher_t* l2cap_dispatcher);
  ~ChannelManager();

  // Returns a handler for data packets received from the Bluetooth controller bound to this object.
  // It must be called from the creation thread, but it is safe to call past ChannelManager's
  // lifetime.
  hci::ACLPacketHandler MakeInboundDataHandler();

  // Registers the ACL connection with the L2CAP layer. L2CAP channels can be
  // opened on the logical link represented by |handle| after a call to this
  // method.
  //
  // |link_error_callback| will be used to notify when a channel signals a link
  // error.
  //
  // |security_callback| will be used to request an upgrade to the link security
  // level. This can be triggered by dynamic L2CAP channel creation or by a
  // service-level client via Channel::UpgradeSecurity().
  //
  // It is an error to register the same |handle| value more than once as either
  // kind of channel without first unregistering it (asserted in debug builds).
  void RegisterACL(hci::ConnectionHandle handle, hci::Connection::Role role,
                   LinkErrorCallback link_error_callback,
                   SecurityUpgradeCallback security_callback);

  // Registers a LE connection with the L2CAP layer. L2CAP channels can be
  // opened on the logical link represented by |handle| after a call to this
  // method.
  //
  // |conn_param_callback| will be used to notify the caller if new connection
  // parameters were accepted from the remote end of the link.
  //
  // |link_error_callback| will be used to notify when a channel signals a link
  // error.
  //
  // |security_callback| will be used to request an upgrade to the link security
  // level. This can be triggered by dynamic L2CAP channel creation or by a
  // service-level client via Channel::UpgradeSecurity().
  //
  // It is an error to register the same |handle| value more than once as either
  // kind of channel without first unregistering it (asserted in debug builds).
  void RegisterLE(hci::ConnectionHandle handle, hci::Connection::Role role,
                  LEConnectionParameterUpdateCallback conn_param_callback,
                  LinkErrorCallback link_error_callback, SecurityUpgradeCallback security_callback);

  // Removes a connection. All incoming data packets on this link will be dropped. If the
  // connection was previously registered, all corresponding Channels will be closed.
  //
  // NOTE: It is recommended that a link entry be removed AFTER the controller
  // sends a HCI Disconnection Complete Event for the corresponding logical
  // link. This is to prevent incorrectly buffering data if the controller has
  // more packets to send after removing the link entry.
  void Unregister(hci::ConnectionHandle handle);

  // Assigns the security level of a logical link. Has no effect if |handle| has
  // not been previously registered or the link is closed.
  void AssignLinkSecurityProperties(hci::ConnectionHandle handle, sm::SecurityProperties security);

  // Opens the L2CAP fixed channel with |channel_id| over the logical link
  // identified by |connection_handle| and starts routing packets. Returns
  // nullptr if the channel is already open.
  fbl::RefPtr<Channel> OpenFixedChannel(hci::ConnectionHandle connection_handle,
                                        ChannelId channel_id);

  // Opens an out-bound connection-oriented L2CAP channel on the link specified by |handle| to the
  // requested |psm| with the preferred parameters |params|.
  // Returns a channel asynchronously via |callback| (posted on the given |dispatcher|).
  void OpenChannel(hci::ConnectionHandle handle, PSM psm, ChannelParameters params,
                   ChannelCallback cb, async_dispatcher_t* dispatcher);

  // Register/Unregister a callback for incoming service connections.
  // Incoming channels will be configured using using the preferred parameters |params|.
  bool RegisterService(PSM psm, ChannelParameters params, ChannelCallback cb,
                       async_dispatcher_t* dispatcher);
  void UnregisterService(PSM psm);

  // Information stored and returned for registered services that is needed to configure and forward
  // new channels for this service.
  using ServiceInfo = ServiceInfo<ChannelCallback>;

  // Returns mapping of ChannelId -> PacketPriority for use with ACLDataChannel::SendPacket.
  static hci::ACLDataChannel::PacketPriority ChannelPriority(ChannelId id);

  // Send a Connection Parameter Update Request on the LE signaling channel. When the Connection
  // Parameter Update Response is received, |request_cb| will be called on |dispatcher| and passed
  // the result, |accepted|.
  // NOTE: The local Host must be an LE slave, and this request should only be sent if the slave or
  // host does not support the Connection Parameters Request Link Layer Control Procedure (Core Spec
  // v5.2, Vol 3, Part A, Sec 4.20).
  void RequestConnectionParameterUpdate(hci::ConnectionHandle handle,
                                        hci::LEPreferredConnectionParameters params,
                                        ConnectionParameterUpdateRequestCallback request_cb,
                                        async_dispatcher_t* dispatcher);

 private:
  // Called when an ACL data packet is received from the controller. This method
  // is responsible for routing the packet to the corresponding LogicalLink.
  void OnACLDataReceived(hci::ACLDataPacketPtr data_packet);

  // Called by the various Register functions. Returns a pointer to the newly
  // added link.
  internal::LogicalLink* RegisterInternal(hci::ConnectionHandle handle,
                                          hci::Connection::LinkType ll_type,
                                          hci::Connection::Role role, size_t max_payload_size);

  // If a service (identified by |psm|) requested has been registered, return a ServiceInfo object
  // containing preferred channel parameters and a callback that passes an inbound channel to the
  // registrant. The callback may be called repeatedly to pass multiple channels for |psm|, but
  // should not be stored because the service may be unregistered at a later time. Calls for
  // unregistered services return null.
  std::optional<ServiceInfo> QueryService(hci::ConnectionHandle handle, PSM psm);

  // Maximum sizes for data packet payloads from host to controller.
  const size_t max_acl_payload_size_;
  const size_t max_le_payload_size_;

  // Queues data packets to be delivered to the controller for a given link type.
  SendAclCallback send_acl_cb_;

  // Drops data packets pending delivery to the controller.
  DropQueuedAclCallback drop_queued_acl_cb_;

  async_dispatcher_t* l2cap_dispatcher_;

  using LinkMap = std::unordered_map<hci::ConnectionHandle, fbl::RefPtr<internal::LogicalLink>>;
  LinkMap ll_map_;

  // Stores packets received on a connection handle before a link for it has
  // been created.
  using PendingPacketMap =
      std::unordered_map<hci::ConnectionHandle, LinkedList<hci::ACLDataPacket>>;
  PendingPacketMap pending_packets_;

  // Store information required to create and forward channels for locally-
  // hosted services.
  using ServiceMap = std::unordered_map<PSM, ServiceInfo>;
  ServiceMap services_;

  fxl::ThreadChecker thread_checker_;
  fxl::WeakPtrFactory<ChannelManager> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(ChannelManager);
};

}  // namespace l2cap
}  // namespace bt

#endif  // SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_L2CAP_CHANNEL_MANAGER_H_
