Connection Creation Timeout in NCS v3.2.1

While running scan & connection tests with NCS 3.2.1, I encountered frequent connection timeouts (bt_hci_core: Connection creation timeout triggered) when using the Nordic protocol stack. The issue disappeared immediately after switching to the Zephyr protocol stack.
What could be the root cause of this discrepancy?

This is the master side code I used during the testing.
/* main.c - Application main entry point */

/*
 * Copyright (c) 2015-2016 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <bluetooth/scan.h>
#include <errno.h>
#include <stddef.h>
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/conn.h>
#include <zephyr/bluetooth/gatt.h>
#include <zephyr/bluetooth/hci.h>
#include <zephyr/bluetooth/uuid.h>
#include <zephyr/kernel.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/types.h>

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(main, CONFIG_MAIN_LOG_LEVEL);

static struct bt_conn *default_conn;

static void connected(struct bt_conn *conn, uint8_t err) {
  char addr[BT_ADDR_LE_STR_LEN];

  bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));

  if (err) {
    LOG_INF("Failed to connect to %s %u %s\n", addr, err,
            bt_hci_err_to_str(err));

    bt_conn_unref(default_conn);
    default_conn = NULL;
    return;
  }

  if (conn != default_conn) {
    return;
  }

  LOG_INF("Connected: %s\n", addr);

}

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));

  LOG_INF("Disconnected: %s, reason 0x%02x %s\n", addr, reason,
          bt_hci_err_to_str(reason));

  bt_conn_unref(default_conn);
  default_conn = NULL;

}

BT_CONN_CB_DEFINE(conn_callbacks) = {
    .connected = connected,
    .disconnected = disconnected,
};

static void scan_filter_match(struct bt_scan_device_info *device_info,
                              struct bt_scan_filter_match *filter_match,
                              bool connectable) {
  char addr[BT_ADDR_LE_STR_LEN];

  bt_addr_le_to_str(device_info->recv_info->addr, addr, sizeof(addr));

  LOG_INF("Filters matched. Address: %s connectable: %s\n", addr,
          connectable ? "yes" : "no");

  int err = bt_scan_stop();
  if (err) {
    LOG_INF("Stop LE scan failed (err %d)\n", err);
  }
}

static void scan_connecting_error(struct bt_scan_device_info *device_info) {
  LOG_ERR("Connecting failed\n");
}

static void scan_connecting(struct bt_scan_device_info *device_info,
                            struct bt_conn *conn) {
  default_conn = bt_conn_ref(conn);
}

static void scan_filter_no_match(struct bt_scan_device_info *device_info,
                                 bool connectable) {

  // LOG_INF("no matched");
}

BT_SCAN_CB_INIT(scan_cb, scan_filter_match, scan_filter_no_match,
                scan_connecting_error, scan_connecting);

int main(void) {
  int err;

  err = bt_enable(NULL);
  if (err) {
    LOG_INF("Bluetooth init failed (err %d)\n", err);
    return 0;
  }

  LOG_INF("Bluetooth initialized\n");

  struct bt_scan_init_param scan_init = {
      .connect_if_match = 1,
      .scan_param = BT_LE_SCAN_PARAM(
          BT_LE_SCAN_TYPE_PASSIVE, BT_LE_SCAN_OPT_NONE,
          3200, 3200),
  };

  bt_scan_init(&scan_init);
  bt_scan_cb_register(&scan_cb);

  bt_addr_le_t addr;
  err = bt_addr_le_from_str("e1:00:00:02:0a:a0", "public", &addr);
  if (err) {
    LOG_INF("bt_addr_le_from_str (err %d)\n", err);
    return 0;
  }

  /* 例如按 UUID 过滤 */
  err = bt_scan_filter_add(BT_SCAN_FILTER_TYPE_ADDR, &addr);
  if (err) {
    LOG_INF("Scanning filters cannot be set (err %d)\n", err);
    return 0;
  }

  err = bt_scan_filter_enable(BT_SCAN_ADDR_FILTER, false);
  if (err) {
    LOG_INF("Filters cannot be turned on (err %d)\n", err);
    return 0;
  }

  err = bt_scan_start(BT_SCAN_TYPE_SCAN_PASSIVE);
  if (err) {
    LOG_INF("Scanning failed to start (err %d)\n", err);
  }

  return 0;
}
When I added the following configuration to the app.overlay file, the timeout issue no longer occurred when using the Zephyr protocol stack.
Oddly enough, no connection timeouts occurred when I tested with nrf5-sdk. Are the Nordic protocol stacks in nrf5-sdk and NCS different? How should I resolve this issue?
Parents
  • Hi,

    Are the Nordic protocol stacks in nrf5-sdk and NCS different?

    The link layer (controller) is basically the same, since the SoftDevice Controller in nRF Connect SDK is a continuation of those layers from the SoftDevice from nRF5 SDK. It has however been updated and maintained since nRF5 SDK, so there are some differences, yes.

    The host layer is different in nRF Connect SDK, but that host layer is also the same in nRF Connect SDK regardless of whether you use the SoftDevice or Zephyr controller.

    err = bt_addr_le_from_str("e1:00:00:02:0a:a0", "public", &addr);

    Do you see the same issue with other addresses as well? In particular, there are four sub-types of addresses, indicated by the two most significant bits of the address, where 0b00 is Non-resolvable private address, 0b01 is Resolvable private address, 0b11 is Static device address, and 0b10 is Reserved for future use. Is this happening with any static device address (which from what I understand is the address type you currently use), and also does it happen with addresses where there are shorter stretches of 0 bits (you currently have at least 20 consecutive zeroes in that address, each 0 in the above notation is four bits of 0.)

    Regards,
    Terje

  • Hi,
    I tried using other types of addresses and reducing the number of zeros in the MAC address, yet the connection timeout issue still occurs.
    I found during testing that the connection timeout issue still occurs when using the Zephyr stack, only with a lower occurrence rate—and this issue was not observed in previous tests.

  • Hi,

    Do you have a sniffer trace from when this is happening? (nRF Sniffer or other.)

    Regards,
    Terje

Reply Children
No Data
Related