Returned Tusage_delay to the MS/TP state machines to fix excessive Reply-Posponed messages when received packet is decoupled from immediate handling. Some BACnet routers do not handle Reply-Postponed correctly and drop the subsequent valid reply.

Added Slave Node FSM to linux/win32 MS/TP layer.
Added PDU queue to Linux MS/TP datalink layer.
This commit is contained in:
skarg
2011-08-24 12:33:20 +00:00
parent bd7011fda1
commit 26b5fdd3d0
8 changed files with 238 additions and 94 deletions
+14 -12
View File
@@ -1090,7 +1090,6 @@ static bool MSTP_Master_Node_FSM(
/* BACnet Data Expecting Reply, a Test_Request, or */
/* a proprietary frame that expects a reply is received. */
case MSTP_MASTER_STATE_ANSWER_DATA_REQUEST:
/* Note: we could wait for up to Treply_delay */
matched = false;
if (!Ringbuf_Empty(&PDU_Queue)) {
pkt = (struct mstp_pdu_packet *) Ringbuf_Get_Front(&PDU_Queue);
@@ -1117,7 +1116,9 @@ static bool MSTP_Master_Node_FSM(
MSTP_Send_Frame(frame_type, pkt->destination_mac, This_Station,
(uint8_t *) & pkt->buffer[0], pkt->length);
Master_State = MSTP_MASTER_STATE_IDLE;
} else {
/* clear our flag we were holding for comparison */
MSTP_Flag.ReceivedValidFrame = false;
} else if (rs485_silence_time_elapsed(Treply_delay)) {
/* DeferredReply */
/* If no reply will be available from the higher layers */
/* within Treply_delay after the reception of the */
@@ -1130,9 +1131,9 @@ static bool MSTP_Master_Node_FSM(
MSTP_Send_Frame(FRAME_TYPE_REPLY_POSTPONED, SourceAddress,
This_Station, NULL, 0);
Master_State = MSTP_MASTER_STATE_IDLE;
/* clear our flag we were holding for comparison */
MSTP_Flag.ReceivedValidFrame = false;
}
/* clear our flag we were holding for comparison */
MSTP_Flag.ReceivedValidFrame = false;
break;
default:
Master_State = MSTP_MASTER_STATE_IDLE;
@@ -1150,6 +1151,7 @@ static void MSTP_Slave_Node_FSM(
/* did the frame in the queue match the last request? */
bool matched = false;
Master_State = MSTP_MASTER_STATE_IDLE;
if (MSTP_Flag.ReceivedInvalidFrame == true) {
/* ReceivedInvalidFrame */
/* invalid frame was received */
@@ -1175,13 +1177,7 @@ static void MSTP_Slave_Node_FSM(
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 {
if (!Ringbuf_Empty(&PDU_Queue)) {
pkt = (struct mstp_pdu_packet *) Ringbuf_Pop_Front(&PDU_Queue);
matched =
dlmstp_compare_data_expecting_reply(&InputBuffer[0],
@@ -1204,10 +1200,16 @@ static void MSTP_Slave_Node_FSM(
}
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;
} else if (rs485_silence_time_elapsed(Treply_delay)) {
/* 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. */
/* clear our flag we were holding for comparison */
MSTP_Flag.ReceivePacketPending = false;
}
}
}