Repository: eclipse-bluechi/bluechi (language: python)

Issue:
Build as a messaging library rather than 3 apps
## Please describe what you would like to see

Blue Chihuahua maybe should be delivered as a messaging library, rather than as a set of applications.  Experiment with changing the POC to be built as a library and tested with orch, client and node test programs.  If the team agrees with this approach, change the new project to be built as a library.


Discussion / hints:

Fix patch:
diff --git a/.clang-tidy b/.clang-tidy
index 8eb81445b8..4e4325d8a4 100644
--- a/.clang-tidy
+++ b/.clang-tidy
@@ -14,7 +14,7 @@ Checks: >
     -altera-unroll-loops,
     -altera-id-dependent-backward-branch,
     -bugprone-easily-swappable-parameters,
-
+    -altera-struct-pack-align,
 
 # Turn all the warnings from the checks above into errors.,
 WarningsAsErrors: "*"
diff --git a/Makefile b/Makefile
index c4483a17e3..8a2cdddcf7 100644
--- a/Makefile
+++ b/Makefile
@@ -1,18 +1,14 @@
+
+ALL_SRC_FILES = 'find . -name "*.[ch]" ! -path "./binchihua/src/ini/*" ! -path "./binchihua/test/**" ! -path "./builddir/**" -print0'
+
 fmt:
-	for file in ./src/**/*.[ch] ; do \
-		clang-format -i --sort-includes $${file} ; \
-	done
+	eval $(ALL_SRC_FILES) | xargs -0 -I {} clang-format -i --sort-includes {}
 
 check-fmt:
-	for file in ./src/**/*.[ch] ; do \
-		clang-format --dry-run -Werror $${file} ; \
-		if [ $$? -ne 0 ] ; then \
-			exit 1 ; \
-		fi ; \
-	done
+	eval $(ALL_SRC_FILES) | xargs -0 -I {} clang-format  --dry-run -Werror {}
 
 lint: 
-	find . -name "*.[ch]" ! -path "./src/ini/*" ! -path "./test/**" -print0 | xargs -0 -I {} clang-tidy --quiet {} -- -D_GNU_SOURCE
+	eval $(ALL_SRC_FILES) | xargs -0 -I {} clang-tidy --quiet {} -- -D_GNU_SOURCE
 
 lint-fix: 
-	find . -name "*.[ch]" ! -path "./src/ini/*" ! -path "./test/**" -print0 | xargs -0 -I {} clang-tidy --quiet {} --fix -- -D_GNU_SOURCE
+	eval $(ALL_SRC_FILES) | xargs -0 -I {} clang-tidy --quiet {} --fix -- -D_GNU_SOURCE
diff --git a/binchihua/meson.build b/binchihua/meson.build
new file mode 100644
index 0000000000..e7275444fe
--- /dev/null
+++ b/binchihua/meson.build
@@ -0,0 +1,13 @@
+# internal dependencies
+common_inc = include_directories('src/common')
+common_src = files('src/common/parse-util.c')
+ini_inc = include_directories('src/ini')
+ini_src = files('src/ini/ini.c')
+
+# build each binary
+subdir('src/client')
+subdir('src/node')
+subdir('src/orch')
+
+# build test binaries
+subdir('test/common')
\ No newline at end of file
diff --git a/src/client/client.c b/binchihua/src/client/client.c
similarity index 100%
rename from src/client/client.c
rename to binchihua/src/client/client.c
diff --git a/src/client/meson.build b/binchihua/src/client/meson.build
similarity index 100%
rename from src/client/meson.build
rename to binchihua/src/client/meson.build
diff --git a/src/common/list.h b/binchihua/src/common/list.h
similarity index 100%
rename from src/common/list.h
rename to binchihua/src/common/list.h
diff --git a/src/common/opt.h b/binchihua/src/common/opt.h
similarity index 100%
rename from src/common/opt.h
rename to binchihua/src/common/opt.h
diff --git a/src/common/parse-util.c b/binchihua/src/common/parse-util.c
similarity index 100%
rename from src/common/parse-util.c
rename to binchihua/src/common/parse-util.c
diff --git a/src/common/parse-util.h b/binchihua/src/common/parse-util.h
similarity index 100%
rename from src/common/parse-util.h
rename to binchihua/src/common/parse-util.h
diff --git a/src/ini/ini.c b/binchihua/src/ini/ini.c
similarity index 100%
rename from src/ini/ini.c
rename to binchihua/src/ini/ini.c
diff --git a/src/ini/ini.h b/binchihua/src/ini/ini.h
similarity index 100%
rename from src/ini/ini.h
rename to binchihua/src/ini/ini.h
diff --git a/src/node/meson.build b/binchihua/src/node/meson.build
similarity index 86%
rename from src/node/meson.build
rename to binchihua/src/node/meson.build
index 2a9341ab3d..74ec20b857 100644
--- a/src/node/meson.build
+++ b/binchihua/src/node/meson.build
@@ -1,7 +1,6 @@
 # node build configuration
 
 node_src = [
-  'dbus.c',
   'node.c',
   'opt.c'
 ]
@@ -16,5 +15,6 @@ executable(
   dependencies: [
     systemd_dep
   ],
+  link_with: blue_chihuahua_shared,
   install: true
 )
diff --git a/binchihua/src/node/node.c b/binchihua/src/node/node.c
new file mode 100644
index 0000000000..04700e13a0
--- /dev/null
+++ b/binchihua/src/node/node.c
@@ -0,0 +1,25 @@
+#include "../../../libchihua-msg/include/node.h"
+#include "opt.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int main(int argc, char *argv[]) {
+        fprintf(stdout, "Hello from node!\n");
+
+        struct sockaddr_in host;
+        memset(&host, 0, sizeof(host));
+        host.sin_family = AF_INET;
+        host.sin_addr.s_addr = htonl(INADDR_ANY);
+        host.sin_port = 0;
+
+        get_opts(argc, argv, &host);
+
+        NodeParams node_params = { .orch_addr = &host };
+        _cleanup_node_ Node *node = node_new(&node_params);
+        if (node_start(node)) {
+                return EXIT_SUCCESS;
+        }
+        return EXIT_FAILURE;
+}
\ No newline at end of file
diff --git a/src/node/opt.c b/binchihua/src/node/opt.c
similarity index 100%
rename from src/node/opt.c
rename to binchihua/src/node/opt.c
diff --git a/src/node/opt.h b/binchihua/src/node/opt.h
similarity index 100%
rename from src/node/opt.h
rename to binchihua/src/node/opt.h
diff --git a/src/orch/meson.build b/binchihua/src/orch/meson.build
similarity index 87%
rename from src/orch/meson.build
rename to binchihua/src/orch/meson.build
index b43a3a0b0d..982848f58d 100644
--- a/src/orch/meson.build
+++ b/binchihua/src/orch/meson.build
@@ -3,7 +3,6 @@
 orch_src = [
   'orch.c',
   'opt.c',
-  'controller.c'
 ]
 orch_src += ini_src
 orch_src += common_src
@@ -18,5 +17,6 @@ executable(
   dependencies: [
     systemd_dep
   ],
+  link_with: blue_chihuahua_shared,
   install: true
 )
diff --git a/src/orch/opt.c b/binchihua/src/orch/opt.c
similarity index 100%
rename from src/orch/opt.c
rename to binchihua/src/orch/opt.c
diff --git a/src/orch/opt.h b/binchihua/src/orch/opt.h
similarity index 100%
rename from src/orch/opt.h
rename to binchihua/src/orch/opt.h
diff --git a/binchihua/src/orch/orch.c b/binchihua/src/orch/orch.c
new file mode 100644
index 0000000000..e69febc849
--- /dev/null
+++ b/binchihua/src/orch/orch.c
@@ -0,0 +1,37 @@
+#include "../../../libchihua-msg/include/orchestrator.h"
+#include "../ini/ini.h"
+#include "opt.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+/* A function that takes care of printing the lines of the ini file  */
+// NOLINTNEXTLINE
+static int ini_handler_func(void *user, const char *section, const char *name, const char *value) {
+        printf("[%s] %s = %s\n", section, name, value);
+        return EXIT_FAILURE;
+}
+
+int main(int argc, char *argv[]) {
+        fprintf(stdout, "Hello from orchestrator!\n");
+
+        uint16_t accept_port = 0;
+        char *config_path = NULL;
+
+        get_opts(argc, argv, &accept_port, &config_path);
+
+        OrchestratorParams orch_params = { .port = accept_port };
+        _cleanup_orchestrator_ Orchestrator *orchestrator = orch_new(&orch_params);
+        if (orch_start(orchestrator)) {
+                return EXIT_SUCCESS;
+        }
+
+        // TODO: move upwards and implement ini to OrchestratorParams in ini_handler_func
+        int r = ini_parse(config_path, ini_handler_func, NULL);
+        if (r < 0) {
+                fprintf(stderr, "Failed to parse INI file: %s\n", config_path);
+                return EXIT_FAILURE;
+        }
+
+        return EXIT_FAILURE;
+}
\ No newline at end of file
diff --git a/libchihua-msg/include/common/memory.h b/libchihua-msg/include/common/memory.h
new file mode 100644
index 0000000000..f77ce7893f
--- /dev/null
+++ b/libchihua-msg/include/common/memory.h
@@ -0,0 +1,6 @@
+#ifndef _BLUE_CHIHUAHUA_LIB_COMMON_MEMORY
+#define _BLUE_CHIHUAHUA_LIB_COMMON_MEMORY
+
+#define _cleanup_(x) __attribute__((__cleanup__(x)))
+
+#endif
\ No newline at end of file
diff --git a/libchihua-msg/include/node.h b/libchihua-msg/include/node.h
new file mode 100644
index 0000000000..6630a4342f
--- /dev/null
+++ b/libchihua-msg/include/node.h
@@ -0,0 +1,28 @@
+#ifndef _BLUE_CHIHUAHUA_LIB_NODE
+#define _BLUE_CHIHUAHUA_LIB_NODE
+
+#include "./common/memory.h"
+
+#include <netinet/in.h>
+#include <stdbool.h>
+#include <sys/socket.h>
+#include <systemd/sd-event.h>
+
+typedef struct {
+        struct sockaddr_in *orch_addr;
+} NodeParams;
+
+typedef struct {
+        char *orch_addr;
+        sd_event *event_loop;
+} Node;
+
+Node *node_new(const NodeParams *params);
+void node_unrefp(Node **node);
+
+bool node_start(const Node *node);
+bool node_stop(const Node *node);
+
+#define _cleanup_node_ _cleanup_(node_unrefp)
+
+#endif
\ No newline at end of file
diff --git a/libchihua-msg/include/node/peer-dbus.h b/libchihua-msg/include/node/peer-dbus.h
new file mode 100644
index 0000000000..ddb052d84d
--- /dev/null
+++ b/libchihua-msg/include/node/peer-dbus.h
@@ -0,0 +1,26 @@
+#ifndef _BLUE_CHIHUAHUA_LIB_NODE_PEER_DBUS
+#define _BLUE_CHIHUAHUA_LIB_NODE_PEER_DBUS
+
+#include "../common/memory.h"
+
+#include <netinet/in.h>
+#include <stdbool.h>
+#include <sys/socket.h>
+#include <systemd/sd-bus.h>
+#include <systemd/sd-event.h>
+
+typedef struct {
+        char *peer_dbus_addr;
+        sd_bus *internal_dbus;
+} PeerDBus;
+
+char *assemble_address(const struct sockaddr_in *addr);
+
+PeerDBus *peer_dbus_new(const char *peer_addr, sd_event *event);
+void peer_dbus_unrefp(PeerDBus **dbus);
+
+bool peer_dbus_start(PeerDBus *dbus);
+
+#define _cleanup_peer_dbus_ _cleanup_(peer_dbus_unrefp)
+
+#endif
\ No newline at end of file
diff --git a/libchihua-msg/include/orchestrator.h b/libchihua-msg/include/orchestrator.h
new file mode 100644
index 0000000000..a3a7013f63
--- /dev/null
+++ b/libchihua-msg/include/orchestrator.h
@@ -0,0 +1,27 @@
+#ifndef _BLUE_CHIHUAHUA_LIB_ORCHESTRATOR
+#define _BLUE_CHIHUAHUA_LIB_ORCHESTRATOR
+
+#include "./common/memory.h"
+
+#include <inttypes.h>
+#include <stdbool.h>
+#include <systemd/sd-event.h>
+
+typedef struct {
+        uint16_t port;
+} OrchestratorParams;
+
+typedef struct {
+        uint16_t accept_port;
+        sd_event *event_loop;
+} Orchestrator;
+
+Orchestrator *orch_new(const OrchestratorParams *params);
+void orch_unrefp(Orchestrator **orchestrator);
+
+bool orch_start(const Orchestrator *orchestrator);
+bool orch_stop(const Orchestrator *orchestrator);
+
+#define _cleanup_orchestrator_ _cleanup_(orch_unrefp)
+
+#endif
\ No newline at end of file
diff --git a/libchihua-msg/include/orchestrator/controller.h b/libchihua-msg/include/orchestrator/controller.h
new file mode 100644
index 0000000000..f65f066f38
--- /dev/null
+++ b/libchihua-msg/include/orchestrator/controller.h
@@ -0,0 +1,23 @@
+#ifndef _BLUE_CHIHUAHUA_LIB_ORCHESTRATOR_CONTROLLER
+#define _BLUE_CHIHUAHUA_LIB_ORCHESTRATOR_CONTROLLER
+
+#include "../common/memory.h"
+
+#include <stdbool.h>
+#include <systemd/sd-event.h>
+
+// TODO: include common/dbus and cleanup event_source in _new
+
+typedef struct {
+        int accept_fd;
+        sd_event_source *sd_event_source;
+} Controller;
+
+Controller *controller_new(uint16_t port, sd_event *event, sd_event_io_handler_t accept_handler);
+void controller_unrefp(Controller **controller);
+
+sd_event_io_handler_t default_accept_handler();
+
+#define _cleanup_controller_ _cleanup_(controller_unrefp)
+
+#endif
\ No newline at end of file
diff --git a/libchihua-msg/meson.build b/libchihua-msg/meson.build
new file mode 100644
index 0000000000..5670d5931f
--- /dev/null
+++ b/libchihua-msg/meson.build
@@ -0,0 +1,38 @@
+libchihua_src = [
+    'include/common/memory.h',
+    'include/node.h',
+    'include/node/peer-dbus.h',
+    'include/orchestrator.h',
+    'include/orchestrator/controller.h',
+
+    'src/common/memory.h',
+    'src/common/dbus.h',
+    'src/node.c',
+    'src/node/peer-dbus.c',
+    'src/orchestrator.c',
+    'src/orchestrator/controller.c',
+]
+
+# We use libtool-version numbers because it's easier to understand.
+# Before making a release, the libruntime_so_*
+# numbers should be modified. The components are of the form C:R:A.
+# a) If binary compatibility has been broken (eg removed or changed interfaces)
+#    change to C+1:0:0.
+# b) If interfaces have been changed or added, but binary compatibility has
+#    been preserved, change to C+1:0:A+1
+# c) If the interface is the same as the previous version, change to C:R+1:A
+libruntime_lt_c=1
+libruntime_lt_r=0
+libruntime_lt_a=0
+
+libruntime_so_version = '@0@.@1@.@2@'.format((libruntime_lt_c - libruntime_lt_a),
+                                              libruntime_lt_a,
+                                              libruntime_lt_r)
+
+blue_chihuahua_shared = shared_library('-chihua-msg',
+                            libchihua_src,
+                            dependencies: [
+                                systemd_dep
+                            ],
+                            version : libruntime_so_version,
+                            install : true)
\ No newline at end of file
diff --git a/src/common/dbus.h b/libchihua-msg/src/common/dbus.h
similarity index 100%
rename from src/common/dbus.h
rename to libchihua-msg/src/common/dbus.h
diff --git a/src/common/memory.h b/libchihua-msg/src/common/memory.h
similarity index 91%
rename from src/common/memory.h
rename to libchihua-msg/src/common/memory.h
index 637e0814dd..4b1eb99d12 100644
--- a/src/common/memory.h
+++ b/libchihua-msg/src/common/memory.h
@@ -1,6 +1,8 @@
 #ifndef _BLUE_CHIHUAHUA_COMMON_MEMORY
 #define _BLUE_CHIHUAHUA_COMMON_MEMORY
 
+#include "../../include/common/memory.h"
+
 #include <stdlib.h>
 #include <unistd.h>
 
@@ -23,8 +25,6 @@ static inline void freep(void *p) {
 
 #define malloc0(n) (calloc(1, (n) ?: 1))
 
-#define _cleanup_(x) __attribute__((__cleanup__(x)))
-
 #define _cleanup_free_ _cleanup_(freep)
 #define _cleanup_fd_ _cleanup_(closep)
 
diff --git a/libchihua-msg/src/node.c b/libchihua-msg/src/node.c
new file mode 100644
index 0000000000..47d0f66ba8
--- /dev/null
+++ b/libchihua-msg/src/node.c
@@ -0,0 +1,81 @@
+#include "../include/node.h"
+#include "../include/node/peer-dbus.h"
+#include "./common/dbus.h"
+
+#include <stdio.h>
+
+Node *node_new(const NodeParams *params) {
+        fprintf(stdout, "Creating Node...\n");
+
+        int r = 0;
+        _cleanup_sd_event_ sd_event *event = NULL;
+        r = sd_event_default(&event);
+        if (r < 0) {
+                fprintf(stderr, "Failed to create event loop: %s\n", strerror(-r));
+                return NULL;
+        }
+
+        char *orch_addr = assemble_address(params->orch_addr);
+        if (orch_addr == NULL) {
+                return NULL;
+        }
+
+        Node *n = malloc0(sizeof(Node));
+        n->event_loop = steal_pointer(&event);
+        n->orch_addr = orch_addr;
+
+        return n;
+}
+
+void node_unrefp(Node **node) {
+        fprintf(stdout, "Freeing allocated memory of Orchestrator...\n");
+        if (node == NULL) {
+                return;
+        }
+        if ((*node)->event_loop != NULL) {
+                fprintf(stdout, "Freeing allocated sd-event of Orchestrator...\n");
+                sd_event_unrefp(&(*node)->event_loop);
+        }
+        if ((*node)->orch_addr != NULL) {
+                fprintf(stdout, "Freeing allocated orch_addr of Orchestrator...\n");
+                freep((*node)->orch_addr);
+        }
+
+        free(*node);
+}
+
+bool node_start(const Node *node) {
+        fprintf(stdout, "Starting Node...\n");
+
+        if (node == NULL) {
+                return false;
+        }
+
+        _cleanup_peer_dbus_ PeerDBus *orch_dbus = peer_dbus_new(node->orch_addr, node->event_loop);
+        if (orch_dbus == NULL) {
+                return false;
+        }
+        bool started_successful = peer_dbus_start(orch_dbus);
+        if (!started_successful) {
+                return false;
+        }
+
+        int r = 0;
+        r = sd_event_loop(node->event_loop);
+        if (r < 0) {
+                fprintf(stderr, "Starting event loop failed: %s\n", strerror(-r));
+                return false;
+        }
+
+        return true;
+}
+
+bool node_stop(const Node *node) {
+        fprintf(stdout, "Stopping Node...\n");
+
+        if (node == NULL) {
+                return false;
+        }
+
+        return true;
+}
diff --git a/libchihua-msg/src/node/peer-dbus.c b/libchihua-msg/src/node/peer-dbus.c
new file mode 100644
index 0000000000..17b8625e41
--- /dev/null
+++ b/libchihua-msg/src/node/peer-dbus.c
@@ -0,0 +1,96 @@
+#include "../../include/node/peer-dbus.h"
+#include "../common/dbus.h"
+
+#include <arpa/inet.h>
+#include <stdio.h>
+
+char *assemble_address(const struct sockaddr_in *addr) {
+        if (addr == NULL) {
+                fprintf(stderr, "Can not assemble an empty address\n");
+                return NULL;
+        }
+
+        char *dbus_addr = NULL;
+        int r = asprintf(&dbus_addr, "tcp:host=%s,port=%d", inet_ntoa(addr->sin_addr), ntohs(addr->sin_port));
+        if (r < 0) {
+                fprintf(stderr, "Out of memory\n");
+                return NULL;
+        }
+        return dbus_addr;
+}
+
+PeerDBus *peer_dbus_new(const char *peer_addr, sd_event *event) {
+        if (peer_addr == NULL) {
+                fprintf(stderr, "Peer address must be initialized\n");
+                return NULL;
+        }
+        if (event == NULL) {
+                fprintf(stderr, "Event loop must be initialized\n");
+                return NULL;
+        }
+
+        int r = 0;
+        _cleanup_sd_bus_ sd_bus *dbus = NULL;
+
+        r = sd_bus_new(&dbus);
+        if (r < 0) {
+                fprintf(stderr, "Failed to create bus: %s\n", strerror(-r));
+                return NULL;
+        }
+        (void) sd_bus_set_description(dbus, "orchestrator");
+
+        /* we trust everything from the orchestrator, there is only one peer anyway */
+        r = sd_bus_set_trusted(dbus, true);
+        if (r < 0) {
+                fprintf(stderr, "Failed to trust orchestrator: %s\n", strerror(-r));
+                return NULL;
+        }
+
+        r = sd_bus_set_address(dbus, peer_addr);
+        if (r < 0) {
+                fprintf(stderr, "Failed to set address: %s\n", strerror(-r));
+                return NULL;
+        }
+
+        r = sd_bus_attach_event(dbus, event, SD_EVENT_PRIORITY_NORMAL);
+        if (r < 0) {
+                fprintf(stderr, "Failed to attach bus to event: %s\n", strerror(-r));
+                return NULL;
+        }
+
+        char *dbus_addr = NULL;
+        r = asprintf(&dbus_addr, "%s", peer_addr);
+        if (r < 0) {
+                fprintf(stderr, "Out of memory\n");
+                return NULL;
+        }
+
+        PeerDBus *p = malloc0(sizeof(PeerDBus));
+        p->peer_dbus_addr = dbus_addr;
+        p->internal_dbus = steal_pointer(&dbus);
+
+        return p;
+}
+
+void peer_dbus_unrefp(PeerDBus **dbus) {
+        fprintf(stdout, "Freeing allocated memory of PeerDBus...\n");
+        if (dbus == NULL) {
+                return;
+        }
+        if ((*dbus)->peer_dbus_addr != NULL) {
+                fprintf(stdout, "Freeing allocated sd-event-source of Controller...\n");
+                freep((*dbus)->peer_dbus_addr);
+        }
+        if ((*dbus)->internal_dbus != NULL) {
+                fprintf(stdout, "Freeing allocated internal dbus of PeerDBus...\n");
+                sd_bus_unrefp(&(*dbus)->internal_dbus);
+        }
+        free(*dbus);
+}
+
+bool peer_dbus_start(PeerDBus *dbus) {
+        if (dbus == NULL) {
+                return false;
+        }
+        return sd_bus_start(dbus->internal_dbus) >= 0;
+}
diff --git a/libchihua-msg/src/orchestrator.c b/libchihua-msg/src/orchestrator.c
new file mode 100644
index 0000000000..4a2ffd4cf5
--- /dev/null
+++ b/libchihua-msg/src/orchestrator.c
@@ -0,0 +1,70 @@
+#include "../include/orchestrator.h"
+#include "../include/orchestrator/controller.h"
+#include "./common/dbus.h"
+
+#include <stdio.h>
+#include <string.h>
+
+Orchestrator *orch_new(const OrchestratorParams *params) {
+        fprintf(stdout, "Creating Orchestrator...\n");
+
+        int r = 0;
+        _cleanup_sd_event_ sd_event *event = NULL;
+        r = sd_event_default(&event);
+        if (r < 0) {
+                fprintf(stderr, "Failed to create event loop: %s\n", strerror(-r));
+                return NULL;
+        }
+
+        Orchestrator *o = malloc0(sizeof(Orchestrator));
+        o->event_loop = steal_pointer(&event);
+        o->accept_port = params->port;
+
+        return o;
+}
+
+void orch_unrefp(Orchestrator **orchestrator) {
+        fprintf(stdout, "Freeing allocated memory of Orchestrator...\n");
+        if (orchestrator == NULL) {
+                return;
+        }
+        if ((*orchestrator)->event_loop != NULL) {
+                fprintf(stdout, "Freeing allocated sd-event of Orchestrator...\n");
+                sd_event_unrefp(&(*orchestrator)->event_loop);
+        }
+        free(*orchestrator);
+}
+
+bool orch_start(const Orchestrator *orchestrator) {
+        fprintf(stdout, "Starting Orchestrator...\n");
+
+        if (orchestrator == NULL) {
+                return false;
+        }
+        if (orchestrator->event_loop == NULL) {
+                return false;
+        }
+
+        _cleanup_controller_ Controller *c = NULL;
+        // NOLINTNEXTLINE
+        c = controller_new(orchestrator->accept_port, orchestrator->event_loop, default_accept_handler());
+
+        int r = 0;
+        r = sd_event_loop(orchestrator->event_loop);
+        if (r < 0) {
+                fprintf(stderr, "Starting event loop failed: %s\n", strerror(-r));
+                return false;
+        }
+
+        return true;
+}
+
+bool orch_stop(const Orchestrator *orchestrator) {
+        fprintf(stdout, "Stopping Orchestrator...\n");
+
+        if (orchestrator == NULL) {
+                return false;
+        }
+
+        return true;
+}
diff --git a/src/orch/controller.c b/libchihua-msg/src/orchestrator/controller.c
similarity index 59%
rename from src/orch/controller.c
rename to libchihua-msg/src/orchestrator/controller.c
index a7c3ea3a12..e77ec3b50d 100644
--- a/src/orch/controller.c
+++ b/libchihua-msg/src/orchestrator/controller.c
@@ -1,13 +1,13 @@
-#include "controller.h"
+#include "../../include/orchestrator/controller.h"
+#include "../common/dbus.h"
 
 #include <errno.h>
 #include <netinet/in.h>
-#include <stdbool.h>
 #include <stdio.h>
-#include <stdlib.h>
+#include <string.h>
 #include <sys/socket.h>
 
-int create_master_socket(const uint16_t port) {
+static int create_master_socket(uint16_t port) {
         struct sockaddr_in servaddr;
 
         int fd = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
@@ -36,13 +36,60 @@ int create_master_socket(const uint16_t port) {
 
         if ((listen(fd, SOMAXCONN)) != 0) {
                 int errsv = errno;
-                fprintf(stderr, "Failed to listed socket: %m\n");
+                fprintf(stderr, "Failed to listen to socket: %m\n");
                 return -errsv;
         }
 
         return fd;
 }
 
+Controller *controller_new(uint16_t port, sd_event *event, sd_event_io_handler_t accept_handler) {
+        fprintf(stdout, "Creating Controller...\n");
+
+        int r = 0;
+        _cleanup_sd_event_source_ sd_event_source *event_source = NULL;
+
+        int accept_fd = create_master_socket(port);
+        if (accept_fd < 0) {
+                return NULL;
+        }
+
+        r = sd_event_add_io(event, &event_source, accept_fd, EPOLLIN, accept_handler, NULL);
+        if (r < 0) {
+                fprintf(stderr, "Failed to add io event: %s\n", strerror(-r));
+                return NULL;
+        }
+
+        r = sd_event_source_set_io_fd_own(event_source, true);
+        if (r < 0) {
+                fprintf(stderr, "Failed to set io fd own: %s\n", strerror(-r));
+                return NULL;
+        }
+
+        (void) sd_event_source_set_description(event_source, "master-socket");
+
+        Controller *c = malloc0(sizeof(Controller));
+        c->accept_fd = accept_fd;
+        c->sd_event_source = steal_pointer(&event_source);
+
+        return c;
+}
+
+void controller_unrefp(Controller **controller) {
+        fprintf(stdout, "Freeing allocated memory of Controller...\n");
+        if (controller == NULL) {
+                return;
+        }
+        if ((*controller)->sd_event_source != NULL) {
+                fprintf(stdout, "Freeing allocated sd-event-source of Controller...\n");
+                sd_event_source_unrefp(&(*controller)->sd_event_source);
+        }
+        if ((*controller)->accept_fd >= 0) {
+                closep(&(*controller)->accept_fd);
+        }
+        free(*controller);
+}
+
 // NOLINTNEXTLINE
 static int accept_handler(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
         _cleanup_fd_ int nfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK | SOCK_CLOEXEC);
@@ -62,25 +109,6 @@ static int accept_handler(sd_event_source *s, int fd, uint32_t revents, void *us
         return 0;
 }
 
-int controller_setup(int accept_fd, uint16_t port, sd_event *event, sd_event_source *event_source) {
-        accept_fd = create_master_socket(port);
-        if (accept_fd < 0) {
-                return -1;
-        }
-
-        int r = sd_event_add_io(event, &event_source, accept_fd, EPOLLIN, accept_handler, NULL);
-        if (r < 0) {
-                fprintf(stderr, "Failed to add io event: %s\n", strerror(-r));
-                return -1;
-        }
-
-        r = sd_event_source_set_io_fd_own(event_source, true);
-        if (r < 0) {
-                fprintf(stderr, "Failed to set io fd own: %s\n", strerror(-r));
-                return -1;
-        }
-
-        (void) sd_event_source_set_description(event_source, "master-socket");
-
-        return 0;
-}
+sd_event_io_handler_t default_accept_handler() {
+        return &accept_handler;
+}
\ No newline at end of file
diff --git a/meson.build b/meson.build
index 9f3b25288b..37756a4f9f 100644
--- a/meson.build
+++ b/meson.build
@@ -16,25 +16,8 @@ add_global_arguments('-D_GNU_SOURCE', language : 'c')
 # external dependencies
 systemd_dep = dependency('libsystemd')
 
+# build shared library
+subdir('libchihua-msg')
 
-# internal dependencies
-common_inc = include_directories('src/common')
-common_src = files('src/common/parse-util.c')
-ini_inc = include_directories('src/ini')
-ini_src = files('src/ini/ini.c')
-
-
-# client
-subdir('src/client')
-
-
-# node
-subdir('src/node')
-
-
-# orch
-subdir('src/orch')
-
-
-# tests
-subdir('test/common')
+# build binaries
+subdir('binchihua')
diff --git a/src/node/dbus.c b/src/node/dbus.c
deleted file mode 100644
index 613f5d7786..0000000000
--- a/src/node/dbus.c
+++ /dev/null
@@ -1,45 +0,0 @@
-#include "dbus.h"
-
-#include <arpa/inet.h>
-#include <stdbool.h>
-#include <stdio.h>
-
-int setup_peer_dbus(sd_bus *dbus, const struct sockaddr_in *addr) {
-        int r = 0;
-
-        r = sd_bus_new(&dbus);
-        if (r < 0) {
-                fprintf(stderr, "Failed to create bus: %s\n", strerror(-r));
-                return -1;
-        }
-        (void) sd_bus_set_description(dbus, "orchestrator");
-
-        /* we trust everything from the orchestrator, there is only one peer anyway */
-        r = sd_bus_set_trusted(dbus, true);
-        if (r < 0) {
-                fprintf(stderr, "Failed to trust orchestrator: %s\n", strerror(-r));
-                return -1;
-        }
-
-        _cleanup_free_ char *dbus_addr = NULL;
-        r = asprintf(&dbus_addr, "tcp:host=%s,port=%d", inet_ntoa(addr->sin_addr), ntohs(addr->sin_port));
-        if (r < 0) {
-                fprintf(stderr, "Out of memory\n");
-                return -1;
-        }
-
-        r = sd_bus_set_address(dbus, dbus_addr);
-        if (r < 0) {
-                fprintf(stderr, "Failed to set address: %s\n", strerror(-r));
-                return -1;
-        }
-
-        fprintf(stdout, "connecting to orchestrator on '%s'\n", dbus_addr);
-        r = sd_bus_start(dbus);
-        if (r < 0) {
-                fprintf(stderr, "Failed to connect to orchestrator: %s\n", strerror(-r));
-                return -1;
-        }
-
-        return 0;
-}
\ No newline at end of file
diff --git a/src/node/dbus.h b/src/node/dbus.h
deleted file mode 100644
index 2e8d2bae65..0000000000
--- a/src/node/dbus.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef _BLUE_CHIHUAHUA_NODE_PEER_DBUS
-#define _BLUE_CHIHUAHUA_NODE_PEER_DBUS
-
-#include "../common/dbus.h"
-
-#include <netinet/in.h>
-
-int setup_peer_dbus(sd_bus *dbus, const struct sockaddr_in *addr);
-
-#endif
\ No newline at end of file
diff --git a/src/node/node.c b/src/node/node.c
deleted file mode 100644
index 133a1b8a76..0000000000
--- a/src/node/node.c
+++ /dev/null
@@ -1,44 +0,0 @@
-#include "../common/dbus.h"
-#include "dbus.h"
-#include "opt.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-int main(int argc, char *argv[]) {
-        fprintf(stdout, "Hello from node!\n");
-
-        struct sockaddr_in host;
-        memset(&host, 0, sizeof(host));
-        host.sin_family = AF_INET;
-        host.sin_addr.s_addr = htonl(INADDR_ANY);
-        host.sin_port = 0;
-
-        get_opts(argc, argv, &host);
-
-        int r = 0;
-        _cleanup_sd_event_ sd_event *event = NULL;
-        r = sd_event_default(&event);
-        if (r < 0) {
-                fprintf(stderr, "Failed to create event: %s\n", strerror(-r));
-                return EXIT_FAILURE;
-        }
-
-        _cleanup_sd_bus_ sd_bus *orch = NULL;
-        r = setup_peer_dbus(orch, &host);
-        if (r < 0) {
-                return EXIT_FAILURE;
-        }
-
-        r = sd_event_loop(event);
-        if (r < 0) {
-                fprintf(stderr, "Event loop failed: %s\n", strerror(-r));
-                return EXIT_FAILURE;
-        }
-        if (r < 0) {
-                return EXIT_FAILURE;
-        }
-
-        return EXIT_SUCCESS;
-}
\ No newline at end of file
diff --git a/src/orch/controller.h b/src/orch/controller.h
deleted file mode 100644
index 165060cc3b..0000000000
--- a/src/orch/controller.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef _BLUE_CHIHUAHUA_ORCH_CONTROLLER
-#define _BLUE_CHIHUAHUA_ORCH_CONTROLLER
-
-#include "../common/dbus.h"
-
-int controller_setup(int accept_fd, uint16_t port, sd_event *event, sd_event_source *event_source);
-
-#endif
\ No newline at end of file
diff --git a/src/orch/orch.c b/src/orch/orch.c
deleted file mode 100644
index 836d8d31ab..0000000000
--- a/src/orch/orch.c
+++ /dev/null
@@ -1,52 +0,0 @@
-#include "../common/dbus.h"
-#include "../ini/ini.h"
-#include "controller.h"
-#include "opt.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-
-/* A function that takes care of printing the lines of the ini file  */
-// NOLINTNEXTLINE
-static int ini_handler_func(void *user, const char *section, const char *name, const char *value) {
-        printf("[%s] %s = %s\n", section, name, value);
-        return EXIT_FAILURE;
-}
-
-int main(int argc, char *argv[]) {
-        fprintf(stdout, "Hello from orchestrator!\n");
-
-        uint16_t port = 0;
-        _cleanup_free_ char *configPath = NULL;
-
-        get_opts(argc, argv, &port, &configPath);
-
-        _cleanup_sd_event_ sd_event *event = NULL;
-        int r = sd_event_default(&event);
-        if (r < 0) {
-                fprintf(stderr, "Failed to create event: %s\n", strerror(-r));
-                return EXIT_FAILURE;
-        }
-
-        _cleanup_fd_ int accept_fd = -1;
-        _cleanup_sd_event_source_ sd_event_source *event_source = NULL;
-        r = controller_setup(accept_fd, port, event, event_source);
-        if (r < 0) {
-                fprintf(stderr, "Failed to setup controller\n");
-                return EXIT_FAILURE;
-        }
-
-        r = ini_parse(configPath, ini_handler_func, NULL);
-        if (r < 0) {
-                fprintf(stderr, "Failed to parse INI file: %s\n", configPath);
-                return EXIT_FAILURE;
-        }
-
-        r = sd_event_loop(event);
-        if (r < 0) {
-                fprintf(stderr, "Event loop failed: %s\n", strerror(-r));
-                return EXIT_FAILURE;
-        }
-
-        return EXIT_SUCCESS;
-}
\ No newline at end of file


Test patch:
diff --git a/test/client/.gitkeep b/binchihua/test/client/.gitkeep
similarity index 100%
rename from test/client/.gitkeep
rename to binchihua/test/client/.gitkeep
diff --git a/test/common/meson.build b/binchihua/test/common/meson.build
similarity index 100%
rename from test/common/meson.build
rename to binchihua/test/common/meson.build
diff --git a/test/common/parse-util_test.c b/binchihua/test/common/parse-util_test.c
similarity index 98%
rename from test/common/parse-util_test.c
rename to binchihua/test/common/parse-util_test.c
index ccd83ed840..70e5ca7884 100644
--- a/test/common/parse-util_test.c
+++ b/binchihua/test/common/parse-util_test.c
@@ -1,9 +1,8 @@
-#include "../../src/common/memory.h"
 #include "../../src/common/parse-util.h"
 
 #include <assert.h>
-#include <stdio.h>
 #include <stdbool.h>
+#include <stdio.h>
 
 #ifndef __FUNCTION_NAME__
 #        define __FUNCTION_NAME__ __func__
diff --git a/test/node/.gitkeep b/binchihua/test/node/.gitkeep
similarity index 100%
rename from test/node/.gitkeep
rename to binchihua/test/node/.gitkeep
diff --git a/test/orch/.gitkeep b/binchihua/test/orch/.gitkeep
similarity index 100%
rename from test/orch/.gitkeep
rename to binchihua/test/orch/.gitkeep