1 /*
2 * Copyright 2020 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
18 #include <gmock/gmock.h>
19 #include <gtest/gtest.h>
20
21 #include <iostream>
22 #include <sstream>
23
24 #include "common/init_flags.h"
25 #include "hci/controller_interface_mock.h"
26 #include "hci/hci_layer_mock.h"
27 #include "stack/btm/btm_dev.h"
28 #include "stack/btm/btm_int_types.h"
29 #include "stack/btm/btm_sco.h"
30 #include "stack/btm/btm_sec.h"
31 #include "stack/btm/btm_sec_cb.h"
32 #include "stack/include/acl_api.h"
33 #include "stack/include/acl_hci_link_interface.h"
34 #include "stack/include/btm_client_interface.h"
35 #include "stack/l2cap/l2c_int.h"
36 #include "stack/test/btm/btm_test_fixtures.h"
37 #include "test/common/mock_functions.h"
38 #include "test/mock/mock_legacy_hci_interface.h"
39 #include "test/mock/mock_main_shim_entry.h"
40 #include "types/raw_address.h"
41
42 using testing::Each;
43 using testing::Eq;
44
45 extern tBTM_CB btm_cb;
46
47 tL2C_CB l2cb;
48
49 const std::string kSmpOptions("mock smp options");
50 const std::string kBroadcastAudioConfigOptions(
51 "mock broadcast audio config options");
52
53 namespace {
54
55 using testing::Return;
56 using testing::Test;
57
58 class StackBtmTest : public BtmWithMocksTest {
59 public:
60 protected:
SetUp()61 void SetUp() override {
62 BtmWithMocksTest::SetUp();
63 bluetooth::hci::testing::mock_controller_ = &controller_;
64 }
TearDown()65 void TearDown() override {
66 bluetooth::hci::testing::mock_controller_ = nullptr;
67 BtmWithMocksTest::TearDown();
68 }
69 bluetooth::hci::testing::MockControllerInterface controller_;
70 };
71
72 class StackBtmWithQueuesTest : public StackBtmTest {
73 public:
74 protected:
SetUp()75 void SetUp() override {
76 StackBtmTest::SetUp();
77 up_thread_ = new bluetooth::os::Thread(
78 "up_thread", bluetooth::os::Thread::Priority::NORMAL);
79 up_handler_ = new bluetooth::os::Handler(up_thread_);
80 down_thread_ = new bluetooth::os::Thread(
81 "down_thread", bluetooth::os::Thread::Priority::NORMAL);
82 down_handler_ = new bluetooth::os::Handler(down_thread_);
83 bluetooth::hci::testing::mock_hci_layer_ = &mock_hci_;
84 bluetooth::hci::testing::mock_gd_shim_handler_ = up_handler_;
85 bluetooth::legacy::hci::testing::SetMock(legacy_hci_mock_);
86 }
TearDown()87 void TearDown() override {
88 up_handler_->Clear();
89 delete up_handler_;
90 delete up_thread_;
91 down_handler_->Clear();
92 delete down_handler_;
93 delete down_thread_;
94 StackBtmTest::TearDown();
95 }
96 bluetooth::common::BidiQueue<bluetooth::hci::ScoView,
97 bluetooth::hci::ScoBuilder>
98 sco_queue_{10};
99 bluetooth::hci::testing::MockHciLayer mock_hci_;
100 bluetooth::legacy::hci::testing::MockInterface legacy_hci_mock_;
101 bluetooth::os::Thread* up_thread_;
102 bluetooth::os::Handler* up_handler_;
103 bluetooth::os::Thread* down_thread_;
104 bluetooth::os::Handler* down_handler_;
105 };
106
107 class StackBtmWithInitFreeTest : public StackBtmWithQueuesTest {
108 public:
109 protected:
SetUp()110 void SetUp() override {
111 StackBtmWithQueuesTest::SetUp();
112 EXPECT_CALL(mock_hci_, GetScoQueueEnd())
113 .WillOnce(Return(sco_queue_.GetUpEnd()));
114
115 btm_cb.Init();
116 btm_sec_cb.Init(BTM_SEC_MODE_SC);
117 }
TearDown()118 void TearDown() override {
119 btm_sec_cb.Free();
120 btm_cb.Free();
121 StackBtmWithQueuesTest::TearDown();
122 }
123 };
124
TEST_F(StackBtmWithQueuesTest,GlobalLifecycle)125 TEST_F(StackBtmWithQueuesTest, GlobalLifecycle) {
126 EXPECT_CALL(mock_hci_, GetScoQueueEnd())
127 .WillOnce(Return(sco_queue_.GetUpEnd()));
128 get_btm_client_interface().lifecycle.btm_init();
129 get_btm_client_interface().lifecycle.btm_free();
130 }
131
TEST_F(StackBtmTest,DynamicLifecycle)132 TEST_F(StackBtmTest, DynamicLifecycle) {
133 auto* btm = new tBTM_CB();
134 delete btm;
135 }
136
TEST_F(StackBtmWithQueuesTest,InitFree)137 TEST_F(StackBtmWithQueuesTest, InitFree) {
138 EXPECT_CALL(mock_hci_, GetScoQueueEnd())
139 .WillOnce(Return(sco_queue_.GetUpEnd()));
140 btm_cb.Init();
141 btm_cb.Free();
142 }
143
TEST_F(StackBtmWithQueuesTest,tSCO_CB)144 TEST_F(StackBtmWithQueuesTest, tSCO_CB) {
145 EXPECT_CALL(mock_hci_, GetScoQueueEnd())
146 .WillOnce(Return(sco_queue_.GetUpEnd()));
147 bluetooth::common::InitFlags::SetAllForTesting();
148 tSCO_CB* p_sco = &btm_cb.sco_cb;
149 p_sco->Init();
150 p_sco->Free();
151 }
152
TEST_F(StackBtmWithQueuesTest,InformClientOnConnectionSuccess)153 TEST_F(StackBtmWithQueuesTest, InformClientOnConnectionSuccess) {
154 EXPECT_CALL(mock_hci_, GetScoQueueEnd())
155 .WillOnce(Return(sco_queue_.GetUpEnd()));
156 get_btm_client_interface().lifecycle.btm_init();
157
158 RawAddress bda({0x11, 0x22, 0x33, 0x44, 0x55, 0x66});
159
160 btm_acl_connected(bda, 2, HCI_SUCCESS, false);
161 ASSERT_EQ(1, get_func_call_count("BTA_dm_acl_up"));
162
163 get_btm_client_interface().lifecycle.btm_free();
164 }
165
TEST_F(StackBtmWithQueuesTest,NoInformClientOnConnectionFail)166 TEST_F(StackBtmWithQueuesTest, NoInformClientOnConnectionFail) {
167 EXPECT_CALL(mock_hci_, GetScoQueueEnd())
168 .WillOnce(Return(sco_queue_.GetUpEnd()));
169 get_btm_client_interface().lifecycle.btm_init();
170
171 RawAddress bda({0x11, 0x22, 0x33, 0x44, 0x55, 0x66});
172
173 btm_acl_connected(bda, 2, HCI_ERR_NO_CONNECTION, false);
174 ASSERT_EQ(0, get_func_call_count("BTA_dm_acl_up"));
175
176 get_btm_client_interface().lifecycle.btm_free();
177 }
178
TEST_F(StackBtmWithQueuesTest,default_packet_type)179 TEST_F(StackBtmWithQueuesTest, default_packet_type) {
180 EXPECT_CALL(mock_hci_, GetScoQueueEnd())
181 .WillOnce(Return(sco_queue_.GetUpEnd()));
182 get_btm_client_interface().lifecycle.btm_init();
183
184 btm_cb.acl_cb_.SetDefaultPacketTypeMask(0x4321);
185 ASSERT_EQ(0x4321, btm_cb.acl_cb_.DefaultPacketTypes());
186
187 get_btm_client_interface().lifecycle.btm_free();
188 }
189
TEST_F(StackBtmWithQueuesTest,change_packet_type)190 TEST_F(StackBtmWithQueuesTest, change_packet_type) {
191 EXPECT_CALL(mock_hci_, GetScoQueueEnd())
192 .WillOnce(Return(sco_queue_.GetUpEnd()));
193 get_btm_client_interface().lifecycle.btm_init();
194
195 uint16_t handle = 0x123;
196
197 btm_cb.acl_cb_.SetDefaultPacketTypeMask(0xffff);
198 ASSERT_EQ(0xffff, btm_cb.acl_cb_.DefaultPacketTypes());
199
200 // Create connection
201 RawAddress bda({0x11, 0x22, 0x33, 0x44, 0x55, 0x66});
202 btm_acl_created(bda, handle, HCI_ROLE_CENTRAL, BT_TRANSPORT_BR_EDR);
203
204 uint64_t features = 0xffffffffffffffff;
205 acl_process_supported_features(0x123, features);
206
207 EXPECT_CALL(legacy_hci_mock_, ChangeConnectionPacketType(
208 handle, 0x4400 | HCI_PKT_TYPES_MASK_DM1));
209 EXPECT_CALL(legacy_hci_mock_, ChangeConnectionPacketType(
210 handle, (0xcc00 | HCI_PKT_TYPES_MASK_DM1 |
211 HCI_PKT_TYPES_MASK_DH1)));
212
213 btm_set_packet_types_from_address(bda, 0x55aa);
214 btm_set_packet_types_from_address(bda, 0xffff);
215 // Illegal mask, won't be sent.
216 btm_set_packet_types_from_address(bda, 0x0);
217
218 get_btm_client_interface().lifecycle.btm_free();
219 }
220
TEST(BtmTest,BTM_EIR_MAX_SERVICES)221 TEST(BtmTest, BTM_EIR_MAX_SERVICES) { ASSERT_EQ(46, BTM_EIR_MAX_SERVICES); }
222
223 } // namespace
224
225 void btm_sec_rmt_name_request_complete(const RawAddress* p_bd_addr,
226 const uint8_t* p_bd_name,
227 tHCI_STATUS status);
228
229 struct {
230 RawAddress bd_addr;
231 DEV_CLASS dc;
232 BD_NAME bd_name;
233 } btm_test;
234
TEST_F(StackBtmWithInitFreeTest,btm_sec_rmt_name_request_complete)235 TEST_F(StackBtmWithInitFreeTest, btm_sec_rmt_name_request_complete) {
236 bluetooth::common::InitFlags::SetAllForTesting();
237
238 ASSERT_TRUE(BTM_SecAddRmtNameNotifyCallback(
239 [](const RawAddress& bd_addr, DEV_CLASS dc, BD_NAME bd_name) {
240 btm_test.bd_addr = bd_addr;
241 btm_test.dc = dc;
242 memcpy(btm_test.bd_name, bd_name, BD_NAME_LEN);
243 }));
244
245 RawAddress bd_addr = RawAddress({0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6});
246 const uint8_t* p_bd_name = (const uint8_t*)"MyTestName";
247
248 btm_test = {};
249 btm_sec_rmt_name_request_complete(&bd_addr, p_bd_name, HCI_SUCCESS);
250
251 ASSERT_THAT(btm_test.bd_name, Each(Eq(0)));
252 ASSERT_THAT(btm_test.dc, Each(Eq(0)));
253 ASSERT_EQ(bd_addr, btm_test.bd_addr);
254
255 btm_test = {};
256 ASSERT_TRUE(btm_find_or_alloc_dev(bd_addr) != nullptr);
257 btm_sec_rmt_name_request_complete(&bd_addr, p_bd_name, HCI_SUCCESS);
258
259 ASSERT_STREQ((const char*)p_bd_name, (const char*)btm_test.bd_name);
260 ASSERT_THAT(btm_test.dc, Each(Eq(0)));
261 ASSERT_EQ(bd_addr, btm_test.bd_addr);
262 }
263
TEST_F(StackBtmTest,sco_state_text)264 TEST_F(StackBtmTest, sco_state_text) {
265 std::vector<std::pair<tSCO_STATE, std::string>> states = {
266 std::make_pair(SCO_ST_UNUSED, "SCO_ST_UNUSED"),
267 std::make_pair(SCO_ST_LISTENING, "SCO_ST_LISTENING"),
268 std::make_pair(SCO_ST_W4_CONN_RSP, "SCO_ST_W4_CONN_RSP"),
269 std::make_pair(SCO_ST_CONNECTING, "SCO_ST_CONNECTING"),
270 std::make_pair(SCO_ST_CONNECTED, "SCO_ST_CONNECTED"),
271 std::make_pair(SCO_ST_DISCONNECTING, "SCO_ST_DISCONNECTING"),
272 std::make_pair(SCO_ST_PEND_UNPARK, "SCO_ST_PEND_UNPARK"),
273 std::make_pair(SCO_ST_PEND_ROLECHANGE, "SCO_ST_PEND_ROLECHANGE"),
274 std::make_pair(SCO_ST_PEND_MODECHANGE, "SCO_ST_PEND_MODECHANGE"),
275 };
276 for (const auto& state : states) {
277 ASSERT_STREQ(state.second.c_str(), sco_state_text(state.first).c_str());
278 }
279 std::ostringstream oss;
280 oss << "unknown_sco_state: " << std::numeric_limits<std::uint16_t>::max();
281 ASSERT_STREQ(oss.str().c_str(),
282 sco_state_text(static_cast<tSCO_STATE>(
283 std::numeric_limits<std::uint16_t>::max()))
284 .c_str());
285 }
286
287 bool is_disconnect_reason_valid(const tHCI_REASON& reason);
TEST_F(StackBtmWithInitFreeTest,is_disconnect_reason_valid)288 TEST_F(StackBtmWithInitFreeTest, is_disconnect_reason_valid) {
289 std::set<tHCI_REASON> valid_reason_set{
290 HCI_ERR_AUTH_FAILURE,
291 HCI_ERR_PEER_USER,
292 HCI_ERR_REMOTE_LOW_RESOURCE,
293 HCI_ERR_REMOTE_POWER_OFF,
294 HCI_ERR_UNSUPPORTED_REM_FEATURE,
295 HCI_ERR_PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED,
296 HCI_ERR_UNACCEPT_CONN_INTERVAL,
297 };
298 for (unsigned u = 0; u < 256; u++) {
299 const tHCI_REASON reason = static_cast<tHCI_REASON>(u);
300 if (valid_reason_set.count(reason))
301 ASSERT_TRUE(is_disconnect_reason_valid(reason));
302 else
303 ASSERT_FALSE(is_disconnect_reason_valid(reason));
304 }
305 }
306
TEST_F(StackBtmWithInitFreeTest,Init)307 TEST_F(StackBtmWithInitFreeTest, Init) {
308 ASSERT_FALSE(btm_cb.btm_inq_vars.remname_active);
309 }
310