This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Soft device enable and disable - [DFU] disconnected by the remote device

Hello all

I am facing a very strange issue, already searched the forum but didnt find anything like it.

Okay so I can get DFU to work. For our custom application we have to disable the soft device for some time for sensor acquisitions and re enable it at a later time for OTA upgrades.

I simply use nrf_sdh_disable_request() to de initialize the soft device successfully, which it does.

I later re - enable soft device using the standard ble calls in example code:

ble_stack_init();
    peer_manager_init();
    gap_params_init();
    gatt_init();
    advertising_init();
    services_init_2();
    conn_params_init();   
     
    //Start execution.
    application_timers_start();
    advertising_start(erase_bonds);

BLE gets initialized successfully, device is advertised and connects to as well. The problem is in DFU. When I attempt DFU, it keeps getting stuck into trying to switch to bootloader, repeatedly giving
"[DFU] disconnected by the remote device"

The logs then try to open the firmware file again, re initiating the process but nothing happen. I have spend quite some time on this and hit a blocker. Any help is appreciated. There must be a step I am missing during re-enabling the soft device

Parents
  • Hello,

    "[DFU] disconnected by the remote device"

    Where is this message printed? Is it in the mobile app on iOS or Android? And have you tried to debug the FW app to see if it hangs or enters the app_error_fault_handler() function?

    Okay so I can get DFU to work. For our custom application we have to disable the soft device for some time for sensor acquisitions and re enable it at a later time for OTA upgrades.

    Sure you really need to disable the Softdevice for this? The only case I can think of where it makes sense to disable the Softdevice is when there is a need to stop the LF clock. 

    Best regards,

    Vidar

  • Hi Vidar.
    I read an article here which said that in order to disable a service and re-enable it later, I need to disable the whole soft device as the services at start up become part of the "stack"

    if there is another way, please let me know. Basically I just want to disable the DFU service and show that service at some other point

    Also, this message appeared on the android app

  • Hi,

    AliMahmood123 said:
    Okay regarding this, I have removed the disconnect functionality from BLE_DFU_EVT_BOOTLOADER_ENTER_PREPARE event and the DFU still works. The connection seems to be maintained, so is the link encrypted in DFU mode or not?

    The transition from app to bootloader is transparent seen from the user. You have to view the debug logs in nRF connect to see that the connection gets terminated after ble_dfu_buttonless_bootloader_start_finalize() call in your main app, and re-established once the bootloader starts advertising again on the following boot.

    ble_dfu_buttonless_bootloader_start_finalize() will perform a system reset and cause the device to boot into the bootloader, which will then enter DFU mode and start connectable advertising.

    AliMahmood123 said:
    Okay so I can just set SEC_PARAM_BOND to 1 and not set DFU bond forwarding flags in sdk_config.h? Can I do that?

    Yes you can. Users still have to be bonded to initiate buttonless DFU as long as you have increased the sec. level of the buttonless characteristic.

    AliMahmood123 said:
    Do you mean that even if I dont include crypto libraries, and especially if I don't see BLE_GAP_EVT_LESC_DHKEY_REQUEST exchange, the link layer is encrypted? i.e, By just enabling bond forwarding conventional example. the layer is encrypted? I dont think so, what do you think?

    No, what I meant to say is that these crypto libraries are only used for the bonding procedure where the encryption key is exchanged. So you do need these libraries to support LESC bonding in the app. But the pairing method does not affect the security of the bootloader (not directly at least), it simply uses the app provided encryption key to secure the link.

    AliMahmood123 said:
    Dont I need to enable LESC associated flags in SDK and peer manager?

    Yes, if you want LESC bonding, and not legacy bonding.

  • Hmm
    So bottomline is that the session is not encrypted when I go into DFU Mode if I just pair from base firmware? RIght?

    Having said that, I managed to implement Bonding + LESC but its quite buggy I have to say, Sometimes there is GATT Error and what not, I'll update this post soon
    Also, with this implementation DFU only works in the second, third or even fourth try sometimes. It does upload, but after 50,60,70 % it just resets the device being unable to DFU. What could be the issue?

    Btw

    Yes you can. Users still have to be bonded to initiate buttonless DFU as long as you have increased the sec. level of the buttonless characteristic.

    This doesnt work, it was giving me error on ble_dfu_buttonless_async_svci_init(). I did secure the characteristic. Now I was assuming this occurred as the Bootloader supported bonds, but the application did not. Hence, I didnt move forward with it. What could be the issue?

    I just want my DFU to be encrypted btw, thats the ultimate goal.

  • ble_dfu_buttonless_bootloader_start_finalize() will perform a system reset and cause the device to boot into the bootloader, which will then enter DFU mode and start connectable advertising.

    Yes I know. I dont know much about connectable advertising though so please fill me in? The device auto connects and starts DFU instantly, but the key is lost in pairing mode then? The temporary key generated when the main app was running, it's gone then? That's why I need to bond and use the LTK?

  • This doesnt work, it was giving me error on ble_dfu_buttonless_async_svci_init(). I did secure the characteristic. Now I was assuming this occurred as the Bootloader supported bonds, but the application did not. Hence, I didnt move forward with it. What could be the issue?

    I just want my DFU to be encrypted btw, thats the ultimate goal.

    This indicates that the NRF_DFU_BLE_REQUIRES_BONDS setting in your bootloader does not match the one used in your app. They have to be set to the same. Otherwise, the SVC interface between the bootloader and app will not be compatible (Supervisor call interface).

    Steps to test DFU with bond farwing using the original SDK examples:

    1. Build the bootloader and and buttonless template app with NRF_DFU_BLE_REQUIRES_BONDS == 1

    2. Program bootloader, softdevice, app, and bootloader settings page to the target device

    3. Connect and bond with the target device using nRF connect app

    4. Upload a signed DFU package.

    That's why I need to bond and use the LTK?

    Yes this is why you need to bond. The short term key exchanged during pairing is only valid for the given connection, while a LTK will remain valid across connections.

  • They have to be set to the same.

    Didnt you say that I can just configure bonding and not set any DFU bonding flags in SDK? (See below my statement from the previous answer)

    Okay so I can just set SEC_PARAM_BOND to 1 and not set DFU bond forwarding flags in sdk_config.h? Can I do that?

    By the SDK bonding flags I meant this actually NRF_DFU_BLE_REQUIRES_BONDS.. Kindly verify. Sorry man I am a bit confused about this. It caught my eye when you said I can just set SEC_PARAM_BOND on the main app so that I can bond without setting anything DFU_ BOND related in BL or APP.

    I think it cant work without it, as the peer manager saves the session data while shifting from APP to DFU Mode BL

    Yes this is why you need to bond. The short term key exchanged during pairing is only valid for the given connection, while a LTK will remain valid across connections.

    Okay this is great, thanks I got it. Just wanna know out of curiosity the question at the start of the post.

    Regarding the problems I am facing when I configure NRF_DFU_BLE_REQUIRES_BONDS in both APP + BL + LESC
    Problems such as DFU retries and GATT errors, any ideas right off the bat? I will be sharing exact error logs here today itself though

Reply
  • They have to be set to the same.

    Didnt you say that I can just configure bonding and not set any DFU bonding flags in SDK? (See below my statement from the previous answer)

    Okay so I can just set SEC_PARAM_BOND to 1 and not set DFU bond forwarding flags in sdk_config.h? Can I do that?

    By the SDK bonding flags I meant this actually NRF_DFU_BLE_REQUIRES_BONDS.. Kindly verify. Sorry man I am a bit confused about this. It caught my eye when you said I can just set SEC_PARAM_BOND on the main app so that I can bond without setting anything DFU_ BOND related in BL or APP.

    I think it cant work without it, as the peer manager saves the session data while shifting from APP to DFU Mode BL

    Yes this is why you need to bond. The short term key exchanged during pairing is only valid for the given connection, while a LTK will remain valid across connections.

    Okay this is great, thanks I got it. Just wanna know out of curiosity the question at the start of the post.

    Regarding the problems I am facing when I configure NRF_DFU_BLE_REQUIRES_BONDS in both APP + BL + LESC
    Problems such as DFU retries and GATT errors, any ideas right off the bat? I will be sharing exact error logs here today itself though

Children
  • Didnt you say that I can just configure bonding and not set any DFU bonding flags in SDK? (See below my statement from the previous answer)

    Yes. This is also the default configuration used in the buttonless template example. That is, bonding enabled but no bond forwarding to the bootloader. So this configuration allows you to secure connections during normal use while the main app is running, but not when you are in DFU mode.

    The point is that NRF_DFU_BLE_REQUIRES_BONDS settings must match. You can't disable NRF_DFU_BLE_REQUIRES_BONDS in the app if it is enabled in the bootloader, and vice versa.

    By the SDK bonding flags I meant this actually NRF_DFU_BLE_REQUIRES_BONDS.. Kindly verify. Sorry man I am a bit confused about this. It caught my eye when you said I can just set SEC_PARAM_BOND on the main app so that I can bond without setting anything DFU_ BOND related in BL or APP.

    I think it cant work without it, as the peer manager saves the session data while shifting from APP to DFU Mode BL

    For Buttonless Secure DFU with bonds and encrypted connections during DFU, you must enable both SEC_PARAM_BOND and NRF_DFU_BLE_REQUIRES_BONDS

    Problems such as DFU retries and GATT errors, any ideas right off the bat? I will be sharing exact error logs here today itself though

    I need more to go on I'm afraid. This can be a lot of things. Can you try repeat the test with our pre-compiled app and bootloader to see if you experience the same issues?

    Testing Buttonless Secure DFU with bonds

  • For Buttonless Secure DFU with bonds and encrypted connections during DFU, you must enable both SEC_PARAM_BOND and NRF_DFU_BLE_REQUIRES_BONDS

    I got that now, Thanks.

    I need more to go on I'm afraid. This can be a lot of things. Can you try repeat the test with our pre-compiled app and bootloader to see if you experience the same issues?

    Yes I repeated it. The same issue persists in Buttonless DFU example with bonds but it's a bit lesser than my custom Secure bonds + LESC

    Buttonless example with Bonds

    1) GATT Write not Permit
    Happens mostly just once

    2) GATT Conn Timeout
    Happens mostly just once (Second try though). Sometimes both error occur together (1) and (2)

    3) DFU Retry

    Okay so after the above two errors which usually occur once (either ones). There is a guaranteed DFU retry, the peer gets disconnected.. idk why But it always happens and on the second retry its successful, but I have also noticed that the disconnection happens and the DFU restarts again on its own from 0%.

    2) Custom APP - Bonding + LESC

    Okay so the errors are same but the GATT errors sometimes occurs 3-4 times, and retry is also 2-3 times. It's mostly automatic, as in the DFU stops somewhere in between around 60% and retires again automatically. I also found it happening with just one retry too sometimes (like the example)

    Point is the issue is with example project as well. Btw we are making our own app so perhaps we can negate it, the DFU is always successful though, just retires and stuff.

    Note: In case of GATT error DFU has to be attempted again manually by user, in case of retries mostly it's automatic, in between of DFU it will start to re-attempt. Also regarding retry, the DFU always starts successfully at least.

    Its the final nail in the coffin Vidar... You have been of tremendous help

  • Hi,

    This is good progress. Though I don't think I have seen this instability problem before. Are you using the same phone for all your tests? My guess is that it might be a timing related issue. In that case, it's probably something you can work around in your app

    As a test, maybe you could try entering DFU mode manually through nrfconnect by following the message sequence chart here: Message sequence charts

  • Yes I am using the same phone, does that matter? I have an old Nokia 6.1 Plus though. It's not a very recent phone

    Okay I will try using nRF Connect and let you know, I'll use the dongle.

    Also, what kind of timing issue it might be?

  • Generally It shouldn't matter what phone you use, but sometimes it does, no devices are perfect. Please let me know if you experience the same behavior with the dongle.

    AliMahmood123 said:
    Also, what kind of timing issue it might be?

    It's hard to say. The disconnect during the transfer could be caused by drift on the LF clock (on either side of the link). A sniffer trace would likely provide some more clues.

Related