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