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 <com_android_bluetooth_flags.h>
18 #include <flag_macros.h>
19 #include <gtest/gtest.h>
20 #include <string.h>
21 
22 #include <cstddef>
23 #include <cstdint>
24 #include <memory>
25 #include <string>
26 
27 #include "common/strings.h"
28 #include "gd/os/rand.h"
29 #include "osi/include/allocator.h"
30 #include "stack/gatt/gatt_int.h"
31 #include "stack/include/bt_types.h"
32 #include "stack/include/gatt_api.h"
33 #include "stack/include/l2cap_types.h"
34 #include "stack/sdp/internal/sdp_api.h"
35 #include "test/mock/mock_stack_sdp_legacy_api.h"
36 #include "types/bluetooth/uuid.h"
37 #include "types/raw_address.h"
38 
39 #define TEST_BT com::android::bluetooth::flags
40 
41 namespace bluetooth {
42 namespace legacy {
43 namespace testing {
44 BT_HDR* attp_build_value_cmd(uint16_t payload_size, uint8_t op_code, uint16_t handle,
45                              uint16_t offset, uint16_t len, uint8_t* p_data);
46 }  // namespace testing
47 }  // namespace legacy
48 }  // namespace bluetooth
49 
50 class StackGattTest : public ::testing::Test {
51 protected:
SetUp()52   void SetUp() override {
53     test::mock::stack_sdp_legacy::api_.handle.SDP_CreateRecord = ::SDP_CreateRecord;
54     test::mock::stack_sdp_legacy::api_.handle.SDP_AddServiceClassIdList =
55             ::SDP_AddServiceClassIdList;
56     test::mock::stack_sdp_legacy::api_.handle.SDP_AddAttribute = ::SDP_AddAttribute;
57     test::mock::stack_sdp_legacy::api_.handle.SDP_AddProtocolList = ::SDP_AddProtocolList;
58     test::mock::stack_sdp_legacy::api_.handle.SDP_AddUuidSequence = ::SDP_AddUuidSequence;
59   }
TearDown()60   void TearDown() override { test::mock::stack_sdp_legacy::api_.handle = {}; }
61 };
62 
63 namespace {
64 
65 // Actual size of structure without compiler padding
actual_sizeof_tGATT_REG()66 size_t actual_sizeof_tGATT_REG() {
67   return sizeof(bluetooth::Uuid) + sizeof(tGATT_CBACK) + sizeof(tGATT_IF) + sizeof(bool) +
68          sizeof(uint8_t) + sizeof(bool);
69 }
70 
tGATT_DISC_RES_CB(uint16_t,tGATT_DISC_TYPE,tGATT_DISC_RES *)71 void tGATT_DISC_RES_CB(uint16_t /*conn_id*/, tGATT_DISC_TYPE /*disc_type*/,
72                        tGATT_DISC_RES* /*p_data*/) {}
tGATT_DISC_CMPL_CB(uint16_t,tGATT_DISC_TYPE,tGATT_STATUS)73 void tGATT_DISC_CMPL_CB(uint16_t /*conn_id*/, tGATT_DISC_TYPE /*disc_type*/,
74                         tGATT_STATUS /*status*/) {}
tGATT_CMPL_CBACK(uint16_t,tGATTC_OPTYPE,tGATT_STATUS,tGATT_CL_COMPLETE *)75 void tGATT_CMPL_CBACK(uint16_t /*conn_id*/, tGATTC_OPTYPE /*op*/, tGATT_STATUS /*status*/,
76                       tGATT_CL_COMPLETE* /*p_data*/) {}
tGATT_CONN_CBACK(tGATT_IF,const RawAddress &,uint16_t,bool,tGATT_DISCONN_REASON,tBT_TRANSPORT)77 void tGATT_CONN_CBACK(tGATT_IF /*gatt_if*/, const RawAddress& /*bda*/, uint16_t /*conn_id*/,
78                       bool /*connected*/, tGATT_DISCONN_REASON /*reason*/,
79                       tBT_TRANSPORT /*transport*/) {}
tGATT_REQ_CBACK(uint16_t,uint32_t,tGATTS_REQ_TYPE,tGATTS_DATA *)80 void tGATT_REQ_CBACK(uint16_t /*conn_id*/, uint32_t /*trans_id*/, tGATTS_REQ_TYPE /*type*/,
81                      tGATTS_DATA* /*p_data*/) {}
tGATT_CONGESTION_CBACK(uint16_t,bool)82 void tGATT_CONGESTION_CBACK(uint16_t /*conn_id*/, bool /*congested*/) {}
tGATT_ENC_CMPL_CB(tGATT_IF,const RawAddress &)83 void tGATT_ENC_CMPL_CB(tGATT_IF /*gatt_if*/, const RawAddress& /*bda*/) {}
tGATT_PHY_UPDATE_CB(tGATT_IF,uint16_t,uint8_t,uint8_t,tGATT_STATUS)84 void tGATT_PHY_UPDATE_CB(tGATT_IF /*gatt_if*/, uint16_t /*conn_id*/, uint8_t /*tx_phy*/,
85                          uint8_t /*rx_phy*/, tGATT_STATUS /*status*/) {}
tGATT_CONN_UPDATE_CB(tGATT_IF,uint16_t,uint16_t,uint16_t,uint16_t,tGATT_STATUS)86 void tGATT_CONN_UPDATE_CB(tGATT_IF /*gatt_if*/, uint16_t /*conn_id*/, uint16_t /*interval*/,
87                           uint16_t /*latency*/, uint16_t /*timeout*/, tGATT_STATUS /*status*/) {}
88 
89 tGATT_CBACK gatt_callbacks = {
90         .p_conn_cb = tGATT_CONN_CBACK,
91         .p_cmpl_cb = tGATT_CMPL_CBACK,
92         .p_disc_res_cb = tGATT_DISC_RES_CB,
93         .p_disc_cmpl_cb = tGATT_DISC_CMPL_CB,
94         .p_req_cb = tGATT_REQ_CBACK,
95         .p_enc_cmpl_cb = tGATT_ENC_CMPL_CB,
96         .p_congestion_cb = tGATT_CONGESTION_CBACK,
97         .p_phy_update_cb = tGATT_PHY_UPDATE_CB,
98         .p_conn_update_cb = tGATT_CONN_UPDATE_CB,
99 };
100 
101 }  // namespace
102 
TEST_F(StackGattTest,lifecycle_tGATT_REG)103 TEST_F(StackGattTest, lifecycle_tGATT_REG) {
104   {
105     std::unique_ptr<tGATT_REG> reg0 = std::make_unique<tGATT_REG>();
106     std::unique_ptr<tGATT_REG> reg1 = std::make_unique<tGATT_REG>();
107     memset(reg0.get(), 0xff, sizeof(tGATT_REG));
108     memset(reg1.get(), 0xff, sizeof(tGATT_REG));
109     ASSERT_EQ(0, memcmp(reg0.get(), reg1.get(), sizeof(tGATT_REG)));
110 
111     memset(reg0.get(), 0x0, sizeof(tGATT_REG));
112     memset(reg1.get(), 0x0, sizeof(tGATT_REG));
113     ASSERT_EQ(0, memcmp(reg0.get(), reg1.get(), sizeof(tGATT_REG)));
114   }
115 
116   {
117     std::unique_ptr<tGATT_REG> reg0 = std::make_unique<tGATT_REG>();
118     memset(reg0.get(), 0xff, sizeof(tGATT_REG));
119 
120     tGATT_REG reg1;
121     memset(&reg1, 0xff, sizeof(tGATT_REG));
122 
123     // Clear the structures
124     memset(reg0.get(), 0, sizeof(tGATT_REG));
125     // Restore the complex structure after memset
126     memset(&reg1.name, 0, sizeof(std::string));
127     memset(&reg1.direct_connect_request, 0, sizeof(std::set<RawAddress>));
128     memset(&reg1.mtu_prefs, 0, sizeof(std::map<RawAddress, uint16_t>));
129     reg1 = {};
130     ASSERT_EQ(0, memcmp(reg0.get(), &reg1, actual_sizeof_tGATT_REG()));
131   }
132 
133   {
134     tGATT_REG* reg0 = new tGATT_REG();
135     tGATT_REG* reg1 = new tGATT_REG();
136     memset(reg0, 0, sizeof(tGATT_REG));
137     *reg1 = {};
138     reg0->in_use = true;
139     ASSERT_NE(0, memcmp(reg0, reg1, sizeof(tGATT_REG)));
140     delete reg1;
141     delete reg0;
142   }
143 }
144 
TEST_F(StackGattTest,gatt_init_free)145 TEST_F(StackGattTest, gatt_init_free) {
146   gatt_init();
147   gatt_free();
148 }
149 
TEST_F(StackGattTest,GATT_Register_Deregister)150 TEST_F(StackGattTest, GATT_Register_Deregister) {
151   gatt_init();
152 
153   // Gatt db profile always takes the first slot
154   tGATT_IF apps[GATT_MAX_APPS - 1];
155 
156   for (int i = 0; i < GATT_MAX_APPS - 1; i++) {
157     std::string name = bluetooth::common::StringFormat("name%02d", i);
158 
159     bluetooth::Uuid uuid = bluetooth::Uuid::From128BitBE(
160             bluetooth::os::GenerateRandom<bluetooth::Uuid::kNumBytes128>());
161     apps[i] = GATT_Register(uuid, name, &gatt_callbacks, false);
162   }
163 
164   for (int i = 0; i < GATT_MAX_APPS - 1; i++) {
165     GATT_Deregister(apps[i]);
166   }
167 
168   gatt_free();
169 }
170 
TEST_F(StackGattTest,gatt_status_text)171 TEST_F(StackGattTest, gatt_status_text) {
172   std::vector<std::pair<tGATT_STATUS, std::string>> statuses = {
173           std::make_pair(GATT_SUCCESS, "GATT_SUCCESS"),  // Also GATT_ENCRYPED_MITM
174           std::make_pair(GATT_INVALID_HANDLE, "GATT_INVALID_HANDLE"),
175           std::make_pair(GATT_READ_NOT_PERMIT, "GATT_READ_NOT_PERMIT"),
176           std::make_pair(GATT_WRITE_NOT_PERMIT, "GATT_WRITE_NOT_PERMIT"),
177           std::make_pair(GATT_INVALID_PDU, "GATT_INVALID_PDU"),
178           std::make_pair(GATT_INSUF_AUTHENTICATION, "GATT_INSUF_AUTHENTICATION"),
179           std::make_pair(GATT_REQ_NOT_SUPPORTED, "GATT_REQ_NOT_SUPPORTED"),
180           std::make_pair(GATT_INVALID_OFFSET, "GATT_INVALID_OFFSET"),
181           std::make_pair(GATT_INSUF_AUTHORIZATION, "GATT_INSUF_AUTHORIZATION"),
182           std::make_pair(GATT_PREPARE_Q_FULL, "GATT_PREPARE_Q_FULL"),
183           std::make_pair(GATT_NOT_FOUND, "GATT_NOT_FOUND"),
184           std::make_pair(GATT_NOT_LONG, "GATT_NOT_LONG"),
185           std::make_pair(GATT_INSUF_KEY_SIZE, "GATT_INSUF_KEY_SIZE"),
186           std::make_pair(GATT_INVALID_ATTR_LEN, "GATT_INVALID_ATTR_LEN"),
187           std::make_pair(GATT_ERR_UNLIKELY, "GATT_ERR_UNLIKELY"),
188           std::make_pair(GATT_INSUF_ENCRYPTION, "GATT_INSUF_ENCRYPTION"),
189           std::make_pair(GATT_UNSUPPORT_GRP_TYPE, "GATT_UNSUPPORT_GRP_TYPE"),
190           std::make_pair(GATT_INSUF_RESOURCE, "GATT_INSUF_RESOURCE"),
191           std::make_pair(GATT_DATABASE_OUT_OF_SYNC, "GATT_DATABASE_OUT_OF_SYNC"),
192           std::make_pair(GATT_VALUE_NOT_ALLOWED, "GATT_VALUE_NOT_ALLOWED"),
193           std::make_pair(GATT_ILLEGAL_PARAMETER, "GATT_ILLEGAL_PARAMETER"),
194           std::make_pair(GATT_NO_RESOURCES, "GATT_NO_RESOURCES"),
195           std::make_pair(GATT_INTERNAL_ERROR, "GATT_INTERNAL_ERROR"),
196           std::make_pair(GATT_WRONG_STATE, "GATT_WRONG_STATE"),
197           std::make_pair(GATT_DB_FULL, "GATT_DB_FULL"),
198           std::make_pair(GATT_BUSY, "GATT_BUSY"),
199           std::make_pair(GATT_ERROR, "GATT_ERROR"),
200           std::make_pair(GATT_CMD_STARTED, "GATT_CMD_STARTED"),
201           std::make_pair(GATT_PENDING, "GATT_PENDING"),
202           std::make_pair(GATT_AUTH_FAIL, "GATT_AUTH_FAIL"),
203           std::make_pair(GATT_INVALID_CFG, "GATT_INVALID_CFG"),
204           std::make_pair(GATT_SERVICE_STARTED, "GATT_SERVICE_STARTED"),
205           std::make_pair(GATT_ENCRYPED_NO_MITM, "GATT_ENCRYPED_NO_MITM"),
206           std::make_pair(GATT_NOT_ENCRYPTED, "GATT_NOT_ENCRYPTED"),
207           std::make_pair(GATT_CONGESTED, "GATT_CONGESTED"),
208           std::make_pair(GATT_DUP_REG, "GATT_DUP_REG"),
209           std::make_pair(GATT_ALREADY_OPEN, "GATT_ALREADY_OPEN"),
210           std::make_pair(GATT_CANCEL, "GATT_CANCEL"),
211           std::make_pair(GATT_CONNECTION_TIMEOUT, "GATT_CONNECTION_TIMEOUT"),
212           std::make_pair(GATT_CCC_CFG_ERR, "GATT_CCC_CFG_ERR"),
213           std::make_pair(GATT_PRC_IN_PROGRESS, "GATT_PRC_IN_PROGRESS"),
214           std::make_pair(GATT_OUT_OF_RANGE, "GATT_OUT_OF_RANGE"),
215   };
216   for (const auto& status : statuses) {
217     ASSERT_STREQ(status.second.c_str(), gatt_status_text(status.first).c_str());
218   }
219   // Typical max value is already classified so use arbitrary unused one.
220   auto unknown = base::StringPrintf("UNKNOWN[%hhu]", 0xfc);
221   ASSERT_STREQ(unknown.c_str(), gatt_status_text(static_cast<tGATT_STATUS>(0xfc)).c_str());
222 }
223 
224 const static std::map<uint8_t, uint16_t> gatt_min_value_cmd_size{
225         {GATT_RSP_READ_BY_TYPE, 4},  // op_code (1) + pair_len (1) + handle (2)
226         {GATT_RSP_READ_BLOB, 1},     // op_code (1)
227         {GATT_RSP_READ, 1},
228         {GATT_REQ_PREPARE_WRITE, 5},     // op_code (1) + handle (2) + offset (2)
229         {GATT_REQ_READ_BY_GRP_TYPE, 3},  // op_code + handle
230 };
231 
attp_build_value_cmd_test_with_p_data(uint16_t payload_size,uint8_t op_code,uint16_t handle,uint16_t offset,uint16_t len,uint8_t * p_data)232 static void attp_build_value_cmd_test_with_p_data(uint16_t payload_size, uint8_t op_code,
233                                                   uint16_t handle, uint16_t offset, uint16_t len,
234                                                   uint8_t* p_data) {
235   uint16_t min_payload_size;
236   uint8_t pair_len_read;
237   uint16_t offset_read = 0;
238   uint16_t handle_read = 0;
239 
240   ASSERT_TRUE(gatt_min_value_cmd_size.find(op_code) != gatt_min_value_cmd_size.end());
241   min_payload_size = gatt_min_value_cmd_size.at(op_code);
242 
243   ASSERT_GE(payload_size, min_payload_size);
244 
245   BT_HDR* ret = bluetooth::legacy::testing::attp_build_value_cmd(payload_size, op_code, handle,
246                                                                  offset, len, p_data);
247 
248   ASSERT_NE(ret, nullptr);
249   uint8_t* p = (uint8_t*)(ret + 1) + L2CAP_MIN_OFFSET;
250 
251   uint8_t op_code_read;
252   STREAM_TO_UINT8(op_code_read, p);
253   ASSERT_EQ(op_code_read, op_code);
254 
255   if (op_code == GATT_RSP_READ_BY_TYPE) {
256     STREAM_TO_UINT8(pair_len_read, p);
257 
258     STREAM_TO_UINT16(handle_read, p);
259     ASSERT_EQ(handle_read, handle);
260   } else if (op_code == GATT_RSP_READ_BLOB || op_code == GATT_RSP_READ) {
261     ;
262   } else if (op_code == GATT_REQ_PREPARE_WRITE || op_code == GATT_RSP_PREPARE_WRITE) {
263     STREAM_TO_UINT16(handle_read, p);
264     ASSERT_EQ(handle_read, handle);
265     STREAM_TO_UINT16(offset_read, p);
266     ASSERT_EQ(offset_read, offset);
267   } else {
268     STREAM_TO_UINT16(handle_read, p);
269     ASSERT_EQ(handle_read, handle);
270   }
271 
272   uint16_t actual_payload_size;
273   uint8_t pair_len;
274 
275   if (p_data != nullptr) {
276     if (min_payload_size + len <= payload_size) {
277       actual_payload_size = min_payload_size + len;
278       pair_len = len + 2;
279     } else {
280       actual_payload_size = payload_size;
281       pair_len = payload_size - min_payload_size + 2;
282     }
283 
284     size_t cmp_size = actual_payload_size - min_payload_size;
285     int ret = memcmp(p_data, p, cmp_size);
286     ASSERT_EQ(ret, 0);
287 
288   } else {
289     pair_len = len + 2;
290     actual_payload_size = min_payload_size;
291   }
292 
293   ASSERT_EQ(ret->len, actual_payload_size);
294 
295   if (op_code == GATT_RSP_READ_BY_TYPE) {
296     ASSERT_EQ(pair_len_read, pair_len);
297   }
298 
299   osi_free_and_reset((void**)&ret);
300 }
301 
TEST_F(StackGattTest,attp_build_value_cmd_p_data_null)302 TEST_F(StackGattTest, attp_build_value_cmd_p_data_null) {
303   for (auto it = gatt_min_value_cmd_size.begin(); it != gatt_min_value_cmd_size.end(); it++) {
304     attp_build_value_cmd_test_with_p_data(it->second, it->first, 0x1, 0x1234, 0, nullptr);
305   }
306 }
307 
TEST_F(StackGattTest,attp_build_value_cmd_no_p_data)308 TEST_F(StackGattTest, attp_build_value_cmd_no_p_data) {
309   for (auto it = gatt_min_value_cmd_size.begin(); it != gatt_min_value_cmd_size.end(); it++) {
310     attp_build_value_cmd_test_with_p_data(it->second, it->first, 0x1, 0x1234, 3, (uint8_t*)"abc");
311   }
312 }
313 
TEST_F(StackGattTest,attp_build_value_cmd_partial_p_data)314 TEST_F(StackGattTest, attp_build_value_cmd_partial_p_data) {
315   for (auto it = gatt_min_value_cmd_size.begin(); it != gatt_min_value_cmd_size.end(); it++) {
316     attp_build_value_cmd_test_with_p_data(it->second + 1, it->first, 0x1, 0x1234, 3,
317                                           (uint8_t*)"abc");
318   }
319 }
320 
TEST_F(StackGattTest,attp_build_value_cmd_full_p_data)321 TEST_F(StackGattTest, attp_build_value_cmd_full_p_data) {
322   for (auto it = gatt_min_value_cmd_size.begin(); it != gatt_min_value_cmd_size.end(); it++) {
323     attp_build_value_cmd_test_with_p_data(it->second + 5, it->first, 0x1, 0x1234, 3,
324                                           (uint8_t*)"abc");
325   }
326 }
327 
attp_build_value_cmd_small_payload_size(uint8_t op_code)328 static void attp_build_value_cmd_small_payload_size(uint8_t op_code) {
329   // payload size too small
330   uint16_t offset_0 = 0;
331   uint16_t handle = 0x1;
332   uint16_t len = 0;
333   uint8_t* p_data = nullptr;
334   uint16_t test_payload_size = gatt_min_value_cmd_size.at(op_code) - 1;
335 
336   ASSERT_TRUE(gatt_min_value_cmd_size.find(op_code) != gatt_min_value_cmd_size.end());
337   test_payload_size = gatt_min_value_cmd_size.at(op_code) - 1;
338 
339   BT_HDR* ret = bluetooth::legacy::testing::attp_build_value_cmd(test_payload_size, op_code, handle,
340                                                                  offset_0, len, p_data);
341 
342   ASSERT_EQ(ret, nullptr);
343 }
344 
TEST_F(StackGattTest,attp_build_value_cmd_test_payload_size_less_than_mimimal)345 TEST_F(StackGattTest, attp_build_value_cmd_test_payload_size_less_than_mimimal) {
346   for (auto it = gatt_min_value_cmd_size.begin(); it != gatt_min_value_cmd_size.end(); it++) {
347     attp_build_value_cmd_small_payload_size(it->first);
348   }
349 }
350 
TEST_F(StackGattTest,attp_build_value_cmd_read_by_type_test_long_data)351 TEST_F(StackGattTest, attp_build_value_cmd_read_by_type_test_long_data) {
352   // p_data too large and does not fit in pair_len
353   // only for GATT_RSP_READ_BY_TYPE
354   uint16_t offset_0 = 0;
355   uint16_t handle = 0x1;
356   const uint8_t op_code = GATT_RSP_READ_BY_TYPE;
357 
358   const int data_size = 255;
359   uint16_t payload_size = data_size + 4;
360 
361   uint8_t data[data_size];
362 
363   for (int i = 0; i < data_size; i++) {
364     data[i] = 'A';
365   }
366 
367   BT_HDR* ret = bluetooth::legacy::testing::attp_build_value_cmd(payload_size, op_code, handle,
368                                                                  offset_0, data_size, data);
369   ASSERT_EQ(ret, nullptr);
370 }
371