• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 =
__anon24cf8d0a0202() 258     ModuleFactory([]() { return nullptr; });
259 }  // namespace activity_attribution
260 
261 namespace hal {
__anon24cf8d0a0302() 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