Commit Graph

5 Commits

Author SHA1 Message Date
35db634317 fix: hotkey-based port switching and HTML entity unescaping
All checks were successful
CI / fmt (push) Successful in 36s
Publish / frontend (push) Successful in 44s
CI / check (push) Successful in 1m23s
CI / clippy (push) Successful in 1m36s
Publish / backend (push) Successful in 2m45s
Three fixes for KVM port management:

1. HTML unescape scraped values — the > character in hotkey strings
   (e.g., PrintScreen>0>1) gets entity-encoded to > in the device's
   HTML. Added html_unescape() to the scraper so hotkeys round-trip
   correctly.

2. Send hotkeys over WebSocket — port switching via the Belkin web form
   only changes the active port number, it doesn't send the hotkey
   sequence to the downstream KVM. Now when switching ports from the
   console dropdown, blekin parses the Belkin hotkey syntax and sends
   the key press/release sequence over the existing WebSocket connection.

3. New hotkey.ts parser — converts Belkin hotkey syntax to scancode
   sequences:
   - > and -> = sequential (tap each key)
   - + = simultaneous (hold all, release in reverse)
   - Supports all key names: PrintScreen, Ctrl, Alt, Shift, F1-F12,
     letters, digits, navigation keys, numpad

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-07 12:13:57 +03:00
9bd215356b fix: add __templates__ and image button coords to KVM form submissions
All checks were successful
CI / fmt (push) Successful in 34s
Publish / frontend (push) Successful in 46s
CI / clippy (push) Successful in 1m21s
CI / check (push) Successful in 1m32s
Publish / backend (push) Successful in 2m44s
The Belkin firmware requires:
1. A hidden __templates__ field in all form POSTs
2. Image button actions submitted as name.x=0&name.y=0 (not name=value)
3. ECG_kvm_powerport_cnt hidden field

Without these, the device returns "Permission denied" on port config
saves. Also fixed the switch endpoint with the same pattern.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-07 11:50:38 +03:00
ea18d97aa6 feat: KVM port management — configuration, switching, and navigation shell
Some checks failed
CI / fmt (push) Failing after 43s
Publish / frontend (push) Successful in 44s
CI / check (push) Successful in 1m20s
CI / clippy (push) Successful in 1m41s
Publish / backend (push) Successful in 2m49s
Backend (crates/ericrfb-proxy):
- Session cookie now persisted in AppState for device API calls
- New kvm.rs with three REST endpoints:
  GET /api/kvm/ports — scrapes kvm.asp, returns port config as JSON
  PUT /api/kvm/ports — saves port names, hotkeys, visibility, count
  POST /api/kvm/switch — switches active KVM port via home2.asp
- HTML scraping extracts form values from predictable firmware HTML

Frontend (crates/ericrfb-frontend):
- New shell.ts: sidebar navigation with page routing pattern
  (Console, Ports — extensible for Virtual Media, Users, etc.)
- Console refactored into pages/console.ts with mount/unmount lifecycle
  - Port switcher dropdown in toolbar (fetches port list, switches on change)
  - WebSocket auto-reconnects after port switch
- New pages/ports.ts: editable port configuration table
  - Port count, key pause duration, per-port name/hotkey/show-in-console
  - Save, reload, and per-port switch buttons
  - Active port highlighted
- Dark theme sidebar with active state indicators

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-07 11:18:36 +03:00
3bd7ee8eac feat: phase 7 — proxy daemon with HTTP login and WebSocket bridge
All checks were successful
CI / fmt (push) Successful in 38s
CI / check (push) Successful in 1m20s
CI / clippy (push) Successful in 1m19s
ericrfb-proxy axum server with three endpoints:

POST /api/login:
- Proxies credentials to OmniView auth.asp
- Extracts session cookie, fetches title_app.asp
- Returns JSON with applet_id, port, protocol_version, board_name

GET /api/ws?applet_id=...&port=...:
- WebSocket upgrade, connects to OmniView via e-RIC RFB
- Bidirectional pump: OmniView frames → RGBA blits over WS,
  browser input events → key/mouse/hotkey to OmniView
- Binary protocol: TAG_BLIT(0x01), TAG_RESIZE(0x03) server→client;
  TAG_KEY_PRESS(0x10), TAG_KEY_RELEASE(0x11), TAG_POINTER(0x12),
  TAG_CTRL_ALT_DEL(0x13) client→server

Static file fallback via tower-http ServeDir.

Config via config.toml or BLEKIN_HOST env var.

Tested against real OmniView:
- Login endpoint returns valid APPLET_ID
- WebSocket upgrade succeeds (HTTP 101)
- Session connects and pumps frames

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-06 15:11:50 +03:00
3db2927add feat: phase 0+1 — workspace scaffold and protocol primitives
Phase 0: Cargo workspace with ericrfb (lib) and ericrfb-proxy (bin)
crates, .envrc for RUST_LOG, workspace dependency pins.

Phase 1: ericrfb/src/proto.rs implements all wire primitives:
- read/write helpers matching h.java (u8, i8, u16-BE, i16-BE, i32-BE)
- varint reader/writer matching aw.int() (1-3 bytes, Tight lengths)
- modified-UTF-8 string reader matching h.byte()
- RectHeader { x: u16, y: u16, w: u16, h: u16, encoding: i32 }
- RGB332 → RGBA compile-time LUT (256 entries)

20 tests including proptest varint roundtrip over [0, 2^22).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-06 13:44:24 +03:00