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