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