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