fix(voice): persist late outbound SDP answers when ACCEPTED races connect
If status=ACCEPTED is processed before Meta's connect webhook, the call is already in_progress when accept_outbound_call runs, and the previous guard dropped the SDP answer — leaving the browser without the data it needs to complete the WebRTC handshake. Gate on a stored sdp_answer instead of in_progress so out-of-order delivery still persists and broadcasts the answer (and connect retries stay idempotent).
This commit is contained in:
@@ -84,10 +84,15 @@ class Whatsapp::IncomingCallService
|
||||
|
||||
# `connect` is the WebRTC tunnel-ready signal, not the pickup signal. Apply
|
||||
# Meta's SDP answer so the handshake completes during ringing; the call
|
||||
# stays in `ringing` until status=ACCEPTED arrives.
|
||||
# stays in `ringing` until status=ACCEPTED arrives. Don't gate on
|
||||
# in_progress: an out-of-order ACCEPTED can flip status before connect is
|
||||
# processed, and dropping the SDP answer would leave the browser without
|
||||
# the data it needs to complete the handshake. Use the stored answer as
|
||||
# the idempotency key instead.
|
||||
def accept_outbound_call(call, payload)
|
||||
call.with_lock do
|
||||
next if call.in_progress? || call.terminal?
|
||||
next if call.terminal?
|
||||
next if call.meta&.dig('sdp_answer').present?
|
||||
|
||||
# Pin setup:active so browsers don't renegotiate when Meta echoes actpass.
|
||||
sdp_answer = payload.dig(:session, :sdp)&.gsub('a=setup:actpass', 'a=setup:active')
|
||||
|
||||
Reference in New Issue
Block a user