NCS Connection handle or alternative for keeping track of multiple connected devices

Hello,

I am using NCS v2.5.0 and I am working on an central application that keeps track of multiple connected peripheral devices. I wanted to manage the connected devices through a list of structs that contain some information about each connected device. The plan was to easily identify connection events based on their connection handle, and thus use the connection handle as the array index to identify the relevant device when an event happens similar to the below example:

static uint8_t on_sensor_data_received(
    struct bt_conn *conn,
    struct bt_gatt_subscribe_params *params,
    const void *data, uint16_t length)
{
    uint16_t conn_handle = conn->handle;
    struct peripheral_t peripheral = connected_devices[conn_handle];
    // Do something with peripheral
    
    return BT_GATT_ITER_CONTINUE;
}

The issue is that it seems that I cannot use the bt_conn struct pointer like that, because I get a 'pointer to incomplete class type "struct bt_conn" is not allowed' build error, even when I include <zephyr/bluetooth/conn.h>.

I use Visual Studio Code (with nRF Connect Extension), and when I go to the definition of the bt_conn struct, it takes me to conn_internal.h, which I cannot include. The definition there indicates that the handle is present in the bt_conn struct.

I am also tracking the RSSI of connected devices, and following the HCI Power Control example, I saw that you can get the connection handle using the bt_hci_get_conn_handle function from the HCI driver, however when I try to get the handle in the on_disconnected callback, the handle no longer exists using that approach(since there is a connection anymore).

So now I'm wondering, what is the best way to get a connection handle (from a bt_conn struct?) such that it also applies during the on_disconnected callback (i.e. connection handle of the lost connection)? Or is there a better way to create a list of structs that can be used to keep information from each connected device and that each individual struct can easily be extracted upon a connection event?

And why can I not do things with the bt_conn struct pointer, even if I include conn.h?

Parents
  • Ho Wout

    The bt_conn struct is a opaque type, meaning the internal fields are not known outside the Bluetooth libraries. This is by design to avoid applications altering the internal fields, and to allow changing the internals without risk of breaking application code. 

    Instead you should simply use the pointer itself as the handle, and use that to reference the connection. 

    I made a multi link demo some time back and used this principle to keep track of the connected devices, and saved various link specific state data in a struct that also included the *conn pointer. You can see the struct here

    I must admit to not being very familiar with opaque C types myself, and I found this article quite illuminating. 

    Best regards
    Torbjørn

  • Hi Torbjørn,

    It's been a while since I asked this question, but after developing quite a bit more and getting more familiar with the SDK and the patterns used there, I was wondering if we can't just use CONTAINTER_OF(conn, struct per_context_t, conn) (in the case of the project you shared) to get the correct per_context pointer?

    It seems that that does exactly what is needed without having to loop over the array, and hence would achieve O(1) complexity. Or am I missing something as to why this won't work (reliably) in this case?

Reply
  • Hi Torbjørn,

    It's been a while since I asked this question, but after developing quite a bit more and getting more familiar with the SDK and the patterns used there, I was wondering if we can't just use CONTAINTER_OF(conn, struct per_context_t, conn) (in the case of the project you shared) to get the correct per_context pointer?

    It seems that that does exactly what is needed without having to loop over the array, and hence would achieve O(1) complexity. Or am I missing something as to why this won't work (reliably) in this case?

Children
No Data
Related