diff --git a/bacnet-stack/dlmstp.h b/bacnet-stack/dlmstp.h
index a5d3918d..3c9ee66a 100644
--- a/bacnet-stack/dlmstp.h
+++ b/bacnet-stack/dlmstp.h
@@ -45,6 +45,55 @@
#define MAX_HEADER (2+1+1+1+2+1+2+1)
#define MAX_MPDU (MAX_HEADER+MAX_PDU)
+/* 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
+/* The initial CRC16 checksum value */
+#define CRC16_INITIAL_VALUE (0xFFFF)
+
+/* receive FSM states */
+typedef enum {
+ MSTP_RECEIVE_STATE_IDLE = 0,
+ MSTP_RECEIVE_STATE_PREAMBLE = 1,
+ MSTP_RECEIVE_STATE_HEADER = 2,
+ MSTP_RECEIVE_STATE_HEADER_CRC = 3,
+ MSTP_RECEIVE_STATE_DATA = 4
+} 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;
+
typedef struct dlmstp_packet {
bool ready; /* true if ready to be sent or received */
BACNET_ADDRESS address; /* source address */
diff --git a/bacnet-stack/ports/linux/mstp.c b/bacnet-stack/ports/linux/mstp.c
index f5da3012..154e4388 100644
--- a/bacnet-stack/ports/linux/mstp.c
+++ b/bacnet-stack/ports/linux/mstp.c
@@ -1177,9 +1177,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 */
@@ -1203,7 +1205,8 @@ bool MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t * mstp_port)
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 +1216,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,
diff --git a/bacnet-stack/ports/pic18f6720/mstp.c b/bacnet-stack/ports/pic18f6720/mstp.c
index 47a3d6bd..faae1286 100644
--- a/bacnet-stack/ports/pic18f6720/mstp.c
+++ b/bacnet-stack/ports/pic18f6720/mstp.c
@@ -53,6 +53,9 @@
#include "bytes.h"
#include "crc.h"
#include "rs485.h"
+#if PRINT_ENABLED
+#include "mstptext.h"
+#endif
/* debug print statements */
#if PRINT_ENABLED
@@ -227,35 +230,6 @@ void MSTP_Create_And_Send_Frame(volatile struct mstp_port_struct_t *mstp_port,
/* 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
@@ -264,7 +238,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);
@@ -576,88 +550,6 @@ 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)
{
@@ -694,7 +586,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
@@ -736,7 +628,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 ==
@@ -1139,8 +1031,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 */
+ 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 */
@@ -1159,7 +1054,8 @@ bool MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t * mstp_port)
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 */
@@ -1169,7 +1065,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,
diff --git a/bacnet-stack/ports/rtos32/mstp.c b/bacnet-stack/ports/rtos32/mstp.c
index 5303eabf..77971849 100644
--- a/bacnet-stack/ports/rtos32/mstp.c
+++ b/bacnet-stack/ports/rtos32/mstp.c
@@ -1166,46 +1166,33 @@ 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
if (mstp_port->ReplyPostponedTimer <= Treply_delay) {
- /* 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_Create_And_Send_Frame to transmit the reply frame */
- /* and enter the IDLE state to wait for the next frame. */
+ /* 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
+ along with the matching src/dest and invoke ID */
if ((mstp_port->FrameType ==
FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY)
&& (mstp_port->TxReady)) {
+ /* 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_Create_And_Send_Frame to transmit the reply frame */
+ /* and enter the IDLE state to wait for the next frame. */
RS485_Send_Frame(mstp_port,
(uint8_t *) & mstp_port->TxBuffer[0],
mstp_port->TxLength);
mstp_port->TxReady = false;
mstp_port->master_state = MSTP_MASTER_STATE_IDLE;
transition_now = true;
+ } else {
+ /* Test Request - handled directly in IDLE state */
}
- /* Test Request */
- /* If a receiving node can successfully receive and return */
- /* the information field, it shall do so. If it cannot receive */
- /* and return the entire information field but can detect */
- /* the reception of a valid Test_Request frame */
- /* (for example, by computing the CRC on octets as */
- /* they are received), then the receiving node shall discard */
- /* the information field and return a Test_Response containing */
- /* no information field. If the receiving node cannot detect */
- /* the valid reception of frames with overlength information fields, */
- /* then no response shall be returned. */
- else if (mstp_port->FrameType == FRAME_TYPE_TEST_REQUEST) {
- MSTP_Create_And_Send_Frame(mstp_port,
- FRAME_TYPE_TEST_RESPONSE,
- mstp_port->SourceAddress,
- mstp_port->This_Station,
- (uint8_t *) & mstp_port->InputBuffer[0],
- mstp_port->DataLength);
- mstp_port->master_state = MSTP_MASTER_STATE_IDLE;
- transition_now = true;
- }
- }
+ } else
+#endif
/* DeferredReply */
/* If no reply will be available from the higher layers */
/* within Treply_delay after the reception of the */
@@ -1215,7 +1202,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,
@@ -1719,7 +1706,6 @@ void testMasterNodeFSM(Test * pTest)
MSTP_Init(&mstp_port, my_mac);
ct_test(pTest, mstp_port.master_state == MSTP_MASTER_STATE_INITIALIZE);
-
}
#endif
diff --git a/bacnet-stack/ports/win32/dlmstp.c b/bacnet-stack/ports/win32/dlmstp.c
index 38a62318..cf60c8a5 100644
--- a/bacnet-stack/ports/win32/dlmstp.c
+++ b/bacnet-stack/ports/win32/dlmstp.c
@@ -42,11 +42,14 @@
/* Number of MS/TP Packets Rx/Tx */
uint16_t MSTP_Packets = 0;
-/* receive buffer */
-static DLMSTP_PACKET Receive_Buffer;
-/* temp buffer for NPDU insertion */
+/* packet queues */
+static DLMSTP_PACKET Receive_Packet;
+static DLMSTP_PACKET Transmit_Packet;
/* local MS/TP port data - shared with RS-485 */
volatile struct mstp_port_struct_t MSTP_Port;
+/* buffers needed by mstp port struct */
+static uint8_t TxBuffer[MAX_MPDU];
+static uint8_t RxBuffer[MAX_MPDU];
#define INCREMENT_AND_LIMIT_UINT16(x) {if (x < 0xFFFF) x++;}
@@ -76,13 +79,12 @@ int dlmstp_send_pdu(BACNET_ADDRESS * dest, /* destination address */
{ /* number of bytes of data */
int bytes_sent = 0;
uint8_t destination = 0; /* destination address */
- BACNET_ADDRESS src;
- if (MSTP_Port.TxReady == false) {
+ if (!Transmit_Packet.ready) {
if (npdu_data->data_expecting_reply)
- MSTP_Port.TxFrameType = FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY;
+ Transmit_Packet.frame_type = FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY;
else
- MSTP_Port.TxFrameType =
+ Transmit_Packet.frame_type =
FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY;
/* load destination MAC address */
@@ -91,17 +93,17 @@ int dlmstp_send_pdu(BACNET_ADDRESS * dest, /* destination address */
} else {
return -2;
}
- dlmstp_get_my_address(&src);
if ((8 /* header len */ + pdu_len) > MAX_MPDU) {
return -4;
}
- bytes_sent = MSTP_Create_Frame(
- (uint8_t *) & MSTP_Port.TxBuffer[0],
- sizeof(MSTP_Port.TxBuffer),
- MSTP_Port.TxFrameType,
- destination, MSTP_Port.This_Station, pdu, pdu_len);
- MSTP_Port.TxLength = bytes_sent;
- MSTP_Port.TxReady = true;
+ Transmit_Packet.pdu_len = MSTP_Create_Frame(
+ (uint8_t *) & Transmit_Packet.pdu[0],
+ sizeof(Transmit_Packet.pdu),
+ Transmit_Packet.frame_type,
+ destination,
+ MSTP_Port.This_Station,
+ pdu, pdu_len);
+ Transmit_Packet.ready = true;
MSTP_Packets++;
}
@@ -118,22 +120,22 @@ uint16_t dlmstp_receive(
/* see if there is a packet available, and a place
to put the reply (if necessary) and process it */
- if (Receive_Buffer.ready) {
- if (Receive_Buffer.pdu_len) {
+ if (Receive_Packet.ready) {
+ if (Receive_Packet.pdu_len) {
MSTP_Packets++;
if (src) {
memmove(src,
- &Receive_Buffer.address,
- sizeof(Receive_Buffer.address));
+ &Receive_Packet.address,
+ sizeof(Receive_Packet.address));
}
if (pdu) {
memmove(pdu,
- &Receive_Buffer.pdu,
- sizeof(Receive_Buffer.pdu));
+ &Receive_Packet.pdu,
+ sizeof(Receive_Packet.pdu));
}
- pdu_len = Receive_Buffer.pdu_len;
+ pdu_len = Receive_Packet.pdu_len;
}
- Receive_Buffer.ready = false;
+ Receive_Packet.ready = false;
}
return pdu_len;
@@ -210,10 +212,10 @@ uint16_t dlmstp_put_receive(uint8_t src, /* source MS/TP address */
uint8_t * pdu, /* PDU data */
uint16_t pdu_len)
{ /* amount of PDU data */
- /* PDU is already in the Receive_Buffer */
- dlmstp_fill_bacnet_address(&Receive_Buffer.address, src);
- Receive_Buffer.pdu_len = pdu_len;
- Receive_Buffer.ready = true;
+ /* PDU is already in the Receive_Packet */
+ dlmstp_fill_bacnet_address(&Receive_Packet.address, src);
+ Receive_Packet.pdu_len = pdu_len;
+ Receive_Packet.ready = true;
return pdu_len;
}
@@ -229,11 +231,15 @@ uint16_t dlmstp_get_send(
uint16_t pdu_len = 0;
(void)src;
- (void)max_pdu;
- if (MSTP_Port.TxReady) {
- memmove(&pdu[0],(void *)&MSTP_Port.TxBuffer[0],sizeof(MSTP_Port.TxBuffer));
- pdu_len = MSTP_Port.TxLength;
- MSTP_Port.TxReady = false;
+ (void)timeout;
+ if (Transmit_Packet.ready) {
+ if (Transmit_Packet.pdu_len <= max_pdu) {
+ memmove(&pdu[0],
+ (void *) & Transmit_Packet.pdu[0],
+ Transmit_Packet.pdu_len);
+ pdu_len = Transmit_Packet.pdu_len;
+ }
+ Transmit_Packet.ready = false;
}
return pdu_len;
@@ -361,9 +367,9 @@ bool dlmstp_init(char *ifname)
unsigned long hThread = 0;
uint32_t arg_value = 0;
- /* initialize buffer */
- Receive_Buffer.ready = false;
- Receive_Buffer.pdu_len = 0;
+ /* initialize packet queue */
+ Receive_Packet.ready = false;
+ Receive_Packet.pdu_len = 0;
/* initialize hardware */
/* initialize hardware */
if (ifname) {
@@ -373,6 +379,10 @@ bool dlmstp_init(char *ifname)
#endif
}
RS485_Initialize();
+ MSTP_Port.InputBuffer = &RxBuffer[0];
+ MSTP_Port.InputBufferSize = sizeof(RxBuffer);
+ MSTP_Port.OutputBuffer = &TxBuffer[0];
+ MSTP_Port.OutputBufferSize = sizeof(TxBuffer);
MSTP_Init(&MSTP_Port);
#if 0
uint8_t data;
diff --git a/bacnet-stack/ports/win32/dlmstp.cbp b/bacnet-stack/ports/win32/dlmstp.cbp
index 1383ac20..5ac59a48 100644
--- a/bacnet-stack/ports/win32/dlmstp.cbp
+++ b/bacnet-stack/ports/win32/dlmstp.cbp
@@ -49,6 +49,14 @@
+
+
+
+
+
+
+
+
@@ -63,6 +71,7 @@
+
diff --git a/bacnet-stack/ports/win32/mstp.c b/bacnet-stack/ports/win32/mstp.c
index f5da3012..4b26f580 100644
--- a/bacnet-stack/ports/win32/mstp.c
+++ b/bacnet-stack/ports/win32/mstp.c
@@ -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
#include
+#if PRINT_ENABLED
#include
+#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;
-
}
}
diff --git a/bacnet-stack/ports/win32/mstp.h b/bacnet-stack/ports/win32/mstp.h
index 76b402c5..235ba88e 100644
--- a/bacnet-stack/ports/win32/mstp.h
+++ b/bacnet-stack/ports/win32/mstp.h
@@ -42,55 +42,6 @@
#include "bacdef.h"
#include "dlmstp.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
-/* The initial CRC16 checksum value */
-#define CRC16_INITIAL_VALUE (0xFFFF)
-
-/* receive FSM states */
-typedef enum {
- MSTP_RECEIVE_STATE_IDLE = 0,
- MSTP_RECEIVE_STATE_PREAMBLE = 1,
- MSTP_RECEIVE_STATE_HEADER = 2,
- MSTP_RECEIVE_STATE_HEADER_CRC = 3,
- MSTP_RECEIVE_STATE_DATA = 4
-} 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;
-
struct mstp_port_struct_t {
MSTP_RECEIVE_STATE receive_state;
/* When a master node is powered up or reset, */
@@ -141,7 +92,12 @@ struct mstp_port_struct_t {
/* An array of octets, used to store octets as they are received. */
/* InputBuffer is indexed from 0 to InputBufferSize-1. */
/* The maximum size of a frame is 501 octets. */
- uint8_t InputBuffer[MAX_MPDU];
+ /* FIXME: assign this to an actual array of bytes! */
+ /* Note: the buffer is designed as a pointer since some compilers
+ and microcontroller architectures have limits as to places to
+ hold contiguous memory. */
+ uint8_t *InputBuffer;
+ uint16_t InputBufferSize;
/* "Next Station," the MAC address of the node to which This Station passes */
/* the token. If the Next_Station is unknown, Next_Station shall be equal to */
/* This_Station. */
@@ -202,13 +158,16 @@ struct mstp_port_struct_t {
/* less than or equal to 127. If Max_Master is not writable in a node, */
/* its value shall be 127. */
unsigned Nmax_master;
-
- /* An array of octets, used to store PDU octets prior to being transmitted. */
- /* This array is only used for APDU messages */
- uint8_t TxBuffer[MAX_MPDU];
- unsigned TxLength;
- bool TxReady; /* true if ready to be sent or received */
- uint8_t TxFrameType; /* type of message - needed by MS/TP */
+
+ /* An array of octets, used to store octets for transmitting */
+ /* OutputBuffer is indexed from 0 to OutputBufferSize-1. */
+ /* The maximum size of a frame is 501 octets. */
+ /* FIXME: assign this to an actual array of bytes! */
+ /* Note: the buffer is designed as a pointer since some compilers
+ and microcontroller architectures have limits as to places to
+ hold contiguous memory. */
+ uint8_t *OutputBuffer;
+ uint16_t OutputBufferSize;
};
#define DEFAULT_MAX_INFO_FRAMES 1
@@ -239,14 +198,14 @@ extern "C" {
/* returns true if line is active */
bool MSTP_Line_Active(volatile struct mstp_port_struct_t *mstp_port);
- unsigned MSTP_Create_Frame(
+ uint16_t MSTP_Create_Frame(
uint8_t * buffer, /* where frame is loaded */
- unsigned buffer_len, /* amount of space available */
+ 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); /* number of bytes of data (up to 501) */
+ uint16_t data_len); /* number of bytes of data (up to 501) */
void MSTP_Create_And_Send_Frame(
volatile struct mstp_port_struct_t *mstp_port, /* port to send from */
@@ -254,7 +213,7 @@ extern "C" {
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);
#ifdef __cplusplus
}