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