Home | History | Annotate | Download | only in gatt
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2003-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 the GATT client utility function.
     22  *
     23  ******************************************************************************/
     24 
     25 #define LOG_TAG "bt_bta_gattc"
     26 
     27 #include "bt_target.h"
     28 
     29 #include <base/logging.h>
     30 #include <string.h>
     31 
     32 #include "bt_common.h"
     33 #include "bta_gattc_int.h"
     34 #include "bta_sys.h"
     35 #include "l2c_api.h"
     36 #include "utl.h"
     37 
     38 /*****************************************************************************
     39  *  Constants
     40  ****************************************************************************/
     41 
     42 static const uint8_t base_uuid[LEN_UUID_128] = {
     43     0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80,
     44     0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
     45 
     46 /*******************************************************************************
     47  *
     48  * Function         bta_gatt_convert_uuid16_to_uuid128
     49  *
     50  * Description      Convert a 16 bits UUID to be an standard 128 bits one.
     51  *
     52  * Returns          true if two uuid match; false otherwise.
     53  *
     54  ******************************************************************************/
     55 void bta_gatt_convert_uuid16_to_uuid128(uint8_t uuid_128[LEN_UUID_128],
     56                                         uint16_t uuid_16) {
     57   uint8_t* p = &uuid_128[LEN_UUID_128 - 4];
     58 
     59   memcpy(uuid_128, base_uuid, LEN_UUID_128);
     60 
     61   UINT16_TO_STREAM(p, uuid_16);
     62 }
     63 /*******************************************************************************
     64  *
     65  * Function         bta_gattc_uuid_compare
     66  *
     67  * Description      Compare two UUID to see if they are the same.
     68  *
     69  * Returns          true if two uuid match; false otherwise.
     70  *
     71  ******************************************************************************/
     72 bool bta_gattc_uuid_compare(const tBT_UUID* p_src, const tBT_UUID* p_tar,
     73                             bool is_precise) {
     74   uint8_t su[LEN_UUID_128], tu[LEN_UUID_128];
     75   const uint8_t *ps, *pt;
     76 
     77   /* any of the UUID is unspecified */
     78   if (p_src == 0 || p_tar == 0) {
     79     if (is_precise)
     80       return false;
     81     else
     82       return true;
     83   }
     84 
     85   /* If both are 16-bit, we can do a simple compare */
     86   if (p_src->len == 2 && p_tar->len == 2) {
     87     return p_src->uu.uuid16 == p_tar->uu.uuid16;
     88   }
     89 
     90   /* One or both of the UUIDs is 128-bit */
     91   if (p_src->len == LEN_UUID_16) {
     92     /* convert a 16 bits UUID to 128 bits value */
     93     bta_gatt_convert_uuid16_to_uuid128(su, p_src->uu.uuid16);
     94     ps = su;
     95   } else
     96     ps = p_src->uu.uuid128;
     97 
     98   if (p_tar->len == LEN_UUID_16) {
     99     /* convert a 16 bits UUID to 128 bits value */
    100     bta_gatt_convert_uuid16_to_uuid128(tu, p_tar->uu.uuid16);
    101     pt = tu;
    102   } else
    103     pt = p_tar->uu.uuid128;
    104 
    105   return (memcmp(ps, pt, LEN_UUID_128) == 0);
    106 }
    107 
    108 /*******************************************************************************
    109  *
    110  * Function         bta_gattc_cl_get_regcb
    111  *
    112  * Description      get registration control block by client interface.
    113  *
    114  * Returns          pointer to the regcb
    115  *
    116  ******************************************************************************/
    117 tBTA_GATTC_RCB* bta_gattc_cl_get_regcb(uint8_t client_if) {
    118   uint8_t i = 0;
    119   tBTA_GATTC_RCB* p_clrcb = &bta_gattc_cb.cl_rcb[0];
    120 
    121   for (i = 0; i < BTA_GATTC_CL_MAX; i++, p_clrcb++) {
    122     if (p_clrcb->in_use && p_clrcb->client_if == client_if) return p_clrcb;
    123   }
    124   return NULL;
    125 }
    126 /*******************************************************************************
    127  *
    128  * Function         bta_gattc_num_reg_app
    129  *
    130  * Description      find the number of registered application.
    131  *
    132  * Returns          pointer to the regcb
    133  *
    134  ******************************************************************************/
    135 uint8_t bta_gattc_num_reg_app(void) {
    136   uint8_t i = 0, j = 0;
    137 
    138   for (i = 0; i < BTA_GATTC_CL_MAX; i++) {
    139     if (bta_gattc_cb.cl_rcb[i].in_use) j++;
    140   }
    141   return j;
    142 }
    143 /*******************************************************************************
    144  *
    145  * Function         bta_gattc_find_clcb_by_cif
    146  *
    147  * Description      get clcb by client interface and remote bd adddress
    148  *
    149  * Returns          pointer to the clcb
    150  *
    151  ******************************************************************************/
    152 tBTA_GATTC_CLCB* bta_gattc_find_clcb_by_cif(uint8_t client_if,
    153                                             const RawAddress& remote_bda,
    154                                             tBTA_TRANSPORT transport) {
    155   tBTA_GATTC_CLCB* p_clcb = &bta_gattc_cb.clcb[0];
    156   uint8_t i;
    157 
    158   for (i = 0; i < BTA_GATTC_CLCB_MAX; i++, p_clcb++) {
    159     if (p_clcb->in_use && p_clcb->p_rcb->client_if == client_if &&
    160         p_clcb->transport == transport && p_clcb->bda == remote_bda)
    161       return p_clcb;
    162   }
    163   return NULL;
    164 }
    165 /*******************************************************************************
    166  *
    167  * Function         bta_gattc_find_clcb_by_conn_id
    168  *
    169  * Description      get clcb by connection ID
    170  *
    171  * Returns          pointer to the clcb
    172  *
    173  ******************************************************************************/
    174 tBTA_GATTC_CLCB* bta_gattc_find_clcb_by_conn_id(uint16_t conn_id) {
    175   tBTA_GATTC_CLCB* p_clcb = &bta_gattc_cb.clcb[0];
    176   uint8_t i;
    177 
    178   for (i = 0; i < BTA_GATTC_CLCB_MAX; i++, p_clcb++) {
    179     if (p_clcb->in_use && p_clcb->bta_conn_id == conn_id) return p_clcb;
    180   }
    181   return NULL;
    182 }
    183 
    184 /*******************************************************************************
    185  *
    186  * Function         bta_gattc_clcb_alloc
    187  *
    188  * Description      allocate CLCB
    189  *
    190  * Returns          pointer to the clcb
    191  *
    192  ******************************************************************************/
    193 tBTA_GATTC_CLCB* bta_gattc_clcb_alloc(tBTA_GATTC_IF client_if,
    194                                       const RawAddress& remote_bda,
    195                                       tBTA_TRANSPORT transport) {
    196   uint8_t i_clcb = 0;
    197   tBTA_GATTC_CLCB* p_clcb = NULL;
    198 
    199   for (i_clcb = 0; i_clcb < BTA_GATTC_CLCB_MAX; i_clcb++) {
    200     if (!bta_gattc_cb.clcb[i_clcb].in_use) {
    201 #if (BTA_GATT_DEBUG == TRUE)
    202       APPL_TRACE_DEBUG("bta_gattc_clcb_alloc: found clcb[%d] available",
    203                        i_clcb);
    204 #endif
    205       p_clcb = &bta_gattc_cb.clcb[i_clcb];
    206       p_clcb->in_use = true;
    207       p_clcb->status = BTA_GATT_OK;
    208       p_clcb->transport = transport;
    209       p_clcb->bda = remote_bda;
    210 
    211       p_clcb->p_rcb = bta_gattc_cl_get_regcb(client_if);
    212 
    213       p_clcb->p_srcb = bta_gattc_find_srcb(remote_bda);
    214       if (p_clcb->p_srcb == NULL)
    215         p_clcb->p_srcb = bta_gattc_srcb_alloc(remote_bda);
    216 
    217       if (p_clcb->p_rcb != NULL && p_clcb->p_srcb != NULL) {
    218         p_clcb->p_srcb->num_clcb++;
    219         p_clcb->p_rcb->num_clcb++;
    220       } else {
    221         /* release this clcb if clcb or srcb allocation failed */
    222         p_clcb->in_use = false;
    223         p_clcb = NULL;
    224       }
    225       break;
    226     }
    227   }
    228   return p_clcb;
    229 }
    230 /*******************************************************************************
    231  *
    232  * Function         bta_gattc_find_alloc_clcb
    233  *
    234  * Description      find or allocate CLCB if not found.
    235  *
    236  * Returns          pointer to the clcb
    237  *
    238  ******************************************************************************/
    239 tBTA_GATTC_CLCB* bta_gattc_find_alloc_clcb(tBTA_GATTC_IF client_if,
    240                                            const RawAddress& remote_bda,
    241                                            tBTA_TRANSPORT transport) {
    242   tBTA_GATTC_CLCB* p_clcb;
    243 
    244   p_clcb = bta_gattc_find_clcb_by_cif(client_if, remote_bda, transport);
    245   if (p_clcb == NULL) {
    246     p_clcb = bta_gattc_clcb_alloc(client_if, remote_bda, transport);
    247   }
    248   return p_clcb;
    249 }
    250 
    251 /*******************************************************************************
    252  *
    253  * Function         bta_gattc_clcb_dealloc
    254  *
    255  * Description      Deallocte a clcb
    256  *
    257  * Returns          pointer to the clcb
    258  *
    259  ******************************************************************************/
    260 void bta_gattc_clcb_dealloc(tBTA_GATTC_CLCB* p_clcb) {
    261   tBTA_GATTC_SERV* p_srcb = NULL;
    262 
    263   if (p_clcb) {
    264     p_srcb = p_clcb->p_srcb;
    265     if (p_srcb->num_clcb) p_srcb->num_clcb--;
    266 
    267     if (p_clcb->p_rcb->num_clcb) p_clcb->p_rcb->num_clcb--;
    268 
    269     /* if the srcb is no longer needed, reset the state */
    270     if (p_srcb->num_clcb == 0) {
    271       p_srcb->connected = false;
    272       p_srcb->state = BTA_GATTC_SERV_IDLE;
    273       p_srcb->mtu = 0;
    274 
    275       /* clean up cache */
    276       if (p_srcb->p_srvc_cache) {
    277         list_free(p_srcb->p_srvc_cache);
    278         p_srcb->p_srvc_cache = NULL;
    279       }
    280     }
    281 
    282     osi_free_and_reset((void**)&p_clcb->p_q_cmd);
    283     memset(p_clcb, 0, sizeof(tBTA_GATTC_CLCB));
    284   } else {
    285     APPL_TRACE_ERROR("bta_gattc_clcb_dealloc p_clcb=NULL");
    286   }
    287 }
    288 
    289 /*******************************************************************************
    290  *
    291  * Function         bta_gattc_find_srcb
    292  *
    293  * Description      find server cache by remote bd address currently in use
    294  *
    295  * Returns          pointer to the server cache.
    296  *
    297  ******************************************************************************/
    298 tBTA_GATTC_SERV* bta_gattc_find_srcb(const RawAddress& bda) {
    299   tBTA_GATTC_SERV* p_srcb = &bta_gattc_cb.known_server[0];
    300   uint8_t i;
    301 
    302   for (i = 0; i < BTA_GATTC_KNOWN_SR_MAX; i++, p_srcb++) {
    303     if (p_srcb->in_use && p_srcb->server_bda == bda) return p_srcb;
    304   }
    305   return NULL;
    306 }
    307 
    308 /*******************************************************************************
    309  *
    310  * Function         bta_gattc_find_srvr_cache
    311  *
    312  * Description      find server cache by remote bd address
    313  *
    314  * Returns          pointer to the server cache.
    315  *
    316  ******************************************************************************/
    317 tBTA_GATTC_SERV* bta_gattc_find_srvr_cache(const RawAddress& bda) {
    318   tBTA_GATTC_SERV* p_srcb = &bta_gattc_cb.known_server[0];
    319   uint8_t i;
    320 
    321   for (i = 0; i < BTA_GATTC_KNOWN_SR_MAX; i++, p_srcb++) {
    322     if (p_srcb->server_bda == bda) return p_srcb;
    323   }
    324   return NULL;
    325 }
    326 /*******************************************************************************
    327  *
    328  * Function         bta_gattc_find_scb_by_cid
    329  *
    330  * Description      find server control block by connection ID
    331  *
    332  * Returns          pointer to the server cache.
    333  *
    334  ******************************************************************************/
    335 tBTA_GATTC_SERV* bta_gattc_find_scb_by_cid(uint16_t conn_id) {
    336   tBTA_GATTC_CLCB* p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
    337 
    338   if (p_clcb)
    339     return p_clcb->p_srcb;
    340   else
    341     return NULL;
    342 }
    343 /*******************************************************************************
    344  *
    345  * Function         bta_gattc_srcb_alloc
    346  *
    347  * Description      allocate server cache control block
    348  *
    349  * Returns          pointer to the server cache.
    350  *
    351  ******************************************************************************/
    352 tBTA_GATTC_SERV* bta_gattc_srcb_alloc(const RawAddress& bda) {
    353   tBTA_GATTC_SERV *p_tcb = &bta_gattc_cb.known_server[0], *p_recycle = NULL;
    354   bool found = false;
    355   uint8_t i;
    356 
    357   for (i = 0; i < BTA_GATTC_KNOWN_SR_MAX; i++, p_tcb++) {
    358     if (!p_tcb->in_use) {
    359       found = true;
    360       break;
    361     } else if (!p_tcb->connected) {
    362       p_recycle = p_tcb;
    363     }
    364   }
    365 
    366   /* if not found, try to recycle one known device */
    367   if (!found && !p_recycle)
    368     p_tcb = NULL;
    369   else if (!found && p_recycle)
    370     p_tcb = p_recycle;
    371 
    372   if (p_tcb != NULL) {
    373     if (p_tcb->p_srvc_cache != NULL) list_free(p_tcb->p_srvc_cache);
    374 
    375     osi_free_and_reset((void**)&p_tcb->p_srvc_list);
    376     memset(p_tcb, 0, sizeof(tBTA_GATTC_SERV));
    377 
    378     p_tcb->in_use = true;
    379     p_tcb->server_bda = bda;
    380   }
    381   return p_tcb;
    382 }
    383 /*******************************************************************************
    384  *
    385  * Function         bta_gattc_enqueue
    386  *
    387  * Description      enqueue a client request in clcb.
    388  *
    389  * Returns          success or failure.
    390  *
    391  ******************************************************************************/
    392 bool bta_gattc_enqueue(tBTA_GATTC_CLCB* p_clcb, tBTA_GATTC_DATA* p_data) {
    393   if (p_clcb->p_q_cmd == NULL) {
    394     p_clcb->p_q_cmd = p_data;
    395     return true;
    396   }
    397 
    398   APPL_TRACE_ERROR("%s: already has a pending command!!", __func__);
    399   /* skip the callback now. ----- need to send callback ? */
    400   return false;
    401 }
    402 
    403 /*******************************************************************************
    404  *
    405  * Function         bta_gattc_check_notif_registry
    406  *
    407  * Description      check if the service notificaition has been registered.
    408  *
    409  * Returns
    410  *
    411  ******************************************************************************/
    412 bool bta_gattc_check_notif_registry(tBTA_GATTC_RCB* p_clreg,
    413                                     tBTA_GATTC_SERV* p_srcb,
    414                                     tBTA_GATTC_NOTIFY* p_notify) {
    415   uint8_t i;
    416 
    417   for (i = 0; i < BTA_GATTC_NOTIF_REG_MAX; i++) {
    418     if (p_clreg->notif_reg[i].in_use &&
    419         p_clreg->notif_reg[i].remote_bda == p_srcb->server_bda &&
    420         p_clreg->notif_reg[i].handle == p_notify->handle) {
    421       APPL_TRACE_DEBUG("Notification registered!");
    422       return true;
    423     }
    424   }
    425   return false;
    426 }
    427 /*******************************************************************************
    428  *
    429  * Function         bta_gattc_clear_notif_registration
    430  *
    431  * Description      Clear up the notification registration information by
    432  *                  RawAddress.
    433  *                  Where handle is between start_handle and end_handle, and
    434  *                  start_handle and end_handle are boundaries of service
    435  *                  containing characteristic.
    436  *
    437  * Returns          None.
    438  *
    439  ******************************************************************************/
    440 void bta_gattc_clear_notif_registration(tBTA_GATTC_SERV* p_srcb,
    441                                         uint16_t conn_id, uint16_t start_handle,
    442                                         uint16_t end_handle) {
    443   RawAddress remote_bda;
    444   tBTA_GATTC_IF gatt_if;
    445   tBTA_GATTC_RCB* p_clrcb;
    446   uint8_t i;
    447   tGATT_TRANSPORT transport;
    448   uint16_t handle;
    449 
    450   if (GATT_GetConnectionInfor(conn_id, &gatt_if, remote_bda, &transport)) {
    451     p_clrcb = bta_gattc_cl_get_regcb(gatt_if);
    452     if (p_clrcb != NULL) {
    453       for (i = 0; i < BTA_GATTC_NOTIF_REG_MAX; i++) {
    454         if (p_clrcb->notif_reg[i].in_use &&
    455             p_clrcb->notif_reg[i].remote_bda == remote_bda) {
    456           /* It's enough to get service or characteristic handle, as
    457            * clear boundaries are always around service.
    458            */
    459           handle = p_clrcb->notif_reg[i].handle;
    460           if (handle >= start_handle && handle <= end_handle)
    461             memset(&p_clrcb->notif_reg[i], 0, sizeof(tBTA_GATTC_NOTIF_REG));
    462         }
    463       }
    464     }
    465   } else {
    466     APPL_TRACE_ERROR(
    467         "can not clear indication/notif registration for unknown app");
    468   }
    469   return;
    470 }
    471 
    472 /*******************************************************************************
    473  *
    474  * Function         bta_gattc_mark_bg_conn
    475  *
    476  * Description      mark background connection status when a bg connection is
    477  *                  initiated or terminated.
    478  *
    479  * Returns          true if success; false otherwise.
    480  *
    481  ******************************************************************************/
    482 bool bta_gattc_mark_bg_conn(tBTA_GATTC_IF client_if,
    483                             const RawAddress& remote_bda_ptr, bool add) {
    484   tBTA_GATTC_BG_TCK* p_bg_tck = &bta_gattc_cb.bg_track[0];
    485   uint8_t i = 0;
    486   tBTA_GATTC_CIF_MASK* p_cif_mask;
    487 
    488   for (i = 0; i < BTA_GATTC_KNOWN_SR_MAX; i++, p_bg_tck++) {
    489     if (p_bg_tck->in_use && ((p_bg_tck->remote_bda == remote_bda_ptr) ||
    490                              (p_bg_tck->remote_bda.IsEmpty()))) {
    491       p_cif_mask = &p_bg_tck->cif_mask;
    492 
    493       if (add) /* mask on the cif bit */
    494         *p_cif_mask |= (1 << (client_if - 1));
    495       else {
    496         if (client_if != 0)
    497           *p_cif_mask &= (~(1 << (client_if - 1)));
    498         else
    499           *p_cif_mask = 0;
    500       }
    501       /* no BG connection for this device, make it available */
    502       if (p_bg_tck->cif_mask == 0) {
    503         memset(p_bg_tck, 0, sizeof(tBTA_GATTC_BG_TCK));
    504       }
    505       return true;
    506     }
    507   }
    508   if (!add) {
    509     LOG(ERROR) << __func__ << " unable to find the bg connection mask for: "
    510                << remote_bda_ptr;
    511     return false;
    512   } else /* adding a new device mask */
    513   {
    514     for (i = 0, p_bg_tck = &bta_gattc_cb.bg_track[0];
    515          i < BTA_GATTC_KNOWN_SR_MAX; i++, p_bg_tck++) {
    516       if (!p_bg_tck->in_use) {
    517         p_bg_tck->in_use = true;
    518         p_bg_tck->remote_bda = remote_bda_ptr;
    519 
    520         p_cif_mask = &p_bg_tck->cif_mask;
    521 
    522         *p_cif_mask = (1 << (client_if - 1));
    523         return true;
    524       }
    525     }
    526     APPL_TRACE_ERROR("no available space to mark the bg connection status");
    527     return false;
    528   }
    529 }
    530 /*******************************************************************************
    531  *
    532  * Function         bta_gattc_check_bg_conn
    533  *
    534  * Description      check if this is a background connection background
    535  *                  connection.
    536  *
    537  * Returns          true if success; false otherwise.
    538  *
    539  ******************************************************************************/
    540 bool bta_gattc_check_bg_conn(tBTA_GATTC_IF client_if,
    541                              const RawAddress& remote_bda, uint8_t role) {
    542   tBTA_GATTC_BG_TCK* p_bg_tck = &bta_gattc_cb.bg_track[0];
    543   uint8_t i = 0;
    544   bool is_bg_conn = false;
    545 
    546   for (i = 0; i < BTA_GATTC_KNOWN_SR_MAX && !is_bg_conn; i++, p_bg_tck++) {
    547     if (p_bg_tck->in_use && (p_bg_tck->remote_bda == remote_bda ||
    548                              p_bg_tck->remote_bda.IsEmpty())) {
    549       if (((p_bg_tck->cif_mask & (1 << (client_if - 1))) != 0) &&
    550           role == HCI_ROLE_MASTER)
    551         is_bg_conn = true;
    552     }
    553   }
    554   return is_bg_conn;
    555 }
    556 /*******************************************************************************
    557  *
    558  * Function         bta_gattc_send_open_cback
    559  *
    560  * Description      send open callback
    561  *
    562  * Returns
    563  *
    564  ******************************************************************************/
    565 void bta_gattc_send_open_cback(tBTA_GATTC_RCB* p_clreg, tBTA_GATT_STATUS status,
    566                                const RawAddress& remote_bda, uint16_t conn_id,
    567                                tBTA_TRANSPORT transport, uint16_t mtu) {
    568   tBTA_GATTC cb_data;
    569 
    570   if (p_clreg->p_cback) {
    571     memset(&cb_data, 0, sizeof(tBTA_GATTC));
    572 
    573     cb_data.open.status = status;
    574     cb_data.open.client_if = p_clreg->client_if;
    575     cb_data.open.conn_id = conn_id;
    576     cb_data.open.mtu = mtu;
    577     cb_data.open.transport = transport;
    578     cb_data.open.remote_bda = remote_bda;
    579 
    580     (*p_clreg->p_cback)(BTA_GATTC_OPEN_EVT, &cb_data);
    581   }
    582 }
    583 /*******************************************************************************
    584  *
    585  * Function         bta_gattc_conn_alloc
    586  *
    587  * Description      allocate connection tracking spot
    588  *
    589  * Returns          pointer to the clcb
    590  *
    591  ******************************************************************************/
    592 tBTA_GATTC_CONN* bta_gattc_conn_alloc(const RawAddress& remote_bda) {
    593   uint8_t i_conn = 0;
    594   tBTA_GATTC_CONN* p_conn = &bta_gattc_cb.conn_track[0];
    595 
    596   for (i_conn = 0; i_conn < BTA_GATTC_CONN_MAX; i_conn++, p_conn++) {
    597     if (!p_conn->in_use) {
    598 #if (BTA_GATT_DEBUG == TRUE)
    599       APPL_TRACE_DEBUG("bta_gattc_conn_alloc: found conn_track[%d] available",
    600                        i_conn);
    601 #endif
    602       p_conn->in_use = true;
    603       p_conn->remote_bda = remote_bda;
    604       return p_conn;
    605     }
    606   }
    607   return NULL;
    608 }
    609 
    610 /*******************************************************************************
    611  *
    612  * Function         bta_gattc_conn_find
    613  *
    614  * Description      allocate connection tracking spot
    615  *
    616  * Returns          pointer to the clcb
    617  *
    618  ******************************************************************************/
    619 tBTA_GATTC_CONN* bta_gattc_conn_find(const RawAddress& remote_bda) {
    620   uint8_t i_conn = 0;
    621   tBTA_GATTC_CONN* p_conn = &bta_gattc_cb.conn_track[0];
    622 
    623   for (i_conn = 0; i_conn < BTA_GATTC_CONN_MAX; i_conn++, p_conn++) {
    624     if (p_conn->in_use && remote_bda == p_conn->remote_bda) {
    625 #if (BTA_GATT_DEBUG == TRUE)
    626       APPL_TRACE_DEBUG("bta_gattc_conn_find: found conn_track[%d] matched",
    627                        i_conn);
    628 #endif
    629       return p_conn;
    630     }
    631   }
    632   return NULL;
    633 }
    634 
    635 /*******************************************************************************
    636  *
    637  * Function         bta_gattc_conn_find_alloc
    638  *
    639  * Description      find or allocate connection tracking spot
    640  *
    641  * Returns          pointer to the clcb
    642  *
    643  ******************************************************************************/
    644 tBTA_GATTC_CONN* bta_gattc_conn_find_alloc(const RawAddress& remote_bda) {
    645   tBTA_GATTC_CONN* p_conn = bta_gattc_conn_find(remote_bda);
    646 
    647   if (p_conn == NULL) {
    648     p_conn = bta_gattc_conn_alloc(remote_bda);
    649   }
    650   return p_conn;
    651 }
    652 
    653 /*******************************************************************************
    654  *
    655  * Function         bta_gattc_conn_dealloc
    656  *
    657  * Description      de-allocate connection tracking spot
    658  *
    659  * Returns          pointer to the clcb
    660  *
    661  ******************************************************************************/
    662 bool bta_gattc_conn_dealloc(const RawAddress& remote_bda) {
    663   tBTA_GATTC_CONN* p_conn = bta_gattc_conn_find(remote_bda);
    664 
    665   if (p_conn != NULL) {
    666     p_conn->in_use = false;
    667     p_conn->remote_bda = RawAddress::kEmpty;
    668     return true;
    669   }
    670   return false;
    671 }
    672 
    673 /*******************************************************************************
    674  *
    675  * Function         bta_gattc_find_int_conn_clcb
    676  *
    677  * Description      try to locate a clcb when an internal connecion event
    678  *                  arrives.
    679  *
    680  * Returns          pointer to the clcb
    681  *
    682  ******************************************************************************/
    683 tBTA_GATTC_CLCB* bta_gattc_find_int_conn_clcb(tBTA_GATTC_DATA* p_msg) {
    684   tBTA_GATTC_CLCB* p_clcb = NULL;
    685 
    686   if (p_msg->int_conn.role == HCI_ROLE_SLAVE)
    687     bta_gattc_conn_find_alloc(p_msg->int_conn.remote_bda);
    688 
    689   /* try to locate a logic channel */
    690   p_clcb = bta_gattc_find_clcb_by_cif(p_msg->int_conn.client_if,
    691                                       p_msg->int_conn.remote_bda,
    692                                       p_msg->int_conn.transport);
    693   if (p_clcb == NULL) {
    694     /* for a background connection or listening connection */
    695     if (/*p_msg->int_conn.role == HCI_ROLE_SLAVE ||  */
    696         bta_gattc_check_bg_conn(p_msg->int_conn.client_if,
    697                                 p_msg->int_conn.remote_bda,
    698                                 p_msg->int_conn.role)) {
    699       /* allocate a new channel */
    700       p_clcb = bta_gattc_clcb_alloc(p_msg->int_conn.client_if,
    701                                     p_msg->int_conn.remote_bda,
    702                                     p_msg->int_conn.transport);
    703     }
    704   }
    705   return p_clcb;
    706 }
    707 
    708 /*******************************************************************************
    709  *
    710  * Function         bta_gattc_find_int_disconn_clcb
    711  *
    712  * Description      try to locate a clcb when an internal disconnect callback
    713  *                  arrives.
    714  *
    715  * Returns          pointer to the clcb
    716  *
    717  ******************************************************************************/
    718 tBTA_GATTC_CLCB* bta_gattc_find_int_disconn_clcb(tBTA_GATTC_DATA* p_msg) {
    719   tBTA_GATTC_CLCB* p_clcb = NULL;
    720 
    721   bta_gattc_conn_dealloc(p_msg->int_conn.remote_bda);
    722   p_clcb = bta_gattc_find_clcb_by_conn_id(p_msg->int_conn.hdr.layer_specific);
    723   if (p_clcb == NULL) {
    724     /* connection attempt failed, send connection callback event */
    725     p_clcb = bta_gattc_find_clcb_by_cif(p_msg->int_conn.client_if,
    726                                         p_msg->int_conn.remote_bda,
    727                                         p_msg->int_conn.transport);
    728   }
    729   if (p_clcb == NULL) {
    730     APPL_TRACE_DEBUG(" disconnection ID: [%d] not used by BTA",
    731                      p_msg->int_conn.hdr.layer_specific);
    732   }
    733   return p_clcb;
    734 }
    735