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

How to use new BLE_NUS_C module for multiple connections

I'm developing a central providing NUS client services to multiple concurrent peripherals. I had code working reliably under SDK 9.0.0 based on the NUS client example in github (the one that has NUS client code in file ble_uart_c.c). I'm trying to migrate to SDK 10.0.0 and use its new ble_nus_c.c module.

My old code used a single NUS client service and changed the conn_handle parameter in the NUS client structure depending on which client I wanted to send data to. Fortunately the old NUS client code in the ble_uart_c.c example called my NUS client event handler regardless of the conn_handle setting, so would generate RX events regardless of which peer they came from. However that method doesn't work with the new NUS client in SDK10.0.0, I only get RX events for the peer that connected most recently.

After examining the ble_nus_c.c file, I spotted that the ble_nus_c_on_ble_evt function rejects any events in which the conn_handle doesn't match the value specified in the NUS client structure. I've got my code working by changing:

void ble_nus_c_on_ble_evt(ble_nus_c_t * p_ble_nus_c, const ble_evt_t * p_ble_evt)
{
    if ((p_ble_nus_c == NULL) || (p_ble_evt == NULL))
    {
        return;
    }

    if ( (p_ble_nus_c->conn_handle != BLE_CONN_HANDLE_INVALID) 
       &&(p_ble_nus_c->conn_handle != p_ble_evt->evt.gap_evt.conn_handle) )
    {
        return;
    }
        
    switch (p_ble_evt->header.evt_id)
    {
        case BLE_GATTC_EVT_HVX:
            on_hvx(p_ble_nus_c, p_ble_evt);
            break;
        ...    

to:

void ble_nus_c_on_ble_evt(ble_nus_c_t * p_ble_nus_c, const ble_evt_t * p_ble_evt)
{
    if ((p_ble_nus_c == NULL) || (p_ble_evt == NULL))
    {
        return;
    }

    switch (p_ble_evt->header.evt_id)
    {
        case BLE_GATTC_EVT_HVX:
            p_ble_nus_c->conn_handle = p_ble_evt->evt.gattc_evt.conn_handle;   // Added to allow handler to determine which peer was source of data
            on_hvx(p_ble_nus_c, p_ble_evt);
            break;
         ...

This does seem very quick-and-dirty and I would rather not edit the Nordic component files. Is there a better way to achieve this?

Related