mirror of
https://git.rwth-aachen.de/acs/public/villas/node/
synced 2025-03-09 00:00:00 +01:00
asyncip: refactored socket code to eliminate global variables
This commit is contained in:
parent
ecd996f251
commit
d0a1022e48
3 changed files with 51 additions and 46 deletions
|
@ -8,18 +8,26 @@
|
|||
#ifndef _SOCKET_H_
|
||||
#define _SOCKET_H_
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
#define RT
|
||||
#include "OpalGenAsyncParamCtrl.h"
|
||||
|
||||
#define UDP_PROTOCOL 1
|
||||
#define TCP_PROTOCOL 2
|
||||
|
||||
int InitSocket(Opal_GenAsyncParam_Ctrl IconCtrlStruct);
|
||||
struct socket {
|
||||
struct sockaddr_in send_ad; /* Send address */
|
||||
struct sockaddr_in recv_ad; /* Receive address */
|
||||
int sd; /* socket descriptor */
|
||||
};
|
||||
|
||||
int SendPacket(char* DataSend, int datalength);
|
||||
int socket_init(struct socket *s, Opal_GenAsyncParam_Ctrl IconCtrlStruct);
|
||||
|
||||
int RecvPacket(char* DataRecv, int datalength, double timeout);
|
||||
int socket_send(struct socket *s, char *data, int len);
|
||||
|
||||
int CloseSocket(Opal_GenAsyncParam_Ctrl IconCtrlStruct);
|
||||
int socket_recv(struct socket *s, char *data, int len, double timeout);
|
||||
|
||||
int socket_close(struct socket *s, Opal_GenAsyncParam_Ctrl IconCtrlStruct);
|
||||
|
||||
#endif /* _SOCKET_H_ */
|
||||
|
|
|
@ -59,6 +59,8 @@ void Tick(int sig, siginfo_t *si, void *ptr)
|
|||
PROGNAME, (CpuTime - CpuTimeStart) / CPU_TICKS, ModelTime, msg_send->sequence, msg_send->data[0].f);
|
||||
}
|
||||
#endif /* _DEBUG */
|
||||
/* Global Variables */
|
||||
struct socket skt;
|
||||
|
||||
static void * SendToIPPort(void *arg)
|
||||
{
|
||||
|
@ -128,7 +130,7 @@ static void * SendToIPPort(void *arg)
|
|||
msg_hton(msg);
|
||||
|
||||
/* Perform the actual write to the ip port */
|
||||
ret = SendPacket((char *) msg, MSG_LEN(msg->length));
|
||||
ret = socket_send(&skt, (char *) msg, len);
|
||||
if (ret < 0)
|
||||
OpalSetAsyncSendIconError(errno, SendID);
|
||||
else
|
||||
|
@ -175,8 +177,8 @@ static void * RecvFromIPPort(void *arg)
|
|||
|
||||
do {
|
||||
/* Receive message */
|
||||
n = RecvPacket((char *) msg, sizeof(buf), 1.0);
|
||||
if (n < 1) {
|
||||
ret = socket_recv(&skt, (char *) msg, sizeof(buf), 1.0);
|
||||
if (ret < 1) {
|
||||
ModelState = OpalGetAsyncModelState();
|
||||
if ((ModelState != STATE_RESET) && (ModelState != STATE_STOP)) {
|
||||
if (n == 0) /* timeout, so we continue silently */
|
||||
|
@ -271,7 +273,7 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
|
||||
/* Initialize socket */
|
||||
ret = InitSocket(IconCtrlStruct);
|
||||
ret = socket_init(&skt, IconCtrlStruct);
|
||||
if (ret != EOK) {
|
||||
OpalPrint("%s: ERROR: Initialization failed.\n", PROGNAME);
|
||||
exit(EXIT_FAILURE);
|
||||
|
@ -323,7 +325,8 @@ int main(int argc, char *argv[])
|
|||
OpalPrint("%s: ERROR: pthread_join (RecvFromIPPort), errno %d\n", PROGNAME, ret);
|
||||
|
||||
/* Close the ip port and shared memories */
|
||||
CloseSocket(IconCtrlStruct);
|
||||
socket_close(&skt, IconCtrlStruct);
|
||||
|
||||
OpalCloseAsyncMem (ASYNC_SHMEM_SIZE, ASYNC_SHMEM_NAME);
|
||||
OpalSystemCtrl_UnRegister(PRINT_SHMEM_NAME);
|
||||
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
/* Define RTLAB before including OpalPrint.h for messages to be sent
|
||||
|
@ -23,12 +22,7 @@
|
|||
#include "config.h"
|
||||
#include "socket.h"
|
||||
|
||||
/* Globals variables */
|
||||
struct sockaddr_in send_ad; /* Send address */
|
||||
struct sockaddr_in recv_ad; /* Receive address */
|
||||
int sd = -1; /* socket descriptor */
|
||||
|
||||
int InitSocket(Opal_GenAsyncParam_Ctrl IconCtrlStruct)
|
||||
int socket_init(struct socket *s, Opal_GenAsyncParam_Ctrl IconCtrlStruct)
|
||||
{
|
||||
struct ip_mreq mreq; /* Multicast group structure */
|
||||
unsigned char TTL = 1, LOOP = 0;
|
||||
|
@ -46,26 +40,26 @@ int InitSocket(Opal_GenAsyncParam_Ctrl IconCtrlStruct)
|
|||
OpalPrint("%s: Remote Port : %d\n", PROGNAME, (int) IconCtrlStruct.FloatParam[1]);
|
||||
|
||||
/* Initialize the socket */
|
||||
sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if (sd < 0) {
|
||||
s->sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if (s->sd < 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]);
|
||||
memset(&s->send_ad, 0, sizeof(s->send_ad));
|
||||
s->send_ad.sin_family = AF_INET;
|
||||
s->send_ad.sin_addr.s_addr = inet_addr(IconCtrlStruct.StringParam[0]);
|
||||
s->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]);
|
||||
memset(&s->recv_ad, 0, sizeof(s->recv_ad));
|
||||
s->recv_ad.sin_family = AF_INET;
|
||||
s->recv_ad.sin_addr.s_addr = INADDR_ANY;
|
||||
s->recv_ad.sin_port = htons((u_short) IconCtrlStruct.FloatParam[2]);
|
||||
|
||||
/* Bind local port and address to socket. */
|
||||
ret = bind(sd, (struct sockaddr *) &recv_ad, sizeof(struct sockaddr_in));
|
||||
ret = bind(s->sd, (struct sockaddr *) &s->recv_ad, sizeof(struct sockaddr_in));
|
||||
if (ret == -1) {
|
||||
OpalPrint("%s: ERROR: Could not bind local port to socket\n", PROGNAME);
|
||||
return EIO;
|
||||
|
@ -75,13 +69,13 @@ int InitSocket(Opal_GenAsyncParam_Ctrl IconCtrlStruct)
|
|||
|
||||
/* If sending to a multicast address */
|
||||
if ((inet_addr(IconCtrlStruct.StringParam[0]) & inet_addr("240.0.0.0")) == inet_addr("224.0.0.0")) {
|
||||
ret = setsockopt(sd, IPPROTO_IP, IP_MULTICAST_TTL, (char *) &TTL, sizeof(TTL));
|
||||
ret = setsockopt(s->sd, IPPROTO_IP, IP_MULTICAST_TTL, (char *) &TTL, sizeof(TTL));
|
||||
if (ret == -1) {
|
||||
OpalPrint("%s: ERROR: Could not set TTL for multicast send (%d)\n", PROGNAME, errno);
|
||||
return EIO;
|
||||
}
|
||||
|
||||
ret = setsockopt(sd, IPPROTO_IP, IP_MULTICAST_LOOP, (char *)&LOOP, sizeof(LOOP));
|
||||
ret = setsockopt(s->sd, IPPROTO_IP, IP_MULTICAST_LOOP, (char *)&LOOP, sizeof(LOOP));
|
||||
if (ret == -1) {
|
||||
OpalPrint("%s: ERROR: Could not set loopback for multicast send (%d)\n", PROGNAME, errno);
|
||||
return EIO;
|
||||
|
@ -97,7 +91,7 @@ int InitSocket(Opal_GenAsyncParam_Ctrl IconCtrlStruct)
|
|||
mreq.imr_interface.s_addr = INADDR_ANY;
|
||||
|
||||
/* Have the multicast socket join the multicast group */
|
||||
ret = setsockopt(sd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) &mreq, sizeof(mreq));
|
||||
ret = setsockopt(s->sd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) &mreq, sizeof(mreq));
|
||||
if (ret == -1) {
|
||||
OpalPrint("%s: ERROR: Could not join multicast group (%d)\n", PROGNAME, errno);
|
||||
return EIO;
|
||||
|
@ -115,39 +109,39 @@ int InitSocket(Opal_GenAsyncParam_Ctrl IconCtrlStruct)
|
|||
return EOK;
|
||||
}
|
||||
|
||||
int CloseSocket(Opal_GenAsyncParam_Ctrl IconCtrlStruct)
|
||||
int socket_close(struct socket *s, Opal_GenAsyncParam_Ctrl IconCtrlStruct)
|
||||
{
|
||||
if (sd < 0) {
|
||||
shutdown(sd, SHUT_RDWR);
|
||||
close(sd);
|
||||
if (s->sd < 0) {
|
||||
shutdown(s->sd, SHUT_RDWR);
|
||||
close(s->sd);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SendPacket(char* DataSend, int datalength)
|
||||
int socket_send(struct socket *s, char *data, int len)
|
||||
{
|
||||
if (sd < 0)
|
||||
if (s->sd < 0)
|
||||
return -1;
|
||||
|
||||
/* Send the packet */
|
||||
return sendto(sd, DataSend, datalength, 0, (struct sockaddr *)&send_ad, sizeof(send_ad));
|
||||
return sendto(s->sd, data, len, 0, (struct sockaddr *) &s->send_ad, sizeof(s->send_ad));
|
||||
}
|
||||
|
||||
int RecvPacket(char* DataRecv, int datalength, double timeout)
|
||||
int socket_recv(struct socket *s, char *data, int len, double timeout)
|
||||
{
|
||||
int len, ret;
|
||||
int ret;
|
||||
struct sockaddr_in client_ad;
|
||||
struct timeval tv;
|
||||
socklen_t client_ad_size = sizeof(client_ad);
|
||||
fd_set sd_set;
|
||||
|
||||
if (sd < 0)
|
||||
if (s->sd < 0)
|
||||
return -1;
|
||||
|
||||
/* Set the descriptor set for the select() call */
|
||||
FD_ZERO(&sd_set);
|
||||
FD_SET(sd, &sd_set);
|
||||
FD_SET(s->sd, &sd_set);
|
||||
|
||||
/* Set the tv structure to the correct timeout value */
|
||||
tv.tv_sec = (int) timeout;
|
||||
|
@ -157,14 +151,14 @@ int RecvPacket(char* DataRecv, int datalength, double timeout)
|
|||
* 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). */
|
||||
ret = select(sd+1, &sd_set, (fd_set *) 0, (fd_set *) 0, &tv);
|
||||
ret = select(s->sd + 1, &sd_set, (fd_set *) 0, (fd_set *) 0, &tv);
|
||||
switch (ret) {
|
||||
case -1: /* Error */
|
||||
return -1;
|
||||
case 0: /* We hit the timeout */
|
||||
return 0;
|
||||
default:
|
||||
if (!(FD_ISSET(sd, &sd_set))) {
|
||||
if (!(FD_ISSET(s->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);
|
||||
|
@ -172,9 +166,9 @@ int RecvPacket(char* DataRecv, int datalength, double timeout)
|
|||
}
|
||||
}
|
||||
|
||||
/* Clear the DataRecv array (in case we receive an incomplete packet) */
|
||||
memset(DataRecv, 0, datalength);
|
||||
/* Clear the data array (in case we receive an incomplete packet) */
|
||||
memset(data, 0, len);
|
||||
|
||||
/* Perform the reception */
|
||||
return recvfrom(sd, DataRecv, datalength, 0, (struct sockaddr *) &client_ad, &client_ad_size);
|
||||
return recvfrom(s->sd, data, len, 0, (struct sockaddr *) &client_ad, &client_ad_size);
|
||||
}
|
Loading…
Add table
Reference in a new issue