# KVM port configuration and switching ## Context The Belkin OmniView fronts an Avocent KVM switch with up to 16 ports. The legacy web interface at `http://10.3.0.130` allows port naming, hotkey assignment, visibility toggling, and active port switching. Users currently need to visit that interface separately. We want blekin to fully replace it — starting with port management, with a navigation structure that supports adding more settings pages later. ## Belkin device API (from HTML form inspection) **GET /kvm.asp** — returns HTML form with current port config: - `ECG_kvm_nr_ports`: port count (1,2,4,8,12,16,24,32,48,64) - `ECG_key_pause_duration`: ms (default 100) - Per port N (0-indexed): `ECG_kvm_portname_N`, `ECG_kvm_hotkey_N`, `ECG_kvm_show_in_rc_N` - `kvm_active_port_0`: currently selected port **POST /kvm.asp** — save port config (same fields + `action_apply=Apply`) **POST /home2.asp** — switch active port: `kvm_active_port_0=<0-15>&action_switch_0=Switch` All requests require `pp_session_id` cookie. ## Changes ### Backend: persist session cookie Modify `AppState` in `main.rs` to hold the device session cookie: ```rust pub session_cookie: Arc>>, ``` Update `login.rs` to store the cookie into shared state after successful auth. ### Backend: new REST endpoints (`crates/ericrfb-proxy/src/kvm.rs`) | Endpoint | Method | Purpose | |----------|--------|---------| | `/api/kvm/ports` | GET | Fetch port config (scrape kvm.asp, return JSON) | | `/api/kvm/ports` | PUT | Save port config (build form, POST to kvm.asp) | | `/api/kvm/switch` | POST | Switch active port (POST to home2.asp) | **GET /api/kvm/ports response:** ```json { "port_count": 16, "key_pause_duration": 100, "active_port": 0, "ports": [ { "index": 0, "name": "oolon", "hotkey": "", "show_in_rc": true }, ... ] } ``` HTML scraping: simple string/regex matching on the predictable firmware HTML (extract `value="..."` from named inputs, `selected` from dropdowns, `checked` from checkboxes). ### Frontend: app shell with navigation (`crates/ericrfb-frontend/src/shell.ts`) After login, render a shell layout: ``` +----------+----------------------------------+ | sidebar | content area | | | | | Console | (active page rendered here) | | Ports | | | | | +----------+----------------------------------+ ``` Each page module exports `mount(container)` and `unmount()`. The shell swaps them on nav clicks. This pattern supports adding Virtual Media, Users, Device Settings etc. later without restructuring. ### Frontend: refactor console into page module Move `console.ts` logic into a `pages/console.ts` with mount/unmount pattern: - `mount(el, session)`: creates toolbar + canvas, connects WebSocket - `unmount()`: tears down WebSocket, removes event listeners Add port switcher `