Closed AdinAck closed 11 months ago
I just realized I need to check if the built advertisement data exceeds the maximum allowed length... I'll implement that in a bit.
Done. Also realized this repo is not really set up for unit tests so I removed them.
This looks pretty good to me. I prefer it to the macro version, though it does have some runtime cost. One issue I see is that hard-coding ADV_LEN
means it doesn't support extended advertising packets (which can be up to 254 bytes) and also means that you can't use a smaller buffer if your advertising packet is less than 31 bytes. I wonder if you could have the builder take in the buffer to use as a parameter or use a const generic for the packet length.
Another feature that would be nice to have is a name
function that fills the remaining space in the buffer with as much of the name that fits. If the whole name fits it gives it type FullName
, otherwise ShortName
.
...though it does have some runtime cost. ...it doesn't support extended advertising packets (which can be up to 254 bytes)
Both of these are listed as future changes.
I wonder if you could have the builder take in the buffer to use as a parameter or use a const generic for the packet length.
Yeah I've been thinking about this... I can't think of a good way to utilize generics and still allow the order to be controlled as you have made it clear you want.
Passing in the buffer is sketchy since this is at runtime, how would the user decide the length each time they change the advertisement data? I decided a small burst of some memory usage is better than an ambiguity related panic.
Another feature that would be nice to have is a
name
function that fills the remaining space in the buffer with as much of the name that fits. If the whole name fits it gives it typeFullName
, otherwiseShortName
.
Great idea, I'll get right on this.
I wonder if you could have the builder take in the buffer to use as a parameter or use a const generic for the packet length.
Yeah I've been thinking about this... I can't think of a good way to utilize generics and still allow the order to be controlled as you have made it clear you want.
Passing in the buffer is sketchy since this is at runtime, how would the user decide the length each time they change the advertisement data? I decided a small burst of some memory usage is better than an ambiguity related panic.
Const generic version could look like this (and just use N
in place of ADV_LEN
everywhere):
pub struct AdvertisementData<const N = 31> {
buf: [u8; N],
ptr: usize,
}
The buffer version would be something like (using self.buf.len()
in place of ADV_LEN
):
pub struct AdvertisementData<'a> {
buf: &'a mut [u8],
ptr: usize,
}
impl<'a> AdvertisementData<'a> {
pub fn new(buf: &'a mut [u8]) -> Self {
Self {
buf,
ptr: 0,
}
}
...
}
When you said const generics I thought you were referring to the builder supporting constant evaluation (so it could be a const
). What I am working on now is something like AdvertisementData<Standard>
or AdvertisementData<Extended>
.
Passing in a buffer would make it so that the user would have to compute all of the bytes themselves to know the length, defeating the purpose of the builder.
Motivation
This is how adv/scan data is currently configured:
You don't often get to deal with raw bytes in a top level interface!
Proposal
With this PR, advertisement/scan data can be generated with a builder rather than raw bytes.
Changes
ble
examples
Some examples have been updated to use the new builder.
Features
Future
Examples
Multiple 16 bit Services
Arbitrary 128bit service
Raw Bytes
Adaptable Name
Extended Data
Notes
Some slight adjustments other than what I listed in the Future section may be needed, but I believe this pretty much covers all the bases and will be very useful.