1 /******************************************************************************
2  *
3  *  Copyright 2010-2012 Broadcom Corporation
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18 
19 /******************************************************************************
20  *
21  *  This is the implementation of the API for GATT module of BTA.
22  *
23  ******************************************************************************/
24 
25 #define LOG_TAG "bta_gattc_api"
26 
27 #include <base/functional/bind.h>
28 #include <bluetooth/log.h>
29 
30 #include <ios>
31 #include <list>
32 #include <vector>
33 
34 #include "bta/gatt/bta_gattc_int.h"
35 #include "gd/hci/uuid.h"
36 #include "gd/os/rand.h"
37 #include "osi/include/allocator.h"
38 #include "stack/include/bt_hdr.h"
39 #include "stack/include/main_thread.h"
40 #include "types/bluetooth/uuid.h"
41 #include "types/bt_transport.h"
42 #include "types/raw_address.h"
43 
44 using bluetooth::Uuid;
45 using namespace bluetooth;
46 
47 /*****************************************************************************
48  *  Constants
49  ****************************************************************************/
50 
51 static const tBTA_SYS_REG bta_gattc_reg = {bta_gattc_hdl_event, BTA_GATTC_Disable};
52 
53 /*******************************************************************************
54  *
55  * Function         BTA_GATTC_Disable
56  *
57  * Description      This function is called to disable GATTC module
58  *
59  * Parameters       None.
60  *
61  * Returns          None
62  *
63  ******************************************************************************/
BTA_GATTC_Disable(void)64 void BTA_GATTC_Disable(void) {
65   if (!bta_sys_is_register(BTA_ID_GATTC)) {
66     log::warn("GATTC Module not enabled/already disabled");
67     return;
68   }
69 
70   do_in_main_thread(base::BindOnce(&bta_gattc_disable));
71   bta_sys_deregister(BTA_ID_GATTC);
72 }
73 
74 /**
75  * This function is called to register application callbacks with BTA GATTC
76  * module. |client_cb| pointer to the application callback function.
77  * |cb| one time callback when registration is finished
78  */
BTA_GATTC_AppRegister(tBTA_GATTC_CBACK * p_client_cb,BtaAppRegisterCallback cb,bool eatt_support)79 void BTA_GATTC_AppRegister(tBTA_GATTC_CBACK* p_client_cb, BtaAppRegisterCallback cb,
80                            bool eatt_support) {
81   log::debug("eatt_support={}", eatt_support);
82   if (!bta_sys_is_register(BTA_ID_GATTC)) {
83     log::debug("BTA_ID_GATTC not registered in BTA, registering it");
84     bta_sys_register(BTA_ID_GATTC, &bta_gattc_reg);
85   }
86 
87   Uuid uuid = Uuid::From128BitBE(bluetooth::os::GenerateRandom<Uuid::kNumBytes128>());
88 
89   do_in_main_thread(
90           base::BindOnce(&bta_gattc_register, uuid, p_client_cb, std::move(cb), eatt_support));
91 }
92 
app_deregister_impl(tGATT_IF client_if)93 static void app_deregister_impl(tGATT_IF client_if) {
94   tBTA_GATTC_RCB* p_clreg = bta_gattc_cl_get_regcb(client_if);
95 
96   if (p_clreg != nullptr) {
97     bta_gattc_deregister(p_clreg);
98   } else {
99     log::error("Unknown GATT ID: {}, state: {}", client_if, bta_gattc_cb.state);
100   }
101 }
102 /*******************************************************************************
103  *
104  * Function         BTA_GATTC_AppDeregister
105  *
106  * Description      This function is called to deregister an application
107  *                  from BTA GATTC module.
108  *
109  * Parameters       client_if - client interface identifier.
110  *
111  * Returns          None
112  *
113  ******************************************************************************/
BTA_GATTC_AppDeregister(tGATT_IF client_if)114 void BTA_GATTC_AppDeregister(tGATT_IF client_if) {
115   do_in_main_thread(base::BindOnce(&app_deregister_impl, client_if));
116 }
117 
118 /*******************************************************************************
119  *
120  * Function         BTA_GATTC_Open
121  *
122  * Description      Open a direct connection or add a background auto connection
123  *                  bd address
124  *
125  * Parameters       client_if: server interface.
126  *                  remote_bda: remote device BD address.
127  *                  connection_type: connection type used for the peer device
128  *                  transport: Transport to be used for GATT connection
129  *                             (BREDR/LE)
130  *                  initiating_phys: LE PHY to use, optional
131  *                  opportunistic: whether the connection shall be
132  *                  opportunistic, and don't impact the disconnection timer
133  *
134  ******************************************************************************/
BTA_GATTC_Open(tGATT_IF client_if,const RawAddress & remote_bda,tBLE_ADDR_TYPE addr_type,tBTM_BLE_CONN_TYPE connection_type,tBT_TRANSPORT transport,bool opportunistic,uint8_t initiating_phys,uint16_t preferred_mtu)135 void BTA_GATTC_Open(tGATT_IF client_if, const RawAddress& remote_bda, tBLE_ADDR_TYPE addr_type,
136                     tBTM_BLE_CONN_TYPE connection_type, tBT_TRANSPORT transport, bool opportunistic,
137                     uint8_t initiating_phys, uint16_t preferred_mtu) {
138   tBTA_GATTC_DATA data = {
139           .api_conn =
140                   {
141                           .hdr =
142                                   {
143                                           .event = BTA_GATTC_API_OPEN_EVT,
144                                   },
145                           .remote_bda = remote_bda,
146                           .client_if = client_if,
147                           .connection_type = connection_type,
148                           .transport = transport,
149                           .initiating_phys = initiating_phys,
150                           .opportunistic = opportunistic,
151                           .remote_addr_type = addr_type,
152                           .preferred_mtu = preferred_mtu,
153                   },
154   };
155 
156   post_on_bt_main([data]() { bta_gattc_process_api_open(&data); });
157 }
158 
BTA_GATTC_Open(tGATT_IF client_if,const RawAddress & remote_bda,tBTM_BLE_CONN_TYPE connection_type,bool opportunistic)159 void BTA_GATTC_Open(tGATT_IF client_if, const RawAddress& remote_bda,
160                     tBTM_BLE_CONN_TYPE connection_type, bool opportunistic) {
161   BTA_GATTC_Open(client_if, remote_bda, BLE_ADDR_PUBLIC, connection_type, BT_TRANSPORT_LE,
162                  opportunistic, LE_PHY_1M, 0);
163 }
164 
165 /*******************************************************************************
166  *
167  * Function         BTA_GATTC_CancelOpen
168  *
169  * Description      Cancel a direct open connection or remove a background auto
170  *                  connection
171  *                  bd address
172  *
173  * Parameters       client_if: server interface.
174  *                  remote_bda: remote device BD address.
175  *                  is_direct: direct connection or background auto connection
176  *
177  * Returns          void
178  *
179  ******************************************************************************/
BTA_GATTC_CancelOpen(tGATT_IF client_if,const RawAddress & remote_bda,bool is_direct)180 void BTA_GATTC_CancelOpen(tGATT_IF client_if, const RawAddress& remote_bda, bool is_direct) {
181   tBTA_GATTC_API_CANCEL_OPEN* p_buf =
182           (tBTA_GATTC_API_CANCEL_OPEN*)osi_malloc(sizeof(tBTA_GATTC_API_CANCEL_OPEN));
183 
184   p_buf->hdr.event = BTA_GATTC_API_CANCEL_OPEN_EVT;
185   p_buf->client_if = client_if;
186   p_buf->is_direct = is_direct;
187   p_buf->remote_bda = remote_bda;
188 
189   bta_sys_sendmsg(p_buf);
190 }
191 
192 /*******************************************************************************
193  *
194  * Function         BTA_GATTC_Close
195  *
196  * Description      Close a connection to a GATT server.
197  *
198  * Parameters       conn_id: connectino ID to be closed.
199  *
200  * Returns          void
201  *
202  ******************************************************************************/
BTA_GATTC_Close(tCONN_ID conn_id)203 void BTA_GATTC_Close(tCONN_ID conn_id) {
204   BT_HDR_RIGID* p_buf = (BT_HDR_RIGID*)osi_malloc(sizeof(BT_HDR_RIGID));
205 
206   p_buf->event = BTA_GATTC_API_CLOSE_EVT;
207   p_buf->layer_specific = static_cast<uint16_t>(conn_id);
208 
209   bta_sys_sendmsg(p_buf);
210 }
211 
212 /*******************************************************************************
213  *
214  * Function         BTA_GATTC_ConfigureMTU
215  *
216  * Description      Configure the MTU size in the GATT channel. This can be done
217  *                  only once per connection.
218  *
219  * Parameters       conn_id: connection ID.
220  *                  mtu: desired MTU size to use.
221  *
222  * Returns          void
223  *
224  ******************************************************************************/
225 
BTA_GATTC_ConfigureMTU(tCONN_ID conn_id,uint16_t mtu)226 void BTA_GATTC_ConfigureMTU(tCONN_ID conn_id, uint16_t mtu) {
227   BTA_GATTC_ConfigureMTU(conn_id, mtu, NULL, NULL);
228 }
229 
BTA_GATTC_ConfigureMTU(tCONN_ID conn_id,uint16_t mtu,GATT_CONFIGURE_MTU_OP_CB callback,void * cb_data)230 void BTA_GATTC_ConfigureMTU(tCONN_ID conn_id, uint16_t mtu, GATT_CONFIGURE_MTU_OP_CB callback,
231                             void* cb_data) {
232   tBTA_GATTC_API_CFG_MTU* p_buf =
233           (tBTA_GATTC_API_CFG_MTU*)osi_malloc(sizeof(tBTA_GATTC_API_CFG_MTU));
234 
235   p_buf->hdr.event = BTA_GATTC_API_CFG_MTU_EVT;
236   p_buf->hdr.layer_specific = static_cast<uint16_t>(conn_id);
237   p_buf->mtu = mtu;
238   p_buf->mtu_cb = callback;
239   p_buf->mtu_cb_data = cb_data;
240 
241   bta_sys_sendmsg(p_buf);
242 }
243 
BTA_GATTC_ServiceSearchAllRequest(tCONN_ID conn_id)244 void BTA_GATTC_ServiceSearchAllRequest(tCONN_ID conn_id) {
245   const size_t len = sizeof(tBTA_GATTC_API_SEARCH);
246   tBTA_GATTC_API_SEARCH* p_buf = (tBTA_GATTC_API_SEARCH*)osi_calloc(len);
247 
248   p_buf->hdr.event = BTA_GATTC_API_SEARCH_EVT;
249   p_buf->hdr.layer_specific = static_cast<uint16_t>(conn_id);
250   p_buf->p_srvc_uuid = NULL;
251 
252   bta_sys_sendmsg(p_buf);
253 }
254 
BTA_GATTC_ServiceSearchRequest(tCONN_ID conn_id,Uuid p_srvc_uuid)255 void BTA_GATTC_ServiceSearchRequest(tCONN_ID conn_id, Uuid p_srvc_uuid) {
256   const size_t len = sizeof(tBTA_GATTC_API_SEARCH) + sizeof(Uuid);
257   tBTA_GATTC_API_SEARCH* p_buf = (tBTA_GATTC_API_SEARCH*)osi_calloc(len);
258 
259   p_buf->hdr.event = BTA_GATTC_API_SEARCH_EVT;
260   p_buf->hdr.layer_specific = static_cast<uint16_t>(conn_id);
261   p_buf->p_srvc_uuid = (Uuid*)(p_buf + 1);
262   *p_buf->p_srvc_uuid = p_srvc_uuid;
263 
264   bta_sys_sendmsg(p_buf);
265 }
266 
BTA_GATTC_DiscoverServiceByUuid(tCONN_ID conn_id,const Uuid & srvc_uuid)267 void BTA_GATTC_DiscoverServiceByUuid(tCONN_ID conn_id, const Uuid& srvc_uuid) {
268   do_in_main_thread(base::BindOnce(
269           base::IgnoreResult<tGATT_STATUS (*)(tCONN_ID, tGATT_DISC_TYPE, uint16_t, uint16_t,
270                                               const Uuid&)>(&GATTC_Discover),
271           conn_id, GATT_DISC_SRVC_BY_UUID, 0x0001, 0xFFFF, srvc_uuid));
272 }
273 
274 /*******************************************************************************
275  *
276  * Function         BTA_GATTC_GetServices
277  *
278  * Description      This function is called to find the services on the given
279  *                  server.
280  *
281  * Parameters       conn_id: connection ID which identify the server.
282  *
283  * Returns          returns list of gatt::Service or NULL.
284  *
285  ******************************************************************************/
BTA_GATTC_GetServices(tCONN_ID conn_id)286 const std::list<gatt::Service>* BTA_GATTC_GetServices(tCONN_ID conn_id) {
287   return bta_gattc_get_services(conn_id);
288 }
289 
290 /*******************************************************************************
291  *
292  * Function         BTA_GATTC_GetCharacteristic
293  *
294  * Description      This function is called to find the characteristic on the
295  *                  given server.
296  *
297  * Parameters       conn_id - connection ID which identify the server.
298  *                  handle - characteristic handle
299  *
300  * Returns          returns pointer to gatt::Characteristic or NULL.
301  *
302  ******************************************************************************/
BTA_GATTC_GetCharacteristic(tCONN_ID conn_id,uint16_t handle)303 const gatt::Characteristic* BTA_GATTC_GetCharacteristic(tCONN_ID conn_id, uint16_t handle) {
304   return bta_gattc_get_characteristic(conn_id, handle);
305 }
306 
307 /*******************************************************************************
308  *
309  * Function         BTA_GATTC_GetDescriptor
310  *
311  * Description      This function is called to find the characteristic on the
312  *                  given server.
313  *
314  * Parameters       conn_id - connection ID which identify the server.
315  *                  handle - descriptor handle
316  *
317  * Returns          returns pointer to gatt::Descriptor or NULL.
318  *
319  ******************************************************************************/
BTA_GATTC_GetDescriptor(tCONN_ID conn_id,uint16_t handle)320 const gatt::Descriptor* BTA_GATTC_GetDescriptor(tCONN_ID conn_id, uint16_t handle) {
321   return bta_gattc_get_descriptor(conn_id, handle);
322 }
323 
324 /* Return characteristic that owns descriptor with handle equal to |handle|, or
325  * NULL */
BTA_GATTC_GetOwningCharacteristic(tCONN_ID conn_id,uint16_t handle)326 const gatt::Characteristic* BTA_GATTC_GetOwningCharacteristic(tCONN_ID conn_id, uint16_t handle) {
327   return bta_gattc_get_owning_characteristic(conn_id, handle);
328 }
329 
330 /* Return service that owns descriptor or characteristic with handle equal to
331  * |handle|, or NULL */
BTA_GATTC_GetOwningService(tCONN_ID conn_id,uint16_t handle)332 const gatt::Service* BTA_GATTC_GetOwningService(tCONN_ID conn_id, uint16_t handle) {
333   return bta_gattc_get_service_for_handle(conn_id, handle);
334 }
335 
336 /*******************************************************************************
337  *
338  * Function         BTA_GATTC_GetGattDb
339  *
340  * Description      This function is called to get the GATT database.
341  *
342  * Parameters       conn_id: connection ID which identify the server.
343  *                  db: output parameter which will contain the GATT database
344  *                      copy. Caller is responsible for freeing it.
345  *                  count: number of elements in database.
346  *
347  ******************************************************************************/
BTA_GATTC_GetGattDb(tCONN_ID conn_id,uint16_t start_handle,uint16_t end_handle,btgatt_db_element_t ** db,int * count)348 void BTA_GATTC_GetGattDb(tCONN_ID conn_id, uint16_t start_handle, uint16_t end_handle,
349                          btgatt_db_element_t** db, int* count) {
350   bta_gattc_get_gatt_db(conn_id, start_handle, end_handle, db, count);
351 }
352 
353 /*******************************************************************************
354  *
355  * Function         BTA_GATTC_ReadCharacteristic
356  *
357  * Description      This function is called to read a characteristics value
358  *
359  * Parameters       conn_id - connection ID.
360  *                  handle - characteritic handle to read.
361  *
362  * Returns          None
363  *
364  ******************************************************************************/
BTA_GATTC_ReadCharacteristic(tCONN_ID conn_id,uint16_t handle,tGATT_AUTH_REQ auth_req,GATT_READ_OP_CB callback,void * cb_data)365 void BTA_GATTC_ReadCharacteristic(tCONN_ID conn_id, uint16_t handle, tGATT_AUTH_REQ auth_req,
366                                   GATT_READ_OP_CB callback, void* cb_data) {
367   tBTA_GATTC_API_READ* p_buf = (tBTA_GATTC_API_READ*)osi_calloc(sizeof(tBTA_GATTC_API_READ));
368 
369   p_buf->hdr.event = BTA_GATTC_API_READ_EVT;
370   p_buf->hdr.layer_specific = static_cast<uint16_t>(conn_id);
371   p_buf->is_multi_read = false;
372   p_buf->auth_req = auth_req;
373   p_buf->handle = handle;
374   p_buf->read_cb = callback;
375   p_buf->read_cb_data = cb_data;
376 
377   bta_sys_sendmsg(p_buf);
378 }
379 
380 /**
381  * This function is called to read a value of characteristic with uuid equal to
382  * |uuid|
383  */
BTA_GATTC_ReadUsingCharUuid(tCONN_ID conn_id,const Uuid & uuid,uint16_t s_handle,uint16_t e_handle,tGATT_AUTH_REQ auth_req,GATT_READ_OP_CB callback,void * cb_data)384 void BTA_GATTC_ReadUsingCharUuid(tCONN_ID conn_id, const Uuid& uuid, uint16_t s_handle,
385                                  uint16_t e_handle, tGATT_AUTH_REQ auth_req,
386                                  GATT_READ_OP_CB callback, void* cb_data) {
387   tBTA_GATTC_API_READ* p_buf = (tBTA_GATTC_API_READ*)osi_calloc(sizeof(tBTA_GATTC_API_READ));
388 
389   p_buf->hdr.event = BTA_GATTC_API_READ_EVT;
390   p_buf->hdr.layer_specific = static_cast<uint16_t>(conn_id);
391   p_buf->is_multi_read = false;
392   p_buf->auth_req = auth_req;
393   p_buf->handle = 0;
394   p_buf->uuid = uuid;
395   p_buf->s_handle = s_handle;
396   p_buf->e_handle = e_handle;
397   p_buf->read_cb = callback;
398   p_buf->read_cb_data = cb_data;
399 
400   bta_sys_sendmsg(p_buf);
401 }
402 
403 /*******************************************************************************
404  *
405  * Function         BTA_GATTC_ReadCharDescr
406  *
407  * Description      This function is called to read a descriptor value.
408  *
409  * Parameters       conn_id - connection ID.
410  *                  handle - descriptor handle to read.
411  *
412  * Returns          None
413  *
414  ******************************************************************************/
BTA_GATTC_ReadCharDescr(tCONN_ID conn_id,uint16_t handle,tGATT_AUTH_REQ auth_req,GATT_READ_OP_CB callback,void * cb_data)415 void BTA_GATTC_ReadCharDescr(tCONN_ID conn_id, uint16_t handle, tGATT_AUTH_REQ auth_req,
416                              GATT_READ_OP_CB callback, void* cb_data) {
417   tBTA_GATTC_API_READ* p_buf = (tBTA_GATTC_API_READ*)osi_calloc(sizeof(tBTA_GATTC_API_READ));
418 
419   p_buf->hdr.event = BTA_GATTC_API_READ_EVT;
420   p_buf->hdr.layer_specific = static_cast<uint16_t>(conn_id);
421   p_buf->is_multi_read = false;
422   p_buf->auth_req = auth_req;
423   p_buf->handle = handle;
424   p_buf->read_cb = callback;
425   p_buf->read_cb_data = cb_data;
426 
427   bta_sys_sendmsg(p_buf);
428 }
429 
430 /*******************************************************************************
431  *
432  * Function         BTA_GATTC_ReadMultiple
433  *
434  * Description      This function is called to read multiple characteristic or
435  *                  characteristic descriptors.
436  *
437  * Parameters       conn_id - connection ID.
438  *                  p_read_multi - pointer to the read multiple parameter.
439  *                  variable_len - whether "read multi variable length" variant
440  *                                 shall be used.
441  *
442  *
443  * Returns          None
444  *
445  ******************************************************************************/
BTA_GATTC_ReadMultiple(tCONN_ID conn_id,tBTA_GATTC_MULTI & handles,bool variable_len,tGATT_AUTH_REQ auth_req,GATT_READ_MULTI_OP_CB callback,void * cb_data)446 void BTA_GATTC_ReadMultiple(tCONN_ID conn_id, tBTA_GATTC_MULTI& handles, bool variable_len,
447                             tGATT_AUTH_REQ auth_req, GATT_READ_MULTI_OP_CB callback,
448                             void* cb_data) {
449   tBTA_GATTC_API_READ_MULTI* p_buf =
450           (tBTA_GATTC_API_READ_MULTI*)osi_calloc(sizeof(tBTA_GATTC_API_READ_MULTI));
451 
452   p_buf->hdr.event = BTA_GATTC_API_READ_MULTI_EVT;
453   p_buf->hdr.layer_specific = static_cast<uint16_t>(conn_id);
454   p_buf->is_multi_read = true;
455   p_buf->auth_req = auth_req;
456   p_buf->handles = handles;
457   p_buf->variable_len = variable_len;
458   p_buf->read_cb = callback;
459   p_buf->read_cb_data = cb_data;
460   bta_sys_sendmsg(p_buf);
461 }
462 
463 /*******************************************************************************
464  *
465  * Function         BTA_GATTC_WriteCharValue
466  *
467  * Description      This function is called to write characteristic value.
468  *
469  * Parameters       conn_id - connection ID.
470  *                  handle - characteristic handle to write.
471  *                  write_type - type of write.
472  *                  value - the value to be written.
473  *
474  * Returns          None
475  *
476  ******************************************************************************/
BTA_GATTC_WriteCharValue(tCONN_ID conn_id,uint16_t handle,tGATT_WRITE_TYPE write_type,std::vector<uint8_t> value,tGATT_AUTH_REQ auth_req,GATT_WRITE_OP_CB callback,void * cb_data)477 void BTA_GATTC_WriteCharValue(tCONN_ID conn_id, uint16_t handle, tGATT_WRITE_TYPE write_type,
478                               std::vector<uint8_t> value, tGATT_AUTH_REQ auth_req,
479                               GATT_WRITE_OP_CB callback, void* cb_data) {
480   tBTA_GATTC_API_WRITE* p_buf =
481           (tBTA_GATTC_API_WRITE*)osi_calloc(sizeof(tBTA_GATTC_API_WRITE) + value.size());
482 
483   p_buf->hdr.event = BTA_GATTC_API_WRITE_EVT;
484   p_buf->hdr.layer_specific = static_cast<uint16_t>(conn_id);
485   p_buf->auth_req = auth_req;
486   p_buf->handle = handle;
487   p_buf->write_type = write_type;
488   p_buf->len = value.size();
489   p_buf->write_cb = callback;
490   p_buf->write_cb_data = cb_data;
491 
492   if (value.size() > 0) {
493     p_buf->p_value = (uint8_t*)(p_buf + 1);
494     memcpy(p_buf->p_value, value.data(), value.size());
495   }
496 
497   bta_sys_sendmsg(p_buf);
498 }
499 
500 /*******************************************************************************
501  *
502  * Function         BTA_GATTC_WriteCharDescr
503  *
504  * Description      This function is called to write descriptor value.
505  *
506  * Parameters       conn_id - connection ID
507  *                  handle - descriptor hadle to write.
508  *                  value - the value to be written.
509  *
510  * Returns          None
511  *
512  ******************************************************************************/
BTA_GATTC_WriteCharDescr(tCONN_ID conn_id,uint16_t handle,std::vector<uint8_t> value,tGATT_AUTH_REQ auth_req,GATT_WRITE_OP_CB callback,void * cb_data)513 void BTA_GATTC_WriteCharDescr(tCONN_ID conn_id, uint16_t handle, std::vector<uint8_t> value,
514                               tGATT_AUTH_REQ auth_req, GATT_WRITE_OP_CB callback, void* cb_data) {
515   tBTA_GATTC_API_WRITE* p_buf =
516           (tBTA_GATTC_API_WRITE*)osi_calloc(sizeof(tBTA_GATTC_API_WRITE) + value.size());
517 
518   p_buf->hdr.event = BTA_GATTC_API_WRITE_EVT;
519   p_buf->hdr.layer_specific = static_cast<uint16_t>(conn_id);
520   p_buf->auth_req = auth_req;
521   p_buf->handle = handle;
522   p_buf->write_type = GATT_WRITE;
523   p_buf->write_cb = callback;
524   p_buf->write_cb_data = cb_data;
525 
526   if (value.size() != 0) {
527     p_buf->p_value = (uint8_t*)(p_buf + 1);
528     p_buf->len = value.size();
529     memcpy(p_buf->p_value, value.data(), value.size());
530   }
531 
532   bta_sys_sendmsg(p_buf);
533 }
534 
535 /*******************************************************************************
536  *
537  * Function         BTA_GATTC_PrepareWrite
538  *
539  * Description      This function is called to prepare write a characteristic
540  *                  value.
541  *
542  * Parameters       conn_id - connection ID.
543  *                  p_char_id - GATT characteritic ID of the service.
544  *                  offset - offset of the write value.
545  *                  value - the value to be written.
546  *
547  * Returns          None
548  *
549  ******************************************************************************/
BTA_GATTC_PrepareWrite(tCONN_ID conn_id,uint16_t handle,uint16_t offset,std::vector<uint8_t> value,tGATT_AUTH_REQ auth_req,GATT_WRITE_OP_CB callback,void * cb_data)550 void BTA_GATTC_PrepareWrite(tCONN_ID conn_id, uint16_t handle, uint16_t offset,
551                             std::vector<uint8_t> value, tGATT_AUTH_REQ auth_req,
552                             GATT_WRITE_OP_CB callback, void* cb_data) {
553   tBTA_GATTC_API_WRITE* p_buf =
554           (tBTA_GATTC_API_WRITE*)osi_calloc(sizeof(tBTA_GATTC_API_WRITE) + value.size());
555 
556   p_buf->hdr.event = BTA_GATTC_API_WRITE_EVT;
557   p_buf->hdr.layer_specific = static_cast<uint16_t>(conn_id);
558   p_buf->auth_req = auth_req;
559   p_buf->handle = handle;
560   p_buf->write_cb = callback;
561   p_buf->write_cb_data = cb_data;
562 
563   p_buf->write_type = BTA_GATTC_WRITE_PREPARE;
564   p_buf->offset = offset;
565   p_buf->len = value.size();
566 
567   if (value.size() > 0) {
568     p_buf->p_value = (uint8_t*)(p_buf + 1);
569     memcpy(p_buf->p_value, value.data(), value.size());
570   }
571 
572   bta_sys_sendmsg(p_buf);
573 }
574 
575 /*******************************************************************************
576  *
577  * Function         BTA_GATTC_ExecuteWrite
578  *
579  * Description      This function is called to execute write a prepare write
580  *                  sequence.
581  *
582  * Parameters       conn_id - connection ID.
583  *                    is_execute - execute or cancel.
584  *
585  * Returns          None
586  *
587  ******************************************************************************/
BTA_GATTC_ExecuteWrite(tCONN_ID conn_id,bool is_execute)588 void BTA_GATTC_ExecuteWrite(tCONN_ID conn_id, bool is_execute) {
589   tBTA_GATTC_API_EXEC* p_buf = (tBTA_GATTC_API_EXEC*)osi_calloc(sizeof(tBTA_GATTC_API_EXEC));
590 
591   p_buf->hdr.event = BTA_GATTC_API_EXEC_EVT;
592   p_buf->hdr.layer_specific = static_cast<uint16_t>(conn_id);
593   p_buf->is_execute = is_execute;
594 
595   bta_sys_sendmsg(p_buf);
596 }
597 
598 /*******************************************************************************
599  *
600  * Function         BTA_GATTC_SendIndConfirm
601  *
602  * Description      This function is called to send handle value confirmation.
603  *
604  * Parameters       conn_id - connection ID.
605  *                  cid
606  *
607  * Returns          None
608  *
609  ******************************************************************************/
BTA_GATTC_SendIndConfirm(tCONN_ID conn_id,uint16_t cid)610 void BTA_GATTC_SendIndConfirm(tCONN_ID conn_id, uint16_t cid) {
611   tBTA_GATTC_API_CONFIRM* p_buf =
612           (tBTA_GATTC_API_CONFIRM*)osi_calloc(sizeof(tBTA_GATTC_API_CONFIRM));
613 
614   log::verbose("conn_id={} cid=0x{:x}", conn_id, cid);
615 
616   p_buf->hdr.event = BTA_GATTC_API_CONFIRM_EVT;
617   p_buf->hdr.layer_specific = static_cast<uint16_t>(conn_id);
618   p_buf->cid = cid;
619 
620   bta_sys_sendmsg(p_buf);
621 }
622 
623 /*******************************************************************************
624  *
625  * Function         BTA_GATTC_RegisterForNotifications
626  *
627  * Description      This function is called to register for notification of a
628  *                  service.
629  *
630  * Parameters       client_if - client interface.
631  *                  bda - target GATT server.
632  *                  handle - GATT characteristic handle.
633  *
634  * Returns          OK if registration succeed, otherwise failed.
635  *
636  ******************************************************************************/
BTA_GATTC_RegisterForNotifications(tGATT_IF client_if,const RawAddress & bda,uint16_t handle)637 tGATT_STATUS BTA_GATTC_RegisterForNotifications(tGATT_IF client_if, const RawAddress& bda,
638                                                 uint16_t handle) {
639   tBTA_GATTC_RCB* p_clreg;
640   tGATT_STATUS status = GATT_ILLEGAL_PARAMETER;
641   uint8_t i;
642 
643   if (!handle) {
644     log::error("registration failed, handle is 0");
645     return status;
646   }
647 
648   p_clreg = bta_gattc_cl_get_regcb(client_if);
649   if (p_clreg != NULL) {
650     for (i = 0; i < BTA_GATTC_NOTIF_REG_MAX; i++) {
651       if (p_clreg->notif_reg[i].in_use && p_clreg->notif_reg[i].remote_bda == bda &&
652           p_clreg->notif_reg[i].handle == handle) {
653         log::warn("notification already registered");
654         status = GATT_SUCCESS;
655         break;
656       }
657     }
658     if (status != GATT_SUCCESS) {
659       for (i = 0; i < BTA_GATTC_NOTIF_REG_MAX; i++) {
660         if (!p_clreg->notif_reg[i].in_use) {
661           memset((void*)&p_clreg->notif_reg[i], 0, sizeof(tBTA_GATTC_NOTIF_REG));
662 
663           p_clreg->notif_reg[i].in_use = true;
664           p_clreg->notif_reg[i].remote_bda = bda;
665 
666           p_clreg->notif_reg[i].handle = handle;
667           status = GATT_SUCCESS;
668           break;
669         }
670       }
671       if (i == BTA_GATTC_NOTIF_REG_MAX) {
672         status = GATT_NO_RESOURCES;
673         log::error("Max Notification Reached, registration failed.");
674       }
675     }
676   } else {
677     log::error("client_if={} Not Registered", client_if);
678   }
679 
680   return status;
681 }
682 
683 /*******************************************************************************
684  *
685  * Function         BTA_GATTC_DeregisterForNotifications
686  *
687  * Description      This function is called to de-register for notification of a
688  *                  service.
689  *
690  * Parameters       client_if - client interface.
691  *                  remote_bda - target GATT server.
692  *                  handle - GATT characteristic handle.
693  *
694  * Returns          OK if deregistration succeed, otherwise failed.
695  *
696  ******************************************************************************/
BTA_GATTC_DeregisterForNotifications(tGATT_IF client_if,const RawAddress & bda,uint16_t handle)697 tGATT_STATUS BTA_GATTC_DeregisterForNotifications(tGATT_IF client_if, const RawAddress& bda,
698                                                   uint16_t handle) {
699   if (!handle) {
700     log::error("deregistration failed, handle is 0");
701     return GATT_ILLEGAL_PARAMETER;
702   }
703 
704   tBTA_GATTC_RCB* p_clreg = bta_gattc_cl_get_regcb(client_if);
705   if (p_clreg == NULL) {
706     log::error("client_if={} not registered bd_addr={}", client_if, bda);
707     return GATT_ILLEGAL_PARAMETER;
708   }
709 
710   for (int i = 0; i < BTA_GATTC_NOTIF_REG_MAX; i++) {
711     if (p_clreg->notif_reg[i].in_use && p_clreg->notif_reg[i].remote_bda == bda &&
712         p_clreg->notif_reg[i].handle == handle) {
713       log::verbose("deregistered bd_addr={}", bda);
714       memset(&p_clreg->notif_reg[i], 0, sizeof(tBTA_GATTC_NOTIF_REG));
715       return GATT_SUCCESS;
716     }
717   }
718 
719   log::error("registration not found bd_addr={}", bda);
720   return GATT_ERROR;
721 }
722 
723 /*******************************************************************************
724  *
725  * Function         BTA_GATTC_Refresh
726  *
727  * Description      Refresh the server cache of the remote device
728  *
729  * Parameters       remote_bda: remote device BD address.
730  *
731  * Returns          void
732  *
733  ******************************************************************************/
BTA_GATTC_Refresh(const RawAddress & remote_bda)734 void BTA_GATTC_Refresh(const RawAddress& remote_bda) {
735   do_in_main_thread(base::Bind(&bta_gattc_process_api_refresh, remote_bda));
736 }
737