flowrs-engine/crates/flowrs-device/Cargo.toml
flowRS fd958c0547 flowRS engine, cut from flowRS 3451b065
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-11-02 19:04:39 -05:00

137 lines
6.6 KiB
TOML

[package]
name = "flowrs-device"
version.workspace = true
edition.workspace = true
publish.workspace = true
rust-version.workspace = true
authors.workspace = true
license = "MIT OR Apache-2.0"
description = "Host-side device HAL for FlowRS: serial + WebSerial instrument/board IO, with optional probe-rs firmware flashing."
[dependencies]
serde = { workspace = true }
# The typed link's port (postcard values, the stand-in interface digest) over this crate's
# byte ports: the same code the firmware on the other end runs.
flowrs-hal = { path = "../flowrs-hal", features = ["link"] }
# Native (desktop) — real serial ports + async wrapper; probe-rs flashing behind a feature.
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
# No default features, so no libudev. On Linux it only adds port metadata that serialport
# reads from sysfs without it (USB VID/PID included), and linking it made every program
# that depends on this crate need the target board's libudev to cross-compile.
serialport = { version = "4", default-features = false }
tokio = { version = "1", features = ["sync", "rt"] }
tracing = "0.1"
probe-rs = { version = "0.32", optional = true }
uuid = { version = "1", features = ["v4"], optional = true }
tokio-modbus = { version = "0.17.0", optional = true, default-features = false, features = ["tcp"] }
# The VISA-free instrument transports (`visa`): HiSLIP, VXI-11, raw socket and USBTMC
# drivers over flowrs-transport's sans-IO protocol code.
flowrs-transport = { path = "../flowrs-transport" }
# HiSLIP 2.0 TLS, on flowrs-tls's provider (aws-lc-rs, X25519MLKEM768 first). No default
# features here: the provider is always named explicitly, never left to whichever rustls
# features are unified into the build. Native only, so the browser build compiles no TLS.
rustls = { version = "0.23.46", default-features = false, features = ["std", "tls12"], optional = true }
flowrs-tls = { path = "../flowrs-tls", optional = true }
# The typed link's host nonce, from the operating system's random source.
getrandom = "0.3.4"
# SCRAM-SHA-256 (IVI-6.5), the tls-server-end-point channel binding and certificate pins.
sha2 = { version = "0.10", optional = true }
hmac = { version = "0.12", optional = true }
base64 = { version = "0.22", optional = true }
# USBTMC on pure-Rust USB. 0.2.7 rather than the four-day-old 0.2.8.
nusb = { version = "0.2.7", optional = true }
# Browser — WebSerial via web-sys navigator.serial.
[target.'cfg(target_arch = "wasm32")'.dependencies]
wasm-bindgen = { workspace = true }
wasm-bindgen-futures = "0.4"
js-sys = { workspace = true }
web-sys = { workspace = true, features = [
"Window",
# The typed link's nonce in the browser: crypto.getRandomValues.
"Crypto",
"Navigator",
"Serial",
"SerialPort",
"SerialPortInfo",
"SerialOptions",
"SerialInputSignals",
"SerialOutputSignals",
"ReadableStream",
"WritableStream",
"ReadableStreamDefaultReader",
"WritableStreamDefaultWriter",
"ParityType",
"FlowControlType",
# WebUSB — the door PICOBOOT and DFU go through. Both are USB protocols a page may drive:
# PICOBOOT is a vendor-class interface, DFU is class requests on the control endpoint.
# Neither is mass storage, which is the one class WebUSB may not claim.
"Usb",
"UsbDevice",
"UsbDeviceFilter",
"UsbDeviceRequestOptions",
"UsbControlTransferParameters",
"UsbRequestType",
"UsbRecipient",
"UsbInTransferResult",
"UsbOutTransferResult",
"UsbTransferStatus",
# Endpoint discovery. picotool does not hardcode PICOBOOT's interface or endpoints — it
# scans for the vendor-class interface with two endpoints, which sits at index 0 or 1
# depending on whether the device also mounts mass storage. Doing the same needs the
# configuration descriptor.
"UsbConfiguration",
"UsbInterface",
"UsbAlternateInterface",
"UsbEndpoint",
"UsbDirection",
"UsbEndpointType",
# WebHID — CMSIS-DAP is a HID protocol, so a DAPLink probe arrives here.
"Hid",
"HidDevice",
"HidDeviceFilter",
"HidDeviceRequestOptions",
"HidInputReportEvent",
] }
# Linux host IO — GPIO lines (gpiocdev, modern character-device ABI) and
# I2C/SPI as embedded-hal 1.0 traits (linux-embedded-hal). Unlocks single-board
# computers (Raspberry Pi, BeagleBone, Jetson) and the Qwiic/STEMMA I2C sensor
# catalog. Target-gated, so non-Linux builds never see these deps. Only linux-embedded-hal's
# I2C and SPI: GPIO goes through gpiocdev, and UART through serialport above.
[target.'cfg(target_os = "linux")'.dependencies]
# The kernel's CAN (`can::linux`): socket, CAN FD mode, receive timestamps and vcan creation
# over netlink (MIT). No default features: no candump parser and no udev.
socketcan = { version = "4.0.0", default-features = false, features = ["netlink"] }
# recvmsg with the timestamp control messages, and send, on that socket: the frames are read
# and written in the kernel's layouts by flowrs_hal::can::socketcan (MIT). The version
# socketcan 4.0 builds on, so nothing new enters the lockfile.
nix = { version = "0.31", default-features = false, features = ["socket", "uio", "poll", "time", "net"] }
gpiocdev = "0.8.0"
linux-embedded-hal = { version = "0.5.0", default-features = false, features = ["i2c", "spi"] }
embedded-hal = { workspace = true }
[dev-dependencies]
[features]
default = ["visa", "cdc"]
# A USB CDC-ACM serial function driven directly over nusb (`link::CdcAcm`): a board's USB
# serial without a kernel driver or a tty, for the typed link on a Mac or Windows.
cdc = ["dep:nusb"]
# The VISA-free instrument transports (`visa`): TLS, SASL and USB. On by default. A program
# flowRS generates for a Linux board turns it off (`default-features = false`) and keeps
# `linux_io`, serial and SCPI, so it cross-compiles without a C toolchain for aws-lc.
visa = ["dep:rustls", "dep:flowrs-tls", "dep:sha2", "dep:hmac", "dep:base64", "dep:nusb"]
# In-process instrument simulators (HiSLIP with TLS and SASL, VXI-11 with portmapper and
# abort channel, raw socket, mDNS responder, LXI identification server). Tests here use
# them; other crates enable this in their dev-dependencies to test against the same ones.
sim = ["visa"]
# Enable probe-rs debug-probe enumeration + firmware flashing (native only).
probe = ["dep:probe-rs", "dep:uuid"]
# Use the richer WebSerial options (parity / flow-control setters) where the
# browser + web-sys expose them; off by default (browser defaults are used).
web-serial-full = []
# Modbus RTU / TCP client (industrial fieldbus) via tokio-modbus. Native-only;
# off by default to keep the base build lean.
modbus = ["dep:tokio-modbus"]