Turns inbound <call> stanzas into call-log records and live call events.
WhatsApp delivers call signalling as a <call> stanza with one child naming
the phase: offer/offer_notice (ringing), accept (a device answered),
terminate (ended, with a reason attribute), or reject. Each phase is
merged into the persistent call log (ExWapp.Call) and forwarded to the
session worker as {:call_event, %ExWapp.Call{}} so subscribers can react
in real time. VoIP negotiation children (preaccept, transport,
relaylatency, ...) carry no log-worthy information and are skipped.
Outcome semantics for terminate:
- a call with a known accept (or a positive
durationattribute) ends:connected - an unanswered outgoing call ends
:cancelled - any other unanswered call ends
:missed— WhatsApp usesreason="timeout"for a ring-out, but a caller hang-up is still a missed call for the callee
The raw terminate reason is preserved in end_reason. Duration comes from
the stanza's duration attribute when present, otherwise from the delta
between the observed accept and terminate timestamps.
Summary
Functions
Handles one inbound <call> stanza.
Functions
Handles one inbound <call> stanza.
Always returns {:ok, state}: call stanzas never produce outbound actions
here (the transport ACK is already handled at the connection boundary).