mirror of
https://git.rwth-aachen.de/acs/public/villas/node/
synced 2025-03-09 00:00:00 +01:00
fixed some byte ordering issues with OPAL
replaced custom htonf/ntohf() functions by existing msg_swap() git-svn-id: https://zerberus.eonerc.rwth-aachen.de:8443/svn/s2ss/trunk@179 8ec27952-4edc-4aab-86aa-e87bb2611832
This commit is contained in:
parent
fd550e49c2
commit
b171dfa3e0
9 changed files with 75 additions and 54 deletions
|
@ -11,4 +11,6 @@
|
|||
#define PROGNAME "S2SS"
|
||||
#define VERSION "0.1"
|
||||
|
||||
#define MAX_VALUES 16
|
||||
|
||||
#endif /* _CONFIG_H_ */
|
||||
|
|
15
clients/opal/models/send_receive/include/msg.h
Normal file
15
clients/opal/models/send_receive/include/msg.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
/** Message related functions.
|
||||
*
|
||||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2014, Institute for Automation of Complex Power Systems, EONERC
|
||||
*/
|
||||
|
||||
#ifndef _MSG_H_
|
||||
#define _MSG_H_
|
||||
|
||||
#include "msg_format.h"
|
||||
|
||||
void msg_swap(struct msg *m);
|
||||
|
||||
#endif /* _MSG_H_ */
|
||||
|
|
@ -15,8 +15,10 @@
|
|||
#include <endian.h>
|
||||
#endif
|
||||
|
||||
#include "config.h"
|
||||
|
||||
/** Maximum number of dword values in a message */
|
||||
#define MSG_VALUES 16
|
||||
#define MSG_VALUES MAX_VALUES
|
||||
|
||||
/** The current version number for the message format */
|
||||
#define MSG_VERSION 0
|
||||
|
@ -56,16 +58,17 @@ struct msg
|
|||
unsigned version: 4; /**< Specifies the format of the remaining message (see MGS_VERSION) */
|
||||
unsigned type : 2; /**< Data or control message (see MSG_TYPE_*) */
|
||||
unsigned endian : 1; /**< Specifies the byteorder of the message (see MSG_ENDIAN_*) */
|
||||
unsigned : 1; /**< Reserved padding bits */
|
||||
unsigned : 1; /**< Reserved padding bits */
|
||||
|
||||
/** Number of valid dword values in msg::data[] */
|
||||
uint8_t length;
|
||||
/** The sequence number gets incremented by one for consecutive messages */
|
||||
uint16_t sequence;
|
||||
|
||||
/** The message payload */
|
||||
union {
|
||||
float f;
|
||||
uint32_t i;
|
||||
float f; /**< Floating point values (note msg::endian) */
|
||||
uint32_t i; /**< Integer values (note msg::endian) */
|
||||
} data[MSG_VALUES];
|
||||
} __attribute__((packed));
|
||||
|
||||
|
|
|
@ -40,11 +40,13 @@ INTERNAL_LIBRARY3=-lOpalAsyncApiCore
|
|||
s2ss.mk=Ascii
|
||||
include\config.h=Ascii
|
||||
include\interface.h=Ascii
|
||||
include\msg.h=Ascii
|
||||
include\msg_format.h=Ascii
|
||||
include\sched.h=Ascii
|
||||
include\socket.h=Ascii
|
||||
src\s2ss.c=Ascii
|
||||
src\interface.c=Ascii
|
||||
src\msg.c=Ascii
|
||||
src\sched.c=Ascii
|
||||
src\socket.c=Ascii
|
||||
[ExtraPutFilesComp_1_RT_LAB]
|
||||
|
|
22
clients/opal/models/send_receive/src/msg.c
Normal file
22
clients/opal/models/send_receive/src/msg.c
Normal file
|
@ -0,0 +1,22 @@
|
|||
/** Message related functions.
|
||||
*
|
||||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2014, Institute for Automation of Complex Power Systems, EONERC
|
||||
*/
|
||||
|
||||
#include <byteswap.h>
|
||||
|
||||
#include "msg.h"
|
||||
|
||||
void msg_swap(struct msg *m)
|
||||
{
|
||||
uint32_t *data = (uint32_t *) m->data;
|
||||
|
||||
|
||||
/* Swap data */
|
||||
for (int i = 0; i < m->length; i++)
|
||||
data[i] = bswap_32(data[i]);
|
||||
|
||||
m->endian ^= 1;
|
||||
}
|
||||
|
|
@ -39,7 +39,7 @@
|
|||
|
||||
/* This is the message format */
|
||||
#include "config.h"
|
||||
#include "msg_format.h"
|
||||
#include "msg.h"
|
||||
#include "socket.h"
|
||||
#include "interface.h"
|
||||
|
||||
|
@ -51,10 +51,11 @@
|
|||
|
||||
static void *SendToIPPort(void *arg)
|
||||
{
|
||||
unsigned SendID = 1;
|
||||
unsigned i, n;
|
||||
unsigned int SendID = 1;
|
||||
unsigned int ModelState;
|
||||
unsigned int i, n;
|
||||
unsigned short seq = 0;
|
||||
int nbSend = 0;
|
||||
unsigned ModelState;
|
||||
|
||||
/* Data from OPAL-RT model */
|
||||
double mdldata[MSG_VALUES];
|
||||
|
@ -97,13 +98,13 @@ static void *SendToIPPort(void *arg)
|
|||
|
||||
/******* FORMAT TO SPECIFIC PROTOCOL HERE *****************************/
|
||||
// msg.dev_id = SendID; /* Use the SendID as a device ID here */
|
||||
msg.sequence++;
|
||||
msg.sequence = htons(seq++);
|
||||
msg.length = mdldata_size / sizeof(double);
|
||||
|
||||
for (i = 0; i < msg.length; i++)
|
||||
msg.data[i] = htonf((float) mdldata[i]);
|
||||
msg.data[i] = (float) mdldata[i].f;
|
||||
|
||||
msg_size = 4 * (msg.length + 1);
|
||||
msg_size = MSG_LEN(msg.length);
|
||||
/**********************************************************************/
|
||||
|
||||
/* Perform the actual write to the ip port */
|
||||
|
@ -159,6 +160,8 @@ static void *RecvFromIPPort(void *arg)
|
|||
msg_size = sizeof(msg);
|
||||
n = RecvPacket((char *) &msg, msg_size, 1.0);
|
||||
|
||||
/** @todo: Check and ntohs() sequence number! */
|
||||
|
||||
if (msg.version != MSG_VERSION) {
|
||||
OpalPrint("%s: Received message with unknown version. Skipping..\n", PROGNAME);
|
||||
continue;
|
||||
|
@ -169,7 +172,7 @@ static void *RecvFromIPPort(void *arg)
|
|||
continue;
|
||||
}
|
||||
|
||||
msg_size = 4 * (msg.length + 1);
|
||||
msg_size = MSG_LEN(msg.length);
|
||||
/***********************************************************************/
|
||||
|
||||
if (n < 1) {
|
||||
|
@ -208,8 +211,11 @@ static void *RecvFromIPPort(void *arg)
|
|||
PROGNAME, RecvID, mdldata_size / sizeof(double), msg.length);
|
||||
}
|
||||
|
||||
if (msg.endian != MSG_ENDIAN_HOST)
|
||||
msg_swap(&msg);
|
||||
|
||||
for (i = 0; i < msg.length; i++)
|
||||
mdldata[i] = (double) ntohf(msg.data[i]);
|
||||
mdldata[i] = (double) msg.data[i].f;
|
||||
/************************************************************************/
|
||||
|
||||
OpalSetAsyncRecvIconData(mdldata, mdldata_size, RecvID);
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
#include "utils.h"
|
||||
|
||||
static union fi {
|
||||
float f;
|
||||
uint32_t i;
|
||||
};
|
||||
|
||||
inline float ntohf(float flt)
|
||||
{
|
||||
union fi u = { .f = flt };
|
||||
|
||||
u.i = ntohl(u.i);
|
||||
|
||||
return u.f;
|
||||
}
|
||||
|
||||
inline float htonf(float flt)
|
||||
{
|
||||
union u = { .f = flt };
|
||||
|
||||
u.i = htonl(u.i);
|
||||
|
||||
return u.f;
|
||||
}
|
|
@ -38,7 +38,7 @@
|
|||
#endif
|
||||
|
||||
/** The total length of a message */
|
||||
#define MSG_LEN(values) (4 * (values + 1))
|
||||
#define MSG_LEN(values) (4 * (values + 1))
|
||||
|
||||
/** Initialize a message */
|
||||
#define MSG_INIT(i) { \
|
||||
|
@ -55,17 +55,11 @@
|
|||
**/
|
||||
struct msg
|
||||
{
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
unsigned version: 4; /**< Specifies the format of the remaining message (see MGS_VERSION) */
|
||||
unsigned type : 2; /**< Data or control message (see MSG_TYPE_*) */
|
||||
unsigned endian : 1; /**< Specifies the byteorder of the message (see MSG_ENDIAN_*) */
|
||||
unsigned : 1; /**< Reserved padding bits */
|
||||
#else
|
||||
unsigned : 1; /**< Reserved padding bits */
|
||||
unsigned endian : 1; /**< Specifies the byteorder of the message (see MSG_ENDIAN_*) */
|
||||
unsigned type : 2; /**< Data or control message (see MSG_TYPE_*) */
|
||||
unsigned version: 4; /**< Specifies the format of the remaining message (see MGS_VERSION) */
|
||||
#endif
|
||||
unsigned : 1; /**< Reserved padding bits */
|
||||
|
||||
/** Number of valid dword values in msg::data[] */
|
||||
uint8_t length;
|
||||
/** The sequence number gets incremented by one for consecutive messages */
|
||||
|
@ -73,8 +67,8 @@ struct msg
|
|||
|
||||
/** The message payload */
|
||||
union {
|
||||
float f;
|
||||
uint32_t i;
|
||||
float f; /**< Floating point values (note msg::endian) */
|
||||
uint32_t i; /**< Integer values (note msg::endian) */
|
||||
} data[MSG_VALUES];
|
||||
} __attribute__((packed));
|
||||
|
||||
|
|
|
@ -18,8 +18,6 @@ void msg_swap(struct msg *m)
|
|||
{
|
||||
uint32_t *data = (uint32_t *) m->data;
|
||||
|
||||
/* Swap sequence number */
|
||||
m->sequence = bswap_16(m->sequence);
|
||||
|
||||
/* Swap data */
|
||||
for (int i = 0; i < m->length; i++)
|
||||
|
@ -58,19 +56,19 @@ int msg_fscan(FILE *f, struct msg *m)
|
|||
|
||||
void msg_random(struct msg *m)
|
||||
{
|
||||
assert(m->endian == MSG_ENDIAN_HOST);
|
||||
|
||||
for (int i = 0; i < m->length; i++)
|
||||
m->data[i].f += (float) random() / RAND_MAX - .5;
|
||||
|
||||
m->endian = MSG_ENDIAN_HOST;
|
||||
m->sequence++;
|
||||
}
|
||||
|
||||
int msg_send(struct msg *m, struct node *n)
|
||||
{
|
||||
/* We dont care about the endianess of outgoing messages */
|
||||
/* Convert headers to network byte order */
|
||||
m->sequence = ntohs(m->sequence);
|
||||
|
||||
if (sendto(n->sd, m, (m->length+1) * 4, 0,
|
||||
if (sendto(n->sd, m, MSG_LEN(m->length), 0,
|
||||
(struct sockaddr *) &n->remote,
|
||||
sizeof(struct sockaddr_in)) < 0)
|
||||
perror("Failed sendto");
|
||||
|
@ -88,6 +86,9 @@ int msg_recv(struct msg *m, struct node *n)
|
|||
if (recv(n->sd, m, sizeof(struct msg), 0) < 0)
|
||||
perror("Failed recv");
|
||||
|
||||
/* Convert headers to host byte order */
|
||||
m->sequence = htons(m->sequence);
|
||||
|
||||
/* Convert message to host endianess */
|
||||
if (m->endian != MSG_ENDIAN_HOST)
|
||||
msg_swap(m);
|
||||
|
|
Loading…
Add table
Reference in a new issue