# Chanora Function Inventory > Auto-generated comprehensive inventory of all public APIs across 10 Rust crates and 50+ Dart files. ## Summary Statistics | Category | Count | |----------|-------| | **Rust Crates** | 10 | | **Rust pub fn** | ~180 | | **Rust pub struct** | ~90 | | **Rust pub enum** | ~50 | | **Rust pub trait** | 6 | | **Rust pub const** | ~30 | | **Dart files** | 56 | | **Dart public classes** | ~80 | | **TODO/FIXME comments** | 15 | | **Empty/commented stubs** | 0 | --- ## Rust Crates ### 1. `chanora_cache` — Content-Addressed Blob Cache Disposable blob cache for avatar/icon files. Wraps `cacache` for crash safety. | Kind | Name | File:Line | Purpose | |------|------|-----------|---------| | struct | `BlobCache` | lib.rs:30 | Content-addressed blob cache backed by cacache | | enum | `BlobCacheError` | lib.rs:20 | Errors raised by blob cache (Io, InvalidKey) | | const | `PREFIX_AVATAR` | lib.rs:37 | Avatar blob prefix `"av_"` | | const | `PREFIX_ICON` | lib.rs:39 | Icon blob prefix `"ic_"` | | fn | `BlobCache::new` | lib.rs:46 | Create/open cache rooted at `cache_dir/chanora/` | | fn | `BlobCache::put` | lib.rs:63 | Store a blob with prefix+key | | fn | `BlobCache::get` | lib.rs:80 | Read a blob (returns None if missing) | | fn | `BlobCache::remove` | lib.rs:101 | Delete a specific blob | | fn | `BlobCache::clear` | lib.rs:111 | Delete all blobs | | fn | `BlobCache::total_size` | lib.rs:129 | Return total bytes used | | fn | `BlobCache::evict` | lib.rs:154 | Evict oldest entries until under max_bytes | **Dead code:** None found. All public items consumed by `chanora_core`. --- ### 2. `chanora_protocol` — TeamSpeak Protocol Adapter Isolates `tsclientlib` behind a typed boundary. No upstream types leak. | Kind | Name | File:Line | Purpose | |------|------|-----------|---------| | struct | `ConnectConfig` | adapter.rs:146 | Typed connection parameters | | struct | `ProtocolClient` | adapter.rs:236 | Async handle owning live protocol connection | | struct | `InboundVoice` | adapter.rs:260 | One inbound voice packet from remote client | | struct | `SnapshotProbe` | adapter.rs:270 | Clone-free probe handle for watchdog | | struct | `ChannelInfo` | dto.rs:19 | One channel in server tree | | struct | `ClientInfo` | dto.rs:72 | One connected client | | struct | `ClientProfile` | dto.rs:96 | Rich profile + live connection details | | struct | `ServerSnapshot` | dto.rs:153 | Full server state snapshot | | struct | `ChatMessage` | dto.rs:50 | In-channel text message | | struct | `ServerActivity` | dto.rs:65 | Server-activity notification | | struct | `ChannelId` | dto.rs:11 | Opaque channel identifier (u64 newtype) | | struct | `ClientId` | dto.rs:15 | Opaque client identifier (u64 newtype) | | struct | `PokeLimiter` | poke_limiter.rs:19 | Per-connection poke rate limiter | | enum | `ProtocolError` | lib.rs:62 | Typed error catalogue (10 variants) | | enum | `ProtocolDelta` | dto.rs:183 | Incremental state changes (7 variants) | | enum | `DisconnectReason` | adapter.rs:225 | Why protocol task ended | | enum | `MessageTarget` | dto.rs:37 | Text message target scope | | enum | `PokeStrength` | poke_limiter.rs:8 | Poke notification strength | | trait | *(re-exports)* | lib.rs:52 | `AudioData`, `CodecType`, `Direction`, `InAudioBuf`, `OutAudio`, `OutPacket` | | fn | `ProtocolClient::generate_identity` | adapter.rs:296 | Generate fresh TS3 identity string | | fn | `ProtocolClient::connect` | adapter.rs:304 | Dial server, wait for initial snapshot | | fn | `ProtocolClient::snapshot` | adapter.rs:354 | Read typed server state snapshot | | fn | `ProtocolClient::client_profile` | adapter.rs:365 | Fetch rich client profile | | fn | `ProtocolClient::download_avatar` | adapter.rs:389 | Download avatar bytes by UID | | fn | `ProtocolClient::download_icon` | adapter.rs:394 | Download icon bytes by ID | | fn | `ProtocolClient::disconnect` | adapter.rs:399 | Clean disconnect | | fn | `ProtocolClient::move_to_channel` | adapter.rs:421 | Move self to channel | | fn | `ProtocolClient::queue_move_to_channel` | adapter.rs:442 | Fire-and-forget move | | fn | `ProtocolClient::set_muted` | adapter.rs:458 | Update own mute state | | fn | `ProtocolClient::voice_out` | adapter.rs:477 | Get outbound voice sender | | fn | `ProtocolClient::snapshot_probe` | adapter.rs:485 | Get watchdog probe handle | | fn | `ProtocolClient::take_voice_in` | adapter.rs:493 | Take inbound voice receiver | | fn | `ProtocolClient::put_voice_in` | adapter.rs:503 | Put voice receiver back | | fn | `ProtocolClient::take_loss_notifier` | adapter.rs:519 | Take disconnect notifier | | fn | `ProtocolClient::take_chat_rx` | adapter.rs:525 | Take chat receiver | | fn | `ProtocolClient::put_chat_rx` | adapter.rs:530 | Put chat receiver back | | fn | `ProtocolClient::take_activity_rx` | adapter.rs:540 | Take activity receiver | | fn | `ProtocolClient::put_activity_rx` | adapter.rs:545 | Put activity receiver back | | fn | `ProtocolClient::take_delta_rx` | adapter.rs:556 | Take delta receiver | | fn | `ProtocolClient::send_text_message` | adapter.rs:561 | Send text message | | fn | `SnapshotProbe::probe` | adapter.rs:278 | Issue single snapshot RPC | | fn | `PokeLimiter::new` | poke_limiter.rs:36 | Create limiter with 5-min window | | fn | `PokeLimiter::record` | poke_limiter.rs:44 | Record poke, return strength | | fn | `ChannelId::ROOT` | dto.rs:176 | Root channel constant | **Dead code:** None found. All items consumed by `chanora_core`. --- ### 3. `chanora_bridge` — Flutter/Rust Bridge Typed DTOs and commands for `flutter_rust_bridge` 2.x. | Kind | Name | File:Line | Purpose | |------|------|-----------|---------| | struct | `BridgeChannel` | api.rs:404 | Channel DTO for Dart | | struct | `BridgeClient` | api.rs:422 | Client DTO for Dart | | struct | `BridgeClientProfile` | api.rs:445 | Rich profile DTO for Dart | | struct | `BridgeSnapshot` | api.rs:502 | Server snapshot DTO for Dart | | struct | `BridgeAudioStats` | api.rs:1034 | Audio engine statistics | | struct | `BridgeAudioProcessingConfig` | api.rs:1112 | Audio processing config DTO | | struct | `BridgeAudioProcessingStats` | api.rs:1143 | Audio processing stats DTO | | struct | `BridgePttDescriptor` | api.rs:854 | PTT capability descriptor | | struct | `BridgePttBinding` | api.rs:875 | PTT binding display state | | enum | `BridgeError` | lib.rs:55 | Bridge-layer errors (7 variants) | | enum | `BridgeTransmitMode` | api.rs:731 | Transmit mode mirror | | enum | `BridgePttInputClass` | api.rs:843 | PTT input class | | enum | `BridgeAudioRoute` | api.rs:1047 | Audio route class | | enum | `BridgeIosVoiceProcessingMode` | api.rs:1064 | iOS voice processing mode | | enum | `BridgeAudioBackend` | api.rs:1071 | Processing backend | | enum | `BridgeVadBackend` | api.rs:1084 | VAD backend | | enum | `BridgeEffectOwner` | api.rs:1097 | AEC/NS/AGC owner | | fn | `bridge_init` | api.rs:220 | One-time process init (FRB init) | | fn | `log_file_path_str` | api.rs:294 | Platform log file path | | fn | `connect` | api.rs:601 | Connect to TS3 server | | fn | `prefetch_server` | api.rs:636 | Warm DNS resolution | | fn | `snapshot` | api.rs:645 | Re-fetch server snapshot | | fn | `client_profile` | api.rs:654 | Fetch client profile | | fn | `disconnect` | api.rs:663 | Disconnect from server | | fn | `is_connected` | api.rs:672 | Check connection status | | fn | `handle_route_change` | api.rs:687 | iOS route change handler | | fn | `handle_media_services_reset_with_route` | api.rs:696 | iOS media reset handler | | fn | `handle_interruption_began` | api.rs:703 | iOS interruption begin | | fn | `handle_interruption_ended` | api.rs:709 | iOS interruption end | | fn | `set_ptt` | api.rs:718 | Set PTT active state | | fn | `voice_join` | api.rs:770 | Join voice channel | | fn | `voice_leave` | api.rs:785 | Leave voice channel | | fn | `set_transmit_mode` | api.rs:794 | Set transmit mode | | fn | `get_transmit_mode` | api.rs:803 | Get transmit mode | | fn | `set_release_tail_ms` | api.rs:814 | Set release tail | | fn | `get_release_tail_ms` | api.rs:823 | Get release tail | | fn | `set_hard_mute` | api.rs:832 | Engage/release hard mute | | fn | `set_ptt_binding` | api.rs:907 | Update PTT binding | | fn | `ptt_descriptor` | api.rs:925 | Get PTT descriptor | | fn | `get_ptt_binding` | api.rs:941 | Get persisted PTT binding | | fn | `move_to_channel` | api.rs:955 | Move self to channel | | fn | `set_input_muted` | api.rs:971 | Toggle input mute | | fn | `set_output_muted` | api.rs:983 | Toggle output mute | | fn | `set_output_gain` | api.rs:994 | Set master output gain | | fn | `set_client_volume` | api.rs:1006 | Set per-client volume | | fn | `send_chat_message` | api.rs:1015 | Send text message | | fn | `export_diagnostics` | api.rs:1392 | User-initiated diagnostic export | **Dead code:** `publish_permission_state` is `#[cfg_attr(not(target_os = "android"), allow(dead_code))]` — intentional, only used on Android via JNI. --- ### 4. `chanora_storage` — Identity & Bookmark Storage SQLite bookmarks + ChaCha20-Poly1305 encrypted identity file. | Kind | Name | File:Line | Purpose | |------|------|-----------|---------| | struct | `IdentityFileStore` | lib.rs:176 | Encrypted identity file store | | struct | `BookmarkRepository` | lib.rs:792 | SQLite-backed bookmark store | | struct | `Bookmark` | lib.rs:767 | A persisted bookmark | | struct | `PttBindingMeta` | lib.rs:117 | PTT binding metadata | | enum | `StorageError` | lib.rs:59 | Storage errors (6 variants) | | trait | `Crypto` | lib.rs:673 | Envelope encryption abstraction | | const | `KEYRING_SERVICE` | lib.rs:190 | Keyring service name `"chanora"` | | fn | `IdentityFileStore::new` | lib.rs:194 | Construct store at directory | | fn | `IdentityFileStore::path` | lib.rs:211 | Get identity file path | | fn | `IdentityFileStore::crypto` | lib.rs:384 | Get DekCrypto helper | | fn | `IdentityFileStore::load` | lib.rs:390 | Read persisted identity | | fn | `IdentityFileStore::save` | lib.rs:449 | Persist identity (encrypted) | | fn | `IdentityFileStore::set_transmit_mode` | lib.rs:520 | Persist transmit mode | | fn | `IdentityFileStore::get_transmit_mode` | lib.rs:528 | Read transmit mode | | fn | `IdentityFileStore::set_release_tail_ms` | lib.rs:534 | Persist release tail | | fn | `IdentityFileStore::get_release_tail_ms` | lib.rs:542 | Read release tail | | fn | `IdentityFileStore::set_ptt_binding` | lib.rs:554 | Persist PTT binding | | fn | `IdentityFileStore::get_ptt_binding` | lib.rs:568 | Read PTT binding | | fn | `IdentityFileStore::clear` | lib.rs:579 | Remove persisted identity | | fn | `BookmarkRepository::new` | lib.rs:801 | Open DB without encryption | | fn | `BookmarkRepository::with_crypto` | lib.rs:807 | Open DB with password encryption | | fn | `BookmarkRepository::encrypts_passwords` | lib.rs:858 | Check if encryption wired | | fn | `BookmarkRepository::add` | lib.rs:865 | Insert bookmark | | fn | `BookmarkRepository::upsert_or_add` | lib.rs:891 | Insert or update by host | | fn | `BookmarkRepository::update` | lib.rs:935 | Replace existing bookmark | | fn | `BookmarkRepository::delete` | lib.rs:963 | Delete bookmark by id | | fn | `BookmarkRepository::list` | lib.rs:976 | List all bookmarks | **Dead code:** None found. --- ### 5. `chanora_state` — Server State Mirror Authoritative client-side mirror of server state with deterministic reducers. | Kind | Name | File:Line | Purpose | |------|------|-----------|---------| | struct | `ServerState` | lib.rs:62 | Authoritative server state mirror | | struct | `Reduction` | lib.rs:266 | Result of applying one event | | struct | `ChannelJoinState` | channel_join.rs:53 | Channel-join reducer state | | struct | `AuthoritativeMembership` | channel_join.rs:27 | Server-confirmed membership | | struct | `JoinPending` | channel_join.rs:36 | Active pending join intent | | struct | `ChannelJoinProjection` | channel_join.rs:135 | Reducer projection for UI | | struct | `JoinOutcomeKey` | channel_join.rs:124 | Correlation key for outcomes | | struct | `ConnectionEpoch` | channel_join.rs:15 | Per-connection epoch | | struct | `JoinGeneration` | channel_join.rs:19 | Monotonic join generation | | struct | `JoinRequestId` | channel_join.rs:23 | Protocol request identifier | | struct | `ChannelId` (join) | channel_join.rs:11 | Channel identifier at reducer seam | | enum | `ConnectionState` | lib.rs:43 | Connection lifecycle (5 variants) | | enum | `Delta` | lib.rs:209 | State changes for bridge (8 variants) | | enum | `StateEvent` | lib.rs:237 | Events flowing into reducer (9 variants) | | enum | `StateError` | lib.rs:32 | State errors (2 variants) | | enum | `ChannelJoinEvent` | channel_join.rs:165 | Channel-join events (10 variants) | | enum | `ChannelJoinAction` | channel_join.rs:240 | Side-effect actions (7 variants) | | enum | `ChannelJoinSyncState` | channel_join.rs:101 | Sync readiness (2 variants) | | enum | `SyncReason` | channel_join.rs:115 | Sync reason (2 variants) | | enum | `JoinReduceStatus` | channel_join.rs:309 | Transition status (9 variants) | | enum | `JoinIntentRejected` | channel_join.rs:332 | Rejection reasons (2 variants) | | enum | `JoinFailureKind` | channel_join.rs:341 | Failure kinds (5 variants) | | enum | `JoinErrorCode` | channel_join.rs:356 | Stable error codes (11 variants) | | enum | `JoinDiagnosticKey` | channel_join.rs:284 | Diagnostic event keys (10 variants) | | enum | `AuthoritativeSource` | channel_join.rs:156 | Membership input source | | fn | `ServerState::from_snapshot` | lib.rs:83 | Build from initial snapshot | | fn | `ServerState::replace_from_snapshot` | lib.rs:114 | Replace with fresh snapshot | | fn | `ServerState::channel` | lib.rs:119 | Look up channel by id | | fn | `ServerState::client` | lib.rs:124 | Look up client by id | | fn | `ServerState::channels` | lib.rs:130 | All channels iterator | | fn | `ServerState::clients` | lib.rs:141 | All clients iterator | | fn | `ServerState::channel_count` | lib.rs:148 | Number of channels | | fn | `ServerState::client_count` | lib.rs:153 | Number of clients | | fn | `ServerState::own_channel` | lib.rs:158 | Own client's channel | | fn | `ServerState::clients_in_channel` | lib.rs:164 | Clients in specific channel | | fn | `reduce` | lib.rs:281 | Apply StateEvent to state | | fn | `reduce_reconnect_snapshot` | lib.rs:409 | Replace state after reconnect | | fn | `channel_join::reduce` | channel_join.rs:393 | Channel-join event reducer | | fn | `channel_join::project` | channel_join.rs:670 | Build channel-join projection | | fn | `ChannelJoinState::new` | channel_join.rs:68 | Create join state for epoch | **Dead code:** None found. --- ### 6. `chanora_audio` — Audio Subsystem Platform capture/playback, Opus encoding, VAD, PTT, DSP. | Kind | Name | File:Line | Purpose | |------|------|-----------|---------| | **Core Engine** | | | | | struct | `AudioEngine` | engine.rs:289 | Main audio engine | | struct | `AudioEngineConfig` | engine.rs:223 | Engine configuration | | struct | `SessionAudioId` | engine.rs:69 | Stable audio session ID | | struct | `AudioDeviceList` | engine.rs:87 | Available audio devices | | struct | `AudioDeviceInfo` | engine.rs:96 | Single audio device info | | enum | `AudioError` | lib.rs:100 | Audio subsystem errors (8 variants) | | struct | `AudioEffects` | lib.rs:136 | AEC/AGC/NS/HPF toggles | | fn | `list_audio_devices` | engine.rs:176 | Enumerate input/output devices | | fn | `AudioEngine::start` | engine.rs:634 | Start audio engine | | fn | `AudioEngine::start_with_gate` | engine.rs:647 | Start with transmit gate | | fn | `AudioEngine::stop` | engine.rs:1358 | Stop audio engine | | fn | `AudioEngine::set_transmit_active` | engine.rs:1601 | Set transmit state | | fn | `AudioEngine::transmit_active` | engine.rs:1606 | Get transmit state | | fn | `AudioEngine::set_output_muted` | engine.rs:1702 | Set output mute | | fn | `AudioEngine::set_output_gain` | engine.rs:1714 | Set output gain | | fn | `AudioEngine::set_client_volume` | engine.rs:1727 | Set per-client volume | | fn | `AudioEngine::set_audio_processing_config` | engine.rs:1646 | Update processing config | | fn | `AudioEngine::audio_processing_stats` | engine.rs:1683 | Get processing stats | | **Frame Helpers** | | | | | const | `SAMPLE_RATE_HZ` | frame.rs:9 | 48000 Hz | | const | `FRAME_10MS_SAMPLES` | frame.rs:15 | 480 samples | | const | `FRAME_20MS_SAMPLES` | frame.rs:17 | 960 samples | | struct | `AudioFrame10ms` | frame.rs:21 | 10ms processing frame | | struct | `AudioFrame20ms` | frame.rs:28 | 20ms network frame | | fn | `i16_to_f32` | frame.rs:64 | PCM conversion | | fn | `f32_to_i16` | frame.rs:69 | PCM conversion | | fn | `dbfs` | frame.rs:74 | RMS dBFS calculation | | **Transmit** | | | | | enum | `TransmitMode` | transmit_mode.rs:13 | Ptt/Continuous/VoiceActivity | | enum | `PermissionGate` | transmit_selector.rs:38 | Mic permission state | | struct | `TransmitModeSelector` | transmit_selector.rs:88 | Multi-signal transmit selector | | struct | `AudioTransmitGate` | ptt.rs:139 | Atomic transmit flag | | struct | `ReleaseTailTimer` | release_tail.rs:43 | PTT release-tail timer | | const | `DEFAULT_TAIL_MS` | release_tail.rs:24 | 200ms default | | const | `MAX_TAIL_MS` | release_tail.rs:21 | 500ms max | | **PTT** | | | | | enum | `PttCapabilityLevel` | ptt.rs:34 | L0-L4 capability levels | | struct | `PttBackendDescriptor` | ptt.rs:97 | Privacy-safe PTT descriptor | | struct | `MissedKeyUpWatchdog` | ptt.rs:202 | PTT safety watchdog | | trait | `DesktopPttBackend` | ptt_backends/mod.rs:162 | Platform PTT backend trait | | struct | `PttBinding` | ptt_backends/mod.rs:48 | PTT binding metadata | | enum | `PttInputClass` | ptt_backends/mod.rs:84 | None/Keyboard/MouseSideButton | | enum | `PttBackendError` | ptt_backends/mod.rs:113 | PTT backend errors | | fn | `select_ptt_backend` | ptt_backends/mod.rs:213 | Auto-select best backend | | **Audio Processing** | | | | | enum | `AudioRoute` | audio_processing.rs:14 | Route class (6 variants) | | enum | `AudioBackend` | audio_processing.rs:65 | Processing backend (4 variants) | | enum | `VadBackend` | audio_processing.rs:90 | VAD backend (4 variants) | | enum | `EffectOwner` | audio_processing.rs:122 | Effect owner (5 variants) | | enum | `IosVoiceProcessingMode` | audio_processing.rs:58 | iOS VPIO mode | | struct | `AudioProcessingConfig` | audio_processing.rs:137 | Full processing config | | struct | `AudioProcessingStats` | audio_processing.rs:270 | Processing statistics | | struct | `SharedAudioProcessingStats` | audio_processing.rs:322 | Thread-safe stats | | **DSP** | | | | | struct | `Aec3` | processor/dsp/aec3.rs:48 | Acoustic echo canceller | | struct | `Agc2` | processor/dsp/agc2.rs:206 | Automatic gain control | | struct | `HighPassFilter` | processor/dsp/hpf.rs:42 | High-pass filter | | struct | `NoiseSuppressor` | processor/dsp/ns.rs:40 | Noise suppressor | | trait | `AudioProcessor` | processor/mod.rs:21 | Realtime processor trait | | struct | `NoopProcessor` | processor/noop.rs:6 | No-op processor | | struct | `PlatformVoiceProcessor` | processor/platform.rs:10 | Platform VPIO processor | | struct | `SonoraProcessor` | processor/sonora.rs:88 | Sonora DSP processor | | struct | `SonoraConfig` | processor/sonora.rs:37 | Sonora configuration | | struct | `WebRtcApmProcessor` | processor/webrtc_apm.rs:91 | WebRTC APM processor | | struct | `WebRtcApmConfig` | processor/webrtc_apm.rs:17 | WebRTC APM config | | **VAD** | | | | | trait | `VoiceActivityDetector` | vad/mod.rs:34 | VAD trait | | struct | `VadOutput` | vad/mod.rs:26 | VAD output (probability + speech) | | struct | `WebRtcFallbackVad` | vad/mod.rs:40 | WebRTC fallback VAD | | struct | `Resampled16kHzVad` | vad/mod.rs:77 | 48→16kHz resampling wrapper | | struct | `SileroOnnxVad` | vad/silero_onnx.rs:62 | Silero ONNX VAD | | struct | `Downsampler48to16` | vad/resampler.rs:44 | 48→16kHz downsampler | | fn | `set_silero_model_path` | vad/mod.rs:126 | Set VAD model path | | fn | `silero_model_epoch` | vad/mod.rs:147 | Get model epoch | | **Voice Activity** | | | | | struct | `VoiceActivityStateMachine` | voice_activity.rs:29 | VAD gate state machine | | **Mobile Backend** | | | | | trait | `MobileVoiceAudioBackend` | mobile_voice_backend.rs:262 | Mobile audio backend trait | | struct | `AndroidVoiceStreamConfig` | mobile_voice_backend.rs:194 | Android stream config | | struct | `AndroidAudioDiagnostics` | mobile_voice_backend.rs:499 | Android diagnostics | | enum | `BackendEvent` | mobile_voice_backend.rs:35 | Backend events | | enum | `BackendError` | mobile_voice_backend.rs:154 | Backend errors | | enum | `AchievedPerformanceMode` | mobile_voice_backend.rs:112 | Performance mode | | enum | `LatencyTier` | mobile_voice_backend.rs:377 | Latency tier | | struct | `AndroidVoiceUnit` | android_voice_unit.rs:565 | Android voice unit | | struct | `IosVoiceUnit` | ios_voice_unit.rs:522 | iOS voice unit | | **Route Policy** | | | | | fn | `ios_route_policy` | route_policy.rs:27 | Route→config policy for iOS | | fn | `apply_route_change` | route_policy.rs:105 | Apply route change | | **Mode Stack** | | | | | struct | `ModeStack` | mode_stack.rs:88 | Android audio mode refcount | | enum | `ModeAcquire` | mode_stack.rs:41 | Acquire result | | enum | `ModeRelease` | mode_stack.rs:62 | Release result | | **Debug** | | | | | struct | `WavDebugRecorder` | debug_wav.rs:68 | Debug WAV recorder | **Dead code:** `AndroidVoiceUnit`, `IosVoiceUnit`, and platform-specific backends are `#[cfg]`-gated — intentional. --- ### 7. `chanora_resolver` — DNS/SRV/TSDNS Resolver TeamSpeak address resolution: SRV, TSDNS, nick lookup. | Kind | Name | File:Line | Purpose | |------|------|-----------|---------| | struct | `ChanoraResolver` | lib.rs:108 | Main resolver | | struct | `Args` | lib.rs:26 | Resolution arguments | | struct | `BuildInfo` | lib.rs:33 | Build metadata | | struct | `SrvRecord` | lib.rs:40 | SRV record | | struct | `ClientResolution` | lib.rs:58 | Client resolution result | | enum | `Resolution` | lib.rs:85 | Resolution result (Dns/Srv/Nick) | | enum | `ClientResolutionMethod` | lib.rs:48 | Resolution method (6 variants) | | const | `DEFAULT_TEAMSPEAK_PORT` | lib.rs:23 | Port 9987 | | fn | `build_info` | lib.rs:123 | Get build info | | fn | `setup_log` | lib.rs:137 | Setup logging | | fn | `ChanoraResolver::new` | lib.rs:157 | Create resolver | | fn | `ChanoraResolver::resolve` | lib.rs:178 | Resolve with Args | | fn | `ChanoraResolver::resolve_connection_address` | lib.rs:193 | Resolve to connection address | | fn | `ChanoraResolver::resolve_client_address` | lib.rs:197 | Resolve client input to address | | fn | `ChanoraResolver::resolve_client_request` | lib.rs:201 | Resolve with full metadata | | fn | `ChanoraResolver::resolve_dns` | lib.rs:594 | DNS lookup | | fn | `ChanoraResolver::resolve_ts3` | lib.rs:614 | TS3 SRV lookup | | fn | `ChanoraResolver::resolve_tsdns` | lib.rs:619 | TSDNS SRV lookup | | fn | `ChanoraResolver::resolve_nick` | lib.rs:624 | Nick lookup | | fn | `normalize_args` | lib.rs:778 | Normalize Args | | fn | `validate_args` | lib.rs:785 | Validate Args | | fn | `run` | lib.rs:804 | CLI entry point | **Dead code:** `run()` is a CLI entry point, not called from library code — intentional. --- ### 8. `chanora_prefetch` — Server Address Prefetch Speculative DNS warming for faster connects. | Kind | Name | File:Line | Purpose | |------|------|-----------|---------| | struct | `ServerPrefetcher` | lib.rs:83 | Prefetch cache + async resolver | | enum | `ServerPrefetchError` | lib.rs:18 | Prefetch errors | | fn | `ServerPrefetcher::new` | lib.rs:90 | Create prefetcher | | fn | `ServerPrefetcher::prefetch` | lib.rs:99 | Schedule fire-and-forget prefetch | | fn | `ServerPrefetcher::fresh_match` | lib.rs:145 | Check for cached result | **Dead code:** None found. --- ### 9. `chanora_diagnostics` — Redaction & Diagnostic Export Redaction policy, in-memory log sink, PTT sanitizer. | Kind | Name | File:Line | Purpose | |------|------|-----------|---------| | struct | `Redactor` | lib.rs:121 | Production redaction policy | | struct | `KnownSecretRegistry` | lib.rs:79 | Secret substring registry | | struct | `InMemoryLogSink` | lib.rs:356 | Bounded redacted log sink | | struct | `RedactingLogLayer` | lib.rs:440 | tracing Layer for redaction | | struct | `PttSanitizer` | lib.rs:505 | PTT field ban Layer | | struct | `DiagnosticExport` | lib.rs:614 | Export bundle | | struct | `ProtocolEventRecorder` | lib.rs:714 | Protocol event ring buffer | | enum | `DiagnosticsError` | lib.rs:51 | Diagnostics errors | | const | `REDACTION_MARKER` | lib.rs:62 | `"[REDACTED]"` | | const | `DEFAULT_LOG_CAPACITY` | lib.rs:67/70 | 256 (release) / 4096 (debug) | | fn | `Redactor::with_default_policy` | lib.rs:128 | Create redactor | | fn | `Redactor::with_secrets` | lib.rs:134 | Create with secret registry | | fn | `Redactor::secrets` | lib.rs:140 | Access secret registry | | fn | `Redactor::redact` | lib.rs:150 | Apply redaction policy | | fn | `KnownSecretRegistry::register` | lib.rs:85 | Register secret | | fn | `KnownSecretRegistry::len` | lib.rs:99 | Count secrets | | fn | `KnownSecretRegistry::is_empty` | lib.rs:104 | Check empty | | fn | `KnownSecretRegistry::contains_substr` | lib.rs:110 | Substring check | | fn | `InMemoryLogSink::new` | lib.rs:365 | Create sink | | fn | `InMemoryLogSink::snapshot` | lib.rs:377 | Snapshot lines | | fn | `InMemoryLogSink::push` | lib.rs:386 | Push redacted line | | fn | `InMemoryLogSink::redactor` | lib.rs:397 | Access redactor | | fn | `RedactingLogLayer::new` | lib.rs:446 | Create layer | | fn | `RedactingLogLayer::with_sanitizer` | lib.rs:452 | Wrap with PTT sanitizer | | fn | `PttSanitizer::wrap` | lib.rs:513 | Wrap inner layer | | fn | `DiagnosticExport::from_sink` | lib.rs:636 | Build export | | fn | `DiagnosticExport::with_android_audio` | lib.rs:655 | Attach Android audio YAML | | fn | `DiagnosticExport::with_network_info` | lib.rs:661 | Attach network info | | fn | `DiagnosticExport::with_protocol_events` | lib.rs:667 | Attach protocol events | | fn | `DiagnosticExport::to_text` | lib.rs:674 | Render as plaintext | | fn | `ProtocolEventRecorder::new` | lib.rs:721 | Create recorder | | fn | `ProtocolEventRecorder::record_connected` | lib.rs:740 | Record connection | | fn | `ProtocolEventRecorder::record_disconnected` | lib.rs:745 | Record disconnect | | fn | `ProtocolEventRecorder::record_reconnecting` | lib.rs:750 | Record reconnect | | fn | `ProtocolEventRecorder::record_snapshot_changed` | lib.rs:759 | Record snapshot change | | fn | `ProtocolEventRecorder::record_channel_join` | lib.rs:768 | Record channel join | | fn | `ProtocolEventRecorder::record_lifecycle` | lib.rs:777 | Record lifecycle | | fn | `ProtocolEventRecorder::drain` | lib.rs:782 | Drain all events | | fn | `ProtocolEventRecorder::snapshot` | lib.rs:787 | Snapshot events | **Dead code:** None found. --- ### 10. `chanora_core` — Top-Level Orchestration Integration point composing all subsystems behind a stable API. | Kind | Name | File:Line | Purpose | |------|------|-----------|---------| | struct | `ChanoraSession` | lib.rs:191 | Process-wide session handle | | enum | `CoreError` | lib.rs:84 | Top-level errors (12 variants) | | struct | `PttDescriptorSnapshot` | events.rs:6 | PTT descriptor snapshot | | struct | `PersistedPttBinding` | events.rs:27 | Persisted PTT binding | | struct | `PttController` | ptt.rs:68 | PTT controller | | struct | `FileTransferService` | file_transfer.rs:39 | File transfer service | | enum | `SessionEvent` | events.rs:49 | Session lifecycle events | | enum | `VoiceJoinSyncState` | events.rs:239 | Voice join sync state | | enum | `VoiceJoinErrorCode` | events.rs:250 | Voice join error codes | | enum | `NetworkState` | events.rs:280 | Network connectivity state | | enum | `FileTransferError` | file_transfer.rs:17 | File transfer errors | | enum | `PttControllerError` | ptt.rs:35 | PTT controller errors | | fn | `ChanoraSession::new` | lib.rs:245 | Create session | | fn | `ChanoraSession::subscribe_events` | lib.rs:478 | Subscribe to session events | | fn | `ChanoraSession::set_network_state` | lib.rs:460 | Set network state | | fn | `ChanoraSession::network_state` | lib.rs:469 | Get network state | | fn | `ChanoraSession::transmit_mode` | lib.rs:1568 | Get transmit mode | | fn | `ChanoraSession::hard_mute` | lib.rs:1591 | Get hard mute state | | fn | `ChanoraSession::release_tail_ms` | lib.rs:1645 | Get release tail | | fn | `ChanoraSession::transmit_selector` | lib.rs:1652 | Get transmit selector | | fn | `ChanoraSession::release_tail_timer` | lib.rs:1659 | Get release tail timer | | fn | `ChanoraSession::audio_processing_stats_if_ready` | lib.rs:1205 | Get audio stats | | fn | `PttController::new` | ptt.rs:103 | Create PTT controller | | fn | `PttController::current_capability` | ptt.rs:226 | Get PTT capability | | fn | `PttController::subscribe_capability` | ptt.rs:233 | Subscribe to capability | | fn | `PttController::descriptor_watch` | ptt.rs:250 | Watch PTT descriptor | | fn | `PttController::press_gate` | ptt.rs:257 | Get press gate | | fn | `PttController::release_tail` | ptt.rs:263 | Get release tail | **Dead code:** None found. All items consumed by `chanora_bridge`. --- ## Dart Files (apps/chanora_flutter/lib/) ### Widgets (31 files) | Class | File:Line | Purpose | |-------|-----------|---------| | `AppSnackBar` | widgets/app_snack_bar.dart:9 | Snackbar notifications | | `AppSnackBarVariant` | widgets/app_snack_bar.dart:6 | Neutral/success/warning/error | | `AudioDebugStatsPanel` | widgets/audio_debug_stats_panel.dart:22 | Audio stats debug panel | | `AudioDeviceListTile` | widgets/audio_device_list_tile.dart:21 | Audio device list item | | `AudioDeviceKind` | widgets/audio_device_list_tile.dart:12 | Input/Output device kind | | `AudioOutputTile` | widgets/audio_output_tile.dart:15 | Audio output route picker | | `AudioProcessingConfigState` | widgets/audio_processing_config_state.dart:34 | Processing config state | | `BbCodeText` | widgets/bbcode_text.dart:47 | BBCode renderer | | `ChatPanel` | widgets/chat_panel.dart:13 | Chat panel container | | `ChatEntry` | widgets/chat_views.dart:25 | Chat message entry | | `ChatClientGroups` | widgets/chat_views.dart:374 | Client grouping for chat | | `ChatPage` | widgets/chat_views.dart:548 | Full chat page | | `ChatDetailView` | widgets/chat_views.dart:1070 | Chat detail view | | `ClientInfoSheet` | widgets/client_info_sheet.dart:7 | Client info bottom sheet | | `ConnectForm` | widgets/connect_widgets.dart:9 | Server connect form | | `BookmarkList` | widgets/connect_widgets.dart:154 | Bookmark list | | `CapturedBinding` | widgets/input_dialogs.dart:50 | PTT binding capture result | | `BookmarkNameDialog` | widgets/input_dialogs.dart:61 | Bookmark name input | | `ChannelPasswordDialog` | widgets/input_dialogs.dart:109 | Channel password input | | `PttBindingCaptureDialog` | widgets/input_dialogs.dart:154 | PTT key binding dialog | | `PermissionStateBanner` | widgets/permission_state_banner.dart:28 | Permission state banner | | `PokeNotificationSettingsDialog` | widgets/poke_notification_settings.dart:7 | Poke notification settings | | `PttCapabilityBadge` | widgets/ptt_capability_badge.dart:14 | PTT capability badge | | `SnapshotView` | widgets/snapshot_view.dart:14 | Server tree view | | `TalkPowerWarning` | widgets/talk_power_warning.dart:14 | Talk power warning | | `VoiceBar` | widgets/voice_bar.dart:18 | Voice status bar | | `VoiceStatusChip` | widgets/voice_compact.dart:46 | Voice status chip | | `VoicePttButton` | widgets/voice_compact.dart:255 | PTT button widget | | `VoiceLevelMeter` | widgets/voice_level_meter.dart:11 | Voice level meter | | `VoiceSettingsDialog` | widgets/voice_settings.dart:61 | Voice settings dialog | | `VoiceSettingsResult` | widgets/voice_settings.dart:46 | Settings result | | `VoiceStatusSummary` | widgets/voice_status_summary.dart:5 | Voice status summary | | `VoiceSubHeader` | widgets/voice_settings_controls.dart:117 | Voice sub-header | | `VoiceSectionHeader` | widgets/voice_settings_controls.dart:141 | Voice section header | | `AudioProcessingToggleRow` | widgets/voice_settings_controls.dart:159 | Processing toggle row | ### Services (20 files) | Class/Function | File:Line | Purpose | |----------------|-----------|---------| | `AndroidAudioOutputDevice` | services/android_audio_output_devices.dart:1 | Android audio device | | `AndroidPermissionsService` | services/android_permissions_service.dart:34 | Android permission handler | | `AppBootstrap` | services/app_bootstrap.dart:95 | App bootstrap helpers | | `AudioLifecycleService` | services/audio_lifecycle_service.dart:46 | Audio lifecycle wiring | | `BackIntentPolicy` | services/back_intent_policy.dart | Back intent policy | | `BackIntentService` | services/back_intent_service.dart:97 | Back intent handler | | `ChannelJoinErrorMapper` | services/channel_join_error_mapper.dart:5 | Error message mapper | | `ChannelSpacer` | services/channel_spacer.dart:110 | Spacer channel detection | | `ConnectionPhaseState` | services/connection_phase_state.dart:38 | Connection phase state | | `HardMuteOwners` | services/hard_mute_owners.dart | Hard mute owners | | `IosAudioSessionController` | services/ios_audio_session_controller.dart | iOS audio session | | `IosPermissionsService` | services/ios_permissions_service.dart:66 | iOS permission handler | | `LinkTrustService` | services/link_trust_service.dart:29 | Link trust checker | | `MacosPermissionsService` | services/macos_permissions_service.dart:273 | macOS permission handler | | `PokePreferencesService` | services/poke_preferences_service.dart:44 | Poke mute preferences | | `PokeNotificationService` | services/poke_notification_service.dart | Poke notification handler | | `PrefetchDebouncer` | services/prefetch_debouncer.dart:15 | DNS prefetch debouncer | | `OwnClientSnapshotState` | services/snapshot_state_mapper.dart:3 | Snapshot→state mapper | | `ownClientSnapshotState()` | services/snapshot_state_mapper.dart:23 | Build snapshot state | | `snapshotChannelName()` | services/snapshot_state_mapper.dart:43 | Get channel name from snapshot | | `snapshotNeededTalkPower()` | services/snapshot_state_mapper.dart:48 | Get required talk power | | `Ts3ServerLink` | services/ts3_server_link.dart:83 | TS3 server link parser | | `UiPreferencesService` | services/ui_preferences_service.dart | UI preferences | | `VoiceJoinOrdering` | services/voice_join_ordering.dart | Voice join ordering | ### Design (4 files) | Class | File:Line | Purpose | |-------|-----------|---------| | `ChanoraTokens` | design/chanora_tokens.dart | Design tokens | | `Breakpoints` | design/breakpoints.dart | Responsive breakpoints | | `ViewportInfo` | design/viewport_info.dart | Viewport info | | `PlatformCapabilities` | design/platform_capabilities.dart | Platform capabilities | --- ## Dead Code Analysis ### Confirmed Dead Code None found. All public items are consumed by downstream crates or are intentionally platform-gated. ### Platform-Gated (Intentional) - `AndroidVoiceUnit`, `IosVoiceUnit` — only compiled on target platforms - `chanora_android_*` JNI functions — Android only - `ios_voice_unit.rs`, `android_voice_unit.rs` — platform-specific - `sdl_output.rs` — Linux only ### TODO/FIXME Items (15 total) | File | Line | Note | |------|------|------| | `chanora_audio/src/audio_event_queue.rs` | 27 | Wire to client disconnect path | | `chanora_audio/src/engine.rs` | 2348 | Realtime audio callback concern | | `chanora_audio/src/mobile_voice_backend.rs` | 16 | Back-fill IosVoiceUnit to trait | | `audio_lifecycle_service.dart` | 151 | Wire macOS default device change | | `audio_lifecycle_service.dart` | 156 | macOS device change no action yet | | `poke_notification_service.dart` | 33,35,41,43,48,130,132,142,155,168 | Future EventSoundService (10 items) | ### Useless Code - No empty impls found - No commented-out function bodies found - No dead trait implementations found --- ## Architecture Notes - **Boundary discipline**: `tsclientlib` types never cross `chanora_protocol` boundary (SAD-067) - **Single connection**: DEC-006 enforces one connection at runtime - **Secret isolation**: `chanora_storage` never stores secrets in plaintext DB - **Deterministic reducers**: `chanora_state` reducers are pure functions (SRS-056) - **PTT privacy**: Raw key codes never appear in logs or diagnostics (DEC-027) - **Audio pipeline**: 48kHz mono, 20ms Opus frames, 10ms processing frames