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