diff --git a/bacnet-stack/demo/server/main.c b/bacnet-stack/demo/server/main.c index a492646d..5f220684 100644 --- a/bacnet-stack/demo/server/main.c +++ b/bacnet-stack/demo/server/main.c @@ -109,11 +109,13 @@ int main(int argc, char *argv[]) bip_set_port(strtol(argv[3], NULL, 0)); #endif #if defined(BACDL_MSTP) + dlmstp_set_max_info_frames(1); + dlmstp_set_max_master(127); if (argc > 2) { Network_Interface = argv[2]; } if (argc > 3) { - dlmstp_set_mac_address(strtol(argv[1], NULL, 0)); + dlmstp_set_mac_address(strtol(argv[3], NULL, 0)); } #if 0 RS485_Set_Baud_Rate(38400); diff --git a/bacnet-stack/dlmstp.h b/bacnet-stack/dlmstp.h index 81bb4e52..d10abd44 100644 --- a/bacnet-stack/dlmstp.h +++ b/bacnet-stack/dlmstp.h @@ -99,12 +99,18 @@ extern "C" { void dlmstp_get_broadcast_address(BACNET_ADDRESS * dest); /* destination address */ /* MS/TP state machine functions */ - uint16_t dlmstp_put_receive(uint8_t src, /* source MS/TP address */ - uint8_t * pdu, /* PDU data */ + uint16_t dlmstp_put_receive( + uint8_t src, /* source MS/TP address */ + uint8_t * pdu, /* PDU data */ uint16_t pdu_len); - - + /* for the MS/TP state machine to use for getting data to send */ + /* Return: amount of PDU data */ + uint16_t dlmstp_get_send( + uint8_t src, /* source MS/TP address for creating packet */ + uint8_t * pdu, /* data to send */ + uint16_t max_pdu, /* amount of space available */ + unsigned timeout); /* milliseconds to wait for a packet */ #ifdef __cplusplus } diff --git a/bacnet-stack/ports/linux/dlmstp.c b/bacnet-stack/ports/linux/dlmstp.c index fb4db746..c68a4b7f 100644 --- a/bacnet-stack/ports/linux/dlmstp.c +++ b/bacnet-stack/ports/linux/dlmstp.c @@ -55,9 +55,6 @@ static int Receive_Client_SockFD = -1; static int Transmit_Client_SockFD = -1; static int Receive_Server_SockFD = -1; static int Transmit_Server_SockFD = -1; -/* receive buffer */ -static DLMSTP_PACKET Receive_Buffer; -/* temp buffer for NPDU insertion */ /* local MS/TP port data - shared with RS-485 */ volatile struct mstp_port_struct_t MSTP_Port; @@ -91,12 +88,6 @@ void dlmstp_reinit(void) dlmstp_set_max_master(DEFAULT_MAX_MASTER); } -void dlmstp_cleanup(void) -{ - RS485_Cleanup(); - /* nothing to do for static buffers */ -} - /* returns number of bytes sent on success, zero on failure */ int dlmstp_send_pdu(BACNET_ADDRESS * dest, /* destination address */ BACNET_NPDU_DATA * npdu_data, /* network information */ @@ -227,8 +218,11 @@ static void *dlmstp_fsm_master_task(void *pArg) for (;;) { nanosleep(&timeOut, &remains); - while (MSTP_Master_Node_FSM(&MSTP_Port)) { + /* 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)) { sched_yield(); + } } } @@ -265,7 +259,6 @@ uint16_t dlmstp_put_receive(uint8_t src, /* source MS/TP address */ { /* amount of PDU data */ DLMSTP_PACKET packet; - /* PDU is already in the Receive_Buffer */ if (pdu_len) { MSTP_Packets++; memmove(&packet.pdu[0], pdu, pdu_len); @@ -287,6 +280,7 @@ uint16_t dlmstp_get_send( unsigned timeout) /* milliseconds to wait for a packet */ { uint16_t pdu_len = 0; /* return value */ + int received_bytes = 0; DLMSTP_PACKET packet; struct timeval select_timeout; fd_set read_fds; @@ -337,8 +331,8 @@ uint16_t dlmstp_get_send( return 0; /* load destination MAC address */ - if (packet.address && packet.address.mac_len == 1) { - destination = dest->mac[0]; + if (packet.address.mac_len == 1) { + destination = packet.address.mac[0]; } else { return 0; } @@ -472,7 +466,9 @@ static int create_named_server_socket (const char *filename) /* Create the socket. */ sock = socket (PF_LOCAL, SOCK_DGRAM, 0); if (sock < 0) { +#if PRINT_ENABLED perror ("socket"); +#endif exit (EXIT_FAILURE); } setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &sock, sizeof(sock)); @@ -489,7 +485,9 @@ static int create_named_server_socket (const char *filename) size = (offsetof (struct sockaddr_un, sun_path) + strlen (name.sun_path) + 1); if (bind (sock, (struct sockaddr *) &name, size) < 0) { +#if PRINT_ENABLED perror ("bind"); +#endif exit (EXIT_FAILURE); } @@ -506,7 +504,9 @@ static int connect_named_server_socket (const char *filename) /* Create the socket. */ sock = socket (PF_LOCAL, SOCK_DGRAM, 0); if (sock < 0) { +#if PRINT_ENABLED perror ("socket"); +#endif exit (EXIT_FAILURE); } strncpy (name.sun_path, filename, sizeof (name.sun_path)); @@ -521,7 +521,9 @@ static int connect_named_server_socket (const char *filename) + strlen (name.sun_path) + 1); if (connect(sock, (struct sockaddr *) &name, size) < 0) { +#if PRINT_ENABLED perror ("client: can't connect to socket"); +#endif exit (EXIT_FAILURE); } @@ -531,13 +533,21 @@ static int connect_named_server_socket (const char *filename) static char *dlmstp_transmit_socket_name = "/tmp/BACnet_MSTP_Tx"; static char *dlmstp_receive_socket_name = "/tmp/BACnet_MSTP_Rx"; +void dlmstp_cleanup(void) +{ + remove(dlmstp_transmit_socket_name); + remove(dlmstp_receive_socket_name); + RS485_Cleanup(); + /* nothing to do for static buffers */ +} + bool dlmstp_init(char *ifname) { int rc = 0; pthread_t hThread; - struct sockaddr_un name; - size_t size; + remove(dlmstp_transmit_socket_name); + remove(dlmstp_receive_socket_name); /* create a socket for queuing the NDPU data between MS/TP */ Transmit_Server_SockFD = create_named_server_socket(dlmstp_transmit_socket_name); @@ -549,12 +559,13 @@ bool dlmstp_init(char *ifname) Receive_Client_SockFD = connect_named_server_socket(dlmstp_receive_socket_name); - /* initialize buffer */ - Receive_Buffer.ready = false; - Receive_Buffer.pdu_len = 0; /* initialize hardware */ - if (ifname) + if (ifname) { RS485_Set_Interface(ifname); +#if PRINT_ENABLED + fprintf(stderr,"MS/TP Interface: %s\n", ifname); +#endif + } RS485_Initialize(); MSTP_Init(&MSTP_Port); #if 0 @@ -572,6 +583,14 @@ bool dlmstp_init(char *ifname) else dlmstp_set_max_info_frames(DEFAULT_MAX_INFO_FRAMES); #endif +#if PRINT_ENABLED + fprintf(stderr,"MS/TP MAC: %02X\n", + MSTP_Port.This_Station); + fprintf(stderr,"MS/TP Max_Master: %02X\n", + MSTP_Port.Nmax_master); + fprintf(stderr,"MS/TP Max_Info_Frames: %u\n", + MSTP_Port.Nmax_info_frames); +#endif /* start our MilliSec task */ rc = pthread_create(&hThread, NULL, dlmstp_milliseconds_task, NULL); @@ -589,14 +608,15 @@ static char *Network_Interface = NULL; int main(int argc, char *argv[]) { - struct timespec timeOut,remains; uint16_t bytes_received = 0; BACNET_ADDRESS src; /* source address */ uint8_t pdu[MAX_APDU]; /* PDU data */ +#if (defined(MSTP_TEST_REQUEST) && MSTP_TEST_REQUEST) + struct timespec timeOut, remains; timeOut.tv_sec = 1; timeOut.tv_nsec = 0; /* 1 millisecond */ - +#endif /* argv has the "/dev/ttyS0" or some other device */ if (argc > 1) { Network_Interface = argv[1]; @@ -608,7 +628,7 @@ int main(int argc, char *argv[]) dlmstp_init(Network_Interface); /* forever task */ for (;;) { -#if 0 +#if (defined(MSTP_TEST_REQUEST) && MSTP_TEST_REQUEST) MSTP_Create_And_Send_Frame( &MSTP_Port, FRAME_TYPE_TEST_REQUEST, diff --git a/bacnet-stack/ports/linux/mstp.c b/bacnet-stack/ports/linux/mstp.c index 9e2ab31a..f5da3012 100644 --- a/bacnet-stack/ports/linux/mstp.c +++ b/bacnet-stack/ports/linux/mstp.c @@ -54,7 +54,8 @@ /* debug print statements */ #if PRINT_ENABLED #define PRINT_ENABLED_RECEIVE 0 -#define PRINT_ENABLED_RECEIVE_DATA 1 +#define PRINT_ENABLED_RECEIVE_DATA 0 +#define PRINT_ENABLED_RECEIVE_ERRORS 1 #define PRINT_ENABLED_MASTER 0 #else #define PRINT_ENABLED_RECEIVE 0 @@ -210,7 +211,7 @@ void MSTP_Create_And_Send_Frame(volatile struct mstp_port_struct_t *mstp_port, unsigned data_len) { /* number of bytes of data (up to 501) */ mstp_port->TxLength = (uint16_t) MSTP_Create_Frame( - &mstp_port->TxBuffer[0], /* where frame is loaded */ + (uint8_t *)&mstp_port->TxBuffer[0], /* where frame is loaded */ sizeof(mstp_port->TxBuffer), /* amount of space available */ frame_type, /* type of frame to send - see defines */ destination, /* destination address */ @@ -220,7 +221,7 @@ void MSTP_Create_And_Send_Frame(volatile struct mstp_port_struct_t *mstp_port, RS485_Send_Frame( mstp_port, - &mstp_port->TxBuffer[0], + (uint8_t *)&mstp_port->TxBuffer[0], mstp_port->TxLength); /* FIXME: be sure to reset SilenceTimer after each octet is sent! */ } @@ -457,7 +458,10 @@ void MSTP_Receive_Frame_FSM(volatile struct mstp_port_struct_t *mstp_port) /* indicate that an error has occurred during the reception of a frame */ mstp_port->ReceivedInvalidFrame = true; - fprintf(stderr,"MSTP: Rx Header: BadCRC\n"); +#if PRINT_ENABLED_RECEIVE_ERRORS + fprintf(stderr,"MSTP: Rx Header: BadCRC [%02X]\n", + mstp_port->DataRegister); +#endif /* wait for the start of the next frame. */ mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; } else { @@ -471,8 +475,10 @@ void MSTP_Receive_Frame_FSM(volatile struct mstp_port_struct_t *mstp_port) /* 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); + mstp_port->DataLength); +#endif /* wait for the start of the next frame. */ mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; @@ -509,8 +515,10 @@ void MSTP_Receive_Frame_FSM(volatile struct mstp_port_struct_t *mstp_port) /* 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 Data: BadIndex %d\n", - mstp_port->Index); + mstp_port->Index); +#endif /* wait for the start of a frame. */ mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; } @@ -526,8 +534,10 @@ void MSTP_Receive_Frame_FSM(volatile struct mstp_port_struct_t *mstp_port) if (mstp_port->SilenceTimer > Tframe_abort) { /* 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 Data: SilenceTimer %d > %d\n", - mstp_port->SilenceTimer, Tframe_abort); + mstp_port->SilenceTimer, Tframe_abort); +#endif /* wait for the start of the next frame. */ mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; } @@ -537,7 +547,9 @@ void MSTP_Receive_Frame_FSM(volatile struct mstp_port_struct_t *mstp_port) mstp_port->SilenceTimer = 0; /* 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 Data: ReceiveError\n"); +#endif /* wait for the start of the next frame. */ mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; } else if (mstp_port->DataAvailable == true) { @@ -572,7 +584,10 @@ void MSTP_Receive_Frame_FSM(volatile struct mstp_port_struct_t *mstp_port) mstp_port->ReceivedValidFrame = true; else { mstp_port->ReceivedInvalidFrame = true; - fprintf(stderr,"MSTP: Rx Data: BadCRC\n"); +#if PRINT_ENABLED_RECEIVE_ERRORS + fprintf(stderr,"MSTP: Rx Data: BadCRC [%02X]\n", + mstp_port->DataRegister); +#endif } mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; } @@ -821,9 +836,9 @@ bool MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t * mstp_port) case MSTP_MASTER_STATE_USE_TOKEN: mstp_port->TxLength = dlmstp_get_send( mstp_port->This_Station, - &mstp_port->TxBuffer[0], + (uint8_t *)&mstp_port->TxBuffer[0], sizeof(mstp_port->TxBuffer), - 5); /* milliseconds to wait for a packet */ + 0); /* milliseconds to wait for a packet */ if (mstp_port->TxLength < 1) { /* NothingToSend */ mstp_port->FrameCount = mstp_port->Nmax_info_frames; @@ -1176,9 +1191,9 @@ bool MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t * mstp_port) /* and enter the IDLE state to wait for the next frame. */ mstp_port->TxLength = dlmstp_get_send( mstp_port->This_Station, - &mstp_port->TxBuffer[0], + (uint8_t *)&mstp_port->TxBuffer[0], sizeof(mstp_port->TxBuffer), - 5); /* milliseconds to wait for a packet */ + 0); /* milliseconds to wait for a packet */ if ((mstp_port->FrameType == FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY) && (mstp_port->TxLength > 0)) {