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 using namespace bluetooth;
37 using namespace std::chrono_literals;
38 
39 using ::bluetooth::common::BidiQueue;
40 using ::bluetooth::common::Callback;
41 using ::bluetooth::os::Handler;
42 using ::bluetooth::os::Thread;
43 using ::bluetooth::packet::BitInserter;
44 using ::bluetooth::packet::RawBuilder;
45 
46 using ::testing::_;
47 using ::testing::DoAll;
48 using ::testing::Eq;
49 using ::testing::Field;
50 using ::testing::Mock;
51 using ::testing::MockFunction;
52 using ::testing::SaveArg;
53 using ::testing::VariantWith;
54 using ::testing::WithArg;
55 
56 namespace {
57 constexpr bool kCrashOnUnknownHandle = true;
58 constexpr char kFixedAddress[] = "c0:aa:bb:cc:dd:ee";
59 const bluetooth::hci::Address kRemoteAddress =
60     bluetooth::hci::Address({0x00, 0x11, 0x22, 0x33, 0x44, 0x55});
61 [[maybe_unused]] constexpr uint16_t kHciHandle = 123;
62 template <typename B>
Serialize(std::unique_ptr<B> build)63 std::shared_ptr<std::vector<uint8_t>> Serialize(std::unique_ptr<B> build) {
64   auto bytes = std::make_shared<std::vector<uint8_t>>();
65   BitInserter bi(*bytes);
66   build->Serialize(bi);
67   return bytes;
68 }
69 
70 template <typename T>
CreateCommandView(std::shared_ptr<std::vector<uint8_t>> bytes)71 T CreateCommandView(std::shared_ptr<std::vector<uint8_t>> bytes) {
72   return T::Create(hci::CommandView::Create(hci::PacketView<hci::kLittleEndian>(bytes)));
73 }
74 
75 template <typename T>
CreateAclCommandView(std::shared_ptr<std::vector<uint8_t>> bytes)76 T CreateAclCommandView(std::shared_ptr<std::vector<uint8_t>> bytes) {
77   return T::Create(CreateCommandView<hci::AclCommandView>(bytes));
78 }
79 
80 template <typename T>
CreateConnectionManagementCommandView(std::shared_ptr<std::vector<uint8_t>> bytes)81 T CreateConnectionManagementCommandView(std::shared_ptr<std::vector<uint8_t>> bytes) {
82   return T::Create(CreateAclCommandView<hci::ConnectionManagementCommandView>(bytes));
83 }
84 
85 template <typename T>
CreateSecurityCommandView(std::shared_ptr<std::vector<uint8_t>> bytes)86 T CreateSecurityCommandView(std::shared_ptr<std::vector<uint8_t>> bytes) {
87   return T::Create(CreateCommandView<hci::SecurityCommandView>(bytes));
88 }
89 
90 template <typename T>
CreateEventView(std::shared_ptr<std::vector<uint8_t>> bytes)91 T CreateEventView(std::shared_ptr<std::vector<uint8_t>> bytes) {
92   return T::Create(hci::EventView::Create(hci::PacketView<hci::kLittleEndian>(bytes)));
93 }
94 
ReturnCommandComplete(hci::OpCode op_code,hci::ErrorCode error_code)95 [[maybe_unused]] hci::CommandCompleteView ReturnCommandComplete(
96     hci::OpCode op_code, hci::ErrorCode error_code) {
97   std::vector<uint8_t> success_vector{static_cast<uint8_t>(error_code)};
98   auto builder = hci::CommandCompleteBuilder::Create(
99       uint8_t{1}, op_code, std::make_unique<RawBuilder>(success_vector));
100   auto bytes = Serialize<hci::CommandCompleteBuilder>(std::move(builder));
101   return hci::CommandCompleteView::Create(
102       hci::EventView::Create(hci::PacketView<hci::kLittleEndian>(bytes)));
103 }
104 
ReturnCommandStatus(hci::OpCode op_code,hci::ErrorCode error_code)105 [[maybe_unused]] hci::CommandStatusView ReturnCommandStatus(
106     hci::OpCode op_code, hci::ErrorCode error_code) {
107   std::vector<uint8_t> success_vector{static_cast<uint8_t>(error_code)};
108   auto builder = hci::CommandStatusBuilder::Create(
109       hci::ErrorCode::SUCCESS, uint8_t{1}, op_code, std::make_unique<RawBuilder>(success_vector));
110   auto bytes = Serialize<hci::CommandStatusBuilder>(std::move(builder));
111   return hci::CommandStatusView::Create(
112       hci::EventView::Create(hci::PacketView<hci::kLittleEndian>(bytes)));
113 }
114 
115 bool handle_outgoing_connection_ = false;
116 bool handle_incoming_connection_ = false;
117 
118 }  // namespace
119 
120 namespace bluetooth {
121 namespace hci {
122 namespace acl_manager {
123 
124 class MockAclScheduler : public AclScheduler {
125  public:
ReportAclConnectionCompletion(Address,common::ContextualOnceCallback<void ()> handle_outgoing_connection,common::ContextualOnceCallback<void ()> handle_incoming_connection,common::ContextualOnceCallback<void (std::string)> handle_unknown_connection)126   virtual void ReportAclConnectionCompletion(
127       Address /* address */,
128       common::ContextualOnceCallback<void()> handle_outgoing_connection,
129       common::ContextualOnceCallback<void()> handle_incoming_connection,
130       common::ContextualOnceCallback<void(std::string)> handle_unknown_connection) override {
131     if (handle_outgoing_connection_) {
132       handle_outgoing_connection();
133       return;
134     }
135 
136     if (handle_incoming_connection_) {
137       handle_incoming_connection();
138     } else {
139       handle_unknown_connection("set_of_incoming_connecting_addresses()");
140     }
141   }
142 };
143 
GetPacketView(std::unique_ptr<packet::BasePacketBuilder> packet)144 PacketView<kLittleEndian> GetPacketView(std::unique_ptr<packet::BasePacketBuilder> packet) {
145   auto bytes = std::make_shared<std::vector<uint8_t>>();
146   BitInserter i(*bytes);
147   bytes->reserve(packet->size());
148   packet->Serialize(i);
149   return packet::PacketView<packet::kLittleEndian>(bytes);
150 }
151 
152 class ClassicImplTest : public ::testing::Test {
153  protected:
SetUp()154   void SetUp() override {
155     bluetooth::common::InitFlags::SetAllForTesting();
156     thread_ = new Thread("thread", Thread::Priority::NORMAL);
157     handler_ = new Handler(thread_);
158     hci_layer_ = new HciLayerFake();
159     controller_ = new testing::MockController();
160 
161     EXPECT_CALL(*controller_, GetNumAclPacketBuffers);
162     EXPECT_CALL(*controller_, GetAclPacketLength);
163     EXPECT_CALL(*controller_, GetLeBufferSize);
164     EXPECT_CALL(*controller_, RegisterCompletedAclPacketsCallback);
165     EXPECT_CALL(*controller_, UnregisterCompletedAclPacketsCallback);
166 
167     round_robin_scheduler_ =
168         new acl_manager::RoundRobinScheduler(handler_, controller_, hci_queue_.GetUpEnd());
169     hci_queue_.GetDownEnd()->RegisterDequeue(
170         handler_, common::Bind(&ClassicImplTest::HciDownEndDequeue, common::Unretained(this)));
171     acl_scheduler_ = new MockAclScheduler();
172     rnr_ = new RemoteNameRequestModule();
173     classic_impl_ = new acl_manager::classic_impl(
174         hci_layer_,
175         controller_,
176         handler_,
177         round_robin_scheduler_,
178         kCrashOnUnknownHandle,
179         acl_scheduler_,
180         rnr_);
181     classic_impl_->handle_register_callbacks(&mock_connection_callback_, handler_);
182 
183     Address address;
184     Address::FromString(kFixedAddress, address);
185   }
186 
TearDown()187   void TearDown() override {
188     sync_handler();
189     delete classic_impl_;
190 
191     hci_queue_.GetDownEnd()->UnregisterDequeue();
192 
193     delete rnr_;
194     delete acl_scheduler_;
195     delete round_robin_scheduler_;
196     delete controller_;
197     delete hci_layer_;
198 
199     handler_->Clear();
200     delete handler_;
201     delete thread_;
202   }
203 
204   MockAclScheduler* acl_scheduler_;
205   RemoteNameRequestModule* rnr_;
206 
sync_handler()207   void sync_handler() {
208     thread_->GetReactor()->WaitForIdle(2s);
209   }
210 
HciDownEndDequeue()211   void HciDownEndDequeue() {
212     auto packet = hci_queue_.GetDownEnd()->TryDequeue();
213     // Convert from a Builder to a View
214     auto bytes = std::make_shared<std::vector<uint8_t>>();
215     bluetooth::packet::BitInserter i(*bytes);
216     bytes->reserve(packet->size());
217     packet->Serialize(i);
218     auto packet_view = bluetooth::packet::PacketView<bluetooth::packet::kLittleEndian>(bytes);
219     AclView acl_packet_view = AclView::Create(packet_view);
220     ASSERT_TRUE(acl_packet_view.IsValid());
221     PacketView<true> count_view = acl_packet_view.GetPayload();
222     sent_acl_packets_.push(acl_packet_view);
223 
224     packet_count_--;
225     if (packet_count_ == 0) {
226       packet_promise_->set_value();
227       packet_promise_ = nullptr;
228     }
229   }
230 
231  protected:
232   Address remote_address_;
233 
234   uint16_t packet_count_;
235   std::unique_ptr<std::promise<void>> packet_promise_;
236   std::unique_ptr<std::future<void>> packet_future_;
237   std::queue<AclView> sent_acl_packets_;
238 
239   BidiQueue<AclView, AclBuilder> hci_queue_{3};
240 
241   Thread* thread_;
242   Handler* handler_;
243   HciLayerFake* hci_layer_{nullptr};
244   testing::MockController* controller_;
245   acl_manager::RoundRobinScheduler* round_robin_scheduler_{nullptr};
246 
247   acl_manager::MockConnectionCallback mock_connection_callback_;
248   acl_manager::MockConnectionManagementCallbacks connection_management_callbacks_;
249 
250   struct acl_manager::classic_impl* classic_impl_;
251 };
252 
TEST_F(ClassicImplTest,nop)253 TEST_F(ClassicImplTest, nop) {}
254 
TEST_F(ClassicImplTest,on_classic_event_CONNECTION_COMPLETE__SUCCESS)255 TEST_F(ClassicImplTest, on_classic_event_CONNECTION_COMPLETE__SUCCESS) {
256   // Expecting valid response
257   EXPECT_CALL(mock_connection_callback_, OnConnectSuccess);
258   handle_outgoing_connection_ = true;
259 
260   auto command = ConnectionCompleteBuilder::Create(
261       ErrorCode::SUCCESS,
262       kHciHandle,
263       kRemoteAddress,
264       LinkType::ACL,
265       bluetooth::hci::Enable::ENABLED);
266 
267   auto bytes = Serialize<ConnectionCompleteBuilder>(std::move(command));
268   auto view = CreateEventView<hci::ConnectionCompleteView>(bytes);
269   ASSERT_TRUE(view.IsValid());
270   classic_impl_->on_classic_event(view);
271 }
272 
273 }  // namespace acl_manager
274 }  // namespace hci
275 }  // namespace bluetooth
276