Changed the MSTP_MASTER_STATE_ANSWER_DATA_REQUEST state to always send a REPLY_POSTPONED by
commenting out the section that checks for new packets to send. It was not the intent of the BACnet standard, but it makes the Master Node FSM compliant. It's either that or re-parse the message for a matching apdu and invoke id, and then defer if the next message does not match. The problem happens when an unconfirmed request (i.e. WhoIs) is followed immediated by a confirmed request (i.e. ReadProperty) before the device can respond to the unconfirmed request (i.e. the I-Am is queued in the Transmit buffer).
This commit is contained in:
+111
-193
@@ -1,6 +1,6 @@
|
||||
/*####COPYRIGHTBEGIN####
|
||||
-------------------------------------------
|
||||
Copyright (C) 2003 Steve Karg
|
||||
Copyright (C) 2003-2007 Steve Karg
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
@@ -46,15 +46,20 @@
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#if PRINT_ENABLED
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
#include "mstp.h"
|
||||
#include "crc.h"
|
||||
#include "rs485.h"
|
||||
#if PRINT_ENABLED
|
||||
#include "mstptext.h"
|
||||
#endif
|
||||
|
||||
/* debug print statements */
|
||||
#if PRINT_ENABLED
|
||||
#define PRINT_ENABLED_RECEIVE 0
|
||||
#define PRINT_ENABLED_RECEIVE_DATA 0
|
||||
#define PRINT_ENABLED_RECEIVE_DATA 1
|
||||
#define PRINT_ENABLED_RECEIVE_ERRORS 1
|
||||
#define PRINT_ENABLED_MASTER 0
|
||||
#else
|
||||
@@ -94,7 +99,7 @@
|
||||
/* not to exceed 100 milliseconds.) */
|
||||
/* At 9600 baud, 60 bit times would be about 6.25 milliseconds */
|
||||
/* const uint16_t Tframe_abort = 1 + ((1000 * 60) / 9600); */
|
||||
#define Tframe_abort 100
|
||||
#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. */
|
||||
@@ -150,13 +155,13 @@ bool MSTP_Line_Active(volatile struct mstp_port_struct_t *mstp_port)
|
||||
return (mstp_port->EventCount > Nmin_octets);
|
||||
}
|
||||
|
||||
unsigned MSTP_Create_Frame(uint8_t * buffer, /* where frame is loaded */
|
||||
unsigned buffer_len, /* amount of space available */
|
||||
uint16_t MSTP_Create_Frame(uint8_t * buffer, /* where frame is loaded */
|
||||
uint16_t buffer_len, /* amount of space available */
|
||||
uint8_t frame_type, /* type of frame to send - see defines */
|
||||
uint8_t destination, /* destination address */
|
||||
uint8_t source, /* source address */
|
||||
uint8_t * data, /* any data to be sent - may be null */
|
||||
unsigned data_len)
|
||||
uint16_t data_len)
|
||||
{ /* number of bytes of data (up to 501) */
|
||||
uint8_t crc8 = 0xFF; /* used to calculate the crc value */
|
||||
uint16_t crc16 = 0xFFFF; /* used to calculate the crc value */
|
||||
@@ -208,53 +213,25 @@ void MSTP_Create_And_Send_Frame(volatile struct mstp_port_struct_t *mstp_port,
|
||||
uint8_t destination, /* destination address */
|
||||
uint8_t source, /* source address */
|
||||
uint8_t * data, /* any data to be sent - may be null */
|
||||
unsigned data_len)
|
||||
uint16_t data_len)
|
||||
{ /* number of bytes of data (up to 501) */
|
||||
mstp_port->TxLength = (uint16_t) MSTP_Create_Frame(
|
||||
(uint8_t *)&mstp_port->TxBuffer[0], /* where frame is loaded */
|
||||
sizeof(mstp_port->TxBuffer), /* amount of space available */
|
||||
uint16_t len = 0; /* number of bytes to send */
|
||||
|
||||
len = MSTP_Create_Frame(
|
||||
(uint8_t *)&mstp_port->OutputBuffer[0], /* where frame is loaded */
|
||||
mstp_port->OutputBufferSize, /* amount of space available */
|
||||
frame_type, /* type of frame to send - see defines */
|
||||
destination, /* destination address */
|
||||
source, /* source address */
|
||||
data, /* any data to be sent - may be null */
|
||||
data_len); /* number of bytes of data (up to 501) */
|
||||
|
||||
RS485_Send_Frame(
|
||||
mstp_port,
|
||||
(uint8_t *)&mstp_port->TxBuffer[0],
|
||||
mstp_port->TxLength);
|
||||
RS485_Send_Frame(mstp_port,
|
||||
(uint8_t *)&mstp_port->OutputBuffer[0],
|
||||
len);
|
||||
/* FIXME: be sure to reset SilenceTimer after each octet is sent! */
|
||||
}
|
||||
|
||||
#if PRINT_ENABLED_RECEIVE
|
||||
char *mstp_receive_state_text(int state)
|
||||
{
|
||||
char *text = "unknown";
|
||||
|
||||
switch (state) {
|
||||
case MSTP_RECEIVE_STATE_IDLE:
|
||||
text = "IDLE";
|
||||
break;
|
||||
case MSTP_RECEIVE_STATE_PREAMBLE:
|
||||
text = "PREAMBLE";
|
||||
break;
|
||||
case MSTP_RECEIVE_STATE_HEADER:
|
||||
text = "HEADER";
|
||||
break;
|
||||
case MSTP_RECEIVE_STATE_HEADER_CRC:
|
||||
text = "HEADER_CRC";
|
||||
break;
|
||||
case MSTP_RECEIVE_STATE_DATA:
|
||||
text = "DATA";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
#endif
|
||||
|
||||
void MSTP_Receive_Frame_FSM(volatile struct mstp_port_struct_t *mstp_port)
|
||||
{
|
||||
#if PRINT_ENABLED_RECEIVE_DATA
|
||||
@@ -263,7 +240,7 @@ void MSTP_Receive_Frame_FSM(volatile struct mstp_port_struct_t *mstp_port)
|
||||
#if PRINT_ENABLED_RECEIVE
|
||||
fprintf(stderr,
|
||||
"MSTP Rx: State=%s Data=%02X hCRC=%02X Index=%u EC=%u DateLen=%u Silence=%u\n",
|
||||
mstp_receive_state_text(mstp_port->receive_state),
|
||||
mstptext_receive_state(mstp_port->receive_state),
|
||||
mstp_port->DataRegister, mstp_port->HeaderCRC, mstp_port->Index,
|
||||
mstp_port->EventCount, mstp_port->DataLength,
|
||||
mstp_port->SilenceTimer);
|
||||
@@ -365,8 +342,10 @@ void MSTP_Receive_Frame_FSM(volatile struct mstp_port_struct_t *mstp_port)
|
||||
mstp_port->ReceivedInvalidFrame = true;
|
||||
/* wait for the start of a frame. */
|
||||
mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE;
|
||||
#if PRINT_ENABLED_RECEIVE_ERRORS
|
||||
fprintf(stderr,"MSTP: Rx Header: SilenceTimer %d > %d\n",
|
||||
mstp_port->SilenceTimer, Tframe_abort);
|
||||
#endif
|
||||
}
|
||||
/* Error */
|
||||
else if (mstp_port->ReceiveError == true) {
|
||||
@@ -375,7 +354,9 @@ void MSTP_Receive_Frame_FSM(volatile struct mstp_port_struct_t *mstp_port)
|
||||
INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount);
|
||||
/* indicate that an error has occurred during the reception of a frame */
|
||||
mstp_port->ReceivedInvalidFrame = true;
|
||||
#if PRINT_ENABLED_RECEIVE_ERRORS
|
||||
fprintf(stderr,"MSTP: Rx Header: ReceiveError\n");
|
||||
#endif
|
||||
/* wait for the start of a frame. */
|
||||
mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE;
|
||||
} else if (mstp_port->DataAvailable == true) {
|
||||
@@ -465,45 +446,50 @@ void MSTP_Receive_Frame_FSM(volatile struct mstp_port_struct_t *mstp_port)
|
||||
/* wait for the start of the next frame. */
|
||||
mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE;
|
||||
} else {
|
||||
if ((mstp_port->DestinationAddress ==
|
||||
mstp_port->This_Station)
|
||||
|| (mstp_port->DestinationAddress ==
|
||||
MSTP_BROADCAST_ADDRESS)
|
||||
|| (mstp_port->Lurking)) {
|
||||
/* FIXME: if we don't decode the data, we could
|
||||
get confused if the Preamble 55 FF is part
|
||||
of the data. */
|
||||
/* Data */
|
||||
if ((mstp_port->DataLength) &&
|
||||
(mstp_port->DataLength <= MAX_MPDU)) {
|
||||
/* 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 > MAX_MPDU) {
|
||||
/* indicate that a frame with an illegal or */
|
||||
/* unacceptable data length has been received */
|
||||
mstp_port->ReceivedInvalidFrame = true;
|
||||
#if PRINT_ENABLED_RECEIVE_ERRORS
|
||||
fprintf(stderr,"MSTP: Rx Header: FrameTooLong %d\n",
|
||||
mstp_port->DataLength);
|
||||
#endif
|
||||
/* wait for the start of the next frame. */
|
||||
mstp_port->receive_state =
|
||||
MSTP_RECEIVE_STATE_IDLE;
|
||||
/* indicate that a frame with an illegal or */
|
||||
/* unacceptable data length has been received */
|
||||
mstp_port->ReceivedInvalidFrame = true;
|
||||
}
|
||||
/* NoData */
|
||||
else if (mstp_port->DataLength == 0) {
|
||||
/* indicate that a frame with no data has been received */
|
||||
mstp_port->ReceivedValidFrame = true;
|
||||
/* wait for the start of the next frame. */
|
||||
mstp_port->receive_state =
|
||||
MSTP_RECEIVE_STATE_IDLE;
|
||||
#if PRINT_ENABLED_RECEIVE_DATA
|
||||
fprintf(stderr, "%s",
|
||||
mstptext_frame_type(mstp_port->FrameType));
|
||||
#endif
|
||||
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 */
|
||||
}
|
||||
}
|
||||
/* Data */
|
||||
else {
|
||||
mstp_port->Index = 0;
|
||||
mstp_port->DataCRC = 0xFFFF;
|
||||
/* receive the data portion of the frame. */
|
||||
mstp_port->receive_state =
|
||||
MSTP_RECEIVE_STATE_DATA;
|
||||
}
|
||||
}
|
||||
/* NotForUs */
|
||||
else {
|
||||
/* wait for the start of the next frame. */
|
||||
mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE;
|
||||
mstp_port->receive_state =
|
||||
MSTP_RECEIVE_STATE_IDLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -578,10 +564,25 @@ void MSTP_Receive_Frame_FSM(volatile struct mstp_port_struct_t *mstp_port)
|
||||
mstp_port->DataCRC = CRC_Calc_Data(mstp_port->DataRegister,
|
||||
mstp_port->DataCRC);
|
||||
mstp_port->DataCRCActualLSB = mstp_port->DataRegister;
|
||||
#if PRINT_ENABLED_RECEIVE_DATA
|
||||
fprintf(stderr, "%s",
|
||||
mstptext_frame_type(mstp_port->FrameType));
|
||||
#endif
|
||||
/* STATE DATA CRC - no need for new state */
|
||||
/* indicate the complete reception of a valid frame */
|
||||
if (mstp_port->DataCRC == 0xF0B8)
|
||||
mstp_port->ReceivedValidFrame = true;
|
||||
if (mstp_port->DataCRC == 0xF0B8) {
|
||||
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 */
|
||||
}
|
||||
}
|
||||
else {
|
||||
mstp_port->ReceivedInvalidFrame = true;
|
||||
#if PRINT_ENABLED_RECEIVE_ERRORS
|
||||
@@ -612,91 +613,10 @@ void MSTP_Receive_Frame_FSM(volatile struct mstp_port_struct_t *mstp_port)
|
||||
return;
|
||||
}
|
||||
|
||||
#if PRINT_ENABLED
|
||||
char *mstp_master_state_text(int state)
|
||||
{
|
||||
char *text = "unknown";
|
||||
|
||||
switch (state) {
|
||||
case MSTP_MASTER_STATE_INITIALIZE:
|
||||
text = "INITIALIZE";
|
||||
break;
|
||||
case MSTP_MASTER_STATE_IDLE:
|
||||
text = "IDLE";
|
||||
break;
|
||||
case MSTP_MASTER_STATE_USE_TOKEN:
|
||||
text = "USE_TOKEN";
|
||||
break;
|
||||
case MSTP_MASTER_STATE_WAIT_FOR_REPLY:
|
||||
text = "WAIT_FOR_REPLY";
|
||||
break;
|
||||
case MSTP_MASTER_STATE_DONE_WITH_TOKEN:
|
||||
text = "IDLE";
|
||||
break;
|
||||
case MSTP_MASTER_STATE_PASS_TOKEN:
|
||||
text = "DONE_WITH_TOKEN";
|
||||
break;
|
||||
case MSTP_MASTER_STATE_NO_TOKEN:
|
||||
text = "NO_TOKEN";
|
||||
break;
|
||||
case MSTP_MASTER_STATE_POLL_FOR_MASTER:
|
||||
text = "POLL_FOR_MASTER";
|
||||
break;
|
||||
case MSTP_MASTER_STATE_ANSWER_DATA_REQUEST:
|
||||
text = "ANSWER_DATA_REQUEST";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if PRINT_ENABLED
|
||||
char *mstp_frame_type_text(int type)
|
||||
{
|
||||
char *text = "unknown";
|
||||
|
||||
switch (type) {
|
||||
case FRAME_TYPE_TOKEN:
|
||||
text = "TOKEN";
|
||||
break;
|
||||
case FRAME_TYPE_POLL_FOR_MASTER:
|
||||
text = "POLL_FOR_MASTER";
|
||||
break;
|
||||
case FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER:
|
||||
text = "REPLY_TO_POLL_FOR_MASTER";
|
||||
break;
|
||||
case FRAME_TYPE_TEST_REQUEST:
|
||||
text = "TEST_REQUEST";
|
||||
break;
|
||||
case FRAME_TYPE_TEST_RESPONSE:
|
||||
text = "TEST_RESPONSE";
|
||||
break;
|
||||
case FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY:
|
||||
text = "BACNET_DATA_EXPECTING_REPLY";
|
||||
break;
|
||||
case FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY:
|
||||
text = "BACNET_DATA_NOT_EXPECTING_REPLY";
|
||||
break;
|
||||
case FRAME_TYPE_REPLY_POSTPONED:
|
||||
text = "REPLY_POSTPONED";
|
||||
break;
|
||||
default:
|
||||
if ((type >= FRAME_TYPE_PROPRIETARY_MIN) &&
|
||||
(type <= FRAME_TYPE_PROPRIETARY_MAX))
|
||||
text = "PROPRIETARY";
|
||||
break;
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* returns true if we need to transition immediately */
|
||||
bool MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t * mstp_port)
|
||||
{
|
||||
unsigned length = 0;
|
||||
uint8_t next_poll_station = 0;
|
||||
uint8_t next_this_station = 0;
|
||||
uint8_t next_next_station = 0;
|
||||
@@ -728,7 +648,7 @@ bool MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t * mstp_port)
|
||||
mstp_port->EventCount,
|
||||
mstp_port->TokenCount,
|
||||
mstp_port->SilenceTimer,
|
||||
mstp_master_state_text(mstp_port->master_state));
|
||||
mstptext_master_state(mstp_port->master_state));
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -770,7 +690,7 @@ bool MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t * mstp_port)
|
||||
mstp_port->DataLength,
|
||||
mstp_port->FrameCount,
|
||||
mstp_port->SilenceTimer,
|
||||
mstp_frame_type_text(mstp_port->FrameType));
|
||||
mstptext_frame_type(mstp_port->FrameType));
|
||||
#endif
|
||||
/* destined for me! */
|
||||
if ((mstp_port->DestinationAddress ==
|
||||
@@ -834,12 +754,12 @@ bool MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t * mstp_port)
|
||||
/* more data frames. These may be BACnet Data frames or */
|
||||
/* proprietary frames. */
|
||||
case MSTP_MASTER_STATE_USE_TOKEN:
|
||||
mstp_port->TxLength = dlmstp_get_send(
|
||||
length = dlmstp_get_send(
|
||||
mstp_port->This_Station,
|
||||
(uint8_t *)&mstp_port->TxBuffer[0],
|
||||
sizeof(mstp_port->TxBuffer),
|
||||
(uint8_t *)&mstp_port->OutputBuffer[0],
|
||||
mstp_port->OutputBufferSize,
|
||||
0); /* milliseconds to wait for a packet */
|
||||
if (mstp_port->TxLength < 1) {
|
||||
if (length < 1) {
|
||||
/* NothingToSend */
|
||||
mstp_port->FrameCount = mstp_port->Nmax_info_frames;
|
||||
mstp_port->master_state = MSTP_MASTER_STATE_DONE_WITH_TOKEN;
|
||||
@@ -848,11 +768,14 @@ bool MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t * mstp_port)
|
||||
/* if we missed our timing deadline, another token will be sent */
|
||||
mstp_port->master_state = MSTP_MASTER_STATE_IDLE;
|
||||
} else {
|
||||
uint8_t destination = mstp_port->TxBuffer[3];
|
||||
/* don't send it if we are too late in getting out */
|
||||
uint8_t frame_type = mstp_port->OutputBuffer[2];
|
||||
uint8_t destination = mstp_port->OutputBuffer[3];
|
||||
RS485_Send_Frame(mstp_port,
|
||||
(uint8_t *) & mstp_port->TxBuffer[0], mstp_port->TxLength);
|
||||
(uint8_t *) & mstp_port->OutputBuffer[0], length);
|
||||
mstp_port->FrameCount++;
|
||||
switch (mstp_port->TxFrameType) {
|
||||
/* last trasmitted frame type */
|
||||
switch (frame_type) {
|
||||
case FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY:
|
||||
/* SendAndWait */
|
||||
if (destination == MSTP_BROADCAST_ADDRESS)
|
||||
@@ -873,7 +796,6 @@ bool MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t * mstp_port)
|
||||
MSTP_MASTER_STATE_DONE_WITH_TOKEN;
|
||||
break;
|
||||
}
|
||||
mstp_port->TxReady = false;
|
||||
}
|
||||
break;
|
||||
/* In the WAIT_FOR_REPLY state, the node waits for */
|
||||
@@ -900,7 +822,8 @@ bool MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t * mstp_port)
|
||||
} else if (mstp_port->ReceivedValidFrame == true) {
|
||||
if (mstp_port->DestinationAddress ==
|
||||
mstp_port->This_Station) {
|
||||
switch (mstp_port->TxFrameType) {
|
||||
/* Last Transmitted Frame Type */
|
||||
switch (mstp_port->OutputBuffer[2]) {
|
||||
case FRAME_TYPE_REPLY_POSTPONED:
|
||||
/* ReceivedReplyPostponed */
|
||||
mstp_port->master_state =
|
||||
@@ -1177,9 +1100,11 @@ bool MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t * mstp_port)
|
||||
/* BACnet Data Expecting Reply, a Test_Request, or */
|
||||
/* a proprietary frame that expects a reply is received. */
|
||||
case MSTP_MASTER_STATE_ANSWER_DATA_REQUEST:
|
||||
#if 0
|
||||
/* FIXME: we always defer the reply to be safe */
|
||||
/* FIXME: if we knew the APDU type received, we could
|
||||
see if the next message was that same APDU type */
|
||||
/* FIXME: we could always defer the reply to be safe */
|
||||
see if the next message was that same APDU type
|
||||
along with the matching src/dest and invoke ID */
|
||||
if ((mstp_port->SilenceTimer <= Treply_delay) &&
|
||||
mstp_port->TxReady) {
|
||||
/* Reply */
|
||||
@@ -1189,21 +1114,22 @@ bool MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t * mstp_port)
|
||||
/* (the mechanism used to determine this is a local matter), */
|
||||
/* then call MSTP_Create_And_Send_Frame to transmit the reply frame */
|
||||
/* and enter the IDLE state to wait for the next frame. */
|
||||
mstp_port->TxLength = dlmstp_get_send(
|
||||
length = dlmstp_get_send(
|
||||
mstp_port->This_Station,
|
||||
(uint8_t *)&mstp_port->TxBuffer[0],
|
||||
sizeof(mstp_port->TxBuffer),
|
||||
(uint8_t *)&mstp_port->OutputBuffer[0],
|
||||
mstp_port->OutputBufferSize,
|
||||
0); /* milliseconds to wait for a packet */
|
||||
if ((mstp_port->FrameType ==
|
||||
FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY)
|
||||
&& (mstp_port->TxLength > 0)) {
|
||||
&& (length > 0)) {
|
||||
RS485_Send_Frame(mstp_port,
|
||||
(uint8_t *) & mstp_port->TxBuffer[0],
|
||||
mstp_port->TxLength);
|
||||
length);
|
||||
mstp_port->TxReady = false;
|
||||
mstp_port->master_state = MSTP_MASTER_STATE_IDLE;
|
||||
}
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
/* DeferredReply */
|
||||
/* If no reply will be available from the higher layers */
|
||||
/* within Treply_delay after the reception of the */
|
||||
@@ -1213,7 +1139,7 @@ bool MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t * mstp_port)
|
||||
/* Any reply shall wait until this node receives the token. */
|
||||
/* Call MSTP_Create_And_Send_Frame to transmit a Reply Postponed frame, */
|
||||
/* and enter the IDLE state. */
|
||||
else {
|
||||
{
|
||||
MSTP_Create_And_Send_Frame(mstp_port,
|
||||
FRAME_TYPE_REPLY_POSTPONED,
|
||||
mstp_port->SourceAddress,
|
||||
@@ -1232,10 +1158,10 @@ bool MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t * mstp_port)
|
||||
/* note: This_Station assumed to be set with the MAC address */
|
||||
/* note: Nmax_info_frames assumed to be set (default=1) */
|
||||
/* note: Nmax_master assumed to be set (default=127) */
|
||||
/* note: InputBuffer and InputBufferSize assumed to be set */
|
||||
/* note: OutputBuffer and OutputBufferSize assumed to be set */
|
||||
void MSTP_Init(volatile struct mstp_port_struct_t *mstp_port)
|
||||
{
|
||||
int i; /*loop counter */
|
||||
|
||||
if (mstp_port) {
|
||||
mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE;
|
||||
mstp_port->master_state = MSTP_MASTER_STATE_INITIALIZE;
|
||||
@@ -1252,35 +1178,27 @@ void MSTP_Init(volatile struct mstp_port_struct_t *mstp_port)
|
||||
mstp_port->HeaderCRC = 0;
|
||||
mstp_port->Index = 0;
|
||||
mstp_port->Index = 0;
|
||||
for (i = 0; i < sizeof(mstp_port->InputBuffer); i++) {
|
||||
mstp_port->InputBuffer[i] = 0;
|
||||
}
|
||||
mstp_port->Next_Station = mstp_port->This_Station;
|
||||
mstp_port->Poll_Station = mstp_port->This_Station;
|
||||
mstp_port->ReceivedInvalidFrame = false;
|
||||
mstp_port->ReceivedValidFrame = false;
|
||||
mstp_port->RetryCount = 0;
|
||||
mstp_port->SilenceTimer = 0;
|
||||
/* mstp_port->ReplyPostponedTimer = 0; */
|
||||
mstp_port->SoleMaster = false;
|
||||
mstp_port->SourceAddress = 0;
|
||||
mstp_port->TokenCount = 0;
|
||||
mstp_port->Lurking = false;
|
||||
#if 0
|
||||
/* these are adjustable, so should already be set */
|
||||
/* FIXME: you must point these buffers to actual byte buckets
|
||||
in the dlmstp function before or after calling this init. */
|
||||
mstp_port->InputBuffer = &InputBuffer[0];
|
||||
mstp_port->InputBufferSize = sizeof(InputBuffer);
|
||||
mstp_port->OutputBuffer = &OutputBuffer[0];
|
||||
mstp_port->OutputBufferSize = sizeof(OutputBuffer);
|
||||
/* these are adjustable, so you must set these in dlmstp */
|
||||
mstp_port->Nmax_info_frames = DEFAULT_MAX_INFO_FRAMES;
|
||||
mstp_port->Nmax_master = DEFAULT_MAX_MASTER;
|
||||
#endif
|
||||
|
||||
/* An array of octets, used to store PDU octets prior to being transmitted. */
|
||||
/* This array is only used for APDU messages */
|
||||
for (i = 0; i < sizeof(mstp_port->TxBuffer); i++) {
|
||||
mstp_port->TxBuffer[i] = 0;
|
||||
}
|
||||
mstp_port->TxLength = 0;
|
||||
mstp_port->TxReady = false;
|
||||
mstp_port->TxFrameType = 0;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user