Skip to content

fix(call): correlate PLANET replies and handle remote release - #241

Merged
EdamAme-x merged 4 commits into
evex-dev:mainfrom
dryob:fix/planet-reply-release-t_f76e4c0a
Oct 10, 2026
Merged

EdamAme-x merged 4 commits into
evex-dev:mainfrom
dryob:fix/planet-reply-release-t_f76e4c0a

Conversation

@dryob

@dryob dryob commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Related to #198 (not closing the broader issue).

  • Preserve each incoming request's transaction ID, sequence and established session in CONN_RSP (including duplicates), INFO_RSP and MC DATA/JOIN/CHANGE responses. Newly originated requests retain fresh transactions and contiguous local request sequences.
  • Answer remote CC REL_REQ with REL_RSP (0x2245, result=0), mirror channels, resolve typed PlanetTransport.ended, finish receive/signaling waiters, stop keepalive and reject later media sends. Concurrent close shares teardown and does not originate another release after remote release.
  • Add explicit client.call.answerIncoming(event, { deviceId, signal, timeoutMs }) for ordinary 1:1 incoming audio. Listening never auto-answers. Validated event.audio binds the authenticated operation's caller, CID, route credential and local profile; video/group/unclassified operations fail closed. The application owns admission and installation-ID persistence.
  • Implement callee VERIFY → fresh E2EE-only CONN answer → final correlated CONN response. Provisional responses cannot enable media. Bind transactions, channels, nonces and session before changing state. For no-mAddr replies, pin the authenticated correlated VERIFY UDP peer; an explicit malformed address fails rather than falling back to our NAT address or unauthenticated RTP source.
  • Use callee media directions and derive outgoing SSRC from the local answer's field 11, not the caller offer's field 61. Preserve outgoing behavior and existing reply/release fixes.
  • Add an admission/media lifecycle example and incoming audio guide. Reuse encrypted loopback UDP/SRTP tests with synthetic identifiers and generated keys; no new dependencies.

Verification

Local Deno 2.9.6 checks:

  • deno test -A: 361 passed, 0 failed.
  • node scripts/test_node_transport.mts: 2 passed, 0 failed.
  • deno publish --dry-run --allow-dirty in packages/linejs and packages/types: passed, including public API checks.
  • deno check example/call/incoming.ts, formatting on changed TypeScript files and git diff --check: passed.
  • Encrypted UDP regression uses the public answer helper and checks VERIFY identity/credential, foreign and provisional replies, fresh E2EE answer, bidirectional SRTP, pinned no-address routing, local SSRC, remote release, abort/timeout cleanup, malformed media addresses and malformed offers.
  • SSRC RED/GREEN: restoring peer-offer selection produces 201 instead of the local answer's 102; restoring local-answer derivation passes. The stream ID is derived, not hardcoded in transport.
  • Earlier reply/release regressions demonstrated transaction mismatches and a pending receive surviving remote release before the fixes.

The existing Opus regression remains diagnostic only: synthetic [0x7a, 107] plus 68 zero bytes is structurally invalid; [0x7a, 0] is a legal two-frame control producing 1920 samples. No codec runtime change, guessed framing repair or suppressed error is included.

Evidence boundary and limitations

The source experimental JavaScript vendor was live-tested: outgoing audio completed a 60-second media window with audible speech and no T103, later remote release ended promptly, and the incoming callee path was confirmed audible after correcting its send SSRC. This upstream TypeScript port has automated synthetic verification, not a separate live phone-call test. The vendor's live results are not a claim that every upstream/group-call T103 is fixed.

Supported scope is ordinary 1:1 incoming audio. CANCEL_CALL operation correlation is not established, so cancellation is never inferred from a caller alone; use explicit abort or correlated PLANET release. Alternate BEPI/P2P migration, group/video interoperability and full native media-KDF byte equality remain unresolved. Applications coordinate incoming admission with outgoing calls and longer-lived replay policy. UDP requires Node/Deno, not a browser.

No account login, live call, production deployment or merge was performed for this port. No raw voice, captures, keys, auth tokens, real participant/device identities, private operator configuration or private PoC history are included.

@EdamAme-x
EdamAme-x merged commit e5d03c0 into evex-dev:main Oct 10, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants