From 300070ce0aaf11964eccfba556c60ad1842ecde5 Mon Sep 17 00:00:00 2001 From: Justin Kovacich Date: Tue, 28 Apr 2026 21:15:38 -0400 Subject: [PATCH] phase 19a: scaffold simple-someip-embassy-net workspace member MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New crate at `simple-someip-embassy-net/` providing the reference no_std backend for `simple-someip`'s transport-trait surface. As of this commit, the crate is scaffolded only: - `Cargo.toml` depends on `simple-someip` (default-features = false, client+server+bare_metal) and `embassy-net = "0.4"` (the last release line that builds against `embassy-sync 0.6`, which is what simple-someip currently uses; bumping both deps in lockstep is its own future phase). - `src/lib.rs` declares `factory` and `socket` modules plus `pub use` re-exports for the eventual `EmbassyNetFactory` / `SocketPool` / `EmbassyNetSocket` surface. - `src/factory.rs` skeleton declares `SocketPool` and `EmbassyNetFactory<'a, POOL, RX_BUF, TX_BUF>` types with stubbed-out fields (`_todo: ()`); actual buffer storage and the `TransportFactory` impl land in 19b. - `src/socket.rs` skeleton declares `EmbassyNetSocket` placeholder; full `TransportSocket` impl lands in 19c. - `README.md` documents target shape (post-19c) and the surrounding bare-metal-plan-v3 phase 19 framing. Workspace `Cargo.toml` adds the new member. Verification: cargo build -p simple-someip-embassy-net ✓ cargo build -p simple-someip-embassy-net --target thumbv7em-none-eabihf ✓ cargo build --workspace --all-features ✓ cargo clippy --workspace --all-features -- -D warnings -D clippy::pedantic ✓ cargo fmt --all --check ✓ Co-Authored-By: Claude Opus 4.7 (1M context) --- Cargo.lock | 395 ++++++++++++++++++++++- Cargo.toml | 1 + simple-someip-embassy-net/Cargo.toml | 59 ++++ simple-someip-embassy-net/README.md | 54 ++++ simple-someip-embassy-net/src/factory.rs | 81 +++++ simple-someip-embassy-net/src/lib.rs | 49 +++ simple-someip-embassy-net/src/socket.rs | 19 ++ 7 files changed, 655 insertions(+), 3 deletions(-) create mode 100644 simple-someip-embassy-net/Cargo.toml create mode 100644 simple-someip-embassy-net/README.md create mode 100644 simple-someip-embassy-net/src/factory.rs create mode 100644 simple-someip-embassy-net/src/lib.rs create mode 100644 simple-someip-embassy-net/src/socket.rs diff --git a/Cargo.lock b/Cargo.lock index e20bf97..02a5bd3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,12 +2,54 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "as-slice" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45403b49e3954a4b8428a0ac21a4b7afadccf92bfd96273f1a58cd4812496ae0" +dependencies = [ + "generic-array 0.12.4", + "generic-array 0.13.3", + "generic-array 0.14.9", + "stable_deref_trait", +] + +[[package]] +name = "as-slice" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "516b6b4f0e40d50dcda9365d53964ec74560ad4284da2e7fc97122cd83174516" +dependencies = [ + "stable_deref_trait", +] + +[[package]] +name = "atomic-polyfill" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4" +dependencies = [ + "critical-section", +] + +[[package]] +name = "atomic-pool" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58c5fc22e05ec2884db458bf307dc7b278c9428888d2b6e6fad9c0ae7804f5f6" +dependencies = [ + "as-slice 0.1.5", + "as-slice 0.2.1", + "atomic-polyfill", + "stable_deref_trait", +] + [[package]] name = "bare_metal_client" version = "0.0.0" dependencies = [ "critical-section", - "embassy-sync", + "embassy-sync 0.6.2", "simple-someip", "tokio", ] @@ -17,11 +59,17 @@ name = "bare_metal_server" version = "0.0.0" dependencies = [ "critical-section", - "embassy-sync", + "embassy-sync 0.6.2", "simple-someip", "tokio", ] +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + [[package]] name = "byteorder" version = "1.5.0" @@ -65,6 +113,41 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" +[[package]] +name = "darling" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" +dependencies = [ + "darling_core", + "quote", + "syn", +] + [[package]] name = "discovery_client" version = "0.0.0" @@ -76,6 +159,79 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "document-features" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61" +dependencies = [ + "litrs", +] + +[[package]] +name = "embassy-executor" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f64f84599b0f4296b92a4b6ac2109bc02340094bda47b9766c5f9ec6a318ebf8" +dependencies = [ + "critical-section", + "document-features", + "embassy-executor-macros", +] + +[[package]] +name = "embassy-executor-macros" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3577b1e9446f61381179a330fc5324b01d511624c55f25e3c66c9e3c626dbecf" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "embassy-net" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55cf91dd36dfd623de32242af711fd294d41159f02130052fc93c5c5ba93febe" +dependencies = [ + "as-slice 0.2.1", + "atomic-pool", + "document-features", + "embassy-net-driver", + "embassy-sync 0.5.0", + "embassy-time", + "embedded-io-async", + "embedded-nal-async", + "futures", + "generic-array 0.14.9", + "heapless 0.8.0", + "managed", + "smoltcp", + "stable_deref_trait", +] + +[[package]] +name = "embassy-net-driver" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524eb3c489760508f71360112bca70f6e53173e6fe48fc5f0efd0f5ab217751d" + +[[package]] +name = "embassy-sync" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd938f25c0798db4280fcd8026bf4c2f48789aebf8f77b6e5cf8a7693ba114ec" +dependencies = [ + "cfg-if", + "critical-section", + "embedded-io-async", + "futures-util", + "heapless 0.8.0", +] + [[package]] name = "embassy-sync" version = "0.6.2" @@ -90,6 +246,64 @@ dependencies = [ "heapless 0.8.0", ] +[[package]] +name = "embassy-time" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "158080d48f824fad101d7b2fae2d83ac39e3f7a6fa01811034f7ab8ffc6e7309" +dependencies = [ + "cfg-if", + "critical-section", + "document-features", + "embassy-time-driver", + "embassy-time-queue-driver", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-async", + "futures-util", + "heapless 0.8.0", +] + +[[package]] +name = "embassy-time-driver" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e0c214077aaa9206958b16411c157961fb7990d4ea628120a78d1a5a28aed24" +dependencies = [ + "document-features", +] + +[[package]] +name = "embassy-time-queue-driver" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1177859559ebf42cd24ae7ba8fe6ee707489b01d0bf471f8827b7b12dcb0bc0" + +[[package]] +name = "embedded-hal" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff" +dependencies = [ + "nb 0.1.3", + "void", +] + +[[package]] +name = "embedded-hal" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89" + +[[package]] +name = "embedded-hal-async" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4c685bbef7fe13c3c6dd4da26841ed3980ef33e841cddfa15ce8a8fb3f1884" +dependencies = [ + "embedded-hal 1.0.0", +] + [[package]] name = "embedded-io" version = "0.6.1" @@ -111,12 +325,69 @@ dependencies = [ "embedded-io 0.6.1", ] +[[package]] +name = "embedded-nal" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8a943fad5ed3d3f8a00f1e80f6bba371f1e7f0df28ec38477535eb318dc19cc" +dependencies = [ + "nb 1.1.0", + "no-std-net", +] + +[[package]] +name = "embedded-nal-async" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72229137a4fc12d239b0b7f50f04b30790678da6d782a0f3f1909bf57ec4b759" +dependencies = [ + "embedded-io-async", + "embedded-nal", + "no-std-net", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "futures" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" +dependencies = [ + "futures-core", + "futures-sink", +] + [[package]] name = "futures-core" version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" +[[package]] +name = "futures-io" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" + [[package]] name = "futures-macro" version = "0.3.32" @@ -148,10 +419,39 @@ checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" dependencies = [ "futures-core", "futures-macro", + "futures-sink", "futures-task", "pin-project-lite", ] +[[package]] +name = "generic-array" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" +dependencies = [ + "typenum", +] + +[[package]] +name = "generic-array" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f797e67af32588215eaaab8327027ee8e71b9dd0b2b26996aedf20c030fce309" +dependencies = [ + "typenum", +] + +[[package]] +name = "generic-array" +version = "0.14.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2" +dependencies = [ + "typenum", + "version_check", +] + [[package]] name = "hash32" version = "0.3.1" @@ -181,6 +481,12 @@ dependencies = [ "stable_deref_trait", ] +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + [[package]] name = "lazy_static" version = "1.5.0" @@ -193,12 +499,24 @@ version = "0.2.184" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af" +[[package]] +name = "litrs" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092" + [[package]] name = "log" version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +[[package]] +name = "managed" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ca88d725a0a943b096803bd34e73a4437208b6077654cc4ecb2947a5f91618d" + [[package]] name = "mio" version = "1.2.0" @@ -210,6 +528,27 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "nb" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f" +dependencies = [ + "nb 1.1.0", +] + +[[package]] +name = "nb" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d" + +[[package]] +name = "no-std-net" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43794a0ace135be66a25d3ae77d41b91615fb68ae937f904090203e81f755b65" + [[package]] name = "nu-ansi-term" version = "0.50.3" @@ -264,7 +603,7 @@ version = "0.8.0" dependencies = [ "crc", "critical-section", - "embassy-sync", + "embassy-sync 0.6.2", "embedded-io 0.7.1", "futures-util", "heapless 0.9.2", @@ -275,12 +614,38 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "simple-someip-embassy-net" +version = "0.1.0" +dependencies = [ + "critical-section", + "embassy-executor", + "embassy-net", + "embassy-sync 0.6.2", + "embassy-time", + "heapless 0.9.2", + "simple-someip", +] + [[package]] name = "smallvec" version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +[[package]] +name = "smoltcp" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a1a996951e50b5971a2c8c0fa05a381480d70a933064245c4a223ddc87ccc97" +dependencies = [ + "bitflags", + "byteorder", + "cfg-if", + "heapless 0.8.0", + "managed", +] + [[package]] name = "socket2" version = "0.5.10" @@ -307,6 +672,12 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + [[package]] name = "syn" version = "2.0.117" @@ -429,6 +800,12 @@ dependencies = [ "tracing-log", ] +[[package]] +name = "typenum" +version = "1.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de" + [[package]] name = "unicode-ident" version = "1.0.24" @@ -441,6 +818,18 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + [[package]] name = "wasi" version = "0.11.1+wasi-snapshot-preview1" diff --git a/Cargo.toml b/Cargo.toml index a86890b..370b357 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,6 +5,7 @@ members = [ "examples/bare_metal_server", "examples/client_server", "examples/discovery_client", + "simple-someip-embassy-net", ] [package] diff --git a/simple-someip-embassy-net/Cargo.toml b/simple-someip-embassy-net/Cargo.toml new file mode 100644 index 0000000..46130bf --- /dev/null +++ b/simple-someip-embassy-net/Cargo.toml @@ -0,0 +1,59 @@ +[package] +name = "simple-someip-embassy-net" +version = "0.1.0" +edition = "2024" +license = "MIT OR Apache-2.0" +description = "embassy-net `TransportFactory` / `TransportSocket` adapter for the simple-someip crate" +repository = "https://github.com/luminartech/simple_someip" +readme = "README.md" + +# This crate is the reference no_std backend for `simple-someip`'s +# trait surface. It depends on `simple-someip` with +# `default-features = false, features = ["client", "server", "bare_metal"]` +# — no std, no tokio, no socket2 — and provides a thin adapter from +# embassy-net's `UdpSocket` API to simple-someip's +# `TransportSocket` / `TransportFactory` traits. +# +# Sized for: bare-metal Rust embedded targets running embassy-net + +# embassy-executor (cortex-m, RISC-V). Does not require alloc. +# +# See `bare_metal_plan_v3.md` for the surrounding plan (phase 19). + +[dependencies] +simple-someip = { path = "..", version = "0.8", default-features = false, features = [ + "client", + "server", + "bare_metal", +] } +# Pinned to a version known to coexist with `simple-someip`'s +# `embassy-sync = "0.6"` dep. embassy-net 0.4.x is the last +# release line that builds against embassy-sync 0.6; later +# embassy-net releases (0.5+) require embassy-sync 0.7+, which +# would force a parallel-version cargo resolution that bloats the +# binary. Bumping both deps in lockstep is its own future phase. +embassy-net = { version = "0.4", default-features = false, features = [ + "udp", + "proto-ipv4", + "igmp", + # smoltcp (embassy-net's underlying TCP/IP stack) requires at + # least one network-medium feature to be enabled. We enable both + # `medium-ethernet` (the common case for SOME/IP on automotive + # Ethernet) and `medium-ip` (for raw IP backends like SLIP / lwIP + # tap devices). `medium-ieee802154` is intentionally not enabled + # — SOME/IP-over-802.15.4 is not in scope for this adapter. + "medium-ethernet", + "medium-ip", +] } +embassy-sync = "0.6" +heapless = "0.9" + +[dev-dependencies] +# Host-side tests use a tuntap-backed embassy-net stack to drive a +# request/response roundtrip. The dev-dep is what gets us link-time +# `critical-section` impls on the host. +critical-section = { version = "1", features = ["std"] } +embassy-executor = { version = "0.6", features = [ + "arch-std", + "executor-thread", +] } +embassy-time = { version = "0.3", features = ["std", "generic-queue-8"] } diff --git a/simple-someip-embassy-net/README.md b/simple-someip-embassy-net/README.md new file mode 100644 index 0000000..ace8569 --- /dev/null +++ b/simple-someip-embassy-net/README.md @@ -0,0 +1,54 @@ +# simple-someip-embassy-net + +[embassy-net]-backed `TransportFactory` / `TransportSocket` adapter for +the [`simple-someip`] crate. + +This is the **reference no_std backend** for `simple-someip`'s +transport-trait surface. It lets bare-metal Rust embedded projects +running on [embassy-executor] + embassy-net pick up SOME/IP service +discovery and request/response messaging as a one-line dependency +add, without writing their own transport adapter. + +## Status + +Phase 19 of the [bare-metal roadmap][plan-v3]. As of phase 19a, this +crate is a scaffolded skeleton; the full `TransportFactory` / +`TransportSocket` impl lands incrementally in 19b–19c, with a host +loopback integration test in 19e and an in-tree example in 19f. + +## Quick sketch (target shape, post-19c) + +```rust,ignore +use simple_someip::{Client, ClientDeps}; +use simple_someip_embassy_net::{EmbassyNetFactory, SocketPool}; + +static SOCKET_POOL: SocketPool<8, 1500, 1500> = SocketPool::new(); + +#[embassy_executor::main] +async fn main(spawner: embassy_executor::Spawner) { + let stack = /* ... build embassy-net Stack ... */; + let factory = EmbassyNetFactory::new(stack, &SOCKET_POOL); + + let (client, _updates, run_fut) = Client::<_, _, _, _>::new_with_deps( + ClientDeps { + factory, + spawner, // embassy_executor::Spawner + timer: EmbassyTimer, + e2e_registry: /* StaticE2EHandle */, + interface: /* AtomicInterfaceHandle */, + }, + false, // multicast_loopback + ); + spawner.spawn(run_fut).unwrap(); + // ... use the client ... +} +``` + +## License + +MIT OR Apache-2.0, matching `simple-someip`. + +[embassy-net]: https://crates.io/crates/embassy-net +[embassy-executor]: https://crates.io/crates/embassy-executor +[`simple-someip`]: https://crates.io/crates/simple-someip +[plan-v3]: https://github.com/luminartech/simple_someip diff --git a/simple-someip-embassy-net/src/factory.rs b/simple-someip-embassy-net/src/factory.rs new file mode 100644 index 0000000..8c315e2 --- /dev/null +++ b/simple-someip-embassy-net/src/factory.rs @@ -0,0 +1,81 @@ +//! `TransportFactory` impl over embassy-net's UDP API. +//! +//! See the crate-level doc for context. This module is the scaffolding +//! introduced in phase 19a; the full impl lands in 19b. + +use crate::socket::EmbassyNetSocket; + +/// Caller-owned pool of UDP-socket buffer storage. +/// +/// embassy-net's [`UdpSocket`](embassy_net::udp::UdpSocket) requires +/// the caller to provide RX/TX buffers and metadata arrays. To satisfy +/// `simple-someip`'s `F::Socket: 'static` bound (the run-loop spawns +/// per-socket I/O tasks), the buffers must live in `&'static` storage. +/// +/// `SocketPool` declares N slots of buffer storage; the +/// [`EmbassyNetFactory`] hands each `bind()` call a fresh slot until +/// the pool is exhausted, after which `bind()` returns +/// [`simple_someip::transport::TransportError::AddressInUse`] (the +/// closest existing variant — phase 19b will introduce a dedicated +/// pool-exhaustion path or rename this). +/// +/// **NB phase 19a:** the actual storage fields are deferred to 19b +/// once the embassy-net buffer-shape bring-up reveals what we need +/// (`PacketMetadata` arrays vs. the older `[u8]` form, etc.). This +/// stub exists so the `factory` module type-checks against the +/// `EmbassyNetFactory` skeleton. +#[allow(dead_code)] // populated in 19b +pub struct SocketPool { + // Storage arrays will land in 19b. + _todo: (), +} + +impl SocketPool { + /// Construct an empty socket pool. Const so it can live in a + /// `static`. + #[must_use] + pub const fn new() -> Self { + Self { _todo: () } + } +} + +impl Default + for SocketPool +{ + fn default() -> Self { + Self::new() + } +} + +/// embassy-net `TransportFactory` implementation. +/// +/// Holds a reference to the embassy-net `Stack` and a `&'static` +/// [`SocketPool`] from which `bind()` allocates per-socket buffers. +/// +/// **NB phase 19a:** the [`TransportFactory`](simple_someip::transport::TransportFactory) +/// trait impl lands in 19b. This skeleton exists so downstream code +/// can name the type and so the workspace integration can be +/// validated incrementally. +#[allow(dead_code)] // populated in 19b +pub struct EmbassyNetFactory<'a, const POOL: usize, const RX_BUF: usize, const TX_BUF: usize> { + pool: &'a SocketPool, +} + +impl<'a, const POOL: usize, const RX_BUF: usize, const TX_BUF: usize> + EmbassyNetFactory<'a, POOL, RX_BUF, TX_BUF> +{ + /// Build a factory borrowing from the given socket pool. + #[must_use] + pub fn new(pool: &'a SocketPool) -> Self { + Self { pool } + } +} + +// `EmbassyNetSocket` is the eventual associated type of the +// `TransportFactory` impl; the explicit `use` above keeps the +// import live so 19b doesn't have to reintroduce it. Without an +// active reference Rust would fire `unused_import`. +#[allow(dead_code)] +fn _phantom_socket_use() -> Option { + None +} diff --git a/simple-someip-embassy-net/src/lib.rs b/simple-someip-embassy-net/src/lib.rs new file mode 100644 index 0000000..a163327 --- /dev/null +++ b/simple-someip-embassy-net/src/lib.rs @@ -0,0 +1,49 @@ +//! embassy-net `TransportFactory` / `TransportSocket` adapter for +//! [`simple-someip`]. +//! +//! This crate is the **reference `no_std` backend** for `simple-someip`'s +//! transport-trait surface. It wraps [`embassy_net::udp::UdpSocket`] +//! behind [`simple_someip::transport::TransportSocket`] and provides a +//! [`simple_someip::transport::TransportFactory`] that hands out sockets +//! from a caller-declared `&'static` storage pool. +//! +//! # Why this crate exists +//! +//! Phase 18 of the bare-metal effort closed the literal compile gate: +//! `simple-someip` + `client,server,bare_metal` cross-compiles for +//! `thumbv7em-none-eabihf`. But "compiles" is not "works" — until a +//! real backend satisfies the trait surface against an actual `no_std` +//! network stack, the trait surface is unverified. This crate is the +//! verification: an end-to-end working backend that bare-metal Rust +//! consumers can either depend on directly or treat as the worked +//! example for their own (lwIP, smoltcp-direct, vendor-stack) adapters. +//! +//! # Status +//! +//! Phase 19 in progress (per `bare_metal_plan_v3.md`). 19a (this +//! commit) is the scaffold; 19b implements [`EmbassyNetFactory`], +//! 19c implements [`EmbassyNetSocket`], 19e wires up the loopback +//! integration test, 19f produces an in-tree example. +//! +//! # Pairing with `simple-someip` +//! +//! ```toml +//! [dependencies] +//! simple-someip = { version = "0.8", default-features = false, +//! features = ["client", "server", "bare_metal"] } +//! simple-someip-embassy-net = "0.1" +//! embassy-net = { version = "0.4", default-features = false, +//! features = ["udp", "proto-ipv4", "igmp"] } +//! ``` +//! +//! [`simple-someip`]: https://crates.io/crates/simple-someip + +#![no_std] +#![warn(clippy::pedantic)] +#![warn(missing_docs)] + +pub mod factory; +pub mod socket; + +pub use factory::{EmbassyNetFactory, SocketPool}; +pub use socket::EmbassyNetSocket; diff --git a/simple-someip-embassy-net/src/socket.rs b/simple-someip-embassy-net/src/socket.rs new file mode 100644 index 0000000..a4a9293 --- /dev/null +++ b/simple-someip-embassy-net/src/socket.rs @@ -0,0 +1,19 @@ +//! `TransportSocket` impl wrapping `embassy_net::udp::UdpSocket`. +//! +//! Phase 19a scaffold; full impl in 19c. + +/// embassy-net-backed [`simple_someip::transport::TransportSocket`]. +/// +/// Holds an `embassy_net::udp::UdpSocket<'a>` borrowing into +/// caller-owned `&'static` buffer storage (managed by +/// [`crate::SocketPool`] / [`crate::EmbassyNetFactory`]). +/// +/// **NB phase 19a:** the [`TransportSocket`](simple_someip::transport::TransportSocket) +/// trait impl lands in 19c. This skeleton lets [`crate::factory`] +/// reference the type without forward-declaration gymnastics. +#[allow(dead_code)] // populated in 19c +pub struct EmbassyNetSocket { + // Inner `UdpSocket<'a>` + bookkeeping (pool slot index for + // free-list reclamation, local addr) lands in 19c. + _todo: (), +}