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