bacnet_router_core/router/counters.rs
1//! What the router counts.
2
3/// Counts of what the router dropped, sent and was refused. They saturate,
4/// never change a decision, and name no peer. The table's own counts are
5/// [`Table::claim_counters`](crate::table::Table::claim_counters).
6///
7/// It is `#[non_exhaustive]`, so a new count isn't a breaking change.
8/// Outside this crate, build one from `Counters::default()` and set its
9/// fields.
10#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
11#[non_exhaustive]
12pub struct Counters {
13 /// Frames refused because the link source, the DLEN or the SLEN was
14 /// past [`MAX_MAC_LEN`](crate::MAX_MAC_LEN) (#1141, #1198).
15 pub address_length_drops: u64,
16 /// Frames dropped for a DADR beside DNET 0xFFFF (#1379).
17 pub global_broadcast_dadr_drops: u64,
18 /// Broadcasts dropped for carrying an APDU other than an
19 /// Unconfirmed-Request (#1491).
20 pub broadcast_pdu_type_drops: u64,
21 /// Frames dropped for a DADR that is a group address on its delivery
22 /// port: an APDU other than an Unconfirmed-Request, a network message,
23 /// or anything for a [`Group::Refuse`](super::Group::Refuse) address
24 /// (#1504, #1677). An Unconfirmed-Request sent as the port's broadcast
25 /// instead isn't counted.
26 pub group_dadr_drops: u64,
27 /// Frames that didn't parse as an NPDU for any other reason.
28 pub malformed: u64,
29 /// Network messages whose data or addressing the router refused.
30 pub bad_messages: u64,
31 /// Frames that came on a port the router doesn't have, or whose route
32 /// names one.
33 pub unknown_port: u64,
34 /// Relays not sent because the hop count had run out.
35 pub hop_count_drops: u64,
36 /// Protected network messages [`Host::authorize`](super::Host::authorize)
37 /// refused.
38 pub denied: u64,
39 /// Received rejects that were neither for this router nor routable.
40 pub unroutable_rejects: u64,
41 /// Rejects this router queued.
42 pub rejects: u64,
43 /// Who-Is-Router searches for unknown networks queued.
44 pub solicitations: u64,
45 /// Outputs that couldn't be written: longer than the scratch, or with
46 /// a field no NPDU may carry, such as an SNET of 0.
47 pub write_failures: u64,
48 /// Sends left out because their egress port can't carry them: by the
49 /// router's own check (R1), or refused by the port as too long.
50 pub egress_too_long: u64,
51 /// Sends the caller reported refused.
52 pub refused: u64,
53 /// Actions dropped because a call came before they were polled.
54 pub undrained: u64,
55}
56
57impl Counters {
58 /// All zero.
59 pub(super) const ZERO: Self = Self {
60 address_length_drops: 0,
61 global_broadcast_dadr_drops: 0,
62 broadcast_pdu_type_drops: 0,
63 group_dadr_drops: 0,
64 malformed: 0,
65 bad_messages: 0,
66 unknown_port: 0,
67 hop_count_drops: 0,
68 denied: 0,
69 unroutable_rejects: 0,
70 rejects: 0,
71 solicitations: 0,
72 write_failures: 0,
73 egress_too_long: 0,
74 refused: 0,
75 undrained: 0,
76 };
77}
78
79/// Add one to a count, saturating.
80pub(super) fn bump(count: &mut u64) {
81 *count = count.saturating_add(1);
82}