diff --git a/bacnet-stack/ports/at91sam7s/dlmstp.c b/bacnet-stack/ports/at91sam7s/dlmstp.c index 45e93a03..e2bfbf5e 100644 --- a/bacnet-stack/ports/at91sam7s/dlmstp.c +++ b/bacnet-stack/ports/at91sam7s/dlmstp.c @@ -866,9 +866,19 @@ static bool MSTP_Master_Node_FSM( /* before passing the token. */ Master_State = MSTP_MASTER_STATE_USE_TOKEN; transition_now = true; - } - /* Npoll changed in Errata SSPC-135-2004 */ - else if (TokenCount < (Npoll - 1)) { + } else if ((MSTP_Flag.SoleMaster == false) && + (Next_Station == This_Station)) { + /* NextStationUnknown - added in Addendum 135-2008v-1 */ + /* then the next station to which the token + should be sent is unknown - so PollForMaster */ + Poll_Station = next_this_station; + MSTP_Send_Frame( + FRAME_TYPE_POLL_FOR_MASTER, Poll_Station, + This_Station, NULL, 0); + RetryCount = 0; + Master_State = MSTP_MASTER_STATE_POLL_FOR_MASTER; + } else if (TokenCount < (Npoll - 1)) { + /* Npoll changed in Errata SSPC-135-2004 */ if ((MSTP_Flag.SoleMaster == true) && (Next_Station != next_this_station)) { /* SoleMaster */ diff --git a/bacnet-stack/ports/atmega168/dlmstp.c b/bacnet-stack/ports/atmega168/dlmstp.c index 134276cf..b16e4142 100644 --- a/bacnet-stack/ports/atmega168/dlmstp.c +++ b/bacnet-stack/ports/atmega168/dlmstp.c @@ -783,6 +783,17 @@ static bool MSTP_Master_Node_FSM( /* before passing the token. */ Master_State = MSTP_MASTER_STATE_USE_TOKEN; transition_now = true; + } else if ((MSTP_Flag.SoleMaster == false) && + (Next_Station == This_Station)) { + /* NextStationUnknown - added in Addendum 135-2008v-1 */ + /* then the next station to which the token + should be sent is unknown - so PollForMaster */ + Poll_Station = next_this_station; + MSTP_Send_Frame( + FRAME_TYPE_POLL_FOR_MASTER, Poll_Station, + This_Station, NULL, 0); + RetryCount = 0; + Master_State = MSTP_MASTER_STATE_POLL_FOR_MASTER; } /* Npoll changed in Errata SSPC-135-2004 */ else if (TokenCount < (Npoll - 1)) { diff --git a/bacnet-stack/ports/bdk-atxx4-mstp/dlmstp.c b/bacnet-stack/ports/bdk-atxx4-mstp/dlmstp.c index 7aec583e..01426088 100644 --- a/bacnet-stack/ports/bdk-atxx4-mstp/dlmstp.c +++ b/bacnet-stack/ports/bdk-atxx4-mstp/dlmstp.c @@ -888,6 +888,17 @@ static bool MSTP_Master_Node_FSM( /* before passing the token. */ Master_State = MSTP_MASTER_STATE_USE_TOKEN; transition_now = true; + } else if ((MSTP_Flag.SoleMaster == false) && + (Next_Station == This_Station)) { + /* NextStationUnknown - added in Addendum 135-2008v-1 */ + /* then the next station to which the token + should be sent is unknown - so PollForMaster */ + Poll_Station = next_this_station; + MSTP_Send_Frame( + FRAME_TYPE_POLL_FOR_MASTER, Poll_Station, + This_Station, NULL, 0); + RetryCount = 0; + Master_State = MSTP_MASTER_STATE_POLL_FOR_MASTER; } /* Npoll changed in Errata SSPC-135-2004 */ else if (TokenCount < (Npoll - 1)) { diff --git a/bacnet-stack/ports/dos/dlmstp.c b/bacnet-stack/ports/dos/dlmstp.c index 513a7e20..abca1148 100644 --- a/bacnet-stack/ports/dos/dlmstp.c +++ b/bacnet-stack/ports/dos/dlmstp.c @@ -46,7 +46,7 @@ #include "bacaddr.h" /* This file has been customized for use with small microprocessors */ -/* Assumptions: +/* Assumptions: Only one MS/TP datalink layer */ #include "timer.h" @@ -121,7 +121,7 @@ static struct mstp_flag_t { /* A Boolean flag set TRUE by the datalink transmit if a pending packet is DataExpectingReply */ unsigned TransmitPacketDER:1; - /* A Boolean flag set TRUE by the datalink if a + /* A Boolean flag set TRUE by the datalink if a packet has been received, but not processed. */ unsigned ReceivePacketPending:1; } MSTP_Flag; @@ -287,8 +287,8 @@ static bool dlmstp_compare_data_expecting_reply( uint8_t dest_address) { uint16_t offset; - /* One way to check the message is to compare NPDU - src, dest, along with the APDU type, invoke id. + /* One way to check the message is to compare NPDU + src, dest, along with the APDU type, invoke id. Seems a bit overkill */ struct DER_compare_t { BACNET_NPDU_DATA npdu_data; @@ -327,7 +327,7 @@ static bool dlmstp_compare_data_expecting_reply( if (reply.npdu_data.network_layer_message) { return false; } - /* reply could be a lot of things: + /* reply could be a lot of things: confirmed, simple ack, abort, reject, error */ reply.pdu_type = reply_pdu[offset] & 0xF0; switch (reply.pdu_type) { @@ -451,7 +451,7 @@ static void MSTP_Receive_Frame_FSM( static uint16_t DataCRC = 0; /* Used to accumulate the CRC on the header of a frame. */ static uint8_t HeaderCRC = 0; - /* Used as an index by the Receive State Machine, + /* Used as an index by the Receive State Machine, up to a maximum value of the MPDU */ static uint8_t Index = 0; @@ -473,7 +473,7 @@ static void MSTP_Receive_Frame_FSM( } break; case MSTP_RECEIVE_STATE_PREAMBLE: - /* In the PREAMBLE state, the node waits for the + /* In the PREAMBLE state, the node waits for the second octet of the preamble. */ if (Timer_Silence() > Tframe_abort) { /* Timeout */ @@ -553,7 +553,7 @@ static void MSTP_Receive_Frame_FSM( } else if (Index == 5) { /* HeaderCRC */ HeaderCRC = CRC_Calc_Header(DataRegister, HeaderCRC); - /* In the HEADER_CRC state, the node validates the CRC + /* In the HEADER_CRC state, the node validates the CRC on the fixed message header. */ if (HeaderCRC != 0x55) { /* BadCRC */ @@ -565,7 +565,7 @@ static void MSTP_Receive_Frame_FSM( } 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 + get confused about the start if the Preamble 55 FF is part of the data. */ if ((DataLength) && (DataLength <= InputBufferSize)) { /* Data */ @@ -580,7 +580,7 @@ static void MSTP_Receive_Frame_FSM( (DestinationAddress == MSTP_BROADCAST_ADDRESS)) { /* ForUs */ - /* indicate that a frame with + /* indicate that a frame with no data has been received */ MSTP_Flag.ReceivedValidFrame = true; } else { @@ -617,7 +617,7 @@ static void MSTP_Receive_Frame_FSM( /* Error */ Timer_Silence_Reset(); INCREMENT_AND_LIMIT_UINT8(EventCount); - /* indicate that an error has occurred during + /* indicate that an error has occurred during the reception of a frame */ MSTP_Flag.ReceivedInvalidFrame = true; /* wait for the start of the next frame. */ @@ -643,7 +643,7 @@ static void MSTP_Receive_Frame_FSM( if ((DestinationAddress == This_Station) || (DestinationAddress == MSTP_BROADCAST_ADDRESS)) { /* ForUs */ - /* indicate that a frame with no data + /* indicate that a frame with no data has been received */ MSTP_Flag.ReceivedValidFrame = true; } @@ -766,7 +766,7 @@ static bool MSTP_Master_Node_FSM( default: break; } - /* For DATA_EXPECTING_REPLY, we will keep the Rx Frame for + /* For DATA_EXPECTING_REPLY, we will keep the Rx Frame for reference, and the flag will be cleared in the next state */ if (Master_State != MSTP_MASTER_STATE_ANSWER_DATA_REQUEST) { MSTP_Flag.ReceivedValidFrame = false; @@ -884,6 +884,17 @@ static bool MSTP_Master_Node_FSM( /* before passing the token. */ Master_State = MSTP_MASTER_STATE_USE_TOKEN; transition_now = true; + } else if ((MSTP_Flag.SoleMaster == false) && + (Next_Station == This_Station)) { + /* NextStationUnknown - added in Addendum 135-2008v-1 */ + /* then the next station to which the token + should be sent is unknown - so PollForMaster */ + Poll_Station = next_this_station; + MSTP_Send_Frame( + FRAME_TYPE_POLL_FOR_MASTER, Poll_Station, + This_Station, NULL, 0); + RetryCount = 0; + Master_State = MSTP_MASTER_STATE_POLL_FOR_MASTER; } /* Npoll changed in Errata SSPC-135-2004 */ else if (TokenCount < (Npoll - 1)) { @@ -1182,7 +1193,7 @@ uint16_t dlmstp_receive( MSTP_Receive_Frame_FSM(); if (MSTP_Flag.ReceivedValidFrame || MSTP_Flag.ReceivedInvalidFrame) break; - /* if we are not idle, then we are + /* if we are not idle, then we are receiving a frame or timing out */ if (Receive_State == MSTP_RECEIVE_STATE_IDLE) break; @@ -1214,7 +1225,7 @@ void dlmstp_set_mac_address( This_Station = mac_address; /* FIXME: implement your data storage */ /* I2C_Write_Byte( - EEPROM_DEVICE_ADDRESS, + EEPROM_DEVICE_ADDRESS, mac_address, EEPROM_MSTP_MAC_ADDR); */ if (mac_address > Nmax_master) @@ -1243,8 +1254,8 @@ void dlmstp_set_max_info_frames( if (max_info_frames >= 1) { Nmax_info_frames = max_info_frames; /* FIXME: implement your data storage */ - /* I2C_Write_Byte( - EEPROM_DEVICE_ADDRESS, + /* I2C_Write_Byte( + EEPROM_DEVICE_ADDRESS, (uint8_t)max_info_frames, EEPROM_MSTP_MAX_INFO_FRAMES_ADDR); */ } @@ -1271,7 +1282,7 @@ void dlmstp_set_max_master( Nmax_master = max_master; /* FIXME: implement your data storage */ /* I2C_Write_Byte( - EEPROM_DEVICE_ADDRESS, + EEPROM_DEVICE_ADDRESS, max_master, EEPROM_MSTP_MAX_MASTER_ADDR); */ } diff --git a/bacnet-stack/ports/pic18f6720/mstp.c b/bacnet-stack/ports/pic18f6720/mstp.c index 3b874024..877c275d 100644 --- a/bacnet-stack/ports/pic18f6720/mstp.c +++ b/bacnet-stack/ports/pic18f6720/mstp.c @@ -799,6 +799,17 @@ bool MSTP_Master_Node_FSM( /* before passing the token. */ mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN; transition_now = true; + } else if ((MSTP_Flag.SoleMaster == false) && + (Next_Station == This_Station)) { + /* NextStationUnknown - added in Addendum 135-2008v-1 */ + /* then the next station to which the token + should be sent is unknown - so PollForMaster */ + Poll_Station = next_this_station; + MSTP_Send_Frame( + FRAME_TYPE_POLL_FOR_MASTER, Poll_Station, + This_Station, NULL, 0); + RetryCount = 0; + Master_State = MSTP_MASTER_STATE_POLL_FOR_MASTER; } /* Npoll changed in Errata SSPC-135-2004 */ else if (mstp_port->TokenCount < (Npoll - 1)) { diff --git a/bacnet-stack/ports/rtos32/mstp.c b/bacnet-stack/ports/rtos32/mstp.c index df84e9d4..ee913825 100644 --- a/bacnet-stack/ports/rtos32/mstp.c +++ b/bacnet-stack/ports/rtos32/mstp.c @@ -474,7 +474,7 @@ void MSTP_Receive_Frame_FSM( } /* NoData */ else if (mstp_port->DataLength == 0) { - /* CHEAT: it is very difficult to respond to + /* CHEAT: it is very difficult to respond to poll for master in the Master Node state machine before Tusage_timeout, so we will do it here. */ if ((mstp_port->FrameType == @@ -784,7 +784,7 @@ bool MSTP_Master_Node_FSM( case FRAME_TYPE_POLL_FOR_MASTER: /* CHEAT: we cheat a little and this is really handled in the receive state machine since it is difficult to respond - quick enough (i.e. faster than Tusage_timeout of the + quick enough (i.e. faster than Tusage_timeout of the other node which could be 20ms). */ MSTP_Create_And_Send_Frame(mstp_port, FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER, @@ -938,6 +938,17 @@ bool MSTP_Master_Node_FSM( /* then this node may send another information frame */ /* before passing the token. */ mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN; + } else if ((mstp_port->SoleMaster == false) && + (mstp_port->Next_Station == mstp_port->This_Station)) { + /* NextStationUnknown - added in Addendum 135-2008v-1 */ + /* then the next station to which the token + should be sent is unknown - so PollForMaster */ + mstp_port->Poll_Station = next_this_station; + MSTP_Create_And_Send_Frame(mstp_port, + FRAME_TYPE_POLL_FOR_MASTER, mstp_port->Poll_Station, + mstp_port->This_Station, NULL, 0); + mstp_port->RetryCount = 0; + mstp_port->master_state = MSTP_MASTER_STATE_POLL_FOR_MASTER; } /* Npoll changed in Errata SSPC-135-2004 */ else if (mstp_port->TokenCount < (Npoll - 1)) { diff --git a/bacnet-stack/src/mstp.c b/bacnet-stack/src/mstp.c index f9172f85..e5187017 100644 --- a/bacnet-stack/src/mstp.c +++ b/bacnet-stack/src/mstp.c @@ -795,6 +795,17 @@ bool MSTP_Master_Node_FSM( /* before passing the token. */ mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN; transition_now = true; + } else if ((mstp_port->SoleMaster == false) && + (mstp_port->Next_Station == mstp_port->This_Station)) { + /* NextStationUnknown - added in Addendum 135-2008v-1 */ + /* then the next station to which the token + should be sent is unknown - so PollForMaster */ + mstp_port->Poll_Station = next_this_station; + MSTP_Create_And_Send_Frame(mstp_port, + FRAME_TYPE_POLL_FOR_MASTER, mstp_port->Poll_Station, + mstp_port->This_Station, NULL, 0); + mstp_port->RetryCount = 0; + mstp_port->master_state = MSTP_MASTER_STATE_POLL_FOR_MASTER; } else if (mstp_port->TokenCount < (Npoll - 1)) { /* Npoll changed in Errata SSPC-135-2004 */ if ((mstp_port->SoleMaster == true) &&