CCCD change not written to flash after BLE Write (Server)

Hello,

I am currently developing a firmware where I am acting as a server with nRF52840.

The protocol of my use case is:

  1. Client is connecting to my device (server with bonding)
  2. Client sets notification enabled (is written to flash by the server as PM_EVT_PEER_DATA_UPDATE_SUCCEEDED event indicates)
  3. Client is writing to a custom characteristic
  4. Client wants to set notification disabled (I receive the event that it is written to CCCD but I don't get the PM_EVT_PEER_DATA_UPDATE_SUCCEEDED event and nothing is written to the flash, since I want to store the information for reconnecting with the bonded device)

Do I have to handle the write to the CCCD on my own or could there be a problem with writing to my characteristic?

Note: When no write is executed, just notification enabling and disabling, everything works fine and is stored to flash.

best regards 

Parents
  • I am guessing that you are connecting, bonding, enabling notifications, and turning off the server/peripheral. 

    By default, the CCCD values are stored after the disconnect event, but if you disconnect by turning off the power, then obviously, that will not happen.

    You can add this to your prj.conf file:

    CONFIG_BT_SETTINGS_CCC_STORE_ON_WRITE=y

    Which will cause it to store it at once instead. Please see the description of the config BT_SETTINGS_CCC_STORE_ON_WRITE from NCS\zephyr\subsys\bluetooth\host\Kconfig:

    config BT_SETTINGS_CCC_STORE_ON_WRITE
    	bool "Store CCC value immediately after it has been written"
    	depends on BT_CONN
    	default y
    	help
    	  Store Client Configuration Characteristic value right after it has
    	  been updated. If the option is disabled, the CCC is only stored on
    	  disconnection.

    Try that, and see if it helps.

    Best regards,

    Edvin

Reply
  • I am guessing that you are connecting, bonding, enabling notifications, and turning off the server/peripheral. 

    By default, the CCCD values are stored after the disconnect event, but if you disconnect by turning off the power, then obviously, that will not happen.

    You can add this to your prj.conf file:

    CONFIG_BT_SETTINGS_CCC_STORE_ON_WRITE=y

    Which will cause it to store it at once instead. Please see the description of the config BT_SETTINGS_CCC_STORE_ON_WRITE from NCS\zephyr\subsys\bluetooth\host\Kconfig:

    config BT_SETTINGS_CCC_STORE_ON_WRITE
    	bool "Store CCC value immediately after it has been written"
    	depends on BT_CONN
    	default y
    	help
    	  Store Client Configuration Characteristic value right after it has
    	  been updated. If the option is disabled, the CCC is only stored on
    	  disconnection.

    Try that, and see if it helps.

    Best regards,

    Edvin

Children
  • Thanks for the reply. After I want to disable notification I am disconnecting from the device. So there is no poweroff or something like that.

    I did some debugging and discovered that when I first write something to characteristic 1, and I want to enable/disable characteristic 2. I get the event that something is written to UUID 0x2902 (as BLE_GATTS_EVT_WRITE indicates) but afterwards there is nothing written to flash. When I am not writting to characteristic 1 in the first place, everything works fine with enabling/disabling notification on characteristic 2. Might there be a problem with memory size somehow? Since characteristic 1 has a size of 510 bytes..? I did some debugging in the peer manager as well and I reach this function in the gatt_cache_manager.c with correct parameters:

    case BLE_GATTS_EVT_WRITE:
                if (cccd_written(&p_ble_evt->evt.gatts_evt.params.write))
                {
                    local_db_update(conn_handle, true);
                    update_pending_flags_check();
                }
                break;

    But after that, nothing is written to flash and this only after I did a write to characteristic 1 before. Might there be a chance that I am blocking the fds module somehow when I receive the write event in the first place form characteristic 1?

    Thanks for your help

    best regards

  • Oh, sorry. I thought you were using NCS, not the nRF5 SDK. Never mind what I said in the previous reply then.

    KonstantinK said:
    But after that, nothing is written to flash and this only after I did a write to characteristic 1 before

    What connection parameters are you using? Does it work with one of the examples that use bonding by default in the SDK if you test?

    And what exactly is it that is not working? Updating the CCCD value that is stored in flash?

    Best regards,

    Edvin

  • My connection parameters are:

    MIN_CONN_INTERVAL                   MSEC_TO_UNITS(100, UNIT_1_25_MS)
    MAX_CONN_INTERVAL                   MSEC_TO_UNITS(200, UNIT_1_25_MS)        
    SLAVE_LATENCY                       0                                       
    CONN_SUP_TIMEOUT                    MSEC_TO_UNITS(4000, UNIT_10_MS)    

    Are these values good to go or should I use other?

    Yes, the updating of CCCD values is not correct. The new value gets written to the CCCD but the new value is not stored to flash. (when doing a write on a characteristic before). Have you ever experienced something like this before? 

  • Edit: After more debugging I discovered following:

    1. First connect (everything works and central and peripheral are bonded)

    2. Writing to a characteristic (BLE_GATTS_EVT_WRITE occurred and value is written to characteristic)

    3. Disconnecting

    4. Reconnecting (Device is not recognized as peer and is doing rebonding)

    Note: If I am doing the steps 1., 3. and 4. Device is recognized as already bonded peer

    Any ideas where the issue might be? 

  • Hello,

    It sounds like the bonding data is being erased on disconnect for some reason. It could be because the FDS storage is full as you indicated earlier and that  pm_handler_flash_clean()/pm_handler_flash_clean_on_return() is called. Or do you see the same if you do a full chip erase before you program your FW? 

    FDS usage can be monitored with the fds_stat() function.

Related