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?