This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

DFU with extra authentication

Hello, I want to put extra authentication when device is preparing for boot loader. I found callback  "ble_dfu_evt_handler". I think inside case  BLE_DFU_EVT_BOOTLOADER_ENTER_PREPARE , I can add that condition like below:

        case BLE_DFU_EVT_BOOTLOADER_ENTER_PREPARE:
        {
            NRF_LOG_INFO("Device is preparing to enter bootloader mode.");
            
            if(authentication_condition != true ){
                stop_DFU_api();
            }{
                // Prevent device from advertising on disconnect.
                ble_adv_modes_config_t config;
                advertising_config_get(&config);
                config.ble_adv_on_disconnect_disabled = true;
                ble_advertising_modes_config_set(&m_advertising, &config);

                // Disconnect all other bonded devices that currently are connected.
                // This is required to receive a service changed indication
                // on bootup after a successful (or aborted) Device Firmware Update.
                uint32_t conn_count = ble_conn_state_for_each_connected(disconnect, NULL);
                NRF_LOG_INFO("Disconnected %d links.", conn_count);
            }
            break;
        }

I am unable to find api to stop DFU process. Please suggest. Also let me know if this is correct way of doing same.

Thanks

Parents
  • HI Chandan, 

    the BLE_DFU_EVT_BOOTLOADER_ENTER_PREPARE event will be generated when ble_dfu_buttonless_bootloader_start_prepare is called. 

    uint32_t ble_dfu_buttonless_bootloader_start_prepare(void)
    {
        uint32_t err_code;
    
        // Indicate to main app that DFU mode is starting.
        mp_dfu->evt_handler(BLE_DFU_EVT_BOOTLOADER_ENTER_PREPARE);
    
        err_code = ble_dfu_buttonless_bootloader_start_finalize();
        return err_code;
    }

    As you can see ble_dfu_buttonless_bootloader_start_finalize() is called when the evt_handler has returned. So if you want to prevent the device from entering bootloader moder, then you will have to set a flag or similar when the extra authentication fails and then check this in ble_dfu_buttonless_bootloader_start_prepare() after the evt_handler has returned. One way to do this is as follows:

    uint32_t ble_dfu_buttonless_bootloader_start_prepare(void)
    {
        uint32_t err_code;
    
        // Indicate to main app that DFU mode is starting.
        mp_dfu->evt_handler(BLE_DFU_EVT_BOOTLOADER_ENTER_PREPARE);
        
        if(authentication_ok)
        {
            err_code = ble_dfu_buttonless_bootloader_start_finalize();
            return err_code;
        }else
        {
            //Authentication failed. Do not enter bootloader mode
            return NRF_ERROR_FORBIDDEN;
        }
    }

    Best regards

    Bjørn

  • Thanks for quick reply.

    I don't want to make change in any SDK file. Its difficult to update same change in all member's SDK file. Please suggest similar to callback function change.

  • If ble_dfu_buttonless_bootloader_start_prepare returns a non-zero error code, then the ble_dfu_evt_handler() will be called with the as BLE_DFU_EVT_BOOTLOADER_ENTER_FAILED as the event type. 

    static void on_hvc(ble_evt_t const * p_ble_evt)
    {
        uint32_t err_code;
        ble_gatts_evt_hvc_t const * p_hvc = &p_ble_evt->evt.gatts_evt.params.hvc;
    
        if (p_hvc->handle == m_dfu.control_point_char.value_handle)
        {
            // Enter bootloader if we were waiting for reset after hvc indication confimation.
            if (m_dfu.is_waiting_for_reset)
            {
                err_code = ble_dfu_buttonless_bootloader_start_prepare();
                if (err_code != NRF_SUCCESS)
                {
                    m_dfu.evt_handler(BLE_DFU_EVT_BOOTLOADER_ENTER_FAILED);
                }
            }
        }
    }

    Hence, you can restart advertisment in ble_dfu_evt_handler() under case BLE_DFU_EVT_BOOTLOADER_ENTER_FAILED:

  • Thanks, I can find only ble_advertising_start, but don't think its correct one. Found ble_advertising_restart_without_whitelist

  • I am getting error number 0x12 when calling ble_advertising_start().

  • 0x12 corresponds to NRF_ERROR_CONN_COUNT. Looking at the documentation for sd_ble_gap_adv_start which is called by ble_advertising_start

    @retval ::NRF_ERROR_CONN_COUNT The limit of available connections for this connection configuration
    * tag has been reached; connectable advertiser cannot be started.
    * To increase the number of available connections,
    * use @ref sd_ble_cfg_set with @ref BLE_GAP_CFG_ROLE_COUNT or @ref BLE_CONN_CFG_GAP.

    So you are in a connection when calling ble_advertising_start() and the NRF_SDH_BLE_PERIPHERAL_LINK_COUNT is set 1. So if you want to advertise, you will either have to disconnect the existing connection or increase the peripheral link count. Note you also have to increase the NRF_SDH_BLE_TOTAL_LINK_COUNT if you go for the second option. 

Reply
  • 0x12 corresponds to NRF_ERROR_CONN_COUNT. Looking at the documentation for sd_ble_gap_adv_start which is called by ble_advertising_start

    @retval ::NRF_ERROR_CONN_COUNT The limit of available connections for this connection configuration
    * tag has been reached; connectable advertiser cannot be started.
    * To increase the number of available connections,
    * use @ref sd_ble_cfg_set with @ref BLE_GAP_CFG_ROLE_COUNT or @ref BLE_CONN_CFG_GAP.

    So you are in a connection when calling ble_advertising_start() and the NRF_SDH_BLE_PERIPHERAL_LINK_COUNT is set 1. So if you want to advertise, you will either have to disconnect the existing connection or increase the peripheral link count. Note you also have to increase the NRF_SDH_BLE_TOTAL_LINK_COUNT if you go for the second option. 

Children
Related