Merge "L2CAP Basic and ERTM DataController initial unittest" am: f9638a68ea
am: a096a71365

Change-Id: I6aaf11bb638e0d7df863ca393897b060e478d319
diff --git a/gd/l2cap/Android.bp b/gd/l2cap/Android.bp
index 649f618..3d65446 100644
--- a/gd/l2cap/Android.bp
+++ b/gd/l2cap/Android.bp
@@ -42,6 +42,8 @@
         "classic/internal/fixed_channel_service_manager_test.cc",
         "classic/internal/link_manager_test.cc",
         "classic/internal/signalling_manager_test.cc",
+        "internal/basic_mode_channel_data_controller_test.cc",
+        "internal/enhanced_retransmission_mode_channel_data_controller_test.cc",
         "internal/fixed_channel_allocator_test.cc",
         "internal/receiver_test.cc",
         "internal/scheduler_fifo_test.cc",
diff --git a/gd/l2cap/internal/basic_mode_channel_data_controller_test.cc b/gd/l2cap/internal/basic_mode_channel_data_controller_test.cc
new file mode 100644
index 0000000..35c3002
--- /dev/null
+++ b/gd/l2cap/internal/basic_mode_channel_data_controller_test.cc
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "l2cap/internal/basic_mode_channel_data_controller.h"
+
+#include <gtest/gtest.h>
+
+#include "l2cap/internal/scheduler_mock.h"
+#include "packet/raw_builder.h"
+
+namespace bluetooth {
+namespace l2cap {
+namespace internal {
+namespace {
+
+std::unique_ptr<packet::BasePacketBuilder> CreateSdu(std::vector<uint8_t> payload) {
+  auto raw_builder = std::make_unique<packet::RawBuilder>();
+  raw_builder->AddOctets(payload);
+  return raw_builder;
+}
+
+PacketView<kLittleEndian> GetPacketView(std::unique_ptr<packet::BasePacketBuilder> packet) {
+  auto bytes = std::make_shared<std::vector<uint8_t>>();
+  BitInserter i(*bytes);
+  bytes->reserve(packet->size());
+  packet->Serialize(i);
+  return packet::PacketView<packet::kLittleEndian>(bytes);
+}
+
+void sync_handler(os::Handler* handler) {
+  std::promise<void> promise;
+  auto future = promise.get_future();
+  handler->Post(common::BindOnce(&std::promise<void>::set_value, common::Unretained(&promise)));
+  auto status = future.wait_for(std::chrono::milliseconds(300));
+  EXPECT_EQ(status, std::future_status::ready);
+}
+
+class BasicModeDataControllerTest : public ::testing::Test {
+ protected:
+  void SetUp() override {
+    thread_ = new os::Thread("test_thread", os::Thread::Priority::NORMAL);
+    user_handler_ = new os::Handler(thread_);
+    queue_handler_ = new os::Handler(thread_);
+  }
+
+  void TearDown() override {
+    queue_handler_->Clear();
+    user_handler_->Clear();
+    delete queue_handler_;
+    delete user_handler_;
+    delete thread_;
+  }
+
+  os::Thread* thread_ = nullptr;
+  os::Handler* user_handler_ = nullptr;
+  os::Handler* queue_handler_ = nullptr;
+};
+
+TEST_F(BasicModeDataControllerTest, transmit) {
+  common::BidiQueue<Scheduler::UpperEnqueue, Scheduler::UpperDequeue> channel_queue{10};
+  testing::MockScheduler scheduler;
+  BasicModeDataController controller{1, 1, channel_queue.GetDownEnd(), queue_handler_, &scheduler};
+  EXPECT_CALL(scheduler, OnPacketsReady(1, 1));
+  controller.OnSdu(CreateSdu({1, 2, 3}));
+  auto next_packet = controller.GetNextPacket();
+  EXPECT_NE(next_packet, nullptr);
+}
+
+TEST_F(BasicModeDataControllerTest, receive) {
+  common::BidiQueue<Scheduler::UpperEnqueue, Scheduler::UpperDequeue> channel_queue{10};
+  testing::MockScheduler scheduler;
+  BasicModeDataController controller{1, 1, channel_queue.GetDownEnd(), queue_handler_, &scheduler};
+  auto base_view = GetPacketView(CreateSdu({0, 0, 1, 0}));
+  auto basic_frame_view = BasicFrameView::Create(base_view);
+  EXPECT_TRUE(basic_frame_view.IsValid());
+  controller.OnPdu(basic_frame_view);
+  sync_handler(queue_handler_);
+  auto packet_view = channel_queue.GetUpEnd()->TryDequeue();
+  EXPECT_NE(packet_view, nullptr);
+}
+
+}  // namespace
+}  // namespace internal
+}  // namespace l2cap
+}  // namespace bluetooth
diff --git a/gd/l2cap/internal/enhanced_retransmission_mode_channel_data_controller.cc b/gd/l2cap/internal/enhanced_retransmission_mode_channel_data_controller.cc
index c31ad85..3e5042d 100644
--- a/gd/l2cap/internal/enhanced_retransmission_mode_channel_data_controller.cc
+++ b/gd/l2cap/internal/enhanced_retransmission_mode_channel_data_controller.cc
@@ -490,11 +490,11 @@
   }
 
   bool with_valid_req_seq(uint8_t req_seq) {
-    return expected_ack_seq_ <= req_seq && req_seq < next_tx_seq_;
+    return expected_ack_seq_ <= req_seq && req_seq <= next_tx_seq_;
   }
 
   bool with_valid_req_seq_retrans(uint8_t req_seq) {
-    return expected_ack_seq_ <= req_seq && req_seq < next_tx_seq_;
+    return expected_ack_seq_ <= req_seq && req_seq <= next_tx_seq_;
   }
 
   bool with_valid_f_bit(Final f) {
diff --git a/gd/l2cap/internal/enhanced_retransmission_mode_channel_data_controller_test.cc b/gd/l2cap/internal/enhanced_retransmission_mode_channel_data_controller_test.cc
new file mode 100644
index 0000000..dd87e36
--- /dev/null
+++ b/gd/l2cap/internal/enhanced_retransmission_mode_channel_data_controller_test.cc
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "l2cap/internal/enhanced_retransmission_mode_channel_data_controller.h"
+
+#include <gtest/gtest.h>
+
+#include "l2cap/internal/scheduler_mock.h"
+#include "l2cap/l2cap_packets.h"
+#include "packet/raw_builder.h"
+
+namespace bluetooth {
+namespace l2cap {
+namespace internal {
+namespace {
+
+std::unique_ptr<packet::BasePacketBuilder> CreateSdu(std::vector<uint8_t> payload) {
+  auto raw_builder = std::make_unique<packet::RawBuilder>();
+  raw_builder->AddOctets(payload);
+  return raw_builder;
+}
+
+PacketView<kLittleEndian> GetPacketView(std::unique_ptr<packet::BasePacketBuilder> packet) {
+  auto bytes = std::make_shared<std::vector<uint8_t>>();
+  BitInserter i(*bytes);
+  bytes->reserve(packet->size());
+  packet->Serialize(i);
+  return packet::PacketView<packet::kLittleEndian>(bytes);
+}
+
+void sync_handler(os::Handler* handler) {
+  std::promise<void> promise;
+  auto future = promise.get_future();
+  handler->Post(common::BindOnce(&std::promise<void>::set_value, common::Unretained(&promise)));
+  auto status = future.wait_for(std::chrono::milliseconds(300));
+  EXPECT_EQ(status, std::future_status::ready);
+}
+
+class ErtmDataControllerTest : public ::testing::Test {
+ protected:
+  void SetUp() override {
+    thread_ = new os::Thread("test_thread", os::Thread::Priority::NORMAL);
+    user_handler_ = new os::Handler(thread_);
+    queue_handler_ = new os::Handler(thread_);
+  }
+
+  void TearDown() override {
+    queue_handler_->Clear();
+    user_handler_->Clear();
+    delete queue_handler_;
+    delete user_handler_;
+    delete thread_;
+  }
+
+  os::Thread* thread_ = nullptr;
+  os::Handler* user_handler_ = nullptr;
+  os::Handler* queue_handler_ = nullptr;
+};
+
+TEST_F(ErtmDataControllerTest, receive) {
+  common::BidiQueue<Scheduler::UpperEnqueue, Scheduler::UpperDequeue> channel_queue{10};
+  testing::MockScheduler scheduler;
+  ErtmController controller{1, 1, channel_queue.GetDownEnd(), queue_handler_, &scheduler};
+  auto segment = CreateSdu({'a', 'b', 'c', 'd'});
+  auto builder = EnhancedInformationFrameBuilder::Create(1, 0, Final::NOT_SET, 0,
+                                                         SegmentationAndReassembly::UNSEGMENTED, std::move(segment));
+  auto base_view = GetPacketView(std::move(builder));
+  auto basic_frame_view = BasicFrameView::Create(base_view);
+  EXPECT_TRUE(basic_frame_view.IsValid());
+  controller.OnPdu(basic_frame_view);
+  sync_handler(queue_handler_);
+  auto payload = channel_queue.GetUpEnd()->TryDequeue();
+  EXPECT_NE(payload, nullptr);
+  std::string data = std::string(payload->begin(), payload->end());
+  EXPECT_EQ(data, "abcd");
+}
+
+}  // namespace
+}  // namespace internal
+}  // namespace l2cap
+}  // namespace bluetooth