This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

How to get current length of variable length attribute?

According to https://devzone.nordicsemi.com/f/nordic-q-a/3497/sd_ble_gatts_value_get/12659#12659, it appears that sd_ble_gatts_value_get() can only return the maximum length of a variable-length attribute. Is that correct?

If so, how can one get the current length, other that accessing the init-data passed to characteristic_add()?

Thanks!

Parents
  • Hi, 

    sd_ble_gatts_value_get() can Get the value of a given attribute. 

    If the attribute value is longer than the size of the supplied buffer, ble_gatts_value_t::len will return the total attribute value length (excluding offset), and not the number of bytes actually returned in ble_gatts_value_t::p_value. The application may use this information to allocate a suitable buffer size. When retrieving system attribute values with this function, the connection handle may refer to an already disconnected connection. Refer to the documentation of sd_ble_gatts_sys_attr_get for further information.

    -Amanda H.

  • Amanda,

    Updated to correct and clarify!

    Yep, I've tried setting len to 0 and p_value to NULL; both return the current length. The title should be "How to get the maximum length of a variable length attribute", but I don't know how to edit the title ;)

    My test code:

    ret_code_t GetAttrMaxLength(uint16_t conn_handle, uint16_t attr_handle, uint16_t* max_length) 
    {
        VERIFY_PARAM_NOT_NULL(max_length);
        uint8_t buffer;
        ble_gatts_value_t   gatts_value = 
        {
            .len     = 0,
            .p_value = &buffer
        };
    
        const ret_code_t err_code = sd_ble_gatts_value_get(conn_handle, attr_handle, &gatts_value);
        VERIFY_SUCCESS(err_code);
    
        *max_length = gatts_value.len;
    
        return err_code;
    }
    
    /********************************************************************************************//**
     ************************************************************************************************/
    ret_code_t GetAttrLength(uint16_t conn_handle, uint16_t attr_handle, uint16_t* length)
    {
        VERIFY_PARAM_NOT_NULL(length);
        ble_gatts_value_t   gatts_value = 
        {
            .len     = 0,
            .p_value = NULL
        };
    
        const ret_code_t err_code = sd_ble_gatts_value_get(conn_handle, attr_handle, &gatts_value);
        VERIFY_SUCCESS(err_code);
    
        *length = gatts_value.len;
    
        return err_code;
    }

    For example:

    • 4 byte variable length attribute with an initial 1 byte value
    • Both of the above functions return 1 byte
    • Write a 4 byte value to the attribute, both of the above return 4 bytes.
  • Hi, 

     If there are several writes to one handle, calling sd_ble_gatts_value_get() may only return the value of the last write.

    Please also see this post

    -Amanda H.

  • Makes sense for the current length; return the number of bytes last written.

    So, the SDK doesn't provide a way to get an attributes maximum length?

  • Hi,

    Why do you need to ask the softdevice for the max length?

    The max length is provided from the application to the softdevice when you declare the characteristic. The max length of an attribute is defined when they define the attribute. For example here:

    So the application just needs to store that value somewhere. I don't see the point of having the softdevice to tell the max length.

    -Amanda H.

  • So I don't have to store it redundantly and I can have a library of GATT access functions that only need the attribute handle.

    I'll take this as a "No, you can't get the maximum length from a SoftDevice".

Reply Children
No Data
Related