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

NRF_SDH_BLE_EVT_BUF_SIZE very large

I'm trying to configure an application queue to hold BLE events I receive from the SoftDevice.  The SDK defines NRF_SDH_BLE_EVT_BUF_SIZE as the "Size of the buffer for a BLE event."  Ultimately, the value of NRF_SDH_BLE_EVT_BUF_SIZE is related to NRF_SDH_BLE_GATT_MAX_MTU_SIZE, as the event has to house any associated GATT data.

However if I set NRF_SDH_BLE_GATT_MAX_MTU_SIZE to 251, the value of NRF_SDH_BLE_EVT_BUF_SIZE goes to 508--over twice the size of the MTU!  I would expect size of NRF_SDH_BLE_EVT_BUF_SIZE to be roughly sizeof(ble_evt_t) + NRF_SDH_BLE_GATT_MAX_MTU_SIZE, which would be 48 + 251 = 299.  Instead its 209 bytes bigger.

This appears to be the result of the BLE_EVT_LEN_MAX macro, which is defined as

#define BLE_EVT_LEN_MAX(ATT_MTU) ( \
offsetof(ble_evt_t, evt.gattc_evt.params.prim_srvc_disc_rsp.services) + ((ATT_MTU) - 1) / 4 * sizeof(ble_gattc_service_t) \
)

Looking at the expression, this seems to imply that the event size is related to how many services I might receive from a GATT server while acting as a GATT client.  But my application doesn't act as a GATT client.

So how do I determine the maximum size of an event for my use case?  And where is this formula documented?

--Jay

Parents
  • The macro was trying to set the buffer aside for when the biggest chunk is needed.

    If you have a closer look it is not about the server, but about the GATT client, and how long buffer it is required to fetch the maximum length packet (after it has been parsed) from the SoftDevice. And this have been calculated to be the Service Discovery response, and it is dependent on the ATT MTU size

      

Reply
  • The macro was trying to set the buffer aside for when the biggest chunk is needed.

    If you have a closer look it is not about the server, but about the GATT client, and how long buffer it is required to fetch the maximum length packet (after it has been parsed) from the SoftDevice. And this have been calculated to be the Service Discovery response, and it is dependent on the ATT MTU size

      

Children
  • Thanks for your response.

    If you have a closer look it is not about the server, but about the GATT client, and how long buffer it is required to fetch the maximum length packet (after it has been parsed) from the SoftDevice. And this have been calculated to be the Service Discovery response, and it is dependent on the ATT MTU size

    Indeed.  That's was exactly my point: The buffer is sized so that a client can receive and process a full MTU-sized Service Discovery response from a server.

    However, in my application, the node is acting as a server only.  Furthermore, it only has one application-defined service.  Therefore it can never generate, nor receive, a Service Discovery response that consumes the full MTU size (251).

    So the question remains: How do I determine the maximum size of an event that will be generated by the SoftDevice in my application?  And where is this formula documented?

    --Jay

  • I am not certain on the exact need of max event buffer need for GATTS only device.

    You can try to change the nrf_sdh_ble_evts_poll() function in nrf_sdh_ble.c in a way that

    1. Reserve a big chunk of buffer for evt_buffer (way larger than we need)
    2. it calls sd_ble_evt_get first with NULL as first argument to get the size of the event length This will update the second parameter with the size of the incoming event.
    3. if the evt_len is larger than previously saved last_known_evt_len_max, then update last_known_evt_len_max with this new size.
    4. call sd_ble_evt_get now with event_buffer (instead of NULL)
    5. Run your program for some time and test all your features.
    6. Get the value of last_known_evt_len_max after all your tests are done.
    7. Readjust your evt_buffer to only have this size. and remove the logic to save last_known_evt_len_max (we do not need this anymore)

    This seems a bit crude but will definitely help you to reduce the buffer size to be fine tuned to your needs. I should do some tests when I have some free time to see which other use case takes max event_buffer for GATTS only device.

  • Certainly doable, although I worry that it would be difficult in practice to exercise all cases that produce extreme event sizes.

    A better solution would be a way to identify all events that are of variable length (perhaps a standardized marker in the documentation), along with a formula/macro for calculating the size.  Additionally (and this would be useful for other reasons) we need a table that enumerates all SoftDevice events along the general scenarios in which the event can occur (when acting as a GATT client, when acting as a GATT server, when using feature A, when using feature B, etc.).

    In theory I can collect all of the above information.  However the surface area of the SoftDevice is vast, and probably like most people, I don't understand all of it yet.  So it would be better if the experts at Nordic provides this information and keep it up to date.

  • However the surface area of the SoftDevice is vast, and probably like most people, I don't understand all of it yet.  So it would be better if the experts at Nordic provides this information and keep it up to date.

    I agree that this information could be very handy. I will pass the information to the softdevice team to evaluate this and provide the detail info at some point. 

    Thanks for your feedback.

Related