Commit graph

111 commits

Author SHA1 Message Date
40f8649126 fix(aten-gui): bundle emoji font via fontconfig for button glyphs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 21:36:53 +00:00
f2123eb737 fix(aten-mount): distinguish handled vs ignored SCSI commands in log
Add LUN field and handled/ignored status to SCSI debug log lines so
unknown opcodes (silently accepted per firmware behavior) are clearly
distinguishable from handled commands that return no data.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 20:01:25 +00:00
3ffe840bfc fix(aten-mount): report media present in GET_EVENT_STATUS_NOTIF response
GET_EVENT_STATUS_NOTIFICATION was returning media status byte 0x00 (no
media present) instead of 0x02 (media present, door/tray closed). This
caused the host kernel to think the disc was ejected after initial reads,
triggering USB bus resets that cascaded to the shared IPMI Virtual CDROM
interface.

Also properly handle Notification Class Request field (CDB byte 4):
class_request=0 now returns 4-byte NEA response matching the original
client behavior.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 19:13:21 +00:00
03df723d39 fix(aten-mount): fix PDU dispatch order and add SCSI debug logging
Fix command loop to check PDU type before length (matching the original
client's State_Fn_RX_PDU_TAG dispatch order). Previously length==0x1F
was checked first, which could misparse known PDU types as SCSI CBWs.

Drain payload bytes for keepalive and other known PDU types to prevent
stream desync if the BMC sends them with a non-zero length field.

Add structured logging via the log crate: SCSI commands log opcode name,
endpoint, tag, transfer/response sizes, status, and elapsed time.
READ_10/READ_12 additionally log LBA and sector count. Protocol events
(keepalives, mount status, unknown PDUs) are logged at trace/debug level.
Enable with RUST_LOG=debug (or RUST_LOG=trace for PDU headers).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 18:51:40 +00:00
06edf3a4be fix(aten-mount): use ToSocketAddrs for DNS resolution
SocketAddr::parse only accepts IP addresses, not hostnames. Switch to
ToSocketAddrs to match the KVM connection code and support hostnames.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 18:12:30 +00:00
fde91700c8 fix(aten-gui): run mount session on separate thread from rfd
The async-std runtime initialized by rfd's xdg-portal file dialog
pollutes the thread state, causing EAGAIN on subsequent blocking
socket I/O. Spawning the mount session on a fresh thread avoids this.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 18:01:30 +00:00
a1b99cceee fix(aten-gui): use async-std instead of tokio for rfd
Tokio in the dependency tree causes zbus (used by Slint for XDG
settings) to expect a tokio runtime, panicking on startup. async-std
avoids this conflict.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 16:35:56 +00:00
cda5e81312 chore(nix): update cargoHash for mount dependencies
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 15:32:05 +00:00
d545a0ab31 feat(aten-gui): implement mount/unmount ISO logic
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 15:29:08 +00:00
a1dfc51dba feat(aten-gui): add mount/unmount buttons to toolbar
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 15:26:15 +00:00
43faa05e0c feat(aten-gui): add --mount-port CLI arg
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 15:26:05 +00:00
24fe9bf306 feat(aten-gui): add aten-mount and rfd dependencies
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 15:26:01 +00:00
58d8ada1fc Release all modifier keys on window focus loss
Prevents modifier keys from getting stuck on the BMC when the
window loses focus (e.g. Alt+Tab) before the key-up event fires.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 15:08:47 +00:00
fe143db717 Fix garbled display on video mode switch and framebuffer clipping
Clear the entire framebuffer pixel buffer on resize instead of
preserving stale data from the previous resolution. Vec::resize()
only zeroes newly-added bytes, so old pixels were reinterpreted
with the new stride, producing garbled output after mode changes.

Fix bottom/right clipping by giving the Image explicit dimensions
bound to framebuffer size properties instead of using image-fit:
contain with a hardcoded toolbar width estimate. The window's
preferred size now derives from the layout.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 15:06:39 +00:00
186322b765 dos2unix on KVM_PROTOCOL.md, MOUNT_PROTOCOL.md and REVERSING_CLIENT.md 2026-03-12 13:38:03 +00:00
400d08bc72 Update protocol docs with server-side findings from RE
Add server-side implementation notes to KVM_PROTOCOL.md for KeyEvent
encryption support, ScreenSetPosition/ScreenCalibration handling,
SetScreenUILang desync risk, QoS bandwidth throttling, and PowerControl
dispatch. Add server-side architecture section to MOUNT_PROTOCOL.md
documenting ikvm_vmass.ko kernel module internals.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 13:34:24 +00:00
84b22693ce RE: cross-reference review, corrections, and gap-filling
Final review pass cross-referencing server RE with client protocol
spec and client RE. Key corrections and findings:

- Type 0x07 is MouseSync/ReSync, NOT ClientCutText — dispatches
  through DeviceManager to MouseDevice::ReSync ioctl
- Differential frame tile format includes 4 bytes padding
  (uninitialized stack data from CopyTileData)
- Differential-to-full fallback when diff data exceeds frame size
- Hermon sub-header byte 1 is color depth flag (0=RGB555, else 8bpp)
- ServerInit firmware bug: width/height are sent in reversed order
- Type 0x35 firmware bug: server sends 3 bytes but client expects 6
  (missing mouse info bytes)
- KeepAlive broadcast dispatches as type 0x39 PrivilegeInfo with
  hi=7 for LED sync
- libutility.so function signatures: UtilAuthUser returns 0-9 on
  success (>=10 failure), UtilGetNowPowerStatus returns u8

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 13:28:52 +00:00
aa041556b7 RE: ikvmserver startup, VCD module, vmass module, globals
Document initialization flow, kernel module internals, and remaining
undocumented functions. Key findings:

- main() is minimal: CreateServerSocket -> MainAcceptLoop, with
  C++ global constructors handling DeviceManager/session list init
- DeviceManager construction (0xb63c): allocates three sub-devices
- Shared memory init (0xdc10): GlobalVar, NVRAM, PS segments
- vcddev.ko: NO ioctl interface — VCD registers accessed directly
  via /dev/mem mmap at 0xF0028000. Module only handles interrupt-
  based capture completion (IRQ 22, major 25)
- ikvm_vmass.ko: USB VID=0x0EA0 PID=0x2168, Bulk-Only Mass Storage,
  3 ioctls (register/disconnect/connect), dual-LUN support,
  userspace reads CBW and writes responses via char device
- ~30 new functions documented: thread management, session cleanup,
  bandwidth throttling (select-based sleep), VCD utilities,
  message queue helpers
- 5 new global variable addresses (session count, shared memory
  pointers, connection ref count, listen socket)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 13:14:06 +00:00
9e78e481aa RE: ikvmserver protocol dispatch and complete message catalog
Document the ProtocolHandler dispatch loop and build comprehensive
message type reference tables. Key findings:

- ProtocolHandler: 24 switch cases, flow is ProcessCommandQueue ->
  read type -> PermissionFilter -> dispatch/skip. Type 0x16
  uniquely triggers two handlers sequentially
- SetEncoding handlers: type 0x08/0x36 set mouse mode, type 0x34
  is a no-op stub
- RequestRefresh (0x3a): triggers USB mouse hot-plug, not video
- Complete client-to-server table: 20 message types with payload
  formats, sizes, and permission requirements
- Complete server-to-client table: 9 response types with triggers
- Byte-level wire format for all 9 server responses including
  FramebufferUpdate 24-byte header, CursorPos, KeepAlive, VideoInfo,
  KbdMouseInfo, SessionInfo, PrivilegeCommand, ViewerLang, SessionStatus
- PowerControl: full 4-state dispatch (off/on/reset/soft-off)
- SetViewerLang: persists to /nv/IKVMViewerLang via atomic write

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 12:57:54 +00:00
0487dc5075 RE: ikvmserver keyboard/mouse input and USB HID devices
Document the complete input path from client events to USB HID
device writes. Key findings:

- KeyEvent (type 0x04): 17-byte payload with AES encryption flag,
  decrypts to [down_flag, keycode], writes 8-byte record to
  /dev/keyboard. down_flag=2 triggers press+release sequence
- PointerEvent (type 0x05): same encryption scheme, decrypts to
  [button_mask, x, y], writes 20-byte record to /dev/mouse with
  display dimensions for coordinate scaling
- usb_hid.ko (unstripped, "ATEN, Bobby"): two virtual USB HID
  devices with EP1 (keyboard, 8-byte boot protocol reports) and
  EP2 (mouse, 3-6 byte reports with 4 modes: absolute/relative/
  scroll/passthrough). 5 ioctls for hotplug, mouse mode, resync, LEDs
- AES encryption: single-block CBC with static key/IV, first byte
  of payload is encryption flag (0=plaintext, non-zero=encrypted)
- KeyboardDevice and MouseDevice object layouts and vtables
- DeviceManager vtable corrections and delegate target mappings

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 12:51:30 +00:00
1e32f656a0 RE: ikvmserver authentication, sessions, and permissions
Document the complete authentication flow, session lifecycle,
message queue IPC, and permission system. Key findings:

- Authentication: VNC type 0x10, ATEN-modified challenge/response
  with plaintext username/password, web SSO via /tmp/sess_* files,
  fallback to IPMI UtilAuthUser
- ServerInit: standard RFB fields + ATEN extension with session_id
  and 4 permission bytes mapped from IPMI privilege levels
- Session lifecycle: accept loop, per-session thread with Stream/
  RFBProtocol construction, max session enforcement, peer notification
- POSIX message queues: /<thread_id_hex>, 0x104-byte messages with
  7 known command codes for inter-session communication
- Permission filter: message type to permission byte mapping,
  GetFilterLen payload size table for all 20 message types
- SessionContext (0x50 bytes) and PrivilegeInfo (0x164 bytes) layouts
- 25 new functions mapped, 12 existing entries updated

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 12:35:44 +00:00
8077ca7135 RE: ikvmserver video capture and encoding pipeline
Document the complete video capture flow from FBUpdateRequest to
frame response. Key findings:

- DeviceManager object (global at 0x1e560) with VideoCaptureDevice,
  KeyboardDevice, and MouseDevice sub-objects
- DeviceManager vtable (0x14518) with 18 virtual methods
- VideoCaptureDevice (0x84 bytes) manages /dev/vcd and mmap'd buffers
- WPCM450 VCD hardware register map and 4-slot frame buffer layout
- Hermon encoding: full frame (0x01 + magic + raw pixels) vs
  differential (0x00 + tile count + 16x16 dirty tiles)
- Tile dirty bitmap at 0xF0020000 for differential encoding
- Preview thread and snapshot mechanisms
- VideoControl handlers (all three delegate to VCD::VideoControl)
- 50+ new functions identified and mapped

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 12:21:46 +00:00
ca27521d52 Add initial server RE, RE doc restructuring 2026-03-12 11:36:40 +00:00
b6ae488fc9 Update KVM_PROTOCOL.md with initial findings from BMC server RE 2026-03-12 10:52:36 +00:00
4f6c577ea7 fix(aten-kvm): send USB HID keycodes instead of X11 keysyms
The ATEN BMC expects USB HID keycodes in the key event packet, not X11
keysyms. Sending keysyms caused wrong keys (e.g. Q→Down Arrow, C→F10)
because the BMC interpreted the keysym value as a HID keycode.

Rewrote keymap to use HID keycodes from Java KeyMap.initHidKeyMap(),
renamed keysym→keycode throughout, and added toolbar width compensation
to window sizing so the framebuffer image gets its full width.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 10:46:15 +00:00
4e3d24064e fix(aten-kvm): fix tile header size and keyboard keysym mapping
Hermon incremental tiles have a 6-byte header (4 reserved + tile_y at
offset 4 + tile_x at offset 5), not 2 bytes. Confirmed via Ghidra
decompilation of HermonVideoDecoder::Decode. The 2-byte header caused
every tile after the first to misalign by 4 bytes, producing square
artifacts and preventing framebuffer updates.

Keyboard keysyms now use uppercase letters (0x41-0x5A) and shifted
symbol variants to match the original Java client's processVK Table 1,
which the BMC firmware's keysym-to-HID translation table expects.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 10:05:41 +00:00
a4020771b3 fix(nix): update cargoHash for new log dependency
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 09:40:02 +00:00
e7b4d7dedd feat(aten-kvm): add debug logging to protocol and decoder
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>
2026-03-12 09:37:14 +00:00
2d38afd4b2 fix(aten-kvm): move keyboard input to writer thread to fix EAGAIN crash
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>
2026-03-12 00:29:08 +00:00
7f181345d9 docs: update CLAUDE.md with toolbar and error dialog info
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 00:13:26 +00:00
1ca5d42b5e feat(aten-gui): show error dialog on KVM errors and connection failures
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 00:10:38 +00:00
035922617f feat(aten-gui): wire toolbar button callbacks to KVM input
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 00:08:01 +00:00
c1d973b131 feat(aten-gui): add toolbar and error dialog to Slint UI
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 00:04:25 +00:00
d1c8da025a docs: add implementation plan for GUI toolbar and error dialog
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 23:58:50 +00:00
434f128194 docs: add design for GUI toolbar and error dialog
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 23:56:24 +00:00
cb2cf7557a fix(aten-gui): wrap binary with LD_LIBRARY_PATH for dlopen'd libs
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>
2026-03-11 23:49:17 +00:00
e45a221a78 chore: update cargoHash in flake.nix
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 23:24:17 +00:00
e6006f5332 docs: update README and CLAUDE.md for keyboard input and winit backend
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 23:14:15 +00:00
fe6cdb7e1c feat(aten-gui): wire up keyboard input via winit event interception
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 23:13:08 +00:00
b3cad61184 feat(aten-gui): add physical key to X11 keysym mapping
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 23:11:04 +00:00
45ffad42ee chore: replace Qt6 deps with winit/X11/Wayland deps in flake.nix
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 23:06:56 +00:00
00b8e62b23 chore(aten-gui): switch from Qt6 to winit backend, add logging deps
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 23:06:52 +00:00
5f3d46de8f feat(aten-kvm): add input channel to session loop, reduce timeout to 5ms
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 23:05:18 +00:00
0511226611 feat(aten-kvm): add InputEvent type and build_key_event
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 23:02:48 +00:00
1f1415b601 Add aten-gui keyboard input implementation plan
7 tasks: aten-kvm protocol changes, winit backend switch,
flake.nix Qt6 removal, keymap module, event interception, docs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 23:00:38 +00:00
01343ca206 Add aten-gui keyboard input design
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>
2026-03-11 22:53:55 +00:00
2bdda6b0e6 fix(aten-kvm): reuse encoding from first frame for subsequent updates
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>
2026-03-11 22:12:11 +00:00
42d1960dc0 Remove obsolete plans 2026-03-11 22:07:50 +00:00
74ad76f4b4 fix: support hostnames in KVM connect, update README
- 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>
2026-03-11 21:57:39 +00:00
5591771984 chore: update flake.nix and CLAUDE.md for aten-kvm
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 21:54:35 +00:00