Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Async callback to gatt_server::run #184

Open
uhinze opened this issue May 29, 2023 · 5 comments
Open

Async callback to gatt_server::run #184

uhinze opened this issue May 29, 2023 · 5 comments

Comments

@uhinze
Copy link

uhinze commented May 29, 2023

Thank you for this project, I'm starting with Rust and embedded programming and happy to have found this.

My current issue: It doesn't seem possible to make the callback f to gatt_server::run async.

What I want to achieve is: Upon receiving a BLE event, turn on the LED for a couple of seconds, then turn off. Pseudo-code:

led.set_high();
Timer::after(Duration::from_secs(1)).await;
led.set_low();

Happy for any pointers how to implement this another way.

@alexmoon
Copy link
Contributor

It's not possible for the callback to be async. You can do what you're wanting by sending a message or signal from your callback to an async task or spawning an async task from the callback.

@sureshjoshi
Copy link

@uhinze Did you come up with a re-usable pattern that you liked? I'm working on something where I'd need this too. Almost identically start something with a timer to turn it off later, concept. e.g. Start scanning for devices with a timeout, and accept a user-generated stop otherwise.

I had originally planned to spawn a task for this - but I wasn't sure how that works at runtime. As in, can a spawned task functionally act as a lambda?

@uhinze
Copy link
Author

uhinze commented Jun 29, 2023

I just solved the problem on my end.
@alexmoon the pointer to channels was very helpful, thank you! Took me a while to figure out you meant this Channel.
So now I'm spawning an async task and wait for new messages in the channel in an endless loop.

I additionally had to solve the challenge to be able to use the Server and current Connection in the other task, as I wanted to send a response to the BLE client after successful processing. I solved this using static_cell, Mutex, and RefCell.

@sureshjoshi I'm not sure if your challenge is the same one. I understand you want to interrupt device scanning after some timeout? Not sure how that would work tbh. A task in Embassy from my understanding has a static lifetime, so it's not really meant for a request/response style interaction. Would suggest to open a new issue for this.

@sureshjoshi
Copy link

Thanks for the reply!

I think what you've landed on might work close to what I had in mind overall. I had originally imagined selecting on some futures, but I would also want a "clean" scan stop, rather than an interrupted future (e.g. return scanned devices).

My other idea was to do something similar to what you're doing which is an endless task that accepts control messages via a channel.

I'll be testing this out over the weekend - so one way or another, I'll have some sort of solution :)

@osiler
Copy link

osiler commented Sep 15, 2023

The solution I found was to use a static cell, and share &'static gatt_server::MyServer as arguments to each task.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants