From 3b6e7ef70c92ac4bd07a69a11a4ff902e3fc92e3 Mon Sep 17 00:00:00 2001
From: Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
Date: Mon, 23 Nov 2015 16:44:01 +0100
Subject: [PATCH] moving generic node code to libs2ss to be reusable across
 server, send, receive, test and 3party executables

---
 server/.gitignore     |  1 +
 server/Makefile       | 74 ++++++++++++++++++++++++++-----------------
 server/include/node.h | 20 +++---------
 server/src/file.c     | 14 +++++++-
 server/src/gtfpga.c   | 15 ++++++++-
 server/src/ngsi.c     | 15 ++++++++-
 server/src/opal.c     | 15 ++++++++-
 server/src/server.c   | 17 ++--------
 server/src/socket.c   | 19 ++++++++++-
 9 files changed, 126 insertions(+), 64 deletions(-)

diff --git a/server/.gitignore b/server/.gitignore
index 5772b93b7..aff5c0002 100644
--- a/server/.gitignore
+++ b/server/.gitignore
@@ -2,6 +2,7 @@ logs/
 
 *.d
 *.o
+*.so
 *~
 
 server
diff --git a/server/Makefile b/server/Makefile
index f79198f26..c4a3cc3e5 100644
--- a/server/Makefile
+++ b/server/Makefile
@@ -1,72 +1,82 @@
+# Executables
 TARGETS = server send random receive test
 
-# Common objs
-OBJS  = path.o node.o hooks.o msg.o cfg.o
-# Helper libs
-OBJS += utils.o list.o hist.o log.o timing.o checks.o
+# Libraries
+LIBS = libs2ss.so
 
-VPATH = src
+# Common objs
+OBJS = path.o hooks.o cfg.o utils.o list.o hist.o log.o timing.o checks.o
+
+# Object files for libs2ss
+LIB_OBJS = msg.o node.o checks.o list.o
+
+# Source directories
+VPATH = src lib
 
 # Default debug level
 V ?= 2
 
 # Compiler and linker flags
 CC = gcc
-LDLIBS  = -pthread -lrt -lm -lconfig
-override CFLAGS += -std=gnu99 -Iinclude/ -MMD -Wall
-override CFLAGS += -D_POSIX_C_SOURCE=200809L -D_GNU_SOURCE=1 -DV=$(V)
+LDLIBS  = -pthread -lrt -lm -lconfig -ls2ss
+LDFLAGS = -Wl,-L.
+
+CFLAGS += -std=gnu99 -Iinclude/ -MMD -Wall
+CFLAGS += -D_POSIX_C_SOURCE=200809L -D_GNU_SOURCE=1 -DV=$(V)
 
 # Add more compiler flags
 ifdef DEBUG
-	override CFLAGS += -O0 -g
+	CFLAGS += -O0 -g
 else
-	override CFLAGS += -O3
+	CFLAGS += -O3
 endif
+
 ifneq (,$(shell which git))
-	override CFLAGS += -D_GIT_REV='"$(shell git rev-parse --short HEAD)"'
+	CFLAGS += -D_GIT_REV='"$(shell git rev-parse --short HEAD)"'
 endif
 
 ######## Node types ########
 
 # Enable file node type support
 ifndef DISABLE_FILE
-	override CFLAGS += -DENABLE_FILE
-	OBJS   += file.o
+	LIB_OBJS += file.o
 endif
 
 # Enable Socket node type when libnl3 is available
 ifeq ($(shell pkg-config libnl-3.0; echo $$?),0)
-	override CFLAGS += -DENABLE_SOCKET $(shell pkg-config --cflags libnl-3.0)
-	LDLIBS += -lnl-3 -lnl-route-3
-	OBJS   += nl.o tc.o if.o socket.o
+	LIB_OBJS   += socket.o nl.o tc.o if.o
+	LIB_CFLAGS += $(shell pkg-config --cflags libnl-3.0)
+	LIB_LDLIBS += -lnl-3 -lnl-route-3 
 endif
 
 # Enable GTFPGA support when libpci is available
 ifeq ($(shell pkg-config libpci; echo $$?),0)
-	override CFLAGS += -DENABLE_GTFPGA $(shell pkg-config --cflags libpci)
-	LDLIBS += $(shell pkg-config --libs libpci)
-	OBJS   += gtfpga.o
+	LIB_OBJS   += gtfpga.o
+	LIB_CFLAGS += $(shell pkg-config --cflags libpci)
+	LIB_LDLIBS += $(shell pkg-config --libs libpci)
 endif
 
 # Enable NGSI support
 ifeq ($(shell pkg-config libcurl jansson uuid; echo $$?),0)
-	override CFLAGS += -DENABLE_NGSI $(shell pkg-config --cflags libcurl jansson uuid)
-	LDLIBS += $(shell pkg-config --libs libcurl jansson uuid)
-	OBJS   += ngsi.o
+	LIB_OBJS   += ngsi.o
+	LIB_CFLAGS += $(shell pkg-config --cflags libcurl jansson uuid)
+	LIB_LDLIBS += $(shell pkg-config --libs libcurl jansson uuid)
 endif
 
 # Enable OPAL-RT Asynchronous Process support (will result in 32bit binary!!!)
 ifneq (,$(wildcard $(OPALDIR)/include_target/AsyncApi.h))
-	override CFLAGS += -m32 -DENABLE_OPAL_ASYNC
-	LDFLAGS += -m32 -Wl,-L/lib/i386-linux-gnu/,-L/usr/lib/i386-linux-gnu/
-	LDLIBS  += $(addprefix $(OPALDIR)/lib/redhawk/, libOpalAsyncApiCore.a libOpalCore.a libOpalUtils.a libirc.a)
-	OBJS    += opal.o
+	LIB_OBJS    += opal.o
+	LIB_CFLAGS  += -m32 -I$(OPALDIR)/include_target
+	LIB_LDFLAGS += -m32 -Wl,-L/lib/i386-linux-gnu/,-L/usr/lib/i386-linux-gnu/,-L$(OPALDIR)/lib/redhawk/
+	LIB_LDLIBS  += -lOpalAsyncApiCore -lOpalCore -lOpalUtils -lirc
 endif
 
-.PHONY: all clean strip protected
+######## Targets ########
+
+.PHONY: all clean install
 
 # Default target: build everything
-all: $(TARGETS)
+all: $(LIBS) $(TARGETS)
 
 # Dependencies for individual binaries
 server:  server.o  $(OBJS)
@@ -75,9 +85,15 @@ receive: receive.o $(OBJS)
 test:    test.o    $(OBJS)
 random:  random.o  msg.o utils.o timing.o log.o
 
+lib/%.o: 
+	$(CC) $(LIB_CFLAGS) -o $@ $^
+
+libs2ss.so: CFLAGS += -fPIC $(LIB_CFLAGS)
+libs2ss.so: $(LIB_OBJS)
+	$(CC) $(LIB_LDFLAGS) $(LIB_LDLIBS) -shared -o $@ $^
 
 clean:
-	$(RM) *~ *.o *.d
+	$(RM) *~ *.o *.d *.so
 	$(RM) $(TARGETS)
 
 # Include auto-generated dependencies
diff --git a/server/include/node.h b/server/include/node.h
index 7c3de43d3..6806236aa 100644
--- a/server/include/node.h
+++ b/server/include/node.h
@@ -27,14 +27,9 @@
 #include "list.h"
 
 /* Helper macros for virtual node type */
-#define REGISTER_NODE_TYPE(type, name, fnc)				\
-__attribute__((constructor)) void __register_node_ ## fnc () {		\
-	static struct node_type t = { name, type,			\
-					fnc ## _parse, fnc ## _print,	\
-					fnc ## _open,  fnc ## _close,	\
-					fnc ## _read,  fnc ## _write,	\
-					fnc ## _init,  fnc ## _deinit };\
-	list_push(&node_types, &t);					\
+#define REGISTER_NODE_TYPE(vt)				\
+__attribute__((constructor)) static void __register() {	\
+	list_push(&node_types, vt);			\
 }
 
 extern struct list node_types;
@@ -43,6 +38,8 @@ extern struct list node_types;
 struct node_type {
 	/** The unique name of this node. This must be allways the first member! */
 	const char *name;
+	/** A short description of this node type. Will be shown in help text. */
+	const char *description;
 	/** A list of all existing nodes of this type. */
 	struct list instances;
 	
@@ -58,13 +55,6 @@ struct node_type {
 	 */
 	int (*init)(int argc, char *argv[], struct settings *set);
 
-	enum {
-		BSD_SOCKET,		/**< BSD Socket API */
-		LOG_FILE,		/**< File IO */
-		OPAL_ASYNC,		/**< OPAL-RT Asynchronous Process Api */
-		GTFPGA,			/**< Xilinx ML507 GTFPGA card */
-		NGSI			/**< NGSI 9/10 HTTP RESTful API (FIRWARE ContextBroker) */
-	} type;				/**< Node type */
 	/** Global de-initialization per node type.
 	 *
 	 * This callback is invoked once per node-type.
diff --git a/server/src/file.c b/server/src/file.c
index c0241f50b..4b5385818 100644
--- a/server/src/file.c
+++ b/server/src/file.c
@@ -371,4 +371,16 @@ int file_write(struct node *n, struct msg *pool, int poolsize, int first, int cn
 	return i;
 }
 
-REGISTER_NODE_TYPE(LOG_FILE, "file", file)
\ No newline at end of file
+static struct node_type vt = {
+	.name		= "file",
+	.description	= "support for file log / replay node type",
+	.reverse	= file_reverse,
+	.parse		= file_parse,
+	.print		= file_print,
+	.open		= file_open,
+	.close		= file_close,
+	.read		= file_read,
+	.write		= file_write
+};
+
+REGISTER_NODE_TYPE(&vt)
\ No newline at end of file
diff --git a/server/src/gtfpga.c b/server/src/gtfpga.c
index 9a9d6a70c..c362a1ebd 100644
--- a/server/src/gtfpga.c
+++ b/server/src/gtfpga.c
@@ -267,4 +267,17 @@ int gtfpga_write(struct node *n, struct msg *pool, int poolsize, int first, int
 	return 0;
 }
 
-REGISTER_NODE_TYPE(GTFPGA, "gtfpga", gtfpga)
\ No newline at end of file
+static struct node_type vt = {
+	.name		= "gtfpga",
+	.description	= "GTFPGA PCIe card (libpci)",
+	.parse		= gtfpga_parse,
+	.print		= gtfpga_print,
+	.open		= gtfpga_open,
+	.close		= gtfpga_close,
+	.read		= gtfpga_read,
+	.write		= gtfpga_write,
+	.init		= gtfpga_init,
+	.deinit		= gtfpga_deinit
+};
+
+REGISTER_NODE_TYPE(&vt)
\ No newline at end of file
diff --git a/server/src/ngsi.c b/server/src/ngsi.c
index 51338fc23..1c4478cd5 100644
--- a/server/src/ngsi.c
+++ b/server/src/ngsi.c
@@ -586,4 +586,17 @@ int ngsi_write(struct node *n, struct msg *pool, int poolsize, int first, int cn
 	return ret ? 0 : cnt;
 }
 
-REGISTER_NODE_TYPE(NGSI, "ngsi", ngsi)
+static struct node_type vt = {
+	.name		= "ngsi",
+	.description	= "OMA Next Generation Services Interface 10 (libcurl, libjansson, libuuid)",
+	.parse		= ngsi_parse,
+	.print		= ngsi_print,
+	.open		= ngsi_open,
+	.close		= ngsi_close,
+	.read		= ngsi_read,
+	.write		= ngsi_write,
+	.init		= ngsi_init,
+	.deinit		= ngsi_deinit
+};
+
+REGISTER_NODE_TYPE(&vt)
diff --git a/server/src/opal.c b/server/src/opal.c
index aa875eae8..29a28cb2e 100644
--- a/server/src/opal.c
+++ b/server/src/opal.c
@@ -284,4 +284,17 @@ int opal_write(struct node *n, struct msg *pool, int poolsize, int first, int cn
 	return 1;
 }
 
-REGISTER_NODE_TYPE(OPAL_ASYNC, "opal", opal)
\ No newline at end of file
+static struct node_type vt = {
+	.name		= "opal",
+	.description	= "run as OPAL Asynchronous Process (libOpalAsyncApi)",
+	.parse		= opal_parse,
+	.print		= opal_print,
+	.open		= opal_open,
+	.close		= opal_close,
+	.read		= opal_read,
+	.write		= opal_write,
+	.init		= opal_init,
+	.deinit		= opal_deinit
+};
+
+REGISTER_NODE_TYPE(&vt)
\ No newline at end of file
diff --git a/server/src/server.c b/server/src/server.c
index 1f522cd49..92eebdbbf 100644
--- a/server/src/server.c
+++ b/server/src/server.c
@@ -107,21 +107,8 @@ static void usage(const char *name)
 	printf("  See in the RT-LAB User Guide for more information.\n\n");
 #endif
 	printf("Supported node types:\n");
-#ifdef ENABLE_FILE
-	printf(" - file: support for file log / replay node type\n");
-#endif
-#ifdef ENABLE_SOCKET
-	printf(" - socket: Network socket (libnl3)\n");
-#endif
-#ifdef ENABLE_GTFPGA
-	printf(" - gtfpga: GTFPGA PCIe card (libpci)\n");
-#endif
-#ifdef ENABLE_OPAL_ASYNC
-	printf(" - opal: run as OPAL Asynchronous Process (libOpalAsyncApi)\n");
-#endif
-#ifdef ENABLE_NGSI
-	printf(" - ngsi: OMA Next Generation Services Interface 10 (libcurl, libjansson, libuuid)\n");
-#endif
+	list_foreach(struct node_type *vt, &node_types)
+		printf(" - %s: %s\n", vt->name, vt->description);
 	printf("\n");
 	printf("Simulator2Simulator Server %s (built on %s %s)\n",
 		BLU(VERSION), MAG(__DATE__), MAG(__TIME__));
diff --git a/server/src/socket.c b/server/src/socket.c
index 3ef719070..20a4aec7b 100644
--- a/server/src/socket.c
+++ b/server/src/socket.c
@@ -35,6 +35,8 @@
 /** Linked list of interfaces */
 extern struct list interfaces;
 
+/* Forward declartions */
+static struct node_type vt;
 
 int socket_init(int argc, char * argv[], struct settings *set)
 { INDENT
@@ -473,4 +475,19 @@ int socket_parse_addr(const char *addr, struct sockaddr *saddr, enum socket_laye
 	return ret;
 }
 
-REGISTER_NODE_TYPE(BSD_SOCKET, "socket", socket)
+static struct node_type vt = {
+	.name		= "socket",
+	.description	= "Network socket (libnl3)",
+	.destroy	= socket_destroy,
+	.reverse	= socket_reverse,
+	.parse		= socket_parse,
+	.print		= socket_print,
+	.open		= socket_open,
+	.close		= socket_close,
+	.read		= socket_read,
+	.write		= socket_write,
+	.init		= socket_init,
+	.deinit		= socket_deinit
+};
+
+REGISTER_NODE_TYPE(&vt)