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/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 };
+};
+
}
}