OSDN Git Service

am 1e1f1598: Merge "[DS] BTM_VSC_CHIP_CAPABILITY_M_VERSION doesn\'t match" into mnc-dev
[android-x86/system-bt.git] / bta / gatt / bta_gattc_cache.c
1 /******************************************************************************
2  *
3  *  Copyright (C) 2003-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 the GATT client discovery procedures and cache
22  *  related functions.
23  *
24  ******************************************************************************/
25
26 #define LOG_TAG "bt_bta_gattc"
27
28 #include "bt_target.h"
29
30 #if defined(BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE)
31
32 #include <string.h>
33
34 #include "bta_gattc_int.h"
35 #include "bta_sys.h"
36 #include "btm_api.h"
37 #include "btm_ble_api.h"
38 #include "gki.h"
39 #include "osi/include/log.h"
40 #include "sdp_api.h"
41 #include "sdpdefs.h"
42 #include "utl.h"
43
44 static void bta_gattc_char_dscpt_disc_cmpl(UINT16 conn_id, tBTA_GATTC_SERV *p_srvc_cb);
45 static tBTA_GATT_STATUS bta_gattc_sdp_service_disc(UINT16 conn_id, tBTA_GATTC_SERV *p_server_cb);
46
47 #define BTA_GATT_SDP_DB_SIZE 4096
48
49 /*****************************************************************************
50 **  Constants
51 *****************************************************************************/
52
53 #if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
54 static char *bta_gattc_attr_type[] =
55 {
56     "I", /* Included Service */
57     "C", /* Characteristic */
58     "D" /* Characteristic Descriptor */
59 };
60 /* utility functions */
61
62 /*******************************************************************************
63 **
64 ** Function         bta_gattc_display_cache_server
65 **
66 ** Description      debug function to display the server cache.
67 **
68 ** Returns          none.
69 **
70 *******************************************************************************/
71 static void bta_gattc_display_cache_server(tBTA_GATTC_CACHE *p_cache)
72 {
73     UINT8 i = 0, j;
74     tBTA_GATTC_CACHE    *p_cur_srvc = p_cache;
75     tBTA_GATTC_CACHE_ATTR   *p_attr;
76
77     APPL_TRACE_ERROR("<================Start Server Cache =============>");
78
79     while (p_cur_srvc)
80     {
81         APPL_TRACE_ERROR("Service[%d]: handle[%d ~ %d] %s[0x%04x] inst[%d]",
82                           i, p_cur_srvc->s_handle, p_cur_srvc->e_handle,
83                           ((p_cur_srvc->service_uuid.id.uuid.len == 2) ? "uuid16" : "uuid128"),
84                           p_cur_srvc->service_uuid.id.uuid.uu.uuid16,
85                           p_cur_srvc->service_uuid.id.inst_id);
86         i ++;
87
88         p_attr = p_cur_srvc->p_attr;
89
90         for (j = 0; p_attr; j ++ )
91         {
92             APPL_TRACE_ERROR("\t Attr[0x%04x] handle[%d] uuid[0x%04x] inst[%d] type[%s] prop[0x%1x]",
93                               j + 1, p_attr->attr_handle, p_attr->p_uuid->uuid16, p_attr->inst_id,
94                               bta_gattc_attr_type[p_attr->attr_type], p_attr->property);
95
96             p_attr = p_attr->p_next;
97         }
98         p_cur_srvc = p_cur_srvc->p_next;
99     }
100
101     APPL_TRACE_ERROR("<================End Server Cache =============>");
102     APPL_TRACE_ERROR(" ");
103 }
104
105 /*******************************************************************************
106 **
107 ** Function         bta_gattc_display_explore_record
108 **
109 ** Description      debug function to display the exploration list
110 **
111 ** Returns          none.
112 **
113 *******************************************************************************/
114 static void bta_gattc_display_explore_record(tBTA_GATTC_ATTR_REC *p_rec, UINT8 num_rec)
115 {
116     UINT8 i;
117     tBTA_GATTC_ATTR_REC *pp = p_rec;
118
119     APPL_TRACE_ERROR("<================Start Explore Queue =============>");
120     for (i = 0; i < num_rec; i ++, pp ++)
121     {
122         APPL_TRACE_ERROR("\t rec[%d] uuid[0x%04x] s_handle[%d] e_handle[%d] is_primary[%d]",
123                           i + 1, pp->uuid.uu.uuid16, pp->s_handle, pp->e_handle, pp->is_primary);
124     }
125     APPL_TRACE_ERROR("<================ End Explore Queue =============>");
126     APPL_TRACE_ERROR(" ");
127
128 }
129 #endif  /* BTA_GATT_DEBUG == TRUE */
130
131
132 /*******************************************************************************
133 **
134 ** Function         bta_gattc_alloc_cache_buf
135 **
136 ** Description      Allocate a GKI buffer for database cache.
137 **
138 ** Returns          status
139 **
140 *******************************************************************************/
141 BT_HDR *bta_gattc_alloc_cache_buf(tBTA_GATTC_SERV *p_srvc_cb)
142 {
143     BT_HDR  *p_buf;
144
145     if ((p_buf = (BT_HDR *)GKI_getpoolbuf(GATT_DB_POOL_ID)) == NULL)
146     {
147         APPL_TRACE_DEBUG("No resources: GKI buffer allocation failed.");
148         utl_freebuf((void **)&p_srvc_cb->p_srvc_list);
149         p_srvc_cb->free_byte = 0;
150     }
151     else
152     {
153         memset(p_buf, 0, GKI_get_buf_size(p_buf));
154         p_srvc_cb->p_free = (UINT8 *) p_buf;
155         p_srvc_cb->free_byte = GKI_get_buf_size(p_buf);
156
157         /* link into buffer queue */
158         GKI_enqueue(&p_srvc_cb->cache_buffer, p_buf);
159     }
160 #if BTA_GATT_DEBUG== TRUE
161     APPL_TRACE_DEBUG("allocating new buffer: free byte = %d", p_srvc_cb->free_byte);
162 #endif
163     return p_buf;
164 }
165 /*******************************************************************************
166 **
167 ** Function         bta_gattc_init_cache
168 **
169 ** Description      Initialize the database cache and discovery related resources.
170 **
171 ** Returns          status
172 **
173 *******************************************************************************/
174 tBTA_GATT_STATUS bta_gattc_init_cache(tBTA_GATTC_SERV *p_srvc_cb)
175 {
176     tBTA_GATT_STATUS    status = BTA_GATT_OK;
177
178     while (!GKI_queue_is_empty(&p_srvc_cb->cache_buffer))
179         GKI_freebuf (GKI_dequeue (&p_srvc_cb->cache_buffer));
180
181     utl_freebuf((void **)&p_srvc_cb->p_srvc_list);
182
183     if ((p_srvc_cb->p_srvc_list = (tBTA_GATTC_ATTR_REC*)GKI_getbuf(BTA_GATTC_ATTR_LIST_SIZE)) == NULL)
184     {
185         APPL_TRACE_DEBUG("No resources: GKI buffer allocation failed.");
186         status = GATT_NO_RESOURCES;
187     }
188     else
189     {
190         p_srvc_cb->total_srvc = 0;
191         p_srvc_cb->cur_srvc_idx =
192         p_srvc_cb->cur_char_idx =
193         p_srvc_cb->next_avail_idx = 0;
194
195         if (bta_gattc_alloc_cache_buf(p_srvc_cb) == NULL)
196         {
197             status = GATT_NO_RESOURCES;
198         }
199         else
200         {
201             p_srvc_cb->p_cur_srvc = p_srvc_cb->p_srvc_cache = NULL;
202         }
203     }
204
205     return status;
206 }
207 /*******************************************************************************
208 **
209 ** Function         bta_gattc_get_srvc_inst_id
210 **
211 ** Description      get service instance number
212 **
213 ** Returns          instance ID of the service.
214 **
215 *******************************************************************************/
216 static UINT8 bta_gattc_get_srvc_inst_id(tBTA_GATTC_SERV *p_srvc_cb, tBT_UUID uuid)
217 {
218     UINT8 i = 0, inst = 0;
219     tBTA_GATTC_ATTR_REC   *p_srvc_rec;
220
221     for (i = 0; i < p_srvc_cb->total_srvc; i ++)
222     /*
223     for (; i < p_srvc_cb->cur_srvc_idx; i ++)*/
224     {
225         p_srvc_rec = p_srvc_cb->p_srvc_list + i;
226
227         if (bta_gattc_uuid_compare(&p_srvc_rec->uuid, &uuid, TRUE))
228             inst ++;
229     }
230     return inst ;
231 }
232 /*******************************************************************************
233 **
234 ** Function         bta_gattc_get_char_inst_id
235 **
236 ** Description      get characteristic instance number
237 **
238 ** Returns          characteristic instance ID.
239 **
240 *******************************************************************************/
241 static UINT8 bta_gattc_get_char_inst_id(tBTA_GATTC_CACHE *p_service_cache, tBT_UUID *p_uuid)
242 {
243     UINT8 inst = 0;
244     tBTA_GATTC_CACHE_ATTR   *p_attr;
245     tBT_UUID    attr_uuid;
246
247     p_attr = p_service_cache->p_attr;
248
249     while (p_attr)
250     {
251         bta_gattc_pack_attr_uuid(p_attr, &attr_uuid);
252
253         if (bta_gattc_uuid_compare(&attr_uuid, p_uuid, TRUE))
254             inst ++;
255
256         p_attr = p_attr->p_next;
257     }
258
259     return inst ;
260 }
261 /*******************************************************************************
262 **
263 ** Function         bta_gattc_get_char_descr_inst_id
264 **
265 ** Description      get characteristic descriptor instance number
266 **
267 ** Returns          characteristic instance ID.
268 **
269 *******************************************************************************/
270 static UINT8 bta_gattc_get_char_descr_inst_id(tBTA_GATTC_CACHE_ATTR *p_char_attr, tBT_UUID *p_uuid)
271 {
272     UINT8 inst = 0;
273     tBT_UUID    attr_uuid;
274
275     if (p_char_attr != NULL)
276         p_char_attr = p_char_attr->p_next;
277
278     while (p_char_attr)
279     {
280         bta_gattc_pack_attr_uuid(p_char_attr, &attr_uuid);
281
282         if (bta_gattc_uuid_compare(&attr_uuid, p_uuid, TRUE))
283             inst ++;
284
285         p_char_attr = p_char_attr->p_next;
286     }
287     return inst ;
288 }
289
290 /*******************************************************************************
291 **
292 ** Function         bta_gattc_add_srvc_to_cache
293 **
294 ** Description      Add a service into database cache.
295 **
296 ** Returns          status
297 **
298 *******************************************************************************/
299 static tBTA_GATT_STATUS bta_gattc_add_srvc_to_cache(tBTA_GATTC_SERV *p_srvc_cb,
300                                                     UINT16 s_handle, UINT16 e_handle,
301                                                     tBT_UUID *p_uuid,
302                                                     BOOLEAN is_primary, UINT8 srvc_inst)
303 {
304     tBTA_GATTC_CACHE    *p_new_srvc = NULL;
305     tBTA_GATT_STATUS    status = BTA_GATT_OK;
306
307 #if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
308     APPL_TRACE_DEBUG("Add a service into Service");
309     APPL_TRACE_DEBUG("free byte = %d,  req %d bytes.", p_srvc_cb->free_byte, sizeof(tBTA_GATTC_CACHE))
310 #endif
311
312     if (p_srvc_cb->free_byte < sizeof(tBTA_GATTC_CACHE))
313     {
314         if (bta_gattc_alloc_cache_buf(p_srvc_cb) == NULL)
315             return GATT_NO_RESOURCES;
316     }
317
318     p_new_srvc = (tBTA_GATTC_CACHE *)p_srvc_cb->p_free;
319     /* update service information */
320     p_new_srvc->s_handle = s_handle;
321     p_new_srvc->e_handle = e_handle;
322     p_new_srvc->service_uuid.is_primary = is_primary;
323     memcpy(&p_new_srvc->service_uuid.id.uuid, p_uuid, sizeof(tBT_UUID));
324     p_new_srvc->service_uuid.id.inst_id = srvc_inst;
325     p_new_srvc->p_next  = NULL;
326
327     if (p_srvc_cb->p_cur_srvc != NULL)
328         p_srvc_cb->p_cur_srvc->p_next = p_new_srvc;
329     p_srvc_cb->p_cur_srvc = p_new_srvc;
330     p_srvc_cb->p_cur_srvc->p_cur_char = NULL;
331
332     /* first service */
333     if (p_srvc_cb->p_srvc_cache == NULL)
334         p_srvc_cb->p_srvc_cache = p_new_srvc;
335
336     /* update buffer managament info */
337     p_srvc_cb->p_free += sizeof(tBTA_GATTC_CACHE);
338     p_srvc_cb->free_byte -= sizeof(tBTA_GATTC_CACHE);
339
340
341     return status;
342 }
343 /*******************************************************************************
344 **
345 ** Function         bta_gattc_add_attr_to_cache
346 **
347 ** Description      Add an attribute into database cache buffer.
348 **
349 ** Returns          status
350 **
351 *******************************************************************************/
352 static tBTA_GATT_STATUS bta_gattc_add_attr_to_cache(tBTA_GATTC_SERV *p_srvc_cb,
353                                                     UINT16 handle,
354                                                     tBT_UUID *p_uuid,
355                                                     UINT8 property,
356                                                     tBTA_GATTC_ATTR_TYPE type)
357 {
358     tBTA_GATTC_CACHE_ATTR *p_attr;
359     tBTA_GATT_STATUS    status = BTA_GATT_OK;
360     UINT16  len = sizeof(tBTA_GATTC_CACHE_ATTR) + p_uuid->len;
361     UINT8   *pp;
362
363 #if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
364     APPL_TRACE_DEBUG("bta_gattc_add_attr_to_cache: Add a [%s] into Service", bta_gattc_attr_type[type]);
365     APPL_TRACE_DEBUG("handle=%d uuid16=0x%x property=0x%x type=%d", handle, p_uuid->uu.uuid16, property, type);
366     APPL_TRACE_DEBUG("free byte = %d,  req %d bytes.", p_srvc_cb->free_byte, len);
367 #endif
368
369     if (p_srvc_cb->p_cur_srvc == NULL)
370     {
371         APPL_TRACE_ERROR("Illegal action to add char/descr/incl srvc before adding a service!");
372         return GATT_WRONG_STATE;
373     }
374
375     if (p_srvc_cb->free_byte < len)
376     {
377         if (bta_gattc_alloc_cache_buf(p_srvc_cb) == NULL)
378             return GATT_NO_RESOURCES;
379     }
380
381     p_attr = (tBTA_GATTC_CACHE_ATTR *)p_srvc_cb->p_free;
382
383     p_attr->attr_handle = handle;
384     p_attr->attr_type   = type;
385     p_attr->property    = property;
386     p_attr->uuid_len    = p_uuid->len;
387     p_attr->p_uuid      = (tBTA_GATTC_UUID *)(p_attr + 1);
388     p_attr->p_next      = NULL;
389
390     pp = (UINT8 *)p_attr->p_uuid;
391
392     if (p_uuid->len == LEN_UUID_16)
393     {
394         UINT16_TO_STREAM(pp, p_uuid->uu.uuid16);
395     }
396     else if (p_uuid->len == LEN_UUID_128)
397     {
398         memcpy(pp, p_uuid->uu.uuid128, LEN_UUID_128);
399     }
400
401     if (type == BTA_GATTC_ATTR_TYPE_CHAR)
402     {
403         p_attr->inst_id = bta_gattc_get_char_inst_id(p_srvc_cb->p_cur_srvc, p_uuid);
404         p_srvc_cb->p_cur_srvc->p_cur_char = p_attr;
405     }
406     else if (type == BTA_GATTC_ATTR_TYPE_CHAR_DESCR)
407         p_attr->inst_id = bta_gattc_get_char_descr_inst_id(p_srvc_cb->p_cur_srvc->p_cur_char, p_uuid);
408     else /* TODO: --->> temp treat included service as single instance */
409         p_attr->inst_id = 0;
410
411     /* update service information */
412     p_srvc_cb->p_free += len;
413     p_srvc_cb->free_byte -= len;
414
415     /* first attribute within the service, update the attribute pointer */
416     if (p_srvc_cb->p_cur_srvc->p_attr == NULL)
417     {
418         p_srvc_cb->p_cur_srvc->p_attr = p_attr;
419     }
420     if (p_srvc_cb->p_cur_srvc->p_last_attr != NULL)
421         p_srvc_cb->p_cur_srvc->p_last_attr->p_next = p_attr;
422
423     p_srvc_cb->p_cur_srvc->p_last_attr = p_attr;
424
425     return status;
426 }
427
428 /*******************************************************************************
429 **
430 ** Function         bta_gattc_get_disc_range
431 **
432 ** Description      get discovery stating and ending handle range.
433 **
434 ** Returns          None.
435 **
436 *******************************************************************************/
437 void bta_gattc_get_disc_range(tBTA_GATTC_SERV *p_srvc_cb, UINT16 *p_s_hdl, UINT16 *p_e_hdl, BOOLEAN is_srvc)
438 {
439     tBTA_GATTC_ATTR_REC *p_rec = NULL;
440
441     if (is_srvc)
442     {
443         p_rec = p_srvc_cb->p_srvc_list + p_srvc_cb->cur_srvc_idx;
444         *p_s_hdl = p_rec->s_handle;
445     }
446     else
447     {
448         p_rec = p_srvc_cb->p_srvc_list + p_srvc_cb->cur_char_idx;
449         *p_s_hdl = p_rec->s_handle + 1;
450     }
451
452     *p_e_hdl = p_rec->e_handle;
453 #if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
454     APPL_TRACE_DEBUG("discover range [%d ~ %d]",p_rec->s_handle, p_rec->e_handle);
455 #endif
456     return;
457 }
458 /*******************************************************************************
459 **
460 ** Function         bta_gattc_discover_pri_service
461 **
462 ** Description      Start primary service discovery
463 **
464 ** Returns          status of the operation.
465 **
466 *******************************************************************************/
467 tBTA_GATT_STATUS bta_gattc_discover_pri_service(UINT16 conn_id, tBTA_GATTC_SERV *p_server_cb,
468                                                     UINT8 disc_type)
469 {
470     tBTA_GATTC_CLCB     *p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
471     tBTA_GATT_STATUS    status =  BTA_GATT_ERROR;
472
473     if (p_clcb)
474     {
475         if (p_clcb->transport == BTA_TRANSPORT_LE)
476             status = bta_gattc_discover_procedure(conn_id, p_server_cb, disc_type);
477         else
478             status = bta_gattc_sdp_service_disc(conn_id, p_server_cb);
479     }
480
481     return status;
482 }
483 /*******************************************************************************
484 **
485 ** Function         bta_gattc_discover_procedure
486 **
487 ** Description      Start a particular type of discovery procedure on server.
488 **
489 ** Returns          status of the operation.
490 **
491 *******************************************************************************/
492 tBTA_GATT_STATUS bta_gattc_discover_procedure(UINT16 conn_id, tBTA_GATTC_SERV *p_server_cb,
493                                                    UINT8 disc_type)
494 {
495     tGATT_DISC_PARAM param;
496     BOOLEAN is_service = TRUE;
497
498     memset(&param, 0, sizeof(tGATT_DISC_PARAM));
499
500     if (disc_type == GATT_DISC_SRVC_ALL || disc_type == GATT_DISC_SRVC_BY_UUID)
501     {
502         param.s_handle = 1;
503         param.e_handle = 0xFFFF;
504     }
505     else
506     {
507         if (disc_type == GATT_DISC_CHAR_DSCPT)
508             is_service = FALSE;
509
510         bta_gattc_get_disc_range(p_server_cb, &param.s_handle, &param.e_handle, is_service);
511
512         if (param.s_handle > param.e_handle)
513         {
514             return GATT_ERROR;
515         }
516     }
517     return GATTC_Discover (conn_id, disc_type, &param);
518
519 }
520 /*******************************************************************************
521 **
522 ** Function         bta_gattc_start_disc_include_srvc
523 **
524 ** Description      Start discovery for included service
525 **
526 ** Returns          status of the operation.
527 **
528 *******************************************************************************/
529 tBTA_GATT_STATUS bta_gattc_start_disc_include_srvc(UINT16 conn_id, tBTA_GATTC_SERV *p_srvc_cb)
530 {
531     return bta_gattc_discover_procedure(conn_id, p_srvc_cb, GATT_DISC_INC_SRVC);
532 }
533 /*******************************************************************************
534 **
535 ** Function         bta_gattc_start_disc_char
536 **
537 ** Description      Start discovery for characteristic
538 **
539 ** Returns          status of the operation.
540 **
541 *******************************************************************************/
542 tBTA_GATT_STATUS bta_gattc_start_disc_char(UINT16 conn_id, tBTA_GATTC_SERV *p_srvc_cb)
543 {
544     p_srvc_cb->total_char = 0;
545
546     return bta_gattc_discover_procedure(conn_id, p_srvc_cb, GATT_DISC_CHAR);
547 }
548 /*******************************************************************************
549 **
550 ** Function         bta_gattc_start_disc_char_dscp
551 **
552 ** Description      Start discovery for characteristic descriptor
553 **
554 ** Returns          none.
555 **
556 *******************************************************************************/
557 void bta_gattc_start_disc_char_dscp(UINT16 conn_id, tBTA_GATTC_SERV *p_srvc_cb)
558 {
559     APPL_TRACE_DEBUG("starting discover characteristics descriptor");
560
561     if (bta_gattc_discover_procedure(conn_id, p_srvc_cb, GATT_DISC_CHAR_DSCPT) != 0)
562         bta_gattc_char_dscpt_disc_cmpl(conn_id, p_srvc_cb);
563
564 }
565 /*******************************************************************************
566 **
567 ** Function         bta_gattc_explore_srvc
568 **
569 ** Description      process the service discovery complete event
570 **
571 ** Returns          status
572 **
573 *******************************************************************************/
574 static void bta_gattc_explore_srvc(UINT16 conn_id, tBTA_GATTC_SERV *p_srvc_cb)
575 {
576     tBTA_GATTC_ATTR_REC *p_rec = p_srvc_cb->p_srvc_list + p_srvc_cb->cur_srvc_idx;
577     tBTA_GATTC_CLCB *p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
578
579     APPL_TRACE_DEBUG("Start service discovery: srvc_idx = %d", p_srvc_cb->cur_srvc_idx);
580
581     p_srvc_cb->cur_char_idx = p_srvc_cb->next_avail_idx = p_srvc_cb->total_srvc;
582
583     if (p_clcb == NULL)
584     {
585         APPL_TRACE_ERROR("unknown connection ID");
586         return;
587     }
588     /* start expore a service if there is service not been explored */
589     if (p_srvc_cb->cur_srvc_idx < p_srvc_cb->total_srvc)
590     {
591         /* add the first service into cache */
592         if (bta_gattc_add_srvc_to_cache (p_srvc_cb,
593                                          p_rec->s_handle,
594                                          p_rec->e_handle,
595                                          &p_rec->uuid,
596                                          p_rec->is_primary,
597                                          p_rec->srvc_inst_id) == 0)
598         {
599             /* start discovering included services */
600             bta_gattc_start_disc_include_srvc(conn_id, p_srvc_cb);
601             return;
602         }
603     }
604     /* no service found at all, the end of server discovery*/
605     LOG_WARN(LOG_TAG, "%s no more services found", __func__);
606
607 #if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
608     bta_gattc_display_cache_server(p_srvc_cb->p_srvc_cache);
609 #endif
610     /* save cache to NV */
611     p_clcb->p_srcb->state = BTA_GATTC_SERV_SAVE;
612     bta_gattc_co_cache_open(p_srvc_cb->server_bda, BTA_GATTC_CI_CACHE_OPEN_EVT,
613                             conn_id, TRUE);
614 }
615 /*******************************************************************************
616 **
617 ** Function         bta_gattc_incl_srvc_disc_cmpl
618 **
619 ** Description      process the relationship discovery complete event
620 **
621 ** Returns          status
622 **
623 *******************************************************************************/
624 static void bta_gattc_incl_srvc_disc_cmpl(UINT16 conn_id, tBTA_GATTC_SERV *p_srvc_cb)
625 {
626     p_srvc_cb->cur_char_idx = p_srvc_cb->total_srvc;
627
628     /* start discoverying characteristic */
629     bta_gattc_start_disc_char(conn_id, p_srvc_cb);
630 }
631 /*******************************************************************************
632 **
633 ** Function         bta_gattc_char_disc_cmpl
634 **
635 ** Description      process the characteristic discovery complete event
636 **
637 ** Returns          status
638 **
639 *******************************************************************************/
640 static void bta_gattc_char_disc_cmpl(UINT16 conn_id, tBTA_GATTC_SERV *p_srvc_cb)
641 {
642     tBTA_GATTC_ATTR_REC *p_rec = p_srvc_cb->p_srvc_list + p_srvc_cb->cur_char_idx;
643
644     /* if there are characteristic needs to be explored */
645     if (p_srvc_cb->total_char > 0)
646     {
647         /* add the first characteristic into cache */
648         bta_gattc_add_attr_to_cache (p_srvc_cb,
649                                      p_rec->s_handle,
650                                      &p_rec->uuid,
651                                      p_rec->property,
652                                      BTA_GATTC_ATTR_TYPE_CHAR);
653
654         /* start discoverying characteristic descriptor , if failed, disc for next char*/
655         bta_gattc_start_disc_char_dscp(conn_id, p_srvc_cb);
656     }
657     else /* otherwise start with next service */
658     {
659         p_srvc_cb->cur_srvc_idx ++;
660
661         bta_gattc_explore_srvc (conn_id, p_srvc_cb);
662     }
663 }
664 /*******************************************************************************
665 **
666 ** Function         bta_gattc_char_dscpt_disc_cmpl
667 **
668 ** Description      process the char descriptor discovery complete event
669 **
670 ** Returns          status
671 **
672 *******************************************************************************/
673 static void bta_gattc_char_dscpt_disc_cmpl(UINT16 conn_id, tBTA_GATTC_SERV *p_srvc_cb)
674 {
675     tBTA_GATTC_ATTR_REC *p_rec = NULL;
676
677     if (-- p_srvc_cb->total_char > 0)
678     {
679         p_rec = p_srvc_cb->p_srvc_list + (++ p_srvc_cb->cur_char_idx);
680         /* add the next characteristic into cache */
681         bta_gattc_add_attr_to_cache (p_srvc_cb,
682                                      p_rec->s_handle,
683                                      &p_rec->uuid,
684                                      p_rec->property,
685                                      BTA_GATTC_ATTR_TYPE_CHAR);
686
687         /* start discoverying next characteristic for char descriptor */
688         bta_gattc_start_disc_char_dscp(conn_id, p_srvc_cb);
689     }
690     else
691     /* all characteristic has been explored, start with next service if any */
692     {
693 #if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
694         APPL_TRACE_ERROR("all char has been explored");
695 #endif
696         p_srvc_cb->cur_srvc_idx ++;
697         bta_gattc_explore_srvc (conn_id, p_srvc_cb);
698     }
699
700 }
701 static BOOLEAN bta_gattc_srvc_in_list(tBTA_GATTC_SERV *p_srvc_cb, UINT16 s_handle,
702                                       UINT16 e_handle, tBT_UUID uuid)
703 {
704     tBTA_GATTC_ATTR_REC *p_rec = NULL;
705     UINT8   i;
706     BOOLEAN exist_srvc = FALSE;
707     UNUSED(uuid);
708
709     if (!GATT_HANDLE_IS_VALID(s_handle) || !GATT_HANDLE_IS_VALID(e_handle))
710     {
711         APPL_TRACE_ERROR("invalid included service handle: [0x%04x ~ 0x%04x]", s_handle, e_handle);
712         exist_srvc = TRUE;
713     }
714     else
715     {
716         for (i = 0; i < p_srvc_cb->next_avail_idx; i ++)
717         {
718             p_rec = p_srvc_cb->p_srvc_list + i;
719
720             /* a new service should not have any overlap with other service handle range */
721             if (p_rec->s_handle == s_handle || p_rec->e_handle == e_handle)
722             {
723                 exist_srvc = TRUE;
724                 break;
725             }
726         }
727     }
728     return exist_srvc;
729 }
730 /*******************************************************************************
731 **
732 ** Function         bta_gattc_add_srvc_to_list
733 **
734 ** Description      Add a service into explore pending list
735 **
736 ** Returns          status
737 **
738 *******************************************************************************/
739 static tBTA_GATT_STATUS bta_gattc_add_srvc_to_list(tBTA_GATTC_SERV *p_srvc_cb,
740                                                    UINT16 s_handle, UINT16 e_handle,
741                                                    tBT_UUID uuid, BOOLEAN is_primary)
742 {
743     tBTA_GATTC_ATTR_REC *p_rec = NULL;
744     tBTA_GATT_STATUS    status = BTA_GATT_OK;
745
746     if (p_srvc_cb->p_srvc_list && p_srvc_cb->next_avail_idx < BTA_GATTC_MAX_CACHE_CHAR)
747     {
748         p_rec = p_srvc_cb->p_srvc_list + p_srvc_cb->next_avail_idx;
749
750         APPL_TRACE_DEBUG("%s handle=%d, service type=0x%04x",
751                             __func__, s_handle, uuid.uu.uuid16);
752
753         p_rec->s_handle     = s_handle;
754         p_rec->e_handle     = e_handle;
755         p_rec->is_primary   = is_primary;
756         p_rec->srvc_inst_id = bta_gattc_get_srvc_inst_id(p_srvc_cb, uuid);
757         memcpy(&p_rec->uuid, &uuid, sizeof(tBT_UUID));
758
759         p_srvc_cb->total_srvc ++;
760         p_srvc_cb->next_avail_idx ++;
761     }
762     else
763     {   /* allocate bigger buffer ?? */
764         status = GATT_DB_FULL;
765
766         APPL_TRACE_ERROR("service not added, no resources or wrong state");
767     }
768     return status;
769 }
770 /*******************************************************************************
771 **
772 ** Function         bta_gattc_add_char_to_list
773 **
774 ** Description      Add a characteristic into explore pending list
775 **
776 ** Returns          status
777 **
778 *******************************************************************************/
779 static tBTA_GATT_STATUS bta_gattc_add_char_to_list(tBTA_GATTC_SERV *p_srvc_cb,
780                                                    UINT16 decl_handle, UINT16 value_handle,
781                                                    tBT_UUID uuid, UINT8 property)
782 {
783     tBTA_GATTC_ATTR_REC *p_rec = NULL;
784     tBTA_GATT_STATUS    status = BTA_GATT_OK;
785
786     if (p_srvc_cb->p_srvc_list == NULL)
787     {
788         APPL_TRACE_ERROR("No service available, unexpected char discovery result");
789         status = BTA_GATT_INTERNAL_ERROR;
790     }
791     else if (p_srvc_cb->next_avail_idx < BTA_GATTC_MAX_CACHE_CHAR)
792     {
793
794         p_rec = p_srvc_cb->p_srvc_list + p_srvc_cb->next_avail_idx;
795
796         p_srvc_cb->total_char ++;
797
798         p_rec->s_handle = value_handle;
799         p_rec->property = property;
800         p_rec->e_handle = (p_srvc_cb->p_srvc_list + p_srvc_cb->cur_srvc_idx)->e_handle;
801         memcpy(&p_rec->uuid, &uuid, sizeof(tBT_UUID));
802
803         /* update the endind handle of pervious characteristic if available */
804         if (p_srvc_cb->total_char > 1)
805         {
806             p_rec -= 1;
807             p_rec->e_handle = decl_handle - 1;
808         }
809         p_srvc_cb->next_avail_idx ++;
810     }
811     else
812     {
813         APPL_TRACE_ERROR("char not added, no resources");
814         /* allocate bigger buffer ?? */
815         status = BTA_GATT_DB_FULL;
816     }
817     return status;
818
819 }
820 /*******************************************************************************
821 **
822 ** Function         bta_gattc_sdp_callback
823 **
824 ** Description      Process the discovery result from sdp
825 **
826 ** Returns          void
827 **
828 *******************************************************************************/
829 void bta_gattc_sdp_callback (UINT16 sdp_status)
830 {
831     tSDP_DISC_REC       *p_sdp_rec = NULL;
832     tBT_UUID            service_uuid;
833     tSDP_PROTOCOL_ELEM  pe;
834     UINT16              start_handle = 0, end_handle = 0;
835     tBTA_GATTC_SERV     *p_srvc_cb = bta_gattc_find_scb_by_cid(bta_gattc_cb.sdp_conn_id);
836
837     if(((sdp_status == SDP_SUCCESS) || (sdp_status == SDP_DB_FULL)) && p_srvc_cb != NULL)
838     {
839         do
840         {
841             /* find a service record, report it */
842             p_sdp_rec = SDP_FindServiceInDb(bta_gattc_cb.p_sdp_db,
843                                             0, p_sdp_rec);
844             if (p_sdp_rec)
845             {
846                 if (SDP_FindServiceUUIDInRec(p_sdp_rec, &service_uuid))
847                 {
848
849                     if (SDP_FindProtocolListElemInRec(p_sdp_rec, UUID_PROTOCOL_ATT, &pe))
850                     {
851                         start_handle    = (UINT16) pe.params[0];
852                         end_handle      = (UINT16) pe.params[1];
853
854 #if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
855                         APPL_TRACE_EVENT("Found ATT service [0x%04x] handle[0x%04x ~ 0x%04x]",
856                                         service_uuid.uu.uuid16, start_handle, end_handle);
857 #endif
858
859                         if (GATT_HANDLE_IS_VALID(start_handle) && GATT_HANDLE_IS_VALID(end_handle)&&
860                             p_srvc_cb != NULL)
861                         {
862                             /* discover services result, add services into a service list */
863                             bta_gattc_add_srvc_to_list(p_srvc_cb,
864                                                        start_handle,
865                                                        end_handle,
866                                                        service_uuid,
867                                                        TRUE);
868                         }
869                         else
870                         {
871                             APPL_TRACE_ERROR("invalid start_handle = %d end_handle = %d",
872                                                 start_handle, end_handle);
873                         }
874                 }
875
876
877                 }
878             }
879         } while (p_sdp_rec);
880     }
881
882     if ( p_srvc_cb != NULL)
883         /* start discover primary service */
884         bta_gattc_explore_srvc(bta_gattc_cb.sdp_conn_id, p_srvc_cb);
885     else
886     {
887         APPL_TRACE_ERROR("GATT service discovery is done on unknown connection");
888     }
889
890     GKI_freebuf(bta_gattc_cb.p_sdp_db);
891     bta_gattc_cb.p_sdp_db  = NULL;
892     bta_gattc_cb.sdp_conn_id = 0;
893 }
894 /*******************************************************************************
895 **
896 ** Function         bta_gattc_sdp_service_disc
897 **
898 ** Description      Start DSP Service Discovert
899 **
900 ** Returns          void
901 **
902 *******************************************************************************/
903 static tBTA_GATT_STATUS bta_gattc_sdp_service_disc(UINT16 conn_id, tBTA_GATTC_SERV *p_server_cb)
904 {
905     tSDP_UUID       uuid;
906     UINT16          num_attrs = 2;
907     UINT16          attr_list[2];
908     tBTA_GATT_STATUS    status = BTA_GATT_ERROR;
909
910     memset (&uuid, 0, sizeof(tSDP_UUID));
911
912     uuid.len = LEN_UUID_16;
913     uuid.uu.uuid16 = UUID_PROTOCOL_ATT;
914
915      if((bta_gattc_cb.p_sdp_db = (tSDP_DISCOVERY_DB *)GKI_getbuf(BTA_GATT_SDP_DB_SIZE)) != NULL)
916     {
917         attr_list[0] = ATTR_ID_SERVICE_CLASS_ID_LIST;
918         attr_list[1] = ATTR_ID_PROTOCOL_DESC_LIST;
919
920         SDP_InitDiscoveryDb (bta_gattc_cb.p_sdp_db, BTA_GATT_SDP_DB_SIZE, 1,
921                              &uuid, num_attrs, attr_list);
922
923         if(!SDP_ServiceSearchAttributeRequest (p_server_cb->server_bda,
924                                               bta_gattc_cb.p_sdp_db, &bta_gattc_sdp_callback))
925         {
926             GKI_freebuf(bta_gattc_cb.p_sdp_db);
927             bta_gattc_cb.p_sdp_db = NULL;
928         }
929         else
930         {
931             bta_gattc_cb.sdp_conn_id = conn_id;
932             status = BTA_GATT_OK;
933         }
934      }
935      return status;
936 }
937 /*******************************************************************************
938 **
939 ** Function         bta_gattc_disc_res_cback
940 **                  bta_gattc_disc_cmpl_cback
941 **
942 ** Description      callback functions to GATT client stack.
943 **
944 ** Returns          void
945 **
946 *******************************************************************************/
947 void bta_gattc_disc_res_cback (UINT16 conn_id, tGATT_DISC_TYPE disc_type, tGATT_DISC_RES *p_data)
948 {
949     tBTA_GATTC_SERV * p_srvc_cb = NULL;
950     BOOLEAN          pri_srvc;
951     tBTA_GATTC_CLCB *p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
952
953     p_srvc_cb = bta_gattc_find_scb_by_cid(conn_id);
954
955     if (p_srvc_cb != NULL && p_clcb != NULL && p_clcb->state == BTA_GATTC_DISCOVER_ST)
956     {
957         switch (disc_type)
958         {
959             case GATT_DISC_SRVC_ALL:
960                 /* discover services result, add services into a service list */
961                 bta_gattc_add_srvc_to_list(p_srvc_cb,
962                                            p_data->handle,
963                                            p_data->value.group_value.e_handle,
964                                            p_data->value.group_value.service_type,
965                                            TRUE);
966
967                 break;
968             case GATT_DISC_SRVC_BY_UUID:
969                 bta_gattc_add_srvc_to_list(p_srvc_cb,
970                                            p_data->handle,
971                                            p_data->value.group_value.e_handle,
972                                            p_data->value.group_value.service_type,
973                                            TRUE);
974                 break;
975
976             case GATT_DISC_INC_SRVC:
977                 /* add included service into service list if it's secondary or it never showed up
978                    in the primary service search */
979                 pri_srvc = bta_gattc_srvc_in_list(p_srvc_cb,
980                                                   p_data->value.incl_service.s_handle,
981                                                   p_data->value.incl_service.e_handle,
982                                                   p_data->value.incl_service.service_type);
983
984                 if (!pri_srvc)
985                     bta_gattc_add_srvc_to_list(p_srvc_cb,
986                                                p_data->value.incl_service.s_handle,
987                                                p_data->value.incl_service.e_handle,
988                                                p_data->value.incl_service.service_type,
989                                                FALSE);
990                 /* add into database */
991                 bta_gattc_add_attr_to_cache(p_srvc_cb,
992                                             p_data->handle,
993                                             &p_data->value.incl_service.service_type,
994                                             pri_srvc,
995                                             BTA_GATTC_ATTR_TYPE_INCL_SRVC);
996                 break;
997
998             case GATT_DISC_CHAR:
999                 /* add char value into database */
1000                 bta_gattc_add_char_to_list(p_srvc_cb,
1001                                            p_data->handle,
1002                                            p_data->value.dclr_value.val_handle,
1003                                            p_data->value.dclr_value.char_uuid,
1004                                            p_data->value.dclr_value.char_prop);
1005                 break;
1006
1007             case GATT_DISC_CHAR_DSCPT:
1008                 bta_gattc_add_attr_to_cache(p_srvc_cb, p_data->handle, &p_data->type, 0,
1009                                             BTA_GATTC_ATTR_TYPE_CHAR_DESCR);
1010                 break;
1011         }
1012     }
1013 }
1014 void bta_gattc_disc_cmpl_cback (UINT16 conn_id, tGATT_DISC_TYPE disc_type, tGATT_STATUS status)
1015 {
1016     tBTA_GATTC_SERV * p_srvc_cb;
1017     tBTA_GATTC_CLCB *p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
1018
1019     if ( p_clcb && (status != GATT_SUCCESS || p_clcb->status != GATT_SUCCESS) )
1020     {
1021         if (p_clcb->status == GATT_SUCCESS)
1022             p_clcb->status = status;
1023         bta_gattc_sm_execute(p_clcb, BTA_GATTC_DISCOVER_CMPL_EVT, NULL);
1024         return;
1025     }
1026     p_srvc_cb = bta_gattc_find_scb_by_cid(conn_id);
1027
1028     if (p_srvc_cb != NULL)
1029     {
1030         switch (disc_type)
1031         {
1032             case GATT_DISC_SRVC_ALL:
1033             case GATT_DISC_SRVC_BY_UUID:
1034 #if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
1035                 bta_gattc_display_explore_record(p_srvc_cb->p_srvc_list, p_srvc_cb->next_avail_idx);
1036 #endif
1037                 bta_gattc_explore_srvc(conn_id, p_srvc_cb);
1038                 break;
1039
1040             case GATT_DISC_INC_SRVC:
1041                 bta_gattc_incl_srvc_disc_cmpl(conn_id, p_srvc_cb);
1042
1043                 break;
1044
1045             case GATT_DISC_CHAR:
1046 #if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
1047                 bta_gattc_display_explore_record(p_srvc_cb->p_srvc_list, p_srvc_cb->next_avail_idx);
1048 #endif
1049                 bta_gattc_char_disc_cmpl(conn_id, p_srvc_cb);
1050                 break;
1051
1052             case GATT_DISC_CHAR_DSCPT:
1053                 bta_gattc_char_dscpt_disc_cmpl(conn_id, p_srvc_cb);
1054                 break;
1055         }
1056     }
1057 }
1058 /*******************************************************************************
1059 **
1060 ** Function         bta_gattc_id2handle
1061 **
1062 ** Description      map GATT ID to handle in a given cache.
1063 **
1064 ** Returns          the handle mapped. 0 if not found.
1065 **
1066 *******************************************************************************/
1067 UINT16 bta_gattc_id2handle(tBTA_GATTC_SERV *p_srcb, tBTA_GATT_SRVC_ID *p_service_id,
1068                            tBTA_GATT_ID *p_char_id, tBTA_GATT_ID *p_descr_uuid)
1069 {
1070     tBTA_GATTC_CACHE    *p_cache = p_srcb->p_srvc_cache;
1071     tBTA_GATTC_CACHE_ATTR   *p_attr;
1072     UINT8       j;
1073     UINT16      handle = 0;
1074     tBT_UUID    attr_uuid;
1075     BOOLEAN     char_map = FALSE, done = FALSE;
1076
1077     while (p_service_id && p_cache && !done)
1078     {
1079 #if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
1080         APPL_TRACE_DEBUG("Service: handle[%d] uuid[0x%04x] inst[%d]",
1081                           p_cache->s_handle, p_cache->service_uuid.id.uuid.uu.uuid16,
1082                           p_cache->service_uuid.id.inst_id);
1083 #endif
1084         p_attr = p_cache->p_attr;
1085
1086         if (bta_gattc_srvcid_compare(p_service_id, &p_cache->service_uuid))
1087         {
1088             for (j = 0; p_attr; j ++)
1089             {
1090 #if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
1091                 APPL_TRACE_DEBUG("\t Attr[0x%04x] handle[0x%04x] uuid[0x%04x] inst[%d] type[%d]",
1092                                   j + 1, p_attr->attr_handle, p_attr->p_uuid->uuid16,
1093                                     p_attr->inst_id, p_attr->attr_type);
1094 #endif
1095                 bta_gattc_pack_attr_uuid(p_attr, &attr_uuid);
1096
1097                 if (bta_gattc_uuid_compare(&p_char_id->uuid, &attr_uuid, TRUE) &&
1098                     p_char_id->inst_id == p_attr->inst_id)
1099                 {
1100                     if (p_descr_uuid == NULL)
1101                     {
1102                         handle = p_attr->attr_handle;
1103                         done = TRUE;
1104                         break;
1105                     }
1106                     else
1107                     {
1108 #if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
1109                         APPL_TRACE_DEBUG("found matching characteristic for the descriptor");
1110 #endif
1111                         char_map = TRUE;
1112                     }
1113                 }
1114                 else if (char_map == TRUE)
1115                 {
1116                     if (p_attr->attr_type == BTA_GATTC_ATTR_TYPE_CHAR_DESCR)
1117                     {
1118
1119                         if (p_descr_uuid != NULL &&
1120                             bta_gattc_uuid_compare(&p_descr_uuid->uuid, &attr_uuid, TRUE) &&
1121                             p_descr_uuid->inst_id == p_attr->inst_id)
1122                         {
1123 #if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
1124                             APPL_TRACE_DEBUG("found descriptor!!");
1125 #endif
1126                             handle = p_attr->attr_handle;
1127                             done = TRUE;
1128                             break;
1129                         }
1130                         else
1131                         {
1132 #if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
1133                             APPL_TRACE_DEBUG("descriptor UUID not matching");
1134 #endif
1135                         }
1136                     }
1137                     else /* another char */
1138                     {
1139 #if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
1140                        APPL_TRACE_DEBUG("no matching descptr found!!start of next characteristic");
1141 #endif
1142                         char_map = FALSE;
1143                         done = TRUE;
1144                         break;
1145                     }
1146                 }
1147                 p_attr = p_attr->p_next;
1148             }
1149         }
1150         p_cache = p_cache->p_next;
1151     }
1152
1153     return handle;
1154 }
1155 /*******************************************************************************
1156 **
1157 ** Function         bta_gattc_handle2id
1158 **
1159 ** Description      map a handle to GATT ID in a given cache.
1160 **
1161 ** Returns          FALSE if map can not be found.
1162 **
1163 *******************************************************************************/
1164
1165 BOOLEAN bta_gattc_handle2id(tBTA_GATTC_SERV *p_srcb, UINT16 handle, tBTA_GATT_SRVC_ID *p_service_id,
1166                             tBTA_GATT_ID *p_char_id, tBTA_GATT_ID *p_descr_type)
1167 {
1168     tBTA_GATTC_CACHE    *p_cache = p_srcb->p_srvc_cache;
1169     tBTA_GATTC_CACHE_ATTR   *p_attr, *p_char = NULL;
1170     UINT8       j;
1171
1172     memset(p_service_id, 0, sizeof(tBTA_GATT_SRVC_ID));
1173     memset(p_char_id, 0, sizeof(tBTA_GATT_ID));
1174     memset(p_descr_type, 0, sizeof(tBTA_GATT_ID));
1175
1176     while (p_cache)
1177     {
1178 #if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
1179         APPL_TRACE_DEBUG("Service: handle[%d] uuid[0x%04x] inst[%d]",
1180                           p_cache->s_handle, p_cache->service_uuid.id.uuid.uu.uuid16,
1181                           p_cache->service_uuid.id.inst_id);
1182 #endif
1183         /* a service found */
1184         if (p_cache->s_handle == handle)
1185         {
1186             memcpy(p_service_id, &p_cache->service_uuid, sizeof(tBTA_GATT_SRVC_ID));
1187
1188             return TRUE;
1189         }
1190         else /* start looking for attributes within the service */
1191         {
1192             p_attr = p_cache->p_attr;
1193
1194             for (j = 0; p_attr; j ++)
1195             {
1196 #if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
1197                 APPL_TRACE_DEBUG("\t Attr[0x%04x] handle[0x%04x] uuid[0x%04x] inst[%d] type[%d]",
1198                                   j + 1, p_attr->attr_handle, p_attr->p_uuid->uuid16,
1199                                   p_attr->inst_id, p_attr->attr_type);
1200 #endif
1201                 if (p_attr->attr_type == BTA_GATTC_ATTR_TYPE_CHAR)
1202                     p_char = p_attr;
1203
1204                 if (handle == p_attr->attr_handle)
1205                 {
1206                     memcpy(p_service_id, &p_cache->service_uuid, sizeof(tBTA_GATT_SRVC_ID));
1207
1208                     if (p_attr->attr_type == BTA_GATTC_ATTR_TYPE_CHAR_DESCR)
1209                     {
1210                         bta_gattc_pack_attr_uuid(p_attr, &p_descr_type->uuid);
1211                         p_descr_type->inst_id = p_attr->inst_id;
1212
1213                         if (p_char != NULL)
1214                         {
1215                             bta_gattc_pack_attr_uuid(p_char, &p_char_id->uuid);
1216                             p_char_id->inst_id = p_char->inst_id;
1217                         }
1218                         else
1219                         {
1220                             APPL_TRACE_ERROR("descptr does not belong to any chracteristic");
1221                         }
1222                     }
1223                     else
1224                     /* is a characterisitc value or included service */
1225                     {
1226                         bta_gattc_pack_attr_uuid(p_attr, &p_char_id->uuid);
1227                         p_char_id->inst_id =p_attr->inst_id;
1228                     }
1229                     return TRUE;
1230                 }
1231                 p_attr = p_attr->p_next;
1232             }
1233         }
1234         p_cache = p_cache->p_next;
1235     }
1236
1237     return FALSE;
1238 }
1239
1240 /*******************************************************************************
1241 **
1242 ** Function         bta_gattc_search_service
1243 **
1244 ** Description      search local cache for matching service record.
1245 **
1246 ** Returns          FALSE if map can not be found.
1247 **
1248 *******************************************************************************/
1249 void bta_gattc_search_service(tBTA_GATTC_CLCB *p_clcb, tBT_UUID *p_uuid)
1250 {
1251     tBTA_GATTC_SERV     *p_srcb = p_clcb->p_srcb;
1252     tBTA_GATTC_CACHE    *p_cache = p_srcb->p_srvc_cache;
1253     tBTA_GATTC          cb_data;
1254
1255     while (p_cache)
1256     {
1257         if (bta_gattc_uuid_compare(p_uuid, &p_cache->service_uuid.id.uuid, FALSE))
1258         {
1259 #if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
1260             APPL_TRACE_DEBUG("found service [0x%04x], inst[%d] handle [%d]",
1261                               p_cache->service_uuid.id.uuid.uu.uuid16,
1262                               p_cache->service_uuid.id.inst_id,
1263                               p_cache->s_handle);
1264 #endif
1265             if (p_clcb->p_rcb->p_cback)
1266             {
1267                 memset(&cb_data, 0, sizeof(tBTA_GATTC));
1268
1269                 cb_data.srvc_res.conn_id = p_clcb->bta_conn_id;
1270                 memcpy(&cb_data.srvc_res.service_uuid, &p_cache->service_uuid,
1271                         sizeof(tBTA_GATT_SRVC_ID));
1272
1273                 (* p_clcb->p_rcb->p_cback)(BTA_GATTC_SEARCH_RES_EVT, &cb_data);
1274             }
1275         }
1276         p_cache = p_cache->p_next;
1277     }
1278 }
1279 /*******************************************************************************
1280 **
1281 ** Function         bta_gattc_find_record
1282 **
1283 ** Description      search local cache for matching attribute record.
1284 **
1285 ** Parameter        p_result: output parameter to store the characteristic/
1286 **                            included service GATT ID.
1287 **
1288 ** Returns          GATT_ERROR is no recording found. BTA_GATT_OK if record found.
1289 **
1290 *******************************************************************************/
1291 static tBTA_GATT_STATUS bta_gattc_find_record(tBTA_GATTC_SERV *p_srcb,
1292                                               tBTA_GATTC_ATTR_TYPE attr_type,
1293                                               tBTA_GATT_SRVC_ID *p_service_id,
1294                                               tBTA_GATT_ID  *p_start_rec,
1295                                               tBT_UUID      * p_uuid_cond,
1296                                               tBTA_GATT_ID  *p_result,
1297                                               void *p_param)
1298 {
1299     tBTA_GATTC_CACHE    *p_cache = p_srcb->p_srvc_cache;
1300     tBTA_GATT_STATUS    status = BTA_GATT_ERROR;
1301     UINT8               i, j;
1302     tBTA_GATTC_CACHE_ATTR   *p_attr;
1303     BOOLEAN             char_found = FALSE, descr_found = FALSE;
1304     tBTA_GATT_ID        *p_descr_id = (tBTA_GATT_ID *)p_param;;
1305
1306     for (i = 0; p_cache && status != BTA_GATT_OK; i ++)
1307     {
1308         if (bta_gattc_srvcid_compare(p_service_id, &p_cache->service_uuid))
1309         {
1310 #if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
1311             APPL_TRACE_DEBUG("found matching service [0x%04x], inst[%d]",
1312                               p_cache->service_uuid.id.uuid.uu.uuid16,
1313                               p_cache->service_uuid.id.inst_id);
1314 #endif
1315             p_attr = p_cache->p_attr;
1316
1317             for (j = 0; p_attr; j ++)
1318             {
1319 #if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
1320                 APPL_TRACE_DEBUG("\t Attr[%d] handle[0x%04x] uuid[0x%04x] inst[%d] type[%d]",
1321                                   j + 1, p_attr->attr_handle,
1322                                   p_attr->p_uuid->uuid16,
1323                                   p_attr->inst_id,
1324                                   p_attr->attr_type);
1325 #endif
1326                 bta_gattc_pack_attr_uuid(p_attr, &p_result->uuid);
1327
1328                 if (p_start_rec != NULL && char_found == FALSE)
1329                 {
1330                     /* find the starting record first */
1331                     if (bta_gattc_uuid_compare(&p_start_rec->uuid, &p_result->uuid, FALSE) &&
1332                         p_start_rec->inst_id  == p_attr->inst_id &&
1333                         (attr_type == p_attr->attr_type ||
1334                         /* find descriptor would look for characteristic first */
1335                          (attr_type == BTA_GATTC_ATTR_TYPE_CHAR_DESCR &&
1336                           p_attr->attr_type == BTA_GATTC_ATTR_TYPE_CHAR)))
1337                     {
1338                         char_found = TRUE;
1339                     }
1340                 }
1341                 else
1342                 {
1343                     /* if looking for descriptor, here is the where the descrptor to be found */
1344                     if (attr_type == BTA_GATTC_ATTR_TYPE_CHAR_DESCR)
1345                     {
1346                         /* next characeteristic already, return error */
1347                         if (p_attr->attr_type != BTA_GATTC_ATTR_TYPE_CHAR_DESCR)
1348                         {
1349                             break;
1350                         }
1351                         else
1352                         {
1353                             /* find starting descriptor */
1354                             if (p_descr_id != NULL && !descr_found)
1355                             {
1356                                 if (bta_gattc_uuid_compare(&p_descr_id->uuid, &p_result->uuid, TRUE)
1357                                     && p_descr_id->inst_id == p_attr->inst_id)
1358                                 {
1359                                     descr_found = TRUE;
1360                                 }
1361                             }
1362                             else
1363                             {
1364                                 /* with matching descriptor */
1365                                 if (bta_gattc_uuid_compare(p_uuid_cond, &p_result->uuid, FALSE))
1366                                 {
1367                                     p_result->inst_id = p_attr->inst_id;
1368                                     status = BTA_GATT_OK;
1369                                     break;
1370                                 }
1371                             }
1372                         }
1373                     }
1374                     else
1375                     {
1376                         if (bta_gattc_uuid_compare(p_uuid_cond, &p_result->uuid, FALSE) &&
1377                             attr_type == p_attr->attr_type)
1378                         {
1379
1380 #if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
1381                             APPL_TRACE_DEBUG("found char handle mapping characteristic");
1382 #endif
1383                             p_result->inst_id = p_attr->inst_id;
1384
1385                             if (p_param != NULL)
1386                             {
1387                                 if (attr_type == BTA_GATTC_ATTR_TYPE_CHAR ||
1388                                     attr_type == BTA_GATTC_ATTR_TYPE_INCL_SRVC)
1389                                 {
1390                                     *(tBTA_GATT_CHAR_PROP *)p_param = p_attr->property;
1391                                 }
1392                             }
1393
1394                             status = BTA_GATT_OK;
1395                             break;
1396                         }
1397                     }
1398                 }
1399                 p_attr = p_attr->p_next;
1400             }
1401 #if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
1402             if (status)
1403             {
1404                 APPL_TRACE_ERROR("In the given service, can not find matching record");
1405             }
1406 #endif
1407             break;
1408         }
1409
1410         p_cache = p_cache->p_next;
1411     }
1412     return status;
1413
1414 }
1415
1416 /*******************************************************************************
1417 **
1418 ** Function         bta_gattc_query_cache
1419 **
1420 ** Description      search local cache for matching attribute record.
1421 **
1422 ** Parameters       conn_id: connection ID which identify the server.
1423 **                  p_srvc_id: the service ID of which the characteristic is belonged to.
1424 **                  *p_start_rec: start the search from the next record
1425 **                                  after the one identified by *p_start_rec.
1426 **                  p_uuid_cond: UUID, if NULL find the first available
1427 **                               characteristic/included service.
1428 **                  p_output:   output parameter which will store the GATT ID
1429 **                              of the characteristic /included service found.
1430 **
1431 ** Returns          BTA_GATT_ERROR is no recording found. BTA_GATT_OK if record found.
1432 **
1433 *******************************************************************************/
1434 tBTA_GATT_STATUS bta_gattc_query_cache(UINT16 conn_id,
1435                                        tBTA_GATTC_ATTR_TYPE query_type,
1436                                        tBTA_GATT_SRVC_ID *p_srvc_id,
1437                                        tBTA_GATT_ID *p_start_rec,
1438                                        tBT_UUID *p_uuid_cond,
1439                                        tBTA_GATT_ID *p_output,
1440                                        void *p_param)
1441 {
1442     tBTA_GATTC_CLCB *p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
1443     tBTA_GATT_STATUS status = BTA_GATT_ILLEGAL_PARAMETER;
1444
1445     if (p_clcb != NULL )
1446     {
1447         if (p_clcb->state == BTA_GATTC_CONN_ST)
1448         {
1449             if (p_clcb->p_srcb &&
1450                 !p_clcb->p_srcb->p_srvc_list && /* no active discovery */
1451                 p_clcb->p_srcb->p_srvc_cache)
1452             {
1453                 status = bta_gattc_find_record(p_clcb->p_srcb,
1454                                                query_type,
1455                                                p_srvc_id,
1456                                                p_start_rec,
1457                                                p_uuid_cond,
1458                                                p_output,
1459                                                p_param);
1460             }
1461             else
1462             {
1463                 status = BTA_GATT_ERROR;
1464                 APPL_TRACE_ERROR("No server cache available");
1465             }
1466         }
1467         else
1468         {
1469             APPL_TRACE_ERROR("server cache not available, CLCB state = %d", p_clcb->state);
1470
1471             status = (p_clcb->state == BTA_GATTC_DISCOVER_ST) ? BTA_GATT_BUSY : BTA_GATT_ERROR;
1472         }
1473     }
1474     else
1475     {
1476         APPL_TRACE_ERROR("Unknown conn ID: %d", conn_id);
1477     }
1478
1479     return status;
1480 }
1481
1482 /*******************************************************************************
1483 **
1484 ** Function         bta_gattc_rebuild_cache
1485 **
1486 ** Description      rebuild server cache from NV cache.
1487 **
1488 ** Parameters
1489 **
1490 ** Returns          None.
1491 **
1492 *******************************************************************************/
1493 void bta_gattc_rebuild_cache(tBTA_GATTC_SERV *p_srvc_cb, UINT16 num_attr,
1494                              tBTA_GATTC_NV_ATTR *p_attr, UINT16 attr_index)
1495 {
1496     /* first attribute loading, initialize buffer */
1497     APPL_TRACE_ERROR("bta_gattc_rebuild_cache");
1498     if (attr_index == 0)
1499     {
1500         while (!GKI_queue_is_empty(&p_srvc_cb->cache_buffer))
1501             GKI_freebuf (GKI_dequeue (&p_srvc_cb->cache_buffer));
1502
1503         if (bta_gattc_alloc_cache_buf(p_srvc_cb) == NULL)
1504         {
1505             APPL_TRACE_ERROR("allocate cache buffer failed, no resources");
1506         }
1507         else
1508         {
1509             p_srvc_cb->p_cur_srvc = p_srvc_cb->p_srvc_cache = NULL;
1510         }
1511     }
1512
1513     while (num_attr > 0 && p_attr != NULL)
1514     {
1515         switch (p_attr->attr_type)
1516         {
1517             case BTA_GATTC_ATTR_TYPE_SRVC:
1518                 bta_gattc_add_srvc_to_cache(p_srvc_cb,
1519                                             p_attr->s_handle,
1520                                             p_attr->e_handle,
1521                                             &p_attr->uuid,
1522                                             p_attr->is_primary,
1523                                             p_attr->id);
1524                 break;
1525
1526             case BTA_GATTC_ATTR_TYPE_CHAR:
1527             case BTA_GATTC_ATTR_TYPE_CHAR_DESCR:
1528             case BTA_GATTC_ATTR_TYPE_INCL_SRVC:
1529                 bta_gattc_add_attr_to_cache(p_srvc_cb,
1530                                             p_attr->s_handle,
1531                                             &p_attr->uuid,
1532                                             p_attr->prop,
1533                                             p_attr->attr_type);
1534                 break;
1535         }
1536         p_attr ++;
1537         num_attr --;
1538     }
1539 }
1540
1541 /*******************************************************************************
1542 **
1543 ** Function         bta_gattc_fill_nv_attr
1544 **
1545 ** Description      fill a NV attribute entry value
1546 **
1547 ** Returns          None.
1548 **
1549 *******************************************************************************/
1550 void bta_gattc_fill_nv_attr(tBTA_GATTC_NV_ATTR *p_attr, UINT8 type, UINT16 s_handle,
1551                             UINT16 e_handle, UINT8 id, tBT_UUID uuid, UINT8 prop,
1552                             BOOLEAN is_primary)
1553 {
1554     p_attr->s_handle    = s_handle;
1555     p_attr->e_handle    = e_handle;
1556     p_attr->attr_type   = type;
1557     p_attr->is_primary  = is_primary;
1558     p_attr->id          = id;
1559     p_attr->prop        = prop;
1560
1561     memcpy(&p_attr->uuid, &uuid, sizeof(tBT_UUID));
1562 }
1563 /*******************************************************************************
1564 **
1565 ** Function         bta_gattc_cache_save
1566 **
1567 ** Description      save the server cache into NV
1568 **
1569 ** Returns          None.
1570 **
1571 *******************************************************************************/
1572 BOOLEAN bta_gattc_cache_save(tBTA_GATTC_SERV *p_srvc_cb, UINT16 conn_id)
1573 {
1574     tBTA_GATTC_CACHE        *p_cur_srvc = p_srvc_cb->p_srvc_cache;
1575     UINT8                   i = 0;
1576     UINT16                  offset = 0;
1577     tBTA_GATTC_NV_ATTR      nv_attr[BTA_GATTC_NV_LOAD_MAX];
1578     tBTA_GATTC_CACHE_ATTR   *p_attr;
1579     tBT_UUID                uuid;
1580
1581     while (p_cur_srvc && i < BTA_GATTC_NV_LOAD_MAX)
1582     {
1583         if (offset ++ >= p_srvc_cb->attr_index)
1584         {
1585             bta_gattc_fill_nv_attr(&nv_attr[i++],
1586                                    BTA_GATTC_ATTR_TYPE_SRVC,
1587                                    p_cur_srvc->s_handle,
1588                                    p_cur_srvc->e_handle,
1589                                    p_cur_srvc->service_uuid.id.inst_id,
1590                                    p_cur_srvc->service_uuid.id.uuid,
1591                                    0,
1592                                    p_cur_srvc->service_uuid.is_primary);
1593         }
1594
1595         p_attr = p_cur_srvc->p_attr;
1596
1597         for (; p_attr && i < BTA_GATTC_NV_LOAD_MAX ; offset ++, p_attr = p_attr->p_next)
1598         {
1599             if (offset >= p_srvc_cb->attr_index)
1600             {
1601                 if ((uuid.len = p_attr->uuid_len) == LEN_UUID_16)
1602                 {
1603                     uuid.uu.uuid16 = p_attr->p_uuid->uuid16;
1604                 }
1605                 else
1606                 {
1607                     memcpy(uuid.uu.uuid128, p_attr->p_uuid->uuid128, LEN_UUID_128);
1608                 }
1609
1610                 bta_gattc_fill_nv_attr(&nv_attr[i++],
1611                                        p_attr->attr_type,
1612                                        p_attr->attr_handle,
1613                                        0,
1614                                        p_attr->inst_id,
1615                                        uuid,
1616                                        p_attr->property,
1617                                        FALSE);
1618             }
1619         }
1620         p_cur_srvc = p_cur_srvc->p_next;
1621     }
1622
1623     if (i > 0)
1624     {
1625         bta_gattc_co_cache_save(p_srvc_cb->server_bda, BTA_GATTC_CI_CACHE_SAVE_EVT, i,
1626                                 nv_attr, p_srvc_cb->attr_index, conn_id);
1627
1628         p_srvc_cb->attr_index += i;
1629
1630         return TRUE;
1631     }
1632     else
1633     {
1634         return FALSE;
1635     }
1636 }
1637 #endif /* BTA_GATT_INCLUDED */
1638