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