Skip to content
Version 6.1.0
Contact Us

MS/TP Network Port object and settings

Create one Network Port object for the MS/TP port after BACnetStack_AddDevice():

DllExport 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);
  • networkType: 2 (BACnetNetworkType mstp).
  • protocolLevel: 2 (BACnetProtocolLevel bacnetApplication). It is the only level accepted for MS/TP.
  • networkNumber: the MS/TP network’s number, or 0 with quality 0 (unknown). 65535 is rejected.
  • networkNumberQuality: 0–3. Higher values are rejected.
  • referencePort: 4194303 (this is the lowest protocol layer).

The object then has Reference_Port, Max_Master, Max_Info_Frames, MAC_Address, Network_Number, Network_Number_Quality, APDU_Length, Command and Command_Validation_Result. The stack serves APDU_Length (480) itself. MAC_Address comes from your CallbackGetPropertyOctetString and must be exactly one octet. Return this node’s station address. A matching You-Are can assign a new MAC. It is held pending and passed to your CallbackSetPropertyOctetString when the pending Network Port changes are activated (ReinitializeDevice ACTIVATE_CHANGES or WARMSTART, or BACnetStack_ActivateNetworkPortPendingChanges()), so store it then and return it from CallbackGetPropertyOctetString from then on; the engine reads it again after the activation. This needs that callback and BACnetStack_RegisterCallbackReinitializeDevice().

When your start-up configuration is done, call BACnetStack_ActivateNetworkPortPendingChanges() so the device does not boot reporting Changes_Pending. For Changes_Pending, the Command property and ReinitializeDevice in general, see the Network Port objects and ReinitializeDevice chapters.

The stack makes both properties writable and checks every write:

Property Accepted values Rejected with
Max_Master 0–127 PROPERTY / VALUE_OUT_OF_RANGE
Max_Info_Frames 1–255 PROPERTY / VALUE_OUT_OF_RANGE

An accepted write is held pending. Until it is activated, Changes_Pending reads TRUE and a read returns the written value. On ReinitializeDevice ACTIVATE_CHANGES or WARMSTART, or on BACnetStack_ActivateNetworkPortPendingChanges(), the stack calls your CallbackSetPropertyUnsignedInteger with the new value. Store it so it survives a restart, and return it from your CallbackGetPropertyUnsignedInteger from then on: the engine reads Max_Master and Max_Info_Frames from that callback again after the activation, so there is nothing to apply to it yourself. At other times the stack reads the values in use from the same callback.

Max_Master and Max_Info_Frames are always writable. A client still needs a write service the device has enabled (WriteProperty or WritePropertyMultiple). In CASBACnetStackDLL.h the Max_Master property is called Max_Manager (BACnetPropertyIdentifier_maxManager, 64).

The engine’s timing values are fixed, except for the four the Network Port object supplies: the station (MAC_Address), Max_Master, Max_Info_Frames and the baud rate (Link_Speed). All times are whole milliseconds.

Setting Value Notes
Nmax_master 127 From Max_Master, range 0-127, never below this station.
Nmax_info_frames 1 From Max_Info_Frames: frames sent per token hold. Range 1-255.
Npoll 50 Tokens between Poll For Master cycles.
Nretry_token 1 Token retries.
Nmin_octets 4 Octets seen before the line counts as active.
Tno_token 500 Silence before the token is declared lost.
Treply_timeout 255 Wait for a reply to a Data Expecting Reply frame.
Tslot 10 Token-generation slot width.
Tusage_timeout 35 Wait for a successor to use the token. This engine uses 35 ms, the longest value BACnet allows.
Baud rate 38400 From Link_Speed.
Tframe_abort, Tturnaround, Tframe_gap, Tpostdrive from the baud rate See below.
Treply_delay 250 Deadline for the first octet of a reply or Reply Postponed. The engine decides at half of it.

The engine computes four timers from the bit time and rounds each up to a whole millisecond. Tturnaround is 40 bit times, Tframe_gap 20 and Tpostdrive 15, with a minimum of 1 ms each. Tframe_abort is 60 bit times multiplied by 10 and capped at 100 ms.

Baud Tframe_abort Tturnaround Tframe_gap Tpostdrive
9600 63 5 3 2
19200 32 3 2 1
38400 16 2 1 1
57600 11 1 1 1
76800 8 1 1 1
115200 6 1 1 1

Before sending, the engine waits until the line has been silent for Tturnaround. It does this by checking the clock on each call of BACnetStack_LoopMSTP(), not by sleeping.