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 #include <base/logging.h>
18 #include <gtest/gtest.h>
19 #include <stdio.h>
20 #include <cstdint>
21 
22 #include "osi/test/AllocationTestHarness.h"
23 #include "stack/test/common/mock_eatt.h"
24 #include "stack/gatt/gatt_int.h"
25 #undef LOG_TAG
26 #include "stack/gatt/gatt_sr.cc"
27 #include "types/raw_address.h"
28 
29 #define MAX_UINT16 ((uint16_t)0xffff)
30 
31 bool MOCK_bluetooth_shim_is_gd_acl_enabled_ = true;
32 std::map<std::string, int> mock_function_count_map;
33 
34 tGATT_CB gatt_cb;
35 
36 namespace {
37 
38 struct TestMutables {
39   struct {
40     uint8_t op_code_;
41   } attp_build_sr_msg;
42   struct {
43     uint16_t conn_id_{0};
44     uint32_t trans_id_{0};
45     tGATTS_REQ_TYPE type_{0xff};
46     tGATTS_DATA data_;
47   } application_request_callback;
48   struct {
49     int access_count_{0};
50     tGATT_STATUS return_status_{GATT_SUCCESS};
51   } gatts_write_attr_perm_check;
52 };
53 
54 TestMutables test_state_;
55 }  // namespace
56 
57 namespace connection_manager {
background_connect_remove(uint8_t app_id,const RawAddress & address)58 bool background_connect_remove(uint8_t app_id, const RawAddress& address) {
59   return false;
60 }
direct_connect_remove(uint8_t app_id,const RawAddress & address)61 bool direct_connect_remove(uint8_t app_id, const RawAddress& address) {
62   return false;
63 }
64 }  // namespace connection_manager
65 
attp_build_sr_msg(tGATT_TCB & tcb,uint8_t op_code,tGATT_SR_MSG * p_msg)66 BT_HDR* attp_build_sr_msg(tGATT_TCB& tcb, uint8_t op_code,
67                           tGATT_SR_MSG* p_msg) {
68   test_state_.attp_build_sr_msg.op_code_ = op_code;
69   return nullptr;
70 }
attp_send_cl_confirmation_msg(tGATT_TCB & tcb,uint16_t cid)71 tGATT_STATUS attp_send_cl_confirmation_msg(tGATT_TCB& tcb, uint16_t cid) {
72   return GATT_SUCCESS;
73 }
attp_send_cl_msg(tGATT_TCB & tcb,tGATT_CLCB * p_clcb,uint8_t op_code,tGATT_CL_MSG * p_msg)74 tGATT_STATUS attp_send_cl_msg(tGATT_TCB& tcb, tGATT_CLCB* p_clcb,
75                               uint8_t op_code, tGATT_CL_MSG* p_msg) {
76   return GATT_SUCCESS;
77 }
attp_send_sr_msg(tGATT_TCB & tcb,uint16_t cid,BT_HDR * p_msg)78 tGATT_STATUS attp_send_sr_msg(tGATT_TCB& tcb, uint16_t cid, BT_HDR* p_msg) {
79   return GATT_SUCCESS;
80 }
81 
BTM_SetBleDataLength(const RawAddress & bd_addr,uint16_t length)82 tBTM_STATUS BTM_SetBleDataLength(const RawAddress& bd_addr, uint16_t length) {
83   return BTM_SUCCESS;
84 }
85 
btm_ble_read_sec_key_size(const RawAddress & bd_addr)86 uint8_t btm_ble_read_sec_key_size(const RawAddress& bd_addr) { return 0; }
BTM_GetSecurityFlagsByTransport(const RawAddress & bd_addr,uint8_t * p_sec_flags,tBT_TRANSPORT transport)87 bool BTM_GetSecurityFlagsByTransport(const RawAddress& bd_addr,
88                                      uint8_t* p_sec_flags,
89                                      tBT_TRANSPORT transport) {
90   return false;
91 }
gatt_act_discovery(tGATT_CLCB * p_clcb)92 void gatt_act_discovery(tGATT_CLCB* p_clcb) {}
gatt_disconnect(tGATT_TCB * p_tcb)93 bool gatt_disconnect(tGATT_TCB* p_tcb) { return false; }
gatt_get_ch_state(tGATT_TCB * p_tcb)94 tGATT_CH_STATE gatt_get_ch_state(tGATT_TCB* p_tcb) { return GATT_CH_CLOSE; }
gatts_db_read_attr_value_by_type(tGATT_TCB & tcb,uint16_t cid,tGATT_SVC_DB * p_db,uint8_t op_code,BT_HDR * p_rsp,uint16_t s_handle,uint16_t e_handle,const Uuid & type,uint16_t * p_len,tGATT_SEC_FLAG sec_flag,uint8_t key_size,uint32_t trans_id,uint16_t * p_cur_handle)95 tGATT_STATUS gatts_db_read_attr_value_by_type(
96     tGATT_TCB& tcb, uint16_t cid, tGATT_SVC_DB* p_db, uint8_t op_code,
97     BT_HDR* p_rsp, uint16_t s_handle, uint16_t e_handle, const Uuid& type,
98     uint16_t* p_len, tGATT_SEC_FLAG sec_flag, uint8_t key_size,
99     uint32_t trans_id, uint16_t* p_cur_handle) {
100   return GATT_SUCCESS;
101 }
gatt_set_ch_state(tGATT_TCB * p_tcb,tGATT_CH_STATE ch_state)102 void gatt_set_ch_state(tGATT_TCB* p_tcb, tGATT_CH_STATE ch_state) {}
gatts_get_service_uuid(tGATT_SVC_DB * p_db)103 Uuid* gatts_get_service_uuid(tGATT_SVC_DB* p_db) { return nullptr; }
GATTS_HandleValueIndication(uint16_t conn_id,uint16_t attr_handle,uint16_t val_len,uint8_t * p_val)104 tGATT_STATUS GATTS_HandleValueIndication(uint16_t conn_id, uint16_t attr_handle,
105                                          uint16_t val_len, uint8_t* p_val) {
106   return GATT_SUCCESS;
107 }
gatts_read_attr_perm_check(tGATT_SVC_DB * p_db,bool is_long,uint16_t handle,tGATT_SEC_FLAG sec_flag,uint8_t key_size)108 tGATT_STATUS gatts_read_attr_perm_check(tGATT_SVC_DB* p_db, bool is_long,
109                                         uint16_t handle,
110                                         tGATT_SEC_FLAG sec_flag,
111                                         uint8_t key_size) {
112   return GATT_SUCCESS;
113 }
gatts_read_attr_value_by_handle(tGATT_TCB & tcb,uint16_t cid,tGATT_SVC_DB * p_db,uint8_t op_code,uint16_t handle,uint16_t offset,uint8_t * p_value,uint16_t * p_len,uint16_t mtu,tGATT_SEC_FLAG sec_flag,uint8_t key_size,uint32_t trans_id)114 tGATT_STATUS gatts_read_attr_value_by_handle(
115     tGATT_TCB& tcb, uint16_t cid, tGATT_SVC_DB* p_db, uint8_t op_code,
116     uint16_t handle, uint16_t offset, uint8_t* p_value, uint16_t* p_len,
117     uint16_t mtu, tGATT_SEC_FLAG sec_flag, uint8_t key_size,
118     uint32_t trans_id) {
119   return GATT_SUCCESS;
120 }
gatts_write_attr_perm_check(tGATT_SVC_DB * p_db,uint8_t op_code,uint16_t handle,uint16_t offset,uint8_t * p_data,uint16_t len,tGATT_SEC_FLAG sec_flag,uint8_t key_size)121 tGATT_STATUS gatts_write_attr_perm_check(tGATT_SVC_DB* p_db, uint8_t op_code,
122                                          uint16_t handle, uint16_t offset,
123                                          uint8_t* p_data, uint16_t len,
124                                          tGATT_SEC_FLAG sec_flag,
125                                          uint8_t key_size) {
126   test_state_.gatts_write_attr_perm_check.access_count_++;
127   return test_state_.gatts_write_attr_perm_check.return_status_;
128 }
gatt_update_app_use_link_flag(tGATT_IF gatt_if,tGATT_TCB * p_tcb,bool is_add,bool check_acl_link)129 void gatt_update_app_use_link_flag(tGATT_IF gatt_if, tGATT_TCB* p_tcb,
130                                    bool is_add, bool check_acl_link) {}
get_main_thread()131 bluetooth::common::MessageLoopThread* get_main_thread() { return nullptr; }
l2cble_set_fixed_channel_tx_data_length(const RawAddress & remote_bda,uint16_t fix_cid,uint16_t tx_mtu)132 void l2cble_set_fixed_channel_tx_data_length(const RawAddress& remote_bda,
133                                              uint16_t fix_cid,
134                                              uint16_t tx_mtu) {}
L2CA_SetLeFixedChannelTxDataLength(const RawAddress & remote_bda,uint16_t fix_cid,uint16_t tx_mtu)135 void L2CA_SetLeFixedChannelTxDataLength(const RawAddress& remote_bda,
136                                         uint16_t fix_cid,
137                                         uint16_t tx_mtu) {}
SDP_AddAttribute(uint32_t handle,uint16_t attr_id,uint8_t attr_type,uint32_t attr_len,uint8_t * p_val)138 bool SDP_AddAttribute(uint32_t handle, uint16_t attr_id, uint8_t attr_type,
139                       uint32_t attr_len, uint8_t* p_val) {
140   return false;
141 }
SDP_AddProtocolList(uint32_t handle,uint16_t num_elem,tSDP_PROTOCOL_ELEM * p_elem_list)142 bool SDP_AddProtocolList(uint32_t handle, uint16_t num_elem,
143                          tSDP_PROTOCOL_ELEM* p_elem_list) {
144   return false;
145 }
SDP_AddServiceClassIdList(uint32_t handle,uint16_t num_services,uint16_t * p_service_uuids)146 bool SDP_AddServiceClassIdList(uint32_t handle, uint16_t num_services,
147                                uint16_t* p_service_uuids) {
148   return false;
149 }
SDP_AddUuidSequence(uint32_t handle,uint16_t attr_id,uint16_t num_uuids,uint16_t * p_uuids)150 bool SDP_AddUuidSequence(uint32_t handle, uint16_t attr_id, uint16_t num_uuids,
151                          uint16_t* p_uuids) {
152   return false;
153 }
SDP_CreateRecord(void)154 uint32_t SDP_CreateRecord(void) { return 0; }
155 
ApplicationRequestCallback(uint16_t conn_id,uint32_t trans_id,tGATTS_REQ_TYPE type,tGATTS_DATA * p_data)156 void ApplicationRequestCallback(uint16_t conn_id, uint32_t trans_id,
157                                 tGATTS_REQ_TYPE type, tGATTS_DATA* p_data) {
158   test_state_.application_request_callback.conn_id_ = conn_id;
159   test_state_.application_request_callback.trans_id_ = trans_id;
160   test_state_.application_request_callback.type_ = type;
161   test_state_.application_request_callback.data_ = *p_data;
162 }
163 
gatt_sr_is_cl_change_aware(tGATT_TCB & tcb)164 bool gatt_sr_is_cl_change_aware(tGATT_TCB& tcb) { return false; }
gatt_sr_init_cl_status(tGATT_TCB & p_tcb)165 void gatt_sr_init_cl_status(tGATT_TCB& p_tcb) {}
gatt_sr_update_cl_status(tGATT_TCB & p_tcb,bool chg_aware)166 void gatt_sr_update_cl_status(tGATT_TCB& p_tcb, bool chg_aware) {
167   p_tcb.is_robust_cache_change_aware = chg_aware;
168 }
169 
170 /**
171  * Test class to test selected functionality in stack/gatt/gatt_sr.cc
172  */
173 extern void allocation_tracker_uninit(void);
174 namespace {
175 uint16_t kHandle = 1;
176 bt_gatt_db_attribute_type_t kGattCharacteristicType = BTGATT_DB_CHARACTERISTIC;
177 }  // namespace
178 class GattSrTest : public AllocationTestHarness {
179  protected:
SetUp()180   void SetUp() override {
181     AllocationTestHarness::SetUp();
182     // Disable our allocation tracker to allow ASAN full range
183     allocation_tracker_uninit();
184     memset(&tcb_, 0, sizeof(tcb_));
185     memset(&el_, 0, sizeof(el_));
186 
187     tcb_.trans_id = 0x12345677;
188     tcb_.att_lcid = L2CAP_ATT_CID;
189     el_.gatt_if = 1;
190     gatt_cb.cl_rcb[el_.gatt_if - 1].in_use = true;
191     gatt_cb.cl_rcb[el_.gatt_if - 1].app_cb.p_req_cb =
192         ApplicationRequestCallback;
193 
194     test_state_ = TestMutables();
195   }
196 
TearDown()197   void TearDown() override { AllocationTestHarness::TearDown(); }
198 
199   tGATT_TCB tcb_;
200   tGATT_SRV_LIST_ELEM el_;
201 };
202 
203 /* Server Robust Caching Test */
204 class GattSrRobustCachingTest : public AllocationTestHarness {
205  protected:
SetUp()206   void SetUp() override {
207     AllocationTestHarness::SetUp();
208     memset(&tcb_, 0, sizeof(tcb_));
209 
210     default_length_ = 2;
211     memset(default_data_, 0, sizeof(default_data_));
212 
213     gatt_cb.handle_of_database_hash = 0x0010;
214   }
215 
TearDown()216   void TearDown() override { AllocationTestHarness::TearDown(); }
217 
218   tGATT_TCB tcb_;
219   uint16_t default_length_;
220   uint8_t default_data_[2];
221 };
222 
TEST_F(GattSrTest,gatts_process_write_req_request_prepare_write_no_data)223 TEST_F(GattSrTest, gatts_process_write_req_request_prepare_write_no_data) {
224   gatts_process_write_req(tcb_, L2CAP_ATT_CID, el_, kHandle,
225                           GATT_REQ_PREPARE_WRITE, 0, nullptr,
226                           kGattCharacteristicType);
227 }
228 
TEST_F(GattSrTest,gatts_process_write_req_request_prepare_write_max_len_no_data)229 TEST_F(GattSrTest,
230        gatts_process_write_req_request_prepare_write_max_len_no_data) {
231   gatts_process_write_req(tcb_, L2CAP_ATT_CID, el_, kHandle,
232                           GATT_REQ_PREPARE_WRITE, MAX_UINT16, nullptr,
233                           kGattCharacteristicType);
234 }
235 
TEST_F(GattSrTest,gatts_process_write_req_request_prepare_write_zero_len_max_data)236 TEST_F(GattSrTest,
237        gatts_process_write_req_request_prepare_write_zero_len_max_data) {
238   uint8_t max_mem[MAX_UINT16];
239   gatts_process_write_req(tcb_, L2CAP_ATT_CID, el_, kHandle,
240                           GATT_REQ_PREPARE_WRITE, 0, max_mem,
241                           kGattCharacteristicType);
242 }
243 
TEST_F(GattSrTest,gatts_process_write_req_request_prepare_write_typical)244 TEST_F(GattSrTest, gatts_process_write_req_request_prepare_write_typical) {
245   uint8_t p_data[2] = {0x34, 0x12};
246   uint16_t length = static_cast<uint16_t>(sizeof(p_data) / sizeof(p_data[0]));
247   gatts_process_write_req(tcb_, L2CAP_ATT_CID, el_, kHandle,
248                           GATT_REQ_PREPARE_WRITE, length, p_data,
249                           kGattCharacteristicType);
250 
251   CHECK(test_state_.gatts_write_attr_perm_check.access_count_ == 1);
252   CHECK(test_state_.application_request_callback.conn_id_ == el_.gatt_if);
253   CHECK(test_state_.application_request_callback.trans_id_ == 0x12345678);
254   CHECK(test_state_.application_request_callback.type_ ==
255         GATTS_REQ_TYPE_WRITE_CHARACTERISTIC);
256   CHECK(test_state_.application_request_callback.data_.write_req.offset ==
257         0x1234);
258   CHECK(test_state_.application_request_callback.data_.write_req.is_prep ==
259         true);
260   CHECK(test_state_.application_request_callback.data_.write_req.len == 0);
261 }
262 
TEST_F(GattSrTest,gatts_process_write_req_signed_command_write_no_data)263 TEST_F(GattSrTest, gatts_process_write_req_signed_command_write_no_data) {
264   gatts_process_write_req(tcb_, L2CAP_ATT_CID, el_, kHandle,
265                           GATT_SIGN_CMD_WRITE, 0, nullptr,
266                           kGattCharacteristicType);
267 }
268 
TEST_F(GattSrTest,gatts_process_write_req_signed_command_write_max_len_no_data)269 TEST_F(GattSrTest,
270        gatts_process_write_req_signed_command_write_max_len_no_data) {
271   gatts_process_write_req(tcb_, L2CAP_ATT_CID, el_, kHandle,
272                           GATT_SIGN_CMD_WRITE, MAX_UINT16, nullptr,
273                           kGattCharacteristicType);
274 }
275 
TEST_F(GattSrTest,gatts_process_write_req_signed_command_write_zero_len_max_data)276 TEST_F(GattSrTest,
277        gatts_process_write_req_signed_command_write_zero_len_max_data) {
278   uint8_t max_mem[MAX_UINT16];
279   gatts_process_write_req(tcb_, L2CAP_ATT_CID, el_, kHandle,
280                           GATT_SIGN_CMD_WRITE, 0, max_mem,
281                           kGattCharacteristicType);
282 }
283 
TEST_F(GattSrTest,gatts_process_write_req_signed_command_write_typical)284 TEST_F(GattSrTest, gatts_process_write_req_signed_command_write_typical) {
285   static constexpr size_t kDataLength = 4;
286   uint8_t p_data[GATT_AUTH_SIGN_LEN + kDataLength] = {
287       0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
288       0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x01};
289   uint16_t length = static_cast<uint16_t>(sizeof(p_data) / sizeof(p_data[0]));
290   gatts_process_write_req(tcb_, L2CAP_ATT_CID, el_, kHandle,
291                           GATT_SIGN_CMD_WRITE, length, p_data,
292                           kGattCharacteristicType);
293 
294   CHECK(test_state_.gatts_write_attr_perm_check.access_count_ == 1);
295   CHECK(test_state_.application_request_callback.conn_id_ == el_.gatt_if);
296   CHECK(test_state_.application_request_callback.trans_id_ == 0x12345678);
297   CHECK(test_state_.application_request_callback.type_ ==
298         GATTS_REQ_TYPE_WRITE_CHARACTERISTIC);
299   CHECK(test_state_.application_request_callback.data_.write_req.offset == 0x0);
300   CHECK(test_state_.application_request_callback.data_.write_req.is_prep ==
301         false);
302   CHECK(test_state_.application_request_callback.data_.write_req.len ==
303         kDataLength);
304 }
305 
TEST_F(GattSrTest,gatts_process_write_req_command_write_no_data)306 TEST_F(GattSrTest, gatts_process_write_req_command_write_no_data) {
307   gatts_process_write_req(tcb_, L2CAP_ATT_CID, el_, kHandle, GATT_CMD_WRITE, 0,
308                           nullptr, kGattCharacteristicType);
309 }
310 
TEST_F(GattSrTest,gatts_process_write_req_command_write_max_len_no_data)311 TEST_F(GattSrTest, gatts_process_write_req_command_write_max_len_no_data) {
312   gatts_process_write_req(tcb_, L2CAP_ATT_CID, el_, kHandle, GATT_CMD_WRITE,
313                           MAX_UINT16, nullptr, kGattCharacteristicType);
314 }
315 
TEST_F(GattSrTest,gatts_process_write_req_command_write_zero_len_max_data)316 TEST_F(GattSrTest, gatts_process_write_req_command_write_zero_len_max_data) {
317   uint8_t max_mem[MAX_UINT16];
318   gatts_process_write_req(tcb_, L2CAP_ATT_CID, el_, kHandle, GATT_CMD_WRITE, 0,
319                           max_mem, kGattCharacteristicType);
320 }
321 
TEST_F(GattSrTest,gatts_process_write_req_command_write_typical)322 TEST_F(GattSrTest, gatts_process_write_req_command_write_typical) {
323   uint8_t p_data[16] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
324                         0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x01};
325   uint16_t length = static_cast<uint16_t>(sizeof(p_data) / sizeof(p_data[0]));
326   gatts_process_write_req(tcb_, L2CAP_ATT_CID, el_, kHandle, GATT_CMD_WRITE,
327                           length, p_data, kGattCharacteristicType);
328 
329   CHECK(test_state_.gatts_write_attr_perm_check.access_count_ == 1);
330   CHECK(test_state_.application_request_callback.conn_id_ == el_.gatt_if);
331   CHECK(test_state_.application_request_callback.trans_id_ == 0x12345678);
332   CHECK(test_state_.application_request_callback.type_ ==
333         GATTS_REQ_TYPE_WRITE_CHARACTERISTIC);
334   CHECK(test_state_.application_request_callback.data_.write_req.offset == 0x0);
335   CHECK(test_state_.application_request_callback.data_.write_req.is_prep ==
336         false);
337   CHECK(test_state_.application_request_callback.data_.write_req.len == length);
338 }
339 
TEST_F(GattSrTest,gatts_process_write_req_request_write_no_data)340 TEST_F(GattSrTest, gatts_process_write_req_request_write_no_data) {
341   gatts_process_write_req(tcb_, L2CAP_ATT_CID, el_, kHandle, GATT_REQ_WRITE, 0,
342                           nullptr, kGattCharacteristicType);
343 }
344 
TEST_F(GattSrTest,gatts_process_write_req_request_write_max_len_no_data)345 TEST_F(GattSrTest, gatts_process_write_req_request_write_max_len_no_data) {
346   gatts_process_write_req(tcb_, L2CAP_ATT_CID, el_, kHandle, GATT_REQ_WRITE,
347                           MAX_UINT16, nullptr, kGattCharacteristicType);
348 }
349 
TEST_F(GattSrTest,gatts_process_write_req_request_write_zero_len_max_data)350 TEST_F(GattSrTest, gatts_process_write_req_request_write_zero_len_max_data) {
351   uint8_t max_mem[MAX_UINT16];
352   gatts_process_write_req(tcb_, L2CAP_ATT_CID, el_, kHandle, GATT_REQ_WRITE, 0,
353                           max_mem, kGattCharacteristicType);
354 }
355 
TEST_F(GattSrTest,gatts_process_write_req_request_write_typical)356 TEST_F(GattSrTest, gatts_process_write_req_request_write_typical) {
357   uint8_t p_data[16] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
358                         0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x01};
359   uint16_t length = static_cast<uint16_t>(sizeof(p_data) / sizeof(p_data[0]));
360 
361   gatts_process_write_req(tcb_, L2CAP_ATT_CID, el_, kHandle, GATT_REQ_WRITE,
362                           length, p_data, kGattCharacteristicType);
363 
364   CHECK(test_state_.gatts_write_attr_perm_check.access_count_ == 1);
365   CHECK(test_state_.application_request_callback.conn_id_ == el_.gatt_if);
366   CHECK(test_state_.application_request_callback.trans_id_ == 0x12345678);
367   CHECK(test_state_.application_request_callback.type_ ==
368         GATTS_REQ_TYPE_WRITE_CHARACTERISTIC);
369   CHECK(test_state_.application_request_callback.data_.write_req.offset == 0x0);
370   CHECK(test_state_.application_request_callback.data_.write_req.is_prep ==
371         false);
372   CHECK(test_state_.application_request_callback.data_.write_req.len == length);
373 }
374 
TEST_F(GattSrRobustCachingTest,gatts_process_db_out_of_sync_for_gatt_req_read_by_grp_type)375 TEST_F(GattSrRobustCachingTest,
376        gatts_process_db_out_of_sync_for_gatt_req_read_by_grp_type) {
377   tcb_.is_robust_cache_change_aware = false;
378 
379   bool should_ignore = gatts_process_db_out_of_sync(
380       tcb_, L2CAP_ATT_CID, GATT_REQ_READ_BY_GRP_TYPE, default_length_,
381       default_data_);
382 
383   ASSERT_TRUE(should_ignore);
384   ASSERT_TRUE(tcb_.is_robust_cache_change_aware);
385 }
386 
TEST_F(GattSrRobustCachingTest,gatts_process_db_out_of_sync_for_gatt_req_find_type_value)387 TEST_F(GattSrRobustCachingTest,
388        gatts_process_db_out_of_sync_for_gatt_req_find_type_value) {
389   tcb_.is_robust_cache_change_aware = false;
390 
391   bool should_ignore = gatts_process_db_out_of_sync(
392       tcb_, L2CAP_ATT_CID, GATT_REQ_FIND_TYPE_VALUE, default_length_,
393       default_data_);
394 
395   ASSERT_TRUE(should_ignore);
396   ASSERT_TRUE(tcb_.is_robust_cache_change_aware);
397 }
398 
TEST_F(GattSrRobustCachingTest,gatts_process_db_out_of_sync_for_gatt_req_find_info)399 TEST_F(GattSrRobustCachingTest,
400        gatts_process_db_out_of_sync_for_gatt_req_find_info) {
401   tcb_.is_robust_cache_change_aware = false;
402 
403   bool should_ignore = gatts_process_db_out_of_sync(
404       tcb_, L2CAP_ATT_CID, GATT_REQ_FIND_INFO, default_length_, default_data_);
405 
406   ASSERT_TRUE(should_ignore);
407   ASSERT_TRUE(tcb_.is_robust_cache_change_aware);
408 }
409 
TEST_F(GattSrRobustCachingTest,gatts_process_db_out_of_sync_for_gatt_req_read_by_type_parse_failed)410 TEST_F(GattSrRobustCachingTest,
411        gatts_process_db_out_of_sync_for_gatt_req_read_by_type_parse_failed) {
412   // INVALID_PDU
413   uint16_t len = 4;
414   uint8_t p_data[4] = {0x00, 0x02, 0x14, 0x02};
415   tcb_.is_robust_cache_change_aware = false;
416 
417   bool should_ignore = gatts_process_db_out_of_sync(
418       tcb_, L2CAP_ATT_CID, GATT_REQ_READ_BY_TYPE, len, p_data);
419 
420   ASSERT_TRUE(should_ignore);
421   ASSERT_TRUE(tcb_.is_robust_cache_change_aware);
422 }
423 
TEST_F(GattSrRobustCachingTest,gatts_process_db_out_of_sync_for_gatt_req_read_by_type_db_hash_uuid)424 TEST_F(GattSrRobustCachingTest,
425        gatts_process_db_out_of_sync_for_gatt_req_read_by_type_db_hash_uuid) {
426   // ATT_READ_BY_TYPE_REQ(0x0001, 0x0010, 0x2B2A)
427   uint16_t len = 6;
428   uint8_t p_data[6] = {0x01, 0x00, 0x10, 0x00, 0x2A, 0x2B};
429   tcb_.is_robust_cache_change_aware = false;
430 
431   bool should_ignore = gatts_process_db_out_of_sync(
432       tcb_, L2CAP_ATT_CID, GATT_REQ_READ_BY_TYPE, len, p_data);
433 
434   ASSERT_FALSE(should_ignore);
435 }
436 
TEST_F(GattSrRobustCachingTest,gatts_process_db_out_of_sync_for_gatt_req_read_by_type_wrong_range)437 TEST_F(GattSrRobustCachingTest,
438        gatts_process_db_out_of_sync_for_gatt_req_read_by_type_wrong_range) {
439   // ATT_READ_BY_TYPE_REQ(0x0200, 0x0214, 0x2803)
440   uint16_t len = 6;
441   uint8_t p_data[6] = {0x00, 0x02, 0x14, 0x02, 0x2A, 0x28};
442   tcb_.is_robust_cache_change_aware = false;
443 
444   bool should_ignore = gatts_process_db_out_of_sync(
445       tcb_, L2CAP_ATT_CID, GATT_REQ_READ_BY_TYPE, len, p_data);
446 
447   ASSERT_TRUE(should_ignore);
448   ASSERT_TRUE(tcb_.is_robust_cache_change_aware);
449 }
450 
TEST_F(GattSrRobustCachingTest,gatts_process_db_out_of_sync_for_gatt_req_read_by_type_other_uuid)451 TEST_F(GattSrRobustCachingTest,
452        gatts_process_db_out_of_sync_for_gatt_req_read_by_type_other_uuid) {
453   // ATT_READ_BY_TYPE_REQ(0x0200, 0x0214, 0x2803)
454   uint16_t len = 6;
455   uint8_t p_data[6] = {0x00, 0x02, 0x14, 0x02, 0x03, 0x28};
456   tcb_.is_robust_cache_change_aware = false;
457 
458   bool should_ignore = gatts_process_db_out_of_sync(
459       tcb_, L2CAP_ATT_CID, GATT_REQ_READ_BY_TYPE, len, p_data);
460 
461   ASSERT_TRUE(should_ignore);
462   ASSERT_TRUE(tcb_.is_robust_cache_change_aware);
463 }
464 
TEST_F(GattSrRobustCachingTest,gatts_process_db_out_of_sync_for_gatt_req_read_parse_failed)465 TEST_F(GattSrRobustCachingTest,
466        gatts_process_db_out_of_sync_for_gatt_req_read_parse_failed) {
467   // INVALID_PDU
468   uint8_t p_data[1] = {0x02};
469   uint16_t len = 1;
470   tcb_.is_robust_cache_change_aware = false;
471 
472   bool should_ignore = gatts_process_db_out_of_sync(tcb_, L2CAP_ATT_CID,
473                                                     GATT_REQ_READ, len, p_data);
474 
475   ASSERT_TRUE(should_ignore);
476   ASSERT_TRUE(tcb_.is_robust_cache_change_aware);
477 }
478 
TEST_F(GattSrRobustCachingTest,gatts_process_db_out_of_sync_for_gatt_req_read_db_hash_handle)479 TEST_F(GattSrRobustCachingTest,
480        gatts_process_db_out_of_sync_for_gatt_req_read_db_hash_handle) {
481   // ATT_READ_REQ(0x0010)
482   uint8_t p_data[2] = {0x10, 0x00};
483   uint16_t len = 2;
484   tcb_.is_robust_cache_change_aware = false;
485 
486   bool should_ignore = gatts_process_db_out_of_sync(tcb_, L2CAP_ATT_CID,
487                                                     GATT_REQ_READ, len, p_data);
488 
489   ASSERT_FALSE(should_ignore);
490 }
491 
TEST_F(GattSrRobustCachingTest,gatts_process_db_out_of_sync_for_gatt_req_read_other_handle)492 TEST_F(GattSrRobustCachingTest,
493        gatts_process_db_out_of_sync_for_gatt_req_read_other_handle) {
494   // ATT_READ_REQ(0x0002)
495   uint8_t p_data[2] = {0x02, 0x00};
496   uint16_t len = 2;
497   tcb_.is_robust_cache_change_aware = false;
498 
499   bool should_ignore = gatts_process_db_out_of_sync(tcb_, L2CAP_ATT_CID,
500                                                     GATT_REQ_READ, len, p_data);
501 
502   ASSERT_TRUE(should_ignore);
503   ASSERT_TRUE(tcb_.is_robust_cache_change_aware);
504 }
505 
TEST_F(GattSrRobustCachingTest,gatts_process_db_out_of_sync_for_gatt_req_read_blob)506 TEST_F(GattSrRobustCachingTest,
507        gatts_process_db_out_of_sync_for_gatt_req_read_blob) {
508   tcb_.is_robust_cache_change_aware = false;
509 
510   bool should_ignore = gatts_process_db_out_of_sync(
511       tcb_, L2CAP_ATT_CID, GATT_REQ_READ_BLOB, default_length_, default_data_);
512 
513   ASSERT_TRUE(should_ignore);
514   ASSERT_TRUE(tcb_.is_robust_cache_change_aware);
515 }
516 
TEST_F(GattSrRobustCachingTest,gatts_process_db_out_of_sync_for_gatt_req_read_multi)517 TEST_F(GattSrRobustCachingTest,
518        gatts_process_db_out_of_sync_for_gatt_req_read_multi) {
519   tcb_.is_robust_cache_change_aware = false;
520 
521   bool should_ignore = gatts_process_db_out_of_sync(
522       tcb_, L2CAP_ATT_CID, GATT_REQ_READ_MULTI, default_length_, default_data_);
523 
524   ASSERT_TRUE(should_ignore);
525   ASSERT_TRUE(tcb_.is_robust_cache_change_aware);
526 }
527 
TEST_F(GattSrRobustCachingTest,gatts_process_db_out_of_sync_for_gatt_req_write)528 TEST_F(GattSrRobustCachingTest,
529        gatts_process_db_out_of_sync_for_gatt_req_write) {
530   tcb_.is_robust_cache_change_aware = false;
531 
532   bool should_ignore = gatts_process_db_out_of_sync(
533       tcb_, L2CAP_ATT_CID, GATT_REQ_WRITE, default_length_, default_data_);
534 
535   ASSERT_TRUE(should_ignore);
536   ASSERT_TRUE(tcb_.is_robust_cache_change_aware);
537 }
538 
TEST_F(GattSrRobustCachingTest,gatts_process_db_out_of_sync_for_gatt_cmd_write)539 TEST_F(GattSrRobustCachingTest,
540        gatts_process_db_out_of_sync_for_gatt_cmd_write) {
541   tcb_.is_robust_cache_change_aware = false;
542 
543   bool should_ignore = gatts_process_db_out_of_sync(
544       tcb_, L2CAP_ATT_CID, GATT_CMD_WRITE, default_length_, default_data_);
545 
546   ASSERT_TRUE(should_ignore);
547   ASSERT_FALSE(tcb_.is_robust_cache_change_aware);
548 }
549 
TEST_F(GattSrRobustCachingTest,gatts_process_db_out_of_sync_for_gatt_sign_cmd_write)550 TEST_F(GattSrRobustCachingTest,
551        gatts_process_db_out_of_sync_for_gatt_sign_cmd_write) {
552   tcb_.is_robust_cache_change_aware = false;
553 
554   bool should_ignore = gatts_process_db_out_of_sync(
555       tcb_, L2CAP_ATT_CID, GATT_SIGN_CMD_WRITE, default_length_, default_data_);
556 
557   ASSERT_TRUE(should_ignore);
558   ASSERT_FALSE(tcb_.is_robust_cache_change_aware);
559 }
560 
TEST_F(GattSrRobustCachingTest,gatts_process_db_out_of_sync_for_gatt_req_prepare_write)561 TEST_F(GattSrRobustCachingTest,
562        gatts_process_db_out_of_sync_for_gatt_req_prepare_write) {
563   tcb_.is_robust_cache_change_aware = false;
564 
565   bool should_ignore =
566       gatts_process_db_out_of_sync(tcb_, L2CAP_ATT_CID, GATT_REQ_PREPARE_WRITE,
567                                    default_length_, default_data_);
568 
569   ASSERT_TRUE(should_ignore);
570   ASSERT_TRUE(tcb_.is_robust_cache_change_aware);
571 }
572 
TEST_F(GattSrRobustCachingTest,gatts_process_db_out_of_sync_for_gatt_req_mtu)573 TEST_F(GattSrRobustCachingTest, gatts_process_db_out_of_sync_for_gatt_req_mtu) {
574   tcb_.is_robust_cache_change_aware = false;
575 
576   bool should_ignore = gatts_process_db_out_of_sync(
577       tcb_, L2CAP_ATT_CID, GATT_REQ_MTU, default_length_, default_data_);
578 
579   ASSERT_FALSE(should_ignore);
580 }
581 
TEST_F(GattSrRobustCachingTest,gatts_process_db_out_of_sync_for_gatt_req_exec_write)582 TEST_F(GattSrRobustCachingTest,
583        gatts_process_db_out_of_sync_for_gatt_req_exec_write) {
584   tcb_.is_robust_cache_change_aware = false;
585 
586   bool should_ignore = gatts_process_db_out_of_sync(
587       tcb_, L2CAP_ATT_CID, GATT_REQ_EXEC_WRITE, default_length_, default_data_);
588 
589   ASSERT_FALSE(should_ignore);
590 }
591 
TEST_F(GattSrRobustCachingTest,gatts_process_db_out_of_sync_for_gatt_handle_value_conf)592 TEST_F(GattSrRobustCachingTest,
593        gatts_process_db_out_of_sync_for_gatt_handle_value_conf) {
594   tcb_.is_robust_cache_change_aware = false;
595 
596   bool should_ignore =
597       gatts_process_db_out_of_sync(tcb_, L2CAP_ATT_CID, GATT_HANDLE_VALUE_CONF,
598                                    default_length_, default_data_);
599 
600   ASSERT_FALSE(should_ignore);
601 }
602