1 /******************************************************************************
2 *
3 * Copyright 1999-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 interface functions
22 *
23 ******************************************************************************/
24 #define LOG_TAG "gatt_api"
25
26 #include "stack/include/gatt_api.h"
27
28 #include <base/strings/string_number_conversions.h>
29 #include <bluetooth/log.h>
30 #include <com_android_bluetooth_flags.h>
31
32 #include <string>
33
34 #include "internal_include/bt_target.h"
35 #include "internal_include/stack_config.h"
36 #include "l2c_api.h"
37 #include "os/system_properties.h"
38 #include "osi/include/allocator.h"
39 #include "rust/src/connection/ffi/connection_shim.h"
40 #include "stack/arbiter/acl_arbiter.h"
41 #include "stack/btm/btm_dev.h"
42 #include "stack/gatt/connection_manager.h"
43 #include "stack/gatt/gatt_int.h"
44 #include "stack/include/bt_hdr.h"
45 #include "stack/include/bt_uuid16.h"
46 #include "stack/include/l2cap_acl_interface.h"
47 #include "stack/include/l2cdefs.h"
48 #include "stack/include/sdp_api.h"
49 #include "types/bluetooth/uuid.h"
50 #include "types/bt_transport.h"
51 #include "types/raw_address.h"
52
53 using namespace bluetooth::legacy::stack::sdp;
54 using namespace bluetooth;
55
56 using bluetooth::Uuid;
57
58 /**
59 * Add a service handle range to the list in descending order of the start
60 * handle. Return reference to the newly added element.
61 **/
gatt_add_an_item_to_list(uint16_t s_handle)62 tGATT_HDL_LIST_ELEM& gatt_add_an_item_to_list(uint16_t s_handle) {
63 auto lst_ptr = gatt_cb.hdl_list_info;
64 auto it = lst_ptr->begin();
65 for (; it != lst_ptr->end(); it++) {
66 if (s_handle > it->asgn_range.s_handle) break;
67 }
68
69 auto rit = lst_ptr->emplace(it);
70 return *rit;
71 }
72
73 /*****************************************************************************
74 *
75 * GATT SERVER API
76 *
77 *****************************************************************************/
78 /*******************************************************************************
79 *
80 * Function GATTS_NVRegister
81 *
82 * Description Application manager calls this function to register for
83 * NV save callback function. There can be one and only one
84 * NV save callback function.
85 *
86 * Parameter p_cb_info : callback information
87 *
88 * Returns true if registered OK, else false
89 *
90 ******************************************************************************/
GATTS_NVRegister(tGATT_APPL_INFO * p_cb_info)91 bool GATTS_NVRegister(tGATT_APPL_INFO* p_cb_info) {
92 bool status = false;
93 if (p_cb_info) {
94 gatt_cb.cb_info = *p_cb_info;
95 status = true;
96 gatt_init_srv_chg();
97 }
98
99 return status;
100 }
101
compute_service_size(btgatt_db_element_t * service,int count)102 static uint16_t compute_service_size(btgatt_db_element_t* service, int count) {
103 int db_size = 0;
104 btgatt_db_element_t* el = service;
105
106 for (int i = 0; i < count; i++, el++)
107 if (el->type == BTGATT_DB_PRIMARY_SERVICE ||
108 el->type == BTGATT_DB_SECONDARY_SERVICE ||
109 el->type == BTGATT_DB_DESCRIPTOR ||
110 el->type == BTGATT_DB_INCLUDED_SERVICE) {
111 db_size += 1;
112 } else if (el->type == BTGATT_DB_CHARACTERISTIC) {
113 db_size += 2;
114
115 // if present, Characteristic Extended Properties takes one handle
116 if (el->properties & GATT_CHAR_PROP_BIT_EXT_PROP) db_size++;
117 } else {
118 log::error("Unknown element type: {}", el->type);
119 }
120
121 return db_size;
122 }
123
is_gatt_attr_type(const Uuid & uuid)124 static bool is_gatt_attr_type(const Uuid& uuid) {
125 if (uuid == Uuid::From16Bit(GATT_UUID_PRI_SERVICE) ||
126 uuid == Uuid::From16Bit(GATT_UUID_SEC_SERVICE) ||
127 uuid == Uuid::From16Bit(GATT_UUID_INCLUDE_SERVICE) ||
128 uuid == Uuid::From16Bit(GATT_UUID_CHAR_DECLARE)) {
129 return true;
130 }
131 return false;
132 }
133
134 /** Update the the last service info for the service list info */
gatt_update_last_srv_info()135 static void gatt_update_last_srv_info() {
136 gatt_cb.last_service_handle = 0;
137
138 for (tGATT_SRV_LIST_ELEM& el : *gatt_cb.srv_list_info) {
139 gatt_cb.last_service_handle = el.s_hdl;
140 }
141 }
142
143 /** Update database hash and client status */
gatt_update_for_database_change()144 static void gatt_update_for_database_change() {
145 gatt_cb.database_hash = gatts_calculate_database_hash(gatt_cb.srv_list_info);
146
147 uint8_t i = 0;
148 for (i = 0; i < GATT_MAX_PHY_CHANNEL; i++) {
149 tGATT_TCB& tcb = gatt_cb.tcb[i];
150 if (tcb.in_use) gatt_sr_update_cl_status(tcb, /* chg_aware= */ false);
151 }
152 }
153
154 /*******************************************************************************
155 *
156 * Function GATTS_AddService
157 *
158 * Description This function is called to add GATT service.
159 *
160 * Parameter gatt_if : application if
161 * service : pseudo-representation of service and it's content
162 * count : size of service
163 *
164 * Returns on success GATT_SERVICE_STARTED is returned, and
165 * attribute_handle field inside service elements are filled.
166 * on error error status is returned.
167 *
168 ******************************************************************************/
GATTS_AddService(tGATT_IF gatt_if,btgatt_db_element_t * service,int count)169 tGATT_STATUS GATTS_AddService(tGATT_IF gatt_if, btgatt_db_element_t* service,
170 int count) {
171 uint16_t s_hdl = 0;
172 bool save_hdl = false;
173 tGATT_REG* p_reg = gatt_get_regcb(gatt_if);
174
175 bool is_pri = (service->type == BTGATT_DB_PRIMARY_SERVICE) ? true : false;
176 Uuid svc_uuid = service->uuid;
177
178 log::info("");
179
180 if (!p_reg) {
181 log::error("Invalid gatt_if={}", gatt_if);
182 return GATT_INTERNAL_ERROR;
183 }
184
185 uint16_t num_handles = compute_service_size(service, count);
186
187 if (svc_uuid == Uuid::From16Bit(UUID_SERVCLASS_GATT_SERVER)) {
188 s_hdl = gatt_cb.hdl_cfg.gatt_start_hdl;
189 } else if (svc_uuid == Uuid::From16Bit(UUID_SERVCLASS_GAP_SERVER)) {
190 s_hdl = gatt_cb.hdl_cfg.gap_start_hdl;
191 } else if (svc_uuid == Uuid::From16Bit(UUID_SERVCLASS_GMCS_SERVER)) {
192 s_hdl = gatt_cb.hdl_cfg.gmcs_start_hdl;
193 } else if (svc_uuid == Uuid::From16Bit(UUID_SERVCLASS_GTBS_SERVER)) {
194 s_hdl = gatt_cb.hdl_cfg.gtbs_start_hdl;
195 } else if (svc_uuid == Uuid::From16Bit(UUID_SERVCLASS_TMAS_SERVER)) {
196 s_hdl = gatt_cb.hdl_cfg.tmas_start_hdl;
197 } else {
198 if (!gatt_cb.hdl_list_info->empty()) {
199 s_hdl = gatt_cb.hdl_list_info->front().asgn_range.e_handle + 1;
200 }
201
202 if (s_hdl < gatt_cb.hdl_cfg.app_start_hdl)
203 s_hdl = gatt_cb.hdl_cfg.app_start_hdl;
204
205 save_hdl = true;
206 }
207
208 /* check for space */
209 if (num_handles > (0xFFFF - s_hdl + 1)) {
210 log::error("no handles, s_hdl={} needed={}", s_hdl, num_handles);
211 return GATT_INTERNAL_ERROR;
212 }
213
214 tGATT_HDL_LIST_ELEM& list = gatt_add_an_item_to_list(s_hdl);
215 list.asgn_range.app_uuid128 = p_reg->app_uuid128;
216 list.asgn_range.svc_uuid = svc_uuid;
217 list.asgn_range.s_handle = s_hdl;
218 list.asgn_range.e_handle = s_hdl + num_handles - 1;
219 list.asgn_range.is_primary = is_pri;
220
221 if (save_hdl) {
222 if (gatt_cb.cb_info.p_nv_save_callback)
223 (*gatt_cb.cb_info.p_nv_save_callback)(true, &list.asgn_range);
224 }
225
226 gatts_init_service_db(list.svc_db, svc_uuid, is_pri, s_hdl, num_handles);
227
228 log::verbose(
229 "handles needed={}, s_hdl=0x{:x}, e_hdl=0x{:x}, uuid={}, is_primary={}",
230 num_handles, list.asgn_range.s_handle, list.asgn_range.e_handle,
231 list.asgn_range.svc_uuid, list.asgn_range.is_primary);
232
233 service->attribute_handle = s_hdl;
234
235 btgatt_db_element_t* el = service + 1;
236 for (int i = 0; i < count - 1; i++, el++) {
237 const Uuid& uuid = el->uuid;
238
239 if (el->type == BTGATT_DB_CHARACTERISTIC) {
240 /* data validity checking */
241 if (((el->properties & GATT_CHAR_PROP_BIT_AUTH) &&
242 !(el->permissions & GATT_WRITE_SIGNED_PERM)) ||
243 ((el->permissions & GATT_WRITE_SIGNED_PERM) &&
244 !(el->properties & GATT_CHAR_PROP_BIT_AUTH))) {
245 log::verbose("Invalid configuration property=0x{:x}, perm=0x{:x}",
246 el->properties, el->permissions);
247 return GATT_INTERNAL_ERROR;
248 }
249
250 if (is_gatt_attr_type(uuid)) {
251 log::error(
252 "attempt to add characteristic with UUID equal to GATT Attribute "
253 "Type {}",
254 uuid);
255 return GATT_INTERNAL_ERROR;
256 }
257
258 el->attribute_handle = gatts_add_characteristic(
259 list.svc_db, el->permissions, el->properties, uuid);
260
261 // add characteristic extended properties descriptor if needed
262 if (el->properties & GATT_CHAR_PROP_BIT_EXT_PROP) {
263 gatts_add_char_ext_prop_descr(list.svc_db, el->extended_properties);
264 }
265
266 } else if (el->type == BTGATT_DB_DESCRIPTOR) {
267 if (is_gatt_attr_type(uuid)) {
268 log::error(
269 "attempt to add descriptor with UUID equal to GATT Attribute Type "
270 "{}",
271 uuid);
272 return GATT_INTERNAL_ERROR;
273 }
274
275 el->attribute_handle =
276 gatts_add_char_descr(list.svc_db, el->permissions, uuid);
277 } else if (el->type == BTGATT_DB_INCLUDED_SERVICE) {
278 tGATT_HDL_LIST_ELEM* p_incl_decl;
279 p_incl_decl = gatt_find_hdl_buffer_by_handle(el->attribute_handle);
280 if (p_incl_decl == nullptr) {
281 log::verbose("Included Service not created");
282 return GATT_INTERNAL_ERROR;
283 }
284
285 el->attribute_handle = gatts_add_included_service(
286 list.svc_db, p_incl_decl->asgn_range.s_handle,
287 p_incl_decl->asgn_range.e_handle, p_incl_decl->asgn_range.svc_uuid);
288 }
289 }
290
291 log::info("service parsed correctly, now starting");
292
293 /*this is a new application service start */
294
295 // find a place for this service in the list
296 auto lst_ptr = gatt_cb.srv_list_info;
297 auto it = lst_ptr->begin();
298 for (; it != lst_ptr->end(); it++) {
299 if (list.asgn_range.s_handle < it->s_hdl) break;
300 }
301 auto rit = lst_ptr->emplace(it);
302
303 tGATT_SRV_LIST_ELEM& elem = *rit;
304 elem.gatt_if = gatt_if;
305 elem.s_hdl = list.asgn_range.s_handle;
306 elem.e_hdl = list.asgn_range.e_handle;
307 elem.p_db = &list.svc_db;
308 elem.is_primary = list.asgn_range.is_primary;
309
310 elem.app_uuid = list.asgn_range.app_uuid128;
311 elem.type = list.asgn_range.is_primary ? GATT_UUID_PRI_SERVICE
312 : GATT_UUID_SEC_SERVICE;
313
314 if (elem.type == GATT_UUID_PRI_SERVICE && gatt_cb.over_br_enabled) {
315 Uuid* p_uuid = gatts_get_service_uuid(elem.p_db);
316 if (*p_uuid != Uuid::From16Bit(UUID_SERVCLASS_GMCS_SERVER) &&
317 *p_uuid != Uuid::From16Bit(UUID_SERVCLASS_GTBS_SERVER)) {
318 elem.sdp_handle = gatt_add_sdp_record(*p_uuid, elem.s_hdl, elem.e_hdl);
319 } else {
320 elem.sdp_handle = 0;
321 }
322 } else {
323 elem.sdp_handle = 0;
324 }
325
326 gatt_update_last_srv_info();
327
328 log::verbose(
329 "allocated el s_hdl=0x{:x}, e_hdl=0x{:x}, type=0x{:x}, sdp_hdl=0x{:x}",
330 elem.s_hdl, elem.e_hdl, elem.type, elem.sdp_handle);
331
332 gatt_update_for_database_change();
333 gatt_proc_srv_chg();
334
335 return GATT_SERVICE_STARTED;
336 }
337
is_active_service(const Uuid & app_uuid128,Uuid * p_svc_uuid,uint16_t start_handle)338 bool is_active_service(const Uuid& app_uuid128, Uuid* p_svc_uuid,
339 uint16_t start_handle) {
340 for (auto& info : *gatt_cb.srv_list_info) {
341 Uuid* p_this_uuid = gatts_get_service_uuid(info.p_db);
342
343 if (p_this_uuid && app_uuid128 == info.app_uuid &&
344 *p_svc_uuid == *p_this_uuid && (start_handle == info.s_hdl)) {
345 log::error("Active Service Found: {}", *p_svc_uuid);
346 return true;
347 }
348 }
349 return false;
350 }
351
352 /*******************************************************************************
353 *
354 * Function GATTS_DeleteService
355 *
356 * Description This function is called to delete a service.
357 *
358 * Parameter gatt_if : application interface
359 * p_svc_uuid : service UUID
360 * start_handle : start handle of the service
361 *
362 * Returns true if the operation succeeded, false if the handle block
363 * was not found.
364 *
365 ******************************************************************************/
GATTS_DeleteService(tGATT_IF gatt_if,Uuid * p_svc_uuid,uint16_t svc_inst)366 bool GATTS_DeleteService(tGATT_IF gatt_if, Uuid* p_svc_uuid,
367 uint16_t svc_inst) {
368 log::verbose("");
369
370 tGATT_REG* p_reg = gatt_get_regcb(gatt_if);
371 if (p_reg == NULL) {
372 log::error("Application not found");
373 return false;
374 }
375
376 auto it =
377 gatt_find_hdl_buffer_by_app_id(p_reg->app_uuid128, p_svc_uuid, svc_inst);
378 if (it == gatt_cb.hdl_list_info->end()) {
379 log::error("No Service found");
380 return false;
381 }
382
383 if (is_active_service(p_reg->app_uuid128, p_svc_uuid, svc_inst)) {
384 GATTS_StopService(it->asgn_range.s_handle);
385 }
386
387 gatt_update_for_database_change();
388 gatt_proc_srv_chg();
389
390 log::verbose("released handles s_hdl=0x{:x}, e_hdl=0x{:x}",
391 it->asgn_range.s_handle, it->asgn_range.e_handle);
392
393 if ((it->asgn_range.s_handle >= gatt_cb.hdl_cfg.app_start_hdl) &&
394 gatt_cb.cb_info.p_nv_save_callback)
395 (*gatt_cb.cb_info.p_nv_save_callback)(false, &it->asgn_range);
396
397 gatt_cb.hdl_list_info->erase(it);
398 return true;
399 }
400
401 /*******************************************************************************
402 *
403 * Function GATTS_StopService
404 *
405 * Description This function is called to stop a service
406 *
407 * Parameter service_handle : this is the start handle of a service
408 *
409 * Returns None.
410 *
411 ******************************************************************************/
GATTS_StopService(uint16_t service_handle)412 void GATTS_StopService(uint16_t service_handle) {
413 log::info("service = 0x{:x}", service_handle);
414
415 auto it = gatt_sr_find_i_rcb_by_handle(service_handle);
416 if (it == gatt_cb.srv_list_info->end()) {
417 log::error("service_handle=0x{:x} is not in use", service_handle);
418 return;
419 }
420
421 if (it->sdp_handle) {
422 if (!get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(it->sdp_handle)) {
423 log::warn("Unable to delete record handle:{}", it->sdp_handle);
424 }
425 }
426
427 gatt_cb.srv_list_info->erase(it);
428 gatt_update_last_srv_info();
429 }
430 /*******************************************************************************
431 *
432 * Function GATTs_HandleValueIndication
433 *
434 * Description This function sends a handle value indication to a client.
435 *
436 * Parameter conn_id: connection identifier.
437 * attr_handle: Attribute handle of this handle value
438 * indication.
439 * val_len: Length of the indicated attribute value.
440 * p_val: Pointer to the indicated attribute value data.
441 *
442 * Returns GATT_SUCCESS if successfully sent or queued; otherwise error
443 * code.
444 *
445 ******************************************************************************/
GATTS_HandleValueIndication(uint16_t conn_id,uint16_t attr_handle,uint16_t val_len,uint8_t * p_val)446 tGATT_STATUS GATTS_HandleValueIndication(uint16_t conn_id, uint16_t attr_handle,
447 uint16_t val_len, uint8_t* p_val) {
448 tGATT_IF gatt_if = GATT_GET_GATT_IF(conn_id);
449 uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id);
450 tGATT_REG* p_reg = gatt_get_regcb(gatt_if);
451 tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(tcb_idx);
452
453 log::verbose("");
454 if ((p_reg == NULL) || (p_tcb == NULL)) {
455 log::error("Unknown conn_id=0x{:x}", conn_id);
456 return (tGATT_STATUS)GATT_INVALID_CONN_ID;
457 }
458
459 if (!GATT_HANDLE_IS_VALID(attr_handle)) return GATT_ILLEGAL_PARAMETER;
460
461 tGATT_VALUE indication;
462 indication.conn_id = conn_id;
463 indication.handle = attr_handle;
464 indication.len = val_len;
465 memcpy(indication.value, p_val, val_len);
466 indication.auth_req = GATT_AUTH_REQ_NONE;
467
468 uint16_t* indicate_handle_p = NULL;
469 uint16_t cid;
470
471 if (!gatt_tcb_get_cid_available_for_indication(p_tcb, p_reg->eatt_support,
472 &indicate_handle_p, &cid)) {
473 log::verbose("Add a pending indication");
474 gatt_add_pending_ind(p_tcb, &indication);
475 return GATT_SUCCESS;
476 }
477
478 tGATT_SR_MSG gatt_sr_msg;
479 gatt_sr_msg.attr_value = indication;
480
481 uint16_t payload_size = gatt_tcb_get_payload_size(*p_tcb, cid);
482 BT_HDR* p_msg = attp_build_sr_msg(*p_tcb, GATT_HANDLE_VALUE_IND, &gatt_sr_msg,
483 payload_size);
484 if (!p_msg) return GATT_NO_RESOURCES;
485
486 tGATT_STATUS cmd_status = attp_send_sr_msg(*p_tcb, cid, p_msg);
487 if (cmd_status == GATT_SUCCESS || cmd_status == GATT_CONGESTED) {
488 *indicate_handle_p = indication.handle;
489 gatt_start_conf_timer(p_tcb, cid);
490 }
491 return cmd_status;
492 }
493
494 #if (GATT_UPPER_TESTER_MULT_VARIABLE_LENGTH_NOTIF == TRUE)
GATTS_HandleMultipleValueNotification(tGATT_TCB * p_tcb,std::vector<tGATT_VALUE> gatt_notif_vector)495 static tGATT_STATUS GATTS_HandleMultipleValueNotification(
496 tGATT_TCB* p_tcb, std::vector<tGATT_VALUE> gatt_notif_vector) {
497 log::info("");
498
499 uint16_t cid = gatt_tcb_get_att_cid(*p_tcb, true /* eatt support */);
500 uint16_t payload_size = gatt_tcb_get_payload_size(*p_tcb, cid);
501
502 /* TODO Handle too big packet size here. Not needed now for testing. */
503 /* Just build the message. */
504 BT_HDR* p_buf =
505 (BT_HDR*)osi_malloc(sizeof(BT_HDR) + payload_size + L2CAP_MIN_OFFSET);
506
507 uint8_t* p = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET;
508 UINT8_TO_STREAM(p, GATT_HANDLE_MULTI_VALUE_NOTIF);
509 p_buf->offset = L2CAP_MIN_OFFSET;
510 p_buf->len = 1;
511 for (auto notif : gatt_notif_vector) {
512 log::info("Adding handle: 0x{:04x}, val len {}", notif.handle, notif.len);
513 UINT16_TO_STREAM(p, notif.handle);
514 p_buf->len += 2;
515 UINT16_TO_STREAM(p, notif.len);
516 p_buf->len += 2;
517 ARRAY_TO_STREAM(p, notif.value, notif.len);
518 p_buf->len += notif.len;
519 }
520
521 log::info("Total len: {}", p_buf->len);
522
523 return attp_send_sr_msg(*p_tcb, cid, p_buf);
524 }
525 #endif
526 /*******************************************************************************
527 *
528 * Function GATTS_HandleValueNotification
529 *
530 * Description This function sends a handle value notification to a client.
531 *
532 * Parameter conn_id: connection identifier.
533 * attr_handle: Attribute handle of this handle value
534 * indication.
535 * val_len: Length of the indicated attribute value.
536 * p_val: Pointer to the indicated attribute value data.
537 *
538 * Returns GATT_SUCCESS if successfully sent; otherwise error code.
539 *
540 ******************************************************************************/
GATTS_HandleValueNotification(uint16_t conn_id,uint16_t attr_handle,uint16_t val_len,uint8_t * p_val)541 tGATT_STATUS GATTS_HandleValueNotification(uint16_t conn_id,
542 uint16_t attr_handle,
543 uint16_t val_len, uint8_t* p_val) {
544 tGATT_VALUE notif;
545 tGATT_IF gatt_if = GATT_GET_GATT_IF(conn_id);
546 uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id);
547 tGATT_REG* p_reg = gatt_get_regcb(gatt_if);
548 tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(tcb_idx);
549 #if (GATT_UPPER_TESTER_MULT_VARIABLE_LENGTH_NOTIF == TRUE)
550 static uint8_t cached_tcb_idx = 0xFF;
551 static std::vector<tGATT_VALUE> gatt_notif_vector(2);
552 tGATT_VALUE* p_gatt_notif;
553 #endif
554
555 log::verbose("");
556
557 if ((p_reg == NULL) || (p_tcb == NULL)) {
558 log::error("Unknown conn_id: {}", conn_id);
559 return (tGATT_STATUS)GATT_INVALID_CONN_ID;
560 }
561
562 if (!GATT_HANDLE_IS_VALID(attr_handle)) {
563 return GATT_ILLEGAL_PARAMETER;
564 }
565
566 #if (GATT_UPPER_TESTER_MULT_VARIABLE_LENGTH_NOTIF == TRUE)
567 /* Upper tester for Multiple Value length notifications */
568 if (stack_config_get_interface()->get_pts_force_eatt_for_notifications() &&
569 gatt_sr_is_cl_multi_variable_len_notif_supported(*p_tcb)) {
570 if (cached_tcb_idx == 0xFF) {
571 log::info("Storing first notification");
572 p_gatt_notif = &gatt_notif_vector[0];
573
574 p_gatt_notif->handle = attr_handle;
575 p_gatt_notif->len = val_len;
576 std::copy(p_val, p_val + val_len, p_gatt_notif->value);
577
578 notif.auth_req = GATT_AUTH_REQ_NONE;
579
580 cached_tcb_idx = tcb_idx;
581 return GATT_SUCCESS;
582 }
583
584 if (cached_tcb_idx == tcb_idx) {
585 log::info("Storing second notification");
586 cached_tcb_idx = 0xFF;
587 p_gatt_notif = &gatt_notif_vector[1];
588
589 p_gatt_notif->handle = attr_handle;
590 p_gatt_notif->len = val_len;
591 std::copy(p_val, p_val + val_len, p_gatt_notif->value);
592
593 notif.auth_req = GATT_AUTH_REQ_NONE;
594
595 return GATTS_HandleMultipleValueNotification(p_tcb, gatt_notif_vector);
596 }
597
598 log::error("PTS Mode: Invalid tcb_idx: {}, cached_tcb_idx: {}", tcb_idx,
599 cached_tcb_idx);
600 }
601 #endif
602
603 memset(¬if, 0, sizeof(notif));
604 notif.handle = attr_handle;
605 notif.len = val_len;
606 memcpy(notif.value, p_val, val_len);
607 notif.auth_req = GATT_AUTH_REQ_NONE;
608
609 tGATT_STATUS cmd_sent;
610 tGATT_SR_MSG gatt_sr_msg;
611 gatt_sr_msg.attr_value = notif;
612
613 uint16_t cid = gatt_tcb_get_att_cid(*p_tcb, p_reg->eatt_support);
614 uint16_t payload_size = gatt_tcb_get_payload_size(*p_tcb, cid);
615 BT_HDR* p_buf = attp_build_sr_msg(*p_tcb, GATT_HANDLE_VALUE_NOTIF,
616 &gatt_sr_msg, payload_size);
617
618 if (p_buf != NULL) {
619 cmd_sent = attp_send_sr_msg(*p_tcb, cid, p_buf);
620 } else {
621 cmd_sent = GATT_NO_RESOURCES;
622 }
623 return cmd_sent;
624 }
625
626 /*******************************************************************************
627 *
628 * Function GATTS_SendRsp
629 *
630 * Description This function sends the server response to client.
631 *
632 * Parameter conn_id: connection identifier.
633 * trans_id: transaction id
634 * status: response status
635 * p_msg: pointer to message parameters structure.
636 *
637 * Returns GATT_SUCCESS if successfully sent; otherwise error code.
638 *
639 ******************************************************************************/
GATTS_SendRsp(uint16_t conn_id,uint32_t trans_id,tGATT_STATUS status,tGATTS_RSP * p_msg)640 tGATT_STATUS GATTS_SendRsp(uint16_t conn_id, uint32_t trans_id,
641 tGATT_STATUS status, tGATTS_RSP* p_msg) {
642 tGATT_IF gatt_if = GATT_GET_GATT_IF(conn_id);
643 uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id);
644 tGATT_REG* p_reg = gatt_get_regcb(gatt_if);
645 tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(tcb_idx);
646
647 log::verbose("conn_id=0x{:x}, trans_id=0x{:x}, status=0x{:x}", conn_id,
648 trans_id, static_cast<uint8_t>(status));
649
650 if ((p_reg == NULL) || (p_tcb == NULL)) {
651 log::error("Unknown conn_id=0x{:x}", conn_id);
652 return (tGATT_STATUS)GATT_INVALID_CONN_ID;
653 }
654
655 tGATT_SR_CMD* sr_res_p = gatt_sr_get_cmd_by_trans_id(p_tcb, trans_id);
656
657 if (!sr_res_p) {
658 log::error("conn_id=0x{:x} waiting for other op_code", conn_id);
659 return (GATT_WRONG_STATE);
660 }
661
662 /* Process App response */
663 return gatt_sr_process_app_rsp(*p_tcb, gatt_if, trans_id, sr_res_p->op_code,
664 status, p_msg, sr_res_p);
665 }
666
667 /******************************************************************************/
668 /* GATT Profile Srvr Functions */
669 /******************************************************************************/
670
671 /******************************************************************************/
672 /* */
673 /* GATT CLIENT APIs */
674 /* */
675 /******************************************************************************/
676
677 /*******************************************************************************
678 *
679 * Function GATTC_ConfigureMTU
680 *
681 * Description This function is called to configure the ATT MTU size.
682 *
683 * Parameters conn_id: connection identifier.
684 * mtu - attribute MTU size..
685 *
686 * Returns GATT_SUCCESS if command started successfully.
687 *
688 ******************************************************************************/
GATTC_ConfigureMTU(uint16_t conn_id,uint16_t mtu)689 tGATT_STATUS GATTC_ConfigureMTU(uint16_t conn_id, uint16_t mtu) {
690 tGATT_IF gatt_if = GATT_GET_GATT_IF(conn_id);
691 uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id);
692 tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(tcb_idx);
693 tGATT_REG* p_reg = gatt_get_regcb(gatt_if);
694
695 if ((p_tcb == NULL) || (p_reg == NULL) || (mtu < GATT_DEF_BLE_MTU_SIZE) ||
696 (mtu > GATT_MAX_MTU_SIZE)) {
697 log::warn(
698 "Unable to configure ATT mtu size illegal parameter conn_id:{} mtu:{} "
699 "tcb:{} reg:{}",
700 conn_id, mtu, (p_tcb == nullptr) ? "BAD" : "ok",
701 (p_reg == nullptr) ? "BAD" : "ok");
702 return GATT_ILLEGAL_PARAMETER;
703 }
704
705 /* Validate that the link is BLE, not BR/EDR */
706 if (p_tcb->transport != BT_TRANSPORT_LE) {
707 return GATT_REQ_NOT_SUPPORTED;
708 }
709
710 tGATT_CLCB* p_clcb = gatt_clcb_alloc(conn_id);
711 if (!p_clcb) {
712 log::warn("Unable to allocate connection link control block");
713 return GATT_NO_RESOURCES;
714 }
715
716 /* For this request only ATT CID is valid */
717 p_clcb->cid = L2CAP_ATT_CID;
718 p_clcb->operation = GATTC_OPTYPE_CONFIG;
719 tGATT_CL_MSG gatt_cl_msg;
720
721 bluetooth::shim::arbiter::GetArbiter().OnOutgoingMtuReq(tcb_idx);
722
723 /* Since GATT MTU Exchange can be done only once, and it is impossible to
724 * predict what MTU will be requested by other applications, let's use
725 * default MTU in the request. */
726 gatt_cl_msg.mtu = gatt_get_local_mtu();
727
728 log::info("Configuring ATT mtu size conn_id:{} mtu:{} user mtu {}", conn_id,
729 gatt_cl_msg.mtu, mtu);
730
731 auto result =
732 attp_send_cl_msg(*p_clcb->p_tcb, p_clcb, GATT_REQ_MTU, &gatt_cl_msg);
733 if (result == GATT_SUCCESS) {
734 p_clcb->p_tcb->pending_user_mtu_exchange_value = mtu;
735 }
736 return result;
737 }
738
739 /******************************************************************************
740 *
741 * Function GATTC_TryMtuRequest
742 *
743 * Description This function shall be called before calling
744 * GATTC_ConfigureMTU in order to check if operation is
745 * available to do.
746 *
747 * Parameters remote_bda : peer device address. (input)
748 * transport : physical transport of the GATT connection
749 * (BR/EDR or LE) (input)
750 * conn_id : connection id (input)
751 * current_mtu: current mtu on the link (output)
752 *
753 * Returns tGATTC_TryMtuRequestResult:
754 * - MTU_EXCHANGE_NOT_DONE_YET: There was no MTU Exchange
755 * procedure on the link. User can call GATTC_ConfigureMTU
756 * now.
757 * - MTU_EXCHANGE_NOT_ALLOWED : Not allowed for BR/EDR or if
758 * link does not exist
759 * - MTU_EXCHANGE_ALREADY_DONE: MTU Exchange is done. MTU
760 * should be taken from current_mtu
761 * - MTU_EXCHANGE_IN_PROGRESS : Other use is doing MTU
762 * Exchange. Conn_id is stored for result.
763 *
764 ******************************************************************************/
GATTC_TryMtuRequest(const RawAddress & remote_bda,tBT_TRANSPORT transport,uint16_t conn_id,uint16_t * current_mtu)765 tGATTC_TryMtuRequestResult GATTC_TryMtuRequest(const RawAddress& remote_bda,
766 tBT_TRANSPORT transport,
767 uint16_t conn_id,
768 uint16_t* current_mtu) {
769 log::info("{} conn_id=0x{:04x}", remote_bda, conn_id);
770 *current_mtu = GATT_DEF_BLE_MTU_SIZE;
771
772 if (transport == BT_TRANSPORT_BR_EDR) {
773 log::error("Device {} connected over BR/EDR", remote_bda);
774 return MTU_EXCHANGE_NOT_ALLOWED;
775 }
776
777 tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(remote_bda, transport);
778 if (!p_tcb) {
779 log::error("Device {} is not connected", remote_bda);
780 return MTU_EXCHANGE_DEVICE_DISCONNECTED;
781 }
782
783 if (gatt_is_pending_mtu_exchange(p_tcb)) {
784 log::debug("Continue MTU pending for other client.");
785 /* MTU Exchange is in progress, started by other GATT Client.
786 * Wait until it is completed.
787 */
788 gatt_set_conn_id_waiting_for_mtu_exchange(p_tcb, conn_id);
789 return MTU_EXCHANGE_IN_PROGRESS;
790 }
791
792 uint16_t mtu = gatt_get_mtu(remote_bda, transport);
793 if (mtu == GATT_DEF_BLE_MTU_SIZE || mtu == 0) {
794 log::debug("MTU not yet updated for {}", remote_bda);
795 return MTU_EXCHANGE_NOT_DONE_YET;
796 }
797
798 *current_mtu = mtu;
799 return MTU_EXCHANGE_ALREADY_DONE;
800 }
801
802 /*******************************************************************************
803 * Function GATTC_UpdateUserAttMtuIfNeeded
804 *
805 * Description This function to be called when user requested MTU after
806 * MTU Exchange has been already done. This will update data
807 * length in the controller.
808 *
809 * Parameters remote_bda : peer device address. (input)
810 * transport : physical transport of the GATT connection
811 * (BR/EDR or LE) (input)
812 * user_mtu: user request mtu
813 *
814 ******************************************************************************/
GATTC_UpdateUserAttMtuIfNeeded(const RawAddress & remote_bda,tBT_TRANSPORT transport,uint16_t user_mtu)815 void GATTC_UpdateUserAttMtuIfNeeded(const RawAddress& remote_bda,
816 tBT_TRANSPORT transport,
817 uint16_t user_mtu) {
818 log::info("{}, mtu={}", remote_bda, user_mtu);
819 tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(remote_bda, transport);
820 if (!p_tcb) {
821 log::warn("Transport control block not found");
822 return;
823 }
824
825 log::info("{}, current mtu: {}, max_user_mtu:{}, user_mtu: {}", remote_bda,
826 p_tcb->payload_size, p_tcb->max_user_mtu, user_mtu);
827
828 if (p_tcb->payload_size < user_mtu) {
829 log::info("User requested more than what GATT can handle. Trim it.");
830 user_mtu = p_tcb->payload_size;
831 }
832
833 if (p_tcb->max_user_mtu >= user_mtu) {
834 return;
835 }
836
837 p_tcb->max_user_mtu = user_mtu;
838 BTM_SetBleDataLength(remote_bda, user_mtu);
839 }
840
GATTC_GetAndRemoveListOfConnIdsWaitingForMtuRequest(const RawAddress & remote_bda)841 std::list<uint16_t> GATTC_GetAndRemoveListOfConnIdsWaitingForMtuRequest(
842 const RawAddress& remote_bda) {
843 std::list result = std::list<uint16_t>();
844
845 tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(remote_bda, BT_TRANSPORT_LE);
846 if (!p_tcb || p_tcb->conn_ids_waiting_for_mtu_exchange.empty()) {
847 return result;
848 }
849
850 result.swap(p_tcb->conn_ids_waiting_for_mtu_exchange);
851 return result;
852 }
853
854 /*******************************************************************************
855 *
856 * Function GATTC_Discover
857 *
858 * Description This function is called to do a discovery procedure on ATT
859 * server.
860 *
861 * Parameters conn_id: connection identifier.
862 * disc_type:discovery type.
863 * start_handle and end_handle: range of handles for discovery
864 * uuid: uuid to discovery. set to Uuid::kEmpty for requests
865 * that don't need it
866 *
867 * Returns GATT_SUCCESS if command received/sent successfully.
868 *
869 ******************************************************************************/
GATTC_Discover(uint16_t conn_id,tGATT_DISC_TYPE disc_type,uint16_t start_handle,uint16_t end_handle,const Uuid & uuid)870 tGATT_STATUS GATTC_Discover(uint16_t conn_id, tGATT_DISC_TYPE disc_type,
871 uint16_t start_handle, uint16_t end_handle,
872 const Uuid& uuid) {
873 tGATT_IF gatt_if = GATT_GET_GATT_IF(conn_id);
874 uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id);
875 tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(tcb_idx);
876 tGATT_REG* p_reg = gatt_get_regcb(gatt_if);
877
878 if ((p_tcb == NULL) || (p_reg == NULL) || (disc_type >= GATT_DISC_MAX)) {
879 log::error("Illegal param: disc_type={} conn_id=0x{:x}", disc_type,
880 conn_id);
881 return GATT_ILLEGAL_PARAMETER;
882 }
883
884 if (!GATT_HANDLE_IS_VALID(start_handle) ||
885 !GATT_HANDLE_IS_VALID(end_handle) ||
886 /* search by type does not have a valid UUID param */
887 (disc_type == GATT_DISC_SRVC_BY_UUID && uuid.IsEmpty())) {
888 log::warn(
889 "Illegal parameter conn_id=0x{:x}, disc_type={}, s_handle=0x{:x}, "
890 "e_handle=0x{:x}",
891 conn_id, disc_type, start_handle, end_handle);
892 return GATT_ILLEGAL_PARAMETER;
893 }
894
895 tGATT_CLCB* p_clcb = gatt_clcb_alloc(conn_id);
896 if (!p_clcb) {
897 log::warn(
898 "No resources conn_id=0x{:x}, disc_type={}, s_handle=0x{:x}, "
899 "e_handle=0x{:x}",
900 conn_id, disc_type, start_handle, end_handle);
901 return GATT_NO_RESOURCES;
902 }
903
904 p_clcb->operation = GATTC_OPTYPE_DISCOVERY;
905 p_clcb->op_subtype = disc_type;
906 p_clcb->s_handle = start_handle;
907 p_clcb->e_handle = end_handle;
908 p_clcb->uuid = uuid;
909
910 log::info("conn_id=0x{:x}, disc_type={}, s_handle=0x{:x}, e_handle=0x{:x}",
911 conn_id, disc_type, start_handle, end_handle);
912
913 gatt_act_discovery(p_clcb);
914 return GATT_SUCCESS;
915 }
916
GATTC_Discover(uint16_t conn_id,tGATT_DISC_TYPE disc_type,uint16_t start_handle,uint16_t end_handle)917 tGATT_STATUS GATTC_Discover(uint16_t conn_id, tGATT_DISC_TYPE disc_type,
918 uint16_t start_handle, uint16_t end_handle) {
919 return GATTC_Discover(conn_id, disc_type, start_handle, end_handle,
920 Uuid::kEmpty);
921 }
922
923 /*******************************************************************************
924 *
925 * Function GATTC_Read
926 *
927 * Description This function is called to read the value of an attribute
928 * from the server.
929 *
930 * Parameters conn_id: connection identifier.
931 * type - attribute read type.
932 * p_read - read operation parameters.
933 *
934 * Returns GATT_SUCCESS if command started successfully.
935 *
936 ******************************************************************************/
GATTC_Read(uint16_t conn_id,tGATT_READ_TYPE type,tGATT_READ_PARAM * p_read)937 tGATT_STATUS GATTC_Read(uint16_t conn_id, tGATT_READ_TYPE type,
938 tGATT_READ_PARAM* p_read) {
939 tGATT_IF gatt_if = GATT_GET_GATT_IF(conn_id);
940 uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id);
941 tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(tcb_idx);
942 tGATT_REG* p_reg = gatt_get_regcb(gatt_if);
943 #if (GATT_UPPER_TESTER_MULT_VARIABLE_LENGTH_READ == TRUE)
944 static uint16_t cached_read_handle;
945 static int cached_tcb_idx = -1;
946 #endif
947
948 log::verbose("conn_id=0x{:x}, type=0x{:x}", conn_id, type);
949
950 if ((p_tcb == NULL) || (p_reg == NULL) || (p_read == NULL) ||
951 ((type >= GATT_READ_MAX) || (type == 0))) {
952 log::error("illegal param: conn_id=0x{:x}, type=0x{:x}", conn_id, type);
953 return GATT_ILLEGAL_PARAMETER;
954 }
955
956 tGATT_CLCB* p_clcb = gatt_clcb_alloc(conn_id);
957 if (!p_clcb) return GATT_NO_RESOURCES;
958
959 p_clcb->operation = GATTC_OPTYPE_READ;
960 p_clcb->op_subtype = type;
961 p_clcb->auth_req = p_read->by_handle.auth_req;
962 p_clcb->counter = 0;
963 p_clcb->read_req_current_mtu = gatt_tcb_get_payload_size(*p_tcb, p_clcb->cid);
964
965 switch (type) {
966 case GATT_READ_BY_TYPE:
967 case GATT_READ_CHAR_VALUE:
968 p_clcb->s_handle = p_read->service.s_handle;
969 p_clcb->e_handle = p_read->service.e_handle;
970 p_clcb->uuid = p_read->service.uuid;
971 break;
972 case GATT_READ_MULTIPLE:
973 case GATT_READ_MULTIPLE_VAR_LEN: {
974 p_clcb->s_handle = 0;
975 /* copy multiple handles in CB */
976 tGATT_READ_MULTI* p_read_multi =
977 (tGATT_READ_MULTI*)osi_malloc(sizeof(tGATT_READ_MULTI));
978 p_clcb->p_attr_buf = (uint8_t*)p_read_multi;
979 memcpy(p_read_multi, &p_read->read_multiple, sizeof(tGATT_READ_MULTI));
980 break;
981 }
982 case GATT_READ_BY_HANDLE:
983 #if (GATT_UPPER_TESTER_MULT_VARIABLE_LENGTH_READ == TRUE)
984 log::info("Upper tester: Handle read 0x{:04x}", p_read->by_handle.handle);
985 /* This is upper tester for the Multi Read stuff as this is mandatory for
986 * EATT, even Android is not making use of this operation :/ */
987 if (cached_tcb_idx < 0) {
988 cached_tcb_idx = tcb_idx;
989 log::info("Upper tester: Read multiple - first read");
990 cached_read_handle = p_read->by_handle.handle;
991 } else if (cached_tcb_idx == tcb_idx) {
992 log::info("Upper tester: Read multiple - second read");
993 cached_tcb_idx = -1;
994 tGATT_READ_MULTI* p_read_multi =
995 (tGATT_READ_MULTI*)osi_malloc(sizeof(tGATT_READ_MULTI));
996 p_read_multi->num_handles = 2;
997 p_read_multi->handles[0] = cached_read_handle;
998 p_read_multi->handles[1] = p_read->by_handle.handle;
999 p_read_multi->variable_len = true;
1000
1001 p_clcb->s_handle = 0;
1002 p_clcb->op_subtype = GATT_READ_MULTIPLE_VAR_LEN;
1003 p_clcb->p_attr_buf = (uint8_t*)p_read_multi;
1004 p_clcb->cid = gatt_tcb_get_att_cid(*p_tcb, true /* eatt support */);
1005
1006 break;
1007 }
1008
1009 FALLTHROUGH_INTENDED;
1010 #endif
1011 case GATT_READ_PARTIAL:
1012 p_clcb->uuid = Uuid::kEmpty;
1013 p_clcb->s_handle = p_read->by_handle.handle;
1014
1015 if (type == GATT_READ_PARTIAL) {
1016 p_clcb->counter = p_read->partial.offset;
1017 }
1018
1019 break;
1020 default:
1021 break;
1022 }
1023
1024 /* start security check */
1025 if (gatt_security_check_start(p_clcb))
1026 p_tcb->pending_enc_clcb.push_back(p_clcb);
1027 return GATT_SUCCESS;
1028 }
1029
1030 /*******************************************************************************
1031 *
1032 * Function GATTC_Write
1033 *
1034 * Description This function is called to write the value of an attribute
1035 * to the server.
1036 *
1037 * Parameters conn_id: connection identifier.
1038 * type - attribute write type.
1039 * p_write - write operation parameters.
1040 *
1041 * Returns GATT_SUCCESS if command started successfully.
1042 *
1043 ******************************************************************************/
GATTC_Write(uint16_t conn_id,tGATT_WRITE_TYPE type,tGATT_VALUE * p_write)1044 tGATT_STATUS GATTC_Write(uint16_t conn_id, tGATT_WRITE_TYPE type,
1045 tGATT_VALUE* p_write) {
1046 tGATT_IF gatt_if = GATT_GET_GATT_IF(conn_id);
1047 uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id);
1048 tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(tcb_idx);
1049 tGATT_REG* p_reg = gatt_get_regcb(gatt_if);
1050
1051 if ((p_tcb == NULL) || (p_reg == NULL) || (p_write == NULL) ||
1052 ((type != GATT_WRITE) && (type != GATT_WRITE_PREPARE) &&
1053 (type != GATT_WRITE_NO_RSP))) {
1054 log::error("Illegal param: conn_id=0x{:x}, type=0x{:x}", conn_id, type);
1055 return GATT_ILLEGAL_PARAMETER;
1056 }
1057
1058 tGATT_CLCB* p_clcb = gatt_clcb_alloc(conn_id);
1059 if (!p_clcb) return GATT_NO_RESOURCES;
1060
1061 p_clcb->operation = GATTC_OPTYPE_WRITE;
1062 p_clcb->op_subtype = type;
1063 p_clcb->auth_req = p_write->auth_req;
1064
1065 p_clcb->p_attr_buf = (uint8_t*)osi_malloc(sizeof(tGATT_VALUE));
1066 memcpy(p_clcb->p_attr_buf, (void*)p_write, sizeof(tGATT_VALUE));
1067
1068 tGATT_VALUE* p = (tGATT_VALUE*)p_clcb->p_attr_buf;
1069 if (type == GATT_WRITE_PREPARE) {
1070 p_clcb->start_offset = p_write->offset;
1071 p->offset = 0;
1072 }
1073
1074 if (gatt_security_check_start(p_clcb))
1075 p_tcb->pending_enc_clcb.push_back(p_clcb);
1076 return GATT_SUCCESS;
1077 }
1078
1079 /*******************************************************************************
1080 *
1081 * Function GATTC_ExecuteWrite
1082 *
1083 * Description This function is called to send an Execute write request to
1084 * the server.
1085 *
1086 * Parameters conn_id: connection identifier.
1087 * is_execute - to execute or cancel the prepared write
1088 * request(s)
1089 *
1090 * Returns GATT_SUCCESS if command started successfully.
1091 *
1092 ******************************************************************************/
GATTC_ExecuteWrite(uint16_t conn_id,bool is_execute)1093 tGATT_STATUS GATTC_ExecuteWrite(uint16_t conn_id, bool is_execute) {
1094 tGATT_IF gatt_if = GATT_GET_GATT_IF(conn_id);
1095 uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id);
1096 tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(tcb_idx);
1097 tGATT_REG* p_reg = gatt_get_regcb(gatt_if);
1098
1099 log::verbose("conn_id=0x{:x}, is_execute={}", conn_id, is_execute);
1100
1101 if ((p_tcb == NULL) || (p_reg == NULL)) {
1102 log::error("Illegal param: conn_id=0x{:x}", conn_id);
1103 return GATT_ILLEGAL_PARAMETER;
1104 }
1105
1106 tGATT_CLCB* p_clcb = gatt_clcb_alloc(conn_id);
1107 if (!p_clcb) return GATT_NO_RESOURCES;
1108
1109 p_clcb->operation = GATTC_OPTYPE_EXE_WRITE;
1110 tGATT_EXEC_FLAG flag =
1111 is_execute ? GATT_PREP_WRITE_EXEC : GATT_PREP_WRITE_CANCEL;
1112 gatt_send_queue_write_cancel(*p_clcb->p_tcb, p_clcb, flag);
1113 return GATT_SUCCESS;
1114 }
1115
1116 /*******************************************************************************
1117 *
1118 * Function GATTC_SendHandleValueConfirm
1119 *
1120 * Description This function is called to send a handle value confirmation
1121 * as response to a handle value notification from server.
1122 *
1123 * Parameters conn_id: connection identifier.
1124 * cid: channel id.
1125 *
1126 * Returns GATT_SUCCESS if command started successfully.
1127 *
1128 ******************************************************************************/
GATTC_SendHandleValueConfirm(uint16_t conn_id,uint16_t cid)1129 tGATT_STATUS GATTC_SendHandleValueConfirm(uint16_t conn_id, uint16_t cid) {
1130 log::info("conn_id=0x{:04x} , cid=0x{:04x}", conn_id, cid);
1131
1132 tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(GATT_GET_TCB_IDX(conn_id));
1133 if (!p_tcb) {
1134 log::error("Unknown conn_id=0x{:x}", conn_id);
1135 return GATT_ILLEGAL_PARAMETER;
1136 }
1137
1138 if (p_tcb->ind_count == 0) {
1139 log::info("conn_id: 0x{:04x} ignored not waiting for indication ack",
1140 conn_id);
1141 return GATT_SUCCESS;
1142 }
1143
1144 log::info("Received confirmation, ind_count= {}, sending confirmation",
1145 p_tcb->ind_count);
1146
1147 /* Just wait for first confirmation.*/
1148 p_tcb->ind_count = 0;
1149 gatt_stop_ind_ack_timer(p_tcb, cid);
1150
1151 /* send confirmation now */
1152 return attp_send_cl_confirmation_msg(*p_tcb, cid);
1153 }
1154
1155 /******************************************************************************/
1156 /* */
1157 /* GATT APIs */
1158 /* */
1159 /******************************************************************************/
1160 /*******************************************************************************
1161 *
1162 * Function GATT_SetIdleTimeout
1163 *
1164 * Description This function (common to both client and server) sets the
1165 * idle timeout for a transport connection
1166 *
1167 * Parameter bd_addr: target device bd address.
1168 * idle_tout: timeout value in seconds.
1169 * transport: transport option.
1170 * is_active: whether we should use this as a signal that an
1171 * active client now exists (which changes link
1172 * timeout logic, see
1173 * t_l2c_linkcb.with_active_local_clients for
1174 * details).
1175 *
1176 * Returns void
1177 *
1178 ******************************************************************************/
GATT_SetIdleTimeout(const RawAddress & bd_addr,uint16_t idle_tout,tBT_TRANSPORT transport,bool is_active)1179 void GATT_SetIdleTimeout(const RawAddress& bd_addr, uint16_t idle_tout,
1180 tBT_TRANSPORT transport, bool is_active) {
1181 bool status = false;
1182
1183 tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(bd_addr, transport);
1184 if (p_tcb != nullptr) {
1185 status = L2CA_SetLeGattTimeout(bd_addr, idle_tout);
1186
1187 if (is_active) {
1188 status &= L2CA_MarkLeLinkAsActive(bd_addr);
1189 }
1190
1191 if (idle_tout == GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP) {
1192 if (!L2CA_SetIdleTimeoutByBdAddr(p_tcb->peer_bda,
1193 GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP,
1194 BT_TRANSPORT_LE)) {
1195 log::warn("Unable to set L2CAP link idle timeout peer:{} transport:{}",
1196 p_tcb->peer_bda, bt_transport_text(transport));
1197 }
1198 }
1199 }
1200
1201 log::info("idle_timeout={}, is_active={}, status={} (1-OK 0-not performed)",
1202 idle_tout, is_active, status);
1203 }
1204
1205 /*******************************************************************************
1206 *
1207 * Function GATT_Register
1208 *
1209 * Description This function is called to register an application
1210 * with GATT
1211 *
1212 * Parameter p_app_uuid128: Application UUID
1213 * p_cb_info: callback functions.
1214 * eatt_support: indicate eatt support.
1215 *
1216 * Returns 0 for error, otherwise the index of the client registered
1217 * with GATT
1218 *
1219 ******************************************************************************/
GATT_Register(const Uuid & app_uuid128,const std::string & name,tGATT_CBACK * p_cb_info,bool eatt_support)1220 tGATT_IF GATT_Register(const Uuid& app_uuid128, const std::string& name,
1221 tGATT_CBACK* p_cb_info, bool eatt_support) {
1222 tGATT_REG* p_reg;
1223 uint8_t i_gatt_if = 0;
1224 tGATT_IF gatt_if = 0;
1225
1226 for (i_gatt_if = 0, p_reg = gatt_cb.cl_rcb; i_gatt_if < GATT_MAX_APPS;
1227 i_gatt_if++, p_reg++) {
1228 if (p_reg->in_use && p_reg->app_uuid128 == app_uuid128) {
1229 log::error("Application already registered, uuid={}",
1230 app_uuid128.ToString());
1231 return 0;
1232 }
1233 }
1234
1235 if (stack_config_get_interface()->get_pts_use_eatt_for_all_services()) {
1236 log::info("PTS: Force to use EATT for servers");
1237 eatt_support = true;
1238 }
1239
1240 for (i_gatt_if = 0, p_reg = gatt_cb.cl_rcb; i_gatt_if < GATT_MAX_APPS;
1241 i_gatt_if++, p_reg++) {
1242 if (!p_reg->in_use) {
1243 *p_reg = {};
1244 i_gatt_if++; /* one based number */
1245 p_reg->app_uuid128 = app_uuid128;
1246 gatt_if = p_reg->gatt_if = (tGATT_IF)i_gatt_if;
1247 p_reg->app_cb = *p_cb_info;
1248 p_reg->in_use = true;
1249 p_reg->eatt_support = eatt_support;
1250 p_reg->name = name;
1251 log::info("Allocated name:{} uuid:{} gatt_if:{} eatt_support:{}", name,
1252 app_uuid128.ToString(), gatt_if, eatt_support);
1253 return gatt_if;
1254 }
1255 }
1256
1257 log::error("Unable to register GATT client, MAX client reached: {}",
1258 GATT_MAX_APPS);
1259 return 0;
1260 }
1261
1262 /*******************************************************************************
1263 *
1264 * Function GATT_Deregister
1265 *
1266 * Description This function deregistered the application from GATT.
1267 *
1268 * Parameters gatt_if: application interface.
1269 *
1270 * Returns None.
1271 *
1272 ******************************************************************************/
GATT_Deregister(tGATT_IF gatt_if)1273 void GATT_Deregister(tGATT_IF gatt_if) {
1274 log::info("gatt_if={}", gatt_if);
1275
1276 tGATT_REG* p_reg = gatt_get_regcb(gatt_if);
1277 /* Index 0 is GAP and is never deregistered */
1278 if ((gatt_if == 0) || (p_reg == NULL)) {
1279 log::error("Unable to deregister client with invalid gatt_if={}", gatt_if);
1280 return;
1281 }
1282
1283 /* stop all services */
1284 /* todo an application can not be deregistered if its services is also used by
1285 other application
1286 deregistration need to be performed in an orderly fashion
1287 no check for now */
1288 for (auto it = gatt_cb.srv_list_info->begin();
1289 it != gatt_cb.srv_list_info->end();) {
1290 if (it->gatt_if == gatt_if) {
1291 GATTS_StopService(it++->s_hdl);
1292 } else {
1293 ++it;
1294 }
1295 }
1296
1297 /* free all services db buffers if owned by this application */
1298 gatt_free_srvc_db_buffer_app_id(p_reg->app_uuid128);
1299
1300 /* When an application deregisters, check remove the link associated with the
1301 * app */
1302 tGATT_TCB* p_tcb;
1303 int i;
1304 for (i = 0, p_tcb = gatt_cb.tcb; i < GATT_MAX_PHY_CHANNEL; i++, p_tcb++) {
1305 if (!p_tcb->in_use) continue;
1306
1307 if (gatt_get_ch_state(p_tcb) != GATT_CH_CLOSE) {
1308 gatt_update_app_use_link_flag(gatt_if, p_tcb, false, true);
1309 }
1310
1311 for (auto clcb_it = gatt_cb.clcb_queue.begin();
1312 clcb_it != gatt_cb.clcb_queue.end();) {
1313 if ((clcb_it->p_reg->gatt_if == gatt_if) &&
1314 (clcb_it->p_tcb->tcb_idx == p_tcb->tcb_idx)) {
1315 alarm_cancel(clcb_it->gatt_rsp_timer_ent);
1316 gatt_clcb_invalidate(p_tcb, &(*clcb_it));
1317 clcb_it = gatt_cb.clcb_queue.erase(clcb_it);
1318 } else {
1319 clcb_it++;
1320 }
1321 }
1322 }
1323
1324 if (bluetooth::common::init_flags::
1325 use_unified_connection_manager_is_enabled()) {
1326 bluetooth::connection::GetConnectionManager().remove_client(gatt_if);
1327 } else {
1328 connection_manager::on_app_deregistered(gatt_if);
1329 }
1330
1331 *p_reg = {};
1332 }
1333
1334 /*******************************************************************************
1335 *
1336 * Function GATT_StartIf
1337 *
1338 * Description This function is called after registration to start
1339 * receiving callbacks for registered interface. Function may
1340 * call back with connection status and queued notifications
1341 *
1342 * Parameter gatt_if: application interface.
1343 *
1344 * Returns None.
1345 *
1346 ******************************************************************************/
GATT_StartIf(tGATT_IF gatt_if)1347 void GATT_StartIf(tGATT_IF gatt_if) {
1348 tGATT_REG* p_reg;
1349 tGATT_TCB* p_tcb;
1350 RawAddress bda = {};
1351 uint8_t start_idx, found_idx;
1352 uint16_t conn_id;
1353 tBT_TRANSPORT transport;
1354
1355 log::debug("Starting GATT interface gatt_if_:{}", gatt_if);
1356
1357 p_reg = gatt_get_regcb(gatt_if);
1358 if (p_reg != NULL) {
1359 start_idx = 0;
1360 while (
1361 gatt_find_the_connected_bda(start_idx, bda, &found_idx, &transport)) {
1362 p_tcb = gatt_find_tcb_by_addr(bda, transport);
1363 log::info("GATT interface {} already has connected device {}", gatt_if,
1364 bda);
1365 if (p_reg->app_cb.p_conn_cb && p_tcb) {
1366 conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, gatt_if);
1367 log::info("Invoking callback with connection id {}", conn_id);
1368 (*p_reg->app_cb.p_conn_cb)(gatt_if, bda, conn_id, true, GATT_CONN_OK,
1369 transport);
1370 } else {
1371 log::info("Skipping callback as none is registered");
1372 }
1373 start_idx = ++found_idx;
1374 }
1375 }
1376 }
1377
1378 /*******************************************************************************
1379 *
1380 * Function GATT_Connect
1381 *
1382 * Description This function initiate a connection to a remote device on
1383 * GATT channel.
1384 *
1385 * Parameters gatt_if: application interface
1386 * bd_addr: peer device address.
1387 * connection_type: is a direct connection or a background
1388 * auto connection or targeted announcements
1389 *
1390 * Returns true if connection started; false if connection start
1391 * failure.
1392 *
1393 ******************************************************************************/
GATT_Connect(tGATT_IF gatt_if,const RawAddress & bd_addr,tBTM_BLE_CONN_TYPE connection_type,tBT_TRANSPORT transport,bool opportunistic)1394 bool GATT_Connect(tGATT_IF gatt_if, const RawAddress& bd_addr,
1395 tBTM_BLE_CONN_TYPE connection_type, tBT_TRANSPORT transport,
1396 bool opportunistic) {
1397 constexpr uint8_t kPhyLe1M = 0x01; // From the old controller shim.
1398 uint8_t phy = kPhyLe1M;
1399 return GATT_Connect(gatt_if, bd_addr, connection_type, transport,
1400 opportunistic, phy);
1401 }
1402
GATT_Connect(tGATT_IF gatt_if,const RawAddress & bd_addr,tBLE_ADDR_TYPE addr_type,tBTM_BLE_CONN_TYPE connection_type,tBT_TRANSPORT transport,bool opportunistic,uint8_t initiating_phys)1403 bool GATT_Connect(tGATT_IF gatt_if, const RawAddress& bd_addr,
1404 tBLE_ADDR_TYPE addr_type, tBTM_BLE_CONN_TYPE connection_type,
1405 tBT_TRANSPORT transport, bool opportunistic,
1406 uint8_t initiating_phys) {
1407 /* Make sure app is registered */
1408 tGATT_REG* p_reg = gatt_get_regcb(gatt_if);
1409 if (!p_reg) {
1410 log::error("Unable to find registered app gatt_if={}", gatt_if);
1411 return false;
1412 }
1413
1414 bool is_direct = (connection_type == BTM_BLE_DIRECT_CONNECTION);
1415
1416 if (!is_direct && transport != BT_TRANSPORT_LE) {
1417 log::warn("Unsupported transport for background connection gatt_if={}",
1418 gatt_if);
1419 return false;
1420 }
1421
1422 if (opportunistic) {
1423 log::info("Registered for opportunistic connection gatt_if={}", gatt_if);
1424 return true;
1425 }
1426
1427 bool ret = false;
1428 if (is_direct) {
1429 log::debug("Starting direct connect gatt_if={} address={} transport={}", gatt_if, bd_addr,
1430 transport);
1431 bool tcb_exist = !!gatt_find_tcb_by_addr(bd_addr, transport);
1432
1433 if (!com::android::bluetooth::flags::gatt_reconnect_on_bt_on_fix() || tcb_exist ||
1434 transport == BT_TRANSPORT_BR_EDR) {
1435 /* Consider to remove gatt_act_connect at all */
1436 ret = gatt_act_connect(p_reg, bd_addr, addr_type, transport,
1437 initiating_phys);
1438 } else {
1439 log::verbose("Connecting without tcb address: {}", bd_addr);
1440
1441 if (p_reg->direct_connect_request.count(bd_addr) == 0) {
1442 p_reg->direct_connect_request.insert(bd_addr);
1443 } else {
1444 log::warn("{} already added to gatt_if {} direct conn list", bd_addr,
1445 gatt_if);
1446 }
1447
1448 ret = acl_create_le_connection_with_id(gatt_if, bd_addr, addr_type);
1449 }
1450
1451 } else {
1452 log::debug("Starting background connect gatt_if={} address={}", gatt_if,
1453 bd_addr);
1454 if (!BTM_Sec_AddressKnown(bd_addr)) {
1455 // RPA can rotate, causing address to "expire" in the background
1456 // connection list. RPA is allowed for direct connect, as such request
1457 // times out after 30 seconds
1458 log::warn("Unable to add RPA {} to background connection gatt_if={}",
1459 bd_addr, gatt_if);
1460 ret = false;
1461 } else {
1462 log::debug("Adding to background connect to device:{}", bd_addr);
1463 if (bluetooth::common::init_flags::
1464 use_unified_connection_manager_is_enabled()) {
1465 if (connection_type == BTM_BLE_BKG_CONNECT_ALLOW_LIST) {
1466 bluetooth::connection::GetConnectionManager()
1467 .add_background_connection(
1468 gatt_if, bluetooth::connection::ResolveRawAddress(bd_addr));
1469 ret = true; // TODO(aryarahul): error handling
1470 } else {
1471 log::fatal("unimplemented, TODO(aryarahul)");
1472 }
1473 } else {
1474 if (connection_type == BTM_BLE_BKG_CONNECT_ALLOW_LIST) {
1475 ret = connection_manager::background_connect_add(gatt_if, bd_addr);
1476 } else {
1477 ret =
1478 connection_manager::background_connect_targeted_announcement_add(
1479 gatt_if, bd_addr);
1480 }
1481 }
1482 }
1483 }
1484
1485 tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(bd_addr, transport);
1486 // background connections don't necessarily create tcb
1487 if (p_tcb && ret) {
1488 gatt_update_app_use_link_flag(p_reg->gatt_if, p_tcb, true, !is_direct);
1489 } else {
1490 if (p_tcb == nullptr) {
1491 log::debug("p_tcb is null");
1492 }
1493 if (!ret) {
1494 log::debug("Previous step returned false");
1495 }
1496 }
1497
1498 return ret;
1499 }
1500
GATT_Connect(tGATT_IF gatt_if,const RawAddress & bd_addr,tBLE_ADDR_TYPE addr_type,tBTM_BLE_CONN_TYPE connection_type,tBT_TRANSPORT transport,bool opportunistic)1501 bool GATT_Connect(tGATT_IF gatt_if, const RawAddress& bd_addr,
1502 tBLE_ADDR_TYPE addr_type, tBTM_BLE_CONN_TYPE connection_type,
1503 tBT_TRANSPORT transport, bool opportunistic) {
1504 constexpr uint8_t kPhyLe1M = 0x01; // From the old controller shim.
1505 uint8_t phy = kPhyLe1M;
1506 return GATT_Connect(gatt_if, bd_addr, addr_type, connection_type, transport,
1507 opportunistic, phy);
1508 }
1509
GATT_Connect(tGATT_IF gatt_if,const RawAddress & bd_addr,tBTM_BLE_CONN_TYPE connection_type,tBT_TRANSPORT transport,bool opportunistic,uint8_t initiating_phys)1510 bool GATT_Connect(tGATT_IF gatt_if, const RawAddress& bd_addr,
1511 tBTM_BLE_CONN_TYPE connection_type, tBT_TRANSPORT transport,
1512 bool opportunistic, uint8_t initiating_phys) {
1513 return GATT_Connect(gatt_if, bd_addr, BLE_ADDR_PUBLIC, connection_type,
1514 transport, opportunistic, initiating_phys);
1515 }
1516
1517 /*******************************************************************************
1518 *
1519 * Function GATT_CancelConnect
1520 *
1521 * Description This function terminates the connection initiation to a
1522 * remote device on GATT channel.
1523 *
1524 * Parameters gatt_if: client interface. If 0 used as unconditionally
1525 * disconnect, typically used for direct connection
1526 * cancellation.
1527 * bd_addr: peer device address.
1528 *
1529 * Returns true if the connection started; false otherwise.
1530 *
1531 ******************************************************************************/
GATT_CancelConnect(tGATT_IF gatt_if,const RawAddress & bd_addr,bool is_direct)1532 bool GATT_CancelConnect(tGATT_IF gatt_if, const RawAddress& bd_addr,
1533 bool is_direct) {
1534 log::info("gatt_if:{}, address: {}, direct:{}", gatt_if, bd_addr, is_direct);
1535
1536 tGATT_REG* p_reg;
1537 if (gatt_if) {
1538 p_reg = gatt_get_regcb(gatt_if);
1539 if (!p_reg) {
1540 log::error("gatt_if={} is not registered", gatt_if);
1541 return false;
1542 }
1543
1544 if (is_direct) {
1545 return gatt_cancel_open(gatt_if, bd_addr);
1546 } else {
1547 return gatt_auto_connect_dev_remove(p_reg->gatt_if, bd_addr);
1548 }
1549 }
1550
1551 log::verbose("unconditional");
1552
1553 /* only LE connection can be cancelled */
1554 tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE);
1555 if (p_tcb && !p_tcb->app_hold_link.empty()) {
1556 for (auto it = p_tcb->app_hold_link.begin();
1557 it != p_tcb->app_hold_link.end();) {
1558 auto next = std::next(it);
1559 // gatt_cancel_open modifies the app_hold_link.
1560 gatt_cancel_open(*it, bd_addr);
1561
1562 it = next;
1563 }
1564 }
1565
1566 if (bluetooth::common::init_flags::
1567 use_unified_connection_manager_is_enabled()) {
1568 bluetooth::connection::GetConnectionManager()
1569 .stop_all_connections_to_device(
1570 bluetooth::connection::ResolveRawAddress(bd_addr));
1571 } else {
1572 if (!connection_manager::remove_unconditional(bd_addr)) {
1573 log::error(
1574 "no app associated with the bg device for unconditional removal");
1575 return false;
1576 }
1577 }
1578
1579 return true;
1580 }
1581
1582 /*******************************************************************************
1583 *
1584 * Function GATT_Disconnect
1585 *
1586 * Description This function disconnects the GATT channel for this
1587 * registered application.
1588 *
1589 * Parameters conn_id: connection identifier.
1590 *
1591 * Returns GATT_SUCCESS if disconnected.
1592 *
1593 ******************************************************************************/
GATT_Disconnect(uint16_t conn_id)1594 tGATT_STATUS GATT_Disconnect(uint16_t conn_id) {
1595 log::info("conn_id={}", conn_id);
1596
1597 uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id);
1598 tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(tcb_idx);
1599 if (!p_tcb) {
1600 log::warn("Cannot find TCB for connection {}", conn_id);
1601 return GATT_ILLEGAL_PARAMETER;
1602 }
1603
1604 tGATT_IF gatt_if = GATT_GET_GATT_IF(conn_id);
1605 gatt_update_app_use_link_flag(gatt_if, p_tcb, false, true);
1606 return GATT_SUCCESS;
1607 }
1608
1609 /*******************************************************************************
1610 *
1611 * Function GATT_GetConnectionInfor
1612 *
1613 * Description This function uses conn_id to find its associated BD address
1614 * and application interface
1615 *
1616 * Parameters conn_id: connection id (input)
1617 * p_gatt_if: application interface (output)
1618 * bd_addr: peer device address. (output)
1619 *
1620 * Returns true the logical link information is found for conn_id
1621 *
1622 ******************************************************************************/
GATT_GetConnectionInfor(uint16_t conn_id,tGATT_IF * p_gatt_if,RawAddress & bd_addr,tBT_TRANSPORT * p_transport)1623 bool GATT_GetConnectionInfor(uint16_t conn_id, tGATT_IF* p_gatt_if,
1624 RawAddress& bd_addr, tBT_TRANSPORT* p_transport) {
1625 tGATT_IF gatt_if = GATT_GET_GATT_IF(conn_id);
1626 tGATT_REG* p_reg = gatt_get_regcb(gatt_if);
1627 uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id);
1628 tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(tcb_idx);
1629
1630 log::verbose("conn_id=0x{:x}", conn_id);
1631
1632 if (!p_tcb || !p_reg) return false;
1633
1634 bd_addr = p_tcb->peer_bda;
1635 *p_gatt_if = gatt_if;
1636 *p_transport = p_tcb->transport;
1637 return true;
1638 }
1639
1640 /*******************************************************************************
1641 *
1642 * Function GATT_GetConnIdIfConnected
1643 *
1644 * Description This function finds the conn_id if the logical link for BD
1645 * address and application interface is connected
1646 *
1647 * Parameters gatt_if: application interface (input)
1648 * bd_addr: peer device address. (input)
1649 * p_conn_id: connection id (output)
1650 * transport: transport option
1651 *
1652 * Returns true the logical link is connected
1653 *
1654 ******************************************************************************/
GATT_GetConnIdIfConnected(tGATT_IF gatt_if,const RawAddress & bd_addr,uint16_t * p_conn_id,tBT_TRANSPORT transport)1655 bool GATT_GetConnIdIfConnected(tGATT_IF gatt_if, const RawAddress& bd_addr,
1656 uint16_t* p_conn_id, tBT_TRANSPORT transport) {
1657 tGATT_REG* p_reg = gatt_get_regcb(gatt_if);
1658 tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(bd_addr, transport);
1659 bool status = false;
1660
1661 if (p_reg && p_tcb && (gatt_get_ch_state(p_tcb) == GATT_CH_OPEN)) {
1662 *p_conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, gatt_if);
1663 status = true;
1664 }
1665
1666 log::debug("status={}", status);
1667 return status;
1668 }
1669
gatt_bonded_check_add_address(const RawAddress & bda)1670 static void gatt_bonded_check_add_address(const RawAddress& bda) {
1671 if (!gatt_is_bda_in_the_srv_chg_clt_list(bda)) {
1672 gatt_add_a_bonded_dev_for_srv_chg(bda);
1673 }
1674 }
1675
1676 std::optional<bool> OVERRIDE_GATT_LOAD_BONDED = std::nullopt;
1677
gatt_load_bonded_is_enabled()1678 static bool gatt_load_bonded_is_enabled() {
1679 static const bool sGATT_LOAD_BONDED = bluetooth::os::GetSystemPropertyBool(
1680 "bluetooth.gatt.load_bonded.enabled", false);
1681 if (OVERRIDE_GATT_LOAD_BONDED.has_value()) {
1682 return OVERRIDE_GATT_LOAD_BONDED.value();
1683 }
1684 return sGATT_LOAD_BONDED;
1685 }
1686
1687 /* Initialize GATTS list of bonded device service change updates.
1688 *
1689 * Addresses for bonded devices (public for BR/EDR or pseudo for BLE) are added
1690 * to GATTS service change control list so that updates are sent to bonded
1691 * devices on next connect after any handles for GATTS services change due to
1692 * services added/removed.
1693 */
gatt_load_bonded(void)1694 void gatt_load_bonded(void) {
1695 const bool load_bonded = gatt_load_bonded_is_enabled();
1696 log::info("load bonded: {}", load_bonded ? "True" : "False");
1697 if (!load_bonded) {
1698 return;
1699 }
1700 for (tBTM_SEC_DEV_REC* p_dev_rec : btm_get_sec_dev_rec()) {
1701 if (p_dev_rec->sec_rec.is_link_key_known()) {
1702 log::verbose("Add bonded BR/EDR transport {}", p_dev_rec->bd_addr);
1703 gatt_bonded_check_add_address(p_dev_rec->bd_addr);
1704 }
1705 if (p_dev_rec->sec_rec.is_le_link_key_known()) {
1706 log::verbose("Add bonded BLE {}", p_dev_rec->ble.pseudo_addr);
1707 gatt_bonded_check_add_address(p_dev_rec->ble.pseudo_addr);
1708 }
1709 }
1710 }
1711