Extensive rewrite of basyx::vab

This commit
 - Significantly improves and simplifies frame handling
 - Introduces proper exception handling in vab return frames
 - Adjusts VAB behaviour to reflect changes made in the Java SDK
 - Fixes bugs in server code
 - Fixes bugs in model provider code

Change-Id: Iada7096102c3dc6d42a4832ab488d0b4799dd15c
Signed-off-by: Thomas Psota <thomas.psota@iese.fraunhofer.de>
diff --git a/sdks/c++/basys.sdk.cc/src/server/CMakeLists.txt b/sdks/c++/basys.sdk.cc/src/server/CMakeLists.txt
index 301dc9c..8d40802 100644
--- a/sdks/c++/basys.sdk.cc/src/server/CMakeLists.txt
+++ b/sdks/c++/basys.sdk.cc/src/server/CMakeLists.txt
@@ -6,6 +6,7 @@
 set (BASYX_SERVER_LIB_SUFFIX "Server")
 
 set (BASYX_SERVER_LIBRARY_NAME "${PROJECT_SHORTNAME}${BASYX_SERVER_LIB_SUFFIX}")
+set (BASYX_SHARED_INCLUDE_DIR "${BASYX_INCLUDE_DIR}/BaSyx/server")
 
 add_library(${BASYX_SERVER_LIB_SUFFIX})
 
@@ -22,7 +23,8 @@
 
 target_sources(${BASYX_SERVER_LIB_SUFFIX}
     PRIVATE
-    ${CMAKE_CURRENT_SOURCE_DIR}/server/server.cpp
+    ${BASYX_SHARED_INCLUDE_DIR}/TCPServer.h
+    ${BASYX_SHARED_INCLUDE_DIR}/BaSyxNativeProvider.h
 )
 
 # TCPSelectServer currently only supported under UNIX
diff --git a/sdks/c++/basys.sdk.cc/src/server/server/TCPSelectServer.cpp b/sdks/c++/basys.sdk.cc/src/server/server/TCPSelectServer.cpp
index bebecc0..7e32b56 100644
--- a/sdks/c++/basys.sdk.cc/src/server/server/TCPSelectServer.cpp
+++ b/sdks/c++/basys.sdk.cc/src/server/server/TCPSelectServer.cpp
@@ -4,8 +4,8 @@
  *      Author: wendel
  */
 
-#include "include/BaSyx/server/TCPSelectServer.h"
-#include <BaSyx/vab/provider/native/frame/BaSyxNativeFrameHelper.h>
+#include <BaSyx/server/TCPSelectServer.h>
+#include <BaSyx/vab/backend//connector/native/frame/Frame.h>
 #include <BaSyx/vab/provider/native/frame/BaSyxNativeFrameProcessor.h>
 
 #include <errno.h>
@@ -21,242 +21,226 @@
 namespace provider {
 namespace native {
 
-TCPSelectServer::TCPSelectServer(core::IModelProvider *backend, int port, int timeout_ms, int listen_backlog)
+TCPSelectServer::TCPSelectServer(core::IModelProvider* backend, int port, int timeout_ms, int listen_backlog)
     : port(port)
-      , initialized(false)
-      , backend(backend)
-      , log("TCPSelectServer")
-      , listen_backlog(listen_backlog)
+    , initialized(false)
+    , backend(backend)
+    , log("TCPSelectServer")
+    , listen_backlog(listen_backlog)
 {
-  frame_processor = std::unique_ptr<frame::BaSyxNativeFrameProcessor>(new frame::BaSyxNativeFrameProcessor(backend));
-  timeout.tv_sec = timeout_ms / 1000;
-  timeout.tv_usec = (timeout_ms % 1000) * 1000;
+    frame_processor = std::unique_ptr<frame::BaSyxNativeFrameProcessor>(new frame::BaSyxNativeFrameProcessor(backend));
+    timeout.tv_sec = timeout_ms / 1000;
+    timeout.tv_usec = (timeout_ms % 1000) * 1000;
 }
 
 TCPSelectServer::~TCPSelectServer()
 {
-  this->clean_up();
+    this->clean_up();
 }
 
 void TCPSelectServer::Init()
 {
-  int rc, on = 1;
-  // create socket to accept incoming connections
-  listen_sd = socket(AF_INET, SOCK_STREAM, 0);
-  if (listen_sd < 0)
-  {
-    log.error("socket() failed");
-    exit(-1);
-  }
+    int rc, on = 1;
+    // create socket to accept incoming connections
+    listen_sd = socket(AF_INET, SOCK_STREAM, 0);
+    if (listen_sd < 0) {
+        log.error("socket() failed");
+        exit(-1);
+    }
 
-  // set socket reusable
-  int setsocketopt_state = setsockopt(listen_sd, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof(on));
-  if (setsocketopt_state < 0)
-  {
-    log.error("setsockopt() failed");
-    close(listen_sd);
-    exit(-1);
-  }
+    // set socket reusable
+    int setsocketopt_state = setsockopt(listen_sd, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof(on));
+    if (setsocketopt_state < 0) {
+        log.error("setsockopt() failed");
+        close(listen_sd);
+        exit(-1);
+    }
 
-  // Set socket to nonblocking state (FIONBIO -> non-blocking io)
-  int ioctl_state = ioctl(listen_sd, FIONBIO, (char *) &on);
-  if (ioctl_state < 0)
-  {
-    log.error("ioctl() failed");
-    close(listen_sd);
-    exit(-1);
-  }
+    // Set socket to nonblocking state (FIONBIO -> non-blocking io)
+    int ioctl_state = ioctl(listen_sd, FIONBIO, (char*)&on);
+    if (ioctl_state < 0) {
+        log.error("ioctl() failed");
+        close(listen_sd);
+        exit(-1);
+    }
 
-  // bind socket
-  memset(&addr, 0, sizeof(addr));
-  addr.sin_family = AF_INET;
-  memset(&addr.sin_addr, INADDR_ANY, sizeof(INADDR_ANY));
-  //memcpy(&addr.sin_addr, INADDR_ANY, sizeof(INADDR_ANY));
-  addr.sin_port = htons(port);
+    // bind socket
+    memset(&addr, 0, sizeof(addr));
+    addr.sin_family = AF_INET;
+    memset(&addr.sin_addr, INADDR_ANY, sizeof(INADDR_ANY));
+    //memcpy(&addr.sin_addr, INADDR_ANY, sizeof(INADDR_ANY));
+    addr.sin_port = htons(port);
 
-  int bind_state = bind(listen_sd, (struct sockaddr *) &addr, sizeof(addr));
-  if (bind_state < 0)
-  {
-    log.error("bind() failed");
-    close(listen_sd);
-    exit(-1);
-  }
+    int bind_state = bind(listen_sd, (struct sockaddr*)&addr, sizeof(addr));
+    if (bind_state < 0) {
+        log.error("bind() failed");
+        close(listen_sd);
+        exit(-1);
+    }
 
-  int listen_state = listen(listen_sd, listen_backlog);
-  if (listen_state < 0)
-  {
-    log.error("listen() failed");
-    close(listen_sd);
-    exit(-1);
-  }
+    int listen_state = listen(listen_sd, listen_backlog);
+    if (listen_state < 0) {
+        log.error("listen() failed");
+        close(listen_sd);
+        exit(-1);
+    }
 
-  //init master filedescriptor
-  FD_ZERO(&master_set);
-  max_socket = listen_sd;
-  FD_SET(listen_sd, &master_set);
+    //init master filedescriptor
+    FD_ZERO(&master_set);
+    max_socket = listen_sd;
+    FD_SET(listen_sd, &master_set);
 
-  log.info("Select server initialized. Listen socket-descriptor({})", listen_sd);
-  this->initialized = true;
+    log.info("Select server initialized. Listen socket-descriptor({})", listen_sd);
+    this->initialized = true;
 }
 
 int TCPSelectServer::Update()
 {
-  if (not initialized)
-    log.warn("Select server not initialized");
+    if (not initialized)
+        log.warn("Select server not initialized");
 
-  int rc;
-  fd_set working_set;
+    int rc;
+    fd_set working_set;
 
-  // copy filedescriptor
-  memcpy(&working_set, &master_set, sizeof(master_set));
+    // copy filedescriptor
+    memcpy(&working_set, &master_set, sizeof(master_set));
 
-  log.info("Waiting on select()...");
-  rc = select(max_socket + 1, &working_set, nullptr, nullptr, &timeout);
+    log.info("Waiting on select()...");
+    rc = select(max_socket + 1, &working_set, nullptr, nullptr, &timeout);
 
-  // check select state
-  if (rc < 0)
-  {
-    log.error("select() failed");
-    return -1;
-  }
-  if (rc == 0)
-  {
-    log.info("select() timed out.  End program.");
-    return -2;
-  }
-
-  desc_ready = rc;
-  // check which descriptors are readable
-  for (int fd = 0; fd <= max_socket && desc_ready > 0; ++fd)
-  {
-    // Check readiness of descriptors
-    if (FD_ISSET(fd, &working_set))
-    {
-      // decrease number of readable descriptors, if all found stop looking for them
-      desc_ready -= 1;
-
-      if (fd == listen_sd)
-        this->accept_incoming_connections();
-      else //if not listen socket, socket should be readable
-      {
-        log.info("Descriptor {} is readable", fd);
-        close_connection = false;
-        this->receive_incoming_data(fd);
-
-        // if connection is closed, clean up
-        if (close_connection)
-        {
-          close(fd);
-          log.info("Connection {} closed", fd);
-          FD_CLR(fd, &master_set);
-          if (fd == max_socket)
-          {
-            while (FD_ISSET(max_socket, &master_set) == false)
-            {
-              max_socket -= 1;
-            }
-          }
-        }
-      }
+    // check select state
+    if (rc < 0) {
+        log.error("select() failed");
+        return -1;
     }
-  }
-  return 0;
+    if (rc == 0) {
+        log.info("select() timed out.  End program.");
+        return -2;
+    }
+
+    desc_ready = rc;
+    // check which descriptors are readable
+    for (int fd = 0; fd <= max_socket && desc_ready > 0; ++fd) {
+        // Check readiness of descriptors
+        if (FD_ISSET(fd, &working_set)) {
+            // decrease number of readable descriptors, if all found stop looking for them
+            desc_ready -= 1;
+
+            if (fd == listen_sd)
+                this->accept_incoming_connections();
+            else //if not listen socket, socket should be readable
+            {
+                log.info("Descriptor {} is readable", fd);
+                close_connection = false;
+                this->receive_incoming_data(fd);
+
+                // if connection is closed, clean up
+                if (close_connection) {
+                    close(fd);
+                    log.info("Connection {} closed", fd);
+                    FD_CLR(fd, &master_set);
+                    if (fd == max_socket) {
+                        while (FD_ISSET(max_socket, &master_set) == false) {
+                            max_socket -= 1;
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return 0;
 }
 
 void TCPSelectServer::Close()
 {
-  this->clean_up();
+    this->clean_up();
 }
 
 bool TCPSelectServer::isRunning()
 {
-  log.warn("Not implemented!");
-  return false;
+    log.warn("Not implemented!");
+    return false;
 }
 
 void TCPSelectServer::clean_up()
 {
-  for (int i = 0; i <= max_socket; ++i)
-  {
-    if (FD_ISSET(i, &master_set))
-    {
-      close(i);
+    for (int i = 0; i <= max_socket; ++i) {
+        if (FD_ISSET(i, &master_set)) {
+            close(i);
+        }
     }
-  }
 }
 
 void TCPSelectServer::accept_incoming_connections()
 {
-  log.info("Listening socket is readable");
-  int new_sd;
-  do
-  {
-    // accept incoming connections
-    new_sd = accept(listen_sd, nullptr, nullptr);
-    if (new_sd < 0)
-    {
-      // if not EWOULDBLOCK -> all incomminng connections are accepted
-      if (errno != EWOULDBLOCK)
-      {
-        log.error("accept() failed");
-        end_server = true;
-      }
-      break;
-    }
+    log.info("Listening socket is readable");
+    int new_sd;
+    do {
+        // accept incoming connections
+        new_sd = accept(listen_sd, nullptr, nullptr);
+        if (new_sd < 0) {
+            // if not EWOULDBLOCK -> all incomminng connections are accepted
+            if (errno != EWOULDBLOCK) {
+                log.error("accept() failed");
+                end_server = true;
+            }
+            break;
+        }
 
-    log.info("New incoming connection - {}", new_sd);
+        log.info("New incoming connection - {}", new_sd);
 
-    // add incoming connections to master read set
-    FD_SET(new_sd, &master_set);
-    if (new_sd > max_socket)
-    {
-      max_socket = new_sd;
-    }
-  } while (new_sd != -1);
+        // add incoming connections to master read set
+        FD_SET(new_sd, &master_set);
+        if (new_sd > max_socket) {
+            max_socket = new_sd;
+        }
+    } while (new_sd != -1);
 }
 
 void TCPSelectServer::receive_incoming_data(int fd)
 {
-  do
-  {
-    // receive data
-    int receive_state = recv(fd, recv_buffer.data(), recv_buffer.size(), 0);
-    if (receive_state < 0)
-    {
-      log.debug("receive state {}", receive_state);
-      if (errno != EWOULDBLOCK)
-      {
-        log.error("recv() failed {}", errno);
-        close_connection = true;
-      }
-      break;
-    }
+    do {
+        // receive data
+        int receive_state = recv(fd, recv_buffer.data(), recv_buffer.size(), 0);
+        if (receive_state < 0) {
+            log.debug("receive state {}", receive_state);
+            if (errno != EWOULDBLOCK) {
+                log.error("recv() failed {}", errno);
+                close_connection = true;
+            }
+            break;
+        }
 
-    // if 0, client closed connection
-    if (receive_state == 0)
-    {
-      log.info("Connection closed");
-      close_connection = true;
-      break;
-    }
+        // if 0, client closed connection
+        if (receive_state == 0) {
+            log.info("Connection closed");
+            close_connection = true;
+            break;
+        }
 
-    int len = receive_state;
-    log.info("{} bytes received", len);
+        int len = receive_state;
+        log.info("{} bytes received", len);
 
-    std::size_t txSize = 0;
-    frame_processor->processInputFrame(recv_buffer.data() + BASYX_FRAMESIZE_SIZE, len - BASYX_FRAMESIZE_SIZE, ret_buffer.data() + BASYX_FRAMESIZE_SIZE, &txSize);
-    txSize += BASYX_FRAMESIZE_SIZE;
+        std::size_t txSize = 0;
 
-    // answer client
-    int send_state = send(fd, ret_buffer.data(), txSize, 0);
-    if (send_state < 0)
-    {
-      log.error("send() failed");
-      close_connection = true;
-      break;
-    }
 
-  } while (true);
+
+
+
+
+        // ToDo: Use new frame handling
+  //      frame_processor->processInputFrame(recv_buffer.data() + BASYX_FRAMESIZE_SIZE, len - BASYX_FRAMESIZE_SIZE, ret_buffer.data() + BASYX_FRAMESIZE_SIZE, &txSize);
+  //      txSize += BASYX_FRAMESIZE_SIZE;
+
+        // answer client
+        int send_state = send(fd, ret_buffer.data(), txSize, 0);
+        if (send_state < 0) {
+            log.error("send() failed");
+            close_connection = true;
+            break;
+        }
+
+    } while (true);
 }
 
 }
diff --git a/sdks/c++/basys.sdk.cc/src/server/server/server.cpp b/sdks/c++/basys.sdk.cc/src/server/server/server.cpp
deleted file mode 100644
index e69de29..0000000
--- a/sdks/c++/basys.sdk.cc/src/server/server/server.cpp
+++ /dev/null
diff --git a/sdks/c++/basys.sdk.cc/src/shared/CMakeLists.txt b/sdks/c++/basys.sdk.cc/src/shared/CMakeLists.txt
index 4982767..98e2bc5 100644
--- a/sdks/c++/basys.sdk.cc/src/shared/CMakeLists.txt
+++ b/sdks/c++/basys.sdk.cc/src/shared/CMakeLists.txt
@@ -21,6 +21,7 @@
 
 target_sources(${BASYX_SHARED_TARGET_NAME}
     PRIVATE
+        ${CMAKE_CURRENT_SOURCE_DIR}/shared/object/impl/obj_error.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/shared/object/impl/object_impl.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/shared/serialization/json/typeid.cpp
 )
@@ -36,6 +37,7 @@
         ${BASYX_SHARED_INCLUDE_DIR}/object/object_header.h
         ${BASYX_SHARED_INCLUDE_DIR}/object/object_type.h
         ${BASYX_SHARED_INCLUDE_DIR}/object/obj_function.h
+        ${BASYX_SHARED_INCLUDE_DIR}/object/obj_error.h
         ${BASYX_SHARED_INCLUDE_DIR}/object/obj_holder.h
         ${BASYX_SHARED_INCLUDE_DIR}/object/obj_placeholder.h
         ${BASYX_SHARED_INCLUDE_DIR}/object/obj_error_holder.h
diff --git a/sdks/c++/basys.sdk.cc/src/shared/shared/object/impl/obj_error.cpp b/sdks/c++/basys.sdk.cc/src/shared/shared/object/impl/obj_error.cpp
new file mode 100644
index 0000000..43b9ff0
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/src/shared/shared/object/impl/obj_error.cpp
@@ -0,0 +1,42 @@
+#include <BaSyx/shared/object/obj_error.h>
+
+#include <array>
+#include <algorithm>
+#include <memory>
+#include <string>
+
+using namespace basyx::detail;
+
+using enum_pair_t = std::pair<const char*, error>;
+
+static const std::array<enum_pair_t, 7> string_to_enum = 
+{
+    std::make_pair("None",  error::None),
+    std::make_pair("PropertyNotFound", error::PropertyNotFound),
+    std::make_pair("IndexOutOfBounds", error::IndexOutOfBounds),
+    std::make_pair("NotInvokable", error::NotInvokable),
+    std::make_pair("ObjectAlreadyExists", error::ObjectAlreadyExists),
+    std::make_pair("MalformedRequest", error::MalformedRequest),
+    std::make_pair("ProviderException", error::ProviderException),
+};
+
+error error_::from_string(const std::string & name)
+{
+    auto pair = std::find_if(string_to_enum.begin(), string_to_enum.end(), 
+		[&name](const enum_pair_t & pair) {
+			return !name.compare(pair.first);
+	});
+
+    return pair->second;
+}
+
+const char * error_::to_string(error value)
+{
+    auto pair = std::find_if(string_to_enum.begin(), string_to_enum.end(), 
+		[value](const enum_pair_t & pair) {
+			return value == pair.second;
+	});
+
+    return pair->first;
+}
+
diff --git a/sdks/c++/basys.sdk.cc/src/shared/shared/object/impl/object_impl.cpp b/sdks/c++/basys.sdk.cc/src/shared/shared/object/impl/object_impl.cpp
index 584ca15..257e74d 100644
--- a/sdks/c++/basys.sdk.cc/src/shared/shared/object/impl/object_impl.cpp
+++ b/sdks/c++/basys.sdk.cc/src/shared/shared/object/impl/object_impl.cpp
@@ -208,6 +208,9 @@
 
 basyx::object::error basyx::object::getError() const
 {
+	if (this->GetObjectType() != basyx::type::objectType::Error)
+		return basyx::object::error::None;
+
 	auto & errorHolder = dynamic_cast<basyx::detail::objErrorHolder&>(*this->content);
 	return errorHolder.error;
 }
diff --git a/sdks/c++/basys.sdk.cc/src/vab/CMakeLists.txt b/sdks/c++/basys.sdk.cc/src/vab/CMakeLists.txt
index f3425fa..549a9e0 100644
--- a/sdks/c++/basys.sdk.cc/src/vab/CMakeLists.txt
+++ b/sdks/c++/basys.sdk.cc/src/vab/CMakeLists.txt
@@ -25,7 +25,8 @@
 target_sources(${BASYX_VAB_LIB_SUFFIX}
     PRIVATE
         ${CMAKE_CURRENT_SOURCE_DIR}/vab/backend/connector/native/BaSyxConnector.cpp
-        ${CMAKE_CURRENT_SOURCE_DIR}/vab/backend/connector/native/frame/BaSyxNativeFrameBuilder.cpp
+        ${CMAKE_CURRENT_SOURCE_DIR}/vab/backend/connector/native/frame/Frame.cpp
+        ${CMAKE_CURRENT_SOURCE_DIR}/vab/backend/connector/native/frame/EntityWrapper.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/vab/core/proxy/VABElementProxy.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/vab/core/util/VABPath.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/vab/core/VABConnectionManager.cpp
@@ -40,7 +41,8 @@
         ${BASYX_VAB_INCLUDE_DIR}/backend/connector/IBaSyxConnector.h
         ${BASYX_VAB_INCLUDE_DIR}/backend/connector/JSONProvider.h
         ${BASYX_VAB_INCLUDE_DIR}/backend/connector/native/BaSyxConnector.h
-        ${BASYX_VAB_INCLUDE_DIR}/backend/connector/native/frame/BaSyxNativeFrameBuilder.h
+        ${BASYX_VAB_INCLUDE_DIR}/backend/connector/native/frame/Frame.h
+        ${BASYX_VAB_INCLUDE_DIR}/backend/connector/native/frame/EntityWrapper.h
         ${BASYX_VAB_INCLUDE_DIR}/core/IModelProvider.h
         ${BASYX_VAB_INCLUDE_DIR}/core/proxy/IVABElementProxy.h
         ${BASYX_VAB_INCLUDE_DIR}/core/proxy/VABElementProxy.h
diff --git a/sdks/c++/basys.sdk.cc/src/vab/vab/backend/connector/native/BaSyxConnector.cpp b/sdks/c++/basys.sdk.cc/src/vab/vab/backend/connector/native/BaSyxConnector.cpp
index c5fdd01..8924014 100644
--- a/sdks/c++/basys.sdk.cc/src/vab/vab/backend/connector/native/BaSyxConnector.cpp
+++ b/sdks/c++/basys.sdk.cc/src/vab/vab/backend/connector/native/BaSyxConnector.cpp
@@ -6,7 +6,8 @@
 */
 
 #include <BaSyx/vab/backend/connector/native/BaSyxConnector.h>
-#include <BaSyx/vab/backend/connector/native/frame/BaSyxNativeFrameBuilder.h>
+#include <BaSyx/vab/backend/connector/native/frame/Frame.h>
+#include <BaSyx/vab/backend/connector/native/frame/EntityWrapper.h>
 #include <BaSyx/vab/provider/native/frame/BaSyxNativeFrameHelper.h>
 
 #include <BaSyx/shared/serialization/json.h>
@@ -22,8 +23,7 @@
 namespace native {
 
 NativeConnector::NativeConnector(std::string const& address, int port)
-	: builder{}
-	, socket{ basyx::net::tcp::Socket::Connect(address, port) }
+	: socket{ basyx::net::tcp::Socket::Connect(address, port) }
 	, log{ "NativeConnector" }
 {
 	log.trace("Connected to {}:{}", address, port);
@@ -32,7 +32,6 @@
 
 
 NativeConnector::~NativeConnector() {
-	this->socket.Close();
 }
 
 
@@ -42,65 +41,69 @@
 	log.trace("basysGet() called:");
 	log.trace("    path: {}", path);
 
-	auto entityWrapper = basysGetRaw(path);
-	auto value = basyx::serialization::json::deserialize(entityWrapper["entity"]);
+	auto value = basysProcess(Frame::Builder::Get(path));
 	return value;
 }
 
-nlohmann::json NativeConnector::basysGetRaw(std::string const& path) {
-	size_t size = builder.buildGetFrame(path, buffer.data() + BASYX_FRAMESIZE_SIZE);
-	sendData(buffer.data(), size);
-	size = receiveData(buffer.data());
-	if (buffer[4] != 0) { // Error happened
-		return ""_json; // TODO: Error handling
-	}
-	std::string data = StringTools::fromArray(buffer.data() + BASYX_FRAMESIZE_SIZE + 1);
-	return nlohmann::json::parse(data);
-}
+basyx::object NativeConnector::basysProcess(const Frame & frame)
+{
+	this->sendFrame(frame);
 
-void NativeConnector::basysSet(std::string const& path, const basyx::object & newValue)
+	auto response_frame = this->recvFrame();
+	if (response_frame.getFlag() != 0x00) {
+		return basyx::object::make_error(basyx::object::error::MalformedRequest, "invalid frame received");
+	};
+
+	auto entityWrapper = nlohmann::json::parse(response_frame.getFirstValue());
+
+	auto value = basyx::vab::EntityWrapper::from_json(entityWrapper);
+	return value;
+};
+
+basyx::object NativeConnector::basysSet(std::string const& path, const basyx::object & newValue)
 {
 	log.trace("basysSet() called:");
 	log.trace("    path: {}", path);
 
-	size_t size = builder.buildSetFrame(path, newValue, buffer.data() + BASYX_FRAMESIZE_SIZE);
-	sendData(buffer.data(), size);
-	size = receiveData(buffer.data());
+	auto return_code = basysProcess(Frame::Builder::Set(path, newValue));
+	return return_code;
 }
 
-void NativeConnector::basysCreate(std::string const& path, const basyx::object & val)
+basyx::object NativeConnector::basysCreate(std::string const& path, const basyx::object & val)
 {
-	size_t size = builder.buildCreateFrame(path, val, buffer.data() + BASYX_FRAMESIZE_SIZE);
-	sendData(buffer.data(), size);
-	size = receiveData(buffer.data());
+	log.trace("basysCreate() called:");
+	log.trace("    path: {}", path);
+
+	auto return_code = basysProcess(Frame::Builder::Create(path, val));
+	return return_code;
 }
 
 basyx::object NativeConnector::basysInvoke(std::string const& path, const basyx::object & param)
 {
-	size_t size = builder.buildInvokeFrame(path, param, buffer.data() + BASYX_FRAMESIZE_SIZE);
-	sendData(buffer.data(), size);
-	size = receiveData(buffer.data());
-	return decode(buffer.data() + 5);
+	log.trace("basysInvoke() called:");
+	log.trace("    path: {}", path);
+
+	auto return_code = basysProcess(Frame::Builder::Invoke(path, param));
+	return return_code;
 }
 
-void NativeConnector::basysDelete(std::string const& path)
+basyx::object NativeConnector::basysDelete(std::string const& path)
 {
-	size_t size = builder.buildDeleteFrame(path, buffer.data() + BASYX_FRAMESIZE_SIZE);
-	sendData(buffer.data(), size);
-	size = receiveData(buffer.data());
+	log.trace("basysDelete() called:");
+	log.trace("    path: {}", path);
+
+	auto return_code = basysProcess(Frame::Builder::Delete(path));
+	return return_code;
 }
 
-void NativeConnector::basysDelete(std::string const& path, const basyx::object & obj) {
-	size_t size = builder.buildDeleteFrame(path, obj, buffer.data() + BASYX_FRAMESIZE_SIZE);
-	sendData(buffer.data(), size);
-	size = receiveData(buffer.data());
-}
+basyx::object NativeConnector::basysDelete(std::string const& path, const basyx::object & obj) 
+{
+	log.trace("basysDelete() called:");
+	log.trace("    path: {}", path);
 
-// TODO: Error handling
-/**
-	* Builds a send frame and sends it to server
-	* @param msg a frame constructed with the BaSyxNativeFrameBuilder
-	*/
+	auto return_code = basysProcess(Frame::Builder::Delete(path, obj));
+	return return_code;
+}
 
 void NativeConnector::sendData(char* msg, size_t size) 
 {
@@ -110,10 +113,6 @@
 
 	CoderTools::setInt32(msg, 0, size);
 	size += BASYX_FRAMESIZE_SIZE;
-#ifdef PRINT_FRAME
-	log.debug("Sending:");
-	vab::provider::native::frame::BaSyxNativeFrameHelper::printFrame(msg, size);
-#endif
 
 	log.debug("Sending {} bytes.", size);
 	int sent_bytes = this->socket.Send(basyx::net::make_buffer(msg, size));
@@ -125,7 +124,8 @@
 }
 
 // TODO: Error handling
-size_t NativeConnector::receiveData(char* data) {
+size_t NativeConnector::receiveData(char* data) 
+{
 	log.trace("receiveData() called");
 	log.trace("    data: 0x{0:x}", (std::size_t)data);
 
@@ -135,10 +135,6 @@
 	log.debug("Received {} bytes.", recv_bytes);
 
 	if (recv_bytes > 0) {
-#ifdef PRINT_FRAME
-		log.debug("Received:");
-		vab::provider::native::frame::BaSyxNativeFrameHelper::printFrame(data, recv_bytes);
-#endif
 		return recv_bytes;
 	}
 	else {
@@ -147,10 +143,23 @@
 	}
 }
 
-basyx::object NativeConnector::decode(char* buffer)
+void NativeConnector::sendFrame(const Frame & frame)
 {
-	std::string data = StringTools::fromArray(buffer);
-	return basyx::serialization::json::deserialize(data).Get<basyx::object::object_map_t&>()["entity"];
+	Frame::write_to_buffer(
+		basyx::net::make_buffer(
+			buffer.data() + BASYX_FRAMESIZE_SIZE, default_buffer_length - BASYX_FRAMESIZE_SIZE), 
+		frame);
+
+	sendData(buffer.data(), frame.size());
+};
+
+Frame NativeConnector::recvFrame()
+{
+	this->receiveData(buffer.data());
+	auto size = *reinterpret_cast<uint32_t*>(buffer.data());
+	auto frame = Frame::read_from_buffer(basyx::net::make_buffer(this->buffer.data() + BASYX_FRAMESIZE_SIZE, size));
+
+	return frame;
 };
 
 }
diff --git a/sdks/c++/basys.sdk.cc/src/vab/vab/backend/connector/native/frame/BaSyxNativeFrameBuilder.cpp b/sdks/c++/basys.sdk.cc/src/vab/vab/backend/connector/native/frame/BaSyxNativeFrameBuilder.cpp
deleted file mode 100644
index 34987eb..0000000
--- a/sdks/c++/basys.sdk.cc/src/vab/vab/backend/connector/native/frame/BaSyxNativeFrameBuilder.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * BaSyxNativeFrameBuilder.cpp
- *
- *  Created on: 14.08.2018
- *      Author: schnicke
- */
-
-#include <BaSyx/vab/backend/connector/native/frame/BaSyxNativeFrameBuilder.h>
-
-#include <BaSyx/shared/serialization/json.h>
-
-#include <BaSyx/util/tools/StringTools.h>
-
-namespace basyx {
-namespace vab {
-namespace connector {
-namespace native {
-namespace frame {
-
-	
-BaSyxNativeFrameBuilder::BaSyxNativeFrameBuilder() { };
-
-size_t BaSyxNativeFrameBuilder::buildGetFrame(std::string const& path, char * buffer)
-{
-	return encodeCommandAndPath(BaSyxCommand::Get, path, buffer);
-}
-
-size_t BaSyxNativeFrameBuilder::buildSetFrame(std::string const& path, const basyx::object & newVal, char * buffer)
-{
-	size_t size = encodeCommandAndPath(BaSyxCommand::Set, path, buffer);
-	size += encodeValue(newVal, buffer + size);
-	return size;
-}
-
-size_t BaSyxNativeFrameBuilder::buildCreateFrame(std::string const& path, const basyx::object & newVal, char * buffer)
-{
-	size_t size = encodeCommandAndPath(BaSyxCommand::Create, path, buffer);
-	size += encodeValue(newVal, buffer + size);
-	return size;
-}
-
-size_t BaSyxNativeFrameBuilder::buildDeleteFrame(std::string const& path, char * buffer)
-{
-	return encodeCommandAndPath(BaSyxCommand::Delete, path, buffer);
-}
-
-size_t BaSyxNativeFrameBuilder::buildDeleteFrame(std::string const& path, const basyx::object & deleteVal, char * buffer)
-{
-	size_t size = encodeCommandAndPath(BaSyxCommand::Delete, path, buffer);
-	size += encodeValue(deleteVal, buffer + size);
-	return size;
-}
-
-size_t BaSyxNativeFrameBuilder::buildInvokeFrame(std::string const& path, const basyx::object & param, char * buffer)
-{
-	size_t size = encodeCommandAndPath(BaSyxCommand::Invoke, path, buffer);
-	size += encodeValue(param, buffer + size);
-	return size;
-}
-
-size_t BaSyxNativeFrameBuilder::buildInvokeFrame(std::string const& path, const basyx::object::object_list_t & params, char * buffer)
-{
-	size_t size = encodeCommandAndPath(BaSyxCommand::Invoke, path, buffer);
-	size += encodeValue(params, buffer + size);
-	return size;
-}
-
-size_t BaSyxNativeFrameBuilder::encodeCommand(BaSyxCommand command, char* buffer)
-{
-	buffer[0] = static_cast<uint8_t>(command);
-	return 1;
-}
-
-std::size_t BaSyxNativeFrameBuilder::encodeValue(const basyx::object & value, char * buffer)
-{
-	std::string dumped = basyx::serialization::json::serialize(value).dump(4);
-	return StringTools::toArray(dumped, buffer);
-}
-
-size_t BaSyxNativeFrameBuilder::encodeCommandAndPath(BaSyxCommand command, std::string const& path, char* buffer)
-{
-	size_t size = encodeCommand(command, buffer);
-	size += StringTools::toArray(path, buffer + size);
-	return size;
-}
-
-}
-}
-}
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/vab/vab/backend/connector/native/frame/EntityWrapper.cpp b/sdks/c++/basys.sdk.cc/src/vab/vab/backend/connector/native/frame/EntityWrapper.cpp
new file mode 100644
index 0000000..37c2989
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/src/vab/vab/backend/connector/native/frame/EntityWrapper.cpp
@@ -0,0 +1,112 @@
+#include <BaSyx/vab/backend/connector/native/frame/EntityWrapper.h>
+
+using basyx::vab::EntityWrapper;
+
+
+namespace {
+	std::string prepareErrorCode(basyx::object::error errorCode)
+	{
+		std::string error;
+		switch (errorCode)
+		{
+		case basyx::object::error::PropertyNotFound:
+			error = "ResourceNotFoundException";
+			break;
+		case basyx::object::error::ObjectAlreadyExists:
+			error = "ResourceAlreadyExistsException";
+			break;
+		case basyx::object::error::MalformedRequest:
+			error = "MalformedRequestException";
+			break;
+		default:
+			error = "ProviderException";
+			break;
+		};
+		return error;
+	};
+
+	std::string prepareErrorMessage(basyx::object::error errorCode, const std::string & message)
+	{
+		return prepareErrorCode(errorCode) + ": " + message;
+	};
+}
+
+basyx::object build_exception(const std::string & type, const std::string & message)
+{
+	basyx::object::error error = basyx::object::error::ProviderException;
+
+	if (type == "ResourceNotFoundException")
+	{
+		error = basyx::object::error::PropertyNotFound;
+	}
+	else if (type == "ResourceAlreadyExistsException")
+	{
+		error = basyx::object::error::ObjectAlreadyExists;
+	}
+	else if (type == "MalformedRequestException")
+	{
+		error = basyx::object::error::MalformedRequest;
+	}
+	else if (type == "ProviderException")
+	{
+		error = basyx::object::error::ProviderException;
+	};
+
+	return basyx::object::make_error(error, message);
+};
+
+basyx::json_t EntityWrapper::build_from_error(basyx::object::error error, const std::string & message)
+{
+	json_t msg;
+	msg["messageType"] = 6;
+	msg["text"] = prepareErrorMessage(error, message);
+	msg["code"] = nullptr;
+
+	basyx::json_t j_obj;
+	j_obj["success"] = false;
+	j_obj["isException"] = true;
+	j_obj["messages"] = json_t::array({ msg });
+	j_obj["entityType"] = prepareErrorCode(error);
+	return j_obj;
+};
+
+basyx::json_t EntityWrapper::build_from_object(const basyx::object & object)
+{
+	basyx::json_t j_obj;
+	if (object.IsError())
+	{
+		return build_from_error(object.getError(), object.getErrorMessage());
+	}
+	else
+	{
+		j_obj["success"] = true;
+//		j_obj["isException"] = false;
+		j_obj["entityType"] = "entity";
+		j_obj["entity"] = basyx::serialization::json::serialize(object);
+	}
+	return j_obj;
+};
+
+
+basyx::object EntityWrapper::from_json(const basyx::json_t & json)
+{
+	bool success = json["success"];
+	// everyhing okay, deserialize entity
+	if (success)
+	{
+		if (json.contains("entity"))
+			return basyx::serialization::json::deserialize(json["entity"]);
+		else
+			return basyx::object::make_null();
+	}
+	// something went wrong, check for exception
+	else if (json.contains("isException") && json.contains("messages"))
+	{
+		return build_exception(json["entityType"], json["messages"][0]["text"]);
+	}
+	// error and no exception; create one
+	else
+	{
+		return basyx::object::make_error(basyx::object::error::MalformedRequest);
+	};
+};
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/src/vab/vab/backend/connector/native/frame/Frame.cpp b/sdks/c++/basys.sdk.cc/src/vab/vab/backend/connector/native/frame/Frame.cpp
new file mode 100644
index 0000000..9d7a649
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/src/vab/vab/backend/connector/native/frame/Frame.cpp
@@ -0,0 +1,166 @@
+#include <BaSyx/vab/backend/connector/native/frame/Frame.h>
+
+#include <BaSyx/util/tools/StringTools.h>
+
+using namespace basyx::vab::connector::native;
+
+Frame::Frame()
+	: flag(0xFF)
+	, value_1()
+	, value_2()
+{
+};
+
+Frame::Frame(uint8_t flag, const std::string & value_1) 
+	: flag(flag)
+	, value_1(value_1)
+	, value_2()
+{
+};
+
+Frame::Frame(uint8_t flag, const std::string & value_1, const std::string & value_2)
+	: flag(flag)
+	, value_1(value_1)
+	, value_2(value_2)
+{
+};
+
+uint8_t Frame::getFlag() const
+{
+	return this->flag;
+};
+
+void Frame::setFlag(uint8_t flag)
+{
+	this->flag = flag;
+};
+
+void Frame::setFlag(BaSyxCommand flag)
+{
+	this->flag = static_cast<decltype(this->flag)>(flag);
+};
+
+const std::string & Frame::getFirstValue() const
+{
+	return this->value_1;
+};
+
+void Frame::setFirstValue(const std::string & value)
+{
+	this->value_1 = value;
+};
+
+const std::string & Frame::getSecondValue() const
+{
+	return this->value_2;
+};
+
+void Frame::setSecondValue(const std::string & value)
+{
+	this->value_2 = value;
+};
+
+bool Frame::write_to_buffer(const basyx::net::Buffer & buffer, const Frame & frame)
+{
+	// bail out if buffer to small
+	if (frame.size() > buffer.size())
+		return false;
+
+	std::size_t pos = 0;
+	char * data = reinterpret_cast<char*>(buffer.data());
+
+	// write command field
+	data[pos] = static_cast<uint8_t>(frame.getFlag());
+	pos += 1;
+	
+	// write first value field
+	pos += StringTools::toArray(frame.getFirstValue(), &data[pos]);
+
+	// write second value field
+	if (!frame.getSecondValue().empty())
+	{
+		pos += StringTools::toArray(frame.getSecondValue(), &data[pos]);
+	};
+
+	return true;
+};
+
+Frame Frame::read_from_buffer(const basyx::net::Buffer & buffer)
+{
+	Frame frame;
+
+	std::size_t pos = 0;
+	char * data = reinterpret_cast<char*>(buffer.data());
+	
+	uint8_t flag = static_cast<uint8_t>(data[pos]);
+	frame.setFlag(flag);
+	pos += 1;
+
+	frame.setFirstValue(StringTools::fromArray(&data[pos]));
+	pos += frame.getFirstValue().size() + sizeof(uint32_t);
+
+	if (pos < buffer.size())
+	{
+		frame.setSecondValue(StringTools::fromArray(&data[pos]));
+		pos += frame.getSecondValue().size() + sizeof(uint32_t);
+	};
+
+	return frame;
+};
+
+std::size_t Frame::size() const
+{
+	std::size_t size = 1; // size of flag field
+	size += sizeof(uint32_t) + this->getFirstValue().size(); // size of first value + length
+
+	if(!this->getSecondValue().empty())
+		size += sizeof(uint32_t) + this->getSecondValue().size(); // size of second value + length
+
+	return size;
+};
+
+Frame Frame::Builder::Get(const std::string & path)
+{
+	return Frame{ static_cast<uint8_t>(BaSyxCommand::Get), path };
+};
+
+Frame Frame::Builder::Set(const std::string & path, const basyx::object & value)
+{
+	return Frame{
+		static_cast<uint8_t>(BaSyxCommand::Set),
+		path,
+		basyx::serialization::json::serialize(value).dump(4)
+	};
+};
+
+Frame Frame::Builder::Create(const std::string & path, const basyx::object & value)
+{
+	return Frame{
+		static_cast<uint8_t>(BaSyxCommand::Create),
+		path,
+		basyx::serialization::json::serialize(value).dump(4)
+	};
+};
+
+Frame Frame::Builder::Delete(const std::string & path)
+{
+	return Frame{ static_cast<uint8_t>(BaSyxCommand::Delete), path };
+}; 
+
+Frame Frame::Builder::Delete(const std::string & path, const basyx::object & value)
+{
+	return Frame{
+		static_cast<uint8_t>(BaSyxCommand::Delete),
+		path,
+		basyx::serialization::json::serialize(value).dump(4)
+	};
+};
+
+Frame Frame::Builder::Invoke(const std::string & path, const basyx::object & value)
+{
+	return Frame{
+		static_cast<uint8_t>(BaSyxCommand::Invoke),
+		path,
+		basyx::serialization::json::serialize(value).dump(4)
+	};
+};
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/src/vab/vab/provider/VABModelProvider.cpp b/sdks/c++/basys.sdk.cc/src/vab/vab/provider/VABModelProvider.cpp
index b63c498..10b2a67 100644
--- a/sdks/c++/basys.sdk.cc/src/vab/vab/provider/VABModelProvider.cpp
+++ b/sdks/c++/basys.sdk.cc/src/vab/vab/provider/VABModelProvider.cpp
@@ -87,11 +87,12 @@
 	// Only write values, that already exist
 	auto thisElement = parentElement.getProperty(propertyName);
 
-	if (!parentElement.IsNull() && !thisElement.IsNull()) {
+	if (!parentElement.IsNull()/* && !thisElement.IsNull()*/) {
 		parentElement.insertKey(propertyName, newValue, true);
+		return basyx::object::error::None;
 	}
 
-	return basyx::object::error::None;
+	return basyx::object::error::PropertyNotFound;
 };
 
 basyx::object::error VABModelProvider::createValue(const std::string& path, const basyx::object newValue)
@@ -163,10 +164,11 @@
 		if (!childElement.IsNull()) {
 			//handler.DeleteValue(childElement, deletedValue);
 			childElement.remove(deletedValue);
+			return basyx::object::error::None;
 		}
 	}
 
-	return basyx::object::error::None;
+	return basyx::object::error::PropertyNotFound;
 };
 
 basyx::object::error VABModelProvider::deleteValue(const std::string& path)
@@ -200,14 +202,14 @@
 		log.error("Function not found!");
 		log.trace("Returning basyx::object::null");
 
-		return basyx::object{ nullptr };
+		return basyx::object::make_error(basyx::object::error::PropertyNotFound, "method not found");
 	}
 
 	if (!element.IsInvokable()) {
 		log.error("Found object is not invokable!");
 		log.trace("Returning basyx::object::null");
 
-		return basyx::object{ nullptr };
+		return basyx::object::make_error(basyx::object::error::ProviderException, "method not invokable");
 	};
 
 	log.trace("Function found. Invoking...");
diff --git a/sdks/c++/basys.sdk.cc/src/vab/vab/provider/native/frame/BaSyxNativeFrameProcessor.cpp b/sdks/c++/basys.sdk.cc/src/vab/vab/provider/native/frame/BaSyxNativeFrameProcessor.cpp
index 805dda6..9667497 100644
--- a/sdks/c++/basys.sdk.cc/src/vab/vab/provider/native/frame/BaSyxNativeFrameProcessor.cpp
+++ b/sdks/c++/basys.sdk.cc/src/vab/vab/provider/native/frame/BaSyxNativeFrameProcessor.cpp
@@ -13,159 +13,96 @@
 #include <BaSyx/util/tools/StringTools.h>
 
 #include <BaSyx/shared/types.h>
- 
+
 namespace basyx {
 namespace vab {
 namespace provider {
 namespace native {
 namespace frame {
 
+using connector::native::Frame;
+
+
 BaSyxNativeFrameProcessor::BaSyxNativeFrameProcessor(vab::core::IModelProvider* providerBackend) 
 	: jsonProvider{ providerBackend}
 {
 }
 
-BaSyxNativeFrameProcessor::~BaSyxNativeFrameProcessor() 
+Frame BaSyxNativeFrameProcessor::processInputFrame(const Frame & frame)
 {
-}
+	auto command = static_cast<BaSyxCommand>(frame.getFlag());
 
-void BaSyxNativeFrameProcessor::processInputFrame(char const* rxFrame, std::size_t rxSize, char* txFrame, std::size_t* txSize) 
-{
-	std::size_t offset;
-	auto command = vab::provider::native::frame::BaSyxNativeFrameHelper::getCommand(rxFrame, &offset);
-	rxFrame += offset;
-	switch (command) {
+	switch (command) 
+	{
 	case BaSyxCommand::Get:
-		processGet(rxFrame, txFrame, txSize);
-		break;
+		return processGet(frame);
 	case BaSyxCommand::Set:
-		processSet(rxFrame, txFrame, txSize);
-		break;
+		return processSet(frame);
 	case BaSyxCommand::Create:
-		processCreate(rxFrame, txFrame, txSize);
-		break;
+		return processCreate(frame);
 	case BaSyxCommand::Delete:
-		processDelete(rxFrame, rxSize - offset, txFrame, txSize);
-		break;
+		return processDelete(frame);
 	case BaSyxCommand::Invoke:
-		processInvoke(rxFrame, txFrame, txSize);
-		break;
-
-	}
-}
-
-void BaSyxNativeFrameProcessor::processGet(char const* rxFrame, char* txFrame, std::size_t* txSize) 
-{
-	// Try to get the requested value
-	// TODO: Error Handling?
-
-	std::string path = BaSyxNativeFrameHelper::getString(rxFrame, 0);
-	// Advance txFrame by 5 because of the following setup of txFrame:
-	// 1 byte result field
-	// 4 byte string size
-	// N byte return value
-	std::string getResult = jsonProvider.processBaSysGet(path);
-	*txSize += getResult.size();
-	memcpy(txFrame + 5, getResult.c_str(), getResult.size());
-
-	// Set return string size
-	CoderTools::setInt32(txFrame + 1, 0, *txSize);
-	*txSize += BASYX_STRINGSIZE_SIZE;
-	
-	// Set result field to 0 to indicate success
-	txFrame[0] = 0;
-	*txSize += 1;
-}
-
-void BaSyxNativeFrameProcessor::processSet(char const* rxFrame, char* txFrame, std::size_t* txSize) 
-{
-	std::string path = BaSyxNativeFrameHelper::getString(rxFrame, 0);
-
-	// TODO: Error Handling?
-	std::string serializedValue = BaSyxNativeFrameHelper::getString(rxFrame, 1);
-	std::string getResult = jsonProvider.processBaSysSet(path, serializedValue);
-	memcpy(txFrame + 5, getResult.c_str(), getResult.size());
-
-	// Set return string size
-	CoderTools::setInt32(txFrame + 1, 0, *txSize);
-	*txSize += BASYX_STRINGSIZE_SIZE;
-	
-        // Set result field to 0 to indicate success
-	txFrame[0] = 0;
-	*txSize += 1;
-}
-
-void BaSyxNativeFrameProcessor::processCreate(char const* rxFrame, char* txFrame, std::size_t* txSize)
-{
-	std::string path = BaSyxNativeFrameHelper::getString(rxFrame, 0);
-
-	// TODO: Error Handling?
-	std::string serializedValue = BaSyxNativeFrameHelper::getString(rxFrame, 1);
-
-	std::string getResult =	jsonProvider.processBaSysCreate(path, serializedValue);
-	memcpy(txFrame + 5, getResult.c_str(), getResult.size());
-
-	// Set return string size
-	CoderTools::setInt32(txFrame + 1, 0, *txSize);
-	*txSize += BASYX_STRINGSIZE_SIZE;
-	
-        // Set result field to 0 to indicate success
-	txFrame[0] = 0;
-	*txSize += 1;
-}
-
-void BaSyxNativeFrameProcessor::processDelete(char const* rxFrame, std::size_t rxSize, char* txFrame, std::size_t* txSize) 
-{
-	std::string path = BaSyxNativeFrameHelper::getString(rxFrame, 0);
-
-        std::string result;
-
-	// Check if there is a serialized json after the path to distinguish between map/collection delete and simple delete
-	if (path.size() + BASYX_STRINGSIZE_SIZE < rxSize) {
-		std::string serializedValue = BaSyxNativeFrameHelper::getString(rxFrame,
-				1);
-            result = jsonProvider.processBaSysDelete(path, serializedValue);
-	} else {
-	    result = jsonProvider.processBaSysDelete(path);
+		return processInvoke(frame);
 	}
 
-	memcpy(txFrame + 5, result.c_str(), result.size());
-
-	// Set return string size
-	CoderTools::setInt32(txFrame + 1, 0, *txSize);
-	*txSize += BASYX_STRINGSIZE_SIZE;
-
-	// Set result field to 0 to indicate success
-	txFrame[0] = 0;
-	*txSize += 1;
+	return Frame{};
 }
 
-void BaSyxNativeFrameProcessor::processInvoke(char const* rxFrame, char* txFrame, std::size_t* txSize)
+Frame BaSyxNativeFrameProcessor::processGet(const Frame & frame)
 {
-	std::string path = BaSyxNativeFrameHelper::getString(rxFrame, 0);
+	auto path = frame.getFirstValue();
+	auto getResult = jsonProvider.processBaSysGet(path);
 
-	// TODO: Error Handling?
-	std::string serializedValue = BaSyxNativeFrameHelper::getString(rxFrame, 1);
-
-	// Advance txFrame by 5 because of the following setup of txFrame:
-	// 1 byte result field
-	// 4 byte string size
-	// N byte return value
-	auto result = jsonProvider.processBaSysInvoke(path, serializedValue, txFrame + 5,
-			txSize);
-
-	*txSize = result.size();
-	memcpy(txFrame + 5, result.c_str(), result.size());
-
-	// Set return value size
-	CoderTools::setInt32(txFrame + 1, 0, *txSize);
-	*txSize += BASYX_STRINGSIZE_SIZE;
-
-	// Set result field to 0 to indicate success
-	txFrame[0] = 0;
-	*txSize += 1;
+	return Frame{ 0x00, getResult };
 }
 
+Frame BaSyxNativeFrameProcessor::processSet(const Frame & frame)
+{
+	auto path = frame.getFirstValue();
+	auto value = frame.getSecondValue();
+
+	auto result = jsonProvider.processBaSysSet(path, value);
+
+	return Frame{ 0x00, result };
+};
+
+Frame BaSyxNativeFrameProcessor::processCreate(const Frame & frame)
+{
+	auto path = frame.getFirstValue();
+	auto value = frame.getSecondValue();
+
+	auto result = jsonProvider.processBaSysCreate(path, value);
+
+	return Frame{ 0x00, result };
+};
+
+Frame BaSyxNativeFrameProcessor::processDelete(const Frame & frame)
+{
+	auto path = frame.getFirstValue();
+	auto value = frame.getSecondValue();
+
+	// if no value specified, simple delete
+	if (value.empty())
+	{
+		auto result = jsonProvider.processBaSysDelete(path);
+		return Frame{ 0x00, result };
+	};
+
+	auto result = jsonProvider.processBaSysDelete(path, value);
+	return Frame{ 0x00, result };
+};
+
+Frame BaSyxNativeFrameProcessor::processInvoke(const Frame & frame)
+{
+	auto path = frame.getFirstValue();
+	auto value = frame.getSecondValue();
+
+	auto result = jsonProvider.processBaSysInvoke(path, value);
+
+	return Frame{ 0x00, result };
+};
+
 
 }
 }