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