diff --git a/server/include/msg.h b/server/include/msg.h index 73fd3b6bc..d76f9118d 100644 --- a/server/include/msg.h +++ b/server/include/msg.h @@ -14,6 +14,19 @@ struct node; +/** Swap a message to host 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. + * 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. + * + * @param m A pointer to the message + */ +void msg_swap(struct msg *m); + /** Print a raw UDP message in human readable form. * * @param f The file stream diff --git a/server/src/msg.c b/server/src/msg.c index 944240b66..5f8941bc9 100644 --- a/server/src/msg.c +++ b/server/src/msg.c @@ -7,18 +7,35 @@ #include #include #include +#include #include #include "msg.h" #include "node.h" #include "utils.h" -int msg_fprint(FILE *f, struct msg *msg) +void msg_swap(struct msg *m) { - fprintf(f, "%-8hu", msg->sequence); + uint32_t *data = (uint32_t *) m->data; - for (int i = 0; i < msg->length; i++) - fprintf(f, "%-12.6f ", msg->data[i]); + /* Swap sequence number */ + m->sequence = bswap_16(m->sequence); + + /* Swap data */ + for (int i = 0; i < m->length; i++) + data[i] = bswap_32(data[i]); + + m->endian ^= 1; +} + +int msg_fprint(FILE *f, struct msg *m) +{ + assert(m->endian == MSG_ENDIAN_HOST); + + fprintf(f, "%-8hu", m->sequence); + + for (int i = 0; i < m->length; i++) + fprintf(f, "%-12.6f ", m->data[i].f); fprintf(f, "\n"); @@ -30,25 +47,32 @@ int msg_fscan(FILE *f, struct msg *m) fscanf(f, "%8hu ", &m->sequence); for (int i = 0; i < m->length; i++) - fscanf(f, "%12f ", &m->data[i]); + fscanf(f, "%12f ", &m->data[i].f); fscanf(f, "\n"); + + m->endian = MSG_ENDIAN_HOST; + return 0; } void msg_random(struct msg *m) { + assert(m->endian == MSG_ENDIAN_HOST); + for (int i = 0; i < m->length; i++) - m->data[i] += (float) random() / RAND_MAX - .5; + m->data[i].f += (float) random() / RAND_MAX - .5; m->sequence++; } int msg_send(struct msg *m, struct node *n) { + /* We dont care about the endianess of outgoing messages */ + if (sendto(n->sd, m, (m->length+1) * 4, 0, - (struct sockaddr *) &n->remote, - sizeof(struct sockaddr_in)) < 0) + (struct sockaddr *) &n->remote, + sizeof(struct sockaddr_in)) < 0) perror("Failed sendto"); debug(10, "Message sent to node '%s'", n->name); @@ -59,9 +83,16 @@ int msg_send(struct msg *m, struct node *n) int msg_recv(struct msg *m, struct node *n) { + /** @todo Fix this for multiple paths calling msg_recv. */ + + /* Receive message from socket */ if (recv(n->sd, m, sizeof(struct msg), 0) < 0) perror("Failed recv"); + /* Convert message to host endianess */ + if (m->endian != MSG_ENDIAN_HOST) + msg_swap(m); + debug(10, "Message received from node '%s'", n->name); if (V >= 10) msg_fprint(stdout, m);