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