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