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