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

  • Hi, you have to add the SMP service's based UUID through the sd_ble_uuid_vs_add() call before you start service discovery. You may take a look at the ble_app_uart_c example to see how it's done there for the the NUS client service.

  • Hi,

      I am doing that, I am calling smp_c_init(); from my main, here is the code for that..

    static void smp_c_init(void)
    {
    	ret_code_t  err_code;
    	ble_smp_c_init_t init;
    
    	init.evt_handler = ble_smp_c_evt_handler;
    
    	err_code = ble_smp_c_init(&m_ble_smp_c, &init);
    	APP_ERROR_CHECK(err_code);
    }
    
    #define SMP_BASE_UUID                   {{0x84, 0xAA, 0x60, 0x74, 0x52, 0x8A, 0x8B, 0x86, 0xD3, 0x4C, 0xB7, 0x1D, 0x1D, 0xDC, 0x53, 0x8D}} /**< Used vendor specific UUID. */
    #define BLE_UUID_SMP_SERVICE            0x0001
    
    uint32_t ble_smp_c_init(ble_smp_c_t * p_ble_smp_c, ble_smp_c_init_t * p_ble_smp_c_init)
    {
        uint32_t      err_code;
        ble_uuid_t    smp_uuid;
        ble_uuid128_t smp_base_uuid = SMP_BASE_UUID;
    
        VERIFY_PARAM_NOT_NULL(p_ble_smp_c);
        VERIFY_PARAM_NOT_NULL(p_ble_smp_c_init);
    
        err_code = sd_ble_uuid_vs_add(&smp_base_uuid, &p_ble_smp_c->uuid_type);
        VERIFY_SUCCESS(err_code);
    
        smp_uuid.type = p_ble_smp_c->uuid_type;
        smp_uuid.uuid = BLE_UUID_SMP_SERVICE;
    
        p_ble_smp_c->conn_handle           = BLE_CONN_HANDLE_INVALID;
        p_ble_smp_c->evt_handler           = p_ble_smp_c_init->evt_handler;
        p_ble_smp_c->handles.smp_tx_handle = BLE_GATT_HANDLE_INVALID;
        p_ble_smp_c->handles.smp_status_handle = BLE_GATT_HANDLE_INVALID;
        p_ble_smp_c->handles.smp_buffer_handle = BLE_GATT_HANDLE_INVALID;
        p_ble_smp_c->handles.smp_rx_handle = BLE_GATT_HANDLE_INVALID;
    
        return ble_db_discovery_evt_register(&smp_uuid);
    }
    

    Also, here is the page that specifies the SMP UUID:  https://github.com/apache/mynewt-mcumgr/blob/master/transport/smp-bluetooth.md

    I think I have this initial part correct but I am not seeing what the nRFConnect app is seeing.

  • Hi,

    I do not immediately see any issues with the code you have posted. Would you mind posting the rest so I can try to debug it here?

    Thanks,

    Vidar

  • Hi,

      I bought a nRF52840 development kit so I could put my code in a project that you can debug.  I have attached the code.  It came from this directory which shoulkd provide the exact sdk I am using: C:\nRF5_SDK_17.0.2_d674dde\examples\ble_central My_ble_app_blinky_c.zip

    The BT610 device I am connecting to uses coded PHY.  I added a #define SCAN_FOR_CODED_PHY_DEVICES 1

    to enable scanning coded PHY devices, you can set that #define to 0 if the SMP device you will be connecting to does not use coded PHY.  Here is the output I am getting while running under the debugger...

    <info> app: Soft Device Ver: 10, SubVer: 0x100
    <info> app: on_adv_report()
    <info> app: Found BT610 we are looking for
    <info> app: dev_name.size: 5
    <info> app: Device Name: BT610Ô
    <info> app: ble_evt_handler, p_ble_evt->header.evt_id: 16
    <info> app: Connected.
    <info> app: call to ble_lbs_on_db_disc_evt for instance 0 and link 0x0!
    <info> app: p_evt->evt_type: 2, p_evt->params.err_code: 141570
    <info> app: p_evt->params.discovered_db.srv_uuid.uuid: 0x2902
    <info> app: p_evt->params.discovered_db.srv_uuid.type: 0x2
    <info> app: p_evt->params.discovered_db.char_count: 0
    <info> app: call to ble_lbs_on_db_disc_evt for instance 0 and link 0x0!
    <info> app: p_evt->evt_type: 3, p_evt->params.err_code: 536878616
    <info> app: p_evt->params.discovered_db.srv_uuid.uuid: 0x1E18
    <info> app: p_evt->params.discovered_db.srv_uuid.type: 0x0
    <info> app: ble_evt_handler, p_ble_evt->header.evt_id: 31
    <info> app: ble_evt_handler, p_ble_evt->header.evt_id: 18

    My goal right now is to discover the SMP characteristic that I can then use to write to.

    Thanks...

  • Hi,

      Just a little more information.  The sensor I am connecting to is a BT610 by Laird.  The BT610 firmware is built upon the Zephyr RTOS. Zephyr incorporates a complete device management subsystem. This is based upon Apache’s MCU Manager. The transport protocol defined by MCU Manager, the Simple Management Protocol (SMP) is used as the underlying protocol for all transport layers.  I can do a firmware upgrade of the sensor DFU over SMP using the nrfConnect application on my android.  I am definitely missing something, I can connect to the sensor but the discovery isn't completing successfully, that is what I need help with.

Reply
  • Hi,

      Just a little more information.  The sensor I am connecting to is a BT610 by Laird.  The BT610 firmware is built upon the Zephyr RTOS. Zephyr incorporates a complete device management subsystem. This is based upon Apache’s MCU Manager. The transport protocol defined by MCU Manager, the Simple Management Protocol (SMP) is used as the underlying protocol for all transport layers.  I can do a firmware upgrade of the sensor DFU over SMP using the nrfConnect application on my android.  I am definitely missing something, I can connect to the sensor but the discovery isn't completing successfully, that is what I need help with.

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

  • 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

Related