bt_conn_le_create() create_param timeout setting error

ncs v2.6.1

If I use bt_conn_le_create() and do not use the default (0) value for create_param->timeout, the actual connection creation timeout does not match the description in the comment: @brief Connection initiation timeout (N * 10 MS)

For example, if create_param->timeout set to 0, I can add printk in conn.c and find that bt_dev.create_param.timeout = 300, and the actual timeout is indeed 3000ms. However, if create_param->timeout is set to 300, and in conn.c, printk bt_dev.create_param.timeout is also equal to 300, the actual create connection timeout is 300ms!

I use BT_CONN_CB_DEFINE()with .connected , print in the callback and check the timestamp to know the actual timeout duration.

This is very confusing, and I can't see any problems in the code. I hope an expert can answer my doubts.

Parents
  • Hi,

    This seems to come from the host implementation here. I will look into why this is and get back to you.

  • Hi,

    Please disregard my previous post. I tested this and am not able to reproduce an issue. When specifying the default timeout via Kconfig, the unit is in seconds and that is converted to the 10 ms unit in the linked code. Tested with this modified Zephyr Central sample (zephyr/samples/bluetooth/central/) and measuring timeout with logic analyzer on the toggling pin:

    /* main.c - Application main entry point */
    
    /*
     * Copyright (c) 2015-2016 Intel Corporation
     *
     * SPDX-License-Identifier: Apache-2.0
     */
    
    #include <zephyr/types.h>
    #include <stddef.h>
    #include <errno.h>
    #include <zephyr/kernel.h>
    #include <zephyr/sys/printk.h>
    
    #include <zephyr/bluetooth/bluetooth.h>
    #include <zephyr/bluetooth/hci.h>
    #include <zephyr/bluetooth/conn.h>
    #include <zephyr/bluetooth/uuid.h>
    #include <zephyr/bluetooth/gatt.h>
    #include <zephyr/sys/byteorder.h>
    #include <hal/nrf_gpio.h> 
    
    #define LED1_GPIO_PIN 13 // Adjust according to your board
    
    static void start_scan(void);
    
    static struct bt_conn *default_conn;
    
    static void device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t type,
    			 struct net_buf_simple *ad)
    {
    	char addr_str[BT_ADDR_LE_STR_LEN];
    	int err;
    	struct bt_conn_le_create_param *create_param;
    
    	if (default_conn) {
    		return;
    	}
    
    	/* We're only interested in connectable events */
    	if (type != BT_GAP_ADV_TYPE_ADV_IND &&
    	    type != BT_GAP_ADV_TYPE_ADV_DIRECT_IND) {
    		return;
    	}
    
    	bt_addr_le_to_str(addr, addr_str, sizeof(addr_str));
    	printk("Device found: %s (RSSI %d)\n", addr_str, rssi);
    
    	/* connect only to devices in close proximity */
    	if (rssi < -50) {
    		return;
    	}
    
    	if (bt_le_scan_stop()) {
    		return;
    	}
    
    	create_param = BT_CONN_LE_CREATE_CONN;
    	create_param->timeout = 300;
    
    	bt_addr_le_t connect_addr = *addr;
    	connect_addr.a.val[4]++; // Connect to an incremented invalid addres to ensure timeout
    
    	nrf_gpio_pin_clear(LED1_GPIO_PIN);
    
    	err = bt_conn_le_create(&connect_addr, create_param,
    				BT_LE_CONN_PARAM_DEFAULT, &default_conn);
    	if (err) {
    		printk("Create conn to %s failed (%d)\n", addr_str, err);
    		start_scan();
    	}
    }
    
    static void start_scan(void)
    {
    	int err;
    
    	/* This demo doesn't require active scan */
    	err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, device_found);
    	if (err) {
    		printk("Scanning failed to start (err %d)\n", err);
    		return;
    	}
    
    	printk("Scanning successfully started\n");
    }
    
    static void connected(struct bt_conn *conn, uint8_t err)
    {
    	char addr[BT_ADDR_LE_STR_LEN];
    
    	nrf_gpio_pin_set(LED1_GPIO_PIN);
    
    	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
    
    	if (err) {
    		printk("Failed to connect to %s %u %s\n", addr, err, bt_hci_err_to_str(err));
    
    		bt_conn_unref(default_conn);
    		default_conn = NULL;
    
    		start_scan();
    		return;
    	}
    
    	if (conn != default_conn) {
    		return;
    	}
    
    	printk("Connected: %s\n", addr);
    
    	bt_conn_disconnect(conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN);
    }
    
    static void disconnected(struct bt_conn *conn, uint8_t reason)
    {
    	char addr[BT_ADDR_LE_STR_LEN];
    
    	if (conn != default_conn) {
    		return;
    	}
    
    	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
    
    	printk("Disconnected: %s, reason 0x%02x %s\n", addr, reason, bt_hci_err_to_str(reason));
    
    	bt_conn_unref(default_conn);
    	default_conn = NULL;
    
    	start_scan();
    }
    
    BT_CONN_CB_DEFINE(conn_callbacks) = {
    	.connected = connected,
    	.disconnected = disconnected,
    };
    
    int main(void)
    {
    	int err;
    
    	nrf_gpio_cfg_output(LED1_GPIO_PIN);
    	nrf_gpio_pin_set(LED1_GPIO_PIN);
    
    	err = bt_enable(NULL);
    	if (err) {
    		printk("Bluetooth init failed (err %d)\n", err);
    		return 0;
    	}
    
    	printk("Bluetooth initialized\n");
    
    	start_scan();
    	return 0;
    }
    

  • Hi Einar, 
    Thank you very much for your reply. I tested using dk and found that it is indeed not a problem with create_param.timeout. After checking my own application code, I discovered that I passed the wrong time when using the delayed k_work, and bt_conn_disconnect() is called in the callback of the k_work. This is my mistake, and thank you again for your test.

Reply Children
No Data
Related