Repository navigation
ADR: SOL Terminal Emulation & OEM Capabilities Encoding Support
Proposed
Serial-over-LAN (SOL) redirection on Intel vPro and ISM devices transmits text and control sequences from remote platforms during BIOS POST and runtime execution. Currently, ui-toolkit decodes incoming SOL data before passing it down to frontend component wrappers (ui-toolkit-angular, ui-toolkit-react) and consumer applications (such as sample-web-ui and console).
As tracked in ui-toolkit Issue #1855 and ui-toolkit Issue #1768, character rendering corruptions occur under two primary conditions:
- Multi-byte UTF-8 split across chunks: Network packets and WebSocket chunks may break multi-byte UTF-8 characters across boundaries, causing chunk-by-chunk decoders to treat partial trailing bytes as invalid sequences.
-
Character set and emulation mismatches: Legacy BIOS setup screens transmit OEM terminal emulation types (such as PC-ANSI single-byte high-ASCII box-drawing characters like
0xDA,0xC4,0xBF), but the toolkit blindly decodes them as UTF-8, resulting in garbled replacement glyphs (reported in Console BIOS Issue #530).
According to the Intel CSME/AMT Redirection specifications, the 2nd Byte of OEM Capabilities (Terminal Emulation) defines the terminal emulation expected by the remote host:
-
Bit 0:3 – Terminal Type:
-
1– VT52 (Basic monochrome) -
2– VT100+ (Adds function keys F5–F14; Note: Deprecated/unsupported in CSME 14.0 and later) -
3– VT-UTF8 (Adds function key F8; standard streaming UTF-8) -
4– PC-ANSI (Standard PC-ANSI / Code Page 437 box-drawing characters) -
5 and higher– Reserved for future definitions
-
To support both modern and legacy devices, console operators require the ability to configure or override the terminal emulation type directly from the UI, with sensible automatic defaults derived from device OEM capabilities.
- Spike Objectives (Issue #1855): Resolve character rendering distortions on Intel vPro and ISM devices without regressing legacy BIOS terminal rendering.
- Fidelity Across Generations: Modern environments expect standard VT-UTF8, whereas legacy BIOS setup utilities depend heavily on CP437/PC-ANSI box-drawing characters or VT52 sequences.
- Split-Chunk Stream Safety: Seamlessly buffer and stitch multi-byte characters split across chunk boundaries without leaking memory or corrupting succeeding sessions.
-
Separation of Concerns: Keep core byte decoding and emulation translations centralized within
ui-toolkit, keepingui-toolkit-angularandui-toolkit-reactwrappers lightweight. - User Control & Fallback: Support auto-negotiation via OEM capabilities while giving UI operators manual dropdown controls to override terminal emulation if firmware reports incorrect flags.
Define a strongly typed enum matching the OEM capability bit definitions:
export enum SolTerminalType {
VT52 = 1,
VT100Plus = 2, // Deprecated in CSME >= 14.0; maintained for backwards compatibility
VTUTF8 = 3,
PCANSI = 4
}- Deprecation metadata and UI annotations will flag
VT100Plusas unavailable or deprecated for CSME >= 14.0 platforms.
TerminalDataProcessor in ui-toolkit will manage both a stateful byte decoder and an emulation profile based on the active terminal mode:
-
VT-UTF8 Mode: Employs a stateful stream decoder (
new TextDecoder('utf-8', { fatal: false })using{ stream: true }). Trailing partial multi-byte sequences are retained between chunk boundaries and resolved with subsequent data. -
PC-ANSI / CP437 Mode: Maps single-byte high-ASCII characters (0x80–0xFF) directly to corresponding Unicode characters (e.g., box-drawing glyphs
┌,─,┐,│) via a lookup table, preserving legacy BIOS setup screens. -
VT52 Mode: Decodes 7-bit ASCII and maps legacy 2-byte escape sequences (
<ESC>Athrough<ESC>K) into standard xterm-compatible cursor movement sequences.
To address vulnerabilities identified during review of PR #1800:
-
Hard Buffer Boundary: The cache for split trailing bytes is capped at 3 bytes (the maximum possible incomplete prefix for a 4-byte UTF-8 character). If an invalid sequence persists beyond this boundary, the buffer is purged, a replacement character (
\uFFFD) is output, and the state resets. -
Session Lifecycle Hook (
reset()): An explicit.reset()method flushes all cached state upon WebSocket disconnects, session renegotiation, or terminal type switching, preventing stale bytes from bleeding into new sessions.
The UI architecture will support capability-negotiated defaults alongside manual operator overrides:
- Default Negotiation: When the redirector completes the capability handshake, the initial terminal emulation type defaults to the value parsed from Bit 0:3 of the 2nd Byte of OEM Capabilities.
-
UI Selector: A dropdown menu is exposed in the terminal toolbar across consumer applications (
sample-web-ui,console) displaying:-
VT-UTF8(Default for modern firmware) -
PC-ANSI(Recommended for BIOS setup menus) VT52-
VT100+(Marked as "Legacy only (< CSME 14)")
-
- Dynamic selection changes take effect immediately on
TerminalDataProcessorwithout restarting or dropping the underlying WebSocket redirector connection.
┌────────────────────────────────────────────────────────┐
│ Consumer UI / Sample Web UI │
│ [ Terminal Selector: VT-UTF8 | PC-ANSI | VT52 ] │
└──────────────────────────┬─────────────────────────────┘
│ (Input / Property Change)
┌──────────────────────────▼─────────────────────────────┐
│ ui-toolkit-angular / ui-toolkit-react Wrappers │
└──────────────────────────┬─────────────────────────────┘
│ setTerminalType(type)
┌──────────────────────────▼─────────────────────────────┐
│ ui-toolkit Core │
│ ┌──────────────────────────────────────────────────┐ │
│ │ TerminalDataProcessor │ │
│ │ │ │
│ │ Incoming Chunks ──► [ Stateful Stream Cache ] │ │
│ │ │ │ │
│ │ Active Decoder Match │ │
│ │ ┌──────────┴──────────┐ │ │
│ │ ▼ ▼ │ │
│ │ [VT-UTF8] [PC-ANSI] │ │
│ └─────────────────────┬─────────────────────┬──────┘ │
└────────────────────────┼─────────────────────┼─────────┘
▼ ▼
┌─────────────────────────────────────┐
│ xterm.js Terminal Display │
└─────────────────────────────────────┘
- Resolves Issue #1855: Eliminates character corruption caused by multi-byte UTF-8 splits across network packets.
- Preserves Legacy Compatibility: Restores accurate layout and line drawing for console BIOS setup menus (Console Issue #530).
- Specification Compliance: Aligns terminal handling with Intel CSME/AMT Redirection OEM capability bit specifications.
- Manual Recovery Path: Enables operators to override emulation if BIOS firmware misreports capabilities.
-
Encoding Lookup Table: Requires embedding a lightweight CP437-to-Unicode conversion mapping inside
ui-toolkitfor browser environments lacking native CP437TextDecodersupport. - Coordinated Rollout: Requires staged version bumps across multiple downstream repositories.
| Step | Repository | Scope of Changes |
|---|---|---|
| 1 | ui-toolkit |
Implement SolTerminalType, update TerminalDataProcessor with stateful TextDecoder, add CP437 mapping, introduce setTerminalType() and reset(). |
| 2 | ui-toolkit-angular |
Update ui-toolkit dependency; expose terminalType @Input() and change emitter. |
| 3 | ui-toolkit-react |
Update ui-toolkit dependency; expose terminalType prop and event callback. |
| 4 |
sample-web-ui & console
|
Upgrade wrapper dependencies; add terminal selection dropdown in the SOL action bar. |