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