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