1 /*
2 * Copyright 2021 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 <gmock/gmock.h>
18 #include <gtest/gtest.h>
19 #include <condition_variable>
20 #include <future>
21 #include <map>
22 #include <thread>
23
24 #include "btif/include/btif_hh.h"
25 #include "device/include/controller.h"
26 #include "gd/btaa/activity_attribution.h"
27 #include "gd/hal/hci_hal.h"
28 #include "gd/hci/acl_manager_mock.h"
29 #include "gd/hci/controller_mock.h"
30 #include "gd/module.h"
31 #include "gd/os/mock_queue.h"
32 #include "gd/os/queue.h"
33 #include "gd/packet/packet_view.h"
34 #include "hci/acl_manager.h"
35 #include "hci/acl_manager/classic_acl_connection.h"
36 #include "hci/acl_manager/connection_callbacks.h"
37 #include "hci/acl_manager/connection_management_callbacks.h"
38 #include "hci/acl_manager/le_acl_connection.h"
39 #include "hci/acl_manager/le_connection_callbacks.h"
40 #include "hci/acl_manager/le_connection_management_callbacks.h"
41 #include "hci/include/hci_layer.h"
42 #include "hci/include/hci_packet_factory.h"
43 #include "hci/include/hci_packet_parser.h"
44 #include "hci/include/packet_fragmenter.h"
45 #include "include/hardware/bt_activity_attribution.h"
46 #include "main/shim/acl.h"
47 #include "main/shim/acl_legacy_interface.h"
48 #include "main/shim/helpers.h"
49 #include "os/handler.h"
50 #include "os/thread.h"
51 #include "stack/btm/btm_int_types.h"
52 #include "stack/include/btu.h"
53 #include "stack/l2cap/l2c_int.h"
54 #include "test/common/main_handler.h"
55 #include "test/mock/mock_main_shim_entry.h"
56
57 using namespace bluetooth;
58 using namespace testing;
59
60 namespace test = bluetooth::hci::testing;
61
62 const uint8_t kMaxLeAcceptlistSize = 16;
63 std::map<std::string, int> mock_function_count_map;
64 tL2C_CB l2cb;
65 tBTM_CB btm_cb;
66 btif_hh_cb_t btif_hh_cb;
67
68 namespace {
69 std::map<std::string, std::promise<uint16_t>> mock_function_handle_promise_map;
70 }
71
mock_get_ble_acceptlist_size()72 uint8_t mock_get_ble_acceptlist_size() { return 123; }
73
74 struct controller_t mock_controller {
75 .get_ble_acceptlist_size = mock_get_ble_acceptlist_size,
76 };
77
controller_get_interface()78 const controller_t* controller_get_interface() { return &mock_controller; }
79
mock_on_send_data_upwards(BT_HDR *)80 void mock_on_send_data_upwards(BT_HDR*) { mock_function_count_map[__func__]++; }
81
mock_on_packets_completed(uint16_t handle,uint16_t num_packets)82 void mock_on_packets_completed(uint16_t handle, uint16_t num_packets) {
83 mock_function_count_map[__func__]++;
84 }
85
mock_connection_classic_on_connected(const RawAddress & bda,uint16_t handle,uint8_t enc_mode)86 void mock_connection_classic_on_connected(const RawAddress& bda,
87 uint16_t handle, uint8_t enc_mode) {
88 mock_function_count_map[__func__]++;
89 }
90
mock_connection_classic_on_failed(const RawAddress & bda,tHCI_STATUS status)91 void mock_connection_classic_on_failed(const RawAddress& bda,
92 tHCI_STATUS status) {
93 mock_function_count_map[__func__]++;
94 }
95
mock_connection_classic_on_disconnected(tHCI_STATUS status,uint16_t handle,tHCI_STATUS reason)96 void mock_connection_classic_on_disconnected(tHCI_STATUS status,
97 uint16_t handle,
98 tHCI_STATUS reason) {
99 mock_function_count_map[__func__]++;
100 ASSERT_TRUE(mock_function_handle_promise_map.find(__func__) !=
101 mock_function_handle_promise_map.end());
102 mock_function_handle_promise_map[__func__].set_value(handle);
103 }
mock_connection_le_on_connected(const tBLE_BD_ADDR & address_with_type,uint16_t handle,tHCI_ROLE role,uint16_t conn_interval,uint16_t conn_latency,uint16_t conn_timeout,const RawAddress & local_rpa,const RawAddress & peer_rpa,uint8_t peer_addr_type)104 void mock_connection_le_on_connected(
105 const tBLE_BD_ADDR& address_with_type, uint16_t handle, tHCI_ROLE role,
106 uint16_t conn_interval, uint16_t conn_latency, uint16_t conn_timeout,
107 const RawAddress& local_rpa, const RawAddress& peer_rpa,
108 uint8_t peer_addr_type) {
109 mock_function_count_map[__func__]++;
110 }
mock_connection_le_on_failed(const tBLE_BD_ADDR & address_with_type,uint16_t handle,bool enhanced,tHCI_STATUS status)111 void mock_connection_le_on_failed(const tBLE_BD_ADDR& address_with_type,
112 uint16_t handle, bool enhanced,
113 tHCI_STATUS status) {
114 mock_function_count_map[__func__]++;
115 }
mock_connection_le_on_disconnected(tHCI_STATUS status,uint16_t handle,tHCI_STATUS reason)116 void mock_connection_le_on_disconnected(tHCI_STATUS status, uint16_t handle,
117 tHCI_STATUS reason) {
118 mock_function_count_map[__func__]++;
119 }
120
GetMockAclInterface()121 const shim::legacy::acl_interface_t GetMockAclInterface() {
122 shim::legacy::acl_interface_t acl_interface{
123 .on_send_data_upwards = mock_on_send_data_upwards,
124 .on_packets_completed = mock_on_packets_completed,
125
126 .connection.classic.on_connected = mock_connection_classic_on_connected,
127 .connection.classic.on_failed = mock_connection_classic_on_failed,
128 .connection.classic.on_disconnected =
129 mock_connection_classic_on_disconnected,
130
131 .connection.le.on_connected = mock_connection_le_on_connected,
132 .connection.le.on_failed = mock_connection_le_on_failed,
133 .connection.le.on_disconnected = mock_connection_le_on_disconnected,
134
135 .connection.sco.on_esco_connect_request = nullptr,
136 .connection.sco.on_sco_connect_request = nullptr,
137 .connection.sco.on_disconnected = nullptr,
138
139 .link.classic.on_authentication_complete = nullptr,
140 .link.classic.on_central_link_key_complete = nullptr,
141 .link.classic.on_change_connection_link_key_complete = nullptr,
142 .link.classic.on_encryption_change = nullptr,
143 .link.classic.on_flow_specification_complete = nullptr,
144 .link.classic.on_flush_occurred = nullptr,
145 .link.classic.on_mode_change = nullptr,
146 .link.classic.on_packet_type_changed = nullptr,
147 .link.classic.on_qos_setup_complete = nullptr,
148 .link.classic.on_read_afh_channel_map_complete = nullptr,
149 .link.classic.on_read_automatic_flush_timeout_complete = nullptr,
150 .link.classic.on_sniff_subrating = nullptr,
151 .link.classic.on_read_clock_complete = nullptr,
152 .link.classic.on_read_clock_offset_complete = nullptr,
153 .link.classic.on_read_failed_contact_counter_complete = nullptr,
154 .link.classic.on_read_link_policy_settings_complete = nullptr,
155 .link.classic.on_read_link_quality_complete = nullptr,
156 .link.classic.on_read_link_supervision_timeout_complete = nullptr,
157 .link.classic.on_read_remote_version_information_complete = nullptr,
158 .link.classic.on_read_remote_extended_features_complete = nullptr,
159 .link.classic.on_read_rssi_complete = nullptr,
160 .link.classic.on_read_transmit_power_level_complete = nullptr,
161 .link.classic.on_role_change = nullptr,
162 .link.classic.on_role_discovery_complete = nullptr,
163
164 .link.le.on_connection_update = nullptr,
165 .link.le.on_data_length_change = nullptr,
166 .link.le.on_read_remote_version_information_complete = nullptr,
167 };
168 return acl_interface;
169 }
170
hci_packet_factory_get_interface()171 const hci_packet_factory_t* hci_packet_factory_get_interface() {
172 return nullptr;
173 }
hci_packet_parser_get_interface()174 const hci_packet_parser_t* hci_packet_parser_get_interface() { return nullptr; }
hci_layer_get_interface()175 const hci_t* hci_layer_get_interface() { return nullptr; }
packet_fragmenter_get_interface()176 const packet_fragmenter_t* packet_fragmenter_get_interface() { return nullptr; }
LogMsg(uint32_t trace_set_mask,const char * fmt_str,...)177 void LogMsg(uint32_t trace_set_mask, const char* fmt_str, ...) {}
178
179 template <typename T>
180 class MockEnQueue : public os::IQueueEnqueue<T> {
181 using EnqueueCallback = base::Callback<std::unique_ptr<T>()>;
182
RegisterEnqueue(os::Handler * handler,EnqueueCallback callback)183 void RegisterEnqueue(os::Handler* handler,
184 EnqueueCallback callback) override {}
UnregisterEnqueue()185 void UnregisterEnqueue() override {}
186 };
187
188 template <typename T>
189 class MockDeQueue : public os::IQueueDequeue<T> {
190 using DequeueCallback = base::Callback<void()>;
191
RegisterDequeue(os::Handler * handler,DequeueCallback callback)192 void RegisterDequeue(os::Handler* handler,
193 DequeueCallback callback) override {}
UnregisterDequeue()194 void UnregisterDequeue() override {}
TryDequeue()195 std::unique_ptr<T> TryDequeue() override { return nullptr; }
196 };
197
198 class MockClassicAclConnection
199 : public bluetooth::hci::acl_manager::ClassicAclConnection {
200 public:
MockClassicAclConnection(const hci::Address & address,uint16_t handle)201 MockClassicAclConnection(const hci::Address& address, uint16_t handle) {
202 address_ = address; // ClassicAclConnection
203 handle_ = handle; // AclConnection
204 }
205
RegisterCallbacks(hci::acl_manager::ConnectionManagementCallbacks * callbacks,os::Handler * handler)206 void RegisterCallbacks(
207 hci::acl_manager::ConnectionManagementCallbacks* callbacks,
208 os::Handler* handler) override {
209 callbacks_ = callbacks;
210 handler_ = handler;
211 }
212
213 // Returns the bidi queue for this mock connection
GetAclQueueEnd() const214 AclConnection::QueueUpEnd* GetAclQueueEnd() const override {
215 return &mock_acl_queue_;
216 }
217
218 mutable common::BidiQueueEnd<hci::BasePacketBuilder,
219 packet::PacketView<hci::kLittleEndian>>
220 mock_acl_queue_{&tx_, &rx_};
221
222 MockEnQueue<hci::BasePacketBuilder> tx_;
223 MockDeQueue<packet::PacketView<hci::kLittleEndian>> rx_;
224
ReadRemoteVersionInformation()225 bool ReadRemoteVersionInformation() override { return true; }
ReadRemoteSupportedFeatures()226 bool ReadRemoteSupportedFeatures() override { return true; }
227
Disconnect(hci::DisconnectReason reason)228 bool Disconnect(hci::DisconnectReason reason) override {
229 disconnect_cnt_++;
230 disconnect_promise_.set_value(handle_);
231 return true;
232 }
233
234 std::promise<uint16_t> disconnect_promise_;
235
236 hci::acl_manager::ConnectionManagementCallbacks* callbacks_{nullptr};
237 os::Handler* handler_{nullptr};
238
239 int disconnect_cnt_{0};
240 };
241
242 namespace bluetooth {
243 namespace shim {
init_activity_attribution()244 void init_activity_attribution() {}
245
246 namespace testing {
247 extern os::Handler* mock_handler_;
248
249 } // namespace testing
250 } // namespace shim
251
252 namespace activity_attribution {
get_activity_attribution_instance()253 ActivityAttributionInterface* get_activity_attribution_instance() {
254 return nullptr;
255 }
256
257 const ModuleFactory ActivityAttribution::Factory =
__anon31c7d3c30202() 258 ModuleFactory([]() { return nullptr; });
259 } // namespace activity_attribution
260
261 namespace hal {
__anon31c7d3c30302() 262 const ModuleFactory HciHal::Factory = ModuleFactory([]() { return nullptr; });
263 } // namespace hal
264
265 } // namespace bluetooth
266
267 class MainShimTest : public testing::Test {
268 public:
269 protected:
SetUp()270 void SetUp() override {
271 main_thread_start_up();
272
273 thread_ = new os::Thread("acl_thread", os::Thread::Priority::NORMAL);
274 handler_ = new os::Handler(thread_);
275
276 /* extern */ test::mock_controller_ =
277 new bluetooth::hci::testing::MockController();
278 /* extern */ test::mock_acl_manager_ =
279 new bluetooth::hci::testing::MockAclManager();
280 }
TearDown()281 void TearDown() override {
282 delete test::mock_controller_;
283 test::mock_controller_ = nullptr;
284 delete test::mock_acl_manager_;
285 test::mock_acl_manager_ = nullptr;
286
287 handler_->Clear();
288 delete handler_;
289 delete thread_;
290
291 main_thread_shut_down();
292 }
293 os::Thread* thread_{nullptr};
294 os::Handler* handler_{nullptr};
295
296 // Convenience method to create ACL objects
MakeAcl()297 std::unique_ptr<shim::legacy::Acl> MakeAcl() {
298 EXPECT_CALL(*test::mock_acl_manager_, RegisterCallbacks(_, _)).Times(1);
299 EXPECT_CALL(*test::mock_acl_manager_, RegisterLeCallbacks(_, _)).Times(1);
300 EXPECT_CALL(*test::mock_controller_,
301 RegisterCompletedMonitorAclPacketsCallback(_))
302 .Times(1);
303 EXPECT_CALL(*test::mock_acl_manager_, HACK_SetScoDisconnectCallback(_))
304 .Times(1);
305 EXPECT_CALL(*test::mock_controller_,
306 UnregisterCompletedMonitorAclPacketsCallback)
307 .Times(1);
308 return std::make_unique<shim::legacy::Acl>(handler_, GetMockAclInterface(),
309 kMaxLeAcceptlistSize);
310 }
311 };
312
TEST_F(MainShimTest,Nop)313 TEST_F(MainShimTest, Nop) {}
314
TEST_F(MainShimTest,Acl_Lifecycle)315 TEST_F(MainShimTest, Acl_Lifecycle) {
316 auto acl = MakeAcl();
317 acl.reset();
318 acl = MakeAcl();
319 }
320
TEST_F(MainShimTest,helpers)321 TEST_F(MainShimTest, helpers) {
322 uint8_t reason = 0;
323 do {
324 hci::ErrorCode gd_error_code = static_cast<hci::ErrorCode>(reason);
325 tHCI_STATUS legacy_code = ToLegacyHciErrorCode(gd_error_code);
326 ASSERT_EQ(reason,
327 static_cast<uint8_t>(ToLegacyHciErrorCode(gd_error_code)));
328 ASSERT_EQ(reason, static_cast<uint8_t>(legacy_code));
329 } while (++reason != 0);
330 }
331
TEST_F(MainShimTest,connect_and_disconnect)332 TEST_F(MainShimTest, connect_and_disconnect) {
333 hci::Address address({0x11, 0x22, 0x33, 0x44, 0x55, 0x66});
334
335 auto acl = MakeAcl();
336
337 // Create connection
338 EXPECT_CALL(*test::mock_acl_manager_, CreateConnection(_)).Times(1);
339 acl->CreateClassicConnection(address);
340
341 // Respond with a mock connection created
342 auto connection = std::make_unique<MockClassicAclConnection>(address, 123);
343 ASSERT_EQ(123, connection->GetHandle());
344 ASSERT_EQ(hci::Address({0x11, 0x22, 0x33, 0x44, 0x55, 0x66}),
345 connection->GetAddress());
346 MockClassicAclConnection* raw_connection = connection.get();
347
348 acl->OnConnectSuccess(std::move(connection));
349 ASSERT_EQ(nullptr, connection);
350
351 // Specify local disconnect request
352 auto tx_disconnect_future = raw_connection->disconnect_promise_.get_future();
353 acl->DisconnectClassic(123, HCI_SUCCESS);
354
355 // Wait for disconnect to be received
356 uint16_t result = tx_disconnect_future.get();
357 ASSERT_EQ(123, result);
358
359 // Now emulate the remote disconnect response
360 auto handle_promise = std::promise<uint16_t>();
361 auto rx_disconnect_future = handle_promise.get_future();
362 mock_function_handle_promise_map["mock_connection_classic_on_disconnected"] =
363 std::move(handle_promise);
364 raw_connection->callbacks_->OnDisconnection(hci::ErrorCode::SUCCESS);
365
366 result = rx_disconnect_future.get();
367 ASSERT_EQ(123, result);
368
369 // *Our* task completing indicates reactor is done
370 std::promise<void> done;
371 auto future = done.get_future();
372 handler_->Call([](std::promise<void> done) { done.set_value(); },
373 std::move(done));
374 future.wait();
375 }
376
TEST_F(MainShimTest,is_flushable)377 TEST_F(MainShimTest, is_flushable) {
378 {
379 BT_HDR* bt_hdr =
380 (BT_HDR*)calloc(1, sizeof(BT_HDR) + sizeof(HciDataPreamble));
381
382 ASSERT_TRUE(!IsPacketFlushable(bt_hdr));
383 HciDataPreamble* hci = ToPacketData<HciDataPreamble>(bt_hdr);
384 hci->SetFlushable();
385 ASSERT_TRUE(IsPacketFlushable(bt_hdr));
386
387 free(bt_hdr);
388 }
389
390 {
391 size_t offset = 1024;
392 BT_HDR* bt_hdr =
393 (BT_HDR*)calloc(1, sizeof(BT_HDR) + sizeof(HciDataPreamble) + offset);
394 bt_hdr->offset = offset;
395
396 ASSERT_TRUE(!IsPacketFlushable(bt_hdr));
397 HciDataPreamble* hci = ToPacketData<HciDataPreamble>(bt_hdr);
398 hci->SetFlushable();
399 ASSERT_TRUE(IsPacketFlushable(bt_hdr));
400
401 free(bt_hdr);
402 }
403
404 {
405 size_t offset = 1024;
406 BT_HDR* bt_hdr =
407 (BT_HDR*)calloc(1, sizeof(BT_HDR) + sizeof(HciDataPreamble) + offset);
408
409 uint8_t* p = ToPacketData<uint8_t>(bt_hdr, L2CAP_SEND_CMD_OFFSET);
410 UINT16_TO_STREAM(
411 p, 0x123 | (L2CAP_PKT_START_NON_FLUSHABLE << L2CAP_PKT_TYPE_SHIFT));
412 ASSERT_TRUE(!IsPacketFlushable(bt_hdr));
413
414 p = ToPacketData<uint8_t>(bt_hdr, L2CAP_SEND_CMD_OFFSET);
415 UINT16_TO_STREAM(p, 0x123 | (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT));
416 ASSERT_TRUE(IsPacketFlushable(bt_hdr));
417
418 free(bt_hdr);
419 }
420 }
421