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