Reconnect to bonded Smartphone

Hi, 

nRF5340 and SDK v3.0.0 I'm using.

Currently my nRF5340 based BLE device can be bonded with smartphone via passkey, after bond is done, the device stops advertising and be invisible.

From smartphone side:  in case the smartphone is out of range or the bluetooth on smartphone is disabled

From BLE device side: or in case the bond information on the nRF5340 is removed.

Except rebooting the device, there is no way to make them connect to each other again. 

this is the BLE related funcitons:

	if (bt_conn_auth_cb_register(&conn_auth_callbacks)) {
		LOG_ERR("Failed to register authorization callbacks.\n");}

	if (bt_conn_auth_info_cb_register(&conn_auth_info_callbacks)) {
		LOG_ERR("Failed to register authorization info callbacks.\n");}

	bt_conn_cb_register(&connection_callbacks);

	if (bt_enable(NULL)) {
		LOG_ERR("Bluetooth init failed. \n");}

	if (IS_ENABLED(CONFIG_SETTINGS)) {
		settings_load();}

	if (bt_services_init(&app_callbacks)) {
		LOG_ERR("Failed to init LBS. \n");}

	LOG_INF("Bluetooth initialized\n");

	if (bt_le_adv_start(BT_LE_ADV_CONN_FAST_2, ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd))) {
		LOG_ERR("Advertising failed to start. \n");}

this is BLE related configurations:

# Button and LED library
CONFIG_BT_LBS=y
CONFIG_BT_LBS_POLL_BUTTON=y
CONFIG_DK_LIBRARY=y
CONFIG_BT_LBS_SECURITY_ENABLED=y

# Bluetooth LE
CONFIG_BT=y
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_DEVICE_NAME="TEST_BLE"
CONFIG_BT_SMP=y
CONFIG_SETTINGS=y
CONFIG_BT_SETTINGS=y
#data length and MTU
CONFIG_BT_USER_DATA_LEN_UPDATE=y
CONFIG_BT_CTLR_DATA_LENGTH_MAX=251
CONFIG_BT_BUF_ACL_RX_SIZE=1024
CONFIG_BT_BUF_ACL_TX_SIZE=251
CONFIG_BT_L2CAP_TX_MTU=247
CONFIG_BT_GATT_CLIENT=y
CONFIG_BT_AUTO_PHY_UPDATE=n

**********************************************************************

What I want:

1. just like the earphone, if the connection is lost, they shall be able to reconnect to each other by themselves automatically.

2. if the bond info is removed on the device, it shall advertise and be visible again. 

How can I achive these? 

Regards

Danny

Parents
  • Hello,

    I am terribly sorry for the late reply. We are a bit low staffed, and we are working on holding the queue down. I am sorry for the inconvenience.

    Except rebooting the device, there is no way to make them connect to each other again.

    Do you mean rebooting, or re-programming the device?

    Is it possible to upload the entire application? Mot relevant is the file with all of your Bluetooth implementation, where you set what sort of advertising to use when there is a bonded device, but in case I need to look at something else. That saves us one day of back and forth in case I need some other file.

    Are you able to see this behavior on a DK, or does it require a custom board?

    General: How do you want your peripheral device to behave? If it is connected and bonded to a central device, and then the central disconnects (possibly out of range for a short while). What do you want the peripheral to do? Only accept connections from the already bonded device?

    When do you want it to start accepting new connections? On a button press? After a given amount of time?

    Best regards,

    Edvin

  • Hi  

    fully understandable, it's sommer, the most are in holiday:)

    Anyway thanks a lot for the reply!

    1. rebooting, I mean cycle the power, USB plug out, then plug in.

    2. I don't think it's hardware related.

    3. "General: How do you want your peripheral device to behave?"
    good question: first, they are connected to each other, then the central(smartphone) is out of range, for a certain time, for instance 15 minutes, the peripheral and central shall try to reconnect to each other, after 15 minutes, stop the try.

    yes, only accept connections from the alreay bonded device, as the earphone to smartphone.

    "When do you want it to start accepting new connections? On a button press? After a given amount of time?"

    No buttons on device, if it receives a int signal from the inertial sensor on board occasionally, it will try to start accepting new conncections again, or every 5 minutes there will be a try for reconncetion.

    it's difficult to share the whole project code, just give me some hints, which functions or logic or documents shall I try, I can try it by myself.

    Best regards

    Danny

  • danny0007 said:
    1. rebooting, I mean cycle the power, USB plug out, then plug in.

    Ok, so I guess your device stops advertising at some point. If you don't want that to happen, then you don't need to have it stop advertising. I am not quite sure how you stop it, but if you look at most of the samples in NCS\nrf\samples\bluetooth, such as the peripheral_uart, this will never stop advertising.

    2: ok.

    3: I think you need to sit down and write down how you want your device to behave in detail in these cases. If you can't write it on a piece of paper, you can't program it to do so either. 

    danny0007 said:
    then the central(smartphone) is out of range, for a certain time, for instance 15 minutes, the peripheral and central shall try to reconnect to each other, after 15 minutes, stop the try

    To me, this is not clear. Does that mean that the peripheral should advertise with a whitelist for 15 minutes, and then switch to not using a whitelist after that? (Whitelist = filter accept list). 

    To me, it sounds like you are already using a whitelist, but it is difficult to tell without knowing more about your application (source code). Are you using a whitelist? 

    And is the question how to stop using the whitelist after 15 minutes, and advertise normally? 

    Or is the issue that your device is not advertising at all after a while? Can you see it's advertisements if you scan for it using nRF Connect for Android/iOS? 

    Can you see it's advertisements if you are using the nRF Sniffer for Bluetooth LE? (they should show up even if you are using a whitelist).

    Best regards,

    Edvin

  • Sorry for the confusion. I'm still not that deep in this topic.

    1. with "stop advertising" I mean, if one smartphone is connected/bonded to the device, it will be unvisible for other smartphones. this behavior is already ok.

    Now the issue I'm trying to solve is for this senario:
    for instance, in a room there are many the same kind of devices with the same name, they were already bonded with different smartphones by one to one, they are just disconnected from their bonded smartphone. Now one person comes in the room with his smartphone, I want only the device, which was already bonded with this smartphone, is visibale and connectable to this smartphone, the other devices shall be unvisible to this smartphone and unconnectable(because only one smartphone is allowed to be bonded to each device.) 

    3. yes, I think what I need is advertise with whitelist.

    after disconnected, first advertise with a whitelist for 15 minutes, then doesn't advertise any more. if a interrupt is triggered, then advertise with a whitelist again.

    my issue is I'm trying to use directed advertising to the publich adresse(Android), here is my code, basically if bonded, directed advertising, otherwise general advertising.

    // Simple advertising restart
    static int start_advertising(void)
    {
        int err;
        
        // Stop any existing advertising
        if (advertising_active) {
            bt_le_adv_stop();
            advertising_active = false;
            k_sleep(K_MSEC(10));
        }
        
        // Try directed advertising first if we have a bonded device
        if (has_bonded_device) {
            struct bt_le_adv_param adv_param = {
                .id = BT_ID_DEFAULT,
                .options = BT_LE_ADV_OPT_CONN,
                .interval_min = BT_GAP_ADV_FAST_INT_MIN_2,
                .interval_max = BT_GAP_ADV_FAST_INT_MAX_2,
                .peer = &last_bonded_addr,
            };
            // Assuming last_bonded_addr is a bt_addr_le_t
    		char addr_str[BT_ADDR_LE_STR_LEN]; // Buffer to hold the string representation
    		bt_addr_le_to_str(&last_bonded_addr, addr_str, sizeof(addr_str));
    		LOG_INF("Starting directed advertising to bonded device: %s", addr_str);
    
            err = bt_le_adv_start(&adv_param, ad, ARRAY_SIZE(ad), NULL, 0);
            
            // If directed fails, fall back to general advertising
            if (err) {
                LOG_WRN("Directed advertising failed, trying general");
                err = bt_le_adv_start(BT_LE_ADV_CONN_FAST_2, ad, ARRAY_SIZE(ad), NULL, 0);
            }
        } else {
            // No bonded device - use general advertising
            LOG_INF("Starting general advertising");
            err = bt_le_adv_start(BT_LE_ADV_CONN_FAST_2, ad, ARRAY_SIZE(ad), NULL, 0);
        }
        
        if (!err) {
            advertising_active = true;
            LOG_INF("Advertising started successfully");
        } else {
            LOG_ERR("Advertising failed (err %d)", err);
        }
        
        return err;
    }

    for general advertising, it's working, but for directed advertising I get error from the on_connected funciton:

    void on_connected(struct bt_conn *conn, uint8_t err)
    {
        if (err) {
            LOG_ERR("Connection failed (err %u)", err);
            // Schedule reconnection attempt
            k_work_schedule(&reconnect_work, K_MSEC(1000));
            return;
        }
        
        LOG_INF("Connected successfully");
    	dk_set_led_on(DK_LED2);
    	update_data_length(conn);
    	update_mtu(conn);
    	// Stop advertising when connected
        if (advertising_active) {
            bt_le_adv_stop();
            advertising_active = false;
        }
    }


    I: Starting directed advertising to bonded device: E8:D5:2B:7A:B6:44 (public)
    I: Advertising started successfully
    switch LED 
    switch LED
    E: Connection failed (err 60)
    switch LED 
    I: Starting directed advertising to bonded device: E8:D5:2B:7A:B6:44 (public)
    I: Advertising started successfully
    switch LED 
    E: Connection failed (err 60)
    switch LED 
    I: Starting directed advertising to bonded device: E8:D5:2B:7A:B6:44 (public)
    I: Advertising started successfully
    switch LED
    E: Connection failed (err 60)
    switch LED
    I: Starting directed advertising to bonded device: E8:D5:2B:7A:B6:44 (public)
    I: Advertising started successfully
    switch LED 
    switch LED 
    E: Connection failed (err 60)
    switch LED 
    I: Starting directed advertising to bonded device: E8:D5:2B:7A:B6:44 (public)
    I: Advertising started successfully
    switch LED 
    E: Connection failed (err 60)
    switch LED 

    Regards

    Danny

Reply
  • Sorry for the confusion. I'm still not that deep in this topic.

    1. with "stop advertising" I mean, if one smartphone is connected/bonded to the device, it will be unvisible for other smartphones. this behavior is already ok.

    Now the issue I'm trying to solve is for this senario:
    for instance, in a room there are many the same kind of devices with the same name, they were already bonded with different smartphones by one to one, they are just disconnected from their bonded smartphone. Now one person comes in the room with his smartphone, I want only the device, which was already bonded with this smartphone, is visibale and connectable to this smartphone, the other devices shall be unvisible to this smartphone and unconnectable(because only one smartphone is allowed to be bonded to each device.) 

    3. yes, I think what I need is advertise with whitelist.

    after disconnected, first advertise with a whitelist for 15 minutes, then doesn't advertise any more. if a interrupt is triggered, then advertise with a whitelist again.

    my issue is I'm trying to use directed advertising to the publich adresse(Android), here is my code, basically if bonded, directed advertising, otherwise general advertising.

    // Simple advertising restart
    static int start_advertising(void)
    {
        int err;
        
        // Stop any existing advertising
        if (advertising_active) {
            bt_le_adv_stop();
            advertising_active = false;
            k_sleep(K_MSEC(10));
        }
        
        // Try directed advertising first if we have a bonded device
        if (has_bonded_device) {
            struct bt_le_adv_param adv_param = {
                .id = BT_ID_DEFAULT,
                .options = BT_LE_ADV_OPT_CONN,
                .interval_min = BT_GAP_ADV_FAST_INT_MIN_2,
                .interval_max = BT_GAP_ADV_FAST_INT_MAX_2,
                .peer = &last_bonded_addr,
            };
            // Assuming last_bonded_addr is a bt_addr_le_t
    		char addr_str[BT_ADDR_LE_STR_LEN]; // Buffer to hold the string representation
    		bt_addr_le_to_str(&last_bonded_addr, addr_str, sizeof(addr_str));
    		LOG_INF("Starting directed advertising to bonded device: %s", addr_str);
    
            err = bt_le_adv_start(&adv_param, ad, ARRAY_SIZE(ad), NULL, 0);
            
            // If directed fails, fall back to general advertising
            if (err) {
                LOG_WRN("Directed advertising failed, trying general");
                err = bt_le_adv_start(BT_LE_ADV_CONN_FAST_2, ad, ARRAY_SIZE(ad), NULL, 0);
            }
        } else {
            // No bonded device - use general advertising
            LOG_INF("Starting general advertising");
            err = bt_le_adv_start(BT_LE_ADV_CONN_FAST_2, ad, ARRAY_SIZE(ad), NULL, 0);
        }
        
        if (!err) {
            advertising_active = true;
            LOG_INF("Advertising started successfully");
        } else {
            LOG_ERR("Advertising failed (err %d)", err);
        }
        
        return err;
    }

    for general advertising, it's working, but for directed advertising I get error from the on_connected funciton:

    void on_connected(struct bt_conn *conn, uint8_t err)
    {
        if (err) {
            LOG_ERR("Connection failed (err %u)", err);
            // Schedule reconnection attempt
            k_work_schedule(&reconnect_work, K_MSEC(1000));
            return;
        }
        
        LOG_INF("Connected successfully");
    	dk_set_led_on(DK_LED2);
    	update_data_length(conn);
    	update_mtu(conn);
    	// Stop advertising when connected
        if (advertising_active) {
            bt_le_adv_stop();
            advertising_active = false;
        }
    }


    I: Starting directed advertising to bonded device: E8:D5:2B:7A:B6:44 (public)
    I: Advertising started successfully
    switch LED 
    switch LED
    E: Connection failed (err 60)
    switch LED 
    I: Starting directed advertising to bonded device: E8:D5:2B:7A:B6:44 (public)
    I: Advertising started successfully
    switch LED 
    E: Connection failed (err 60)
    switch LED 
    I: Starting directed advertising to bonded device: E8:D5:2B:7A:B6:44 (public)
    I: Advertising started successfully
    switch LED
    E: Connection failed (err 60)
    switch LED
    I: Starting directed advertising to bonded device: E8:D5:2B:7A:B6:44 (public)
    I: Advertising started successfully
    switch LED 
    switch LED 
    E: Connection failed (err 60)
    switch LED 
    I: Starting directed advertising to bonded device: E8:D5:2B:7A:B6:44 (public)
    I: Advertising started successfully
    switch LED 
    E: Connection failed (err 60)
    switch LED 

    Regards

    Danny

Children
No Data
Related