nRF52832 buttonless DFU without bonds failed

I use nRF Connect to test  buttonless DFU without bonds failed. But nRF52832 receives BLE_GATTS_EVT_SYS_ATTR_MISSING event.

->static void ble_evt_handler(ble_evt_t const* pBleEvt, void* pContext)
->{
->    ret_code_t errCode = NRF_SUCCESS;
->   
->   switch (pBleEvt->header.evt_id)
->   {
->       case BLE_GAP_EVT_CONNECTED:
->       {
->           NRF_LOG_INFO("BLE_GAP_EVT_CONNECTED\n");
->           BLE_UART_SetState(BLE_NUS_STATE_CONNECT);
->           errCode = bsp_indication_set(BSP_INDICATE_CONNECTED);
->           if (errCode != NRF_SUCCESS) {
->               NRF_LOG_WARNING("bsp_indication_set() failed, errCode=0x%x\n", errCode);
->               return;
->           }    
->
->           m_cur_conn_handle = pBleEvt->evt.gap_evt.conn_handle;
->
->           errCode = nrf_ble_qwr_conn_handle_assign(&m_qwr, m_cur_conn_handle);
->           if (errCode != NRF_SUCCESS) {
->               NRF_LOG_WARNING("nrf_ble_qwr_conn_handle_assign() failed, errCode=0x%x\n", errCode);
->               return;
->           }
->       }    
->       break;
->
->       case BLE_GATTS_EVT_SYS_ATTR_MISSING:
->       {
->           NRF_LOG_INFO("BLE_GATTS_EVT_SYS_ATTR_MISSING\n");
->           // No system attributes have been stored.
->           errCode = sd_ble_gatts_sys_attr_set(pBleEvt->evt.gap_evt.conn_handle, NULL, 0, 0);
->           APP_ERROR_CHECK(errCode);
->       }
->...
->}

-> Code0> <debug> nrf_ble_gatt: Requesting to update ATT MTU to 185 bytes on connection 0x0.
 0> <info> app: BLE_GAP_EVT_CONNECTED
 0>
 0> <debug> app: state=1
 0>
 0> <debug> nrf_ble_gatt: ATT MTU updated to 185 bytes on connection 0x0 (response).
 0> <info> app: BLE_GATTS_EVT_SYS_ATTR_MISSING

Parents
  • Hi, 

    What SDK version are you using?

    I use nRF Connect to test  buttonless DFU without bonds failed.

    Can you provide the log from the nRF Connect? 

    Please try to erase the kit before programming. 

    Regards,
    Amanda

  • Hi, 

    It has the buttonless DFU service, so it doesn't need to trigger to get into DFU again. 

    -Amanda

  • Which event will be received in nRF52832 device when I press "Button DFU without bonds" soft key? I can't see any BLE_DFU_EVT_BOOTLOADER_xxx events in log messages. But ble_dfu_buttonless_init() return 0.:

    log messages:

    00> <info> app_timer: RTC: initialized.
    00>
    00> <info> app: Setting vector table to bootloader: 0x00072000
    00>
    00> <info> app: Setting vector table to main app: 0x00026000
    00> <debug> app:bleDfuInit() return 0
    00>
    00> <debug> app: NOR_DATA_PERIOD=819
    00>
    00>
    00> <debug> app: NOR_RECORD_PERIOD=8192
    00>
    00>
    00> <info> app: bsp_button_longkey_handler 0.
    00>
    00> <debug> nrf_ble_gatt: Requesting to update ATT MTU to 185 bytes on connection 0x0.
    00>
    00> <info> app: PM_EVT_BONDED_PEER_CONNECTED
    00>
    00>
    00> <info> app: BLE_GAP_EVT_CONNECTED
    00>
    00>
    00> <debug> app: state=1
    00>
    00>
    00> <info> app: PM_EVT_CONN_SEC_SUCCEEDED
    00>
    00>
    00> <info> app: Connection secured: role: 1, conn_handle: 0x0, procedure: 0.
    00>
    00> <debug> nrf_ble_gatt: ATT MTU updated to 185 bytes on connection 0x0 (response).
    00>
    00> <debug> app: _securityRequestHandler
    00>
    00>
    00> <info> app: PM_EVT_CONN_SEC_CONFIG_REQ
    00>
    00>
    00> <info> app: BLE_GAP_EVT_SEC_PARAMS_REQUEST
    00>
    00>
    00> <info> app: PM_EVT_CONN_SEC_SUCCEEDED
    00>
    00>
    00> <info> app: Connection secured: role: 1, conn_handle: 0x0, procedure: 1.
    00>
    00> <info> app: BLE_GAP_EVT_AUTH_STATUS
    00>

    source code related to BLE_DFU_EVT_BOOTLOADER_xxx event handling.
    static void _bleDfuEvtHandler(ble_dfu_buttonless_evt_type_t event) {
        switch (event) {
            case BLE_DFU_EVT_BOOTLOADER_ENTER_PREPARE:
            {
                NRF_LOG_INFO("BLE_DFU_EVT_BOOTLOADER_ENTER_PREPARE");

                // Prevent device from advertising on disconnect.
                advertisingModesConfigSet();

                // 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(_bleDfuDisconnect, NULL);
                NRF_LOG_INFO("Disconnected %d links.", conn_count);            
            }
            break;

            case BLE_DFU_EVT_BOOTLOADER_ENTER:
            {
                // YOUR_JOB: Write app-specific unwritten data to FLASH, control finalization of this
                //           by delaying reset by reporting false in app_shutdown_handler
                NRF_LOG_INFO("BLE_DFU_EVT_BOOTLOADER_ENTER\n");
            }    
            break;

            case BLE_DFU_EVT_BOOTLOADER_ENTER_FAILED:
            {
                NRF_LOG_ERROR("BLE_DFU_EVT_BOOTLOADER_ENTER_FAILED\n");
                // YOUR_JOB: Take corrective measures to resolve the issue
                //           like calling APP_ERROR_CHECK to reset the device.
            }    
            break;

            case BLE_DFU_EVT_RESPONSE_SEND_ERROR:
            {
                NRF_LOG_ERROR("BLE_DFU_EVT_RESPONSE_SEND_ERROR\n");
                // YOUR_JOB: Take corrective measures to resolve the issue
                //           like calling APP_ERROR_CHECK to reset the device.
            }    
            break;

            default:
            {
                NRF_LOG_ERROR("Unknown event from ble_dfu_buttonless.");
            }    
            break;
        }
    }

    int bleDfuInit(void) {
        ret_code_t errCode = ble_dfu_buttonless_async_svci_init();
        if (errCode != NRF_SUCCESS) {
            NRF_LOG_WARNING("ble_dfu_buttonless_async_svci_init() failed, errCode=0x%x\n", errCode);
            return ERROR_OTA_INITIALIZE_FAIL;
        }

        ble_dfu_buttonless_init_t init = {0};
        init.evt_handler = _bleDfuEvtHandler;
        errCode = ble_dfu_buttonless_init(&init);
        if (errCode != NRF_SUCCESS) {
            NRF_LOG_WARNING("ble_dfu_buttonless_init() failed, errCode=0x%x\n", errCode);
            return ERROR_OTA_INITIALIZE_FAIL;
        }    

        NRF_LOG_DEBUG("bleDfuInit() return 0\n");
        return 0;
    }

  • Hi, 

    Do you write opcode 0x01 to get into DFU mode?

    Have a look at this Buttonless Secure DFU Service without bonds doc.

    -Amanda

  • I try to use iOS nRF Connect APP to perform DFU. But it failed with "scanning timeout returning no matching peripheral". Why no bootloader log messages after BLE_DFU_EVT_BOOTLOADER_ENTER_PREPARE event?

    The following is log messages of nRF52832 device.

    00> <info> app: Version 1.2.1
    00>
    00>
    00> <info> app: ========| flash info |========
    00>
    00> <info> app: erase unit:   4096 bytes
    00>
    00> <info> app: program unit: 4 bytes
    00>
    00> <info> app: end address: 0x72000
    00>
    00> <info> app: ==============================
    00>
    00> <info> app_timer: RTC: initialized.
    00>
    00> <info> app: Setting vector table to bootloader: 0x00072000
    00>
    00> <info> app: Setting vector table to main app: 0x00026000
    00>
    00> <debug> app: bleDfuInit() return 0
    00>
    00>
    00> <debug> app: NOR_DATA_PERIOD=819
    00>
    00>
    00> <debug> app: NOR_RECORD_PERIOD=8192
    00>
    00>
    00> <info> app: bsp_button_longkey_handler 0.
    00>
    00> <warning> app: Battery volage 0mV is too low
    00>
    00>
    00> <warning> app: Battery volage 3374mV is too low
    00>
    00>
    00> <info> app: POWER_ON.
    00>
    00> <info> app: External devices initializing start
    00> <info> app: External devices initializing finish
    00>
    00> <info> app: bsp_button_longkey_handler 1.
    00>
    00> <debug> nrf_ble_gatt: Requesting to update ATT MTU to 185 bytes on connection 0x0.
    00>
    00> <info> app: BLE_GAP_EVT_CONNECTED
    00>
    00>
    00> <debug> app: state=1
    00>
    00>
    00> <info> app: BLE_GAP_EVT_PHY_UPDATE_REQUEST
    00>
    00>
    00> <debug> nrf_ble_gatt: Peer on connection 0x0 requested a data length of 251 bytes.
    00>
    00> <debug> nrf_ble_gatt: Updating data length to 27 on connection 0x0.
    00>
    00> <debug> nrf_ble_gatt: Data length updated to 27 on connection 0x0.
    00>
    00> <debug> nrf_ble_gatt: max_rx_octets: 27
    00>
    00> <debug> nrf_ble_gatt: max_tx_octets: 27
    00>
    00> <debug> nrf_ble_gatt: max_rx_time: 2120
    00>
    00> <debug> nrf_ble_gatt: max_tx_time: 2120
    00>
    00> <debug> nrf_ble_gatt: ATT MTU updated to 185 bytes on connection 0x0 (response).
    00>
    00> <debug> app: _securityRequestHandler
    00>
    00>
    00> <info> app: BLE_GAP_EVT_SEC_PARAMS_REQUEST
    00>
    00>
    00> <info> app: PM_EVT_CONN_SEC_SUCCEEDED
    00>
    00>
    00> <info> app: Connection secured: role: 1, conn_handle: 0x0, procedure: 1.
    00>
    00> <info> app: BLE_GAP_EVT_AUTH_STATUS
    00>
    00>
    00> <info> app: BLE_DFU_EVT_BOOTLOADER_ENTER_PREPARE

Reply Children
  • #include "sdk_config.h"
    #include "advertising.h"
    #include "ble_types.h"
    #include "ble_nus.h"
    #include "bsp.h"
    #include "bsp_btn_ble.h"
    #include "error.h"
    #include "nrf_log.h"
    #include "nrf_sdh_ble.h"
    
    #define APP_ADV_INTERVAL               800             /**< The advertising interval (in units of 0.625 ms. This value corresponds to 40 ms). */
    #define APP_ADV_DURATION               1800            /**< The advertising duration (180 seconds) in units of 10 milliseconds. */         
    #define APP_ADV_FAST_DURATION          0//1800          /**< The advertising duration of fast advertising in units of 10 milliseconds. */
    #define APP_ADV_SLOW_DURATION          0//1800          /**< The advertising duration of slow advertising in units of 10 milliseconds. */
    #define APP_ADV_FAST_INTERVAL          MSEC_TO_UNITS(500, UNIT_0_625_MS)        /**< The advertising interval (in units of 0.625 ms). The default value corresponds to 25 ms. */
    #define APP_ADV_SLOW_INTERVAL          MSEC_TO_UNITS(500, UNIT_0_625_MS)        /**< Slow advertising interval (in units of 0.625 ms). The default value corresponds to 2 seconds. */
    #define NUS_SERVICE_UUID_TYPE          BLE_UUID_TYPE_VENDOR_BEGIN                  /**< UUID type for the Nordic UART Service (vendor specific). */
    
    BLE_ADVERTISING_DEF(_gAdvertising);  /**< Advertising module instance. */ 
    
    static ble_uuid_t _gAdvUuids[]          = {                                         /**< Universally unique service identifier. */ 
        {BLE_UUID_NUS_SERVICE, NUS_SERVICE_UUID_TYPE}
    };
    
    /**@brief Function for putting the chip into sleep mode.
     *
     * @note This function will not return.
     */
    static void _sleepModeEnter(void) {
        ret_code_t errCode;
        errCode = bsp_indication_set(BSP_INDICATE_IDLE);
        if (errCode != NRF_SUCCESS) {
            NRF_LOG_WARNING("bsp_indication_set() failed, errCode=0x%x\n", errCode);
            return;
        }
    
        // Prepare wakeup buttons.
        errCode = bsp_btn_ble_sleep_mode_prepare();
        if (errCode != NRF_SUCCESS) {
            NRF_LOG_WARNING("bsp_btn_ble_sleep_mode_prepare() failed, errCode=0x%x\n", errCode);
            return;
        }
    
        // Go to system-off mode (this function will not return; wakeup will cause a reset).
        errCode = sd_power_system_off();
        if (errCode != NRF_SUCCESS) {
            NRF_LOG_WARNING("sd_power_system_off() failed, errCode=0x%x\n", errCode);
            return;
        }
    }
    
    
    /**@brief Function for handling advertising events.
     *
     * @details This function is called for advertising events that are passed to the application.
     *
     * @param[in] ble_adv_evt  Advertising event.
     */
    static void _advertisingEvtHandler(ble_adv_evt_t evt) {
        ret_code_t errCode;
    
        switch (evt) {
                case BLE_ADV_EVT_FAST:
                        errCode = bsp_indication_set(BSP_INDICATE_ADVERTISING);
                        if (errCode != NRF_SUCCESS) {
                            NRF_LOG_WARNING("bsp_indication_set() failed, errCode=0x%x\n", errCode);
                            return;
                        }    
                        break;
                        
                case BLE_ADV_EVT_IDLE:
                        _sleepModeEnter();
                        break;
    
                default:
                        break;
        }
    }
    
    int advertisingInit(void) {
        ret_code_t errCode;
        ble_advertising_init_t init;
    
        memset(&init, 0, sizeof(init));
    
        init.advdata.name_type          = BLE_ADVDATA_FULL_NAME;
        init.advdata.include_appearance = false;
        init.advdata.flags              = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
    
        init.srdata.uuids_complete.uuid_cnt = sizeof(_gAdvUuids) / sizeof(_gAdvUuids[0]);
        init.srdata.uuids_complete.p_uuids  = _gAdvUuids;
    
        init.config.ble_adv_whitelist_enabled = false;
        init.config.ble_adv_fast_enabled  = true;
        init.config.ble_adv_fast_interval = APP_ADV_FAST_INTERVAL;
        init.config.ble_adv_fast_timeout  = APP_ADV_FAST_DURATION;
        init.config.ble_adv_slow_enabled  = true;
        init.config.ble_adv_slow_interval = APP_ADV_SLOW_INTERVAL;
        init.config.ble_adv_slow_timeout  = APP_ADV_SLOW_DURATION;
        init.evt_handler = _advertisingEvtHandler;
    
        errCode = ble_advertising_init(&_gAdvertising, &init);
        if (errCode != NRF_SUCCESS) {
            NRF_LOG_WARNING("ble_advertising_init() failed errCode=0x%x", errCode);
            return ERROR_ADVERTISING_INITIALIZE_FAIL;
        }
    
        ble_advertising_conn_cfg_tag_set(&_gAdvertising, APP_BLE_CONN_CFG_TAG);
    
        return 0;
    }
    
    ble_adv_modes_config_t advertisingConfigGet(void) {
        ble_adv_modes_config_t config;
        memset(&config, 0, sizeof(ble_adv_modes_config_t));
    
        config.ble_adv_fast_enabled           = true;
        config.ble_adv_fast_interval          = APP_ADV_INTERVAL;
        config.ble_adv_fast_timeout           = APP_ADV_DURATION;
        config.ble_adv_on_disconnect_disabled = true;
    
        return config;
    }
    
    void advertisingModesConfigSet(void) {
        const ble_adv_modes_config_t config = advertisingConfigGet();
        ble_advertising_modes_config_set(&_gAdvertising, &config);
    }    
    
    
    /* Function for starting advertising. */
    int advertisingStart(void) {
    //        memset(m_whitelist_peers, PM_PEER_ID_INVALID, sizeof(m_whitelist_peers));
    //        m_whitelist_peer_cnt = (sizeof(m_whitelist_peers) / sizeof(pm_peer_id_t));
    
    //        peer_list_get(m_whitelist_peers, &m_whitelist_peer_cnt);
    
    //        ret = pm_whitelist_set(m_whitelist_peers, m_whitelist_peer_cnt);
    //        APP_ERROR_CHECK(ret);
    
    //        // Setup the device identies list.
    //        // Some SoftDevices do not support this feature.
    //        ret = pm_device_identities_list_set(m_whitelist_peers, m_whitelist_peer_cnt);
    //        if (ret != NRF_ERROR_NOT_SUPPORTED)
    //        {
    //            APP_ERROR_CHECK(ret);
    //        }
    
    
        const ret_code_t errCode = ble_advertising_start(&_gAdvertising, BLE_ADV_MODE_FAST);
        if (errCode != NRF_SUCCESS) {
            NRF_LOG_WARNING("ble_advertising_start() failed errCode=0x%x", errCode);
            return ERROR_ADVERTISING_START_FAIL;
        }
        
        return 0;
    }
    
    
    #include "ota.h"
    #include "advertising.h"
    #include "ble_conn_state.h"
    #include "ble_dfu.h"
    #include "error.h"
    #include "nrf_log.h"
    
    #if BLE_DFU_APP_SUPPORT
    static void _bleDfuDisconnect(const uint16_t connHandle, void* pContext) {
        UNUSED_PARAMETER(pContext);
        const ret_code_t errCode = sd_ble_gap_disconnect(connHandle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
        if (errCode != NRF_SUCCESS) {
            NRF_LOG_WARNING("Failed to disconnect connection. Connection handle: %d Error: 0x%x\n", connHandle, errCode);
            return;
        }
        
        NRF_LOG_INFO("Disconnected connection handle %d", connHandle);
    }
    
    /**@brief Function for handling dfu events from the Buttonless Secure DFU service
     *
     * @param[in]   event   Event from the Buttonless Secure DFU service.
     */
    static void _bleDfuEvtHandler(ble_dfu_buttonless_evt_type_t event) {
        switch (event) {
            case BLE_DFU_EVT_BOOTLOADER_ENTER_PREPARE:
            {
                NRF_LOG_INFO("BLE_DFU_EVT_BOOTLOADER_ENTER_PREPARE");
    
                // Prevent device from advertising on disconnect.
                advertisingModesConfigSet();
    
    
                // 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(_bleDfuDisconnect, NULL);
                NRF_LOG_INFO("Disconnected %d links.", conn_count);            
            }
            break;
    
            case BLE_DFU_EVT_BOOTLOADER_ENTER:
            {
                // YOUR_JOB: Write app-specific unwritten data to FLASH, control finalization of this
                //           by delaying reset by reporting false in _appShutdownHandler
                NRF_LOG_INFO("BLE_DFU_EVT_BOOTLOADER_ENTER\n");
            }    
            break;
    
            case BLE_DFU_EVT_BOOTLOADER_ENTER_FAILED:
            {
                NRF_LOG_ERROR("BLE_DFU_EVT_BOOTLOADER_ENTER_FAILED\n");
                // YOUR_JOB: Take corrective measures to resolve the issue
                //           like calling APP_ERROR_CHECK to reset the device.
            }    
            break;
    
            case BLE_DFU_EVT_RESPONSE_SEND_ERROR:
            {
                NRF_LOG_ERROR("BLE_DFU_EVT_RESPONSE_SEND_ERROR\n");
                // YOUR_JOB: Take corrective measures to resolve the issue
                //           like calling APP_ERROR_CHECK to reset the device.
            }    
            break;
    
            default:
            {
                NRF_LOG_ERROR("Unknown event from ble_dfu_buttonless.");
            }    
            break;
        }
    }
    
    int bleDfuInit(void) {
        ret_code_t errCode = ble_dfu_buttonless_async_svci_init();
        if (errCode != NRF_SUCCESS) {
            NRF_LOG_WARNING("ble_dfu_buttonless_async_svci_init() failed, errCode=0x%x\n", errCode);
            return ERROR_OTA_INITIALIZE_FAIL;
        }
    
        ble_dfu_buttonless_init_t init = {0};
        init.evt_handler = _bleDfuEvtHandler;
        errCode = ble_dfu_buttonless_init(&init);
        if (errCode != NRF_SUCCESS) {
            NRF_LOG_WARNING("ble_dfu_buttonless_init() failed, errCode=0x%x\n", errCode);
            return ERROR_OTA_INITIALIZE_FAIL;
        }    
    
        NRF_LOG_DEBUG("bleDfuInit() return 0\n");
        return 0;
    }    
    #endif
    
    

  • Hi, 

    The latest issue is far away from the original scope, and my colleague answered it in this thread

    -Amanda

Related