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