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

NUS Server does not restore notification state

Enabling or disabling notification on Client does always lead to an update of local database of Server by writing to its flash memory. Particularly NUS requires enabling of notification on each reconnection. Up to me flash memory of NUS Server's IC will fully degrade after about a dozen thousand of reconnections following this way. If I don't enable notification on NUS Client by skipping a call of ble_nus_c_tx_notif_enable() relying on everything was previously restored from database cache, NUS Server isn't able to send data. What is the reason to store anything on flash while it'll not be used (restored) when required?

Parents Reply Children
  • Hello,

    Sorry. I didn't mean to be imprecise. I am still trying to clarify whether you want the notification status to be stored but it is not being stored, or if the issue is something else?

    If that is the issue:

    When you are connected to the already bonded device. Can you then try to call sd_ble_gatts_sys_attr_get() with the current connection?

    The reason that I can't tell you exactly how to use it is because I haven't tested this functionality before. Is it possible to share your project, and I can give it a go.

    In your peripheral project:

    Do you call sd_ble_gatts_sys_attr_set in the BLE_GATTS_EVT_SYS_ATTR_MISSING event?

    Can you try to add the following in your ble_evt_handler():

    // near top of main.c:
    static volatile uint8_t * my_p_sus_attr_data;
    
    
    
    static void ble_evt_handler(...)
    {
        ret_code_t err_code;
    
        switch (p_ble_evt->header.evt_id)
        {
            case BLE_GAP_EVT_DISCONNECTED:
            {
                uint16_t * my_p_len;
                uint32_t flags = BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS | BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS;
                
                err_code = sd_ble_gatts_sys_attr_get(conn_handle, my_p_sus_attr_data, my_p_len, flags);
                APP_ERROR_CHECK(err_code);
                
                // Somehow, you need to store this data. my_p_sus_attr_data. 
                // For testing purposes  before you start doing this, you can just 
                // disconnect and reconnect, so that you don't have to store the data in flash.
            }break;
            
            case BLE_GATTS_EVT_SYS_ATTR_MISSING:
            {
                err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, my_p_sys_attr_data, len, flags);
                APP_ERROR_CHECK(err_code);
            }break;
        }    
    }   

    Best regards,

    Edvin

  • Dear Edvin, everything was much easier than we thought. After reading Automatically start notification upon connection event and How to know if the Notification/Indication of a Characteristic is enabled I've got a look into on_connect() handler in ble_nus.c, there's a call of sd_ble_gatts_value_get(), and the great mistake was in the name of the handle which we need to get a value of: rx_handles. Once I've changed it to tx_handles, the log on Server became as expected. Please report this bug to SDK team.

    peer_manager_handler: Event PM_EVT_BONDED_PEER_CONNECTED
    peer_manager_handler: Previously bonded peer connected: role: Peripheral, conn_handle: 0, peer_id: 0
    peer_manager_handler: Event PM_EVT_LOCAL_DB_CACHE_APPLIED
    peer_manager_handler: Previously stored local DB applied: conn_handle: 0, peer_id: 0
    app: BLE_NUS_EVT_COMM_STARTED <Server restored a notification state of just connected bonded Client>
    app: Connected to 0xXXXXXXXXXXXX
    peer_manager_handler: Event PM_EVT_CONN_SEC_START
    peer_manager_handler: Connection security procedure started: role: Peripheral, conn_handle: 0, procedure: Encryption
    peer_manager_handler: Event PM_EVT_CONN_SEC_SUCCEEDED
    peer_manager_handler: Connection secured: role: Peripheral, conn_handle: 0, procedure: Encryption

Related