Added test in MS/TP datalink for MAC Address in the Master Node range (0-127).
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user