BACnet Networking BACnet
BACnet Basics covered the object model and the services — how to read a property, write a priority-array slot, and discover devices on the same network. This page is the other half of the story: how devices on different networks find each other, why a normal Ethernet broadcast doesn't reach across a router, and what the BBMD and Foreign Device Registration machinery is actually doing. It also unpacks the EBO hex blob the BACnet/IP Hex Converter tool decodes for you — same string, but now you can see what each byte is doing.
Three addresses, one device
Every BACnet conversation eventually targets a specific property on a specific object on a specific device. The property and the object are application-layer concepts that BACnet Basics already covered; addressing the device takes three different identifiers, each at a different layer of the stack.
- Device instance number. A 22-bit unsigned
integer (range 0 to 4,194,302) that uniquely identifies a
controller across the entire BACnet internetwork. This is the
identifier the application layer speaks in —
device:1001is a device instance. It does not encode location or topology; two controllers physically on opposite sides of a building must still pick different instance numbers if both are visible to the same BMS. - Network number. A 16-bit integer that names
a BACnet network segment — a group of devices that
share a single data link (one MS/TP bus, or one BACnet/IP
UDP broadcast domain). Network number
0means "the local network — wherever this message originated";65535means "broadcast to every network." Useful network numbers are 1 to 65534, assigned by the system designer. The network-layer header on every BACnet message carries source and destination network numbers when a message crosses between networks. - MAC address. The data-link identifier that
a specific transport uses to deliver the message. On
BACnet/IP the MAC is six bytes: four bytes
of IPv4 address plus two bytes of UDP port (almost always
0xBAC0— 47808). On MS/TP the MAC is a single byte: the device's station address on the RS-485 bus, in the range 0 to 127.
A useful way to think about which layer to reach for: the device instance is what the BMS graphic remembers and what the sequence programs against; the network number is how a router decides which way to send the message; the MAC is how the cable, switch, or RS-485 chip actually delivers it. Change the network topology — a new BBMD, a re-IP, a moved controller — and the MAC and network numbers may shift, but a device's instance number is still the same instance number.
The BACnet/IP frame — BVLL + NPDU + APDU
When you put a Wireshark capture on a BACnet/IP segment, every BACnet message expands into three nested layers above the standard UDP/IP wrapping. From outside in:
- BVLL — BACnet Virtual Link Layer. A 4-byte
header that names what kind of BACnet/IP packet this is.
Byte 1 is always
0x81(the BVLL type marker for BACnet/IP). Byte 2 is the BVLL function — values like0x0Afor Original-Unicast-NPDU,0x0Bfor Original-Broadcast-NPDU, or0x04for Forwarded-NPDU (a broadcast a BBMD has unicast across to a peer). Bytes 3–4 are the total BVLL message length. A Forwarded-NPDU additionally carries the originating IP and port as the next six bytes, so the original source survives the forward. - NPDU — Network Protocol Data Unit. The BACnet network-layer header. Carries the version byte, a control byte (whose flags say whether destination / source / expecting-reply fields are present), and — when set — destination network number, destination MAC length and bytes, hop count, source network number, source MAC length and bytes. Local-network messages are short; cross-network messages carry the full address pair.
- APDU — Application Protocol Data Unit.
The actual service: a
ReadPropertyrequest, anI-Amannouncement, aSubscribeCOVmessage. The APDU's first byte encodes the PDU type (confirmed-request, unconfirmed- request, simple-ACK, complex-ACK, error, reject, abort) and segmentation flags; the rest is the encoded service parameters.
Most BACnet/IP traffic on a healthy network is
Original-Unicast-NPDU (a normal read or write to a
known device) or Original-Broadcast-NPDU (a Who-Is
or I-Am on the local segment). Forwarded-NPDU is the giveaway
that a BBMD is doing the work of carrying a broadcast somewhere
it wouldn't otherwise go — which is the next section.
BBMDs — broadcasts across an L3 boundary
BACnet uses broadcasts heavily — Who-Is, I-Am, the
Time-Synchronization service, COV notifications
to the network-broadcast address. On a single subnet that's
fine: UDP broadcasts are something every Ethernet switch
handles. But the moment two BACnet/IP devices sit on different
IP subnets — a router between them — the broadcast story
breaks. Routers, by design, do not forward UDP broadcasts.
Without help, a Who-Is from subnet A is invisible to every
device on subnet B.
The help is the BBMD — BACnet/IP Broadcast Management Device. A BBMD is just a BACnet/IP node (often a JACE, an EBO server, or a software service running on a controller) configured with a Broadcast Distribution Table — the BDT — that lists the IP addresses of peer BBMDs on other subnets. When the BBMD sees a local broadcast on its own subnet, it captures the message, wraps it in a Forwarded-NPDU BVLL header (so the original source IP and port survive), and unicasts a copy to each peer BBMD in its BDT. Each peer BBMD then re-broadcasts the message on its subnet, where local devices pick it up the normal way.
Two BBMDs is the simplest case. A real installation may have three, four, or a dozen — every subnet that hosts BACnet/IP devices and wants to participate in cross-network broadcasts needs one BBMD, with each BBMD's BDT carrying every other BBMD's IP. The BDTs must be kept symmetric: if BBMD A's BDT lists BBMD B but BBMD B's BDT does not list BBMD A, broadcasts from A reach B but the reverse silently fails. The asymmetric- BDT trap is one of the most common BBMD misconfigurations in the field.
One BBMD per subnet, no more. Two BBMDs on the same subnet create a broadcast loop — every Forwarded-NPDU arriving from a peer gets re-broadcast by both BBMDs, each of which the other captures and re-forwards. The condition produces a quiet but persistent storm that scales with the number of peers and is usually only noticed once a Wireshark capture makes the duplicate frames visible.
Foreign Device Registration — joining from outside
A BBMD handles broadcasts between subnets that each have their own BBMD. What about a device that sits on a subnet with no local BBMD — a laptop on a guest Wi-Fi, an engineering workstation tunneled in over a VPN, a remote monitoring server in another building? It can't hear local broadcasts on its own subnet (nobody on that subnet is speaking BACnet), and it has no local BBMD to forward through.
The answer is Foreign Device Registration.
The remote device sends a
Register-Foreign-Device BVLL message — a
unicast — to a BBMD it can reach on the BAS network. The
request carries a Time-to-Live: how long the
registration should stay valid (in seconds). The BBMD adds
an entry to its FDT — Foreign Device Table
with the remote device's IP, port, and TTL. From that
moment, every broadcast the BBMD would have re-broadcast
locally also gets unicast to the foreign device. The remote
gains broadcast visibility into the BAS network as if it
were locally attached, without needing its own BBMD.
The TTL is the catch. If the foreign device fails to send a
fresh Register-Foreign-Device before the previous
TTL expires, the BBMD silently drops the FDT entry and
broadcasts stop arriving — no error, no notification. The
remote tool just stops discovering. Most workstations and
engineering tools handle re-registration automatically, but
lab-built clients and ad-hoc scripts often don't, and a
forgotten TTL is a classic cause of "I could see this device
yesterday and now I can't."
Reading the hex blob EBO shows you
EBO and several other BAS workstations display a discovered BACnet/IP device address as a hex string rather than the dotted-decimal form. The string is just the device's MAC — the four-byte IPv4 address, optionally followed by the two-byte UDP port. Decoded:
The default port (0xBAC0 = 47808) is almost
always omitted from the displayed hex — an 8-character
string is normal, and any 12-character string ending in
BAC0 is the IP at the default port written
long-hand. A 12-character string ending in something else
(BAC1 = 47809, for example) means the device is
on a non-default BACnet/IP port, usually because someone
stood up a second logical BACnet/IP network on the same
host using ASHRAE 135 Annex J's sequential-port convention.
The BACnet/IP Hex Converter tool does the same decoding in both directions — paste a hex string from an EBO discovery dialog and read the IP + port back, or assemble the hex string from an IP and port to paste into a configuration field. The math is trivial; the tool exists so you don't lose flow context doing it by hand.
When discovery silently fails
BACnet has no "couldn't deliver" feedback for broadcasts. When discovery doesn't work, the symptom is almost always "I can't see a device I expect to see," with no error to grep for. The list below is what to check, in roughly the order it bites in the field:
- No BBMD on the remote subnet. The target device sits on a subnet with no BBMD configured at all. Local devices on that subnet see each other fine; cross-network discovery never reaches them. Stand up a BBMD on that subnet and add it to every peer's BDT.
- Asymmetric BDT. BBMD A lists B, but B's BDT doesn't list A. Discovery from A reaches B, but the I-Am reply doesn't make it back. Symmetric BDT entries are a deployment hygiene rule; every BBMD's BDT needs every other BBMD.
- Firewall blocks UDP 47808. A firewall rule (host-based on the BBMD, network ACL on the router, or a corporate edge filter) is dropping UDP 47808 between the subnets. Symptom: BBMDs are configured correctly but no Forwarded-NPDU ever arrives. Confirm with a Wireshark capture or by pinging UDP 47808 between the two BBMDs.
- Network-number collision. Two BACnet network segments routed together both claim the same network number. The network layer can't disambiguate; routers and BBMDs throw the message away or send it the wrong way. Every BACnet network in an internetwork needs a unique number.
- BBMD on the wrong VLAN. The BBMD's IP is on a different VLAN than the BACnet/IP devices it's supposed to serve. The BBMD captures nothing because it isn't actually on the broadcast domain. The fix is network plumbing: put the BBMD's NIC on the BAS VLAN, or trunk the VLAN to it.
- FDR TTL expired. A foreign-registered
workstation isn't re-sending
Register-Foreign-Deviceoften enough; the BBMD's FDT entry timed out. Most engineering tools handle this automatically; a custom client may not. Symptom: discovery works briefly after a re-connect, then stops. - Two BBMDs on one subnet. Someone added a second BBMD to a subnet that already had one. Every Forwarded-NPDU arriving from a peer gets re-broadcast by both — and each of those re-broadcasts gets captured by the other BBMD and forwarded again. A slow, expensive loop. One BBMD per subnet is the rule.
- Max APDU mismatch on segmented replies.
The client asks for a property whose value is too
large for a single APDU; the device tries to send a
segmented reply; segmentation is disabled or the
client's
Max APDUdoesn't match what the device announced in its I-Am. The exchange falls on the floor. Rare in everyday work, common when reading very large object-property lists from a Device object.
What this page didn't cover
Two pages on BACnet — one on the object model and services, one on addressing and networking — cover what most BMS techs need to read a point list, form a request, route a message across a router, and reason about why a device isn't showing up in a discovery scan. What's left, deliberately out of scope on this pair:
- MS/TP on the wire. Token rotation, the
master-token-passing mechanic,
Max_MasterandMax_Info_Frames, baud rates, the cable- length and device-count limits per segment. Now its own page: BACnet MS/TP. - Segmentation of long messages. When an APDU is too big for one frame, how segmentation breaks it up and how the receiver reassembles. Hinted at in the discovery-fails list above; a deeper treatment belongs on its own page.
- BACnet/SC — Secure Connect. The newer TLS-WebSocket transport. Different framing, different discovery (no broadcasts at all — hub-and-spoke), worth its own page once it's common enough in BAS work to justify the depth.
- Capture-driven troubleshooting. A Wireshark or Yabe walkthrough — what a Who-Is looks like in a capture, how to spot a Forwarded-NPDU, what an Abort or Reject PDU is telling you. Worth its own treatment given how often a capture is the fastest path to a root cause.
- Alarms and event notifications. The confirmed and unconfirmed alarm services, the Notification Class object, recipient lists, COV-style push for events. Their own page; touches BACnet's biggest object-model surface outside the analog/binary/multi-state core.
- Vendor profile differences. The practical reality that two BACnet devices, both advertising the same object types, may expose them with very different property sets and command behavior. Vendor-specific notes don't fit on a general education page; they belong on per-platform pages (Niagara, EBO, …) when those land.