diff --git a/bacnet-stack/demo/mstpcap/Makefile b/bacnet-stack/demo/mstpcap/Makefile index 1dab905f..d228a834 100644 --- a/bacnet-stack/demo/mstpcap/Makefile +++ b/bacnet-stack/demo/mstpcap/Makefile @@ -1,6 +1,6 @@ #Makefile to build BACnet Application for the Linux Port -# tools - only if you need them. +# tools - only if you need them. # Most platforms have this already defined # CC = gcc @@ -37,7 +37,8 @@ OPTIMIZATION = -O0 DEBUGGING = -g endif # put all the flags together -CFLAGS = -Wall $(DEBUGGING) $(OPTIMIZATION) $(INCLUDES) $(DEFINES) -fdata-sections -ffunction-sections +CFLAGS = -Wall $(DEBUGGING) $(OPTIMIZATION) $(INCLUDES) $(DEFINES) +CFLAGS += -fdata-sections -ffunction-sections LFLAGS = -Wl,-Map=$(TARGET).map,$(LIBRARIES),--gc-sections SRCS = main.c \ diff --git a/bacnet-stack/demo/mstpcap/main.c b/bacnet-stack/demo/mstpcap/main.c index d4035003..c2c1aea4 100644 --- a/bacnet-stack/demo/mstpcap/main.c +++ b/bacnet-stack/demo/mstpcap/main.c @@ -600,7 +600,6 @@ int main( MSTP_Port.SilenceTimer = Timer_Silence; MSTP_Port.SilenceTimerReset = Timer_Silence_Reset; MSTP_Init(mstp_port); - mstp_port->Lurking = true; fprintf(stdout, "mstpcap: Using %s for capture at %ld bps.\n", RS485_Interface(), (long) RS485_Get_Baud_Rate()); atexit(cleanup); @@ -623,15 +622,19 @@ int main( write_received_packet(mstp_port); mstp_port->ReceivedValidFrame = false; packet_count++; + } else if (mstp_port->ReceivedValidFrameNotForUs) { + write_received_packet(mstp_port); + mstp_port->ReceivedValidFrameNotForUs = false; + packet_count++; } else if (mstp_port->ReceivedInvalidFrame) { - fprintf(stderr, "ReceivedInvalidFrame\n"); write_received_packet(mstp_port); Invalid_Frame_Count++; mstp_port->ReceivedInvalidFrame = false; packet_count++; } if (!(packet_count % 100)) { - fprintf(stdout, "\r%hu packets", packet_count); + fprintf(stdout, "\r%hu packets, %hu invalid frames", + packet_count, Invalid_Frame_Count); } if (packet_count >= 65535) { packet_statistics_save(); diff --git a/bacnet-stack/include/mstp.h b/bacnet-stack/include/mstp.h index 7ca9da6b..cacc222f 100644 --- a/bacnet-stack/include/mstp.h +++ b/bacnet-stack/include/mstp.h @@ -37,15 +37,19 @@ struct mstp_port_struct_t { MSTP_MASTER_STATE master_state; /* A Boolean flag set to TRUE by the Receive State Machine */ /* if an error is detected during the reception of a frame. */ - /* Set to FALSE by the main state machine. */ + /* Set to FALSE by the Master or Slave Node state machine. */ unsigned ReceiveError:1; /* There is data in the buffer */ unsigned DataAvailable:1; unsigned ReceivedInvalidFrame:1; /* A Boolean flag set to TRUE by the Receive State Machine */ /* if a valid frame is received. */ - /* Set to FALSE by the main state machine. */ + /* Set to FALSE by the Master or Slave Node state machine. */ unsigned ReceivedValidFrame:1; + /* A Boolean flag set to TRUE by the Receive State Machine */ + /* if a valid frame is received but it is not addressed to us. */ + /* Set to FALSE by the Master or Slave Node state machine. */ + unsigned ReceivedValidFrameNotForUs:1; /* A Boolean flag set to TRUE by the master machine if this node is the */ /* only known master node. */ unsigned SoleMaster:1; @@ -76,7 +80,7 @@ struct mstp_port_struct_t { uint8_t HeaderCRCActual; /* Used as an index by the Receive State Machine, up to a maximum value of */ /* InputBufferSize. */ - uint16_t Index; + uint32_t Index; /* An array of octets, used to store octets as they are received. */ /* InputBuffer is indexed from 0 to InputBufferSize-1. */ /* The maximum size of a frame is 501 octets. */ @@ -121,10 +125,6 @@ struct mstp_port_struct_t { /* Used to store the Source Address of a received frame. */ uint8_t SourceAddress; - /* The addresses are compared and frames that are not - addressed to us are discarded *unless* Lurking is - set to true. */ - bool Lurking; /* The number of tokens received by this node. When this counter reaches the */ /* value Npoll, the node polls the address range between TS and NS for */ diff --git a/bacnet-stack/src/mstp.c b/bacnet-stack/src/mstp.c index 7a1fea4d..f9172f85 100644 --- a/bacnet-stack/src/mstp.c +++ b/bacnet-stack/src/mstp.c @@ -398,48 +398,50 @@ void MSTP_Receive_Frame_FSM( /* wait for the start of the next frame. */ mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; } else { - /* Note: proposed change to BACnet MSTP state machine! - If we don't decode data that is not for us, we could - get confused about the start if the Preamble 55 FF - is part of the data. */ - /* Data */ - if ((mstp_port->DataLength) && - (mstp_port->DataLength <= - mstp_port->InputBufferSize)) { - /* Data - decode anyway to keep from false */ - mstp_port->Index = 0; - mstp_port->DataCRC = 0xFFFF; - /* receive the data portion of the frame. */ - mstp_port->receive_state = MSTP_RECEIVE_STATE_DATA; - } else { - /* FrameTooLong */ - if (mstp_port->DataLength) { - printf_receive_error - ("MSTP: Rx Header: FrameTooLong %u\n", - (unsigned) mstp_port->DataLength); - /* indicate that a frame with an illegal or */ - /* unacceptable data length has been received */ - mstp_port->ReceivedInvalidFrame = true; - } + if (mstp_port->DataLength == 0) { /* NoData */ - else if (mstp_port->DataLength == 0) { - printf_receive_data("%s", - mstptext_frame_type((unsigned) - mstp_port->FrameType)); - if ((mstp_port->DestinationAddress == - mstp_port->This_Station) - || (mstp_port->DestinationAddress == - MSTP_BROADCAST_ADDRESS) - || (mstp_port->Lurking)) { - /* ForUs */ - /* indicate that a frame with no data has been received */ - mstp_port->ReceivedValidFrame = true; - } else { - /* NotForUs - drop */ - } + printf_receive_data("%s", + mstptext_frame_type((unsigned) + mstp_port->FrameType)); + if ((mstp_port->DestinationAddress == + mstp_port->This_Station) + || (mstp_port->DestinationAddress == + MSTP_BROADCAST_ADDRESS)) { + /* ForUs */ + /* indicate that a frame with no data has been received */ + mstp_port->ReceivedValidFrame = true; + } else { + /* NotForUs */ + mstp_port->ReceivedValidFrameNotForUs = true; } /* wait for the start of the next frame. */ mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; + } else { + /* receive the data portion of the frame. */ + if ((mstp_port->DestinationAddress == + mstp_port->This_Station) + || (mstp_port->DestinationAddress == + MSTP_BROADCAST_ADDRESS)) { + if (mstp_port->DataLength <= + mstp_port->InputBufferSize) { + /* Data */ + mstp_port->receive_state = + MSTP_RECEIVE_STATE_DATA; + } else { + /* FrameTooLong */ + printf_receive_error + ("MSTP: Rx Header: FrameTooLong %u\n", + (unsigned) mstp_port->DataLength); + mstp_port->receive_state = + MSTP_RECEIVE_STATE_SKIP_DATA; + } + } else { + /* NotForUs */ + mstp_port->receive_state = + MSTP_RECEIVE_STATE_SKIP_DATA; + } + mstp_port->Index = 0; + mstp_port->DataCRC = 0xFFFF; } } } @@ -461,6 +463,7 @@ void MSTP_Receive_Frame_FSM( break; /* In the DATA state, the node waits for the data portion of a frame. */ case MSTP_RECEIVE_STATE_DATA: + case MSTP_RECEIVE_STATE_SKIP_DATA: /* Timeout */ if (mstp_port->SilenceTimer() > Tframe_abort) { /* indicate that an error has occurred during the reception of a frame */ @@ -487,8 +490,10 @@ void MSTP_Receive_Frame_FSM( mstp_port->DataCRC = CRC_Calc_Data(mstp_port->DataRegister, mstp_port->DataCRC); - mstp_port->InputBuffer[mstp_port->Index] = - mstp_port->DataRegister; + if (mstp_port->Index < mstp_port->InputBufferSize) { + mstp_port->InputBuffer[mstp_port->Index] = + mstp_port->DataRegister; + } mstp_port->Index++; mstp_port->receive_state = MSTP_RECEIVE_STATE_DATA; } else if (mstp_port->Index == mstp_port->DataLength) { @@ -510,16 +515,13 @@ void MSTP_Receive_Frame_FSM( /* STATE DATA CRC - no need for new state */ /* indicate the complete reception of a valid frame */ if (mstp_port->DataCRC == 0xF0B8) { - if ((mstp_port->DestinationAddress == - mstp_port->This_Station) - || (mstp_port->DestinationAddress == - MSTP_BROADCAST_ADDRESS) - || (mstp_port->Lurking)) { + if (mstp_port->receive_state == + MSTP_RECEIVE_STATE_DATA) { /* ForUs */ - /* indicate that a frame with no data has been received */ mstp_port->ReceivedValidFrame = true; } else { - /* NotForUs - drop */ + /* NotForUs */ + mstp_port->ReceivedValidFrameNotForUs = true; } } else { mstp_port->ReceivedInvalidFrame = true; @@ -527,6 +529,9 @@ void MSTP_Receive_Frame_FSM( mstp_port->DataRegister); } mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; + } else { + mstp_port->ReceivedInvalidFrame = true; + mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; } mstp_port->DataAvailable = false; mstp_port->SilenceTimerReset(); @@ -1095,12 +1100,12 @@ void MSTP_Init( mstp_port->Poll_Station = mstp_port->This_Station; mstp_port->ReceivedInvalidFrame = false; mstp_port->ReceivedValidFrame = false; + mstp_port->ReceivedValidFrameNotForUs = false; mstp_port->RetryCount = 0; mstp_port->SilenceTimerReset(); mstp_port->SoleMaster = false; mstp_port->SourceAddress = 0; mstp_port->TokenCount = 0; - mstp_port->Lurking = false; } }