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