From c640a6ba2141b773c361910b415c9a8bac4b7445 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Thu, 8 Oct 2015 10:51:48 +0200 Subject: [PATCH] Changed UDP message format: sequence no, length and timestamps are also affected by struct msg::endian!!! Important: this will break the current GTFPGA code --- .../opal/udp/models/send_receive/include/msg.h | 4 ++-- .../models/send_receive/include/msg_format.h | 12 +++++------- clients/opal/udp/models/send_receive/src/msg.c | 15 ++++++++++----- clients/opal/udp/models/send_receive/src/s2ss.c | 17 +++++++---------- server/include/msg.h | 4 ++-- server/include/msg_format.h | 12 +++++------- server/src/msg.c | 9 +++++++-- server/src/socket.c | 13 +++---------- 8 files changed, 41 insertions(+), 45 deletions(-) diff --git a/clients/opal/udp/models/send_receive/include/msg.h b/clients/opal/udp/models/send_receive/include/msg.h index 70d5ae4b7..efbf9552b 100644 --- a/clients/opal/udp/models/send_receive/include/msg.h +++ b/clients/opal/udp/models/send_receive/include/msg.h @@ -12,11 +12,11 @@ #include "msg_format.h" -/** Swap a message to host byte order. +/** Swaps message contents byte-order. * * Message can either be transmitted in little or big endian * format. The actual endianess for a message is defined by the - * msg::byteorder field. + * msg::endian field. This covers msg::length, msg::sequence, msg::data and msg::ts fields. * Received message are usally converted to the endianess of the host. * This is required for further sanity checks of the sequence number * or parsing of the data. diff --git a/clients/opal/udp/models/send_receive/include/msg_format.h b/clients/opal/udp/models/send_receive/include/msg_format.h index d7b41d6cc..a85bbea5c 100644 --- a/clients/opal/udp/models/send_receive/include/msg_format.h +++ b/clients/opal/udp/models/send_receive/include/msg_format.h @@ -80,18 +80,16 @@ struct msg #endif unsigned rsvd2 : 8; /**< Reserved bits */ - /** The number of values in msg::data[] */ - uint16_t length; - - uint32_t sequence; /**< The sequence number is incremented by one for consecutive messages */ + uint16_t length; /**< The number of values in msg::data[]. Endianess is specified in msg::endian. */ + uint32_t sequence; /**< The sequence number is incremented by one for consecutive messages. Endianess is specified in msg::endian. */ - /** A timestamp per message */ + /** A timestamp per message. Endianess is specified in msg::endian. */ struct { uint32_t sec; /**< Seconds since 1970-01-01 00:00:00 */ - uint32_t nsec; /**< Nanoseconds since 1970-01-01 00:00:00 */ + uint32_t nsec; /**< Nanoseconds of the current second. */ } ts; - /** The message payload */ + /** The message payload. Endianess is specified in msg::endian. */ union { float f; /**< Floating point values (note msg::endian) */ uint32_t i; /**< Integer values (note msg::endian) */ diff --git a/clients/opal/udp/models/send_receive/src/msg.c b/clients/opal/udp/models/send_receive/src/msg.c index 00c519328..911133c72 100644 --- a/clients/opal/udp/models/send_receive/src/msg.c +++ b/clients/opal/udp/models/send_receive/src/msg.c @@ -7,18 +7,23 @@ *********************************************************************************/ #ifdef __linux__ - #include + #include #elif defined(__PPC__) /* Xilinx toolchain */ - #include - #define bswap_32(x) Xil_EndianSwap32(x) + #include + #define bswap_16(x) Xil_EndianSwap16(x) + #define bswap_32(x) Xil_EndianSwap32(x) #endif #include "msg.h" void msg_swap(struct msg *m) { - int i; - for (i = 0; i < m->length; i++) + m->length = bswap_16(m->length); + m->sequence = bswap_32(m->sequence); + m->ts.sec = bswap_32(m->ts.sec); + m->ts.nsec = bswap_32(m->ts.nsec); + + for (int i = 0; i < m->length; i++) m->data[i].i = bswap_32(m->data[i].i); m->endian ^= 1; diff --git a/clients/opal/udp/models/send_receive/src/s2ss.c b/clients/opal/udp/models/send_receive/src/s2ss.c index 9beef8095..4ac32161a 100644 --- a/clients/opal/udp/models/send_receive/src/s2ss.c +++ b/clients/opal/udp/models/send_receive/src/s2ss.c @@ -69,7 +69,7 @@ void Tick(int sig, siginfo_t *si, void *ptr) OpalGetAsyncModelTime(IconCtrlStruct, &CpuTime, &ModelTime); OpalPrint("%s: CpuTime: %llu\tModelTime: %.3f\tSequence: %hu\tValue: %.2f\n", - PROGNAME, (CpuTime - CpuTimeStart) / CPU_TICKS, ModelTime, ntohs(msg_send->sequence), msg_send->data[0].f); + PROGNAME, (CpuTime - CpuTimeStart) / CPU_TICKS, ModelTime, msg_send->sequence, msg_send->data[0].f); } #endif /* _DEBUG */ @@ -131,8 +131,8 @@ static void *SendToIPPort(void *arg) msg.data[i].f = (float) mdldata[i]; /* Convert to network byte order */ - msg.sequence = htonl(seq++); - msg.length = htons(msg.length); + msg.sequence = seq++; + msg.length = msg.length; /* Perform the actual write to the ip port */ if (SendPacket((char *) &msg, MSG_LEN(&msg)) < 0) @@ -206,18 +206,15 @@ static void *RecvFromIPPort(void *arg) OpalPrint("%s: Received no data. Skipping..\n", PROGNAME); continue; } - - /* Convert to host byte order */ - msg.sequence = ntohl(msg.sequence); - msg.length = ntohs(msg.length); + + /* Convert message to host endianess */ + if (msg.endian != MSG_ENDIAN_HOST) + msg_swap(&msg); if (n != MSG_LEN(&msg)) { OpalPrint("%s: Received incoherent packet (size: %d, complete: %d)\n", PROGNAME, n, MSG_LEN(&msg)); continue; } - - if (msg.endian != MSG_ENDIAN_HOST) - msg_swap(&msg); /* Update OPAL model */ OpalSetAsyncRecvIconStatus(msg.sequence, RecvID); /* Set the Status to the message ID */ diff --git a/server/include/msg.h b/server/include/msg.h index 0bb043c81..afce6df70 100644 --- a/server/include/msg.h +++ b/server/include/msg.h @@ -26,11 +26,11 @@ enum msg_flags { MSG_PRINT_ALL = 0xFF }; -/** Swap a message to host byte order. +/** Swaps message contents byte-order. * * Message can either be transmitted in little or big endian * format. The actual endianess for a message is defined by the - * msg::byteorder field. + * msg::endian field. This covers msg::length, msg::sequence, msg::data and msg::ts fields. * Received message are usally converted to the endianess of the host. * This is required for further sanity checks of the sequence number * or parsing of the data. diff --git a/server/include/msg_format.h b/server/include/msg_format.h index eb680a57e..dfda52201 100644 --- a/server/include/msg_format.h +++ b/server/include/msg_format.h @@ -81,18 +81,16 @@ struct msg #endif unsigned rsvd2 : 8; /**< Reserved bits */ - /** The number of values in msg::data[] */ - uint16_t length; - - uint32_t sequence; /**< The sequence number is incremented by one for consecutive messages */ + uint16_t length; /**< The number of values in msg::data[]. Endianess is specified in msg::endian. */ + uint32_t sequence; /**< The sequence number is incremented by one for consecutive messages. Endianess is specified in msg::endian. */ - /** A timestamp per message */ + /** A timestamp per message. Endianess is specified in msg::endian. */ struct { uint32_t sec; /**< Seconds since 1970-01-01 00:00:00 */ - uint32_t nsec; /**< Nanoseconds since 1970-01-01 00:00:00 */ + uint32_t nsec; /**< Nanoseconds of the current second. */ } ts; - /** The message payload */ + /** The message payload. Endianess is specified in msg::endian. */ union { float f; /**< Floating point values (note msg::endian) */ uint32_t i; /**< Integer values (note msg::endian) */ diff --git a/server/src/msg.c b/server/src/msg.c index 20cf4639e..cd9e7ea04 100644 --- a/server/src/msg.c +++ b/server/src/msg.c @@ -14,6 +14,7 @@ #include #elif defined(__PPC__) /* Xilinx toolchain */ #include + #define bswap_16(x) Xil_EndianSwap16(x) #define bswap_32(x) Xil_EndianSwap32(x) #endif @@ -23,8 +24,12 @@ void msg_swap(struct msg *m) { - int i; - for (i = 0; i < m->length; i++) + m->length = bswap_16(m->length); + m->sequence = bswap_32(m->sequence); + m->ts.sec = bswap_32(m->ts.sec); + m->ts.nsec = bswap_32(m->ts.nsec); + + for (int i = 0; i < m->length; i++) m->data[i].i = bswap_32(m->data[i].i); m->endian ^= 1; diff --git a/server/src/socket.c b/server/src/socket.c index 437e13f60..4629efa93 100644 --- a/server/src/socket.c +++ b/server/src/socket.c @@ -210,19 +210,15 @@ int socket_read(struct node *n, struct msg *pool, int poolsize, int first, int c for (int i = 0; i < cnt; i++) { struct msg *m = &pool[(first+poolsize+i) % poolsize]; - /* Convert headers to host byte order */ - m->sequence = ntohl(m->sequence); - m->length = ntohs(m->length); + /* Convert message to host endianess */ + if (m->endian != MSG_ENDIAN_HOST) + msg_swap(m); /* Check integrity of packet */ if (bytes / cnt != MSG_LEN(m)) error("Invalid message len: %u for node '%s'", MSG_LEN(m), n->name); bytes -= MSG_LEN(m); - - /* Convert message to host endianess */ - if (m->endian != MSG_ENDIAN_HOST) - msg_swap(m); } /* Check packet integrity */ @@ -246,9 +242,6 @@ int socket_write(struct node *n, struct msg *pool, int poolsize, int first, int if (m->type == MSG_TYPE_EMPTY) continue; - /* Convert headers to network byte order */ - n->sequence = htons(n->sequence); - iov[sent].iov_base = m; iov[sent].iov_len = MSG_LEN(m);