Files
Christian Nennemann 2e081ead8e chore: rename quicproquo → quicprochat in docs, Docker, CI, and packaging
Rename all project references from quicproquo/qpq to quicprochat/qpc
across documentation, Docker configuration, CI workflows, packaging
scripts, operational configs, and build tooling.

- Docker: crate paths, binary names, user/group, data dirs, env vars
- CI: workflow crate references, binary names, artifact names
- Docs: all markdown files under docs/, SDK READMEs, book.toml
- Packaging: OpenWrt Makefile, init script, UCI config (file renames)
- Scripts: justfile, dev-shell, screenshot, cross-compile, ai_team
- Operations: Prometheus config, alert rules, Grafana dashboard
- Config: .env.example (QPQ_* → QPC_*), CODEOWNERS paths
- Top-level: README, CONTRIBUTING, ROADMAP, CLAUDE.md
2026-03-21 19:14:06 +01:00

74 lines
1.7 KiB
Python

"""v2 wire format: ``[method_id:u16][req_id:u32][len:u32][protobuf]``.
Each RPC is sent over its own QUIC stream. The response uses the same
framing on the same stream.
"""
from __future__ import annotations
import struct
# Header: method_id (u16) + req_id (u32) + length (u32) = 10 bytes.
HEADER_FMT = "!HII" # network byte-order: u16 + u32 + u32
HEADER_SIZE = struct.calcsize(HEADER_FMT)
# Method IDs (mirrors quicprochat-proto/src/lib.rs::method_ids).
# Auth (100-103)
OPAQUE_REGISTER_START = 100
OPAQUE_REGISTER_FINISH = 101
OPAQUE_LOGIN_START = 102
OPAQUE_LOGIN_FINISH = 103
# Delivery (200-205)
ENQUEUE = 200
FETCH = 201
FETCH_WAIT = 202
PEEK = 203
ACK = 204
BATCH_ENQUEUE = 205
# Keys (300-304)
UPLOAD_KEY_PACKAGE = 300
FETCH_KEY_PACKAGE = 301
UPLOAD_HYBRID_KEY = 302
FETCH_HYBRID_KEY = 303
FETCH_HYBRID_KEYS = 304
# Channel (400)
CREATE_CHANNEL = 400
# User (500-501)
RESOLVE_USER = 500
RESOLVE_IDENTITY = 501
# Blob (600-601)
UPLOAD_BLOB = 600
DOWNLOAD_BLOB = 601
# Device (700-702)
REGISTER_DEVICE = 700
LIST_DEVICES = 701
REVOKE_DEVICE = 702
# P2P (800-802)
PUBLISH_ENDPOINT = 800
RESOLVE_ENDPOINT = 801
HEALTH = 802
# Delete account (950)
DELETE_ACCOUNT = 950
def encode_frame(method_id: int, req_id: int, payload: bytes) -> bytes:
"""Encode a wire frame: header + protobuf payload."""
header = struct.pack(HEADER_FMT, method_id, req_id, len(payload))
return header + payload
def decode_header(data: bytes) -> tuple[int, int, int]:
"""Decode a wire frame header, returning (method_id, req_id, payload_len)."""
if len(data) < HEADER_SIZE:
raise ValueError(f"header too short: {len(data)} < {HEADER_SIZE}")
method_id, req_id, length = struct.unpack(HEADER_FMT, data[:HEADER_SIZE])
return method_id, req_id, length