/* * protocol/protocol.h — control-plane (de)serialization + routing. * * Design: docs/protocol.md. Wire format is a length-prefixed protobuf `Envelope` * (core/proto/voicecat.proto). This layer parses frames into Envelopes, correlates * request_id ↔ response, and dispatches to handlers. Media frames do NOT come through here * (they use the fixed binary header in voice.md §2). * * STATUS: real. Protobuf codegen is on (core/CMakeLists.txt) for VOICECAT_HAS_NET builds * (`m1-dev`/`server-release`); FrameCodec below is fully implemented and used by both the * client (net/transport.h) and the server (conn_session.cpp). See protocol/envelope.h for the * Envelope-level encode/decode that sits on top of this. */ #ifndef VOICECAT_PROTOCOL_PROTOCOL_H #define VOICECAT_PROTOCOL_PROTOCOL_H #include #include #include namespace voicecat::protocol { constexpr uint32_t kProtocolVersion = 1; constexpr uint32_t kMaxFrameBytes = 16u * 1024 * 1024; // docs/protocol.md §1 guard constexpr size_t kLengthHeaderSize = 4; // big-endian u32 prefix // Reads/writes [u32 big-endian length][payload] frames from a byte stream. class FrameCodec { public: // Append received bytes; pop complete frame payloads into out_frames. // Returns false on protocol error (oversized frame or framing violation). bool feed(const uint8_t* data, size_t len, std::vector>& out_frames); // Serialize a frame into out: [big-endian u32 length][payload bytes]. static void emit(const uint8_t* payload, size_t len, std::vector& out); static void emit(const std::vector& payload, std::vector& out); // Number of bytes buffered but not yet forming a complete frame. size_t pending_bytes() const { return buf_.size(); } void reset() { buf_.clear(); } private: std::vector buf_; }; } // namespace voicecat::protocol #endif // VOICECAT_PROTOCOL_PROTOCOL_H