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->sr_cmd.multi_rsp_q = fixed_queue_new(SIZE_MAX);
    976             p_tcb->in_use = TRUE;
    977             p_tcb->tcb_idx = i;
    978             p_tcb->transport = transport;
    979         }
    980         memcpy(p_tcb->peer_bda, bda, BD_ADDR_LEN);
    981     }
    982     return p_tcb;
    983 }
    984 
    985 /*******************************************************************************
    986 **
    987 ** Function         gatt_convert_uuid16_to_uuid128
    988 **
    989 ** Description      Convert a 16 bits UUID to be an standard 128 bits one.
    990 **
    991 ** Returns          TRUE if two uuid match; FALSE otherwise.
    992 **
    993 *******************************************************************************/
    994 void gatt_convert_uuid16_to_uuid128(UINT8 uuid_128[LEN_UUID_128], UINT16 uuid_16)
    995 {
    996     UINT8   *p = &uuid_128[LEN_UUID_128 - 4];
    997 
    998     memcpy (uuid_128, base_uuid, LEN_UUID_128);
    999 
   1000     UINT16_TO_STREAM(p, uuid_16);
   1001 }
   1002 
   1003 /*******************************************************************************
   1004 **
   1005 ** Function         gatt_convert_uuid32_to_uuid128
   1006 **
   1007 ** Description      Convert a 32 bits UUID to be an standard 128 bits one.
   1008 **
   1009 ** Returns          TRUE if two uuid match; FALSE otherwise.
   1010 **
   1011 *******************************************************************************/
   1012 void gatt_convert_uuid32_to_uuid128(UINT8 uuid_128[LEN_UUID_128], UINT32 uuid_32)
   1013 {
   1014     UINT8   *p = &uuid_128[LEN_UUID_128 - 4];
   1015 
   1016     memcpy (uuid_128, base_uuid, LEN_UUID_128);
   1017 
   1018     UINT32_TO_STREAM(p, uuid_32);
   1019 }
   1020 /*******************************************************************************
   1021 **
   1022 ** Function         gatt_uuid_compare
   1023 **
   1024 ** Description      Compare two UUID to see if they are the same.
   1025 **
   1026 ** Returns          TRUE if two uuid match; FALSE otherwise.
   1027 **
   1028 *******************************************************************************/
   1029 BOOLEAN gatt_uuid_compare (tBT_UUID src, tBT_UUID tar)
   1030 {
   1031     UINT8  su[LEN_UUID_128], tu[LEN_UUID_128];
   1032     UINT8  *ps, *pt;
   1033 
   1034     /* any of the UUID is unspecified */
   1035     if (src.len == 0 || tar.len == 0)
   1036     {
   1037         return TRUE;
   1038     }
   1039 
   1040     /* If both are 16-bit, we can do a simple compare */
   1041     if (src.len == LEN_UUID_16 && tar.len == LEN_UUID_16)
   1042     {
   1043         return src.uu.uuid16 == tar.uu.uuid16;
   1044     }
   1045 
   1046     /* If both are 32-bit, we can do a simple compare */
   1047     if (src.len == LEN_UUID_32 && tar.len == LEN_UUID_32)
   1048     {
   1049         return src.uu.uuid32 == tar.uu.uuid32;
   1050     }
   1051 
   1052     /* One or both of the UUIDs is 128-bit */
   1053     if (src.len == LEN_UUID_16)
   1054     {
   1055         /* convert a 16 bits UUID to 128 bits value */
   1056         gatt_convert_uuid16_to_uuid128(su, src.uu.uuid16);
   1057         ps = su;
   1058     }
   1059     else if (src.len == LEN_UUID_32)
   1060     {
   1061         gatt_convert_uuid32_to_uuid128(su, src.uu.uuid32);
   1062         ps = su;
   1063     }
   1064     else
   1065         ps = src.uu.uuid128;
   1066 
   1067     if (tar.len == LEN_UUID_16)
   1068     {
   1069         /* convert a 16 bits UUID to 128 bits value */
   1070         gatt_convert_uuid16_to_uuid128(tu, tar.uu.uuid16);
   1071         pt = tu;
   1072     }
   1073     else if (tar.len == LEN_UUID_32)
   1074     {
   1075         /* convert a 32 bits UUID to 128 bits value */
   1076         gatt_convert_uuid32_to_uuid128(tu, tar.uu.uuid32);
   1077         pt = tu;
   1078     }
   1079     else
   1080         pt = tar.uu.uuid128;
   1081 
   1082     return(memcmp(ps, pt, LEN_UUID_128) == 0);
   1083 }
   1084 
   1085 /*******************************************************************************
   1086 **
   1087 ** Function         gatt_build_uuid_to_stream
   1088 **
   1089 ** Description      Add UUID into stream.
   1090 **
   1091 ** Returns          UUID length.
   1092 **
   1093 *******************************************************************************/
   1094 UINT8 gatt_build_uuid_to_stream(UINT8 **p_dst, tBT_UUID uuid)
   1095 {
   1096     UINT8   *p = *p_dst;
   1097     UINT8   len = 0;
   1098 
   1099     if (uuid.len == LEN_UUID_16)
   1100     {
   1101         UINT16_TO_STREAM (p, uuid.uu.uuid16);
   1102         len = LEN_UUID_16;
   1103     }
   1104     else if (uuid.len == LEN_UUID_32) /* always convert 32 bits into 128 bits as alwats */
   1105     {
   1106         gatt_convert_uuid32_to_uuid128(p, uuid.uu.uuid32);
   1107         p += LEN_UUID_128;
   1108         len = LEN_UUID_128;
   1109     }
   1110     else if (uuid.len == LEN_UUID_128)
   1111     {
   1112         ARRAY_TO_STREAM (p, uuid.uu.uuid128, LEN_UUID_128);
   1113         len = LEN_UUID_128;
   1114     }
   1115 
   1116     *p_dst = p;
   1117     return len;
   1118 }
   1119 
   1120 /*******************************************************************************
   1121 **
   1122 ** Function         gatt_parse_uuid_from_cmd
   1123 **
   1124 ** Description      Convert a 128 bits UUID into a 16 bits UUID.
   1125 **
   1126 ** Returns          TRUE if command sent, otherwise FALSE.
   1127 **
   1128 *******************************************************************************/
   1129 BOOLEAN gatt_parse_uuid_from_cmd(tBT_UUID *p_uuid_rec, UINT16 uuid_size, UINT8 **p_data)
   1130 {
   1131     BOOLEAN is_base_uuid, ret = TRUE;
   1132     UINT8  xx;
   1133     UINT8 *p_uuid = *p_data;
   1134 
   1135     memset(p_uuid_rec, 0, sizeof(tBT_UUID));
   1136 
   1137     switch (uuid_size)
   1138     {
   1139         case LEN_UUID_16:
   1140             p_uuid_rec->len = uuid_size;
   1141             STREAM_TO_UINT16 (p_uuid_rec->uu.uuid16, p_uuid);
   1142             *p_data += LEN_UUID_16;
   1143             break;
   1144 
   1145         case LEN_UUID_128:
   1146             /* See if we can compress his UUID down to 16 or 32bit UUIDs */
   1147             is_base_uuid = TRUE;
   1148             for (xx = 0; xx < LEN_UUID_128 - 4; xx++)
   1149             {
   1150                 if (p_uuid[xx] != base_uuid[xx])
   1151                 {
   1152                     is_base_uuid = FALSE;
   1153                     break;
   1154                 }
   1155             }
   1156             if (is_base_uuid)
   1157             {
   1158                 if ((p_uuid[LEN_UUID_128 - 1] == 0) && (p_uuid[LEN_UUID_128 - 2] == 0))
   1159                 {
   1160                     p_uuid += (LEN_UUID_128 - 4);
   1161                     p_uuid_rec->len = LEN_UUID_16;
   1162                     STREAM_TO_UINT16(p_uuid_rec->uu.uuid16, p_uuid);
   1163                 }
   1164                 else
   1165                 {
   1166                     p_uuid += (LEN_UUID_128 - LEN_UUID_32);
   1167                     p_uuid_rec->len = LEN_UUID_32;
   1168                     STREAM_TO_UINT32(p_uuid_rec->uu.uuid32, p_uuid);
   1169                 }
   1170             }
   1171             if (!is_base_uuid)
   1172             {
   1173                 p_uuid_rec->len = LEN_UUID_128;
   1174                 memcpy(p_uuid_rec->uu.uuid128, p_uuid, LEN_UUID_128);
   1175             }
   1176             *p_data += LEN_UUID_128;
   1177             break;
   1178 
   1179         /* do not allow 32 bits UUID in ATT PDU now */
   1180         case LEN_UUID_32:
   1181             GATT_TRACE_ERROR("DO NOT ALLOW 32 BITS UUID IN ATT PDU");
   1182         case 0:
   1183         default:
   1184             if (uuid_size != 0) ret = FALSE;
   1185             GATT_TRACE_WARNING("gatt_parse_uuid_from_cmd invalid uuid size");
   1186             break;
   1187     }
   1188 
   1189     return( ret);
   1190 }
   1191 
   1192 /*******************************************************************************
   1193 **
   1194 ** Function         gatt_start_rsp_timer
   1195 **
   1196 ** Description      Start a wait_for_response timer.
   1197 **
   1198 ** Returns          void
   1199 **
   1200 *******************************************************************************/
   1201 void gatt_start_rsp_timer(UINT16 clcb_idx)
   1202 {
   1203     tGATT_CLCB *p_clcb = &gatt_cb.clcb[clcb_idx];
   1204     period_ms_t timeout_ms = GATT_WAIT_FOR_RSP_TIMEOUT_MS;
   1205 
   1206     if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY &&
   1207         p_clcb->op_subtype == GATT_DISC_SRVC_ALL) {
   1208         timeout_ms = GATT_WAIT_FOR_DISC_RSP_TIMEOUT_MS;
   1209     }
   1210 
   1211     // TODO: The tGATT_CLCB memory and state management needs cleanup,
   1212     // and then the timers can be allocated elsewhere.
   1213     if (p_clcb->gatt_rsp_timer_ent == NULL) {
   1214         p_clcb->gatt_rsp_timer_ent = alarm_new("gatt.gatt_rsp_timer_ent");
   1215     }
   1216     alarm_set_on_queue(p_clcb->gatt_rsp_timer_ent, timeout_ms,
   1217                        gatt_rsp_timeout, p_clcb, btu_general_alarm_queue);
   1218 }
   1219 
   1220 /*******************************************************************************
   1221 **
   1222 ** Function         gatt_start_conf_timer
   1223 **
   1224 ** Description      Start a wait_for_confirmation timer.
   1225 **
   1226 ** Returns          void
   1227 **
   1228 *******************************************************************************/
   1229 void gatt_start_conf_timer(tGATT_TCB *p_tcb)
   1230 {
   1231     alarm_set_on_queue(p_tcb->conf_timer, GATT_WAIT_FOR_RSP_TIMEOUT_MS,
   1232                        gatt_indication_confirmation_timeout, p_tcb,
   1233                        btu_general_alarm_queue);
   1234 }
   1235 
   1236 /*******************************************************************************
   1237 **
   1238 ** Function         gatt_start_ind_ack_timer
   1239 **
   1240 ** Description      start the application ack timer
   1241 **
   1242 ** Returns          void
   1243 **
   1244 *******************************************************************************/
   1245 void gatt_start_ind_ack_timer(tGATT_TCB *p_tcb)
   1246 {
   1247     /* start notification cache timer */
   1248     alarm_set_on_queue(p_tcb->ind_ack_timer, GATT_WAIT_FOR_RSP_TIMEOUT_MS,
   1249                        gatt_ind_ack_timeout, p_tcb, btu_general_alarm_queue);
   1250 }
   1251 
   1252 /*******************************************************************************
   1253 **
   1254 ** Function         gatt_rsp_timeout
   1255 **
   1256 ** Description      Called when GATT wait for ATT command response timer expires
   1257 **
   1258 ** Returns          void
   1259 **
   1260 *******************************************************************************/
   1261 void gatt_rsp_timeout(void *data)
   1262 {
   1263     tGATT_CLCB *p_clcb = (tGATT_CLCB *)data;
   1264 
   1265     if (p_clcb == NULL || p_clcb->p_tcb == NULL)
   1266     {
   1267         GATT_TRACE_WARNING("%s clcb is already deleted", __func__);
   1268         return;
   1269     }
   1270     if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY &&
   1271         p_clcb->op_subtype == GATT_DISC_SRVC_ALL &&
   1272         p_clcb->retry_count < GATT_REQ_RETRY_LIMIT)
   1273     {
   1274         UINT8 rsp_code;
   1275         GATT_TRACE_WARNING("%s retry discovery primary service", __func__);
   1276         if (p_clcb != gatt_cmd_dequeue(p_clcb->p_tcb, &rsp_code))
   1277         {
   1278             GATT_TRACE_ERROR("%s command queue out of sync, disconnect",
   1279                              __func__);
   1280         }
   1281         else
   1282         {
   1283             p_clcb->retry_count++;
   1284             gatt_act_discovery(p_clcb);
   1285             return;
   1286         }
   1287     }
   1288 
   1289     GATT_TRACE_WARNING("%s disconnecting...", __func__);
   1290     gatt_disconnect (p_clcb->p_tcb);
   1291 }
   1292 
   1293 /*******************************************************************************
   1294 **
   1295 ** Function         gatt_indication_confirmation_timeout
   1296 **
   1297 ** Description      Called when the indication confirmation timer expires
   1298 **
   1299 ** Returns          void
   1300 **
   1301 *******************************************************************************/
   1302 void gatt_indication_confirmation_timeout(void *data)
   1303 {
   1304     tGATT_TCB *p_tcb = (tGATT_TCB *)data;
   1305 
   1306     GATT_TRACE_WARNING("%s disconnecting...", __func__);
   1307     gatt_disconnect(p_tcb);
   1308 }
   1309 
   1310 /*******************************************************************************
   1311 **
   1312 ** Function         gatt_ind_ack_timeout
   1313 **
   1314 ** Description      Called when GATT wait for ATT handle confirmation timeout
   1315 **
   1316 ** Returns          void
   1317 **
   1318 *******************************************************************************/
   1319 void gatt_ind_ack_timeout(void *data)
   1320 {
   1321     tGATT_TCB *p_tcb = (tGATT_TCB *)data;
   1322 
   1323     GATT_TRACE_WARNING("%s send ack now", __func__);
   1324 
   1325     if (p_tcb != NULL)
   1326         p_tcb->ind_count = 0;
   1327 
   1328     attp_send_cl_msg(p_tcb, 0, GATT_HANDLE_VALUE_CONF, NULL);
   1329 }
   1330 /*******************************************************************************
   1331 **
   1332 ** Function         gatt_sr_find_i_rcb_by_handle
   1333 **
   1334 ** Description      The function searches for a service that owns a specific handle.
   1335 **
   1336 ** Returns          GATT_MAX_SR_PROFILES if not found. Otherwise index of th eservice.
   1337 **
   1338 *******************************************************************************/
   1339 UINT8 gatt_sr_find_i_rcb_by_handle(UINT16 handle)
   1340 {
   1341     UINT8  i_rcb = 0;
   1342 
   1343     for ( ; i_rcb < GATT_MAX_SR_PROFILES; i_rcb++)
   1344     {
   1345         if (gatt_cb.sr_reg[i_rcb].in_use &&
   1346             gatt_cb.sr_reg[i_rcb].s_hdl <= handle &&
   1347             gatt_cb.sr_reg[i_rcb].e_hdl >= handle )
   1348         {
   1349             break;
   1350         }
   1351     }
   1352     return i_rcb;
   1353 }
   1354 
   1355 /*******************************************************************************
   1356 **
   1357 ** Function         gatt_sr_find_i_rcb_by_handle
   1358 **
   1359 ** Description      The function searches for a service that owns a specific handle.
   1360 **
   1361 ** Returns          0 if not found. Otherwise index of th eservice.
   1362 **
   1363 *******************************************************************************/
   1364 UINT8 gatt_sr_find_i_rcb_by_app_id(tBT_UUID *p_app_uuid128, tBT_UUID *p_svc_uuid, UINT16 svc_inst)
   1365 {
   1366     UINT8           i_rcb = 0;
   1367     tGATT_SR_REG    *p_sreg;
   1368     tBT_UUID        *p_this_uuid;
   1369 
   1370     for (i_rcb = 0, p_sreg = gatt_cb.sr_reg; i_rcb < GATT_MAX_SR_PROFILES; i_rcb++, p_sreg++)
   1371     {
   1372         if ( p_sreg->in_use )
   1373         {
   1374             p_this_uuid = gatts_get_service_uuid (p_sreg->p_db);
   1375 
   1376             if (p_this_uuid &&
   1377                 gatt_uuid_compare (*p_app_uuid128, p_sreg->app_uuid ) &&
   1378                 gatt_uuid_compare (*p_svc_uuid, *p_this_uuid) &&
   1379                 (svc_inst == p_sreg->service_instance))
   1380             {
   1381                 GATT_TRACE_ERROR ("Active Service Found ");
   1382                 gatt_dbg_display_uuid(*p_svc_uuid);
   1383 
   1384                 break;
   1385             }
   1386         }
   1387     }
   1388     return i_rcb;
   1389 }
   1390 /*******************************************************************************
   1391 **
   1392 ** Function         gatt_sr_find_i_rcb_by_handle
   1393 **
   1394 ** Description      The function searches for a service that owns a specific handle.
   1395 **
   1396 ** Returns          0 if not found. Otherwise index of th eservice.
   1397 **
   1398 *******************************************************************************/
   1399 UINT8 gatt_sr_alloc_rcb(tGATT_HDL_LIST_ELEM *p_list )
   1400 {
   1401     UINT8   ii = 0;
   1402     tGATT_SR_REG    *p_sreg = NULL;
   1403 
   1404     /*this is a new application servoce start */
   1405     for (ii = 0, p_sreg = gatt_cb.sr_reg; ii < GATT_MAX_SR_PROFILES; ii++, p_sreg++)
   1406     {
   1407         if (!p_sreg->in_use)
   1408         {
   1409             memset (p_sreg, 0, sizeof(tGATT_SR_REG));
   1410 
   1411             p_sreg->in_use = TRUE;
   1412             memcpy (&p_sreg->app_uuid, &p_list->asgn_range.app_uuid128, sizeof(tBT_UUID));
   1413 
   1414             p_sreg->service_instance    = p_list->asgn_range.svc_inst;
   1415             p_sreg->type                = p_list->asgn_range.is_primary ? GATT_UUID_PRI_SERVICE: GATT_UUID_SEC_SERVICE;
   1416             p_sreg->s_hdl               = p_list->asgn_range.s_handle;
   1417             p_sreg->e_hdl               = p_list->asgn_range.e_handle;
   1418             p_sreg->p_db                = &p_list->svc_db;
   1419 
   1420             GATT_TRACE_DEBUG("total buffer in db [%d]",
   1421                              fixed_queue_length(p_sreg->p_db->svc_buffer));
   1422             break;
   1423         }
   1424     }
   1425 
   1426     return ii;
   1427 }
   1428 /*******************************************************************************
   1429 **
   1430 ** Function         gatt_sr_get_sec_info
   1431 **
   1432 ** Description      Get the security flag and key size information for the peer
   1433 **                  device.
   1434 **
   1435 ** Returns          void
   1436 **
   1437 *******************************************************************************/
   1438 void gatt_sr_get_sec_info(BD_ADDR rem_bda, tBT_TRANSPORT transport, UINT8 *p_sec_flag, UINT8 *p_key_size)
   1439 {
   1440     UINT8           sec_flag = 0;
   1441 
   1442     BTM_GetSecurityFlagsByTransport(rem_bda, &sec_flag, transport);
   1443 
   1444     sec_flag &= (GATT_SEC_FLAG_LKEY_UNAUTHED | GATT_SEC_FLAG_LKEY_AUTHED | GATT_SEC_FLAG_ENCRYPTED);
   1445 
   1446     *p_key_size = btm_ble_read_sec_key_size(rem_bda);
   1447     *p_sec_flag = sec_flag;
   1448 }
   1449 /*******************************************************************************
   1450 **
   1451 ** Function         gatt_sr_send_req_callback
   1452 **
   1453 ** Description
   1454 **
   1455 **
   1456 ** Returns          void
   1457 **
   1458 *******************************************************************************/
   1459 void gatt_sr_send_req_callback(UINT16 conn_id,
   1460                                UINT32 trans_id,
   1461                                tGATTS_REQ_TYPE type, tGATTS_DATA *p_data)
   1462 {
   1463     tGATT_IF        gatt_if = GATT_GET_GATT_IF(conn_id);
   1464     tGATT_REG       *p_reg = gatt_get_regcb(gatt_if);
   1465 
   1466     if (!p_reg )
   1467     {
   1468         GATT_TRACE_ERROR ("p_reg not found discard request");
   1469         return;
   1470     }
   1471 
   1472     if ( p_reg->in_use &&
   1473          p_reg->app_cb.p_req_cb)
   1474     {
   1475         (*p_reg->app_cb.p_req_cb)(conn_id, trans_id, type, p_data);
   1476     }
   1477     else
   1478     {
   1479         GATT_TRACE_WARNING("Call back not found for application conn_id=%d", conn_id);
   1480     }
   1481 
   1482 }
   1483 
   1484 /*******************************************************************************
   1485 **
   1486 ** Function         gatt_send_error_rsp
   1487 **
   1488 ** Description      This function sends an error response.
   1489 **
   1490 ** Returns          void
   1491 **
   1492 *******************************************************************************/
   1493 tGATT_STATUS gatt_send_error_rsp (tGATT_TCB *p_tcb, UINT8 err_code, UINT8 op_code,
   1494                                   UINT16 handle, BOOLEAN deq)
   1495 {
   1496     tGATT_ERROR      error;
   1497     tGATT_STATUS     status;
   1498     BT_HDR           *p_buf;
   1499 
   1500     error.cmd_code = op_code;
   1501     error.reason = err_code;
   1502     error.handle =handle;
   1503 
   1504     if ((p_buf = attp_build_sr_msg(p_tcb, GATT_RSP_ERROR, (tGATT_SR_MSG *)&error)) != NULL)
   1505     {
   1506         status = attp_send_sr_msg (p_tcb, p_buf);
   1507     }
   1508     else
   1509         status = GATT_INSUF_RESOURCE;
   1510 
   1511     if (deq)
   1512         gatt_dequeue_sr_cmd(p_tcb);
   1513 
   1514     return status;
   1515 }
   1516 
   1517 
   1518 /*******************************************************************************
   1519 **
   1520 ** Function         gatt_add_sdp_record
   1521 **
   1522 ** Description      This function add a SDP record for a GATT primary service
   1523 **
   1524 ** Returns          0 if error else sdp handle for the record.
   1525 **
   1526 *******************************************************************************/
   1527 UINT32 gatt_add_sdp_record (tBT_UUID *p_uuid, UINT16 start_hdl, UINT16 end_hdl)
   1528 {
   1529     tSDP_PROTOCOL_ELEM  proto_elem_list[2];
   1530     UINT32              sdp_handle;
   1531     UINT16              list = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
   1532     UINT8               buff[60];
   1533     UINT8               *p = buff;
   1534 
   1535     GATT_TRACE_DEBUG("gatt_add_sdp_record s_hdl=0x%x  s_hdl=0x%x",start_hdl, end_hdl);
   1536 
   1537     if ((sdp_handle = SDP_CreateRecord()) == 0)
   1538         return 0;
   1539 
   1540     switch (p_uuid->len)
   1541     {
   1542         case LEN_UUID_16:
   1543             SDP_AddServiceClassIdList(sdp_handle, 1, &p_uuid->uu.uuid16);
   1544             break;
   1545 
   1546         case LEN_UUID_32:
   1547             UINT8_TO_BE_STREAM (p, (UUID_DESC_TYPE << 3) | SIZE_FOUR_BYTES);
   1548             UINT32_TO_BE_STREAM (p, p_uuid->uu.uuid32);
   1549             SDP_AddAttribute (sdp_handle, ATTR_ID_SERVICE_CLASS_ID_LIST, DATA_ELE_SEQ_DESC_TYPE,
   1550                               (UINT32) (p - buff), buff);
   1551             break;
   1552 
   1553         case LEN_UUID_128:
   1554             UINT8_TO_BE_STREAM (p, (UUID_DESC_TYPE << 3) | SIZE_SIXTEEN_BYTES);
   1555             ARRAY_TO_BE_STREAM_REVERSE (p, p_uuid->uu.uuid128, LEN_UUID_128);
   1556             SDP_AddAttribute (sdp_handle, ATTR_ID_SERVICE_CLASS_ID_LIST, DATA_ELE_SEQ_DESC_TYPE,
   1557                               (UINT32) (p - buff), buff);
   1558             break;
   1559 
   1560         default:
   1561             GATT_TRACE_ERROR("inavlid UUID len=%d", p_uuid->len);
   1562             SDP_DeleteRecord(sdp_handle);
   1563             return 0;
   1564             break;
   1565     }
   1566 
   1567     /*** Fill out the protocol element sequence for SDP ***/
   1568     proto_elem_list[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
   1569     proto_elem_list[0].num_params    = 1;
   1570     proto_elem_list[0].params[0]     = BT_PSM_ATT;
   1571     proto_elem_list[1].protocol_uuid = UUID_PROTOCOL_ATT;
   1572     proto_elem_list[1].num_params    = 2;
   1573     proto_elem_list[1].params[0]     = start_hdl;
   1574     proto_elem_list[1].params[1]     = end_hdl;
   1575 
   1576     SDP_AddProtocolList(sdp_handle, 2, proto_elem_list);
   1577 
   1578     /* Make the service browseable */
   1579     SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &list);
   1580 
   1581     return(sdp_handle);
   1582 }
   1583 
   1584 
   1585     #if GATT_CONFORMANCE_TESTING == TRUE
   1586 /*******************************************************************************
   1587 **
   1588 ** Function         gatt_set_err_rsp
   1589 **
   1590 ** Description      This function is called to set the test confirm value
   1591 **
   1592 ** Returns          void
   1593 **
   1594 *******************************************************************************/
   1595 void gatt_set_err_rsp(BOOLEAN enable, UINT8 req_op_code, UINT8 err_status)
   1596 {
   1597     GATT_TRACE_DEBUG("gatt_set_err_rsp enable=%d op_code=%d, err_status=%d", enable, req_op_code, err_status);
   1598     gatt_cb.enable_err_rsp  = enable;
   1599     gatt_cb.req_op_code     = req_op_code;
   1600     gatt_cb.err_status      = err_status;
   1601 }
   1602     #endif
   1603 
   1604 
   1605 
   1606 /*******************************************************************************
   1607 **
   1608 ** Function         gatt_get_regcb
   1609 **
   1610 ** Description      The function returns the registration control block.
   1611 **
   1612 ** Returns          pointer to the registration control block or NULL
   1613 **
   1614 *******************************************************************************/
   1615 tGATT_REG *gatt_get_regcb (tGATT_IF gatt_if)
   1616 {
   1617     UINT8           ii = (UINT8)gatt_if;
   1618     tGATT_REG       *p_reg = NULL;
   1619 
   1620     if (ii < 1 || ii > GATT_MAX_APPS) {
   1621         GATT_TRACE_WARNING("gatt_if out of range [ = %d]", ii);
   1622         return NULL;
   1623     }
   1624 
   1625     // Index for cl_rcb is always 1 less than gatt_if.
   1626     p_reg = &gatt_cb.cl_rcb[ii - 1];
   1627 
   1628     if (!p_reg->in_use) {
   1629         GATT_TRACE_WARNING("gatt_if found but not in use.");
   1630         return NULL;
   1631     }
   1632 
   1633     return p_reg;
   1634 }
   1635 
   1636 
   1637 /*******************************************************************************
   1638 **
   1639 ** Function         gatt_is_clcb_allocated
   1640 **
   1641 ** Description      The function check clcb for conn_id is allocated or not
   1642 **
   1643 ** Returns           True already allocated
   1644 **
   1645 *******************************************************************************/
   1646 
   1647 BOOLEAN gatt_is_clcb_allocated (UINT16 conn_id)
   1648 {
   1649     UINT8         i = 0;
   1650     BOOLEAN       is_allocated= FALSE;
   1651 
   1652     for (i = 0; i < GATT_CL_MAX_LCB; i++)
   1653     {
   1654         if (gatt_cb.clcb[i].in_use && (gatt_cb.clcb[i].conn_id == conn_id))
   1655         {
   1656             is_allocated = TRUE;
   1657             break;
   1658         }
   1659     }
   1660 
   1661     return is_allocated;
   1662 }
   1663 
   1664 /*******************************************************************************
   1665 **
   1666 ** Function         gatt_clcb_alloc
   1667 **
   1668 ** Description      The function allocates a GATT  connection link control block
   1669 **
   1670 ** Returns           NULL if not found. Otherwise pointer to the connection link block.
   1671 **
   1672 *******************************************************************************/
   1673 tGATT_CLCB *gatt_clcb_alloc (UINT16 conn_id)
   1674 {
   1675     UINT8           i = 0;
   1676     tGATT_CLCB      *p_clcb = NULL;
   1677     tGATT_IF        gatt_if=GATT_GET_GATT_IF(conn_id);
   1678     UINT8           tcb_idx = GATT_GET_TCB_IDX(conn_id);
   1679     tGATT_TCB       *p_tcb = gatt_get_tcb_by_idx(tcb_idx);
   1680     tGATT_REG       *p_reg = gatt_get_regcb(gatt_if);
   1681 
   1682     for (i = 0; i < GATT_CL_MAX_LCB; i++)
   1683     {
   1684         if (!gatt_cb.clcb[i].in_use)
   1685         {
   1686             p_clcb = &gatt_cb.clcb[i];
   1687 
   1688             p_clcb->in_use      = TRUE;
   1689             p_clcb->conn_id     = conn_id;
   1690             p_clcb->clcb_idx    = i;
   1691             p_clcb->p_reg       = p_reg;
   1692             p_clcb->p_tcb       = p_tcb;
   1693             break;
   1694         }
   1695     }
   1696     return p_clcb;
   1697 }
   1698 
   1699 /*******************************************************************************
   1700 **
   1701 ** Function         gatt_clcb_dealloc
   1702 **
   1703 ** Description      The function de allocates a GATT  connection link control block
   1704 **
   1705 ** Returns         None
   1706 **
   1707 *******************************************************************************/
   1708 void gatt_clcb_dealloc (tGATT_CLCB *p_clcb)
   1709 {
   1710     if (p_clcb && p_clcb->in_use)
   1711     {
   1712         alarm_free(p_clcb->gatt_rsp_timer_ent);
   1713         memset(p_clcb, 0, sizeof(tGATT_CLCB));
   1714     }
   1715 }
   1716 
   1717 
   1718 
   1719 /*******************************************************************************
   1720 **
   1721 ** Function         gatt_find_tcb_by_cid
   1722 **
   1723 ** Description      The function searches for an empty entry
   1724 **                   in registration info table for GATT client
   1725 **
   1726 ** Returns           NULL if not found. Otherwise pointer to the rcb.
   1727 **
   1728 *******************************************************************************/
   1729 tGATT_TCB * gatt_find_tcb_by_cid (UINT16 lcid)
   1730 {
   1731     UINT16       xx = 0;
   1732     tGATT_TCB    *p_tcb = NULL;
   1733 
   1734     for (xx = 0; xx < GATT_MAX_PHY_CHANNEL; xx++)
   1735     {
   1736         if (gatt_cb.tcb[xx].in_use && gatt_cb.tcb[xx].att_lcid == lcid)
   1737         {
   1738             p_tcb = &gatt_cb.tcb[xx];
   1739             break;
   1740         }
   1741     }
   1742     return p_tcb;
   1743 }
   1744 
   1745 
   1746 /*******************************************************************************
   1747 **
   1748 ** Function         gatt_num_apps_hold_link
   1749 **
   1750 ** Description      The function find the number of applcaitions is holding the link
   1751 **
   1752 ** Returns          total number of applications holding this acl link.
   1753 **
   1754 *******************************************************************************/
   1755 UINT8 gatt_num_apps_hold_link(tGATT_TCB *p_tcb)
   1756 {
   1757     UINT8 i, num = 0;
   1758 
   1759     for (i = 0; i < GATT_MAX_APPS; i ++)
   1760     {
   1761         if (p_tcb->app_hold_link[i])
   1762             num ++;
   1763     }
   1764 
   1765     GATT_TRACE_DEBUG("gatt_num_apps_hold_link   num=%d",  num);
   1766     return num;
   1767 }
   1768 
   1769 
   1770 /*******************************************************************************
   1771 **
   1772 ** Function         gatt_num_clcb_by_bd_addr
   1773 **
   1774 ** Description      The function searches all LCB with macthing bd address
   1775 **
   1776 ** Returns          total number of clcb found.
   1777 **
   1778 *******************************************************************************/
   1779 UINT8 gatt_num_clcb_by_bd_addr(BD_ADDR bda)
   1780 {
   1781     UINT8 i, num = 0;
   1782 
   1783     for (i = 0; i < GATT_CL_MAX_LCB; i ++)
   1784     {
   1785         if (gatt_cb.clcb[i].in_use && memcmp(gatt_cb.clcb[i].p_tcb->peer_bda, bda, BD_ADDR_LEN) == 0)
   1786             num ++;
   1787     }
   1788     return num;
   1789 }
   1790 
   1791 /*******************************************************************************
   1792 **
   1793 ** Function         gatt_sr_update_cback_cnt
   1794 **
   1795 ** Description      The function searches all LCB with macthing bd address
   1796 **
   1797 ** Returns          total number of clcb found.
   1798 **
   1799 *******************************************************************************/
   1800 void gatt_sr_copy_prep_cnt_to_cback_cnt(tGATT_TCB *p_tcb )
   1801 {
   1802     UINT8 i;
   1803 
   1804     if (p_tcb)
   1805     {
   1806         for (i = 0; i < GATT_MAX_APPS; i ++)
   1807         {
   1808             if (p_tcb->prep_cnt[i])
   1809             {
   1810                 p_tcb->sr_cmd.cback_cnt[i]=1;
   1811             }
   1812         }
   1813     }
   1814 
   1815 }
   1816 
   1817 /*******************************************************************************
   1818 **
   1819 ** Function         gatt_sr_is_cback_cnt_zero
   1820 **
   1821 ** Description      The function searches all LCB with macthing bd address
   1822 **
   1823 ** Returns          True if thetotal application callback count is zero
   1824 **
   1825 *******************************************************************************/
   1826 BOOLEAN gatt_sr_is_cback_cnt_zero(tGATT_TCB *p_tcb )
   1827 {
   1828     BOOLEAN status = TRUE;
   1829     UINT8   i;
   1830 
   1831     if (p_tcb)
   1832     {
   1833         for (i = 0; i < GATT_MAX_APPS; i ++)
   1834         {
   1835             if (p_tcb->sr_cmd.cback_cnt[i])
   1836             {
   1837                 status = FALSE;
   1838                 break;
   1839             }
   1840         }
   1841     }
   1842     else
   1843     {
   1844         status = FALSE;
   1845     }
   1846     return status;
   1847 }
   1848 
   1849 /*******************************************************************************
   1850 **
   1851 ** Function         gatt_sr_is_prep_cnt_zero
   1852 **
   1853 ** Description      Check the prepare write request count is zero or not
   1854 **
   1855 ** Returns          True no prepare write request
   1856 **
   1857 *******************************************************************************/
   1858 BOOLEAN gatt_sr_is_prep_cnt_zero(tGATT_TCB *p_tcb)
   1859 {
   1860     BOOLEAN status = TRUE;
   1861     UINT8   i;
   1862 
   1863     if (p_tcb)
   1864     {
   1865         for (i = 0; i < GATT_MAX_APPS; i ++)
   1866         {
   1867             if (p_tcb->prep_cnt[i])
   1868             {
   1869                 status = FALSE;
   1870                 break;
   1871             }
   1872         }
   1873     }
   1874     else
   1875     {
   1876         status = FALSE;
   1877     }
   1878     return status;
   1879 }
   1880 
   1881 
   1882 /*******************************************************************************
   1883 **
   1884 ** Function         gatt_sr_reset_cback_cnt
   1885 **
   1886 ** Description      Reset the application callback count to zero
   1887 **
   1888 ** Returns         None
   1889 **
   1890 *******************************************************************************/
   1891 void gatt_sr_reset_cback_cnt(tGATT_TCB *p_tcb )
   1892 {
   1893     UINT8 i;
   1894 
   1895     if (p_tcb)
   1896     {
   1897         for (i = 0; i < GATT_MAX_APPS; i ++)
   1898         {
   1899             p_tcb->sr_cmd.cback_cnt[i]=0;
   1900         }
   1901     }
   1902 }
   1903 
   1904 /*******************************************************************************
   1905 **
   1906 ** Function         gatt_sr_reset_prep_cnt
   1907 **
   1908 ** Description     Reset the prep write count to zero
   1909 **
   1910 ** Returns        None
   1911 **
   1912 *******************************************************************************/
   1913 void gatt_sr_reset_prep_cnt(tGATT_TCB *p_tcb )
   1914 {
   1915     UINT8 i;
   1916     if (p_tcb)
   1917     {
   1918         for (i = 0; i < GATT_MAX_APPS; i ++)
   1919         {
   1920             p_tcb->prep_cnt[i]=0;
   1921         }
   1922     }
   1923 }
   1924 
   1925 
   1926 /*******************************************************************************
   1927 **
   1928 ** Function         gatt_sr_update_cback_cnt
   1929 **
   1930 ** Description    Update the teh applicaiton callback count
   1931 **
   1932 ** Returns           None
   1933 **
   1934 *******************************************************************************/
   1935 void gatt_sr_update_cback_cnt(tGATT_TCB *p_tcb, tGATT_IF gatt_if, BOOLEAN is_inc, BOOLEAN is_reset_first)
   1936 {
   1937 
   1938     UINT8 idx = ((UINT8) gatt_if) - 1 ;
   1939 
   1940     if (p_tcb)
   1941     {
   1942         if (is_reset_first)
   1943         {
   1944             gatt_sr_reset_cback_cnt(p_tcb);
   1945         }
   1946         if (is_inc)
   1947         {
   1948             p_tcb->sr_cmd.cback_cnt[idx]++;
   1949         }
   1950         else
   1951         {
   1952             if ( p_tcb->sr_cmd.cback_cnt[idx])
   1953             {
   1954                 p_tcb->sr_cmd.cback_cnt[idx]--;
   1955             }
   1956         }
   1957     }
   1958 }
   1959 
   1960 
   1961 /*******************************************************************************
   1962 **
   1963 ** Function         gatt_sr_update_prep_cnt
   1964 **
   1965 ** Description    Update the teh prepare write request count
   1966 **
   1967 ** Returns           None
   1968 **
   1969 *******************************************************************************/
   1970 void gatt_sr_update_prep_cnt(tGATT_TCB *p_tcb, tGATT_IF gatt_if, BOOLEAN is_inc, BOOLEAN is_reset_first)
   1971 {
   1972     UINT8 idx = ((UINT8) gatt_if) - 1 ;
   1973 
   1974     GATT_TRACE_DEBUG("gatt_sr_update_prep_cnt tcb idx=%d gatt_if=%d is_inc=%d is_reset_first=%d",
   1975                       p_tcb->tcb_idx, gatt_if, is_inc, is_reset_first);
   1976 
   1977     if (p_tcb)
   1978     {
   1979         if (is_reset_first)
   1980         {
   1981             gatt_sr_reset_prep_cnt(p_tcb);
   1982         }
   1983         if (is_inc)
   1984         {
   1985             p_tcb->prep_cnt[idx]++;
   1986         }
   1987         else
   1988         {
   1989             if (p_tcb->prep_cnt[idx])
   1990             {
   1991                 p_tcb->prep_cnt[idx]--;
   1992             }
   1993         }
   1994     }
   1995 }
   1996 /*******************************************************************************
   1997 **
   1998 ** Function         gatt_cancel_open
   1999 **
   2000 ** Description      Cancel open request
   2001 **
   2002 ** Returns         Boolean
   2003 **
   2004 *******************************************************************************/
   2005 BOOLEAN gatt_cancel_open(tGATT_IF gatt_if, BD_ADDR bda)
   2006 {
   2007     tGATT_TCB *p_tcb=NULL;
   2008     BOOLEAN status= TRUE;
   2009 
   2010     p_tcb = gatt_find_tcb_by_addr(bda, BT_TRANSPORT_LE);
   2011 
   2012     if (p_tcb)
   2013     {
   2014         if (gatt_get_ch_state(p_tcb) == GATT_CH_OPEN)
   2015         {
   2016             GATT_TRACE_ERROR("GATT_CancelConnect - link connected Too late to cancel");
   2017             status = FALSE;
   2018         }
   2019         else
   2020         {
   2021             gatt_update_app_use_link_flag(gatt_if, p_tcb, FALSE, FALSE);
   2022             if (!gatt_num_apps_hold_link(p_tcb))
   2023             {
   2024                 gatt_disconnect(p_tcb);
   2025             }
   2026         }
   2027     }
   2028 
   2029     return status;
   2030 }
   2031 
   2032 /*******************************************************************************
   2033 **
   2034 ** Function         gatt_find_app_hold_link
   2035 **
   2036 ** Description      find the applicaiton that is holding the specified link
   2037 **
   2038 ** Returns         Boolean
   2039 **
   2040 *******************************************************************************/
   2041 BOOLEAN gatt_find_app_hold_link(tGATT_TCB *p_tcb, UINT8 start_idx, UINT8 *p_found_idx, tGATT_IF *p_gatt_if)
   2042 {
   2043     UINT8 i;
   2044     BOOLEAN found= FALSE;
   2045 
   2046     for (i = start_idx; i < GATT_MAX_APPS; i ++)
   2047     {
   2048         if (p_tcb->app_hold_link[i])
   2049         {
   2050             *p_gatt_if = gatt_cb.clcb[i].p_reg->gatt_if;
   2051             *p_found_idx = i;
   2052             found = TRUE;
   2053             break;
   2054         }
   2055     }
   2056     return found;
   2057 }
   2058 
   2059 /*******************************************************************************
   2060 **
   2061 ** Function         gatt_cmd_enq
   2062 **
   2063 ** Description      Enqueue this command.
   2064 **
   2065 ** Returns          None.
   2066 **
   2067 *******************************************************************************/
   2068 BOOLEAN gatt_cmd_enq(tGATT_TCB *p_tcb, UINT16 clcb_idx, BOOLEAN to_send, UINT8 op_code, BT_HDR *p_buf)
   2069 {
   2070     tGATT_CMD_Q  *p_cmd = &p_tcb->cl_cmd_q[p_tcb->next_slot_inq];
   2071 
   2072     p_cmd->to_send = to_send; /* waiting to be sent */
   2073     p_cmd->op_code  = op_code;
   2074     p_cmd->p_cmd    = p_buf;
   2075     p_cmd->clcb_idx = clcb_idx;
   2076 
   2077     if (!to_send)
   2078     {
   2079         p_tcb->pending_cl_req = p_tcb->next_slot_inq;
   2080     }
   2081 
   2082     p_tcb->next_slot_inq ++;
   2083     p_tcb->next_slot_inq %= GATT_CL_MAX_LCB;
   2084 
   2085     return TRUE;
   2086 }
   2087 
   2088 /*******************************************************************************
   2089 **
   2090 ** Function         gatt_cmd_dequeue
   2091 **
   2092 ** Description      dequeue the command in the client CCB command queue.
   2093 **
   2094 ** Returns          total number of clcb found.
   2095 **
   2096 *******************************************************************************/
   2097 tGATT_CLCB * gatt_cmd_dequeue(tGATT_TCB *p_tcb, UINT8 *p_op_code)
   2098 {
   2099     tGATT_CMD_Q  *p_cmd = &p_tcb->cl_cmd_q[p_tcb->pending_cl_req];
   2100     tGATT_CLCB *p_clcb = NULL;
   2101 
   2102     if (p_tcb->pending_cl_req != p_tcb->next_slot_inq)
   2103     {
   2104         p_clcb = &gatt_cb.clcb[p_cmd->clcb_idx];
   2105 
   2106         *p_op_code = p_cmd->op_code;
   2107 
   2108         p_tcb->pending_cl_req ++;
   2109         p_tcb->pending_cl_req %= GATT_CL_MAX_LCB;
   2110     }
   2111 
   2112     return p_clcb;
   2113 }
   2114 
   2115 /*******************************************************************************
   2116 **
   2117 ** Function         gatt_send_write_msg
   2118 **
   2119 ** Description      This real function send out the ATT message for write.
   2120 **
   2121 ** Returns          status code
   2122 **
   2123 *******************************************************************************/
   2124 UINT8 gatt_send_write_msg (tGATT_TCB *p_tcb, UINT16 clcb_idx, UINT8 op_code,
   2125                            UINT16 handle, UINT16 len,
   2126                            UINT16 offset, UINT8 *p_data)
   2127 {
   2128     tGATT_CL_MSG     msg;
   2129 
   2130     msg.attr_value.handle = handle;
   2131     msg.attr_value.len = len;
   2132     msg.attr_value.offset = offset;
   2133 
   2134     memcpy (msg.attr_value.value, p_data, len);
   2135 
   2136     /* write by handle */
   2137     return attp_send_cl_msg(p_tcb, clcb_idx, op_code, &msg);
   2138 }
   2139 
   2140 /*******************************************************************************
   2141 **
   2142 ** Function         gatt_act_send_browse
   2143 **
   2144 ** Description      This function ends a browse command request, including read
   2145 **                  information request and read by type request.
   2146 **
   2147 ** Returns          status code
   2148 **
   2149 *******************************************************************************/
   2150 UINT8 gatt_act_send_browse(tGATT_TCB *p_tcb, UINT16 index, UINT8 op, UINT16 s_handle,
   2151                            UINT16 e_handle, tBT_UUID uuid)
   2152 {
   2153     tGATT_CL_MSG     msg;
   2154 
   2155     msg.browse.s_handle = s_handle;
   2156     msg.browse.e_handle   = e_handle;
   2157     memcpy(&msg.browse.uuid, &uuid, sizeof(tBT_UUID));
   2158 
   2159     /* write by handle */
   2160     return attp_send_cl_msg(p_tcb, index, op, &msg);
   2161 }
   2162 
   2163 /*******************************************************************************
   2164 **
   2165 ** Function         gatt_end_operation
   2166 **
   2167 ** Description      This function ends a discovery, send callback and finalize
   2168 **                  some control value.
   2169 **
   2170 ** Returns          16 bits uuid.
   2171 **
   2172 *******************************************************************************/
   2173 void gatt_end_operation(tGATT_CLCB *p_clcb, tGATT_STATUS status, void *p_data)
   2174 {
   2175     tGATT_CL_COMPLETE   cb_data;
   2176     tGATT_CMPL_CBACK    *p_cmpl_cb = (p_clcb->p_reg) ? p_clcb->p_reg->app_cb.p_cmpl_cb : NULL;
   2177     UINT8               op = p_clcb->operation, disc_type=GATT_DISC_MAX;
   2178     tGATT_DISC_CMPL_CB  *p_disc_cmpl_cb = (p_clcb->p_reg) ? p_clcb->p_reg->app_cb.p_disc_cmpl_cb : NULL;
   2179     UINT16              conn_id;
   2180     UINT8               operation;
   2181 
   2182     GATT_TRACE_DEBUG ("gatt_end_operation status=%d op=%d subtype=%d",
   2183                        status, p_clcb->operation, p_clcb->op_subtype);
   2184     memset(&cb_data.att_value, 0, sizeof(tGATT_VALUE));
   2185 
   2186     if (p_cmpl_cb != NULL && p_clcb->operation != 0)
   2187     {
   2188         if (p_clcb->operation == GATTC_OPTYPE_READ)
   2189         {
   2190             cb_data.att_value.handle   = p_clcb->s_handle;
   2191             cb_data.att_value.len      = p_clcb->counter;
   2192 
   2193             if (p_data && p_clcb->counter)
   2194                 memcpy (cb_data.att_value.value, p_data, cb_data.att_value.len);
   2195         }
   2196 
   2197         if (p_clcb->operation == GATTC_OPTYPE_WRITE)
   2198         {
   2199             memset(&cb_data.att_value, 0, sizeof(tGATT_VALUE));
   2200             cb_data.handle           =
   2201             cb_data.att_value.handle = p_clcb->s_handle;
   2202             if (p_clcb->op_subtype == GATT_WRITE_PREPARE)
   2203             {
   2204                 if (p_data)
   2205                 {
   2206                     cb_data.att_value = *((tGATT_VALUE *) p_data);
   2207                 }
   2208                 else
   2209                 {
   2210                     GATT_TRACE_DEBUG("Rcv Prepare write rsp but no data");
   2211                 }
   2212             }
   2213         }
   2214 
   2215         if (p_clcb->operation == GATTC_OPTYPE_CONFIG)
   2216             cb_data.mtu = p_clcb->p_tcb->payload_size;
   2217 
   2218         if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY)
   2219         {
   2220             disc_type = p_clcb->op_subtype;
   2221         }
   2222     }
   2223 
   2224     osi_free_and_reset((void **)&p_clcb->p_attr_buf);
   2225 
   2226     operation =  p_clcb->operation;
   2227     conn_id = p_clcb->conn_id;
   2228     alarm_cancel(p_clcb->gatt_rsp_timer_ent);
   2229 
   2230     gatt_clcb_dealloc(p_clcb);
   2231 
   2232     if (p_disc_cmpl_cb && (op == GATTC_OPTYPE_DISCOVERY))
   2233         (*p_disc_cmpl_cb)(conn_id, disc_type, status);
   2234     else if (p_cmpl_cb && op)
   2235         (*p_cmpl_cb)(conn_id, op, status, &cb_data);
   2236     else
   2237         GATT_TRACE_WARNING ("gatt_end_operation not sent out op=%d p_disc_cmpl_cb:%p p_cmpl_cb:%p",
   2238                              operation, p_disc_cmpl_cb, p_cmpl_cb);
   2239 }
   2240 
   2241 /*******************************************************************************
   2242 **
   2243 ** Function         gatt_cleanup_upon_disc
   2244 **
   2245 ** Description      This function cleans up the control blocks when L2CAP channel
   2246 **                  disconnect.
   2247 **
   2248 ** Returns          16 bits uuid.
   2249 **
   2250 *******************************************************************************/
   2251 void gatt_cleanup_upon_disc(BD_ADDR bda, UINT16 reason, tBT_TRANSPORT transport)
   2252 {
   2253     tGATT_TCB       *p_tcb = NULL;
   2254     tGATT_CLCB      *p_clcb;
   2255     UINT8           i;
   2256     UINT16          conn_id;
   2257     tGATT_REG        *p_reg=NULL;
   2258 
   2259 
   2260     GATT_TRACE_DEBUG ("gatt_cleanup_upon_disc ");
   2261 
   2262     if ((p_tcb = gatt_find_tcb_by_addr(bda, transport)) != NULL)
   2263     {
   2264         GATT_TRACE_DEBUG ("found p_tcb ");
   2265         gatt_set_ch_state(p_tcb, GATT_CH_CLOSE);
   2266         for (i = 0; i < GATT_CL_MAX_LCB; i ++)
   2267         {
   2268             p_clcb = &gatt_cb.clcb[i];
   2269             if (p_clcb->in_use && p_clcb->p_tcb == p_tcb)
   2270             {
   2271                 alarm_cancel(p_clcb->gatt_rsp_timer_ent);
   2272                 GATT_TRACE_DEBUG ("found p_clcb conn_id=%d clcb_idx=%d", p_clcb->conn_id, p_clcb->clcb_idx);
   2273                 if (p_clcb->operation != GATTC_OPTYPE_NONE)
   2274                     gatt_end_operation(p_clcb, GATT_ERROR, NULL);
   2275 
   2276                 gatt_clcb_dealloc(p_clcb);
   2277 
   2278             }
   2279         }
   2280 
   2281         alarm_free(p_tcb->ind_ack_timer);
   2282         p_tcb->ind_ack_timer = NULL;
   2283         alarm_free(p_tcb->conf_timer);
   2284         p_tcb->conf_timer = NULL;
   2285         gatt_free_pending_ind(p_tcb);
   2286         gatt_free_pending_enc_queue(p_tcb);
   2287         fixed_queue_free(p_tcb->sr_cmd.multi_rsp_q, NULL);
   2288         p_tcb->sr_cmd.multi_rsp_q = NULL;
   2289 
   2290         for (i = 0; i < GATT_MAX_APPS; i ++)
   2291         {
   2292             p_reg = &gatt_cb.cl_rcb[i];
   2293             if (p_reg->in_use && p_reg->app_cb.p_conn_cb)
   2294             {
   2295                 conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if);
   2296                 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);
   2297                 (*p_reg->app_cb.p_conn_cb)(p_reg->gatt_if,  bda, conn_id, FALSE, reason, transport);
   2298             }
   2299         }
   2300         memset(p_tcb, 0, sizeof(tGATT_TCB));
   2301 
   2302     }
   2303     GATT_TRACE_DEBUG ("exit gatt_cleanup_upon_disc ");
   2304 }
   2305 /*******************************************************************************
   2306 **
   2307 ** Function         gatt_dbg_req_op_name
   2308 **
   2309 ** Description      Get op code description name, for debug information.
   2310 **
   2311 ** Returns          UINT8 *: name of the operation.
   2312 **
   2313 *******************************************************************************/
   2314 UINT8 * gatt_dbg_op_name(UINT8 op_code)
   2315 {
   2316     UINT8 pseduo_op_code_idx = op_code & (~GATT_WRITE_CMD_MASK);
   2317 
   2318     if (op_code == GATT_CMD_WRITE )
   2319     {
   2320         pseduo_op_code_idx = 0x14; /* just an index to op_code_name */
   2321 
   2322     }
   2323 
   2324     if (op_code == GATT_SIGN_CMD_WRITE)
   2325     {
   2326         pseduo_op_code_idx = 0x15; /* just an index to op_code_name */
   2327     }
   2328 
   2329     if (pseduo_op_code_idx <= GATT_OP_CODE_MAX)
   2330         return(UINT8*) op_code_name[pseduo_op_code_idx];
   2331     else
   2332         return(UINT8 *)"Op Code Exceed Max";
   2333 }
   2334 
   2335 /*******************************************************************************
   2336 **
   2337 ** Function         gatt_dbg_display_uuid
   2338 **
   2339 ** Description      Disaplay the UUID
   2340 **
   2341 ** Returns          None
   2342 **
   2343 *******************************************************************************/
   2344 void gatt_dbg_display_uuid(tBT_UUID bt_uuid)
   2345 {
   2346     char str_buf[50];
   2347     int x = 0;
   2348 
   2349     if (bt_uuid.len == LEN_UUID_16)
   2350     {
   2351         sprintf(str_buf, "0x%04x", bt_uuid.uu.uuid16);
   2352     }
   2353     else if (bt_uuid.len == LEN_UUID_32)
   2354     {
   2355         sprintf(str_buf, "0x%08x", (unsigned int)bt_uuid.uu.uuid32);
   2356     }
   2357     else if (bt_uuid.len == LEN_UUID_128)
   2358     {
   2359         x += sprintf(&str_buf[x], "0x%02x%02x%02x%02x%02x%02x%02x%02x",
   2360                      bt_uuid.uu.uuid128[15], bt_uuid.uu.uuid128[14],
   2361                      bt_uuid.uu.uuid128[13], bt_uuid.uu.uuid128[12],
   2362                      bt_uuid.uu.uuid128[11], bt_uuid.uu.uuid128[10],
   2363                      bt_uuid.uu.uuid128[9], bt_uuid.uu.uuid128[8]);
   2364         sprintf(&str_buf[x], "%02x%02x%02x%02x%02x%02x%02x%02x",
   2365                 bt_uuid.uu.uuid128[7], bt_uuid.uu.uuid128[6],
   2366                 bt_uuid.uu.uuid128[5], bt_uuid.uu.uuid128[4],
   2367                 bt_uuid.uu.uuid128[3], bt_uuid.uu.uuid128[2],
   2368                 bt_uuid.uu.uuid128[1], bt_uuid.uu.uuid128[0]);
   2369     }
   2370     else
   2371         strlcpy(str_buf, "Unknown UUID 0", sizeof(str_buf));
   2372 
   2373     GATT_TRACE_DEBUG ("UUID=[%s]", str_buf);
   2374 }
   2375 
   2376 
   2377 /*******************************************************************************
   2378 **
   2379 ** Function         gatt_is_bg_dev_for_app
   2380 **
   2381 ** Description      find is this one of the background devices for the application
   2382 **
   2383 ** Returns          TRUE this is one of the background devices for the  application
   2384 **
   2385 *******************************************************************************/
   2386 BOOLEAN gatt_is_bg_dev_for_app(tGATT_BG_CONN_DEV *p_dev, tGATT_IF gatt_if)
   2387 {
   2388     UINT8   i;
   2389 
   2390     for (i = 0; i < GATT_MAX_APPS; i ++ )
   2391     {
   2392         if (p_dev->in_use && (p_dev->gatt_if[i] == gatt_if))
   2393         {
   2394             return TRUE;
   2395         }
   2396     }
   2397     return FALSE;
   2398 }
   2399 /*******************************************************************************
   2400 **
   2401 ** Function         gatt_find_bg_dev
   2402 **
   2403 ** Description      find background connection device from the list.
   2404 **
   2405 ** Returns          pointer to the device record
   2406 **
   2407 *******************************************************************************/
   2408 tGATT_BG_CONN_DEV * gatt_find_bg_dev(BD_ADDR remote_bda)
   2409 {
   2410     tGATT_BG_CONN_DEV    *p_dev_list = &gatt_cb.bgconn_dev[0];
   2411     UINT8   i;
   2412 
   2413     for (i = 0; i < GATT_MAX_BG_CONN_DEV; i ++, p_dev_list ++)
   2414     {
   2415         if (p_dev_list->in_use && !memcmp(p_dev_list->remote_bda, remote_bda, BD_ADDR_LEN))
   2416         {
   2417             return p_dev_list;
   2418         }
   2419     }
   2420     return NULL;
   2421 }
   2422 /*******************************************************************************
   2423 **
   2424 ** Function         gatt_alloc_bg_dev
   2425 **
   2426 ** Description      allocate a background connection device record
   2427 **
   2428 ** Returns          pointer to the device record
   2429 **
   2430 *******************************************************************************/
   2431 tGATT_BG_CONN_DEV * gatt_alloc_bg_dev(BD_ADDR remote_bda)
   2432 {
   2433     tGATT_BG_CONN_DEV    *p_dev_list = &gatt_cb.bgconn_dev[0];
   2434     UINT8   i;
   2435 
   2436     for (i = 0; i < GATT_MAX_BG_CONN_DEV; i ++, p_dev_list ++)
   2437     {
   2438         if (!p_dev_list->in_use)
   2439         {
   2440             p_dev_list->in_use = TRUE;
   2441             memcpy(p_dev_list->remote_bda, remote_bda, BD_ADDR_LEN);
   2442 
   2443             return p_dev_list;
   2444         }
   2445     }
   2446     return NULL;
   2447 }
   2448 
   2449 /*******************************************************************************
   2450 **
   2451 ** Function         gatt_add_bg_dev_list
   2452 **
   2453 ** Description      add/remove device from the back ground connection device list
   2454 **
   2455 ** Returns          TRUE if device added to the list; FALSE failed
   2456 **
   2457 *******************************************************************************/
   2458 BOOLEAN gatt_add_bg_dev_list(tGATT_REG *p_reg,  BD_ADDR bd_addr, BOOLEAN is_initator)
   2459 {
   2460     tGATT_IF gatt_if =  p_reg->gatt_if;
   2461     tGATT_BG_CONN_DEV   *p_dev = NULL;
   2462     UINT8       i;
   2463     BOOLEAN      ret = FALSE;
   2464 
   2465     if ((p_dev = gatt_find_bg_dev(bd_addr)) == NULL)
   2466     {
   2467         p_dev = gatt_alloc_bg_dev(bd_addr);
   2468     }
   2469 
   2470     if (p_dev)
   2471     {
   2472         for (i = 0; i < GATT_MAX_APPS; i ++)
   2473         {
   2474             if (is_initator)
   2475             {
   2476                 if (p_dev->gatt_if[i] == gatt_if)
   2477                 {
   2478                     GATT_TRACE_ERROR("device already in iniator white list");
   2479                     return TRUE;
   2480                 }
   2481                 else if (p_dev->gatt_if[i] == 0)
   2482                 {
   2483                     p_dev->gatt_if[i] = gatt_if;
   2484                     if (i == 0)
   2485                         ret = BTM_BleUpdateBgConnDev(TRUE, bd_addr);
   2486                     else
   2487                         ret = TRUE;
   2488                     break;
   2489                 }
   2490             }
   2491             else
   2492             {
   2493                 if (p_dev->listen_gif[i] == gatt_if)
   2494                 {
   2495                     GATT_TRACE_ERROR("device already in adv white list");
   2496                     return TRUE;
   2497                 }
   2498                 else if (p_dev->listen_gif[i] == 0)
   2499                 {
   2500                     if (p_reg->listening == GATT_LISTEN_TO_ALL)
   2501                         p_reg->listening = GATT_LISTEN_TO_NONE;
   2502 
   2503                     p_reg->listening ++;
   2504                     p_dev->listen_gif[i] = gatt_if;
   2505 
   2506                     if (i == 0)
   2507                         ret = BTM_BleUpdateAdvWhitelist(TRUE, bd_addr);
   2508                     else
   2509                         ret = TRUE;
   2510                     break;
   2511                 }
   2512             }
   2513         }
   2514     }
   2515     else
   2516     {
   2517         GATT_TRACE_ERROR("no device record available");
   2518     }
   2519 
   2520     return ret;
   2521 }
   2522 
   2523 /*******************************************************************************
   2524 **
   2525 ** Function         gatt_remove_bg_dev_for_app
   2526 **
   2527 ** Description      Remove the application interface for the specified background device
   2528 **
   2529 ** Returns          Boolean
   2530 **
   2531 *******************************************************************************/
   2532 BOOLEAN gatt_remove_bg_dev_for_app(tGATT_IF gatt_if, BD_ADDR bd_addr)
   2533 {
   2534     tGATT_TCB    *p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE);
   2535     BOOLEAN       status;
   2536 
   2537     if (p_tcb)
   2538         gatt_update_app_use_link_flag(gatt_if, p_tcb, FALSE, FALSE);
   2539     status = gatt_update_auto_connect_dev(gatt_if, FALSE, bd_addr, TRUE);
   2540     return status;
   2541 }
   2542 
   2543 
   2544 /*******************************************************************************
   2545 **
   2546 ** Function         gatt_get_num_apps_for_bg_dev
   2547 **
   2548 ** Description      Gte the number of applciations for the specified background device
   2549 **
   2550 ** Returns          UINT8 total number fo applications
   2551 **
   2552 *******************************************************************************/
   2553 UINT8 gatt_get_num_apps_for_bg_dev(BD_ADDR bd_addr)
   2554 {
   2555     tGATT_BG_CONN_DEV   *p_dev = NULL;
   2556     UINT8   i;
   2557     UINT8   cnt = 0;
   2558 
   2559     if ((p_dev = gatt_find_bg_dev(bd_addr)) != NULL)
   2560     {
   2561         for (i = 0; i < GATT_MAX_APPS; i ++)
   2562         {
   2563             if (p_dev->gatt_if[i])
   2564                 cnt++;
   2565         }
   2566     }
   2567     return cnt;
   2568 }
   2569 
   2570 /*******************************************************************************
   2571 **
   2572 ** Function         gatt_find_app_for_bg_dev
   2573 **
   2574 ** Description      find the application interface for the specified background device
   2575 **
   2576 ** Returns          Boolean
   2577 **
   2578 *******************************************************************************/
   2579 BOOLEAN gatt_find_app_for_bg_dev(BD_ADDR bd_addr, tGATT_IF *p_gatt_if)
   2580 {
   2581     tGATT_BG_CONN_DEV   *p_dev = NULL;
   2582     UINT8   i;
   2583     BOOLEAN ret = FALSE;
   2584 
   2585     if ((p_dev = gatt_find_bg_dev(bd_addr)) == NULL)
   2586     {
   2587         return ret;
   2588     }
   2589 
   2590     for (i = 0; i < GATT_MAX_APPS; i ++)
   2591     {
   2592         if (p_dev->gatt_if[i] != 0 )
   2593         {
   2594             *p_gatt_if = p_dev->gatt_if[i];
   2595             ret = TRUE;
   2596             break;
   2597         }
   2598     }
   2599     return ret;
   2600 }
   2601 
   2602 
   2603 /*******************************************************************************
   2604 **
   2605 ** Function         gatt_remove_bg_dev_from_list
   2606 **
   2607 ** Description      add/remove device from the back ground connection device list or
   2608 **                  listening to advertising list.
   2609 **
   2610 ** Returns          pointer to the device record
   2611 **
   2612 *******************************************************************************/
   2613 BOOLEAN gatt_remove_bg_dev_from_list(tGATT_REG *p_reg, BD_ADDR bd_addr, BOOLEAN is_initiator)
   2614 {
   2615     tGATT_IF gatt_if = p_reg->gatt_if;
   2616     tGATT_BG_CONN_DEV   *p_dev = NULL;
   2617     UINT8   i, j;
   2618     BOOLEAN ret = FALSE;
   2619 
   2620     if ((p_dev = gatt_find_bg_dev(bd_addr)) == NULL)
   2621     {
   2622         return ret;
   2623     }
   2624 
   2625     for (i = 0; i < GATT_MAX_APPS && (p_dev->gatt_if[i] > 0 || p_dev->listen_gif[i]); i ++)
   2626     {
   2627         if (is_initiator)
   2628         {
   2629             if (p_dev->gatt_if[i] == gatt_if)
   2630             {
   2631                 p_dev->gatt_if[i] = 0;
   2632                 /* move all element behind one forward */
   2633                 for (j = i + 1; j < GATT_MAX_APPS; j ++)
   2634                     p_dev->gatt_if[j - 1] = p_dev->gatt_if[j];
   2635 
   2636                 if (p_dev->gatt_if[0] == 0)
   2637                     ret = BTM_BleUpdateBgConnDev(FALSE, p_dev->remote_bda);
   2638                 else
   2639                     ret = TRUE;
   2640 
   2641                 break;
   2642             }
   2643         }
   2644         else
   2645         {
   2646             if (p_dev->listen_gif[i] == gatt_if)
   2647             {
   2648                 p_dev->listen_gif[i] = 0;
   2649                 p_reg->listening --;
   2650                 /* move all element behind one forward */
   2651                 for (j = i + 1; j < GATT_MAX_APPS; j ++)
   2652                     p_dev->listen_gif[j - 1] = p_dev->listen_gif[j];
   2653 
   2654                 if (p_dev->listen_gif[0] == 0)
   2655                     ret = BTM_BleUpdateAdvWhitelist(FALSE, p_dev->remote_bda);
   2656                 else
   2657                     ret = TRUE;
   2658                 break;
   2659             }
   2660         }
   2661     }
   2662 
   2663     if (i != GATT_MAX_APPS && p_dev->gatt_if[0] == 0 && p_dev->listen_gif[0] == 0)
   2664     {
   2665         memset(p_dev, 0, sizeof(tGATT_BG_CONN_DEV));
   2666     }
   2667 
   2668     return ret;
   2669 }
   2670 /*******************************************************************************
   2671 **
   2672 ** Function         gatt_deregister_bgdev_list
   2673 **
   2674 ** Description      deregister all related back ground connetion device.
   2675 **
   2676 ** Returns          pointer to the device record
   2677 **
   2678 *******************************************************************************/
   2679 void gatt_deregister_bgdev_list(tGATT_IF gatt_if)
   2680 {
   2681     tGATT_BG_CONN_DEV    *p_dev_list = &gatt_cb.bgconn_dev[0];
   2682     UINT8 i , j, k;
   2683     tGATT_REG       *p_reg = gatt_get_regcb(gatt_if);
   2684 
   2685     /* update the BG conn device list */
   2686     for (i = 0 ; i <GATT_MAX_BG_CONN_DEV; i ++, p_dev_list ++ )
   2687     {
   2688         if (p_dev_list->in_use)
   2689         {
   2690             for (j = 0; j < GATT_MAX_APPS; j ++)
   2691             {
   2692                 if (p_dev_list->gatt_if[j] == 0 && p_dev_list->listen_gif[j] == 0)
   2693                     break;
   2694 
   2695                 if (p_dev_list->gatt_if[j] == gatt_if)
   2696                 {
   2697                     for (k = j + 1; k < GATT_MAX_APPS; k ++)
   2698                         p_dev_list->gatt_if[k - 1] = p_dev_list->gatt_if[k];
   2699 
   2700                     if (p_dev_list->gatt_if[0] == 0)
   2701                         BTM_BleUpdateBgConnDev(FALSE, p_dev_list->remote_bda);
   2702                 }
   2703 
   2704                 if (p_dev_list->listen_gif[j] == gatt_if)
   2705                 {
   2706                     p_dev_list->listen_gif[j] = 0;
   2707 
   2708                     if (p_reg != NULL && p_reg->listening > 0)
   2709                         p_reg->listening --;
   2710 
   2711                     /* move all element behind one forward */
   2712                     for (k = j + 1; k < GATT_MAX_APPS; k ++)
   2713                         p_dev_list->listen_gif[k - 1] = p_dev_list->listen_gif[k];
   2714 
   2715                     if (p_dev_list->listen_gif[0] == 0)
   2716                         BTM_BleUpdateAdvWhitelist(FALSE, p_dev_list->remote_bda);
   2717                 }
   2718             }
   2719         }
   2720     }
   2721 }
   2722 
   2723 
   2724 /*******************************************************************************
   2725 **
   2726 ** Function         gatt_reset_bgdev_list
   2727 **
   2728 ** Description      reset bg device list
   2729 **
   2730 ** Returns          pointer to the device record
   2731 **
   2732 *******************************************************************************/
   2733 void gatt_reset_bgdev_list(void)
   2734 {
   2735     memset(&gatt_cb.bgconn_dev, 0 , sizeof(tGATT_BG_CONN_DEV)*GATT_MAX_BG_CONN_DEV);
   2736 
   2737 }
   2738 /*******************************************************************************
   2739 **
   2740 ** Function         gatt_update_auto_connect_dev
   2741 **
   2742 ** Description      This function add or remove a device for background connection
   2743 **                  procedure.
   2744 **
   2745 ** Parameters       gatt_if: Application ID.
   2746 **                  add: add peer device
   2747 **                  bd_addr: peer device address.
   2748 **
   2749 ** Returns          TRUE if connection started; FALSE if connection start failure.
   2750 **
   2751 *******************************************************************************/
   2752 BOOLEAN gatt_update_auto_connect_dev (tGATT_IF gatt_if, BOOLEAN add, BD_ADDR bd_addr, BOOLEAN is_initator)
   2753 {
   2754     BOOLEAN         ret = FALSE;
   2755     tGATT_REG        *p_reg;
   2756     tGATT_TCB       *p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE);
   2757 
   2758     GATT_TRACE_API ("gatt_update_auto_connect_dev ");
   2759     /* Make sure app is registered */
   2760     if ((p_reg = gatt_get_regcb(gatt_if)) == NULL)
   2761     {
   2762         GATT_TRACE_ERROR("gatt_update_auto_connect_dev - gatt_if is not registered", gatt_if);
   2763         return(FALSE);
   2764     }
   2765 
   2766     if (add)
   2767     {
   2768         ret = gatt_add_bg_dev_list(p_reg, bd_addr, is_initator);
   2769 
   2770         if (ret && p_tcb != NULL)
   2771         {
   2772             /* if a connected device, update the link holding number */
   2773             gatt_update_app_use_link_flag(gatt_if, p_tcb, TRUE, TRUE);
   2774         }
   2775     }
   2776     else
   2777     {
   2778         ret = gatt_remove_bg_dev_from_list(p_reg, bd_addr, is_initator);
   2779     }
   2780     return ret;
   2781 }
   2782 
   2783 
   2784 
   2785 /*******************************************************************************
   2786 **
   2787 ** Function     gatt_add_pending_new_srv_start
   2788 **
   2789 ** Description  Add a pending new srv start to the new service start queue
   2790 **
   2791 ** Returns    Pointer to the new service start buffer, NULL no buffer available
   2792 **
   2793 *******************************************************************************/
   2794 tGATT_PENDING_ENC_CLCB* gatt_add_pending_enc_channel_clcb(tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb)
   2795 {
   2796     tGATT_PENDING_ENC_CLCB *p_buf =
   2797         (tGATT_PENDING_ENC_CLCB *)osi_malloc(sizeof(tGATT_PENDING_ENC_CLCB));
   2798 
   2799     GATT_TRACE_DEBUG ("%s", __func__);
   2800     GATT_TRACE_DEBUG("enqueue a new pending encryption channel clcb");
   2801 
   2802     p_buf->p_clcb = p_clcb;
   2803     fixed_queue_enqueue(p_tcb->pending_enc_clcb, p_buf);
   2804 
   2805     return p_buf;
   2806 }
   2807 /*******************************************************************************
   2808 **
   2809 ** Function     gatt_update_listen_mode
   2810 **
   2811 ** Description  update peripheral role listening mode
   2812 **
   2813 ** Returns    Pointer to the new service start buffer, NULL no buffer available
   2814 **
   2815 *******************************************************************************/
   2816 BOOLEAN gatt_update_listen_mode(void)
   2817 {
   2818     UINT8           ii = 0;
   2819     tGATT_REG       *p_reg = &gatt_cb.cl_rcb[0];
   2820     UINT8           listening = 0;
   2821     UINT16          connectability, window, interval;
   2822     BOOLEAN         rt = TRUE;
   2823 
   2824     for (; ii < GATT_MAX_APPS; ii ++, p_reg ++)
   2825     {
   2826         if ( p_reg->in_use && p_reg->listening > listening)
   2827         {
   2828             listening = p_reg->listening;
   2829         }
   2830     }
   2831 
   2832     if (listening == GATT_LISTEN_TO_ALL ||
   2833         listening == GATT_LISTEN_TO_NONE)
   2834         BTM_BleUpdateAdvFilterPolicy (AP_SCAN_CONN_ALL);
   2835     else
   2836         BTM_BleUpdateAdvFilterPolicy (AP_SCAN_CONN_WL);
   2837 
   2838     if (rt)
   2839     {
   2840         connectability = BTM_ReadConnectability (&window, &interval);
   2841 
   2842         if (listening != GATT_LISTEN_TO_NONE)
   2843         {
   2844             connectability |= BTM_BLE_CONNECTABLE;
   2845         }
   2846         else
   2847         {
   2848             if ((connectability & BTM_BLE_CONNECTABLE) == 0)
   2849             connectability &= ~BTM_BLE_CONNECTABLE;
   2850         }
   2851         /* turning on the adv now */
   2852         btm_ble_set_connectability(connectability);
   2853     }
   2854 
   2855     return rt;
   2856 
   2857 }
   2858 #endif
   2859 
   2860 
   2861