Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -184,3 +184,6 @@ harness = false
[[test]]
name = "bare_metal_e2e"
required-features = ["client", "server", "bare_metal"]

[[test]]
name = "buffer_pool"

Large diffs are not rendered by default.

14 changes: 11 additions & 3 deletions examples/bare_metal_client/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,13 @@ use simple_someip::client::{ClientUpdate, ControlMessage, ReceivedMessage, SendM
use simple_someip::define_static_channels;
use simple_someip::e2e::E2ERegistry;
use simple_someip::protocol::sd::RebootFlag;
use simple_someip::static_channels::BufferPool;
use simple_someip::transport::{
ReceivedDatagram, SocketOptions, Spawner, Timer, TransportError, TransportFactory,
TransportSocket,
ReceivedDatagram, SocketOptions, Spawner, StaticBufferProvider, Timer, TransportError,
TransportFactory, TransportSocket,
};
use simple_someip::{AtomicInterfaceHandle, StaticE2EHandle, StaticE2EStorage};
use simple_someip::{Client, ClientDeps, RawPayload};
use simple_someip::{Client, ClientDeps, RawPayload, UDP_BUFFER_SIZE};

// ── Static-pool channel factory ───────────────────────────────────────
//
Expand Down Expand Up @@ -298,6 +299,13 @@ async fn main() {
timer: MockTimer,
e2e_registry: e2e,
interface: iface,
// Caller-declared static buffer pool (#125): one slot per
// possible socket. On real firmware this is a `static`; here it
// is a function-local `static` for the example.
buffer_provider: {
static POOL: BufferPool<9, UDP_BUFFER_SIZE> = BufferPool::new();
StaticBufferProvider(&POOL)
},
Comment on lines +302 to +308

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in #133 (commit 82be01d): bumped the example pool to BufferPool<10, _> (UNICAST_SOCKETS_CAP + discovery + release-lag slack), matching the tokio provider and the documented sizing guidance.

},
false, // multicast_loopback
);
Expand Down
6 changes: 5 additions & 1 deletion examples/embassy_net_client/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ use simple_someip::define_static_channels;
use simple_someip::e2e::E2ERegistry;
use simple_someip::protocol::sd::RebootFlag;
use simple_someip::server::{ServerConfig, SubscribeError, Subscriber, SubscriptionHandle};
use simple_someip::transport::{LocalSpawner, Timer};
use simple_someip::static_channels::BufferPool;
use simple_someip::transport::{LocalSpawner, StaticBufferProvider, Timer};
use simple_someip::{Client, ClientDeps, RawPayload, Server, ServerDeps};
use simple_someip_embassy_net::{EmbassyNetFactory, EmbassyNetSocket, LINK_MTU, SocketPool};

Expand Down Expand Up @@ -410,12 +411,15 @@ async fn main() {
let client_e2e: Arc<Mutex<E2ERegistry>> = Arc::new(Mutex::new(E2ERegistry::new()));
let client_iface: Arc<RwLock<Ipv4Addr>> = Arc::new(RwLock::new(IP_B));

let buf_pool: &'static BufferPool<8, LINK_MTU> =
Box::leak(Box::new(BufferPool::new()));
let client_deps = ClientDeps {
factory: client_factory,
spawner: LocalTokioSpawner,
timer: LocalTimer,
e2e_registry: client_e2e,
interface: client_iface,
buffer_provider: StaticBufferProvider(buf_pool),
};

let (client, mut updates, run_fut) = Client::<
Expand Down
28 changes: 13 additions & 15 deletions simple-someip-embassy-net/src/socket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,29 +150,27 @@ impl Future for EmbassyNetRecvFut<'_> {
}
},
Poll::Ready(Err(RecvError::Truncated)) => {
// CONTRACT NOTE: simple-someip's `TransportSocket::
// recv_from` documents that "a datagram whose payload
// exceeds `buf` is **not** an error; it is returned
// with [`ReceivedDatagram::truncated`] set to `true`."
//
// embassy-net 0.4's `poll_recv_from` returns
// `RecvError::Truncated` and (a) does not deliver any
// bytes when the datagram doesn't fit and (b) does
// not surface the original datagram length. We can't
// honor the trait's `truncated: true` semantics
// truthfully — there's no copied prefix to return and
// no original-length to record. This adapter
// therefore treats truncation as a fatal *operator*
// configuration error, mapped to `IoErrorKind::Other`
// so it shows up distinctly in logs.
// `RecvError::Truncated` when the datagram does not fit
// the receive buffer. It delivers NO bytes and does NOT
// surface the original datagram length, so we cannot
// fulfill the `TransportSocket::recv_from` contract
// (`truncated: true` with a partial prefix).
//
// The datagram is therefore dropped. We signal this via
// `IoErrorKind::Truncated`, which `is_transient_recv`
// classifies as a drop-and-continue condition: the
// socket loop survives and does NOT count this toward
// the consecutive-error kill cap. `IoErrorKind::Other`
// (genuine I/O errors) retains its fatal classification.
//
// The caller-side fix is to size `SocketPool`'s
// `RX_BUF` ≥ link MTU (typically 1500). With
// `RX_BUF = 1500`, IPv4 + UDP header overhead capped
// at 28 B, and `simple-someip::UDP_BUFFER_SIZE`
// already at 1500, this branch should never fire
// under correct configuration.
Poll::Ready(Err(TransportError::Io(IoErrorKind::Other)))
Poll::Ready(Err(TransportError::Io(IoErrorKind::Truncated)))
}
}
}
Expand Down
11 changes: 10 additions & 1 deletion simple-someip-embassy-net/tests/loopback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,10 @@ use std::sync::{Arc, Mutex};
use embassy_net::driver::{Capabilities, Driver, HardwareAddress, LinkState, RxToken, TxToken};
use embassy_net::{Config, Stack, StackResources, StaticConfigV4};

use simple_someip::transport::{SocketOptions, TransportFactory, TransportSocket};
use simple_someip::static_channels::BufferPool;
use simple_someip::transport::{
SocketOptions, StaticBufferProvider, TransportFactory, TransportSocket,
};
use simple_someip_embassy_net::{EmbassyNetFactory, LINK_MTU, SocketPool};

// ── LoopbackDriver pair ──────────────────────────────────────────────
Expand Down Expand Up @@ -640,12 +643,15 @@ async fn client_receives_server_sd_announcement() {
Arc::new(std::sync::Mutex::new(E2ERegistry::new()));
let client_iface: Arc<RwLock<Ipv4Addr>> = Arc::new(RwLock::new(IP_B));

let buf_pool: &'static BufferPool<2, LINK_MTU> =
Box::leak(Box::new(BufferPool::new()));
let client_deps = ClientDeps {
factory: client_factory,
spawner: LocalTokioSpawner,
timer: LocalTimer,
e2e_registry: client_e2e,
interface: client_iface,
buffer_provider: StaticBufferProvider(buf_pool),
};

let (client, mut updates, run_fut) =
Expand Down Expand Up @@ -762,12 +768,15 @@ async fn client_send_request_server_runloop_stable() {
Arc::new(std::sync::Mutex::new(E2ERegistry::new()));
let client_iface: Arc<RwLock<Ipv4Addr>> = Arc::new(RwLock::new(IP_B));

let buf_pool: &'static BufferPool<8, LINK_MTU> =
Box::leak(Box::new(BufferPool::new()));
let client_deps = ClientDeps {
factory: client_factory,
spawner: LocalTokioSpawner,
timer: LocalTimer,
e2e_registry: client_e2e,
interface: client_iface,
buffer_provider: StaticBufferProvider(buf_pool),
};

let (client, _updates, run_fut) = Client::<
Expand Down
Loading