Skip to content
Version 6.1.0
Contact Us

The IPv4 Network Port object

Every BACnet/IP port is described by a Network Port object. Add it after the device:

bool BACnetStack_AddNetworkPortObject(
const uint32_t deviceInstance,
const uint32_t objectInstance,
const uint8_t networkType,
const uint8_t protocolLevel,
const uint16_t networkNumber,
const uint8_t networkNumberQuality,
const uint32_t referencePort);
Parameter Value for a BACnet/IP port
deviceInstance The device added with BACnetStack_AddDevice().
objectInstance Any instance from 0 to 4194302. 4194303 is reserved and rejected. This is the value the message callbacks carry as networkPortInstance.
networkType 5 (ipv4, a BACnetNetworkType value).
protocolLevel 2 (bacnetApplication, a BACnetProtocolLevel value).
networkNumber The BACnet network number of this IP network, or 0 if you do not assign one.
networkNumberQuality 0 = unknown, 1 = learned, 2 = learned-configured, 3 = configured. Values above 3 are rejected. Pass 0 with a network number of 0.
referencePort 4194303, because a BACnet/IP port is the lowest protocol layer.

networkType 5 with protocolLevel 1 (protocol) creates an IP port without the BACnet/IP application properties. That is not a BACnet/IP data link; use 2.

For an IPv4 port at the BACnet application level the stack enables these properties and asks your property callbacks for their values:

Property Identifier Read through Value
IP_Address 400 CallbackGetPropertyOctetString 4 octets, for example C0 A8 01 05
IP_Subnet_Mask 411 CallbackGetPropertyOctetString 4 octets, for example FF FF FF 00
IP_Default_Gateway 401 CallbackGetPropertyOctetString 4 octets
BACnet_IP_UDP_Port 412 CallbackGetPropertyUnsignedInteger the UDP port, for example 47808
IP_DNS_Server 406 CallbackGetPropertyUnsignedInteger (element count at array index 0), then CallbackGetPropertyOctetString per element an array of 4-octet addresses
Link_Speed 420 CallbackGetPropertyReal bits per second

The property callbacks are called with object type 56 (Network Port) and the port’s instance. Return false for anything you do not serve. The stack derives MAC_Address from IP_Address and BACnet_IP_UDP_Port, and it cannot be overridden. APDU_Length is fixed at 1476 for an IPv4 port. BACnet_IP_Mode reads as NORMAL, BBMD after BACnetStack_SetBBMD(), and FOREIGN while the port is registered as a foreign device. The full property and callback table, including the foreign-device properties FD_BBMD_Address and FD_Subscription_Lifetime, is in the documentation of BACnetStack_AddNetworkPortObject() in source/CASBACnetStackDLL.h.

If a client may change these properties, make them writable with BACnetStack_SetPropertyWritable() and register the matching CallbackSetPropertyOctetString and CallbackSetPropertyUnsignedInteger (and CallbackSetPropertyBool for IP_DHCP_Enable), and CallbackReinitializeDevice. A written IP_Address, IP_Subnet_Mask, IP_Default_Gateway, IP_DHCP_Enable, BACnet_IP_UDP_Port, Link_Speed (CallbackSetPropertyReal), Link_Speed_Autonegotiate or an IP_DNS_Server element (CallbackSetPropertyOctetString, called with the element’s array index) is held pending: your Set callback is called when the change is activated (a ReinitializeDevice ACTIVATE_CHANGES or WARMSTART, or BACnetStack_ActivateNetworkPortPendingChanges()), not at the write. Without CallbackReinitializeDevice or the Set callback, the write is refused with Abort(other). Applying a new address to the socket is your application’s work. Pending changes and ReinitializeDevice are covered in Network Port objects and ReinitializeDevice.

Changes_Pending reads TRUE while a change is pending on the port, for example after a client writes Network_Number. Call BACnetStack_ActivateNetworkPortPendingChanges() once your start-up configuration is done so that the device does not boot with changes pending that nobody made over the network.

When the stack reads the port’s own address

Section titled “When the stack reads the port’s own address”

The stack reads IP_Address, BACnet_IP_UDP_Port and IP_Subnet_Mask through your callbacks, and records them as the port’s own address and subnet. It uses them to:

  • choose the port for a received datagram reported with BACNET_NETWORK_PORT_DEFAULT in a single-data-link build;
  • recognise its own broadcasts when it is a BBMD;
  • screen directed broadcasts in received Forwarded-NPDU messages.

It reads them when you add the Network Port object, and again whenever you register BACnetStack_RegisterCallbackGetPropertyOctetString() or BACnetStack_RegisterCallbackGetPropertyUnsignedInteger() once the octet-string callback is registered. So the order does not matter: register both callbacks before or after BACnetStack_AddNetworkPortObject(). If the read never succeeds, for example because a callback is missing or the port reported is 0, the port still works, but none of the above happens. To pick up an address that changed later, call BACnetStack_AddNetworkPortObject() again for that port.