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