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