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

  • Thank you Torbjørn, I wasn't familiar with opaque C types as well. The article you posted did help to understand. 

    I had a look at your demo and I can definitely make something like that, so thanks for sharing. I was just hoping to have something with O(1) complexity instead of O(n) since I expect that I will have to do the lookup regularly (every time data comes in, for each of the connected devices). But it may not really make that much a difference, so I'll start with your demo implementation and go from there.

  • Hi Wout

    I agree that O(n) doesn't feel right for a simple search like this, but considering how small N would typically be in these applications I don't think it makes sense to spend much time optimizing it. Not sure how many connections you expect to run in parallel though, in my case it's usually 10 or less. 

    If you sort the conn references you could do a quick binary search and get down to O(log(n)), but again I doubt it's worth the effort unless you plan to support dozens of connections.

    Best regards
    Torbjørn

  • Hi Torbjørn,

    Thank you again for your feedback. I plan to allow to max out the max amount of connections supported by the Softdevice, so that would be 20 which is still not that much indeed. The amount of data exchanged between the central and peripherals is also pretty small, so the search should take too much of a toll.

Reply Children
Related