summaryrefslogtreecommitdiff
path: root/host/src/station.c
diff options
context:
space:
mode:
Diffstat (limited to 'host/src/station.c')
-rw-r--r--host/src/station.c125
1 files changed, 114 insertions, 11 deletions
diff --git a/host/src/station.c b/host/src/station.c
index 30501aa61b..55fe3522a3 100644
--- a/host/src/station.c
+++ b/host/src/station.c
@@ -26,11 +26,14 @@
#include "host/sci.h"
#include "host/station.h"
#ifndef UNIT_TEST
+#include "host/socket.h"
#include "host/syscall.h"
#else
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/un.h>
#endif
/* awfull, but needed */
@@ -64,6 +67,10 @@ static netclock_callback_t _ecos_tick_cb;
*/
int station_init(station_ctx_t *station)
{
+#ifdef STATION_SOCK
+ int sock_server_fd;
+#endif /* STATION_SOCK */
+
DBG_ASSERT(station);
if(station == NULL)
{
@@ -72,8 +79,14 @@ int station_init(station_ctx_t *station)
}
memset(station, '\0', sizeof(station_ctx_t));
+#ifdef STATION_SOCK
+ station->sock_fd = -1;
+ station->sock_pair_fd = -1;
+ sock_server_fd = -1;
+#else /* STATION_SOCK */
station->pipe_in_fd = -1;
station->pipe_out_fd = -1;
+#endif
station->pipe_log_fd = -1;
/* get station id */
@@ -85,17 +98,66 @@ int station_init(station_ctx_t *station)
/* build pipe names */
sprintf(station->pipe_log_name, "%s/%s_log_%d", STATION_PIPE_PATH, STATION_PIPE_PREFIX, station->id);
unlink(station->pipe_log_name);
+#ifndef STATION_SOCK
sprintf(station->pipe_in_name, "%s/%s_in_%d", STATION_PIPE_PATH, STATION_PIPE_PREFIX, station->id);
unlink(station->pipe_in_name);
sprintf(station->pipe_out_name, "%s/%s_out_%d", STATION_PIPE_PATH, STATION_PIPE_PREFIX, station->id);
unlink(station->pipe_out_name);
-
+#endif
+
/* open log */
if(mknod(station->pipe_log_name, 0770 | S_IFIFO, 0) < 0)
goto failed;
if((station->pipe_log_fd = open(station->pipe_log_name, O_RDWR | O_NONBLOCK, S_IRWXU | S_IRWXG)) < 0)
goto failed;
+#ifdef STATION_SOCK
+ /* build sock name */
+ sprintf(station->sock_name, "%s/%s_sock_%d", STATION_SOCK_PATH, STATION_SOCK_PREFIX, station->id);
+ unlink(station->sock_name);
+
+ /* create socket */
+#ifdef UNIT_TEST
+ int sock_fd[2];
+ socketpair(PF_UNIX, SOCK_STREAM, 0, sock_fd);
+ station->sock_fd = sock_fd[0];
+ station->sock_pair_fd = sock_fd[1];
+#else /* UNIT_TEST */
+ if((sock_server_fd = socket (PF_UNIX, SOCK_STREAM, 0)) < 0)
+ {
+ station_log(station, STATION_LOG_WARNING, STATION_LOGTYPE_STATION,
+ "%s: failed to create socket (errno=%d)",
+ __FUNCTION__, errno);
+ goto failed;
+ }
+
+ /* extend send buffer size */
+ {
+ int bufsize = STATION_MAX_SOCK_BUFFER_SIZE;
+ if(setsockopt (sock_server_fd, SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof(bufsize)) < 0)
+ {
+ station_log(station, STATION_LOG_WARNING, STATION_LOGTYPE_STATION,
+ "%s: failed to set buffer size to %d bytes (errno=%d)",
+ __FUNCTION__, bufsize, errno);
+ goto failed;
+ }
+ }
+
+ /* bind the socket */
+ {
+ struct sockaddr_un sockaddr;
+ sockaddr.sun_family = AF_UNIX;
+ strcpy (sockaddr.sun_path, station->sock_name);
+ if((bind (sock_server_fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr))) < 0)
+ {
+ station_log(station, STATION_LOG_WARNING, STATION_LOGTYPE_STATION,
+ "%s: bind to '%s' failed (errno=%d)",
+ __FUNCTION__, station->sock_name, errno);
+ goto failed;
+ }
+ }
+#endif /* UNIT_TEST */
+#else /* STATION_SOCK */
/* open in pipe */
if(mknod(station->pipe_in_name, 0770 | S_IFIFO, 0) < 0)
{
@@ -127,6 +189,8 @@ int station_init(station_ctx_t *station)
__FUNCTION__, station->pipe_out_name, errno);
goto failed;
}
+
+#endif /* STATION_SOCK */
/* init all contexts */
station->sci = &_my_sci;
@@ -143,6 +207,19 @@ int station_init(station_ctx_t *station)
/* init the random generator */
srand(station->id);
+#if (defined STATION_SOCK) && !defined(UNIT_TEST)
+ /* listen and accept connection */
+ listen(sock_server_fd, 1);
+ if((station->sock_fd = accept(sock_server_fd, NULL, NULL)) < 0)
+ {
+ station_log(station, STATION_LOG_WARNING, STATION_LOGTYPE_STATION,
+ "%s: accept failed (errno=%d)",
+ __FUNCTION__, errno);
+ goto failed;
+ }
+ close(sock_server_fd);
+#endif /* STATION_SOCK && !UNIT_TEST */
+
#ifndef UNIT_TEST
/* first call for tick */
station_ecos_set_itimer(station, TICK_HZ / 100);
@@ -151,18 +228,30 @@ int station_init(station_ctx_t *station)
return 0;
failed:
- if(station->pipe_out_fd >= 0)
+ if(station->pipe_log_fd >= 0)
+ close(station->pipe_log_fd);
+ unlink(station->pipe_log_name);
+ station->pipe_log_fd = -1;
+#ifdef STATION_SOCK
+ if(station->sock_fd >= 0)
+ close(station->sock_fd);
+ if(station->sock_pair_fd >= 0)
+ close(station->sock_pair_fd);
+ if(sock_server_fd >= 0)
+ close(sock_server_fd);
+ unlink(station->sock_name);
+ station->sock_fd = -1;
+ station->sock_pair_fd = -1;
+#else /* STATION_SOCK */
+ if(station->pipe_out_fd >= 0)
close(station->pipe_out_fd);
if(station->pipe_in_fd >= 0)
close(station->pipe_in_fd);
- if(station->pipe_log_fd >= 0)
- close(station->pipe_log_fd);
unlink(station->pipe_out_name);
unlink(station->pipe_in_name);
- unlink(station->pipe_log_name);
station->pipe_out_fd = -1;
station->pipe_in_fd = -1;
- station->pipe_log_fd = -1;
+#endif /* STATION_SOCK */
station->status = STATION_STATUS_ERROR;
return -1;
}
@@ -176,18 +265,28 @@ void station_down(station_ctx_t *station)
if((station == NULL)
|| (station->status == STATION_STATUS_INIT))
return;
-
+
+#ifdef STATION_SOCK
+ if(station->sock_fd >= 0)
+ close(station->sock_fd);
+ if(station->sock_pair_fd >= 0)
+ close(station->sock_pair_fd);
+ unlink(station->sock_name);
+ station->sock_fd = -1;
+ station->sock_pair_fd = -1;
+#else /* STATION_SOCK */
if(station->pipe_out_fd >= 0)
close(station->pipe_out_fd);
if(station->pipe_in_fd >= 0)
close(station->pipe_in_fd);
- if(station->pipe_log_fd >= 0)
- close(station->pipe_log_fd);
unlink(station->pipe_out_name);
unlink(station->pipe_in_name);
- unlink(station->pipe_log_name);
station->pipe_out_fd = -1;
station->pipe_in_fd = -1;
+#endif /* STATION_SOCK */
+ if(station->pipe_log_fd >= 0)
+ close(station->pipe_log_fd);
+ unlink(station->pipe_log_name);
station->pipe_log_fd = -1;
return;
}
@@ -247,10 +346,14 @@ int station_idle(station_ctx_t *station)
/* vait for next message with 1 second timeout */
FD_ZERO(&read_fds);
+#ifdef STATION_SOCK
+ FD_SET(station->sock_fd, &read_fds);
+#else /* STATION_SOCK */
FD_SET(station->pipe_in_fd, &read_fds);
+#endif /* STATION_SOCK */
timeout.tv_sec = 1;
timeout.tv_usec = 0;
- sel = select(station->pipe_in_fd + 1, &read_fds, NULL, NULL, &timeout);
+ sel = select(STATION_MAX_FD + 1, &read_fds, NULL, NULL, &timeout);
if(sel < 0)
{
station_log(station, STATION_LOG_WARNING, STATION_LOGTYPE_STATION, "%s select failed (errno=%d)", __FUNCTION__, errno);