1 /******************************************************************************
3 * Copyright (C) 2003-2012 Broadcom Corporation
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:
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 ******************************************************************************/
19 /******************************************************************************
21 * This file contains the GATT client utility function.
23 ******************************************************************************/
25 #include "bt_target.h"
27 #if defined(GATTC_INCLUDED) && (GATTC_INCLUDED == TRUE)
32 // #include "btif/include/btif_util.h"
35 #include "bta_gattc_int.h"
37 #include "allocator.h"
39 #define LOG_TAG "bt_bta_gattc"
40 /*****************************************************************************
42 *****************************************************************************/
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
49 static const BD_ADDR dummy_bda = {0, 0, 0, 0, 0, 0};
51 #define GATTC_COMMAND_QUEUE_SIZE_MAX 30
53 /*******************************************************************************
55 ** Function bta_gatt_convert_uuid16_to_uuid128
57 ** Description Convert a 16 bits UUID to be an standard 128 bits one.
59 ** Returns TRUE if two uuid match; FALSE otherwise.
61 *******************************************************************************/
62 void bta_gatt_convert_uuid16_to_uuid128(UINT8 uuid_128[LEN_UUID_128], UINT16 uuid_16)
64 UINT8 *p = &uuid_128[LEN_UUID_128 - 4];
66 memcpy (uuid_128, base_uuid, LEN_UUID_128);
68 UINT16_TO_STREAM(p, uuid_16);
70 /*******************************************************************************
72 ** Function bta_gattc_uuid_compare
74 ** Description Compare two UUID to see if they are the same.
76 ** Returns TRUE if two uuid match; FALSE otherwise.
78 *******************************************************************************/
79 BOOLEAN bta_gattc_uuid_compare (const tBT_UUID *p_src, const tBT_UUID *p_tar, BOOLEAN is_precise)
81 UINT8 su[LEN_UUID_128], tu[LEN_UUID_128];
84 /* any of the UUID is unspecified */
85 if (p_src == 0 || p_tar == 0) {
93 /* If both are 16-bit, we can do a simple compare */
94 if (p_src->len == 2 && p_tar->len == 2) {
95 return p_src->uu.uuid16 == p_tar->uu.uuid16;
98 /* One or both of the UUIDs is 128-bit */
99 if (p_src->len == LEN_UUID_16) {
100 /* convert a 16 bits UUID to 128 bits value */
101 bta_gatt_convert_uuid16_to_uuid128(su, p_src->uu.uuid16);
104 ps = p_src->uu.uuid128;
107 if (p_tar->len == LEN_UUID_16) {
108 /* convert a 16 bits UUID to 128 bits value */
109 bta_gatt_convert_uuid16_to_uuid128(tu, p_tar->uu.uuid16);
112 pt = p_tar->uu.uuid128;
115 return (memcmp(ps, pt, LEN_UUID_128) == 0);
118 /*******************************************************************************
120 ** Function bta_gattc_cl_get_regcb
122 ** Description get registration control block by client interface.
124 ** Returns pointer to the regcb
126 *******************************************************************************/
127 tBTA_GATTC_RCB *bta_gattc_cl_get_regcb(UINT8 client_if)
130 tBTA_GATTC_RCB *p_clrcb = &bta_gattc_cb.cl_rcb[0];
132 for (i = 0; i < BTA_GATTC_CL_MAX; i ++, p_clrcb ++) {
133 if (p_clrcb->in_use &&
134 p_clrcb->client_if == client_if) {
140 /*******************************************************************************
142 ** Function bta_gattc_num_reg_app
144 ** Description find the number of registered application.
146 ** Returns pointer to the regcb
148 *******************************************************************************/
149 UINT8 bta_gattc_num_reg_app(void)
153 for (i = 0; i < BTA_GATTC_CL_MAX; i ++) {
154 if (bta_gattc_cb.cl_rcb[i].in_use) {
160 /*******************************************************************************
162 ** Function bta_gattc_find_clcb_by_cif
164 ** Description get clcb by client interface and remote bd adddress
166 ** Returns pointer to the clcb
168 *******************************************************************************/
169 tBTA_GATTC_CLCB *bta_gattc_find_clcb_by_cif (UINT8 client_if, BD_ADDR remote_bda,
170 tBTA_TRANSPORT transport)
172 tBTA_GATTC_CLCB *p_clcb = &bta_gattc_cb.clcb[0];
175 for (i = 0; i < BTA_GATTC_CLCB_MAX; i ++, p_clcb ++) {
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) {
185 /*******************************************************************************
187 ** Function bta_gattc_find_clcb_by_conn_id
189 ** Description get clcb by connection ID
191 ** Returns pointer to the clcb
193 *******************************************************************************/
194 tBTA_GATTC_CLCB *bta_gattc_find_clcb_by_conn_id (UINT16 conn_id)
196 tBTA_GATTC_CLCB *p_clcb = &bta_gattc_cb.clcb[0];
199 for (i = 0; i < BTA_GATTC_CLCB_MAX; i ++, p_clcb ++) {
200 if (p_clcb->in_use &&
201 p_clcb->bta_conn_id == conn_id) {
208 /*******************************************************************************
210 ** Function bta_gattc_clcb_alloc
212 ** Description allocate CLCB
214 ** Returns pointer to the clcb
216 *******************************************************************************/
217 tBTA_GATTC_CLCB *bta_gattc_clcb_alloc(tBTA_GATTC_IF client_if, BD_ADDR remote_bda,
218 tBTA_TRANSPORT transport)
221 tBTA_GATTC_CLCB *p_clcb = NULL;
223 for (i_clcb = 0; i_clcb < BTA_GATTC_CLCB_MAX; i_clcb++) {
224 if (!bta_gattc_cb.clcb[i_clcb].in_use) {
225 #if BTA_GATT_DEBUG == TRUE
226 APPL_TRACE_DEBUG("bta_gattc_clcb_alloc: found clcb[%d] available", i_clcb);
228 p_clcb = &bta_gattc_cb.clcb[i_clcb];
229 p_clcb->in_use = TRUE;
230 p_clcb->status = BTA_GATT_OK;
231 p_clcb->transport = transport;
232 bdcpy(p_clcb->bda, remote_bda);
234 p_clcb->p_rcb = bta_gattc_cl_get_regcb(client_if);
235 if (p_clcb->p_cmd_list == NULL) {
236 p_clcb->p_cmd_list = list_new(osi_free_func);
238 if ((p_clcb->p_srcb = bta_gattc_find_srcb(remote_bda)) == NULL) {
239 p_clcb->p_srcb = bta_gattc_srcb_alloc(remote_bda);
242 if (p_clcb->p_rcb != NULL && p_clcb->p_srcb != NULL) {
243 p_clcb->p_srcb->num_clcb ++;
244 p_clcb->p_rcb->num_clcb ++;
246 /* release this clcb if clcb or srcb allocation failed */
247 p_clcb->in_use = FALSE;
255 /*******************************************************************************
257 ** Function bta_gattc_find_alloc_clcb
259 ** Description find or allocate CLCB if not found.
261 ** Returns pointer to the clcb
263 *******************************************************************************/
264 tBTA_GATTC_CLCB *bta_gattc_find_alloc_clcb(tBTA_GATTC_IF client_if, BD_ADDR remote_bda,
265 tBTA_TRANSPORT transport)
267 tBTA_GATTC_CLCB *p_clcb ;
269 if ((p_clcb = bta_gattc_find_clcb_by_cif(client_if, remote_bda, transport)) == NULL) {
270 p_clcb = bta_gattc_clcb_alloc(client_if, remote_bda, transport);
275 /*******************************************************************************
277 ** Function bta_gattc_clcb_dealloc
279 ** Description Deallocte a clcb
281 ** Returns pointer to the clcb
283 *******************************************************************************/
284 void bta_gattc_clcb_dealloc(tBTA_GATTC_CLCB *p_clcb)
286 tBTA_GATTC_SERV *p_srcb = NULL;
289 p_srcb = p_clcb->p_srcb;
290 if (p_srcb->num_clcb) {
294 if (p_clcb->p_rcb->num_clcb) {
295 p_clcb->p_rcb->num_clcb --;
298 /* if the srcb is no longer needed, reset the state */
299 if ( p_srcb->num_clcb == 0) {
300 p_srcb->connected = FALSE;
301 p_srcb->state = BTA_GATTC_SERV_IDLE;
305 if (p_srcb->p_srvc_cache) {
306 list_free(p_srcb->p_srvc_cache);
307 p_srcb->p_srvc_cache = NULL;
310 osi_free(p_clcb->p_q_cmd);
311 p_clcb->p_q_cmd = NULL;
312 // don't forget to clear the command queue before dealloc the clcb.
313 list_clear(p_clcb->p_cmd_list);
314 osi_free((void *)p_clcb->p_cmd_list);
315 p_clcb->p_cmd_list = NULL;
316 //osi_free_and_reset((void **)&p_clcb->p_q_cmd);
317 memset(p_clcb, 0, sizeof(tBTA_GATTC_CLCB));
319 APPL_TRACE_ERROR("bta_gattc_clcb_dealloc p_clcb=NULL");
323 /*******************************************************************************
325 ** Function bta_gattc_find_srcb
327 ** Description find server cache by remote bd address currently in use
329 ** Returns pointer to the server cache.
331 *******************************************************************************/
332 tBTA_GATTC_SERV *bta_gattc_find_srcb(BD_ADDR bda)
334 tBTA_GATTC_SERV *p_srcb = &bta_gattc_cb.known_server[0];
337 for (i = 0; i < BTA_GATTC_KNOWN_SR_MAX; i ++, p_srcb ++) {
338 if (p_srcb->in_use && bdcmp(p_srcb->server_bda, bda) == 0) {
345 /*******************************************************************************
347 ** Function bta_gattc_find_srvr_cache
349 ** Description find server cache by remote bd address
351 ** Returns pointer to the server cache.
353 *******************************************************************************/
354 tBTA_GATTC_SERV *bta_gattc_find_srvr_cache(BD_ADDR bda)
356 tBTA_GATTC_SERV *p_srcb = &bta_gattc_cb.known_server[0];
359 for (i = 0; i < BTA_GATTC_KNOWN_SR_MAX; i ++, p_srcb ++) {
360 if (bdcmp(p_srcb->server_bda, bda) == 0) {
366 /*******************************************************************************
368 ** Function bta_gattc_find_scb_by_cid
370 ** Description find server control block by connection ID
372 ** Returns pointer to the server cache.
374 *******************************************************************************/
375 tBTA_GATTC_SERV *bta_gattc_find_scb_by_cid (UINT16 conn_id)
377 tBTA_GATTC_CLCB *p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
380 return p_clcb->p_srcb;
385 /*******************************************************************************
387 ** Function bta_gattc_srcb_alloc
389 ** Description allocate server cache control block
391 ** Returns pointer to the server cache.
393 *******************************************************************************/
394 tBTA_GATTC_SERV *bta_gattc_srcb_alloc(BD_ADDR bda)
396 tBTA_GATTC_SERV *p_tcb = &bta_gattc_cb.known_server[0],
398 BOOLEAN found = FALSE;
401 for (i = 0; i < BTA_GATTC_KNOWN_SR_MAX; i ++, p_tcb ++) {
402 if (!p_tcb->in_use) {
405 } else if (!p_tcb->connected) {
410 /* if not found, try to recycle one known device */
411 if (!found && !p_recycle) {
414 else if (!found && p_recycle) {
420 if (p_tcb->p_srvc_cache != NULL)
421 list_free(p_tcb->p_srvc_cache);
422 osi_free(p_tcb->p_srvc_list);
423 p_tcb->p_srvc_list = NULL;
424 //osi_free_and_reset((void **)&p_tcb->p_srvc_list);
425 memset(p_tcb, 0 , sizeof(tBTA_GATTC_SERV));
427 p_tcb->in_use = TRUE;
428 bdcpy(p_tcb->server_bda, bda);
433 static BOOLEAN bta_gattc_has_prepare_command_in_queue(tBTA_GATTC_CLCB *p_clcb)
435 assert(p_clcb != NULL);
437 for(list_node_t *sn = list_begin(p_clcb->p_cmd_list);
438 sn != list_end(p_clcb->p_cmd_list); sn = list_next(sn)) {
440 tBTA_GATTC_DATA *cmd_data = (tBTA_GATTC_DATA *)list_node(sn);
441 if (cmd_data != NULL && ((cmd_data->hdr.event == BTA_GATTC_API_WRITE_EVT &&
442 cmd_data->api_write.write_type == BTA_GATTC_WRITE_PREPARE) ||
443 cmd_data->hdr.event == BTA_GATTC_API_EXEC_EVT)) {
450 /*******************************************************************************
452 ** Function bta_gattc_enqueue
454 ** Description enqueue a client request in clcb.
456 ** Returns success or failure.
458 *******************************************************************************/
459 BOOLEAN bta_gattc_enqueue(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
461 tBTA_GATTC cb_data = {0};
463 if (p_clcb->p_q_cmd == NULL) {
464 p_clcb->p_q_cmd = p_data;
466 } else if ((p_data->hdr.event == BTA_GATTC_API_WRITE_EVT &&
467 p_data->api_write.write_type == BTA_GATTC_WRITE_PREPARE) &&
468 ((p_clcb->p_q_cmd->hdr.event == BTA_GATTC_API_WRITE_EVT &&
469 p_clcb->p_q_cmd->api_write.write_type == BTA_GATTC_WRITE_PREPARE) ||
470 bta_gattc_has_prepare_command_in_queue(p_clcb))) {
471 APPL_TRACE_DEBUG("%s(), prepare offset = %d", __func__, p_data->api_write.offset);
472 cb_data.write.status = BTA_GATT_CONGESTED;
473 cb_data.write.handle = p_data->api_write.handle;
474 cb_data.write.conn_id = p_clcb->bta_conn_id;
475 cb_data.write.offset = p_data->api_write.offset;
476 /* write complete, callback */
477 if (p_clcb->p_rcb->p_cback != NULL) {
478 ( *p_clcb->p_rcb->p_cback)(BTA_GATTC_PREP_WRITE_EVT, (tBTA_GATTC *)&cb_data);
482 else if (p_clcb->p_cmd_list) {
484 tBTA_GATTC_DATA *cmd_data = NULL;
486 if (list_length(p_clcb->p_cmd_list) >= GATTC_COMMAND_QUEUE_SIZE_MAX) {
488 APPL_TRACE_ERROR("%s(), the gattc command queue is full.", __func__);
489 cb_data.status = GATT_BUSY;
490 cb_data.queue_full.conn_id = p_clcb->bta_conn_id;
491 cb_data.queue_full.is_full = TRUE;
492 p_clcb->is_full = TRUE;
493 if (p_clcb->p_rcb->p_cback != NULL) {
494 ( *p_clcb->p_rcb->p_cback)(BTA_GATTC_QUEUE_FULL_EVT, (tBTA_GATTC *)&cb_data);
499 if (p_data->hdr.event == BTA_GATTC_API_WRITE_EVT) {
500 len = p_data->api_write.len;
501 if ((cmd_data = (tBTA_GATTC_DATA *)osi_malloc(sizeof(tBTA_GATTC_DATA) + len)) != NULL) {
502 memset(cmd_data, 0, sizeof(tBTA_GATTC_DATA) + len);
503 memcpy(cmd_data, p_data, sizeof(tBTA_GATTC_DATA));
504 cmd_data->api_write.p_value = (UINT8 *)(cmd_data + 1);
505 memcpy(cmd_data->api_write.p_value, p_data->api_write.p_value, len);
507 APPL_TRACE_ERROR("%s(), line = %d, alloc fail, no memery.", __func__, __LINE__);
511 if ((cmd_data = (tBTA_GATTC_DATA *)osi_malloc(sizeof(tBTA_GATTC_DATA))) != NULL) {
512 memset(cmd_data, 0, sizeof(tBTA_GATTC_DATA));
513 memcpy(cmd_data, p_data, sizeof(tBTA_GATTC_DATA));
515 APPL_TRACE_ERROR("%s(), line = %d, alloc fail, no memery.", __func__, __LINE__);
520 //store the command to the command list.
521 list_append(p_clcb->p_cmd_list, (void *)cmd_data);
528 /*******************************************************************************
530 ** Function bta_gattc_check_notif_registry
532 ** Description check if the service notificaition has been registered.
536 *******************************************************************************/
537 BOOLEAN bta_gattc_check_notif_registry(tBTA_GATTC_RCB *p_clreg, tBTA_GATTC_SERV *p_srcb,
538 tBTA_GATTC_NOTIFY *p_notify)
542 for (i = 0 ; i < BTA_GATTC_NOTIF_REG_MAX; i ++)
544 if (p_clreg->notif_reg[i].in_use &&
545 bdcmp(p_clreg->notif_reg[i].remote_bda, p_srcb->server_bda) == 0 &&
546 p_clreg->notif_reg[i].handle == p_notify->handle)
548 APPL_TRACE_DEBUG("Notification registered!");
555 /*******************************************************************************
557 ** Function bta_gattc_clear_notif_registration
559 ** Description Clear up the notification registration information by BD_ADDR.
560 ** Where handle is between start_handle and end_handle, and
561 ** start_handle and end_handle are boundaries of service
562 ** containing characteristic.
566 *******************************************************************************/
567 void bta_gattc_clear_notif_registration(tBTA_GATTC_SERV *p_srcb, UINT16 conn_id,
568 UINT16 start_handle, UINT16 end_handle)
571 tBTA_GATTC_IF gatt_if;
572 tBTA_GATTC_RCB *p_clrcb ;
574 tGATT_TRANSPORT transport;
577 if (GATT_GetConnectionInfor(conn_id, &gatt_if, remote_bda, &transport)) {
578 if ((p_clrcb = bta_gattc_cl_get_regcb(gatt_if)) != NULL) {
579 for (i = 0 ; i < BTA_GATTC_NOTIF_REG_MAX; i ++) {
580 if (p_clrcb->notif_reg[i].in_use &&
581 !bdcmp(p_clrcb->notif_reg[i].remote_bda, remote_bda))
583 /* It's enough to get service or characteristic handle, as
584 * clear boundaries are always around service.
586 handle = p_clrcb->notif_reg[i].handle;
587 if (handle >= start_handle && handle <= end_handle)
588 memset(&p_clrcb->notif_reg[i], 0, sizeof(tBTA_GATTC_NOTIF_REG));
592 APPL_TRACE_ERROR("can not clear indication/notif registration for unknown app");
597 /*******************************************************************************
599 ** Function bta_gattc_mark_bg_conn
601 ** Description mark background connection status when a bg connection is initiated
604 ** Returns TRUE if success; FALSE otherwise.
606 *******************************************************************************/
607 BOOLEAN bta_gattc_mark_bg_conn (tBTA_GATTC_IF client_if, BD_ADDR_PTR remote_bda_ptr,
608 BOOLEAN add, BOOLEAN is_listen)
610 tBTA_GATTC_BG_TCK *p_bg_tck = &bta_gattc_cb.bg_track[0];
612 tBTA_GATTC_CIF_MASK *p_cif_mask;
614 for (i = 0; i < BTA_GATTC_KNOWN_SR_MAX; i ++, p_bg_tck ++) {
615 if (p_bg_tck->in_use &&
616 ((remote_bda_ptr != NULL && bdcmp(p_bg_tck->remote_bda, remote_bda_ptr) == 0) ||
617 (remote_bda_ptr == NULL && bdcmp(p_bg_tck->remote_bda, dummy_bda) == 0))) {
618 p_cif_mask = is_listen ? &p_bg_tck->cif_adv_mask : &p_bg_tck->cif_mask;
621 /* mask on the cif bit */
623 *p_cif_mask |= (1 << (client_if - 1));
625 if (client_if != 0) {
626 *p_cif_mask &= (~(1 << (client_if - 1)));
631 /* no BG connection for this device, make it available */
632 if (p_bg_tck->cif_mask == 0 && p_bg_tck->cif_adv_mask == 0) {
633 memset(p_bg_tck, 0, sizeof(tBTA_GATTC_BG_TCK));
639 if (remote_bda_ptr) {
640 // bdstr_t bdstr = {0};
641 char bdstr[18] = {0};
642 APPL_TRACE_ERROR("%s unable to find the bg connection mask for: %s", __func__,
643 bdaddr_to_string((bt_bdaddr_t *)remote_bda_ptr, bdstr, sizeof(bdstr)));
646 } else { /* adding a new device mask */
647 for (i = 0, p_bg_tck = &bta_gattc_cb.bg_track[0];
648 i < BTA_GATTC_KNOWN_SR_MAX; i ++, p_bg_tck ++) {
649 if (!p_bg_tck->in_use) {
650 p_bg_tck->in_use = TRUE;
651 if (remote_bda_ptr) {
652 bdcpy(p_bg_tck->remote_bda, remote_bda_ptr);
654 bdcpy(p_bg_tck->remote_bda, dummy_bda);
657 p_cif_mask = is_listen ? &p_bg_tck->cif_adv_mask : &p_bg_tck->cif_mask;
659 *p_cif_mask = (1 << (client_if - 1));
663 APPL_TRACE_ERROR("no available space to mark the bg connection status");
667 /*******************************************************************************
669 ** Function bta_gattc_check_bg_conn
671 ** Description check if this is a background connection background connection.
673 ** Returns TRUE if success; FALSE otherwise.
675 *******************************************************************************/
676 BOOLEAN bta_gattc_check_bg_conn (tBTA_GATTC_IF client_if, BD_ADDR remote_bda, UINT8 role)
678 tBTA_GATTC_BG_TCK *p_bg_tck = &bta_gattc_cb.bg_track[0];
680 BOOLEAN is_bg_conn = FALSE;
682 for (i = 0; i < BTA_GATTC_KNOWN_SR_MAX && !is_bg_conn; i ++, p_bg_tck ++) {
683 if (p_bg_tck->in_use &&
684 (bdcmp(p_bg_tck->remote_bda, remote_bda) == 0 ||
685 bdcmp(p_bg_tck->remote_bda, dummy_bda) == 0)) {
686 if (((p_bg_tck->cif_mask & (1 << (client_if - 1))) != 0) &&
687 role == HCI_ROLE_MASTER) {
691 if (((p_bg_tck->cif_adv_mask & (1 << (client_if - 1))) != 0) &&
692 role == HCI_ROLE_SLAVE) {
699 /*******************************************************************************
701 ** Function bta_gattc_send_open_cback
703 ** Description send open callback
707 *******************************************************************************/
708 void bta_gattc_send_open_cback( tBTA_GATTC_RCB *p_clreg, tBTA_GATT_STATUS status,
709 BD_ADDR remote_bda, UINT16 conn_id,
710 tBTA_TRANSPORT transport, UINT16 mtu)
714 if (p_clreg->p_cback) {
715 memset(&cb_data, 0, sizeof(tBTA_GATTC));
717 cb_data.open.status = status;
718 cb_data.open.client_if = p_clreg->client_if;
719 cb_data.open.conn_id = conn_id;
720 cb_data.open.mtu = mtu;
721 cb_data.open.transport = transport;
722 bdcpy(cb_data.open.remote_bda, remote_bda);
724 (*p_clreg->p_cback)(BTA_GATTC_OPEN_EVT, &cb_data);
728 /*******************************************************************************
730 ** Function bta_gattc_send_connect_cback
732 ** Description send connect callback
736 *******************************************************************************/
737 void bta_gattc_send_connect_cback( tBTA_GATTC_RCB *p_clreg, BD_ADDR remote_bda, UINT16 conn_id)
741 if (p_clreg->p_cback) {
742 memset(&cb_data, 0, sizeof(tBTA_GATTC));
744 cb_data.connect.client_if = p_clreg->client_if;
745 cb_data.connect.conn_id = conn_id;
746 bdcpy(cb_data.connect.remote_bda, remote_bda);
748 (*p_clreg->p_cback)(BTA_GATTC_CONNECT_EVT, &cb_data);
752 /*******************************************************************************
754 ** Function bta_gattc_send_disconnect_cback
756 ** Description send disconnect callback
760 *******************************************************************************/
761 void bta_gattc_send_disconnect_cback( tBTA_GATTC_RCB *p_clreg, tGATT_DISCONN_REASON reason,
762 BD_ADDR remote_bda, UINT16 conn_id)
766 if (p_clreg->p_cback) {
767 memset(&cb_data, 0, sizeof(tBTA_GATTC));
769 cb_data.disconnect.reason = reason;
770 cb_data.disconnect.client_if = p_clreg->client_if;
771 cb_data.disconnect.conn_id = conn_id;
772 bdcpy(cb_data.disconnect.remote_bda, remote_bda);
774 (*p_clreg->p_cback)(BTA_GATTC_DISCONNECT_EVT, &cb_data);
777 /*******************************************************************************
779 ** Function bta_gattc_conn_alloc
781 ** Description allocate connection tracking spot
783 ** Returns pointer to the clcb
785 *******************************************************************************/
786 tBTA_GATTC_CONN *bta_gattc_conn_alloc(BD_ADDR remote_bda)
789 tBTA_GATTC_CONN *p_conn = &bta_gattc_cb.conn_track[0];
791 for (i_conn = 0; i_conn < BTA_GATTC_CONN_MAX; i_conn++, p_conn ++) {
792 if (!p_conn->in_use) {
793 #if BTA_GATT_DEBUG == TRUE
794 APPL_TRACE_DEBUG("bta_gattc_conn_alloc: found conn_track[%d] available", i_conn);
796 p_conn->in_use = TRUE;
797 bdcpy(p_conn->remote_bda, remote_bda);
804 /*******************************************************************************
806 ** Function bta_gattc_conn_find
808 ** Description allocate connection tracking spot
810 ** Returns pointer to the clcb
812 *******************************************************************************/
813 tBTA_GATTC_CONN *bta_gattc_conn_find(BD_ADDR remote_bda)
816 tBTA_GATTC_CONN *p_conn = &bta_gattc_cb.conn_track[0];
818 for (i_conn = 0; i_conn < BTA_GATTC_CONN_MAX; i_conn++, p_conn ++) {
819 if (p_conn->in_use && bdcmp(remote_bda, p_conn->remote_bda) == 0) {
820 #if BTA_GATT_DEBUG == TRUE
821 APPL_TRACE_DEBUG("bta_gattc_conn_find: found conn_track[%d] matched", i_conn);
830 /*******************************************************************************
832 ** Function bta_gattc_conn_find_alloc
834 ** Description find or allocate connection tracking spot
836 ** Returns pointer to the clcb
838 *******************************************************************************/
839 tBTA_GATTC_CONN *bta_gattc_conn_find_alloc(BD_ADDR remote_bda)
841 tBTA_GATTC_CONN *p_conn = bta_gattc_conn_find (remote_bda);
843 if (p_conn == NULL) {
844 p_conn = bta_gattc_conn_alloc(remote_bda);
849 /*******************************************************************************
851 ** Function bta_gattc_conn_dealloc
853 ** Description de-allocate connection tracking spot
855 ** Returns pointer to the clcb
857 *******************************************************************************/
858 BOOLEAN bta_gattc_conn_dealloc(BD_ADDR remote_bda)
860 tBTA_GATTC_CONN *p_conn = bta_gattc_conn_find (remote_bda);
862 if (p_conn != NULL) {
863 p_conn->in_use = FALSE;
864 memset(p_conn->remote_bda, 0, BD_ADDR_LEN);
870 /*******************************************************************************
872 ** Function bta_gattc_find_int_conn_clcb
874 ** Description try to locate a clcb when an internal connecion event arrives.
876 ** Returns pointer to the clcb
878 *******************************************************************************/
879 tBTA_GATTC_CLCB *bta_gattc_find_int_conn_clcb(tBTA_GATTC_DATA *p_msg)
881 tBTA_GATTC_CLCB *p_clcb = NULL;
883 if (p_msg->int_conn.role == HCI_ROLE_SLAVE) {
884 bta_gattc_conn_find_alloc(p_msg->int_conn.remote_bda);
887 /* try to locate a logic channel */
888 if ((p_clcb = bta_gattc_find_clcb_by_cif(p_msg->int_conn.client_if,
889 p_msg->int_conn.remote_bda,
890 p_msg->int_conn.transport)) == NULL) {
891 /* for a background connection or listening connection */
892 if (/*p_msg->int_conn.role == HCI_ROLE_SLAVE || */
893 bta_gattc_check_bg_conn(p_msg->int_conn.client_if,
894 p_msg->int_conn.remote_bda,
895 p_msg->int_conn.role)) {
896 /* allocate a new channel */
897 p_clcb = bta_gattc_clcb_alloc(p_msg->int_conn.client_if,
898 p_msg->int_conn.remote_bda,
899 p_msg->int_conn.transport);
905 /*******************************************************************************
907 ** Function bta_gattc_find_int_disconn_clcb
909 ** Description try to locate a clcb when an internal disconnect callback arrives.
911 ** Returns pointer to the clcb
913 *******************************************************************************/
914 tBTA_GATTC_CLCB *bta_gattc_find_int_disconn_clcb(tBTA_GATTC_DATA *p_msg)
916 tBTA_GATTC_CLCB *p_clcb = NULL;
918 bta_gattc_conn_dealloc(p_msg->int_conn.remote_bda);
919 if ((p_clcb = bta_gattc_find_clcb_by_conn_id(p_msg->int_conn.hdr.layer_specific)) == NULL) {
920 /* connection attempt failed, send connection callback event */
921 p_clcb = bta_gattc_find_clcb_by_cif(p_msg->int_conn.client_if,
922 p_msg->int_conn.remote_bda,
923 p_msg->int_conn.transport);
925 if (p_clcb == NULL) {
926 APPL_TRACE_DEBUG(" disconnection ID: [%d] not used by BTA",
927 p_msg->int_conn.hdr.layer_specific);
932 void bta_to_btif_uuid(bt_uuid_t *p_dest, tBT_UUID *p_src)
936 if (p_src->len == LEN_UUID_16 || p_src->len == LEN_UUID_32)
938 for(i=0; i != 16; ++i)
939 p_dest->uu[i] = base_uuid[i];
948 p_dest->uu[12] = p_src->uu.uuid16 & 0xff;
949 p_dest->uu[13] = (p_src->uu.uuid16 >> 8) & 0xff;
953 p_dest->uu[12] = p_src->uu.uuid16 & 0xff;
954 p_dest->uu[13] = (p_src->uu.uuid16 >> 8) & 0xff;
955 p_dest->uu[14] = (p_src->uu.uuid32 >> 16) & 0xff;
956 p_dest->uu[15] = (p_src->uu.uuid32 >> 24) & 0xff;
960 for(i=0; i != 16; ++i)
961 p_dest->uu[i] = p_src->uu.uuid128[i];
965 LOG_ERROR("%s: Unknown UUID length %d!", __FUNCTION__, p_src->len);
971 #endif /* BTA_GATT_INCLUDED */