someip-sd-wire

Crates.iosomeip-sd-wire
lib.rssomeip-sd-wire
version0.1.1
created_at2025-11-16 13:08:26.075115+00
updated_at2025-11-16 13:10:20.714112+00
descriptionA no_std SOME/IP-SD wire protocol parser and serializer with zero-allocation design
homepage
repositoryhttps://github.com/martinpalsson/someip-sd-wire
max_upload_size
id1935507
size147,656
Martin PÄlsson (martinpalsson)

documentation

README

someip-sd-wire

Crates.io Documentation License

A no_std Rust crate for parsing and serializing SOME/IP Service Discovery (SOME/IP-SD) wire protocol packets. This crate is inspired by the smoltcp architecture.

Based on the AUTOSAR SOME/IP Service Discovery Protocol Specification.

Disclaimer

This crate is intended for educational and research purposes to study the SOME/IP-SD protocol.

The SOME/IP-SD protocol is an AUTOSAR standard. AUTOSAR claims intellectual property rights over their specifications.

Scope

This crate handles SOME/IP Service Discovery message parsing and serialization.

SOME/IP-SD is used for dynamic service discovery in automotive networks. The crate parses the 12-byte SD header, service/eventgroup entries, and various option types (endpoints, configuration, load balancing). It provides zero-copy access to the wire format data.

Usage

Add this to your Cargo.toml:

[dependencies]
someip-sd-wire = "0.1.1"

Examples

Parsing a SOME/IP-SD packet

use someip_sd_wire::prelude::*;

let buffer = [
    0x00, // Flags
    0x00, 0x00, 0x00, // Reserved
    0x00, 0x00, 0x00, 0x10, // Entries length (16 bytes)
    // Service entry: FindService
    0x00, // Entry type (FindService)
    0x01, // Index first option run
    0x00, // Index second option run
    0x00, // Number of options (bits 0-3: num opt 1, bits 4-7: num opt 2)
    0x12, 0x34, // Service ID
    0x00, 0x01, // Instance ID
    0x01, // Major version
    0x00, 0x00, 0x00, // TTL (3 bytes)
    0x00, 0x00, 0x00, 0x00, // Minor version
    0x00, 0x00, 0x00, 0x00, // Options length
];

let packet = Packet::new_checked(&buffer).unwrap();
let repr = Repr::parse(&packet).unwrap();

assert_eq!(repr.entries.len(), 16);
assert_eq!(repr.options.len(), 0);

// Parse service entry
let service_entry = ServiceEntry::new_checked(&repr.entries[0..16]).unwrap();
assert_eq!(service_entry.entry_type(), 0x00); // FindService
assert_eq!(service_entry.service_id(), 0x1234);

Creating a SOME/IP-SD OfferService message

use someip_sd_wire::prelude::*;

// Create high-level representations
let service_entry = ServiceEntryRepr {
    entry_type: EntryType::OfferService,
    index_first_option_run: 0,
    index_second_option_run: 0,
    number_of_options: NumberOfOptions::from_options(1, 0),
    service_id: 0x1234,
    instance_id: 0x0001,
    major_version: 1,
    ttl: 3, // 3 seconds
    minor_version: 0,
};

let endpoint_option = IPv4EndpointOptionRepr {
    ipv4_address: [192, 168, 1, 100],
    protocol: TransportProtocol::UDP,
    port: 30000,
};

// Emit to buffers
let mut entry_buf = [0u8; 16];
let mut entry = ServiceEntry::new_unchecked(&mut entry_buf[..]);
service_entry.emit(&mut entry);

let mut option_buf = [0u8; 12];
endpoint_option.emit(&mut option_buf);

// Create packet representation and emit
let repr = Repr::new(0x00, &entry_buf, &option_buf);
let mut packet_buf = [0u8; 64];
let mut packet = Packet::new_unchecked(&mut packet_buf);
repr.emit(&mut packet);

Working with Configuration Options

Configuration options follow DNS-SD TXT record format for key-value pairs:

use someip_sd_wire::prelude::*;

// Parse configuration data
let data = b"\x07enabled\x0cversion=1.0a\x00";
for result in ConfigurationOption::parse(data) {
    let entry = result.unwrap();
    if entry.is_flag() {
        println!("Flag: {}", entry.key());
    } else {
        println!("{}={}", entry.key(), entry.value().unwrap());
    }
}

// Create configuration entries
let entries = [
    ConfigEntry::flag("enabled").unwrap(),
    ConfigEntry::with_value("version", "1.0").unwrap(),
];

let mut buf = [0u8; 64];
let size = ConfigurationOption::serialize(entries, &mut buf).unwrap();

Architecture

The crate follows the smoltcp zero-copy architecture with representation types for high-level API:

  • Packet layer (packet module) - Zero-copy wrapper around the 12-byte SD header
  • Representation layer (repr module) - High-level packet representation with validated entries/options slices
  • Entry wrappers (entries module) - Zero-copy accessors (ServiceEntry, EventGroupEntry) and high-level representations (ServiceEntryRepr, EventGroupEntryRepr)
  • Option wrappers (options module) - Zero-copy accessors and high-level representations for various option types

Two-Layer Design

Each major type has two layers:

  1. Zero-copy wrapper - Works directly on byte slices without allocation (e.g., ServiceEntry, IPv4EndpointOption)
  2. Representation struct - High-level builder with typed fields for easy construction (e.g., ServiceEntryRepr, IPv4EndpointOptionRepr)

Use zero-copy wrappers for parsing received data. Use representation types for constructing messages to send.

Key Components

  • Entries - Service entries (FindService, OfferService) and EventGroup entries (Subscribe, SubscribeAck)

  • Options - IPv4/IPv6 endpoints, load balancing, configuration, multicast, and SD endpoint options

  • Configuration - DNS-SD TXT record style key-value pairs for service metadata

License

Licensed under either of:

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Commit count: 0

cargo fmt