BLE event handlers, why so many! Plz explain structure!

Afternoon folks,

I'm new to nordic, previously a TI developer. I'm still getting my head around the SDK. I've unfortunately been left with some poorly organised, very-un-annotated firmware to try and decipher. I am currently trying to get my head around the system for handling BLE events:

I'm new to BLE terminology and subsequently i have tried to find best terms to express my understanding, please bare with me:

The code i have. Runs 3 event handlers every time a device is connected (for example). In no particular order, these are: a generic "ble_evt_handler", the register observer for this is set up during BLE stack initialisation. The application also runs a "ble_cus" handler, the register observer for this is set up during a separate initialisation function, before the main superloop. This second handler, contains a function that sets another event, triggering a third event handler "ble_cus_evt_handler" this handler is seemingly associated with the individual service during the initialisation of the service. 

I have seen a similar structure implemented on a few examples, but these examples seemed to split events across the handlers, not pile all events blindly through all 3 handlers. 

1: What is the difference between all of the "smaller", more specific handlers, such as "gatt_evt_handler", "hrs_evt_handler" etc. and the seemingly more global "ble_evt_handler"?

2: Why do these "smaller" handlers need to contain functions that trigger a secondary handler, can the first handler not just service the event itself?

3: Do i really need 3 handlers for a simple event?

4: I come from a background of "simplicity leads to functioning reliable code" - If i were to rationalise this, knowing the application will likely not have a great number of different events to process, is there some way i can do without one or two of these handlers? 

Many thanks,

Sean Howson

-nRf52840 DK, SDK17.0.2, S140, segger embedded studio, windows 10.

Parents
  • Hi Sean

    It sounds a bit like the project you are looking at is based on the ble_app_uart project, and they replaced the ble_nus module (Nordic UART Service) with their own service called ble_cus. 

    1: What is the difference between all of the "smaller", more specific handlers, such as "gatt_evt_handler", "hrs_evt_handler" etc. and the seemingly more global "ble_evt_handler"?

    The main difference is that the ble_evt_handler will receive every single BLE related event from the Bluetooth stack (SoftDevice), and as such can receive a very wide number of different events. These are sorted into groups based on what part of the stack they originate from, such as the common BLE events, GAP , GATT client and GATT server events. 

    The gatt_evt_handler and hrs_evt_handler are associated with specific SDK modules, and will only forward event related to their domain. For example the gatt module will only forward events related to data length or MTU exchange, while the hrs module will only forward events related to the heart rate service. 

    Both of these modules will have their own BLE event handler (similar to ble_evt_handler), but will only filter out events that they care about, and trigger the gatt_evt_handler or hrs_evt_handler when there is something happening that the application might need to respond to. 

    2: Why do these "smaller" handlers need to contain functions that trigger a secondary handler, can the first handler not just service the event itself?

    Typically triggering a secondary handler is done to pass events up one layer in the application (from the gatt module to the application layer for instance). These modules will be self contained as much as it is reasonable, but certain events or state changes need to be forwarded to the caller of the module, which would be the application main file in most examples. 

    I agree it would be odd to have several handler forwards happening within one file or module, I don't think this is happening in any of the standard modules or examples, but I have seen cases where the ble_evt_handler would do some pre-filtering of events, and then forward the events to various other handlers based on the event type (you could have a ble_gap_evt_handler for only handling BLE_GAP events for instance). 

    3: Do i really need 3 handlers for a simple event?

    In the same file or module, no, but in the case of BLE events it is common to have a large number of modules that all register for BLE events, even if they all just care about a small subset of the events available. 

    4: I come from a background of "simplicity leads to functioning reliable code" - If i were to rationalise this, knowing the application will likely not have a great number of different events to process, is there some way i can do without one or two of these handlers? 

    It is a bit hard to answer this question without having a look at the implementation. Would it be possible for you to share the related code snippets, if not the whole application?

    I can make the case private, in case you don't want to share any code in a public ticket. 

    Best regards
    Torbjørn

  • It sounds a bit like the project you are looking at is based on the ble_app_uart project, and they replaced the ble_nus module (Nordic UART Service) with their own service called ble_cus.

    I think the project may be based on this tutorial by Nordic:

    https://github.com/NordicPlayground/nRF5x-custom-ble-service-tutorial

    It uses the name "cus" for the custom service, and also does the event handling in the way described.

Reply Children
No Data
Related