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

#include <zircon/assert.h>

#include <functional>
#include <memory>

#include <trace/event.h>

#include "logical_link.h"
#include "src/connectivity/bluetooth/core/bt-host/common/log.h"
#include "src/connectivity/bluetooth/core/bt-host/common/run_or_post.h"
#include "src/connectivity/bluetooth/core/bt-host/l2cap/basic_mode_rx_engine.h"
#include "src/connectivity/bluetooth/core/bt-host/l2cap/basic_mode_tx_engine.h"
#include "src/connectivity/bluetooth/core/bt-host/l2cap/enhanced_retransmission_mode_engines.h"
#include "src/lib/fxl/strings/string_printf.h"

namespace bt {
namespace l2cap {

Channel::Channel(ChannelId id, ChannelId remote_id, hci::Connection::LinkType link_type,
                 hci::ConnectionHandle link_handle, ChannelInfo info)
    : id_(id),
      remote_id_(remote_id),
      link_type_(link_type),
      link_handle_(link_handle),
      info_(info) {
  ZX_DEBUG_ASSERT(id_);
  ZX_DEBUG_ASSERT(link_type_ == hci::Connection::LinkType::kLE ||
                  link_type_ == hci::Connection::LinkType::kACL);
}

namespace internal {

fbl::RefPtr<ChannelImpl> ChannelImpl::CreateFixedChannel(ChannelId id,
                                                         fbl::RefPtr<internal::LogicalLink> link) {
  // A fixed channel's endpoints have the same local and remote identifiers.
  // Signaling channels use the default MTU (Core Spec v5.1, Vol 3, Part A, Section 4).
  return fbl::AdoptRef(
      new ChannelImpl(id, id, link, ChannelInfo::MakeBasicMode(kDefaultMTU, kDefaultMTU)));
}

fbl::RefPtr<ChannelImpl> ChannelImpl::CreateDynamicChannel(ChannelId id, ChannelId peer_id,
                                                           fbl::RefPtr<internal::LogicalLink> link,
                                                           ChannelInfo info) {
  return fbl::AdoptRef(new ChannelImpl(id, peer_id, link, info));
}

ChannelImpl::ChannelImpl(ChannelId id, ChannelId remote_id, fbl::RefPtr<internal::LogicalLink> link,
                         ChannelInfo info)
    : Channel(id, remote_id, link->type(), link->handle(), info),
      active_(false),
      dispatcher_(nullptr),
      link_(link) {
  ZX_ASSERT(link_);
  ZX_ASSERT_MSG(
      info_.mode == ChannelMode::kBasic || info_.mode == ChannelMode::kEnhancedRetransmission,
      "Channel constructed with unsupported mode: %hhu\n", info.mode);

  // B-frames for Basic Mode contain only an "Information payload" (v5.0 Vol 3, Part A, Sec 3.1)
  FrameCheckSequenceOption fcs_option = info_.mode == ChannelMode::kEnhancedRetransmission
                                            ? FrameCheckSequenceOption::kIncludeFcs
                                            : FrameCheckSequenceOption::kNoFcs;
  auto send_cb = [rid = remote_id, link, fcs_option](auto pdu) {
    async::PostTask(link->dispatcher(), [=, pdu = std::move(pdu)] {
      // |link| is expected to ignore this call and drop the packet if it has been closed.
      link->SendFrame(rid, *pdu, fcs_option);
    });
  };

  if (info_.mode == ChannelMode::kBasic) {
    rx_engine_ = std::make_unique<BasicModeRxEngine>();
    tx_engine_ = std::make_unique<BasicModeTxEngine>(id, max_tx_sdu_size(), send_cb);
  } else {
    // Must capture |link| and not |link_| to avoid having to take |mutex_|.
    auto connection_failure_cb = [this, link] {
      ZX_ASSERT(thread_checker_.IsCreationThreadCurrent());

      // This isn't called until Channel has been activated and the callback is destroyed by
      // Deactivate, so even without taking |mutex_| we know that the channel is active. However,
      // this may be called from a locked context in HandleRxPdu, so defer the signal to after the
      // critical section so that we don't deadlock when removing this channel.
      async::PostTask(link->dispatcher(), [link] {
        // |link| is expected to ignore this call if it has been closed.
        link->SignalError();
      });
    };
    std::tie(rx_engine_, tx_engine_) = MakeLinkedEnhancedRetransmissionModeEngines(
        id, max_tx_sdu_size(), info_.max_transmissions, info_.n_frames_in_tx_window, send_cb,
        std::move(connection_failure_cb));
  }
}

const sm::SecurityProperties ChannelImpl::security() {
  std::lock_guard lock(mtx_);
  if (link_) {
    return link_->security();
  }
  return sm::SecurityProperties();
}

bool ChannelImpl::ActivateWithDispatcher(RxCallback rx_callback, ClosedCallback closed_callback,
                                         async_dispatcher_t* dispatcher) {
  ZX_DEBUG_ASSERT(rx_callback);
  ZX_DEBUG_ASSERT(closed_callback);

  fit::closure task;
  bool run_task = false;

  {
    std::lock_guard lock(mtx_);

    // Activating on a closed link has no effect. We also clear this on
    // deactivation to prevent a channel from being activated more than once.
    if (!link_)
      return false;

    ZX_DEBUG_ASSERT(!active_);
    active_ = true;
    ZX_DEBUG_ASSERT(!dispatcher_);
    dispatcher_ = dispatcher;
    rx_cb_ = std::move(rx_callback);
    closed_cb_ = std::move(closed_callback);

    // Route the buffered packets.
    if (!pending_rx_sdus_.empty()) {
      run_task = true;
      task = [func = rx_cb_.share(), pending = std::move(pending_rx_sdus_)]() mutable {
        TRACE_DURATION("bluetooth", "ChannelImpl::ActivateWithDispatcher pending drain");
        while (!pending.empty()) {
          TRACE_FLOW_END("bluetooth", "ChannelImpl::HandleRxPdu queued", pending.size());
          func(std::move(pending.front()));
          pending.pop();
        }
      };
      ZX_DEBUG_ASSERT(pending_rx_sdus_.empty());
    }
  }

  if (run_task) {
    RunOrPost(std::move(task), dispatcher);
  }

  return true;
}

bool ChannelImpl::ActivateOnDataDomain(RxCallback rx_callback, ClosedCallback closed_callback) {
  return ActivateWithDispatcher(std::move(rx_callback), std::move(closed_callback), nullptr);
}

void ChannelImpl::Deactivate() {
  std::lock_guard lock(mtx_);

  // De-activating on a closed link has no effect.
  if (!link_ || !active_) {
    link_ = nullptr;
    return;
  }

  active_ = false;
  dispatcher_ = nullptr;
  rx_cb_ = {};
  closed_cb_ = {};
  rx_engine_ = {};
  tx_engine_ = {};

  // Tell the link to release this channel on its thread.
  async::PostTask(link_->dispatcher(), [this, link = link_] {
    // |link| is expected to ignore this call if it has been closed.
    link->RemoveChannel(this);
  });

  link_ = nullptr;
}

void ChannelImpl::SignalLinkError() {
  std::lock_guard lock(mtx_);

  // Cannot signal an error on a closed or deactivated link.
  if (!link_ || !active_)
    return;

  async::PostTask(link_->dispatcher(), [link = link_] {
    // |link| is expected to ignore this call if it has been closed.
    link->SignalError();
  });
}

bool ChannelImpl::Send(ByteBufferPtr sdu) {
  ZX_DEBUG_ASSERT(sdu);

  std::lock_guard lock(mtx_);
  TRACE_DURATION("bluetooth", "l2cap:channel_send", "handle", link_->handle(), "id", id());

  if (!link_) {
    bt_log(ERROR, "l2cap", "cannot send SDU on a closed link");
    return false;
  }

  // Drop the packet if the channel is inactive.
  if (!active_)
    return false;

  return tx_engine_->QueueSdu(std::move(sdu));
}

void ChannelImpl::UpgradeSecurity(sm::SecurityLevel level, sm::StatusCallback callback,
                                  async_dispatcher_t* dispatcher) {
  ZX_ASSERT(callback);
  ZX_ASSERT(dispatcher);

  std::lock_guard lock(mtx_);

  if (!link_ || !active_) {
    bt_log(TRACE, "l2cap", "Ignoring security request on inactive channel");
    return;
  }

  async::PostTask(link_->dispatcher(),
                  [link = link_, level, callback = std::move(callback), dispatcher]() mutable {
                    link->UpgradeSecurity(level, std::move(callback), dispatcher);
                  });
}

void ChannelImpl::OnClosed() {
  async_dispatcher_t* dispatcher;
  fit::closure task;

  {
    std::lock_guard lock(mtx_);

    if (!link_ || !active_) {
      link_ = nullptr;
      return;
    }

    ZX_DEBUG_ASSERT(closed_cb_);
    dispatcher = dispatcher_;
    task = std::move(closed_cb_);
    active_ = false;
    link_ = nullptr;
    dispatcher_ = nullptr;
  }

  RunOrPost(std::move(task), dispatcher);
}

void ChannelImpl::HandleRxPdu(PDU&& pdu) {
  async_dispatcher_t* dispatcher;
  fit::closure task;

  {
    std::lock_guard lock(mtx_);
    TRACE_DURATION("bluetooth", "ChannelImpl::HandleRxPdu", "handle", link_->handle(), "channel_id",
                   id_);

    // link_ may be nullptr if a pdu is received after the channel has been deactivated but
    // before LogicalLink::RemoveChannel has been dispatched
    if (!link_) {
      bt_log(SPEW, "l2cap", "ignoring pdu on deactivated channel");
      return;
    }

    ZX_DEBUG_ASSERT(rx_engine_);

    ByteBufferPtr sdu = rx_engine_->ProcessPdu(std::move(pdu));
    if (!sdu) {
      // The PDU may have been invalid, out-of-sequence, or part of a segmented
      // SDU.
      // * If invalid, we drop the PDU (per Core Spec Ver 5, Vol 3, Part A,
      //   Secs. 3.3.6 and/or 3.3.7).
      // * If out-of-sequence or part of a segmented SDU, we expect that some
      //   later call to ProcessPdu() will return us an SDU containing this
      //   PDU's data.
      return;
    }

    // Buffer the packets if the channel hasn't been activated.
    if (!active_) {
      pending_rx_sdus_.emplace(std::move(sdu));
      // Tracing: we assume pending_rx_sdus_ is only filled once and use the length of queue
      // for trace ids.
      TRACE_FLOW_BEGIN("bluetooth", "ChannelImpl::HandleRxPdu queued", pending_rx_sdus_.size());
      return;
    }

    trace_flow_id_t trace_id = TRACE_NONCE();
    TRACE_FLOW_BEGIN("bluetooth", "ChannelImpl::HandleRxPdu callback", trace_id);

    dispatcher = dispatcher_;
    task = [func = rx_cb_.share(), sdu = std::move(sdu), trace_id]() mutable {
      TRACE_DURATION("bluetooth", "ChannelImpl::HandleRxPdu callback task");
      TRACE_FLOW_END("bluetooth", "ChannelImpl::HandleRxPdu callback", trace_id);
      func(std::move(sdu));
    };

    ZX_DEBUG_ASSERT(rx_cb_);
  }
  RunOrPost(std::move(task), dispatcher);
}

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