5.0 KiB
Gateway input and feedback v1
This grammar is carried only in an authenticated Phase 3C gateway session. It is deliberately provider-neutral: it never carries provider routes, certificates, credentials, opaque provider packets, clipboard bytes, files, or client-folder data. It does not change the v1 datagram header or any existing kind encoding; the new kinds require explicit feature negotiation and a new immutable Protocol release candidate.
input.sequenced.v1 payload (VGI1)
All multibyte fields are big-endian and unsigned unless a field is explicitly marked signed. The payload has exactly six bytes of header followed by the declared body:
| Offset | Size | Field | Rule |
|---|---|---|---|
| 0 | 4 | magic | ASCII VGI1 |
| 4 | 1 | kind | one of the kinds below |
| 5 | 1 | payload length | exact body byte count |
| 6 | N | body | exact kind-specific body |
The decoder rejects an unknown kind, non-exact length, nonzero reserved byte, unsupported controller index, malformed UTF-8, a non-scalar UTF-8 value, or a payload larger than the channel limit before provider translation. A false keyboard or mouse state and a zeroed controller state are explicit releases; they are retained by the gateway and replayed as individual provider releases during cleanup.
| Kind | Name | Exact body |
|---|---|---|
0x01 |
keyboard | state (0 release, 1 press), modifiers (one byte), nonzero scancode (u16). |
0x02 |
mouse button | state (0 release, 1 press), button (1 through 5), reserved 0. |
0x03 |
relative mouse | delta_x (i16), delta_y (i16). |
0x04 |
UTF-8 scalar | exactly one valid UTF-8 Unicode scalar, one through four bytes. |
0x05 |
controller state | controller (0 through 15), active_mask (u16), button_flags (u16), left_trigger (u8), right_trigger (u8), left_x (i16), left_y (i16), right_x (i16), right_y (i16), extra_button_flags (u16). A zero active_mask and zero state is release. |
0x06 |
absolute mouse | x (u16), y (u16), viewport_width (u16), viewport_height (u16). Viewport dimensions must be nonzero and each coordinate must be strictly smaller than its corresponding dimension. |
0x07 |
high-resolution scroll | vertical_delta (i16), horizontal_delta (i16). Positive and negative values preserve the client scroll direction without provider-specific scaling. |
Keyboard, mouse button, UTF-8, controller, absolute mouse, and scroll messages
are delivered over the gateway's reliable ordered input flow. Relative and
absolute mouse movement and scroll are state changes, not pressed-state
entries. Kinds 0x06 and 0x07 are accepted only when the session advertises
input.absolute.v1 and input.scroll.v1, respectively. The gateway maps the
validated values to the provider's separate input messages; it does not forward
this envelope to the provider.
Reliable control payload (VGF1)
control.ack.v1 remains the existing authenticated bidirectional reliable
control flow. Within an active gateway session, its provider-feedback payload
is the following exact envelope:
| Offset | Size | Field | Rule |
|---|---|---|---|
| 0 | 4 | magic | ASCII VGF1 |
| 4 | 1 | direction | 0 client-to-gateway; 1 gateway-to-client |
| 5 | 1 | type | valid only for the stated direction |
| 6 | 2 | payload length | exact payload byte count |
| 8 | N | payload | exact type-specific body |
The client-to-gateway types are 0x01 IDR request (empty), 0x02 FEC
status, and 0x03 terminal receipt (empty). FEC status contains
frame_index (u32), highest_received_sequence (u16),
next_contiguous_sequence (u16), missing_before_highest (u16),
total_data_packets (u16), total_parity_packets (u16),
received_data_packets (u16), received_parity_packets (u16),
fec_percentage (u8), multi_fec_block_index (u8), and
multi_fec_block_count (u8). The gateway maps this fixed 21-byte structure to
the provider's unsequenced ENet FEC delivery; it does not put it on the reliable
provider input path.
The terminal receipt is valid only from client to gateway with an exact zero-byte payload. Session-state authorization remains a gateway responsibility; the Protocol grammar defines only its fixed wire shape.
The gateway-to-client types are 0x10 host termination (exit_code u32),
0x11 rumble (controller u8, low_frequency u16,
high_frequency u16), and 0x12 HDR mode (enabled exactly 0 or 1). The
gateway derives these from authenticated provider control messages, normalizes
their bounded fields, and rejects all unrecognized provider feedback. The HDR
envelope intentionally carries only the negotiated mode; provider-specific HDR
metadata remains behind the gateway boundary.
Apollo's pinned src/stream.cpp source defines separate termination, rumble,
and HDR control structures, while Moonlight common-C's ControlStream.c and
InputStream.c separate reliable input/control from UDP media. This Verse
grammar is a new normalized contract; it does not copy either implementation or
expose its wire format.