Closed AdinAck closed 6 months ago
Does there really need to be separate macros for adv_data and scan_data? It's the same format for both. Also, I don't think the macro should do length validation. Legacy advertising and scan packets are limited to 31 bytes, but extended advertising packets can be up to 254 bytes long.
Does there really need to be separate macros for adv_data and scan_data?
The only difference is the error message when it exceeds the byte limit, also i'm no expert in the differences between them so I just wanted to have it set up for future implementation differences, I can remove generate_scan_data
if you like.
...I don't think the macro should do length validation. Legacy advertising and scan packets are limited to 31 bytes, but extended advertising packets can be up to 254 bytes long.
Ok cool I didn't know this, I just read somewhere that it was max 31 bytes, and noticed with my current Softdevice config that there would be a runtime error if either exceeded 31 bytes, but I don't want to defer this check to runtime, maybe somehow the user could specify legacy or extended. For now though, I will comment out the length validation.
A few other notes:
I think it's important to respect the user's order of fields for the advertising block. Generally speaking it shouldn't matter (other than flags coming first if present), but there may be edge cases.
Good idea I'll get on that.
It's possible to have a mix of 16-bit and 128-bit services in an advertising block. You might even mix a complete 16-bit service field with an incomplete 128-bit service field or vice-versa. I'm not sure if that is supported here?
No it's not, an easy addition though.
Trying to keep up with the list of valid 16-bit UUIDs is probably a bit of a losing battle. I'd recommend an escape hatch to let users provide a custom 16-bit UUID.
Haha yes that's what the Custom
service is for. Although I didn't test it with 16bit services I'll make sure that works.
In addition to 16-bit and 128-bit services, there are also 32-bit service UUIDs (I believe these are generally assigned to companies by the Bluetooth SIG).
Yes I list this as a future capability.
In fact, there are a number of data types other than flags, name, or services which can be used in advertising (you can see the current list in Table 1.1 of the Core Specification Supplement). I'm not sure it makes sense to try to support the whole list, but I think you need some sort of escape hatch to let users say "data type N with bytes [1, 2, 3]".
I also list this as something to be implemented in the future.
Some data types (such as manufacturer data) can be (and may need to be) repeated within an advertising block.
My knowledge of how BLE works is in it's infancy, once I understand this I will probably implement it.
Much like how you said the gatt_server proc macro is incomplete and the builder API should be used for more complex systems, this proc macro is also incomplete but the idea is it's better than nothing and is good enough that it fits into every example.
In addition to 16-bit and 128-bit services, there are also 32-bit service UUIDs (I believe these are generally assigned to companies by the Bluetooth SIG).
Yes I list this as a future capability.
Oops, sorry. Poor reading comprehension on my part. 😅
Some data types (such as manufacturer data) can be (and may need to be) repeated within an advertising block.
My knowledge of how BLE works is in it's infancy, once I understand this I will probably implement it.
So the manufacturer data is sort of a catch-all that lets people stick arbitrary data in advertising packets. For example, the big OS vendors (Google, Microsoft, maybe Apple?) have special manufacturer data that can let your device pair faster or more easily with their OS. So if you want to support both Google Fast Pair and Windows Swift Pair you'd need manufacturing data fields from both vendors.
Much like how you said the gatt_server proc macro is incomplete and the builder API should be used for more complex systems, this proc macro is also incomplete but the idea is it's better than nothing and is good enough that it fits into every example.
Yep completely agreed. Especially with things like manufacturer data you're never going to have a complete version anyway. As long as there's a way to provide an arbitrary key/value pair I think what you've already got is plenty.
That's super interesting, I had no idea different OSs had such a capability.
I'll add the following sometime soon:
This is definitely a missing piece in the current API. Cannot wait to see it merged!
ch58x-hal met the same problem, as it's also a BLE MCU. I am concerned that excessive abstraction may lead to a significant deviation in the programming model compared to the official C version. Consequently, all online and official references and sample projects would become obsolete.
Replaced by #214
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, these code snippets are equivalent at runtime, as the array is generated by the proc macro at compile time.
Changes
Cargo
There are two additional dependencies:
strum
andstrum-macros
.nrf-softdevice-macro
In
lib.rs
there is one new proc macro:generate_adv_data
, along with the associated structures made for its implementation.examples
All applicable examples have been updated to use the new macro instead of the raw array.
Features
Future
Examples
Multiple 16bit Services
Arbitrary 128bit Service
Notes
I tried my best to decouple the structures as best as I could, there is a little bit of coupling left but I'd say it's a fine start