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