# super_cereal
Serial port proxy over [RustDDS](https://github.com/Atostek/RustDDS). Expose a UART on one machine and use it as a local virtual serial device on another over the LAN.
Install the `super_cereal` system binary from [crates.io](https://crates.io/crates/super_cereal):
```bash
cargo install super_cereal
```
## Requirements
- macOS or Linux
- Two machines on the **same LAN segment** (RustDDS multicast discovery)
- Rust toolchain (edition 2021) — only needed to build from source
Docker-on-Mac and Tailscale are not supported in v1 because RustDDS discovery relies on multicast. A unicast transport is planned for a future release.
## Install
From crates.io (recommended):
```bash
cargo install super_cereal
```
From source:
```bash
git clone https://github.com/victoryforphil/super_cereal.git
cd super_cereal
cargo install --path .
```
The installed binary is `~/.cargo/bin/super_cereal`.
## Usage
### Serve (machine with the physical serial device)
```bash
super_cereal serve --port /dev/ttyACM0 --baud 115200 --channel dev1
```
Reads from the UART and publishes bytes on DDS topic `super_cereal/dev1/up`. Writes client bytes from `super_cereal/dev1/down` back to the port.
### Attach (consumer machine)
```bash
super_cereal attach --channel dev1 --link /tmp/ttyVIRT0
```
Creates a PTY and symlinks it to `/tmp/ttyVIRT0`. Open that path with minicom, pyserial, or any tool that expects a serial device.
### List discovered channels
```bash
super_cereal list
super_cereal list --wait 5
```
Waits for DDS discovery (default 3 seconds), then prints channel names seen on the LAN.
## Two-machine validation
1. **Machine A** (device attached):
```bash
super_cereal serve --port /dev/ttyACM0 --baud 115200 --channel dev1
```
2. **Machine B**:
```bash
super_cereal attach --channel dev1 --link /tmp/ttyVIRT0
```
3. On machine B, open the virtual port:
```bash
minicom -D /tmp/ttyVIRT0 -b 115200
```
Or with Python:
```python
import serial
ser = serial.Serial("/tmp/ttyVIRT0", 115200)
ser.write(b"hello\n")
print(ser.read(64))
```
4. Confirm bidirectional traffic matches the real device on machine A. An MCU echo firmware or a TX–RX loopback jumper makes this easy to verify.
## Logging
Set `RUST_LOG` to control verbosity:
```bash
RUST_LOG=debug super_cereal serve --port /dev/ttyACM0 --channel dev1
```
## Background service templates
Shipped in the repository under `contrib/`:
- Linux: `contrib/systemd/super_cereal@.service`
- macOS: `contrib/launchd/com.vfp.super_cereal.plist`
Edit the port, baud, and channel before installing.
## Architecture
```
/dev/ttyACM0 <--> serve --DDS--> attach <--> /tmp/ttyVIRT0 (PTY symlink) <--> your app
```
Topics per channel:
- `super_cereal/<channel>/up` — device → client
- `super_cereal/<channel>/down` — client → device
## Limitations (v1)
- Multicast LAN only; no Docker Desktop or Tailscale without phase-2 unicast support
- PTY baud/termios changes are not forwarded to the remote UART
- One attach client per channel is the expected use case
## License
GPL-3.0-or-later. See [LICENSE](LICENSE).