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

sd_ble_gatts_value_set with const data

Hi

When implementing some characteristic handling i noticed, that in the newer softdevices the function "sd_ble_gatts_value_set" has changed to the following declaration: uint32_t sd_ble_gatts_value_set(uint16_t conn_handle, uint16_t handle, ble_gatts_value_t *p_value);

In the structure ble_gatts_value_t the member p_value points to the data to be written. As the type of p_value is "uint8_t *" i got a warning when using the function with a pointer to a constnant value. I ignored that by casting the pointer to (uint8_t *) because i assuemd, that when using the sturcture in sd_ble_gatts_value_set the data space won't be written. This actually work on target without a problem.

Yesterday i found out, that when this is used with serialization it is a problem. The serialization implementation of sd_ble_gatts_value_set somehow tries to write to the area the the p_value pointer points at. I did a quick fix for the probelm by copy the constant data into RAM anf us this area on the call of sd_ble_gatts_value_set.

I'm now not sure what is the right way to use sd_ble_gatts_value_set. If not necessairy i would prefere not to copy a value everytime it needs to be set. From my opinion the serialization should behave as much as possible like the softdevice itself.

How do you use the "sd_ble_gatts_value_set" function with constant data? Can the behavior of the serialisation be fixed to be equal to the softdevice?

Regards Adrian

Parents
  • Hi Adrian,

    typedef struct
    {
      uint16_t  len;        /**< Length in bytes to be written or read. Length in bytes written or read after successful return.*/
      uint16_t  offset;     /**< Attribute value offset. */
      uint8_t   *p_value;   /**< Pointer to where value is stored or will be stored. 
                                 If value is stored in user memory, only the attribute length is updated when p_value == NULL.
                                 Set to NULL when reading to obtain the complete length of the attribute value */
    } ble_gatts_value_t;
    

    As you can see that the len field will be updated by SD. That is the reason for the member being [in,out] So the behavior or newer softdevice and serialization code are compatible,

Reply
  • Hi Adrian,

    typedef struct
    {
      uint16_t  len;        /**< Length in bytes to be written or read. Length in bytes written or read after successful return.*/
      uint16_t  offset;     /**< Attribute value offset. */
      uint8_t   *p_value;   /**< Pointer to where value is stored or will be stored. 
                                 If value is stored in user memory, only the attribute length is updated when p_value == NULL.
                                 Set to NULL when reading to obtain the complete length of the attribute value */
    } ble_gatts_value_t;
    

    As you can see that the len field will be updated by SD. That is the reason for the member being [in,out] So the behavior or newer softdevice and serialization code are compatible,

Children
Related