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

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

Children
  • 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.

  • I see. Then I agree that it uses flash to store data.

    The peer manager uses the FDS (flash data storage) module to store peer data (encryption keys, BLE addresses and so on). Eventually the flash will fill up. If any of your peer manager or fds calls returns an error indicating that the flash is full, you should run fds_gc(). By default, I believe that the peer manager already did this, but maybe it isn't done correctly if you are missing some parts in the implementation. 

    If I understand your question correctly, you ask why the peer manager stores the notification state? This is because when the devices are bonded, the notification state needs to be stored for the next time they connect, so that they do not have to turn on the notification the next time they connect. It is part of the BLE spec.

    But it isn't much data that is stored each time, and the peer manager should clean the flash if it is full. Do you run into an issue with the full flash?

    Best regards,

    Edvin

  • Dear Edvin, I know that PM uses FDS including fds_gc(). But I don't receive any errors from FDS, flash isn't full for sure because I work with two fresh (erased) ICs. So each peer stores on flash the only data of one bond which is less than 100 bytes.

    It's great that PM stores notification state (I assumed the same in my original post) but I observe this state isn't restored on next connect - that's my question - see the log on Server:

    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: 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
    <here Client calls ble_nus_c_tx_notif_enable() even it was called on last connection>
    app: BLE_NUS_EVT_COMM_STARTED
    peer_manager_handler: Event PM_EVT_PEER_DATA_UPDATE_SUCCEEDED
    peer_manager_handler: Peer data updated in flash: peer_id: 0, data_id: Local database, action: Update

    Once again: if Client will not call ble_nus_c_tx_notif_enable() then Server will not be able to send data, ble_nus_data_send() will return NRF_ERROR_INVALID_STATE.

    Is there any alternative way for the Server to check a state of notification in local database? What type of data should be passed to pm_peer_data_load(PM_PEER_DATA_ID_GATT_LOCAL)?

  • Ok. So your issue is that the notification state is not stored, correct?

    What SDK version are you using?

  • Dear Edvin, if you (and spec) say that Server should store notification state then correct, I observe it's not (re)stored. I'm using SDK 15.2.0 and SD 6.1.0.

Related