Skip to content
Version 6.1.0
Contact Us

Moving from MSTP.c

Before the removal of MSTP.c and MSTP.h (the stack’s C MS/TP engine), your application compiled source/MSTP.c, called MSTP_Init() and MSTP_Loop(), and bridged the engine to the stack with the per-port message callbacks. That is a breaking change for anything that compiled MSTP.c itself, such as the BACnetServerMSTPExampleCPP example or an application of yours. The Zephyr adapter in adapters/zephyr already uses the interface below. The engine now lives in the stack (source/BACnetMSTPEngine.cpp), one per port, and the same behaviour is behind a byte-level interface.

MSTP.c The stack now
MSTP_Init() with the callbacks and the station Register BACnetStack_RegisterCallbackMSTPReceiveBytes(), ...MSTPSendBytes() and ...MSTPMicroseconds() once, before or after you add the Network Port object. There is no init call. The engine starts on the first BACnetStack_Tick() after the port exists.
MSTP_SetBaudRate(), MSTP_SetMaxMaster(), mstp_settings.Nmax_info_frames, the station in MSTP_Init() The Network Port object’s Link_Speed, Max_Master, Max_Info_Frames and MAC_Address, served by your property callbacks. There are no setters.
mstp_RecvByte (one octet) CallbackMSTPReceiveBytes: copy every octet that is waiting, up to the size of the buffer, and return the count.
mstp_SendByte CallbackMSTPSendBytes: the same body. Return only after the last stop bit has left the transmitter.
mstp_Sleep, mstp_TimerReset, mstp_TimerDifference Delete all three. CallbackMSTPMicroseconds returns one monotonic microsecond clock that wraps at 2^32. The engine never sleeps.
mstp_RS485EnableTXDPin and MSTP_SetRS485EnableTXDPin() BACnetStack_RegisterCallbackMSTPTransmitEnable(), with the port instance as a first parameter.
mstp_FrameHeaderCallBack BACnetStack_RegisterCallbackMSTPFrameHeader(), or the counters.
mstp_EventLog, MSTP_DEBUG, MSTP_DEBUG_SPRINTF Gone.
mstp_APDUCallBack and your receive-message queue; MSTP_InsertFrameToSend() and your send-message callback Delete the queues and both callbacks. The stack queues outgoing NPDUs for the engine and takes received NPDUs from it, inside BACnetStack_Tick().
MSTP_Loop() BACnetStack_LoopMSTP(networkPortInstance). It may run on its own thread, with no lock shared with BACnetStack_Tick(). Start that thread after the Network Port object is added (the stack forbids adding or removing Network Port objects while another thread is inside the call); the Zephyr adapter’s cbz::mstp::Start() does so.
MSTP_IsConnected() The BACnetMSTPCounter_InTokenRing entry of BACnetStack_GetMSTPCounters().
MSTP_ReportReceiveError() BACnetStack_ReportMSTPReceiveError(networkPortInstance).

The sizes that MSTP.h defined as macros are constants of the engine class, in source/BACnetMSTPEngine.h:

Was (MSTP.h) Is Value
MSTP_MAX_PACKET_OCTETS CASBACnetStack::BACnetMSTPEngine::MAX_PACKET_OCTETS 501
MSTP_MAX_NPDU_OCTETS CASBACnetStack::BACnetMSTPEngine::MAX_NPDU_OCTETS 1497
MSTP_INPUT_BUFFER_SIZE CASBACnetStack::BACnetMSTPEngine::INPUT_BUFFER_SIZE 1508

They are plain enumerators, usable in array sizes, and exist when STACK_OPTION_DATA_LINK_LAYER_MSTP is on. The old -DMSTP_MAX_NPDU_OCTETS=501 option for saving memory has no equivalent: the engine’s buffers are a fixed size.

If you would rather keep your own engine, stay in packet mode: register no byte callbacks and keep the message callbacks as they were. Nothing else in the stack depended on MSTP.c.