Fixed MS/TP ANSWER_DATA_REQUEST state in some of the ports to be compliant to the standard by emitting Reply-Postponed rather than nothing when the data request times out.

This commit is contained in:
skarg
2017-05-02 20:17:39 +00:00
parent c9742a594c
commit 8af8043d49
2 changed files with 94 additions and 98 deletions
+12 -14
View File
@@ -666,22 +666,22 @@ static bool MSTP_Master_Node_FSM(
/* The number of frames sent by this node during a single token hold. */ /* The number of frames sent by this node during a single token hold. */
/* When this counter reaches the value Nmax_info_frames, the node must */ /* When this counter reaches the value Nmax_info_frames, the node must */
/* pass the token. */ /* pass the token. */
static uint8_t FrameCount; static uint8_t FrameCount = 0;
/* "Next Station," the MAC address of the node to which This Station /* "Next Station," the MAC address of the node to which This Station
passes the token. If the Next_Station is unknown, Next_Station shall passes the token. If the Next_Station is unknown, Next_Station shall
be equal to This_Station. */ be equal to This_Station. */
static uint8_t Next_Station; static uint8_t Next_Station = 0;
/* "Poll Station," the MAC address of the node to which This Station last */ /* "Poll Station," the MAC address of the node to which This Station last */
/* sent a Poll For Master. This is used during token maintenance. */ /* sent a Poll For Master. This is used during token maintenance. */
static uint8_t Poll_Station; static uint8_t Poll_Station = 0;
/* A counter of transmission retries used for Token and Poll For Master */ /* A counter of transmission retries used for Token and Poll For Master */
/* transmission. */ /* transmission. */
static unsigned RetryCount; static unsigned RetryCount = 0;
/* The number of tokens received by this node. When this counter reaches */ /* 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 */ /* the value Npoll, the node polls the address range between TS and NS */
/* for additional master nodes. TokenCount is set to zero at the end of */ /* for additional master nodes. TokenCount is set to zero at the end of */
/* the polling process. */ /* the polling process. */
static unsigned TokenCount; static unsigned TokenCount = 0;
/* next-x-station calculations */ /* next-x-station calculations */
uint8_t next_poll_station = 0; uint8_t next_poll_station = 0;
uint8_t next_this_station = 0; uint8_t next_this_station = 0;
@@ -689,10 +689,11 @@ static bool MSTP_Master_Node_FSM(
/* timeout values */ /* timeout values */
uint16_t my_timeout = 10, ns_timeout = 0; uint16_t my_timeout = 10, ns_timeout = 0;
bool matched = false; bool matched = false;
bool timeout = false;
/* transition immediately to the next state */ /* transition immediately to the next state */
bool transition_now = false; bool transition_now = false;
/* packet from the PDU Queue */ /* packet from the PDU Queue */
struct mstp_pdu_packet *pkt; struct mstp_pdu_packet *pkt = NULL;
/* some calculations that several states need */ /* some calculations that several states need */
next_poll_station = (Poll_Station + 1) % (Nmax_master + 1); next_poll_station = (Poll_Station + 1) % (Nmax_master + 1);
@@ -1120,15 +1121,12 @@ static bool MSTP_Master_Node_FSM(
MSTP_Flag.ReceivedInvalidFrame = false; MSTP_Flag.ReceivedInvalidFrame = false;
} }
break; break;
case MSTP_MASTER_STATE_ANSWER_DATA_REQUEST:
/* The ANSWER_DATA_REQUEST state is entered when a */ /* The ANSWER_DATA_REQUEST state is entered when a */
/* BACnet Data Expecting Reply, a Test_Request, or */ /* BACnet Data Expecting Reply, a Test_Request, or */
/* a proprietary frame that expects a reply is received. */ /* a proprietary frame that expects a reply is received. */
case MSTP_MASTER_STATE_ANSWER_DATA_REQUEST: timeout = rs485_silence_time_elapsed(Treply_delay);
if (rs485_silence_time_elapsed(Treply_delay)) { if (!timeout) {
Master_State = MSTP_MASTER_STATE_IDLE;
/* clear our flag we were holding for comparison */
MSTP_Flag.ReceivedValidFrame = false;
} else {
pkt = (struct mstp_pdu_packet *) Ringbuf_Peek(&PDU_Queue); pkt = (struct mstp_pdu_packet *) Ringbuf_Peek(&PDU_Queue);
if (pkt != NULL) { if (pkt != NULL) {
matched = matched =
@@ -1138,6 +1136,7 @@ static bool MSTP_Master_Node_FSM(
} else { } else {
matched = false; matched = false;
} }
}
if (matched) { if (matched) {
/* Reply */ /* Reply */
/* If a reply is available from the higher layers */ /* If a reply is available from the higher layers */
@@ -1161,7 +1160,7 @@ static bool MSTP_Master_Node_FSM(
MSTP_Flag.ReceivedValidFrame = false; MSTP_Flag.ReceivedValidFrame = false;
/* clear the queue */ /* clear the queue */
(void) Ringbuf_Pop(&PDU_Queue, NULL); (void) Ringbuf_Pop(&PDU_Queue, NULL);
} else if (pkt != NULL) { } else if ((pkt != NULL) || timeout) {
/* DeferredReply */ /* DeferredReply */
/* If no reply will be available from the higher layers */ /* If no reply will be available from the higher layers */
/* within Treply_delay after the reception of the */ /* within Treply_delay after the reception of the */
@@ -1177,7 +1176,6 @@ static bool MSTP_Master_Node_FSM(
/* clear our flag we were holding for comparison */ /* clear our flag we were holding for comparison */
MSTP_Flag.ReceivedValidFrame = false; MSTP_Flag.ReceivedValidFrame = false;
} }
}
break; break;
default: default:
Master_State = MSTP_MASTER_STATE_IDLE; Master_State = MSTP_MASTER_STATE_IDLE;
+10 -12
View File
@@ -725,22 +725,22 @@ static bool MSTP_Master_Node_FSM(void)
/* The number of frames sent by this node during a single token hold. */ /* The number of frames sent by this node during a single token hold. */
/* When this counter reaches the value Nmax_info_frames, the node must */ /* When this counter reaches the value Nmax_info_frames, the node must */
/* pass the token. */ /* pass the token. */
static uint8_t FrameCount; static uint8_t FrameCount = 0;
/* "Next Station," the MAC address of the node to which This Station /* "Next Station," the MAC address of the node to which This Station
passes the token. If the Next_Station is unknown, Next_Station shall passes the token. If the Next_Station is unknown, Next_Station shall
be equal to This_Station. */ be equal to This_Station. */
static uint8_t Next_Station; static uint8_t Next_Station = 0;
/* "Poll Station," the MAC address of the node to which This Station last */ /* "Poll Station," the MAC address of the node to which This Station last */
/* sent a Poll For Master. This is used during token maintenance. */ /* sent a Poll For Master. This is used during token maintenance. */
static uint8_t Poll_Station; static uint8_t Poll_Station;
/* A counter of transmission retries used for Token and Poll For Master */ /* A counter of transmission retries used for Token and Poll For Master */
/* transmission. */ /* transmission. */
static unsigned RetryCount; static unsigned RetryCount = 0;
/* The number of tokens received by this node. When this counter reaches */ /* 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 */ /* the value Npoll, the node polls the address range between TS and NS */
/* for additional master nodes. TokenCount is set to zero at the end of */ /* for additional master nodes. TokenCount is set to zero at the end of */
/* the polling process. */ /* the polling process. */
static unsigned TokenCount; static unsigned TokenCount = 0;
/* next-x-station calculations */ /* next-x-station calculations */
uint8_t next_poll_station = 0; uint8_t next_poll_station = 0;
uint8_t next_this_station = 0; uint8_t next_this_station = 0;
@@ -748,10 +748,11 @@ static bool MSTP_Master_Node_FSM(void)
/* timeout values */ /* timeout values */
uint16_t my_timeout = 10, ns_timeout = 0; uint16_t my_timeout = 10, ns_timeout = 0;
bool matched = false; bool matched = false;
bool timeout = false;
/* transition immediately to the next state */ /* transition immediately to the next state */
bool transition_now = false; bool transition_now = false;
/* packet from the PDU Queue */ /* packet from the PDU Queue */
struct mstp_pdu_packet *pkt; struct mstp_pdu_packet *pkt = NULL;
/* some calculations that several states need */ /* some calculations that several states need */
next_poll_station = (Poll_Station + 1) % (Nmax_master + 1); next_poll_station = (Poll_Station + 1) % (Nmax_master + 1);
@@ -1183,11 +1184,8 @@ static bool MSTP_Master_Node_FSM(void)
/* BACnet Data Expecting Reply, a Test_Request, or */ /* BACnet Data Expecting Reply, a Test_Request, or */
/* a proprietary frame that expects a reply is received. */ /* a proprietary frame that expects a reply is received. */
case MSTP_MASTER_STATE_ANSWER_DATA_REQUEST: case MSTP_MASTER_STATE_ANSWER_DATA_REQUEST:
if (rs485_silence_elapsed(Treply_delay)) { timeout = rs485_silence_elapsed(Treply_delay);
Master_State = MSTP_MASTER_STATE_IDLE; if (!timeout) {
/* clear our flag we were holding for comparison */
MSTP_Flag.ReceivedValidFrame = false;
} else {
pkt = (struct mstp_pdu_packet *) Ringbuf_Peek(&PDU_Queue); pkt = (struct mstp_pdu_packet *) Ringbuf_Peek(&PDU_Queue);
if (pkt != NULL) { if (pkt != NULL) {
matched = matched =
@@ -1197,6 +1195,7 @@ static bool MSTP_Master_Node_FSM(void)
} else { } else {
matched = false; matched = false;
} }
}
if (matched) { if (matched) {
/* Reply */ /* Reply */
/* If a reply is available from the higher layers */ /* If a reply is available from the higher layers */
@@ -1220,7 +1219,7 @@ static bool MSTP_Master_Node_FSM(void)
MSTP_Flag.ReceivedValidFrame = false; MSTP_Flag.ReceivedValidFrame = false;
/* clear the queue */ /* clear the queue */
(void) Ringbuf_Pop(&PDU_Queue, NULL); (void) Ringbuf_Pop(&PDU_Queue, NULL);
} else if (pkt != NULL) { } else if ((pkt != NULL) || timeout) {
/* DeferredReply */ /* DeferredReply */
/* If no reply will be available from the higher layers */ /* If no reply will be available from the higher layers */
/* within Treply_delay after the reception of the */ /* within Treply_delay after the reception of the */
@@ -1236,7 +1235,6 @@ static bool MSTP_Master_Node_FSM(void)
/* clear our flag we were holding for comparison */ /* clear our flag we were holding for comparison */
MSTP_Flag.ReceivedValidFrame = false; MSTP_Flag.ReceivedValidFrame = false;
} }
}
break; break;
default: default:
Master_State = MSTP_MASTER_STATE_IDLE; Master_State = MSTP_MASTER_STATE_IDLE;