Home | History | Annotate | Download | only in gatt
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2009-2012 Broadcom Corporation
      4  *
      5  *  Licensed under the Apache License, Version 2.0 (the "License");
      6  *  you may not use this file except in compliance with the License.
      7  *  You may obtain a copy of the License at:
      8  *
      9  *  http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  *
     17  ******************************************************************************/
     18 
     19 /******************************************************************************
     20  *
     21  *  this file contains GATT utility functions
     22  *
     23  ******************************************************************************/
     24 #include "bt_target.h"
     25 #include "bt_utils.h"
     26 #include "osi/include/osi.h"
     27 
     28 #include <string.h>
     29 #include "bt_common.h"
     30 #include "stdio.h"
     31 
     32 #include "btm_int.h"
     33 #include "gatt_api.h"
     34 #include "gatt_int.h"
     35 #include "gattdefs.h"
     36 #include "l2cdefs.h"
     37 #include "sdp_api.h"
     38 /* check if [x, y] and [a, b] have overlapping range */
     39 #define GATT_VALIDATE_HANDLE_RANGE(x, y, a, b) ((y) >= (a) && (x) <= (b))
     40 
     41 #define GATT_GET_NEXT_VALID_HANDLE(x) (((x) / 10 + 1) * 10)
     42 
     43 const char* const op_code_name[] = {"UNKNOWN",
     44                                     "ATT_RSP_ERROR",
     45                                     "ATT_REQ_MTU",
     46                                     "ATT_RSP_MTU",
     47                                     "ATT_REQ_READ_INFO",
     48                                     "ATT_RSP_READ_INFO",
     49                                     "ATT_REQ_FIND_TYPE_VALUE",
     50                                     "ATT_RSP_FIND_TYPE_VALUE",
     51                                     "ATT_REQ_READ_BY_TYPE",
     52                                     "ATT_RSP_READ_BY_TYPE",
     53                                     "ATT_REQ_READ",
     54                                     "ATT_RSP_READ",
     55                                     "ATT_REQ_READ_BLOB",
     56                                     "ATT_RSP_READ_BLOB",
     57                                     "GATT_REQ_READ_MULTI",
     58                                     "GATT_RSP_READ_MULTI",
     59                                     "GATT_REQ_READ_BY_GRP_TYPE",
     60                                     "GATT_RSP_READ_BY_GRP_TYPE",
     61                                     "ATT_REQ_WRITE",
     62                                     "ATT_RSP_WRITE",
     63                                     "ATT_CMD_WRITE",
     64                                     "ATT_SIGN_CMD_WRITE",
     65                                     "ATT_REQ_PREPARE_WRITE",
     66                                     "ATT_RSP_PREPARE_WRITE",
     67                                     "ATT_REQ_EXEC_WRITE",
     68                                     "ATT_RSP_EXEC_WRITE",
     69                                     "Reserved",
     70                                     "ATT_HANDLE_VALUE_NOTIF",
     71                                     "Reserved",
     72                                     "ATT_HANDLE_VALUE_IND",
     73                                     "ATT_HANDLE_VALUE_CONF",
     74                                     "ATT_OP_CODE_MAX"};
     75 
     76 static const uint8_t base_uuid[LEN_UUID_128] = {
     77     0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80,
     78     0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
     79 
     80 extern fixed_queue_t* btu_general_alarm_queue;
     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   GATT_TRACE_DEBUG("%s", __func__);
     93 
     94   if (p_tcb->pending_ind_q == NULL) return;
     95 
     96   /* release all queued indications */
     97   while (!fixed_queue_is_empty(p_tcb->pending_ind_q))
     98     osi_free(fixed_queue_try_dequeue(p_tcb->pending_ind_q));
     99   fixed_queue_free(p_tcb->pending_ind_q, NULL);
    100   p_tcb->pending_ind_q = NULL;
    101 }
    102 
    103 /*******************************************************************************
    104  *
    105  * Function         gatt_free_pending_enc_queue
    106  *
    107  * Description       Free all buffers in pending encyption queue
    108  *
    109  * Returns       None
    110  *
    111  ******************************************************************************/
    112 void gatt_free_pending_enc_queue(tGATT_TCB* p_tcb) {
    113   GATT_TRACE_DEBUG("%s", __func__);
    114 
    115   if (p_tcb->pending_enc_clcb == NULL) return;
    116 
    117   /* release all queued indications */
    118   while (!fixed_queue_is_empty(p_tcb->pending_enc_clcb))
    119     osi_free(fixed_queue_try_dequeue(p_tcb->pending_enc_clcb));
    120   fixed_queue_free(p_tcb->pending_enc_clcb, NULL);
    121   p_tcb->pending_enc_clcb = NULL;
    122 }
    123 
    124 /*******************************************************************************
    125  *
    126  * Function         gatt_delete_dev_from_srv_chg_clt_list
    127  *
    128  * Description    Delete a device from the service changed client lit
    129  *
    130  * Returns       None
    131  *
    132  ******************************************************************************/
    133 void gatt_delete_dev_from_srv_chg_clt_list(BD_ADDR bd_addr) {
    134   GATT_TRACE_DEBUG("gatt_delete_dev_from_srv_chg_clt_list");
    135 
    136   tGATTS_SRV_CHG* p_buf = gatt_is_bda_in_the_srv_chg_clt_list(bd_addr);
    137   if (p_buf != NULL) {
    138     if (gatt_cb.cb_info.p_srv_chg_callback) {
    139       /* delete from NV */
    140       tGATTS_SRV_CHG_REQ req;
    141       memcpy(req.srv_chg.bda, bd_addr, BD_ADDR_LEN);
    142       (*gatt_cb.cb_info.p_srv_chg_callback)(GATTS_SRV_CHG_CMD_REMOVE_CLIENT,
    143                                             &req, NULL);
    144     }
    145     osi_free(fixed_queue_try_remove_from_queue(gatt_cb.srv_chg_clt_q, p_buf));
    146   }
    147 }
    148 
    149 /*******************************************************************************
    150  *
    151  * Function         gatt_set_srv_chg
    152  *
    153  * Description      Set the service changed flag to true
    154  *
    155  * Returns        None
    156  *
    157  ******************************************************************************/
    158 void gatt_set_srv_chg(void) {
    159   GATT_TRACE_DEBUG("gatt_set_srv_chg");
    160 
    161   if (fixed_queue_is_empty(gatt_cb.srv_chg_clt_q)) return;
    162 
    163   list_t* list = fixed_queue_get_list(gatt_cb.srv_chg_clt_q);
    164   for (const list_node_t* node = list_begin(list); node != list_end(list);
    165        node = list_next(node)) {
    166     GATT_TRACE_DEBUG("found a srv_chg clt");
    167 
    168     tGATTS_SRV_CHG* p_buf = (tGATTS_SRV_CHG*)list_node(node);
    169     if (!p_buf->srv_changed) {
    170       GATT_TRACE_DEBUG("set srv_changed to true");
    171       p_buf->srv_changed = true;
    172       tGATTS_SRV_CHG_REQ req;
    173       memcpy(&req.srv_chg, p_buf, sizeof(tGATTS_SRV_CHG));
    174       if (gatt_cb.cb_info.p_srv_chg_callback)
    175         (*gatt_cb.cb_info.p_srv_chg_callback)(GATTS_SRV_CHG_CMD_UPDATE_CLIENT,
    176                                               &req, NULL);
    177     }
    178   }
    179 }
    180 
    181 /*******************************************************************************
    182  *
    183  * Function     gatt_add_pending_ind
    184  *
    185  * Description  Add a pending indication
    186  *
    187  * Returns    Pointer to the current pending indication buffer, NULL no buffer
    188  *            available
    189  *
    190  ******************************************************************************/
    191 tGATT_VALUE* gatt_add_pending_ind(tGATT_TCB* p_tcb, tGATT_VALUE* p_ind) {
    192   tGATT_VALUE* p_buf = (tGATT_VALUE*)osi_malloc(sizeof(tGATT_VALUE));
    193 
    194   GATT_TRACE_DEBUG("%s", __func__);
    195   GATT_TRACE_DEBUG("enqueue a pending indication");
    196 
    197   memcpy(p_buf, p_ind, sizeof(tGATT_VALUE));
    198   fixed_queue_enqueue(p_tcb->pending_ind_q, p_buf);
    199 
    200   return p_buf;
    201 }
    202 
    203 /*******************************************************************************
    204  *
    205  * Function     gatt_add_srv_chg_clt
    206  *
    207  * Description  Add a service chnage client to the service change client queue
    208  *
    209  * Returns    Pointer to the service change client buffer; Null no buffer
    210  *            available
    211  *
    212  ******************************************************************************/
    213 tGATTS_SRV_CHG* gatt_add_srv_chg_clt(tGATTS_SRV_CHG* p_srv_chg) {
    214   tGATTS_SRV_CHG* p_buf = (tGATTS_SRV_CHG*)osi_malloc(sizeof(tGATTS_SRV_CHG));
    215 
    216   GATT_TRACE_DEBUG("%s", __func__);
    217   GATT_TRACE_DEBUG("enqueue a srv chg client");
    218 
    219   memcpy(p_buf, p_srv_chg, sizeof(tGATTS_SRV_CHG));
    220   fixed_queue_enqueue(gatt_cb.srv_chg_clt_q, p_buf);
    221 
    222   return p_buf;
    223 }
    224 
    225 /**
    226  * Returns pointer to the handle range buffer starting at handle |handle|,
    227  * nullptr
    228  * if no buffer available
    229  */
    230 tGATT_HDL_LIST_ELEM* gatt_find_hdl_buffer_by_handle(uint16_t handle) {
    231   for (auto& elem : *gatt_cb.hdl_list_info) {
    232     if (elem.asgn_range.s_handle == handle) return &elem;
    233   }
    234 
    235   return nullptr;
    236 }
    237 /*******************************************************************************
    238  *
    239  * Description  Find handle range buffer by app ID, service and service instance
    240  *              ID.
    241  *
    242  * Returns    Pointer to the buffer, NULL no buffer available
    243  *
    244  ******************************************************************************/
    245 std::list<tGATT_HDL_LIST_ELEM>::iterator gatt_find_hdl_buffer_by_app_id(
    246     tBT_UUID* p_app_uuid128, tBT_UUID* p_svc_uuid, uint16_t start_handle) {
    247   auto end_it = gatt_cb.hdl_list_info->end();
    248   auto it = gatt_cb.hdl_list_info->begin();
    249   for (; it != end_it; it++) {
    250     if (gatt_uuid_compare(*p_app_uuid128, it->asgn_range.app_uuid128) &&
    251         gatt_uuid_compare(*p_svc_uuid, it->asgn_range.svc_uuid) &&
    252         (start_handle == it->asgn_range.s_handle)) {
    253       return it;
    254     }
    255   }
    256 
    257   return it;
    258 }
    259 
    260 /**
    261  * free the service attribute database buffers by the owner of the service app
    262  * ID.
    263  */
    264 void gatt_free_srvc_db_buffer_app_id(tBT_UUID* p_app_id) {
    265   auto end_it = gatt_cb.hdl_list_info->end();
    266   for (auto it = gatt_cb.hdl_list_info->begin(); it != end_it; it++) {
    267     if (memcmp(p_app_id, &it->asgn_range.app_uuid128, sizeof(tBT_UUID)) == 0) {
    268       it = gatt_cb.hdl_list_info->erase(it);
    269     }
    270   }
    271 }
    272 
    273 /*******************************************************************************
    274  *
    275  * Function         gatt_find_the_connected_bda
    276  *
    277  * Description      This function find the connected bda
    278  *
    279  * Returns           true if found
    280  *
    281  ******************************************************************************/
    282 bool gatt_find_the_connected_bda(uint8_t start_idx, BD_ADDR bda,
    283                                  uint8_t* p_found_idx,
    284                                  tBT_TRANSPORT* p_transport) {
    285   uint8_t i;
    286   bool found = false;
    287   GATT_TRACE_DEBUG("gatt_find_the_connected_bda start_idx=%d", start_idx);
    288 
    289   for (i = start_idx; i < GATT_MAX_PHY_CHANNEL; i++) {
    290     if (gatt_cb.tcb[i].in_use && gatt_cb.tcb[i].ch_state == GATT_CH_OPEN) {
    291       memcpy(bda, gatt_cb.tcb[i].peer_bda, BD_ADDR_LEN);
    292       *p_found_idx = i;
    293       *p_transport = gatt_cb.tcb[i].transport;
    294       found = true;
    295       GATT_TRACE_DEBUG(
    296           "gatt_find_the_connected_bda bda :%02x-%02x-%02x-%02x-%02x-%02x",
    297           bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);
    298       break;
    299     }
    300   }
    301   GATT_TRACE_DEBUG("gatt_find_the_connected_bda found=%d found_idx=%d", found,
    302                    i);
    303   return found;
    304 }
    305 
    306 /*******************************************************************************
    307  *
    308  * Function         gatt_is_srv_chg_ind_pending
    309  *
    310  * Description      Check whether a service chnaged is in the indication pending
    311  *                  queue or waiting for an Ack already
    312  *
    313  * Returns         bool
    314  *
    315  ******************************************************************************/
    316 bool gatt_is_srv_chg_ind_pending(tGATT_TCB* p_tcb) {
    317   bool srv_chg_ind_pending = false;
    318 
    319   GATT_TRACE_DEBUG("gatt_is_srv_chg_ind_pending is_queue_empty=%d",
    320                    fixed_queue_is_empty(p_tcb->pending_ind_q));
    321 
    322   if (p_tcb->indicate_handle == gatt_cb.handle_of_h_r) {
    323     srv_chg_ind_pending = true;
    324   } else if (!fixed_queue_is_empty(p_tcb->pending_ind_q)) {
    325     list_t* list = fixed_queue_get_list(p_tcb->pending_ind_q);
    326     for (const list_node_t* node = list_begin(list); node != list_end(list);
    327          node = list_next(node)) {
    328       tGATT_VALUE* p_buf = (tGATT_VALUE*)list_node(node);
    329       if (p_buf->handle == gatt_cb.handle_of_h_r) {
    330         srv_chg_ind_pending = true;
    331         break;
    332       }
    333     }
    334   }
    335 
    336   GATT_TRACE_DEBUG("srv_chg_ind_pending = %d", srv_chg_ind_pending);
    337   return srv_chg_ind_pending;
    338 }
    339 
    340 /*******************************************************************************
    341  *
    342  * Function         gatt_is_bda_in_the_srv_chg_clt_list
    343  *
    344  * Description      This function check the specified bda is in the srv chg
    345  *                  client list or not
    346  *
    347  * Returns         pointer to the found elemenet otherwise NULL
    348  *
    349  ******************************************************************************/
    350 tGATTS_SRV_CHG* gatt_is_bda_in_the_srv_chg_clt_list(BD_ADDR bda) {
    351   tGATTS_SRV_CHG* p_buf = NULL;
    352 
    353   GATT_TRACE_DEBUG(
    354       "gatt_is_bda_in_the_srv_chg_clt_list :%02x-%02x-%02x-%02x-%02x-%02x",
    355       bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);
    356 
    357   if (fixed_queue_is_empty(gatt_cb.srv_chg_clt_q)) return NULL;
    358 
    359   list_t* list = fixed_queue_get_list(gatt_cb.srv_chg_clt_q);
    360   for (const list_node_t* node = list_begin(list); node != list_end(list);
    361        node = list_next(node)) {
    362     tGATTS_SRV_CHG* p_buf = (tGATTS_SRV_CHG*)list_node(node);
    363     if (!memcmp(bda, p_buf->bda, BD_ADDR_LEN)) {
    364       GATT_TRACE_DEBUG("bda is in the srv chg clt list");
    365       break;
    366     }
    367   }
    368 
    369   return p_buf;
    370 }
    371 
    372 /*******************************************************************************
    373  *
    374  * Function         gatt_is_bda_connected
    375  *
    376  * Description
    377  *
    378  * Returns          GATT_INDEX_INVALID if not found. Otherwise index to the tcb.
    379  *
    380  ******************************************************************************/
    381 bool gatt_is_bda_connected(BD_ADDR bda) {
    382   uint8_t i = 0;
    383   bool connected = false;
    384 
    385   for (i = 0; i < GATT_MAX_PHY_CHANNEL; i++) {
    386     if (gatt_cb.tcb[i].in_use &&
    387         !memcmp(gatt_cb.tcb[i].peer_bda, bda, BD_ADDR_LEN)) {
    388       connected = true;
    389       break;
    390     }
    391   }
    392   return connected;
    393 }
    394 
    395 /*******************************************************************************
    396  *
    397  * Function         gatt_find_i_tcb_by_addr
    398  *
    399  * Description      Search for an empty tcb entry, and return the index.
    400  *
    401  * Returns          GATT_INDEX_INVALID if not found. Otherwise index to the tcb.
    402  *
    403  ******************************************************************************/
    404 uint8_t gatt_find_i_tcb_by_addr(BD_ADDR bda, tBT_TRANSPORT transport) {
    405   uint8_t i = 0;
    406 
    407   for (; i < GATT_MAX_PHY_CHANNEL; i++) {
    408     if (!memcmp(gatt_cb.tcb[i].peer_bda, bda, BD_ADDR_LEN) &&
    409         gatt_cb.tcb[i].transport == transport) {
    410       return i;
    411     }
    412   }
    413   return GATT_INDEX_INVALID;
    414 }
    415 
    416 /*******************************************************************************
    417  *
    418  * Function         gatt_get_tcb_by_idx
    419  *
    420  * Description      The function get TCB using the TCB index
    421  *
    422  * Returns           NULL if not found. Otherwise index to the tcb.
    423  *
    424  ******************************************************************************/
    425 tGATT_TCB* gatt_get_tcb_by_idx(uint8_t tcb_idx) {
    426   tGATT_TCB* p_tcb = NULL;
    427 
    428   if ((tcb_idx < GATT_MAX_PHY_CHANNEL) && gatt_cb.tcb[tcb_idx].in_use)
    429     p_tcb = &gatt_cb.tcb[tcb_idx];
    430 
    431   return p_tcb;
    432 }
    433 
    434 /*******************************************************************************
    435  *
    436  * Function         gatt_find_tcb_by_addr
    437  *
    438  * Description      Search for an empty tcb entry, and return pointer.
    439  *
    440  * Returns          NULL if not found. Otherwise index to the tcb.
    441  *
    442  ******************************************************************************/
    443 tGATT_TCB* gatt_find_tcb_by_addr(BD_ADDR bda, tBT_TRANSPORT transport) {
    444   tGATT_TCB* p_tcb = NULL;
    445   uint8_t i = 0;
    446 
    447   i = gatt_find_i_tcb_by_addr(bda, transport);
    448   if (i != GATT_INDEX_INVALID) p_tcb = &gatt_cb.tcb[i];
    449 
    450   return p_tcb;
    451 }
    452 /*******************************************************************************
    453  *
    454  * Function         gatt_find_i_tcb_free
    455  *
    456  * Description      Search for an empty tcb entry, and return the index.
    457  *
    458  * Returns          GATT_INDEX_INVALID if not found. Otherwise index to the tcb.
    459  *
    460  ******************************************************************************/
    461 uint8_t gatt_find_i_tcb_free(void) {
    462   uint8_t i = 0, j = GATT_INDEX_INVALID;
    463 
    464   for (i = 0; i < GATT_MAX_PHY_CHANNEL; i++) {
    465     if (!gatt_cb.tcb[i].in_use) {
    466       j = i;
    467       break;
    468     }
    469   }
    470   return j;
    471 }
    472 /*******************************************************************************
    473  *
    474  * Function         gatt_allocate_tcb_by_bdaddr
    475  *
    476  * Description      Locate or allocate a new tcb entry for matching bda.
    477  *
    478  * Returns          GATT_INDEX_INVALID if not found. Otherwise index to the tcb.
    479  *
    480  ******************************************************************************/
    481 tGATT_TCB* gatt_allocate_tcb_by_bdaddr(BD_ADDR bda, tBT_TRANSPORT transport) {
    482   uint8_t i = 0;
    483   bool allocated = false;
    484   tGATT_TCB* p_tcb = NULL;
    485 
    486   /* search for existing tcb with matching bda    */
    487   i = gatt_find_i_tcb_by_addr(bda, transport);
    488   /* find free tcb */
    489   if (i == GATT_INDEX_INVALID) {
    490     i = gatt_find_i_tcb_free();
    491     allocated = true;
    492   }
    493   if (i != GATT_INDEX_INVALID) {
    494     p_tcb = &gatt_cb.tcb[i];
    495 
    496     if (allocated) {
    497       memset(p_tcb, 0, sizeof(tGATT_TCB));
    498       p_tcb->pending_enc_clcb = fixed_queue_new(SIZE_MAX);
    499       p_tcb->pending_ind_q = fixed_queue_new(SIZE_MAX);
    500       p_tcb->conf_timer = alarm_new("gatt.conf_timer");
    501       p_tcb->ind_ack_timer = alarm_new("gatt.ind_ack_timer");
    502       p_tcb->in_use = true;
    503       p_tcb->tcb_idx = i;
    504       p_tcb->transport = transport;
    505     }
    506     memcpy(p_tcb->peer_bda, bda, BD_ADDR_LEN);
    507   }
    508   return p_tcb;
    509 }
    510 
    511 /*******************************************************************************
    512  *
    513  * Function         gatt_convert_uuid16_to_uuid128
    514  *
    515  * Description      Convert a 16 bits UUID to be an standard 128 bits one.
    516  *
    517  * Returns          true if two uuid match; false otherwise.
    518  *
    519  ******************************************************************************/
    520 void gatt_convert_uuid16_to_uuid128(uint8_t uuid_128[LEN_UUID_128],
    521                                     uint16_t uuid_16) {
    522   uint8_t* p = &uuid_128[LEN_UUID_128 - 4];
    523 
    524   memcpy(uuid_128, base_uuid, LEN_UUID_128);
    525 
    526   UINT16_TO_STREAM(p, uuid_16);
    527 }
    528 
    529 /*******************************************************************************
    530  *
    531  * Function         gatt_convert_uuid32_to_uuid128
    532  *
    533  * Description      Convert a 32 bits UUID to be an standard 128 bits one.
    534  *
    535  * Returns          true if two uuid match; false otherwise.
    536  *
    537  ******************************************************************************/
    538 void gatt_convert_uuid32_to_uuid128(uint8_t uuid_128[LEN_UUID_128],
    539                                     uint32_t uuid_32) {
    540   uint8_t* p = &uuid_128[LEN_UUID_128 - 4];
    541 
    542   memcpy(uuid_128, base_uuid, LEN_UUID_128);
    543 
    544   UINT32_TO_STREAM(p, uuid_32);
    545 }
    546 /*******************************************************************************
    547  *
    548  * Function         gatt_uuid_compare
    549  *
    550  * Description      Compare two UUID to see if they are the same.
    551  *
    552  * Returns          true if two uuid match; false otherwise.
    553  *
    554  ******************************************************************************/
    555 bool gatt_uuid_compare(tBT_UUID src, tBT_UUID tar) {
    556   uint8_t su[LEN_UUID_128], tu[LEN_UUID_128];
    557   uint8_t *ps, *pt;
    558 
    559   /* any of the UUID is unspecified */
    560   if (src.len == 0 || tar.len == 0) {
    561     return true;
    562   }
    563 
    564   /* If both are 16-bit, we can do a simple compare */
    565   if (src.len == LEN_UUID_16 && tar.len == LEN_UUID_16) {
    566     return src.uu.uuid16 == tar.uu.uuid16;
    567   }
    568 
    569   /* If both are 32-bit, we can do a simple compare */
    570   if (src.len == LEN_UUID_32 && tar.len == LEN_UUID_32) {
    571     return src.uu.uuid32 == tar.uu.uuid32;
    572   }
    573 
    574   /* One or both of the UUIDs is 128-bit */
    575   if (src.len == LEN_UUID_16) {
    576     /* convert a 16 bits UUID to 128 bits value */
    577     gatt_convert_uuid16_to_uuid128(su, src.uu.uuid16);
    578     ps = su;
    579   } else if (src.len == LEN_UUID_32) {
    580     gatt_convert_uuid32_to_uuid128(su, src.uu.uuid32);
    581     ps = su;
    582   } else
    583     ps = src.uu.uuid128;
    584 
    585   if (tar.len == LEN_UUID_16) {
    586     /* convert a 16 bits UUID to 128 bits value */
    587     gatt_convert_uuid16_to_uuid128(tu, tar.uu.uuid16);
    588     pt = tu;
    589   } else if (tar.len == LEN_UUID_32) {
    590     /* convert a 32 bits UUID to 128 bits value */
    591     gatt_convert_uuid32_to_uuid128(tu, tar.uu.uuid32);
    592     pt = tu;
    593   } else
    594     pt = tar.uu.uuid128;
    595 
    596   return (memcmp(ps, pt, LEN_UUID_128) == 0);
    597 }
    598 
    599 /*******************************************************************************
    600  *
    601  * Function         gatt_build_uuid_to_stream
    602  *
    603  * Description      Add UUID into stream.
    604  *
    605  * Returns          UUID length.
    606  *
    607  ******************************************************************************/
    608 uint8_t gatt_build_uuid_to_stream(uint8_t** p_dst, tBT_UUID uuid) {
    609   uint8_t* p = *p_dst;
    610   uint8_t len = 0;
    611 
    612   if (uuid.len == LEN_UUID_16) {
    613     UINT16_TO_STREAM(p, uuid.uu.uuid16);
    614     len = LEN_UUID_16;
    615   } else if (uuid.len ==
    616              LEN_UUID_32) /* always convert 32 bits into 128 bits as alwats */
    617   {
    618     gatt_convert_uuid32_to_uuid128(p, uuid.uu.uuid32);
    619     p += LEN_UUID_128;
    620     len = LEN_UUID_128;
    621   } else if (uuid.len == LEN_UUID_128) {
    622     ARRAY_TO_STREAM(p, uuid.uu.uuid128, LEN_UUID_128);
    623     len = LEN_UUID_128;
    624   }
    625 
    626   *p_dst = p;
    627   return len;
    628 }
    629 
    630 /*******************************************************************************
    631  *
    632  * Function         gatt_parse_uuid_from_cmd
    633  *
    634  * Description      Convert a 128 bits UUID into a 16 bits UUID.
    635  *
    636  * Returns          true if command sent, otherwise false.
    637  *
    638  ******************************************************************************/
    639 bool gatt_parse_uuid_from_cmd(tBT_UUID* p_uuid_rec, uint16_t uuid_size,
    640                               uint8_t** p_data) {
    641   bool is_base_uuid, ret = true;
    642   uint8_t xx;
    643   uint8_t* p_uuid = *p_data;
    644 
    645   memset(p_uuid_rec, 0, sizeof(tBT_UUID));
    646 
    647   switch (uuid_size) {
    648     case LEN_UUID_16:
    649       p_uuid_rec->len = uuid_size;
    650       STREAM_TO_UINT16(p_uuid_rec->uu.uuid16, p_uuid);
    651       *p_data += LEN_UUID_16;
    652       break;
    653 
    654     case LEN_UUID_128:
    655       /* See if we can compress his UUID down to 16 or 32bit UUIDs */
    656       is_base_uuid = true;
    657       for (xx = 0; xx < LEN_UUID_128 - 4; xx++) {
    658         if (p_uuid[xx] != base_uuid[xx]) {
    659           is_base_uuid = false;
    660           break;
    661         }
    662       }
    663       if (is_base_uuid) {
    664         if ((p_uuid[LEN_UUID_128 - 1] == 0) &&
    665             (p_uuid[LEN_UUID_128 - 2] == 0)) {
    666           p_uuid += (LEN_UUID_128 - 4);
    667           p_uuid_rec->len = LEN_UUID_16;
    668           STREAM_TO_UINT16(p_uuid_rec->uu.uuid16, p_uuid);
    669         } else {
    670           p_uuid += (LEN_UUID_128 - LEN_UUID_32);
    671           p_uuid_rec->len = LEN_UUID_32;
    672           STREAM_TO_UINT32(p_uuid_rec->uu.uuid32, p_uuid);
    673         }
    674       }
    675       if (!is_base_uuid) {
    676         p_uuid_rec->len = LEN_UUID_128;
    677         memcpy(p_uuid_rec->uu.uuid128, p_uuid, LEN_UUID_128);
    678       }
    679       *p_data += LEN_UUID_128;
    680       break;
    681 
    682     /* do not allow 32 bits UUID in ATT PDU now */
    683     case LEN_UUID_32:
    684       GATT_TRACE_ERROR("DO NOT ALLOW 32 BITS UUID IN ATT PDU");
    685       return false;
    686     case 0:
    687     default:
    688       if (uuid_size != 0) ret = false;
    689       GATT_TRACE_WARNING("gatt_parse_uuid_from_cmd invalid uuid size");
    690       break;
    691   }
    692 
    693   return (ret);
    694 }
    695 
    696 /*******************************************************************************
    697  *
    698  * Function         gatt_start_rsp_timer
    699  *
    700  * Description      Start a wait_for_response timer.
    701  *
    702  * Returns          void
    703  *
    704  ******************************************************************************/
    705 void gatt_start_rsp_timer(uint16_t clcb_idx) {
    706   tGATT_CLCB* p_clcb = &gatt_cb.clcb[clcb_idx];
    707   period_ms_t timeout_ms = GATT_WAIT_FOR_RSP_TIMEOUT_MS;
    708 
    709   if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY &&
    710       p_clcb->op_subtype == GATT_DISC_SRVC_ALL) {
    711     timeout_ms = GATT_WAIT_FOR_DISC_RSP_TIMEOUT_MS;
    712   }
    713 
    714   // TODO: The tGATT_CLCB memory and state management needs cleanup,
    715   // and then the timers can be allocated elsewhere.
    716   if (p_clcb->gatt_rsp_timer_ent == NULL) {
    717     p_clcb->gatt_rsp_timer_ent = alarm_new("gatt.gatt_rsp_timer_ent");
    718   }
    719   alarm_set_on_queue(p_clcb->gatt_rsp_timer_ent, timeout_ms, gatt_rsp_timeout,
    720                      p_clcb, btu_general_alarm_queue);
    721 }
    722 
    723 /*******************************************************************************
    724  *
    725  * Function         gatt_start_conf_timer
    726  *
    727  * Description      Start a wait_for_confirmation timer.
    728  *
    729  * Returns          void
    730  *
    731  ******************************************************************************/
    732 void gatt_start_conf_timer(tGATT_TCB* p_tcb) {
    733   alarm_set_on_queue(p_tcb->conf_timer, GATT_WAIT_FOR_RSP_TIMEOUT_MS,
    734                      gatt_indication_confirmation_timeout, p_tcb,
    735                      btu_general_alarm_queue);
    736 }
    737 
    738 /*******************************************************************************
    739  *
    740  * Function         gatt_start_ind_ack_timer
    741  *
    742  * Description      start the application ack timer
    743  *
    744  * Returns          void
    745  *
    746  ******************************************************************************/
    747 void gatt_start_ind_ack_timer(tGATT_TCB* p_tcb) {
    748   /* start notification cache timer */
    749   alarm_set_on_queue(p_tcb->ind_ack_timer, GATT_WAIT_FOR_RSP_TIMEOUT_MS,
    750                      gatt_ind_ack_timeout, p_tcb, btu_general_alarm_queue);
    751 }
    752 
    753 /*******************************************************************************
    754  *
    755  * Function         gatt_rsp_timeout
    756  *
    757  * Description      Called when GATT wait for ATT command response timer expires
    758  *
    759  * Returns          void
    760  *
    761  ******************************************************************************/
    762 void gatt_rsp_timeout(void* data) {
    763   tGATT_CLCB* p_clcb = (tGATT_CLCB*)data;
    764 
    765   if (p_clcb == NULL || p_clcb->p_tcb == NULL) {
    766     GATT_TRACE_WARNING("%s clcb is already deleted", __func__);
    767     return;
    768   }
    769   if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY &&
    770       p_clcb->op_subtype == GATT_DISC_SRVC_ALL &&
    771       p_clcb->retry_count < GATT_REQ_RETRY_LIMIT) {
    772     uint8_t rsp_code;
    773     GATT_TRACE_WARNING("%s retry discovery primary service", __func__);
    774     if (p_clcb != gatt_cmd_dequeue(p_clcb->p_tcb, &rsp_code)) {
    775       GATT_TRACE_ERROR("%s command queue out of sync, disconnect", __func__);
    776     } else {
    777       p_clcb->retry_count++;
    778       gatt_act_discovery(p_clcb);
    779       return;
    780     }
    781   }
    782 
    783   GATT_TRACE_WARNING("%s disconnecting...", __func__);
    784   gatt_disconnect(p_clcb->p_tcb);
    785 }
    786 
    787 /*******************************************************************************
    788  *
    789  * Function         gatt_indication_confirmation_timeout
    790  *
    791  * Description      Called when the indication confirmation timer expires
    792  *
    793  * Returns          void
    794  *
    795  ******************************************************************************/
    796 void gatt_indication_confirmation_timeout(void* data) {
    797   tGATT_TCB* p_tcb = (tGATT_TCB*)data;
    798 
    799   GATT_TRACE_WARNING("%s disconnecting...", __func__);
    800   gatt_disconnect(p_tcb);
    801 }
    802 
    803 /*******************************************************************************
    804  *
    805  * Function         gatt_ind_ack_timeout
    806  *
    807  * Description      Called when GATT wait for ATT handle confirmation timeout
    808  *
    809  * Returns          void
    810  *
    811  ******************************************************************************/
    812 void gatt_ind_ack_timeout(void* data) {
    813   tGATT_TCB* p_tcb = (tGATT_TCB*)data;
    814 
    815   GATT_TRACE_WARNING("%s send ack now", __func__);
    816 
    817   if (p_tcb != NULL) p_tcb->ind_count = 0;
    818 
    819   attp_send_cl_msg(p_tcb, 0, GATT_HANDLE_VALUE_CONF, NULL);
    820 }
    821 /*******************************************************************************
    822  *
    823  * Description      Search for a service that owns a specific handle.
    824  *
    825  * Returns          GATT_MAX_SR_PROFILES if not found. Otherwise the index of
    826  *                  the service.
    827  *
    828  ******************************************************************************/
    829 std::list<tGATT_SRV_LIST_ELEM>::iterator gatt_sr_find_i_rcb_by_handle(
    830     uint16_t handle) {
    831   auto it = gatt_cb.srv_list_info->begin();
    832 
    833   for (; it != gatt_cb.srv_list_info->end(); it++) {
    834     if (it->s_hdl <= handle && it->e_hdl >= handle) {
    835       return it;
    836     }
    837   }
    838 
    839   return it;
    840 }
    841 
    842 /*******************************************************************************
    843  *
    844  * Function         gatt_sr_get_sec_info
    845  *
    846  * Description      Get the security flag and key size information for the peer
    847  *                  device.
    848  *
    849  * Returns          void
    850  *
    851  ******************************************************************************/
    852 void gatt_sr_get_sec_info(BD_ADDR rem_bda, tBT_TRANSPORT transport,
    853                           uint8_t* p_sec_flag, uint8_t* p_key_size) {
    854   uint8_t sec_flag = 0;
    855 
    856   BTM_GetSecurityFlagsByTransport(rem_bda, &sec_flag, transport);
    857 
    858   sec_flag &= (GATT_SEC_FLAG_LKEY_UNAUTHED | GATT_SEC_FLAG_LKEY_AUTHED |
    859                GATT_SEC_FLAG_ENCRYPTED);
    860 
    861   *p_key_size = btm_ble_read_sec_key_size(rem_bda);
    862   *p_sec_flag = sec_flag;
    863 }
    864 /*******************************************************************************
    865  *
    866  * Function         gatt_sr_send_req_callback
    867  *
    868  * Description
    869  *
    870  *
    871  * Returns          void
    872  *
    873  ******************************************************************************/
    874 void gatt_sr_send_req_callback(uint16_t conn_id, uint32_t trans_id,
    875                                tGATTS_REQ_TYPE type, tGATTS_DATA* p_data) {
    876   tGATT_IF gatt_if = GATT_GET_GATT_IF(conn_id);
    877   tGATT_REG* p_reg = gatt_get_regcb(gatt_if);
    878 
    879   if (!p_reg) {
    880     GATT_TRACE_ERROR("p_reg not found discard request");
    881     return;
    882   }
    883 
    884   if (p_reg->in_use && p_reg->app_cb.p_req_cb) {
    885     (*p_reg->app_cb.p_req_cb)(conn_id, trans_id, type, p_data);
    886   } else {
    887     GATT_TRACE_WARNING("Call back not found for application conn_id=%d",
    888                        conn_id);
    889   }
    890 }
    891 
    892 /*******************************************************************************
    893  *
    894  * Function         gatt_send_error_rsp
    895  *
    896  * Description      This function sends an error response.
    897  *
    898  * Returns          void
    899  *
    900  ******************************************************************************/
    901 tGATT_STATUS gatt_send_error_rsp(tGATT_TCB* p_tcb, uint8_t err_code,
    902                                  uint8_t op_code, uint16_t handle, bool deq) {
    903   tGATT_ERROR error;
    904   tGATT_STATUS status;
    905   BT_HDR* p_buf;
    906 
    907   error.cmd_code = op_code;
    908   error.reason = err_code;
    909   error.handle = handle;
    910 
    911   p_buf = attp_build_sr_msg(p_tcb, GATT_RSP_ERROR, (tGATT_SR_MSG*)&error);
    912   if (p_buf != NULL) {
    913     status = attp_send_sr_msg(p_tcb, p_buf);
    914   } else
    915     status = GATT_INSUF_RESOURCE;
    916 
    917   if (deq) gatt_dequeue_sr_cmd(p_tcb);
    918 
    919   return status;
    920 }
    921 
    922 /*******************************************************************************
    923  *
    924  * Function         gatt_add_sdp_record
    925  *
    926  * Description      This function add a SDP record for a GATT primary service
    927  *
    928  * Returns          0 if error else sdp handle for the record.
    929  *
    930  ******************************************************************************/
    931 uint32_t gatt_add_sdp_record(tBT_UUID* p_uuid, uint16_t start_hdl,
    932                              uint16_t end_hdl) {
    933   tSDP_PROTOCOL_ELEM proto_elem_list[2];
    934   uint32_t sdp_handle;
    935   uint16_t list = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
    936   uint8_t buff[60];
    937   uint8_t* p = buff;
    938 
    939   GATT_TRACE_DEBUG("gatt_add_sdp_record s_hdl=0x%x  s_hdl=0x%x", start_hdl,
    940                    end_hdl);
    941 
    942   sdp_handle = SDP_CreateRecord();
    943   if (sdp_handle == 0) return 0;
    944 
    945   switch (p_uuid->len) {
    946     case LEN_UUID_16:
    947       SDP_AddServiceClassIdList(sdp_handle, 1, &p_uuid->uu.uuid16);
    948       break;
    949 
    950     case LEN_UUID_32:
    951       UINT8_TO_BE_STREAM(p, (UUID_DESC_TYPE << 3) | SIZE_FOUR_BYTES);
    952       UINT32_TO_BE_STREAM(p, p_uuid->uu.uuid32);
    953       SDP_AddAttribute(sdp_handle, ATTR_ID_SERVICE_CLASS_ID_LIST,
    954                        DATA_ELE_SEQ_DESC_TYPE, (uint32_t)(p - buff), buff);
    955       break;
    956 
    957     case LEN_UUID_128:
    958       UINT8_TO_BE_STREAM(p, (UUID_DESC_TYPE << 3) | SIZE_SIXTEEN_BYTES);
    959       ARRAY_TO_BE_STREAM_REVERSE(p, p_uuid->uu.uuid128, LEN_UUID_128);
    960       SDP_AddAttribute(sdp_handle, ATTR_ID_SERVICE_CLASS_ID_LIST,
    961                        DATA_ELE_SEQ_DESC_TYPE, (uint32_t)(p - buff), buff);
    962       break;
    963 
    964     default:
    965       GATT_TRACE_ERROR("inavlid UUID len=%d", p_uuid->len);
    966       SDP_DeleteRecord(sdp_handle);
    967       return 0;
    968       break;
    969   }
    970 
    971   /*** Fill out the protocol element sequence for SDP ***/
    972   proto_elem_list[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
    973   proto_elem_list[0].num_params = 1;
    974   proto_elem_list[0].params[0] = BT_PSM_ATT;
    975   proto_elem_list[1].protocol_uuid = UUID_PROTOCOL_ATT;
    976   proto_elem_list[1].num_params = 2;
    977   proto_elem_list[1].params[0] = start_hdl;
    978   proto_elem_list[1].params[1] = end_hdl;
    979 
    980   SDP_AddProtocolList(sdp_handle, 2, proto_elem_list);
    981 
    982   /* Make the service browseable */
    983   SDP_AddUuidSequence(sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &list);
    984 
    985   return (sdp_handle);
    986 }
    987 
    988 #if GATT_CONFORMANCE_TESTING == TRUE
    989 /*******************************************************************************
    990  *
    991  * Function         gatt_set_err_rsp
    992  *
    993  * Description      This function is called to set the test confirm value
    994  *
    995  * Returns          void
    996  *
    997  ******************************************************************************/
    998 void gatt_set_err_rsp(bool enable, uint8_t req_op_code, uint8_t err_status) {
    999   GATT_TRACE_DEBUG("gatt_set_err_rsp enable=%d op_code=%d, err_status=%d",
   1000                    enable, req_op_code, err_status);
   1001   gatt_cb.enable_err_rsp = enable;
   1002   gatt_cb.req_op_code = req_op_code;
   1003   gatt_cb.err_status = err_status;
   1004 }
   1005 #endif
   1006 
   1007 /*******************************************************************************
   1008  *
   1009  * Function         gatt_get_regcb
   1010  *
   1011  * Description      The function returns the registration control block.
   1012  *
   1013  * Returns          pointer to the registration control block or NULL
   1014  *
   1015  ******************************************************************************/
   1016 tGATT_REG* gatt_get_regcb(tGATT_IF gatt_if) {
   1017   uint8_t ii = (uint8_t)gatt_if;
   1018   tGATT_REG* p_reg = NULL;
   1019 
   1020   if (ii < 1 || ii > GATT_MAX_APPS) {
   1021     GATT_TRACE_WARNING("gatt_if out of range [ = %d]", ii);
   1022     return NULL;
   1023   }
   1024 
   1025   // Index for cl_rcb is always 1 less than gatt_if.
   1026   p_reg = &gatt_cb.cl_rcb[ii - 1];
   1027 
   1028   if (!p_reg->in_use) {
   1029     GATT_TRACE_WARNING("gatt_if found but not in use.");
   1030     return NULL;
   1031   }
   1032 
   1033   return p_reg;
   1034 }
   1035 
   1036 /*******************************************************************************
   1037  *
   1038  * Function         gatt_is_clcb_allocated
   1039  *
   1040  * Description      The function check clcb for conn_id is allocated or not
   1041  *
   1042  * Returns           True already allocated
   1043  *
   1044  ******************************************************************************/
   1045 
   1046 bool gatt_is_clcb_allocated(uint16_t conn_id) {
   1047   uint8_t i = 0;
   1048   bool is_allocated = false;
   1049 
   1050   for (i = 0; i < GATT_CL_MAX_LCB; i++) {
   1051     if (gatt_cb.clcb[i].in_use && (gatt_cb.clcb[i].conn_id == conn_id)) {
   1052       is_allocated = true;
   1053       break;
   1054     }
   1055   }
   1056 
   1057   return is_allocated;
   1058 }
   1059 
   1060 /*******************************************************************************
   1061  *
   1062  * Function         gatt_clcb_alloc
   1063  *
   1064  * Description      The function allocates a GATT  connection link control block
   1065  *
   1066  * Returns          NULL if not found. Otherwise pointer to the connection link
   1067  *                  block.
   1068  *
   1069  ******************************************************************************/
   1070 tGATT_CLCB* gatt_clcb_alloc(uint16_t conn_id) {
   1071   uint8_t i = 0;
   1072   tGATT_CLCB* p_clcb = NULL;
   1073   tGATT_IF gatt_if = GATT_GET_GATT_IF(conn_id);
   1074   uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id);
   1075   tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(tcb_idx);
   1076   tGATT_REG* p_reg = gatt_get_regcb(gatt_if);
   1077 
   1078   for (i = 0; i < GATT_CL_MAX_LCB; i++) {
   1079     if (!gatt_cb.clcb[i].in_use) {
   1080       p_clcb = &gatt_cb.clcb[i];
   1081 
   1082       p_clcb->in_use = true;
   1083       p_clcb->conn_id = conn_id;
   1084       p_clcb->clcb_idx = i;
   1085       p_clcb->p_reg = p_reg;
   1086       p_clcb->p_tcb = p_tcb;
   1087       break;
   1088     }
   1089   }
   1090   return p_clcb;
   1091 }
   1092 
   1093 /*******************************************************************************
   1094  *
   1095  * Function         gatt_clcb_dealloc
   1096  *
   1097  * Description      The function de-allocates a GATT connection link control
   1098  *                  block
   1099  *
   1100  * Returns         None
   1101  *
   1102  ******************************************************************************/
   1103 void gatt_clcb_dealloc(tGATT_CLCB* p_clcb) {
   1104   if (p_clcb && p_clcb->in_use) {
   1105     alarm_free(p_clcb->gatt_rsp_timer_ent);
   1106     memset(p_clcb, 0, sizeof(tGATT_CLCB));
   1107   }
   1108 }
   1109 
   1110 /*******************************************************************************
   1111  *
   1112  * Function         gatt_find_tcb_by_cid
   1113  *
   1114  * Description      The function searches for an empty entry
   1115  *                   in registration info table for GATT client
   1116  *
   1117  * Returns           NULL if not found. Otherwise pointer to the rcb.
   1118  *
   1119  ******************************************************************************/
   1120 tGATT_TCB* gatt_find_tcb_by_cid(uint16_t lcid) {
   1121   uint16_t xx = 0;
   1122   tGATT_TCB* p_tcb = NULL;
   1123 
   1124   for (xx = 0; xx < GATT_MAX_PHY_CHANNEL; xx++) {
   1125     if (gatt_cb.tcb[xx].in_use && gatt_cb.tcb[xx].att_lcid == lcid) {
   1126       p_tcb = &gatt_cb.tcb[xx];
   1127       break;
   1128     }
   1129   }
   1130   return p_tcb;
   1131 }
   1132 
   1133 /*******************************************************************************
   1134  *
   1135  * Function         gatt_num_apps_hold_link
   1136  *
   1137  * Description      The function find the number of applcaitions is holding the
   1138  *                  link
   1139  *
   1140  * Returns          total number of applications holding this acl link.
   1141  *
   1142  ******************************************************************************/
   1143 uint8_t gatt_num_apps_hold_link(tGATT_TCB* p_tcb) {
   1144   uint8_t i, num = 0;
   1145 
   1146   for (i = 0; i < GATT_MAX_APPS; i++) {
   1147     if (p_tcb->app_hold_link[i]) num++;
   1148   }
   1149 
   1150   GATT_TRACE_DEBUG("gatt_num_apps_hold_link   num=%d", num);
   1151   return num;
   1152 }
   1153 
   1154 /*******************************************************************************
   1155  *
   1156  * Function         gatt_num_clcb_by_bd_addr
   1157  *
   1158  * Description      The function searches all LCB with macthing bd address
   1159  *
   1160  * Returns          total number of clcb found.
   1161  *
   1162  ******************************************************************************/
   1163 uint8_t gatt_num_clcb_by_bd_addr(BD_ADDR bda) {
   1164   uint8_t i, num = 0;
   1165 
   1166   for (i = 0; i < GATT_CL_MAX_LCB; i++) {
   1167     if (gatt_cb.clcb[i].in_use &&
   1168         memcmp(gatt_cb.clcb[i].p_tcb->peer_bda, bda, BD_ADDR_LEN) == 0)
   1169       num++;
   1170   }
   1171   return num;
   1172 }
   1173 
   1174 /*******************************************************************************
   1175  *
   1176  * Function         gatt_sr_update_cback_cnt
   1177  *
   1178  * Description      The function searches all LCB with macthing bd address
   1179  *
   1180  * Returns          total number of clcb found.
   1181  *
   1182  ******************************************************************************/
   1183 void gatt_sr_copy_prep_cnt_to_cback_cnt(tGATT_TCB* p_tcb) {
   1184   uint8_t i;
   1185 
   1186   if (p_tcb) {
   1187     for (i = 0; i < GATT_MAX_APPS; i++) {
   1188       if (p_tcb->prep_cnt[i]) {
   1189         p_tcb->sr_cmd.cback_cnt[i] = 1;
   1190       }
   1191     }
   1192   }
   1193 }
   1194 
   1195 /*******************************************************************************
   1196  *
   1197  * Function         gatt_sr_is_cback_cnt_zero
   1198  *
   1199  * Description      The function searches all LCB with macthing bd address
   1200  *
   1201  * Returns          True if thetotal application callback count is zero
   1202  *
   1203  ******************************************************************************/
   1204 bool gatt_sr_is_cback_cnt_zero(tGATT_TCB* p_tcb) {
   1205   bool status = true;
   1206   uint8_t i;
   1207 
   1208   if (p_tcb) {
   1209     for (i = 0; i < GATT_MAX_APPS; i++) {
   1210       if (p_tcb->sr_cmd.cback_cnt[i]) {
   1211         status = false;
   1212         break;
   1213       }
   1214     }
   1215   } else {
   1216     status = false;
   1217   }
   1218   return status;
   1219 }
   1220 
   1221 /*******************************************************************************
   1222  *
   1223  * Function         gatt_sr_is_prep_cnt_zero
   1224  *
   1225  * Description      Check the prepare write request count is zero or not
   1226  *
   1227  * Returns          True no prepare write request
   1228  *
   1229  ******************************************************************************/
   1230 bool gatt_sr_is_prep_cnt_zero(tGATT_TCB* p_tcb) {
   1231   bool status = true;
   1232   uint8_t i;
   1233 
   1234   if (p_tcb) {
   1235     for (i = 0; i < GATT_MAX_APPS; i++) {
   1236       if (p_tcb->prep_cnt[i]) {
   1237         status = false;
   1238         break;
   1239       }
   1240     }
   1241   } else {
   1242     status = false;
   1243   }
   1244   return status;
   1245 }
   1246 
   1247 /*******************************************************************************
   1248  *
   1249  * Function         gatt_sr_reset_cback_cnt
   1250  *
   1251  * Description      Reset the application callback count to zero
   1252  *
   1253  * Returns         None
   1254  *
   1255  ******************************************************************************/
   1256 void gatt_sr_reset_cback_cnt(tGATT_TCB* p_tcb) {
   1257   uint8_t i;
   1258 
   1259   if (p_tcb) {
   1260     for (i = 0; i < GATT_MAX_APPS; i++) {
   1261       p_tcb->sr_cmd.cback_cnt[i] = 0;
   1262     }
   1263   }
   1264 }
   1265 
   1266 /*******************************************************************************
   1267  *
   1268  * Function         gatt_sr_reset_prep_cnt
   1269  *
   1270  * Description     Reset the prep write count to zero
   1271  *
   1272  * Returns        None
   1273  *
   1274  ******************************************************************************/
   1275 void gatt_sr_reset_prep_cnt(tGATT_TCB* p_tcb) {
   1276   uint8_t i;
   1277   if (p_tcb) {
   1278     for (i = 0; i < GATT_MAX_APPS; i++) {
   1279       p_tcb->prep_cnt[i] = 0;
   1280     }
   1281   }
   1282 }
   1283 
   1284 /*******************************************************************************
   1285  *
   1286  * Function         gatt_sr_update_cback_cnt
   1287  *
   1288  * Description    Update the teh applicaiton callback count
   1289  *
   1290  * Returns           None
   1291  *
   1292  ******************************************************************************/
   1293 void gatt_sr_update_cback_cnt(tGATT_TCB* p_tcb, tGATT_IF gatt_if, bool is_inc,
   1294                               bool is_reset_first) {
   1295   uint8_t idx = ((uint8_t)gatt_if) - 1;
   1296 
   1297   if (p_tcb) {
   1298     if (is_reset_first) {
   1299       gatt_sr_reset_cback_cnt(p_tcb);
   1300     }
   1301     if (is_inc) {
   1302       p_tcb->sr_cmd.cback_cnt[idx]++;
   1303     } else {
   1304       if (p_tcb->sr_cmd.cback_cnt[idx]) {
   1305         p_tcb->sr_cmd.cback_cnt[idx]--;
   1306       }
   1307     }
   1308   }
   1309 }
   1310 
   1311 /*******************************************************************************
   1312  *
   1313  * Function         gatt_sr_update_prep_cnt
   1314  *
   1315  * Description    Update the teh prepare write request count
   1316  *
   1317  * Returns           None
   1318  *
   1319  ******************************************************************************/
   1320 void gatt_sr_update_prep_cnt(tGATT_TCB* p_tcb, tGATT_IF gatt_if, bool is_inc,
   1321                              bool is_reset_first) {
   1322   uint8_t idx = ((uint8_t)gatt_if) - 1;
   1323 
   1324   GATT_TRACE_DEBUG(
   1325       "gatt_sr_update_prep_cnt tcb idx=%d gatt_if=%d is_inc=%d "
   1326       "is_reset_first=%d",
   1327       p_tcb->tcb_idx, gatt_if, is_inc, is_reset_first);
   1328 
   1329   if (p_tcb) {
   1330     if (is_reset_first) {
   1331       gatt_sr_reset_prep_cnt(p_tcb);
   1332     }
   1333     if (is_inc) {
   1334       p_tcb->prep_cnt[idx]++;
   1335     } else {
   1336       if (p_tcb->prep_cnt[idx]) {
   1337         p_tcb->prep_cnt[idx]--;
   1338       }
   1339     }
   1340   }
   1341 }
   1342 /*******************************************************************************
   1343  *
   1344  * Function         gatt_cancel_open
   1345  *
   1346  * Description      Cancel open request
   1347  *
   1348  * Returns         Boolean
   1349  *
   1350  ******************************************************************************/
   1351 bool gatt_cancel_open(tGATT_IF gatt_if, BD_ADDR bda) {
   1352   tGATT_TCB* p_tcb = NULL;
   1353   bool status = true;
   1354 
   1355   p_tcb = gatt_find_tcb_by_addr(bda, BT_TRANSPORT_LE);
   1356 
   1357   if (p_tcb) {
   1358     if (gatt_get_ch_state(p_tcb) == GATT_CH_OPEN) {
   1359       GATT_TRACE_ERROR(
   1360           "GATT_CancelConnect - link connected Too late to cancel");
   1361       status = false;
   1362     } else {
   1363       gatt_update_app_use_link_flag(gatt_if, p_tcb, false, false);
   1364       if (!gatt_num_apps_hold_link(p_tcb)) {
   1365         gatt_disconnect(p_tcb);
   1366       }
   1367     }
   1368   }
   1369 
   1370   return status;
   1371 }
   1372 
   1373 /*******************************************************************************
   1374  *
   1375  * Function         gatt_find_app_hold_link
   1376  *
   1377  * Description      find the applicaiton that is holding the specified link
   1378  *
   1379  * Returns         Boolean
   1380  *
   1381  ******************************************************************************/
   1382 bool gatt_find_app_hold_link(tGATT_TCB* p_tcb, uint8_t start_idx,
   1383                              uint8_t* p_found_idx, tGATT_IF* p_gatt_if) {
   1384   uint8_t i;
   1385   bool found = false;
   1386 
   1387   for (i = start_idx; i < GATT_MAX_APPS; i++) {
   1388     if (p_tcb->app_hold_link[i]) {
   1389       *p_gatt_if = gatt_cb.clcb[i].p_reg->gatt_if;
   1390       *p_found_idx = i;
   1391       found = true;
   1392       break;
   1393     }
   1394   }
   1395   return found;
   1396 }
   1397 
   1398 /*******************************************************************************
   1399  *
   1400  * Function         gatt_cmd_enq
   1401  *
   1402  * Description      Enqueue this command.
   1403  *
   1404  * Returns          None.
   1405  *
   1406  ******************************************************************************/
   1407 bool gatt_cmd_enq(tGATT_TCB* p_tcb, uint16_t clcb_idx, bool to_send,
   1408                   uint8_t op_code, BT_HDR* p_buf) {
   1409   tGATT_CMD_Q* p_cmd = &p_tcb->cl_cmd_q[p_tcb->next_slot_inq];
   1410 
   1411   p_cmd->to_send = to_send; /* waiting to be sent */
   1412   p_cmd->op_code = op_code;
   1413   p_cmd->p_cmd = p_buf;
   1414   p_cmd->clcb_idx = clcb_idx;
   1415 
   1416   if (!to_send) {
   1417     p_tcb->pending_cl_req = p_tcb->next_slot_inq;
   1418   }
   1419 
   1420   p_tcb->next_slot_inq++;
   1421   p_tcb->next_slot_inq %= GATT_CL_MAX_LCB;
   1422 
   1423   return true;
   1424 }
   1425 
   1426 /*******************************************************************************
   1427  *
   1428  * Function         gatt_cmd_dequeue
   1429  *
   1430  * Description      dequeue the command in the client CCB command queue.
   1431  *
   1432  * Returns          total number of clcb found.
   1433  *
   1434  ******************************************************************************/
   1435 tGATT_CLCB* gatt_cmd_dequeue(tGATT_TCB* p_tcb, uint8_t* p_op_code) {
   1436   tGATT_CMD_Q* p_cmd = &p_tcb->cl_cmd_q[p_tcb->pending_cl_req];
   1437   tGATT_CLCB* p_clcb = NULL;
   1438 
   1439   if (p_tcb->pending_cl_req != p_tcb->next_slot_inq) {
   1440     p_clcb = &gatt_cb.clcb[p_cmd->clcb_idx];
   1441 
   1442     *p_op_code = p_cmd->op_code;
   1443 
   1444     p_tcb->pending_cl_req++;
   1445     p_tcb->pending_cl_req %= GATT_CL_MAX_LCB;
   1446   }
   1447 
   1448   return p_clcb;
   1449 }
   1450 
   1451 /*******************************************************************************
   1452  *
   1453  * Function         gatt_send_write_msg
   1454  *
   1455  * Description      This real function send out the ATT message for write.
   1456  *
   1457  * Returns          status code
   1458  *
   1459  ******************************************************************************/
   1460 uint8_t gatt_send_write_msg(tGATT_TCB* p_tcb, uint16_t clcb_idx,
   1461                             uint8_t op_code, uint16_t handle, uint16_t len,
   1462                             uint16_t offset, uint8_t* p_data) {
   1463   tGATT_CL_MSG msg;
   1464 
   1465   msg.attr_value.handle = handle;
   1466   msg.attr_value.len = len;
   1467   msg.attr_value.offset = offset;
   1468 
   1469   memcpy(msg.attr_value.value, p_data, len);
   1470 
   1471   /* write by handle */
   1472   return attp_send_cl_msg(p_tcb, clcb_idx, op_code, &msg);
   1473 }
   1474 
   1475 /*******************************************************************************
   1476  *
   1477  * Function         gatt_act_send_browse
   1478  *
   1479  * Description      This function ends a browse command request, including read
   1480  *                  information request and read by type request.
   1481  *
   1482  * Returns          status code
   1483  *
   1484  ******************************************************************************/
   1485 uint8_t gatt_act_send_browse(tGATT_TCB* p_tcb, uint16_t index, uint8_t op,
   1486                              uint16_t s_handle, uint16_t e_handle,
   1487                              tBT_UUID uuid) {
   1488   tGATT_CL_MSG msg;
   1489 
   1490   msg.browse.s_handle = s_handle;
   1491   msg.browse.e_handle = e_handle;
   1492   memcpy(&msg.browse.uuid, &uuid, sizeof(tBT_UUID));
   1493 
   1494   /* write by handle */
   1495   return attp_send_cl_msg(p_tcb, index, op, &msg);
   1496 }
   1497 
   1498 /*******************************************************************************
   1499  *
   1500  * Function         gatt_end_operation
   1501  *
   1502  * Description      This function ends a discovery, send callback and finalize
   1503  *                  some control value.
   1504  *
   1505  * Returns          16 bits uuid.
   1506  *
   1507  ******************************************************************************/
   1508 void gatt_end_operation(tGATT_CLCB* p_clcb, tGATT_STATUS status, void* p_data) {
   1509   tGATT_CL_COMPLETE cb_data;
   1510   tGATT_CMPL_CBACK* p_cmpl_cb =
   1511       (p_clcb->p_reg) ? p_clcb->p_reg->app_cb.p_cmpl_cb : NULL;
   1512   uint8_t op = p_clcb->operation, disc_type = GATT_DISC_MAX;
   1513   tGATT_DISC_CMPL_CB* p_disc_cmpl_cb =
   1514       (p_clcb->p_reg) ? p_clcb->p_reg->app_cb.p_disc_cmpl_cb : NULL;
   1515   uint16_t conn_id;
   1516   uint8_t operation;
   1517 
   1518   GATT_TRACE_DEBUG("gatt_end_operation status=%d op=%d subtype=%d", status,
   1519                    p_clcb->operation, p_clcb->op_subtype);
   1520   memset(&cb_data.att_value, 0, sizeof(tGATT_VALUE));
   1521 
   1522   if (p_cmpl_cb != NULL && p_clcb->operation != 0) {
   1523     if (p_clcb->operation == GATTC_OPTYPE_READ) {
   1524       cb_data.att_value.handle = p_clcb->s_handle;
   1525       cb_data.att_value.len = p_clcb->counter;
   1526 
   1527       if (p_data && p_clcb->counter)
   1528         memcpy(cb_data.att_value.value, p_data, cb_data.att_value.len);
   1529     }
   1530 
   1531     if (p_clcb->operation == GATTC_OPTYPE_WRITE) {
   1532       memset(&cb_data.att_value, 0, sizeof(tGATT_VALUE));
   1533       cb_data.handle = cb_data.att_value.handle = p_clcb->s_handle;
   1534       if (p_clcb->op_subtype == GATT_WRITE_PREPARE) {
   1535         if (p_data) {
   1536           cb_data.att_value = *((tGATT_VALUE*)p_data);
   1537         } else {
   1538           GATT_TRACE_DEBUG("Rcv Prepare write rsp but no data");
   1539         }
   1540       }
   1541     }
   1542 
   1543     if (p_clcb->operation == GATTC_OPTYPE_CONFIG)
   1544       cb_data.mtu = p_clcb->p_tcb->payload_size;
   1545 
   1546     if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY) {
   1547       disc_type = p_clcb->op_subtype;
   1548     }
   1549   }
   1550 
   1551   osi_free_and_reset((void**)&p_clcb->p_attr_buf);
   1552 
   1553   operation = p_clcb->operation;
   1554   conn_id = p_clcb->conn_id;
   1555   alarm_cancel(p_clcb->gatt_rsp_timer_ent);
   1556 
   1557   gatt_clcb_dealloc(p_clcb);
   1558 
   1559   if (p_disc_cmpl_cb && (op == GATTC_OPTYPE_DISCOVERY))
   1560     (*p_disc_cmpl_cb)(conn_id, disc_type, status);
   1561   else if (p_cmpl_cb && op)
   1562     (*p_cmpl_cb)(conn_id, op, status, &cb_data);
   1563   else
   1564     GATT_TRACE_WARNING(
   1565         "gatt_end_operation not sent out op=%d p_disc_cmpl_cb:%p p_cmpl_cb:%p",
   1566         operation, p_disc_cmpl_cb, p_cmpl_cb);
   1567 }
   1568 
   1569 /*******************************************************************************
   1570  *
   1571  * Function         gatt_cleanup_upon_disc
   1572  *
   1573  * Description      This function cleans up the control blocks when L2CAP
   1574  *                  channel disconnect.
   1575  *
   1576  * Returns          16 bits uuid.
   1577  *
   1578  ******************************************************************************/
   1579 void gatt_cleanup_upon_disc(BD_ADDR bda, uint16_t reason,
   1580                             tBT_TRANSPORT transport) {
   1581   tGATT_TCB* p_tcb = NULL;
   1582   tGATT_CLCB* p_clcb;
   1583   uint8_t i;
   1584   uint16_t conn_id;
   1585   tGATT_REG* p_reg = NULL;
   1586 
   1587   GATT_TRACE_DEBUG("gatt_cleanup_upon_disc ");
   1588 
   1589   p_tcb = gatt_find_tcb_by_addr(bda, transport);
   1590   if (p_tcb != NULL) {
   1591     GATT_TRACE_DEBUG("found p_tcb ");
   1592     gatt_set_ch_state(p_tcb, GATT_CH_CLOSE);
   1593     for (i = 0; i < GATT_CL_MAX_LCB; i++) {
   1594       p_clcb = &gatt_cb.clcb[i];
   1595       if (p_clcb->in_use && p_clcb->p_tcb == p_tcb) {
   1596         alarm_cancel(p_clcb->gatt_rsp_timer_ent);
   1597         GATT_TRACE_DEBUG("found p_clcb conn_id=%d clcb_idx=%d", p_clcb->conn_id,
   1598                          p_clcb->clcb_idx);
   1599         if (p_clcb->operation != GATTC_OPTYPE_NONE)
   1600           gatt_end_operation(p_clcb, GATT_ERROR, NULL);
   1601 
   1602         gatt_clcb_dealloc(p_clcb);
   1603       }
   1604     }
   1605 
   1606     alarm_free(p_tcb->ind_ack_timer);
   1607     p_tcb->ind_ack_timer = NULL;
   1608     alarm_free(p_tcb->conf_timer);
   1609     p_tcb->conf_timer = NULL;
   1610     gatt_free_pending_ind(p_tcb);
   1611     gatt_free_pending_enc_queue(p_tcb);
   1612     fixed_queue_free(p_tcb->sr_cmd.multi_rsp_q, NULL);
   1613     p_tcb->sr_cmd.multi_rsp_q = NULL;
   1614 
   1615     for (i = 0; i < GATT_MAX_APPS; i++) {
   1616       p_reg = &gatt_cb.cl_rcb[i];
   1617       if (p_reg->in_use && p_reg->app_cb.p_conn_cb) {
   1618         conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if);
   1619         GATT_TRACE_DEBUG("found p_reg tcb_idx=%d gatt_if=%d  conn_id=0x%x",
   1620                          p_tcb->tcb_idx, p_reg->gatt_if, conn_id);
   1621         (*p_reg->app_cb.p_conn_cb)(p_reg->gatt_if, bda, conn_id, false, reason,
   1622                                    transport);
   1623       }
   1624     }
   1625     memset(p_tcb, 0, sizeof(tGATT_TCB));
   1626   }
   1627   GATT_TRACE_DEBUG("exit gatt_cleanup_upon_disc ");
   1628 }
   1629 /*******************************************************************************
   1630  *
   1631  * Function         gatt_dbg_req_op_name
   1632  *
   1633  * Description      Get op code description name, for debug information.
   1634  *
   1635  * Returns          uint8_t *: name of the operation.
   1636  *
   1637  ******************************************************************************/
   1638 uint8_t* gatt_dbg_op_name(uint8_t op_code) {
   1639   uint8_t pseduo_op_code_idx = op_code & (~GATT_WRITE_CMD_MASK);
   1640 
   1641   if (op_code == GATT_CMD_WRITE) {
   1642     pseduo_op_code_idx = 0x14; /* just an index to op_code_name */
   1643   }
   1644 
   1645   if (op_code == GATT_SIGN_CMD_WRITE) {
   1646     pseduo_op_code_idx = 0x15; /* just an index to op_code_name */
   1647   }
   1648 
   1649   if (pseduo_op_code_idx <= GATT_OP_CODE_MAX)
   1650     return (uint8_t*)op_code_name[pseduo_op_code_idx];
   1651   else
   1652     return (uint8_t*)"Op Code Exceed Max";
   1653 }
   1654 
   1655 /*******************************************************************************
   1656  *
   1657  * Function         gatt_dbg_display_uuid
   1658  *
   1659  * Description      Disaplay the UUID
   1660  *
   1661  * Returns          None
   1662  *
   1663  ******************************************************************************/
   1664 void gatt_dbg_display_uuid(tBT_UUID bt_uuid) {
   1665   char str_buf[50];
   1666 
   1667   if (bt_uuid.len == LEN_UUID_16) {
   1668     snprintf(str_buf, sizeof(str_buf), "0x%04x", bt_uuid.uu.uuid16);
   1669   } else if (bt_uuid.len == LEN_UUID_32) {
   1670     snprintf(str_buf, sizeof(str_buf), "0x%08x",
   1671              (unsigned int)bt_uuid.uu.uuid32);
   1672   } else if (bt_uuid.len == LEN_UUID_128) {
   1673     int x = snprintf(
   1674         str_buf, sizeof(str_buf), "0x%02x%02x%02x%02x%02x%02x%02x%02x",
   1675         bt_uuid.uu.uuid128[15], bt_uuid.uu.uuid128[14], bt_uuid.uu.uuid128[13],
   1676         bt_uuid.uu.uuid128[12], bt_uuid.uu.uuid128[11], bt_uuid.uu.uuid128[10],
   1677         bt_uuid.uu.uuid128[9], bt_uuid.uu.uuid128[8]);
   1678     snprintf(
   1679         &str_buf[x], sizeof(str_buf) - x, "%02x%02x%02x%02x%02x%02x%02x%02x",
   1680         bt_uuid.uu.uuid128[7], bt_uuid.uu.uuid128[6], bt_uuid.uu.uuid128[5],
   1681         bt_uuid.uu.uuid128[4], bt_uuid.uu.uuid128[3], bt_uuid.uu.uuid128[2],
   1682         bt_uuid.uu.uuid128[1], bt_uuid.uu.uuid128[0]);
   1683   } else
   1684     strlcpy(str_buf, "Unknown UUID 0", sizeof(str_buf));
   1685 
   1686   GATT_TRACE_DEBUG("UUID=[%s]", str_buf);
   1687 }
   1688 
   1689 /*******************************************************************************
   1690  *
   1691  * Function         gatt_is_bg_dev_for_app
   1692  *
   1693  * Description      Is this one of the background devices for the application
   1694  *
   1695  * Returns          true if it is, otherwise false
   1696  *
   1697  ******************************************************************************/
   1698 bool gatt_is_bg_dev_for_app(tGATT_BG_CONN_DEV* p_dev, tGATT_IF gatt_if) {
   1699   uint8_t i;
   1700 
   1701   for (i = 0; i < GATT_MAX_APPS; i++) {
   1702     if (p_dev->in_use && (p_dev->gatt_if[i] == gatt_if)) {
   1703       return true;
   1704     }
   1705   }
   1706   return false;
   1707 }
   1708 /*******************************************************************************
   1709  *
   1710  * Function         gatt_find_bg_dev
   1711  *
   1712  * Description      find background connection device from the list.
   1713  *
   1714  * Returns          pointer to the device record
   1715  *
   1716  ******************************************************************************/
   1717 tGATT_BG_CONN_DEV* gatt_find_bg_dev(BD_ADDR remote_bda) {
   1718   tGATT_BG_CONN_DEV* p_dev_list = &gatt_cb.bgconn_dev[0];
   1719   uint8_t i;
   1720 
   1721   for (i = 0; i < GATT_MAX_BG_CONN_DEV; i++, p_dev_list++) {
   1722     if (p_dev_list->in_use &&
   1723         !memcmp(p_dev_list->remote_bda, remote_bda, BD_ADDR_LEN)) {
   1724       return p_dev_list;
   1725     }
   1726   }
   1727   return NULL;
   1728 }
   1729 /*******************************************************************************
   1730  *
   1731  * Function         gatt_alloc_bg_dev
   1732  *
   1733  * Description      allocate a background connection device record
   1734  *
   1735  * Returns          pointer to the device record
   1736  *
   1737  ******************************************************************************/
   1738 tGATT_BG_CONN_DEV* gatt_alloc_bg_dev(BD_ADDR remote_bda) {
   1739   tGATT_BG_CONN_DEV* p_dev_list = &gatt_cb.bgconn_dev[0];
   1740   uint8_t i;
   1741 
   1742   for (i = 0; i < GATT_MAX_BG_CONN_DEV; i++, p_dev_list++) {
   1743     if (!p_dev_list->in_use) {
   1744       p_dev_list->in_use = true;
   1745       memcpy(p_dev_list->remote_bda, remote_bda, BD_ADDR_LEN);
   1746 
   1747       return p_dev_list;
   1748     }
   1749   }
   1750   return NULL;
   1751 }
   1752 
   1753 /*******************************************************************************
   1754  *
   1755  * Function         gatt_add_bg_dev_list
   1756  *
   1757  * Description      Add/remove a device from the background connection list
   1758  *
   1759  * Returns          true if device added to the list; false failed
   1760  *
   1761  ******************************************************************************/
   1762 bool gatt_add_bg_dev_list(tGATT_REG* p_reg, BD_ADDR bd_addr) {
   1763   tGATT_IF gatt_if = p_reg->gatt_if;
   1764   tGATT_BG_CONN_DEV* p_dev = NULL;
   1765   uint8_t i;
   1766   bool ret = false;
   1767 
   1768   p_dev = gatt_find_bg_dev(bd_addr);
   1769   if (p_dev == NULL) {
   1770     p_dev = gatt_alloc_bg_dev(bd_addr);
   1771   }
   1772 
   1773   if (p_dev) {
   1774     for (i = 0; i < GATT_MAX_APPS; i++) {
   1775       if (p_dev->gatt_if[i] == gatt_if) {
   1776         GATT_TRACE_ERROR("device already in iniator white list");
   1777         return true;
   1778       } else if (p_dev->gatt_if[i] == 0) {
   1779         p_dev->gatt_if[i] = gatt_if;
   1780         if (i == 0)
   1781           ret = BTM_BleUpdateBgConnDev(true, bd_addr);
   1782         else
   1783           ret = true;
   1784         break;
   1785       }
   1786     }
   1787   } else {
   1788     GATT_TRACE_ERROR("no device record available");
   1789   }
   1790 
   1791   return ret;
   1792 }
   1793 
   1794 /*******************************************************************************
   1795  *
   1796  * Function         gatt_remove_bg_dev_for_app
   1797  *
   1798  * Description      Remove the application interface for the specified
   1799  *                  background device
   1800  *
   1801  * Returns          Boolean
   1802  *
   1803  ******************************************************************************/
   1804 bool gatt_remove_bg_dev_for_app(tGATT_IF gatt_if, BD_ADDR bd_addr) {
   1805   tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE);
   1806   bool status;
   1807 
   1808   if (p_tcb) gatt_update_app_use_link_flag(gatt_if, p_tcb, false, false);
   1809   status = gatt_update_auto_connect_dev(gatt_if, false, bd_addr);
   1810   return status;
   1811 }
   1812 
   1813 /*******************************************************************************
   1814  *
   1815  * Function         gatt_get_num_apps_for_bg_dev
   1816  *
   1817  * Description      Get the number of applciations for the specified background
   1818  *                  device
   1819  *
   1820  * Returns          uint8_t total number fo applications
   1821  *
   1822  ******************************************************************************/
   1823 uint8_t gatt_get_num_apps_for_bg_dev(BD_ADDR bd_addr) {
   1824   tGATT_BG_CONN_DEV* p_dev = NULL;
   1825   uint8_t i;
   1826   uint8_t cnt = 0;
   1827 
   1828   p_dev = gatt_find_bg_dev(bd_addr);
   1829   if (p_dev != NULL) {
   1830     for (i = 0; i < GATT_MAX_APPS; i++) {
   1831       if (p_dev->gatt_if[i]) cnt++;
   1832     }
   1833   }
   1834   return cnt;
   1835 }
   1836 
   1837 /*******************************************************************************
   1838  *
   1839  * Function         gatt_find_app_for_bg_dev
   1840  *
   1841  * Description      Find the application interface for the specified background
   1842  *                  device
   1843  *
   1844  * Returns          Boolean
   1845  *
   1846  ******************************************************************************/
   1847 bool gatt_find_app_for_bg_dev(BD_ADDR bd_addr, tGATT_IF* p_gatt_if) {
   1848   tGATT_BG_CONN_DEV* p_dev = NULL;
   1849   uint8_t i;
   1850   bool ret = false;
   1851 
   1852   p_dev = gatt_find_bg_dev(bd_addr);
   1853   if (p_dev == NULL) {
   1854     return ret;
   1855   }
   1856 
   1857   for (i = 0; i < GATT_MAX_APPS; i++) {
   1858     if (p_dev->gatt_if[i] != 0) {
   1859       *p_gatt_if = p_dev->gatt_if[i];
   1860       ret = true;
   1861       break;
   1862     }
   1863   }
   1864   return ret;
   1865 }
   1866 
   1867 /*******************************************************************************
   1868  *
   1869  * Function         gatt_remove_bg_dev_from_list
   1870  *
   1871  * Description      add/remove device from the back ground connection device
   1872  *                  list or listening to advertising list.
   1873  *
   1874  * Returns          pointer to the device record
   1875  *
   1876  ******************************************************************************/
   1877 bool gatt_remove_bg_dev_from_list(tGATT_REG* p_reg, BD_ADDR bd_addr) {
   1878   tGATT_IF gatt_if = p_reg->gatt_if;
   1879   tGATT_BG_CONN_DEV* p_dev = NULL;
   1880   uint8_t i, j;
   1881   bool ret = false;
   1882 
   1883   p_dev = gatt_find_bg_dev(bd_addr);
   1884   if (p_dev == NULL) {
   1885     return ret;
   1886   }
   1887 
   1888   for (i = 0; i < GATT_MAX_APPS && (p_dev->gatt_if[i] > 0); i++) {
   1889     if (p_dev->gatt_if[i] == gatt_if) {
   1890       p_dev->gatt_if[i] = 0;
   1891       /* move all element behind one forward */
   1892       for (j = i + 1; j < GATT_MAX_APPS; j++)
   1893         p_dev->gatt_if[j - 1] = p_dev->gatt_if[j];
   1894 
   1895       if (p_dev->gatt_if[0] == 0)
   1896         ret = BTM_BleUpdateBgConnDev(false, p_dev->remote_bda);
   1897       else
   1898         ret = true;
   1899 
   1900       break;
   1901     }
   1902   }
   1903 
   1904   if (i != GATT_MAX_APPS && p_dev->gatt_if[0] == 0) {
   1905     memset(p_dev, 0, sizeof(tGATT_BG_CONN_DEV));
   1906   }
   1907 
   1908   return ret;
   1909 }
   1910 /*******************************************************************************
   1911  *
   1912  * Function         gatt_deregister_bgdev_list
   1913  *
   1914  * Description      deregister all related back ground connetion device.
   1915  *
   1916  * Returns          pointer to the device record
   1917  *
   1918  ******************************************************************************/
   1919 void gatt_deregister_bgdev_list(tGATT_IF gatt_if) {
   1920   tGATT_BG_CONN_DEV* p_dev_list = &gatt_cb.bgconn_dev[0];
   1921   uint8_t i, j, k;
   1922 
   1923   /* update the BG conn device list */
   1924   for (i = 0; i < GATT_MAX_BG_CONN_DEV; i++, p_dev_list++) {
   1925     if (p_dev_list->in_use) {
   1926       for (j = 0; j < GATT_MAX_APPS; j++) {
   1927         if (p_dev_list->gatt_if[j] == 0) break;
   1928 
   1929         if (p_dev_list->gatt_if[j] == gatt_if) {
   1930           for (k = j + 1; k < GATT_MAX_APPS; k++)
   1931             p_dev_list->gatt_if[k - 1] = p_dev_list->gatt_if[k];
   1932 
   1933           if (p_dev_list->gatt_if[0] == 0)
   1934             BTM_BleUpdateBgConnDev(false, p_dev_list->remote_bda);
   1935         }
   1936       }
   1937     }
   1938   }
   1939 }
   1940 
   1941 /*******************************************************************************
   1942  *
   1943  * Function         gatt_reset_bgdev_list
   1944  *
   1945  * Description      reset bg device list
   1946  *
   1947  * Returns          pointer to the device record
   1948  *
   1949  ******************************************************************************/
   1950 void gatt_reset_bgdev_list(void) {
   1951   memset(&gatt_cb.bgconn_dev, 0,
   1952          sizeof(tGATT_BG_CONN_DEV) * GATT_MAX_BG_CONN_DEV);
   1953 }
   1954 /*******************************************************************************
   1955  *
   1956  * Function         gatt_update_auto_connect_dev
   1957  *
   1958  * Description      This function add or remove a device for background
   1959  *                  connection procedure.
   1960  *
   1961  * Parameters       gatt_if: Application ID.
   1962  *                  add: add peer device
   1963  *                  bd_addr: peer device address.
   1964  *
   1965  * Returns          true if connection started; false otherwise.
   1966  *
   1967  ******************************************************************************/
   1968 bool gatt_update_auto_connect_dev(tGATT_IF gatt_if, bool add, BD_ADDR bd_addr) {
   1969   bool ret = false;
   1970   tGATT_REG* p_reg;
   1971   tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE);
   1972 
   1973   GATT_TRACE_API("gatt_update_auto_connect_dev ");
   1974   /* Make sure app is registered */
   1975   p_reg = gatt_get_regcb(gatt_if);
   1976   if (p_reg == NULL) {
   1977     GATT_TRACE_ERROR("gatt_update_auto_connect_dev - gatt_if is not registered",
   1978                      gatt_if);
   1979     return (false);
   1980   }
   1981 
   1982   if (add) {
   1983     ret = gatt_add_bg_dev_list(p_reg, bd_addr);
   1984 
   1985     if (ret && p_tcb != NULL) {
   1986       /* if a connected device, update the link holding number */
   1987       gatt_update_app_use_link_flag(gatt_if, p_tcb, true, true);
   1988     }
   1989   } else {
   1990     ret = gatt_remove_bg_dev_from_list(p_reg, bd_addr);
   1991   }
   1992   return ret;
   1993 }
   1994 
   1995 /*******************************************************************************
   1996  *
   1997  * Function     gatt_add_pending_new_srv_start
   1998  *
   1999  * Description  Add a pending new srv start to the new service start queue
   2000  *
   2001  * Returns    Pointer to the new service start buffer, NULL no buffer available
   2002  *
   2003  ******************************************************************************/
   2004 tGATT_PENDING_ENC_CLCB* gatt_add_pending_enc_channel_clcb(tGATT_TCB* p_tcb,
   2005                                                           tGATT_CLCB* p_clcb) {
   2006   tGATT_PENDING_ENC_CLCB* p_buf =
   2007       (tGATT_PENDING_ENC_CLCB*)osi_malloc(sizeof(tGATT_PENDING_ENC_CLCB));
   2008 
   2009   GATT_TRACE_DEBUG("%s", __func__);
   2010   GATT_TRACE_DEBUG("enqueue a new pending encryption channel clcb");
   2011 
   2012   p_buf->p_clcb = p_clcb;
   2013   fixed_queue_enqueue(p_tcb->pending_enc_clcb, p_buf);
   2014 
   2015   return p_buf;
   2016 }
   2017