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