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