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