OSDN Git Service

Fix missing GATT Characteristic from last service
authorJakub Pawlowski <jpawlowski@google.com>
Tue, 14 Jun 2016 19:23:44 +0000 (12:23 -0700)
committerJakub Pawlowski <jpawlowski@google.com>
Tue, 14 Jun 2016 19:28:00 +0000 (12:28 -0700)
GATT Service is contained between start and end handle. If
characteristic definition is at end handle, and it's value definition is
after end handle, it will not be properly discovered. That's because we
use value_handle instead of attribute_handle to identify
characteristics.

As a workaround, increase service boundary if value is defined after
it's definition.

Bug: 29253825
Change-Id: Ib145aea4f5cf38a1fbb977c301136e16f8f900f7

bta/gatt/bta_gattc_cache.c
bta/gatt/bta_gattc_int.h

index aaff813..a3ccc40 100644 (file)
@@ -224,6 +224,44 @@ static tBTA_GATT_STATUS bta_gattc_add_srvc_to_cache(tBTA_GATTC_SERV *p_srvc_cb,
     list_append(p_srvc_cb->p_srvc_cache, p_new_srvc);
     return BTA_GATT_OK;
 }
+
+static tBTA_GATT_STATUS bta_gattc_add_char_to_cache(tBTA_GATTC_SERV *p_srvc_cb,
+                                                    UINT16 attr_handle,
+                                                    UINT16 value_handle,
+                                                    tBT_UUID *p_uuid,
+                                                    UINT8 property)
+{
+#if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
+    APPL_TRACE_DEBUG("%s: Add a characteristic into Service", __func__);
+    APPL_TRACE_DEBUG("handle=%d uuid16=0x%x property=0x%x",
+                      value_handle, p_uuid->uu.uuid16, property);
+#endif
+
+    tBTA_GATTC_SERVICE *service = bta_gattc_find_matching_service(p_srvc_cb->p_srvc_cache, attr_handle);
+    if (!service) {
+        APPL_TRACE_ERROR("Illegal action to add char/descr/incl srvc for non-existing service!");
+        return GATT_WRONG_STATE;
+    }
+
+    /* TODO(jpawlowski): We should use attribute handle, not value handle to refer to characteristic.
+       This is just a temporary workaround.
+    */
+    if (service->e_handle < value_handle)
+        service->e_handle = value_handle;
+
+    tBTA_GATTC_CHARACTERISTIC *characteristic = osi_malloc(sizeof(tBTA_GATTC_CHARACTERISTIC));
+
+    characteristic->handle = value_handle;
+    characteristic->properties = property;
+    characteristic->descriptors = list_new(osi_free);
+    memcpy(&characteristic->uuid, p_uuid, sizeof(tBT_UUID));
+
+    characteristic->service = service;
+    list_append(service->characteristics, characteristic);
+
+    return BTA_GATT_OK;
+}
+
 /*******************************************************************************
 **
 ** Function         bta_gattc_add_attr_to_cache
@@ -252,18 +290,7 @@ static tBTA_GATT_STATUS bta_gattc_add_attr_to_cache(tBTA_GATTC_SERV *p_srvc_cb,
         return GATT_WRONG_STATE;
     }
 
-    if (type == BTA_GATTC_ATTR_TYPE_CHAR) {
-        tBTA_GATTC_CHARACTERISTIC *characteristic =
-            osi_malloc(sizeof(tBTA_GATTC_CHARACTERISTIC));
-
-        characteristic->handle = handle;
-        characteristic->properties = property;
-        characteristic->descriptors = list_new(osi_free);
-        memcpy(&characteristic->uuid, p_uuid, sizeof(tBT_UUID));
-
-        characteristic->service = service;
-        list_append(service->characteristics, characteristic);
-    } else if (type == BTA_GATTC_ATTR_TYPE_INCL_SRVC) {
+    if (type == BTA_GATTC_ATTR_TYPE_INCL_SRVC) {
         tBTA_GATTC_INCLUDED_SVC *isvc =
             osi_malloc(sizeof(tBTA_GATTC_INCLUDED_SVC));
 
@@ -525,12 +552,11 @@ static void bta_gattc_char_disc_cmpl(UINT16 conn_id, tBTA_GATTC_SERV *p_srvc_cb)
     if (p_srvc_cb->total_char > 0)
     {
         /* add the first characteristic into cache */
-        bta_gattc_add_attr_to_cache (p_srvc_cb,
+        bta_gattc_add_char_to_cache (p_srvc_cb,
+                                     p_rec->char_decl_handle,
                                      p_rec->s_handle,
                                      &p_rec->uuid,
-                                     p_rec->property,
-                                     0 /* incl_srvc_handle */,
-                                     BTA_GATTC_ATTR_TYPE_CHAR);
+                                     p_rec->property);
 
         /* start discoverying characteristic descriptor , if failed, disc for next char*/
         bta_gattc_start_disc_char_dscp(conn_id, p_srvc_cb);
@@ -559,12 +585,11 @@ static void bta_gattc_char_dscpt_disc_cmpl(UINT16 conn_id, tBTA_GATTC_SERV *p_sr
     {
         p_rec = p_srvc_cb->p_srvc_list + (++ p_srvc_cb->cur_char_idx);
         /* add the next characteristic into cache */
-        bta_gattc_add_attr_to_cache (p_srvc_cb,
+        bta_gattc_add_char_to_cache (p_srvc_cb,
+                                     p_rec->char_decl_handle,
                                      p_rec->s_handle,
                                      &p_rec->uuid,
-                                     p_rec->property,
-                                     0 /* incl_srvc_handle */,
-                                     BTA_GATTC_ATTR_TYPE_CHAR);
+                                     p_rec->property);
 
         /* start discoverying next characteristic for char descriptor */
         bta_gattc_start_disc_char_dscp(conn_id, p_srvc_cb);
@@ -677,6 +702,7 @@ static tBTA_GATT_STATUS bta_gattc_add_char_to_list(tBTA_GATTC_SERV *p_srvc_cb,
         p_srvc_cb->total_char ++;
 
         p_rec->s_handle = value_handle;
+        p_rec->char_decl_handle = decl_handle;
         p_rec->property = property;
         p_rec->e_handle = (p_srvc_cb->p_srvc_list + p_srvc_cb->cur_srvc_idx)->e_handle;
         memcpy(&p_rec->uuid, &uuid, sizeof(tBT_UUID));
@@ -1173,7 +1199,7 @@ static void bta_gattc_get_gatt_db_impl(tBTA_GATTC_SERV *p_srvc_cb,
                                        btgatt_db_element_t **db,
                                        int *count)
 {
-    APPL_TRACE_DEBUG(LOG_TAG, "%s: start_handle 0x%04x, end_handle 0x%04x",
+    APPL_TRACE_DEBUG("%s: start_handle 0x%04x, end_handle 0x%04x",
                      __func__, start_handle, end_handle);
 
     if (!p_srvc_cb->p_srvc_cache || list_is_empty(p_srvc_cb->p_srvc_cache)) {
@@ -1339,6 +1365,14 @@ void bta_gattc_rebuild_cache(tBTA_GATTC_SERV *p_srvc_cb, UINT16 num_attr,
                 break;
 
             case BTA_GATTC_ATTR_TYPE_CHAR:
+                //TODO(jpawlowski): store decl_handle properly.
+                bta_gattc_add_char_to_cache(p_srvc_cb,
+                                            p_attr->s_handle,
+                                            p_attr->s_handle,
+                                            &p_attr->uuid,
+                                            p_attr->prop);
+                break;
+
             case BTA_GATTC_ATTR_TYPE_CHAR_DESCR:
             case BTA_GATTC_ATTR_TYPE_INCL_SRVC:
                 bta_gattc_add_attr_to_cache(p_srvc_cb,
index c74f7d2..d895864 100644 (file)
@@ -240,6 +240,8 @@ typedef struct
     tBT_UUID            uuid;
     UINT16              s_handle;
     UINT16              e_handle;
+    // this field is set only for characteristic
+    UINT16              char_decl_handle;
     BOOLEAN             is_primary;
     tBTA_GATT_CHAR_PROP property;
 }tBTA_GATTC_ATTR_REC;