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