Expand description
§mctp-rs
A no_std Rust implementation of the DMTF Management Component Transport Protocol (MCTP)
transport.
§Receiving and parsing messages
Use MctpPacketContext with your medium to assemble messages from packets.
let mut assembly_buffer = [0u8; 1024];
let medium = MyMedium { mtu: 256 };
let mut context = MctpPacketContext::new(medium, &mut assembly_buffer);
// Typically obtained from your bus
let raw_packet_data: &[u8] = &[0x01, 0x02, 0x03, 0x83];
match context.deserialize_packet(raw_packet_data) {
Ok(Some(message)) => {
// We received a complete MCTP message
if let Ok((header, control)) = message.parse_as::<MctpControl>() {
match control {
MctpControl::GetEndpointIdRequest => {
// Handle control request
let _instance = header.instance_id;
}
MctpControl::GetEndpointIdResponse(bytes3) => {
// Use response payload (3 bytes as per spec)
let _eid = bytes3[0];
}
_ => {}
}
}
}
Ok(None) => { /* partial message; wait for more packets */ }
Err(e) => {
// handle protocol/medium error
let _ = e;
}
}§Sending messages
Construct a header + body pair implementing MctpMessageTrait and serialize to one or
more packets using serialize_packet.
let mut buf = [0u8; 1024];
let mut ctx = MctpPacketContext::new(MyMedium { mtu: 64 }, &mut buf);
let reply = MctpReplyContext {
destination_endpoint_id: EndpointId::try_from(0x20).unwrap(),
source_endpoint_id: EndpointId::try_from(0x21).unwrap(),
packet_sequence_number: MctpSequenceNumber::new(0),
message_tag: MctpMessageTag::try_from(1).unwrap(),
medium_context: (),
};
let message = (
VendorDefinedPciHeader(0x1234),
VendorDefinedPci(&[0xDE, 0xAD, 0xBE, 0xEF]),
);
let mut packets = ctx.serialize_packet(reply, message).unwrap();
while let Some(packet_result) = packets.next() {
let packet_bytes = packet_result.unwrap();
// send `packet_bytes` via your bus
let _ = packet_bytes;
}§Implementing a custom medium
The crate is transport-agnostic via the MctpMedium trait. Implement it for your bus
(e.g., SMBus, eSPI) and provide a frame type implementing MctpMediumFrame.
use mctp_rs::*;
#[derive(Debug, Clone, Copy)]
struct MyMedium {
mtu: usize,
}
#[derive(Debug, Clone, Copy)]
struct MyMediumFrame {
packet_size: usize,
}
impl MctpMedium for MyMedium {
type Frame = MyMediumFrame;
type Error = &'static str;
type ReplyContext = ();
type Encoding = PassthroughEncoding;
fn max_message_body_size(&self) -> usize {
self.mtu
}
fn deserialize<'buf>(
&self,
packet: &'buf [u8],
) -> MctpPacketResult<(Self::Frame, EncodingDecoder<'buf, Self::Encoding>), Self> {
// Strip/validate transport headers as needed for your bus and return MCTP payload slice
Ok((
MyMediumFrame {
packet_size: packet.len(),
},
EncodingDecoder::new(packet),
))
}
fn serialize<'buf, F>(
&self,
_reply_context: Self::ReplyContext,
buffer: &'buf mut [u8],
message_writer: F,
) -> MctpPacketResult<&'buf [u8], Self>
where
F: for<'a> FnOnce(
&mut EncodingEncoder<'a, Self::Encoding>,
) -> MctpPacketResult<(), Self>,
{
// Prepend transport headers as needed, then ask the writer to write MCTP payload
let written = {
let mut encoder = EncodingEncoder::<Self::Encoding>::new(buffer);
message_writer(&mut encoder)?;
encoder.wire_position()
};
Ok(&buffer[..written])
}
}
impl MctpMediumFrame<MyMedium> for MyMediumFrame {
fn packet_size(&self) -> usize {
self.packet_size
}
fn reply_context(&self) -> <MyMedium as MctpMedium>::ReplyContext {
()
}
}Re-exports§
pub use error::MctpPacketError;pub use error::MctpPacketResult;
Modules§
- error
- mctp_
completion_ code - serial
- DSP0253 byte-stuffed serial medium for MCTP.
- smbus_
espi
Structs§
- Encoding
Decoder - Stateful cursor over a
&[u8]wire buffer that reads decoded bytes throughE: BufferEncoding. Constructed byMctpMedium::deserializeand handed to higher layers so they cannot bypass the encoding by slicing the underlying buffer directly. - Encoding
Encoder - Stateful cursor over a
&mut [u8]wire buffer that writes decoded bytes throughE: BufferEncoding. Constructed byMctpMedium::serializeand handed to the caller’smessage_writerclosure so the closure cannot bypass the encoding. - Mctp
Control Header - Mctp
Message - Mctp
Message Buffer - Mctp
Message Tag - Mctp
Packet Context - Context for serializing and deserializing an MCTP message, which may be split among multiple packets.
- Mctp
Reply Context - Represents the state needed to construct a repsonse to a request: the MCTP transport source/destination, the sequence number to use for the reply, and the medium-specific context that came with the request.
- Mctp
Sequence Number - Mctp
Serial Medium - Mctp
Serial Medium Frame - Passthrough
Encoding - No-op encoding: wire bytes ARE payload bytes. Used by media that do not byte-stuff (SMBus/eSPI, test fixtures).
- Serial
Encoding - DSP0253 byte-stuffing transform. Stateless ZST.
- Vendor
Defined Pci - Vendor
Defined PciHeader
Enums§
Constants§
- CONST_
MTU - Maximum DSP0253 packet body size (DECODED bytes, before stuffing).
- EC_EID
- EC MCTP endpoint id per CONTEXT D-D-06.
- SP_EID
- SP MCTP endpoint id per CONTEXT D-D-06.
Traits§
- Buffer
Encoding - Stateless byte-stuffing transform. Implementors define how a single logical (payload) byte maps to one or more wire bytes (encode) and how a wire-byte prefix maps back to a single payload byte (decode).
- Mctp
Medium - Mctp
Medium Frame - Mctp
Message Header Trait - Mctp
Message Trait