1 /*
2  * Copyright 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "hci/acl_manager/classic_impl.h"
18 
19 #include <gmock/gmock.h>
20 #include <gtest/gtest.h>
21 
22 #include <chrono>
23 
24 #include "common/bidi_queue.h"
25 #include "hci/acl_manager/acl_scheduler.h"
26 #include "hci/acl_manager/connection_callbacks_mock.h"
27 #include "hci/acl_manager/connection_management_callbacks_mock.h"
28 #include "hci/address.h"
29 #include "hci/controller_mock.h"
30 #include "hci/hci_layer_fake.h"
31 #include "hci/hci_packets.h"
32 #include "os/handler.h"
33 #include "packet/bit_inserter.h"
34 #include "packet/raw_builder.h"
35 
36 // TODO(b/369381361) Enfore -Wmissing-prototypes
37 #pragma GCC diagnostic ignored "-Wmissing-prototypes"
38 
39 using namespace bluetooth;
40 using namespace std::chrono_literals;
41 
42 using ::bluetooth::common::BidiQueue;
43 using ::bluetooth::common::Callback;
44 using ::bluetooth::os::Handler;
45 using ::bluetooth::os::Thread;
46 using ::bluetooth::packet::BitInserter;
47 using ::bluetooth::packet::RawBuilder;
48 
49 using ::testing::_;
50 using ::testing::DoAll;
51 using ::testing::Eq;
52 using ::testing::Field;
53 using ::testing::Mock;
54 using ::testing::MockFunction;
55 using ::testing::SaveArg;
56 using ::testing::VariantWith;
57 using ::testing::WithArg;
58 
59 namespace {
60 constexpr bool kCrashOnUnknownHandle = true;
61 constexpr char kFixedAddress[] = "c0:aa:bb:cc:dd:ee";
62 const bluetooth::hci::Address kRemoteAddress =
63         bluetooth::hci::Address({0x00, 0x11, 0x22, 0x33, 0x44, 0x55});
64 [[maybe_unused]] constexpr uint16_t kHciHandle = 123;
65 template <typename B>
Serialize(std::unique_ptr<B> build)66 std::shared_ptr<std::vector<uint8_t>> Serialize(std::unique_ptr<B> build) {
67   auto bytes = std::make_shared<std::vector<uint8_t>>();
68   BitInserter bi(*bytes);
69   build->Serialize(bi);
70   return bytes;
71 }
72 
73 template <typename T>
CreateCommandView(std::shared_ptr<std::vector<uint8_t>> bytes)74 T CreateCommandView(std::shared_ptr<std::vector<uint8_t>> bytes) {
75   return T::Create(hci::CommandView::Create(hci::PacketView<hci::kLittleEndian>(bytes)));
76 }
77 
78 template <typename T>
CreateAclCommandView(std::shared_ptr<std::vector<uint8_t>> bytes)79 T CreateAclCommandView(std::shared_ptr<std::vector<uint8_t>> bytes) {
80   return T::Create(CreateCommandView<hci::AclCommandView>(bytes));
81 }
82 
83 template <typename T>
CreateConnectionManagementCommandView(std::shared_ptr<std::vector<uint8_t>> bytes)84 T CreateConnectionManagementCommandView(std::shared_ptr<std::vector<uint8_t>> bytes) {
85   return T::Create(CreateAclCommandView<hci::ConnectionManagementCommandView>(bytes));
86 }
87 
88 template <typename T>
CreateSecurityCommandView(std::shared_ptr<std::vector<uint8_t>> bytes)89 T CreateSecurityCommandView(std::shared_ptr<std::vector<uint8_t>> bytes) {
90   return T::Create(CreateCommandView<hci::SecurityCommandView>(bytes));
91 }
92 
93 template <typename T>
CreateEventView(std::shared_ptr<std::vector<uint8_t>> bytes)94 T CreateEventView(std::shared_ptr<std::vector<uint8_t>> bytes) {
95   return T::Create(hci::EventView::Create(hci::PacketView<hci::kLittleEndian>(bytes)));
96 }
97 
ReturnCommandComplete(hci::OpCode op_code,hci::ErrorCode error_code)98 [[maybe_unused]] hci::CommandCompleteView ReturnCommandComplete(hci::OpCode op_code,
99                                                                 hci::ErrorCode error_code) {
100   std::vector<uint8_t> success_vector{static_cast<uint8_t>(error_code)};
101   auto builder = hci::CommandCompleteBuilder::Create(uint8_t{1}, op_code,
102                                                      std::make_unique<RawBuilder>(success_vector));
103   auto bytes = Serialize<hci::CommandCompleteBuilder>(std::move(builder));
104   return hci::CommandCompleteView::Create(
105           hci::EventView::Create(hci::PacketView<hci::kLittleEndian>(bytes)));
106 }
107 
ReturnCommandStatus(hci::OpCode op_code,hci::ErrorCode error_code)108 [[maybe_unused]] hci::CommandStatusView ReturnCommandStatus(hci::OpCode op_code,
109                                                             hci::ErrorCode error_code) {
110   std::vector<uint8_t> success_vector{static_cast<uint8_t>(error_code)};
111   auto builder = hci::CommandStatusBuilder::Create(hci::ErrorCode::SUCCESS, uint8_t{1}, op_code,
112                                                    std::make_unique<RawBuilder>(success_vector));
113   auto bytes = Serialize<hci::CommandStatusBuilder>(std::move(builder));
114   return hci::CommandStatusView::Create(
115           hci::EventView::Create(hci::PacketView<hci::kLittleEndian>(bytes)));
116 }
117 
118 bool handle_outgoing_connection_ = false;
119 bool handle_incoming_connection_ = false;
120 
121 }  // namespace
122 
123 namespace bluetooth {
124 namespace hci {
125 namespace acl_manager {
126 
127 class MockAclScheduler : public AclScheduler {
128 public:
ReportAclConnectionCompletion(Address,common::ContextualOnceCallback<void ()> handle_outgoing_connection,common::ContextualOnceCallback<void ()> handle_incoming_connection,common::ContextualOnceCallback<void (std::string)> handle_unknown_connection)129   virtual void ReportAclConnectionCompletion(
130           Address /* address */, common::ContextualOnceCallback<void()> handle_outgoing_connection,
131           common::ContextualOnceCallback<void()> handle_incoming_connection,
132           common::ContextualOnceCallback<void(std::string)> handle_unknown_connection) override {
133     if (handle_outgoing_connection_) {
134       handle_outgoing_connection();
135       return;
136     }
137 
138     if (handle_incoming_connection_) {
139       handle_incoming_connection();
140     } else {
141       handle_unknown_connection("set_of_incoming_connecting_addresses()");
142     }
143   }
144 };
145 
GetPacketView(std::unique_ptr<packet::BasePacketBuilder> packet)146 PacketView<kLittleEndian> GetPacketView(std::unique_ptr<packet::BasePacketBuilder> packet) {
147   auto bytes = std::make_shared<std::vector<uint8_t>>();
148   BitInserter i(*bytes);
149   bytes->reserve(packet->size());
150   packet->Serialize(i);
151   return packet::PacketView<packet::kLittleEndian>(bytes);
152 }
153 
154 class ClassicImplTest : public ::testing::Test {
155 protected:
SetUp()156   void SetUp() override {
157     thread_ = new Thread("thread", Thread::Priority::NORMAL);
158     handler_ = new Handler(thread_);
159     hci_layer_ = new HciLayerFake();
160     controller_ = new testing::MockController();
161 
162     EXPECT_CALL(*controller_, GetNumAclPacketBuffers);
163     EXPECT_CALL(*controller_, GetAclPacketLength);
164     EXPECT_CALL(*controller_, GetLeBufferSize);
165     EXPECT_CALL(*controller_, RegisterCompletedAclPacketsCallback);
166     EXPECT_CALL(*controller_, UnregisterCompletedAclPacketsCallback);
167 
168     round_robin_scheduler_ =
169             new acl_manager::RoundRobinScheduler(handler_, controller_, hci_queue_.GetUpEnd());
170     hci_queue_.GetDownEnd()->RegisterDequeue(
171             handler_, common::Bind(&ClassicImplTest::HciDownEndDequeue, common::Unretained(this)));
172     acl_scheduler_ = new MockAclScheduler();
173     rnr_ = new RemoteNameRequestModule();
174     classic_impl_ =
175             new acl_manager::classic_impl(hci_layer_, controller_, handler_, round_robin_scheduler_,
176                                           kCrashOnUnknownHandle, acl_scheduler_, rnr_);
177     classic_impl_->handle_register_callbacks(&mock_connection_callback_, handler_);
178 
179     Address address;
180     Address::FromString(kFixedAddress, address);
181   }
182 
TearDown()183   void TearDown() override {
184     sync_handler();
185     delete classic_impl_;
186 
187     hci_queue_.GetDownEnd()->UnregisterDequeue();
188 
189     delete rnr_;
190     delete acl_scheduler_;
191     delete round_robin_scheduler_;
192     delete controller_;
193     delete hci_layer_;
194 
195     handler_->Clear();
196     delete handler_;
197     delete thread_;
198   }
199 
200   MockAclScheduler* acl_scheduler_;
201   RemoteNameRequestModule* rnr_;
202 
sync_handler()203   void sync_handler() { thread_->GetReactor()->WaitForIdle(2s); }
204 
HciDownEndDequeue()205   void HciDownEndDequeue() {
206     auto packet = hci_queue_.GetDownEnd()->TryDequeue();
207     // Convert from a Builder to a View
208     auto bytes = std::make_shared<std::vector<uint8_t>>();
209     bluetooth::packet::BitInserter i(*bytes);
210     bytes->reserve(packet->size());
211     packet->Serialize(i);
212     auto packet_view = bluetooth::packet::PacketView<bluetooth::packet::kLittleEndian>(bytes);
213     AclView acl_packet_view = AclView::Create(packet_view);
214     ASSERT_TRUE(acl_packet_view.IsValid());
215     PacketView<true> count_view = acl_packet_view.GetPayload();
216     sent_acl_packets_.push(acl_packet_view);
217 
218     packet_count_--;
219     if (packet_count_ == 0) {
220       packet_promise_->set_value();
221       packet_promise_ = nullptr;
222     }
223   }
224 
225 protected:
226   Address remote_address_;
227 
228   uint16_t packet_count_;
229   std::unique_ptr<std::promise<void>> packet_promise_;
230   std::unique_ptr<std::future<void>> packet_future_;
231   std::queue<AclView> sent_acl_packets_;
232 
233   BidiQueue<AclView, AclBuilder> hci_queue_{3};
234 
235   Thread* thread_;
236   Handler* handler_;
237   HciLayerFake* hci_layer_{nullptr};
238   testing::MockController* controller_;
239   acl_manager::RoundRobinScheduler* round_robin_scheduler_{nullptr};
240 
241   acl_manager::MockConnectionCallback mock_connection_callback_;
242   acl_manager::MockConnectionManagementCallbacks connection_management_callbacks_;
243 
244   struct acl_manager::classic_impl* classic_impl_;
245 };
246 
TEST_F(ClassicImplTest,nop)247 TEST_F(ClassicImplTest, nop) {}
248 
TEST_F(ClassicImplTest,on_classic_event_CONNECTION_COMPLETE__SUCCESS)249 TEST_F(ClassicImplTest, on_classic_event_CONNECTION_COMPLETE__SUCCESS) {
250   // Expecting valid response
251   EXPECT_CALL(mock_connection_callback_, OnConnectSuccess);
252   handle_outgoing_connection_ = true;
253 
254   auto command = ConnectionCompleteBuilder::Create(ErrorCode::SUCCESS, kHciHandle, kRemoteAddress,
255                                                    LinkType::ACL, bluetooth::hci::Enable::ENABLED);
256 
257   auto bytes = Serialize<ConnectionCompleteBuilder>(std::move(command));
258   auto view = CreateEventView<hci::ConnectionCompleteView>(bytes);
259   ASSERT_TRUE(view.IsValid());
260   classic_impl_->on_classic_event(view);
261 }
262 
263 }  // namespace acl_manager
264 }  // namespace hci
265 }  // namespace bluetooth
266