// Copyright 2018 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_DYNAMIC_CHANNEL_REGISTRY_H_
#define SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_L2CAP_DYNAMIC_CHANNEL_REGISTRY_H_

#include <lib/fit/function.h>

#include <unordered_map>

#include "src/connectivity/bluetooth/core/bt-host/l2cap/dynamic_channel.h"
#include "src/connectivity/bluetooth/core/bt-host/l2cap/signaling_channel.h"

namespace bt {
namespace l2cap {
namespace internal {

// Base class for registries of dynamic L2CAP channels. It serves both as the
// factory and owner of dynamic channels created on a logical link, including
// assigning and tracking dynamic channel IDs.
//
// Registry entries are DynamicChannels that do not implement the l2cap::Channel
// interface used for user data transfer.
//
// This class is not thread-safe and is intended to be created and run on the
// L2CAP thread for each logical link connected.
class DynamicChannelRegistry {
 public:
  // Used to pass an optional channel to clients of the registry. |channel| may
  // be nullptr upon failure to open. Otherwise, it points to an instance owned
  // by the registry and should not be retained by the callee.
  using DynamicChannelCallback =
      fit::function<void(const DynamicChannel* channel)>;

  // Used to query the upper layers for the presence of a service that is
  // accepting channels. If the service exists, it should return a callback
  // that accepts the inbound dynamic channel opened.
  using ServiceRequestCallback = fit::function<DynamicChannelCallback(PSM psm)>;

  virtual ~DynamicChannelRegistry();

  // Create and connect a dynamic channel. The result will be returned by
  // calling |open_cb| on the L2CAP thread the channel is ready for data
  // transfer, with a nullptr if unsuccessful. The DynamicChannel passed will
  // contain the local and remote channel IDs to be used for user data transfer
  // over the new channel.
  void OpenOutbound(PSM psm, DynamicChannelCallback open_cb);

  // Disconnect and remove the channel identified by |local_cid|. After this
  // call completes, incoming PDUs with |local_cid| should be discarded as in
  // error or considered to belong to a subsequent channel with that ID. Any
  // outbound PDUs passed to the Channel interface for this channel should be
  // discarded. The internal channel will be immediately destroyed and
  // |local_cid| may be recycled for another dynamic channel.
  //
  // TODO(xow): Maybe take a DynamicChannel* to have greater confidence over the
  // instance of DynamicChannel being deleted (similar to
  // |LogicalLink::RemoveChannel|)?
  void CloseChannel(ChannelId local_cid);

 protected:
  // |largest_channel_id| is the greatest dynamic channel ID that can be
  // allocated on this link and must be at least |kFirstDynamicChannelId|.
  //
  // |close_cb| will be called upon a remote-initiated closure of an open
  // channel. The registry's internal channel is passed as a parameter, and it
  // will be closed for user data transfer before the callback fires. When the
  // callback returns, the channel is destroyed and its ID may be recycled for
  // another dynamic channel. Channels that fail to open due to error or are
  // closed using CloseChannel will not trigger this callback.
  //
  // |service_request_cb| will be called upon remote-initiated channel requests.
  // For services accepting channels, it shall return a callback to accept the
  // opened channel, which only be called if the channel successfully opens. To
  // deny the channel creation, |service_request_cb| should return a nullptr.
  DynamicChannelRegistry(ChannelId largest_channel_id_,
                         DynamicChannelCallback close_cb,
                         ServiceRequestCallback service_request_cb);

  // Factory method for a DynamicChannel implementation that represents an
  // outbound channel with an endpoint on this device identified by |local_cid|.
  virtual DynamicChannelPtr MakeOutbound(PSM psm, ChannelId local_cid) = 0;

  // Factory method for a DynamicChannel implementation that represents an
  // inbound channel from a remote endpoint identified by |remote_cid| to an
  // endpoint on this device identified by |local_cid|.
  virtual DynamicChannelPtr MakeInbound(PSM psm, ChannelId local_cid,
                                        ChannelId remote_cid) = 0;

  // Open an inbound channel for a service |psm| from the remote endpoint
  // identified by |remote_cid| to the local endpoint by |local_cid|.
  DynamicChannel* RequestService(PSM psm, ChannelId local_cid,
                                 ChannelId remote_cid);

  // Starting at kFirstDynamicChannelId and ending on |largest_channel_id_|
  // (inclusive), search for the next dynamic channel ID available on this link.
  // Returns kInvalidChannelId if all IDs have been exhausted.
  ChannelId FindAvailableChannelId() const;

  // Returns null if not found. Can be downcast to the derived DynamicChannel
  // created by MakeOutbound.
  DynamicChannel* FindChannel(ChannelId local_cid) const;

 private:
  friend class DynamicChannel;

  // Open a newly-created channel. If |pass_failed| is true, always invoke
  // |open_cb| with the result of the operation, including with nullptr if the
  // channel failed to open. Otherwise if |pass_failed| is false, only invoke
  // |open_cb| for successfully-opened channels.
  void ActivateChannel(DynamicChannel* channel, DynamicChannelCallback open_cb,
                       bool pass_failed);

  // Signal a remote-initiated closure of a channel owned by this registry, then
  // delete it. |close_cb_| is invoked if the channel was ever open (see
  // |DynamicChannel::opened|).
  void OnChannelDisconnected(DynamicChannel* channel);

  // Delete a channel owned by this registry. Then, after this returns,
  // |local_cid| may be recycled for another dynamic channel.
  void RemoveChannel(DynamicChannel* channel);

  // Greatest dynamic channel ID that can be assigned on the kind of logical
  // link associated to this registry.
  const ChannelId largest_channel_id_;

  // Called only for channels that were already open (see
  // |DynamicChannel::opened|).
  DynamicChannelCallback close_cb_;
  ServiceRequestCallback service_request_cb_;

  // Maps local CIDs to alive dynamic channels on this logical link.
  std::unordered_map<ChannelId, DynamicChannelPtr> channels_;

  DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(DynamicChannelRegistry);
};

}  // namespace internal
}  // namespace l2cap
}  // namespace bt

#endif  // SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_L2CAP_DYNAMIC_CHANNEL_REGISTRY_H_
