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