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