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?

Reply Children
Related