Platform-independent PLDM Firmware Device (FD) service, talking PLDM-over-MCTP directly to a remote Update Agent (UA).
This crate bridges openprot-mctp-api and pldm-interface so that firmware can run the PLDM firmware-update state machine and exchange PLDM messages over MCTP without depending on any particular MCTP implementation or OS.
FirmwareDevice owns two [MctpPldmTransport] instances and drives both directions of traffic itself — there is no separate responder/requester process or platform-specific IPC bridge:
┌──────────────────────────┐ │ Application / Firmware │ constructs FirmwareDevice, calls run_terminus() └───────────┬──────────────┘ │ ▼ ┌───────────────────────────────────────────┐ │ openprot-pldm-service │◄── this crate │ FirmwareDevice<'a, O: FdOps, Cr, Cq> │ │ - cmd_interface: CmdInterface<'a, O> │ PLDM FW-update state machine │ - responder_transport: inbound UA→FD │ │ - requester_transport: outbound FD→UA │ └───────────┬──────────────┬────────────────┘ │ │ MctpPldmTransport<C: MctpClient> ▼ ▼ ┌───────────────────────────────────────────┐ │ openprot-mctp-api │ Stack<C: MctpClient> └───────────┬───────────────────────────────┘ │ IPC / transport ▼ ┌──────────────────────────┐ │ MCTP Server │ └──────────────────────────┘
| Type | Description |
|---|---|
FirmwareDevice<'a, O: FdOps, Cr: MctpClient, Cq: MctpClient> | Owns the CmdInterface FW-update state machine plus the responder/requester MctpPldmTransports; run_terminus() drives both to completion |
MctpPldmTransport<C: MctpClient> | Wraps a Stack<C> and manages the MCTP PLDM framing byte (0x01) for sends/receives |
PldmServiceError | Union of MCTP transport errors (Mctp), PLDM handler errors (MsgHandler), buffer/arithmetic overflow, and IPC errors |
PLDM_MSG_TYPE (pldm_common::util::mctp_transport::MCTP_PLDM_MSG_TYPE) | MCTP message-type constant for PLDM (0x01) |
use openprot_pldm_service::firmware_device::FirmwareDevice; use openprot_pldm_service::MctpPldmTransport; use pldm_interface::config::PLDM_PROTOCOL_CAPABILITIES; // `fd_ops` implements `FdOps` (platform-specific flash / component logic). // `responder_client` / `requester_client` are `MctpClient` implementations // (they may share the same underlying MCTP endpoint). let responder_transport = MctpPldmTransport::new(responder_client); let requester_transport = MctpPldmTransport::new(requester_client); let mut fd = FirmwareDevice::init( &fd_ops, &PLDM_PROTOCOL_CAPABILITIES, responder_transport, requester_transport, ); const UA_EID: u8 = 8; let mut buf = [0u8; 1024]; // `run_terminus` loops forever, interleaving inbound UA commands with any // FD-initiated requests (e.g. RequestFirmwareData) once an update begins. // It returns only on error; a `timeout_millis`/`requester_timeout_millis` // of `0` blocks indefinitely while idle. if let Err(e) = fd.run_terminus(UA_EID, &mut buf, 0, 0) { // handle or log error }
All transport methods (MctpPldmTransport::send_request, recv_and_respond, respond_once) and FirmwareDevice::run_terminus use the same flat-buffer convention:
buf[0] : MCTP message-type byte (0x01) — managed by MctpPldmTransport buf[1..] : PLDM request / response bytes
Size the buffer to accommodate the largest PLDM message your application expects (typically ≤ 1024 bytes; smaller for embedded targets). See FD_MAX_MSG in src/firmware_device.rs for the scratch-buffer size used internally for FD-initiated requests.
bazel build //services/pldm:pldm_service
Run the host-side integration tests:
bazel build -c dbg --strip=never //services/pldm:base_host_test bazel build -c dbg --strip=never //services/pldm:firmware_update_host_test
After changing pldm-common / pldm-interface versions in third_party/crates_io/Cargo.toml, re-pin the lock file. This repo is bzlmod-only (no WORKSPACE file), so use bazel build with CARGO_BAZEL_REPIN=1, not bazel sync (which errors with “WORKSPACE has to be enabled”):
CARGO_BAZEL_REPIN=1 bazel build //services/pldm:pldm_service
openprot-mctp-api — MCTP stack facade and traitspldm-interface — PLDM command dispatcher (CmdInterface, FdOps, FirmwareDeviceContext)pldm-common — PLDM protocol types and MCTP transport helpers