Home | History | Annotate | Download | only in gatt
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2009-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 GATT utility functions
     22  *
     23  ******************************************************************************/
     24 #include "bt_target.h"
     25 #include "bt_utils.h"
     26 
     27 #if BLE_INCLUDED == TRUE
     28     #include <string.h>
     29     #include "stdio.h"
     30     #include "bt_common.h"
     31 
     32     #include "l2cdefs.h"
     33     #include "gatt_int.h"
     34     #include "gatt_api.h"
     35     #include "gattdefs.h"
     36     #include "sdp_api.h"
     37     #include "btm_int.h"
     38 /* check if [x, y] and [a, b] have overlapping range */
     39     #define GATT_VALIDATE_HANDLE_RANGE(x, y, a, b)   (y >= a && x <= b)
     40 
     41     #define GATT_GET_NEXT_VALID_HANDLE(x)    (((x)/10 + 1) * 10)
     42 
     43 const char * const op_code_name[] =
     44 {
     45     "UNKNOWN",
     46     "ATT_RSP_ERROR",
     47     "ATT_REQ_MTU",
     48     "ATT_RSP_MTU",
     49     "ATT_REQ_READ_INFO",
     50     "ATT_RSP_READ_INFO",
     51     "ATT_REQ_FIND_TYPE_VALUE",
     52     "ATT_RSP_FIND_TYPE_VALUE",
     53     "ATT_REQ_READ_BY_TYPE",
     54     "ATT_RSP_READ_BY_TYPE",
     55     "ATT_REQ_READ",
     56     "ATT_RSP_READ",
     57     "ATT_REQ_READ_BLOB",
     58     "ATT_RSP_READ_BLOB",
     59     "GATT_REQ_READ_MULTI",
     60     "GATT_RSP_READ_MULTI",
     61     "GATT_REQ_READ_BY_GRP_TYPE",
     62     "GATT_RSP_READ_BY_GRP_TYPE",
     63     "ATT_REQ_WRITE",
     64     "ATT_RSP_WRITE",
     65     "ATT_CMD_WRITE",
     66     "ATT_SIGN_CMD_WRITE",
     67     "ATT_REQ_PREPARE_WRITE",
     68     "ATT_RSP_PREPARE_WRITE",
     69     "ATT_REQ_EXEC_WRITE",
     70     "ATT_RSP_EXEC_WRITE",
     71     "Reserved",
     72     "ATT_HANDLE_VALUE_NOTIF",
     73     "Reserved",
     74     "ATT_HANDLE_VALUE_IND",
     75     "ATT_HANDLE_VALUE_CONF",
     76     "ATT_OP_CODE_MAX"
     77 };
     78 
     79 static const UINT8  base_uuid[LEN_UUID_128] = {0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80,
     80     0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
     81 
     82 extern fixed_queue_t *btu_general_alarm_queue;
     83 
     84 /*******************************************************************************
     85 **
     86 ** Function         gatt_free_pending_ind
     87 **
     88 ** Description    Free all pending indications
     89 **
     90 ** Returns       None
     91 **
     92 *******************************************************************************/
     93 void gatt_free_pending_ind(tGATT_TCB *p_tcb)
     94 {
     95     GATT_TRACE_DEBUG("%s", __func__);
     96 
     97     if (p_tcb->pending_ind_q == NULL)
     98         return;
     99 
    100     /* release all queued indications */
    101     while (!fixed_queue_is_empty(p_tcb->pending_ind_q))
    102         osi_free(fixed_queue_try_dequeue(p_tcb->pending_ind_q));
    103     fixed_queue_free(p_tcb->pending_ind_q, NULL);
    104     p_tcb->pending_ind_q = NULL;
    105 }
    106 
    107 /*******************************************************************************
    108 **
    109 ** Function         gatt_free_pending_enc_queue
    110 **
    111 ** Description       Free all buffers in pending encyption queue
    112 **
    113 ** Returns       None
    114 **
    115 *******************************************************************************/
    116 void gatt_free_pending_enc_queue(tGATT_TCB *p_tcb)
    117 {
    118     GATT_TRACE_DEBUG("%s", __func__);
    119 
    120     if (p_tcb->pending_enc_clcb == NULL)
    121         return;
    122 
    123     /* release all queued indications */
    124     while (!fixed_queue_is_empty(p_tcb->pending_enc_clcb))
    125         osi_free(fixed_queue_try_dequeue(p_tcb->pending_enc_clcb));
    126     fixed_queue_free(p_tcb->pending_enc_clcb, NULL);
    127     p_tcb->pending_enc_clcb = NULL;
    128 }
    129 
    130 /*******************************************************************************
    131 **
    132 ** Function         gatt_delete_dev_from_srv_chg_clt_list
    133 **
    134 ** Description    Delete a device from the service changed client lit
    135 **
    136 ** Returns       None
    137 **
    138 *******************************************************************************/
    139 void gatt_delete_dev_from_srv_chg_clt_list(BD_ADDR bd_addr)
    140 {
    141     GATT_TRACE_DEBUG("gatt_delete_dev_from_srv_chg_clt_list");
    142 
    143     tGATTS_SRV_CHG *p_buf = gatt_is_bda_in_the_srv_chg_clt_list(bd_addr);
    144     if (p_buf != NULL)
    145     {
    146         if (gatt_cb.cb_info.p_srv_chg_callback)
    147         {
    148             /* delete from NV */
    149             tGATTS_SRV_CHG_REQ req;
    150             memcpy(req.srv_chg.bda, bd_addr, BD_ADDR_LEN);
    151             (*gatt_cb.cb_info.p_srv_chg_callback)(GATTS_SRV_CHG_CMD_REMOVE_CLIENT,&req, NULL);
    152         }
    153         osi_free(fixed_queue_try_remove_from_queue(gatt_cb.srv_chg_clt_q,
    154                                                       p_buf));
    155     }
    156 }
    157 
    158 /*******************************************************************************
    159 **
    160 ** Function         gatt_set_srv_chg
    161 **
    162 ** Description      Set the service changed flag to TRUE
    163 **
    164 ** Returns        None
    165 **
    166 *******************************************************************************/
    167 void gatt_set_srv_chg(void)
    168 {
    169     GATT_TRACE_DEBUG ("gatt_set_srv_chg");
    170 
    171     if (fixed_queue_is_empty(gatt_cb.srv_chg_clt_q))
    172         return;
    173 
    174     list_t *list = fixed_queue_get_list(gatt_cb.srv_chg_clt_q);
    175     for (const list_node_t *node = list_begin(list); node != list_end(list);
    176          node = list_next(node)) {
    177         GATT_TRACE_DEBUG ("found a srv_chg clt");
    178 
    179         tGATTS_SRV_CHG *p_buf = (tGATTS_SRV_CHG *)list_node(node);
    180         if (!p_buf->srv_changed)
    181         {
    182             GATT_TRACE_DEBUG("set srv_changed to TRUE");
    183             p_buf->srv_changed = TRUE;
    184             tGATTS_SRV_CHG_REQ req;
    185             memcpy(&req.srv_chg, p_buf, sizeof(tGATTS_SRV_CHG));
    186             if (gatt_cb.cb_info.p_srv_chg_callback)
    187                 (*gatt_cb.cb_info.p_srv_chg_callback)(GATTS_SRV_CHG_CMD_UPDATE_CLIENT,&req, NULL);
    188         }
    189     }
    190 }
    191 
    192 /*******************************************************************************
    193 **
    194 ** Function         gatt_sr_is_new_srv_chg
    195 **
    196 ** Description     Find the app id in on the new service changed list
    197 **
    198 ** Returns     Pointer to the found new service changed item othwerwise NULL
    199 **
    200 *******************************************************************************/
    201 tGATTS_PENDING_NEW_SRV_START *gatt_sr_is_new_srv_chg(tBT_UUID *p_app_uuid128, tBT_UUID *p_svc_uuid, UINT16 svc_inst)
    202 {
    203     tGATTS_PENDING_NEW_SRV_START *p_buf = NULL;
    204 
    205     if (fixed_queue_is_empty(gatt_cb.pending_new_srv_start_q))
    206         return NULL;
    207 
    208     list_t *list = fixed_queue_get_list(gatt_cb.pending_new_srv_start_q);
    209     for (const list_node_t *node = list_begin(list); node != list_end(list);
    210          node = list_next(node)) {
    211         p_buf = (tGATTS_PENDING_NEW_SRV_START *)list_node(node);
    212         tGATTS_HNDL_RANGE *p = p_buf->p_new_srv_start;
    213         if (gatt_uuid_compare(*p_app_uuid128, p->app_uuid128)
    214             && gatt_uuid_compare (*p_svc_uuid, p->svc_uuid)
    215             && (svc_inst == p->svc_inst)) {
    216             GATT_TRACE_DEBUG("gatt_sr_is_new_srv_chg: Yes");
    217             break;
    218         }
    219     }
    220 
    221     return p_buf;
    222 }
    223 
    224 
    225 /*******************************************************************************
    226 **
    227 ** Function     gatt_add_pending_ind
    228 **
    229 ** Description  Add a pending indication
    230 **
    231 ** Returns    Pointer to the current pending indication buffer, NULL no buffer available
    232 **
    233 *******************************************************************************/
    234 tGATT_VALUE *gatt_add_pending_ind(tGATT_TCB  *p_tcb, tGATT_VALUE *p_ind)
    235 {
    236     tGATT_VALUE *p_buf = (tGATT_VALUE *)osi_malloc(sizeof(tGATT_VALUE));
    237 
    238     GATT_TRACE_DEBUG("%s", __func__);
    239     GATT_TRACE_DEBUG("enqueue a pending indication");
    240 
    241     memcpy(p_buf, p_ind, sizeof(tGATT_VALUE));
    242     fixed_queue_enqueue(p_tcb->pending_ind_q, p_buf);
    243 
    244     return p_buf;
    245 }
    246 
    247 /*******************************************************************************
    248 **
    249 ** Function     gatt_add_pending_new_srv_start
    250 **
    251 ** Description  Add a pending new srv start to the new service start queue
    252 **
    253 ** Returns    Pointer to the new service start buffer, NULL no buffer available
    254 **
    255 *******************************************************************************/
    256 tGATTS_PENDING_NEW_SRV_START *gatt_add_pending_new_srv_start(tGATTS_HNDL_RANGE *p_new_srv_start)
    257 {
    258     tGATTS_PENDING_NEW_SRV_START *p_buf =
    259         (tGATTS_PENDING_NEW_SRV_START *)osi_malloc(sizeof(tGATTS_PENDING_NEW_SRV_START));
    260 
    261     GATT_TRACE_DEBUG("%s", __func__);
    262     GATT_TRACE_DEBUG("enqueue a new pending new srv start");
    263 
    264     p_buf->p_new_srv_start = p_new_srv_start;
    265     fixed_queue_enqueue(gatt_cb.pending_new_srv_start_q, p_buf);
    266 
    267     return p_buf;
    268 }
    269 
    270 
    271 /*******************************************************************************
    272 **
    273 ** Function     gatt_add_srv_chg_clt
    274 **
    275 ** Description  Add a service chnage client to the service change client queue
    276 **
    277 ** Returns    Pointer to the service change client buffer; Null no buffer available
    278 **
    279 *******************************************************************************/
    280 tGATTS_SRV_CHG *gatt_add_srv_chg_clt(tGATTS_SRV_CHG *p_srv_chg)
    281 {
    282     tGATTS_SRV_CHG *p_buf = (tGATTS_SRV_CHG *)osi_malloc(sizeof(tGATTS_SRV_CHG));
    283 
    284     GATT_TRACE_DEBUG("%s", __func__);
    285     GATT_TRACE_DEBUG("enqueue a srv chg client");
    286 
    287     memcpy(p_buf, p_srv_chg, sizeof(tGATTS_SRV_CHG));
    288     fixed_queue_enqueue(gatt_cb.srv_chg_clt_q, p_buf);
    289 
    290     return p_buf;
    291 }
    292 
    293 /*******************************************************************************
    294 **
    295 ** Function     gatt_alloc_hdl_buffer
    296 **
    297 ** Description  Allocate a handle buufer
    298 **
    299 ** Returns    Pointer to the allocated buffer, NULL no buffer available
    300 **
    301 *******************************************************************************/
    302 tGATT_HDL_LIST_ELEM *gatt_alloc_hdl_buffer(void)
    303 {
    304     UINT8 i;
    305     tGATT_CB    *p_cb = &gatt_cb;
    306     tGATT_HDL_LIST_ELEM * p_elem= &p_cb->hdl_list[0];
    307 
    308     for (i = 0; i < GATT_MAX_SR_PROFILES; i++, p_elem++)
    309     {
    310         if (!p_cb->hdl_list[i].in_use)
    311         {
    312             memset(p_elem, 0, sizeof(tGATT_HDL_LIST_ELEM));
    313             p_elem->in_use = TRUE;
    314             p_elem->svc_db.svc_buffer = fixed_queue_new(SIZE_MAX);
    315             return p_elem;
    316         }
    317     }
    318 
    319     return NULL;
    320 }
    321 
    322 /*******************************************************************************
    323 **
    324 ** Function     gatt_find_hdl_buffer_by_handle
    325 **
    326 ** Description  Find handle range buffer by service handle.
    327 **
    328 ** Returns    Pointer to the buffer, NULL no buffer available
    329 **
    330 *******************************************************************************/
    331 tGATT_HDL_LIST_ELEM *gatt_find_hdl_buffer_by_handle(UINT16 handle)
    332 {
    333     tGATT_HDL_LIST_INFO *p_list_info= &gatt_cb.hdl_list_info;
    334     tGATT_HDL_LIST_ELEM      *p_list = NULL;
    335 
    336     p_list = p_list_info->p_first;
    337 
    338     while (p_list != NULL)
    339     {
    340         if (p_list->in_use && p_list->asgn_range.s_handle == handle)
    341         {
    342             return(p_list);
    343         }
    344         p_list = p_list->p_next;
    345     }
    346     return NULL;
    347 }
    348 /*******************************************************************************
    349 **
    350 ** Function     gatt_find_hdl_buffer_by_app_id
    351 **
    352 ** Description  Find handle range buffer by app ID, service and service instance ID.
    353 **
    354 ** Returns    Pointer to the buffer, NULL no buffer available
    355 **
    356 *******************************************************************************/
    357 tGATT_HDL_LIST_ELEM *gatt_find_hdl_buffer_by_app_id (tBT_UUID *p_app_uuid128,
    358                                                      tBT_UUID *p_svc_uuid,
    359                                                      UINT16 svc_inst)
    360 {
    361     tGATT_HDL_LIST_INFO *p_list_info= &gatt_cb.hdl_list_info;
    362     tGATT_HDL_LIST_ELEM      *p_list = NULL;
    363 
    364     p_list = p_list_info->p_first;
    365 
    366     while (p_list != NULL)
    367     {
    368         if ( gatt_uuid_compare (*p_app_uuid128, p_list->asgn_range.app_uuid128)
    369              &&  gatt_uuid_compare (*p_svc_uuid,    p_list->asgn_range.svc_uuid)
    370              &&  (svc_inst == p_list->asgn_range.svc_inst) )
    371         {
    372             GATT_TRACE_DEBUG ("Already allocated handles for this service before!!");
    373             return(p_list);
    374         }
    375         p_list = p_list->p_next;
    376     }
    377     return NULL;
    378 }
    379 /*******************************************************************************
    380 **
    381 ** Function         gatt_free_hdl_buffer
    382 **
    383 ** Description     free a handle buffer
    384 **
    385 ** Returns       None
    386 **
    387 *******************************************************************************/
    388 void gatt_free_hdl_buffer(tGATT_HDL_LIST_ELEM *p)
    389 {
    390 
    391     if (p)
    392     {
    393         while (!fixed_queue_is_empty(p->svc_db.svc_buffer))
    394             osi_free(fixed_queue_try_dequeue(p->svc_db.svc_buffer));
    395         fixed_queue_free(p->svc_db.svc_buffer, NULL);
    396         memset(p, 0, sizeof(tGATT_HDL_LIST_ELEM));
    397     }
    398 }
    399 /*******************************************************************************
    400 **
    401 ** Function         gatt_free_srvc_db_buffer_app_id
    402 **
    403 ** Description      free the service attribute database buffers by the owner of the
    404 **                  service app ID.
    405 **
    406 ** Returns       None
    407 **
    408 *******************************************************************************/
    409 void gatt_free_srvc_db_buffer_app_id(tBT_UUID *p_app_id)
    410 {
    411     tGATT_HDL_LIST_ELEM *p_elem =  &gatt_cb.hdl_list[0];
    412     UINT8   i;
    413 
    414     for (i = 0; i < GATT_MAX_SR_PROFILES; i ++, p_elem ++)
    415     {
    416         if (memcmp(p_app_id, &p_elem->asgn_range.app_uuid128, sizeof(tBT_UUID)) == 0)
    417         {
    418             while (!fixed_queue_is_empty(p_elem->svc_db.svc_buffer))
    419                 osi_free(fixed_queue_try_dequeue(p_elem->svc_db.svc_buffer));
    420             fixed_queue_free(p_elem->svc_db.svc_buffer, NULL);
    421             p_elem->svc_db.svc_buffer = NULL;
    422 
    423             p_elem->svc_db.mem_free = 0;
    424             p_elem->svc_db.p_attr_list = p_elem->svc_db.p_free_mem = NULL;
    425         }
    426     }
    427 }
    428 /*******************************************************************************
    429 **
    430 ** Function         gatt_is_last_attribute
    431 **
    432 ** Description     Check this is the last attribute of the specified value or not
    433 **
    434 ** Returns       TRUE - yes this is the last attribute
    435 **
    436 *******************************************************************************/
    437 BOOLEAN gatt_is_last_attribute(tGATT_SRV_LIST_INFO *p_list, tGATT_SRV_LIST_ELEM *p_start, tBT_UUID value)
    438 {
    439     tGATT_SRV_LIST_ELEM *p_srv= p_start->p_next;
    440     BOOLEAN              is_last_attribute = TRUE;
    441     tGATT_SR_REG        *p_rcb = NULL;
    442     tBT_UUID            *p_svc_uuid;
    443 
    444     p_list->p_last_primary = NULL;
    445 
    446     while (p_srv)
    447     {
    448         p_rcb = GATT_GET_SR_REG_PTR(p_srv->i_sreg);
    449 
    450         p_svc_uuid = gatts_get_service_uuid (p_rcb->p_db);
    451 
    452         if (gatt_uuid_compare(value, *p_svc_uuid))
    453         {
    454             is_last_attribute = FALSE;
    455             break;
    456 
    457         }
    458         p_srv = p_srv->p_next;
    459     }
    460 
    461     return is_last_attribute;
    462 
    463 }
    464 
    465 /*******************************************************************************
    466 **
    467 ** Function         gatt_update_last_pri_srv_info
    468 **
    469 ** Description     Update the the last primary info for the service list info
    470 **
    471 ** Returns       None
    472 **
    473 *******************************************************************************/
    474 void gatt_update_last_pri_srv_info(tGATT_SRV_LIST_INFO *p_list)
    475 {
    476     tGATT_SRV_LIST_ELEM *p_srv= p_list->p_first;
    477 
    478     p_list->p_last_primary = NULL;
    479 
    480     while (p_srv)
    481     {
    482         if (p_srv->is_primary)
    483         {
    484             p_list->p_last_primary = p_srv;
    485         }
    486         p_srv = p_srv->p_next;
    487     }
    488 
    489 }
    490 /*******************************************************************************
    491 **
    492 ** Function         gatts_update_srv_list_elem
    493 **
    494 ** Description      update an element in the service list.
    495 **
    496 ** Returns          None.
    497 **
    498 *******************************************************************************/
    499 void gatts_update_srv_list_elem(UINT8 i_sreg, UINT16 handle, BOOLEAN is_primary)
    500 {
    501     UNUSED(handle);
    502 
    503     gatt_cb.srv_list[i_sreg].in_use         = TRUE;
    504     gatt_cb.srv_list[i_sreg].i_sreg    = i_sreg;
    505     gatt_cb.srv_list[i_sreg].s_hdl          = gatt_cb.sr_reg[i_sreg].s_hdl;
    506     gatt_cb.srv_list[i_sreg].is_primary     = is_primary;
    507 
    508     return;
    509 }
    510 /*******************************************************************************
    511 **
    512 ** Function  gatt_add_a_srv_to_list
    513 **
    514 ** Description  add an service to the list in ascending
    515 **              order of the start handle
    516 **
    517 ** Returns   BOOLEAN TRUE-if add is successful
    518 **
    519 *******************************************************************************/
    520 BOOLEAN gatt_add_a_srv_to_list(tGATT_SRV_LIST_INFO *p_list, tGATT_SRV_LIST_ELEM *p_new)
    521 {
    522     tGATT_SRV_LIST_ELEM *p_old;
    523 
    524     if (!p_new)
    525     {
    526         GATT_TRACE_DEBUG("p_new==NULL");
    527         return FALSE;
    528     }
    529 
    530     if (!p_list->p_first)
    531     {
    532         /* this is an empty list */
    533         p_list->p_first =
    534         p_list->p_last  = p_new;
    535         p_new->p_next   =
    536         p_new->p_prev   = NULL;
    537     }
    538     else
    539     {
    540         p_old = p_list->p_first;
    541         while (1)
    542         {
    543             if (p_old == NULL)
    544             {
    545                 p_list->p_last->p_next      = p_new;
    546                 p_new->p_prev               = p_list->p_last;
    547                 p_new->p_next               = NULL;
    548                 p_list->p_last              = p_new;
    549                 break;
    550             }
    551             else
    552             {
    553                 if (p_new->s_hdl <  p_old->s_hdl)
    554                 {
    555                     /* if not the first in list */
    556                     if (p_old->p_prev != NULL)
    557                         p_old->p_prev->p_next   = p_new;
    558                     else
    559                         p_list->p_first = p_new;
    560 
    561                     p_new->p_prev           = p_old->p_prev;
    562                     p_new->p_next           = p_old;
    563                     p_old->p_prev           = p_new;
    564                     break;
    565                 }
    566             }
    567             p_old = p_old->p_next;
    568         }
    569     }
    570     p_list->count++;
    571 
    572     gatt_update_last_pri_srv_info(p_list);
    573     return TRUE;
    574 
    575 }
    576 
    577 /*******************************************************************************
    578 **
    579 ** Function  gatt_remove_a_srv_from_list
    580 **
    581 ** Description  Remove a service from the list
    582 **
    583 ** Returns   BOOLEAN TRUE-if remove is successful
    584 **
    585 *******************************************************************************/
    586 BOOLEAN gatt_remove_a_srv_from_list(tGATT_SRV_LIST_INFO *p_list, tGATT_SRV_LIST_ELEM *p_remove)
    587 {
    588     if (!p_remove || !p_list->p_first)
    589     {
    590         GATT_TRACE_DEBUG("p_remove==NULL || p_list->p_first==NULL");
    591         return FALSE;
    592     }
    593 
    594     if (p_remove->p_prev == NULL)
    595     {
    596         p_list->p_first             = p_remove->p_next;
    597         if (p_remove->p_next)
    598             p_remove->p_next->p_prev    = NULL;
    599     }
    600     else if (p_remove->p_next == NULL)
    601     {
    602         p_list->p_last              = p_remove->p_prev;
    603         p_remove->p_prev->p_next    = NULL;
    604     }
    605     else
    606     {
    607         p_remove->p_next->p_prev = p_remove->p_prev;
    608         p_remove->p_prev->p_next = p_remove->p_next;
    609     }
    610     p_list->count--;
    611     gatt_update_last_pri_srv_info(p_list);
    612     return TRUE;
    613 
    614 }
    615 
    616 /*******************************************************************************
    617 **
    618 ** Function  gatt_add_an_item_to_list
    619 **
    620 ** Description  add an service handle range to the list in decending
    621 **              order of the start handle
    622 **
    623 ** Returns   BOOLEAN TRUE-if add is successful
    624 **
    625 *******************************************************************************/
    626 BOOLEAN gatt_add_an_item_to_list(tGATT_HDL_LIST_INFO *p_list, tGATT_HDL_LIST_ELEM *p_new)
    627 {
    628     tGATT_HDL_LIST_ELEM *p_old;
    629     if (!p_new)
    630     {
    631         GATT_TRACE_DEBUG("p_new==NULL");
    632         return FALSE;
    633     }
    634 
    635     if (!p_list->p_first)
    636     {
    637         /* this is an empty list */
    638         p_list->p_first =
    639         p_list->p_last  = p_new;
    640         p_new->p_next   =
    641         p_new->p_prev   = NULL;
    642     }
    643     else
    644     {
    645         p_old = p_list->p_first;
    646         while (1)
    647         {
    648             if (p_old == NULL)
    649             {
    650                 p_list->p_last->p_next      = p_new;
    651                 p_new->p_prev               = p_list->p_last;
    652                 p_new->p_next               = NULL;
    653                 p_list->p_last              = p_new;
    654 
    655                 break;
    656 
    657             }
    658             else
    659             {
    660                 if (p_new->asgn_range.s_handle >  p_old->asgn_range.s_handle)
    661                 {
    662                     if (p_old == p_list->p_first)
    663                         p_list->p_first = p_new;
    664 
    665                     p_new->p_prev    = p_old->p_prev;
    666                     p_new->p_next    = p_old;
    667 
    668 
    669                     p_old->p_prev    = p_new;
    670                     break;
    671                 }
    672             }
    673             p_old = p_old->p_next;
    674         }
    675     }
    676     p_list->count++;
    677     return TRUE;
    678 
    679 }
    680 
    681 /*******************************************************************************
    682 **
    683 ** Function  gatt_remove_an_item_from_list
    684 **
    685 ** Description  Remove an service handle range from the list
    686 **
    687 ** Returns   BOOLEAN TRUE-if remove is successful
    688 **
    689 *******************************************************************************/
    690 BOOLEAN gatt_remove_an_item_from_list(tGATT_HDL_LIST_INFO *p_list, tGATT_HDL_LIST_ELEM *p_remove)
    691 {
    692     if (!p_remove || !p_list->p_first)
    693     {
    694         GATT_TRACE_DEBUG("p_remove==NULL || p_list->p_first==NULL");
    695         return FALSE;
    696     }
    697 
    698     if (p_remove->p_prev == NULL)
    699     {
    700         p_list->p_first             = p_remove->p_next;
    701         if (p_remove->p_next)
    702             p_remove->p_next->p_prev    = NULL;
    703     }
    704     else if (p_remove->p_next == NULL)
    705     {
    706         p_list->p_last              = p_remove->p_prev;
    707         p_remove->p_prev->p_next    = NULL;
    708     }
    709     else
    710     {
    711         p_remove->p_next->p_prev = p_remove->p_prev;
    712         p_remove->p_prev->p_next = p_remove->p_next;
    713     }
    714     p_list->count--;
    715     return TRUE;
    716 
    717 }
    718 
    719 /*******************************************************************************
    720 **
    721 ** Function         gatt_find_the_connected_bda
    722 **
    723 ** Description      This function find the connected bda
    724 **
    725 ** Returns           TRUE if found
    726 **
    727 *******************************************************************************/
    728 BOOLEAN gatt_find_the_connected_bda(UINT8 start_idx, BD_ADDR bda, UINT8 *p_found_idx,
    729                                     tBT_TRANSPORT *p_transport)
    730 {
    731     UINT8 i;
    732     BOOLEAN found = FALSE;
    733     GATT_TRACE_DEBUG("gatt_find_the_connected_bda start_idx=%d",start_idx);
    734 
    735     for (i = start_idx ; i < GATT_MAX_PHY_CHANNEL; i ++)
    736     {
    737         if (gatt_cb.tcb[i].in_use && gatt_cb.tcb[i].ch_state == GATT_CH_OPEN)
    738         {
    739             memcpy( bda, gatt_cb.tcb[i].peer_bda, BD_ADDR_LEN);
    740             *p_found_idx = i;
    741             *p_transport = gatt_cb.tcb[i].transport;
    742             found = TRUE;
    743             GATT_TRACE_DEBUG("gatt_find_the_connected_bda bda :%02x-%02x-%02x-%02x-%02x-%02x",
    744                               bda[0],  bda[1], bda[2],  bda[3], bda[4],  bda[5]);
    745             break;
    746         }
    747     }
    748     GATT_TRACE_DEBUG("gatt_find_the_connected_bda found=%d found_idx=%d", found, i);
    749     return found;
    750 }
    751 
    752 
    753 
    754 /*******************************************************************************
    755 **
    756 ** Function         gatt_is_srv_chg_ind_pending
    757 **
    758 ** Description      Check whether a service chnaged is in the indication pending queue
    759 **                  or waiting for an Ack already
    760 **
    761 ** Returns         BOOLEAN
    762 **
    763 *******************************************************************************/
    764 BOOLEAN gatt_is_srv_chg_ind_pending (tGATT_TCB *p_tcb)
    765 {
    766     BOOLEAN srv_chg_ind_pending = FALSE;
    767 
    768     GATT_TRACE_DEBUG("gatt_is_srv_chg_ind_pending is_queue_empty=%d",
    769                      fixed_queue_is_empty(p_tcb->pending_ind_q));
    770 
    771     if (p_tcb->indicate_handle == gatt_cb.handle_of_h_r)
    772     {
    773         srv_chg_ind_pending = TRUE;
    774     }
    775     else if (! fixed_queue_is_empty(p_tcb->pending_ind_q))
    776     {
    777         list_t *list = fixed_queue_get_list(p_tcb->pending_ind_q);
    778         for (const list_node_t *node = list_begin(list);
    779              node != list_end(list);
    780              node = list_next(node)) {
    781             tGATT_VALUE *p_buf = (tGATT_VALUE *)list_node(node);
    782             if (p_buf->handle == gatt_cb.handle_of_h_r)
    783             {
    784                 srv_chg_ind_pending = TRUE;
    785                 break;
    786             }
    787         }
    788     }
    789 
    790     GATT_TRACE_DEBUG("srv_chg_ind_pending = %d", srv_chg_ind_pending);
    791     return srv_chg_ind_pending;
    792 }
    793 
    794 
    795 /*******************************************************************************
    796 **
    797 ** Function         gatt_is_bda_in_the_srv_chg_clt_list
    798 **
    799 ** Description      This function check the specified bda is in the srv chg clinet list or not
    800 **
    801 ** Returns         pointer to the found elemenet otherwise NULL
    802 **
    803 *******************************************************************************/
    804 tGATTS_SRV_CHG *gatt_is_bda_in_the_srv_chg_clt_list (BD_ADDR bda)
    805 {
    806     tGATTS_SRV_CHG *p_buf = NULL;
    807 
    808     GATT_TRACE_DEBUG("gatt_is_bda_in_the_srv_chg_clt_list :%02x-%02x-%02x-%02x-%02x-%02x",
    809                       bda[0],  bda[1], bda[2],  bda[3], bda[4],  bda[5]);
    810 
    811     if (fixed_queue_is_empty(gatt_cb.srv_chg_clt_q))
    812         return NULL;
    813 
    814     list_t *list = fixed_queue_get_list(gatt_cb.srv_chg_clt_q);
    815     for (const list_node_t *node = list_begin(list); node != list_end(list);
    816          node = list_next(node)) {
    817         tGATTS_SRV_CHG *p_buf = (tGATTS_SRV_CHG *)list_node(node);
    818         if (!memcmp( bda, p_buf->bda, BD_ADDR_LEN))
    819         {
    820             GATT_TRACE_DEBUG("bda is in the srv chg clt list");
    821             break;
    822         }
    823     }
    824 
    825     return p_buf;
    826 }
    827 
    828 
    829 /*******************************************************************************
    830 **
    831 ** Function         gatt_is_bda_connected
    832 **
    833 ** Description
    834 **
    835 ** Returns           GATT_INDEX_INVALID if not found. Otherwise index to the tcb.
    836 **
    837 *******************************************************************************/
    838 BOOLEAN gatt_is_bda_connected(BD_ADDR bda)
    839 {
    840     UINT8 i = 0;
    841     BOOLEAN connected=FALSE;
    842 
    843     for ( i=0; i < GATT_MAX_PHY_CHANNEL; i ++)
    844     {
    845         if (gatt_cb.tcb[i].in_use &&
    846             !memcmp(gatt_cb.tcb[i].peer_bda, bda, BD_ADDR_LEN))
    847         {
    848             connected = TRUE;
    849             break;
    850         }
    851     }
    852     return connected;
    853 }
    854 
    855 /*******************************************************************************
    856 **
    857 ** Function         gatt_find_i_tcb_by_addr
    858 **
    859 ** Description      The function searches for an empty tcb entry, and return the index.
    860 **
    861 ** Returns           GATT_INDEX_INVALID if not found. Otherwise index to the tcb.
    862 **
    863 *******************************************************************************/
    864 UINT8 gatt_find_i_tcb_by_addr(BD_ADDR bda, tBT_TRANSPORT transport)
    865 {
    866     UINT8 i = 0;
    867 
    868     for ( ; i < GATT_MAX_PHY_CHANNEL; i ++)
    869     {
    870         if (!memcmp(gatt_cb.tcb[i].peer_bda, bda, BD_ADDR_LEN) &&
    871             gatt_cb.tcb[i].transport == transport)
    872         {
    873             return i;
    874         }
    875     }
    876     return GATT_INDEX_INVALID;
    877 }
    878 
    879 
    880 /*******************************************************************************
    881 **
    882 ** Function         gatt_get_tcb_by_idx
    883 **
    884 ** Description      The function get TCB using the TCB index
    885 **
    886 ** Returns           NULL if not found. Otherwise index to the tcb.
    887 **
    888 *******************************************************************************/
    889 tGATT_TCB * gatt_get_tcb_by_idx(UINT8 tcb_idx)
    890 {
    891     tGATT_TCB   *p_tcb = NULL;
    892 
    893     if ( (tcb_idx < GATT_MAX_PHY_CHANNEL) && gatt_cb.tcb[tcb_idx].in_use)
    894         p_tcb = &gatt_cb.tcb[tcb_idx];
    895 
    896     return p_tcb;
    897 }
    898 
    899 /*******************************************************************************
    900 **
    901 ** Function         gatt_find_tcb_by_addr
    902 **
    903 ** Description      The function searches for an empty tcb entry, and return pointer.
    904 **
    905 ** Returns           NULL if not found. Otherwise index to the tcb.
    906 **
    907 *******************************************************************************/
    908 tGATT_TCB * gatt_find_tcb_by_addr(BD_ADDR bda, tBT_TRANSPORT transport)
    909 {
    910     tGATT_TCB   *p_tcb = NULL;
    911     UINT8 i = 0;
    912 
    913     if ((i = gatt_find_i_tcb_by_addr(bda, transport)) != GATT_INDEX_INVALID)
    914         p_tcb = &gatt_cb.tcb[i];
    915 
    916     return p_tcb;
    917 }
    918 /*******************************************************************************
    919 **
    920 ** Function         gatt_find_i_tcb_free
    921 **
    922 ** Description      The function searches for an empty tcb entry, and return the index.
    923 **
    924 ** Returns           GATT_INDEX_INVALID if not found. Otherwise index to the tcb.
    925 **
    926 *******************************************************************************/
    927 UINT8 gatt_find_i_tcb_free(void)
    928 {
    929     UINT8 i = 0, j = GATT_INDEX_INVALID;
    930 
    931     for (i = 0; i < GATT_MAX_PHY_CHANNEL; i ++)
    932     {
    933         if (!gatt_cb.tcb[i].in_use)
    934         {
    935             j = i;
    936             break;
    937         }
    938     }
    939     return j;
    940 }
    941 /*******************************************************************************
    942 **
    943 ** Function         gatt_allocate_tcb_by_bdaddr
    944 **
    945 ** Description      The function locate or allocate new tcb entry for matching bda.
    946 **
    947 ** Returns           GATT_INDEX_INVALID if not found. Otherwise index to the tcb.
    948 **
    949 *******************************************************************************/
    950 tGATT_TCB * gatt_allocate_tcb_by_bdaddr(BD_ADDR bda, tBT_TRANSPORT transport)
    951 {
    952     UINT8 i = 0;
    953     BOOLEAN allocated = FALSE;
    954     tGATT_TCB    *p_tcb = NULL;
    955 
    956     /* search for existing tcb with matching bda    */
    957     i = gatt_find_i_tcb_by_addr(bda, transport);
    958     /* find free tcb */
    959     if (i == GATT_INDEX_INVALID)
    960     {
    961         i = gatt_find_i_tcb_free();
    962         allocated = TRUE;
    963     }
    964     if (i != GATT_INDEX_INVALID)
    965     {
    966         p_tcb = &gatt_cb.tcb[i];
    967 
    968         if (allocated)
    969         {
    970             memset(p_tcb, 0, sizeof(tGATT_TCB));
    971             p_tcb->pending_enc_clcb = fixed_queue_new(SIZE_MAX);
    972             p_tcb->pending_ind_q = fixed_queue_new(SIZE_MAX);
    973             p_tcb->conf_timer = alarm_new("gatt.conf_timer");
    974             p_tcb->ind_ack_timer = alarm_new("gatt.ind_ack_timer");
    975             p_tcb->in_use = TRUE;
    976             p_tcb->tcb_idx = i;
    977             p_tcb->transport = transport;
    978         }
    979         memcpy(p_tcb->peer_bda, bda, BD_ADDR_LEN);
    980     }
    981     return p_tcb;
    982 }
    983 
    984 /*******************************************************************************
    985 **
    986 ** Function         gatt_convert_uuid16_to_uuid128
    987 **
    988 ** Description      Convert a 16 bits UUID to be an standard 128 bits one.
    989 **
    990 ** Returns          TRUE if two uuid match; FALSE otherwise.
    991 **
    992 *******************************************************************************/
    993 void gatt_convert_uuid16_to_uuid128(UINT8 uuid_128[LEN_UUID_128], UINT16 uuid_16)
    994 {
    995     UINT8   *p = &uuid_128[LEN_UUID_128 - 4];
    996 
    997     memcpy (uuid_128, base_uuid, LEN_UUID_128);
    998 
    999     UINT16_TO_STREAM(p, uuid_16);
   1000 }
   1001 
   1002 /*******************************************************************************
   1003 **
   1004 ** Function         gatt_convert_uuid32_to_uuid128
   1005 **
   1006 ** Description      Convert a 32 bits UUID to be an standard 128 bits one.
   1007 **
   1008 ** Returns          TRUE if two uuid match; FALSE otherwise.
   1009 **
   1010 *******************************************************************************/
   1011 void gatt_convert_uuid32_to_uuid128(UINT8 uuid_128[LEN_UUID_128], UINT32 uuid_32)
   1012 {
   1013     UINT8   *p = &uuid_128[LEN_UUID_128 - 4];
   1014 
   1015     memcpy (uuid_128, base_uuid, LEN_UUID_128);
   1016 
   1017     UINT32_TO_STREAM(p, uuid_32);
   1018 }
   1019 /*******************************************************************************
   1020 **
   1021 ** Function         gatt_uuid_compare
   1022 **
   1023 ** Description      Compare two UUID to see if they are the same.
   1024 **
   1025 ** Returns          TRUE if two uuid match; FALSE otherwise.
   1026 **
   1027 *******************************************************************************/
   1028 BOOLEAN gatt_uuid_compare (tBT_UUID src, tBT_UUID tar)
   1029 {
   1030     UINT8  su[LEN_UUID_128], tu[LEN_UUID_128];
   1031     UINT8  *ps, *pt;
   1032 
   1033     /* any of the UUID is unspecified */
   1034     if (src.len == 0 || tar.len == 0)
   1035     {
   1036         return TRUE;
   1037     }
   1038 
   1039     /* If both are 16-bit, we can do a simple compare */
   1040     if (src.len == LEN_UUID_16 && tar.len == LEN_UUID_16)
   1041     {
   1042         return src.uu.uuid16 == tar.uu.uuid16;
   1043     }
   1044 
   1045     /* If both are 32-bit, we can do a simple compare */
   1046     if (src.len == LEN_UUID_32 && tar.len == LEN_UUID_32)
   1047     {
   1048         return src.uu.uuid32 == tar.uu.uuid32;
   1049     }
   1050 
   1051     /* One or both of the UUIDs is 128-bit */
   1052     if (src.len == LEN_UUID_16)
   1053     {
   1054         /* convert a 16 bits UUID to 128 bits value */
   1055         gatt_convert_uuid16_to_uuid128(su, src.uu.uuid16);
   1056         ps = su;
   1057     }
   1058     else if (src.len == LEN_UUID_32)
   1059     {
   1060         gatt_convert_uuid32_to_uuid128(su, src.uu.uuid32);
   1061         ps = su;
   1062     }
   1063     else
   1064         ps = src.uu.uuid128;
   1065 
   1066     if (tar.len == LEN_UUID_16)
   1067     {
   1068         /* convert a 16 bits UUID to 128 bits value */
   1069         gatt_convert_uuid16_to_uuid128(tu, tar.uu.uuid16);
   1070         pt = tu;
   1071     }
   1072     else if (tar.len == LEN_UUID_32)
   1073     {
   1074         /* convert a 32 bits UUID to 128 bits value */
   1075         gatt_convert_uuid32_to_uuid128(tu, tar.uu.uuid32);
   1076         pt = tu;
   1077     }
   1078     else
   1079         pt = tar.uu.uuid128;
   1080 
   1081     return(memcmp(ps, pt, LEN_UUID_128) == 0);
   1082 }
   1083 
   1084 /*******************************************************************************
   1085 **
   1086 ** Function         gatt_build_uuid_to_stream
   1087 **
   1088 ** Description      Add UUID into stream.
   1089 **
   1090 ** Returns          UUID length.
   1091 **
   1092 *******************************************************************************/
   1093 UINT8 gatt_build_uuid_to_stream(UINT8 **p_dst, tBT_UUID uuid)
   1094 {
   1095     UINT8   *p = *p_dst;
   1096     UINT8   len = 0;
   1097 
   1098     if (uuid.len == LEN_UUID_16)
   1099     {
   1100         UINT16_TO_STREAM (p, uuid.uu.uuid16);
   1101         len = LEN_UUID_16;
   1102     }
   1103     else if (uuid.len == LEN_UUID_32) /* always convert 32 bits into 128 bits as alwats */
   1104     {
   1105         gatt_convert_uuid32_to_uuid128(p, uuid.uu.uuid32);
   1106         p += LEN_UUID_128;
   1107         len = LEN_UUID_128;
   1108     }
   1109     else if (uuid.len == LEN_UUID_128)
   1110     {
   1111         ARRAY_TO_STREAM (p, uuid.uu.uuid128, LEN_UUID_128);
   1112         len = LEN_UUID_128;
   1113     }
   1114 
   1115     *p_dst = p;
   1116     return len;
   1117 }
   1118 
   1119 /*******************************************************************************
   1120 **
   1121 ** Function         gatt_parse_uuid_from_cmd
   1122 **
   1123 ** Description      Convert a 128 bits UUID into a 16 bits UUID.
   1124 **
   1125 ** Returns          TRUE if command sent, otherwise FALSE.
   1126 **
   1127 *******************************************************************************/
   1128 BOOLEAN gatt_parse_uuid_from_cmd(tBT_UUID *p_uuid_rec, UINT16 uuid_size, UINT8 **p_data)
   1129 {
   1130     BOOLEAN is_base_uuid, ret = TRUE;
   1131     UINT8  xx;
   1132     UINT8 *p_uuid = *p_data;
   1133 
   1134     memset(p_uuid_rec, 0, sizeof(tBT_UUID));
   1135 
   1136     switch (uuid_size)
   1137     {
   1138         case LEN_UUID_16:
   1139             p_uuid_rec->len = uuid_size;
   1140             STREAM_TO_UINT16 (p_uuid_rec->uu.uuid16, p_uuid);
   1141             *p_data += LEN_UUID_16;
   1142             break;
   1143 
   1144         case LEN_UUID_128:
   1145             /* See if we can compress his UUID down to 16 or 32bit UUIDs */
   1146             is_base_uuid = TRUE;
   1147             for (xx = 0; xx < LEN_UUID_128 - 4; xx++)
   1148             {
   1149                 if (p_uuid[xx] != base_uuid[xx])
   1150                 {
   1151                     is_base_uuid = FALSE;
   1152                     break;
   1153                 }
   1154             }
   1155             if (is_base_uuid)
   1156             {
   1157                 if ((p_uuid[LEN_UUID_128 - 1] == 0) && (p_uuid[LEN_UUID_128 - 2] == 0))
   1158                 {
   1159                     p_uuid += (LEN_UUID_128 - 4);
   1160                     p_uuid_rec->len = LEN_UUID_16;
   1161                     STREAM_TO_UINT16(p_uuid_rec->uu.uuid16, p_uuid);
   1162                 }
   1163                 else
   1164                 {
   1165                     p_uuid += (LEN_UUID_128 - LEN_UUID_32);
   1166                     p_uuid_rec->len = LEN_UUID_32;
   1167                     STREAM_TO_UINT32(p_uuid_rec->uu.uuid32, p_uuid);
   1168                 }
   1169             }
   1170             if (!is_base_uuid)
   1171             {
   1172                 p_uuid_rec->len = LEN_UUID_128;
   1173                 memcpy(p_uuid_rec->uu.uuid128, p_uuid, LEN_UUID_128);
   1174             }
   1175             *p_data += LEN_UUID_128;
   1176             break;
   1177 
   1178         /* do not allow 32 bits UUID in ATT PDU now */
   1179         case LEN_UUID_32:
   1180             GATT_TRACE_ERROR("DO NOT ALLOW 32 BITS UUID IN ATT PDU");
   1181         case 0:
   1182         default:
   1183             if (uuid_size != 0) ret = FALSE;
   1184             GATT_TRACE_WARNING("gatt_parse_uuid_from_cmd invalid uuid size");
   1185             break;
   1186     }
   1187 
   1188     return( ret);
   1189 }
   1190 
   1191 /*******************************************************************************
   1192 **
   1193 ** Function         gatt_start_rsp_timer
   1194 **
   1195 ** Description      Start a wait_for_response timer.
   1196 **
   1197 ** Returns          void
   1198 **
   1199 *******************************************************************************/
   1200 void gatt_start_rsp_timer(UINT16 clcb_idx)
   1201 {
   1202     tGATT_CLCB *p_clcb = &gatt_cb.clcb[clcb_idx];
   1203     period_ms_t timeout_ms = GATT_WAIT_FOR_RSP_TIMEOUT_MS;
   1204 
   1205     if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY &&
   1206         p_clcb->op_subtype == GATT_DISC_SRVC_ALL) {
   1207         timeout_ms = GATT_WAIT_FOR_DISC_RSP_TIMEOUT_MS;
   1208     }
   1209 
   1210     // TODO: The tGATT_CLCB memory and state management needs cleanup,
   1211     // and then the timers can be allocated elsewhere.
   1212     if (p_clcb->gatt_rsp_timer_ent == NULL) {
   1213         p_clcb->gatt_rsp_timer_ent = alarm_new("gatt.gatt_rsp_timer_ent");
   1214     }
   1215     alarm_set_on_queue(p_clcb->gatt_rsp_timer_ent, timeout_ms,
   1216                        gatt_rsp_timeout, p_clcb, btu_general_alarm_queue);
   1217 }
   1218 
   1219 /*******************************************************************************
   1220 **
   1221 ** Function         gatt_start_conf_timer
   1222 **
   1223 ** Description      Start a wait_for_confirmation timer.
   1224 **
   1225 ** Returns          void
   1226 **
   1227 *******************************************************************************/
   1228 void gatt_start_conf_timer(tGATT_TCB *p_tcb)
   1229 {
   1230     alarm_set_on_queue(p_tcb->conf_timer, GATT_WAIT_FOR_RSP_TIMEOUT_MS,
   1231                        gatt_indication_confirmation_timeout, p_tcb,
   1232                        btu_general_alarm_queue);
   1233 }
   1234 
   1235 /*******************************************************************************
   1236 **
   1237 ** Function         gatt_start_ind_ack_timer
   1238 **
   1239 ** Description      start the application ack timer
   1240 **
   1241 ** Returns          void
   1242 **
   1243 *******************************************************************************/
   1244 void gatt_start_ind_ack_timer(tGATT_TCB *p_tcb)
   1245 {
   1246     /* start notification cache timer */
   1247     alarm_set_on_queue(p_tcb->ind_ack_timer, GATT_WAIT_FOR_RSP_TIMEOUT_MS,
   1248                        gatt_ind_ack_timeout, p_tcb, btu_general_alarm_queue);
   1249 }
   1250 
   1251 /*******************************************************************************
   1252 **
   1253 ** Function         gatt_rsp_timeout
   1254 **
   1255 ** Description      Called when GATT wait for ATT command response timer expires
   1256 **
   1257 ** Returns          void
   1258 **
   1259 *******************************************************************************/
   1260 void gatt_rsp_timeout(void *data)
   1261 {
   1262     tGATT_CLCB *p_clcb = (tGATT_CLCB *)data;
   1263 
   1264     if (p_clcb == NULL || p_clcb->p_tcb == NULL)
   1265     {
   1266         GATT_TRACE_WARNING("%s clcb is already deleted", __func__);
   1267         return;
   1268     }
   1269     if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY &&
   1270         p_clcb->op_subtype == GATT_DISC_SRVC_ALL &&
   1271         p_clcb->retry_count < GATT_REQ_RETRY_LIMIT)
   1272     {
   1273         UINT8 rsp_code;
   1274         GATT_TRACE_WARNING("%s retry discovery primary service", __func__);
   1275         if (p_clcb != gatt_cmd_dequeue(p_clcb->p_tcb, &rsp_code))
   1276         {
   1277             GATT_TRACE_ERROR("%s command queue out of sync, disconnect",
   1278                              __func__);
   1279         }
   1280         else
   1281         {
   1282             p_clcb->retry_count++;
   1283             gatt_act_discovery(p_clcb);
   1284             return;
   1285         }
   1286     }
   1287 
   1288     GATT_TRACE_WARNING("%s disconnecting...", __func__);
   1289     gatt_disconnect (p_clcb->p_tcb);
   1290 }
   1291 
   1292 /*******************************************************************************
   1293 **
   1294 ** Function         gatt_indication_confirmation_timeout
   1295 **
   1296 ** Description      Called when the indication confirmation timer expires
   1297 **
   1298 ** Returns          void
   1299 **
   1300 *******************************************************************************/
   1301 void gatt_indication_confirmation_timeout(void *data)
   1302 {
   1303     tGATT_TCB *p_tcb = (tGATT_TCB *)data;
   1304 
   1305     GATT_TRACE_WARNING("%s disconnecting...", __func__);
   1306     gatt_disconnect(p_tcb);
   1307 }
   1308 
   1309 /*******************************************************************************
   1310 **
   1311 ** Function         gatt_ind_ack_timeout
   1312 **
   1313 ** Description      Called when GATT wait for ATT handle confirmation timeout
   1314 **
   1315 ** Returns          void
   1316 **
   1317 *******************************************************************************/
   1318 void gatt_ind_ack_timeout(void *data)
   1319 {
   1320     tGATT_TCB *p_tcb = (tGATT_TCB *)data;
   1321 
   1322     GATT_TRACE_WARNING("%s send ack now", __func__);
   1323 
   1324     if (p_tcb != NULL)
   1325         p_tcb->ind_count = 0;
   1326 
   1327     attp_send_cl_msg(p_tcb, 0, GATT_HANDLE_VALUE_CONF, NULL);
   1328 }
   1329 /*******************************************************************************
   1330 **
   1331 ** Function         gatt_sr_find_i_rcb_by_handle
   1332 **
   1333 ** Description      The function searches for a service that owns a specific handle.
   1334 **
   1335 ** Returns          GATT_MAX_SR_PROFILES if not found. Otherwise index of th eservice.
   1336 **
   1337 *******************************************************************************/
   1338 UINT8 gatt_sr_find_i_rcb_by_handle(UINT16 handle)
   1339 {
   1340     UINT8  i_rcb = 0;
   1341 
   1342     for ( ; i_rcb < GATT_MAX_SR_PROFILES; i_rcb++)
   1343     {
   1344         if (gatt_cb.sr_reg[i_rcb].in_use &&
   1345             gatt_cb.sr_reg[i_rcb].s_hdl <= handle &&
   1346             gatt_cb.sr_reg[i_rcb].e_hdl >= handle )
   1347         {
   1348             break;
   1349         }
   1350     }
   1351     return i_rcb;
   1352 }
   1353 
   1354 /*******************************************************************************
   1355 **
   1356 ** Function         gatt_sr_find_i_rcb_by_handle
   1357 **
   1358 ** Description      The function searches for a service that owns a specific handle.
   1359 **
   1360 ** Returns          0 if not found. Otherwise index of th eservice.
   1361 **
   1362 *******************************************************************************/
   1363 UINT8 gatt_sr_find_i_rcb_by_app_id(tBT_UUID *p_app_uuid128, tBT_UUID *p_svc_uuid, UINT16 svc_inst)
   1364 {
   1365     UINT8           i_rcb = 0;
   1366     tGATT_SR_REG    *p_sreg;
   1367     tBT_UUID        *p_this_uuid;
   1368 
   1369     for (i_rcb = 0, p_sreg = gatt_cb.sr_reg; i_rcb < GATT_MAX_SR_PROFILES; i_rcb++, p_sreg++)
   1370     {
   1371         if ( p_sreg->in_use )
   1372         {
   1373             p_this_uuid = gatts_get_service_uuid (p_sreg->p_db);
   1374 
   1375             if (p_this_uuid &&
   1376                 gatt_uuid_compare (*p_app_uuid128, p_sreg->app_uuid ) &&
   1377                 gatt_uuid_compare (*p_svc_uuid, *p_this_uuid) &&
   1378                 (svc_inst == p_sreg->service_instance))
   1379             {
   1380                 GATT_TRACE_ERROR ("Active Service Found ");
   1381                 gatt_dbg_display_uuid(*p_svc_uuid);
   1382 
   1383                 break;
   1384             }
   1385         }
   1386     }
   1387     return i_rcb;
   1388 }
   1389 /*******************************************************************************
   1390 **
   1391 ** Function         gatt_sr_find_i_rcb_by_handle
   1392 **
   1393 ** Description      The function searches for a service that owns a specific handle.
   1394 **
   1395 ** Returns          0 if not found. Otherwise index of th eservice.
   1396 **
   1397 *******************************************************************************/
   1398 UINT8 gatt_sr_alloc_rcb(tGATT_HDL_LIST_ELEM *p_list )
   1399 {
   1400     UINT8   ii = 0;
   1401     tGATT_SR_REG    *p_sreg = NULL;
   1402 
   1403     /*this is a new application servoce start */
   1404     for (ii = 0, p_sreg = gatt_cb.sr_reg; ii < GATT_MAX_SR_PROFILES; ii++, p_sreg++)
   1405     {
   1406         if (!p_sreg->in_use)
   1407         {
   1408             memset (p_sreg, 0, sizeof(tGATT_SR_REG));
   1409 
   1410             p_sreg->in_use = TRUE;
   1411             memcpy (&p_sreg->app_uuid, &p_list->asgn_range.app_uuid128, sizeof(tBT_UUID));
   1412 
   1413             p_sreg->service_instance    = p_list->asgn_range.svc_inst;
   1414             p_sreg->type                = p_list->asgn_range.is_primary ? GATT_UUID_PRI_SERVICE: GATT_UUID_SEC_SERVICE;
   1415             p_sreg->s_hdl               = p_list->asgn_range.s_handle;
   1416             p_sreg->e_hdl               = p_list->asgn_range.e_handle;
   1417             p_sreg->p_db                = &p_list->svc_db;
   1418 
   1419             GATT_TRACE_DEBUG("total buffer in db [%d]",
   1420                              fixed_queue_length(p_sreg->p_db->svc_buffer));
   1421             break;
   1422         }
   1423     }
   1424 
   1425     return ii;
   1426 }
   1427 /*******************************************************************************
   1428 **
   1429 ** Function         gatt_sr_get_sec_info
   1430 **
   1431 ** Description      Get the security flag and key size information for the peer
   1432 **                  device.
   1433 **
   1434 ** Returns          void
   1435 **
   1436 *******************************************************************************/
   1437 void gatt_sr_get_sec_info(BD_ADDR rem_bda, tBT_TRANSPORT transport, UINT8 *p_sec_flag, UINT8 *p_key_size)
   1438 {
   1439     UINT8           sec_flag = 0;
   1440 
   1441     BTM_GetSecurityFlagsByTransport(rem_bda, &sec_flag, transport);
   1442 
   1443     sec_flag &= (GATT_SEC_FLAG_LKEY_UNAUTHED | GATT_SEC_FLAG_LKEY_AUTHED | GATT_SEC_FLAG_ENCRYPTED);
   1444 
   1445     *p_key_size = btm_ble_read_sec_key_size(rem_bda);
   1446     *p_sec_flag = sec_flag;
   1447 }
   1448 /*******************************************************************************
   1449 **
   1450 ** Function         gatt_sr_send_req_callback
   1451 **
   1452 ** Description
   1453 **
   1454 **
   1455 ** Returns          void
   1456 **
   1457 *******************************************************************************/
   1458 void gatt_sr_send_req_callback(UINT16 conn_id,
   1459                                UINT32 trans_id,
   1460                                tGATTS_REQ_TYPE type, tGATTS_DATA *p_data)
   1461 {
   1462     tGATT_IF        gatt_if = GATT_GET_GATT_IF(conn_id);
   1463     tGATT_REG       *p_reg = gatt_get_regcb(gatt_if);
   1464 
   1465     if (!p_reg )
   1466     {
   1467         GATT_TRACE_ERROR ("p_reg not found discard request");
   1468         return;
   1469     }
   1470 
   1471     if ( p_reg->in_use &&
   1472          p_reg->app_cb.p_req_cb)
   1473     {
   1474         (*p_reg->app_cb.p_req_cb)(conn_id, trans_id, type, p_data);
   1475     }
   1476     else
   1477     {
   1478         GATT_TRACE_WARNING("Call back not found for application conn_id=%d", conn_id);
   1479     }
   1480 
   1481 }
   1482 
   1483 /*******************************************************************************
   1484 **
   1485 ** Function         gatt_send_error_rsp
   1486 **
   1487 ** Description      This function sends an error response.
   1488 **
   1489 ** Returns          void
   1490 **
   1491 *******************************************************************************/
   1492 tGATT_STATUS gatt_send_error_rsp (tGATT_TCB *p_tcb, UINT8 err_code, UINT8 op_code,
   1493                                   UINT16 handle, BOOLEAN deq)
   1494 {
   1495     tGATT_ERROR      error;
   1496     tGATT_STATUS     status;
   1497     BT_HDR           *p_buf;
   1498 
   1499     error.cmd_code = op_code;
   1500     error.reason = err_code;
   1501     error.handle =handle;
   1502 
   1503     if ((p_buf = attp_build_sr_msg(p_tcb, GATT_RSP_ERROR, (tGATT_SR_MSG *)&error)) != NULL)
   1504     {
   1505         status = attp_send_sr_msg (p_tcb, p_buf);
   1506     }
   1507     else
   1508         status = GATT_INSUF_RESOURCE;
   1509 
   1510     if (deq)
   1511         gatt_dequeue_sr_cmd(p_tcb);
   1512 
   1513     return status;
   1514 }
   1515 
   1516 
   1517 /*******************************************************************************
   1518 **
   1519 ** Function         gatt_add_sdp_record
   1520 **
   1521 ** Description      This function add a SDP record for a GATT primary service
   1522 **
   1523 ** Returns          0 if error else sdp handle for the record.
   1524 **
   1525 *******************************************************************************/
   1526 UINT32 gatt_add_sdp_record (tBT_UUID *p_uuid, UINT16 start_hdl, UINT16 end_hdl)
   1527 {
   1528     tSDP_PROTOCOL_ELEM  proto_elem_list[2];
   1529     UINT32              sdp_handle;
   1530     UINT16              list = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
   1531     UINT8               buff[60];
   1532     UINT8               *p = buff;
   1533 
   1534     GATT_TRACE_DEBUG("gatt_add_sdp_record s_hdl=0x%x  s_hdl=0x%x",start_hdl, end_hdl);
   1535 
   1536     if ((sdp_handle = SDP_CreateRecord()) == 0)
   1537         return 0;
   1538 
   1539     switch (p_uuid->len)
   1540     {
   1541         case LEN_UUID_16:
   1542             SDP_AddServiceClassIdList(sdp_handle, 1, &p_uuid->uu.uuid16);
   1543             break;
   1544 
   1545         case LEN_UUID_32:
   1546             UINT8_TO_BE_STREAM (p, (UUID_DESC_TYPE << 3) | SIZE_FOUR_BYTES);
   1547             UINT32_TO_BE_STREAM (p, p_uuid->uu.uuid32);
   1548             SDP_AddAttribute (sdp_handle, ATTR_ID_SERVICE_CLASS_ID_LIST, DATA_ELE_SEQ_DESC_TYPE,
   1549                               (UINT32) (p - buff), buff);
   1550             break;
   1551 
   1552         case LEN_UUID_128:
   1553             UINT8_TO_BE_STREAM (p, (UUID_DESC_TYPE << 3) | SIZE_SIXTEEN_BYTES);
   1554             ARRAY_TO_BE_STREAM_REVERSE (p, p_uuid->uu.uuid128, LEN_UUID_128);
   1555             SDP_AddAttribute (sdp_handle, ATTR_ID_SERVICE_CLASS_ID_LIST, DATA_ELE_SEQ_DESC_TYPE,
   1556                               (UINT32) (p - buff), buff);
   1557             break;
   1558 
   1559         default:
   1560             GATT_TRACE_ERROR("inavlid UUID len=%d", p_uuid->len);
   1561             SDP_DeleteRecord(sdp_handle);
   1562             return 0;
   1563             break;
   1564     }
   1565 
   1566     /*** Fill out the protocol element sequence for SDP ***/
   1567     proto_elem_list[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
   1568     proto_elem_list[0].num_params    = 1;
   1569     proto_elem_list[0].params[0]     = BT_PSM_ATT;
   1570     proto_elem_list[1].protocol_uuid = UUID_PROTOCOL_ATT;
   1571     proto_elem_list[1].num_params    = 2;
   1572     proto_elem_list[1].params[0]     = start_hdl;
   1573     proto_elem_list[1].params[1]     = end_hdl;
   1574 
   1575     SDP_AddProtocolList(sdp_handle, 2, proto_elem_list);
   1576 
   1577     /* Make the service browseable */
   1578     SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &list);
   1579 
   1580     return(sdp_handle);
   1581 }
   1582 
   1583 
   1584     #if GATT_CONFORMANCE_TESTING == TRUE
   1585 /*******************************************************************************
   1586 **
   1587 ** Function         gatt_set_err_rsp
   1588 **
   1589 ** Description      This function is called to set the test confirm value
   1590 **
   1591 ** Returns          void
   1592 **
   1593 *******************************************************************************/
   1594 void gatt_set_err_rsp(BOOLEAN enable, UINT8 req_op_code, UINT8 err_status)
   1595 {
   1596     GATT_TRACE_DEBUG("gatt_set_err_rsp enable=%d op_code=%d, err_status=%d", enable, req_op_code, err_status);
   1597     gatt_cb.enable_err_rsp  = enable;
   1598     gatt_cb.req_op_code     = req_op_code;
   1599     gatt_cb.err_status      = err_status;
   1600 }
   1601     #endif
   1602 
   1603 
   1604 
   1605 /*******************************************************************************
   1606 **
   1607 ** Function         gatt_get_regcb
   1608 **
   1609 ** Description      The function returns the registration control block.
   1610 **
   1611 ** Returns          pointer to the registration control block or NULL
   1612 **
   1613 *******************************************************************************/
   1614 tGATT_REG *gatt_get_regcb (tGATT_IF gatt_if)
   1615 {
   1616     UINT8           ii = (UINT8)gatt_if;
   1617     tGATT_REG       *p_reg = NULL;
   1618 
   1619     if (ii < 1 || ii > GATT_MAX_APPS) {
   1620         GATT_TRACE_WARNING("gatt_if out of range [ = %d]", ii);
   1621         return NULL;
   1622     }
   1623 
   1624     // Index for cl_rcb is always 1 less than gatt_if.
   1625     p_reg = &gatt_cb.cl_rcb[ii - 1];
   1626 
   1627     if (!p_reg->in_use) {
   1628         GATT_TRACE_WARNING("gatt_if found but not in use.");
   1629         return NULL;
   1630     }
   1631 
   1632     return p_reg;
   1633 }
   1634 
   1635 
   1636 /*******************************************************************************
   1637 **
   1638 ** Function         gatt_is_clcb_allocated
   1639 **
   1640 ** Description      The function check clcb for conn_id is allocated or not
   1641 **
   1642 ** Returns           True already allocated
   1643 **
   1644 *******************************************************************************/
   1645 
   1646 BOOLEAN gatt_is_clcb_allocated (UINT16 conn_id)
   1647 {
   1648     UINT8         i = 0;
   1649     BOOLEAN       is_allocated= FALSE;
   1650 
   1651     for (i = 0; i < GATT_CL_MAX_LCB; i++)
   1652     {
   1653         if (gatt_cb.clcb[i].in_use && (gatt_cb.clcb[i].conn_id == conn_id))
   1654         {
   1655             is_allocated = TRUE;
   1656             break;
   1657         }
   1658     }
   1659 
   1660     return is_allocated;
   1661 }
   1662 
   1663 /*******************************************************************************
   1664 **
   1665 ** Function         gatt_clcb_alloc
   1666 **
   1667 ** Description      The function allocates a GATT  connection link control block
   1668 **
   1669 ** Returns           NULL if not found. Otherwise pointer to the connection link block.
   1670 **
   1671 *******************************************************************************/
   1672 tGATT_CLCB *gatt_clcb_alloc (UINT16 conn_id)
   1673 {
   1674     UINT8           i = 0;
   1675     tGATT_CLCB      *p_clcb = NULL;
   1676     tGATT_IF        gatt_if=GATT_GET_GATT_IF(conn_id);
   1677     UINT8           tcb_idx = GATT_GET_TCB_IDX(conn_id);
   1678     tGATT_TCB       *p_tcb = gatt_get_tcb_by_idx(tcb_idx);
   1679     tGATT_REG       *p_reg = gatt_get_regcb(gatt_if);
   1680 
   1681     for (i = 0; i < GATT_CL_MAX_LCB; i++)
   1682     {
   1683         if (!gatt_cb.clcb[i].in_use)
   1684         {
   1685             p_clcb = &gatt_cb.clcb[i];
   1686 
   1687             p_clcb->in_use      = TRUE;
   1688             p_clcb->conn_id     = conn_id;
   1689             p_clcb->clcb_idx    = i;
   1690             p_clcb->p_reg       = p_reg;
   1691             p_clcb->p_tcb       = p_tcb;
   1692             break;
   1693         }
   1694     }
   1695     return p_clcb;
   1696 }
   1697 
   1698 /*******************************************************************************
   1699 **
   1700 ** Function         gatt_clcb_dealloc
   1701 **
   1702 ** Description      The function de allocates a GATT  connection link control block
   1703 **
   1704 ** Returns         None
   1705 **
   1706 *******************************************************************************/
   1707 void gatt_clcb_dealloc (tGATT_CLCB *p_clcb)
   1708 {
   1709     if (p_clcb && p_clcb->in_use)
   1710     {
   1711         alarm_free(p_clcb->gatt_rsp_timer_ent);
   1712         memset(p_clcb, 0, sizeof(tGATT_CLCB));
   1713     }
   1714 }
   1715 
   1716 
   1717 
   1718 /*******************************************************************************
   1719 **
   1720 ** Function         gatt_find_tcb_by_cid
   1721 **
   1722 ** Description      The function searches for an empty entry
   1723 **                   in registration info table for GATT client
   1724 **
   1725 ** Returns           NULL if not found. Otherwise pointer to the rcb.
   1726 **
   1727 *******************************************************************************/
   1728 tGATT_TCB * gatt_find_tcb_by_cid (UINT16 lcid)
   1729 {
   1730     UINT16       xx = 0;
   1731     tGATT_TCB    *p_tcb = NULL;
   1732 
   1733     for (xx = 0; xx < GATT_MAX_PHY_CHANNEL; xx++)
   1734     {
   1735         if (gatt_cb.tcb[xx].in_use && gatt_cb.tcb[xx].att_lcid == lcid)
   1736         {
   1737             p_tcb = &gatt_cb.tcb[xx];
   1738             break;
   1739         }
   1740     }
   1741     return p_tcb;
   1742 }
   1743 
   1744 
   1745 /*******************************************************************************
   1746 **
   1747 ** Function         gatt_num_apps_hold_link
   1748 **
   1749 ** Description      The function find the number of applcaitions is holding the link
   1750 **
   1751 ** Returns          total number of applications holding this acl link.
   1752 **
   1753 *******************************************************************************/
   1754 UINT8 gatt_num_apps_hold_link(tGATT_TCB *p_tcb)
   1755 {
   1756     UINT8 i, num = 0;
   1757 
   1758     for (i = 0; i < GATT_MAX_APPS; i ++)
   1759     {
   1760         if (p_tcb->app_hold_link[i])
   1761             num ++;
   1762     }
   1763 
   1764     GATT_TRACE_DEBUG("gatt_num_apps_hold_link   num=%d",  num);
   1765     return num;
   1766 }
   1767 
   1768 
   1769 /*******************************************************************************
   1770 **
   1771 ** Function         gatt_num_clcb_by_bd_addr
   1772 **
   1773 ** Description      The function searches all LCB with macthing bd address
   1774 **
   1775 ** Returns          total number of clcb found.
   1776 **
   1777 *******************************************************************************/
   1778 UINT8 gatt_num_clcb_by_bd_addr(BD_ADDR bda)
   1779 {
   1780     UINT8 i, num = 0;
   1781 
   1782     for (i = 0; i < GATT_CL_MAX_LCB; i ++)
   1783     {
   1784         if (gatt_cb.clcb[i].in_use && memcmp(gatt_cb.clcb[i].p_tcb->peer_bda, bda, BD_ADDR_LEN) == 0)
   1785             num ++;
   1786     }
   1787     return num;
   1788 }
   1789 
   1790 /*******************************************************************************
   1791 **
   1792 ** Function         gatt_sr_update_cback_cnt
   1793 **
   1794 ** Description      The function searches all LCB with macthing bd address
   1795 **
   1796 ** Returns          total number of clcb found.
   1797 **
   1798 *******************************************************************************/
   1799 void gatt_sr_copy_prep_cnt_to_cback_cnt(tGATT_TCB *p_tcb )
   1800 {
   1801     UINT8 i;
   1802 
   1803     if (p_tcb)
   1804     {
   1805         for (i = 0; i < GATT_MAX_APPS; i ++)
   1806         {
   1807             if (p_tcb->prep_cnt[i])
   1808             {
   1809                 p_tcb->sr_cmd.cback_cnt[i]=1;
   1810             }
   1811         }
   1812     }
   1813 
   1814 }
   1815 
   1816 /*******************************************************************************
   1817 **
   1818 ** Function         gatt_sr_is_cback_cnt_zero
   1819 **
   1820 ** Description      The function searches all LCB with macthing bd address
   1821 **
   1822 ** Returns          True if thetotal application callback count is zero
   1823 **
   1824 *******************************************************************************/
   1825 BOOLEAN gatt_sr_is_cback_cnt_zero(tGATT_TCB *p_tcb )
   1826 {
   1827     BOOLEAN status = TRUE;
   1828     UINT8   i;
   1829 
   1830     if (p_tcb)
   1831     {
   1832         for (i = 0; i < GATT_MAX_APPS; i ++)
   1833         {
   1834             if (p_tcb->sr_cmd.cback_cnt[i])
   1835             {
   1836                 status = FALSE;
   1837                 break;
   1838             }
   1839         }
   1840     }
   1841     else
   1842     {
   1843         status = FALSE;
   1844     }
   1845     return status;
   1846 }
   1847 
   1848 /*******************************************************************************
   1849 **
   1850 ** Function         gatt_sr_is_prep_cnt_zero
   1851 **
   1852 ** Description      Check the prepare write request count is zero or not
   1853 **
   1854 ** Returns          True no prepare write request
   1855 **
   1856 *******************************************************************************/
   1857 BOOLEAN gatt_sr_is_prep_cnt_zero(tGATT_TCB *p_tcb)
   1858 {
   1859     BOOLEAN status = TRUE;
   1860     UINT8   i;
   1861 
   1862     if (p_tcb)
   1863     {
   1864         for (i = 0; i < GATT_MAX_APPS; i ++)
   1865         {
   1866             if (p_tcb->prep_cnt[i])
   1867             {
   1868                 status = FALSE;
   1869                 break;
   1870             }
   1871         }
   1872     }
   1873     else
   1874     {
   1875         status = FALSE;
   1876     }
   1877     return status;
   1878 }
   1879 
   1880 
   1881 /*******************************************************************************
   1882 **
   1883 ** Function         gatt_sr_reset_cback_cnt
   1884 **
   1885 ** Description      Reset the application callback count to zero
   1886 **
   1887 ** Returns         None
   1888 **
   1889 *******************************************************************************/
   1890 void gatt_sr_reset_cback_cnt(tGATT_TCB *p_tcb )
   1891 {
   1892     UINT8 i;
   1893 
   1894     if (p_tcb)
   1895     {
   1896         for (i = 0; i < GATT_MAX_APPS; i ++)
   1897         {
   1898             p_tcb->sr_cmd.cback_cnt[i]=0;
   1899         }
   1900     }
   1901 }
   1902 
   1903 /*******************************************************************************
   1904 **
   1905 ** Function         gatt_sr_reset_prep_cnt
   1906 **
   1907 ** Description     Reset the prep write count to zero
   1908 **
   1909 ** Returns        None
   1910 **
   1911 *******************************************************************************/
   1912 void gatt_sr_reset_prep_cnt(tGATT_TCB *p_tcb )
   1913 {
   1914     UINT8 i;
   1915     if (p_tcb)
   1916     {
   1917         for (i = 0; i < GATT_MAX_APPS; i ++)
   1918         {
   1919             p_tcb->prep_cnt[i]=0;
   1920         }
   1921     }
   1922 }
   1923 
   1924 
   1925 /*******************************************************************************
   1926 **
   1927 ** Function         gatt_sr_update_cback_cnt
   1928 **
   1929 ** Description    Update the teh applicaiton callback count
   1930 **
   1931 ** Returns           None
   1932 **
   1933 *******************************************************************************/
   1934 void gatt_sr_update_cback_cnt(tGATT_TCB *p_tcb, tGATT_IF gatt_if, BOOLEAN is_inc, BOOLEAN is_reset_first)
   1935 {
   1936 
   1937     UINT8 idx = ((UINT8) gatt_if) - 1 ;
   1938 
   1939     if (p_tcb)
   1940     {
   1941         if (is_reset_first)
   1942         {
   1943             gatt_sr_reset_cback_cnt(p_tcb);
   1944         }
   1945         if (is_inc)
   1946         {
   1947             p_tcb->sr_cmd.cback_cnt[idx]++;
   1948         }
   1949         else
   1950         {
   1951             if ( p_tcb->sr_cmd.cback_cnt[idx])
   1952             {
   1953                 p_tcb->sr_cmd.cback_cnt[idx]--;
   1954             }
   1955         }
   1956     }
   1957 }
   1958 
   1959 
   1960 /*******************************************************************************
   1961 **
   1962 ** Function         gatt_sr_update_prep_cnt
   1963 **
   1964 ** Description    Update the teh prepare write request count
   1965 **
   1966 ** Returns           None
   1967 **
   1968 *******************************************************************************/
   1969 void gatt_sr_update_prep_cnt(tGATT_TCB *p_tcb, tGATT_IF gatt_if, BOOLEAN is_inc, BOOLEAN is_reset_first)
   1970 {
   1971     UINT8 idx = ((UINT8) gatt_if) - 1 ;
   1972 
   1973     GATT_TRACE_DEBUG("gatt_sr_update_prep_cnt tcb idx=%d gatt_if=%d is_inc=%d is_reset_first=%d",
   1974                       p_tcb->tcb_idx, gatt_if, is_inc, is_reset_first);
   1975 
   1976     if (p_tcb)
   1977     {
   1978         if (is_reset_first)
   1979         {
   1980             gatt_sr_reset_prep_cnt(p_tcb);
   1981         }
   1982         if (is_inc)
   1983         {
   1984             p_tcb->prep_cnt[idx]++;
   1985         }
   1986         else
   1987         {
   1988             if (p_tcb->prep_cnt[idx])
   1989             {
   1990                 p_tcb->prep_cnt[idx]--;
   1991             }
   1992         }
   1993     }
   1994 }
   1995 /*******************************************************************************
   1996 **
   1997 ** Function         gatt_cancel_open
   1998 **
   1999 ** Description      Cancel open request
   2000 **
   2001 ** Returns         Boolean
   2002 **
   2003 *******************************************************************************/
   2004 BOOLEAN gatt_cancel_open(tGATT_IF gatt_if, BD_ADDR bda)
   2005 {
   2006     tGATT_TCB *p_tcb=NULL;
   2007     BOOLEAN status= TRUE;
   2008 
   2009     p_tcb = gatt_find_tcb_by_addr(bda, BT_TRANSPORT_LE);
   2010 
   2011     if (p_tcb)
   2012     {
   2013         if (gatt_get_ch_state(p_tcb) == GATT_CH_OPEN)
   2014         {
   2015             GATT_TRACE_ERROR("GATT_CancelConnect - link connected Too late to cancel");
   2016             status = FALSE;
   2017         }
   2018         else
   2019         {
   2020             gatt_update_app_use_link_flag(gatt_if, p_tcb, FALSE, FALSE);
   2021             if (!gatt_num_apps_hold_link(p_tcb))
   2022             {
   2023                 gatt_disconnect(p_tcb);
   2024             }
   2025         }
   2026     }
   2027 
   2028     return status;
   2029 }
   2030 
   2031 /*******************************************************************************
   2032 **
   2033 ** Function         gatt_find_app_hold_link
   2034 **
   2035 ** Description      find the applicaiton that is holding the specified link
   2036 **
   2037 ** Returns         Boolean
   2038 **
   2039 *******************************************************************************/
   2040 BOOLEAN gatt_find_app_hold_link(tGATT_TCB *p_tcb, UINT8 start_idx, UINT8 *p_found_idx, tGATT_IF *p_gatt_if)
   2041 {
   2042     UINT8 i;
   2043     BOOLEAN found= FALSE;
   2044 
   2045     for (i = start_idx; i < GATT_MAX_APPS; i ++)
   2046     {
   2047         if (p_tcb->app_hold_link[i])
   2048         {
   2049             *p_gatt_if = gatt_cb.clcb[i].p_reg->gatt_if;
   2050             *p_found_idx = i;
   2051             found = TRUE;
   2052             break;
   2053         }
   2054     }
   2055     return found;
   2056 }
   2057 
   2058 /*******************************************************************************
   2059 **
   2060 ** Function         gatt_cmd_enq
   2061 **
   2062 ** Description      Enqueue this command.
   2063 **
   2064 ** Returns          None.
   2065 **
   2066 *******************************************************************************/
   2067 BOOLEAN gatt_cmd_enq(tGATT_TCB *p_tcb, UINT16 clcb_idx, BOOLEAN to_send, UINT8 op_code, BT_HDR *p_buf)
   2068 {
   2069     tGATT_CMD_Q  *p_cmd = &p_tcb->cl_cmd_q[p_tcb->next_slot_inq];
   2070 
   2071     p_cmd->to_send = to_send; /* waiting to be sent */
   2072     p_cmd->op_code  = op_code;
   2073     p_cmd->p_cmd    = p_buf;
   2074     p_cmd->clcb_idx = clcb_idx;
   2075 
   2076     if (!to_send)
   2077     {
   2078         p_tcb->pending_cl_req = p_tcb->next_slot_inq;
   2079     }
   2080 
   2081     p_tcb->next_slot_inq ++;
   2082     p_tcb->next_slot_inq %= GATT_CL_MAX_LCB;
   2083 
   2084     return TRUE;
   2085 }
   2086 
   2087 /*******************************************************************************
   2088 **
   2089 ** Function         gatt_cmd_dequeue
   2090 **
   2091 ** Description      dequeue the command in the client CCB command queue.
   2092 **
   2093 ** Returns          total number of clcb found.
   2094 **
   2095 *******************************************************************************/
   2096 tGATT_CLCB * gatt_cmd_dequeue(tGATT_TCB *p_tcb, UINT8 *p_op_code)
   2097 {
   2098     tGATT_CMD_Q  *p_cmd = &p_tcb->cl_cmd_q[p_tcb->pending_cl_req];
   2099     tGATT_CLCB *p_clcb = NULL;
   2100 
   2101     if (p_tcb->pending_cl_req != p_tcb->next_slot_inq)
   2102     {
   2103         p_clcb = &gatt_cb.clcb[p_cmd->clcb_idx];
   2104 
   2105         *p_op_code = p_cmd->op_code;
   2106 
   2107         p_tcb->pending_cl_req ++;
   2108         p_tcb->pending_cl_req %= GATT_CL_MAX_LCB;
   2109     }
   2110 
   2111     return p_clcb;
   2112 }
   2113 
   2114 /*******************************************************************************
   2115 **
   2116 ** Function         gatt_send_write_msg
   2117 **
   2118 ** Description      This real function send out the ATT message for write.
   2119 **
   2120 ** Returns          status code
   2121 **
   2122 *******************************************************************************/
   2123 UINT8 gatt_send_write_msg (tGATT_TCB *p_tcb, UINT16 clcb_idx, UINT8 op_code,
   2124                            UINT16 handle, UINT16 len,
   2125                            UINT16 offset, UINT8 *p_data)
   2126 {
   2127     tGATT_CL_MSG     msg;
   2128 
   2129     msg.attr_value.handle = handle;
   2130     msg.attr_value.len = len;
   2131     msg.attr_value.offset = offset;
   2132 
   2133     memcpy (msg.attr_value.value, p_data, len);
   2134 
   2135     /* write by handle */
   2136     return attp_send_cl_msg(p_tcb, clcb_idx, op_code, &msg);
   2137 }
   2138 
   2139 /*******************************************************************************
   2140 **
   2141 ** Function         gatt_act_send_browse
   2142 **
   2143 ** Description      This function ends a browse command request, including read
   2144 **                  information request and read by type request.
   2145 **
   2146 ** Returns          status code
   2147 **
   2148 *******************************************************************************/
   2149 UINT8 gatt_act_send_browse(tGATT_TCB *p_tcb, UINT16 index, UINT8 op, UINT16 s_handle,
   2150                            UINT16 e_handle, tBT_UUID uuid)
   2151 {
   2152     tGATT_CL_MSG     msg;
   2153 
   2154     msg.browse.s_handle = s_handle;
   2155     msg.browse.e_handle   = e_handle;
   2156     memcpy(&msg.browse.uuid, &uuid, sizeof(tBT_UUID));
   2157 
   2158     /* write by handle */
   2159     return attp_send_cl_msg(p_tcb, index, op, &msg);
   2160 }
   2161 
   2162 /*******************************************************************************
   2163 **
   2164 ** Function         gatt_end_operation
   2165 **
   2166 ** Description      This function ends a discovery, send callback and finalize
   2167 **                  some control value.
   2168 **
   2169 ** Returns          16 bits uuid.
   2170 **
   2171 *******************************************************************************/
   2172 void gatt_end_operation(tGATT_CLCB *p_clcb, tGATT_STATUS status, void *p_data)
   2173 {
   2174     tGATT_CL_COMPLETE   cb_data;
   2175     tGATT_CMPL_CBACK    *p_cmpl_cb = (p_clcb->p_reg) ? p_clcb->p_reg->app_cb.p_cmpl_cb : NULL;
   2176     UINT8               op = p_clcb->operation, disc_type=GATT_DISC_MAX;
   2177     tGATT_DISC_CMPL_CB  *p_disc_cmpl_cb = (p_clcb->p_reg) ? p_clcb->p_reg->app_cb.p_disc_cmpl_cb : NULL;
   2178     UINT16              conn_id;
   2179     UINT8               operation;
   2180 
   2181     GATT_TRACE_DEBUG ("gatt_end_operation status=%d op=%d subtype=%d",
   2182                        status, p_clcb->operation, p_clcb->op_subtype);
   2183     memset(&cb_data.att_value, 0, sizeof(tGATT_VALUE));
   2184 
   2185     if (p_cmpl_cb != NULL && p_clcb->operation != 0)
   2186     {
   2187         if (p_clcb->operation == GATTC_OPTYPE_READ)
   2188         {
   2189             cb_data.att_value.handle   = p_clcb->s_handle;
   2190             cb_data.att_value.len      = p_clcb->counter;
   2191 
   2192             if (p_data && p_clcb->counter)
   2193                 memcpy (cb_data.att_value.value, p_data, cb_data.att_value.len);
   2194         }
   2195 
   2196         if (p_clcb->operation == GATTC_OPTYPE_WRITE)
   2197         {
   2198             memset(&cb_data.att_value, 0, sizeof(tGATT_VALUE));
   2199             cb_data.handle           =
   2200             cb_data.att_value.handle = p_clcb->s_handle;
   2201             if (p_clcb->op_subtype == GATT_WRITE_PREPARE)
   2202             {
   2203                 if (p_data)
   2204                 {
   2205                     cb_data.att_value = *((tGATT_VALUE *) p_data);
   2206                 }
   2207                 else
   2208                 {
   2209                     GATT_TRACE_DEBUG("Rcv Prepare write rsp but no data");
   2210                 }
   2211             }
   2212         }
   2213 
   2214         if (p_clcb->operation == GATTC_OPTYPE_CONFIG)
   2215             cb_data.mtu = p_clcb->p_tcb->payload_size;
   2216 
   2217         if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY)
   2218         {
   2219             disc_type = p_clcb->op_subtype;
   2220         }
   2221     }
   2222 
   2223     osi_free_and_reset((void **)&p_clcb->p_attr_buf);
   2224 
   2225     operation =  p_clcb->operation;
   2226     conn_id = p_clcb->conn_id;
   2227     alarm_cancel(p_clcb->gatt_rsp_timer_ent);
   2228 
   2229     gatt_clcb_dealloc(p_clcb);
   2230 
   2231     if (p_disc_cmpl_cb && (op == GATTC_OPTYPE_DISCOVERY))
   2232         (*p_disc_cmpl_cb)(conn_id, disc_type, status);
   2233     else if (p_cmpl_cb && op)
   2234         (*p_cmpl_cb)(conn_id, op, status, &cb_data);
   2235     else
   2236         GATT_TRACE_WARNING ("gatt_end_operation not sent out op=%d p_disc_cmpl_cb:%p p_cmpl_cb:%p",
   2237                              operation, p_disc_cmpl_cb, p_cmpl_cb);
   2238 }
   2239 
   2240 /*******************************************************************************
   2241 **
   2242 ** Function         gatt_cleanup_upon_disc
   2243 **
   2244 ** Description      This function cleans up the control blocks when L2CAP channel
   2245 **                  disconnect.
   2246 **
   2247 ** Returns          16 bits uuid.
   2248 **
   2249 *******************************************************************************/
   2250 void gatt_cleanup_upon_disc(BD_ADDR bda, UINT16 reason, tBT_TRANSPORT transport)
   2251 {
   2252     tGATT_TCB       *p_tcb = NULL;
   2253     tGATT_CLCB      *p_clcb;
   2254     UINT8           i;
   2255     UINT16          conn_id;
   2256     tGATT_REG        *p_reg=NULL;
   2257 
   2258 
   2259     GATT_TRACE_DEBUG ("gatt_cleanup_upon_disc ");
   2260 
   2261     if ((p_tcb = gatt_find_tcb_by_addr(bda, transport)) != NULL)
   2262     {
   2263         GATT_TRACE_DEBUG ("found p_tcb ");
   2264         gatt_set_ch_state(p_tcb, GATT_CH_CLOSE);
   2265         for (i = 0; i < GATT_CL_MAX_LCB; i ++)
   2266         {
   2267             p_clcb = &gatt_cb.clcb[i];
   2268             if (p_clcb->in_use && p_clcb->p_tcb == p_tcb)
   2269             {
   2270                 alarm_cancel(p_clcb->gatt_rsp_timer_ent);
   2271                 GATT_TRACE_DEBUG ("found p_clcb conn_id=%d clcb_idx=%d", p_clcb->conn_id, p_clcb->clcb_idx);
   2272                 if (p_clcb->operation != GATTC_OPTYPE_NONE)
   2273                     gatt_end_operation(p_clcb, GATT_ERROR, NULL);
   2274 
   2275                 gatt_clcb_dealloc(p_clcb);
   2276 
   2277             }
   2278         }
   2279 
   2280         alarm_free(p_tcb->ind_ack_timer);
   2281         p_tcb->ind_ack_timer = NULL;
   2282         alarm_free(p_tcb->conf_timer);
   2283         p_tcb->conf_timer = NULL;
   2284         gatt_free_pending_ind(p_tcb);
   2285         gatt_free_pending_enc_queue(p_tcb);
   2286         fixed_queue_free(p_tcb->sr_cmd.multi_rsp_q, NULL);
   2287         p_tcb->sr_cmd.multi_rsp_q = NULL;
   2288 
   2289         for (i = 0; i < GATT_MAX_APPS; i ++)
   2290         {
   2291             p_reg = &gatt_cb.cl_rcb[i];
   2292             if (p_reg->in_use && p_reg->app_cb.p_conn_cb)
   2293             {
   2294                 conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if);
   2295                 GATT_TRACE_DEBUG ("found p_reg tcb_idx=%d gatt_if=%d  conn_id=0x%x", p_tcb->tcb_idx, p_reg->gatt_if, conn_id);
   2296                 (*p_reg->app_cb.p_conn_cb)(p_reg->gatt_if,  bda, conn_id, FALSE, reason, transport);
   2297             }
   2298         }
   2299         memset(p_tcb, 0, sizeof(tGATT_TCB));
   2300 
   2301     }
   2302     GATT_TRACE_DEBUG ("exit gatt_cleanup_upon_disc ");
   2303 }
   2304 /*******************************************************************************
   2305 **
   2306 ** Function         gatt_dbg_req_op_name
   2307 **
   2308 ** Description      Get op code description name, for debug information.
   2309 **
   2310 ** Returns          UINT8 *: name of the operation.
   2311 **
   2312 *******************************************************************************/
   2313 UINT8 * gatt_dbg_op_name(UINT8 op_code)
   2314 {
   2315     UINT8 pseduo_op_code_idx = op_code & (~GATT_WRITE_CMD_MASK);
   2316 
   2317     if (op_code == GATT_CMD_WRITE )
   2318     {
   2319         pseduo_op_code_idx = 0x14; /* just an index to op_code_name */
   2320 
   2321     }
   2322 
   2323     if (op_code == GATT_SIGN_CMD_WRITE)
   2324     {
   2325         pseduo_op_code_idx = 0x15; /* just an index to op_code_name */
   2326     }
   2327 
   2328     if (pseduo_op_code_idx <= GATT_OP_CODE_MAX)
   2329         return(UINT8*) op_code_name[pseduo_op_code_idx];
   2330     else
   2331         return(UINT8 *)"Op Code Exceed Max";
   2332 }
   2333 
   2334 /*******************************************************************************
   2335 **
   2336 ** Function         gatt_dbg_display_uuid
   2337 **
   2338 ** Description      Disaplay the UUID
   2339 **
   2340 ** Returns          None
   2341 **
   2342 *******************************************************************************/
   2343 void gatt_dbg_display_uuid(tBT_UUID bt_uuid)
   2344 {
   2345     char str_buf[50];
   2346     int x = 0;
   2347 
   2348     if (bt_uuid.len == LEN_UUID_16)
   2349     {
   2350         sprintf(str_buf, "0x%04x", bt_uuid.uu.uuid16);
   2351     }
   2352     else if (bt_uuid.len == LEN_UUID_32)
   2353     {
   2354         sprintf(str_buf, "0x%08x", (unsigned int)bt_uuid.uu.uuid32);
   2355     }
   2356     else if (bt_uuid.len == LEN_UUID_128)
   2357     {
   2358         x += sprintf(&str_buf[x], "0x%02x%02x%02x%02x%02x%02x%02x%02x",
   2359                      bt_uuid.uu.uuid128[15], bt_uuid.uu.uuid128[14],
   2360                      bt_uuid.uu.uuid128[13], bt_uuid.uu.uuid128[12],
   2361                      bt_uuid.uu.uuid128[11], bt_uuid.uu.uuid128[10],
   2362                      bt_uuid.uu.uuid128[9], bt_uuid.uu.uuid128[8]);
   2363         sprintf(&str_buf[x], "%02x%02x%02x%02x%02x%02x%02x%02x",
   2364                 bt_uuid.uu.uuid128[7], bt_uuid.uu.uuid128[6],
   2365                 bt_uuid.uu.uuid128[5], bt_uuid.uu.uuid128[4],
   2366                 bt_uuid.uu.uuid128[3], bt_uuid.uu.uuid128[2],
   2367                 bt_uuid.uu.uuid128[1], bt_uuid.uu.uuid128[0]);
   2368     }
   2369     else
   2370         strlcpy(str_buf, "Unknown UUID 0", sizeof(str_buf));
   2371 
   2372     GATT_TRACE_DEBUG ("UUID=[%s]", str_buf);
   2373 }
   2374 
   2375 
   2376 /*******************************************************************************
   2377 **
   2378 ** Function         gatt_is_bg_dev_for_app
   2379 **
   2380 ** Description      find is this one of the background devices for the application
   2381 **
   2382 ** Returns          TRUE this is one of the background devices for the  application
   2383 **
   2384 *******************************************************************************/
   2385 BOOLEAN gatt_is_bg_dev_for_app(tGATT_BG_CONN_DEV *p_dev, tGATT_IF gatt_if)
   2386 {
   2387     UINT8   i;
   2388 
   2389     for (i = 0; i < GATT_MAX_APPS; i ++ )
   2390     {
   2391         if (p_dev->in_use && (p_dev->gatt_if[i] == gatt_if))
   2392         {
   2393             return TRUE;
   2394         }
   2395     }
   2396     return FALSE;
   2397 }
   2398 /*******************************************************************************
   2399 **
   2400 ** Function         gatt_find_bg_dev
   2401 **
   2402 ** Description      find background connection device from the list.
   2403 **
   2404 ** Returns          pointer to the device record
   2405 **
   2406 *******************************************************************************/
   2407 tGATT_BG_CONN_DEV * gatt_find_bg_dev(BD_ADDR remote_bda)
   2408 {
   2409     tGATT_BG_CONN_DEV    *p_dev_list = &gatt_cb.bgconn_dev[0];
   2410     UINT8   i;
   2411 
   2412     for (i = 0; i < GATT_MAX_BG_CONN_DEV; i ++, p_dev_list ++)
   2413     {
   2414         if (p_dev_list->in_use && !memcmp(p_dev_list->remote_bda, remote_bda, BD_ADDR_LEN))
   2415         {
   2416             return p_dev_list;
   2417         }
   2418     }
   2419     return NULL;
   2420 }
   2421 /*******************************************************************************
   2422 **
   2423 ** Function         gatt_alloc_bg_dev
   2424 **
   2425 ** Description      allocate a background connection device record
   2426 **
   2427 ** Returns          pointer to the device record
   2428 **
   2429 *******************************************************************************/
   2430 tGATT_BG_CONN_DEV * gatt_alloc_bg_dev(BD_ADDR remote_bda)
   2431 {
   2432     tGATT_BG_CONN_DEV    *p_dev_list = &gatt_cb.bgconn_dev[0];
   2433     UINT8   i;
   2434 
   2435     for (i = 0; i < GATT_MAX_BG_CONN_DEV; i ++, p_dev_list ++)
   2436     {
   2437         if (!p_dev_list->in_use)
   2438         {
   2439             p_dev_list->in_use = TRUE;
   2440             memcpy(p_dev_list->remote_bda, remote_bda, BD_ADDR_LEN);
   2441 
   2442             return p_dev_list;
   2443         }
   2444     }
   2445     return NULL;
   2446 }
   2447 
   2448 /*******************************************************************************
   2449 **
   2450 ** Function         gatt_add_bg_dev_list
   2451 **
   2452 ** Description      add/remove device from the back ground connection device list
   2453 **
   2454 ** Returns          TRUE if device added to the list; FALSE failed
   2455 **
   2456 *******************************************************************************/
   2457 BOOLEAN gatt_add_bg_dev_list(tGATT_REG *p_reg,  BD_ADDR bd_addr, BOOLEAN is_initator)
   2458 {
   2459     tGATT_IF gatt_if =  p_reg->gatt_if;
   2460     tGATT_BG_CONN_DEV   *p_dev = NULL;
   2461     UINT8       i;
   2462     BOOLEAN      ret = FALSE;
   2463 
   2464     if ((p_dev = gatt_find_bg_dev(bd_addr)) == NULL)
   2465     {
   2466         p_dev = gatt_alloc_bg_dev(bd_addr);
   2467     }
   2468 
   2469     if (p_dev)
   2470     {
   2471         for (i = 0; i < GATT_MAX_APPS; i ++)
   2472         {
   2473             if (is_initator)
   2474             {
   2475                 if (p_dev->gatt_if[i] == gatt_if)
   2476                 {
   2477                     GATT_TRACE_ERROR("device already in iniator white list");
   2478                     return TRUE;
   2479                 }
   2480                 else if (p_dev->gatt_if[i] == 0)
   2481                 {
   2482                     p_dev->gatt_if[i] = gatt_if;
   2483                     if (i == 0)
   2484                         ret = BTM_BleUpdateBgConnDev(TRUE, bd_addr);
   2485                     else
   2486                         ret = TRUE;
   2487                     break;
   2488                 }
   2489             }
   2490             else
   2491             {
   2492                 if (p_dev->listen_gif[i] == gatt_if)
   2493                 {
   2494                     GATT_TRACE_ERROR("device already in adv white list");
   2495                     return TRUE;
   2496                 }
   2497                 else if (p_dev->listen_gif[i] == 0)
   2498                 {
   2499                     if (p_reg->listening == GATT_LISTEN_TO_ALL)
   2500                         p_reg->listening = GATT_LISTEN_TO_NONE;
   2501 
   2502                     p_reg->listening ++;
   2503                     p_dev->listen_gif[i] = gatt_if;
   2504 
   2505                     if (i == 0)
   2506                         ret = BTM_BleUpdateAdvWhitelist(TRUE, bd_addr);
   2507                     else
   2508                         ret = TRUE;
   2509                     break;
   2510                 }
   2511             }
   2512         }
   2513     }
   2514     else
   2515     {
   2516         GATT_TRACE_ERROR("no device record available");
   2517     }
   2518 
   2519     return ret;
   2520 }
   2521 
   2522 /*******************************************************************************
   2523 **
   2524 ** Function         gatt_remove_bg_dev_for_app
   2525 **
   2526 ** Description      Remove the application interface for the specified background device
   2527 **
   2528 ** Returns          Boolean
   2529 **
   2530 *******************************************************************************/
   2531 BOOLEAN gatt_remove_bg_dev_for_app(tGATT_IF gatt_if, BD_ADDR bd_addr)
   2532 {
   2533     tGATT_TCB    *p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE);
   2534     BOOLEAN       status;
   2535 
   2536     if (p_tcb)
   2537         gatt_update_app_use_link_flag(gatt_if, p_tcb, FALSE, FALSE);
   2538     status = gatt_update_auto_connect_dev(gatt_if, FALSE, bd_addr, TRUE);
   2539     return status;
   2540 }
   2541 
   2542 
   2543 /*******************************************************************************
   2544 **
   2545 ** Function         gatt_get_num_apps_for_bg_dev
   2546 **
   2547 ** Description      Gte the number of applciations for the specified background device
   2548 **
   2549 ** Returns          UINT8 total number fo applications
   2550 **
   2551 *******************************************************************************/
   2552 UINT8 gatt_get_num_apps_for_bg_dev(BD_ADDR bd_addr)
   2553 {
   2554     tGATT_BG_CONN_DEV   *p_dev = NULL;
   2555     UINT8   i;
   2556     UINT8   cnt = 0;
   2557 
   2558     if ((p_dev = gatt_find_bg_dev(bd_addr)) != NULL)
   2559     {
   2560         for (i = 0; i < GATT_MAX_APPS; i ++)
   2561         {
   2562             if (p_dev->gatt_if[i])
   2563                 cnt++;
   2564         }
   2565     }
   2566     return cnt;
   2567 }
   2568 
   2569 /*******************************************************************************
   2570 **
   2571 ** Function         gatt_find_app_for_bg_dev
   2572 **
   2573 ** Description      find the application interface for the specified background device
   2574 **
   2575 ** Returns          Boolean
   2576 **
   2577 *******************************************************************************/
   2578 BOOLEAN gatt_find_app_for_bg_dev(BD_ADDR bd_addr, tGATT_IF *p_gatt_if)
   2579 {
   2580     tGATT_BG_CONN_DEV   *p_dev = NULL;
   2581     UINT8   i;
   2582     BOOLEAN ret = FALSE;
   2583 
   2584     if ((p_dev = gatt_find_bg_dev(bd_addr)) == NULL)
   2585     {
   2586         return ret;
   2587     }
   2588 
   2589     for (i = 0; i < GATT_MAX_APPS; i ++)
   2590     {
   2591         if (p_dev->gatt_if[i] != 0 )
   2592         {
   2593             *p_gatt_if = p_dev->gatt_if[i];
   2594             ret = TRUE;
   2595             break;
   2596         }
   2597     }
   2598     return ret;
   2599 }
   2600 
   2601 
   2602 /*******************************************************************************
   2603 **
   2604 ** Function         gatt_remove_bg_dev_from_list
   2605 **
   2606 ** Description      add/remove device from the back ground connection device list or
   2607 **                  listening to advertising list.
   2608 **
   2609 ** Returns          pointer to the device record
   2610 **
   2611 *******************************************************************************/
   2612 BOOLEAN gatt_remove_bg_dev_from_list(tGATT_REG *p_reg, BD_ADDR bd_addr, BOOLEAN is_initiator)
   2613 {
   2614     tGATT_IF gatt_if = p_reg->gatt_if;
   2615     tGATT_BG_CONN_DEV   *p_dev = NULL;
   2616     UINT8   i, j;
   2617     BOOLEAN ret = FALSE;
   2618 
   2619     if ((p_dev = gatt_find_bg_dev(bd_addr)) == NULL)
   2620     {
   2621         return ret;
   2622     }
   2623 
   2624     for (i = 0; i < GATT_MAX_APPS && (p_dev->gatt_if[i] > 0 || p_dev->listen_gif[i]); i ++)
   2625     {
   2626         if (is_initiator)
   2627         {
   2628             if (p_dev->gatt_if[i] == gatt_if)
   2629             {
   2630                 p_dev->gatt_if[i] = 0;
   2631                 /* move all element behind one forward */
   2632                 for (j = i + 1; j < GATT_MAX_APPS; j ++)
   2633                     p_dev->gatt_if[j - 1] = p_dev->gatt_if[j];
   2634 
   2635                 if (p_dev->gatt_if[0] == 0)
   2636                     ret = BTM_BleUpdateBgConnDev(FALSE, p_dev->remote_bda);
   2637                 else
   2638                     ret = TRUE;
   2639 
   2640                 break;
   2641             }
   2642         }
   2643         else
   2644         {
   2645             if (p_dev->listen_gif[i] == gatt_if)
   2646             {
   2647                 p_dev->listen_gif[i] = 0;
   2648                 p_reg->listening --;
   2649                 /* move all element behind one forward */
   2650                 for (j = i + 1; j < GATT_MAX_APPS; j ++)
   2651                     p_dev->listen_gif[j - 1] = p_dev->listen_gif[j];
   2652 
   2653                 if (p_dev->listen_gif[0] == 0)
   2654                     ret = BTM_BleUpdateAdvWhitelist(FALSE, p_dev->remote_bda);
   2655                 else
   2656                     ret = TRUE;
   2657                 break;
   2658             }
   2659         }
   2660     }
   2661 
   2662     if (i != GATT_MAX_APPS && p_dev->gatt_if[0] == 0 && p_dev->listen_gif[0] == 0)
   2663     {
   2664         memset(p_dev, 0, sizeof(tGATT_BG_CONN_DEV));
   2665     }
   2666 
   2667     return ret;
   2668 }
   2669 /*******************************************************************************
   2670 **
   2671 ** Function         gatt_deregister_bgdev_list
   2672 **
   2673 ** Description      deregister all related back ground connetion device.
   2674 **
   2675 ** Returns          pointer to the device record
   2676 **
   2677 *******************************************************************************/
   2678 void gatt_deregister_bgdev_list(tGATT_IF gatt_if)
   2679 {
   2680     tGATT_BG_CONN_DEV    *p_dev_list = &gatt_cb.bgconn_dev[0];
   2681     UINT8 i , j, k;
   2682     tGATT_REG       *p_reg = gatt_get_regcb(gatt_if);
   2683 
   2684     /* update the BG conn device list */
   2685     for (i = 0 ; i <GATT_MAX_BG_CONN_DEV; i ++, p_dev_list ++ )
   2686     {
   2687         if (p_dev_list->in_use)
   2688         {
   2689             for (j = 0; j < GATT_MAX_APPS; j ++)
   2690             {
   2691                 if (p_dev_list->gatt_if[j] == 0 && p_dev_list->listen_gif[j] == 0)
   2692                     break;
   2693 
   2694                 if (p_dev_list->gatt_if[j] == gatt_if)
   2695                 {
   2696                     for (k = j + 1; k < GATT_MAX_APPS; k ++)
   2697                         p_dev_list->gatt_if[k - 1] = p_dev_list->gatt_if[k];
   2698 
   2699                     if (p_dev_list->gatt_if[0] == 0)
   2700                         BTM_BleUpdateBgConnDev(FALSE, p_dev_list->remote_bda);
   2701                 }
   2702 
   2703                 if (p_dev_list->listen_gif[j] == gatt_if)
   2704                 {
   2705                     p_dev_list->listen_gif[j] = 0;
   2706 
   2707                     if (p_reg != NULL && p_reg->listening > 0)
   2708                         p_reg->listening --;
   2709 
   2710                     /* move all element behind one forward */
   2711                     for (k = j + 1; k < GATT_MAX_APPS; k ++)
   2712                         p_dev_list->listen_gif[k - 1] = p_dev_list->listen_gif[k];
   2713 
   2714                     if (p_dev_list->listen_gif[0] == 0)
   2715                         BTM_BleUpdateAdvWhitelist(FALSE, p_dev_list->remote_bda);
   2716                 }
   2717             }
   2718         }
   2719     }
   2720 }
   2721 
   2722 
   2723 /*******************************************************************************
   2724 **
   2725 ** Function         gatt_reset_bgdev_list
   2726 **
   2727 ** Description      reset bg device list
   2728 **
   2729 ** Returns          pointer to the device record
   2730 **
   2731 *******************************************************************************/
   2732 void gatt_reset_bgdev_list(void)
   2733 {
   2734     memset(&gatt_cb.bgconn_dev, 0 , sizeof(tGATT_BG_CONN_DEV)*GATT_MAX_BG_CONN_DEV);
   2735 
   2736 }
   2737 /*******************************************************************************
   2738 **
   2739 ** Function         gatt_update_auto_connect_dev
   2740 **
   2741 ** Description      This function add or remove a device for background connection
   2742 **                  procedure.
   2743 **
   2744 ** Parameters       gatt_if: Application ID.
   2745 **                  add: add peer device
   2746 **                  bd_addr: peer device address.
   2747 **
   2748 ** Returns          TRUE if connection started; FALSE if connection start failure.
   2749 **
   2750 *******************************************************************************/
   2751 BOOLEAN gatt_update_auto_connect_dev (tGATT_IF gatt_if, BOOLEAN add, BD_ADDR bd_addr, BOOLEAN is_initator)
   2752 {
   2753     BOOLEAN         ret = FALSE;
   2754     tGATT_REG        *p_reg;
   2755     tGATT_TCB       *p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE);
   2756 
   2757     GATT_TRACE_API ("gatt_update_auto_connect_dev ");
   2758     /* Make sure app is registered */
   2759     if ((p_reg = gatt_get_regcb(gatt_if)) == NULL)
   2760     {
   2761         GATT_TRACE_ERROR("gatt_update_auto_connect_dev - gatt_if is not registered", gatt_if);
   2762         return(FALSE);
   2763     }
   2764 
   2765     if (add)
   2766     {
   2767         ret = gatt_add_bg_dev_list(p_reg, bd_addr, is_initator);
   2768 
   2769         if (ret && p_tcb != NULL)
   2770         {
   2771             /* if a connected device, update the link holding number */
   2772             gatt_update_app_use_link_flag(gatt_if, p_tcb, TRUE, TRUE);
   2773         }
   2774     }
   2775     else
   2776     {
   2777         ret = gatt_remove_bg_dev_from_list(p_reg, bd_addr, is_initator);
   2778     }
   2779     return ret;
   2780 }
   2781 
   2782 
   2783 
   2784 /*******************************************************************************
   2785 **
   2786 ** Function     gatt_add_pending_new_srv_start
   2787 **
   2788 ** Description  Add a pending new srv start to the new service start queue
   2789 **
   2790 ** Returns    Pointer to the new service start buffer, NULL no buffer available
   2791 **
   2792 *******************************************************************************/
   2793 tGATT_PENDING_ENC_CLCB* gatt_add_pending_enc_channel_clcb(tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb)
   2794 {
   2795     tGATT_PENDING_ENC_CLCB *p_buf =
   2796         (tGATT_PENDING_ENC_CLCB *)osi_malloc(sizeof(tGATT_PENDING_ENC_CLCB));
   2797 
   2798     GATT_TRACE_DEBUG ("%s", __func__);
   2799     GATT_TRACE_DEBUG("enqueue a new pending encryption channel clcb");
   2800 
   2801     p_buf->p_clcb = p_clcb;
   2802     fixed_queue_enqueue(p_tcb->pending_enc_clcb, p_buf);
   2803 
   2804     return p_buf;
   2805 }
   2806 /*******************************************************************************
   2807 **
   2808 ** Function     gatt_update_listen_mode
   2809 **
   2810 ** Description  update peripheral role listening mode
   2811 **
   2812 ** Returns    Pointer to the new service start buffer, NULL no buffer available
   2813 **
   2814 *******************************************************************************/
   2815 BOOLEAN gatt_update_listen_mode(void)
   2816 {
   2817     UINT8           ii = 0;
   2818     tGATT_REG       *p_reg = &gatt_cb.cl_rcb[0];
   2819     UINT8           listening = 0;
   2820     UINT16          connectability, window, interval;
   2821     BOOLEAN         rt = TRUE;
   2822 
   2823     for (; ii < GATT_MAX_APPS; ii ++, p_reg ++)
   2824     {
   2825         if ( p_reg->in_use && p_reg->listening > listening)
   2826         {
   2827             listening = p_reg->listening;
   2828         }
   2829     }
   2830 
   2831     if (listening == GATT_LISTEN_TO_ALL ||
   2832         listening == GATT_LISTEN_TO_NONE)
   2833         BTM_BleUpdateAdvFilterPolicy (AP_SCAN_CONN_ALL);
   2834     else
   2835         BTM_BleUpdateAdvFilterPolicy (AP_SCAN_CONN_WL);
   2836 
   2837     if (rt)
   2838     {
   2839         connectability = BTM_ReadConnectability (&window, &interval);
   2840 
   2841         if (listening != GATT_LISTEN_TO_NONE)
   2842         {
   2843             connectability |= BTM_BLE_CONNECTABLE;
   2844         }
   2845         else
   2846         {
   2847             if ((connectability & BTM_BLE_CONNECTABLE) == 0)
   2848             connectability &= ~BTM_BLE_CONNECTABLE;
   2849         }
   2850         /* turning on the adv now */
   2851         btm_ble_set_connectability(connectability);
   2852     }
   2853 
   2854     return rt;
   2855 
   2856 }
   2857 #endif
   2858 
   2859 
   2860