C++ runtime: add eRPC server, minimal CLI and Makefile. WIP.
authorEdouard Tisserant <edouard.tisserant@gmail.com>
Wed, 24 Apr 2024 02:15:33 +0200
changeset 3937 e13543d716b6
parent 3936 129202e555e0
child 3938 fc4af5685aa3
C++ runtime: add eRPC server, minimal CLI and Makefile. WIP.
C_runtime/Makefile
C_runtime/PLCObject.cpp
C_runtime/PLCObject.hpp
C_runtime/c_erpc_PLCObject_client.cpp
C_runtime/c_erpc_PLCObject_client.h
C_runtime/c_erpc_PLCObject_server.cpp
C_runtime/c_erpc_PLCObject_server.h
C_runtime/erpc_PLCObject_client.cpp
C_runtime/erpc_PLCObject_client.hpp
C_runtime/erpc_PLCObject_common.h
C_runtime/erpc_PLCObject_common.hpp
C_runtime/erpc_PLCObject_interface.cpp
C_runtime/erpc_PLCObject_interface.hpp
C_runtime/erpc_PLCObject_server.cpp
C_runtime/erpc_PLCObject_server.hpp
C_runtime/posix_main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/C_runtime/Makefile	Wed Apr 24 02:15:33 2024 +0200
@@ -0,0 +1,107 @@
+# Builds standalone C/C++ Beremiz runtime
+
+# This Makefile is based on fragments of eRPC Makefiles
+
+APP_NAME = beremiz_runtime
+
+RUNTIME_ROOT = $(abspath $(dir $(lastword $(MAKEFILE_LIST))))
+ERPC_ROOT ?= $(abspath $(RUNTIME_ROOT)/../../erpc)
+ERPC_C_ROOT = $(ERPC_ROOT)/erpc_c
+
+INCLUDES += $(ERPC_C_ROOT)/infra \
+            $(ERPC_C_ROOT)/port \
+            $(ERPC_C_ROOT)/setup \
+            $(ERPC_C_ROOT)/transports \
+            $(ERPC_ROOT)/test/common/config \
+            $(ERPC_ROOT)/erpcgen/src
+
+INCLUDES := $(foreach includes, $(INCLUDES), -I $(includes))
+
+ERPC_SOURCES += $(ERPC_ROOT)/erpcgen/src/format_string.cpp \
+                $(ERPC_ROOT)/erpcgen/src/Logging.cpp \
+                $(ERPC_ROOT)/erpcgen/src/options.cpp \
+                $(ERPC_C_ROOT)/infra/erpc_arbitrated_client_manager.cpp \
+                $(ERPC_C_ROOT)/infra/erpc_basic_codec.cpp \
+                $(ERPC_C_ROOT)/infra/erpc_client_manager.cpp \
+                $(ERPC_C_ROOT)/infra/erpc_crc16.cpp \
+                $(ERPC_C_ROOT)/infra/erpc_server.cpp \
+                $(ERPC_C_ROOT)/infra/erpc_simple_server.cpp \
+                $(ERPC_C_ROOT)/infra/erpc_framed_transport.cpp \
+                $(ERPC_C_ROOT)/infra/erpc_message_buffer.cpp \
+                $(ERPC_C_ROOT)/infra/erpc_message_loggers.cpp \
+                $(ERPC_C_ROOT)/infra/erpc_transport_arbitrator.cpp \
+                $(ERPC_C_ROOT)/infra/erpc_utils.cpp \
+                $(ERPC_C_ROOT)/port/erpc_port_stdlib.cpp \
+                $(ERPC_C_ROOT)/port/erpc_threading_pthreads.cpp \
+                $(ERPC_C_ROOT)/port/erpc_serial.cpp \
+                $(ERPC_C_ROOT)/transports/erpc_serial_transport.cpp \
+                $(ERPC_C_ROOT)/transports/erpc_tcp_transport.cpp
+			
+SOURCES +=  $(RUNTIME_ROOT)/c_erpc_PLCObject_client.cpp \
+            $(RUNTIME_ROOT)/c_erpc_PLCObject_server.cpp \
+            $(RUNTIME_ROOT)/erpc_PLCObject_client.cpp \
+            $(RUNTIME_ROOT)/erpc_PLCObject_interface.cpp \
+            $(RUNTIME_ROOT)/erpc_PLCObject_server.cpp \
+			$(RUNTIME_ROOT)/posix_main.cpp \
+			$(RUNTIME_ROOT)/PLCObject.cpp
+
+
+# get version from version.py
+BEREMIZ_VERSION := $(shell python3 $(RUNTIME_ROOT)/../version.py)
+
+CXXFLAGS += -std=gnu++17 -Wunused-variable -Wno-deprecated-register -Wno-narrowing -Werror -DBEREMIZ_VERSION=$(BEREMIZ_VERSION)
+# CFLAGS += -Os -DNDEBUG
+CXXFLAGS += -g3 -O0 -DDEBUG
+
+LIBRARIES += -lpthread -lrt -lc -lm
+LD = $(CXX)
+
+OBJS_ROOT = $(RUNTIME_ROOT)/build
+SOURCES_ABS := $(foreach s,$(SOURCES),$(abspath $(s)))
+SOURCES_REL := $(subst $(RUNTIME_ROOT)/,,$(SOURCES_ABS))
+SOURCE_DIRS_ABS := $(sort $(foreach f,$(SOURCES_ABS),$(dir $(f))))
+SOURCE_DIRS_REL := $(subst $(RUNTIME_ROOT)/,,$(SOURCE_DIRS_ABS))
+CXX_SOURCES = $(filter %.cpp,$(SOURCES_REL))
+OBJECTS_CXX := $(addprefix $(OBJS_ROOT)/,$(CXX_SOURCES:.cpp=.o))
+
+$(OBJS_ROOT)/%.o: $(RUNTIME_ROOT)/%.cpp
+	@echo Compiling $(subst $(RUNTIME_ROOT)/,,$<)
+	$(CXX) $(CXXFLAGS) $(INCLUDES) -MMD -MF $(basename $@).d -MP -o $@ -c $<
+
+ERPC_OBJS_ROOT = $(RUNTIME_ROOT)/erpcbuild
+ERPC_SOURCES_ABS := $(foreach s,$(ERPC_SOURCES),$(abspath $(s)))
+ERPC_SOURCES_REL := $(subst $(ERPC_ROOT)/,,$(ERPC_SOURCES_ABS))
+ERPC_SOURCE_DIRS_ABS := $(sort $(foreach f,$(ERPC_SOURCES_ABS),$(dir $(f))))
+ERPC_SOURCE_DIRS_REL := $(subst $(ERPC_ROOT)/,,$(ERPC_SOURCE_DIRS_ABS))
+ERPC_CXX_SOURCES = $(filter %.cpp,$(ERPC_SOURCES_REL))
+ERPC_OBJECTS_CXX := $(addprefix $(ERPC_OBJS_ROOT)/,$(ERPC_CXX_SOURCES:.cpp=.o))
+
+$(ERPC_OBJS_ROOT)/%.o: $(ERPC_ROOT)/%.cpp
+	@echo Compiling, $(subst $(ERPC_ROOT)/,,$<)
+	$(CXX) $(CXXFLAGS) $(INCLUDES) -MMD -MF $(basename $@).d -MP -o $@ -c $<
+
+OBJECTS_ALL := $(sort $(ERPC_OBJECTS_CXX) $(OBJECTS_CXX))
+OBJECTS_DIRS := $(OBJS_ROOT) $(addprefix $(OBJS_ROOT)/,$(SOURCE_DIRS_REL)) $(ERPC_OBJS_ROOT) $(addprefix $(ERPC_OBJS_ROOT)/,$(ERPC_SOURCE_DIRS_REL))
+
+.PHONY: all $(APP_NAME)
+all: $(APP_NAME) $(OBJECTS_DIRS)
+
+$(OBJECTS_DIRS) :
+	mkdir -p $@
+
+$(OBJECTS_ALL): | $(OBJECTS_DIRS)
+
+$(APP_NAME): $(OBJECTS_ALL)
+	@echo Linking, $(APP_NAME)
+	$(LD) $(LDFLAGS) \
+		$(OBJECTS_ALL) \
+		-o $@ \
+		$(LIBRARIES)
+	@echo "Output binary:" ; echo "  $(APP_NAME)"
+
+.PHONY: clean
+clean::
+	@echo "Cleaning $(APP_NAME)"
+	rm -rf $(OBJECTS_ALL) $(OBJECTS_DIRS) $(APP_NAME)
+
+-include $(OBJECTS_ALL:.o=.d)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/C_runtime/PLCObject.cpp	Wed Apr 24 02:15:33 2024 +0200
@@ -0,0 +1,80 @@
+
+#include <stdlib.h>
+
+#include "Logging.hpp"
+
+#include "PLCObject.hpp"
+
+PLCObject::~PLCObject(void)
+{
+}
+
+uint32_t PLCObject::AppendChunkToBlob(const binary_t * data, const binary_t * blobID, binary_t * newBlobID)
+{
+    return 0;
+}
+
+uint32_t PLCObject::GetLogMessage(uint8_t level, uint32_t msgID, log_message * message)
+{
+    return 0;
+}
+
+uint32_t PLCObject::GetPLCID(PSKID * plcID)
+{
+    return 0;
+}
+
+uint32_t PLCObject::GetPLCstatus(PLCstatus * status)
+{
+    return 0;
+}
+
+uint32_t PLCObject::GetTraceVariables(uint32_t debugToken, TraceVariables * traces)
+{
+    return 0;
+}
+
+uint32_t PLCObject::MatchMD5(const char * MD5, bool * match)
+{
+    return 0;
+}
+
+uint32_t PLCObject::NewPLC(const char * md5sum, const binary_t * plcObjectBlobID, const list_extra_file_1_t * extrafiles, bool * success)
+{
+    return 0;
+}
+
+uint32_t PLCObject::PurgeBlobs(void)
+{
+    return 0;
+}
+
+uint32_t PLCObject::RepairPLC(void)
+{
+    return 0;
+}
+
+uint32_t PLCObject::ResetLogCount(void)
+{
+    return 0;
+}
+
+uint32_t PLCObject::SeedBlob(const binary_t * seed, binary_t * blobID)
+{
+    return 0;
+}
+
+uint32_t PLCObject::SetTraceVariablesList(const list_trace_order_1_t * orders, uint32_t * debugtoken)
+{
+    return 0;
+}
+
+uint32_t PLCObject::StartPLC(void)
+{
+    return 0;
+}
+
+uint32_t PLCObject::StopPLC(bool * success)
+{
+    return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/C_runtime/PLCObject.hpp	Wed Apr 24 02:15:33 2024 +0200
@@ -0,0 +1,35 @@
+/*
+    Copyright Edouard TISSERANT 2024
+    See COPYING for details
+*/
+
+#if !defined(_PLCObject_hpp_)
+#define _PLCObject_hpp_
+
+#include "erpc_PLCObject_interface.hpp"
+
+using namespace erpcShim;
+
+class PLCObject : public BeremizPLCObjectService_interface
+{
+    public:
+
+        ~PLCObject(void);
+
+        virtual uint32_t AppendChunkToBlob(const binary_t * data, const binary_t * blobID, binary_t * newBlobID);
+        virtual uint32_t GetLogMessage(uint8_t level, uint32_t msgID, log_message * message);
+        virtual uint32_t GetPLCID(PSKID * plcID);
+        virtual uint32_t GetPLCstatus(PLCstatus * status);
+        virtual uint32_t GetTraceVariables(uint32_t debugToken, TraceVariables * traces);
+        virtual uint32_t MatchMD5(const char * MD5, bool * match);
+        virtual uint32_t NewPLC(const char * md5sum, const binary_t * plcObjectBlobID, const list_extra_file_1_t * extrafiles, bool * success);
+        virtual uint32_t PurgeBlobs(void);
+        virtual uint32_t RepairPLC(void);
+        virtual uint32_t ResetLogCount(void);
+        virtual uint32_t SeedBlob(const binary_t * seed, binary_t * blobID);
+        virtual uint32_t SetTraceVariablesList(const list_trace_order_1_t * orders, uint32_t * debugtoken);
+        virtual uint32_t StartPLC(void);
+        virtual uint32_t StopPLC(bool * success);
+};
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/C_runtime/c_erpc_PLCObject_client.cpp	Wed Apr 24 02:15:33 2024 +0200
@@ -0,0 +1,157 @@
+/*
+ * Generated by erpcgen 1.11.0 on Wed Mar 27 13:43:44 2024.
+ *
+ * AUTOGENERATED - DO NOT EDIT
+ */
+
+
+#include "c_erpc_PLCObject_client.h"
+#include "erpc_PLCObject_client.hpp"
+#include "erpc_manually_constructed.hpp"
+
+using namespace erpc;
+using namespace std;
+using namespace erpcShim;
+
+
+#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
+BeremizPLCObjectService_client *s_BeremizPLCObjectService_client = nullptr;
+#else
+ERPC_MANUALLY_CONSTRUCTED_STATIC(BeremizPLCObjectService_client, s_BeremizPLCObjectService_client);
+#endif
+
+uint32_t AppendChunkToBlob(const binary_t * data, const binary_t * blobID, binary_t * newBlobID)
+{
+    uint32_t result;
+    result = s_BeremizPLCObjectService_client->AppendChunkToBlob(data, blobID, newBlobID);
+
+    return result;
+}
+
+uint32_t GetLogMessage(uint8_t level, uint32_t msgID, log_message * message)
+{
+    uint32_t result;
+    result = s_BeremizPLCObjectService_client->GetLogMessage(level, msgID, message);
+
+    return result;
+}
+
+uint32_t GetPLCID(PSKID * plcID)
+{
+    uint32_t result;
+    result = s_BeremizPLCObjectService_client->GetPLCID(plcID);
+
+    return result;
+}
+
+uint32_t GetPLCstatus(PLCstatus * status)
+{
+    uint32_t result;
+    result = s_BeremizPLCObjectService_client->GetPLCstatus(status);
+
+    return result;
+}
+
+uint32_t GetTraceVariables(uint32_t debugToken, TraceVariables * traces)
+{
+    uint32_t result;
+    result = s_BeremizPLCObjectService_client->GetTraceVariables(debugToken, traces);
+
+    return result;
+}
+
+uint32_t MatchMD5(const char * MD5, bool * match)
+{
+    uint32_t result;
+    result = s_BeremizPLCObjectService_client->MatchMD5(MD5, match);
+
+    return result;
+}
+
+uint32_t NewPLC(const char * md5sum, const binary_t * plcObjectBlobID, const list_extra_file_1_t * extrafiles, bool * success)
+{
+    uint32_t result;
+    result = s_BeremizPLCObjectService_client->NewPLC(md5sum, plcObjectBlobID, extrafiles, success);
+
+    return result;
+}
+
+uint32_t PurgeBlobs(void)
+{
+    uint32_t result;
+    result = s_BeremizPLCObjectService_client->PurgeBlobs();
+
+    return result;
+}
+
+uint32_t RepairPLC(void)
+{
+    uint32_t result;
+    result = s_BeremizPLCObjectService_client->RepairPLC();
+
+    return result;
+}
+
+uint32_t ResetLogCount(void)
+{
+    uint32_t result;
+    result = s_BeremizPLCObjectService_client->ResetLogCount();
+
+    return result;
+}
+
+uint32_t SeedBlob(const binary_t * seed, binary_t * blobID)
+{
+    uint32_t result;
+    result = s_BeremizPLCObjectService_client->SeedBlob(seed, blobID);
+
+    return result;
+}
+
+uint32_t SetTraceVariablesList(const list_trace_order_1_t * orders, uint32_t * debugtoken)
+{
+    uint32_t result;
+    result = s_BeremizPLCObjectService_client->SetTraceVariablesList(orders, debugtoken);
+
+    return result;
+}
+
+uint32_t StartPLC(void)
+{
+    uint32_t result;
+    result = s_BeremizPLCObjectService_client->StartPLC();
+
+    return result;
+}
+
+uint32_t StopPLC(bool * success)
+{
+    uint32_t result;
+    result = s_BeremizPLCObjectService_client->StopPLC(success);
+
+    return result;
+}
+
+void initBeremizPLCObjectService_client(erpc_client_t client)
+{
+#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
+    erpc_assert(s_BeremizPLCObjectService_client == nullptr);
+    s_BeremizPLCObjectService_client = new BeremizPLCObjectService_client(reinterpret_cast<ClientManager *>(client));
+#else
+    erpc_assert(!s_BeremizPLCObjectService_client.isUsed());
+    s_BeremizPLCObjectService_client.construct(reinterpret_cast<ClientManager *>(client));
+#endif
+}
+
+void deinitBeremizPLCObjectService_client(void)
+{
+#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
+    if (s_BeremizPLCObjectService_client != nullptr)
+    {
+        delete s_BeremizPLCObjectService_client;
+        s_BeremizPLCObjectService_client = nullptr;
+    }
+#else
+    s_BeremizPLCObjectService_client.destroy();
+#endif
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/C_runtime/c_erpc_PLCObject_client.h	Wed Apr 24 02:15:33 2024 +0200
@@ -0,0 +1,84 @@
+/*
+ * Generated by erpcgen 1.11.0 on Wed Mar 27 13:43:44 2024.
+ *
+ * AUTOGENERATED - DO NOT EDIT
+ */
+
+
+#if !defined(_c_erpc_PLCObject_client_h_)
+#define _c_erpc_PLCObject_client_h_
+
+#include "erpc_PLCObject_common.h"
+#include "erpc_client_manager.h"
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+#if !defined(ERPC_FUNCTIONS_DEFINITIONS)
+#define ERPC_FUNCTIONS_DEFINITIONS
+
+
+/*! @brief BeremizPLCObjectService identifiers */
+enum _BeremizPLCObjectService_ids
+{
+    kBeremizPLCObjectService_service_id = 1,
+    kBeremizPLCObjectService_AppendChunkToBlob_id = 1,
+    kBeremizPLCObjectService_GetLogMessage_id = 2,
+    kBeremizPLCObjectService_GetPLCID_id = 3,
+    kBeremizPLCObjectService_GetPLCstatus_id = 4,
+    kBeremizPLCObjectService_GetTraceVariables_id = 5,
+    kBeremizPLCObjectService_MatchMD5_id = 6,
+    kBeremizPLCObjectService_NewPLC_id = 7,
+    kBeremizPLCObjectService_PurgeBlobs_id = 8,
+    kBeremizPLCObjectService_RepairPLC_id = 9,
+    kBeremizPLCObjectService_ResetLogCount_id = 10,
+    kBeremizPLCObjectService_SeedBlob_id = 11,
+    kBeremizPLCObjectService_SetTraceVariablesList_id = 12,
+    kBeremizPLCObjectService_StartPLC_id = 13,
+    kBeremizPLCObjectService_StopPLC_id = 14,
+};
+
+//! @name BeremizPLCObjectService
+//@{
+uint32_t AppendChunkToBlob(const binary_t * data, const binary_t * blobID, binary_t * newBlobID);
+
+uint32_t GetLogMessage(uint8_t level, uint32_t msgID, log_message * message);
+
+uint32_t GetPLCID(PSKID * plcID);
+
+uint32_t GetPLCstatus(PLCstatus * status);
+
+uint32_t GetTraceVariables(uint32_t debugToken, TraceVariables * traces);
+
+uint32_t MatchMD5(const char * MD5, bool * match);
+
+uint32_t NewPLC(const char * md5sum, const binary_t * plcObjectBlobID, const list_extra_file_1_t * extrafiles, bool * success);
+
+uint32_t PurgeBlobs(void);
+
+uint32_t RepairPLC(void);
+
+uint32_t ResetLogCount(void);
+
+uint32_t SeedBlob(const binary_t * seed, binary_t * blobID);
+
+uint32_t SetTraceVariablesList(const list_trace_order_1_t * orders, uint32_t * debugtoken);
+
+uint32_t StartPLC(void);
+
+uint32_t StopPLC(bool * success);
+//@}
+
+#endif // ERPC_FUNCTIONS_DEFINITIONS
+
+void initBeremizPLCObjectService_client(erpc_client_t client);
+
+void deinitBeremizPLCObjectService_client(void);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif // _c_erpc_PLCObject_client_h_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/C_runtime/c_erpc_PLCObject_server.cpp	Wed Apr 24 02:15:33 2024 +0200
@@ -0,0 +1,177 @@
+/*
+ * Generated by erpcgen 1.11.0 on Wed Mar 27 13:43:44 2024.
+ *
+ * AUTOGENERATED - DO NOT EDIT
+ */
+
+
+#include <new>
+#include "c_erpc_PLCObject_server.h"
+#include "erpc_PLCObject_server.hpp"
+#include "erpc_manually_constructed.hpp"
+
+using namespace erpc;
+using namespace std;
+using namespace erpcShim;
+
+
+class BeremizPLCObjectService_server: public BeremizPLCObjectService_interface
+{
+    public:
+        virtual ~BeremizPLCObjectService_server() {};
+
+
+        uint32_t AppendChunkToBlob(const binary_t * data, const binary_t * blobID, binary_t * newBlobID)
+        {
+            uint32_t result;
+            result = ::AppendChunkToBlob(data, blobID, newBlobID);
+
+            return result;
+        }
+
+        uint32_t GetLogMessage(uint8_t level, uint32_t msgID, log_message * message)
+        {
+            uint32_t result;
+            result = ::GetLogMessage(level, msgID, message);
+
+            return result;
+        }
+
+        uint32_t GetPLCID(PSKID * plcID)
+        {
+            uint32_t result;
+            result = ::GetPLCID(plcID);
+
+            return result;
+        }
+
+        uint32_t GetPLCstatus(PLCstatus * status)
+        {
+            uint32_t result;
+            result = ::GetPLCstatus(status);
+
+            return result;
+        }
+
+        uint32_t GetTraceVariables(uint32_t debugToken, TraceVariables * traces)
+        {
+            uint32_t result;
+            result = ::GetTraceVariables(debugToken, traces);
+
+            return result;
+        }
+
+        uint32_t MatchMD5(const char * MD5, bool * match)
+        {
+            uint32_t result;
+            result = ::MatchMD5(MD5, match);
+
+            return result;
+        }
+
+        uint32_t NewPLC(const char * md5sum, const binary_t * plcObjectBlobID, const list_extra_file_1_t * extrafiles, bool * success)
+        {
+            uint32_t result;
+            result = ::NewPLC(md5sum, plcObjectBlobID, extrafiles, success);
+
+            return result;
+        }
+
+        uint32_t PurgeBlobs(void)
+        {
+            uint32_t result;
+            result = ::PurgeBlobs();
+
+            return result;
+        }
+
+        uint32_t RepairPLC(void)
+        {
+            uint32_t result;
+            result = ::RepairPLC();
+
+            return result;
+        }
+
+        uint32_t ResetLogCount(void)
+        {
+            uint32_t result;
+            result = ::ResetLogCount();
+
+            return result;
+        }
+
+        uint32_t SeedBlob(const binary_t * seed, binary_t * blobID)
+        {
+            uint32_t result;
+            result = ::SeedBlob(seed, blobID);
+
+            return result;
+        }
+
+        uint32_t SetTraceVariablesList(const list_trace_order_1_t * orders, uint32_t * debugtoken)
+        {
+            uint32_t result;
+            result = ::SetTraceVariablesList(orders, debugtoken);
+
+            return result;
+        }
+
+        uint32_t StartPLC(void)
+        {
+            uint32_t result;
+            result = ::StartPLC();
+
+            return result;
+        }
+
+        uint32_t StopPLC(bool * success)
+        {
+            uint32_t result;
+            result = ::StopPLC(success);
+
+            return result;
+        }
+};
+
+ERPC_MANUALLY_CONSTRUCTED_STATIC(BeremizPLCObjectService_service, s_BeremizPLCObjectService_service);
+ERPC_MANUALLY_CONSTRUCTED_STATIC(BeremizPLCObjectService_server, s_BeremizPLCObjectService_server);
+
+erpc_service_t create_BeremizPLCObjectService_service(void)
+{
+    erpc_service_t service;
+
+#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
+    service = new (nothrow) BeremizPLCObjectService_service(new (nothrow)BeremizPLCObjectService_server());
+#else
+    if (s_BeremizPLCObjectService_service.isUsed())
+    {
+        service = NULL;
+    }
+    else
+    {
+        s_BeremizPLCObjectService_server.construct();
+        s_BeremizPLCObjectService_service.construct(s_BeremizPLCObjectService_server.get());
+        service = s_BeremizPLCObjectService_service.get();
+    }
+#endif
+
+    return service;
+}
+
+void destroy_BeremizPLCObjectService_service(erpc_service_t service)
+{
+#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
+    if (service)
+    {
+        delete (BeremizPLCObjectService_server *)(((BeremizPLCObjectService_service *)service)->getHandler());
+        delete (BeremizPLCObjectService_service *)service;
+    }
+#else
+    (void)service;
+    erpc_assert(service == s_BeremizPLCObjectService_service.get());
+    s_BeremizPLCObjectService_service.destroy();
+    s_BeremizPLCObjectService_server.destroy();
+#endif
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/C_runtime/c_erpc_PLCObject_server.h	Wed Apr 24 02:15:33 2024 +0200
@@ -0,0 +1,89 @@
+/*
+ * Generated by erpcgen 1.11.0 on Wed Mar 27 13:43:44 2024.
+ *
+ * AUTOGENERATED - DO NOT EDIT
+ */
+
+
+#if !defined(_c_erpc_PLCObject_server_h_)
+#define _c_erpc_PLCObject_server_h_
+
+#include "erpc_PLCObject_common.h"
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+typedef void * erpc_service_t;
+
+#if !defined(ERPC_FUNCTIONS_DEFINITIONS)
+#define ERPC_FUNCTIONS_DEFINITIONS
+
+
+/*! @brief BeremizPLCObjectService identifiers */
+enum _BeremizPLCObjectService_ids
+{
+    kBeremizPLCObjectService_service_id = 1,
+    kBeremizPLCObjectService_AppendChunkToBlob_id = 1,
+    kBeremizPLCObjectService_GetLogMessage_id = 2,
+    kBeremizPLCObjectService_GetPLCID_id = 3,
+    kBeremizPLCObjectService_GetPLCstatus_id = 4,
+    kBeremizPLCObjectService_GetTraceVariables_id = 5,
+    kBeremizPLCObjectService_MatchMD5_id = 6,
+    kBeremizPLCObjectService_NewPLC_id = 7,
+    kBeremizPLCObjectService_PurgeBlobs_id = 8,
+    kBeremizPLCObjectService_RepairPLC_id = 9,
+    kBeremizPLCObjectService_ResetLogCount_id = 10,
+    kBeremizPLCObjectService_SeedBlob_id = 11,
+    kBeremizPLCObjectService_SetTraceVariablesList_id = 12,
+    kBeremizPLCObjectService_StartPLC_id = 13,
+    kBeremizPLCObjectService_StopPLC_id = 14,
+};
+
+//! @name BeremizPLCObjectService
+//@{
+uint32_t AppendChunkToBlob(const binary_t * data, const binary_t * blobID, binary_t * newBlobID);
+
+uint32_t GetLogMessage(uint8_t level, uint32_t msgID, log_message * message);
+
+uint32_t GetPLCID(PSKID * plcID);
+
+uint32_t GetPLCstatus(PLCstatus * status);
+
+uint32_t GetTraceVariables(uint32_t debugToken, TraceVariables * traces);
+
+uint32_t MatchMD5(const char * MD5, bool * match);
+
+uint32_t NewPLC(const char * md5sum, const binary_t * plcObjectBlobID, const list_extra_file_1_t * extrafiles, bool * success);
+
+uint32_t PurgeBlobs(void);
+
+uint32_t RepairPLC(void);
+
+uint32_t ResetLogCount(void);
+
+uint32_t SeedBlob(const binary_t * seed, binary_t * blobID);
+
+uint32_t SetTraceVariablesList(const list_trace_order_1_t * orders, uint32_t * debugtoken);
+
+uint32_t StartPLC(void);
+
+uint32_t StopPLC(bool * success);
+//@}
+
+
+#endif // ERPC_FUNCTIONS_DEFINITIONS
+
+/*! @brief Return BeremizPLCObjectService_service service object. */
+erpc_service_t create_BeremizPLCObjectService_service(void);
+
+/*! @brief Destroy BeremizPLCObjectService_service service object. */
+void destroy_BeremizPLCObjectService_service(erpc_service_t service);
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif // _c_erpc_PLCObject_server_h_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/C_runtime/erpc_PLCObject_client.cpp	Wed Apr 24 02:15:33 2024 +0200
@@ -0,0 +1,1215 @@
+/*
+ * Generated by erpcgen 1.11.0 on Wed Mar 27 13:43:44 2024.
+ *
+ * AUTOGENERATED - DO NOT EDIT
+ */
+
+
+#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
+#include "erpc_port.h"
+#endif
+#include "erpc_codec.hpp"
+#include "erpc_PLCObject_client.hpp"
+#include "erpc_manually_constructed.hpp"
+
+#if 11100 != ERPC_VERSION_NUMBER
+#error "The generated shim code version is different to the rest of eRPC code."
+#endif
+
+using namespace erpc;
+using namespace std;
+using namespace erpcShim;
+
+//! @brief Function to write struct binary_t
+static void write_binary_t_struct(erpc::Codec * codec, const binary_t * data);
+
+//! @brief Function to write struct extra_file
+static void write_extra_file_struct(erpc::Codec * codec, const extra_file * data);
+
+//! @brief Function to write struct list_extra_file_1_t
+static void write_list_extra_file_1_t_struct(erpc::Codec * codec, const list_extra_file_1_t * data);
+
+//! @brief Function to write struct trace_order
+static void write_trace_order_struct(erpc::Codec * codec, const trace_order * data);
+
+//! @brief Function to write struct list_trace_order_1_t
+static void write_list_trace_order_1_t_struct(erpc::Codec * codec, const list_trace_order_1_t * data);
+
+
+// Write struct binary_t function implementation
+static void write_binary_t_struct(erpc::Codec * codec, const binary_t * data)
+{
+    if(NULL == data)
+    {
+        return;
+    }
+
+    codec->writeBinary(data->dataLength, data->data);
+}
+
+// Write struct extra_file function implementation
+static void write_extra_file_struct(erpc::Codec * codec, const extra_file * data)
+{
+    if(NULL == data)
+    {
+        return;
+    }
+
+    {
+        uint32_t fname_len = strlen((const char*)data->fname);
+
+        codec->writeString(fname_len, (const char*)data->fname);
+    }
+
+    write_binary_t_struct(codec, &(data->blobID));
+}
+
+// Write struct list_extra_file_1_t function implementation
+static void write_list_extra_file_1_t_struct(erpc::Codec * codec, const list_extra_file_1_t * data)
+{
+    if(NULL == data)
+    {
+        return;
+    }
+
+    codec->startWriteList(data->elementsCount);
+    for (uint32_t listCount = 0U; listCount < data->elementsCount; ++listCount)
+    {
+        write_extra_file_struct(codec, &(data->elements[listCount]));
+    }
+}
+
+// Write struct trace_order function implementation
+static void write_trace_order_struct(erpc::Codec * codec, const trace_order * data)
+{
+    if(NULL == data)
+    {
+        return;
+    }
+
+    codec->write(data->idx);
+
+    write_binary_t_struct(codec, &(data->force));
+}
+
+// Write struct list_trace_order_1_t function implementation
+static void write_list_trace_order_1_t_struct(erpc::Codec * codec, const list_trace_order_1_t * data)
+{
+    if(NULL == data)
+    {
+        return;
+    }
+
+    codec->startWriteList(data->elementsCount);
+    for (uint32_t listCount = 0U; listCount < data->elementsCount; ++listCount)
+    {
+        write_trace_order_struct(codec, &(data->elements[listCount]));
+    }
+}
+
+
+//! @brief Function to read struct binary_t
+static void read_binary_t_struct(erpc::Codec * codec, binary_t * data);
+
+//! @brief Function to read struct log_message
+static void read_log_message_struct(erpc::Codec * codec, log_message * data);
+
+//! @brief Function to read struct PSKID
+static void read_PSKID_struct(erpc::Codec * codec, PSKID * data);
+
+//! @brief Function to read struct PLCstatus
+static void read_PLCstatus_struct(erpc::Codec * codec, PLCstatus * data);
+
+//! @brief Function to read struct trace_sample
+static void read_trace_sample_struct(erpc::Codec * codec, trace_sample * data);
+
+//! @brief Function to read struct TraceVariables
+static void read_TraceVariables_struct(erpc::Codec * codec, TraceVariables * data);
+
+//! @brief Function to read struct list_trace_sample_1_t
+static void read_list_trace_sample_1_t_struct(erpc::Codec * codec, list_trace_sample_1_t * data);
+
+
+// Read struct binary_t function implementation
+static void read_binary_t_struct(erpc::Codec * codec, binary_t * data)
+{
+    if(NULL == data)
+    {
+        return;
+    }
+
+    uint8_t * data_local;
+    codec->readBinary(data->dataLength, &data_local);
+    if (data->dataLength > 0)
+    {
+    data->data = (uint8_t *) erpc_malloc(data->dataLength * sizeof(uint8_t));
+        if (data->data == NULL)
+        {
+            codec->updateStatus(kErpcStatus_MemoryError);
+        }
+        else
+        {
+            memcpy(data->data, data_local, data->dataLength);
+        }
+    }
+    else
+    {
+        data->data = NULL;
+    }
+}
+
+// Read struct log_message function implementation
+static void read_log_message_struct(erpc::Codec * codec, log_message * data)
+{
+    if(NULL == data)
+    {
+        return;
+    }
+
+    {
+        uint32_t msg_len;
+        char * msg_local;
+        codec->readString(msg_len, &msg_local);
+        data->msg = (char*) erpc_malloc((msg_len + 1) * sizeof(char));
+        if ((data->msg == NULL) || (msg_local == NULL))
+        {
+            codec->updateStatus(kErpcStatus_MemoryError);
+        }
+        else
+        {
+            memcpy(data->msg, msg_local, msg_len);
+            (data->msg)[msg_len] = 0;
+        }
+    }
+
+    codec->read(data->tick);
+
+    codec->read(data->sec);
+
+    codec->read(data->nsec);
+}
+
+// Read struct PSKID function implementation
+static void read_PSKID_struct(erpc::Codec * codec, PSKID * data)
+{
+    if(NULL == data)
+    {
+        return;
+    }
+
+    {
+        uint32_t ID_len;
+        char * ID_local;
+        codec->readString(ID_len, &ID_local);
+        data->ID = (char*) erpc_malloc((ID_len + 1) * sizeof(char));
+        if ((data->ID == NULL) || (ID_local == NULL))
+        {
+            codec->updateStatus(kErpcStatus_MemoryError);
+        }
+        else
+        {
+            memcpy(data->ID, ID_local, ID_len);
+            (data->ID)[ID_len] = 0;
+        }
+    }
+
+    {
+        uint32_t PSK_len;
+        char * PSK_local;
+        codec->readString(PSK_len, &PSK_local);
+        data->PSK = (char*) erpc_malloc((PSK_len + 1) * sizeof(char));
+        if ((data->PSK == NULL) || (PSK_local == NULL))
+        {
+            codec->updateStatus(kErpcStatus_MemoryError);
+        }
+        else
+        {
+            memcpy(data->PSK, PSK_local, PSK_len);
+            (data->PSK)[PSK_len] = 0;
+        }
+    }
+}
+
+// Read struct PLCstatus function implementation
+static void read_PLCstatus_struct(erpc::Codec * codec, PLCstatus * data)
+{
+    int32_t _tmp_local_i32;
+
+    if(NULL == data)
+    {
+        return;
+    }
+
+    codec->read(_tmp_local_i32);
+    data->PLCstatus = static_cast<PLCstatus_enum>(_tmp_local_i32);
+
+    for (uint32_t arrayCount0 = 0U; arrayCount0 < 4U; ++arrayCount0)
+    {
+        codec->read(data->logcounts[arrayCount0]);
+    }
+}
+
+// Read struct trace_sample function implementation
+static void read_trace_sample_struct(erpc::Codec * codec, trace_sample * data)
+{
+    if(NULL == data)
+    {
+        return;
+    }
+
+    codec->read(data->tick);
+
+    read_binary_t_struct(codec, &(data->TraceBuffer));
+}
+
+// Read struct TraceVariables function implementation
+static void read_TraceVariables_struct(erpc::Codec * codec, TraceVariables * data)
+{
+    int32_t _tmp_local_i32;
+
+    if(NULL == data)
+    {
+        return;
+    }
+
+    codec->read(_tmp_local_i32);
+    data->PLCstatus = static_cast<PLCstatus_enum>(_tmp_local_i32);
+
+    read_list_trace_sample_1_t_struct(codec, &(data->traces));
+}
+
+// Read struct list_trace_sample_1_t function implementation
+static void read_list_trace_sample_1_t_struct(erpc::Codec * codec, list_trace_sample_1_t * data)
+{
+    if(NULL == data)
+    {
+        return;
+    }
+
+    codec->startReadList(data->elementsCount);
+    data->elements = (trace_sample *) erpc_malloc(data->elementsCount * sizeof(trace_sample));
+    if ((data->elements == NULL) && (data->elementsCount > 0))
+    {
+        codec->updateStatus(kErpcStatus_MemoryError);
+    }
+    for (uint32_t listCount = 0U; listCount < data->elementsCount; ++listCount)
+    {
+        read_trace_sample_struct(codec, &(data->elements[listCount]));
+    }
+}
+
+
+
+
+BeremizPLCObjectService_client::BeremizPLCObjectService_client(ClientManager *manager)
+:m_clientManager(manager)
+{
+}
+
+BeremizPLCObjectService_client::~BeremizPLCObjectService_client()
+{
+}
+
+// BeremizPLCObjectService interface AppendChunkToBlob function client shim.
+uint32_t BeremizPLCObjectService_client::AppendChunkToBlob(const binary_t * data, const binary_t * blobID, binary_t * newBlobID)
+{
+    erpc_status_t err = kErpcStatus_Success;
+
+    uint32_t result;
+
+#if ERPC_PRE_POST_ACTION
+    pre_post_action_cb preCB = m_clientManager->getPreCB();
+    if (preCB)
+    {
+        preCB();
+    }
+#endif
+
+    // Get a new request.
+    RequestContext request = m_clientManager->createRequest(false);
+
+    // Encode the request.
+    Codec * codec = request.getCodec();
+
+    if (codec == NULL)
+    {
+        err = kErpcStatus_MemoryError;
+    }
+    else
+    {
+        codec->startWriteMessage(message_type_t::kInvocationMessage, m_serviceId, m_AppendChunkToBlobId, request.getSequence());
+
+        write_binary_t_struct(codec, data);
+
+        write_binary_t_struct(codec, blobID);
+
+        // Send message to server
+        // Codec status is checked inside this function.
+        m_clientManager->performRequest(request);
+
+        read_binary_t_struct(codec, newBlobID);
+
+        codec->read(result);
+
+        err = codec->getStatus();
+    }
+
+    // Dispose of the request.
+    m_clientManager->releaseRequest(request);
+
+    // Invoke error handler callback function
+    m_clientManager->callErrorHandler(err, m_AppendChunkToBlobId);
+
+#if ERPC_PRE_POST_ACTION
+    pre_post_action_cb postCB = m_clientManager->getPostCB();
+    if (postCB)
+    {
+        postCB();
+    }
+#endif
+
+
+    if (err != kErpcStatus_Success)
+    {
+        result = 0xFFFFFFFFU;
+    }
+
+    return result;
+}
+
+// BeremizPLCObjectService interface GetLogMessage function client shim.
+uint32_t BeremizPLCObjectService_client::GetLogMessage(uint8_t level, uint32_t msgID, log_message * message)
+{
+    erpc_status_t err = kErpcStatus_Success;
+
+    uint32_t result;
+
+#if ERPC_PRE_POST_ACTION
+    pre_post_action_cb preCB = m_clientManager->getPreCB();
+    if (preCB)
+    {
+        preCB();
+    }
+#endif
+
+    // Get a new request.
+    RequestContext request = m_clientManager->createRequest(false);
+
+    // Encode the request.
+    Codec * codec = request.getCodec();
+
+    if (codec == NULL)
+    {
+        err = kErpcStatus_MemoryError;
+    }
+    else
+    {
+        codec->startWriteMessage(message_type_t::kInvocationMessage, m_serviceId, m_GetLogMessageId, request.getSequence());
+
+        codec->write(level);
+
+        codec->write(msgID);
+
+        // Send message to server
+        // Codec status is checked inside this function.
+        m_clientManager->performRequest(request);
+
+        read_log_message_struct(codec, message);
+
+        codec->read(result);
+
+        err = codec->getStatus();
+    }
+
+    // Dispose of the request.
+    m_clientManager->releaseRequest(request);
+
+    // Invoke error handler callback function
+    m_clientManager->callErrorHandler(err, m_GetLogMessageId);
+
+#if ERPC_PRE_POST_ACTION
+    pre_post_action_cb postCB = m_clientManager->getPostCB();
+    if (postCB)
+    {
+        postCB();
+    }
+#endif
+
+
+    if (err != kErpcStatus_Success)
+    {
+        result = 0xFFFFFFFFU;
+    }
+
+    return result;
+}
+
+// BeremizPLCObjectService interface GetPLCID function client shim.
+uint32_t BeremizPLCObjectService_client::GetPLCID(PSKID * plcID)
+{
+    erpc_status_t err = kErpcStatus_Success;
+
+    uint32_t result;
+
+#if ERPC_PRE_POST_ACTION
+    pre_post_action_cb preCB = m_clientManager->getPreCB();
+    if (preCB)
+    {
+        preCB();
+    }
+#endif
+
+    // Get a new request.
+    RequestContext request = m_clientManager->createRequest(false);
+
+    // Encode the request.
+    Codec * codec = request.getCodec();
+
+    if (codec == NULL)
+    {
+        err = kErpcStatus_MemoryError;
+    }
+    else
+    {
+        codec->startWriteMessage(message_type_t::kInvocationMessage, m_serviceId, m_GetPLCIDId, request.getSequence());
+
+        // Send message to server
+        // Codec status is checked inside this function.
+        m_clientManager->performRequest(request);
+
+        read_PSKID_struct(codec, plcID);
+
+        codec->read(result);
+
+        err = codec->getStatus();
+    }
+
+    // Dispose of the request.
+    m_clientManager->releaseRequest(request);
+
+    // Invoke error handler callback function
+    m_clientManager->callErrorHandler(err, m_GetPLCIDId);
+
+#if ERPC_PRE_POST_ACTION
+    pre_post_action_cb postCB = m_clientManager->getPostCB();
+    if (postCB)
+    {
+        postCB();
+    }
+#endif
+
+
+    if (err != kErpcStatus_Success)
+    {
+        result = 0xFFFFFFFFU;
+    }
+
+    return result;
+}
+
+// BeremizPLCObjectService interface GetPLCstatus function client shim.
+uint32_t BeremizPLCObjectService_client::GetPLCstatus(PLCstatus * status)
+{
+    erpc_status_t err = kErpcStatus_Success;
+
+    uint32_t result;
+
+#if ERPC_PRE_POST_ACTION
+    pre_post_action_cb preCB = m_clientManager->getPreCB();
+    if (preCB)
+    {
+        preCB();
+    }
+#endif
+
+    // Get a new request.
+    RequestContext request = m_clientManager->createRequest(false);
+
+    // Encode the request.
+    Codec * codec = request.getCodec();
+
+    if (codec == NULL)
+    {
+        err = kErpcStatus_MemoryError;
+    }
+    else
+    {
+        codec->startWriteMessage(message_type_t::kInvocationMessage, m_serviceId, m_GetPLCstatusId, request.getSequence());
+
+        // Send message to server
+        // Codec status is checked inside this function.
+        m_clientManager->performRequest(request);
+
+        read_PLCstatus_struct(codec, status);
+
+        codec->read(result);
+
+        err = codec->getStatus();
+    }
+
+    // Dispose of the request.
+    m_clientManager->releaseRequest(request);
+
+    // Invoke error handler callback function
+    m_clientManager->callErrorHandler(err, m_GetPLCstatusId);
+
+#if ERPC_PRE_POST_ACTION
+    pre_post_action_cb postCB = m_clientManager->getPostCB();
+    if (postCB)
+    {
+        postCB();
+    }
+#endif
+
+
+    if (err != kErpcStatus_Success)
+    {
+        result = 0xFFFFFFFFU;
+    }
+
+    return result;
+}
+
+// BeremizPLCObjectService interface GetTraceVariables function client shim.
+uint32_t BeremizPLCObjectService_client::GetTraceVariables(uint32_t debugToken, TraceVariables * traces)
+{
+    erpc_status_t err = kErpcStatus_Success;
+
+    uint32_t result;
+
+#if ERPC_PRE_POST_ACTION
+    pre_post_action_cb preCB = m_clientManager->getPreCB();
+    if (preCB)
+    {
+        preCB();
+    }
+#endif
+
+    // Get a new request.
+    RequestContext request = m_clientManager->createRequest(false);
+
+    // Encode the request.
+    Codec * codec = request.getCodec();
+
+    if (codec == NULL)
+    {
+        err = kErpcStatus_MemoryError;
+    }
+    else
+    {
+        codec->startWriteMessage(message_type_t::kInvocationMessage, m_serviceId, m_GetTraceVariablesId, request.getSequence());
+
+        codec->write(debugToken);
+
+        // Send message to server
+        // Codec status is checked inside this function.
+        m_clientManager->performRequest(request);
+
+        read_TraceVariables_struct(codec, traces);
+
+        codec->read(result);
+
+        err = codec->getStatus();
+    }
+
+    // Dispose of the request.
+    m_clientManager->releaseRequest(request);
+
+    // Invoke error handler callback function
+    m_clientManager->callErrorHandler(err, m_GetTraceVariablesId);
+
+#if ERPC_PRE_POST_ACTION
+    pre_post_action_cb postCB = m_clientManager->getPostCB();
+    if (postCB)
+    {
+        postCB();
+    }
+#endif
+
+
+    if (err != kErpcStatus_Success)
+    {
+        result = 0xFFFFFFFFU;
+    }
+
+    return result;
+}
+
+// BeremizPLCObjectService interface MatchMD5 function client shim.
+uint32_t BeremizPLCObjectService_client::MatchMD5(const char * MD5, bool * match)
+{
+    erpc_status_t err = kErpcStatus_Success;
+
+    uint32_t result;
+
+#if ERPC_PRE_POST_ACTION
+    pre_post_action_cb preCB = m_clientManager->getPreCB();
+    if (preCB)
+    {
+        preCB();
+    }
+#endif
+
+    // Get a new request.
+    RequestContext request = m_clientManager->createRequest(false);
+
+    // Encode the request.
+    Codec * codec = request.getCodec();
+
+    if (codec == NULL)
+    {
+        err = kErpcStatus_MemoryError;
+    }
+    else
+    {
+        codec->startWriteMessage(message_type_t::kInvocationMessage, m_serviceId, m_MatchMD5Id, request.getSequence());
+
+        {
+            uint32_t MD5_len = strlen((const char*)MD5);
+
+            codec->writeString(MD5_len, (const char*)MD5);
+        }
+
+        // Send message to server
+        // Codec status is checked inside this function.
+        m_clientManager->performRequest(request);
+
+        codec->read(*match);
+
+        codec->read(result);
+
+        err = codec->getStatus();
+    }
+
+    // Dispose of the request.
+    m_clientManager->releaseRequest(request);
+
+    // Invoke error handler callback function
+    m_clientManager->callErrorHandler(err, m_MatchMD5Id);
+
+#if ERPC_PRE_POST_ACTION
+    pre_post_action_cb postCB = m_clientManager->getPostCB();
+    if (postCB)
+    {
+        postCB();
+    }
+#endif
+
+
+    if (err != kErpcStatus_Success)
+    {
+        result = 0xFFFFFFFFU;
+    }
+
+    return result;
+}
+
+// BeremizPLCObjectService interface NewPLC function client shim.
+uint32_t BeremizPLCObjectService_client::NewPLC(const char * md5sum, const binary_t * plcObjectBlobID, const list_extra_file_1_t * extrafiles, bool * success)
+{
+    erpc_status_t err = kErpcStatus_Success;
+
+    uint32_t result;
+
+#if ERPC_PRE_POST_ACTION
+    pre_post_action_cb preCB = m_clientManager->getPreCB();
+    if (preCB)
+    {
+        preCB();
+    }
+#endif
+
+    // Get a new request.
+    RequestContext request = m_clientManager->createRequest(false);
+
+    // Encode the request.
+    Codec * codec = request.getCodec();
+
+    if (codec == NULL)
+    {
+        err = kErpcStatus_MemoryError;
+    }
+    else
+    {
+        codec->startWriteMessage(message_type_t::kInvocationMessage, m_serviceId, m_NewPLCId, request.getSequence());
+
+        {
+            uint32_t md5sum_len = strlen((const char*)md5sum);
+
+            codec->writeString(md5sum_len, (const char*)md5sum);
+        }
+
+        write_binary_t_struct(codec, plcObjectBlobID);
+
+        write_list_extra_file_1_t_struct(codec, extrafiles);
+
+        // Send message to server
+        // Codec status is checked inside this function.
+        m_clientManager->performRequest(request);
+
+        codec->read(*success);
+
+        codec->read(result);
+
+        err = codec->getStatus();
+    }
+
+    // Dispose of the request.
+    m_clientManager->releaseRequest(request);
+
+    // Invoke error handler callback function
+    m_clientManager->callErrorHandler(err, m_NewPLCId);
+
+#if ERPC_PRE_POST_ACTION
+    pre_post_action_cb postCB = m_clientManager->getPostCB();
+    if (postCB)
+    {
+        postCB();
+    }
+#endif
+
+
+    if (err != kErpcStatus_Success)
+    {
+        result = 0xFFFFFFFFU;
+    }
+
+    return result;
+}
+
+// BeremizPLCObjectService interface PurgeBlobs function client shim.
+uint32_t BeremizPLCObjectService_client::PurgeBlobs(void)
+{
+    erpc_status_t err = kErpcStatus_Success;
+
+    uint32_t result;
+
+#if ERPC_PRE_POST_ACTION
+    pre_post_action_cb preCB = m_clientManager->getPreCB();
+    if (preCB)
+    {
+        preCB();
+    }
+#endif
+
+    // Get a new request.
+    RequestContext request = m_clientManager->createRequest(false);
+
+    // Encode the request.
+    Codec * codec = request.getCodec();
+
+    if (codec == NULL)
+    {
+        err = kErpcStatus_MemoryError;
+    }
+    else
+    {
+        codec->startWriteMessage(message_type_t::kInvocationMessage, m_serviceId, m_PurgeBlobsId, request.getSequence());
+
+        // Send message to server
+        // Codec status is checked inside this function.
+        m_clientManager->performRequest(request);
+
+        codec->read(result);
+
+        err = codec->getStatus();
+    }
+
+    // Dispose of the request.
+    m_clientManager->releaseRequest(request);
+
+    // Invoke error handler callback function
+    m_clientManager->callErrorHandler(err, m_PurgeBlobsId);
+
+#if ERPC_PRE_POST_ACTION
+    pre_post_action_cb postCB = m_clientManager->getPostCB();
+    if (postCB)
+    {
+        postCB();
+    }
+#endif
+
+
+    if (err != kErpcStatus_Success)
+    {
+        result = 0xFFFFFFFFU;
+    }
+
+    return result;
+}
+
+// BeremizPLCObjectService interface RepairPLC function client shim.
+uint32_t BeremizPLCObjectService_client::RepairPLC(void)
+{
+    erpc_status_t err = kErpcStatus_Success;
+
+    uint32_t result;
+
+#if ERPC_PRE_POST_ACTION
+    pre_post_action_cb preCB = m_clientManager->getPreCB();
+    if (preCB)
+    {
+        preCB();
+    }
+#endif
+
+    // Get a new request.
+    RequestContext request = m_clientManager->createRequest(false);
+
+    // Encode the request.
+    Codec * codec = request.getCodec();
+
+    if (codec == NULL)
+    {
+        err = kErpcStatus_MemoryError;
+    }
+    else
+    {
+        codec->startWriteMessage(message_type_t::kInvocationMessage, m_serviceId, m_RepairPLCId, request.getSequence());
+
+        // Send message to server
+        // Codec status is checked inside this function.
+        m_clientManager->performRequest(request);
+
+        codec->read(result);
+
+        err = codec->getStatus();
+    }
+
+    // Dispose of the request.
+    m_clientManager->releaseRequest(request);
+
+    // Invoke error handler callback function
+    m_clientManager->callErrorHandler(err, m_RepairPLCId);
+
+#if ERPC_PRE_POST_ACTION
+    pre_post_action_cb postCB = m_clientManager->getPostCB();
+    if (postCB)
+    {
+        postCB();
+    }
+#endif
+
+
+    if (err != kErpcStatus_Success)
+    {
+        result = 0xFFFFFFFFU;
+    }
+
+    return result;
+}
+
+// BeremizPLCObjectService interface ResetLogCount function client shim.
+uint32_t BeremizPLCObjectService_client::ResetLogCount(void)
+{
+    erpc_status_t err = kErpcStatus_Success;
+
+    uint32_t result;
+
+#if ERPC_PRE_POST_ACTION
+    pre_post_action_cb preCB = m_clientManager->getPreCB();
+    if (preCB)
+    {
+        preCB();
+    }
+#endif
+
+    // Get a new request.
+    RequestContext request = m_clientManager->createRequest(false);
+
+    // Encode the request.
+    Codec * codec = request.getCodec();
+
+    if (codec == NULL)
+    {
+        err = kErpcStatus_MemoryError;
+    }
+    else
+    {
+        codec->startWriteMessage(message_type_t::kInvocationMessage, m_serviceId, m_ResetLogCountId, request.getSequence());
+
+        // Send message to server
+        // Codec status is checked inside this function.
+        m_clientManager->performRequest(request);
+
+        codec->read(result);
+
+        err = codec->getStatus();
+    }
+
+    // Dispose of the request.
+    m_clientManager->releaseRequest(request);
+
+    // Invoke error handler callback function
+    m_clientManager->callErrorHandler(err, m_ResetLogCountId);
+
+#if ERPC_PRE_POST_ACTION
+    pre_post_action_cb postCB = m_clientManager->getPostCB();
+    if (postCB)
+    {
+        postCB();
+    }
+#endif
+
+
+    if (err != kErpcStatus_Success)
+    {
+        result = 0xFFFFFFFFU;
+    }
+
+    return result;
+}
+
+// BeremizPLCObjectService interface SeedBlob function client shim.
+uint32_t BeremizPLCObjectService_client::SeedBlob(const binary_t * seed, binary_t * blobID)
+{
+    erpc_status_t err = kErpcStatus_Success;
+
+    uint32_t result;
+
+#if ERPC_PRE_POST_ACTION
+    pre_post_action_cb preCB = m_clientManager->getPreCB();
+    if (preCB)
+    {
+        preCB();
+    }
+#endif
+
+    // Get a new request.
+    RequestContext request = m_clientManager->createRequest(false);
+
+    // Encode the request.
+    Codec * codec = request.getCodec();
+
+    if (codec == NULL)
+    {
+        err = kErpcStatus_MemoryError;
+    }
+    else
+    {
+        codec->startWriteMessage(message_type_t::kInvocationMessage, m_serviceId, m_SeedBlobId, request.getSequence());
+
+        write_binary_t_struct(codec, seed);
+
+        // Send message to server
+        // Codec status is checked inside this function.
+        m_clientManager->performRequest(request);
+
+        read_binary_t_struct(codec, blobID);
+
+        codec->read(result);
+
+        err = codec->getStatus();
+    }
+
+    // Dispose of the request.
+    m_clientManager->releaseRequest(request);
+
+    // Invoke error handler callback function
+    m_clientManager->callErrorHandler(err, m_SeedBlobId);
+
+#if ERPC_PRE_POST_ACTION
+    pre_post_action_cb postCB = m_clientManager->getPostCB();
+    if (postCB)
+    {
+        postCB();
+    }
+#endif
+
+
+    if (err != kErpcStatus_Success)
+    {
+        result = 0xFFFFFFFFU;
+    }
+
+    return result;
+}
+
+// BeremizPLCObjectService interface SetTraceVariablesList function client shim.
+uint32_t BeremizPLCObjectService_client::SetTraceVariablesList(const list_trace_order_1_t * orders, uint32_t * debugtoken)
+{
+    erpc_status_t err = kErpcStatus_Success;
+
+    uint32_t result;
+
+#if ERPC_PRE_POST_ACTION
+    pre_post_action_cb preCB = m_clientManager->getPreCB();
+    if (preCB)
+    {
+        preCB();
+    }
+#endif
+
+    // Get a new request.
+    RequestContext request = m_clientManager->createRequest(false);
+
+    // Encode the request.
+    Codec * codec = request.getCodec();
+
+    if (codec == NULL)
+    {
+        err = kErpcStatus_MemoryError;
+    }
+    else
+    {
+        codec->startWriteMessage(message_type_t::kInvocationMessage, m_serviceId, m_SetTraceVariablesListId, request.getSequence());
+
+        write_list_trace_order_1_t_struct(codec, orders);
+
+        // Send message to server
+        // Codec status is checked inside this function.
+        m_clientManager->performRequest(request);
+
+        codec->read(*debugtoken);
+
+        codec->read(result);
+
+        err = codec->getStatus();
+    }
+
+    // Dispose of the request.
+    m_clientManager->releaseRequest(request);
+
+    // Invoke error handler callback function
+    m_clientManager->callErrorHandler(err, m_SetTraceVariablesListId);
+
+#if ERPC_PRE_POST_ACTION
+    pre_post_action_cb postCB = m_clientManager->getPostCB();
+    if (postCB)
+    {
+        postCB();
+    }
+#endif
+
+
+    if (err != kErpcStatus_Success)
+    {
+        result = 0xFFFFFFFFU;
+    }
+
+    return result;
+}
+
+// BeremizPLCObjectService interface StartPLC function client shim.
+uint32_t BeremizPLCObjectService_client::StartPLC(void)
+{
+    erpc_status_t err = kErpcStatus_Success;
+
+    uint32_t result;
+
+#if ERPC_PRE_POST_ACTION
+    pre_post_action_cb preCB = m_clientManager->getPreCB();
+    if (preCB)
+    {
+        preCB();
+    }
+#endif
+
+    // Get a new request.
+    RequestContext request = m_clientManager->createRequest(false);
+
+    // Encode the request.
+    Codec * codec = request.getCodec();
+
+    if (codec == NULL)
+    {
+        err = kErpcStatus_MemoryError;
+    }
+    else
+    {
+        codec->startWriteMessage(message_type_t::kInvocationMessage, m_serviceId, m_StartPLCId, request.getSequence());
+
+        // Send message to server
+        // Codec status is checked inside this function.
+        m_clientManager->performRequest(request);
+
+        codec->read(result);
+
+        err = codec->getStatus();
+    }
+
+    // Dispose of the request.
+    m_clientManager->releaseRequest(request);
+
+    // Invoke error handler callback function
+    m_clientManager->callErrorHandler(err, m_StartPLCId);
+
+#if ERPC_PRE_POST_ACTION
+    pre_post_action_cb postCB = m_clientManager->getPostCB();
+    if (postCB)
+    {
+        postCB();
+    }
+#endif
+
+
+    if (err != kErpcStatus_Success)
+    {
+        result = 0xFFFFFFFFU;
+    }
+
+    return result;
+}
+
+// BeremizPLCObjectService interface StopPLC function client shim.
+uint32_t BeremizPLCObjectService_client::StopPLC(bool * success)
+{
+    erpc_status_t err = kErpcStatus_Success;
+
+    uint32_t result;
+
+#if ERPC_PRE_POST_ACTION
+    pre_post_action_cb preCB = m_clientManager->getPreCB();
+    if (preCB)
+    {
+        preCB();
+    }
+#endif
+
+    // Get a new request.
+    RequestContext request = m_clientManager->createRequest(false);
+
+    // Encode the request.
+    Codec * codec = request.getCodec();
+
+    if (codec == NULL)
+    {
+        err = kErpcStatus_MemoryError;
+    }
+    else
+    {
+        codec->startWriteMessage(message_type_t::kInvocationMessage, m_serviceId, m_StopPLCId, request.getSequence());
+
+        // Send message to server
+        // Codec status is checked inside this function.
+        m_clientManager->performRequest(request);
+
+        codec->read(*success);
+
+        codec->read(result);
+
+        err = codec->getStatus();
+    }
+
+    // Dispose of the request.
+    m_clientManager->releaseRequest(request);
+
+    // Invoke error handler callback function
+    m_clientManager->callErrorHandler(err, m_StopPLCId);
+
+#if ERPC_PRE_POST_ACTION
+    pre_post_action_cb postCB = m_clientManager->getPostCB();
+    if (postCB)
+    {
+        postCB();
+    }
+#endif
+
+
+    if (err != kErpcStatus_Success)
+    {
+        result = 0xFFFFFFFFU;
+    }
+
+    return result;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/C_runtime/erpc_PLCObject_client.hpp	Wed Apr 24 02:15:33 2024 +0200
@@ -0,0 +1,60 @@
+/*
+ * Generated by erpcgen 1.11.0 on Wed Mar 27 13:43:44 2024.
+ *
+ * AUTOGENERATED - DO NOT EDIT
+ */
+
+
+#if !defined(_erpc_PLCObject_client_hpp_)
+#define _erpc_PLCObject_client_hpp_
+
+#include "erpc_PLCObject_interface.hpp"
+
+#include "erpc_client_manager.h"
+
+namespace erpcShim
+{
+
+class BeremizPLCObjectService_client: public BeremizPLCObjectService_interface
+{
+    public:
+        BeremizPLCObjectService_client(erpc::ClientManager *manager);
+
+        virtual ~BeremizPLCObjectService_client();
+
+        virtual uint32_t AppendChunkToBlob(const binary_t * data, const binary_t * blobID, binary_t * newBlobID);
+
+        virtual uint32_t GetLogMessage(uint8_t level, uint32_t msgID, log_message * message);
+
+        virtual uint32_t GetPLCID(PSKID * plcID);
+
+        virtual uint32_t GetPLCstatus(PLCstatus * status);
+
+        virtual uint32_t GetTraceVariables(uint32_t debugToken, TraceVariables * traces);
+
+        virtual uint32_t MatchMD5(const char * MD5, bool * match);
+
+        virtual uint32_t NewPLC(const char * md5sum, const binary_t * plcObjectBlobID, const list_extra_file_1_t * extrafiles, bool * success);
+
+        virtual uint32_t PurgeBlobs(void);
+
+        virtual uint32_t RepairPLC(void);
+
+        virtual uint32_t ResetLogCount(void);
+
+        virtual uint32_t SeedBlob(const binary_t * seed, binary_t * blobID);
+
+        virtual uint32_t SetTraceVariablesList(const list_trace_order_1_t * orders, uint32_t * debugtoken);
+
+        virtual uint32_t StartPLC(void);
+
+        virtual uint32_t StopPLC(bool * success);
+
+    protected:
+        erpc::ClientManager *m_clientManager;
+};
+
+} // erpcShim
+
+
+#endif // _erpc_PLCObject_client_hpp_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/C_runtime/erpc_PLCObject_common.h	Wed Apr 24 02:15:33 2024 +0200
@@ -0,0 +1,129 @@
+/*
+ * Generated by erpcgen 1.11.0 on Wed Mar 27 13:43:44 2024.
+ *
+ * AUTOGENERATED - DO NOT EDIT
+ */
+
+
+#if !defined(_erpc_PLCObject_common_h_)
+#define _erpc_PLCObject_common_h_
+
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include "erpc_version.h"
+
+#if 11100 != ERPC_VERSION_NUMBER
+#error "The generated shim code version is different to the rest of eRPC code."
+#endif
+
+
+#if !defined(ERPC_TYPE_DEFINITIONS_ERPC_PLCOBJECT)
+#define ERPC_TYPE_DEFINITIONS_ERPC_PLCOBJECT
+
+// Enumerators data types declarations
+typedef enum PLCstatus_enum
+{
+    Empty = 0,
+    Stopped = 1,
+    Started = 2,
+    Broken = 3,
+    Disconnected = 4
+} PLCstatus_enum;
+
+// Aliases data types declarations
+typedef struct binary_t binary_t;
+typedef struct PSKID PSKID;
+typedef struct PLCstatus PLCstatus;
+typedef struct trace_sample trace_sample;
+typedef struct list_trace_sample_1_t list_trace_sample_1_t;
+typedef struct TraceVariables TraceVariables;
+typedef struct extra_file extra_file;
+typedef struct list_extra_file_1_t list_extra_file_1_t;
+typedef struct trace_order trace_order;
+typedef struct list_trace_order_1_t list_trace_order_1_t;
+typedef struct log_message log_message;
+
+// Structures/unions data types declarations
+struct binary_t
+{
+    uint8_t * data;
+    uint32_t dataLength;
+};
+
+struct PSKID
+{
+    char * ID;
+    char * PSK;
+};
+
+struct PLCstatus
+{
+    PLCstatus_enum PLCstatus;
+    uint32_t logcounts[4];
+};
+
+struct trace_sample
+{
+    uint32_t tick;
+    binary_t TraceBuffer;
+};
+
+struct list_trace_sample_1_t
+{
+    trace_sample * elements;
+    uint32_t elementsCount;
+};
+
+struct TraceVariables
+{
+    PLCstatus_enum PLCstatus;
+    list_trace_sample_1_t traces;
+};
+
+struct extra_file
+{
+    char * fname;
+    binary_t blobID;
+};
+
+struct list_extra_file_1_t
+{
+    extra_file * elements;
+    uint32_t elementsCount;
+};
+
+struct trace_order
+{
+    uint32_t idx;
+    binary_t force;
+};
+
+struct list_trace_order_1_t
+{
+    trace_order * elements;
+    uint32_t elementsCount;
+};
+
+struct log_message
+{
+    char * msg;
+    uint32_t tick;
+    uint32_t sec;
+    uint32_t nsec;
+};
+
+
+#endif // ERPC_TYPE_DEFINITIONS_ERPC_PLCOBJECT
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif // _erpc_PLCObject_common_h_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/C_runtime/erpc_PLCObject_common.hpp	Wed Apr 24 02:15:33 2024 +0200
@@ -0,0 +1,122 @@
+/*
+ * Generated by erpcgen 1.11.0 on Wed Mar 27 13:43:44 2024.
+ *
+ * AUTOGENERATED - DO NOT EDIT
+ */
+
+
+#if !defined(_erpc_PLCObject_common_hpp_)
+#define _erpc_PLCObject_common_hpp_
+
+
+#include <cstdbool>
+#include <cstddef>
+#include <cstdint>
+
+#include "erpc_version.h"
+
+#if 11100 != ERPC_VERSION_NUMBER
+#error "The generated shim code version is different to the rest of eRPC code."
+#endif
+
+
+#if !defined(ERPC_TYPE_DEFINITIONS_ERPC_PLCOBJECT)
+#define ERPC_TYPE_DEFINITIONS_ERPC_PLCOBJECT
+
+// Enumerators data types declarations
+typedef enum PLCstatus_enum
+{
+    Empty = 0,
+    Stopped = 1,
+    Started = 2,
+    Broken = 3,
+    Disconnected = 4
+} PLCstatus_enum;
+
+// Aliases data types declarations
+typedef struct binary_t binary_t;
+typedef struct PSKID PSKID;
+typedef struct PLCstatus PLCstatus;
+typedef struct trace_sample trace_sample;
+typedef struct list_trace_sample_1_t list_trace_sample_1_t;
+typedef struct TraceVariables TraceVariables;
+typedef struct extra_file extra_file;
+typedef struct list_extra_file_1_t list_extra_file_1_t;
+typedef struct trace_order trace_order;
+typedef struct list_trace_order_1_t list_trace_order_1_t;
+typedef struct log_message log_message;
+
+// Structures/unions data types declarations
+struct binary_t
+{
+    uint8_t * data;
+    uint32_t dataLength;
+};
+
+struct PSKID
+{
+    char * ID;
+    char * PSK;
+};
+
+struct PLCstatus
+{
+    PLCstatus_enum PLCstatus;
+    uint32_t logcounts[4];
+};
+
+struct trace_sample
+{
+    uint32_t tick;
+    binary_t TraceBuffer;
+};
+
+struct list_trace_sample_1_t
+{
+    trace_sample * elements;
+    uint32_t elementsCount;
+};
+
+struct TraceVariables
+{
+    PLCstatus_enum PLCstatus;
+    list_trace_sample_1_t traces;
+};
+
+struct extra_file
+{
+    char * fname;
+    binary_t blobID;
+};
+
+struct list_extra_file_1_t
+{
+    extra_file * elements;
+    uint32_t elementsCount;
+};
+
+struct trace_order
+{
+    uint32_t idx;
+    binary_t force;
+};
+
+struct list_trace_order_1_t
+{
+    trace_order * elements;
+    uint32_t elementsCount;
+};
+
+struct log_message
+{
+    char * msg;
+    uint32_t tick;
+    uint32_t sec;
+    uint32_t nsec;
+};
+
+
+#endif // ERPC_TYPE_DEFINITIONS_ERPC_PLCOBJECT
+
+
+#endif // _erpc_PLCObject_common_hpp_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/C_runtime/erpc_PLCObject_interface.cpp	Wed Apr 24 02:15:33 2024 +0200
@@ -0,0 +1,20 @@
+/*
+ * Generated by erpcgen 1.11.0 on Wed Mar 27 13:43:44 2024.
+ *
+ * AUTOGENERATED - DO NOT EDIT
+ */
+
+
+#include "erpc_PLCObject_interface.hpp"
+
+#if 11100 != ERPC_VERSION_NUMBER
+#error "The generated shim code version is different to the rest of eRPC code."
+#endif
+
+
+using namespace std;
+using namespace erpcShim;
+
+BeremizPLCObjectService_interface::~BeremizPLCObjectService_interface(void)
+{
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/C_runtime/erpc_PLCObject_interface.hpp	Wed Apr 24 02:15:33 2024 +0200
@@ -0,0 +1,71 @@
+/*
+ * Generated by erpcgen 1.11.0 on Wed Mar 27 13:43:44 2024.
+ *
+ * AUTOGENERATED - DO NOT EDIT
+ */
+
+
+#if !defined(_erpc_PLCObject_interface_hpp_)
+#define _erpc_PLCObject_interface_hpp_
+
+#include "erpc_PLCObject_common.hpp"
+
+namespace erpcShim
+{
+
+
+// Abstract base class for BeremizPLCObjectService
+class BeremizPLCObjectService_interface
+{
+    public:
+        static const uint8_t m_serviceId = 1;
+        static const uint8_t m_AppendChunkToBlobId = 1;
+        static const uint8_t m_GetLogMessageId = 2;
+        static const uint8_t m_GetPLCIDId = 3;
+        static const uint8_t m_GetPLCstatusId = 4;
+        static const uint8_t m_GetTraceVariablesId = 5;
+        static const uint8_t m_MatchMD5Id = 6;
+        static const uint8_t m_NewPLCId = 7;
+        static const uint8_t m_PurgeBlobsId = 8;
+        static const uint8_t m_RepairPLCId = 9;
+        static const uint8_t m_ResetLogCountId = 10;
+        static const uint8_t m_SeedBlobId = 11;
+        static const uint8_t m_SetTraceVariablesListId = 12;
+        static const uint8_t m_StartPLCId = 13;
+        static const uint8_t m_StopPLCId = 14;
+
+        virtual ~BeremizPLCObjectService_interface(void);
+
+        virtual uint32_t AppendChunkToBlob(const binary_t * data, const binary_t * blobID, binary_t * newBlobID) = 0;
+
+        virtual uint32_t GetLogMessage(uint8_t level, uint32_t msgID, log_message * message) = 0;
+
+        virtual uint32_t GetPLCID(PSKID * plcID) = 0;
+
+        virtual uint32_t GetPLCstatus(PLCstatus * status) = 0;
+
+        virtual uint32_t GetTraceVariables(uint32_t debugToken, TraceVariables * traces) = 0;
+
+        virtual uint32_t MatchMD5(const char * MD5, bool * match) = 0;
+
+        virtual uint32_t NewPLC(const char * md5sum, const binary_t * plcObjectBlobID, const list_extra_file_1_t * extrafiles, bool * success) = 0;
+
+        virtual uint32_t PurgeBlobs(void) = 0;
+
+        virtual uint32_t RepairPLC(void) = 0;
+
+        virtual uint32_t ResetLogCount(void) = 0;
+
+        virtual uint32_t SeedBlob(const binary_t * seed, binary_t * blobID) = 0;
+
+        virtual uint32_t SetTraceVariablesList(const list_trace_order_1_t * orders, uint32_t * debugtoken) = 0;
+
+        virtual uint32_t StartPLC(void) = 0;
+
+        virtual uint32_t StopPLC(bool * success) = 0;
+private:
+};
+} // erpcShim
+
+
+#endif // _erpc_PLCObject_interface_hpp_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/C_runtime/erpc_PLCObject_server.cpp	Wed Apr 24 02:15:33 2024 +0200
@@ -0,0 +1,1315 @@
+/*
+ * Generated by erpcgen 1.11.0 on Wed Mar 27 13:43:44 2024.
+ *
+ * AUTOGENERATED - DO NOT EDIT
+ */
+
+
+#include "erpc_PLCObject_server.hpp"
+#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
+#include <new>
+#include "erpc_port.h"
+#endif
+#include "erpc_manually_constructed.hpp"
+
+#if 11100 != ERPC_VERSION_NUMBER
+#error "The generated shim code version is different to the rest of eRPC code."
+#endif
+
+using namespace erpc;
+using namespace std;
+using namespace erpcShim;
+
+#if ERPC_NESTED_CALLS_DETECTION
+extern bool nestingDetection;
+#endif
+
+
+//! @brief Function to read struct binary_t
+static void read_binary_t_struct(erpc::Codec * codec, binary_t * data);
+
+//! @brief Function to read struct extra_file
+static void read_extra_file_struct(erpc::Codec * codec, extra_file * data);
+
+//! @brief Function to read struct list_extra_file_1_t
+static void read_list_extra_file_1_t_struct(erpc::Codec * codec, list_extra_file_1_t * data);
+
+//! @brief Function to read struct trace_order
+static void read_trace_order_struct(erpc::Codec * codec, trace_order * data);
+
+//! @brief Function to read struct list_trace_order_1_t
+static void read_list_trace_order_1_t_struct(erpc::Codec * codec, list_trace_order_1_t * data);
+
+
+// Read struct binary_t function implementation
+static void read_binary_t_struct(erpc::Codec * codec, binary_t * data)
+{
+    if(NULL == data)
+    {
+        return;
+    }
+
+    uint8_t * data_local;
+    codec->readBinary(data->dataLength, &data_local);
+    if (data->dataLength > 0)
+    {
+    data->data = (uint8_t *) erpc_malloc(data->dataLength * sizeof(uint8_t));
+        if (data->data == NULL)
+        {
+            codec->updateStatus(kErpcStatus_MemoryError);
+        }
+        else
+        {
+            memcpy(data->data, data_local, data->dataLength);
+        }
+    }
+    else
+    {
+        data->data = NULL;
+    }
+}
+
+// Read struct extra_file function implementation
+static void read_extra_file_struct(erpc::Codec * codec, extra_file * data)
+{
+    if(NULL == data)
+    {
+        return;
+    }
+
+    {
+        uint32_t fname_len;
+        char * fname_local;
+        codec->readString(fname_len, &fname_local);
+        data->fname = (char*) erpc_malloc((fname_len + 1) * sizeof(char));
+        if ((data->fname == NULL) || (fname_local == NULL))
+        {
+            codec->updateStatus(kErpcStatus_MemoryError);
+        }
+        else
+        {
+            memcpy(data->fname, fname_local, fname_len);
+            (data->fname)[fname_len] = 0;
+        }
+    }
+
+    read_binary_t_struct(codec, &(data->blobID));
+}
+
+// Read struct list_extra_file_1_t function implementation
+static void read_list_extra_file_1_t_struct(erpc::Codec * codec, list_extra_file_1_t * data)
+{
+    if(NULL == data)
+    {
+        return;
+    }
+
+    codec->startReadList(data->elementsCount);
+    data->elements = (extra_file *) erpc_malloc(data->elementsCount * sizeof(extra_file));
+    if ((data->elements == NULL) && (data->elementsCount > 0))
+    {
+        codec->updateStatus(kErpcStatus_MemoryError);
+    }
+    for (uint32_t listCount = 0U; listCount < data->elementsCount; ++listCount)
+    {
+        read_extra_file_struct(codec, &(data->elements[listCount]));
+    }
+}
+
+// Read struct trace_order function implementation
+static void read_trace_order_struct(erpc::Codec * codec, trace_order * data)
+{
+    if(NULL == data)
+    {
+        return;
+    }
+
+    codec->read(data->idx);
+
+    read_binary_t_struct(codec, &(data->force));
+}
+
+// Read struct list_trace_order_1_t function implementation
+static void read_list_trace_order_1_t_struct(erpc::Codec * codec, list_trace_order_1_t * data)
+{
+    if(NULL == data)
+    {
+        return;
+    }
+
+    codec->startReadList(data->elementsCount);
+    data->elements = (trace_order *) erpc_malloc(data->elementsCount * sizeof(trace_order));
+    if ((data->elements == NULL) && (data->elementsCount > 0))
+    {
+        codec->updateStatus(kErpcStatus_MemoryError);
+    }
+    for (uint32_t listCount = 0U; listCount < data->elementsCount; ++listCount)
+    {
+        read_trace_order_struct(codec, &(data->elements[listCount]));
+    }
+}
+
+
+//! @brief Function to write struct binary_t
+static void write_binary_t_struct(erpc::Codec * codec, const binary_t * data);
+
+//! @brief Function to write struct log_message
+static void write_log_message_struct(erpc::Codec * codec, const log_message * data);
+
+//! @brief Function to write struct PSKID
+static void write_PSKID_struct(erpc::Codec * codec, const PSKID * data);
+
+//! @brief Function to write struct PLCstatus
+static void write_PLCstatus_struct(erpc::Codec * codec, const PLCstatus * data);
+
+//! @brief Function to write struct trace_sample
+static void write_trace_sample_struct(erpc::Codec * codec, const trace_sample * data);
+
+//! @brief Function to write struct TraceVariables
+static void write_TraceVariables_struct(erpc::Codec * codec, const TraceVariables * data);
+
+//! @brief Function to write struct list_trace_sample_1_t
+static void write_list_trace_sample_1_t_struct(erpc::Codec * codec, const list_trace_sample_1_t * data);
+
+
+// Write struct binary_t function implementation
+static void write_binary_t_struct(erpc::Codec * codec, const binary_t * data)
+{
+    if(NULL == data)
+    {
+        return;
+    }
+
+    codec->writeBinary(data->dataLength, data->data);
+}
+
+// Write struct log_message function implementation
+static void write_log_message_struct(erpc::Codec * codec, const log_message * data)
+{
+    if(NULL == data)
+    {
+        return;
+    }
+
+    {
+        uint32_t msg_len = strlen((const char*)data->msg);
+
+        codec->writeString(msg_len, (const char*)data->msg);
+    }
+
+    codec->write(data->tick);
+
+    codec->write(data->sec);
+
+    codec->write(data->nsec);
+}
+
+// Write struct PSKID function implementation
+static void write_PSKID_struct(erpc::Codec * codec, const PSKID * data)
+{
+    if(NULL == data)
+    {
+        return;
+    }
+
+    {
+        uint32_t ID_len = strlen((const char*)data->ID);
+
+        codec->writeString(ID_len, (const char*)data->ID);
+    }
+
+    {
+        uint32_t PSK_len = strlen((const char*)data->PSK);
+
+        codec->writeString(PSK_len, (const char*)data->PSK);
+    }
+}
+
+// Write struct PLCstatus function implementation
+static void write_PLCstatus_struct(erpc::Codec * codec, const PLCstatus * data)
+{
+    if(NULL == data)
+    {
+        return;
+    }
+
+    codec->write(static_cast<int32_t>(data->PLCstatus));
+
+    for (uint32_t arrayCount0 = 0U; arrayCount0 < 4U; ++arrayCount0)
+    {
+        codec->write(data->logcounts[arrayCount0]);
+    }
+}
+
+// Write struct trace_sample function implementation
+static void write_trace_sample_struct(erpc::Codec * codec, const trace_sample * data)
+{
+    if(NULL == data)
+    {
+        return;
+    }
+
+    codec->write(data->tick);
+
+    write_binary_t_struct(codec, &(data->TraceBuffer));
+}
+
+// Write struct TraceVariables function implementation
+static void write_TraceVariables_struct(erpc::Codec * codec, const TraceVariables * data)
+{
+    if(NULL == data)
+    {
+        return;
+    }
+
+    codec->write(static_cast<int32_t>(data->PLCstatus));
+
+    write_list_trace_sample_1_t_struct(codec, &(data->traces));
+}
+
+// Write struct list_trace_sample_1_t function implementation
+static void write_list_trace_sample_1_t_struct(erpc::Codec * codec, const list_trace_sample_1_t * data)
+{
+    if(NULL == data)
+    {
+        return;
+    }
+
+    codec->startWriteList(data->elementsCount);
+    for (uint32_t listCount = 0U; listCount < data->elementsCount; ++listCount)
+    {
+        write_trace_sample_struct(codec, &(data->elements[listCount]));
+    }
+}
+
+
+//! @brief Function to free space allocated inside struct binary_t
+static void free_binary_t_struct(binary_t * data);
+
+//! @brief Function to free space allocated inside struct log_message
+static void free_log_message_struct(log_message * data);
+
+//! @brief Function to free space allocated inside struct PSKID
+static void free_PSKID_struct(PSKID * data);
+
+//! @brief Function to free space allocated inside struct trace_sample
+static void free_trace_sample_struct(trace_sample * data);
+
+//! @brief Function to free space allocated inside struct TraceVariables
+static void free_TraceVariables_struct(TraceVariables * data);
+
+//! @brief Function to free space allocated inside struct list_trace_sample_1_t
+static void free_list_trace_sample_1_t_struct(list_trace_sample_1_t * data);
+
+//! @brief Function to free space allocated inside struct extra_file
+static void free_extra_file_struct(extra_file * data);
+
+//! @brief Function to free space allocated inside struct list_extra_file_1_t
+static void free_list_extra_file_1_t_struct(list_extra_file_1_t * data);
+
+//! @brief Function to free space allocated inside struct trace_order
+static void free_trace_order_struct(trace_order * data);
+
+//! @brief Function to free space allocated inside struct list_trace_order_1_t
+static void free_list_trace_order_1_t_struct(list_trace_order_1_t * data);
+
+
+// Free space allocated inside struct binary_t function implementation
+static void free_binary_t_struct(binary_t * data)
+{
+    erpc_free(data->data);
+}
+
+// Free space allocated inside struct log_message function implementation
+static void free_log_message_struct(log_message * data)
+{
+    erpc_free(data->msg);
+}
+
+// Free space allocated inside struct PSKID function implementation
+static void free_PSKID_struct(PSKID * data)
+{
+    erpc_free(data->ID);
+
+    erpc_free(data->PSK);
+}
+
+// Free space allocated inside struct trace_sample function implementation
+static void free_trace_sample_struct(trace_sample * data)
+{
+    free_binary_t_struct(&data->TraceBuffer);
+}
+
+// Free space allocated inside struct TraceVariables function implementation
+static void free_TraceVariables_struct(TraceVariables * data)
+{
+    free_list_trace_sample_1_t_struct(&data->traces);
+}
+
+// Free space allocated inside struct list_trace_sample_1_t function implementation
+static void free_list_trace_sample_1_t_struct(list_trace_sample_1_t * data)
+{
+    for (uint32_t listCount = 0; listCount < data->elementsCount; ++listCount)
+    {
+        free_trace_sample_struct(&data->elements[listCount]);
+    }
+
+    erpc_free(data->elements);
+}
+
+// Free space allocated inside struct extra_file function implementation
+static void free_extra_file_struct(extra_file * data)
+{
+    erpc_free(data->fname);
+
+    free_binary_t_struct(&data->blobID);
+}
+
+// Free space allocated inside struct list_extra_file_1_t function implementation
+static void free_list_extra_file_1_t_struct(list_extra_file_1_t * data)
+{
+    for (uint32_t listCount = 0; listCount < data->elementsCount; ++listCount)
+    {
+        free_extra_file_struct(&data->elements[listCount]);
+    }
+
+    erpc_free(data->elements);
+}
+
+// Free space allocated inside struct trace_order function implementation
+static void free_trace_order_struct(trace_order * data)
+{
+    free_binary_t_struct(&data->force);
+}
+
+// Free space allocated inside struct list_trace_order_1_t function implementation
+static void free_list_trace_order_1_t_struct(list_trace_order_1_t * data)
+{
+    for (uint32_t listCount = 0; listCount < data->elementsCount; ++listCount)
+    {
+        free_trace_order_struct(&data->elements[listCount]);
+    }
+
+    erpc_free(data->elements);
+}
+
+
+
+BeremizPLCObjectService_service::BeremizPLCObjectService_service(BeremizPLCObjectService_interface *_BeremizPLCObjectService_interface)
+    : erpc::Service(BeremizPLCObjectService_interface::m_serviceId)
+    , m_handler(_BeremizPLCObjectService_interface)
+{
+}
+
+BeremizPLCObjectService_service::~BeremizPLCObjectService_service()
+{
+}
+
+// return service interface handler.
+BeremizPLCObjectService_interface* BeremizPLCObjectService_service::getHandler(void)
+{
+    return m_handler;
+}
+
+// Call the correct server shim based on method unique ID.
+erpc_status_t BeremizPLCObjectService_service::handleInvocation(uint32_t methodId, uint32_t sequence, Codec * codec, MessageBufferFactory *messageFactory, Transport * transport)
+{
+    erpc_status_t erpcStatus;
+    switch (methodId)
+    {
+        case BeremizPLCObjectService_interface::m_AppendChunkToBlobId:
+        {
+            erpcStatus = AppendChunkToBlob_shim(codec, messageFactory, transport, sequence);
+            break;
+        }
+
+        case BeremizPLCObjectService_interface::m_GetLogMessageId:
+        {
+            erpcStatus = GetLogMessage_shim(codec, messageFactory, transport, sequence);
+            break;
+        }
+
+        case BeremizPLCObjectService_interface::m_GetPLCIDId:
+        {
+            erpcStatus = GetPLCID_shim(codec, messageFactory, transport, sequence);
+            break;
+        }
+
+        case BeremizPLCObjectService_interface::m_GetPLCstatusId:
+        {
+            erpcStatus = GetPLCstatus_shim(codec, messageFactory, transport, sequence);
+            break;
+        }
+
+        case BeremizPLCObjectService_interface::m_GetTraceVariablesId:
+        {
+            erpcStatus = GetTraceVariables_shim(codec, messageFactory, transport, sequence);
+            break;
+        }
+
+        case BeremizPLCObjectService_interface::m_MatchMD5Id:
+        {
+            erpcStatus = MatchMD5_shim(codec, messageFactory, transport, sequence);
+            break;
+        }
+
+        case BeremizPLCObjectService_interface::m_NewPLCId:
+        {
+            erpcStatus = NewPLC_shim(codec, messageFactory, transport, sequence);
+            break;
+        }
+
+        case BeremizPLCObjectService_interface::m_PurgeBlobsId:
+        {
+            erpcStatus = PurgeBlobs_shim(codec, messageFactory, transport, sequence);
+            break;
+        }
+
+        case BeremizPLCObjectService_interface::m_RepairPLCId:
+        {
+            erpcStatus = RepairPLC_shim(codec, messageFactory, transport, sequence);
+            break;
+        }
+
+        case BeremizPLCObjectService_interface::m_ResetLogCountId:
+        {
+            erpcStatus = ResetLogCount_shim(codec, messageFactory, transport, sequence);
+            break;
+        }
+
+        case BeremizPLCObjectService_interface::m_SeedBlobId:
+        {
+            erpcStatus = SeedBlob_shim(codec, messageFactory, transport, sequence);
+            break;
+        }
+
+        case BeremizPLCObjectService_interface::m_SetTraceVariablesListId:
+        {
+            erpcStatus = SetTraceVariablesList_shim(codec, messageFactory, transport, sequence);
+            break;
+        }
+
+        case BeremizPLCObjectService_interface::m_StartPLCId:
+        {
+            erpcStatus = StartPLC_shim(codec, messageFactory, transport, sequence);
+            break;
+        }
+
+        case BeremizPLCObjectService_interface::m_StopPLCId:
+        {
+            erpcStatus = StopPLC_shim(codec, messageFactory, transport, sequence);
+            break;
+        }
+
+        default:
+        {
+            erpcStatus = kErpcStatus_InvalidArgument;
+            break;
+        }
+    }
+
+    return erpcStatus;
+}
+
+// Server shim for AppendChunkToBlob of BeremizPLCObjectService interface.
+erpc_status_t BeremizPLCObjectService_service::AppendChunkToBlob_shim(Codec * codec, MessageBufferFactory *messageFactory, Transport * transport, uint32_t sequence)
+{
+    erpc_status_t err = kErpcStatus_Success;
+
+    binary_t *data = NULL;
+    data = (binary_t *) erpc_malloc(sizeof(binary_t));
+    if (data == NULL)
+    {
+        codec->updateStatus(kErpcStatus_MemoryError);
+    }
+    binary_t *blobID = NULL;
+    blobID = (binary_t *) erpc_malloc(sizeof(binary_t));
+    if (blobID == NULL)
+    {
+        codec->updateStatus(kErpcStatus_MemoryError);
+    }
+    binary_t *newBlobID = NULL;
+    uint32_t result;
+
+    // startReadMessage() was already called before this shim was invoked.
+
+    read_binary_t_struct(codec, data);
+
+    read_binary_t_struct(codec, blobID);
+
+    newBlobID = (binary_t *) erpc_malloc(sizeof(binary_t));
+    if (newBlobID == NULL)
+    {
+        codec->updateStatus(kErpcStatus_MemoryError);
+    }
+
+    err = codec->getStatus();
+    if (err == kErpcStatus_Success)
+    {
+        // Invoke the actual served function.
+#if ERPC_NESTED_CALLS_DETECTION
+        nestingDetection = true;
+#endif
+        result = m_handler->AppendChunkToBlob(data, blobID, newBlobID);
+#if ERPC_NESTED_CALLS_DETECTION
+        nestingDetection = false;
+#endif
+
+        // preparing MessageBuffer for serializing data
+        err = messageFactory->prepareServerBufferForSend(codec->getBufferRef(), transport->reserveHeaderSize());
+    }
+
+    if (err == kErpcStatus_Success)
+    {
+        // preparing codec for serializing data
+        codec->reset(transport->reserveHeaderSize());
+
+        // Build response message.
+        codec->startWriteMessage(message_type_t::kReplyMessage, BeremizPLCObjectService_interface::m_serviceId, BeremizPLCObjectService_interface::m_AppendChunkToBlobId, sequence);
+
+        write_binary_t_struct(codec, newBlobID);
+
+        codec->write(result);
+
+        err = codec->getStatus();
+    }
+
+    if (data)
+    {
+        free_binary_t_struct(data);
+    }
+    erpc_free(data);
+
+    if (blobID)
+    {
+        free_binary_t_struct(blobID);
+    }
+    erpc_free(blobID);
+
+    if (newBlobID)
+    {
+        free_binary_t_struct(newBlobID);
+    }
+    erpc_free(newBlobID);
+
+    return err;
+}
+
+// Server shim for GetLogMessage of BeremizPLCObjectService interface.
+erpc_status_t BeremizPLCObjectService_service::GetLogMessage_shim(Codec * codec, MessageBufferFactory *messageFactory, Transport * transport, uint32_t sequence)
+{
+    erpc_status_t err = kErpcStatus_Success;
+
+    uint8_t level;
+    uint32_t msgID;
+    log_message *message = NULL;
+    uint32_t result;
+
+    // startReadMessage() was already called before this shim was invoked.
+
+    codec->read(level);
+
+    codec->read(msgID);
+
+    message = (log_message *) erpc_malloc(sizeof(log_message));
+    if (message == NULL)
+    {
+        codec->updateStatus(kErpcStatus_MemoryError);
+    }
+
+    err = codec->getStatus();
+    if (err == kErpcStatus_Success)
+    {
+        // Invoke the actual served function.
+#if ERPC_NESTED_CALLS_DETECTION
+        nestingDetection = true;
+#endif
+        result = m_handler->GetLogMessage(level, msgID, message);
+#if ERPC_NESTED_CALLS_DETECTION
+        nestingDetection = false;
+#endif
+
+        // preparing MessageBuffer for serializing data
+        err = messageFactory->prepareServerBufferForSend(codec->getBufferRef(), transport->reserveHeaderSize());
+    }
+
+    if (err == kErpcStatus_Success)
+    {
+        // preparing codec for serializing data
+        codec->reset(transport->reserveHeaderSize());
+
+        // Build response message.
+        codec->startWriteMessage(message_type_t::kReplyMessage, BeremizPLCObjectService_interface::m_serviceId, BeremizPLCObjectService_interface::m_GetLogMessageId, sequence);
+
+        write_log_message_struct(codec, message);
+
+        codec->write(result);
+
+        err = codec->getStatus();
+    }
+
+    if (message)
+    {
+        free_log_message_struct(message);
+    }
+    erpc_free(message);
+
+    return err;
+}
+
+// Server shim for GetPLCID of BeremizPLCObjectService interface.
+erpc_status_t BeremizPLCObjectService_service::GetPLCID_shim(Codec * codec, MessageBufferFactory *messageFactory, Transport * transport, uint32_t sequence)
+{
+    erpc_status_t err = kErpcStatus_Success;
+
+    PSKID *plcID = NULL;
+    uint32_t result;
+
+    // startReadMessage() was already called before this shim was invoked.
+
+    plcID = (PSKID *) erpc_malloc(sizeof(PSKID));
+    if (plcID == NULL)
+    {
+        codec->updateStatus(kErpcStatus_MemoryError);
+    }
+
+    err = codec->getStatus();
+    if (err == kErpcStatus_Success)
+    {
+        // Invoke the actual served function.
+#if ERPC_NESTED_CALLS_DETECTION
+        nestingDetection = true;
+#endif
+        result = m_handler->GetPLCID(plcID);
+#if ERPC_NESTED_CALLS_DETECTION
+        nestingDetection = false;
+#endif
+
+        // preparing MessageBuffer for serializing data
+        err = messageFactory->prepareServerBufferForSend(codec->getBufferRef(), transport->reserveHeaderSize());
+    }
+
+    if (err == kErpcStatus_Success)
+    {
+        // preparing codec for serializing data
+        codec->reset(transport->reserveHeaderSize());
+
+        // Build response message.
+        codec->startWriteMessage(message_type_t::kReplyMessage, BeremizPLCObjectService_interface::m_serviceId, BeremizPLCObjectService_interface::m_GetPLCIDId, sequence);
+
+        write_PSKID_struct(codec, plcID);
+
+        codec->write(result);
+
+        err = codec->getStatus();
+    }
+
+    if (plcID)
+    {
+        free_PSKID_struct(plcID);
+    }
+    erpc_free(plcID);
+
+    return err;
+}
+
+// Server shim for GetPLCstatus of BeremizPLCObjectService interface.
+erpc_status_t BeremizPLCObjectService_service::GetPLCstatus_shim(Codec * codec, MessageBufferFactory *messageFactory, Transport * transport, uint32_t sequence)
+{
+    erpc_status_t err = kErpcStatus_Success;
+
+    PLCstatus *status = NULL;
+    uint32_t result;
+
+    // startReadMessage() was already called before this shim was invoked.
+
+    status = (PLCstatus *) erpc_malloc(sizeof(PLCstatus));
+    if (status == NULL)
+    {
+        codec->updateStatus(kErpcStatus_MemoryError);
+    }
+
+    err = codec->getStatus();
+    if (err == kErpcStatus_Success)
+    {
+        // Invoke the actual served function.
+#if ERPC_NESTED_CALLS_DETECTION
+        nestingDetection = true;
+#endif
+        result = m_handler->GetPLCstatus(status);
+#if ERPC_NESTED_CALLS_DETECTION
+        nestingDetection = false;
+#endif
+
+        // preparing MessageBuffer for serializing data
+        err = messageFactory->prepareServerBufferForSend(codec->getBufferRef(), transport->reserveHeaderSize());
+    }
+
+    if (err == kErpcStatus_Success)
+    {
+        // preparing codec for serializing data
+        codec->reset(transport->reserveHeaderSize());
+
+        // Build response message.
+        codec->startWriteMessage(message_type_t::kReplyMessage, BeremizPLCObjectService_interface::m_serviceId, BeremizPLCObjectService_interface::m_GetPLCstatusId, sequence);
+
+        write_PLCstatus_struct(codec, status);
+
+        codec->write(result);
+
+        err = codec->getStatus();
+    }
+
+    erpc_free(status);
+
+    return err;
+}
+
+// Server shim for GetTraceVariables of BeremizPLCObjectService interface.
+erpc_status_t BeremizPLCObjectService_service::GetTraceVariables_shim(Codec * codec, MessageBufferFactory *messageFactory, Transport * transport, uint32_t sequence)
+{
+    erpc_status_t err = kErpcStatus_Success;
+
+    uint32_t debugToken;
+    TraceVariables *traces = NULL;
+    uint32_t result;
+
+    // startReadMessage() was already called before this shim was invoked.
+
+    codec->read(debugToken);
+
+    traces = (TraceVariables *) erpc_malloc(sizeof(TraceVariables));
+    if (traces == NULL)
+    {
+        codec->updateStatus(kErpcStatus_MemoryError);
+    }
+
+    err = codec->getStatus();
+    if (err == kErpcStatus_Success)
+    {
+        // Invoke the actual served function.
+#if ERPC_NESTED_CALLS_DETECTION
+        nestingDetection = true;
+#endif
+        result = m_handler->GetTraceVariables(debugToken, traces);
+#if ERPC_NESTED_CALLS_DETECTION
+        nestingDetection = false;
+#endif
+
+        // preparing MessageBuffer for serializing data
+        err = messageFactory->prepareServerBufferForSend(codec->getBufferRef(), transport->reserveHeaderSize());
+    }
+
+    if (err == kErpcStatus_Success)
+    {
+        // preparing codec for serializing data
+        codec->reset(transport->reserveHeaderSize());
+
+        // Build response message.
+        codec->startWriteMessage(message_type_t::kReplyMessage, BeremizPLCObjectService_interface::m_serviceId, BeremizPLCObjectService_interface::m_GetTraceVariablesId, sequence);
+
+        write_TraceVariables_struct(codec, traces);
+
+        codec->write(result);
+
+        err = codec->getStatus();
+    }
+
+    if (traces)
+    {
+        free_TraceVariables_struct(traces);
+    }
+    erpc_free(traces);
+
+    return err;
+}
+
+// Server shim for MatchMD5 of BeremizPLCObjectService interface.
+erpc_status_t BeremizPLCObjectService_service::MatchMD5_shim(Codec * codec, MessageBufferFactory *messageFactory, Transport * transport, uint32_t sequence)
+{
+    erpc_status_t err = kErpcStatus_Success;
+
+    char * MD5 = NULL;
+    bool match;
+    uint32_t result;
+
+    // startReadMessage() was already called before this shim was invoked.
+
+    {
+        uint32_t MD5_len;
+        char * MD5_local;
+        codec->readString(MD5_len, &MD5_local);
+        MD5 = (char*) erpc_malloc((MD5_len + 1) * sizeof(char));
+        if ((MD5 == NULL) || (MD5_local == NULL))
+        {
+            codec->updateStatus(kErpcStatus_MemoryError);
+        }
+        else
+        {
+            memcpy(MD5, MD5_local, MD5_len);
+            (MD5)[MD5_len] = 0;
+        }
+    }
+
+    err = codec->getStatus();
+    if (err == kErpcStatus_Success)
+    {
+        // Invoke the actual served function.
+#if ERPC_NESTED_CALLS_DETECTION
+        nestingDetection = true;
+#endif
+        result = m_handler->MatchMD5(MD5, &match);
+#if ERPC_NESTED_CALLS_DETECTION
+        nestingDetection = false;
+#endif
+
+        // preparing MessageBuffer for serializing data
+        err = messageFactory->prepareServerBufferForSend(codec->getBufferRef(), transport->reserveHeaderSize());
+    }
+
+    if (err == kErpcStatus_Success)
+    {
+        // preparing codec for serializing data
+        codec->reset(transport->reserveHeaderSize());
+
+        // Build response message.
+        codec->startWriteMessage(message_type_t::kReplyMessage, BeremizPLCObjectService_interface::m_serviceId, BeremizPLCObjectService_interface::m_MatchMD5Id, sequence);
+
+        codec->write(match);
+
+        codec->write(result);
+
+        err = codec->getStatus();
+    }
+
+    erpc_free(MD5);
+
+    return err;
+}
+
+// Server shim for NewPLC of BeremizPLCObjectService interface.
+erpc_status_t BeremizPLCObjectService_service::NewPLC_shim(Codec * codec, MessageBufferFactory *messageFactory, Transport * transport, uint32_t sequence)
+{
+    erpc_status_t err = kErpcStatus_Success;
+
+    char * md5sum = NULL;
+    binary_t *plcObjectBlobID = NULL;
+    plcObjectBlobID = (binary_t *) erpc_malloc(sizeof(binary_t));
+    if (plcObjectBlobID == NULL)
+    {
+        codec->updateStatus(kErpcStatus_MemoryError);
+    }
+    list_extra_file_1_t *extrafiles = NULL;
+    extrafiles = (list_extra_file_1_t *) erpc_malloc(sizeof(list_extra_file_1_t));
+    if (extrafiles == NULL)
+    {
+        codec->updateStatus(kErpcStatus_MemoryError);
+    }
+    bool success;
+    uint32_t result;
+
+    // startReadMessage() was already called before this shim was invoked.
+
+    {
+        uint32_t md5sum_len;
+        char * md5sum_local;
+        codec->readString(md5sum_len, &md5sum_local);
+        md5sum = (char*) erpc_malloc((md5sum_len + 1) * sizeof(char));
+        if ((md5sum == NULL) || (md5sum_local == NULL))
+        {
+            codec->updateStatus(kErpcStatus_MemoryError);
+        }
+        else
+        {
+            memcpy(md5sum, md5sum_local, md5sum_len);
+            (md5sum)[md5sum_len] = 0;
+        }
+    }
+
+    read_binary_t_struct(codec, plcObjectBlobID);
+
+    read_list_extra_file_1_t_struct(codec, extrafiles);
+
+    err = codec->getStatus();
+    if (err == kErpcStatus_Success)
+    {
+        // Invoke the actual served function.
+#if ERPC_NESTED_CALLS_DETECTION
+        nestingDetection = true;
+#endif
+        result = m_handler->NewPLC(md5sum, plcObjectBlobID, extrafiles, &success);
+#if ERPC_NESTED_CALLS_DETECTION
+        nestingDetection = false;
+#endif
+
+        // preparing MessageBuffer for serializing data
+        err = messageFactory->prepareServerBufferForSend(codec->getBufferRef(), transport->reserveHeaderSize());
+    }
+
+    if (err == kErpcStatus_Success)
+    {
+        // preparing codec for serializing data
+        codec->reset(transport->reserveHeaderSize());
+
+        // Build response message.
+        codec->startWriteMessage(message_type_t::kReplyMessage, BeremizPLCObjectService_interface::m_serviceId, BeremizPLCObjectService_interface::m_NewPLCId, sequence);
+
+        codec->write(success);
+
+        codec->write(result);
+
+        err = codec->getStatus();
+    }
+
+    erpc_free(md5sum);
+
+    if (plcObjectBlobID)
+    {
+        free_binary_t_struct(plcObjectBlobID);
+    }
+    erpc_free(plcObjectBlobID);
+
+    if (extrafiles)
+    {
+        free_list_extra_file_1_t_struct(extrafiles);
+    }
+    erpc_free(extrafiles);
+
+    return err;
+}
+
+// Server shim for PurgeBlobs of BeremizPLCObjectService interface.
+erpc_status_t BeremizPLCObjectService_service::PurgeBlobs_shim(Codec * codec, MessageBufferFactory *messageFactory, Transport * transport, uint32_t sequence)
+{
+    erpc_status_t err = kErpcStatus_Success;
+
+    uint32_t result;
+
+    // startReadMessage() was already called before this shim was invoked.
+
+    err = codec->getStatus();
+    if (err == kErpcStatus_Success)
+    {
+        // Invoke the actual served function.
+#if ERPC_NESTED_CALLS_DETECTION
+        nestingDetection = true;
+#endif
+        result = m_handler->PurgeBlobs();
+#if ERPC_NESTED_CALLS_DETECTION
+        nestingDetection = false;
+#endif
+
+        // preparing MessageBuffer for serializing data
+        err = messageFactory->prepareServerBufferForSend(codec->getBufferRef(), transport->reserveHeaderSize());
+    }
+
+    if (err == kErpcStatus_Success)
+    {
+        // preparing codec for serializing data
+        codec->reset(transport->reserveHeaderSize());
+
+        // Build response message.
+        codec->startWriteMessage(message_type_t::kReplyMessage, BeremizPLCObjectService_interface::m_serviceId, BeremizPLCObjectService_interface::m_PurgeBlobsId, sequence);
+
+        codec->write(result);
+
+        err = codec->getStatus();
+    }
+
+    return err;
+}
+
+// Server shim for RepairPLC of BeremizPLCObjectService interface.
+erpc_status_t BeremizPLCObjectService_service::RepairPLC_shim(Codec * codec, MessageBufferFactory *messageFactory, Transport * transport, uint32_t sequence)
+{
+    erpc_status_t err = kErpcStatus_Success;
+
+    uint32_t result;
+
+    // startReadMessage() was already called before this shim was invoked.
+
+    err = codec->getStatus();
+    if (err == kErpcStatus_Success)
+    {
+        // Invoke the actual served function.
+#if ERPC_NESTED_CALLS_DETECTION
+        nestingDetection = true;
+#endif
+        result = m_handler->RepairPLC();
+#if ERPC_NESTED_CALLS_DETECTION
+        nestingDetection = false;
+#endif
+
+        // preparing MessageBuffer for serializing data
+        err = messageFactory->prepareServerBufferForSend(codec->getBufferRef(), transport->reserveHeaderSize());
+    }
+
+    if (err == kErpcStatus_Success)
+    {
+        // preparing codec for serializing data
+        codec->reset(transport->reserveHeaderSize());
+
+        // Build response message.
+        codec->startWriteMessage(message_type_t::kReplyMessage, BeremizPLCObjectService_interface::m_serviceId, BeremizPLCObjectService_interface::m_RepairPLCId, sequence);
+
+        codec->write(result);
+
+        err = codec->getStatus();
+    }
+
+    return err;
+}
+
+// Server shim for ResetLogCount of BeremizPLCObjectService interface.
+erpc_status_t BeremizPLCObjectService_service::ResetLogCount_shim(Codec * codec, MessageBufferFactory *messageFactory, Transport * transport, uint32_t sequence)
+{
+    erpc_status_t err = kErpcStatus_Success;
+
+    uint32_t result;
+
+    // startReadMessage() was already called before this shim was invoked.
+
+    err = codec->getStatus();
+    if (err == kErpcStatus_Success)
+    {
+        // Invoke the actual served function.
+#if ERPC_NESTED_CALLS_DETECTION
+        nestingDetection = true;
+#endif
+        result = m_handler->ResetLogCount();
+#if ERPC_NESTED_CALLS_DETECTION
+        nestingDetection = false;
+#endif
+
+        // preparing MessageBuffer for serializing data
+        err = messageFactory->prepareServerBufferForSend(codec->getBufferRef(), transport->reserveHeaderSize());
+    }
+
+    if (err == kErpcStatus_Success)
+    {
+        // preparing codec for serializing data
+        codec->reset(transport->reserveHeaderSize());
+
+        // Build response message.
+        codec->startWriteMessage(message_type_t::kReplyMessage, BeremizPLCObjectService_interface::m_serviceId, BeremizPLCObjectService_interface::m_ResetLogCountId, sequence);
+
+        codec->write(result);
+
+        err = codec->getStatus();
+    }
+
+    return err;
+}
+
+// Server shim for SeedBlob of BeremizPLCObjectService interface.
+erpc_status_t BeremizPLCObjectService_service::SeedBlob_shim(Codec * codec, MessageBufferFactory *messageFactory, Transport * transport, uint32_t sequence)
+{
+    erpc_status_t err = kErpcStatus_Success;
+
+    binary_t *seed = NULL;
+    seed = (binary_t *) erpc_malloc(sizeof(binary_t));
+    if (seed == NULL)
+    {
+        codec->updateStatus(kErpcStatus_MemoryError);
+    }
+    binary_t *blobID = NULL;
+    uint32_t result;
+
+    // startReadMessage() was already called before this shim was invoked.
+
+    read_binary_t_struct(codec, seed);
+
+    blobID = (binary_t *) erpc_malloc(sizeof(binary_t));
+    if (blobID == NULL)
+    {
+        codec->updateStatus(kErpcStatus_MemoryError);
+    }
+
+    err = codec->getStatus();
+    if (err == kErpcStatus_Success)
+    {
+        // Invoke the actual served function.
+#if ERPC_NESTED_CALLS_DETECTION
+        nestingDetection = true;
+#endif
+        result = m_handler->SeedBlob(seed, blobID);
+#if ERPC_NESTED_CALLS_DETECTION
+        nestingDetection = false;
+#endif
+
+        // preparing MessageBuffer for serializing data
+        err = messageFactory->prepareServerBufferForSend(codec->getBufferRef(), transport->reserveHeaderSize());
+    }
+
+    if (err == kErpcStatus_Success)
+    {
+        // preparing codec for serializing data
+        codec->reset(transport->reserveHeaderSize());
+
+        // Build response message.
+        codec->startWriteMessage(message_type_t::kReplyMessage, BeremizPLCObjectService_interface::m_serviceId, BeremizPLCObjectService_interface::m_SeedBlobId, sequence);
+
+        write_binary_t_struct(codec, blobID);
+
+        codec->write(result);
+
+        err = codec->getStatus();
+    }
+
+    if (seed)
+    {
+        free_binary_t_struct(seed);
+    }
+    erpc_free(seed);
+
+    if (blobID)
+    {
+        free_binary_t_struct(blobID);
+    }
+    erpc_free(blobID);
+
+    return err;
+}
+
+// Server shim for SetTraceVariablesList of BeremizPLCObjectService interface.
+erpc_status_t BeremizPLCObjectService_service::SetTraceVariablesList_shim(Codec * codec, MessageBufferFactory *messageFactory, Transport * transport, uint32_t sequence)
+{
+    erpc_status_t err = kErpcStatus_Success;
+
+    list_trace_order_1_t *orders = NULL;
+    orders = (list_trace_order_1_t *) erpc_malloc(sizeof(list_trace_order_1_t));
+    if (orders == NULL)
+    {
+        codec->updateStatus(kErpcStatus_MemoryError);
+    }
+    uint32_t debugtoken;
+    uint32_t result;
+
+    // startReadMessage() was already called before this shim was invoked.
+
+    read_list_trace_order_1_t_struct(codec, orders);
+
+    err = codec->getStatus();
+    if (err == kErpcStatus_Success)
+    {
+        // Invoke the actual served function.
+#if ERPC_NESTED_CALLS_DETECTION
+        nestingDetection = true;
+#endif
+        result = m_handler->SetTraceVariablesList(orders, &debugtoken);
+#if ERPC_NESTED_CALLS_DETECTION
+        nestingDetection = false;
+#endif
+
+        // preparing MessageBuffer for serializing data
+        err = messageFactory->prepareServerBufferForSend(codec->getBufferRef(), transport->reserveHeaderSize());
+    }
+
+    if (err == kErpcStatus_Success)
+    {
+        // preparing codec for serializing data
+        codec->reset(transport->reserveHeaderSize());
+
+        // Build response message.
+        codec->startWriteMessage(message_type_t::kReplyMessage, BeremizPLCObjectService_interface::m_serviceId, BeremizPLCObjectService_interface::m_SetTraceVariablesListId, sequence);
+
+        codec->write(debugtoken);
+
+        codec->write(result);
+
+        err = codec->getStatus();
+    }
+
+    if (orders)
+    {
+        free_list_trace_order_1_t_struct(orders);
+    }
+    erpc_free(orders);
+
+    return err;
+}
+
+// Server shim for StartPLC of BeremizPLCObjectService interface.
+erpc_status_t BeremizPLCObjectService_service::StartPLC_shim(Codec * codec, MessageBufferFactory *messageFactory, Transport * transport, uint32_t sequence)
+{
+    erpc_status_t err = kErpcStatus_Success;
+
+    uint32_t result;
+
+    // startReadMessage() was already called before this shim was invoked.
+
+    err = codec->getStatus();
+    if (err == kErpcStatus_Success)
+    {
+        // Invoke the actual served function.
+#if ERPC_NESTED_CALLS_DETECTION
+        nestingDetection = true;
+#endif
+        result = m_handler->StartPLC();
+#if ERPC_NESTED_CALLS_DETECTION
+        nestingDetection = false;
+#endif
+
+        // preparing MessageBuffer for serializing data
+        err = messageFactory->prepareServerBufferForSend(codec->getBufferRef(), transport->reserveHeaderSize());
+    }
+
+    if (err == kErpcStatus_Success)
+    {
+        // preparing codec for serializing data
+        codec->reset(transport->reserveHeaderSize());
+
+        // Build response message.
+        codec->startWriteMessage(message_type_t::kReplyMessage, BeremizPLCObjectService_interface::m_serviceId, BeremizPLCObjectService_interface::m_StartPLCId, sequence);
+
+        codec->write(result);
+
+        err = codec->getStatus();
+    }
+
+    return err;
+}
+
+// Server shim for StopPLC of BeremizPLCObjectService interface.
+erpc_status_t BeremizPLCObjectService_service::StopPLC_shim(Codec * codec, MessageBufferFactory *messageFactory, Transport * transport, uint32_t sequence)
+{
+    erpc_status_t err = kErpcStatus_Success;
+
+    bool success;
+    uint32_t result;
+
+    // startReadMessage() was already called before this shim was invoked.
+
+    err = codec->getStatus();
+    if (err == kErpcStatus_Success)
+    {
+        // Invoke the actual served function.
+#if ERPC_NESTED_CALLS_DETECTION
+        nestingDetection = true;
+#endif
+        result = m_handler->StopPLC(&success);
+#if ERPC_NESTED_CALLS_DETECTION
+        nestingDetection = false;
+#endif
+
+        // preparing MessageBuffer for serializing data
+        err = messageFactory->prepareServerBufferForSend(codec->getBufferRef(), transport->reserveHeaderSize());
+    }
+
+    if (err == kErpcStatus_Success)
+    {
+        // preparing codec for serializing data
+        codec->reset(transport->reserveHeaderSize());
+
+        // Build response message.
+        codec->startWriteMessage(message_type_t::kReplyMessage, BeremizPLCObjectService_interface::m_serviceId, BeremizPLCObjectService_interface::m_StopPLCId, sequence);
+
+        codec->write(success);
+
+        codec->write(result);
+
+        err = codec->getStatus();
+    }
+
+    return err;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/C_runtime/erpc_PLCObject_server.hpp	Wed Apr 24 02:15:33 2024 +0200
@@ -0,0 +1,88 @@
+/*
+ * Generated by erpcgen 1.11.0 on Wed Mar 27 13:43:44 2024.
+ *
+ * AUTOGENERATED - DO NOT EDIT
+ */
+
+
+#if !defined(_erpc_PLCObject_server_hpp_)
+#define _erpc_PLCObject_server_hpp_
+
+#include "erpc_PLCObject_interface.hpp"
+
+#include "erpc_server.hpp"
+#include "erpc_codec.hpp"
+
+#if 11100 != ERPC_VERSION_NUMBER
+#error "The generated shim code version is different to the rest of eRPC code."
+#endif
+
+
+namespace erpcShim
+{
+
+/*!
+ * @brief Service subclass for BeremizPLCObjectService.
+ */
+class BeremizPLCObjectService_service : public erpc::Service
+{
+public:
+    BeremizPLCObjectService_service(BeremizPLCObjectService_interface *_BeremizPLCObjectService_interface);
+
+    virtual ~BeremizPLCObjectService_service();
+
+    /*! @brief return service interface handler. */
+    BeremizPLCObjectService_interface* getHandler(void);
+
+    /*! @brief Call the correct server shim based on method unique ID. */
+    virtual erpc_status_t handleInvocation(uint32_t methodId, uint32_t sequence, erpc::Codec * codec, erpc::MessageBufferFactory *messageFactory, erpc::Transport * transport);
+
+private:
+    BeremizPLCObjectService_interface *m_handler;
+    /*! @brief Server shim for AppendChunkToBlob of BeremizPLCObjectService interface. */
+    erpc_status_t AppendChunkToBlob_shim(erpc::Codec * codec, erpc::MessageBufferFactory *messageFactory, erpc::Transport * transport, uint32_t sequence);
+
+    /*! @brief Server shim for GetLogMessage of BeremizPLCObjectService interface. */
+    erpc_status_t GetLogMessage_shim(erpc::Codec * codec, erpc::MessageBufferFactory *messageFactory, erpc::Transport * transport, uint32_t sequence);
+
+    /*! @brief Server shim for GetPLCID of BeremizPLCObjectService interface. */
+    erpc_status_t GetPLCID_shim(erpc::Codec * codec, erpc::MessageBufferFactory *messageFactory, erpc::Transport * transport, uint32_t sequence);
+
+    /*! @brief Server shim for GetPLCstatus of BeremizPLCObjectService interface. */
+    erpc_status_t GetPLCstatus_shim(erpc::Codec * codec, erpc::MessageBufferFactory *messageFactory, erpc::Transport * transport, uint32_t sequence);
+
+    /*! @brief Server shim for GetTraceVariables of BeremizPLCObjectService interface. */
+    erpc_status_t GetTraceVariables_shim(erpc::Codec * codec, erpc::MessageBufferFactory *messageFactory, erpc::Transport * transport, uint32_t sequence);
+
+    /*! @brief Server shim for MatchMD5 of BeremizPLCObjectService interface. */
+    erpc_status_t MatchMD5_shim(erpc::Codec * codec, erpc::MessageBufferFactory *messageFactory, erpc::Transport * transport, uint32_t sequence);
+
+    /*! @brief Server shim for NewPLC of BeremizPLCObjectService interface. */
+    erpc_status_t NewPLC_shim(erpc::Codec * codec, erpc::MessageBufferFactory *messageFactory, erpc::Transport * transport, uint32_t sequence);
+
+    /*! @brief Server shim for PurgeBlobs of BeremizPLCObjectService interface. */
+    erpc_status_t PurgeBlobs_shim(erpc::Codec * codec, erpc::MessageBufferFactory *messageFactory, erpc::Transport * transport, uint32_t sequence);
+
+    /*! @brief Server shim for RepairPLC of BeremizPLCObjectService interface. */
+    erpc_status_t RepairPLC_shim(erpc::Codec * codec, erpc::MessageBufferFactory *messageFactory, erpc::Transport * transport, uint32_t sequence);
+
+    /*! @brief Server shim for ResetLogCount of BeremizPLCObjectService interface. */
+    erpc_status_t ResetLogCount_shim(erpc::Codec * codec, erpc::MessageBufferFactory *messageFactory, erpc::Transport * transport, uint32_t sequence);
+
+    /*! @brief Server shim for SeedBlob of BeremizPLCObjectService interface. */
+    erpc_status_t SeedBlob_shim(erpc::Codec * codec, erpc::MessageBufferFactory *messageFactory, erpc::Transport * transport, uint32_t sequence);
+
+    /*! @brief Server shim for SetTraceVariablesList of BeremizPLCObjectService interface. */
+    erpc_status_t SetTraceVariablesList_shim(erpc::Codec * codec, erpc::MessageBufferFactory *messageFactory, erpc::Transport * transport, uint32_t sequence);
+
+    /*! @brief Server shim for StartPLC of BeremizPLCObjectService interface. */
+    erpc_status_t StartPLC_shim(erpc::Codec * codec, erpc::MessageBufferFactory *messageFactory, erpc::Transport * transport, uint32_t sequence);
+
+    /*! @brief Server shim for StopPLC of BeremizPLCObjectService interface. */
+    erpc_status_t StopPLC_shim(erpc::Codec * codec, erpc::MessageBufferFactory *messageFactory, erpc::Transport * transport, uint32_t sequence);
+};
+
+} // erpcShim
+
+
+#endif // _erpc_PLCObject_server_hpp_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/C_runtime/posix_main.cpp	Wed Apr 24 02:15:33 2024 +0200
@@ -0,0 +1,413 @@
+
+#include <stdlib.h>
+#include <vector>
+#include <filesystem>
+
+#include "erpc_basic_codec.hpp"
+#include "erpc_serial_transport.hpp"
+#include "erpc_tcp_transport.hpp"
+#include "erpc_simple_server.hpp"
+
+#include "erpc_PLCObject_server.hpp"
+#include "Logging.hpp"
+#include "options.hpp"
+
+#include "PLCObject.hpp"
+
+using namespace erpc;
+using namespace std;
+
+class MyMessageBufferFactory : public MessageBufferFactory
+{
+public:
+    virtual MessageBuffer create()
+    {
+        uint8_t *buf = new uint8_t[1024];
+        return MessageBuffer(buf, 1024);
+    }
+
+    virtual void dispose(MessageBuffer *buf)
+    {
+        erpc_assert(buf);
+        if (*buf)
+        {
+            delete[] buf->get();
+        }
+    }
+};
+
+
+namespace beremizRuntime {
+
+/*! The tool's name. */
+const char k_toolName[] = "beremizRuntime";
+
+/*! Current version number for the tool. */
+const char k_version[] = __STRING(BEREMIZ_VERSION);
+
+/*! Copyright string. */
+const char k_copyright[] = "Copyright 2024 Beremiz SAS. All rights reserved.";
+
+static const char *k_optionsDefinition[] = { "?|help",
+                                             "V|version",
+                                             "v|verbose",
+                                             "t:transport <transport>",
+                                             "b:baudrate <baudrate>",
+                                             "p:port <port>",
+                                             "h:host <host>",
+                                             NULL };
+
+/*! Help string. */
+const char k_usageText[] =
+    "\nOptions:\n\
+  -?/--help                    Show this help\n\
+  -V/--version                 Display tool version\n\
+  -v/--verbose                 Print extra detailed log information\n\
+  -t/--transport <transport>   Type of transport.\n\
+  -b/--baudrate <baudrate>     Baud rate.\n\
+  -p/--port <port>             Port name or port number.\n\
+  -h/--host <host>             Host definition.\n\
+\n\
+Available transports (use with -t option):\n\
+  tcp      Tcp transport type (host, port number).\n\
+  serial   Serial transport type (port name, baud rate).\n\
+\n";
+
+
+/*!
+ * @brief Class that encapsulates the beremizRuntime tool.
+ *
+ * A single global logger instance is created during object construction. It is
+ * never freed because we need it up to the last possible minute, when an
+ * exception could be thrown.
+ */
+class beremizRuntimeCLI
+{
+protected:
+    enum class verbose_type_t
+    {
+        kWarning,
+        kInfo,
+        kDebug,
+        kExtraDebug
+    }; /*!< Types of verbose outputs from beremizRuntime application. */
+
+    enum class transports_t
+    {
+        kNoneTransport,
+        kTcpTransport,
+        kSerialTransport
+    }; /*!< Type of transport to use. */
+
+    typedef vector<string> string_vector_t;
+
+    int m_argc;                   /*!< Number of command line arguments. */
+    char **m_argv;                /*!< String value for each command line argument. */
+    StdoutLogger *m_logger;       /*!< Singleton logger instance. */
+    verbose_type_t m_verboseType; /*!< Which type of log is need to set (warning, info, debug). */
+    const char *m_workingDir;     /*!< working directory. */
+    string_vector_t m_positionalArgs;
+    transports_t m_transport; /*!< Transport used for receiving messages. */
+    uint32_t m_baudrate;      /*!< Baudrate rate speed. */
+    const char *m_port;       /*!< Name or number of port. Based on used transport. */
+    const char *m_host;       /*!< Host name */
+
+public:
+    /*!
+     * @brief Constructor.
+     *
+     * @param[in] argc Count of arguments in argv variable.
+     * @param[in] argv Pointer to array of arguments.
+     *
+     * Creates the singleton logger instance.
+     */
+    beremizRuntimeCLI(int argc, char *argv[]) :
+    m_argc(argc), m_argv(argv), m_logger(0), m_verboseType(verbose_type_t::kWarning),
+    m_workingDir(NULL), m_transport(transports_t::kNoneTransport), m_baudrate(115200), m_port(NULL),
+    m_host(NULL)
+    {
+        // create logger instance
+        m_logger = new StdoutLogger();
+        m_logger->setFilterLevel(Logger::log_level_t::kWarning);
+        Log::setLogger(m_logger);
+    }
+
+    /*!
+     * @brief Destructor.
+     */
+    ~beremizRuntimeCLI() {}
+
+    /*!
+     * @brief Reads the command line options passed into the constructor.
+     *
+     * This method can return a return code to its caller, which will cause the
+     * tool to exit immediately with that return code value. Normally, though, it
+     * will return -1 to signal that the tool should continue to execute and
+     * all options were processed successfully.
+     *
+     * The Options class is used to parse command line options. See
+     * #k_optionsDefinition for the list of options and #k_usageText for the
+     * descriptive help for each option.
+     *
+     * @retval -1 The options were processed successfully. Let the tool run normally.
+     * @return A zero or positive result is a return code value that should be
+     *      returned from the tool as it exits immediately.
+     */
+    int processOptions()
+    {
+        Options options(*m_argv, k_optionsDefinition);
+        OptArgvIter iter(--m_argc, ++m_argv);
+
+        // process command line options
+        int optchar;
+        const char *optarg;
+        while ((optchar = options(iter, optarg)))
+        {
+            switch (optchar)
+            {
+                case '?':
+                {
+                    printUsage(options);
+                    return 0;
+                }
+
+                case 'V':
+                {
+                    printf("%s %s\n%s\n", k_toolName, k_version, k_copyright);
+                    return 0;
+                }
+
+                case 'v':
+                {
+                    if (m_verboseType != verbose_type_t::kExtraDebug)
+                    {
+                        m_verboseType = (verbose_type_t)(((int)m_verboseType) + 1);
+                    }
+                    break;
+                }
+
+                case 't':
+                {
+                    string transport = optarg;
+                    if (transport == "tcp")
+                    {
+                        m_transport = transports_t::kTcpTransport;
+                    }
+                    else if (transport == "serial")
+                    {
+                        m_transport = transports_t::kSerialTransport;
+                    }
+                    else
+                    {
+                        Log::error("error: unknown transport type %s", transport.c_str());
+                        return 1;
+                    }
+                    break;
+                }
+
+                case 'b':
+                {
+                    m_baudrate = strtoul(optarg, NULL, 10);
+                    break;
+                }
+
+                case 'p':
+                {
+                    m_port = optarg;
+                    break;
+                }
+
+                case 'h':
+                {
+                    m_host = optarg;
+                    break;
+                }
+
+                default:
+                {
+                    Log::error("error: unrecognized option\n\n");
+                    printUsage(options);
+                    return 0;
+                }
+            }
+        }
+
+        // handle positional args
+        if (iter.index() < m_argc)
+        {
+            if (m_argc - iter.index() > 1){
+                Log::error("error: too many arguments\n\n");
+                printUsage(options);
+                return 0;
+            }
+            int i;
+            for (i = iter.index(); i < m_argc; ++i)
+            {
+                m_positionalArgs.push_back(m_argv[i]);
+            }
+        }
+
+        // all is well
+        return -1;
+    }
+
+    /*!
+     * @brief Prints help for the tool.
+     *
+     * @param[in] options Options, which can be used.
+     */
+    void printUsage(Options &options)
+    {
+        options.usage(cout, "[path]");
+        printf(k_usageText);
+    }
+
+    /*!
+     * @brief Core of the tool.
+     *
+     * Calls processOptions() to handle command line options before performing the
+     * real work the tool does.
+     *
+     * @retval 1 The functions wasn't processed successfully.
+     * @retval 0 The function was processed successfully.
+     *
+     * @exception Log::error This function is called, when function wasn't
+     *              processed successfully.
+     * @exception runtime_error Thrown, when positional args is empty.
+     */
+    int run()
+    {
+        try
+        {
+            // read command line options
+            int result;
+            if ((result = processOptions()) != -1)
+            {
+                return result;
+            }
+
+            // set verbose logging
+            setVerboseLogging();
+
+            if (!m_positionalArgs.size())
+            {
+                m_workingDir = std::filesystem::current_path().c_str();
+            } else {
+                m_workingDir = m_positionalArgs[0].c_str();
+            }
+
+            Transport *_transport;
+            switch (m_transport)
+            {
+                case transports_t::kTcpTransport:
+                {
+                    uint16_t portNumber = strtoul(m_port, NULL, 10);
+                    TCPTransport *tcpTransport = new TCPTransport(m_host, portNumber, true);
+                    if (erpc_status_t err = tcpTransport->open())
+                    {
+                        return err;
+                    }
+                    _transport = tcpTransport;
+                    break;
+                }
+
+                case transports_t::kSerialTransport:
+                {
+                    SerialTransport *serialTransport = new SerialTransport(m_port, m_baudrate);
+
+                    uint8_t vtime = 0;
+                    uint8_t vmin = 1;
+                    while (kErpcStatus_Success != serialTransport->init(vtime, vmin))
+                        ;
+
+                    _transport = serialTransport;
+                    break;
+                }
+
+                default:
+                {
+                    break;
+                }
+            }
+
+            MyMessageBufferFactory _msgFactory;
+            BasicCodecFactory _basicCodecFactory;
+            SimpleServer _server;
+
+            BeremizPLCObjectService_service *svc;
+
+            Log::info("Starting ERPC server...\n");
+
+            _server.setMessageBufferFactory(&_msgFactory);
+            _server.setTransport(_transport);
+            _server.setCodecFactory(&_basicCodecFactory);
+
+            svc = new BeremizPLCObjectService_service(new PLCObject());
+
+            _server.addService(svc);
+
+            _server.run();
+
+            return 0;
+        }
+        catch (exception &e)
+        {
+            Log::error("error: %s\n", e.what());
+            return 1;
+        }
+        catch (...)
+        {
+            Log::error("error: unexpected exception\n");
+            return 1;
+        }
+
+        return 0;
+    }
+
+    /*!
+     * @brief Turns on verbose logging.
+     */
+    void setVerboseLogging()
+    {
+        // verbose only affects the INFO and DEBUG filter levels
+        // if the user has selected quiet mode, it overrides verbose
+        switch (m_verboseType)
+        {
+            case verbose_type_t::kWarning:
+                Log::getLogger()->setFilterLevel(Logger::log_level_t::kWarning);
+                break;
+            case verbose_type_t::kInfo:
+                Log::getLogger()->setFilterLevel(Logger::log_level_t::kInfo);
+                break;
+            case verbose_type_t::kDebug:
+                Log::getLogger()->setFilterLevel(Logger::log_level_t::kDebug);
+                break;
+            case verbose_type_t::kExtraDebug:
+                Log::getLogger()->setFilterLevel(Logger::log_level_t::kDebug2);
+                break;
+        }
+    }
+};
+
+} // namespace beremizRuntime
+
+/*!
+ * @brief Main application entry point.
+ *
+ * Creates a tool instance and lets it take over.
+ */
+int main(int argc, char *argv[], char *envp[])
+{
+    (void)envp;
+    try
+    {
+        return beremizRuntime::beremizRuntimeCLI(argc, argv).run();
+    }
+    catch (...)
+    {
+        Log::error("error: unexpected exception\n");
+        return 1;
+    }
+
+    return 0;
+}
\ No newline at end of file