Compiled MS/TP for server demo using sockets. Doesn't seem to keep up with token passing. Still investigating.

This commit is contained in:
skarg
2007-07-02 16:47:16 +00:00
parent 5435d46621
commit c1be9b7adf
4 changed files with 82 additions and 39 deletions
+3 -1
View File
@@ -109,11 +109,13 @@ int main(int argc, char *argv[])
bip_set_port(strtol(argv[3], NULL, 0)); bip_set_port(strtol(argv[3], NULL, 0));
#endif #endif
#if defined(BACDL_MSTP) #if defined(BACDL_MSTP)
dlmstp_set_max_info_frames(1);
dlmstp_set_max_master(127);
if (argc > 2) { if (argc > 2) {
Network_Interface = argv[2]; Network_Interface = argv[2];
} }
if (argc > 3) { if (argc > 3) {
dlmstp_set_mac_address(strtol(argv[1], NULL, 0)); dlmstp_set_mac_address(strtol(argv[3], NULL, 0));
} }
#if 0 #if 0
RS485_Set_Baud_Rate(38400); RS485_Set_Baud_Rate(38400);
+10 -4
View File
@@ -99,12 +99,18 @@ extern "C" {
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(uint8_t src, /* source MS/TP address */ uint16_t dlmstp_put_receive(
uint8_t * pdu, /* PDU data */ uint8_t src, /* source MS/TP address */
uint8_t * pdu, /* PDU data */
uint16_t pdu_len); 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 #ifdef __cplusplus
} }
+42 -22
View File
@@ -55,9 +55,6 @@ static int Receive_Client_SockFD = -1;
static int Transmit_Client_SockFD = -1; static int Transmit_Client_SockFD = -1;
static int Receive_Server_SockFD = -1; static int Receive_Server_SockFD = -1;
static int Transmit_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 */ /* local MS/TP port data - shared with RS-485 */
volatile struct mstp_port_struct_t MSTP_Port; volatile struct mstp_port_struct_t MSTP_Port;
@@ -91,12 +88,6 @@ void dlmstp_reinit(void)
dlmstp_set_max_master(DEFAULT_MAX_MASTER); 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 */ /* 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 */
@@ -227,8 +218,11 @@ static void *dlmstp_fsm_master_task(void *pArg)
for (;;) { for (;;) {
nanosleep(&timeOut, &remains); 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(); sched_yield();
}
} }
} }
@@ -265,7 +259,6 @@ uint16_t dlmstp_put_receive(uint8_t src, /* source MS/TP address */
{ /* amount of PDU data */ { /* amount of PDU data */
DLMSTP_PACKET packet; DLMSTP_PACKET packet;
/* PDU is already in the Receive_Buffer */
if (pdu_len) { if (pdu_len) {
MSTP_Packets++; MSTP_Packets++;
memmove(&packet.pdu[0], pdu, pdu_len); memmove(&packet.pdu[0], pdu, pdu_len);
@@ -287,6 +280,7 @@ uint16_t dlmstp_get_send(
unsigned timeout) /* milliseconds to wait for a packet */ unsigned timeout) /* milliseconds to wait for a packet */
{ {
uint16_t pdu_len = 0; /* return value */ uint16_t pdu_len = 0; /* return value */
int received_bytes = 0;
DLMSTP_PACKET packet; DLMSTP_PACKET packet;
struct timeval select_timeout; struct timeval select_timeout;
fd_set read_fds; fd_set read_fds;
@@ -337,8 +331,8 @@ uint16_t dlmstp_get_send(
return 0; return 0;
/* load destination MAC address */ /* load destination MAC address */
if (packet.address && packet.address.mac_len == 1) { if (packet.address.mac_len == 1) {
destination = dest->mac[0]; destination = packet.address.mac[0];
} else { } else {
return 0; return 0;
} }
@@ -472,7 +466,9 @@ static int create_named_server_socket (const char *filename)
/* Create the socket. */ /* Create the socket. */
sock = socket (PF_LOCAL, SOCK_DGRAM, 0); sock = socket (PF_LOCAL, SOCK_DGRAM, 0);
if (sock < 0) { if (sock < 0) {
#if PRINT_ENABLED
perror ("socket"); perror ("socket");
#endif
exit (EXIT_FAILURE); exit (EXIT_FAILURE);
} }
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &sock, sizeof(sock)); 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) size = (offsetof (struct sockaddr_un, sun_path)
+ strlen (name.sun_path) + 1); + strlen (name.sun_path) + 1);
if (bind (sock, (struct sockaddr *) &name, size) < 0) { if (bind (sock, (struct sockaddr *) &name, size) < 0) {
#if PRINT_ENABLED
perror ("bind"); perror ("bind");
#endif
exit (EXIT_FAILURE); exit (EXIT_FAILURE);
} }
@@ -506,7 +504,9 @@ static int connect_named_server_socket (const char *filename)
/* Create the socket. */ /* Create the socket. */
sock = socket (PF_LOCAL, SOCK_DGRAM, 0); sock = socket (PF_LOCAL, SOCK_DGRAM, 0);
if (sock < 0) { if (sock < 0) {
#if PRINT_ENABLED
perror ("socket"); perror ("socket");
#endif
exit (EXIT_FAILURE); exit (EXIT_FAILURE);
} }
strncpy (name.sun_path, filename, sizeof (name.sun_path)); 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); + strlen (name.sun_path) + 1);
if (connect(sock, (struct sockaddr *) &name, size) < 0) { if (connect(sock, (struct sockaddr *) &name, size) < 0) {
#if PRINT_ENABLED
perror ("client: can't connect to socket"); perror ("client: can't connect to socket");
#endif
exit (EXIT_FAILURE); 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_transmit_socket_name = "/tmp/BACnet_MSTP_Tx";
static char *dlmstp_receive_socket_name = "/tmp/BACnet_MSTP_Rx"; 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) bool dlmstp_init(char *ifname)
{ {
int rc = 0; int rc = 0;
pthread_t hThread; 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 */ /* create a socket for queuing the NDPU data between MS/TP */
Transmit_Server_SockFD = Transmit_Server_SockFD =
create_named_server_socket(dlmstp_transmit_socket_name); create_named_server_socket(dlmstp_transmit_socket_name);
@@ -549,12 +559,13 @@ bool dlmstp_init(char *ifname)
Receive_Client_SockFD = Receive_Client_SockFD =
connect_named_server_socket(dlmstp_receive_socket_name); connect_named_server_socket(dlmstp_receive_socket_name);
/* initialize buffer */
Receive_Buffer.ready = false;
Receive_Buffer.pdu_len = 0;
/* initialize hardware */ /* initialize hardware */
if (ifname) if (ifname) {
RS485_Set_Interface(ifname); RS485_Set_Interface(ifname);
#if PRINT_ENABLED
fprintf(stderr,"MS/TP Interface: %s\n", ifname);
#endif
}
RS485_Initialize(); RS485_Initialize();
MSTP_Init(&MSTP_Port); MSTP_Init(&MSTP_Port);
#if 0 #if 0
@@ -572,6 +583,14 @@ bool dlmstp_init(char *ifname)
else else
dlmstp_set_max_info_frames(DEFAULT_MAX_INFO_FRAMES); dlmstp_set_max_info_frames(DEFAULT_MAX_INFO_FRAMES);
#endif #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 */ /* start our MilliSec task */
rc = pthread_create(&hThread, NULL, dlmstp_milliseconds_task, NULL); rc = pthread_create(&hThread, NULL, dlmstp_milliseconds_task, NULL);
@@ -589,14 +608,15 @@ static char *Network_Interface = NULL;
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
struct timespec timeOut,remains;
uint16_t bytes_received = 0; uint16_t bytes_received = 0;
BACNET_ADDRESS src; /* source address */ BACNET_ADDRESS src; /* source address */
uint8_t pdu[MAX_APDU]; /* PDU data */ 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_sec = 1;
timeOut.tv_nsec = 0; /* 1 millisecond */ timeOut.tv_nsec = 0; /* 1 millisecond */
#endif
/* argv has the "/dev/ttyS0" or some other device */ /* argv has the "/dev/ttyS0" or some other device */
if (argc > 1) { if (argc > 1) {
Network_Interface = argv[1]; Network_Interface = argv[1];
@@ -608,7 +628,7 @@ int main(int argc, char *argv[])
dlmstp_init(Network_Interface); dlmstp_init(Network_Interface);
/* forever task */ /* forever task */
for (;;) { for (;;) {
#if 0 #if (defined(MSTP_TEST_REQUEST) && MSTP_TEST_REQUEST)
MSTP_Create_And_Send_Frame( MSTP_Create_And_Send_Frame(
&MSTP_Port, &MSTP_Port,
FRAME_TYPE_TEST_REQUEST, FRAME_TYPE_TEST_REQUEST,
+27 -12
View File
@@ -54,7 +54,8 @@
/* debug print statements */ /* debug print statements */
#if PRINT_ENABLED #if PRINT_ENABLED
#define PRINT_ENABLED_RECEIVE 0 #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 #define PRINT_ENABLED_MASTER 0
#else #else
#define PRINT_ENABLED_RECEIVE 0 #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) unsigned data_len)
{ /* number of bytes of data (up to 501) */ { /* number of bytes of data (up to 501) */
mstp_port->TxLength = (uint16_t) MSTP_Create_Frame( 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 */ sizeof(mstp_port->TxBuffer), /* 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 */
@@ -220,7 +221,7 @@ void MSTP_Create_And_Send_Frame(volatile struct mstp_port_struct_t *mstp_port,
RS485_Send_Frame( RS485_Send_Frame(
mstp_port, mstp_port,
&mstp_port->TxBuffer[0], (uint8_t *)&mstp_port->TxBuffer[0],
mstp_port->TxLength); mstp_port->TxLength);
/* FIXME: be sure to reset SilenceTimer after each octet is sent! */ /* 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 /* indicate that an error has occurred during
the reception of a frame */ the reception of a frame */
mstp_port->ReceivedInvalidFrame = true; 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. */ /* wait for the start of the next frame. */
mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE;
} else { } 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 */ /* indicate that a frame with an illegal or */
/* unacceptable data length has been received */ /* unacceptable data length has been received */
mstp_port->ReceivedInvalidFrame = true; mstp_port->ReceivedInvalidFrame = true;
#if PRINT_ENABLED_RECEIVE_ERRORS
fprintf(stderr,"MSTP: Rx Header: FrameTooLong %d\n", fprintf(stderr,"MSTP: Rx Header: FrameTooLong %d\n",
mstp_port->DataLength); mstp_port->DataLength);
#endif
/* wait for the start of the next frame. */ /* wait for the start of the next frame. */
mstp_port->receive_state = mstp_port->receive_state =
MSTP_RECEIVE_STATE_IDLE; 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 */ /* indicate that an error has occurred during */
/* the reception of a frame */ /* the reception of a frame */
mstp_port->ReceivedInvalidFrame = true; mstp_port->ReceivedInvalidFrame = true;
#if PRINT_ENABLED_RECEIVE_ERRORS
fprintf(stderr,"MSTP: Rx Data: BadIndex %d\n", fprintf(stderr,"MSTP: Rx Data: BadIndex %d\n",
mstp_port->Index); mstp_port->Index);
#endif
/* wait for the start of a frame. */ /* wait for the start of a frame. */
mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; 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) { if (mstp_port->SilenceTimer > Tframe_abort) {
/* indicate that an error has occurred during the reception of a frame */ /* indicate that an error has occurred during the reception of a frame */
mstp_port->ReceivedInvalidFrame = true; mstp_port->ReceivedInvalidFrame = true;
#if PRINT_ENABLED_RECEIVE_ERRORS
fprintf(stderr,"MSTP: Rx Data: SilenceTimer %d > %d\n", 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. */ /* wait for the start of the next frame. */
mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; 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; mstp_port->SilenceTimer = 0;
/* indicate that an error has occurred during the reception of a frame */ /* indicate that an error has occurred during the reception of a frame */
mstp_port->ReceivedInvalidFrame = true; mstp_port->ReceivedInvalidFrame = true;
#if PRINT_ENABLED_RECEIVE_ERRORS
fprintf(stderr,"MSTP: Rx Data: ReceiveError\n"); fprintf(stderr,"MSTP: Rx Data: ReceiveError\n");
#endif
/* wait for the start of the next frame. */ /* wait for the start of the next frame. */
mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE;
} else if (mstp_port->DataAvailable == true) { } 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; mstp_port->ReceivedValidFrame = true;
else { else {
mstp_port->ReceivedInvalidFrame = true; 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; 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: case MSTP_MASTER_STATE_USE_TOKEN:
mstp_port->TxLength = dlmstp_get_send( mstp_port->TxLength = dlmstp_get_send(
mstp_port->This_Station, mstp_port->This_Station,
&mstp_port->TxBuffer[0], (uint8_t *)&mstp_port->TxBuffer[0],
sizeof(mstp_port->TxBuffer), sizeof(mstp_port->TxBuffer),
5); /* milliseconds to wait for a packet */ 0); /* milliseconds to wait for a packet */
if (mstp_port->TxLength < 1) { if (mstp_port->TxLength < 1) {
/* NothingToSend */ /* NothingToSend */
mstp_port->FrameCount = mstp_port->Nmax_info_frames; 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. */ /* and enter the IDLE state to wait for the next frame. */
mstp_port->TxLength = dlmstp_get_send( mstp_port->TxLength = dlmstp_get_send(
mstp_port->This_Station, mstp_port->This_Station,
&mstp_port->TxBuffer[0], (uint8_t *)&mstp_port->TxBuffer[0],
sizeof(mstp_port->TxBuffer), sizeof(mstp_port->TxBuffer),
5); /* milliseconds to wait for a packet */ 0); /* milliseconds to wait for a packet */
if ((mstp_port->FrameType == if ((mstp_port->FrameType ==
FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY) FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY)
&& (mstp_port->TxLength > 0)) { && (mstp_port->TxLength > 0)) {