Attribute Caching

I am trying to implement Attribute caching as described in Vol 3, part G, section 2.5.2 of the Bluetooth Core Spec.

  • Reading the GATT Database Hash seems to work:
    • The bt_gatt_read returns zero
    • The callback function returns a zero “err” parameter
  • However:
    • the callback also returns a “length” of 3 (I would expect a 1 (if the return is a “field”) or a 16 (if the return is an array of bytes))
    • the bytes are not what I would expect – they don’t match my reference db hash.
    • an Ellisys trace does not show the Read by UUID ATT Transaction I would expect
  • I expect I am not configuring the bt_gatt_read_params correctly - here's the relevant code snippet:

// Callback for GATT DB Hash read

static uint8_t unicast_client_read_func_cb(struct bt_conn *conn, uint8_t err,

                                                                                struct bt_gatt_read_params *read, const void *data,

                                                                                uint16_t length)

{

                LOG_INF("TEC - unicast_client_read_func_cb: conn %p err %u read %p data 0x%032x length 0x%02x\n",

                                (void *)conn, err, (void *)read, data, length);

                for (int i = 0; i < 32; i++) {

                                LOG_INF("TEC - unicast_client_read_func_cb: data[%0d] = 0x%02x", i, ((uint8_t *)data)[i]);

                }              

                return BT_GATT_ITER_STOP;

}

 

int unicast_client_gatt_db_hash_read(struct bt_conn *conn)

{

                LOG_INF("TEC - unicast_client_gatt_db_hash_read: conn %p\n", (void *)conn);

                int ret;

                struct stream_index idx;

                static struct bt_gatt_read_params read_params;

                struct bt_gatt_read_params* read_params_ptr = &read_params;

                ret = device_index_get(conn, &idx);

                LOG_INF("TEC - device_index_get ret %d idx %d,%d,%d\n", ret, idx.lvl1, idx.lvl2, idx.lvl3);

                if (ret) {

                                return ret;

                }

                (*read_params_ptr).func = unicast_client_read_func_cb;

                (*read_params_ptr).by_uuid.uuid = BT_UUID_GATT_DB_HASH_VAL; // GATT DB Hash UUID

                (*read_params_ptr).by_uuid.start_handle = 0x0001;

                (*read_params_ptr).by_uuid.end_handle = 0xffff;

                (*read_params_ptr).handle_count = 0;

                ret = bt_gatt_read(conn, read_params_ptr);

                if (ret) {

                                LOG_WRN("Failed to read gatt db hash: %d", ret);

                                return ret;

                }

                return 0;

}

Parents
  • Hi,

    Interesting. 

    First memset the read_prams_ptr before use as a good practice.

    Are you sure that you are setting the uuid correct here?
    (*read_params_ptr).by_uuid.uuid = BT_UUID_GATT_DB_HASH_VAL; 

    Shouldn't this be set to BT_UUID_GATT_DB_HASH?

    Also guard your callback when data == NULL when you return BT_GATT_ITER_STOP else you keep on looping on the GATT iterations even though you see no data.

  • Excellent! Step 1 achieved.  The key was the uuid itself - using BT_UUID_GATT_DB_HASH solved my immediate problem.  I'll work with my FW expert on code cleanup - implementing your other suggestions - now that we've got read by uuid working.  I'm sure we'll have more questions as we continue to implement Attribute caching.

    Thanks for your prompt and accurate response!

    Tom

Reply Children
No Data
Related