Compiled MS/TP for server demo using sockets. Doesn't seem to keep up with token passing. Still investigating.
This commit is contained in:
@@ -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);
|
||||
|
||||
+10
-4
@@ -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
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
Reference in New Issue
Block a user