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 "gki.h"
     31 #include "bta_sys.h"
     32 #include "bta_gatt_api.h"
     33 #include "bta_gattc_int.h"
     34 
     35 
     36 /*****************************************************************************
     37 **  Externs
     38 *****************************************************************************/
     39 #if BTA_DYNAMIC_MEMORY == FALSE
     40 extern tBTA_GATTC_CB  bta_gattc_cb;
     41 #endif
     42 
     43 /*****************************************************************************
     44 **  Constants
     45 *****************************************************************************/
     46 
     47 static const tBTA_SYS_REG bta_gatt_reg =
     48 {
     49     bta_gattc_hdl_event,
     50     NULL        /* need a disable functino to be called when BT is disabled */
     51 };
     52 
     53 /*******************************************************************************
     54 **
     55 ** Function         BTA_GATTC_Init
     56 **
     57 ** Description     This function is called to initalize GATTC module
     58 **
     59 ** Parameters       None
     60 **
     61 ** Returns          None
     62 **
     63 *******************************************************************************/
     64 void BTA_GATTC_Init()
     65 {
     66     memset(&bta_gattc_cb, 0, sizeof(tBTA_GATTC_CB));
     67 }
     68 
     69 /*******************************************************************************
     70 **
     71 ** Function         BTA_GATTC_AppRegister
     72 **
     73 ** Description      This function is called to register application callbacks
     74 **                    with BTA GATTC module.
     75 **
     76 ** Parameters       p_app_uuid - applicaiton UUID
     77 **                  p_client_cb - pointer to the application callback function.
     78 **
     79 ** Returns          None
     80 **
     81 *******************************************************************************/
     82 void BTA_GATTC_AppRegister(tBT_UUID *p_app_uuid, tBTA_GATTC_CBACK *p_client_cb)
     83 {
     84     tBTA_GATTC_API_REG  *p_buf;
     85 
     86     /* register with BTA system manager */
     87     GKI_sched_lock();
     88     bta_sys_register(BTA_ID_GATTC, &bta_gatt_reg);
     89     GKI_sched_unlock();
     90 
     91     if ((p_buf = (tBTA_GATTC_API_REG *) GKI_getbuf(sizeof(tBTA_GATTC_API_REG))) != NULL)
     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     return;
    101 }
    102 
    103 /*******************************************************************************
    104 **
    105 ** Function         BTA_GATTC_AppDeregister
    106 **
    107 ** Description      This function is called to deregister an application
    108 **                  from BTA GATTC module.
    109 **
    110 ** Parameters       client_if - client interface identifier.
    111 **
    112 ** Returns          None
    113 **
    114 *******************************************************************************/
    115 void BTA_GATTC_AppDeregister(tBTA_GATTC_IF client_if)
    116 {
    117     tBTA_GATTC_API_DEREG  *p_buf;
    118 
    119     if ((p_buf = (tBTA_GATTC_API_DEREG *) GKI_getbuf(sizeof(tBTA_GATTC_API_DEREG))) != NULL)
    120     {
    121         p_buf->hdr.event = BTA_GATTC_API_DEREG_EVT;
    122         p_buf->client_if = client_if;
    123         bta_sys_sendmsg(p_buf);
    124     }
    125     return;
    126 }
    127 
    128 /*******************************************************************************
    129 **
    130 ** Function         BTA_GATTC_Open
    131 **
    132 ** Description      Open a direct connection or add a background auto connection
    133 **                  bd address
    134 **
    135 ** Parameters       client_if: server interface.
    136 **                  remote_bda: remote device BD address.
    137 **                  is_direct: direct connection or background auto connection
    138 **
    139 ** Returns          void
    140 **
    141 *******************************************************************************/
    142 void BTA_GATTC_Open(tBTA_GATTC_IF client_if, BD_ADDR remote_bda, BOOLEAN is_direct)
    143 {
    144     tBTA_GATTC_API_OPEN  *p_buf;
    145 
    146     if ((p_buf = (tBTA_GATTC_API_OPEN *) GKI_getbuf(sizeof(tBTA_GATTC_API_OPEN))) != NULL)
    147     {
    148         p_buf->hdr.event = BTA_GATTC_API_OPEN_EVT;
    149 
    150         p_buf->client_if = client_if;
    151         p_buf->is_direct = is_direct;
    152         memcpy(p_buf->remote_bda, remote_bda, BD_ADDR_LEN);
    153 
    154 
    155         bta_sys_sendmsg(p_buf);
    156     }
    157     return;
    158 }
    159 
    160 /*******************************************************************************
    161 **
    162 ** Function         BTA_GATTC_CancelOpen
    163 **
    164 ** Description      Cancel a direct open connection or remove a background auto connection
    165 **                  bd address
    166 **
    167 ** Parameters       client_if: server interface.
    168 **                  remote_bda: remote device BD address.
    169 **                  is_direct: direct connection or background auto connection
    170 **
    171 ** Returns          void
    172 **
    173 *******************************************************************************/
    174 void BTA_GATTC_CancelOpen(tBTA_GATTC_IF client_if, BD_ADDR remote_bda, BOOLEAN is_direct)
    175 {
    176     tBTA_GATTC_API_CANCEL_OPEN  *p_buf;
    177 
    178     if ((p_buf = (tBTA_GATTC_API_CANCEL_OPEN *) GKI_getbuf(sizeof(tBTA_GATTC_API_CANCEL_OPEN))) != NULL)
    179     {
    180         p_buf->hdr.event = BTA_GATTC_API_CANCEL_OPEN_EVT;
    181 
    182         p_buf->client_if = client_if;
    183         p_buf->is_direct = is_direct;
    184         memcpy(p_buf->remote_bda, remote_bda, BD_ADDR_LEN);
    185 
    186         bta_sys_sendmsg(p_buf);
    187     }
    188     return;
    189 }
    190 
    191 /*******************************************************************************
    192 **
    193 ** Function         BTA_GATTC_Close
    194 **
    195 ** Description      Close a connection to a GATT server.
    196 **
    197 ** Parameters       conn_id: connectino ID to be closed.
    198 **
    199 ** Returns          void
    200 **
    201 *******************************************************************************/
    202 void BTA_GATTC_Close(UINT16 conn_id)
    203 {
    204     BT_HDR  *p_buf;
    205 
    206     if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
    207     {
    208         p_buf->event = BTA_GATTC_API_CLOSE_EVT;
    209 
    210         p_buf->layer_specific = conn_id;
    211 
    212         bta_sys_sendmsg(p_buf);
    213     }
    214     return;
    215 
    216 }
    217 /*******************************************************************************
    218 **
    219 ** Function         BTA_GATTC_ServiceSearchRequest
    220 **
    221 ** Description      This function is called to request a GATT service discovery
    222 **                    on a GATT server. This function report service search result
    223 **                  by a callback event, and followed by a service search complete
    224 **                  event.
    225 **
    226 ** Parameters       conn_id: connection ID.
    227 **                  p_srvc_uuid: a UUID of the service application is interested in.
    228 **                              If Null, discover for all services.
    229 **
    230 ** Returns          None
    231 **
    232 *******************************************************************************/
    233 void BTA_GATTC_ServiceSearchRequest (UINT16 conn_id, tBT_UUID *p_srvc_uuid)
    234 {
    235     tBTA_GATTC_API_SEARCH  *p_buf;
    236     UINT16  len = sizeof(tBTA_GATTC_API_SEARCH) + sizeof(tBT_UUID);
    237 
    238     if ((p_buf = (tBTA_GATTC_API_SEARCH *) GKI_getbuf(len)) != NULL)
    239     {
    240         memset(p_buf, 0, len);
    241 
    242         p_buf->hdr.event = BTA_GATTC_API_SEARCH_EVT;
    243         p_buf->hdr.layer_specific = conn_id;
    244 
    245         if (p_srvc_uuid)
    246         {
    247             memcpy(&p_buf->srvc_uuid, p_srvc_uuid, sizeof(tBT_UUID));
    248         }
    249         bta_sys_sendmsg(p_buf);
    250     }
    251     return;
    252 }
    253 
    254 
    255 /*******************************************************************************
    256 **
    257 ** Function         BTA_GATTC_GetFirstChar
    258 **
    259 ** Description      This function is called to find the first characteristic of the
    260 **                  service on the given server.
    261 **
    262 ** Parameters       conn_id: connection ID which identify the server.
    263 **                  p_srvc_id: the service ID of which the characteristic is belonged to.
    264 **                  p_char_uuid_cond: Characteristic UUID, if NULL find the first available
    265 **                               characteristic.
    266 **                  p_char_result: output parameter which will store the GATT
    267 **                                  characteristic ID.
    268 **                  p_property: output parameter to carry the characteristic property.
    269 **
    270 ** Returns          returns status.
    271 **
    272 *******************************************************************************/
    273 tBTA_GATT_STATUS  BTA_GATTC_GetFirstChar (UINT16 conn_id, tBTA_GATT_SRVC_ID *p_srvc_id,
    274                                           tBT_UUID *p_char_uuid_cond,
    275                                           tBTA_GATTC_CHAR_ID *p_char_result,
    276                                           tBTA_GATT_CHAR_PROP *p_property)
    277 {
    278     tBTA_GATT_STATUS    status;
    279 
    280     if (!p_srvc_id || !p_char_result)
    281         return BTA_GATT_ILLEGAL_PARAMETER;
    282 
    283     if ((status = bta_gattc_query_cache(conn_id, BTA_GATTC_ATTR_TYPE_CHAR, p_srvc_id, NULL,
    284                                         p_char_uuid_cond, &p_char_result->char_id, p_property))
    285         == BTA_GATT_OK)
    286     {
    287         memcpy(&p_char_result->srvc_id, p_srvc_id, sizeof(tBTA_GATT_SRVC_ID));
    288     }
    289 
    290     return status;
    291 
    292 }
    293 /*******************************************************************************
    294 **
    295 ** Function         BTA_GATTC_GetNextChar
    296 **
    297 ** Description      This function is called to find the next characteristic of the
    298 **                  service on the given server.
    299 **
    300 ** Parameters       conn_id: connection ID which identify the server.
    301 **                  p_start_char_id: start the characteristic search from the next record
    302 **                           after the one identified by char_id.
    303 **                  p_char_uuid_cond: Characteristic UUID, if NULL find the first available
    304 **                               characteristic.
    305 **                  p_char_result: output parameter which will store the GATT
    306 **                                  characteristic ID.
    307 **                  p_property: output parameter to carry the characteristic property.
    308 **
    309 ** Returns          returns status.
    310 **
    311 *******************************************************************************/
    312 tBTA_GATT_STATUS  BTA_GATTC_GetNextChar (UINT16 conn_id,
    313                                          tBTA_GATTC_CHAR_ID *p_start_char_id,
    314                                          tBT_UUID           *p_char_uuid_cond,
    315                                          tBTA_GATTC_CHAR_ID *p_char_result,
    316                                          tBTA_GATT_CHAR_PROP    *p_property)
    317 {
    318     tBTA_GATT_STATUS    status;
    319 
    320     if (!p_start_char_id || !p_char_result)
    321         return BTA_GATT_ILLEGAL_PARAMETER;
    322 
    323     if ((status = bta_gattc_query_cache(conn_id, BTA_GATTC_ATTR_TYPE_CHAR,
    324                                         &p_start_char_id->srvc_id,
    325                                         &p_start_char_id->char_id,
    326                                         p_char_uuid_cond,
    327                                         &p_char_result->char_id,
    328                                         p_property))
    329         == BTA_GATT_OK)
    330     {
    331         memcpy(&p_char_result->srvc_id, &p_start_char_id->srvc_id, sizeof(tBTA_GATT_SRVC_ID));
    332     }
    333 
    334     return status;
    335 }
    336 
    337 /*******************************************************************************
    338 **
    339 ** Function         BTA_GATTC_GetFirstCharDescr
    340 **
    341 ** Description      This function is called to find the first characteristic descriptor of the
    342 **                  characteristic on the given server.
    343 **
    344 ** Parameters       conn_id: connection ID which identify the server.
    345 **                  p_char_id: the characteristic ID of which the descriptor is belonged to.
    346 **                  p_descr_uuid_cond: Characteristic Descr UUID, if NULL find the first available
    347 **                               characteristic.
    348 **                  p_descr_result: output parameter which will store the GATT
    349 **                                  characteristic descriptor ID.
    350 **
    351 ** Returns          returns status.
    352 **
    353 *******************************************************************************/
    354 tBTA_GATT_STATUS  BTA_GATTC_GetFirstCharDescr (UINT16 conn_id, tBTA_GATTC_CHAR_ID *p_char_id,
    355                                                 tBT_UUID *p_descr_uuid_cond,
    356                                                 tBTA_GATTC_CHAR_DESCR_ID *p_descr_result)
    357 {
    358     tBTA_GATT_STATUS    status;
    359 
    360     if (!p_char_id || !p_descr_result)
    361         return BTA_GATT_ILLEGAL_PARAMETER;
    362 
    363     memset(p_descr_result, 0, sizeof(tBTA_GATTC_CHAR_DESCR_ID));
    364 
    365     if ((status = bta_gattc_query_cache(conn_id,
    366                                         BTA_GATTC_ATTR_TYPE_CHAR_DESCR,
    367                                         &p_char_id->srvc_id,
    368                                         &p_char_id->char_id,
    369                                         p_descr_uuid_cond,
    370                                         &p_descr_result->char_id.char_id,
    371                                         NULL))
    372         == BTA_GATT_OK)
    373     {
    374         memcpy(&p_descr_result->descr_type, &p_descr_result->char_id.char_id.uuid, sizeof(tBT_UUID));
    375         memcpy(&p_descr_result->char_id, p_char_id, sizeof(tBTA_GATTC_CHAR_ID));
    376     }
    377 
    378     return status;
    379 
    380 }
    381 /*******************************************************************************
    382 **
    383 ** Function         BTA_GATTC_GetNextCharDescr
    384 **
    385 ** Description      This function is called to find the next characteristic descriptor
    386 **                  of the characterisctic.
    387 **
    388 ** Parameters       conn_id: connection ID which identify the server.
    389 **                  p_start_descr_id: start the characteristic search from the next record
    390 **                           after the one identified by p_start_descr_id.
    391 **                  p_descr_uuid_cond: Characteristic descriptor UUID, if NULL find
    392 **                               the first available characteristic descriptor.
    393 **                  p_descr_result: output parameter which will store the GATT
    394 **                                  characteristic descriptor ID.
    395 **
    396 ** Returns          returns status.
    397 **
    398 *******************************************************************************/
    399 tBTA_GATT_STATUS  BTA_GATTC_GetNextCharDescr (UINT16 conn_id,
    400                                              tBTA_GATTC_CHAR_DESCR_ID *p_start_descr_id,
    401                                              tBT_UUID           *p_descr_uuid_cond,
    402                                              tBTA_GATTC_CHAR_DESCR_ID *p_descr_result)
    403 {
    404     tBTA_GATT_STATUS    status;
    405 
    406     if (!p_start_descr_id || !p_descr_result)
    407         return BTA_GATT_ILLEGAL_PARAMETER;
    408 
    409     memset(p_descr_result, 0, sizeof(tBTA_GATTC_CHAR_DESCR_ID));
    410 
    411     if ((status = bta_gattc_query_cache(conn_id, BTA_GATTC_ATTR_TYPE_CHAR_DESCR,
    412                                         &p_start_descr_id->char_id.srvc_id,
    413                                         &p_start_descr_id->char_id.char_id,
    414                                         p_descr_uuid_cond,
    415                                         &p_descr_result->char_id.char_id,
    416                                         (void *)&p_start_descr_id->descr_type))
    417         == BTA_GATT_OK)
    418     {
    419         memcpy(&p_descr_result->descr_type, &p_descr_result->char_id.char_id.uuid, sizeof(tBT_UUID));
    420         memcpy(&p_descr_result->char_id, p_start_descr_id, sizeof(tBTA_GATTC_CHAR_ID));
    421     }
    422 
    423     return status;
    424 }
    425 
    426 
    427 /*******************************************************************************
    428 **
    429 ** Function         BTA_GATTC_GetFirstIncludedService
    430 **
    431 ** Description      This function is called to find the first included service of the
    432 **                  service on the given server.
    433 **
    434 ** Parameters       conn_id: connection ID which identify the server.
    435 **                  p_srvc_id: the service ID of which the characteristic is belonged to.
    436 **                  p_uuid_cond: Characteristic UUID, if NULL find the first available
    437 **                               characteristic.
    438 **                  p_result: output parameter which will store the GATT ID
    439 **                              of the included service found.
    440 **
    441 ** Returns          returns status.
    442 **
    443 *******************************************************************************/
    444 tBTA_GATT_STATUS  BTA_GATTC_GetFirstIncludedService(UINT16 conn_id, tBTA_GATT_SRVC_ID *p_srvc_id,
    445                                                     tBT_UUID *p_uuid_cond, tBTA_GATTC_INCL_SVC_ID *p_result)
    446 {
    447     tBTA_GATT_STATUS    status;
    448 
    449     if (!p_srvc_id || !p_result)
    450         return BTA_GATT_ILLEGAL_PARAMETER;
    451 
    452     if ((status = bta_gattc_query_cache(conn_id,
    453                                         BTA_GATTC_ATTR_TYPE_INCL_SRVC,
    454                                         p_srvc_id,
    455                                         NULL,
    456                                         p_uuid_cond,
    457                                         &p_result->incl_svc_id.id,
    458                                         (tBTA_GATT_CHAR_PROP *)&p_result->incl_svc_id.is_primary))
    459         == BTA_GATT_OK)
    460     {
    461         memcpy(&p_result->srvc_id, p_srvc_id, sizeof(tBTA_GATT_SRVC_ID));
    462     }
    463 
    464     return status;
    465 }
    466 /*******************************************************************************
    467 **
    468 ** Function         BTA_GATTC_GetNextIncludedService
    469 **
    470 ** Description      This function is called to find the next included service of the
    471 **                  service on the given server.
    472 **
    473 ** Parameters       conn_id: connection ID which identify the server.
    474 **                  p_start_id: start the search from the next record
    475 **                                  after the one identified by p_start_id.
    476 **                  p_uuid_cond: Included service UUID, if NULL find the first available
    477 **                               included service.
    478 **                  p_result: output parameter which will store the GATT ID
    479 **                              of the included service found.
    480 **
    481 ** Returns          returns status.
    482 **
    483 *******************************************************************************/
    484 tBTA_GATT_STATUS  BTA_GATTC_GetNextIncludedService(UINT16 conn_id,
    485                                                    tBTA_GATTC_INCL_SVC_ID *p_start_id,
    486                                                    tBT_UUID               *p_uuid_cond,
    487                                                    tBTA_GATTC_INCL_SVC_ID *p_result)
    488 {
    489     tBTA_GATT_STATUS    status;
    490 
    491     if (!p_start_id || !p_result)
    492         return BTA_GATT_ILLEGAL_PARAMETER;
    493 
    494     if ((status = bta_gattc_query_cache(conn_id,
    495                                         BTA_GATTC_ATTR_TYPE_INCL_SRVC,
    496                                         &p_start_id->srvc_id,
    497                                         &p_start_id->incl_svc_id.id,
    498                                         p_uuid_cond,
    499                                         &p_result->incl_svc_id.id,
    500                                         (tBTA_GATT_CHAR_PROP *)&p_result->incl_svc_id.is_primary))
    501         == BTA_GATT_OK)
    502     {
    503         memcpy(&p_result->srvc_id, &p_start_id->srvc_id, sizeof(tBTA_GATT_SRVC_ID));
    504     }
    505 
    506     return status;
    507 }
    508 
    509 /*******************************************************************************
    510 **
    511 ** Function         BTA_GATTC_ReadCharacteristic
    512 **
    513 ** Description      This function is called to read a service's characteristics of
    514 **                    the given characteritisc ID.
    515 **
    516 ** Parameters       conn_id - connectino ID.
    517 **                    p_char_id - characteritic ID to read.
    518 **
    519 ** Returns          None
    520 **
    521 *******************************************************************************/
    522 void BTA_GATTC_ReadCharacteristic(UINT16 conn_id, tBTA_GATTC_CHAR_ID *p_char_id,
    523                                   tBTA_GATT_AUTH_REQ auth_req)
    524 {
    525     tBTA_GATTC_API_READ  *p_buf;
    526 
    527     if ((p_buf = (tBTA_GATTC_API_READ *) GKI_getbuf(sizeof(tBTA_GATTC_API_READ))) != NULL)
    528     {
    529         memset(p_buf, 0, sizeof(tBTA_GATTC_API_READ));
    530 
    531         p_buf->hdr.event = BTA_GATTC_API_READ_EVT;
    532         p_buf->hdr.layer_specific = conn_id;
    533         p_buf->auth_req = auth_req;
    534 
    535         memcpy(&p_buf->srvc_id, &p_char_id->srvc_id, sizeof(tBTA_GATT_SRVC_ID));
    536         memcpy(&p_buf->char_id, &p_char_id->char_id, sizeof(tBTA_GATT_ID));
    537 
    538         bta_sys_sendmsg(p_buf);
    539     }
    540     return;
    541 }
    542 
    543 /*******************************************************************************
    544 **
    545 ** Function         BTA_GATTC_ReadCharDescr
    546 **
    547 ** Description      This function is called to read a characteristics descriptor.
    548 **
    549 ** Parameters       conn_id - connection ID.
    550 **                    p_char_descr_id - characteritic descriptor ID to read.
    551 **
    552 ** Returns          None
    553 **
    554 *******************************************************************************/
    555 void BTA_GATTC_ReadCharDescr (UINT16 conn_id,
    556                               tBTA_GATTC_CHAR_DESCR_ID  *p_descr_id,
    557                               tBTA_GATT_AUTH_REQ auth_req)
    558 {
    559     tBTA_GATTC_API_READ  *p_buf;
    560 
    561     if ((p_buf = (tBTA_GATTC_API_READ *) GKI_getbuf(sizeof(tBTA_GATTC_API_READ))) != NULL)
    562     {
    563         memset(p_buf, 0, sizeof(tBTA_GATTC_API_READ));
    564 
    565         p_buf->hdr.event = BTA_GATTC_API_READ_EVT;
    566         p_buf->hdr.layer_specific = conn_id;
    567         p_buf->auth_req = auth_req;
    568 
    569         memcpy(&p_buf->srvc_id, &p_descr_id->char_id.srvc_id, sizeof(tBTA_GATT_SRVC_ID));
    570         memcpy(&p_buf->char_id, &p_descr_id->char_id.char_id, sizeof(tBTA_GATT_ID));
    571         memcpy(&p_buf->descr_type, &p_descr_id->descr_type, sizeof(tBT_UUID));
    572 
    573         bta_sys_sendmsg(p_buf);
    574     }
    575     return;
    576 
    577 }
    578 /*******************************************************************************
    579 **
    580 ** Function         BTA_GATTC_ReadMultiple
    581 **
    582 ** Description      This function is called to read multiple characteristic or
    583 **                  characteristic descriptors.
    584 **
    585 ** Parameters       conn_id - connectino ID.
    586 **                    p_read_multi - pointer to the read multiple parameter.
    587 **
    588 ** Returns          None
    589 **
    590 *******************************************************************************/
    591 void BTA_GATTC_ReadMultiple(UINT16 conn_id, tBTA_GATTC_MULTI *p_read_multi,
    592                             tBTA_GATT_AUTH_REQ auth_req)
    593 {
    594     tBTA_GATTC_API_READ_MULTI  *p_buf;
    595     tBTA_GATTC_ATTR_ID          *p_value;
    596     UINT16      len = (UINT16)(sizeof(tBTA_GATTC_API_READ_MULTI) +
    597                                p_read_multi->num_attr * sizeof(tBTA_GATTC_ATTR_ID));
    598     UINT8       i;
    599 
    600     if ((p_buf = (tBTA_GATTC_API_READ_MULTI *) GKI_getbuf(len)) != NULL)
    601     {
    602         memset(p_buf, 0, len);
    603 
    604         p_buf->hdr.event = BTA_GATTC_API_READ_MULTI_EVT;
    605         p_buf->hdr.layer_specific = conn_id;
    606         p_buf->auth_req = auth_req;
    607 
    608         p_buf->num_attr = p_read_multi->num_attr;
    609 
    610         if (p_buf->num_attr > 0)
    611         {
    612             p_buf->p_id_list = p_value = (tBTA_GATTC_ATTR_ID *)(p_buf + 1);
    613 
    614             for (i = 0; i < p_buf->num_attr; i ++, p_value ++)
    615             {
    616                 memcpy(p_value, &p_read_multi->id_list[i], sizeof(tBTA_GATTC_ATTR_ID));
    617             }
    618         }
    619         bta_sys_sendmsg(p_buf);
    620     }
    621     return;
    622 }
    623 
    624 
    625 /*******************************************************************************
    626 **
    627 ** Function         BTA_GATTC_WriteCharValue
    628 **
    629 ** Description      This function is called to write characteristic value.
    630 **
    631 ** Parameters       conn_id - connection ID.
    632 **                    p_char_id - characteristic ID to write.
    633 **                    write_type - type of write.
    634 **                  len: length of the data to be written.
    635 **                  p_value - the value to be written.
    636 **
    637 ** Returns          None
    638 **
    639 *******************************************************************************/
    640 void BTA_GATTC_WriteCharValue ( UINT16 conn_id,
    641                                 tBTA_GATTC_CHAR_ID *p_char_id,
    642                                 tBTA_GATTC_WRITE_TYPE  write_type,
    643                                 UINT16 len,
    644                                 UINT8 *p_value,
    645                                 tBTA_GATT_AUTH_REQ auth_req)
    646 {
    647     tBTA_GATTC_API_WRITE  *p_buf;
    648 
    649     if ((p_buf = (tBTA_GATTC_API_WRITE *) GKI_getbuf((UINT16)(sizeof(tBTA_GATTC_API_WRITE) + len))) != NULL)
    650     {
    651         memset(p_buf, 0, sizeof(tBTA_GATTC_API_WRITE) + len);
    652 
    653         p_buf->hdr.event = BTA_GATTC_API_WRITE_EVT;
    654         p_buf->hdr.layer_specific = conn_id;
    655         p_buf->auth_req = auth_req;
    656 
    657         memcpy(&p_buf->srvc_id, &p_char_id->srvc_id, sizeof(tBTA_GATT_SRVC_ID));
    658         memcpy(&p_buf->char_id, &p_char_id->char_id, sizeof(tBTA_GATT_ID));
    659 
    660         p_buf->write_type = write_type;
    661         p_buf->len = len;
    662 
    663         if (p_value && len > 0)
    664         {
    665             p_buf->p_value = (UINT8 *)(p_buf + 1);
    666             memcpy(p_buf->p_value, p_value, len);
    667         }
    668 
    669         bta_sys_sendmsg(p_buf);
    670     }
    671     return;
    672 }
    673 /*******************************************************************************
    674 **
    675 ** Function         BTA_GATTC_WriteCharDescr
    676 **
    677 ** Description      This function is called to write characteristic descriptor value.
    678 **
    679 ** Parameters       conn_id - connection ID
    680 **                    p_char_descr_id - characteristic descriptor ID to write.
    681 **                  write_type - write type.
    682 **                  p_value - the value to be written.
    683 **
    684 ** Returns          None
    685 **
    686 *******************************************************************************/
    687 void BTA_GATTC_WriteCharDescr (UINT16 conn_id,
    688                                tBTA_GATTC_CHAR_DESCR_ID *p_char_descr_id,
    689                                tBTA_GATTC_WRITE_TYPE  write_type,
    690                                tBTA_GATT_UNFMT      *p_data,
    691                                tBTA_GATT_AUTH_REQ auth_req)
    692 {
    693     tBTA_GATTC_API_WRITE  *p_buf;
    694     UINT16  len = sizeof(tBTA_GATTC_API_WRITE);
    695 
    696     if (p_data != NULL)
    697         len += p_data->len;
    698 
    699     if ((p_buf = (tBTA_GATTC_API_WRITE *) GKI_getbuf(len)) != NULL)
    700     {
    701         memset(p_buf, 0, len);
    702 
    703         p_buf->hdr.event = BTA_GATTC_API_WRITE_EVT;
    704         p_buf->hdr.layer_specific = conn_id;
    705         p_buf->auth_req = auth_req;
    706 
    707         memcpy(&p_buf->srvc_id, &p_char_descr_id->char_id.srvc_id, sizeof(tBTA_GATT_SRVC_ID));
    708         memcpy(&p_buf->char_id, &p_char_descr_id->char_id.char_id, sizeof(tBTA_GATT_ID));
    709         memcpy(&p_buf->descr_type, &p_char_descr_id->descr_type, sizeof(tBT_UUID));
    710         p_buf->write_type = write_type;
    711 
    712         if (p_data && p_data->len != 0)
    713         {
    714             p_buf->p_value  = (UINT8 *)(p_buf + 1);
    715             p_buf->len      = p_data->len;
    716             /* pack the descr data */
    717             memcpy(p_buf->p_value, p_data->p_value, p_data->len);
    718         }
    719 
    720         bta_sys_sendmsg(p_buf);
    721     }
    722     return;
    723 
    724 }
    725 /*******************************************************************************
    726 **
    727 ** Function         BTA_GATTC_PrepareWrite
    728 **
    729 ** Description      This function is called to prepare write a characteristic value.
    730 **
    731 ** Parameters       conn_id - connection ID.
    732 **                    p_char_id - GATT characteritic ID of the service.
    733 **                  offset - offset of the write value.
    734 **                  len: length of the data to be written.
    735 **                  p_value - the value to be written.
    736 **
    737 ** Returns          None
    738 **
    739 *******************************************************************************/
    740 void BTA_GATTC_PrepareWrite  (UINT16 conn_id, tBTA_GATTC_CHAR_ID *p_char_id,
    741                               UINT16 offset, UINT16 len, UINT8 *p_value,
    742                               tBTA_GATT_AUTH_REQ auth_req)
    743 {
    744     tBTA_GATTC_API_WRITE  *p_buf;
    745 
    746     if ((p_buf = (tBTA_GATTC_API_WRITE *) GKI_getbuf((UINT16)(sizeof(tBTA_GATTC_API_WRITE) + len))) != NULL)
    747     {
    748         memset(p_buf, 0, sizeof(tBTA_GATTC_API_WRITE) + len);
    749 
    750         p_buf->hdr.event = BTA_GATTC_API_WRITE_EVT;
    751         p_buf->hdr.layer_specific = conn_id;
    752         p_buf->auth_req = auth_req;
    753 
    754         memcpy(&p_buf->srvc_id, &p_char_id->srvc_id, sizeof(tBTA_GATT_SRVC_ID));
    755         memcpy(&p_buf->char_id, &p_char_id->char_id, sizeof(tBTA_GATT_ID));
    756 
    757         p_buf->write_type = BTA_GATTC_WRITE_PREPARE;
    758         p_buf->offset   = offset;
    759         p_buf->len = len;
    760 
    761         if (p_value && len > 0)
    762         {
    763             p_buf->p_value = (UINT8 *)(p_buf + 1);
    764             memcpy(p_buf->p_value, p_value, len);
    765         }
    766 
    767         bta_sys_sendmsg(p_buf);
    768     }
    769     return;
    770 
    771 }
    772 /*******************************************************************************
    773 **
    774 ** Function         BTA_GATTC_ExecuteWrite
    775 **
    776 ** Description      This function is called to execute write a prepare write sequence.
    777 **
    778 ** Parameters       conn_id - connection ID.
    779 **                    is_execute - execute or cancel.
    780 **
    781 ** Returns          None
    782 **
    783 *******************************************************************************/
    784 void BTA_GATTC_ExecuteWrite  (UINT16 conn_id, BOOLEAN is_execute)
    785 {
    786     tBTA_GATTC_API_EXEC  *p_buf;
    787 
    788     if ((p_buf = (tBTA_GATTC_API_EXEC *) GKI_getbuf((UINT16)sizeof(tBTA_GATTC_API_EXEC))) != NULL)
    789     {
    790         memset(p_buf, 0, sizeof(tBTA_GATTC_API_EXEC));
    791 
    792         p_buf->hdr.event = BTA_GATTC_API_EXEC_EVT;
    793         p_buf->hdr.layer_specific = conn_id;
    794 
    795         p_buf->is_execute = is_execute;
    796 
    797         bta_sys_sendmsg(p_buf);
    798     }
    799     return;
    800 
    801 }
    802 /*******************************************************************************
    803 **
    804 ** Function         BTA_GATTC_SendIndConfirm
    805 **
    806 ** Description      This function is called to send handle value confirmation.
    807 **
    808 ** Parameters       conn_id - connection ID.
    809 **                    p_char_id - characteristic ID to confirm.
    810 **
    811 ** Returns          None
    812 **
    813 *******************************************************************************/
    814 void BTA_GATTC_SendIndConfirm (UINT16 conn_id, tBTA_GATTC_CHAR_ID *p_char_id)
    815 {
    816     tBTA_GATTC_API_CONFIRM  *p_buf;
    817 
    818     APPL_TRACE_API3("BTA_GATTC_SendIndConfirm conn_id=%d service uuid1=0x%x char uuid=0x%x",
    819                     conn_id, p_char_id->srvc_id.id.uuid.uu.uuid16, p_char_id->char_id.uuid.uu.uuid16);
    820 
    821     if ((p_buf = (tBTA_GATTC_API_CONFIRM *) GKI_getbuf(sizeof(tBTA_GATTC_API_CONFIRM))) != NULL)
    822     {
    823         memset(p_buf, 0, sizeof(tBTA_GATTC_API_CONFIRM));
    824 
    825         p_buf->hdr.event = BTA_GATTC_API_CONFIRM_EVT;
    826         p_buf->hdr.layer_specific = conn_id;
    827 
    828         memcpy(&p_buf->srvc_id, &p_char_id->srvc_id, sizeof(tBTA_GATT_SRVC_ID));
    829         memcpy(&p_buf->char_id, &p_char_id->char_id, sizeof(tBTA_GATT_ID));
    830 
    831         bta_sys_sendmsg(p_buf);
    832     }
    833     return;
    834 
    835 }
    836 
    837 /*******************************************************************************
    838 **
    839 ** Function         BTA_GATTC_RegisterForNotifications
    840 **
    841 ** Description      This function is called to register for notification of a service.
    842 **
    843 ** Parameters       client_if - client interface.
    844 **                  bda - target GATT server.
    845 **                  p_char_id - pointer to GATT characteristic ID.
    846 **
    847 ** Returns          OK if registration succeed, otherwise failed.
    848 **
    849 *******************************************************************************/
    850 tBTA_GATT_STATUS BTA_GATTC_RegisterForNotifications (tBTA_GATTC_IF client_if,
    851                                                      BD_ADDR bda,
    852                                                      tBTA_GATTC_CHAR_ID *p_char_id)
    853 {
    854     tBTA_GATTC_RCB      *p_clreg;
    855     tBTA_GATT_STATUS    status = BTA_GATT_ILLEGAL_PARAMETER;
    856     UINT8               i;
    857 
    858     if (!p_char_id)
    859     {
    860         APPL_TRACE_ERROR0("deregistration failed, unknow char id");
    861         return status;
    862     }
    863 
    864     /* lock other GKI task */
    865     GKI_sched_lock();
    866 
    867     if ((p_clreg = bta_gattc_cl_get_regcb(client_if)) != NULL)
    868     {
    869         for (i = 0; i < BTA_GATTC_NOTIF_REG_MAX; i ++)
    870         {
    871             if ( p_clreg->notif_reg[i].in_use &&
    872                  !memcmp(p_clreg->notif_reg[i].remote_bda, bda, BD_ADDR_LEN) &&
    873                   bta_gattc_charid_compare(&p_clreg->notif_reg[i].char_id, p_char_id))
    874             {
    875                 APPL_TRACE_WARNING0("notification already registered");
    876                 status = BTA_GATT_OK;
    877                 break;
    878             }
    879         }
    880         if (status != BTA_GATT_OK)
    881         {
    882             for (i = 0; i < BTA_GATTC_NOTIF_REG_MAX; i ++)
    883             {
    884                 if (!p_clreg->notif_reg[i].in_use)
    885                 {
    886                     memset((void *)&p_clreg->notif_reg[i], 0, sizeof(tBTA_GATTC_NOTIF_REG));
    887 
    888                     p_clreg->notif_reg[i].in_use = TRUE;
    889                     memcpy(p_clreg->notif_reg[i].remote_bda, bda, BD_ADDR_LEN);
    890 
    891                     p_clreg->notif_reg[i].char_id.srvc_id.is_primary = p_char_id->srvc_id.is_primary;
    892                     bta_gattc_cpygattid(&p_clreg->notif_reg[i].char_id.srvc_id.id, &p_char_id->srvc_id.id);
    893                     bta_gattc_cpygattid(&p_clreg->notif_reg[i].char_id.char_id, &p_char_id->char_id);
    894 
    895                     status = BTA_GATT_OK;
    896                     break;
    897                 }
    898             }
    899             if (i == BTA_GATTC_NOTIF_REG_MAX)
    900             {
    901                 status = BTA_GATT_NO_RESOURCES;
    902                 APPL_TRACE_ERROR0("Max Notification Reached, registration failed.");
    903             }
    904         }
    905     }
    906     else
    907     {
    908         APPL_TRACE_ERROR1("Client_if: %d Not Registered", client_if);
    909     }
    910 
    911     GKI_sched_unlock();
    912 
    913     return status;
    914 }
    915 
    916 /*******************************************************************************
    917 **
    918 ** Function         BTA_GATTC_DeregisterForNotifications
    919 **
    920 ** Description      This function is called to de-register for notification of a service.
    921 **
    922 ** Parameters       client_if - client interface.
    923 **                  bda - target GATT server.
    924 **                  p_char_id - pointer to GATT characteristic ID.
    925 **
    926 ** Returns          OK if deregistration succeed, otherwise failed.
    927 **
    928 *******************************************************************************/
    929 tBTA_GATT_STATUS BTA_GATTC_DeregisterForNotifications (tBTA_GATTC_IF client_if,
    930                                                        BD_ADDR bda,
    931                                                        tBTA_GATTC_CHAR_ID *p_char_id)
    932 {
    933     tBTA_GATTC_RCB      *p_clreg;
    934     tBTA_GATT_STATUS    status = BTA_GATT_ILLEGAL_PARAMETER;
    935     UINT8               i;
    936 
    937     if (!p_char_id)
    938     {
    939         APPL_TRACE_ERROR0("deregistration failed, unknow char id");
    940         return status;
    941     }
    942 
    943     /* lock other GKI task */
    944     GKI_sched_lock();
    945 
    946     if ((p_clreg = bta_gattc_cl_get_regcb(client_if)) != NULL)
    947     {
    948         for (i = 0; i < BTA_GATTC_NOTIF_REG_MAX; i ++)
    949         {
    950             if (p_clreg->notif_reg[i].in_use &&
    951                 !memcmp(p_clreg->notif_reg[i].remote_bda, bda, BD_ADDR_LEN) &&
    952                 bta_gattc_charid_compare(&p_clreg->notif_reg[i].char_id, p_char_id))
    953             {
    954                 APPL_TRACE_DEBUG0("Deregistered.");
    955                 memset(&p_clreg->notif_reg[i], 0, sizeof(tBTA_GATTC_NOTIF_REG));
    956                 status = BTA_GATT_OK;
    957                 break;
    958             }
    959         }
    960         if (i == BTA_GATTC_NOTIF_REG_MAX)
    961         {
    962             status = BTA_GATT_ERROR;
    963 
    964             APPL_TRACE_ERROR0("registration not found");
    965         }
    966     }
    967     else
    968     {
    969         APPL_TRACE_ERROR1("Client_if: %d Not Registered", client_if);
    970     }
    971 
    972     GKI_sched_unlock();
    973 
    974     return status;
    975 }
    976 
    977 /*******************************************************************************
    978 **
    979 ** Function         BTA_GATTC_Refresh
    980 **
    981 ** Description      Refresh the server cache of the remote device
    982 **
    983 ** Parameters       remote_bda: remote device BD address.
    984 **
    985 ** Returns          void
    986 **
    987 *******************************************************************************/
    988 void BTA_GATTC_Refresh(BD_ADDR remote_bda)
    989 {
    990     tBTA_GATTC_API_OPEN  *p_buf;
    991 
    992     if ((p_buf = (tBTA_GATTC_API_OPEN *) GKI_getbuf(sizeof(tBTA_GATTC_API_OPEN))) != NULL)
    993     {
    994         p_buf->hdr.event = BTA_GATTC_API_REFRESH_EVT;
    995 
    996         memcpy(p_buf->remote_bda, remote_bda, BD_ADDR_LEN);
    997 
    998 
    999         bta_sys_sendmsg(p_buf);
   1000     }
   1001     return;
   1002 }
   1003 #endif /* BTA_GATT_INCLUDED */
   1004 
   1005