oficina / meet Public

Clone
git clone https://amadan.net/oficina/meet

Plain git — no account needed to clone.

Download

Download this file

1package protocol
2
3// Quality and problem reports (spec §15.26, 2026-10-03): the wire shape a
4// client POSTs, client-neutral like the rest of this package.
5//
6// A quality report is a fixed schema of numbers and enums about how this
7// client's connections went over the last window: no names, no addresses,
8// no device names, no meeting, nothing typed by a person. Every number is
9// optional (absent means "this client could not measure it"), finite and
10// non-negative, and has a ceiling the server enforces; every string is an
11// enum or a version. Counts are what happened during the window (a delta),
12// not running totals. The server re-encodes what it validated and drops
13// anything it does not know, so a member a newer client adds is tolerated
14// and never logged.
15
16// QualityVersion is the schema's version, the report's "v".
17const QualityVersion = 1
18
19// Bounds the server enforces, here so a client can clamp to the same ones.
20const (
21 MaxQualityPeers = 4 // remote peers in one report: the mesh holds three, and one spare for a connection on its way out
22 MaxQualitySeconds = 600 // a window, in seconds
23 MaxQualityMillis = 600_000 // any rtt, jitter or buffer delay, in ms
24 MaxQualityCount = 1e9 // any count of packets, frames or samples
25 MaxQualityKbps = 1e6 // any bitrate, in kbit/s
26 MaxQualityPixels = 16384 // a frame's width or height
27 MaxQualityFPS = 240 // frames per second
28 MaxQualityBody = 16 << 10
29 MaxProblemNote = 1000 // characters of "What went wrong?"
30 MaxProblemBody = 64 << 10 // the whole problem report, diagnostics included
31)
32
33// QualityReport is one window's summary.
34type QualityReport struct {
35 V int `json:"v"`
36 Final bool `json:"final,omitempty"` // the report sent at leave or end
37 Seconds *float64 `json:"seconds"` // how long the window was
38 Client ReportClient `json:"client"`
39 Devices *Devices `json:"devices,omitempty"`
40 Events *CallEvents `json:"events,omitempty"`
41 Peers []PeerQuality `json:"peers,omitempty"`
42}
43
44// ReportClient says what is reporting. Enums, and versions as digits and
45// dots: never a user agent string, a device model or a machine name.
46type ReportClient struct {
47 App string `json:"app"` // web, mac, iphone, ipad
48 Version string `json:"version,omitempty"` // the app's version, or the server's build for web
49 Browser string `json:"browser,omitempty"` // chrome, safari, firefox, edge, other (web only)
50 BrowserVersion string `json:"browserVersion,omitempty"` // major[.minor]
51 OS string `json:"os,omitempty"` // macos, ios, ipados, windows, linux, android, chromeos, other
52 OSVersion string `json:"osVersion,omitempty"`
53}
54
55// Devices are the kinds of microphone and speaker in use, by transport:
56// never a device's name, which can be personal ("Paul's AirPods Pro").
57type Devices struct {
58 Input string `json:"input,omitempty"` // DeviceKinds
59 Output string `json:"output,omitempty"` // DeviceKinds
60}
61
62// DeviceKinds are the values Devices may carry.
63var DeviceKinds = []string{"built-in", "bluetooth", "usb", "wired", "airplay", "virtual", "continuity", "other", "none", "unknown"}
64
65// CallEvents are the notices this client showed for the whole call during
66// the window (§15.23), and whether its browser blocked playing sound
67// (§15.20).
68type CallEvents struct {
69 Reconnecting *float64 `json:"reconnecting,omitempty"` // times "Reconnecting…" was shown
70 ReconnectingSeconds *float64 `json:"reconnectingSeconds,omitempty"` // for how long
71 AudioBlocked bool `json:"audioBlocked,omitempty"`
72}
73
74// PeerQuality is one remote peer's connection, from this side.
75type PeerQuality struct {
76 // Peer is the remote peer's id as this client knows it. The server
77 // logs the peer's tag in its place and never the id.
78 Peer PeerID `json:"peer"`
79 Path *Path `json:"path,omitempty"`
80 RTT *float64 `json:"rtt,omitempty"` // the selected candidate pair's, ms
81 Out *Outbound `json:"out,omitempty"`
82 In *Inbound `json:"in,omitempty"`
83 Events *PeerEvents `json:"events,omitempty"`
84}
85
86// Path is the selected candidate pair: what kind of candidate each end
87// used, and the transport. Never an address or a port.
88type Path struct {
89 Local string `json:"local,omitempty"` // CandidateKinds
90 Remote string `json:"remote,omitempty"` // CandidateKinds
91 Protocol string `json:"protocol,omitempty"` // udp, tcp, tls, unknown
92}
93
94// CandidateKinds are the values Path.Local and Path.Remote may carry.
95var CandidateKinds = []string{"host", "srflx", "prflx", "relay", "unknown"}
96
97// PathProtocols are the values Path.Protocol may carry. "tls" is a relay
98// reached over TURN/TLS.
99var PathProtocols = []string{"udp", "tcp", "tls", "unknown"}
100
101// Outbound is what this client sends to the peer.
102type Outbound struct {
103 Audio *OutStream `json:"audio,omitempty"`
104 Video *OutStream `json:"video,omitempty"`
105 Screen *OutStream `json:"screen,omitempty"`
106}
107
108// OutStream is one outbound stream. Lost, RTT and Jitter are the
109// receiver's own account (remote-inbound-rtp).
110type OutStream struct {
111 Kbps *float64 `json:"kbps,omitempty"`
112 Packets *float64 `json:"packets,omitempty"`
113 Lost *float64 `json:"lost,omitempty"`
114 RTT *float64 `json:"rtt,omitempty"`
115 Jitter *float64 `json:"jitter,omitempty"`
116 Limit string `json:"limit,omitempty"` // QualityLimits
117 Width *float64 `json:"width,omitempty"`
118 Height *float64 `json:"height,omitempty"`
119 FPS *float64 `json:"fps,omitempty"`
120 // The screen-share recovery ladder's steps toward this peer during
121 // the window (§15.22): keyframes sent, rebuilds, shares again, and
122 // times it gave up.
123 Keyframes *float64 `json:"keyframes,omitempty"`
124 Rebuilds *float64 `json:"rebuilds,omitempty"`
125 Reshares *float64 `json:"reshares,omitempty"`
126 Failures *float64 `json:"failures,omitempty"`
127}
128
129// QualityLimits are qualityLimitationReason's values.
130var QualityLimits = []string{"none", "cpu", "bandwidth", "other"}
131
132// Inbound is what arrives from the peer.
133type Inbound struct {
134 Audio *InAudio `json:"audio,omitempty"`
135 Video *InVideo `json:"video,omitempty"`
136 Screen *InVideo `json:"screen,omitempty"`
137}
138
139// InAudio is the peer's audio as it arrives here.
140type InAudio struct {
141 Kbps *float64 `json:"kbps,omitempty"`
142 Packets *float64 `json:"packets,omitempty"`
143 Lost *float64 `json:"lost,omitempty"`
144 Jitter *float64 `json:"jitter,omitempty"` // ms
145 Samples *float64 `json:"samples,omitempty"` // totalSamplesReceived
146 Concealed *float64 `json:"concealed,omitempty"` // concealedSamples
147 Inserted *float64 `json:"inserted,omitempty"` // insertedSamplesForDeceleration
148 Removed *float64 `json:"removed,omitempty"` // removedSamplesForAcceleration
149 JitterBufferMs *float64 `json:"jitterBufferMs,omitempty"` // mean jitterBufferDelay per emitted sample over the window
150}
151
152// InVideo is the peer's camera or screen as it arrives here.
153type InVideo struct {
154 Kbps *float64 `json:"kbps,omitempty"`
155 Packets *float64 `json:"packets,omitempty"`
156 Lost *float64 `json:"lost,omitempty"`
157 Jitter *float64 `json:"jitter,omitempty"`
158 Freezes *float64 `json:"freezes,omitempty"` // freezeCount
159 FreezeSeconds *float64 `json:"freezeSeconds,omitempty"` // totalFreezesDuration
160 Decoded *float64 `json:"decoded,omitempty"`
161 Dropped *float64 `json:"dropped,omitempty"`
162 Width *float64 `json:"width,omitempty"`
163 Height *float64 `json:"height,omitempty"`
164 FPS *float64 `json:"fps,omitempty"`
165 Reattaches *float64 `json:"reattaches,omitempty"` // a stalled screen handed to its view again (§15.22)
166}
167
168// PeerEvents are the notices about this peer during the window.
169type PeerEvents struct {
170 Reconnecting *float64 `json:"reconnecting,omitempty"` // "Reconnecting to …" shown
171 ReconnectingSeconds *float64 `json:"reconnectingSeconds,omitempty"` // for how long
172 CantHearSeconds *float64 `json:"cantHearSeconds,omitempty"` // "… can't hear you yet" (§15.24)
173 NoSound bool `json:"noSound,omitempty"` // this client listed them in noSoundFrom (§15.20)
174 NoSoundFromUs bool `json:"noSoundFromUs,omitempty"` // they listed this client
175 AudioBlocked bool `json:"audioBlocked,omitempty"` // they said their browser blocked sound
176 ScreenStalled bool `json:"screenStalled,omitempty"` // this client reported their screen stalled (§15.21)
177}
178
179// ProblemReport is "Report a problem": what the person typed, and the
180// text "Copy call diagnostics" would copy, with the people in the call
181// named by short peer ids rather than their names.
182type ProblemReport struct {
183 Note string `json:"note"`
184 Diagnostics string `json:"diagnostics"`
185 Client ReportClient `json:"client"`
186}
187
188// ProblemReceipt is the server's answer: the reference to quote.
189type ProblemReceipt struct {
190 Ref string `json:"ref"`
191}
192