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

233 lines
6.7 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;
}
// Stable protocol-level categories for devices managed by cmvr-es. These
// values intentionally do not reuse the configuration or gRPC API enums:
// their zero values and supported categories have different semantics.
enum DeviceKind {
DEVICE_KIND_UNSPECIFIED = 0;
DEVICE_KIND_AGV = 1;
DEVICE_KIND_ARM = 2;
DEVICE_KIND_BATTERY = 3;
DEVICE_KIND_BIO_HEAD = 4;
DEVICE_KIND_CAMERA = 5;
DEVICE_KIND_CAN_BUS = 6;
DEVICE_KIND_DEX_HAND = 7;
DEVICE_KIND_GRIPPER = 8;
DEVICE_KIND_MICROPHONE = 9;
DEVICE_KIND_MOTOR = 10;
DEVICE_KIND_MOTOR_SYSTEM = 11;
DEVICE_KIND_ROBOT = 12;
DEVICE_KIND_SPEAKER = 13;
}
// DeviceManager's view of a configured entry. REGISTERED means that the
// manager owns a device record but has no more specific lifecycle signal.
enum ManagedDeviceState {
MANAGED_DEVICE_STATE_UNSPECIFIED = 0;
MANAGED_DEVICE_STATE_DISABLED = 1;
MANAGED_DEVICE_STATE_INITIALIZING = 2;
MANAGED_DEVICE_STATE_REGISTERED = 3;
MANAGED_DEVICE_STATE_READY = 4;
MANAGED_DEVICE_STATE_RUNNING = 5;
MANAGED_DEVICE_STATE_STOPPED = 6;
MANAGED_DEVICE_STATE_ERROR = 7;
}
// Health is independent of lifecycle. UNSPECIFIED means that no trustworthy
// health observation is available and must never be interpreted as healthy.
enum DeviceHealthStatus {
DEVICE_HEALTH_STATUS_UNSPECIFIED = 0;
DEVICE_HEALTH_STATUS_HEALTHY = 1;
DEVICE_HEALTH_STATUS_DEGRADED = 2;
DEVICE_HEALTH_STATUS_FAULT = 3;
}
message ManagedDeviceStatus {
string device_id = 1;
DeviceKind kind = 2;
// Concrete implementation name when a device object exists; otherwise a
// category label. It is for display/diagnostics only. Consumers use kind,
// rather than this free-form string, for machine decisions.
string type_name = 3;
bool enabled = 4;
ManagedDeviceState manager_state = 5;
DeviceHealthStatus health = 6;
// false means that no error is currently confirmed. It does not turn
// DEVICE_HEALTH_STATUS_UNSPECIFIED into a healthy observation.
bool has_error = 7;
string error_message = 8;
// Time at which DeviceManager last changed the lifecycle/error record.
// DeviceManagerSnapshot.sampled_at_unix_ms is the freshness timestamp for
// the health observation carried by this heartbeat.
uint64 status_updated_at_unix_ms = 9;
}
message DeviceManagerSnapshot {
string manager_name = 1;
string manager_version = 2;
string manager_description = 3;
// Current cmvr-es senders include only enabled devices. The enabled field in
// each row and DISABLED enum value remain part of v1 for wire compatibility.
repeated ManagedDeviceStatus devices = 4;
uint64 sampled_at_unix_ms = 5;
}
message NodeDescriptor {
string node_id = 1;
string boot_id = 2;
string software_version = 3;
repeated NetworkInterfaceAddress local_interfaces = 4;
GrpcEndpoint grpc_endpoint = 5;
string robot_id = 6;
}
// 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;
DeviceManagerSnapshot device_manager = 9;
string robot_id = 10;
}
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;
}