Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Secure DFU, OTA failed scenario is not as expected

Hi,

I run the Secure DFU, and I'm doing OTA update without any issue.

The problem is the case that I'm doing an OTA update  with a application-version smaller than the one is currently in the board. The Prevalidate fails as expected and sends the respond to the phone. But, the bootloader will stuck and do noting. (I was expecting to get a reset here)

Logs:

-----------------------------

:INFO:Handling signed command
:INFO:Req version: 1, Present: 2
:INFO:Prevalidate FAILED!
:INFO:Sending Response: [0x4, 0xa]

(will stuck here.. )

-----------------------------

So, my question is that, Do I do something wrong here, or it's been like this by design?

SDK v12.3 -  NRF52 - SoftDevice S132 v3.0.0

Parents
  • Hi,

    The most likely reason for this is that you have DEBUG defined in your project.

    I expect that NRF_ERROR_INVALID_STATE is returned from the call to on_ctrl_pt_write() in this case, which should be caught by the APP_ERROR_CHECK(). The app_error_handler_bare() or app_error_handler() which calls app_error_fault_handler() behaves differently if DEBUG is defined or not. The state of the system will be preserved without a reset to ease debugging in case DEBUG is defined. However, NVIC_SystemReset() is called if DEBUG is not defined.

     

  • Hi Einar

    Thanks for you response and time. 

    That is exactly What I have was expecting, but not seeing in action. I'm pretty much sure that I don't have DEBUG defined.

    and if you take a look at the on_ctrl_pt_write() function, you would see the following code:

    case BLE_DFU_OP_CODE_EXECUTE_OBJECT:
                NRF_LOG_INFO("Received execute object\r\n");
    
                // Set req type
                dfu_req.req_type     =  NRF_DFU_OBJECT_OP_EXECUTE;
    
                res_code = nrf_dfu_req_handler_on_req(NULL, &dfu_req, &dfu_res);
                return response_send(p_dfu, BLE_DFU_OP_CODE_EXECUTE_OBJECT, res_code);

    nrf_dfu_handler_on_req will return a fail state as expected (the prevalidate failed), then it send the response the the mobile phone. when sending the response to the phone is successful, it would return success, noting else. 

    And, if you take a look at the on_ble_evt (inside nrf_ble_dfu.c), you would see the following code:

    case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST:
                if (p_ble_evt->evt.gatts_evt.params.authorize_request.type
                    != BLE_GATTS_AUTHORIZE_TYPE_INVALID)
                {
                    if (on_rw_authorize_req(&m_dfu, p_ble_evt))
                    {
                        err_code = on_ctrl_pt_write(&m_dfu, 
                               &(p_ble_evt->evt.gatts_evt.params.authorize_request.request.write));
    #ifdef NRF_DFU_DEBUG_VERSION  
                        if (err_code != NRF_SUCCESS)
                        {
                            NRF_LOG_ERROR("Could not handle on_ctrl_pt_write. err_code: 0x%04x\r\n", err_code);
                        }
    #else
                        // Swallow result
                        (void) err_code;
    #endif
                    }
                }
                break;

    the code I see, will swallow the return code of on_ctrl_pt_write(). 

    So, Am i tracking the issue in a wrong place?

  • You are absolutely right. The only way to continue from this state is to upgrade with a valid DFU image. This behavior has been remedied by the introduction of a inactivity timer in SDK 14, which triggers a reset if there has been no activity for some time. This is essentially a application timer that is restarted every time there is activity, and calls NVIC_SystemReset() if it times out, so it should not be much work to port it to SDK 12.3 if you want it. A simpler alternative if you want to reset if prevalidation failed is to just call NVIC_SystemReset() after logging "Prevalidate FAILED".

  • Hi Einar

    Ok, great. I wanted to make sure that I'm not doing anything wrong. 

    I will tell the Mobile Application developer guys to do the check before doing OTA in a first place. until we migrate the production code to SDK v14 at some point.

    Thanks again.

    BR

    Pouya

Reply Children
No Data
Related