Missed / timed-out call flow¶
Signalling - flow-call-missed
SIG-12 - status: draft - audio, video
Stanza sequence for a 1:1 call offered but never answered: offer, per-device offer-receipt, no preaccept/accept, then a timeout-driven terminate.
Opens like any 1:1 call (see flow-incoming-1to1, call-offer) but never reaches accept.
-
Offer. Caller sends
<call to="{callee}" id="{stanza-id}">wrapping<offer call-id call-creator>(see call-offer). Server<ack>s and fans out to each callee device. -
Offer-receipt (per device). Each callee device receiving the offer MUST send a
<receipt>in addition to the transport<ack>: -
idMUST equal the inbound<call>stanzaid(NOTcall-id). from, when present, MUST be the acknowledging device's own addressable JID: its LID if the offer arrived addressed to a LID, otherwise its PN.-
This is NOT an accept and MUST NOT be treated as one.
-
No answer. No callee device sends
<preaccept>(see call-preaccept) or<accept>(see call-accept). Call stays ringing for the offer/ring timeout window. -
Terminate. On ring timeout with no answer, the call MUST be ended with a
<terminate>inside the<call>wrapper (see call-terminate):[ ]... -
<terminate>MUST carry the samecall-id/call-creatoras the offer. - When targeting a peer's other ringing devices, it MAY carry a single
<destination>enumerating them with one<to jid="..."/>per device; otherwise<destination>MUST be omitted. reason, when unspecified, MUST be omitted entirely (never sent empty).
A <terminate> for an unanswered call MAY carry duration/audio_duration
counters; expected zero/absent for a missed call. A receiver MUST treat their
absence as "not reported", not infer a value.
A receiver that does not recognize a <call> action child MUST ignore the
stanza rather than error.
Requires: call-offer, call-accept, call-preaccept, call-terminate, flow-incoming-1to1
Implemented by
| Flavor | Status | Source | Notes |
|---|---|---|---|
whatsapp-rust |
working | history - blame - commits d68af6c |
Parses inbound |
zapo-caller |
working | — | Signalling builders (offer/accept/terminate) ported from this flavor's signaling.ts. |
Annotation wacrg:SIG-12 — a flavor marks its implementation site in source with this comment; a script clones the source, finds it, and attaches the commit blame/permalink.
Contributors
| Contributor | Role |
|---|---|
| wrote initial spec |
protocol history / diff - blame
Open questions - The ring/offer timeout duration and which side (caller, callee, or server) drives the terminate when a call goes unanswered. - Whether a distinct reason value (e.g. a 'timeout'/'no_answer' code) marks a missed-call terminate, or whether the reason is simply omitted; the source only confirms accepted_elsewhere. - Whether the server emits its own terminate/notification for a timed-out call independent of the caller's terminate, and how a missed call is recorded in chat history. - Exact values of duration/audio_duration on a missed-call terminate (expected zero/absent but not confirmed from source).
References - wacore voip signaling builders (build_offer, build_terminate) - wacore call stanza parser and build_offer_ack_receipt
Changelog¶
- 2026-06-21 — Initial spec entry.