Home | History | Annotate | Download | only in gatt
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2003-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 file contains the GATT client utility function.
     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 "utl.h"
     31 #include "gki.h"
     32 #include "bta_sys.h"
     33 #include "bta_gattc_int.h"
     34 #include "bd.h"
     35 
     36 /*****************************************************************************
     37 **  Constants
     38 *****************************************************************************/
     39 
     40 
     41 static const UINT8  base_uuid[LEN_UUID_128] = {0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80,
     42     0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
     43 
     44 /*******************************************************************************
     45 **
     46 ** Function         bta_gatt_convert_uuid16_to_uuid128
     47 **
     48 ** Description      Convert a 16 bits UUID to be an standard 128 bits one.
     49 **
     50 ** Returns          TRUE if two uuid match; FALSE otherwise.
     51 **
     52 *******************************************************************************/
     53 void bta_gatt_convert_uuid16_to_uuid128(UINT8 uuid_128[LEN_UUID_128], UINT16 uuid_16)
     54 {
     55     UINT8   *p = &uuid_128[LEN_UUID_128 - 4];
     56 
     57     memcpy (uuid_128, base_uuid, LEN_UUID_128);
     58 
     59     UINT16_TO_STREAM(p, uuid_16);
     60 }
     61 /*******************************************************************************
     62 **
     63 ** Function         bta_gattc_uuid_compare
     64 **
     65 ** Description      Compare two UUID to see if they are the same.
     66 **
     67 ** Returns          TRUE if two uuid match; FALSE otherwise.
     68 **
     69 *******************************************************************************/
     70 BOOLEAN bta_gattc_uuid_compare (tBT_UUID src, tBT_UUID tar, BOOLEAN is_precise)
     71 {
     72     UINT8  su[LEN_UUID_128], tu[LEN_UUID_128];
     73     UINT8  *ps, *pt;
     74 
     75     /* any of the UUID is unspecified */
     76     if (src.len == 0 || tar.len == 0)
     77     {
     78         if (is_precise)
     79             return FALSE;
     80         else
     81             return TRUE;
     82     }
     83 
     84     /* If both are 16-bit, we can do a simple compare */
     85     if (src.len == 2 && tar.len == 2)
     86     {
     87         return src.uu.uuid16 == tar.uu.uuid16;
     88     }
     89 
     90     /* One or both of the UUIDs is 128-bit */
     91     if (src.len == LEN_UUID_16)
     92     {
     93         /* convert a 16 bits UUID to 128 bits value */
     94         bta_gatt_convert_uuid16_to_uuid128(su, src.uu.uuid16);
     95         ps = su;
     96     }
     97     else
     98         ps = src.uu.uuid128;
     99 
    100     if (tar.len == LEN_UUID_16)
    101     {
    102         /* convert a 16 bits UUID to 128 bits value */
    103         bta_gatt_convert_uuid16_to_uuid128(tu, tar.uu.uuid16);
    104         pt = tu;
    105     }
    106     else
    107         pt = tar.uu.uuid128;
    108 
    109     return(memcmp(ps, pt, LEN_UUID_128) == 0);
    110 }
    111 
    112 /*******************************************************************************
    113 **
    114 ** Function         bta_gattc_cl_get_regcb
    115 **
    116 ** Description      get registration control block by client interface.
    117 **
    118 ** Returns          pointer to the regcb
    119 **
    120 *******************************************************************************/
    121 tBTA_GATTC_RCB * bta_gattc_cl_get_regcb(UINT8 client_if)
    122 {
    123     UINT8   i = 0;
    124     tBTA_GATTC_RCB  *p_clrcb = &bta_gattc_cb.cl_rcb[0];
    125 
    126     for (i = 0; i < BTA_GATTC_CL_MAX; i ++, p_clrcb ++)
    127     {
    128         if (p_clrcb->in_use &&
    129             p_clrcb->client_if == client_if)
    130             return p_clrcb;
    131     }
    132     return NULL;
    133 }
    134 /*******************************************************************************
    135 **
    136 ** Function         bta_gattc_num_reg_app
    137 **
    138 ** Description      find the number of registered application.
    139 **
    140 ** Returns          pointer to the regcb
    141 **
    142 *******************************************************************************/
    143 UINT8 bta_gattc_num_reg_app(void)
    144 {
    145     UINT8   i = 0, j = 0;
    146 
    147     for (i = 0; i < BTA_GATTC_CL_MAX; i ++)
    148     {
    149         if (bta_gattc_cb.cl_rcb[i].in_use)
    150             j ++;
    151     }
    152     return j;
    153 }
    154 /*******************************************************************************
    155 **
    156 ** Function         bta_gattc_find_clcb_by_cif
    157 **
    158 ** Description      get clcb by client interface and remote bd adddress
    159 **
    160 ** Returns          pointer to the clcb
    161 **
    162 *******************************************************************************/
    163 tBTA_GATTC_CLCB * bta_gattc_find_clcb_by_cif (UINT8 client_if, BD_ADDR remote_bda)
    164 {
    165     tBTA_GATTC_CLCB *p_clcb = &bta_gattc_cb.clcb[0];
    166     UINT8   i;
    167 
    168     for (i = 0; i < BTA_GATTC_CLCB_MAX; i ++, p_clcb ++)
    169     {
    170         if (p_clcb->in_use &&
    171             p_clcb->p_rcb->client_if == client_if &&
    172             p_clcb->p_srcb &&
    173             bdcmp(p_clcb->p_srcb->server_bda, remote_bda) == 0)
    174             return p_clcb;
    175     }
    176     return NULL;
    177 }
    178 /*******************************************************************************
    179 **
    180 ** Function         bta_gattc_find_clcb_by_conn_id
    181 **
    182 ** Description      get clcb by connection ID
    183 **
    184 ** Returns          pointer to the clcb
    185 **
    186 *******************************************************************************/
    187 tBTA_GATTC_CLCB * bta_gattc_find_clcb_by_conn_id (UINT16 conn_id)
    188 {
    189     tBTA_GATTC_CLCB *p_clcb = &bta_gattc_cb.clcb[0];
    190     UINT8 i;
    191 
    192     for (i = 0; i < BTA_GATTC_CLCB_MAX; i ++, p_clcb ++)
    193     {
    194         if (p_clcb->in_use &&
    195             p_clcb->bta_conn_id == conn_id)
    196             return p_clcb;
    197     }
    198     return NULL;
    199 }
    200 
    201 /*******************************************************************************
    202 **
    203 ** Function         bta_gattc_clcb_alloc
    204 **
    205 ** Description      allocate CLCB
    206 **
    207 ** Returns          pointer to the clcb
    208 **
    209 *******************************************************************************/
    210 tBTA_GATTC_CLCB * bta_gattc_clcb_alloc(tBTA_GATTC_IF client_if, BD_ADDR remote_bda)
    211 {
    212     UINT8               i_clcb = 0;
    213     tBTA_GATTC_CLCB     *p_clcb = NULL;
    214 
    215     for (i_clcb = 0; i_clcb < BTA_GATTC_CLCB_MAX; i_clcb++)
    216     {
    217         if (!bta_gattc_cb.clcb[i_clcb].in_use)
    218         {
    219 #if BTA_GATT_DEBUG == TRUE
    220             APPL_TRACE_DEBUG1("bta_gattc_clcb_alloc: found clcb[%d] available",i_clcb);
    221 #endif
    222             p_clcb                  = &bta_gattc_cb.clcb[i_clcb];
    223             p_clcb->in_use          = TRUE;
    224             p_clcb->status          = BTA_GATT_OK;
    225             bdcpy(p_clcb->bda, remote_bda);
    226 
    227             p_clcb->p_rcb = bta_gattc_cl_get_regcb(client_if);
    228 
    229             if ((p_clcb->p_srcb = bta_gattc_find_srcb(remote_bda)) == NULL)
    230                 p_clcb->p_srcb      = bta_gattc_srcb_alloc(remote_bda);
    231 
    232             if (p_clcb->p_rcb != NULL && p_clcb->p_srcb != NULL)
    233             {
    234                 p_clcb->p_srcb->num_clcb ++;
    235                 p_clcb->p_rcb->num_clcb ++;
    236             }
    237             else
    238             {
    239                 /* release this clcb if clcb or srcb allocation failed */
    240                 p_clcb->in_use = FALSE;
    241                 p_clcb = NULL;
    242             }
    243             break;
    244         }
    245     }
    246     return p_clcb;
    247 }
    248 /*******************************************************************************
    249 **
    250 ** Function         bta_gattc_find_alloc_clcb
    251 **
    252 ** Description      find or allocate CLCB if not found.
    253 **
    254 ** Returns          pointer to the clcb
    255 **
    256 *******************************************************************************/
    257 tBTA_GATTC_CLCB *bta_gattc_find_alloc_clcb(tBTA_GATTC_IF client_if, BD_ADDR remote_bda)
    258 {
    259     tBTA_GATTC_CLCB *p_clcb ;
    260 
    261     if ((p_clcb = bta_gattc_find_clcb_by_cif(client_if, remote_bda)) == NULL)
    262     {
    263         p_clcb = bta_gattc_clcb_alloc(client_if, remote_bda);
    264     }
    265     return p_clcb;
    266 }
    267 
    268 /*******************************************************************************
    269 **
    270 ** Function         bta_gattc_clcb_dealloc
    271 **
    272 ** Description      Deallocte a clcb
    273 **
    274 ** Returns          pointer to the clcb
    275 **
    276 *******************************************************************************/
    277 void bta_gattc_clcb_dealloc(tBTA_GATTC_CLCB *p_clcb)
    278 {
    279     tBTA_GATTC_SERV     *p_srcb = p_clcb->p_srcb;
    280 
    281     if (p_clcb)
    282     {
    283         if (p_srcb->num_clcb)
    284             p_srcb->num_clcb --;
    285 
    286         if (p_clcb->p_rcb->num_clcb)
    287             p_clcb->p_rcb->num_clcb --;
    288         if ( p_srcb->num_clcb == 0)
    289         {
    290             p_srcb->connected = FALSE;
    291             p_srcb->state = BTA_GATTC_SERV_IDLE;
    292         }
    293 
    294         utl_freebuf((void **)&p_clcb->p_q_cmd);
    295 
    296         memset(p_clcb, 0, sizeof(tBTA_GATTC_CLCB));
    297     }
    298     else
    299     {
    300         APPL_TRACE_ERROR0("bta_gattc_clcb_dealloc p_clcb=NULL");
    301     }
    302 }
    303 
    304 /*******************************************************************************
    305 **
    306 ** Function         bta_gattc_find_srcb
    307 **
    308 ** Description      find server cache by remote bd address currently in use
    309 **
    310 ** Returns          pointer to the server cache.
    311 **
    312 *******************************************************************************/
    313 tBTA_GATTC_SERV * bta_gattc_find_srcb(BD_ADDR bda)
    314 {
    315     tBTA_GATTC_SERV *p_srcb = &bta_gattc_cb.known_server[0];
    316     UINT8   i;
    317 
    318     for (i = 0; i < BTA_GATTC_KNOWN_SR_MAX; i ++, p_srcb ++)
    319     {
    320         if (p_srcb->in_use && bdcmp(p_srcb->server_bda, bda) == 0)
    321             return p_srcb;
    322     }
    323     return NULL;
    324 }
    325 
    326 /*******************************************************************************
    327 **
    328 ** Function         bta_gattc_find_srvr_cache
    329 **
    330 ** Description      find server cache by remote bd address
    331 **
    332 ** Returns          pointer to the server cache.
    333 **
    334 *******************************************************************************/
    335 tBTA_GATTC_SERV * bta_gattc_find_srvr_cache(BD_ADDR bda)
    336 {
    337     tBTA_GATTC_SERV *p_srcb = &bta_gattc_cb.known_server[0];
    338     UINT8   i;
    339 
    340     for (i = 0; i < BTA_GATTC_KNOWN_SR_MAX; i ++, p_srcb ++)
    341     {
    342         if (bdcmp(p_srcb->server_bda, bda) == 0)
    343             return p_srcb;
    344     }
    345     return NULL;
    346 }
    347 /*******************************************************************************
    348 **
    349 ** Function         bta_gattc_find_scb_by_cid
    350 **
    351 ** Description      find server control block by connection ID
    352 **
    353 ** Returns          pointer to the server cache.
    354 **
    355 *******************************************************************************/
    356 tBTA_GATTC_SERV * bta_gattc_find_scb_by_cid (UINT16 conn_id)
    357 {
    358     tBTA_GATTC_CLCB *p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
    359 
    360     if (p_clcb)
    361         return p_clcb->p_srcb;
    362     else
    363         return NULL;
    364 }
    365 /*******************************************************************************
    366 **
    367 ** Function         bta_gattc_srcb_alloc
    368 **
    369 ** Description      allocate server cache control block
    370 **
    371 ** Returns          pointer to the server cache.
    372 **
    373 *******************************************************************************/
    374 tBTA_GATTC_SERV * bta_gattc_srcb_alloc(BD_ADDR bda)
    375 {
    376     tBTA_GATTC_SERV *p_tcb = &bta_gattc_cb.known_server[0],
    377                              *p_recycle = NULL;
    378     BOOLEAN         found = FALSE;
    379     UINT8           i;
    380 
    381     for (i = 0; i < BTA_GATTC_KNOWN_SR_MAX; i ++, p_tcb ++)
    382     {
    383         if (!p_tcb->in_use)
    384         {
    385             found = TRUE;
    386             break;
    387         }
    388         else if (!p_tcb->connected)
    389         {
    390             p_recycle = p_tcb;
    391         }
    392     }
    393 
    394     /* if not found, try to recycle one known device */
    395     if (!found && !p_recycle)
    396         p_tcb = NULL;
    397     else if (p_recycle)
    398         p_tcb = p_recycle;
    399 
    400     if (p_tcb != NULL)
    401     {
    402         while (p_tcb->cache_buffer.p_first)
    403             GKI_freebuf (GKI_dequeue (&p_tcb->cache_buffer));
    404 
    405         utl_freebuf((void **)&p_tcb->p_srvc_list);
    406         memset(p_tcb, 0 , sizeof(tBTA_GATTC_SERV));
    407 
    408         p_tcb->in_use = TRUE;
    409         bdcpy(p_tcb->server_bda, bda);
    410     }
    411     return p_tcb;
    412 }
    413 /*******************************************************************************
    414 **
    415 ** Function         bta_gattc_enqueue
    416 **
    417 ** Description      enqueue a client request in clcb.
    418 **
    419 ** Returns          success or failure.
    420 **
    421 *******************************************************************************/
    422 BOOLEAN bta_gattc_enqueue(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
    423 {
    424     BOOLEAN in_q = FALSE;
    425 
    426     if (p_clcb->p_q_cmd == NULL)
    427     {
    428         p_clcb->p_q_cmd = (tBTA_GATTC_DATA *)GKI_getbuf(sizeof(tBTA_GATTC_DATA));
    429 
    430         if (p_data)
    431             memcpy(p_clcb->p_q_cmd, p_data, sizeof(tBTA_GATTC_DATA));
    432 
    433         in_q = TRUE;
    434     }
    435     else
    436     {
    437         APPL_TRACE_ERROR0("already has a pending command!!");
    438         /* skip the callback now. ----- need to send callback ? */
    439     }
    440     return in_q;
    441 }
    442 /*******************************************************************************
    443 **
    444 ** Function         bta_gattc_pack_attr_uuid
    445 **
    446 ** Description      pack UUID into a stream.
    447 **
    448 ** Returns
    449 **
    450 *******************************************************************************/
    451 void bta_gattc_pack_attr_uuid(tBTA_GATTC_CACHE_ATTR   *p_attr, tBT_UUID *p_uuid)
    452 {
    453     UINT8 *pp = (UINT8 *)p_attr->p_uuid;
    454 
    455     memset(p_uuid, 0, sizeof(tBT_UUID));
    456 
    457     p_uuid->len = p_attr->uuid_len;
    458 
    459     if (p_attr->uuid_len == LEN_UUID_16)
    460     {
    461         STREAM_TO_UINT16(p_uuid->uu.uuid16, pp);
    462     }
    463     else
    464     {
    465         memcpy(p_uuid->uu.uuid128, pp, LEN_UUID_128);
    466     }
    467 
    468     return;
    469 }
    470 /*******************************************************************************
    471 **
    472 ** Function         bta_gattc_cpygattid
    473 **
    474 ** Description      copy two tBTA_GATT_ID value
    475 **
    476 ** Returns
    477 **
    478 *******************************************************************************/
    479 void bta_gattc_cpygattid(tBTA_GATT_ID *p_des, tBTA_GATT_ID *p_src)
    480 {
    481     memset ((void *)p_des, 0, sizeof(tBTA_GATT_ID));
    482 
    483     p_des->inst_id = p_src->inst_id;
    484 
    485     p_des->uuid.len = p_src->uuid.len;
    486 
    487     if (p_des->uuid.len == LEN_UUID_16)
    488     {
    489         p_des->uuid.uu.uuid16 = p_src->uuid.uu.uuid16;
    490     }
    491     else if (p_des->uuid.len == LEN_UUID_128)
    492     {
    493         memcpy(p_des->uuid.uu.uuid128, p_src->uuid.uu.uuid128, LEN_UUID_128);
    494     }
    495 }
    496 /*******************************************************************************
    497 **
    498 ** Function         bta_gattc_gattid_compare
    499 **
    500 ** Description      compare two tBTA_GATT_ID type of pointer
    501 **
    502 ** Returns
    503 **
    504 *******************************************************************************/
    505 BOOLEAN bta_gattc_gattid_compare(tBTA_GATT_ID *p_src, tBTA_GATT_ID *p_tar)
    506 {
    507     if (p_src->inst_id == p_tar->inst_id &&
    508         bta_gattc_uuid_compare (p_src->uuid, p_tar->uuid, TRUE ))
    509         return TRUE;
    510     else
    511         return FALSE;
    512 
    513 }
    514 /*******************************************************************************
    515 **
    516 ** Function         bta_gattc_srvcid_compare
    517 **
    518 ** Description      compare two tBTA_GATT_SRVC_ID type of pointer
    519 **
    520 ** Returns
    521 **
    522 *******************************************************************************/
    523 BOOLEAN bta_gattc_srvcid_compare(tBTA_GATT_SRVC_ID *p_src, tBTA_GATT_SRVC_ID *p_tar)
    524 {
    525     if (p_src->is_primary == p_tar->is_primary &&
    526         bta_gattc_gattid_compare (&p_src->id, &p_tar->id))
    527         return TRUE;
    528     else
    529         return FALSE;
    530 }
    531 /*******************************************************************************
    532 **
    533 ** Function         bta_gattc_charid_compare
    534 **
    535 ** Description      compare two tBTA_GATTC_CHAR_ID type of pointer
    536 **
    537 ** Returns
    538 **
    539 *******************************************************************************/
    540 BOOLEAN bta_gattc_charid_compare(tBTA_GATTC_CHAR_ID *p_src, tBTA_GATTC_CHAR_ID *p_tar)
    541 {
    542     if (bta_gattc_gattid_compare (&p_src->char_id, &p_tar->char_id) &&
    543         bta_gattc_srvcid_compare (&p_src->srvc_id, &p_tar->srvc_id))
    544         return TRUE;
    545     else
    546         return FALSE;
    547 }
    548 
    549 /*******************************************************************************
    550 **
    551 ** Function         bta_gattc_check_notif_registry
    552 **
    553 ** Description      check if the service notificaition has been registered.
    554 **
    555 ** Returns
    556 **
    557 *******************************************************************************/
    558 BOOLEAN bta_gattc_check_notif_registry(tBTA_GATTC_RCB  *p_clreg, tBTA_GATTC_SERV *p_srcb,
    559                                        tBTA_GATTC_NOTIFY  *p_notify)
    560 {
    561     UINT8           i;
    562 
    563     for (i = 0 ; i < BTA_GATTC_NOTIF_REG_MAX; i ++)
    564     {
    565         if (p_clreg->notif_reg[i].in_use &&
    566             bdcmp(p_clreg->notif_reg[i].remote_bda, p_srcb->server_bda) == 0 &&
    567             bta_gattc_charid_compare (&p_clreg->notif_reg[i].char_id, &p_notify->char_id))
    568         {
    569             APPL_TRACE_DEBUG0("Notification registered!");
    570             return TRUE;
    571         }
    572     }
    573     return FALSE;
    574 
    575 }
    576 /*******************************************************************************
    577 **
    578 ** Function         bta_gattc_clear_notif_registration
    579 **
    580 ** Description      clear up the notification registration information by BD_ADDR.
    581 **
    582 ** Returns          None.
    583 **
    584 *******************************************************************************/
    585 void bta_gattc_clear_notif_registration(UINT16 conn_id)
    586 {
    587     BD_ADDR             remote_bda;
    588     tBTA_GATTC_IF       gatt_if;
    589     tBTA_GATTC_RCB      *p_clrcb ;
    590     UINT8       i;
    591 
    592     if (GATT_GetConnectionInfor(conn_id, &gatt_if, remote_bda))
    593     {
    594         if ((p_clrcb = bta_gattc_cl_get_regcb(gatt_if)) != NULL)
    595         {
    596             for (i = 0 ; i < BTA_GATTC_NOTIF_REG_MAX; i ++)
    597             {
    598                 if (p_clrcb->notif_reg[i].in_use && !bdcmp(p_clrcb->notif_reg[i].remote_bda, remote_bda))
    599                     memset(&p_clrcb->notif_reg[i], 0, sizeof(tBTA_GATTC_NOTIF_REG));
    600             }
    601         }
    602     }
    603     else
    604     {
    605         APPL_TRACE_ERROR0("can not clear indication/notif registration for unknown app");
    606     }
    607     return;
    608 }
    609 
    610 /*******************************************************************************
    611 **
    612 ** Function         bta_gattc_pack_cb_data
    613 **
    614 ** Description      pack the data from read response into callback data structure.
    615 **
    616 ** Returns
    617 **
    618 *******************************************************************************/
    619 tBTA_GATT_STATUS bta_gattc_pack_read_cb_data(tBTA_GATTC_SERV *p_srcb, tBT_UUID descr_uuid,
    620                                              tGATT_VALUE *p_attr, tBTA_GATT_READ_VAL *p_value)
    621 {
    622     UINT8                   i = 0, *pp = p_attr->value;
    623     tBT_UUID                uuid = {LEN_UUID_16, {GATT_UUID_CHAR_AGG_FORMAT}};
    624     UINT16                  handle;
    625     tBTA_GATT_STATUS        status = BTA_GATT_OK;
    626 
    627     /* GATT_UUID_CHAR_AGG_FORMAT */
    628     if (bta_gattc_uuid_compare (uuid, descr_uuid, TRUE))
    629     {
    630         while (p_attr->len >= 2 && i < BTA_GATTC_MULTI_MAX)
    631         {
    632             STREAM_TO_UINT16(handle, pp);
    633 
    634             if (bta_gattc_handle2id(p_srcb,
    635                                     handle,
    636                                     &p_value->aggre_value.pre_format[i].char_id.srvc_id,
    637                                     &p_value->aggre_value.pre_format[i].char_id.char_id,
    638                                     &p_value->aggre_value.pre_format[i].descr_type) == FALSE)
    639             {
    640                 status = BTA_GATT_INTERNAL_ERROR;
    641                 APPL_TRACE_ERROR1("can not map to GATT ID. handle = 0x%04x", handle);
    642                 break;
    643             }
    644             i ++;
    645             p_attr->len -= 2;
    646         }
    647         p_value->aggre_value.num_pres_fmt = i;
    648     }
    649     else
    650     {
    651         /* all others, take as raw format */
    652         p_value->unformat.len = p_attr->len;
    653         p_value->unformat.p_value = p_attr->value;
    654     }
    655     return status;
    656 }
    657 /*******************************************************************************
    658 **
    659 ** Function         bta_gattc_mark_bg_conn
    660 **
    661 ** Description      mark background connection status when a bg connection is initiated
    662 **                  or terminated.
    663 **
    664 ** Returns          TRUE if success; FALSE otherwise.
    665 **
    666 *******************************************************************************/
    667 BOOLEAN bta_gattc_mark_bg_conn (tBTA_GATTC_IF client_if,  BD_ADDR_PTR remote_bda_ptr,
    668                                 BOOLEAN add, BOOLEAN is_listen)
    669 {
    670     tBTA_GATTC_BG_TCK   *p_bg_tck = &bta_gattc_cb.bg_track[0];
    671     UINT8   i = 0;
    672     tBTA_GATTC_CIF_MASK  *p_cif_mask;
    673 
    674     for (i = 0; i < BTA_GATTC_KNOWN_SR_MAX; i ++, p_bg_tck ++)
    675     {
    676         if (p_bg_tck->in_use &&
    677             ((remote_bda_ptr != NULL && bdcmp(p_bg_tck->remote_bda, remote_bda_ptr) == 0) ||
    678             (remote_bda_ptr == NULL && bdcmp(p_bg_tck->remote_bda, bd_addr_null) == 0)))
    679         {
    680              p_cif_mask = is_listen ? &p_bg_tck->cif_adv_mask : &p_bg_tck->cif_mask;
    681 
    682             if (add)
    683                 /* mask on the cif bit */
    684                 *p_cif_mask |= (1 <<(client_if - 1));
    685             else
    686             {
    687                 if (client_if != 0)
    688                     *p_cif_mask &= (~(1 <<(client_if - 1)));
    689                 else
    690                     *p_cif_mask = 0;
    691             }
    692             /* no BG connection for this device, make it available */
    693             if (p_bg_tck->cif_mask == 0 && p_bg_tck->cif_adv_mask == 0)
    694             {
    695                 memset(p_bg_tck, 0, sizeof(tBTA_GATTC_BG_TCK));
    696             }
    697             return TRUE;
    698         }
    699     }
    700     if (!add)
    701     {
    702         APPL_TRACE_ERROR0("Do not find the bg connection mask for the remote device");
    703         return FALSE;
    704     }
    705     else /* adding a new device mask */
    706     {
    707         for (i = 0, p_bg_tck = &bta_gattc_cb.bg_track[0];
    708              i < BTA_GATTC_KNOWN_SR_MAX; i ++, p_bg_tck ++)
    709         {
    710             if (!p_bg_tck->in_use)
    711             {
    712                 p_bg_tck->in_use = TRUE;
    713                 if (remote_bda_ptr)
    714                     bdcpy(p_bg_tck->remote_bda, remote_bda_ptr);
    715                 else
    716                     bdcpy(p_bg_tck->remote_bda, bd_addr_null);
    717 
    718                 p_cif_mask = is_listen ? &p_bg_tck->cif_adv_mask : &p_bg_tck->cif_mask;
    719 
    720                 *p_cif_mask = (1 <<(client_if - 1));
    721                 return TRUE;
    722             }
    723         }
    724         APPL_TRACE_ERROR0("no available space to mark the bg connection status");
    725         return FALSE;
    726     }
    727 }
    728 /*******************************************************************************
    729 **
    730 ** Function         bta_gattc_check_bg_conn
    731 **
    732 ** Description      check if this is a background connection background connection.
    733 **
    734 ** Returns          TRUE if success; FALSE otherwise.
    735 **
    736 *******************************************************************************/
    737 BOOLEAN bta_gattc_check_bg_conn (tBTA_GATTC_IF client_if,  BD_ADDR remote_bda, UINT8 role)
    738 {
    739     tBTA_GATTC_BG_TCK   *p_bg_tck = &bta_gattc_cb.bg_track[0];
    740     UINT8       i = 0;
    741     BOOLEAN     is_bg_conn = FALSE;
    742 
    743     for (i = 0; i < BTA_GATTC_KNOWN_SR_MAX && !is_bg_conn; i ++, p_bg_tck ++)
    744     {
    745         if (p_bg_tck->in_use &&
    746             (bdcmp(p_bg_tck->remote_bda, remote_bda) == 0 ||
    747              bdcmp(p_bg_tck->remote_bda, bd_addr_null) == 0))
    748         {
    749             if (((p_bg_tck->cif_mask &(1 <<(client_if - 1))) != 0) &&
    750                 role == HCI_ROLE_MASTER)
    751                 is_bg_conn = TRUE;
    752 
    753             if (((p_bg_tck->cif_adv_mask &(1 <<(client_if - 1))) != 0) &&
    754                 role == HCI_ROLE_SLAVE)
    755                 is_bg_conn = TRUE;
    756         }
    757     }
    758     return is_bg_conn;
    759 }
    760 /*******************************************************************************
    761 **
    762 ** Function         bta_gattc_send_open_cback
    763 **
    764 ** Description      send open callback
    765 **
    766 ** Returns
    767 **
    768 *******************************************************************************/
    769 void bta_gattc_send_open_cback( tBTA_GATTC_RCB *p_clreg, tBTA_GATT_STATUS status,
    770                                 BD_ADDR remote_bda, UINT16 conn_id)
    771 {
    772     tBTA_GATTC      cb_data;
    773 
    774     if (p_clreg->p_cback)
    775     {
    776         memset(&cb_data, 0, sizeof(tBTA_GATTC));
    777 
    778         cb_data.open.status = status;
    779         cb_data.open.client_if = p_clreg->client_if;
    780         cb_data.open.conn_id = conn_id;
    781         bdcpy(cb_data.open.remote_bda, remote_bda);
    782 
    783         (*p_clreg->p_cback)(BTA_GATTC_OPEN_EVT, &cb_data);
    784     }
    785 }
    786 /*******************************************************************************
    787 **
    788 ** Function         bta_gattc_conn_alloc
    789 **
    790 ** Description      allocate connection tracking spot
    791 **
    792 ** Returns          pointer to the clcb
    793 **
    794 *******************************************************************************/
    795 tBTA_GATTC_CONN * bta_gattc_conn_alloc(BD_ADDR remote_bda)
    796 {
    797     UINT8               i_conn = 0;
    798     tBTA_GATTC_CONN     *p_conn = &bta_gattc_cb.conn_track[0];
    799 
    800     for (i_conn = 0; i_conn < BTA_GATTC_CONN_MAX; i_conn++, p_conn ++)
    801     {
    802         if (!p_conn->in_use)
    803         {
    804 #if BTA_GATT_DEBUG == TRUE
    805             APPL_TRACE_DEBUG1("bta_gattc_conn_alloc: found conn_track[%d] available",i_conn);
    806 #endif
    807             p_conn->in_use          = TRUE;
    808             bdcpy(p_conn->remote_bda, remote_bda);
    809             return p_conn;
    810         }
    811     }
    812     return NULL;
    813 }
    814 
    815 /*******************************************************************************
    816 **
    817 ** Function         bta_gattc_conn_find
    818 **
    819 ** Description      allocate connection tracking spot
    820 **
    821 ** Returns          pointer to the clcb
    822 **
    823 *******************************************************************************/
    824 tBTA_GATTC_CONN * bta_gattc_conn_find(BD_ADDR remote_bda)
    825 {
    826     UINT8               i_conn = 0;
    827     tBTA_GATTC_CONN     *p_conn = &bta_gattc_cb.conn_track[0];
    828 
    829     for (i_conn = 0; i_conn < BTA_GATTC_CONN_MAX; i_conn++, p_conn ++)
    830     {
    831         if (p_conn->in_use && bdcmp(remote_bda, p_conn->remote_bda) == 0)
    832         {
    833 #if BTA_GATT_DEBUG == TRUE
    834             APPL_TRACE_DEBUG1("bta_gattc_conn_find: found conn_track[%d] matched",i_conn);
    835 #endif
    836             return p_conn;
    837         }
    838     }
    839     return NULL;
    840 }
    841 
    842 
    843 /*******************************************************************************
    844 **
    845 ** Function         bta_gattc_conn_find_alloc
    846 **
    847 ** Description      find or allocate connection tracking spot
    848 **
    849 ** Returns          pointer to the clcb
    850 **
    851 *******************************************************************************/
    852 tBTA_GATTC_CONN * bta_gattc_conn_find_alloc(BD_ADDR remote_bda)
    853 {
    854     tBTA_GATTC_CONN     *p_conn = bta_gattc_conn_find (remote_bda);
    855 
    856     if (p_conn == NULL)
    857     {
    858         p_conn = bta_gattc_conn_alloc(remote_bda);
    859     }
    860     return p_conn;
    861 }
    862 
    863 /*******************************************************************************
    864 **
    865 ** Function         bta_gattc_conn_dealloc
    866 **
    867 ** Description      de-allocate connection tracking spot
    868 **
    869 ** Returns          pointer to the clcb
    870 **
    871 *******************************************************************************/
    872 BOOLEAN bta_gattc_conn_dealloc(BD_ADDR remote_bda)
    873 {
    874     tBTA_GATTC_CONN     *p_conn = bta_gattc_conn_find (remote_bda);
    875 
    876     if (p_conn != NULL)
    877     {
    878         p_conn->in_use = FALSE;
    879         memset(p_conn->remote_bda, 0, BD_ADDR_LEN);
    880         return TRUE;
    881     }
    882     return FALSE;
    883 }
    884 
    885 #endif /* BTA_GATT_INCLUDED */
    886