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

How to use BLE_GATTS_VLOC_USER ?

Do I still have to call sd_ble_gatts_value_set() on the characteristic handle [using whatever temporary buffer I would have been using anyway for BLE_GATTS_VLOC_STACK]?

Or can I simply modify the referenced buffer, and characteristic reads will magically start returning the updated buffer value? (I am not using rd_auth for characteristic reads; the ble_gatts_attr_md_t for the characteristic has rd_auth=0.)

Thanks!

Parents
  • Ah, I understand the problem with variable-length attributes, so things would break without rd_auth.

    We keep the actual (current) length and the maximum length in the stack memory space, the only thing that exists in app memory space is the value itself. When you add an attribute (characteristic, descriptor, whatever) you specify both current length and max length, and if you are using VLOC_USER you just need to make sure that the buffer you provide is at least max_len bytes long. However, if that attribute is variable length then of course you need to tell the stack if the length changes (this is not needed if the peer device writes to it changing the length, since at that point the stack already knows about the new length, it is only needed if you want to change it locally). Currently the only way to do this is via sd_ble_gatts_value_set().

    So if variable-length attributes are being used with VLOC_USER, then sd_ble_gatts_value_set() must be called? If the characteristic value is large, is there any way to avoid the memcpy penalty in sd_ble_gatts_value_set()?

    Yes, and no. This is unfortunate, we realize. Stay tuned for updates on this issue.

    Would it be OK to call sd_ble_gatts_value_set() with the correct p_len, but then to specify a NULL p_value (since the value is VLOC_USER)? That should satisfy the softdevice bookkeeping for variable-length attributes without actually unnecessarily copying data around?

    No, today sd_ble_gatts_value_set() only accepts valid pointers. If you call with a NULL pointer you will get an error back and no values will be changed inside the stack.

    Carles

Reply
  • Ah, I understand the problem with variable-length attributes, so things would break without rd_auth.

    We keep the actual (current) length and the maximum length in the stack memory space, the only thing that exists in app memory space is the value itself. When you add an attribute (characteristic, descriptor, whatever) you specify both current length and max length, and if you are using VLOC_USER you just need to make sure that the buffer you provide is at least max_len bytes long. However, if that attribute is variable length then of course you need to tell the stack if the length changes (this is not needed if the peer device writes to it changing the length, since at that point the stack already knows about the new length, it is only needed if you want to change it locally). Currently the only way to do this is via sd_ble_gatts_value_set().

    So if variable-length attributes are being used with VLOC_USER, then sd_ble_gatts_value_set() must be called? If the characteristic value is large, is there any way to avoid the memcpy penalty in sd_ble_gatts_value_set()?

    Yes, and no. This is unfortunate, we realize. Stay tuned for updates on this issue.

    Would it be OK to call sd_ble_gatts_value_set() with the correct p_len, but then to specify a NULL p_value (since the value is VLOC_USER)? That should satisfy the softdevice bookkeeping for variable-length attributes without actually unnecessarily copying data around?

    No, today sd_ble_gatts_value_set() only accepts valid pointers. If you call with a NULL pointer you will get an error back and no values will be changed inside the stack.

    Carles

Children
Related