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