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

#include "channel_manager.h"

#include <lib/async/default.h>
#include <lib/trace/event.h>
#include <zircon/assert.h>

#include "logical_link.h"
#include "src/connectivity/bluetooth/core/bt-host/common/log.h"
#include "src/connectivity/bluetooth/lib/cpp-string/string_printf.h"

namespace bt::l2cap {

namespace {

constexpr const char* kInspectServicesNodeName = "services";
constexpr const char* kInspectServiceNodePrefix = "service_";
constexpr const char* kInspectLogicalLinksNodeName = "logical_links";
constexpr const char* kInspectLogicalLinkNodePrefix = "logical_link_";
constexpr const char* kInspectPsmPropertyName = "psm";

}  // namespace

ChannelManager::ChannelManager(hci::AclDataChannel* acl_data_channel, bool random_channel_ids)
    : acl_data_channel_(acl_data_channel),
      random_channel_ids_(random_channel_ids),
      executor_(async_get_default_dispatcher()),
      weak_ptr_factory_(this) {
  ZX_ASSERT(acl_data_channel_);
  max_acl_payload_size_ = acl_data_channel_->GetBufferInfo().max_data_length();
  max_le_payload_size_ = acl_data_channel_->GetLeBufferInfo().max_data_length();
  acl_data_channel_->SetDataRxHandler(MakeInboundDataHandler());
  bt_log(DEBUG, "l2cap", "initialized");
}

ChannelManager::~ChannelManager() {
  bt_log(DEBUG, "l2cap", "shutting down");
  ZX_DEBUG_ASSERT(thread_checker_.is_thread_valid());

  // Explicitly shut down all links to force associated L2CAP channels to
  // release their strong references.
  for (auto& [handle, link] : ll_map_) {
    link->Close();
  }
}

hci::ACLPacketHandler ChannelManager::MakeInboundDataHandler() {
  return [self = weak_ptr_factory_.GetWeakPtr()](auto packet) {
    if (self) {
      self->OnACLDataReceived(std::move(packet));
    }
  };
}

void ChannelManager::AddACLConnection(hci_spec::ConnectionHandle handle,
                                      hci_spec::ConnectionRole role,
                                      LinkErrorCallback link_error_cb,
                                      SecurityUpgradeCallback security_cb) {
  ZX_DEBUG_ASSERT(thread_checker_.is_thread_valid());
  bt_log(DEBUG, "l2cap", "register ACL link (handle: %#.4x)", handle);

  auto* ll = RegisterInternal(handle, bt::LinkType::kACL, role, max_acl_payload_size_);
  ll->set_error_callback(std::move(link_error_cb));
  ll->set_security_upgrade_callback(std::move(security_cb));
}

ChannelManager::LEFixedChannels ChannelManager::AddLEConnection(
    hci_spec::ConnectionHandle handle, hci_spec::ConnectionRole role,
    LinkErrorCallback link_error_cb, LEConnectionParameterUpdateCallback conn_param_cb,
    SecurityUpgradeCallback security_cb) {
  ZX_DEBUG_ASSERT(thread_checker_.is_thread_valid());
  bt_log(DEBUG, "l2cap", "register LE link (handle: %#.4x)", handle);

  auto* ll = RegisterInternal(handle, bt::LinkType::kLE, role, max_le_payload_size_);
  ll->set_error_callback(std::move(link_error_cb));
  ll->set_security_upgrade_callback(std::move(security_cb));
  ll->set_connection_parameter_update_callback(std::move(conn_param_cb));

  fbl::RefPtr<Channel> att = OpenFixedChannel(handle, kATTChannelId);
  fbl::RefPtr<Channel> smp = OpenFixedChannel(handle, kLESMPChannelId);
  ZX_ASSERT(att);
  ZX_ASSERT(smp);
  return LEFixedChannels{.att = std::move(att), .smp = std::move(smp)};
}

void ChannelManager::RemoveConnection(hci_spec::ConnectionHandle handle) {
  ZX_DEBUG_ASSERT(thread_checker_.is_thread_valid());

  bt_log(DEBUG, "l2cap", "unregister link (handle: %#.4x)", handle);

  pending_packets_.erase(handle);
  auto iter = ll_map_.find(handle);
  if (iter == ll_map_.end()) {
    bt_log(DEBUG, "l2cap", "attempt to unregister unknown link (handle: %#.4x)", handle);
    return;
  }

  // Explicitly shut down the link to force associated L2CAP channels to release
  // their strong references.
  iter->second->Close();
  ll_map_.erase(iter);
}

void ChannelManager::AssignLinkSecurityProperties(hci_spec::ConnectionHandle handle,
                                                  sm::SecurityProperties security) {
  ZX_DEBUG_ASSERT(thread_checker_.is_thread_valid());

  bt_log(DEBUG, "l2cap", "received new security properties (handle: %#.4x)", handle);

  auto iter = ll_map_.find(handle);
  if (iter == ll_map_.end()) {
    bt_log(DEBUG, "l2cap", "ignoring new security properties on unknown link");
    return;
  }

  iter->second->AssignSecurityProperties(security);
}

fbl::RefPtr<Channel> ChannelManager::OpenFixedChannel(hci_spec::ConnectionHandle handle,
                                                      ChannelId channel_id) {
  ZX_DEBUG_ASSERT(thread_checker_.is_thread_valid());

  auto iter = ll_map_.find(handle);
  if (iter == ll_map_.end()) {
    bt_log(ERROR, "l2cap", "cannot open fixed channel on unknown connection handle: %#.4x", handle);
    return nullptr;
  }

  return iter->second->OpenFixedChannel(channel_id);
}

void ChannelManager::OpenL2capChannel(hci_spec::ConnectionHandle handle, PSM psm,
                                      ChannelParameters params, ChannelCallback cb) {
  ZX_DEBUG_ASSERT(thread_checker_.is_thread_valid());

  auto iter = ll_map_.find(handle);
  if (iter == ll_map_.end()) {
    bt_log(ERROR, "l2cap", "Cannot open channel on unknown connection handle: %#.4x", handle);
    cb(nullptr);
    return;
  }

  iter->second->OpenChannel(psm, params, std::move(cb));
}

bool ChannelManager::RegisterService(PSM psm, ChannelParameters params, ChannelCallback cb) {
  ZX_DEBUG_ASSERT(thread_checker_.is_thread_valid());

  // v5.0 Vol 3, Part A, Sec 4.2: PSMs shall be odd and the least significant
  // bit of the most significant byte shall be zero
  if (((psm & 0x0001) != 0x0001) || ((psm & 0x0100) != 0x0000)) {
    return false;
  }

  auto iter = services_.find(psm);
  if (iter != services_.end()) {
    return false;
  }

  ServiceData service{.info = ServiceInfo(params, std::move(cb)), .psm = psm};
  service.AttachInspect(services_node_);
  services_.emplace(psm, std::move(service));
  return true;
}

void ChannelManager::UnregisterService(PSM psm) {
  FX_DCHECK(thread_checker_.is_thread_valid());

  services_.erase(psm);
}

void ChannelManager::RequestConnectionParameterUpdate(
    hci_spec::ConnectionHandle handle, hci_spec::LEPreferredConnectionParameters params,
    ConnectionParameterUpdateRequestCallback request_cb) {
  ZX_ASSERT(thread_checker_.is_thread_valid());

  auto iter = ll_map_.find(handle);
  if (iter == ll_map_.end()) {
    bt_log(DEBUG, "l2cap", "ignoring Connection Parameter Update request on unknown link");
    return;
  }

  iter->second->SendConnectionParameterUpdateRequest(params, std::move(request_cb));
}

void ChannelManager::AttachInspect(inspect::Node& parent, std::string name) {
  if (!parent) {
    return;
  }

  node_ = parent.CreateChild(name);

  services_node_ = node_.CreateChild(kInspectServicesNodeName);
  for (auto& [psm, service] : services_) {
    service.AttachInspect(services_node_);
  }

  ll_node_ = node_.CreateChild(kInspectLogicalLinksNodeName);
  for (auto& [_, ll] : ll_map_) {
    ll->AttachInspect(ll_node_, ll_node_.UniqueName(kInspectLogicalLinkNodePrefix));
  }
}

fxl::WeakPtr<internal::LogicalLink> ChannelManager::LogicalLinkForTesting(
    hci_spec::ConnectionHandle handle) {
  auto iter = ll_map_.find(handle);
  if (iter == ll_map_.end()) {
    return nullptr;
  }
  return iter->second->GetWeakPtr();
}

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

  auto handle = packet->connection_handle();
  TRACE_DURATION("bluetooth", "ChannelManager::OnDataReceived", "handle", handle);

  auto iter = ll_map_.find(handle);
  PendingPacketMap::iterator pp_iter;

  // If a LogicalLink does not exist, we set up a queue for its packets to be
  // delivered when the LogicalLink gets created.
  if (iter == ll_map_.end()) {
    pp_iter = pending_packets_.emplace(handle, LinkedList<hci::ACLDataPacket>()).first;
  } else {
    // A logical link exists. |pp_iter| will be valid only if the drain task has
    // not run yet (see ChannelManager::RegisterInternal()).
    pp_iter = pending_packets_.find(handle);
  }

  if (pp_iter != pending_packets_.end()) {
    packet->set_trace_id(TRACE_NONCE());
    TRACE_FLOW_BEGIN("bluetooth", "ChannelMaager::OnDataReceived queued", packet->trace_id());
    pp_iter->second.push_back(std::move(packet));
    bt_log(TRACE, "l2cap", "queued rx packet on handle: %#.4x", handle);
    return;
  }

  iter->second->HandleRxPacket(std::move(packet));
}

internal::LogicalLink* ChannelManager::RegisterInternal(hci_spec::ConnectionHandle handle,
                                                        bt::LinkType ll_type,
                                                        hci_spec::ConnectionRole role,
                                                        size_t max_payload_size) {
  ZX_DEBUG_ASSERT(thread_checker_.is_thread_valid());
  TRACE_DURATION("bluetooth", "ChannelManager::RegisterInternal", "handle", handle);

  // TODO(armansito): Return nullptr instead of asserting. Callers shouldn't
  // assume this will succeed.
  auto iter = ll_map_.find(handle);
  ZX_DEBUG_ASSERT_MSG(iter == ll_map_.end(), "connection handle re-used! (handle=%#.4x)", handle);

  auto ll = internal::LogicalLink::New(handle, ll_type, role, &executor_, max_payload_size,
                                       fit::bind_member<&ChannelManager::QueryService>(this),
                                       acl_data_channel_, random_channel_ids_);
  if (ll_node_) {
    ll->AttachInspect(ll_node_, ll_node_.UniqueName(kInspectLogicalLinkNodePrefix));
  }

  // Route all pending packets to the link.
  auto pp_iter = pending_packets_.find(handle);
  if (pp_iter != pending_packets_.end()) {
    auto& packets = pp_iter->second;
    while (!packets.is_empty()) {
      auto packet = packets.pop_front();
      TRACE_FLOW_END("bluetooth", "ChannelManager::OnDataReceived queued", packet->trace_id());
      ll->HandleRxPacket(std::move(packet));
    }
    pending_packets_.erase(pp_iter);
  }

  auto* ll_raw = ll.get();
  ll_map_[handle] = std::move(ll);

  return ll_raw;
}

std::optional<ChannelManager::ServiceInfo> ChannelManager::QueryService(
    hci_spec::ConnectionHandle handle, PSM psm) {
  auto iter = services_.find(psm);
  if (iter == services_.end()) {
    return std::nullopt;
  }

  // |channel_cb| will be called in LogicalLink. Each callback in |services_| already trampolines
  // to the appropriate dispatcher (passed to RegisterService).
  return ChannelManager::ServiceInfo(iter->second.info.channel_params,
                                     iter->second.info.channel_cb.share());
}

void ChannelManager::ServiceData::AttachInspect(inspect::Node& parent) {
  if (!parent) {
    return;
  }
  node = parent.CreateChild(parent.UniqueName(kInspectServiceNodePrefix));
  psm_property = node.CreateString(kInspectPsmPropertyName, PsmToString(psm));
}

}  // namespace bt::l2cap
