96 lines
5.5 KiB
Markdown
96 lines
5.5 KiB
Markdown
# 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. |
|
|
| `0x08` | controller arrival | `controller` (u8, 0 through 15), `active_mask` (u16), `family` (u8: `0` unknown, `1` xbox, `2` playstation, `3` nintendo), `supported_button_flags` (u32). It must precede controller state for that controller. |
|
|
|
|
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, `0x03` terminal receipt (empty), `0x04` quality-work prompt, and
|
|
`0x05` Stop-work prompt. The quality prompt is exactly `operation_id` (16
|
|
canonical UUID bytes) followed by `revision` (nonzero u64). The Stop prompt is
|
|
exactly `operation_id` (16 canonical UUID bytes). Prompts never authorize or
|
|
complete work; the gateway acquires the matching durable mTLS work item.
|
|
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.
|