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