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 ** Function         gatt_find_i_tcb_by_addr
906 **
907 ** Description      The function searches for an empty tcb entry, and return the index.
908 **
909 ** Returns           GATT_INDEX_INVALID if not found. Otherwise index to the tcb.
910 **
911 *******************************************************************************/
gatt_find_i_tcb_by_addr(BD_ADDR bda,tBT_TRANSPORT transport)912 UINT8 gatt_find_i_tcb_by_addr(BD_ADDR bda, tBT_TRANSPORT transport)
913 {
914     UINT8 i = 0;
915     list_node_t *p_node = NULL;
916     tGATT_TCB   *p_tcb  = NULL;
917     for(p_node = list_begin(gatt_cb.p_tcb_list); p_node; p_node = list_next(p_node)) {
918 	p_tcb = list_node(p_node);
919         if (!memcmp(p_tcb->peer_bda, bda, BD_ADDR_LEN) &&
920                 p_tcb->transport == transport) {
921 	    i = p_tcb->tcb_idx;
922             return i;
923         }
924     }
925     return GATT_INDEX_INVALID;
926 }
927 
928 /*******************************************************************************
929 **
930 ** Function         gatt_get_tcb_by_idx
931 **
932 ** Description      The function get TCB using the TCB index
933 **
934 ** Returns           NULL if not found. Otherwise index to the tcb.
935 **
936 *******************************************************************************/
gatt_get_tcb_by_idx(UINT8 tcb_idx)937 tGATT_TCB *gatt_get_tcb_by_idx(UINT8 tcb_idx)
938 {
939     tGATT_TCB   *p_tcb  = NULL;
940     list_node_t *p_node = NULL;
941     for(p_node = list_begin(gatt_cb.p_tcb_list); p_node; p_node = list_next(p_node)) {
942 	p_tcb = list_node(p_node);
943         if ( (tcb_idx < GATT_MAX_PHY_CHANNEL) && p_tcb->in_use && p_tcb->tcb_idx == tcb_idx ) {
944             break;
945         } else {
946 	    p_tcb = NULL;
947 	}
948     }
949 
950     return p_tcb;
951 }
952 
953 /*******************************************************************************
954 **
955 ** Function         gatt_find_tcb_by_addr
956 **
957 ** Description      The function searches for an empty tcb entry, and return pointer.
958 **
959 ** Returns           NULL if not found. Otherwise index to the tcb.
960 **
961 *******************************************************************************/
gatt_find_tcb_by_addr(BD_ADDR bda,tBT_TRANSPORT transport)962 tGATT_TCB *gatt_find_tcb_by_addr(BD_ADDR bda, tBT_TRANSPORT transport)
963 {
964     tGATT_TCB   *p_tcb = NULL;
965     UINT8 i = 0;
966 
967     if ((i = gatt_find_i_tcb_by_addr(bda, transport)) != GATT_INDEX_INVALID) {
968         p_tcb = gatt_get_tcb_by_idx(i);
969     }
970 
971     return p_tcb;
972 }
973 /*******************************************************************************
974 **
975 ** Function         gatt_find_i_tcb_free
976 **
977 ** Description      The function searches for an empty tcb entry, and return the index.
978 **
979 ** Returns           GATT_INDEX_INVALID if not found. Otherwise index to the tcb.
980 **
981 *******************************************************************************/
gatt_find_i_tcb_free(void)982 UINT8 gatt_find_i_tcb_free(void)
983 {
984     UINT8 i = 0, j = GATT_INDEX_INVALID;
985 
986     for (i = 0; i < GATT_MAX_PHY_CHANNEL; i ++) {
987         if (!((1 << i) & gatt_tcb_id)) {
988             j = i;
989             break;
990         }
991     }
992     return j;
993 }
994 /*******************************************************************************
995 **
996 ** Function         gatt_tcb_alloc
997 **
998 ** Description      The function allocates tcb for given tcb_idx and update tcb_id
999 **
1000 ** Returns          Allocated tcb block
1001 **
1002 *******************************************************************************/
gatt_tcb_alloc(UINT8 tcb_idx)1003 tGATT_TCB *gatt_tcb_alloc(UINT8 tcb_idx)
1004 {
1005     /* Allocate tcb block */
1006     tGATT_TCB *p_tcb = (tGATT_TCB *)osi_malloc(sizeof(tGATT_TCB));
1007     if (p_tcb && list_length(gatt_cb.p_tcb_list) < GATT_MAX_PHY_CHANNEL) {
1008         memset(p_tcb, 0, sizeof(tGATT_TCB));
1009         /* Add tcb  block to list in gatt_cb */
1010         list_append(gatt_cb.p_tcb_list, p_tcb);
1011         /*  Update tcb id */
1012         gatt_tcb_id |= 1 << tcb_idx;
1013     } else if(p_tcb) {
1014 	osi_free(p_tcb);
1015         p_tcb = NULL;
1016     }
1017     return p_tcb;
1018 }
1019 
1020 /*******************************************************************************
1021 **
1022 ** Function         gatt_tcb_free
1023 **
1024 ** Description      The function free the given tcb block and update tcb id
1025 **
1026 ** Returns          void
1027 **
1028 *******************************************************************************/
gatt_tcb_free(tGATT_TCB * p_tcb)1029 void gatt_tcb_free( tGATT_TCB *p_tcb)
1030 {
1031     UINT8 tcb_idx = p_tcb->tcb_idx;
1032     if (list_remove(gatt_cb.p_tcb_list, p_tcb)) {
1033         gatt_tcb_id &= ~(1 << tcb_idx);
1034     }
1035 }
1036 /*******************************************************************************
1037 **
1038 ** Function         gatt_allocate_tcb_by_bdaddr
1039 **
1040 ** Description      The function locate or allocate new tcb entry for matching bda.
1041 **
1042 ** Returns           GATT_INDEX_INVALID if not found. Otherwise index to the tcb.
1043 **
1044 *******************************************************************************/
gatt_allocate_tcb_by_bdaddr(BD_ADDR bda,tBT_TRANSPORT transport)1045 tGATT_TCB *gatt_allocate_tcb_by_bdaddr(BD_ADDR bda, tBT_TRANSPORT transport)
1046 {
1047     UINT8 i = 0;
1048     BOOLEAN allocated = FALSE;
1049     tGATT_TCB    *p_tcb = NULL;
1050 
1051     /* search for existing tcb with matching bda    */
1052     i = gatt_find_i_tcb_by_addr(bda, transport);
1053     /* find free tcb */
1054     if (i == GATT_INDEX_INVALID) {
1055         i = gatt_find_i_tcb_free();
1056         allocated = TRUE;
1057     }
1058     if (i != GATT_INDEX_INVALID) {
1059         p_tcb = gatt_tcb_alloc(i);
1060 	if (!p_tcb) {
1061 	    return NULL;
1062 	}
1063         if (allocated) {
1064             memset(p_tcb, 0, sizeof(tGATT_TCB));
1065             p_tcb->pending_enc_clcb = fixed_queue_new(QUEUE_SIZE_MAX);
1066             p_tcb->pending_ind_q = fixed_queue_new(QUEUE_SIZE_MAX);
1067             p_tcb->in_use = TRUE;
1068             p_tcb->tcb_idx = i;
1069             p_tcb->transport = transport;
1070         }
1071         memcpy(p_tcb->peer_bda, bda, BD_ADDR_LEN);
1072     }
1073     return p_tcb;
1074 }
1075 
1076 /*******************************************************************************
1077 **
1078 ** Function         gatt_convert_uuid16_to_uuid128
1079 **
1080 ** Description      Convert a 16 bits UUID to be an standard 128 bits one.
1081 **
1082 ** Returns          TRUE if two uuid match; FALSE otherwise.
1083 **
1084 *******************************************************************************/
gatt_convert_uuid16_to_uuid128(UINT8 uuid_128[LEN_UUID_128],UINT16 uuid_16)1085 void gatt_convert_uuid16_to_uuid128(UINT8 uuid_128[LEN_UUID_128], UINT16 uuid_16)
1086 {
1087     UINT8   *p = &uuid_128[LEN_UUID_128 - 4];
1088 
1089     memcpy (uuid_128, base_uuid, LEN_UUID_128);
1090 
1091     UINT16_TO_STREAM(p, uuid_16);
1092 }
1093 
1094 /*******************************************************************************
1095 **
1096 ** Function         gatt_convert_uuid32_to_uuid128
1097 **
1098 ** Description      Convert a 32 bits UUID to be an standard 128 bits one.
1099 **
1100 ** Returns          TRUE if two uuid match; FALSE otherwise.
1101 **
1102 *******************************************************************************/
gatt_convert_uuid32_to_uuid128(UINT8 uuid_128[LEN_UUID_128],UINT32 uuid_32)1103 void gatt_convert_uuid32_to_uuid128(UINT8 uuid_128[LEN_UUID_128], UINT32 uuid_32)
1104 {
1105     UINT8   *p = &uuid_128[LEN_UUID_128 - 4];
1106 
1107     memcpy (uuid_128, base_uuid, LEN_UUID_128);
1108 
1109     UINT32_TO_STREAM(p, uuid_32);
1110 }
1111 /*******************************************************************************
1112 **
1113 ** Function         gatt_uuid_compare
1114 **
1115 ** Description      Compare two UUID to see if they are the same.
1116 **
1117 ** Returns          TRUE if two uuid match; FALSE otherwise.
1118 **
1119 *******************************************************************************/
gatt_uuid_compare(tBT_UUID src,tBT_UUID tar)1120 BOOLEAN gatt_uuid_compare (tBT_UUID src, tBT_UUID tar)
1121 {
1122     UINT8  su[LEN_UUID_128], tu[LEN_UUID_128];
1123     UINT8  *ps, *pt;
1124 
1125     /* any of the UUID is unspecified */
1126     if (src.len == 0 || tar.len == 0) {
1127         return TRUE;
1128     }
1129 
1130     /* If both are 16-bit, we can do a simple compare */
1131     if (src.len == LEN_UUID_16 && tar.len == LEN_UUID_16) {
1132         return src.uu.uuid16 == tar.uu.uuid16;
1133     }
1134 
1135     /* If both are 32-bit, we can do a simple compare */
1136     if (src.len == LEN_UUID_32 && tar.len == LEN_UUID_32) {
1137         return src.uu.uuid32 == tar.uu.uuid32;
1138     }
1139 
1140     /* One or both of the UUIDs is 128-bit */
1141     if (src.len == LEN_UUID_16) {
1142         /* convert a 16 bits UUID to 128 bits value */
1143         gatt_convert_uuid16_to_uuid128(su, src.uu.uuid16);
1144         ps = su;
1145     } else if (src.len == LEN_UUID_32) {
1146         gatt_convert_uuid32_to_uuid128(su, src.uu.uuid32);
1147         ps = su;
1148     } else {
1149         ps = src.uu.uuid128;
1150     }
1151 
1152     if (tar.len == LEN_UUID_16) {
1153         /* convert a 16 bits UUID to 128 bits value */
1154         gatt_convert_uuid16_to_uuid128(tu, tar.uu.uuid16);
1155         pt = tu;
1156     } else if (tar.len == LEN_UUID_32) {
1157         /* convert a 32 bits UUID to 128 bits value */
1158         gatt_convert_uuid32_to_uuid128(tu, tar.uu.uuid32);
1159         pt = tu;
1160     } else {
1161         pt = tar.uu.uuid128;
1162     }
1163 
1164     return (memcmp(ps, pt, LEN_UUID_128) == 0);
1165 }
1166 
1167 /*******************************************************************************
1168 **
1169 ** Function         gatt_build_uuid_to_stream
1170 **
1171 ** Description      Add UUID into stream.
1172 **
1173 ** Returns          UUID length.
1174 **
1175 *******************************************************************************/
gatt_build_uuid_to_stream(UINT8 ** p_dst,tBT_UUID uuid)1176 UINT8 gatt_build_uuid_to_stream(UINT8 **p_dst, tBT_UUID uuid)
1177 {
1178     UINT8   *p = *p_dst;
1179     UINT8   len = 0;
1180 
1181     if (uuid.len == LEN_UUID_16) {
1182         UINT16_TO_STREAM (p, uuid.uu.uuid16);
1183         len = LEN_UUID_16;
1184     } else if (uuid.len == LEN_UUID_32) { /* always convert 32 bits into 128 bits as alwats */
1185         gatt_convert_uuid32_to_uuid128(p, uuid.uu.uuid32);
1186         p += LEN_UUID_128;
1187         len = LEN_UUID_128;
1188     } else if (uuid.len == LEN_UUID_128) {
1189         ARRAY_TO_STREAM (p, uuid.uu.uuid128, LEN_UUID_128);
1190         len = LEN_UUID_128;
1191     }
1192 
1193     *p_dst = p;
1194     return len;
1195 }
1196 
1197 /*******************************************************************************
1198 **
1199 ** Function         gatt_parse_uuid_from_cmd
1200 **
1201 ** Description      Convert a 128 bits UUID into a 16 bits UUID.
1202 **
1203 ** Returns          TRUE if command sent, otherwise FALSE.
1204 **
1205 *******************************************************************************/
gatt_parse_uuid_from_cmd(tBT_UUID * p_uuid_rec,UINT16 uuid_size,UINT8 ** p_data)1206 BOOLEAN gatt_parse_uuid_from_cmd(tBT_UUID *p_uuid_rec, UINT16 uuid_size, UINT8 **p_data)
1207 {
1208     BOOLEAN is_base_uuid, ret = TRUE;
1209     UINT8  xx;
1210     UINT8 *p_uuid = *p_data;
1211 
1212     memset(p_uuid_rec, 0, sizeof(tBT_UUID));
1213 
1214     switch (uuid_size) {
1215     case LEN_UUID_16:
1216         p_uuid_rec->len = uuid_size;
1217         STREAM_TO_UINT16 (p_uuid_rec->uu.uuid16, p_uuid);
1218         *p_data += LEN_UUID_16;
1219         break;
1220 
1221     case LEN_UUID_128:
1222         /* See if we can compress his UUID down to 16 or 32bit UUIDs */
1223         is_base_uuid = TRUE;
1224         for (xx = 0; xx < LEN_UUID_128 - 4; xx++) {
1225             if (p_uuid[xx] != base_uuid[xx]) {
1226                 is_base_uuid = FALSE;
1227                 break;
1228             }
1229         }
1230         if (is_base_uuid) {
1231             if ((p_uuid[LEN_UUID_128 - 1] == 0) && (p_uuid[LEN_UUID_128 - 2] == 0)) {
1232                 p_uuid += (LEN_UUID_128 - 4);
1233                 p_uuid_rec->len = LEN_UUID_16;
1234                 STREAM_TO_UINT16(p_uuid_rec->uu.uuid16, p_uuid);
1235             } else {
1236                 p_uuid += (LEN_UUID_128 - LEN_UUID_32);
1237                 p_uuid_rec->len = LEN_UUID_32;
1238                 STREAM_TO_UINT32(p_uuid_rec->uu.uuid32, p_uuid);
1239             }
1240         }
1241         if (!is_base_uuid) {
1242             p_uuid_rec->len = LEN_UUID_128;
1243             memcpy(p_uuid_rec->uu.uuid128, p_uuid, LEN_UUID_128);
1244         }
1245         *p_data += LEN_UUID_128;
1246         break;
1247 
1248     /* do not allow 32 bits UUID in ATT PDU now */
1249     case LEN_UUID_32:
1250         GATT_TRACE_ERROR("DO NOT ALLOW 32 BITS UUID IN ATT PDU");
1251     case 0:
1252     default:
1253         if (uuid_size != 0) {
1254             ret = FALSE;
1255         }
1256         GATT_TRACE_WARNING("gatt_parse_uuid_from_cmd invalid uuid size");
1257         break;
1258     }
1259 
1260     return ( ret);
1261 }
1262 
1263 /*******************************************************************************
1264 **
1265 ** Function         gatt_start_rsp_timer
1266 **
1267 ** Description      Start a wait_for_response timer.
1268 **
1269 ** Returns          TRUE if command sent, otherwise FALSE.
1270 **
1271 *******************************************************************************/
gatt_start_rsp_timer(UINT16 clcb_idx)1272 void gatt_start_rsp_timer(UINT16 clcb_idx)
1273 {
1274     tGATT_CLCB *p_clcb = gatt_clcb_find_by_idx(clcb_idx);
1275     UINT32 timeout = GATT_WAIT_FOR_RSP_TOUT;
1276     p_clcb->rsp_timer_ent.param  = (TIMER_PARAM_TYPE)p_clcb;
1277     if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY &&
1278             p_clcb->op_subtype == GATT_DISC_SRVC_ALL) {
1279         timeout = GATT_WAIT_FOR_DISC_RSP_TOUT;
1280     }
1281     btu_start_timer (&p_clcb->rsp_timer_ent, BTU_TTYPE_ATT_WAIT_FOR_RSP,
1282                      timeout);
1283 }
1284 /*******************************************************************************
1285 **
1286 ** Function         gatt_start_conf_timer
1287 **
1288 ** Description      Start a wait_for_confirmation timer.
1289 **
1290 ** Returns          TRUE if command sent, otherwise FALSE.
1291 **
1292 *******************************************************************************/
gatt_start_conf_timer(tGATT_TCB * p_tcb)1293 void gatt_start_conf_timer(tGATT_TCB    *p_tcb)
1294 {
1295     p_tcb->conf_timer_ent.param  = (TIMER_PARAM_TYPE)p_tcb;
1296     btu_start_timer (&p_tcb->conf_timer_ent, BTU_TTYPE_ATT_WAIT_FOR_RSP,
1297                      GATT_WAIT_FOR_RSP_TOUT);
1298 }
1299 /*******************************************************************************
1300 **
1301 ** Function         gatt_start_ind_ack_timer
1302 **
1303 ** Description      start the application ack timer
1304 **
1305 ** Returns          void
1306 **
1307 *******************************************************************************/
gatt_start_ind_ack_timer(tGATT_TCB * p_tcb)1308 void gatt_start_ind_ack_timer(tGATT_TCB *p_tcb)
1309 {
1310     p_tcb->ind_ack_timer_ent.param  = (TIMER_PARAM_TYPE)p_tcb;
1311     /* start notification cache timer */
1312     btu_start_timer (&p_tcb->ind_ack_timer_ent, BTU_TTYPE_ATT_WAIT_FOR_IND_ACK,
1313                      GATT_WAIT_FOR_IND_ACK_TOUT);
1314 
1315 }
1316 /*******************************************************************************
1317 **
1318 ** Function         gatt_rsp_timeout
1319 **
1320 ** Description      Called when GATT wait for ATT command response timer expires
1321 **
1322 ** Returns          void
1323 **
1324 *******************************************************************************/
gatt_rsp_timeout(TIMER_LIST_ENT * p_tle)1325 void gatt_rsp_timeout(TIMER_LIST_ENT *p_tle)
1326 {
1327     tGATT_CLCB *p_clcb = (tGATT_CLCB *)p_tle->param;
1328     if (p_clcb == NULL || p_clcb->p_tcb == NULL) {
1329         GATT_TRACE_WARNING("gatt_rsp_timeout clcb is already deleted");
1330         return;
1331     }
1332     if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY &&
1333             p_clcb->op_subtype == GATT_DISC_SRVC_ALL &&
1334             p_clcb->retry_count < GATT_REQ_RETRY_LIMIT) {
1335         UINT8 rsp_code;
1336         GATT_TRACE_WARNING("gatt_rsp_timeout retry discovery primary service");
1337         if (p_clcb != gatt_cmd_dequeue(p_clcb->p_tcb, &rsp_code)) {
1338             GATT_TRACE_ERROR("gatt_rsp_timeout command queue out of sync, disconnect");
1339         } else {
1340             p_clcb->retry_count++;
1341 #if (GATTC_INCLUDED == TRUE)
1342             gatt_act_discovery(p_clcb);
1343 #endif  ///GATTC_INCLUDED == TRUE
1344             return;
1345         }
1346     }
1347 
1348     GATT_TRACE_WARNING("gatt_rsp_timeout disconnecting...");
1349     gatt_disconnect (p_clcb->p_tcb);
1350 }
1351 
1352 /*******************************************************************************
1353 **
1354 ** Function         gatt_ind_ack_timeout
1355 **
1356 ** Description      Called when GATT wait for ATT handle confirmation timeout
1357 **
1358 ** Returns          void
1359 **
1360 *******************************************************************************/
gatt_ind_ack_timeout(TIMER_LIST_ENT * p_tle)1361 void gatt_ind_ack_timeout(TIMER_LIST_ENT *p_tle)
1362 {
1363     tGATT_TCB *p_tcb = (tGATT_TCB *)p_tle->param;
1364 
1365     GATT_TRACE_WARNING("gatt_ind_ack_timeout send ack now");
1366 
1367     if (p_tcb != NULL) {
1368         p_tcb->ind_count = 0;
1369     }
1370 
1371     attp_send_cl_msg(((tGATT_TCB *)p_tle->param), 0, GATT_HANDLE_VALUE_CONF, NULL);
1372 }
1373 /*******************************************************************************
1374 **
1375 ** Function         gatt_sr_find_i_rcb_by_handle
1376 **
1377 ** Description      The function searches for a service that owns a specific handle.
1378 **
1379 ** Returns          GATT_MAX_SR_PROFILES if not found. Otherwise index of th eservice.
1380 **
1381 *******************************************************************************/
gatt_sr_find_i_rcb_by_handle(UINT16 handle)1382 UINT8 gatt_sr_find_i_rcb_by_handle(UINT16 handle)
1383 {
1384     UINT8  i_rcb = 0;
1385 
1386     for ( ; i_rcb < GATT_MAX_SR_PROFILES; i_rcb++) {
1387         if (gatt_cb.sr_reg[i_rcb].in_use &&
1388                 gatt_cb.sr_reg[i_rcb].s_hdl <= handle &&
1389                 gatt_cb.sr_reg[i_rcb].e_hdl >= handle ) {
1390             break;
1391         }
1392     }
1393     return i_rcb;
1394 }
1395 
1396 /*******************************************************************************
1397 **
1398 ** Function         gatt_sr_find_i_rcb_by_handle
1399 **
1400 ** Description      The function searches for a service that owns a specific handle.
1401 **
1402 ** Returns          GATT_MAX_SR_PROFILES if not found. Otherwise index of th eservice.
1403 **
1404 *******************************************************************************/
1405 #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)1406 UINT8 gatt_sr_find_i_rcb_by_app_id(tBT_UUID *p_app_uuid128, tBT_UUID *p_svc_uuid, UINT16 svc_inst)
1407 {
1408     UINT8           i_rcb = 0;
1409     tGATT_SR_REG    *p_sreg;
1410     tBT_UUID        *p_this_uuid;
1411 
1412     for (i_rcb = 0, p_sreg = gatt_cb.sr_reg; i_rcb < GATT_MAX_SR_PROFILES; i_rcb++, p_sreg++) {
1413         if ( p_sreg->in_use ) {
1414             p_this_uuid = gatts_get_service_uuid (p_sreg->p_db);
1415 
1416             if (p_this_uuid &&
1417                     gatt_uuid_compare (*p_app_uuid128, p_sreg->app_uuid ) &&
1418                     gatt_uuid_compare (*p_svc_uuid, *p_this_uuid) &&
1419                     (svc_inst == p_sreg->service_instance)) {
1420                 GATT_TRACE_ERROR ("Active Service Found ");
1421                 gatt_dbg_display_uuid(*p_svc_uuid);
1422 
1423                 break;
1424             }
1425         }
1426     }
1427     return i_rcb;
1428 }
1429 #endif  ///GATTS_INCLUDED == TRUE
1430 /*******************************************************************************
1431 **
1432 ** Function         gatt_sr_find_i_rcb_by_handle
1433 **
1434 ** Description      The function searches for a service that owns a specific handle.
1435 **
1436 ** Returns          0 if not found. Otherwise index of th eservice.
1437 **
1438 *******************************************************************************/
gatt_sr_alloc_rcb(tGATT_HDL_LIST_ELEM * p_list)1439 UINT8 gatt_sr_alloc_rcb(tGATT_HDL_LIST_ELEM *p_list )
1440 {
1441     UINT8   ii = 0;
1442     tGATT_SR_REG    *p_sreg = NULL;
1443 
1444     /*this is a new application servoce start */
1445     for (ii = 0, p_sreg = gatt_cb.sr_reg; ii < GATT_MAX_SR_PROFILES; ii++, p_sreg++) {
1446         if (!p_sreg->in_use) {
1447             memset (p_sreg, 0, sizeof(tGATT_SR_REG));
1448 
1449             p_sreg->in_use = TRUE;
1450             memcpy (&p_sreg->app_uuid, &p_list->asgn_range.app_uuid128, sizeof(tBT_UUID));
1451 
1452             p_sreg->service_instance    = p_list->asgn_range.svc_inst;
1453             p_sreg->type                = p_list->asgn_range.is_primary ? GATT_UUID_PRI_SERVICE : GATT_UUID_SEC_SERVICE;
1454             p_sreg->s_hdl               = p_list->asgn_range.s_handle;
1455             p_sreg->e_hdl               = p_list->asgn_range.e_handle;
1456             p_sreg->p_db                = &p_list->svc_db;
1457 
1458             GATT_TRACE_DEBUG ("total buffer in db [%d]", fixed_queue_length(p_sreg->p_db->svc_buffer));
1459             break;
1460         }
1461     }
1462 
1463     return ii;
1464 }
1465 /*******************************************************************************
1466 **
1467 ** Function         gatt_sr_get_sec_info
1468 **
1469 ** Description      Get the security flag and key size information for the peer
1470 **                  device.
1471 **
1472 ** Returns          void
1473 **
1474 *******************************************************************************/
gatt_sr_get_sec_info(BD_ADDR rem_bda,tBT_TRANSPORT transport,UINT8 * p_sec_flag,UINT8 * p_key_size)1475 void gatt_sr_get_sec_info(BD_ADDR rem_bda, tBT_TRANSPORT transport, UINT8 *p_sec_flag, UINT8 *p_key_size)
1476 {
1477     UINT8           sec_flag = 0;
1478 
1479     BTM_GetSecurityFlagsByTransport(rem_bda, &sec_flag, transport);
1480 
1481     sec_flag &= (GATT_SEC_FLAG_LKEY_UNAUTHED | GATT_SEC_FLAG_LKEY_AUTHED | GATT_SEC_FLAG_ENCRYPTED | GATT_SEC_FLAG_AUTHORIZATION);
1482 #if (SMP_INCLUDED == TRUE)
1483     *p_key_size = btm_ble_read_sec_key_size(rem_bda);
1484 #endif  ///SMP_INCLUDED == TRUE
1485     *p_sec_flag = sec_flag;
1486 }
1487 /*******************************************************************************
1488 **
1489 ** Function         gatt_sr_send_req_callback
1490 **
1491 ** Description
1492 **
1493 **
1494 ** Returns          void
1495 **
1496 *******************************************************************************/
gatt_sr_send_req_callback(UINT16 conn_id,UINT32 trans_id,tGATTS_REQ_TYPE type,tGATTS_DATA * p_data)1497 void gatt_sr_send_req_callback(UINT16 conn_id,
1498                                UINT32 trans_id,
1499                                tGATTS_REQ_TYPE type, tGATTS_DATA *p_data)
1500 {
1501     tGATT_IF        gatt_if = GATT_GET_GATT_IF(conn_id);
1502     tGATT_REG       *p_reg = gatt_get_regcb(gatt_if);
1503 
1504     if (!p_reg ) {
1505         GATT_TRACE_ERROR ("p_reg not found discard request");
1506         return;
1507     }
1508 
1509     if ( p_reg->in_use &&
1510             p_reg->app_cb.p_req_cb) {
1511         (*p_reg->app_cb.p_req_cb)(conn_id, trans_id, type, p_data);
1512     } else {
1513         GATT_TRACE_WARNING("Call back not found for application conn_id=%d", conn_id);
1514     }
1515 
1516 }
1517 
1518 /*******************************************************************************
1519 **
1520 ** Function         gatt_send_error_rsp
1521 **
1522 ** Description      This function sends an error response.
1523 **
1524 ** Returns          void
1525 **
1526 *******************************************************************************/
gatt_send_error_rsp(tGATT_TCB * p_tcb,UINT8 err_code,UINT8 op_code,UINT16 handle,BOOLEAN deq)1527 tGATT_STATUS gatt_send_error_rsp (tGATT_TCB *p_tcb, UINT8 err_code, UINT8 op_code,
1528                                   UINT16 handle, BOOLEAN deq)
1529 {
1530     tGATT_ERROR      error;
1531     tGATT_STATUS     status;
1532     BT_HDR           *p_buf;
1533 
1534     error.cmd_code = op_code;
1535     error.reason = err_code;
1536     error.handle = handle;
1537 
1538     if ((p_buf = attp_build_sr_msg(p_tcb, GATT_RSP_ERROR, (tGATT_SR_MSG *)&error)) != NULL) {
1539         status = attp_send_sr_msg (p_tcb, p_buf);
1540     } else {
1541         status = GATT_INSUF_RESOURCE;
1542     }
1543 #if (GATTS_INCLUDED == TRUE)
1544     if (deq) {
1545         gatt_dequeue_sr_cmd(p_tcb);
1546     }
1547 #endif  ///GATTS_INCLUDED == TRUE
1548     return status;
1549 }
1550 
1551 #if (SDP_INCLUDED == TRUE && CLASSIC_BT_GATT_INCLUDED == TRUE)
1552 /*******************************************************************************
1553 **
1554 ** Function         gatt_add_sdp_record
1555 **
1556 ** Description      This function add a SDP record for a GATT primary service
1557 **
1558 ** Returns          0 if error else sdp handle for the record.
1559 **
1560 *******************************************************************************/
gatt_add_sdp_record(tBT_UUID * p_uuid,UINT16 start_hdl,UINT16 end_hdl)1561 UINT32 gatt_add_sdp_record (tBT_UUID *p_uuid, UINT16 start_hdl, UINT16 end_hdl)
1562 {
1563     tSDP_PROTOCOL_ELEM  proto_elem_list[2];
1564     UINT32              sdp_handle;
1565     UINT16              list = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
1566     UINT8               buff[60];
1567     UINT8               *p = buff;
1568 
1569     GATT_TRACE_DEBUG("gatt_add_sdp_record s_hdl=0x%x  s_hdl=0x%x", start_hdl, end_hdl);
1570 
1571     if ((sdp_handle = SDP_CreateRecord()) == 0) {
1572         return 0;
1573     }
1574 
1575     switch (p_uuid->len) {
1576     case LEN_UUID_16:
1577         SDP_AddServiceClassIdList(sdp_handle, 1, &p_uuid->uu.uuid16);
1578         break;
1579 
1580     case LEN_UUID_32:
1581         UINT8_TO_BE_STREAM (p, (UUID_DESC_TYPE << 3) | SIZE_FOUR_BYTES);
1582         UINT32_TO_BE_STREAM (p, p_uuid->uu.uuid32);
1583         SDP_AddAttribute (sdp_handle, ATTR_ID_SERVICE_CLASS_ID_LIST, DATA_ELE_SEQ_DESC_TYPE,
1584                           (UINT32) (p - buff), buff);
1585         break;
1586 
1587     case LEN_UUID_128:
1588         UINT8_TO_BE_STREAM (p, (UUID_DESC_TYPE << 3) | SIZE_SIXTEEN_BYTES);
1589         ARRAY_TO_BE_STREAM_REVERSE (p, p_uuid->uu.uuid128, LEN_UUID_128);
1590         SDP_AddAttribute (sdp_handle, ATTR_ID_SERVICE_CLASS_ID_LIST, DATA_ELE_SEQ_DESC_TYPE,
1591                           (UINT32) (p - buff), buff);
1592         break;
1593 
1594     default:
1595         GATT_TRACE_ERROR("inavlid UUID len=%d", p_uuid->len);
1596         SDP_DeleteRecord(sdp_handle);
1597         return 0;
1598         break;
1599     }
1600 
1601     /*** Fill out the protocol element sequence for SDP ***/
1602     proto_elem_list[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
1603     proto_elem_list[0].num_params    = 1;
1604     proto_elem_list[0].params[0]     = BT_PSM_ATT;
1605     proto_elem_list[1].protocol_uuid = UUID_PROTOCOL_ATT;
1606     proto_elem_list[1].num_params    = 2;
1607     proto_elem_list[1].params[0]     = start_hdl;
1608     proto_elem_list[1].params[1]     = end_hdl;
1609 
1610     SDP_AddProtocolList(sdp_handle, 2, proto_elem_list);
1611 
1612     /* Make the service browseable */
1613     SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &list);
1614 
1615     return (sdp_handle);
1616 }
1617 #endif  ///SDP_INCLUDED == TRUE && CLASSIC_BT_GATT_INCLUDED == TRUE
1618 
1619 #if GATT_CONFORMANCE_TESTING == TRUE
1620 /*******************************************************************************
1621 **
1622 ** Function         gatt_set_err_rsp
1623 **
1624 ** Description      This function is called to set the test confirm value
1625 **
1626 ** Returns          void
1627 **
1628 *******************************************************************************/
gatt_set_err_rsp(BOOLEAN enable,UINT8 req_op_code,UINT8 err_status)1629 void gatt_set_err_rsp(BOOLEAN enable, UINT8 req_op_code, UINT8 err_status)
1630 {
1631     GATT_TRACE_DEBUG("gatt_set_err_rsp enable=%d op_code=%d, err_status=%d", enable, req_op_code, err_status);
1632     gatt_cb.enable_err_rsp  = enable;
1633     gatt_cb.req_op_code     = req_op_code;
1634     gatt_cb.err_status      = err_status;
1635 }
1636 #endif
1637 
1638 
1639 
1640 /*******************************************************************************
1641 **
1642 ** Function         gatt_get_regcb
1643 **
1644 ** Description      The function returns the registration control block.
1645 **
1646 ** Returns          pointer to the registration control block or NULL
1647 **
1648 *******************************************************************************/
gatt_get_regcb(tGATT_IF gatt_if)1649 tGATT_REG *gatt_get_regcb (tGATT_IF gatt_if)
1650 {
1651     UINT8           ii = (UINT8)gatt_if;
1652     tGATT_REG       *p_reg = NULL;
1653 
1654     if (ii < 1 || ii > GATT_MAX_APPS) {
1655         GATT_TRACE_WARNING("gatt_if out of range [ = %d]", ii);
1656         return NULL;
1657     }
1658 
1659     // Index for cl_rcb is always 1 less than gatt_if.
1660     p_reg = &gatt_cb.cl_rcb[ii - 1];
1661 
1662     if (!p_reg->in_use) {
1663         GATT_TRACE_WARNING("gatt_if found but not in use.\n");
1664         return NULL;
1665     }
1666 
1667     return p_reg;
1668 }
1669 
1670 
1671 /*******************************************************************************
1672 **
1673 ** Function         gatt_is_clcb_allocated
1674 **
1675 ** Description      The function check clcb for conn_id is allocated or not
1676 **
1677 ** Returns           True already allocated
1678 **
1679 *******************************************************************************/
1680 
gatt_is_clcb_allocated(UINT16 conn_id)1681 BOOLEAN gatt_is_clcb_allocated (UINT16 conn_id)
1682 {
1683     BOOLEAN       is_allocated = FALSE;
1684 
1685     tGATT_CLCB  *p_clcb = gatt_clcb_find_by_conn_id(conn_id);
1686     if (p_clcb) {
1687         is_allocated = TRUE;
1688     }
1689     return is_allocated;
1690 }
1691 
1692 /*******************************************************************************
1693 **
1694 ** Function         gatt_clcb_find_by_conn_id
1695 **
1696 ** Description      Find clcb block using clcb_idx stored at the time of alloc
1697 **
1698 ** Returns          pointer to clcb corresponding to conn_id
1699 **
1700 *******************************************************************************/
1701 
gatt_clcb_find_by_conn_id(UINT16 conn_id)1702 tGATT_CLCB *gatt_clcb_find_by_conn_id(UINT16 conn_id)
1703 {
1704     list_node_t *p_node     = NULL;
1705     tGATT_CLCB  *p_clcb     = NULL;
1706     tGATT_CLCB  *p_clcb_ret = NULL;
1707     for(p_node = list_begin(gatt_cb.p_clcb_list); p_node; p_node = list_next(p_node)) {
1708         p_clcb = list_node(p_node);
1709 	if (p_clcb->conn_id == conn_id) {
1710 	    p_clcb_ret = p_clcb;
1711 	    break;
1712 	}
1713     }
1714     return p_clcb_ret;
1715 }
1716 
1717 /*******************************************************************************
1718 **
1719 ** Function         gatt_clcb_find_by_idx
1720 **
1721 ** Description      Find clcb block using clcb_idx stored at the time of alloc
1722 **
1723 ** Returns          pointer to clcb corresponding to clcb_idx
1724 **
1725 *******************************************************************************/
1726 
gatt_clcb_find_by_idx(UINT16 clcb_idx)1727 tGATT_CLCB *gatt_clcb_find_by_idx(UINT16 clcb_idx)
1728 {
1729     list_node_t *p_node     = NULL;
1730     tGATT_CLCB  *p_clcb     = NULL;
1731     tGATT_CLCB  *p_clcb_ret = NULL;
1732     for(p_node = list_begin(gatt_cb.p_clcb_list); p_node; p_node = list_next(p_node)) {
1733         p_clcb = list_node(p_node);
1734 	if (p_clcb->clcb_idx == clcb_idx) {
1735 	    p_clcb_ret = p_clcb;
1736 	    break;
1737 	}
1738     }
1739     return p_clcb_ret;
1740 }
1741 
1742 /*******************************************************************************
1743 **
1744 ** Function         gatt_clcb_alloc
1745 **
1746 ** Description      The function allocates a GATT  connection link control block
1747 **
1748 ** Returns           NULL if not found. Otherwise pointer to the connection link block.
1749 **
1750 *******************************************************************************/
gatt_clcb_alloc(UINT16 conn_id)1751 tGATT_CLCB *gatt_clcb_alloc (UINT16 conn_id)
1752 {
1753     tGATT_CLCB      *p_clcb = NULL;
1754     tGATT_IF        gatt_if = GATT_GET_GATT_IF(conn_id);
1755     UINT8           tcb_idx = GATT_GET_TCB_IDX(conn_id);
1756     tGATT_TCB       *p_tcb = gatt_get_tcb_by_idx(tcb_idx);
1757     tGATT_REG       *p_reg = gatt_get_regcb(gatt_if);
1758 
1759     if (list_length(gatt_cb.p_clcb_list) < GATT_CL_MAX_LCB) {
1760 	p_clcb = (tGATT_CLCB *)osi_malloc(sizeof(tGATT_CLCB));
1761 	if (p_clcb) {
1762 	   list_append(gatt_cb.p_clcb_list, p_clcb);
1763     	   memset(p_clcb, 0, sizeof(tGATT_CLCB));
1764            p_clcb->in_use      = TRUE;
1765            p_clcb->conn_id     = conn_id;
1766     	   //Add index of the clcb same as conn_id
1767            p_clcb->clcb_idx    = conn_id;
1768            p_clcb->p_reg       = p_reg;
1769            p_clcb->p_tcb       = p_tcb;
1770 	}
1771     }
1772     return p_clcb;
1773 }
1774 
1775 /*******************************************************************************
1776 **
1777 ** Function         gatt_clcb_dealloc
1778 **
1779 ** Description      The function de allocates a GATT  connection link control block
1780 **
1781 ** Returns         None
1782 **
1783 *******************************************************************************/
gatt_clcb_dealloc(tGATT_CLCB * p_clcb)1784 void gatt_clcb_dealloc (tGATT_CLCB *p_clcb)
1785 {
1786     if (p_clcb && p_clcb->in_use) {
1787         btu_free_timer(&p_clcb->rsp_timer_ent);
1788         memset(p_clcb, 0, sizeof(tGATT_CLCB));
1789         list_remove(gatt_cb.p_clcb_list, p_clcb);
1790 	p_clcb = NULL;
1791     }
1792 }
1793 
1794 
1795 
1796 /*******************************************************************************
1797 **
1798 ** Function         gatt_find_tcb_by_cid
1799 **
1800 ** Description      The function searches for an empty entry
1801 **                   in registration info table for GATT client
1802 **
1803 ** Returns           NULL if not found. Otherwise pointer to the rcb.
1804 **
1805 *******************************************************************************/
gatt_find_tcb_by_cid(UINT16 lcid)1806 tGATT_TCB *gatt_find_tcb_by_cid (UINT16 lcid)
1807 {
1808     tGATT_TCB   *p_tcb  = NULL;
1809     list_node_t *p_node = NULL;
1810     for(p_node = list_begin(gatt_cb.p_tcb_list); p_node; p_node = list_next(p_node)) {
1811 	p_tcb = list_node(p_node);
1812         if (p_tcb->in_use && p_tcb->att_lcid == lcid) {
1813             break;
1814         }
1815     }
1816     return p_tcb;
1817 }
1818 
1819 /*******************************************************************************
1820 **
1821 ** Function         gatt_num_apps_hold_link
1822 **
1823 ** Description      The function find the number of applcaitions is holding the link
1824 **
1825 ** Returns          total number of applications holding this acl link.
1826 **
1827 *******************************************************************************/
gatt_num_apps_hold_link(tGATT_TCB * p_tcb)1828 UINT8 gatt_num_apps_hold_link(tGATT_TCB *p_tcb)
1829 {
1830     UINT8 i, num = 0;
1831 
1832     for (i = 0; i < GATT_MAX_APPS; i ++) {
1833         if (p_tcb->app_hold_link[i]) {
1834             num ++;
1835         }
1836     }
1837 
1838     GATT_TRACE_DEBUG("gatt_num_apps_hold_link   num=%d",  num);
1839     return num;
1840 }
1841 
1842 
1843 /*******************************************************************************
1844 **
1845 ** Function         gatt_num_clcb_by_bd_addr
1846 **
1847 ** Description      The function searches all LCB with macthing bd address
1848 **
1849 ** Returns          total number of clcb found.
1850 **
1851 *******************************************************************************/
gatt_num_clcb_by_bd_addr(BD_ADDR bda)1852 UINT8 gatt_num_clcb_by_bd_addr(BD_ADDR bda)
1853 {
1854     UINT8 num = 0;
1855 
1856     list_node_t *p_node = NULL;
1857     tGATT_CLCB  *p_clcb = NULL;
1858     for(p_node = list_begin(gatt_cb.p_clcb_list); p_node; p_node = list_next(p_node)) {
1859         p_clcb = list_node(p_node);
1860 	if (memcmp(p_clcb->p_tcb->peer_bda, bda, BD_ADDR_LEN) == 0) {
1861 	    num++;
1862 	}
1863     }
1864     return num;
1865 }
1866 
1867 /*******************************************************************************
1868 **
1869 ** Function         gatt_sr_update_cback_cnt
1870 **
1871 ** Description      The function searches all LCB with macthing bd address
1872 **
1873 ** Returns          total number of clcb found.
1874 **
1875 *******************************************************************************/
gatt_sr_copy_prep_cnt_to_cback_cnt(tGATT_TCB * p_tcb)1876 void gatt_sr_copy_prep_cnt_to_cback_cnt(tGATT_TCB *p_tcb )
1877 {
1878 #if (GATTS_INCLUDED == TRUE)
1879     UINT8 i;
1880 
1881     if (p_tcb) {
1882         for (i = 0; i < GATT_MAX_APPS; i ++) {
1883             if (p_tcb->prep_cnt[i]) {
1884                 p_tcb->sr_cmd.cback_cnt[i] = 1;
1885             }
1886         }
1887     }
1888 #endif  ///GATTS_INCLUDED == TRUE
1889 }
1890 
1891 /*******************************************************************************
1892 **
1893 ** Function         gatt_sr_is_cback_cnt_zero
1894 **
1895 ** Description      The function searches all LCB with macthing bd address
1896 **
1897 ** Returns          True if thetotal application callback count is zero
1898 **
1899 *******************************************************************************/
gatt_sr_is_cback_cnt_zero(tGATT_TCB * p_tcb)1900 BOOLEAN gatt_sr_is_cback_cnt_zero(tGATT_TCB *p_tcb )
1901 {
1902     BOOLEAN status = TRUE;
1903 #if (GATTS_INCLUDED == TRUE)
1904     UINT8   i;
1905 
1906     if (p_tcb) {
1907         for (i = 0; i < GATT_MAX_APPS; i ++) {
1908             if (p_tcb->sr_cmd.cback_cnt[i]) {
1909                 status = FALSE;
1910                 break;
1911             }
1912         }
1913     } else {
1914         status = FALSE;
1915     }
1916 #endif  ///GATTS_INCLUDED == TRUE
1917     return status;
1918 }
1919 
1920 /*******************************************************************************
1921 **
1922 ** Function         gatt_sr_is_prep_cnt_zero
1923 **
1924 ** Description      Check the prepare write request count is zero or not
1925 **
1926 ** Returns          True no prepare write request
1927 **
1928 *******************************************************************************/
gatt_sr_is_prep_cnt_zero(tGATT_TCB * p_tcb)1929 BOOLEAN gatt_sr_is_prep_cnt_zero(tGATT_TCB *p_tcb)
1930 {
1931     BOOLEAN status = TRUE;
1932     UINT8   i;
1933 
1934     if (p_tcb) {
1935         for (i = 0; i < GATT_MAX_APPS; i ++) {
1936             if (p_tcb->prep_cnt[i]) {
1937                 status = FALSE;
1938                 break;
1939             }
1940         }
1941     } else {
1942         status = FALSE;
1943     }
1944     return status;
1945 }
1946 
1947 
1948 /*******************************************************************************
1949 **
1950 ** Function         gatt_sr_reset_cback_cnt
1951 **
1952 ** Description      Reset the application callback count to zero
1953 **
1954 ** Returns         None
1955 **
1956 *******************************************************************************/
gatt_sr_reset_cback_cnt(tGATT_TCB * p_tcb)1957 void gatt_sr_reset_cback_cnt(tGATT_TCB *p_tcb )
1958 {
1959 #if (GATTS_INCLUDED == TRUE)
1960     UINT8 i;
1961 
1962     if (p_tcb) {
1963         for (i = 0; i < GATT_MAX_APPS; i ++) {
1964             p_tcb->sr_cmd.cback_cnt[i] = 0;
1965         }
1966     }
1967 #endif  ///GATTS_INCLUDED == TRUE
1968 }
1969 
1970 /*******************************************************************************
1971 **
1972 ** Function         gatt_sr_reset_prep_cnt
1973 **
1974 ** Description     Reset the prep write count to zero
1975 **
1976 ** Returns        None
1977 **
1978 *******************************************************************************/
gatt_sr_reset_prep_cnt(tGATT_TCB * p_tcb)1979 void gatt_sr_reset_prep_cnt(tGATT_TCB *p_tcb )
1980 {
1981     UINT8 i;
1982     if (p_tcb) {
1983         for (i = 0; i < GATT_MAX_APPS; i ++) {
1984             p_tcb->prep_cnt[i] = 0;
1985         }
1986     }
1987 }
1988 
1989 
1990 /*******************************************************************************
1991 **
1992 ** Function         gatt_sr_update_cback_cnt
1993 **
1994 ** Description    Update the teh application callback count
1995 **
1996 ** Returns           None
1997 **
1998 *******************************************************************************/
gatt_sr_update_cback_cnt(tGATT_TCB * p_tcb,tGATT_IF gatt_if,BOOLEAN is_inc,BOOLEAN is_reset_first)1999 void gatt_sr_update_cback_cnt(tGATT_TCB *p_tcb, tGATT_IF gatt_if, BOOLEAN is_inc, BOOLEAN is_reset_first)
2000 {
2001 #if (GATTS_INCLUDED == TRUE)
2002     UINT8 idx = ((UINT8) gatt_if) - 1 ;
2003 
2004     if (p_tcb) {
2005         if (is_reset_first) {
2006             gatt_sr_reset_cback_cnt(p_tcb);
2007         }
2008         if (is_inc) {
2009             p_tcb->sr_cmd.cback_cnt[idx]++;
2010         } else {
2011             if ( p_tcb->sr_cmd.cback_cnt[idx]) {
2012                 p_tcb->sr_cmd.cback_cnt[idx]--;
2013             }
2014         }
2015     }
2016 #endif  ///GATTS_INCLUDED == TRUE
2017 }
2018 
2019 
2020 /*******************************************************************************
2021 **
2022 ** Function         gatt_sr_update_prep_cnt
2023 **
2024 ** Description    Update the teh prepare write request count
2025 **
2026 ** Returns           None
2027 **
2028 *******************************************************************************/
gatt_sr_update_prep_cnt(tGATT_TCB * p_tcb,tGATT_IF gatt_if,BOOLEAN is_inc,BOOLEAN is_reset_first)2029 void gatt_sr_update_prep_cnt(tGATT_TCB *p_tcb, tGATT_IF gatt_if, BOOLEAN is_inc, BOOLEAN is_reset_first)
2030 {
2031     UINT8 idx = ((UINT8) gatt_if) - 1 ;
2032 
2033     GATT_TRACE_DEBUG("gatt_sr_update_prep_cnt tcb idx=%d gatt_if=%d is_inc=%d is_reset_first=%d",
2034                      p_tcb->tcb_idx, gatt_if, is_inc, is_reset_first);
2035 
2036     if (p_tcb) {
2037         if (is_reset_first) {
2038             gatt_sr_reset_prep_cnt(p_tcb);
2039         }
2040         if (is_inc) {
2041             p_tcb->prep_cnt[idx]++;
2042         } else {
2043             if (p_tcb->prep_cnt[idx]) {
2044                 p_tcb->prep_cnt[idx]--;
2045             }
2046         }
2047     }
2048 }
2049 /*******************************************************************************
2050 **
2051 ** Function         gatt_cancel_open
2052 **
2053 ** Description      Cancel open request
2054 **
2055 ** Returns         Boolean
2056 **
2057 *******************************************************************************/
gatt_cancel_open(tGATT_IF gatt_if,BD_ADDR bda)2058 BOOLEAN gatt_cancel_open(tGATT_IF gatt_if, BD_ADDR bda)
2059 {
2060     tGATT_TCB *p_tcb = NULL;
2061     BOOLEAN status = TRUE;
2062 
2063     p_tcb = gatt_find_tcb_by_addr(bda, BT_TRANSPORT_LE);
2064 
2065     if (p_tcb) {
2066         if (gatt_get_ch_state(p_tcb) == GATT_CH_OPEN) {
2067             GATT_TRACE_ERROR("GATT_CancelConnect - link connected Too late to cancel");
2068             status = FALSE;
2069         } else {
2070             gatt_update_app_use_link_flag(gatt_if, p_tcb, FALSE, FALSE);
2071             if (!gatt_num_apps_hold_link(p_tcb)) {
2072                 gatt_disconnect(p_tcb);
2073             }
2074         }
2075     }
2076 
2077     return status;
2078 }
2079 
2080 /*******************************************************************************
2081 **
2082 ** Function         gatt_find_app_hold_link
2083 **
2084 ** Description      find the application that is holding the specified link
2085 **
2086 ** Returns         Boolean
2087 **
2088 *******************************************************************************/
gatt_find_app_hold_link(tGATT_TCB * p_tcb,UINT8 start_idx,UINT8 * p_found_idx,tGATT_IF * p_gatt_if)2089 BOOLEAN gatt_find_app_hold_link(tGATT_TCB *p_tcb, UINT8 start_idx, UINT8 *p_found_idx, tGATT_IF *p_gatt_if)
2090 {
2091     UINT8 i;
2092     BOOLEAN found = FALSE;
2093 
2094     for (i = start_idx; i < GATT_MAX_APPS; i ++) {
2095         if (p_tcb->app_hold_link[i]) {
2096             *p_gatt_if = p_tcb->app_hold_link[i];
2097             *p_found_idx = i;
2098             found = TRUE;
2099             break;
2100         }
2101     }
2102     return found;
2103 }
2104 
2105 /*******************************************************************************
2106 **
2107 ** Function         gatt_find_specific_app_in_hold_link
2108 **
2109 ** Description      find the specific application that is holding the specified link
2110 **
2111 ** Returns         Boolean
2112 **
2113 *******************************************************************************/
gatt_find_specific_app_in_hold_link(tGATT_TCB * p_tcb,tGATT_IF p_gatt_if)2114 BOOLEAN gatt_find_specific_app_in_hold_link(tGATT_TCB *p_tcb, tGATT_IF p_gatt_if)
2115 {
2116     UINT8 i;
2117     BOOLEAN found = FALSE;
2118 
2119     for (i = 0; i < GATT_MAX_APPS; i ++) {
2120         if (p_tcb->app_hold_link[i] && p_tcb->app_hold_link[i] == p_gatt_if) {
2121             found = TRUE;
2122             break;
2123         }
2124     }
2125     return found;
2126 }
2127 
2128 /*******************************************************************************
2129 **
2130 ** Function         gatt_cmd_enq
2131 **
2132 ** Description      Enqueue this command.
2133 **
2134 ** Returns          None.
2135 **
2136 *******************************************************************************/
gatt_cmd_enq(tGATT_TCB * p_tcb,UINT16 clcb_idx,BOOLEAN to_send,UINT8 op_code,BT_HDR * p_buf)2137 BOOLEAN gatt_cmd_enq(tGATT_TCB *p_tcb, UINT16 clcb_idx, BOOLEAN to_send, UINT8 op_code, BT_HDR *p_buf)
2138 {
2139     tGATT_CMD_Q  *p_cmd = &p_tcb->cl_cmd_q[p_tcb->next_slot_inq];
2140 
2141     p_cmd->to_send = to_send; /* waiting to be sent */
2142     p_cmd->op_code  = op_code;
2143     p_cmd->p_cmd    = p_buf;
2144     p_cmd->clcb_idx = clcb_idx;
2145 
2146     if (!to_send) {
2147         p_tcb->pending_cl_req = p_tcb->next_slot_inq;
2148     }
2149 
2150     p_tcb->next_slot_inq ++;
2151     p_tcb->next_slot_inq %= GATT_CL_MAX_LCB;
2152 
2153     return TRUE;
2154 }
2155 
2156 /*******************************************************************************
2157 **
2158 ** Function         gatt_cmd_dequeue
2159 **
2160 ** Description      dequeue the command in the client CCB command queue.
2161 **
2162 ** Returns          total number of clcb found.
2163 **
2164 *******************************************************************************/
gatt_cmd_dequeue(tGATT_TCB * p_tcb,UINT8 * p_op_code)2165 tGATT_CLCB *gatt_cmd_dequeue(tGATT_TCB *p_tcb, UINT8 *p_op_code)
2166 {
2167     tGATT_CMD_Q  *p_cmd = &p_tcb->cl_cmd_q[p_tcb->pending_cl_req];
2168     tGATT_CLCB *p_clcb = NULL;
2169 
2170     if (p_tcb->pending_cl_req != p_tcb->next_slot_inq) {
2171         p_clcb = gatt_clcb_find_by_idx(p_cmd->clcb_idx);
2172 
2173         *p_op_code = p_cmd->op_code;
2174 
2175         p_tcb->pending_cl_req ++;
2176         p_tcb->pending_cl_req %= GATT_CL_MAX_LCB;
2177     }
2178 
2179     return p_clcb;
2180 }
2181 
2182 /*******************************************************************************
2183 **
2184 ** Function         gatt_send_write_msg
2185 **
2186 ** Description      This real function send out the ATT message for write.
2187 **
2188 ** Returns          status code
2189 **
2190 *******************************************************************************/
gatt_send_write_msg(tGATT_TCB * p_tcb,UINT16 clcb_idx,UINT8 op_code,UINT16 handle,UINT16 len,UINT16 offset,UINT8 * p_data)2191 UINT8 gatt_send_write_msg (tGATT_TCB *p_tcb, UINT16 clcb_idx, UINT8 op_code,
2192                            UINT16 handle, UINT16 len,
2193                            UINT16 offset, UINT8 *p_data)
2194 {
2195     tGATT_CL_MSG     msg;
2196 
2197     msg.attr_value.handle = handle;
2198     msg.attr_value.len = len;
2199     msg.attr_value.offset = offset;
2200 
2201     memcpy (msg.attr_value.value, p_data, len);
2202 
2203     /* write by handle */
2204     return attp_send_cl_msg(p_tcb, clcb_idx, op_code, &msg);
2205 }
2206 
2207 /*******************************************************************************
2208 **
2209 ** Function         gatt_act_send_browse
2210 **
2211 ** Description      This function ends a browse command request, including read
2212 **                  information request and read by type request.
2213 **
2214 ** Returns          status code
2215 **
2216 *******************************************************************************/
gatt_act_send_browse(tGATT_TCB * p_tcb,UINT16 index,UINT8 op,UINT16 s_handle,UINT16 e_handle,tBT_UUID uuid)2217 UINT8 gatt_act_send_browse(tGATT_TCB *p_tcb, UINT16 index, UINT8 op, UINT16 s_handle,
2218                            UINT16 e_handle, tBT_UUID uuid)
2219 {
2220     tGATT_CL_MSG     msg;
2221 
2222     msg.browse.s_handle = s_handle;
2223     msg.browse.e_handle   = e_handle;
2224     memcpy(&msg.browse.uuid, &uuid, sizeof(tBT_UUID));
2225 
2226     /* write by handle */
2227     return attp_send_cl_msg(p_tcb, index, op, &msg);
2228 }
2229 
2230 /*******************************************************************************
2231 **
2232 ** Function         gatt_end_operation
2233 **
2234 ** Description      This function ends a discovery, send callback and finalize
2235 **                  some control value.
2236 **
2237 ** Returns          16 bits uuid.
2238 **
2239 *******************************************************************************/
gatt_end_operation(tGATT_CLCB * p_clcb,tGATT_STATUS status,void * p_data)2240 void gatt_end_operation(tGATT_CLCB *p_clcb, tGATT_STATUS status, void *p_data)
2241 {
2242     tGATT_CL_COMPLETE   cb_data;
2243     tGATT_CMPL_CBACK    *p_cmpl_cb = (p_clcb->p_reg) ? p_clcb->p_reg->app_cb.p_cmpl_cb : NULL;
2244     UINT8               op = p_clcb->operation, disc_type = GATT_DISC_MAX;
2245     tGATT_DISC_CMPL_CB  *p_disc_cmpl_cb = (p_clcb->p_reg) ? p_clcb->p_reg->app_cb.p_disc_cmpl_cb : NULL;
2246     UINT16              conn_id;
2247 #if (!CONFIG_BT_STACK_NO_LOG)
2248     UINT8               operation;
2249 #endif
2250 
2251     GATT_TRACE_DEBUG ("gatt_end_operation status=%d op=%d subtype=%d",
2252                       status, p_clcb->operation, p_clcb->op_subtype);
2253     memset(&cb_data.att_value, 0, sizeof(tGATT_VALUE));
2254 
2255     if (p_cmpl_cb != NULL && p_clcb->operation != 0) {
2256         if (p_clcb->operation == GATTC_OPTYPE_READ) {
2257             cb_data.att_value.handle   = p_clcb->s_handle;
2258             cb_data.att_value.len      = p_clcb->counter;
2259 
2260             if (p_data && p_clcb->counter) {
2261                 memcpy (cb_data.att_value.value, p_data, cb_data.att_value.len);
2262             }
2263         }
2264 
2265         if (p_clcb->operation == GATTC_OPTYPE_WRITE) {
2266             memset(&cb_data.att_value, 0, sizeof(tGATT_VALUE));
2267             cb_data.handle           =
2268                 cb_data.att_value.handle = p_clcb->s_handle;
2269             if (p_clcb->op_subtype == GATT_WRITE_PREPARE) {
2270                 if (p_data) {
2271                     cb_data.att_value = *((tGATT_VALUE *) p_data);
2272                 } else {
2273                     GATT_TRACE_DEBUG("Rcv Prepare write rsp but no data");
2274                 }
2275             }
2276         }
2277 
2278         if (p_clcb->operation == GATTC_OPTYPE_CONFIG) {
2279             cb_data.mtu = p_clcb->p_tcb->payload_size;
2280         }
2281 
2282         if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY) {
2283             disc_type = p_clcb->op_subtype;
2284         }
2285     }
2286 
2287     if (p_clcb->p_attr_buf) {
2288         osi_free(p_clcb->p_attr_buf);
2289     }
2290 
2291 #if !CONFIG_BT_STACK_NO_LOG
2292     operation =  p_clcb->operation;
2293 #endif
2294 
2295     conn_id = p_clcb->conn_id;
2296     btu_stop_timer(&p_clcb->rsp_timer_ent);
2297 
2298     gatt_clcb_dealloc(p_clcb);
2299 
2300     if (p_disc_cmpl_cb && (op == GATTC_OPTYPE_DISCOVERY)) {
2301         (*p_disc_cmpl_cb)(conn_id, disc_type, status);
2302     } else if (p_cmpl_cb && op) {
2303         (*p_cmpl_cb)(conn_id, op, status, &cb_data);
2304     } else {
2305         GATT_TRACE_WARNING ("gatt_end_operation not sent out op=%d p_disc_cmpl_cb:%p p_cmpl_cb:%p",
2306                             operation, p_disc_cmpl_cb, p_cmpl_cb);
2307     }
2308 }
2309 
2310 /*******************************************************************************
2311 **
2312 ** Function         gatt_cleanup_upon_disc
2313 **
2314 ** Description      This function cleans up the control blocks when L2CAP channel
2315 **                  disconnect.
2316 **
2317 ** Returns          16 bits uuid.
2318 **
2319 *******************************************************************************/
gatt_cleanup_upon_disc(BD_ADDR bda,UINT16 reason,tBT_TRANSPORT transport)2320 void gatt_cleanup_upon_disc(BD_ADDR bda, UINT16 reason, tBT_TRANSPORT transport)
2321 {
2322     tGATT_TCB       *p_tcb = NULL;
2323     tGATT_CLCB      *p_clcb;
2324     UINT8           i;
2325     UINT16          conn_id;
2326     tGATT_REG        *p_reg = NULL;
2327 
2328 
2329     GATT_TRACE_DEBUG ("gatt_cleanup_upon_disc ");
2330 
2331     if ((p_tcb = gatt_find_tcb_by_addr(bda, transport)) != NULL) {
2332         GATT_TRACE_DEBUG ("found p_tcb ");
2333         gatt_set_ch_state(p_tcb, GATT_CH_CLOSE);
2334         list_node_t *p_node = NULL;
2335         list_node_t *p_node_next = NULL;
2336 	for(p_node = list_begin(gatt_cb.p_clcb_list); p_node; p_node = p_node_next) {
2337             p_clcb = list_node(p_node);
2338             p_node_next = list_next(p_node);
2339             if (p_clcb->in_use && p_clcb->p_tcb == p_tcb) {
2340                 btu_stop_timer(&p_clcb->rsp_timer_ent);
2341                 GATT_TRACE_DEBUG ("found p_clcb conn_id=%d clcb_idx=%d", p_clcb->conn_id, p_clcb->clcb_idx);
2342                 if (p_clcb->operation != GATTC_OPTYPE_NONE) {
2343                     gatt_end_operation(p_clcb, GATT_ERROR, NULL);
2344                     p_clcb = NULL;
2345                 }
2346                 gatt_clcb_dealloc(p_clcb);
2347             }
2348         }
2349 
2350         btu_free_timer (&p_tcb->ind_ack_timer_ent);
2351         btu_free_timer (&p_tcb->conf_timer_ent);
2352         gatt_free_pending_ind(p_tcb);
2353         gatt_free_pending_enc_queue(p_tcb);
2354         gatt_free_pending_prepare_write_queue(p_tcb);
2355 #if (GATTS_INCLUDED)
2356         fixed_queue_free(p_tcb->sr_cmd.multi_rsp_q, osi_free_func);
2357         p_tcb->sr_cmd.multi_rsp_q = NULL;
2358 #endif /* #if (GATTS_INCLUDED) */
2359         for (i = 0; i < GATT_MAX_APPS; i ++) {
2360             p_reg = &gatt_cb.cl_rcb[i];
2361             if (p_reg->in_use && p_reg->app_cb.p_conn_cb) {
2362                 conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if);
2363                 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);
2364                 (*p_reg->app_cb.p_conn_cb)(p_reg->gatt_if,  bda, conn_id, FALSE, reason, transport);
2365             }
2366         }
2367         gatt_tcb_free(p_tcb);
2368     } else {
2369         GATT_TRACE_DEBUG ("exit gatt_cleanup_upon_disc ");
2370         BTM_Recovery_Pre_State();
2371     }
2372     gatt_delete_dev_from_srv_chg_clt_list(bda);
2373 }
2374 /*******************************************************************************
2375 **
2376 ** Function         gatt_dbg_req_op_name
2377 **
2378 ** Description      Get op code description name, for debug information.
2379 **
2380 ** Returns          UINT8 *: name of the operation.
2381 **
2382 *******************************************************************************/
gatt_dbg_op_name(UINT8 op_code)2383 UINT8 *gatt_dbg_op_name(UINT8 op_code)
2384 {
2385     UINT8 pseduo_op_code_idx = op_code & (~GATT_WRITE_CMD_MASK);
2386 
2387     if (op_code == GATT_CMD_WRITE ) {
2388         pseduo_op_code_idx = 0x14; /* just an index to op_code_name */
2389 
2390     }
2391 
2392     if (op_code == GATT_SIGN_CMD_WRITE) {
2393         pseduo_op_code_idx = 0x15; /* just an index to op_code_name */
2394     }
2395 
2396     if (pseduo_op_code_idx <= GATT_OP_CODE_MAX) {
2397         return (UINT8 *) op_code_name[pseduo_op_code_idx];
2398     } else {
2399         return (UINT8 *)"Op Code Exceed Max";
2400     }
2401 }
2402 
2403 /*******************************************************************************
2404 **
2405 ** Function         gatt_dbg_display_uuid
2406 **
2407 ** Description      Disaplay the UUID
2408 **
2409 ** Returns          None
2410 **
2411 *******************************************************************************/
gatt_dbg_display_uuid(tBT_UUID bt_uuid)2412 void gatt_dbg_display_uuid(tBT_UUID bt_uuid)
2413 {
2414     char str_buf[50];
2415     int x = 0;
2416 
2417     if (bt_uuid.len == LEN_UUID_16) {
2418         sprintf(str_buf, "0x%04x", bt_uuid.uu.uuid16);
2419     } else if (bt_uuid.len == LEN_UUID_32) {
2420         sprintf(str_buf, "0x%08x", (unsigned int)bt_uuid.uu.uuid32);
2421     } else if (bt_uuid.len == LEN_UUID_128) {
2422         x += sprintf(&str_buf[x], "0x%02x%02x%02x%02x%02x%02x%02x%02x",
2423                      bt_uuid.uu.uuid128[15], bt_uuid.uu.uuid128[14],
2424                      bt_uuid.uu.uuid128[13], bt_uuid.uu.uuid128[12],
2425                      bt_uuid.uu.uuid128[11], bt_uuid.uu.uuid128[10],
2426                      bt_uuid.uu.uuid128[9], bt_uuid.uu.uuid128[8]);
2427         sprintf(&str_buf[x], "%02x%02x%02x%02x%02x%02x%02x%02x",
2428                 bt_uuid.uu.uuid128[7], bt_uuid.uu.uuid128[6],
2429                 bt_uuid.uu.uuid128[5], bt_uuid.uu.uuid128[4],
2430                 bt_uuid.uu.uuid128[3], bt_uuid.uu.uuid128[2],
2431                 bt_uuid.uu.uuid128[1], bt_uuid.uu.uuid128[0]);
2432     } else {
2433         BCM_STRNCPY_S(str_buf, "Unknown UUID 0", 15);
2434     }
2435 
2436     GATT_TRACE_DEBUG ("UUID=[%s]", str_buf);
2437 
2438 }
2439 
2440 
2441 /*******************************************************************************
2442 **
2443 ** Function         gatt_is_bg_dev_for_app
2444 **
2445 ** Description      find is this one of the background devices for the application
2446 **
2447 ** Returns          TRUE this is one of the background devices for the  application
2448 **
2449 *******************************************************************************/
gatt_is_bg_dev_for_app(tGATT_BG_CONN_DEV * p_dev,tGATT_IF gatt_if)2450 BOOLEAN gatt_is_bg_dev_for_app(tGATT_BG_CONN_DEV *p_dev, tGATT_IF gatt_if)
2451 {
2452     UINT8   i;
2453 
2454     for (i = 0; i < GATT_MAX_APPS; i ++ ) {
2455         if (p_dev->in_use && (p_dev->gatt_if[i] == gatt_if)) {
2456             return TRUE;
2457         }
2458     }
2459     return FALSE;
2460 }
2461 /*******************************************************************************
2462 **
2463 ** Function         gatt_find_bg_dev
2464 **
2465 ** Description      find background connection device from the list.
2466 **
2467 ** Returns          pointer to the device record
2468 **
2469 *******************************************************************************/
gatt_find_bg_dev(BD_ADDR remote_bda)2470 tGATT_BG_CONN_DEV *gatt_find_bg_dev(BD_ADDR remote_bda)
2471 {
2472     tGATT_BG_CONN_DEV    *p_dev_list = &gatt_cb.bgconn_dev[0];
2473     UINT8   i;
2474 
2475     for (i = 0; i < GATT_MAX_BG_CONN_DEV; i ++, p_dev_list ++) {
2476         if (p_dev_list->in_use && !memcmp(p_dev_list->remote_bda, remote_bda, BD_ADDR_LEN)) {
2477             return p_dev_list;
2478         }
2479     }
2480     return NULL;
2481 }
2482 /*******************************************************************************
2483 **
2484 ** Function         gatt_alloc_bg_dev
2485 **
2486 ** Description      allocate a background connection device record
2487 **
2488 ** Returns          pointer to the device record
2489 **
2490 *******************************************************************************/
gatt_alloc_bg_dev(BD_ADDR remote_bda)2491 tGATT_BG_CONN_DEV *gatt_alloc_bg_dev(BD_ADDR remote_bda)
2492 {
2493     tGATT_BG_CONN_DEV    *p_dev_list = &gatt_cb.bgconn_dev[0];
2494     UINT8   i;
2495 
2496     for (i = 0; i < GATT_MAX_BG_CONN_DEV; i ++, p_dev_list ++) {
2497         if (!p_dev_list->in_use) {
2498             p_dev_list->in_use = TRUE;
2499             memcpy(p_dev_list->remote_bda, remote_bda, BD_ADDR_LEN);
2500 
2501             return p_dev_list;
2502         }
2503     }
2504     return NULL;
2505 }
2506 
2507 /*******************************************************************************
2508 **
2509 ** Function         gatt_add_bg_dev_list
2510 **
2511 ** Description      add/remove device from the background connection device list
2512 **
2513 ** Returns          TRUE if device added to the list; FALSE failed
2514 **
2515 *******************************************************************************/
gatt_add_bg_dev_list(tGATT_REG * p_reg,BD_ADDR bd_addr,BOOLEAN is_initator)2516 BOOLEAN gatt_add_bg_dev_list(tGATT_REG *p_reg,  BD_ADDR bd_addr, BOOLEAN is_initator)
2517 {
2518     tGATT_IF gatt_if =  p_reg->gatt_if;
2519     tGATT_BG_CONN_DEV   *p_dev = NULL;
2520     UINT8       i;
2521     BOOLEAN      ret = FALSE;
2522 
2523     if ((p_dev = gatt_find_bg_dev(bd_addr)) == NULL) {
2524         p_dev = gatt_alloc_bg_dev(bd_addr);
2525     }
2526 
2527     if (p_dev) {
2528         for (i = 0; i < GATT_MAX_APPS; i ++) {
2529             if (is_initator) {
2530                 if (p_dev->gatt_if[i] == gatt_if) {
2531                     GATT_TRACE_ERROR("device already in iniator white list");
2532                     return TRUE;
2533                 } else if (p_dev->gatt_if[i] == 0) {
2534                     p_dev->gatt_if[i] = gatt_if;
2535                     if (i == 0) {
2536                         ret = BTM_BleUpdateBgConnDev(TRUE, bd_addr);
2537                     } else {
2538                         ret = TRUE;
2539                     }
2540                     break;
2541                 }
2542             } else {
2543                 if (p_dev->listen_gif[i] == gatt_if) {
2544                     GATT_TRACE_ERROR("device already in adv white list");
2545                     return TRUE;
2546                 } else if (p_dev->listen_gif[i] == 0) {
2547                     if (p_reg->listening == GATT_LISTEN_TO_ALL) {
2548                         p_reg->listening = GATT_LISTEN_TO_NONE;
2549                     }
2550 
2551                     p_reg->listening ++;
2552                     p_dev->listen_gif[i] = gatt_if;
2553 
2554                     if (i == 0) {
2555                         // To check, we do not support background connection, code will not be called here
2556                         ret = BTM_BleUpdateAdvWhitelist(TRUE, bd_addr, 0, NULL);
2557                     } else {
2558                         ret = TRUE;
2559                     }
2560                     break;
2561                 }
2562             }
2563         }
2564     } else {
2565         GATT_TRACE_ERROR("no device record available");
2566     }
2567 
2568     return ret;
2569 }
2570 
2571 /*******************************************************************************
2572 **
2573 ** Function         gatt_remove_bg_dev_for_app
2574 **
2575 ** Description      Remove the application interface for the specified background device
2576 **
2577 ** Returns          Boolean
2578 **
2579 *******************************************************************************/
gatt_remove_bg_dev_for_app(tGATT_IF gatt_if,BD_ADDR bd_addr)2580 BOOLEAN gatt_remove_bg_dev_for_app(tGATT_IF gatt_if, BD_ADDR bd_addr)
2581 {
2582     tGATT_TCB    *p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE);
2583     BOOLEAN       status;
2584 
2585     if (p_tcb) {
2586         gatt_update_app_use_link_flag(gatt_if, p_tcb, FALSE, FALSE);
2587     }
2588     status = gatt_update_auto_connect_dev(gatt_if, FALSE, bd_addr, TRUE);
2589     return status;
2590 }
2591 
2592 
2593 /*******************************************************************************
2594 **
2595 ** Function         gatt_get_num_apps_for_bg_dev
2596 **
2597 ** Description      Gte the number of applciations for the specified background device
2598 **
2599 ** Returns          UINT8 total number fo applications
2600 **
2601 *******************************************************************************/
gatt_get_num_apps_for_bg_dev(BD_ADDR bd_addr)2602 UINT8 gatt_get_num_apps_for_bg_dev(BD_ADDR bd_addr)
2603 {
2604     tGATT_BG_CONN_DEV   *p_dev = NULL;
2605     UINT8   i;
2606     UINT8   cnt = 0;
2607 
2608     if ((p_dev = gatt_find_bg_dev(bd_addr)) != NULL) {
2609         for (i = 0; i < GATT_MAX_APPS; i ++) {
2610             if (p_dev->gatt_if[i]) {
2611                 cnt++;
2612             }
2613         }
2614     }
2615     return cnt;
2616 }
2617 
2618 /*******************************************************************************
2619 **
2620 ** Function         gatt_find_app_for_bg_dev
2621 **
2622 ** Description      find the application interface for the specified background device
2623 **
2624 ** Returns          Boolean
2625 **
2626 *******************************************************************************/
gatt_find_app_for_bg_dev(BD_ADDR bd_addr,tGATT_IF * p_gatt_if)2627 BOOLEAN gatt_find_app_for_bg_dev(BD_ADDR bd_addr, tGATT_IF *p_gatt_if)
2628 {
2629     tGATT_BG_CONN_DEV   *p_dev = NULL;
2630     UINT8   i;
2631     BOOLEAN ret = FALSE;
2632 
2633     if ((p_dev = gatt_find_bg_dev(bd_addr)) == NULL) {
2634         return ret;
2635     }
2636 
2637     for (i = 0; i < GATT_MAX_APPS; i ++) {
2638         if (p_dev->gatt_if[i] != 0 ) {
2639             *p_gatt_if = p_dev->gatt_if[i];
2640             ret = TRUE;
2641             break;
2642         }
2643     }
2644     return ret;
2645 }
2646 
2647 
2648 /*******************************************************************************
2649 **
2650 ** Function         gatt_remove_bg_dev_from_list
2651 **
2652 ** Description      add/remove device from the background connection device list or
2653 **                  listening to advertising list.
2654 **
2655 ** Returns          pointer to the device record
2656 **
2657 *******************************************************************************/
gatt_remove_bg_dev_from_list(tGATT_REG * p_reg,BD_ADDR bd_addr,BOOLEAN is_initiator)2658 BOOLEAN gatt_remove_bg_dev_from_list(tGATT_REG *p_reg, BD_ADDR bd_addr, BOOLEAN is_initiator)
2659 {
2660     tGATT_IF gatt_if = p_reg->gatt_if;
2661     tGATT_BG_CONN_DEV   *p_dev = NULL;
2662     UINT8   i, j;
2663     BOOLEAN ret = FALSE;
2664 
2665     if ((p_dev = gatt_find_bg_dev(bd_addr)) == NULL) {
2666         return ret;
2667     }
2668 
2669     for (i = 0; i < GATT_MAX_APPS && (p_dev->gatt_if[i] > 0 || p_dev->listen_gif[i]); i ++) {
2670         if (is_initiator) {
2671             if (p_dev->gatt_if[i] == gatt_if) {
2672                 p_dev->gatt_if[i] = 0;
2673                 /* move all element behind one forward */
2674                 for (j = i + 1; j < GATT_MAX_APPS; j ++) {
2675                     p_dev->gatt_if[j - 1] = p_dev->gatt_if[j];
2676                 }
2677 
2678                 if (p_dev->gatt_if[0] == 0) {
2679                     ret = BTM_BleUpdateBgConnDev(FALSE, p_dev->remote_bda);
2680                 } else {
2681                     ret = TRUE;
2682                 }
2683 
2684                 break;
2685             }
2686         } else {
2687             if (p_dev->listen_gif[i] == gatt_if) {
2688                 p_dev->listen_gif[i] = 0;
2689                 p_reg->listening --;
2690                 /* move all element behind one forward */
2691                 for (j = i + 1; j < GATT_MAX_APPS; j ++) {
2692                     p_dev->listen_gif[j - 1] = p_dev->listen_gif[j];
2693                 }
2694 
2695                 if (p_dev->listen_gif[0] == 0) {
2696                     // To check, we do not support background connection, code will not be called here
2697                     ret = BTM_BleUpdateAdvWhitelist(FALSE, p_dev->remote_bda, 0, NULL);
2698                 } else {
2699                     ret = TRUE;
2700                 }
2701                 break;
2702             }
2703         }
2704     }
2705 
2706     if (i != GATT_MAX_APPS && p_dev->gatt_if[0] == 0 && p_dev->listen_gif[0] == 0) {
2707         memset(p_dev, 0, sizeof(tGATT_BG_CONN_DEV));
2708     }
2709 
2710     return ret;
2711 }
2712 /*******************************************************************************
2713 **
2714 ** Function         gatt_deregister_bgdev_list
2715 **
2716 ** Description      deregister all related background connection device.
2717 **
2718 ** Returns          pointer to the device record
2719 **
2720 *******************************************************************************/
gatt_deregister_bgdev_list(tGATT_IF gatt_if)2721 void gatt_deregister_bgdev_list(tGATT_IF gatt_if)
2722 {
2723     tGATT_BG_CONN_DEV    *p_dev_list = &gatt_cb.bgconn_dev[0];
2724     UINT8 i , j, k;
2725     tGATT_REG       *p_reg = gatt_get_regcb(gatt_if);
2726 
2727     /* update the BG conn device list */
2728     for (i = 0 ; i < GATT_MAX_BG_CONN_DEV; i ++, p_dev_list ++ ) {
2729         if (p_dev_list->in_use) {
2730             for (j = 0; j < GATT_MAX_APPS; j ++) {
2731                 if (p_dev_list->gatt_if[j] == 0 && p_dev_list->listen_gif[j] == 0) {
2732                     break;
2733                 }
2734 
2735                 if (p_dev_list->gatt_if[j] == gatt_if) {
2736                     for (k = j + 1; k < GATT_MAX_APPS; k ++) {
2737                         p_dev_list->gatt_if[k - 1] = p_dev_list->gatt_if[k];
2738                     }
2739 
2740                     if (p_dev_list->gatt_if[0] == 0) {
2741                         BTM_BleUpdateBgConnDev(FALSE, p_dev_list->remote_bda);
2742                     }
2743                 }
2744 
2745                 if (p_dev_list->listen_gif[j] == gatt_if) {
2746                     p_dev_list->listen_gif[j] = 0;
2747 
2748                     if (p_reg != NULL && p_reg->listening > 0) {
2749                         p_reg->listening --;
2750                     }
2751 
2752                     /* move all element behind one forward */
2753                     for (k = j + 1; k < GATT_MAX_APPS; k ++) {
2754                         p_dev_list->listen_gif[k - 1] = p_dev_list->listen_gif[k];
2755                     }
2756 
2757                     if (p_dev_list->listen_gif[0] == 0) {
2758                         // To check, we do not support background connection, code will not be called here
2759                         BTM_BleUpdateAdvWhitelist(FALSE, p_dev_list->remote_bda, 0, NULL);
2760                     }
2761                 }
2762             }
2763         }
2764     }
2765 }
2766 
2767 
2768 /*******************************************************************************
2769 **
2770 ** Function         gatt_reset_bgdev_list
2771 **
2772 ** Description      reset bg device list
2773 **
2774 ** Returns          pointer to the device record
2775 **
2776 *******************************************************************************/
gatt_reset_bgdev_list(void)2777 void gatt_reset_bgdev_list(void)
2778 {
2779     memset(&gatt_cb.bgconn_dev, 0 , sizeof(tGATT_BG_CONN_DEV)*GATT_MAX_BG_CONN_DEV);
2780 
2781 }
2782 /*******************************************************************************
2783 **
2784 ** Function         gatt_update_auto_connect_dev
2785 **
2786 ** Description      This function add or remove a device for background connection
2787 **                  procedure.
2788 **
2789 ** Parameters       gatt_if: Application ID.
2790 **                  add: add peer device
2791 **                  bd_addr: peer device address.
2792 **
2793 ** Returns          TRUE if connection started; FALSE if connection start failure.
2794 **
2795 *******************************************************************************/
gatt_update_auto_connect_dev(tGATT_IF gatt_if,BOOLEAN add,BD_ADDR bd_addr,BOOLEAN is_initator)2796 BOOLEAN gatt_update_auto_connect_dev (tGATT_IF gatt_if, BOOLEAN add, BD_ADDR bd_addr, BOOLEAN is_initator)
2797 {
2798     BOOLEAN         ret = FALSE;
2799     tGATT_REG        *p_reg;
2800     tGATT_TCB       *p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE);
2801 
2802     GATT_TRACE_API ("gatt_update_auto_connect_dev ");
2803     /* Make sure app is registered */
2804     if ((p_reg = gatt_get_regcb(gatt_if)) == NULL) {
2805         GATT_TRACE_ERROR("gatt_update_auto_connect_dev - gatt_if %d is not registered", gatt_if);
2806         return (FALSE);
2807     }
2808 
2809     if (add) {
2810         ret = gatt_add_bg_dev_list(p_reg, bd_addr, is_initator);
2811 
2812         if (ret && p_tcb != NULL) {
2813             /* if a connected device, update the link holding number */
2814             gatt_update_app_use_link_flag(gatt_if, p_tcb, TRUE, TRUE);
2815         }
2816     } else {
2817         ret = gatt_remove_bg_dev_from_list(p_reg, bd_addr, is_initator);
2818     }
2819     return ret;
2820 }
2821 
2822 
2823 
2824 /*******************************************************************************
2825 **
2826 ** Function     gatt_add_pending_new_srv_start
2827 **
2828 ** Description  Add a pending new srv start to the new service start queue
2829 **
2830 ** Returns    Pointer to the new service start buffer, NULL no buffer available
2831 **
2832 *******************************************************************************/
gatt_add_pending_enc_channel_clcb(tGATT_TCB * p_tcb,tGATT_CLCB * p_clcb)2833 tGATT_PENDING_ENC_CLCB *gatt_add_pending_enc_channel_clcb(tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb )
2834 {
2835     tGATT_PENDING_ENC_CLCB   *p_buf;
2836 
2837     GATT_TRACE_DEBUG ("gatt_add_pending_new_srv_start");
2838     if ((p_buf = (tGATT_PENDING_ENC_CLCB *)osi_malloc((UINT16)sizeof(tGATT_PENDING_ENC_CLCB))) != NULL) {
2839         GATT_TRACE_DEBUG ("enqueue a new pending encryption channel clcb");
2840         p_buf->p_clcb = p_clcb;
2841     fixed_queue_enqueue(p_tcb->pending_enc_clcb, p_buf, FIXED_QUEUE_MAX_TIMEOUT);
2842     }
2843     return p_buf;
2844 }
2845 /*******************************************************************************
2846 **
2847 ** Function     gatt_update_listen_mode
2848 **
2849 ** Description  update peripheral role listening mode
2850 **
2851 ** Returns    Pointer to the new service start buffer, NULL no buffer available
2852 **
2853 *******************************************************************************/
gatt_update_listen_mode(void)2854 BOOLEAN gatt_update_listen_mode(void)
2855 {
2856     UINT8           ii = 0;
2857     tGATT_REG       *p_reg = &gatt_cb.cl_rcb[0];
2858     UINT8           listening = 0;
2859     UINT16          connectability, window, interval;
2860     BOOLEAN         rt = TRUE;
2861 
2862     for (; ii < GATT_MAX_APPS; ii ++, p_reg ++) {
2863         if ( p_reg->in_use && p_reg->listening > listening) {
2864             listening = p_reg->listening;
2865         }
2866     }
2867 
2868     if (listening == GATT_LISTEN_TO_ALL ||
2869             listening == GATT_LISTEN_TO_NONE) {
2870         BTM_BleUpdateAdvFilterPolicy (AP_SCAN_CONN_ALL);
2871     } else {
2872         BTM_BleUpdateAdvFilterPolicy (AP_SCAN_CONN_WL);
2873     }
2874 
2875     if (rt) {
2876         connectability = BTM_ReadConnectability (&window, &interval);
2877 
2878         if (listening != GATT_LISTEN_TO_NONE) {
2879             connectability |= BTM_BLE_CONNECTABLE;
2880         } else {
2881             if ((connectability & BTM_BLE_CONNECTABLE) == 0) {
2882                 connectability &= ~BTM_BLE_CONNECTABLE;
2883             }
2884         }
2885         /* turning on the adv now */
2886         btm_ble_set_connectability(connectability);
2887     }
2888 
2889     return rt;
2890 
2891 }
2892 #endif
2893