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