OSDN Git Service

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