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