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:
parent
30fbc53e06
commit
6efe8e810f
3 changed files with 406 additions and 523 deletions
|
@ -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;
|
||||
}
|
||||
/************************************************************************/
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Add table
Reference in a new issue