feat(052): runtime-neutral MQTT connector - #253
Open
lxsaah wants to merge 20 commits into
Open
Conversation
… Embedded backends
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`Self::tls` is `embassy-tls`-gated, but `make doc` builds this crate with `embassy-runtime` only, so the link failed the docs gate in CI. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…hance documentation
- Implemented a new `manager` module to handle per-session broker state, event handling, and message pumping. - Updated `MqttConnector` to support `Delay` and `StreamDialer` traits for embedded systems. - Refactored `MqttSink` and `MqttSource` to use action and event channels directly, removing unnecessary wrappers. - Introduced `ClientDelay` to bridge core's `Delay` with the MQTT client's requirements. - Enhanced the `run_sessions` function to manage MQTT sessions more effectively, ensuring reconnections and resubscriptions. - Updated tests to ensure proper session reconnection and resubscription behavior. - Adjusted Tokio adapter to implement `Delay` for seamless integration with the connector.
…ial support - Consolidated the MqttConnector structure to allow seamless switching between Native and Embedded backends without separate builders. - Introduced credential handling in the Native backend, allowing credentials to be set via the MqttConnector interface. - Updated the Embassy client to streamline the transport setup and improve TLS handling. - Enhanced tests to verify credential transmission for both backends, ensuring consistent behavior across different configurations. - Removed deprecated builder patterns and unnecessary complexity in the connector implementation.
- Implement SNTP codec for encoding and parsing SNTP packets, including request and reply handling. - Introduce TLS transport for the Embassy MQTT client, supporting secure connections with certificate verification. - Refactor the library structure to separate native and embedded implementations, enhancing modularity. - Update the MQTT connector to support both plain and secure MQTT connections, with appropriate error handling and logging.
- Introduced a new feature `_test-tls-broker` for testing MQTT over TLS with a pinned self-signed root CA. - Updated the Makefile to include new test commands for the MQTT connector with TLS. - Modified `Cargo.toml` to add dependencies for embedded TLS and SNTP. - Refactored the `EmbeddedTls` struct to use a caller-supplied transport instead of owning the network stack. - Implemented a new `WallClock` for certificate validity checks in the absence of an RTC. - Created a new test `tls_broker.rs` to validate the MQTT handshake over TLS. - Updated the example to demonstrate the use of MQTT over TLS with SNTP for time synchronization.
…ges and enhanced features for std and no_std runtimes
…ated docs `make doc` runs `cargo doc` per feature leg with `-D warnings`, so an intra-doc link that resolves on one leg and not another fails the build. Five such links had crept in: - `[Embedded]` in the ungated backend table, which only exists with the embedded backend - `[build]` and `[WallClock]`, both private - `[SntpClock]`, deleted when the TLS clock became the runtime's - `[sntp]`, now `embassy-tls`-gated while `tls.rs` is `embedded-tls` The `doc` target only covered `std` and `embassy-runtime`, which is why only the first two reached CI; add the `embedded`, `embedded-tls` and `embassy-tls` legs so the rest cannot recur silently. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Wave C of design 052. MQTT is the exception among the connectors and stays that way deliberately — see below — but the embedded backend now takes a caller-supplied transport, which is what makes a FreeRTOS port possible without touching this crate.
Why MQTT keeps two protocol clients
Unifying on
mountain-mqttwas considered and rejected: it does not support QoS 2 (Qos2NotSupported; the codec haspubrec/pubrel/pubcomp, the state machine does not use them) and itstokiomodule has no TLS — while the Tokio connector exposes both.rumqttccannot ride the neutral layer either: itsTransportis a closed enum, so no stream can be injected.So one
MqttConnector<B>over two backends, which is the seam that keeps unification a later, small change — if QoS 2 and a TLS connection land in the fork, deletingNativeis a deletion, not a rewrite.Nativerumqttc(std)Embedded<D>mountain-mqtt(no_std)embedded-tlsBreaking
The Tokio path is unchanged —
MqttConnector::new(&url)still. Embassy callers supply the transport:The two new statics are not new RAM: the previous commit already allocated them inside the connector as private
StaticCells. They are now visible and sizeable by the caller.On FreeRTOS the same line is
.transport(LwipNet::tcp()), with no edit here.Worth a look in review
run_with_subscriptionsis gone. It bindsembassy_net::Stackand cannot take a transport, so injecting one meant giving it up — and with it, reconnect-and-resubscribe. That behaviour is now explicit intransport::run_sessions, one loop for both plain and TLS, extracted from the TLS path that was already running it in production.The transport seam is
mountain-mqtt's ownConnection, not core'sByteStream. The client needsreceive_if_ready— a non-blocking peek — whichByteStreamdoes not express and a TLS session cannot provide (this crate's ownembassy_tlsdocuments why).SocketTransport<D>bridges from core'sStreamDialerfor adapters whose stream also offersRead + Write + ReadReady, which is the path a new runtime takes.EmbassyTcpStreamgainedembedded_io_async::{Read, Write, ReadReady}by delegation — design 052 §6 specified this and wave A had not delivered it.tests/embassy_broker.rsdrives the whole connector against a fake broker over two crossover-wiredembassy-netstacks, asserting CONNECT and SUBSCRIBE reach the wire. The subscribe is the propertyrun_with_subscriptionsused to own; without it inbound routing dies silently on the first reconnect. CI has nomosquitto, hence the fake.Not addressed
mqtts://stays Embassy-only —set_unix_timehas no neutral home (design §9). SNTP is likewise unported, since it serves only that path.Verification
make checkclean: 2 023 tests, 0 failures, all stages.