Compare commits
6
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
30bb1a2fa3 | ||
|
|
021ecf425f | ||
|
|
ec15279b42 | ||
|
|
37c041e13e | ||
|
|
2e92fae27f | ||
|
|
534bb1031b |
@@ -9,6 +9,7 @@ valid-controller 1 gateway_input hex=5647493105110200030004ffff00010002000300040
|
||||
valid-controller-release 1 gateway_input hex=5647493105110200000000000000000000000000000000 valid
|
||||
valid-idr 1 gateway_feedback hex=5647463100010000 valid
|
||||
valid-fec 1 gateway_feedback hex=56474631000200150000002a000500030002000a000200080002140001 valid
|
||||
valid-terminal-receipt 1 gateway_feedback hex=5647463100030000 valid
|
||||
valid-termination 1 gateway_feedback hex=564746310110000400000001 valid
|
||||
valid-rumble 1 gateway_feedback hex=56474631011100050112345678 valid
|
||||
valid-hdr 1 gateway_feedback hex=564746310112000101 valid
|
||||
@@ -18,5 +19,9 @@ invalid-input-reserved 1 gateway_input hex=564749310203010101 invalid:reserved
|
||||
invalid-input-utf8 1 gateway_input hex=564749310402c328 invalid:utf8
|
||||
invalid-input-length 1 gateway_input hex=564749310104010200 invalid:length
|
||||
invalid-feedback-direction 1 gateway_feedback hex=5647463101020000 invalid:direction
|
||||
invalid-feedback-type 1 gateway_feedback hex=5647463100030000 invalid:type
|
||||
invalid-terminal-receipt-direction 1 gateway_feedback hex=5647463101030000 invalid:direction
|
||||
invalid-terminal-receipt-body 1 gateway_feedback hex=5647463100030001ff invalid:length
|
||||
invalid-terminal-receipt-truncated 1 gateway_feedback hex=56474631000300 invalid:truncated
|
||||
invalid-terminal-receipt-length 1 gateway_feedback hex=5647463100030001 invalid:length
|
||||
invalid-feedback-type 1 gateway_feedback hex=5647463100040000 invalid:type
|
||||
invalid-feedback-length 1 gateway_feedback hex=5647463101100003000000 invalid:length
|
||||
|
||||
|
@@ -9,5 +9,5 @@
|
||||
"fixtures/conformance/gateway-input-feedback-v1.tsv",
|
||||
"fixtures/conformance/tunnel-v1.tsv"
|
||||
],
|
||||
"corpus_sha256": "69d5b12a533ff0d9786784b99aecc8a74a7ec2c6855b75c52e46ecff5bd3e6c5"
|
||||
"corpus_sha256": "0eb9e905e77069c0bd67182b40e7f9b1b41041d5290b0e3b2152abf83ce32eae"
|
||||
}
|
||||
|
||||
@@ -53,8 +53,9 @@ is the following exact envelope:
|
||||
| 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) and `0x02` FEC
|
||||
status: `frame_index` (u32), `highest_received_sequence` (u16),
|
||||
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),
|
||||
@@ -63,6 +64,10 @@ status: `frame_index` (u32), `highest_received_sequence` (u16),
|
||||
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
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-07-30
|
||||
@@ -0,0 +1,26 @@
|
||||
## Context
|
||||
|
||||
QUIC stream writes complete before peer receipt. The previous gateway avoided losing its last control frame by waiting for client-owned connection closure; immediate gateway closure reproduced event loss. `control.ack.v1` is already reliable and bidirectional, so no new flow is needed.
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
|
||||
- Represent peer receipt of the one terminal control event.
|
||||
- Keep the message bounded, direction-specific, and independent of provider data.
|
||||
|
||||
**Non-Goals:**
|
||||
|
||||
- General acknowledgements, retries, lifecycle state, or provider transport semantics.
|
||||
- Changes to JSON schemas or generated bindings.
|
||||
|
||||
## Decisions
|
||||
|
||||
- Assign client-direction `VGF1` type `0x03` with an empty payload to terminal receipt.
|
||||
- Permit it only after a terminal event; the Data Plane enforces session state and deadline.
|
||||
- Preserve all existing message bytes and meanings.
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
- [Older clients do not send the receipt] → The gateway closes at its bounded receipt deadline; compatibility does not transfer tunnel ownership back to the client.
|
||||
- [A stale receipt is replayed] → The gateway rejects receipts outside the single awaiting-terminal state.
|
||||
@@ -0,0 +1,23 @@
|
||||
## Why
|
||||
|
||||
A public independent QUIC regression proved that closing the gateway connection immediately after writing the reliable terminal event can discard that event, while waiting for the client to close leaves session ownership with the client. The registered bidirectional control flow needs one bounded receipt semantic so the gateway can close only after observed delivery or a fixed receipt deadline.
|
||||
|
||||
## What Changes
|
||||
|
||||
- Add a client-to-gateway terminal receipt to the existing bounded `VGF1` envelope on `control.ack.v1`.
|
||||
- Keep the receipt payload empty and valid only while one terminal event is awaiting receipt.
|
||||
- Preserve the existing IDR, FEC, termination, rumble, and HDR meanings.
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
None.
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
- `gateway-input-feedback`: Permit the narrowly scoped terminal receipt in the existing reliable control envelope.
|
||||
|
||||
## Impact
|
||||
|
||||
This changes the immutable Protocol semantics consumed by the GPLv3 Data Plane and independent Verse clients. It adds no schema field, dependency, provider address, credential, generic acknowledgement framework, or provider-facing message.
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Bounded provider feedback control envelope
|
||||
The registered bidirectional reliable `control.ack.v1` flow SHALL define an ASCII `VGF1` envelope
|
||||
with a direction byte, type byte, big-endian payload length, and exact payload
|
||||
bytes. Only host termination, rumble, and HDR feedback SHALL be valid from the
|
||||
gateway to the client. Only IDR, FEC/loss feedback, and an empty terminal receipt
|
||||
SHALL be valid from the client to the gateway. The terminal receipt SHALL be
|
||||
valid only while the same session awaits receipt of its one terminal event and
|
||||
MUST NOT be forwarded to the provider. The envelope SHALL contain no provider
|
||||
address, certificate, credential, or opaque provider packet.
|
||||
|
||||
#### Scenario: Host termination forwarding
|
||||
- **WHEN** the Apollo adapter receives an authenticated host termination packet
|
||||
- **THEN** the gateway forwards a bounded `VGF1` termination envelope over reliable Verse control and reports the provider state separately
|
||||
|
||||
#### Scenario: Terminal event receipt
|
||||
- **WHEN** a client receives the reliable typed terminal event
|
||||
- **THEN** it sends the empty terminal receipt and the gateway owns bounded tunnel closure without forwarding the receipt to the provider
|
||||
|
||||
#### Scenario: Unauthorized or malformed feedback
|
||||
- **WHEN** feedback is disabled by policy, has an invalid direction/type/length, contains a forbidden provider field, or sends a terminal receipt outside the awaiting-terminal state
|
||||
- **THEN** the gateway rejects it without forwarding or provider mutation
|
||||
@@ -0,0 +1,9 @@
|
||||
## 1. Contract
|
||||
|
||||
- [x] 1.1 Define the empty client-direction terminal receipt on `control.ack.v1`
|
||||
- [x] 1.2 Run complete Protocol verification and deterministic generation checks
|
||||
|
||||
## 2. Immutable release
|
||||
|
||||
- [x] 2.1 Publish one new never-reused immutable Protocol version after final contract verification
|
||||
- [x] 2.2 Resolve the version from separate empty consumer caches and record exact checksums
|
||||
+2
-2
@@ -8,5 +8,5 @@
|
||||
## 2. Consumer Boundary
|
||||
|
||||
- [x] 2.1 Verify local Data Plane and Server consumers through a temporary workspace
|
||||
- [ ] 2.2 Publish one new never-reused immutable Protocol version under separate authorization
|
||||
- [ ] 2.3 Resolve from empty caches and pin exact checksums in both consumers
|
||||
- [x] 2.2 Publish one new never-reused immutable Protocol version under separate authorization
|
||||
- [x] 2.3 Resolve from empty caches and pin exact checksums in both consumers
|
||||
+2
-2
@@ -9,5 +9,5 @@
|
||||
## 2. Consumer Boundary
|
||||
|
||||
- [x] 2.1 Verify local Server and Data Plane consumers through a temporary workspace
|
||||
- [ ] 2.2 Publish one new never-reused immutable Protocol version under separate authorization
|
||||
- [ ] 2.3 Resolve from empty caches and pin exact checksums in both consumers
|
||||
- [x] 2.2 Publish one new never-reused immutable Protocol version under separate authorization
|
||||
- [x] 2.3 Resolve from empty caches and pin exact checksums in both consumers
|
||||
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-07-30
|
||||
@@ -0,0 +1,27 @@
|
||||
## Context
|
||||
|
||||
RC8's canonical requirement names a terminal receipt, but its frame grammar, fixed fixture, and all Protocol validators reject the exact receipt accepted by Data Plane. The existing VGF1 envelope and generated conformance machinery already cover the required boundary.
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
|
||||
- Make one fixed empty client-direction type `0x03` receipt valid in every Protocol validator.
|
||||
- Preserve all existing VGF1 direction, type, size, and payload validation.
|
||||
- Make independent clients able to construct the receipt from Protocol-owned evidence.
|
||||
|
||||
**Non-Goals:**
|
||||
|
||||
- No new envelope, feedback framework, transport, or acknowledgement protocol.
|
||||
- No change to gateway-to-client termination, rumble, HDR, client IDR, or FEC payloads.
|
||||
|
||||
## Decisions
|
||||
|
||||
- Extend the existing VGF1 grammar and fixed TSV corpus; generated and native validators remain consumers of that single contract.
|
||||
- Reserve type `0x03` only for client direction with a zero-length payload. Direction and exact-length checks remain prior trust-boundary requirements.
|
||||
- Publish the verified change as a new immutable version; RC8 remains unchanged.
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
- [A validator diverges from the fixed corpus] → Require normalized cross-language conformance in `make verify`.
|
||||
- [Receipt handling is accepted outside terminal state] → Keep state authorization in Data Plane; Protocol validates only the wire shape.
|
||||
@@ -0,0 +1,23 @@
|
||||
## Why
|
||||
|
||||
The canonical terminal-receipt requirement contradicts the fixed VGF1 grammar and every generated validator, so RC8 cannot provide an executable cross-language contract for gateway-owned terminal closure.
|
||||
|
||||
## What Changes
|
||||
|
||||
- Define client-direction VGF1 type `0x03` as an empty terminal receipt in the existing frame grammar.
|
||||
- Add fixed conformance vectors for valid receipt handling and invalid direction, body, truncation, length, and unknown-type cases.
|
||||
- Generate consistent Go, Rust, Swift, and Python validation behavior from the Protocol source.
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
None.
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
- `gateway-input-feedback`: Make the already-required terminal receipt executable and cross-language conformant without weakening other VGF1 validation.
|
||||
|
||||
## Impact
|
||||
|
||||
Protocol frame documentation, conformance fixtures, generators, generated bindings, native validator tools, and immutable Protocol consumers. RC8 remains unchanged and a new immutable Protocol version is required.
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Bounded provider feedback control envelope
|
||||
The registered bidirectional reliable `control.ack.v1` flow SHALL define an ASCII `VGF1` envelope
|
||||
with a direction byte, type byte, big-endian payload length, and exact payload
|
||||
bytes. Only host termination, rumble, and HDR feedback SHALL be valid from the
|
||||
gateway to the client. Only IDR, FEC/loss feedback, and client-direction type
|
||||
`0x03` with an empty payload as terminal receipt SHALL be valid from the client
|
||||
to the gateway. The fixed conformance corpus and every generated or native
|
||||
Protocol validator SHALL accept that exact receipt and reject unknown types,
|
||||
wrong direction, nonempty receipt bodies, truncation, and length mismatch. The
|
||||
terminal receipt SHALL be valid only while the same session awaits receipt of
|
||||
its one terminal event and MUST NOT be forwarded to the provider. The envelope
|
||||
SHALL contain no provider address, certificate, credential, or opaque provider
|
||||
packet.
|
||||
|
||||
#### Scenario: Host termination forwarding
|
||||
- **WHEN** the Apollo adapter receives an authenticated host termination packet
|
||||
- **THEN** the gateway forwards a bounded `VGF1` termination envelope over reliable Verse control and reports the provider state separately
|
||||
|
||||
#### Scenario: Terminal event receipt
|
||||
- **WHEN** a client receives the reliable typed terminal event
|
||||
- **THEN** it sends the fixed empty client-direction type `0x03` receipt and the gateway owns bounded tunnel closure without forwarding the receipt to the provider
|
||||
|
||||
#### Scenario: Unauthorized or malformed feedback
|
||||
- **WHEN** feedback is disabled by policy, has an invalid direction/type/length, contains a forbidden provider field, or sends a terminal receipt outside the awaiting-terminal state
|
||||
- **THEN** the gateway rejects it without forwarding or provider mutation
|
||||
@@ -0,0 +1,15 @@
|
||||
## 1. Red Conformance
|
||||
|
||||
- [x] 1.1 Add fixed valid and invalid terminal-receipt vectors and prove Python, Go, Rust, and Swift reject the required valid vector
|
||||
- [x] 1.2 Add a Data Plane independent-client regression that consumes the Protocol fixed vector rather than the production encoder
|
||||
|
||||
## 2. Contract Repair
|
||||
|
||||
- [x] 2.1 Update the VGF1 grammar and Protocol validator sources for the exact empty client-direction type `0x03` receipt
|
||||
- [x] 2.2 Regenerate bindings normally and prove deterministic generation has no drift
|
||||
- [x] 2.3 Run complete Protocol verification and strict OpenSpec validation
|
||||
|
||||
## 3. Immutable Release
|
||||
|
||||
- [ ] 3.1 Verify the next version is unused locally and remotely, publish one immutable annotated tag, and verify its object and peeled commit
|
||||
- [ ] 3.2 Resolve the version from separate empty caches and pin exact fetched checksums in Data Plane and Connection Server
|
||||
@@ -0,0 +1,25 @@
|
||||
# gateway-heartbeat-telemetry Specification
|
||||
|
||||
## Purpose
|
||||
Define the bounded, low-cardinality gateway observations carried by authenticated heartbeats and their canonical units and exclusions.
|
||||
## Requirements
|
||||
### Requirement: Heartbeat carries observed gateway telemetry
|
||||
Every authenticated `GatewayHeartbeat` SHALL carry the bounded process-level counters, delay totals and samples, control RTT/loss/jitter, pending reliable work, reconnect count, and provider state defined by `GatewayTelemetry`.
|
||||
|
||||
#### Scenario: Valid telemetry heartbeat
|
||||
- **WHEN** a gateway reports its current observed snapshot
|
||||
- **THEN** Go, Rust, and Swift bindings accept the same bounded low-cardinality values and units
|
||||
|
||||
### Requirement: Heartbeat telemetry excludes sensitive dimensions
|
||||
Heartbeat telemetry MUST reject unknown fields and MUST NOT include session, route, endpoint, credential, label, or payload values.
|
||||
|
||||
#### Scenario: Secret or high-cardinality field is attempted
|
||||
- **WHEN** a heartbeat contains an unregistered session, route, endpoint, credential, or payload field
|
||||
- **THEN** strict contract validation rejects it before authenticated transport
|
||||
|
||||
### Requirement: Delay and egress observations have one canonical meaning
|
||||
Queue delay SHALL measure provider-queue residence, processing delay SHALL measure active gateway recovery/framing/QUIC work excluding queue and pacing, and pacing delay SHALL measure scheduler waiting only. Processing samples SHALL count complete provider media units rather than Verse fragments. Measured egress SHALL derive from transmitted-byte deltas over monotonic elapsed time and MUST NOT be copied from configured capacity.
|
||||
|
||||
#### Scenario: One provider unit becomes multiple Verse frames
|
||||
- **WHEN** one complete provider unit waits in the queue, traverses gateway processing, waits for pacing, and fragments into multiple Verse frames
|
||||
- **THEN** each delay total includes only its defined interval and the heartbeat advances processing samples exactly once
|
||||
@@ -40,20 +40,23 @@ an implementation-specific release-all provider command.
|
||||
The registered bidirectional reliable `control.ack.v1` flow SHALL define an ASCII `VGF1` envelope
|
||||
with a direction byte, type byte, big-endian payload length, and exact payload
|
||||
bytes. Only host termination, rumble, and HDR feedback SHALL be valid from the
|
||||
gateway to the client; only IDR and FEC/loss feedback SHALL be valid from the
|
||||
client to the gateway. The envelope SHALL contain no provider address,
|
||||
certificate, credential, or opaque provider packet.
|
||||
gateway to the client. Only IDR, FEC/loss feedback, and an empty terminal receipt
|
||||
SHALL be valid from the client to the gateway. The terminal receipt SHALL be
|
||||
valid only while the same session awaits receipt of its one terminal event and
|
||||
MUST NOT be forwarded to the provider. The envelope SHALL contain no provider
|
||||
address, certificate, credential, or opaque provider packet.
|
||||
|
||||
#### Scenario: Host termination forwarding
|
||||
- **WHEN** the Apollo adapter receives an authenticated host termination
|
||||
packet
|
||||
- **THEN** the gateway forwards a bounded `VGF1` termination envelope over
|
||||
reliable Verse control and reports the provider state separately.
|
||||
- **WHEN** the Apollo adapter receives an authenticated host termination packet
|
||||
- **THEN** the gateway forwards a bounded `VGF1` termination envelope over reliable Verse control and reports the provider state separately
|
||||
|
||||
#### Scenario: Terminal event receipt
|
||||
- **WHEN** a client receives the reliable typed terminal event
|
||||
- **THEN** it sends the empty terminal receipt and the gateway owns bounded tunnel closure without forwarding the receipt to the provider
|
||||
|
||||
#### Scenario: Unauthorized or malformed feedback
|
||||
- **WHEN** feedback is disabled by policy, has an invalid direction/type/length,
|
||||
or contains a forbidden provider field
|
||||
- **THEN** the gateway rejects it without forwarding or provider mutation.
|
||||
- **WHEN** feedback is disabled by policy, has an invalid direction/type/length, contains a forbidden provider field, or sends a terminal receipt outside the awaiting-terminal state
|
||||
- **THEN** the gateway rejects it without forwarding or provider mutation
|
||||
|
||||
### Requirement: Policy-bound text clipboard envelope
|
||||
The reliable `clipboard.text.v1` flow SHALL carry only a typed UTF-8 text
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
# provider-stream-policy Specification
|
||||
|
||||
## Purpose
|
||||
Define immutable provider stream-policy fields and the registered ordered decode-profile intersection shared by all generated bindings.
|
||||
## Requirements
|
||||
### Requirement: Provider work carries the effective stream policy
|
||||
Authenticated `ProviderSessionWork` SHALL carry the immutable policy version and its effective resolution, frame rate, codec, target bitrate, and audio-enabled decision.
|
||||
|
||||
#### Scenario: Gateway receives an effective policy
|
||||
- **WHEN** the Server issues provider work for an admitted session
|
||||
- **THEN** the work identifies the policy version and includes the effective bounded stream-policy values
|
||||
|
||||
### Requirement: Stream-policy bindings share one strict contract
|
||||
Generated Go, Rust, and Swift bindings MUST reject missing, unknown, out-of-range, or unsupported stream-policy wire values according to the canonical schema.
|
||||
|
||||
#### Scenario: Invalid policy is rejected consistently
|
||||
- **WHEN** provider work contains an unknown codec or a value outside the canonical bounds
|
||||
- **THEN** every generated binding rejects the work before it can reach provider setup
|
||||
|
||||
### Requirement: Decode capabilities use registered ordered profiles
|
||||
`CapabilityProfile.client_decode` SHALL be a non-empty ordered unique set containing only registered `h264-opus` and `hevc-opus` profile identifiers. It MUST NOT encode multiple capabilities in an opaque private token.
|
||||
|
||||
#### Scenario: Independent peer advertises one registered profile
|
||||
- **WHEN** an independent peer advertises one registered decode profile
|
||||
- **THEN** canonical validation accepts that profile without requiring a combined private token
|
||||
|
||||
### Requirement: Consumers share one ordered registered-profile intersection
|
||||
Generated Protocol behavior SHALL select common registered profiles in the first peer's preference order. Provider consumers SHALL separately reject the resulting intersection when it cannot honor the immutable stream policy.
|
||||
|
||||
#### Scenario: Policy-compatible profile overlaps
|
||||
- **WHEN** the gateway advertises HEVC then H.264 and the client advertises only H.264
|
||||
- **THEN** the shared intersection selects `h264-opus`
|
||||
|
||||
#### Scenario: No policy-compatible profile overlaps
|
||||
- **WHEN** peers have no registered common profile
|
||||
- **THEN** the shared intersection rejects admission without inventing a private combined token
|
||||
@@ -270,12 +270,16 @@ func classifyGatewayFeedback(encoded string) string {
|
||||
return "valid"
|
||||
}
|
||||
return "invalid:field"
|
||||
case 3:
|
||||
if len(body) == 0 {
|
||||
return "valid"
|
||||
}
|
||||
default:
|
||||
return "invalid:type"
|
||||
}
|
||||
return "invalid:length"
|
||||
}
|
||||
if kind == 1 || kind == 2 {
|
||||
if kind == 1 || kind == 2 || kind == 3 {
|
||||
return "invalid:direction"
|
||||
}
|
||||
switch kind {
|
||||
|
||||
@@ -143,10 +143,12 @@ fn classify_gateway_feedback(encoded: &str) -> &'static str {
|
||||
1 => "invalid:length",
|
||||
2 if valid_fec_status(body) => "valid",
|
||||
2 => "invalid:field",
|
||||
3 if body.is_empty() => "valid",
|
||||
3 => "invalid:length",
|
||||
_ => "invalid:type",
|
||||
};
|
||||
}
|
||||
if kind == 1 || kind == 2 {
|
||||
if kind == 1 || kind == 2 || kind == 3 {
|
||||
return "invalid:direction";
|
||||
}
|
||||
match kind {
|
||||
|
||||
@@ -101,10 +101,11 @@ func classifyGatewayFeedback(_ encoded: String) -> String {
|
||||
case 1: return body.isEmpty ? "valid" : "invalid:length"
|
||||
case 2:
|
||||
return validFECStatus(body) ? "valid" : "invalid:field"
|
||||
case 3: return body.isEmpty ? "valid" : "invalid:length"
|
||||
default: return "invalid:type"
|
||||
}
|
||||
}
|
||||
if kind == 1 || kind == 2 { return "invalid:direction" }
|
||||
if kind == 1 || kind == 2 || kind == 3 { return "invalid:direction" }
|
||||
switch kind {
|
||||
case 0x10: return body.count == 4 ? "valid" : "invalid:length"
|
||||
case 0x11:
|
||||
|
||||
@@ -59,8 +59,10 @@ def classify_feedback(raw: bytes) -> str:
|
||||
return "valid" if not body else "invalid:length"
|
||||
if kind == 2:
|
||||
return "valid" if valid_fec_status(body) else "invalid:field"
|
||||
if kind == 3:
|
||||
return "valid" if not body else "invalid:length"
|
||||
return "invalid:type"
|
||||
if kind in (1, 2):
|
||||
if kind in (1, 2, 3):
|
||||
return "invalid:direction"
|
||||
if kind == 0x10:
|
||||
return "valid" if len(body) == 4 else "invalid:length"
|
||||
|
||||
Reference in New Issue
Block a user