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