This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Need help understanding the behavior of `sd_ble_gatts_hvx()`

Update 2016-Mar-29: I used SDK v10 along with SoftDevice S110 v8 when I run the experiments described in this question.

Update 2016-Mar-30: Upload source code of the modified NUS module used in the experiments: test_characteristic.zip

I am modifying a copy of ble_nus.c (from SDK v10) to test the behavior of characteristics bigger than 20 bytes. Here is how I have the notifying part of ble_nus_string_send() modified to try to send a RX characteristic notification with new value length over 20.

uint32_t err_code;
uint16_t nTransactions = length/20;
int16_t i;
uint16_t tempU16;

hvx_params.handle = p_nus->rx_handles.value_handle;

if ((length % 20) != 0)
{
    nTransactions += 1;
}

// for (i = nTransactions - 1; i > -1; i--)
for (i = 0; i < nTransactions; i++)
{
    hvx_params.p_data = &p_string[i * 20];
    hvx_params.offset = i * 20;
    tempU16 = (length - i * 20) ;
    if (tempU16 > 20)
    {
        tempU16 = 20;
    }
    hvx_params.p_len    = &tempU16;
    hvx_params.type     = BLE_GATT_HVX_NOTIFICATION;
    err_code = sd_ble_gatts_hvx(p_nus->conn_handle, &hvx_params);
    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }
}

Of course I have also modified the characteristic sizes to BLE_GATTS_VAR_ATTR_LEN_MAX. I also enable read permission of the RX characteristic for my little experiment. My question is at the behavior of the code.

Both way of running the for loop (commented out way and the active way) only result in Android version of Master Control Panel receiving notification of the first 20 byte of the p_string I passed to the function. However:

  • With for (i = 0; i < nTransactions; i++), when I read the RX characteristic value, I have all the bytes of the p_string I tried to notify.

    For example, if I call with p_string = "01234567890123456789ABC", I will get a notify of value "01234567890123456789", but if I read, I can read all "01234567890123456789ABC"

  • With for (i = nTransactions - 1; i > -1; i--) I only got the first 20 byte of p_string, the rest is lost.

    For example, if I call with p_string = "01234567890123456789ABC", I will get a notify of value "01234567890123456789", and when I read, I could still only get "01234567890123456789"

I have tested with up to 59 bytes sent. I assume little would change with more/fewer bytes. So I have two questions:

  1. Why is there such a difference? Could it be due to how sd_ble_gatts_hvx() is implemented?

  2. Is there any way to perform a notification for more than 20 byte at all? Apparently this does not work. Back in 2013 a Nordic employee said that it was impossible, but I hope things have changed.

Parents
  • Please specify the version of the SoftDevice you are using.

    As for your questions, first I need to know what the "TX" characteristic value is. when you call sd_ble_gatts_hvx() you are sending data directly and storing it at the same time in the local attribute that you are notifying. I also need to know if the characteristic you are notifying is set as fixed or variable length when you add it to the Attribute Table.

    [EDITED]

    1. When you notify a characteristic, you can choose to specify an offset and a length and that will modify the characteristic value inside the Attribute Table in RAM. However, the notification (or indication) packet itself will always send the first ATT_MTU-3 bytes of the characteristic value. In this case ATT_MTU = 23 so only the first 20 bytes of the characteristic will be sent. So to sum up: offset and length will affect the value inside the SoftDevice's RAM, but the packet going out will always only contain the first 20 bytes of the value.

    2. Not yet, but this will come very soon.

    Carles

  • I've edited my answer above, the response to question 1)

Reply Children
No Data
Related