Secure buttonless DFU operation fails when DFU service is enabled after initialization

Hello,

In my application (SDK, 16.0.0, nRF 52840) I need to enable the DFU service after initialization, which I do by exposing a custom service "DFU enable". This in turn allows to read/write a uint8_t property which I check in the code, inside the DFU enable callback function (executed on BLE_GATTS_EVT_WRITE). If this uint8 is equal to a hardcoded value I execute:

ble_dfu_buttonless_init_t dfus_init = {.evt_handler = ble_dfu_buttonless_evt_handler};

......

if(app_state.enable_key==0xCA) {
nrf_gpio_pin_write(LED_2,1);
ble_dfu_buttonless_init(&dfus_init);
}

The fact that LED_2 switches on only when I write 0xCA in the custom property assures that the logic is correct and, after all, once I write 0xCA and refresh the connection the DFU icon nicely pops out on the Nordic NRFConnect app (both on my smartphone and on desktop, using a Nrf52840SDK board). However, if I select the (correctly signed) .zip and try to update the device I get the following message:

DFU failed with error: Unable to find characteristic 8EC90001F3154F609FB8838830DAEA50 for service FE59 on device DA:A9:8D:E5:90:9E.0.

I should mention that when the DFU service is started at inizialization (with exactly the same command) the service is up and running and I can complete the DFU successfully with the same zip file.

Is there smtg that I should do in addition to enabling the DFU to correctly expose the new service? From the error message It seems like the required DFU characteristics cannot be found.

Thanks!

Stefano

Parents
  • Hi Stefano,

    I do not see any explanation for this, and I was not able to reproduce it with a slightly modified buttonless example in nRF5 SDK 16.0.0 (see below). Perhaps you also do some other changes? Can you explain/show?

    diff --git a/examples/ble_peripheral/ble_app_buttonless_dfu/main.c b/examples/ble_peripheral/ble_app_buttonless_dfu/main.c
    index 978be07..ae1929f 100644
    --- a/examples/ble_peripheral/ble_app_buttonless_dfu/main.c
    +++ b/examples/ble_peripheral/ble_app_buttonless_dfu/main.c
    @@ -406,13 +406,26 @@ static void nrf_qwr_error_handler(uint32_t nrf_error)
        }*/
     
     
    +static void dfu_thing_init(void)
    +{
    +    uint32_t                  err_code;
    +    ble_dfu_buttonless_init_t dfus_init = {0};
    +
    +    dfus_init.evt_handler = ble_dfu_evt_handler;
    +
    +    err_code = ble_dfu_buttonless_init(&dfus_init);
    +    APP_ERROR_CHECK(err_code);
    +
    +
    +}
    +
    +
     /**@brief Function for initializing services that will be used by the application.
      */
     static void services_init(void)
     {
         uint32_t                  err_code;
         nrf_ble_qwr_init_t        qwr_init  = {0};
    -    ble_dfu_buttonless_init_t dfus_init = {0};
     
         // Initialize Queued Write Module.
         qwr_init.error_handler = nrf_qwr_error_handler;
    @@ -420,10 +433,7 @@ static void services_init(void)
         err_code = nrf_ble_qwr_init(&m_qwr, &qwr_init);
         APP_ERROR_CHECK(err_code);
     
    -    dfus_init.evt_handler = ble_dfu_evt_handler;
     
    -    err_code = ble_dfu_buttonless_init(&dfus_init);
    -    APP_ERROR_CHECK(err_code);
     
         /* YOUR_JOB: Add code to initialize the services used by the application.
            uint32_t                           err_code;
    @@ -706,30 +716,12 @@ static void bsp_event_handler(bsp_event_t event)
     
         switch (event)
         {
    -        case BSP_EVENT_SLEEP:
    -            sleep_mode_enter();
    +        case BSP_EVENT_KEY_0:
    +            //sleep_mode_enter();
    +            NRF_LOG_INFO("Enable buttonless DFU service");
    +            dfu_thing_init();
                 break; // BSP_EVENT_SLEEP
     
    -        case BSP_EVENT_DISCONNECT:
    -            err_code = sd_ble_gap_disconnect(m_conn_handle,
    -                                             BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
    -            if (err_code != NRF_ERROR_INVALID_STATE)
    -            {
    -                APP_ERROR_CHECK(err_code);
    -            }
    -            break; // BSP_EVENT_DISCONNECT
    -
    -        case BSP_EVENT_WHITELIST_OFF:
    -            if (m_conn_handle == BLE_CONN_HANDLE_INVALID)
    -            {
    -                err_code = ble_advertising_restart_without_whitelist(&m_advertising);
    -                if (err_code != NRF_ERROR_INVALID_STATE)
    -                {
    -                    APP_ERROR_CHECK(err_code);
    -                }
    -            }
    -            break; // BSP_EVENT_KEY_0
    -
             default:
                 break;
         }
    

  • Dear Einar,

    Thanks for your answer. In the end what worked for me was to increase the NRF_SDH_BLE_VS_UUID_COUNT parameter in the sdk_config by the number of UUIDs added (I forgot that while adding the custom service). This was somehow troubling the DFU, even though the custom characteristic I added seemd to work fine anyhow. Do you have by any chance an explanation for that?

    Thank you.

    Regards,

    Stefano 

Reply
  • Dear Einar,

    Thanks for your answer. In the end what worked for me was to increase the NRF_SDH_BLE_VS_UUID_COUNT parameter in the sdk_config by the number of UUIDs added (I forgot that while adding the custom service). This was somehow troubling the DFU, even though the custom characteristic I added seemd to work fine anyhow. Do you have by any chance an explanation for that?

    Thank you.

    Regards,

    Stefano 

Children
Related