BACnet/IP
BACnet/IP carries BACnet messages in UDP datagrams. This chapter describes what your application provides for it, how to set up the IPv4 Network Port object, and the behaviour you need to know to write the transport code. BBMDs and foreign-device registration have their own chapter, BBMD and foreign devices. Writable Network Port properties and ReinitializeDevice are covered in Network Port objects and ReinitializeDevice.
The chapter has these pages:
- Sending and receiving: the two message callbacks, the connection string, broadcasts and the Network Port instance.
- Network Port object: the IPv4 Network Port object and the properties your callbacks serve.
- Example on GitHub: a complete BACnet/IP device to build and run.
- Practical notes: buffer sizes, threading, what Who-Is and I-Am look like, and what to check when nothing arrives.
What your application provides
Section titled “What your application provides”The stack opens no sockets. For BACnet/IP your application owns:
- One UDP socket per BACnet/IP port, bound to the BACnet UDP port. The conventional port is 47808 (0xBAC0); the stack does not choose it, your application does, and reports it through the Network Port object.
- The send callback, registered with
BACnetStack_RegisterCallbackSendMessageForPort(). The stack calls it with each outbound datagram. - The receive callback, registered with
BACnetStack_RegisterCallbackReceiveMessageForPort(). The stack calls it once perBACnetStack_Tick()to collect one inbound datagram. - The IP configuration (address, subnet mask, default gateway, UDP port), served through the property callbacks of the IPv4 Network Port object.
- A clock, through
BACnetStack_RegisterCallbackGetSystemTime(), if the device registers as a foreign device.
The stack builds and parses everything inside the datagram: the BACnet Virtual Link Layer (BVLL) header, the NPDU and the APDU. Your code moves whole datagrams between the socket and the stack.
Build option
Section titled “Build option”BACnet/IP is compiled in by STACK_OPTION_DATA_LINK_LAYER_IPV4. STACK_OPTION_ENABLE_ALL_DATA_LINK and
STACK_OPTION_TARGET_FULL turn it on for you. The IPv4 Network Port object also needs
STACK_OPTION_OBJECT_TYPE_NETWORK_PORT.
BACnet/SC cannot be built without BACnet/IP: CASBACnetStackOptions.h stops the build with an #error when
STACK_OPTION_DATA_LINK_LAYER_SC is defined without STACK_OPTION_DATA_LINK_LAYER_IPV4. A build that contains
BACnet/SC therefore always contains at least two data links. See Several data links.
The number of BACnet/IP Network Port objects one build can serve is STACK_OPTION_MAX_DATA_LINK_INSTANCES_IPV4: 1 by
default, 2 in a STACK_OPTION_TARGET_FULL build. Adding a BACnet/IP Network Port object beyond that limit fails and
logs a message naming the option.
Example on GitHub
Section titled “Example on GitHub”Chipkin keeps its examples on GitHub up to date with the stack, so this manual does not copy their code. For
BACnet/IP, start with BACnetProfileExample-B-SS-CPP, a BACnet Smart Sensor device that runs on Windows and
Linux. Its UDP socket is in common/SimpleUDP.cpp, and its send and receive
callbacks are in common/CASExampleHelper.cpp.
Related chapters
Section titled “Related chapters”- BBMD and foreign devices: broadcast distribution tables, BBMD mode and foreign-device registration.
- Network Port objects and ReinitializeDevice: writable Network Port properties, pending changes and ReinitializeDevice.
- BACnet/SC and MS/TP: the other data links.