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,

      I have my app scanning the BT610 which in fact a Zephyr RTOS based device.  I have attached a screen shot of the connection that nRfConnect app makes to this sensor.

    I have successfully scanned and made a connection to this BT610 sensor from my application but I am not seeing the characteristics and UUID that I am expecting during the discovery phase.  I have added a bunch of print statements in the discovery handler as shown here:  

    static void db_disc_handler(ble_db_discovery_evt_t *p_evt)
    {
    	ble_gatt_db_char_t * p_chars = p_evt->params.discovered_db.charateristics;
    
    	print_trace("call to ble_lbs_on_db_disc_evt for instance %d and link 0x%x!", p_evt->conn_handle, p_evt->conn_handle);
    	print_trace("p_evt->evt_type: %d", p_evt->evt_type);
    	print_trace("p_evt->params.discovered_db.srv_uuid.uuid: 0x%X", p_evt->params.discovered_db.srv_uuid.uuid);
    	print_trace("p_evt->params.discovered_db.srv_uuid: 0x%X", p_evt->params.discovered_db.srv_uuid.type);
    	for (uint32_t ii = 0; ii < p_evt->params.discovered_db.char_count; ii++) {
    		print_trace("p_chars[%d].characteristic.uuid.uuid: 0x%X, Type: 0x%X", ii, p_chars[ii].characteristic.uuid.uuid, p_chars[ii].characteristic.uuid.type);
    	}	
    }
    This is what is being printed..

    <info> app: trace:1634844344:p_evt->evt_type: 2
    <info> app: trace:1634844344:p_evt->params.discovered_db.srv_uuid.uuid: 0x1
    <info> app: trace:1634844344:p_evt->params.discovered_db.srv_uuid: 0x3
    <info> app: trace:1634844344:call to ble_lbs_on_db_disc_evt for instance 0 and link 0x0!
    <info> app: trace:1634844344:p_evt->evt_type: 2
    <info> app: trace:1634844344:p_evt->params.discovered_db.srv_uuid.uuid: 0x1523
    <info> app: trace:1634844344:p_evt->params.discovered_db.srv_uuid: 0x5
    <info> app: trace:1634844344:call to ble_lbs_on_db_disc_evt for instance 0 and link 0x0!
    <info> app: trace:1634844344:p_evt->evt_type: 2
    <info> app: trace:1634844344:p_evt->params.discovered_db.srv_uuid.uuid: 0x1
    <info> app: trace:1634844344:p_evt->params.discovered_db.srv_uuid: 0x6
    <info> app: trace:1634844344:call to ble_lbs_on_db_disc_evt for instance 0 and link 0x0!
    <info> app: trace:1634844344:p_evt->evt_type: 2
    <info> app: trace:1634844344:p_evt->params.discovered_db.srv_uuid.uuid: 0x1
    <info> app: trace:1634844344:p_evt->params.discovered_db.srv_uuid: 0x7

    The p_evt->evt_type: 2 indicates BLE_DB_DISCOVERY_SRV_NOT_FOUND (Event indicating that the service was not found at the peer).  Can you shed some light on why I am getting BLE_DB_DISCOVERY_SRV_NOT_FOUND back?  I am expecting to get what the nRfConnect application sees?

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

Reply
  • 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...

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

Related