1
0
Fork 0
mirror of https://git.rwth-aachen.de/acs/public/villas/node/ synced 2025-03-09 00:00:00 +01:00

applied coding style to OPAL-RT AsyncIP stuff

git-svn-id: https://zerberus.eonerc.rwth-aachen.de:8443/svn/s2ss/trunk@137 8ec27952-4edc-4aab-86aa-e87bb2611832
This commit is contained in:
Steffen Vogel 2014-07-07 07:53:45 +00:00
parent 30fbc53e06
commit 6efe8e810f
3 changed files with 406 additions and 523 deletions

View file

@ -15,11 +15,11 @@
* application. You should normally only have to modify the sections
* marked with: ****** Format to specific protocol here. ******.
*
*-----------------------------------------------------------------*/
*-----------------------------------------------------------------*/
#define PROGNAME "AsyncIP"
// Standard ANSI C headers needed for this program
/* Standard ANSI C headers needed for this program */
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
@ -44,387 +44,315 @@
# endif
#endif
// Define RTLAB before including OpalPrint.h for messages to be sent
// to the OpalDisplay. Otherwise stdout will be used.
/* This is the message format */
#include "msg_types.h"
/* Define RTLAB before including OpalPrint.h for messages to be sent
* to the OpalDisplay. Otherwise stdout will be used. */
#define RTLAB
#include "OpalPrint.h"
#include "AsyncApi.h"
#include "AsyncIPUtils.h"
// This is just for initializing the shared memory access to communicate
// with the RT-LAB model. It's easier to remember the arguments like this
/* This is just for initializing the shared memory access to communicate
* with the RT-LAB model. It's easier to remember the arguments like this */
#define ASYNC_SHMEM_NAME argv[1]
#define ASYNC_SHMEM_SIZE atoi(argv[2])
#define PRINT_SHMEM_NAME argv[3]
// This defines the maximum number of signals (doubles) that can be sent
// or received by any individual Send or Recv block in the model. This
// only applies to the "model <-> asynchronous process" communication.
/* This defines the maximum number of signals (doubles) that can be sent
* or received by any individual Send or Recv block in the model. This
* only applies to the "model <-> asynchronous process" communication. */
#define MAXSENDSIZE 64
#define MAXRECVSIZE 64
// Set the stack size of each thread.
#define STACKSIZE 4096
// Use the smallest possible memory footprint to store the data_out
// and data_in structures.
#pragma pack(1)
// ****** FORMAT TO SPECIFIC PROTOCOL HERE ******************************
//
// Define the structure of the data that we send out. This is used in the
// SendToIPPort function
struct data_out
{
short dev_id; // (2 bytes) Sender device ID
int msg_id; // (4 bytes) Message ID
short msg_len; // (2 bytes) Message length (data only)
double data[MAXSENDSIZE]; // Up to MAXSENDSIZE doubles (8 bytes each)
};
//
// Define the structure of the data that we receive. This is used in the
// RecvFromIPPort function
struct data_in
{
short dev_id; // (2 bytes) Sender device ID
int msg_id; // (4 bytes) Message ID
short msg_len; // (2 bytes) Message length (data only)
double data[MAXRECVSIZE]; // Up to MAXRECVSIZE doubles (8 bytes each)
};
// **********************************************************************
// Go back to the standard memory allocation scheme.
#pragma pack()
volatile int thread_count = 0;
/************************************************************************/
int AssignProcToCpu0(void)
{
#if defined(__linux__)
# if defined(__redhawk__)
int rc;
#if defined(__redhawk__)
int rc;
pid_t pid = getpid();
cpuset_t *pCpuset;
pCpuset = cpuset_alloc();
if (NULL == pCpuset)
{
if (NULL == pCpuset) {
fprintf(stderr, "Error allocating a cpuset\n");
return(ENOMEM);
}
cpuset_init(pCpuset);
cpuset_set_cpu(pCpuset, 0, 1);
rc = mpadvise(MPA_PRC_SETBIAS, MPA_TID, pid, pCpuset);
if (MPA_FAILURE == rc)
{
if (MPA_FAILURE == rc) {
rc = errno;
fprintf(stderr, "Error from mpadvise, %d %s, for pid %d\n", errno, strerror(errno), pid);
cpuset_free(pCpuset);
return(rc);
}
cpuset_free(pCpuset);
return EOK;
# else
#else
cpu_set_t bindSet;
CPU_ZERO( &bindSet );
CPU_SET( 0, &bindSet );
CPU_ZERO(&bindSet);
CPU_SET(0, &bindSet);
/* changing process cpu affinity */
if ( sched_setaffinity( 0, sizeof(cpu_set_t), &bindSet ) != 0 )
{
(int) fprintf(stderr, "Unable to bind the process to cpu 0. (sched_setaffinity errno %d)\n", errno );
if (sched_setaffinity(0, sizeof(cpu_set_t), &bindSet) != 0) {
fprintf(stderr, "Unable to bind the process to CPU 0. (sched_setaffinity errno %d)\n", errno );
return EINVAL;
}
return EOK;
# endif
#endif // __linux__
#endif
#endif /* __linux__ */
}
/************************************************************************/
/************************************************************************/
void *SendToIPPort (void * arg)
void *SendToIPPort(void * arg)
{
int SendID = 1;
int i,n;
int nbSend = 0;
int ModelState;
int SendID = 1;
int i, n;
int nbSend = 0;
int ModelState;
double mdldata[MAXSENDSIZE];
int mdldata_size;
struct data_out comdata;
int comdata_size;
int count = 0;
OpalPrint("%s: SendToIPPort thread started\n", PROGNAME);
OpalGetNbAsyncSendIcon(&nbSend);
if(nbSend >= 1)
{
do
{
// This call unblocks when the 'Data Ready' line of a send icon is asserted.
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;
}
double mdldata[MAXSENDSIZE];
int mdldata_size;
struct data_out comdata;
int comdata_size;
int count = 0;
OpalPrint("%s: SendToIPPort thread started\n", PROGNAME);
OpalGetNbAsyncSendIcon(&nbSend);
if (nbSend >= 1) {
do {
/* This call unblocks when the 'Data Ready' line of a send icon is asserted. */
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;
}
/* No errors encountered yet */
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) {
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);
/******* 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" */
// No errors encountered yet
OpalSetAsyncSendIconError(0, SendID);
/* 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" */
// Get the size of the data being sent by the unblocking SendID
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;
}
/* 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 */
/**********************************************************************/
// Read data from the model
OpalGetAsyncSendIconData (mdldata, mdldata_size, SendID);
/* Perform the actual write to the ip port */
if (SendPacket((char*)&comdata, comdata_size) < 0)
OpalSetAsyncSendIconError(errno, SendID);
else
OpalSetAsyncSendIconError(0, 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"
//
// 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"
//
// 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
// **********************************************************************
/* This next call allows the execution of the "asynchronous" process
* to actually be synchronous with the model. To achieve this, you
* should set the "Sending Mode" in the Async_Send block to
* NEED_REPLY_BEFORE_NEXT_SEND or NEED_REPLY_NOW. This will force
* the model to wait for this process to call this
* OpalAsyncSendRequestDone function before continuing. */
OpalAsyncSendRequestDone(SendID);
// Perform the actual write to the ip port
if (SendPacket((char*)&comdata, comdata_size) < 0)
OpalSetAsyncSendIconError (errno, SendID);
else
OpalSetAsyncSendIconError (0, SendID);
/* Before continuing, we make sure that the real-time model
* has not been stopped. If it has, we quit. */
ModelState = OpalGetAsyncModelState();
} while ((ModelState != STATE_RESET) && (ModelState != STATE_STOP));
// This next call allows the execution of the "asynchronous" process
// to actually be synchronous with the model. To achieve this, you
// should set the "Sending Mode" in the Async_Send block to
// NEED_REPLY_BEFORE_NEXT_SEND or NEED_REPLY_NOW. This will force
// the model to wait for this process to call this
// OpalAsyncSendRequestDone function before continuing.
OpalAsyncSendRequestDone (SendID);
OpalPrint("%s: SendToIPPort: Finished\n", PROGNAME);
}
else {
OpalPrint("%s: SendToIPPort: No transimission block for this controller. Stopping thread.\n", PROGNAME);
}
// Before continuing, we make sure that the real-time model
// has not been stopped. If it has, we quit.
ModelState = OpalGetAsyncModelState();
} while ((ModelState != STATE_RESET) && (ModelState != STATE_STOP));
OpalPrint("%s: SendToIPPort: Finished\n", PROGNAME);
}
else
{
OpalPrint("%s: SendToIPPort: No transimission block for this controller. Stopping thread.\n", PROGNAME);
}
thread_count--;
return NULL;
return NULL;
}
/************************************************************************/
/************************************************************************/
void *RecvFromIPPort (void * arg)
{
int RecvID = 1;
int i, n1, n2, nt, n;
int nbRecv = 0;
int ModelState;
int RecvID = 1;
int i, n1, n2, nt, n;
int nbRecv = 0;
int ModelState;
double mdldata[MAXRECVSIZE];
int mdldata_size;
struct data_in comdata;
int comdata_size;
OpalPrint("%s: RecvFromIPPort thread started\n", PROGNAME);
OpalGetNbAsyncRecvIcon(&nbRecv);
if(nbRecv >= 1)
{
do
{
memset (&comdata, 0, sizeof(comdata));
double mdldata[MAXRECVSIZE];
int mdldata_size;
struct data_in comdata;
int comdata_size;
OpalPrint("%s: RecvFromIPPort thread started\n", PROGNAME);
OpalGetNbAsyncRecvIcon(&nbRecv);
if (nbRecv >= 1) {
do {
memset (&comdata, 0, sizeof(comdata));
// ****** 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;
/******* 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;
// 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;
// **********************************************************************
/* 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;
/***********************************************************************/
if (n < 1)
{
ModelState = OpalGetAsyncModelState();
if ((ModelState != STATE_RESET) && (ModelState != STATE_STOP))
{
// n == 0 means timeout, so we continue silently
//if (n == 0)
// OpalPrint("%s: Timeout while waiting for data\n", PROGNAME, errno);
// n == -1 means a more serious error, so we print it
if (n == -1)
OpalPrint("%s: Error %d while waiting for data\n", PROGNAME, errno);
continue;
}
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);
continue;
}
if (n < 1) {
ModelState = OpalGetAsyncModelState();
if ((ModelState != STATE_RESET) && (ModelState != STATE_STOP)) {
// n == 0 means timeout, so we continue silently
//if (n == 0)
// OpalPrint("%s: Timeout while waiting for data\n", PROGNAME, errno);
// n == -1 means a more serious error, so we print it
if (n == -1)
OpalPrint("%s: Error %d while waiting for data\n", PROGNAME, errno);
continue;
}
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);
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
OpalSetAsyncRecvIconError (0, RecvID); // Set the Error to 0
/******* 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 */
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)
{
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 > comdata.msg_len)
// if (mdldata_size/sizeof(double) > comdata.msg_len/sizeof(int)) // If comdata.data was an "int"
{
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));
}
/* Get the number of signals to send back to the model */
OpalGetAsyncRecvIconDataLength(&mdldata_size, RecvID);
for (i=0; i < (mdldata_size / sizeof(double)); i++)
mdldata[i] = (double)comdata.data[i];
// **********************************************************************
if (mdldata_size/sizeof(double) > MAXRECVSIZE) {
OpalPrint("%s: Number of signals for RecvID=%d (%d) exceeds allowed maximum (%d)\n",
PROGNAME, RecvID, mdldata_size/sizeof(double), MAXRECVSIZE);
return NULL;
}
OpalSetAsyncRecvIconData (mdldata, mdldata_size, RecvID);
// if (mdldata_size/sizeof(double) > comdata.msg_len/sizeof(int)) // If comdata.data was an "int"
if (mdldata_size > comdata.msg_len) {
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));
}
// Before continuing, we make sure that the real-time model
// has not been stopped. If it has, we quit.
ModelState = OpalGetAsyncModelState();
} while ((ModelState != STATE_RESET) && (ModelState != STATE_STOP));
for (i=0; i < (mdldata_size / sizeof(double)); i++)
mdldata[i] = (double)comdata.data[i];
/************************************************************************/
OpalPrint("%s: RecvFromIPPort: Finished\n", PROGNAME);
}
else
{
OpalPrint("%s: RecvFromIPPort: No reception block for this controller. Stopping thread.\n", PROGNAME);
}
thread_count--;
return NULL;
OpalSetAsyncRecvIconData(mdldata, mdldata_size, RecvID);
/* Before continuing, we make sure that the real-time model
* has not been stopped. If it has, we quit. */
ModelState = OpalGetAsyncModelState();
} while ((ModelState != STATE_RESET) && (ModelState != STATE_STOP));
OpalPrint("%s: RecvFromIPPort: Finished\n", PROGNAME);
}
else {
OpalPrint("%s: RecvFromIPPort: No reception block for this controller. Stopping thread.\n", PROGNAME);
}
return NULL;
}
/************************************************************************/
/************************************************************************/
int main (int argc, char *argv[])
int main(int argc, char *argv[])
{
Opal_GenAsyncParam_Ctrl IconCtrlStruct;
int err;
pthread_t tid_send, tid_recv;
pthread_attr_t attr_send, attr_recv;
// Check for the proper arguments to the program
if (argc < 4)
{
printf("Invalid Arguments: 1-AsyncShmemName 2-AsyncShmemSize 3-PrintShmemName\n");
exit(0);
}
// Enable the OpalPrint function. This prints to the OpalDisplay.
if (OpalSystemCtrl_Register(PRINT_SHMEM_NAME) != EOK)
{
printf("%s: ERROR: OpalPrint() access not available\n", PROGNAME);
exit(-1);
}
// Open Share Memory created by the model. -----------------------
if((OpalOpenAsyncMem (ASYNC_SHMEM_SIZE, ASYNC_SHMEM_NAME)) != EOK)
{
OpalPrint("%s: ERROR: Model shared memory not available\n", PROGNAME);
exit(-1);
}
// For Redhawk, Assign this process to CPU 0 in order to support partial XHP
AssignProcToCpu0();
// Get IP Controler Parameters (ie: ip address, port number...) and
// initialize the device on the QNX node.
memset(&IconCtrlStruct, 0, sizeof(IconCtrlStruct));
if((err = OpalGetAsyncCtrlParameters(&IconCtrlStruct, sizeof(IconCtrlStruct))) != EOK)
{
OpalPrint("%s: ERROR: Could not get controller parameters (%d).\n", PROGNAME, err);
exit(-1);
}
if(InitSocket (IconCtrlStruct) != EOK)
{
OpalPrint("%s: ERROR: Initialization failed.\n", PROGNAME);
exit(-1);
}
Opal_GenAsyncParam_Ctrl IconCtrlStruct;
int err;
pthread_t tid_send, tid_recv;
pthread_attr_t attr_send, attr_recv;
/* Check for the proper arguments to the program */
if (argc < 4) {
printf("Invalid Arguments: 1-AsyncShmemName 2-AsyncShmemSize 3-PrintShmemName\n");
exit(0);
}
/* Enable the OpalPrint function. This prints to the OpalDisplay. */
if (OpalSystemCtrl_Register(PRINT_SHMEM_NAME) != EOK) {
printf("%s: ERROR: OpalPrint() access not available\n", PROGNAME);
exit(EXIT_FAILURE);
}
/* Open Share Memory created by the model. */
if ((OpalOpenAsyncMem(ASYNC_SHMEM_SIZE, ASYNC_SHMEM_NAME)) != EOK) {
OpalPrint("%s: ERROR: Model shared memory not available\n", PROGNAME);
exit(EXIT_FAILURE);
}
/* For Redhawk, Assign this process to CPU 0 in order to support partial XHP */
AssignProcToCpu0();
/* Get IP Controler Parameters (ie: ip address, port number...) and
* initialize the device on the QNX node. */
memset(&IconCtrlStruct, 0, sizeof(IconCtrlStruct));
if ((err = OpalGetAsyncCtrlParameters(&IconCtrlStruct, sizeof(IconCtrlStruct))) != EOK) {
OpalPrint("%s: ERROR: Could not get controller parameters (%d).\n", PROGNAME, err);
exit(EXIT_FAILURE);
}
if (InitSocket(IconCtrlStruct) != EOK) {
OpalPrint("%s: ERROR: Initialization failed.\n", PROGNAME);
exit(EXIT_FAILURE);
}
// Start transmission thread --------------------------------------
thread_count++;
pthread_attr_init (&attr_send);
//pthread_attr_setstacksize (&attr_send, STACKSIZE); // Has been known to crash the application
if ((pthread_create (&tid_send, &attr_send, SendToIPPort, NULL)) == -1)
{
OpalPrint("%s: ERROR: Could not create thread (SendToIPPort), errno %d\n", PROGNAME, errno);
thread_count--;
}
// Start reception thread -----------------------------------------
thread_count++;
pthread_attr_init (&attr_recv);
//pthread_attr_setstacksize (&attr_recv, STACKSIZE); // Has been known to crash the application
if ((pthread_create (&tid_recv, &attr_recv, RecvFromIPPort, NULL)) == -1)
{
OpalPrint("%s: ERROR: Could not create thread (RecvFromIPPort), errno %d\n", PROGNAME, errno);
thread_count--;
}
/* Start send/receive threads */
if ((pthread_create(&tid_send, NULL, SendToIPPort, NULL)) == -1)
OpalPrint("%s: ERROR: Could not create thread (SendToIPPort), errno %d\n", PROGNAME, errno);
if ((pthread_create(&tid_recv, NULL, RecvFromIPPort, NULL)) == -1)
OpalPrint("%s: ERROR: Could not create thread (RecvFromIPPort), errno %d\n", PROGNAME, errno);
// Wait for both threads to finish --------------------------------
if ((err = pthread_join (tid_send, NULL)) != 0)
{ OpalPrint("%s: ERROR: pthread_join (SendToIPPort), errno %d\n", PROGNAME, err); }
if ((err = pthread_join (tid_recv, NULL)) != 0)
{ OpalPrint("%s: ERROR: pthread_join (RecvFromIPPort), errno %d\n", PROGNAME, err); }
/* Wait for both threads to finish */
if ((err = pthread_join(tid_send, NULL)) != 0)
OpalPrint("%s: ERROR: pthread_join (SendToIPPort), errno %d\n", PROGNAME, err);
if ((err = pthread_join(tid_recv, NULL)) != 0)
OpalPrint("%s: ERROR: pthread_join (RecvFromIPPort), errno %d\n", PROGNAME, err);
// Close the ip port and shared memories ----------------------
CloseSocket (IconCtrlStruct);
OpalCloseAsyncMem (ASYNC_SHMEM_SIZE,ASYNC_SHMEM_NAME);
OpalSystemCtrl_UnRegister(PRINT_SHMEM_NAME);
/* Close the ip port and shared memories */
CloseSocket(IconCtrlStruct);
OpalCloseAsyncMem (ASYNC_SHMEM_SIZE, ASYNC_SHMEM_NAME);
OpalSystemCtrl_UnRegister(PRINT_SHMEM_NAME);
return(0);
return 0;
}
/************************************************************************/

View file

@ -1,18 +1,10 @@
# ----------------------------------------------------------------------------#
# Specify program name
PROGRAM = AsyncIP
# ----------------------------------------------------------------------------#
# Specify default values if we are not compiling from RT-LAB
#
# ----------------------------------------------------------------------------#
TARGET_OPALRT_ROOT = /usr/opalrt
# ----------------------------------------------------------------------------#
# QNX v6.x
#
ifeq "$(SYSNAME)" "nto"
CC = gcc
@ -20,14 +12,11 @@ ifeq "$(SYSNAME)" "nto"
TARGET_LIB = -lsocket
endif
# ----------------------------------------------------------------------------#
# ----------------------------------------------------------------------------#
# RedHawk Linux
#
ifeq "$(shell uname)" "Linux"
RTLAB_INTEL_COMPILER ?= 1
# Intel Compiler support
ifeq ($(RTLAB_INTEL_COMPILER),1)
CC = opicc
@ -51,7 +40,6 @@ ifeq "$(shell uname)" "Linux"
TARGET_LIB = -lpthread -lm -ldl -lutil -lrt $(RH_LIBS) $(INTEL_LIBS)
endif
# ----------------------------------------------------------------------------#
# Support for debugging symbols
ifeq ($(DEBUG),1)

View file

@ -36,223 +36,190 @@
#define TCP_PROTOCOL 2
#define EOK 0
// Globals variables
//
struct sockaddr_in send_ad; // send address
struct sockaddr_in recv_ad; // recv address
int sd = -1; // socket descriptor
int proto = 1;
/* Globals variables */
struct sockaddr_in send_ad; /* Send address */
struct sockaddr_in recv_ad; /* Recveive address */
int sd = -1; /* socket descriptor */
int proto = 1;
/************************************************************************/
int InitSocket(Opal_GenAsyncParam_Ctrl IconCtrlStruct)
{
struct ip_mreq mreq; // Multicast group structure
int socket_type;
int socket_proto;
unsigned char TTL = 1;
unsigned char LOOP = 0;
int rc;
struct ip_mreq mreq; /* Multicast group structure */
int socket_type;
int socket_proto;
unsigned char TTL = 1;
unsigned char LOOP = 0;
int rc;
proto = (int) IconCtrlStruct.FloatParam[0];
OpalPrint("%s: Version : %s\n", PROGNAME, VERSION);
proto = (int) IconCtrlStruct.FloatParam[0];
OpalPrint("%s: Version : %s\n", PROGNAME, VERSION);
// Communication using UDP/IP protocol ----------------------------------------------------
if(proto == UDP_PROTOCOL)
{
socket_proto = IPPROTO_UDP;
socket_type = SOCK_DGRAM;
OpalPrint("%s: Protocol : UDP/IP\n", PROGNAME);
}
switch (proto) {
case UDP_PROTOCOL: /* Communication using UDP/IP protocol */
socket_proto = IPPROTO_UDP;
socket_type = SOCK_DGRAM;
OpalPrint("%s: Protocol : UDP/IP\n", PROGNAME);
case TCP_PROTOCOL: /* Communication using TCP/IP protocol */
socket_proto = IPPROTO_IP;
socket_type = SOCK_STREAM;
OpalPrint("%s: Protocol : TCP/IP\n", PROGNAME);
case default: /* Protocol is not recognized */
OpalPrint("%s: ERROR: Protocol (%d) not supported!\n", PROGNAME, proto);
return EINVAL;
}
OpalPrint("%s: Remote Address : %s\n", PROGNAME, IconCtrlStruct.StringParam[0]);
OpalPrint("%s: Remote Port : %d\n", PROGNAME, (int)IconCtrlStruct.FloatParam[1]);
// Communication using TCP/IP protocol ----------------------------------------------------
else if(proto == TCP_PROTOCOL)
{
socket_proto = IPPROTO_IP;
socket_type = SOCK_STREAM;
OpalPrint("%s: Protocol : TCP/IP\n", PROGNAME);
}
// Protocol is not recognized -------------------------------------------------------------
else
{
OpalPrint("%s: ERROR: Protocol (%d) not supported!\n", PROGNAME, proto);
return (EINVAL);
}
OpalPrint("%s: Remote Address : %s\n", PROGNAME, IconCtrlStruct.StringParam[0]);
OpalPrint("%s: Remote Port : %d\n", PROGNAME, (int)IconCtrlStruct.FloatParam[1]);
// Initialize the socket
if((sd = socket(AF_INET, socket_type, socket_proto)) < 0)
{
OpalPrint("%s: ERROR: Could not open socket\n", PROGNAME);
return(EIO);
}
// Set the structure for the remote port and address
memset(&send_ad, 0, sizeof(send_ad));
send_ad.sin_family = AF_INET;
send_ad.sin_addr.s_addr = inet_addr(IconCtrlStruct.StringParam[0]);
send_ad.sin_port = htons((u_short)IconCtrlStruct.FloatParam[1]);
// Set the structure for the local port and address
memset(&recv_ad, 0, sizeof(recv_ad));
recv_ad.sin_family = AF_INET;
recv_ad.sin_addr.s_addr = INADDR_ANY;
recv_ad.sin_port = htons((u_short)IconCtrlStruct.FloatParam[2]);
// Bind local port and address to socket.
if (bind(sd, (struct sockaddr *)&recv_ad, sizeof(struct sockaddr_in)) == -1)
{
OpalPrint("%s: ERROR: Could not bind local port to socket\n", PROGNAME);
return(EIO);
}
else
OpalPrint("%s: Local Port : %d\n", PROGNAME, (int)IconCtrlStruct.FloatParam[2]);
/* Initialize the socket */
if ((sd = socket(AF_INET, socket_type, socket_proto)) < 0) {
OpalPrint("%s: ERROR: Could not open socket\n", PROGNAME);
return EIO;
}
/* Set the structure for the remote port and address */
memset(&send_ad, 0, sizeof(send_ad));
send_ad.sin_family = AF_INET;
send_ad.sin_addr.s_addr = inet_addr(IconCtrlStruct.StringParam[0]);
send_ad.sin_port = htons((u_short)IconCtrlStruct.FloatParam[1]);
/* Set the structure for the local port and address */
memset(&recv_ad, 0, sizeof(recv_ad));
recv_ad.sin_family = AF_INET;
recv_ad.sin_addr.s_addr = INADDR_ANY;
recv_ad.sin_port = htons((u_short)IconCtrlStruct.FloatParam[2]);
/* Bind local port and address to socket. */
if (bind(sd, (struct sockaddr *)&recv_ad, sizeof(struct sockaddr_in)) == -1) {
OpalPrint("%s: ERROR: Could not bind local port to socket\n", PROGNAME);
return EIO;
}
else
OpalPrint("%s: Local Port : %d\n", PROGNAME, (int)IconCtrlStruct.FloatParam[2]);
// Communication using UDP/IP protocol ----------------------------------------------------
if(proto == UDP_PROTOCOL)
{
// If sending to a multicast address
if ((inet_addr(IconCtrlStruct.StringParam[0]) & inet_addr("240.0.0.0")) == inet_addr("224.0.0.0"))
{
if (setsockopt(sd, IPPROTO_IP, IP_MULTICAST_TTL, (char*)&TTL, sizeof(TTL)) == -1)
{
OpalPrint("%s: ERROR: Could not set TTL for multicast send (%d)\n", PROGNAME, errno);
return(EIO);
}
if (setsockopt(sd, IPPROTO_IP, IP_MULTICAST_LOOP, (char*)&LOOP, sizeof(LOOP)) == -1)
{
OpalPrint("%s: ERROR: Could not set loopback for multicast send (%d)\n", PROGNAME, errno);
return(EIO);
}
switch (proto) {
case UDP_PROTOCOL: /* Communication using UDP/IP protocol */
/* If sending to a multicast address */
if ((inet_addr(IconCtrlStruct.StringParam[0]) & inet_addr("240.0.0.0")) == inet_addr("224.0.0.0")) {
if (setsockopt(sd, IPPROTO_IP, IP_MULTICAST_TTL, (char*)&TTL, sizeof(TTL)) == -1) {
OpalPrint("%s: ERROR: Could not set TTL for multicast send (%d)\n", PROGNAME, errno);
return EIO;
}
if (setsockopt(sd, IPPROTO_IP, IP_MULTICAST_LOOP, (char*)&LOOP, sizeof(LOOP)) == -1) {
OpalPrint("%s: ERROR: Could not set loopback for multicast send (%d)\n", PROGNAME, errno);
return EIO;
}
OpalPrint("%s: Configured socket for sending to multicast address\n", PROGNAME);
OpalPrint("%s: Configured socket for sending to multicast address\n", PROGNAME);
}
/* If receiving from a multicast group, register for it. */
if (inet_addr(IconCtrlStruct.StringParam[1]) > 0) {
if ((inet_addr(IconCtrlStruct.StringParam[1]) & inet_addr("240.0.0.0")) == inet_addr("224.0.0.0")) {
mreq.imr_multiaddr.s_addr = inet_addr(IconCtrlStruct.StringParam[1]);
mreq.imr_interface.s_addr = INADDR_ANY;
/* Have the multicast socket join the multicast group */
if (setsockopt(sd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&mreq, sizeof(mreq)) == -1) {
OpalPrint("%s: ERROR: Could not join multicast group (%d)\n", PROGNAME, errno);
return EIO;
}
OpalPrint("%s: Added process to multicast group (%s)\n",
PROGNAME, IconCtrlStruct.StringParam[1]);
}
else {
OpalPrint("%s: WARNING: IP address for multicast group is not in multicast range. Ignored\n",
PROGNAME);
}
}
case TCP_PROTOCOL: /* Communication using TCP/IP protocol */
OpalPrint("%s: Calling connect()\n", PROGNAME);
/* Connect to server to start data transmission */
rc = connect(sd, (struct sockaddr *)&send_ad, sizeof(send_ad));
if (rc < 0) {
OpalPrint("%s: ERROR: Call to connect() failed\n", PROGNAME);
return EIO;
}
}
// If receiving from a multicast group, register for it.
if (inet_addr(IconCtrlStruct.StringParam[1]) > 0)
{
if ((inet_addr(IconCtrlStruct.StringParam[1]) & inet_addr("240.0.0.0")) == inet_addr("224.0.0.0"))
{
mreq.imr_multiaddr.s_addr = inet_addr(IconCtrlStruct.StringParam[1]);
mreq.imr_interface.s_addr = INADDR_ANY;
// Have the multicast socket join the multicast group
if (setsockopt(sd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&mreq, sizeof(mreq)) == -1)
{
OpalPrint("%s: ERROR: Could not join multicast group (%d)\n", PROGNAME, errno);
return(EIO);
}
OpalPrint("%s: Added process to multicast group (%s)\n", PROGNAME, IconCtrlStruct.StringParam[1]);
}
else
{
OpalPrint("%s: WARNING: IP address for multicast group is not in multicast range. Ignored\n", PROGNAME);
}
}
}
// Communication using TCP/IP protocol ----------------------------------------------------
else if(proto == TCP_PROTOCOL)
{
OpalPrint("%s: Calling connect()\n", PROGNAME);
// Connect to server to start data transmission
rc = connect(sd, (struct sockaddr *)&send_ad, sizeof(send_ad));
if (rc < 0)
{
OpalPrint("%s: ERROR: Call to connect() failed\n", PROGNAME);
return(EIO);
}
OpalPrint("%s: Called connect()\n", PROGNAME);
}
return(EOK);
return EOK;
}
/************************************************************************/
/************************************************************************/
int SendPacket (char* DataSend, int datalength)
{
int err;
if(sd < 0) return(-1);
int err;
if(sd < 0)
return -1;
// Send the packet
if (proto == TCP_PROTOCOL)
err = send (sd, DataSend, datalength, 0);
else
err = sendto (sd, DataSend, datalength, 0, (struct sockaddr *)&send_ad, sizeof(send_ad));
return(err);
/* Send the packet */
if (proto == TCP_PROTOCOL)
err = send (sd, DataSend, datalength, 0);
else
err = sendto (sd, DataSend, datalength, 0, (struct sockaddr *)&send_ad, sizeof(send_ad));
return err;
}
/************************************************************************/
/************************************************************************/
int RecvPacket (char* DataRecv, int datalength, double timeout)
{
int len;
struct sockaddr_in client_ad;
socklen_t client_ad_size = sizeof(client_ad);
fd_set sd_set;
struct timeval tv;
if(sd < 0) return(-1);
// Set the descriptor set for the select() call
//
FD_ZERO (&sd_set);
FD_SET (sd, &sd_set);
// Set the tv structure to the correct timeout value
tv.tv_sec = (int)(timeout);
tv.tv_usec = (int)((timeout - tv.tv_sec)*1000000);
int len;
struct sockaddr_in client_ad;
socklen_t client_ad_size = sizeof(client_ad);
fd_set sd_set;
struct timeval tv;
if (sd < 0)
return -1;
/* Set the descriptor set for the select() call */
FD_ZERO (&sd_set);
FD_SET (sd, &sd_set);
/* Set the tv structure to the correct timeout value */
tv.tv_sec = (int)(timeout);
tv.tv_usec = (int)((timeout - tv.tv_sec)*1000000);
// Wait for a packet. We use select() to have a timeout. This is
// necessary when reseting the model so we don't wait indefinitely
// and prevent the process from exiting and freeing the port for
// a future instance (model load).
switch (select (sd+1, &sd_set, (fd_set*)0, (fd_set*)0, &tv))
{
case -1:
// Error
return (-1);
case 0:
// We hit the timeout
return (0);
default:
if (!(FD_ISSET (sd, &sd_set)))
{
// We received something, but it's not on "sd". Since sd is the only
// descriptor in the set...
OpalPrint("%s: RecvPacket: God, is that You trying to reach me?\n", PROGNAME);
return (-1);
/* Wait for a packet. We use select() to have a timeout. This is
* necessary when reseting the model so we don't wait indefinitely
* and prevent the process from exiting and freeing the port for
* a future instance (model load). */
switch (select(sd+1, &sd_set, (fd_set*)0, (fd_set*)0, &tv)) {
case -1: /* Error */
return -1;
case 0: /* We hit the timeout */
return 0;
default:
if (!(FD_ISSET (sd, &sd_set))) {
/* We received something, but it's not on "sd". Since sd is the only
* descriptor in the set... */
OpalPrint("%s: RecvPacket: God, is that You trying to reach me?\n", PROGNAME);
return -1;
}
}
}
// Clear the DataRecv array (in case we receive an incomplete packet)
memset (DataRecv, 0, datalength);
// Perform the reception
if (proto == TCP_PROTOCOL)
len = recv (sd, DataRecv, datalength, 0);
else
len = recvfrom (sd, DataRecv, datalength, 0, (struct sockaddr *)&client_ad, &client_ad_size);
return(len);
/* Clear the DataRecv array (in case we receive an incomplete packet) */
memset (DataRecv, 0, datalength);
/* Perform the reception */
if (proto == TCP_PROTOCOL)
len = recv (sd, DataRecv, datalength, 0);
else
len = recvfrom (sd, DataRecv, datalength, 0, (struct sockaddr *)&client_ad, &client_ad_size);
return len;
}
/************************************************************************/
/************************************************************************/
int CloseSocket (Opal_GenAsyncParam_Ctrl IconCtrlStruct)
{
if(sd < 0)
{
shutdown(sd, SHUT_RDWR);
close(sd);
}
return(0);
if (sd < 0) {
shutdown(sd, SHUT_RDWR);
close(sd);
}
return 0;
}
#endif
#endif /* OPAL_IP_H */