cmvr-es/protos/cmvr/quic_edge/v1/quic_edge.proto

153 lines
4.1 KiB
Protocol Buffer
Raw Normal View History

syntax = "proto3";
package cmvr.quic_edge.v1;
// Every application message on the edge-opened reliable bidirectional stream
// is carried by this envelope. message_sequence is strictly increasing per
// sender (gaps are allowed) and is independent from the heartbeat sequence used
// for liveness acknowledgement.
message EdgeControlEnvelope {
uint32 protocol_version = 1;
uint64 message_sequence = 2;
oneof payload {
NodeRegisterRequest node_register_request = 10;
NodeRegisterResponse node_register_response = 11;
NodeHeartbeat node_heartbeat = 12;
NodeHeartbeatAck node_heartbeat_ack = 13;
MediaSessionOpen media_session_open = 20;
MediaTrackDescriptor media_track_descriptor = 21;
MediaSessionClose media_session_close = 22;
ProtocolError protocol_error = 30;
}
}
message NetworkInterfaceAddress {
enum AddressFamily {
ADDRESS_FAMILY_UNSPECIFIED = 0;
ADDRESS_FAMILY_IPV4 = 1;
ADDRESS_FAMILY_IPV6 = 2;
}
string interface_name = 1;
string ip_address = 2;
AddressFamily family = 3;
bool loopback = 4;
}
// The existing cmvr-es gRPC server remains the robot-control endpoint. The
// edge advertises its current reachable address through the QUIC control plane.
message GrpcEndpoint {
string host = 1;
uint32 port = 2;
bool tls = 3;
}
message NodeDescriptor {
string node_id = 1;
string boot_id = 2;
string software_version = 3;
repeated NetworkInterfaceAddress local_interfaces = 4;
GrpcEndpoint grpc_endpoint = 5;
}
// This must be the first application message sent after each QUIC connection
// is established. A reconnect always creates a new registration session.
message NodeRegisterRequest {
NodeDescriptor node = 1;
uint64 sent_at_unix_ms = 2;
}
message NodeRegisterResponse {
bool accepted = 1;
string session_id = 2;
string message = 3;
// Zero tells the edge to keep its locally configured interval.
uint32 heartbeat_interval_ms = 4;
// Derived by the receiver from the authenticated QUIC peer address. It is
// not copied from a client-supplied local interface.
string observed_source_ip = 5;
}
// A heartbeat carries a fresh network snapshot so address changes are reported
// without opening a second protocol or connection.
message NodeHeartbeat {
string node_id = 1;
string boot_id = 2;
string session_id = 3;
uint64 sequence = 4;
uint64 sent_at_unix_ms = 5;
string software_version = 6;
repeated NetworkInterfaceAddress local_interfaces = 7;
GrpcEndpoint grpc_endpoint = 8;
}
message NodeHeartbeatAck {
bool accepted = 1;
uint64 acknowledged_sequence = 2;
string message = 3;
uint64 server_time_unix_ms = 4;
string observed_source_ip = 5;
string session_id = 6;
}
message MediaSessionOpen {
string node_id = 1;
uint64 session_epoch = 2;
// Binds the media epoch to the accepted node registration on this QUIC
// connection. Media must not start before this session is assigned.
string session_id = 3;
}
enum MediaKind {
MEDIA_KIND_UNSPECIFIED = 0;
MEDIA_KIND_VIDEO = 1;
MEDIA_KIND_AUDIO = 2;
}
message MediaTrackDescriptor {
uint32 track_id = 1;
MediaKind kind = 2;
string device_id = 3;
string codec = 4;
uint64 codec_generation = 5;
// The exact MediaSourceHub track and the 32-bit token repeated in every
// DATAGRAM header. The full generation remains on the reliable stream.
string source_track_id = 6;
uint32 codec_generation_token = 7;
string payload_format = 8;
// Video fields. They are zero for audio tracks.
uint32 width = 10;
uint32 height = 11;
uint32 frames_per_second = 12;
// Audio fields. They are zero for video tracks.
uint32 sample_rate = 20;
uint32 channels = 21;
// Decoder initialization bytes, for example AVCC/HVCC or AudioSpecificConfig.
// Existing cmvr-es sources may leave this empty when configuration NAL units
// are carried in-band.
bytes codec_config = 30;
}
message MediaSessionClose {
string reason = 1;
string session_id = 2;
uint64 session_epoch = 3;
}
message ProtocolError {
uint32 code = 1;
string message = 2;
uint64 related_message_sequence = 3;
bool fatal = 4;
}