From 5195925f3b74f5cba979be3842c5b47f95500798 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Mon, 14 Jul 2014 10:47:35 +0000 Subject: [PATCH] changed OPAL Async IP code for new msg format git-svn-id: https://zerberus.eonerc.rwth-aachen.de:8443/svn/s2ss/trunk@144 8ec27952-4edc-4aab-86aa-e87bb2611832 --- clients/opal/models/AsyncIP_sl/AsyncIP.c | 97 +++++++++------------ clients/opal/models/AsyncIP_sl/msg_format.h | 43 +++++++++ 2 files changed, 85 insertions(+), 55 deletions(-) create mode 100644 clients/opal/models/AsyncIP_sl/msg_format.h diff --git a/clients/opal/models/AsyncIP_sl/AsyncIP.c b/clients/opal/models/AsyncIP_sl/AsyncIP.c index a7cd36be2..2c1e5207a 100644 --- a/clients/opal/models/AsyncIP_sl/AsyncIP.c +++ b/clients/opal/models/AsyncIP_sl/AsyncIP.c @@ -69,23 +69,29 @@ void *SendToIPPort(void * arg) double mdldata[MAXSENDSIZE]; int mdldata_size; - struct data_out comdata; - int comdata_size; - int count = 0; + + struct msg msg; + int msg_size; OpalPrint("%s: SendToIPPort thread started\n", PROGNAME); OpalGetNbAsyncSendIcon(&nbSend); - if (nbSend >= 1) { + + /* Prepare message header */ + msg.version = MSG_VERSION; + msg.type = MSG_TYPE_DATA; + msg.sequence = 0; + do { /* This call unblocks when the 'Data Ready' line of a send icon is asserted. */ - if ((n = OpalWaitForAsyncSendRequest (&SendID)) != EOK) { + if ((n = OpalWaitForAsyncSendRequest(&SendID)) != EOK) { ModelState = OpalGetAsyncModelState(); if ((ModelState != STATE_RESET) && (ModelState != STATE_STOP)) { OpalSetAsyncSendIconError(n, SendID); OpalPrint("%s: OpalWaitForAsyncSendRequest(), errno %d\n", PROGNAME, n); } + continue; } @@ -93,40 +99,30 @@ void *SendToIPPort(void * arg) OpalSetAsyncSendIconError(0, SendID); /* Get the size of the data being sent by the unblocking SendID */ - OpalGetAsyncSendIconDataLength (&mdldata_size, SendID); - if (mdldata_size/sizeof(double) > MAXSENDSIZE) { + OpalGetAsyncSendIconDataLength(&mdldata_size, SendID); + if (mdldata_size / sizeof(double) > MAXSENDSIZE) { OpalPrint("%s: Number of signals for SendID=%d exceeds allowed maximum (%d)\n", PROGNAME, SendID, MAXSENDSIZE); + return NULL; } /* Read data from the model */ - OpalGetAsyncSendIconData (mdldata, mdldata_size, SendID); + OpalGetAsyncSendIconData(mdldata, mdldata_size, SendID); -/******* FORMAT TO SPECIFIC PROTOCOL HERE ****************************** - * Modify this section to use values differently or to cast them - * to other data types depending on the structure... - */ - comdata.dev_id = SendID; /* Use the SendID as a device ID here */ - comdata.msg_id++; /* The message ID is just incremented */ - comdata.msg_len = mdldata_size; -// comdata.msg_len = (mdldata_size/sizeof(double)) * sizeof(int); /* If comdata.data was an "int" */ +/******* FORMAT TO SPECIFIC PROTOCOL HERE *****************************/ -/* In our case, because the data in the packet is in double format - * we don't need to cast the data from the model to another format */ - for (i=0; i < (mdldata_size / sizeof(double)); i++) - comdata.data[i] = mdldata[i]; -// comdata.data[i] = (int)mdldata[i]; /* If comdata.data was an "int" */ + // msg.dev_id = SendID; /* Use the SendID as a device ID here */ + msg.sequence++; + msg.length = mdldata_size / sizeof(double); + + for (i = 0; i < msg.length; i++) + msg.data[i] = (float) mdldata[i]; -/* Because the useful length of the structure is variable, we use - * the comdata_size variable to send just what is necessary with - * the write function. */ - comdata_size = 8 + comdata.msg_len; -// comdata_size = sizeof(comdata); /* For fixed length packets */ /**********************************************************************/ /* Perform the actual write to the ip port */ - if (SendPacket((char*)&comdata, comdata_size) < 0) + if (SendPacket((char *) &msg, msg_size) < 0) OpalSetAsyncSendIconError(errno, SendID); else OpalSetAsyncSendIconError(0, SendID); @@ -153,37 +149,33 @@ void *SendToIPPort(void * arg) return NULL; } -void *RecvFromIPPort (void * arg) +void *RecvFromIPPort(void * arg) { int RecvID = 1; - int i, n1, n2, nt, n; + int i, n; int nbRecv = 0; int ModelState; double mdldata[MAXRECVSIZE]; int mdldata_size; - struct data_in comdata; - int comdata_size; + + struct msg msg; + int msg_size; OpalPrint("%s: RecvFromIPPort thread started\n", PROGNAME); OpalGetNbAsyncRecvIcon(&nbRecv); - if (nbRecv >= 1) { do { - memset (&comdata, 0, sizeof(comdata)); + memset(&msg, 0, sizeof(msg)); /******* FORMAT TO SPECIFIC PROTOCOL HERE ****************************** * Modify this section if your protocol needs to receive more than one * packet to process the data */ - comdata_size = sizeof(comdata); - n = RecvPacket((char*)&comdata, comdata_size, 1.0); - nt = n; + msg_size = sizeof(msg); + n = RecvPacket((char *) &msg, msg_size, 1.0); -/* In our example protocol, the length of the message is variable and it - * is specified in the header. If your protocol is fixed-length, you can - * remove this line. */ - comdata_size = 8 + comdata.msg_len; + msg_size = 4 * (msg.length + 1); /***********************************************************************/ if (n < 1) { @@ -199,37 +191,32 @@ void *RecvFromIPPort (void * arg) } break; } - else if (nt != comdata_size) { - /* Disable this print. It may happen in TCP/IP mode. - * The server needs to be modified to check packet size. */ - // OpalPrint("%s: Received incoherent packet (size: %d, complete: %d)\n", PROGNAME, nt, comdata_size); + else if (n != msg_size) { + OpalPrint("%s: Received incoherent packet (size: %d, complete: %d)\n", PROGNAME, n, msg_size); continue; } -/******* FORMAT TO SPECIFIC PROTOCOL HERE ****************************** - * Modify this section to use values differently or to cast them - * to other data types depending on the structure... */ - RecvID = comdata.dev_id; /* Use the deviceID as the RecvID */ - OpalSetAsyncRecvIconStatus(comdata.msg_id, RecvID); /* Set the Status to the message ID */ +/******* FORMAT TO SPECIFIC PROTOCOL HERE *******************************/ + RecvID = 0; // msg.dev_id; /* Use the deviceID as the RecvID */ + OpalSetAsyncRecvIconStatus(msg.sequence, RecvID); /* Set the Status to the message ID */ OpalSetAsyncRecvIconError(0, RecvID); /* Set the Error to 0 */ /* Get the number of signals to send back to the model */ OpalGetAsyncRecvIconDataLength(&mdldata_size, RecvID); - if (mdldata_size/sizeof(double) > MAXRECVSIZE) { + if (mdldata_size / sizeof(double) > MAX_VALUES) { OpalPrint("%s: Number of signals for RecvID=%d (%d) exceeds allowed maximum (%d)\n", PROGNAME, RecvID, mdldata_size/sizeof(double), MAXRECVSIZE); return NULL; } -// if (mdldata_size/sizeof(double) > comdata.msg_len/sizeof(int)) // If comdata.data was an "int" - if (mdldata_size > comdata.msg_len) { + if (mdldata_size > msg.length * sizeof(float)) { OpalPrint("%s: Number of signals for RecvID=%d (%d) exceeds what was received (%d)\n", - PROGNAME, RecvID, mdldata_size/sizeof(double), comdata.msg_len/sizeof(double)); + PROGNAME, RecvID, mdldata_size / sizeof(double), msg.length); } - for (i=0; i < (mdldata_size / sizeof(double)); i++) - mdldata[i] = (double)comdata.data[i]; + for (i = 0; i < msg.length; i++) + mdldata[i] = (double) msg.data[i]; /************************************************************************/ OpalSetAsyncRecvIconData(mdldata, mdldata_size, RecvID); diff --git a/clients/opal/models/AsyncIP_sl/msg_format.h b/clients/opal/models/AsyncIP_sl/msg_format.h new file mode 100644 index 000000000..f5fd509be --- /dev/null +++ b/clients/opal/models/AsyncIP_sl/msg_format.h @@ -0,0 +1,43 @@ +/** Message format + * + * @author Steffen Vogel + * @copyright 2014, Institute for Automation of Complex Power Systems, EONERC + * @file + */ + +#ifndef _MSG_FORMAT_H_ +#define _MSG_FORMAT_H_ + +#include + +/** Maximum number of dword values in a message */ +#define MSG_VALUES 16 +/** The current version number for the message format */ +#define MSG_VERSION 0 + +/** @todo Implement more message types */ +#define MSG_TYPE_DATA 0 +#define MSG_TYPE_START 1 +#define MSG_TYPE_STOP 2 + +/** This message format is used by all clients + * + * @diafile msg_format.dia + **/ +struct msg +{ + /** The version specifies the format of the remaining message */ + unsigned version : 4; + /** Data or control message */ + unsigned type : 2; + /** These bits are reserved for future extensions */ + unsigned __padding : 2; + /** 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 */ + float data[MSG_VALUES]; +} __attribute__((packed)); + +#endif /* _MSG_FORMAT_H_ */