Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

How to know if a characteristic requires a long read or not?

Hi,

I'm developing a central application and I want my central to read the device name characteristic from 3rd-party peripherals. I do not know the length of the data in the characteristic beforehand.

If the first time I call sd_ble_gattc_read() with offset 0, how can I know whether there is more data to be read?

When I receive the BLE_GATTC_EVT_READ_RSP event I have access to a "len" and an "offset" variable. The documentation states the following:

/**@brief Event structure for @ref BLE_GATTC_EVT_READ_RSP. */
typedef struct
{
  uint16_t            handle;         /**< Attribute Handle. */
  uint16_t            offset;         /**< Offset of the attribute data. */
  uint16_t            len;            /**< Attribute data length. */
  uint8_t             data[1];        /**< Attribute data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
                                           See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
} ble_gattc_evt_read_rsp_t;

Does len return the complete length of the attribute? Or is it just the length of the data read? If len is indeed the complete length of the attribute, how can I know the length of the data array?

Thanks for your help.

Parents
  • Hi Andy

    The len parameter is the number of bytes returned in this transaction, and will be limited by the MTU size. 

    As an example, say you have a device name of 30 bytes and an MTU of 23 (leaving 20 bytes for data), then the len parameter will be 20 when trying to read the device name with offset 0. 

    Then you should assume that there could be more data and issue another read request with offset 20. 

    On the second read the len will be 10, giving you the remaining 10 bytes, and since the len is lower than the maximum you will know that there is no more data to be read. 

    Best regards
    Torbjørn

  • Ok, so if I understand correctly, every time I do a read where (len == ATT_MTU - 3) I need to assume that there's more data and ask for it using offset 20.

    What happens if there isn't more data? Won't an error be thrown saying invalid offset or something like that? I don't see that in the documentation but somehow I recall reading something about invalid offset somewhere.

    If there isn't such a thing as an invalid offset, I assume then the operation would return an event with len = 0.

  • Hi Andy

    That is correct. If you post a read with an offset that is too large you will get an error in return. 

    Best regards
    Torbjørn

  • What error? The documentation for sd_ble_gattc_read() states this:

     * @retval ::NRF_SUCCESS Successfully started or resumed the Read (Long) procedure.
     * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
     * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
     * @retval ::NRF_ERROR_BUSY Client procedure already in progress.
     * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.

Reply
  • What error? The documentation for sd_ble_gattc_read() states this:

     * @retval ::NRF_SUCCESS Successfully started or resumed the Read (Long) procedure.
     * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
     * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
     * @retval ::NRF_ERROR_BUSY Client procedure already in progress.
     * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.

Children
Related