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