diff --git a/bacnet-stack/include/version.h b/bacnet-stack/include/version.h index 43100394..550ae17e 100644 --- a/bacnet-stack/include/version.h +++ b/bacnet-stack/include/version.h @@ -39,8 +39,8 @@ #define BACNET_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z)) #endif -#define BACNET_VERSION_TEXT "0.5.9" -#define BACNET_VERSION_CODE BACNET_VERSION(0,5,9) +#define BACNET_VERSION_TEXT "0.6.0" +#define BACNET_VERSION_CODE BACNET_VERSION(0,6,0) #define BACNET_VERSION_MAJOR ((BACNET_VERSION_CODE>>16)&0xFF) #define BACNET_VERSION_MINOR ((BACNET_VERSION_CODE>>8)&0xFF) #define BACNET_VERSION_MAINTENANCE (BACNET_VERSION_CODE&0xFF) diff --git a/bacnet-stack/ports/at91sam7s/dlmstp.c b/bacnet-stack/ports/at91sam7s/dlmstp.c index 0449d7d3..80f0173b 100644 --- a/bacnet-stack/ports/at91sam7s/dlmstp.c +++ b/bacnet-stack/ports/at91sam7s/dlmstp.c @@ -1142,6 +1142,76 @@ static bool MSTP_Master_Node_FSM( return transition_now; } +static void MSTP_Slave_Node_FSM( + void) +{ + /* packet from the PDU Queue */ + struct mstp_pdu_packet *pkt; + /* did the frame in the queue match the last request? */ + bool matched = false; + + if (MSTP_Flag.ReceivedInvalidFrame == true) { + /* ReceivedInvalidFrame */ + /* invalid frame was received */ + MSTP_Flag.ReceivedInvalidFrame = false; + } else if (MSTP_Flag.ReceivedValidFrame) { + MSTP_Flag.ReceivedValidFrame = false; + switch (FrameType) { + case FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY: + if (DestinationAddress != MSTP_BROADCAST_ADDRESS) { + /* indicate successful reception to the higher layers */ + MSTP_Flag.ReceivePacketPending = true; + } + break; + case FRAME_TYPE_TEST_REQUEST: + MSTP_Send_Frame(FRAME_TYPE_TEST_RESPONSE, SourceAddress, + This_Station, &InputBuffer[0], DataLength); + break; + case FRAME_TYPE_TOKEN: + case FRAME_TYPE_POLL_FOR_MASTER: + case FRAME_TYPE_TEST_RESPONSE: + case FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY: + default: + break; + } + } else if (MSTP_Flag.ReceivePacketPending) { + if (Ringbuf_Empty(&PDU_Queue)) { + /* If no reply will be available from the higher layers + within Treply_delay after the reception of the final octet + of the requesting frame (the mechanism used to determine + this is a local matter), then no reply is possible. */ + MSTP_Flag.ReceivePacketPending = false; + } else { + pkt = (struct mstp_pdu_packet *) Ringbuf_Pop_Front(&PDU_Queue); + matched = + dlmstp_compare_data_expecting_reply(&InputBuffer[0], + DataLength, SourceAddress, &pkt->buffer[0], pkt->length, + pkt->destination_mac); + if (matched) { + /* Reply */ + /* If a reply is available from the higher layers */ + /* within Treply_delay after the reception of the */ + /* final octet of the requesting frame */ + /* (the mechanism used to determine this is a local matter), */ + /* then call MSTP_Send_Frame to transmit the reply frame */ + /* and enter the IDLE state to wait for the next frame. */ + uint8_t frame_type; + pkt = (struct mstp_pdu_packet *) Ringbuf_Pop_Front(&PDU_Queue); + if (pkt->data_expecting_reply) { + frame_type = FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY; + } else { + frame_type = FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY; + } + MSTP_Send_Frame(frame_type, pkt->destination_mac, This_Station, + (uint8_t *) & pkt->buffer[0], pkt->length); + Master_State = MSTP_MASTER_STATE_IDLE; + } + /* clear our flag we were holding for comparison */ + MSTP_Flag.ReceivePacketPending = false; + } + } +} + /* returns number of bytes sent on success, zero on failure */ int dlmstp_send_pdu( BACNET_ADDRESS * dest, /* destination address */ @@ -1192,9 +1262,13 @@ uint16_t dlmstp_receive( } if (Receive_State == MSTP_RECEIVE_STATE_IDLE) { /* only do master state machine while rx is idle */ - while (MSTP_Master_Node_FSM()) { - /* do nothing while some states fast transition */ - }; + if (This_Station <= DEFAULT_MAX_MASTER) { + while (MSTP_Master_Node_FSM()) { + /* do nothing while some states fast transition */ + }; + } else if (This_Station < 255) { + MSTP_Slave_Node_FSM(); + } } /* if there is a packet that needs processed, do it now. */ if (MSTP_Flag.ReceivePacketPending) { diff --git a/bacnet-stack/ports/atmega168/dlmstp.c b/bacnet-stack/ports/atmega168/dlmstp.c index 47cc5e68..3007d630 100644 --- a/bacnet-stack/ports/atmega168/dlmstp.c +++ b/bacnet-stack/ports/atmega168/dlmstp.c @@ -37,6 +37,7 @@ #include #include #include "bacdef.h" +#include "mstpdef.h" #include "dlmstp.h" #include "rs485.h" #include "crc.h" @@ -55,52 +56,6 @@ #include "hardware.h" #include "timer.h" -/* The value 255 is used to denote broadcast when used as a */ -/* destination address but is not allowed as a value for a station. */ -/* Station addresses for master nodes can be 0-127. */ -/* Station addresses for slave nodes can be 127-254. */ -#define MSTP_BROADCAST_ADDRESS 255 - -/* MS/TP Frame Type */ -/* Frame Types 8 through 127 are reserved by ASHRAE. */ -#define FRAME_TYPE_TOKEN 0 -#define FRAME_TYPE_POLL_FOR_MASTER 1 -#define FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER 2 -#define FRAME_TYPE_TEST_REQUEST 3 -#define FRAME_TYPE_TEST_RESPONSE 4 -#define FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY 5 -#define FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY 6 -#define FRAME_TYPE_REPLY_POSTPONED 7 -/* Frame Types 128 through 255: Proprietary Frames */ -/* These frames are available to vendors as proprietary (non-BACnet) frames. */ -/* The first two octets of the Data field shall specify the unique vendor */ -/* identification code, most significant octet first, for the type of */ -/* vendor-proprietary frame to be conveyed. The length of the data portion */ -/* of a Proprietary frame shall be in the range of 2 to 501 octets. */ -#define FRAME_TYPE_PROPRIETARY_MIN 128 -#define FRAME_TYPE_PROPRIETARY_MAX 255 - -/* receive FSM states */ -typedef enum { - MSTP_RECEIVE_STATE_IDLE = 0, - MSTP_RECEIVE_STATE_PREAMBLE = 1, - MSTP_RECEIVE_STATE_HEADER = 2, - MSTP_RECEIVE_STATE_DATA = 3 -} MSTP_RECEIVE_STATE; - -/* master node FSM states */ -typedef enum { - MSTP_MASTER_STATE_INITIALIZE = 0, - MSTP_MASTER_STATE_IDLE = 1, - MSTP_MASTER_STATE_USE_TOKEN = 2, - MSTP_MASTER_STATE_WAIT_FOR_REPLY = 3, - MSTP_MASTER_STATE_DONE_WITH_TOKEN = 4, - MSTP_MASTER_STATE_PASS_TOKEN = 5, - MSTP_MASTER_STATE_NO_TOKEN = 6, - MSTP_MASTER_STATE_POLL_FOR_MASTER = 7, - MSTP_MASTER_STATE_ANSWER_DATA_REQUEST = 8 -} MSTP_MASTER_STATE; - /* The state of the Receive State Machine */ static MSTP_RECEIVE_STATE Receive_State; /* When a master node is powered up or reset, */ @@ -180,10 +135,6 @@ static uint8_t *TransmitPacket; static uint16_t TransmitPacketLen; static uint8_t TransmitPacketDest; -/* The time without a DataAvailable or ReceiveError event before declaration */ -/* of loss of token: 500 milliseconds. */ -#define Tno_token 500 - /* The minimum time without a DataAvailable or ReceiveError event */ /* that a node must wait for a station to begin replying to a */ /* confirmed request: 255 milliseconds. (Implementations may use */ @@ -196,13 +147,6 @@ static uint8_t TransmitPacketDest; /* larger values for this timeout, not to exceed 100 milliseconds.) */ #define Tusage_timeout 95 -/* The number of tokens received or used before a Poll For Master cycle */ -/* is executed: 50. */ -#define Npoll 50 - -/* The number of retries on sending Token: 1. */ -#define Nretry_token 1 - /* The minimum number of DataAvailable or ReceiveError events that must be */ /* seen by a receiving node in order to declare the line "active": 4. */ #define Nmin_octets 4 @@ -215,24 +159,11 @@ static uint8_t TransmitPacketDest; /* const uint16_t Tframe_abort = 1 + ((1000 * 60) / 9600); */ #define Tframe_abort 30 -/* The maximum idle time a sending node may allow to elapse between octets */ -/* of a frame the node is transmitting: 20 bit times. */ -#define Tframe_gap 20 - /* The maximum time a node may wait after reception of a frame that expects */ /* a reply before sending the first octet of a reply or Reply Postponed */ /* frame: 250 milliseconds. */ #define Treply_delay 250 -/* The width of the time slot within which a node may generate a token: */ -/* 10 milliseconds. */ -#define Tslot 10 - -/* The maximum time a node may wait after reception of the token or */ -/* a Poll For Master frame before sending the first octet of a frame: */ -/* 15 milliseconds. */ -#define Tusage_delay 15 - /* we need to be able to increment without rolling over */ #define INCREMENT_AND_LIMIT_UINT8(x) {if (x < 0xFF) x++;} @@ -1092,9 +1023,11 @@ uint16_t dlmstp_receive( } /* only do master state machine while rx is idle */ if (Receive_State == MSTP_RECEIVE_STATE_IDLE) { - while (MSTP_Master_Node_FSM()) { - /* do nothing while some states fast transition */ - }; + if (This_Station <= DEFAULT_MAX_MASTER) { + while (MSTP_Master_Node_FSM()) { + /* do nothing while some states fast transition */ + }; + } } /* if there is a packet that needs processed, do it now. */ if (MSTP_Flag.ReceivePacketPending) { diff --git a/bacnet-stack/ports/bdk-atxx4-mstp/dlmstp.c b/bacnet-stack/ports/bdk-atxx4-mstp/dlmstp.c index eab83c03..9957b7f7 100644 --- a/bacnet-stack/ports/bdk-atxx4-mstp/dlmstp.c +++ b/bacnet-stack/ports/bdk-atxx4-mstp/dlmstp.c @@ -1218,10 +1218,12 @@ uint16_t dlmstp_receive( MSTP_Flag.ReceivedValidFrameNotForUs = false; } if (Receive_State == MSTP_RECEIVE_STATE_IDLE) { - /* only do master state machine while rx is idle */ - while (MSTP_Master_Node_FSM()) { - /* do nothing while some states fast transition */ - }; + /* only do master or slave state machine while rx is idle */ + if (This_Station <= DEFAULT_MAX_MASTER) { + while (MSTP_Master_Node_FSM()) { + /* do nothing while some states fast transition */ + }; + } } /* if there is a packet that needs processed, do it now. */ if (MSTP_Flag.ReceivePacketPending) { diff --git a/bacnet-stack/ports/pic18f6720/dlmstp.c b/bacnet-stack/ports/pic18f6720/dlmstp.c index 82fbb7bc..1ea6e42c 100644 --- a/bacnet-stack/ports/pic18f6720/dlmstp.c +++ b/bacnet-stack/ports/pic18f6720/dlmstp.c @@ -147,8 +147,11 @@ void dlmstp_task( } /* only do master state machine while rx is idle */ if (MSTP_Port.receive_state == MSTP_RECEIVE_STATE_IDLE) { - while (MSTP_Master_Node_FSM(&MSTP_Port)) { - }; + if (This_Station <= DEFAULT_MAX_MASTER) { + while (MSTP_Master_Node_FSM(&MSTP_Port)) { + /* do nothing while some states fast transition */ + }; + } } /* see if there is a packet available, and a place to put the reply (if necessary) and process it */ diff --git a/bacnet-stack/ports/rtos32/dlmstp.c b/bacnet-stack/ports/rtos32/dlmstp.c index 309cdd66..1a3eddb7 100644 --- a/bacnet-stack/ports/rtos32/dlmstp.c +++ b/bacnet-stack/ports/rtos32/dlmstp.c @@ -135,8 +135,10 @@ uint16_t dlmstp_receive( } /* only do master state machine while rx is idle */ if (MSTP_Port.receive_state == MSTP_RECEIVE_STATE_IDLE) { - while (MSTP_Master_Node_FSM(&MSTP_Port)) { - }; + if (This_Station <= DEFAULT_MAX_MASTER) { + while (MSTP_Master_Node_FSM(&MSTP_Port)) { + }; + } } /* see if there is a packet available */ if (Receive_Buffer.ready) {