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