diff --git a/clients/opal/models/AsyncIP_sl/AsyncIP.c b/clients/opal/models/AsyncIP_sl/AsyncIP.c index b94483b06..35ed61370 100644 --- a/clients/opal/models/AsyncIP_sl/AsyncIP.c +++ b/clients/opal/models/AsyncIP_sl/AsyncIP.c @@ -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 #include #include @@ -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; } -/************************************************************************/ + diff --git a/clients/opal/models/AsyncIP_sl/AsyncIP.mk b/clients/opal/models/AsyncIP_sl/AsyncIP.mk index 5e7800f01..0dded5209 100644 --- a/clients/opal/models/AsyncIP_sl/AsyncIP.mk +++ b/clients/opal/models/AsyncIP_sl/AsyncIP.mk @@ -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) diff --git a/clients/opal/models/AsyncIP_sl/AsyncIPUtils.h b/clients/opal/models/AsyncIP_sl/AsyncIPUtils.h index bf4919b33..7c671954b 100644 --- a/clients/opal/models/AsyncIP_sl/AsyncIPUtils.h +++ b/clients/opal/models/AsyncIP_sl/AsyncIPUtils.h @@ -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 */