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 "common/bt_target.h"
25 #include "osi/allocator.h"
26 
27 #if BLE_INCLUDED == TRUE
28 #include <string.h>
29 #include <stdio.h>
30 
31 #include "stack/l2cdefs.h"
32 #include "gatt_int.h"
33 #include "stack/gatt_api.h"
34 #include "stack/gattdefs.h"
35 #include "stack/sdp_api.h"
36 #include "btm_int.h"
37 /* check if [x, y] and [a, b] have overlapping range */
38 #define GATT_VALIDATE_HANDLE_RANGE(x, y, a, b)   (y >= a && x <= b)
39 
40 #define GATT_GET_NEXT_VALID_HANDLE(x)    (((x)/10 + 1) * 10)
41 
42 const char *const op_code_name[] = {
43     "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 
77 static const UINT8  base_uuid[LEN_UUID_128] = {0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80,
78                                                0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
79                                               };
80 
81 static UINT32 gatt_tcb_id;
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 {
94     GATT_TRACE_DEBUG("gatt_free_pending_ind");
95     if (p_tcb->pending_ind_q == NULL) {
96         return;
97     }
98 
99     /* release all queued indications */
100     while (!fixed_queue_is_empty(p_tcb->pending_ind_q)) {
101         osi_free(fixed_queue_dequeue(p_tcb->pending_ind_q, 0));
102 	}
103     fixed_queue_free(p_tcb->pending_ind_q, NULL);
104     p_tcb->pending_ind_q = NULL;
105 }
106 
107 /*******************************************************************************
108 **
109 ** Function         gatt_free_pending_enc_queue
110 **
111 ** Description       Free all buffers in pending encyption queue
112 **
113 ** Returns       None
114 **
115 *******************************************************************************/
gatt_free_pending_enc_queue(tGATT_TCB * p_tcb)116 void gatt_free_pending_enc_queue(tGATT_TCB *p_tcb)
117 {
118     GATT_TRACE_DEBUG("gatt_free_pending_enc_queue");
119     if (p_tcb->pending_enc_clcb == NULL) {
120         return;
121     }
122 
123     /* release all queued indications */
124     while (!fixed_queue_is_empty(p_tcb->pending_enc_clcb)) {
125         osi_free(fixed_queue_dequeue(p_tcb->pending_enc_clcb, 0));
126     }
127 	fixed_queue_free(p_tcb->pending_enc_clcb, NULL);
128     p_tcb->pending_enc_clcb = NULL;
129 }
130 
131 /*******************************************************************************
132 **
133 ** Function         gatt_free_pending_prepare_write_queue
134 **
135 ** Description       Free all buffers in pending prepare write packets queue
136 **
137 ** Returns       None
138 **
139 *******************************************************************************/
gatt_free_pending_prepare_write_queue(tGATT_TCB * p_tcb)140 void gatt_free_pending_prepare_write_queue(tGATT_TCB *p_tcb)
141 {
142     GATT_TRACE_DEBUG("gatt_free_pending_prepare_write_queue");
143 
144     if (p_tcb->prepare_write_record.queue) {
145         /* release all queued prepare write packets */
146         while (!fixed_queue_is_empty(p_tcb->prepare_write_record.queue)) {
147             osi_free(fixed_queue_dequeue(p_tcb->prepare_write_record.queue, FIXED_QUEUE_MAX_TIMEOUT));
148         }
149         fixed_queue_free(p_tcb->prepare_write_record.queue, NULL);
150         p_tcb->prepare_write_record.queue = NULL;
151     }
152 
153     p_tcb->prepare_write_record.total_num = 0;
154     p_tcb->prepare_write_record.error_code_app = GATT_SUCCESS;
155 }
156 
157 /*******************************************************************************
158 **
159 ** Function         gatt_delete_dev_from_srv_chg_clt_list
160 **
161 ** Description    Delete a device from the service changed client lit
162 **
163 ** Returns       None
164 **
165 *******************************************************************************/
gatt_delete_dev_from_srv_chg_clt_list(BD_ADDR bd_addr)166 void gatt_delete_dev_from_srv_chg_clt_list(BD_ADDR bd_addr)
167 {
168     tGATTS_SRV_CHG     *p_buf;
169     tGATTS_SRV_CHG_REQ  req;
170 
171     GATT_TRACE_DEBUG ("gatt_delete_dev_from_srv_chg_clt_list");
172     if ((p_buf = gatt_is_bda_in_the_srv_chg_clt_list(bd_addr)) != NULL) {
173         if (gatt_cb.cb_info.p_srv_chg_callback) {
174             /* delete from NV */
175             memcpy(req.srv_chg.bda, bd_addr, BD_ADDR_LEN);
176             (*gatt_cb.cb_info.p_srv_chg_callback)(GATTS_SRV_CHG_CMD_REMOVE_CLIENT, &req, NULL);
177         }
178         osi_free(fixed_queue_try_remove_from_queue(gatt_cb.srv_chg_clt_q,
179                                                       p_buf));
180     }
181 
182 }
183 
184 /*******************************************************************************
185 **
186 ** Function         gatt_set_srv_chg
187 **
188 ** Description      Set the service changed flag to TRUE
189 **
190 ** Returns        None
191 **
192 *******************************************************************************/
gatt_set_srv_chg(void)193 void gatt_set_srv_chg(void)
194 {
195     GATT_TRACE_DEBUG ("gatt_set_srv_chg");
196 
197     if (fixed_queue_is_empty(gatt_cb.srv_chg_clt_q)) {
198         return;
199 	}
200 
201     list_t *list = fixed_queue_get_list(gatt_cb.srv_chg_clt_q);
202     for (const list_node_t *node = list_begin(list); node != list_end(list);
203          node = list_next(node)) {
204         GATT_TRACE_DEBUG ("found a srv_chg clt");
205 
206         tGATTS_SRV_CHG *p_buf = (tGATTS_SRV_CHG *)list_node(node);
207         if (!p_buf->srv_changed) {
208             GATT_TRACE_DEBUG("set srv_changed to TRUE");
209             p_buf->srv_changed = TRUE;
210             tGATTS_SRV_CHG_REQ req;
211             memcpy(&req.srv_chg, p_buf, sizeof(tGATTS_SRV_CHG));
212             if (gatt_cb.cb_info.p_srv_chg_callback) {
213                 (*gatt_cb.cb_info.p_srv_chg_callback)(GATTS_SRV_CHG_CMD_UPDATE_CLIENT,&req, NULL);
214 			}
215         }
216     }
217 }
218 
219 /*******************************************************************************
220 **
221 ** Function         gatt_sr_is_new_srv_chg
222 **
223 ** Description     Find the app id in on the new service changed list
224 **
225 ** Returns     Pointer to the found new service changed item othwerwise NULL
226 **
227 *******************************************************************************/
gatt_sr_is_new_srv_chg(tBT_UUID * p_app_uuid128,tBT_UUID * p_svc_uuid,UINT16 svc_inst)228 tGATTS_PENDING_NEW_SRV_START *gatt_sr_is_new_srv_chg(tBT_UUID *p_app_uuid128, tBT_UUID *p_svc_uuid, UINT16 svc_inst)
229 {
230     tGATTS_PENDING_NEW_SRV_START *p_buf = NULL;
231 
232     if (fixed_queue_is_empty(gatt_cb.pending_new_srv_start_q)) {
233         return NULL;
234 	}
235 
236     list_t *list = fixed_queue_get_list(gatt_cb.pending_new_srv_start_q);
237     for (const list_node_t *node = list_begin(list); node != list_end(list);
238          node = list_next(node)) {
239         p_buf = (tGATTS_PENDING_NEW_SRV_START *)list_node(node);
240         tGATTS_HNDL_RANGE *p = p_buf->p_new_srv_start;
241         if (gatt_uuid_compare(*p_app_uuid128, p->app_uuid128)
242             && gatt_uuid_compare (*p_svc_uuid, p->svc_uuid)
243             && (svc_inst == p->svc_inst)) {
244             GATT_TRACE_DEBUG("gatt_sr_is_new_srv_chg: Yes");
245             break;
246         }
247     }
248 
249     return p_buf;
250 }
251 
252 
253 /*******************************************************************************
254 **
255 ** Function     gatt_add_pending_ind
256 **
257 ** Description  Add a pending indication
258 **
259 ** Returns    Pointer to the current pending indication buffer, NULL no buffer available
260 **
261 *******************************************************************************/
gatt_add_pending_ind(tGATT_TCB * p_tcb,tGATT_VALUE * p_ind)262 tGATT_VALUE *gatt_add_pending_ind(tGATT_TCB  *p_tcb, tGATT_VALUE *p_ind)
263 {
264     tGATT_VALUE   *p_buf;
265     GATT_TRACE_DEBUG ("gatt_add_pending_ind");
266     if ((p_buf = (tGATT_VALUE *)osi_malloc((UINT16)sizeof(tGATT_VALUE))) != NULL) {
267         GATT_TRACE_DEBUG ("enqueue a pending indication");
268         memcpy(p_buf, p_ind, sizeof(tGATT_VALUE));
269     fixed_queue_enqueue(p_tcb->pending_ind_q, p_buf, FIXED_QUEUE_MAX_TIMEOUT);
270     }
271     return p_buf;
272 }
273 
274 
275 /*******************************************************************************
276 **
277 ** Function     gatt_add_pending_new_srv_start
278 **
279 ** Description  Add a pending new srv start to the new service start queue
280 **
281 ** Returns    Pointer to the new service start buffer, NULL no buffer available
282 **
283 *******************************************************************************/
gatt_add_pending_new_srv_start(tGATTS_HNDL_RANGE * p_new_srv_start)284 tGATTS_PENDING_NEW_SRV_START *gatt_add_pending_new_srv_start(tGATTS_HNDL_RANGE *p_new_srv_start)
285 {
286     tGATTS_PENDING_NEW_SRV_START   *p_buf;
287 
288     GATT_TRACE_DEBUG ("gatt_add_pending_new_srv_start");
289     if ((p_buf = (tGATTS_PENDING_NEW_SRV_START *)osi_malloc((UINT16)sizeof(tGATTS_PENDING_NEW_SRV_START))) != NULL) {
290         GATT_TRACE_DEBUG ("enqueue a new pending new srv start");
291         p_buf->p_new_srv_start = p_new_srv_start;
292     fixed_queue_enqueue(gatt_cb.pending_new_srv_start_q, p_buf, FIXED_QUEUE_MAX_TIMEOUT);
293     }
294     return p_buf;
295 }
296 
297 
298 /*******************************************************************************
299 **
300 ** Function     gatt_add_srv_chg_clt
301 **
302 ** Description  Add a service chnage client to the service change client queue
303 **
304 ** Returns    Pointer to the service change client buffer; Null no buffer available
305 **
306 *******************************************************************************/
gatt_add_srv_chg_clt(tGATTS_SRV_CHG * p_srv_chg)307 tGATTS_SRV_CHG *gatt_add_srv_chg_clt(tGATTS_SRV_CHG *p_srv_chg)
308 {
309     tGATTS_SRV_CHG *p_buf;
310     GATT_TRACE_DEBUG ("gatt_add_srv_chg_clt");
311     if ((p_buf = (tGATTS_SRV_CHG *)osi_malloc((UINT16)sizeof(tGATTS_SRV_CHG))) != NULL) {
312         GATT_TRACE_DEBUG ("enqueue a srv chg client");
313         memcpy(p_buf, p_srv_chg, sizeof(tGATTS_SRV_CHG));
314     fixed_queue_enqueue(gatt_cb.srv_chg_clt_q, p_buf, FIXED_QUEUE_MAX_TIMEOUT);
315     }
316 
317     return p_buf;
318 }
319 
320 
321 /*******************************************************************************
322 **
323 ** Function     gatt_alloc_hdl_buffer
324 **
325 ** Description  Allocate a handle buufer
326 **
327 ** Returns    Pointer to the allocated buffer, NULL no buffer available
328 **
329 *******************************************************************************/
330 #if (GATTS_INCLUDED == TRUE)
gatt_alloc_hdl_buffer(void)331 tGATT_HDL_LIST_ELEM *gatt_alloc_hdl_buffer(void)
332 {
333     UINT8 i;
334     tGATT_CB    *p_cb = &gatt_cb;
335     tGATT_HDL_LIST_ELEM *p_elem = &p_cb->hdl_list[0];
336 
337     for (i = 0; i < GATT_MAX_SR_PROFILES; i++, p_elem ++) {
338         if (!p_cb->hdl_list[i].in_use) {
339             memset(p_elem, 0, sizeof(tGATT_HDL_LIST_ELEM));
340             p_elem->in_use = TRUE;
341             p_elem->svc_db.svc_buffer = fixed_queue_new(QUEUE_SIZE_MAX);
342             return p_elem;
343         }
344     }
345 
346     return NULL;
347 }
348 
349 /*******************************************************************************
350 **
351 ** Function     gatt_find_hdl_buffer_by_handle
352 **
353 ** Description  Find handle range buffer by service handle.
354 **
355 ** Returns    Pointer to the buffer, NULL no buffer available
356 **
357 *******************************************************************************/
gatt_find_hdl_buffer_by_handle(UINT16 handle)358 tGATT_HDL_LIST_ELEM *gatt_find_hdl_buffer_by_handle(UINT16 handle)
359 {
360     tGATT_HDL_LIST_INFO *p_list_info = &gatt_cb.hdl_list_info;
361     tGATT_HDL_LIST_ELEM      *p_list = NULL;
362 
363     p_list = p_list_info->p_first;
364 
365     while (p_list != NULL) {
366         if (p_list->in_use && p_list->asgn_range.s_handle == handle) {
367             return (p_list);
368         }
369         p_list = p_list->p_next;
370     }
371     return NULL;
372 }
373 
374 /*******************************************************************************
375 **
376 ** Function     gatt_find_hdl_buffer_by_attr_handle
377 **
378 ** Description  Find handle range buffer by attribute handle.
379 **
380 ** Returns    Pointer to the buffer, NULL no buffer available
381 **
382 *******************************************************************************/
gatt_find_hdl_buffer_by_attr_handle(UINT16 attr_handle)383 tGATT_HDL_LIST_ELEM *gatt_find_hdl_buffer_by_attr_handle(UINT16 attr_handle)
384 {
385     tGATT_HDL_LIST_INFO *p_list_info = &gatt_cb.hdl_list_info;
386     tGATT_HDL_LIST_ELEM      *p_list = NULL;
387 
388     p_list = p_list_info->p_first;
389 
390     while (p_list != NULL) {
391         if (p_list->in_use && (p_list->asgn_range.s_handle <= attr_handle)
392 			&& (p_list->asgn_range.e_handle >= attr_handle)) {
393             return (p_list);
394         }
395         p_list = p_list->p_next;
396     }
397     return NULL;
398 }
399 
400 
401 /*******************************************************************************
402 **
403 ** Function     gatt_find_hdl_buffer_by_app_id
404 **
405 ** Description  Find handle range buffer by app ID, service and service instance ID.
406 **
407 ** Returns    Pointer to the buffer, NULL no buffer available
408 **
409 *******************************************************************************/
gatt_find_hdl_buffer_by_app_id(tBT_UUID * p_app_uuid128,tBT_UUID * p_svc_uuid,UINT16 svc_inst)410 tGATT_HDL_LIST_ELEM *gatt_find_hdl_buffer_by_app_id (tBT_UUID *p_app_uuid128,
411         tBT_UUID *p_svc_uuid,
412         UINT16 svc_inst)
413 {
414     tGATT_HDL_LIST_INFO *p_list_info = &gatt_cb.hdl_list_info;
415     tGATT_HDL_LIST_ELEM      *p_list = NULL;
416 
417     p_list = p_list_info->p_first;
418 
419     while (p_list != NULL) {
420         if ( gatt_uuid_compare (*p_app_uuid128, p_list->asgn_range.app_uuid128)
421                 &&  gatt_uuid_compare (*p_svc_uuid,    p_list->asgn_range.svc_uuid)
422                 &&  (svc_inst == p_list->asgn_range.svc_inst) ) {
423             GATT_TRACE_DEBUG ("Already allocated handles for this service before!!");
424             return (p_list);
425         }
426         p_list = p_list->p_next;
427     }
428     return NULL;
429 }
430 #endif  ///GATTS_INCLUDED == TRUE
431 
432 /*******************************************************************************
433 **
434 ** Function         gatt_free_attr_value_buffer
435 **
436 ** Description      free characteristic attribute value buffer in a service
437 **
438 ** Returns          None
439 **
440 *******************************************************************************/
gatt_free_attr_value_buffer(tGATT_HDL_LIST_ELEM * p)441 void gatt_free_attr_value_buffer(tGATT_HDL_LIST_ELEM *p)
442 {
443     if (p){
444         tGATT_SVC_DB *p_db = &(p->svc_db);
445         tGATT_ATTR16 *p_attr = p_db->p_attr_list;
446         tGATT_ATTR_VALUE *p_value = NULL;
447 
448         while(p_attr){
449             if (p_attr->mask & GATT_ATTR_VALUE_ALLOCATED){
450                 p_value = p_attr->p_value;
451                 if ((p_value != NULL) && (p_value->attr_val.attr_val != NULL)){
452                     osi_free(p_value->attr_val.attr_val);
453                 }
454             }
455             p_attr = p_attr->p_next;
456         }
457     }
458 }
459 /*******************************************************************************
460 **
461 ** Function         gatt_free_hdl_buffer
462 **
463 ** Description      free a handle buffer
464 **
465 ** Returns          None
466 **
467 *******************************************************************************/
gatt_free_hdl_buffer(tGATT_HDL_LIST_ELEM * p)468 void gatt_free_hdl_buffer(tGATT_HDL_LIST_ELEM *p)
469 {
470 
471     if (p) {
472         while (!fixed_queue_is_empty(p->svc_db.svc_buffer)) {
473             osi_free(fixed_queue_dequeue(p->svc_db.svc_buffer, 0));
474 		}
475         fixed_queue_free(p->svc_db.svc_buffer, NULL);
476         memset(p, 0, sizeof(tGATT_HDL_LIST_ELEM));
477     }
478 }
479 /*******************************************************************************
480 **
481 ** Function         gatt_free_srvc_db_buffer_app_id
482 **
483 ** Description      free the service attribute database buffers by the owner of the
484 **                  service app ID.
485 **
486 ** Returns       None
487 **
488 *******************************************************************************/
489 #if (GATTS_INCLUDED == TRUE)
gatt_free_srvc_db_buffer_app_id(tBT_UUID * p_app_id)490 void gatt_free_srvc_db_buffer_app_id(tBT_UUID *p_app_id)
491 {
492     tGATT_HDL_LIST_ELEM *p_elem =  &gatt_cb.hdl_list[0];
493     UINT8   i;
494 
495     for (i = 0; i < GATT_MAX_SR_PROFILES; i ++, p_elem ++) {
496         if (memcmp(p_app_id, &p_elem->asgn_range.app_uuid128, sizeof(tBT_UUID)) == 0) {
497             gatt_free_attr_value_buffer(p_elem);
498             while (!fixed_queue_is_empty(p_elem->svc_db.svc_buffer)) {
499                 osi_free(fixed_queue_dequeue(p_elem->svc_db.svc_buffer, 0));
500 			}
501             fixed_queue_free(p_elem->svc_db.svc_buffer, NULL);
502             p_elem->svc_db.svc_buffer = NULL;
503 
504             p_elem->svc_db.mem_free = 0;
505             p_elem->svc_db.p_attr_list = p_elem->svc_db.p_free_mem = NULL;
506         }
507     }
508 }
509 /*******************************************************************************
510 **
511 ** Function         gatt_is_last_attribute
512 **
513 ** Description     Check this is the last attribute of the specified value or not
514 **
515 ** Returns       TRUE - yes this is the last attribute
516 **
517 *******************************************************************************/
gatt_is_last_attribute(tGATT_SRV_LIST_INFO * p_list,tGATT_SRV_LIST_ELEM * p_start,tBT_UUID value)518 BOOLEAN gatt_is_last_attribute(tGATT_SRV_LIST_INFO *p_list, tGATT_SRV_LIST_ELEM *p_start, tBT_UUID value)
519 {
520     tGATT_SRV_LIST_ELEM *p_srv = p_start->p_next;
521     BOOLEAN              is_last_attribute = TRUE;
522     tGATT_SR_REG        *p_rcb = NULL;
523     tBT_UUID            *p_svc_uuid;
524 
525     p_list->p_last_primary = NULL;
526 
527     while (p_srv) {
528         p_rcb = GATT_GET_SR_REG_PTR(p_srv->i_sreg);
529 
530         p_svc_uuid = gatts_get_service_uuid (p_rcb->p_db);
531 
532         if (gatt_uuid_compare(value, *p_svc_uuid)) {
533             is_last_attribute = FALSE;
534             break;
535 
536         }
537         p_srv = p_srv->p_next;
538     }
539 
540     return is_last_attribute;
541 
542 }
543 /*******************************************************************************
544 **
545 ** Function         gatt_update_last_pri_srv_info
546 **
547 ** Description     Update the the last primary info for the service list info
548 **
549 ** Returns       None
550 **
551 *******************************************************************************/
gatt_update_last_pri_srv_info(tGATT_SRV_LIST_INFO * p_list)552 void gatt_update_last_pri_srv_info(tGATT_SRV_LIST_INFO *p_list)
553 {
554     tGATT_SRV_LIST_ELEM *p_srv = p_list->p_first;
555 
556     p_list->p_last_primary = NULL;
557 
558     while (p_srv) {
559         if (p_srv->is_primary) {
560             p_list->p_last_primary = p_srv;
561         }
562         p_srv = p_srv->p_next;
563     }
564 
565 }
566 /*******************************************************************************
567 **
568 ** Function         gatts_update_srv_list_elem
569 **
570 ** Description      update an element in the service list.
571 **
572 ** Returns          None.
573 **
574 *******************************************************************************/
gatts_update_srv_list_elem(UINT8 i_sreg,UINT16 handle,BOOLEAN is_primary)575 void gatts_update_srv_list_elem(UINT8 i_sreg, UINT16 handle, BOOLEAN is_primary)
576 {
577     UNUSED(handle);
578 
579     gatt_cb.srv_list[i_sreg].in_use         = TRUE;
580     gatt_cb.srv_list[i_sreg].i_sreg    = i_sreg;
581     gatt_cb.srv_list[i_sreg].s_hdl          = gatt_cb.sr_reg[i_sreg].s_hdl;
582     gatt_cb.srv_list[i_sreg].is_primary     = is_primary;
583 
584     return;
585 }
586 #endif  ///GATTS_INCLUDED == TRUE
587 
588 /*******************************************************************************
589 **
590 ** Function  gatt_add_a_srv_to_list
591 **
592 ** Description  add an service to the list in ascending
593 **              order of the start handle
594 **
595 ** Returns   BOOLEAN TRUE-if add is successful
596 **
597 *******************************************************************************/
gatt_add_a_srv_to_list(tGATT_SRV_LIST_INFO * p_list,tGATT_SRV_LIST_ELEM * p_new)598 BOOLEAN gatt_add_a_srv_to_list(tGATT_SRV_LIST_INFO *p_list, tGATT_SRV_LIST_ELEM *p_new)
599 {
600     tGATT_SRV_LIST_ELEM *p_old;
601 
602     if (!p_new) {
603         GATT_TRACE_DEBUG("p_new==NULL");
604         return FALSE;
605     }
606 
607     if (!p_list->p_first) {
608         /* this is an empty list */
609         p_list->p_first =
610             p_list->p_last  = p_new;
611         p_new->p_next   =
612             p_new->p_prev   = NULL;
613     } else {
614         p_old = p_list->p_first;
615         while (1) {
616             if (p_old == NULL) {
617                 p_list->p_last->p_next      = p_new;
618                 p_new->p_prev               = p_list->p_last;
619                 p_new->p_next               = NULL;
620                 p_list->p_last              = p_new;
621                 break;
622             } else {
623                 if (p_new->s_hdl <  p_old->s_hdl) {
624                     /* if not the first in list */
625                     if (p_old->p_prev != NULL) {
626                         p_old->p_prev->p_next   = p_new;
627                     } else {
628                         p_list->p_first = p_new;
629                     }
630 
631                     p_new->p_prev           = p_old->p_prev;
632                     p_new->p_next           = p_old;
633                     p_old->p_prev           = p_new;
634                     break;
635                 }
636             }
637             p_old = p_old->p_next;
638         }
639     }
640     p_list->count++;
641 
642     gatt_update_last_pri_srv_info(p_list);
643     return TRUE;
644 
645 }
646 
647 /*******************************************************************************
648 **
649 ** Function  gatt_remove_a_srv_from_list
650 **
651 ** Description  Remove a service from the list
652 **
653 ** Returns   BOOLEAN TRUE-if remove is successful
654 **
655 *******************************************************************************/
gatt_remove_a_srv_from_list(tGATT_SRV_LIST_INFO * p_list,tGATT_SRV_LIST_ELEM * p_remove)656 BOOLEAN gatt_remove_a_srv_from_list(tGATT_SRV_LIST_INFO *p_list, tGATT_SRV_LIST_ELEM *p_remove)
657 {
658     if (!p_remove || !p_list->p_first) {
659         GATT_TRACE_DEBUG("p_remove==NULL || p_list->p_first==NULL");
660         return FALSE;
661     }
662 
663     if (p_remove->p_prev == NULL) {
664         p_list->p_first             = p_remove->p_next;
665         if (p_remove->p_next) {
666             p_remove->p_next->p_prev    = NULL;
667         }
668     } else if (p_remove->p_next == NULL) {
669         p_list->p_last              = p_remove->p_prev;
670         p_remove->p_prev->p_next    = NULL;
671     } else {
672         p_remove->p_next->p_prev = p_remove->p_prev;
673         p_remove->p_prev->p_next = p_remove->p_next;
674     }
675     p_list->count--;
676     gatt_update_last_pri_srv_info(p_list);
677     return TRUE;
678 
679 }
680 
681 /*******************************************************************************
682 **
683 ** Function  gatt_add_an_item_to_list
684 **
685 ** Description  add an service handle range to the list in decending
686 **              order of the start handle
687 **
688 ** Returns   BOOLEAN TRUE-if add is successful
689 **
690 *******************************************************************************/
gatt_add_an_item_to_list(tGATT_HDL_LIST_INFO * p_list,tGATT_HDL_LIST_ELEM * p_new)691 BOOLEAN gatt_add_an_item_to_list(tGATT_HDL_LIST_INFO *p_list, tGATT_HDL_LIST_ELEM *p_new)
692 {
693     tGATT_HDL_LIST_ELEM *p_old;
694     if (!p_new) {
695         GATT_TRACE_DEBUG("p_new==NULL");
696         return FALSE;
697     }
698 
699     if (!p_list->p_first) {
700         /* this is an empty list */
701         p_list->p_first =
702             p_list->p_last  = p_new;
703         p_new->p_next   =
704             p_new->p_prev   = NULL;
705     } else {
706         p_old = p_list->p_first;
707         while (1) {
708             if (p_old == NULL) {
709                 p_list->p_last->p_next      = p_new;
710                 p_new->p_prev               = p_list->p_last;
711                 p_new->p_next               = NULL;
712                 p_list->p_last              = p_new;
713 
714                 break;
715 
716             } else {
717                 if (p_new->asgn_range.s_handle >  p_old->asgn_range.s_handle) {
718                     if (p_old == p_list->p_first) {
719                         p_list->p_first = p_new;
720                     }
721 
722                     p_new->p_prev    = p_old->p_prev;
723                     p_new->p_next    = p_old;
724 
725 
726                     p_old->p_prev    = p_new;
727                     break;
728                 }
729             }
730             p_old = p_old->p_next;
731         }
732     }
733     p_list->count++;
734     return TRUE;
735 
736 }
737 
738 /*******************************************************************************
739 **
740 ** Function  gatt_remove_an_item_from_list
741 **
742 ** Description  Remove an service handle range from the list
743 **
744 ** Returns   BOOLEAN TRUE-if remove is successful
745 **
746 *******************************************************************************/
gatt_remove_an_item_from_list(tGATT_HDL_LIST_INFO * p_list,tGATT_HDL_LIST_ELEM * p_remove)747 BOOLEAN gatt_remove_an_item_from_list(tGATT_HDL_LIST_INFO *p_list, tGATT_HDL_LIST_ELEM *p_remove)
748 {
749     if (!p_remove || !p_list->p_first) {
750         GATT_TRACE_DEBUG("p_remove==NULL || p_list->p_first==NULL");
751         return FALSE;
752     }
753 
754     if (p_remove->p_prev == NULL) {
755         p_list->p_first             = p_remove->p_next;
756         if (p_remove->p_next) {
757             p_remove->p_next->p_prev    = NULL;
758         }
759     } else if (p_remove->p_next == NULL) {
760         p_list->p_last              = p_remove->p_prev;
761         p_remove->p_prev->p_next    = NULL;
762     } else {
763         p_remove->p_next->p_prev = p_remove->p_prev;
764         p_remove->p_prev->p_next = p_remove->p_next;
765     }
766     p_list->count--;
767     return TRUE;
768 
769 }
770 
771 /*******************************************************************************
772 **
773 ** Function         gatt_find_the_connected_bda
774 **
775 ** Description      This function find the connected bda
776 **
777 ** Returns           TRUE if found
778 **
779 *******************************************************************************/
gatt_find_the_connected_bda(UINT8 start_idx,BD_ADDR bda,UINT8 * p_found_idx,tBT_TRANSPORT * p_transport)780 BOOLEAN gatt_find_the_connected_bda(UINT8 start_idx, BD_ADDR bda, UINT8 *p_found_idx,
781                                     tBT_TRANSPORT *p_transport)
782 {
783     BOOLEAN found = FALSE;
784     GATT_TRACE_DEBUG("gatt_find_the_connected_bda start_idx=%d", start_idx);
785     tGATT_TCB   *p_tcb  = NULL;
786     list_node_t *p_node = NULL;
787     p_tcb = gatt_get_tcb_by_idx(start_idx);
788     if (p_tcb) {
789         for(p_node = list_get_node(gatt_cb.p_tcb_list, p_tcb); p_node; p_node = list_next(p_node)) {
790 	    p_tcb = list_node(p_node);
791             if (p_tcb->in_use && p_tcb->ch_state == GATT_CH_OPEN) {
792                 memcpy( bda, p_tcb->peer_bda, BD_ADDR_LEN);
793                 *p_found_idx = p_tcb->tcb_idx;
794                 *p_transport = p_tcb->transport;
795                 found = TRUE;
796                 GATT_TRACE_DEBUG("gatt_find_the_connected_bda bda :%02x-%02x-%02x-%02x-%02x-%02x",
797                                  bda[0],  bda[1], bda[2],  bda[3], bda[4],  bda[5]);
798                 break;
799             }
800         }
801         GATT_TRACE_DEBUG("gatt_find_the_connected_bda found=%d found_idx=%d", found, p_tcb->tcb_idx);
802     }
803     return found;
804 }
805 
806 
807 /*******************************************************************************
808 **
809 ** Function         gatt_is_srv_chg_ind_pending
810 **
811 ** Description      Check whether a service chnaged is in the indication pending queue
812 **                  or waiting for an Ack already
813 **
814 ** Returns         BOOLEAN
815 **
816 *******************************************************************************/
gatt_is_srv_chg_ind_pending(tGATT_TCB * p_tcb)817 BOOLEAN gatt_is_srv_chg_ind_pending (tGATT_TCB *p_tcb)
818 {
819     BOOLEAN srv_chg_ind_pending = FALSE;
820 
821     GATT_TRACE_DEBUG("gatt_is_srv_chg_ind_pending is_queue_empty=%d",
822                      fixed_queue_is_empty(p_tcb->pending_ind_q));
823 
824     if (p_tcb->indicate_handle == gatt_cb.handle_of_h_r) {
825         srv_chg_ind_pending = TRUE;
826     } else if (! fixed_queue_is_empty(p_tcb->pending_ind_q)) {
827         list_t *list = fixed_queue_get_list(p_tcb->pending_ind_q);
828         for (const list_node_t *node = list_begin(list);
829              node != list_end(list);
830              node = list_next(node)) {
831             tGATT_VALUE *p_buf = (tGATT_VALUE *)list_node(node);
832             if (p_buf->handle == gatt_cb.handle_of_h_r)
833             {
834                 srv_chg_ind_pending = TRUE;
835                 break;
836             }
837         }
838     }
839 
840     GATT_TRACE_DEBUG("srv_chg_ind_pending = %d", srv_chg_ind_pending);
841     return srv_chg_ind_pending;
842 }
843 
844 
845 /*******************************************************************************
846 **
847 ** Function         gatt_is_bda_in_the_srv_chg_clt_list
848 **
849 ** Description      This function check the specified bda is in the srv chg clinet list or not
850 **
851 ** Returns         pointer to the found elemenet otherwise NULL
852 **
853 *******************************************************************************/
gatt_is_bda_in_the_srv_chg_clt_list(BD_ADDR bda)854 tGATTS_SRV_CHG *gatt_is_bda_in_the_srv_chg_clt_list (BD_ADDR bda)
855 {
856     tGATTS_SRV_CHG *p_buf = NULL;
857 
858     GATT_TRACE_DEBUG("gatt_is_bda_in_the_srv_chg_clt_list :%02x-%02x-%02x-%02x-%02x-%02x",
859                      bda[0],  bda[1], bda[2],  bda[3], bda[4],  bda[5]);
860 
861     if (fixed_queue_is_empty(gatt_cb.srv_chg_clt_q)) {
862         return NULL;
863 	}
864 
865     list_t *list = fixed_queue_get_list(gatt_cb.srv_chg_clt_q);
866     for (const list_node_t *node = list_begin(list); node != list_end(list);
867          node = list_next(node)) {
868         p_buf = (tGATTS_SRV_CHG *)list_node(node);
869         if (!memcmp( bda, p_buf->bda, BD_ADDR_LEN)) {
870             GATT_TRACE_DEBUG("bda is in the srv chg clt list");
871             break;
872         }
873     }
874 
875     return p_buf;
876 }
877 
878 
879 /*******************************************************************************
880 **
881 ** Function         gatt_is_bda_connected
882 **
883 ** Description
884 **
885 ** Returns           GATT_INDEX_INVALID if not found. Otherwise index to the tcb.
886 **
887 *******************************************************************************/
gatt_is_bda_connected(BD_ADDR bda)888 BOOLEAN gatt_is_bda_connected(BD_ADDR bda)
889 {
890     BOOLEAN connected = FALSE;
891     tGATT_TCB   *p_tcb  = NULL;
892     list_node_t *p_node = NULL;
893     for(p_node = list_begin(gatt_cb.p_tcb_list); p_node; p_node = list_next(p_node)) {
894 	p_tcb = list_node(p_node);
895         if (p_tcb->in_use &&
896                 !memcmp(p_tcb->peer_bda, bda, BD_ADDR_LEN)) {
897             connected = TRUE;
898             break;
899         }
900     }
901     return connected;
902 }
903 
904 /*******************************************************************************
905 **
906 ** Function         gatt_check_connection_state_by_tcb
907 **
908 ** Description
909 **
910 ** Returns           TRUE if connected. Otherwise connection not established.
911 **
912 *******************************************************************************/
gatt_check_connection_state_by_tcb(tGATT_TCB * p_tcb)913 BOOLEAN gatt_check_connection_state_by_tcb(tGATT_TCB *p_tcb)
914 {
915     BOOLEAN connected = FALSE;
916 
917     if(p_tcb && gatt_get_ch_state(p_tcb) == GATT_CH_OPEN) {
918         connected = TRUE;
919     }
920 
921     return connected;
922 }
923 
924 /*******************************************************************************
925 **
926 ** Function         gatt_find_i_tcb_by_addr
927 **
928 ** Description      The function searches for an empty tcb entry, and return the index.
929 **
930 ** Returns           GATT_INDEX_INVALID if not found. Otherwise index to the tcb.
931 **
932 *******************************************************************************/
gatt_find_i_tcb_by_addr(BD_ADDR bda,tBT_TRANSPORT transport)933 UINT8 gatt_find_i_tcb_by_addr(BD_ADDR bda, tBT_TRANSPORT transport)
934 {
935     UINT8 i = 0;
936     list_node_t *p_node = NULL;
937     tGATT_TCB   *p_tcb  = NULL;
938     for(p_node = list_begin(gatt_cb.p_tcb_list); p_node; p_node = list_next(p_node)) {
939 	p_tcb = list_node(p_node);
940         if (!memcmp(p_tcb->peer_bda, bda, BD_ADDR_LEN) &&
941                 p_tcb->transport == transport) {
942 	    i = p_tcb->tcb_idx;
943             return i;
944         }
945     }
946     return GATT_INDEX_INVALID;
947 }
948 
949 /*******************************************************************************
950 **
951 ** Function         gatt_get_tcb_by_idx
952 **
953 ** Description      The function get TCB using the TCB index
954 **
955 ** Returns           NULL if not found. Otherwise index to the tcb.
956 **
957 *******************************************************************************/
gatt_get_tcb_by_idx(UINT8 tcb_idx)958 tGATT_TCB *gatt_get_tcb_by_idx(UINT8 tcb_idx)
959 {
960     tGATT_TCB   *p_tcb  = NULL;
961     list_node_t *p_node = NULL;
962     for(p_node = list_begin(gatt_cb.p_tcb_list); p_node; p_node = list_next(p_node)) {
963 	p_tcb = list_node(p_node);
964         if ( (tcb_idx < GATT_MAX_PHY_CHANNEL) && p_tcb->in_use && p_tcb->tcb_idx == tcb_idx ) {
965             break;
966         } else {
967 	    p_tcb = NULL;
968 	}
969     }
970 
971     return p_tcb;
972 }
973 
974 /*******************************************************************************
975 **
976 ** Function         gatt_find_tcb_by_addr
977 **
978 ** Description      The function searches for an empty tcb entry, and return pointer.
979 **
980 ** Returns           NULL if not found. Otherwise index to the tcb.
981 **
982 *******************************************************************************/
gatt_find_tcb_by_addr(BD_ADDR bda,tBT_TRANSPORT transport)983 tGATT_TCB *gatt_find_tcb_by_addr(BD_ADDR bda, tBT_TRANSPORT transport)
984 {
985     tGATT_TCB   *p_tcb = NULL;
986     UINT8 i = 0;
987 
988     if ((i = gatt_find_i_tcb_by_addr(bda, transport)) != GATT_INDEX_INVALID) {
989         p_tcb = gatt_get_tcb_by_idx(i);
990     }
991 
992     return p_tcb;
993 }
994 /*******************************************************************************
995 **
996 ** Function         gatt_find_i_tcb_free
997 **
998 ** Description      The function searches for an empty tcb entry, and return the index.
999 **
1000 ** Returns           GATT_INDEX_INVALID if not found. Otherwise index to the tcb.
1001 **
1002 *******************************************************************************/
gatt_find_i_tcb_free(void)1003 UINT8 gatt_find_i_tcb_free(void)
1004 {
1005     UINT8 i = 0, j = GATT_INDEX_INVALID;
1006 
1007     for (i = 0; i < GATT_MAX_PHY_CHANNEL; i ++) {
1008         if (!((1 << i) & gatt_tcb_id)) {
1009             j = i;
1010             break;
1011         }
1012     }
1013     return j;
1014 }
1015 /*******************************************************************************
1016 **
1017 ** Function         gatt_tcb_alloc
1018 **
1019 ** Description      The function allocates tcb for given tcb_idx and update tcb_id
1020 **
1021 ** Returns          Allocated tcb block
1022 **
1023 *******************************************************************************/
gatt_tcb_alloc(UINT8 tcb_idx)1024 tGATT_TCB *gatt_tcb_alloc(UINT8 tcb_idx)
1025 {
1026     /* Allocate tcb block */
1027     tGATT_TCB *p_tcb = (tGATT_TCB *)osi_malloc(sizeof(tGATT_TCB));
1028     if (p_tcb && list_length(gatt_cb.p_tcb_list) < GATT_MAX_PHY_CHANNEL) {
1029         memset(p_tcb, 0, sizeof(tGATT_TCB));
1030         /* Add tcb  block to list in gatt_cb */
1031         list_append(gatt_cb.p_tcb_list, p_tcb);
1032         /*  Update tcb id */
1033         gatt_tcb_id |= 1 << tcb_idx;
1034     } else if(p_tcb) {
1035 	osi_free(p_tcb);
1036         p_tcb = NULL;
1037     }
1038     return p_tcb;
1039 }
1040 
1041 /*******************************************************************************
1042 **
1043 ** Function         gatt_tcb_free
1044 **
1045 ** Description      The function free the given tcb block and update tcb id
1046 **
1047 ** Returns          void
1048 **
1049 *******************************************************************************/
gatt_tcb_free(tGATT_TCB * p_tcb)1050 void gatt_tcb_free( tGATT_TCB *p_tcb)
1051 {
1052     UINT8 tcb_idx = p_tcb->tcb_idx;
1053     if (list_remove(gatt_cb.p_tcb_list, p_tcb)) {
1054         gatt_tcb_id &= ~(1 << tcb_idx);
1055     }
1056 }
1057 /*******************************************************************************
1058 **
1059 ** Function         gatt_allocate_tcb_by_bdaddr
1060 **
1061 ** Description      The function locate or allocate new tcb entry for matching bda.
1062 **
1063 ** Returns           GATT_INDEX_INVALID if not found. Otherwise index to the tcb.
1064 **
1065 *******************************************************************************/
gatt_allocate_tcb_by_bdaddr(BD_ADDR bda,tBT_TRANSPORT transport)1066 tGATT_TCB *gatt_allocate_tcb_by_bdaddr(BD_ADDR bda, tBT_TRANSPORT transport)
1067 {
1068     UINT8 i = 0;
1069     BOOLEAN allocated = FALSE;
1070     tGATT_TCB    *p_tcb = NULL;
1071 
1072     /* search for existing tcb with matching bda    */
1073     i = gatt_find_i_tcb_by_addr(bda, transport);
1074     /* find free tcb */
1075     if (i == GATT_INDEX_INVALID) {
1076         i = gatt_find_i_tcb_free();
1077         allocated = TRUE;
1078     }
1079     if (i != GATT_INDEX_INVALID) {
1080         p_tcb = gatt_tcb_alloc(i);
1081 	if (!p_tcb) {
1082 	    return NULL;
1083 	}
1084         if (allocated) {
1085             memset(p_tcb, 0, sizeof(tGATT_TCB));
1086             p_tcb->pending_enc_clcb = fixed_queue_new(QUEUE_SIZE_MAX);
1087             p_tcb->pending_ind_q = fixed_queue_new(QUEUE_SIZE_MAX);
1088             p_tcb->in_use = TRUE;
1089             p_tcb->tcb_idx = i;
1090             p_tcb->transport = transport;
1091         }
1092         memcpy(p_tcb->peer_bda, bda, BD_ADDR_LEN);
1093 #if (GATTS_INCLUDED == TRUE)
1094         gatt_sr_init_cl_status(p_tcb);
1095 #endif  ///GATTS_INCLUDED == TRUE
1096     }
1097     return p_tcb;
1098 }
1099 
1100 /*******************************************************************************
1101 **
1102 ** Function         gatt_convert_uuid16_to_uuid128
1103 **
1104 ** Description      Convert a 16 bits UUID to be an standard 128 bits one.
1105 **
1106 ** Returns          TRUE if two uuid match; FALSE otherwise.
1107 **
1108 *******************************************************************************/
gatt_convert_uuid16_to_uuid128(UINT8 uuid_128[LEN_UUID_128],UINT16 uuid_16)1109 void gatt_convert_uuid16_to_uuid128(UINT8 uuid_128[LEN_UUID_128], UINT16 uuid_16)
1110 {
1111     UINT8   *p = &uuid_128[LEN_UUID_128 - 4];
1112 
1113     memcpy (uuid_128, base_uuid, LEN_UUID_128);
1114 
1115     UINT16_TO_STREAM(p, uuid_16);
1116 }
1117 
1118 /*******************************************************************************
1119 **
1120 ** Function         gatt_convert_uuid32_to_uuid128
1121 **
1122 ** Description      Convert a 32 bits UUID to be an standard 128 bits one.
1123 **
1124 ** Returns          TRUE if two uuid match; FALSE otherwise.
1125 **
1126 *******************************************************************************/
gatt_convert_uuid32_to_uuid128(UINT8 uuid_128[LEN_UUID_128],UINT32 uuid_32)1127 void gatt_convert_uuid32_to_uuid128(UINT8 uuid_128[LEN_UUID_128], UINT32 uuid_32)
1128 {
1129     UINT8   *p = &uuid_128[LEN_UUID_128 - 4];
1130 
1131     memcpy (uuid_128, base_uuid, LEN_UUID_128);
1132 
1133     UINT32_TO_STREAM(p, uuid_32);
1134 }
1135 /*******************************************************************************
1136 **
1137 ** Function         gatt_uuid_compare
1138 **
1139 ** Description      Compare two UUID to see if they are the same.
1140 **
1141 ** Returns          TRUE if two uuid match; FALSE otherwise.
1142 **
1143 *******************************************************************************/
gatt_uuid_compare(tBT_UUID src,tBT_UUID tar)1144 BOOLEAN gatt_uuid_compare (tBT_UUID src, tBT_UUID tar)
1145 {
1146     UINT8  su[LEN_UUID_128], tu[LEN_UUID_128];
1147     UINT8  *ps, *pt;
1148 
1149     /* any of the UUID is unspecified */
1150     if (src.len == 0 || tar.len == 0) {
1151         return TRUE;
1152     }
1153 
1154     /* If both are 16-bit, we can do a simple compare */
1155     if (src.len == LEN_UUID_16 && tar.len == LEN_UUID_16) {
1156         return src.uu.uuid16 == tar.uu.uuid16;
1157     }
1158 
1159     /* If both are 32-bit, we can do a simple compare */
1160     if (src.len == LEN_UUID_32 && tar.len == LEN_UUID_32) {
1161         return src.uu.uuid32 == tar.uu.uuid32;
1162     }
1163 
1164     /* One or both of the UUIDs is 128-bit */
1165     if (src.len == LEN_UUID_16) {
1166         /* convert a 16 bits UUID to 128 bits value */
1167         gatt_convert_uuid16_to_uuid128(su, src.uu.uuid16);
1168         ps = su;
1169     } else if (src.len == LEN_UUID_32) {
1170         gatt_convert_uuid32_to_uuid128(su, src.uu.uuid32);
1171         ps = su;
1172     } else {
1173         ps = src.uu.uuid128;
1174     }
1175 
1176     if (tar.len == LEN_UUID_16) {
1177         /* convert a 16 bits UUID to 128 bits value */
1178         gatt_convert_uuid16_to_uuid128(tu, tar.uu.uuid16);
1179         pt = tu;
1180     } else if (tar.len == LEN_UUID_32) {
1181         /* convert a 32 bits UUID to 128 bits value */
1182         gatt_convert_uuid32_to_uuid128(tu, tar.uu.uuid32);
1183         pt = tu;
1184     } else {
1185         pt = tar.uu.uuid128;
1186     }
1187 
1188     return (memcmp(ps, pt, LEN_UUID_128) == 0);
1189 }
1190 
1191 /*******************************************************************************
1192 **
1193 ** Function         gatt_build_uuid_to_stream
1194 **
1195 ** Description      Add UUID into stream.
1196 **
1197 ** Returns          UUID length.
1198 **
1199 *******************************************************************************/
gatt_build_uuid_to_stream(UINT8 ** p_dst,tBT_UUID uuid)1200 UINT8 gatt_build_uuid_to_stream(UINT8 **p_dst, tBT_UUID uuid)
1201 {
1202     UINT8   *p = *p_dst;
1203     UINT8   len = 0;
1204 
1205     if (uuid.len == LEN_UUID_16) {
1206         UINT16_TO_STREAM (p, uuid.uu.uuid16);
1207         len = LEN_UUID_16;
1208     } else if (uuid.len == LEN_UUID_32) { /* always convert 32 bits into 128 bits as alwats */
1209         gatt_convert_uuid32_to_uuid128(p, uuid.uu.uuid32);
1210         p += LEN_UUID_128;
1211         len = LEN_UUID_128;
1212     } else if (uuid.len == LEN_UUID_128) {
1213         ARRAY_TO_STREAM (p, uuid.uu.uuid128, LEN_UUID_128);
1214         len = LEN_UUID_128;
1215     }
1216 
1217     *p_dst = p;
1218     return len;
1219 }
1220 
1221 /*******************************************************************************
1222 **
1223 ** Function         gatt_parse_uuid_from_cmd
1224 **
1225 ** Description      Convert a 128 bits UUID into a 16 bits UUID.
1226 **
1227 ** Returns          TRUE if command sent, otherwise FALSE.
1228 **
1229 *******************************************************************************/
gatt_parse_uuid_from_cmd(tBT_UUID * p_uuid_rec,UINT16 uuid_size,UINT8 ** p_data)1230 BOOLEAN gatt_parse_uuid_from_cmd(tBT_UUID *p_uuid_rec, UINT16 uuid_size, UINT8 **p_data)
1231 {
1232     BOOLEAN is_base_uuid, ret = TRUE;
1233     UINT8  xx;
1234     UINT8 *p_uuid = *p_data;
1235 
1236     memset(p_uuid_rec, 0, sizeof(tBT_UUID));
1237 
1238     switch (uuid_size) {
1239     case LEN_UUID_16:
1240         p_uuid_rec->len = uuid_size;
1241         STREAM_TO_UINT16 (p_uuid_rec->uu.uuid16, p_uuid);
1242         *p_data += LEN_UUID_16;
1243         break;
1244 
1245     case LEN_UUID_128:
1246         /* See if we can compress his UUID down to 16 or 32bit UUIDs */
1247         is_base_uuid = TRUE;
1248         for (xx = 0; xx < LEN_UUID_128 - 4; xx++) {
1249             if (p_uuid[xx] != base_uuid[xx]) {
1250                 is_base_uuid = FALSE;
1251                 break;
1252             }
1253         }
1254         if (is_base_uuid) {
1255             if ((p_uuid[LEN_UUID_128 - 1] == 0) && (p_uuid[LEN_UUID_128 - 2] == 0)) {
1256                 p_uuid += (LEN_UUID_128 - 4);
1257                 p_uuid_rec->len = LEN_UUID_16;
1258                 STREAM_TO_UINT16(p_uuid_rec->uu.uuid16, p_uuid);
1259             } else {
1260                 p_uuid += (LEN_UUID_128 - LEN_UUID_32);
1261                 p_uuid_rec->len = LEN_UUID_32;
1262                 STREAM_TO_UINT32(p_uuid_rec->uu.uuid32, p_uuid);
1263             }
1264         }
1265         if (!is_base_uuid) {
1266             p_uuid_rec->len = LEN_UUID_128;
1267             memcpy(p_uuid_rec->uu.uuid128, p_uuid, LEN_UUID_128);
1268         }
1269         *p_data += LEN_UUID_128;
1270         break;
1271 
1272     /* do not allow 32 bits UUID in ATT PDU now */
1273     case LEN_UUID_32:
1274         GATT_TRACE_ERROR("DO NOT ALLOW 32 BITS UUID IN ATT PDU");
1275     case 0:
1276     default:
1277         if (uuid_size != 0) {
1278             ret = FALSE;
1279         }
1280         GATT_TRACE_WARNING("gatt_parse_uuid_from_cmd invalid uuid size");
1281         break;
1282     }
1283 
1284     return ( ret);
1285 }
1286 
1287 /*******************************************************************************
1288 **
1289 ** Function         gatt_start_rsp_timer
1290 **
1291 ** Description      Start a wait_for_response timer.
1292 **
1293 ** Returns          TRUE if command sent, otherwise FALSE.
1294 **
1295 *******************************************************************************/
gatt_start_rsp_timer(UINT16 clcb_idx)1296 void gatt_start_rsp_timer(UINT16 clcb_idx)
1297 {
1298     tGATT_CLCB *p_clcb = gatt_clcb_find_by_idx(clcb_idx);
1299     UINT32 timeout = GATT_WAIT_FOR_RSP_TOUT;
1300     p_clcb->rsp_timer_ent.param  = (TIMER_PARAM_TYPE)p_clcb;
1301     if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY &&
1302             p_clcb->op_subtype == GATT_DISC_SRVC_ALL) {
1303         timeout = GATT_WAIT_FOR_DISC_RSP_TOUT;
1304     }
1305     btu_start_timer (&p_clcb->rsp_timer_ent, BTU_TTYPE_ATT_WAIT_FOR_RSP,
1306                      timeout);
1307 }
1308 /*******************************************************************************
1309 **
1310 ** Function         gatt_start_conf_timer
1311 **
1312 ** Description      Start a wait_for_confirmation timer.
1313 **
1314 ** Returns          TRUE if command sent, otherwise FALSE.
1315 **
1316 *******************************************************************************/
gatt_start_conf_timer(tGATT_TCB * p_tcb)1317 void gatt_start_conf_timer(tGATT_TCB    *p_tcb)
1318 {
1319     p_tcb->conf_timer_ent.param  = (TIMER_PARAM_TYPE)p_tcb;
1320     btu_start_timer (&p_tcb->conf_timer_ent, BTU_TTYPE_ATT_WAIT_FOR_RSP,
1321                      GATT_WAIT_FOR_RSP_TOUT);
1322 }
1323 /*******************************************************************************
1324 **
1325 ** Function         gatt_start_ind_ack_timer
1326 **
1327 ** Description      start the application ack timer
1328 **
1329 ** Returns          void
1330 **
1331 *******************************************************************************/
gatt_start_ind_ack_timer(tGATT_TCB * p_tcb)1332 void gatt_start_ind_ack_timer(tGATT_TCB *p_tcb)
1333 {
1334     p_tcb->ind_ack_timer_ent.param  = (TIMER_PARAM_TYPE)p_tcb;
1335     /* start notification cache timer */
1336     btu_start_timer (&p_tcb->ind_ack_timer_ent, BTU_TTYPE_ATT_WAIT_FOR_IND_ACK,
1337                      GATT_WAIT_FOR_IND_ACK_TOUT);
1338 
1339 }
1340 /*******************************************************************************
1341 **
1342 ** Function         gatt_rsp_timeout
1343 **
1344 ** Description      Called when GATT wait for ATT command response timer expires
1345 **
1346 ** Returns          void
1347 **
1348 *******************************************************************************/
gatt_rsp_timeout(TIMER_LIST_ENT * p_tle)1349 void gatt_rsp_timeout(TIMER_LIST_ENT *p_tle)
1350 {
1351     tGATT_CLCB *p_clcb = (tGATT_CLCB *)p_tle->param;
1352     if (p_clcb == NULL || p_clcb->p_tcb == NULL) {
1353         GATT_TRACE_WARNING("gatt_rsp_timeout clcb is already deleted");
1354         return;
1355     }
1356     if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY &&
1357             p_clcb->op_subtype == GATT_DISC_SRVC_ALL &&
1358             p_clcb->retry_count < GATT_REQ_RETRY_LIMIT) {
1359         UINT8 rsp_code;
1360         GATT_TRACE_WARNING("gatt_rsp_timeout retry discovery primary service");
1361         if (p_clcb != gatt_cmd_dequeue(p_clcb->p_tcb, &rsp_code)) {
1362             GATT_TRACE_ERROR("gatt_rsp_timeout command queue out of sync, disconnect");
1363         } else {
1364             p_clcb->retry_count++;
1365 #if (GATTC_INCLUDED == TRUE)
1366             gatt_act_discovery(p_clcb);
1367 #endif  ///GATTC_INCLUDED == TRUE
1368             return;
1369         }
1370     }
1371 
1372     GATT_TRACE_WARNING("gatt_rsp_timeout disconnecting...");
1373     gatt_disconnect (p_clcb->p_tcb);
1374 }
1375 
1376 /*******************************************************************************
1377 **
1378 ** Function         gatt_ind_ack_timeout
1379 **
1380 ** Description      Called when GATT wait for ATT handle confirmation timeout
1381 **
1382 ** Returns          void
1383 **
1384 *******************************************************************************/
gatt_ind_ack_timeout(TIMER_LIST_ENT * p_tle)1385 void gatt_ind_ack_timeout(TIMER_LIST_ENT *p_tle)
1386 {
1387     tGATT_TCB *p_tcb = (tGATT_TCB *)p_tle->param;
1388 
1389     GATT_TRACE_WARNING("gatt_ind_ack_timeout send ack now");
1390 
1391     if (p_tcb != NULL) {
1392         p_tcb->ind_count = 0;
1393     }
1394 
1395     attp_send_cl_msg(((tGATT_TCB *)p_tle->param), 0, GATT_HANDLE_VALUE_CONF, NULL);
1396 }
1397 /*******************************************************************************
1398 **
1399 ** Function         gatt_sr_find_i_rcb_by_handle
1400 **
1401 ** Description      The function searches for a service that owns a specific handle.
1402 **
1403 ** Returns          GATT_MAX_SR_PROFILES if not found. Otherwise index of th eservice.
1404 **
1405 *******************************************************************************/
gatt_sr_find_i_rcb_by_handle(UINT16 handle)1406 UINT8 gatt_sr_find_i_rcb_by_handle(UINT16 handle)
1407 {
1408     UINT8  i_rcb = 0;
1409 
1410     for ( ; i_rcb < GATT_MAX_SR_PROFILES; i_rcb++) {
1411         if (gatt_cb.sr_reg[i_rcb].in_use &&
1412                 gatt_cb.sr_reg[i_rcb].s_hdl <= handle &&
1413                 gatt_cb.sr_reg[i_rcb].e_hdl >= handle ) {
1414             break;
1415         }
1416     }
1417     return i_rcb;
1418 }
1419 
1420 /*******************************************************************************
1421 **
1422 ** Function         gatt_sr_find_i_rcb_by_handle
1423 **
1424 ** Description      The function searches for a service that owns a specific handle.
1425 **
1426 ** Returns          GATT_MAX_SR_PROFILES if not found. Otherwise index of th eservice.
1427 **
1428 *******************************************************************************/
1429 #if (GATTS_INCLUDED == TRUE)
gatt_sr_find_i_rcb_by_app_id(tBT_UUID * p_app_uuid128,tBT_UUID * p_svc_uuid,UINT16 svc_inst)1430 UINT8 gatt_sr_find_i_rcb_by_app_id(tBT_UUID *p_app_uuid128, tBT_UUID *p_svc_uuid, UINT16 svc_inst)
1431 {
1432     UINT8           i_rcb = 0;
1433     tGATT_SR_REG    *p_sreg;
1434     tBT_UUID        *p_this_uuid;
1435 
1436     for (i_rcb = 0, p_sreg = gatt_cb.sr_reg; i_rcb < GATT_MAX_SR_PROFILES; i_rcb++, p_sreg++) {
1437         if ( p_sreg->in_use ) {
1438             p_this_uuid = gatts_get_service_uuid (p_sreg->p_db);
1439 
1440             if (p_this_uuid &&
1441                     gatt_uuid_compare (*p_app_uuid128, p_sreg->app_uuid ) &&
1442                     gatt_uuid_compare (*p_svc_uuid, *p_this_uuid) &&
1443                     (svc_inst == p_sreg->service_instance)) {
1444                 GATT_TRACE_ERROR ("Active Service Found ");
1445                 gatt_dbg_display_uuid(*p_svc_uuid);
1446 
1447                 break;
1448             }
1449         }
1450     }
1451     return i_rcb;
1452 }
1453 #endif  ///GATTS_INCLUDED == TRUE
1454 /*******************************************************************************
1455 **
1456 ** Function         gatt_sr_find_i_rcb_by_handle
1457 **
1458 ** Description      The function searches for a service that owns a specific handle.
1459 **
1460 ** Returns          0 if not found. Otherwise index of th eservice.
1461 **
1462 *******************************************************************************/
gatt_sr_alloc_rcb(tGATT_HDL_LIST_ELEM * p_list)1463 UINT8 gatt_sr_alloc_rcb(tGATT_HDL_LIST_ELEM *p_list )
1464 {
1465     UINT8   ii = 0;
1466     tGATT_SR_REG    *p_sreg = NULL;
1467 
1468     /*this is a new application servoce start */
1469     for (ii = 0, p_sreg = gatt_cb.sr_reg; ii < GATT_MAX_SR_PROFILES; ii++, p_sreg++) {
1470         if (!p_sreg->in_use) {
1471             memset (p_sreg, 0, sizeof(tGATT_SR_REG));
1472 
1473             p_sreg->in_use = TRUE;
1474             memcpy (&p_sreg->app_uuid, &p_list->asgn_range.app_uuid128, sizeof(tBT_UUID));
1475 
1476             p_sreg->service_instance    = p_list->asgn_range.svc_inst;
1477             p_sreg->type                = p_list->asgn_range.is_primary ? GATT_UUID_PRI_SERVICE : GATT_UUID_SEC_SERVICE;
1478             p_sreg->s_hdl               = p_list->asgn_range.s_handle;
1479             p_sreg->e_hdl               = p_list->asgn_range.e_handle;
1480             p_sreg->p_db                = &p_list->svc_db;
1481 
1482             GATT_TRACE_DEBUG ("total buffer in db [%d]", fixed_queue_length(p_sreg->p_db->svc_buffer));
1483             break;
1484         }
1485     }
1486 
1487     return ii;
1488 }
1489 /*******************************************************************************
1490 **
1491 ** Function         gatt_sr_get_sec_info
1492 **
1493 ** Description      Get the security flag and key size information for the peer
1494 **                  device.
1495 **
1496 ** Returns          void
1497 **
1498 *******************************************************************************/
gatt_sr_get_sec_info(BD_ADDR rem_bda,tBT_TRANSPORT transport,UINT8 * p_sec_flag,UINT8 * p_key_size)1499 void gatt_sr_get_sec_info(BD_ADDR rem_bda, tBT_TRANSPORT transport, UINT8 *p_sec_flag, UINT8 *p_key_size)
1500 {
1501     UINT8           sec_flag = 0;
1502 
1503     BTM_GetSecurityFlagsByTransport(rem_bda, &sec_flag, transport);
1504 
1505     sec_flag &= (GATT_SEC_FLAG_LKEY_UNAUTHED | GATT_SEC_FLAG_LKEY_AUTHED | GATT_SEC_FLAG_ENCRYPTED | GATT_SEC_FLAG_AUTHORIZATION);
1506 #if (SMP_INCLUDED == TRUE)
1507     *p_key_size = btm_ble_read_sec_key_size(rem_bda);
1508 #endif  ///SMP_INCLUDED == TRUE
1509     *p_sec_flag = sec_flag;
1510 }
1511 /*******************************************************************************
1512 **
1513 ** Function         gatt_sr_send_req_callback
1514 **
1515 ** Description
1516 **
1517 **
1518 ** Returns          void
1519 **
1520 *******************************************************************************/
gatt_sr_send_req_callback(UINT16 conn_id,UINT32 trans_id,tGATTS_REQ_TYPE type,tGATTS_DATA * p_data)1521 void gatt_sr_send_req_callback(UINT16 conn_id,
1522                                UINT32 trans_id,
1523                                tGATTS_REQ_TYPE type, tGATTS_DATA *p_data)
1524 {
1525     tGATT_IF        gatt_if = GATT_GET_GATT_IF(conn_id);
1526     tGATT_REG       *p_reg = gatt_get_regcb(gatt_if);
1527 
1528     if (!p_reg ) {
1529         GATT_TRACE_ERROR ("p_reg not found discard request");
1530         return;
1531     }
1532 
1533     if ( p_reg->in_use &&
1534             p_reg->app_cb.p_req_cb) {
1535         (*p_reg->app_cb.p_req_cb)(conn_id, trans_id, type, p_data);
1536     } else {
1537         GATT_TRACE_WARNING("Call back not found for application conn_id=%d", conn_id);
1538     }
1539 
1540 }
1541 
1542 /*******************************************************************************
1543 **
1544 ** Function         gatt_send_error_rsp
1545 **
1546 ** Description      This function sends an error response.
1547 **
1548 ** Returns          void
1549 **
1550 *******************************************************************************/
gatt_send_error_rsp(tGATT_TCB * p_tcb,UINT8 err_code,UINT8 op_code,UINT16 handle,BOOLEAN deq)1551 tGATT_STATUS gatt_send_error_rsp (tGATT_TCB *p_tcb, UINT8 err_code, UINT8 op_code,
1552                                   UINT16 handle, BOOLEAN deq)
1553 {
1554     tGATT_ERROR      error;
1555     tGATT_STATUS     status;
1556     BT_HDR           *p_buf;
1557 
1558     error.cmd_code = op_code;
1559     error.reason = err_code;
1560     error.handle = handle;
1561 
1562     if ((p_buf = attp_build_sr_msg(p_tcb, GATT_RSP_ERROR, (tGATT_SR_MSG *)&error)) != NULL) {
1563         status = attp_send_sr_msg (p_tcb, p_buf);
1564     } else {
1565         status = GATT_INSUF_RESOURCE;
1566     }
1567 #if (GATTS_INCLUDED == TRUE)
1568     if (deq) {
1569         gatt_dequeue_sr_cmd(p_tcb);
1570     }
1571 #endif  ///GATTS_INCLUDED == TRUE
1572     return status;
1573 }
1574 
1575 #if (SDP_INCLUDED == TRUE && CLASSIC_BT_GATT_INCLUDED == TRUE)
1576 /*******************************************************************************
1577 **
1578 ** Function         gatt_add_sdp_record
1579 **
1580 ** Description      This function add a SDP record for a GATT primary service
1581 **
1582 ** Returns          0 if error else sdp handle for the record.
1583 **
1584 *******************************************************************************/
gatt_add_sdp_record(tBT_UUID * p_uuid,UINT16 start_hdl,UINT16 end_hdl)1585 UINT32 gatt_add_sdp_record (tBT_UUID *p_uuid, UINT16 start_hdl, UINT16 end_hdl)
1586 {
1587     tSDP_PROTOCOL_ELEM  proto_elem_list[2];
1588     UINT32              sdp_handle;
1589     UINT16              list = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
1590     UINT8               buff[60];
1591     UINT8               *p = buff;
1592 
1593     GATT_TRACE_DEBUG("gatt_add_sdp_record s_hdl=0x%x  s_hdl=0x%x", start_hdl, end_hdl);
1594 
1595     if ((sdp_handle = SDP_CreateRecord()) == 0) {
1596         return 0;
1597     }
1598 
1599     switch (p_uuid->len) {
1600     case LEN_UUID_16:
1601         SDP_AddServiceClassIdList(sdp_handle, 1, &p_uuid->uu.uuid16);
1602         break;
1603 
1604     case LEN_UUID_32:
1605         UINT8_TO_BE_STREAM (p, (UUID_DESC_TYPE << 3) | SIZE_FOUR_BYTES);
1606         UINT32_TO_BE_STREAM (p, p_uuid->uu.uuid32);
1607         SDP_AddAttribute (sdp_handle, ATTR_ID_SERVICE_CLASS_ID_LIST, DATA_ELE_SEQ_DESC_TYPE,
1608                           (UINT32) (p - buff), buff);
1609         break;
1610 
1611     case LEN_UUID_128:
1612         UINT8_TO_BE_STREAM (p, (UUID_DESC_TYPE << 3) | SIZE_SIXTEEN_BYTES);
1613         ARRAY_TO_BE_STREAM_REVERSE (p, p_uuid->uu.uuid128, LEN_UUID_128);
1614         SDP_AddAttribute (sdp_handle, ATTR_ID_SERVICE_CLASS_ID_LIST, DATA_ELE_SEQ_DESC_TYPE,
1615                           (UINT32) (p - buff), buff);
1616         break;
1617 
1618     default:
1619         GATT_TRACE_ERROR("inavlid UUID len=%d", p_uuid->len);
1620         SDP_DeleteRecord(sdp_handle);
1621         return 0;
1622         break;
1623     }
1624 
1625     /*** Fill out the protocol element sequence for SDP ***/
1626     proto_elem_list[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
1627     proto_elem_list[0].num_params    = 1;
1628     proto_elem_list[0].params[0]     = BT_PSM_ATT;
1629     proto_elem_list[1].protocol_uuid = UUID_PROTOCOL_ATT;
1630     proto_elem_list[1].num_params    = 2;
1631     proto_elem_list[1].params[0]     = start_hdl;
1632     proto_elem_list[1].params[1]     = end_hdl;
1633 
1634     SDP_AddProtocolList(sdp_handle, 2, proto_elem_list);
1635 
1636     /* Make the service browseable */
1637     SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &list);
1638 
1639     return (sdp_handle);
1640 }
1641 #endif  ///SDP_INCLUDED == TRUE && CLASSIC_BT_GATT_INCLUDED == TRUE
1642 
1643 #if GATT_CONFORMANCE_TESTING == TRUE
1644 /*******************************************************************************
1645 **
1646 ** Function         gatt_set_err_rsp
1647 **
1648 ** Description      This function is called to set the test confirm value
1649 **
1650 ** Returns          void
1651 **
1652 *******************************************************************************/
gatt_set_err_rsp(BOOLEAN enable,UINT8 req_op_code,UINT8 err_status)1653 void gatt_set_err_rsp(BOOLEAN enable, UINT8 req_op_code, UINT8 err_status)
1654 {
1655     GATT_TRACE_DEBUG("gatt_set_err_rsp enable=%d op_code=%d, err_status=%d", enable, req_op_code, err_status);
1656     gatt_cb.enable_err_rsp  = enable;
1657     gatt_cb.req_op_code     = req_op_code;
1658     gatt_cb.err_status      = err_status;
1659 }
1660 #endif
1661 
1662 
1663 
1664 /*******************************************************************************
1665 **
1666 ** Function         gatt_get_regcb
1667 **
1668 ** Description      The function returns the registration control block.
1669 **
1670 ** Returns          pointer to the registration control block or NULL
1671 **
1672 *******************************************************************************/
gatt_get_regcb(tGATT_IF gatt_if)1673 tGATT_REG *gatt_get_regcb (tGATT_IF gatt_if)
1674 {
1675     UINT8           ii = (UINT8)gatt_if;
1676     tGATT_REG       *p_reg = NULL;
1677 
1678     if (ii < 1 || ii > GATT_MAX_APPS) {
1679         GATT_TRACE_WARNING("gatt_if out of range [ = %d]", ii);
1680         return NULL;
1681     }
1682 
1683     // Index for cl_rcb is always 1 less than gatt_if.
1684     p_reg = &gatt_cb.cl_rcb[ii - 1];
1685 
1686     if (!p_reg->in_use) {
1687         GATT_TRACE_WARNING("gatt_if found but not in use.\n");
1688         return NULL;
1689     }
1690 
1691     return p_reg;
1692 }
1693 
1694 
1695 /*******************************************************************************
1696 **
1697 ** Function         gatt_is_clcb_allocated
1698 **
1699 ** Description      The function check clcb for conn_id is allocated or not
1700 **
1701 ** Returns           True already allocated
1702 **
1703 *******************************************************************************/
1704 
gatt_is_clcb_allocated(UINT16 conn_id)1705 BOOLEAN gatt_is_clcb_allocated (UINT16 conn_id)
1706 {
1707     BOOLEAN       is_allocated = FALSE;
1708 
1709     tGATT_CLCB  *p_clcb = gatt_clcb_find_by_conn_id(conn_id);
1710     if (p_clcb) {
1711         is_allocated = TRUE;
1712     }
1713     return is_allocated;
1714 }
1715 
1716 /*******************************************************************************
1717 **
1718 ** Function         gatt_clcb_find_by_conn_id
1719 **
1720 ** Description      Find clcb block using clcb_idx stored at the time of alloc
1721 **
1722 ** Returns          pointer to clcb corresponding to conn_id
1723 **
1724 *******************************************************************************/
1725 
gatt_clcb_find_by_conn_id(UINT16 conn_id)1726 tGATT_CLCB *gatt_clcb_find_by_conn_id(UINT16 conn_id)
1727 {
1728     list_node_t *p_node     = NULL;
1729     tGATT_CLCB  *p_clcb     = NULL;
1730     tGATT_CLCB  *p_clcb_ret = NULL;
1731     for(p_node = list_begin(gatt_cb.p_clcb_list); p_node; p_node = list_next(p_node)) {
1732         p_clcb = list_node(p_node);
1733 	if (p_clcb->conn_id == conn_id) {
1734 	    p_clcb_ret = p_clcb;
1735 	    break;
1736 	}
1737     }
1738     return p_clcb_ret;
1739 }
1740 
1741 /*******************************************************************************
1742 **
1743 ** Function         gatt_clcb_find_by_idx
1744 **
1745 ** Description      Find clcb block using clcb_idx stored at the time of alloc
1746 **
1747 ** Returns          pointer to clcb corresponding to clcb_idx
1748 **
1749 *******************************************************************************/
1750 
gatt_clcb_find_by_idx(UINT16 clcb_idx)1751 tGATT_CLCB *gatt_clcb_find_by_idx(UINT16 clcb_idx)
1752 {
1753     list_node_t *p_node     = NULL;
1754     tGATT_CLCB  *p_clcb     = NULL;
1755     tGATT_CLCB  *p_clcb_ret = NULL;
1756     for(p_node = list_begin(gatt_cb.p_clcb_list); p_node; p_node = list_next(p_node)) {
1757         p_clcb = list_node(p_node);
1758 	if (p_clcb->clcb_idx == clcb_idx) {
1759 	    p_clcb_ret = p_clcb;
1760 	    break;
1761 	}
1762     }
1763     return p_clcb_ret;
1764 }
1765 
1766 /*******************************************************************************
1767 **
1768 ** Function         gatt_clcb_alloc
1769 **
1770 ** Description      The function allocates a GATT  connection link control block
1771 **
1772 ** Returns           NULL if not found. Otherwise pointer to the connection link block.
1773 **
1774 *******************************************************************************/
gatt_clcb_alloc(UINT16 conn_id)1775 tGATT_CLCB *gatt_clcb_alloc (UINT16 conn_id)
1776 {
1777     tGATT_CLCB      *p_clcb = NULL;
1778     tGATT_IF        gatt_if = GATT_GET_GATT_IF(conn_id);
1779     UINT8           tcb_idx = GATT_GET_TCB_IDX(conn_id);
1780     tGATT_TCB       *p_tcb = gatt_get_tcb_by_idx(tcb_idx);
1781     tGATT_REG       *p_reg = gatt_get_regcb(gatt_if);
1782 
1783     if (list_length(gatt_cb.p_clcb_list) < GATT_CL_MAX_LCB) {
1784 	p_clcb = (tGATT_CLCB *)osi_malloc(sizeof(tGATT_CLCB));
1785 	if (p_clcb) {
1786 	   list_append(gatt_cb.p_clcb_list, p_clcb);
1787     	   memset(p_clcb, 0, sizeof(tGATT_CLCB));
1788            p_clcb->in_use      = TRUE;
1789            p_clcb->conn_id     = conn_id;
1790     	   //Add index of the clcb same as conn_id
1791            p_clcb->clcb_idx    = conn_id;
1792            p_clcb->p_reg       = p_reg;
1793            p_clcb->p_tcb       = p_tcb;
1794 	}
1795     }
1796     return p_clcb;
1797 }
1798 
1799 /*******************************************************************************
1800 **
1801 ** Function         gatt_clcb_dealloc
1802 **
1803 ** Description      The function de allocates a GATT  connection link control block
1804 **
1805 ** Returns         None
1806 **
1807 *******************************************************************************/
gatt_clcb_dealloc(tGATT_CLCB * p_clcb)1808 void gatt_clcb_dealloc (tGATT_CLCB *p_clcb)
1809 {
1810     if (p_clcb && p_clcb->in_use) {
1811         btu_free_timer(&p_clcb->rsp_timer_ent);
1812         memset(p_clcb, 0, sizeof(tGATT_CLCB));
1813         list_remove(gatt_cb.p_clcb_list, p_clcb);
1814 	p_clcb = NULL;
1815     }
1816 }
1817 
1818 
1819 
1820 /*******************************************************************************
1821 **
1822 ** Function         gatt_find_tcb_by_cid
1823 **
1824 ** Description      The function searches for an empty entry
1825 **                   in registration info table for GATT client
1826 **
1827 ** Returns           NULL if not found. Otherwise pointer to the rcb.
1828 **
1829 *******************************************************************************/
gatt_find_tcb_by_cid(UINT16 lcid)1830 tGATT_TCB *gatt_find_tcb_by_cid (UINT16 lcid)
1831 {
1832     tGATT_TCB   *p_tcb  = NULL;
1833     list_node_t *p_node = NULL;
1834     for(p_node = list_begin(gatt_cb.p_tcb_list); p_node; p_node = list_next(p_node)) {
1835 	p_tcb = list_node(p_node);
1836         if (p_tcb->in_use && p_tcb->att_lcid == lcid) {
1837             break;
1838         }
1839     }
1840     return p_tcb;
1841 }
1842 
1843 /*******************************************************************************
1844 **
1845 ** Function         gatt_num_apps_hold_link
1846 **
1847 ** Description      The function find the number of applcaitions is holding the link
1848 **
1849 ** Returns          total number of applications holding this acl link.
1850 **
1851 *******************************************************************************/
gatt_num_apps_hold_link(tGATT_TCB * p_tcb)1852 UINT8 gatt_num_apps_hold_link(tGATT_TCB *p_tcb)
1853 {
1854     UINT8 i, num = 0;
1855 
1856     for (i = 0; i < GATT_MAX_APPS; i ++) {
1857         if (p_tcb->app_hold_link[i]) {
1858             num ++;
1859         }
1860     }
1861 
1862     GATT_TRACE_DEBUG("gatt_num_apps_hold_link   num=%d",  num);
1863     return num;
1864 }
1865 
1866 
1867 /*******************************************************************************
1868 **
1869 ** Function         gatt_num_clcb_by_bd_addr
1870 **
1871 ** Description      The function searches all LCB with macthing bd address
1872 **
1873 ** Returns          total number of clcb found.
1874 **
1875 *******************************************************************************/
gatt_num_clcb_by_bd_addr(BD_ADDR bda)1876 UINT8 gatt_num_clcb_by_bd_addr(BD_ADDR bda)
1877 {
1878     UINT8 num = 0;
1879 
1880     list_node_t *p_node = NULL;
1881     tGATT_CLCB  *p_clcb = NULL;
1882     for(p_node = list_begin(gatt_cb.p_clcb_list); p_node; p_node = list_next(p_node)) {
1883         p_clcb = list_node(p_node);
1884 	if (memcmp(p_clcb->p_tcb->peer_bda, bda, BD_ADDR_LEN) == 0) {
1885 	    num++;
1886 	}
1887     }
1888     return num;
1889 }
1890 
1891 /*******************************************************************************
1892 **
1893 ** Function         gatt_sr_update_cback_cnt
1894 **
1895 ** Description      The function searches all LCB with macthing bd address
1896 **
1897 ** Returns          total number of clcb found.
1898 **
1899 *******************************************************************************/
gatt_sr_copy_prep_cnt_to_cback_cnt(tGATT_TCB * p_tcb)1900 void gatt_sr_copy_prep_cnt_to_cback_cnt(tGATT_TCB *p_tcb )
1901 {
1902 #if (GATTS_INCLUDED == TRUE)
1903     UINT8 i;
1904 
1905     if (p_tcb) {
1906         for (i = 0; i < GATT_MAX_APPS; i ++) {
1907             if (p_tcb->prep_cnt[i]) {
1908                 p_tcb->sr_cmd.cback_cnt[i] = 1;
1909             }
1910         }
1911     }
1912 #endif  ///GATTS_INCLUDED == TRUE
1913 }
1914 
1915 /*******************************************************************************
1916 **
1917 ** Function         gatt_sr_is_cback_cnt_zero
1918 **
1919 ** Description      The function searches all LCB with macthing bd address
1920 **
1921 ** Returns          True if thetotal application callback count is zero
1922 **
1923 *******************************************************************************/
gatt_sr_is_cback_cnt_zero(tGATT_TCB * p_tcb)1924 BOOLEAN gatt_sr_is_cback_cnt_zero(tGATT_TCB *p_tcb )
1925 {
1926     BOOLEAN status = TRUE;
1927 #if (GATTS_INCLUDED == TRUE)
1928     UINT8   i;
1929 
1930     if (p_tcb) {
1931         for (i = 0; i < GATT_MAX_APPS; i ++) {
1932             if (p_tcb->sr_cmd.cback_cnt[i]) {
1933                 status = FALSE;
1934                 break;
1935             }
1936         }
1937     } else {
1938         status = FALSE;
1939     }
1940 #endif  ///GATTS_INCLUDED == TRUE
1941     return status;
1942 }
1943 
1944 /*******************************************************************************
1945 **
1946 ** Function         gatt_sr_is_prep_cnt_zero
1947 **
1948 ** Description      Check the prepare write request count is zero or not
1949 **
1950 ** Returns          True no prepare write request
1951 **
1952 *******************************************************************************/
gatt_sr_is_prep_cnt_zero(tGATT_TCB * p_tcb)1953 BOOLEAN gatt_sr_is_prep_cnt_zero(tGATT_TCB *p_tcb)
1954 {
1955     BOOLEAN status = TRUE;
1956     UINT8   i;
1957 
1958     if (p_tcb) {
1959         for (i = 0; i < GATT_MAX_APPS; i ++) {
1960             if (p_tcb->prep_cnt[i]) {
1961                 status = FALSE;
1962                 break;
1963             }
1964         }
1965     } else {
1966         status = FALSE;
1967     }
1968     return status;
1969 }
1970 
1971 
1972 /*******************************************************************************
1973 **
1974 ** Function         gatt_sr_reset_cback_cnt
1975 **
1976 ** Description      Reset the application callback count to zero
1977 **
1978 ** Returns         None
1979 **
1980 *******************************************************************************/
gatt_sr_reset_cback_cnt(tGATT_TCB * p_tcb)1981 void gatt_sr_reset_cback_cnt(tGATT_TCB *p_tcb )
1982 {
1983 #if (GATTS_INCLUDED == TRUE)
1984     UINT8 i;
1985 
1986     if (p_tcb) {
1987         for (i = 0; i < GATT_MAX_APPS; i ++) {
1988             p_tcb->sr_cmd.cback_cnt[i] = 0;
1989         }
1990     }
1991 #endif  ///GATTS_INCLUDED == TRUE
1992 }
1993 
1994 /*******************************************************************************
1995 **
1996 ** Function         gatt_sr_reset_prep_cnt
1997 **
1998 ** Description     Reset the prep write count to zero
1999 **
2000 ** Returns        None
2001 **
2002 *******************************************************************************/
gatt_sr_reset_prep_cnt(tGATT_TCB * p_tcb)2003 void gatt_sr_reset_prep_cnt(tGATT_TCB *p_tcb )
2004 {
2005     UINT8 i;
2006     if (p_tcb) {
2007         for (i = 0; i < GATT_MAX_APPS; i ++) {
2008             p_tcb->prep_cnt[i] = 0;
2009         }
2010     }
2011 }
2012 
2013 
2014 /*******************************************************************************
2015 **
2016 ** Function         gatt_sr_update_cback_cnt
2017 **
2018 ** Description    Update the teh application callback count
2019 **
2020 ** Returns           None
2021 **
2022 *******************************************************************************/
gatt_sr_update_cback_cnt(tGATT_TCB * p_tcb,tGATT_IF gatt_if,BOOLEAN is_inc,BOOLEAN is_reset_first)2023 void gatt_sr_update_cback_cnt(tGATT_TCB *p_tcb, tGATT_IF gatt_if, BOOLEAN is_inc, BOOLEAN is_reset_first)
2024 {
2025 #if (GATTS_INCLUDED == TRUE)
2026     UINT8 idx = ((UINT8) gatt_if) - 1 ;
2027 
2028     if (p_tcb) {
2029         if (is_reset_first) {
2030             gatt_sr_reset_cback_cnt(p_tcb);
2031         }
2032         if (is_inc) {
2033             p_tcb->sr_cmd.cback_cnt[idx]++;
2034         } else {
2035             if ( p_tcb->sr_cmd.cback_cnt[idx]) {
2036                 p_tcb->sr_cmd.cback_cnt[idx]--;
2037             }
2038         }
2039     }
2040 #endif  ///GATTS_INCLUDED == TRUE
2041 }
2042 
2043 
2044 /*******************************************************************************
2045 **
2046 ** Function         gatt_sr_update_prep_cnt
2047 **
2048 ** Description    Update the teh prepare write request count
2049 **
2050 ** Returns           None
2051 **
2052 *******************************************************************************/
gatt_sr_update_prep_cnt(tGATT_TCB * p_tcb,tGATT_IF gatt_if,BOOLEAN is_inc,BOOLEAN is_reset_first)2053 void gatt_sr_update_prep_cnt(tGATT_TCB *p_tcb, tGATT_IF gatt_if, BOOLEAN is_inc, BOOLEAN is_reset_first)
2054 {
2055     UINT8 idx = ((UINT8) gatt_if) - 1 ;
2056 
2057     GATT_TRACE_DEBUG("gatt_sr_update_prep_cnt tcb idx=%d gatt_if=%d is_inc=%d is_reset_first=%d",
2058                      p_tcb->tcb_idx, gatt_if, is_inc, is_reset_first);
2059 
2060     if (p_tcb) {
2061         if (is_reset_first) {
2062             gatt_sr_reset_prep_cnt(p_tcb);
2063         }
2064         if (is_inc) {
2065             p_tcb->prep_cnt[idx]++;
2066         } else {
2067             if (p_tcb->prep_cnt[idx]) {
2068                 p_tcb->prep_cnt[idx]--;
2069             }
2070         }
2071     }
2072 }
2073 /*******************************************************************************
2074 **
2075 ** Function         gatt_cancel_open
2076 **
2077 ** Description      Cancel open request
2078 **
2079 ** Returns         Boolean
2080 **
2081 *******************************************************************************/
gatt_cancel_open(tGATT_IF gatt_if,BD_ADDR bda)2082 BOOLEAN gatt_cancel_open(tGATT_IF gatt_if, BD_ADDR bda)
2083 {
2084     tGATT_TCB *p_tcb = NULL;
2085     BOOLEAN status = TRUE;
2086 
2087     p_tcb = gatt_find_tcb_by_addr(bda, BT_TRANSPORT_LE);
2088 
2089     if (p_tcb) {
2090         if (gatt_get_ch_state(p_tcb) == GATT_CH_OPEN) {
2091             GATT_TRACE_ERROR("GATT_CancelConnect - link connected Too late to cancel");
2092             status = FALSE;
2093         } else {
2094             gatt_update_app_use_link_flag(gatt_if, p_tcb, FALSE, FALSE);
2095             if (!gatt_num_apps_hold_link(p_tcb)) {
2096                 gatt_disconnect(p_tcb);
2097             }
2098         }
2099     }
2100 
2101     return status;
2102 }
2103 
2104 /*******************************************************************************
2105 **
2106 ** Function         gatt_find_app_hold_link
2107 **
2108 ** Description      find the application that is holding the specified link
2109 **
2110 ** Returns         Boolean
2111 **
2112 *******************************************************************************/
gatt_find_app_hold_link(tGATT_TCB * p_tcb,UINT8 start_idx,UINT8 * p_found_idx,tGATT_IF * p_gatt_if)2113 BOOLEAN gatt_find_app_hold_link(tGATT_TCB *p_tcb, UINT8 start_idx, UINT8 *p_found_idx, tGATT_IF *p_gatt_if)
2114 {
2115     UINT8 i;
2116     BOOLEAN found = FALSE;
2117 
2118     for (i = start_idx; i < GATT_MAX_APPS; i ++) {
2119         if (p_tcb->app_hold_link[i]) {
2120             *p_gatt_if = p_tcb->app_hold_link[i];
2121             *p_found_idx = i;
2122             found = TRUE;
2123             break;
2124         }
2125     }
2126     return found;
2127 }
2128 
2129 /*******************************************************************************
2130 **
2131 ** Function         gatt_find_specific_app_in_hold_link
2132 **
2133 ** Description      find the specific application that is holding the specified link
2134 **
2135 ** Returns         Boolean
2136 **
2137 *******************************************************************************/
gatt_find_specific_app_in_hold_link(tGATT_TCB * p_tcb,tGATT_IF p_gatt_if)2138 BOOLEAN gatt_find_specific_app_in_hold_link(tGATT_TCB *p_tcb, tGATT_IF p_gatt_if)
2139 {
2140     UINT8 i;
2141     BOOLEAN found = FALSE;
2142 
2143     for (i = 0; i < GATT_MAX_APPS; i ++) {
2144         if (p_tcb->app_hold_link[i] && p_tcb->app_hold_link[i] == p_gatt_if) {
2145             found = TRUE;
2146             break;
2147         }
2148     }
2149     return found;
2150 }
2151 
2152 /*******************************************************************************
2153 **
2154 ** Function         gatt_cmd_enq
2155 **
2156 ** Description      Enqueue this command.
2157 **
2158 ** Returns          None.
2159 **
2160 *******************************************************************************/
gatt_cmd_enq(tGATT_TCB * p_tcb,UINT16 clcb_idx,BOOLEAN to_send,UINT8 op_code,BT_HDR * p_buf)2161 BOOLEAN gatt_cmd_enq(tGATT_TCB *p_tcb, UINT16 clcb_idx, BOOLEAN to_send, UINT8 op_code, BT_HDR *p_buf)
2162 {
2163     tGATT_CMD_Q  *p_cmd = &p_tcb->cl_cmd_q[p_tcb->next_slot_inq];
2164 
2165     p_cmd->to_send = to_send; /* waiting to be sent */
2166     p_cmd->op_code  = op_code;
2167     p_cmd->p_cmd    = p_buf;
2168     p_cmd->clcb_idx = clcb_idx;
2169 
2170     if (!to_send) {
2171         p_tcb->pending_cl_req = p_tcb->next_slot_inq;
2172     }
2173 
2174     p_tcb->next_slot_inq ++;
2175     p_tcb->next_slot_inq %= GATT_CL_MAX_LCB;
2176 
2177     return TRUE;
2178 }
2179 
2180 /*******************************************************************************
2181 **
2182 ** Function         gatt_cmd_dequeue
2183 **
2184 ** Description      dequeue the command in the client CCB command queue.
2185 **
2186 ** Returns          total number of clcb found.
2187 **
2188 *******************************************************************************/
gatt_cmd_dequeue(tGATT_TCB * p_tcb,UINT8 * p_op_code)2189 tGATT_CLCB *gatt_cmd_dequeue(tGATT_TCB *p_tcb, UINT8 *p_op_code)
2190 {
2191     tGATT_CMD_Q  *p_cmd = &p_tcb->cl_cmd_q[p_tcb->pending_cl_req];
2192     tGATT_CLCB *p_clcb = NULL;
2193 
2194     if (p_tcb->pending_cl_req != p_tcb->next_slot_inq) {
2195         p_clcb = gatt_clcb_find_by_idx(p_cmd->clcb_idx);
2196 
2197         *p_op_code = p_cmd->op_code;
2198 
2199         p_tcb->pending_cl_req ++;
2200         p_tcb->pending_cl_req %= GATT_CL_MAX_LCB;
2201     }
2202 
2203     return p_clcb;
2204 }
2205 
2206 /*******************************************************************************
2207 **
2208 ** Function         gatt_send_write_msg
2209 **
2210 ** Description      This real function send out the ATT message for write.
2211 **
2212 ** Returns          status code
2213 **
2214 *******************************************************************************/
gatt_send_write_msg(tGATT_TCB * p_tcb,UINT16 clcb_idx,UINT8 op_code,UINT16 handle,UINT16 len,UINT16 offset,UINT8 * p_data)2215 UINT8 gatt_send_write_msg (tGATT_TCB *p_tcb, UINT16 clcb_idx, UINT8 op_code,
2216                            UINT16 handle, UINT16 len,
2217                            UINT16 offset, UINT8 *p_data)
2218 {
2219     tGATT_CL_MSG     msg;
2220 
2221     msg.attr_value.handle = handle;
2222     msg.attr_value.len = len;
2223     msg.attr_value.offset = offset;
2224 
2225     memcpy (msg.attr_value.value, p_data, len);
2226 
2227     /* write by handle */
2228     return attp_send_cl_msg(p_tcb, clcb_idx, op_code, &msg);
2229 }
2230 
2231 /*******************************************************************************
2232 **
2233 ** Function         gatt_act_send_browse
2234 **
2235 ** Description      This function ends a browse command request, including read
2236 **                  information request and read by type request.
2237 **
2238 ** Returns          status code
2239 **
2240 *******************************************************************************/
gatt_act_send_browse(tGATT_TCB * p_tcb,UINT16 index,UINT8 op,UINT16 s_handle,UINT16 e_handle,tBT_UUID uuid)2241 UINT8 gatt_act_send_browse(tGATT_TCB *p_tcb, UINT16 index, UINT8 op, UINT16 s_handle,
2242                            UINT16 e_handle, tBT_UUID uuid)
2243 {
2244     tGATT_CL_MSG     msg;
2245 
2246     msg.browse.s_handle = s_handle;
2247     msg.browse.e_handle   = e_handle;
2248     memcpy(&msg.browse.uuid, &uuid, sizeof(tBT_UUID));
2249 
2250     /* write by handle */
2251     return attp_send_cl_msg(p_tcb, index, op, &msg);
2252 }
2253 
2254 /*******************************************************************************
2255 **
2256 ** Function         gatt_end_operation
2257 **
2258 ** Description      This function ends a discovery, send callback and finalize
2259 **                  some control value.
2260 **
2261 ** Returns          16 bits uuid.
2262 **
2263 *******************************************************************************/
gatt_end_operation(tGATT_CLCB * p_clcb,tGATT_STATUS status,void * p_data)2264 void gatt_end_operation(tGATT_CLCB *p_clcb, tGATT_STATUS status, void *p_data)
2265 {
2266     tGATT_CL_COMPLETE   cb_data;
2267     tGATT_CMPL_CBACK    *p_cmpl_cb = (p_clcb->p_reg) ? p_clcb->p_reg->app_cb.p_cmpl_cb : NULL;
2268     UINT8               op = p_clcb->operation, disc_type = GATT_DISC_MAX;
2269     tGATT_DISC_CMPL_CB  *p_disc_cmpl_cb = (p_clcb->p_reg) ? p_clcb->p_reg->app_cb.p_disc_cmpl_cb : NULL;
2270     UINT16              conn_id;
2271 #if (!CONFIG_BT_STACK_NO_LOG)
2272     UINT8               operation;
2273 #endif
2274 
2275     GATT_TRACE_DEBUG ("gatt_end_operation status=%d op=%d subtype=%d",
2276                       status, p_clcb->operation, p_clcb->op_subtype);
2277     memset(&cb_data.att_value, 0, sizeof(tGATT_VALUE));
2278 
2279     if (p_cmpl_cb != NULL && p_clcb->operation != 0) {
2280         if (p_clcb->operation == GATTC_OPTYPE_READ) {
2281             cb_data.att_value.handle   = p_clcb->s_handle;
2282             cb_data.att_value.len      = p_clcb->counter;
2283 
2284             if (p_data && p_clcb->counter) {
2285                 memcpy (cb_data.att_value.value, p_data, cb_data.att_value.len);
2286             }
2287         }
2288 
2289         if (p_clcb->operation == GATTC_OPTYPE_WRITE) {
2290             memset(&cb_data.att_value, 0, sizeof(tGATT_VALUE));
2291             cb_data.handle           =
2292                 cb_data.att_value.handle = p_clcb->s_handle;
2293             if (p_clcb->op_subtype == GATT_WRITE_PREPARE) {
2294                 if (p_data) {
2295                     cb_data.att_value = *((tGATT_VALUE *) p_data);
2296                 } else {
2297                     GATT_TRACE_DEBUG("Rcv Prepare write rsp but no data");
2298                 }
2299             }
2300         }
2301 
2302         if (p_clcb->operation == GATTC_OPTYPE_CONFIG) {
2303             cb_data.mtu = p_clcb->p_tcb->payload_size;
2304         }
2305 
2306         if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY) {
2307             disc_type = p_clcb->op_subtype;
2308         }
2309     }
2310 
2311     if (p_clcb->p_attr_buf) {
2312         osi_free(p_clcb->p_attr_buf);
2313     }
2314 
2315 #if !CONFIG_BT_STACK_NO_LOG
2316     operation =  p_clcb->operation;
2317 #endif
2318 
2319     conn_id = p_clcb->conn_id;
2320     btu_stop_timer(&p_clcb->rsp_timer_ent);
2321 
2322     gatt_clcb_dealloc(p_clcb);
2323 
2324     if (p_disc_cmpl_cb && (op == GATTC_OPTYPE_DISCOVERY)) {
2325         (*p_disc_cmpl_cb)(conn_id, disc_type, status);
2326     } else if (p_cmpl_cb && op) {
2327         (*p_cmpl_cb)(conn_id, op, status, &cb_data);
2328     } else {
2329         GATT_TRACE_WARNING ("gatt_end_operation not sent out op=%d p_disc_cmpl_cb:%p p_cmpl_cb:%p",
2330                             operation, p_disc_cmpl_cb, p_cmpl_cb);
2331     }
2332 }
2333 
2334 /*******************************************************************************
2335 **
2336 ** Function         gatt_cleanup_upon_disc
2337 **
2338 ** Description      This function cleans up the control blocks when L2CAP channel
2339 **                  disconnect.
2340 **
2341 ** Returns          16 bits uuid.
2342 **
2343 *******************************************************************************/
gatt_cleanup_upon_disc(BD_ADDR bda,UINT16 reason,tBT_TRANSPORT transport)2344 void gatt_cleanup_upon_disc(BD_ADDR bda, UINT16 reason, tBT_TRANSPORT transport)
2345 {
2346     tGATT_TCB       *p_tcb = NULL;
2347     tGATT_CLCB      *p_clcb;
2348     UINT8           i;
2349     UINT16          conn_id;
2350     tGATT_REG        *p_reg = NULL;
2351 
2352 
2353     GATT_TRACE_DEBUG ("gatt_cleanup_upon_disc ");
2354 
2355     if ((p_tcb = gatt_find_tcb_by_addr(bda, transport)) != NULL) {
2356         GATT_TRACE_DEBUG ("found p_tcb ");
2357         gatt_set_ch_state(p_tcb, GATT_CH_CLOSE);
2358         list_node_t *p_node = NULL;
2359         list_node_t *p_node_next = NULL;
2360 	for(p_node = list_begin(gatt_cb.p_clcb_list); p_node; p_node = p_node_next) {
2361             p_clcb = list_node(p_node);
2362             p_node_next = list_next(p_node);
2363             if (p_clcb->in_use && p_clcb->p_tcb == p_tcb) {
2364                 btu_stop_timer(&p_clcb->rsp_timer_ent);
2365                 GATT_TRACE_DEBUG ("found p_clcb conn_id=%d clcb_idx=%d", p_clcb->conn_id, p_clcb->clcb_idx);
2366                 if (p_clcb->operation != GATTC_OPTYPE_NONE) {
2367                     gatt_end_operation(p_clcb, GATT_ERROR, NULL);
2368                     p_clcb = NULL;
2369                 }
2370                 gatt_clcb_dealloc(p_clcb);
2371             }
2372         }
2373 
2374         btu_free_timer (&p_tcb->ind_ack_timer_ent);
2375         btu_free_timer (&p_tcb->conf_timer_ent);
2376         gatt_free_pending_ind(p_tcb);
2377         gatt_free_pending_enc_queue(p_tcb);
2378         gatt_free_pending_prepare_write_queue(p_tcb);
2379 #if (GATTS_INCLUDED)
2380         fixed_queue_free(p_tcb->sr_cmd.multi_rsp_q, osi_free_func);
2381         p_tcb->sr_cmd.multi_rsp_q = NULL;
2382 #endif /* #if (GATTS_INCLUDED) */
2383         for (i = 0; i < GATT_MAX_APPS; i ++) {
2384             p_reg = &gatt_cb.cl_rcb[i];
2385             if (p_reg->in_use && p_reg->app_cb.p_conn_cb) {
2386                 conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if);
2387                 GATT_TRACE_DEBUG ("found p_reg tcb_idx=%d gatt_if=%d  conn_id=0x%x", p_tcb->tcb_idx, p_reg->gatt_if, conn_id);
2388                 (*p_reg->app_cb.p_conn_cb)(p_reg->gatt_if,  bda, conn_id, FALSE, reason, transport);
2389             }
2390         }
2391         gatt_tcb_free(p_tcb);
2392     } else {
2393         GATT_TRACE_DEBUG ("exit gatt_cleanup_upon_disc ");
2394         BTM_Recovery_Pre_State();
2395     }
2396     gatt_delete_dev_from_srv_chg_clt_list(bda);
2397 }
2398 /*******************************************************************************
2399 **
2400 ** Function         gatt_dbg_req_op_name
2401 **
2402 ** Description      Get op code description name, for debug information.
2403 **
2404 ** Returns          UINT8 *: name of the operation.
2405 **
2406 *******************************************************************************/
gatt_dbg_op_name(UINT8 op_code)2407 UINT8 *gatt_dbg_op_name(UINT8 op_code)
2408 {
2409     UINT8 pseduo_op_code_idx = op_code & (~GATT_WRITE_CMD_MASK);
2410 
2411     if (op_code == GATT_CMD_WRITE ) {
2412         pseduo_op_code_idx = 0x14; /* just an index to op_code_name */
2413 
2414     }
2415 
2416     if (op_code == GATT_SIGN_CMD_WRITE) {
2417         pseduo_op_code_idx = 0x15; /* just an index to op_code_name */
2418     }
2419 
2420     if (pseduo_op_code_idx <= GATT_OP_CODE_MAX) {
2421         return (UINT8 *) op_code_name[pseduo_op_code_idx];
2422     } else {
2423         return (UINT8 *)"Op Code Exceed Max";
2424     }
2425 }
2426 
2427 /*******************************************************************************
2428 **
2429 ** Function         gatt_dbg_display_uuid
2430 **
2431 ** Description      Disaplay the UUID
2432 **
2433 ** Returns          None
2434 **
2435 *******************************************************************************/
gatt_dbg_display_uuid(tBT_UUID bt_uuid)2436 void gatt_dbg_display_uuid(tBT_UUID bt_uuid)
2437 {
2438     char str_buf[50];
2439     int x = 0;
2440 
2441     if (bt_uuid.len == LEN_UUID_16) {
2442         sprintf(str_buf, "0x%04x", bt_uuid.uu.uuid16);
2443     } else if (bt_uuid.len == LEN_UUID_32) {
2444         sprintf(str_buf, "0x%08x", (unsigned int)bt_uuid.uu.uuid32);
2445     } else if (bt_uuid.len == LEN_UUID_128) {
2446         x += sprintf(&str_buf[x], "0x%02x%02x%02x%02x%02x%02x%02x%02x",
2447                      bt_uuid.uu.uuid128[15], bt_uuid.uu.uuid128[14],
2448                      bt_uuid.uu.uuid128[13], bt_uuid.uu.uuid128[12],
2449                      bt_uuid.uu.uuid128[11], bt_uuid.uu.uuid128[10],
2450                      bt_uuid.uu.uuid128[9], bt_uuid.uu.uuid128[8]);
2451         sprintf(&str_buf[x], "%02x%02x%02x%02x%02x%02x%02x%02x",
2452                 bt_uuid.uu.uuid128[7], bt_uuid.uu.uuid128[6],
2453                 bt_uuid.uu.uuid128[5], bt_uuid.uu.uuid128[4],
2454                 bt_uuid.uu.uuid128[3], bt_uuid.uu.uuid128[2],
2455                 bt_uuid.uu.uuid128[1], bt_uuid.uu.uuid128[0]);
2456     } else {
2457         BCM_STRNCPY_S(str_buf, "Unknown UUID 0", 15);
2458     }
2459 
2460     GATT_TRACE_DEBUG ("UUID=[%s]", str_buf);
2461 
2462 }
2463 
2464 
2465 /*******************************************************************************
2466 **
2467 ** Function         gatt_is_bg_dev_for_app
2468 **
2469 ** Description      find is this one of the background devices for the application
2470 **
2471 ** Returns          TRUE this is one of the background devices for the  application
2472 **
2473 *******************************************************************************/
gatt_is_bg_dev_for_app(tGATT_BG_CONN_DEV * p_dev,tGATT_IF gatt_if)2474 BOOLEAN gatt_is_bg_dev_for_app(tGATT_BG_CONN_DEV *p_dev, tGATT_IF gatt_if)
2475 {
2476     UINT8   i;
2477 
2478     for (i = 0; i < GATT_MAX_APPS; i ++ ) {
2479         if (p_dev->in_use && (p_dev->gatt_if[i] == gatt_if)) {
2480             return TRUE;
2481         }
2482     }
2483     return FALSE;
2484 }
2485 /*******************************************************************************
2486 **
2487 ** Function         gatt_find_bg_dev
2488 **
2489 ** Description      find background connection device from the list.
2490 **
2491 ** Returns          pointer to the device record
2492 **
2493 *******************************************************************************/
gatt_find_bg_dev(BD_ADDR remote_bda)2494 tGATT_BG_CONN_DEV *gatt_find_bg_dev(BD_ADDR remote_bda)
2495 {
2496     tGATT_BG_CONN_DEV    *p_dev_list = &gatt_cb.bgconn_dev[0];
2497     UINT8   i;
2498 
2499     for (i = 0; i < GATT_MAX_BG_CONN_DEV; i ++, p_dev_list ++) {
2500         if (p_dev_list->in_use && !memcmp(p_dev_list->remote_bda, remote_bda, BD_ADDR_LEN)) {
2501             return p_dev_list;
2502         }
2503     }
2504     return NULL;
2505 }
2506 /*******************************************************************************
2507 **
2508 ** Function         gatt_alloc_bg_dev
2509 **
2510 ** Description      allocate a background connection device record
2511 **
2512 ** Returns          pointer to the device record
2513 **
2514 *******************************************************************************/
gatt_alloc_bg_dev(BD_ADDR remote_bda)2515 tGATT_BG_CONN_DEV *gatt_alloc_bg_dev(BD_ADDR remote_bda)
2516 {
2517     tGATT_BG_CONN_DEV    *p_dev_list = &gatt_cb.bgconn_dev[0];
2518     UINT8   i;
2519 
2520     for (i = 0; i < GATT_MAX_BG_CONN_DEV; i ++, p_dev_list ++) {
2521         if (!p_dev_list->in_use) {
2522             p_dev_list->in_use = TRUE;
2523             memcpy(p_dev_list->remote_bda, remote_bda, BD_ADDR_LEN);
2524 
2525             return p_dev_list;
2526         }
2527     }
2528     return NULL;
2529 }
2530 
2531 /*******************************************************************************
2532 **
2533 ** Function         gatt_add_bg_dev_list
2534 **
2535 ** Description      add/remove device from the background connection device list
2536 **
2537 ** Returns          TRUE if device added to the list; FALSE failed
2538 **
2539 *******************************************************************************/
gatt_add_bg_dev_list(tGATT_REG * p_reg,BD_ADDR bd_addr,BOOLEAN is_initator)2540 BOOLEAN gatt_add_bg_dev_list(tGATT_REG *p_reg,  BD_ADDR bd_addr, BOOLEAN is_initator)
2541 {
2542     tGATT_IF gatt_if =  p_reg->gatt_if;
2543     tGATT_BG_CONN_DEV   *p_dev = NULL;
2544     UINT8       i;
2545     BOOLEAN      ret = FALSE;
2546 
2547     if ((p_dev = gatt_find_bg_dev(bd_addr)) == NULL) {
2548         p_dev = gatt_alloc_bg_dev(bd_addr);
2549     }
2550 
2551     if (p_dev) {
2552         for (i = 0; i < GATT_MAX_APPS; i ++) {
2553             if (is_initator) {
2554                 if (p_dev->gatt_if[i] == gatt_if) {
2555                     GATT_TRACE_ERROR("device already in iniator white list");
2556                     return TRUE;
2557                 } else if (p_dev->gatt_if[i] == 0) {
2558                     p_dev->gatt_if[i] = gatt_if;
2559                     if (i == 0) {
2560                         ret = BTM_BleUpdateBgConnDev(TRUE, bd_addr);
2561                     } else {
2562                         ret = TRUE;
2563                     }
2564                     break;
2565                 }
2566             } else {
2567                 if (p_dev->listen_gif[i] == gatt_if) {
2568                     GATT_TRACE_ERROR("device already in adv white list");
2569                     return TRUE;
2570                 } else if (p_dev->listen_gif[i] == 0) {
2571                     if (p_reg->listening == GATT_LISTEN_TO_ALL) {
2572                         p_reg->listening = GATT_LISTEN_TO_NONE;
2573                     }
2574 
2575                     p_reg->listening ++;
2576                     p_dev->listen_gif[i] = gatt_if;
2577 
2578                     if (i == 0) {
2579                         // To check, we do not support background connection, code will not be called here
2580                         ret = BTM_BleUpdateAdvWhitelist(TRUE, bd_addr, 0, NULL);
2581                     } else {
2582                         ret = TRUE;
2583                     }
2584                     break;
2585                 }
2586             }
2587         }
2588     } else {
2589         GATT_TRACE_ERROR("no device record available");
2590     }
2591 
2592     return ret;
2593 }
2594 
2595 /*******************************************************************************
2596 **
2597 ** Function         gatt_remove_bg_dev_for_app
2598 **
2599 ** Description      Remove the application interface for the specified background device
2600 **
2601 ** Returns          Boolean
2602 **
2603 *******************************************************************************/
gatt_remove_bg_dev_for_app(tGATT_IF gatt_if,BD_ADDR bd_addr)2604 BOOLEAN gatt_remove_bg_dev_for_app(tGATT_IF gatt_if, BD_ADDR bd_addr)
2605 {
2606     tGATT_TCB    *p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE);
2607     BOOLEAN       status;
2608 
2609     if (p_tcb) {
2610         gatt_update_app_use_link_flag(gatt_if, p_tcb, FALSE, FALSE);
2611     }
2612     status = gatt_update_auto_connect_dev(gatt_if, FALSE, bd_addr, TRUE);
2613     return status;
2614 }
2615 
2616 
2617 /*******************************************************************************
2618 **
2619 ** Function         gatt_get_num_apps_for_bg_dev
2620 **
2621 ** Description      Gte the number of applciations for the specified background device
2622 **
2623 ** Returns          UINT8 total number fo applications
2624 **
2625 *******************************************************************************/
gatt_get_num_apps_for_bg_dev(BD_ADDR bd_addr)2626 UINT8 gatt_get_num_apps_for_bg_dev(BD_ADDR bd_addr)
2627 {
2628     tGATT_BG_CONN_DEV   *p_dev = NULL;
2629     UINT8   i;
2630     UINT8   cnt = 0;
2631 
2632     if ((p_dev = gatt_find_bg_dev(bd_addr)) != NULL) {
2633         for (i = 0; i < GATT_MAX_APPS; i ++) {
2634             if (p_dev->gatt_if[i]) {
2635                 cnt++;
2636             }
2637         }
2638     }
2639     return cnt;
2640 }
2641 
2642 /*******************************************************************************
2643 **
2644 ** Function         gatt_find_app_for_bg_dev
2645 **
2646 ** Description      find the application interface for the specified background device
2647 **
2648 ** Returns          Boolean
2649 **
2650 *******************************************************************************/
gatt_find_app_for_bg_dev(BD_ADDR bd_addr,tGATT_IF * p_gatt_if)2651 BOOLEAN gatt_find_app_for_bg_dev(BD_ADDR bd_addr, tGATT_IF *p_gatt_if)
2652 {
2653     tGATT_BG_CONN_DEV   *p_dev = NULL;
2654     UINT8   i;
2655     BOOLEAN ret = FALSE;
2656 
2657     if ((p_dev = gatt_find_bg_dev(bd_addr)) == NULL) {
2658         return ret;
2659     }
2660 
2661     for (i = 0; i < GATT_MAX_APPS; i ++) {
2662         if (p_dev->gatt_if[i] != 0 ) {
2663             *p_gatt_if = p_dev->gatt_if[i];
2664             ret = TRUE;
2665             break;
2666         }
2667     }
2668     return ret;
2669 }
2670 
2671 
2672 /*******************************************************************************
2673 **
2674 ** Function         gatt_remove_bg_dev_from_list
2675 **
2676 ** Description      add/remove device from the background connection device list or
2677 **                  listening to advertising list.
2678 **
2679 ** Returns          pointer to the device record
2680 **
2681 *******************************************************************************/
gatt_remove_bg_dev_from_list(tGATT_REG * p_reg,BD_ADDR bd_addr,BOOLEAN is_initiator)2682 BOOLEAN gatt_remove_bg_dev_from_list(tGATT_REG *p_reg, BD_ADDR bd_addr, BOOLEAN is_initiator)
2683 {
2684     tGATT_IF gatt_if = p_reg->gatt_if;
2685     tGATT_BG_CONN_DEV   *p_dev = NULL;
2686     UINT8   i, j;
2687     BOOLEAN ret = FALSE;
2688 
2689     if ((p_dev = gatt_find_bg_dev(bd_addr)) == NULL) {
2690         return ret;
2691     }
2692 
2693     for (i = 0; i < GATT_MAX_APPS && (p_dev->gatt_if[i] > 0 || p_dev->listen_gif[i]); i ++) {
2694         if (is_initiator) {
2695             if (p_dev->gatt_if[i] == gatt_if) {
2696                 p_dev->gatt_if[i] = 0;
2697                 /* move all element behind one forward */
2698                 for (j = i + 1; j < GATT_MAX_APPS; j ++) {
2699                     p_dev->gatt_if[j - 1] = p_dev->gatt_if[j];
2700                 }
2701 
2702                 if (p_dev->gatt_if[0] == 0) {
2703                     ret = BTM_BleUpdateBgConnDev(FALSE, p_dev->remote_bda);
2704                 } else {
2705                     ret = TRUE;
2706                 }
2707 
2708                 break;
2709             }
2710         } else {
2711             if (p_dev->listen_gif[i] == gatt_if) {
2712                 p_dev->listen_gif[i] = 0;
2713                 p_reg->listening --;
2714                 /* move all element behind one forward */
2715                 for (j = i + 1; j < GATT_MAX_APPS; j ++) {
2716                     p_dev->listen_gif[j - 1] = p_dev->listen_gif[j];
2717                 }
2718 
2719                 if (p_dev->listen_gif[0] == 0) {
2720                     // To check, we do not support background connection, code will not be called here
2721                     ret = BTM_BleUpdateAdvWhitelist(FALSE, p_dev->remote_bda, 0, NULL);
2722                 } else {
2723                     ret = TRUE;
2724                 }
2725                 break;
2726             }
2727         }
2728     }
2729 
2730     if (i != GATT_MAX_APPS && p_dev->gatt_if[0] == 0 && p_dev->listen_gif[0] == 0) {
2731         memset(p_dev, 0, sizeof(tGATT_BG_CONN_DEV));
2732     }
2733 
2734     return ret;
2735 }
2736 /*******************************************************************************
2737 **
2738 ** Function         gatt_deregister_bgdev_list
2739 **
2740 ** Description      deregister all related background connection device.
2741 **
2742 ** Returns          pointer to the device record
2743 **
2744 *******************************************************************************/
gatt_deregister_bgdev_list(tGATT_IF gatt_if)2745 void gatt_deregister_bgdev_list(tGATT_IF gatt_if)
2746 {
2747     tGATT_BG_CONN_DEV    *p_dev_list = &gatt_cb.bgconn_dev[0];
2748     UINT8 i , j, k;
2749     tGATT_REG       *p_reg = gatt_get_regcb(gatt_if);
2750 
2751     /* update the BG conn device list */
2752     for (i = 0 ; i < GATT_MAX_BG_CONN_DEV; i ++, p_dev_list ++ ) {
2753         if (p_dev_list->in_use) {
2754             for (j = 0; j < GATT_MAX_APPS; j ++) {
2755                 if (p_dev_list->gatt_if[j] == 0 && p_dev_list->listen_gif[j] == 0) {
2756                     break;
2757                 }
2758 
2759                 if (p_dev_list->gatt_if[j] == gatt_if) {
2760                     for (k = j + 1; k < GATT_MAX_APPS; k ++) {
2761                         p_dev_list->gatt_if[k - 1] = p_dev_list->gatt_if[k];
2762                     }
2763 
2764                     if (p_dev_list->gatt_if[0] == 0) {
2765                         BTM_BleUpdateBgConnDev(FALSE, p_dev_list->remote_bda);
2766                     }
2767                 }
2768 
2769                 if (p_dev_list->listen_gif[j] == gatt_if) {
2770                     p_dev_list->listen_gif[j] = 0;
2771 
2772                     if (p_reg != NULL && p_reg->listening > 0) {
2773                         p_reg->listening --;
2774                     }
2775 
2776                     /* move all element behind one forward */
2777                     for (k = j + 1; k < GATT_MAX_APPS; k ++) {
2778                         p_dev_list->listen_gif[k - 1] = p_dev_list->listen_gif[k];
2779                     }
2780 
2781                     if (p_dev_list->listen_gif[0] == 0) {
2782                         // To check, we do not support background connection, code will not be called here
2783                         BTM_BleUpdateAdvWhitelist(FALSE, p_dev_list->remote_bda, 0, NULL);
2784                     }
2785                 }
2786             }
2787         }
2788     }
2789 }
2790 
2791 
2792 /*******************************************************************************
2793 **
2794 ** Function         gatt_reset_bgdev_list
2795 **
2796 ** Description      reset bg device list
2797 **
2798 ** Returns          pointer to the device record
2799 **
2800 *******************************************************************************/
gatt_reset_bgdev_list(void)2801 void gatt_reset_bgdev_list(void)
2802 {
2803     memset(&gatt_cb.bgconn_dev, 0 , sizeof(tGATT_BG_CONN_DEV)*GATT_MAX_BG_CONN_DEV);
2804 
2805 }
2806 /*******************************************************************************
2807 **
2808 ** Function         gatt_update_auto_connect_dev
2809 **
2810 ** Description      This function add or remove a device for background connection
2811 **                  procedure.
2812 **
2813 ** Parameters       gatt_if: Application ID.
2814 **                  add: add peer device
2815 **                  bd_addr: peer device address.
2816 **
2817 ** Returns          TRUE if connection started; FALSE if connection start failure.
2818 **
2819 *******************************************************************************/
gatt_update_auto_connect_dev(tGATT_IF gatt_if,BOOLEAN add,BD_ADDR bd_addr,BOOLEAN is_initator)2820 BOOLEAN gatt_update_auto_connect_dev (tGATT_IF gatt_if, BOOLEAN add, BD_ADDR bd_addr, BOOLEAN is_initator)
2821 {
2822     BOOLEAN         ret = FALSE;
2823     tGATT_REG        *p_reg;
2824     tGATT_TCB       *p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE);
2825 
2826     GATT_TRACE_API ("gatt_update_auto_connect_dev ");
2827     /* Make sure app is registered */
2828     if ((p_reg = gatt_get_regcb(gatt_if)) == NULL) {
2829         GATT_TRACE_ERROR("gatt_update_auto_connect_dev - gatt_if %d is not registered", gatt_if);
2830         return (FALSE);
2831     }
2832 
2833     if (add) {
2834         ret = gatt_add_bg_dev_list(p_reg, bd_addr, is_initator);
2835 
2836         if (ret && p_tcb != NULL) {
2837             /* if a connected device, update the link holding number */
2838             gatt_update_app_use_link_flag(gatt_if, p_tcb, TRUE, TRUE);
2839         }
2840     } else {
2841         ret = gatt_remove_bg_dev_from_list(p_reg, bd_addr, is_initator);
2842     }
2843     return ret;
2844 }
2845 
2846 
2847 
2848 /*******************************************************************************
2849 **
2850 ** Function     gatt_add_pending_new_srv_start
2851 **
2852 ** Description  Add a pending new srv start to the new service start queue
2853 **
2854 ** Returns    Pointer to the new service start buffer, NULL no buffer available
2855 **
2856 *******************************************************************************/
gatt_add_pending_enc_channel_clcb(tGATT_TCB * p_tcb,tGATT_CLCB * p_clcb)2857 tGATT_PENDING_ENC_CLCB *gatt_add_pending_enc_channel_clcb(tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb )
2858 {
2859     tGATT_PENDING_ENC_CLCB   *p_buf;
2860 
2861     GATT_TRACE_DEBUG ("gatt_add_pending_new_srv_start");
2862     if ((p_buf = (tGATT_PENDING_ENC_CLCB *)osi_malloc((UINT16)sizeof(tGATT_PENDING_ENC_CLCB))) != NULL) {
2863         GATT_TRACE_DEBUG ("enqueue a new pending encryption channel clcb");
2864         p_buf->p_clcb = p_clcb;
2865     fixed_queue_enqueue(p_tcb->pending_enc_clcb, p_buf, FIXED_QUEUE_MAX_TIMEOUT);
2866     }
2867     return p_buf;
2868 }
2869 /*******************************************************************************
2870 **
2871 ** Function     gatt_update_listen_mode
2872 **
2873 ** Description  update peripheral role listening mode
2874 **
2875 ** Returns    Pointer to the new service start buffer, NULL no buffer available
2876 **
2877 *******************************************************************************/
gatt_update_listen_mode(void)2878 BOOLEAN gatt_update_listen_mode(void)
2879 {
2880     UINT8           ii = 0;
2881     tGATT_REG       *p_reg = &gatt_cb.cl_rcb[0];
2882     UINT8           listening = 0;
2883     UINT16          connectability, window, interval;
2884     BOOLEAN         rt = TRUE;
2885 
2886     for (; ii < GATT_MAX_APPS; ii ++, p_reg ++) {
2887         if ( p_reg->in_use && p_reg->listening > listening) {
2888             listening = p_reg->listening;
2889         }
2890     }
2891 
2892     if (listening == GATT_LISTEN_TO_ALL ||
2893             listening == GATT_LISTEN_TO_NONE) {
2894         BTM_BleUpdateAdvFilterPolicy (AP_SCAN_CONN_ALL);
2895     } else {
2896         BTM_BleUpdateAdvFilterPolicy (AP_SCAN_CONN_WL);
2897     }
2898 
2899     if (rt) {
2900         connectability = BTM_ReadConnectability (&window, &interval);
2901 
2902         if (listening != GATT_LISTEN_TO_NONE) {
2903             connectability |= BTM_BLE_CONNECTABLE;
2904         } else {
2905             if ((connectability & BTM_BLE_CONNECTABLE) == 0) {
2906                 connectability &= ~BTM_BLE_CONNECTABLE;
2907             }
2908         }
2909         /* turning on the adv now */
2910         btm_ble_set_connectability(connectability);
2911     }
2912 
2913     return rt;
2914 
2915 }
2916 
gatt_uuid_to_str(const tBT_UUID * uuid)2917 char *gatt_uuid_to_str(const tBT_UUID *uuid)
2918 {
2919     static char dst[48] = {0};
2920     const UINT8 *u8p;
2921 
2922     memset(dst, 0, sizeof(dst));
2923 
2924     switch (uuid->len) {
2925     case LEN_UUID_16:
2926         sprintf(dst, "0x%04x", uuid->uu.uuid16);
2927         break;
2928     case LEN_UUID_32:
2929         sprintf(dst, "0x%08x", uuid->uu.uuid32);
2930         break;
2931     case LEN_UUID_128:
2932         u8p = uuid->uu.uuid128;
2933 
2934         sprintf(dst, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-"
2935                      "%02x%02x%02x%02x%02x%02x",
2936                 u8p[15], u8p[14], u8p[13], u8p[12],
2937                 u8p[11], u8p[10],  u8p[9],  u8p[8],
2938                  u8p[7],  u8p[6],  u8p[5],  u8p[4],
2939                  u8p[3],  u8p[2],  u8p[1],  u8p[0]);
2940         break;
2941     default:
2942         dst[0] = '\0';
2943         break;
2944     }
2945 
2946     return dst;
2947 }
2948 #endif
2949