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

#include "garnet/drivers/bluetooth/lib/data/domain.h"

#include <fbl/macros.h>
#include <lib/async/cpp/task.h>

#include "garnet/drivers/bluetooth/lib/common/byte_buffer.h"
#include "garnet/drivers/bluetooth/lib/common/test_helpers.h"
#include "garnet/drivers/bluetooth/lib/testing/fake_controller_test.h"
#include "garnet/drivers/bluetooth/lib/testing/test_controller.h"

// This test harness provides test cases for interations between L2CAP, RFCOMM,
// and SocketFactory in integration, as they are implemented by the domain
// object. These exercise a production data plane against raw HCI endpoints.

namespace btlib {
namespace data {
namespace {

using ::btlib::testing::TestController;
using TestingBase = ::btlib::testing::FakeControllerTest<TestController>;

using common::CreateStaticByteBuffer;
using common::LowerBits;
using common::StaticByteBuffer;
using common::UpperBits;

class DATA_DomainTest : public TestingBase {
 public:
  DATA_DomainTest() = default;
  ~DATA_DomainTest() override = default;

 protected:
  void SetUp() override {
    TestingBase::SetUp();
    InitializeACLDataChannel();

    domain_ = Domain::CreateWithDispatcher(transport(), dispatcher());
    domain_->Initialize();

    StartTestDevice();
  }

  void TearDown() override {
    domain_->ShutDown();
    domain_ = nullptr;
    TestingBase::TearDown();
  }

  // TODO(armansito): Move this to the testing library. This should set up
  // expectations on the TestController and not just transmit.
  void EmulateIncomingChannelCreation(hci::ConnectionHandle link_handle,
                                      l2cap::ChannelId src_id,
                                      l2cap::ChannelId dst_id, l2cap::PSM psm) {
    // clang-format off
    test_device()->SendACLDataChannelPacket(CreateStaticByteBuffer(
        // ACL data header (handle: |link_handle|, length: 12 bytes)
        LowerBits(link_handle), UpperBits(link_handle), 0x0c, 0x00,

        // L2CAP B-frame header (length: 8 bytes, channel-id: 0x0001 (ACL sig))
        0x08, 0x00, 0x01, 0x00,

        // Connection Request (ID: 1, length: 4, |psm|, |src_id|)
        0x02, 0x01, 0x04, 0x00,
        LowerBits(psm), UpperBits(psm), LowerBits(src_id), UpperBits(src_id)));

    RunLoopUntilIdle();

    test_device()->SendACLDataChannelPacket(CreateStaticByteBuffer(
        // ACL data header (handle: |link_handle|, length: 16 bytes)
        LowerBits(link_handle), UpperBits(link_handle), 0x10, 0x00,

        // L2CAP B-frame header (length: 12 bytes, channel-id: 0x0001 (ACL sig))
        0x0c, 0x00, 0x01, 0x00,

        // Configuration Request (ID: 6, length: 8, |dst_id|, flags: 0,
        // options: [type: MTU, length: 2, MTU: 1024])
        0x04, 0x06, 0x08, 0x00,
        LowerBits(dst_id), UpperBits(dst_id), 0x00, 0x00,
        0x01, 0x02, 0x00, 0x04));

    test_device()->SendACLDataChannelPacket(CreateStaticByteBuffer(
        // ACL data header (handle: |link_handle|, length: 14 bytes)
        LowerBits(link_handle), UpperBits(link_handle), 0x0e, 0x00,

        // L2CAP B-frame header (length: 10 bytes, channel-id: 0x0001 (ACL sig))
        0x0a, 0x00, 0x01, 0x00,

        // Configuration Response (ID: 1, length: 6, src cid: |dst_id|, flags: 0,
        // result: success)
        0x05, 0x01, 0x06, 0x00,
        LowerBits(dst_id), UpperBits(dst_id), 0x00, 0x00,
        0x00, 0x00));
    // clang-format on

    RunLoopUntilIdle();
  }

  void ExpectOutgoingChannelCreation(hci::ConnectionHandle link_handle,
                                     l2cap::ChannelId remote_id,
                                     l2cap::ChannelId expected_local_cid,
                                     l2cap::PSM psm) {
    auto response_cb = [=](const auto& bytes) {
      ASSERT_LE(10u, bytes.size());
      EXPECT_EQ(LowerBits(link_handle), bytes[0]);
      EXPECT_EQ(UpperBits(link_handle), bytes[1]);
      l2cap::CommandCode code = bytes[8];
      auto id = bytes[9];
      switch (code) {
        case l2cap::kConnectionRequest: {
          ASSERT_EQ(16u, bytes.size());
          EXPECT_EQ(LowerBits(psm), bytes[12]);
          EXPECT_EQ(UpperBits(psm), bytes[13]);
          EXPECT_EQ(LowerBits(expected_local_cid), bytes[14]);
          EXPECT_EQ(UpperBits(expected_local_cid), bytes[15]);
          test_device()->SendACLDataChannelPacket(CreateStaticByteBuffer(
              // ACL data header (handle: |link handle|, length: 16 bytes)
              LowerBits(link_handle), UpperBits(link_handle), 0x10, 0x00,
              // L2CAP B-frame header: length 12, channel-id 1 (signaling)
              0x0c, 0x00, 0x01, 0x00,
              // Connection Response (0x03) id: (matches request), length 8
              l2cap::kConnectionResponse, id, 0x08, 0x00,
              // destination cid |remote_id|
              LowerBits(remote_id), UpperBits(remote_id),
              // source cid (same as request)
              bytes[14], bytes[15],
              // Result (success), status
              0x00, 0x00, 0x00, 0x00));
          return;
        }
        case l2cap::kConfigurationRequest: {
          ASSERT_LE(16u, bytes.size());
          // Just blindly accept any configuration request as long as it for our
          // cid
          EXPECT_EQ(LowerBits(remote_id), bytes[12]);
          EXPECT_EQ(UpperBits(remote_id), bytes[13]);
          // Respond to the given request, and make your own request.
          test_device()->SendACLDataChannelPacket(CreateStaticByteBuffer(
              // ACL header: handle |link_handle|, length: 18
              LowerBits(link_handle), UpperBits(link_handle), 0x12, 0x00,
              // L2CAP B-frame header: length 14, channel-id 1 (signaling)
              0x0e, 0x00, 0x01, 0x00,
              // Configuration Response (0x04), id: (match request) length 10
              l2cap::kConfigurationResponse, id, 0x0a, 0x00,
              // Source CID, Flags (same as req)
              LowerBits(expected_local_cid), UpperBits(expected_local_cid),
              bytes[14], bytes[15],
              // Result (success)
              0x00, 0x00,
              // Config option: MTU, length 2, MTU 1024
              0x01, 0x02, 0x00, 0x04));
          test_device()->SendACLDataChannelPacket(CreateStaticByteBuffer(
              // ACL data header (handle: |link_handle|, length: 16 bytes)
              LowerBits(link_handle), UpperBits(link_handle), 0x10, 0x00,

              // L2CAP B-frame header (length: 12 bytes, channel-id: 0x0001 (ACL
              // sig))
              0x0c, 0x00, 0x01, 0x00,

              // Configuration Request (ID: 6, length: 8, |dst_id|, flags: 0,
              // options: [type: MTU, length: 2, MTU: 1024])
              l2cap::kConfigurationRequest, 0x06, 0x08, 0x00,
              LowerBits(expected_local_cid), UpperBits(expected_local_cid),
              0x00, 0x00, 0x01, 0x02, 0x00, 0x04));
          return;
        }
        case l2cap::kConfigurationResponse: {
          ASSERT_LE(16u, bytes.size());
          // Should indicate our cid
          EXPECT_EQ(LowerBits(remote_id), bytes[12]);
          EXPECT_EQ(UpperBits(remote_id), bytes[13]);
          return;
        }
        default:
          ASSERT_TRUE(false);
          return;
      };
    };
    test_device()->SetDataCallback(response_cb, dispatcher());
  }

  Domain* domain() const { return domain_.get(); }

 private:
  fbl::RefPtr<Domain> domain_;

  DISALLOW_COPY_ASSIGN_AND_MOVE(DATA_DomainTest);
};

TEST_F(DATA_DomainTest, InboundL2capSocket) {
  constexpr l2cap::PSM kPSM = l2cap::kAVDTP;
  constexpr l2cap::ChannelId kLocalId = 0x0040;
  constexpr l2cap::ChannelId kRemoteId = 0x9042;
  constexpr hci::ConnectionHandle kLinkHandle = 0x0001;

  // Register a fake link.
  domain()->AddACLConnection(
      kLinkHandle, hci::Connection::Role::kMaster, [] {},
      [](auto, auto, auto) {}, dispatcher());

  zx::socket sock;
  ASSERT_FALSE(sock);
  auto sock_cb = [&](zx::socket cb_sock, hci::ConnectionHandle handle) {
    EXPECT_EQ(kLinkHandle, handle);
    sock = std::move(cb_sock);
  };

  domain()->RegisterService(kPSM, std::move(sock_cb), dispatcher());
  RunLoopUntilIdle();

  EmulateIncomingChannelCreation(kLinkHandle, kRemoteId, kLocalId, kPSM);
  ASSERT_TRUE(sock);

  // Test basic channel<->socket interaction by verifying that an ACL packet
  // gets routed to the socket.
  test_device()->SendACLDataChannelPacket(CreateStaticByteBuffer(
      // ACL data header (handle: 1, length 8)
      0x01, 0x00, 0x08, 0x00,

      // L2CAP B-frame: (length: 4, channel-id: 0x0040 (kLocalId))
      0x04, 0x00, 0x40, 0x00, 't', 'e', 's', 't'));

  // Run until the packet is written to the socket buffer.
  RunLoopUntilIdle();

  // Allocate a larger buffer than the number of SDU bytes we expect (which is
  // 4).
  StaticByteBuffer<10> socket_bytes;
  size_t bytes_read;
  zx_status_t status = sock.read(0, socket_bytes.mutable_data(),
                                 socket_bytes.size(), &bytes_read);
  EXPECT_EQ(ZX_OK, status);
  ASSERT_EQ(4u, bytes_read);
  EXPECT_EQ("test", socket_bytes.view(0, bytes_read).AsString());
}

TEST_F(DATA_DomainTest, OutboundL2apSocket) {
  constexpr l2cap::PSM kPSM = l2cap::kAVCTP;
  constexpr l2cap::ChannelId kLocalId = 0x0040;
  constexpr l2cap::ChannelId kRemoteId = 0x9042;
  constexpr hci::ConnectionHandle kLinkHandle = 0x0001;

  // Register a fake link.
  domain()->AddACLConnection(
      kLinkHandle, hci::Connection::Role::kMaster, [] {},
      [](auto, auto, auto) {}, dispatcher());

  zx::socket sock;
  ASSERT_FALSE(sock);
  auto sock_cb = [&](zx::socket cb_sock, hci::ConnectionHandle handle) {
    EXPECT_EQ(kLinkHandle, handle);
    sock = std::move(cb_sock);
  };

  domain()->OpenL2capChannel(kLinkHandle, kPSM, std::move(sock_cb),
                             dispatcher());

  // Expect the CHANNEL opening stuff here
  ExpectOutgoingChannelCreation(kLinkHandle, kRemoteId, kLocalId, kPSM);

  RunLoopUntilIdle();
  // We should have opened a channel successfully.
  ASSERT_TRUE(sock);

  // Test basic channel<->socket interaction by verifying that an ACL packet
  // gets routed to the socket.
  test_device()->SendACLDataChannelPacket(CreateStaticByteBuffer(
      // ACL data header (handle: 1, length 8)
      0x01, 0x00, 0x08, 0x00,

      // L2CAP B-frame: (length: 4, channel-id: 0x0040 (kLocalId))
      0x04, 0x00, 0x40, 0x00, 't', 'e', 's', 't'));

  // Run until the packet is written to the socket buffer.
  RunLoopUntilIdle();

  // Allocate a larger buffer than the number of SDU bytes we expect (which is
  // 4).
  StaticByteBuffer<10> socket_bytes;
  size_t bytes_read;
  zx_status_t status = sock.read(0, socket_bytes.mutable_data(),
                                 socket_bytes.size(), &bytes_read);
  EXPECT_EQ(ZX_OK, status);
  ASSERT_EQ(4u, bytes_read);
  EXPECT_EQ("test", socket_bytes.view(0, bytes_read).AsString());
}

// TODO(armansito): Add unit tests for RFCOMM sockets when the Domain class
// has a public API for it.

}  // namespace
}  // namespace data
}  // namespace btlib
