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