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
  • Hello,

    By default, enabling a notification doesn't write anything to flash. The examples ble_app_uart and ble_app_uart_c doesn't use flash at all (other than storing the application and softdevice in flash). It doesn't update anything in the flash during runtime, unless you have changed it to do so.

    So have you modified them to store something in flash during runtime?

    Best regards,

    Edvin

  • Dear Edvin, I've included NUS sources ble_nus.c and ble_nus_c.c into my own application which uses bonding and MITM so the only modification I've made is an increase of characteristic's security level to MITM.

  • Dear Edvin, what reply/ticket do you mean? I don't see any replies here other than yours.

  • Dear Edvin, could you kindly be more precise on answers? The ticket you referred to doesn't mention exact instructions, just a couple of ways (functions) which mean about nothing for me.

    sd_ble_gatts_sys_attr_get(SYS_ATTR_FLAG_SYS_SRVCS | SYS_ATTR_FLAG_USR_SRVCS) returns following array of data: 0xCACD000100020010. How should I interpret it?

  • 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

Reply
  • 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

Children
No Data
Related