nrf-softdevice
nrf-softdevice copied to clipboard
Add support for peripheral BLE legacy peering and bonding
This adds peering and bonding support for peripheral devices. Bonding is supported by a new advertise_bondable
function which takes a &'static dyn BondHandler
that provides the methods needed to create, store and retrieve the LTK for the bond.
Very excited to see a bonding API. Shouldn't the new trait functions be async
, though, to match the rest of the crate? Especially since the flash interface in this crate, which would probably be used to implement bonding, is already async
.
Very excited to see a bonding API. Shouldn't the new trait functions be
async
, though, to match the rest of the crate? Especially since the flash interface in this crate, which would probably be used to implement bonding, is alreadyasync
.
That would be ideal, unfortunately there are a couple of problems:
- We don't want to block the ble event loop from handling other events during async handling of bond requests. If the trait functions were async, that would mean they should be spawned as new tasks. That would require an allocator which we can't count on in no-std.
- An async trait (without an allocator) relies on GAT and TAIT. Those features make the trait not object-safe. That means we couldn't store a
&dyn
reference but would have to make everything generic on the type of theBondHandler
. That generic parameter would quickly pollute everything because of how deep in the crate theBondHandler
functions need to be called.
In general, if the implementation of the BondHandler
methods has async requirements, the application should forward the request (via a Channel
or similar) to a task it creates for that purpose. The functions that are expected to provide a reply asynchronously (e.g. enter_passkey
and recv_out_of_band
) take a ...Reply
struct that can be stored or sent over a channel to other tasks for this purpose. The get_key
implementation currently does need to be synchronous; the expectation is that the bond database can be loaded into RAM or accessed via memory-mapped flash and does not need to be asynchronous. Let me know if that's a problem for your application.
In general, if the implementation of the
BondHandler
methods has async requirements, the application should forward the request (via aChannel
or similar) to a task it creates for that purpose. The functions that are expected to provide a reply asynchronously (e.g.enter_passkey
andrecv_out_of_band
) take a...Reply
struct that can be stored or sent over a channel to other tasks for this purpose. Theget_key
implementation currently does need to be synchronous; the expectation is that the bond database can be loaded into RAM or accessed via memory-mapped flash and does not need to be asynchronous. Let me know if that's a problem for your application.
That makes sense. I don't have any particular requirements, though compatibility with the Bluefruit library that's commonly used on Arduino would be nice. I started working on that rabbit hole (they store bonds in a littlefs on internal flash at 0xED000-0xF4000) and I've got working code to read the files now, but I haven't tried connecting it to your interface yet.