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

Change device name during BLE Connection (SDK 15.0.0)

Hi everyone,

My hw/sw configuration:

- nRF52840
- sdk 15.0.0
- softdevice: s140_nrf52_6.0.0

I would like to change the device name and update it in advertising packet, during a BLE connection.

void change_ble_device_name(uint8_t *device_name){
    ble_gap_conn_sec_mode_t sec_mode;
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);

    uint32_t err_code = sd_ble_gap_device_name_set(&sec_mode,
                                          (const uint8_t *)device_name,
                                          strlen(device_name));
    APP_ERROR_CHECK(err_code);

    /* Re-initialize advertising module */
    advertising_init();

    /* Start advertising */
    ble_advertising_start(&m_advertising, BLE_ADV_MODE_FAST);
    APP_ERROR_CHECK(err_code);

    NRF_LOG_DEBUG("Ble name changed");
}

Reading this post: 

https://devzone.nordicsemi.com/f/nordic-q-a/21702/renaming-device

I discovered that is sufficient to change device name using sd_ble_gap_device_name_set and re-init the advertising.

My advertising function:

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

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

    /* Advertising Data */
    init.advdata.name_type               = BLE_ADVDATA_FULL_NAME; 						
    init.advdata.flags                   = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE; 

    /* Scan Response Data */
    init.srdata.uuids_complete.uuid_cnt  = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]); 
    init.srdata.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);
}

I tried this solution, but It doesn't work and ble_advertising_init returns NO error.

I spent a lot of time surfing Nordic DevZone forum, but I didn't find a working solution.

Could you help me, please?

Thanks

Parents
  • I remember solving that once but not 100% of the complex details.

    I think it included calling first sd_ble_gap_device_name_set(), then sd_ble_gap_adv_stop() and then

    [edit:] ble_advertising_init().
  • I think I've solved it

    I modified change_ble_device_name function in this way:

    void change_ble_device_name(uint8_t *device_name){
        ble_gap_conn_sec_mode_t sec_mode;
        BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
    
        /* Change device name */
        uint32_t err_code = sd_ble_gap_device_name_set(&sec_mode,
                                              (const uint8_t *)device_name,
                                              strlen(device_name));
        APP_ERROR_CHECK(err_code);
    
        /* Store Current connection state od adv lib */
        uint16_t m_adv_current_slave_link_conn_handle_saved = m_advertising.current_slave_link_conn_handle;
    
        /* Re-initialize advertising module */
        advertising_init();
    
        /* Re-store Current connection state lib */
        m_advertising.current_slave_link_conn_handle = m_adv_current_slave_link_conn_handle_saved;
    }

    I saved current_slave_link_conn_handle variable, because adv init function set current_slave_link_conn_handle to BLE_CONN_HANDLE_INVALID.

    uint32_t ble_advertising_init(ble_advertising_t            * const p_advertising,
                                  ble_advertising_init_t const * const p_init)
    {
    //...
        p_advertising->adv_mode_current               = BLE_ADV_MODE_IDLE;
        p_advertising->adv_modes_config               = p_init->config;
        p_advertising->conn_cfg_tag                   = BLE_CONN_CFG_TAG_DEFAULT;
        p_advertising->evt_handler                    = p_init->evt_handler;
        p_advertising->error_handler                  = p_init->error_handler;
        p_advertising->current_slave_link_conn_handle = BLE_CONN_HANDLE_INVALID;
        p_advertising->p_adv_data                     = &p_advertising->adv_data;
    //...
    }
    

    Setting current_slave_link_conn_handle to BLE_CONN_HANDLE_INVALID, on_disconnected function inside ble_advertising.c, doesn't restart advertising.

    static void on_disconnected(ble_advertising_t * const p_advertising, ble_evt_t const * p_ble_evt)
    {
        uint32_t ret;
    
        p_advertising->whitelist_temporarily_disabled = false;
    
        if (p_ble_evt->evt.gap_evt.conn_handle == p_advertising->current_slave_link_conn_handle &&
            p_advertising->adv_modes_config.ble_adv_on_disconnect_disabled == false)
        {
           ret = ble_advertising_start(p_advertising, BLE_ADV_MODE_DIRECTED_HIGH_DUTY);
           if ((ret != NRF_SUCCESS) && (p_advertising->error_handler != NULL))
           {
               p_advertising->error_handler(ret);
           }
        }
    }

Reply
  • I think I've solved it

    I modified change_ble_device_name function in this way:

    void change_ble_device_name(uint8_t *device_name){
        ble_gap_conn_sec_mode_t sec_mode;
        BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
    
        /* Change device name */
        uint32_t err_code = sd_ble_gap_device_name_set(&sec_mode,
                                              (const uint8_t *)device_name,
                                              strlen(device_name));
        APP_ERROR_CHECK(err_code);
    
        /* Store Current connection state od adv lib */
        uint16_t m_adv_current_slave_link_conn_handle_saved = m_advertising.current_slave_link_conn_handle;
    
        /* Re-initialize advertising module */
        advertising_init();
    
        /* Re-store Current connection state lib */
        m_advertising.current_slave_link_conn_handle = m_adv_current_slave_link_conn_handle_saved;
    }

    I saved current_slave_link_conn_handle variable, because adv init function set current_slave_link_conn_handle to BLE_CONN_HANDLE_INVALID.

    uint32_t ble_advertising_init(ble_advertising_t            * const p_advertising,
                                  ble_advertising_init_t const * const p_init)
    {
    //...
        p_advertising->adv_mode_current               = BLE_ADV_MODE_IDLE;
        p_advertising->adv_modes_config               = p_init->config;
        p_advertising->conn_cfg_tag                   = BLE_CONN_CFG_TAG_DEFAULT;
        p_advertising->evt_handler                    = p_init->evt_handler;
        p_advertising->error_handler                  = p_init->error_handler;
        p_advertising->current_slave_link_conn_handle = BLE_CONN_HANDLE_INVALID;
        p_advertising->p_adv_data                     = &p_advertising->adv_data;
    //...
    }
    

    Setting current_slave_link_conn_handle to BLE_CONN_HANDLE_INVALID, on_disconnected function inside ble_advertising.c, doesn't restart advertising.

    static void on_disconnected(ble_advertising_t * const p_advertising, ble_evt_t const * p_ble_evt)
    {
        uint32_t ret;
    
        p_advertising->whitelist_temporarily_disabled = false;
    
        if (p_ble_evt->evt.gap_evt.conn_handle == p_advertising->current_slave_link_conn_handle &&
            p_advertising->adv_modes_config.ble_adv_on_disconnect_disabled == false)
        {
           ret = ble_advertising_start(p_advertising, BLE_ADV_MODE_DIRECTED_HIGH_DUTY);
           if ((ret != NRF_SUCCESS) && (p_advertising->error_handler != NULL))
           {
               p_advertising->error_handler(ret);
           }
        }
    }

Children
No Data
Related