This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Getting NRF_ERROR_INVALID_STATE from nrf_dfu_set_adv_name on DFU bootloader

Hi there,

I wanted to change the advertising name while running DFU bootloader (secure_bootloader_ble_s132_pca10040), so I basically added what I found here:

https://devzone.nordicsemi.com/f/nordic-q-a/38534/change-the-advertisement-name-for-dfu-from-application

static bool dfu_is_writing_name = false;

void ble_dfu_buttonless_on_sys_evt(uint32_t sys_evt, void * p_context);

/**@brief Define functions for async interface to set new advertisement name for DFU mode.  */
NRF_SVCI_ASYNC_FUNC_DEFINE(NRF_DFU_SVCI_SET_ADV_NAME, nrf_dfu_set_adv_name, nrf_dfu_adv_name_t);

// Register SoC observer for the Buttonless Secure DFU service
NRF_SDH_SOC_OBSERVER(m_dfu_buttonless_soc_obs, BLE_DFU_SOC_OBSERVER_PRIO, ble_dfu_buttonless_on_sys_evt, NULL);

uint32_t nrf_dfu_svci_vector_table_set(void);
uint32_t nrf_dfu_svci_vector_table_unset(void);

void dfu_init()
{
	nrf_dfu_svci_vector_table_set();
	nrf_dfu_set_adv_name_init();
	nrf_dfu_svci_vector_table_unset();
}

void ble_dfu_buttonless_on_sys_evt(uint32_t sys_evt, void * p_context)
{
	if (sys_evt != NRF_EVT_FLASH_OPERATION_ERROR && sys_evt != NRF_EVT_FLASH_OPERATION_SUCCESS)
		return;

	if (!dfu_is_writing_name)
		return;

	dfu_is_writing_name = false;

	if (nrf_dfu_set_adv_name_is_initialized())
	{
		uint32_t err_code = nrf_dfu_set_adv_name_on_sys_evt(sys_evt);

		if (err_code == NRF_SUCCESS)
		{
			// reboot into DFU mode
		}
	}
}

void write_dfu_adv_name(const char* inName)
{
	static nrf_dfu_adv_name_t dfuAdvName;
	dfuAdvName.crc = 0xFFFFFFFF;
	dfuAdvName.len = strlen(inName);
	memcpy(dfuAdvName.name, inName, dfuAdvName.len);
	dfuAdvName.name[dfuAdvName.len] = '\0';
	
	dfu_is_writing_name = true;
	uint32_t err_code = nrf_dfu_set_adv_name(&dfuAdvName);

	if (err_code == NRF_SUCCESS)
	{
	    dfu_is_writing_name = false;
	}
}

But I keep getting NRF_ERROR_INVALID_STATE from nrf_dfu_set_adv_name (line 51).

Here's my main:

int main(void)
{
    uint32_t ret_val;

    dfu_init();
    write_dfu_adv_name("test_name");

    // Must happen before flash protection is applied, since it edits a protected page.
    nrf_bootloader_mbr_addrs_populate();

    // Protect MBR and bootloader code from being overwritten.
    ret_val = nrf_bootloader_flash_protect(0, MBR_SIZE);
    APP_ERROR_CHECK(ret_val);
    ret_val = nrf_bootloader_flash_protect(BOOTLOADER_START_ADDR, BOOTLOADER_SIZE);
    APP_ERROR_CHECK(ret_val);

    (void) NRF_LOG_INIT(nrf_bootloader_dfu_timer_counter_get);
    NRF_LOG_DEFAULT_BACKENDS_INIT();

    bootloader_board_init();

    NRF_LOG_INFO("Inside main");   

    ret_val = nrf_bootloader_init(dfu_observer);
    APP_ERROR_CHECK(ret_val);

    NRF_LOG_FLUSH();

    nrf_bootloader_app_start();    

    NRF_LOG_ERROR("After main, should never be reached.");
    NRF_LOG_FLUSH();

    APP_ERROR_CHECK_BOOL(false);
}

Any guesses about what is happening?

Setup:

OS: Windows 10

IDE: Segger Embedded Studio for ARM V5.34

Hardware: BL652-SA-01-T/R

SDK version: nRF5_SDK_17.0.2_d674dde

SoftDevice: S132

Parents
  • Hello,

    Could you maybe provide some more background for why you want to change the device name in the bootloader? This function is intended to be called from the application before entering dfu to ensure the central will be able to re-connect when the bootloader starts advertising with the new BLE address.

    From the "Buttonless Secure DFU Service without bonds" section:

    Buttonless Secure DFU Service without bonds

    Configuring the Buttonless Secure DFU service to not support bonds does not restrict write access to the buttonless service. Any device will be able to write to the Buttonless DFU characteristic to enter DFU mode.

    Prerequisites for entering DFU mode:

    • Buttonless DFU Characteristic Indication set to enabled.

    When the Buttonless Secure DFU Service enters the bootloader, the device enters DFU mode and starts advertising on BLE address + 1. This is done to prevent the client from using cached BLE services and characteristics data for the device.

    Setting an alternative advertisement name was added to help locate peer devices in DFU mode when the API for the client application does not provide direct access to the Bluetooth address.

    Setting a new advertisement name is optional, but it must be done prior to requesting to enter DFU mode. It is not possible to set it more than once before entering DFU mode. The advertisement name will be reset upon a successful Device Firmware Update, or when the DFU mode times out due to inactivity.

    Best regards,

    Vidar

  • Sorry, I didn't realise it was restricted for application use. 

    I migrated the code to the application and it worked.

    Thank you for the support!

Reply Children
No Data
Related