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