Skip to content
Open
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
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ defmt = "0.3"
deku = { git = "https://github.com/CodeConstruct/deku.git", tag = "cc/deku-v0.19.1/no-alloc-3", default-features = false }
embedded-io-adapters = { version = "0.6", features = ["std", "futures-03"] }
embedded-io-async = "0.6"
embedded-io = "0.6"
enumset = "1.1"
env_logger = "0.11.3"
heapless = "0.8"
Expand Down
29 changes: 24 additions & 5 deletions ci/runtests.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash

set -v
set -e
Expand All @@ -15,7 +15,7 @@ cargo fmt -- --check

# Check everything first
cargo check --all-targets --locked
if [ -z "NO_CLIPPY" ]; then
if [ -z "$NO_CLIPPY" ]; then
cargo clippy --all-targets
fi

Expand All @@ -27,14 +27,14 @@ cargo test
NOSTD_CRATES="mctp pldm pldm-fw pldm-platform pldm-file"
for c in $NOSTD_CRATES; do
(
cd $c
cd "$c"
cargo build --target thumbv7em-none-eabihf --no-default-features
)
done
ALLOC_CRATES="pldm pldm-platform pldm-file"
for c in $ALLOC_CRATES; do
(
cd $c
cd "$c"
cargo build --target thumbv7em-none-eabihf --no-default-features --features alloc
)
done
Expand All @@ -53,6 +53,25 @@ cargo build --target thumbv7em-none-eabihf --features defmt --no-default-feature
cargo build --features log
)

cargo doc
FEATURES_ASYNC="async"
FEATURES_SYNC=""

declare -a FEATURES=(
"$FEATURES_SYNC"
"$FEATURES_ASYNC"
)

# mctp-estack, sync an async
(
cd mctp-estack
for feature in "${FEATURES[@]}"; do
cargo test --features="$feature"
done;
)

# run cargo doc tests
for feature in "${FEATURES[@]}"; do
cargo doc --features="$feature"
done;

echo success
8 changes: 5 additions & 3 deletions mctp-estack/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ rust-version = "1.85"
[dependencies]
crc = { workspace = true }
defmt = { workspace = true, optional = true }
embassy-sync = "0.7"
embedded-io-async = { workspace = true }
embassy-sync = { version = "0.7", optional = true }
embedded-io.workspace = true
embedded-io-async.workspace = true
heapless = { workspace = true }
log = { workspace = true, optional = true }
mctp = { workspace = true }
Expand All @@ -29,7 +30,8 @@ smol = { workspace = true }


[features]
default = ["log"]
default = ["log", "async"]
std = ["mctp/std"]
log = ["dep:log"]
defmt = ["mctp/defmt", "dep:defmt" ]
async = ["dep:embassy-sync"]
7 changes: 6 additions & 1 deletion mctp-estack/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
[API docs](https://docs.rs/mctp-estack)

This is a MCTP stack suitable for embedded devices.
A `async` Router for [Embassy](https://embassy.dev/) (or other _async runtime_)
based applications is available through the `async` feature.

A `Router` instance handles feeding MCTP packets to and from user
provided MCTP transports, and handles sending receiving MCTP messages
from applications using the `mctp` crate async traits.
from applications using the `mctp` crate _async_ traits.

Applications using MCTP can create `RouterAsyncListener` and
`RouterAsyncReqChannel` instances.
Expand All @@ -16,3 +18,6 @@ MCTP bridging between ports is supported by the `Router`.
The core `Stack` handles IO-less MCTP message reassembly and fragmentation,
and MCTP tag tracking. MCTP transport binding packet encoding and decoding is
provided for I2C, USB, and serial.

## Features
- `async`: _async_ router implementing `mctp` crate _async_ traits
9 changes: 8 additions & 1 deletion mctp-estack/src/control.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@
//! MCTP Control Protocol implementation

use crate::fmt::*;
#[cfg(feature = "async")]
use crate::Router;
use mctp::{AsyncRespChannel, Eid, Error, Listener, MsgIC, MsgType};
#[cfg(feature = "async")]
use mctp::{AsyncRespChannel, MsgIC};
use mctp::{Eid, Error, Listener, MsgType};
use uuid::Uuid;

/// A `Result` with a MCTP control completion code as error.
Expand Down Expand Up @@ -191,7 +194,9 @@ pub struct MctpControlMsg<'a> {
work: [u8; 2],
}

#[cfg(feature = "async")]
const MAX_MSG_SIZE: usize = 20; /* largest is Get Endpoint UUID */
#[cfg(feature = "async")]
const MAX_MSG_TYPES: usize = 8;

impl<'a> MctpControlMsg<'a> {
Expand Down Expand Up @@ -424,13 +429,15 @@ where
}

/// A Control Message handler.
#[cfg(feature = "async")]
pub struct MctpControl<'g, 'r> {
rsp_buf: [u8; MAX_MSG_SIZE],
types: heapless::Vec<MsgType, MAX_MSG_TYPES>,
uuid: Option<Uuid>,
router: &'g Router<'r>,
}

#[cfg(feature = "async")]
impl<'g, 'r> MctpControl<'g, 'r> {
/// Create a new instance.
pub fn new(router: &'g Router<'r>) -> Self {
Expand Down
2 changes: 1 addition & 1 deletion mctp-estack/src/fragment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ impl Fragmenter {
rest = &mut rest[1..];
}

let Ok(n) = self.reader.read(payload, &mut rest) else {
let Ok(n) = self.reader.read(payload, rest) else {
return SendOutput::failure(Error::BadArgument, self);
};
let rest = &rest[n..];
Expand Down
26 changes: 16 additions & 10 deletions mctp-estack/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,22 @@

//! # MCTP Stack
//!
//! This crate provides a MCTP stack that can be embedded in other programs
//! or devices.
//! This crate provides a MCTP stack and transport bindings,
//! that can be embedded in other programs or devices.
//!
//! A [`Router`] object lets programs use a [`Stack`] with
//! MCTP transport binding links. Each *Port* handles transmitting and receiving
//! The IO-less [`Stack`] handles MCTP message formatting and parsing, independent
//! of any particular MCTP transport binding.
//!
//! A Router for *async* applications is available
//! through the `async` feature.
//! The async `Router` lets programs use a `Stack`
//! by providing implementations for the standard [`mctp` crate](mctp) async traits.
//! Transport bindings are provided by *Ports* which handle transmitting and receiving
//! packets independently. Messages destined for the stack's own EID will
//! be passed to applications.
//!
//! Applications can create [`router::RouterAsyncListener`] and [`router::RouterAsyncReqChannel`]
//! instances to communicate over MCTP. Those implement the standard [`mctp` crate](mctp)
//! async traits.
//!
//! The IO-less [`Stack`] handles MCTP message formatting and parsing, independent
//! of any particular MCTP transport binding.
//! ## Features
//! - `async`: _async_ router implementing [`mctp` crate](mctp) _async_ traits
//!
//! ## Configuration
//!
Expand All @@ -35,6 +37,7 @@
// those reworked when using the log crate either.
#![allow(clippy::uninlined_format_args)]
#![warn(clippy::unused_async)]
#![cfg_attr(docsrs, feature(doc_auto_cfg))]

#[cfg(test)]
#[macro_use]
Expand All @@ -61,19 +64,22 @@ pub mod control;
pub mod fragment;
pub mod i2c;
mod reassemble;
#[cfg(feature = "async")]
pub mod router;
pub mod serial;
pub mod usb;
#[macro_use]
mod util;
mod proto;

#[cfg(feature = "async")]
#[rustfmt::skip]
#[allow(clippy::needless_lifetimes)]
mod zerocopy_channel;

use fragment::{Fragmenter, SendOutput};
use reassemble::Reassembler;
#[cfg(feature = "async")]
pub use router::Router;

use crate::fmt::*;
Expand Down
Loading