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(&notif, 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