DFU for external BLE Sensor

Hi,

  I have a current project that is based on the nRf52840.  This project acts both as a peripheral and a central.  I have a need to update the firmware on a remote BLE sensor using DFU, i.e., I need to do exactly what the nRfConnect application does when it updates a peripheral firmware via DFU.  My thought was to use the nRf52840 dongle and develop this code on my PC and then port it to my embedded system.  I also thought the best starting point would be the source code for the nRfConnect application which I would port it but I see from user comments that nordic did not release the source code for this.  Is it possible to get this source code or is there another example that demonstrates what I need to accomplish?

Thanks!

Parents
  • Hi,

      I am a bit confused and am hoping that you can help.  I have a Laird BT610 sensor and when I connect to it it does not show a Secure DFU service; however, I can do an over the air update of this sensor using nRfConnect and a proper firmware.bin file for this sensor. The sensor does advertise the SMP Serviice.  Is nRfConnect using this service to perform the firmware update?

    Thanks,

    Dave

  • Hi Dave,

    I am sorry for the confusion. I assumed your FW was based on our nRF5 SDK which uses a different DFU protocol.  So my initial reply does not apply to your case. As you may know, the nRF connect SDK is relying on the DFU protocol from MCUmgr for FW updates over BLE.

    Here are the MCUmgr libraries we use for our ios and android apps:

    https://github.com/NordicSemiconductor/Android-nRF-Connect-Device-Manager

    https://github.com/NordicSemiconductor/IOS-nRF-Connect-Device-Manager

    Best regards,

    Vidar

  • Hello,

    Thank you for your patience. I could not find any references to your SMP Client implementation inside the project you uploaded so I started a new project instead, please see attached. This is based on the ble_app_hrs_c example and the Nordic UART client service for the SMP implementation. I chose this example as a starting point because it already includes the peer manager module (adds bonding support) in case the Laird module requires authentication for the SMP service.

    I quickly tested this app against Zephyr's SMP sample here: SMP Server Sample using the default configuration with no authentication requirement and 1M PHY and verified that the attribute handles were assigned correctly.

    Some additional notes:

     - I set the scan filter to filter on the SMP UUID in the advertisment packet. You may add a new filter if you wish to filter on the device name instead.

    - NRF_BLE_SCAN_SCAN_PHY must be set to '4' in sdk_config.h to scan on CODED_PHY

    - The device will issue a bonding/security request upon connection if you set the SECURE_CONNECTION flag at the beginning of main.c

    - There are still missing pieces in the implementation. I mostly focused on the service discovery part. I expect any notifications from the SMP server to arrive in the BLE_SMP_C_EVT_SMP_TX_EVT event.

    Attachment (Note: requires nRF5 SDK 17.1.0 to build)

    ble_app_smp_c.zip

  • Thanks!!!   You are AWESOME!!  Now I can send and receive data and can actually start on the real implementation!  I may have more questions but now I have a great starting point...

  • Hi,

     Does nordic have a CBOR library that is suitable for use with my nRF SKD5 implementation?

    Thanks..

  • Hi,

    It looks like it should be straight forward to integrate tinycbor library we use in our nRF Connect SDK. The SDK is including the following files from the library: https://github.com/zephyrproject-rtos/tinycbor/blob/zephyr/zephyr/CMakeLists.txt which do not seem to have any external dependencies. 

  • Hi,

      Thanks to your help I have made significant progress towards uploading a new image via SMP but I need one more piece of information that I am hoping you could help me with.  What I need is an example of one Upload block for the DFU over SMP.  Note that I don't need the BLE overhead, just the DFU SMP data portion of the Upload Block.  What I am looking for is just the raw bytes that are sent for the Upload block.  Here is my attempt at creating and sending two Upload Blocks and the responses that I am getting back.

    // Data sent for block 0 of the upload

    A4 62 70 31 01 64 64 61 74 61 58 C0 3D B8 F3 96 00 00 00 00 00 02 00 00 FC A5 07 00 00 00 00 00 01 1B 02 00 C4 12 53 61 00 00 00 00 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 63 6C 65 6E 18 C0 63 6F 66 66 00 00

    I checked the CBOR through cbor.me it is valid CBOR data and I get the following...

    {"p1": 1, "data": h'3DB8F3960000000000020000FCA5070000000000011B0200C412536100000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF', "len": 192, "off": 0}

    When I send this I get the following response

    BF 62 72 63 00 63 6F 66 66 18 C0 FF

    cbor.me tells me this is the CBOR:  {"rc": 0, "off": 192}

    This seems like a valid response but when I try sending the 2nd block I get something back that is not valid.

    // Data sent for block 1 of the upload

    A4 62 70 31 01 64 64 61 74 61 58 C0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 63 6C 65 6E 18 C0 63 6F 66 66 18 C0

    I checked the CBOR through cbor.me it is valid CBOR data and I get the following...
    cbor.me: {"p1": 1, "data": h'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF', "len": 192, "off": 192}

    // Block #1 response - this is INVALID according to cbor.me
    BF 62 72 63 01 FF 6F 66 66 18 C0 FF

    Thanks,

    Dave 

Reply
  • Hi,

      Thanks to your help I have made significant progress towards uploading a new image via SMP but I need one more piece of information that I am hoping you could help me with.  What I need is an example of one Upload block for the DFU over SMP.  Note that I don't need the BLE overhead, just the DFU SMP data portion of the Upload Block.  What I am looking for is just the raw bytes that are sent for the Upload block.  Here is my attempt at creating and sending two Upload Blocks and the responses that I am getting back.

    // Data sent for block 0 of the upload

    A4 62 70 31 01 64 64 61 74 61 58 C0 3D B8 F3 96 00 00 00 00 00 02 00 00 FC A5 07 00 00 00 00 00 01 1B 02 00 C4 12 53 61 00 00 00 00 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 63 6C 65 6E 18 C0 63 6F 66 66 00 00

    I checked the CBOR through cbor.me it is valid CBOR data and I get the following...

    {"p1": 1, "data": h'3DB8F3960000000000020000FCA5070000000000011B0200C412536100000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF', "len": 192, "off": 0}

    When I send this I get the following response

    BF 62 72 63 00 63 6F 66 66 18 C0 FF

    cbor.me tells me this is the CBOR:  {"rc": 0, "off": 192}

    This seems like a valid response but when I try sending the 2nd block I get something back that is not valid.

    // Data sent for block 1 of the upload

    A4 62 70 31 01 64 64 61 74 61 58 C0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 63 6C 65 6E 18 C0 63 6F 66 66 18 C0

    I checked the CBOR through cbor.me it is valid CBOR data and I get the following...
    cbor.me: {"p1": 1, "data": h'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF', "len": 192, "off": 192}

    // Block #1 response - this is INVALID according to cbor.me
    BF 62 72 63 01 FF 6F 66 66 18 C0 FF

    Thanks,

    Dave 

Children
  • Hi,

    I am not familiar with the low level details of the mcumgr protocol or the cbor encoding, to be honest. But you can do DFU using the same image with nRF connect on Android or iOS, then inspect the log to see the cbor requests and responses that are being sent.

    Here is the log I got from nRF connect on iOS for reference:

    Let me know if this is not the data you are looking for.

    Vidar

  • Hi,

      The image you sent contains the log output from the DFU, this is one level above where the actual bytes are sent.  Although that contains most of the data for an Upload block it is missing some stuff, I am looking for a log at the byte level.  Something that shows the actual bytes being sent over the BLE, if I get this I will know how to extract the data I need:

    BLE Header (I don't really need this)
    SMP Header (this is 8 bytes)
    CBOR Data (this is variable length)

    If possible a file containing the raw bytes would be AWESOME.  Thanks so much for your help, once I get this piece of information I am sure I will be able to complete this project.

    Thanks,

    Dave

  • Hi,

      I figured it out and just had my first successful Image Upload!  I actually discovered "adb" which is android debug and set that up which allowed me to capture EVERYTHING that nRfConnect was sending while it was doing a firmware update of the sensor.  Then I used looked at the capture file with the Wireshark application which allowed me to see the raw bytes that were being sent.  Once I had that I was able to figure it out.  Really there is literally no decent documentation ANYWHERE that describes the DFU vis SMP process on a byte level which is what is needed if you are developing a solution from scratch. 

    Anyway, I wanted to thank you again for the help that you gave me, without that I would still be struggling. 

    Many Thanks,

    Dave Patton

  • Excellent! I did not even think of using debug logs from the phone. My plan was to try to log the data from the DFU target. I didn't get that far though. Not sure if I would have been able to log the data fast enough either.

    I will report the missing documentation as a feature request. Hopefully we can add it so others who are developing their own DFU clients in the future do not have to reverse engineer the protocol like you had to.

    Thanks for the update.

    Vidar

  • Hi,

    There is one piece of information that I have been unable to figure out.  The first block of data in the upload contains the entire image length and a "sha" field.  Below is a real example of the data in both binary and the "json" representation of the cbor data.  I need to know exactly what the "sha" is and how to calculate it so I can include the "sha" with my uploads.

    Binary data = SMPHeader|CBOR_Data packet: 020000f400010001bf646461746158d53db8f3960000000000020000fca5070000000000011b0100860e536100000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff636c656e1a0007a8936373686143525249636f666600ff

    SMPHeader: 020000f400010001

    CBOR_Data: bf646461746158d53db8f3960000000000020000fca5070000000000011b0100860e536100000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff636c656e1a0007a8936373686143525249636f666600ff

    cbor json: {"data": h'3DB8F3960000000000020000FCA5070000000000011B0100860E536100000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF', "len": 501907, "sha": h'525249', "off": 0}

    Thanks,

    Dave Patton

Related