Expand description
NetworkLayer for local BACnet packet assembly and dispatch.
The network layer wraps a transport and provides APDU-level send/receive by handling NPDU encoding/decoding. This is a non-router implementation: it does not forward messages between networks, but it can address remote devices through local routers via NPDU destination fields (DNET/DADR).
§Receive-queue admission
NetworkLayer and BACnetRouter use the
same drop-arriving policy for application delivery. Each receive queue holds
256 items. Admission never waits for a consumer and never evicts an older
queued item. NetworkLayer APDU and opted-in control queues have independent
capacities, so saturation of either does not stall admission to the other.
All router ports share one local APDU queue; its saturation does not stop
forwarding or inline network-message handling.
§Raw and tracked receivers
| Receiver kind | Entry points | Capacity | Per-source quota | Accounting |
|---|---|---|---|---|
| Raw APDU | NetworkLayer::start, BACnetRouter::start with RouterOptions::new | 256 | None | Full/Closed counted internally; no admission snapshot or depth/high-water tracking |
| Tracked APDU | NetworkLayer::start_with_admission, RouterOptions::track_admission | 256 | 16 queued APDUs per key, defined below | Exact depth/high-water and Full/fairness/Closed totals via AdmissionReceiver::counters |
| Raw control | NetworkLayer::enable_network_control_receiver, RouterOptions::network_control_receiver | 256, separate from APDUs | None | Full/Closed counted internally; no admission snapshot or depth/high-water tracking |
| Tracked control | NetworkLayer::enable_network_control_receiver_with_admission, RouterOptions::network_control_receiver_with_admission | 256, separate from APDUs | None | Exact depth/high-water and Full/Closed totals; fairness always zero |
Raw receivers remain tokio::sync::mpsc::Receiver; tracked receivers are the
additive AdmissionReceiver alternatives. APDU and control opt-ins are
independent. Routers process network messages inline; their control receiver
gets only the Reject-Message-To-Network messages addressed to the router
itself, and every closed admission attempt counts as Closed without
disabling the stream. priority_channel is not
used by these ingress paths.
§Source keys and drop precedence
Tracked APDU queues cap each key at 16 queued, unconsumed APDUs:
- NetworkLayer: the complete transport-native
ReceivedApdu::source_macbyte value. Its single transport needs no separate port key. - Router local delivery: (ingress port network number,
source_mac). Identical MAC bytes on different ports have separate quotas. Neither key uses routed NPDU SNET/SADR (source_network) or authenticates a peer.
Each successful recv or
try_recv releases a queue slot and, for
tracked APDUs, that key’s quota slot before returning the item. Retaining or
processing the returned item does not occupy either slot. Sixteen keys at
their quota fill the 256-item queue; a key below quota can still encounter
global Full. This is a queued-item cap, not a byte/rate limit or a delivery
guarantee. Raw receivers and control queues have no per-source quota.
Drop attribution is Closed > fairness > Full: closed admission wins; otherwise a tracked APDU whose key already holds 16 items is a fairness drop, even if the queue also holds 256 items; otherwise global saturation is Full. Only the winning reason is counted. Every admission drop releases the arriving item’s owned payload, metadata and any reply sender without sending reply bytes or generating a wire rejection. This does not suppress ordinary router forwarding/reject behavior or change transport no-reply handling.
§Close, drop, stop, and observation
Closing either receiver kind prevents further admission but retains queued items for draining. Dropping a receiver discards them and releases their payloads, metadata and reply senders without sending reply bytes. For tracked receivers, close preserves depth until dequeued; drop sets depth to zero. Neither operation resets high-water/drop totals, and discarding queued items is not an admission drop.
NetworkLayer ends its dispatcher on the first APDU admission attempt after that receiver closes/drops, also ending control delivery. A closed/dropped control receiver instead disables only that stream on the first subsequent control admission attempt. Later discarded controls (like controls received without either opt-in) are not admission attempts. Router forwarding and inline control handling continue after local delivery closes/drops; each subsequent local admission attempt is counted as Closed.
NetworkLayer::stop after start and BACnetRouter::stop
end dispatch without waiting for application queues to drain; queued items
remain drainable. Stopping is not an admission drop. An independently owned
QueueAdmissionCounters handle remains readable after the receiver, layer,
or router is dropped; it keeps accounting alive, not the channel or tasks.
snapshot is consistent for one queue,
not atomic across queues, and exposes counts only, not payloads, per-source
identities or per-source totals. Its three drop totals saturate at u64::MAX.
Structs§
- Admission
Receiver - Opt-in, one-consumer receiver with exact queue-depth accounting.
- Issued
Apdu - One APDU handed to a local-issuance send.
- Network
Layer - Non-router BACnet network layer.
- Queue
Admission Counters - Cloneable snapshot handle obtained from an
AdmissionReceiver. - Queue
Admission Snapshot - A consistent, count-only snapshot of one network-layer receive queue.
- Received
Apdu - A received APDU with source addressing information.
- Received
Network Control - A decoded network-layer control message received from a transport peer.
- Routed
Target - A remote device reached through a local router.