This commit is contained in:
skarg
2006-08-29 10:48:04 +00:00
parent 0f851d57f0
commit 3d0abf778a
25 changed files with 487 additions and 525 deletions
+4 -3
View File
@@ -976,9 +976,9 @@ int encode_context_object_id(uint8_t * apdu,
len = encode_bacnet_object_id(&apdu[1], object_type, instance); len = encode_bacnet_object_id(&apdu[1], object_type, instance);
/* we only reserved 1 byte for encoding the tag - check the limits */ /* we only reserved 1 byte for encoding the tag - check the limits */
if ((tag_number <= 14) && (len <= 4)) if ((tag_number <= 14) && (len <= 4))
len += encode_tag(&apdu[0], (uint8_t) tag_number, true, len); len += encode_tag(&apdu[0], (uint8_t) tag_number, true, len);
else else
len = 0; len = 0;
return len; return len;
} }
@@ -1436,7 +1436,8 @@ int encode_tagged_date(uint8_t * apdu, BACNET_DATE * bdate)
} }
int encode_context_date(uint8_t * apdu, int tag_number, BACNET_DATE * bdate) int encode_context_date(uint8_t * apdu, int tag_number,
BACNET_DATE * bdate)
{ {
int len = 0; /* return value */ int len = 0; /* return value */
+2 -2
View File
@@ -49,8 +49,8 @@
#elif defined(BACDL_BIP) #elif defined(BACDL_BIP)
#include "bip.h" #include "bip.h"
#else #else
#define MAX_HEADER (1 + 1 + 2) #define MAX_HEADER (1 + 1 + 2)
#define MAX_MPDU (MAX_HEADER+MAX_PDU) #define MAX_MPDU (MAX_HEADER+MAX_PDU)
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
+6 -8
View File
@@ -259,18 +259,16 @@ int main(int argc, char *argv[])
Communication_Password); Communication_Password);
} else if (tsm_invoke_id_free(invoke_id)) } else if (tsm_invoke_id_free(invoke_id))
break; break;
else if (tsm_invoke_id_failed(invoke_id)) else if (tsm_invoke_id_failed(invoke_id)) {
{ fprintf(stderr, "\rError: TSM Timeout!\r\n");
fprintf(stderr, "\rError: TSM Timeout!\r\n"); tsm_free_invoke_id(invoke_id);
tsm_free_invoke_id(invoke_id); /* try again or abort? */
/* try again or abort? */ break;
break;
} }
} else { } else {
/* increment timer - exit if timed out */ /* increment timer - exit if timed out */
elapsed_seconds += (current_seconds - last_seconds); elapsed_seconds += (current_seconds - last_seconds);
if (elapsed_seconds > timeout_seconds) if (elapsed_seconds > timeout_seconds) {
{
printf("\rError: APDU Timeout!\r\n"); printf("\rError: APDU Timeout!\r\n");
break; break;
} }
+6 -9
View File
@@ -285,19 +285,16 @@ int main(int argc, char *argv[])
Target_File_Object_Instance, fileStartPosition, Target_File_Object_Instance, fileStartPosition,
requestedOctetCount); requestedOctetCount);
Current_Invoke_ID = invoke_id; Current_Invoke_ID = invoke_id;
} } else if (tsm_invoke_id_failed(invoke_id)) {
else if (tsm_invoke_id_failed(invoke_id)) fprintf(stderr, "\rError: TSM Timeout!\r\n");
{ tsm_free_invoke_id(invoke_id);
fprintf(stderr, "\rError: TSM Timeout!\r\n"); /* try again or abort? */
tsm_free_invoke_id(invoke_id); break;
/* try again or abort? */
break;
} }
} else { } else {
/* increment timer - exit if timed out */ /* increment timer - exit if timed out */
elapsed_seconds += (current_seconds - last_seconds); elapsed_seconds += (current_seconds - last_seconds);
if (elapsed_seconds > timeout_seconds) if (elapsed_seconds > timeout_seconds) {
{
fprintf(stderr, "\rError: APDU Timeout!\r\n"); fprintf(stderr, "\rError: APDU Timeout!\r\n");
break; break;
} }
+3 -5
View File
@@ -187,7 +187,7 @@ int main(int argc, char *argv[])
if (!arcnet_init("arc0")) if (!arcnet_init("arc0"))
return 1; return 1;
#else #else
#error Datalink (BACDL_ETHERNET,BACDL_BIP, or BACDL_ARCNET) undefined #error Datalink (BACDL_ETHERNET,BACDL_BIP, or BACDL_ARCNET) undefined
#endif #endif
/* configure the timeout values */ /* configure the timeout values */
last_seconds = time(NULL); last_seconds = time(NULL);
@@ -226,8 +226,7 @@ int main(int argc, char *argv[])
Target_Object_Index); Target_Object_Index);
} else if (tsm_invoke_id_free(invoke_id)) } else if (tsm_invoke_id_free(invoke_id))
break; break;
else if (tsm_invoke_id_failed(invoke_id)) else if (tsm_invoke_id_failed(invoke_id)) {
{
fprintf(stderr, "\rError: TSM Timeout!\r\n"); fprintf(stderr, "\rError: TSM Timeout!\r\n");
tsm_free_invoke_id(invoke_id); tsm_free_invoke_id(invoke_id);
/* try again or abort? */ /* try again or abort? */
@@ -236,8 +235,7 @@ int main(int argc, char *argv[])
} else { } else {
/* increment timer - exit if timed out */ /* increment timer - exit if timed out */
elapsed_seconds += (current_seconds - last_seconds); elapsed_seconds += (current_seconds - last_seconds);
if (elapsed_seconds > timeout_seconds) if (elapsed_seconds > timeout_seconds) {
{
printf("\rError: APDU Timeout!\r\n"); printf("\rError: APDU Timeout!\r\n");
break; break;
} }
+6 -8
View File
@@ -245,18 +245,16 @@ int main(int argc, char *argv[])
Reinitialize_Password); Reinitialize_Password);
} else if (tsm_invoke_id_free(invoke_id)) } else if (tsm_invoke_id_free(invoke_id))
break; break;
else if (tsm_invoke_id_failed(invoke_id)) else if (tsm_invoke_id_failed(invoke_id)) {
{ fprintf(stderr, "\rError: TSM Timeout!\r\n");
fprintf(stderr, "\rError: TSM Timeout!\r\n"); tsm_free_invoke_id(invoke_id);
tsm_free_invoke_id(invoke_id); /* try again or abort? */
/* try again or abort? */ break;
break;
} }
} else { } else {
/* increment timer - exit if timed out */ /* increment timer - exit if timed out */
elapsed_seconds += (current_seconds - last_seconds); elapsed_seconds += (current_seconds - last_seconds);
if (elapsed_seconds > timeout_seconds) if (elapsed_seconds > timeout_seconds) {
{
fprintf(stderr, "\rError: APDU Timeout!\r\n"); fprintf(stderr, "\rError: APDU Timeout!\r\n");
break; break;
} }
+2 -2
View File
@@ -112,10 +112,10 @@ int main(int argc, char *argv[])
/* allow the device ID to be set */ /* allow the device ID to be set */
if (argc > 1) if (argc > 1)
Device_Set_Object_Instance_Number(strtol(argv[1], NULL, 0)); Device_Set_Object_Instance_Number(strtol(argv[1], NULL, 0));
#if defined(BACDL_BIP) #if defined(BACDL_BIP)
if (argc > 2) if (argc > 2)
bip_set_port(strtol(argv[2], NULL, 0)); bip_set_port(strtol(argv[2], NULL, 0));
#endif #endif
printf("BACnet Server Demo - Device #%u\r\n", printf("BACnet Server Demo - Device #%u\r\n",
Device_Object_Instance_Number()); Device_Object_Instance_Number());
Init_Service_Handlers(); Init_Service_Handlers();
+6 -9
View File
@@ -263,19 +263,16 @@ int main(int argc, char *argv[])
Target_File_Object_Instance, fileStartPosition, Target_File_Object_Instance, fileStartPosition,
&fileData); &fileData);
Current_Invoke_ID = invoke_id; Current_Invoke_ID = invoke_id;
} } else if (tsm_invoke_id_failed(invoke_id)) {
else if (tsm_invoke_id_failed(invoke_id)) fprintf(stderr, "\rError: TSM Timeout!\r\n");
{ tsm_free_invoke_id(invoke_id);
fprintf(stderr, "\rError: TSM Timeout!\r\n"); /* try again or abort? */
tsm_free_invoke_id(invoke_id); break;
/* try again or abort? */
break;
} }
} else { } else {
/* increment timer - exit if timed out */ /* increment timer - exit if timed out */
elapsed_seconds += (current_seconds - last_seconds); elapsed_seconds += (current_seconds - last_seconds);
if (elapsed_seconds > timeout_seconds) if (elapsed_seconds > timeout_seconds) {
{
fprintf(stderr, "\rError: APDU Timeout!\r\n"); fprintf(stderr, "\rError: APDU Timeout!\r\n");
break; break;
} }
+2 -4
View File
@@ -323,8 +323,7 @@ int main(int argc, char *argv[])
Target_Object_Property_Index); Target_Object_Property_Index);
} else if (tsm_invoke_id_free(invoke_id)) } else if (tsm_invoke_id_free(invoke_id))
break; break;
else if (tsm_invoke_id_failed(invoke_id)) else if (tsm_invoke_id_failed(invoke_id)) {
{
fprintf(stderr, "\rError: TSM Timeout!\r\n"); fprintf(stderr, "\rError: TSM Timeout!\r\n");
tsm_free_invoke_id(invoke_id); tsm_free_invoke_id(invoke_id);
/* try again or abort? */ /* try again or abort? */
@@ -333,8 +332,7 @@ int main(int argc, char *argv[])
} else { } else {
/* increment timer - exit if timed out */ /* increment timer - exit if timed out */
elapsed_seconds += (current_seconds - last_seconds); elapsed_seconds += (current_seconds - last_seconds);
if (elapsed_seconds > timeout_seconds) if (elapsed_seconds > timeout_seconds) {
{
printf("\rError: APDU Timeout!\r\n"); printf("\rError: APDU Timeout!\r\n");
break; break;
} }
+4 -5
View File
@@ -94,13 +94,12 @@ extern "C" {
void dlmstp_set_my_address(uint8_t my_address); void dlmstp_set_my_address(uint8_t my_address);
void dlmstp_get_my_address(BACNET_ADDRESS * my_address); void dlmstp_get_my_address(BACNET_ADDRESS * my_address);
void dlmstp_get_broadcast_address(BACNET_ADDRESS * dest); /* destination address */ void dlmstp_get_broadcast_address(BACNET_ADDRESS * dest); /* destination address */
/* MS/TP state machine functions */ /* MS/TP state machine functions */
uint16_t dlmstp_put_receive( uint16_t dlmstp_put_receive(uint8_t src, /* source MS/TP address */
uint8_t src, /* source MS/TP address */ uint8_t * pdu, /* PDU data */
uint8_t * pdu, /* PDU data */
uint16_t pdu_len); uint16_t pdu_len);
#ifdef __cplusplus #ifdef __cplusplus
} }
+253 -265
View File
@@ -206,10 +206,10 @@ void MSTP_Create_And_Send_Frame(volatile struct mstp_port_struct_t *mstp_port,
uint8_t * data, /* any data to be sent - may be null */ uint8_t * data, /* any data to be sent - may be null */
unsigned data_len) unsigned data_len)
{ /* number of bytes of data (up to 501) */ { /* number of bytes of data (up to 501) */
uint8_t buffer[MAX_MPDU] = {0}; /* buffer for sending */ uint8_t buffer[MAX_MPDU] = { 0 }; /* buffer for sending */
uint16_t len = 0; /* number of bytes to send */ uint16_t len = 0; /* number of bytes to send */
len = (uint16_t) MSTP_Create_Frame(&buffer[0], /* where frame is loaded */ len = (uint16_t) MSTP_Create_Frame(&buffer[0], /* where frame is loaded */
sizeof(buffer), /* amount of space available */ sizeof(buffer), /* amount of space available */
frame_type, /* type of frame to send - see defines */ frame_type, /* type of frame to send - see defines */
destination, /* destination address */ destination, /* destination address */
@@ -231,59 +231,55 @@ void MSTP_Millisecond_Timer(volatile struct mstp_port_struct_t *mstp_port)
#if PRINT_ENABLED_RECEIVE #if PRINT_ENABLED_RECEIVE
char *mstp_receive_state_text(int state) char *mstp_receive_state_text(int state)
{ {
char *text = "unknown"; char *text = "unknown";
switch (state) switch (state) {
{
case MSTP_RECEIVE_STATE_IDLE: case MSTP_RECEIVE_STATE_IDLE:
text = "IDLE"; text = "IDLE";
break; break;
case MSTP_RECEIVE_STATE_PREAMBLE: case MSTP_RECEIVE_STATE_PREAMBLE:
text = "PREAMBLE"; text = "PREAMBLE";
break; break;
case MSTP_RECEIVE_STATE_HEADER: case MSTP_RECEIVE_STATE_HEADER:
text = "HEADER"; text = "HEADER";
break; break;
case MSTP_RECEIVE_STATE_HEADER_CRC: case MSTP_RECEIVE_STATE_HEADER_CRC:
text = "HEADER_CRC"; text = "HEADER_CRC";
break; break;
case MSTP_RECEIVE_STATE_DATA: case MSTP_RECEIVE_STATE_DATA:
text = "DATA"; text = "DATA";
break; break;
default: default:
break; break;
} }
return text; return text;
} }
#endif #endif
void MSTP_Receive_Frame_FSM(volatile struct mstp_port_struct_t *mstp_port) void MSTP_Receive_Frame_FSM(volatile struct mstp_port_struct_t *mstp_port)
{ {
#if PRINT_ENABLED_MASTER #if PRINT_ENABLED_MASTER
static MSTP_RECEIVE_STATE receive_state = MSTP_RECEIVE_STATE_IDLE; static MSTP_RECEIVE_STATE receive_state = MSTP_RECEIVE_STATE_IDLE;
#endif #endif
#if PRINT_ENABLED_RECEIVE #if PRINT_ENABLED_RECEIVE
fprintf(stderr,"MSTP Rx: State=%s Data=%02X hCRC=%02X Index=%u EC=%u DateLen=%u Silence=%u\r\n", fprintf(stderr,
"MSTP Rx: State=%s Data=%02X hCRC=%02X Index=%u EC=%u DateLen=%u Silence=%u\r\n",
mstp_receive_state_text(mstp_port->receive_state), mstp_receive_state_text(mstp_port->receive_state),
mstp_port->DataRegister, mstp_port->DataRegister, mstp_port->HeaderCRC, mstp_port->Index,
mstp_port->HeaderCRC, mstp_port->EventCount, mstp_port->DataLength,
mstp_port->Index,
mstp_port->EventCount,
mstp_port->DataLength,
mstp_port->SilenceTimer); mstp_port->SilenceTimer);
#endif #endif
#if PRINT_ENABLED_RECEIVE_DATA #if PRINT_ENABLED_RECEIVE_DATA
if (mstp_port->DataAvailable == true) if (mstp_port->DataAvailable == true) {
{ if ((mstp_port->receive_state == MSTP_RECEIVE_STATE_IDLE) &&
if ((mstp_port->receive_state == MSTP_RECEIVE_STATE_IDLE) && (receive_state != MSTP_RECEIVE_STATE_IDLE))
(receive_state != MSTP_RECEIVE_STATE_IDLE)) fprintf(stderr, "MSTP Rx: ");
fprintf(stderr,"MSTP Rx: "); fprintf(stderr, "%02X ", mstp_port->DataRegister);
fprintf(stderr,"%02X ", mstp_port->DataRegister);
} }
receive_state = mstp_port->receive_state; receive_state = mstp_port->receive_state;
#endif #endif
switch (mstp_port->receive_state) { switch (mstp_port->receive_state) {
/* In the IDLE state, the node waits for the beginning of a frame. */ /* In the IDLE state, the node waits for the beginning of a frame. */
@@ -562,13 +558,12 @@ void MSTP_Receive_Frame_FSM(volatile struct mstp_port_struct_t *mstp_port)
mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE;
break; break;
} }
#if PRINT_ENABLED_RECEIVE_DATA #if PRINT_ENABLED_RECEIVE_DATA
if ((receive_state != MSTP_RECEIVE_STATE_IDLE) && if ((receive_state != MSTP_RECEIVE_STATE_IDLE) &&
(mstp_port->receive_state == MSTP_RECEIVE_STATE_IDLE)) (mstp_port->receive_state == MSTP_RECEIVE_STATE_IDLE)) {
{ fprintf(stderr, "\r\n");
fprintf(stderr,"\r\n");
} }
#endif #endif
return; return;
} }
@@ -576,85 +571,83 @@ void MSTP_Receive_Frame_FSM(volatile struct mstp_port_struct_t *mstp_port)
#if PRINT_ENABLED #if PRINT_ENABLED
char *mstp_master_state_text(int state) char *mstp_master_state_text(int state)
{ {
char *text = "unknown"; char *text = "unknown";
switch (state) switch (state) {
{
case MSTP_MASTER_STATE_INITIALIZE: case MSTP_MASTER_STATE_INITIALIZE:
text = "INITIALIZE"; text = "INITIALIZE";
break; break;
case MSTP_MASTER_STATE_IDLE: case MSTP_MASTER_STATE_IDLE:
text = "IDLE"; text = "IDLE";
break; break;
case MSTP_MASTER_STATE_USE_TOKEN: case MSTP_MASTER_STATE_USE_TOKEN:
text = "USE_TOKEN"; text = "USE_TOKEN";
break; break;
case MSTP_MASTER_STATE_WAIT_FOR_REPLY: case MSTP_MASTER_STATE_WAIT_FOR_REPLY:
text = "WAIT_FOR_REPLY"; text = "WAIT_FOR_REPLY";
break; break;
case MSTP_MASTER_STATE_DONE_WITH_TOKEN: case MSTP_MASTER_STATE_DONE_WITH_TOKEN:
text = "IDLE"; text = "IDLE";
break; break;
case MSTP_MASTER_STATE_PASS_TOKEN: case MSTP_MASTER_STATE_PASS_TOKEN:
text = "DONE_WITH_TOKEN"; text = "DONE_WITH_TOKEN";
break; break;
case MSTP_MASTER_STATE_NO_TOKEN: case MSTP_MASTER_STATE_NO_TOKEN:
text = "NO_TOKEN"; text = "NO_TOKEN";
break; break;
case MSTP_MASTER_STATE_POLL_FOR_MASTER: case MSTP_MASTER_STATE_POLL_FOR_MASTER:
text = "POLL_FOR_MASTER"; text = "POLL_FOR_MASTER";
break; break;
case MSTP_MASTER_STATE_ANSWER_DATA_REQUEST: case MSTP_MASTER_STATE_ANSWER_DATA_REQUEST:
text = "ANSWER_DATA_REQUEST"; text = "ANSWER_DATA_REQUEST";
break; break;
default: default:
break; break;
} }
return text; return text;
} }
#endif #endif
#if PRINT_ENABLED #if PRINT_ENABLED
char *mstp_frame_type_text(int type) char *mstp_frame_type_text(int type)
{ {
char *text = "unknown"; char *text = "unknown";
switch (type) switch (type) {
{
case FRAME_TYPE_TOKEN: case FRAME_TYPE_TOKEN:
text = "TOKEN"; text = "TOKEN";
break; break;
case FRAME_TYPE_POLL_FOR_MASTER: case FRAME_TYPE_POLL_FOR_MASTER:
text = "POLL_FOR_MASTER"; text = "POLL_FOR_MASTER";
break; break;
case FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER: case FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER:
text = "REPLY_TO_POLL_FOR_MASTER"; text = "REPLY_TO_POLL_FOR_MASTER";
break; break;
case FRAME_TYPE_TEST_REQUEST: case FRAME_TYPE_TEST_REQUEST:
text = "TEST_REQUEST"; text = "TEST_REQUEST";
break; break;
case FRAME_TYPE_TEST_RESPONSE: case FRAME_TYPE_TEST_RESPONSE:
text = "TEST_RESPONSE"; text = "TEST_RESPONSE";
break; break;
case FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY: case FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY:
text = "BACNET_DATA_EXPECTING_REPLY"; text = "BACNET_DATA_EXPECTING_REPLY";
break; break;
case FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY: case FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY:
text = "BACNET_DATA_NOT_EXPECTING_REPLY"; text = "BACNET_DATA_NOT_EXPECTING_REPLY";
break; break;
case FRAME_TYPE_REPLY_POSTPONED: case FRAME_TYPE_REPLY_POSTPONED:
text = "REPLY_POSTPONED"; text = "REPLY_POSTPONED";
break; break;
default: default:
if ((type >= FRAME_TYPE_PROPRIETARY_MIN) && if ((type >= FRAME_TYPE_PROPRIETARY_MIN) &&
(type <= FRAME_TYPE_PROPRIETARY_MAX)) (type <= FRAME_TYPE_PROPRIETARY_MAX))
text = "PROPRIETARY"; text = "PROPRIETARY";
break; break;
} }
return text; return text;
} }
#endif #endif
void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port) void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port)
@@ -665,21 +658,20 @@ void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port)
uint8_t next_this_station = 0; uint8_t next_this_station = 0;
uint8_t next_next_station = 0; uint8_t next_next_station = 0;
uint16_t my_timeout = 10, ns_timeout = 0; uint16_t my_timeout = 10, ns_timeout = 0;
#if PRINT_ENABLED_MASTER #if PRINT_ENABLED_MASTER
static MSTP_MASTER_STATE master_state = MSTP_MASTER_STATE_INITIALIZE; static MSTP_MASTER_STATE master_state = MSTP_MASTER_STATE_INITIALIZE;
#endif #endif
/* some calculations that several states need */ /* some calculations that several states need */
next_poll_station = (mstp_port->Poll_Station + 1) % next_poll_station = (mstp_port->Poll_Station + 1) %
(mstp_port->Nmax_master + 1); (mstp_port->Nmax_master + 1);
next_this_station = (mstp_port->This_Station + 1) % next_this_station = (mstp_port->This_Station + 1) %
(mstp_port->Nmax_master + 1); (mstp_port->Nmax_master + 1);
next_next_station = (mstp_port->Next_Station + 1) % next_next_station = (mstp_port->Next_Station + 1) %
(mstp_port->Nmax_master + 1); (mstp_port->Nmax_master + 1);
#if PRINT_ENABLED_MASTER #if PRINT_ENABLED_MASTER
if (mstp_port->master_state != master_state) if (mstp_port->master_state != master_state) {
{
master_state = mstp_port->master_state; master_state = mstp_port->master_state;
fprintf(stderr, fprintf(stderr,
"MSTP: TS=%02X[%02X] NS=%02X[%02X] PS=%02X[%02X] EC=%u TC=%u ST=%u %s\r\n", "MSTP: TS=%02X[%02X] NS=%02X[%02X] PS=%02X[%02X] EC=%u TC=%u ST=%u %s\r\n",
@@ -694,8 +686,8 @@ void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port)
mstp_port->SilenceTimer, mstp_port->SilenceTimer,
mstp_master_state_text(mstp_port->master_state)); mstp_master_state_text(mstp_port->master_state));
} }
#endif #endif
switch (mstp_port->master_state) { switch (mstp_port->master_state) {
case MSTP_MASTER_STATE_INITIALIZE: case MSTP_MASTER_STATE_INITIALIZE:
/* DoneInitializing */ /* DoneInitializing */
@@ -715,7 +707,7 @@ void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port)
/* LostToken */ /* LostToken */
if (mstp_port->SilenceTimer >= Tno_token) { if (mstp_port->SilenceTimer >= Tno_token) {
/* assume that the token has been lost */ /* assume that the token has been lost */
mstp_port->EventCount = 0; /* Addendum 135-2004d-8 */ mstp_port->EventCount = 0; /* Addendum 135-2004d-8 */
mstp_port->master_state = MSTP_MASTER_STATE_NO_TOKEN; mstp_port->master_state = MSTP_MASTER_STATE_NO_TOKEN;
} }
/* ReceivedInvalidFrame */ /* ReceivedInvalidFrame */
@@ -723,9 +715,8 @@ void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port)
/* invalid frame was received */ /* invalid frame was received */
mstp_port->ReceivedInvalidFrame = false; mstp_port->ReceivedInvalidFrame = false;
/* wait for the next frame - remain in IDLE */ /* wait for the next frame - remain in IDLE */
} } else if (mstp_port->ReceivedValidFrame == true) {
else if (mstp_port->ReceivedValidFrame == true) { #if PRINT_ENABLED_MASTER
#if PRINT_ENABLED_MASTER
fprintf(stderr, fprintf(stderr,
"MSTP: ReceivedValidFrame Src=%02X Dest=%02X DataLen=%u FC=%u ST=%u Type=%s\r\n", "MSTP: ReceivedValidFrame Src=%02X Dest=%02X DataLen=%u FC=%u ST=%u Type=%s\r\n",
mstp_port->SourceAddress, mstp_port->SourceAddress,
@@ -734,63 +725,60 @@ void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port)
mstp_port->FrameCount, mstp_port->FrameCount,
mstp_port->SilenceTimer, mstp_port->SilenceTimer,
mstp_frame_type_text(mstp_port->FrameType)); mstp_frame_type_text(mstp_port->FrameType));
#endif #endif
/* destined for me! */ /* destined for me! */
if ((mstp_port->DestinationAddress == if ((mstp_port->DestinationAddress ==
mstp_port->This_Station) || mstp_port->This_Station) ||
(mstp_port->DestinationAddress == (mstp_port->DestinationAddress ==
MSTP_BROADCAST_ADDRESS)) { MSTP_BROADCAST_ADDRESS)) {
switch (mstp_port->FrameType) switch (mstp_port->FrameType) {
{
/* ReceivedToken */ /* ReceivedToken */
case FRAME_TYPE_TOKEN: case FRAME_TYPE_TOKEN:
/* tokens can't be broadcast */ /* tokens can't be broadcast */
if (mstp_port->DestinationAddress == if (mstp_port->DestinationAddress ==
MSTP_BROADCAST_ADDRESS) MSTP_BROADCAST_ADDRESS)
break;
mstp_port->ReceivedValidFrame = false;
mstp_port->FrameCount = 0;
mstp_port->SoleMaster = false;
mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN;
break; break;
mstp_port->ReceivedValidFrame = false;
mstp_port->FrameCount = 0;
mstp_port->SoleMaster = false;
mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN;
break;
/* ReceivedPFM */ /* ReceivedPFM */
case FRAME_TYPE_POLL_FOR_MASTER: case FRAME_TYPE_POLL_FOR_MASTER:
MSTP_Create_And_Send_Frame(mstp_port, MSTP_Create_And_Send_Frame(mstp_port,
FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER, FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER,
mstp_port->SourceAddress, mstp_port->This_Station, mstp_port->SourceAddress, mstp_port->This_Station,
NULL, 0); NULL, 0);
break; break;
case FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY: case FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY:
/* indicate successful reception to the higher layers */ /* indicate successful reception to the higher layers */
dlmstp_put_receive( dlmstp_put_receive(mstp_port->SourceAddress,
mstp_port->SourceAddress, (uint8_t *) & mstp_port->InputBuffer[0],
(uint8_t *) & mstp_port->InputBuffer[0], mstp_port->DataLength);
mstp_port->DataLength); break;
break; case FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY:
case FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY: mstp_port->ReplyPostponedTimer = 0;
mstp_port->ReplyPostponedTimer = 0; /* indicate successful reception to the higher layers */
/* indicate successful reception to the higher layers */ dlmstp_put_receive(mstp_port->SourceAddress, /* source MS/TP address */
dlmstp_put_receive( (uint8_t *) & mstp_port->InputBuffer[0],
mstp_port->SourceAddress, /* source MS/TP address */ mstp_port->DataLength);
(uint8_t *) & mstp_port->InputBuffer[0], /* broadcast DER just remains IDLE */
mstp_port->DataLength); if (mstp_port->DestinationAddress !=
/* broadcast DER just remains IDLE */ MSTP_BROADCAST_ADDRESS)
if (mstp_port->DestinationAddress != mstp_port->master_state =
MSTP_BROADCAST_ADDRESS) MSTP_MASTER_STATE_ANSWER_DATA_REQUEST;
mstp_port->master_state = break;
MSTP_MASTER_STATE_ANSWER_DATA_REQUEST; case FRAME_TYPE_TEST_REQUEST:
break; MSTP_Create_And_Send_Frame(mstp_port,
case FRAME_TYPE_TEST_REQUEST: FRAME_TYPE_TEST_RESPONSE,
MSTP_Create_And_Send_Frame(mstp_port, mstp_port->SourceAddress, mstp_port->This_Station,
FRAME_TYPE_TEST_RESPONSE, NULL, 0);
mstp_port->SourceAddress, mstp_port->This_Station, break;
NULL, 0); case FRAME_TYPE_TEST_RESPONSE:
break; default:
case FRAME_TYPE_TEST_RESPONSE: break;
default:
break;
} }
} }
mstp_port->ReceivedValidFrame = false; mstp_port->ReceivedValidFrame = false;
} }
break; break;
@@ -799,43 +787,40 @@ void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port)
/* proprietary frames. */ /* proprietary frames. */
case MSTP_MASTER_STATE_USE_TOKEN: case MSTP_MASTER_STATE_USE_TOKEN:
/* NothingToSend */ /* NothingToSend */
if (!mstp_port->TxReady) if (!mstp_port->TxReady) {
{
mstp_port->FrameCount = mstp_port->Nmax_info_frames; mstp_port->FrameCount = mstp_port->Nmax_info_frames;
mstp_port->master_state = MSTP_MASTER_STATE_DONE_WITH_TOKEN; mstp_port->master_state = MSTP_MASTER_STATE_DONE_WITH_TOKEN;
} } else {
else
{
uint8_t destination = mstp_port->TxBuffer[3]; uint8_t destination = mstp_port->TxBuffer[3];
RS485_Send_Frame( RS485_Send_Frame(mstp_port,
mstp_port, (uint8_t *) & mstp_port->TxBuffer[0], mstp_port->TxLength);
(uint8_t *) &mstp_port->TxBuffer[0],
mstp_port->TxLength);
mstp_port->FrameCount++; mstp_port->FrameCount++;
switch (mstp_port->TxFrameType) switch (mstp_port->TxFrameType) {
{
/* SendAndWait */ /* SendAndWait */
case FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY: case FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY:
if (destination == MSTP_BROADCAST_ADDRESS) if (destination == MSTP_BROADCAST_ADDRESS)
mstp_port->master_state = MSTP_MASTER_STATE_DONE_WITH_TOKEN; mstp_port->master_state =
else MSTP_MASTER_STATE_DONE_WITH_TOKEN;
mstp_port->master_state = MSTP_MASTER_STATE_WAIT_FOR_REPLY; else
break; mstp_port->master_state =
case FRAME_TYPE_TEST_REQUEST: MSTP_MASTER_STATE_WAIT_FOR_REPLY;
mstp_port->master_state = MSTP_MASTER_STATE_WAIT_FOR_REPLY; break;
break; case FRAME_TYPE_TEST_REQUEST:
mstp_port->master_state = MSTP_MASTER_STATE_WAIT_FOR_REPLY;
break;
/* SendNoWait */ /* SendNoWait */
case FRAME_TYPE_TEST_RESPONSE: case FRAME_TYPE_TEST_RESPONSE:
case FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY: case FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY:
default: default:
mstp_port->master_state = MSTP_MASTER_STATE_DONE_WITH_TOKEN; mstp_port->master_state =
break; MSTP_MASTER_STATE_DONE_WITH_TOKEN;
break;
} }
mstp_port->TxReady = false; mstp_port->TxReady = false;
} }
break; break;
/* In the WAIT_FOR_REPLY state, the node waits for */ /* In the WAIT_FOR_REPLY state, the node waits for */
/* a reply from another node. */ /* a reply from another node. */
case MSTP_MASTER_STATE_WAIT_FOR_REPLY: case MSTP_MASTER_STATE_WAIT_FOR_REPLY:
if (mstp_port->SilenceTimer >= Treply_timeout) { if (mstp_port->SilenceTimer >= Treply_timeout) {
/* ReplyTimeout */ /* ReplyTimeout */
@@ -851,33 +836,35 @@ void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port)
/* InvalidFrame */ /* InvalidFrame */
/* error in frame reception */ /* error in frame reception */
mstp_port->ReceivedInvalidFrame = false; mstp_port->ReceivedInvalidFrame = false;
mstp_port->master_state = MSTP_MASTER_STATE_DONE_WITH_TOKEN; mstp_port->master_state =
MSTP_MASTER_STATE_DONE_WITH_TOKEN;
} else if (mstp_port->ReceivedValidFrame == true) { } else if (mstp_port->ReceivedValidFrame == true) {
if (mstp_port->DestinationAddress == mstp_port->This_Station) { if (mstp_port->DestinationAddress ==
switch (mstp_port->TxFrameType) mstp_port->This_Station) {
{ switch (mstp_port->TxFrameType) {
case FRAME_TYPE_REPLY_POSTPONED: case FRAME_TYPE_REPLY_POSTPONED:
/* ReceivedReplyPostponed */ /* ReceivedReplyPostponed */
mstp_port->master_state = MSTP_MASTER_STATE_DONE_WITH_TOKEN; mstp_port->master_state =
break; MSTP_MASTER_STATE_DONE_WITH_TOKEN;
case FRAME_TYPE_TEST_RESPONSE: break;
mstp_port->master_state = MSTP_MASTER_STATE_IDLE; case FRAME_TYPE_TEST_RESPONSE:
break; mstp_port->master_state = MSTP_MASTER_STATE_IDLE;
case FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY: break;
/* ReceivedReply */ case FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY:
/* or a proprietary type that indicates a reply */ /* ReceivedReply */
/* indicate successful reception to the higher layers */ /* or a proprietary type that indicates a reply */
dlmstp_put_receive( /* indicate successful reception to the higher layers */
mstp_port->SourceAddress, /* source MS/TP address */ dlmstp_put_receive(mstp_port->SourceAddress, /* source MS/TP address */
(uint8_t *) & mstp_port->InputBuffer[0], (uint8_t *) & mstp_port->InputBuffer[0],
mstp_port->DataLength); mstp_port->DataLength);
mstp_port->master_state = MSTP_MASTER_STATE_DONE_WITH_TOKEN; mstp_port->master_state =
break; MSTP_MASTER_STATE_DONE_WITH_TOKEN;
default: break;
/* if proprietary frame was expected, you might default:
need to transition to DONE WITH TOKEN */ /* if proprietary frame was expected, you might
mstp_port->master_state = MSTP_MASTER_STATE_IDLE; need to transition to DONE WITH TOKEN */
break; mstp_port->master_state = MSTP_MASTER_STATE_IDLE;
break;
} }
} else { } else {
/* ReceivedUnexpectedFrame */ /* ReceivedUnexpectedFrame */
@@ -901,8 +888,7 @@ void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port)
mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN; mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN;
} }
/* Npoll changed in Errata SSPC-135-2004 */ /* Npoll changed in Errata SSPC-135-2004 */
else if (mstp_port->TokenCount < (Npoll-1)) else if (mstp_port->TokenCount < (Npoll - 1)) {
{
if ((mstp_port->SoleMaster == true) && if ((mstp_port->SoleMaster == true) &&
(mstp_port->Next_Station != next_this_station)) { (mstp_port->Next_Station != next_this_station)) {
/* SoleMaster */ /* SoleMaster */
@@ -911,8 +897,7 @@ void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port)
mstp_port->FrameCount = 0; mstp_port->FrameCount = 0;
mstp_port->TokenCount++; mstp_port->TokenCount++;
mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN; mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN;
} } else {
else {
/* SendToken */ /* SendToken */
/* Npoll changed in Errata SSPC-135-2004 */ /* Npoll changed in Errata SSPC-135-2004 */
/* The comparison of NS and TS+1 eliminates the Poll For Master */ /* The comparison of NS and TS+1 eliminates the Poll For Master */
@@ -922,14 +907,13 @@ void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port)
/* transmit a Token frame to NS */ /* transmit a Token frame to NS */
MSTP_Create_And_Send_Frame(mstp_port, MSTP_Create_And_Send_Frame(mstp_port,
FRAME_TYPE_TOKEN, FRAME_TYPE_TOKEN,
mstp_port->Next_Station, mstp_port->Next_Station,
mstp_port->This_Station, NULL, 0); mstp_port->This_Station, NULL, 0);
mstp_port->RetryCount = 0; mstp_port->RetryCount = 0;
mstp_port->EventCount = 0; mstp_port->EventCount = 0;
mstp_port->master_state = MSTP_MASTER_STATE_PASS_TOKEN; mstp_port->master_state = MSTP_MASTER_STATE_PASS_TOKEN;
} }
} } else if (next_poll_station == mstp_port->Next_Station) {
else if (next_poll_station == mstp_port->Next_Station) {
if (mstp_port->SoleMaster == true) { if (mstp_port->SoleMaster == true) {
/* SoleMasterRestartMaintenancePFM */ /* SoleMasterRestartMaintenancePFM */
mstp_port->Poll_Station = next_poll_station; mstp_port->Poll_Station = next_poll_station;
@@ -939,32 +923,30 @@ void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port)
/* no known successor node */ /* no known successor node */
mstp_port->Next_Station = mstp_port->This_Station; mstp_port->Next_Station = mstp_port->This_Station;
mstp_port->RetryCount = 0; mstp_port->RetryCount = 0;
mstp_port->TokenCount = 1; /* changed in Errata SSPC-135-2004 */ mstp_port->TokenCount = 1; /* changed in Errata SSPC-135-2004 */
/* mstp_port->EventCount = 0; removed in Addendum 135-2004d-8 */ /* mstp_port->EventCount = 0; removed in Addendum 135-2004d-8 */
/* find a new successor to TS */ /* find a new successor to TS */
mstp_port->master_state = MSTP_MASTER_STATE_POLL_FOR_MASTER; mstp_port->master_state =
} MSTP_MASTER_STATE_POLL_FOR_MASTER;
else { } else {
/* ResetMaintenancePFM */ /* ResetMaintenancePFM */
mstp_port->Poll_Station = mstp_port->This_Station; mstp_port->Poll_Station = mstp_port->This_Station;
/* transmit a Token frame to NS */ /* transmit a Token frame to NS */
MSTP_Create_And_Send_Frame(mstp_port, MSTP_Create_And_Send_Frame(mstp_port,
FRAME_TYPE_TOKEN, FRAME_TYPE_TOKEN,
mstp_port->Next_Station, mstp_port->Next_Station,
mstp_port->This_Station, NULL, 0); mstp_port->This_Station, NULL, 0);
mstp_port->RetryCount = 0; mstp_port->RetryCount = 0;
mstp_port->TokenCount = 1; /* changed in Errata SSPC-135-2004 */ mstp_port->TokenCount = 1; /* changed in Errata SSPC-135-2004 */
mstp_port->EventCount = 0; mstp_port->EventCount = 0;
mstp_port->master_state = MSTP_MASTER_STATE_PASS_TOKEN; mstp_port->master_state = MSTP_MASTER_STATE_PASS_TOKEN;
} }
} } else {
else {
/* SendMaintenancePFM */ /* SendMaintenancePFM */
mstp_port->Poll_Station = next_poll_station; mstp_port->Poll_Station = next_poll_station;
MSTP_Create_And_Send_Frame(mstp_port, MSTP_Create_And_Send_Frame(mstp_port,
FRAME_TYPE_POLL_FOR_MASTER, FRAME_TYPE_POLL_FOR_MASTER,
mstp_port->Poll_Station, mstp_port->Poll_Station, mstp_port->This_Station, NULL, 0);
mstp_port->This_Station, NULL, 0);
mstp_port->RetryCount = 0; mstp_port->RetryCount = 0;
mstp_port->master_state = MSTP_MASTER_STATE_POLL_FOR_MASTER; mstp_port->master_state = MSTP_MASTER_STATE_POLL_FOR_MASTER;
} }
@@ -986,7 +968,8 @@ void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port)
/* Transmit a Token frame to NS */ /* Transmit a Token frame to NS */
MSTP_Create_And_Send_Frame(mstp_port, MSTP_Create_And_Send_Frame(mstp_port,
FRAME_TYPE_TOKEN, FRAME_TYPE_TOKEN,
mstp_port->Next_Station, mstp_port->This_Station, NULL, 0); mstp_port->Next_Station, mstp_port->This_Station, NULL,
0);
mstp_port->EventCount = 0; mstp_port->EventCount = 0;
/* re-enter the current state to listen for NS */ /* re-enter the current state to listen for NS */
/* to begin using the token. */ /* to begin using the token. */
@@ -997,14 +980,16 @@ void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port)
/* Transmit a Poll For Master frame to PS. */ /* Transmit a Poll For Master frame to PS. */
MSTP_Create_And_Send_Frame(mstp_port, MSTP_Create_And_Send_Frame(mstp_port,
FRAME_TYPE_POLL_FOR_MASTER, FRAME_TYPE_POLL_FOR_MASTER,
mstp_port->Poll_Station, mstp_port->This_Station, NULL, 0); mstp_port->Poll_Station, mstp_port->This_Station, NULL,
0);
/* no known successor node */ /* no known successor node */
mstp_port->Next_Station = mstp_port->This_Station; mstp_port->Next_Station = mstp_port->This_Station;
mstp_port->RetryCount = 0; mstp_port->RetryCount = 0;
mstp_port->TokenCount = 0; mstp_port->TokenCount = 0;
/* mstp_port->EventCount = 0; removed in Addendum 135-2004d-8 */ /* mstp_port->EventCount = 0; removed in Addendum 135-2004d-8 */
/* find a new successor to TS */ /* find a new successor to TS */
mstp_port->master_state = MSTP_MASTER_STATE_POLL_FOR_MASTER; mstp_port->master_state =
MSTP_MASTER_STATE_POLL_FOR_MASTER;
} }
} }
break; break;
@@ -1021,9 +1006,9 @@ void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port)
/* Enter the IDLE state to receive and process the incoming frame. */ /* Enter the IDLE state to receive and process the incoming frame. */
mstp_port->master_state = MSTP_MASTER_STATE_IDLE; mstp_port->master_state = MSTP_MASTER_STATE_IDLE;
} }
} } else {
else { ns_timeout =
ns_timeout = Tno_token + (Tslot * (mstp_port->This_Station + 1)); Tno_token + (Tslot * (mstp_port->This_Station + 1));
if (mstp_port->SilenceTimer < ns_timeout) { if (mstp_port->SilenceTimer < ns_timeout) {
/* GenerateToken */ /* GenerateToken */
/* Assume that this node is the lowest numerical address */ /* Assume that this node is the lowest numerical address */
@@ -1032,14 +1017,16 @@ void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port)
/* Transmit a Poll For Master frame to PS. */ /* Transmit a Poll For Master frame to PS. */
MSTP_Create_And_Send_Frame(mstp_port, MSTP_Create_And_Send_Frame(mstp_port,
FRAME_TYPE_POLL_FOR_MASTER, FRAME_TYPE_POLL_FOR_MASTER,
mstp_port->Poll_Station, mstp_port->This_Station, NULL, 0); mstp_port->Poll_Station, mstp_port->This_Station, NULL,
0);
/* indicate that the next station is unknown */ /* indicate that the next station is unknown */
mstp_port->Next_Station = mstp_port->This_Station; mstp_port->Next_Station = mstp_port->This_Station;
mstp_port->RetryCount = 0; mstp_port->RetryCount = 0;
mstp_port->TokenCount = 0; mstp_port->TokenCount = 0;
/* mstp_port->EventCount = 0; removed Addendum 135-2004d-8 */ /* mstp_port->EventCount = 0; removed Addendum 135-2004d-8 */
/* enter the POLL_FOR_MASTER state to find a new successor to TS. */ /* enter the POLL_FOR_MASTER state to find a new successor to TS. */
mstp_port->master_state = MSTP_MASTER_STATE_POLL_FOR_MASTER; mstp_port->master_state =
MSTP_MASTER_STATE_POLL_FOR_MASTER;
} }
} }
break; break;
@@ -1047,10 +1034,10 @@ void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port)
/* a previously sent Poll For Master frame in order to find */ /* a previously sent Poll For Master frame in order to find */
/* a successor node. */ /* a successor node. */
case MSTP_MASTER_STATE_POLL_FOR_MASTER: case MSTP_MASTER_STATE_POLL_FOR_MASTER:
if (mstp_port->ReceivedValidFrame == true) if (mstp_port->ReceivedValidFrame == true) {
{ if ((mstp_port->DestinationAddress == mstp_port->This_Station)
if ((mstp_port->DestinationAddress == mstp_port->This_Station) && && (mstp_port->FrameType ==
(mstp_port->FrameType == FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER)) { FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER)) {
/* ReceivedReplyToPFM */ /* ReceivedReplyToPFM */
mstp_port->SoleMaster = false; mstp_port->SoleMaster = false;
mstp_port->Next_Station = mstp_port->SourceAddress; mstp_port->Next_Station = mstp_port->SourceAddress;
@@ -1058,13 +1045,13 @@ void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port)
/* Transmit a Token frame to NS */ /* Transmit a Token frame to NS */
MSTP_Create_And_Send_Frame(mstp_port, MSTP_Create_And_Send_Frame(mstp_port,
FRAME_TYPE_TOKEN, FRAME_TYPE_TOKEN,
mstp_port->Next_Station, mstp_port->This_Station, NULL, 0); mstp_port->Next_Station, mstp_port->This_Station, NULL,
0);
mstp_port->Poll_Station = mstp_port->This_Station; mstp_port->Poll_Station = mstp_port->This_Station;
mstp_port->TokenCount = 0; mstp_port->TokenCount = 0;
mstp_port->RetryCount = 0; mstp_port->RetryCount = 0;
mstp_port->master_state = MSTP_MASTER_STATE_PASS_TOKEN; mstp_port->master_state = MSTP_MASTER_STATE_PASS_TOKEN;
} } else {
else {
/* ReceivedUnexpectedFrame */ /* ReceivedUnexpectedFrame */
/* An unexpected frame was received. */ /* An unexpected frame was received. */
/* This may indicate the presence of multiple tokens. */ /* This may indicate the presence of multiple tokens. */
@@ -1073,9 +1060,8 @@ void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port)
mstp_port->master_state = MSTP_MASTER_STATE_IDLE; mstp_port->master_state = MSTP_MASTER_STATE_IDLE;
} }
mstp_port->ReceivedValidFrame = false; mstp_port->ReceivedValidFrame = false;
} } else if ((mstp_port->SilenceTimer >= Tusage_timeout) ||
else if ((mstp_port->SilenceTimer >= Tusage_timeout) || (mstp_port->ReceivedInvalidFrame == true)) {
(mstp_port->ReceivedInvalidFrame == true)) {
if (mstp_port->SoleMaster == true) { if (mstp_port->SoleMaster == true) {
/* SoleMaster */ /* SoleMaster */
/* There was no valid reply to the periodic poll */ /* There was no valid reply to the periodic poll */
@@ -1092,18 +1078,19 @@ void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port)
/* transmit a Token frame to NS */ /* transmit a Token frame to NS */
MSTP_Create_And_Send_Frame(mstp_port, MSTP_Create_And_Send_Frame(mstp_port,
FRAME_TYPE_TOKEN, FRAME_TYPE_TOKEN,
mstp_port->Next_Station, mstp_port->This_Station, NULL, 0); mstp_port->Next_Station, mstp_port->This_Station,
NULL, 0);
mstp_port->RetryCount = 0; mstp_port->RetryCount = 0;
mstp_port->master_state = MSTP_MASTER_STATE_PASS_TOKEN; mstp_port->master_state = MSTP_MASTER_STATE_PASS_TOKEN;
} else { } else {
if (next_poll_station != mstp_port->This_Station) if (next_poll_station != mstp_port->This_Station) {
{
/* SendNextPFM */ /* SendNextPFM */
mstp_port->Poll_Station = next_poll_station; mstp_port->Poll_Station = next_poll_station;
/* Transmit a Poll For Master frame to PS. */ /* Transmit a Poll For Master frame to PS. */
MSTP_Create_And_Send_Frame(mstp_port, MSTP_Create_And_Send_Frame(mstp_port,
FRAME_TYPE_POLL_FOR_MASTER, FRAME_TYPE_POLL_FOR_MASTER,
mstp_port->Poll_Station, mstp_port->This_Station, NULL, 0); mstp_port->Poll_Station,
mstp_port->This_Station, NULL, 0);
mstp_port->RetryCount = 0; mstp_port->RetryCount = 0;
/* Re-enter the current state. */ /* Re-enter the current state. */
} else { } else {
@@ -1111,7 +1098,8 @@ void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port)
/* to indicate that this station is the only master */ /* to indicate that this station is the only master */
mstp_port->SoleMaster = true; mstp_port->SoleMaster = true;
mstp_port->FrameCount = 0; mstp_port->FrameCount = 0;
mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN; mstp_port->master_state =
MSTP_MASTER_STATE_USE_TOKEN;
} }
} }
} }
@@ -1130,11 +1118,11 @@ void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port)
/* (the mechanism used to determine this is a local matter), */ /* (the mechanism used to determine this is a local matter), */
/* then call MSTP_Create_And_Send_Frame to transmit the reply frame */ /* then call MSTP_Create_And_Send_Frame to transmit the reply frame */
/* and enter the IDLE state to wait for the next frame. */ /* and enter the IDLE state to wait for the next frame. */
if ((mstp_port->FrameType == FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY) && if ((mstp_port->FrameType ==
(mstp_port->TxReady)) { FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY)
RS485_Send_Frame( && (mstp_port->TxReady)) {
mstp_port, RS485_Send_Frame(mstp_port,
(uint8_t *) &mstp_port->TxBuffer[0], (uint8_t *) & mstp_port->TxBuffer[0],
mstp_port->TxLength); mstp_port->TxLength);
mstp_port->TxReady = false; mstp_port->TxReady = false;
} }
@@ -1230,7 +1218,7 @@ void MSTP_Init(volatile struct mstp_port_struct_t *mstp_port,
mstp_port->TxLength = 0; mstp_port->TxLength = 0;
mstp_port->TxReady = false; mstp_port->TxReady = false;
mstp_port->TxFrameType = 0; mstp_port->TxFrameType = 0;
} }
} }
+11 -11
View File
@@ -199,8 +199,8 @@ struct mstp_port_struct_t {
/* This array is only used for APDU messages */ /* This array is only used for APDU messages */
uint8_t TxBuffer[MAX_MPDU]; uint8_t TxBuffer[MAX_MPDU];
unsigned TxLength; unsigned TxLength;
bool TxReady; /* true if ready to be sent or received */ bool TxReady; /* true if ready to be sent or received */
uint8_t TxFrameType; /* type of message - needed by MS/TP */ uint8_t TxFrameType; /* type of message - needed by MS/TP */
}; };
#define DEFAULT_MAX_INFO_FRAMES 1 #define DEFAULT_MAX_INFO_FRAMES 1
@@ -223,18 +223,18 @@ extern "C" {
*mstp_port); *mstp_port);
void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t
*mstp_port); *mstp_port);
/* returns true if line is active */ /* returns true if line is active */
bool MSTP_Line_Active(volatile struct mstp_port_struct_t *mstp_port); bool MSTP_Line_Active(volatile struct mstp_port_struct_t *mstp_port);
unsigned MSTP_Create_Frame(uint8_t * buffer, /* where frame is loaded */ unsigned MSTP_Create_Frame(uint8_t * buffer, /* where frame is loaded */
unsigned buffer_len, /* amount of space available */ unsigned buffer_len, /* amount of space available */
uint8_t frame_type, /* type of frame to send - see defines */ uint8_t frame_type, /* type of frame to send - see defines */
uint8_t destination, /* destination address */ uint8_t destination, /* destination address */
uint8_t source, /* source address */ uint8_t source, /* source address */
uint8_t * data, /* any data to be sent - may be null */ uint8_t * data, /* any data to be sent - may be null */
unsigned data_len); /* number of bytes of data (up to 501) */ unsigned data_len); /* number of bytes of data (up to 501) */
#ifdef __cplusplus #ifdef __cplusplus
} }
+2 -2
View File
@@ -186,7 +186,7 @@ bool arcnet_init(char *interface_name)
/* function to send a PDU out the socket */ /* function to send a PDU out the socket */
/* returns number of bytes sent on success, negative on failure */ /* returns number of bytes sent on success, negative on failure */
int arcnet_send_pdu(BACNET_ADDRESS * dest, /* destination address */ int arcnet_send_pdu(BACNET_ADDRESS * dest, /* destination address */
BACNET_NPDU_DATA * npdu_data, /* network information */ BACNET_NPDU_DATA * npdu_data, /* network information */
uint8_t * pdu, /* any data to be sent - may be null */ uint8_t * pdu, /* any data to be sent - may be null */
unsigned pdu_len) unsigned pdu_len)
{ /* number of bytes of data */ { /* number of bytes of data */
@@ -230,7 +230,7 @@ int arcnet_send_pdu(BACNET_ADDRESS * dest, /* destination address */
fprintf(stderr, "arcnet: PDU is too big to send!\n"); fprintf(stderr, "arcnet: PDU is too big to send!\n");
return -4; return -4;
} }
memcpy(&pkt->soft.raw[4+npdu_len], pdu, pdu_len); memcpy(&pkt->soft.raw[4 + npdu_len], pdu, pdu_len);
/* Send the packet */ /* Send the packet */
bytes = bytes =
sendto(ARCNET_Sock_FD, &mtu, mtu_len, 0, sendto(ARCNET_Sock_FD, &mtu, mtu_len, 0,
+6 -6
View File
@@ -179,14 +179,14 @@ bool ethernet_init(char *interface_name)
/* function to send a packet out the 802.2 socket */ /* function to send a packet out the 802.2 socket */
/* returns number of bytes sent on success, negative on failure */ /* returns number of bytes sent on success, negative on failure */
int ethernet_send_pdu(BACNET_ADDRESS * dest, /* destination address */ int ethernet_send_pdu(BACNET_ADDRESS * dest, /* destination address */
BACNET_NPDU_DATA * npdu_data, /* network information */ BACNET_NPDU_DATA * npdu_data, /* network information */
uint8_t * pdu, /* any data to be sent - may be null */ uint8_t * pdu, /* any data to be sent - may be null */
unsigned pdu_len) unsigned pdu_len)
{ /* number of bytes of data */ { /* number of bytes of data */
int i = 0; /* counter */ int i = 0; /* counter */
int bytes = 0; int bytes = 0;
BACNET_ADDRESS src = { 0 }; /* source address for npdu*/ BACNET_ADDRESS src = { 0 }; /* source address for npdu */
uint8_t mtu[MAX_MPDU] = { 0 }; /* our buffer */ uint8_t mtu[MAX_MPDU] = { 0 }; /* our buffer */
int mtu_len = 0; int mtu_len = 0;
int npdu_len = 0; int npdu_len = 0;
@@ -221,9 +221,9 @@ int ethernet_send_pdu(BACNET_ADDRESS * dest, /* destination address */
return -3; return -3;
} }
/* Logical PDU portion */ /* Logical PDU portion */
mtu[14] = 0x82; /* DSAP for BACnet */ mtu[14] = 0x82; /* DSAP for BACnet */
mtu[15] = 0x82; /* SSAP for BACnet */ mtu[15] = 0x82; /* SSAP for BACnet */
mtu[16] = 0x03; /* Control byte in header */ mtu[16] = 0x03; /* Control byte in header */
npdu_len = npdu_encode_pdu(&mtu[17], dest, &src, npdu_data); npdu_len = npdu_encode_pdu(&mtu[17], dest, &src, npdu_data);
mtu_len = 17 + npdu_len; mtu_len = 17 + npdu_len;
if ((mtu_len + pdu_len) > MAX_MPDU) { if ((mtu_len + pdu_len) > MAX_MPDU) {
+26 -28
View File
@@ -31,13 +31,13 @@
#include "dlmstp.h" #include "dlmstp.h"
#include "rs485.h" #include "rs485.h"
#include "npdu.h" #include "npdu.h"
/* receive buffer */ /* receive buffer */
static DLMSTP_PACKET Receive_Buffer; static DLMSTP_PACKET Receive_Buffer;
/* temp buffer for NPDU insertion */ /* temp buffer for NPDU insertion */
static uint8_t PDU_Buffer[MAX_MPDU]; static uint8_t PDU_Buffer[MAX_MPDU];
/* local MS/TP port data */ /* local MS/TP port data */
static volatile struct mstp_port_struct_t MSTP_Port; static volatile struct mstp_port_struct_t MSTP_Port;
void dlmstp_init(void) void dlmstp_init(void)
{ {
@@ -56,49 +56,47 @@ void dlmstp_cleanup(void)
/* returns number of bytes sent on success, zero on failure */ /* returns number of bytes sent on success, zero on failure */
int dlmstp_send_pdu(BACNET_ADDRESS * dest, /* destination address */ int dlmstp_send_pdu(BACNET_ADDRESS * dest, /* destination address */
BACNET_NPDU_DATA * npdu_data, /* network information */ BACNET_NPDU_DATA * npdu_data, /* network information */
uint8_t * pdu, /* any data to be sent - may be null */ uint8_t * pdu, /* any data to be sent - may be null */
unsigned pdu_len) unsigned pdu_len)
{ /* number of bytes of data */ { /* number of bytes of data */
bool status; bool status;
int bytes_sent = 0; int bytes_sent = 0;
int npdu_len = 0; int npdu_len = 0;
uint8_t frame_type = 0; uint8_t frame_type = 0;
uint8_t destination = 0; /* destination address */ uint8_t destination = 0; /* destination address */
BACNET_ADDRESS src; BACNET_ADDRESS src;
if (MSTP_Port.TxReady == false) { if (MSTP_Port.TxReady == false) {
if (npdu_data->confirmed_message) if (npdu_data->confirmed_message)
MSTP_Port.TxFrameType = FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY; MSTP_Port.TxFrameType = FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY;
else else
MSTP_Port.TxFrameType = FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY; MSTP_Port.TxFrameType =
FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY;
/* load destination MAC address */ /* load destination MAC address */
if (dest && dest->mac_len == 1) { if (dest && dest->mac_len == 1) {
destination = dest->mac[0]; destination = dest->mac[0];
} else { } else {
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "mstp: invalid destination MAC address!\n"); fprintf(stderr, "mstp: invalid destination MAC address!\n");
#endif #endif
return -2; return -2;
} }
dlmstp_get_my_address(&src); dlmstp_get_my_address(&src);
npdu_len = npdu_encode_pdu(&PDU_Buffer[0], dest, &src, npdu_data); npdu_len = npdu_encode_pdu(&PDU_Buffer[0], dest, &src, npdu_data);
if ((8 /* header len */ + npdu_len + pdu_len) > MAX_MPDU) { if ((8 /* header len */ + npdu_len + pdu_len) > MAX_MPDU) {
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "mstp: PDU is too big to send!\n"); fprintf(stderr, "mstp: PDU is too big to send!\n");
#endif #endif
return -4; return -4;
} }
memmove(&PDU_Buffer[npdu_len], pdu, pdu_len); memmove(&PDU_Buffer[npdu_len], pdu, pdu_len);
bytes_sent = MSTP_Create_Frame( bytes_sent = MSTP_Create_Frame(&MSTP_Port.TxBuffer[0],
&MSTP_Port.TxBuffer[0],
sizeof(MSTP_Port.TxBuffer), sizeof(MSTP_Port.TxBuffer),
MSTP_Port.TxFrameType, MSTP_Port.TxFrameType,
destination, destination,
MSTP_Port.This_Station, MSTP_Port.This_Station, &PDU_Buffer[0], npdu_len + pdu_len);
&PDU_Buffer[0],
npdu_len + pdu_len);
MSTP_Port.TxLength = bytes_sent; MSTP_Port.TxLength = bytes_sent;
MSTP_Port.TxReady = true; MSTP_Port.TxReady = true;
} }
@@ -127,17 +125,17 @@ uint16_t dlmstp_receive(BACNET_ADDRESS * src, /* source address */
uint8_t * pdu, /* PDU data */ uint8_t * pdu, /* PDU data */
uint16_t max_pdu, /* amount of space available in the PDU */ uint16_t max_pdu, /* amount of space available in the PDU */
unsigned timeout) unsigned timeout)
{ {
uint16_t pdu_len = 0; uint16_t pdu_len = 0;
(void) timeout; (void) timeout;
/* see if there is a packet available */ /* see if there is a packet available */
if (Receive_Buffer.ready) if (Receive_Buffer.ready) {
{ memmove(src, &Receive_Buffer.address,
memmove(src, &Receive_Buffer.address, sizeof(Receive_Buffer.address)); sizeof(Receive_Buffer.address));
pdu_len = Receive_Buffer.pdu_len; pdu_len = Receive_Buffer.pdu_len;
memmove(&pdu[0], &Receive_Buffer.pdu[0], max_pdu); memmove(&pdu[0], &Receive_Buffer.pdu[0], max_pdu);
Receive_Buffer.ready = false; Receive_Buffer.ready = false;
} }
return pdu_len; return pdu_len;
+4 -3
View File
@@ -95,7 +95,9 @@ void My_Read_Property_Handler(uint8_t * service_request,
data.application_data = &Temp_Buf[0]; data.application_data = &Temp_Buf[0];
data.application_data_len = len; data.application_data_len = len;
/* FIXME: probably need a length limitation sent with encode */ /* FIXME: probably need a length limitation sent with encode */
pdu_len = rp_ack_encode_apdu(&Handler_Transmit_Buffer[0], service_data->invoke_id, &data); pdu_len =
rp_ack_encode_apdu(&Handler_Transmit_Buffer[0],
service_data->invoke_id, &data);
} else } else
error = true; error = true;
} else } else
@@ -112,8 +114,7 @@ void My_Read_Property_Handler(uint8_t * service_request,
SERVICE_CONFIRMED_READ_PROPERTY, error_class, error_code); SERVICE_CONFIRMED_READ_PROPERTY, error_class, error_code);
} }
npdu_encode_confirmed_apdu(&npdu_data, MESSAGE_PRIORITY_NORMAL); npdu_encode_confirmed_apdu(&npdu_data, MESSAGE_PRIORITY_NORMAL);
bytes_sent = datalink_send_pdu(src, &npdu_data, bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); /* number of bytes of data */
&Handler_Transmit_Buffer[0], pdu_len); /* number of bytes of data */
return; return;
} }
+1 -1
View File
@@ -215,7 +215,7 @@ void RS485_Process_Tx_Message(void)
*****************************************************************************/ *****************************************************************************/
bool RS485_Tx_Complete(void) bool RS485_Tx_Complete(void)
{ {
return RS485_Flags.TransmitComplete; return RS485_Flags.TransmitComplete;
} }
/**************************************************************************** /****************************************************************************
+7 -8
View File
@@ -42,7 +42,7 @@ static int interface = SOCKET_ERROR; /* SOCKET_ERROR means no open interface
void bip_set_interface(char *ifname) void bip_set_interface(char *ifname)
{ {
/*dummy function - to make the demos compile easier */ /*dummy function - to make the demos compile easier */
(void)ifname; (void) ifname;
} }
/*-----------------------------------*/ /*-----------------------------------*/
@@ -204,16 +204,15 @@ static void NetInitialize(void)
* ALGORITHM: none * ALGORITHM: none
* NOTES: none * NOTES: none
******************************************************************/ ******************************************************************/
static void RTIP_To_Network_Address( static void RTIP_To_Network_Address(BYTE * octet_address,
BYTE *octet_address, struct in_addr *addr)
struct in_addr *addr)
{ {
uint32_t ip_address = 0; /* for decoding the subnet mask */ uint32_t ip_address = 0; /* for decoding the subnet mask */
decode_unsigned32(octet_address, &ip_address); decode_unsigned32(octet_address, &ip_address);
addr->s_addr = htonl(ip_address); addr->s_addr = htonl(ip_address);
return; return;
} }
static void set_broadcast_address(uint32_t net_address) static void set_broadcast_address(uint32_t net_address)
+74 -80
View File
@@ -26,21 +26,21 @@
#include <stdint.h> #include <stdint.h>
#include <stddef.h> #include <stddef.h>
#include <string.h> #include <string.h>
#if PRINT_ENABLED #if PRINT_ENABLED
#include <stdio.h> #include <stdio.h>
#endif #endif
#include "bacdef.h" #include "bacdef.h"
#include "mstp.h" #include "mstp.h"
#include "dlmstp.h" #include "dlmstp.h"
#include "rs485.h" #include "rs485.h"
#include "npdu.h" #include "npdu.h"
/* receive buffer */ /* receive buffer */
static DLMSTP_PACKET Receive_Buffer; static DLMSTP_PACKET Receive_Buffer;
/* temp buffer for NPDU insertion */ /* temp buffer for NPDU insertion */
static uint8_t PDU_Buffer[MAX_MPDU]; static uint8_t PDU_Buffer[MAX_MPDU];
/* local MS/TP port data */ /* local MS/TP port data */
static volatile struct mstp_port_struct_t MSTP_Port; static volatile struct mstp_port_struct_t MSTP_Port;
void dlmstp_init(void) void dlmstp_init(void)
{ {
@@ -59,49 +59,48 @@ void dlmstp_cleanup(void)
/* returns number of bytes sent on success, zero on failure */ /* returns number of bytes sent on success, zero on failure */
int dlmstp_send_pdu(BACNET_ADDRESS * dest, /* destination address */ int dlmstp_send_pdu(BACNET_ADDRESS * dest, /* destination address */
BACNET_NPDU_DATA * npdu_data, /* network information */ BACNET_NPDU_DATA * npdu_data, /* network information */
uint8_t * pdu, /* any data to be sent - may be null */ uint8_t * pdu, /* any data to be sent - may be null */
unsigned pdu_len) unsigned pdu_len)
{ /* number of bytes of data */ { /* number of bytes of data */
int bytes_sent = 0; int bytes_sent = 0;
unsigned npdu_len = 0; unsigned npdu_len = 0;
uint8_t frame_type = 0; uint8_t frame_type = 0;
uint8_t destination = 0; /* destination address */ uint8_t destination = 0; /* destination address */
BACNET_ADDRESS src; BACNET_ADDRESS src;
if (MSTP_Port.TxReady == false) { if (MSTP_Port.TxReady == false) {
if (npdu_data->confirmed_message) if (npdu_data->confirmed_message)
MSTP_Port.TxFrameType = FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY; MSTP_Port.TxFrameType = FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY;
else else
MSTP_Port.TxFrameType = FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY; MSTP_Port.TxFrameType =
FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY;
/* load destination MAC address */ /* load destination MAC address */
if (dest && dest->mac_len == 1) { if (dest && dest->mac_len == 1) {
destination = dest->mac[0]; destination = dest->mac[0];
} else { } else {
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "mstp: invalid destination MAC address!\n"); fprintf(stderr, "mstp: invalid destination MAC address!\n");
#endif #endif
return -2; return -2;
} }
dlmstp_get_my_address(&src); dlmstp_get_my_address(&src);
npdu_len = npdu_encode_pdu(&PDU_Buffer[0], dest, &src, npdu_data); npdu_len = npdu_encode_pdu(&PDU_Buffer[0], dest, &src, npdu_data);
if ((8 /* header len */ + npdu_len + pdu_len) > MAX_MPDU) { if ((8 /* header len */ + npdu_len + pdu_len) > MAX_MPDU) {
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "mstp: PDU is too big to send!\n"); fprintf(stderr, "mstp: PDU is too big to send!\n");
#endif #endif
return -4; return -4;
} }
memmove(&PDU_Buffer[npdu_len], pdu, pdu_len); memmove(&PDU_Buffer[npdu_len], pdu, pdu_len);
bytes_sent = MSTP_Create_Frame( bytes_sent = MSTP_Create_Frame(
(uint8_t *)&MSTP_Port.TxBuffer[0], (uint8_t *) & MSTP_Port.TxBuffer[0],
sizeof(MSTP_Port.TxBuffer), sizeof(MSTP_Port.TxBuffer),
MSTP_Port.TxFrameType, MSTP_Port.TxFrameType,
destination, destination,
MSTP_Port.This_Station, MSTP_Port.This_Station, &PDU_Buffer[0], npdu_len + pdu_len);
&PDU_Buffer[0], MSTP_Port.TxLength = bytes_sent;
npdu_len + pdu_len);
MSTP_Port.TxLength = bytes_sent;
MSTP_Port.TxReady = true; MSTP_Port.TxReady = true;
} }
@@ -109,16 +108,15 @@ int dlmstp_send_pdu(BACNET_ADDRESS * dest, /* destination address */
} }
void dlmstp_task(void) void dlmstp_task(void)
{ {
RS485_Check_UART_Data(&MSTP_Port); RS485_Check_UART_Data(&MSTP_Port);
/* only do receive state machine while we don't have a frame */ /* only do receive state machine while we don't have a frame */
if ((MSTP_Port.ReceivedValidFrame == false) && if ((MSTP_Port.ReceivedValidFrame == false) &&
(MSTP_Port.ReceivedInvalidFrame == false)) (MSTP_Port.ReceivedInvalidFrame == false)) {
{ MSTP_Receive_Frame_FSM(&MSTP_Port);
MSTP_Receive_Frame_FSM(&MSTP_Port); }
} /* only do master state machine while rx is idle */
/* only do master state machine while rx is idle */ if (MSTP_Port.receive_state == MSTP_RECEIVE_STATE_IDLE)
if (MSTP_Port.receive_state == MSTP_RECEIVE_STATE_IDLE)
MSTP_Master_Node_FSM(&MSTP_Port); MSTP_Master_Node_FSM(&MSTP_Port);
} }
@@ -127,74 +125,70 @@ void dlmstp_millisecond_timer(void)
{ {
MSTP_Millisecond_Timer(&MSTP_Port); MSTP_Millisecond_Timer(&MSTP_Port);
} }
/* returns the number of octets in the PDU, or zero on failure */ /* returns the number of octets in the PDU, or zero on failure */
/* This function is expecting to be polled. */ /* This function is expecting to be polled. */
uint16_t dlmstp_receive(BACNET_ADDRESS * src, /* source address */ uint16_t dlmstp_receive(BACNET_ADDRESS * src, /* source address */
uint8_t * pdu, /* PDU data */ uint8_t * pdu, /* PDU data */
uint16_t max_pdu, /* amount of space available in the PDU */ uint16_t max_pdu, /* amount of space available in the PDU */
unsigned timeout) unsigned timeout)
{ {
uint16_t pdu_len = 0; uint16_t pdu_len = 0;
(void) timeout; (void) timeout;
/* see if there is a packet available */ /* see if there is a packet available */
if (Receive_Buffer.ready) if (Receive_Buffer.ready) {
{ memmove(src, &Receive_Buffer.address,
memmove(src, &Receive_Buffer.address, sizeof(Receive_Buffer.address)); sizeof(Receive_Buffer.address));
pdu_len = Receive_Buffer.pdu_len; pdu_len = Receive_Buffer.pdu_len;
memmove(&pdu[0], &Receive_Buffer.pdu[0], max_pdu); memmove(&pdu[0], &Receive_Buffer.pdu[0], max_pdu);
Receive_Buffer.ready = false; Receive_Buffer.ready = false;
} }
return pdu_len; return pdu_len;
} }
void dlmstp_fill_bacnet_address(BACNET_ADDRESS * src, uint8_t mstp_address) void dlmstp_fill_bacnet_address(BACNET_ADDRESS * src, uint8_t mstp_address)
{ {
int i = 0; int i = 0;
if (mstp_address == MSTP_BROADCAST_ADDRESS) if (mstp_address == MSTP_BROADCAST_ADDRESS) {
{ /* mac_len = 0 if broadcast address */
/* mac_len = 0 if broadcast address */ src->mac_len = 0;
src->mac_len = 0; src->mac[0] = 0;
src->mac[0] = 0; } else {
} src->mac_len = 1;
else src->mac[0] = mstp_address;
{ }
src->mac_len = 1; /* fill with 0's starting with index 1; index 0 filled above */
src->mac[0] = mstp_address; for (i = 1; i < MAX_MAC_LEN; i++) {
} src->mac[i] = 0;
/* fill with 0's starting with index 1; index 0 filled above */ }
for (i = 1; i <MAX_MAC_LEN; i++) { src->net = 0;
src->mac[i] = 0; src->len = 0;
} for (i = 0; i < MAX_MAC_LEN; i++) {
src->net = 0; src->adr[i] = 0;
src->len = 0; }
for (i = 0; i < MAX_MAC_LEN; i++) { }
src->adr[i] = 0;
}
}
/* for the MS/TP state machine to use for putting received data */ /* for the MS/TP state machine to use for putting received data */
uint16_t dlmstp_put_receive( uint16_t dlmstp_put_receive(uint8_t src, /* source MS/TP address */
uint8_t src, /* source MS/TP address */
uint8_t * pdu, /* PDU data */ uint8_t * pdu, /* PDU data */
uint16_t pdu_len) uint16_t pdu_len)
{ {
if (Receive_Buffer.ready) { if (Receive_Buffer.ready) {
/* FIXME: what to do when we miss a message? */ /* FIXME: what to do when we miss a message? */
pdu_len = 0; pdu_len = 0;
} else if (pdu_len < sizeof(Receive_Buffer.pdu)) { } else if (pdu_len < sizeof(Receive_Buffer.pdu)) {
dlmstp_fill_bacnet_address(&Receive_Buffer.address, src); dlmstp_fill_bacnet_address(&Receive_Buffer.address, src);
Receive_Buffer.pdu_len = pdu_len; Receive_Buffer.pdu_len = pdu_len;
memmove(Receive_Buffer.pdu, pdu, pdu_len); memmove(Receive_Buffer.pdu, pdu, pdu_len);
Receive_Buffer.ready = true; Receive_Buffer.ready = true;
} else { } else {
/* FIXME: message too large? */ /* FIXME: message too large? */
pdu_len = 0; pdu_len = 0;
} }
return pdu_len; return pdu_len;
} }
+4 -5
View File
@@ -87,7 +87,7 @@ bool ethernet_init(char *interface_name)
/* returns bytes sent on success, negative number on failure */ /* returns bytes sent on success, negative number on failure */
int ethernet_send(BACNET_ADDRESS * dest, /* destination address */ int ethernet_send(BACNET_ADDRESS * dest, /* destination address */
BACNET_ADDRESS * src, /* source address */ BACNET_ADDRESS * src, /* source address */
BACNET_NPDU_DATA * npdu_data, /* network information */ BACNET_NPDU_DATA * npdu_data, /* network information */
uint8_t * pdu, /* any data to be sent - may be null */ uint8_t * pdu, /* any data to be sent - may be null */
unsigned pdu_len) unsigned pdu_len)
{ /* number of bytes of data */ { /* number of bytes of data */
@@ -158,7 +158,7 @@ int ethernet_send(BACNET_ADDRESS * dest, /* destination address */
/* function to send a packet out the 802.2 socket */ /* function to send a packet out the 802.2 socket */
/* returns bytes sent on success, negative number on failure */ /* returns bytes sent on success, negative number on failure */
int ethernet_send_pdu(BACNET_ADDRESS * dest, /* destination address */ int ethernet_send_pdu(BACNET_ADDRESS * dest, /* destination address */
BACNET_NPDU_DATA * npdu_data, /* network information */ BACNET_NPDU_DATA * npdu_data, /* network information */
uint8_t * pdu, /* any data to be sent - may be null */ uint8_t * pdu, /* any data to be sent - may be null */
unsigned pdu_len) unsigned pdu_len)
{ /* number of bytes of data */ { /* number of bytes of data */
@@ -169,14 +169,13 @@ int ethernet_send_pdu(BACNET_ADDRESS * dest, /* destination address */
src.mac[i] = Ethernet_MAC_Address[i]; src.mac[i] = Ethernet_MAC_Address[i];
src.mac_len++; src.mac_len++;
} }
/* FIXME: npdu_data? */ /* FIXME: npdu_data? */
/* function to send a packet out the 802.2 socket */ /* function to send a packet out the 802.2 socket */
/* returns 1 on success, 0 on failure */ /* returns 1 on success, 0 on failure */
return ethernet_send(dest, /* destination address */ return ethernet_send(dest, /* destination address */
&src, /* source address */ &src, /* source address */
npdu_data, npdu_data, pdu, /* any data to be sent - may be null */
pdu, /* any data to be sent - may be null */
pdu_len); /* number of bytes of data */ pdu_len); /* number of bytes of data */
} }
+38 -38
View File
@@ -28,7 +28,7 @@
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <conio.h> /* for kbhit */ #include <conio.h> /* for kbhit */
#include "config.h" #include "config.h"
#include "bacdef.h" #include "bacdef.h"
#include "npdu.h" #include "npdu.h"
@@ -42,17 +42,17 @@
/* RTOS-32 */ /* RTOS-32 */
#include "rtkernel.h" #include "rtkernel.h"
#if defined(RTK32_VER) #if defined(RTK32_VER)
#define _USER32_ #define _USER32_
#define _KERNEL32_ #define _KERNEL32_
#include <windows.h> #include <windows.h>
#include <rttarget.h> /* for RTCMOSSetSystemTime */ #include <rttarget.h> /* for RTCMOSSetSystemTime */
#include <rtfiles.h> /* file system */ #include <rtfiles.h> /* file system */
#include <rtfsys.h> /* file system */ #include <rtfsys.h> /* file system */
#include <Rttbios.h> #include <Rttbios.h>
#endif #endif
#include <rtcom.h> /* serial port driver */ #include <rtcom.h> /* serial port driver */
#include <itimer.h> /* time measurement & timer interrupt rate control */ #include <itimer.h> /* time measurement & timer interrupt rate control */
#include <rtkeybrd.h> /* interrupt handler for the keyboard */ #include <rtkeybrd.h> /* interrupt handler for the keyboard */
/* buffers used for transmit and receive */ /* buffers used for transmit and receive */
static uint8_t Rx_Buf[MAX_MPDU] = { 0 }; static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
@@ -60,10 +60,12 @@ static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
static void Init_Service_Handlers(void) static void Init_Service_Handlers(void)
{ {
/* we need to handle who-is to support dynamic device binding */ /* we need to handle who-is to support dynamic device binding */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is); apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS,
handler_who_is);
/* set the handler for all the services we don't implement */ /* set the handler for all the services we don't implement */
/* It is required to send the proper reject message... */ /* It is required to send the proper reject message... */
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service); apdu_set_unrecognized_service_handler_handler
(handler_unrecognized_service);
/* we must implement read property - it's required! */ /* we must implement read property - it's required! */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
handler_read_property); handler_read_property);
@@ -73,30 +75,28 @@ static void Init_Service_Handlers(void)
void millisecond_task(void) void millisecond_task(void)
{ {
Time ticks = 0; /* task cycle */ Time ticks = 0; /* task cycle */
int i = 0; /* loop counter */ int i = 0; /* loop counter */
ticks = RTKGetTime() + MilliSecsToTicks(1); ticks = RTKGetTime() + MilliSecsToTicks(1);
while (TRUE) while (TRUE) {
{ RTKDelayUntil(ticks);
RTKDelayUntil(ticks); dlmstp_millisecond_timer();
dlmstp_millisecond_timer(); ticks += MilliSecsToTicks(1);
ticks += MilliSecsToTicks(1); }
}
} }
void RTOS_Initialize(void) void RTOS_Initialize(void)
{ {
/* allow OS to setup IRQ 1 by using a dummy call */ /* allow OS to setup IRQ 1 by using a dummy call */
(void)kbhit(); (void) kbhit();
RTKernelInit(0); /* get the kernel going */ RTKernelInit(0); /* get the kernel going */
RTKeybrdInit(); RTKeybrdInit();
//(void)CPUMoniInit(); /* not needed - just monitor idle task */ //(void)CPUMoniInit(); /* not needed - just monitor idle task */
RTComInit(); RTComInit();
ITimerInit(); ITimerInit();
if (RTCallDebugger(RT_DBG_MONITOR,0,0) != -1) if (RTCallDebugger(RT_DBG_MONITOR, 0, 0) != -1) {
{
/* Win32 structured exception - if no handler is /* Win32 structured exception - if no handler is
installed, TerminateProcess() will be called, installed, TerminateProcess() will be called,
which will reboot - a good thing in our case. */ which will reboot - a good thing in our case. */
@@ -107,25 +107,25 @@ void RTOS_Initialize(void)
RTRaiseCPUException(4); // Overflow INTO instruction. RTRaiseCPUException(4); // Overflow INTO instruction.
RTRaiseCPUException(5); // BOUND Range Exceeded BOUND instruction. RTRaiseCPUException(5); // BOUND Range Exceeded BOUND instruction.
RTRaiseCPUException(6); // Invalid Opcode (Undefined Opcode) RTRaiseCPUException(6); // Invalid Opcode (Undefined Opcode)
// RTRaiseCPUException(7); // Device Not Available (No Math Coprocessor) // RTRaiseCPUException(7); // Device Not Available (No Math Coprocessor)
RTRaiseCPUException(8); // Double Fault any exception instruction,NMI,INTR. RTRaiseCPUException(8); // Double Fault any exception instruction,NMI,INTR.
RTRaiseCPUException(9); // Co-Processor overrun RTRaiseCPUException(9); // Co-Processor overrun
RTRaiseCPUException(10); // Invalid TSS Task switch or TSS access. RTRaiseCPUException(10); // Invalid TSS Task switch or TSS access.
RTRaiseCPUException(11); // Segment Not Present Loading segment registers RTRaiseCPUException(11); // Segment Not Present Loading segment registers
RTRaiseCPUException(12); // Stack Seg Fault Stack ops /SS reg loads. RTRaiseCPUException(12); // Stack Seg Fault Stack ops /SS reg loads.
RTRaiseCPUException(13); // General Protection Any memory reference RTRaiseCPUException(13); // General Protection Any memory reference
RTRaiseCPUException(14); // Page Fault Any memory reference. RTRaiseCPUException(14); // Page Fault Any memory reference.
RTRaiseCPUException(15); // reserved RTRaiseCPUException(15); // reserved
RTRaiseCPUException(16); // Floating-Point Error (Math Fault) RTRaiseCPUException(16); // Floating-Point Error (Math Fault)
} }
/* setup 1ms timer tick */ /* setup 1ms timer tick */
SetTimerIntVal(1000); SetTimerIntVal(1000);
/* per recommendation in manual */ /* per recommendation in manual */
RTKDelay(1); RTKDelay(1);
RTCMOSSetSystemTime(); /* get the right time-of-day */ RTCMOSSetSystemTime(); /* get the right time-of-day */
/* create timer tick task */ /* create timer tick task */
RTKCreateTask(millisecond_task,1,1024*8,"millisec task"); RTKCreateTask(millisecond_task, 1, 1024 * 8, "millisec task");
} }
int main(int argc, char *argv[]) int main(int argc, char *argv[])
@@ -138,7 +138,7 @@ int main(int argc, char *argv[])
(void) argv; (void) argv;
Device_Set_Object_Instance_Number(126); Device_Set_Object_Instance_Number(126);
Init_Service_Handlers(); Init_Service_Handlers();
RTOS_Initialize(); RTOS_Initialize();
/* init the physical layer */ /* init the physical layer */
#ifdef BACDL_BIP #ifdef BACDL_BIP
if (!bip_init()) if (!bip_init())
@@ -166,7 +166,7 @@ int main(int argc, char *argv[])
npdu_handler(&src, &Rx_Buf[0], pdu_len); npdu_handler(&src, &Rx_Buf[0], pdu_len);
} }
/* output */ /* output */
/* blink LEDs, Turn on or off outputs, etc */ /* blink LEDs, Turn on or off outputs, etc */
+3 -3
View File
@@ -66,9 +66,9 @@
#define IN_CLASSC_HOST 0x000000ff #define IN_CLASSC_HOST 0x000000ff
#define IN_CLASSD(i) (((long)(i) & 0xf0000000) == 0xe0000000) #define IN_CLASSD(i) (((long)(i) & 0xf0000000) == 0xe0000000)
#define IN_CLASSD_NET 0xf0000000 /* These ones aren't really */ #define IN_CLASSD_NET 0xf0000000 /* These ones aren't really */
#define IN_CLASSD_NSHIFT 28 /* net and host fields, but */ #define IN_CLASSD_NSHIFT 28 /* net and host fields, but */
#define IN_CLASSD_HOST 0x0fffffff /* routing needn't know. */ #define IN_CLASSD_HOST 0x0fffffff /* routing needn't know. */
#define IN_MULTICAST(i) IN_CLASSD(i) #define IN_MULTICAST(i) IN_CLASSD(i)
#else #else
+4 -6
View File
@@ -158,8 +158,8 @@ void RS485_Send_Frame(volatile struct mstp_port_struct_t *mstp_port, /* port
void RS485_Check_UART_Data(volatile struct mstp_port_struct_t *mstp_port) void RS485_Check_UART_Data(volatile struct mstp_port_struct_t *mstp_port)
{ /* port specific data */ { /* port specific data */
COMData com_data = 0; /* byte from COM driver */ COMData com_data = 0; /* byte from COM driver */
unsigned timeout = 1; /* milliseconds to wait for a character */ unsigned timeout = 1; /* milliseconds to wait for a character */
static Duration ticks = 0; /* duration to wait for data */ static Duration ticks = 0; /* duration to wait for data */
if (mstp_port->ReceiveError) { if (mstp_port->ReceiveError) {
/* wait for state machine to clear this */ /* wait for state machine to clear this */
@@ -167,8 +167,7 @@ void RS485_Check_UART_Data(volatile struct mstp_port_struct_t *mstp_port)
} }
/* wait for state machine to read from the DataRegister */ /* wait for state machine to read from the DataRegister */
else if (!mstp_port->DataAvailable) { else if (!mstp_port->DataAvailable) {
if (!ticks) if (!ticks) {
{
ticks = MilliSecsToTicks(timeout); ticks = MilliSecsToTicks(timeout);
if (!ticks) if (!ticks)
ticks = 1; ticks = 1;
@@ -185,7 +184,6 @@ void RS485_Check_UART_Data(volatile struct mstp_port_struct_t *mstp_port)
mstp_port->DataAvailable = true; mstp_port->DataAvailable = true;
} }
} }
} } else
else
RTKScheduler(); RTKScheduler();
} }
+12 -13
View File
@@ -238,8 +238,8 @@ void tsm_timer_milliseconds(uint16_t milliseconds)
&TSM_List[i].apdu[0], TSM_List[i].apdu_len); &TSM_List[i].apdu[0], TSM_List[i].apdu_len);
} else { } else {
/* note: the invoke id has not been cleared yet /* note: the invoke id has not been cleared yet
and this indicates a failed message: and this indicates a failed message:
IDLE and a valid invoke id */ IDLE and a valid invoke id */
TSM_List[i].state = TSM_STATE_IDLE; TSM_List[i].state = TSM_STATE_IDLE;
} }
} }
@@ -274,19 +274,18 @@ bool tsm_invoke_id_free(uint8_t invokeID)
/* see if the invoke ID has failed get a confirmation */ /* see if the invoke ID has failed get a confirmation */
bool tsm_invoke_id_failed(uint8_t invokeID) bool tsm_invoke_id_failed(uint8_t invokeID)
{ {
bool status = false; bool status = false;
uint8_t index; uint8_t index;
index = tsm_find_invokeID_index(invokeID); index = tsm_find_invokeID_index(invokeID);
if (index < MAX_TSM_TRANSACTIONS) if (index < MAX_TSM_TRANSACTIONS) {
{ /* a valid invoke ID and the state is IDLE is a
/* a valid invoke ID and the state is IDLE is a message that failed to confirm */
message that failed to confirm */ if (TSM_List[index].state == TSM_STATE_IDLE)
if (TSM_List[index].state == TSM_STATE_IDLE) status = true;
status = true; }
}
return status; return status;
} }
+1 -1
View File
@@ -110,7 +110,7 @@ extern "C" {
bool tsm_invoke_id_free(uint8_t invokeID); bool tsm_invoke_id_free(uint8_t invokeID);
bool tsm_invoke_id_failed(uint8_t invokeID); bool tsm_invoke_id_failed(uint8_t invokeID);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */