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

S110 v7 HVX notification bug

I am not sure, but i think we found bug or some interesting feature in sending notification values.

Here is the code i used:

uint32_t ble_meas_on_ext_adc_change(ble_meas_t * p_meas, uint32_t adcread){

uint32_t err_code = NRF_SUCCESS;
static uint8_t _sampling_counter;
if(adcread != p_meas->ext_adc_last_state)
{
    _sampling_counter++;
    uint16_t len = 5;
    uint8_t buffer[5];
    memcpy(buffer, (void *)&adcread, sizeof(uint32_t));
    buffer[4] = _sampling_counter;
    p_meas->ext_adc_last_state = adcread;
    err_code = sd_ble_gatts_value_set(p_meas->ext_adc_char_handles.value_handle,
                                      0,
                                      &len,
                                      buffer);
    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }
    if((p_meas->conn_handle != BLE_CONN_HANDLE_INVALID) && p_meas->ext_adc_is_notification_enabled)
    {
        ble_gatts_hvx_params_t params;
        memset(&params, 0, sizeof(params));
        len = sizeof(uint16_t);
        params.handle   = p_meas->ext_adc_char_handles.value_handle;
        params.type     = BLE_GATT_HVX_NOTIFICATION;
        params.p_len    = &len;
        params.p_data   = (uint8_t *)&adcread;
        return sd_ble_gatts_hvx(p_meas->conn_handle, &params);
    }
}
return err_code;
}

On the beginning i check if last reading from ADC is different comparing to new value (adcread). Next, I copy the value to 5byte buffer and add _sampling_counter. I succesfully set whole buffer as characteristic value. To this point, everything is clear.

And now comes black magic - I want to send notification with this new value, and i set p_len as 2 bytes (which is so wrong - should be 5 bytes!) and p_data as (uint8_t *)&adcread (adcread still contains only 4 bytes, which is my fault again - it should be buffer instead).

So if everything would work correctly, i assume that HVX notification should only contain 2 first bytes of adcread, but when i receive it on my central device, i got all 5 bytes from buffer[] which i actually wanted to receive. What is going on here? Does hvx notification ignore p_data and sends data stored in characteristic value?

Parents
  • Hi there,

    Both notifications and indications will send the complete contents of the characteristic value (up to the MTU or Maximum Transmission Unit currently active).

    Your characteristic is probably 5 bytes long and fixed length (i.e. you did not set the ble_gatts_attr_md_t :: vlen bit when creating it) meaning that what you are actually doing is modifying only the first 2 bytes of the 5 but then sending the contents of the value to the peer. Since the characteristic is fixed length, even if you write it only partially the length remains 5, and the whole 5 bytes are sent as a notification.

    Hope that helps,

    Carles

Reply
  • Hi there,

    Both notifications and indications will send the complete contents of the characteristic value (up to the MTU or Maximum Transmission Unit currently active).

    Your characteristic is probably 5 bytes long and fixed length (i.e. you did not set the ble_gatts_attr_md_t :: vlen bit when creating it) meaning that what you are actually doing is modifying only the first 2 bytes of the 5 but then sending the contents of the value to the peer. Since the characteristic is fixed length, even if you write it only partially the length remains 5, and the whole 5 bytes are sent as a notification.

    Hope that helps,

    Carles

Children
No Data
Related