Renaming connected device

Hello Nordic

I am developing a sensor application using nRF52833. The user must be able to connect to the nRF52833 and give it a new name. I have a name characteristic that the user will write the new name to. When the nRF52833 receives the new name, it should disconnect and start advertising the new name. Then the user will reconnect using the new name.

I have read a lot of post on this subject. But none of them seems to work for me. I get the general idea about how to do it:

  • Set the new name using sd_ble_gap_device_name_set
  • Restart the advertising, several ways to do it are described in posts

I am using: SDK 17.1.0

Code starting point: examples\ble_peripheral\ble_app_template

I can rename the nRF52833, but nothing happens until a power cycling takes place.

This is my code:

In the main file I check whether the user has requested a new name. Then I set the new name and run the advertisement initialization again (suggested in this forum)

 if (is_new_device_name_requested()) // if the user has requested a new name for this sensor, then go ahead and set it

    {

        NRF_LOG_INFO("setting new device name");

        set_device_name(DEVICE_NAME);

        advertising_init();

  }

The set_device_name function is shown below:

void set_device_name(uint8_t* first_name)
{
ret_code_t err_code;
ble_gap_conn_sec_mode_t sec_mode;

BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);

memset(full_device_name, 0, sizeof full_device_name);
strcpy(full_device_name, first_name);
strcat(full_device_name, general_par.last_device_name);

err_code = sd_ble_gap_device_name_set(&sec_mode,
(const uint8_t *)full_device_name,
strlen(full_device_name));
APP_ERROR_CHECK(err_code);
general_par.is_new_device_name_wanted = false;
}

The advertising_init function is shown below:

static void advertising_init(void)
{
ret_code_t err_code;
ble_advertising_init_t init;

memset(&init, 0, sizeof(init));

init.advdata.name_type = BLE_ADVDATA_FULL_NAME;
init.advdata.include_appearance = true;
init.advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
init.advdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
init.advdata.uuids_complete.p_uuids = m_adv_uuids;

init.config.ble_adv_fast_enabled = true;
init.config.ble_adv_fast_interval = APP_ADV_INTERVAL;
init.config.ble_adv_fast_timeout = APP_ADV_DURATION;

init.evt_handler = on_adv_evt;

err_code = ble_advertising_init(&m_advertising, &init);
APP_ERROR_CHECK(err_code);

ble_advertising_conn_cfg_tag_set(&m_advertising, APP_BLE_CONN_CFG_TAG);
}

Parents
  • Hi Thomas,

    Are you changing the name while advertising? I take a look at the design of the ble_advertising module and it seems it isn't intended for the "start > stop > update > start again" update method.

    The module does come with a function that is intended to help updating advertising data. It is ble_advertising_advdata_update().

    I have tested using your code, adjusting the bit that use advertising_init() to use that function instead, and I can successfully get the advertising device name to update.

    One of our colleagues, Karl, also wrote a great blog on updating advertising data, which include a sample code using that function in nRF5 SDK v17.1.0. You can find it here:  How to update advertising data dynamically using BLE Advertising library 

    Could you please tweak things to use that function instead, and let me know if it works/does not work?

  • Hi Hieu

    I am changing the name while being in connected mode. I am now using: ble_advertising_advdata_update(). 

    From Karls example I have used and modified the timer handler: static void adv_data_update_timer_handler(void * p_context). I have converted it to a normal function because i do not need timers to trigger it. I have deleted the manufacturer specific data, because I solely want to change the device name. The modified code is shown below:

    static ble_advdata_t new_advdata;
    
    static void adv_data_update(void)
    {
        ret_code_t                  err_code;
    
        NRF_LOG_INFO("Updating advertising data!");
        
        err_code = ble_advertising_advdata_update(&m_advertising, &new_advdata, NULL);
        APP_ERROR_CHECK(err_code);  
        
        NRF_LOG_INFO("Advertising data updated!");
    }

    While the NRF52833 is connected a new name is given by the user and the function below is called:

    void set_device_name(uint8_t* first_name)
    {
        ret_code_t              err_code;
        ble_gap_conn_sec_mode_t sec_mode;
    
        BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
        
        memset(full_device_name, 0, sizeof full_device_name);
        strcpy(full_device_name, first_name);
        strcat(full_device_name, general_par.last_device_name);
    
        err_code = sd_ble_gap_device_name_set(&sec_mode,
                                              (const uint8_t *)full_device_name,
                                              strlen(full_device_name));
        APP_ERROR_CHECK(err_code);
        general_par.is_new_device_name_wanted = false;
    }

    Then I proceed to call the adv_data_update function. I have tried calling it from two code locations:

    1. Subsequent to the device name change

    2. After disconnection has occurred

    Below i 2 code snippets showing where I have called adv_data_udpate.

        if (is_new_device_name_requested()) // if the user has requested a new name for this sensor, then go ahead and set it
        {
            NRF_LOG_INFO("setting new device name");
            set_device_name(DEVICE_NAME);
            adv_data_update();

    /**@brief Function for handling BLE events.
     *
     * @param[in]   p_ble_evt   Bluetooth stack event.
     * @param[in]   p_context   Unused.
     */
    static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
    {
        ret_code_t err_code = NRF_SUCCESS;
    
        switch (p_ble_evt->header.evt_id)
        {
            case BLE_GAP_EVT_DISCONNECTED:
                NRF_LOG_INFO("Disconnected.");
                adv_data_update();
                // LED indication will be changed when advertising starts.
                break;
    

    The result is the same. When I disconnect the NRF52833 will not advertise. A power cycle is needed before i start advertising again. Thank you for your help.

  • Hi Hieu, I really appreciate your help. Nice discovery that "ble_advertising_start()" is called by the module itself. The error that I received must be generated by calling "ble_advertising_start()" two times. When I delete the call to "ble_advertising_start()", there is no error, but the NRF52833 goes into a silent disconnected state without advertising. That is, if I do not change the device name, then the advertising works fine, but after a device name change and a disconnect the silent state occurs. 

     

    I am using DFU and setting a breakpoint is not so easy. But searching this forum I see that it is possible.

     

    I am at a small Christmas vacation right now. I will be back in the office Tuesday. Then I can set breakpoints and continue solving this mysteryBlush

  • I don't think you need to worry about the DFU. Just supporting DFU is not going to cause problems with using breakpoints. It is the SoftDevice and its radio operations that don't like breakpoints, and breakpoint throws their timing off and break communications. Therefore, you won't be able to resume from a breakpoint. We will use it as a tool to see how far the code go and what functions/branches got executed.

    We will resume when you get back though. Enjoy your vacation! Smiley

  • Hello Hieu

    I am back and ready to tackle this issueSlight smile

    The error was caused by calling "ble_advertising_start()" twice. Now there is no errors.

    After renaming device and a disconnect, the NRF52833 starts advertising again but it has lost its name. By using the nRF connect tool i see an advertisement from my NRF52833. I recognize the address: DE:A0:BB:0F:EF:9D. But the name is <Unknown name>

  • Hello Thomas,

    Sorry for the late follow up. How is your new_advdata setup? Does it already include the full device name field?

  • Hello Hieu

    Thank you very much, I am so happy, finally it works.

    Setting the full device name did the trickRelaxed

    static void adv_data_update(void)
    {
        ret_code_t                  err_code;
    
        NRF_LOG_INFO("Updating advertising data!");
        
        new_advdata.name_type = BLE_ADVDATA_FULL_NAME;
        err_code = ble_advertising_advdata_update(&m_advertising, &new_advdata, NULL);
        APP_ERROR_CHECK(err_code);  
        
        NRF_LOG_INFO("Advertising data updated!");
    }

Reply
  • Hello Hieu

    Thank you very much, I am so happy, finally it works.

    Setting the full device name did the trickRelaxed

    static void adv_data_update(void)
    {
        ret_code_t                  err_code;
    
        NRF_LOG_INFO("Updating advertising data!");
        
        new_advdata.name_type = BLE_ADVDATA_FULL_NAME;
        err_code = ble_advertising_advdata_update(&m_advertising, &new_advdata, NULL);
        APP_ERROR_CHECK(err_code);  
        
        NRF_LOG_INFO("Advertising data updated!");
    }

Children
Related