• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
44 static 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 
47 static 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 *******************************************************************************/
bta_gatt_convert_uuid16_to_uuid128(UINT8 uuid_128[LEN_UUID_128],UINT16 uuid_16)58 void 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 *******************************************************************************/
bta_gattc_uuid_compare(const tBT_UUID * p_src,const tBT_UUID * p_tar,BOOLEAN is_precise)75 BOOLEAN 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 *******************************************************************************/
bta_gattc_cl_get_regcb(UINT8 client_if)126 tBTA_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 *******************************************************************************/
bta_gattc_num_reg_app(void)148 UINT8 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 *******************************************************************************/
bta_gattc_find_clcb_by_cif(UINT8 client_if,BD_ADDR remote_bda,tBTA_TRANSPORT transport)168 tBTA_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 *******************************************************************************/
bta_gattc_find_clcb_by_conn_id(UINT16 conn_id)193 tBTA_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 *******************************************************************************/
bta_gattc_clcb_alloc(tBTA_GATTC_IF client_if,BD_ADDR remote_bda,tBTA_TRANSPORT transport)216 tBTA_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 *******************************************************************************/
bta_gattc_find_alloc_clcb(tBTA_GATTC_IF client_if,BD_ADDR remote_bda,tBTA_TRANSPORT transport)265 tBTA_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 *******************************************************************************/
bta_gattc_clcb_dealloc(tBTA_GATTC_CLCB * p_clcb)286 void 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             /* clean up cache */
307             if (p_srcb->p_srvc_cache) {
308                 list_free(p_srcb->p_srvc_cache);
309                 p_srcb->p_srvc_cache = NULL;
310             }
311         }
312 
313         osi_free_and_reset((void **)&p_clcb->p_q_cmd);
314         memset(p_clcb, 0, sizeof(tBTA_GATTC_CLCB));
315     } else {
316         APPL_TRACE_ERROR("bta_gattc_clcb_dealloc p_clcb=NULL");
317     }
318 }
319 
320 /*******************************************************************************
321 **
322 ** Function         bta_gattc_find_srcb
323 **
324 ** Description      find server cache by remote bd address currently in use
325 **
326 ** Returns          pointer to the server cache.
327 **
328 *******************************************************************************/
bta_gattc_find_srcb(BD_ADDR bda)329 tBTA_GATTC_SERV * bta_gattc_find_srcb(BD_ADDR bda)
330 {
331     tBTA_GATTC_SERV *p_srcb = &bta_gattc_cb.known_server[0];
332     UINT8   i;
333 
334     for (i = 0; i < BTA_GATTC_KNOWN_SR_MAX; i ++, p_srcb ++)
335     {
336         if (p_srcb->in_use && bdcmp(p_srcb->server_bda, bda) == 0)
337             return p_srcb;
338     }
339     return NULL;
340 }
341 
342 /*******************************************************************************
343 **
344 ** Function         bta_gattc_find_srvr_cache
345 **
346 ** Description      find server cache by remote bd address
347 **
348 ** Returns          pointer to the server cache.
349 **
350 *******************************************************************************/
bta_gattc_find_srvr_cache(BD_ADDR bda)351 tBTA_GATTC_SERV * bta_gattc_find_srvr_cache(BD_ADDR bda)
352 {
353     tBTA_GATTC_SERV *p_srcb = &bta_gattc_cb.known_server[0];
354     UINT8   i;
355 
356     for (i = 0; i < BTA_GATTC_KNOWN_SR_MAX; i ++, p_srcb ++)
357     {
358         if (bdcmp(p_srcb->server_bda, bda) == 0)
359             return p_srcb;
360     }
361     return NULL;
362 }
363 /*******************************************************************************
364 **
365 ** Function         bta_gattc_find_scb_by_cid
366 **
367 ** Description      find server control block by connection ID
368 **
369 ** Returns          pointer to the server cache.
370 **
371 *******************************************************************************/
bta_gattc_find_scb_by_cid(UINT16 conn_id)372 tBTA_GATTC_SERV * bta_gattc_find_scb_by_cid (UINT16 conn_id)
373 {
374     tBTA_GATTC_CLCB *p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
375 
376     if (p_clcb)
377         return p_clcb->p_srcb;
378     else
379         return NULL;
380 }
381 /*******************************************************************************
382 **
383 ** Function         bta_gattc_srcb_alloc
384 **
385 ** Description      allocate server cache control block
386 **
387 ** Returns          pointer to the server cache.
388 **
389 *******************************************************************************/
bta_gattc_srcb_alloc(BD_ADDR bda)390 tBTA_GATTC_SERV * bta_gattc_srcb_alloc(BD_ADDR bda)
391 {
392     tBTA_GATTC_SERV *p_tcb = &bta_gattc_cb.known_server[0],
393                              *p_recycle = NULL;
394     BOOLEAN         found = FALSE;
395     UINT8           i;
396 
397     for (i = 0; i < BTA_GATTC_KNOWN_SR_MAX; i ++, p_tcb ++)
398     {
399         if (!p_tcb->in_use)
400         {
401             found = TRUE;
402             break;
403         }
404         else if (!p_tcb->connected)
405         {
406             p_recycle = p_tcb;
407         }
408     }
409 
410     /* if not found, try to recycle one known device */
411     if (!found && !p_recycle)
412         p_tcb = NULL;
413     else if (!found && p_recycle)
414         p_tcb = p_recycle;
415 
416     if (p_tcb != NULL)
417     {
418         if (p_tcb->p_srvc_cache != NULL)
419             list_free(p_tcb->p_srvc_cache);
420 
421         osi_free_and_reset((void **)&p_tcb->p_srvc_list);
422         memset(p_tcb, 0 , sizeof(tBTA_GATTC_SERV));
423 
424         p_tcb->in_use = TRUE;
425         bdcpy(p_tcb->server_bda, bda);
426     }
427     return p_tcb;
428 }
429 /*******************************************************************************
430 **
431 ** Function         bta_gattc_enqueue
432 **
433 ** Description      enqueue a client request in clcb.
434 **
435 ** Returns          success or failure.
436 **
437 *******************************************************************************/
bta_gattc_enqueue(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)438 BOOLEAN bta_gattc_enqueue(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
439 {
440 
441     if (p_clcb->p_q_cmd == NULL)
442     {
443         p_clcb->p_q_cmd = p_data;
444         return TRUE;
445     }
446 
447     APPL_TRACE_ERROR ("%s: already has a pending command!!", __func__);
448     /* skip the callback now. ----- need to send callback ? */
449     return FALSE;
450 }
451 
452 /*******************************************************************************
453 **
454 ** Function         bta_gattc_check_notif_registry
455 **
456 ** Description      check if the service notificaition has been registered.
457 **
458 ** Returns
459 **
460 *******************************************************************************/
bta_gattc_check_notif_registry(tBTA_GATTC_RCB * p_clreg,tBTA_GATTC_SERV * p_srcb,tBTA_GATTC_NOTIFY * p_notify)461 BOOLEAN bta_gattc_check_notif_registry(tBTA_GATTC_RCB  *p_clreg, tBTA_GATTC_SERV *p_srcb,
462                                        tBTA_GATTC_NOTIFY  *p_notify)
463 {
464     UINT8           i;
465 
466     for (i = 0 ; i < BTA_GATTC_NOTIF_REG_MAX; i ++)
467     {
468         if (p_clreg->notif_reg[i].in_use &&
469             bdcmp(p_clreg->notif_reg[i].remote_bda, p_srcb->server_bda) == 0 &&
470             p_clreg->notif_reg[i].handle == p_notify->handle)
471         {
472             APPL_TRACE_DEBUG("Notification registered!");
473             return TRUE;
474         }
475     }
476     return FALSE;
477 
478 }
479 /*******************************************************************************
480 **
481 ** Function         bta_gattc_clear_notif_registration
482 **
483 ** Description      Clear up the notification registration information by BD_ADDR.
484 **                  Where handle is between start_handle and end_handle, and
485 **                  start_handle and end_handle are boundaries of service
486 **                  containing characteristic.
487 **
488 ** Returns          None.
489 **
490 *******************************************************************************/
bta_gattc_clear_notif_registration(tBTA_GATTC_SERV * p_srcb,UINT16 conn_id,UINT16 start_handle,UINT16 end_handle)491 void bta_gattc_clear_notif_registration(tBTA_GATTC_SERV *p_srcb, UINT16 conn_id,
492                                         UINT16 start_handle, UINT16 end_handle)
493 {
494     BD_ADDR             remote_bda;
495     tBTA_GATTC_IF       gatt_if;
496     tBTA_GATTC_RCB      *p_clrcb ;
497     UINT8       i;
498     tGATT_TRANSPORT     transport;
499     UINT16              handle;
500 
501     if (GATT_GetConnectionInfor(conn_id, &gatt_if, remote_bda, &transport)) {
502         if ((p_clrcb = bta_gattc_cl_get_regcb(gatt_if)) != NULL) {
503             for (i = 0 ; i < BTA_GATTC_NOTIF_REG_MAX; i ++) {
504                 if (p_clrcb->notif_reg[i].in_use &&
505                     !bdcmp(p_clrcb->notif_reg[i].remote_bda, remote_bda))
506 
507                     /* It's enough to get service or characteristic handle, as
508                      * clear boundaries are always around service.
509                      */
510                     handle = p_clrcb->notif_reg[i].handle;
511                     if (handle >= start_handle && handle <= end_handle)
512                         memset(&p_clrcb->notif_reg[i], 0, sizeof(tBTA_GATTC_NOTIF_REG));
513             }
514         }
515     } else {
516         APPL_TRACE_ERROR("can not clear indication/notif registration for unknown app");
517     }
518     return;
519 }
520 
521 /*******************************************************************************
522 **
523 ** Function         bta_gattc_mark_bg_conn
524 **
525 ** Description      mark background connection status when a bg connection is initiated
526 **                  or terminated.
527 **
528 ** Returns          TRUE if success; FALSE otherwise.
529 **
530 *******************************************************************************/
bta_gattc_mark_bg_conn(tBTA_GATTC_IF client_if,BD_ADDR_PTR remote_bda_ptr,BOOLEAN add,BOOLEAN is_listen)531 BOOLEAN bta_gattc_mark_bg_conn (tBTA_GATTC_IF client_if,  BD_ADDR_PTR remote_bda_ptr,
532                                 BOOLEAN add, BOOLEAN is_listen)
533 {
534     tBTA_GATTC_BG_TCK   *p_bg_tck = &bta_gattc_cb.bg_track[0];
535     UINT8   i = 0;
536     tBTA_GATTC_CIF_MASK  *p_cif_mask;
537 
538     for (i = 0; i < BTA_GATTC_KNOWN_SR_MAX; i ++, p_bg_tck ++)
539     {
540         if (p_bg_tck->in_use &&
541             ((remote_bda_ptr != NULL && bdcmp(p_bg_tck->remote_bda, remote_bda_ptr) == 0) ||
542             (remote_bda_ptr == NULL && bdcmp(p_bg_tck->remote_bda, dummy_bda) == 0)))
543         {
544              p_cif_mask = is_listen ? &p_bg_tck->cif_adv_mask : &p_bg_tck->cif_mask;
545 
546             if (add)
547                 /* mask on the cif bit */
548                 *p_cif_mask |= (1 <<(client_if - 1));
549             else
550             {
551                 if (client_if != 0)
552                     *p_cif_mask &= (~(1 <<(client_if - 1)));
553                 else
554                     *p_cif_mask = 0;
555             }
556             /* no BG connection for this device, make it available */
557             if (p_bg_tck->cif_mask == 0 && p_bg_tck->cif_adv_mask == 0)
558             {
559                 memset(p_bg_tck, 0, sizeof(tBTA_GATTC_BG_TCK));
560             }
561             return TRUE;
562         }
563     }
564     if (!add)
565     {
566         if (remote_bda_ptr)
567         {
568             bdstr_t bdstr = {0};
569             APPL_TRACE_ERROR("%s unable to find the bg connection mask for: %s", __func__,
570                 bdaddr_to_string((bt_bdaddr_t *)remote_bda_ptr, bdstr, sizeof(bdstr)));
571         }
572         return FALSE;
573     }
574     else /* adding a new device mask */
575     {
576         for (i = 0, p_bg_tck = &bta_gattc_cb.bg_track[0];
577              i < BTA_GATTC_KNOWN_SR_MAX; i ++, p_bg_tck ++)
578         {
579             if (!p_bg_tck->in_use)
580             {
581                 p_bg_tck->in_use = TRUE;
582                 if (remote_bda_ptr)
583                     bdcpy(p_bg_tck->remote_bda, remote_bda_ptr);
584                 else
585                     bdcpy(p_bg_tck->remote_bda, dummy_bda);
586 
587                 p_cif_mask = is_listen ? &p_bg_tck->cif_adv_mask : &p_bg_tck->cif_mask;
588 
589                 *p_cif_mask = (1 <<(client_if - 1));
590                 return TRUE;
591             }
592         }
593         APPL_TRACE_ERROR("no available space to mark the bg connection status");
594         return FALSE;
595     }
596 }
597 /*******************************************************************************
598 **
599 ** Function         bta_gattc_check_bg_conn
600 **
601 ** Description      check if this is a background connection background connection.
602 **
603 ** Returns          TRUE if success; FALSE otherwise.
604 **
605 *******************************************************************************/
bta_gattc_check_bg_conn(tBTA_GATTC_IF client_if,BD_ADDR remote_bda,UINT8 role)606 BOOLEAN bta_gattc_check_bg_conn (tBTA_GATTC_IF client_if,  BD_ADDR remote_bda, UINT8 role)
607 {
608     tBTA_GATTC_BG_TCK   *p_bg_tck = &bta_gattc_cb.bg_track[0];
609     UINT8       i = 0;
610     BOOLEAN     is_bg_conn = FALSE;
611 
612     for (i = 0; i < BTA_GATTC_KNOWN_SR_MAX && !is_bg_conn; i ++, p_bg_tck ++)
613     {
614         if (p_bg_tck->in_use &&
615             (bdcmp(p_bg_tck->remote_bda, remote_bda) == 0 ||
616              bdcmp(p_bg_tck->remote_bda, dummy_bda) == 0))
617         {
618             if (((p_bg_tck->cif_mask &(1 <<(client_if - 1))) != 0) &&
619                 role == HCI_ROLE_MASTER)
620                 is_bg_conn = TRUE;
621 
622             if (((p_bg_tck->cif_adv_mask &(1 <<(client_if - 1))) != 0) &&
623                 role == HCI_ROLE_SLAVE)
624                 is_bg_conn = TRUE;
625         }
626     }
627     return is_bg_conn;
628 }
629 /*******************************************************************************
630 **
631 ** Function         bta_gattc_send_open_cback
632 **
633 ** Description      send open callback
634 **
635 ** Returns
636 **
637 *******************************************************************************/
bta_gattc_send_open_cback(tBTA_GATTC_RCB * p_clreg,tBTA_GATT_STATUS status,BD_ADDR remote_bda,UINT16 conn_id,tBTA_TRANSPORT transport,UINT16 mtu)638 void bta_gattc_send_open_cback( tBTA_GATTC_RCB *p_clreg, tBTA_GATT_STATUS status,
639                                 BD_ADDR remote_bda, UINT16 conn_id,
640                                 tBTA_TRANSPORT transport, UINT16 mtu)
641 {
642     tBTA_GATTC      cb_data;
643 
644     if (p_clreg->p_cback)
645     {
646         memset(&cb_data, 0, sizeof(tBTA_GATTC));
647 
648         cb_data.open.status = status;
649         cb_data.open.client_if = p_clreg->client_if;
650         cb_data.open.conn_id = conn_id;
651         cb_data.open.mtu = mtu;
652         cb_data.open.transport = transport;
653         bdcpy(cb_data.open.remote_bda, remote_bda);
654 
655         (*p_clreg->p_cback)(BTA_GATTC_OPEN_EVT, &cb_data);
656     }
657 }
658 /*******************************************************************************
659 **
660 ** Function         bta_gattc_conn_alloc
661 **
662 ** Description      allocate connection tracking spot
663 **
664 ** Returns          pointer to the clcb
665 **
666 *******************************************************************************/
bta_gattc_conn_alloc(BD_ADDR remote_bda)667 tBTA_GATTC_CONN * bta_gattc_conn_alloc(BD_ADDR remote_bda)
668 {
669     UINT8               i_conn = 0;
670     tBTA_GATTC_CONN     *p_conn = &bta_gattc_cb.conn_track[0];
671 
672     for (i_conn = 0; i_conn < BTA_GATTC_CONN_MAX; i_conn++, p_conn ++)
673     {
674         if (!p_conn->in_use)
675         {
676 #if BTA_GATT_DEBUG == TRUE
677             APPL_TRACE_DEBUG("bta_gattc_conn_alloc: found conn_track[%d] available",i_conn);
678 #endif
679             p_conn->in_use          = TRUE;
680             bdcpy(p_conn->remote_bda, remote_bda);
681             return p_conn;
682         }
683     }
684     return NULL;
685 }
686 
687 /*******************************************************************************
688 **
689 ** Function         bta_gattc_conn_find
690 **
691 ** Description      allocate connection tracking spot
692 **
693 ** Returns          pointer to the clcb
694 **
695 *******************************************************************************/
bta_gattc_conn_find(BD_ADDR remote_bda)696 tBTA_GATTC_CONN * bta_gattc_conn_find(BD_ADDR remote_bda)
697 {
698     UINT8               i_conn = 0;
699     tBTA_GATTC_CONN     *p_conn = &bta_gattc_cb.conn_track[0];
700 
701     for (i_conn = 0; i_conn < BTA_GATTC_CONN_MAX; i_conn++, p_conn ++)
702     {
703         if (p_conn->in_use && bdcmp(remote_bda, p_conn->remote_bda) == 0)
704         {
705 #if BTA_GATT_DEBUG == TRUE
706             APPL_TRACE_DEBUG("bta_gattc_conn_find: found conn_track[%d] matched",i_conn);
707 #endif
708             return p_conn;
709         }
710     }
711     return NULL;
712 }
713 
714 /*******************************************************************************
715 **
716 ** Function         bta_gattc_conn_find_alloc
717 **
718 ** Description      find or allocate connection tracking spot
719 **
720 ** Returns          pointer to the clcb
721 **
722 *******************************************************************************/
bta_gattc_conn_find_alloc(BD_ADDR remote_bda)723 tBTA_GATTC_CONN * bta_gattc_conn_find_alloc(BD_ADDR remote_bda)
724 {
725     tBTA_GATTC_CONN     *p_conn = bta_gattc_conn_find (remote_bda);
726 
727     if (p_conn == NULL)
728     {
729         p_conn = bta_gattc_conn_alloc(remote_bda);
730     }
731     return p_conn;
732 }
733 
734 /*******************************************************************************
735 **
736 ** Function         bta_gattc_conn_dealloc
737 **
738 ** Description      de-allocate connection tracking spot
739 **
740 ** Returns          pointer to the clcb
741 **
742 *******************************************************************************/
bta_gattc_conn_dealloc(BD_ADDR remote_bda)743 BOOLEAN bta_gattc_conn_dealloc(BD_ADDR remote_bda)
744 {
745     tBTA_GATTC_CONN     *p_conn = bta_gattc_conn_find (remote_bda);
746 
747     if (p_conn != NULL)
748     {
749         p_conn->in_use = FALSE;
750         memset(p_conn->remote_bda, 0, BD_ADDR_LEN);
751         return TRUE;
752     }
753     return FALSE;
754 }
755 
756 /*******************************************************************************
757 **
758 ** Function         bta_gattc_find_int_conn_clcb
759 **
760 ** Description      try to locate a clcb when an internal connecion event arrives.
761 **
762 ** Returns          pointer to the clcb
763 **
764 *******************************************************************************/
bta_gattc_find_int_conn_clcb(tBTA_GATTC_DATA * p_msg)765 tBTA_GATTC_CLCB * bta_gattc_find_int_conn_clcb(tBTA_GATTC_DATA *p_msg)
766 {
767     tBTA_GATTC_CLCB *p_clcb = NULL;
768 
769     if (p_msg->int_conn.role == HCI_ROLE_SLAVE)
770         bta_gattc_conn_find_alloc(p_msg->int_conn.remote_bda);
771 
772     /* try to locate a logic channel */
773     if ((p_clcb = bta_gattc_find_clcb_by_cif(p_msg->int_conn.client_if,
774                                              p_msg->int_conn.remote_bda,
775                                              p_msg->int_conn.transport)) == NULL)
776     {
777         /* for a background connection or listening connection */
778         if (/*p_msg->int_conn.role == HCI_ROLE_SLAVE ||  */
779             bta_gattc_check_bg_conn(p_msg->int_conn.client_if,
780                                     p_msg->int_conn.remote_bda,
781                                     p_msg->int_conn.role))
782         {
783             /* allocate a new channel */
784             p_clcb = bta_gattc_clcb_alloc(p_msg->int_conn.client_if,
785                                           p_msg->int_conn.remote_bda,
786                                           p_msg->int_conn.transport);
787         }
788     }
789     return p_clcb;
790 }
791 
792 /*******************************************************************************
793 **
794 ** Function         bta_gattc_find_int_disconn_clcb
795 **
796 ** Description      try to locate a clcb when an internal disconnect callback arrives.
797 **
798 ** Returns          pointer to the clcb
799 **
800 *******************************************************************************/
bta_gattc_find_int_disconn_clcb(tBTA_GATTC_DATA * p_msg)801 tBTA_GATTC_CLCB * bta_gattc_find_int_disconn_clcb(tBTA_GATTC_DATA *p_msg)
802 {
803     tBTA_GATTC_CLCB         *p_clcb = NULL;
804 
805     bta_gattc_conn_dealloc(p_msg->int_conn.remote_bda);
806     if ((p_clcb = bta_gattc_find_clcb_by_conn_id(p_msg->int_conn.hdr.layer_specific)) == NULL)
807     {
808         /* connection attempt failed, send connection callback event */
809         p_clcb = bta_gattc_find_clcb_by_cif(p_msg->int_conn.client_if,
810                                             p_msg->int_conn.remote_bda,
811                                             p_msg->int_conn.transport);
812     }
813     if (p_clcb == NULL)
814     {
815         APPL_TRACE_DEBUG(" disconnection ID: [%d] not used by BTA",
816             p_msg->int_conn.hdr.layer_specific);
817     }
818     return p_clcb;
819 }
820 
821 #endif /* BTA_GATT_INCLUDED */
822