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