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