• 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->in_use = TRUE;
976             p_tcb->tcb_idx = i;
977             p_tcb->transport = transport;
978         }
979         memcpy(p_tcb->peer_bda, bda, BD_ADDR_LEN);
980     }
981     return p_tcb;
982 }
983 
984 /*******************************************************************************
985 **
986 ** Function         gatt_convert_uuid16_to_uuid128
987 **
988 ** Description      Convert a 16 bits UUID to be an standard 128 bits one.
989 **
990 ** Returns          TRUE if two uuid match; FALSE otherwise.
991 **
992 *******************************************************************************/
gatt_convert_uuid16_to_uuid128(UINT8 uuid_128[LEN_UUID_128],UINT16 uuid_16)993 void gatt_convert_uuid16_to_uuid128(UINT8 uuid_128[LEN_UUID_128], UINT16 uuid_16)
994 {
995     UINT8   *p = &uuid_128[LEN_UUID_128 - 4];
996 
997     memcpy (uuid_128, base_uuid, LEN_UUID_128);
998 
999     UINT16_TO_STREAM(p, uuid_16);
1000 }
1001 
1002 /*******************************************************************************
1003 **
1004 ** Function         gatt_convert_uuid32_to_uuid128
1005 **
1006 ** Description      Convert a 32 bits UUID to be an standard 128 bits one.
1007 **
1008 ** Returns          TRUE if two uuid match; FALSE otherwise.
1009 **
1010 *******************************************************************************/
gatt_convert_uuid32_to_uuid128(UINT8 uuid_128[LEN_UUID_128],UINT32 uuid_32)1011 void gatt_convert_uuid32_to_uuid128(UINT8 uuid_128[LEN_UUID_128], UINT32 uuid_32)
1012 {
1013     UINT8   *p = &uuid_128[LEN_UUID_128 - 4];
1014 
1015     memcpy (uuid_128, base_uuid, LEN_UUID_128);
1016 
1017     UINT32_TO_STREAM(p, uuid_32);
1018 }
1019 /*******************************************************************************
1020 **
1021 ** Function         gatt_uuid_compare
1022 **
1023 ** Description      Compare two UUID to see if they are the same.
1024 **
1025 ** Returns          TRUE if two uuid match; FALSE otherwise.
1026 **
1027 *******************************************************************************/
gatt_uuid_compare(tBT_UUID src,tBT_UUID tar)1028 BOOLEAN gatt_uuid_compare (tBT_UUID src, tBT_UUID tar)
1029 {
1030     UINT8  su[LEN_UUID_128], tu[LEN_UUID_128];
1031     UINT8  *ps, *pt;
1032 
1033     /* any of the UUID is unspecified */
1034     if (src.len == 0 || tar.len == 0)
1035     {
1036         return TRUE;
1037     }
1038 
1039     /* If both are 16-bit, we can do a simple compare */
1040     if (src.len == LEN_UUID_16 && tar.len == LEN_UUID_16)
1041     {
1042         return src.uu.uuid16 == tar.uu.uuid16;
1043     }
1044 
1045     /* If both are 32-bit, we can do a simple compare */
1046     if (src.len == LEN_UUID_32 && tar.len == LEN_UUID_32)
1047     {
1048         return src.uu.uuid32 == tar.uu.uuid32;
1049     }
1050 
1051     /* One or both of the UUIDs is 128-bit */
1052     if (src.len == LEN_UUID_16)
1053     {
1054         /* convert a 16 bits UUID to 128 bits value */
1055         gatt_convert_uuid16_to_uuid128(su, src.uu.uuid16);
1056         ps = su;
1057     }
1058     else if (src.len == LEN_UUID_32)
1059     {
1060         gatt_convert_uuid32_to_uuid128(su, src.uu.uuid32);
1061         ps = su;
1062     }
1063     else
1064         ps = src.uu.uuid128;
1065 
1066     if (tar.len == LEN_UUID_16)
1067     {
1068         /* convert a 16 bits UUID to 128 bits value */
1069         gatt_convert_uuid16_to_uuid128(tu, tar.uu.uuid16);
1070         pt = tu;
1071     }
1072     else if (tar.len == LEN_UUID_32)
1073     {
1074         /* convert a 32 bits UUID to 128 bits value */
1075         gatt_convert_uuid32_to_uuid128(tu, tar.uu.uuid32);
1076         pt = tu;
1077     }
1078     else
1079         pt = tar.uu.uuid128;
1080 
1081     return(memcmp(ps, pt, LEN_UUID_128) == 0);
1082 }
1083 
1084 /*******************************************************************************
1085 **
1086 ** Function         gatt_build_uuid_to_stream
1087 **
1088 ** Description      Add UUID into stream.
1089 **
1090 ** Returns          UUID length.
1091 **
1092 *******************************************************************************/
gatt_build_uuid_to_stream(UINT8 ** p_dst,tBT_UUID uuid)1093 UINT8 gatt_build_uuid_to_stream(UINT8 **p_dst, tBT_UUID uuid)
1094 {
1095     UINT8   *p = *p_dst;
1096     UINT8   len = 0;
1097 
1098     if (uuid.len == LEN_UUID_16)
1099     {
1100         UINT16_TO_STREAM (p, uuid.uu.uuid16);
1101         len = LEN_UUID_16;
1102     }
1103     else if (uuid.len == LEN_UUID_32) /* always convert 32 bits into 128 bits as alwats */
1104     {
1105         gatt_convert_uuid32_to_uuid128(p, uuid.uu.uuid32);
1106         p += LEN_UUID_128;
1107         len = LEN_UUID_128;
1108     }
1109     else if (uuid.len == LEN_UUID_128)
1110     {
1111         ARRAY_TO_STREAM (p, uuid.uu.uuid128, LEN_UUID_128);
1112         len = LEN_UUID_128;
1113     }
1114 
1115     *p_dst = p;
1116     return len;
1117 }
1118 
1119 /*******************************************************************************
1120 **
1121 ** Function         gatt_parse_uuid_from_cmd
1122 **
1123 ** Description      Convert a 128 bits UUID into a 16 bits UUID.
1124 **
1125 ** Returns          TRUE if command sent, otherwise FALSE.
1126 **
1127 *******************************************************************************/
gatt_parse_uuid_from_cmd(tBT_UUID * p_uuid_rec,UINT16 uuid_size,UINT8 ** p_data)1128 BOOLEAN gatt_parse_uuid_from_cmd(tBT_UUID *p_uuid_rec, UINT16 uuid_size, UINT8 **p_data)
1129 {
1130     BOOLEAN is_base_uuid, ret = TRUE;
1131     UINT8  xx;
1132     UINT8 *p_uuid = *p_data;
1133 
1134     memset(p_uuid_rec, 0, sizeof(tBT_UUID));
1135 
1136     switch (uuid_size)
1137     {
1138         case LEN_UUID_16:
1139             p_uuid_rec->len = uuid_size;
1140             STREAM_TO_UINT16 (p_uuid_rec->uu.uuid16, p_uuid);
1141             *p_data += LEN_UUID_16;
1142             break;
1143 
1144         case LEN_UUID_128:
1145             /* See if we can compress his UUID down to 16 or 32bit UUIDs */
1146             is_base_uuid = TRUE;
1147             for (xx = 0; xx < LEN_UUID_128 - 4; xx++)
1148             {
1149                 if (p_uuid[xx] != base_uuid[xx])
1150                 {
1151                     is_base_uuid = FALSE;
1152                     break;
1153                 }
1154             }
1155             if (is_base_uuid)
1156             {
1157                 if ((p_uuid[LEN_UUID_128 - 1] == 0) && (p_uuid[LEN_UUID_128 - 2] == 0))
1158                 {
1159                     p_uuid += (LEN_UUID_128 - 4);
1160                     p_uuid_rec->len = LEN_UUID_16;
1161                     STREAM_TO_UINT16(p_uuid_rec->uu.uuid16, p_uuid);
1162                 }
1163                 else
1164                 {
1165                     p_uuid += (LEN_UUID_128 - LEN_UUID_32);
1166                     p_uuid_rec->len = LEN_UUID_32;
1167                     STREAM_TO_UINT32(p_uuid_rec->uu.uuid32, p_uuid);
1168                 }
1169             }
1170             if (!is_base_uuid)
1171             {
1172                 p_uuid_rec->len = LEN_UUID_128;
1173                 memcpy(p_uuid_rec->uu.uuid128, p_uuid, LEN_UUID_128);
1174             }
1175             *p_data += LEN_UUID_128;
1176             break;
1177 
1178         /* do not allow 32 bits UUID in ATT PDU now */
1179         case LEN_UUID_32:
1180             GATT_TRACE_ERROR("DO NOT ALLOW 32 BITS UUID IN ATT PDU");
1181         case 0:
1182         default:
1183             if (uuid_size != 0) ret = FALSE;
1184             GATT_TRACE_WARNING("gatt_parse_uuid_from_cmd invalid uuid size");
1185             break;
1186     }
1187 
1188     return( ret);
1189 }
1190 
1191 /*******************************************************************************
1192 **
1193 ** Function         gatt_start_rsp_timer
1194 **
1195 ** Description      Start a wait_for_response timer.
1196 **
1197 ** Returns          void
1198 **
1199 *******************************************************************************/
gatt_start_rsp_timer(UINT16 clcb_idx)1200 void gatt_start_rsp_timer(UINT16 clcb_idx)
1201 {
1202     tGATT_CLCB *p_clcb = &gatt_cb.clcb[clcb_idx];
1203     period_ms_t timeout_ms = GATT_WAIT_FOR_RSP_TIMEOUT_MS;
1204 
1205     if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY &&
1206         p_clcb->op_subtype == GATT_DISC_SRVC_ALL) {
1207         timeout_ms = GATT_WAIT_FOR_DISC_RSP_TIMEOUT_MS;
1208     }
1209 
1210     // TODO: The tGATT_CLCB memory and state management needs cleanup,
1211     // and then the timers can be allocated elsewhere.
1212     if (p_clcb->gatt_rsp_timer_ent == NULL) {
1213         p_clcb->gatt_rsp_timer_ent = alarm_new("gatt.gatt_rsp_timer_ent");
1214     }
1215     alarm_set_on_queue(p_clcb->gatt_rsp_timer_ent, timeout_ms,
1216                        gatt_rsp_timeout, p_clcb, btu_general_alarm_queue);
1217 }
1218 
1219 /*******************************************************************************
1220 **
1221 ** Function         gatt_start_conf_timer
1222 **
1223 ** Description      Start a wait_for_confirmation timer.
1224 **
1225 ** Returns          void
1226 **
1227 *******************************************************************************/
gatt_start_conf_timer(tGATT_TCB * p_tcb)1228 void gatt_start_conf_timer(tGATT_TCB *p_tcb)
1229 {
1230     alarm_set_on_queue(p_tcb->conf_timer, GATT_WAIT_FOR_RSP_TIMEOUT_MS,
1231                        gatt_indication_confirmation_timeout, p_tcb,
1232                        btu_general_alarm_queue);
1233 }
1234 
1235 /*******************************************************************************
1236 **
1237 ** Function         gatt_start_ind_ack_timer
1238 **
1239 ** Description      start the application ack timer
1240 **
1241 ** Returns          void
1242 **
1243 *******************************************************************************/
gatt_start_ind_ack_timer(tGATT_TCB * p_tcb)1244 void gatt_start_ind_ack_timer(tGATT_TCB *p_tcb)
1245 {
1246     /* start notification cache timer */
1247     alarm_set_on_queue(p_tcb->ind_ack_timer, GATT_WAIT_FOR_RSP_TIMEOUT_MS,
1248                        gatt_ind_ack_timeout, p_tcb, btu_general_alarm_queue);
1249 }
1250 
1251 /*******************************************************************************
1252 **
1253 ** Function         gatt_rsp_timeout
1254 **
1255 ** Description      Called when GATT wait for ATT command response timer expires
1256 **
1257 ** Returns          void
1258 **
1259 *******************************************************************************/
gatt_rsp_timeout(void * data)1260 void gatt_rsp_timeout(void *data)
1261 {
1262     tGATT_CLCB *p_clcb = (tGATT_CLCB *)data;
1263 
1264     if (p_clcb == NULL || p_clcb->p_tcb == NULL)
1265     {
1266         GATT_TRACE_WARNING("%s clcb is already deleted", __func__);
1267         return;
1268     }
1269     if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY &&
1270         p_clcb->op_subtype == GATT_DISC_SRVC_ALL &&
1271         p_clcb->retry_count < GATT_REQ_RETRY_LIMIT)
1272     {
1273         UINT8 rsp_code;
1274         GATT_TRACE_WARNING("%s retry discovery primary service", __func__);
1275         if (p_clcb != gatt_cmd_dequeue(p_clcb->p_tcb, &rsp_code))
1276         {
1277             GATT_TRACE_ERROR("%s command queue out of sync, disconnect",
1278                              __func__);
1279         }
1280         else
1281         {
1282             p_clcb->retry_count++;
1283             gatt_act_discovery(p_clcb);
1284             return;
1285         }
1286     }
1287 
1288     GATT_TRACE_WARNING("%s disconnecting...", __func__);
1289     gatt_disconnect (p_clcb->p_tcb);
1290 }
1291 
1292 /*******************************************************************************
1293 **
1294 ** Function         gatt_indication_confirmation_timeout
1295 **
1296 ** Description      Called when the indication confirmation timer expires
1297 **
1298 ** Returns          void
1299 **
1300 *******************************************************************************/
gatt_indication_confirmation_timeout(void * data)1301 void gatt_indication_confirmation_timeout(void *data)
1302 {
1303     tGATT_TCB *p_tcb = (tGATT_TCB *)data;
1304 
1305     GATT_TRACE_WARNING("%s disconnecting...", __func__);
1306     gatt_disconnect(p_tcb);
1307 }
1308 
1309 /*******************************************************************************
1310 **
1311 ** Function         gatt_ind_ack_timeout
1312 **
1313 ** Description      Called when GATT wait for ATT handle confirmation timeout
1314 **
1315 ** Returns          void
1316 **
1317 *******************************************************************************/
gatt_ind_ack_timeout(void * data)1318 void gatt_ind_ack_timeout(void *data)
1319 {
1320     tGATT_TCB *p_tcb = (tGATT_TCB *)data;
1321 
1322     GATT_TRACE_WARNING("%s send ack now", __func__);
1323 
1324     if (p_tcb != NULL)
1325         p_tcb->ind_count = 0;
1326 
1327     attp_send_cl_msg(p_tcb, 0, GATT_HANDLE_VALUE_CONF, NULL);
1328 }
1329 /*******************************************************************************
1330 **
1331 ** Function         gatt_sr_find_i_rcb_by_handle
1332 **
1333 ** Description      The function searches for a service that owns a specific handle.
1334 **
1335 ** Returns          GATT_MAX_SR_PROFILES if not found. Otherwise index of th eservice.
1336 **
1337 *******************************************************************************/
gatt_sr_find_i_rcb_by_handle(UINT16 handle)1338 UINT8 gatt_sr_find_i_rcb_by_handle(UINT16 handle)
1339 {
1340     UINT8  i_rcb = 0;
1341 
1342     for ( ; i_rcb < GATT_MAX_SR_PROFILES; i_rcb++)
1343     {
1344         if (gatt_cb.sr_reg[i_rcb].in_use &&
1345             gatt_cb.sr_reg[i_rcb].s_hdl <= handle &&
1346             gatt_cb.sr_reg[i_rcb].e_hdl >= handle )
1347         {
1348             break;
1349         }
1350     }
1351     return i_rcb;
1352 }
1353 
1354 /*******************************************************************************
1355 **
1356 ** Function         gatt_sr_find_i_rcb_by_handle
1357 **
1358 ** Description      The function searches for a service that owns a specific handle.
1359 **
1360 ** Returns          0 if not found. Otherwise index of th eservice.
1361 **
1362 *******************************************************************************/
gatt_sr_find_i_rcb_by_app_id(tBT_UUID * p_app_uuid128,tBT_UUID * p_svc_uuid,UINT16 svc_inst)1363 UINT8 gatt_sr_find_i_rcb_by_app_id(tBT_UUID *p_app_uuid128, tBT_UUID *p_svc_uuid, UINT16 svc_inst)
1364 {
1365     UINT8           i_rcb = 0;
1366     tGATT_SR_REG    *p_sreg;
1367     tBT_UUID        *p_this_uuid;
1368 
1369     for (i_rcb = 0, p_sreg = gatt_cb.sr_reg; i_rcb < GATT_MAX_SR_PROFILES; i_rcb++, p_sreg++)
1370     {
1371         if ( p_sreg->in_use )
1372         {
1373             p_this_uuid = gatts_get_service_uuid (p_sreg->p_db);
1374 
1375             if (p_this_uuid &&
1376                 gatt_uuid_compare (*p_app_uuid128, p_sreg->app_uuid ) &&
1377                 gatt_uuid_compare (*p_svc_uuid, *p_this_uuid) &&
1378                 (svc_inst == p_sreg->service_instance))
1379             {
1380                 GATT_TRACE_ERROR ("Active Service Found ");
1381                 gatt_dbg_display_uuid(*p_svc_uuid);
1382 
1383                 break;
1384             }
1385         }
1386     }
1387     return i_rcb;
1388 }
1389 /*******************************************************************************
1390 **
1391 ** Function         gatt_sr_find_i_rcb_by_handle
1392 **
1393 ** Description      The function searches for a service that owns a specific handle.
1394 **
1395 ** Returns          0 if not found. Otherwise index of th eservice.
1396 **
1397 *******************************************************************************/
gatt_sr_alloc_rcb(tGATT_HDL_LIST_ELEM * p_list)1398 UINT8 gatt_sr_alloc_rcb(tGATT_HDL_LIST_ELEM *p_list )
1399 {
1400     UINT8   ii = 0;
1401     tGATT_SR_REG    *p_sreg = NULL;
1402 
1403     /*this is a new application servoce start */
1404     for (ii = 0, p_sreg = gatt_cb.sr_reg; ii < GATT_MAX_SR_PROFILES; ii++, p_sreg++)
1405     {
1406         if (!p_sreg->in_use)
1407         {
1408             memset (p_sreg, 0, sizeof(tGATT_SR_REG));
1409 
1410             p_sreg->in_use = TRUE;
1411             memcpy (&p_sreg->app_uuid, &p_list->asgn_range.app_uuid128, sizeof(tBT_UUID));
1412 
1413             p_sreg->service_instance    = p_list->asgn_range.svc_inst;
1414             p_sreg->type                = p_list->asgn_range.is_primary ? GATT_UUID_PRI_SERVICE: GATT_UUID_SEC_SERVICE;
1415             p_sreg->s_hdl               = p_list->asgn_range.s_handle;
1416             p_sreg->e_hdl               = p_list->asgn_range.e_handle;
1417             p_sreg->p_db                = &p_list->svc_db;
1418 
1419             GATT_TRACE_DEBUG("total buffer in db [%d]",
1420                              fixed_queue_length(p_sreg->p_db->svc_buffer));
1421             break;
1422         }
1423     }
1424 
1425     return ii;
1426 }
1427 /*******************************************************************************
1428 **
1429 ** Function         gatt_sr_get_sec_info
1430 **
1431 ** Description      Get the security flag and key size information for the peer
1432 **                  device.
1433 **
1434 ** Returns          void
1435 **
1436 *******************************************************************************/
gatt_sr_get_sec_info(BD_ADDR rem_bda,tBT_TRANSPORT transport,UINT8 * p_sec_flag,UINT8 * p_key_size)1437 void gatt_sr_get_sec_info(BD_ADDR rem_bda, tBT_TRANSPORT transport, UINT8 *p_sec_flag, UINT8 *p_key_size)
1438 {
1439     UINT8           sec_flag = 0;
1440 
1441     BTM_GetSecurityFlagsByTransport(rem_bda, &sec_flag, transport);
1442 
1443     sec_flag &= (GATT_SEC_FLAG_LKEY_UNAUTHED | GATT_SEC_FLAG_LKEY_AUTHED | GATT_SEC_FLAG_ENCRYPTED);
1444 
1445     *p_key_size = btm_ble_read_sec_key_size(rem_bda);
1446     *p_sec_flag = sec_flag;
1447 }
1448 /*******************************************************************************
1449 **
1450 ** Function         gatt_sr_send_req_callback
1451 **
1452 ** Description
1453 **
1454 **
1455 ** Returns          void
1456 **
1457 *******************************************************************************/
gatt_sr_send_req_callback(UINT16 conn_id,UINT32 trans_id,tGATTS_REQ_TYPE type,tGATTS_DATA * p_data)1458 void gatt_sr_send_req_callback(UINT16 conn_id,
1459                                UINT32 trans_id,
1460                                tGATTS_REQ_TYPE type, tGATTS_DATA *p_data)
1461 {
1462     tGATT_IF        gatt_if = GATT_GET_GATT_IF(conn_id);
1463     tGATT_REG       *p_reg = gatt_get_regcb(gatt_if);
1464 
1465     if (!p_reg )
1466     {
1467         GATT_TRACE_ERROR ("p_reg not found discard request");
1468         return;
1469     }
1470 
1471     if ( p_reg->in_use &&
1472          p_reg->app_cb.p_req_cb)
1473     {
1474         (*p_reg->app_cb.p_req_cb)(conn_id, trans_id, type, p_data);
1475     }
1476     else
1477     {
1478         GATT_TRACE_WARNING("Call back not found for application conn_id=%d", conn_id);
1479     }
1480 
1481 }
1482 
1483 /*******************************************************************************
1484 **
1485 ** Function         gatt_send_error_rsp
1486 **
1487 ** Description      This function sends an error response.
1488 **
1489 ** Returns          void
1490 **
1491 *******************************************************************************/
gatt_send_error_rsp(tGATT_TCB * p_tcb,UINT8 err_code,UINT8 op_code,UINT16 handle,BOOLEAN deq)1492 tGATT_STATUS gatt_send_error_rsp (tGATT_TCB *p_tcb, UINT8 err_code, UINT8 op_code,
1493                                   UINT16 handle, BOOLEAN deq)
1494 {
1495     tGATT_ERROR      error;
1496     tGATT_STATUS     status;
1497     BT_HDR           *p_buf;
1498 
1499     error.cmd_code = op_code;
1500     error.reason = err_code;
1501     error.handle =handle;
1502 
1503     if ((p_buf = attp_build_sr_msg(p_tcb, GATT_RSP_ERROR, (tGATT_SR_MSG *)&error)) != NULL)
1504     {
1505         status = attp_send_sr_msg (p_tcb, p_buf);
1506     }
1507     else
1508         status = GATT_INSUF_RESOURCE;
1509 
1510     if (deq)
1511         gatt_dequeue_sr_cmd(p_tcb);
1512 
1513     return status;
1514 }
1515 
1516 
1517 /*******************************************************************************
1518 **
1519 ** Function         gatt_add_sdp_record
1520 **
1521 ** Description      This function add a SDP record for a GATT primary service
1522 **
1523 ** Returns          0 if error else sdp handle for the record.
1524 **
1525 *******************************************************************************/
gatt_add_sdp_record(tBT_UUID * p_uuid,UINT16 start_hdl,UINT16 end_hdl)1526 UINT32 gatt_add_sdp_record (tBT_UUID *p_uuid, UINT16 start_hdl, UINT16 end_hdl)
1527 {
1528     tSDP_PROTOCOL_ELEM  proto_elem_list[2];
1529     UINT32              sdp_handle;
1530     UINT16              list = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
1531     UINT8               buff[60];
1532     UINT8               *p = buff;
1533 
1534     GATT_TRACE_DEBUG("gatt_add_sdp_record s_hdl=0x%x  s_hdl=0x%x",start_hdl, end_hdl);
1535 
1536     if ((sdp_handle = SDP_CreateRecord()) == 0)
1537         return 0;
1538 
1539     switch (p_uuid->len)
1540     {
1541         case LEN_UUID_16:
1542             SDP_AddServiceClassIdList(sdp_handle, 1, &p_uuid->uu.uuid16);
1543             break;
1544 
1545         case LEN_UUID_32:
1546             UINT8_TO_BE_STREAM (p, (UUID_DESC_TYPE << 3) | SIZE_FOUR_BYTES);
1547             UINT32_TO_BE_STREAM (p, p_uuid->uu.uuid32);
1548             SDP_AddAttribute (sdp_handle, ATTR_ID_SERVICE_CLASS_ID_LIST, DATA_ELE_SEQ_DESC_TYPE,
1549                               (UINT32) (p - buff), buff);
1550             break;
1551 
1552         case LEN_UUID_128:
1553             UINT8_TO_BE_STREAM (p, (UUID_DESC_TYPE << 3) | SIZE_SIXTEEN_BYTES);
1554             ARRAY_TO_BE_STREAM_REVERSE (p, p_uuid->uu.uuid128, LEN_UUID_128);
1555             SDP_AddAttribute (sdp_handle, ATTR_ID_SERVICE_CLASS_ID_LIST, DATA_ELE_SEQ_DESC_TYPE,
1556                               (UINT32) (p - buff), buff);
1557             break;
1558 
1559         default:
1560             GATT_TRACE_ERROR("inavlid UUID len=%d", p_uuid->len);
1561             SDP_DeleteRecord(sdp_handle);
1562             return 0;
1563             break;
1564     }
1565 
1566     /*** Fill out the protocol element sequence for SDP ***/
1567     proto_elem_list[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
1568     proto_elem_list[0].num_params    = 1;
1569     proto_elem_list[0].params[0]     = BT_PSM_ATT;
1570     proto_elem_list[1].protocol_uuid = UUID_PROTOCOL_ATT;
1571     proto_elem_list[1].num_params    = 2;
1572     proto_elem_list[1].params[0]     = start_hdl;
1573     proto_elem_list[1].params[1]     = end_hdl;
1574 
1575     SDP_AddProtocolList(sdp_handle, 2, proto_elem_list);
1576 
1577     /* Make the service browseable */
1578     SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &list);
1579 
1580     return(sdp_handle);
1581 }
1582 
1583 
1584     #if GATT_CONFORMANCE_TESTING == TRUE
1585 /*******************************************************************************
1586 **
1587 ** Function         gatt_set_err_rsp
1588 **
1589 ** Description      This function is called to set the test confirm value
1590 **
1591 ** Returns          void
1592 **
1593 *******************************************************************************/
gatt_set_err_rsp(BOOLEAN enable,UINT8 req_op_code,UINT8 err_status)1594 void gatt_set_err_rsp(BOOLEAN enable, UINT8 req_op_code, UINT8 err_status)
1595 {
1596     GATT_TRACE_DEBUG("gatt_set_err_rsp enable=%d op_code=%d, err_status=%d", enable, req_op_code, err_status);
1597     gatt_cb.enable_err_rsp  = enable;
1598     gatt_cb.req_op_code     = req_op_code;
1599     gatt_cb.err_status      = err_status;
1600 }
1601     #endif
1602 
1603 
1604 
1605 /*******************************************************************************
1606 **
1607 ** Function         gatt_get_regcb
1608 **
1609 ** Description      The function returns the registration control block.
1610 **
1611 ** Returns          pointer to the registration control block or NULL
1612 **
1613 *******************************************************************************/
gatt_get_regcb(tGATT_IF gatt_if)1614 tGATT_REG *gatt_get_regcb (tGATT_IF gatt_if)
1615 {
1616     UINT8           ii = (UINT8)gatt_if;
1617     tGATT_REG       *p_reg = NULL;
1618 
1619     if (ii < 1 || ii > GATT_MAX_APPS) {
1620         GATT_TRACE_WARNING("gatt_if out of range [ = %d]", ii);
1621         return NULL;
1622     }
1623 
1624     // Index for cl_rcb is always 1 less than gatt_if.
1625     p_reg = &gatt_cb.cl_rcb[ii - 1];
1626 
1627     if (!p_reg->in_use) {
1628         GATT_TRACE_WARNING("gatt_if found but not in use.");
1629         return NULL;
1630     }
1631 
1632     return p_reg;
1633 }
1634 
1635 
1636 /*******************************************************************************
1637 **
1638 ** Function         gatt_is_clcb_allocated
1639 **
1640 ** Description      The function check clcb for conn_id is allocated or not
1641 **
1642 ** Returns           True already allocated
1643 **
1644 *******************************************************************************/
1645 
gatt_is_clcb_allocated(UINT16 conn_id)1646 BOOLEAN gatt_is_clcb_allocated (UINT16 conn_id)
1647 {
1648     UINT8         i = 0;
1649     BOOLEAN       is_allocated= FALSE;
1650 
1651     for (i = 0; i < GATT_CL_MAX_LCB; i++)
1652     {
1653         if (gatt_cb.clcb[i].in_use && (gatt_cb.clcb[i].conn_id == conn_id))
1654         {
1655             is_allocated = TRUE;
1656             break;
1657         }
1658     }
1659 
1660     return is_allocated;
1661 }
1662 
1663 /*******************************************************************************
1664 **
1665 ** Function         gatt_clcb_alloc
1666 **
1667 ** Description      The function allocates a GATT  connection link control block
1668 **
1669 ** Returns           NULL if not found. Otherwise pointer to the connection link block.
1670 **
1671 *******************************************************************************/
gatt_clcb_alloc(UINT16 conn_id)1672 tGATT_CLCB *gatt_clcb_alloc (UINT16 conn_id)
1673 {
1674     UINT8           i = 0;
1675     tGATT_CLCB      *p_clcb = NULL;
1676     tGATT_IF        gatt_if=GATT_GET_GATT_IF(conn_id);
1677     UINT8           tcb_idx = GATT_GET_TCB_IDX(conn_id);
1678     tGATT_TCB       *p_tcb = gatt_get_tcb_by_idx(tcb_idx);
1679     tGATT_REG       *p_reg = gatt_get_regcb(gatt_if);
1680 
1681     for (i = 0; i < GATT_CL_MAX_LCB; i++)
1682     {
1683         if (!gatt_cb.clcb[i].in_use)
1684         {
1685             p_clcb = &gatt_cb.clcb[i];
1686 
1687             p_clcb->in_use      = TRUE;
1688             p_clcb->conn_id     = conn_id;
1689             p_clcb->clcb_idx    = i;
1690             p_clcb->p_reg       = p_reg;
1691             p_clcb->p_tcb       = p_tcb;
1692             break;
1693         }
1694     }
1695     return p_clcb;
1696 }
1697 
1698 /*******************************************************************************
1699 **
1700 ** Function         gatt_clcb_dealloc
1701 **
1702 ** Description      The function de allocates a GATT  connection link control block
1703 **
1704 ** Returns         None
1705 **
1706 *******************************************************************************/
gatt_clcb_dealloc(tGATT_CLCB * p_clcb)1707 void gatt_clcb_dealloc (tGATT_CLCB *p_clcb)
1708 {
1709     if (p_clcb && p_clcb->in_use)
1710     {
1711         alarm_free(p_clcb->gatt_rsp_timer_ent);
1712         memset(p_clcb, 0, sizeof(tGATT_CLCB));
1713     }
1714 }
1715 
1716 
1717 
1718 /*******************************************************************************
1719 **
1720 ** Function         gatt_find_tcb_by_cid
1721 **
1722 ** Description      The function searches for an empty entry
1723 **                   in registration info table for GATT client
1724 **
1725 ** Returns           NULL if not found. Otherwise pointer to the rcb.
1726 **
1727 *******************************************************************************/
gatt_find_tcb_by_cid(UINT16 lcid)1728 tGATT_TCB * gatt_find_tcb_by_cid (UINT16 lcid)
1729 {
1730     UINT16       xx = 0;
1731     tGATT_TCB    *p_tcb = NULL;
1732 
1733     for (xx = 0; xx < GATT_MAX_PHY_CHANNEL; xx++)
1734     {
1735         if (gatt_cb.tcb[xx].in_use && gatt_cb.tcb[xx].att_lcid == lcid)
1736         {
1737             p_tcb = &gatt_cb.tcb[xx];
1738             break;
1739         }
1740     }
1741     return p_tcb;
1742 }
1743 
1744 
1745 /*******************************************************************************
1746 **
1747 ** Function         gatt_num_apps_hold_link
1748 **
1749 ** Description      The function find the number of applcaitions is holding the link
1750 **
1751 ** Returns          total number of applications holding this acl link.
1752 **
1753 *******************************************************************************/
gatt_num_apps_hold_link(tGATT_TCB * p_tcb)1754 UINT8 gatt_num_apps_hold_link(tGATT_TCB *p_tcb)
1755 {
1756     UINT8 i, num = 0;
1757 
1758     for (i = 0; i < GATT_MAX_APPS; i ++)
1759     {
1760         if (p_tcb->app_hold_link[i])
1761             num ++;
1762     }
1763 
1764     GATT_TRACE_DEBUG("gatt_num_apps_hold_link   num=%d",  num);
1765     return num;
1766 }
1767 
1768 
1769 /*******************************************************************************
1770 **
1771 ** Function         gatt_num_clcb_by_bd_addr
1772 **
1773 ** Description      The function searches all LCB with macthing bd address
1774 **
1775 ** Returns          total number of clcb found.
1776 **
1777 *******************************************************************************/
gatt_num_clcb_by_bd_addr(BD_ADDR bda)1778 UINT8 gatt_num_clcb_by_bd_addr(BD_ADDR bda)
1779 {
1780     UINT8 i, num = 0;
1781 
1782     for (i = 0; i < GATT_CL_MAX_LCB; i ++)
1783     {
1784         if (gatt_cb.clcb[i].in_use && memcmp(gatt_cb.clcb[i].p_tcb->peer_bda, bda, BD_ADDR_LEN) == 0)
1785             num ++;
1786     }
1787     return num;
1788 }
1789 
1790 /*******************************************************************************
1791 **
1792 ** Function         gatt_sr_update_cback_cnt
1793 **
1794 ** Description      The function searches all LCB with macthing bd address
1795 **
1796 ** Returns          total number of clcb found.
1797 **
1798 *******************************************************************************/
gatt_sr_copy_prep_cnt_to_cback_cnt(tGATT_TCB * p_tcb)1799 void gatt_sr_copy_prep_cnt_to_cback_cnt(tGATT_TCB *p_tcb )
1800 {
1801     UINT8 i;
1802 
1803     if (p_tcb)
1804     {
1805         for (i = 0; i < GATT_MAX_APPS; i ++)
1806         {
1807             if (p_tcb->prep_cnt[i])
1808             {
1809                 p_tcb->sr_cmd.cback_cnt[i]=1;
1810             }
1811         }
1812     }
1813 
1814 }
1815 
1816 /*******************************************************************************
1817 **
1818 ** Function         gatt_sr_is_cback_cnt_zero
1819 **
1820 ** Description      The function searches all LCB with macthing bd address
1821 **
1822 ** Returns          True if thetotal application callback count is zero
1823 **
1824 *******************************************************************************/
gatt_sr_is_cback_cnt_zero(tGATT_TCB * p_tcb)1825 BOOLEAN gatt_sr_is_cback_cnt_zero(tGATT_TCB *p_tcb )
1826 {
1827     BOOLEAN status = TRUE;
1828     UINT8   i;
1829 
1830     if (p_tcb)
1831     {
1832         for (i = 0; i < GATT_MAX_APPS; i ++)
1833         {
1834             if (p_tcb->sr_cmd.cback_cnt[i])
1835             {
1836                 status = FALSE;
1837                 break;
1838             }
1839         }
1840     }
1841     else
1842     {
1843         status = FALSE;
1844     }
1845     return status;
1846 }
1847 
1848 /*******************************************************************************
1849 **
1850 ** Function         gatt_sr_is_prep_cnt_zero
1851 **
1852 ** Description      Check the prepare write request count is zero or not
1853 **
1854 ** Returns          True no prepare write request
1855 **
1856 *******************************************************************************/
gatt_sr_is_prep_cnt_zero(tGATT_TCB * p_tcb)1857 BOOLEAN gatt_sr_is_prep_cnt_zero(tGATT_TCB *p_tcb)
1858 {
1859     BOOLEAN status = TRUE;
1860     UINT8   i;
1861 
1862     if (p_tcb)
1863     {
1864         for (i = 0; i < GATT_MAX_APPS; i ++)
1865         {
1866             if (p_tcb->prep_cnt[i])
1867             {
1868                 status = FALSE;
1869                 break;
1870             }
1871         }
1872     }
1873     else
1874     {
1875         status = FALSE;
1876     }
1877     return status;
1878 }
1879 
1880 
1881 /*******************************************************************************
1882 **
1883 ** Function         gatt_sr_reset_cback_cnt
1884 **
1885 ** Description      Reset the application callback count to zero
1886 **
1887 ** Returns         None
1888 **
1889 *******************************************************************************/
gatt_sr_reset_cback_cnt(tGATT_TCB * p_tcb)1890 void gatt_sr_reset_cback_cnt(tGATT_TCB *p_tcb )
1891 {
1892     UINT8 i;
1893 
1894     if (p_tcb)
1895     {
1896         for (i = 0; i < GATT_MAX_APPS; i ++)
1897         {
1898             p_tcb->sr_cmd.cback_cnt[i]=0;
1899         }
1900     }
1901 }
1902 
1903 /*******************************************************************************
1904 **
1905 ** Function         gatt_sr_reset_prep_cnt
1906 **
1907 ** Description     Reset the prep write count to zero
1908 **
1909 ** Returns        None
1910 **
1911 *******************************************************************************/
gatt_sr_reset_prep_cnt(tGATT_TCB * p_tcb)1912 void gatt_sr_reset_prep_cnt(tGATT_TCB *p_tcb )
1913 {
1914     UINT8 i;
1915     if (p_tcb)
1916     {
1917         for (i = 0; i < GATT_MAX_APPS; i ++)
1918         {
1919             p_tcb->prep_cnt[i]=0;
1920         }
1921     }
1922 }
1923 
1924 
1925 /*******************************************************************************
1926 **
1927 ** Function         gatt_sr_update_cback_cnt
1928 **
1929 ** Description    Update the teh applicaiton callback count
1930 **
1931 ** Returns           None
1932 **
1933 *******************************************************************************/
gatt_sr_update_cback_cnt(tGATT_TCB * p_tcb,tGATT_IF gatt_if,BOOLEAN is_inc,BOOLEAN is_reset_first)1934 void gatt_sr_update_cback_cnt(tGATT_TCB *p_tcb, tGATT_IF gatt_if, BOOLEAN is_inc, BOOLEAN is_reset_first)
1935 {
1936 
1937     UINT8 idx = ((UINT8) gatt_if) - 1 ;
1938 
1939     if (p_tcb)
1940     {
1941         if (is_reset_first)
1942         {
1943             gatt_sr_reset_cback_cnt(p_tcb);
1944         }
1945         if (is_inc)
1946         {
1947             p_tcb->sr_cmd.cback_cnt[idx]++;
1948         }
1949         else
1950         {
1951             if ( p_tcb->sr_cmd.cback_cnt[idx])
1952             {
1953                 p_tcb->sr_cmd.cback_cnt[idx]--;
1954             }
1955         }
1956     }
1957 }
1958 
1959 
1960 /*******************************************************************************
1961 **
1962 ** Function         gatt_sr_update_prep_cnt
1963 **
1964 ** Description    Update the teh prepare write request count
1965 **
1966 ** Returns           None
1967 **
1968 *******************************************************************************/
gatt_sr_update_prep_cnt(tGATT_TCB * p_tcb,tGATT_IF gatt_if,BOOLEAN is_inc,BOOLEAN is_reset_first)1969 void gatt_sr_update_prep_cnt(tGATT_TCB *p_tcb, tGATT_IF gatt_if, BOOLEAN is_inc, BOOLEAN is_reset_first)
1970 {
1971     UINT8 idx = ((UINT8) gatt_if) - 1 ;
1972 
1973     GATT_TRACE_DEBUG("gatt_sr_update_prep_cnt tcb idx=%d gatt_if=%d is_inc=%d is_reset_first=%d",
1974                       p_tcb->tcb_idx, gatt_if, is_inc, is_reset_first);
1975 
1976     if (p_tcb)
1977     {
1978         if (is_reset_first)
1979         {
1980             gatt_sr_reset_prep_cnt(p_tcb);
1981         }
1982         if (is_inc)
1983         {
1984             p_tcb->prep_cnt[idx]++;
1985         }
1986         else
1987         {
1988             if (p_tcb->prep_cnt[idx])
1989             {
1990                 p_tcb->prep_cnt[idx]--;
1991             }
1992         }
1993     }
1994 }
1995 /*******************************************************************************
1996 **
1997 ** Function         gatt_cancel_open
1998 **
1999 ** Description      Cancel open request
2000 **
2001 ** Returns         Boolean
2002 **
2003 *******************************************************************************/
gatt_cancel_open(tGATT_IF gatt_if,BD_ADDR bda)2004 BOOLEAN gatt_cancel_open(tGATT_IF gatt_if, BD_ADDR bda)
2005 {
2006     tGATT_TCB *p_tcb=NULL;
2007     BOOLEAN status= TRUE;
2008 
2009     p_tcb = gatt_find_tcb_by_addr(bda, BT_TRANSPORT_LE);
2010 
2011     if (p_tcb)
2012     {
2013         if (gatt_get_ch_state(p_tcb) == GATT_CH_OPEN)
2014         {
2015             GATT_TRACE_ERROR("GATT_CancelConnect - link connected Too late to cancel");
2016             status = FALSE;
2017         }
2018         else
2019         {
2020             gatt_update_app_use_link_flag(gatt_if, p_tcb, FALSE, FALSE);
2021             if (!gatt_num_apps_hold_link(p_tcb))
2022             {
2023                 gatt_disconnect(p_tcb);
2024             }
2025         }
2026     }
2027 
2028     return status;
2029 }
2030 
2031 /*******************************************************************************
2032 **
2033 ** Function         gatt_find_app_hold_link
2034 **
2035 ** Description      find the applicaiton that is holding the specified link
2036 **
2037 ** Returns         Boolean
2038 **
2039 *******************************************************************************/
gatt_find_app_hold_link(tGATT_TCB * p_tcb,UINT8 start_idx,UINT8 * p_found_idx,tGATT_IF * p_gatt_if)2040 BOOLEAN gatt_find_app_hold_link(tGATT_TCB *p_tcb, UINT8 start_idx, UINT8 *p_found_idx, tGATT_IF *p_gatt_if)
2041 {
2042     UINT8 i;
2043     BOOLEAN found= FALSE;
2044 
2045     for (i = start_idx; i < GATT_MAX_APPS; i ++)
2046     {
2047         if (p_tcb->app_hold_link[i])
2048         {
2049             *p_gatt_if = gatt_cb.clcb[i].p_reg->gatt_if;
2050             *p_found_idx = i;
2051             found = TRUE;
2052             break;
2053         }
2054     }
2055     return found;
2056 }
2057 
2058 /*******************************************************************************
2059 **
2060 ** Function         gatt_cmd_enq
2061 **
2062 ** Description      Enqueue this command.
2063 **
2064 ** Returns          None.
2065 **
2066 *******************************************************************************/
gatt_cmd_enq(tGATT_TCB * p_tcb,UINT16 clcb_idx,BOOLEAN to_send,UINT8 op_code,BT_HDR * p_buf)2067 BOOLEAN gatt_cmd_enq(tGATT_TCB *p_tcb, UINT16 clcb_idx, BOOLEAN to_send, UINT8 op_code, BT_HDR *p_buf)
2068 {
2069     tGATT_CMD_Q  *p_cmd = &p_tcb->cl_cmd_q[p_tcb->next_slot_inq];
2070 
2071     p_cmd->to_send = to_send; /* waiting to be sent */
2072     p_cmd->op_code  = op_code;
2073     p_cmd->p_cmd    = p_buf;
2074     p_cmd->clcb_idx = clcb_idx;
2075 
2076     if (!to_send)
2077     {
2078         p_tcb->pending_cl_req = p_tcb->next_slot_inq;
2079     }
2080 
2081     p_tcb->next_slot_inq ++;
2082     p_tcb->next_slot_inq %= GATT_CL_MAX_LCB;
2083 
2084     return TRUE;
2085 }
2086 
2087 /*******************************************************************************
2088 **
2089 ** Function         gatt_cmd_dequeue
2090 **
2091 ** Description      dequeue the command in the client CCB command queue.
2092 **
2093 ** Returns          total number of clcb found.
2094 **
2095 *******************************************************************************/
gatt_cmd_dequeue(tGATT_TCB * p_tcb,UINT8 * p_op_code)2096 tGATT_CLCB * gatt_cmd_dequeue(tGATT_TCB *p_tcb, UINT8 *p_op_code)
2097 {
2098     tGATT_CMD_Q  *p_cmd = &p_tcb->cl_cmd_q[p_tcb->pending_cl_req];
2099     tGATT_CLCB *p_clcb = NULL;
2100 
2101     if (p_tcb->pending_cl_req != p_tcb->next_slot_inq)
2102     {
2103         p_clcb = &gatt_cb.clcb[p_cmd->clcb_idx];
2104 
2105         *p_op_code = p_cmd->op_code;
2106 
2107         p_tcb->pending_cl_req ++;
2108         p_tcb->pending_cl_req %= GATT_CL_MAX_LCB;
2109     }
2110 
2111     return p_clcb;
2112 }
2113 
2114 /*******************************************************************************
2115 **
2116 ** Function         gatt_send_write_msg
2117 **
2118 ** Description      This real function send out the ATT message for write.
2119 **
2120 ** Returns          status code
2121 **
2122 *******************************************************************************/
gatt_send_write_msg(tGATT_TCB * p_tcb,UINT16 clcb_idx,UINT8 op_code,UINT16 handle,UINT16 len,UINT16 offset,UINT8 * p_data)2123 UINT8 gatt_send_write_msg (tGATT_TCB *p_tcb, UINT16 clcb_idx, UINT8 op_code,
2124                            UINT16 handle, UINT16 len,
2125                            UINT16 offset, UINT8 *p_data)
2126 {
2127     tGATT_CL_MSG     msg;
2128 
2129     msg.attr_value.handle = handle;
2130     msg.attr_value.len = len;
2131     msg.attr_value.offset = offset;
2132 
2133     memcpy (msg.attr_value.value, p_data, len);
2134 
2135     /* write by handle */
2136     return attp_send_cl_msg(p_tcb, clcb_idx, op_code, &msg);
2137 }
2138 
2139 /*******************************************************************************
2140 **
2141 ** Function         gatt_act_send_browse
2142 **
2143 ** Description      This function ends a browse command request, including read
2144 **                  information request and read by type request.
2145 **
2146 ** Returns          status code
2147 **
2148 *******************************************************************************/
gatt_act_send_browse(tGATT_TCB * p_tcb,UINT16 index,UINT8 op,UINT16 s_handle,UINT16 e_handle,tBT_UUID uuid)2149 UINT8 gatt_act_send_browse(tGATT_TCB *p_tcb, UINT16 index, UINT8 op, UINT16 s_handle,
2150                            UINT16 e_handle, tBT_UUID uuid)
2151 {
2152     tGATT_CL_MSG     msg;
2153 
2154     msg.browse.s_handle = s_handle;
2155     msg.browse.e_handle   = e_handle;
2156     memcpy(&msg.browse.uuid, &uuid, sizeof(tBT_UUID));
2157 
2158     /* write by handle */
2159     return attp_send_cl_msg(p_tcb, index, op, &msg);
2160 }
2161 
2162 /*******************************************************************************
2163 **
2164 ** Function         gatt_end_operation
2165 **
2166 ** Description      This function ends a discovery, send callback and finalize
2167 **                  some control value.
2168 **
2169 ** Returns          16 bits uuid.
2170 **
2171 *******************************************************************************/
gatt_end_operation(tGATT_CLCB * p_clcb,tGATT_STATUS status,void * p_data)2172 void gatt_end_operation(tGATT_CLCB *p_clcb, tGATT_STATUS status, void *p_data)
2173 {
2174     tGATT_CL_COMPLETE   cb_data;
2175     tGATT_CMPL_CBACK    *p_cmpl_cb = (p_clcb->p_reg) ? p_clcb->p_reg->app_cb.p_cmpl_cb : NULL;
2176     UINT8               op = p_clcb->operation, disc_type=GATT_DISC_MAX;
2177     tGATT_DISC_CMPL_CB  *p_disc_cmpl_cb = (p_clcb->p_reg) ? p_clcb->p_reg->app_cb.p_disc_cmpl_cb : NULL;
2178     UINT16              conn_id;
2179     UINT8               operation;
2180 
2181     GATT_TRACE_DEBUG ("gatt_end_operation status=%d op=%d subtype=%d",
2182                        status, p_clcb->operation, p_clcb->op_subtype);
2183     memset(&cb_data.att_value, 0, sizeof(tGATT_VALUE));
2184 
2185     if (p_cmpl_cb != NULL && p_clcb->operation != 0)
2186     {
2187         if (p_clcb->operation == GATTC_OPTYPE_READ)
2188         {
2189             cb_data.att_value.handle   = p_clcb->s_handle;
2190             cb_data.att_value.len      = p_clcb->counter;
2191 
2192             if (p_data && p_clcb->counter)
2193                 memcpy (cb_data.att_value.value, p_data, cb_data.att_value.len);
2194         }
2195 
2196         if (p_clcb->operation == GATTC_OPTYPE_WRITE)
2197         {
2198             memset(&cb_data.att_value, 0, sizeof(tGATT_VALUE));
2199             cb_data.handle           =
2200             cb_data.att_value.handle = p_clcb->s_handle;
2201             if (p_clcb->op_subtype == GATT_WRITE_PREPARE)
2202             {
2203                 if (p_data)
2204                 {
2205                     cb_data.att_value = *((tGATT_VALUE *) p_data);
2206                 }
2207                 else
2208                 {
2209                     GATT_TRACE_DEBUG("Rcv Prepare write rsp but no data");
2210                 }
2211             }
2212         }
2213 
2214         if (p_clcb->operation == GATTC_OPTYPE_CONFIG)
2215             cb_data.mtu = p_clcb->p_tcb->payload_size;
2216 
2217         if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY)
2218         {
2219             disc_type = p_clcb->op_subtype;
2220         }
2221     }
2222 
2223     osi_free_and_reset((void **)&p_clcb->p_attr_buf);
2224 
2225     operation =  p_clcb->operation;
2226     conn_id = p_clcb->conn_id;
2227     alarm_cancel(p_clcb->gatt_rsp_timer_ent);
2228 
2229     gatt_clcb_dealloc(p_clcb);
2230 
2231     if (p_disc_cmpl_cb && (op == GATTC_OPTYPE_DISCOVERY))
2232         (*p_disc_cmpl_cb)(conn_id, disc_type, status);
2233     else if (p_cmpl_cb && op)
2234         (*p_cmpl_cb)(conn_id, op, status, &cb_data);
2235     else
2236         GATT_TRACE_WARNING ("gatt_end_operation not sent out op=%d p_disc_cmpl_cb:%p p_cmpl_cb:%p",
2237                              operation, p_disc_cmpl_cb, p_cmpl_cb);
2238 }
2239 
2240 /*******************************************************************************
2241 **
2242 ** Function         gatt_cleanup_upon_disc
2243 **
2244 ** Description      This function cleans up the control blocks when L2CAP channel
2245 **                  disconnect.
2246 **
2247 ** Returns          16 bits uuid.
2248 **
2249 *******************************************************************************/
gatt_cleanup_upon_disc(BD_ADDR bda,UINT16 reason,tBT_TRANSPORT transport)2250 void gatt_cleanup_upon_disc(BD_ADDR bda, UINT16 reason, tBT_TRANSPORT transport)
2251 {
2252     tGATT_TCB       *p_tcb = NULL;
2253     tGATT_CLCB      *p_clcb;
2254     UINT8           i;
2255     UINT16          conn_id;
2256     tGATT_REG        *p_reg=NULL;
2257 
2258 
2259     GATT_TRACE_DEBUG ("gatt_cleanup_upon_disc ");
2260 
2261     if ((p_tcb = gatt_find_tcb_by_addr(bda, transport)) != NULL)
2262     {
2263         GATT_TRACE_DEBUG ("found p_tcb ");
2264         gatt_set_ch_state(p_tcb, GATT_CH_CLOSE);
2265         for (i = 0; i < GATT_CL_MAX_LCB; i ++)
2266         {
2267             p_clcb = &gatt_cb.clcb[i];
2268             if (p_clcb->in_use && p_clcb->p_tcb == p_tcb)
2269             {
2270                 alarm_cancel(p_clcb->gatt_rsp_timer_ent);
2271                 GATT_TRACE_DEBUG ("found p_clcb conn_id=%d clcb_idx=%d", p_clcb->conn_id, p_clcb->clcb_idx);
2272                 if (p_clcb->operation != GATTC_OPTYPE_NONE)
2273                     gatt_end_operation(p_clcb, GATT_ERROR, NULL);
2274 
2275                 gatt_clcb_dealloc(p_clcb);
2276 
2277             }
2278         }
2279 
2280         alarm_free(p_tcb->ind_ack_timer);
2281         p_tcb->ind_ack_timer = NULL;
2282         alarm_free(p_tcb->conf_timer);
2283         p_tcb->conf_timer = NULL;
2284         gatt_free_pending_ind(p_tcb);
2285         gatt_free_pending_enc_queue(p_tcb);
2286         fixed_queue_free(p_tcb->sr_cmd.multi_rsp_q, NULL);
2287         p_tcb->sr_cmd.multi_rsp_q = NULL;
2288 
2289         for (i = 0; i < GATT_MAX_APPS; i ++)
2290         {
2291             p_reg = &gatt_cb.cl_rcb[i];
2292             if (p_reg->in_use && p_reg->app_cb.p_conn_cb)
2293             {
2294                 conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if);
2295                 GATT_TRACE_DEBUG ("found p_reg tcb_idx=%d gatt_if=%d  conn_id=0x%x", p_tcb->tcb_idx, p_reg->gatt_if, conn_id);
2296                 (*p_reg->app_cb.p_conn_cb)(p_reg->gatt_if,  bda, conn_id, FALSE, reason, transport);
2297             }
2298         }
2299         memset(p_tcb, 0, sizeof(tGATT_TCB));
2300 
2301     }
2302     GATT_TRACE_DEBUG ("exit gatt_cleanup_upon_disc ");
2303 }
2304 /*******************************************************************************
2305 **
2306 ** Function         gatt_dbg_req_op_name
2307 **
2308 ** Description      Get op code description name, for debug information.
2309 **
2310 ** Returns          UINT8 *: name of the operation.
2311 **
2312 *******************************************************************************/
gatt_dbg_op_name(UINT8 op_code)2313 UINT8 * gatt_dbg_op_name(UINT8 op_code)
2314 {
2315     UINT8 pseduo_op_code_idx = op_code & (~GATT_WRITE_CMD_MASK);
2316 
2317     if (op_code == GATT_CMD_WRITE )
2318     {
2319         pseduo_op_code_idx = 0x14; /* just an index to op_code_name */
2320 
2321     }
2322 
2323     if (op_code == GATT_SIGN_CMD_WRITE)
2324     {
2325         pseduo_op_code_idx = 0x15; /* just an index to op_code_name */
2326     }
2327 
2328     if (pseduo_op_code_idx <= GATT_OP_CODE_MAX)
2329         return(UINT8*) op_code_name[pseduo_op_code_idx];
2330     else
2331         return(UINT8 *)"Op Code Exceed Max";
2332 }
2333 
2334 /*******************************************************************************
2335 **
2336 ** Function         gatt_dbg_display_uuid
2337 **
2338 ** Description      Disaplay the UUID
2339 **
2340 ** Returns          None
2341 **
2342 *******************************************************************************/
gatt_dbg_display_uuid(tBT_UUID bt_uuid)2343 void gatt_dbg_display_uuid(tBT_UUID bt_uuid)
2344 {
2345     char str_buf[50];
2346     int x = 0;
2347 
2348     if (bt_uuid.len == LEN_UUID_16)
2349     {
2350         sprintf(str_buf, "0x%04x", bt_uuid.uu.uuid16);
2351     }
2352     else if (bt_uuid.len == LEN_UUID_32)
2353     {
2354         sprintf(str_buf, "0x%08x", (unsigned int)bt_uuid.uu.uuid32);
2355     }
2356     else if (bt_uuid.len == LEN_UUID_128)
2357     {
2358         x += sprintf(&str_buf[x], "0x%02x%02x%02x%02x%02x%02x%02x%02x",
2359                      bt_uuid.uu.uuid128[15], bt_uuid.uu.uuid128[14],
2360                      bt_uuid.uu.uuid128[13], bt_uuid.uu.uuid128[12],
2361                      bt_uuid.uu.uuid128[11], bt_uuid.uu.uuid128[10],
2362                      bt_uuid.uu.uuid128[9], bt_uuid.uu.uuid128[8]);
2363         sprintf(&str_buf[x], "%02x%02x%02x%02x%02x%02x%02x%02x",
2364                 bt_uuid.uu.uuid128[7], bt_uuid.uu.uuid128[6],
2365                 bt_uuid.uu.uuid128[5], bt_uuid.uu.uuid128[4],
2366                 bt_uuid.uu.uuid128[3], bt_uuid.uu.uuid128[2],
2367                 bt_uuid.uu.uuid128[1], bt_uuid.uu.uuid128[0]);
2368     }
2369     else
2370         strlcpy(str_buf, "Unknown UUID 0", sizeof(str_buf));
2371 
2372     GATT_TRACE_DEBUG ("UUID=[%s]", str_buf);
2373 }
2374 
2375 
2376 /*******************************************************************************
2377 **
2378 ** Function         gatt_is_bg_dev_for_app
2379 **
2380 ** Description      find is this one of the background devices for the application
2381 **
2382 ** Returns          TRUE this is one of the background devices for the  application
2383 **
2384 *******************************************************************************/
gatt_is_bg_dev_for_app(tGATT_BG_CONN_DEV * p_dev,tGATT_IF gatt_if)2385 BOOLEAN gatt_is_bg_dev_for_app(tGATT_BG_CONN_DEV *p_dev, tGATT_IF gatt_if)
2386 {
2387     UINT8   i;
2388 
2389     for (i = 0; i < GATT_MAX_APPS; i ++ )
2390     {
2391         if (p_dev->in_use && (p_dev->gatt_if[i] == gatt_if))
2392         {
2393             return TRUE;
2394         }
2395     }
2396     return FALSE;
2397 }
2398 /*******************************************************************************
2399 **
2400 ** Function         gatt_find_bg_dev
2401 **
2402 ** Description      find background connection device from the list.
2403 **
2404 ** Returns          pointer to the device record
2405 **
2406 *******************************************************************************/
gatt_find_bg_dev(BD_ADDR remote_bda)2407 tGATT_BG_CONN_DEV * gatt_find_bg_dev(BD_ADDR remote_bda)
2408 {
2409     tGATT_BG_CONN_DEV    *p_dev_list = &gatt_cb.bgconn_dev[0];
2410     UINT8   i;
2411 
2412     for (i = 0; i < GATT_MAX_BG_CONN_DEV; i ++, p_dev_list ++)
2413     {
2414         if (p_dev_list->in_use && !memcmp(p_dev_list->remote_bda, remote_bda, BD_ADDR_LEN))
2415         {
2416             return p_dev_list;
2417         }
2418     }
2419     return NULL;
2420 }
2421 /*******************************************************************************
2422 **
2423 ** Function         gatt_alloc_bg_dev
2424 **
2425 ** Description      allocate a background connection device record
2426 **
2427 ** Returns          pointer to the device record
2428 **
2429 *******************************************************************************/
gatt_alloc_bg_dev(BD_ADDR remote_bda)2430 tGATT_BG_CONN_DEV * gatt_alloc_bg_dev(BD_ADDR remote_bda)
2431 {
2432     tGATT_BG_CONN_DEV    *p_dev_list = &gatt_cb.bgconn_dev[0];
2433     UINT8   i;
2434 
2435     for (i = 0; i < GATT_MAX_BG_CONN_DEV; i ++, p_dev_list ++)
2436     {
2437         if (!p_dev_list->in_use)
2438         {
2439             p_dev_list->in_use = TRUE;
2440             memcpy(p_dev_list->remote_bda, remote_bda, BD_ADDR_LEN);
2441 
2442             return p_dev_list;
2443         }
2444     }
2445     return NULL;
2446 }
2447 
2448 /*******************************************************************************
2449 **
2450 ** Function         gatt_add_bg_dev_list
2451 **
2452 ** Description      add/remove device from the back ground connection device list
2453 **
2454 ** Returns          TRUE if device added to the list; FALSE failed
2455 **
2456 *******************************************************************************/
gatt_add_bg_dev_list(tGATT_REG * p_reg,BD_ADDR bd_addr,BOOLEAN is_initator)2457 BOOLEAN gatt_add_bg_dev_list(tGATT_REG *p_reg,  BD_ADDR bd_addr, BOOLEAN is_initator)
2458 {
2459     tGATT_IF gatt_if =  p_reg->gatt_if;
2460     tGATT_BG_CONN_DEV   *p_dev = NULL;
2461     UINT8       i;
2462     BOOLEAN      ret = FALSE;
2463 
2464     if ((p_dev = gatt_find_bg_dev(bd_addr)) == NULL)
2465     {
2466         p_dev = gatt_alloc_bg_dev(bd_addr);
2467     }
2468 
2469     if (p_dev)
2470     {
2471         for (i = 0; i < GATT_MAX_APPS; i ++)
2472         {
2473             if (is_initator)
2474             {
2475                 if (p_dev->gatt_if[i] == gatt_if)
2476                 {
2477                     GATT_TRACE_ERROR("device already in iniator white list");
2478                     return TRUE;
2479                 }
2480                 else if (p_dev->gatt_if[i] == 0)
2481                 {
2482                     p_dev->gatt_if[i] = gatt_if;
2483                     if (i == 0)
2484                         ret = BTM_BleUpdateBgConnDev(TRUE, bd_addr);
2485                     else
2486                         ret = TRUE;
2487                     break;
2488                 }
2489             }
2490             else
2491             {
2492                 if (p_dev->listen_gif[i] == gatt_if)
2493                 {
2494                     GATT_TRACE_ERROR("device already in adv white list");
2495                     return TRUE;
2496                 }
2497                 else if (p_dev->listen_gif[i] == 0)
2498                 {
2499                     if (p_reg->listening == GATT_LISTEN_TO_ALL)
2500                         p_reg->listening = GATT_LISTEN_TO_NONE;
2501 
2502                     p_reg->listening ++;
2503                     p_dev->listen_gif[i] = gatt_if;
2504 
2505                     if (i == 0)
2506                         ret = BTM_BleUpdateAdvWhitelist(TRUE, bd_addr);
2507                     else
2508                         ret = TRUE;
2509                     break;
2510                 }
2511             }
2512         }
2513     }
2514     else
2515     {
2516         GATT_TRACE_ERROR("no device record available");
2517     }
2518 
2519     return ret;
2520 }
2521 
2522 /*******************************************************************************
2523 **
2524 ** Function         gatt_remove_bg_dev_for_app
2525 **
2526 ** Description      Remove the application interface for the specified background device
2527 **
2528 ** Returns          Boolean
2529 **
2530 *******************************************************************************/
gatt_remove_bg_dev_for_app(tGATT_IF gatt_if,BD_ADDR bd_addr)2531 BOOLEAN gatt_remove_bg_dev_for_app(tGATT_IF gatt_if, BD_ADDR bd_addr)
2532 {
2533     tGATT_TCB    *p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE);
2534     BOOLEAN       status;
2535 
2536     if (p_tcb)
2537         gatt_update_app_use_link_flag(gatt_if, p_tcb, FALSE, FALSE);
2538     status = gatt_update_auto_connect_dev(gatt_if, FALSE, bd_addr, TRUE);
2539     return status;
2540 }
2541 
2542 
2543 /*******************************************************************************
2544 **
2545 ** Function         gatt_get_num_apps_for_bg_dev
2546 **
2547 ** Description      Gte the number of applciations for the specified background device
2548 **
2549 ** Returns          UINT8 total number fo applications
2550 **
2551 *******************************************************************************/
gatt_get_num_apps_for_bg_dev(BD_ADDR bd_addr)2552 UINT8 gatt_get_num_apps_for_bg_dev(BD_ADDR bd_addr)
2553 {
2554     tGATT_BG_CONN_DEV   *p_dev = NULL;
2555     UINT8   i;
2556     UINT8   cnt = 0;
2557 
2558     if ((p_dev = gatt_find_bg_dev(bd_addr)) != NULL)
2559     {
2560         for (i = 0; i < GATT_MAX_APPS; i ++)
2561         {
2562             if (p_dev->gatt_if[i])
2563                 cnt++;
2564         }
2565     }
2566     return cnt;
2567 }
2568 
2569 /*******************************************************************************
2570 **
2571 ** Function         gatt_find_app_for_bg_dev
2572 **
2573 ** Description      find the application interface for the specified background device
2574 **
2575 ** Returns          Boolean
2576 **
2577 *******************************************************************************/
gatt_find_app_for_bg_dev(BD_ADDR bd_addr,tGATT_IF * p_gatt_if)2578 BOOLEAN gatt_find_app_for_bg_dev(BD_ADDR bd_addr, tGATT_IF *p_gatt_if)
2579 {
2580     tGATT_BG_CONN_DEV   *p_dev = NULL;
2581     UINT8   i;
2582     BOOLEAN ret = FALSE;
2583 
2584     if ((p_dev = gatt_find_bg_dev(bd_addr)) == NULL)
2585     {
2586         return ret;
2587     }
2588 
2589     for (i = 0; i < GATT_MAX_APPS; i ++)
2590     {
2591         if (p_dev->gatt_if[i] != 0 )
2592         {
2593             *p_gatt_if = p_dev->gatt_if[i];
2594             ret = TRUE;
2595             break;
2596         }
2597     }
2598     return ret;
2599 }
2600 
2601 
2602 /*******************************************************************************
2603 **
2604 ** Function         gatt_remove_bg_dev_from_list
2605 **
2606 ** Description      add/remove device from the back ground connection device list or
2607 **                  listening to advertising list.
2608 **
2609 ** Returns          pointer to the device record
2610 **
2611 *******************************************************************************/
gatt_remove_bg_dev_from_list(tGATT_REG * p_reg,BD_ADDR bd_addr,BOOLEAN is_initiator)2612 BOOLEAN gatt_remove_bg_dev_from_list(tGATT_REG *p_reg, BD_ADDR bd_addr, BOOLEAN is_initiator)
2613 {
2614     tGATT_IF gatt_if = p_reg->gatt_if;
2615     tGATT_BG_CONN_DEV   *p_dev = NULL;
2616     UINT8   i, j;
2617     BOOLEAN ret = FALSE;
2618 
2619     if ((p_dev = gatt_find_bg_dev(bd_addr)) == NULL)
2620     {
2621         return ret;
2622     }
2623 
2624     for (i = 0; i < GATT_MAX_APPS && (p_dev->gatt_if[i] > 0 || p_dev->listen_gif[i]); i ++)
2625     {
2626         if (is_initiator)
2627         {
2628             if (p_dev->gatt_if[i] == gatt_if)
2629             {
2630                 p_dev->gatt_if[i] = 0;
2631                 /* move all element behind one forward */
2632                 for (j = i + 1; j < GATT_MAX_APPS; j ++)
2633                     p_dev->gatt_if[j - 1] = p_dev->gatt_if[j];
2634 
2635                 if (p_dev->gatt_if[0] == 0)
2636                     ret = BTM_BleUpdateBgConnDev(FALSE, p_dev->remote_bda);
2637                 else
2638                     ret = TRUE;
2639 
2640                 break;
2641             }
2642         }
2643         else
2644         {
2645             if (p_dev->listen_gif[i] == gatt_if)
2646             {
2647                 p_dev->listen_gif[i] = 0;
2648                 p_reg->listening --;
2649                 /* move all element behind one forward */
2650                 for (j = i + 1; j < GATT_MAX_APPS; j ++)
2651                     p_dev->listen_gif[j - 1] = p_dev->listen_gif[j];
2652 
2653                 if (p_dev->listen_gif[0] == 0)
2654                     ret = BTM_BleUpdateAdvWhitelist(FALSE, p_dev->remote_bda);
2655                 else
2656                     ret = TRUE;
2657                 break;
2658             }
2659         }
2660     }
2661 
2662     if (i != GATT_MAX_APPS && p_dev->gatt_if[0] == 0 && p_dev->listen_gif[0] == 0)
2663     {
2664         memset(p_dev, 0, sizeof(tGATT_BG_CONN_DEV));
2665     }
2666 
2667     return ret;
2668 }
2669 /*******************************************************************************
2670 **
2671 ** Function         gatt_deregister_bgdev_list
2672 **
2673 ** Description      deregister all related back ground connetion device.
2674 **
2675 ** Returns          pointer to the device record
2676 **
2677 *******************************************************************************/
gatt_deregister_bgdev_list(tGATT_IF gatt_if)2678 void gatt_deregister_bgdev_list(tGATT_IF gatt_if)
2679 {
2680     tGATT_BG_CONN_DEV    *p_dev_list = &gatt_cb.bgconn_dev[0];
2681     UINT8 i , j, k;
2682     tGATT_REG       *p_reg = gatt_get_regcb(gatt_if);
2683 
2684     /* update the BG conn device list */
2685     for (i = 0 ; i <GATT_MAX_BG_CONN_DEV; i ++, p_dev_list ++ )
2686     {
2687         if (p_dev_list->in_use)
2688         {
2689             for (j = 0; j < GATT_MAX_APPS; j ++)
2690             {
2691                 if (p_dev_list->gatt_if[j] == 0 && p_dev_list->listen_gif[j] == 0)
2692                     break;
2693 
2694                 if (p_dev_list->gatt_if[j] == gatt_if)
2695                 {
2696                     for (k = j + 1; k < GATT_MAX_APPS; k ++)
2697                         p_dev_list->gatt_if[k - 1] = p_dev_list->gatt_if[k];
2698 
2699                     if (p_dev_list->gatt_if[0] == 0)
2700                         BTM_BleUpdateBgConnDev(FALSE, p_dev_list->remote_bda);
2701                 }
2702 
2703                 if (p_dev_list->listen_gif[j] == gatt_if)
2704                 {
2705                     p_dev_list->listen_gif[j] = 0;
2706 
2707                     if (p_reg != NULL && p_reg->listening > 0)
2708                         p_reg->listening --;
2709 
2710                     /* move all element behind one forward */
2711                     for (k = j + 1; k < GATT_MAX_APPS; k ++)
2712                         p_dev_list->listen_gif[k - 1] = p_dev_list->listen_gif[k];
2713 
2714                     if (p_dev_list->listen_gif[0] == 0)
2715                         BTM_BleUpdateAdvWhitelist(FALSE, p_dev_list->remote_bda);
2716                 }
2717             }
2718         }
2719     }
2720 }
2721 
2722 
2723 /*******************************************************************************
2724 **
2725 ** Function         gatt_reset_bgdev_list
2726 **
2727 ** Description      reset bg device list
2728 **
2729 ** Returns          pointer to the device record
2730 **
2731 *******************************************************************************/
gatt_reset_bgdev_list(void)2732 void gatt_reset_bgdev_list(void)
2733 {
2734     memset(&gatt_cb.bgconn_dev, 0 , sizeof(tGATT_BG_CONN_DEV)*GATT_MAX_BG_CONN_DEV);
2735 
2736 }
2737 /*******************************************************************************
2738 **
2739 ** Function         gatt_update_auto_connect_dev
2740 **
2741 ** Description      This function add or remove a device for background connection
2742 **                  procedure.
2743 **
2744 ** Parameters       gatt_if: Application ID.
2745 **                  add: add peer device
2746 **                  bd_addr: peer device address.
2747 **
2748 ** Returns          TRUE if connection started; FALSE if connection start failure.
2749 **
2750 *******************************************************************************/
gatt_update_auto_connect_dev(tGATT_IF gatt_if,BOOLEAN add,BD_ADDR bd_addr,BOOLEAN is_initator)2751 BOOLEAN gatt_update_auto_connect_dev (tGATT_IF gatt_if, BOOLEAN add, BD_ADDR bd_addr, BOOLEAN is_initator)
2752 {
2753     BOOLEAN         ret = FALSE;
2754     tGATT_REG        *p_reg;
2755     tGATT_TCB       *p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE);
2756 
2757     GATT_TRACE_API ("gatt_update_auto_connect_dev ");
2758     /* Make sure app is registered */
2759     if ((p_reg = gatt_get_regcb(gatt_if)) == NULL)
2760     {
2761         GATT_TRACE_ERROR("gatt_update_auto_connect_dev - gatt_if is not registered", gatt_if);
2762         return(FALSE);
2763     }
2764 
2765     if (add)
2766     {
2767         ret = gatt_add_bg_dev_list(p_reg, bd_addr, is_initator);
2768 
2769         if (ret && p_tcb != NULL)
2770         {
2771             /* if a connected device, update the link holding number */
2772             gatt_update_app_use_link_flag(gatt_if, p_tcb, TRUE, TRUE);
2773         }
2774     }
2775     else
2776     {
2777         ret = gatt_remove_bg_dev_from_list(p_reg, bd_addr, is_initator);
2778     }
2779     return ret;
2780 }
2781 
2782 
2783 
2784 /*******************************************************************************
2785 **
2786 ** Function     gatt_add_pending_new_srv_start
2787 **
2788 ** Description  Add a pending new srv start to the new service start queue
2789 **
2790 ** Returns    Pointer to the new service start buffer, NULL no buffer available
2791 **
2792 *******************************************************************************/
gatt_add_pending_enc_channel_clcb(tGATT_TCB * p_tcb,tGATT_CLCB * p_clcb)2793 tGATT_PENDING_ENC_CLCB* gatt_add_pending_enc_channel_clcb(tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb)
2794 {
2795     tGATT_PENDING_ENC_CLCB *p_buf =
2796         (tGATT_PENDING_ENC_CLCB *)osi_malloc(sizeof(tGATT_PENDING_ENC_CLCB));
2797 
2798     GATT_TRACE_DEBUG ("%s", __func__);
2799     GATT_TRACE_DEBUG("enqueue a new pending encryption channel clcb");
2800 
2801     p_buf->p_clcb = p_clcb;
2802     fixed_queue_enqueue(p_tcb->pending_enc_clcb, p_buf);
2803 
2804     return p_buf;
2805 }
2806 /*******************************************************************************
2807 **
2808 ** Function     gatt_update_listen_mode
2809 **
2810 ** Description  update peripheral role listening mode
2811 **
2812 ** Returns    Pointer to the new service start buffer, NULL no buffer available
2813 **
2814 *******************************************************************************/
gatt_update_listen_mode(void)2815 BOOLEAN gatt_update_listen_mode(void)
2816 {
2817     UINT8           ii = 0;
2818     tGATT_REG       *p_reg = &gatt_cb.cl_rcb[0];
2819     UINT8           listening = 0;
2820     UINT16          connectability, window, interval;
2821     BOOLEAN         rt = TRUE;
2822 
2823     for (; ii < GATT_MAX_APPS; ii ++, p_reg ++)
2824     {
2825         if ( p_reg->in_use && p_reg->listening > listening)
2826         {
2827             listening = p_reg->listening;
2828         }
2829     }
2830 
2831     if (listening == GATT_LISTEN_TO_ALL ||
2832         listening == GATT_LISTEN_TO_NONE)
2833         BTM_BleUpdateAdvFilterPolicy (AP_SCAN_CONN_ALL);
2834     else
2835         BTM_BleUpdateAdvFilterPolicy (AP_SCAN_CONN_WL);
2836 
2837     if (rt)
2838     {
2839         connectability = BTM_ReadConnectability (&window, &interval);
2840 
2841         if (listening != GATT_LISTEN_TO_NONE)
2842         {
2843             connectability |= BTM_BLE_CONNECTABLE;
2844         }
2845         else
2846         {
2847             if ((connectability & BTM_BLE_CONNECTABLE) == 0)
2848             connectability &= ~BTM_BLE_CONNECTABLE;
2849         }
2850         /* turning on the adv now */
2851         btm_ble_set_connectability(connectability);
2852     }
2853 
2854     return rt;
2855 
2856 }
2857 #endif
2858 
2859 
2860