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