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

Commissioning over BLE #41

Open
kedars opened this issue Mar 4, 2023 · 6 comments
Open

Commissioning over BLE #41

kedars opened this issue Mar 4, 2023 · 6 comments
Labels
enhancement New feature or request

Comments

@kedars
Copy link
Collaborator

kedars commented Mar 4, 2023

No description provided.

@kedars kedars added the enhancement New feature or request label Mar 4, 2023
@jasta
Copy link
Contributor

jasta commented Sep 26, 2023

I'm interested in trying to add this, but I'm thinking about starting from the beginning and introducing an embedded-svc-style set of traits for BLE first. I'd really rather avoid going the monolith strategy of a complete BT implementation that supports every platform directly (i.e. not like https://crates.io/crates/btleplug or https://crates.io/crates/rumble) as I don't think that will scale well for the diverse set of customers that rs-matter could one day have. I also have a non-goal of implementing BLE or choosing a specific strategy for its implementation. The caller should just be able to inject whichever library meets our contract (e.g. nimble for esp-idf or bluez for Linux, whatever).

Thoughts?

EDIT: See rust-embedded/not-yet-awesome-embedded-rust#29 for a potential discussion with the broader Rust embedded community

@jasta
Copy link
Contributor

jasta commented Oct 6, 2023

An update here since it was discussed recently, a rough overview of my current strategy and timeline:

  1. Develop ble-peripheral, a trait only crate that defines a complete set of GATT server APIs and the BLE peripheral definitions to support it. This should be sufficient for all BLE embedded use cases I'm aware of, for Matter or otherwise. Status: Working locally, RFC by Oct 9.
  2. Develop bluer-ble-peripheral, an impl crate combining the BlueZ Rust API (BlueR) with ble-peripheral and a set of examples showing it in action. Status: Working locally, RFC by Oct 9.
  3. Develop PoC esp-idf-ble-peripheral, an impl crate combining the current esp-idf-svc BLE support with ble-peripheral. Status: Early research, RFC by Oct 16.
  4. Extend esp-idf-svc support to include all necessary use cases to support ble-peripheral. Apply fixes as necessary. Status: Early research, no code written, RFC by Oct 16.
  5. Implement BTP protocol using ble-peripheral for rs-matter. This will be a lot of work for sure but from the spec nothing seems too scary or hairy. The biggest issue will be if I have to do heavy refactoring of Matter to decouple transports; we'll see. Status: Reviewed Matter spec only, RFC by Oct 20.

Obviously these dates are just wild guesses but so far the work is pretty straight forward and I'm quite familiar with BLE transport work. If someone wants to re-order and speed up (5) I'm supportive of that, I can just merge in my work after the fact to make the support generalized.

An alternative I considered as well was to just develop the traits within rs-matter and have them only as fleshed out as Matter's BTP needs. I decided against this approach as it's still a huge amount of work given the scope of BTP and ends up with wayyyyyy less community value for embedded Rust.

@jasta
Copy link
Contributor

jasta commented Oct 6, 2023

Oh yeah, and it looks like someone is also squatting the ble-peripheral crate name, sigh: https://crates.io/crates/ble-peripheral. I'll reach out to the author soon.

@jasta
Copy link
Contributor

jasta commented Oct 8, 2023

Actually, I've decided to swap the order of (3) & (4) with (5). I also have (1) and (2) ready for preview, so I'm moving on to implementing BTP directly in Matter now.

@jasta
Copy link
Contributor

jasta commented Oct 11, 2023

I'm making good progress on generic support for BTP, there's really not that much sophistication there other than some simple windowing implementation you need to do. There are, however, a few issues that need to be resolved before I can get a PR up:

  1. Message Reliability Protocol (MRP) looks a bit too cozy in Exchange and may need to be abstracted. What's unclear to me is whether MRP is actually meant to be a supportable feature for all transports, given that it's explicitly part of the exchange flags. As in, if I wanted to, could I get the MRP protocol support engaged over TCP? If that's the case, the only change we might need is to just modify ExchangeCtx and use an Option<ReliableMessage> based on the exchange flags?
  2. Matter.run hardcodes the raw UDP transport backend (but it seems only this function, so bravo!). This means we'll need a breaking API change to provide some configuration of different transports. As I see it we have a couple of different options here: (a) keep the Matter.run API more or less the same and expand NetworkStack to support plugging in abstract backend transports (UDP, BTP, etc) or (b) go the mdns route and require that the caller fire up separate runners for each transport, with the current Matter.run really being run_udp. I'm of the opinion that we should actually lean more into (a) than we do today and merge the mdns runner into a pure UDP transport backend and make it so Matter.run is a declarative API where you set up everything you want to happen and just hit run and off you go. As it is now, simply forgetting to poll the mdns future means that you won't get mdns support. That said, I'm not married to any particular solution and definitely looking for feedback on the preferred approach.
  3. Commissioning seems a bit hardcoded to an IP-based transport (e.g. pake.rs talks about mdns directly). We might want to think about this in terms of (2) making for a more robust notion of transport roles not just sending/receiving raw packets. We might also need a global commissioning state machine that has an affinity to a particular transport but is otherwise agnostic. For example, you might want to say that commissioning should only occur at a given time over either BLE or UDP, never both at once. But UDP can be used as a fallback if BLE isn't available.

I don't think I'm quite ready to need answers to all of these questions, but just wanted to jot down my notes so as not to surprise anyone when PRs start coming in :)

@ivmarkov
Copy link
Contributor

Relevant PR here

Still in "Draft" as it needs more testing (including - if possible - unit tests). But other than that, it seems to work OK (testing with BlueZ and ESP-IDF's Bluedroid stack for now).

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

No branches or pull requests

3 participants