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