Skip to main content

bacnet_objects/network_port/
bip_config.rs

1//! Declared configuration for an unbound, flat application-level B/IP port.
2//! The B/IP mode is not configuration here: a registered owner publishes it.
3
4use crate::common;
5use bacnet_types::error::Error;
6
7/// Complete configured B/IP snapshot. Fixed-size addresses prevent malformed
8/// IPv4 values. Zero address/mask/gateway and one zero DNS address mean unknown
9/// or unconfigured; they do not describe an observed interface or route.
10#[derive(Clone, Debug, PartialEq, Eq)]
11pub struct BipPortConfig {
12    /// Caller-configured number; zero means unknown, 65535 is invalid.
13    pub network_number: u16,
14    /// Port APDU_Length (399), independent of Device Max_APDU_Length_Accepted.
15    /// Any Unsigned value >= 50 is permitted by the property clause.
16    pub apdu_length: u32,
17    /// Configured IPv4 address, in network byte order.
18    pub ip_address: [u8; 4],
19    /// Zero is allowed in this unbound configuration, independently of Port ID.
20    pub udp_port: u16,
21    /// Configured mask, with no assumed prefix or interface discovery.
22    pub subnet_mask: [u8; 4],
23    /// Configured gateway, with no assumed OS route.
24    pub default_gateway: [u8; 4],
25    /// At least one address; a zero address represents unavailable DNS.
26    pub dns_servers: Vec<[u8; 4]>,
27}
28
29impl Default for BipPortConfig {
30    fn default() -> Self {
31        Self {
32            network_number: 0,
33            // Declared B/IP capacity used by this library's transport profile.
34            // No active transport is discovered or verified by this object.
35            apdu_length: 1476,
36            ip_address: [0; 4],
37            udp_port: 47808,
38            subnet_mask: [0; 4],
39            default_gateway: [0; 4],
40            dns_servers: vec![[0; 4]],
41        }
42    }
43}
44
45impl BipPortConfig {
46    pub(super) fn validate(&self, instance: u32) -> Result<(), Error> {
47        // Local policy for the explicit flat B/IP application profile only.
48        if !(1..=255).contains(&instance)
49            || self.network_number == u16::MAX
50            || self.apdu_length < 50
51            || self.dns_servers.is_empty()
52        {
53            return Err(common::value_out_of_range_error());
54        }
55        Ok(())
56    }
57}