Skip to content

feat: implement Fairlight Live protocol client crate with CLI example - #1

Merged
FlowingSPDG merged 4 commits into
mainfrom
feat/initial-implementation
Apr 23, 2026
Merged

feat: implement Fairlight Live protocol client crate with CLI example#1
FlowingSPDG merged 4 commits into
mainfrom
feat/initial-implementation

Conversation

@FlowingSPDG

Copy link
Copy Markdown
Member

Summary

  • Reverse-engineered Fairlight Live TCP protocol (port 23461) fully implemented in Rust
  • Binary packet framing via tokio-util codec using magic number 0x55667788
  • All 4 packet types implemented: Ack, MixerControl, ProjectOpen, DataChunk
  • Async FairlightClient handles the full connection lifecycle:
    • Receives PROJECT_OPEN, streams 182 DATA_CHUNK packets with periodic ACKs
    • Waits for server transfer-complete notification
    • Applies initial 78-entry mixer state sync
  • High-level mixer API: set_mute(cam, bool), set_fader(cam, level), set_bus_fader(bus, level)
  • MixerState tracks 24 input strips and 6 output buses
  • examples/cli.rs — clap CLI with subcommands: connect, mute, fader, raw

Test plan

  • cargo build --examples passes without warnings
  • cargo clippy --examples -- -D warnings passes clean
  • cargo run --example cli -- connect against a live Fairlight Live instance
  • cargo run --example cli -- mute --cam 1 --on mutes CAM1
  • cargo run --example cli -- fader --cam 2 --level -500 sets CAM2 fader
  • cargo run --example cli -- raw --object-type 0 --index 0 --param 2 --value 1 sends raw entry

Misei. added 4 commits April 24, 2026 00:52
- Add complete binary packet codec (tokio-util Decoder/Encoder) with magic framing (0x55667788)

- Add ProjectOpen, DataChunk, Ack, MixerControl packet types

- Add async FairlightClient with full connection handshake (PROJECT_OPEN, DATA_CHUNK stream, ACK, initial mixer sync)

- Add high-level mixer API: set_mute, set_fader, set_bus_fader

- Add MixerState tracking (24 strips, 6 buses)

- Add clap CLI example with subcommands: connect, mute, fader, raw
MAGIC = 0x55667788 is a big-endian representation of the four wire bytes 55 66 77 88. All encode paths were using to_le_bytes() which produced the reversed sequence [88 77 66 55], and the codec find_magic() likewise searched for the reversed pattern - so the decoder never matched a single incoming packet and framed.next().await blocked forever.

- constants.rs: export MAGIC_BYTES = MAGIC.to_be_bytes() = [55 66 77 88]

- header.rs: decode uses from_be_bytes; encode uses MAGIC_BYTES

- codec.rs: import MAGIC_BYTES from constants (removes local const)

- ack.rs / data_chunk.rs / mixer.rs / project_open.rs: replace MAGIC.to_le_bytes() with MAGIC_BYTES in every encode function
clap treats leading '-' as a flag prefix by default. Adding allow_negative_numbers = true to FaderArgs and RawArgs lets users pass values like --level -1000 without quoting workarounds.
- Matrix on ubuntu-latest and windows-latest

- dtolnay/rust-toolchain stable with rustfmt + clippy

- Swatinem/rust-cache for faster builds

- Apply rustfmt so cargo fmt --check passes in CI
@FlowingSPDG
FlowingSPDG merged commit 8d2becd into main Apr 23, 2026
4 checks passed
@FlowingSPDG
FlowingSPDG deleted the feat/initial-implementation branch April 23, 2026 16:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant