Skip to main content

bacnet_server/server/
atomic_write_file_budget.rs

1//! Local AtomicWriteFile payload admission, not backend allocation or file-size limits.
2use super::*;
3
4/// Positive payload limits independent of peer APDU size and segmentation.
5///
6/// Checked after existing validation and before the single storage write. Tags,
7/// headers, decoding, metadata hooks, and opaque backend/gap-fill work are excluded.
8#[derive(Clone, Copy, Debug, PartialEq, Eq)]
9pub struct AtomicWriteFileBudget {
10    /// Maximum stream payload octets (default 16384).
11    pub max_stream_payload_octets: usize,
12    /// Maximum records, including empty records (default 256).
13    pub max_records: usize,
14    /// Maximum sum of actual record payload lengths (default 16384).
15    pub max_record_payload_bytes: usize,
16}
17
18impl Default for AtomicWriteFileBudget {
19    fn default() -> Self {
20        Self {
21            max_stream_payload_octets: 16384,
22            max_records: 256,
23            max_record_payload_bytes: 16384,
24        }
25    }
26}
27
28impl AtomicWriteFileBudget {
29    /// Reject zero configuration before startup; empty requests remain permitted.
30    pub fn validate(&self) -> Result<(), Error> {
31        for (name, value) in [
32            (
33                "atomic_write_file_max_stream_payload_octets",
34                self.max_stream_payload_octets,
35            ),
36            ("atomic_write_file_max_records", self.max_records),
37            (
38                "atomic_write_file_max_record_payload_bytes",
39                self.max_record_payload_bytes,
40            ),
41        ] {
42            if value == 0 {
43                return Err(Error::Encoding(format!("{name} must be positive")));
44            }
45        }
46        Ok(())
47    }
48}
49
50impl<T: TransportPort + 'static> ServerBuilder<T> {
51    /// Set AtomicWriteFile payload limits, validated before transport startup.
52    pub fn atomic_write_file_budget(mut self, budget: AtomicWriteFileBudget) -> Self {
53        self.config.atomic_write_file_budget = budget;
54        self
55    }
56}
57impl BipServerBuilder {
58    /// Set AtomicWriteFile payload limits, validated before transport startup.
59    pub fn atomic_write_file_budget(mut self, budget: AtomicWriteFileBudget) -> Self {
60        self.config.atomic_write_file_budget = budget;
61        self
62    }
63}
64#[cfg(feature = "sc-tls")]
65impl ScServerBuilder {
66    /// Set AtomicWriteFile payload limits, validated before SC dialing.
67    pub fn atomic_write_file_budget(mut self, budget: AtomicWriteFileBudget) -> Self {
68        self.config.atomic_write_file_budget = budget;
69        self
70    }
71}