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