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
31 #include "btcore/include/bdaddr.h"
32 #include "btif/include/btif_util.h"
33 #include "gki.h"
34 #include "utl.h"
35 #include "bta_sys.h"
36 #include "bta_gattc_int.h"
37 #include "l2c_api.h"
38
39 #define LOG_TAG "bt_bta_gattc"
40 /*****************************************************************************
41 ** Constants
42 *****************************************************************************/
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 *******************************************************************************/
bta_gatt_convert_uuid16_to_uuid128(UINT8 uuid_128[LEN_UUID_128],UINT16 uuid_16)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 *******************************************************************************/
bta_gattc_uuid_compare(tBT_UUID * p_src,tBT_UUID * p_tar,BOOLEAN is_precise)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 *******************************************************************************/
bta_gattc_cl_get_regcb(UINT8 client_if)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 *******************************************************************************/
bta_gattc_num_reg_app(void)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 *******************************************************************************/
bta_gattc_find_clcb_by_cif(UINT8 client_if,BD_ADDR remote_bda,tBTA_TRANSPORT transport)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 *******************************************************************************/
bta_gattc_find_clcb_by_conn_id(UINT16 conn_id)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 *******************************************************************************/
bta_gattc_clcb_alloc(tBTA_GATTC_IF client_if,BD_ADDR remote_bda,tBTA_TRANSPORT transport)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 *******************************************************************************/
bta_gattc_find_alloc_clcb(tBTA_GATTC_IF client_if,BD_ADDR remote_bda,tBTA_TRANSPORT transport)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 *******************************************************************************/
bta_gattc_clcb_dealloc(tBTA_GATTC_CLCB * p_clcb)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 *******************************************************************************/
bta_gattc_find_srcb(BD_ADDR bda)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 *******************************************************************************/
bta_gattc_find_srvr_cache(BD_ADDR bda)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 *******************************************************************************/
bta_gattc_find_scb_by_cid(UINT16 conn_id)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 *******************************************************************************/
bta_gattc_srcb_alloc(BD_ADDR bda)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 while (!GKI_queue_is_empty(&p_tcb->cache_buffer))
417 GKI_freebuf (GKI_dequeue (&p_tcb->cache_buffer));
418
419 utl_freebuf((void **)&p_tcb->p_srvc_list);
420 memset(p_tcb, 0 , sizeof(tBTA_GATTC_SERV));
421
422 p_tcb->in_use = TRUE;
423 bdcpy(p_tcb->server_bda, bda);
424 }
425 return p_tcb;
426 }
427 /*******************************************************************************
428 **
429 ** Function bta_gattc_enqueue
430 **
431 ** Description enqueue a client request in clcb.
432 **
433 ** Returns success or failure.
434 **
435 *******************************************************************************/
bta_gattc_enqueue(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)436 BOOLEAN bta_gattc_enqueue(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
437 {
438
439 if (p_clcb->p_q_cmd == NULL)
440 {
441 p_clcb->p_q_cmd = p_data;
442 }
443 else
444 {
445 APPL_TRACE_ERROR("already has a pending command!!");
446 /* skip the callback now. ----- need to send callback ? */
447 }
448 return (p_clcb->p_q_cmd != NULL) ? TRUE : FALSE;
449
450 }
451
452 /*******************************************************************************
453 **
454 ** Function bta_gattc_pack_attr_uuid
455 **
456 ** Description pack UUID into a stream.
457 **
458 ** Returns
459 **
460 *******************************************************************************/
bta_gattc_pack_attr_uuid(tBTA_GATTC_CACHE_ATTR * p_attr,tBT_UUID * p_uuid)461 void bta_gattc_pack_attr_uuid(tBTA_GATTC_CACHE_ATTR *p_attr, tBT_UUID *p_uuid)
462 {
463 UINT8 *pp = (UINT8 *)p_attr->p_uuid;
464
465 memset(p_uuid, 0, sizeof(tBT_UUID));
466
467 p_uuid->len = p_attr->uuid_len;
468
469 if (p_attr->uuid_len == LEN_UUID_16)
470 {
471 STREAM_TO_UINT16(p_uuid->uu.uuid16, pp);
472 }
473 else
474 {
475 memcpy(p_uuid->uu.uuid128, pp, LEN_UUID_128);
476 }
477
478 return;
479 }
480 /*******************************************************************************
481 **
482 ** Function bta_gattc_cpygattid
483 **
484 ** Description copy two tBTA_GATT_ID value
485 **
486 ** Returns
487 **
488 *******************************************************************************/
bta_gattc_cpygattid(tBTA_GATT_ID * p_des,tBTA_GATT_ID * p_src)489 void bta_gattc_cpygattid(tBTA_GATT_ID *p_des, tBTA_GATT_ID *p_src)
490 {
491 memset ((void *)p_des, 0, sizeof(tBTA_GATT_ID));
492
493 p_des->inst_id = p_src->inst_id;
494
495 p_des->uuid.len = p_src->uuid.len;
496
497 if (p_des->uuid.len == LEN_UUID_16)
498 {
499 p_des->uuid.uu.uuid16 = p_src->uuid.uu.uuid16;
500 }
501 else if (p_des->uuid.len == LEN_UUID_128)
502 {
503 memcpy(p_des->uuid.uu.uuid128, p_src->uuid.uu.uuid128, LEN_UUID_128);
504 }
505 }
506 /*******************************************************************************
507 **
508 ** Function bta_gattc_gattid_compare
509 **
510 ** Description compare two tBTA_GATT_ID type of pointer
511 **
512 ** Returns
513 **
514 *******************************************************************************/
bta_gattc_gattid_compare(tBTA_GATT_ID * p_src,tBTA_GATT_ID * p_tar)515 BOOLEAN bta_gattc_gattid_compare(tBTA_GATT_ID *p_src, tBTA_GATT_ID *p_tar)
516 {
517 if (p_src->inst_id == p_tar->inst_id &&
518 bta_gattc_uuid_compare (&p_src->uuid, &p_tar->uuid, TRUE ))
519 return TRUE;
520 else
521 return FALSE;
522
523 }
524 /*******************************************************************************
525 **
526 ** Function bta_gattc_srvcid_compare
527 **
528 ** Description compare two tBTA_GATT_SRVC_ID type of pointer
529 **
530 ** Returns
531 **
532 *******************************************************************************/
bta_gattc_srvcid_compare(tBTA_GATT_SRVC_ID * p_src,tBTA_GATT_SRVC_ID * p_tar)533 BOOLEAN bta_gattc_srvcid_compare(tBTA_GATT_SRVC_ID *p_src, tBTA_GATT_SRVC_ID *p_tar)
534 {
535 if (p_src->is_primary == p_tar->is_primary &&
536 bta_gattc_gattid_compare (&p_src->id, &p_tar->id))
537 return TRUE;
538 else
539 return FALSE;
540 }
541 /*******************************************************************************
542 **
543 ** Function bta_gattc_charid_compare
544 **
545 ** Description compare two tBTA_GATTC_CHAR_ID type of pointer
546 **
547 ** Returns
548 **
549 *******************************************************************************/
bta_gattc_charid_compare(tBTA_GATTC_CHAR_ID * p_src,tBTA_GATTC_CHAR_ID * p_tar)550 BOOLEAN bta_gattc_charid_compare(tBTA_GATTC_CHAR_ID *p_src, tBTA_GATTC_CHAR_ID *p_tar)
551 {
552 if (bta_gattc_gattid_compare (&p_src->char_id, &p_tar->char_id) &&
553 bta_gattc_srvcid_compare (&p_src->srvc_id, &p_tar->srvc_id))
554 return TRUE;
555 else
556 return FALSE;
557 }
558
559 /*******************************************************************************
560 **
561 ** Function bta_gattc_check_notif_registry
562 **
563 ** Description check if the service notificaition has been registered.
564 **
565 ** Returns
566 **
567 *******************************************************************************/
bta_gattc_check_notif_registry(tBTA_GATTC_RCB * p_clreg,tBTA_GATTC_SERV * p_srcb,tBTA_GATTC_NOTIFY * p_notify)568 BOOLEAN bta_gattc_check_notif_registry(tBTA_GATTC_RCB *p_clreg, tBTA_GATTC_SERV *p_srcb,
569 tBTA_GATTC_NOTIFY *p_notify)
570 {
571 UINT8 i;
572
573 for (i = 0 ; i < BTA_GATTC_NOTIF_REG_MAX; i ++)
574 {
575 if (p_clreg->notif_reg[i].in_use &&
576 bdcmp(p_clreg->notif_reg[i].remote_bda, p_srcb->server_bda) == 0 &&
577 bta_gattc_charid_compare (&p_clreg->notif_reg[i].char_id, &p_notify->char_id))
578 {
579 APPL_TRACE_DEBUG("Notification registered!");
580 return TRUE;
581 }
582 }
583 return FALSE;
584
585 }
586 /*******************************************************************************
587 **
588 ** Function bta_gattc_clear_notif_registration
589 **
590 ** Description clear up the notification registration information by BD_ADDR.
591 **
592 ** Returns None.
593 **
594 *******************************************************************************/
bta_gattc_clear_notif_registration(UINT16 conn_id)595 void bta_gattc_clear_notif_registration(UINT16 conn_id)
596 {
597 BD_ADDR remote_bda;
598 tBTA_GATTC_IF gatt_if;
599 tBTA_GATTC_RCB *p_clrcb ;
600 UINT8 i;
601 tGATT_TRANSPORT transport;
602
603 if (GATT_GetConnectionInfor(conn_id, &gatt_if, remote_bda, &transport))
604 {
605 if ((p_clrcb = bta_gattc_cl_get_regcb(gatt_if)) != NULL)
606 {
607 for (i = 0 ; i < BTA_GATTC_NOTIF_REG_MAX; i ++)
608 {
609 if (p_clrcb->notif_reg[i].in_use &&
610 !bdcmp(p_clrcb->notif_reg[i].remote_bda, remote_bda))
611 memset(&p_clrcb->notif_reg[i], 0, sizeof(tBTA_GATTC_NOTIF_REG));
612 }
613 }
614 }
615 else
616 {
617 APPL_TRACE_ERROR("can not clear indication/notif registration for unknown app");
618 }
619 return;
620 }
621
622 /*******************************************************************************
623 **
624 ** Function bta_gattc_pack_cb_data
625 **
626 ** Description pack the data from read response into callback data structure.
627 **
628 ** Returns
629 **
630 *******************************************************************************/
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)631 tBTA_GATT_STATUS bta_gattc_pack_read_cb_data(tBTA_GATTC_SERV *p_srcb,
632 tBT_UUID *p_descr_uuid,
633 tGATT_VALUE *p_attr,
634 tBTA_GATT_READ_VAL *p_value)
635 {
636 UINT8 i = 0, *pp = p_attr->value;
637 tBT_UUID uuid = {LEN_UUID_16, {GATT_UUID_CHAR_AGG_FORMAT}};
638 UINT16 handle;
639 tBTA_GATT_STATUS status = BTA_GATT_OK;
640
641 /* GATT_UUID_CHAR_AGG_FORMAT */
642 if (bta_gattc_uuid_compare (&uuid, p_descr_uuid, TRUE))
643 {
644 while (p_attr->len >= 2 && i < BTA_GATTC_MULTI_MAX)
645 {
646 STREAM_TO_UINT16(handle, pp);
647
648 if (bta_gattc_handle2id(p_srcb,
649 handle,
650 &p_value->aggre_value.pre_format[i].char_id.srvc_id,
651 &p_value->aggre_value.pre_format[i].char_id.char_id,
652 &p_value->aggre_value.pre_format[i].descr_id) == FALSE)
653 {
654 status = BTA_GATT_INTERNAL_ERROR;
655 APPL_TRACE_ERROR("can not map to GATT ID. handle = 0x%04x", handle);
656 break;
657 }
658 i ++;
659 p_attr->len -= 2;
660 }
661 p_value->aggre_value.num_pres_fmt = i;
662 }
663 else
664 {
665 /* all others, take as raw format */
666 p_value->unformat.len = p_attr->len;
667 p_value->unformat.p_value = p_attr->value;
668 }
669 return status;
670 }
671 /*******************************************************************************
672 **
673 ** Function bta_gattc_mark_bg_conn
674 **
675 ** Description mark background connection status when a bg connection is initiated
676 ** or terminated.
677 **
678 ** Returns TRUE if success; FALSE otherwise.
679 **
680 *******************************************************************************/
bta_gattc_mark_bg_conn(tBTA_GATTC_IF client_if,BD_ADDR_PTR remote_bda_ptr,BOOLEAN add,BOOLEAN is_listen)681 BOOLEAN bta_gattc_mark_bg_conn (tBTA_GATTC_IF client_if, BD_ADDR_PTR remote_bda_ptr,
682 BOOLEAN add, BOOLEAN is_listen)
683 {
684 tBTA_GATTC_BG_TCK *p_bg_tck = &bta_gattc_cb.bg_track[0];
685 UINT8 i = 0;
686 tBTA_GATTC_CIF_MASK *p_cif_mask;
687
688 for (i = 0; i < BTA_GATTC_KNOWN_SR_MAX; i ++, p_bg_tck ++)
689 {
690 if (p_bg_tck->in_use &&
691 ((remote_bda_ptr != NULL && bdcmp(p_bg_tck->remote_bda, remote_bda_ptr) == 0) ||
692 (remote_bda_ptr == NULL && bdcmp(p_bg_tck->remote_bda, dummy_bda) == 0)))
693 {
694 p_cif_mask = is_listen ? &p_bg_tck->cif_adv_mask : &p_bg_tck->cif_mask;
695
696 if (add)
697 /* mask on the cif bit */
698 *p_cif_mask |= (1 <<(client_if - 1));
699 else
700 {
701 if (client_if != 0)
702 *p_cif_mask &= (~(1 <<(client_if - 1)));
703 else
704 *p_cif_mask = 0;
705 }
706 /* no BG connection for this device, make it available */
707 if (p_bg_tck->cif_mask == 0 && p_bg_tck->cif_adv_mask == 0)
708 {
709 memset(p_bg_tck, 0, sizeof(tBTA_GATTC_BG_TCK));
710 }
711 return TRUE;
712 }
713 }
714 if (!add)
715 {
716 if (remote_bda_ptr)
717 {
718 bdstr_t bdstr = {0};
719 APPL_TRACE_ERROR("%s unable to find the bg connection mask for: %s", __func__,
720 bdaddr_to_string((bt_bdaddr_t *)remote_bda_ptr, bdstr, sizeof(bdstr)));
721 }
722 return FALSE;
723 }
724 else /* adding a new device mask */
725 {
726 for (i = 0, p_bg_tck = &bta_gattc_cb.bg_track[0];
727 i < BTA_GATTC_KNOWN_SR_MAX; i ++, p_bg_tck ++)
728 {
729 if (!p_bg_tck->in_use)
730 {
731 p_bg_tck->in_use = TRUE;
732 if (remote_bda_ptr)
733 bdcpy(p_bg_tck->remote_bda, remote_bda_ptr);
734 else
735 bdcpy(p_bg_tck->remote_bda, dummy_bda);
736
737 p_cif_mask = is_listen ? &p_bg_tck->cif_adv_mask : &p_bg_tck->cif_mask;
738
739 *p_cif_mask = (1 <<(client_if - 1));
740 return TRUE;
741 }
742 }
743 APPL_TRACE_ERROR("no available space to mark the bg connection status");
744 return FALSE;
745 }
746 }
747 /*******************************************************************************
748 **
749 ** Function bta_gattc_check_bg_conn
750 **
751 ** Description check if this is a background connection background connection.
752 **
753 ** Returns TRUE if success; FALSE otherwise.
754 **
755 *******************************************************************************/
bta_gattc_check_bg_conn(tBTA_GATTC_IF client_if,BD_ADDR remote_bda,UINT8 role)756 BOOLEAN bta_gattc_check_bg_conn (tBTA_GATTC_IF client_if, BD_ADDR remote_bda, UINT8 role)
757 {
758 tBTA_GATTC_BG_TCK *p_bg_tck = &bta_gattc_cb.bg_track[0];
759 UINT8 i = 0;
760 BOOLEAN is_bg_conn = FALSE;
761
762 for (i = 0; i < BTA_GATTC_KNOWN_SR_MAX && !is_bg_conn; i ++, p_bg_tck ++)
763 {
764 if (p_bg_tck->in_use &&
765 (bdcmp(p_bg_tck->remote_bda, remote_bda) == 0 ||
766 bdcmp(p_bg_tck->remote_bda, dummy_bda) == 0))
767 {
768 if (((p_bg_tck->cif_mask &(1 <<(client_if - 1))) != 0) &&
769 role == HCI_ROLE_MASTER)
770 is_bg_conn = TRUE;
771
772 if (((p_bg_tck->cif_adv_mask &(1 <<(client_if - 1))) != 0) &&
773 role == HCI_ROLE_SLAVE)
774 is_bg_conn = TRUE;
775 }
776 }
777 return is_bg_conn;
778 }
779 /*******************************************************************************
780 **
781 ** Function bta_gattc_send_open_cback
782 **
783 ** Description send open callback
784 **
785 ** Returns
786 **
787 *******************************************************************************/
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)788 void bta_gattc_send_open_cback( tBTA_GATTC_RCB *p_clreg, tBTA_GATT_STATUS status,
789 BD_ADDR remote_bda, UINT16 conn_id,
790 tBTA_TRANSPORT transport, UINT16 mtu)
791 {
792 tBTA_GATTC cb_data;
793
794 if (p_clreg->p_cback)
795 {
796 memset(&cb_data, 0, sizeof(tBTA_GATTC));
797
798 cb_data.open.status = status;
799 cb_data.open.client_if = p_clreg->client_if;
800 cb_data.open.conn_id = conn_id;
801 cb_data.open.mtu = mtu;
802 cb_data.open.transport = transport;
803 bdcpy(cb_data.open.remote_bda, remote_bda);
804
805 (*p_clreg->p_cback)(BTA_GATTC_OPEN_EVT, &cb_data);
806 }
807 }
808 /*******************************************************************************
809 **
810 ** Function bta_gattc_conn_alloc
811 **
812 ** Description allocate connection tracking spot
813 **
814 ** Returns pointer to the clcb
815 **
816 *******************************************************************************/
bta_gattc_conn_alloc(BD_ADDR remote_bda)817 tBTA_GATTC_CONN * bta_gattc_conn_alloc(BD_ADDR remote_bda)
818 {
819 UINT8 i_conn = 0;
820 tBTA_GATTC_CONN *p_conn = &bta_gattc_cb.conn_track[0];
821
822 for (i_conn = 0; i_conn < BTA_GATTC_CONN_MAX; i_conn++, p_conn ++)
823 {
824 if (!p_conn->in_use)
825 {
826 #if BTA_GATT_DEBUG == TRUE
827 APPL_TRACE_DEBUG("bta_gattc_conn_alloc: found conn_track[%d] available",i_conn);
828 #endif
829 p_conn->in_use = TRUE;
830 bdcpy(p_conn->remote_bda, remote_bda);
831 return p_conn;
832 }
833 }
834 return NULL;
835 }
836
837 /*******************************************************************************
838 **
839 ** Function bta_gattc_conn_find
840 **
841 ** Description allocate connection tracking spot
842 **
843 ** Returns pointer to the clcb
844 **
845 *******************************************************************************/
bta_gattc_conn_find(BD_ADDR remote_bda)846 tBTA_GATTC_CONN * bta_gattc_conn_find(BD_ADDR remote_bda)
847 {
848 UINT8 i_conn = 0;
849 tBTA_GATTC_CONN *p_conn = &bta_gattc_cb.conn_track[0];
850
851 for (i_conn = 0; i_conn < BTA_GATTC_CONN_MAX; i_conn++, p_conn ++)
852 {
853 if (p_conn->in_use && bdcmp(remote_bda, p_conn->remote_bda) == 0)
854 {
855 #if BTA_GATT_DEBUG == TRUE
856 APPL_TRACE_DEBUG("bta_gattc_conn_find: found conn_track[%d] matched",i_conn);
857 #endif
858 return p_conn;
859 }
860 }
861 return NULL;
862 }
863
864
865 /*******************************************************************************
866 **
867 ** Function bta_gattc_conn_find_alloc
868 **
869 ** Description find or allocate connection tracking spot
870 **
871 ** Returns pointer to the clcb
872 **
873 *******************************************************************************/
bta_gattc_conn_find_alloc(BD_ADDR remote_bda)874 tBTA_GATTC_CONN * bta_gattc_conn_find_alloc(BD_ADDR remote_bda)
875 {
876 tBTA_GATTC_CONN *p_conn = bta_gattc_conn_find (remote_bda);
877
878 if (p_conn == NULL)
879 {
880 p_conn = bta_gattc_conn_alloc(remote_bda);
881 }
882 return p_conn;
883 }
884
885 /*******************************************************************************
886 **
887 ** Function bta_gattc_conn_dealloc
888 **
889 ** Description de-allocate connection tracking spot
890 **
891 ** Returns pointer to the clcb
892 **
893 *******************************************************************************/
bta_gattc_conn_dealloc(BD_ADDR remote_bda)894 BOOLEAN bta_gattc_conn_dealloc(BD_ADDR remote_bda)
895 {
896 tBTA_GATTC_CONN *p_conn = bta_gattc_conn_find (remote_bda);
897
898 if (p_conn != NULL)
899 {
900 p_conn->in_use = FALSE;
901 memset(p_conn->remote_bda, 0, BD_ADDR_LEN);
902 return TRUE;
903 }
904 return FALSE;
905 }
906
907 /*******************************************************************************
908 **
909 ** Function bta_gattc_find_int_conn_clcb
910 **
911 ** Description try to locate a clcb when an internal connecion event arrives.
912 **
913 ** Returns pointer to the clcb
914 **
915 *******************************************************************************/
bta_gattc_find_int_conn_clcb(tBTA_GATTC_DATA * p_msg)916 tBTA_GATTC_CLCB * bta_gattc_find_int_conn_clcb(tBTA_GATTC_DATA *p_msg)
917 {
918 tBTA_GATTC_CLCB *p_clcb = NULL;
919
920 if (p_msg->int_conn.role == HCI_ROLE_SLAVE)
921 bta_gattc_conn_find_alloc(p_msg->int_conn.remote_bda);
922
923 /* try to locate a logic channel */
924 if ((p_clcb = bta_gattc_find_clcb_by_cif(p_msg->int_conn.client_if,
925 p_msg->int_conn.remote_bda,
926 p_msg->int_conn.transport)) == NULL)
927 {
928 /* for a background connection or listening connection */
929 if (/*p_msg->int_conn.role == HCI_ROLE_SLAVE || */
930 bta_gattc_check_bg_conn(p_msg->int_conn.client_if,
931 p_msg->int_conn.remote_bda,
932 p_msg->int_conn.role))
933 {
934 /* allocate a new channel */
935 p_clcb = bta_gattc_clcb_alloc(p_msg->int_conn.client_if,
936 p_msg->int_conn.remote_bda,
937 p_msg->int_conn.transport);
938 }
939 }
940 return p_clcb;
941 }
942
943 /*******************************************************************************
944 **
945 ** Function bta_gattc_find_int_disconn_clcb
946 **
947 ** Description try to locate a clcb when an internal disconnect callback arrives.
948 **
949 ** Returns pointer to the clcb
950 **
951 *******************************************************************************/
bta_gattc_find_int_disconn_clcb(tBTA_GATTC_DATA * p_msg)952 tBTA_GATTC_CLCB * bta_gattc_find_int_disconn_clcb(tBTA_GATTC_DATA *p_msg)
953 {
954 tBTA_GATTC_CLCB *p_clcb = NULL;
955
956 bta_gattc_conn_dealloc(p_msg->int_conn.remote_bda);
957 if ((p_clcb = bta_gattc_find_clcb_by_conn_id(p_msg->int_conn.hdr.layer_specific)) == NULL)
958 {
959 /* connection attempt failed, send connection callback event */
960 p_clcb = bta_gattc_find_clcb_by_cif(p_msg->int_conn.client_if,
961 p_msg->int_conn.remote_bda,
962 p_msg->int_conn.transport);
963 }
964 if (p_clcb == NULL)
965 {
966 APPL_TRACE_DEBUG(" disconnection ID: [%d] not used by BTA",
967 p_msg->int_conn.hdr.layer_specific);
968 }
969 return p_clcb;
970 }
971
972 #endif /* BTA_GATT_INCLUDED */
973