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