Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Bug in Discovery Module ble_db_discovery.c

This is on SDK 15: Not all services are reported when doing service discovery on more than one connection at a time.

Basically, 'ble_db_discovery.c' uses 'm_pending_usr_evt_index' to keep track of the number of services discovered, and when all services for a connection is discovered, it reports it to the higher layer handling function as a BLE_DB_DISCOVERY_COMPLETE event. However, this variable (m_pending_usr_evt_index) is cleared when a new service discovery starts. So if one service discovery is busy and another start, the variable is cleared for both discovery processes and the first discovery process loses track of its discovered services resulting in the already discovered services to never be reported to the higher layer driver.

An easy fix is to simply send the BLE_DB_DISCOVERY_COMPLETE event as soon as one service is discovered and not to wait for all services to be discovered. Alternatively m_pending_user_evts and m_pending_usr_evt_index must be adjusted to have a specific instance for each connection.

Parents Reply Children
  • Hi

    My code is based on SDK 15.0 so it might have already been fixed. Regardless, here is what I did:

    In the ble_db_discovery.c is a function called "discovery_complete_evt_trigger". At the end of the function instead of incrementing the events counter and then sending the events as a bundle to the higher layer handlers, I simply send the event immediately. Here is the change I made:

    m_pending_user_evts[m_pending_usr_evt_index].evt_handler = p_evt_handler;
    
    // +++++ I added the following line to send every event as it is received and leave it to the upper layer driver to handle the individual events
    m_pending_user_evts[0].evt_handler(&(m_pending_user_evts[0].evt));
    
    /* +++++ The below part is what I removed
    m_pending_usr_evt_index++;
    
    if (m_pending_usr_evt_index == m_num_of_handlers_reg)
    {
        // All registered modules have pending events. Send all pending events to the user
        // modules.
    	NRF_LOG_ERROR("x%d%dx",conn_handle,m_pending_usr_evt_index);
        pending_user_evts_send();
    }
    else
    {
        // Too many events pending. Do nothing. (Ideally this should not happen.)
    	NRF_LOG_ERROR("x%d%dx",conn_handle,m_pending_usr_evt_index);
    }*/

    This is not a perfect fix but works great for me.

    Hope it helps.

Related