OSDN Git Service

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