Expand description
§bacnet-network
NPDU assembly, APDU dispatch and routing components for the
Rusty BACnet workspace.
layer::NetworkLayer wraps one transport and handles NPDU headers around APDUs.
It can address remote devices through a local router, but does not forward
between networks. router::BACnetRouter is the separate multi-port router.
This hosted crate requires std and Tokio.
§Quickstart from development source
This dependency block uses a checkout named rusty-bacnet beside your application
directory. It describes development source, not the contents of a published
crate version. Adjust the relative paths for another layout. Each crate used
by the example is a direct dependency, including the Tokio runtime and macros.
[dependencies]
bacnet-network = { path = "../rusty-bacnet/crates/bacnet-network" }
bacnet-transport = { path = "../rusty-bacnet/crates/bacnet-transport" }
bacnet-npdu = { path = "../rusty-bacnet/crates/bacnet-npdu" }
tokio = { version = "1", features = ["macros", "rt", "time"] }Send an APDU through two network layers connected by in-process loopback channels. The receiving layer removes the NPDU header and exposes the immediate source MAC. The timeout bounds the wait; no socket or device is opened.
use bacnet_network::layer::NetworkLayer;
use bacnet_transport::loopback::LoopbackTransport;
use bacnet_npdu::NetworkPriority;
use tokio::time::{timeout, Duration};
#[tokio::main(flavor = "current_thread")]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let (left_port, right_port) = LoopbackTransport::pair(vec![1], vec![2]);
let mut left = NetworkLayer::new(left_port);
let mut right = NetworkLayer::new(right_port);
let left_rx = left.start().await?;
let mut right_rx = right.start().await?;
let apdu = [0x10, 0x08];
left.send_apdu(&apdu, &[2], false, NetworkPriority::Normal)
.await?;
let received = timeout(Duration::from_secs(2), right_rx.recv())
.await?
.ok_or("network receive channel closed")?;
assert_eq!(received.apdu.as_ref(), &apdu);
assert_eq!(received.source_mac.as_ref(), &[1]);
assert!(received.source_network.is_none());
assert!(!received.link_layer_group);
left.stop().await?;
right.stop().await?;
drop((left_rx, right_rx));
Ok(())
}Both receivers returned by start stay owned until cleanup. Each network
layer’s stop ends and joins its dispatch task before stopping its transport.
Loopback always hands a send to its paired peer, regardless of destination MAC;
the example does not establish destination filtering. These assertions prove
local APDU delivery without a routed source. They do not demonstrate a remote
response, a completed BACnet transaction or forwarding between networks.
§API boundaries and features
layerowns single-transport NPDU processing, APDU delivery and optional network-control reception.start_with_admissionexposes receive-queue counters and the documented per-source admission policy.routerowns forwarding between configured ports and delivery to local endpoints. ItsBACnetRouter,RouterPortandRouterOptionstypes describe that lifecycle separately fromNetworkLayer.router.stop().awaitreturnsResult<(), RouterStopError>: success means router workers and each transport’s async cleanup have completed. A cancelled stop wait leaves cleanup running; subsequent calls replay the same result, including original transport errors inRouterStopError::failures(). Dropping a router or cancelling startup initiates cleanup on a live runtime, without an immediate resource-reuse guarantee. Awaited startup failure settles rollback for every attempted port; its original startup error takes precedence over logged cleanup failures.network_number,router_table,response_routeandpriority_channelprovide the associated state, captured reply routes and queue primitives.
This crate declares no optional features. Select an optional transport through
a direct bacnet-transport dependency; Cargo unifies that crate’s features.
Neither crate has a no_std or allocation-free hosted configuration. Physical
transport access, TLS configuration and hardware qualification are separate
from this channel-based quickstart.
§API documentation
This README is also the crate’s Rust documentation landing page. The docs.rs
profile disables implicit defaults, selects no additional features, and renders
only x86_64-unknown-linux-gnu. Its own network layer and router APIs are present
without enabling every optional transport. The underlying transport crate has
its own documentation profile. Local rendering checks documentation; it does
not establish a docs.rs deployment or physical-network interoperability.
Modules§
- layer
- NetworkLayer for local BACnet packet assembly and dispatch.
- network_
number - Shared packet contract for the two local nonrouter Network Number controls.
- priority_
channel - Priority-aware channel for BACnet NPDU dispatch (Clause 6.2.2).
- response_
route - Original-ingress authority for an application response.
- router
- BACnet half-router — forwards APDUs between BACnet networks.
- router_
table - The routing table a
BACnetRouterkeeps (Clause 6.6.1), which isbacnet-router-core’sTable(#1679).