• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2021 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 #include <string.h>
19 
20 #include <cstdint>
21 #include <map>
22 #include <memory>
23 #include <string>
24 
25 #include "bta/gatt/bta_gattc_int.h"
26 #include "common/message_loop_thread.h"
27 #include "osi/include/allocator.h"
28 #include "stack/gatt/gatt_int.h"
29 #include "test/common/mock_functions.h"
30 
31 namespace param {
32 struct {
33   uint16_t conn_id;
34   tGATT_STATUS status;
35   uint16_t handle;
36   uint16_t len;
37   uint8_t* value;
38   void* data;
39 } bta_gatt_read_complete_callback;
40 }  // namespace param
bta_gatt_read_complete_callback(uint16_t conn_id,tGATT_STATUS status,uint16_t handle,uint16_t len,uint8_t * value,void * data)41 void bta_gatt_read_complete_callback(uint16_t conn_id, tGATT_STATUS status,
42                                      uint16_t handle, uint16_t len,
43                                      uint8_t* value, void* data) {
44   param::bta_gatt_read_complete_callback.conn_id = conn_id;
45   param::bta_gatt_read_complete_callback.status = status;
46   param::bta_gatt_read_complete_callback.handle = handle;
47   param::bta_gatt_read_complete_callback.len = len;
48   param::bta_gatt_read_complete_callback.value = value;
49   param::bta_gatt_read_complete_callback.data = data;
50 }
51 
52 namespace param {
53 struct {
54   uint16_t conn_id;
55   tGATT_STATUS status;
56   uint16_t handle;
57   uint16_t len;
58   const uint8_t* value;
59   void* data;
60 } bta_gatt_write_complete_callback;
61 }  // namespace param
62 
bta_gatt_write_complete_callback(uint16_t conn_id,tGATT_STATUS status,uint16_t handle,uint16_t len,const uint8_t * value,void * data)63 void bta_gatt_write_complete_callback(uint16_t conn_id, tGATT_STATUS status,
64                                       uint16_t handle, uint16_t len,
65                                       const uint8_t* value, void* data) {
66   param::bta_gatt_write_complete_callback.conn_id = conn_id;
67   param::bta_gatt_write_complete_callback.status = status;
68   param::bta_gatt_write_complete_callback.handle = handle;
69   param::bta_gatt_write_complete_callback.len = len;
70   param::bta_gatt_write_complete_callback.value = value;
71   param::bta_gatt_write_complete_callback.data = data;
72 }
73 
74 namespace param {
75 struct {
76   uint16_t conn_id;
77   tGATT_STATUS status;
78   void* data;
79 } bta_gatt_configure_mtu_complete_callback;
80 }  // namespace param
81 
bta_gatt_configure_mtu_complete_callback(uint16_t conn_id,tGATT_STATUS status,void * data)82 void bta_gatt_configure_mtu_complete_callback(uint16_t conn_id,
83                                               tGATT_STATUS status, void* data) {
84   param::bta_gatt_configure_mtu_complete_callback.conn_id = conn_id;
85   param::bta_gatt_configure_mtu_complete_callback.status = status;
86   param::bta_gatt_configure_mtu_complete_callback.data = data;
87 }
88 
89 namespace param {
90 struct {
91   tBTA_GATTC_EVT event;
92   tBTA_GATTC* p_data;
93 } bta_gattc_event_complete_callback;
94 }  // namespace param
95 
bta_gattc_event_complete_callback(tBTA_GATTC_EVT event,tBTA_GATTC * p_data)96 void bta_gattc_event_complete_callback(tBTA_GATTC_EVT event,
97                                        tBTA_GATTC* p_data) {
98   param::bta_gattc_event_complete_callback.event = event;
99   param::bta_gattc_event_complete_callback.p_data = p_data;
100 }
101 
102 class BtaGattTest : public ::testing::Test {
103  protected:
SetUp()104   void SetUp() override {
105     reset_mock_function_count_map();
106     param::bta_gatt_read_complete_callback = {};
107     param::bta_gatt_write_complete_callback = {};
108     param::bta_gatt_configure_mtu_complete_callback = {};
109     param::bta_gattc_event_complete_callback = {};
110   }
111 
TearDown()112   void TearDown() override {}
113 
114   tBTA_GATTC_RCB app_control_block = {
115       .p_cback = bta_gattc_event_complete_callback,
116   };
117 
118   tGATT_CL_COMPLETE gatt_cl_complete = {
119       .att_value =
120           {
121               .conn_id = 1,
122               .handle = 2,
123               .offset = 3,
124               .auth_req = GATT_AUTH_REQ_NONE,
125               .value = {10, 11, 12, 13},
126               .len = 4,  // length of value above
127           },
128   };
129 
130   tBTA_GATTC_SERV service_control_block = {
131       .mtu = 456,
132   };
133   tBTA_GATTC_DATA command_queue;
134 
135   tBTA_GATTC_CLCB client_channel_control_block = {
136       .p_q_cmd = &command_queue,
137       .p_rcb = &app_control_block,
138       .p_srcb = &service_control_block,
139       .bta_conn_id = 456,
140   };
141 };
142 
TEST_F(BtaGattTest,bta_gattc_op_cmpl_read)143 TEST_F(BtaGattTest, bta_gattc_op_cmpl_read) {
144   command_queue = {
145       .api_read =  // tBTA_GATTC_API_READ
146       {
147           .hdr =
148               {
149                   .event = BTA_GATTC_API_READ_EVT,
150               },
151           .handle = 123,
152           .read_cb = bta_gatt_read_complete_callback,
153           .read_cb_data = static_cast<void*>(this),
154       },
155   };
156 
157   client_channel_control_block.p_q_cmd = &command_queue;
158 
159   tBTA_GATTC_DATA data = {
160       .op_cmpl =
161           {
162               .op_code = GATTC_OPTYPE_READ,
163               .status = GATT_OUT_OF_RANGE,
164               .p_cmpl = &gatt_cl_complete,
165           },
166   };
167 
168   bta_gattc_op_cmpl(&client_channel_control_block, &data);
169   ASSERT_EQ(1, get_func_call_count("osi_free_and_reset"));
170   ASSERT_EQ(456, param::bta_gatt_read_complete_callback.conn_id);
171   ASSERT_EQ(GATT_OUT_OF_RANGE, param::bta_gatt_read_complete_callback.status);
172   ASSERT_EQ(123, param::bta_gatt_read_complete_callback.handle);
173   ASSERT_EQ(4, param::bta_gatt_read_complete_callback.len);
174   ASSERT_EQ(10, param::bta_gatt_read_complete_callback.value[0]);
175   ASSERT_EQ(this, param::bta_gatt_read_complete_callback.data);
176 }
177 
TEST_F(BtaGattTest,bta_gattc_op_cmpl_write)178 TEST_F(BtaGattTest, bta_gattc_op_cmpl_write) {
179   command_queue = {
180       .api_write =  // tBTA_GATTC_API_WRITE
181       {
182           .hdr =
183               {
184                   .event = BTA_GATTC_API_WRITE_EVT,
185               },
186           .handle = 123,
187           .write_cb = bta_gatt_write_complete_callback,
188           .write_cb_data = static_cast<void*>(this),
189       },
190   };
191 
192   client_channel_control_block.p_q_cmd = &command_queue;
193 
194   tBTA_GATTC_DATA data = {
195       .op_cmpl =
196           {
197               .op_code = GATTC_OPTYPE_WRITE,
198               .status = GATT_OUT_OF_RANGE,
199               .p_cmpl = &gatt_cl_complete,
200           },
201   };
202 
203   bta_gattc_op_cmpl(&client_channel_control_block, &data);
204   ASSERT_EQ(1, get_func_call_count("osi_free_and_reset"));
205   ASSERT_EQ(456, param::bta_gatt_write_complete_callback.conn_id);
206   ASSERT_EQ(2, param::bta_gatt_write_complete_callback.handle);
207   ASSERT_EQ(GATT_OUT_OF_RANGE, param::bta_gatt_write_complete_callback.status);
208   ASSERT_EQ(this, param::bta_gatt_write_complete_callback.data);
209 }
210 
TEST_F(BtaGattTest,bta_gattc_op_cmpl_config)211 TEST_F(BtaGattTest, bta_gattc_op_cmpl_config) {
212   command_queue = {
213       .api_mtu =  // tBTA_GATTC_API_CFG_MTU
214       {
215           .hdr =
216               {
217                   .event = BTA_GATTC_API_CFG_MTU_EVT,
218               },
219           .mtu_cb = bta_gatt_configure_mtu_complete_callback,
220           .mtu_cb_data = static_cast<void*>(this),
221       },
222   };
223 
224   client_channel_control_block.p_q_cmd = &command_queue;
225 
226   tBTA_GATTC_DATA data = {
227       .op_cmpl =
228           {
229               .op_code = GATTC_OPTYPE_CONFIG,
230               .status = GATT_PRC_IN_PROGRESS,
231           },
232   };
233 
234   bta_gattc_op_cmpl(&client_channel_control_block, &data);
235   ASSERT_EQ(1, get_func_call_count("osi_free_and_reset"));
236   ASSERT_EQ(456, param::bta_gatt_configure_mtu_complete_callback.conn_id);
237 
238   ASSERT_EQ(GATT_PRC_IN_PROGRESS,
239             param::bta_gatt_configure_mtu_complete_callback.status);
240   ASSERT_EQ(this, param::bta_gatt_configure_mtu_complete_callback.data);
241 }
242 
TEST_F(BtaGattTest,bta_gattc_op_cmpl_execute)243 TEST_F(BtaGattTest, bta_gattc_op_cmpl_execute) {
244   command_queue = {
245       .api_exec =  // tBTA_GATTC_API_EXEC
246       {
247           .hdr =
248               {
249                   .event = BTA_GATTC_API_EXEC_EVT,
250               },
251       },
252   };
253 
254   client_channel_control_block.p_q_cmd = &command_queue;
255 
256   tBTA_GATTC_DATA data = {
257       .op_cmpl =
258           {
259               .op_code = GATTC_OPTYPE_EXE_WRITE,
260           },
261   };
262 
263   bta_gattc_op_cmpl(&client_channel_control_block, &data);
264   ASSERT_EQ(BTA_GATTC_EXEC_EVT, param::bta_gattc_event_complete_callback.event);
265   ASSERT_EQ(1, get_func_call_count("osi_free_and_reset"));
266 }
267 
TEST_F(BtaGattTest,bta_gattc_op_cmpl_read_interrupted)268 TEST_F(BtaGattTest, bta_gattc_op_cmpl_read_interrupted) {
269   command_queue = {
270       .api_read =  // tBTA_GATTC_API_READ
271       {
272           .hdr =
273               {
274                   .event = BTA_GATTC_API_READ_EVT,
275               },
276           .handle = 123,
277           .read_cb = bta_gatt_read_complete_callback,
278           .read_cb_data = static_cast<void*>(this),
279       },
280   };
281 
282   client_channel_control_block.p_q_cmd = &command_queue;
283 
284   // Create interrupt condition
285   client_channel_control_block.auto_update = BTA_GATTC_DISC_WAITING;
286   client_channel_control_block.p_srcb->srvc_hdl_chg = 1;
287 
288   tBTA_GATTC_DATA data = {
289       .op_cmpl =
290           {
291               .op_code = GATTC_OPTYPE_READ,
292               .status = GATT_OUT_OF_RANGE,
293               .p_cmpl = &gatt_cl_complete,
294           },
295   };
296 
297   bta_gattc_op_cmpl(&client_channel_control_block, &data);
298   ASSERT_EQ(GATT_ERROR, param::bta_gatt_read_complete_callback.status);
299 }
300