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

Duplicate Events - Periph + Central Database Discovery SDK14

I am moving an SDK12 peripheral nus + central nus application to SDK14.

I am following the ble_app_hrs_rscs_relay example for SDK14 on how to setup the dual role ble event dispatching, but i am getting duplicate nus-c discovery events when I start the db_discovery.

Here is my softdevice handler ble_event_handler

static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
{
    uint16_t conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
    uint16_t role = ble_conn_state_role(conn_handle);

    // Based on the role this device plays in the connection, dispatch to the right handler.
    if (role == BLE_GAP_ROLE_PERIPH || ble_evt_is_advertising_timeout(p_ble_evt))
    {
	//ble_nus_on_ble_evt(p_ble_evt, &m_nus);
	on_ble_peripheral_evt(p_ble_evt);
    }
    else if ((role == BLE_GAP_ROLE_CENTRAL) || (p_ble_evt->header.evt_id == BLE_GAP_EVT_ADV_REPORT))
    {
        //ble_nus_c_on_ble_evt(p_ble_evt, &m_ble_nus_c);
	on_ble_central_evt(p_ble_evt);
    }
}

This is definitely routing my correctly to find the advertising packets in on_ble_central_evt -> BLE_GAP_EVT_ADV_REPORT
 

I call sd_connect which succeeds and gives me BLE_GAP_EVT_CONNECTED.  Code below:

case BLE_GAP_EVT_CONNECTED:
	    NRF_LOG_INFO("GAP-C Connected to Peripheral.");
	    APP_ERROR_CHECK(err_code);

            if (nus_central_handle == BLE_CONN_HANDLE_INVALID )
            {
              // start discovery of services. The NUS Client waits for a discovery result
              memset(&m_ble_db_discovery, 0, sizeof(m_ble_db_discovery));
              err_code =
                  ble_db_discovery_start(&m_ble_db_discovery[0], p_ble_evt->evt.gap_evt.conn_handle);
              APP_ERROR_CHECK(err_code);
              nus_central_handle = p_ble_evt->evt.gap_evt.conn_handle;
            }
	    break; // BLE_GAP_EVT_CONNECTED

The problem is that ble_db_discovery_start is only called once (I have verified from RTT output and setting breakpoints), yet I am getting duplicate BLE_NUS_C_EVT_DISCOVERY_COMPLETE in my ble_nus_c_evt_handler

static void ble_nus_c_evt_handler(ble_nus_c_t * p_ble_nus_c, ble_nus_c_evt_t const * p_ble_nus_evt)
{
    ret_code_t err_code;

    switch (p_ble_nus_evt->evt_type)
    {
	case BLE_NUS_C_EVT_DISCOVERY_COMPLETE:
	    NRF_LOG_INFO("NUS-C Discovery complete.");
	    err_code = ble_nus_c_handles_assign(
	        p_ble_nus_c, p_ble_nus_evt->conn_handle, &p_ble_nus_evt->handles);
	    APP_ERROR_CHECK(err_code);

	    err_code = ble_nus_c_tx_notif_enable(p_ble_nus_c);

	    APP_ERROR_CHECK(err_code);
	    NRF_LOG_INFO("NUS-C Peripheral Found.");
	    break;

It seems to me like events are being called without going through the ble_event_handler . Comparing my code to the SDK14 example, I would think these events should be going through the soft-device handler ble_event_handler  and that I would need ble_nus_c_on_ble_evt(p_ble_evt, &m_ble_nus_c) in ble_event_handler in order to get events to ble_nus_c_evt_handler

I am seeing a similar issue with my nus peripheral.  I would think I should need to include ble_nus_on_ble_evt(p_ble_evt, &m_nus);  in ble_nus_c_evt_handler in order to handle events from the nus peripheral service.  However, i am getting NUS events even without this.

Is there some setting I have messed up in setting up a dual role application?  I feel like the soft device event handler ble_event_handler is not working correctly or at least in the same way it did using SDK12.

Parents
  • Hello,

    If you look in the SDK14\examples\ble_central\ble_nuc_c example you can see that there is no function called ble_event_handler. There is also no dispatch function, like there was in the older SDKs.

    From SDK14.0.0, the instances are initialized in the macros near the top of the main.c file, such as BLE_NUS_C_DEF(m_ble_nus_c). You can see in the definition of this macro(in ble_nus_c.h), that the event handler is set here, ble_nus_c_on_ble_evt(). Therefore, you do not need to include the ble_nuc_c_on_ble_evt() function in ble_event_handler(). It is already set up when you initialize the ble_nuc_c instance in the BLE_NUS_C_DEF macro.

    Best regards,
    Edvin

  • Edvin,


    Thanks, that is helpful to understand how the events are being setup using the macros.

    The issue I believe was that I used the BLE_DB_DISCOVERY_ARRAY_DEF(m_ble_db_discovery, 2);from the dual mode example when I should have just used the single discovery instance of LE_DB_DISCOVERY_DEF(m_ble_db_discovery);

Reply Children
  • One issue that has come up from the SDK14 and the way it handles the events to the services is that my NUS Central was receiving events from the NUS Peripheral.

    I added this to my ble_nus_c_on_ble_evt.  I did the opposite for the ble_nus_on_ble_evt.  Perhaps there is a recommended my to do this other than this but this seems to work for me.

        uint16_t conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
        uint16_t role = ble_conn_state_role(conn_handle);
    
        // Based on the role this device plays in the connection, dispatch to the right handler.
        if (role == BLE_GAP_ROLE_PERIPH )
        {
            return;
        }

Related