EDA.Voice.Dave.Manager (EDA v0.3.0)

Copy Markdown View Source

Coordinates the DAVE (Discord Audio Video E2EE) protocol.

This is a pure struct (not a GenServer) to avoid bottlenecks on the audio hot path (50 frames/sec). The NIF resource is thread-safe (Mutex on the Rust side).

When protocol_version is 0, all operations are passthrough (zero-cost).

Summary

Functions

Returns true if DAVE E2EE is active (version > 0 and NIF session available).

Decrypts a DAVE-encrypted frame.

Encrypts an Opus frame through DAVE E2EE.

Handles an MLS-related voice gateway event.

Builds an OP26 key package payload from the current MLS session.

Creates a new DAVE manager. Version 0 means passthrough (no E2EE).

Returns true when the MLS session is ready to encrypt media.

Types

t()

@type t() :: %EDA.Voice.Dave.Manager{
  channel_id: non_neg_integer(),
  mls_session: reference() | nil,
  pending_epoch: non_neg_integer() | nil,
  protocol_version: non_neg_integer(),
  transition_id: non_neg_integer() | nil,
  user_id: non_neg_integer()
}

Functions

active?(manager)

@spec active?(t()) :: boolean()

Returns true if DAVE E2EE is active (version > 0 and NIF session available).

decrypt_frame(manager, frame, sender_user_id)

@spec decrypt_frame(t(), binary(), non_neg_integer()) ::
  {:ok, binary(), t()} | {:error, atom()}

Decrypts a DAVE-encrypted frame.

In passthrough mode, returns the frame unchanged. Returns {:ok, decrypted_frame, updated_manager} or {:error, reason}.

encrypt_frame(manager, opus_frame)

@spec encrypt_frame(t(), binary()) :: {:ok, binary(), t()} | {:error, term(), t()}

Encrypts an Opus frame through DAVE E2EE.

In passthrough mode, returns the frame unchanged. Returns {:ok, encrypted_frame, updated_manager} on success. Returns {:error, reason, updated_manager} when an active DAVE session cannot encrypt media, so callers can stop playback instead of sending undecryptable raw Opus.

handle_mls_event(manager, opcode, data)

@spec handle_mls_event(t(), non_neg_integer(), map()) :: {t(), list()}

Handles an MLS-related voice gateway event.

Returns {updated_manager, reply_payloads} where reply_payloads is a list of payloads to send back to the voice gateway.

key_package_payload(manager)

@spec key_package_payload(t()) :: {:ok, term()} | :error

Builds an OP26 key package payload from the current MLS session.

Returns {:ok, payload} when available, otherwise :error.

new(protocol_version, user_id, channel_id)

Creates a new DAVE manager. Version 0 means passthrough (no E2EE).

ready?(manager)

@spec ready?(t()) :: boolean()

Returns true when the MLS session is ready to encrypt media.