embassy-rs / trouble

A Rust Host BLE stack with a future goal of qualification.
Apache License 2.0
86 stars 11 forks source link

Add Attribute Data On Callback functionality #98

Open nm17 opened 2 weeks ago

nm17 commented 2 weeks ago

Current problem

Current GATT API requires the user to create a buffer for data that can't be changed afterwards by the outside code easily and requires the buffer to live as much as the device does ('d).

This limits the possible returned values from GATT to a fixed length, without modifying the Attribute Table, which isn't good developer experience.

My proposed solution

Add two variants for AttributeData which allow read and write functionality, containing the props and the callback, which processes either reads or writes. I'm not exactly sure about the parameters and return type for the callback, I will think about that later. Any suggestions are welcome.

The questions for now

nm17 commented 2 weeks ago

Should this variant be done by:

Honestly, either way is fine IMHO, since I don't think many people are matching on AttributeData either way.

lulf commented 2 weeks ago

Thanks for raising the issue and sharing your ideas. I think storing the callback per attribute is not going to work generically without an allocator? But what could work is providing a callback to the gatt server perhaps, and then pass the handle and 'buffer' to the callback.

Regarding breaking APIs I wouldn't worry about it at this point, we don't have any release on crates.io yet.

nm17 commented 2 weeks ago

I guess anything that allocates will be off limits for this repo? Or can I add a feature flag for this and put the additional AttributeData variant and functions that use it under it?

lulf commented 2 weeks ago

Yes, I would like to avoid alloc. Especially if we can get almost similar functionality with just a slight inconvenience in the api.

lulf commented 2 weeks ago

Maybe you could look at the gatt api for nrf softdevice for inspiration. It allows using heapless Vec types as attribute types, which allows for not always copying all the data.

lulf commented 2 weeks ago

I'll throw another idea into the mix :)

What if it was possible to make trait out of the AttributeTable functionality, so that you could potentially replace that one with a type that only worked using callbacks. This way you could potentially run a gatt server that didn't require specifying an AttributeTable up front, and AttributeTable could be one implementation of such a trait. Then you could potentially provide your own alloc-based implementation that had the more convenient experience.

I'm not sure if it's feasible or not, and would be a lot of work, but sounds like it could have some nice benefits.

lulf commented 2 weeks ago

Also, regarding your first idea, it might be possible to have that closure per attribute, if you look at how it's done in bleps https://github.com/bjoernQ/bleps/blob/main/example/src/main.rs#L88

nm17 commented 2 weeks ago

What if it was possible to make trait out of the AttributeTable functionality, so that you could potentially replace that one with a type that only worked using callbacks

That would be great, honestly. That would provide a lot of flexibility for me. I'll see what I can do