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