Matter : SRP update error: domain name or RRset is duplicated when using external flash for settings_storage using "nordic,qspi-nor" compatible flash.

First, I'm using an NRF connect 2.3.0 and applying the light_bulb sample with a custom nrf52840 board with an external is25wp064a flash using QSPI.

Moving the settings_storage to the external flash I had problems commissioning the device using HomeKit (previously worked with the internal flash), I always got the error [DL] Error from SRP Update: The domain name or RRset is duplicated.

I'm using "nordic_qspi_nor" compatible flash.

After several investigations and troubleshooting and inspired by the answer for case 300157 (also referring to the openthread issue https://github.com/openthread/openthread/issues/8056), where it says that SRP updates are signed at using ECDSA.
Adding additional traces, I first realized that openthread wanted to save the ECDSA_KEY setting from a word unaligned memory location which will lead the nrfx_qspi code to return an NRFX_ERROR_INVALID_ADDR error from the qspi_xfer function.
Apparently the qspi_nor_write function (in nrf_qspi_nor.c the base code) only calls the write_from_nvmc function for "src" memory not in ram (!nrfx_is_in_ram), and does not test its alignment.
Thus, by adding in the qspi_nor_write function the condition (!nrfx_is_word_aligned) to force a call to the write_from_nvmc function for an unaligned memory source, remove the NRFX_ERROR_INVALID_ADDR error.
However, for the commissioning to happen totally, that was not enough, the saved ECDSA_KEY is corrupted, reading the parameter Openthread got a key with the last 2 bytes with a value that is not the same at the time he save it!
Further investigation into the write_from_nvmc function when openthread tries to save ECDSA_KEY reveals to me another problem in the write_from_nvmc function itself.
if the length of the buffer to write (slen) is not a multiple of CONFIG_NORDIC_QSPI_NOR_STACK_WRITE_BUFFER_SIZE than the case of an ECDSA_KEY, the nrfx_qspi_write function is always called using sizeof(buf) as tx_buffer_length.
To handle this case it has to be called using the "len" variable which is the min between the remaining part and the buffer size.

By changing "res = nrfx_qspi_write(buf, sizeof(buf), addr);" with "res = nrfx_qspi_write(buf, len, addr);" now solve the last problem preventing the commission from happening.
I can now commission the device using HomeKit having the setting saved in the external flash :-)
Looking at the latest version in GitHub https://github.com/nrfconnect/sdk-zephyr/blob/main/drivers/flash/nrf_qspi_nor.c , it looks like the latest version of the code still doesn't fix this issue.
Can you take a look and see if these qspi_nor_write issues can be officially resolved.

Thank you Best regards
Parents
  • Hi, 

    The error Error from SRP Update: The domain name or RRset is duplicated.means that in the Thread network there is already a device with given nodeid and other credentials. SRP updates are signed ECDSA indeed, and if they realized that there is a problem with saving credentials it may be the root cause of the issue. I can see that they tried to provide the specific length of the buffer instead of its maximum length, and that seems good in this case. Unfortunately, we don't have 25wp064a flash memory since we're using mx25r64 in our DKs, so it can be hard to confirm that solution directly, and we haven't seen that issue on mx25r64. I guess, that solution may be helpful also for other customers who use different flash memories and Zephyr nordic_qspi_nor . BTW, are you commissioning the device to Matter or HomeKit?

    Regards,
    Amanda H.

  • Hello,

    I'm commissioning Matter using an APPLE TV as border router (via Apple home, aka "HomeKit").

    As I'm using the same QSPI setup, which are used by the NRF nrf52840dk_nrf52840, you should have the same problem using the nrf52840dk board.

    Just Create a project using Matter light_bulb sample using an nrf52840dk board as build configuration.

    When the sample is working well in your environment, change the config to save openthread settings in the external flash.

    Normally, as this example use QSPI using "nordic_qspi_nor" compatible flash, you will be faced to the same issue.

    To save setting in the external flash, if I'm remembering well, here what I did: 

    Add the following to the project config (prj.conf):

    # Need this when storage is on 25wp064a
    CONFIG_NORDIC_QSPI_NOR=y
    CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096
    CONFIG_SETTINGS_NVS=y
    CONFIG_SETTINGS_NVS_SECTOR_COUNT=4
    Change the pm_static_dfu.yml to move the "settings_storage" (use the name of your device instead :
    mcuboot:
        address: 0x0
        size: 0x7000
        region: flash_primary
    mcuboot_pad:
        address: 0x7000
        size: 0x200
    app:
        address: 0x7200
        size: 0xf3e00
    mcuboot_primary:
        orig_span: &id001
            - mcuboot_pad
            - app
        span: *id001
        address: 0x7000
        size: 0xf4000
        region: flash_primary
    mcuboot_primary_app:
        orig_span: &id002
            - app
        span: *id002
        address: 0x7200
        size: 0xf3e00
    factory_data:
        address: 0xfb000
        size: 0x1000
        region: flash_primary
    gap:
        address: 0xfc000
        size: 0x4000
        region: flash_primary
    mcuboot_secondary:
        address: 0x0
        size: 0xf4000
        device: MX25R64
        region: external_flash
    external_flash:
        address: 0xf4000
        size: 0x60c000
        device: MX25R64
        region: external_flash
    settings_storage:
        address: 0x00700000
        size: 0x00100000
        device: MX25R64
        region: external_flash
     

    I hope I'm not forgetting any step :-)

    If any question do not hesitate.

    Regards

    Didier

  • Hi, 

    We do not support moving settings to the external flash. It was not tested by us and there are no plans to do so. First of all, it raises a lot of security concerns, and we do not recommend it. Do you use some kind of encryption? Also as access to external flash is slower, we cannot guarantee that code will work correctly if some actions are more time sensitive. What is the reason to put the settings to external flash?

    -Amanda H.

  • Hello,

    Thanks you for the clarification indeed storing keys in external flash is raising security concerns. And based on it, I will certainly change my mind.

    The reason why I want to put setting to external flash is to re-use setting feature (library) to save my own application setting.

    As these settings have an high level rate of changes, I want to use larger external flash to take care of the live time of the flash.

    If there is no way to keep sensitive settings on internal flash and using the same setting library to keep larger/volatile settings to external flash, I will certainly use an others approach to save the later one.

    Concerning the two issues of the "nordic_qspi_nor" module described in my first post, there are independent of the use case.

    The qspi_nor_write base code does not support today to write (qspi_nor_write) memory source which are either word unaligned and not a multiple of CONFIG_NORDIC_QSPI_NOR_STACK_WRITE_BUFFER_SIZE.

    I hope it is clarifying the problem.

    Thanks & Regards

    Didier

  • Hello

    Do you have any update concerning the two issues of the "nordic_qspi_nor" module described in my first post ?

    Thanks & Regards

    Didier

     

  • Hi, 

    From the team:

    Both observations are valid. The driver should support writing from an unaligned buffer in RAM, but it currently does not handle such transactions correctly, and the function incorrectly writes the last part when CONFIG_NORDIC_QSPI_NOR_STACK_WRITE_BUFFER_SIZE is above 4. The proposed fix for the latter problem (replacing sizeof(buf) with len) is correct. But I believe the first problem, although the proposed solution would work, should be handled differently. The write_from_nvmc function should be used only when the source buffer is not in RAM. For an unaligned RAM buffer, only its beginning and ending sub-words should be written separately (using write_sub_word()) and the middle part (aligned and properly sized) should be written directly using nrfx_qspi_write().

    Regards,
    Amanda H.

Reply Children
Related