Architecture¶
System Overview¶
See the rendered system diagram: architecture.svg.
At a high level:
- firmware application code runs on top of xylolabs-sdk
- xylolabs-protocol provides the shared XMBP wire format
- xylolabs-hal-* crates implement target-specific platform adapters
- xylolabs-server accepts HTTP/WebSocket ingest, enforces auth, and coordinates persistence
- PostgreSQL stores metadata/index state while MinIO stores audio/blob payloads
Data Flow¶
- MCU captures audio (I2S) and sensor data, feeds them into
XylolabsClient. - XylolabsClient encodes audio via XAP or ADPCM into the ring buffer, accumulates metadata samples.
- On each
tick(), the client batches metadata into an XMBP packet and sends audio + metadata over HTTP POST (or WebSocket) to the server. - Server authenticates via API key, decodes XMBP, buffers samples in
IngestManager, and flushes to PostgreSQL (metadata) and MinIO (audio chunks in XMCH format).
Crate Dependency Graph¶
Dependency flow summary:
- xylolabs-server depends on xylolabs-core, xylolabs-db, xylolabs-storage, and xylolabs-transcode
- xylolabs-transcode also depends on xylolabs-core and xylolabs-protocol
- xylolabs-sdk depends on xylolabs-protocol
- xylolabs-hal-* crates sit on top of xylolabs-sdk
Crate Roles¶
| Crate | Role | no_std |
|---|---|---|
xylolabs-core |
Domain models, DTOs, error types, chunk format (XMCH), XMBP server-side codec, downsampling | No |
xylolabs-db |
SQLx repository layer + PostgreSQL migrations | No |
xylolabs-storage |
S3/MinIO client abstraction | No |
xylolabs-transcode |
FFmpeg worker, XAP server-side decoder, stale job reaper, transcoding pipeline | No |
xylolabs-server |
Axum web server, routes, middleware, ingest engine | No |
xylolabs-protocol |
XMBP wire protocol encoder/decoder (shared with SDK) | Yes |
xylolabs-sdk |
Embedded SDK core: client, session, codecs, transport | Yes |
xylolabs-hal-* |
Per-target Platform trait implementations (not in workspace) | Yes |
Proprietary Protocols (Summary)¶
XMBP -- Xylolabs Metadata Batch Protocol¶
Binary big-endian wire protocol for batched sensor/metadata transmission from MCU to server. Shared between the no_std SDK encoder and the server decoder.
- Magic:
0x584D4250("XMBP"), Version: 1 - Supports 11 value types (F64, F32, I64, I32, Bool, String, Bytes, F64Array, F32Array, I32Array, Json)
- Up to 256 streams per batch, microsecond timestamps
- Encoder: zero-copy, zero-alloc into borrowed buffer with sticky overflow
- Decoder: validates all lengths before allocation (DoS-safe)
- Batch sequence wraps at u16::MAX with forward/backward gap detection
Full specification: XMBP-SPECIFICATION.md
XAP -- Xylolabs Audio Protocol¶
Proprietary MDCT-based spectral audio codec providing ~8:1 to 10:1 compression of 16-bit PCM.
- Sample rates: 8, 16, 24, 32, 48, 96 kHz
- Channels: 1--4 (encoded independently)
- Frame durations: 7.5 ms, 10 ms
- ~10 MIPS per channel (with DSP acceleration), ~8 KB RAM per channel
- Requires FPU; platforms without FPU use IMA-ADPCM instead
- Codec ID in XMBP:
0x03
Server-side decoder: The xylolabs-transcode crate includes an XAP decoder (xap_decode.rs) that performs inverse MDCT + dequantization. When a .xap file is uploaded, the transcode pipeline automatically decodes it to PCM WAV before passing to FFmpeg for transcoding to the target format. Sample rate is inferred from the frame header's frame_samples field.
Full specification: XAP-SPECIFICATION.md
XMCH -- Xylolabs Metadata Chunk Format¶
Server-side binary format for storing flushed metadata chunks in S3/MinIO.
Layout:
- 32-byte header
- magic: 0x584D4348 (XMCH)
- version: 1
- value type: wire tag
- reserved: 2 bytes
- sample count: u32
- start timestamp: u64 microseconds
- end timestamp: u64 microseconds
- data size: u32
- timestamps column: N × u64 big-endian
- values column: type-dependent payload
Chunks are optionally zstd-compressed via encode_chunk_compressed() before S3 upload.
Server Ingestion Pipeline¶
IngestManager¶
Located at crates/xylolabs-server/src/ingest/manager.rs.
- Maintains per-session state with per-stream
StreamBuffers. - Buffers up to 500,000 samples per stream before flush.
- Flush writes encoded XMCH chunks to S3 and metadata records to PostgreSQL.
- Concurrent flush guard (
flushingflag) prevents double-flush. Samples arriving during flush are accumulated separately and merged on completion. - On flush failure, original samples are prepended back for retry.
- Supports live event broadcasting via
tokio::sync::broadcastfor real-time WebSocket subscribers. - Stale session eviction based on last activity timestamp.
Batch Sequence Tracking¶
The server uses classify_batch_sequence() with forward/backward gap heuristics to distinguish reordering from genuine gaps at u16 wraparound boundaries.
Downsampling¶
LTTB (Largest Triangle Three Buckets) algorithm at crates/xylolabs-core/src/downsample.rs for query-time visual downsampling of time series data. Preserves visual shape while reducing point count.
Auth Architecture¶
Dual Auth Model¶
| Path | Method | Auth |
|---|---|---|
/api/v1/ingest/* |
API Key | X-Api-Key header, scoped to facility |
/api/v1/auth/* |
Public | Rate-limited (10 req/min per IP) |
All other /api/v1/* |
JWT | Bearer token, RBAC-enforced |
RBAC Hierarchy¶
super_admin-- global access, manages all facilitiesfacility_admin-- manages own facility's data and usersuser-- read-only access to own facility's data
Rate Limiting¶
Auth endpoints use in-memory rate limiting via mini_moka::sync::Cache with 60-second TTL windows. Max 10 attempts per IP per minute. Trusted proxy IPs can be configured for correct X-Forwarded-For extraction.