• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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