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.
Properties your callbacks serve
Section titled “Properties your callbacks serve”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_DEFAULTin 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.