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