Skip to main content

Crate simple_someip

Crate simple_someip 

Source
Expand description

§Simple SOME/IP

CI Coverage Crates.io

A Rust implementation of the SOME/IP automotive communication protocol — remote procedure calls, event notifications, service discovery, and wire-format serialization.

The core protocol layer (protocol, e2e, and trait modules) is no_std-compatible with zero heap allocation, making it suitable for embedded targets. Optional client and server modules provide async tokio-based networking for std environments.

§Modules

Moduleno_stdDescription
protocolYesWire format: headers, messages, message types, return codes, and service discovery (SD) entries/options
e2eYesEnd-to-End protection — Profile 4 (CRC-32) and Profile 5 (CRC-16)
WireFormat / PayloadWireFormatYesTraits for serializing messages and defining custom payload types
clientNoAsync client trait surface — service discovery, subscriptions, request/response (feature client; add client-tokio for Client::new)
serverNoAsync server trait surface — service offering, event publishing, subscription management (feature server; add server-tokio for Server::new)

§Feature Flags

FeatureDefaultDescription
stdyesEnables std-dependent helpers (RawPayload, VecSdHeader) and the Arc<Mutex<E2ERegistry>> / Arc<RwLock<…>> default lock-handle impls used by the tokio backends.
clientnoTrait-surface client. Pure no_std-clean (does not pull extern crate alloc). Caller supplies Spawner / Timer / ChannelFactory / TransportFactory / E2ERegistryHandle / InterfaceHandle impls.
client-tokionoAdds the Client::new / TokioSpawner / TokioTransport convenience defaults; implies client + std + tokio + socket2.
servernoTrait-surface server. Alloc-free since PR #124: the no-alloc path is Server::new_with_handles + run_with_buffers with static handles. The Arc-backed conveniences (new_with_deps, run) are gated behind the internal _alloc feature (pulled in by std / embassy_channels).
server-tokionoAdds the Server::new / TokioTransport / TokioTimer convenience defaults; implies server + std + tokio + socket2.
bare_metalnoActivates embassy-sync, the static_channels module (no-alloc ChannelFactory), AtomicInterfaceHandle, StaticE2EHandle, and StaticSubscriptionHandle. All five are pure no_std (no allocator required). See examples/bare_metal_client/ and examples/bare_metal_server/ for runnable bare-metal integration examples.
embassy_channelsnoHeap-backed EmbassySyncChannels ChannelFactory. Implies bare_metal and pulls extern crate alloc; into the crate; on no_std, downstream consumers must provide a #[global_allocator]. Useful for tests / early prototypes before sizing static pools.

The default feature set is ["std"], which links std and enables the RawPayload / VecSdHeader helpers. For a minimal build with no allocator requirement — the protocol, trait, transport, and e2e modules only — pass --no-default-features. The trait-surface canary workspace members (examples/bare_metal_client, examples/bare_metal_server) depend on the crate with default-features = false, features = ["bare_metal", "client"] / ["bare_metal", "server"] and validate that configuration when built in isolation (cargo build -p bare_metal_client / cargo build -p bare_metal_server), rather than as part of a workspace-wide build where features may be unified across members.

§Examples

§Encoding a SOME/IP-SD header (no_std)

use simple_someip::WireFormat;
use simple_someip::protocol::sd::{self, Entry, RebootFlag, ServiceEntry};

// Build an SD header with a FindService entry
let entries = [Entry::FindService(ServiceEntry::find(0x1234))];
// A fresh process should set RebootFlag::RecentlyRebooted until its
// session counter wraps past 0xFFFF for the first time.
let sd_header =
    sd::Header::new(sd::Flags::new_sd(RebootFlag::RecentlyRebooted), &entries, &[]);

// Encode to bytes
let mut buf = [0u8; 64];
let n = sd_header.encode(&mut buf.as_mut_slice()).unwrap();

// Decode from bytes (zero-copy view)
let view = sd::SdHeaderView::parse(&buf[..n]).unwrap();
assert_eq!(view.entry_count(), 1);

§Async client (requires feature = "client-tokio")

use simple_someip::{Client, ClientUpdate, RawPayload};

#[tokio::main]
async fn main() {
    // Client::new returns a Clone-able handle, an update stream, and
    // the run-loop future. Spawn the future on the tokio runtime;
    // the returned future depends on `tokio::select!` / `tokio::time`
    // / tokio sockets, so it is not executor-agnostic today.
    let (client, mut updates, run) = Client::<RawPayload, _, _, _>::new([192, 168, 1, 100].into());
    let _run_task = tokio::spawn(run);
    client.bind_discovery().await.unwrap();

    while let Some(update) = updates.recv().await {
        match update {
            ClientUpdate::DiscoveryUpdated(msg) => { /* SD message received */ }
            ClientUpdate::Unicast { message, e2e_status, source } => { /* unicast reply */ }
            ClientUpdate::SenderRebooted(addr) => { /* remote reboot */ }
            ClientUpdate::Error(err) => { /* error */ }
        }
    }
}

§References

Re-exports§

pub use e2e::E2ECheckStatus;
pub use e2e::E2EKey;
pub use e2e::E2EProfile;
pub use transport::ChannelFactory;
pub use transport::E2ERegistryHandle;
pub use transport::InterfaceHandle;
pub use transport::IoErrorKind;
pub use transport::LocalSpawner;
pub use transport::MpscRecv;
pub use transport::MpscSend;
pub use transport::OneshotCancelled;
pub use transport::OneshotRecv;
pub use transport::OneshotSend;
pub use transport::ReceivedDatagram;
pub use transport::SocketOptions;
pub use transport::Spawner;
pub use transport::Timer;
pub use transport::TransportError;
pub use transport::TransportFactory;
pub use transport::TransportSocket;
pub use transport::UnboundedRecv;
pub use transport::UnboundedSend;

Modules§

buffer_pool
Fixed-capacity pool of &'static mut [u8] receive/scratch buffers. Pure no_std (uses only core::). Exposed without a feature gate so both the bare-metal and std/tokio paths can reach buffer_pool::BufferPool and buffer_pool::BufferLease. Fixed-capacity pool of byte buffers with claim/release semantics, mirroring the channel pools in this module. A BufferPool is declared as a static (bare-metal) or held behind an Arc (std/tokio) by the consumer; each claim hands out one slot as a BufferLease (a raw NonNull slice whose exclusivity is enforced by the per-slot AtomicBool, not the borrow checker) that returns the slot on drop.
e2e
End-to-end (E2E) protection utilities for SOME/IP payloads. E2E (End-to-End) protection for SOME/IP payloads.
protocol
SOME/IP protocol primitives: headers, messages, return codes, and service discovery.
transport
Executor-agnostic UDP transport abstraction used by the client and server modules. no_std-compatible; a default std + tokio backend ships in tokio_transport (available under the client-tokio / server-tokio features) — the link is rendered as a code literal because the target module is feature-gated and would break default-feature rustdoc builds. Executor-agnostic transport abstraction.

Structs§

OfferedEndpoint
Information about a service endpoint extracted from an SD message.
RawPayload
A concrete PayloadWireFormat backed by heap-allocated storage.
VecSdHeader
Owned SD header backed by heap-allocated vectors.

Constants§

UDP_BUFFER_SIZE
Maximum size, in bytes, of UDP payloads for client / server send paths that serialize into a fixed-size buffer of this size.

Traits§

PayloadWireFormat
A trait for SOME/IP Payload types that can be serialized to a Writer and constructed from raw payload bytes.
WireFormat
A trait for types that can be serialized to a Writer.