Instrument the message loop, hermon decoder, and writer thread with
log crate calls to help diagnose framebuffer update and keyboard issues.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The 5ms read timeout (added for keyboard input polling) caused
read_exact calls inside message handlers to fail with EAGAIN when
large framebuffer updates didn't arrive within the window. This
crashed the session 15-30 seconds after any keyboard input.
Split the socket with try_clone: a dedicated writer thread handles
keyboard events via blocking recv, while the reader uses a 1-second
timeout (only for stop-flag checking). This fixes both the crash and
the non-updating framebuffer (content updates from the server can now
survive long enough to be decoded and displayed).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
xkbcommon-dl loads libxkbcommon-x11.so via dlopen at runtime, which
isn't covered by the binary's RPATH in nix builds.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Physical key passthrough approach: capture winit PhysicalKey codes,
map to X11 keysyms via fixed table, send as independent key events.
Avoids local keymap dependency entirely.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The BMC's GetDecoder is a singleton factory that creates a decoder on
the first frame and reuses it for all subsequent frames. The BMC sends
encoding 0x00 for incremental frames after the initial 0x59 (Hermon)
frame, which was incorrectly rejected as unsupported.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Use ToSocketAddrs instead of parse::<SocketAddr> so hostnames resolve
- Update README.md to reflect aten-gui is now a KVM console viewer
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Display-only KVM console: RFB protocol with Hermon (WPCM450) video
decoder, Slint framebuffer display, no keyboard/mouse input.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The qtbase setup hook sets QMAKE to a path inside the setup-hook
derivation that doesn't contain an actual qmake binary. Combined
with CRLF line endings injecting \r into shell variable values,
this caused qttypes to compile with cfg(no_qt), producing a Slint
binary with no functional Qt backend.
Fix by overriding QMAKE in preBuild (nix build) and shellHook
(devShell), and converting flake.nix to Unix line endings.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The server could not open the virtual CD-ROM block device because the
Linux kernel sends READ TRACK INFORMATION during device enumeration and
our client was returning ILLEGAL REQUEST instead of track data.
Implemented the 0x52 handler by decompiling the firmware's ReadTrackInfo
function (at 0x00128bea). Returns a 28-byte Track Information Block
describing a single Mode 1 data track covering the full disc.
Also fixed the default SCSI opcode handler to match firmware behavior:
the original IsoCommand default case returns no data with status PASS
(no error sense), but we were returning ILLEGAL REQUEST with FAILED
status, which could cause the host OS to reject the device.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove panics from build_plugin_packet (return io::Result)
- Drain unknown PDU payloads to prevent stream desync
- Use overflow-safe LBA bounds check in READ(10)/READ(12)
- Move set_nodelay before initial packet exchange
- Move set_read_timeout out of command loop
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>