• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/gatt/gatt_int.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)57 bool direct_connect_remove(uint8_t app_id, const RawAddress& address) {
58   return false;
59 }
60 }  // namespace connection_manager
61 
attp_build_sr_msg(tGATT_TCB & tcb,uint8_t op_code,tGATT_SR_MSG * p_msg)62 BT_HDR* attp_build_sr_msg(tGATT_TCB& tcb, uint8_t op_code,
63                           tGATT_SR_MSG* p_msg) {
64   test_state_.attp_build_sr_msg.op_code_ = op_code;
65   return nullptr;
66 }
attp_send_cl_msg(tGATT_TCB & tcb,tGATT_CLCB * p_clcb,uint8_t op_code,tGATT_CL_MSG * p_msg)67 tGATT_STATUS attp_send_cl_msg(tGATT_TCB& tcb, tGATT_CLCB* p_clcb,
68                               uint8_t op_code, tGATT_CL_MSG* p_msg) {
69   return 0;
70 }
attp_send_sr_msg(tGATT_TCB & tcb,BT_HDR * p_msg)71 tGATT_STATUS attp_send_sr_msg(tGATT_TCB& tcb, BT_HDR* p_msg) { return 0; }
btm_ble_read_sec_key_size(const RawAddress & bd_addr)72 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)73 bool BTM_GetSecurityFlagsByTransport(const RawAddress& bd_addr,
74                                      uint8_t* p_sec_flags,
75                                      tBT_TRANSPORT transport) {
76   return false;
77 }
gatt_act_discovery(tGATT_CLCB * p_clcb)78 void gatt_act_discovery(tGATT_CLCB* p_clcb) {}
gatt_disconnect(tGATT_TCB * p_tcb)79 bool gatt_disconnect(tGATT_TCB* p_tcb) { return false; }
gatt_get_ch_state(tGATT_TCB * p_tcb)80 tGATT_CH_STATE gatt_get_ch_state(tGATT_TCB* p_tcb) { return 0; }
gatts_db_read_attr_value_by_type(tGATT_TCB & tcb,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)81 tGATT_STATUS gatts_db_read_attr_value_by_type(
82     tGATT_TCB& tcb, tGATT_SVC_DB* p_db, uint8_t op_code, BT_HDR* p_rsp,
83     uint16_t s_handle, uint16_t e_handle, const Uuid& type, uint16_t* p_len,
84     tGATT_SEC_FLAG sec_flag, uint8_t key_size, uint32_t trans_id,
85     uint16_t* p_cur_handle) {
86   return 0;
87 }
gatt_set_ch_state(tGATT_TCB * p_tcb,tGATT_CH_STATE ch_state)88 void gatt_set_ch_state(tGATT_TCB* p_tcb, tGATT_CH_STATE ch_state) {}
gatts_get_service_uuid(tGATT_SVC_DB * p_db)89 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)90 tGATT_STATUS GATTS_HandleValueIndication(uint16_t conn_id, uint16_t attr_handle,
91                                          uint16_t val_len, uint8_t* p_val) {
92   return GATT_SUCCESS;
93 }
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)94 tGATT_STATUS gatts_read_attr_perm_check(tGATT_SVC_DB* p_db, bool is_long,
95                                         uint16_t handle,
96                                         tGATT_SEC_FLAG sec_flag,
97                                         uint8_t key_size) {
98   return GATT_SUCCESS;
99 }
gatts_read_attr_value_by_handle(tGATT_TCB & tcb,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)100 tGATT_STATUS gatts_read_attr_value_by_handle(
101     tGATT_TCB& tcb, tGATT_SVC_DB* p_db, uint8_t op_code, uint16_t handle,
102     uint16_t offset, uint8_t* p_value, uint16_t* p_len, uint16_t mtu,
103     tGATT_SEC_FLAG sec_flag, uint8_t key_size, uint32_t trans_id) {
104   return GATT_SUCCESS;
105 }
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)106 tGATT_STATUS gatts_write_attr_perm_check(tGATT_SVC_DB* p_db, uint8_t op_code,
107                                          uint16_t handle, uint16_t offset,
108                                          uint8_t* p_data, uint16_t len,
109                                          tGATT_SEC_FLAG sec_flag,
110                                          uint8_t key_size) {
111   test_state_.gatts_write_attr_perm_check.access_count_++;
112   return test_state_.gatts_write_attr_perm_check.return_status_;
113 }
gatt_update_app_use_link_flag(tGATT_IF gatt_if,tGATT_TCB * p_tcb,bool is_add,bool check_acl_link)114 void gatt_update_app_use_link_flag(tGATT_IF gatt_if, tGATT_TCB* p_tcb,
115                                    bool is_add, bool check_acl_link) {}
get_main_message_loop()116 base::MessageLoop* get_main_message_loop() { return nullptr; }
l2cble_set_fixed_channel_tx_data_length(const RawAddress & remote_bda,uint16_t fix_cid,uint16_t tx_mtu)117 void l2cble_set_fixed_channel_tx_data_length(const RawAddress& remote_bda,
118                                              uint16_t fix_cid,
119                                              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)120 bool SDP_AddAttribute(uint32_t handle, uint16_t attr_id, uint8_t attr_type,
121                       uint32_t attr_len, uint8_t* p_val) {
122   return false;
123 }
SDP_AddProtocolList(uint32_t handle,uint16_t num_elem,tSDP_PROTOCOL_ELEM * p_elem_list)124 bool SDP_AddProtocolList(uint32_t handle, uint16_t num_elem,
125                          tSDP_PROTOCOL_ELEM* p_elem_list) {
126   return false;
127 }
SDP_AddServiceClassIdList(uint32_t handle,uint16_t num_services,uint16_t * p_service_uuids)128 bool SDP_AddServiceClassIdList(uint32_t handle, uint16_t num_services,
129                                uint16_t* p_service_uuids) {
130   return false;
131 }
SDP_AddUuidSequence(uint32_t handle,uint16_t attr_id,uint16_t num_uuids,uint16_t * p_uuids)132 bool SDP_AddUuidSequence(uint32_t handle, uint16_t attr_id, uint16_t num_uuids,
133                          uint16_t* p_uuids) {
134   return false;
135 }
SDP_CreateRecord(void)136 uint32_t SDP_CreateRecord(void) { return 0; }
137 
ApplicationRequestCallback(uint16_t conn_id,uint32_t trans_id,tGATTS_REQ_TYPE type,tGATTS_DATA * p_data)138 void ApplicationRequestCallback(uint16_t conn_id, uint32_t trans_id,
139                                 tGATTS_REQ_TYPE type, tGATTS_DATA* p_data) {
140   test_state_.application_request_callback.conn_id_ = conn_id;
141   test_state_.application_request_callback.trans_id_ = trans_id;
142   test_state_.application_request_callback.type_ = type;
143   test_state_.application_request_callback.data_ = *p_data;
144 }
145 
146 /**
147  * Test class to test selected functionality in stack/gatt/gatt_sr.cc
148  */
149 extern void allocation_tracker_uninit(void);
150 namespace {
151 uint16_t kHandle = 1;
152 bt_gatt_db_attribute_type_t kGattCharacteristicType = BTGATT_DB_CHARACTERISTIC;
153 }  // namespace
154 class GattSrTest : public AllocationTestHarness {
155  protected:
SetUp()156   void SetUp() override {
157     AllocationTestHarness::SetUp();
158     // Disable our allocation tracker to allow ASAN full range
159     allocation_tracker_uninit();
160     memset(&tcb_, 0, sizeof(tcb_));
161     memset(&el_, 0, sizeof(el_));
162 
163     tcb_.trans_id = 0x12345677;
164     el_.gatt_if = 1;
165     gatt_cb.cl_rcb[el_.gatt_if - 1].in_use = true;
166     gatt_cb.cl_rcb[el_.gatt_if - 1].app_cb.p_req_cb =
167         ApplicationRequestCallback;
168 
169     test_state_ = TestMutables();
170   }
171 
TearDown()172   void TearDown() override { AllocationTestHarness::TearDown(); }
173 
174   tGATT_TCB tcb_;
175   tGATT_SRV_LIST_ELEM el_;
176 };
177 
TEST_F(GattSrTest,gatts_process_write_req_request_prepare_write_no_data)178 TEST_F(GattSrTest, gatts_process_write_req_request_prepare_write_no_data) {
179   gatts_process_write_req(tcb_, el_, kHandle, GATT_REQ_PREPARE_WRITE, 0,
180                           nullptr, kGattCharacteristicType);
181 }
182 
TEST_F(GattSrTest,gatts_process_write_req_request_prepare_write_max_len_no_data)183 TEST_F(GattSrTest,
184        gatts_process_write_req_request_prepare_write_max_len_no_data) {
185   gatts_process_write_req(tcb_, el_, kHandle, GATT_REQ_PREPARE_WRITE,
186                           MAX_UINT16, nullptr, kGattCharacteristicType);
187 }
188 
TEST_F(GattSrTest,gatts_process_write_req_request_prepare_write_zero_len_max_data)189 TEST_F(GattSrTest,
190        gatts_process_write_req_request_prepare_write_zero_len_max_data) {
191   uint8_t max_mem[MAX_UINT16];
192   gatts_process_write_req(tcb_, el_, kHandle, GATT_REQ_PREPARE_WRITE, 0,
193                           max_mem, kGattCharacteristicType);
194 }
195 
TEST_F(GattSrTest,gatts_process_write_req_request_prepare_write_typical)196 TEST_F(GattSrTest, gatts_process_write_req_request_prepare_write_typical) {
197   uint8_t p_data[2] = {0x34, 0x12};
198   uint16_t length = static_cast<uint16_t>(sizeof(p_data) / sizeof(p_data[0]));
199   gatts_process_write_req(tcb_, el_, kHandle, GATT_REQ_PREPARE_WRITE, length,
200                           p_data, kGattCharacteristicType);
201 
202   CHECK(test_state_.gatts_write_attr_perm_check.access_count_ == 1);
203   CHECK(test_state_.application_request_callback.conn_id_ == el_.gatt_if);
204   CHECK(test_state_.application_request_callback.trans_id_ == 0x12345678);
205   CHECK(test_state_.application_request_callback.type_ ==
206         GATTS_REQ_TYPE_WRITE_CHARACTERISTIC);
207   CHECK(test_state_.application_request_callback.data_.write_req.offset ==
208         0x1234);
209   CHECK(test_state_.application_request_callback.data_.write_req.is_prep ==
210         true);
211   CHECK(test_state_.application_request_callback.data_.write_req.len == 0);
212 }
213 
TEST_F(GattSrTest,gatts_process_write_req_signed_command_write_no_data)214 TEST_F(GattSrTest, gatts_process_write_req_signed_command_write_no_data) {
215   gatts_process_write_req(tcb_, el_, kHandle, GATT_SIGN_CMD_WRITE, 0, nullptr,
216                           kGattCharacteristicType);
217 }
218 
TEST_F(GattSrTest,gatts_process_write_req_signed_command_write_max_len_no_data)219 TEST_F(GattSrTest,
220        gatts_process_write_req_signed_command_write_max_len_no_data) {
221   gatts_process_write_req(tcb_, el_, kHandle, GATT_SIGN_CMD_WRITE, MAX_UINT16,
222                           nullptr, kGattCharacteristicType);
223 }
224 
TEST_F(GattSrTest,gatts_process_write_req_signed_command_write_zero_len_max_data)225 TEST_F(GattSrTest,
226        gatts_process_write_req_signed_command_write_zero_len_max_data) {
227   uint8_t max_mem[MAX_UINT16];
228   gatts_process_write_req(tcb_, el_, kHandle, GATT_SIGN_CMD_WRITE, 0, max_mem,
229                           kGattCharacteristicType);
230 }
231 
TEST_F(GattSrTest,gatts_process_write_req_signed_command_write_typical)232 TEST_F(GattSrTest, gatts_process_write_req_signed_command_write_typical) {
233   static constexpr size_t kDataLength = 4;
234   uint8_t p_data[GATT_AUTH_SIGN_LEN + kDataLength] = {
235       0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
236       0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x01};
237   uint16_t length = static_cast<uint16_t>(sizeof(p_data) / sizeof(p_data[0]));
238   gatts_process_write_req(tcb_, el_, kHandle, GATT_SIGN_CMD_WRITE, length,
239                           p_data, kGattCharacteristicType);
240 
241   CHECK(test_state_.gatts_write_attr_perm_check.access_count_ == 1);
242   CHECK(test_state_.application_request_callback.conn_id_ == el_.gatt_if);
243   CHECK(test_state_.application_request_callback.trans_id_ == 0x12345678);
244   CHECK(test_state_.application_request_callback.type_ ==
245         GATTS_REQ_TYPE_WRITE_CHARACTERISTIC);
246   CHECK(test_state_.application_request_callback.data_.write_req.offset == 0x0);
247   CHECK(test_state_.application_request_callback.data_.write_req.is_prep ==
248         false);
249   CHECK(test_state_.application_request_callback.data_.write_req.len ==
250         kDataLength);
251 }
252 
TEST_F(GattSrTest,gatts_process_write_req_command_write_no_data)253 TEST_F(GattSrTest, gatts_process_write_req_command_write_no_data) {
254   gatts_process_write_req(tcb_, el_, kHandle, GATT_CMD_WRITE, 0, nullptr,
255                           kGattCharacteristicType);
256 }
257 
TEST_F(GattSrTest,gatts_process_write_req_command_write_max_len_no_data)258 TEST_F(GattSrTest, gatts_process_write_req_command_write_max_len_no_data) {
259   gatts_process_write_req(tcb_, el_, kHandle, GATT_CMD_WRITE, MAX_UINT16,
260                           nullptr, kGattCharacteristicType);
261 }
262 
TEST_F(GattSrTest,gatts_process_write_req_command_write_zero_len_max_data)263 TEST_F(GattSrTest, gatts_process_write_req_command_write_zero_len_max_data) {
264   uint8_t max_mem[MAX_UINT16];
265   gatts_process_write_req(tcb_, el_, kHandle, GATT_CMD_WRITE, 0, max_mem,
266                           kGattCharacteristicType);
267 }
268 
TEST_F(GattSrTest,gatts_process_write_req_command_write_typical)269 TEST_F(GattSrTest, gatts_process_write_req_command_write_typical) {
270   uint8_t p_data[16] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
271                         0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x01};
272   uint16_t length = static_cast<uint16_t>(sizeof(p_data) / sizeof(p_data[0]));
273   gatts_process_write_req(tcb_, el_, kHandle, GATT_CMD_WRITE, length, p_data,
274                           kGattCharacteristicType);
275 
276   CHECK(test_state_.gatts_write_attr_perm_check.access_count_ == 1);
277   CHECK(test_state_.application_request_callback.conn_id_ == el_.gatt_if);
278   CHECK(test_state_.application_request_callback.trans_id_ == 0x12345678);
279   CHECK(test_state_.application_request_callback.type_ ==
280         GATTS_REQ_TYPE_WRITE_CHARACTERISTIC);
281   CHECK(test_state_.application_request_callback.data_.write_req.offset == 0x0);
282   CHECK(test_state_.application_request_callback.data_.write_req.is_prep ==
283         false);
284   CHECK(test_state_.application_request_callback.data_.write_req.len == length);
285 }
286 
TEST_F(GattSrTest,gatts_process_write_req_request_write_no_data)287 TEST_F(GattSrTest, gatts_process_write_req_request_write_no_data) {
288   gatts_process_write_req(tcb_, el_, kHandle, GATT_REQ_WRITE, 0, nullptr,
289                           kGattCharacteristicType);
290 }
291 
TEST_F(GattSrTest,gatts_process_write_req_request_write_max_len_no_data)292 TEST_F(GattSrTest, gatts_process_write_req_request_write_max_len_no_data) {
293   gatts_process_write_req(tcb_, el_, kHandle, GATT_REQ_WRITE, MAX_UINT16,
294                           nullptr, kGattCharacteristicType);
295 }
296 
TEST_F(GattSrTest,gatts_process_write_req_request_write_zero_len_max_data)297 TEST_F(GattSrTest, gatts_process_write_req_request_write_zero_len_max_data) {
298   uint8_t max_mem[MAX_UINT16];
299   gatts_process_write_req(tcb_, el_, kHandle, GATT_REQ_WRITE, 0, max_mem,
300                           kGattCharacteristicType);
301 }
302 
TEST_F(GattSrTest,gatts_process_write_req_request_write_typical)303 TEST_F(GattSrTest, gatts_process_write_req_request_write_typical) {
304   uint8_t p_data[16] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
305                         0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x01};
306   uint16_t length = static_cast<uint16_t>(sizeof(p_data) / sizeof(p_data[0]));
307 
308   gatts_process_write_req(tcb_, el_, kHandle, GATT_REQ_WRITE, length, p_data,
309                           kGattCharacteristicType);
310 
311   CHECK(test_state_.gatts_write_attr_perm_check.access_count_ == 1);
312   CHECK(test_state_.application_request_callback.conn_id_ == el_.gatt_if);
313   CHECK(test_state_.application_request_callback.trans_id_ == 0x12345678);
314   CHECK(test_state_.application_request_callback.type_ ==
315         GATTS_REQ_TYPE_WRITE_CHARACTERISTIC);
316   CHECK(test_state_.application_request_callback.data_.write_req.offset == 0x0);
317   CHECK(test_state_.application_request_callback.data_.write_req.is_prep ==
318         false);
319   CHECK(test_state_.application_request_callback.data_.write_req.len == length);
320 }
321