Home | History | Annotate | Download | only in gatt
      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  ******************************************************************************/
     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 
     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  */
     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  ******************************************************************************/
    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  ******************************************************************************/
    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 
    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  ******************************************************************************/
    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  ******************************************************************************/
    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  ******************************************************************************/
    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  ******************************************************************************/
    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 
    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  ******************************************************************************/
    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  ******************************************************************************/
    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  ******************************************************************************/
    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  ******************************************************************************/
    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  ******************************************************************************/
    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  */
    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  ******************************************************************************/
    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  ******************************************************************************/
    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  ******************************************************************************/
    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  ******************************************************************************/
    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  ******************************************************************************/
    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  ******************************************************************************/
    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  ******************************************************************************/
    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  ******************************************************************************/
    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  ******************************************************************************/
    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  ******************************************************************************/
    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