1 /******************************************************************************
2 *
3 * Copyright 2009-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 GATT utility functions
22 *
23 ******************************************************************************/
24 #define LOG_TAG "gatt_utils"
25
26 #include <base/logging.h>
27 #include <base/strings/stringprintf.h>
28
29 #include <cstdint>
30 #include <deque>
31
32 #include "bt_target.h" // Must be first to define build configuration
33 #include "osi/include/allocator.h"
34 #include "osi/include/log.h"
35 #include "rust/src/connection/ffi/connection_shim.h"
36 #include "stack/btm/btm_sec.h"
37 #include "stack/eatt/eatt.h"
38 #include "stack/gatt/connection_manager.h"
39 #include "stack/gatt/gatt_int.h"
40 #include "stack/include/acl_api.h"
41 #include "stack/include/bt_hdr.h"
42 #include "stack/include/l2cdefs.h"
43 #include "stack/include/sdp_api.h"
44 #include "types/bluetooth/uuid.h"
45 #include "types/raw_address.h"
46
47 uint8_t btm_ble_read_sec_key_size(const RawAddress& bd_addr);
48
49 using base::StringPrintf;
50 using bluetooth::Uuid;
51 using bluetooth::eatt::EattExtension;
52 using bluetooth::eatt::EattChannel;
53
54 /* check if [x, y] and [a, b] have overlapping range */
55 #define GATT_VALIDATE_HANDLE_RANGE(x, y, a, b) ((y) >= (a) && (x) <= (b))
56
57 #define GATT_GET_NEXT_VALID_HANDLE(x) (((x) / 10 + 1) * 10)
58
59 const char* const op_code_name[] = {"UNKNOWN",
60 "ATT_RSP_ERROR",
61 "ATT_REQ_MTU",
62 "ATT_RSP_MTU",
63 "ATT_REQ_READ_INFO",
64 "ATT_RSP_READ_INFO",
65 "ATT_REQ_FIND_TYPE_VALUE",
66 "ATT_RSP_FIND_TYPE_VALUE",
67 "ATT_REQ_READ_BY_TYPE",
68 "ATT_RSP_READ_BY_TYPE",
69 "ATT_REQ_READ",
70 "ATT_RSP_READ",
71 "ATT_REQ_READ_BLOB",
72 "ATT_RSP_READ_BLOB",
73 "GATT_REQ_READ_MULTI",
74 "GATT_RSP_READ_MULTI",
75 "GATT_REQ_READ_BY_GRP_TYPE",
76 "GATT_RSP_READ_BY_GRP_TYPE",
77 "ATT_REQ_WRITE",
78 "ATT_RSP_WRITE",
79 "ATT_CMD_WRITE",
80 "ATT_SIGN_CMD_WRITE",
81 "ATT_REQ_PREPARE_WRITE",
82 "ATT_RSP_PREPARE_WRITE",
83 "ATT_REQ_EXEC_WRITE",
84 "ATT_RSP_EXEC_WRITE",
85 "Reserved",
86 "ATT_HANDLE_VALUE_NOTIF",
87 "Reserved",
88 "ATT_HANDLE_VALUE_IND",
89 "ATT_HANDLE_VALUE_CONF",
90 "ATT_OP_CODE_MAX"};
91
92 /*******************************************************************************
93 *
94 * Function gatt_free_pending_ind
95 *
96 * Description Free all pending indications
97 *
98 * Returns None
99 *
100 ******************************************************************************/
gatt_free_pending_ind(tGATT_TCB * p_tcb)101 void gatt_free_pending_ind(tGATT_TCB* p_tcb) {
102 VLOG(1) << __func__;
103
104 if (p_tcb->pending_ind_q == NULL) return;
105
106 /* release all queued indications */
107 while (!fixed_queue_is_empty(p_tcb->pending_ind_q))
108 osi_free(fixed_queue_try_dequeue(p_tcb->pending_ind_q));
109 fixed_queue_free(p_tcb->pending_ind_q, NULL);
110 p_tcb->pending_ind_q = NULL;
111 }
112
113 /*******************************************************************************
114 *
115 * Function gatt_delete_dev_from_srv_chg_clt_list
116 *
117 * Description Delete a device from the service changed client lit
118 *
119 * Returns None
120 *
121 ******************************************************************************/
gatt_delete_dev_from_srv_chg_clt_list(const RawAddress & bd_addr)122 void gatt_delete_dev_from_srv_chg_clt_list(const RawAddress& bd_addr) {
123 VLOG(1) << __func__;
124
125 tGATTS_SRV_CHG* p_buf = gatt_is_bda_in_the_srv_chg_clt_list(bd_addr);
126 if (p_buf != NULL) {
127 if (gatt_cb.cb_info.p_srv_chg_callback) {
128 /* delete from NV */
129 tGATTS_SRV_CHG_REQ req;
130 req.srv_chg.bda = bd_addr;
131 (*gatt_cb.cb_info.p_srv_chg_callback)(GATTS_SRV_CHG_CMD_REMOVE_CLIENT,
132 &req, NULL);
133 }
134 osi_free(fixed_queue_try_remove_from_queue(gatt_cb.srv_chg_clt_q, p_buf));
135 }
136 }
137
138 /*******************************************************************************
139 *
140 * Function gatt_set_srv_chg
141 *
142 * Description Set the service changed flag to true
143 *
144 * Returns None
145 *
146 ******************************************************************************/
gatt_set_srv_chg(void)147 void gatt_set_srv_chg(void) {
148 VLOG(1) << __func__;
149
150 if (fixed_queue_is_empty(gatt_cb.srv_chg_clt_q)) return;
151
152 list_t* list = fixed_queue_get_list(gatt_cb.srv_chg_clt_q);
153 for (const list_node_t* node = list_begin(list); node != list_end(list);
154 node = list_next(node)) {
155 VLOG(1) << "found a srv_chg clt";
156
157 tGATTS_SRV_CHG* p_buf = (tGATTS_SRV_CHG*)list_node(node);
158 if (!p_buf->srv_changed) {
159 VLOG(1) << "set srv_changed to true";
160 p_buf->srv_changed = true;
161 tGATTS_SRV_CHG_REQ req;
162 memcpy(&req.srv_chg, p_buf, sizeof(tGATTS_SRV_CHG));
163 if (gatt_cb.cb_info.p_srv_chg_callback)
164 (*gatt_cb.cb_info.p_srv_chg_callback)(GATTS_SRV_CHG_CMD_UPDATE_CLIENT,
165 &req, NULL);
166 }
167 }
168 }
169
170 /** Add a pending indication */
gatt_add_pending_ind(tGATT_TCB * p_tcb,tGATT_VALUE * p_ind)171 void gatt_add_pending_ind(tGATT_TCB* p_tcb, tGATT_VALUE* p_ind) {
172 VLOG(1) << __func__ << "enqueue a pending indication";
173
174 tGATT_VALUE* p_buf = (tGATT_VALUE*)osi_malloc(sizeof(tGATT_VALUE));
175 memcpy(p_buf, p_ind, sizeof(tGATT_VALUE));
176 fixed_queue_enqueue(p_tcb->pending_ind_q, p_buf);
177 }
178
179 /*******************************************************************************
180 *
181 * Function gatt_add_srv_chg_clt
182 *
183 * Description Add a service chnage client to the service change client queue
184 *
185 * Returns Pointer to the service change client buffer; Null no buffer
186 * available
187 *
188 ******************************************************************************/
gatt_add_srv_chg_clt(tGATTS_SRV_CHG * p_srv_chg)189 tGATTS_SRV_CHG* gatt_add_srv_chg_clt(tGATTS_SRV_CHG* p_srv_chg) {
190 tGATTS_SRV_CHG* p_buf = (tGATTS_SRV_CHG*)osi_malloc(sizeof(tGATTS_SRV_CHG));
191 VLOG(1) << __func__ << "enqueue a srv chg client";
192
193 memcpy(p_buf, p_srv_chg, sizeof(tGATTS_SRV_CHG));
194 fixed_queue_enqueue(gatt_cb.srv_chg_clt_q, p_buf);
195
196 return p_buf;
197 }
198
199 /**
200 * Returns pointer to the handle range buffer starting at handle |handle|,
201 * nullptr
202 * if no buffer available
203 */
gatt_find_hdl_buffer_by_handle(uint16_t handle)204 tGATT_HDL_LIST_ELEM* gatt_find_hdl_buffer_by_handle(uint16_t handle) {
205 for (auto& elem : *gatt_cb.hdl_list_info) {
206 if (elem.asgn_range.s_handle == handle) return &elem;
207 }
208
209 return nullptr;
210 }
211 /*******************************************************************************
212 *
213 * Description Find handle range buffer by app ID, service and service instance
214 * ID.
215 *
216 * Returns Pointer to the buffer, NULL no buffer available
217 *
218 ******************************************************************************/
gatt_find_hdl_buffer_by_app_id(const Uuid & app_uuid128,Uuid * p_svc_uuid,uint16_t start_handle)219 std::list<tGATT_HDL_LIST_ELEM>::iterator gatt_find_hdl_buffer_by_app_id(
220 const Uuid& app_uuid128, Uuid* p_svc_uuid, uint16_t start_handle) {
221 auto end_it = gatt_cb.hdl_list_info->end();
222 auto it = gatt_cb.hdl_list_info->begin();
223 for (; it != end_it; it++) {
224 if (app_uuid128 == it->asgn_range.app_uuid128 &&
225 *p_svc_uuid == it->asgn_range.svc_uuid &&
226 (start_handle == it->asgn_range.s_handle)) {
227 return it;
228 }
229 }
230
231 return it;
232 }
233
234 /**
235 * free the service attribute database buffers by the owner of the service app
236 * ID.
237 */
gatt_free_srvc_db_buffer_app_id(const Uuid & app_id)238 void gatt_free_srvc_db_buffer_app_id(const Uuid& app_id) {
239 auto it = gatt_cb.hdl_list_info->begin();
240 auto end = gatt_cb.hdl_list_info->end();
241 while (it != end) {
242 if (app_id == it->asgn_range.app_uuid128) {
243 it = gatt_cb.hdl_list_info->erase(it);
244 } else {
245 it++;
246 }
247 }
248 }
249
250 /*******************************************************************************
251 *
252 * Function gatt_find_the_connected_bda
253 *
254 * Description This function find the connected bda
255 *
256 * Returns true if found
257 *
258 ******************************************************************************/
gatt_find_the_connected_bda(uint8_t start_idx,RawAddress & bda,uint8_t * p_found_idx,tBT_TRANSPORT * p_transport)259 bool gatt_find_the_connected_bda(uint8_t start_idx, RawAddress& bda,
260 uint8_t* p_found_idx,
261 tBT_TRANSPORT* p_transport) {
262 uint8_t i;
263 bool found = false;
264 LOG_DEBUG("start_idx=%d", +start_idx);
265
266 for (i = start_idx; i < GATT_MAX_PHY_CHANNEL; i++) {
267 if (gatt_cb.tcb[i].in_use && gatt_cb.tcb[i].ch_state == GATT_CH_OPEN) {
268 bda = gatt_cb.tcb[i].peer_bda;
269 *p_found_idx = i;
270 *p_transport = gatt_cb.tcb[i].transport;
271 found = true;
272 LOG_DEBUG("bda: %s", ADDRESS_TO_LOGGABLE_CSTR(bda));
273 break;
274 }
275 }
276 LOG_DEBUG("found=%d found_idx=%d", found, +i);
277 return found;
278 }
279
280 /*******************************************************************************
281 *
282 * Function gatt_is_srv_chg_ind_pending
283 *
284 * Description Check whether a service chnaged is in the indication pending
285 * queue or waiting for an Ack already
286 *
287 * Returns bool
288 *
289 ******************************************************************************/
gatt_is_srv_chg_ind_pending(tGATT_TCB * p_tcb)290 bool gatt_is_srv_chg_ind_pending(tGATT_TCB* p_tcb) {
291 VLOG(1) << __func__
292 << " is_queue_empty=" << fixed_queue_is_empty(p_tcb->pending_ind_q);
293
294 if (p_tcb->indicate_handle == gatt_cb.handle_of_h_r) return true;
295
296 if (p_tcb->eatt && EattExtension::GetInstance()->IsIndicationPending(
297 p_tcb->peer_bda, gatt_cb.handle_of_h_r))
298 return true;
299
300 if (fixed_queue_is_empty(p_tcb->pending_ind_q)) return false;
301
302 list_t* list = fixed_queue_get_list(p_tcb->pending_ind_q);
303 for (const list_node_t* node = list_begin(list); node != list_end(list);
304 node = list_next(node)) {
305 tGATT_VALUE* p_buf = (tGATT_VALUE*)list_node(node);
306 if (p_buf->handle == gatt_cb.handle_of_h_r) {
307 return true;
308 }
309 }
310
311 return false;
312 }
313
314 /*******************************************************************************
315 *
316 * Function gatt_is_bda_in_the_srv_chg_clt_list
317 *
318 * Description This function check the specified bda is in the srv chg
319 * client list or not
320 *
321 * Returns pointer to the found elemenet otherwise NULL
322 *
323 ******************************************************************************/
gatt_is_bda_in_the_srv_chg_clt_list(const RawAddress & bda)324 tGATTS_SRV_CHG* gatt_is_bda_in_the_srv_chg_clt_list(const RawAddress& bda) {
325
326 VLOG(1) << __func__ << ": " << bda;
327
328 if (fixed_queue_is_empty(gatt_cb.srv_chg_clt_q)) return NULL;
329
330 list_t* list = fixed_queue_get_list(gatt_cb.srv_chg_clt_q);
331 for (const list_node_t* node = list_begin(list); node != list_end(list);
332 node = list_next(node)) {
333 tGATTS_SRV_CHG* p_buf = (tGATTS_SRV_CHG*)list_node(node);
334 if (bda == p_buf->bda) {
335 VLOG(1) << "bda is in the srv chg clt list";
336 return p_buf;
337 }
338 }
339
340 return NULL;
341 }
342
343 /*******************************************************************************
344 *
345 * Function gatt_is_bda_connected
346 *
347 * Description
348 *
349 * Returns GATT_INDEX_INVALID if not found. Otherwise index to the tcb.
350 *
351 ******************************************************************************/
gatt_is_bda_connected(const RawAddress & bda)352 bool gatt_is_bda_connected(const RawAddress& bda) {
353 uint8_t i = 0;
354 bool connected = false;
355
356 for (i = 0; i < GATT_MAX_PHY_CHANNEL; i++) {
357 if (gatt_cb.tcb[i].in_use && gatt_cb.tcb[i].peer_bda == bda) {
358 connected = true;
359 break;
360 }
361 }
362 return connected;
363 }
364
365 /*******************************************************************************
366 *
367 * Function gatt_find_i_tcb_by_addr
368 *
369 * Description Search for an empty tcb entry, and return the index.
370 *
371 * Returns GATT_INDEX_INVALID if not found. Otherwise index to the tcb.
372 *
373 ******************************************************************************/
gatt_find_i_tcb_by_addr(const RawAddress & bda,tBT_TRANSPORT transport)374 uint8_t gatt_find_i_tcb_by_addr(const RawAddress& bda,
375 tBT_TRANSPORT transport) {
376 uint8_t i = 0;
377
378 for (; i < GATT_MAX_PHY_CHANNEL; i++) {
379 if (gatt_cb.tcb[i].peer_bda == bda &&
380 gatt_cb.tcb[i].transport == transport) {
381 return i;
382 }
383 }
384 return GATT_INDEX_INVALID;
385 }
386
387 /*******************************************************************************
388 *
389 * Function gatt_get_tcb_by_idx
390 *
391 * Description The function get TCB using the TCB index
392 *
393 * Returns NULL if not found. Otherwise index to the tcb.
394 *
395 ******************************************************************************/
gatt_get_tcb_by_idx(uint8_t tcb_idx)396 tGATT_TCB* gatt_get_tcb_by_idx(uint8_t tcb_idx) {
397 tGATT_TCB* p_tcb = NULL;
398
399 if ((tcb_idx < GATT_MAX_PHY_CHANNEL) && gatt_cb.tcb[tcb_idx].in_use)
400 p_tcb = &gatt_cb.tcb[tcb_idx];
401
402 return p_tcb;
403 }
404
405 /*******************************************************************************
406 *
407 * Function gatt_find_tcb_by_addr
408 *
409 * Description Search for an empty tcb entry, and return pointer.
410 *
411 * Returns NULL if not found. Otherwise index to the tcb.
412 *
413 ******************************************************************************/
gatt_find_tcb_by_addr(const RawAddress & bda,tBT_TRANSPORT transport)414 tGATT_TCB* gatt_find_tcb_by_addr(const RawAddress& bda,
415 tBT_TRANSPORT transport) {
416 tGATT_TCB* p_tcb = nullptr;
417 uint8_t i = 0;
418
419 i = gatt_find_i_tcb_by_addr(bda, transport);
420 if (i != GATT_INDEX_INVALID) p_tcb = &gatt_cb.tcb[i];
421
422 return p_tcb;
423 }
424
425 /*******************************************************************************
426 *
427 * Function gatt_allocate_tcb_by_bdaddr
428 *
429 * Description Locate or allocate a new tcb entry for matching bda.
430 *
431 * Returns GATT_INDEX_INVALID if not found. Otherwise index to the tcb.
432 *
433 ******************************************************************************/
gatt_allocate_tcb_by_bdaddr(const RawAddress & bda,tBT_TRANSPORT transport)434 tGATT_TCB* gatt_allocate_tcb_by_bdaddr(const RawAddress& bda,
435 tBT_TRANSPORT transport) {
436 /* search for existing tcb with matching bda */
437 uint8_t j = gatt_find_i_tcb_by_addr(bda, transport);
438 if (j != GATT_INDEX_INVALID) return &gatt_cb.tcb[j];
439
440 /* find free tcb */
441 for (int i = 0; i < GATT_MAX_PHY_CHANNEL; i++) {
442 tGATT_TCB* p_tcb = &gatt_cb.tcb[i];
443 if (p_tcb->in_use) continue;
444
445 *p_tcb = tGATT_TCB();
446
447 p_tcb->pending_ind_q = fixed_queue_new(SIZE_MAX);
448 p_tcb->conf_timer = alarm_new("gatt.conf_timer");
449 p_tcb->ind_ack_timer = alarm_new("gatt.ind_ack_timer");
450 p_tcb->in_use = true;
451 p_tcb->tcb_idx = i;
452 p_tcb->transport = transport;
453 p_tcb->peer_bda = bda;
454 p_tcb->eatt = 0;
455 p_tcb->pending_user_mtu_exchange_value = 0;
456 p_tcb->conn_ids_waiting_for_mtu_exchange = std::list<uint16_t>();
457 p_tcb->max_user_mtu = 0;
458 gatt_sr_init_cl_status(*p_tcb);
459 gatt_cl_init_sr_status(*p_tcb);
460
461 return p_tcb;
462 }
463
464 return NULL;
465 }
466
gatt_get_mtu(const RawAddress & bda,tBT_TRANSPORT transport)467 uint16_t gatt_get_mtu(const RawAddress& bda, tBT_TRANSPORT transport) {
468 tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(bda, transport);
469 if (!p_tcb) return 0;
470
471 return p_tcb->payload_size;
472 }
473
gatt_is_pending_mtu_exchange(tGATT_TCB * p_tcb)474 bool gatt_is_pending_mtu_exchange(tGATT_TCB* p_tcb) {
475 return p_tcb->pending_user_mtu_exchange_value != 0;
476 }
477
gatt_set_conn_id_waiting_for_mtu_exchange(tGATT_TCB * p_tcb,uint16_t conn_id)478 void gatt_set_conn_id_waiting_for_mtu_exchange(tGATT_TCB* p_tcb,
479 uint16_t conn_id) {
480 auto it = std::find(p_tcb->conn_ids_waiting_for_mtu_exchange.begin(),
481 p_tcb->conn_ids_waiting_for_mtu_exchange.end(), conn_id);
482 if (it == p_tcb->conn_ids_waiting_for_mtu_exchange.end()) {
483 p_tcb->conn_ids_waiting_for_mtu_exchange.push_back(conn_id);
484 LOG_INFO("Put conn_id=0x%04x on wait list", conn_id);
485 } else {
486 LOG_INFO("Conn_id=0x%04x already on wait list", conn_id);
487 }
488 }
489
490 /** gatt_build_uuid_to_stream will convert 32bit UUIDs to 128bit. This function
491 * will return lenght required to build uuid, either |UUID:kNumBytes16| or
492 * |UUID::kNumBytes128| */
gatt_build_uuid_to_stream_len(const Uuid & uuid)493 uint8_t gatt_build_uuid_to_stream_len(const Uuid& uuid) {
494 size_t len = uuid.GetShortestRepresentationSize();
495 return len == Uuid::kNumBytes32 ? Uuid::kNumBytes128 : len;
496 }
497
498 /** Add UUID into stream. Returns UUID length. */
gatt_build_uuid_to_stream(uint8_t ** p_dst,const Uuid & uuid)499 uint8_t gatt_build_uuid_to_stream(uint8_t** p_dst, const Uuid& uuid) {
500 uint8_t* p = *p_dst;
501 size_t len = uuid.GetShortestRepresentationSize();
502
503 if (uuid.IsEmpty()) {
504 return 0;
505 }
506
507 if (len == Uuid::kNumBytes16) {
508 UINT16_TO_STREAM(p, uuid.As16Bit());
509 } else if (len == Uuid::kNumBytes32) {
510 /* always convert 32 bits into 128 bits */
511 ARRAY_TO_STREAM(p, uuid.To128BitLE(), (int)Uuid::kNumBytes128);
512 len = Uuid::kNumBytes128;
513 } else if (len == Uuid::kNumBytes128) {
514 ARRAY_TO_STREAM(p, uuid.To128BitLE(), (int)Uuid::kNumBytes128);
515 }
516
517 *p_dst = p;
518 return len;
519 }
520
gatt_parse_uuid_from_cmd(Uuid * p_uuid_rec,uint16_t uuid_size,uint8_t ** p_data)521 bool gatt_parse_uuid_from_cmd(Uuid* p_uuid_rec, uint16_t uuid_size,
522 uint8_t** p_data) {
523 bool ret = true;
524 uint8_t* p_uuid = *p_data;
525
526 switch (uuid_size) {
527 case Uuid::kNumBytes16: {
528 uint16_t val;
529 STREAM_TO_UINT16(val, p_uuid);
530 *p_uuid_rec = Uuid::From16Bit(val);
531 *p_data += Uuid::kNumBytes16;
532 return true;
533 }
534
535 case Uuid::kNumBytes128: {
536 *p_uuid_rec = Uuid::From128BitLE(p_uuid);
537 *p_data += Uuid::kNumBytes128;
538 return true;
539 }
540
541 /* do not allow 32 bits UUID in ATT PDU now */
542 case Uuid::kNumBytes32:
543 LOG(ERROR) << "DO NOT ALLOW 32 BITS UUID IN ATT PDU";
544 return false;
545 case 0:
546 default:
547 if (uuid_size != 0) ret = false;
548 LOG(WARNING) << __func__ << ": invalid uuid size";
549 break;
550 }
551
552 return (ret);
553 }
554
555 /*******************************************************************************
556 *
557 * Function gatt_start_rsp_timer
558 *
559 * Description Start a wait_for_response timer.
560 *
561 * Returns void
562 *
563 ******************************************************************************/
gatt_start_rsp_timer(tGATT_CLCB * p_clcb)564 void gatt_start_rsp_timer(tGATT_CLCB* p_clcb) {
565 uint64_t timeout_ms = GATT_WAIT_FOR_RSP_TIMEOUT_MS;
566
567 if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY &&
568 p_clcb->op_subtype == GATT_DISC_SRVC_ALL) {
569 timeout_ms = GATT_WAIT_FOR_DISC_RSP_TIMEOUT_MS;
570 }
571
572 // TODO: The tGATT_CLCB memory and state management needs cleanup,
573 // and then the timers can be allocated elsewhere.
574 if (p_clcb->gatt_rsp_timer_ent == NULL) {
575 p_clcb->gatt_rsp_timer_ent = alarm_new("gatt.gatt_rsp_timer_ent");
576 }
577 alarm_set_on_mloop(p_clcb->gatt_rsp_timer_ent, timeout_ms, gatt_rsp_timeout,
578 p_clcb);
579 }
580
581 /*******************************************************************************
582 *
583 * Function gatt_stop_rsp_timer
584 *
585 * Description Stops a GATT response timer.
586 *
587 * Returns void
588 *
589 ******************************************************************************/
gatt_stop_rsp_timer(tGATT_CLCB * p_clcb)590 void gatt_stop_rsp_timer(tGATT_CLCB* p_clcb) {
591 alarm_cancel(p_clcb->gatt_rsp_timer_ent);
592 }
593
594 /*******************************************************************************
595 *
596 * Function gatt_start_conf_timer
597 *
598 * Description Start a wait_for_confirmation timer.
599 *
600 * Returns void
601 *
602 ******************************************************************************/
gatt_start_conf_timer(tGATT_TCB * p_tcb,uint16_t cid)603 void gatt_start_conf_timer(tGATT_TCB* p_tcb, uint16_t cid) {
604 /* start notification cache timer */
605 if (p_tcb->eatt && cid != L2CAP_ATT_CID)
606 EattExtension::GetInstance()->StartIndicationConfirmationTimer(p_tcb->peer_bda, cid);
607 else
608 alarm_set_on_mloop(p_tcb->conf_timer, GATT_WAIT_FOR_RSP_TIMEOUT_MS,
609 gatt_indication_confirmation_timeout, p_tcb);
610 }
611
612 /*******************************************************************************
613 *
614 * Function gatt_stop_conf_timer
615 *
616 * Description Start a wait_for_confirmation timer.
617 *
618 * Returns void
619 *
620 ******************************************************************************/
gatt_stop_conf_timer(tGATT_TCB & tcb,uint16_t cid)621 void gatt_stop_conf_timer(tGATT_TCB& tcb, uint16_t cid) {
622 /* start notification cache timer */
623 if (tcb.eatt && cid != L2CAP_ATT_CID)
624 EattExtension::GetInstance()->StopIndicationConfirmationTimer(tcb.peer_bda, cid);
625 else
626 alarm_cancel(tcb.conf_timer);
627 }
628
629 /*******************************************************************************
630 *
631 * Function gatt_start_ind_ack_timer
632 *
633 * Description start the application ack timer
634 *
635 * Returns void
636 *
637 ******************************************************************************/
gatt_start_ind_ack_timer(tGATT_TCB & tcb,uint16_t cid)638 void gatt_start_ind_ack_timer(tGATT_TCB& tcb, uint16_t cid) {
639 /* start notification cache timer */
640 if (tcb.eatt && cid != L2CAP_ATT_CID)
641 EattExtension::GetInstance()->StartAppIndicationTimer(tcb.peer_bda, cid);
642 else
643 alarm_set_on_mloop(tcb.ind_ack_timer, GATT_WAIT_FOR_RSP_TIMEOUT_MS,
644 gatt_ind_ack_timeout, &tcb);
645 }
646
647 /*******************************************************************************
648 *
649 * Function gatt_stop_ind_ack_timer
650 *
651 * Description stop the application ack timer
652 *
653 * Returns void
654 *
655 ******************************************************************************/
gatt_stop_ind_ack_timer(tGATT_TCB * p_tcb,uint16_t cid)656 void gatt_stop_ind_ack_timer(tGATT_TCB* p_tcb, uint16_t cid) {
657 /* start notification cache timer */
658 if (p_tcb->eatt && cid != L2CAP_ATT_CID) {
659 EattExtension::GetInstance()->StopAppIndicationTimer(p_tcb->peer_bda, cid);
660 } else {
661 alarm_cancel(p_tcb->ind_ack_timer);
662 p_tcb->ind_count = 0;
663 }
664 }
665 /*******************************************************************************
666 *
667 * Function gatt_rsp_timeout
668 *
669 * Description Called when GATT wait for ATT command response timer expires
670 *
671 * Returns void
672 *
673 ******************************************************************************/
gatt_rsp_timeout(void * data)674 void gatt_rsp_timeout(void* data) {
675 tGATT_CLCB* p_clcb = (tGATT_CLCB*)data;
676
677 if (p_clcb == NULL || p_clcb->p_tcb == NULL) {
678 LOG(WARNING) << __func__ << " clcb is already deleted";
679 return;
680 }
681 if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY &&
682 p_clcb->op_subtype == GATT_DISC_SRVC_ALL &&
683 p_clcb->retry_count < GATT_REQ_RETRY_LIMIT) {
684 uint8_t rsp_code;
685 LOG(WARNING) << __func__ << " retry discovery primary service";
686 if (p_clcb != gatt_cmd_dequeue(*p_clcb->p_tcb, p_clcb->cid, &rsp_code)) {
687 LOG(ERROR) << __func__ << " command queue out of sync, disconnect";
688 } else {
689 p_clcb->retry_count++;
690 gatt_act_discovery(p_clcb);
691 return;
692 }
693 }
694
695 auto eatt_channel = EattExtension::GetInstance()->FindEattChannelByCid(
696 p_clcb->p_tcb->peer_bda, p_clcb->cid);
697 if (eatt_channel) {
698 LOG_WARN("disconnecting EATT cid: %d", p_clcb->cid);
699 EattExtension::GetInstance()->Disconnect(p_clcb->p_tcb->peer_bda,
700 p_clcb->cid);
701 } else {
702 LOG_WARN("disconnecting GATT...");
703 gatt_disconnect(p_clcb->p_tcb);
704 }
705 }
706
707 void gatts_proc_srv_chg_ind_ack(tGATT_TCB tcb);
708
709 /*******************************************************************************
710 *
711 * Function gatt_indication_confirmation_timeout
712 *
713 * Description Called when the indication confirmation timer expires
714 *
715 * Returns void
716 *
717 ******************************************************************************/
gatt_indication_confirmation_timeout(void * data)718 void gatt_indication_confirmation_timeout(void* data) {
719 tGATT_TCB* p_tcb = (tGATT_TCB*)data;
720
721 if (p_tcb->indicate_handle == gatt_cb.handle_of_h_r) {
722 /* There are some GATT Server only devices, that don't implement GATT client
723 * functionalities, and ignore "Service Changed" indication. Android does
724 * not have CCC in "Service Changed" characteristic, and sends it to all
725 * bonded devices. This leads to situation where remote can ignore the
726 * indication, and trigger 30s timeout, then reconnection in a loop.
727 *
728 * Since chances of healthy Client device keeping connection for 30 seconds
729 * and not responding to "Service Changed" indication are very low, assume
730 * we are dealing with Server only device, and don't trigger disconnection.
731 *
732 * TODO: In future, we should properly expose CCC, and send indication only
733 * to devices that register for it.
734 */
735 LOG(WARNING) << " Service Changed notification timed out in 30 "
736 "seconds, assuming server-only remote, not disconnecting";
737 gatts_proc_srv_chg_ind_ack(*p_tcb);
738 return;
739 }
740
741 LOG(WARNING) << __func__ << " disconnecting...";
742 gatt_disconnect(p_tcb);
743 }
744
745 /*******************************************************************************
746 *
747 * Function gatt_ind_ack_timeout
748 *
749 * Description Called when GATT wait for ATT handle confirmation timeout
750 *
751 * Returns void
752 *
753 ******************************************************************************/
gatt_ind_ack_timeout(void * data)754 void gatt_ind_ack_timeout(void* data) {
755 tGATT_TCB* p_tcb = (tGATT_TCB*)data;
756 CHECK(p_tcb);
757
758 LOG(WARNING) << __func__ << ": send ack now";
759 p_tcb->ind_count = 0;
760 /*TODO: For now ATT used only, but we need to have timeout per CID
761 * and use it here corretly.
762 */
763 attp_send_cl_confirmation_msg(*p_tcb, L2CAP_ATT_CID);
764 }
765 /*******************************************************************************
766 *
767 * Description Search for a service that owns a specific handle.
768 *
769 * Returns GATT_MAX_SR_PROFILES if not found. Otherwise the index of
770 * the service.
771 *
772 ******************************************************************************/
gatt_sr_find_i_rcb_by_handle(uint16_t handle)773 std::list<tGATT_SRV_LIST_ELEM>::iterator gatt_sr_find_i_rcb_by_handle(
774 uint16_t handle) {
775 auto it = gatt_cb.srv_list_info->begin();
776
777 for (; it != gatt_cb.srv_list_info->end(); it++) {
778 if (it->s_hdl <= handle && it->e_hdl >= handle) {
779 return it;
780 }
781 }
782
783 return it;
784 }
785
786 /*******************************************************************************
787 *
788 * Function gatt_sr_get_sec_info
789 *
790 * Description Get the security flag and key size information for the peer
791 * device.
792 *
793 * Returns void
794 *
795 ******************************************************************************/
gatt_sr_get_sec_info(const RawAddress & rem_bda,tBT_TRANSPORT transport,tGATT_SEC_FLAG * p_sec_flag,uint8_t * p_key_size)796 void gatt_sr_get_sec_info(const RawAddress& rem_bda, tBT_TRANSPORT transport,
797 tGATT_SEC_FLAG* p_sec_flag, uint8_t* p_key_size) {
798 tGATT_SEC_FLAG flags = {};
799 flags.is_link_key_known = BTM_IsLinkKeyKnown(rem_bda, transport);
800 flags.is_link_key_authed = BTM_IsLinkKeyAuthed(rem_bda, transport);
801 flags.is_encrypted = BTM_IsEncrypted(rem_bda, transport);
802 flags.can_read_discoverable_characteristics =
803 BTM_CanReadDiscoverableCharacteristics(rem_bda);
804
805 *p_key_size = btm_ble_read_sec_key_size(rem_bda);
806 *p_sec_flag = flags;
807 }
808 /*******************************************************************************
809 *
810 * Function gatt_sr_send_req_callback
811 *
812 * Description
813 *
814 *
815 * Returns void
816 *
817 ******************************************************************************/
gatt_sr_send_req_callback(uint16_t conn_id,uint32_t trans_id,tGATTS_REQ_TYPE type,tGATTS_DATA * p_data)818 void gatt_sr_send_req_callback(uint16_t conn_id, uint32_t trans_id,
819 tGATTS_REQ_TYPE type, tGATTS_DATA* p_data) {
820 tGATT_IF gatt_if = GATT_GET_GATT_IF(conn_id);
821 tGATT_REG* p_reg = gatt_get_regcb(gatt_if);
822
823 if (!p_reg) {
824 LOG(ERROR) << "p_reg not found discard request";
825 return;
826 }
827
828 if (p_reg->in_use && p_reg->app_cb.p_req_cb) {
829 (*p_reg->app_cb.p_req_cb)(conn_id, trans_id, type, p_data);
830 } else {
831 LOG(WARNING) << "Call back not found for application conn_id=" << conn_id;
832 }
833 }
834
835 /*******************************************************************************
836 *
837 * Function gatt_send_error_rsp
838 *
839 * Description This function sends an error response.
840 *
841 * Returns void
842 *
843 ******************************************************************************/
gatt_send_error_rsp(tGATT_TCB & tcb,uint16_t cid,uint8_t err_code,uint8_t op_code,uint16_t handle,bool deq)844 tGATT_STATUS gatt_send_error_rsp(tGATT_TCB& tcb, uint16_t cid, uint8_t err_code,
845 uint8_t op_code, uint16_t handle, bool deq) {
846 tGATT_STATUS status;
847 BT_HDR* p_buf;
848
849 tGATT_SR_MSG msg;
850 msg.error.cmd_code = op_code;
851 msg.error.reason = err_code;
852 msg.error.handle = handle;
853
854 uint16_t payload_size = gatt_tcb_get_payload_size_tx(tcb, cid);
855 p_buf = attp_build_sr_msg(tcb, GATT_RSP_ERROR, &msg, payload_size);
856 if (p_buf != NULL) {
857 status = attp_send_sr_msg(tcb, cid, p_buf);
858 } else
859 status = GATT_INSUF_RESOURCE;
860
861 if (deq)
862 gatt_dequeue_sr_cmd(tcb, cid);
863
864 return status;
865 }
866
867 /*******************************************************************************
868 *
869 * Function gatt_add_sdp_record
870 *
871 * Description This function add a SDP record for a GATT primary service
872 *
873 * Returns 0 if error else sdp handle for the record.
874 *
875 ******************************************************************************/
gatt_add_sdp_record(const Uuid & uuid,uint16_t start_hdl,uint16_t end_hdl)876 uint32_t gatt_add_sdp_record(const Uuid& uuid, uint16_t start_hdl,
877 uint16_t end_hdl) {
878 uint8_t buff[60];
879 uint8_t* p = buff;
880
881 VLOG(1) << __func__
882 << StringPrintf(" s_hdl=0x%x s_hdl=0x%x", start_hdl, end_hdl);
883
884 uint32_t sdp_handle = SDP_CreateRecord();
885 if (sdp_handle == 0) return 0;
886
887 switch (uuid.GetShortestRepresentationSize()) {
888 case Uuid::kNumBytes16: {
889 uint16_t tmp = uuid.As16Bit();
890 SDP_AddServiceClassIdList(sdp_handle, 1, &tmp);
891 break;
892 }
893
894 case Uuid::kNumBytes32: {
895 UINT8_TO_BE_STREAM(p, (UUID_DESC_TYPE << 3) | SIZE_FOUR_BYTES);
896 uint32_t tmp = uuid.As32Bit();
897 UINT32_TO_BE_STREAM(p, tmp);
898 SDP_AddAttribute(sdp_handle, ATTR_ID_SERVICE_CLASS_ID_LIST,
899 DATA_ELE_SEQ_DESC_TYPE, (uint32_t)(p - buff), buff);
900 break;
901 }
902
903 case Uuid::kNumBytes128:
904 UINT8_TO_BE_STREAM(p, (UUID_DESC_TYPE << 3) | SIZE_SIXTEEN_BYTES);
905 ARRAY_TO_BE_STREAM(p, uuid.To128BitBE().data(), (int)Uuid::kNumBytes128);
906 SDP_AddAttribute(sdp_handle, ATTR_ID_SERVICE_CLASS_ID_LIST,
907 DATA_ELE_SEQ_DESC_TYPE, (uint32_t)(p - buff), buff);
908 break;
909 }
910
911 /*** Fill out the protocol element sequence for SDP ***/
912 tSDP_PROTOCOL_ELEM proto_elem_list[2];
913 proto_elem_list[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
914 proto_elem_list[0].num_params = 1;
915 proto_elem_list[0].params[0] = BT_PSM_ATT;
916 proto_elem_list[1].protocol_uuid = UUID_PROTOCOL_ATT;
917 proto_elem_list[1].num_params = 2;
918 proto_elem_list[1].params[0] = start_hdl;
919 proto_elem_list[1].params[1] = end_hdl;
920
921 SDP_AddProtocolList(sdp_handle, 2, proto_elem_list);
922
923 /* Make the service browseable */
924 uint16_t list = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
925 SDP_AddUuidSequence(sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &list);
926
927 return (sdp_handle);
928 }
929
930 #if GATT_CONFORMANCE_TESTING == TRUE
931 /*******************************************************************************
932 *
933 * Function gatt_set_err_rsp
934 *
935 * Description This function is called to set the test confirm value
936 *
937 * Returns void
938 *
939 ******************************************************************************/
gatt_set_err_rsp(bool enable,uint8_t req_op_code,uint8_t err_status)940 void gatt_set_err_rsp(bool enable, uint8_t req_op_code, uint8_t err_status) {
941 VLOG(1) << __func__
942 << StringPrintf(" enable=%d op_code=%d, err_status=%d", enable,
943 req_op_code, err_status);
944 gatt_cb.enable_err_rsp = enable;
945 gatt_cb.req_op_code = req_op_code;
946 gatt_cb.err_status = err_status;
947 }
948 #endif
949
950 /*******************************************************************************
951 *
952 * Function gatt_get_regcb
953 *
954 * Description The function returns the registration control block.
955 *
956 * Returns pointer to the registration control block or NULL
957 *
958 ******************************************************************************/
gatt_get_regcb(tGATT_IF gatt_if)959 tGATT_REG* gatt_get_regcb(tGATT_IF gatt_if) {
960 uint8_t ii = (uint8_t)gatt_if;
961 tGATT_REG* p_reg = NULL;
962
963 if (ii < 1 || ii > GATT_MAX_APPS) {
964 LOG(WARNING) << "gatt_if out of range = " << +ii;
965 return NULL;
966 }
967
968 // Index for cl_rcb is always 1 less than gatt_if.
969 p_reg = &gatt_cb.cl_rcb[ii - 1];
970
971 if (!p_reg->in_use) {
972 LOG(WARNING) << "gatt_if found but not in use.";
973 return NULL;
974 }
975
976 return p_reg;
977 }
978
979 /*******************************************************************************
980 *
981 * Function gatt_tcb_is_cid_busy
982 *
983 * Description The function check if channel with given cid is busy
984 *
985 * Returns True when busy
986 *
987 ******************************************************************************/
988
gatt_tcb_is_cid_busy(tGATT_TCB & tcb,uint16_t cid)989 bool gatt_tcb_is_cid_busy(tGATT_TCB& tcb, uint16_t cid) {
990 if (cid == tcb.att_lcid) return !tcb.cl_cmd_q.empty();
991
992 EattChannel* channel =
993 EattExtension::GetInstance()->FindEattChannelByCid(tcb.peer_bda, cid);
994 if (!channel) return false;
995
996 return !channel->cl_cmd_q_.empty();
997 }
998 /*******************************************************************************
999 *
1000 * Function gatt_clcb_alloc
1001 *
1002 * Description The function allocates a GATT connection link control block
1003 *
1004 * Returns NULL if not found. Otherwise pointer to the connection link
1005 * block.
1006 *
1007 ******************************************************************************/
gatt_clcb_alloc(uint16_t conn_id)1008 tGATT_CLCB* gatt_clcb_alloc(uint16_t conn_id) {
1009 tGATT_CLCB clcb = {};
1010 tGATT_IF gatt_if = GATT_GET_GATT_IF(conn_id);
1011 uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id);
1012 tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(tcb_idx);
1013 tGATT_REG* p_reg = gatt_get_regcb(gatt_if);
1014
1015 clcb.conn_id = conn_id;
1016 clcb.p_reg = p_reg;
1017 clcb.p_tcb = p_tcb;
1018 /* Use eatt only when clients wants that */
1019 clcb.cid = gatt_tcb_get_att_cid(*p_tcb, p_reg->eatt_support);
1020
1021 gatt_cb.clcb_queue.emplace_back(clcb);
1022 auto p_clcb = &(gatt_cb.clcb_queue.back());
1023
1024 if (gatt_cb.clcb_queue.size() > GATT_CL_MAX_LCB) {
1025 /* GATT_CL_MAX_LCB is here from the historical reasons. We believe this
1026 * limitation is not needed. In addition, number of clcb should not be
1027 * bigger than that and also if it is bigger, we believe it should not
1028 * cause the problem. This WARN is just to monitor number of CLCB and will
1029 * help in debugging in case we are wrong */
1030 LOG_WARN("Number of CLCB: %zu > %d", gatt_cb.clcb_queue.size(),
1031 GATT_CL_MAX_LCB);
1032 }
1033 return p_clcb;
1034 }
1035
1036 /*******************************************************************************
1037 *
1038 * Function gatt_tcb_get_cid_available_for_indication
1039 *
1040 * Description This function checks if indication can be send
1041 *
1042 * Returns true when stack is busy with waiting on indication
1043 * confirmation, false otherwise
1044 *
1045 ******************************************************************************/
gatt_tcb_get_cid_available_for_indication(tGATT_TCB * p_tcb,bool eatt_support,uint16_t ** indicated_handle_p,uint16_t * cid_p)1046 bool gatt_tcb_get_cid_available_for_indication(tGATT_TCB* p_tcb,
1047 bool eatt_support,
1048 uint16_t** indicated_handle_p,
1049 uint16_t* cid_p) {
1050 if (p_tcb->eatt && eatt_support) {
1051 EattChannel* channel =
1052 EattExtension::GetInstance()->GetChannelAvailableForIndication(p_tcb->peer_bda);
1053 if (channel) {
1054 *indicated_handle_p = &channel->indicate_handle_;
1055 *cid_p = channel->cid_;
1056 return true;
1057 }
1058 }
1059
1060 if (!GATT_HANDLE_IS_VALID(p_tcb->indicate_handle)) {
1061 *indicated_handle_p = &p_tcb->indicate_handle;
1062 *cid_p = p_tcb->att_lcid;
1063 return true;
1064 }
1065
1066 return false;
1067 }
1068
1069 /*******************************************************************************
1070 *
1071 * Function gatt_tcb_find_indicate_handle
1072 *
1073 * Description This function checks if indication can be send
1074 *
1075 * Returns true when indication handle found, false otherwise
1076 *
1077 ******************************************************************************/
gatt_tcb_find_indicate_handle(tGATT_TCB & tcb,uint16_t cid,uint16_t * indicated_handle_p)1078 bool gatt_tcb_find_indicate_handle(tGATT_TCB& tcb, uint16_t cid,
1079 uint16_t* indicated_handle_p) {
1080 if (cid == tcb.att_lcid) {
1081 *indicated_handle_p = tcb.indicate_handle;
1082 tcb.indicate_handle = 0;
1083 return true;
1084 }
1085
1086 if (tcb.eatt) {
1087 EattChannel* channel =
1088 EattExtension::GetInstance()->FindEattChannelByCid(tcb.peer_bda, cid);
1089 if (channel) {
1090 *indicated_handle_p = channel->indicate_handle_;
1091 channel->indicate_handle_ = 0;
1092 return true;
1093 }
1094 }
1095
1096 return false;
1097 }
1098
1099 /*******************************************************************************
1100 *
1101 * Function gatt_tcb_get_att_cid
1102 *
1103 * Description This function gets cid for the GATT operation
1104 *
1105 * Returns Available CID
1106 *
1107 ******************************************************************************/
1108
gatt_tcb_get_att_cid(tGATT_TCB & tcb,bool eatt_support)1109 uint16_t gatt_tcb_get_att_cid(tGATT_TCB& tcb, bool eatt_support) {
1110 if (eatt_support && tcb.eatt) {
1111 EattChannel* channel =
1112 EattExtension::GetInstance()->GetChannelAvailableForClientRequest(tcb.peer_bda);
1113 if (channel) {
1114 return channel->cid_;
1115 }
1116 }
1117 return tcb.att_lcid;
1118 }
1119
1120 /*******************************************************************************
1121 *
1122 * Function gatt_tcb_get_payload_size_tx
1123 *
1124 * Description This function gets payload size for the GATT operation
1125 *
1126 * Returns Payload size for sending data
1127 *
1128 ******************************************************************************/
gatt_tcb_get_payload_size_tx(tGATT_TCB & tcb,uint16_t cid)1129 uint16_t gatt_tcb_get_payload_size_tx(tGATT_TCB& tcb, uint16_t cid) {
1130 if (!tcb.eatt || (cid == tcb.att_lcid)) return tcb.payload_size;
1131
1132 EattChannel* channel =
1133 EattExtension::GetInstance()->FindEattChannelByCid(tcb.peer_bda, cid);
1134
1135 return channel->tx_mtu_;
1136 }
1137
1138 /*******************************************************************************
1139 *
1140 * Function gatt_tcb_get_payload_size_rx
1141 *
1142 * Description This function gets payload size for the GATT operation
1143 *
1144 * Returns Payload size for receiving data
1145 *
1146 ******************************************************************************/
1147
gatt_tcb_get_payload_size_rx(tGATT_TCB & tcb,uint16_t cid)1148 uint16_t gatt_tcb_get_payload_size_rx(tGATT_TCB& tcb, uint16_t cid) {
1149 if (!tcb.eatt || (cid == tcb.att_lcid)) return tcb.payload_size;
1150
1151 EattChannel* channel =
1152 EattExtension::GetInstance()->FindEattChannelByCid(tcb.peer_bda, cid);
1153
1154 return channel->rx_mtu_;
1155 }
1156
1157 /*******************************************************************************
1158 *
1159 * Function gatt_clcb_dealloc
1160 *
1161 * Description The function de-allocates a GATT connection link control
1162 * block
1163 *
1164 * Returns None
1165 *
1166 ******************************************************************************/
gatt_clcb_dealloc(tGATT_CLCB * p_clcb)1167 static void gatt_clcb_dealloc(tGATT_CLCB* p_clcb) {
1168 if (p_clcb) {
1169 alarm_free(p_clcb->gatt_rsp_timer_ent);
1170 gatt_clcb_invalidate(p_clcb->p_tcb, p_clcb);
1171 for (auto clcb_it = gatt_cb.clcb_queue.begin();
1172 clcb_it != gatt_cb.clcb_queue.end(); clcb_it++) {
1173 if (&(*clcb_it) == p_clcb) {
1174 gatt_cb.clcb_queue.erase(clcb_it);
1175 return;
1176 }
1177 }
1178 }
1179 }
1180
1181 /*******************************************************************************
1182 *
1183 * Function gatt_clcb_invalidate
1184 *
1185 * Description The function invalidates already scheduled p_clcb.
1186 *
1187 * Returns None
1188 *
1189 ******************************************************************************/
gatt_clcb_invalidate(tGATT_TCB * p_tcb,const tGATT_CLCB * p_clcb)1190 void gatt_clcb_invalidate(tGATT_TCB* p_tcb, const tGATT_CLCB* p_clcb) {
1191 std::deque<tGATT_CMD_Q>* cl_cmd_q_p;
1192 uint16_t cid = p_clcb->cid;
1193
1194 if (!p_tcb->pending_enc_clcb.empty()) {
1195 for (size_t i = 0; i < p_tcb->pending_enc_clcb.size(); i++) {
1196 if (p_tcb->pending_enc_clcb.at(i) == p_clcb) {
1197 LOG_WARN("Removing clcb (%p) for conn id=0x%04x from pending_enc_clcb",
1198 p_clcb, p_clcb->conn_id);
1199 p_tcb->pending_enc_clcb.at(i) = NULL;
1200 break;
1201 }
1202 }
1203 }
1204
1205 if (cid == p_tcb->att_lcid) {
1206 cl_cmd_q_p = &p_tcb->cl_cmd_q;
1207 } else {
1208 EattChannel* channel = EattExtension::GetInstance()->FindEattChannelByCid(
1209 p_tcb->peer_bda, cid);
1210 if (channel == nullptr) {
1211 return;
1212 }
1213 cl_cmd_q_p = &channel->cl_cmd_q_;
1214 }
1215
1216 if (cl_cmd_q_p->empty()) {
1217 return;
1218 }
1219
1220 auto iter = std::find_if(cl_cmd_q_p->begin(), cl_cmd_q_p->end(),
1221 [p_clcb](auto& el) { return el.p_clcb == p_clcb; });
1222
1223 if (iter == cl_cmd_q_p->end()) {
1224 return;
1225 }
1226
1227 if (iter->to_send) {
1228 /* If command was not send, just remove the entire element */
1229 cl_cmd_q_p->erase(iter);
1230 LOG_WARN("Removing scheduled clcb (%p) for conn_id=0x%04x", p_clcb,
1231 p_clcb->conn_id);
1232 } else {
1233 /* If command has been sent, just invalidate p_clcb pointer for proper
1234 * response handling */
1235 iter->p_clcb = NULL;
1236 LOG_WARN(
1237 "Invalidating clcb (%p) for already sent request on conn_id=0x%04x",
1238 p_clcb, p_clcb->conn_id);
1239 }
1240 }
1241 /*******************************************************************************
1242 *
1243 * Function gatt_find_tcb_by_cid
1244 *
1245 * Description The function searches for an empty entry
1246 * in registration info table for GATT client
1247 *
1248 * Returns NULL if not found. Otherwise pointer to the rcb.
1249 *
1250 ******************************************************************************/
gatt_find_tcb_by_cid(uint16_t lcid)1251 tGATT_TCB* gatt_find_tcb_by_cid(uint16_t lcid) {
1252 uint16_t xx = 0;
1253 tGATT_TCB* p_tcb = NULL;
1254
1255 for (xx = 0; xx < GATT_MAX_PHY_CHANNEL; xx++) {
1256 if (gatt_cb.tcb[xx].in_use &&
1257 ((gatt_cb.tcb[xx].att_lcid == lcid) ||
1258 ((EattExtension::GetInstance()->FindEattChannelByCid(gatt_cb.tcb[xx].peer_bda,
1259 lcid) != nullptr)))) {
1260 p_tcb = &gatt_cb.tcb[xx];
1261 break;
1262 }
1263 }
1264 return p_tcb;
1265 }
1266
1267 /*******************************************************************************
1268 *
1269 * Function gatt_num_clcb_by_bd_addr
1270 *
1271 * Description The function searches all LCB with macthing bd address
1272 *
1273 * Returns total number of clcb found.
1274 *
1275 ******************************************************************************/
gatt_num_clcb_by_bd_addr(const RawAddress & bda)1276 uint8_t gatt_num_clcb_by_bd_addr(const RawAddress& bda) {
1277 uint8_t num = 0;
1278
1279 for (auto const& clcb : gatt_cb.clcb_queue) {
1280 if (clcb.p_tcb->peer_bda == bda) num++;
1281 }
1282 return num;
1283 }
1284
gatt_sr_copy_prep_cnt_to_cback_cnt(tGATT_TCB & tcb)1285 void gatt_sr_copy_prep_cnt_to_cback_cnt(tGATT_TCB& tcb) {
1286 for (uint8_t i = 0; i < GATT_MAX_APPS; i++) {
1287 if (tcb.prep_cnt[i]) {
1288 tcb.sr_cmd.cback_cnt[i] = 1;
1289 }
1290 }
1291 }
1292
1293 /* Get outstanding server command pointer by the transaction id */
gatt_sr_get_cmd_by_trans_id(tGATT_TCB * p_tcb,uint32_t trans_id)1294 tGATT_SR_CMD* gatt_sr_get_cmd_by_trans_id(tGATT_TCB* p_tcb, uint32_t trans_id) {
1295 if (p_tcb->sr_cmd.trans_id == trans_id) return &p_tcb->sr_cmd;
1296
1297 if (!p_tcb->eatt) return nullptr;
1298
1299 EattChannel* channel =
1300 EattExtension::GetInstance()->FindEattChannelByTransId(p_tcb->peer_bda, trans_id);
1301 if (!channel) return nullptr;
1302
1303 return &channel->server_outstanding_cmd_;
1304 }
1305 /*******************************************************************************
1306 *
1307 * Function gatt_sr_is_cback_cnt_zero
1308 *
1309 * Description The function searches all LCB with macthing bd address
1310 *
1311 * Returns True if thetotal application callback count is zero
1312 *
1313 ******************************************************************************/
gatt_sr_is_cback_cnt_zero(tGATT_TCB & tcb)1314 bool gatt_sr_is_cback_cnt_zero(tGATT_TCB& tcb) {
1315 for (uint8_t i = 0; i < GATT_MAX_APPS; i++) {
1316 if (tcb.sr_cmd.cback_cnt[i]) {
1317 return false;
1318 }
1319 }
1320 return true;
1321 }
1322
1323 /*******************************************************************************
1324 *
1325 * Function gatt_sr_is_prep_cnt_zero
1326 *
1327 * Description Check the prepare write request count is zero or not
1328 *
1329 * Returns True no prepare write request
1330 *
1331 ******************************************************************************/
gatt_sr_is_prep_cnt_zero(tGATT_TCB & tcb)1332 bool gatt_sr_is_prep_cnt_zero(tGATT_TCB& tcb) {
1333 for (uint8_t i = 0; i < GATT_MAX_APPS; i++) {
1334 if (tcb.prep_cnt[i]) {
1335 return false;
1336 }
1337 }
1338 return true;
1339 }
1340
1341 /*******************************************************************************
1342 *
1343 * Function gatt_sr_reset_cback_cnt
1344 *
1345 * Description Reset the application callback count to zero
1346 *
1347 * Returns None
1348 *
1349 ******************************************************************************/
gatt_sr_reset_cback_cnt(tGATT_TCB & tcb,uint16_t cid)1350 void gatt_sr_reset_cback_cnt(tGATT_TCB& tcb, uint16_t cid) {
1351 for (uint8_t i = 0; i < GATT_MAX_APPS; i++) {
1352 if (cid == tcb.att_lcid) {
1353 tcb.sr_cmd.cback_cnt[i] = 0;
1354 } else {
1355 EattChannel* channel =
1356 EattExtension::GetInstance()->FindEattChannelByCid(tcb.peer_bda, cid);
1357 channel->server_outstanding_cmd_.cback_cnt[i] = 0;
1358 }
1359 }
1360 }
1361
1362 /*******************************************************************************
1363 *
1364 * Function gatt_sr_reset_prep_cnt
1365 *
1366 * Description Reset the prep write count to zero
1367 *
1368 * Returns None
1369 *
1370 ******************************************************************************/
gatt_sr_reset_prep_cnt(tGATT_TCB & tcb)1371 void gatt_sr_reset_prep_cnt(tGATT_TCB& tcb) {
1372 for (uint8_t i = 0; i < GATT_MAX_APPS; i++) {
1373 tcb.prep_cnt[i] = 0;
1374 }
1375 }
1376
1377 /* Get pointer to server command on given cid */
gatt_sr_get_cmd_by_cid(tGATT_TCB & tcb,uint16_t cid)1378 tGATT_SR_CMD* gatt_sr_get_cmd_by_cid(tGATT_TCB& tcb, uint16_t cid) {
1379 tGATT_SR_CMD* sr_cmd_p;
1380
1381 LOG(INFO) << __func__ << " cid: " << int(cid) << " tcb cid " << tcb.att_lcid;
1382 if (cid == tcb.att_lcid) {
1383 sr_cmd_p = &tcb.sr_cmd;
1384 } else {
1385 EattChannel* channel =
1386 EattExtension::GetInstance()->FindEattChannelByCid(tcb.peer_bda, cid);
1387 sr_cmd_p = &channel->server_outstanding_cmd_;
1388 }
1389
1390 return sr_cmd_p;
1391 }
1392
1393 /* Get pointer to the context of outstanding multi request */
gatt_sr_get_read_multi(tGATT_TCB & tcb,uint16_t cid)1394 tGATT_READ_MULTI* gatt_sr_get_read_multi(tGATT_TCB& tcb, uint16_t cid) {
1395 tGATT_READ_MULTI* read_multi_p;
1396
1397 LOG(INFO) << __func__ << " cid: " << int(cid) << " tcb cid " << tcb.att_lcid;
1398 if (cid == tcb.att_lcid) {
1399 read_multi_p = &tcb.sr_cmd.multi_req;
1400 } else {
1401 EattChannel* channel =
1402 EattExtension::GetInstance()->FindEattChannelByCid(tcb.peer_bda, cid);
1403 read_multi_p = &channel->server_outstanding_cmd_.multi_req;
1404 }
1405
1406 return read_multi_p;
1407 }
1408
1409 /*******************************************************************************
1410 *
1411 * Function gatt_sr_update_cback_cnt
1412 *
1413 * Description Update the teh applicaiton callback count
1414 *
1415 * Returns None
1416 *
1417 ******************************************************************************/
gatt_sr_update_cback_cnt(tGATT_TCB & tcb,uint16_t cid,tGATT_IF gatt_if,bool is_inc,bool is_reset_first)1418 void gatt_sr_update_cback_cnt(tGATT_TCB& tcb, uint16_t cid, tGATT_IF gatt_if,
1419 bool is_inc, bool is_reset_first) {
1420 uint8_t idx = ((uint8_t)gatt_if) - 1;
1421 tGATT_SR_CMD* sr_cmd_p;
1422
1423 if (cid == tcb.att_lcid) {
1424 sr_cmd_p = &tcb.sr_cmd;
1425 } else {
1426 EattChannel* channel =
1427 EattExtension::GetInstance()->FindEattChannelByCid(tcb.peer_bda, cid);
1428 sr_cmd_p = &channel->server_outstanding_cmd_;
1429 }
1430
1431 if (is_reset_first) {
1432 gatt_sr_reset_cback_cnt(tcb, cid);
1433 }
1434 if (is_inc) {
1435 sr_cmd_p->cback_cnt[idx]++;
1436 } else {
1437 if (sr_cmd_p->cback_cnt[idx]) {
1438 sr_cmd_p->cback_cnt[idx]--;
1439 }
1440 }
1441 }
1442
1443 /*******************************************************************************
1444 *
1445 * Function gatt_sr_update_prep_cnt
1446 *
1447 * Description Update the teh prepare write request count
1448 *
1449 * Returns None
1450 *
1451 ******************************************************************************/
gatt_sr_update_prep_cnt(tGATT_TCB & tcb,tGATT_IF gatt_if,bool is_inc,bool is_reset_first)1452 void gatt_sr_update_prep_cnt(tGATT_TCB& tcb, tGATT_IF gatt_if, bool is_inc,
1453 bool is_reset_first) {
1454 uint8_t idx = ((uint8_t)gatt_if) - 1;
1455
1456 VLOG(1) << StringPrintf(
1457 "%s tcb idx=%d gatt_if=%d is_inc=%d is_reset_first=%d", __func__,
1458 tcb.tcb_idx, gatt_if, is_inc, is_reset_first);
1459
1460 if (is_reset_first) {
1461 gatt_sr_reset_prep_cnt(tcb);
1462 }
1463 if (is_inc) {
1464 tcb.prep_cnt[idx]++;
1465 } else {
1466 if (tcb.prep_cnt[idx]) {
1467 tcb.prep_cnt[idx]--;
1468 }
1469 }
1470 }
1471
1472 /** Cancel LE Create Connection request */
gatt_cancel_open(tGATT_IF gatt_if,const RawAddress & bda)1473 bool gatt_cancel_open(tGATT_IF gatt_if, const RawAddress& bda) {
1474 tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(bda, BT_TRANSPORT_LE);
1475 if (!p_tcb) {
1476 LOG_WARN(
1477 "Unable to cancel open for unknown connection gatt_if:%hhu peer:%s",
1478 gatt_if, ADDRESS_TO_LOGGABLE_CSTR(bda));
1479 return true;
1480 }
1481
1482 if (gatt_get_ch_state(p_tcb) == GATT_CH_OPEN) {
1483 LOG(ERROR) << __func__ << ": link connected Too late to cancel";
1484 return false;
1485 }
1486
1487 gatt_update_app_use_link_flag(gatt_if, p_tcb, false, false);
1488
1489 if (p_tcb->app_hold_link.empty()) {
1490 LOG_DEBUG(
1491 "Client reference count is zero disconnecting device gatt_if:%hhu "
1492 "peer:%s",
1493 gatt_if, ADDRESS_TO_LOGGABLE_CSTR(bda));
1494 gatt_disconnect(p_tcb);
1495 }
1496
1497 if (bluetooth::common::init_flags::
1498 use_unified_connection_manager_is_enabled()) {
1499 bluetooth::connection::GetConnectionManager().stop_direct_connection(
1500 gatt_if, bluetooth::connection::ResolveRawAddress(bda));
1501 } else {
1502 if (!connection_manager::direct_connect_remove(gatt_if, bda)) {
1503 if (!connection_manager::is_background_connection(bda)) {
1504 BTM_AcceptlistRemove(bda);
1505 LOG_INFO(
1506 "Gatt connection manager has no background record but "
1507 " removed filter acceptlist gatt_if:%hhu peer:%s",
1508 gatt_if, ADDRESS_TO_LOGGABLE_CSTR(bda));
1509 } else {
1510 LOG_INFO(
1511 "Gatt connection manager maintains a background record"
1512 " preserving filter acceptlist gatt_if:%hhu peer:%s",
1513 gatt_if, ADDRESS_TO_LOGGABLE_CSTR(bda));
1514 }
1515 }
1516 }
1517
1518 return true;
1519 }
1520
1521 /** Enqueue this command */
gatt_cmd_enq(tGATT_TCB & tcb,tGATT_CLCB * p_clcb,bool to_send,uint8_t op_code,BT_HDR * p_buf)1522 void gatt_cmd_enq(tGATT_TCB& tcb, tGATT_CLCB* p_clcb, bool to_send,
1523 uint8_t op_code, BT_HDR* p_buf) {
1524 tGATT_CMD_Q cmd;
1525 cmd.to_send = to_send; /* waiting to be sent */
1526 cmd.op_code = op_code;
1527 cmd.p_cmd = p_buf;
1528 cmd.p_clcb = p_clcb;
1529 cmd.cid = p_clcb->cid;
1530
1531 if (p_clcb->cid == tcb.att_lcid) {
1532 tcb.cl_cmd_q.push_back(cmd);
1533 } else {
1534 EattChannel* channel =
1535 EattExtension::GetInstance()->FindEattChannelByCid(tcb.peer_bda, cmd.cid);
1536 CHECK(channel);
1537 channel->cl_cmd_q_.push_back(cmd);
1538 }
1539 }
1540
1541 /** dequeue the command in the client CCB command queue */
gatt_cmd_dequeue(tGATT_TCB & tcb,uint16_t cid,uint8_t * p_op_code)1542 tGATT_CLCB* gatt_cmd_dequeue(tGATT_TCB& tcb, uint16_t cid, uint8_t* p_op_code) {
1543 std::deque<tGATT_CMD_Q>* cl_cmd_q_p;
1544
1545 if (cid == tcb.att_lcid) {
1546 cl_cmd_q_p = &tcb.cl_cmd_q;
1547 } else {
1548 EattChannel* channel =
1549 EattExtension::GetInstance()->FindEattChannelByCid(tcb.peer_bda, cid);
1550 CHECK(channel);
1551 cl_cmd_q_p = &channel->cl_cmd_q_;
1552 }
1553
1554 if (cl_cmd_q_p->empty()) return nullptr;
1555
1556 tGATT_CMD_Q cmd = cl_cmd_q_p->front();
1557 tGATT_CLCB* p_clcb = cmd.p_clcb;
1558 *p_op_code = cmd.op_code;
1559
1560 /* Note: If GATT client deregistered while the ATT request was on the way to
1561 * peer, device p_clcb will be null.
1562 */
1563 if (p_clcb && p_clcb->cid != cid) {
1564 LOG_WARN(" CID does not match (%d!=%d), conn_id=0x%04x", p_clcb->cid, cid,
1565 p_clcb->conn_id);
1566 }
1567
1568 cl_cmd_q_p->pop_front();
1569
1570 return p_clcb;
1571 }
1572
1573 /** Send out the ATT message for write */
gatt_send_write_msg(tGATT_TCB & tcb,tGATT_CLCB * p_clcb,uint8_t op_code,uint16_t handle,uint16_t len,uint16_t offset,uint8_t * p_data)1574 tGATT_STATUS gatt_send_write_msg(tGATT_TCB& tcb, tGATT_CLCB* p_clcb,
1575 uint8_t op_code, uint16_t handle, uint16_t len,
1576 uint16_t offset, uint8_t* p_data) {
1577 tGATT_CL_MSG msg;
1578 msg.attr_value.handle = handle;
1579 msg.attr_value.len = len;
1580 msg.attr_value.offset = offset;
1581 memcpy(msg.attr_value.value, p_data, len);
1582
1583 /* write by handle */
1584 return attp_send_cl_msg(tcb, p_clcb, op_code, &msg);
1585 }
1586
1587 /*******************************************************************************
1588 *
1589 * Function gatt_is_outstanding_msg_in_att_send_queue
1590 *
1591 * Description checks if there is message on the ATT fixed channel to send
1592 *
1593 * Returns true: on success; false otherwise
1594 *
1595 ******************************************************************************/
gatt_is_outstanding_msg_in_att_send_queue(const tGATT_TCB & tcb)1596 bool gatt_is_outstanding_msg_in_att_send_queue(const tGATT_TCB& tcb) {
1597 return (!tcb.cl_cmd_q.empty() && (tcb.cl_cmd_q.front()).to_send);
1598 }
1599 /*******************************************************************************
1600 *
1601 * Function gatt_end_operation
1602 *
1603 * Description This function ends a discovery, send callback and finalize
1604 * some control value.
1605 *
1606 * Returns 16 bits uuid.
1607 *
1608 ******************************************************************************/
gatt_end_operation(tGATT_CLCB * p_clcb,tGATT_STATUS status,void * p_data)1609 void gatt_end_operation(tGATT_CLCB* p_clcb, tGATT_STATUS status, void* p_data) {
1610 tGATT_CL_COMPLETE cb_data;
1611 tGATT_CMPL_CBACK* p_cmpl_cb =
1612 (p_clcb->p_reg) ? p_clcb->p_reg->app_cb.p_cmpl_cb : NULL;
1613 tGATTC_OPTYPE op = p_clcb->operation;
1614 tGATT_DISC_TYPE disc_type = GATT_DISC_MAX;
1615 tGATT_DISC_CMPL_CB* p_disc_cmpl_cb =
1616 (p_clcb->p_reg) ? p_clcb->p_reg->app_cb.p_disc_cmpl_cb : NULL;
1617 uint16_t conn_id;
1618 uint8_t operation;
1619
1620 VLOG(1) << __func__
1621 << StringPrintf(" status=%d op=%d subtype=%d", status,
1622 p_clcb->operation, p_clcb->op_subtype);
1623 memset(&cb_data.att_value, 0, sizeof(tGATT_VALUE));
1624
1625 if (p_cmpl_cb != NULL && p_clcb->operation != 0) {
1626 if (p_clcb->operation == GATTC_OPTYPE_READ) {
1627 cb_data.att_value.handle = p_clcb->s_handle;
1628 cb_data.att_value.len = p_clcb->counter;
1629
1630 if (cb_data.att_value.len > GATT_MAX_ATTR_LEN) {
1631 LOG(WARNING) << __func__
1632 << StringPrintf(" Large cb_data.att_value, size=%d",
1633 cb_data.att_value.len);
1634 cb_data.att_value.len = GATT_MAX_ATTR_LEN;
1635 }
1636
1637 if (p_data && p_clcb->counter)
1638 memcpy(cb_data.att_value.value, p_data, cb_data.att_value.len);
1639 }
1640
1641 if (p_clcb->operation == GATTC_OPTYPE_WRITE) {
1642 memset(&cb_data.att_value, 0, sizeof(tGATT_VALUE));
1643 cb_data.handle = cb_data.att_value.handle = p_clcb->s_handle;
1644 if (p_clcb->op_subtype == GATT_WRITE_PREPARE) {
1645 if (p_data) {
1646 cb_data.att_value = *((tGATT_VALUE*)p_data);
1647 } else {
1648 VLOG(1) << "Rcv Prepare write rsp but no data";
1649 }
1650 }
1651 }
1652
1653 if (p_clcb->operation == GATTC_OPTYPE_CONFIG)
1654 cb_data.mtu = p_clcb->p_tcb->payload_size;
1655
1656 if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY) {
1657 disc_type = static_cast<tGATT_DISC_TYPE>(p_clcb->op_subtype);
1658 }
1659 }
1660
1661 osi_free_and_reset((void**)&p_clcb->p_attr_buf);
1662
1663 operation = p_clcb->operation;
1664 conn_id = p_clcb->conn_id;
1665 gatt_stop_rsp_timer(p_clcb);
1666
1667 gatt_clcb_dealloc(p_clcb);
1668
1669 if (p_disc_cmpl_cb && (op == GATTC_OPTYPE_DISCOVERY))
1670 (*p_disc_cmpl_cb)(conn_id, disc_type, status);
1671 else if (p_cmpl_cb && op)
1672 (*p_cmpl_cb)(conn_id, op, status, &cb_data);
1673 else
1674 LOG(WARNING) << __func__
1675 << StringPrintf(
1676 ": not sent out op=%d p_disc_cmpl_cb:%p p_cmpl_cb:%p",
1677 operation, p_disc_cmpl_cb, p_cmpl_cb);
1678 }
1679
1680 /** This function cleans up the control blocks when L2CAP channel disconnect */
gatt_cleanup_upon_disc(const RawAddress & bda,tGATT_DISCONN_REASON reason,tBT_TRANSPORT transport)1681 void gatt_cleanup_upon_disc(const RawAddress& bda, tGATT_DISCONN_REASON reason,
1682 tBT_TRANSPORT transport) {
1683 VLOG(1) << __func__;
1684
1685 tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(bda, transport);
1686 if (!p_tcb) {
1687 LOG_ERROR(
1688 "Disconnect for unknown connection bd_addr:%s reason:%s transport:%s",
1689 ADDRESS_TO_LOGGABLE_CSTR(bda), gatt_disconnection_reason_text(reason).c_str(),
1690 bt_transport_text(transport).c_str());
1691 return;
1692 }
1693
1694 gatt_set_ch_state(p_tcb, GATT_CH_CLOSE);
1695
1696 /* Notify EATT about disconnection. */
1697 EattExtension::GetInstance()->Disconnect(p_tcb->peer_bda);
1698
1699 for (auto clcb_it = gatt_cb.clcb_queue.begin();
1700 clcb_it != gatt_cb.clcb_queue.end();) {
1701 if (clcb_it->p_tcb != p_tcb) {
1702 ++clcb_it;
1703 continue;
1704 }
1705
1706 gatt_stop_rsp_timer(&(*clcb_it));
1707 VLOG(1) << "found p_clcb conn_id=" << +clcb_it->conn_id;
1708 if (clcb_it->operation == GATTC_OPTYPE_NONE) {
1709 clcb_it = gatt_cb.clcb_queue.erase(clcb_it);
1710 continue;
1711 }
1712
1713 tGATT_CLCB* p_clcb = &(*clcb_it);
1714 ++clcb_it;
1715 gatt_end_operation(p_clcb, GATT_ERROR, NULL);
1716 }
1717
1718 /* Remove the outstanding ATT commnads if any */
1719 p_tcb->cl_cmd_q.clear();
1720
1721 alarm_free(p_tcb->ind_ack_timer);
1722 p_tcb->ind_ack_timer = NULL;
1723 alarm_free(p_tcb->conf_timer);
1724 p_tcb->conf_timer = NULL;
1725 gatt_free_pending_ind(p_tcb);
1726 fixed_queue_free(p_tcb->sr_cmd.multi_rsp_q, NULL);
1727 p_tcb->sr_cmd.multi_rsp_q = NULL;
1728
1729 for (uint8_t i = 0; i < GATT_MAX_APPS; i++) {
1730 tGATT_REG* p_reg = &gatt_cb.cl_rcb[i];
1731 if (p_reg->in_use && p_reg->app_cb.p_conn_cb) {
1732 uint16_t conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if);
1733 (*p_reg->app_cb.p_conn_cb)(p_reg->gatt_if, bda, conn_id,
1734 kGattDisconnected, reason, transport);
1735 }
1736 }
1737
1738 *p_tcb = tGATT_TCB();
1739 VLOG(1) << __func__ << ": exit";
1740 }
1741 /*******************************************************************************
1742 *
1743 * Function gatt_dbg_req_op_name
1744 *
1745 * Description Get op code description name, for debug information.
1746 *
1747 * Returns uint8_t *: name of the operation.
1748 *
1749 ******************************************************************************/
gatt_dbg_op_name(uint8_t op_code)1750 uint8_t* gatt_dbg_op_name(uint8_t op_code) {
1751 uint8_t pseduo_op_code_idx = op_code & (~GATT_WRITE_CMD_MASK);
1752
1753 if (op_code == GATT_CMD_WRITE) {
1754 pseduo_op_code_idx = 0x14; /* just an index to op_code_name */
1755 }
1756
1757 if (op_code == GATT_SIGN_CMD_WRITE) {
1758 pseduo_op_code_idx = 0x15; /* just an index to op_code_name */
1759 }
1760
1761 #define ARR_SIZE(a) (sizeof(a)/sizeof(a[0]))
1762 if (pseduo_op_code_idx < ARR_SIZE(op_code_name))
1763 return (uint8_t*)op_code_name[pseduo_op_code_idx];
1764 else
1765 return (uint8_t*)"Op Code Exceed Max";
1766 #undef ARR_SIZE
1767 }
1768
1769 /** Remove the application interface for the specified background device */
gatt_auto_connect_dev_remove(tGATT_IF gatt_if,const RawAddress & bd_addr)1770 bool gatt_auto_connect_dev_remove(tGATT_IF gatt_if, const RawAddress& bd_addr) {
1771 tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE);
1772 if (p_tcb) gatt_update_app_use_link_flag(gatt_if, p_tcb, false, false);
1773 if (bluetooth::common::init_flags::
1774 use_unified_connection_manager_is_enabled()) {
1775 bluetooth::connection::GetConnectionManager().remove_background_connection(
1776 gatt_if, bluetooth::connection::ResolveRawAddress(bd_addr));
1777 // TODO(aryarahul): handle failure case
1778 return true;
1779 } else {
1780 return connection_manager::background_connect_remove(gatt_if, bd_addr);
1781 }
1782 }
1783