BLE peripheral with multiple connections

I'm struggling to get a peripheral device to work with two simultaneous connections. I have attached my configuration (for the application) and my connect/disconnect callbacks, with the advertizing data.

  1. I'm advertizingwith BT_LE_ADV_OPT_CONNECTABLE and not with ONE_TIME flag. I understand this should keep adv running until I manually stop it. This is my desired behaviour. Upon the first connection to the device, however, I already get a warning from bt_hci_core   <wrn> bt_hci_core: opcode 0x200a status 0x0d. Where 0x0d means CONNECTION REJECTED DUE TO LIMITED RESOURCES. Note that this is different from CONNECTION LIMIT EXCEEDED (0x09) that I read in other posts. I have the feeling that the controller is still somehow allocating only resources for one single peripheral, despite the BT_MA_CONN=2 configuration. 
    I read in some posts about the CONFIG_BT_CTLR_SDC_PERIPHERAL_COUNT config, which seems to address this, however this should be relevant only in the case where the device is also acting as Central device. I cannot select this config in my application. However, if I check the compiled .config in the hci_ipc application, indeed there I find this configured to 1 and with BT_CENTRAL enabled. I'm now confused on what I should do to get my application running. I don't think I'm expected to modify the hci_ipc sample manually
  2. On a different note, I'm also confused on the purpose of bt_conn_ref() and bt_conn_unref(). They are not always present in the ble samples, and I'm not sure I understand what they are used for (the examples seem to work without them).

Many thanks for the help!

CONFIG_BT=y
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_MAX_CONN=2
# CONFIG_BT_CTLR_SDC_PERIPHERAL_COUNT=2 # this is not selectable in the application?
CONFIG_BT_USER_DATA_LEN_UPDATE=y
CONFIG_BT_USER_PHY_UPDATE=y
CONFIG_BT_GAP_AUTO_UPDATE_CONN_PARAMS=n

static void connected(struct bt_conn *conn, uint8_t code){

    if(code){
        LOG_ERR("Connection failed (code 0x%0x2)", code);
        // bt_conn_unref(conn);
        return;
    }

    conn_count++;
    bt_conn_ref(conn);

    __ASSERT(conn_count < CONFIG_BT_MAX_CONN, "Conn counting error");

    LOG_INF("Connected to Client (code 0x%0x2)", code);

    if(conn_count >= CONFIG_BT_MAX_CONN){
        int err = stop_advertising();
        if(err){
            LOG_ERR("Advertising failed to start (err %d)", err);
        }
    }

    post_event_async(BLE_EVT_CONNECTED);
}

static void disconnected(struct bt_conn *conn, uint8_t code){

    LOG_INF("Disconnected from Client (code 0x%0x2)", code);

    bt_conn_unref(conn);

    conn_count--;

    __ASSERT(conn_count <= CONFIG_BT_MAX_CONN, "Conn counting error");

    int err = start_advertising();
    if(err){
        LOG_ERR("Advertising failed to start (err %d)", err);
    }

    post_event_async(BLE_EVT_DISCONNECTED);
}

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

static int start_advertising(void){
    struct bt_data ad[] = {
        BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
        BT_DATA_BYTES(BT_DATA_NAME_SHORTENED, CONFIG_BT_DEVICE_NAME),
    };
    return bt_le_adv_start(
        BT_LE_ADV_PARAM(BT_LE_ADV_OPT_CONNECTABLE,
            BT_GAP_ADV_FAST_INT_MIN_2,
            BT_GAP_ADV_FAST_INT_MAX_2,
            NULL), // undirected adv
        ad, ARRAY_SIZE(ad), NULL, 0);
}

PS: I'm using NCS 2.7.0 on nrf5340

  • Hi Yaxit,

    For the question regarding bt_conn_ref() and unref(), I recommend giving this thread a read:  Info about bt_conn_ref and bt_conn_unref?

    Onto the topic #1. First, we need to remember that you are using the nRF5340, so the BT Host and Controller each stays on a different application image. The Host resides on the Application Core image, while the Controller resides on the Network Core image.

    You are right in your identifying the two Kconfig that are relevant to changing the number of concurrent connections, CONFIG_BT_MAX_CONN and CONFIG_BT_CTLR_SDC_PERIPHERAL_COUNT.

    CONFIG_BT_MAX_CONN is relevant for both the BT Host and Controller and therefore must be set for both the Application and Network Core image.

    CONFIG_BT_CTLR_SDC_PERIPHERAL_COUNT is only relevant for the BT Controller.
    In particular, it is only relevant for the SoftDevice Controller, Nordic's proprietary BT Controller.
    It must be set for the Network Core image.

    That being said, I see that maybe you are having difficulty setting the configurations for the Network Core image.

    Since you have a child image named "hci_ipc," I believe you are building the image pair using the child and parent solution
    In this setup, the simplest way to add Kconfig to the network core is by creating an overlay file at <project dir>/child_image/hci_ipc.conf.

    Inside that file, you can simply set:

    CONFIG_BT_MAX_CONN=3
    CONFIG_BT_CTLR_SDC_PERIPHERAL_COUNT=2

    or, if you don't need the Central feature,

    CONFIG_BT_CENTRAL=n
    CONFIG_BT_MAX_CONN=2

    Hieu

Related