d65ab7b616
Phase 3c-2 of the Clubhouse/nests integration. Extends the MoQ
control-plane codec with the subscribe lifecycle messages (SUBSCRIBE,
SUBSCRIBE_OK, SUBSCRIBE_ERROR, UNSUBSCRIBE) and adds the
OBJECT_DATAGRAM wire format the listener uses to receive low-latency
Opus audio. Pure codec layer — no session-pump or network changes;
the subscribe/object delivery Flow arrives in Phase 3c-3.
commonMain (nestsclient.moq):
- New message types in `MoqMessageType`: Subscribe (0x03),
SubscribeOk (0x04), SubscribeError (0x05), Unsubscribe (0x0A).
- New data classes in MoqMessage.kt:
* `TrackNamespace` — tuple of byte strings, with `of(vararg String)`
helper for the common UTF-8 case.
* `SubscribeFilter` enum. Phase 3c-2 supports LatestGroup /
LatestObject; AbsoluteStart/AbsoluteRange throw at construction
(they need extra wire fields we'll add when nests needs them).
* `Subscribe`, `SubscribeOk`, `SubscribeError`, `Unsubscribe` data
classes. `SubscribeOk` validates contentExists + largest-id
coupling at construction.
- New codecs in `MoqCodec` (namespace tuple + all four messages).
Unknown filter codes on the wire are rejected.
- `MoqObject` data class + `MoqObjectDatagram` encode/decode for the
OBJECT_DATAGRAM wire format (track_alias, group_id, object_id,
publisher_priority, status, payload).
Tests:
- `SubscribeCodecTest` — round-trips for each message with multi-
segment namespaces + parameters, SUBSCRIBE_OK with and without
contentExists, concatenated decode in sequence, unknown-filter
rejection, construction-time validation.
- `MoqObjectDatagramTest` — Opus-sized payload round-trip, zero-
length payload with OBJECT_DOES_NOT_EXIST status, 8-byte-varint
boundary coverage, truncated datagram rejection, out-of-range
priority rejection.
https://claude.ai/code/session_013nVLALALKaHVgHm9u5Cg8D