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