Add streaming IAm API with BVLL transport metadata - #3
Open
acedrew wants to merge 4 commits into
Open
Conversation
Introduces RequestTarget enum (Direct/Routed/ImplicitRouted) so all client service methods accept routed addresses via `impl Into<RequestTarget>`. Adds ClientRouterTable auto-populated from I-Am-Router-To-Network, with resolve_router() for automatic router discovery. Python bindings gain parse_target() supporting "network:mac" address format and a `router` keyword-only param on all 32 address-taking methods. Includes unit tests for parse_target and ClientRouterTable. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Two issues caused routed confirmed requests to time out: 1. The NPDU destination filter in layer.rs (line 143) discarded all non-broadcast messages with a DNET, including legitimate application- layer responses to our routed requests. Since network-layer messages are already handled earlier in the dispatch loop, the remaining messages are all APDUs — which should be accepted regardless of DNET, as a non-router can be the destination of a routed reply. 2. The non-BBMD FORWARDED_NPDU handler in bip.rs used the UDP sender address as source_mac instead of the originating IP from the BVLL header. When a response came through a BBMD relay, the source_mac wouldn't match the router_mac registered in the TSM, causing a correlation failure. Now uses originating_ip consistently with the BBMD code path. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add routed_test.rs: 8-test integration binary for campus simulator (router discovery, direct reads, routed reads to multiple networks, error round-trip, and implicit routing via auto-discovery) - Auto-resolve ImplicitRouted targets in confirmed_request() and unconfirmed_request() instead of requiring callers to pre-resolve Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds a broadcast channel for raw IAm events so downstream consumers can see every IAm as it arrives (including BBMD relay duplicates) with full BVLL context. This fixes the edge driver's inability to distinguish original vs forwarded IAms and its reliance on the last-write-wins device table. Transport layer: - Add TransportMeta struct (bvlc_function, forwarded_from_ip/port) - Populate in BIP transport at all 5 BVLL message handlers - Thread through ReceivedNpdu → ReceivedApdu → dispatch Client layer: - Add IAmEvent struct with IAm fields + BVLL metadata + timestamp - Add iam_tx broadcast channel (follows cov_tx pattern) - Send IAmEvent on every IAm, alongside existing device_table.upsert() - Add iam_events() public accessor Python bindings: - Add PyIAmEvent (frozen pyclass) and PyIAmEventIterator (async iter) - Add who_is_stream() — subscribe first, send WhoIs, return iterator - Add iam_events() — passive listener, no WhoIs sent - Add type stubs for all new types and methods Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
TransportMetastruct to carry BVLL framing context (function code, forwarded-from IP/port) through the transport → network → client pipelineIAmEventbroadcast channel so every IAm is streamed to consumers with full metadata, including BBMD relay duplicateswho_is_stream()(subscribe-then-WhoIs) andiam_events()(passive listener) in the Python bindingsThis fixes the downstream edge driver's inability to:
Changes by layer
port.rs,bip.rs,bip6.rs,mstp.rs,ethernet.rs,sc.rsTransportMetastruct + populate at allReceivedNpdusiteslayer.rs,router.rstransport_metathroughReceivedApduserver.rstransport_meta: Noneto fallback constructionsdiscovery.rs,client.rsIAmEventstruct,iam_txbroadcast channel,iam_events()accessortypes.rs,client.rs,rusty_bacnet.pyiPyIAmEvent,PyIAmEventIterator,who_is_stream(),iam_events(), type stubsTest plan
cargo check— full workspace compilescargo test— all 1703 existing tests pass (backward compatible)iam_events()withbvlc_function: Some(0x0b)async for event in await client.who_is_stream(): ...yieldsIAmEventwith expected fieldsforwarded_fromfields🤖 Generated with Claude Code