Files
bacnet_stack/test/bacnet/datalink/mstp/src/main.c
T
Steve Karg 1f591db6e7 Feature/mstp zero config option (#564)
* Added a MS/TP zero-config (automatically choose an unused MAC address) using an algorithm that starts with MAC=64 and waits for a random number of PFM (minimum of 8 plus modulo 64) before attempting to choose a MAC sequentially from 64..127. The confirmation uses a 128-bit UUID with the MSTP Test Request frame. The modifications are in src/bacnet/datalink/mstp.c and src/bacnet/datalink/dlmstp.c modules enabling any device to use zero-config if enabled. A working demonstration is in the ports/stm32f4xx for the NUCLEO board. Complete unit testing is included.  Options include lurking forever (wait for a router or another master node before joining) or lurking for a minimum time (enables self forming automatic MAC addressing device nodes).
2024-02-02 11:18:20 -06:00

1069 lines
42 KiB
C

/**
* @file
* @author Steve Karg <skarg@users.sourceforge.net>
* @brief test BACnet MSTP datalink state machines
*
* SPDX-License-Identifier: MIT
*/
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <zephyr/ztest.h>
#include <bacnet/bytes.h>
#include <bacnet/datalink/crc.h>
#include <bacnet/datalink/datalink.h>
#include <bacnet/datalink/mstp.h>
#include <bacnet/datalink/mstpdef.h>
#include <bacnet/datalink/mstptext.h>
#include <bacnet/datalink/crc.h>
#include <bacnet/basic/sys/fifo.h>
/**
* @addtogroup bacnet_tests
* @{
*/
#define INCREMENT_AND_LIMIT_UINT8(x) \
{ \
if ((x) < 0xFF) \
(x)++; \
}
static uint8_t RxBuffer[MAX_MPDU];
static uint8_t TxBuffer[MAX_MPDU];
/* test stub functions */
/**
* @brief Send a frame to the RS-485 network
* @param mstp_port port specific context data
* @param buffer pointer to the frame data
* @param nbytes number of bytes to send
*/
void RS485_Send_Frame(
struct mstp_port_struct_t *mstp_port, uint8_t *buffer, uint16_t nbytes)
{
(void)mstp_port;
(void)buffer;
(void)nbytes;
}
/* A data queue for the test */
FIFO_DATA_STORE(Test_Queue_Data, MAX_MPDU);
static FIFO_BUFFER Test_Queue;
/**
* @brief Load the input buffer with data
* @param buffer pointer to the data
* @param len number of bytes to load
*/
static void Load_Input_Buffer(uint8_t *buffer, size_t len)
{
static bool initialized = false; /* tracks our init */
if (!initialized) {
initialized = true;
FIFO_Init(&Test_Queue, Test_Queue_Data, MAX_MPDU);
}
/* empty any the existing data */
FIFO_Flush(&Test_Queue);
FIFO_Add(&Test_Queue, buffer, len);
}
/**
* @brief Check the UART for data
* @param mstp_port port specific context data
*/
void RS485_Check_UART_Data(struct mstp_port_struct_t *mstp_port)
{
if (!FIFO_Empty(&Test_Queue)) {
if (mstp_port) {
mstp_port->DataRegister = FIFO_Get(&Test_Queue);
mstp_port->DataAvailable = true;
}
}
}
/**
* @brief Store data about a RS-485 network received packet
* @param mstp_port port specific context data
*/
uint16_t MSTP_Put_Receive(struct mstp_port_struct_t *mstp_port)
{
return mstp_port->DataLength;
}
/**
* @brief MS/TP state machine calls this to get data to send
* @param mstp_port port specific context data
* @param timeout milliseconds to wait for a packet to send
* @return amount of PDU data
*/
uint16_t MSTP_Get_Send(struct mstp_port_struct_t *mstp_port, unsigned timeout)
{ /* milliseconds to wait for a packet */
return 0;
}
/**
* @brief MS/TP state machine calls this to get data to send
* @param mstp_port port specific context data
* @param timeout milliseconds to wait for a packet
* @return amount of PDU data
*/
uint16_t MSTP_Get_Reply(struct mstp_port_struct_t *mstp_port, unsigned timeout)
{ /* milliseconds to wait for a packet */
return 0;
}
/* track the RS485 line silence time in milliseconds */
uint32_t SilenceTime = 0;
/**
* @brief MS/TP state machine calls this to get the silence time
* @param pArg pointer to the port specific context data
* @return amount of time in milliseconds
*/
static uint32_t Timer_Silence(void *pArg)
{
(void)pArg;
return SilenceTime;
}
/**
* @brief MS/TP state machine calls this to reset the silence time
* @param pArg pointer to the port specific context data
*/
static void Timer_Silence_Reset(void *pArg)
{
(void)pArg;
SilenceTime = 0;
}
/**
* @brief MS/TP state machine calls this to send a frame
* @param mstp_port port specific context data
* @param buffer pointer to the frame data
* @param nbytes number of bytes to send
*/
void MSTP_Send_Frame(
struct mstp_port_struct_t *mstp_port, uint8_t *buffer, uint16_t nbytes)
{
if (mstp_port && mstp_port->OutputBuffer && buffer && (nbytes > 0) &&
(nbytes <= mstp_port->OutputBufferSize)) {
memcpy(mstp_port->OutputBuffer, buffer, nbytes);
}
}
static void testReceiveNodeFSM(void)
{
struct mstp_port_struct_t mstp_port; /* port data */
unsigned EventCount = 0; /* local counter */
uint8_t my_mac = 0x05; /* local MAC address */
uint8_t HeaderCRC = 0; /* for local CRC calculation */
uint8_t FrameType = 0; /* type of packet that was sent */
unsigned len; /* used for the size of the message packet */
size_t i; /* used to loop through the message bytes */
uint8_t buffer[MAX_MPDU] = { 0 };
uint8_t data[MAX_PDU] = { 0 };
uint8_t data_proprietary[MSTP_FRAME_NPDU_MAX] = { 0 };
mstp_port.InputBuffer = &RxBuffer[0];
mstp_port.InputBufferSize = sizeof(RxBuffer);
mstp_port.OutputBuffer = &TxBuffer[0];
mstp_port.OutputBufferSize = sizeof(TxBuffer);
mstp_port.SilenceTimer = Timer_Silence;
mstp_port.SilenceTimerReset = Timer_Silence_Reset;
mstp_port.This_Station = my_mac;
mstp_port.Nmax_info_frames = 1;
mstp_port.Nmax_master = 127;
MSTP_Init(&mstp_port);
/* check the receive error during idle */
mstp_port.receive_state = MSTP_RECEIVE_STATE_IDLE;
mstp_port.ReceiveError = true;
SilenceTime = 255;
mstp_port.EventCount = 0;
INCREMENT_AND_LIMIT_UINT8(EventCount);
MSTP_Receive_Frame_FSM(&mstp_port);
zassert_true(mstp_port.EventCount == EventCount, NULL);
zassert_true(mstp_port.SilenceTimer(&mstp_port) == 0, NULL);
zassert_true(mstp_port.ReceiveError == false, NULL);
zassert_true(mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE, NULL);
/* check for bad packet header */
mstp_port.DataAvailable = true;
mstp_port.DataRegister = 0x11;
INCREMENT_AND_LIMIT_UINT8(EventCount);
MSTP_Receive_Frame_FSM(&mstp_port);
zassert_true(mstp_port.DataAvailable == false, NULL);
zassert_true(mstp_port.SilenceTimer(&mstp_port) == 0, NULL);
zassert_true(mstp_port.EventCount == EventCount, NULL);
zassert_true(mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE, NULL);
/* check for good packet header, but timeout */
mstp_port.DataAvailable = true;
mstp_port.DataRegister = 0x55;
INCREMENT_AND_LIMIT_UINT8(EventCount);
MSTP_Receive_Frame_FSM(&mstp_port);
zassert_true(mstp_port.DataAvailable == false, NULL);
zassert_true(mstp_port.SilenceTimer(&mstp_port) == 0, NULL);
zassert_true(mstp_port.EventCount == EventCount, NULL);
zassert_true(mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE, NULL);
/* force the timeout */
SilenceTime = mstp_port.Tframe_abort + 1;
MSTP_Receive_Frame_FSM(&mstp_port);
zassert_true(mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE, NULL);
/* check for good packet header preamble, but receive error */
mstp_port.DataAvailable = true;
mstp_port.DataRegister = 0x55;
INCREMENT_AND_LIMIT_UINT8(EventCount);
MSTP_Receive_Frame_FSM(&mstp_port);
zassert_true(mstp_port.DataAvailable == false, NULL);
zassert_true(mstp_port.SilenceTimer(&mstp_port) == 0, NULL);
zassert_true(mstp_port.EventCount == EventCount, NULL);
zassert_true(mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE, NULL);
/* force the error */
mstp_port.ReceiveError = true;
INCREMENT_AND_LIMIT_UINT8(EventCount);
MSTP_Receive_Frame_FSM(&mstp_port);
zassert_true(mstp_port.ReceiveError == false, NULL);
zassert_true(mstp_port.SilenceTimer(&mstp_port) == 0, NULL);
zassert_true(mstp_port.EventCount == EventCount, NULL);
zassert_true(mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE, NULL);
/* check for good packet header preamble1, but bad preamble2 */
mstp_port.DataAvailable = true;
mstp_port.DataRegister = 0x55;
INCREMENT_AND_LIMIT_UINT8(EventCount);
MSTP_Receive_Frame_FSM(&mstp_port);
zassert_true(mstp_port.DataAvailable == false, NULL);
zassert_true(mstp_port.SilenceTimer(&mstp_port) == 0, NULL);
zassert_true(mstp_port.EventCount == EventCount, NULL);
zassert_true(mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE, NULL);
MSTP_Receive_Frame_FSM(&mstp_port);
/* no change of state if no data yet */
MSTP_Receive_Frame_FSM(&mstp_port);
zassert_true(mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE, NULL);
MSTP_Receive_Frame_FSM(&mstp_port);
zassert_true(mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE, NULL);
/* repeated preamble1 */
mstp_port.DataAvailable = true;
mstp_port.DataRegister = 0x55;
INCREMENT_AND_LIMIT_UINT8(EventCount);
MSTP_Receive_Frame_FSM(&mstp_port);
zassert_true(mstp_port.DataAvailable == false, NULL);
zassert_true(mstp_port.SilenceTimer(&mstp_port) == 0, NULL);
zassert_true(mstp_port.EventCount == EventCount, NULL);
zassert_true(mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE, NULL);
/* repeated preamble1 */
mstp_port.DataAvailable = true;
mstp_port.DataRegister = 0x55;
INCREMENT_AND_LIMIT_UINT8(EventCount);
MSTP_Receive_Frame_FSM(&mstp_port);
zassert_true(mstp_port.DataAvailable == false, NULL);
zassert_true(mstp_port.SilenceTimer(&mstp_port) == 0, NULL);
zassert_true(mstp_port.EventCount == EventCount, NULL);
zassert_true(mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE, NULL);
/* bad data */
mstp_port.DataAvailable = true;
mstp_port.DataRegister = 0x11;
INCREMENT_AND_LIMIT_UINT8(EventCount);
MSTP_Receive_Frame_FSM(&mstp_port);
zassert_true(mstp_port.ReceiveError == false, NULL);
zassert_true(mstp_port.SilenceTimer(&mstp_port) == 0, NULL);
zassert_true(mstp_port.EventCount == EventCount, NULL);
zassert_true(mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE, NULL);
/* check for good packet header preamble, but timeout in packet */
mstp_port.DataAvailable = true;
mstp_port.DataRegister = 0x55;
INCREMENT_AND_LIMIT_UINT8(EventCount);
MSTP_Receive_Frame_FSM(&mstp_port);
zassert_true(mstp_port.DataAvailable == false, NULL);
zassert_true(mstp_port.SilenceTimer(&mstp_port) == 0, NULL);
zassert_true(mstp_port.EventCount == EventCount, NULL);
zassert_true(mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE, NULL);
MSTP_Receive_Frame_FSM(&mstp_port);
/* preamble2 */
mstp_port.DataAvailable = true;
mstp_port.DataRegister = 0xFF;
INCREMENT_AND_LIMIT_UINT8(EventCount);
MSTP_Receive_Frame_FSM(&mstp_port);
zassert_true(mstp_port.DataAvailable == false, NULL);
zassert_true(mstp_port.SilenceTimer(&mstp_port) == 0, NULL);
zassert_true(mstp_port.EventCount == EventCount, NULL);
zassert_true(mstp_port.Index == 0, NULL);
zassert_true(mstp_port.HeaderCRC == 0xFF, NULL);
zassert_true(mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER, NULL);
/* force the timeout */
SilenceTime = mstp_port.Tframe_abort + 1;
MSTP_Receive_Frame_FSM(&mstp_port);
zassert_true(mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE, NULL);
zassert_true(mstp_port.ReceivedInvalidFrame == true, NULL);
/* check for good packet header preamble, but error in packet */
mstp_port.DataAvailable = true;
mstp_port.DataRegister = 0x55;
INCREMENT_AND_LIMIT_UINT8(EventCount);
MSTP_Receive_Frame_FSM(&mstp_port);
zassert_true(mstp_port.DataAvailable == false, NULL);
zassert_true(mstp_port.SilenceTimer(&mstp_port) == 0, NULL);
zassert_true(mstp_port.EventCount == EventCount, NULL);
zassert_true(mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE, NULL);
MSTP_Receive_Frame_FSM(&mstp_port);
/* preamble2 */
mstp_port.DataAvailable = true;
mstp_port.DataRegister = 0xFF;
INCREMENT_AND_LIMIT_UINT8(EventCount);
MSTP_Receive_Frame_FSM(&mstp_port);
zassert_true(mstp_port.DataAvailable == false, NULL);
zassert_true(mstp_port.SilenceTimer(&mstp_port) == 0, NULL);
zassert_true(mstp_port.EventCount == EventCount, NULL);
zassert_true(mstp_port.Index == 0, NULL);
zassert_true(mstp_port.HeaderCRC == 0xFF, NULL);
zassert_true(mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER, NULL);
/* force the error */
mstp_port.ReceiveError = true;
INCREMENT_AND_LIMIT_UINT8(EventCount);
MSTP_Receive_Frame_FSM(&mstp_port);
zassert_true(mstp_port.ReceiveError == false, NULL);
zassert_true(mstp_port.SilenceTimer(&mstp_port) == 0, NULL);
zassert_true(mstp_port.EventCount == EventCount, NULL);
zassert_true(mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE, NULL);
/* check for good packet header preamble */
mstp_port.DataAvailable = true;
mstp_port.DataRegister = 0x55;
INCREMENT_AND_LIMIT_UINT8(EventCount);
MSTP_Receive_Frame_FSM(&mstp_port);
zassert_true(mstp_port.DataAvailable == false, NULL);
zassert_true(mstp_port.SilenceTimer(&mstp_port) == 0, NULL);
zassert_true(mstp_port.EventCount == EventCount, NULL);
zassert_true(mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE, NULL);
MSTP_Receive_Frame_FSM(&mstp_port);
/* preamble2 */
mstp_port.DataAvailable = true;
mstp_port.DataRegister = 0xFF;
INCREMENT_AND_LIMIT_UINT8(EventCount);
MSTP_Receive_Frame_FSM(&mstp_port);
zassert_true(mstp_port.DataAvailable == false, NULL);
zassert_true(mstp_port.SilenceTimer(&mstp_port) == 0, NULL);
zassert_true(mstp_port.EventCount == EventCount, NULL);
zassert_true(mstp_port.Index == 0, NULL);
zassert_true(mstp_port.HeaderCRC == 0xFF, NULL);
zassert_true(mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER, NULL);
/* no change of state if no data yet */
MSTP_Receive_Frame_FSM(&mstp_port);
zassert_true(mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER, NULL);
MSTP_Receive_Frame_FSM(&mstp_port);
zassert_true(mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER, NULL);
/* Data is received - index is incremented */
/* FrameType */
mstp_port.DataAvailable = true;
mstp_port.DataRegister = FRAME_TYPE_TOKEN;
HeaderCRC = 0xFF;
HeaderCRC = CRC_Calc_Header(mstp_port.DataRegister, HeaderCRC);
INCREMENT_AND_LIMIT_UINT8(EventCount);
MSTP_Receive_Frame_FSM(&mstp_port);
zassert_true(mstp_port.DataAvailable == false, NULL);
zassert_true(mstp_port.SilenceTimer(&mstp_port) == 0, NULL);
zassert_true(mstp_port.EventCount == EventCount, NULL);
zassert_true(mstp_port.Index == 1, NULL);
zassert_true(mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER, NULL);
zassert_true(FrameType == FRAME_TYPE_TOKEN, NULL);
/* Destination */
mstp_port.DataAvailable = true;
mstp_port.DataRegister = 0x10;
HeaderCRC = CRC_Calc_Header(mstp_port.DataRegister, HeaderCRC);
INCREMENT_AND_LIMIT_UINT8(EventCount);
MSTP_Receive_Frame_FSM(&mstp_port);
zassert_true(mstp_port.DataAvailable == false, NULL);
zassert_true(mstp_port.SilenceTimer(&mstp_port) == 0, NULL);
zassert_true(mstp_port.EventCount == EventCount, NULL);
zassert_true(mstp_port.Index == 2, NULL);
zassert_true(mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER, NULL);
zassert_true(mstp_port.DestinationAddress == 0x10, NULL);
/* Source */
mstp_port.DataAvailable = true;
mstp_port.DataRegister = my_mac;
HeaderCRC = CRC_Calc_Header(mstp_port.DataRegister, HeaderCRC);
INCREMENT_AND_LIMIT_UINT8(EventCount);
MSTP_Receive_Frame_FSM(&mstp_port);
zassert_true(mstp_port.DataAvailable == false, NULL);
zassert_true(mstp_port.SilenceTimer(&mstp_port) == 0, NULL);
zassert_true(mstp_port.EventCount == EventCount, NULL);
zassert_true(mstp_port.Index == 3, NULL);
zassert_true(mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER, NULL);
zassert_true(mstp_port.SourceAddress == my_mac, NULL);
/* Length1 = length*256 */
mstp_port.DataAvailable = true;
mstp_port.DataRegister = 0;
HeaderCRC = CRC_Calc_Header(mstp_port.DataRegister, HeaderCRC);
INCREMENT_AND_LIMIT_UINT8(EventCount);
MSTP_Receive_Frame_FSM(&mstp_port);
zassert_true(mstp_port.DataAvailable == false, NULL);
zassert_true(mstp_port.SilenceTimer(&mstp_port) == 0, NULL);
zassert_true(mstp_port.EventCount == EventCount, NULL);
zassert_true(mstp_port.Index == 4, NULL);
zassert_true(mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER, NULL);
zassert_true(mstp_port.DataLength == 0, NULL);
/* Length2 */
mstp_port.DataAvailable = true;
mstp_port.DataRegister = 0;
HeaderCRC = CRC_Calc_Header(mstp_port.DataRegister, HeaderCRC);
INCREMENT_AND_LIMIT_UINT8(EventCount);
MSTP_Receive_Frame_FSM(&mstp_port);
zassert_true(mstp_port.DataAvailable == false, NULL);
zassert_true(mstp_port.SilenceTimer(&mstp_port) == 0, NULL);
zassert_true(mstp_port.EventCount == EventCount, NULL);
zassert_true(mstp_port.Index == 5, NULL);
zassert_true(mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER, NULL);
zassert_true(mstp_port.DataLength == 0, NULL);
/* HeaderCRC */
mstp_port.DataAvailable = true;
zassert_true(HeaderCRC == 0x73, NULL); /* per Annex G example */
mstp_port.DataRegister = ~HeaderCRC; /* one's compliment of CRC is sent */
INCREMENT_AND_LIMIT_UINT8(EventCount);
MSTP_Receive_Frame_FSM(&mstp_port);
zassert_true(mstp_port.DataAvailable == false, NULL);
zassert_true(mstp_port.SilenceTimer(&mstp_port) == 0, NULL);
zassert_true(mstp_port.EventCount == EventCount, NULL);
zassert_true(mstp_port.Index == 5, NULL);
zassert_true(mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE, NULL);
zassert_true(mstp_port.HeaderCRC == 0x55, NULL);
/* BadCRC in header check */
mstp_port.ReceivedInvalidFrame = false;
mstp_port.ReceivedValidFrame = false;
len = MSTP_Create_Frame(buffer, sizeof(buffer), FRAME_TYPE_TOKEN,
0x10, /* destination */
my_mac, /* source */
NULL, /* data */
0); /* data size */
zassert_true(len > 0, NULL);
/* make the header CRC bad */
buffer[7] = 0x00;
Load_Input_Buffer(buffer, len);
for (i = 0; i < len; i++) {
RS485_Check_UART_Data(&mstp_port);
INCREMENT_AND_LIMIT_UINT8(EventCount);
MSTP_Receive_Frame_FSM(&mstp_port);
zassert_true(mstp_port.DataAvailable == false, NULL);
zassert_true(mstp_port.SilenceTimer(&mstp_port) == 0, NULL);
zassert_true(mstp_port.EventCount == EventCount, "i=%u %u!=%u len=%u",
i, mstp_port.EventCount, EventCount, len);
}
zassert_true(mstp_port.ReceivedInvalidFrame == true, NULL);
zassert_true(mstp_port.ReceivedValidFrame == false, NULL);
zassert_true(mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE, NULL);
/* NoData for us */
mstp_port.ReceivedInvalidFrame = false;
mstp_port.ReceivedValidFrame = false;
len = MSTP_Create_Frame(buffer, sizeof(buffer), FRAME_TYPE_TOKEN,
my_mac, /* destination */
my_mac, /* source */
NULL, /* data */
0); /* data size */
zassert_true(len > 0, NULL);
Load_Input_Buffer(buffer, len);
for (i = 0; i < len; i++) {
RS485_Check_UART_Data(&mstp_port);
INCREMENT_AND_LIMIT_UINT8(EventCount);
MSTP_Receive_Frame_FSM(&mstp_port);
zassert_true(mstp_port.DataAvailable == false, NULL);
zassert_true(mstp_port.SilenceTimer(&mstp_port) == 0, NULL);
zassert_true(mstp_port.EventCount == EventCount, NULL);
}
zassert_true(mstp_port.ReceivedInvalidFrame == false, NULL);
zassert_true(mstp_port.ReceivedValidFrame == true, NULL);
zassert_true(mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE, NULL);
/* FrameTooLong */
mstp_port.ReceivedInvalidFrame = false;
mstp_port.ReceivedValidFrame = false;
len = MSTP_Create_Frame(buffer, sizeof(buffer), FRAME_TYPE_TOKEN,
my_mac, /* destination */
my_mac, /* source */
NULL, /* data */
0); /* data size */
zassert_true(len > 0, NULL);
/* make the header data length bad */
buffer[5] = 0x02;
Load_Input_Buffer(buffer, len);
for (i = 0; i < len; i++) {
RS485_Check_UART_Data(&mstp_port);
INCREMENT_AND_LIMIT_UINT8(EventCount);
MSTP_Receive_Frame_FSM(&mstp_port);
zassert_true(mstp_port.DataAvailable == false, NULL);
zassert_true(mstp_port.SilenceTimer(&mstp_port) == 0, NULL);
zassert_true(mstp_port.EventCount == EventCount, NULL);
}
zassert_true(mstp_port.ReceivedInvalidFrame == true, NULL);
zassert_true(mstp_port.ReceivedValidFrame == false, NULL);
zassert_true(mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE, NULL);
/* Proprietary Data */
mstp_port.ReceivedInvalidFrame = false;
mstp_port.ReceivedValidFrame = false;
memset(data_proprietary, 0, sizeof(data_proprietary));
len = MSTP_Create_Frame(buffer, sizeof(buffer), FRAME_TYPE_PROPRIETARY_MIN,
my_mac, my_mac, data_proprietary, sizeof(data_proprietary));
zassert_true(len > 0, NULL);
Load_Input_Buffer(buffer, len);
RS485_Check_UART_Data(&mstp_port);
MSTP_Receive_Frame_FSM(&mstp_port);
while (mstp_port.receive_state != MSTP_RECEIVE_STATE_IDLE) {
RS485_Check_UART_Data(&mstp_port);
MSTP_Receive_Frame_FSM(&mstp_port);
}
zassert_true(mstp_port.DataLength == sizeof(data_proprietary), NULL);
zassert_true(mstp_port.ReceivedInvalidFrame == false, NULL);
zassert_true(mstp_port.ReceivedValidFrame == true, NULL);
zassert_true(mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE, NULL);
return;
}
static void testMasterNodeFSM(void)
{
struct mstp_port_struct_t MSTP_Port; /* port data */
uint8_t my_mac = 0x05; /* local MAC address */
MSTP_Port.InputBuffer = &RxBuffer[0];
MSTP_Port.InputBufferSize = sizeof(RxBuffer);
MSTP_Port.OutputBuffer = &TxBuffer[0];
MSTP_Port.OutputBufferSize = sizeof(TxBuffer);
MSTP_Port.Nmax_info_frames = 1;
MSTP_Port.Nmax_master = 127;
MSTP_Port.Tframe_abort = DEFAULT_Tframe_abort;
MSTP_Port.Treply_delay = DEFAULT_Treply_delay;
MSTP_Port.Treply_timeout = DEFAULT_Treply_timeout;
MSTP_Port.Tusage_timeout = DEFAULT_Tusage_timeout;
MSTP_Port.SilenceTimer = Timer_Silence;
MSTP_Port.SilenceTimerReset = Timer_Silence_Reset;
MSTP_Port.This_Station = my_mac;
MSTP_Init(&MSTP_Port);
zassert_true(MSTP_Port.master_state == MSTP_MASTER_STATE_INITIALIZE, NULL);
/* FIXME: write a unit test for the Master Node State Machine */
}
static void testSlaveNodeFSM(void)
{
struct mstp_port_struct_t MSTP_Port = { 0 }; /* port data */
bool transition_now, non_zero;
unsigned slots, silence, i;
MSTP_Port.InputBuffer = &RxBuffer[0];
MSTP_Port.InputBufferSize = sizeof(RxBuffer);
MSTP_Port.OutputBuffer = &TxBuffer[0];
MSTP_Port.OutputBufferSize = sizeof(TxBuffer);
MSTP_Port.Nmax_info_frames = 0;
MSTP_Port.Nmax_master = 0;
MSTP_Port.Tframe_abort = DEFAULT_Tframe_abort;
MSTP_Port.Treply_delay = DEFAULT_Treply_delay;
MSTP_Port.Treply_timeout = DEFAULT_Treply_timeout;
MSTP_Port.Tusage_timeout = DEFAULT_Tusage_timeout;
MSTP_Port.SilenceTimer = Timer_Silence;
MSTP_Port.SilenceTimerReset = Timer_Silence_Reset;
MSTP_Port.This_Station = 128;
MSTP_Init(&MSTP_Port);
MSTP_Slave_Node_FSM(&MSTP_Port);
zassert_true(MSTP_Port.master_state == MSTP_MASTER_STATE_IDLE, NULL);
}
static void testZeroConfigNode_Init(struct mstp_port_struct_t *mstp_port)
{
bool transition_now, non_zero;
unsigned slots, silence, i;
mstp_port->InputBuffer = &RxBuffer[0];
mstp_port->InputBufferSize = sizeof(RxBuffer);
mstp_port->OutputBuffer = &TxBuffer[0];
mstp_port->OutputBufferSize = sizeof(TxBuffer);
mstp_port->Nmax_info_frames = 1;
mstp_port->Nmax_master = 127;
mstp_port->Tframe_abort = DEFAULT_Tframe_abort;
mstp_port->Treply_delay = DEFAULT_Treply_delay;
mstp_port->Treply_timeout = DEFAULT_Treply_timeout;
mstp_port->Tusage_timeout = DEFAULT_Tusage_timeout;
mstp_port->SilenceTimer = Timer_Silence;
mstp_port->SilenceTimerReset = Timer_Silence_Reset;
/* configure for Zero Config */
mstp_port->ZeroConfigEnabled = true;
mstp_port->This_Station = 255;
MSTP_Init(mstp_port);
zassert_true(mstp_port->master_state == MSTP_MASTER_STATE_INITIALIZE, NULL);
zassert_true(
mstp_port->Zero_Config_State == MSTP_ZERO_CONFIG_STATE_INIT, NULL);
zassert_true(mstp_port->Tframe_abort == DEFAULT_Tframe_abort, NULL);
zassert_true(mstp_port->Treply_delay == DEFAULT_Treply_delay, NULL);
zassert_true(mstp_port->Treply_timeout == DEFAULT_Treply_timeout, NULL);
zassert_true(mstp_port->Tusage_timeout == DEFAULT_Tusage_timeout, NULL);
transition_now = MSTP_Master_Node_FSM(mstp_port);
zassert_false(transition_now, NULL);
zassert_true(
mstp_port->Zero_Config_State == MSTP_ZERO_CONFIG_STATE_IDLE, NULL);
zassert_true(mstp_port->Poll_Count == 0, NULL);
zassert_true(mstp_port->Zero_Config_Station == 64, NULL);
zassert_true(mstp_port->Npoll_slot >= 1, NULL);
zassert_true(mstp_port->Npoll_slot <= 64, NULL);
slots = 128 + mstp_port->Npoll_slot;
silence = Tno_token + Tslot * slots;
zassert_true(mstp_port->Zero_Config_Silence == silence, NULL);
non_zero = false;
for (i = 0; i < MSTP_UUID_SIZE; i++) {
if (mstp_port->UUID[i] > 0) {
non_zero = true;
}
}
zassert_true(non_zero, NULL);
zassert_true(mstp_port->Zero_Config_Max_Master == 0, NULL);
}
static void testZeroConfigNode_No_Events_Timeout(
struct mstp_port_struct_t *mstp_port)
{
bool transition_now, non_zero;
unsigned slots, silence, i;
SilenceTime = mstp_port->Zero_Config_Silence + 1;
transition_now = MSTP_Master_Node_FSM(mstp_port);
zassert_false(transition_now, NULL);
zassert_true(
mstp_port->Zero_Config_State == MSTP_ZERO_CONFIG_STATE_CONFIRM, NULL);
}
static void testZeroConfigNode_Test_Request_Unsupported(
struct mstp_port_struct_t *mstp_port)
{
bool transition_now, non_zero;
unsigned slots, silence, i;
/* test case: remote node does not support Test-Request; timeout */
SilenceTime = mstp_port->Treply_timeout + 1;
transition_now = MSTP_Master_Node_FSM(mstp_port);
zassert_true(transition_now, NULL);
zassert_true(
mstp_port->Zero_Config_State == MSTP_ZERO_CONFIG_STATE_USE, NULL);
zassert_true(
mstp_port->This_Station == mstp_port->Zero_Config_Station, NULL);
}
static void testZeroConfigNode_Test_Request_Supported(
struct mstp_port_struct_t *mstp_port)
{
bool transition_now, non_zero;
unsigned slots, silence, i;
/* test case: remote node supports Test-Request */
SilenceTime = 0;
mstp_port->DestinationAddress = mstp_port->Zero_Config_Station;
mstp_port->SourceAddress = 0;
mstp_port->FrameType = FRAME_TYPE_TEST_RESPONSE;
transition_now = MSTP_Master_Node_FSM(mstp_port);
zassert_true(transition_now, NULL);
zassert_true(
mstp_port->Zero_Config_State == MSTP_ZERO_CONFIG_STATE_USE, NULL);
zassert_true(
mstp_port->This_Station == mstp_port->Zero_Config_Station, NULL);
}
static void testZeroConfigNode_Test_IDLE_InvalidFrame(
struct mstp_port_struct_t *mstp_port)
{
bool transition_now, non_zero;
unsigned slots, silence, i;
/* test case: waiting for a invalid frame */
SilenceTime = 0;
mstp_port->ReceivedInvalidFrame = true;
transition_now = MSTP_Master_Node_FSM(mstp_port);
zassert_false(transition_now, NULL);
zassert_true(
mstp_port->Zero_Config_State == MSTP_ZERO_CONFIG_STATE_IDLE, NULL);
zassert_true(mstp_port->ReceivedInvalidFrame == false, NULL);
transition_now = MSTP_Master_Node_FSM(mstp_port);
zassert_false(transition_now, NULL);
zassert_true(
mstp_port->Zero_Config_State == MSTP_ZERO_CONFIG_STATE_IDLE, NULL);
zassert_true(mstp_port->ReceivedInvalidFrame == false, NULL);
}
static void testZeroConfigNode_Test_IDLE_ValidFrameTimeout(
struct mstp_port_struct_t *mstp_port)
{
bool transition_now, non_zero;
unsigned slots, silence, i;
/* test case: get a valid frame, followed by timeout */
SilenceTime = 0;
mstp_port->SourceAddress = 0;
mstp_port->DestinationAddress = 1;
mstp_port->ReceivedValidFrame = true;
transition_now = MSTP_Master_Node_FSM(mstp_port);
zassert_false(transition_now, NULL);
zassert_true(
mstp_port->Zero_Config_State == MSTP_ZERO_CONFIG_STATE_LURK, NULL);
zassert_true(mstp_port->ReceivedValidFrame == true, NULL);
transition_now = MSTP_Master_Node_FSM(mstp_port);
zassert_false(transition_now, NULL);
zassert_true(
mstp_port->Zero_Config_State == MSTP_ZERO_CONFIG_STATE_LURK, NULL);
zassert_true(mstp_port->ReceivedValidFrame == false, NULL);
SilenceTime = mstp_port->Zero_Config_Silence + 1;
transition_now = MSTP_Master_Node_FSM(mstp_port);
zassert_false(transition_now, NULL);
zassert_true(
mstp_port->Zero_Config_State == MSTP_ZERO_CONFIG_STATE_IDLE, NULL);
}
static void testZeroConfigNode_Test_IDLE_ValidFrame(
struct mstp_port_struct_t *mstp_port)
{
bool transition_now, non_zero;
unsigned slots, silence, i;
/* test case: get a valid frame, followed by timeout */
SilenceTime = 0;
mstp_port->SourceAddress = 0;
mstp_port->DestinationAddress = 1;
mstp_port->ReceivedValidFrame = true;
transition_now = MSTP_Master_Node_FSM(mstp_port);
zassert_false(transition_now, NULL);
zassert_true(
mstp_port->Zero_Config_State == MSTP_ZERO_CONFIG_STATE_LURK, NULL);
zassert_true(mstp_port->ReceivedValidFrame == true, NULL);
}
static void testZeroConfigNode_Test_LURK_AddressInUse(
struct mstp_port_struct_t *mstp_port)
{
bool transition_now, non_zero;
unsigned slots, silence, i;
uint8_t src, dst;
/* test case: src emits a token from each MAC in the zero-config range */
SilenceTime = 0;
mstp_port->FrameType = FRAME_TYPE_TOKEN;
for (src = Nmin_poll_station; src <= Nmax_poll_station; src++) {
mstp_port->ReceivedValidFrame = true;
mstp_port->SourceAddress = src;
dst = (src + 1) % (Nmax_master_station + 1);
mstp_port->DestinationAddress = dst;
zassert_true(mstp_port->Zero_Config_Station == src, NULL);
transition_now = MSTP_Master_Node_FSM(mstp_port);
zassert_false(transition_now, NULL);
zassert_true(
mstp_port->Zero_Config_State == MSTP_ZERO_CONFIG_STATE_LURK, NULL);
zassert_true(mstp_port->ReceivedValidFrame == false, NULL);
zassert_true(mstp_port->Zero_Config_Station != src, "src=%u zc=%u", src,
mstp_port->Zero_Config_Station);
}
}
static void testZeroConfigNode_Test_LURK_LearnMaxMaster(
struct mstp_port_struct_t *mstp_port)
{
bool transition_now, non_zero;
unsigned slots, silence, i;
uint8_t src, dst;
/* test case: src emits a token from each MAC in the zero-config range */
SilenceTime = 0;
mstp_port->SourceAddress = 0;
mstp_port->FrameType = FRAME_TYPE_POLL_FOR_MASTER;
for (dst = 1; dst <= Nmax_master_station; dst++) {
mstp_port->ReceivedValidFrame = true;
mstp_port->DestinationAddress = dst;
transition_now = MSTP_Master_Node_FSM(mstp_port);
zassert_false(transition_now, NULL);
zassert_true(
mstp_port->Zero_Config_State == MSTP_ZERO_CONFIG_STATE_LURK, NULL);
zassert_true(mstp_port->ReceivedValidFrame == false, NULL);
zassert_true(mstp_port->Zero_Config_Max_Master == dst, NULL);
}
}
static void testZeroConfigNode_Test_LURK_Claim(
struct mstp_port_struct_t *mstp_port)
{
bool transition_now, non_zero;
unsigned slots, silence, i;
uint8_t src = 0, dst, count, count_max, count_claim;
/* test case: src emits a PFM from each MAC in the zero-config range */
SilenceTime = 0;
mstp_port->SourceAddress = src;
mstp_port->FrameType = FRAME_TYPE_POLL_FOR_MASTER;
dst = Nmin_poll_station;
count_claim = Nmin_poll + mstp_port->Npoll_slot;
count_max = Nmin_poll + Nmax_poll_station;
for (count = 0; count < count_max; count++) {
/* simulate receiving PFM */
mstp_port->ReceivedValidFrame = true;
mstp_port->DestinationAddress = dst;
transition_now = MSTP_Master_Node_FSM(mstp_port);
zassert_false(transition_now, NULL);
zassert_true(mstp_port->ReceivedValidFrame == false, NULL);
zassert_true((mstp_port->Zero_Config_Station) == dst, NULL);
if (mstp_port->Npoll_slot == count_claim) {
zassert_true(
mstp_port->Zero_Config_State == MSTP_ZERO_CONFIG_STATE_CLAIM,
NULL);
} else if (mstp_port->Zero_Config_State ==
MSTP_ZERO_CONFIG_STATE_LURK) {
zassert_true(
mstp_port->Poll_Count == (count + 1), "count=%u", count);
zassert_true(
mstp_port->Zero_Config_State == MSTP_ZERO_CONFIG_STATE_LURK,
NULL);
} else {
break;
}
}
/* verify the Reply To Poll For Master was sent for confirmation */
zassert_equal(mstp_port->OutputBuffer[2], FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER, NULL);
zassert_equal(mstp_port->OutputBuffer[3], mstp_port->SourceAddress, NULL);
zassert_equal(mstp_port->OutputBuffer[4], mstp_port->Zero_Config_Station, NULL);
}
static void testZeroConfigNode_Test_LURK_ClaimTokenForUs(
struct mstp_port_struct_t *mstp_port)
{
bool transition_now;
uint8_t src = 0, dst;
/* ClaimTokenForUs */
dst = mstp_port->Zero_Config_Station;
mstp_port->SourceAddress = src;
mstp_port->DestinationAddress = dst;
mstp_port->FrameType = FRAME_TYPE_TOKEN;
mstp_port->ReceivedValidFrame = true;
transition_now = MSTP_Master_Node_FSM(mstp_port);
zassert_false(transition_now, NULL);
zassert_true(mstp_port->ReceivedValidFrame == false, NULL);
zassert_equal(mstp_port->Zero_Config_State, MSTP_ZERO_CONFIG_STATE_CONFIRM, NULL);
/* verify the Test Request Frame was sent for confirmation */
zassert_equal(mstp_port->OutputBuffer[2], FRAME_TYPE_TEST_REQUEST, NULL);
zassert_equal(mstp_port->OutputBuffer[3], mstp_port->SourceAddress, NULL);
zassert_equal(mstp_port->OutputBuffer[4], mstp_port->Zero_Config_Station, NULL);
}
static void testZeroConfigNode_Test_LURK_ConfirmationSuccessful(
struct mstp_port_struct_t *mstp_port)
{
bool transition_now;
uint8_t src = 0, dst;
/* ConfirmationSuccessful */
dst = mstp_port->Zero_Config_Station;
mstp_port->SourceAddress = src;
mstp_port->DestinationAddress = dst;
mstp_port->FrameType = FRAME_TYPE_TEST_RESPONSE;
memcpy(mstp_port->InputBuffer, mstp_port->UUID, MSTP_UUID_SIZE);
mstp_port->DataLength = MSTP_UUID_SIZE;
mstp_port->ReceivedValidFrame = true;
transition_now = MSTP_Master_Node_FSM(mstp_port);
zassert_true(transition_now, NULL);
zassert_true(mstp_port->ReceivedValidFrame == false, NULL);
zassert_equal(mstp_port->This_Station, mstp_port->Zero_Config_Station, NULL);
zassert_equal(mstp_port->Zero_Config_State, MSTP_ZERO_CONFIG_STATE_USE, NULL);
}
static void testZeroConfigNode_Test_LURK_ConfirmationAddressInUse(
struct mstp_port_struct_t *mstp_port)
{
bool transition_now;
uint8_t src, dst, test_station;
/* ConfirmationAddressInUse */
dst = mstp_port->Zero_Config_Station;
src = mstp_port->Zero_Config_Station;
mstp_port->SourceAddress = src;
mstp_port->DestinationAddress = dst;
mstp_port->FrameType = FRAME_TYPE_PROPRIETARY_MIN;
encode_unsigned16(&mstp_port->InputBuffer[0], BACNET_VENDOR_ID);
memcpy(&mstp_port->InputBuffer[2], mstp_port->UUID, MSTP_UUID_SIZE);
mstp_port->DataLength = MSTP_UUID_SIZE+2;
mstp_port->ReceivedValidFrame = true;
test_station = mstp_port->Zero_Config_Station + 1;
transition_now = MSTP_Master_Node_FSM(mstp_port);
zassert_false(transition_now, NULL);
zassert_true(mstp_port->ReceivedValidFrame == false, NULL);
zassert_equal(test_station, mstp_port->Zero_Config_Station, NULL);
zassert_equal(mstp_port->Zero_Config_State, MSTP_ZERO_CONFIG_STATE_LURK, NULL);
}
static void testZeroConfigNode_Test_LURK_ConfirmationUnuccessful_UUID_Size(
struct mstp_port_struct_t *mstp_port)
{
bool transition_now;
uint8_t src = 0, dst;
/* ConfirmationFailed */
dst = mstp_port->Zero_Config_Station;
mstp_port->SourceAddress = src;
mstp_port->DestinationAddress = dst;
mstp_port->FrameType = FRAME_TYPE_TEST_RESPONSE;
memcpy(mstp_port->InputBuffer, mstp_port->UUID, MSTP_UUID_SIZE);
/* set to an invalid size */
mstp_port->DataLength = MSTP_UUID_SIZE-1;
mstp_port->ReceivedValidFrame = true;
transition_now = MSTP_Master_Node_FSM(mstp_port);
zassert_false(transition_now, NULL);
zassert_true(mstp_port->ReceivedValidFrame == false, NULL);
zassert_equal(mstp_port->Zero_Config_State, MSTP_ZERO_CONFIG_STATE_IDLE, NULL);
}
static void testZeroConfigNode_Test_LURK_ConfirmationUnuccessful_UUID(
struct mstp_port_struct_t *mstp_port)
{
bool transition_now;
uint8_t src = 0, dst;
/* ConfirmationFailed */
dst = mstp_port->Zero_Config_Station;
mstp_port->SourceAddress = src;
mstp_port->DestinationAddress = dst;
mstp_port->FrameType = FRAME_TYPE_TEST_RESPONSE;
memcpy(mstp_port->InputBuffer, mstp_port->UUID, MSTP_UUID_SIZE);
/* make the UUID invalid */
mstp_port->InputBuffer[0] = ~mstp_port->InputBuffer[0];
mstp_port->DataLength = MSTP_UUID_SIZE;
mstp_port->ReceivedValidFrame = true;
transition_now = MSTP_Master_Node_FSM(mstp_port);
zassert_false(transition_now, NULL);
zassert_true(mstp_port->ReceivedValidFrame == false, NULL);
zassert_equal(mstp_port->Zero_Config_State, MSTP_ZERO_CONFIG_STATE_IDLE, NULL);
}
static void testZeroConfigNode_Test_LURK_ClaimAddressInUse(
struct mstp_port_struct_t *mstp_port)
{
bool transition_now;
uint8_t station;
/* ClaimAddressInUse */
station = mstp_port->Zero_Config_Station;
mstp_port->SourceAddress = station;
mstp_port->DestinationAddress = 0;
mstp_port->FrameType = FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER;
mstp_port->ReceivedValidFrame = true;
transition_now = MSTP_Master_Node_FSM(mstp_port);
zassert_false(transition_now, NULL);
zassert_true(mstp_port->ReceivedValidFrame == false, NULL);
zassert_equal(mstp_port->Zero_Config_State, MSTP_ZERO_CONFIG_STATE_LURK, NULL);
zassert_equal(mstp_port->Zero_Config_Station, station + 1, NULL);
}
static void testZeroConfigNode_Test_LURK_ClaimInvalidFrame(
struct mstp_port_struct_t *mstp_port)
{
bool transition_now;
/* ClaimInvalidFrame */
mstp_port->ReceivedValidFrame = false;
mstp_port->ReceivedInvalidFrame = true;
transition_now = MSTP_Master_Node_FSM(mstp_port);
zassert_false(transition_now, NULL);
zassert_true(mstp_port->ReceivedInvalidFrame == false, NULL);
zassert_equal(mstp_port->Zero_Config_State, MSTP_ZERO_CONFIG_STATE_CLAIM, NULL);
}
static void testZeroConfigNode_Test_LURK_ClaimLostToken(
struct mstp_port_struct_t *mstp_port)
{
bool transition_now;
/* ClaimLostToken */
mstp_port->ReceivedValidFrame = false;
mstp_port->ReceivedInvalidFrame = false;
SilenceTime = mstp_port->Zero_Config_Silence + 1;
transition_now = MSTP_Master_Node_FSM(mstp_port);
zassert_false(transition_now, NULL);
zassert_equal(mstp_port->Zero_Config_State, MSTP_ZERO_CONFIG_STATE_IDLE, NULL);
}
static void testZeroConfigNodeFSM(void)
{
struct mstp_port_struct_t MSTP_Port = { 0 }; /* port data */
/* test case: timeout event */
testZeroConfigNode_Init(&MSTP_Port);
testZeroConfigNode_No_Events_Timeout(&MSTP_Port);
testZeroConfigNode_Test_Request_Unsupported(&MSTP_Port);
/* test case: invalid frame event */
testZeroConfigNode_Init(&MSTP_Port);
testZeroConfigNode_Test_IDLE_InvalidFrame(&MSTP_Port);
/* test case: valid frame event and timeout */
testZeroConfigNode_Init(&MSTP_Port);
testZeroConfigNode_Test_IDLE_ValidFrameTimeout(&MSTP_Port);
/* test case: valid frame event LURK Tokens: AddressInUse */
testZeroConfigNode_Init(&MSTP_Port);
testZeroConfigNode_Test_IDLE_ValidFrame(&MSTP_Port);
testZeroConfigNode_Test_LURK_AddressInUse(&MSTP_Port);
/* test case: valid frame event LURK PFMs: LearnMaxMaster */
testZeroConfigNode_Init(&MSTP_Port);
testZeroConfigNode_Test_IDLE_ValidFrame(&MSTP_Port);
testZeroConfigNode_Test_LURK_LearnMaxMaster(&MSTP_Port);
/* test case: valid frame event LURK PFMs: ClaimAddress
ConfirmationSuccessful */
testZeroConfigNode_Init(&MSTP_Port);
testZeroConfigNode_Test_IDLE_ValidFrame(&MSTP_Port);
testZeroConfigNode_Test_LURK_Claim(&MSTP_Port);
testZeroConfigNode_Test_LURK_ClaimTokenForUs(&MSTP_Port);
testZeroConfigNode_Test_LURK_ConfirmationSuccessful(&MSTP_Port);
/* test case: valid frame event LURK PFMs: ClaimAddress
ConfirmationAddressInUse */
testZeroConfigNode_Init(&MSTP_Port);
testZeroConfigNode_Test_IDLE_ValidFrame(&MSTP_Port);
testZeroConfigNode_Test_LURK_Claim(&MSTP_Port);
testZeroConfigNode_Test_LURK_ClaimTokenForUs(&MSTP_Port);
testZeroConfigNode_Test_LURK_ConfirmationAddressInUse(&MSTP_Port);
/* test case: valid frame event LURK PFMs: ClaimAddress
but Confirmation is Unsuccessful - UUID is invalid */
testZeroConfigNode_Init(&MSTP_Port);
testZeroConfigNode_Test_IDLE_ValidFrame(&MSTP_Port);
testZeroConfigNode_Test_LURK_Claim(&MSTP_Port);
testZeroConfigNode_Test_LURK_ClaimTokenForUs(&MSTP_Port);
testZeroConfigNode_Test_LURK_ConfirmationUnuccessful_UUID(&MSTP_Port);
/* test case: valid frame event LURK PFMs: ClaimAddress
but Confirmation is Unsuccessful - UUID is too short */
testZeroConfigNode_Init(&MSTP_Port);
testZeroConfigNode_Test_IDLE_ValidFrame(&MSTP_Port);
testZeroConfigNode_Test_LURK_Claim(&MSTP_Port);
testZeroConfigNode_Test_LURK_ClaimTokenForUs(&MSTP_Port);
testZeroConfigNode_Test_LURK_ConfirmationUnuccessful_UUID_Size(&MSTP_Port);
/* test case: valid frame event LURK PFMs: ClaimAddressInUse */
testZeroConfigNode_Init(&MSTP_Port);
testZeroConfigNode_Test_IDLE_ValidFrame(&MSTP_Port);
testZeroConfigNode_Test_LURK_Claim(&MSTP_Port);
testZeroConfigNode_Test_LURK_ClaimAddressInUse(&MSTP_Port);
/* test case: valid frame event LURK PFMs: ClaimInvalidFrame */
testZeroConfigNode_Init(&MSTP_Port);
testZeroConfigNode_Test_IDLE_ValidFrame(&MSTP_Port);
testZeroConfigNode_Test_LURK_Claim(&MSTP_Port);
testZeroConfigNode_Test_LURK_ClaimInvalidFrame(&MSTP_Port);
/* test case: valid frame event LURK PFMs: ClaimLostToken */
testZeroConfigNode_Init(&MSTP_Port);
testZeroConfigNode_Test_IDLE_ValidFrame(&MSTP_Port);
testZeroConfigNode_Test_LURK_Claim(&MSTP_Port);
testZeroConfigNode_Test_LURK_ClaimLostToken(&MSTP_Port);
}
/**
* @}
*/
void test_main(void)
{
ztest_test_suite(crc_tests, ztest_unit_test(testReceiveNodeFSM),
ztest_unit_test(testMasterNodeFSM), ztest_unit_test(testSlaveNodeFSM),
ztest_unit_test(testZeroConfigNodeFSM));
ztest_run_test_suite(crc_tests);
}