OSDN Git Service

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