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