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 <bluetooth/log.h>
28
29 #include <cstdint>
30
31 #include "bta/gatt/bta_gattc_int.h"
32 #include "common/init_flags.h"
33 #include "hci/controller_interface.h"
34 #include "internal_include/bt_target.h"
35 #include "internal_include/bt_trace.h"
36 #include "main/shim/entry.h"
37 #include "os/log.h"
38 #include "osi/include/allocator.h"
39 #include "types/bt_transport.h"
40 #include "types/hci_role.h"
41 #include "types/raw_address.h"
42
43 using namespace bluetooth;
44
ble_acceptlist_size()45 static uint8_t ble_acceptlist_size() {
46 if (!bluetooth::shim::GetController()->SupportsBle()) {
47 return 0;
48 }
49 return bluetooth::shim::GetController()->GetLeFilterAcceptListSize();
50 }
51
52 /*******************************************************************************
53 *
54 * Function bta_gattc_cl_get_regcb
55 *
56 * Description get registration control block by client interface.
57 *
58 * Returns pointer to the regcb
59 *
60 ******************************************************************************/
bta_gattc_cl_get_regcb(uint8_t client_if)61 tBTA_GATTC_RCB* bta_gattc_cl_get_regcb(uint8_t client_if) {
62 uint8_t i = 0;
63 tBTA_GATTC_RCB* p_clrcb = &bta_gattc_cb.cl_rcb[0];
64
65 for (i = 0; i < BTA_GATTC_CL_MAX; i++, p_clrcb++) {
66 if (p_clrcb->in_use && p_clrcb->client_if == client_if) return p_clrcb;
67 }
68 return NULL;
69 }
70 /*******************************************************************************
71 *
72 * Function bta_gattc_num_reg_app
73 *
74 * Description find the number of registered application.
75 *
76 * Returns pointer to the regcb
77 *
78 ******************************************************************************/
bta_gattc_num_reg_app(void)79 uint8_t bta_gattc_num_reg_app(void) {
80 uint8_t i = 0, j = 0;
81
82 for (i = 0; i < BTA_GATTC_CL_MAX; i++) {
83 if (bta_gattc_cb.cl_rcb[i].in_use) j++;
84 }
85 return j;
86 }
87 /*******************************************************************************
88 *
89 * Function bta_gattc_find_clcb_by_cif
90 *
91 * Description get clcb by client interface and remote bd adddress
92 *
93 * Returns pointer to the clcb
94 *
95 ******************************************************************************/
bta_gattc_find_clcb_by_cif(uint8_t client_if,const RawAddress & remote_bda,tBT_TRANSPORT transport)96 tBTA_GATTC_CLCB* bta_gattc_find_clcb_by_cif(uint8_t client_if,
97 const RawAddress& remote_bda,
98 tBT_TRANSPORT transport) {
99 tBTA_GATTC_CLCB* p_clcb = &bta_gattc_cb.clcb[0];
100
101 for (size_t i = 0; i < BTA_GATTC_CLCB_MAX; i++, p_clcb++) {
102 if (p_clcb->in_use && p_clcb->p_rcb->client_if == client_if &&
103 p_clcb->transport == transport && p_clcb->bda == remote_bda)
104 return p_clcb;
105 }
106 return NULL;
107 }
108 /*******************************************************************************
109 *
110 * Function bta_gattc_find_clcb_by_conn_id
111 *
112 * Description get clcb by connection ID
113 *
114 * Returns pointer to the clcb
115 *
116 ******************************************************************************/
bta_gattc_find_clcb_by_conn_id(uint16_t conn_id)117 tBTA_GATTC_CLCB* bta_gattc_find_clcb_by_conn_id(uint16_t conn_id) {
118 tBTA_GATTC_CLCB* p_clcb = &bta_gattc_cb.clcb[0];
119
120 for (size_t i = 0; i < BTA_GATTC_CLCB_MAX; i++, p_clcb++) {
121 if (p_clcb->in_use && p_clcb->bta_conn_id == conn_id) return p_clcb;
122 }
123 return NULL;
124 }
125
126 /*******************************************************************************
127 *
128 * Function bta_gattc_clcb_alloc
129 *
130 * Description allocate CLCB
131 *
132 * Returns pointer to the clcb
133 *
134 ******************************************************************************/
bta_gattc_clcb_alloc(tGATT_IF client_if,const RawAddress & remote_bda,tBT_TRANSPORT transport)135 tBTA_GATTC_CLCB* bta_gattc_clcb_alloc(tGATT_IF client_if,
136 const RawAddress& remote_bda,
137 tBT_TRANSPORT transport) {
138 tBTA_GATTC_CLCB* p_clcb = NULL;
139
140 for (int i_clcb = 0; i_clcb < BTA_GATTC_CLCB_MAX; i_clcb++) {
141 if (!bta_gattc_cb.clcb[i_clcb].in_use) {
142 #if (BTA_GATT_DEBUG == TRUE)
143 log::verbose("found clcb:{} available", i_clcb);
144 #endif
145 p_clcb = &bta_gattc_cb.clcb[i_clcb];
146 p_clcb->in_use = true;
147 p_clcb->status = GATT_SUCCESS;
148 p_clcb->transport = transport;
149 p_clcb->bda = remote_bda;
150 p_clcb->p_q_cmd = NULL;
151
152 p_clcb->p_rcb = bta_gattc_cl_get_regcb(client_if);
153
154 p_clcb->p_srcb = bta_gattc_find_srcb(remote_bda);
155 if (p_clcb->p_srcb == NULL)
156 p_clcb->p_srcb = bta_gattc_srcb_alloc(remote_bda);
157
158 if (p_clcb->p_rcb != NULL && p_clcb->p_srcb != NULL) {
159 p_clcb->p_srcb->num_clcb++;
160 p_clcb->p_rcb->num_clcb++;
161 } else {
162 /* release this clcb if clcb or srcb allocation failed */
163 p_clcb->in_use = false;
164 p_clcb = NULL;
165 }
166 break;
167 }
168 }
169 return p_clcb;
170 }
171 /*******************************************************************************
172 *
173 * Function bta_gattc_find_alloc_clcb
174 *
175 * Description find or allocate CLCB if not found.
176 *
177 * Returns pointer to the clcb
178 *
179 ******************************************************************************/
bta_gattc_find_alloc_clcb(tGATT_IF client_if,const RawAddress & remote_bda,tBT_TRANSPORT transport)180 tBTA_GATTC_CLCB* bta_gattc_find_alloc_clcb(tGATT_IF client_if,
181 const RawAddress& remote_bda,
182 tBT_TRANSPORT transport) {
183 tBTA_GATTC_CLCB* p_clcb;
184
185 p_clcb = bta_gattc_find_clcb_by_cif(client_if, remote_bda, transport);
186 if (p_clcb == NULL) {
187 p_clcb = bta_gattc_clcb_alloc(client_if, remote_bda, transport);
188 }
189 return p_clcb;
190 }
191
192 /*******************************************************************************
193 *
194 * Function bta_gattc_server_disconnected
195 *
196 * Description Set server cache disconnected
197 *
198 * Returns pointer to the srcb
199 *
200 ******************************************************************************/
bta_gattc_server_disconnected(tBTA_GATTC_SERV * p_srcb)201 void bta_gattc_server_disconnected(tBTA_GATTC_SERV* p_srcb) {
202 if (p_srcb && p_srcb->connected) {
203 p_srcb->connected = false;
204 p_srcb->state = BTA_GATTC_SERV_IDLE;
205 p_srcb->mtu = 0;
206
207 // clear reallocating
208 p_srcb->gatt_database.Clear();
209 }
210 }
211
212 /*******************************************************************************
213 *
214 * Function bta_gattc_clcb_dealloc
215 *
216 * Description Deallocte a clcb
217 *
218 * Returns pointer to the clcb
219 *
220 ******************************************************************************/
bta_gattc_clcb_dealloc(tBTA_GATTC_CLCB * p_clcb)221 void bta_gattc_clcb_dealloc(tBTA_GATTC_CLCB* p_clcb) {
222 if (!p_clcb) {
223 log::error("p_clcb=NULL");
224 return;
225 }
226
227 tBTA_GATTC_SERV* p_srcb = p_clcb->p_srcb;
228 if (p_srcb->num_clcb) p_srcb->num_clcb--;
229
230 if (p_clcb->p_rcb->num_clcb) p_clcb->p_rcb->num_clcb--;
231
232 /* if the srcb is no longer needed, reset the state */
233 if (p_srcb->num_clcb == 0) {
234 p_srcb->connected = false;
235 p_srcb->state = BTA_GATTC_SERV_IDLE;
236 p_srcb->mtu = 0;
237
238 // clear reallocating
239 p_srcb->gatt_database.Clear();
240 }
241
242 while (!p_clcb->p_q_cmd_queue.empty()) {
243 auto p_q_cmd = p_clcb->p_q_cmd_queue.front();
244 p_clcb->p_q_cmd_queue.pop_front();
245 osi_free_and_reset((void**)&p_q_cmd);
246 }
247
248 if (p_clcb->p_q_cmd != NULL) {
249 osi_free_and_reset((void**)&p_clcb->p_q_cmd);
250 }
251
252 /* Clear p_clcb. Some of the fields are already reset e.g. p_q_cmd_queue and
253 * p_q_cmd. */
254 p_clcb->bta_conn_id = 0;
255 p_clcb->bda = {};
256 p_clcb->transport = 0;
257 p_clcb->p_rcb = NULL;
258 p_clcb->p_srcb = NULL;
259 p_clcb->request_during_discovery = 0;
260 p_clcb->auto_update = 0;
261 p_clcb->disc_active = 0;
262 p_clcb->in_use = 0;
263 p_clcb->state = BTA_GATTC_IDLE_ST;
264 p_clcb->status = GATT_SUCCESS;
265 }
266
267 /*******************************************************************************
268 *
269 * Function bta_gattc_find_srcb
270 *
271 * Description find server cache by remote bd address currently in use
272 *
273 * Returns pointer to the server cache.
274 *
275 ******************************************************************************/
bta_gattc_find_srcb(const RawAddress & bda)276 tBTA_GATTC_SERV* bta_gattc_find_srcb(const RawAddress& bda) {
277 tBTA_GATTC_SERV* p_srcb = &bta_gattc_cb.known_server[0];
278 uint8_t i;
279
280 for (i = 0; i < ble_acceptlist_size(); i++, p_srcb++) {
281 if (p_srcb->in_use && p_srcb->server_bda == bda) return p_srcb;
282 }
283 return NULL;
284 }
285
286 /*******************************************************************************
287 *
288 * Function bta_gattc_find_srvr_cache
289 *
290 * Description find server cache by remote bd address
291 *
292 * Returns pointer to the server cache.
293 *
294 ******************************************************************************/
bta_gattc_find_srvr_cache(const RawAddress & bda)295 tBTA_GATTC_SERV* bta_gattc_find_srvr_cache(const RawAddress& bda) {
296 tBTA_GATTC_SERV* p_srcb = &bta_gattc_cb.known_server[0];
297 uint8_t i;
298
299 for (i = 0; i < ble_acceptlist_size(); i++, p_srcb++) {
300 if (p_srcb->server_bda == bda) return p_srcb;
301 }
302 return NULL;
303 }
304 /*******************************************************************************
305 *
306 * Function bta_gattc_find_scb_by_cid
307 *
308 * Description find server control block by connection ID
309 *
310 * Returns pointer to the server cache.
311 *
312 ******************************************************************************/
bta_gattc_find_scb_by_cid(uint16_t conn_id)313 tBTA_GATTC_SERV* bta_gattc_find_scb_by_cid(uint16_t conn_id) {
314 tBTA_GATTC_CLCB* p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
315
316 if (p_clcb)
317 return p_clcb->p_srcb;
318 else
319 return NULL;
320 }
321 /*******************************************************************************
322 *
323 * Function bta_gattc_srcb_alloc
324 *
325 * Description allocate server cache control block
326 *
327 * Returns pointer to the server cache.
328 *
329 ******************************************************************************/
bta_gattc_srcb_alloc(const RawAddress & bda)330 tBTA_GATTC_SERV* bta_gattc_srcb_alloc(const RawAddress& bda) {
331 tBTA_GATTC_SERV *p_tcb = &bta_gattc_cb.known_server[0], *p_recycle = NULL;
332 bool found = false;
333 uint8_t i;
334
335 for (i = 0; i < ble_acceptlist_size(); i++, p_tcb++) {
336 if (!p_tcb->in_use) {
337 found = true;
338 break;
339 } else if (!p_tcb->connected) {
340 p_recycle = p_tcb;
341 }
342 }
343
344 /* if not found, try to recycle one known device */
345 if (!found && !p_recycle)
346 p_tcb = NULL;
347 else if (!found && p_recycle)
348 p_tcb = p_recycle;
349
350 if (p_tcb != NULL) {
351 // clear reallocating
352 p_tcb->gatt_database.Clear();
353 p_tcb->pending_discovery.Clear();
354 *p_tcb = tBTA_GATTC_SERV();
355
356 p_tcb->in_use = true;
357 p_tcb->server_bda = bda;
358 }
359 return p_tcb;
360 }
361
bta_gattc_send_mtu_response(tBTA_GATTC_CLCB * p_clcb,const tBTA_GATTC_DATA * p_data,uint16_t current_mtu)362 void bta_gattc_send_mtu_response(tBTA_GATTC_CLCB* p_clcb,
363 const tBTA_GATTC_DATA* p_data,
364 uint16_t current_mtu) {
365 GATT_CONFIGURE_MTU_OP_CB cb = p_data->api_mtu.mtu_cb;
366 if (cb) {
367 void* my_cb_data = p_data->api_mtu.mtu_cb_data;
368 cb(p_clcb->bta_conn_id, GATT_SUCCESS, my_cb_data);
369 }
370
371 tBTA_GATTC cb_data;
372 p_clcb->status = GATT_SUCCESS;
373 cb_data.cfg_mtu.conn_id = p_clcb->bta_conn_id;
374 cb_data.cfg_mtu.status = GATT_SUCCESS;
375
376 cb_data.cfg_mtu.mtu = current_mtu;
377
378 if (p_clcb->p_rcb) {
379 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CFG_MTU_EVT, &cb_data);
380 }
381 }
382
bta_gattc_continue(tBTA_GATTC_CLCB * p_clcb)383 void bta_gattc_continue(tBTA_GATTC_CLCB* p_clcb) {
384 if (p_clcb->p_q_cmd != NULL) {
385 log::info("Already scheduled another request for conn_id = 0x{:04x}",
386 p_clcb->bta_conn_id);
387 return;
388 }
389
390 while (!p_clcb->p_q_cmd_queue.empty()) {
391 const tBTA_GATTC_DATA* p_q_cmd = p_clcb->p_q_cmd_queue.front();
392 if (p_q_cmd->hdr.event != BTA_GATTC_API_CFG_MTU_EVT) {
393 p_clcb->p_q_cmd_queue.pop_front();
394 bta_gattc_sm_execute(p_clcb, p_q_cmd->hdr.event, p_q_cmd);
395 return;
396 }
397
398 /* The p_q_cmd is the MTU Request event. */
399 uint16_t current_mtu = 0;
400 auto result = GATTC_TryMtuRequest(p_clcb->bda, p_clcb->transport,
401 p_clcb->bta_conn_id, ¤t_mtu);
402 switch (result) {
403 case MTU_EXCHANGE_DEVICE_DISCONNECTED:
404 bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_CONFIG,
405 GATT_NO_RESOURCES, NULL);
406 /* Handled, free command below and continue with a p_q_cmd_queue */
407 break;
408 case MTU_EXCHANGE_NOT_ALLOWED:
409 bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_CONFIG,
410 GATT_ERR_UNLIKELY, NULL);
411 /* Handled, free command below and continue with a p_q_cmd_queue */
412 break;
413 case MTU_EXCHANGE_ALREADY_DONE:
414 bta_gattc_send_mtu_response(p_clcb, p_q_cmd, current_mtu);
415 /* Handled, free command below and continue with a p_q_cmd_queue */
416 break;
417 case MTU_EXCHANGE_IN_PROGRESS:
418 log::warn("Waiting p_clcb {}", fmt::ptr(p_clcb));
419 return;
420 case MTU_EXCHANGE_NOT_DONE_YET:
421 p_clcb->p_q_cmd_queue.pop_front();
422 bta_gattc_sm_execute(p_clcb, p_q_cmd->hdr.event, p_q_cmd);
423 return;
424 }
425
426 /* p_q_cmd was the MTU request and it was handled.
427 * If MTU request was handled without actually ATT request,
428 * it is ok to take another message from the queue and proceed.
429 */
430 p_clcb->p_q_cmd_queue.pop_front();
431 osi_free_and_reset((void**)&p_q_cmd);
432 }
433 }
434
bta_gattc_is_data_queued(tBTA_GATTC_CLCB * p_clcb,const tBTA_GATTC_DATA * p_data)435 bool bta_gattc_is_data_queued(tBTA_GATTC_CLCB* p_clcb,
436 const tBTA_GATTC_DATA* p_data) {
437 if (p_clcb->p_q_cmd == p_data) {
438 return true;
439 }
440
441 auto it = std::find(p_clcb->p_q_cmd_queue.begin(),
442 p_clcb->p_q_cmd_queue.end(), p_data);
443 return it != p_clcb->p_q_cmd_queue.end();
444 }
445 /*******************************************************************************
446 *
447 * Function bta_gattc_enqueue
448 *
449 * Description enqueue a client request in clcb.
450 *
451 * Returns BtaEnqueuedResult_t
452 *
453 ******************************************************************************/
bta_gattc_enqueue(tBTA_GATTC_CLCB * p_clcb,const tBTA_GATTC_DATA * p_data)454 BtaEnqueuedResult_t bta_gattc_enqueue(tBTA_GATTC_CLCB* p_clcb,
455 const tBTA_GATTC_DATA* p_data) {
456 if (p_clcb->p_q_cmd == NULL) {
457 p_clcb->p_q_cmd = p_data;
458 return ENQUEUED_READY_TO_SEND;
459 }
460
461 log::info(
462 "Already has a pending command to executer. Queuing for later {} conn "
463 "id=0x{:04x}",
464 p_clcb->bda, p_clcb->bta_conn_id);
465 p_clcb->p_q_cmd_queue.push_back(p_data);
466
467 return ENQUEUED_FOR_LATER;
468 }
469
470 /*******************************************************************************
471 *
472 * Function bta_gattc_check_notif_registry
473 *
474 * Description check if the service notificaition has been registered.
475 *
476 * Returns
477 *
478 ******************************************************************************/
bta_gattc_check_notif_registry(tBTA_GATTC_RCB * p_clreg,tBTA_GATTC_SERV * p_srcb,tBTA_GATTC_NOTIFY * p_notify)479 bool bta_gattc_check_notif_registry(tBTA_GATTC_RCB* p_clreg,
480 tBTA_GATTC_SERV* p_srcb,
481 tBTA_GATTC_NOTIFY* p_notify) {
482 uint8_t i;
483
484 for (i = 0; i < BTA_GATTC_NOTIF_REG_MAX; i++) {
485 if (p_clreg->notif_reg[i].in_use &&
486 p_clreg->notif_reg[i].remote_bda == p_srcb->server_bda &&
487 p_clreg->notif_reg[i].handle == p_notify->handle &&
488 !p_clreg->notif_reg[i].app_disconnected) {
489 log::verbose("Notification registered!");
490 return true;
491 }
492 }
493 return false;
494 }
495 /*******************************************************************************
496 *
497 * Function bta_gattc_clear_notif_registration
498 *
499 * Description Clear up the notification registration information by
500 * RawAddress.
501 * Where handle is between start_handle and end_handle, and
502 * start_handle and end_handle are boundaries of service
503 * containing characteristic.
504 *
505 * Returns None.
506 *
507 ******************************************************************************/
bta_gattc_clear_notif_registration(tBTA_GATTC_SERV * p_srcb,uint16_t conn_id,uint16_t start_handle,uint16_t end_handle)508 void bta_gattc_clear_notif_registration(tBTA_GATTC_SERV* p_srcb,
509 uint16_t conn_id, uint16_t start_handle,
510 uint16_t end_handle) {
511 RawAddress remote_bda;
512 tGATT_IF gatt_if;
513 tBTA_GATTC_RCB* p_clrcb;
514 uint8_t i;
515 tBT_TRANSPORT transport;
516 uint16_t handle;
517
518 if (GATT_GetConnectionInfor(conn_id, &gatt_if, remote_bda, &transport)) {
519 p_clrcb = bta_gattc_cl_get_regcb(gatt_if);
520 if (p_clrcb != NULL) {
521 for (i = 0; i < BTA_GATTC_NOTIF_REG_MAX; i++) {
522 if (p_clrcb->notif_reg[i].in_use &&
523 p_clrcb->notif_reg[i].remote_bda == remote_bda) {
524 /* It's enough to get service or characteristic handle, as
525 * clear boundaries are always around service.
526 */
527 handle = p_clrcb->notif_reg[i].handle;
528 if (handle >= start_handle && handle <= end_handle)
529 memset(&p_clrcb->notif_reg[i], 0, sizeof(tBTA_GATTC_NOTIF_REG));
530 }
531 }
532 }
533 } else {
534 log::error("can not clear indication/notif registration for unknown app");
535 }
536 return;
537 }
538
539 /*******************************************************************************
540 *
541 * Function bta_gattc_mark_bg_conn
542 *
543 * Description mark background connection status when a bg connection is
544 * initiated or terminated.
545 *
546 * Returns true if success; false otherwise.
547 *
548 ******************************************************************************/
bta_gattc_mark_bg_conn(tGATT_IF client_if,const RawAddress & remote_bda_ptr,bool add)549 bool bta_gattc_mark_bg_conn(tGATT_IF client_if,
550 const RawAddress& remote_bda_ptr, bool add) {
551 tBTA_GATTC_BG_TCK* p_bg_tck = &bta_gattc_cb.bg_track[0];
552 uint8_t i = 0;
553 tBTA_GATTC_CIF_MASK* p_cif_mask;
554
555 for (i = 0; i < ble_acceptlist_size(); i++, p_bg_tck++) {
556 if (p_bg_tck->in_use && ((p_bg_tck->remote_bda == remote_bda_ptr) ||
557 (p_bg_tck->remote_bda.IsEmpty()))) {
558 p_cif_mask = &p_bg_tck->cif_mask;
559
560 if (add) /* mask on the cif bit */
561 *p_cif_mask |= (1 << (client_if - 1));
562 else {
563 if (client_if != 0)
564 *p_cif_mask &= (~(1 << (client_if - 1)));
565 else
566 *p_cif_mask = 0;
567 }
568 /* no BG connection for this device, make it available */
569 if (p_bg_tck->cif_mask == 0) {
570 memset(p_bg_tck, 0, sizeof(tBTA_GATTC_BG_TCK));
571 }
572 return true;
573 }
574 }
575 if (!add) {
576 log::error("unable to find the bg connection mask for bd_addr={}",
577 remote_bda_ptr);
578 return false;
579 } else /* adding a new device mask */
580 {
581 for (i = 0, p_bg_tck = &bta_gattc_cb.bg_track[0]; i < ble_acceptlist_size();
582 i++, p_bg_tck++) {
583 if (!p_bg_tck->in_use) {
584 p_bg_tck->in_use = true;
585 p_bg_tck->remote_bda = remote_bda_ptr;
586
587 p_cif_mask = &p_bg_tck->cif_mask;
588
589 *p_cif_mask = ((tBTA_GATTC_CIF_MASK)1 << (client_if - 1));
590 return true;
591 }
592 }
593 log::error("no available space to mark the bg connection status");
594 return false;
595 }
596 }
597 /*******************************************************************************
598 *
599 * Function bta_gattc_check_bg_conn
600 *
601 * Description check if this is a background connection background
602 * connection.
603 *
604 * Returns true if success; false otherwise.
605 *
606 ******************************************************************************/
bta_gattc_check_bg_conn(tGATT_IF client_if,const RawAddress & remote_bda,uint8_t role)607 bool bta_gattc_check_bg_conn(tGATT_IF client_if, const RawAddress& remote_bda,
608 uint8_t role) {
609 tBTA_GATTC_BG_TCK* p_bg_tck = &bta_gattc_cb.bg_track[0];
610 uint8_t i = 0;
611 bool is_bg_conn = false;
612
613 for (i = 0; i < ble_acceptlist_size() && !is_bg_conn; i++, p_bg_tck++) {
614 if (p_bg_tck->in_use && (p_bg_tck->remote_bda == remote_bda ||
615 p_bg_tck->remote_bda.IsEmpty())) {
616 if (((p_bg_tck->cif_mask & ((tBTA_GATTC_CIF_MASK)1 << (client_if - 1))) != 0) &&
617 role == HCI_ROLE_CENTRAL)
618 is_bg_conn = true;
619 }
620 }
621 return is_bg_conn;
622 }
623 /*******************************************************************************
624 *
625 * Function bta_gattc_send_open_cback
626 *
627 * Description send open callback
628 *
629 * Returns
630 *
631 ******************************************************************************/
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)632 void bta_gattc_send_open_cback(tBTA_GATTC_RCB* p_clreg, tGATT_STATUS status,
633 const RawAddress& remote_bda, uint16_t conn_id,
634 tBT_TRANSPORT transport, uint16_t mtu) {
635 tBTA_GATTC cb_data;
636
637 if (p_clreg->p_cback) {
638 memset(&cb_data, 0, sizeof(tBTA_GATTC));
639
640 cb_data.open.status = status;
641 cb_data.open.client_if = p_clreg->client_if;
642 cb_data.open.conn_id = conn_id;
643 cb_data.open.mtu = mtu;
644 cb_data.open.transport = transport;
645 cb_data.open.remote_bda = remote_bda;
646
647 (*p_clreg->p_cback)(BTA_GATTC_OPEN_EVT, &cb_data);
648 }
649 }
650 /*******************************************************************************
651 *
652 * Function bta_gattc_conn_alloc
653 *
654 * Description allocate connection tracking spot
655 *
656 * Returns pointer to the clcb
657 *
658 ******************************************************************************/
bta_gattc_conn_alloc(const RawAddress & remote_bda)659 tBTA_GATTC_CONN* bta_gattc_conn_alloc(const RawAddress& remote_bda) {
660 uint8_t i_conn = 0;
661 tBTA_GATTC_CONN* p_conn = &bta_gattc_cb.conn_track[0];
662
663 for (i_conn = 0; i_conn < GATT_MAX_PHY_CHANNEL; i_conn++, p_conn++) {
664 if (!p_conn->in_use) {
665 #if (BTA_GATT_DEBUG == TRUE)
666 log::verbose("found conn_track:{} available", i_conn);
667 #endif
668 p_conn->in_use = true;
669 p_conn->remote_bda = remote_bda;
670 return p_conn;
671 }
672 }
673 return NULL;
674 }
675
676 /*******************************************************************************
677 *
678 * Function bta_gattc_conn_find
679 *
680 * Description allocate connection tracking spot
681 *
682 * Returns pointer to the clcb
683 *
684 ******************************************************************************/
bta_gattc_conn_find(const RawAddress & remote_bda)685 tBTA_GATTC_CONN* bta_gattc_conn_find(const RawAddress& remote_bda) {
686 uint8_t i_conn = 0;
687 tBTA_GATTC_CONN* p_conn = &bta_gattc_cb.conn_track[0];
688
689 for (i_conn = 0; i_conn < GATT_MAX_PHY_CHANNEL; i_conn++, p_conn++) {
690 if (p_conn->in_use && remote_bda == p_conn->remote_bda) {
691 #if (BTA_GATT_DEBUG == TRUE)
692 log::verbose("found conn_track:{} matched", i_conn);
693 #endif
694 return p_conn;
695 }
696 }
697 return NULL;
698 }
699
700 /*******************************************************************************
701 *
702 * Function bta_gattc_conn_find_alloc
703 *
704 * Description find or allocate connection tracking spot
705 *
706 * Returns pointer to the clcb
707 *
708 ******************************************************************************/
bta_gattc_conn_find_alloc(const RawAddress & remote_bda)709 tBTA_GATTC_CONN* bta_gattc_conn_find_alloc(const RawAddress& remote_bda) {
710 tBTA_GATTC_CONN* p_conn = bta_gattc_conn_find(remote_bda);
711
712 if (p_conn == NULL) {
713 p_conn = bta_gattc_conn_alloc(remote_bda);
714 }
715 return p_conn;
716 }
717
718 /*******************************************************************************
719 *
720 * Function bta_gattc_conn_dealloc
721 *
722 * Description de-allocate connection tracking spot
723 *
724 * Returns pointer to the clcb
725 *
726 ******************************************************************************/
bta_gattc_conn_dealloc(const RawAddress & remote_bda)727 bool bta_gattc_conn_dealloc(const RawAddress& remote_bda) {
728 tBTA_GATTC_CONN* p_conn = bta_gattc_conn_find(remote_bda);
729
730 if (p_conn != NULL) {
731 p_conn->in_use = false;
732 p_conn->remote_bda = RawAddress::kEmpty;
733 return true;
734 }
735 return false;
736 }
737
738 /*******************************************************************************
739 *
740 * Function bta_gattc_find_int_conn_clcb
741 *
742 * Description try to locate a clcb when an internal connecion event
743 * arrives.
744 *
745 * Returns pointer to the clcb
746 *
747 ******************************************************************************/
bta_gattc_find_int_conn_clcb(tBTA_GATTC_DATA * p_msg)748 tBTA_GATTC_CLCB* bta_gattc_find_int_conn_clcb(tBTA_GATTC_DATA* p_msg) {
749 tBTA_GATTC_CLCB* p_clcb = NULL;
750
751 if (p_msg->int_conn.role == HCI_ROLE_PERIPHERAL)
752 bta_gattc_conn_find_alloc(p_msg->int_conn.remote_bda);
753
754 /* try to locate a logic channel */
755 p_clcb = bta_gattc_find_clcb_by_cif(p_msg->int_conn.client_if,
756 p_msg->int_conn.remote_bda,
757 p_msg->int_conn.transport);
758 if (p_clcb == NULL) {
759 /* for a background connection or listening connection */
760 if (/*p_msg->int_conn.role == HCI_ROLE_PERIPHERAL || */
761 bta_gattc_check_bg_conn(p_msg->int_conn.client_if,
762 p_msg->int_conn.remote_bda,
763 p_msg->int_conn.role)) {
764 /* allocate a new channel */
765 p_clcb = bta_gattc_clcb_alloc(p_msg->int_conn.client_if,
766 p_msg->int_conn.remote_bda,
767 p_msg->int_conn.transport);
768 }
769 }
770 return p_clcb;
771 }
772
773 /*******************************************************************************
774 *
775 * Function bta_gattc_find_int_disconn_clcb
776 *
777 * Description try to locate a clcb when an internal disconnect callback
778 * arrives.
779 *
780 * Returns pointer to the clcb
781 *
782 ******************************************************************************/
bta_gattc_find_int_disconn_clcb(tBTA_GATTC_DATA * p_msg)783 tBTA_GATTC_CLCB* bta_gattc_find_int_disconn_clcb(tBTA_GATTC_DATA* p_msg) {
784 tBTA_GATTC_CLCB* p_clcb = NULL;
785
786 bta_gattc_conn_dealloc(p_msg->int_conn.remote_bda);
787 p_clcb = bta_gattc_find_clcb_by_conn_id(p_msg->int_conn.hdr.layer_specific);
788 if (p_clcb == NULL) {
789 /* connection attempt failed, send connection callback event */
790 p_clcb = bta_gattc_find_clcb_by_cif(p_msg->int_conn.client_if,
791 p_msg->int_conn.remote_bda,
792 p_msg->int_conn.transport);
793 }
794 if (p_clcb == NULL) {
795 log::verbose("disconnection ID:{} not used by BTA",
796 p_msg->int_conn.hdr.layer_specific);
797 }
798 return p_clcb;
799 }
800
bta_gatt_client_dump(int fd)801 void bta_gatt_client_dump(int fd) {
802 std::stringstream stream;
803 int entry_count = 0;
804
805 stream << " ->conn_track (GATT_MAX_PHY_CHANNEL=" << GATT_MAX_PHY_CHANNEL
806 << ")\n";
807 for (int i = 0; i < GATT_MAX_PHY_CHANNEL; i++) {
808 tBTA_GATTC_CONN* p_conn_track = &bta_gattc_cb.conn_track[i];
809 if (p_conn_track->in_use) {
810 entry_count++;
811 stream << " address: "
812 << ADDRESS_TO_LOGGABLE_STR(p_conn_track->remote_bda);
813 stream << "\n";
814 }
815 }
816 stream << " -- used: " << entry_count << "\n";
817 entry_count = 0;
818
819 stream << " ->bg_track (BTA_GATTC_KNOWN_SR_MAX=" << BTA_GATTC_KNOWN_SR_MAX
820 << ")\n";
821 for (int i = 0; i < BTA_GATTC_KNOWN_SR_MAX; i++) {
822 tBTA_GATTC_BG_TCK* p_bg_track = &bta_gattc_cb.bg_track[i];
823 if (!p_bg_track->in_use) {
824 continue;
825 }
826 entry_count++;
827 stream << " address: " << ADDRESS_TO_LOGGABLE_STR(p_bg_track->remote_bda)
828 << " cif_mask: " << loghex(p_bg_track->cif_mask);
829 stream << "\n";
830 }
831
832 stream << " -- used: " << entry_count << "\n";
833 entry_count = 0;
834 stream << " ->cl_rcb (BTA_GATTC_CL_MAX=" << BTA_GATTC_CL_MAX << ")\n";
835 for (int i = 0; i < BTA_GATTC_CL_MAX; i++) {
836 tBTA_GATTC_RCB* p_cl_rcb = &bta_gattc_cb.cl_rcb[i];
837 if (!p_cl_rcb->in_use) {
838 continue;
839 }
840 entry_count++;
841 stream << " client_if: " << +p_cl_rcb->client_if
842 << " app uuids: " << p_cl_rcb->app_uuid
843 << " clcb_num: " << +p_cl_rcb->num_clcb;
844 stream << "\n";
845 }
846
847 stream << " -- used: " << entry_count << "\n";
848 entry_count = 0;
849 stream << " ->clcb (BTA_GATTC_CLCB_MAX=" << BTA_GATTC_CLCB_MAX << ")\n";
850 for (size_t i = 0; i < BTA_GATTC_CLCB_MAX; i++) {
851 tBTA_GATTC_CLCB* p_clcb = &bta_gattc_cb.clcb[i];
852 if (!p_clcb->in_use) {
853 continue;
854 }
855 entry_count++;
856 stream << " conn_id: " << loghex(p_clcb->bta_conn_id)
857 << " address: " << ADDRESS_TO_LOGGABLE_STR(p_clcb->bda)
858 << " transport: " << bt_transport_text(p_clcb->transport)
859 << " state: " << bta_clcb_state_text(p_clcb->state);
860 stream << "\n";
861 }
862
863 stream << " -- used: " << entry_count << "\n";
864 entry_count = 0;
865 stream << " ->known_server (BTA_GATTC_KNOWN_SR_MAX=" << BTA_GATTC_KNOWN_SR_MAX
866 << ")\n";
867 for (int i = 0; i < BTA_GATTC_CL_MAX; i++) {
868 tBTA_GATTC_SERV* p_known_server = &bta_gattc_cb.known_server[i];
869 if (!p_known_server->in_use) {
870 continue;
871 }
872 entry_count++;
873 stream << " server_address: "
874 << ADDRESS_TO_LOGGABLE_STR(p_known_server->server_bda)
875 << " mtu: " << p_known_server->mtu
876 << " blocked_conn_id: " << loghex(p_known_server->blocked_conn_id)
877 << " pending_discovery: "
878 << p_known_server->pending_discovery.ToString()
879 << " num_clcb: " << +p_known_server->num_clcb
880 << " state: " << bta_server_state_text(p_known_server->state)
881 << " connected: " << p_known_server->connected
882 << " srvc_disc_count: " << p_known_server->srvc_disc_count
883 << " disc_blocked_waiting_on_version: "
884 << p_known_server->disc_blocked_waiting_on_version
885 << " srvc_hdl_chg: " << +p_known_server->srvc_hdl_chg
886 << " srvc_hdl_db_hash: " << p_known_server->srvc_hdl_db_hash
887 << " update_count: " << +p_known_server->update_count;
888
889 stream << "\n";
890 }
891
892 stream << " -- used: " << entry_count << "\n";
893 entry_count = 0;
894 dprintf(fd, "BTA_GATTC_CB state %s \n%s\n",
895 bta_gattc_state_text(bta_gattc_cb.state).c_str(),
896 stream.str().c_str());
897 }
898