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