From d0e306cb78a0ecba9e0c788fd12a734a3f2f17b6 Mon Sep 17 00:00:00 2001 From: Wouter Bokslag Date: Mon, 23 Feb 2026 17:15:52 +0100 Subject: [PATCH] Optimized out redundant BrewConfig struct Struct contents were nearly identical to CfgBrew from config. Removed BrewConfig and updating passing config to Brew entity --- bins/bluestation-bs/src/main.rs | 18 ++--------- crates/tetra-config/src/stack_config_brew.rs | 8 ++--- .../src/brew/components/brew_routable.rs | 7 ++--- crates/tetra-entities/src/brew/entity.rs | 13 +++++--- crates/tetra-entities/src/brew/worker.rs | 31 ++----------------- 5 files changed, 20 insertions(+), 57 deletions(-) diff --git a/bins/bluestation-bs/src/main.rs b/bins/bluestation-bs/src/main.rs index 2864a3b..b25dc63 100644 --- a/bins/bluestation-bs/src/main.rs +++ b/bins/bluestation-bs/src/main.rs @@ -2,13 +2,11 @@ use clap::Parser; use std::sync::Arc; use std::sync::atomic::{AtomicBool, Ordering}; -use std::time::Duration; use tetra_config::{PhyBackend, SharedConfig, StackMode, toml_config}; use tetra_core::{TdmaTime, debug}; use tetra_entities::MessageRouter; use tetra_entities::brew::entity::BrewEntity; -use tetra_entities::brew::worker::BrewConfig; use tetra_entities::{ cmce::cmce_bs::CmceBs, llc::llc_bs_ms::Llc, @@ -64,20 +62,8 @@ fn build_bs_stack(cfg: &mut SharedConfig) -> MessageRouter { router.register_entity(Box::new(cmce)); // Register Brew entity if enabled - if let Some(brew_cfg) = cfg.config().brew.clone() { - let brew_config = BrewConfig { - host: brew_cfg.host, - port: brew_cfg.port, - tls: brew_cfg.tls, - username: brew_cfg.username, - password: brew_cfg.password, - issi: brew_cfg.issi, - reconnect_delay: Duration::from_secs(brew_cfg.reconnect_delay_secs), - jitter_initial_latency_frames: brew_cfg.jitter_initial_latency_frames, - whitelisted_ssi_ranges: brew_cfg.whitelisted_ssi_ranges, - blacklisted_ssi_ranges: brew_cfg.blacklisted_ssi_ranges, - }; - let brew_entity = BrewEntity::new(cfg.clone(), brew_config); + if cfg.config().brew.is_some() { + let brew_entity = BrewEntity::new(cfg.clone()); router.register_entity(Box::new(brew_entity)); eprintln!(" -> Brew/TetraPack integration enabled"); } diff --git a/crates/tetra-config/src/stack_config_brew.rs b/crates/tetra-config/src/stack_config_brew.rs index 2d43e29..fdcc545 100644 --- a/crates/tetra-config/src/stack_config_brew.rs +++ b/crates/tetra-config/src/stack_config_brew.rs @@ -1,4 +1,4 @@ -use std::collections::HashMap; +use std::{collections::HashMap, time::Duration}; use serde::Deserialize; use tetra_core::ranges::SortedDisjointSsiRanges; @@ -19,8 +19,8 @@ pub struct CfgBrew { pub password: Option, /// ISSI to register with the TetraPack server pub issi: u32, - /// Reconnection delay in seconds - pub reconnect_delay_secs: u64, + /// Reconnection delay + pub reconnect_delay: Duration, /// Extra initial jitter playout delay in frames (added on top of adaptive baseline) pub jitter_initial_latency_frames: u8, @@ -84,7 +84,7 @@ pub fn apply_brew_patch(src: CfgBrewDto) -> CfgBrew { username: Some(src.username.to_string()), password: Some(src.password), issi: src.issi, - reconnect_delay_secs: src.reconnect_delay_secs, + reconnect_delay: Duration::from_secs(src.reconnect_delay_secs), jitter_initial_latency_frames: src.jitter_initial_latency_frames, whitelisted_ssi_ranges: whitelist, blacklisted_ssi_ranges: blacklist, diff --git a/crates/tetra-entities/src/brew/components/brew_routable.rs b/crates/tetra-entities/src/brew/components/brew_routable.rs index ebedb61..fb88342 100644 --- a/crates/tetra-entities/src/brew/components/brew_routable.rs +++ b/crates/tetra-entities/src/brew/components/brew_routable.rs @@ -1,8 +1,7 @@ -use tetra_config::SharedConfig; +use tetra_config::{SharedConfig, stack_config_brew::CfgBrew}; -use crate::brew::worker::BrewConfig; - -pub fn is_brew_routable(config: &SharedConfig, brew_config: &BrewConfig, ssi: u32) -> bool { +/// Determine if a given SSI should be routed over brew, or is restricted to local handling +pub fn is_brew_routable(config: &SharedConfig, brew_config: &CfgBrew, ssi: u32) -> bool { if ssi <= 90 { // Brew doesn't route 0..=90 return false; diff --git a/crates/tetra-entities/src/brew/entity.rs b/crates/tetra-entities/src/brew/entity.rs index f88893b..8485702 100644 --- a/crates/tetra-entities/src/brew/entity.rs +++ b/crates/tetra-entities/src/brew/entity.rs @@ -5,6 +5,7 @@ use std::thread; use std::time::{Duration, Instant}; use crossbeam_channel::{Receiver, Sender, unbounded}; +use tetra_config::stack_config_brew::CfgBrew; use uuid::Uuid; use crate::{MessageQueue, TetraEntityTrait}; @@ -13,7 +14,7 @@ use tetra_core::{Sap, TdmaTime, tetra_entities::TetraEntity}; use tetra_saps::control::brew::{BrewSubscriberAction, BrewSubscriberUpdate}; use tetra_saps::{SapMsg, SapMsgInner, control::call_control::CallControl, tmd::TmdCircuitDataReq}; -use super::worker::{BrewCommand, BrewConfig, BrewEvent, BrewWorker}; +use super::worker::{BrewCommand, BrewEvent, BrewWorker}; /// Hangtime before releasing group call circuit to allow reuse without re-signaling. const GROUP_CALL_HANGTIME: Duration = Duration::from_secs(1); @@ -227,7 +228,8 @@ impl VoiceJitterBuffer { pub struct BrewEntity { config: SharedConfig, - brew_config: BrewConfig, + /// Also contained in the SharedConfig, but kept for fast, convenient access + brew_config: CfgBrew, dltime: TdmaTime, @@ -259,13 +261,14 @@ pub struct BrewEntity { } impl BrewEntity { - pub fn new(config: SharedConfig, brew_config: BrewConfig) -> Self { + pub fn new(config: SharedConfig) -> Self { // Create channels let (event_sender, event_receiver) = unbounded::(); let (command_sender, command_receiver) = unbounded::(); // Spawn worker thread - let worker_config = brew_config.clone(); + let worker_config = config.config().as_ref().brew.clone().unwrap(); // Never fails + let entity_config = worker_config.clone(); let handle = thread::Builder::new() .name("brew-worker".to_string()) .spawn(move || { @@ -281,7 +284,7 @@ impl BrewEntity { Self { config, - brew_config, + brew_config: entity_config, dltime: TdmaTime::default(), event_receiver, command_sender, diff --git a/crates/tetra-entities/src/brew/worker.rs b/crates/tetra-entities/src/brew/worker.rs index 444a9cc..3f9c506 100644 --- a/crates/tetra-entities/src/brew/worker.rs +++ b/crates/tetra-entities/src/brew/worker.rs @@ -7,7 +7,7 @@ use std::sync::Arc; use std::time::{Duration, Instant}; use crossbeam_channel::{Receiver, Sender}; -use tetra_core::ranges::SortedDisjointSsiRanges; +use tetra_config::stack_config_brew::CfgBrew; use tungstenite::{Message, WebSocket, stream::MaybeTlsStream}; use uuid::Uuid; @@ -83,31 +83,6 @@ pub enum BrewCommand { Disconnect, } -// ─── Configuration ──────────────────────────────────────────────── - -#[derive(Debug, Clone)] -pub struct BrewConfig { - /// TetraPack server hostname or IP - pub host: String, - /// TetraPack server port - pub port: u16, - /// Use TLS (wss:// / https://) - pub tls: bool, - /// Optional username for HTTP Digest auth - pub username: Option, - /// Optional password for HTTP Digest auth - pub password: Option, - /// ISSI to register with the server - pub issi: u32, - /// Reconnection delay - pub reconnect_delay: Duration, - /// Extra initial jitter playout delay in frames (added on top of adaptive baseline) - pub jitter_initial_latency_frames: u8, - - pub whitelisted_ssi_ranges: Option, - pub blacklisted_ssi_ranges: Option, -} - // ─── TLS helper ────────────────────────────────────────────────── /// A stream that is either plain TCP or TLS-wrapped TCP @@ -254,7 +229,7 @@ fn build_digest_response( // ─── Worker ─────────────────────────────────────────────────────── pub struct BrewWorker { - config: BrewConfig, + config: CfgBrew, /// Send events to the BrewEntity event_sender: Sender, /// Receive commands from the BrewEntity @@ -264,7 +239,7 @@ pub struct BrewWorker { } impl BrewWorker { - pub fn new(config: BrewConfig, event_sender: Sender, command_receiver: Receiver) -> Self { + pub fn new(config: CfgBrew, event_sender: Sender, command_receiver: Receiver) -> Self { Self { config, event_sender,