diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..071b535 --- /dev/null +++ b/.gitignore @@ -0,0 +1,67 @@ +# Local IDE / agent state +.vscode/ +.claude/settings.local.json +.codex +**/.vscode/ + +# Generic build/install outputs +build/ +install/ +cmake-build-*/ +CMakeFiles/ +CMakeCache.txt +cmake_install.cmake +compile_commands.json +*.o +*.a +*.so +*.d +*.dep +*build* +*install* +*include* +!*build*.sh + +# Generated QNX artifacts +qnx/build/ +qnx/install/ +qnx/targets/*/output/ +scripts/logs/ + +# Repo-local QNX assets are intentionally versionable even though the generic +# build/install/include patterns above would otherwise hide parts of them. +!qnx/ +!qnx/toolchains/ +!qnx/toolchains/** +!qnx/targets/ +!qnx/targets/qemu-qnx800-*/ +!qnx/targets/qemu-qnx800-*/mkqnximage-wrapper.sh +!qnx/targets/qemu-qnx800-*/local/ +!qnx/targets/qemu-qnx800-*/local/options +!qnx/targets/qemu-qnx800-*/local/valgrind.files +!qnx/targets/qemu-qnx800-*/local/misc_files/ +!qnx/targets/qemu-qnx800-*/local/snippets/ +!qnx/targets/qemu-qnx800-*/local/snippets/data_files.custom +!qnx/targets/qemu-qnx800-*/local/snippets/ifs_files.custom +!qnx/targets/qemu-qnx800-*/local/snippets/profile.custom + +# Local QNX keys/credentials and generated snippets are rewritten by QNX tooling +# or by the TPI launch scripts and must not be committed. +qnx/targets/qemu-qnx800-*/local/misc_files/* +qnx/targets/qemu-qnx800-*/local/ssh-ident +qnx/targets/qemu-qnx800-*/local/snippets/ifs_start.custom +qnx/targets/qemu-qnx800-*/local/snippets/post_start.custom +qnx/targets/qemu-qnx800-*/local/snippets/system_files.custom + +# fast_dds/ FastDDS components — source and generated IDL files are intentionally versioned. +# The broad patterns above (*include*, *build*, *install*) would otherwise hide them. +!fast_dds/ +!fast_dds/** +fast_dds/build/ +fast_dds/install/ + +# SafeDDS component headers are source files, not generated build artifacts. +!safe_dds/*/include/ +!safe_dds/*/include/** +!common_server/include/ +!common_server/include/** diff --git a/README.md b/README.md new file mode 100644 index 0000000..52c69b3 --- /dev/null +++ b/README.md @@ -0,0 +1,314 @@ +# SafeEDGE + +This repository is self-contained for SafeEDGE source code, QNX target definitions, build scripts, and test launchers. +It does not require the old `~/Safe/SAFE-EDGE` repository. + +It does not vendor third-party SDKs or source trees. QNX SDP 8 and Safe-DDS source code must be installed/provided outside this repository and pointed to with environment variables. + +## Running scripts + +All scripts live under `scripts/` and resolve paths relative to their own location. +**Always run them from inside the `scripts/` directory:** + +```bash +cd scripts +bash .sh [options] +``` + +They also work when invoked from the repository root with a prefix (`bash scripts/.sh`), but the canonical form is from inside `scripts/`. + +## Customer Quick Start + +For Ubuntu/Debian hosts, install the host packages that can be installed automatically: + +```bash +cd scripts +bash install_host_deps.sh +``` + +Provide the two external inputs that are not stored in this repository: + +```bash +export QNX_SDP_ROOT="/path/to/qnx800" +export QNX_HOST="$QNX_SDP_ROOT/host/linux/x86_64" +export QNX_TARGET="$QNX_SDP_ROOT/target/qnx" +export SAFE_DDS_PATH="/path/to/Safe-DDS-source-release" +``` + +`scripts/env.example` contains the same variables as a source-able template. + +Check the environment: + +```bash +bash check_setup.sh +``` + +Build and test (QNX): + +```bash +bash build_safedds_qnx.sh -- -j2 +bash build_qnx.sh -- -j2 +bash launch_tpi_2_3_test.sh +bash launch_tpi_2_1_test.sh +bash launch_tpi_2_2_test.sh +``` + +Build and test (FastDDS / Docker): + +```bash +bash build_ubuntu.sh --tests +bash launch_fast_server_test.sh +bash launch_fast_edge_test.sh +``` + +For Linux-only validation of the common server component: + +```bash +bash install_host_deps.sh --linux-only +bash check_setup.sh --linux-only +bash launch_tpi_2_3_test.sh +``` + +## Repository Paths + +- Shared IDL sources: `idl/` +- Safe DDS generated headers: `safe_dds/idl/` +- Shared server code: `common_server/` +- Safe DDS server: `safe_dds/server/` +- Safe DDS edge: `safe_dds/edge/` +- FastDDS server: `fast_dds/server/` +- FastDDS edge: `fast_dds/edge/` +- FastDDS generated headers: `fast_dds/idl/` +- FastDDS Dockerfiles: `fast_dds/docker/` +- QNX toolchain file: `qnx/toolchains/qnx8.cmake` +- Safe DDS QNX build script: `scripts/build_safedds_qnx.sh` +- Generated Safe DDS QNX package: `qnx/install/safedds-qnx8-x86_64/safedds` +- Bundled QNX QEMU target: `qnx/targets/qemu-qnx800-x86_64` +- Scripts: `scripts/` +- Test logs: `scripts/logs/` + +## Versioned QNX Assets + +These files are needed by the build and QNX test scripts and are intended to be kept in this repository: + +- `qnx/toolchains/qnx8.cmake` +- `scripts/build_safedds_qnx.sh` +- `qnx/targets/qemu-qnx800-x86_64/mkqnximage-wrapper.sh` +- `qnx/targets/qemu-qnx800-x86_64/local/options` +- `qnx/targets/qemu-qnx800-x86_64/local/valgrind.files` +- stable snippets under `qnx/targets/qemu-qnx800-x86_64/local/snippets/` + +These files are generated and should not be committed: + +- `qnx/build/` +- `qnx/install/` +- `qnx/targets/qemu-qnx800-x86_64/output/` +- `scripts/logs/` +- `qnx/targets/qemu-qnx800-x86_64/local/misc_files/*` +- `qnx/targets/qemu-qnx800-x86_64/local/ssh-ident` +- `qnx/targets/qemu-qnx800-x86_64/local/snippets/ifs_start.custom` +- `qnx/targets/qemu-qnx800-x86_64/local/snippets/post_start.custom` +- `qnx/targets/qemu-qnx800-x86_64/local/snippets/system_files.custom` + +The `misc_files` entries include QNX VM keys, `shadow`, and other local image files. The three generated snippets above are rewritten by `launch_tpi_2_1_test.sh` and `launch_tpi_2_2_test.sh`. + +## External Prerequisites + +### Required to build QNX targets + +- QNX SDP 8 installed on the host +- Safe-DDS source tree available on the host +- `SAFE_DDS_PATH` exported and pointing to the Safe-DDS source tree +- Default SDK path used by scripts if `QNX_SDP_ROOT` is not set: `/home/$USER/qnx800` +- Required SDK files/directories: + - `$QNX_SDP_ROOT/qnxsdp-env.sh` + - `$QNX_SDP_ROOT/host/linux/x86_64` + - `$QNX_SDP_ROOT/target/qnx` +- `cmake` +- a C/C++ build toolchain usable by CMake on the host +- Internet access during configure time if GTest is not already available locally + +`scripts/install_host_deps.sh` installs the host packages listed above where possible. It does not install QNX SDP 8 or Safe-DDS sources. + +### Required to run QNX VM tests + +- `qemu-system-x86_64` +- `sshpass` +- `brctl` from `bridge-utils` +- `file` + +### Required to build and run FastDDS Docker tests + +- Docker + +FastDDS is provided by the base Docker image (`eprosima/vulcanexus:kilted-base`); no separate FastDDS installation is required on the host. + +### Required to run the Linux test + +- `cmake` +- `libcurl` development package + - Ubuntu/Debian: `sudo apt install libcurl4-openssl-dev` + +## Environment Variables + +Required for QNX builds: + +```bash +export QNX_SDP_ROOT="/home/$USER/qnx800" +export QNX_HOST="$QNX_SDP_ROOT/host/linux/x86_64" +export QNX_TARGET="$QNX_SDP_ROOT/target/qnx" +export SAFE_DDS_PATH="/path/to/Safe-DDS-source-release" +``` + +Optional variables: + +```bash +export QNX_ARCH="x86_64" +export CMAKE_BUILD_TYPE="Release" +``` + +## Setup Check + +Install Ubuntu/Debian host packages: + +```bash +cd scripts +bash install_host_deps.sh +``` + +For only the Linux test dependencies: + +```bash +bash install_host_deps.sh --linux-only +``` + +Run: + +```bash +bash check_setup.sh +``` + +What it does: + +- checks for required host tools +- validates the expected QNX SDK path +- validates repo paths under `qnx/` +- validates that `SAFE_DDS_PATH` is defined for QNX builds +- reports local/generated QNX folders if they have not been created yet + +For a Linux-only check: + +```bash +bash check_setup.sh --linux-only +``` + +## Build + +### QNX targets + +Build and install Safe DDS for QNX if `qnx/install/safedds-qnx8-x86_64/safedds` is missing: + +```bash +cd scripts +bash build_safedds_qnx.sh -- -j2 +``` + +Build all QNX targets from this repository: + +```bash +bash build_qnx.sh -- -j2 +``` + +This configures and installs: + +- `common_server` +- `safe_dds/server` +- `safe_dds/edge` + +Installed binaries end up in: + +- `common_server/install/server-common-qnx8-x86_64-Release/bin` +- `safe_dds/install/server-qnx8-x86_64-Release/bin` +- `safe_dds/install/edge-qnx8-x86_64-Release/bin` + +### FastDDS Docker images + +Build the runtime images: + +```bash +cd scripts +bash build_ubuntu.sh +``` + +Build runtime and test images: + +```bash +bash build_ubuntu.sh --tests +``` + +Images produced: + +- `safe-edge-server:fast` +- `safe-edge-edge:fast` +- `safe-edge-server:fast-test` (with `--tests`) +- `safe-edge-edge:fast-test` (with `--tests`) + +## Test + +All test scripts log their output under `scripts/logs/`. + +### KPI/TPI 2.3: Linux test + +```bash +cd scripts +bash launch_tpi_2_3_test.sh +``` + +Log: `scripts/logs/launch_tpi_2_3.log` + +### TPI 2.1: QNX server test + +```bash +cd scripts +bash launch_tpi_2_1_test.sh +``` + +Log: `scripts/logs/launch_tpi_2_1.log` + +### TPI 2.2: QNX edge test + +```bash +cd scripts +bash launch_tpi_2_2_test.sh +``` + +Log: `scripts/logs/launch_tpi_2_2.log` + +### FastDDS server integration test + +```bash +cd scripts +bash launch_fast_server_test.sh +``` + +Log: `scripts/logs/launch_fast_server_test.log` + +Builds `safe-edge-server:fast-test` automatically if the image is not present. + +### FastDDS edge integration test + +```bash +cd scripts +bash launch_fast_edge_test.sh +``` + +Log: `scripts/logs/launch_fast_edge_test.log` + +Builds `safe-edge-edge:fast-test` automatically if the image is not present. + +## Notes + +- The QNX tests rebuild the QEMU image from `qnx/targets/qemu-qnx800-x86_64`. +- Generated target output is recreated under `qnx/targets/qemu-qnx800-x86_64/output/` and is ignored by git. +- The Linux test may execute real Pilot Server checks if `/etc/safe-edge/server.ini` exists on the host. +- The FastDDS Docker tests are self-contained: each test image spawns the component under test as a subprocess and communicates with it via DDS over the loopback interface. diff --git a/common_server/CMakeLists.txt b/common_server/CMakeLists.txt new file mode 100644 index 0000000..f7dc8a3 --- /dev/null +++ b/common_server/CMakeLists.txt @@ -0,0 +1,75 @@ +cmake_minimum_required(VERSION 3.16) + +project(safe_edge_server_common_tests LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +find_package(CURL REQUIRED) + +if(CMAKE_SYSTEM_NAME STREQUAL "QNX") + set(SAFE_EDGE_PLATFORM_SOCKET_LIB socket) +endif() + +set(SAFE_EDGE_SERVER_COMMON_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include") + +# --------------------------------------------------------------------------- +# GTest +# --------------------------------------------------------------------------- +find_package(GTest QUIET) + +if(NOT GTest_FOUND) + message(STATUS "GTest not found — fetching from source") + include(FetchContent) + FetchContent_Declare( + googletest + URL https://github.com/google/googletest/archive/refs/tags/v1.14.0.tar.gz + URL_HASH SHA256=8ad598c73ad796e0d8280b082cebd82a630d73e73cd3c70057938a6501bba5d7 + DOWNLOAD_EXTRACT_TIMESTAMP TRUE + ) + set(INSTALL_GTEST OFF CACHE BOOL "" FORCE) + FetchContent_MakeAvailable(googletest) + + if(NOT TARGET GTest::gtest_main) + add_library(GTest::gtest_main ALIAS gtest_main) + endif() +endif() + +# --------------------------------------------------------------------------- +# Test binary +# --------------------------------------------------------------------------- +add_executable( + test_server_common + src/PilotServerClient.cpp + src/PilotServerPayloadParser.cpp + test/test_server_common.cpp +) + +target_include_directories( + test_server_common + PRIVATE + "${SAFE_EDGE_SERVER_COMMON_INCLUDE_DIR}" +) + +target_compile_options( + test_server_common + PRIVATE + -Wall -Wextra -Wpedantic +) + +target_link_libraries( + test_server_common + PRIVATE + CURL::libcurl + GTest::gtest_main + ${SAFE_EDGE_PLATFORM_SOCKET_LIB} +) + +enable_testing() +add_test(NAME server_common COMMAND test_server_common) + +install( + TARGETS test_server_common + RUNTIME DESTINATION bin +) diff --git a/common_server/include/safe_edge/server/common/PilotServerClient.hpp b/common_server/include/safe_edge/server/common/PilotServerClient.hpp new file mode 100644 index 0000000..4f817c6 --- /dev/null +++ b/common_server/include/safe_edge/server/common/PilotServerClient.hpp @@ -0,0 +1,35 @@ +#ifndef SAFE_EDGE_SERVER_COMMON_PILOTSERVERCLIENT_HPP +#define SAFE_EDGE_SERVER_COMMON_PILOTSERVERCLIENT_HPP + +#include + +namespace safe_edge { +namespace server { +namespace common { + +class PilotServerClient +{ +public: + PilotServerClient( + const std::string& base_url, + const std::string& ini_path); + ~PilotServerClient(); + + // Executes HTTP GET base_url + endpoint with Authorization: Bearer . + // Returns the response body on success, empty string on any error. + // The api_key never appears in any log output. + std::string fetch(const std::string& endpoint) noexcept; + +private: + bool load_api_key(const std::string& ini_path); + + std::string base_url_; + std::string api_key_; + bool ready_ = false; +}; + +} // namespace common +} // namespace server +} // namespace safe_edge + +#endif // SAFE_EDGE_SERVER_COMMON_PILOTSERVERCLIENT_HPP diff --git a/common_server/include/safe_edge/server/common/PilotServerPayloadParser.hpp b/common_server/include/safe_edge/server/common/PilotServerPayloadParser.hpp new file mode 100644 index 0000000..003b626 --- /dev/null +++ b/common_server/include/safe_edge/server/common/PilotServerPayloadParser.hpp @@ -0,0 +1,32 @@ +#ifndef SAFE_EDGE_SERVER_COMMON_PILOTSERVERPAYLOADPARSER_HPP +#define SAFE_EDGE_SERVER_COMMON_PILOTSERVERPAYLOADPARSER_HPP + +#include +#include + +namespace safe_edge { +namespace server { +namespace common { + +// Neutral parsed representation — no DDS-stack types. +struct ParsedChargerLocation +{ + int id = 0; + std::string name; + float latitude = 0.0F; + float longitude = 0.0F; +}; + +class PilotServerPayloadParser +{ +public: + + static std::vector parse_charger_locations( + const std::string& body); +}; + +} // namespace common +} // namespace server +} // namespace safe_edge + +#endif // SAFE_EDGE_SERVER_COMMON_PILOTSERVERPAYLOADPARSER_HPP diff --git a/common_server/src/PilotServerClient.cpp b/common_server/src/PilotServerClient.cpp new file mode 100644 index 0000000..e078447 --- /dev/null +++ b/common_server/src/PilotServerClient.cpp @@ -0,0 +1,161 @@ +#include + +#include + +#include +#include +#include + +namespace safe_edge { +namespace server { +namespace common { + +namespace { + +static size_t write_callback(void* ptr, size_t size, size_t nmemb, void* userdata) +{ + static_cast(userdata)->append( + static_cast(ptr), size * nmemb); + return size * nmemb; +} + +} // namespace + +PilotServerClient::PilotServerClient( + const std::string& base_url, + const std::string& ini_path) + : base_url_(base_url) +{ + // curl_global_init / curl_global_cleanup are called once per PilotServerClient instance. + // This is safe because exactly one PilotServerClient exists in the process (owned by ServerNode). + curl_global_init(CURL_GLOBAL_DEFAULT); + ready_ = load_api_key(ini_path); +} + +PilotServerClient::~PilotServerClient() +{ + curl_global_cleanup(); +} + +bool PilotServerClient::load_api_key( + const std::string& ini_path) +{ + std::ifstream file(ini_path); + if (!file.is_open()) + { + std::cerr << "[pilot_client] Cannot open config file: " << ini_path << std::endl; + return false; + } + + bool in_section = false; + std::string line; + while (std::getline(file, line)) + { + // Strip leading whitespace + const size_t start = line.find_first_not_of(" \t\r\n"); + if (start == std::string::npos || line[start] == '#' || line[start] == ';') + { + continue; // blank line or comment + } + const std::string trimmed = line.substr(start); + + if (trimmed == "[pilot_server]") + { + in_section = true; + continue; + } + if (trimmed[0] == '[') + { + in_section = false; // different section + continue; + } + + if (!in_section) + { + continue; + } + + const size_t eq = trimmed.find('='); + if (eq == std::string::npos) + { + continue; + } + + // Trim key + const std::string raw_key = trimmed.substr(0, eq); + const size_t key_end = raw_key.find_last_not_of(" \t"); + const std::string key = (key_end != std::string::npos) + ? raw_key.substr(0, key_end + 1) : raw_key; + + // Trim value + const std::string raw_val = trimmed.substr(eq + 1); + const size_t val_start = raw_val.find_first_not_of(" \t"); + if (val_start == std::string::npos) + { + continue; + } + const size_t val_end = raw_val.find_last_not_of(" \t\r\n"); + const std::string value = raw_val.substr(val_start, val_end - val_start + 1); + + if (key == "api_key") + { + api_key_ = value; + return true; + } + } + + std::cerr << "[pilot_client] api_key not found in [pilot_server] section of " + << ini_path << std::endl; + return false; +} + +std::string PilotServerClient::fetch( + const std::string& endpoint) noexcept +{ + if (!ready_) + { + std::cerr << "[pilot_client] Not ready — check config file" << std::endl; + return {}; + } + + CURL* curl = curl_easy_init(); + if (nullptr == curl) + { + std::cerr << "[pilot_client] curl_easy_init failed" << std::endl; + return {}; + } + + const std::string url = base_url_ + endpoint; + // api_key_ must NOT appear in any log line + const std::string auth = "X-API-KEY: " + api_key_; + struct curl_slist* headers = curl_slist_append(nullptr, auth.c_str()); + + std::string body; + + curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &body); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + + const CURLcode res = curl_easy_perform(curl); + + curl_slist_free_all(headers); + curl_easy_cleanup(curl); + + if (res != CURLE_OK) + { + std::cerr << "[pilot_client] GET " << endpoint + << " failed: " << curl_easy_strerror(res) << std::endl; + return {}; + } + + std::cout << "[pilot_client] GET " << endpoint + << " bytes=" << body.size() << std::endl; + return body; +} + +} // namespace common +} // namespace server +} // namespace safe_edge diff --git a/common_server/src/PilotServerPayloadParser.cpp b/common_server/src/PilotServerPayloadParser.cpp new file mode 100644 index 0000000..8ff35ad --- /dev/null +++ b/common_server/src/PilotServerPayloadParser.cpp @@ -0,0 +1,240 @@ +#include + +#include +#include +#include + +// Hand-rolled JSON extractor — no external library, no exceptions. +// Compatible with -fno-exceptions / -fno-rtti. + +namespace safe_edge { +namespace server { +namespace common { + +namespace { + +// Returns the index one past the closing '}' matching the '{' at obj_start, +// or std::string::npos on mismatch. +static size_t find_object_end(const std::string& s, size_t obj_start) +{ + int depth = 0; + bool in_string = false; + bool escape = false; + + for (size_t i = obj_start; i < s.size(); ++i) + { + const char c = s[i]; + if (escape) + { + escape = false; + continue; + } + if (c == '\\' && in_string) + { + escape = true; + continue; + } + if (c == '"') + { + in_string = !in_string; + continue; + } + if (in_string) + { + continue; + } + if (c == '{') + { + ++depth; + } + else if (c == '}') + { + --depth; + if (depth == 0) + { + return i + 1U; + } + } + } + return std::string::npos; +} + +static bool extract_string(const std::string& obj, const char* key, std::string& out) +{ + const std::string token = std::string("\"") + key + "\""; + const size_t kpos = obj.find(token); + if (kpos == std::string::npos) + { + return false; + } + size_t pos = obj.find(':', kpos + token.size()); + if (pos == std::string::npos) + { + return false; + } + pos = obj.find('"', pos + 1U); + if (pos == std::string::npos) + { + return false; + } + const size_t start = pos + 1U; + bool escape = false; + size_t end = start; + while (end < obj.size()) + { + if (escape) + { + escape = false; + } + else if (obj[end] == '\\') + { + escape = true; + } + else if (obj[end] == '"') + { + break; + } + ++end; + } + if (end >= obj.size()) + { + return false; + } + out = obj.substr(start, end - start); + return true; +} + +static bool extract_int(const std::string& obj, const char* key, int& out) +{ + const std::string token = std::string("\"") + key + "\""; + const size_t kpos = obj.find(token); + if (kpos == std::string::npos) + { + return false; + } + size_t pos = obj.find(':', kpos + token.size()); + if (pos == std::string::npos) + { + return false; + } + ++pos; + while (pos < obj.size() && (obj[pos] == ' ' || obj[pos] == '\t' || obj[pos] == '\n')) + { + ++pos; + } + if (pos >= obj.size()) + { + return false; + } + errno = 0; + char* endp = nullptr; + const long val = strtol(obj.c_str() + pos, &endp, 10); + if (endp == obj.c_str() + pos || errno != 0) + { + return false; + } + out = static_cast(val); + return true; +} + +static bool extract_float(const std::string& obj, const char* key, float& out) +{ + const std::string token = std::string("\"") + key + "\""; + const size_t kpos = obj.find(token); + if (kpos == std::string::npos) + { + return false; + } + size_t pos = obj.find(':', kpos + token.size()); + if (pos == std::string::npos) + { + return false; + } + ++pos; + while (pos < obj.size() && (obj[pos] == ' ' || obj[pos] == '\t' || obj[pos] == '\n')) + { + ++pos; + } + if (pos >= obj.size()) + { + return false; + } + errno = 0; + char* endp = nullptr; + const double val = strtod(obj.c_str() + pos, &endp); + if (endp == obj.c_str() + pos || errno != 0) + { + return false; + } + out = static_cast(val); + return true; +} + +} // namespace + +std::vector +PilotServerPayloadParser::parse_charger_locations( + const std::string& body) +{ + std::vector result; + + size_t pos = 0U; + while (pos < body.size()) + { + const size_t obj_start = body.find('{', pos); + if (obj_start == std::string::npos) + { + break; + } + const size_t obj_end = find_object_end(body, obj_start); + if (obj_end == std::string::npos) + { + std::cerr << "[payload_parser] parse_charger_locations: unmatched '{'" << std::endl; + break; + } + + const std::string obj = body.substr(obj_start, obj_end - obj_start); + + ParsedChargerLocation loc; + + extract_int(obj, "id", loc.id); + if (!extract_string(obj, "charger_name", loc.name)) + { + extract_string(obj, "name", loc.name); // fallback + } + + // Try flat fields first, then nested "position" object + const bool has_flat = + extract_float(obj, "latitude", loc.latitude) && + extract_float(obj, "longitude", loc.longitude); + + if (!has_flat) + { + const size_t pos_key = obj.find("\"position\""); + if (pos_key != std::string::npos) + { + const size_t inner_start = obj.find('{', pos_key); + if (inner_start != std::string::npos) + { + const size_t inner_end = find_object_end(obj, inner_start); + if (inner_end != std::string::npos) + { + const std::string inner = obj.substr(inner_start, + inner_end - inner_start); + extract_float(inner, "latitude", loc.latitude); + extract_float(inner, "longitude", loc.longitude); + } + } + } + } + + result.push_back(loc); + pos = obj_end; + } + + return result; +} + +} // namespace common +} // namespace server +} // namespace safe_edge diff --git a/common_server/test/launch_server_common_test.sh b/common_server/test/launch_server_common_test.sh new file mode 100755 index 0000000..7842e98 --- /dev/null +++ b/common_server/test/launch_server_common_test.sh @@ -0,0 +1,55 @@ +#!/usr/bin/env bash +# Build and run server_common unit tests on Linux/Ubuntu. +# +# Usage: +# bash launch_server_common_test.sh +# +# Prerequisites: +# - cmake >= 3.16 +# - libcurl development headers: sudo apt install libcurl4-openssl-dev +# - Internet access at configure time (GTest fetched if not installed) +# +# Environment variables: +# CMAKE_BUILD_TYPE Release|Debug (default: Debug) +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +SERVER_COMMON_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)" + +: "${CMAKE_BUILD_TYPE:=Debug}" + +BUILD_DIR="${SERVER_COMMON_DIR}/build/linux-${CMAKE_BUILD_TYPE}" +CACHE_FILE="${BUILD_DIR}/CMakeCache.txt" + +if [[ -f "${CACHE_FILE}" ]]; then + CACHED_SOURCE_DIR="$(sed -n 's/^CMAKE_HOME_DIRECTORY:INTERNAL=//p' "${CACHE_FILE}")" + if [[ -n "${CACHED_SOURCE_DIR}" && "${CACHED_SOURCE_DIR}" != "${SERVER_COMMON_DIR}" ]]; then + echo "Removing stale CMake cache from copied build directory..." + rm -rf "${BUILD_DIR}" + fi +fi + +echo "Configuring server_common tests..." +cmake \ + -S "${SERVER_COMMON_DIR}" \ + -B "${BUILD_DIR}" \ + -DCMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE}" + +echo "Building..." +cmake --build "${BUILD_DIR}" --parallel + +echo "" +echo "Running test_server_common..." +echo "---------------------------------------------" + +TEST_RC=0 +"${BUILD_DIR}/test_server_common" || TEST_RC=$? + +echo "---------------------------------------------" + +if [[ "${TEST_RC}" -eq 0 ]]; then + echo "PASSED" +else + echo "FAILED (exit code ${TEST_RC})" + exit "${TEST_RC}" +fi diff --git a/common_server/test/test_server_common.cpp b/common_server/test/test_server_common.cpp new file mode 100644 index 0000000..1d45d95 --- /dev/null +++ b/common_server/test/test_server_common.cpp @@ -0,0 +1,316 @@ +#include +#include + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +using safe_edge::server::common::ParsedChargerLocation; +using safe_edge::server::common::PilotServerPayloadParser; +using safe_edge::server::common::PilotServerClient; + +static const char* const PILOT_SERVER_BASE_URL = "https://pilot2.dumitru-alexandru.work"; +static const char* const PILOT_SERVER_INI_PATH = "/etc/safe-edge/server.ini"; +static const char* const CHARGER_LOCATIONS_EP = "/api/chargers/locations"; +static const char* const CHARGER_TYPES_EP = "/api/chargers/types"; +static const char* const CHARGING_SESSIONS_EP = "/api/chargers/sessions"; +static const char* const TRANSIT_HEALTH_EP = "/api/transit/health"; +static const char* const TRANSIT_METRICS_EP = "/api/transit/metrics"; + +static bool looks_like_json_payload(const std::string& body) +{ + for (char ch : body) + { + if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') + { + continue; + } + return ch == '{' || ch == '['; + } + return false; +} + +static void skip_if_degraded_real_response( + const std::string& body, + const char* endpoint, + const char* expected_marker) +{ + if (body.empty()) + { + GTEST_SKIP() << endpoint << " returned an empty response"; + } + + if (!looks_like_json_payload(body)) + { + GTEST_SKIP() << endpoint << " returned a non-JSON payload of " << body.size() << " bytes"; + } + + if (body.find(expected_marker) == std::string::npos) + { + GTEST_SKIP() << endpoint << " returned a schema-mismatched payload of " << body.size() + << " bytes; expected marker '" << expected_marker << "'"; + } +} + +// ============================================================================ +// PilotServerPayloadParser +// ============================================================================ + +TEST(PilotServerPayloadParserTest, FlatFields) +{ + const std::string body = + R"([{"id":1,"name":"Hub A","latitude":40.4637,"longitude":-3.7492},)" + R"( {"id":2,"name":"Hub B","latitude":41.3851,"longitude":2.1734}])"; + + const auto result = PilotServerPayloadParser::parse_charger_locations(body); + + ASSERT_EQ(2U, result.size()); + EXPECT_EQ(1, result[0].id); + EXPECT_EQ("Hub A", result[0].name); + EXPECT_FLOAT_EQ(40.4637F, result[0].latitude); + EXPECT_FLOAT_EQ(-3.7492F, result[0].longitude); + EXPECT_EQ(2, result[1].id); + EXPECT_EQ("Hub B", result[1].name); +} + +TEST(PilotServerPayloadParserTest, NestedPosition) +{ + const std::string body = + R"([{"id":5,"name":"Depot","position":{"latitude":39.4699,"longitude":-0.3763}}])"; + + const auto result = PilotServerPayloadParser::parse_charger_locations(body); + + ASSERT_EQ(1U, result.size()); + EXPECT_EQ(5, result[0].id); + EXPECT_EQ("Depot", result[0].name); + EXPECT_FLOAT_EQ(39.4699F, result[0].latitude); + EXPECT_FLOAT_EQ(-0.3763F, result[0].longitude); +} + +TEST(PilotServerPayloadParserTest, EmptyPayload) +{ + const auto result = PilotServerPayloadParser::parse_charger_locations(""); + EXPECT_TRUE(result.empty()); +} + +TEST(PilotServerPayloadParserTest, InvalidJson) +{ + const auto result = PilotServerPayloadParser::parse_charger_locations("not json at all"); + EXPECT_TRUE(result.empty()); +} + +TEST(PilotServerPayloadParserTest, MissingFields) +{ + // Object present but only id — name, latitude, longitude absent + const std::string body = R"([{"id":7}])"; + + const auto result = PilotServerPayloadParser::parse_charger_locations(body); + + ASSERT_EQ(1U, result.size()); + EXPECT_EQ(7, result[0].id); + EXPECT_EQ("", result[0].name); + EXPECT_FLOAT_EQ(0.0F, result[0].latitude); + EXPECT_FLOAT_EQ(0.0F, result[0].longitude); +} + +// ============================================================================ +// PilotServerClient +// ============================================================================ + +static const char* const CONFIG_PATH = "/tmp/test_pilotclient.ini"; + +static void write_config(const char* content) +{ + std::ofstream f(CONFIG_PATH); + f << content; +} + +static void remove_config() +{ + ::unlink(CONFIG_PATH); +} + +TEST(PilotServerClientTest, MissingConfigFile) +{ + remove_config(); + PilotServerClient client("http://127.0.0.1:18099", CONFIG_PATH); + EXPECT_TRUE(client.fetch("/any").empty()); +} + +TEST(PilotServerClientTest, MissingApiKey) +{ + write_config("[pilot_server]\n# no api_key\n"); + PilotServerClient client("http://127.0.0.1:18099", CONFIG_PATH); + EXPECT_TRUE(client.fetch("/any").empty()); + remove_config(); +} + +TEST(PilotServerClientTest, WrongSection) +{ + write_config("[other_section]\napi_key = secret\n"); + PilotServerClient client("http://127.0.0.1:18099", CONFIG_PATH); + EXPECT_TRUE(client.fetch("/any").empty()); + remove_config(); +} + +TEST(PilotServerClientTest, SuccessPathMockServer) +{ + static constexpr uint16_t PORT = 18099U; + static const char* const BODY = + R"([{"id":1,"name":"Mock","latitude":1.0,"longitude":2.0}])"; + + std::thread server_thread([&]() + { + const int srv = ::socket(AF_INET, SOCK_STREAM, 0); + if (srv < 0) { return; } + + const int opt = 1; + ::setsockopt(srv, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); + + struct sockaddr_in addr{}; + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + addr.sin_port = htons(PORT); + + if (::bind(srv, reinterpret_cast(&addr), sizeof(addr)) < 0) + { + ::close(srv); + return; + } + ::listen(srv, 1); + + const int conn = ::accept(srv, nullptr, nullptr); + if (conn >= 0) + { + char buf[4096]; + ::recv(conn, buf, sizeof(buf), 0); + + const std::string body = BODY; + const std::string response = + "HTTP/1.1 200 OK\r\n" + "Content-Type: application/json\r\n" + "Content-Length: " + std::to_string(body.size()) + "\r\n" + "Connection: close\r\n" + "\r\n" + body; + ::send(conn, response.c_str(), response.size(), 0); + ::close(conn); + } + ::close(srv); + }); + + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + + write_config("[pilot_server]\napi_key = testkey\n"); + PilotServerClient client( + "http://127.0.0.1:" + std::to_string(PORT), CONFIG_PATH); + + const std::string result = client.fetch("/locations"); + remove_config(); + server_thread.join(); + + EXPECT_FALSE(result.empty()); + EXPECT_NE(std::string::npos, result.find("Mock")); +} + +// ============================================================================ +// Real Pilot Server tests +// Skipped automatically if /etc/safe-edge/server.ini is not present. +// ============================================================================ + +TEST(RealPilotServerTest, ChargerLocationsReturnsParsedData) +{ + if (::access(PILOT_SERVER_INI_PATH, F_OK) != 0) + { + GTEST_SKIP() << PILOT_SERVER_INI_PATH << " not found — skipping real server test"; + } + + PilotServerClient client(PILOT_SERVER_BASE_URL, PILOT_SERVER_INI_PATH); + + const std::string body = client.fetch(CHARGER_LOCATIONS_EP); + skip_if_degraded_real_response(body, CHARGER_LOCATIONS_EP, "id"); + + const auto locations = PilotServerPayloadParser::parse_charger_locations(body); + if (locations.empty()) + { + GTEST_SKIP() << CHARGER_LOCATIONS_EP + << " returned JSON but no parseable charger locations"; + } + + std::cout << " [real] Received " << locations.size() << " charger location(s)\n"; + for (const auto& loc : locations) + { + std::cout << " [real] id=" << loc.id + << " name=" << loc.name + << " lat=" << loc.latitude + << " lng=" << loc.longitude << "\n"; + } +} + +TEST(RealPilotServerTest, ChargerTypesReturnsData) +{ + if (::access(PILOT_SERVER_INI_PATH, F_OK) != 0) + { + GTEST_SKIP() << PILOT_SERVER_INI_PATH << " not found — skipping real server test"; + } + + PilotServerClient client(PILOT_SERVER_BASE_URL, PILOT_SERVER_INI_PATH); + const std::string body = client.fetch(CHARGER_TYPES_EP); + + skip_if_degraded_real_response(body, CHARGER_TYPES_EP, "charger_type"); + + std::cout << " [real] charger_types response bytes=" << body.size() << "\n"; +} + +TEST(RealPilotServerTest, ChargingSessionsReturnsData) +{ + if (::access(PILOT_SERVER_INI_PATH, F_OK) != 0) + { + GTEST_SKIP() << PILOT_SERVER_INI_PATH << " not found — skipping real server test"; + } + + PilotServerClient client(PILOT_SERVER_BASE_URL, PILOT_SERVER_INI_PATH); + const std::string body = client.fetch(CHARGING_SESSIONS_EP); + + skip_if_degraded_real_response(body, CHARGING_SESSIONS_EP, "station_id"); + + std::cout << " [real] charging_sessions response bytes=" << body.size() << "\n"; +} + +TEST(RealPilotServerTest, TransitHealthReturnsStatus) +{ + if (::access(PILOT_SERVER_INI_PATH, F_OK) != 0) + { + GTEST_SKIP() << PILOT_SERVER_INI_PATH << " not found — skipping real server test"; + } + + PilotServerClient client(PILOT_SERVER_BASE_URL, PILOT_SERVER_INI_PATH); + const std::string body = client.fetch(TRANSIT_HEALTH_EP); + + skip_if_degraded_real_response(body, TRANSIT_HEALTH_EP, "status"); + + std::cout << " [real] transit_health response: " << body << "\n"; +} + +TEST(RealPilotServerTest, TransitMetricsReturnsByRoute) +{ + if (::access(PILOT_SERVER_INI_PATH, F_OK) != 0) + { + GTEST_SKIP() << PILOT_SERVER_INI_PATH << " not found — skipping real server test"; + } + + PilotServerClient client(PILOT_SERVER_BASE_URL, PILOT_SERVER_INI_PATH); + const std::string body = client.fetch(TRANSIT_METRICS_EP); + + skip_if_degraded_real_response(body, TRANSIT_METRICS_EP, "by_route"); + + std::cout << " [real] transit_metrics response bytes=" << body.size() << "\n"; +} diff --git a/fast_dds/docker/edge.Dockerfile b/fast_dds/docker/edge.Dockerfile new file mode 100644 index 0000000..a5c693a --- /dev/null +++ b/fast_dds/docker/edge.Dockerfile @@ -0,0 +1,31 @@ +ARG FASTDDS_BASE_IMAGE=eprosima/vulcanexus:kilted-base +FROM ${FASTDDS_BASE_IMAGE} AS build + +ARG CMAKE_BUILD_TYPE=Release +ARG CMAKE_PREFIX_PATH=/opt/ros/kilted +ARG EDGE_INSTALL_PREFIX=/opt/safe-edge/edge + +WORKDIR /workspace + +COPY fast_dds/idl /workspace/fast_dds/idl +COPY fast_dds/edge /workspace/fast_dds/edge + +RUN cmake -S /workspace/fast_dds/edge \ + -B /workspace/build/edge \ + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} \ + -DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH} \ + -DCMAKE_INSTALL_PREFIX=${EDGE_INSTALL_PREFIX} \ + && cmake --build /workspace/build/edge --target install -j"$(nproc)" + +FROM ${FASTDDS_BASE_IMAGE} AS runtime + +ARG EDGE_INSTALL_PREFIX=/opt/safe-edge/edge + +ENV LD_LIBRARY_PATH=/opt/ros/kilted/lib +ENV FASTDDS_BUILTIN_TRANSPORTS=UDPv4 + +COPY --from=build ${EDGE_INSTALL_PREFIX} ${EDGE_INSTALL_PREFIX} + +WORKDIR ${EDGE_INSTALL_PREFIX} + +ENTRYPOINT ["/opt/safe-edge/edge/bin/safe_edge_edge_gateway"] diff --git a/fast_dds/docker/edge.test.Dockerfile b/fast_dds/docker/edge.test.Dockerfile new file mode 100644 index 0000000..ede70d4 --- /dev/null +++ b/fast_dds/docker/edge.test.Dockerfile @@ -0,0 +1,31 @@ +ARG FASTDDS_BASE_IMAGE=eprosima/vulcanexus:kilted-base +FROM ${FASTDDS_BASE_IMAGE} AS build + +ARG CMAKE_BUILD_TYPE=Release +ARG CMAKE_PREFIX_PATH=/opt/ros/kilted +ARG EDGE_INSTALL_PREFIX=/opt/safe-edge/edge + +WORKDIR /workspace + +COPY fast_dds/idl /workspace/fast_dds/idl +COPY fast_dds/edge /workspace/fast_dds/edge + +RUN cmake -S /workspace/fast_dds/edge \ + -B /workspace/build/edge \ + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} \ + -DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH} \ + -DCMAKE_INSTALL_PREFIX=${EDGE_INSTALL_PREFIX} \ + -DSAFE_EDGE_BUILD_TESTS=ON \ + && cmake --build /workspace/build/edge --target install -j"$(nproc)" + +FROM ${FASTDDS_BASE_IMAGE} AS test + +ARG EDGE_INSTALL_PREFIX=/opt/safe-edge/edge + +ENV LD_LIBRARY_PATH=/opt/ros/kilted/lib +ENV FASTDDS_BUILTIN_TRANSPORTS=UDPv4 +ENV SAFE_EDGE_FAST_EDGE_BIN=${EDGE_INSTALL_PREFIX}/bin/safe_edge_edge_gateway + +COPY --from=build ${EDGE_INSTALL_PREFIX} ${EDGE_INSTALL_PREFIX} + +ENTRYPOINT ["/opt/safe-edge/edge/bin/test_edge_integration"] diff --git a/fast_dds/docker/server.Dockerfile b/fast_dds/docker/server.Dockerfile new file mode 100644 index 0000000..5b510f0 --- /dev/null +++ b/fast_dds/docker/server.Dockerfile @@ -0,0 +1,32 @@ +ARG FASTDDS_BASE_IMAGE=eprosima/vulcanexus:kilted-base +FROM ${FASTDDS_BASE_IMAGE} AS build + +ARG CMAKE_BUILD_TYPE=Release +ARG CMAKE_PREFIX_PATH=/opt/ros/kilted +ARG SERVER_INSTALL_PREFIX=/opt/safe-edge/server + +WORKDIR /workspace + +COPY fast_dds/idl /workspace/fast_dds/idl +COPY fast_dds/server /workspace/fast_dds/server +COPY common_server /workspace/common_server + +RUN cmake -S /workspace/fast_dds/server \ + -B /workspace/build/server \ + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} \ + -DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH} \ + -DCMAKE_INSTALL_PREFIX=${SERVER_INSTALL_PREFIX} \ + && cmake --build /workspace/build/server --target install -j"$(nproc)" + +FROM ${FASTDDS_BASE_IMAGE} AS runtime + +ARG SERVER_INSTALL_PREFIX=/opt/safe-edge/server + +ENV LD_LIBRARY_PATH=/opt/ros/kilted/lib +ENV FASTDDS_BUILTIN_TRANSPORTS=UDPv4 + +COPY --from=build ${SERVER_INSTALL_PREFIX} ${SERVER_INSTALL_PREFIX} + +WORKDIR ${SERVER_INSTALL_PREFIX} + +ENTRYPOINT ["/opt/safe-edge/server/bin/safe_edge_server"] diff --git a/fast_dds/docker/server.test.Dockerfile b/fast_dds/docker/server.test.Dockerfile new file mode 100644 index 0000000..cf2dcf5 --- /dev/null +++ b/fast_dds/docker/server.test.Dockerfile @@ -0,0 +1,32 @@ +ARG FASTDDS_BASE_IMAGE=eprosima/vulcanexus:kilted-base +FROM ${FASTDDS_BASE_IMAGE} AS build + +ARG CMAKE_BUILD_TYPE=Release +ARG CMAKE_PREFIX_PATH=/opt/ros/kilted +ARG SERVER_INSTALL_PREFIX=/opt/safe-edge/server + +WORKDIR /workspace + +COPY fast_dds/idl /workspace/fast_dds/idl +COPY fast_dds/server /workspace/fast_dds/server +COPY common_server /workspace/common_server + +RUN cmake -S /workspace/fast_dds/server \ + -B /workspace/build/server \ + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} \ + -DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH} \ + -DCMAKE_INSTALL_PREFIX=${SERVER_INSTALL_PREFIX} \ + -DSAFE_EDGE_BUILD_TESTS=ON \ + && cmake --build /workspace/build/server --target install -j"$(nproc)" + +FROM ${FASTDDS_BASE_IMAGE} AS test + +ARG SERVER_INSTALL_PREFIX=/opt/safe-edge/server + +ENV LD_LIBRARY_PATH=/opt/ros/kilted/lib +ENV FASTDDS_BUILTIN_TRANSPORTS=UDPv4 +ENV SAFE_EDGE_FAST_SERVER_BIN=${SERVER_INSTALL_PREFIX}/bin/safe_edge_server + +COPY --from=build ${SERVER_INSTALL_PREFIX} ${SERVER_INSTALL_PREFIX} + +ENTRYPOINT ["/opt/safe-edge/server/bin/test_server_integration"] diff --git a/fast_dds/edge/CMakeLists.txt b/fast_dds/edge/CMakeLists.txt new file mode 100644 index 0000000..0899426 --- /dev/null +++ b/fast_dds/edge/CMakeLists.txt @@ -0,0 +1,142 @@ +cmake_minimum_required(VERSION 3.16) + +project(safe_edge_edge LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +find_package(fastdds REQUIRED) + +if(CMAKE_SYSTEM_NAME STREQUAL "QNX") + set(SAFE_EDGE_PLATFORM_SOCKET_LIB socket) +endif() + +set(SAFE_EDGE_EDGE_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include") +set(SAFE_EDGE_IDL_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../idl") + +function(safe_edge_apply_common_build_settings target_name) + target_include_directories( + "${target_name}" + PUBLIC + "${SAFE_EDGE_EDGE_INCLUDE_DIR}" + ) + + target_compile_options( + "${target_name}" + PRIVATE + -Wall + -Werror + -Wextra + -Wpedantic + ) +endfunction() + +add_library( + safe_edge_edge_common + STATIC + ${SAFE_EDGE_IDL_INCLUDE_DIR}/commonPubSubTypes.cxx + ${SAFE_EDGE_IDL_INCLUDE_DIR}/commonTypeObjectSupport.cxx + ${SAFE_EDGE_IDL_INCLUDE_DIR}/edgePubSubTypes.cxx + ${SAFE_EDGE_IDL_INCLUDE_DIR}/edgeTypeObjectSupport.cxx + ${SAFE_EDGE_IDL_INCLUDE_DIR}/pilot_serverPubSubTypes.cxx + ${SAFE_EDGE_IDL_INCLUDE_DIR}/pilot_serverTypeObjectSupport.cxx + src/common/RuntimeConfig.cpp + src/common/TopicNames.cpp + src/common/HeaderFactory.cpp + src/logic/EdgeAdvisor.cpp +) +safe_edge_apply_common_build_settings(safe_edge_edge_common) +target_include_directories( + safe_edge_edge_common + PUBLIC + "${SAFE_EDGE_IDL_INCLUDE_DIR}" +) +target_link_libraries( + safe_edge_edge_common + PUBLIC + fastdds +) + +add_executable( + safe_edge_edge_gateway + src/apps/edge_gateway_main.cpp + src/nodes/EdgeGatewayNode.cpp +) +safe_edge_apply_common_build_settings(safe_edge_edge_gateway) +target_include_directories( + safe_edge_edge_gateway + PRIVATE + "${SAFE_EDGE_IDL_INCLUDE_DIR}" +) +target_link_libraries( + safe_edge_edge_gateway + PRIVATE + safe_edge_edge_common + fastdds + ${SAFE_EDGE_PLATFORM_SOCKET_LIB} +) + +install( + TARGETS + safe_edge_edge_gateway + RUNTIME DESTINATION bin +) + +option(SAFE_EDGE_BUILD_TESTS "Build integration tests" ON) + +if(SAFE_EDGE_BUILD_TESTS) + find_package(GTest QUIET) + + if(NOT GTest_FOUND) + message(STATUS "GTest not found — fetching from source") + include(FetchContent) + FetchContent_Declare( + googletest + URL https://github.com/google/googletest/archive/refs/tags/v1.14.0.tar.gz + URL_HASH SHA256=8ad598c73ad796e0d8280b082cebd82a630d73e73cd3c70057938a6501bba5d7 + DOWNLOAD_EXTRACT_TIMESTAMP TRUE + ) + set(INSTALL_GTEST OFF CACHE BOOL "" FORCE) + FetchContent_MakeAvailable(googletest) + + if(NOT TARGET GTest::gtest) + add_library(GTest::gtest ALIAS gtest) + endif() + endif() + + add_executable( + test_edge_integration + test/test_edge_integration.cpp + ) + + # Tests need exceptions and RTTI (GTest requirement). + # Do not reuse safe_edge_apply_common_build_settings which disables them. + target_include_directories( + test_edge_integration + PRIVATE + "${SAFE_EDGE_EDGE_INCLUDE_DIR}" + "${SAFE_EDGE_IDL_INCLUDE_DIR}" + ) + target_compile_options( + test_edge_integration + PRIVATE + -Wall -Wextra -Wpedantic + ) + target_link_libraries( + test_edge_integration + PRIVATE + safe_edge_edge_common + fastdds + ${SAFE_EDGE_PLATFORM_SOCKET_LIB} + GTest::gtest + ) + + enable_testing() + add_test(NAME edge_integration COMMAND test_edge_integration) + + install( + TARGETS test_edge_integration + RUNTIME DESTINATION bin + ) +endif() diff --git a/fast_dds/edge/include/safe_edge/edge_module/common/HeaderFactory.hpp b/fast_dds/edge/include/safe_edge/edge_module/common/HeaderFactory.hpp new file mode 100644 index 0000000..fa53aa9 --- /dev/null +++ b/fast_dds/edge/include/safe_edge/edge_module/common/HeaderFactory.hpp @@ -0,0 +1,33 @@ +#ifndef SAFE_EDGE_EDGE_MODULE_COMMON_HEADERFACTORY_HPP +#define SAFE_EDGE_EDGE_MODULE_COMMON_HEADERFACTORY_HPP + +#include + +#include +#include + +namespace safe_edge { +namespace edge_module { +namespace common { + +class HeaderFactory +{ +public: + + explicit HeaderFactory(std::string source_name); + + safe_edge::common::Header make_header(const char* trace_suffix = nullptr); + + static uint64_t now_ms() noexcept; + +private: + + std::string source_name_; + uint64_t counter_ = 0U; +}; + +} // namespace common +} // namespace edge_module +} // namespace safe_edge + +#endif // SAFE_EDGE_EDGE_MODULE_COMMON_HEADERFACTORY_HPP diff --git a/fast_dds/edge/include/safe_edge/edge_module/common/RuntimeConfig.hpp b/fast_dds/edge/include/safe_edge/edge_module/common/RuntimeConfig.hpp new file mode 100644 index 0000000..88a357c --- /dev/null +++ b/fast_dds/edge/include/safe_edge/edge_module/common/RuntimeConfig.hpp @@ -0,0 +1,27 @@ +#ifndef SAFE_EDGE_EDGE_MODULE_COMMON_RUNTIMECONFIG_HPP +#define SAFE_EDGE_EDGE_MODULE_COMMON_RUNTIMECONFIG_HPP + +#include +#include + +namespace safe_edge { +namespace edge_module { +namespace common { + +struct RuntimeConfig +{ + std::string participant_name; + std::string service_name; + std::string source_name; + uint32_t domain_id = 0U; + uint16_t participant_port = 0U; + uint32_t status_interval_sec = 5U; +}; + +RuntimeConfig make_edge_gateway_runtime_config(); + +} // namespace common +} // namespace edge_module +} // namespace safe_edge + +#endif // SAFE_EDGE_EDGE_MODULE_COMMON_RUNTIMECONFIG_HPP diff --git a/fast_dds/edge/include/safe_edge/edge_module/common/TopicNames.hpp b/fast_dds/edge/include/safe_edge/edge_module/common/TopicNames.hpp new file mode 100644 index 0000000..eef164e --- /dev/null +++ b/fast_dds/edge/include/safe_edge/edge_module/common/TopicNames.hpp @@ -0,0 +1,20 @@ +#ifndef SAFE_EDGE_EDGE_MODULE_COMMON_TOPICNAMES_HPP +#define SAFE_EDGE_EDGE_MODULE_COMMON_TOPICNAMES_HPP + +namespace safe_edge { +namespace edge_module { +namespace common { +namespace topic_names { + +const char* vehicle_edge_summary() noexcept; +const char* energy_advisory() noexcept; +const char* edge_gateway_status() noexcept; +const char* charger_locations() noexcept; +const char* service_heartbeat() noexcept; + +} // namespace topic_names +} // namespace common +} // namespace edge_module +} // namespace safe_edge + +#endif // SAFE_EDGE_EDGE_MODULE_COMMON_TOPICNAMES_HPP diff --git a/fast_dds/edge/include/safe_edge/edge_module/logic/EdgeAdvisor.hpp b/fast_dds/edge/include/safe_edge/edge_module/logic/EdgeAdvisor.hpp new file mode 100644 index 0000000..c6d7c7d --- /dev/null +++ b/fast_dds/edge/include/safe_edge/edge_module/logic/EdgeAdvisor.hpp @@ -0,0 +1,25 @@ +#ifndef SAFE_EDGE_EDGE_MODULE_LOGIC_EDGEADVISOR_HPP +#define SAFE_EDGE_EDGE_MODULE_LOGIC_EDGEADVISOR_HPP + +#include +#include + +namespace safe_edge { +namespace edge_module { +namespace logic { + +class EdgeAdvisor +{ +public: + + static safe_edge::edge::EnergyAdvisory evaluate( + const safe_edge::edge::VehicleEdgeSummary& summary, + const safe_edge::pilot_server::ChargerLocation* chargers, + int32_t charger_count); +}; + +} // namespace logic +} // namespace edge_module +} // namespace safe_edge + +#endif // SAFE_EDGE_EDGE_MODULE_LOGIC_EDGEADVISOR_HPP diff --git a/fast_dds/edge/include/safe_edge/edge_module/nodes/EdgeGatewayNode.hpp b/fast_dds/edge/include/safe_edge/edge_module/nodes/EdgeGatewayNode.hpp new file mode 100644 index 0000000..f18646a --- /dev/null +++ b/fast_dds/edge/include/safe_edge/edge_module/nodes/EdgeGatewayNode.hpp @@ -0,0 +1,169 @@ +#ifndef SAFE_EDGE_EDGE_MODULE_NODES_EDGEGATEWAYNODE_HPP +#define SAFE_EDGE_EDGE_MODULE_NODES_EDGEGATEWAYNODE_HPP + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace safe_edge { +namespace edge_module { +namespace nodes { + +class EdgeGatewayNode +{ +public: + + explicit EdgeGatewayNode(const common::RuntimeConfig& runtime_config); + + int run(); + +private: + + class ParticipantListener : + public eprosima::fastdds::dds::DomainParticipantListener + { + public: + + explicit ParticipantListener(EdgeGatewayNode& owner); + + void on_subscription_matched( + eprosima::fastdds::dds::DataReader* reader, + const eprosima::fastdds::dds::SubscriptionMatchedStatus& info) noexcept override; + + void on_publication_matched( + eprosima::fastdds::dds::DataWriter* writer, + const eprosima::fastdds::dds::PublicationMatchedStatus& info) noexcept override; + + private: + + EdgeGatewayNode& owner_; + }; + + class VehicleEdgeSummaryListener : + public eprosima::fastdds::dds::DataReaderListener + { + public: + + explicit VehicleEdgeSummaryListener(EdgeGatewayNode& owner); + + void on_data_available( + eprosima::fastdds::dds::DataReader* reader) noexcept override; + + private: + + EdgeGatewayNode& owner_; + }; + + class ChargerLocationListener : + public eprosima::fastdds::dds::DataReaderListener + { + public: + + explicit ChargerLocationListener(EdgeGatewayNode& owner); + + void on_data_available( + eprosima::fastdds::dds::DataReader* reader) noexcept override; + + private: + + EdgeGatewayNode& owner_; + }; + + class HeartbeatListener : + public eprosima::fastdds::dds::DataReaderListener + { + public: + + explicit HeartbeatListener(EdgeGatewayNode& owner); + + void on_data_available( + eprosima::fastdds::dds::DataReader* reader) noexcept override; + + private: + + EdgeGatewayNode& owner_; + }; + + bool initialize(); + bool create_participant(); + bool register_types(); + bool create_topics(); + bool create_endpoints(); + bool enable_entities(); + + void on_vehicle_edge_summary_received(const safe_edge::edge::VehicleEdgeSummary& summary); + void on_charger_location_received(const safe_edge::pilot_server::ChargerLocation& location); + void on_server_heartbeat_received(const safe_edge::common::ServiceHeartbeat& heartbeat); + void publish_energy_advisory(const safe_edge::edge::EnergyAdvisory& advisory); + void publish_edge_gateway_status(); + + void log_subscription_match(const char* topic_name, int32_t total_count) const; + void log_publication_match(const char* topic_name, int32_t total_count) const; + + common::RuntimeConfig runtime_config_; + common::HeaderFactory header_factory_; + + ParticipantListener participant_listener_; + VehicleEdgeSummaryListener vehicle_edge_summary_listener_; + ChargerLocationListener charger_location_listener_; + HeartbeatListener heartbeat_listener_; + + eprosima::fastdds::dds::TypeSupport vehicle_edge_summary_type_support_; + eprosima::fastdds::dds::TypeSupport energy_advisory_type_support_; + eprosima::fastdds::dds::TypeSupport edge_gateway_status_type_support_; + eprosima::fastdds::dds::TypeSupport charger_location_type_support_; + eprosima::fastdds::dds::TypeSupport service_heartbeat_type_support_; + + eprosima::fastdds::dds::DomainParticipant* participant_ = nullptr; + eprosima::fastdds::dds::Publisher* publisher_ = nullptr; + eprosima::fastdds::dds::Subscriber* subscriber_ = nullptr; + + std::string vehicle_edge_summary_topic_name_; + std::string energy_advisory_topic_name_; + std::string edge_gateway_status_topic_name_; + std::string charger_location_topic_name_; + std::string service_heartbeat_topic_name_; + + eprosima::fastdds::dds::Topic* vehicle_edge_summary_topic_ = nullptr; + eprosima::fastdds::dds::Topic* energy_advisory_topic_ = nullptr; + eprosima::fastdds::dds::Topic* edge_gateway_status_topic_ = nullptr; + eprosima::fastdds::dds::Topic* charger_location_topic_ = nullptr; + eprosima::fastdds::dds::Topic* service_heartbeat_topic_ = nullptr; + + eprosima::fastdds::dds::DataWriter* energy_advisory_datawriter_ = nullptr; + eprosima::fastdds::dds::DataWriter* edge_gateway_status_datawriter_ = nullptr; + + eprosima::fastdds::dds::DataReader* vehicle_edge_summary_datareader_ = nullptr; + eprosima::fastdds::dds::DataReader* charger_location_datareader_ = nullptr; + eprosima::fastdds::dds::DataReader* service_heartbeat_datareader_ = nullptr; + + safe_edge::pilot_server::ChargerLocation cached_chargers_[3]; + int32_t cached_charger_count_ = 0; + uint64_t last_server_sync_ms_ = 0U; + uint64_t last_server_hb_ms_ = 0U; + bool server_available_ = false; + + std::chrono::steady_clock::time_point next_status_fire_; +}; + +} // namespace nodes +} // namespace edge_module +} // namespace safe_edge + +#endif // SAFE_EDGE_EDGE_MODULE_NODES_EDGEGATEWAYNODE_HPP diff --git a/fast_dds/edge/src/apps/edge_gateway_main.cpp b/fast_dds/edge/src/apps/edge_gateway_main.cpp new file mode 100644 index 0000000..69026fa --- /dev/null +++ b/fast_dds/edge/src/apps/edge_gateway_main.cpp @@ -0,0 +1,11 @@ +#include +#include + +int main() +{ + const safe_edge::edge_module::common::RuntimeConfig config = + safe_edge::edge_module::common::make_edge_gateway_runtime_config(); + + safe_edge::edge_module::nodes::EdgeGatewayNode node(config); + return node.run(); +} diff --git a/fast_dds/edge/src/common/HeaderFactory.cpp b/fast_dds/edge/src/common/HeaderFactory.cpp new file mode 100644 index 0000000..632189d --- /dev/null +++ b/fast_dds/edge/src/common/HeaderFactory.cpp @@ -0,0 +1,49 @@ +#include + +#include +#include +#include +#include + +namespace safe_edge { +namespace edge_module { +namespace common { + +HeaderFactory::HeaderFactory(std::string source_name) + : source_name_(std::move(source_name)) +{ +} + +safe_edge::common::Header HeaderFactory::make_header(const char* trace_suffix) +{ + std::string trace_id = source_name_; + trace_id += "-"; + + std::array buf{}; + std::snprintf(buf.data(), buf.size(), "%llu", static_cast(counter_++)); + trace_id += buf.data(); + + if (nullptr != trace_suffix && trace_suffix[0] != '\0') + { + trace_id += "-"; + trace_id += trace_suffix; + } + + safe_edge::common::Header header; + header.source(source_name_); + header.timestamp_ms(now_ms()); + header.trace_id(trace_id); + return header; +} + +uint64_t HeaderFactory::now_ms() noexcept +{ + const auto now = std::chrono::system_clock::now(); + const auto since_epoch = now.time_since_epoch(); + return static_cast( + std::chrono::duration_cast(since_epoch).count()); +} + +} // namespace common +} // namespace edge_module +} // namespace safe_edge diff --git a/fast_dds/edge/src/common/RuntimeConfig.cpp b/fast_dds/edge/src/common/RuntimeConfig.cpp new file mode 100644 index 0000000..ee6eb27 --- /dev/null +++ b/fast_dds/edge/src/common/RuntimeConfig.cpp @@ -0,0 +1,21 @@ +#include + +namespace safe_edge { +namespace edge_module { +namespace common { + +RuntimeConfig make_edge_gateway_runtime_config() +{ + RuntimeConfig config; + config.participant_name = "SafeEdgeEdgeGatewayParticipant"; + config.service_name = "edge_gateway"; + config.source_name = "edge_gateway"; + config.domain_id = 0U; + config.participant_port = 8030U; + config.status_interval_sec = 5U; + return config; +} + +} // namespace common +} // namespace edge_module +} // namespace safe_edge diff --git a/fast_dds/edge/src/common/TopicNames.cpp b/fast_dds/edge/src/common/TopicNames.cpp new file mode 100644 index 0000000..dc1a5d4 --- /dev/null +++ b/fast_dds/edge/src/common/TopicNames.cpp @@ -0,0 +1,36 @@ +#include + +namespace safe_edge { +namespace edge_module { +namespace common { +namespace topic_names { + +const char* vehicle_edge_summary() noexcept +{ + return "safe_edge.edge.vehicle_edge_summary"; +} + +const char* energy_advisory() noexcept +{ + return "safe_edge.edge.energy_advisory"; +} + +const char* edge_gateway_status() noexcept +{ + return "safe_edge.edge.edge_gateway_status"; +} + +const char* charger_locations() noexcept +{ + return "safe_edge.pilot_server.charger_locations"; +} + +const char* service_heartbeat() noexcept +{ + return "safe_edge.common.service_heartbeat"; +} + +} // namespace topic_names +} // namespace common +} // namespace edge_module +} // namespace safe_edge diff --git a/fast_dds/edge/src/logic/EdgeAdvisor.cpp b/fast_dds/edge/src/logic/EdgeAdvisor.cpp new file mode 100644 index 0000000..1761832 --- /dev/null +++ b/fast_dds/edge/src/logic/EdgeAdvisor.cpp @@ -0,0 +1,41 @@ +#include + +namespace safe_edge { +namespace edge_module { +namespace logic { + +safe_edge::edge::EnergyAdvisory EdgeAdvisor::evaluate( + const safe_edge::edge::VehicleEdgeSummary& summary, + const safe_edge::pilot_server::ChargerLocation* chargers, + int32_t charger_count) +{ + safe_edge::edge::EnergyAdvisory advisory; + + if (summary.soc_pct() < 20.0F) + { + advisory.suggested_mode(safe_edge::common::PolicyMode::POLICY_LOW_SOC); + advisory.advisory_reason("Low battery -- charge now"); + advisory.recommended_charger_id((charger_count > 0) ? chargers[0].id() : 1); + advisory.target_soc_pct(80.0F); + } + else if (summary.v2g_ready()) + { + advisory.suggested_mode(safe_edge::common::PolicyMode::POLICY_EDGE_AUTONOMOUS); + advisory.advisory_reason("V2G available"); + advisory.recommended_charger_id(0); + advisory.target_soc_pct(90.0F); + } + else + { + advisory.suggested_mode(safe_edge::common::PolicyMode::POLICY_NOMINAL); + advisory.advisory_reason("Normal operation"); + advisory.recommended_charger_id(0); + advisory.target_soc_pct(80.0F); + } + + return advisory; +} + +} // namespace logic +} // namespace edge_module +} // namespace safe_edge diff --git a/fast_dds/edge/src/nodes/EdgeGatewayNode.cpp b/fast_dds/edge/src/nodes/EdgeGatewayNode.cpp new file mode 100644 index 0000000..b453cf6 --- /dev/null +++ b/fast_dds/edge/src/nodes/EdgeGatewayNode.cpp @@ -0,0 +1,467 @@ +#include + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +namespace safe_edge { +namespace edge_module { +namespace nodes { + +namespace { + +bool register_type( + eprosima::fastdds::dds::DomainParticipant* participant, + eprosima::fastdds::dds::TypeSupport& type_support, + const char* label) +{ + if (eprosima::fastdds::dds::RETCODE_OK != type_support.register_type(participant)) + { + std::cerr << "[edge_gateway] Failed to register type: " << label << std::endl; + return false; + } + return true; +} + +eprosima::fastdds::dds::Topic* create_topic( + eprosima::fastdds::dds::DomainParticipant* participant, + const std::string& topic_name, + eprosima::fastdds::dds::TypeSupport& type_support) +{ + eprosima::fastdds::dds::TopicQos topic_qos{}; + return participant->create_topic( + topic_name, + type_support.get_type_name(), + topic_qos, + nullptr, + eprosima::fastdds::dds::StatusMask::none()); +} + +} // namespace + +EdgeGatewayNode::ParticipantListener::ParticipantListener(EdgeGatewayNode& owner) + : owner_(owner) +{ +} + +void EdgeGatewayNode::ParticipantListener::on_subscription_matched( + eprosima::fastdds::dds::DataReader* reader, + const eprosima::fastdds::dds::SubscriptionMatchedStatus& info) noexcept +{ + owner_.log_subscription_match( + reader->get_topicdescription()->get_name().c_str(), info.total_count); +} + +void EdgeGatewayNode::ParticipantListener::on_publication_matched( + eprosima::fastdds::dds::DataWriter* writer, + const eprosima::fastdds::dds::PublicationMatchedStatus& info) noexcept +{ + owner_.log_publication_match( + writer->get_topic()->get_name().c_str(), info.total_count); +} + +EdgeGatewayNode::VehicleEdgeSummaryListener::VehicleEdgeSummaryListener(EdgeGatewayNode& owner) + : owner_(owner) +{ +} + +void EdgeGatewayNode::VehicleEdgeSummaryListener::on_data_available( + eprosima::fastdds::dds::DataReader* reader) noexcept +{ + safe_edge::edge::VehicleEdgeSummary sample{}; + eprosima::fastdds::dds::SampleInfo info{}; + + while (eprosima::fastdds::dds::RETCODE_OK == reader->take_next_sample(&sample, &info)) + { + if (info.valid_data) + { + owner_.on_vehicle_edge_summary_received(sample); + } + } +} + +EdgeGatewayNode::ChargerLocationListener::ChargerLocationListener(EdgeGatewayNode& owner) + : owner_(owner) +{ +} + +void EdgeGatewayNode::ChargerLocationListener::on_data_available( + eprosima::fastdds::dds::DataReader* reader) noexcept +{ + safe_edge::pilot_server::ChargerLocation sample{}; + eprosima::fastdds::dds::SampleInfo info{}; + + while (eprosima::fastdds::dds::RETCODE_OK == reader->take_next_sample(&sample, &info)) + { + if (info.valid_data) + { + owner_.on_charger_location_received(sample); + } + } +} + +EdgeGatewayNode::HeartbeatListener::HeartbeatListener(EdgeGatewayNode& owner) + : owner_(owner) +{ +} + +void EdgeGatewayNode::HeartbeatListener::on_data_available( + eprosima::fastdds::dds::DataReader* reader) noexcept +{ + safe_edge::common::ServiceHeartbeat sample{}; + eprosima::fastdds::dds::SampleInfo info{}; + + while (eprosima::fastdds::dds::RETCODE_OK == reader->take_next_sample(&sample, &info)) + { + if (info.valid_data) + { + owner_.on_server_heartbeat_received(sample); + } + } +} + +EdgeGatewayNode::EdgeGatewayNode(const common::RuntimeConfig& runtime_config) + : runtime_config_(runtime_config) + , header_factory_(runtime_config.source_name) + , participant_listener_(*this) + , vehicle_edge_summary_listener_(*this) + , charger_location_listener_(*this) + , heartbeat_listener_(*this) + , vehicle_edge_summary_type_support_(new safe_edge::edge::VehicleEdgeSummaryPubSubType()) + , energy_advisory_type_support_(new safe_edge::edge::EnergyAdvisoryPubSubType()) + , edge_gateway_status_type_support_(new safe_edge::edge::EdgeGatewayStatusPubSubType()) + , charger_location_type_support_(new safe_edge::pilot_server::ChargerLocationPubSubType()) + , service_heartbeat_type_support_(new safe_edge::common::ServiceHeartbeatPubSubType()) +{ +} + +int EdgeGatewayNode::run() +{ + if (!initialize()) + { + return 1; + } + + next_status_fire_ = std::chrono::steady_clock::now() + + std::chrono::seconds(runtime_config_.status_interval_sec); + + std::cout << "[edge_gateway] [START] Running with participant port " + << runtime_config_.participant_port << std::endl; + + while (true) + { + std::this_thread::sleep_until(next_status_fire_); + publish_edge_gateway_status(); + next_status_fire_ += std::chrono::seconds(runtime_config_.status_interval_sec); + } + + return 0; +} + +bool EdgeGatewayNode::initialize() +{ + return create_participant() && + register_types() && + create_topics() && + create_endpoints() && + enable_entities(); +} + +bool EdgeGatewayNode::create_participant() +{ + eprosima::fastdds::dds::DomainParticipantQos participant_qos{}; + participant_qos.name(runtime_config_.participant_name); + + eprosima::fastdds::rtps::Locator_t locator; + eprosima::fastdds::rtps::IPLocator::setIPv4(locator, "127.0.0.1"); + locator.port = runtime_config_.participant_port; + participant_qos.wire_protocol().builtin.metatrafficUnicastLocatorList.push_back(locator); + + eprosima::fastdds::dds::StatusMask participant_mask = + eprosima::fastdds::dds::StatusMask::publication_matched(); + participant_mask |= eprosima::fastdds::dds::StatusMask::subscription_matched(); + + participant_ = eprosima::fastdds::dds::DomainParticipantFactory::get_instance() + ->create_participant( + runtime_config_.domain_id, + participant_qos, + &participant_listener_, + participant_mask); + + if (nullptr == participant_) + { + std::cerr << "[edge_gateway] Failed to create participant" << std::endl; + return false; + } + + return true; +} + +bool EdgeGatewayNode::register_types() +{ + return register_type(participant_, vehicle_edge_summary_type_support_, "VehicleEdgeSummary") && + register_type(participant_, energy_advisory_type_support_, "EnergyAdvisory") && + register_type(participant_, edge_gateway_status_type_support_, "EdgeGatewayStatus") && + register_type(participant_, charger_location_type_support_, "ChargerLocation") && + register_type(participant_, service_heartbeat_type_support_, "ServiceHeartbeat"); +} + +bool EdgeGatewayNode::create_topics() +{ + vehicle_edge_summary_topic_name_ = common::topic_names::vehicle_edge_summary(); + vehicle_edge_summary_topic_ = create_topic( + participant_, vehicle_edge_summary_topic_name_, vehicle_edge_summary_type_support_); + if (nullptr == vehicle_edge_summary_topic_) + { + std::cerr << "[edge_gateway] Failed to create topic: vehicle_edge_summary" << std::endl; + return false; + } + + energy_advisory_topic_name_ = common::topic_names::energy_advisory(); + energy_advisory_topic_ = create_topic( + participant_, energy_advisory_topic_name_, energy_advisory_type_support_); + if (nullptr == energy_advisory_topic_) + { + std::cerr << "[edge_gateway] Failed to create topic: energy_advisory" << std::endl; + return false; + } + + edge_gateway_status_topic_name_ = common::topic_names::edge_gateway_status(); + edge_gateway_status_topic_ = create_topic( + participant_, edge_gateway_status_topic_name_, edge_gateway_status_type_support_); + if (nullptr == edge_gateway_status_topic_) + { + std::cerr << "[edge_gateway] Failed to create topic: edge_gateway_status" << std::endl; + return false; + } + + charger_location_topic_name_ = common::topic_names::charger_locations(); + charger_location_topic_ = create_topic( + participant_, charger_location_topic_name_, charger_location_type_support_); + if (nullptr == charger_location_topic_) + { + std::cerr << "[edge_gateway] Failed to create topic: charger_locations" << std::endl; + return false; + } + + service_heartbeat_topic_name_ = common::topic_names::service_heartbeat(); + service_heartbeat_topic_ = create_topic( + participant_, service_heartbeat_topic_name_, service_heartbeat_type_support_); + if (nullptr == service_heartbeat_topic_) + { + std::cerr << "[edge_gateway] Failed to create topic: service_heartbeat" << std::endl; + return false; + } + + return true; +} + +bool EdgeGatewayNode::create_endpoints() +{ + eprosima::fastdds::dds::PublisherQos publisher_qos{}; + publisher_ = participant_->create_publisher( + publisher_qos, + nullptr, + eprosima::fastdds::dds::StatusMask::none()); + + eprosima::fastdds::dds::SubscriberQos subscriber_qos{}; + subscriber_ = participant_->create_subscriber( + subscriber_qos, + nullptr, + eprosima::fastdds::dds::StatusMask::none()); + + if (nullptr == publisher_ || nullptr == subscriber_) + { + std::cerr << "[edge_gateway] Failed to create publisher or subscriber" << std::endl; + return false; + } + + eprosima::fastdds::dds::DataWriterQos writer_qos{}; + writer_qos.reliability().kind = eprosima::fastdds::dds::RELIABLE_RELIABILITY_QOS; + + energy_advisory_datawriter_ = publisher_->create_datawriter( + energy_advisory_topic_, + writer_qos, + nullptr, + eprosima::fastdds::dds::StatusMask::none()); + edge_gateway_status_datawriter_ = publisher_->create_datawriter( + edge_gateway_status_topic_, + writer_qos, + nullptr, + eprosima::fastdds::dds::StatusMask::none()); + + eprosima::fastdds::dds::DataReaderQos reader_qos{}; + reader_qos.reliability().kind = eprosima::fastdds::dds::RELIABLE_RELIABILITY_QOS; + + vehicle_edge_summary_datareader_ = subscriber_->create_datareader( + vehicle_edge_summary_topic_, + reader_qos, + &vehicle_edge_summary_listener_, + eprosima::fastdds::dds::StatusMask::data_available()); + charger_location_datareader_ = subscriber_->create_datareader( + charger_location_topic_, + reader_qos, + &charger_location_listener_, + eprosima::fastdds::dds::StatusMask::data_available()); + service_heartbeat_datareader_ = subscriber_->create_datareader( + service_heartbeat_topic_, + reader_qos, + &heartbeat_listener_, + eprosima::fastdds::dds::StatusMask::data_available()); + + const bool success = + nullptr != energy_advisory_datawriter_ && + nullptr != edge_gateway_status_datawriter_ && + nullptr != vehicle_edge_summary_datareader_ && + nullptr != charger_location_datareader_ && + nullptr != service_heartbeat_datareader_; + + if (!success) + { + std::cerr << "[edge_gateway] Failed to create endpoints" << std::endl; + return false; + } + + return true; +} + +bool EdgeGatewayNode::enable_entities() +{ + bool enabled = true; + enabled = enabled && (eprosima::fastdds::dds::RETCODE_OK == publisher_->enable()); + enabled = enabled && (eprosima::fastdds::dds::RETCODE_OK == energy_advisory_datawriter_->enable()); + enabled = enabled && (eprosima::fastdds::dds::RETCODE_OK == edge_gateway_status_datawriter_->enable()); + enabled = enabled && (eprosima::fastdds::dds::RETCODE_OK == subscriber_->enable()); + enabled = enabled && (eprosima::fastdds::dds::RETCODE_OK == vehicle_edge_summary_datareader_->enable()); + enabled = enabled && (eprosima::fastdds::dds::RETCODE_OK == charger_location_datareader_->enable()); + enabled = enabled && (eprosima::fastdds::dds::RETCODE_OK == service_heartbeat_datareader_->enable()); + enabled = enabled && (eprosima::fastdds::dds::RETCODE_OK == participant_->enable()); + + if (!enabled) + { + std::cerr << "[edge_gateway] Failed to enable DDS entities" << std::endl; + } + + return enabled; +} + +void EdgeGatewayNode::on_vehicle_edge_summary_received( + const safe_edge::edge::VehicleEdgeSummary& summary) +{ + std::cout << "[edge_gateway] Received VehicleEdgeSummary soc=" << summary.soc_pct() + << " v2g_ready=" << summary.v2g_ready() + << " mode=" << static_cast(summary.current_mode()) << std::endl; + + safe_edge::edge::EnergyAdvisory advisory = logic::EdgeAdvisor::evaluate( + summary, cached_chargers_, cached_charger_count_); + advisory.header(header_factory_.make_header("energy_advisory")); + publish_energy_advisory(advisory); +} + +void EdgeGatewayNode::on_charger_location_received( + const safe_edge::pilot_server::ChargerLocation& location) +{ + if (cached_charger_count_ < 3) + { + cached_chargers_[cached_charger_count_++] = location; + } + last_server_sync_ms_ = common::HeaderFactory::now_ms(); + + std::cout << "[edge_gateway] Received ChargerLocation id=" << location.id() + << " name=" << location.name() << std::endl; +} + +void EdgeGatewayNode::publish_energy_advisory(const safe_edge::edge::EnergyAdvisory& advisory) +{ + if (eprosima::fastdds::dds::RETCODE_OK != + energy_advisory_datawriter_->write( + const_cast(&advisory), + eprosima::fastdds::dds::HANDLE_NIL)) + { + std::cerr << "[edge_gateway] Failed to publish EnergyAdvisory" << std::endl; + return; + } + + std::cout << "[edge_gateway] Published EnergyAdvisory mode=" + << static_cast(advisory.suggested_mode()) + << " reason=" << advisory.advisory_reason() << std::endl; +} + +void EdgeGatewayNode::on_server_heartbeat_received( + const safe_edge::common::ServiceHeartbeat& heartbeat) +{ + if (heartbeat.service_name() != "server") + { + return; + } + last_server_hb_ms_ = common::HeaderFactory::now_ms(); + server_available_ = true; +} + +void EdgeGatewayNode::publish_edge_gateway_status() +{ + constexpr uint64_t SERVER_HB_TIMEOUT_MS = 10000U; + if (last_server_hb_ms_ > 0U && + (common::HeaderFactory::now_ms() - last_server_hb_ms_) > SERVER_HB_TIMEOUT_MS) + { + server_available_ = false; + } + + safe_edge::edge::EdgeGatewayStatus status; + status.header(header_factory_.make_header("edge_gateway_status")); + status.status(server_available_ + ? safe_edge::common::HealthStatus::HEALTH_OK + : safe_edge::common::HealthStatus::HEALTH_DEGRADED); + status.last_server_sync_ms(last_server_sync_ms_); + status.detail(server_available_ + ? "edge connected, server synced" + : "edge connected, server_down"); + + if (eprosima::fastdds::dds::RETCODE_OK != + edge_gateway_status_datawriter_->write(&status, eprosima::fastdds::dds::HANDLE_NIL)) + { + std::cerr << "[edge_gateway] Failed to publish EdgeGatewayStatus" << std::endl; + return; + } + + std::cout << "[edge_gateway] Published EdgeGatewayStatus status=" + << (server_available_ ? "OK" : "DEGRADED") << std::endl; +} + +void EdgeGatewayNode::log_subscription_match(const char* topic_name, int32_t total_count) const +{ + std::cout << "[edge_gateway] Subscription matched on " << topic_name + << " total_count=" << total_count << std::endl; +} + +void EdgeGatewayNode::log_publication_match(const char* topic_name, int32_t total_count) const +{ + std::cout << "[edge_gateway] Publication matched on " << topic_name + << " total_count=" << total_count << std::endl; +} + +} // namespace nodes +} // namespace edge_module +} // namespace safe_edge diff --git a/fast_dds/edge/test/test_edge_integration.cpp b/fast_dds/edge/test/test_edge_integration.cpp new file mode 100644 index 0000000..5bcbf7b --- /dev/null +++ b/fast_dds/edge/test/test_edge_integration.cpp @@ -0,0 +1,363 @@ +// test_edge_integration.cpp — Fast DDS variant +// +// Integration tests for EdgeGatewayNode health state machine. +// Starts safe_edge_edge_gateway as a subprocess, runs all suites, stops it. +// +// Usage: +// ./test_edge_integration +// ./test_edge_integration --gtest_output=xml:results.xml +// +// Environment variables: +// SAFE_EDGE_FAST_EDGE_BIN path to safe_edge_edge_gateway (default: safe_edge_edge_gateway) + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +// Edge participant port (from RuntimeConfig) +static constexpr uint16_t EDGE_PORT = 8030U; + +// --------------------------------------------------------------------------- +// Helper: participant peered with edge at EDGE_PORT +// --------------------------------------------------------------------------- + +static eprosima::fastdds::dds::DomainParticipant* make_participant( + const char* name, uint16_t port) +{ + eprosima::fastdds::dds::DomainParticipantQos qos{}; + qos.name(name); + + eprosima::fastdds::rtps::Locator_t announced; + eprosima::fastdds::rtps::IPLocator::setIPv4(announced, "127.0.0.1"); + announced.port = port; + qos.wire_protocol().builtin.metatrafficUnicastLocatorList.push_back(announced); + + eprosima::fastdds::rtps::Locator_t peer; + eprosima::fastdds::rtps::IPLocator::setIPv4(peer, "127.0.0.1"); + peer.port = EDGE_PORT; + qos.wire_protocol().builtin.initialPeersList.push_back(peer); + + return eprosima::fastdds::dds::DomainParticipantFactory::get_instance() + ->create_participant(0U, qos, nullptr, + eprosima::fastdds::dds::StatusMask::none()); +} + +// --------------------------------------------------------------------------- +// Global environment: lifecycle of safe_edge_edge_gateway subprocess +// --------------------------------------------------------------------------- + +class EdgeEnvironment : public ::testing::Environment +{ +public: + void SetUp() override + { + const char* bin = std::getenv("SAFE_EDGE_FAST_EDGE_BIN"); + const std::string cmd = + std::string(bin != nullptr ? bin : "safe_edge_edge_gateway") + " &"; + ASSERT_EQ(0, std::system(cmd.c_str())) + << "Failed to launch safe_edge_edge_gateway. " + "Set SAFE_EDGE_FAST_EDGE_BIN to the full path if needed."; + std::cout << "[env] safe_edge_edge_gateway started — waiting 5 s for init...\n"; + std::this_thread::sleep_for(std::chrono::seconds(5)); + std::cout << "[env] Edge ready.\n"; + } + + void TearDown() override + { + std::cout << "[env] Stopping safe_edge_edge_gateway...\n"; + std::system("pkill -f safe_edge_edge_gateway 2>/dev/null || true"); + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + } +}; + +// --------------------------------------------------------------------------- +// Fixture: mock server participant (port 8050, peered with edge at 8030) +// Publishes: ServiceHeartbeat, ChargerLocation +// Reads: EdgeGatewayStatus +// --------------------------------------------------------------------------- + +class MockServerFixture : public ::testing::Test +{ +protected: + void SetUp() override + { + participant_ = make_participant("TestMockServer", 8050U); + ASSERT_NE(nullptr, participant_); + + eprosima::fastdds::dds::TypeSupport hb_ts( + new safe_edge::common::ServiceHeartbeatPubSubType()); + eprosima::fastdds::dds::TypeSupport loc_ts( + new safe_edge::pilot_server::ChargerLocationPubSubType()); + eprosima::fastdds::dds::TypeSupport status_ts( + new safe_edge::edge::EdgeGatewayStatusPubSubType()); + + ASSERT_EQ(eprosima::fastdds::dds::RETCODE_OK, hb_ts.register_type(participant_)); + ASSERT_EQ(eprosima::fastdds::dds::RETCODE_OK, loc_ts.register_type(participant_)); + ASSERT_EQ(eprosima::fastdds::dds::RETCODE_OK, status_ts.register_type(participant_)); + + namespace TN = safe_edge::edge_module::common::topic_names; + hb_topic_ = participant_->create_topic( + TN::service_heartbeat(), hb_ts.get_type_name(), + eprosima::fastdds::dds::TOPIC_QOS_DEFAULT); + loc_topic_ = participant_->create_topic( + TN::charger_locations(), loc_ts.get_type_name(), + eprosima::fastdds::dds::TOPIC_QOS_DEFAULT); + status_topic_ = participant_->create_topic( + TN::edge_gateway_status(), status_ts.get_type_name(), + eprosima::fastdds::dds::TOPIC_QOS_DEFAULT); + ASSERT_NE(nullptr, hb_topic_); + ASSERT_NE(nullptr, loc_topic_); + ASSERT_NE(nullptr, status_topic_); + + publisher_ = participant_->create_publisher( + eprosima::fastdds::dds::PUBLISHER_QOS_DEFAULT, nullptr, + eprosima::fastdds::dds::StatusMask::none()); + subscriber_ = participant_->create_subscriber( + eprosima::fastdds::dds::SUBSCRIBER_QOS_DEFAULT, nullptr, + eprosima::fastdds::dds::StatusMask::none()); + ASSERT_NE(nullptr, publisher_); + ASSERT_NE(nullptr, subscriber_); + + eprosima::fastdds::dds::DataWriterQos wqos = + eprosima::fastdds::dds::DATAWRITER_QOS_DEFAULT; + wqos.reliability().kind = eprosima::fastdds::dds::RELIABLE_RELIABILITY_QOS; + eprosima::fastdds::dds::DataReaderQos rqos = + eprosima::fastdds::dds::DATAREADER_QOS_DEFAULT; + rqos.reliability().kind = eprosima::fastdds::dds::RELIABLE_RELIABILITY_QOS; + + hb_writer_ = publisher_->create_datawriter( + hb_topic_, wqos, nullptr, eprosima::fastdds::dds::StatusMask::none()); + loc_writer_ = publisher_->create_datawriter( + loc_topic_, wqos, nullptr, eprosima::fastdds::dds::StatusMask::none()); + status_reader_ = subscriber_->create_datareader( + status_topic_, rqos, nullptr, eprosima::fastdds::dds::StatusMask::none()); + ASSERT_NE(nullptr, hb_writer_); + ASSERT_NE(nullptr, loc_writer_); + ASSERT_NE(nullptr, status_reader_); + + std::this_thread::sleep_for(std::chrono::seconds(3)); // discovery + } + + void TearDown() override + { + if (participant_ != nullptr) + { + participant_->delete_contained_entities(); + eprosima::fastdds::dds::DomainParticipantFactory::get_instance() + ->delete_participant(participant_); + participant_ = nullptr; + } + } + + void send_heartbeat() + { + safe_edge::common::ServiceHeartbeat hb{}; + hb.service_name("server"); + EXPECT_EQ(eprosima::fastdds::dds::RETCODE_OK, + hb_writer_->write(&hb, eprosima::fastdds::dds::HANDLE_NIL)); + } + + bool wait_for_status(safe_edge::common::HealthStatus expected, int timeout_s) + { + const auto deadline = + std::chrono::steady_clock::now() + std::chrono::seconds(timeout_s); + while (std::chrono::steady_clock::now() < deadline) + { + safe_edge::edge::EdgeGatewayStatus sample{}; + eprosima::fastdds::dds::SampleInfo info{}; + if (status_reader_->take_next_sample(&sample, &info) == + eprosima::fastdds::dds::RETCODE_OK && info.valid_data) + { + const bool is_ok = + sample.status() == safe_edge::common::HealthStatus::HEALTH_OK; + std::cout << "[dds] EdgeGatewayStatus=" + << (is_ok ? "OK" : "DEGRADED") << "\n"; + if (sample.status() == expected) + { + return true; + } + } + std::this_thread::sleep_for(std::chrono::milliseconds(200)); + } + return false; + } + + eprosima::fastdds::dds::DomainParticipant* participant_ = nullptr; + eprosima::fastdds::dds::Publisher* publisher_ = nullptr; + eprosima::fastdds::dds::Subscriber* subscriber_ = nullptr; + eprosima::fastdds::dds::Topic* hb_topic_ = nullptr; + eprosima::fastdds::dds::Topic* loc_topic_ = nullptr; + eprosima::fastdds::dds::Topic* status_topic_ = nullptr; + eprosima::fastdds::dds::DataWriter* hb_writer_ = nullptr; + eprosima::fastdds::dds::DataWriter* loc_writer_ = nullptr; + eprosima::fastdds::dds::DataReader* status_reader_= nullptr; +}; + +// --------------------------------------------------------------------------- +// 1. DEGRADED when no server present +// --------------------------------------------------------------------------- + +TEST_F(MockServerFixture, EdgeStatusIsDegradedWithoutServer) +{ + // server_available_ starts false → first status (≤5 s) is DEGRADED + EXPECT_TRUE(wait_for_status(safe_edge::common::HealthStatus::HEALTH_DEGRADED, 12)) + << "Expected DEGRADED within 12 s with no server heartbeat"; +} + +// --------------------------------------------------------------------------- +// 2. OK when server publishes heartbeats +// --------------------------------------------------------------------------- + +TEST_F(MockServerFixture, EdgeStatusIsOkWithServer) +{ + for (int i = 0; i < 3; ++i) + { + send_heartbeat(); + std::this_thread::sleep_for(std::chrono::seconds(2)); + } + EXPECT_TRUE(wait_for_status(safe_edge::common::HealthStatus::HEALTH_OK, 12)) + << "Expected OK within 12 s after sending heartbeats"; +} + +// --------------------------------------------------------------------------- +// 3. Recovers from DEGRADED to OK when server starts +// --------------------------------------------------------------------------- + +TEST_F(MockServerFixture, EdgeRecoversDegradedToOk) +{ + ASSERT_TRUE(wait_for_status(safe_edge::common::HealthStatus::HEALTH_DEGRADED, 12)) + << "Expected initial DEGRADED state"; + + for (int i = 0; i < 3; ++i) + { + send_heartbeat(); + std::this_thread::sleep_for(std::chrono::seconds(2)); + } + EXPECT_TRUE(wait_for_status(safe_edge::common::HealthStatus::HEALTH_OK, 12)) + << "Expected OK after heartbeats sent"; +} + +// --------------------------------------------------------------------------- +// 4. Transitions from OK to DEGRADED when server stops +// --------------------------------------------------------------------------- + +TEST_F(MockServerFixture, EdgeTransitionsOkToDegraded) +{ + std::atomic hb_running{true}; + std::thread hb_thread([&]() + { + while (hb_running.load()) + { + send_heartbeat(); + std::this_thread::sleep_for(std::chrono::seconds(2)); + } + }); + + ASSERT_TRUE(wait_for_status(safe_edge::common::HealthStatus::HEALTH_OK, 12)) + << "Expected OK while heartbeats are running"; + + // Stop heartbeats — DEGRADED after SERVER_HB_TIMEOUT_MS (10 s) + + // next status interval (≤5 s) → allow 20 s + hb_running.store(false); + hb_thread.join(); + + EXPECT_TRUE(wait_for_status(safe_edge::common::HealthStatus::HEALTH_DEGRADED, 20)) + << "Expected DEGRADED within 20 s after heartbeats stopped"; +} + +// --------------------------------------------------------------------------- +// 5. Status published periodically (status_interval_sec = 5) +// --------------------------------------------------------------------------- + +TEST(EdgePublishesStatusPeriodically, AtLeastTwoSamplesIn15Seconds) +{ + auto* participant = make_participant("TestPeriodic", 8051U); + ASSERT_NE(nullptr, participant); + + eprosima::fastdds::dds::TypeSupport status_ts( + new safe_edge::edge::EdgeGatewayStatusPubSubType()); + ASSERT_EQ(eprosima::fastdds::dds::RETCODE_OK, status_ts.register_type(participant)); + + auto* topic = participant->create_topic( + safe_edge::edge_module::common::topic_names::edge_gateway_status(), + status_ts.get_type_name(), + eprosima::fastdds::dds::TOPIC_QOS_DEFAULT); + ASSERT_NE(nullptr, topic); + + auto* sub = participant->create_subscriber( + eprosima::fastdds::dds::SUBSCRIBER_QOS_DEFAULT, nullptr, + eprosima::fastdds::dds::StatusMask::none()); + ASSERT_NE(nullptr, sub); + + eprosima::fastdds::dds::DataReaderQos rqos = + eprosima::fastdds::dds::DATAREADER_QOS_DEFAULT; + rqos.reliability().kind = eprosima::fastdds::dds::RELIABLE_RELIABILITY_QOS; + auto* reader = sub->create_datareader( + topic, rqos, nullptr, eprosima::fastdds::dds::StatusMask::none()); + ASSERT_NE(nullptr, reader); + + std::this_thread::sleep_for(std::chrono::seconds(3)); // discovery + + int count = 0; + const auto end = std::chrono::steady_clock::now() + std::chrono::seconds(15); + while (std::chrono::steady_clock::now() < end) + { + safe_edge::edge::EdgeGatewayStatus sample{}; + eprosima::fastdds::dds::SampleInfo info{}; + if (reader->take_next_sample(&sample, &info) == + eprosima::fastdds::dds::RETCODE_OK && info.valid_data) + { + ++count; + std::cout << "[dds] Status sample #" << count << "\n"; + } + else + { + std::this_thread::sleep_for(std::chrono::milliseconds(200)); + } + } + + EXPECT_GE(count, 2) + << "Expected >=2 EdgeGatewayStatus samples in 15 s, got " << count; +} + +// --------------------------------------------------------------------------- +// main +// --------------------------------------------------------------------------- + +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + ::testing::AddGlobalTestEnvironment(new EdgeEnvironment()); + return RUN_ALL_TESTS(); +} diff --git a/fast_dds/idl/common.hpp b/fast_dds/idl/common.hpp new file mode 100644 index 0000000..a331aaa --- /dev/null +++ b/fast_dds/idl/common.hpp @@ -0,0 +1,730 @@ +// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/*! + * @file common.hpp + * This header file contains the declaration of the described types in the IDL file. + * + * This file was generated by the tool fastddsgen (version: 4.3.0). + */ + +#ifndef FAST_DDS_GENERATED__SAFE_EDGE_COMMON_COMMON_HPP +#define FAST_DDS_GENERATED__SAFE_EDGE_COMMON_COMMON_HPP + +#include +#include +#include +#include + +#if defined(_WIN32) +#if defined(EPROSIMA_USER_DLL_EXPORT) +#define eProsima_user_DllExport __declspec( dllexport ) +#else +#define eProsima_user_DllExport +#endif // EPROSIMA_USER_DLL_EXPORT +#else +#define eProsima_user_DllExport +#endif // _WIN32 + +#if defined(_WIN32) +#if defined(EPROSIMA_USER_DLL_EXPORT) +#if defined(COMMON_SOURCE) +#define COMMON_DllAPI __declspec( dllexport ) +#else +#define COMMON_DllAPI __declspec( dllimport ) +#endif // COMMON_SOURCE +#else +#define COMMON_DllAPI +#endif // EPROSIMA_USER_DLL_EXPORT +#else +#define COMMON_DllAPI +#endif // _WIN32 + +namespace safe_edge { + +namespace common { + +/*! + * @brief This class represents the structure Header defined by the user in the IDL file. + * @ingroup common + */ +class Header +{ +public: + + /*! + * @brief Default constructor. + */ + eProsima_user_DllExport Header() + { + } + + /*! + * @brief Default destructor. + */ + eProsima_user_DllExport ~Header() + { + } + + /*! + * @brief Copy constructor. + * @param x Reference to the object Header that will be copied. + */ + eProsima_user_DllExport Header( + const Header& x) + { + m_source = x.m_source; + + m_timestamp_ms = x.m_timestamp_ms; + + m_trace_id = x.m_trace_id; + + } + + /*! + * @brief Move constructor. + * @param x Reference to the object Header that will be copied. + */ + eProsima_user_DllExport Header( + Header&& x) noexcept + { + m_source = std::move(x.m_source); + m_timestamp_ms = x.m_timestamp_ms; + m_trace_id = std::move(x.m_trace_id); + } + + /*! + * @brief Copy assignment. + * @param x Reference to the object Header that will be copied. + */ + eProsima_user_DllExport Header& operator =( + const Header& x) + { + + m_source = x.m_source; + + m_timestamp_ms = x.m_timestamp_ms; + + m_trace_id = x.m_trace_id; + + return *this; + } + + /*! + * @brief Move assignment. + * @param x Reference to the object Header that will be copied. + */ + eProsima_user_DllExport Header& operator =( + Header&& x) noexcept + { + + m_source = std::move(x.m_source); + m_timestamp_ms = x.m_timestamp_ms; + m_trace_id = std::move(x.m_trace_id); + return *this; + } + + /*! + * @brief Comparison operator. + * @param x Header object to compare. + */ + eProsima_user_DllExport bool operator ==( + const Header& x) const + { + return (m_source == x.m_source && + m_timestamp_ms == x.m_timestamp_ms && + m_trace_id == x.m_trace_id); + } + + /*! + * @brief Comparison operator. + * @param x Header object to compare. + */ + eProsima_user_DllExport bool operator !=( + const Header& x) const + { + return !(*this == x); + } + + /*! + * @brief This function copies the value in member source + * @param _source New value to be copied in member source + */ + eProsima_user_DllExport void source( + const std::string& _source) + { + m_source = _source; + } + + /*! + * @brief This function moves the value in member source + * @param _source New value to be moved in member source + */ + eProsima_user_DllExport void source( + std::string&& _source) + { + m_source = std::move(_source); + } + + /*! + * @brief This function returns a constant reference to member source + * @return Constant reference to member source + */ + eProsima_user_DllExport const std::string& source() const + { + return m_source; + } + + /*! + * @brief This function returns a reference to member source + * @return Reference to member source + */ + eProsima_user_DllExport std::string& source() + { + return m_source; + } + + + /*! + * @brief This function sets a value in member timestamp_ms + * @param _timestamp_ms New value for member timestamp_ms + */ + eProsima_user_DllExport void timestamp_ms( + uint64_t _timestamp_ms) + { + m_timestamp_ms = _timestamp_ms; + } + + /*! + * @brief This function returns the value of member timestamp_ms + * @return Value of member timestamp_ms + */ + eProsima_user_DllExport uint64_t timestamp_ms() const + { + return m_timestamp_ms; + } + + /*! + * @brief This function returns a reference to member timestamp_ms + * @return Reference to member timestamp_ms + */ + eProsima_user_DllExport uint64_t& timestamp_ms() + { + return m_timestamp_ms; + } + + + /*! + * @brief This function copies the value in member trace_id + * @param _trace_id New value to be copied in member trace_id + */ + eProsima_user_DllExport void trace_id( + const std::string& _trace_id) + { + m_trace_id = _trace_id; + } + + /*! + * @brief This function moves the value in member trace_id + * @param _trace_id New value to be moved in member trace_id + */ + eProsima_user_DllExport void trace_id( + std::string&& _trace_id) + { + m_trace_id = std::move(_trace_id); + } + + /*! + * @brief This function returns a constant reference to member trace_id + * @return Constant reference to member trace_id + */ + eProsima_user_DllExport const std::string& trace_id() const + { + return m_trace_id; + } + + /*! + * @brief This function returns a reference to member trace_id + * @return Reference to member trace_id + */ + eProsima_user_DllExport std::string& trace_id() + { + return m_trace_id; + } + + + +private: + + std::string m_source; + uint64_t m_timestamp_ms{0}; + std::string m_trace_id; + +}; +/*! + * @brief This class represents the structure GeoPoint defined by the user in the IDL file. + * @ingroup common + */ +class GeoPoint +{ +public: + + /*! + * @brief Default constructor. + */ + eProsima_user_DllExport GeoPoint() + { + } + + /*! + * @brief Default destructor. + */ + eProsima_user_DllExport ~GeoPoint() + { + } + + /*! + * @brief Copy constructor. + * @param x Reference to the object GeoPoint that will be copied. + */ + eProsima_user_DllExport GeoPoint( + const GeoPoint& x) + { + m_latitude = x.m_latitude; + + m_longitude = x.m_longitude; + + } + + /*! + * @brief Move constructor. + * @param x Reference to the object GeoPoint that will be copied. + */ + eProsima_user_DllExport GeoPoint( + GeoPoint&& x) noexcept + { + m_latitude = x.m_latitude; + m_longitude = x.m_longitude; + } + + /*! + * @brief Copy assignment. + * @param x Reference to the object GeoPoint that will be copied. + */ + eProsima_user_DllExport GeoPoint& operator =( + const GeoPoint& x) + { + + m_latitude = x.m_latitude; + + m_longitude = x.m_longitude; + + return *this; + } + + /*! + * @brief Move assignment. + * @param x Reference to the object GeoPoint that will be copied. + */ + eProsima_user_DllExport GeoPoint& operator =( + GeoPoint&& x) noexcept + { + + m_latitude = x.m_latitude; + m_longitude = x.m_longitude; + return *this; + } + + /*! + * @brief Comparison operator. + * @param x GeoPoint object to compare. + */ + eProsima_user_DllExport bool operator ==( + const GeoPoint& x) const + { + return (m_latitude == x.m_latitude && + m_longitude == x.m_longitude); + } + + /*! + * @brief Comparison operator. + * @param x GeoPoint object to compare. + */ + eProsima_user_DllExport bool operator !=( + const GeoPoint& x) const + { + return !(*this == x); + } + + /*! + * @brief This function sets a value in member latitude + * @param _latitude New value for member latitude + */ + eProsima_user_DllExport void latitude( + double _latitude) + { + m_latitude = _latitude; + } + + /*! + * @brief This function returns the value of member latitude + * @return Value of member latitude + */ + eProsima_user_DllExport double latitude() const + { + return m_latitude; + } + + /*! + * @brief This function returns a reference to member latitude + * @return Reference to member latitude + */ + eProsima_user_DllExport double& latitude() + { + return m_latitude; + } + + + /*! + * @brief This function sets a value in member longitude + * @param _longitude New value for member longitude + */ + eProsima_user_DllExport void longitude( + double _longitude) + { + m_longitude = _longitude; + } + + /*! + * @brief This function returns the value of member longitude + * @return Value of member longitude + */ + eProsima_user_DllExport double longitude() const + { + return m_longitude; + } + + /*! + * @brief This function returns a reference to member longitude + * @return Reference to member longitude + */ + eProsima_user_DllExport double& longitude() + { + return m_longitude; + } + + + +private: + + double m_latitude{0.0}; + double m_longitude{0.0}; + +}; +/*! + * @brief This class represents the enumeration HealthStatus defined by the user in the IDL file. + * @ingroup common + */ +enum class HealthStatus : int32_t +{ + HEALTH_UNKNOWN, + HEALTH_OK, + HEALTH_DEGRADED, + HEALTH_ERROR +}; +/*! + * @brief This class represents the structure ServiceHeartbeat defined by the user in the IDL file. + * @ingroup common + */ +class ServiceHeartbeat +{ +public: + + /*! + * @brief Default constructor. + */ + eProsima_user_DllExport ServiceHeartbeat() + { + } + + /*! + * @brief Default destructor. + */ + eProsima_user_DllExport ~ServiceHeartbeat() + { + } + + /*! + * @brief Copy constructor. + * @param x Reference to the object ServiceHeartbeat that will be copied. + */ + eProsima_user_DllExport ServiceHeartbeat( + const ServiceHeartbeat& x) + { + m_header_st = x.m_header_st; + + m_service_name = x.m_service_name; + + m_status = x.m_status; + + m_detail = x.m_detail; + + } + + /*! + * @brief Move constructor. + * @param x Reference to the object ServiceHeartbeat that will be copied. + */ + eProsima_user_DllExport ServiceHeartbeat( + ServiceHeartbeat&& x) noexcept + { + m_header_st = std::move(x.m_header_st); + m_service_name = std::move(x.m_service_name); + m_status = x.m_status; + m_detail = std::move(x.m_detail); + } + + /*! + * @brief Copy assignment. + * @param x Reference to the object ServiceHeartbeat that will be copied. + */ + eProsima_user_DllExport ServiceHeartbeat& operator =( + const ServiceHeartbeat& x) + { + + m_header_st = x.m_header_st; + + m_service_name = x.m_service_name; + + m_status = x.m_status; + + m_detail = x.m_detail; + + return *this; + } + + /*! + * @brief Move assignment. + * @param x Reference to the object ServiceHeartbeat that will be copied. + */ + eProsima_user_DllExport ServiceHeartbeat& operator =( + ServiceHeartbeat&& x) noexcept + { + + m_header_st = std::move(x.m_header_st); + m_service_name = std::move(x.m_service_name); + m_status = x.m_status; + m_detail = std::move(x.m_detail); + return *this; + } + + /*! + * @brief Comparison operator. + * @param x ServiceHeartbeat object to compare. + */ + eProsima_user_DllExport bool operator ==( + const ServiceHeartbeat& x) const + { + return (m_header_st == x.m_header_st && + m_service_name == x.m_service_name && + m_status == x.m_status && + m_detail == x.m_detail); + } + + /*! + * @brief Comparison operator. + * @param x ServiceHeartbeat object to compare. + */ + eProsima_user_DllExport bool operator !=( + const ServiceHeartbeat& x) const + { + return !(*this == x); + } + + /*! + * @brief This function copies the value in member header_st + * @param _header_st New value to be copied in member header_st + */ + eProsima_user_DllExport void header_st( + const Header& _header_st) + { + m_header_st = _header_st; + } + + /*! + * @brief This function moves the value in member header_st + * @param _header_st New value to be moved in member header_st + */ + eProsima_user_DllExport void header_st( + Header&& _header_st) + { + m_header_st = std::move(_header_st); + } + + /*! + * @brief This function returns a constant reference to member header_st + * @return Constant reference to member header_st + */ + eProsima_user_DllExport const Header& header_st() const + { + return m_header_st; + } + + /*! + * @brief This function returns a reference to member header_st + * @return Reference to member header_st + */ + eProsima_user_DllExport Header& header_st() + { + return m_header_st; + } + + + /*! + * @brief This function copies the value in member service_name + * @param _service_name New value to be copied in member service_name + */ + eProsima_user_DllExport void service_name( + const std::string& _service_name) + { + m_service_name = _service_name; + } + + /*! + * @brief This function moves the value in member service_name + * @param _service_name New value to be moved in member service_name + */ + eProsima_user_DllExport void service_name( + std::string&& _service_name) + { + m_service_name = std::move(_service_name); + } + + /*! + * @brief This function returns a constant reference to member service_name + * @return Constant reference to member service_name + */ + eProsima_user_DllExport const std::string& service_name() const + { + return m_service_name; + } + + /*! + * @brief This function returns a reference to member service_name + * @return Reference to member service_name + */ + eProsima_user_DllExport std::string& service_name() + { + return m_service_name; + } + + + /*! + * @brief This function sets a value in member status + * @param _status New value for member status + */ + eProsima_user_DllExport void status( + HealthStatus _status) + { + m_status = _status; + } + + /*! + * @brief This function returns the value of member status + * @return Value of member status + */ + eProsima_user_DllExport HealthStatus status() const + { + return m_status; + } + + /*! + * @brief This function returns a reference to member status + * @return Reference to member status + */ + eProsima_user_DllExport HealthStatus& status() + { + return m_status; + } + + + /*! + * @brief This function copies the value in member detail + * @param _detail New value to be copied in member detail + */ + eProsima_user_DllExport void detail( + const std::string& _detail) + { + m_detail = _detail; + } + + /*! + * @brief This function moves the value in member detail + * @param _detail New value to be moved in member detail + */ + eProsima_user_DllExport void detail( + std::string&& _detail) + { + m_detail = std::move(_detail); + } + + /*! + * @brief This function returns a constant reference to member detail + * @return Constant reference to member detail + */ + eProsima_user_DllExport const std::string& detail() const + { + return m_detail; + } + + /*! + * @brief This function returns a reference to member detail + * @return Reference to member detail + */ + eProsima_user_DllExport std::string& detail() + { + return m_detail; + } + + + +private: + + Header m_header_st; + std::string m_service_name; + HealthStatus m_status{HealthStatus::HEALTH_UNKNOWN}; + std::string m_detail; + +}; +/*! + * @brief This class represents the enumeration PolicyMode defined by the user in the IDL file. + * @ingroup common + */ +enum class PolicyMode : int32_t +{ + POLICY_UNKNOWN, + POLICY_NOMINAL, + POLICY_LOW_SOC, + POLICY_EDGE_AUTONOMOUS, + POLICY_DEGRADED_SERVER_DOWN, + POLICY_DEGRADED_COMPLETE +}; + +} // namespace common + +} // namespace safe_edge + +#endif // _FAST_DDS_GENERATED_SAFE_EDGE_COMMON_COMMON_HPP_ + + diff --git a/fast_dds/idl/commonCdrAux.hpp b/fast_dds/idl/commonCdrAux.hpp new file mode 100644 index 0000000..444271f --- /dev/null +++ b/fast_dds/idl/commonCdrAux.hpp @@ -0,0 +1,62 @@ +// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/*! + * @file commonCdrAux.hpp + * This source file contains some definitions of CDR related functions. + * + * This file was generated by the tool fastddsgen (version: 4.3.0). + */ + +#ifndef FAST_DDS_GENERATED__SAFE_EDGE_COMMON_COMMONCDRAUX_HPP +#define FAST_DDS_GENERATED__SAFE_EDGE_COMMON_COMMONCDRAUX_HPP + +#include "common.hpp" + +constexpr uint32_t safe_edge_common_ServiceHeartbeat_max_cdr_typesize {1064UL}; +constexpr uint32_t safe_edge_common_ServiceHeartbeat_max_key_cdr_typesize {0UL}; + +constexpr uint32_t safe_edge_common_GeoPoint_max_cdr_typesize {24UL}; +constexpr uint32_t safe_edge_common_GeoPoint_max_key_cdr_typesize {0UL}; + +constexpr uint32_t safe_edge_common_Header_max_cdr_typesize {532UL}; +constexpr uint32_t safe_edge_common_Header_max_key_cdr_typesize {0UL}; + + + + +namespace eprosima { +namespace fastcdr { + +class Cdr; +class CdrSizeCalculator; + +eProsima_user_DllExport void serialize_key( + eprosima::fastcdr::Cdr& scdr, + const safe_edge::common::Header& data); + +eProsima_user_DllExport void serialize_key( + eprosima::fastcdr::Cdr& scdr, + const safe_edge::common::GeoPoint& data); + +eProsima_user_DllExport void serialize_key( + eprosima::fastcdr::Cdr& scdr, + const safe_edge::common::ServiceHeartbeat& data); + + +} // namespace fastcdr +} // namespace eprosima + +#endif // FAST_DDS_GENERATED__SAFE_EDGE_COMMON_COMMONCDRAUX_HPP + diff --git a/fast_dds/idl/commonCdrAux.ipp b/fast_dds/idl/commonCdrAux.ipp new file mode 100644 index 0000000..6fe9e60 --- /dev/null +++ b/fast_dds/idl/commonCdrAux.ipp @@ -0,0 +1,367 @@ +// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/*! + * @file commonCdrAux.ipp + * This source file contains some declarations of CDR related functions. + * + * This file was generated by the tool fastddsgen (version: 4.3.0). + */ + +#ifndef FAST_DDS_GENERATED__SAFE_EDGE_COMMON_COMMONCDRAUX_IPP +#define FAST_DDS_GENERATED__SAFE_EDGE_COMMON_COMMONCDRAUX_IPP + +#include "commonCdrAux.hpp" + +#include +#include + + +#include +using namespace eprosima::fastcdr::exception; + +namespace eprosima { +namespace fastcdr { + +template<> +eProsima_user_DllExport size_t calculate_serialized_size( + eprosima::fastcdr::CdrSizeCalculator& calculator, + const safe_edge::common::Header& data, + size_t& current_alignment) +{ + using namespace safe_edge::common; + + static_cast(data); + + eprosima::fastcdr::EncodingAlgorithmFlag previous_encoding = calculator.get_encoding(); + size_t calculated_size {calculator.begin_calculate_type_serialized_size( + eprosima::fastcdr::CdrVersion::XCDRv2 == calculator.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, + current_alignment)}; + + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(0), + data.source(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(1), + data.timestamp_ms(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(2), + data.trace_id(), current_alignment); + + + calculated_size += calculator.end_calculate_type_serialized_size(previous_encoding, current_alignment); + + return calculated_size; +} + +template<> +eProsima_user_DllExport void serialize( + eprosima::fastcdr::Cdr& scdr, + const safe_edge::common::Header& data) +{ + using namespace safe_edge::common; + + eprosima::fastcdr::Cdr::state current_state(scdr); + scdr.begin_serialize_type(current_state, + eprosima::fastcdr::CdrVersion::XCDRv2 == scdr.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR); + + scdr + << eprosima::fastcdr::MemberId(0) << data.source() + << eprosima::fastcdr::MemberId(1) << data.timestamp_ms() + << eprosima::fastcdr::MemberId(2) << data.trace_id() +; + scdr.end_serialize_type(current_state); +} + +template<> +eProsima_user_DllExport void deserialize( + eprosima::fastcdr::Cdr& cdr, + safe_edge::common::Header& data) +{ + using namespace safe_edge::common; + + cdr.deserialize_type(eprosima::fastcdr::CdrVersion::XCDRv2 == cdr.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, + [&data](eprosima::fastcdr::Cdr& dcdr, const eprosima::fastcdr::MemberId& mid) -> bool + { + bool ret_value = true; + switch (mid.id) + { + case 0: + dcdr >> data.source(); + break; + + case 1: + dcdr >> data.timestamp_ms(); + break; + + case 2: + dcdr >> data.trace_id(); + break; + + default: + ret_value = false; + break; + } + return ret_value; + }); +} + +void serialize_key( + eprosima::fastcdr::Cdr& scdr, + const safe_edge::common::Header& data) +{ + using namespace safe_edge::common; + + static_cast(scdr); + static_cast(data); + scdr << data.source(); + + scdr << data.timestamp_ms(); + + scdr << data.trace_id(); + +} + + +template<> +eProsima_user_DllExport size_t calculate_serialized_size( + eprosima::fastcdr::CdrSizeCalculator& calculator, + const safe_edge::common::GeoPoint& data, + size_t& current_alignment) +{ + using namespace safe_edge::common; + + static_cast(data); + + eprosima::fastcdr::EncodingAlgorithmFlag previous_encoding = calculator.get_encoding(); + size_t calculated_size {calculator.begin_calculate_type_serialized_size( + eprosima::fastcdr::CdrVersion::XCDRv2 == calculator.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, + current_alignment)}; + + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(0), + data.latitude(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(1), + data.longitude(), current_alignment); + + + calculated_size += calculator.end_calculate_type_serialized_size(previous_encoding, current_alignment); + + return calculated_size; +} + +template<> +eProsima_user_DllExport void serialize( + eprosima::fastcdr::Cdr& scdr, + const safe_edge::common::GeoPoint& data) +{ + using namespace safe_edge::common; + + eprosima::fastcdr::Cdr::state current_state(scdr); + scdr.begin_serialize_type(current_state, + eprosima::fastcdr::CdrVersion::XCDRv2 == scdr.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR); + + scdr + << eprosima::fastcdr::MemberId(0) << data.latitude() + << eprosima::fastcdr::MemberId(1) << data.longitude() +; + scdr.end_serialize_type(current_state); +} + +template<> +eProsima_user_DllExport void deserialize( + eprosima::fastcdr::Cdr& cdr, + safe_edge::common::GeoPoint& data) +{ + using namespace safe_edge::common; + + cdr.deserialize_type(eprosima::fastcdr::CdrVersion::XCDRv2 == cdr.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, + [&data](eprosima::fastcdr::Cdr& dcdr, const eprosima::fastcdr::MemberId& mid) -> bool + { + bool ret_value = true; + switch (mid.id) + { + case 0: + dcdr >> data.latitude(); + break; + + case 1: + dcdr >> data.longitude(); + break; + + default: + ret_value = false; + break; + } + return ret_value; + }); +} + +void serialize_key( + eprosima::fastcdr::Cdr& scdr, + const safe_edge::common::GeoPoint& data) +{ + using namespace safe_edge::common; + + static_cast(scdr); + static_cast(data); + scdr << data.latitude(); + + scdr << data.longitude(); + +} + + +template<> +eProsima_user_DllExport size_t calculate_serialized_size( + eprosima::fastcdr::CdrSizeCalculator& calculator, + const safe_edge::common::ServiceHeartbeat& data, + size_t& current_alignment) +{ + using namespace safe_edge::common; + + static_cast(data); + + eprosima::fastcdr::EncodingAlgorithmFlag previous_encoding = calculator.get_encoding(); + size_t calculated_size {calculator.begin_calculate_type_serialized_size( + eprosima::fastcdr::CdrVersion::XCDRv2 == calculator.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, + current_alignment)}; + + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(0), + data.header_st(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(1), + data.service_name(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(2), + data.status(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(3), + data.detail(), current_alignment); + + + calculated_size += calculator.end_calculate_type_serialized_size(previous_encoding, current_alignment); + + return calculated_size; +} + +template<> +eProsima_user_DllExport void serialize( + eprosima::fastcdr::Cdr& scdr, + const safe_edge::common::ServiceHeartbeat& data) +{ + using namespace safe_edge::common; + + eprosima::fastcdr::Cdr::state current_state(scdr); + scdr.begin_serialize_type(current_state, + eprosima::fastcdr::CdrVersion::XCDRv2 == scdr.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR); + + scdr + << eprosima::fastcdr::MemberId(0) << data.header_st() + << eprosima::fastcdr::MemberId(1) << data.service_name() + << eprosima::fastcdr::MemberId(2) << data.status() + << eprosima::fastcdr::MemberId(3) << data.detail() +; + scdr.end_serialize_type(current_state); +} + +template<> +eProsima_user_DllExport void deserialize( + eprosima::fastcdr::Cdr& cdr, + safe_edge::common::ServiceHeartbeat& data) +{ + using namespace safe_edge::common; + + cdr.deserialize_type(eprosima::fastcdr::CdrVersion::XCDRv2 == cdr.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, + [&data](eprosima::fastcdr::Cdr& dcdr, const eprosima::fastcdr::MemberId& mid) -> bool + { + bool ret_value = true; + switch (mid.id) + { + case 0: + dcdr >> data.header_st(); + break; + + case 1: + dcdr >> data.service_name(); + break; + + case 2: + dcdr >> data.status(); + break; + + case 3: + dcdr >> data.detail(); + break; + + default: + ret_value = false; + break; + } + return ret_value; + }); +} + +void serialize_key( + eprosima::fastcdr::Cdr& scdr, + const safe_edge::common::ServiceHeartbeat& data) +{ + using namespace safe_edge::common; + extern void serialize_key( + Cdr& scdr, + const safe_edge::common::Header& data); + + + + + + static_cast(scdr); + static_cast(data); + serialize_key(scdr, data.header_st()); + + scdr << data.service_name(); + + scdr << data.status(); + + scdr << data.detail(); + +} + + + +} // namespace fastcdr +} // namespace eprosima + +#endif // FAST_DDS_GENERATED__SAFE_EDGE_COMMON_COMMONCDRAUX_IPP + diff --git a/fast_dds/idl/commonPubSubTypes.cxx b/fast_dds/idl/commonPubSubTypes.cxx new file mode 100644 index 0000000..17eb4b6 --- /dev/null +++ b/fast_dds/idl/commonPubSubTypes.cxx @@ -0,0 +1,474 @@ +// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/*! + * @file commonPubSubTypes.cpp + * This header file contains the implementation of the serialization functions. + * + * This file was generated by the tool fastddsgen (version: 4.3.0). + */ + +#include "commonPubSubTypes.hpp" + +#include +#include + +#include +#include + +#include "commonCdrAux.hpp" +#include "commonTypeObjectSupport.hpp" + +using SerializedPayload_t = eprosima::fastdds::rtps::SerializedPayload_t; +using InstanceHandle_t = eprosima::fastdds::rtps::InstanceHandle_t; +using DataRepresentationId_t = eprosima::fastdds::dds::DataRepresentationId_t; + +namespace safe_edge { +namespace common { +HeaderPubSubType::HeaderPubSubType() +{ + set_name("safe_edge::common::Header"); + uint32_t type_size = safe_edge_common_Header_max_cdr_typesize; + type_size += static_cast(eprosima::fastcdr::Cdr::alignment(type_size, 4)); /* possible submessage alignment */ + max_serialized_type_size = type_size + 4; /*encapsulation*/ + is_compute_key_provided = false; +} + +HeaderPubSubType::~HeaderPubSubType() +{ +} + +bool HeaderPubSubType::serialize( + const void* const data, + SerializedPayload_t& payload, + DataRepresentationId_t data_representation) +{ + const ::safe_edge::common::Header* p_type = + static_cast(data); + + // Object that manages the raw buffer. + eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(payload.data), payload.max_size); + // Object that serializes the data. + eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN, + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::CdrVersion::XCDRv1 : eprosima::fastcdr::CdrVersion::XCDRv2); + payload.encapsulation = ser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE; + ser.set_encoding_flag( + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR : + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2); + + try + { + // Serialize encapsulation + ser.serialize_encapsulation(); + // Serialize the object. + ser << *p_type; + ser.set_dds_cdr_options({0, 0}); + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return false; + } + + // Get the serialized length + payload.length = static_cast(ser.get_serialized_data_length()); + return true; +} + +bool HeaderPubSubType::deserialize( + SerializedPayload_t& payload, + void* data) +{ + try + { + // Convert DATA to pointer of your type + ::safe_edge::common::Header* p_type = + static_cast<::safe_edge::common::Header*>(data); + + // Object that manages the raw buffer. + eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(payload.data), payload.length); + + // Object that deserializes the data. + eprosima::fastcdr::Cdr deser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN); + + // Deserialize encapsulation. + deser.read_encapsulation(); + payload.encapsulation = deser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE; + + // Deserialize the object. + deser >> *p_type; + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return false; + } + + return true; +} + +uint32_t HeaderPubSubType::calculate_serialized_size( + const void* const data, + DataRepresentationId_t data_representation) +{ + try + { + eprosima::fastcdr::CdrSizeCalculator calculator( + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::CdrVersion::XCDRv1 :eprosima::fastcdr::CdrVersion::XCDRv2); + size_t current_alignment {0}; + const ::safe_edge::common::Header* p_type = + static_cast(data); + auto calc_size = calculator.calculate_serialized_size(*p_type, current_alignment); + return static_cast(calc_size) + 4u /*encapsulation*/; + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return 0; + } +} + +void* HeaderPubSubType::create_data() +{ + return reinterpret_cast(new ::safe_edge::common::Header()); +} + +void HeaderPubSubType::delete_data( + void* data) +{ + delete(reinterpret_cast<::safe_edge::common::Header*>(data)); +} + +bool HeaderPubSubType::compute_key( + SerializedPayload_t& payload, + InstanceHandle_t& handle, + bool force_md5) +{ + static_cast(payload); + static_cast(handle); + static_cast(force_md5); + + return false; +} + +bool HeaderPubSubType::compute_key( + const void* const data, + InstanceHandle_t& handle, + bool force_md5) +{ + static_cast(data); + static_cast(handle); + static_cast(force_md5); + + return false; +} + +void HeaderPubSubType::register_type_object_representation() +{ + register_Header_type_identifier(type_identifiers_); +} + +GeoPointPubSubType::GeoPointPubSubType() +{ + set_name("safe_edge::common::GeoPoint"); + uint32_t type_size = safe_edge_common_GeoPoint_max_cdr_typesize; + type_size += static_cast(eprosima::fastcdr::Cdr::alignment(type_size, 4)); /* possible submessage alignment */ + max_serialized_type_size = type_size + 4; /*encapsulation*/ + is_compute_key_provided = false; +} + +GeoPointPubSubType::~GeoPointPubSubType() +{ +} + +bool GeoPointPubSubType::serialize( + const void* const data, + SerializedPayload_t& payload, + DataRepresentationId_t data_representation) +{ + const ::safe_edge::common::GeoPoint* p_type = + static_cast(data); + + // Object that manages the raw buffer. + eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(payload.data), payload.max_size); + // Object that serializes the data. + eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN, + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::CdrVersion::XCDRv1 : eprosima::fastcdr::CdrVersion::XCDRv2); + payload.encapsulation = ser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE; + ser.set_encoding_flag( + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR : + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2); + + try + { + // Serialize encapsulation + ser.serialize_encapsulation(); + // Serialize the object. + ser << *p_type; + ser.set_dds_cdr_options({0, 0}); + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return false; + } + + // Get the serialized length + payload.length = static_cast(ser.get_serialized_data_length()); + return true; +} + +bool GeoPointPubSubType::deserialize( + SerializedPayload_t& payload, + void* data) +{ + try + { + // Convert DATA to pointer of your type + ::safe_edge::common::GeoPoint* p_type = + static_cast<::safe_edge::common::GeoPoint*>(data); + + // Object that manages the raw buffer. + eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(payload.data), payload.length); + + // Object that deserializes the data. + eprosima::fastcdr::Cdr deser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN); + + // Deserialize encapsulation. + deser.read_encapsulation(); + payload.encapsulation = deser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE; + + // Deserialize the object. + deser >> *p_type; + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return false; + } + + return true; +} + +uint32_t GeoPointPubSubType::calculate_serialized_size( + const void* const data, + DataRepresentationId_t data_representation) +{ + try + { + eprosima::fastcdr::CdrSizeCalculator calculator( + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::CdrVersion::XCDRv1 :eprosima::fastcdr::CdrVersion::XCDRv2); + size_t current_alignment {0}; + const ::safe_edge::common::GeoPoint* p_type = + static_cast(data); + auto calc_size = calculator.calculate_serialized_size(*p_type, current_alignment); + return static_cast(calc_size) + 4u /*encapsulation*/; + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return 0; + } +} + +void* GeoPointPubSubType::create_data() +{ + return reinterpret_cast(new ::safe_edge::common::GeoPoint()); +} + +void GeoPointPubSubType::delete_data( + void* data) +{ + delete(reinterpret_cast<::safe_edge::common::GeoPoint*>(data)); +} + +bool GeoPointPubSubType::compute_key( + SerializedPayload_t& payload, + InstanceHandle_t& handle, + bool force_md5) +{ + static_cast(payload); + static_cast(handle); + static_cast(force_md5); + + return false; +} + +bool GeoPointPubSubType::compute_key( + const void* const data, + InstanceHandle_t& handle, + bool force_md5) +{ + static_cast(data); + static_cast(handle); + static_cast(force_md5); + + return false; +} + +void GeoPointPubSubType::register_type_object_representation() +{ + register_GeoPoint_type_identifier(type_identifiers_); +} + +ServiceHeartbeatPubSubType::ServiceHeartbeatPubSubType() +{ + set_name("safe_edge::common::ServiceHeartbeat"); + uint32_t type_size = safe_edge_common_ServiceHeartbeat_max_cdr_typesize; + type_size += static_cast(eprosima::fastcdr::Cdr::alignment(type_size, 4)); /* possible submessage alignment */ + max_serialized_type_size = type_size + 4; /*encapsulation*/ + is_compute_key_provided = false; +} + +ServiceHeartbeatPubSubType::~ServiceHeartbeatPubSubType() +{ +} + +bool ServiceHeartbeatPubSubType::serialize( + const void* const data, + SerializedPayload_t& payload, + DataRepresentationId_t data_representation) +{ + const ::safe_edge::common::ServiceHeartbeat* p_type = + static_cast(data); + + // Object that manages the raw buffer. + eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(payload.data), payload.max_size); + // Object that serializes the data. + eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN, + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::CdrVersion::XCDRv1 : eprosima::fastcdr::CdrVersion::XCDRv2); + payload.encapsulation = ser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE; + ser.set_encoding_flag( + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR : + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2); + + try + { + // Serialize encapsulation + ser.serialize_encapsulation(); + // Serialize the object. + ser << *p_type; + ser.set_dds_cdr_options({0, 0}); + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return false; + } + + // Get the serialized length + payload.length = static_cast(ser.get_serialized_data_length()); + return true; +} + +bool ServiceHeartbeatPubSubType::deserialize( + SerializedPayload_t& payload, + void* data) +{ + try + { + // Convert DATA to pointer of your type + ::safe_edge::common::ServiceHeartbeat* p_type = + static_cast<::safe_edge::common::ServiceHeartbeat*>(data); + + // Object that manages the raw buffer. + eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(payload.data), payload.length); + + // Object that deserializes the data. + eprosima::fastcdr::Cdr deser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN); + + // Deserialize encapsulation. + deser.read_encapsulation(); + payload.encapsulation = deser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE; + + // Deserialize the object. + deser >> *p_type; + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return false; + } + + return true; +} + +uint32_t ServiceHeartbeatPubSubType::calculate_serialized_size( + const void* const data, + DataRepresentationId_t data_representation) +{ + try + { + eprosima::fastcdr::CdrSizeCalculator calculator( + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::CdrVersion::XCDRv1 :eprosima::fastcdr::CdrVersion::XCDRv2); + size_t current_alignment {0}; + const ::safe_edge::common::ServiceHeartbeat* p_type = + static_cast(data); + auto calc_size = calculator.calculate_serialized_size(*p_type, current_alignment); + return static_cast(calc_size) + 4u /*encapsulation*/; + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return 0; + } +} + +void* ServiceHeartbeatPubSubType::create_data() +{ + return reinterpret_cast(new ::safe_edge::common::ServiceHeartbeat()); +} + +void ServiceHeartbeatPubSubType::delete_data( + void* data) +{ + delete(reinterpret_cast<::safe_edge::common::ServiceHeartbeat*>(data)); +} + +bool ServiceHeartbeatPubSubType::compute_key( + SerializedPayload_t& payload, + InstanceHandle_t& handle, + bool force_md5) +{ + static_cast(payload); + static_cast(handle); + static_cast(force_md5); + + return false; +} + +bool ServiceHeartbeatPubSubType::compute_key( + const void* const data, + InstanceHandle_t& handle, + bool force_md5) +{ + static_cast(data); + static_cast(handle); + static_cast(force_md5); + + return false; +} + +void ServiceHeartbeatPubSubType::register_type_object_representation() +{ + register_ServiceHeartbeat_type_identifier(type_identifiers_); +} + +} // namespace common + +} // namespace safe_edge + + +// Include auxiliary functions like for serializing/deserializing. +#include "commonCdrAux.ipp" diff --git a/fast_dds/idl/commonPubSubTypes.hpp b/fast_dds/idl/commonPubSubTypes.hpp new file mode 100644 index 0000000..4a39c6a --- /dev/null +++ b/fast_dds/idl/commonPubSubTypes.hpp @@ -0,0 +1,285 @@ +// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/*! + * @file commonPubSubTypes.hpp + * This header file contains the declaration of the serialization functions. + * + * This file was generated by the tool fastddsgen (version: 4.3.0). + */ + + +#ifndef FAST_DDS_GENERATED__SAFE_EDGE_COMMON_COMMON_PUBSUBTYPES_HPP +#define FAST_DDS_GENERATED__SAFE_EDGE_COMMON_COMMON_PUBSUBTYPES_HPP + +#include + +#include +#include +#include +#include +#include + +#include "common.hpp" + + +#if !defined(FASTDDS_GEN_API_VER) || (FASTDDS_GEN_API_VER != 3) +#error \ + Generated common is not compatible with current installed Fast DDS. Please, regenerate it with fastddsgen. +#endif // FASTDDS_GEN_API_VER + +namespace safe_edge { +namespace common { + +/*! + * @brief This class represents the TopicDataType of the type Header defined by the user in the IDL file. + * @ingroup common + */ +class HeaderPubSubType : public eprosima::fastdds::dds::TopicDataType +{ +public: + + typedef ::safe_edge::common::Header type; + + eProsima_user_DllExport HeaderPubSubType(); + + eProsima_user_DllExport ~HeaderPubSubType() override; + + eProsima_user_DllExport bool serialize( + const void* const data, + eprosima::fastdds::rtps::SerializedPayload_t& payload, + eprosima::fastdds::dds::DataRepresentationId_t data_representation) override; + + eProsima_user_DllExport bool deserialize( + eprosima::fastdds::rtps::SerializedPayload_t& payload, + void* data) override; + + eProsima_user_DllExport uint32_t calculate_serialized_size( + const void* const data, + eprosima::fastdds::dds::DataRepresentationId_t data_representation) override; + + eProsima_user_DllExport bool compute_key( + eprosima::fastdds::rtps::SerializedPayload_t& payload, + eprosima::fastdds::rtps::InstanceHandle_t& ihandle, + bool force_md5 = false) override; + + eProsima_user_DllExport bool compute_key( + const void* const data, + eprosima::fastdds::rtps::InstanceHandle_t& ihandle, + bool force_md5 = false) override; + + eProsima_user_DllExport void* create_data() override; + + eProsima_user_DllExport void delete_data( + void* data) override; + + //Register TypeObject representation in Fast DDS TypeObjectRegistry + eProsima_user_DllExport void register_type_object_representation() override; + +#ifdef TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED + eProsima_user_DllExport inline bool is_bounded() const override + { + return false; + } + +#endif // TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED + +#ifdef TOPIC_DATA_TYPE_API_HAS_IS_PLAIN + + eProsima_user_DllExport inline bool is_plain( + eprosima::fastdds::dds::DataRepresentationId_t data_representation) const override + { + static_cast(data_representation); + return false; + } + +#endif // TOPIC_DATA_TYPE_API_HAS_IS_PLAIN + +#ifdef TOPIC_DATA_TYPE_API_HAS_CONSTRUCT_SAMPLE + eProsima_user_DllExport inline bool construct_sample( + void* memory) const override + { + static_cast(memory); + return false; + } + +#endif // TOPIC_DATA_TYPE_API_HAS_CONSTRUCT_SAMPLE + +private: + +}; + + +/*! + * @brief This class represents the TopicDataType of the type GeoPoint defined by the user in the IDL file. + * @ingroup common + */ +class GeoPointPubSubType : public eprosima::fastdds::dds::TopicDataType +{ +public: + + typedef ::safe_edge::common::GeoPoint type; + + eProsima_user_DllExport GeoPointPubSubType(); + + eProsima_user_DllExport ~GeoPointPubSubType() override; + + eProsima_user_DllExport bool serialize( + const void* const data, + eprosima::fastdds::rtps::SerializedPayload_t& payload, + eprosima::fastdds::dds::DataRepresentationId_t data_representation) override; + + eProsima_user_DllExport bool deserialize( + eprosima::fastdds::rtps::SerializedPayload_t& payload, + void* data) override; + + eProsima_user_DllExport uint32_t calculate_serialized_size( + const void* const data, + eprosima::fastdds::dds::DataRepresentationId_t data_representation) override; + + eProsima_user_DllExport bool compute_key( + eprosima::fastdds::rtps::SerializedPayload_t& payload, + eprosima::fastdds::rtps::InstanceHandle_t& ihandle, + bool force_md5 = false) override; + + eProsima_user_DllExport bool compute_key( + const void* const data, + eprosima::fastdds::rtps::InstanceHandle_t& ihandle, + bool force_md5 = false) override; + + eProsima_user_DllExport void* create_data() override; + + eProsima_user_DllExport void delete_data( + void* data) override; + + //Register TypeObject representation in Fast DDS TypeObjectRegistry + eProsima_user_DllExport void register_type_object_representation() override; + +#ifdef TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED + eProsima_user_DllExport inline bool is_bounded() const override + { + return true; + } + +#endif // TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED + +#ifdef TOPIC_DATA_TYPE_API_HAS_IS_PLAIN + + eProsima_user_DllExport inline bool is_plain( + eprosima::fastdds::dds::DataRepresentationId_t data_representation) const override + { + static_cast(data_representation); + return false; + } + +#endif // TOPIC_DATA_TYPE_API_HAS_IS_PLAIN + +#ifdef TOPIC_DATA_TYPE_API_HAS_CONSTRUCT_SAMPLE + eProsima_user_DllExport inline bool construct_sample( + void* memory) const override + { + static_cast(memory); + return false; + } + +#endif // TOPIC_DATA_TYPE_API_HAS_CONSTRUCT_SAMPLE + +private: + +}; + + +/*! + * @brief This class represents the TopicDataType of the type ServiceHeartbeat defined by the user in the IDL file. + * @ingroup common + */ +class ServiceHeartbeatPubSubType : public eprosima::fastdds::dds::TopicDataType +{ +public: + + typedef ::safe_edge::common::ServiceHeartbeat type; + + eProsima_user_DllExport ServiceHeartbeatPubSubType(); + + eProsima_user_DllExport ~ServiceHeartbeatPubSubType() override; + + eProsima_user_DllExport bool serialize( + const void* const data, + eprosima::fastdds::rtps::SerializedPayload_t& payload, + eprosima::fastdds::dds::DataRepresentationId_t data_representation) override; + + eProsima_user_DllExport bool deserialize( + eprosima::fastdds::rtps::SerializedPayload_t& payload, + void* data) override; + + eProsima_user_DllExport uint32_t calculate_serialized_size( + const void* const data, + eprosima::fastdds::dds::DataRepresentationId_t data_representation) override; + + eProsima_user_DllExport bool compute_key( + eprosima::fastdds::rtps::SerializedPayload_t& payload, + eprosima::fastdds::rtps::InstanceHandle_t& ihandle, + bool force_md5 = false) override; + + eProsima_user_DllExport bool compute_key( + const void* const data, + eprosima::fastdds::rtps::InstanceHandle_t& ihandle, + bool force_md5 = false) override; + + eProsima_user_DllExport void* create_data() override; + + eProsima_user_DllExport void delete_data( + void* data) override; + + //Register TypeObject representation in Fast DDS TypeObjectRegistry + eProsima_user_DllExport void register_type_object_representation() override; + +#ifdef TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED + eProsima_user_DllExport inline bool is_bounded() const override + { + return false; + } + +#endif // TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED + +#ifdef TOPIC_DATA_TYPE_API_HAS_IS_PLAIN + + eProsima_user_DllExport inline bool is_plain( + eprosima::fastdds::dds::DataRepresentationId_t data_representation) const override + { + static_cast(data_representation); + return false; + } + +#endif // TOPIC_DATA_TYPE_API_HAS_IS_PLAIN + +#ifdef TOPIC_DATA_TYPE_API_HAS_CONSTRUCT_SAMPLE + eProsima_user_DllExport inline bool construct_sample( + void* memory) const override + { + static_cast(memory); + return false; + } + +#endif // TOPIC_DATA_TYPE_API_HAS_CONSTRUCT_SAMPLE + +private: + +}; + +} // namespace common +} // namespace safe_edge + +#endif // FAST_DDS_GENERATED__SAFE_EDGE_COMMON_COMMON_PUBSUBTYPES_HPP + diff --git a/fast_dds/idl/commonTypeObjectSupport.cxx b/fast_dds/idl/commonTypeObjectSupport.cxx new file mode 100644 index 0000000..5a9d53c --- /dev/null +++ b/fast_dds/idl/commonTypeObjectSupport.cxx @@ -0,0 +1,583 @@ +// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/*! + * @file commonTypeObjectSupport.cxx + * Source file containing the implementation to register the TypeObject representation of the described types in the IDL file + * + * This file was generated by the tool fastddsgen (version: 4.3.0). + */ + +#include "commonTypeObjectSupport.hpp" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common.hpp" + + +using namespace eprosima::fastdds::dds::xtypes; + +namespace safe_edge { +namespace common { +// TypeIdentifier is returned by reference: dependent structures/unions are registered in this same method +void register_Header_type_identifier( + TypeIdentifierPair& type_ids_Header) +{ + + ReturnCode_t return_code_Header {eprosima::fastdds::dds::RETCODE_OK}; + return_code_Header = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "safe_edge::common::Header", type_ids_Header); + if (eprosima::fastdds::dds::RETCODE_OK != return_code_Header) + { + StructTypeFlag struct_flags_Header = TypeObjectUtils::build_struct_type_flag(eprosima::fastdds::dds::xtypes::ExtensibilityKind::APPENDABLE, + false, false); + QualifiedTypeName type_name_Header = "safe_edge::common::Header"; + eprosima::fastcdr::optional type_ann_builtin_Header; + eprosima::fastcdr::optional ann_custom_Header; + CompleteTypeDetail detail_Header = TypeObjectUtils::build_complete_type_detail(type_ann_builtin_Header, ann_custom_Header, type_name_Header.to_string()); + CompleteStructHeader header_Header; + header_Header = TypeObjectUtils::build_complete_struct_header(TypeIdentifier(), detail_Header); + CompleteStructMemberSeq member_seq_Header; + { + TypeIdentifierPair type_ids_source; + ReturnCode_t return_code_source {eprosima::fastdds::dds::RETCODE_OK}; + return_code_source = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "anonymous_string_unbounded", type_ids_source); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_source) + { + { + SBound bound = 0; + StringSTypeDefn string_sdefn = TypeObjectUtils::build_string_s_type_defn(bound); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_s_string_type_identifier(string_sdefn, + "anonymous_string_unbounded", type_ids_source)) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "anonymous_string_unbounded already registered in TypeObjectRegistry for a different type."); + } + } + } + StructMemberFlag member_flags_source = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_source = 0x00000000; + bool common_source_ec {false}; + CommonStructMember common_source {TypeObjectUtils::build_common_struct_member(member_id_source, member_flags_source, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_source, common_source_ec))}; + if (!common_source_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure source member TypeIdentifier inconsistent."); + return; + } + MemberName name_source = "source"; + eprosima::fastcdr::optional member_ann_builtin_source; + ann_custom_Header.reset(); + CompleteMemberDetail detail_source = TypeObjectUtils::build_complete_member_detail(name_source, member_ann_builtin_source, ann_custom_Header); + CompleteStructMember member_source = TypeObjectUtils::build_complete_struct_member(common_source, detail_source); + TypeObjectUtils::add_complete_struct_member(member_seq_Header, member_source); + } + { + TypeIdentifierPair type_ids_timestamp_ms; + ReturnCode_t return_code_timestamp_ms {eprosima::fastdds::dds::RETCODE_OK}; + return_code_timestamp_ms = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "_uint64_t", type_ids_timestamp_ms); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_timestamp_ms) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "timestamp_ms Structure member TypeIdentifier unknown to TypeObjectRegistry."); + return; + } + StructMemberFlag member_flags_timestamp_ms = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_timestamp_ms = 0x00000001; + bool common_timestamp_ms_ec {false}; + CommonStructMember common_timestamp_ms {TypeObjectUtils::build_common_struct_member(member_id_timestamp_ms, member_flags_timestamp_ms, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_timestamp_ms, common_timestamp_ms_ec))}; + if (!common_timestamp_ms_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure timestamp_ms member TypeIdentifier inconsistent."); + return; + } + MemberName name_timestamp_ms = "timestamp_ms"; + eprosima::fastcdr::optional member_ann_builtin_timestamp_ms; + ann_custom_Header.reset(); + CompleteMemberDetail detail_timestamp_ms = TypeObjectUtils::build_complete_member_detail(name_timestamp_ms, member_ann_builtin_timestamp_ms, ann_custom_Header); + CompleteStructMember member_timestamp_ms = TypeObjectUtils::build_complete_struct_member(common_timestamp_ms, detail_timestamp_ms); + TypeObjectUtils::add_complete_struct_member(member_seq_Header, member_timestamp_ms); + } + { + TypeIdentifierPair type_ids_trace_id; + ReturnCode_t return_code_trace_id {eprosima::fastdds::dds::RETCODE_OK}; + return_code_trace_id = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "anonymous_string_unbounded", type_ids_trace_id); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_trace_id) + { + { + SBound bound = 0; + StringSTypeDefn string_sdefn = TypeObjectUtils::build_string_s_type_defn(bound); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_s_string_type_identifier(string_sdefn, + "anonymous_string_unbounded", type_ids_trace_id)) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "anonymous_string_unbounded already registered in TypeObjectRegistry for a different type."); + } + } + } + StructMemberFlag member_flags_trace_id = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_trace_id = 0x00000002; + bool common_trace_id_ec {false}; + CommonStructMember common_trace_id {TypeObjectUtils::build_common_struct_member(member_id_trace_id, member_flags_trace_id, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_trace_id, common_trace_id_ec))}; + if (!common_trace_id_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure trace_id member TypeIdentifier inconsistent."); + return; + } + MemberName name_trace_id = "trace_id"; + eprosima::fastcdr::optional member_ann_builtin_trace_id; + ann_custom_Header.reset(); + CompleteMemberDetail detail_trace_id = TypeObjectUtils::build_complete_member_detail(name_trace_id, member_ann_builtin_trace_id, ann_custom_Header); + CompleteStructMember member_trace_id = TypeObjectUtils::build_complete_struct_member(common_trace_id, detail_trace_id); + TypeObjectUtils::add_complete_struct_member(member_seq_Header, member_trace_id); + } + CompleteStructType struct_type_Header = TypeObjectUtils::build_complete_struct_type(struct_flags_Header, header_Header, member_seq_Header); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_struct_type_object(struct_type_Header, type_name_Header.to_string(), type_ids_Header)) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "safe_edge::common::Header already registered in TypeObjectRegistry for a different type."); + } + } +}// TypeIdentifier is returned by reference: dependent structures/unions are registered in this same method +void register_GeoPoint_type_identifier( + TypeIdentifierPair& type_ids_GeoPoint) +{ + + ReturnCode_t return_code_GeoPoint {eprosima::fastdds::dds::RETCODE_OK}; + return_code_GeoPoint = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "safe_edge::common::GeoPoint", type_ids_GeoPoint); + if (eprosima::fastdds::dds::RETCODE_OK != return_code_GeoPoint) + { + StructTypeFlag struct_flags_GeoPoint = TypeObjectUtils::build_struct_type_flag(eprosima::fastdds::dds::xtypes::ExtensibilityKind::APPENDABLE, + false, false); + QualifiedTypeName type_name_GeoPoint = "safe_edge::common::GeoPoint"; + eprosima::fastcdr::optional type_ann_builtin_GeoPoint; + eprosima::fastcdr::optional ann_custom_GeoPoint; + CompleteTypeDetail detail_GeoPoint = TypeObjectUtils::build_complete_type_detail(type_ann_builtin_GeoPoint, ann_custom_GeoPoint, type_name_GeoPoint.to_string()); + CompleteStructHeader header_GeoPoint; + header_GeoPoint = TypeObjectUtils::build_complete_struct_header(TypeIdentifier(), detail_GeoPoint); + CompleteStructMemberSeq member_seq_GeoPoint; + { + TypeIdentifierPair type_ids_latitude; + ReturnCode_t return_code_latitude {eprosima::fastdds::dds::RETCODE_OK}; + return_code_latitude = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "_double", type_ids_latitude); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_latitude) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "latitude Structure member TypeIdentifier unknown to TypeObjectRegistry."); + return; + } + StructMemberFlag member_flags_latitude = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_latitude = 0x00000000; + bool common_latitude_ec {false}; + CommonStructMember common_latitude {TypeObjectUtils::build_common_struct_member(member_id_latitude, member_flags_latitude, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_latitude, common_latitude_ec))}; + if (!common_latitude_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure latitude member TypeIdentifier inconsistent."); + return; + } + MemberName name_latitude = "latitude"; + eprosima::fastcdr::optional member_ann_builtin_latitude; + ann_custom_GeoPoint.reset(); + CompleteMemberDetail detail_latitude = TypeObjectUtils::build_complete_member_detail(name_latitude, member_ann_builtin_latitude, ann_custom_GeoPoint); + CompleteStructMember member_latitude = TypeObjectUtils::build_complete_struct_member(common_latitude, detail_latitude); + TypeObjectUtils::add_complete_struct_member(member_seq_GeoPoint, member_latitude); + } + { + TypeIdentifierPair type_ids_longitude; + ReturnCode_t return_code_longitude {eprosima::fastdds::dds::RETCODE_OK}; + return_code_longitude = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "_double", type_ids_longitude); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_longitude) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "longitude Structure member TypeIdentifier unknown to TypeObjectRegistry."); + return; + } + StructMemberFlag member_flags_longitude = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_longitude = 0x00000001; + bool common_longitude_ec {false}; + CommonStructMember common_longitude {TypeObjectUtils::build_common_struct_member(member_id_longitude, member_flags_longitude, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_longitude, common_longitude_ec))}; + if (!common_longitude_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure longitude member TypeIdentifier inconsistent."); + return; + } + MemberName name_longitude = "longitude"; + eprosima::fastcdr::optional member_ann_builtin_longitude; + ann_custom_GeoPoint.reset(); + CompleteMemberDetail detail_longitude = TypeObjectUtils::build_complete_member_detail(name_longitude, member_ann_builtin_longitude, ann_custom_GeoPoint); + CompleteStructMember member_longitude = TypeObjectUtils::build_complete_struct_member(common_longitude, detail_longitude); + TypeObjectUtils::add_complete_struct_member(member_seq_GeoPoint, member_longitude); + } + CompleteStructType struct_type_GeoPoint = TypeObjectUtils::build_complete_struct_type(struct_flags_GeoPoint, header_GeoPoint, member_seq_GeoPoint); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_struct_type_object(struct_type_GeoPoint, type_name_GeoPoint.to_string(), type_ids_GeoPoint)) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "safe_edge::common::GeoPoint already registered in TypeObjectRegistry for a different type."); + } + } +}void register_HealthStatus_type_identifier( + TypeIdentifierPair& type_ids_HealthStatus) +{ + ReturnCode_t return_code_HealthStatus {eprosima::fastdds::dds::RETCODE_OK}; + return_code_HealthStatus = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "safe_edge::common::HealthStatus", type_ids_HealthStatus); + if (eprosima::fastdds::dds::RETCODE_OK != return_code_HealthStatus) + { + EnumTypeFlag enum_flags_HealthStatus = 0; + BitBound bit_bound_HealthStatus = 32; + CommonEnumeratedHeader common_HealthStatus = TypeObjectUtils::build_common_enumerated_header(bit_bound_HealthStatus); + QualifiedTypeName type_name_HealthStatus = "safe_edge::common::HealthStatus"; + eprosima::fastcdr::optional type_ann_builtin_HealthStatus; + eprosima::fastcdr::optional ann_custom_HealthStatus; + CompleteTypeDetail detail_HealthStatus = TypeObjectUtils::build_complete_type_detail(type_ann_builtin_HealthStatus, ann_custom_HealthStatus, type_name_HealthStatus.to_string()); + CompleteEnumeratedHeader header_HealthStatus = TypeObjectUtils::build_complete_enumerated_header(common_HealthStatus, detail_HealthStatus); + CompleteEnumeratedLiteralSeq literal_seq_HealthStatus; + { + EnumeratedLiteralFlag flags_HEALTH_UNKNOWN = TypeObjectUtils::build_enumerated_literal_flag(false); + CommonEnumeratedLiteral common_HEALTH_UNKNOWN = TypeObjectUtils::build_common_enumerated_literal(0, flags_HEALTH_UNKNOWN); + eprosima::fastcdr::optional member_ann_builtin_HEALTH_UNKNOWN; + ann_custom_HealthStatus.reset(); + MemberName name_HEALTH_UNKNOWN = "HEALTH_UNKNOWN"; + CompleteMemberDetail detail_HEALTH_UNKNOWN = TypeObjectUtils::build_complete_member_detail(name_HEALTH_UNKNOWN, member_ann_builtin_HEALTH_UNKNOWN, ann_custom_HealthStatus); + CompleteEnumeratedLiteral literal_HEALTH_UNKNOWN = TypeObjectUtils::build_complete_enumerated_literal(common_HEALTH_UNKNOWN, detail_HEALTH_UNKNOWN); + TypeObjectUtils::add_complete_enumerated_literal(literal_seq_HealthStatus, literal_HEALTH_UNKNOWN); + } + { + EnumeratedLiteralFlag flags_HEALTH_OK = TypeObjectUtils::build_enumerated_literal_flag(false); + CommonEnumeratedLiteral common_HEALTH_OK = TypeObjectUtils::build_common_enumerated_literal(1, flags_HEALTH_OK); + eprosima::fastcdr::optional member_ann_builtin_HEALTH_OK; + ann_custom_HealthStatus.reset(); + MemberName name_HEALTH_OK = "HEALTH_OK"; + CompleteMemberDetail detail_HEALTH_OK = TypeObjectUtils::build_complete_member_detail(name_HEALTH_OK, member_ann_builtin_HEALTH_OK, ann_custom_HealthStatus); + CompleteEnumeratedLiteral literal_HEALTH_OK = TypeObjectUtils::build_complete_enumerated_literal(common_HEALTH_OK, detail_HEALTH_OK); + TypeObjectUtils::add_complete_enumerated_literal(literal_seq_HealthStatus, literal_HEALTH_OK); + } + { + EnumeratedLiteralFlag flags_HEALTH_DEGRADED = TypeObjectUtils::build_enumerated_literal_flag(false); + CommonEnumeratedLiteral common_HEALTH_DEGRADED = TypeObjectUtils::build_common_enumerated_literal(2, flags_HEALTH_DEGRADED); + eprosima::fastcdr::optional member_ann_builtin_HEALTH_DEGRADED; + ann_custom_HealthStatus.reset(); + MemberName name_HEALTH_DEGRADED = "HEALTH_DEGRADED"; + CompleteMemberDetail detail_HEALTH_DEGRADED = TypeObjectUtils::build_complete_member_detail(name_HEALTH_DEGRADED, member_ann_builtin_HEALTH_DEGRADED, ann_custom_HealthStatus); + CompleteEnumeratedLiteral literal_HEALTH_DEGRADED = TypeObjectUtils::build_complete_enumerated_literal(common_HEALTH_DEGRADED, detail_HEALTH_DEGRADED); + TypeObjectUtils::add_complete_enumerated_literal(literal_seq_HealthStatus, literal_HEALTH_DEGRADED); + } + { + EnumeratedLiteralFlag flags_HEALTH_ERROR = TypeObjectUtils::build_enumerated_literal_flag(false); + CommonEnumeratedLiteral common_HEALTH_ERROR = TypeObjectUtils::build_common_enumerated_literal(3, flags_HEALTH_ERROR); + eprosima::fastcdr::optional member_ann_builtin_HEALTH_ERROR; + ann_custom_HealthStatus.reset(); + MemberName name_HEALTH_ERROR = "HEALTH_ERROR"; + CompleteMemberDetail detail_HEALTH_ERROR = TypeObjectUtils::build_complete_member_detail(name_HEALTH_ERROR, member_ann_builtin_HEALTH_ERROR, ann_custom_HealthStatus); + CompleteEnumeratedLiteral literal_HEALTH_ERROR = TypeObjectUtils::build_complete_enumerated_literal(common_HEALTH_ERROR, detail_HEALTH_ERROR); + TypeObjectUtils::add_complete_enumerated_literal(literal_seq_HealthStatus, literal_HEALTH_ERROR); + } + CompleteEnumeratedType enumerated_type_HealthStatus = TypeObjectUtils::build_complete_enumerated_type(enum_flags_HealthStatus, header_HealthStatus, + literal_seq_HealthStatus); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_enumerated_type_object(enumerated_type_HealthStatus, type_name_HealthStatus.to_string(), type_ids_HealthStatus)) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "safe_edge::common::HealthStatus already registered in TypeObjectRegistry for a different type."); + } + } +}// TypeIdentifier is returned by reference: dependent structures/unions are registered in this same method +void register_ServiceHeartbeat_type_identifier( + TypeIdentifierPair& type_ids_ServiceHeartbeat) +{ + + ReturnCode_t return_code_ServiceHeartbeat {eprosima::fastdds::dds::RETCODE_OK}; + return_code_ServiceHeartbeat = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "safe_edge::common::ServiceHeartbeat", type_ids_ServiceHeartbeat); + if (eprosima::fastdds::dds::RETCODE_OK != return_code_ServiceHeartbeat) + { + StructTypeFlag struct_flags_ServiceHeartbeat = TypeObjectUtils::build_struct_type_flag(eprosima::fastdds::dds::xtypes::ExtensibilityKind::APPENDABLE, + false, false); + QualifiedTypeName type_name_ServiceHeartbeat = "safe_edge::common::ServiceHeartbeat"; + eprosima::fastcdr::optional type_ann_builtin_ServiceHeartbeat; + eprosima::fastcdr::optional ann_custom_ServiceHeartbeat; + CompleteTypeDetail detail_ServiceHeartbeat = TypeObjectUtils::build_complete_type_detail(type_ann_builtin_ServiceHeartbeat, ann_custom_ServiceHeartbeat, type_name_ServiceHeartbeat.to_string()); + CompleteStructHeader header_ServiceHeartbeat; + header_ServiceHeartbeat = TypeObjectUtils::build_complete_struct_header(TypeIdentifier(), detail_ServiceHeartbeat); + CompleteStructMemberSeq member_seq_ServiceHeartbeat; + { + TypeIdentifierPair type_ids_header_st; + ReturnCode_t return_code_header_st {eprosima::fastdds::dds::RETCODE_OK}; + return_code_header_st = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "safe_edge::common::Header", type_ids_header_st); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_header_st) + { + ::safe_edge::common::register_Header_type_identifier(type_ids_header_st); + } + StructMemberFlag member_flags_header_st = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_header_st = 0x00000000; + bool common_header_st_ec {false}; + CommonStructMember common_header_st {TypeObjectUtils::build_common_struct_member(member_id_header_st, member_flags_header_st, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_header_st, common_header_st_ec))}; + if (!common_header_st_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure header_st member TypeIdentifier inconsistent."); + return; + } + MemberName name_header_st = "header_st"; + eprosima::fastcdr::optional member_ann_builtin_header_st; + ann_custom_ServiceHeartbeat.reset(); + CompleteMemberDetail detail_header_st = TypeObjectUtils::build_complete_member_detail(name_header_st, member_ann_builtin_header_st, ann_custom_ServiceHeartbeat); + CompleteStructMember member_header_st = TypeObjectUtils::build_complete_struct_member(common_header_st, detail_header_st); + TypeObjectUtils::add_complete_struct_member(member_seq_ServiceHeartbeat, member_header_st); + } + { + TypeIdentifierPair type_ids_service_name; + ReturnCode_t return_code_service_name {eprosima::fastdds::dds::RETCODE_OK}; + return_code_service_name = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "anonymous_string_unbounded", type_ids_service_name); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_service_name) + { + { + SBound bound = 0; + StringSTypeDefn string_sdefn = TypeObjectUtils::build_string_s_type_defn(bound); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_s_string_type_identifier(string_sdefn, + "anonymous_string_unbounded", type_ids_service_name)) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "anonymous_string_unbounded already registered in TypeObjectRegistry for a different type."); + } + } + } + StructMemberFlag member_flags_service_name = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_service_name = 0x00000001; + bool common_service_name_ec {false}; + CommonStructMember common_service_name {TypeObjectUtils::build_common_struct_member(member_id_service_name, member_flags_service_name, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_service_name, common_service_name_ec))}; + if (!common_service_name_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure service_name member TypeIdentifier inconsistent."); + return; + } + MemberName name_service_name = "service_name"; + eprosima::fastcdr::optional member_ann_builtin_service_name; + ann_custom_ServiceHeartbeat.reset(); + CompleteMemberDetail detail_service_name = TypeObjectUtils::build_complete_member_detail(name_service_name, member_ann_builtin_service_name, ann_custom_ServiceHeartbeat); + CompleteStructMember member_service_name = TypeObjectUtils::build_complete_struct_member(common_service_name, detail_service_name); + TypeObjectUtils::add_complete_struct_member(member_seq_ServiceHeartbeat, member_service_name); + } + { + TypeIdentifierPair type_ids_status; + ReturnCode_t return_code_status {eprosima::fastdds::dds::RETCODE_OK}; + return_code_status = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "safe_edge::common::HealthStatus", type_ids_status); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_status) + { + ::safe_edge::common::register_HealthStatus_type_identifier(type_ids_status); + } + StructMemberFlag member_flags_status = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_status = 0x00000002; + bool common_status_ec {false}; + CommonStructMember common_status {TypeObjectUtils::build_common_struct_member(member_id_status, member_flags_status, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_status, common_status_ec))}; + if (!common_status_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure status member TypeIdentifier inconsistent."); + return; + } + MemberName name_status = "status"; + eprosima::fastcdr::optional member_ann_builtin_status; + ann_custom_ServiceHeartbeat.reset(); + CompleteMemberDetail detail_status = TypeObjectUtils::build_complete_member_detail(name_status, member_ann_builtin_status, ann_custom_ServiceHeartbeat); + CompleteStructMember member_status = TypeObjectUtils::build_complete_struct_member(common_status, detail_status); + TypeObjectUtils::add_complete_struct_member(member_seq_ServiceHeartbeat, member_status); + } + { + TypeIdentifierPair type_ids_detail; + ReturnCode_t return_code_detail {eprosima::fastdds::dds::RETCODE_OK}; + return_code_detail = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "anonymous_string_unbounded", type_ids_detail); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_detail) + { + { + SBound bound = 0; + StringSTypeDefn string_sdefn = TypeObjectUtils::build_string_s_type_defn(bound); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_s_string_type_identifier(string_sdefn, + "anonymous_string_unbounded", type_ids_detail)) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "anonymous_string_unbounded already registered in TypeObjectRegistry for a different type."); + } + } + } + StructMemberFlag member_flags_detail = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_detail = 0x00000003; + bool common_detail_ec {false}; + CommonStructMember common_detail {TypeObjectUtils::build_common_struct_member(member_id_detail, member_flags_detail, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_detail, common_detail_ec))}; + if (!common_detail_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure detail member TypeIdentifier inconsistent."); + return; + } + MemberName name_detail = "detail"; + eprosima::fastcdr::optional member_ann_builtin_detail; + ann_custom_ServiceHeartbeat.reset(); + CompleteMemberDetail detail_detail = TypeObjectUtils::build_complete_member_detail(name_detail, member_ann_builtin_detail, ann_custom_ServiceHeartbeat); + CompleteStructMember member_detail = TypeObjectUtils::build_complete_struct_member(common_detail, detail_detail); + TypeObjectUtils::add_complete_struct_member(member_seq_ServiceHeartbeat, member_detail); + } + CompleteStructType struct_type_ServiceHeartbeat = TypeObjectUtils::build_complete_struct_type(struct_flags_ServiceHeartbeat, header_ServiceHeartbeat, member_seq_ServiceHeartbeat); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_struct_type_object(struct_type_ServiceHeartbeat, type_name_ServiceHeartbeat.to_string(), type_ids_ServiceHeartbeat)) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "safe_edge::common::ServiceHeartbeat already registered in TypeObjectRegistry for a different type."); + } + } +}void register_PolicyMode_type_identifier( + TypeIdentifierPair& type_ids_PolicyMode) +{ + ReturnCode_t return_code_PolicyMode {eprosima::fastdds::dds::RETCODE_OK}; + return_code_PolicyMode = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "safe_edge::common::PolicyMode", type_ids_PolicyMode); + if (eprosima::fastdds::dds::RETCODE_OK != return_code_PolicyMode) + { + EnumTypeFlag enum_flags_PolicyMode = 0; + BitBound bit_bound_PolicyMode = 32; + CommonEnumeratedHeader common_PolicyMode = TypeObjectUtils::build_common_enumerated_header(bit_bound_PolicyMode); + QualifiedTypeName type_name_PolicyMode = "safe_edge::common::PolicyMode"; + eprosima::fastcdr::optional type_ann_builtin_PolicyMode; + eprosima::fastcdr::optional ann_custom_PolicyMode; + CompleteTypeDetail detail_PolicyMode = TypeObjectUtils::build_complete_type_detail(type_ann_builtin_PolicyMode, ann_custom_PolicyMode, type_name_PolicyMode.to_string()); + CompleteEnumeratedHeader header_PolicyMode = TypeObjectUtils::build_complete_enumerated_header(common_PolicyMode, detail_PolicyMode); + CompleteEnumeratedLiteralSeq literal_seq_PolicyMode; + { + EnumeratedLiteralFlag flags_POLICY_UNKNOWN = TypeObjectUtils::build_enumerated_literal_flag(false); + CommonEnumeratedLiteral common_POLICY_UNKNOWN = TypeObjectUtils::build_common_enumerated_literal(0, flags_POLICY_UNKNOWN); + eprosima::fastcdr::optional member_ann_builtin_POLICY_UNKNOWN; + ann_custom_PolicyMode.reset(); + MemberName name_POLICY_UNKNOWN = "POLICY_UNKNOWN"; + CompleteMemberDetail detail_POLICY_UNKNOWN = TypeObjectUtils::build_complete_member_detail(name_POLICY_UNKNOWN, member_ann_builtin_POLICY_UNKNOWN, ann_custom_PolicyMode); + CompleteEnumeratedLiteral literal_POLICY_UNKNOWN = TypeObjectUtils::build_complete_enumerated_literal(common_POLICY_UNKNOWN, detail_POLICY_UNKNOWN); + TypeObjectUtils::add_complete_enumerated_literal(literal_seq_PolicyMode, literal_POLICY_UNKNOWN); + } + { + EnumeratedLiteralFlag flags_POLICY_NOMINAL = TypeObjectUtils::build_enumerated_literal_flag(false); + CommonEnumeratedLiteral common_POLICY_NOMINAL = TypeObjectUtils::build_common_enumerated_literal(1, flags_POLICY_NOMINAL); + eprosima::fastcdr::optional member_ann_builtin_POLICY_NOMINAL; + ann_custom_PolicyMode.reset(); + MemberName name_POLICY_NOMINAL = "POLICY_NOMINAL"; + CompleteMemberDetail detail_POLICY_NOMINAL = TypeObjectUtils::build_complete_member_detail(name_POLICY_NOMINAL, member_ann_builtin_POLICY_NOMINAL, ann_custom_PolicyMode); + CompleteEnumeratedLiteral literal_POLICY_NOMINAL = TypeObjectUtils::build_complete_enumerated_literal(common_POLICY_NOMINAL, detail_POLICY_NOMINAL); + TypeObjectUtils::add_complete_enumerated_literal(literal_seq_PolicyMode, literal_POLICY_NOMINAL); + } + { + EnumeratedLiteralFlag flags_POLICY_LOW_SOC = TypeObjectUtils::build_enumerated_literal_flag(false); + CommonEnumeratedLiteral common_POLICY_LOW_SOC = TypeObjectUtils::build_common_enumerated_literal(2, flags_POLICY_LOW_SOC); + eprosima::fastcdr::optional member_ann_builtin_POLICY_LOW_SOC; + ann_custom_PolicyMode.reset(); + MemberName name_POLICY_LOW_SOC = "POLICY_LOW_SOC"; + CompleteMemberDetail detail_POLICY_LOW_SOC = TypeObjectUtils::build_complete_member_detail(name_POLICY_LOW_SOC, member_ann_builtin_POLICY_LOW_SOC, ann_custom_PolicyMode); + CompleteEnumeratedLiteral literal_POLICY_LOW_SOC = TypeObjectUtils::build_complete_enumerated_literal(common_POLICY_LOW_SOC, detail_POLICY_LOW_SOC); + TypeObjectUtils::add_complete_enumerated_literal(literal_seq_PolicyMode, literal_POLICY_LOW_SOC); + } + { + EnumeratedLiteralFlag flags_POLICY_EDGE_AUTONOMOUS = TypeObjectUtils::build_enumerated_literal_flag(false); + CommonEnumeratedLiteral common_POLICY_EDGE_AUTONOMOUS = TypeObjectUtils::build_common_enumerated_literal(3, flags_POLICY_EDGE_AUTONOMOUS); + eprosima::fastcdr::optional member_ann_builtin_POLICY_EDGE_AUTONOMOUS; + ann_custom_PolicyMode.reset(); + MemberName name_POLICY_EDGE_AUTONOMOUS = "POLICY_EDGE_AUTONOMOUS"; + CompleteMemberDetail detail_POLICY_EDGE_AUTONOMOUS = TypeObjectUtils::build_complete_member_detail(name_POLICY_EDGE_AUTONOMOUS, member_ann_builtin_POLICY_EDGE_AUTONOMOUS, ann_custom_PolicyMode); + CompleteEnumeratedLiteral literal_POLICY_EDGE_AUTONOMOUS = TypeObjectUtils::build_complete_enumerated_literal(common_POLICY_EDGE_AUTONOMOUS, detail_POLICY_EDGE_AUTONOMOUS); + TypeObjectUtils::add_complete_enumerated_literal(literal_seq_PolicyMode, literal_POLICY_EDGE_AUTONOMOUS); + } + { + EnumeratedLiteralFlag flags_POLICY_DEGRADED_SERVER_DOWN = TypeObjectUtils::build_enumerated_literal_flag(false); + CommonEnumeratedLiteral common_POLICY_DEGRADED_SERVER_DOWN = TypeObjectUtils::build_common_enumerated_literal(4, flags_POLICY_DEGRADED_SERVER_DOWN); + eprosima::fastcdr::optional member_ann_builtin_POLICY_DEGRADED_SERVER_DOWN; + ann_custom_PolicyMode.reset(); + MemberName name_POLICY_DEGRADED_SERVER_DOWN = "POLICY_DEGRADED_SERVER_DOWN"; + CompleteMemberDetail detail_POLICY_DEGRADED_SERVER_DOWN = TypeObjectUtils::build_complete_member_detail(name_POLICY_DEGRADED_SERVER_DOWN, member_ann_builtin_POLICY_DEGRADED_SERVER_DOWN, ann_custom_PolicyMode); + CompleteEnumeratedLiteral literal_POLICY_DEGRADED_SERVER_DOWN = TypeObjectUtils::build_complete_enumerated_literal(common_POLICY_DEGRADED_SERVER_DOWN, detail_POLICY_DEGRADED_SERVER_DOWN); + TypeObjectUtils::add_complete_enumerated_literal(literal_seq_PolicyMode, literal_POLICY_DEGRADED_SERVER_DOWN); + } + { + EnumeratedLiteralFlag flags_POLICY_DEGRADED_COMPLETE = TypeObjectUtils::build_enumerated_literal_flag(false); + CommonEnumeratedLiteral common_POLICY_DEGRADED_COMPLETE = TypeObjectUtils::build_common_enumerated_literal(5, flags_POLICY_DEGRADED_COMPLETE); + eprosima::fastcdr::optional member_ann_builtin_POLICY_DEGRADED_COMPLETE; + ann_custom_PolicyMode.reset(); + MemberName name_POLICY_DEGRADED_COMPLETE = "POLICY_DEGRADED_COMPLETE"; + CompleteMemberDetail detail_POLICY_DEGRADED_COMPLETE = TypeObjectUtils::build_complete_member_detail(name_POLICY_DEGRADED_COMPLETE, member_ann_builtin_POLICY_DEGRADED_COMPLETE, ann_custom_PolicyMode); + CompleteEnumeratedLiteral literal_POLICY_DEGRADED_COMPLETE = TypeObjectUtils::build_complete_enumerated_literal(common_POLICY_DEGRADED_COMPLETE, detail_POLICY_DEGRADED_COMPLETE); + TypeObjectUtils::add_complete_enumerated_literal(literal_seq_PolicyMode, literal_POLICY_DEGRADED_COMPLETE); + } + CompleteEnumeratedType enumerated_type_PolicyMode = TypeObjectUtils::build_complete_enumerated_type(enum_flags_PolicyMode, header_PolicyMode, + literal_seq_PolicyMode); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_enumerated_type_object(enumerated_type_PolicyMode, type_name_PolicyMode.to_string(), type_ids_PolicyMode)) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "safe_edge::common::PolicyMode already registered in TypeObjectRegistry for a different type."); + } + } +} +} // namespace common + +} // namespace safe_edge + diff --git a/fast_dds/idl/commonTypeObjectSupport.hpp b/fast_dds/idl/commonTypeObjectSupport.hpp new file mode 100644 index 0000000..9a2be3b --- /dev/null +++ b/fast_dds/idl/commonTypeObjectSupport.hpp @@ -0,0 +1,114 @@ +// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/*! + * @file commonTypeObjectSupport.hpp + * Header file containing the API required to register the TypeObject representation of the described types in the IDL file + * + * This file was generated by the tool fastddsgen (version: 4.3.0). + */ + +#ifndef FAST_DDS_GENERATED__SAFE_EDGE_COMMON_COMMON_TYPE_OBJECT_SUPPORT_HPP +#define FAST_DDS_GENERATED__SAFE_EDGE_COMMON_COMMON_TYPE_OBJECT_SUPPORT_HPP + +#include + + +#if defined(_WIN32) +#if defined(EPROSIMA_USER_DLL_EXPORT) +#define eProsima_user_DllExport __declspec( dllexport ) +#else +#define eProsima_user_DllExport +#endif // EPROSIMA_USER_DLL_EXPORT +#else +#define eProsima_user_DllExport +#endif // _WIN32 + +#ifndef DOXYGEN_SHOULD_SKIP_THIS_PUBLIC + +namespace safe_edge { +namespace common { +/** + * @brief Register Header related TypeIdentifier. + * Fully-descriptive TypeIdentifiers are directly registered. + * Hash TypeIdentifiers require to fill the TypeObject information and hash it, consequently, the TypeObject is + * indirectly registered as well. + * + * @param[out] type_ids TypeIdentifier of the registered type. + * The returned TypeIdentifier corresponds to the complete TypeIdentifier in case of hashed TypeIdentifiers. + * Invalid TypeIdentifier is returned in case of error. + */ +eProsima_user_DllExport void register_Header_type_identifier( + eprosima::fastdds::dds::xtypes::TypeIdentifierPair& type_ids); + +/** + * @brief Register GeoPoint related TypeIdentifier. + * Fully-descriptive TypeIdentifiers are directly registered. + * Hash TypeIdentifiers require to fill the TypeObject information and hash it, consequently, the TypeObject is + * indirectly registered as well. + * + * @param[out] type_ids TypeIdentifier of the registered type. + * The returned TypeIdentifier corresponds to the complete TypeIdentifier in case of hashed TypeIdentifiers. + * Invalid TypeIdentifier is returned in case of error. + */ +eProsima_user_DllExport void register_GeoPoint_type_identifier( + eprosima::fastdds::dds::xtypes::TypeIdentifierPair& type_ids); + +/** + * @brief Register HealthStatus related TypeIdentifier. + * Fully-descriptive TypeIdentifiers are directly registered. + * Hash TypeIdentifiers require to fill the TypeObject information and hash it, consequently, the TypeObject is + * indirectly registered as well. + * + * @param[out] type_ids TypeIdentifier of the registered type. + * The returned TypeIdentifier corresponds to the complete TypeIdentifier in case of hashed TypeIdentifiers. + * Invalid TypeIdentifier is returned in case of error. + */ +eProsima_user_DllExport void register_HealthStatus_type_identifier( + eprosima::fastdds::dds::xtypes::TypeIdentifierPair& type_ids); + +/** + * @brief Register ServiceHeartbeat related TypeIdentifier. + * Fully-descriptive TypeIdentifiers are directly registered. + * Hash TypeIdentifiers require to fill the TypeObject information and hash it, consequently, the TypeObject is + * indirectly registered as well. + * + * @param[out] type_ids TypeIdentifier of the registered type. + * The returned TypeIdentifier corresponds to the complete TypeIdentifier in case of hashed TypeIdentifiers. + * Invalid TypeIdentifier is returned in case of error. + */ +eProsima_user_DllExport void register_ServiceHeartbeat_type_identifier( + eprosima::fastdds::dds::xtypes::TypeIdentifierPair& type_ids); + +/** + * @brief Register PolicyMode related TypeIdentifier. + * Fully-descriptive TypeIdentifiers are directly registered. + * Hash TypeIdentifiers require to fill the TypeObject information and hash it, consequently, the TypeObject is + * indirectly registered as well. + * + * @param[out] type_ids TypeIdentifier of the registered type. + * The returned TypeIdentifier corresponds to the complete TypeIdentifier in case of hashed TypeIdentifiers. + * Invalid TypeIdentifier is returned in case of error. + */ +eProsima_user_DllExport void register_PolicyMode_type_identifier( + eprosima::fastdds::dds::xtypes::TypeIdentifierPair& type_ids); + +} // namespace common + +} // namespace safe_edge + + +#endif // DOXYGEN_SHOULD_SKIP_THIS_PUBLIC + +#endif // FAST_DDS_GENERATED__SAFE_EDGE_COMMON_COMMON_TYPE_OBJECT_SUPPORT_HPP diff --git a/fast_dds/idl/edge.hpp b/fast_dds/idl/edge.hpp new file mode 100644 index 0000000..7231574 --- /dev/null +++ b/fast_dds/idl/edge.hpp @@ -0,0 +1,892 @@ +// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/*! + * @file edge.hpp + * This header file contains the declaration of the described types in the IDL file. + * + * This file was generated by the tool fastddsgen (version: 4.3.0). + */ + +#ifndef FAST_DDS_GENERATED__SAFE_EDGE_EDGE_EDGE_HPP +#define FAST_DDS_GENERATED__SAFE_EDGE_EDGE_EDGE_HPP + +#include +#include +#include +#include +#include "common.hpp" + +#if defined(_WIN32) +#if defined(EPROSIMA_USER_DLL_EXPORT) +#define eProsima_user_DllExport __declspec( dllexport ) +#else +#define eProsima_user_DllExport +#endif // EPROSIMA_USER_DLL_EXPORT +#else +#define eProsima_user_DllExport +#endif // _WIN32 + +#if defined(_WIN32) +#if defined(EPROSIMA_USER_DLL_EXPORT) +#if defined(EDGE_SOURCE) +#define EDGE_DllAPI __declspec( dllexport ) +#else +#define EDGE_DllAPI __declspec( dllimport ) +#endif // EDGE_SOURCE +#else +#define EDGE_DllAPI +#endif // EPROSIMA_USER_DLL_EXPORT +#else +#define EDGE_DllAPI +#endif // _WIN32 + +namespace safe_edge { + +namespace edge { + +/*! + * @brief This class represents the structure VehicleEdgeSummary defined by the user in the IDL file. + * @ingroup edge + */ +class VehicleEdgeSummary +{ +public: + + /*! + * @brief Default constructor. + */ + eProsima_user_DllExport VehicleEdgeSummary() + { + } + + /*! + * @brief Default destructor. + */ + eProsima_user_DllExport ~VehicleEdgeSummary() + { + } + + /*! + * @brief Copy constructor. + * @param x Reference to the object VehicleEdgeSummary that will be copied. + */ + eProsima_user_DllExport VehicleEdgeSummary( + const VehicleEdgeSummary& x) + { + m_header = x.m_header; + + m_soc_pct = x.m_soc_pct; + + m_current_mode = x.m_current_mode; + + m_vehicle_health = x.m_vehicle_health; + + m_v2g_ready = x.m_v2g_ready; + + } + + /*! + * @brief Move constructor. + * @param x Reference to the object VehicleEdgeSummary that will be copied. + */ + eProsima_user_DllExport VehicleEdgeSummary( + VehicleEdgeSummary&& x) noexcept + { + m_header = std::move(x.m_header); + m_soc_pct = x.m_soc_pct; + m_current_mode = x.m_current_mode; + m_vehicle_health = x.m_vehicle_health; + m_v2g_ready = x.m_v2g_ready; + } + + /*! + * @brief Copy assignment. + * @param x Reference to the object VehicleEdgeSummary that will be copied. + */ + eProsima_user_DllExport VehicleEdgeSummary& operator =( + const VehicleEdgeSummary& x) + { + + m_header = x.m_header; + + m_soc_pct = x.m_soc_pct; + + m_current_mode = x.m_current_mode; + + m_vehicle_health = x.m_vehicle_health; + + m_v2g_ready = x.m_v2g_ready; + + return *this; + } + + /*! + * @brief Move assignment. + * @param x Reference to the object VehicleEdgeSummary that will be copied. + */ + eProsima_user_DllExport VehicleEdgeSummary& operator =( + VehicleEdgeSummary&& x) noexcept + { + + m_header = std::move(x.m_header); + m_soc_pct = x.m_soc_pct; + m_current_mode = x.m_current_mode; + m_vehicle_health = x.m_vehicle_health; + m_v2g_ready = x.m_v2g_ready; + return *this; + } + + /*! + * @brief Comparison operator. + * @param x VehicleEdgeSummary object to compare. + */ + eProsima_user_DllExport bool operator ==( + const VehicleEdgeSummary& x) const + { + return (m_header == x.m_header && + m_soc_pct == x.m_soc_pct && + m_current_mode == x.m_current_mode && + m_vehicle_health == x.m_vehicle_health && + m_v2g_ready == x.m_v2g_ready); + } + + /*! + * @brief Comparison operator. + * @param x VehicleEdgeSummary object to compare. + */ + eProsima_user_DllExport bool operator !=( + const VehicleEdgeSummary& x) const + { + return !(*this == x); + } + + /*! + * @brief This function copies the value in member header + * @param _header New value to be copied in member header + */ + eProsima_user_DllExport void header( + const safe_edge::common::Header& _header) + { + m_header = _header; + } + + /*! + * @brief This function moves the value in member header + * @param _header New value to be moved in member header + */ + eProsima_user_DllExport void header( + safe_edge::common::Header&& _header) + { + m_header = std::move(_header); + } + + /*! + * @brief This function returns a constant reference to member header + * @return Constant reference to member header + */ + eProsima_user_DllExport const safe_edge::common::Header& header() const + { + return m_header; + } + + /*! + * @brief This function returns a reference to member header + * @return Reference to member header + */ + eProsima_user_DllExport safe_edge::common::Header& header() + { + return m_header; + } + + + /*! + * @brief This function sets a value in member soc_pct + * @param _soc_pct New value for member soc_pct + */ + eProsima_user_DllExport void soc_pct( + float _soc_pct) + { + m_soc_pct = _soc_pct; + } + + /*! + * @brief This function returns the value of member soc_pct + * @return Value of member soc_pct + */ + eProsima_user_DllExport float soc_pct() const + { + return m_soc_pct; + } + + /*! + * @brief This function returns a reference to member soc_pct + * @return Reference to member soc_pct + */ + eProsima_user_DllExport float& soc_pct() + { + return m_soc_pct; + } + + + /*! + * @brief This function sets a value in member current_mode + * @param _current_mode New value for member current_mode + */ + eProsima_user_DllExport void current_mode( + safe_edge::common::PolicyMode _current_mode) + { + m_current_mode = _current_mode; + } + + /*! + * @brief This function returns the value of member current_mode + * @return Value of member current_mode + */ + eProsima_user_DllExport safe_edge::common::PolicyMode current_mode() const + { + return m_current_mode; + } + + /*! + * @brief This function returns a reference to member current_mode + * @return Reference to member current_mode + */ + eProsima_user_DllExport safe_edge::common::PolicyMode& current_mode() + { + return m_current_mode; + } + + + /*! + * @brief This function sets a value in member vehicle_health + * @param _vehicle_health New value for member vehicle_health + */ + eProsima_user_DllExport void vehicle_health( + safe_edge::common::HealthStatus _vehicle_health) + { + m_vehicle_health = _vehicle_health; + } + + /*! + * @brief This function returns the value of member vehicle_health + * @return Value of member vehicle_health + */ + eProsima_user_DllExport safe_edge::common::HealthStatus vehicle_health() const + { + return m_vehicle_health; + } + + /*! + * @brief This function returns a reference to member vehicle_health + * @return Reference to member vehicle_health + */ + eProsima_user_DllExport safe_edge::common::HealthStatus& vehicle_health() + { + return m_vehicle_health; + } + + + /*! + * @brief This function sets a value in member v2g_ready + * @param _v2g_ready New value for member v2g_ready + */ + eProsima_user_DllExport void v2g_ready( + bool _v2g_ready) + { + m_v2g_ready = _v2g_ready; + } + + /*! + * @brief This function returns the value of member v2g_ready + * @return Value of member v2g_ready + */ + eProsima_user_DllExport bool v2g_ready() const + { + return m_v2g_ready; + } + + /*! + * @brief This function returns a reference to member v2g_ready + * @return Reference to member v2g_ready + */ + eProsima_user_DllExport bool& v2g_ready() + { + return m_v2g_ready; + } + + + +private: + + safe_edge::common::Header m_header; + float m_soc_pct{0.0}; + safe_edge::common::PolicyMode m_current_mode{safe_edge::common::PolicyMode::POLICY_UNKNOWN}; + safe_edge::common::HealthStatus m_vehicle_health{safe_edge::common::HealthStatus::HEALTH_UNKNOWN}; + bool m_v2g_ready{false}; + +}; +/*! + * @brief This class represents the structure EnergyAdvisory defined by the user in the IDL file. + * @ingroup edge + */ +class EnergyAdvisory +{ +public: + + /*! + * @brief Default constructor. + */ + eProsima_user_DllExport EnergyAdvisory() + { + } + + /*! + * @brief Default destructor. + */ + eProsima_user_DllExport ~EnergyAdvisory() + { + } + + /*! + * @brief Copy constructor. + * @param x Reference to the object EnergyAdvisory that will be copied. + */ + eProsima_user_DllExport EnergyAdvisory( + const EnergyAdvisory& x) + { + m_header = x.m_header; + + m_suggested_mode = x.m_suggested_mode; + + m_advisory_reason = x.m_advisory_reason; + + m_recommended_charger_id = x.m_recommended_charger_id; + + m_target_soc_pct = x.m_target_soc_pct; + + } + + /*! + * @brief Move constructor. + * @param x Reference to the object EnergyAdvisory that will be copied. + */ + eProsima_user_DllExport EnergyAdvisory( + EnergyAdvisory&& x) noexcept + { + m_header = std::move(x.m_header); + m_suggested_mode = x.m_suggested_mode; + m_advisory_reason = std::move(x.m_advisory_reason); + m_recommended_charger_id = x.m_recommended_charger_id; + m_target_soc_pct = x.m_target_soc_pct; + } + + /*! + * @brief Copy assignment. + * @param x Reference to the object EnergyAdvisory that will be copied. + */ + eProsima_user_DllExport EnergyAdvisory& operator =( + const EnergyAdvisory& x) + { + + m_header = x.m_header; + + m_suggested_mode = x.m_suggested_mode; + + m_advisory_reason = x.m_advisory_reason; + + m_recommended_charger_id = x.m_recommended_charger_id; + + m_target_soc_pct = x.m_target_soc_pct; + + return *this; + } + + /*! + * @brief Move assignment. + * @param x Reference to the object EnergyAdvisory that will be copied. + */ + eProsima_user_DllExport EnergyAdvisory& operator =( + EnergyAdvisory&& x) noexcept + { + + m_header = std::move(x.m_header); + m_suggested_mode = x.m_suggested_mode; + m_advisory_reason = std::move(x.m_advisory_reason); + m_recommended_charger_id = x.m_recommended_charger_id; + m_target_soc_pct = x.m_target_soc_pct; + return *this; + } + + /*! + * @brief Comparison operator. + * @param x EnergyAdvisory object to compare. + */ + eProsima_user_DllExport bool operator ==( + const EnergyAdvisory& x) const + { + return (m_header == x.m_header && + m_suggested_mode == x.m_suggested_mode && + m_advisory_reason == x.m_advisory_reason && + m_recommended_charger_id == x.m_recommended_charger_id && + m_target_soc_pct == x.m_target_soc_pct); + } + + /*! + * @brief Comparison operator. + * @param x EnergyAdvisory object to compare. + */ + eProsima_user_DllExport bool operator !=( + const EnergyAdvisory& x) const + { + return !(*this == x); + } + + /*! + * @brief This function copies the value in member header + * @param _header New value to be copied in member header + */ + eProsima_user_DllExport void header( + const safe_edge::common::Header& _header) + { + m_header = _header; + } + + /*! + * @brief This function moves the value in member header + * @param _header New value to be moved in member header + */ + eProsima_user_DllExport void header( + safe_edge::common::Header&& _header) + { + m_header = std::move(_header); + } + + /*! + * @brief This function returns a constant reference to member header + * @return Constant reference to member header + */ + eProsima_user_DllExport const safe_edge::common::Header& header() const + { + return m_header; + } + + /*! + * @brief This function returns a reference to member header + * @return Reference to member header + */ + eProsima_user_DllExport safe_edge::common::Header& header() + { + return m_header; + } + + + /*! + * @brief This function sets a value in member suggested_mode + * @param _suggested_mode New value for member suggested_mode + */ + eProsima_user_DllExport void suggested_mode( + safe_edge::common::PolicyMode _suggested_mode) + { + m_suggested_mode = _suggested_mode; + } + + /*! + * @brief This function returns the value of member suggested_mode + * @return Value of member suggested_mode + */ + eProsima_user_DllExport safe_edge::common::PolicyMode suggested_mode() const + { + return m_suggested_mode; + } + + /*! + * @brief This function returns a reference to member suggested_mode + * @return Reference to member suggested_mode + */ + eProsima_user_DllExport safe_edge::common::PolicyMode& suggested_mode() + { + return m_suggested_mode; + } + + + /*! + * @brief This function copies the value in member advisory_reason + * @param _advisory_reason New value to be copied in member advisory_reason + */ + eProsima_user_DllExport void advisory_reason( + const std::string& _advisory_reason) + { + m_advisory_reason = _advisory_reason; + } + + /*! + * @brief This function moves the value in member advisory_reason + * @param _advisory_reason New value to be moved in member advisory_reason + */ + eProsima_user_DllExport void advisory_reason( + std::string&& _advisory_reason) + { + m_advisory_reason = std::move(_advisory_reason); + } + + /*! + * @brief This function returns a constant reference to member advisory_reason + * @return Constant reference to member advisory_reason + */ + eProsima_user_DllExport const std::string& advisory_reason() const + { + return m_advisory_reason; + } + + /*! + * @brief This function returns a reference to member advisory_reason + * @return Reference to member advisory_reason + */ + eProsima_user_DllExport std::string& advisory_reason() + { + return m_advisory_reason; + } + + + /*! + * @brief This function sets a value in member recommended_charger_id + * @param _recommended_charger_id New value for member recommended_charger_id + */ + eProsima_user_DllExport void recommended_charger_id( + int32_t _recommended_charger_id) + { + m_recommended_charger_id = _recommended_charger_id; + } + + /*! + * @brief This function returns the value of member recommended_charger_id + * @return Value of member recommended_charger_id + */ + eProsima_user_DllExport int32_t recommended_charger_id() const + { + return m_recommended_charger_id; + } + + /*! + * @brief This function returns a reference to member recommended_charger_id + * @return Reference to member recommended_charger_id + */ + eProsima_user_DllExport int32_t& recommended_charger_id() + { + return m_recommended_charger_id; + } + + + /*! + * @brief This function sets a value in member target_soc_pct + * @param _target_soc_pct New value for member target_soc_pct + */ + eProsima_user_DllExport void target_soc_pct( + float _target_soc_pct) + { + m_target_soc_pct = _target_soc_pct; + } + + /*! + * @brief This function returns the value of member target_soc_pct + * @return Value of member target_soc_pct + */ + eProsima_user_DllExport float target_soc_pct() const + { + return m_target_soc_pct; + } + + /*! + * @brief This function returns a reference to member target_soc_pct + * @return Reference to member target_soc_pct + */ + eProsima_user_DllExport float& target_soc_pct() + { + return m_target_soc_pct; + } + + + +private: + + safe_edge::common::Header m_header; + safe_edge::common::PolicyMode m_suggested_mode{safe_edge::common::PolicyMode::POLICY_UNKNOWN}; + std::string m_advisory_reason; + int32_t m_recommended_charger_id{0}; + float m_target_soc_pct{0.0}; + +}; +/*! + * @brief This class represents the structure EdgeGatewayStatus defined by the user in the IDL file. + * @ingroup edge + */ +class EdgeGatewayStatus +{ +public: + + /*! + * @brief Default constructor. + */ + eProsima_user_DllExport EdgeGatewayStatus() + { + } + + /*! + * @brief Default destructor. + */ + eProsima_user_DllExport ~EdgeGatewayStatus() + { + } + + /*! + * @brief Copy constructor. + * @param x Reference to the object EdgeGatewayStatus that will be copied. + */ + eProsima_user_DllExport EdgeGatewayStatus( + const EdgeGatewayStatus& x) + { + m_header = x.m_header; + + m_status = x.m_status; + + m_last_server_sync_ms = x.m_last_server_sync_ms; + + m_detail = x.m_detail; + + } + + /*! + * @brief Move constructor. + * @param x Reference to the object EdgeGatewayStatus that will be copied. + */ + eProsima_user_DllExport EdgeGatewayStatus( + EdgeGatewayStatus&& x) noexcept + { + m_header = std::move(x.m_header); + m_status = x.m_status; + m_last_server_sync_ms = x.m_last_server_sync_ms; + m_detail = std::move(x.m_detail); + } + + /*! + * @brief Copy assignment. + * @param x Reference to the object EdgeGatewayStatus that will be copied. + */ + eProsima_user_DllExport EdgeGatewayStatus& operator =( + const EdgeGatewayStatus& x) + { + + m_header = x.m_header; + + m_status = x.m_status; + + m_last_server_sync_ms = x.m_last_server_sync_ms; + + m_detail = x.m_detail; + + return *this; + } + + /*! + * @brief Move assignment. + * @param x Reference to the object EdgeGatewayStatus that will be copied. + */ + eProsima_user_DllExport EdgeGatewayStatus& operator =( + EdgeGatewayStatus&& x) noexcept + { + + m_header = std::move(x.m_header); + m_status = x.m_status; + m_last_server_sync_ms = x.m_last_server_sync_ms; + m_detail = std::move(x.m_detail); + return *this; + } + + /*! + * @brief Comparison operator. + * @param x EdgeGatewayStatus object to compare. + */ + eProsima_user_DllExport bool operator ==( + const EdgeGatewayStatus& x) const + { + return (m_header == x.m_header && + m_status == x.m_status && + m_last_server_sync_ms == x.m_last_server_sync_ms && + m_detail == x.m_detail); + } + + /*! + * @brief Comparison operator. + * @param x EdgeGatewayStatus object to compare. + */ + eProsima_user_DllExport bool operator !=( + const EdgeGatewayStatus& x) const + { + return !(*this == x); + } + + /*! + * @brief This function copies the value in member header + * @param _header New value to be copied in member header + */ + eProsima_user_DllExport void header( + const safe_edge::common::Header& _header) + { + m_header = _header; + } + + /*! + * @brief This function moves the value in member header + * @param _header New value to be moved in member header + */ + eProsima_user_DllExport void header( + safe_edge::common::Header&& _header) + { + m_header = std::move(_header); + } + + /*! + * @brief This function returns a constant reference to member header + * @return Constant reference to member header + */ + eProsima_user_DllExport const safe_edge::common::Header& header() const + { + return m_header; + } + + /*! + * @brief This function returns a reference to member header + * @return Reference to member header + */ + eProsima_user_DllExport safe_edge::common::Header& header() + { + return m_header; + } + + + /*! + * @brief This function sets a value in member status + * @param _status New value for member status + */ + eProsima_user_DllExport void status( + safe_edge::common::HealthStatus _status) + { + m_status = _status; + } + + /*! + * @brief This function returns the value of member status + * @return Value of member status + */ + eProsima_user_DllExport safe_edge::common::HealthStatus status() const + { + return m_status; + } + + /*! + * @brief This function returns a reference to member status + * @return Reference to member status + */ + eProsima_user_DllExport safe_edge::common::HealthStatus& status() + { + return m_status; + } + + + /*! + * @brief This function sets a value in member last_server_sync_ms + * @param _last_server_sync_ms New value for member last_server_sync_ms + */ + eProsima_user_DllExport void last_server_sync_ms( + uint64_t _last_server_sync_ms) + { + m_last_server_sync_ms = _last_server_sync_ms; + } + + /*! + * @brief This function returns the value of member last_server_sync_ms + * @return Value of member last_server_sync_ms + */ + eProsima_user_DllExport uint64_t last_server_sync_ms() const + { + return m_last_server_sync_ms; + } + + /*! + * @brief This function returns a reference to member last_server_sync_ms + * @return Reference to member last_server_sync_ms + */ + eProsima_user_DllExport uint64_t& last_server_sync_ms() + { + return m_last_server_sync_ms; + } + + + /*! + * @brief This function copies the value in member detail + * @param _detail New value to be copied in member detail + */ + eProsima_user_DllExport void detail( + const std::string& _detail) + { + m_detail = _detail; + } + + /*! + * @brief This function moves the value in member detail + * @param _detail New value to be moved in member detail + */ + eProsima_user_DllExport void detail( + std::string&& _detail) + { + m_detail = std::move(_detail); + } + + /*! + * @brief This function returns a constant reference to member detail + * @return Constant reference to member detail + */ + eProsima_user_DllExport const std::string& detail() const + { + return m_detail; + } + + /*! + * @brief This function returns a reference to member detail + * @return Reference to member detail + */ + eProsima_user_DllExport std::string& detail() + { + return m_detail; + } + + + +private: + + safe_edge::common::Header m_header; + safe_edge::common::HealthStatus m_status{safe_edge::common::HealthStatus::HEALTH_UNKNOWN}; + uint64_t m_last_server_sync_ms{0}; + std::string m_detail; + +}; + +} // namespace edge + +} // namespace safe_edge + +#endif // _FAST_DDS_GENERATED_SAFE_EDGE_EDGE_EDGE_HPP_ + + diff --git a/fast_dds/idl/edgeCdrAux.hpp b/fast_dds/idl/edgeCdrAux.hpp new file mode 100644 index 0000000..f8e126b --- /dev/null +++ b/fast_dds/idl/edgeCdrAux.hpp @@ -0,0 +1,63 @@ +// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/*! + * @file edgeCdrAux.hpp + * This source file contains some definitions of CDR related functions. + * + * This file was generated by the tool fastddsgen (version: 4.3.0). + */ + +#ifndef FAST_DDS_GENERATED__SAFE_EDGE_EDGE_EDGECDRAUX_HPP +#define FAST_DDS_GENERATED__SAFE_EDGE_EDGE_EDGECDRAUX_HPP + +#include "edge.hpp" + +constexpr uint32_t safe_edge_edge_EnergyAdvisory_max_cdr_typesize {812UL}; +constexpr uint32_t safe_edge_edge_EnergyAdvisory_max_key_cdr_typesize {0UL}; + + +constexpr uint32_t safe_edge_edge_EdgeGatewayStatus_max_cdr_typesize {812UL}; +constexpr uint32_t safe_edge_edge_EdgeGatewayStatus_max_key_cdr_typesize {0UL}; + +constexpr uint32_t safe_edge_edge_VehicleEdgeSummary_max_cdr_typesize {553UL}; +constexpr uint32_t safe_edge_edge_VehicleEdgeSummary_max_key_cdr_typesize {0UL}; + + + + +namespace eprosima { +namespace fastcdr { + +class Cdr; +class CdrSizeCalculator; + +eProsima_user_DllExport void serialize_key( + eprosima::fastcdr::Cdr& scdr, + const safe_edge::edge::VehicleEdgeSummary& data); + +eProsima_user_DllExport void serialize_key( + eprosima::fastcdr::Cdr& scdr, + const safe_edge::edge::EnergyAdvisory& data); + +eProsima_user_DllExport void serialize_key( + eprosima::fastcdr::Cdr& scdr, + const safe_edge::edge::EdgeGatewayStatus& data); + + +} // namespace fastcdr +} // namespace eprosima + +#endif // FAST_DDS_GENERATED__SAFE_EDGE_EDGE_EDGECDRAUX_HPP + diff --git a/fast_dds/idl/edgeCdrAux.ipp b/fast_dds/idl/edgeCdrAux.ipp new file mode 100644 index 0000000..4a5a4c4 --- /dev/null +++ b/fast_dds/idl/edgeCdrAux.ipp @@ -0,0 +1,433 @@ +// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/*! + * @file edgeCdrAux.ipp + * This source file contains some declarations of CDR related functions. + * + * This file was generated by the tool fastddsgen (version: 4.3.0). + */ + +#ifndef FAST_DDS_GENERATED__SAFE_EDGE_EDGE_EDGECDRAUX_IPP +#define FAST_DDS_GENERATED__SAFE_EDGE_EDGE_EDGECDRAUX_IPP + +#include "edgeCdrAux.hpp" + +#include +#include + + +#include +using namespace eprosima::fastcdr::exception; + +namespace eprosima { +namespace fastcdr { + +template<> +eProsima_user_DllExport size_t calculate_serialized_size( + eprosima::fastcdr::CdrSizeCalculator& calculator, + const safe_edge::edge::VehicleEdgeSummary& data, + size_t& current_alignment) +{ + using namespace safe_edge::edge; + + static_cast(data); + + eprosima::fastcdr::EncodingAlgorithmFlag previous_encoding = calculator.get_encoding(); + size_t calculated_size {calculator.begin_calculate_type_serialized_size( + eprosima::fastcdr::CdrVersion::XCDRv2 == calculator.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, + current_alignment)}; + + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(0), + data.header(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(1), + data.soc_pct(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(2), + data.current_mode(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(3), + data.vehicle_health(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(4), + data.v2g_ready(), current_alignment); + + + calculated_size += calculator.end_calculate_type_serialized_size(previous_encoding, current_alignment); + + return calculated_size; +} + +template<> +eProsima_user_DllExport void serialize( + eprosima::fastcdr::Cdr& scdr, + const safe_edge::edge::VehicleEdgeSummary& data) +{ + using namespace safe_edge::edge; + + eprosima::fastcdr::Cdr::state current_state(scdr); + scdr.begin_serialize_type(current_state, + eprosima::fastcdr::CdrVersion::XCDRv2 == scdr.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR); + + scdr + << eprosima::fastcdr::MemberId(0) << data.header() + << eprosima::fastcdr::MemberId(1) << data.soc_pct() + << eprosima::fastcdr::MemberId(2) << data.current_mode() + << eprosima::fastcdr::MemberId(3) << data.vehicle_health() + << eprosima::fastcdr::MemberId(4) << data.v2g_ready() +; + scdr.end_serialize_type(current_state); +} + +template<> +eProsima_user_DllExport void deserialize( + eprosima::fastcdr::Cdr& cdr, + safe_edge::edge::VehicleEdgeSummary& data) +{ + using namespace safe_edge::edge; + + cdr.deserialize_type(eprosima::fastcdr::CdrVersion::XCDRv2 == cdr.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, + [&data](eprosima::fastcdr::Cdr& dcdr, const eprosima::fastcdr::MemberId& mid) -> bool + { + bool ret_value = true; + switch (mid.id) + { + case 0: + dcdr >> data.header(); + break; + + case 1: + dcdr >> data.soc_pct(); + break; + + case 2: + dcdr >> data.current_mode(); + break; + + case 3: + dcdr >> data.vehicle_health(); + break; + + case 4: + dcdr >> data.v2g_ready(); + break; + + default: + ret_value = false; + break; + } + return ret_value; + }); +} + +void serialize_key( + eprosima::fastcdr::Cdr& scdr, + const safe_edge::edge::VehicleEdgeSummary& data) +{ + using namespace safe_edge::edge; + extern void serialize_key( + Cdr& scdr, + const safe_edge::common::Header& data); + + + + + + + static_cast(scdr); + static_cast(data); + serialize_key(scdr, data.header()); + + scdr << data.soc_pct(); + + scdr << data.current_mode(); + + scdr << data.vehicle_health(); + + scdr << data.v2g_ready(); + +} + + +template<> +eProsima_user_DllExport size_t calculate_serialized_size( + eprosima::fastcdr::CdrSizeCalculator& calculator, + const safe_edge::edge::EnergyAdvisory& data, + size_t& current_alignment) +{ + using namespace safe_edge::edge; + + static_cast(data); + + eprosima::fastcdr::EncodingAlgorithmFlag previous_encoding = calculator.get_encoding(); + size_t calculated_size {calculator.begin_calculate_type_serialized_size( + eprosima::fastcdr::CdrVersion::XCDRv2 == calculator.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, + current_alignment)}; + + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(0), + data.header(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(1), + data.suggested_mode(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(2), + data.advisory_reason(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(3), + data.recommended_charger_id(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(4), + data.target_soc_pct(), current_alignment); + + + calculated_size += calculator.end_calculate_type_serialized_size(previous_encoding, current_alignment); + + return calculated_size; +} + +template<> +eProsima_user_DllExport void serialize( + eprosima::fastcdr::Cdr& scdr, + const safe_edge::edge::EnergyAdvisory& data) +{ + using namespace safe_edge::edge; + + eprosima::fastcdr::Cdr::state current_state(scdr); + scdr.begin_serialize_type(current_state, + eprosima::fastcdr::CdrVersion::XCDRv2 == scdr.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR); + + scdr + << eprosima::fastcdr::MemberId(0) << data.header() + << eprosima::fastcdr::MemberId(1) << data.suggested_mode() + << eprosima::fastcdr::MemberId(2) << data.advisory_reason() + << eprosima::fastcdr::MemberId(3) << data.recommended_charger_id() + << eprosima::fastcdr::MemberId(4) << data.target_soc_pct() +; + scdr.end_serialize_type(current_state); +} + +template<> +eProsima_user_DllExport void deserialize( + eprosima::fastcdr::Cdr& cdr, + safe_edge::edge::EnergyAdvisory& data) +{ + using namespace safe_edge::edge; + + cdr.deserialize_type(eprosima::fastcdr::CdrVersion::XCDRv2 == cdr.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, + [&data](eprosima::fastcdr::Cdr& dcdr, const eprosima::fastcdr::MemberId& mid) -> bool + { + bool ret_value = true; + switch (mid.id) + { + case 0: + dcdr >> data.header(); + break; + + case 1: + dcdr >> data.suggested_mode(); + break; + + case 2: + dcdr >> data.advisory_reason(); + break; + + case 3: + dcdr >> data.recommended_charger_id(); + break; + + case 4: + dcdr >> data.target_soc_pct(); + break; + + default: + ret_value = false; + break; + } + return ret_value; + }); +} + +void serialize_key( + eprosima::fastcdr::Cdr& scdr, + const safe_edge::edge::EnergyAdvisory& data) +{ + using namespace safe_edge::edge; + extern void serialize_key( + Cdr& scdr, + const safe_edge::common::Header& data); + + + + + + + static_cast(scdr); + static_cast(data); + serialize_key(scdr, data.header()); + + scdr << data.suggested_mode(); + + scdr << data.advisory_reason(); + + scdr << data.recommended_charger_id(); + + scdr << data.target_soc_pct(); + +} + + +template<> +eProsima_user_DllExport size_t calculate_serialized_size( + eprosima::fastcdr::CdrSizeCalculator& calculator, + const safe_edge::edge::EdgeGatewayStatus& data, + size_t& current_alignment) +{ + using namespace safe_edge::edge; + + static_cast(data); + + eprosima::fastcdr::EncodingAlgorithmFlag previous_encoding = calculator.get_encoding(); + size_t calculated_size {calculator.begin_calculate_type_serialized_size( + eprosima::fastcdr::CdrVersion::XCDRv2 == calculator.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, + current_alignment)}; + + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(0), + data.header(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(1), + data.status(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(2), + data.last_server_sync_ms(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(3), + data.detail(), current_alignment); + + + calculated_size += calculator.end_calculate_type_serialized_size(previous_encoding, current_alignment); + + return calculated_size; +} + +template<> +eProsima_user_DllExport void serialize( + eprosima::fastcdr::Cdr& scdr, + const safe_edge::edge::EdgeGatewayStatus& data) +{ + using namespace safe_edge::edge; + + eprosima::fastcdr::Cdr::state current_state(scdr); + scdr.begin_serialize_type(current_state, + eprosima::fastcdr::CdrVersion::XCDRv2 == scdr.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR); + + scdr + << eprosima::fastcdr::MemberId(0) << data.header() + << eprosima::fastcdr::MemberId(1) << data.status() + << eprosima::fastcdr::MemberId(2) << data.last_server_sync_ms() + << eprosima::fastcdr::MemberId(3) << data.detail() +; + scdr.end_serialize_type(current_state); +} + +template<> +eProsima_user_DllExport void deserialize( + eprosima::fastcdr::Cdr& cdr, + safe_edge::edge::EdgeGatewayStatus& data) +{ + using namespace safe_edge::edge; + + cdr.deserialize_type(eprosima::fastcdr::CdrVersion::XCDRv2 == cdr.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, + [&data](eprosima::fastcdr::Cdr& dcdr, const eprosima::fastcdr::MemberId& mid) -> bool + { + bool ret_value = true; + switch (mid.id) + { + case 0: + dcdr >> data.header(); + break; + + case 1: + dcdr >> data.status(); + break; + + case 2: + dcdr >> data.last_server_sync_ms(); + break; + + case 3: + dcdr >> data.detail(); + break; + + default: + ret_value = false; + break; + } + return ret_value; + }); +} + +void serialize_key( + eprosima::fastcdr::Cdr& scdr, + const safe_edge::edge::EdgeGatewayStatus& data) +{ + using namespace safe_edge::edge; + extern void serialize_key( + Cdr& scdr, + const safe_edge::common::Header& data); + + + + + + static_cast(scdr); + static_cast(data); + serialize_key(scdr, data.header()); + + scdr << data.status(); + + scdr << data.last_server_sync_ms(); + + scdr << data.detail(); + +} + + + +} // namespace fastcdr +} // namespace eprosima + +#endif // FAST_DDS_GENERATED__SAFE_EDGE_EDGE_EDGECDRAUX_IPP + diff --git a/fast_dds/idl/edgePubSubTypes.cxx b/fast_dds/idl/edgePubSubTypes.cxx new file mode 100644 index 0000000..64ed959 --- /dev/null +++ b/fast_dds/idl/edgePubSubTypes.cxx @@ -0,0 +1,474 @@ +// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/*! + * @file edgePubSubTypes.cpp + * This header file contains the implementation of the serialization functions. + * + * This file was generated by the tool fastddsgen (version: 4.3.0). + */ + +#include "edgePubSubTypes.hpp" + +#include +#include + +#include +#include + +#include "edgeCdrAux.hpp" +#include "edgeTypeObjectSupport.hpp" + +using SerializedPayload_t = eprosima::fastdds::rtps::SerializedPayload_t; +using InstanceHandle_t = eprosima::fastdds::rtps::InstanceHandle_t; +using DataRepresentationId_t = eprosima::fastdds::dds::DataRepresentationId_t; + +namespace safe_edge { +namespace edge { +VehicleEdgeSummaryPubSubType::VehicleEdgeSummaryPubSubType() +{ + set_name("safe_edge::edge::VehicleEdgeSummary"); + uint32_t type_size = safe_edge_edge_VehicleEdgeSummary_max_cdr_typesize; + type_size += static_cast(eprosima::fastcdr::Cdr::alignment(type_size, 4)); /* possible submessage alignment */ + max_serialized_type_size = type_size + 4; /*encapsulation*/ + is_compute_key_provided = false; +} + +VehicleEdgeSummaryPubSubType::~VehicleEdgeSummaryPubSubType() +{ +} + +bool VehicleEdgeSummaryPubSubType::serialize( + const void* const data, + SerializedPayload_t& payload, + DataRepresentationId_t data_representation) +{ + const ::safe_edge::edge::VehicleEdgeSummary* p_type = + static_cast(data); + + // Object that manages the raw buffer. + eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(payload.data), payload.max_size); + // Object that serializes the data. + eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN, + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::CdrVersion::XCDRv1 : eprosima::fastcdr::CdrVersion::XCDRv2); + payload.encapsulation = ser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE; + ser.set_encoding_flag( + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR : + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2); + + try + { + // Serialize encapsulation + ser.serialize_encapsulation(); + // Serialize the object. + ser << *p_type; + ser.set_dds_cdr_options({0, 0}); + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return false; + } + + // Get the serialized length + payload.length = static_cast(ser.get_serialized_data_length()); + return true; +} + +bool VehicleEdgeSummaryPubSubType::deserialize( + SerializedPayload_t& payload, + void* data) +{ + try + { + // Convert DATA to pointer of your type + ::safe_edge::edge::VehicleEdgeSummary* p_type = + static_cast<::safe_edge::edge::VehicleEdgeSummary*>(data); + + // Object that manages the raw buffer. + eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(payload.data), payload.length); + + // Object that deserializes the data. + eprosima::fastcdr::Cdr deser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN); + + // Deserialize encapsulation. + deser.read_encapsulation(); + payload.encapsulation = deser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE; + + // Deserialize the object. + deser >> *p_type; + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return false; + } + + return true; +} + +uint32_t VehicleEdgeSummaryPubSubType::calculate_serialized_size( + const void* const data, + DataRepresentationId_t data_representation) +{ + try + { + eprosima::fastcdr::CdrSizeCalculator calculator( + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::CdrVersion::XCDRv1 :eprosima::fastcdr::CdrVersion::XCDRv2); + size_t current_alignment {0}; + const ::safe_edge::edge::VehicleEdgeSummary* p_type = + static_cast(data); + auto calc_size = calculator.calculate_serialized_size(*p_type, current_alignment); + return static_cast(calc_size) + 4u /*encapsulation*/; + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return 0; + } +} + +void* VehicleEdgeSummaryPubSubType::create_data() +{ + return reinterpret_cast(new ::safe_edge::edge::VehicleEdgeSummary()); +} + +void VehicleEdgeSummaryPubSubType::delete_data( + void* data) +{ + delete(reinterpret_cast<::safe_edge::edge::VehicleEdgeSummary*>(data)); +} + +bool VehicleEdgeSummaryPubSubType::compute_key( + SerializedPayload_t& payload, + InstanceHandle_t& handle, + bool force_md5) +{ + static_cast(payload); + static_cast(handle); + static_cast(force_md5); + + return false; +} + +bool VehicleEdgeSummaryPubSubType::compute_key( + const void* const data, + InstanceHandle_t& handle, + bool force_md5) +{ + static_cast(data); + static_cast(handle); + static_cast(force_md5); + + return false; +} + +void VehicleEdgeSummaryPubSubType::register_type_object_representation() +{ + register_VehicleEdgeSummary_type_identifier(type_identifiers_); +} + +EnergyAdvisoryPubSubType::EnergyAdvisoryPubSubType() +{ + set_name("safe_edge::edge::EnergyAdvisory"); + uint32_t type_size = safe_edge_edge_EnergyAdvisory_max_cdr_typesize; + type_size += static_cast(eprosima::fastcdr::Cdr::alignment(type_size, 4)); /* possible submessage alignment */ + max_serialized_type_size = type_size + 4; /*encapsulation*/ + is_compute_key_provided = false; +} + +EnergyAdvisoryPubSubType::~EnergyAdvisoryPubSubType() +{ +} + +bool EnergyAdvisoryPubSubType::serialize( + const void* const data, + SerializedPayload_t& payload, + DataRepresentationId_t data_representation) +{ + const ::safe_edge::edge::EnergyAdvisory* p_type = + static_cast(data); + + // Object that manages the raw buffer. + eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(payload.data), payload.max_size); + // Object that serializes the data. + eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN, + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::CdrVersion::XCDRv1 : eprosima::fastcdr::CdrVersion::XCDRv2); + payload.encapsulation = ser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE; + ser.set_encoding_flag( + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR : + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2); + + try + { + // Serialize encapsulation + ser.serialize_encapsulation(); + // Serialize the object. + ser << *p_type; + ser.set_dds_cdr_options({0, 0}); + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return false; + } + + // Get the serialized length + payload.length = static_cast(ser.get_serialized_data_length()); + return true; +} + +bool EnergyAdvisoryPubSubType::deserialize( + SerializedPayload_t& payload, + void* data) +{ + try + { + // Convert DATA to pointer of your type + ::safe_edge::edge::EnergyAdvisory* p_type = + static_cast<::safe_edge::edge::EnergyAdvisory*>(data); + + // Object that manages the raw buffer. + eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(payload.data), payload.length); + + // Object that deserializes the data. + eprosima::fastcdr::Cdr deser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN); + + // Deserialize encapsulation. + deser.read_encapsulation(); + payload.encapsulation = deser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE; + + // Deserialize the object. + deser >> *p_type; + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return false; + } + + return true; +} + +uint32_t EnergyAdvisoryPubSubType::calculate_serialized_size( + const void* const data, + DataRepresentationId_t data_representation) +{ + try + { + eprosima::fastcdr::CdrSizeCalculator calculator( + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::CdrVersion::XCDRv1 :eprosima::fastcdr::CdrVersion::XCDRv2); + size_t current_alignment {0}; + const ::safe_edge::edge::EnergyAdvisory* p_type = + static_cast(data); + auto calc_size = calculator.calculate_serialized_size(*p_type, current_alignment); + return static_cast(calc_size) + 4u /*encapsulation*/; + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return 0; + } +} + +void* EnergyAdvisoryPubSubType::create_data() +{ + return reinterpret_cast(new ::safe_edge::edge::EnergyAdvisory()); +} + +void EnergyAdvisoryPubSubType::delete_data( + void* data) +{ + delete(reinterpret_cast<::safe_edge::edge::EnergyAdvisory*>(data)); +} + +bool EnergyAdvisoryPubSubType::compute_key( + SerializedPayload_t& payload, + InstanceHandle_t& handle, + bool force_md5) +{ + static_cast(payload); + static_cast(handle); + static_cast(force_md5); + + return false; +} + +bool EnergyAdvisoryPubSubType::compute_key( + const void* const data, + InstanceHandle_t& handle, + bool force_md5) +{ + static_cast(data); + static_cast(handle); + static_cast(force_md5); + + return false; +} + +void EnergyAdvisoryPubSubType::register_type_object_representation() +{ + register_EnergyAdvisory_type_identifier(type_identifiers_); +} + +EdgeGatewayStatusPubSubType::EdgeGatewayStatusPubSubType() +{ + set_name("safe_edge::edge::EdgeGatewayStatus"); + uint32_t type_size = safe_edge_edge_EdgeGatewayStatus_max_cdr_typesize; + type_size += static_cast(eprosima::fastcdr::Cdr::alignment(type_size, 4)); /* possible submessage alignment */ + max_serialized_type_size = type_size + 4; /*encapsulation*/ + is_compute_key_provided = false; +} + +EdgeGatewayStatusPubSubType::~EdgeGatewayStatusPubSubType() +{ +} + +bool EdgeGatewayStatusPubSubType::serialize( + const void* const data, + SerializedPayload_t& payload, + DataRepresentationId_t data_representation) +{ + const ::safe_edge::edge::EdgeGatewayStatus* p_type = + static_cast(data); + + // Object that manages the raw buffer. + eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(payload.data), payload.max_size); + // Object that serializes the data. + eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN, + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::CdrVersion::XCDRv1 : eprosima::fastcdr::CdrVersion::XCDRv2); + payload.encapsulation = ser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE; + ser.set_encoding_flag( + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR : + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2); + + try + { + // Serialize encapsulation + ser.serialize_encapsulation(); + // Serialize the object. + ser << *p_type; + ser.set_dds_cdr_options({0, 0}); + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return false; + } + + // Get the serialized length + payload.length = static_cast(ser.get_serialized_data_length()); + return true; +} + +bool EdgeGatewayStatusPubSubType::deserialize( + SerializedPayload_t& payload, + void* data) +{ + try + { + // Convert DATA to pointer of your type + ::safe_edge::edge::EdgeGatewayStatus* p_type = + static_cast<::safe_edge::edge::EdgeGatewayStatus*>(data); + + // Object that manages the raw buffer. + eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(payload.data), payload.length); + + // Object that deserializes the data. + eprosima::fastcdr::Cdr deser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN); + + // Deserialize encapsulation. + deser.read_encapsulation(); + payload.encapsulation = deser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE; + + // Deserialize the object. + deser >> *p_type; + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return false; + } + + return true; +} + +uint32_t EdgeGatewayStatusPubSubType::calculate_serialized_size( + const void* const data, + DataRepresentationId_t data_representation) +{ + try + { + eprosima::fastcdr::CdrSizeCalculator calculator( + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::CdrVersion::XCDRv1 :eprosima::fastcdr::CdrVersion::XCDRv2); + size_t current_alignment {0}; + const ::safe_edge::edge::EdgeGatewayStatus* p_type = + static_cast(data); + auto calc_size = calculator.calculate_serialized_size(*p_type, current_alignment); + return static_cast(calc_size) + 4u /*encapsulation*/; + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return 0; + } +} + +void* EdgeGatewayStatusPubSubType::create_data() +{ + return reinterpret_cast(new ::safe_edge::edge::EdgeGatewayStatus()); +} + +void EdgeGatewayStatusPubSubType::delete_data( + void* data) +{ + delete(reinterpret_cast<::safe_edge::edge::EdgeGatewayStatus*>(data)); +} + +bool EdgeGatewayStatusPubSubType::compute_key( + SerializedPayload_t& payload, + InstanceHandle_t& handle, + bool force_md5) +{ + static_cast(payload); + static_cast(handle); + static_cast(force_md5); + + return false; +} + +bool EdgeGatewayStatusPubSubType::compute_key( + const void* const data, + InstanceHandle_t& handle, + bool force_md5) +{ + static_cast(data); + static_cast(handle); + static_cast(force_md5); + + return false; +} + +void EdgeGatewayStatusPubSubType::register_type_object_representation() +{ + register_EdgeGatewayStatus_type_identifier(type_identifiers_); +} + +} // namespace edge + +} // namespace safe_edge + + +// Include auxiliary functions like for serializing/deserializing. +#include "edgeCdrAux.ipp" diff --git a/fast_dds/idl/edgePubSubTypes.hpp b/fast_dds/idl/edgePubSubTypes.hpp new file mode 100644 index 0000000..737d82f --- /dev/null +++ b/fast_dds/idl/edgePubSubTypes.hpp @@ -0,0 +1,286 @@ +// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/*! + * @file edgePubSubTypes.hpp + * This header file contains the declaration of the serialization functions. + * + * This file was generated by the tool fastddsgen (version: 4.3.0). + */ + + +#ifndef FAST_DDS_GENERATED__SAFE_EDGE_EDGE_EDGE_PUBSUBTYPES_HPP +#define FAST_DDS_GENERATED__SAFE_EDGE_EDGE_EDGE_PUBSUBTYPES_HPP + +#include + +#include +#include +#include +#include +#include + +#include "edge.hpp" + +#include "commonPubSubTypes.hpp" + +#if !defined(FASTDDS_GEN_API_VER) || (FASTDDS_GEN_API_VER != 3) +#error \ + Generated edge is not compatible with current installed Fast DDS. Please, regenerate it with fastddsgen. +#endif // FASTDDS_GEN_API_VER + +namespace safe_edge { +namespace edge { + +/*! + * @brief This class represents the TopicDataType of the type VehicleEdgeSummary defined by the user in the IDL file. + * @ingroup edge + */ +class VehicleEdgeSummaryPubSubType : public eprosima::fastdds::dds::TopicDataType +{ +public: + + typedef ::safe_edge::edge::VehicleEdgeSummary type; + + eProsima_user_DllExport VehicleEdgeSummaryPubSubType(); + + eProsima_user_DllExport ~VehicleEdgeSummaryPubSubType() override; + + eProsima_user_DllExport bool serialize( + const void* const data, + eprosima::fastdds::rtps::SerializedPayload_t& payload, + eprosima::fastdds::dds::DataRepresentationId_t data_representation) override; + + eProsima_user_DllExport bool deserialize( + eprosima::fastdds::rtps::SerializedPayload_t& payload, + void* data) override; + + eProsima_user_DllExport uint32_t calculate_serialized_size( + const void* const data, + eprosima::fastdds::dds::DataRepresentationId_t data_representation) override; + + eProsima_user_DllExport bool compute_key( + eprosima::fastdds::rtps::SerializedPayload_t& payload, + eprosima::fastdds::rtps::InstanceHandle_t& ihandle, + bool force_md5 = false) override; + + eProsima_user_DllExport bool compute_key( + const void* const data, + eprosima::fastdds::rtps::InstanceHandle_t& ihandle, + bool force_md5 = false) override; + + eProsima_user_DllExport void* create_data() override; + + eProsima_user_DllExport void delete_data( + void* data) override; + + //Register TypeObject representation in Fast DDS TypeObjectRegistry + eProsima_user_DllExport void register_type_object_representation() override; + +#ifdef TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED + eProsima_user_DllExport inline bool is_bounded() const override + { + return false; + } + +#endif // TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED + +#ifdef TOPIC_DATA_TYPE_API_HAS_IS_PLAIN + + eProsima_user_DllExport inline bool is_plain( + eprosima::fastdds::dds::DataRepresentationId_t data_representation) const override + { + static_cast(data_representation); + return false; + } + +#endif // TOPIC_DATA_TYPE_API_HAS_IS_PLAIN + +#ifdef TOPIC_DATA_TYPE_API_HAS_CONSTRUCT_SAMPLE + eProsima_user_DllExport inline bool construct_sample( + void* memory) const override + { + static_cast(memory); + return false; + } + +#endif // TOPIC_DATA_TYPE_API_HAS_CONSTRUCT_SAMPLE + +private: + +}; + + +/*! + * @brief This class represents the TopicDataType of the type EnergyAdvisory defined by the user in the IDL file. + * @ingroup edge + */ +class EnergyAdvisoryPubSubType : public eprosima::fastdds::dds::TopicDataType +{ +public: + + typedef ::safe_edge::edge::EnergyAdvisory type; + + eProsima_user_DllExport EnergyAdvisoryPubSubType(); + + eProsima_user_DllExport ~EnergyAdvisoryPubSubType() override; + + eProsima_user_DllExport bool serialize( + const void* const data, + eprosima::fastdds::rtps::SerializedPayload_t& payload, + eprosima::fastdds::dds::DataRepresentationId_t data_representation) override; + + eProsima_user_DllExport bool deserialize( + eprosima::fastdds::rtps::SerializedPayload_t& payload, + void* data) override; + + eProsima_user_DllExport uint32_t calculate_serialized_size( + const void* const data, + eprosima::fastdds::dds::DataRepresentationId_t data_representation) override; + + eProsima_user_DllExport bool compute_key( + eprosima::fastdds::rtps::SerializedPayload_t& payload, + eprosima::fastdds::rtps::InstanceHandle_t& ihandle, + bool force_md5 = false) override; + + eProsima_user_DllExport bool compute_key( + const void* const data, + eprosima::fastdds::rtps::InstanceHandle_t& ihandle, + bool force_md5 = false) override; + + eProsima_user_DllExport void* create_data() override; + + eProsima_user_DllExport void delete_data( + void* data) override; + + //Register TypeObject representation in Fast DDS TypeObjectRegistry + eProsima_user_DllExport void register_type_object_representation() override; + +#ifdef TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED + eProsima_user_DllExport inline bool is_bounded() const override + { + return false; + } + +#endif // TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED + +#ifdef TOPIC_DATA_TYPE_API_HAS_IS_PLAIN + + eProsima_user_DllExport inline bool is_plain( + eprosima::fastdds::dds::DataRepresentationId_t data_representation) const override + { + static_cast(data_representation); + return false; + } + +#endif // TOPIC_DATA_TYPE_API_HAS_IS_PLAIN + +#ifdef TOPIC_DATA_TYPE_API_HAS_CONSTRUCT_SAMPLE + eProsima_user_DllExport inline bool construct_sample( + void* memory) const override + { + static_cast(memory); + return false; + } + +#endif // TOPIC_DATA_TYPE_API_HAS_CONSTRUCT_SAMPLE + +private: + +}; + + +/*! + * @brief This class represents the TopicDataType of the type EdgeGatewayStatus defined by the user in the IDL file. + * @ingroup edge + */ +class EdgeGatewayStatusPubSubType : public eprosima::fastdds::dds::TopicDataType +{ +public: + + typedef ::safe_edge::edge::EdgeGatewayStatus type; + + eProsima_user_DllExport EdgeGatewayStatusPubSubType(); + + eProsima_user_DllExport ~EdgeGatewayStatusPubSubType() override; + + eProsima_user_DllExport bool serialize( + const void* const data, + eprosima::fastdds::rtps::SerializedPayload_t& payload, + eprosima::fastdds::dds::DataRepresentationId_t data_representation) override; + + eProsima_user_DllExport bool deserialize( + eprosima::fastdds::rtps::SerializedPayload_t& payload, + void* data) override; + + eProsima_user_DllExport uint32_t calculate_serialized_size( + const void* const data, + eprosima::fastdds::dds::DataRepresentationId_t data_representation) override; + + eProsima_user_DllExport bool compute_key( + eprosima::fastdds::rtps::SerializedPayload_t& payload, + eprosima::fastdds::rtps::InstanceHandle_t& ihandle, + bool force_md5 = false) override; + + eProsima_user_DllExport bool compute_key( + const void* const data, + eprosima::fastdds::rtps::InstanceHandle_t& ihandle, + bool force_md5 = false) override; + + eProsima_user_DllExport void* create_data() override; + + eProsima_user_DllExport void delete_data( + void* data) override; + + //Register TypeObject representation in Fast DDS TypeObjectRegistry + eProsima_user_DllExport void register_type_object_representation() override; + +#ifdef TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED + eProsima_user_DllExport inline bool is_bounded() const override + { + return false; + } + +#endif // TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED + +#ifdef TOPIC_DATA_TYPE_API_HAS_IS_PLAIN + + eProsima_user_DllExport inline bool is_plain( + eprosima::fastdds::dds::DataRepresentationId_t data_representation) const override + { + static_cast(data_representation); + return false; + } + +#endif // TOPIC_DATA_TYPE_API_HAS_IS_PLAIN + +#ifdef TOPIC_DATA_TYPE_API_HAS_CONSTRUCT_SAMPLE + eProsima_user_DllExport inline bool construct_sample( + void* memory) const override + { + static_cast(memory); + return false; + } + +#endif // TOPIC_DATA_TYPE_API_HAS_CONSTRUCT_SAMPLE + +private: + +}; + +} // namespace edge +} // namespace safe_edge + +#endif // FAST_DDS_GENERATED__SAFE_EDGE_EDGE_EDGE_PUBSUBTYPES_HPP + diff --git a/fast_dds/idl/edgeTypeObjectSupport.cxx b/fast_dds/idl/edgeTypeObjectSupport.cxx new file mode 100644 index 0000000..d42ba9f --- /dev/null +++ b/fast_dds/idl/edgeTypeObjectSupport.cxx @@ -0,0 +1,554 @@ +// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/*! + * @file edgeTypeObjectSupport.cxx + * Source file containing the implementation to register the TypeObject representation of the described types in the IDL file + * + * This file was generated by the tool fastddsgen (version: 4.3.0). + */ + +#include "edgeTypeObjectSupport.hpp" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "edge.hpp" + +#include "common.hpp" + +using namespace eprosima::fastdds::dds::xtypes; + +namespace safe_edge { +namespace edge { +// TypeIdentifier is returned by reference: dependent structures/unions are registered in this same method +void register_VehicleEdgeSummary_type_identifier( + TypeIdentifierPair& type_ids_VehicleEdgeSummary) +{ + + ReturnCode_t return_code_VehicleEdgeSummary {eprosima::fastdds::dds::RETCODE_OK}; + return_code_VehicleEdgeSummary = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "safe_edge::edge::VehicleEdgeSummary", type_ids_VehicleEdgeSummary); + if (eprosima::fastdds::dds::RETCODE_OK != return_code_VehicleEdgeSummary) + { + StructTypeFlag struct_flags_VehicleEdgeSummary = TypeObjectUtils::build_struct_type_flag(eprosima::fastdds::dds::xtypes::ExtensibilityKind::APPENDABLE, + false, false); + QualifiedTypeName type_name_VehicleEdgeSummary = "safe_edge::edge::VehicleEdgeSummary"; + eprosima::fastcdr::optional type_ann_builtin_VehicleEdgeSummary; + eprosima::fastcdr::optional ann_custom_VehicleEdgeSummary; + CompleteTypeDetail detail_VehicleEdgeSummary = TypeObjectUtils::build_complete_type_detail(type_ann_builtin_VehicleEdgeSummary, ann_custom_VehicleEdgeSummary, type_name_VehicleEdgeSummary.to_string()); + CompleteStructHeader header_VehicleEdgeSummary; + header_VehicleEdgeSummary = TypeObjectUtils::build_complete_struct_header(TypeIdentifier(), detail_VehicleEdgeSummary); + CompleteStructMemberSeq member_seq_VehicleEdgeSummary; + { + TypeIdentifierPair type_ids_header; + ReturnCode_t return_code_header {eprosima::fastdds::dds::RETCODE_OK}; + return_code_header = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "safe_edge::common::Header", type_ids_header); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_header) + { + ::safe_edge::common::register_Header_type_identifier(type_ids_header); + } + StructMemberFlag member_flags_header = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_header = 0x00000000; + bool common_header_ec {false}; + CommonStructMember common_header {TypeObjectUtils::build_common_struct_member(member_id_header, member_flags_header, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_header, common_header_ec))}; + if (!common_header_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure header member TypeIdentifier inconsistent."); + return; + } + MemberName name_header = "header"; + eprosima::fastcdr::optional member_ann_builtin_header; + ann_custom_VehicleEdgeSummary.reset(); + CompleteMemberDetail detail_header = TypeObjectUtils::build_complete_member_detail(name_header, member_ann_builtin_header, ann_custom_VehicleEdgeSummary); + CompleteStructMember member_header = TypeObjectUtils::build_complete_struct_member(common_header, detail_header); + TypeObjectUtils::add_complete_struct_member(member_seq_VehicleEdgeSummary, member_header); + } + { + TypeIdentifierPair type_ids_soc_pct; + ReturnCode_t return_code_soc_pct {eprosima::fastdds::dds::RETCODE_OK}; + return_code_soc_pct = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "_float", type_ids_soc_pct); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_soc_pct) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "soc_pct Structure member TypeIdentifier unknown to TypeObjectRegistry."); + return; + } + StructMemberFlag member_flags_soc_pct = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_soc_pct = 0x00000001; + bool common_soc_pct_ec {false}; + CommonStructMember common_soc_pct {TypeObjectUtils::build_common_struct_member(member_id_soc_pct, member_flags_soc_pct, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_soc_pct, common_soc_pct_ec))}; + if (!common_soc_pct_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure soc_pct member TypeIdentifier inconsistent."); + return; + } + MemberName name_soc_pct = "soc_pct"; + eprosima::fastcdr::optional member_ann_builtin_soc_pct; + ann_custom_VehicleEdgeSummary.reset(); + CompleteMemberDetail detail_soc_pct = TypeObjectUtils::build_complete_member_detail(name_soc_pct, member_ann_builtin_soc_pct, ann_custom_VehicleEdgeSummary); + CompleteStructMember member_soc_pct = TypeObjectUtils::build_complete_struct_member(common_soc_pct, detail_soc_pct); + TypeObjectUtils::add_complete_struct_member(member_seq_VehicleEdgeSummary, member_soc_pct); + } + { + TypeIdentifierPair type_ids_current_mode; + ReturnCode_t return_code_current_mode {eprosima::fastdds::dds::RETCODE_OK}; + return_code_current_mode = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "safe_edge::common::PolicyMode", type_ids_current_mode); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_current_mode) + { + ::safe_edge::common::register_PolicyMode_type_identifier(type_ids_current_mode); + } + StructMemberFlag member_flags_current_mode = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_current_mode = 0x00000002; + bool common_current_mode_ec {false}; + CommonStructMember common_current_mode {TypeObjectUtils::build_common_struct_member(member_id_current_mode, member_flags_current_mode, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_current_mode, common_current_mode_ec))}; + if (!common_current_mode_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure current_mode member TypeIdentifier inconsistent."); + return; + } + MemberName name_current_mode = "current_mode"; + eprosima::fastcdr::optional member_ann_builtin_current_mode; + ann_custom_VehicleEdgeSummary.reset(); + CompleteMemberDetail detail_current_mode = TypeObjectUtils::build_complete_member_detail(name_current_mode, member_ann_builtin_current_mode, ann_custom_VehicleEdgeSummary); + CompleteStructMember member_current_mode = TypeObjectUtils::build_complete_struct_member(common_current_mode, detail_current_mode); + TypeObjectUtils::add_complete_struct_member(member_seq_VehicleEdgeSummary, member_current_mode); + } + { + TypeIdentifierPair type_ids_vehicle_health; + ReturnCode_t return_code_vehicle_health {eprosima::fastdds::dds::RETCODE_OK}; + return_code_vehicle_health = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "safe_edge::common::HealthStatus", type_ids_vehicle_health); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_vehicle_health) + { + ::safe_edge::common::register_HealthStatus_type_identifier(type_ids_vehicle_health); + } + StructMemberFlag member_flags_vehicle_health = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_vehicle_health = 0x00000003; + bool common_vehicle_health_ec {false}; + CommonStructMember common_vehicle_health {TypeObjectUtils::build_common_struct_member(member_id_vehicle_health, member_flags_vehicle_health, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_vehicle_health, common_vehicle_health_ec))}; + if (!common_vehicle_health_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure vehicle_health member TypeIdentifier inconsistent."); + return; + } + MemberName name_vehicle_health = "vehicle_health"; + eprosima::fastcdr::optional member_ann_builtin_vehicle_health; + ann_custom_VehicleEdgeSummary.reset(); + CompleteMemberDetail detail_vehicle_health = TypeObjectUtils::build_complete_member_detail(name_vehicle_health, member_ann_builtin_vehicle_health, ann_custom_VehicleEdgeSummary); + CompleteStructMember member_vehicle_health = TypeObjectUtils::build_complete_struct_member(common_vehicle_health, detail_vehicle_health); + TypeObjectUtils::add_complete_struct_member(member_seq_VehicleEdgeSummary, member_vehicle_health); + } + { + TypeIdentifierPair type_ids_v2g_ready; + ReturnCode_t return_code_v2g_ready {eprosima::fastdds::dds::RETCODE_OK}; + return_code_v2g_ready = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "_bool", type_ids_v2g_ready); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_v2g_ready) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "v2g_ready Structure member TypeIdentifier unknown to TypeObjectRegistry."); + return; + } + StructMemberFlag member_flags_v2g_ready = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_v2g_ready = 0x00000004; + bool common_v2g_ready_ec {false}; + CommonStructMember common_v2g_ready {TypeObjectUtils::build_common_struct_member(member_id_v2g_ready, member_flags_v2g_ready, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_v2g_ready, common_v2g_ready_ec))}; + if (!common_v2g_ready_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure v2g_ready member TypeIdentifier inconsistent."); + return; + } + MemberName name_v2g_ready = "v2g_ready"; + eprosima::fastcdr::optional member_ann_builtin_v2g_ready; + ann_custom_VehicleEdgeSummary.reset(); + CompleteMemberDetail detail_v2g_ready = TypeObjectUtils::build_complete_member_detail(name_v2g_ready, member_ann_builtin_v2g_ready, ann_custom_VehicleEdgeSummary); + CompleteStructMember member_v2g_ready = TypeObjectUtils::build_complete_struct_member(common_v2g_ready, detail_v2g_ready); + TypeObjectUtils::add_complete_struct_member(member_seq_VehicleEdgeSummary, member_v2g_ready); + } + CompleteStructType struct_type_VehicleEdgeSummary = TypeObjectUtils::build_complete_struct_type(struct_flags_VehicleEdgeSummary, header_VehicleEdgeSummary, member_seq_VehicleEdgeSummary); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_struct_type_object(struct_type_VehicleEdgeSummary, type_name_VehicleEdgeSummary.to_string(), type_ids_VehicleEdgeSummary)) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "safe_edge::edge::VehicleEdgeSummary already registered in TypeObjectRegistry for a different type."); + } + } +}// TypeIdentifier is returned by reference: dependent structures/unions are registered in this same method +void register_EnergyAdvisory_type_identifier( + TypeIdentifierPair& type_ids_EnergyAdvisory) +{ + + ReturnCode_t return_code_EnergyAdvisory {eprosima::fastdds::dds::RETCODE_OK}; + return_code_EnergyAdvisory = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "safe_edge::edge::EnergyAdvisory", type_ids_EnergyAdvisory); + if (eprosima::fastdds::dds::RETCODE_OK != return_code_EnergyAdvisory) + { + StructTypeFlag struct_flags_EnergyAdvisory = TypeObjectUtils::build_struct_type_flag(eprosima::fastdds::dds::xtypes::ExtensibilityKind::APPENDABLE, + false, false); + QualifiedTypeName type_name_EnergyAdvisory = "safe_edge::edge::EnergyAdvisory"; + eprosima::fastcdr::optional type_ann_builtin_EnergyAdvisory; + eprosima::fastcdr::optional ann_custom_EnergyAdvisory; + CompleteTypeDetail detail_EnergyAdvisory = TypeObjectUtils::build_complete_type_detail(type_ann_builtin_EnergyAdvisory, ann_custom_EnergyAdvisory, type_name_EnergyAdvisory.to_string()); + CompleteStructHeader header_EnergyAdvisory; + header_EnergyAdvisory = TypeObjectUtils::build_complete_struct_header(TypeIdentifier(), detail_EnergyAdvisory); + CompleteStructMemberSeq member_seq_EnergyAdvisory; + { + TypeIdentifierPair type_ids_header; + ReturnCode_t return_code_header {eprosima::fastdds::dds::RETCODE_OK}; + return_code_header = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "safe_edge::common::Header", type_ids_header); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_header) + { + ::safe_edge::common::register_Header_type_identifier(type_ids_header); + } + StructMemberFlag member_flags_header = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_header = 0x00000000; + bool common_header_ec {false}; + CommonStructMember common_header {TypeObjectUtils::build_common_struct_member(member_id_header, member_flags_header, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_header, common_header_ec))}; + if (!common_header_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure header member TypeIdentifier inconsistent."); + return; + } + MemberName name_header = "header"; + eprosima::fastcdr::optional member_ann_builtin_header; + ann_custom_EnergyAdvisory.reset(); + CompleteMemberDetail detail_header = TypeObjectUtils::build_complete_member_detail(name_header, member_ann_builtin_header, ann_custom_EnergyAdvisory); + CompleteStructMember member_header = TypeObjectUtils::build_complete_struct_member(common_header, detail_header); + TypeObjectUtils::add_complete_struct_member(member_seq_EnergyAdvisory, member_header); + } + { + TypeIdentifierPair type_ids_suggested_mode; + ReturnCode_t return_code_suggested_mode {eprosima::fastdds::dds::RETCODE_OK}; + return_code_suggested_mode = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "safe_edge::common::PolicyMode", type_ids_suggested_mode); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_suggested_mode) + { + ::safe_edge::common::register_PolicyMode_type_identifier(type_ids_suggested_mode); + } + StructMemberFlag member_flags_suggested_mode = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_suggested_mode = 0x00000001; + bool common_suggested_mode_ec {false}; + CommonStructMember common_suggested_mode {TypeObjectUtils::build_common_struct_member(member_id_suggested_mode, member_flags_suggested_mode, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_suggested_mode, common_suggested_mode_ec))}; + if (!common_suggested_mode_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure suggested_mode member TypeIdentifier inconsistent."); + return; + } + MemberName name_suggested_mode = "suggested_mode"; + eprosima::fastcdr::optional member_ann_builtin_suggested_mode; + ann_custom_EnergyAdvisory.reset(); + CompleteMemberDetail detail_suggested_mode = TypeObjectUtils::build_complete_member_detail(name_suggested_mode, member_ann_builtin_suggested_mode, ann_custom_EnergyAdvisory); + CompleteStructMember member_suggested_mode = TypeObjectUtils::build_complete_struct_member(common_suggested_mode, detail_suggested_mode); + TypeObjectUtils::add_complete_struct_member(member_seq_EnergyAdvisory, member_suggested_mode); + } + { + TypeIdentifierPair type_ids_advisory_reason; + ReturnCode_t return_code_advisory_reason {eprosima::fastdds::dds::RETCODE_OK}; + return_code_advisory_reason = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "anonymous_string_unbounded", type_ids_advisory_reason); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_advisory_reason) + { + { + SBound bound = 0; + StringSTypeDefn string_sdefn = TypeObjectUtils::build_string_s_type_defn(bound); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_s_string_type_identifier(string_sdefn, + "anonymous_string_unbounded", type_ids_advisory_reason)) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "anonymous_string_unbounded already registered in TypeObjectRegistry for a different type."); + } + } + } + StructMemberFlag member_flags_advisory_reason = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_advisory_reason = 0x00000002; + bool common_advisory_reason_ec {false}; + CommonStructMember common_advisory_reason {TypeObjectUtils::build_common_struct_member(member_id_advisory_reason, member_flags_advisory_reason, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_advisory_reason, common_advisory_reason_ec))}; + if (!common_advisory_reason_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure advisory_reason member TypeIdentifier inconsistent."); + return; + } + MemberName name_advisory_reason = "advisory_reason"; + eprosima::fastcdr::optional member_ann_builtin_advisory_reason; + ann_custom_EnergyAdvisory.reset(); + CompleteMemberDetail detail_advisory_reason = TypeObjectUtils::build_complete_member_detail(name_advisory_reason, member_ann_builtin_advisory_reason, ann_custom_EnergyAdvisory); + CompleteStructMember member_advisory_reason = TypeObjectUtils::build_complete_struct_member(common_advisory_reason, detail_advisory_reason); + TypeObjectUtils::add_complete_struct_member(member_seq_EnergyAdvisory, member_advisory_reason); + } + { + TypeIdentifierPair type_ids_recommended_charger_id; + ReturnCode_t return_code_recommended_charger_id {eprosima::fastdds::dds::RETCODE_OK}; + return_code_recommended_charger_id = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "_int32_t", type_ids_recommended_charger_id); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_recommended_charger_id) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "recommended_charger_id Structure member TypeIdentifier unknown to TypeObjectRegistry."); + return; + } + StructMemberFlag member_flags_recommended_charger_id = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_recommended_charger_id = 0x00000003; + bool common_recommended_charger_id_ec {false}; + CommonStructMember common_recommended_charger_id {TypeObjectUtils::build_common_struct_member(member_id_recommended_charger_id, member_flags_recommended_charger_id, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_recommended_charger_id, common_recommended_charger_id_ec))}; + if (!common_recommended_charger_id_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure recommended_charger_id member TypeIdentifier inconsistent."); + return; + } + MemberName name_recommended_charger_id = "recommended_charger_id"; + eprosima::fastcdr::optional member_ann_builtin_recommended_charger_id; + ann_custom_EnergyAdvisory.reset(); + CompleteMemberDetail detail_recommended_charger_id = TypeObjectUtils::build_complete_member_detail(name_recommended_charger_id, member_ann_builtin_recommended_charger_id, ann_custom_EnergyAdvisory); + CompleteStructMember member_recommended_charger_id = TypeObjectUtils::build_complete_struct_member(common_recommended_charger_id, detail_recommended_charger_id); + TypeObjectUtils::add_complete_struct_member(member_seq_EnergyAdvisory, member_recommended_charger_id); + } + { + TypeIdentifierPair type_ids_target_soc_pct; + ReturnCode_t return_code_target_soc_pct {eprosima::fastdds::dds::RETCODE_OK}; + return_code_target_soc_pct = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "_float", type_ids_target_soc_pct); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_target_soc_pct) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "target_soc_pct Structure member TypeIdentifier unknown to TypeObjectRegistry."); + return; + } + StructMemberFlag member_flags_target_soc_pct = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_target_soc_pct = 0x00000004; + bool common_target_soc_pct_ec {false}; + CommonStructMember common_target_soc_pct {TypeObjectUtils::build_common_struct_member(member_id_target_soc_pct, member_flags_target_soc_pct, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_target_soc_pct, common_target_soc_pct_ec))}; + if (!common_target_soc_pct_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure target_soc_pct member TypeIdentifier inconsistent."); + return; + } + MemberName name_target_soc_pct = "target_soc_pct"; + eprosima::fastcdr::optional member_ann_builtin_target_soc_pct; + ann_custom_EnergyAdvisory.reset(); + CompleteMemberDetail detail_target_soc_pct = TypeObjectUtils::build_complete_member_detail(name_target_soc_pct, member_ann_builtin_target_soc_pct, ann_custom_EnergyAdvisory); + CompleteStructMember member_target_soc_pct = TypeObjectUtils::build_complete_struct_member(common_target_soc_pct, detail_target_soc_pct); + TypeObjectUtils::add_complete_struct_member(member_seq_EnergyAdvisory, member_target_soc_pct); + } + CompleteStructType struct_type_EnergyAdvisory = TypeObjectUtils::build_complete_struct_type(struct_flags_EnergyAdvisory, header_EnergyAdvisory, member_seq_EnergyAdvisory); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_struct_type_object(struct_type_EnergyAdvisory, type_name_EnergyAdvisory.to_string(), type_ids_EnergyAdvisory)) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "safe_edge::edge::EnergyAdvisory already registered in TypeObjectRegistry for a different type."); + } + } +}// TypeIdentifier is returned by reference: dependent structures/unions are registered in this same method +void register_EdgeGatewayStatus_type_identifier( + TypeIdentifierPair& type_ids_EdgeGatewayStatus) +{ + + ReturnCode_t return_code_EdgeGatewayStatus {eprosima::fastdds::dds::RETCODE_OK}; + return_code_EdgeGatewayStatus = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "safe_edge::edge::EdgeGatewayStatus", type_ids_EdgeGatewayStatus); + if (eprosima::fastdds::dds::RETCODE_OK != return_code_EdgeGatewayStatus) + { + StructTypeFlag struct_flags_EdgeGatewayStatus = TypeObjectUtils::build_struct_type_flag(eprosima::fastdds::dds::xtypes::ExtensibilityKind::APPENDABLE, + false, false); + QualifiedTypeName type_name_EdgeGatewayStatus = "safe_edge::edge::EdgeGatewayStatus"; + eprosima::fastcdr::optional type_ann_builtin_EdgeGatewayStatus; + eprosima::fastcdr::optional ann_custom_EdgeGatewayStatus; + CompleteTypeDetail detail_EdgeGatewayStatus = TypeObjectUtils::build_complete_type_detail(type_ann_builtin_EdgeGatewayStatus, ann_custom_EdgeGatewayStatus, type_name_EdgeGatewayStatus.to_string()); + CompleteStructHeader header_EdgeGatewayStatus; + header_EdgeGatewayStatus = TypeObjectUtils::build_complete_struct_header(TypeIdentifier(), detail_EdgeGatewayStatus); + CompleteStructMemberSeq member_seq_EdgeGatewayStatus; + { + TypeIdentifierPair type_ids_header; + ReturnCode_t return_code_header {eprosima::fastdds::dds::RETCODE_OK}; + return_code_header = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "safe_edge::common::Header", type_ids_header); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_header) + { + ::safe_edge::common::register_Header_type_identifier(type_ids_header); + } + StructMemberFlag member_flags_header = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_header = 0x00000000; + bool common_header_ec {false}; + CommonStructMember common_header {TypeObjectUtils::build_common_struct_member(member_id_header, member_flags_header, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_header, common_header_ec))}; + if (!common_header_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure header member TypeIdentifier inconsistent."); + return; + } + MemberName name_header = "header"; + eprosima::fastcdr::optional member_ann_builtin_header; + ann_custom_EdgeGatewayStatus.reset(); + CompleteMemberDetail detail_header = TypeObjectUtils::build_complete_member_detail(name_header, member_ann_builtin_header, ann_custom_EdgeGatewayStatus); + CompleteStructMember member_header = TypeObjectUtils::build_complete_struct_member(common_header, detail_header); + TypeObjectUtils::add_complete_struct_member(member_seq_EdgeGatewayStatus, member_header); + } + { + TypeIdentifierPair type_ids_status; + ReturnCode_t return_code_status {eprosima::fastdds::dds::RETCODE_OK}; + return_code_status = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "safe_edge::common::HealthStatus", type_ids_status); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_status) + { + ::safe_edge::common::register_HealthStatus_type_identifier(type_ids_status); + } + StructMemberFlag member_flags_status = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_status = 0x00000001; + bool common_status_ec {false}; + CommonStructMember common_status {TypeObjectUtils::build_common_struct_member(member_id_status, member_flags_status, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_status, common_status_ec))}; + if (!common_status_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure status member TypeIdentifier inconsistent."); + return; + } + MemberName name_status = "status"; + eprosima::fastcdr::optional member_ann_builtin_status; + ann_custom_EdgeGatewayStatus.reset(); + CompleteMemberDetail detail_status = TypeObjectUtils::build_complete_member_detail(name_status, member_ann_builtin_status, ann_custom_EdgeGatewayStatus); + CompleteStructMember member_status = TypeObjectUtils::build_complete_struct_member(common_status, detail_status); + TypeObjectUtils::add_complete_struct_member(member_seq_EdgeGatewayStatus, member_status); + } + { + TypeIdentifierPair type_ids_last_server_sync_ms; + ReturnCode_t return_code_last_server_sync_ms {eprosima::fastdds::dds::RETCODE_OK}; + return_code_last_server_sync_ms = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "_uint64_t", type_ids_last_server_sync_ms); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_last_server_sync_ms) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "last_server_sync_ms Structure member TypeIdentifier unknown to TypeObjectRegistry."); + return; + } + StructMemberFlag member_flags_last_server_sync_ms = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_last_server_sync_ms = 0x00000002; + bool common_last_server_sync_ms_ec {false}; + CommonStructMember common_last_server_sync_ms {TypeObjectUtils::build_common_struct_member(member_id_last_server_sync_ms, member_flags_last_server_sync_ms, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_last_server_sync_ms, common_last_server_sync_ms_ec))}; + if (!common_last_server_sync_ms_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure last_server_sync_ms member TypeIdentifier inconsistent."); + return; + } + MemberName name_last_server_sync_ms = "last_server_sync_ms"; + eprosima::fastcdr::optional member_ann_builtin_last_server_sync_ms; + ann_custom_EdgeGatewayStatus.reset(); + CompleteMemberDetail detail_last_server_sync_ms = TypeObjectUtils::build_complete_member_detail(name_last_server_sync_ms, member_ann_builtin_last_server_sync_ms, ann_custom_EdgeGatewayStatus); + CompleteStructMember member_last_server_sync_ms = TypeObjectUtils::build_complete_struct_member(common_last_server_sync_ms, detail_last_server_sync_ms); + TypeObjectUtils::add_complete_struct_member(member_seq_EdgeGatewayStatus, member_last_server_sync_ms); + } + { + TypeIdentifierPair type_ids_detail; + ReturnCode_t return_code_detail {eprosima::fastdds::dds::RETCODE_OK}; + return_code_detail = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "anonymous_string_unbounded", type_ids_detail); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_detail) + { + { + SBound bound = 0; + StringSTypeDefn string_sdefn = TypeObjectUtils::build_string_s_type_defn(bound); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_s_string_type_identifier(string_sdefn, + "anonymous_string_unbounded", type_ids_detail)) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "anonymous_string_unbounded already registered in TypeObjectRegistry for a different type."); + } + } + } + StructMemberFlag member_flags_detail = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_detail = 0x00000003; + bool common_detail_ec {false}; + CommonStructMember common_detail {TypeObjectUtils::build_common_struct_member(member_id_detail, member_flags_detail, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_detail, common_detail_ec))}; + if (!common_detail_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure detail member TypeIdentifier inconsistent."); + return; + } + MemberName name_detail = "detail"; + eprosima::fastcdr::optional member_ann_builtin_detail; + ann_custom_EdgeGatewayStatus.reset(); + CompleteMemberDetail detail_detail = TypeObjectUtils::build_complete_member_detail(name_detail, member_ann_builtin_detail, ann_custom_EdgeGatewayStatus); + CompleteStructMember member_detail = TypeObjectUtils::build_complete_struct_member(common_detail, detail_detail); + TypeObjectUtils::add_complete_struct_member(member_seq_EdgeGatewayStatus, member_detail); + } + CompleteStructType struct_type_EdgeGatewayStatus = TypeObjectUtils::build_complete_struct_type(struct_flags_EdgeGatewayStatus, header_EdgeGatewayStatus, member_seq_EdgeGatewayStatus); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_struct_type_object(struct_type_EdgeGatewayStatus, type_name_EdgeGatewayStatus.to_string(), type_ids_EdgeGatewayStatus)) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "safe_edge::edge::EdgeGatewayStatus already registered in TypeObjectRegistry for a different type."); + } + } +} +} // namespace edge + +} // namespace safe_edge + diff --git a/fast_dds/idl/edgeTypeObjectSupport.hpp b/fast_dds/idl/edgeTypeObjectSupport.hpp new file mode 100644 index 0000000..8de7065 --- /dev/null +++ b/fast_dds/idl/edgeTypeObjectSupport.hpp @@ -0,0 +1,89 @@ +// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/*! + * @file edgeTypeObjectSupport.hpp + * Header file containing the API required to register the TypeObject representation of the described types in the IDL file + * + * This file was generated by the tool fastddsgen (version: 4.3.0). + */ + +#ifndef FAST_DDS_GENERATED__SAFE_EDGE_EDGE_EDGE_TYPE_OBJECT_SUPPORT_HPP +#define FAST_DDS_GENERATED__SAFE_EDGE_EDGE_EDGE_TYPE_OBJECT_SUPPORT_HPP + +#include + +#include "commonTypeObjectSupport.hpp" + +#if defined(_WIN32) +#if defined(EPROSIMA_USER_DLL_EXPORT) +#define eProsima_user_DllExport __declspec( dllexport ) +#else +#define eProsima_user_DllExport +#endif // EPROSIMA_USER_DLL_EXPORT +#else +#define eProsima_user_DllExport +#endif // _WIN32 + +#ifndef DOXYGEN_SHOULD_SKIP_THIS_PUBLIC + +namespace safe_edge { +namespace edge { +/** + * @brief Register VehicleEdgeSummary related TypeIdentifier. + * Fully-descriptive TypeIdentifiers are directly registered. + * Hash TypeIdentifiers require to fill the TypeObject information and hash it, consequently, the TypeObject is + * indirectly registered as well. + * + * @param[out] type_ids TypeIdentifier of the registered type. + * The returned TypeIdentifier corresponds to the complete TypeIdentifier in case of hashed TypeIdentifiers. + * Invalid TypeIdentifier is returned in case of error. + */ +eProsima_user_DllExport void register_VehicleEdgeSummary_type_identifier( + eprosima::fastdds::dds::xtypes::TypeIdentifierPair& type_ids); + +/** + * @brief Register EnergyAdvisory related TypeIdentifier. + * Fully-descriptive TypeIdentifiers are directly registered. + * Hash TypeIdentifiers require to fill the TypeObject information and hash it, consequently, the TypeObject is + * indirectly registered as well. + * + * @param[out] type_ids TypeIdentifier of the registered type. + * The returned TypeIdentifier corresponds to the complete TypeIdentifier in case of hashed TypeIdentifiers. + * Invalid TypeIdentifier is returned in case of error. + */ +eProsima_user_DllExport void register_EnergyAdvisory_type_identifier( + eprosima::fastdds::dds::xtypes::TypeIdentifierPair& type_ids); + +/** + * @brief Register EdgeGatewayStatus related TypeIdentifier. + * Fully-descriptive TypeIdentifiers are directly registered. + * Hash TypeIdentifiers require to fill the TypeObject information and hash it, consequently, the TypeObject is + * indirectly registered as well. + * + * @param[out] type_ids TypeIdentifier of the registered type. + * The returned TypeIdentifier corresponds to the complete TypeIdentifier in case of hashed TypeIdentifiers. + * Invalid TypeIdentifier is returned in case of error. + */ +eProsima_user_DllExport void register_EdgeGatewayStatus_type_identifier( + eprosima::fastdds::dds::xtypes::TypeIdentifierPair& type_ids); + +} // namespace edge + +} // namespace safe_edge + + +#endif // DOXYGEN_SHOULD_SKIP_THIS_PUBLIC + +#endif // FAST_DDS_GENERATED__SAFE_EDGE_EDGE_EDGE_TYPE_OBJECT_SUPPORT_HPP diff --git a/fast_dds/idl/pilot_server.hpp b/fast_dds/idl/pilot_server.hpp new file mode 100644 index 0000000..f948c83 --- /dev/null +++ b/fast_dds/idl/pilot_server.hpp @@ -0,0 +1,1534 @@ +// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/*! + * @file pilot_server.hpp + * This header file contains the declaration of the described types in the IDL file. + * + * This file was generated by the tool fastddsgen (version: 4.3.0). + */ + +#ifndef FAST_DDS_GENERATED__SAFE_EDGE_PILOT_SERVER_PILOT_SERVER_HPP +#define FAST_DDS_GENERATED__SAFE_EDGE_PILOT_SERVER_PILOT_SERVER_HPP + +#include +#include +#include +#include + +#include +#include "common.hpp" + +#if defined(_WIN32) +#if defined(EPROSIMA_USER_DLL_EXPORT) +#define eProsima_user_DllExport __declspec( dllexport ) +#else +#define eProsima_user_DllExport +#endif // EPROSIMA_USER_DLL_EXPORT +#else +#define eProsima_user_DllExport +#endif // _WIN32 + +#if defined(_WIN32) +#if defined(EPROSIMA_USER_DLL_EXPORT) +#if defined(PILOT_SERVER_SOURCE) +#define PILOT_SERVER_DllAPI __declspec( dllexport ) +#else +#define PILOT_SERVER_DllAPI __declspec( dllimport ) +#endif // PILOT_SERVER_SOURCE +#else +#define PILOT_SERVER_DllAPI +#endif // EPROSIMA_USER_DLL_EXPORT +#else +#define PILOT_SERVER_DllAPI +#endif // _WIN32 + +namespace safe_edge { + +namespace pilot_server { + +const uint32_t MAX_CHARGER_LOCATIONS = 200; +const uint32_t MAX_CHARGER_TYPES = 64; +const uint32_t MAX_CHARGING_SESSIONS = 1000; +const uint32_t MAX_ROUTE_METRICS = 512; +/*! + * @brief This class represents the structure ChargerLocation defined by the user in the IDL file. + * @ingroup pilot_server + */ +class ChargerLocation +{ +public: + + /*! + * @brief Default constructor. + */ + eProsima_user_DllExport ChargerLocation() + { + } + + /*! + * @brief Default destructor. + */ + eProsima_user_DllExport ~ChargerLocation() + { + } + + /*! + * @brief Copy constructor. + * @param x Reference to the object ChargerLocation that will be copied. + */ + eProsima_user_DllExport ChargerLocation( + const ChargerLocation& x) + { + m_id = x.m_id; + + m_name = x.m_name; + + m_position = x.m_position; + + } + + /*! + * @brief Move constructor. + * @param x Reference to the object ChargerLocation that will be copied. + */ + eProsima_user_DllExport ChargerLocation( + ChargerLocation&& x) noexcept + { + m_id = x.m_id; + m_name = std::move(x.m_name); + m_position = std::move(x.m_position); + } + + /*! + * @brief Copy assignment. + * @param x Reference to the object ChargerLocation that will be copied. + */ + eProsima_user_DllExport ChargerLocation& operator =( + const ChargerLocation& x) + { + + m_id = x.m_id; + + m_name = x.m_name; + + m_position = x.m_position; + + return *this; + } + + /*! + * @brief Move assignment. + * @param x Reference to the object ChargerLocation that will be copied. + */ + eProsima_user_DllExport ChargerLocation& operator =( + ChargerLocation&& x) noexcept + { + + m_id = x.m_id; + m_name = std::move(x.m_name); + m_position = std::move(x.m_position); + return *this; + } + + /*! + * @brief Comparison operator. + * @param x ChargerLocation object to compare. + */ + eProsima_user_DllExport bool operator ==( + const ChargerLocation& x) const + { + return (m_id == x.m_id && + m_name == x.m_name && + m_position == x.m_position); + } + + /*! + * @brief Comparison operator. + * @param x ChargerLocation object to compare. + */ + eProsima_user_DllExport bool operator !=( + const ChargerLocation& x) const + { + return !(*this == x); + } + + /*! + * @brief This function sets a value in member id + * @param _id New value for member id + */ + eProsima_user_DllExport void id( + int32_t _id) + { + m_id = _id; + } + + /*! + * @brief This function returns the value of member id + * @return Value of member id + */ + eProsima_user_DllExport int32_t id() const + { + return m_id; + } + + /*! + * @brief This function returns a reference to member id + * @return Reference to member id + */ + eProsima_user_DllExport int32_t& id() + { + return m_id; + } + + + /*! + * @brief This function copies the value in member name + * @param _name New value to be copied in member name + */ + eProsima_user_DllExport void name( + const std::string& _name) + { + m_name = _name; + } + + /*! + * @brief This function moves the value in member name + * @param _name New value to be moved in member name + */ + eProsima_user_DllExport void name( + std::string&& _name) + { + m_name = std::move(_name); + } + + /*! + * @brief This function returns a constant reference to member name + * @return Constant reference to member name + */ + eProsima_user_DllExport const std::string& name() const + { + return m_name; + } + + /*! + * @brief This function returns a reference to member name + * @return Reference to member name + */ + eProsima_user_DllExport std::string& name() + { + return m_name; + } + + + /*! + * @brief This function copies the value in member position + * @param _position New value to be copied in member position + */ + eProsima_user_DllExport void position( + const safe_edge::common::GeoPoint& _position) + { + m_position = _position; + } + + /*! + * @brief This function moves the value in member position + * @param _position New value to be moved in member position + */ + eProsima_user_DllExport void position( + safe_edge::common::GeoPoint&& _position) + { + m_position = std::move(_position); + } + + /*! + * @brief This function returns a constant reference to member position + * @return Constant reference to member position + */ + eProsima_user_DllExport const safe_edge::common::GeoPoint& position() const + { + return m_position; + } + + /*! + * @brief This function returns a reference to member position + * @return Reference to member position + */ + eProsima_user_DllExport safe_edge::common::GeoPoint& position() + { + return m_position; + } + + + +private: + + int32_t m_id{0}; + std::string m_name; + safe_edge::common::GeoPoint m_position; + +}; +typedef std::vector ChargerLocationSeq; + +/*! + * @brief This class represents the structure ChargerType defined by the user in the IDL file. + * @ingroup pilot_server + */ +class ChargerType +{ +public: + + /*! + * @brief Default constructor. + */ + eProsima_user_DllExport ChargerType() + { + } + + /*! + * @brief Default destructor. + */ + eProsima_user_DllExport ~ChargerType() + { + } + + /*! + * @brief Copy constructor. + * @param x Reference to the object ChargerType that will be copied. + */ + eProsima_user_DllExport ChargerType( + const ChargerType& x) + { + m_id = x.m_id; + + m_charger_type = x.m_charger_type; + + } + + /*! + * @brief Move constructor. + * @param x Reference to the object ChargerType that will be copied. + */ + eProsima_user_DllExport ChargerType( + ChargerType&& x) noexcept + { + m_id = x.m_id; + m_charger_type = std::move(x.m_charger_type); + } + + /*! + * @brief Copy assignment. + * @param x Reference to the object ChargerType that will be copied. + */ + eProsima_user_DllExport ChargerType& operator =( + const ChargerType& x) + { + + m_id = x.m_id; + + m_charger_type = x.m_charger_type; + + return *this; + } + + /*! + * @brief Move assignment. + * @param x Reference to the object ChargerType that will be copied. + */ + eProsima_user_DllExport ChargerType& operator =( + ChargerType&& x) noexcept + { + + m_id = x.m_id; + m_charger_type = std::move(x.m_charger_type); + return *this; + } + + /*! + * @brief Comparison operator. + * @param x ChargerType object to compare. + */ + eProsima_user_DllExport bool operator ==( + const ChargerType& x) const + { + return (m_id == x.m_id && + m_charger_type == x.m_charger_type); + } + + /*! + * @brief Comparison operator. + * @param x ChargerType object to compare. + */ + eProsima_user_DllExport bool operator !=( + const ChargerType& x) const + { + return !(*this == x); + } + + /*! + * @brief This function sets a value in member id + * @param _id New value for member id + */ + eProsima_user_DllExport void id( + int32_t _id) + { + m_id = _id; + } + + /*! + * @brief This function returns the value of member id + * @return Value of member id + */ + eProsima_user_DllExport int32_t id() const + { + return m_id; + } + + /*! + * @brief This function returns a reference to member id + * @return Reference to member id + */ + eProsima_user_DllExport int32_t& id() + { + return m_id; + } + + + /*! + * @brief This function copies the value in member charger_type + * @param _charger_type New value to be copied in member charger_type + */ + eProsima_user_DllExport void charger_type( + const std::string& _charger_type) + { + m_charger_type = _charger_type; + } + + /*! + * @brief This function moves the value in member charger_type + * @param _charger_type New value to be moved in member charger_type + */ + eProsima_user_DllExport void charger_type( + std::string&& _charger_type) + { + m_charger_type = std::move(_charger_type); + } + + /*! + * @brief This function returns a constant reference to member charger_type + * @return Constant reference to member charger_type + */ + eProsima_user_DllExport const std::string& charger_type() const + { + return m_charger_type; + } + + /*! + * @brief This function returns a reference to member charger_type + * @return Reference to member charger_type + */ + eProsima_user_DllExport std::string& charger_type() + { + return m_charger_type; + } + + + +private: + + int32_t m_id{0}; + std::string m_charger_type; + +}; +typedef std::vector ChargerTypeSeq; + +/*! + * @brief This class represents the structure ChargingSession defined by the user in the IDL file. + * @ingroup pilot_server + */ +class ChargingSession +{ +public: + + /*! + * @brief Default constructor. + */ + eProsima_user_DllExport ChargingSession() + { + } + + /*! + * @brief Default destructor. + */ + eProsima_user_DllExport ~ChargingSession() + { + } + + /*! + * @brief Copy constructor. + * @param x Reference to the object ChargingSession that will be copied. + */ + eProsima_user_DllExport ChargingSession( + const ChargingSession& x) + { + m_id = x.m_id; + + m_station_id = x.m_station_id; + + m_charger_type_id = x.m_charger_type_id; + + m_consume_wh = x.m_consume_wh; + + m_duration_min = x.m_duration_min; + + m_date_iso8601 = x.m_date_iso8601; + + m_ingested_at_iso8601 = x.m_ingested_at_iso8601; + + } + + /*! + * @brief Move constructor. + * @param x Reference to the object ChargingSession that will be copied. + */ + eProsima_user_DllExport ChargingSession( + ChargingSession&& x) noexcept + { + m_id = x.m_id; + m_station_id = x.m_station_id; + m_charger_type_id = std::move(x.m_charger_type_id); + m_consume_wh = x.m_consume_wh; + m_duration_min = x.m_duration_min; + m_date_iso8601 = std::move(x.m_date_iso8601); + m_ingested_at_iso8601 = std::move(x.m_ingested_at_iso8601); + } + + /*! + * @brief Copy assignment. + * @param x Reference to the object ChargingSession that will be copied. + */ + eProsima_user_DllExport ChargingSession& operator =( + const ChargingSession& x) + { + + m_id = x.m_id; + + m_station_id = x.m_station_id; + + m_charger_type_id = x.m_charger_type_id; + + m_consume_wh = x.m_consume_wh; + + m_duration_min = x.m_duration_min; + + m_date_iso8601 = x.m_date_iso8601; + + m_ingested_at_iso8601 = x.m_ingested_at_iso8601; + + return *this; + } + + /*! + * @brief Move assignment. + * @param x Reference to the object ChargingSession that will be copied. + */ + eProsima_user_DllExport ChargingSession& operator =( + ChargingSession&& x) noexcept + { + + m_id = x.m_id; + m_station_id = x.m_station_id; + m_charger_type_id = std::move(x.m_charger_type_id); + m_consume_wh = x.m_consume_wh; + m_duration_min = x.m_duration_min; + m_date_iso8601 = std::move(x.m_date_iso8601); + m_ingested_at_iso8601 = std::move(x.m_ingested_at_iso8601); + return *this; + } + + /*! + * @brief Comparison operator. + * @param x ChargingSession object to compare. + */ + eProsima_user_DllExport bool operator ==( + const ChargingSession& x) const + { + return (m_id == x.m_id && + m_station_id == x.m_station_id && + m_charger_type_id == x.m_charger_type_id && + m_consume_wh == x.m_consume_wh && + m_duration_min == x.m_duration_min && + m_date_iso8601 == x.m_date_iso8601 && + m_ingested_at_iso8601 == x.m_ingested_at_iso8601); + } + + /*! + * @brief Comparison operator. + * @param x ChargingSession object to compare. + */ + eProsima_user_DllExport bool operator !=( + const ChargingSession& x) const + { + return !(*this == x); + } + + /*! + * @brief This function sets a value in member id + * @param _id New value for member id + */ + eProsima_user_DllExport void id( + int32_t _id) + { + m_id = _id; + } + + /*! + * @brief This function returns the value of member id + * @return Value of member id + */ + eProsima_user_DllExport int32_t id() const + { + return m_id; + } + + /*! + * @brief This function returns a reference to member id + * @return Reference to member id + */ + eProsima_user_DllExport int32_t& id() + { + return m_id; + } + + + /*! + * @brief This function sets a value in member station_id + * @param _station_id New value for member station_id + */ + eProsima_user_DllExport void station_id( + int32_t _station_id) + { + m_station_id = _station_id; + } + + /*! + * @brief This function returns the value of member station_id + * @return Value of member station_id + */ + eProsima_user_DllExport int32_t station_id() const + { + return m_station_id; + } + + /*! + * @brief This function returns a reference to member station_id + * @return Reference to member station_id + */ + eProsima_user_DllExport int32_t& station_id() + { + return m_station_id; + } + + + /*! + * @brief This function copies the value in member charger_type_id + * @param _charger_type_id New value to be copied in member charger_type_id + */ + eProsima_user_DllExport void charger_type_id( + const std::string& _charger_type_id) + { + m_charger_type_id = _charger_type_id; + } + + /*! + * @brief This function moves the value in member charger_type_id + * @param _charger_type_id New value to be moved in member charger_type_id + */ + eProsima_user_DllExport void charger_type_id( + std::string&& _charger_type_id) + { + m_charger_type_id = std::move(_charger_type_id); + } + + /*! + * @brief This function returns a constant reference to member charger_type_id + * @return Constant reference to member charger_type_id + */ + eProsima_user_DllExport const std::string& charger_type_id() const + { + return m_charger_type_id; + } + + /*! + * @brief This function returns a reference to member charger_type_id + * @return Reference to member charger_type_id + */ + eProsima_user_DllExport std::string& charger_type_id() + { + return m_charger_type_id; + } + + + /*! + * @brief This function sets a value in member consume_wh + * @param _consume_wh New value for member consume_wh + */ + eProsima_user_DllExport void consume_wh( + double _consume_wh) + { + m_consume_wh = _consume_wh; + } + + /*! + * @brief This function returns the value of member consume_wh + * @return Value of member consume_wh + */ + eProsima_user_DllExport double consume_wh() const + { + return m_consume_wh; + } + + /*! + * @brief This function returns a reference to member consume_wh + * @return Reference to member consume_wh + */ + eProsima_user_DllExport double& consume_wh() + { + return m_consume_wh; + } + + + /*! + * @brief This function sets a value in member duration_min + * @param _duration_min New value for member duration_min + */ + eProsima_user_DllExport void duration_min( + int32_t _duration_min) + { + m_duration_min = _duration_min; + } + + /*! + * @brief This function returns the value of member duration_min + * @return Value of member duration_min + */ + eProsima_user_DllExport int32_t duration_min() const + { + return m_duration_min; + } + + /*! + * @brief This function returns a reference to member duration_min + * @return Reference to member duration_min + */ + eProsima_user_DllExport int32_t& duration_min() + { + return m_duration_min; + } + + + /*! + * @brief This function copies the value in member date_iso8601 + * @param _date_iso8601 New value to be copied in member date_iso8601 + */ + eProsima_user_DllExport void date_iso8601( + const std::string& _date_iso8601) + { + m_date_iso8601 = _date_iso8601; + } + + /*! + * @brief This function moves the value in member date_iso8601 + * @param _date_iso8601 New value to be moved in member date_iso8601 + */ + eProsima_user_DllExport void date_iso8601( + std::string&& _date_iso8601) + { + m_date_iso8601 = std::move(_date_iso8601); + } + + /*! + * @brief This function returns a constant reference to member date_iso8601 + * @return Constant reference to member date_iso8601 + */ + eProsima_user_DllExport const std::string& date_iso8601() const + { + return m_date_iso8601; + } + + /*! + * @brief This function returns a reference to member date_iso8601 + * @return Reference to member date_iso8601 + */ + eProsima_user_DllExport std::string& date_iso8601() + { + return m_date_iso8601; + } + + + /*! + * @brief This function copies the value in member ingested_at_iso8601 + * @param _ingested_at_iso8601 New value to be copied in member ingested_at_iso8601 + */ + eProsima_user_DllExport void ingested_at_iso8601( + const std::string& _ingested_at_iso8601) + { + m_ingested_at_iso8601 = _ingested_at_iso8601; + } + + /*! + * @brief This function moves the value in member ingested_at_iso8601 + * @param _ingested_at_iso8601 New value to be moved in member ingested_at_iso8601 + */ + eProsima_user_DllExport void ingested_at_iso8601( + std::string&& _ingested_at_iso8601) + { + m_ingested_at_iso8601 = std::move(_ingested_at_iso8601); + } + + /*! + * @brief This function returns a constant reference to member ingested_at_iso8601 + * @return Constant reference to member ingested_at_iso8601 + */ + eProsima_user_DllExport const std::string& ingested_at_iso8601() const + { + return m_ingested_at_iso8601; + } + + /*! + * @brief This function returns a reference to member ingested_at_iso8601 + * @return Reference to member ingested_at_iso8601 + */ + eProsima_user_DllExport std::string& ingested_at_iso8601() + { + return m_ingested_at_iso8601; + } + + + +private: + + int32_t m_id{0}; + int32_t m_station_id{0}; + std::string m_charger_type_id; + double m_consume_wh{0.0}; + int32_t m_duration_min{0}; + std::string m_date_iso8601; + std::string m_ingested_at_iso8601; + +}; +typedef std::vector ChargingSessionSeq; + +/*! + * @brief This class represents the structure TransitHealth defined by the user in the IDL file. + * @ingroup pilot_server + */ +class TransitHealth +{ +public: + + /*! + * @brief Default constructor. + */ + eProsima_user_DllExport TransitHealth() + { + } + + /*! + * @brief Default destructor. + */ + eProsima_user_DllExport ~TransitHealth() + { + } + + /*! + * @brief Copy constructor. + * @param x Reference to the object TransitHealth that will be copied. + */ + eProsima_user_DllExport TransitHealth( + const TransitHealth& x) + { + m_status = x.m_status; + + m_last_fetch_ts = x.m_last_fetch_ts; + + } + + /*! + * @brief Move constructor. + * @param x Reference to the object TransitHealth that will be copied. + */ + eProsima_user_DllExport TransitHealth( + TransitHealth&& x) noexcept + { + m_status = std::move(x.m_status); + m_last_fetch_ts = x.m_last_fetch_ts; + } + + /*! + * @brief Copy assignment. + * @param x Reference to the object TransitHealth that will be copied. + */ + eProsima_user_DllExport TransitHealth& operator =( + const TransitHealth& x) + { + + m_status = x.m_status; + + m_last_fetch_ts = x.m_last_fetch_ts; + + return *this; + } + + /*! + * @brief Move assignment. + * @param x Reference to the object TransitHealth that will be copied. + */ + eProsima_user_DllExport TransitHealth& operator =( + TransitHealth&& x) noexcept + { + + m_status = std::move(x.m_status); + m_last_fetch_ts = x.m_last_fetch_ts; + return *this; + } + + /*! + * @brief Comparison operator. + * @param x TransitHealth object to compare. + */ + eProsima_user_DllExport bool operator ==( + const TransitHealth& x) const + { + return (m_status == x.m_status && + m_last_fetch_ts == x.m_last_fetch_ts); + } + + /*! + * @brief Comparison operator. + * @param x TransitHealth object to compare. + */ + eProsima_user_DllExport bool operator !=( + const TransitHealth& x) const + { + return !(*this == x); + } + + /*! + * @brief This function copies the value in member status + * @param _status New value to be copied in member status + */ + eProsima_user_DllExport void status( + const std::string& _status) + { + m_status = _status; + } + + /*! + * @brief This function moves the value in member status + * @param _status New value to be moved in member status + */ + eProsima_user_DllExport void status( + std::string&& _status) + { + m_status = std::move(_status); + } + + /*! + * @brief This function returns a constant reference to member status + * @return Constant reference to member status + */ + eProsima_user_DllExport const std::string& status() const + { + return m_status; + } + + /*! + * @brief This function returns a reference to member status + * @return Reference to member status + */ + eProsima_user_DllExport std::string& status() + { + return m_status; + } + + + /*! + * @brief This function sets a value in member last_fetch_ts + * @param _last_fetch_ts New value for member last_fetch_ts + */ + eProsima_user_DllExport void last_fetch_ts( + double _last_fetch_ts) + { + m_last_fetch_ts = _last_fetch_ts; + } + + /*! + * @brief This function returns the value of member last_fetch_ts + * @return Value of member last_fetch_ts + */ + eProsima_user_DllExport double last_fetch_ts() const + { + return m_last_fetch_ts; + } + + /*! + * @brief This function returns a reference to member last_fetch_ts + * @return Reference to member last_fetch_ts + */ + eProsima_user_DllExport double& last_fetch_ts() + { + return m_last_fetch_ts; + } + + + +private: + + std::string m_status; + double m_last_fetch_ts{0.0}; + +}; +/*! + * @brief This class represents the structure RouteMetric defined by the user in the IDL file. + * @ingroup pilot_server + */ +class RouteMetric +{ +public: + + /*! + * @brief Default constructor. + */ + eProsima_user_DllExport RouteMetric() + { + } + + /*! + * @brief Default destructor. + */ + eProsima_user_DllExport ~RouteMetric() + { + } + + /*! + * @brief Copy constructor. + * @param x Reference to the object RouteMetric that will be copied. + */ + eProsima_user_DllExport RouteMetric( + const RouteMetric& x) + { + m_route_id = x.m_route_id; + + m_updates_count = x.m_updates_count; + + } + + /*! + * @brief Move constructor. + * @param x Reference to the object RouteMetric that will be copied. + */ + eProsima_user_DllExport RouteMetric( + RouteMetric&& x) noexcept + { + m_route_id = std::move(x.m_route_id); + m_updates_count = x.m_updates_count; + } + + /*! + * @brief Copy assignment. + * @param x Reference to the object RouteMetric that will be copied. + */ + eProsima_user_DllExport RouteMetric& operator =( + const RouteMetric& x) + { + + m_route_id = x.m_route_id; + + m_updates_count = x.m_updates_count; + + return *this; + } + + /*! + * @brief Move assignment. + * @param x Reference to the object RouteMetric that will be copied. + */ + eProsima_user_DllExport RouteMetric& operator =( + RouteMetric&& x) noexcept + { + + m_route_id = std::move(x.m_route_id); + m_updates_count = x.m_updates_count; + return *this; + } + + /*! + * @brief Comparison operator. + * @param x RouteMetric object to compare. + */ + eProsima_user_DllExport bool operator ==( + const RouteMetric& x) const + { + return (m_route_id == x.m_route_id && + m_updates_count == x.m_updates_count); + } + + /*! + * @brief Comparison operator. + * @param x RouteMetric object to compare. + */ + eProsima_user_DllExport bool operator !=( + const RouteMetric& x) const + { + return !(*this == x); + } + + /*! + * @brief This function copies the value in member route_id + * @param _route_id New value to be copied in member route_id + */ + eProsima_user_DllExport void route_id( + const std::string& _route_id) + { + m_route_id = _route_id; + } + + /*! + * @brief This function moves the value in member route_id + * @param _route_id New value to be moved in member route_id + */ + eProsima_user_DllExport void route_id( + std::string&& _route_id) + { + m_route_id = std::move(_route_id); + } + + /*! + * @brief This function returns a constant reference to member route_id + * @return Constant reference to member route_id + */ + eProsima_user_DllExport const std::string& route_id() const + { + return m_route_id; + } + + /*! + * @brief This function returns a reference to member route_id + * @return Reference to member route_id + */ + eProsima_user_DllExport std::string& route_id() + { + return m_route_id; + } + + + /*! + * @brief This function sets a value in member updates_count + * @param _updates_count New value for member updates_count + */ + eProsima_user_DllExport void updates_count( + int32_t _updates_count) + { + m_updates_count = _updates_count; + } + + /*! + * @brief This function returns the value of member updates_count + * @return Value of member updates_count + */ + eProsima_user_DllExport int32_t updates_count() const + { + return m_updates_count; + } + + /*! + * @brief This function returns a reference to member updates_count + * @return Reference to member updates_count + */ + eProsima_user_DllExport int32_t& updates_count() + { + return m_updates_count; + } + + + +private: + + std::string m_route_id; + int32_t m_updates_count{0}; + +}; +typedef std::vector RouteMetricSeq; + +/*! + * @brief This class represents the structure TransitMetrics defined by the user in the IDL file. + * @ingroup pilot_server + */ +class TransitMetrics +{ +public: + + /*! + * @brief Default constructor. + */ + eProsima_user_DllExport TransitMetrics() + { + } + + /*! + * @brief Default destructor. + */ + eProsima_user_DllExport ~TransitMetrics() + { + } + + /*! + * @brief Copy constructor. + * @param x Reference to the object TransitMetrics that will be copied. + */ + eProsima_user_DllExport TransitMetrics( + const TransitMetrics& x) + { + m_by_route = x.m_by_route; + + m_vehicles_seen = x.m_vehicles_seen; + + } + + /*! + * @brief Move constructor. + * @param x Reference to the object TransitMetrics that will be copied. + */ + eProsima_user_DllExport TransitMetrics( + TransitMetrics&& x) noexcept + { + m_by_route = std::move(x.m_by_route); + m_vehicles_seen = x.m_vehicles_seen; + } + + /*! + * @brief Copy assignment. + * @param x Reference to the object TransitMetrics that will be copied. + */ + eProsima_user_DllExport TransitMetrics& operator =( + const TransitMetrics& x) + { + + m_by_route = x.m_by_route; + + m_vehicles_seen = x.m_vehicles_seen; + + return *this; + } + + /*! + * @brief Move assignment. + * @param x Reference to the object TransitMetrics that will be copied. + */ + eProsima_user_DllExport TransitMetrics& operator =( + TransitMetrics&& x) noexcept + { + + m_by_route = std::move(x.m_by_route); + m_vehicles_seen = x.m_vehicles_seen; + return *this; + } + + /*! + * @brief Comparison operator. + * @param x TransitMetrics object to compare. + */ + eProsima_user_DllExport bool operator ==( + const TransitMetrics& x) const + { + return (m_by_route == x.m_by_route && + m_vehicles_seen == x.m_vehicles_seen); + } + + /*! + * @brief Comparison operator. + * @param x TransitMetrics object to compare. + */ + eProsima_user_DllExport bool operator !=( + const TransitMetrics& x) const + { + return !(*this == x); + } + + /*! + * @brief This function copies the value in member by_route + * @param _by_route New value to be copied in member by_route + */ + eProsima_user_DllExport void by_route( + const RouteMetricSeq& _by_route) + { + m_by_route = _by_route; + } + + /*! + * @brief This function moves the value in member by_route + * @param _by_route New value to be moved in member by_route + */ + eProsima_user_DllExport void by_route( + RouteMetricSeq&& _by_route) + { + m_by_route = std::move(_by_route); + } + + /*! + * @brief This function returns a constant reference to member by_route + * @return Constant reference to member by_route + */ + eProsima_user_DllExport const RouteMetricSeq& by_route() const + { + return m_by_route; + } + + /*! + * @brief This function returns a reference to member by_route + * @return Reference to member by_route + */ + eProsima_user_DllExport RouteMetricSeq& by_route() + { + return m_by_route; + } + + + /*! + * @brief This function sets a value in member vehicles_seen + * @param _vehicles_seen New value for member vehicles_seen + */ + eProsima_user_DllExport void vehicles_seen( + int32_t _vehicles_seen) + { + m_vehicles_seen = _vehicles_seen; + } + + /*! + * @brief This function returns the value of member vehicles_seen + * @return Value of member vehicles_seen + */ + eProsima_user_DllExport int32_t vehicles_seen() const + { + return m_vehicles_seen; + } + + /*! + * @brief This function returns a reference to member vehicles_seen + * @return Reference to member vehicles_seen + */ + eProsima_user_DllExport int32_t& vehicles_seen() + { + return m_vehicles_seen; + } + + + +private: + + RouteMetricSeq m_by_route; + int32_t m_vehicles_seen{0}; + +}; +/*! + * @brief This class represents the enumeration RequestedDataType defined by the user in the IDL file. + * @ingroup pilot_server + */ +enum class RequestedDataType : int32_t +{ + CHARGER_LOCATION, + CHARGER_TYPE, + CHARGING_SESSION, + TRANSIT_HEALTH, + TRANSIT_METRICS +}; +/*! + * @brief This class represents the structure ServerQuery defined by the user in the IDL file. + * @ingroup pilot_server + */ +class ServerQuery +{ +public: + + /*! + * @brief Default constructor. + */ + eProsima_user_DllExport ServerQuery() + { + } + + /*! + * @brief Default destructor. + */ + eProsima_user_DllExport ~ServerQuery() + { + } + + /*! + * @brief Copy constructor. + * @param x Reference to the object ServerQuery that will be copied. + */ + eProsima_user_DllExport ServerQuery( + const ServerQuery& x) + { + m_requested_by = x.m_requested_by; + + m_requested_data_type = x.m_requested_data_type; + + } + + /*! + * @brief Move constructor. + * @param x Reference to the object ServerQuery that will be copied. + */ + eProsima_user_DllExport ServerQuery( + ServerQuery&& x) noexcept + { + m_requested_by = std::move(x.m_requested_by); + m_requested_data_type = x.m_requested_data_type; + } + + /*! + * @brief Copy assignment. + * @param x Reference to the object ServerQuery that will be copied. + */ + eProsima_user_DllExport ServerQuery& operator =( + const ServerQuery& x) + { + + m_requested_by = x.m_requested_by; + + m_requested_data_type = x.m_requested_data_type; + + return *this; + } + + /*! + * @brief Move assignment. + * @param x Reference to the object ServerQuery that will be copied. + */ + eProsima_user_DllExport ServerQuery& operator =( + ServerQuery&& x) noexcept + { + + m_requested_by = std::move(x.m_requested_by); + m_requested_data_type = x.m_requested_data_type; + return *this; + } + + /*! + * @brief Comparison operator. + * @param x ServerQuery object to compare. + */ + eProsima_user_DllExport bool operator ==( + const ServerQuery& x) const + { + return (m_requested_by == x.m_requested_by && + m_requested_data_type == x.m_requested_data_type); + } + + /*! + * @brief Comparison operator. + * @param x ServerQuery object to compare. + */ + eProsima_user_DllExport bool operator !=( + const ServerQuery& x) const + { + return !(*this == x); + } + + /*! + * @brief This function copies the value in member requested_by + * @param _requested_by New value to be copied in member requested_by + */ + eProsima_user_DllExport void requested_by( + const std::string& _requested_by) + { + m_requested_by = _requested_by; + } + + /*! + * @brief This function moves the value in member requested_by + * @param _requested_by New value to be moved in member requested_by + */ + eProsima_user_DllExport void requested_by( + std::string&& _requested_by) + { + m_requested_by = std::move(_requested_by); + } + + /*! + * @brief This function returns a constant reference to member requested_by + * @return Constant reference to member requested_by + */ + eProsima_user_DllExport const std::string& requested_by() const + { + return m_requested_by; + } + + /*! + * @brief This function returns a reference to member requested_by + * @return Reference to member requested_by + */ + eProsima_user_DllExport std::string& requested_by() + { + return m_requested_by; + } + + + /*! + * @brief This function sets a value in member requested_data_type + * @param _requested_data_type New value for member requested_data_type + */ + eProsima_user_DllExport void requested_data_type( + RequestedDataType _requested_data_type) + { + m_requested_data_type = _requested_data_type; + } + + /*! + * @brief This function returns the value of member requested_data_type + * @return Value of member requested_data_type + */ + eProsima_user_DllExport RequestedDataType requested_data_type() const + { + return m_requested_data_type; + } + + /*! + * @brief This function returns a reference to member requested_data_type + * @return Reference to member requested_data_type + */ + eProsima_user_DllExport RequestedDataType& requested_data_type() + { + return m_requested_data_type; + } + + + +private: + + std::string m_requested_by; + RequestedDataType m_requested_data_type{RequestedDataType::CHARGER_LOCATION}; + +}; + +} // namespace pilot_server + +} // namespace safe_edge + +#endif // _FAST_DDS_GENERATED_SAFE_EDGE_PILOT_SERVER_PILOT_SERVER_HPP_ + + diff --git a/fast_dds/idl/pilot_serverCdrAux.hpp b/fast_dds/idl/pilot_serverCdrAux.hpp new file mode 100644 index 0000000..fb82ca0 --- /dev/null +++ b/fast_dds/idl/pilot_serverCdrAux.hpp @@ -0,0 +1,98 @@ +// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/*! + * @file pilot_serverCdrAux.hpp + * This source file contains some definitions of CDR related functions. + * + * This file was generated by the tool fastddsgen (version: 4.3.0). + */ + +#ifndef FAST_DDS_GENERATED__SAFE_EDGE_PILOT_SERVER_PILOT_SERVERCDRAUX_HPP +#define FAST_DDS_GENERATED__SAFE_EDGE_PILOT_SERVER_PILOT_SERVERCDRAUX_HPP + +#include "pilot_server.hpp" + +constexpr uint32_t safe_edge_pilot_server_TransitMetrics_max_cdr_typesize {137232UL}; +constexpr uint32_t safe_edge_pilot_server_TransitMetrics_max_key_cdr_typesize {0UL}; + +constexpr uint32_t safe_edge_pilot_server_ChargingSession_max_cdr_typesize {804UL}; +constexpr uint32_t safe_edge_pilot_server_ChargingSession_max_key_cdr_typesize {0UL}; + +constexpr uint32_t safe_edge_pilot_server_ChargerLocation_max_cdr_typesize {288UL}; +constexpr uint32_t safe_edge_pilot_server_ChargerLocation_max_key_cdr_typesize {0UL}; + +constexpr uint32_t safe_edge_pilot_server_RouteMetric_max_cdr_typesize {268UL}; +constexpr uint32_t safe_edge_pilot_server_RouteMetric_max_key_cdr_typesize {0UL}; + +constexpr uint32_t safe_edge_pilot_server_ServerQuery_max_cdr_typesize {268UL}; +constexpr uint32_t safe_edge_pilot_server_ServerQuery_max_key_cdr_typesize {0UL}; + + + + + +constexpr uint32_t safe_edge_pilot_server_TransitHealth_max_cdr_typesize {272UL}; +constexpr uint32_t safe_edge_pilot_server_TransitHealth_max_key_cdr_typesize {0UL}; + + + + +constexpr uint32_t safe_edge_pilot_server_ChargerType_max_cdr_typesize {268UL}; +constexpr uint32_t safe_edge_pilot_server_ChargerType_max_key_cdr_typesize {0UL}; + + + + + +namespace eprosima { +namespace fastcdr { + +class Cdr; +class CdrSizeCalculator; + +eProsima_user_DllExport void serialize_key( + eprosima::fastcdr::Cdr& scdr, + const safe_edge::pilot_server::ChargerLocation& data); + +eProsima_user_DllExport void serialize_key( + eprosima::fastcdr::Cdr& scdr, + const safe_edge::pilot_server::ChargerType& data); + +eProsima_user_DllExport void serialize_key( + eprosima::fastcdr::Cdr& scdr, + const safe_edge::pilot_server::ChargingSession& data); + +eProsima_user_DllExport void serialize_key( + eprosima::fastcdr::Cdr& scdr, + const safe_edge::pilot_server::TransitHealth& data); + +eProsima_user_DllExport void serialize_key( + eprosima::fastcdr::Cdr& scdr, + const safe_edge::pilot_server::RouteMetric& data); + +eProsima_user_DllExport void serialize_key( + eprosima::fastcdr::Cdr& scdr, + const safe_edge::pilot_server::TransitMetrics& data); + +eProsima_user_DllExport void serialize_key( + eprosima::fastcdr::Cdr& scdr, + const safe_edge::pilot_server::ServerQuery& data); + + +} // namespace fastcdr +} // namespace eprosima + +#endif // FAST_DDS_GENERATED__SAFE_EDGE_PILOT_SERVER_PILOT_SERVERCDRAUX_HPP + diff --git a/fast_dds/idl/pilot_serverCdrAux.ipp b/fast_dds/idl/pilot_serverCdrAux.ipp new file mode 100644 index 0000000..8ad7de6 --- /dev/null +++ b/fast_dds/idl/pilot_serverCdrAux.ipp @@ -0,0 +1,778 @@ +// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/*! + * @file pilot_serverCdrAux.ipp + * This source file contains some declarations of CDR related functions. + * + * This file was generated by the tool fastddsgen (version: 4.3.0). + */ + +#ifndef FAST_DDS_GENERATED__SAFE_EDGE_PILOT_SERVER_PILOT_SERVERCDRAUX_IPP +#define FAST_DDS_GENERATED__SAFE_EDGE_PILOT_SERVER_PILOT_SERVERCDRAUX_IPP + +#include "pilot_serverCdrAux.hpp" + +#include +#include + + +#include +using namespace eprosima::fastcdr::exception; + +namespace eprosima { +namespace fastcdr { + +template<> +eProsima_user_DllExport size_t calculate_serialized_size( + eprosima::fastcdr::CdrSizeCalculator& calculator, + const safe_edge::pilot_server::ChargerLocation& data, + size_t& current_alignment) +{ + using namespace safe_edge::pilot_server; + + static_cast(data); + + eprosima::fastcdr::EncodingAlgorithmFlag previous_encoding = calculator.get_encoding(); + size_t calculated_size {calculator.begin_calculate_type_serialized_size( + eprosima::fastcdr::CdrVersion::XCDRv2 == calculator.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, + current_alignment)}; + + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(0), + data.id(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(1), + data.name(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(2), + data.position(), current_alignment); + + + calculated_size += calculator.end_calculate_type_serialized_size(previous_encoding, current_alignment); + + return calculated_size; +} + +template<> +eProsima_user_DllExport void serialize( + eprosima::fastcdr::Cdr& scdr, + const safe_edge::pilot_server::ChargerLocation& data) +{ + using namespace safe_edge::pilot_server; + + eprosima::fastcdr::Cdr::state current_state(scdr); + scdr.begin_serialize_type(current_state, + eprosima::fastcdr::CdrVersion::XCDRv2 == scdr.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR); + + scdr + << eprosima::fastcdr::MemberId(0) << data.id() + << eprosima::fastcdr::MemberId(1) << data.name() + << eprosima::fastcdr::MemberId(2) << data.position() +; + scdr.end_serialize_type(current_state); +} + +template<> +eProsima_user_DllExport void deserialize( + eprosima::fastcdr::Cdr& cdr, + safe_edge::pilot_server::ChargerLocation& data) +{ + using namespace safe_edge::pilot_server; + + cdr.deserialize_type(eprosima::fastcdr::CdrVersion::XCDRv2 == cdr.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, + [&data](eprosima::fastcdr::Cdr& dcdr, const eprosima::fastcdr::MemberId& mid) -> bool + { + bool ret_value = true; + switch (mid.id) + { + case 0: + dcdr >> data.id(); + break; + + case 1: + dcdr >> data.name(); + break; + + case 2: + dcdr >> data.position(); + break; + + default: + ret_value = false; + break; + } + return ret_value; + }); +} + +void serialize_key( + eprosima::fastcdr::Cdr& scdr, + const safe_edge::pilot_server::ChargerLocation& data) +{ + using namespace safe_edge::pilot_server; + extern void serialize_key( + Cdr& scdr, + const safe_edge::common::GeoPoint& data); + + + static_cast(scdr); + static_cast(data); + scdr << data.id(); + + scdr << data.name(); + + serialize_key(scdr, data.position()); + +} + + +template<> +eProsima_user_DllExport size_t calculate_serialized_size( + eprosima::fastcdr::CdrSizeCalculator& calculator, + const safe_edge::pilot_server::ChargerType& data, + size_t& current_alignment) +{ + using namespace safe_edge::pilot_server; + + static_cast(data); + + eprosima::fastcdr::EncodingAlgorithmFlag previous_encoding = calculator.get_encoding(); + size_t calculated_size {calculator.begin_calculate_type_serialized_size( + eprosima::fastcdr::CdrVersion::XCDRv2 == calculator.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, + current_alignment)}; + + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(0), + data.id(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(1), + data.charger_type(), current_alignment); + + + calculated_size += calculator.end_calculate_type_serialized_size(previous_encoding, current_alignment); + + return calculated_size; +} + +template<> +eProsima_user_DllExport void serialize( + eprosima::fastcdr::Cdr& scdr, + const safe_edge::pilot_server::ChargerType& data) +{ + using namespace safe_edge::pilot_server; + + eprosima::fastcdr::Cdr::state current_state(scdr); + scdr.begin_serialize_type(current_state, + eprosima::fastcdr::CdrVersion::XCDRv2 == scdr.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR); + + scdr + << eprosima::fastcdr::MemberId(0) << data.id() + << eprosima::fastcdr::MemberId(1) << data.charger_type() +; + scdr.end_serialize_type(current_state); +} + +template<> +eProsima_user_DllExport void deserialize( + eprosima::fastcdr::Cdr& cdr, + safe_edge::pilot_server::ChargerType& data) +{ + using namespace safe_edge::pilot_server; + + cdr.deserialize_type(eprosima::fastcdr::CdrVersion::XCDRv2 == cdr.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, + [&data](eprosima::fastcdr::Cdr& dcdr, const eprosima::fastcdr::MemberId& mid) -> bool + { + bool ret_value = true; + switch (mid.id) + { + case 0: + dcdr >> data.id(); + break; + + case 1: + dcdr >> data.charger_type(); + break; + + default: + ret_value = false; + break; + } + return ret_value; + }); +} + +void serialize_key( + eprosima::fastcdr::Cdr& scdr, + const safe_edge::pilot_server::ChargerType& data) +{ + using namespace safe_edge::pilot_server; + + static_cast(scdr); + static_cast(data); + scdr << data.id(); + + scdr << data.charger_type(); + +} + + +template<> +eProsima_user_DllExport size_t calculate_serialized_size( + eprosima::fastcdr::CdrSizeCalculator& calculator, + const safe_edge::pilot_server::ChargingSession& data, + size_t& current_alignment) +{ + using namespace safe_edge::pilot_server; + + static_cast(data); + + eprosima::fastcdr::EncodingAlgorithmFlag previous_encoding = calculator.get_encoding(); + size_t calculated_size {calculator.begin_calculate_type_serialized_size( + eprosima::fastcdr::CdrVersion::XCDRv2 == calculator.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, + current_alignment)}; + + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(0), + data.id(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(1), + data.station_id(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(2), + data.charger_type_id(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(3), + data.consume_wh(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(4), + data.duration_min(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(5), + data.date_iso8601(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(6), + data.ingested_at_iso8601(), current_alignment); + + + calculated_size += calculator.end_calculate_type_serialized_size(previous_encoding, current_alignment); + + return calculated_size; +} + +template<> +eProsima_user_DllExport void serialize( + eprosima::fastcdr::Cdr& scdr, + const safe_edge::pilot_server::ChargingSession& data) +{ + using namespace safe_edge::pilot_server; + + eprosima::fastcdr::Cdr::state current_state(scdr); + scdr.begin_serialize_type(current_state, + eprosima::fastcdr::CdrVersion::XCDRv2 == scdr.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR); + + scdr + << eprosima::fastcdr::MemberId(0) << data.id() + << eprosima::fastcdr::MemberId(1) << data.station_id() + << eprosima::fastcdr::MemberId(2) << data.charger_type_id() + << eprosima::fastcdr::MemberId(3) << data.consume_wh() + << eprosima::fastcdr::MemberId(4) << data.duration_min() + << eprosima::fastcdr::MemberId(5) << data.date_iso8601() + << eprosima::fastcdr::MemberId(6) << data.ingested_at_iso8601() +; + scdr.end_serialize_type(current_state); +} + +template<> +eProsima_user_DllExport void deserialize( + eprosima::fastcdr::Cdr& cdr, + safe_edge::pilot_server::ChargingSession& data) +{ + using namespace safe_edge::pilot_server; + + cdr.deserialize_type(eprosima::fastcdr::CdrVersion::XCDRv2 == cdr.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, + [&data](eprosima::fastcdr::Cdr& dcdr, const eprosima::fastcdr::MemberId& mid) -> bool + { + bool ret_value = true; + switch (mid.id) + { + case 0: + dcdr >> data.id(); + break; + + case 1: + dcdr >> data.station_id(); + break; + + case 2: + dcdr >> data.charger_type_id(); + break; + + case 3: + dcdr >> data.consume_wh(); + break; + + case 4: + dcdr >> data.duration_min(); + break; + + case 5: + dcdr >> data.date_iso8601(); + break; + + case 6: + dcdr >> data.ingested_at_iso8601(); + break; + + default: + ret_value = false; + break; + } + return ret_value; + }); +} + +void serialize_key( + eprosima::fastcdr::Cdr& scdr, + const safe_edge::pilot_server::ChargingSession& data) +{ + using namespace safe_edge::pilot_server; + + static_cast(scdr); + static_cast(data); + scdr << data.id(); + + scdr << data.station_id(); + + scdr << data.charger_type_id(); + + scdr << data.consume_wh(); + + scdr << data.duration_min(); + + scdr << data.date_iso8601(); + + scdr << data.ingested_at_iso8601(); + +} + + +template<> +eProsima_user_DllExport size_t calculate_serialized_size( + eprosima::fastcdr::CdrSizeCalculator& calculator, + const safe_edge::pilot_server::TransitHealth& data, + size_t& current_alignment) +{ + using namespace safe_edge::pilot_server; + + static_cast(data); + + eprosima::fastcdr::EncodingAlgorithmFlag previous_encoding = calculator.get_encoding(); + size_t calculated_size {calculator.begin_calculate_type_serialized_size( + eprosima::fastcdr::CdrVersion::XCDRv2 == calculator.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, + current_alignment)}; + + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(0), + data.status(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(1), + data.last_fetch_ts(), current_alignment); + + + calculated_size += calculator.end_calculate_type_serialized_size(previous_encoding, current_alignment); + + return calculated_size; +} + +template<> +eProsima_user_DllExport void serialize( + eprosima::fastcdr::Cdr& scdr, + const safe_edge::pilot_server::TransitHealth& data) +{ + using namespace safe_edge::pilot_server; + + eprosima::fastcdr::Cdr::state current_state(scdr); + scdr.begin_serialize_type(current_state, + eprosima::fastcdr::CdrVersion::XCDRv2 == scdr.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR); + + scdr + << eprosima::fastcdr::MemberId(0) << data.status() + << eprosima::fastcdr::MemberId(1) << data.last_fetch_ts() +; + scdr.end_serialize_type(current_state); +} + +template<> +eProsima_user_DllExport void deserialize( + eprosima::fastcdr::Cdr& cdr, + safe_edge::pilot_server::TransitHealth& data) +{ + using namespace safe_edge::pilot_server; + + cdr.deserialize_type(eprosima::fastcdr::CdrVersion::XCDRv2 == cdr.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, + [&data](eprosima::fastcdr::Cdr& dcdr, const eprosima::fastcdr::MemberId& mid) -> bool + { + bool ret_value = true; + switch (mid.id) + { + case 0: + dcdr >> data.status(); + break; + + case 1: + dcdr >> data.last_fetch_ts(); + break; + + default: + ret_value = false; + break; + } + return ret_value; + }); +} + +void serialize_key( + eprosima::fastcdr::Cdr& scdr, + const safe_edge::pilot_server::TransitHealth& data) +{ + using namespace safe_edge::pilot_server; + + static_cast(scdr); + static_cast(data); + scdr << data.status(); + + scdr << data.last_fetch_ts(); + +} + + +template<> +eProsima_user_DllExport size_t calculate_serialized_size( + eprosima::fastcdr::CdrSizeCalculator& calculator, + const safe_edge::pilot_server::RouteMetric& data, + size_t& current_alignment) +{ + using namespace safe_edge::pilot_server; + + static_cast(data); + + eprosima::fastcdr::EncodingAlgorithmFlag previous_encoding = calculator.get_encoding(); + size_t calculated_size {calculator.begin_calculate_type_serialized_size( + eprosima::fastcdr::CdrVersion::XCDRv2 == calculator.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, + current_alignment)}; + + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(0), + data.route_id(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(1), + data.updates_count(), current_alignment); + + + calculated_size += calculator.end_calculate_type_serialized_size(previous_encoding, current_alignment); + + return calculated_size; +} + +template<> +eProsima_user_DllExport void serialize( + eprosima::fastcdr::Cdr& scdr, + const safe_edge::pilot_server::RouteMetric& data) +{ + using namespace safe_edge::pilot_server; + + eprosima::fastcdr::Cdr::state current_state(scdr); + scdr.begin_serialize_type(current_state, + eprosima::fastcdr::CdrVersion::XCDRv2 == scdr.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR); + + scdr + << eprosima::fastcdr::MemberId(0) << data.route_id() + << eprosima::fastcdr::MemberId(1) << data.updates_count() +; + scdr.end_serialize_type(current_state); +} + +template<> +eProsima_user_DllExport void deserialize( + eprosima::fastcdr::Cdr& cdr, + safe_edge::pilot_server::RouteMetric& data) +{ + using namespace safe_edge::pilot_server; + + cdr.deserialize_type(eprosima::fastcdr::CdrVersion::XCDRv2 == cdr.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, + [&data](eprosima::fastcdr::Cdr& dcdr, const eprosima::fastcdr::MemberId& mid) -> bool + { + bool ret_value = true; + switch (mid.id) + { + case 0: + dcdr >> data.route_id(); + break; + + case 1: + dcdr >> data.updates_count(); + break; + + default: + ret_value = false; + break; + } + return ret_value; + }); +} + +void serialize_key( + eprosima::fastcdr::Cdr& scdr, + const safe_edge::pilot_server::RouteMetric& data) +{ + using namespace safe_edge::pilot_server; + + static_cast(scdr); + static_cast(data); + scdr << data.route_id(); + + scdr << data.updates_count(); + +} + + +template<> +eProsima_user_DllExport size_t calculate_serialized_size( + eprosima::fastcdr::CdrSizeCalculator& calculator, + const safe_edge::pilot_server::TransitMetrics& data, + size_t& current_alignment) +{ + using namespace safe_edge::pilot_server; + + static_cast(data); + + eprosima::fastcdr::EncodingAlgorithmFlag previous_encoding = calculator.get_encoding(); + size_t calculated_size {calculator.begin_calculate_type_serialized_size( + eprosima::fastcdr::CdrVersion::XCDRv2 == calculator.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, + current_alignment)}; + + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(0), + data.by_route(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(1), + data.vehicles_seen(), current_alignment); + + + calculated_size += calculator.end_calculate_type_serialized_size(previous_encoding, current_alignment); + + return calculated_size; +} + +template<> +eProsima_user_DllExport void serialize( + eprosima::fastcdr::Cdr& scdr, + const safe_edge::pilot_server::TransitMetrics& data) +{ + using namespace safe_edge::pilot_server; + + eprosima::fastcdr::Cdr::state current_state(scdr); + scdr.begin_serialize_type(current_state, + eprosima::fastcdr::CdrVersion::XCDRv2 == scdr.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR); + + scdr + << eprosima::fastcdr::MemberId(0) << data.by_route() + << eprosima::fastcdr::MemberId(1) << data.vehicles_seen() +; + scdr.end_serialize_type(current_state); +} + +template<> +eProsima_user_DllExport void deserialize( + eprosima::fastcdr::Cdr& cdr, + safe_edge::pilot_server::TransitMetrics& data) +{ + using namespace safe_edge::pilot_server; + + cdr.deserialize_type(eprosima::fastcdr::CdrVersion::XCDRv2 == cdr.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, + [&data](eprosima::fastcdr::Cdr& dcdr, const eprosima::fastcdr::MemberId& mid) -> bool + { + bool ret_value = true; + switch (mid.id) + { + case 0: + dcdr >> data.by_route(); + break; + + case 1: + dcdr >> data.vehicles_seen(); + break; + + default: + ret_value = false; + break; + } + return ret_value; + }); +} + +void serialize_key( + eprosima::fastcdr::Cdr& scdr, + const safe_edge::pilot_server::TransitMetrics& data) +{ + using namespace safe_edge::pilot_server; + + static_cast(scdr); + static_cast(data); + scdr << data.by_route(); + + scdr << data.vehicles_seen(); + +} + + +template<> +eProsima_user_DllExport size_t calculate_serialized_size( + eprosima::fastcdr::CdrSizeCalculator& calculator, + const safe_edge::pilot_server::ServerQuery& data, + size_t& current_alignment) +{ + using namespace safe_edge::pilot_server; + + static_cast(data); + + eprosima::fastcdr::EncodingAlgorithmFlag previous_encoding = calculator.get_encoding(); + size_t calculated_size {calculator.begin_calculate_type_serialized_size( + eprosima::fastcdr::CdrVersion::XCDRv2 == calculator.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, + current_alignment)}; + + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(0), + data.requested_by(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(1), + data.requested_data_type(), current_alignment); + + + calculated_size += calculator.end_calculate_type_serialized_size(previous_encoding, current_alignment); + + return calculated_size; +} + +template<> +eProsima_user_DllExport void serialize( + eprosima::fastcdr::Cdr& scdr, + const safe_edge::pilot_server::ServerQuery& data) +{ + using namespace safe_edge::pilot_server; + + eprosima::fastcdr::Cdr::state current_state(scdr); + scdr.begin_serialize_type(current_state, + eprosima::fastcdr::CdrVersion::XCDRv2 == scdr.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR); + + scdr + << eprosima::fastcdr::MemberId(0) << data.requested_by() + << eprosima::fastcdr::MemberId(1) << data.requested_data_type() +; + scdr.end_serialize_type(current_state); +} + +template<> +eProsima_user_DllExport void deserialize( + eprosima::fastcdr::Cdr& cdr, + safe_edge::pilot_server::ServerQuery& data) +{ + using namespace safe_edge::pilot_server; + + cdr.deserialize_type(eprosima::fastcdr::CdrVersion::XCDRv2 == cdr.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, + [&data](eprosima::fastcdr::Cdr& dcdr, const eprosima::fastcdr::MemberId& mid) -> bool + { + bool ret_value = true; + switch (mid.id) + { + case 0: + dcdr >> data.requested_by(); + break; + + case 1: + dcdr >> data.requested_data_type(); + break; + + default: + ret_value = false; + break; + } + return ret_value; + }); +} + +void serialize_key( + eprosima::fastcdr::Cdr& scdr, + const safe_edge::pilot_server::ServerQuery& data) +{ + using namespace safe_edge::pilot_server; + + static_cast(scdr); + static_cast(data); + scdr << data.requested_by(); + + scdr << data.requested_data_type(); + +} + + + +} // namespace fastcdr +} // namespace eprosima + +#endif // FAST_DDS_GENERATED__SAFE_EDGE_PILOT_SERVER_PILOT_SERVERCDRAUX_IPP + diff --git a/fast_dds/idl/pilot_serverPubSubTypes.cxx b/fast_dds/idl/pilot_serverPubSubTypes.cxx new file mode 100644 index 0000000..077e32f --- /dev/null +++ b/fast_dds/idl/pilot_serverPubSubTypes.cxx @@ -0,0 +1,1046 @@ +// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/*! + * @file pilot_serverPubSubTypes.cpp + * This header file contains the implementation of the serialization functions. + * + * This file was generated by the tool fastddsgen (version: 4.3.0). + */ + +#include "pilot_serverPubSubTypes.hpp" + +#include +#include + +#include +#include + +#include "pilot_serverCdrAux.hpp" +#include "pilot_serverTypeObjectSupport.hpp" + +using SerializedPayload_t = eprosima::fastdds::rtps::SerializedPayload_t; +using InstanceHandle_t = eprosima::fastdds::rtps::InstanceHandle_t; +using DataRepresentationId_t = eprosima::fastdds::dds::DataRepresentationId_t; + +namespace safe_edge { +namespace pilot_server { +ChargerLocationPubSubType::ChargerLocationPubSubType() +{ + set_name("safe_edge::pilot_server::ChargerLocation"); + uint32_t type_size = safe_edge_pilot_server_ChargerLocation_max_cdr_typesize; + type_size += static_cast(eprosima::fastcdr::Cdr::alignment(type_size, 4)); /* possible submessage alignment */ + max_serialized_type_size = type_size + 4; /*encapsulation*/ + is_compute_key_provided = false; +} + +ChargerLocationPubSubType::~ChargerLocationPubSubType() +{ +} + +bool ChargerLocationPubSubType::serialize( + const void* const data, + SerializedPayload_t& payload, + DataRepresentationId_t data_representation) +{ + const ::safe_edge::pilot_server::ChargerLocation* p_type = + static_cast(data); + + // Object that manages the raw buffer. + eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(payload.data), payload.max_size); + // Object that serializes the data. + eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN, + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::CdrVersion::XCDRv1 : eprosima::fastcdr::CdrVersion::XCDRv2); + payload.encapsulation = ser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE; + ser.set_encoding_flag( + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR : + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2); + + try + { + // Serialize encapsulation + ser.serialize_encapsulation(); + // Serialize the object. + ser << *p_type; + ser.set_dds_cdr_options({0, 0}); + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return false; + } + + // Get the serialized length + payload.length = static_cast(ser.get_serialized_data_length()); + return true; +} + +bool ChargerLocationPubSubType::deserialize( + SerializedPayload_t& payload, + void* data) +{ + try + { + // Convert DATA to pointer of your type + ::safe_edge::pilot_server::ChargerLocation* p_type = + static_cast<::safe_edge::pilot_server::ChargerLocation*>(data); + + // Object that manages the raw buffer. + eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(payload.data), payload.length); + + // Object that deserializes the data. + eprosima::fastcdr::Cdr deser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN); + + // Deserialize encapsulation. + deser.read_encapsulation(); + payload.encapsulation = deser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE; + + // Deserialize the object. + deser >> *p_type; + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return false; + } + + return true; +} + +uint32_t ChargerLocationPubSubType::calculate_serialized_size( + const void* const data, + DataRepresentationId_t data_representation) +{ + try + { + eprosima::fastcdr::CdrSizeCalculator calculator( + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::CdrVersion::XCDRv1 :eprosima::fastcdr::CdrVersion::XCDRv2); + size_t current_alignment {0}; + const ::safe_edge::pilot_server::ChargerLocation* p_type = + static_cast(data); + auto calc_size = calculator.calculate_serialized_size(*p_type, current_alignment); + return static_cast(calc_size) + 4u /*encapsulation*/; + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return 0; + } +} + +void* ChargerLocationPubSubType::create_data() +{ + return reinterpret_cast(new ::safe_edge::pilot_server::ChargerLocation()); +} + +void ChargerLocationPubSubType::delete_data( + void* data) +{ + delete(reinterpret_cast<::safe_edge::pilot_server::ChargerLocation*>(data)); +} + +bool ChargerLocationPubSubType::compute_key( + SerializedPayload_t& payload, + InstanceHandle_t& handle, + bool force_md5) +{ + static_cast(payload); + static_cast(handle); + static_cast(force_md5); + + return false; +} + +bool ChargerLocationPubSubType::compute_key( + const void* const data, + InstanceHandle_t& handle, + bool force_md5) +{ + static_cast(data); + static_cast(handle); + static_cast(force_md5); + + return false; +} + +void ChargerLocationPubSubType::register_type_object_representation() +{ + register_ChargerLocation_type_identifier(type_identifiers_); +} + +ChargerTypePubSubType::ChargerTypePubSubType() +{ + set_name("safe_edge::pilot_server::ChargerType"); + uint32_t type_size = safe_edge_pilot_server_ChargerType_max_cdr_typesize; + type_size += static_cast(eprosima::fastcdr::Cdr::alignment(type_size, 4)); /* possible submessage alignment */ + max_serialized_type_size = type_size + 4; /*encapsulation*/ + is_compute_key_provided = false; +} + +ChargerTypePubSubType::~ChargerTypePubSubType() +{ +} + +bool ChargerTypePubSubType::serialize( + const void* const data, + SerializedPayload_t& payload, + DataRepresentationId_t data_representation) +{ + const ::safe_edge::pilot_server::ChargerType* p_type = + static_cast(data); + + // Object that manages the raw buffer. + eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(payload.data), payload.max_size); + // Object that serializes the data. + eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN, + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::CdrVersion::XCDRv1 : eprosima::fastcdr::CdrVersion::XCDRv2); + payload.encapsulation = ser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE; + ser.set_encoding_flag( + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR : + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2); + + try + { + // Serialize encapsulation + ser.serialize_encapsulation(); + // Serialize the object. + ser << *p_type; + ser.set_dds_cdr_options({0, 0}); + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return false; + } + + // Get the serialized length + payload.length = static_cast(ser.get_serialized_data_length()); + return true; +} + +bool ChargerTypePubSubType::deserialize( + SerializedPayload_t& payload, + void* data) +{ + try + { + // Convert DATA to pointer of your type + ::safe_edge::pilot_server::ChargerType* p_type = + static_cast<::safe_edge::pilot_server::ChargerType*>(data); + + // Object that manages the raw buffer. + eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(payload.data), payload.length); + + // Object that deserializes the data. + eprosima::fastcdr::Cdr deser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN); + + // Deserialize encapsulation. + deser.read_encapsulation(); + payload.encapsulation = deser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE; + + // Deserialize the object. + deser >> *p_type; + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return false; + } + + return true; +} + +uint32_t ChargerTypePubSubType::calculate_serialized_size( + const void* const data, + DataRepresentationId_t data_representation) +{ + try + { + eprosima::fastcdr::CdrSizeCalculator calculator( + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::CdrVersion::XCDRv1 :eprosima::fastcdr::CdrVersion::XCDRv2); + size_t current_alignment {0}; + const ::safe_edge::pilot_server::ChargerType* p_type = + static_cast(data); + auto calc_size = calculator.calculate_serialized_size(*p_type, current_alignment); + return static_cast(calc_size) + 4u /*encapsulation*/; + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return 0; + } +} + +void* ChargerTypePubSubType::create_data() +{ + return reinterpret_cast(new ::safe_edge::pilot_server::ChargerType()); +} + +void ChargerTypePubSubType::delete_data( + void* data) +{ + delete(reinterpret_cast<::safe_edge::pilot_server::ChargerType*>(data)); +} + +bool ChargerTypePubSubType::compute_key( + SerializedPayload_t& payload, + InstanceHandle_t& handle, + bool force_md5) +{ + static_cast(payload); + static_cast(handle); + static_cast(force_md5); + + return false; +} + +bool ChargerTypePubSubType::compute_key( + const void* const data, + InstanceHandle_t& handle, + bool force_md5) +{ + static_cast(data); + static_cast(handle); + static_cast(force_md5); + + return false; +} + +void ChargerTypePubSubType::register_type_object_representation() +{ + register_ChargerType_type_identifier(type_identifiers_); +} + +ChargingSessionPubSubType::ChargingSessionPubSubType() +{ + set_name("safe_edge::pilot_server::ChargingSession"); + uint32_t type_size = safe_edge_pilot_server_ChargingSession_max_cdr_typesize; + type_size += static_cast(eprosima::fastcdr::Cdr::alignment(type_size, 4)); /* possible submessage alignment */ + max_serialized_type_size = type_size + 4; /*encapsulation*/ + is_compute_key_provided = false; +} + +ChargingSessionPubSubType::~ChargingSessionPubSubType() +{ +} + +bool ChargingSessionPubSubType::serialize( + const void* const data, + SerializedPayload_t& payload, + DataRepresentationId_t data_representation) +{ + const ::safe_edge::pilot_server::ChargingSession* p_type = + static_cast(data); + + // Object that manages the raw buffer. + eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(payload.data), payload.max_size); + // Object that serializes the data. + eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN, + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::CdrVersion::XCDRv1 : eprosima::fastcdr::CdrVersion::XCDRv2); + payload.encapsulation = ser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE; + ser.set_encoding_flag( + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR : + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2); + + try + { + // Serialize encapsulation + ser.serialize_encapsulation(); + // Serialize the object. + ser << *p_type; + ser.set_dds_cdr_options({0, 0}); + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return false; + } + + // Get the serialized length + payload.length = static_cast(ser.get_serialized_data_length()); + return true; +} + +bool ChargingSessionPubSubType::deserialize( + SerializedPayload_t& payload, + void* data) +{ + try + { + // Convert DATA to pointer of your type + ::safe_edge::pilot_server::ChargingSession* p_type = + static_cast<::safe_edge::pilot_server::ChargingSession*>(data); + + // Object that manages the raw buffer. + eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(payload.data), payload.length); + + // Object that deserializes the data. + eprosima::fastcdr::Cdr deser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN); + + // Deserialize encapsulation. + deser.read_encapsulation(); + payload.encapsulation = deser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE; + + // Deserialize the object. + deser >> *p_type; + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return false; + } + + return true; +} + +uint32_t ChargingSessionPubSubType::calculate_serialized_size( + const void* const data, + DataRepresentationId_t data_representation) +{ + try + { + eprosima::fastcdr::CdrSizeCalculator calculator( + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::CdrVersion::XCDRv1 :eprosima::fastcdr::CdrVersion::XCDRv2); + size_t current_alignment {0}; + const ::safe_edge::pilot_server::ChargingSession* p_type = + static_cast(data); + auto calc_size = calculator.calculate_serialized_size(*p_type, current_alignment); + return static_cast(calc_size) + 4u /*encapsulation*/; + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return 0; + } +} + +void* ChargingSessionPubSubType::create_data() +{ + return reinterpret_cast(new ::safe_edge::pilot_server::ChargingSession()); +} + +void ChargingSessionPubSubType::delete_data( + void* data) +{ + delete(reinterpret_cast<::safe_edge::pilot_server::ChargingSession*>(data)); +} + +bool ChargingSessionPubSubType::compute_key( + SerializedPayload_t& payload, + InstanceHandle_t& handle, + bool force_md5) +{ + static_cast(payload); + static_cast(handle); + static_cast(force_md5); + + return false; +} + +bool ChargingSessionPubSubType::compute_key( + const void* const data, + InstanceHandle_t& handle, + bool force_md5) +{ + static_cast(data); + static_cast(handle); + static_cast(force_md5); + + return false; +} + +void ChargingSessionPubSubType::register_type_object_representation() +{ + register_ChargingSession_type_identifier(type_identifiers_); +} + +TransitHealthPubSubType::TransitHealthPubSubType() +{ + set_name("safe_edge::pilot_server::TransitHealth"); + uint32_t type_size = safe_edge_pilot_server_TransitHealth_max_cdr_typesize; + type_size += static_cast(eprosima::fastcdr::Cdr::alignment(type_size, 4)); /* possible submessage alignment */ + max_serialized_type_size = type_size + 4; /*encapsulation*/ + is_compute_key_provided = false; +} + +TransitHealthPubSubType::~TransitHealthPubSubType() +{ +} + +bool TransitHealthPubSubType::serialize( + const void* const data, + SerializedPayload_t& payload, + DataRepresentationId_t data_representation) +{ + const ::safe_edge::pilot_server::TransitHealth* p_type = + static_cast(data); + + // Object that manages the raw buffer. + eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(payload.data), payload.max_size); + // Object that serializes the data. + eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN, + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::CdrVersion::XCDRv1 : eprosima::fastcdr::CdrVersion::XCDRv2); + payload.encapsulation = ser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE; + ser.set_encoding_flag( + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR : + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2); + + try + { + // Serialize encapsulation + ser.serialize_encapsulation(); + // Serialize the object. + ser << *p_type; + ser.set_dds_cdr_options({0, 0}); + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return false; + } + + // Get the serialized length + payload.length = static_cast(ser.get_serialized_data_length()); + return true; +} + +bool TransitHealthPubSubType::deserialize( + SerializedPayload_t& payload, + void* data) +{ + try + { + // Convert DATA to pointer of your type + ::safe_edge::pilot_server::TransitHealth* p_type = + static_cast<::safe_edge::pilot_server::TransitHealth*>(data); + + // Object that manages the raw buffer. + eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(payload.data), payload.length); + + // Object that deserializes the data. + eprosima::fastcdr::Cdr deser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN); + + // Deserialize encapsulation. + deser.read_encapsulation(); + payload.encapsulation = deser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE; + + // Deserialize the object. + deser >> *p_type; + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return false; + } + + return true; +} + +uint32_t TransitHealthPubSubType::calculate_serialized_size( + const void* const data, + DataRepresentationId_t data_representation) +{ + try + { + eprosima::fastcdr::CdrSizeCalculator calculator( + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::CdrVersion::XCDRv1 :eprosima::fastcdr::CdrVersion::XCDRv2); + size_t current_alignment {0}; + const ::safe_edge::pilot_server::TransitHealth* p_type = + static_cast(data); + auto calc_size = calculator.calculate_serialized_size(*p_type, current_alignment); + return static_cast(calc_size) + 4u /*encapsulation*/; + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return 0; + } +} + +void* TransitHealthPubSubType::create_data() +{ + return reinterpret_cast(new ::safe_edge::pilot_server::TransitHealth()); +} + +void TransitHealthPubSubType::delete_data( + void* data) +{ + delete(reinterpret_cast<::safe_edge::pilot_server::TransitHealth*>(data)); +} + +bool TransitHealthPubSubType::compute_key( + SerializedPayload_t& payload, + InstanceHandle_t& handle, + bool force_md5) +{ + static_cast(payload); + static_cast(handle); + static_cast(force_md5); + + return false; +} + +bool TransitHealthPubSubType::compute_key( + const void* const data, + InstanceHandle_t& handle, + bool force_md5) +{ + static_cast(data); + static_cast(handle); + static_cast(force_md5); + + return false; +} + +void TransitHealthPubSubType::register_type_object_representation() +{ + register_TransitHealth_type_identifier(type_identifiers_); +} + +RouteMetricPubSubType::RouteMetricPubSubType() +{ + set_name("safe_edge::pilot_server::RouteMetric"); + uint32_t type_size = safe_edge_pilot_server_RouteMetric_max_cdr_typesize; + type_size += static_cast(eprosima::fastcdr::Cdr::alignment(type_size, 4)); /* possible submessage alignment */ + max_serialized_type_size = type_size + 4; /*encapsulation*/ + is_compute_key_provided = false; +} + +RouteMetricPubSubType::~RouteMetricPubSubType() +{ +} + +bool RouteMetricPubSubType::serialize( + const void* const data, + SerializedPayload_t& payload, + DataRepresentationId_t data_representation) +{ + const ::safe_edge::pilot_server::RouteMetric* p_type = + static_cast(data); + + // Object that manages the raw buffer. + eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(payload.data), payload.max_size); + // Object that serializes the data. + eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN, + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::CdrVersion::XCDRv1 : eprosima::fastcdr::CdrVersion::XCDRv2); + payload.encapsulation = ser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE; + ser.set_encoding_flag( + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR : + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2); + + try + { + // Serialize encapsulation + ser.serialize_encapsulation(); + // Serialize the object. + ser << *p_type; + ser.set_dds_cdr_options({0, 0}); + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return false; + } + + // Get the serialized length + payload.length = static_cast(ser.get_serialized_data_length()); + return true; +} + +bool RouteMetricPubSubType::deserialize( + SerializedPayload_t& payload, + void* data) +{ + try + { + // Convert DATA to pointer of your type + ::safe_edge::pilot_server::RouteMetric* p_type = + static_cast<::safe_edge::pilot_server::RouteMetric*>(data); + + // Object that manages the raw buffer. + eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(payload.data), payload.length); + + // Object that deserializes the data. + eprosima::fastcdr::Cdr deser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN); + + // Deserialize encapsulation. + deser.read_encapsulation(); + payload.encapsulation = deser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE; + + // Deserialize the object. + deser >> *p_type; + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return false; + } + + return true; +} + +uint32_t RouteMetricPubSubType::calculate_serialized_size( + const void* const data, + DataRepresentationId_t data_representation) +{ + try + { + eprosima::fastcdr::CdrSizeCalculator calculator( + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::CdrVersion::XCDRv1 :eprosima::fastcdr::CdrVersion::XCDRv2); + size_t current_alignment {0}; + const ::safe_edge::pilot_server::RouteMetric* p_type = + static_cast(data); + auto calc_size = calculator.calculate_serialized_size(*p_type, current_alignment); + return static_cast(calc_size) + 4u /*encapsulation*/; + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return 0; + } +} + +void* RouteMetricPubSubType::create_data() +{ + return reinterpret_cast(new ::safe_edge::pilot_server::RouteMetric()); +} + +void RouteMetricPubSubType::delete_data( + void* data) +{ + delete(reinterpret_cast<::safe_edge::pilot_server::RouteMetric*>(data)); +} + +bool RouteMetricPubSubType::compute_key( + SerializedPayload_t& payload, + InstanceHandle_t& handle, + bool force_md5) +{ + static_cast(payload); + static_cast(handle); + static_cast(force_md5); + + return false; +} + +bool RouteMetricPubSubType::compute_key( + const void* const data, + InstanceHandle_t& handle, + bool force_md5) +{ + static_cast(data); + static_cast(handle); + static_cast(force_md5); + + return false; +} + +void RouteMetricPubSubType::register_type_object_representation() +{ + register_RouteMetric_type_identifier(type_identifiers_); +} + +TransitMetricsPubSubType::TransitMetricsPubSubType() +{ + set_name("safe_edge::pilot_server::TransitMetrics"); + uint32_t type_size = safe_edge_pilot_server_TransitMetrics_max_cdr_typesize; + type_size += static_cast(eprosima::fastcdr::Cdr::alignment(type_size, 4)); /* possible submessage alignment */ + max_serialized_type_size = type_size + 4; /*encapsulation*/ + is_compute_key_provided = false; +} + +TransitMetricsPubSubType::~TransitMetricsPubSubType() +{ +} + +bool TransitMetricsPubSubType::serialize( + const void* const data, + SerializedPayload_t& payload, + DataRepresentationId_t data_representation) +{ + const ::safe_edge::pilot_server::TransitMetrics* p_type = + static_cast(data); + + // Object that manages the raw buffer. + eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(payload.data), payload.max_size); + // Object that serializes the data. + eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN, + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::CdrVersion::XCDRv1 : eprosima::fastcdr::CdrVersion::XCDRv2); + payload.encapsulation = ser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE; + ser.set_encoding_flag( + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR : + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2); + + try + { + // Serialize encapsulation + ser.serialize_encapsulation(); + // Serialize the object. + ser << *p_type; + ser.set_dds_cdr_options({0, 0}); + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return false; + } + + // Get the serialized length + payload.length = static_cast(ser.get_serialized_data_length()); + return true; +} + +bool TransitMetricsPubSubType::deserialize( + SerializedPayload_t& payload, + void* data) +{ + try + { + // Convert DATA to pointer of your type + ::safe_edge::pilot_server::TransitMetrics* p_type = + static_cast<::safe_edge::pilot_server::TransitMetrics*>(data); + + // Object that manages the raw buffer. + eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(payload.data), payload.length); + + // Object that deserializes the data. + eprosima::fastcdr::Cdr deser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN); + + // Deserialize encapsulation. + deser.read_encapsulation(); + payload.encapsulation = deser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE; + + // Deserialize the object. + deser >> *p_type; + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return false; + } + + return true; +} + +uint32_t TransitMetricsPubSubType::calculate_serialized_size( + const void* const data, + DataRepresentationId_t data_representation) +{ + try + { + eprosima::fastcdr::CdrSizeCalculator calculator( + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::CdrVersion::XCDRv1 :eprosima::fastcdr::CdrVersion::XCDRv2); + size_t current_alignment {0}; + const ::safe_edge::pilot_server::TransitMetrics* p_type = + static_cast(data); + auto calc_size = calculator.calculate_serialized_size(*p_type, current_alignment); + return static_cast(calc_size) + 4u /*encapsulation*/; + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return 0; + } +} + +void* TransitMetricsPubSubType::create_data() +{ + return reinterpret_cast(new ::safe_edge::pilot_server::TransitMetrics()); +} + +void TransitMetricsPubSubType::delete_data( + void* data) +{ + delete(reinterpret_cast<::safe_edge::pilot_server::TransitMetrics*>(data)); +} + +bool TransitMetricsPubSubType::compute_key( + SerializedPayload_t& payload, + InstanceHandle_t& handle, + bool force_md5) +{ + static_cast(payload); + static_cast(handle); + static_cast(force_md5); + + return false; +} + +bool TransitMetricsPubSubType::compute_key( + const void* const data, + InstanceHandle_t& handle, + bool force_md5) +{ + static_cast(data); + static_cast(handle); + static_cast(force_md5); + + return false; +} + +void TransitMetricsPubSubType::register_type_object_representation() +{ + register_TransitMetrics_type_identifier(type_identifiers_); +} + +ServerQueryPubSubType::ServerQueryPubSubType() +{ + set_name("safe_edge::pilot_server::ServerQuery"); + uint32_t type_size = safe_edge_pilot_server_ServerQuery_max_cdr_typesize; + type_size += static_cast(eprosima::fastcdr::Cdr::alignment(type_size, 4)); /* possible submessage alignment */ + max_serialized_type_size = type_size + 4; /*encapsulation*/ + is_compute_key_provided = false; +} + +ServerQueryPubSubType::~ServerQueryPubSubType() +{ +} + +bool ServerQueryPubSubType::serialize( + const void* const data, + SerializedPayload_t& payload, + DataRepresentationId_t data_representation) +{ + const ::safe_edge::pilot_server::ServerQuery* p_type = + static_cast(data); + + // Object that manages the raw buffer. + eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(payload.data), payload.max_size); + // Object that serializes the data. + eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN, + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::CdrVersion::XCDRv1 : eprosima::fastcdr::CdrVersion::XCDRv2); + payload.encapsulation = ser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE; + ser.set_encoding_flag( + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR : + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2); + + try + { + // Serialize encapsulation + ser.serialize_encapsulation(); + // Serialize the object. + ser << *p_type; + ser.set_dds_cdr_options({0, 0}); + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return false; + } + + // Get the serialized length + payload.length = static_cast(ser.get_serialized_data_length()); + return true; +} + +bool ServerQueryPubSubType::deserialize( + SerializedPayload_t& payload, + void* data) +{ + try + { + // Convert DATA to pointer of your type + ::safe_edge::pilot_server::ServerQuery* p_type = + static_cast<::safe_edge::pilot_server::ServerQuery*>(data); + + // Object that manages the raw buffer. + eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(payload.data), payload.length); + + // Object that deserializes the data. + eprosima::fastcdr::Cdr deser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN); + + // Deserialize encapsulation. + deser.read_encapsulation(); + payload.encapsulation = deser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE; + + // Deserialize the object. + deser >> *p_type; + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return false; + } + + return true; +} + +uint32_t ServerQueryPubSubType::calculate_serialized_size( + const void* const data, + DataRepresentationId_t data_representation) +{ + try + { + eprosima::fastcdr::CdrSizeCalculator calculator( + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::CdrVersion::XCDRv1 :eprosima::fastcdr::CdrVersion::XCDRv2); + size_t current_alignment {0}; + const ::safe_edge::pilot_server::ServerQuery* p_type = + static_cast(data); + auto calc_size = calculator.calculate_serialized_size(*p_type, current_alignment); + return static_cast(calc_size) + 4u /*encapsulation*/; + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return 0; + } +} + +void* ServerQueryPubSubType::create_data() +{ + return reinterpret_cast(new ::safe_edge::pilot_server::ServerQuery()); +} + +void ServerQueryPubSubType::delete_data( + void* data) +{ + delete(reinterpret_cast<::safe_edge::pilot_server::ServerQuery*>(data)); +} + +bool ServerQueryPubSubType::compute_key( + SerializedPayload_t& payload, + InstanceHandle_t& handle, + bool force_md5) +{ + static_cast(payload); + static_cast(handle); + static_cast(force_md5); + + return false; +} + +bool ServerQueryPubSubType::compute_key( + const void* const data, + InstanceHandle_t& handle, + bool force_md5) +{ + static_cast(data); + static_cast(handle); + static_cast(force_md5); + + return false; +} + +void ServerQueryPubSubType::register_type_object_representation() +{ + register_ServerQuery_type_identifier(type_identifiers_); +} + +} // namespace pilot_server + +} // namespace safe_edge + + +// Include auxiliary functions like for serializing/deserializing. +#include "pilot_serverCdrAux.ipp" diff --git a/fast_dds/idl/pilot_serverPubSubTypes.hpp b/fast_dds/idl/pilot_serverPubSubTypes.hpp new file mode 100644 index 0000000..9ebc4f2 --- /dev/null +++ b/fast_dds/idl/pilot_serverPubSubTypes.hpp @@ -0,0 +1,606 @@ +// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/*! + * @file pilot_serverPubSubTypes.hpp + * This header file contains the declaration of the serialization functions. + * + * This file was generated by the tool fastddsgen (version: 4.3.0). + */ + + +#ifndef FAST_DDS_GENERATED__SAFE_EDGE_PILOT_SERVER_PILOT_SERVER_PUBSUBTYPES_HPP +#define FAST_DDS_GENERATED__SAFE_EDGE_PILOT_SERVER_PILOT_SERVER_PUBSUBTYPES_HPP + +#include + +#include +#include +#include +#include +#include + +#include "pilot_server.hpp" + +#include "commonPubSubTypes.hpp" + +#if !defined(FASTDDS_GEN_API_VER) || (FASTDDS_GEN_API_VER != 3) +#error \ + Generated pilot_server is not compatible with current installed Fast DDS. Please, regenerate it with fastddsgen. +#endif // FASTDDS_GEN_API_VER + +namespace safe_edge { +namespace pilot_server { + +/*! + * @brief This class represents the TopicDataType of the type ChargerLocation defined by the user in the IDL file. + * @ingroup pilot_server + */ +class ChargerLocationPubSubType : public eprosima::fastdds::dds::TopicDataType +{ +public: + + typedef ::safe_edge::pilot_server::ChargerLocation type; + + eProsima_user_DllExport ChargerLocationPubSubType(); + + eProsima_user_DllExport ~ChargerLocationPubSubType() override; + + eProsima_user_DllExport bool serialize( + const void* const data, + eprosima::fastdds::rtps::SerializedPayload_t& payload, + eprosima::fastdds::dds::DataRepresentationId_t data_representation) override; + + eProsima_user_DllExport bool deserialize( + eprosima::fastdds::rtps::SerializedPayload_t& payload, + void* data) override; + + eProsima_user_DllExport uint32_t calculate_serialized_size( + const void* const data, + eprosima::fastdds::dds::DataRepresentationId_t data_representation) override; + + eProsima_user_DllExport bool compute_key( + eprosima::fastdds::rtps::SerializedPayload_t& payload, + eprosima::fastdds::rtps::InstanceHandle_t& ihandle, + bool force_md5 = false) override; + + eProsima_user_DllExport bool compute_key( + const void* const data, + eprosima::fastdds::rtps::InstanceHandle_t& ihandle, + bool force_md5 = false) override; + + eProsima_user_DllExport void* create_data() override; + + eProsima_user_DllExport void delete_data( + void* data) override; + + //Register TypeObject representation in Fast DDS TypeObjectRegistry + eProsima_user_DllExport void register_type_object_representation() override; + +#ifdef TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED + eProsima_user_DllExport inline bool is_bounded() const override + { + return false; + } + +#endif // TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED + +#ifdef TOPIC_DATA_TYPE_API_HAS_IS_PLAIN + + eProsima_user_DllExport inline bool is_plain( + eprosima::fastdds::dds::DataRepresentationId_t data_representation) const override + { + static_cast(data_representation); + return false; + } + +#endif // TOPIC_DATA_TYPE_API_HAS_IS_PLAIN + +#ifdef TOPIC_DATA_TYPE_API_HAS_CONSTRUCT_SAMPLE + eProsima_user_DllExport inline bool construct_sample( + void* memory) const override + { + static_cast(memory); + return false; + } + +#endif // TOPIC_DATA_TYPE_API_HAS_CONSTRUCT_SAMPLE + +private: + +}; + +typedef std::vector ChargerLocationSeq; + +/*! + * @brief This class represents the TopicDataType of the type ChargerType defined by the user in the IDL file. + * @ingroup pilot_server + */ +class ChargerTypePubSubType : public eprosima::fastdds::dds::TopicDataType +{ +public: + + typedef ::safe_edge::pilot_server::ChargerType type; + + eProsima_user_DllExport ChargerTypePubSubType(); + + eProsima_user_DllExport ~ChargerTypePubSubType() override; + + eProsima_user_DllExport bool serialize( + const void* const data, + eprosima::fastdds::rtps::SerializedPayload_t& payload, + eprosima::fastdds::dds::DataRepresentationId_t data_representation) override; + + eProsima_user_DllExport bool deserialize( + eprosima::fastdds::rtps::SerializedPayload_t& payload, + void* data) override; + + eProsima_user_DllExport uint32_t calculate_serialized_size( + const void* const data, + eprosima::fastdds::dds::DataRepresentationId_t data_representation) override; + + eProsima_user_DllExport bool compute_key( + eprosima::fastdds::rtps::SerializedPayload_t& payload, + eprosima::fastdds::rtps::InstanceHandle_t& ihandle, + bool force_md5 = false) override; + + eProsima_user_DllExport bool compute_key( + const void* const data, + eprosima::fastdds::rtps::InstanceHandle_t& ihandle, + bool force_md5 = false) override; + + eProsima_user_DllExport void* create_data() override; + + eProsima_user_DllExport void delete_data( + void* data) override; + + //Register TypeObject representation in Fast DDS TypeObjectRegistry + eProsima_user_DllExport void register_type_object_representation() override; + +#ifdef TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED + eProsima_user_DllExport inline bool is_bounded() const override + { + return false; + } + +#endif // TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED + +#ifdef TOPIC_DATA_TYPE_API_HAS_IS_PLAIN + + eProsima_user_DllExport inline bool is_plain( + eprosima::fastdds::dds::DataRepresentationId_t data_representation) const override + { + static_cast(data_representation); + return false; + } + +#endif // TOPIC_DATA_TYPE_API_HAS_IS_PLAIN + +#ifdef TOPIC_DATA_TYPE_API_HAS_CONSTRUCT_SAMPLE + eProsima_user_DllExport inline bool construct_sample( + void* memory) const override + { + static_cast(memory); + return false; + } + +#endif // TOPIC_DATA_TYPE_API_HAS_CONSTRUCT_SAMPLE + +private: + +}; + +typedef std::vector ChargerTypeSeq; + +/*! + * @brief This class represents the TopicDataType of the type ChargingSession defined by the user in the IDL file. + * @ingroup pilot_server + */ +class ChargingSessionPubSubType : public eprosima::fastdds::dds::TopicDataType +{ +public: + + typedef ::safe_edge::pilot_server::ChargingSession type; + + eProsima_user_DllExport ChargingSessionPubSubType(); + + eProsima_user_DllExport ~ChargingSessionPubSubType() override; + + eProsima_user_DllExport bool serialize( + const void* const data, + eprosima::fastdds::rtps::SerializedPayload_t& payload, + eprosima::fastdds::dds::DataRepresentationId_t data_representation) override; + + eProsima_user_DllExport bool deserialize( + eprosima::fastdds::rtps::SerializedPayload_t& payload, + void* data) override; + + eProsima_user_DllExport uint32_t calculate_serialized_size( + const void* const data, + eprosima::fastdds::dds::DataRepresentationId_t data_representation) override; + + eProsima_user_DllExport bool compute_key( + eprosima::fastdds::rtps::SerializedPayload_t& payload, + eprosima::fastdds::rtps::InstanceHandle_t& ihandle, + bool force_md5 = false) override; + + eProsima_user_DllExport bool compute_key( + const void* const data, + eprosima::fastdds::rtps::InstanceHandle_t& ihandle, + bool force_md5 = false) override; + + eProsima_user_DllExport void* create_data() override; + + eProsima_user_DllExport void delete_data( + void* data) override; + + //Register TypeObject representation in Fast DDS TypeObjectRegistry + eProsima_user_DllExport void register_type_object_representation() override; + +#ifdef TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED + eProsima_user_DllExport inline bool is_bounded() const override + { + return false; + } + +#endif // TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED + +#ifdef TOPIC_DATA_TYPE_API_HAS_IS_PLAIN + + eProsima_user_DllExport inline bool is_plain( + eprosima::fastdds::dds::DataRepresentationId_t data_representation) const override + { + static_cast(data_representation); + return false; + } + +#endif // TOPIC_DATA_TYPE_API_HAS_IS_PLAIN + +#ifdef TOPIC_DATA_TYPE_API_HAS_CONSTRUCT_SAMPLE + eProsima_user_DllExport inline bool construct_sample( + void* memory) const override + { + static_cast(memory); + return false; + } + +#endif // TOPIC_DATA_TYPE_API_HAS_CONSTRUCT_SAMPLE + +private: + +}; + +typedef std::vector ChargingSessionSeq; + +/*! + * @brief This class represents the TopicDataType of the type TransitHealth defined by the user in the IDL file. + * @ingroup pilot_server + */ +class TransitHealthPubSubType : public eprosima::fastdds::dds::TopicDataType +{ +public: + + typedef ::safe_edge::pilot_server::TransitHealth type; + + eProsima_user_DllExport TransitHealthPubSubType(); + + eProsima_user_DllExport ~TransitHealthPubSubType() override; + + eProsima_user_DllExport bool serialize( + const void* const data, + eprosima::fastdds::rtps::SerializedPayload_t& payload, + eprosima::fastdds::dds::DataRepresentationId_t data_representation) override; + + eProsima_user_DllExport bool deserialize( + eprosima::fastdds::rtps::SerializedPayload_t& payload, + void* data) override; + + eProsima_user_DllExport uint32_t calculate_serialized_size( + const void* const data, + eprosima::fastdds::dds::DataRepresentationId_t data_representation) override; + + eProsima_user_DllExport bool compute_key( + eprosima::fastdds::rtps::SerializedPayload_t& payload, + eprosima::fastdds::rtps::InstanceHandle_t& ihandle, + bool force_md5 = false) override; + + eProsima_user_DllExport bool compute_key( + const void* const data, + eprosima::fastdds::rtps::InstanceHandle_t& ihandle, + bool force_md5 = false) override; + + eProsima_user_DllExport void* create_data() override; + + eProsima_user_DllExport void delete_data( + void* data) override; + + //Register TypeObject representation in Fast DDS TypeObjectRegistry + eProsima_user_DllExport void register_type_object_representation() override; + +#ifdef TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED + eProsima_user_DllExport inline bool is_bounded() const override + { + return false; + } + +#endif // TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED + +#ifdef TOPIC_DATA_TYPE_API_HAS_IS_PLAIN + + eProsima_user_DllExport inline bool is_plain( + eprosima::fastdds::dds::DataRepresentationId_t data_representation) const override + { + static_cast(data_representation); + return false; + } + +#endif // TOPIC_DATA_TYPE_API_HAS_IS_PLAIN + +#ifdef TOPIC_DATA_TYPE_API_HAS_CONSTRUCT_SAMPLE + eProsima_user_DllExport inline bool construct_sample( + void* memory) const override + { + static_cast(memory); + return false; + } + +#endif // TOPIC_DATA_TYPE_API_HAS_CONSTRUCT_SAMPLE + +private: + +}; + + +/*! + * @brief This class represents the TopicDataType of the type RouteMetric defined by the user in the IDL file. + * @ingroup pilot_server + */ +class RouteMetricPubSubType : public eprosima::fastdds::dds::TopicDataType +{ +public: + + typedef ::safe_edge::pilot_server::RouteMetric type; + + eProsima_user_DllExport RouteMetricPubSubType(); + + eProsima_user_DllExport ~RouteMetricPubSubType() override; + + eProsima_user_DllExport bool serialize( + const void* const data, + eprosima::fastdds::rtps::SerializedPayload_t& payload, + eprosima::fastdds::dds::DataRepresentationId_t data_representation) override; + + eProsima_user_DllExport bool deserialize( + eprosima::fastdds::rtps::SerializedPayload_t& payload, + void* data) override; + + eProsima_user_DllExport uint32_t calculate_serialized_size( + const void* const data, + eprosima::fastdds::dds::DataRepresentationId_t data_representation) override; + + eProsima_user_DllExport bool compute_key( + eprosima::fastdds::rtps::SerializedPayload_t& payload, + eprosima::fastdds::rtps::InstanceHandle_t& ihandle, + bool force_md5 = false) override; + + eProsima_user_DllExport bool compute_key( + const void* const data, + eprosima::fastdds::rtps::InstanceHandle_t& ihandle, + bool force_md5 = false) override; + + eProsima_user_DllExport void* create_data() override; + + eProsima_user_DllExport void delete_data( + void* data) override; + + //Register TypeObject representation in Fast DDS TypeObjectRegistry + eProsima_user_DllExport void register_type_object_representation() override; + +#ifdef TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED + eProsima_user_DllExport inline bool is_bounded() const override + { + return false; + } + +#endif // TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED + +#ifdef TOPIC_DATA_TYPE_API_HAS_IS_PLAIN + + eProsima_user_DllExport inline bool is_plain( + eprosima::fastdds::dds::DataRepresentationId_t data_representation) const override + { + static_cast(data_representation); + return false; + } + +#endif // TOPIC_DATA_TYPE_API_HAS_IS_PLAIN + +#ifdef TOPIC_DATA_TYPE_API_HAS_CONSTRUCT_SAMPLE + eProsima_user_DllExport inline bool construct_sample( + void* memory) const override + { + static_cast(memory); + return false; + } + +#endif // TOPIC_DATA_TYPE_API_HAS_CONSTRUCT_SAMPLE + +private: + +}; + +typedef std::vector RouteMetricSeq; + +/*! + * @brief This class represents the TopicDataType of the type TransitMetrics defined by the user in the IDL file. + * @ingroup pilot_server + */ +class TransitMetricsPubSubType : public eprosima::fastdds::dds::TopicDataType +{ +public: + + typedef ::safe_edge::pilot_server::TransitMetrics type; + + eProsima_user_DllExport TransitMetricsPubSubType(); + + eProsima_user_DllExport ~TransitMetricsPubSubType() override; + + eProsima_user_DllExport bool serialize( + const void* const data, + eprosima::fastdds::rtps::SerializedPayload_t& payload, + eprosima::fastdds::dds::DataRepresentationId_t data_representation) override; + + eProsima_user_DllExport bool deserialize( + eprosima::fastdds::rtps::SerializedPayload_t& payload, + void* data) override; + + eProsima_user_DllExport uint32_t calculate_serialized_size( + const void* const data, + eprosima::fastdds::dds::DataRepresentationId_t data_representation) override; + + eProsima_user_DllExport bool compute_key( + eprosima::fastdds::rtps::SerializedPayload_t& payload, + eprosima::fastdds::rtps::InstanceHandle_t& ihandle, + bool force_md5 = false) override; + + eProsima_user_DllExport bool compute_key( + const void* const data, + eprosima::fastdds::rtps::InstanceHandle_t& ihandle, + bool force_md5 = false) override; + + eProsima_user_DllExport void* create_data() override; + + eProsima_user_DllExport void delete_data( + void* data) override; + + //Register TypeObject representation in Fast DDS TypeObjectRegistry + eProsima_user_DllExport void register_type_object_representation() override; + +#ifdef TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED + eProsima_user_DllExport inline bool is_bounded() const override + { + return false; + } + +#endif // TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED + +#ifdef TOPIC_DATA_TYPE_API_HAS_IS_PLAIN + + eProsima_user_DllExport inline bool is_plain( + eprosima::fastdds::dds::DataRepresentationId_t data_representation) const override + { + static_cast(data_representation); + return false; + } + +#endif // TOPIC_DATA_TYPE_API_HAS_IS_PLAIN + +#ifdef TOPIC_DATA_TYPE_API_HAS_CONSTRUCT_SAMPLE + eProsima_user_DllExport inline bool construct_sample( + void* memory) const override + { + static_cast(memory); + return false; + } + +#endif // TOPIC_DATA_TYPE_API_HAS_CONSTRUCT_SAMPLE + +private: + +}; + + +/*! + * @brief This class represents the TopicDataType of the type ServerQuery defined by the user in the IDL file. + * @ingroup pilot_server + */ +class ServerQueryPubSubType : public eprosima::fastdds::dds::TopicDataType +{ +public: + + typedef ::safe_edge::pilot_server::ServerQuery type; + + eProsima_user_DllExport ServerQueryPubSubType(); + + eProsima_user_DllExport ~ServerQueryPubSubType() override; + + eProsima_user_DllExport bool serialize( + const void* const data, + eprosima::fastdds::rtps::SerializedPayload_t& payload, + eprosima::fastdds::dds::DataRepresentationId_t data_representation) override; + + eProsima_user_DllExport bool deserialize( + eprosima::fastdds::rtps::SerializedPayload_t& payload, + void* data) override; + + eProsima_user_DllExport uint32_t calculate_serialized_size( + const void* const data, + eprosima::fastdds::dds::DataRepresentationId_t data_representation) override; + + eProsima_user_DllExport bool compute_key( + eprosima::fastdds::rtps::SerializedPayload_t& payload, + eprosima::fastdds::rtps::InstanceHandle_t& ihandle, + bool force_md5 = false) override; + + eProsima_user_DllExport bool compute_key( + const void* const data, + eprosima::fastdds::rtps::InstanceHandle_t& ihandle, + bool force_md5 = false) override; + + eProsima_user_DllExport void* create_data() override; + + eProsima_user_DllExport void delete_data( + void* data) override; + + //Register TypeObject representation in Fast DDS TypeObjectRegistry + eProsima_user_DllExport void register_type_object_representation() override; + +#ifdef TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED + eProsima_user_DllExport inline bool is_bounded() const override + { + return false; + } + +#endif // TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED + +#ifdef TOPIC_DATA_TYPE_API_HAS_IS_PLAIN + + eProsima_user_DllExport inline bool is_plain( + eprosima::fastdds::dds::DataRepresentationId_t data_representation) const override + { + static_cast(data_representation); + return false; + } + +#endif // TOPIC_DATA_TYPE_API_HAS_IS_PLAIN + +#ifdef TOPIC_DATA_TYPE_API_HAS_CONSTRUCT_SAMPLE + eProsima_user_DllExport inline bool construct_sample( + void* memory) const override + { + static_cast(memory); + return false; + } + +#endif // TOPIC_DATA_TYPE_API_HAS_CONSTRUCT_SAMPLE + +private: + +}; + +} // namespace pilot_server +} // namespace safe_edge + +#endif // FAST_DDS_GENERATED__SAFE_EDGE_PILOT_SERVER_PILOT_SERVER_PUBSUBTYPES_HPP + diff --git a/fast_dds/idl/pilot_serverTypeObjectSupport.cxx b/fast_dds/idl/pilot_serverTypeObjectSupport.cxx new file mode 100644 index 0000000..3ac9ad9 --- /dev/null +++ b/fast_dds/idl/pilot_serverTypeObjectSupport.cxx @@ -0,0 +1,1299 @@ +// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/*! + * @file pilot_serverTypeObjectSupport.cxx + * Source file containing the implementation to register the TypeObject representation of the described types in the IDL file + * + * This file was generated by the tool fastddsgen (version: 4.3.0). + */ + +#include "pilot_serverTypeObjectSupport.hpp" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pilot_server.hpp" + +#include "common.hpp" + +using namespace eprosima::fastdds::dds::xtypes; + +namespace safe_edge { +namespace pilot_server { +// TypeIdentifier is returned by reference: dependent structures/unions are registered in this same method +void register_ChargerLocation_type_identifier( + TypeIdentifierPair& type_ids_ChargerLocation) +{ + + ReturnCode_t return_code_ChargerLocation {eprosima::fastdds::dds::RETCODE_OK}; + return_code_ChargerLocation = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "safe_edge::pilot_server::ChargerLocation", type_ids_ChargerLocation); + if (eprosima::fastdds::dds::RETCODE_OK != return_code_ChargerLocation) + { + StructTypeFlag struct_flags_ChargerLocation = TypeObjectUtils::build_struct_type_flag(eprosima::fastdds::dds::xtypes::ExtensibilityKind::APPENDABLE, + false, false); + QualifiedTypeName type_name_ChargerLocation = "safe_edge::pilot_server::ChargerLocation"; + eprosima::fastcdr::optional type_ann_builtin_ChargerLocation; + eprosima::fastcdr::optional ann_custom_ChargerLocation; + CompleteTypeDetail detail_ChargerLocation = TypeObjectUtils::build_complete_type_detail(type_ann_builtin_ChargerLocation, ann_custom_ChargerLocation, type_name_ChargerLocation.to_string()); + CompleteStructHeader header_ChargerLocation; + header_ChargerLocation = TypeObjectUtils::build_complete_struct_header(TypeIdentifier(), detail_ChargerLocation); + CompleteStructMemberSeq member_seq_ChargerLocation; + { + TypeIdentifierPair type_ids_id; + ReturnCode_t return_code_id {eprosima::fastdds::dds::RETCODE_OK}; + return_code_id = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "_int32_t", type_ids_id); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_id) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "id Structure member TypeIdentifier unknown to TypeObjectRegistry."); + return; + } + StructMemberFlag member_flags_id = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_id = 0x00000000; + bool common_id_ec {false}; + CommonStructMember common_id {TypeObjectUtils::build_common_struct_member(member_id_id, member_flags_id, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_id, common_id_ec))}; + if (!common_id_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure id member TypeIdentifier inconsistent."); + return; + } + MemberName name_id = "id"; + eprosima::fastcdr::optional member_ann_builtin_id; + ann_custom_ChargerLocation.reset(); + CompleteMemberDetail detail_id = TypeObjectUtils::build_complete_member_detail(name_id, member_ann_builtin_id, ann_custom_ChargerLocation); + CompleteStructMember member_id = TypeObjectUtils::build_complete_struct_member(common_id, detail_id); + TypeObjectUtils::add_complete_struct_member(member_seq_ChargerLocation, member_id); + } + { + TypeIdentifierPair type_ids_name; + ReturnCode_t return_code_name {eprosima::fastdds::dds::RETCODE_OK}; + return_code_name = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "anonymous_string_unbounded", type_ids_name); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_name) + { + { + SBound bound = 0; + StringSTypeDefn string_sdefn = TypeObjectUtils::build_string_s_type_defn(bound); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_s_string_type_identifier(string_sdefn, + "anonymous_string_unbounded", type_ids_name)) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "anonymous_string_unbounded already registered in TypeObjectRegistry for a different type."); + } + } + } + StructMemberFlag member_flags_name = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_name = 0x00000001; + bool common_name_ec {false}; + CommonStructMember common_name {TypeObjectUtils::build_common_struct_member(member_id_name, member_flags_name, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_name, common_name_ec))}; + if (!common_name_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure name member TypeIdentifier inconsistent."); + return; + } + MemberName name_name = "name"; + eprosima::fastcdr::optional member_ann_builtin_name; + ann_custom_ChargerLocation.reset(); + CompleteMemberDetail detail_name = TypeObjectUtils::build_complete_member_detail(name_name, member_ann_builtin_name, ann_custom_ChargerLocation); + CompleteStructMember member_name = TypeObjectUtils::build_complete_struct_member(common_name, detail_name); + TypeObjectUtils::add_complete_struct_member(member_seq_ChargerLocation, member_name); + } + { + TypeIdentifierPair type_ids_position; + ReturnCode_t return_code_position {eprosima::fastdds::dds::RETCODE_OK}; + return_code_position = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "safe_edge::common::GeoPoint", type_ids_position); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_position) + { + ::safe_edge::common::register_GeoPoint_type_identifier(type_ids_position); + } + StructMemberFlag member_flags_position = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_position = 0x00000002; + bool common_position_ec {false}; + CommonStructMember common_position {TypeObjectUtils::build_common_struct_member(member_id_position, member_flags_position, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_position, common_position_ec))}; + if (!common_position_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure position member TypeIdentifier inconsistent."); + return; + } + MemberName name_position = "position"; + eprosima::fastcdr::optional member_ann_builtin_position; + ann_custom_ChargerLocation.reset(); + CompleteMemberDetail detail_position = TypeObjectUtils::build_complete_member_detail(name_position, member_ann_builtin_position, ann_custom_ChargerLocation); + CompleteStructMember member_position = TypeObjectUtils::build_complete_struct_member(common_position, detail_position); + TypeObjectUtils::add_complete_struct_member(member_seq_ChargerLocation, member_position); + } + CompleteStructType struct_type_ChargerLocation = TypeObjectUtils::build_complete_struct_type(struct_flags_ChargerLocation, header_ChargerLocation, member_seq_ChargerLocation); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_struct_type_object(struct_type_ChargerLocation, type_name_ChargerLocation.to_string(), type_ids_ChargerLocation)) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "safe_edge::pilot_server::ChargerLocation already registered in TypeObjectRegistry for a different type."); + } + } +}void register_ChargerLocationSeq_type_identifier( + TypeIdentifierPair& type_ids_ChargerLocationSeq) +{ + ReturnCode_t return_code_ChargerLocationSeq {eprosima::fastdds::dds::RETCODE_OK}; + return_code_ChargerLocationSeq = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "safe_edge::pilot_server::ChargerLocationSeq", type_ids_ChargerLocationSeq); + if (eprosima::fastdds::dds::RETCODE_OK != return_code_ChargerLocationSeq) + { + AliasTypeFlag alias_flags_ChargerLocationSeq = 0; + QualifiedTypeName type_name_ChargerLocationSeq = "safe_edge::pilot_server::ChargerLocationSeq"; + eprosima::fastcdr::optional type_ann_builtin_ChargerLocationSeq; + eprosima::fastcdr::optional ann_custom_ChargerLocationSeq; + CompleteTypeDetail detail_ChargerLocationSeq = TypeObjectUtils::build_complete_type_detail(type_ann_builtin_ChargerLocationSeq, ann_custom_ChargerLocationSeq, type_name_ChargerLocationSeq.to_string()); + CompleteAliasHeader header_ChargerLocationSeq = TypeObjectUtils::build_complete_alias_header(detail_ChargerLocationSeq); + AliasMemberFlag related_flags_ChargerLocationSeq = 0; + return_code_ChargerLocationSeq = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "anonymous_sequence_safe_edge_pilot_server_ChargerLocation_200", type_ids_ChargerLocationSeq); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_ChargerLocationSeq) + { + return_code_ChargerLocationSeq = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "safe_edge::pilot_server::ChargerLocation", type_ids_ChargerLocationSeq); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_ChargerLocationSeq) + { + ::safe_edge::pilot_server::register_ChargerLocation_type_identifier(type_ids_ChargerLocationSeq); + } + bool element_identifier_anonymous_sequence_safe_edge_pilot_server_ChargerLocation_200_ec {false}; + TypeIdentifier* element_identifier_anonymous_sequence_safe_edge_pilot_server_ChargerLocation_200 {new TypeIdentifier(TypeObjectUtils::retrieve_complete_type_identifier(type_ids_ChargerLocationSeq, element_identifier_anonymous_sequence_safe_edge_pilot_server_ChargerLocation_200_ec))}; + if (!element_identifier_anonymous_sequence_safe_edge_pilot_server_ChargerLocation_200_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Sequence element TypeIdentifier inconsistent."); + return; + } + EquivalenceKind equiv_kind_anonymous_sequence_safe_edge_pilot_server_ChargerLocation_200 = EK_COMPLETE; + if (TK_NONE == type_ids_ChargerLocationSeq.type_identifier2()._d()) + { + equiv_kind_anonymous_sequence_safe_edge_pilot_server_ChargerLocation_200 = EK_BOTH; + } + CollectionElementFlag element_flags_anonymous_sequence_safe_edge_pilot_server_ChargerLocation_200 = 0; + PlainCollectionHeader header_anonymous_sequence_safe_edge_pilot_server_ChargerLocation_200 = TypeObjectUtils::build_plain_collection_header(equiv_kind_anonymous_sequence_safe_edge_pilot_server_ChargerLocation_200, element_flags_anonymous_sequence_safe_edge_pilot_server_ChargerLocation_200); + { + SBound bound = static_cast(200); + PlainSequenceSElemDefn seq_sdefn = TypeObjectUtils::build_plain_sequence_s_elem_defn(header_anonymous_sequence_safe_edge_pilot_server_ChargerLocation_200, bound, + eprosima::fastcdr::external(element_identifier_anonymous_sequence_safe_edge_pilot_server_ChargerLocation_200)); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_s_sequence_type_identifier(seq_sdefn, "anonymous_sequence_safe_edge_pilot_server_ChargerLocation_200", type_ids_ChargerLocationSeq)) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "anonymous_sequence_safe_edge_pilot_server_ChargerLocation_200 already registered in TypeObjectRegistry for a different type."); + } + } + } + bool common_ChargerLocationSeq_ec {false}; + CommonAliasBody common_ChargerLocationSeq {TypeObjectUtils::build_common_alias_body(related_flags_ChargerLocationSeq, + TypeObjectUtils::retrieve_complete_type_identifier(type_ids_ChargerLocationSeq, common_ChargerLocationSeq_ec))}; + if (!common_ChargerLocationSeq_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "safe_edge::pilot_server::ChargerLocationSeq related TypeIdentifier inconsistent."); + return; + } + eprosima::fastcdr::optional member_ann_builtin_ChargerLocationSeq; + ann_custom_ChargerLocationSeq.reset(); + CompleteAliasBody body_ChargerLocationSeq = TypeObjectUtils::build_complete_alias_body(common_ChargerLocationSeq, + member_ann_builtin_ChargerLocationSeq, ann_custom_ChargerLocationSeq); + CompleteAliasType alias_type_ChargerLocationSeq = TypeObjectUtils::build_complete_alias_type(alias_flags_ChargerLocationSeq, + header_ChargerLocationSeq, body_ChargerLocationSeq); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_alias_type_object(alias_type_ChargerLocationSeq, + type_name_ChargerLocationSeq.to_string(), type_ids_ChargerLocationSeq)) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "safe_edge::pilot_server::ChargerLocationSeq already registered in TypeObjectRegistry for a different type."); + } + } +} + +// TypeIdentifier is returned by reference: dependent structures/unions are registered in this same method +void register_ChargerType_type_identifier( + TypeIdentifierPair& type_ids_ChargerType) +{ + + ReturnCode_t return_code_ChargerType {eprosima::fastdds::dds::RETCODE_OK}; + return_code_ChargerType = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "safe_edge::pilot_server::ChargerType", type_ids_ChargerType); + if (eprosima::fastdds::dds::RETCODE_OK != return_code_ChargerType) + { + StructTypeFlag struct_flags_ChargerType = TypeObjectUtils::build_struct_type_flag(eprosima::fastdds::dds::xtypes::ExtensibilityKind::APPENDABLE, + false, false); + QualifiedTypeName type_name_ChargerType = "safe_edge::pilot_server::ChargerType"; + eprosima::fastcdr::optional type_ann_builtin_ChargerType; + eprosima::fastcdr::optional ann_custom_ChargerType; + CompleteTypeDetail detail_ChargerType = TypeObjectUtils::build_complete_type_detail(type_ann_builtin_ChargerType, ann_custom_ChargerType, type_name_ChargerType.to_string()); + CompleteStructHeader header_ChargerType; + header_ChargerType = TypeObjectUtils::build_complete_struct_header(TypeIdentifier(), detail_ChargerType); + CompleteStructMemberSeq member_seq_ChargerType; + { + TypeIdentifierPair type_ids_id; + ReturnCode_t return_code_id {eprosima::fastdds::dds::RETCODE_OK}; + return_code_id = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "_int32_t", type_ids_id); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_id) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "id Structure member TypeIdentifier unknown to TypeObjectRegistry."); + return; + } + StructMemberFlag member_flags_id = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_id = 0x00000000; + bool common_id_ec {false}; + CommonStructMember common_id {TypeObjectUtils::build_common_struct_member(member_id_id, member_flags_id, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_id, common_id_ec))}; + if (!common_id_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure id member TypeIdentifier inconsistent."); + return; + } + MemberName name_id = "id"; + eprosima::fastcdr::optional member_ann_builtin_id; + ann_custom_ChargerType.reset(); + CompleteMemberDetail detail_id = TypeObjectUtils::build_complete_member_detail(name_id, member_ann_builtin_id, ann_custom_ChargerType); + CompleteStructMember member_id = TypeObjectUtils::build_complete_struct_member(common_id, detail_id); + TypeObjectUtils::add_complete_struct_member(member_seq_ChargerType, member_id); + } + { + TypeIdentifierPair type_ids_charger_type; + ReturnCode_t return_code_charger_type {eprosima::fastdds::dds::RETCODE_OK}; + return_code_charger_type = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "anonymous_string_unbounded", type_ids_charger_type); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_charger_type) + { + { + SBound bound = 0; + StringSTypeDefn string_sdefn = TypeObjectUtils::build_string_s_type_defn(bound); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_s_string_type_identifier(string_sdefn, + "anonymous_string_unbounded", type_ids_charger_type)) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "anonymous_string_unbounded already registered in TypeObjectRegistry for a different type."); + } + } + } + StructMemberFlag member_flags_charger_type = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_charger_type = 0x00000001; + bool common_charger_type_ec {false}; + CommonStructMember common_charger_type {TypeObjectUtils::build_common_struct_member(member_id_charger_type, member_flags_charger_type, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_charger_type, common_charger_type_ec))}; + if (!common_charger_type_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure charger_type member TypeIdentifier inconsistent."); + return; + } + MemberName name_charger_type = "charger_type"; + eprosima::fastcdr::optional member_ann_builtin_charger_type; + ann_custom_ChargerType.reset(); + CompleteMemberDetail detail_charger_type = TypeObjectUtils::build_complete_member_detail(name_charger_type, member_ann_builtin_charger_type, ann_custom_ChargerType); + CompleteStructMember member_charger_type = TypeObjectUtils::build_complete_struct_member(common_charger_type, detail_charger_type); + TypeObjectUtils::add_complete_struct_member(member_seq_ChargerType, member_charger_type); + } + CompleteStructType struct_type_ChargerType = TypeObjectUtils::build_complete_struct_type(struct_flags_ChargerType, header_ChargerType, member_seq_ChargerType); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_struct_type_object(struct_type_ChargerType, type_name_ChargerType.to_string(), type_ids_ChargerType)) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "safe_edge::pilot_server::ChargerType already registered in TypeObjectRegistry for a different type."); + } + } +}void register_ChargerTypeSeq_type_identifier( + TypeIdentifierPair& type_ids_ChargerTypeSeq) +{ + ReturnCode_t return_code_ChargerTypeSeq {eprosima::fastdds::dds::RETCODE_OK}; + return_code_ChargerTypeSeq = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "safe_edge::pilot_server::ChargerTypeSeq", type_ids_ChargerTypeSeq); + if (eprosima::fastdds::dds::RETCODE_OK != return_code_ChargerTypeSeq) + { + AliasTypeFlag alias_flags_ChargerTypeSeq = 0; + QualifiedTypeName type_name_ChargerTypeSeq = "safe_edge::pilot_server::ChargerTypeSeq"; + eprosima::fastcdr::optional type_ann_builtin_ChargerTypeSeq; + eprosima::fastcdr::optional ann_custom_ChargerTypeSeq; + CompleteTypeDetail detail_ChargerTypeSeq = TypeObjectUtils::build_complete_type_detail(type_ann_builtin_ChargerTypeSeq, ann_custom_ChargerTypeSeq, type_name_ChargerTypeSeq.to_string()); + CompleteAliasHeader header_ChargerTypeSeq = TypeObjectUtils::build_complete_alias_header(detail_ChargerTypeSeq); + AliasMemberFlag related_flags_ChargerTypeSeq = 0; + return_code_ChargerTypeSeq = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "anonymous_sequence_safe_edge_pilot_server_ChargerType_64", type_ids_ChargerTypeSeq); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_ChargerTypeSeq) + { + return_code_ChargerTypeSeq = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "safe_edge::pilot_server::ChargerType", type_ids_ChargerTypeSeq); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_ChargerTypeSeq) + { + ::safe_edge::pilot_server::register_ChargerType_type_identifier(type_ids_ChargerTypeSeq); + } + bool element_identifier_anonymous_sequence_safe_edge_pilot_server_ChargerType_64_ec {false}; + TypeIdentifier* element_identifier_anonymous_sequence_safe_edge_pilot_server_ChargerType_64 {new TypeIdentifier(TypeObjectUtils::retrieve_complete_type_identifier(type_ids_ChargerTypeSeq, element_identifier_anonymous_sequence_safe_edge_pilot_server_ChargerType_64_ec))}; + if (!element_identifier_anonymous_sequence_safe_edge_pilot_server_ChargerType_64_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Sequence element TypeIdentifier inconsistent."); + return; + } + EquivalenceKind equiv_kind_anonymous_sequence_safe_edge_pilot_server_ChargerType_64 = EK_COMPLETE; + if (TK_NONE == type_ids_ChargerTypeSeq.type_identifier2()._d()) + { + equiv_kind_anonymous_sequence_safe_edge_pilot_server_ChargerType_64 = EK_BOTH; + } + CollectionElementFlag element_flags_anonymous_sequence_safe_edge_pilot_server_ChargerType_64 = 0; + PlainCollectionHeader header_anonymous_sequence_safe_edge_pilot_server_ChargerType_64 = TypeObjectUtils::build_plain_collection_header(equiv_kind_anonymous_sequence_safe_edge_pilot_server_ChargerType_64, element_flags_anonymous_sequence_safe_edge_pilot_server_ChargerType_64); + { + SBound bound = static_cast(64); + PlainSequenceSElemDefn seq_sdefn = TypeObjectUtils::build_plain_sequence_s_elem_defn(header_anonymous_sequence_safe_edge_pilot_server_ChargerType_64, bound, + eprosima::fastcdr::external(element_identifier_anonymous_sequence_safe_edge_pilot_server_ChargerType_64)); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_s_sequence_type_identifier(seq_sdefn, "anonymous_sequence_safe_edge_pilot_server_ChargerType_64", type_ids_ChargerTypeSeq)) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "anonymous_sequence_safe_edge_pilot_server_ChargerType_64 already registered in TypeObjectRegistry for a different type."); + } + } + } + bool common_ChargerTypeSeq_ec {false}; + CommonAliasBody common_ChargerTypeSeq {TypeObjectUtils::build_common_alias_body(related_flags_ChargerTypeSeq, + TypeObjectUtils::retrieve_complete_type_identifier(type_ids_ChargerTypeSeq, common_ChargerTypeSeq_ec))}; + if (!common_ChargerTypeSeq_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "safe_edge::pilot_server::ChargerTypeSeq related TypeIdentifier inconsistent."); + return; + } + eprosima::fastcdr::optional member_ann_builtin_ChargerTypeSeq; + ann_custom_ChargerTypeSeq.reset(); + CompleteAliasBody body_ChargerTypeSeq = TypeObjectUtils::build_complete_alias_body(common_ChargerTypeSeq, + member_ann_builtin_ChargerTypeSeq, ann_custom_ChargerTypeSeq); + CompleteAliasType alias_type_ChargerTypeSeq = TypeObjectUtils::build_complete_alias_type(alias_flags_ChargerTypeSeq, + header_ChargerTypeSeq, body_ChargerTypeSeq); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_alias_type_object(alias_type_ChargerTypeSeq, + type_name_ChargerTypeSeq.to_string(), type_ids_ChargerTypeSeq)) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "safe_edge::pilot_server::ChargerTypeSeq already registered in TypeObjectRegistry for a different type."); + } + } +} + +// TypeIdentifier is returned by reference: dependent structures/unions are registered in this same method +void register_ChargingSession_type_identifier( + TypeIdentifierPair& type_ids_ChargingSession) +{ + + ReturnCode_t return_code_ChargingSession {eprosima::fastdds::dds::RETCODE_OK}; + return_code_ChargingSession = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "safe_edge::pilot_server::ChargingSession", type_ids_ChargingSession); + if (eprosima::fastdds::dds::RETCODE_OK != return_code_ChargingSession) + { + StructTypeFlag struct_flags_ChargingSession = TypeObjectUtils::build_struct_type_flag(eprosima::fastdds::dds::xtypes::ExtensibilityKind::APPENDABLE, + false, false); + QualifiedTypeName type_name_ChargingSession = "safe_edge::pilot_server::ChargingSession"; + eprosima::fastcdr::optional type_ann_builtin_ChargingSession; + eprosima::fastcdr::optional ann_custom_ChargingSession; + CompleteTypeDetail detail_ChargingSession = TypeObjectUtils::build_complete_type_detail(type_ann_builtin_ChargingSession, ann_custom_ChargingSession, type_name_ChargingSession.to_string()); + CompleteStructHeader header_ChargingSession; + header_ChargingSession = TypeObjectUtils::build_complete_struct_header(TypeIdentifier(), detail_ChargingSession); + CompleteStructMemberSeq member_seq_ChargingSession; + { + TypeIdentifierPair type_ids_id; + ReturnCode_t return_code_id {eprosima::fastdds::dds::RETCODE_OK}; + return_code_id = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "_int32_t", type_ids_id); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_id) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "id Structure member TypeIdentifier unknown to TypeObjectRegistry."); + return; + } + StructMemberFlag member_flags_id = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_id = 0x00000000; + bool common_id_ec {false}; + CommonStructMember common_id {TypeObjectUtils::build_common_struct_member(member_id_id, member_flags_id, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_id, common_id_ec))}; + if (!common_id_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure id member TypeIdentifier inconsistent."); + return; + } + MemberName name_id = "id"; + eprosima::fastcdr::optional member_ann_builtin_id; + ann_custom_ChargingSession.reset(); + CompleteMemberDetail detail_id = TypeObjectUtils::build_complete_member_detail(name_id, member_ann_builtin_id, ann_custom_ChargingSession); + CompleteStructMember member_id = TypeObjectUtils::build_complete_struct_member(common_id, detail_id); + TypeObjectUtils::add_complete_struct_member(member_seq_ChargingSession, member_id); + } + { + TypeIdentifierPair type_ids_station_id; + ReturnCode_t return_code_station_id {eprosima::fastdds::dds::RETCODE_OK}; + return_code_station_id = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "_int32_t", type_ids_station_id); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_station_id) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "station_id Structure member TypeIdentifier unknown to TypeObjectRegistry."); + return; + } + StructMemberFlag member_flags_station_id = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_station_id = 0x00000001; + bool common_station_id_ec {false}; + CommonStructMember common_station_id {TypeObjectUtils::build_common_struct_member(member_id_station_id, member_flags_station_id, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_station_id, common_station_id_ec))}; + if (!common_station_id_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure station_id member TypeIdentifier inconsistent."); + return; + } + MemberName name_station_id = "station_id"; + eprosima::fastcdr::optional member_ann_builtin_station_id; + ann_custom_ChargingSession.reset(); + CompleteMemberDetail detail_station_id = TypeObjectUtils::build_complete_member_detail(name_station_id, member_ann_builtin_station_id, ann_custom_ChargingSession); + CompleteStructMember member_station_id = TypeObjectUtils::build_complete_struct_member(common_station_id, detail_station_id); + TypeObjectUtils::add_complete_struct_member(member_seq_ChargingSession, member_station_id); + } + { + TypeIdentifierPair type_ids_charger_type_id; + ReturnCode_t return_code_charger_type_id {eprosima::fastdds::dds::RETCODE_OK}; + return_code_charger_type_id = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "anonymous_string_unbounded", type_ids_charger_type_id); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_charger_type_id) + { + { + SBound bound = 0; + StringSTypeDefn string_sdefn = TypeObjectUtils::build_string_s_type_defn(bound); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_s_string_type_identifier(string_sdefn, + "anonymous_string_unbounded", type_ids_charger_type_id)) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "anonymous_string_unbounded already registered in TypeObjectRegistry for a different type."); + } + } + } + StructMemberFlag member_flags_charger_type_id = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_charger_type_id = 0x00000002; + bool common_charger_type_id_ec {false}; + CommonStructMember common_charger_type_id {TypeObjectUtils::build_common_struct_member(member_id_charger_type_id, member_flags_charger_type_id, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_charger_type_id, common_charger_type_id_ec))}; + if (!common_charger_type_id_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure charger_type_id member TypeIdentifier inconsistent."); + return; + } + MemberName name_charger_type_id = "charger_type_id"; + eprosima::fastcdr::optional member_ann_builtin_charger_type_id; + ann_custom_ChargingSession.reset(); + CompleteMemberDetail detail_charger_type_id = TypeObjectUtils::build_complete_member_detail(name_charger_type_id, member_ann_builtin_charger_type_id, ann_custom_ChargingSession); + CompleteStructMember member_charger_type_id = TypeObjectUtils::build_complete_struct_member(common_charger_type_id, detail_charger_type_id); + TypeObjectUtils::add_complete_struct_member(member_seq_ChargingSession, member_charger_type_id); + } + { + TypeIdentifierPair type_ids_consume_wh; + ReturnCode_t return_code_consume_wh {eprosima::fastdds::dds::RETCODE_OK}; + return_code_consume_wh = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "_double", type_ids_consume_wh); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_consume_wh) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "consume_wh Structure member TypeIdentifier unknown to TypeObjectRegistry."); + return; + } + StructMemberFlag member_flags_consume_wh = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_consume_wh = 0x00000003; + bool common_consume_wh_ec {false}; + CommonStructMember common_consume_wh {TypeObjectUtils::build_common_struct_member(member_id_consume_wh, member_flags_consume_wh, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_consume_wh, common_consume_wh_ec))}; + if (!common_consume_wh_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure consume_wh member TypeIdentifier inconsistent."); + return; + } + MemberName name_consume_wh = "consume_wh"; + eprosima::fastcdr::optional member_ann_builtin_consume_wh; + ann_custom_ChargingSession.reset(); + CompleteMemberDetail detail_consume_wh = TypeObjectUtils::build_complete_member_detail(name_consume_wh, member_ann_builtin_consume_wh, ann_custom_ChargingSession); + CompleteStructMember member_consume_wh = TypeObjectUtils::build_complete_struct_member(common_consume_wh, detail_consume_wh); + TypeObjectUtils::add_complete_struct_member(member_seq_ChargingSession, member_consume_wh); + } + { + TypeIdentifierPair type_ids_duration_min; + ReturnCode_t return_code_duration_min {eprosima::fastdds::dds::RETCODE_OK}; + return_code_duration_min = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "_int32_t", type_ids_duration_min); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_duration_min) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "duration_min Structure member TypeIdentifier unknown to TypeObjectRegistry."); + return; + } + StructMemberFlag member_flags_duration_min = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_duration_min = 0x00000004; + bool common_duration_min_ec {false}; + CommonStructMember common_duration_min {TypeObjectUtils::build_common_struct_member(member_id_duration_min, member_flags_duration_min, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_duration_min, common_duration_min_ec))}; + if (!common_duration_min_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure duration_min member TypeIdentifier inconsistent."); + return; + } + MemberName name_duration_min = "duration_min"; + eprosima::fastcdr::optional member_ann_builtin_duration_min; + ann_custom_ChargingSession.reset(); + CompleteMemberDetail detail_duration_min = TypeObjectUtils::build_complete_member_detail(name_duration_min, member_ann_builtin_duration_min, ann_custom_ChargingSession); + CompleteStructMember member_duration_min = TypeObjectUtils::build_complete_struct_member(common_duration_min, detail_duration_min); + TypeObjectUtils::add_complete_struct_member(member_seq_ChargingSession, member_duration_min); + } + { + TypeIdentifierPair type_ids_date_iso8601; + ReturnCode_t return_code_date_iso8601 {eprosima::fastdds::dds::RETCODE_OK}; + return_code_date_iso8601 = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "anonymous_string_unbounded", type_ids_date_iso8601); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_date_iso8601) + { + { + SBound bound = 0; + StringSTypeDefn string_sdefn = TypeObjectUtils::build_string_s_type_defn(bound); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_s_string_type_identifier(string_sdefn, + "anonymous_string_unbounded", type_ids_date_iso8601)) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "anonymous_string_unbounded already registered in TypeObjectRegistry for a different type."); + } + } + } + StructMemberFlag member_flags_date_iso8601 = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_date_iso8601 = 0x00000005; + bool common_date_iso8601_ec {false}; + CommonStructMember common_date_iso8601 {TypeObjectUtils::build_common_struct_member(member_id_date_iso8601, member_flags_date_iso8601, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_date_iso8601, common_date_iso8601_ec))}; + if (!common_date_iso8601_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure date_iso8601 member TypeIdentifier inconsistent."); + return; + } + MemberName name_date_iso8601 = "date_iso8601"; + eprosima::fastcdr::optional member_ann_builtin_date_iso8601; + ann_custom_ChargingSession.reset(); + CompleteMemberDetail detail_date_iso8601 = TypeObjectUtils::build_complete_member_detail(name_date_iso8601, member_ann_builtin_date_iso8601, ann_custom_ChargingSession); + CompleteStructMember member_date_iso8601 = TypeObjectUtils::build_complete_struct_member(common_date_iso8601, detail_date_iso8601); + TypeObjectUtils::add_complete_struct_member(member_seq_ChargingSession, member_date_iso8601); + } + { + TypeIdentifierPair type_ids_ingested_at_iso8601; + ReturnCode_t return_code_ingested_at_iso8601 {eprosima::fastdds::dds::RETCODE_OK}; + return_code_ingested_at_iso8601 = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "anonymous_string_unbounded", type_ids_ingested_at_iso8601); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_ingested_at_iso8601) + { + { + SBound bound = 0; + StringSTypeDefn string_sdefn = TypeObjectUtils::build_string_s_type_defn(bound); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_s_string_type_identifier(string_sdefn, + "anonymous_string_unbounded", type_ids_ingested_at_iso8601)) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "anonymous_string_unbounded already registered in TypeObjectRegistry for a different type."); + } + } + } + StructMemberFlag member_flags_ingested_at_iso8601 = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_ingested_at_iso8601 = 0x00000006; + bool common_ingested_at_iso8601_ec {false}; + CommonStructMember common_ingested_at_iso8601 {TypeObjectUtils::build_common_struct_member(member_id_ingested_at_iso8601, member_flags_ingested_at_iso8601, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_ingested_at_iso8601, common_ingested_at_iso8601_ec))}; + if (!common_ingested_at_iso8601_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure ingested_at_iso8601 member TypeIdentifier inconsistent."); + return; + } + MemberName name_ingested_at_iso8601 = "ingested_at_iso8601"; + eprosima::fastcdr::optional member_ann_builtin_ingested_at_iso8601; + ann_custom_ChargingSession.reset(); + CompleteMemberDetail detail_ingested_at_iso8601 = TypeObjectUtils::build_complete_member_detail(name_ingested_at_iso8601, member_ann_builtin_ingested_at_iso8601, ann_custom_ChargingSession); + CompleteStructMember member_ingested_at_iso8601 = TypeObjectUtils::build_complete_struct_member(common_ingested_at_iso8601, detail_ingested_at_iso8601); + TypeObjectUtils::add_complete_struct_member(member_seq_ChargingSession, member_ingested_at_iso8601); + } + CompleteStructType struct_type_ChargingSession = TypeObjectUtils::build_complete_struct_type(struct_flags_ChargingSession, header_ChargingSession, member_seq_ChargingSession); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_struct_type_object(struct_type_ChargingSession, type_name_ChargingSession.to_string(), type_ids_ChargingSession)) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "safe_edge::pilot_server::ChargingSession already registered in TypeObjectRegistry for a different type."); + } + } +}void register_ChargingSessionSeq_type_identifier( + TypeIdentifierPair& type_ids_ChargingSessionSeq) +{ + ReturnCode_t return_code_ChargingSessionSeq {eprosima::fastdds::dds::RETCODE_OK}; + return_code_ChargingSessionSeq = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "safe_edge::pilot_server::ChargingSessionSeq", type_ids_ChargingSessionSeq); + if (eprosima::fastdds::dds::RETCODE_OK != return_code_ChargingSessionSeq) + { + AliasTypeFlag alias_flags_ChargingSessionSeq = 0; + QualifiedTypeName type_name_ChargingSessionSeq = "safe_edge::pilot_server::ChargingSessionSeq"; + eprosima::fastcdr::optional type_ann_builtin_ChargingSessionSeq; + eprosima::fastcdr::optional ann_custom_ChargingSessionSeq; + CompleteTypeDetail detail_ChargingSessionSeq = TypeObjectUtils::build_complete_type_detail(type_ann_builtin_ChargingSessionSeq, ann_custom_ChargingSessionSeq, type_name_ChargingSessionSeq.to_string()); + CompleteAliasHeader header_ChargingSessionSeq = TypeObjectUtils::build_complete_alias_header(detail_ChargingSessionSeq); + AliasMemberFlag related_flags_ChargingSessionSeq = 0; + return_code_ChargingSessionSeq = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "anonymous_sequence_safe_edge_pilot_server_ChargingSession_1000", type_ids_ChargingSessionSeq); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_ChargingSessionSeq) + { + return_code_ChargingSessionSeq = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "safe_edge::pilot_server::ChargingSession", type_ids_ChargingSessionSeq); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_ChargingSessionSeq) + { + ::safe_edge::pilot_server::register_ChargingSession_type_identifier(type_ids_ChargingSessionSeq); + } + bool element_identifier_anonymous_sequence_safe_edge_pilot_server_ChargingSession_1000_ec {false}; + TypeIdentifier* element_identifier_anonymous_sequence_safe_edge_pilot_server_ChargingSession_1000 {new TypeIdentifier(TypeObjectUtils::retrieve_complete_type_identifier(type_ids_ChargingSessionSeq, element_identifier_anonymous_sequence_safe_edge_pilot_server_ChargingSession_1000_ec))}; + if (!element_identifier_anonymous_sequence_safe_edge_pilot_server_ChargingSession_1000_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Sequence element TypeIdentifier inconsistent."); + return; + } + EquivalenceKind equiv_kind_anonymous_sequence_safe_edge_pilot_server_ChargingSession_1000 = EK_COMPLETE; + if (TK_NONE == type_ids_ChargingSessionSeq.type_identifier2()._d()) + { + equiv_kind_anonymous_sequence_safe_edge_pilot_server_ChargingSession_1000 = EK_BOTH; + } + CollectionElementFlag element_flags_anonymous_sequence_safe_edge_pilot_server_ChargingSession_1000 = 0; + PlainCollectionHeader header_anonymous_sequence_safe_edge_pilot_server_ChargingSession_1000 = TypeObjectUtils::build_plain_collection_header(equiv_kind_anonymous_sequence_safe_edge_pilot_server_ChargingSession_1000, element_flags_anonymous_sequence_safe_edge_pilot_server_ChargingSession_1000); + { + LBound bound = 1000; + PlainSequenceLElemDefn seq_ldefn = TypeObjectUtils::build_plain_sequence_l_elem_defn(header_anonymous_sequence_safe_edge_pilot_server_ChargingSession_1000, bound, + eprosima::fastcdr::external(element_identifier_anonymous_sequence_safe_edge_pilot_server_ChargingSession_1000)); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_l_sequence_type_identifier(seq_ldefn, "anonymous_sequence_safe_edge_pilot_server_ChargingSession_1000", type_ids_ChargingSessionSeq)) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "anonymous_sequence_safe_edge_pilot_server_ChargingSession_1000 already registered in TypeObjectRegistry for a different type."); + } + } + } + bool common_ChargingSessionSeq_ec {false}; + CommonAliasBody common_ChargingSessionSeq {TypeObjectUtils::build_common_alias_body(related_flags_ChargingSessionSeq, + TypeObjectUtils::retrieve_complete_type_identifier(type_ids_ChargingSessionSeq, common_ChargingSessionSeq_ec))}; + if (!common_ChargingSessionSeq_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "safe_edge::pilot_server::ChargingSessionSeq related TypeIdentifier inconsistent."); + return; + } + eprosima::fastcdr::optional member_ann_builtin_ChargingSessionSeq; + ann_custom_ChargingSessionSeq.reset(); + CompleteAliasBody body_ChargingSessionSeq = TypeObjectUtils::build_complete_alias_body(common_ChargingSessionSeq, + member_ann_builtin_ChargingSessionSeq, ann_custom_ChargingSessionSeq); + CompleteAliasType alias_type_ChargingSessionSeq = TypeObjectUtils::build_complete_alias_type(alias_flags_ChargingSessionSeq, + header_ChargingSessionSeq, body_ChargingSessionSeq); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_alias_type_object(alias_type_ChargingSessionSeq, + type_name_ChargingSessionSeq.to_string(), type_ids_ChargingSessionSeq)) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "safe_edge::pilot_server::ChargingSessionSeq already registered in TypeObjectRegistry for a different type."); + } + } +} + +// TypeIdentifier is returned by reference: dependent structures/unions are registered in this same method +void register_TransitHealth_type_identifier( + TypeIdentifierPair& type_ids_TransitHealth) +{ + + ReturnCode_t return_code_TransitHealth {eprosima::fastdds::dds::RETCODE_OK}; + return_code_TransitHealth = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "safe_edge::pilot_server::TransitHealth", type_ids_TransitHealth); + if (eprosima::fastdds::dds::RETCODE_OK != return_code_TransitHealth) + { + StructTypeFlag struct_flags_TransitHealth = TypeObjectUtils::build_struct_type_flag(eprosima::fastdds::dds::xtypes::ExtensibilityKind::APPENDABLE, + false, false); + QualifiedTypeName type_name_TransitHealth = "safe_edge::pilot_server::TransitHealth"; + eprosima::fastcdr::optional type_ann_builtin_TransitHealth; + eprosima::fastcdr::optional ann_custom_TransitHealth; + CompleteTypeDetail detail_TransitHealth = TypeObjectUtils::build_complete_type_detail(type_ann_builtin_TransitHealth, ann_custom_TransitHealth, type_name_TransitHealth.to_string()); + CompleteStructHeader header_TransitHealth; + header_TransitHealth = TypeObjectUtils::build_complete_struct_header(TypeIdentifier(), detail_TransitHealth); + CompleteStructMemberSeq member_seq_TransitHealth; + { + TypeIdentifierPair type_ids_status; + ReturnCode_t return_code_status {eprosima::fastdds::dds::RETCODE_OK}; + return_code_status = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "anonymous_string_unbounded", type_ids_status); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_status) + { + { + SBound bound = 0; + StringSTypeDefn string_sdefn = TypeObjectUtils::build_string_s_type_defn(bound); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_s_string_type_identifier(string_sdefn, + "anonymous_string_unbounded", type_ids_status)) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "anonymous_string_unbounded already registered in TypeObjectRegistry for a different type."); + } + } + } + StructMemberFlag member_flags_status = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_status = 0x00000000; + bool common_status_ec {false}; + CommonStructMember common_status {TypeObjectUtils::build_common_struct_member(member_id_status, member_flags_status, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_status, common_status_ec))}; + if (!common_status_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure status member TypeIdentifier inconsistent."); + return; + } + MemberName name_status = "status"; + eprosima::fastcdr::optional member_ann_builtin_status; + ann_custom_TransitHealth.reset(); + CompleteMemberDetail detail_status = TypeObjectUtils::build_complete_member_detail(name_status, member_ann_builtin_status, ann_custom_TransitHealth); + CompleteStructMember member_status = TypeObjectUtils::build_complete_struct_member(common_status, detail_status); + TypeObjectUtils::add_complete_struct_member(member_seq_TransitHealth, member_status); + } + { + TypeIdentifierPair type_ids_last_fetch_ts; + ReturnCode_t return_code_last_fetch_ts {eprosima::fastdds::dds::RETCODE_OK}; + return_code_last_fetch_ts = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "_double", type_ids_last_fetch_ts); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_last_fetch_ts) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "last_fetch_ts Structure member TypeIdentifier unknown to TypeObjectRegistry."); + return; + } + StructMemberFlag member_flags_last_fetch_ts = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_last_fetch_ts = 0x00000001; + bool common_last_fetch_ts_ec {false}; + CommonStructMember common_last_fetch_ts {TypeObjectUtils::build_common_struct_member(member_id_last_fetch_ts, member_flags_last_fetch_ts, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_last_fetch_ts, common_last_fetch_ts_ec))}; + if (!common_last_fetch_ts_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure last_fetch_ts member TypeIdentifier inconsistent."); + return; + } + MemberName name_last_fetch_ts = "last_fetch_ts"; + eprosima::fastcdr::optional member_ann_builtin_last_fetch_ts; + ann_custom_TransitHealth.reset(); + CompleteMemberDetail detail_last_fetch_ts = TypeObjectUtils::build_complete_member_detail(name_last_fetch_ts, member_ann_builtin_last_fetch_ts, ann_custom_TransitHealth); + CompleteStructMember member_last_fetch_ts = TypeObjectUtils::build_complete_struct_member(common_last_fetch_ts, detail_last_fetch_ts); + TypeObjectUtils::add_complete_struct_member(member_seq_TransitHealth, member_last_fetch_ts); + } + CompleteStructType struct_type_TransitHealth = TypeObjectUtils::build_complete_struct_type(struct_flags_TransitHealth, header_TransitHealth, member_seq_TransitHealth); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_struct_type_object(struct_type_TransitHealth, type_name_TransitHealth.to_string(), type_ids_TransitHealth)) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "safe_edge::pilot_server::TransitHealth already registered in TypeObjectRegistry for a different type."); + } + } +}// TypeIdentifier is returned by reference: dependent structures/unions are registered in this same method +void register_RouteMetric_type_identifier( + TypeIdentifierPair& type_ids_RouteMetric) +{ + + ReturnCode_t return_code_RouteMetric {eprosima::fastdds::dds::RETCODE_OK}; + return_code_RouteMetric = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "safe_edge::pilot_server::RouteMetric", type_ids_RouteMetric); + if (eprosima::fastdds::dds::RETCODE_OK != return_code_RouteMetric) + { + StructTypeFlag struct_flags_RouteMetric = TypeObjectUtils::build_struct_type_flag(eprosima::fastdds::dds::xtypes::ExtensibilityKind::APPENDABLE, + false, false); + QualifiedTypeName type_name_RouteMetric = "safe_edge::pilot_server::RouteMetric"; + eprosima::fastcdr::optional type_ann_builtin_RouteMetric; + eprosima::fastcdr::optional ann_custom_RouteMetric; + CompleteTypeDetail detail_RouteMetric = TypeObjectUtils::build_complete_type_detail(type_ann_builtin_RouteMetric, ann_custom_RouteMetric, type_name_RouteMetric.to_string()); + CompleteStructHeader header_RouteMetric; + header_RouteMetric = TypeObjectUtils::build_complete_struct_header(TypeIdentifier(), detail_RouteMetric); + CompleteStructMemberSeq member_seq_RouteMetric; + { + TypeIdentifierPair type_ids_route_id; + ReturnCode_t return_code_route_id {eprosima::fastdds::dds::RETCODE_OK}; + return_code_route_id = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "anonymous_string_unbounded", type_ids_route_id); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_route_id) + { + { + SBound bound = 0; + StringSTypeDefn string_sdefn = TypeObjectUtils::build_string_s_type_defn(bound); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_s_string_type_identifier(string_sdefn, + "anonymous_string_unbounded", type_ids_route_id)) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "anonymous_string_unbounded already registered in TypeObjectRegistry for a different type."); + } + } + } + StructMemberFlag member_flags_route_id = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_route_id = 0x00000000; + bool common_route_id_ec {false}; + CommonStructMember common_route_id {TypeObjectUtils::build_common_struct_member(member_id_route_id, member_flags_route_id, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_route_id, common_route_id_ec))}; + if (!common_route_id_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure route_id member TypeIdentifier inconsistent."); + return; + } + MemberName name_route_id = "route_id"; + eprosima::fastcdr::optional member_ann_builtin_route_id; + ann_custom_RouteMetric.reset(); + CompleteMemberDetail detail_route_id = TypeObjectUtils::build_complete_member_detail(name_route_id, member_ann_builtin_route_id, ann_custom_RouteMetric); + CompleteStructMember member_route_id = TypeObjectUtils::build_complete_struct_member(common_route_id, detail_route_id); + TypeObjectUtils::add_complete_struct_member(member_seq_RouteMetric, member_route_id); + } + { + TypeIdentifierPair type_ids_updates_count; + ReturnCode_t return_code_updates_count {eprosima::fastdds::dds::RETCODE_OK}; + return_code_updates_count = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "_int32_t", type_ids_updates_count); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_updates_count) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "updates_count Structure member TypeIdentifier unknown to TypeObjectRegistry."); + return; + } + StructMemberFlag member_flags_updates_count = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_updates_count = 0x00000001; + bool common_updates_count_ec {false}; + CommonStructMember common_updates_count {TypeObjectUtils::build_common_struct_member(member_id_updates_count, member_flags_updates_count, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_updates_count, common_updates_count_ec))}; + if (!common_updates_count_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure updates_count member TypeIdentifier inconsistent."); + return; + } + MemberName name_updates_count = "updates_count"; + eprosima::fastcdr::optional member_ann_builtin_updates_count; + ann_custom_RouteMetric.reset(); + CompleteMemberDetail detail_updates_count = TypeObjectUtils::build_complete_member_detail(name_updates_count, member_ann_builtin_updates_count, ann_custom_RouteMetric); + CompleteStructMember member_updates_count = TypeObjectUtils::build_complete_struct_member(common_updates_count, detail_updates_count); + TypeObjectUtils::add_complete_struct_member(member_seq_RouteMetric, member_updates_count); + } + CompleteStructType struct_type_RouteMetric = TypeObjectUtils::build_complete_struct_type(struct_flags_RouteMetric, header_RouteMetric, member_seq_RouteMetric); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_struct_type_object(struct_type_RouteMetric, type_name_RouteMetric.to_string(), type_ids_RouteMetric)) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "safe_edge::pilot_server::RouteMetric already registered in TypeObjectRegistry for a different type."); + } + } +}void register_RouteMetricSeq_type_identifier( + TypeIdentifierPair& type_ids_RouteMetricSeq) +{ + ReturnCode_t return_code_RouteMetricSeq {eprosima::fastdds::dds::RETCODE_OK}; + return_code_RouteMetricSeq = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "safe_edge::pilot_server::RouteMetricSeq", type_ids_RouteMetricSeq); + if (eprosima::fastdds::dds::RETCODE_OK != return_code_RouteMetricSeq) + { + AliasTypeFlag alias_flags_RouteMetricSeq = 0; + QualifiedTypeName type_name_RouteMetricSeq = "safe_edge::pilot_server::RouteMetricSeq"; + eprosima::fastcdr::optional type_ann_builtin_RouteMetricSeq; + eprosima::fastcdr::optional ann_custom_RouteMetricSeq; + CompleteTypeDetail detail_RouteMetricSeq = TypeObjectUtils::build_complete_type_detail(type_ann_builtin_RouteMetricSeq, ann_custom_RouteMetricSeq, type_name_RouteMetricSeq.to_string()); + CompleteAliasHeader header_RouteMetricSeq = TypeObjectUtils::build_complete_alias_header(detail_RouteMetricSeq); + AliasMemberFlag related_flags_RouteMetricSeq = 0; + return_code_RouteMetricSeq = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "anonymous_sequence_safe_edge_pilot_server_RouteMetric_512", type_ids_RouteMetricSeq); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_RouteMetricSeq) + { + return_code_RouteMetricSeq = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "safe_edge::pilot_server::RouteMetric", type_ids_RouteMetricSeq); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_RouteMetricSeq) + { + ::safe_edge::pilot_server::register_RouteMetric_type_identifier(type_ids_RouteMetricSeq); + } + bool element_identifier_anonymous_sequence_safe_edge_pilot_server_RouteMetric_512_ec {false}; + TypeIdentifier* element_identifier_anonymous_sequence_safe_edge_pilot_server_RouteMetric_512 {new TypeIdentifier(TypeObjectUtils::retrieve_complete_type_identifier(type_ids_RouteMetricSeq, element_identifier_anonymous_sequence_safe_edge_pilot_server_RouteMetric_512_ec))}; + if (!element_identifier_anonymous_sequence_safe_edge_pilot_server_RouteMetric_512_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Sequence element TypeIdentifier inconsistent."); + return; + } + EquivalenceKind equiv_kind_anonymous_sequence_safe_edge_pilot_server_RouteMetric_512 = EK_COMPLETE; + if (TK_NONE == type_ids_RouteMetricSeq.type_identifier2()._d()) + { + equiv_kind_anonymous_sequence_safe_edge_pilot_server_RouteMetric_512 = EK_BOTH; + } + CollectionElementFlag element_flags_anonymous_sequence_safe_edge_pilot_server_RouteMetric_512 = 0; + PlainCollectionHeader header_anonymous_sequence_safe_edge_pilot_server_RouteMetric_512 = TypeObjectUtils::build_plain_collection_header(equiv_kind_anonymous_sequence_safe_edge_pilot_server_RouteMetric_512, element_flags_anonymous_sequence_safe_edge_pilot_server_RouteMetric_512); + { + LBound bound = 512; + PlainSequenceLElemDefn seq_ldefn = TypeObjectUtils::build_plain_sequence_l_elem_defn(header_anonymous_sequence_safe_edge_pilot_server_RouteMetric_512, bound, + eprosima::fastcdr::external(element_identifier_anonymous_sequence_safe_edge_pilot_server_RouteMetric_512)); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_l_sequence_type_identifier(seq_ldefn, "anonymous_sequence_safe_edge_pilot_server_RouteMetric_512", type_ids_RouteMetricSeq)) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "anonymous_sequence_safe_edge_pilot_server_RouteMetric_512 already registered in TypeObjectRegistry for a different type."); + } + } + } + bool common_RouteMetricSeq_ec {false}; + CommonAliasBody common_RouteMetricSeq {TypeObjectUtils::build_common_alias_body(related_flags_RouteMetricSeq, + TypeObjectUtils::retrieve_complete_type_identifier(type_ids_RouteMetricSeq, common_RouteMetricSeq_ec))}; + if (!common_RouteMetricSeq_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "safe_edge::pilot_server::RouteMetricSeq related TypeIdentifier inconsistent."); + return; + } + eprosima::fastcdr::optional member_ann_builtin_RouteMetricSeq; + ann_custom_RouteMetricSeq.reset(); + CompleteAliasBody body_RouteMetricSeq = TypeObjectUtils::build_complete_alias_body(common_RouteMetricSeq, + member_ann_builtin_RouteMetricSeq, ann_custom_RouteMetricSeq); + CompleteAliasType alias_type_RouteMetricSeq = TypeObjectUtils::build_complete_alias_type(alias_flags_RouteMetricSeq, + header_RouteMetricSeq, body_RouteMetricSeq); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_alias_type_object(alias_type_RouteMetricSeq, + type_name_RouteMetricSeq.to_string(), type_ids_RouteMetricSeq)) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "safe_edge::pilot_server::RouteMetricSeq already registered in TypeObjectRegistry for a different type."); + } + } +} + +// TypeIdentifier is returned by reference: dependent structures/unions are registered in this same method +void register_TransitMetrics_type_identifier( + TypeIdentifierPair& type_ids_TransitMetrics) +{ + + ReturnCode_t return_code_TransitMetrics {eprosima::fastdds::dds::RETCODE_OK}; + return_code_TransitMetrics = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "safe_edge::pilot_server::TransitMetrics", type_ids_TransitMetrics); + if (eprosima::fastdds::dds::RETCODE_OK != return_code_TransitMetrics) + { + StructTypeFlag struct_flags_TransitMetrics = TypeObjectUtils::build_struct_type_flag(eprosima::fastdds::dds::xtypes::ExtensibilityKind::APPENDABLE, + false, false); + QualifiedTypeName type_name_TransitMetrics = "safe_edge::pilot_server::TransitMetrics"; + eprosima::fastcdr::optional type_ann_builtin_TransitMetrics; + eprosima::fastcdr::optional ann_custom_TransitMetrics; + CompleteTypeDetail detail_TransitMetrics = TypeObjectUtils::build_complete_type_detail(type_ann_builtin_TransitMetrics, ann_custom_TransitMetrics, type_name_TransitMetrics.to_string()); + CompleteStructHeader header_TransitMetrics; + header_TransitMetrics = TypeObjectUtils::build_complete_struct_header(TypeIdentifier(), detail_TransitMetrics); + CompleteStructMemberSeq member_seq_TransitMetrics; + { + TypeIdentifierPair type_ids_by_route; + ReturnCode_t return_code_by_route {eprosima::fastdds::dds::RETCODE_OK}; + return_code_by_route = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "safe_edge::pilot_server::RouteMetricSeq", type_ids_by_route); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_by_route) + { + ::safe_edge::pilot_server::register_RouteMetricSeq_type_identifier(type_ids_by_route); + } + StructMemberFlag member_flags_by_route = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_by_route = 0x00000000; + bool common_by_route_ec {false}; + CommonStructMember common_by_route {TypeObjectUtils::build_common_struct_member(member_id_by_route, member_flags_by_route, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_by_route, common_by_route_ec))}; + if (!common_by_route_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure by_route member TypeIdentifier inconsistent."); + return; + } + MemberName name_by_route = "by_route"; + eprosima::fastcdr::optional member_ann_builtin_by_route; + ann_custom_TransitMetrics.reset(); + CompleteMemberDetail detail_by_route = TypeObjectUtils::build_complete_member_detail(name_by_route, member_ann_builtin_by_route, ann_custom_TransitMetrics); + CompleteStructMember member_by_route = TypeObjectUtils::build_complete_struct_member(common_by_route, detail_by_route); + TypeObjectUtils::add_complete_struct_member(member_seq_TransitMetrics, member_by_route); + } + { + TypeIdentifierPair type_ids_vehicles_seen; + ReturnCode_t return_code_vehicles_seen {eprosima::fastdds::dds::RETCODE_OK}; + return_code_vehicles_seen = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "_int32_t", type_ids_vehicles_seen); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_vehicles_seen) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "vehicles_seen Structure member TypeIdentifier unknown to TypeObjectRegistry."); + return; + } + StructMemberFlag member_flags_vehicles_seen = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_vehicles_seen = 0x00000001; + bool common_vehicles_seen_ec {false}; + CommonStructMember common_vehicles_seen {TypeObjectUtils::build_common_struct_member(member_id_vehicles_seen, member_flags_vehicles_seen, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_vehicles_seen, common_vehicles_seen_ec))}; + if (!common_vehicles_seen_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure vehicles_seen member TypeIdentifier inconsistent."); + return; + } + MemberName name_vehicles_seen = "vehicles_seen"; + eprosima::fastcdr::optional member_ann_builtin_vehicles_seen; + ann_custom_TransitMetrics.reset(); + CompleteMemberDetail detail_vehicles_seen = TypeObjectUtils::build_complete_member_detail(name_vehicles_seen, member_ann_builtin_vehicles_seen, ann_custom_TransitMetrics); + CompleteStructMember member_vehicles_seen = TypeObjectUtils::build_complete_struct_member(common_vehicles_seen, detail_vehicles_seen); + TypeObjectUtils::add_complete_struct_member(member_seq_TransitMetrics, member_vehicles_seen); + } + CompleteStructType struct_type_TransitMetrics = TypeObjectUtils::build_complete_struct_type(struct_flags_TransitMetrics, header_TransitMetrics, member_seq_TransitMetrics); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_struct_type_object(struct_type_TransitMetrics, type_name_TransitMetrics.to_string(), type_ids_TransitMetrics)) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "safe_edge::pilot_server::TransitMetrics already registered in TypeObjectRegistry for a different type."); + } + } +}void register_RequestedDataType_type_identifier( + TypeIdentifierPair& type_ids_RequestedDataType) +{ + ReturnCode_t return_code_RequestedDataType {eprosima::fastdds::dds::RETCODE_OK}; + return_code_RequestedDataType = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "safe_edge::pilot_server::RequestedDataType", type_ids_RequestedDataType); + if (eprosima::fastdds::dds::RETCODE_OK != return_code_RequestedDataType) + { + EnumTypeFlag enum_flags_RequestedDataType = 0; + BitBound bit_bound_RequestedDataType = 32; + CommonEnumeratedHeader common_RequestedDataType = TypeObjectUtils::build_common_enumerated_header(bit_bound_RequestedDataType); + QualifiedTypeName type_name_RequestedDataType = "safe_edge::pilot_server::RequestedDataType"; + eprosima::fastcdr::optional type_ann_builtin_RequestedDataType; + eprosima::fastcdr::optional ann_custom_RequestedDataType; + CompleteTypeDetail detail_RequestedDataType = TypeObjectUtils::build_complete_type_detail(type_ann_builtin_RequestedDataType, ann_custom_RequestedDataType, type_name_RequestedDataType.to_string()); + CompleteEnumeratedHeader header_RequestedDataType = TypeObjectUtils::build_complete_enumerated_header(common_RequestedDataType, detail_RequestedDataType); + CompleteEnumeratedLiteralSeq literal_seq_RequestedDataType; + { + EnumeratedLiteralFlag flags_CHARGER_LOCATION = TypeObjectUtils::build_enumerated_literal_flag(false); + CommonEnumeratedLiteral common_CHARGER_LOCATION = TypeObjectUtils::build_common_enumerated_literal(0, flags_CHARGER_LOCATION); + eprosima::fastcdr::optional member_ann_builtin_CHARGER_LOCATION; + ann_custom_RequestedDataType.reset(); + MemberName name_CHARGER_LOCATION = "CHARGER_LOCATION"; + CompleteMemberDetail detail_CHARGER_LOCATION = TypeObjectUtils::build_complete_member_detail(name_CHARGER_LOCATION, member_ann_builtin_CHARGER_LOCATION, ann_custom_RequestedDataType); + CompleteEnumeratedLiteral literal_CHARGER_LOCATION = TypeObjectUtils::build_complete_enumerated_literal(common_CHARGER_LOCATION, detail_CHARGER_LOCATION); + TypeObjectUtils::add_complete_enumerated_literal(literal_seq_RequestedDataType, literal_CHARGER_LOCATION); + } + { + EnumeratedLiteralFlag flags_CHARGER_TYPE = TypeObjectUtils::build_enumerated_literal_flag(false); + CommonEnumeratedLiteral common_CHARGER_TYPE = TypeObjectUtils::build_common_enumerated_literal(1, flags_CHARGER_TYPE); + eprosima::fastcdr::optional member_ann_builtin_CHARGER_TYPE; + ann_custom_RequestedDataType.reset(); + MemberName name_CHARGER_TYPE = "CHARGER_TYPE"; + CompleteMemberDetail detail_CHARGER_TYPE = TypeObjectUtils::build_complete_member_detail(name_CHARGER_TYPE, member_ann_builtin_CHARGER_TYPE, ann_custom_RequestedDataType); + CompleteEnumeratedLiteral literal_CHARGER_TYPE = TypeObjectUtils::build_complete_enumerated_literal(common_CHARGER_TYPE, detail_CHARGER_TYPE); + TypeObjectUtils::add_complete_enumerated_literal(literal_seq_RequestedDataType, literal_CHARGER_TYPE); + } + { + EnumeratedLiteralFlag flags_CHARGING_SESSION = TypeObjectUtils::build_enumerated_literal_flag(false); + CommonEnumeratedLiteral common_CHARGING_SESSION = TypeObjectUtils::build_common_enumerated_literal(2, flags_CHARGING_SESSION); + eprosima::fastcdr::optional member_ann_builtin_CHARGING_SESSION; + ann_custom_RequestedDataType.reset(); + MemberName name_CHARGING_SESSION = "CHARGING_SESSION"; + CompleteMemberDetail detail_CHARGING_SESSION = TypeObjectUtils::build_complete_member_detail(name_CHARGING_SESSION, member_ann_builtin_CHARGING_SESSION, ann_custom_RequestedDataType); + CompleteEnumeratedLiteral literal_CHARGING_SESSION = TypeObjectUtils::build_complete_enumerated_literal(common_CHARGING_SESSION, detail_CHARGING_SESSION); + TypeObjectUtils::add_complete_enumerated_literal(literal_seq_RequestedDataType, literal_CHARGING_SESSION); + } + { + EnumeratedLiteralFlag flags_TRANSIT_HEALTH = TypeObjectUtils::build_enumerated_literal_flag(false); + CommonEnumeratedLiteral common_TRANSIT_HEALTH = TypeObjectUtils::build_common_enumerated_literal(3, flags_TRANSIT_HEALTH); + eprosima::fastcdr::optional member_ann_builtin_TRANSIT_HEALTH; + ann_custom_RequestedDataType.reset(); + MemberName name_TRANSIT_HEALTH = "TRANSIT_HEALTH"; + CompleteMemberDetail detail_TRANSIT_HEALTH = TypeObjectUtils::build_complete_member_detail(name_TRANSIT_HEALTH, member_ann_builtin_TRANSIT_HEALTH, ann_custom_RequestedDataType); + CompleteEnumeratedLiteral literal_TRANSIT_HEALTH = TypeObjectUtils::build_complete_enumerated_literal(common_TRANSIT_HEALTH, detail_TRANSIT_HEALTH); + TypeObjectUtils::add_complete_enumerated_literal(literal_seq_RequestedDataType, literal_TRANSIT_HEALTH); + } + { + EnumeratedLiteralFlag flags_TRANSIT_METRICS = TypeObjectUtils::build_enumerated_literal_flag(false); + CommonEnumeratedLiteral common_TRANSIT_METRICS = TypeObjectUtils::build_common_enumerated_literal(4, flags_TRANSIT_METRICS); + eprosima::fastcdr::optional member_ann_builtin_TRANSIT_METRICS; + ann_custom_RequestedDataType.reset(); + MemberName name_TRANSIT_METRICS = "TRANSIT_METRICS"; + CompleteMemberDetail detail_TRANSIT_METRICS = TypeObjectUtils::build_complete_member_detail(name_TRANSIT_METRICS, member_ann_builtin_TRANSIT_METRICS, ann_custom_RequestedDataType); + CompleteEnumeratedLiteral literal_TRANSIT_METRICS = TypeObjectUtils::build_complete_enumerated_literal(common_TRANSIT_METRICS, detail_TRANSIT_METRICS); + TypeObjectUtils::add_complete_enumerated_literal(literal_seq_RequestedDataType, literal_TRANSIT_METRICS); + } + CompleteEnumeratedType enumerated_type_RequestedDataType = TypeObjectUtils::build_complete_enumerated_type(enum_flags_RequestedDataType, header_RequestedDataType, + literal_seq_RequestedDataType); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_enumerated_type_object(enumerated_type_RequestedDataType, type_name_RequestedDataType.to_string(), type_ids_RequestedDataType)) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "safe_edge::pilot_server::RequestedDataType already registered in TypeObjectRegistry for a different type."); + } + } +}// TypeIdentifier is returned by reference: dependent structures/unions are registered in this same method +void register_ServerQuery_type_identifier( + TypeIdentifierPair& type_ids_ServerQuery) +{ + + ReturnCode_t return_code_ServerQuery {eprosima::fastdds::dds::RETCODE_OK}; + return_code_ServerQuery = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "safe_edge::pilot_server::ServerQuery", type_ids_ServerQuery); + if (eprosima::fastdds::dds::RETCODE_OK != return_code_ServerQuery) + { + StructTypeFlag struct_flags_ServerQuery = TypeObjectUtils::build_struct_type_flag(eprosima::fastdds::dds::xtypes::ExtensibilityKind::APPENDABLE, + false, false); + QualifiedTypeName type_name_ServerQuery = "safe_edge::pilot_server::ServerQuery"; + eprosima::fastcdr::optional type_ann_builtin_ServerQuery; + eprosima::fastcdr::optional ann_custom_ServerQuery; + CompleteTypeDetail detail_ServerQuery = TypeObjectUtils::build_complete_type_detail(type_ann_builtin_ServerQuery, ann_custom_ServerQuery, type_name_ServerQuery.to_string()); + CompleteStructHeader header_ServerQuery; + header_ServerQuery = TypeObjectUtils::build_complete_struct_header(TypeIdentifier(), detail_ServerQuery); + CompleteStructMemberSeq member_seq_ServerQuery; + { + TypeIdentifierPair type_ids_requested_by; + ReturnCode_t return_code_requested_by {eprosima::fastdds::dds::RETCODE_OK}; + return_code_requested_by = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "anonymous_string_unbounded", type_ids_requested_by); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_requested_by) + { + { + SBound bound = 0; + StringSTypeDefn string_sdefn = TypeObjectUtils::build_string_s_type_defn(bound); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_s_string_type_identifier(string_sdefn, + "anonymous_string_unbounded", type_ids_requested_by)) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "anonymous_string_unbounded already registered in TypeObjectRegistry for a different type."); + } + } + } + StructMemberFlag member_flags_requested_by = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_requested_by = 0x00000000; + bool common_requested_by_ec {false}; + CommonStructMember common_requested_by {TypeObjectUtils::build_common_struct_member(member_id_requested_by, member_flags_requested_by, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_requested_by, common_requested_by_ec))}; + if (!common_requested_by_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure requested_by member TypeIdentifier inconsistent."); + return; + } + MemberName name_requested_by = "requested_by"; + eprosima::fastcdr::optional member_ann_builtin_requested_by; + ann_custom_ServerQuery.reset(); + CompleteMemberDetail detail_requested_by = TypeObjectUtils::build_complete_member_detail(name_requested_by, member_ann_builtin_requested_by, ann_custom_ServerQuery); + CompleteStructMember member_requested_by = TypeObjectUtils::build_complete_struct_member(common_requested_by, detail_requested_by); + TypeObjectUtils::add_complete_struct_member(member_seq_ServerQuery, member_requested_by); + } + { + TypeIdentifierPair type_ids_requested_data_type; + ReturnCode_t return_code_requested_data_type {eprosima::fastdds::dds::RETCODE_OK}; + return_code_requested_data_type = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "safe_edge::pilot_server::RequestedDataType", type_ids_requested_data_type); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_requested_data_type) + { + ::safe_edge::pilot_server::register_RequestedDataType_type_identifier(type_ids_requested_data_type); + } + StructMemberFlag member_flags_requested_data_type = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_requested_data_type = 0x00000001; + bool common_requested_data_type_ec {false}; + CommonStructMember common_requested_data_type {TypeObjectUtils::build_common_struct_member(member_id_requested_data_type, member_flags_requested_data_type, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_requested_data_type, common_requested_data_type_ec))}; + if (!common_requested_data_type_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure requested_data_type member TypeIdentifier inconsistent."); + return; + } + MemberName name_requested_data_type = "requested_data_type"; + eprosima::fastcdr::optional member_ann_builtin_requested_data_type; + ann_custom_ServerQuery.reset(); + CompleteMemberDetail detail_requested_data_type = TypeObjectUtils::build_complete_member_detail(name_requested_data_type, member_ann_builtin_requested_data_type, ann_custom_ServerQuery); + CompleteStructMember member_requested_data_type = TypeObjectUtils::build_complete_struct_member(common_requested_data_type, detail_requested_data_type); + TypeObjectUtils::add_complete_struct_member(member_seq_ServerQuery, member_requested_data_type); + } + CompleteStructType struct_type_ServerQuery = TypeObjectUtils::build_complete_struct_type(struct_flags_ServerQuery, header_ServerQuery, member_seq_ServerQuery); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_struct_type_object(struct_type_ServerQuery, type_name_ServerQuery.to_string(), type_ids_ServerQuery)) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "safe_edge::pilot_server::ServerQuery already registered in TypeObjectRegistry for a different type."); + } + } +} +} // namespace pilot_server + +} // namespace safe_edge + diff --git a/fast_dds/idl/pilot_serverTypeObjectSupport.hpp b/fast_dds/idl/pilot_serverTypeObjectSupport.hpp new file mode 100644 index 0000000..8c106b9 --- /dev/null +++ b/fast_dds/idl/pilot_serverTypeObjectSupport.hpp @@ -0,0 +1,214 @@ +// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/*! + * @file pilot_serverTypeObjectSupport.hpp + * Header file containing the API required to register the TypeObject representation of the described types in the IDL file + * + * This file was generated by the tool fastddsgen (version: 4.3.0). + */ + +#ifndef FAST_DDS_GENERATED__SAFE_EDGE_PILOT_SERVER_PILOT_SERVER_TYPE_OBJECT_SUPPORT_HPP +#define FAST_DDS_GENERATED__SAFE_EDGE_PILOT_SERVER_PILOT_SERVER_TYPE_OBJECT_SUPPORT_HPP + +#include + +#include "commonTypeObjectSupport.hpp" + +#if defined(_WIN32) +#if defined(EPROSIMA_USER_DLL_EXPORT) +#define eProsima_user_DllExport __declspec( dllexport ) +#else +#define eProsima_user_DllExport +#endif // EPROSIMA_USER_DLL_EXPORT +#else +#define eProsima_user_DllExport +#endif // _WIN32 + +#ifndef DOXYGEN_SHOULD_SKIP_THIS_PUBLIC + +namespace safe_edge { +namespace pilot_server { +/** + * @brief Register ChargerLocation related TypeIdentifier. + * Fully-descriptive TypeIdentifiers are directly registered. + * Hash TypeIdentifiers require to fill the TypeObject information and hash it, consequently, the TypeObject is + * indirectly registered as well. + * + * @param[out] type_ids TypeIdentifier of the registered type. + * The returned TypeIdentifier corresponds to the complete TypeIdentifier in case of hashed TypeIdentifiers. + * Invalid TypeIdentifier is returned in case of error. + */ +eProsima_user_DllExport void register_ChargerLocation_type_identifier( + eprosima::fastdds::dds::xtypes::TypeIdentifierPair& type_ids); + +/** + * @brief Register ChargerLocationSeq related TypeIdentifier. + * Fully-descriptive TypeIdentifiers are directly registered. + * Hash TypeIdentifiers require to fill the TypeObject information and hash it, consequently, the TypeObject is + * indirectly registered as well. + * + * @param[out] type_ids TypeIdentifier of the registered type. + * The returned TypeIdentifier corresponds to the complete TypeIdentifier in case of hashed TypeIdentifiers. + * Invalid TypeIdentifier is returned in case of error. + */ +eProsima_user_DllExport void register_ChargerLocationSeq_type_identifier( + eprosima::fastdds::dds::xtypes::TypeIdentifierPair& type_ids); + + + +/** + * @brief Register ChargerType related TypeIdentifier. + * Fully-descriptive TypeIdentifiers are directly registered. + * Hash TypeIdentifiers require to fill the TypeObject information and hash it, consequently, the TypeObject is + * indirectly registered as well. + * + * @param[out] type_ids TypeIdentifier of the registered type. + * The returned TypeIdentifier corresponds to the complete TypeIdentifier in case of hashed TypeIdentifiers. + * Invalid TypeIdentifier is returned in case of error. + */ +eProsima_user_DllExport void register_ChargerType_type_identifier( + eprosima::fastdds::dds::xtypes::TypeIdentifierPair& type_ids); + +/** + * @brief Register ChargerTypeSeq related TypeIdentifier. + * Fully-descriptive TypeIdentifiers are directly registered. + * Hash TypeIdentifiers require to fill the TypeObject information and hash it, consequently, the TypeObject is + * indirectly registered as well. + * + * @param[out] type_ids TypeIdentifier of the registered type. + * The returned TypeIdentifier corresponds to the complete TypeIdentifier in case of hashed TypeIdentifiers. + * Invalid TypeIdentifier is returned in case of error. + */ +eProsima_user_DllExport void register_ChargerTypeSeq_type_identifier( + eprosima::fastdds::dds::xtypes::TypeIdentifierPair& type_ids); + + + +/** + * @brief Register ChargingSession related TypeIdentifier. + * Fully-descriptive TypeIdentifiers are directly registered. + * Hash TypeIdentifiers require to fill the TypeObject information and hash it, consequently, the TypeObject is + * indirectly registered as well. + * + * @param[out] type_ids TypeIdentifier of the registered type. + * The returned TypeIdentifier corresponds to the complete TypeIdentifier in case of hashed TypeIdentifiers. + * Invalid TypeIdentifier is returned in case of error. + */ +eProsima_user_DllExport void register_ChargingSession_type_identifier( + eprosima::fastdds::dds::xtypes::TypeIdentifierPair& type_ids); + +/** + * @brief Register ChargingSessionSeq related TypeIdentifier. + * Fully-descriptive TypeIdentifiers are directly registered. + * Hash TypeIdentifiers require to fill the TypeObject information and hash it, consequently, the TypeObject is + * indirectly registered as well. + * + * @param[out] type_ids TypeIdentifier of the registered type. + * The returned TypeIdentifier corresponds to the complete TypeIdentifier in case of hashed TypeIdentifiers. + * Invalid TypeIdentifier is returned in case of error. + */ +eProsima_user_DllExport void register_ChargingSessionSeq_type_identifier( + eprosima::fastdds::dds::xtypes::TypeIdentifierPair& type_ids); + + + +/** + * @brief Register TransitHealth related TypeIdentifier. + * Fully-descriptive TypeIdentifiers are directly registered. + * Hash TypeIdentifiers require to fill the TypeObject information and hash it, consequently, the TypeObject is + * indirectly registered as well. + * + * @param[out] type_ids TypeIdentifier of the registered type. + * The returned TypeIdentifier corresponds to the complete TypeIdentifier in case of hashed TypeIdentifiers. + * Invalid TypeIdentifier is returned in case of error. + */ +eProsima_user_DllExport void register_TransitHealth_type_identifier( + eprosima::fastdds::dds::xtypes::TypeIdentifierPair& type_ids); + +/** + * @brief Register RouteMetric related TypeIdentifier. + * Fully-descriptive TypeIdentifiers are directly registered. + * Hash TypeIdentifiers require to fill the TypeObject information and hash it, consequently, the TypeObject is + * indirectly registered as well. + * + * @param[out] type_ids TypeIdentifier of the registered type. + * The returned TypeIdentifier corresponds to the complete TypeIdentifier in case of hashed TypeIdentifiers. + * Invalid TypeIdentifier is returned in case of error. + */ +eProsima_user_DllExport void register_RouteMetric_type_identifier( + eprosima::fastdds::dds::xtypes::TypeIdentifierPair& type_ids); + +/** + * @brief Register RouteMetricSeq related TypeIdentifier. + * Fully-descriptive TypeIdentifiers are directly registered. + * Hash TypeIdentifiers require to fill the TypeObject information and hash it, consequently, the TypeObject is + * indirectly registered as well. + * + * @param[out] type_ids TypeIdentifier of the registered type. + * The returned TypeIdentifier corresponds to the complete TypeIdentifier in case of hashed TypeIdentifiers. + * Invalid TypeIdentifier is returned in case of error. + */ +eProsima_user_DllExport void register_RouteMetricSeq_type_identifier( + eprosima::fastdds::dds::xtypes::TypeIdentifierPair& type_ids); + + + +/** + * @brief Register TransitMetrics related TypeIdentifier. + * Fully-descriptive TypeIdentifiers are directly registered. + * Hash TypeIdentifiers require to fill the TypeObject information and hash it, consequently, the TypeObject is + * indirectly registered as well. + * + * @param[out] type_ids TypeIdentifier of the registered type. + * The returned TypeIdentifier corresponds to the complete TypeIdentifier in case of hashed TypeIdentifiers. + * Invalid TypeIdentifier is returned in case of error. + */ +eProsima_user_DllExport void register_TransitMetrics_type_identifier( + eprosima::fastdds::dds::xtypes::TypeIdentifierPair& type_ids); + +/** + * @brief Register RequestedDataType related TypeIdentifier. + * Fully-descriptive TypeIdentifiers are directly registered. + * Hash TypeIdentifiers require to fill the TypeObject information and hash it, consequently, the TypeObject is + * indirectly registered as well. + * + * @param[out] type_ids TypeIdentifier of the registered type. + * The returned TypeIdentifier corresponds to the complete TypeIdentifier in case of hashed TypeIdentifiers. + * Invalid TypeIdentifier is returned in case of error. + */ +eProsima_user_DllExport void register_RequestedDataType_type_identifier( + eprosima::fastdds::dds::xtypes::TypeIdentifierPair& type_ids); + +/** + * @brief Register ServerQuery related TypeIdentifier. + * Fully-descriptive TypeIdentifiers are directly registered. + * Hash TypeIdentifiers require to fill the TypeObject information and hash it, consequently, the TypeObject is + * indirectly registered as well. + * + * @param[out] type_ids TypeIdentifier of the registered type. + * The returned TypeIdentifier corresponds to the complete TypeIdentifier in case of hashed TypeIdentifiers. + * Invalid TypeIdentifier is returned in case of error. + */ +eProsima_user_DllExport void register_ServerQuery_type_identifier( + eprosima::fastdds::dds::xtypes::TypeIdentifierPair& type_ids); + +} // namespace pilot_server + +} // namespace safe_edge + + +#endif // DOXYGEN_SHOULD_SKIP_THIS_PUBLIC + +#endif // FAST_DDS_GENERATED__SAFE_EDGE_PILOT_SERVER_PILOT_SERVER_TYPE_OBJECT_SUPPORT_HPP diff --git a/fast_dds/server/CMakeLists.txt b/fast_dds/server/CMakeLists.txt new file mode 100644 index 0000000..8b7fef1 --- /dev/null +++ b/fast_dds/server/CMakeLists.txt @@ -0,0 +1,147 @@ +cmake_minimum_required(VERSION 3.16) + +project(safe_edge_server LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +find_package(fastdds REQUIRED) +find_package(CURL REQUIRED) + + +if(CMAKE_SYSTEM_NAME STREQUAL "QNX") + set(SAFE_EDGE_PLATFORM_SOCKET_LIB socket) +endif() + +set(SAFE_EDGE_SERVER_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include") +set(SAFE_EDGE_IDL_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../idl") +set(SAFE_EDGE_SERVER_COMMON_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../common_server") + +function(safe_edge_apply_common_build_settings target_name) + target_include_directories( + "${target_name}" + PUBLIC + "${SAFE_EDGE_SERVER_INCLUDE_DIR}" + ) + + target_compile_options( + "${target_name}" + PRIVATE + -Wall + -Werror + -Wextra + -Wpedantic + ) +endfunction() + +add_library( + safe_edge_server_common + STATIC + ${SAFE_EDGE_IDL_INCLUDE_DIR}/commonPubSubTypes.cxx + ${SAFE_EDGE_IDL_INCLUDE_DIR}/commonTypeObjectSupport.cxx + ${SAFE_EDGE_IDL_INCLUDE_DIR}/pilot_serverPubSubTypes.cxx + ${SAFE_EDGE_IDL_INCLUDE_DIR}/pilot_serverTypeObjectSupport.cxx + ${SAFE_EDGE_SERVER_COMMON_DIR}/src/PilotServerClient.cpp + ${SAFE_EDGE_SERVER_COMMON_DIR}/src/PilotServerPayloadParser.cpp + src/common/PilotServerPublishHelper.cpp + src/common/RuntimeConfig.cpp + src/common/TopicNames.cpp +) +safe_edge_apply_common_build_settings(safe_edge_server_common) +target_include_directories( + safe_edge_server_common + PUBLIC + "${SAFE_EDGE_IDL_INCLUDE_DIR}" + "${SAFE_EDGE_SERVER_COMMON_DIR}/include" +) +target_link_libraries( + safe_edge_server_common + PUBLIC + fastdds + CURL::libcurl +) + +add_executable( + safe_edge_server + src/apps/server_main.cpp + src/nodes/ServerNode.cpp +) +safe_edge_apply_common_build_settings(safe_edge_server) +target_include_directories( + safe_edge_server + PRIVATE + "${SAFE_EDGE_IDL_INCLUDE_DIR}" +) +target_link_libraries( + safe_edge_server + PRIVATE + safe_edge_server_common + fastdds + ${SAFE_EDGE_PLATFORM_SOCKET_LIB} +) + +install( + TARGETS + safe_edge_server + RUNTIME DESTINATION bin +) + +option(SAFE_EDGE_BUILD_TESTS "Build integration tests" ON) + +if(SAFE_EDGE_BUILD_TESTS) + # Try system GTest first; fall back to fetching from source. + find_package(GTest QUIET) + + if(NOT GTest_FOUND) + message(STATUS "GTest not found — fetching from source") + include(FetchContent) + FetchContent_Declare( + googletest + URL https://github.com/google/googletest/archive/refs/tags/v1.14.0.tar.gz + URL_HASH SHA256=8ad598c73ad796e0d8280b082cebd82a630d73e73cd3c70057938a6501bba5d7 + DOWNLOAD_EXTRACT_TIMESTAMP TRUE + ) + set(INSTALL_GTEST OFF CACHE BOOL "" FORCE) + FetchContent_MakeAvailable(googletest) + + if(NOT TARGET GTest::gtest) + add_library(GTest::gtest ALIAS gtest) + endif() + endif() + + add_executable( + test_server_integration + test/test_server_integration.cpp + ) + + # Tests need exceptions and RTTI (GTest requirement). + # Do not reuse safe_edge_apply_common_build_settings which disables them. + target_include_directories( + test_server_integration + PRIVATE + "${SAFE_EDGE_SERVER_INCLUDE_DIR}" + "${SAFE_EDGE_IDL_INCLUDE_DIR}" + ) + target_compile_options( + test_server_integration + PRIVATE + -Wall -Wextra -Wpedantic + ) + target_link_libraries( + test_server_integration + PRIVATE + safe_edge_server_common + fastdds + ${SAFE_EDGE_PLATFORM_SOCKET_LIB} + GTest::gtest + ) + + enable_testing() + add_test(NAME server_integration COMMAND test_server_integration) + + install( + TARGETS test_server_integration + RUNTIME DESTINATION bin + ) +endif() diff --git a/fast_dds/server/include/safe_edge/server/common/PilotServerPublishHelper.hpp b/fast_dds/server/include/safe_edge/server/common/PilotServerPublishHelper.hpp new file mode 100644 index 0000000..a653bca --- /dev/null +++ b/fast_dds/server/include/safe_edge/server/common/PilotServerPublishHelper.hpp @@ -0,0 +1,25 @@ +#ifndef SAFE_EDGE_SERVER_COMMON_PILOTSERVERPUBLISHHELPER_HPP +#define SAFE_EDGE_SERVER_COMMON_PILOTSERVERPUBLISHHELPER_HPP + +#include + +#include + +#include + +namespace safe_edge { +namespace server { +namespace common { + +struct PilotServerPublishHelper +{ + static void publish_charger_locations( + eprosima::fastdds::dds::DataWriter& writer, + const std::vector& parsed); +}; + +} // namespace common +} // namespace server +} // namespace safe_edge + +#endif // SAFE_EDGE_SERVER_COMMON_PILOTSERVERPUBLISHHELPER_HPP diff --git a/fast_dds/server/include/safe_edge/server/common/RuntimeConfig.hpp b/fast_dds/server/include/safe_edge/server/common/RuntimeConfig.hpp new file mode 100644 index 0000000..c7577c4 --- /dev/null +++ b/fast_dds/server/include/safe_edge/server/common/RuntimeConfig.hpp @@ -0,0 +1,32 @@ +#ifndef SAFE_EDGE_SERVER_COMMON_RUNTIMECONFIG_HPP +#define SAFE_EDGE_SERVER_COMMON_RUNTIMECONFIG_HPP + +#include +#include + +namespace safe_edge { +namespace server { +namespace common { + +struct RuntimeConfig +{ + std::string participant_name; + uint32_t domain_id = 0U; + uint16_t participant_port = 0U; + + std::string pilot_server_base_url; + std::string pilot_server_api_key; + std::string charger_locations_endpoint; + std::string charger_types_endpoint; + std::string charging_sessions_endpoint; + std::string transit_health_endpoint; + std::string transit_metrics_endpoint; +}; + +RuntimeConfig make_server_runtime_config(); + +} // namespace common +} // namespace server +} // namespace safe_edge + +#endif // SAFE_EDGE_SERVER_COMMON_RUNTIMECONFIG_HPP diff --git a/fast_dds/server/include/safe_edge/server/common/TopicNames.hpp b/fast_dds/server/include/safe_edge/server/common/TopicNames.hpp new file mode 100644 index 0000000..6838cf5 --- /dev/null +++ b/fast_dds/server/include/safe_edge/server/common/TopicNames.hpp @@ -0,0 +1,18 @@ +#ifndef SAFE_EDGE_SERVER_COMMON_TOPICNAMES_HPP +#define SAFE_EDGE_SERVER_COMMON_TOPICNAMES_HPP + +namespace safe_edge { +namespace server { +namespace common { +namespace topic_names { + +const char* charger_locations() noexcept; +const char* server_query() noexcept; +const char* service_heartbeat() noexcept; + +} // namespace topic_names +} // namespace common +} // namespace server +} // namespace safe_edge + +#endif // SAFE_EDGE_SERVER_COMMON_TOPICNAMES_HPP diff --git a/fast_dds/server/include/safe_edge/server/nodes/ServerNode.hpp b/fast_dds/server/include/safe_edge/server/nodes/ServerNode.hpp new file mode 100644 index 0000000..8a0810f --- /dev/null +++ b/fast_dds/server/include/safe_edge/server/nodes/ServerNode.hpp @@ -0,0 +1,130 @@ +#ifndef SAFE_EDGE_SERVER_NODES_SERVERNODE_HPP +#define SAFE_EDGE_SERVER_NODES_SERVERNODE_HPP + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace safe_edge { +namespace server { +namespace nodes { + +class ServerNode +{ +public: + + explicit ServerNode(const common::RuntimeConfig& runtime_config); + + int run(); + +private: + + class ParticipantListener : + public eprosima::fastdds::dds::DomainParticipantListener + { + public: + + explicit ParticipantListener(ServerNode& owner); + + void on_subscription_matched( + eprosima::fastdds::dds::DataReader* reader, + const eprosima::fastdds::dds::SubscriptionMatchedStatus& info) noexcept override; + + void on_publication_matched( + eprosima::fastdds::dds::DataWriter* writer, + const eprosima::fastdds::dds::PublicationMatchedStatus& info) noexcept override; + + private: + + ServerNode& owner_; + }; + + class ServerQueryListener : + public eprosima::fastdds::dds::DataReaderListener + { + public: + + explicit ServerQueryListener(ServerNode& owner); + + void on_data_available( + eprosima::fastdds::dds::DataReader* reader) noexcept override; + + private: + + ServerNode& owner_; + }; + + bool initialize(); + bool create_participant(); + bool register_types(); + bool create_topics(); + bool create_endpoints(); + bool enable_entities(); + + void on_server_query_received(const safe_edge::pilot_server::ServerQuery& query); + void publish_heartbeat(); + + void request_pilot_server_data(safe_edge::pilot_server::RequestedDataType resource) noexcept; + void periodic_refresh_all_resources() noexcept; + const char* resolve_endpoint(safe_edge::pilot_server::RequestedDataType resource) const noexcept; + void log_uptime() const noexcept; + + void log_subscription_match(const char* topic_name, int32_t total_count) const; + void log_publication_match(const char* topic_name, int32_t total_count) const; + + common::RuntimeConfig runtime_config_; + common::PilotServerClient pilot_client_; + + ParticipantListener participant_listener_; + ServerQueryListener server_query_listener_; + + std::chrono::steady_clock::time_point next_heartbeat_fire_; + std::chrono::steady_clock::time_point next_refresh_fire_; + std::chrono::steady_clock::time_point next_uptime_fire_; + std::chrono::steady_clock::time_point start_time_; + + eprosima::fastdds::dds::DomainParticipant* participant_ = nullptr; + eprosima::fastdds::dds::Publisher* publisher_ = nullptr; + eprosima::fastdds::dds::Subscriber* subscriber_ = nullptr; + + eprosima::fastdds::dds::Topic* charger_locations_topic_ = nullptr; + eprosima::fastdds::dds::Topic* server_query_topic_ = nullptr; + eprosima::fastdds::dds::Topic* service_heartbeat_topic_ = nullptr; + + std::string charger_locations_topic_name_; + std::string server_query_topic_name_; + std::string service_heartbeat_topic_name_; + + eprosima::fastdds::dds::DataWriter* charger_locations_datawriter_ = nullptr; + eprosima::fastdds::dds::DataWriter* service_heartbeat_datawriter_ = nullptr; + eprosima::fastdds::dds::DataReader* server_query_datareader_ = nullptr; + + eprosima::fastdds::dds::TypeSupport charger_location_type_support_; + eprosima::fastdds::dds::TypeSupport server_query_type_support_; + eprosima::fastdds::dds::TypeSupport service_heartbeat_type_support_; +}; + +} // namespace nodes +} // namespace server +} // namespace safe_edge + +#endif // SAFE_EDGE_SERVER_NODES_SERVERNODE_HPP diff --git a/fast_dds/server/src/apps/server_main.cpp b/fast_dds/server/src/apps/server_main.cpp new file mode 100644 index 0000000..b8fa6db --- /dev/null +++ b/fast_dds/server/src/apps/server_main.cpp @@ -0,0 +1,11 @@ +#include +#include + +int main() +{ + const safe_edge::server::common::RuntimeConfig config = + safe_edge::server::common::make_server_runtime_config(); + + safe_edge::server::nodes::ServerNode node(config); + return node.run(); +} diff --git a/fast_dds/server/src/common/PilotServerPublishHelper.cpp b/fast_dds/server/src/common/PilotServerPublishHelper.cpp new file mode 100644 index 0000000..b35c207 --- /dev/null +++ b/fast_dds/server/src/common/PilotServerPublishHelper.cpp @@ -0,0 +1,39 @@ +#include + +#include +#include + +#include + +#include + +namespace safe_edge { +namespace server { +namespace common { + +void PilotServerPublishHelper::publish_charger_locations( + eprosima::fastdds::dds::DataWriter& writer, + const std::vector& parsed) +{ + for (const auto& p : parsed) + { + safe_edge::pilot_server::ChargerLocation loc; + loc.id(p.id); + loc.name(p.name); + safe_edge::common::GeoPoint pos; + pos.latitude(p.latitude); + pos.longitude(p.longitude); + loc.position(pos); + + if (eprosima::fastdds::dds::RETCODE_OK != + writer.write(&loc, eprosima::fastdds::dds::HANDLE_NIL)) + { + std::cerr << "[publish_helper] Failed to write ChargerLocation id=" + << p.id << std::endl; + } + } +} + +} // namespace common +} // namespace server +} // namespace safe_edge diff --git a/fast_dds/server/src/common/RuntimeConfig.cpp b/fast_dds/server/src/common/RuntimeConfig.cpp new file mode 100644 index 0000000..0034c96 --- /dev/null +++ b/fast_dds/server/src/common/RuntimeConfig.cpp @@ -0,0 +1,27 @@ +#include + +namespace safe_edge { +namespace server { +namespace common { + +RuntimeConfig make_server_runtime_config() +{ + RuntimeConfig config; + config.participant_name = "SafeEdgeServerParticipant"; + config.domain_id = 0U; + config.participant_port = 8020U; + + config.pilot_server_base_url = "https://pilot2.dumitru-alexandru.work"; + // api_key moved to /etc/safe-edge/server.ini — do not hardcode here + config.charger_locations_endpoint = "/api/chargers/locations"; + config.charger_types_endpoint = "/api/chargers/types"; + config.charging_sessions_endpoint = "/api/chargers/sessions"; + config.transit_health_endpoint = "/api/transit/health"; + config.transit_metrics_endpoint = "/api/transit/metrics"; + + return config; +} + +} // namespace common +} // namespace server +} // namespace safe_edge diff --git a/fast_dds/server/src/common/TopicNames.cpp b/fast_dds/server/src/common/TopicNames.cpp new file mode 100644 index 0000000..2c20bea --- /dev/null +++ b/fast_dds/server/src/common/TopicNames.cpp @@ -0,0 +1,26 @@ +#include + +namespace safe_edge { +namespace server { +namespace common { +namespace topic_names { + +const char* charger_locations() noexcept +{ + return "safe_edge.pilot_server.charger_locations"; +} + +const char* server_query() noexcept +{ + return "safe_edge.pilot_server.server_query"; +} + +const char* service_heartbeat() noexcept +{ + return "safe_edge.common.service_heartbeat"; +} + +} // namespace topic_names +} // namespace common +} // namespace server +} // namespace safe_edge diff --git a/fast_dds/server/src/nodes/ServerNode.cpp b/fast_dds/server/src/nodes/ServerNode.cpp new file mode 100644 index 0000000..81c4ec7 --- /dev/null +++ b/fast_dds/server/src/nodes/ServerNode.cpp @@ -0,0 +1,483 @@ +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace safe_edge { +namespace server { +namespace nodes { + +namespace { + +static std::vector build_charger_locations() +{ + std::vector locations; + + safe_edge::pilot_server::ChargerLocation loc1; + loc1.id(1); + loc1.name("Madrid North Hub"); + safe_edge::common::GeoPoint pos1; + pos1.latitude(40.4637F); + pos1.longitude(-3.7492F); + loc1.position(pos1); + locations.push_back(loc1); + + safe_edge::pilot_server::ChargerLocation loc2; + loc2.id(2); + loc2.name("Barcelona Port Station"); + safe_edge::common::GeoPoint pos2; + pos2.latitude(41.3851F); + pos2.longitude(2.1734F); + loc2.position(pos2); + locations.push_back(loc2); + + safe_edge::pilot_server::ChargerLocation loc3; + loc3.id(3); + loc3.name("Valencia Depot"); + safe_edge::common::GeoPoint pos3; + pos3.latitude(39.4699F); + pos3.longitude(-0.3763F); + loc3.position(pos3); + locations.push_back(loc3); + + return locations; +} + +} // namespace + +ServerNode::ParticipantListener::ParticipantListener( + ServerNode& owner) + : owner_(owner) +{ +} + +void ServerNode::ParticipantListener::on_subscription_matched( + eprosima::fastdds::dds::DataReader* reader, + const eprosima::fastdds::dds::SubscriptionMatchedStatus& info) noexcept +{ + owner_.log_subscription_match( + reader->get_topicdescription()->get_name().c_str(), info.total_count); +} + +void ServerNode::ParticipantListener::on_publication_matched( + eprosima::fastdds::dds::DataWriter* writer, + const eprosima::fastdds::dds::PublicationMatchedStatus& info) noexcept +{ + owner_.log_publication_match( + writer->get_topic()->get_name().c_str(), info.total_count); + + if (writer == owner_.charger_locations_datawriter_ && info.total_count_change > 0) + { + owner_.request_pilot_server_data( + safe_edge::pilot_server::RequestedDataType::CHARGER_LOCATION); + } +} + +ServerNode::ServerQueryListener::ServerQueryListener( + ServerNode& owner) + : owner_(owner) +{ +} + +void ServerNode::ServerQueryListener::on_data_available( + eprosima::fastdds::dds::DataReader* reader) noexcept +{ + safe_edge::pilot_server::ServerQuery sample{}; + eprosima::fastdds::dds::SampleInfo info{}; + while (reader->take_next_sample(&sample, &info) == eprosima::fastdds::dds::RETCODE_OK) + { + if (info.valid_data) + { + owner_.on_server_query_received(sample); + } + } +} + +ServerNode::ServerNode( + const common::RuntimeConfig& runtime_config) + : runtime_config_(runtime_config) + , pilot_client_(runtime_config.pilot_server_base_url, "/etc/safe-edge/server.ini") + , participant_listener_(*this) + , server_query_listener_(*this) + , next_heartbeat_fire_(std::chrono::steady_clock::now() + std::chrono::seconds(5)) + , next_refresh_fire_(std::chrono::steady_clock::now() + std::chrono::seconds(30)) + , next_uptime_fire_(std::chrono::steady_clock::now() + std::chrono::seconds(300)) + , start_time_(std::chrono::steady_clock::now()) + , charger_location_type_support_(new safe_edge::pilot_server::ChargerLocationPubSubType()) + , server_query_type_support_(new safe_edge::pilot_server::ServerQueryPubSubType()) + , service_heartbeat_type_support_(new safe_edge::common::ServiceHeartbeatPubSubType()) +{ +} + +int ServerNode::run() +{ + if (!initialize()) + { + return 1; + } + + std::cout << "[server] [START] Running with participant port " + << runtime_config_.participant_port << std::endl; + std::cout << "[server] PilotServer base_url=" << runtime_config_.pilot_server_base_url + << " api_key=***" << std::endl; + + while (true) + { + const auto next = std::min({next_heartbeat_fire_, next_refresh_fire_, next_uptime_fire_}); + std::this_thread::sleep_until(next); + + const auto now = std::chrono::steady_clock::now(); + + if (now >= next_heartbeat_fire_) + { + publish_heartbeat(); + next_heartbeat_fire_ += std::chrono::seconds(5); + } + if (now >= next_refresh_fire_) + { + periodic_refresh_all_resources(); + next_refresh_fire_ += std::chrono::seconds(30); + } + if (now >= next_uptime_fire_) + { + log_uptime(); + next_uptime_fire_ += std::chrono::seconds(300); + } + } + + return 0; +} + +bool ServerNode::initialize() +{ + return create_participant() && + register_types() && + create_topics() && + create_endpoints() && + enable_entities(); +} + +bool ServerNode::create_participant() +{ + eprosima::fastdds::dds::DomainParticipantQos participant_qos{}; + participant_qos.name(runtime_config_.participant_name); + + eprosima::fastdds::rtps::Locator_t announced_locator; + eprosima::fastdds::rtps::IPLocator::setIPv4(announced_locator, "127.0.0.1"); + announced_locator.port = runtime_config_.participant_port; + participant_qos.wire_protocol().builtin.metatrafficUnicastLocatorList.push_back(announced_locator); + + static constexpr uint16_t peer_ports[] = { 8011U, 8030U }; + for (uint16_t port : peer_ports) + { + eprosima::fastdds::rtps::Locator_t peer; + eprosima::fastdds::rtps::IPLocator::setIPv4(peer, "127.0.0.1"); + peer.port = port; + participant_qos.wire_protocol().builtin.initialPeersList.push_back(peer); + } + + eprosima::fastdds::dds::StatusMask participant_mask = + eprosima::fastdds::dds::StatusMask::publication_matched(); + participant_mask |= eprosima::fastdds::dds::StatusMask::subscription_matched(); + + participant_ = eprosima::fastdds::dds::DomainParticipantFactory::get_instance() + ->create_participant(runtime_config_.domain_id, participant_qos, + &participant_listener_, participant_mask); + + if (nullptr == participant_) + { + std::cerr << "[server] Failed to create participant" << std::endl; + return false; + } + + return true; +} + +bool ServerNode::register_types() +{ + if (eprosima::fastdds::dds::RETCODE_OK != charger_location_type_support_.register_type(participant_)) + { + std::cerr << "[server] Failed to register type: ChargerLocation" << std::endl; + return false; + } + if (eprosima::fastdds::dds::RETCODE_OK != server_query_type_support_.register_type(participant_)) + { + std::cerr << "[server] Failed to register type: ServerQuery" << std::endl; + return false; + } + if (eprosima::fastdds::dds::RETCODE_OK != service_heartbeat_type_support_.register_type(participant_)) + { + std::cerr << "[server] Failed to register type: ServiceHeartbeat" << std::endl; + return false; + } + return true; +} + +bool ServerNode::create_topics() +{ + charger_locations_topic_name_ = common::topic_names::charger_locations(); + charger_locations_topic_ = participant_->create_topic( + charger_locations_topic_name_, + charger_location_type_support_.get_type_name(), + eprosima::fastdds::dds::TOPIC_QOS_DEFAULT); + if (nullptr == charger_locations_topic_) + { + std::cerr << "[server] Failed to create topic: charger_locations" << std::endl; + return false; + } + + server_query_topic_name_ = common::topic_names::server_query(); + server_query_topic_ = participant_->create_topic( + server_query_topic_name_, + server_query_type_support_.get_type_name(), + eprosima::fastdds::dds::TOPIC_QOS_DEFAULT); + if (nullptr == server_query_topic_) + { + std::cerr << "[server] Failed to create topic: server_query" << std::endl; + return false; + } + + service_heartbeat_topic_name_ = common::topic_names::service_heartbeat(); + service_heartbeat_topic_ = participant_->create_topic( + service_heartbeat_topic_name_, + service_heartbeat_type_support_.get_type_name(), + eprosima::fastdds::dds::TOPIC_QOS_DEFAULT); + if (nullptr == service_heartbeat_topic_) + { + std::cerr << "[server] Failed to create topic: service_heartbeat" << std::endl; + return false; + } + + return true; +} + +bool ServerNode::create_endpoints() +{ + publisher_ = participant_->create_publisher( + eprosima::fastdds::dds::PUBLISHER_QOS_DEFAULT, + nullptr, + eprosima::fastdds::dds::StatusMask::none()); + + subscriber_ = participant_->create_subscriber( + eprosima::fastdds::dds::SUBSCRIBER_QOS_DEFAULT, + nullptr, + eprosima::fastdds::dds::StatusMask::none()); + + if (nullptr == publisher_ || nullptr == subscriber_) + { + std::cerr << "[server] Failed to create publisher or subscriber" << std::endl; + return false; + } + + eprosima::fastdds::dds::DataWriterQos writer_qos = eprosima::fastdds::dds::DATAWRITER_QOS_DEFAULT; + writer_qos.reliability().kind = eprosima::fastdds::dds::RELIABLE_RELIABILITY_QOS; + + charger_locations_datawriter_ = publisher_->create_datawriter( + charger_locations_topic_, writer_qos, nullptr, + eprosima::fastdds::dds::StatusMask::none()); + + service_heartbeat_datawriter_ = publisher_->create_datawriter( + service_heartbeat_topic_, writer_qos, nullptr, + eprosima::fastdds::dds::StatusMask::none()); + + eprosima::fastdds::dds::DataReaderQos reader_qos = eprosima::fastdds::dds::DATAREADER_QOS_DEFAULT; + reader_qos.reliability().kind = eprosima::fastdds::dds::RELIABLE_RELIABILITY_QOS; + + server_query_datareader_ = subscriber_->create_datareader( + server_query_topic_, reader_qos, + &server_query_listener_, + eprosima::fastdds::dds::StatusMask::data_available()); + + if (nullptr == charger_locations_datawriter_ || + nullptr == service_heartbeat_datawriter_ || + nullptr == server_query_datareader_) + { + std::cerr << "[server] Failed to create endpoints" << std::endl; + return false; + } + + return true; +} + +bool ServerNode::enable_entities() +{ + bool enabled = true; + enabled = enabled && (eprosima::fastdds::dds::RETCODE_OK == publisher_->enable()); + enabled = enabled && (eprosima::fastdds::dds::RETCODE_OK == charger_locations_datawriter_->enable()); + enabled = enabled && (eprosima::fastdds::dds::RETCODE_OK == service_heartbeat_datawriter_->enable()); + enabled = enabled && (eprosima::fastdds::dds::RETCODE_OK == subscriber_->enable()); + enabled = enabled && (eprosima::fastdds::dds::RETCODE_OK == server_query_datareader_->enable()); + enabled = enabled && (eprosima::fastdds::dds::RETCODE_OK == participant_->enable()); + + if (!enabled) + { + std::cerr << "[server] Failed to enable DDS entities" << std::endl; + } + + return enabled; +} + +void ServerNode::on_server_query_received( + const safe_edge::pilot_server::ServerQuery& query) +{ + std::cout << "[server] DDS query from=" << query.requested_by() + << " type=" << static_cast(query.requested_data_type()) << std::endl; + request_pilot_server_data(query.requested_data_type()); +} + +void ServerNode::log_subscription_match( + const char* topic_name, + int32_t total_count) const +{ + std::cout << "[server] Subscription matched on " << topic_name + << " total_count=" << total_count << std::endl; +} + +void ServerNode::log_publication_match( + const char* topic_name, + int32_t total_count) const +{ + std::cout << "[server] Publication matched on " << topic_name + << " total_count=" << total_count << std::endl; +} + +const char* ServerNode::resolve_endpoint( + safe_edge::pilot_server::RequestedDataType resource) const noexcept +{ + switch (resource) + { + case safe_edge::pilot_server::RequestedDataType::CHARGER_LOCATION: + return runtime_config_.charger_locations_endpoint.c_str(); + case safe_edge::pilot_server::RequestedDataType::CHARGER_TYPE: + return runtime_config_.charger_types_endpoint.c_str(); + case safe_edge::pilot_server::RequestedDataType::CHARGING_SESSION: + return runtime_config_.charging_sessions_endpoint.c_str(); + case safe_edge::pilot_server::RequestedDataType::TRANSIT_HEALTH: + return runtime_config_.transit_health_endpoint.c_str(); + case safe_edge::pilot_server::RequestedDataType::TRANSIT_METRICS: + return runtime_config_.transit_metrics_endpoint.c_str(); + default: + return nullptr; + } +} + +void ServerNode::request_pilot_server_data( + safe_edge::pilot_server::RequestedDataType resource) noexcept +{ + const char* endpoint = resolve_endpoint(resource); + if (nullptr == endpoint) + { + std::cerr << "[server] Unsupported resource=" << static_cast(resource) << std::endl; + return; + } + + std::cout << "[server] Request resource=" << static_cast(resource) + << " endpoint=" << endpoint << std::endl; + + const std::string body = pilot_client_.fetch(endpoint); + if (body.empty()) + { + std::cerr << "[server] HTTP fetch failed endpoint=" << endpoint << std::endl; + } + else if (resource == safe_edge::pilot_server::RequestedDataType::CHARGER_LOCATION + && nullptr != charger_locations_datawriter_) + { + const auto parsed = + safe_edge::server::common::PilotServerPayloadParser::parse_charger_locations(body); + safe_edge::server::common::PilotServerPublishHelper::publish_charger_locations( + *charger_locations_datawriter_, parsed); + std::cout << "[server] Published charger_locations count=" << parsed.size() + << " (from HTTP)" << std::endl; + } + else if (!body.empty()) + { + // TODO: add writers and parsers for other resource types + std::cout << "[server] HTTP response received resource=" + << static_cast(resource) + << " bytes=" << body.size() + << " (parse not yet implemented)" << std::endl; + } + + // Stub: preserve charger_locations publication until HTTP response is confirmed correct + if (resource == safe_edge::pilot_server::RequestedDataType::CHARGER_LOCATION + && nullptr != charger_locations_datawriter_) + { + const auto locations = build_charger_locations(); + for (const auto& loc : locations) + { + charger_locations_datawriter_->write( + const_cast(&loc), + eprosima::fastdds::dds::HANDLE_NIL); + } + std::cout << "[server] Published charger_locations count=" << locations.size() + << " (stub)" << std::endl; + } +} + +void ServerNode::periodic_refresh_all_resources() noexcept +{ + static constexpr safe_edge::pilot_server::RequestedDataType all_resources[] = { + safe_edge::pilot_server::RequestedDataType::CHARGER_LOCATION, + safe_edge::pilot_server::RequestedDataType::CHARGER_TYPE, + safe_edge::pilot_server::RequestedDataType::CHARGING_SESSION, + safe_edge::pilot_server::RequestedDataType::TRANSIT_HEALTH, + safe_edge::pilot_server::RequestedDataType::TRANSIT_METRICS, + }; + + for (const auto resource : all_resources) + { + std::cout << "[server] Periodic refresh resource=" << static_cast(resource) << std::endl; + request_pilot_server_data(resource); + } +} + +void ServerNode::log_uptime() const noexcept +{ + const auto elapsed = std::chrono::steady_clock::now() - start_time_; + const auto seconds = std::chrono::duration_cast(elapsed).count(); + std::cout << "[server] Uptime=" << seconds << "s" << std::endl; +} + +void ServerNode::publish_heartbeat() +{ + safe_edge::common::ServiceHeartbeat heartbeat{}; + safe_edge::common::Header hdr; + hdr.source("server"); + heartbeat.header_st(hdr); + heartbeat.service_name("server"); + heartbeat.status(safe_edge::common::HealthStatus::HEALTH_OK); + heartbeat.detail("running"); + + if (eprosima::fastdds::dds::RETCODE_OK != + service_heartbeat_datawriter_->write(&heartbeat, eprosima::fastdds::dds::HANDLE_NIL)) + { + std::cerr << "[server] Failed to publish ServiceHeartbeat" << std::endl; + return; + } + + std::cout << "[server] Published ServiceHeartbeat" << std::endl; +} + +} // namespace nodes +} // namespace server +} // namespace safe_edge diff --git a/fast_dds/server/test/test_server_integration.cpp b/fast_dds/server/test/test_server_integration.cpp new file mode 100644 index 0000000..efd54d8 --- /dev/null +++ b/fast_dds/server/test/test_server_integration.cpp @@ -0,0 +1,315 @@ +// test_server_integration.cpp +// +// Single binary integration test for safe_edge_server (Fast DDS variant). +// Starts the server as a subprocess, runs all test suites, stops the server. +// +// Usage: +// ./test_server_integration +// ./test_server_integration --gtest_output=xml:results.xml (CI / JUnit) +// +// Environment variables: +// SAFE_EDGE_FAST_SERVER_BIN path to safe_edge_server binary (default: safe_edge_server) + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +// --------------------------------------------------------------------------- +// Helper: create a participant peered with the server at 8020 +// --------------------------------------------------------------------------- + +static eprosima::fastdds::dds::DomainParticipant* make_participant( + const char* name, + uint16_t port) +{ + eprosima::fastdds::dds::DomainParticipantQos qos{}; + qos.name(name); + + eprosima::fastdds::rtps::Locator_t announced; + eprosima::fastdds::rtps::IPLocator::setIPv4(announced, "127.0.0.1"); + announced.port = port; + qos.wire_protocol().builtin.metatrafficUnicastLocatorList.push_back(announced); + + eprosima::fastdds::rtps::Locator_t peer; + eprosima::fastdds::rtps::IPLocator::setIPv4(peer, "127.0.0.1"); + peer.port = 8020U; + qos.wire_protocol().builtin.initialPeersList.push_back(peer); + + return eprosima::fastdds::dds::DomainParticipantFactory::get_instance() + ->create_participant(0U, qos, nullptr, + eprosima::fastdds::dds::StatusMask::none()); +} + +// --------------------------------------------------------------------------- +// Helper: poll DataReader until a valid ChargerLocation sample arrives +// --------------------------------------------------------------------------- + +static bool wait_for_charger_location( + eprosima::fastdds::dds::DataReader* reader, + int timeout_s) +{ + const auto deadline = + std::chrono::steady_clock::now() + std::chrono::seconds(timeout_s); + + while (std::chrono::steady_clock::now() < deadline) + { + safe_edge::pilot_server::ChargerLocation sample{}; + eprosima::fastdds::dds::SampleInfo info{}; + if (reader->take_next_sample(&sample, &info) == + eprosima::fastdds::dds::RETCODE_OK && info.valid_data) + { + std::cout << " [dds] Received ChargerLocation id=" << sample.id() + << " name=" << sample.name() << "\n"; + return true; + } + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + return false; +} + +// --------------------------------------------------------------------------- +// Global environment: lifecycle of safe_edge_server subprocess +// --------------------------------------------------------------------------- + +class ServerEnvironment : public ::testing::Environment +{ +public: + void SetUp() override + { + const char* bin = std::getenv("SAFE_EDGE_FAST_SERVER_BIN"); + const std::string cmd = + std::string(bin != nullptr ? bin : "safe_edge_server") + " &"; + ASSERT_EQ(0, std::system(cmd.c_str())) + << "Failed to launch safe_edge_server. " + "Set SAFE_EDGE_FAST_SERVER_BIN to the full path if needed."; + + std::cout << "[env] safe_edge_server started — waiting 5 s for init...\n"; + std::this_thread::sleep_for(std::chrono::seconds(5)); + std::cout << "[env] Server ready.\n"; + } + + void TearDown() override + { + std::cout << "[env] Stopping safe_edge_server...\n"; + std::system("pkill -f safe_edge_server 2>/dev/null || true"); + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + } +}; + +// --------------------------------------------------------------------------- +// Suite 1: QueryDispatch +// Verifies that for each RequestedDataType the server dispatches correctly. +// --------------------------------------------------------------------------- + +class QueryDispatchTest : public ::testing::Test +{ +protected: + void SetUp() override + { + participant_ = make_participant("TestQueryDispatch", 8040U); + ASSERT_NE(nullptr, participant_); + + eprosima::fastdds::dds::TypeSupport charger_ts( + new safe_edge::pilot_server::ChargerLocationPubSubType()); + eprosima::fastdds::dds::TypeSupport query_ts( + new safe_edge::pilot_server::ServerQueryPubSubType()); + + ASSERT_EQ(eprosima::fastdds::dds::RETCODE_OK, + charger_ts.register_type(participant_)); + ASSERT_EQ(eprosima::fastdds::dds::RETCODE_OK, + query_ts.register_type(participant_)); + + charger_topic_ = participant_->create_topic( + safe_edge::server::common::topic_names::charger_locations(), + charger_ts.get_type_name(), + eprosima::fastdds::dds::TOPIC_QOS_DEFAULT); + query_topic_ = participant_->create_topic( + safe_edge::server::common::topic_names::server_query(), + query_ts.get_type_name(), + eprosima::fastdds::dds::TOPIC_QOS_DEFAULT); + ASSERT_NE(nullptr, charger_topic_); + ASSERT_NE(nullptr, query_topic_); + + publisher_ = participant_->create_publisher( + eprosima::fastdds::dds::PUBLISHER_QOS_DEFAULT, nullptr, + eprosima::fastdds::dds::StatusMask::none()); + subscriber_ = participant_->create_subscriber( + eprosima::fastdds::dds::SUBSCRIBER_QOS_DEFAULT, nullptr, + eprosima::fastdds::dds::StatusMask::none()); + ASSERT_NE(nullptr, publisher_); + ASSERT_NE(nullptr, subscriber_); + + eprosima::fastdds::dds::DataWriterQos wqos = eprosima::fastdds::dds::DATAWRITER_QOS_DEFAULT; + wqos.reliability().kind = eprosima::fastdds::dds::RELIABLE_RELIABILITY_QOS; + eprosima::fastdds::dds::DataReaderQos rqos = eprosima::fastdds::dds::DATAREADER_QOS_DEFAULT; + rqos.reliability().kind = eprosima::fastdds::dds::RELIABLE_RELIABILITY_QOS; + + query_writer_ = publisher_->create_datawriter( + query_topic_, wqos, nullptr, + eprosima::fastdds::dds::StatusMask::none()); + charger_reader_ = subscriber_->create_datareader( + charger_topic_, rqos, nullptr, + eprosima::fastdds::dds::StatusMask::none()); + ASSERT_NE(nullptr, query_writer_); + ASSERT_NE(nullptr, charger_reader_); + + std::this_thread::sleep_for(std::chrono::seconds(3)); // discovery + } + + void send_query(safe_edge::pilot_server::RequestedDataType type) + { + safe_edge::pilot_server::ServerQuery q{}; + q.requested_by("test_query_dispatch"); + q.requested_data_type(type); + EXPECT_EQ(eprosima::fastdds::dds::RETCODE_OK, + query_writer_->write(&q, eprosima::fastdds::dds::HANDLE_NIL)); + } + + eprosima::fastdds::dds::DomainParticipant* participant_ = nullptr; + eprosima::fastdds::dds::Publisher* publisher_ = nullptr; + eprosima::fastdds::dds::Subscriber* subscriber_ = nullptr; + eprosima::fastdds::dds::Topic* charger_topic_ = nullptr; + eprosima::fastdds::dds::Topic* query_topic_ = nullptr; + eprosima::fastdds::dds::DataWriter* query_writer_ = nullptr; + eprosima::fastdds::dds::DataReader* charger_reader_= nullptr; +}; + +TEST_F(QueryDispatchTest, ChargerLocationReturnsData) +{ + send_query(safe_edge::pilot_server::RequestedDataType::CHARGER_LOCATION); + EXPECT_TRUE(wait_for_charger_location(charger_reader_, 5)) + << "No ChargerLocation received within 5 s"; +} + +TEST_F(QueryDispatchTest, ChargerTypeHandledWithoutCrash) +{ + send_query(safe_edge::pilot_server::RequestedDataType::CHARGER_TYPE); + std::this_thread::sleep_for(std::chrono::milliseconds(500)); +} + +TEST_F(QueryDispatchTest, ChargingSessionHandledWithoutCrash) +{ + send_query(safe_edge::pilot_server::RequestedDataType::CHARGING_SESSION); + std::this_thread::sleep_for(std::chrono::milliseconds(500)); +} + +TEST_F(QueryDispatchTest, TransitHealthHandledWithoutCrash) +{ + send_query(safe_edge::pilot_server::RequestedDataType::TRANSIT_HEALTH); + std::this_thread::sleep_for(std::chrono::milliseconds(500)); +} + +TEST_F(QueryDispatchTest, TransitMetricsHandledWithoutCrash) +{ + send_query(safe_edge::pilot_server::RequestedDataType::TRANSIT_METRICS); + std::this_thread::sleep_for(std::chrono::milliseconds(500)); +} + +// --------------------------------------------------------------------------- +// Suite 2: PeriodicRefresh +// Verifies the 30-second timer fires without any explicit query. +// --------------------------------------------------------------------------- + +TEST(PeriodicRefresh, TwoBurstsIn35Seconds) +{ + auto* participant = make_participant("TestPeriodicRefresh", 8041U); + ASSERT_NE(nullptr, participant); + + eprosima::fastdds::dds::TypeSupport charger_ts( + new safe_edge::pilot_server::ChargerLocationPubSubType()); + ASSERT_EQ(eprosima::fastdds::dds::RETCODE_OK, + charger_ts.register_type(participant)); + + auto* topic = participant->create_topic( + safe_edge::server::common::topic_names::charger_locations(), + charger_ts.get_type_name(), + eprosima::fastdds::dds::TOPIC_QOS_DEFAULT); + ASSERT_NE(nullptr, topic); + + auto* sub = participant->create_subscriber( + eprosima::fastdds::dds::SUBSCRIBER_QOS_DEFAULT, nullptr, + eprosima::fastdds::dds::StatusMask::none()); + ASSERT_NE(nullptr, sub); + + eprosima::fastdds::dds::DataReaderQos rqos = eprosima::fastdds::dds::DATAREADER_QOS_DEFAULT; + rqos.reliability().kind = eprosima::fastdds::dds::RELIABLE_RELIABILITY_QOS; + + auto* reader = sub->create_datareader( + topic, rqos, nullptr, + eprosima::fastdds::dds::StatusMask::none()); + ASSERT_NE(nullptr, reader); + + std::this_thread::sleep_for(std::chrono::seconds(3)); // discovery + + int burst_count = 0; + const auto t0 = std::chrono::steady_clock::now(); + const auto end = t0 + std::chrono::seconds(35); + auto last_sample = t0 - std::chrono::seconds(10); + + while (std::chrono::steady_clock::now() < end) + { + safe_edge::pilot_server::ChargerLocation sample{}; + eprosima::fastdds::dds::SampleInfo info{}; + if (reader->take_next_sample(&sample, &info) == + eprosima::fastdds::dds::RETCODE_OK && info.valid_data) + { + const auto now = std::chrono::steady_clock::now(); + if (std::chrono::duration_cast( + now - last_sample).count() > 2000) + { + burst_count++; + std::cout << " [dds] Burst " << burst_count << " at t=" + << std::chrono::duration_cast( + now - t0).count() << " s\n"; + } + last_sample = now; + } + else + { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + } + + EXPECT_GE(burst_count, 2) + << "Expected >=2 bursts (publication_match trigger + 30 s periodic refresh), " + << "got " << burst_count; +} + +// --------------------------------------------------------------------------- +// main +// --------------------------------------------------------------------------- + +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + ::testing::AddGlobalTestEnvironment(new ServerEnvironment()); + return RUN_ALL_TESTS(); +} diff --git a/idl/common.idl b/idl/common.idl new file mode 100644 index 0000000..43a4e5e --- /dev/null +++ b/idl/common.idl @@ -0,0 +1,44 @@ +module safe_edge { +module common { + +struct Header +{ + string source; + unsigned long long timestamp_ms; + string trace_id; +}; + +struct GeoPoint +{ + double latitude; + double longitude; +}; + +enum HealthStatus +{ + HEALTH_UNKNOWN, + HEALTH_OK, + HEALTH_DEGRADED, + HEALTH_ERROR +}; + +struct ServiceHeartbeat +{ + Header header_st; + string service_name; + HealthStatus status; + string detail; +}; + +enum PolicyMode +{ + POLICY_UNKNOWN, + POLICY_NOMINAL, + POLICY_LOW_SOC, + POLICY_EDGE_AUTONOMOUS, + POLICY_DEGRADED_SERVER_DOWN, + POLICY_DEGRADED_COMPLETE +}; + +}; +}; diff --git a/idl/edge.idl b/idl/edge.idl new file mode 100644 index 0000000..2901579 --- /dev/null +++ b/idl/edge.idl @@ -0,0 +1,33 @@ +#include "common.idl" + +module safe_edge { +module edge { + +struct VehicleEdgeSummary +{ + safe_edge::common::Header header; + float soc_pct; + safe_edge::common::PolicyMode current_mode; + safe_edge::common::HealthStatus vehicle_health; + boolean v2g_ready; +}; + +struct EnergyAdvisory +{ + safe_edge::common::Header header; + safe_edge::common::PolicyMode suggested_mode; + string advisory_reason; + long recommended_charger_id; + float target_soc_pct; +}; + +struct EdgeGatewayStatus +{ + safe_edge::common::Header header; + safe_edge::common::HealthStatus status; + unsigned long long last_server_sync_ms; + string detail; +}; + +}; +}; diff --git a/idl/pilot_server.idl b/idl/pilot_server.idl new file mode 100644 index 0000000..e6db4cc --- /dev/null +++ b/idl/pilot_server.idl @@ -0,0 +1,77 @@ +#include "common.idl" + +module safe_edge { +module pilot_server { + +const unsigned long MAX_CHARGER_LOCATIONS = 200; +const unsigned long MAX_CHARGER_TYPES = 64; +const unsigned long MAX_CHARGING_SESSIONS = 1000; +const unsigned long MAX_ROUTE_METRICS = 512; + +struct ChargerLocation +{ + long id; + string name; + safe_edge::common::GeoPoint position; +}; + +typedef sequence ChargerLocationSeq; + +struct ChargerType +{ + long id; + string charger_type; +}; + +typedef sequence ChargerTypeSeq; + +struct ChargingSession +{ + long id; + long station_id; + string charger_type_id; + double consume_wh; + long duration_min; + string date_iso8601; + string ingested_at_iso8601; +}; + +typedef sequence ChargingSessionSeq; + +struct TransitHealth +{ + string status; + double last_fetch_ts; +}; + +struct RouteMetric +{ + string route_id; + long updates_count; +}; + +typedef sequence RouteMetricSeq; + +struct TransitMetrics +{ + RouteMetricSeq by_route; + long vehicles_seen; +}; + +enum RequestedDataType +{ + CHARGER_LOCATION, + CHARGER_TYPE, + CHARGING_SESSION, + TRANSIT_HEALTH, + TRANSIT_METRICS +}; + +struct ServerQuery +{ + string requested_by; + RequestedDataType requested_data_type; +}; + +}; +}; diff --git a/qnx/targets/qemu-qnx800-x86_64/local/options b/qnx/targets/qemu-qnx800-x86_64/local/options new file mode 100644 index 0000000..d4c6eb8 --- /dev/null +++ b/qnx/targets/qemu-qnx800-x86_64/local/options @@ -0,0 +1,119 @@ +OPT_AARCH64_VERSION='8' +DEF_OPT_AARCH64_VERSION='8' +OPT_ABLELOCK='yes' +DEF_OPT_ABLELOCK='yes' +OPT_ARCH='x86_64' +DEF_OPT_ARCH='x86_64' +OPT_ASLR='yes' +DEF_OPT_ASLR='yes' +OPT_ASSUMED_IP='none' +DEF_OPT_ASSUMED_IP='none' +OPT_BOOT_SIZE='0' +DEF_OPT_BOOT_SIZE='0' +OPT_BUILD='all' +DEF_OPT_BUILD='all' +OPT_CERTICOM='no' +DEF_OPT_CERTICOM='no' +OPT_COPY='all' +DEF_OPT_COPY='all' +OPT_COPY_DEST='none' +DEF_OPT_COPY_DEST='none' +OPT_CPU='2' +DEF_OPT_CPU='2' +OPT_CRYPTODEV='no' +DEF_OPT_CRYPTODEV='no' +OPT_DATA_INODES='3000' +DEF_OPT_DATA_INODES='3000' +OPT_DATA_SIZE='60' +DEF_OPT_DATA_SIZE='60' +OPT_EXTRA_DIRS='none' +DEF_OPT_EXTRA_DIRS='none' +OPT_GRAPHICS='no' +DEF_OPT_GRAPHICS='no' +OPT_GUEST='none' +DEF_OPT_GUEST='none' +OPT_HOSTNAME='qemu-qnx800-x86_64' +DEF_OPT_HOSTNAME='noname' +OPT_IO_SOCK_DIAG='no' +DEF_OPT_IO_SOCK_DIAG='no' +OPT_IP='dhcp' +DEF_OPT_IP='dhcp' +OPT_MACADDR='52:54:00:38:3a:92' +DEF_OPT_MACADDR='generate' +OPT_NFS='no' +DEF_OPT_NFS='no' +OPT_PART_SIZES='full' +DEF_OPT_PART_SIZES='full' +OPT_PATHTRUST='no' +DEF_OPT_PATHTRUST='no' +OPT_PERL='no' +DEF_OPT_PERL='no' +OPT_PKCS11='no' +DEF_OPT_PKCS11='no' +OPT_POLICY='none' +DEF_OPT_POLICY='none' +OPT_PROC='no' +DEF_OPT_PROC='no' +OPT_PYTHON='no' +DEF_OPT_PYTHON='no' +OPT_QAUDIT='no' +DEF_OPT_QAUDIT='no' +OPT_QCFS='no' +DEF_OPT_QCFS='no' +OPT_QFIM='no' +DEF_OPT_QFIM='no' +OPT_QH_CONFIG='no' +DEF_OPT_QH_CONFIG='no' +OPT_QTD='no' +DEF_OPT_QTD='no' +OPT_QTSAFEFS='no' +DEF_OPT_QTSAFEFS='no' +OPT_QVM='no' +DEF_OPT_QVM='no' +OPT_RAM='1G' +DEF_OPT_RAM='1G' +OPT_REPOS='$QNX_STAGE_nto:$QNX_TARGET' +DEF_OPT_REPOS='$QNX_STAGE_nto:$QNX_TARGET' +OPT_ROOT='no' +DEF_OPT_ROOT='no' +OPT_SANITIZERS='no' +DEF_OPT_SANITIZERS='no' +OPT_SECPOL='no' +DEF_OPT_SECPOL='no' +OPT_SECURE_DATA='no' +DEF_OPT_SECURE_DATA='no' +OPT_SECURE_PROCFS='yes' +DEF_OPT_SECURE_PROCFS='yes' +OPT_SLM='no' +DEF_OPT_SLM='no' +OPT_SSHD_PREGEN='yes' +DEF_OPT_SSHD_PREGEN='yes' +OPT_SSH_IDENT='prompt' +DEF_OPT_SSH_IDENT='prompt' +OPT_SYS_INODES='1000' +DEF_OPT_SYS_INODES='1000' +OPT_SYS_SIZE='20' +DEF_OPT_SYS_SIZE='20' +OPT_TCG='no' +DEF_OPT_TCG='no' +OPT_TIME_SERVERS='pool.ntp.org' +DEF_OPT_TIME_SERVERS='pool.ntp.org' +OPT_TOMCRYPT='no' +DEF_OPT_TOMCRYPT='no' +OPT_TYPE='qemu' +DEF_OPT_TYPE='qemu' +OPT_TZ='UTC0' +DEF_OPT_TZ='UTC0' +OPT_UNION='yes' +DEF_OPT_UNION='yes' +OPT_UPDATE='all' +DEF_OPT_UPDATE='all' +OPT_USB='yes' +DEF_OPT_USB='yes' +OPT_USERS='root:qnxuser:user1:user2:user3:user4:user5:user6' +DEF_OPT_USERS='root:qnxuser:user1:user2:user3:user4:user5:user6' +OPT_VALGRIND='no' +DEF_OPT_VALGRIND='no' +OPT_ZONEINFO='no' +DEF_OPT_ZONEINFO='no' +VERSION=3 diff --git a/qnx/targets/qemu-qnx800-x86_64/local/snippets/data_files.custom b/qnx/targets/qemu-qnx800-x86_64/local/snippets/data_files.custom new file mode 100644 index 0000000..3ee0a4c --- /dev/null +++ b/qnx/targets/qemu-qnx800-x86_64/local/snippets/data_files.custom @@ -0,0 +1,2 @@ +# local/snippets/data_files.custom +# Placeholder for local list of files to add to data partition diff --git a/qnx/targets/qemu-qnx800-x86_64/local/snippets/ifs_files.custom b/qnx/targets/qemu-qnx800-x86_64/local/snippets/ifs_files.custom new file mode 100644 index 0000000..f54033c --- /dev/null +++ b/qnx/targets/qemu-qnx800-x86_64/local/snippets/ifs_files.custom @@ -0,0 +1,2 @@ +# local/snippets/ifs_files.custom +# Placeholder for local list of files to add to ifs diff --git a/qnx/targets/qemu-qnx800-x86_64/local/snippets/profile.custom b/qnx/targets/qemu-qnx800-x86_64/local/snippets/profile.custom new file mode 100644 index 0000000..61b37bb --- /dev/null +++ b/qnx/targets/qemu-qnx800-x86_64/local/snippets/profile.custom @@ -0,0 +1,2 @@ +# local/snippets/profile.custom +# Contents are included at the end of /etc/profile diff --git a/qnx/targets/qemu-qnx800-x86_64/local/valgrind.files b/qnx/targets/qemu-qnx800-x86_64/local/valgrind.files new file mode 100644 index 0000000..65cf691 --- /dev/null +++ b/qnx/targets/qemu-qnx800-x86_64/local/valgrind.files @@ -0,0 +1,12 @@ +# Add the names of the binaries you want to add a symbols to the target +# to debug through valgrind. +# +# e.g sbin/devb-ram +# +# Binaries that should be picked up from SDP/target_symbols should be +# suffixed with .sym else the stage or normal SDP binary will be picked up +# +# e.g. sbin/devb-ram.sym +# +# Note: libc and ldqnx are added automatically. +# diff --git a/qnx/targets/qemu-qnx800-x86_64/mkqnximage-wrapper.sh b/qnx/targets/qemu-qnx800-x86_64/mkqnximage-wrapper.sh new file mode 100755 index 0000000..087aa69 --- /dev/null +++ b/qnx/targets/qemu-qnx800-x86_64/mkqnximage-wrapper.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +set -euo pipefail + +QNX_USER="${USER:-$(id -un)}" +: "${QNX_SDP_ROOT:=/home/${QNX_USER}/qnx800}" + +# shellcheck source=/dev/null +source "${QNX_SDP_ROOT}/qnxsdp-env.sh" +exec mkqnximage "$@" diff --git a/qnx/toolchains/qnx8.cmake b/qnx/toolchains/qnx8.cmake new file mode 100644 index 0000000..8c85e24 --- /dev/null +++ b/qnx/toolchains/qnx8.cmake @@ -0,0 +1,53 @@ +set(CMAKE_SYSTEM_NAME QNX) +set(CMAKE_SYSTEM_VERSION 8.0.0) + +# QNX cross-builds cannot execute target binaries during configure. +set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) + +if(DEFINED QNX_HOST) + set(_qnx_host "${QNX_HOST}") +elseif(DEFINED ENV{QNX_HOST}) + set(_qnx_host "$ENV{QNX_HOST}") +else() + message(FATAL_ERROR "QNX_HOST is not set. Export QNX_HOST before running CMake.") +endif() + +if(DEFINED QNX_TARGET) + set(_qnx_target "${QNX_TARGET}") +elseif(DEFINED ENV{QNX_TARGET}) + set(_qnx_target "$ENV{QNX_TARGET}") +else() + message(FATAL_ERROR "QNX_TARGET is not set. Export QNX_TARGET before running CMake.") +endif() + +set(QNX_ARCH "x86_64" CACHE STRING "QNX target architecture (x86_64 or aarch64le)") +set_property(CACHE QNX_ARCH PROPERTY STRINGS x86_64 aarch64le) + +if(QNX_ARCH STREQUAL "x86_64") + set(_qnx_tool_prefix "ntox86_64") + set(CMAKE_SYSTEM_PROCESSOR "x86_64") +elseif(QNX_ARCH STREQUAL "aarch64le") + set(_qnx_tool_prefix "ntoaarch64") + set(CMAKE_SYSTEM_PROCESSOR "aarch64") +else() + message(FATAL_ERROR "Unsupported QNX_ARCH='${QNX_ARCH}'. Use x86_64 or aarch64le.") +endif() + +set(ENV{QNX_HOST} "${_qnx_host}") +set(ENV{QNX_TARGET} "${_qnx_target}") +set(ENV{PATH} "${_qnx_host}/usr/bin:$ENV{PATH}") + +set(CMAKE_SYSROOT "${_qnx_target}" CACHE PATH "QNX target sysroot" FORCE) +set(CMAKE_C_COMPILER "${_qnx_host}/usr/bin/${_qnx_tool_prefix}-gcc" CACHE FILEPATH "QNX C compiler" FORCE) +set(CMAKE_CXX_COMPILER "${_qnx_host}/usr/bin/${_qnx_tool_prefix}-g++" CACHE FILEPATH "QNX C++ compiler" FORCE) +set(CMAKE_AR "${_qnx_host}/usr/bin/${_qnx_tool_prefix}-ar" CACHE FILEPATH "QNX archiver" FORCE) +set(CMAKE_RANLIB "${_qnx_host}/usr/bin/${_qnx_tool_prefix}-ranlib" CACHE FILEPATH "QNX ranlib" FORCE) +set(CMAKE_STRIP "${_qnx_host}/usr/bin/${_qnx_tool_prefix}-strip" CACHE FILEPATH "QNX strip" FORCE) +set(CMAKE_C_FLAGS_INIT "${CMAKE_C_FLAGS_INIT} -D_QNX_SOURCE") +set(CMAKE_CXX_FLAGS_INIT "${CMAKE_CXX_FLAGS_INIT} -D_QNX_SOURCE") + +set(CMAKE_FIND_ROOT_PATH "${_qnx_target}/${QNX_ARCH}" "${_qnx_target}" CACHE STRING "QNX root paths for find_*" FORCE) +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) diff --git a/safe_dds/edge/CMakeLists.txt b/safe_dds/edge/CMakeLists.txt new file mode 100644 index 0000000..6b05c65 --- /dev/null +++ b/safe_dds/edge/CMakeLists.txt @@ -0,0 +1,138 @@ +cmake_minimum_required(VERSION 3.16) + +project(safe_edge_edge LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +find_package(safedds REQUIRED) + +if(CMAKE_SYSTEM_NAME STREQUAL "QNX") + set(SAFE_EDGE_PLATFORM_SOCKET_LIB socket) +endif() + +set(SAFE_EDGE_EDGE_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include") +set(SAFE_EDGE_IDL_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../idl") + +function(safe_edge_apply_common_build_settings target_name) + target_include_directories( + "${target_name}" + PUBLIC + "${SAFE_EDGE_EDGE_INCLUDE_DIR}" + ) + + target_compile_options( + "${target_name}" + PRIVATE + -fno-exceptions + -fno-rtti + -Wall + -Werror + -Wextra + -Wpedantic + ) +endfunction() + +add_library( + safe_edge_edge_common + STATIC + src/common/RuntimeConfig.cpp + src/common/TopicNames.cpp + src/common/HeaderFactory.cpp + src/logic/EdgeAdvisor.cpp +) +safe_edge_apply_common_build_settings(safe_edge_edge_common) +target_include_directories( + safe_edge_edge_common + PUBLIC + "${SAFE_EDGE_IDL_INCLUDE_DIR}" +) +target_link_libraries( + safe_edge_edge_common + PUBLIC + safedds +) + +add_executable( + safe_edge_edge_gateway + src/apps/edge_gateway_main.cpp + src/nodes/EdgeGatewayNode.cpp +) +safe_edge_apply_common_build_settings(safe_edge_edge_gateway) +target_include_directories( + safe_edge_edge_gateway + PRIVATE + "${SAFE_EDGE_IDL_INCLUDE_DIR}" +) +target_link_libraries( + safe_edge_edge_gateway + PRIVATE + safe_edge_edge_common + safedds + ${SAFE_EDGE_PLATFORM_SOCKET_LIB} +) + +install( + TARGETS + safe_edge_edge_gateway + RUNTIME DESTINATION bin +) + +option(SAFE_EDGE_BUILD_TESTS "Build integration tests" ON) + +if(SAFE_EDGE_BUILD_TESTS) + find_package(GTest QUIET) + + if(NOT GTest_FOUND) + message(STATUS "GTest not found — fetching from source") + include(FetchContent) + FetchContent_Declare( + googletest + URL https://github.com/google/googletest/archive/refs/tags/v1.14.0.tar.gz + URL_HASH SHA256=8ad598c73ad796e0d8280b082cebd82a630d73e73cd3c70057938a6501bba5d7 + DOWNLOAD_EXTRACT_TIMESTAMP TRUE + ) + set(INSTALL_GTEST OFF CACHE BOOL "" FORCE) + FetchContent_MakeAvailable(googletest) + + if(NOT TARGET GTest::gtest) + add_library(GTest::gtest ALIAS gtest) + endif() + endif() + + add_executable( + test_edge_integration + test/test_edge_integration.cpp + ) + + # Tests need exceptions and RTTI (GTest requirement). + # Do not reuse safe_edge_apply_common_build_settings which disables them. + target_include_directories( + test_edge_integration + PRIVATE + "${SAFE_EDGE_EDGE_INCLUDE_DIR}" + "${SAFE_EDGE_IDL_INCLUDE_DIR}" + ) + target_compile_options( + test_edge_integration + PRIVATE + -Wall -Wextra -Wpedantic + ) + target_link_libraries( + test_edge_integration + PRIVATE + safe_edge_edge_common + safedds + ${SAFE_EDGE_PLATFORM_SOCKET_LIB} + GTest::gtest + ) + + enable_testing() + add_test(NAME edge_integration COMMAND test_edge_integration) + + install( + TARGETS test_edge_integration + RUNTIME DESTINATION bin + ) +endif() diff --git a/safe_dds/edge/include/safe_edge/edge_module/common/HeaderFactory.hpp b/safe_dds/edge/include/safe_edge/edge_module/common/HeaderFactory.hpp new file mode 100644 index 0000000..fa53aa9 --- /dev/null +++ b/safe_dds/edge/include/safe_edge/edge_module/common/HeaderFactory.hpp @@ -0,0 +1,33 @@ +#ifndef SAFE_EDGE_EDGE_MODULE_COMMON_HEADERFACTORY_HPP +#define SAFE_EDGE_EDGE_MODULE_COMMON_HEADERFACTORY_HPP + +#include + +#include +#include + +namespace safe_edge { +namespace edge_module { +namespace common { + +class HeaderFactory +{ +public: + + explicit HeaderFactory(std::string source_name); + + safe_edge::common::Header make_header(const char* trace_suffix = nullptr); + + static uint64_t now_ms() noexcept; + +private: + + std::string source_name_; + uint64_t counter_ = 0U; +}; + +} // namespace common +} // namespace edge_module +} // namespace safe_edge + +#endif // SAFE_EDGE_EDGE_MODULE_COMMON_HEADERFACTORY_HPP diff --git a/safe_dds/edge/include/safe_edge/edge_module/common/RuntimeConfig.hpp b/safe_dds/edge/include/safe_edge/edge_module/common/RuntimeConfig.hpp new file mode 100644 index 0000000..88a357c --- /dev/null +++ b/safe_dds/edge/include/safe_edge/edge_module/common/RuntimeConfig.hpp @@ -0,0 +1,27 @@ +#ifndef SAFE_EDGE_EDGE_MODULE_COMMON_RUNTIMECONFIG_HPP +#define SAFE_EDGE_EDGE_MODULE_COMMON_RUNTIMECONFIG_HPP + +#include +#include + +namespace safe_edge { +namespace edge_module { +namespace common { + +struct RuntimeConfig +{ + std::string participant_name; + std::string service_name; + std::string source_name; + uint32_t domain_id = 0U; + uint16_t participant_port = 0U; + uint32_t status_interval_sec = 5U; +}; + +RuntimeConfig make_edge_gateway_runtime_config(); + +} // namespace common +} // namespace edge_module +} // namespace safe_edge + +#endif // SAFE_EDGE_EDGE_MODULE_COMMON_RUNTIMECONFIG_HPP diff --git a/safe_dds/edge/include/safe_edge/edge_module/common/TopicNames.hpp b/safe_dds/edge/include/safe_edge/edge_module/common/TopicNames.hpp new file mode 100644 index 0000000..eef164e --- /dev/null +++ b/safe_dds/edge/include/safe_edge/edge_module/common/TopicNames.hpp @@ -0,0 +1,20 @@ +#ifndef SAFE_EDGE_EDGE_MODULE_COMMON_TOPICNAMES_HPP +#define SAFE_EDGE_EDGE_MODULE_COMMON_TOPICNAMES_HPP + +namespace safe_edge { +namespace edge_module { +namespace common { +namespace topic_names { + +const char* vehicle_edge_summary() noexcept; +const char* energy_advisory() noexcept; +const char* edge_gateway_status() noexcept; +const char* charger_locations() noexcept; +const char* service_heartbeat() noexcept; + +} // namespace topic_names +} // namespace common +} // namespace edge_module +} // namespace safe_edge + +#endif // SAFE_EDGE_EDGE_MODULE_COMMON_TOPICNAMES_HPP diff --git a/safe_dds/edge/include/safe_edge/edge_module/logic/EdgeAdvisor.hpp b/safe_dds/edge/include/safe_edge/edge_module/logic/EdgeAdvisor.hpp new file mode 100644 index 0000000..c6d7c7d --- /dev/null +++ b/safe_dds/edge/include/safe_edge/edge_module/logic/EdgeAdvisor.hpp @@ -0,0 +1,25 @@ +#ifndef SAFE_EDGE_EDGE_MODULE_LOGIC_EDGEADVISOR_HPP +#define SAFE_EDGE_EDGE_MODULE_LOGIC_EDGEADVISOR_HPP + +#include +#include + +namespace safe_edge { +namespace edge_module { +namespace logic { + +class EdgeAdvisor +{ +public: + + static safe_edge::edge::EnergyAdvisory evaluate( + const safe_edge::edge::VehicleEdgeSummary& summary, + const safe_edge::pilot_server::ChargerLocation* chargers, + int32_t charger_count); +}; + +} // namespace logic +} // namespace edge_module +} // namespace safe_edge + +#endif // SAFE_EDGE_EDGE_MODULE_LOGIC_EDGEADVISOR_HPP diff --git a/safe_dds/edge/include/safe_edge/edge_module/nodes/EdgeGatewayNode.hpp b/safe_dds/edge/include/safe_edge/edge_module/nodes/EdgeGatewayNode.hpp new file mode 100644 index 0000000..4965527 --- /dev/null +++ b/safe_dds/edge/include/safe_edge/edge_module/nodes/EdgeGatewayNode.hpp @@ -0,0 +1,189 @@ +#ifndef SAFE_EDGE_EDGE_MODULE_NODES_EDGEGATEWAYNODE_HPP +#define SAFE_EDGE_EDGE_MODULE_NODES_EDGEGATEWAYNODE_HPP + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace safe_edge { +namespace edge_module { +namespace nodes { + +class EdgeGatewayNode +{ +public: + + explicit EdgeGatewayNode(const common::RuntimeConfig& runtime_config); + + int run(); + +private: + + class ParticipantListener : + public eprosima::safedds::dds::DomainParticipantListener + { + public: + + explicit ParticipantListener(EdgeGatewayNode& owner); + + void on_subscription_matched( + eprosima::safedds::dds::DataReader& reader, + const eprosima::safedds::dds::SubscriptionMatchedStatus& info) noexcept override; + + void on_publication_matched( + eprosima::safedds::dds::DataWriter& writer, + const eprosima::safedds::dds::PublicationMatchedStatus& info) noexcept override; + + private: + + EdgeGatewayNode& owner_; + }; + + class VehicleEdgeSummaryListener : + public eprosima::safedds::dds::DataReaderListener + { + public: + + explicit VehicleEdgeSummaryListener(EdgeGatewayNode& owner); + + void on_data_available( + eprosima::safedds::dds::DataReader& reader) noexcept override; + + private: + + EdgeGatewayNode& owner_; + }; + + class ChargerLocationListener : + public eprosima::safedds::dds::DataReaderListener + { + public: + + explicit ChargerLocationListener(EdgeGatewayNode& owner); + + void on_data_available( + eprosima::safedds::dds::DataReader& reader) noexcept override; + + private: + + EdgeGatewayNode& owner_; + }; + + class HeartbeatListener : + public eprosima::safedds::dds::DataReaderListener + { + public: + + explicit HeartbeatListener(EdgeGatewayNode& owner); + + void on_data_available( + eprosima::safedds::dds::DataReader& reader) noexcept override; + + private: + + EdgeGatewayNode& owner_; + }; + + bool initialize(); + bool create_participant(); + bool register_types(); + bool create_topics(); + bool create_endpoints(); + bool enable_entities(); + bool create_executor(); + void start_timers() noexcept; + + void on_vehicle_edge_summary_received(const safe_edge::edge::VehicleEdgeSummary& summary); + void on_charger_location_received(const safe_edge::pilot_server::ChargerLocation& location); + void on_server_heartbeat_received(const safe_edge::common::ServiceHeartbeat& heartbeat); + void publish_energy_advisory(const safe_edge::edge::EnergyAdvisory& advisory); + void publish_edge_gateway_status(); + + void log_subscription_match(const char* topic_name, int32_t total_count) const; + void log_publication_match(const char* topic_name, int32_t total_count) const; + + eprosima::safedds::execution::TimePoint next_wakeup_time() const noexcept; + + eprosima::safedds::dds::DomainParticipantFactory factory_; + common::RuntimeConfig runtime_config_; + common::HeaderFactory header_factory_; + + ParticipantListener participant_listener_; + VehicleEdgeSummaryListener vehicle_edge_summary_listener_; + ChargerLocationListener charger_location_listener_; + HeartbeatListener heartbeat_listener_; + + safe_edge::edge::VehicleEdgeSummaryTypeSupport vehicle_edge_summary_type_support_; + safe_edge::edge::EnergyAdvisoryTypeSupport energy_advisory_type_support_; + safe_edge::edge::EdgeGatewayStatusTypeSupport edge_gateway_status_type_support_; + safe_edge::pilot_server::ChargerLocationTypeSupport charger_location_type_support_; + safe_edge::common::ServiceHeartbeatTypeSupport service_heartbeat_type_support_; + + eprosima::safedds::dds::DomainParticipant* participant_ = nullptr; + eprosima::safedds::dds::Publisher* publisher_ = nullptr; + eprosima::safedds::dds::Subscriber* subscriber_ = nullptr; + eprosima::safedds::execution::ISpinnable* executor_ = nullptr; + + eprosima::safedds::dds::Topic* vehicle_edge_summary_topic_ = nullptr; + eprosima::safedds::dds::Topic* energy_advisory_topic_ = nullptr; + eprosima::safedds::dds::Topic* edge_gateway_status_topic_ = nullptr; + eprosima::safedds::dds::Topic* charger_location_topic_ = nullptr; + eprosima::safedds::dds::Topic* service_heartbeat_topic_ = nullptr; + + eprosima::safedds::memory::container::StaticString256 vehicle_edge_summary_topic_name_; + eprosima::safedds::memory::container::StaticString256 energy_advisory_topic_name_; + eprosima::safedds::memory::container::StaticString256 edge_gateway_status_topic_name_; + eprosima::safedds::memory::container::StaticString256 charger_location_topic_name_; + eprosima::safedds::memory::container::StaticString256 service_heartbeat_topic_name_; + + eprosima::safedds::dds::DataWriter* energy_advisory_datawriter_ = nullptr; + eprosima::safedds::dds::DataWriter* edge_gateway_status_datawriter_ = nullptr; + + eprosima::safedds::dds::TypedDataWriter* energy_advisory_writer_ = + nullptr; + eprosima::safedds::dds::TypedDataWriter* edge_gateway_status_writer_ = + nullptr; + + eprosima::safedds::dds::DataReader* vehicle_edge_summary_datareader_ = nullptr; + eprosima::safedds::dds::TypedDataReader* vehicle_edge_summary_reader_ = + nullptr; + + eprosima::safedds::dds::DataReader* charger_location_datareader_ = nullptr; + eprosima::safedds::dds::TypedDataReader* charger_location_reader_ = + nullptr; + + eprosima::safedds::dds::DataReader* service_heartbeat_datareader_ = nullptr; + eprosima::safedds::dds::TypedDataReader* heartbeat_reader_ = + nullptr; + + safe_edge::pilot_server::ChargerLocation cached_chargers_[3]; + int32_t cached_charger_count_ = 0; + uint64_t last_server_sync_ms_ = 0U; + uint64_t last_server_hb_ms_ = 0U; + bool server_available_ = false; + + eprosima::safedds::execution::Timer status_timer_; +}; + +} // namespace nodes +} // namespace edge_module +} // namespace safe_edge + +#endif // SAFE_EDGE_EDGE_MODULE_NODES_EDGEGATEWAYNODE_HPP diff --git a/safe_dds/edge/src/apps/edge_gateway_main.cpp b/safe_dds/edge/src/apps/edge_gateway_main.cpp new file mode 100644 index 0000000..69026fa --- /dev/null +++ b/safe_dds/edge/src/apps/edge_gateway_main.cpp @@ -0,0 +1,11 @@ +#include +#include + +int main() +{ + const safe_edge::edge_module::common::RuntimeConfig config = + safe_edge::edge_module::common::make_edge_gateway_runtime_config(); + + safe_edge::edge_module::nodes::EdgeGatewayNode node(config); + return node.run(); +} diff --git a/safe_dds/edge/src/common/HeaderFactory.cpp b/safe_dds/edge/src/common/HeaderFactory.cpp new file mode 100644 index 0000000..06b3581 --- /dev/null +++ b/safe_dds/edge/src/common/HeaderFactory.cpp @@ -0,0 +1,48 @@ +#include + +#include +#include +#include +#include + +namespace safe_edge { +namespace edge_module { +namespace common { + +HeaderFactory::HeaderFactory(std::string source_name) + : source_name_(std::move(source_name)) +{ +} + +safe_edge::common::Header HeaderFactory::make_header(const char* trace_suffix) +{ + safe_edge::common::Header header; + header.source = source_name_; + header.timestamp_ms = now_ms(); + header.trace_id = source_name_; + header.trace_id += "-"; + + std::array buf{}; + std::snprintf(buf.data(), buf.size(), "%llu", static_cast(counter_++)); + header.trace_id += buf.data(); + + if (nullptr != trace_suffix && trace_suffix[0] != '\0') + { + header.trace_id += "-"; + header.trace_id += trace_suffix; + } + + return header; +} + +uint64_t HeaderFactory::now_ms() noexcept +{ + const auto now = std::chrono::system_clock::now(); + const auto since_epoch = now.time_since_epoch(); + return static_cast( + std::chrono::duration_cast(since_epoch).count()); +} + +} // namespace common +} // namespace edge_module +} // namespace safe_edge diff --git a/safe_dds/edge/src/common/RuntimeConfig.cpp b/safe_dds/edge/src/common/RuntimeConfig.cpp new file mode 100644 index 0000000..ee6eb27 --- /dev/null +++ b/safe_dds/edge/src/common/RuntimeConfig.cpp @@ -0,0 +1,21 @@ +#include + +namespace safe_edge { +namespace edge_module { +namespace common { + +RuntimeConfig make_edge_gateway_runtime_config() +{ + RuntimeConfig config; + config.participant_name = "SafeEdgeEdgeGatewayParticipant"; + config.service_name = "edge_gateway"; + config.source_name = "edge_gateway"; + config.domain_id = 0U; + config.participant_port = 8030U; + config.status_interval_sec = 5U; + return config; +} + +} // namespace common +} // namespace edge_module +} // namespace safe_edge diff --git a/safe_dds/edge/src/common/TopicNames.cpp b/safe_dds/edge/src/common/TopicNames.cpp new file mode 100644 index 0000000..dc1a5d4 --- /dev/null +++ b/safe_dds/edge/src/common/TopicNames.cpp @@ -0,0 +1,36 @@ +#include + +namespace safe_edge { +namespace edge_module { +namespace common { +namespace topic_names { + +const char* vehicle_edge_summary() noexcept +{ + return "safe_edge.edge.vehicle_edge_summary"; +} + +const char* energy_advisory() noexcept +{ + return "safe_edge.edge.energy_advisory"; +} + +const char* edge_gateway_status() noexcept +{ + return "safe_edge.edge.edge_gateway_status"; +} + +const char* charger_locations() noexcept +{ + return "safe_edge.pilot_server.charger_locations"; +} + +const char* service_heartbeat() noexcept +{ + return "safe_edge.common.service_heartbeat"; +} + +} // namespace topic_names +} // namespace common +} // namespace edge_module +} // namespace safe_edge diff --git a/safe_dds/edge/src/logic/EdgeAdvisor.cpp b/safe_dds/edge/src/logic/EdgeAdvisor.cpp new file mode 100644 index 0000000..f6c22e8 --- /dev/null +++ b/safe_dds/edge/src/logic/EdgeAdvisor.cpp @@ -0,0 +1,41 @@ +#include + +namespace safe_edge { +namespace edge_module { +namespace logic { + +safe_edge::edge::EnergyAdvisory EdgeAdvisor::evaluate( + const safe_edge::edge::VehicleEdgeSummary& summary, + const safe_edge::pilot_server::ChargerLocation* chargers, + int32_t charger_count) +{ + safe_edge::edge::EnergyAdvisory advisory; + + if (summary.soc_pct < 20.0F) + { + advisory.suggested_mode = safe_edge::common::PolicyMode::POLICY_LOW_SOC; + advisory.advisory_reason = "Low battery -- charge now"; + advisory.recommended_charger_id = (charger_count > 0) ? chargers[0].id : 1; + advisory.target_soc_pct = 80.0F; + } + else if (summary.v2g_ready) + { + advisory.suggested_mode = safe_edge::common::PolicyMode::POLICY_EDGE_AUTONOMOUS; + advisory.advisory_reason = "V2G available"; + advisory.recommended_charger_id = 0; + advisory.target_soc_pct = 90.0F; + } + else + { + advisory.suggested_mode = safe_edge::common::PolicyMode::POLICY_NOMINAL; + advisory.advisory_reason = "Normal operation"; + advisory.recommended_charger_id = 0; + advisory.target_soc_pct = 80.0F; + } + + return advisory; +} + +} // namespace logic +} // namespace edge_module +} // namespace safe_edge diff --git a/safe_dds/edge/src/nodes/EdgeGatewayNode.cpp b/safe_dds/edge/src/nodes/EdgeGatewayNode.cpp new file mode 100644 index 0000000..b3a2938 --- /dev/null +++ b/safe_dds/edge/src/nodes/EdgeGatewayNode.cpp @@ -0,0 +1,549 @@ +#include + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace safe_edge { +namespace edge_module { +namespace nodes { + +namespace { + +constexpr eprosima::safedds::execution::TimePeriod STATUS_INTERVAL = {5, 0}; + +template +bool register_type( + eprosima::safedds::dds::DomainParticipant& participant, + TypeSupportT& type_support, + const char* label) +{ + if (eprosima::safedds::dds::ReturnCode::OK != type_support.register_type(participant, type_support.get_type_name())) + { + std::cerr << "[edge_gateway] Failed to register type: " << label << std::endl; + return false; + } + return true; +} + +template +eprosima::safedds::dds::Topic* create_topic( + eprosima::safedds::dds::DomainParticipant& participant, + eprosima::safedds::memory::container::StaticString256& topic_name, + TypeSupportT& type_support) +{ + eprosima::safedds::dds::TopicQos topic_qos{}; + return participant.create_topic( + topic_name, + type_support.get_type_name(), + topic_qos, + nullptr, + eprosima::safedds::dds::NONE_STATUS_MASK); +} + +template +eprosima::safedds::dds::TypedDataWriter* downcast_writer( + eprosima::safedds::dds::DataWriter* writer) +{ + if (nullptr == writer) + { + return nullptr; + } + return eprosima::safedds::dds::TypedDataWriter::downcast(*writer); +} + +template +eprosima::safedds::dds::TypedDataReader* downcast_reader( + eprosima::safedds::dds::DataReader* reader) +{ + if (nullptr == reader) + { + return nullptr; + } + return eprosima::safedds::dds::TypedDataReader::downcast(*reader); +} + +} // namespace + +EdgeGatewayNode::ParticipantListener::ParticipantListener(EdgeGatewayNode& owner) + : owner_(owner) +{ +} + +void EdgeGatewayNode::ParticipantListener::on_subscription_matched( + eprosima::safedds::dds::DataReader& reader, + const eprosima::safedds::dds::SubscriptionMatchedStatus& info) noexcept +{ + owner_.log_subscription_match(reader.get_topicdescription().get_name().const_string_data(), info.total_count); +} + +void EdgeGatewayNode::ParticipantListener::on_publication_matched( + eprosima::safedds::dds::DataWriter& writer, + const eprosima::safedds::dds::PublicationMatchedStatus& info) noexcept +{ + owner_.log_publication_match(writer.get_topic().get_name().const_string_data(), info.total_count); +} + +EdgeGatewayNode::VehicleEdgeSummaryListener::VehicleEdgeSummaryListener(EdgeGatewayNode& owner) + : owner_(owner) +{ +} + +void EdgeGatewayNode::VehicleEdgeSummaryListener::on_data_available( + eprosima::safedds::dds::DataReader& reader) noexcept +{ + auto* typed_reader = + eprosima::safedds::dds::TypedDataReader::downcast(reader); + + if (nullptr == typed_reader) + { + std::cerr << "[edge_gateway] Failed to downcast vehicle edge summary reader" << std::endl; + return; + } + + safe_edge::edge::VehicleEdgeSummary sample{}; + eprosima::safedds::dds::SampleInfo info{}; + + while (typed_reader->take_next_sample(sample, info) == eprosima::safedds::dds::ReturnCode::OK) + { + if (info.valid_data) + { + owner_.on_vehicle_edge_summary_received(sample); + } + } +} + +EdgeGatewayNode::ChargerLocationListener::ChargerLocationListener(EdgeGatewayNode& owner) + : owner_(owner) +{ +} + +void EdgeGatewayNode::ChargerLocationListener::on_data_available( + eprosima::safedds::dds::DataReader& reader) noexcept +{ + auto* typed_reader = + eprosima::safedds::dds::TypedDataReader::downcast(reader); + + if (nullptr == typed_reader) + { + std::cerr << "[edge_gateway] Failed to downcast charger location reader" << std::endl; + return; + } + + safe_edge::pilot_server::ChargerLocation sample{}; + eprosima::safedds::dds::SampleInfo info{}; + + while (typed_reader->take_next_sample(sample, info) == eprosima::safedds::dds::ReturnCode::OK) + { + if (info.valid_data) + { + owner_.on_charger_location_received(sample); + } + } +} + +EdgeGatewayNode::HeartbeatListener::HeartbeatListener(EdgeGatewayNode& owner) + : owner_(owner) +{ +} + +void EdgeGatewayNode::HeartbeatListener::on_data_available( + eprosima::safedds::dds::DataReader& reader) noexcept +{ + auto* typed_reader = + eprosima::safedds::dds::TypedDataReader::downcast(reader); + + if (nullptr == typed_reader) + { + std::cerr << "[edge_gateway] Failed to downcast heartbeat reader" << std::endl; + return; + } + + safe_edge::common::ServiceHeartbeat sample{}; + eprosima::safedds::dds::SampleInfo info{}; + + while (typed_reader->take_next_sample(sample, info) == eprosima::safedds::dds::ReturnCode::OK) + { + if (info.valid_data) + { + owner_.on_server_heartbeat_received(sample); + } + } +} + +EdgeGatewayNode::EdgeGatewayNode(const common::RuntimeConfig& runtime_config) + : runtime_config_(runtime_config) + , header_factory_(runtime_config.source_name) + , participant_listener_(*this) + , vehicle_edge_summary_listener_(*this) + , charger_location_listener_(*this) + , heartbeat_listener_(*this) + , status_timer_(STATUS_INTERVAL) +{ +} + +int EdgeGatewayNode::run() +{ + if (!initialize()) + { + return 1; + } + + start_timers(); + std::cout << "[edge_gateway] [START] Running with participant port " << runtime_config_.participant_port << std::endl; + + while (true) + { + while (executor_->has_pending_work()) + { + executor_->spin(eprosima::safedds::execution::TIME_ZERO); + } + + if (status_timer_.is_triggered_and_reset()) + { + publish_edge_gateway_status(); + } + + executor_->spin(next_wakeup_time()); + } + + return 0; +} + +bool EdgeGatewayNode::initialize() +{ + return create_participant() && + register_types() && + create_topics() && + create_endpoints() && + enable_entities() && + create_executor(); +} + +bool EdgeGatewayNode::create_participant() +{ + eprosima::safedds::dds::DomainParticipantQos participant_qos{}; + eprosima::safedds::memory::container::StaticString256 participant_name(runtime_config_.participant_name.c_str()); + participant_qos.participant_name() = participant_name; + participant_qos.wire_protocol_qos().announced_locator = eprosima::safedds::transport::Locator::from_ipv4( + {127, 0, 0, 1}, + runtime_config_.participant_port); + + participant_ = factory_.create_participant( + runtime_config_.domain_id, + participant_qos, + &participant_listener_, + eprosima::safedds::dds::PUBLICATION_MATCHED_STATUS | + eprosima::safedds::dds::SUBSCRIPTION_MATCHED_STATUS); + + if (nullptr == participant_) + { + std::cerr << "[edge_gateway] Failed to create participant" << std::endl; + return false; + } + + return true; +} + +bool EdgeGatewayNode::register_types() +{ + return register_type(*participant_, vehicle_edge_summary_type_support_, "VehicleEdgeSummary") && + register_type(*participant_, energy_advisory_type_support_, "EnergyAdvisory") && + register_type(*participant_, edge_gateway_status_type_support_, "EdgeGatewayStatus") && + register_type(*participant_, charger_location_type_support_, "ChargerLocation") && + register_type(*participant_, service_heartbeat_type_support_, "ServiceHeartbeat"); +} + +bool EdgeGatewayNode::create_topics() +{ + vehicle_edge_summary_topic_name_ = eprosima::safedds::memory::container::StaticString256( + common::topic_names::vehicle_edge_summary()); + vehicle_edge_summary_topic_ = create_topic( + *participant_, vehicle_edge_summary_topic_name_, vehicle_edge_summary_type_support_); + if (nullptr == vehicle_edge_summary_topic_) + { + std::cerr << "[edge_gateway] Failed to create topic: vehicle_edge_summary" << std::endl; + return false; + } + + energy_advisory_topic_name_ = eprosima::safedds::memory::container::StaticString256( + common::topic_names::energy_advisory()); + energy_advisory_topic_ = create_topic( + *participant_, energy_advisory_topic_name_, energy_advisory_type_support_); + if (nullptr == energy_advisory_topic_) + { + std::cerr << "[edge_gateway] Failed to create topic: energy_advisory" << std::endl; + return false; + } + + edge_gateway_status_topic_name_ = eprosima::safedds::memory::container::StaticString256( + common::topic_names::edge_gateway_status()); + edge_gateway_status_topic_ = create_topic( + *participant_, edge_gateway_status_topic_name_, edge_gateway_status_type_support_); + if (nullptr == edge_gateway_status_topic_) + { + std::cerr << "[edge_gateway] Failed to create topic: edge_gateway_status" << std::endl; + return false; + } + + charger_location_topic_name_ = eprosima::safedds::memory::container::StaticString256( + common::topic_names::charger_locations()); + charger_location_topic_ = create_topic( + *participant_, charger_location_topic_name_, charger_location_type_support_); + if (nullptr == charger_location_topic_) + { + std::cerr << "[edge_gateway] Failed to create topic: charger_locations" << std::endl; + return false; + } + + service_heartbeat_topic_name_ = eprosima::safedds::memory::container::StaticString256( + common::topic_names::service_heartbeat()); + service_heartbeat_topic_ = create_topic( + *participant_, service_heartbeat_topic_name_, service_heartbeat_type_support_); + if (nullptr == service_heartbeat_topic_) + { + std::cerr << "[edge_gateway] Failed to create topic: service_heartbeat" << std::endl; + return false; + } + + return true; +} + +bool EdgeGatewayNode::create_endpoints() +{ + eprosima::safedds::dds::PublisherQos publisher_qos{}; + publisher_ = participant_->create_publisher( + publisher_qos, + nullptr, + eprosima::safedds::dds::NONE_STATUS_MASK); + + eprosima::safedds::dds::SubscriberQos subscriber_qos{}; + subscriber_ = participant_->create_subscriber( + subscriber_qos, + nullptr, + eprosima::safedds::dds::NONE_STATUS_MASK); + + if (nullptr == publisher_ || nullptr == subscriber_) + { + std::cerr << "[edge_gateway] Failed to create publisher or subscriber" << std::endl; + return false; + } + + eprosima::safedds::dds::DataWriterQos writer_qos{}; + writer_qos.reliability().kind = eprosima::safedds::dds::ReliabilityQosPolicyKind::RELIABLE_RELIABILITY_QOS; + + energy_advisory_datawriter_ = publisher_->create_datawriter( + *energy_advisory_topic_, + writer_qos, + nullptr, + eprosima::safedds::dds::NONE_STATUS_MASK); + edge_gateway_status_datawriter_ = publisher_->create_datawriter( + *edge_gateway_status_topic_, + writer_qos, + nullptr, + eprosima::safedds::dds::NONE_STATUS_MASK); + + energy_advisory_writer_ = downcast_writer( + energy_advisory_datawriter_); + edge_gateway_status_writer_ = downcast_writer( + edge_gateway_status_datawriter_); + + eprosima::safedds::dds::DataReaderQos reader_qos{}; + reader_qos.reliability().kind = eprosima::safedds::dds::ReliabilityQosPolicyKind::RELIABLE_RELIABILITY_QOS; + + vehicle_edge_summary_datareader_ = subscriber_->create_datareader( + *vehicle_edge_summary_topic_, + reader_qos, + &vehicle_edge_summary_listener_, + eprosima::safedds::dds::DATA_AVAILABLE_STATUS); + vehicle_edge_summary_reader_ = downcast_reader( + vehicle_edge_summary_datareader_); + + charger_location_datareader_ = subscriber_->create_datareader( + *charger_location_topic_, + reader_qos, + &charger_location_listener_, + eprosima::safedds::dds::DATA_AVAILABLE_STATUS); + charger_location_reader_ = downcast_reader( + charger_location_datareader_); + + service_heartbeat_datareader_ = subscriber_->create_datareader( + *service_heartbeat_topic_, + reader_qos, + &heartbeat_listener_, + eprosima::safedds::dds::DATA_AVAILABLE_STATUS); + heartbeat_reader_ = downcast_reader( + service_heartbeat_datareader_); + + const bool success = nullptr != energy_advisory_writer_ && + nullptr != edge_gateway_status_writer_ && + nullptr != vehicle_edge_summary_reader_ && + nullptr != charger_location_reader_ && + nullptr != heartbeat_reader_; + + if (!success) + { + std::cerr << "[edge_gateway] Failed to create endpoints" << std::endl; + return false; + } + + return true; +} + +bool EdgeGatewayNode::enable_entities() +{ + bool enabled = true; + enabled = enabled && (eprosima::safedds::dds::ReturnCode::OK == publisher_->enable()); + enabled = enabled && (eprosima::safedds::dds::ReturnCode::OK == energy_advisory_datawriter_->enable()); + enabled = enabled && (eprosima::safedds::dds::ReturnCode::OK == edge_gateway_status_datawriter_->enable()); + enabled = enabled && (eprosima::safedds::dds::ReturnCode::OK == subscriber_->enable()); + enabled = enabled && (eprosima::safedds::dds::ReturnCode::OK == vehicle_edge_summary_datareader_->enable()); + enabled = enabled && (eprosima::safedds::dds::ReturnCode::OK == charger_location_datareader_->enable()); + enabled = enabled && (eprosima::safedds::dds::ReturnCode::OK == service_heartbeat_datareader_->enable()); + enabled = enabled && (eprosima::safedds::dds::ReturnCode::OK == participant_->enable()); + + if (!enabled) + { + std::cerr << "[edge_gateway] Failed to enable DDS entities" << std::endl; + } + + return enabled; +} + +bool EdgeGatewayNode::create_executor() +{ + executor_ = factory_.create_default_executor(); + + if (nullptr == executor_) + { + std::cerr << "[edge_gateway] Failed to create executor" << std::endl; + return false; + } + + return true; +} + +void EdgeGatewayNode::start_timers() noexcept +{ + status_timer_.start(); +} + +void EdgeGatewayNode::on_vehicle_edge_summary_received( + const safe_edge::edge::VehicleEdgeSummary& summary) +{ + std::cout << "[edge_gateway] Received VehicleEdgeSummary soc=" << summary.soc_pct + << " v2g_ready=" << summary.v2g_ready + << " mode=" << static_cast(summary.current_mode) << std::endl; + + safe_edge::edge::EnergyAdvisory advisory = logic::EdgeAdvisor::evaluate( + summary, cached_chargers_, cached_charger_count_); + advisory.header = header_factory_.make_header("energy_advisory"); + publish_energy_advisory(advisory); +} + +void EdgeGatewayNode::on_charger_location_received( + const safe_edge::pilot_server::ChargerLocation& location) +{ + if (cached_charger_count_ < 3) + { + cached_chargers_[cached_charger_count_++] = location; + } + last_server_sync_ms_ = common::HeaderFactory::now_ms(); + + std::cout << "[edge_gateway] Received ChargerLocation id=" << location.id + << " name=" << location.name << std::endl; +} + +void EdgeGatewayNode::publish_energy_advisory(const safe_edge::edge::EnergyAdvisory& advisory) +{ + if (eprosima::safedds::dds::ReturnCode::OK != + energy_advisory_writer_->write(advisory, eprosima::safedds::dds::HANDLE_NIL)) + { + std::cerr << "[edge_gateway] Failed to publish EnergyAdvisory" << std::endl; + return; + } + + std::cout << "[edge_gateway] Published EnergyAdvisory mode=" << static_cast(advisory.suggested_mode) + << " reason=" << advisory.advisory_reason << std::endl; +} + +void EdgeGatewayNode::on_server_heartbeat_received( + const safe_edge::common::ServiceHeartbeat& heartbeat) +{ + if (heartbeat.service_name != "server") + { + return; + } + last_server_hb_ms_ = common::HeaderFactory::now_ms(); + server_available_ = true; +} + +void EdgeGatewayNode::publish_edge_gateway_status() +{ + constexpr uint64_t SERVER_HB_TIMEOUT_MS = 10000U; + if (last_server_hb_ms_ > 0U && + (common::HeaderFactory::now_ms() - last_server_hb_ms_) > SERVER_HB_TIMEOUT_MS) + { + server_available_ = false; + } + + safe_edge::edge::EdgeGatewayStatus status; + status.header = header_factory_.make_header("edge_gateway_status"); + status.status = server_available_ + ? safe_edge::common::HealthStatus::HEALTH_OK + : safe_edge::common::HealthStatus::HEALTH_DEGRADED; + status.last_server_sync_ms = last_server_sync_ms_; + status.detail = server_available_ + ? "edge connected, server synced" + : "edge connected, server_down"; + + if (eprosima::safedds::dds::ReturnCode::OK != + edge_gateway_status_writer_->write(status, eprosima::safedds::dds::HANDLE_NIL)) + { + std::cerr << "[edge_gateway] Failed to publish EdgeGatewayStatus" << std::endl; + return; + } + + std::cout << "[edge_gateway] Published EdgeGatewayStatus status=" + << (server_available_ ? "OK" : "DEGRADED") << std::endl; +} + +void EdgeGatewayNode::log_subscription_match(const char* topic_name, int32_t total_count) const +{ + std::cout << "[edge_gateway] Subscription matched on " << topic_name + << " total_count=" << total_count << std::endl; +} + +void EdgeGatewayNode::log_publication_match(const char* topic_name, int32_t total_count) const +{ + std::cout << "[edge_gateway] Publication matched on " << topic_name + << " total_count=" << total_count << std::endl; +} + +eprosima::safedds::execution::TimePoint EdgeGatewayNode::next_wakeup_time() const noexcept +{ + eprosima::safedds::execution::TimePoint next = executor_->get_next_work_timepoint(); + next = eprosima::safedds::execution::TimePoint::min(next, status_timer_.next_trigger()); + return next; +} + +} // namespace nodes +} // namespace edge_module +} // namespace safe_edge diff --git a/safe_dds/edge/test/test_edge_integration.cpp b/safe_dds/edge/test/test_edge_integration.cpp new file mode 100644 index 0000000..3e942e7 --- /dev/null +++ b/safe_dds/edge/test/test_edge_integration.cpp @@ -0,0 +1,527 @@ +// test_edge_integration.cpp — Safe DDS variant +// +// Integration tests for EdgeGatewayNode health state machine. +// Starts safe_edge_edge_gateway as a subprocess, runs all suites, stops it. +// +// Usage: +// ./test_edge_integration +// ./test_edge_integration --gtest_output=xml:results.xml +// +// Environment variables: +// SAFE_EDGE_EDGE_BIN path to safe_edge_edge_gateway (default: safe_edge_edge_gateway) + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +// --------------------------------------------------------------------------- +// Global peers: point at the edge participant (port 8030) +// --------------------------------------------------------------------------- + +static eprosima::safedds::memory::container::StaticList< + eprosima::safedds::transport::Locator, 1U> g_peers; + +static bool init_peers() +{ + g_peers.add(eprosima::safedds::transport::Locator::from_ipv4({127, 0, 0, 1}, 8030U)); + return true; +} + +static const bool PEERS_INIT = init_peers(); + +static const char* EDGE_PID_FILE = "/tmp/safe_edge_edge_gateway_test.pid"; +static const char* EDGE_LOG_FILE = "/tmp/safe_edge_edge_gateway_test.log"; + +// Each test gets a unique port so there is no binding conflict when the OS +// has not yet released the previous socket. +static uint16_t next_test_port() +{ + static std::atomic next_port{8050U}; + return next_port.fetch_add(1U, std::memory_order_relaxed); +} + +static eprosima::safedds::dds::DomainParticipant* make_participant( + eprosima::safedds::dds::DomainParticipantFactory& factory, + const char* name, uint16_t port) +{ + eprosima::safedds::dds::DomainParticipantQos qos{}; + eprosima::safedds::memory::container::StaticString256 sname(name); + qos.participant_name() = sname; + qos.wire_protocol_qos().announced_locator = + eprosima::safedds::transport::Locator::from_ipv4({127, 0, 0, 1}, port); + qos.wire_protocol_qos().use_multicast_discovery = false; + qos.wire_protocol_qos().initial_peers = &g_peers; + return factory.create_participant(0U, qos, nullptr, + eprosima::safedds::dds::NONE_STATUS_MASK); +} + +static void destroy_participant( + eprosima::safedds::dds::DomainParticipantFactory& factory, + eprosima::safedds::dds::DomainParticipant*& participant) noexcept +{ + if (participant != nullptr) + { + (void)participant->delete_contained_entities(); + (void)factory.delete_participant(participant); + participant = nullptr; + std::this_thread::sleep_for(std::chrono::milliseconds(250)); + } +} + +// --------------------------------------------------------------------------- +// Global environment: lifecycle of safe_edge_edge_gateway subprocess +// --------------------------------------------------------------------------- + +class EdgeEnvironment : public ::testing::Environment +{ +public: + void SetUp() override + { + const char* bin = std::getenv("SAFE_EDGE_EDGE_BIN"); + const std::string edge_bin = (bin != nullptr ? bin : "safe_edge_edge_gateway"); + const std::string cmd = + "sh -c 'rm -f " + std::string(EDGE_PID_FILE) + + "; " + edge_bin + " >" + EDGE_LOG_FILE + " 2>&1 & echo $! > " + + EDGE_PID_FILE + "'"; + ASSERT_EQ(0, std::system(cmd.c_str())) + << "Failed to launch safe_edge_edge_gateway. " + "Set SAFE_EDGE_EDGE_BIN to the full path if needed."; + std::cout << "[env] safe_edge_edge_gateway started — waiting 5 s for init...\n"; + std::this_thread::sleep_for(std::chrono::seconds(5)); + std::cout << "[env] Edge ready.\n"; + } + + void TearDown() override + { + std::cout << "[env] safe_edge_edge_gateway log:\n"; + std::system((std::string("sh -c 'if [ -f ") + EDGE_LOG_FILE + + " ]; then cat " + EDGE_LOG_FILE + "; else echo missing log; fi'").c_str()); + std::cout << "[env] Stopping safe_edge_edge_gateway...\n"; + const std::string stop_cmd = + "sh -c '" + "if [ -f " + std::string(EDGE_PID_FILE) + " ]; then " + "pid=$(cat " + std::string(EDGE_PID_FILE) + "); " + "kill \"$pid\" 2>/dev/null || true; " + "sleep 1; " + "kill -9 \"$pid\" 2>/dev/null || true; " + "rm -f " + std::string(EDGE_PID_FILE) + "; " + "fi; " + "pkill -f safe_edge_edge_gateway 2>/dev/null || true" + "'"; + std::system(stop_cmd.c_str()); + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + } +}; + +// --------------------------------------------------------------------------- +// Fixture: mock server participant +// Publishes: ServiceHeartbeat, ChargerLocation +// Reads: EdgeGatewayStatus +// --------------------------------------------------------------------------- + +class MockServerFixture : public ::testing::Test +{ +protected: + void SetUp() override + { + (void)PEERS_INIT; + participant_ = make_participant(factory_, "TestMockServer", next_test_port()); + ASSERT_NE(nullptr, participant_); + + ASSERT_EQ(eprosima::safedds::dds::ReturnCode::OK, + hb_ts_.register_type(*participant_, hb_ts_.get_type_name())); + ASSERT_EQ(eprosima::safedds::dds::ReturnCode::OK, + loc_ts_.register_type(*participant_, loc_ts_.get_type_name())); + ASSERT_EQ(eprosima::safedds::dds::ReturnCode::OK, + status_ts_.register_type(*participant_, status_ts_.get_type_name())); + + namespace TN = safe_edge::edge_module::common::topic_names; + eprosima::safedds::memory::container::StaticString256 + hb_name(TN::service_heartbeat()), + loc_name(TN::charger_locations()), + status_name(TN::edge_gateway_status()); + + hb_topic_ = participant_->create_topic(hb_name, hb_ts_.get_type_name(), + eprosima::safedds::dds::TopicQos{}, nullptr, + eprosima::safedds::dds::NONE_STATUS_MASK); + loc_topic_ = participant_->create_topic(loc_name, loc_ts_.get_type_name(), + eprosima::safedds::dds::TopicQos{}, nullptr, + eprosima::safedds::dds::NONE_STATUS_MASK); + status_topic_ = participant_->create_topic(status_name, status_ts_.get_type_name(), + eprosima::safedds::dds::TopicQos{}, nullptr, + eprosima::safedds::dds::NONE_STATUS_MASK); + ASSERT_NE(nullptr, hb_topic_); + ASSERT_NE(nullptr, loc_topic_); + ASSERT_NE(nullptr, status_topic_); + + publisher_ = participant_->create_publisher( + eprosima::safedds::dds::PublisherQos{}, nullptr, + eprosima::safedds::dds::NONE_STATUS_MASK); + subscriber_ = participant_->create_subscriber( + eprosima::safedds::dds::SubscriberQos{}, nullptr, + eprosima::safedds::dds::NONE_STATUS_MASK); + ASSERT_NE(nullptr, publisher_); + ASSERT_NE(nullptr, subscriber_); + + eprosima::safedds::dds::DataWriterQos wqos{}; + wqos.reliability().kind = + eprosima::safedds::dds::ReliabilityQosPolicyKind::RELIABLE_RELIABILITY_QOS; + eprosima::safedds::dds::DataReaderQos rqos{}; + rqos.reliability().kind = + eprosima::safedds::dds::ReliabilityQosPolicyKind::RELIABLE_RELIABILITY_QOS; + + hb_wb_ = publisher_->create_datawriter(*hb_topic_, wqos, nullptr, + eprosima::safedds::dds::NONE_STATUS_MASK); + loc_wb_ = publisher_->create_datawriter(*loc_topic_, wqos, nullptr, + eprosima::safedds::dds::NONE_STATUS_MASK); + status_rb_ = subscriber_->create_datareader(*status_topic_, rqos, nullptr, + eprosima::safedds::dds::NONE_STATUS_MASK); + ASSERT_NE(nullptr, hb_wb_); + ASSERT_NE(nullptr, loc_wb_); + ASSERT_NE(nullptr, status_rb_); + + hb_writer_ = eprosima::safedds::dds::TypedDataWriter< + safe_edge::common::ServiceHeartbeatTypeSupport>::downcast(*hb_wb_); + loc_writer_ = eprosima::safedds::dds::TypedDataWriter< + safe_edge::pilot_server::ChargerLocationTypeSupport>::downcast(*loc_wb_); + status_reader_ = eprosima::safedds::dds::TypedDataReader< + safe_edge::edge::EdgeGatewayStatusTypeSupport>::downcast(*status_rb_); + ASSERT_NE(nullptr, hb_writer_); + ASSERT_NE(nullptr, loc_writer_); + ASSERT_NE(nullptr, status_reader_); + + // Enable participant FIRST so the transport starts before sub-entities bind. + ASSERT_EQ(eprosima::safedds::dds::ReturnCode::OK, participant_->enable()); + ASSERT_EQ(eprosima::safedds::dds::ReturnCode::OK, publisher_->enable()); + ASSERT_EQ(eprosima::safedds::dds::ReturnCode::OK, subscriber_->enable()); + ASSERT_EQ(eprosima::safedds::dds::ReturnCode::OK, hb_wb_->enable()); + ASSERT_EQ(eprosima::safedds::dds::ReturnCode::OK, loc_wb_->enable()); + ASSERT_EQ(eprosima::safedds::dds::ReturnCode::OK, status_rb_->enable()); + + // Create executor so we can drive SafeDDS I/O from the test thread. + executor_ = factory_.create_default_executor(); + ASSERT_NE(nullptr, executor_); + + // Wait for discovery while spinning so SPDP exchange completes. + spin_for(std::chrono::seconds(3)); + } + + void TearDown() override + { + executor_ = nullptr; + hb_writer_ = nullptr; + loc_writer_ = nullptr; + status_reader_= nullptr; + hb_wb_ = nullptr; + loc_wb_ = nullptr; + status_rb_ = nullptr; + publisher_ = nullptr; + subscriber_ = nullptr; + hb_topic_ = nullptr; + loc_topic_ = nullptr; + status_topic_ = nullptr; + destroy_participant(factory_, participant_); + } + + // Drive the SafeDDS executor for the given duration (single-threaded I/O). + void spin_for(std::chrono::milliseconds dur) + { + const auto end = std::chrono::steady_clock::now() + dur; + while (std::chrono::steady_clock::now() < end) + { + if (executor_ != nullptr) + { + while (executor_->has_pending_work()) + { + executor_->spin(eprosima::safedds::execution::TIME_ZERO); + } + } + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } + } + + void send_heartbeat() + { + safe_edge::common::ServiceHeartbeat hb{}; + hb.service_name = "server"; + hb_writer_->write(hb, eprosima::safedds::dds::HANDLE_NIL); + } + + bool wait_for_status(safe_edge::common::HealthStatus expected, int timeout_s) + { + const auto deadline = + std::chrono::steady_clock::now() + std::chrono::seconds(timeout_s); + while (std::chrono::steady_clock::now() < deadline) + { + if (executor_ != nullptr) + { + while (executor_->has_pending_work()) + { + executor_->spin(eprosima::safedds::execution::TIME_ZERO); + } + } + + safe_edge::edge::EdgeGatewayStatus sample{}; + eprosima::safedds::dds::SampleInfo info{}; + if (status_reader_->take_next_sample(sample, info) == + eprosima::safedds::dds::ReturnCode::OK && info.valid_data) + { + const bool is_ok = + sample.status == safe_edge::common::HealthStatus::HEALTH_OK; + std::cout << " [dds] EdgeGatewayStatus=" + << (is_ok ? "OK" : "DEGRADED") << "\n"; + if (sample.status == expected) + { + return true; + } + } + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + return false; + } + + eprosima::safedds::dds::DomainParticipantFactory factory_; + eprosima::safedds::execution::ISpinnable* executor_ = nullptr; + eprosima::safedds::dds::DomainParticipant* participant_ = nullptr; + eprosima::safedds::dds::Publisher* publisher_ = nullptr; + eprosima::safedds::dds::Subscriber* subscriber_ = nullptr; + eprosima::safedds::dds::Topic* hb_topic_ = nullptr; + eprosima::safedds::dds::Topic* loc_topic_ = nullptr; + eprosima::safedds::dds::Topic* status_topic_= nullptr; + eprosima::safedds::dds::DataWriter* hb_wb_ = nullptr; + eprosima::safedds::dds::DataWriter* loc_wb_ = nullptr; + eprosima::safedds::dds::DataReader* status_rb_ = nullptr; + + safe_edge::common::ServiceHeartbeatTypeSupport hb_ts_; + safe_edge::pilot_server::ChargerLocationTypeSupport loc_ts_; + safe_edge::edge::EdgeGatewayStatusTypeSupport status_ts_; + + eprosima::safedds::dds::TypedDataWriter< + safe_edge::common::ServiceHeartbeatTypeSupport>* hb_writer_ = nullptr; + eprosima::safedds::dds::TypedDataWriter< + safe_edge::pilot_server::ChargerLocationTypeSupport>* loc_writer_ = nullptr; + eprosima::safedds::dds::TypedDataReader< + safe_edge::edge::EdgeGatewayStatusTypeSupport>* status_reader_= nullptr; +}; + +// --------------------------------------------------------------------------- +// 1. DEGRADED when no server present +// --------------------------------------------------------------------------- + +TEST_F(MockServerFixture, EdgeStatusIsDegradedWithoutServer) +{ + EXPECT_TRUE(wait_for_status(safe_edge::common::HealthStatus::HEALTH_DEGRADED, 12)) + << "Expected DEGRADED within 12 s with no server heartbeat"; +} + +// --------------------------------------------------------------------------- +// 2. OK when server publishes heartbeats +// --------------------------------------------------------------------------- + +TEST_F(MockServerFixture, EdgeStatusIsOkWithServer) +{ + for (int i = 0; i < 3; ++i) + { + send_heartbeat(); + spin_for(std::chrono::seconds(2)); + } + EXPECT_TRUE(wait_for_status(safe_edge::common::HealthStatus::HEALTH_OK, 12)) + << "Expected OK within 12 s after sending heartbeats"; +} + +// --------------------------------------------------------------------------- +// 3. Recovers from DEGRADED to OK when server starts +// --------------------------------------------------------------------------- + +TEST_F(MockServerFixture, EdgeRecoversDegradedToOk) +{ + ASSERT_TRUE(wait_for_status(safe_edge::common::HealthStatus::HEALTH_DEGRADED, 12)) + << "Expected initial DEGRADED state"; + + for (int i = 0; i < 3; ++i) + { + send_heartbeat(); + spin_for(std::chrono::seconds(2)); + } + EXPECT_TRUE(wait_for_status(safe_edge::common::HealthStatus::HEALTH_OK, 12)) + << "Expected OK after heartbeats sent"; +} + +// --------------------------------------------------------------------------- +// 4. Transitions from OK to DEGRADED when server stops +// --------------------------------------------------------------------------- +// Single-threaded design: heartbeat sending and status polling are interleaved +// in the same spin loop to avoid concurrent access to the DDS writer. + +TEST_F(MockServerFixture, EdgeTransitionsOkToDegraded) +{ + // Phase 1: send heartbeats every 2 s for up to 12 s; expect HEALTH_OK. + const auto hb_phase_end = + std::chrono::steady_clock::now() + std::chrono::seconds(12); + auto last_hb = std::chrono::steady_clock::now() - std::chrono::seconds(3); + bool ok_seen = false; + + while (std::chrono::steady_clock::now() < hb_phase_end) + { + if (executor_ != nullptr) + { + while (executor_->has_pending_work()) + { + executor_->spin(eprosima::safedds::execution::TIME_ZERO); + } + } + + const auto now = std::chrono::steady_clock::now(); + if (std::chrono::duration_cast( + now - last_hb).count() >= 2000) + { + send_heartbeat(); + last_hb = now; + } + + safe_edge::edge::EdgeGatewayStatus sample{}; + eprosima::safedds::dds::SampleInfo info{}; + if (status_reader_->take_next_sample(sample, info) == + eprosima::safedds::dds::ReturnCode::OK && info.valid_data && + sample.status == safe_edge::common::HealthStatus::HEALTH_OK) + { + ok_seen = true; + std::cout << " [dds] EdgeGatewayStatus=OK\n"; + } + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + ASSERT_TRUE(ok_seen) << "Expected HEALTH_OK while heartbeats running"; + + // Phase 2: stop sending; edge should go DEGRADED after 10 s HB timeout + ≤5 s status interval. + EXPECT_TRUE(wait_for_status(safe_edge::common::HealthStatus::HEALTH_DEGRADED, 20)) + << "Expected DEGRADED within 20 s after heartbeats stopped"; +} + +// --------------------------------------------------------------------------- +// 5. Status published periodically (status_interval_sec = 5) +// --------------------------------------------------------------------------- + +TEST(EdgePublishesStatusPeriodically, AtLeastTwoSamplesIn15Seconds) +{ + (void)PEERS_INIT; + eprosima::safedds::dds::DomainParticipantFactory factory; + auto* participant = make_participant(factory, "TestPeriodic", next_test_port()); + ASSERT_NE(nullptr, participant); + + safe_edge::edge::EdgeGatewayStatusTypeSupport status_ts; + ASSERT_EQ(eprosima::safedds::dds::ReturnCode::OK, + status_ts.register_type(*participant, status_ts.get_type_name())); + + eprosima::safedds::memory::container::StaticString256 tname( + safe_edge::edge_module::common::topic_names::edge_gateway_status()); + auto* topic = participant->create_topic(tname, status_ts.get_type_name(), + eprosima::safedds::dds::TopicQos{}, nullptr, + eprosima::safedds::dds::NONE_STATUS_MASK); + ASSERT_NE(nullptr, topic); + + auto* sub = participant->create_subscriber( + eprosima::safedds::dds::SubscriberQos{}, nullptr, + eprosima::safedds::dds::NONE_STATUS_MASK); + ASSERT_NE(nullptr, sub); + + eprosima::safedds::dds::DataReaderQos rqos{}; + rqos.reliability().kind = + eprosima::safedds::dds::ReliabilityQosPolicyKind::RELIABLE_RELIABILITY_QOS; + auto* rb = sub->create_datareader(*topic, rqos, nullptr, + eprosima::safedds::dds::NONE_STATUS_MASK); + ASSERT_NE(nullptr, rb); + + auto* reader = eprosima::safedds::dds::TypedDataReader< + safe_edge::edge::EdgeGatewayStatusTypeSupport>::downcast(*rb); + ASSERT_NE(nullptr, reader); + + // Enable participant FIRST. + ASSERT_EQ(eprosima::safedds::dds::ReturnCode::OK, participant->enable()); + ASSERT_EQ(eprosima::safedds::dds::ReturnCode::OK, sub->enable()); + ASSERT_EQ(eprosima::safedds::dds::ReturnCode::OK, rb->enable()); + + auto* executor = factory.create_default_executor(); + ASSERT_NE(nullptr, executor); + + // Discovery wait (spin so SPDP exchange completes). + { + const auto disc_end = std::chrono::steady_clock::now() + std::chrono::seconds(3); + while (std::chrono::steady_clock::now() < disc_end) + { + while (executor->has_pending_work()) + { + executor->spin(eprosima::safedds::execution::TIME_ZERO); + } + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } + } + + int count = 0; + const auto end = std::chrono::steady_clock::now() + std::chrono::seconds(15); + while (std::chrono::steady_clock::now() < end) + { + while (executor->has_pending_work()) + { + executor->spin(eprosima::safedds::execution::TIME_ZERO); + } + + safe_edge::edge::EdgeGatewayStatus sample{}; + eprosima::safedds::dds::SampleInfo info{}; + if (reader->take_next_sample(sample, info) == + eprosima::safedds::dds::ReturnCode::OK && info.valid_data) + { + ++count; + std::cout << " [dds] Status sample #" << count << "\n"; + } + else + { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + } + + EXPECT_GE(count, 2) + << "Expected >=2 EdgeGatewayStatus samples in 15 s, got " << count; + + executor = nullptr; + destroy_participant(factory, participant); +} + +// --------------------------------------------------------------------------- +// main +// --------------------------------------------------------------------------- + +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + ::testing::AddGlobalTestEnvironment(new EdgeEnvironment()); + return RUN_ALL_TESTS(); +} diff --git a/safe_dds/idl/SafeDDSGenAux.hpp b/safe_dds/idl/SafeDDSGenAux.hpp new file mode 100644 index 0000000..2ae8678 --- /dev/null +++ b/safe_dds/idl/SafeDDSGenAux.hpp @@ -0,0 +1,2467 @@ +/** + * Copyright (C) 2024, Proyectos y Sistemas de Mantenimiento SL (eProsima) + * + * This program is commercial software licensed under the terms of the + * eProsima Software License Agreement Rev 03 (the "License") + * + * You may obtain a copy of the License at + * https://www.eprosima.com/licenses/LICENSE-REV03 + * + */ + +/** + * @file SafeDDSGenAux.hpp + */ + +#ifndef SAFEDDS_SAFEDDSGEN_SAFEDDSGENAUX_HPP +#define SAFEDDS_SAFEDDSGEN_SAFEDDSGENAUX_HPP + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +namespace eprosima { +namespace safedds { +namespace gen { + +//! Forward declarations +class SafeDDSTypeSupportSerializer; +class SafeDDSTypeSupportDeserializer; + +/** + * @brief SafeDDSTypeSupportSerializer class. + */ +class SafeDDSTypeSupportSerializer : + public safedds::serialization::cdr::Serializer +{ +public: + + /** + * @brief Constructor + * + * @param buffer The byte array view used for serialization. + * @param endianness The endianness to use for serialization. + * @param xcdr_version The XCDR version to use for serialization. + */ + SafeDDSTypeSupportSerializer( + safedds::memory::IByteArrayView& buffer, + safedds::platform::Endianness endianness, + safedds::serialization::cdr::XCDRVersion xcdr_version) noexcept + : safedds::serialization::cdr::Serializer(buffer, endianness, xcdr_version) + , endianness_(endianness) + , encoding_algorithm_( + safedds::serialization::cdr::XCDRVersion::XCDRV1 == xcdr_version ? + EncodingAlgorithm::PLAIN_CDR : + EncodingAlgorithm::PLAIN_CDR2) + { + } + + /** + * @brief Constructor for emulated serialization. + * + * @param endianness The endianness to use for serialization. + * @param xcdr_version The XCDR version to use for serialization. + */ + SafeDDSTypeSupportSerializer( + safedds::platform::Endianness endianness, + safedds::serialization::cdr::XCDRVersion xcdr_version) noexcept + : safedds::serialization::cdr::Serializer(endianness, xcdr_version) + , endianness_(endianness) + , encoding_algorithm_( + safedds::serialization::cdr::XCDRVersion::XCDRV1 == xcdr_version ? + EncodingAlgorithm::PLAIN_CDR : + EncodingAlgorithm::PLAIN_CDR2) + { + } + + /** + * @brief Get XCDR version + * + * @return XCDRVersion + */ + safedds::serialization::cdr::XCDRVersion get_xcdr_version() const + { + return xcdr_version_; + } + + /** + * @brief Retrieves the encoding algorithm. + * + * @return EncodingAlgorithm + */ + EncodingAlgorithm get_encoding_algorithm() const + { + return encoding_algorithm_; + } + + /** + * @brief Sets the encoding algorithm. + * + * @param encoding_algorithm The encoding algorithm to use for serialization. + * + * @return ReturnCode + */ + safedds::ReturnCode set_encoding_algorithm( + const EncodingAlgorithm& encoding_algorithm) + { + safedds::ReturnCode ret = safedds::ReturnCode::OK; + + // Check compatibility of XCDR version and encoding algorithm + if (safedds::serialization::cdr::XCDRVersion::XCDRV1 == xcdr_version_) + { + ret = (encoding_algorithm == EncodingAlgorithm::PLAIN_CDR) || + (encoding_algorithm == EncodingAlgorithm::PL_CDR) ? + safedds::ReturnCode::OK : + safedds::ReturnCode::ERROR; + } + else if (safedds::serialization::cdr::XCDRVersion::XCDRV2 == xcdr_version_) + { + ret = (encoding_algorithm == EncodingAlgorithm::PLAIN_CDR2) || + (encoding_algorithm == EncodingAlgorithm::PL_CDR2) || + (encoding_algorithm == EncodingAlgorithm::DELIMITED_CDR) ? + safedds::ReturnCode::OK : + safedds::ReturnCode::ERROR; + } + else + { + ret = safedds::ReturnCode::ERROR; + } + + if (safedds::ReturnCode::OK == ret) + { + encoding_algorithm_ = encoding_algorithm; + } + + return ret; + } + + /** + * @brief Begins the serialization of a type. + * + * @return ReturnCode + */ + safedds::ReturnCode begin_serialize_type() + { + safedds::ReturnCode ret = safedds::ReturnCode::OK; + + if (EncodingAlgorithm::PL_CDR2 == encoding_algorithm_ || + EncodingAlgorithm::DELIMITED_CDR == encoding_algorithm_) + { + ret = serializer_align_to(4U); + + if (safedds::ReturnCode::OK == ret) + { + if (!emulated_serialization_) + { + object_dheader_view_.mutable_set(&buffer_[position_], sizeof(uint32_t)); + } + + ret = serializer_skip(sizeof(uint32_t)); + } + + object_dheader_begin_position_ = position_; + } + + return ret; + } + + /** + * @brief Ends the serialization of a type. + * + * @return ReturnCode + */ + safedds::ReturnCode end_serialize_type() + { + safedds::ReturnCode ret = safedds::ReturnCode::OK; + + if (EncodingAlgorithm::PL_CDR == encoding_algorithm_) + { + uint8_t* dummy = nullptr; + ret = serialize_parameter(PID_LIST_END, dummy); + } + + if (safedds::ReturnCode::OK == ret && !emulated_serialization_ && + (EncodingAlgorithm::PL_CDR2 == encoding_algorithm_ || + EncodingAlgorithm::DELIMITED_CDR == encoding_algorithm_)) + { + uint32_t dheader_length = position_ - object_dheader_begin_position_; + SafeDDSTypeSupportSerializer dheader_length_serializer(object_dheader_view_, endianness_, xcdr_version_); + ret = dheader_length_serializer.serialize(dheader_length); + } + + return ret; + } + + /** + * @brief Serializes a type. + * + * @param id The parameter ID. + * @param value The value to serialize. + * + * @return ReturnCode + */ + template + safedds::ReturnCode serialize_type( + const uint32_t& id, + const T& value) + { + safedds::ReturnCode ret = safedds::ReturnCode::OK; + + if (EncodingAlgorithm::PL_CDR == encoding_algorithm_ || EncodingAlgorithm::PL_CDR2 == encoding_algorithm_) + { + ret = serialize_parameter(id, &value); + } + else if (EncodingAlgorithm::PLAIN_CDR == encoding_algorithm_ || + EncodingAlgorithm::PLAIN_CDR2 == encoding_algorithm_ || + EncodingAlgorithm::DELIMITED_CDR == encoding_algorithm_) + { + ret = serialize_plain_type(id, value); + } + else + { + ret = safedds::ReturnCode::ERROR; + } + + return ret; + } + + /** + * @brief Specialization for Optional type. + */ + template + safedds::ReturnCode serialize_type( + const uint32_t& id, + const memory::Optional& value) + { + safedds::ReturnCode ret = safedds::ReturnCode::OK; + + if ((EncodingAlgorithm::PL_CDR == encoding_algorithm_ || EncodingAlgorithm::PL_CDR2 == encoding_algorithm_) && + value.has_value()) + { + ret = serialize_parameter(id, &value.value()); + } + else if (EncodingAlgorithm::PLAIN_CDR == encoding_algorithm_) + { + ret = serialize_parameter(id, value.has_value() ? &value.value() : nullptr); + } + else if (EncodingAlgorithm::PLAIN_CDR2 == encoding_algorithm_ || + EncodingAlgorithm::DELIMITED_CDR == encoding_algorithm_) + { + ret = serialize(value.has_value()); + + if (safedds::ReturnCode::OK == ret && value.has_value()) + { + ret = serialize_type(id, value.value()); + } + } + else if (value.has_value()) + { + ret = safedds::ReturnCode::ERROR; + } + + return ret; + } + + /** + * @brief Serializes a type. + * + * @param id The parameter ID. + * @param value The value to serialize. + * + * @return ReturnCode + */ + template + safedds::ReturnCode serialize_type_key( + const uint32_t& id, + const T& value) + { + safedds::ReturnCode ret = + (EncodingAlgorithm::PLAIN_CDR2 == + encoding_algorithm_) ? safedds::ReturnCode::OK : safedds::ReturnCode::ERROR; + + if (safedds::ReturnCode::OK == ret) + { + serializing_key_ = true; + ret = serialize_plain_type(id, value); + serializing_key_ = false; + } + + return ret; + } + +private: + + /** + * @brief SerializerState struct. + */ + struct SerializerState + { + //! Attributes from base class + uint32_t position; //!< Position in the view. + uint32_t alignment_position; //!< Alignment position in the view. + bool native_endianness; //!< Working on native endianness + safedds::serialization::cdr::XCDRVersion xcdr_version; //!< XCDR version to use. + bool emulated_serialization; //!< Emulated serialization flag. + + //! Attributes from derived class + EncodingAlgorithm encoding_algorithm_; //!< The encoding algorithm to use. + safedds::platform::Endianness endianness_; //!< The endianness to use. + memory::byte_array::ByteArrayView object_dheader_view_; //!< The view for the dheader. + uint32_t object_dheader_begin_position_; //!< Initial position for the dheader. + bool serializing_key_; //!< Flag indicating if the serializer is serializing a key. + }; + + /** + * @brief Get the current state of the serializer. + * + * @return SerializerState + */ + SerializerState get_state() const + { + SerializerState state; + + state.position = position_; + state.alignment_position = alignment_position_; + state.native_endianness = native_endianness_; + state.xcdr_version = xcdr_version_; + state.emulated_serialization = emulated_serialization_; + state.encoding_algorithm_ = encoding_algorithm_; + state.endianness_ = endianness_; + state.object_dheader_view_ = object_dheader_view_; + state.object_dheader_begin_position_ = object_dheader_begin_position_; + state.serializing_key_ = serializing_key_; + + return state; + } + + /** + * @brief Set the state of the serializer. + * + * @param state The state to set. + */ + void set_state( + const SerializerState& state) + { + position_ = state.position; + alignment_position_ = state.alignment_position; + native_endianness_ = state.native_endianness; + xcdr_version_ = state.xcdr_version; + emulated_serialization_ = state.emulated_serialization; + encoding_algorithm_ = state.encoding_algorithm_; + endianness_ = state.endianness_; + object_dheader_view_ = state.object_dheader_view_; + object_dheader_begin_position_ = state.object_dheader_begin_position_; + serializing_key_ = state.serializing_key_; + } + + /** + * @brief Serializes a plain type, generic implementation. + * + * @param id The parameter ID. + * @param value The value to serialize. + * + * @return ReturnCode + */ + template + typename std::enable_if::value && !is_safe_dds_serialization_basic_type::value, + safedds::ReturnCode>::type serialize_plain_type( + const uint32_t& /* id */, + const T& value) + { + safedds::ReturnCode ret = safedds::ReturnCode::OK; + + // Store the state of the serializer to use it as a copy + SerializerState state = get_state(); + + if (serializing_key_) + { + ret = T::SerializationStruct::serialize_key(*this, value); + } + else + { + // Serialize the value + ret = T::SerializationStruct::serialize(*this, value); + } + + if (safedds::ReturnCode::OK == ret) + { + state.position = position_; + + // IMPORTANT: This reset at parameter payload is related with an open discussion about PUSH/POP(Origin=0) in OMG Standard + state.alignment_position = alignment_position_; + } + + // Restore the state of the serializer + set_state(state); + + return ret; + } + + /** + * @brief Serializes a plain type, specialization for optional types. + */ + template + safedds::ReturnCode serialize_plain_type( + const uint32_t& id, + const memory::Optional& value) + { + return serialize_parameter(id, value.has_value() ? &value.value() : nullptr); + } + + /** + * @brief Serializes a plain type, specialization for map types. + */ + template + safedds::ReturnCode serialize_plain_type( + const uint32_t& id, + const std::map& value) + { + safedds::ReturnCode ret = safedds::ReturnCode::OK; + + memory::byte_array::ByteArrayView local_map_dheader_view = {}; + + if (safedds::serialization::cdr::XCDRVersion::XCDRV2 == xcdr_version_ && map_require_dheader::value) + { + ret = serializer_align_to(4U); + + if (safedds::ReturnCode::OK == ret && !emulated_serialization_) + { + local_map_dheader_view.mutable_set(&buffer_[position_], sizeof(uint32_t)); + } + + if (safedds::ReturnCode::OK == ret) + { + ret = serializer_skip(sizeof(uint32_t)); + } + } + + const uint32_t begin_position = position_; + + if (safedds::ReturnCode::OK == ret) + { + ret = serialize(static_cast(value.size())); + } + + if (safedds::ReturnCode::OK == ret) + { + for (const auto& element : value) + { + ret = serialize_type(id, element.first); + + if (ret != safedds::ReturnCode::OK) + { + break; + } + + ret = serialize_type(id, element.second); + + if (ret != safedds::ReturnCode::OK) + { + break; + } + } + } + + uint32_t actual_size = position_ - begin_position; + + if (safedds::ReturnCode::OK == ret && !emulated_serialization_ && + safedds::serialization::cdr::XCDRVersion::XCDRV2 == xcdr_version_ && + map_require_dheader::value) + { + SafeDDSTypeSupportSerializer dheader_length_serializer(local_map_dheader_view, endianness_, + xcdr_version_); + ret = dheader_length_serializer.serialize(actual_size); + } + + return ret; + } + + /** + * @brief Util for serializing a raw container. Generic container implementation. + */ + template + typename std::enable_if< + safe_dds_serialization_container_utils::serialize_container_by_element, + safedds::ReturnCode>::type serialize_raw_container( + const uint32_t& id, + const V& container) + { + safedds::ReturnCode ret = safedds::ReturnCode::OK; + + for (uint32_t i = 0; i < container.size(); ++i) + { + ret = serialize_type(id, container.data()[i]); + + if (ret != safedds::ReturnCode::OK) + { + break; + } + } + + return ret; + } + + /** + * @brief Util for serializing a raw container. Specialization for vectors of bool types. + */ + template + typename std::enable_if< + safe_dds_serialization_container_utils::serialize_bool_vector_by_element, + safedds::ReturnCode>::type serialize_raw_container( + const uint32_t& id, + const V& container) + { + safedds::ReturnCode ret = safedds::ReturnCode::OK; + + for (const auto& element : container) + { + ret = serialize_type(id, element); + + if (ret != safedds::ReturnCode::OK) + { + break; + } + } + + return ret; + } + + /** + * @brief Util for serializing a raw container. Specialization for basic type container. + */ + template + typename std::enable_if< + safe_dds_serialization_container_utils::serialize_basic_type, + safedds::ReturnCode>::type serialize_raw_container( + const uint32_t& /* id */, + const V& container) + { + safedds::ReturnCode ret = safedds::ReturnCode::OK; + + if (!container.empty()) + { + ret = serialize_array(container.data(), static_cast(container.size())); + } + + return ret; + } + + /** + * @brief Serializes a plain type, specialization for array types. + */ + template + safedds::ReturnCode serialize_plain_type( + const uint32_t& id, + const std::array& value) + { + return serialize_plain_array_type(id, value); + } + + /** + * @brief Serializes a plain array type. + * + * @note Array can be defined by a pointer to the first element and a size. + */ + template + typename std::enable_if< + is_array::value || is_external_array::value, + safedds::ReturnCode>::type serialize_plain_array_type( + const uint32_t& id, + const V value) + { + safedds::ReturnCode ret = safedds::ReturnCode::OK; + + memory::byte_array::ByteArrayView local_array_dheader_view = {}; + + if (safedds::serialization::cdr::XCDRVersion::XCDRV2 == xcdr_version_ && + sequence_or_array_require_dheader::value) + { + ret = serializer_align_to(4U); + + if (safedds::ReturnCode::OK == ret && !emulated_serialization_) + { + local_array_dheader_view.mutable_set(&buffer_[position_], sizeof(uint32_t)); + } + + if (safedds::ReturnCode::OK == ret) + { + ret = serializer_skip(sizeof(uint32_t)); + } + } + + const uint32_t begin_position = position_; + + // Use templatized raw container serialization + ret = serialize_raw_container(id, value); + + uint32_t actual_size = position_ - begin_position; + + if (safedds::ReturnCode::OK == ret && !emulated_serialization_ && + safedds::serialization::cdr::XCDRVersion::XCDRV2 == xcdr_version_ && + sequence_or_array_require_dheader::value) + { + SafeDDSTypeSupportSerializer dheader_length_serializer(local_array_dheader_view, endianness_, + xcdr_version_); + ret = dheader_length_serializer.serialize(actual_size); + } + + return ret; + } + + /** + * @brief Serializes a plain type, specialization for vector types. + */ + template + safedds::ReturnCode serialize_plain_type( + const uint32_t& id, + const std::vector& value) + { + return serialize_plain_sequence_type(id, value); + } + + /** + * @brief Serializes a plain sequence type + * + * @note Sequence can be defined by a pointer to the first element and a size. + */ + template + typename std::enable_if< + is_sequence::value || is_external_sequence::value, + safedds::ReturnCode>::type serialize_plain_sequence_type( + const uint32_t& id, + const V value) + { + safedds::ReturnCode ret = safedds::ReturnCode::OK; + + memory::byte_array::ByteArrayView local_sequence_dheader_view = {}; + + if (safedds::serialization::cdr::XCDRVersion::XCDRV2 == xcdr_version_ && + sequence_or_array_require_dheader::value) + { + ret = serializer_align_to(4U); + + if (safedds::ReturnCode::OK == ret && !emulated_serialization_) + { + local_sequence_dheader_view.mutable_set(&buffer_[position_], sizeof(uint32_t)); + } + + if (safedds::ReturnCode::OK == ret) + { + ret = serializer_skip(sizeof(uint32_t)); + } + } + + const uint32_t begin_position = position_; + + if (safedds::ReturnCode::OK == ret) + { + ret = serialize(static_cast(value.size())); + } + + if (safedds::ReturnCode::OK == ret) + { + // Use templatized raw container serialization + ret = serialize_raw_container(id, value); + } + + uint32_t actual_size = position_ - begin_position; + + if (safedds::ReturnCode::OK == ret && !emulated_serialization_ && + safedds::serialization::cdr::XCDRVersion::XCDRV2 == xcdr_version_ && + sequence_or_array_require_dheader::value) + { + SafeDDSTypeSupportSerializer dheader_length_serializer(local_sequence_dheader_view, endianness_, + xcdr_version_); + ret = dheader_length_serializer.serialize(actual_size); + } + + return ret; + } + + /** + * @brief Serializes a plain type, specialization for enum types. + */ + template + typename std::enable_if::value, safedds::ReturnCode>::type serialize_plain_type( + const uint32_t& /* id */, + const E& value) + { + return serialize(static_cast::type>(value)); + } + + /** + * @brief Serializes a Safe DDS serialization basic types + */ + template + typename std::enable_if::value, + safedds::ReturnCode>::type serialize_plain_type( + const uint32_t& /* id */, + const T& value) + { + return serialize(value); + } + + /** + * @brief Serializes a plain type, specialization for strings + */ + safedds::ReturnCode serialize_plain_type( + const uint32_t& id, + const std::string& value) + { + return serialize_plain_string_type(id, value); + } + + /** + * @brief Serializes a plain string type. + */ + template + typename std::enable_if::value || is_external_string::value, + safedds::ReturnCode>::type serialize_plain_string_type( + const uint32_t& /* id */, + const T& value) + { + safedds::ReturnCode ret = safedds::ReturnCode::OK; + + ret = serialize(static_cast(value.size() + 1)); + + if (ret == safedds::ReturnCode::OK && value.size() > 0) + { + ret = serialize_array(const_cast(value.data()), static_cast(value.size())); + } + + if (ret == safedds::ReturnCode::OK) + { + ret = serialize(static_cast(0U)); + } + + return ret; + } + + /** + * @brief Serializes an external type. + */ + template + safedds::ReturnCode serialize_plain_type( + const uint32_t& id, + const External& value) + { + safedds::ReturnCode ret = safedds::ReturnCode::ERROR; + + if (nullptr != value.member) + { + ret = serialize_plain_type(id, *(value.member)); + } + + return ret; + } + + /** + * @brief Serializes an external sequence. + */ + template + safedds::ReturnCode serialize_plain_type( + const uint32_t& id, + const ExternalSequence& value) + { + safedds::ReturnCode ret = safedds::ReturnCode::ERROR; + + if (nullptr != value.data()) + { + ret = serialize_plain_sequence_type(id, value); + } + + return ret; + } + + /** + * @brief Serializes an external array. + */ + template + safedds::ReturnCode serialize_plain_type( + const uint32_t& id, + const ExternalArray& value) + { + safedds::ReturnCode ret = safedds::ReturnCode::ERROR; + + if (nullptr != value.data()) + { + ret = serialize_plain_array_type(id, value); + } + + return ret; + } + + /** + * @brief Serializes an external string. + */ + safedds::ReturnCode serialize_plain_type( + const uint32_t& id, + const ExternalString& value) + { + safedds::ReturnCode ret = safedds::ReturnCode::ERROR; + + if (nullptr != value.data()) + { + ret = serialize_plain_string_type(id, value); + } + + return ret; + } + + /** + * @brief Serializes a parameter header. + * + * @note Will not serialize the length field. + * + * @param id The parameter ID. + * + * @return ReturnCode + */ + safedds::ReturnCode serialize_parameter_header( + const uint32_t& id) + { + // Align to 4 bytes + safedds::ReturnCode ret = serializer_align_to(4U); + + // Serialize param_id + if (safedds::ReturnCode::OK == ret) + { + ret = serialize(static_cast(id)); + } + + return ret; + } + + /** + * @brief Serializes an extended parameter header. + * + * @note Will not serialize the extended length field. + * + * @param id The parameter ID. + * + * @return ReturnCode + */ + safedds::ReturnCode serialize_parameter_header_extended( + const uint32_t& id) + { + // Align to 4 bytes + safedds::ReturnCode ret = serializer_align_to(4U); + + // Serialize extension header + if (safedds::ReturnCode::OK == ret) + { + ret = serialize_parameter_header(PID_EXTENDED); + } + + // Serialize extension header length + if (safedds::ReturnCode::OK == ret) + { + ret = serialize(static_cast(8U)); + } + + // Serialize 32 bits id + if (safedds::ReturnCode::OK == ret) + { + ret = serialize(id); + } + + return ret; + } + + /** + * @brief Serializes a parameter assuming XCDR1 encoding. + * + * @param id The parameter ID. + * @param value The value to serialize. + * + * @return ReturnCode + */ + template + safedds::ReturnCode serialize_parameter_xcdr1( + const uint32_t& id, + const T* value) + { + const bool extended_parameter = (id > PID_MAX_SHORT) && (id != PID_LIST_END); + + // Check preconditions + safedds::ReturnCode ret = safedds::serialization::cdr::XCDRVersion::XCDRV1 == xcdr_version_ ? + safedds::ReturnCode::OK : + safedds::ReturnCode::ERROR; + + // Parameter header is aligned to 4 bytes + if (safedds::ReturnCode::OK == ret) + { + ret = serializer_align_to(4U); + } + + // Serialize param_id + if (safedds::ReturnCode::OK == ret) + { + if (extended_parameter) + { + ret = serialize_parameter_header_extended(id); + } + else + { + ret = serialize_parameter_header(id); + } + } + + // Prepare actual parameter length serialization taking into account extensible parameters + const uint32_t length_field_size = extended_parameter ? + safedds::portable::safe_sizeof() : + safedds::portable::safe_sizeof(); + + uint8_t* length_position = emulated_serialization_ ? nullptr : &buffer_[position_]; + + // Skip the length field size + if (safedds::ReturnCode::OK == ret) + { + ret = serializer_skip(length_field_size); + } + + // Serialize the payload if there is enough space + uint32_t payload_size = 0; + + // IMPORTANT: This reset at parameter payload is related with an open discussion about PUSH/POP(Origin=0) in OMG Standard + reset_alignment(); + + // Create a clean serializer for the parameter payload taking into account the emulation mode + if (safedds::ReturnCode::OK == ret && (nullptr != value)) + { + if (emulated_serialization_) + { + SafeDDSTypeSupportSerializer payload_serializer(endianness_, xcdr_version_); + ret = payload_serializer.serialize_plain_type(id, *value); + payload_size = payload_serializer.serializer_used_size(); + } + else + { + memory::byte_array::ByteArrayView payload_view(&buffer_[position_], serializer_remaining_size()); + SafeDDSTypeSupportSerializer payload_serializer(payload_view, endianness_, xcdr_version_); + ret = payload_serializer.serialize_plain_type(id, *value); + payload_size = payload_serializer.serializer_used_size(); + } + } + + // Skip the used size in the current serializer + if (safedds::ReturnCode::OK == ret) + { + ret = serializer_skip(payload_size); + } + + // Serialize length + if (safedds::ReturnCode::OK == ret && !emulated_serialization_) + { + // Create a serializer for the length field stored previously + memory::byte_array::ByteArrayView length_view{length_position, length_field_size}; + safedds::serialization::cdr::Serializer length_serializer(length_view, endianness_, xcdr_version_); + + if (extended_parameter) + { + ret = length_serializer.serialize(static_cast(payload_size)); + } + else + { + ret = length_serializer.serialize(static_cast(payload_size)); + } + } + + return ret; + } + + /** + * @brief Serializes a parameter assuming XCDR2 encoding. + * + * @param id The parameter ID. + * @param value The value to serialize. + * + * @return ReturnCode + */ + template + safedds::ReturnCode serialize_parameter_xcdr2( + const uint32_t& id, + const T* value) + { + // Check preconditions + safedds::ReturnCode ret = safedds::serialization::cdr::XCDRVersion::XCDRV2 == xcdr_version_ ? + safedds::ReturnCode::OK : + safedds::ReturnCode::ERROR; + + // Parameter header is aligned to 4 bytes + if (safedds::ReturnCode::OK == ret) + { + ret = serializer_align_to(4U); + } + + // Check max bound of id + if (id > PID_MAX_CDRV2) + { + ret = safedds::ReturnCode::ERROR; + } + + // Serialize emheader + const uint8_t lc = get_xcdr2_emheader_length_code(*value); + // Explicit nextint field is only needed if the LC == 4. + // LC > 4 is for sequences and strings which already have their associated length at the beginning of the payload, which is the same as the nextint field. + const bool needs_explicit_nextint = (lc == 4); + + if (safedds::ReturnCode::OK == ret) + { + const bool must_understand = false; + const uint32_t member_id = id & 0x0FFFFFFF; + uint32_t emheader = (must_understand ? 0x80000000 : 0) | (lc << 28) | member_id; + + ret = serialize(emheader); + } + + // Store nextint position + uint8_t* nextint_position = + (!needs_explicit_nextint || emulated_serialization_) ? nullptr : &buffer_[position_]; + + // Skip the nextint field size if needed + if ((safedds::ReturnCode::OK == ret) && needs_explicit_nextint) + { + ret = serializer_skip(sizeof(uint32_t)); + } + + // Serialize the payload if there is enough space + uint32_t payload_size = 0; + + // Create a clean serializer for the parameter payload taking into account the emulation mode + if (safedds::ReturnCode::OK == ret && (nullptr != value)) + { + if (emulated_serialization_) + { + SafeDDSTypeSupportSerializer payload_serializer(endianness_, xcdr_version_); + ret = payload_serializer.serialize_plain_type(id, *value); + payload_size = payload_serializer.serializer_used_size(); + } + else + { + memory::byte_array::ByteArrayView payload_view(&buffer_[position_], serializer_remaining_size()); + SafeDDSTypeSupportSerializer payload_serializer(payload_view, endianness_, xcdr_version_); + ret = payload_serializer.serialize_plain_type(id, *value); + payload_size = payload_serializer.serializer_used_size(); + } + } + + // Skip the used size in the current serializer + if (safedds::ReturnCode::OK == ret) + { + ret = serializer_skip(payload_size); + } + + // Serialize nextint + if (safedds::ReturnCode::OK == ret && needs_explicit_nextint && !emulated_serialization_) + { + // Create a serializer for the nextint field stored previously + memory::byte_array::ByteArrayView nextint_view{nextint_position, sizeof(uint32_t)}; + safedds::serialization::cdr::Serializer nextint_serializer(nextint_view, endianness_, xcdr_version_); + + ret = nextint_serializer.serialize(payload_size); + } + + return ret; + } + + /** + * @brief Serializes a parameter. + * + * @param id The parameter ID. + * @param value The value to serialize. + * + * @return ReturnCode + */ + template + safedds::ReturnCode serialize_parameter( + const uint32_t& id, + const T* value) + { + safedds::ReturnCode ret = safedds::ReturnCode::OK; + + if (safedds::serialization::cdr::XCDRVersion::XCDRV1 == xcdr_version_) + { + ret = serialize_parameter_xcdr1(id, value); + } + else if (safedds::serialization::cdr::XCDRVersion::XCDRV2 == xcdr_version_) + { + ret = serialize_parameter_xcdr2(id, value); + } + else + { + ret = safedds::ReturnCode::ERROR; + } + + return ret; + } + +private: + + /** + * @brief Get XCDR2 EMHEADER length code (LC) generic implementation. + * + * @note If the size of the type is not supported, it will default to 4. + * + * @param value The value to get the length code from. + * + * @return length code value + */ + template + const typename std::enable_if::value && !is_external_sequence::value && !is_array::value && !is_external_array::value && !is_map::value && !is_string::value && !is_external_string::value && !is_idl_union::value && !is_external::value && is_idl_extensibility_final::value, + uint8_t>::type get_xcdr2_emheader_length_code( + const T& /* value */) + { + const uint32_t element_size = portable::safe_sizeof(); + + return (element_size == 1 ? 0 : + element_size == 2 ? 1 : + element_size == 4 ? 2 : + element_size == 8 ? 3 : + 4) & 0x07; + } + + /** + * @brief Get XCDR2 EMHEADER length code (LC) specialization for external types. + * + * @note If the size of the type is not supported, it will default to 4. + * + * @param value The value to get the length code from. + * + * @return length code value + */ + template + const typename std::enable_if::value, + uint8_t>::type get_xcdr2_emheader_length_code( + const T& value) + { + return get_xcdr2_emheader_length_code(*value.member); + } + + /** + * @brief Get XCDR2 EMHEADER length code (LC) specialization for sequences (are always final). + * + * @param value The sequence to get the length code from. + * + * @return length code value + */ + template + const typename std::enable_if::value || is_external_sequence::value, + uint8_t>::type get_xcdr2_emheader_length_code( + const T& value) + { + uint8_t length_code = 0; + + if (!is_arithmetic_or_enum::value) + { + // Sequences's dheader is always 4 bytes + length_code = 5 & 0x07; + } + // When having arithmetic and enum inner types the dheader can be optimized + else + { + const uint32_t element_size = portable::safe_sizeof(); + const uint32_t sequence_size = value.size(); + + length_code = (element_size == 1 ? 5 : + element_size == 4 ? 6 : + element_size == 8 ? 7 : + sequence_size == 0 ? 2 : + 4) & 0x07; + } + + return length_code; + } + + /** + * @brief Get XCDR2 EMHEADER length code (LC) specialization for arrays (are always final). + * + * @param value The array to get the length code from. + * + * @return length code value + */ + template + const typename std::enable_if::value || is_external_array::value, + uint8_t>::type get_xcdr2_emheader_length_code( + const T& value) + { + uint8_t length_code = 0; + + if (sequence_or_array_require_dheader::value) + { + // Array's dheader is always 4 bytes and it specifies the size of the array + length_code = 5 & 0x07; + } + else + { + const uint32_t element_size = portable::safe_sizeof(); + const uint32_t array_size = value.size(); + const uint32_t total_size = array_size * element_size; + length_code = (total_size == 1 ? 0 : + total_size == 2 ? 1 : + total_size == 4 ? 2 : + total_size == 8 ? 3 : + 4) & 0x07; + } + + return length_code; + } + + /** + * @brief Get XCDR2 EMHEADER length code (LC) specialization for maps (are always final). + * + * @param value The map to get the length code from. + * + * @return length code value + */ + template + const typename std::enable_if::value, uint8_t>::type get_xcdr2_emheader_length_code( + const T& value) + { + uint8_t length_code = 0; + + if (map_require_dheader::value) + { + // Map's dheader is always 4 bytes and it specifies the size of the map + length_code = 5 & 0x07; + } + else + { + const uint32_t element_size = portable::safe_sizeof() + + portable::safe_sizeof(); + const uint32_t map_size = value.size(); + const uint32_t total_size = map_size * element_size + portable::safe_sizeof(); + + length_code = (map_size == 0 ? 2 : + total_size == 2 ? 1 : + total_size == 4 ? 2 : + total_size == 8 ? 3 : + 4) & 0x07; + } + + return length_code; + } + + /** + * @brief Get XCDR2 EMHEADER length code (LC) specialization for strings (are always final). + * + * @param value The string to get the length code from. + * + * @return length code value + */ + template + const typename std::enable_if::value || is_external_string::value, + uint8_t>::type get_xcdr2_emheader_length_code( + const T& /* value */) + { + return 5 & 0x07; + } + + /** + * @brief Get XCDR2 EMHEADER length code (LC) specialization for non-final types. + * + * @note Always returns 5. + * + * @return length code value + */ + template + const typename std::enable_if::value, uint8_t>::type get_xcdr2_emheader_length_code( + const T& /* value */) + { + return 5 & 0x07; + } + + /** + * @brief Get XCDR2 EMHEADER length code (LC) specialization for union types. + * + * @note If the size of the type is not supported, it will default to 4. + * + * @param value The value to get the length code from. + * + * @return length code value + */ + template + const typename std::enable_if::value && is_idl_union::value, + uint8_t>::type get_xcdr2_emheader_length_code( + const T& value) + { + const uint32_t element_size = value.get_current_union_size(); + + return (element_size == 1 ? 0 : + element_size == 2 ? 1 : + element_size == 4 ? 2 : + element_size == 8 ? 3 : + 4) & 0x07; + } + + safedds::platform::Endianness endianness_; //!< The endianness to use. + EncodingAlgorithm encoding_algorithm_; //!< The encoding algorithm to use. + memory::byte_array::ByteArrayView object_dheader_view_; //!< The view for the dheader. + uint32_t object_dheader_begin_position_; //!< Initial position for the dheader. + bool serializing_key_ = false; //!< Flag indicating if the serializer is serializing a key. +}; + +/** + * @brief SafeDDSTypeSupportDeserializer class. + */ +class SafeDDSTypeSupportDeserializer : + public safedds::serialization::cdr::Deserializer +{ + +public: + + /** + * @brief Constructs a SafeDDSTypeSupportDeserializer object. + * + * @param buffer The memory buffer containing the data to be deserialized. + * @param endianness The endianness to use for deserialization. + * @param xcdr_version The XCDR version to use for deserialization. + */ + SafeDDSTypeSupportDeserializer( + const memory::IConstByteArrayView& buffer, + safedds::platform::Endianness endianness, + safedds::serialization::cdr::XCDRVersion xcdr_version) noexcept + : safedds::serialization::cdr::Deserializer(buffer, endianness, xcdr_version) + , current_encoding_algorithm_( + safedds::serialization::cdr::XCDRVersion::XCDRV1 == xcdr_version ? + EncodingAlgorithm::PLAIN_CDR : + EncodingAlgorithm::PLAIN_CDR2) + { + } + + /** + * @brief Get XCDR version + * + * @return XCDRVersion + */ + safedds::serialization::cdr::XCDRVersion get_xcdr_version() const + { + return xcdr_version_; + } + + /** + * @brief Deserializes a type. + * + * @param encoding_algorithm The encoding algorithm to use for deserialization. + * @param callback The callback to be called for each member. + * + * @return ReturnCode + */ + template + safedds::ReturnCode deserialize_type( + const safedds::gen::EncodingAlgorithm& encoding_algorithm, + Callback callback) + { + safedds::ReturnCode ret = safedds::ReturnCode::OK; + + const EncodingAlgorithm previous_encoding_algorithm = current_encoding_algorithm_; + current_encoding_algorithm_ = encoding_algorithm; + + if (EncodingAlgorithm::PLAIN_CDR == encoding_algorithm) + { + ret = deserialize_type_plaincdr(callback); + } + else if (EncodingAlgorithm::PL_CDR == encoding_algorithm) + { + ret = deserialize_type_parameterlistcdr(callback); + } + else if (EncodingAlgorithm::PLAIN_CDR2 == encoding_algorithm) + { + ret = deserialize_type_plaincdr(callback); + } + else if (EncodingAlgorithm::DELIMITED_CDR == encoding_algorithm) + { + ret = deserialize_type_delimitedcdr(callback); + } + else if (EncodingAlgorithm::PL_CDR2 == encoding_algorithm) + { + ret = deserialize_type_parameterlistcdr2(callback); + } + + current_encoding_algorithm_ = previous_encoding_algorithm; + + return ret; + } + + /** + * @brief Deserializes a member. Generic implementation. + * + * @param member The member to deserialize. + * + * @return ReturnCode + */ + template + typename std::enable_if::value && !is_safe_dds_serialization_basic_type::value, + safedds::ReturnCode>::type deserialize_member( + T& member) + { + return T::SerializationStruct::deserialize(*this, member); + } + + /** + * @brief Deserializes a member. Specialization for optional types. + */ + template + safedds::ReturnCode deserialize_member( + memory::Optional& member) + { + safedds::ReturnCode ret = safedds::ReturnCode::OK; + + member.reset(); + + // When dealing with an optional member, if we are in PLAIN_CDR mode, we need to check if the parameter is present + // by means of the parameter header. + if (EncodingAlgorithm::PLAIN_CDR == current_encoding_algorithm_) + { + uint32_t id = 0; + uint32_t length = 0; + + ret = deserialize_parameter_header(id, length); + + const bool extended_header = get_pid_value(id, false) == PID_EXTENDED; + + if (safedds::ReturnCode::OK == ret && extended_header) + { + ret = deserialize_parameter_header_extended(id, length); + } + + // IMPORTANT: This reset at parameter payload is related with an open discussion about PUSH/POP(Origin=0) in OMG Standard + reset_alignment(); + + if (0U != length && safedds::ReturnCode::OK == ret) + { + // Create a new deserializer for the payload in order to take into account parameter payload alignment + memory::byte_array::ByteArrayView payload_view; + ret = deserializer_skip(length, payload_view); + SafeDDSTypeSupportDeserializer payload_deserializer(payload_view, endianness_, xcdr_version_); + payload_deserializer.current_encoding_algorithm_ = current_encoding_algorithm_; + + V& value = member.inner_reference(); + + if (safedds::ReturnCode::OK == ret) + { + ret = payload_deserializer.deserialize_member(value); + } + + if (safedds::ReturnCode::OK == ret) + { + member.set(value); + } + } + } + // In the case of being in a PL_CDR mode or PL_CDR2, we can assume that the parameter header has been already processed and only the + // payload needs to be deserialized. + else if (EncodingAlgorithm::PL_CDR == current_encoding_algorithm_ || + EncodingAlgorithm::PL_CDR2 == current_encoding_algorithm_) + { + V& value = member.inner_reference(); + ret = deserialize_member(value); + + if (safedds::ReturnCode::OK == ret) + { + member.set(value); + } + } + // In the case of being in a PLAIN_CDR2 or DELIMITED_CDR mode, we need to check if the parameter is present + else if (EncodingAlgorithm::PLAIN_CDR2 == current_encoding_algorithm_ || + EncodingAlgorithm::DELIMITED_CDR == current_encoding_algorithm_) + { + bool is_set = false; + ret = deserialize(is_set); + + if (safedds::ReturnCode::OK == ret && is_set) + { + V& value = member.inner_reference(); + ret = deserialize_member(value); + + if (safedds::ReturnCode::OK == ret) + { + member.set(value); + } + } + } + else + { + ret = safedds::ReturnCode::ERROR; + } + + return ret; + } + + /** + * @brief Util for deserializing a raw container. Generic container implementation. + */ + template + typename std::enable_if< + safe_dds_serialization_container_utils::deserialize_container_by_element, + safedds::ReturnCode>::type deserialize_raw_container( + V& container) + { + safedds::ReturnCode ret = safedds::ReturnCode::OK; + + for (uint32_t i = 0; i < container.size(); ++i) + { + ret = deserialize_member(container.data()[i]); + + if (ret != safedds::ReturnCode::OK) + { + break; + } + } + + return ret; + } + + /** + * @brief Util for deserializing a raw container. Specialization for vectors of bool types. + */ + template + typename std::enable_if< + safe_dds_serialization_container_utils::deserialize_bool_vector_by_element, + safedds::ReturnCode>::type deserialize_raw_container( + V& container) + { + safedds::ReturnCode ret = safedds::ReturnCode::OK; + + for (size_t i = 0; i < container.size(); ++i) + { + bool temp = false; + ret = deserialize(temp); + + if (ret != safedds::ReturnCode::OK) + { + break; + } + + container[i] = temp; + } + + return ret; + } + + /** + * @brief Util for deserializing a raw container. Specialization for basic type containers. + */ + template + typename std::enable_if< + safe_dds_serialization_container_utils::deserialize_basic_type, + safedds::ReturnCode>::type deserialize_raw_container( + V& container) + { + safedds::ReturnCode ret = safedds::ReturnCode::OK; + + if (!container.empty()) + { + ret = deserialize_array(container.data(), static_cast(container.size())); + } + + return ret; + } + + /** + * @brief Deserializes a member. Specialization for array types. + */ + template + safedds::ReturnCode deserialize_member( + std::array& member) + { + return deserialize_array_member(member); + } + + /** + * @brief Deserializes an array member. + * + * @note Array can also be defined by a pointer to the first element and a size. + */ + template + typename std::enable_if< + is_array::value || is_external_array::value, + safedds::ReturnCode>::type deserialize_array_member( + V& member) + { + safedds::ReturnCode ret = safedds::ReturnCode::OK; + + // Deserialize dheader if required + uint32_t dheader = 0; + + if (safedds::serialization::cdr::XCDRVersion::XCDRV2 == xcdr_version_ && + sequence_or_array_require_dheader::value) + { + ret = deserialize(dheader); + } + + const uint32_t begin_position = position_; + + if (safedds::ReturnCode::OK == ret) + { + // Use templatized raw container deserialization + ret = deserialize_raw_container(member); + } + + uint32_t actual_size = position_ - begin_position; + + // Check if the dheader is present and skip the remaining bytes + if (safedds::ReturnCode::OK == ret && safedds::serialization::cdr::XCDRVersion::XCDRV2 == xcdr_version_ && + sequence_or_array_require_dheader::value && dheader > actual_size) + { + ret = deserializer_skip(dheader - actual_size); + } + + return ret; + } + + /** + * @brief Deserializes a member. Specialization for vector types. + */ + template + safedds::ReturnCode deserialize_member( + std::vector& member) + { + member.clear(); + + return deserialize_sequence_member(member); + } + + /** + * @brief Deserializes a sequence member. + * + * @note Sequence can be defined by a pointer to the first element and a size. + */ + template + typename std::enable_if< + is_sequence::value || is_external_sequence::value, + safedds::ReturnCode>::type deserialize_sequence_member( + V& member) + { + safedds::ReturnCode ret = safedds::ReturnCode::OK; + + // Deserialize dheader if required + uint32_t dheader = 0; + + if (safedds::serialization::cdr::XCDRVersion::XCDRV2 == xcdr_version_ && + sequence_or_array_require_dheader::value) + { + ret = deserialize(dheader); + } + + const uint32_t begin_position = position_; + uint32_t size = 0; + + if (safedds::ReturnCode::OK == ret) + { + ret = deserialize(size); + } + + if (safedds::ReturnCode::OK == ret) + { + ret = resize_container(member, size); + } + + if (safedds::ReturnCode::OK == ret) + { + // Use templatized raw container deserialization + ret = deserialize_raw_container(member); + } + + uint32_t actual_size = position_ - begin_position; + + // Check if the dheader is present and skip the remaining bytes + if (safedds::ReturnCode::OK == ret && safedds::serialization::cdr::XCDRVersion::XCDRV2 == xcdr_version_ && + sequence_or_array_require_dheader::value && dheader > actual_size) + { + ret = deserializer_skip(dheader - actual_size); + } + + return ret; + } + + /** + * @brief Deserializes a member. Specialization for map types. + */ + template + safedds::ReturnCode deserialize_member( + std::map& member) + { + safedds::ReturnCode ret = safedds::ReturnCode::OK; + + member.clear(); + + // Deserialize dheader if required + uint32_t dheader = 0; + + if (safedds::serialization::cdr::XCDRVersion::XCDRV2 == xcdr_version_ && map_require_dheader::value) + { + ret = deserialize(dheader); + } + + uint32_t size = 0; + + if (safedds::ReturnCode::OK == ret) + { + ret = deserialize(size); + } + + if (safedds::ReturnCode::OK == ret) + { + while (size-- > 0) + { + K key; + V value; + + ret = deserialize_member(key); + + if (ret != safedds::ReturnCode::OK) + { + break; + } + + ret = deserialize_member(value); + + if (ret != safedds::ReturnCode::OK) + { + break; + } + + member[key] = value; + } + } + + return ret; + } + + /** + * @brief Deserializes a member. Specialization for enum types. + */ + template + typename std::enable_if::value, safedds::ReturnCode>::type deserialize_member( + E& member) + { + typename std::underlying_type::type value; + safedds::ReturnCode ret = deserialize(value); + + if (safedds::ReturnCode::OK == ret) + { + member = static_cast(value); + } + + return ret; + } + + /** + * @brief Deserializes a member. Specialization for Safe DDS serialization basic types. + */ + template + typename std::enable_if::value, + safedds::ReturnCode>::type deserialize_member( + T& member) + { + return deserialize(member); + } + + /** + * @brief Deserializes a member. Specialization for strings. + */ + safedds::ReturnCode deserialize_member( + std::string& member) + { + member.clear(); + + return deserialize_string_member(member); + } + + /** + * @brief Deserializes a string member. + */ + template + typename std::enable_if::value || is_external_string::value, + safedds::ReturnCode>::type deserialize_string_member( + T& member) + { + uint32_t length = 0; + safedds::ReturnCode ret = deserialize(length); + + if ((safedds::ReturnCode::OK == ret) && (length > 1)) + { + ret = resize_container(member, length - 1); + + if (safedds::ReturnCode::OK == ret) + { + ret = deserialize_array(const_cast(member.data()), length - 1); + } + } + + if (safedds::ReturnCode::OK == ret) + { + char null_char = 0; + ret = deserialize(null_char); + } + + return ret; + } + + /** + * @brief Deserializes a member. Specialization for external types. + */ + template + safedds::ReturnCode deserialize_member( + External& member) + { + safedds::ReturnCode ret = safedds::ReturnCode::ERROR; + + if (nullptr != member.member) + { + ret = deserialize_member(*(member.member)); + } + + return ret; + } + + /** + * @brief Deserializes a member. Specialization for external sequences. + */ + template + safedds::ReturnCode deserialize_member( + ExternalSequence& member) + { + safedds::ReturnCode ret = safedds::ReturnCode::ERROR; + + if (nullptr != member.data()) + { + ret = deserialize_sequence_member(member); + } + + return ret; + } + + /** + * @brief Deserializes a member. Specialization for external arrays. + */ + template + safedds::ReturnCode deserialize_member( + ExternalArray& member) + { + safedds::ReturnCode ret = safedds::ReturnCode::ERROR; + + if (nullptr != member.data()) + { + ret = deserialize_array_member(member); + } + + return ret; + } + + /** + * @brief Deserializes a member. Specialization for external strings. + */ + safedds::ReturnCode deserialize_member( + ExternalString& member) + { + safedds::ReturnCode ret = safedds::ReturnCode::ERROR; + + if (nullptr != member.data()) + { + ret = deserialize_string_member(member); + } + + return ret; + } + +private: + + /** + * @brief Deserializes plain CDRv1 and plain CDRv2 type + * + * @param callback The callback to be called for each element. + * + * @return ReturnCode + */ + template + safedds::ReturnCode deserialize_type_plaincdr( + Callback callback) + { + safedds::ReturnCode ret = + (EncodingAlgorithm::PLAIN_CDR == current_encoding_algorithm_ || + EncodingAlgorithm::PLAIN_CDR2 == current_encoding_algorithm_) ? + safedds::ReturnCode::OK : safedds::ReturnCode::ERROR; + + if (safedds::ReturnCode::OK == ret) + { + uint32_t index = 0; + + while (deserializer_remaining_size() > 0 && safedds::ReturnCode::OK == ret) + { + ret = callback(*this, index++); + } + + // Unimplemented means end of the list + if (safedds::ReturnCode::UNIMPLEMENTED == ret) + { + ret = safedds::ReturnCode::OK; + } + } + + return ret; + } + + /** + * @brief Deserializes a Parameter list CDRv1 type + * + * @param callback The callback to be called for each element. + * + * @return ReturnCode + */ + template + safedds::ReturnCode deserialize_type_parameterlistcdr( + Callback callback) + { + safedds::ReturnCode ret = + (EncodingAlgorithm::PL_CDR == current_encoding_algorithm_) ? + safedds::ReturnCode::OK : safedds::ReturnCode::ERROR; + + if (safedds::ReturnCode::OK == ret) + { + bool list_end = false; + + while (deserializer_remaining_size() > 0 && safedds::ReturnCode::OK == ret && !list_end) + { + uint32_t id = 0; + uint32_t length = 0; + + ret = deserialize_parameter_header(id, length); + + const bool extended_header = get_pid_value(id, false) == PID_EXTENDED; + + if (safedds::ReturnCode::OK == ret && extended_header) + { + ret = deserialize_parameter_header_extended(id, length); + } + + // Reset alginment after header deserialization + reset_alignment(); + + // Get id flags + const bool implementation_extension = is_pid_implementation_extension(id, extended_header); + const bool must_understand = is_pid_must_understand(id, extended_header); + + id = get_pid_value(id, extended_header); + const bool ignore = implementation_extension || (id == PID_IGNORE); + list_end = id == PID_LIST_END; + + if (safedds::ReturnCode::OK == ret && !list_end && length > 0) + { + // Create an aux deserializer for the payload + memory::byte_array::ByteArrayView payload_view; + ret = deserializer_skip(length, payload_view); + SafeDDSTypeSupportDeserializer payload_deserializer(payload_view, endianness_, xcdr_version_); + payload_deserializer.current_encoding_algorithm_ = current_encoding_algorithm_; + + if (!ignore && safedds::ReturnCode::OK == ret) + { + ret = callback(payload_deserializer, id); + } + + // Handle unknown parameters + if (safedds::ReturnCode::UNIMPLEMENTED == ret) + { + ret = !must_understand ? safedds::ReturnCode::OK : safedds::ReturnCode::ERROR; + } + } + } + } + + return ret; + } + + /** + * @brief Deserializes a delimitated CDRv2 type + * + * @param callback The callback to be called for each element. + * + * @return ReturnCode + */ + template + safedds::ReturnCode deserialize_type_delimitedcdr( + Callback callback) + { + safedds::ReturnCode ret = + (EncodingAlgorithm::DELIMITED_CDR == current_encoding_algorithm_) ? + safedds::ReturnCode::OK : safedds::ReturnCode::ERROR; + + if (safedds::ReturnCode::OK == ret) + { + // Deserialize dheader + uint32_t dheader = 0; + + ret = deserialize(dheader); + + // Check remaining size + if (safedds::ReturnCode::OK == ret && deserializer_remaining_size() < dheader) + { + ret = safedds::ReturnCode::SERIALIZATION_INVALID_BUFFER_LENGTH; + } + + const uint32_t begin_position = position_; + + if (safedds::ReturnCode::OK == ret) + { + uint32_t index = 0; + + while ((position_ - begin_position) < dheader && safedds::ReturnCode::OK == ret) + { + ret = callback(*this, index++); + } + + // Unimplemented means end of the list + if (safedds::ReturnCode::UNIMPLEMENTED == ret) + { + ret = safedds::ReturnCode::OK; + } + } + + uint32_t actual_size = position_ - begin_position; + + // Skip the remaining bytes if dheader is greater than the actual size + if (safedds::ReturnCode::OK == ret && dheader > actual_size) + { + ret = deserializer_skip(dheader - actual_size); + } + } + + return ret; + } + + /** + * @brief Deserializes a Parameter list CDRv2 type + * + * @param callback The callback to be called for each element. + * + * @return ReturnCode + */ + template + safedds::ReturnCode deserialize_type_parameterlistcdr2( + Callback callback) + { + safedds::ReturnCode ret = + (EncodingAlgorithm::PL_CDR2 == current_encoding_algorithm_) ? + safedds::ReturnCode::OK : safedds::ReturnCode::ERROR; + + // Deserialize dheader + uint32_t dheader = 0; + + if (safedds::ReturnCode::OK == ret) + { + ret = deserialize(dheader); + } + + // Check remaining size + if (safedds::ReturnCode::OK == ret && deserializer_remaining_size() < dheader) + { + ret = safedds::ReturnCode::SERIALIZATION_INVALID_BUFFER_LENGTH; + } + + const uint32_t begin_position = position_; + + if (safedds::ReturnCode::OK == ret) + { + while ((position_ - begin_position) < dheader && safedds::ReturnCode::OK == ret) + { + uint32_t emheader = 0; + ret = deserialize(emheader); + + uint32_t id = emheader & 0x0FFFFFFF; + const uint8_t lc = (emheader >> 28) & 0x07; + const bool must_understand = (emheader & 0x80000000) != 0; + + uint32_t length = 0; + + if (lc < 4U) + { + length = 1U << lc; + } + else if (lc == 4U) + { + deserialize(length); + } + else + { + // See the future and do not skip the nextint field + memory::byte_array::ByteArrayView length_view = {}; + length_view.const_mutable_set(&buffer_[position_], sizeof(uint32_t)); + SafeDDSTypeSupportDeserializer length_deserializer(length_view, endianness_, xcdr_version_); + length_deserializer.deserialize(length); + + // Apply multiplier + length *= (lc == 6U) ? 4U : (lc == 7U) ? 8U : 1U; + + // Add nextint field size + length += sizeof(uint32_t); + } + + if (safedds::ReturnCode::OK == ret && length > 0) + { + // Create an aux deserializer for the payload + memory::byte_array::ByteArrayView payload_view; + ret = deserializer_skip(length, payload_view); + SafeDDSTypeSupportDeserializer payload_deserializer(payload_view, endianness_, xcdr_version_); + payload_deserializer.current_encoding_algorithm_ = current_encoding_algorithm_; + + if (safedds::ReturnCode::OK == ret) + { + ret = callback(payload_deserializer, id); + } + + // Handle unknown parameters + if (safedds::ReturnCode::UNIMPLEMENTED == ret) + { + ret = !must_understand ? safedds::ReturnCode::OK : safedds::ReturnCode::ERROR; + } + } + } + } + + uint32_t actual_size = position_ - begin_position; + + // Skip the remaining bytes if dheader is greater than the actual size + if (safedds::ReturnCode::OK == ret && dheader > actual_size) + { + ret = deserializer_skip(dheader - actual_size); + } + + return ret; + } + + /** + * @brief Aligns the deserializer to the given alignment. + * + * @param alignment The alignment to align the deserializer to. + */ + safedds::ReturnCode deserializer_align_to( + uint32_t type_size) noexcept + { + safedds::ReturnCode ret = safedds::ReturnCode::SERIALIZATION_INVALID_BUFFER_LENGTH; + const uint32_t padding = xcdr_padding_needed(alignment_position_, type_size); + + if ((position_ + padding) <= buffer_.const_size()) + { + position_ += padding; + alignment_position_ += padding; + ret = safedds::ReturnCode::OK; + } + + return ret; + } + + /** + * @brief Deserializes a parameter header. + * + * @param id The parameter ID. + * @param length The parameter length. + * + * @return ReturnCode + */ + safedds::ReturnCode deserialize_parameter_header( + uint32_t& id, + uint32_t& length) + { + // Align to 4 bytes + safedds::ReturnCode ret = deserializer_align_to(4U); + + // Deserialize param_id + if (safedds::ReturnCode::OK == ret) + { + uint16_t param_id = 0; + ret = deserialize(param_id); + + if (safedds::ReturnCode::OK == ret) + { + id = param_id; + } + } + + // Deserialize length + if (safedds::ReturnCode::OK == ret) + { + uint16_t length_value = 0; + ret = deserialize(length_value); + + if (safedds::ReturnCode::OK == ret) + { + length = length_value; + } + } + + return ret; + } + + /** + * @brief Deserializes an extended parameter header. + * + * @param id The parameter ID. + * @param length The parameter length. + * + * @return ReturnCode + */ + safedds::ReturnCode deserialize_parameter_header_extended( + uint32_t& id, + uint32_t& length) + { + // Align to 4 bytes + safedds::ReturnCode ret = deserializer_align_to(4U); + + // Deserialize param_id + if (safedds::ReturnCode::OK == ret) + { + ret = deserialize(id); + } + + // Deserialize length + if (safedds::ReturnCode::OK == ret) + { + ret = deserialize(length); + } + + return ret; + } + +private: + + EncodingAlgorithm current_encoding_algorithm_; //!< The encoding algorithm in use. +}; + +/** + * @brief SafeDDSTypeSupportComparator class + */ +struct SafeDDSTypeSupportComparator +{ + /** + * @brief Compares a member. + * + * @param first The first value to compare. + * @param second The second value to compare. + * + * @return true if the values are equal, false otherwise. + */ + template + static typename std::enable_if::value && !std::is_same::value && !std::is_enum::value, bool>::type + equal( + const T& first, + const T& second) + { + return T::SerializationStruct::compare(first, second); + } + + /** + * @brief Compares two values. Specialization for arithmetic types, strings and enums. + */ + template + static typename std::enable_if::value || std::is_same::value || std::is_enum::value, bool>::type + equal( + const T& first, + const T& second) + { + return first == second; + } + + /** + * @brief Compares two values. Specialization for optional types. + */ + template + static bool equal( + const memory::Optional& first, + const memory::Optional& second) + { + bool ret = true; + + ret = ret && (first.has_value() == second.has_value()); + + if (first.has_value()) + { + ret = ret && equal(first.value(), second.value()); + } + + return ret; + } + + /** + * @brief Compares two values. Specialization for array types. + */ + template + static bool equal( + const std::array& first, + const std::array& second) + { + bool ret = true; + + for (size_t i = 0; i < N; ++i) + { + ret = ret && equal(first[i], second[i]); + + if (!ret) + { + break; + } + } + + return ret; + } + + /** + * @brief Compares two values. Specialization for vector types. + */ + template + static bool equal( + const std::vector& first, + const std::vector& second) + { + bool ret = true; + + ret = ret && (first.size() == second.size()); + + for (size_t i = 0; ret && i < first.size(); ++i) + { + ret = ret && equal(first[i], second[i]); + + if (!ret) + { + break; + } + } + + return ret; + } + + /** + * @brief Compares two values. Specialization for map types. + */ + template + static bool equal( + const std::map& first, + const std::map& second) + { + bool ret = true; + + ret = ret && (first.size() == second.size()); + + for (auto it = first.begin(); ret && it != first.end(); ++it) + { + auto it2 = second.find(it->first); + + if (it2 == second.end()) + { + ret = false; + } + else + { + ret = ret && equal(it->second, it2->second); + } + } + + return ret; + } + + /** + * @brief Compares two values. Specialization for external types. + */ + template + static bool equal( + const External& first, + const External& second) + { + bool ret = false; + + if (first.member == second.member) + { + ret = true; + } + + return ret; + } + + /** + * @brief Compares two values. Specialization for external sequences. + */ + template + static bool equal( + const ExternalSequence& first, + const ExternalSequence& second) + { + bool ret = false; + + if (first.member == second.member) + { + if (first.member != nullptr) + { + ret = first.len == second.len; + } + else + { + ret = true; + } + } + + return ret; + } + + /** + * @brief Compares two values. Specialization for external arrays. + */ + template + static bool equal( + const ExternalArray& first, + const ExternalArray& second) + { + bool ret = false; + + if (first.member == second.member) + { + ret = true; + } + + return ret; + } + + /** + * @brief Compares two values. Specialization for external strings. + */ + static bool equal( + const ExternalString& first, + const ExternalString& second) + { + bool ret = false; + + if (first.member == second.member) + { + if (first.member != nullptr) + { + ret = first.len == second.len; + } + else + { + ret = true; + } + } + + return ret; + } + +}; + +} // namespace gen +} // namespace safedds +} // namespace eprosima + +#endif // SAFEDDS_SAFEDDSGEN_SAFEDDSGENAUX_HPP diff --git a/safe_dds/idl/SafeDDSGenTypeTraits.hpp b/safe_dds/idl/SafeDDSGenTypeTraits.hpp new file mode 100644 index 0000000..4a34bb9 --- /dev/null +++ b/safe_dds/idl/SafeDDSGenTypeTraits.hpp @@ -0,0 +1,270 @@ +/** + * Copyright (C) 2024, Proyectos y Sistemas de Mantenimiento SL (eProsima) + * + * This program is commercial software licensed under the terms of the + * eProsima Software License Agreement Rev 03 (the "License") + * + * You may obtain a copy of the License at + * https://www.eprosima.com/licenses/LICENSE-REV03 + * + */ + +/** + * @file SafeDDSGenTypeTraits.hpp + */ + +#ifndef SAFEDDS_SAFEDDSGEN_SAFEDDSGENTYPETRAITS_HPP +#define SAFEDDS_SAFEDDSGEN_SAFEDDSGENTYPETRAITS_HPP + +#include + +#include +#include +#include +#include + +namespace eprosima { +namespace safedds { +namespace gen { + +/* + * @section Basic type traits + */ + +//! Is arithmetic or enum +template +struct is_arithmetic_or_enum : + std::integral_constant::value || std::is_enum::value> {}; + +//! Is array (false by default) +template +struct is_array : + std::false_type {}; + +//! Is array (true for std::array) +template +struct is_array> : + std::true_type {}; + +//! Is sequence (false by default) +template +struct is_sequence : + std::false_type {}; + +//! Is sequence (true for std::vector) +template +struct is_sequence> : + std::true_type {}; + +//! Is map (false by default) +template +struct is_map : + std::false_type {}; + +//! Is map (true for std::map) +template +struct is_map> : + std::true_type {}; + +//! Is string +template +struct is_string : + std::is_same {}; + +//! Is optional (false by default) +template +struct is_optional : + std::false_type {}; + +//! Is optional (true for safedds::memory::Optional) +template +struct is_optional> : + std::true_type {}; + +//! Is external type (false by default) +template +struct is_external : + std::false_type {}; + +//! Is external type +template +struct External; +template +struct is_external> : + std::true_type {}; + +//! Is external array type (false by default) +template +struct is_external_array : + std::false_type {}; + +//! Is external array type +template +struct ExternalArray; +template +struct is_external_array> : + std::true_type {}; + +//! Is external sequence type (false by default) +template +struct is_external_sequence : + std::false_type {}; + +//! Is external sequence type +template +struct ExternalSequence; +template +struct is_external_sequence> : + std::true_type {}; + +//! Is external string type (false by default) +template +struct is_external_string : + std::false_type {}; + +//! Is external string type +struct ExternalString; +template<> +struct is_external_string : + std::true_type {}; + +//! Is IDLUnion (not C/C++ union, false by default) +struct IDLUnion; +template +struct is_idl_union : + std::is_base_of {}; + +/* + * @section Dheader type traits + */ + +//! By default all types require dheader (included sequences of sequences) +template::value || is_array::value || is_external_sequence::value || is_external_array::value>::type, + typename Enable = void> +struct sequence_or_array_require_dheader : + std::true_type {}; + +//! Specialization for arithmetic types and enums do not require dheader +template +struct sequence_or_array_require_dheader::value>::type> : + std::false_type {}; + +//! Specialization for array types +template +struct sequence_or_array_require_dheader::value>::type> : + sequence_or_array_require_dheader {}; + +//! Specialization for maps +template +struct map_require_dheader : + std::true_type {}; + +//! Specialization for maps with arithmetic types +template +struct map_require_dheader::value && is_arithmetic_or_enum::value>::type> : + std::false_type {}; + +/* + * @section IDL extensibility kind type traits + */ + +//! @brief IDL extensibility kind +enum class IDLExtensibilityKind : uint8_t +{ + FINAL, + APPENDABLE, + MUTABLE +}; + +//! By default get the IDL extensibility kind and check if it is FINAL +template +struct is_idl_extensibility_final +{ + static constexpr bool value = T::IDL_EXTENSIBILITY == IDLExtensibilityKind::FINAL; +}; + +/* + * @brief Specialization for primitive and container types that are considered extensibility FINAL + * + * @note The following types are considered extensibility FINAL: + * - Arithmetic types + * - Enums + * - Arrays + * - Sequences + * - Maps + * - Strings + * - Optional + * - External types + */ +template +struct is_idl_extensibility_final::value || is_array::value || is_sequence::value || is_map::value || is_string::value || is_optional::value || is_external::value || is_external_array::value || is_external_sequence::value || is_external_string::value>::type> +{ + static constexpr bool value = true; +}; + +//! Is Safe DDS serialization basic type +template +struct is_safe_dds_serialization_basic_type : + std::false_type {}; + +//! Is Safe DDS serialization basic type (true for all char, bool, uint8_t, uint16_t, uint32_t, uint64_t, int8_t, int16_t, int32_t, int64_t, float and double) +template +struct is_safe_dds_serialization_basic_type::value || + std::is_same::value || + std::is_same::value || + std::is_same::value || + std::is_same::value || + std::is_same::value || + std::is_same::value || + std::is_same::value || + std::is_same::value || + std::is_same::value || + std::is_same::value || + std::is_same::value>::type + > : + std::true_type {}; + +template::value || is_array::value || is_external_sequence::value || is_external_array::value, + int>::type = 0> +struct safe_dds_serialization_container_utils +{ + // Serialize complex types (except bool vectors) by element + static constexpr bool serialize_container_by_element = + !is_safe_dds_serialization_basic_type::value && + !std::is_same>::value; + + // Serialize bool vectors by element + static constexpr bool serialize_bool_vector_by_element = + std::is_same>::value; + + // Serialize basic types + static constexpr bool serialize_basic_type = + !serialize_container_by_element && !serialize_bool_vector_by_element; + + // Deserialize complex types (except bool vectors) by element + static constexpr bool deserialize_container_by_element = + !is_safe_dds_serialization_basic_type::value && + !std::is_same>::value; + + // Deserialize bool vectors by element + static constexpr bool deserialize_bool_vector_by_element = + std::is_same>::value; + + // Deserilize basic types + static constexpr bool deserialize_basic_type = + !deserialize_container_by_element && !deserialize_bool_vector_by_element; +}; + +} // namespace gen +} // namespace safedds +} // namespace eprosima + +#endif // SAFEDDS_SAFEDDSGEN_SAFEDDSGENTYPETRAITS_HPP diff --git a/safe_dds/idl/SafeDDSGenUtils.hpp b/safe_dds/idl/SafeDDSGenUtils.hpp new file mode 100644 index 0000000..04863b2 --- /dev/null +++ b/safe_dds/idl/SafeDDSGenUtils.hpp @@ -0,0 +1,225 @@ +/** + * Copyright (C) 2024, Proyectos y Sistemas de Mantenimiento SL (eProsima) + * + * This program is commercial software licensed under the terms of the + * eProsima Software License Agreement Rev 03 (the "License") + * + * You may obtain a copy of the License at + * https://www.eprosima.com/licenses/LICENSE-REV03 + * + */ + +/** + * @file SafeDDSGenUtils.hpp + */ + +#ifndef SAFEDDS_SAFEDDSGEN_SAFEDDSGENUTILS_HPP +#define SAFEDDS_SAFEDDSGEN_SAFEDDSGENUTILS_HPP + +#include + +#include +#include + +namespace eprosima { +namespace safedds { +namespace gen { + +template +struct ExternalSequence +{ + static_assert(is_safe_dds_serialization_basic_type::value || std::is_enum::value, + "T must be a basic or enum type"); + + using value_type = T; + + uint32_t size() const + { + return len; + } + + T* data() const + { + return member; + } + + bool empty() const + { + return (member == nullptr) || (len == 0); + } + + T* member = nullptr; + uint32_t len = 0; + uint32_t capacity = 0; +}; + +template +struct ExternalArray +{ + static_assert(is_safe_dds_serialization_basic_type::value || std::is_enum::value, + "T must be a basic or enum type"); + + using value_type = T; + + uint32_t size() const + { + return N; + } + + T* data() const + { + return member; + } + + bool empty() const + { + return (member == nullptr) || (N == 0); + } + + T* member = nullptr; +}; + +template +struct External +{ + static_assert(is_safe_dds_serialization_basic_type::value || std::is_enum::value, + "T must be a basic or enum type"); + + using value_type = T; + + T* member = nullptr; +}; + +struct ExternalString +{ + uint32_t size() const + { + return len; + } + + const char* data() const + { + return member; + } + + bool empty() const + { + return (member == nullptr) || (len == 0); + } + + const char* member = nullptr; + uint32_t len = 0; + uint32_t capacity = 0; +}; + +//! @brief Union type marker +struct IDLUnion +{ + virtual uint32_t get_current_union_size() const = 0; +}; + +/** + * @brief EncodingAlgorithm enumeration. + */ +enum class EncodingAlgorithm +{ + PLAIN_CDR, + PL_CDR, + PLAIN_CDR2, + DELIMITED_CDR, + PL_CDR2 +}; + +//! @brief DDS-XTypes Reserved Parameter IDs +constexpr uint16_t PID_EXTENDED = 0x3F01; +constexpr uint16_t PID_LIST_END = 0x3F02; +constexpr uint16_t PID_IGNORE = 0x3F03; + +//! @brief Maximum short Parameter ID +constexpr uint16_t PID_MAX_SHORT = 0x3F00; +constexpr uint32_t PID_MAX_CDRV2 = 0x0FFFFFFF; + +/** + * @brief Retrieves the value of the parameter ID. + * + * @param pid The parameter ID. + * @param extended Flag indicating if the parameter ID is extended. + * + * @return The value of the parameter ID. + */ +constexpr uint32_t get_pid_value( + uint32_t pid, + bool extended) +{ + // Take into account the size of the parameter ID + return extended ? (pid & 0x3FFFFFFF) : (pid & 0x3FFF); +} + +/** + * @brief Checks if the parameter ID is an implementation extension. + * + * @param pid The parameter ID. + * @param extended Flag indicating if the parameter ID is extended. + * + * @return true if the parameter ID is an implementation extension, false otherwise. + */ +constexpr bool is_pid_implementation_extension( + uint32_t pid, + bool extended) +{ + return extended ? (pid & 0x80000000) : 0 != (pid & 0x8000); +} + +/** + * @brief Checks if the parameter ID must be understood. + * + * @param pid The parameter ID. + * @param extended Flag indicating if the parameter ID is extended. + * + * @return true if the parameter ID must be understood, false otherwise. + */ +constexpr bool is_pid_must_understand( + uint16_t pid, + bool extended) +{ + return extended ? (pid & 0x40000000) : 0 != (pid & 0x4000); +} + +/** + * @brief Resize a sequence to a given size. + */ +template +typename std::enable_if::value || is_string::value, safedds::ReturnCode>::type resize_container( + V& container, + const uint32_t& size) +{ + container.resize(size); + + return safedds::ReturnCode::OK; +} + +template +typename std::enable_if::value || is_external_string::value, + safedds::ReturnCode>::type resize_container( + V& container, + const uint32_t& size) +{ + safedds::ReturnCode ret = safedds::ReturnCode::OK; + + if (size > container.capacity) + { + ret = safedds::ReturnCode::ERROR; + } + else + { + container.len = size; + } + + return ret; +} + +} // namespace gen +} // namespace safedds +} // namespace eprosima + +#endif // SAFEDDS_SAFEDDSGEN_SAFEDDSGENUTILS_HPP diff --git a/safe_dds/idl/common.hpp b/safe_dds/idl/common.hpp new file mode 100644 index 0000000..0240553 --- /dev/null +++ b/safe_dds/idl/common.hpp @@ -0,0 +1,1228 @@ +// This file was generated by Safe DDS code generator, which is +// Copyright (C) 2023, Proyectos y Sistemas de Mantenimiento SL (eProsima) +// +// This program is commercial software licensed under the terms of the +// eProsima Software License Agreement Rev 03 (the "License") +// +// You may obtain a copy of the License at +// https://www.eprosima.com/licenses/LICENSE-REV03 + +/*! + * @file common.hpp + * This header file contains the declaration of the types described in the IDL file. + * + * This file was generated by Safe-DDS-gen. + */ + +#ifndef SAFEDDS_GENERATED__SAFE_EDGE_COMMON_COMMON_HPP +#define SAFEDDS_GENERATED__SAFE_EDGE_COMMON_COMMON_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + + + +namespace safe_edge { + namespace common { + + // Forward declaration + struct HeaderSerialization; + + /*! + * @brief This struct represents the structure Header defined by the user in the IDL file. + * @ingroup common + */ + struct Header + { + using SerializationStruct = HeaderSerialization; + + static constexpr eprosima::safedds::gen::IDLExtensibilityKind IDL_EXTENSIBILITY = eprosima::safedds::gen::IDLExtensibilityKind::APPENDABLE; + + /// Member source + std::string source ; + /// Member timestamp_ms + uint64_t timestamp_ms = 0; + /// Member trace_id + std::string trace_id ; + + // Ensure bounds + static_assert(255 != 0, "source shall be bounded or --default_unbounded_max_size shall be used"); + + static_assert(255 != 0, "trace_id shall be bounded or --default_unbounded_max_size shall be used"); + }; + + struct HeaderSerialization + { + static constexpr uint32_t max_serialized_size() + { + // Return the precalculated max_serialized_size plus required: + // - Representation Header size (+4 B) since it is serialized in the typesupport serialization method + // - Alignment to 4 B since the serialization method adds padding + return eprosima::safedds::memory::align_to<532ULL + 4ULL, 4U>(); + } + + static constexpr uint32_t max_key_serialized_size() + { + return 0ULL; + } + + static eprosima::safedds::ReturnCode serialize( + eprosima::safedds::gen::SafeDDSTypeSupportSerializer& ser, + const Header& sample) + { + using namespace safe_edge::common; + + eprosima::safedds::gen::EncodingAlgorithm prev_encoding = ser.get_encoding_algorithm(); + eprosima::safedds::ReturnCode ret = ser.set_encoding_algorithm( + ser.get_xcdr_version() == eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 ? + eprosima::safedds::gen::EncodingAlgorithm::PLAIN_CDR : + eprosima::safedds::gen::EncodingAlgorithm::DELIMITED_CDR); + + ret = ((eprosima::safedds::ReturnCode::OK == ret) && (sample.source.size() <= 255)) ? ret : eprosima::safedds::ReturnCode::ERROR; + ret = ((eprosima::safedds::ReturnCode::OK == ret) && (sample.trace_id.size() <= 255)) ? ret : eprosima::safedds::ReturnCode::ERROR; + + + + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.begin_serialize_type() : ret; + + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type(0, sample.source) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type(1, sample.timestamp_ms) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type(2, sample.trace_id) : ret; + + if(eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser.end_serialize_type(); + } + + if(eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser.set_encoding_algorithm(prev_encoding); + } + + return ret; + } + + static eprosima::safedds::ReturnCode deserialize( + eprosima::safedds::gen::SafeDDSTypeSupportDeserializer& deser, + Header& sample) + { + using namespace safe_edge::common; + + // Store the values of the external members in auxiliary variables + + sample = {}; + + // Restore the values of the external members + + const eprosima::safedds::gen::EncodingAlgorithm encoding = + deser.get_xcdr_version() == eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 ? + eprosima::safedds::gen::EncodingAlgorithm::PLAIN_CDR : + eprosima::safedds::gen::EncodingAlgorithm::DELIMITED_CDR; + + return deser.deserialize_type(encoding, + [&sample](eprosima::safedds::gen::SafeDDSTypeSupportDeserializer& inner_deser, const uint32_t id) -> eprosima::safedds::ReturnCode + { + eprosima::safedds::ReturnCode ret_value = eprosima::safedds::ReturnCode::OK; + switch (id) + { + case 0: + ret_value = inner_deser.deserialize_member(sample.source); + break; + + case 1: + ret_value = inner_deser.deserialize_member(sample.timestamp_ms); + break; + + case 2: + ret_value = inner_deser.deserialize_member(sample.trace_id); + break; + + default: + ret_value = eprosima::safedds::ReturnCode::UNIMPLEMENTED; + break; + } + return ret_value; + }); + } + + static eprosima::safedds::ReturnCode serialize_key( + eprosima::safedds::gen::SafeDDSTypeSupportSerializer& ser, + const Header& sample) + { + using namespace safe_edge::common; + + + eprosima::safedds::gen::EncodingAlgorithm prev_encoding = ser.get_encoding_algorithm(); + eprosima::safedds::ReturnCode ret = ser.set_encoding_algorithm(eprosima::safedds::gen::EncodingAlgorithm::PLAIN_CDR2); + + ret = ((eprosima::safedds::ReturnCode::OK == ret) && (sample.source.size() <= 255)) ? ret : eprosima::safedds::ReturnCode::ERROR; + ret = ((eprosima::safedds::ReturnCode::OK == ret) && (sample.trace_id.size() <= 255)) ? ret : eprosima::safedds::ReturnCode::ERROR; + + + + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.begin_serialize_type() : ret; + + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type_key(0, sample.source) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type_key(1, sample.timestamp_ms) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type_key(2, sample.trace_id) : ret; + + + if(eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser.end_serialize_type(); + } + + if(eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser.set_encoding_algorithm(prev_encoding); + } + + return ret; + + } + + static bool compare( + const Header& first, + const Header& second) + { + using namespace safe_edge::common; + + bool ret = true; + + ret = ret && eprosima::safedds::gen::SafeDDSTypeSupportComparator::equal(first.source, second.source); + ret = ret && eprosima::safedds::gen::SafeDDSTypeSupportComparator::equal(first.timestamp_ms, second.timestamp_ms); + ret = ret && eprosima::safedds::gen::SafeDDSTypeSupportComparator::equal(first.trace_id, second.trace_id); + + return ret; + } + }; + + + struct HeaderTypeSupport : + public eprosima::safedds::dds::TypedTypeSupport
+ { + using DataType = Header; + + eprosima::safedds::dds::ReturnCode register_type( + eprosima::safedds::dds::DomainParticipant& participant, + const eprosima::safedds::memory::IStringView& type_name) noexcept override + { + return participant.register_type(*this, type_name); + } + + const eprosima::safedds::memory::IStringView& get_type_name() const noexcept override + { + static constexpr char const* default_name = "safe_edge::common::Header"; + static const eprosima::safedds::memory::container::StaticString256 typesupport_name(default_name); + return typesupport_name; + } + + uint32_t max_serialized_size() const noexcept override + { + return HeaderSerialization::max_serialized_size(); + } + + uint32_t serialized_size( + const Header& sample, + eprosima::safedds::serialization::cdr::XCDRVersion xcdr_version) const noexcept override + { + uint32_t sample_size = 0; + + if (eprosima::safedds::ReturnCode::OK == sample_serialized_size(sample, xcdr_version, sample_size)) + { + sample_size = eprosima::safedds::memory::align_to( + eprosima::safedds::portable::safe_sizeof() + + sample_size, 4); + } + + return sample_size; + } + + eprosima::safedds::ReturnCode serialize( + const Header& sample, + eprosima::safedds::memory::IByteArrayView& buffer, + eprosima::safedds::serialization::cdr::XCDRVersion xcdr_version) const noexcept override + { + eprosima::safedds::ReturnCode ret = + (eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 == xcdr_version) || (eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV2 == xcdr_version) ? + eprosima::safedds::ReturnCode::OK : eprosima::safedds::ReturnCode::ERROR; + + eprosima::safedds::serialization::RepresentationHeader representation_header{}; + + if (eprosima::safedds::ReturnCode::OK == ret) + { + if(eprosima::safedds::portable::MACHINE_ENDIANNESS == eprosima::safedds::platform::Endianness::SAFEDDS_BIG_ENDIAN) + { + representation_header = + eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 == xcdr_version ? + eprosima::safedds::serialization::REPRESENTATION_HEADER_CDR_BE : + eprosima::safedds::serialization::REPRESENTATION_HEADER_DELIMITED_CDR_BE; + } + else + { + representation_header = + eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 == xcdr_version ? + eprosima::safedds::serialization::REPRESENTATION_HEADER_CDR_LE : + eprosima::safedds::serialization::REPRESENTATION_HEADER_DELIMITED_CDR_LE; + } + } + + uint32_t sample_size = 0; + + if (eprosima::safedds::ReturnCode::OK == ret) + { + ret = sample_serialized_size(sample, xcdr_version, sample_size); + } + + uint32_t aligned_size = eprosima::safedds::memory::align_to(sample_size, 4); + uint32_t payload_size = eprosima::safedds::portable::safe_sizeof() + aligned_size; + + if (eprosima::safedds::ReturnCode::OK == ret && buffer.size() >= payload_size) + { + // Indicate the number of padding bytes in the encapsulation options + uint32_t required_padding = aligned_size - sample_size; + representation_header.encapsulation_options[1] = static_cast(required_padding); + + eprosima::safedds::gen::SafeDDSTypeSupportSerializer ser_rh(buffer, eprosima::safedds::portable::MACHINE_ENDIANNESS, xcdr_version); + ret = ser_rh.serialize_array( + representation_header.encapsulation_kind.data(), + eprosima::safedds::serialization::RepresentationHeader::ENCAPSULATION_KIND_SIZE); + + if (eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser_rh.serialize_array( + representation_header.encapsulation_options.data(), eprosima::safedds::serialization::RepresentationHeader::ENCAPSULATION_OPTIONS_SIZE); + } + + if (eprosima::safedds::ReturnCode::OK == ret && sample_size > 0) + { + eprosima::safedds::memory::byte_array::ByteArrayView payload_view = { + &buffer[ser_rh.serializer_used_size()], + ser_rh.serializer_remaining_size() + }; + + eprosima::safedds::gen::SafeDDSTypeSupportSerializer ser(payload_view, eprosima::safedds::portable::MACHINE_ENDIANNESS, xcdr_version); + + ret = HeaderSerialization::serialize(ser, sample); + + // Add padding + for (uint32_t i = 0; (eprosima::safedds::ReturnCode::OK == ret) && (i < required_padding); ++i) + { + ret = ser.serialize('\0'); + } + } + } + + return ret; + } + + eprosima::safedds::ReturnCode deserialize( + const eprosima::safedds::memory::IConstByteArrayView& buffer, + Header& sample) const noexcept override + { + eprosima::safedds::serialization::RepresentationHeader representation_header{}; + + eprosima::safedds::serialization::cdr::Deserializer deserializer_rh(buffer, eprosima::safedds::portable::MACHINE_ENDIANNESS, eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1); + eprosima::safedds::ReturnCode ret = eprosima::safedds::protocol::rtps::RTPSTypeSupport::deserialize(deserializer_rh, representation_header); + + // Check expected RepresentationHeader type to be valid and supported + const bool is_cdr_v1 = representation_header.encapsulation_kind[0U] == 0U && (representation_header.encapsulation_kind[1U] <= 0x03U); + const bool is_cdr_v2 = representation_header.encapsulation_kind[0U] == 0U && (representation_header.encapsulation_kind[1U] >= 0x06U && representation_header.encapsulation_kind[1U] <= 0x0BU); + ret = (eprosima::safedds::ReturnCode::OK == ret && (is_cdr_v1 || is_cdr_v2)) ? eprosima::safedds::ReturnCode::OK : eprosima::safedds::ReturnCode::ERROR; + + // Skip payload + eprosima::safedds::memory::byte_array::ByteArrayView payload_view = {nullptr, 0U}; + uint32_t remaining_size = deserializer_rh.deserializer_remaining_size(); + if (eprosima::safedds::ReturnCode::OK == ret && remaining_size > 0) + { + uint32_t padding_size = static_cast(representation_header.encapsulation_options[1] & 0x03); + if (remaining_size >= padding_size) + { + remaining_size -= padding_size; + ret = deserializer_rh.deserializer_skip(remaining_size, payload_view); + } + else + { + ret = eprosima::safedds::ReturnCode::SERIALIZATION_INVALID_REPRESENTATION; + } + } + + if (eprosima::safedds::ReturnCode::OK == ret && remaining_size > 0) + { + // Get received endianness and deserialize payload + eprosima::safedds::gen::SafeDDSTypeSupportDeserializer deserializer(payload_view, + representation_header.get_endianness(), + is_cdr_v1 ? eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 : eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV2); + + ret = HeaderSerialization::deserialize(deserializer, sample); + } + + return ret; + } + + eprosima::safedds::dds::ReturnCode get_key( + const Header& data, + eprosima::safedds::dds::KeyHash& key_hash) const noexcept override + { + key_hash = {}; + + static_cast(data); + + return eprosima::safedds::dds::ReturnCode::ILLEGAL_OPERATION; + } + + eprosima::safedds::dds::ReturnCode get_key_from_payload( + const eprosima::safedds::memory::IConstByteArrayView& view, + const eprosima::safedds::protocol::PayloadKind& kind, + eprosima::safedds::dds::KeyHash& key_hash) const noexcept override + { + key_hash = {}; + + static_cast(view); + static_cast(kind); + + return eprosima::safedds::dds::ReturnCode::ILLEGAL_OPERATION; + } + + bool has_keys() const noexcept override + { + return false; + } + + private: + + eprosima::safedds::ReturnCode sample_serialized_size( + const Header& sample, + eprosima::safedds::serialization::cdr::XCDRVersion xcdr_version, + uint32_t & serialized_size) const noexcept + { + serialized_size = 0; + + // Create a fake serializer to calculate the serialized size + eprosima::safedds::gen::SafeDDSTypeSupportSerializer ser(eprosima::safedds::portable::MACHINE_ENDIANNESS, xcdr_version); + eprosima::safedds::ReturnCode ret = HeaderSerialization::serialize(ser, sample); + + if(eprosima::safedds::ReturnCode::OK == ret) + { + serialized_size = ser.serializer_used_size(); + } + + return ret; + } + + }; + + + + // Forward declaration + struct GeoPointSerialization; + + /*! + * @brief This struct represents the structure GeoPoint defined by the user in the IDL file. + * @ingroup common + */ + struct GeoPoint + { + using SerializationStruct = GeoPointSerialization; + + static constexpr eprosima::safedds::gen::IDLExtensibilityKind IDL_EXTENSIBILITY = eprosima::safedds::gen::IDLExtensibilityKind::APPENDABLE; + + /// Member latitude + double latitude = 0.0; + /// Member longitude + double longitude = 0.0; + + // Ensure bounds + }; + + struct GeoPointSerialization + { + static constexpr uint32_t max_serialized_size() + { + // Return the precalculated max_serialized_size plus required: + // - Representation Header size (+4 B) since it is serialized in the typesupport serialization method + // - Alignment to 4 B since the serialization method adds padding + return eprosima::safedds::memory::align_to<24ULL + 4ULL, 4U>(); + } + + static constexpr uint32_t max_key_serialized_size() + { + return 0ULL; + } + + static eprosima::safedds::ReturnCode serialize( + eprosima::safedds::gen::SafeDDSTypeSupportSerializer& ser, + const GeoPoint& sample) + { + using namespace safe_edge::common; + + eprosima::safedds::gen::EncodingAlgorithm prev_encoding = ser.get_encoding_algorithm(); + eprosima::safedds::ReturnCode ret = ser.set_encoding_algorithm( + ser.get_xcdr_version() == eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 ? + eprosima::safedds::gen::EncodingAlgorithm::PLAIN_CDR : + eprosima::safedds::gen::EncodingAlgorithm::DELIMITED_CDR); + + + + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.begin_serialize_type() : ret; + + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type(0, sample.latitude) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type(1, sample.longitude) : ret; + + if(eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser.end_serialize_type(); + } + + if(eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser.set_encoding_algorithm(prev_encoding); + } + + return ret; + } + + static eprosima::safedds::ReturnCode deserialize( + eprosima::safedds::gen::SafeDDSTypeSupportDeserializer& deser, + GeoPoint& sample) + { + using namespace safe_edge::common; + + // Store the values of the external members in auxiliary variables + + sample = {}; + + // Restore the values of the external members + + const eprosima::safedds::gen::EncodingAlgorithm encoding = + deser.get_xcdr_version() == eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 ? + eprosima::safedds::gen::EncodingAlgorithm::PLAIN_CDR : + eprosima::safedds::gen::EncodingAlgorithm::DELIMITED_CDR; + + return deser.deserialize_type(encoding, + [&sample](eprosima::safedds::gen::SafeDDSTypeSupportDeserializer& inner_deser, const uint32_t id) -> eprosima::safedds::ReturnCode + { + eprosima::safedds::ReturnCode ret_value = eprosima::safedds::ReturnCode::OK; + switch (id) + { + case 0: + ret_value = inner_deser.deserialize_member(sample.latitude); + break; + + case 1: + ret_value = inner_deser.deserialize_member(sample.longitude); + break; + + default: + ret_value = eprosima::safedds::ReturnCode::UNIMPLEMENTED; + break; + } + return ret_value; + }); + } + + static eprosima::safedds::ReturnCode serialize_key( + eprosima::safedds::gen::SafeDDSTypeSupportSerializer& ser, + const GeoPoint& sample) + { + using namespace safe_edge::common; + + + eprosima::safedds::gen::EncodingAlgorithm prev_encoding = ser.get_encoding_algorithm(); + eprosima::safedds::ReturnCode ret = ser.set_encoding_algorithm(eprosima::safedds::gen::EncodingAlgorithm::PLAIN_CDR2); + + + + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.begin_serialize_type() : ret; + + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type_key(0, sample.latitude) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type_key(1, sample.longitude) : ret; + + + if(eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser.end_serialize_type(); + } + + if(eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser.set_encoding_algorithm(prev_encoding); + } + + return ret; + + } + + static bool compare( + const GeoPoint& first, + const GeoPoint& second) + { + using namespace safe_edge::common; + + bool ret = true; + + ret = ret && eprosima::safedds::gen::SafeDDSTypeSupportComparator::equal(first.latitude, second.latitude); + ret = ret && eprosima::safedds::gen::SafeDDSTypeSupportComparator::equal(first.longitude, second.longitude); + + return ret; + } + }; + + + struct GeoPointTypeSupport : + public eprosima::safedds::dds::TypedTypeSupport + { + using DataType = GeoPoint; + + eprosima::safedds::dds::ReturnCode register_type( + eprosima::safedds::dds::DomainParticipant& participant, + const eprosima::safedds::memory::IStringView& type_name) noexcept override + { + return participant.register_type(*this, type_name); + } + + const eprosima::safedds::memory::IStringView& get_type_name() const noexcept override + { + static constexpr char const* default_name = "safe_edge::common::GeoPoint"; + static const eprosima::safedds::memory::container::StaticString256 typesupport_name(default_name); + return typesupport_name; + } + + uint32_t max_serialized_size() const noexcept override + { + return GeoPointSerialization::max_serialized_size(); + } + + uint32_t serialized_size( + const GeoPoint& sample, + eprosima::safedds::serialization::cdr::XCDRVersion xcdr_version) const noexcept override + { + uint32_t sample_size = 0; + + if (eprosima::safedds::ReturnCode::OK == sample_serialized_size(sample, xcdr_version, sample_size)) + { + sample_size = eprosima::safedds::memory::align_to( + eprosima::safedds::portable::safe_sizeof() + + sample_size, 4); + } + + return sample_size; + } + + eprosima::safedds::ReturnCode serialize( + const GeoPoint& sample, + eprosima::safedds::memory::IByteArrayView& buffer, + eprosima::safedds::serialization::cdr::XCDRVersion xcdr_version) const noexcept override + { + eprosima::safedds::ReturnCode ret = + (eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 == xcdr_version) || (eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV2 == xcdr_version) ? + eprosima::safedds::ReturnCode::OK : eprosima::safedds::ReturnCode::ERROR; + + eprosima::safedds::serialization::RepresentationHeader representation_header{}; + + if (eprosima::safedds::ReturnCode::OK == ret) + { + if(eprosima::safedds::portable::MACHINE_ENDIANNESS == eprosima::safedds::platform::Endianness::SAFEDDS_BIG_ENDIAN) + { + representation_header = + eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 == xcdr_version ? + eprosima::safedds::serialization::REPRESENTATION_HEADER_CDR_BE : + eprosima::safedds::serialization::REPRESENTATION_HEADER_DELIMITED_CDR_BE; + } + else + { + representation_header = + eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 == xcdr_version ? + eprosima::safedds::serialization::REPRESENTATION_HEADER_CDR_LE : + eprosima::safedds::serialization::REPRESENTATION_HEADER_DELIMITED_CDR_LE; + } + } + + uint32_t sample_size = 0; + + if (eprosima::safedds::ReturnCode::OK == ret) + { + ret = sample_serialized_size(sample, xcdr_version, sample_size); + } + + uint32_t aligned_size = eprosima::safedds::memory::align_to(sample_size, 4); + uint32_t payload_size = eprosima::safedds::portable::safe_sizeof() + aligned_size; + + if (eprosima::safedds::ReturnCode::OK == ret && buffer.size() >= payload_size) + { + // Indicate the number of padding bytes in the encapsulation options + uint32_t required_padding = aligned_size - sample_size; + representation_header.encapsulation_options[1] = static_cast(required_padding); + + eprosima::safedds::gen::SafeDDSTypeSupportSerializer ser_rh(buffer, eprosima::safedds::portable::MACHINE_ENDIANNESS, xcdr_version); + ret = ser_rh.serialize_array( + representation_header.encapsulation_kind.data(), + eprosima::safedds::serialization::RepresentationHeader::ENCAPSULATION_KIND_SIZE); + + if (eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser_rh.serialize_array( + representation_header.encapsulation_options.data(), eprosima::safedds::serialization::RepresentationHeader::ENCAPSULATION_OPTIONS_SIZE); + } + + if (eprosima::safedds::ReturnCode::OK == ret && sample_size > 0) + { + eprosima::safedds::memory::byte_array::ByteArrayView payload_view = { + &buffer[ser_rh.serializer_used_size()], + ser_rh.serializer_remaining_size() + }; + + eprosima::safedds::gen::SafeDDSTypeSupportSerializer ser(payload_view, eprosima::safedds::portable::MACHINE_ENDIANNESS, xcdr_version); + + ret = GeoPointSerialization::serialize(ser, sample); + + // Add padding + for (uint32_t i = 0; (eprosima::safedds::ReturnCode::OK == ret) && (i < required_padding); ++i) + { + ret = ser.serialize('\0'); + } + } + } + + return ret; + } + + eprosima::safedds::ReturnCode deserialize( + const eprosima::safedds::memory::IConstByteArrayView& buffer, + GeoPoint& sample) const noexcept override + { + eprosima::safedds::serialization::RepresentationHeader representation_header{}; + + eprosima::safedds::serialization::cdr::Deserializer deserializer_rh(buffer, eprosima::safedds::portable::MACHINE_ENDIANNESS, eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1); + eprosima::safedds::ReturnCode ret = eprosima::safedds::protocol::rtps::RTPSTypeSupport::deserialize(deserializer_rh, representation_header); + + // Check expected RepresentationHeader type to be valid and supported + const bool is_cdr_v1 = representation_header.encapsulation_kind[0U] == 0U && (representation_header.encapsulation_kind[1U] <= 0x03U); + const bool is_cdr_v2 = representation_header.encapsulation_kind[0U] == 0U && (representation_header.encapsulation_kind[1U] >= 0x06U && representation_header.encapsulation_kind[1U] <= 0x0BU); + ret = (eprosima::safedds::ReturnCode::OK == ret && (is_cdr_v1 || is_cdr_v2)) ? eprosima::safedds::ReturnCode::OK : eprosima::safedds::ReturnCode::ERROR; + + // Skip payload + eprosima::safedds::memory::byte_array::ByteArrayView payload_view = {nullptr, 0U}; + uint32_t remaining_size = deserializer_rh.deserializer_remaining_size(); + if (eprosima::safedds::ReturnCode::OK == ret && remaining_size > 0) + { + uint32_t padding_size = static_cast(representation_header.encapsulation_options[1] & 0x03); + if (remaining_size >= padding_size) + { + remaining_size -= padding_size; + ret = deserializer_rh.deserializer_skip(remaining_size, payload_view); + } + else + { + ret = eprosima::safedds::ReturnCode::SERIALIZATION_INVALID_REPRESENTATION; + } + } + + if (eprosima::safedds::ReturnCode::OK == ret && remaining_size > 0) + { + // Get received endianness and deserialize payload + eprosima::safedds::gen::SafeDDSTypeSupportDeserializer deserializer(payload_view, + representation_header.get_endianness(), + is_cdr_v1 ? eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 : eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV2); + + ret = GeoPointSerialization::deserialize(deserializer, sample); + } + + return ret; + } + + eprosima::safedds::dds::ReturnCode get_key( + const GeoPoint& data, + eprosima::safedds::dds::KeyHash& key_hash) const noexcept override + { + key_hash = {}; + + static_cast(data); + + return eprosima::safedds::dds::ReturnCode::ILLEGAL_OPERATION; + } + + eprosima::safedds::dds::ReturnCode get_key_from_payload( + const eprosima::safedds::memory::IConstByteArrayView& view, + const eprosima::safedds::protocol::PayloadKind& kind, + eprosima::safedds::dds::KeyHash& key_hash) const noexcept override + { + key_hash = {}; + + static_cast(view); + static_cast(kind); + + return eprosima::safedds::dds::ReturnCode::ILLEGAL_OPERATION; + } + + bool has_keys() const noexcept override + { + return false; + } + + private: + + eprosima::safedds::ReturnCode sample_serialized_size( + const GeoPoint& sample, + eprosima::safedds::serialization::cdr::XCDRVersion xcdr_version, + uint32_t & serialized_size) const noexcept + { + serialized_size = 0; + + // Create a fake serializer to calculate the serialized size + eprosima::safedds::gen::SafeDDSTypeSupportSerializer ser(eprosima::safedds::portable::MACHINE_ENDIANNESS, xcdr_version); + eprosima::safedds::ReturnCode ret = GeoPointSerialization::serialize(ser, sample); + + if(eprosima::safedds::ReturnCode::OK == ret) + { + serialized_size = ser.serializer_used_size(); + } + + return ret; + } + + }; + + + enum class HealthStatus : int32_t + { + HEALTH_UNKNOWN , + HEALTH_OK , + HEALTH_DEGRADED , + HEALTH_ERROR + }; + + + // Forward declaration + struct ServiceHeartbeatSerialization; + + /*! + * @brief This struct represents the structure ServiceHeartbeat defined by the user in the IDL file. + * @ingroup common + */ + struct ServiceHeartbeat + { + using SerializationStruct = ServiceHeartbeatSerialization; + + static constexpr eprosima::safedds::gen::IDLExtensibilityKind IDL_EXTENSIBILITY = eprosima::safedds::gen::IDLExtensibilityKind::APPENDABLE; + + /// Member header_st + safe_edge::common::Header header_st ; + /// Member service_name + std::string service_name ; + /// Member status + safe_edge::common::HealthStatus status = safe_edge::common::HealthStatus::HEALTH_UNKNOWN; + /// Member detail + std::string detail ; + + // Ensure bounds + static_assert(255 != 0, "service_name shall be bounded or --default_unbounded_max_size shall be used"); + + static_assert(255 != 0, "detail shall be bounded or --default_unbounded_max_size shall be used"); + }; + + struct ServiceHeartbeatSerialization + { + static constexpr uint32_t max_serialized_size() + { + // Return the precalculated max_serialized_size plus required: + // - Representation Header size (+4 B) since it is serialized in the typesupport serialization method + // - Alignment to 4 B since the serialization method adds padding + return eprosima::safedds::memory::align_to<1064ULL + 4ULL, 4U>(); + } + + static constexpr uint32_t max_key_serialized_size() + { + return 0ULL; + } + + static eprosima::safedds::ReturnCode serialize( + eprosima::safedds::gen::SafeDDSTypeSupportSerializer& ser, + const ServiceHeartbeat& sample) + { + using namespace safe_edge::common; + + eprosima::safedds::gen::EncodingAlgorithm prev_encoding = ser.get_encoding_algorithm(); + eprosima::safedds::ReturnCode ret = ser.set_encoding_algorithm( + ser.get_xcdr_version() == eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 ? + eprosima::safedds::gen::EncodingAlgorithm::PLAIN_CDR : + eprosima::safedds::gen::EncodingAlgorithm::DELIMITED_CDR); + + ret = ((eprosima::safedds::ReturnCode::OK == ret) && (sample.service_name.size() <= 255)) ? ret : eprosima::safedds::ReturnCode::ERROR; + ret = ((eprosima::safedds::ReturnCode::OK == ret) && (sample.detail.size() <= 255)) ? ret : eprosima::safedds::ReturnCode::ERROR; + + + + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.begin_serialize_type() : ret; + + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type(0, sample.header_st) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type(1, sample.service_name) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type(2, sample.status) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type(3, sample.detail) : ret; + + if(eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser.end_serialize_type(); + } + + if(eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser.set_encoding_algorithm(prev_encoding); + } + + return ret; + } + + static eprosima::safedds::ReturnCode deserialize( + eprosima::safedds::gen::SafeDDSTypeSupportDeserializer& deser, + ServiceHeartbeat& sample) + { + using namespace safe_edge::common; + + // Store the values of the external members in auxiliary variables + + sample = {}; + + // Restore the values of the external members + + const eprosima::safedds::gen::EncodingAlgorithm encoding = + deser.get_xcdr_version() == eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 ? + eprosima::safedds::gen::EncodingAlgorithm::PLAIN_CDR : + eprosima::safedds::gen::EncodingAlgorithm::DELIMITED_CDR; + + return deser.deserialize_type(encoding, + [&sample](eprosima::safedds::gen::SafeDDSTypeSupportDeserializer& inner_deser, const uint32_t id) -> eprosima::safedds::ReturnCode + { + eprosima::safedds::ReturnCode ret_value = eprosima::safedds::ReturnCode::OK; + switch (id) + { + case 0: + ret_value = inner_deser.deserialize_member(sample.header_st); + break; + + case 1: + ret_value = inner_deser.deserialize_member(sample.service_name); + break; + + case 2: + ret_value = inner_deser.deserialize_member(sample.status); + break; + + case 3: + ret_value = inner_deser.deserialize_member(sample.detail); + break; + + default: + ret_value = eprosima::safedds::ReturnCode::UNIMPLEMENTED; + break; + } + return ret_value; + }); + } + + static eprosima::safedds::ReturnCode serialize_key( + eprosima::safedds::gen::SafeDDSTypeSupportSerializer& ser, + const ServiceHeartbeat& sample) + { + using namespace safe_edge::common; + + + eprosima::safedds::gen::EncodingAlgorithm prev_encoding = ser.get_encoding_algorithm(); + eprosima::safedds::ReturnCode ret = ser.set_encoding_algorithm(eprosima::safedds::gen::EncodingAlgorithm::PLAIN_CDR2); + + ret = ((eprosima::safedds::ReturnCode::OK == ret) && (sample.service_name.size() <= 255)) ? ret : eprosima::safedds::ReturnCode::ERROR; + ret = ((eprosima::safedds::ReturnCode::OK == ret) && (sample.detail.size() <= 255)) ? ret : eprosima::safedds::ReturnCode::ERROR; + + + + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.begin_serialize_type() : ret; + + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type_key(0, sample.header_st) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type_key(1, sample.service_name) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type_key(2, sample.status) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type_key(3, sample.detail) : ret; + + + if(eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser.end_serialize_type(); + } + + if(eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser.set_encoding_algorithm(prev_encoding); + } + + return ret; + + } + + static bool compare( + const ServiceHeartbeat& first, + const ServiceHeartbeat& second) + { + using namespace safe_edge::common; + + bool ret = true; + + ret = ret && eprosima::safedds::gen::SafeDDSTypeSupportComparator::equal(first.header_st, second.header_st); + ret = ret && eprosima::safedds::gen::SafeDDSTypeSupportComparator::equal(first.service_name, second.service_name); + ret = ret && eprosima::safedds::gen::SafeDDSTypeSupportComparator::equal(first.status, second.status); + ret = ret && eprosima::safedds::gen::SafeDDSTypeSupportComparator::equal(first.detail, second.detail); + + return ret; + } + }; + + + struct ServiceHeartbeatTypeSupport : + public eprosima::safedds::dds::TypedTypeSupport + { + using DataType = ServiceHeartbeat; + + eprosima::safedds::dds::ReturnCode register_type( + eprosima::safedds::dds::DomainParticipant& participant, + const eprosima::safedds::memory::IStringView& type_name) noexcept override + { + return participant.register_type(*this, type_name); + } + + const eprosima::safedds::memory::IStringView& get_type_name() const noexcept override + { + static constexpr char const* default_name = "safe_edge::common::ServiceHeartbeat"; + static const eprosima::safedds::memory::container::StaticString256 typesupport_name(default_name); + return typesupport_name; + } + + uint32_t max_serialized_size() const noexcept override + { + return ServiceHeartbeatSerialization::max_serialized_size(); + } + + uint32_t serialized_size( + const ServiceHeartbeat& sample, + eprosima::safedds::serialization::cdr::XCDRVersion xcdr_version) const noexcept override + { + uint32_t sample_size = 0; + + if (eprosima::safedds::ReturnCode::OK == sample_serialized_size(sample, xcdr_version, sample_size)) + { + sample_size = eprosima::safedds::memory::align_to( + eprosima::safedds::portable::safe_sizeof() + + sample_size, 4); + } + + return sample_size; + } + + eprosima::safedds::ReturnCode serialize( + const ServiceHeartbeat& sample, + eprosima::safedds::memory::IByteArrayView& buffer, + eprosima::safedds::serialization::cdr::XCDRVersion xcdr_version) const noexcept override + { + eprosima::safedds::ReturnCode ret = + (eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 == xcdr_version) || (eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV2 == xcdr_version) ? + eprosima::safedds::ReturnCode::OK : eprosima::safedds::ReturnCode::ERROR; + + eprosima::safedds::serialization::RepresentationHeader representation_header{}; + + if (eprosima::safedds::ReturnCode::OK == ret) + { + if(eprosima::safedds::portable::MACHINE_ENDIANNESS == eprosima::safedds::platform::Endianness::SAFEDDS_BIG_ENDIAN) + { + representation_header = + eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 == xcdr_version ? + eprosima::safedds::serialization::REPRESENTATION_HEADER_CDR_BE : + eprosima::safedds::serialization::REPRESENTATION_HEADER_DELIMITED_CDR_BE; + } + else + { + representation_header = + eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 == xcdr_version ? + eprosima::safedds::serialization::REPRESENTATION_HEADER_CDR_LE : + eprosima::safedds::serialization::REPRESENTATION_HEADER_DELIMITED_CDR_LE; + } + } + + uint32_t sample_size = 0; + + if (eprosima::safedds::ReturnCode::OK == ret) + { + ret = sample_serialized_size(sample, xcdr_version, sample_size); + } + + uint32_t aligned_size = eprosima::safedds::memory::align_to(sample_size, 4); + uint32_t payload_size = eprosima::safedds::portable::safe_sizeof() + aligned_size; + + if (eprosima::safedds::ReturnCode::OK == ret && buffer.size() >= payload_size) + { + // Indicate the number of padding bytes in the encapsulation options + uint32_t required_padding = aligned_size - sample_size; + representation_header.encapsulation_options[1] = static_cast(required_padding); + + eprosima::safedds::gen::SafeDDSTypeSupportSerializer ser_rh(buffer, eprosima::safedds::portable::MACHINE_ENDIANNESS, xcdr_version); + ret = ser_rh.serialize_array( + representation_header.encapsulation_kind.data(), + eprosima::safedds::serialization::RepresentationHeader::ENCAPSULATION_KIND_SIZE); + + if (eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser_rh.serialize_array( + representation_header.encapsulation_options.data(), eprosima::safedds::serialization::RepresentationHeader::ENCAPSULATION_OPTIONS_SIZE); + } + + if (eprosima::safedds::ReturnCode::OK == ret && sample_size > 0) + { + eprosima::safedds::memory::byte_array::ByteArrayView payload_view = { + &buffer[ser_rh.serializer_used_size()], + ser_rh.serializer_remaining_size() + }; + + eprosima::safedds::gen::SafeDDSTypeSupportSerializer ser(payload_view, eprosima::safedds::portable::MACHINE_ENDIANNESS, xcdr_version); + + ret = ServiceHeartbeatSerialization::serialize(ser, sample); + + // Add padding + for (uint32_t i = 0; (eprosima::safedds::ReturnCode::OK == ret) && (i < required_padding); ++i) + { + ret = ser.serialize('\0'); + } + } + } + + return ret; + } + + eprosima::safedds::ReturnCode deserialize( + const eprosima::safedds::memory::IConstByteArrayView& buffer, + ServiceHeartbeat& sample) const noexcept override + { + eprosima::safedds::serialization::RepresentationHeader representation_header{}; + + eprosima::safedds::serialization::cdr::Deserializer deserializer_rh(buffer, eprosima::safedds::portable::MACHINE_ENDIANNESS, eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1); + eprosima::safedds::ReturnCode ret = eprosima::safedds::protocol::rtps::RTPSTypeSupport::deserialize(deserializer_rh, representation_header); + + // Check expected RepresentationHeader type to be valid and supported + const bool is_cdr_v1 = representation_header.encapsulation_kind[0U] == 0U && (representation_header.encapsulation_kind[1U] <= 0x03U); + const bool is_cdr_v2 = representation_header.encapsulation_kind[0U] == 0U && (representation_header.encapsulation_kind[1U] >= 0x06U && representation_header.encapsulation_kind[1U] <= 0x0BU); + ret = (eprosima::safedds::ReturnCode::OK == ret && (is_cdr_v1 || is_cdr_v2)) ? eprosima::safedds::ReturnCode::OK : eprosima::safedds::ReturnCode::ERROR; + + // Skip payload + eprosima::safedds::memory::byte_array::ByteArrayView payload_view = {nullptr, 0U}; + uint32_t remaining_size = deserializer_rh.deserializer_remaining_size(); + if (eprosima::safedds::ReturnCode::OK == ret && remaining_size > 0) + { + uint32_t padding_size = static_cast(representation_header.encapsulation_options[1] & 0x03); + if (remaining_size >= padding_size) + { + remaining_size -= padding_size; + ret = deserializer_rh.deserializer_skip(remaining_size, payload_view); + } + else + { + ret = eprosima::safedds::ReturnCode::SERIALIZATION_INVALID_REPRESENTATION; + } + } + + if (eprosima::safedds::ReturnCode::OK == ret && remaining_size > 0) + { + // Get received endianness and deserialize payload + eprosima::safedds::gen::SafeDDSTypeSupportDeserializer deserializer(payload_view, + representation_header.get_endianness(), + is_cdr_v1 ? eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 : eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV2); + + ret = ServiceHeartbeatSerialization::deserialize(deserializer, sample); + } + + return ret; + } + + eprosima::safedds::dds::ReturnCode get_key( + const ServiceHeartbeat& data, + eprosima::safedds::dds::KeyHash& key_hash) const noexcept override + { + key_hash = {}; + + static_cast(data); + + return eprosima::safedds::dds::ReturnCode::ILLEGAL_OPERATION; + } + + eprosima::safedds::dds::ReturnCode get_key_from_payload( + const eprosima::safedds::memory::IConstByteArrayView& view, + const eprosima::safedds::protocol::PayloadKind& kind, + eprosima::safedds::dds::KeyHash& key_hash) const noexcept override + { + key_hash = {}; + + static_cast(view); + static_cast(kind); + + return eprosima::safedds::dds::ReturnCode::ILLEGAL_OPERATION; + } + + bool has_keys() const noexcept override + { + return false; + } + + private: + + eprosima::safedds::ReturnCode sample_serialized_size( + const ServiceHeartbeat& sample, + eprosima::safedds::serialization::cdr::XCDRVersion xcdr_version, + uint32_t & serialized_size) const noexcept + { + serialized_size = 0; + + // Create a fake serializer to calculate the serialized size + eprosima::safedds::gen::SafeDDSTypeSupportSerializer ser(eprosima::safedds::portable::MACHINE_ENDIANNESS, xcdr_version); + eprosima::safedds::ReturnCode ret = ServiceHeartbeatSerialization::serialize(ser, sample); + + if(eprosima::safedds::ReturnCode::OK == ret) + { + serialized_size = ser.serializer_used_size(); + } + + return ret; + } + + }; + + + enum class PolicyMode : int32_t + { + POLICY_UNKNOWN , + POLICY_NOMINAL , + POLICY_LOW_SOC , + POLICY_EDGE_AUTONOMOUS , + POLICY_DEGRADED_SERVER_DOWN , + POLICY_DEGRADED_COMPLETE + }; + + } // namespace common +} // namespace safe_edge + +#endif // SAFEDDS_GENERATED__SAFE_EDGE_COMMON_COMMON_HPP \ No newline at end of file diff --git a/safe_dds/idl/edge.hpp b/safe_dds/idl/edge.hpp new file mode 100644 index 0000000..447980f --- /dev/null +++ b/safe_dds/idl/edge.hpp @@ -0,0 +1,1250 @@ +// This file was generated by Safe DDS code generator, which is +// Copyright (C) 2023, Proyectos y Sistemas de Mantenimiento SL (eProsima) +// +// This program is commercial software licensed under the terms of the +// eProsima Software License Agreement Rev 03 (the "License") +// +// You may obtain a copy of the License at +// https://www.eprosima.com/licenses/LICENSE-REV03 + +/*! + * @file edge.hpp + * This header file contains the declaration of the types described in the IDL file. + * + * This file was generated by Safe-DDS-gen. + */ + +#ifndef SAFEDDS_GENERATED__SAFE_EDGE_EDGE_EDGE_HPP +#define SAFEDDS_GENERATED__SAFE_EDGE_EDGE_EDGE_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + + +#include "common.hpp" + +namespace safe_edge { + namespace edge { + + // Forward declaration + struct VehicleEdgeSummarySerialization; + + /*! + * @brief This struct represents the structure VehicleEdgeSummary defined by the user in the IDL file. + * @ingroup edge + */ + struct VehicleEdgeSummary + { + using SerializationStruct = VehicleEdgeSummarySerialization; + + static constexpr eprosima::safedds::gen::IDLExtensibilityKind IDL_EXTENSIBILITY = eprosima::safedds::gen::IDLExtensibilityKind::APPENDABLE; + + /// Member header + safe_edge::common::Header header ; + /// Member soc_pct + float soc_pct = 0.0; + /// Member current_mode + safe_edge::common::PolicyMode current_mode = safe_edge::common::PolicyMode::POLICY_UNKNOWN; + /// Member vehicle_health + safe_edge::common::HealthStatus vehicle_health = safe_edge::common::HealthStatus::HEALTH_UNKNOWN; + /// Member v2g_ready + bool v2g_ready = false; + + // Ensure bounds + }; + + struct VehicleEdgeSummarySerialization + { + static constexpr uint32_t max_serialized_size() + { + // Return the precalculated max_serialized_size plus required: + // - Representation Header size (+4 B) since it is serialized in the typesupport serialization method + // - Alignment to 4 B since the serialization method adds padding + return eprosima::safedds::memory::align_to<553ULL + 4ULL, 4U>(); + } + + static constexpr uint32_t max_key_serialized_size() + { + return 0ULL; + } + + static eprosima::safedds::ReturnCode serialize( + eprosima::safedds::gen::SafeDDSTypeSupportSerializer& ser, + const VehicleEdgeSummary& sample) + { + using namespace safe_edge::edge; + + eprosima::safedds::gen::EncodingAlgorithm prev_encoding = ser.get_encoding_algorithm(); + eprosima::safedds::ReturnCode ret = ser.set_encoding_algorithm( + ser.get_xcdr_version() == eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 ? + eprosima::safedds::gen::EncodingAlgorithm::PLAIN_CDR : + eprosima::safedds::gen::EncodingAlgorithm::DELIMITED_CDR); + + + + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.begin_serialize_type() : ret; + + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type(0, sample.header) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type(1, sample.soc_pct) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type(2, sample.current_mode) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type(3, sample.vehicle_health) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type(4, sample.v2g_ready) : ret; + + if(eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser.end_serialize_type(); + } + + if(eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser.set_encoding_algorithm(prev_encoding); + } + + return ret; + } + + static eprosima::safedds::ReturnCode deserialize( + eprosima::safedds::gen::SafeDDSTypeSupportDeserializer& deser, + VehicleEdgeSummary& sample) + { + using namespace safe_edge::edge; + + // Store the values of the external members in auxiliary variables + + sample = {}; + + // Restore the values of the external members + + const eprosima::safedds::gen::EncodingAlgorithm encoding = + deser.get_xcdr_version() == eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 ? + eprosima::safedds::gen::EncodingAlgorithm::PLAIN_CDR : + eprosima::safedds::gen::EncodingAlgorithm::DELIMITED_CDR; + + return deser.deserialize_type(encoding, + [&sample](eprosima::safedds::gen::SafeDDSTypeSupportDeserializer& inner_deser, const uint32_t id) -> eprosima::safedds::ReturnCode + { + eprosima::safedds::ReturnCode ret_value = eprosima::safedds::ReturnCode::OK; + switch (id) + { + case 0: + ret_value = inner_deser.deserialize_member(sample.header); + break; + + case 1: + ret_value = inner_deser.deserialize_member(sample.soc_pct); + break; + + case 2: + ret_value = inner_deser.deserialize_member(sample.current_mode); + break; + + case 3: + ret_value = inner_deser.deserialize_member(sample.vehicle_health); + break; + + case 4: + ret_value = inner_deser.deserialize_member(sample.v2g_ready); + break; + + default: + ret_value = eprosima::safedds::ReturnCode::UNIMPLEMENTED; + break; + } + return ret_value; + }); + } + + static eprosima::safedds::ReturnCode serialize_key( + eprosima::safedds::gen::SafeDDSTypeSupportSerializer& ser, + const VehicleEdgeSummary& sample) + { + using namespace safe_edge::edge; + + + eprosima::safedds::gen::EncodingAlgorithm prev_encoding = ser.get_encoding_algorithm(); + eprosima::safedds::ReturnCode ret = ser.set_encoding_algorithm(eprosima::safedds::gen::EncodingAlgorithm::PLAIN_CDR2); + + + + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.begin_serialize_type() : ret; + + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type_key(0, sample.header) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type_key(1, sample.soc_pct) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type_key(2, sample.current_mode) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type_key(3, sample.vehicle_health) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type_key(4, sample.v2g_ready) : ret; + + + if(eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser.end_serialize_type(); + } + + if(eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser.set_encoding_algorithm(prev_encoding); + } + + return ret; + + } + + static bool compare( + const VehicleEdgeSummary& first, + const VehicleEdgeSummary& second) + { + using namespace safe_edge::edge; + + bool ret = true; + + ret = ret && eprosima::safedds::gen::SafeDDSTypeSupportComparator::equal(first.header, second.header); + ret = ret && eprosima::safedds::gen::SafeDDSTypeSupportComparator::equal(first.soc_pct, second.soc_pct); + ret = ret && eprosima::safedds::gen::SafeDDSTypeSupportComparator::equal(first.current_mode, second.current_mode); + ret = ret && eprosima::safedds::gen::SafeDDSTypeSupportComparator::equal(first.vehicle_health, second.vehicle_health); + ret = ret && eprosima::safedds::gen::SafeDDSTypeSupportComparator::equal(first.v2g_ready, second.v2g_ready); + + return ret; + } + }; + + + struct VehicleEdgeSummaryTypeSupport : + public eprosima::safedds::dds::TypedTypeSupport + { + using DataType = VehicleEdgeSummary; + + eprosima::safedds::dds::ReturnCode register_type( + eprosima::safedds::dds::DomainParticipant& participant, + const eprosima::safedds::memory::IStringView& type_name) noexcept override + { + return participant.register_type(*this, type_name); + } + + const eprosima::safedds::memory::IStringView& get_type_name() const noexcept override + { + static constexpr char const* default_name = "safe_edge::edge::VehicleEdgeSummary"; + static const eprosima::safedds::memory::container::StaticString256 typesupport_name(default_name); + return typesupport_name; + } + + uint32_t max_serialized_size() const noexcept override + { + return VehicleEdgeSummarySerialization::max_serialized_size(); + } + + uint32_t serialized_size( + const VehicleEdgeSummary& sample, + eprosima::safedds::serialization::cdr::XCDRVersion xcdr_version) const noexcept override + { + uint32_t sample_size = 0; + + if (eprosima::safedds::ReturnCode::OK == sample_serialized_size(sample, xcdr_version, sample_size)) + { + sample_size = eprosima::safedds::memory::align_to( + eprosima::safedds::portable::safe_sizeof() + + sample_size, 4); + } + + return sample_size; + } + + eprosima::safedds::ReturnCode serialize( + const VehicleEdgeSummary& sample, + eprosima::safedds::memory::IByteArrayView& buffer, + eprosima::safedds::serialization::cdr::XCDRVersion xcdr_version) const noexcept override + { + eprosima::safedds::ReturnCode ret = + (eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 == xcdr_version) || (eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV2 == xcdr_version) ? + eprosima::safedds::ReturnCode::OK : eprosima::safedds::ReturnCode::ERROR; + + eprosima::safedds::serialization::RepresentationHeader representation_header{}; + + if (eprosima::safedds::ReturnCode::OK == ret) + { + if(eprosima::safedds::portable::MACHINE_ENDIANNESS == eprosima::safedds::platform::Endianness::SAFEDDS_BIG_ENDIAN) + { + representation_header = + eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 == xcdr_version ? + eprosima::safedds::serialization::REPRESENTATION_HEADER_CDR_BE : + eprosima::safedds::serialization::REPRESENTATION_HEADER_DELIMITED_CDR_BE; + } + else + { + representation_header = + eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 == xcdr_version ? + eprosima::safedds::serialization::REPRESENTATION_HEADER_CDR_LE : + eprosima::safedds::serialization::REPRESENTATION_HEADER_DELIMITED_CDR_LE; + } + } + + uint32_t sample_size = 0; + + if (eprosima::safedds::ReturnCode::OK == ret) + { + ret = sample_serialized_size(sample, xcdr_version, sample_size); + } + + uint32_t aligned_size = eprosima::safedds::memory::align_to(sample_size, 4); + uint32_t payload_size = eprosima::safedds::portable::safe_sizeof() + aligned_size; + + if (eprosima::safedds::ReturnCode::OK == ret && buffer.size() >= payload_size) + { + // Indicate the number of padding bytes in the encapsulation options + uint32_t required_padding = aligned_size - sample_size; + representation_header.encapsulation_options[1] = static_cast(required_padding); + + eprosima::safedds::gen::SafeDDSTypeSupportSerializer ser_rh(buffer, eprosima::safedds::portable::MACHINE_ENDIANNESS, xcdr_version); + ret = ser_rh.serialize_array( + representation_header.encapsulation_kind.data(), + eprosima::safedds::serialization::RepresentationHeader::ENCAPSULATION_KIND_SIZE); + + if (eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser_rh.serialize_array( + representation_header.encapsulation_options.data(), eprosima::safedds::serialization::RepresentationHeader::ENCAPSULATION_OPTIONS_SIZE); + } + + if (eprosima::safedds::ReturnCode::OK == ret && sample_size > 0) + { + eprosima::safedds::memory::byte_array::ByteArrayView payload_view = { + &buffer[ser_rh.serializer_used_size()], + ser_rh.serializer_remaining_size() + }; + + eprosima::safedds::gen::SafeDDSTypeSupportSerializer ser(payload_view, eprosima::safedds::portable::MACHINE_ENDIANNESS, xcdr_version); + + ret = VehicleEdgeSummarySerialization::serialize(ser, sample); + + // Add padding + for (uint32_t i = 0; (eprosima::safedds::ReturnCode::OK == ret) && (i < required_padding); ++i) + { + ret = ser.serialize('\0'); + } + } + } + + return ret; + } + + eprosima::safedds::ReturnCode deserialize( + const eprosima::safedds::memory::IConstByteArrayView& buffer, + VehicleEdgeSummary& sample) const noexcept override + { + eprosima::safedds::serialization::RepresentationHeader representation_header{}; + + eprosima::safedds::serialization::cdr::Deserializer deserializer_rh(buffer, eprosima::safedds::portable::MACHINE_ENDIANNESS, eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1); + eprosima::safedds::ReturnCode ret = eprosima::safedds::protocol::rtps::RTPSTypeSupport::deserialize(deserializer_rh, representation_header); + + // Check expected RepresentationHeader type to be valid and supported + const bool is_cdr_v1 = representation_header.encapsulation_kind[0U] == 0U && (representation_header.encapsulation_kind[1U] <= 0x03U); + const bool is_cdr_v2 = representation_header.encapsulation_kind[0U] == 0U && (representation_header.encapsulation_kind[1U] >= 0x06U && representation_header.encapsulation_kind[1U] <= 0x0BU); + ret = (eprosima::safedds::ReturnCode::OK == ret && (is_cdr_v1 || is_cdr_v2)) ? eprosima::safedds::ReturnCode::OK : eprosima::safedds::ReturnCode::ERROR; + + // Skip payload + eprosima::safedds::memory::byte_array::ByteArrayView payload_view = {nullptr, 0U}; + uint32_t remaining_size = deserializer_rh.deserializer_remaining_size(); + if (eprosima::safedds::ReturnCode::OK == ret && remaining_size > 0) + { + uint32_t padding_size = static_cast(representation_header.encapsulation_options[1] & 0x03); + if (remaining_size >= padding_size) + { + remaining_size -= padding_size; + ret = deserializer_rh.deserializer_skip(remaining_size, payload_view); + } + else + { + ret = eprosima::safedds::ReturnCode::SERIALIZATION_INVALID_REPRESENTATION; + } + } + + if (eprosima::safedds::ReturnCode::OK == ret && remaining_size > 0) + { + // Get received endianness and deserialize payload + eprosima::safedds::gen::SafeDDSTypeSupportDeserializer deserializer(payload_view, + representation_header.get_endianness(), + is_cdr_v1 ? eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 : eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV2); + + ret = VehicleEdgeSummarySerialization::deserialize(deserializer, sample); + } + + return ret; + } + + eprosima::safedds::dds::ReturnCode get_key( + const VehicleEdgeSummary& data, + eprosima::safedds::dds::KeyHash& key_hash) const noexcept override + { + key_hash = {}; + + static_cast(data); + + return eprosima::safedds::dds::ReturnCode::ILLEGAL_OPERATION; + } + + eprosima::safedds::dds::ReturnCode get_key_from_payload( + const eprosima::safedds::memory::IConstByteArrayView& view, + const eprosima::safedds::protocol::PayloadKind& kind, + eprosima::safedds::dds::KeyHash& key_hash) const noexcept override + { + key_hash = {}; + + static_cast(view); + static_cast(kind); + + return eprosima::safedds::dds::ReturnCode::ILLEGAL_OPERATION; + } + + bool has_keys() const noexcept override + { + return false; + } + + private: + + eprosima::safedds::ReturnCode sample_serialized_size( + const VehicleEdgeSummary& sample, + eprosima::safedds::serialization::cdr::XCDRVersion xcdr_version, + uint32_t & serialized_size) const noexcept + { + serialized_size = 0; + + // Create a fake serializer to calculate the serialized size + eprosima::safedds::gen::SafeDDSTypeSupportSerializer ser(eprosima::safedds::portable::MACHINE_ENDIANNESS, xcdr_version); + eprosima::safedds::ReturnCode ret = VehicleEdgeSummarySerialization::serialize(ser, sample); + + if(eprosima::safedds::ReturnCode::OK == ret) + { + serialized_size = ser.serializer_used_size(); + } + + return ret; + } + + }; + + + + // Forward declaration + struct EnergyAdvisorySerialization; + + /*! + * @brief This struct represents the structure EnergyAdvisory defined by the user in the IDL file. + * @ingroup edge + */ + struct EnergyAdvisory + { + using SerializationStruct = EnergyAdvisorySerialization; + + static constexpr eprosima::safedds::gen::IDLExtensibilityKind IDL_EXTENSIBILITY = eprosima::safedds::gen::IDLExtensibilityKind::APPENDABLE; + + /// Member header + safe_edge::common::Header header ; + /// Member suggested_mode + safe_edge::common::PolicyMode suggested_mode = safe_edge::common::PolicyMode::POLICY_UNKNOWN; + /// Member advisory_reason + std::string advisory_reason ; + /// Member recommended_charger_id + int32_t recommended_charger_id = 0; + /// Member target_soc_pct + float target_soc_pct = 0.0; + + // Ensure bounds + static_assert(255 != 0, "advisory_reason shall be bounded or --default_unbounded_max_size shall be used"); + + + }; + + struct EnergyAdvisorySerialization + { + static constexpr uint32_t max_serialized_size() + { + // Return the precalculated max_serialized_size plus required: + // - Representation Header size (+4 B) since it is serialized in the typesupport serialization method + // - Alignment to 4 B since the serialization method adds padding + return eprosima::safedds::memory::align_to<812ULL + 4ULL, 4U>(); + } + + static constexpr uint32_t max_key_serialized_size() + { + return 0ULL; + } + + static eprosima::safedds::ReturnCode serialize( + eprosima::safedds::gen::SafeDDSTypeSupportSerializer& ser, + const EnergyAdvisory& sample) + { + using namespace safe_edge::edge; + + eprosima::safedds::gen::EncodingAlgorithm prev_encoding = ser.get_encoding_algorithm(); + eprosima::safedds::ReturnCode ret = ser.set_encoding_algorithm( + ser.get_xcdr_version() == eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 ? + eprosima::safedds::gen::EncodingAlgorithm::PLAIN_CDR : + eprosima::safedds::gen::EncodingAlgorithm::DELIMITED_CDR); + + ret = ((eprosima::safedds::ReturnCode::OK == ret) && (sample.advisory_reason.size() <= 255)) ? ret : eprosima::safedds::ReturnCode::ERROR; + + + + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.begin_serialize_type() : ret; + + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type(0, sample.header) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type(1, sample.suggested_mode) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type(2, sample.advisory_reason) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type(3, sample.recommended_charger_id) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type(4, sample.target_soc_pct) : ret; + + if(eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser.end_serialize_type(); + } + + if(eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser.set_encoding_algorithm(prev_encoding); + } + + return ret; + } + + static eprosima::safedds::ReturnCode deserialize( + eprosima::safedds::gen::SafeDDSTypeSupportDeserializer& deser, + EnergyAdvisory& sample) + { + using namespace safe_edge::edge; + + // Store the values of the external members in auxiliary variables + + sample = {}; + + // Restore the values of the external members + + const eprosima::safedds::gen::EncodingAlgorithm encoding = + deser.get_xcdr_version() == eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 ? + eprosima::safedds::gen::EncodingAlgorithm::PLAIN_CDR : + eprosima::safedds::gen::EncodingAlgorithm::DELIMITED_CDR; + + return deser.deserialize_type(encoding, + [&sample](eprosima::safedds::gen::SafeDDSTypeSupportDeserializer& inner_deser, const uint32_t id) -> eprosima::safedds::ReturnCode + { + eprosima::safedds::ReturnCode ret_value = eprosima::safedds::ReturnCode::OK; + switch (id) + { + case 0: + ret_value = inner_deser.deserialize_member(sample.header); + break; + + case 1: + ret_value = inner_deser.deserialize_member(sample.suggested_mode); + break; + + case 2: + ret_value = inner_deser.deserialize_member(sample.advisory_reason); + break; + + case 3: + ret_value = inner_deser.deserialize_member(sample.recommended_charger_id); + break; + + case 4: + ret_value = inner_deser.deserialize_member(sample.target_soc_pct); + break; + + default: + ret_value = eprosima::safedds::ReturnCode::UNIMPLEMENTED; + break; + } + return ret_value; + }); + } + + static eprosima::safedds::ReturnCode serialize_key( + eprosima::safedds::gen::SafeDDSTypeSupportSerializer& ser, + const EnergyAdvisory& sample) + { + using namespace safe_edge::edge; + + + eprosima::safedds::gen::EncodingAlgorithm prev_encoding = ser.get_encoding_algorithm(); + eprosima::safedds::ReturnCode ret = ser.set_encoding_algorithm(eprosima::safedds::gen::EncodingAlgorithm::PLAIN_CDR2); + + ret = ((eprosima::safedds::ReturnCode::OK == ret) && (sample.advisory_reason.size() <= 255)) ? ret : eprosima::safedds::ReturnCode::ERROR; + + + + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.begin_serialize_type() : ret; + + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type_key(0, sample.header) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type_key(1, sample.suggested_mode) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type_key(2, sample.advisory_reason) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type_key(3, sample.recommended_charger_id) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type_key(4, sample.target_soc_pct) : ret; + + + if(eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser.end_serialize_type(); + } + + if(eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser.set_encoding_algorithm(prev_encoding); + } + + return ret; + + } + + static bool compare( + const EnergyAdvisory& first, + const EnergyAdvisory& second) + { + using namespace safe_edge::edge; + + bool ret = true; + + ret = ret && eprosima::safedds::gen::SafeDDSTypeSupportComparator::equal(first.header, second.header); + ret = ret && eprosima::safedds::gen::SafeDDSTypeSupportComparator::equal(first.suggested_mode, second.suggested_mode); + ret = ret && eprosima::safedds::gen::SafeDDSTypeSupportComparator::equal(first.advisory_reason, second.advisory_reason); + ret = ret && eprosima::safedds::gen::SafeDDSTypeSupportComparator::equal(first.recommended_charger_id, second.recommended_charger_id); + ret = ret && eprosima::safedds::gen::SafeDDSTypeSupportComparator::equal(first.target_soc_pct, second.target_soc_pct); + + return ret; + } + }; + + + struct EnergyAdvisoryTypeSupport : + public eprosima::safedds::dds::TypedTypeSupport + { + using DataType = EnergyAdvisory; + + eprosima::safedds::dds::ReturnCode register_type( + eprosima::safedds::dds::DomainParticipant& participant, + const eprosima::safedds::memory::IStringView& type_name) noexcept override + { + return participant.register_type(*this, type_name); + } + + const eprosima::safedds::memory::IStringView& get_type_name() const noexcept override + { + static constexpr char const* default_name = "safe_edge::edge::EnergyAdvisory"; + static const eprosima::safedds::memory::container::StaticString256 typesupport_name(default_name); + return typesupport_name; + } + + uint32_t max_serialized_size() const noexcept override + { + return EnergyAdvisorySerialization::max_serialized_size(); + } + + uint32_t serialized_size( + const EnergyAdvisory& sample, + eprosima::safedds::serialization::cdr::XCDRVersion xcdr_version) const noexcept override + { + uint32_t sample_size = 0; + + if (eprosima::safedds::ReturnCode::OK == sample_serialized_size(sample, xcdr_version, sample_size)) + { + sample_size = eprosima::safedds::memory::align_to( + eprosima::safedds::portable::safe_sizeof() + + sample_size, 4); + } + + return sample_size; + } + + eprosima::safedds::ReturnCode serialize( + const EnergyAdvisory& sample, + eprosima::safedds::memory::IByteArrayView& buffer, + eprosima::safedds::serialization::cdr::XCDRVersion xcdr_version) const noexcept override + { + eprosima::safedds::ReturnCode ret = + (eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 == xcdr_version) || (eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV2 == xcdr_version) ? + eprosima::safedds::ReturnCode::OK : eprosima::safedds::ReturnCode::ERROR; + + eprosima::safedds::serialization::RepresentationHeader representation_header{}; + + if (eprosima::safedds::ReturnCode::OK == ret) + { + if(eprosima::safedds::portable::MACHINE_ENDIANNESS == eprosima::safedds::platform::Endianness::SAFEDDS_BIG_ENDIAN) + { + representation_header = + eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 == xcdr_version ? + eprosima::safedds::serialization::REPRESENTATION_HEADER_CDR_BE : + eprosima::safedds::serialization::REPRESENTATION_HEADER_DELIMITED_CDR_BE; + } + else + { + representation_header = + eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 == xcdr_version ? + eprosima::safedds::serialization::REPRESENTATION_HEADER_CDR_LE : + eprosima::safedds::serialization::REPRESENTATION_HEADER_DELIMITED_CDR_LE; + } + } + + uint32_t sample_size = 0; + + if (eprosima::safedds::ReturnCode::OK == ret) + { + ret = sample_serialized_size(sample, xcdr_version, sample_size); + } + + uint32_t aligned_size = eprosima::safedds::memory::align_to(sample_size, 4); + uint32_t payload_size = eprosima::safedds::portable::safe_sizeof() + aligned_size; + + if (eprosima::safedds::ReturnCode::OK == ret && buffer.size() >= payload_size) + { + // Indicate the number of padding bytes in the encapsulation options + uint32_t required_padding = aligned_size - sample_size; + representation_header.encapsulation_options[1] = static_cast(required_padding); + + eprosima::safedds::gen::SafeDDSTypeSupportSerializer ser_rh(buffer, eprosima::safedds::portable::MACHINE_ENDIANNESS, xcdr_version); + ret = ser_rh.serialize_array( + representation_header.encapsulation_kind.data(), + eprosima::safedds::serialization::RepresentationHeader::ENCAPSULATION_KIND_SIZE); + + if (eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser_rh.serialize_array( + representation_header.encapsulation_options.data(), eprosima::safedds::serialization::RepresentationHeader::ENCAPSULATION_OPTIONS_SIZE); + } + + if (eprosima::safedds::ReturnCode::OK == ret && sample_size > 0) + { + eprosima::safedds::memory::byte_array::ByteArrayView payload_view = { + &buffer[ser_rh.serializer_used_size()], + ser_rh.serializer_remaining_size() + }; + + eprosima::safedds::gen::SafeDDSTypeSupportSerializer ser(payload_view, eprosima::safedds::portable::MACHINE_ENDIANNESS, xcdr_version); + + ret = EnergyAdvisorySerialization::serialize(ser, sample); + + // Add padding + for (uint32_t i = 0; (eprosima::safedds::ReturnCode::OK == ret) && (i < required_padding); ++i) + { + ret = ser.serialize('\0'); + } + } + } + + return ret; + } + + eprosima::safedds::ReturnCode deserialize( + const eprosima::safedds::memory::IConstByteArrayView& buffer, + EnergyAdvisory& sample) const noexcept override + { + eprosima::safedds::serialization::RepresentationHeader representation_header{}; + + eprosima::safedds::serialization::cdr::Deserializer deserializer_rh(buffer, eprosima::safedds::portable::MACHINE_ENDIANNESS, eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1); + eprosima::safedds::ReturnCode ret = eprosima::safedds::protocol::rtps::RTPSTypeSupport::deserialize(deserializer_rh, representation_header); + + // Check expected RepresentationHeader type to be valid and supported + const bool is_cdr_v1 = representation_header.encapsulation_kind[0U] == 0U && (representation_header.encapsulation_kind[1U] <= 0x03U); + const bool is_cdr_v2 = representation_header.encapsulation_kind[0U] == 0U && (representation_header.encapsulation_kind[1U] >= 0x06U && representation_header.encapsulation_kind[1U] <= 0x0BU); + ret = (eprosima::safedds::ReturnCode::OK == ret && (is_cdr_v1 || is_cdr_v2)) ? eprosima::safedds::ReturnCode::OK : eprosima::safedds::ReturnCode::ERROR; + + // Skip payload + eprosima::safedds::memory::byte_array::ByteArrayView payload_view = {nullptr, 0U}; + uint32_t remaining_size = deserializer_rh.deserializer_remaining_size(); + if (eprosima::safedds::ReturnCode::OK == ret && remaining_size > 0) + { + uint32_t padding_size = static_cast(representation_header.encapsulation_options[1] & 0x03); + if (remaining_size >= padding_size) + { + remaining_size -= padding_size; + ret = deserializer_rh.deserializer_skip(remaining_size, payload_view); + } + else + { + ret = eprosima::safedds::ReturnCode::SERIALIZATION_INVALID_REPRESENTATION; + } + } + + if (eprosima::safedds::ReturnCode::OK == ret && remaining_size > 0) + { + // Get received endianness and deserialize payload + eprosima::safedds::gen::SafeDDSTypeSupportDeserializer deserializer(payload_view, + representation_header.get_endianness(), + is_cdr_v1 ? eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 : eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV2); + + ret = EnergyAdvisorySerialization::deserialize(deserializer, sample); + } + + return ret; + } + + eprosima::safedds::dds::ReturnCode get_key( + const EnergyAdvisory& data, + eprosima::safedds::dds::KeyHash& key_hash) const noexcept override + { + key_hash = {}; + + static_cast(data); + + return eprosima::safedds::dds::ReturnCode::ILLEGAL_OPERATION; + } + + eprosima::safedds::dds::ReturnCode get_key_from_payload( + const eprosima::safedds::memory::IConstByteArrayView& view, + const eprosima::safedds::protocol::PayloadKind& kind, + eprosima::safedds::dds::KeyHash& key_hash) const noexcept override + { + key_hash = {}; + + static_cast(view); + static_cast(kind); + + return eprosima::safedds::dds::ReturnCode::ILLEGAL_OPERATION; + } + + bool has_keys() const noexcept override + { + return false; + } + + private: + + eprosima::safedds::ReturnCode sample_serialized_size( + const EnergyAdvisory& sample, + eprosima::safedds::serialization::cdr::XCDRVersion xcdr_version, + uint32_t & serialized_size) const noexcept + { + serialized_size = 0; + + // Create a fake serializer to calculate the serialized size + eprosima::safedds::gen::SafeDDSTypeSupportSerializer ser(eprosima::safedds::portable::MACHINE_ENDIANNESS, xcdr_version); + eprosima::safedds::ReturnCode ret = EnergyAdvisorySerialization::serialize(ser, sample); + + if(eprosima::safedds::ReturnCode::OK == ret) + { + serialized_size = ser.serializer_used_size(); + } + + return ret; + } + + }; + + + + // Forward declaration + struct EdgeGatewayStatusSerialization; + + /*! + * @brief This struct represents the structure EdgeGatewayStatus defined by the user in the IDL file. + * @ingroup edge + */ + struct EdgeGatewayStatus + { + using SerializationStruct = EdgeGatewayStatusSerialization; + + static constexpr eprosima::safedds::gen::IDLExtensibilityKind IDL_EXTENSIBILITY = eprosima::safedds::gen::IDLExtensibilityKind::APPENDABLE; + + /// Member header + safe_edge::common::Header header ; + /// Member status + safe_edge::common::HealthStatus status = safe_edge::common::HealthStatus::HEALTH_UNKNOWN; + /// Member last_server_sync_ms + uint64_t last_server_sync_ms = 0; + /// Member detail + std::string detail ; + + // Ensure bounds + static_assert(255 != 0, "detail shall be bounded or --default_unbounded_max_size shall be used"); + }; + + struct EdgeGatewayStatusSerialization + { + static constexpr uint32_t max_serialized_size() + { + // Return the precalculated max_serialized_size plus required: + // - Representation Header size (+4 B) since it is serialized in the typesupport serialization method + // - Alignment to 4 B since the serialization method adds padding + return eprosima::safedds::memory::align_to<812ULL + 4ULL, 4U>(); + } + + static constexpr uint32_t max_key_serialized_size() + { + return 0ULL; + } + + static eprosima::safedds::ReturnCode serialize( + eprosima::safedds::gen::SafeDDSTypeSupportSerializer& ser, + const EdgeGatewayStatus& sample) + { + using namespace safe_edge::edge; + + eprosima::safedds::gen::EncodingAlgorithm prev_encoding = ser.get_encoding_algorithm(); + eprosima::safedds::ReturnCode ret = ser.set_encoding_algorithm( + ser.get_xcdr_version() == eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 ? + eprosima::safedds::gen::EncodingAlgorithm::PLAIN_CDR : + eprosima::safedds::gen::EncodingAlgorithm::DELIMITED_CDR); + + ret = ((eprosima::safedds::ReturnCode::OK == ret) && (sample.detail.size() <= 255)) ? ret : eprosima::safedds::ReturnCode::ERROR; + + + + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.begin_serialize_type() : ret; + + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type(0, sample.header) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type(1, sample.status) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type(2, sample.last_server_sync_ms) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type(3, sample.detail) : ret; + + if(eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser.end_serialize_type(); + } + + if(eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser.set_encoding_algorithm(prev_encoding); + } + + return ret; + } + + static eprosima::safedds::ReturnCode deserialize( + eprosima::safedds::gen::SafeDDSTypeSupportDeserializer& deser, + EdgeGatewayStatus& sample) + { + using namespace safe_edge::edge; + + // Store the values of the external members in auxiliary variables + + sample = {}; + + // Restore the values of the external members + + const eprosima::safedds::gen::EncodingAlgorithm encoding = + deser.get_xcdr_version() == eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 ? + eprosima::safedds::gen::EncodingAlgorithm::PLAIN_CDR : + eprosima::safedds::gen::EncodingAlgorithm::DELIMITED_CDR; + + return deser.deserialize_type(encoding, + [&sample](eprosima::safedds::gen::SafeDDSTypeSupportDeserializer& inner_deser, const uint32_t id) -> eprosima::safedds::ReturnCode + { + eprosima::safedds::ReturnCode ret_value = eprosima::safedds::ReturnCode::OK; + switch (id) + { + case 0: + ret_value = inner_deser.deserialize_member(sample.header); + break; + + case 1: + ret_value = inner_deser.deserialize_member(sample.status); + break; + + case 2: + ret_value = inner_deser.deserialize_member(sample.last_server_sync_ms); + break; + + case 3: + ret_value = inner_deser.deserialize_member(sample.detail); + break; + + default: + ret_value = eprosima::safedds::ReturnCode::UNIMPLEMENTED; + break; + } + return ret_value; + }); + } + + static eprosima::safedds::ReturnCode serialize_key( + eprosima::safedds::gen::SafeDDSTypeSupportSerializer& ser, + const EdgeGatewayStatus& sample) + { + using namespace safe_edge::edge; + + + eprosima::safedds::gen::EncodingAlgorithm prev_encoding = ser.get_encoding_algorithm(); + eprosima::safedds::ReturnCode ret = ser.set_encoding_algorithm(eprosima::safedds::gen::EncodingAlgorithm::PLAIN_CDR2); + + ret = ((eprosima::safedds::ReturnCode::OK == ret) && (sample.detail.size() <= 255)) ? ret : eprosima::safedds::ReturnCode::ERROR; + + + + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.begin_serialize_type() : ret; + + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type_key(0, sample.header) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type_key(1, sample.status) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type_key(2, sample.last_server_sync_ms) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type_key(3, sample.detail) : ret; + + + if(eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser.end_serialize_type(); + } + + if(eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser.set_encoding_algorithm(prev_encoding); + } + + return ret; + + } + + static bool compare( + const EdgeGatewayStatus& first, + const EdgeGatewayStatus& second) + { + using namespace safe_edge::edge; + + bool ret = true; + + ret = ret && eprosima::safedds::gen::SafeDDSTypeSupportComparator::equal(first.header, second.header); + ret = ret && eprosima::safedds::gen::SafeDDSTypeSupportComparator::equal(first.status, second.status); + ret = ret && eprosima::safedds::gen::SafeDDSTypeSupportComparator::equal(first.last_server_sync_ms, second.last_server_sync_ms); + ret = ret && eprosima::safedds::gen::SafeDDSTypeSupportComparator::equal(first.detail, second.detail); + + return ret; + } + }; + + + struct EdgeGatewayStatusTypeSupport : + public eprosima::safedds::dds::TypedTypeSupport + { + using DataType = EdgeGatewayStatus; + + eprosima::safedds::dds::ReturnCode register_type( + eprosima::safedds::dds::DomainParticipant& participant, + const eprosima::safedds::memory::IStringView& type_name) noexcept override + { + return participant.register_type(*this, type_name); + } + + const eprosima::safedds::memory::IStringView& get_type_name() const noexcept override + { + static constexpr char const* default_name = "safe_edge::edge::EdgeGatewayStatus"; + static const eprosima::safedds::memory::container::StaticString256 typesupport_name(default_name); + return typesupport_name; + } + + uint32_t max_serialized_size() const noexcept override + { + return EdgeGatewayStatusSerialization::max_serialized_size(); + } + + uint32_t serialized_size( + const EdgeGatewayStatus& sample, + eprosima::safedds::serialization::cdr::XCDRVersion xcdr_version) const noexcept override + { + uint32_t sample_size = 0; + + if (eprosima::safedds::ReturnCode::OK == sample_serialized_size(sample, xcdr_version, sample_size)) + { + sample_size = eprosima::safedds::memory::align_to( + eprosima::safedds::portable::safe_sizeof() + + sample_size, 4); + } + + return sample_size; + } + + eprosima::safedds::ReturnCode serialize( + const EdgeGatewayStatus& sample, + eprosima::safedds::memory::IByteArrayView& buffer, + eprosima::safedds::serialization::cdr::XCDRVersion xcdr_version) const noexcept override + { + eprosima::safedds::ReturnCode ret = + (eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 == xcdr_version) || (eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV2 == xcdr_version) ? + eprosima::safedds::ReturnCode::OK : eprosima::safedds::ReturnCode::ERROR; + + eprosima::safedds::serialization::RepresentationHeader representation_header{}; + + if (eprosima::safedds::ReturnCode::OK == ret) + { + if(eprosima::safedds::portable::MACHINE_ENDIANNESS == eprosima::safedds::platform::Endianness::SAFEDDS_BIG_ENDIAN) + { + representation_header = + eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 == xcdr_version ? + eprosima::safedds::serialization::REPRESENTATION_HEADER_CDR_BE : + eprosima::safedds::serialization::REPRESENTATION_HEADER_DELIMITED_CDR_BE; + } + else + { + representation_header = + eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 == xcdr_version ? + eprosima::safedds::serialization::REPRESENTATION_HEADER_CDR_LE : + eprosima::safedds::serialization::REPRESENTATION_HEADER_DELIMITED_CDR_LE; + } + } + + uint32_t sample_size = 0; + + if (eprosima::safedds::ReturnCode::OK == ret) + { + ret = sample_serialized_size(sample, xcdr_version, sample_size); + } + + uint32_t aligned_size = eprosima::safedds::memory::align_to(sample_size, 4); + uint32_t payload_size = eprosima::safedds::portable::safe_sizeof() + aligned_size; + + if (eprosima::safedds::ReturnCode::OK == ret && buffer.size() >= payload_size) + { + // Indicate the number of padding bytes in the encapsulation options + uint32_t required_padding = aligned_size - sample_size; + representation_header.encapsulation_options[1] = static_cast(required_padding); + + eprosima::safedds::gen::SafeDDSTypeSupportSerializer ser_rh(buffer, eprosima::safedds::portable::MACHINE_ENDIANNESS, xcdr_version); + ret = ser_rh.serialize_array( + representation_header.encapsulation_kind.data(), + eprosima::safedds::serialization::RepresentationHeader::ENCAPSULATION_KIND_SIZE); + + if (eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser_rh.serialize_array( + representation_header.encapsulation_options.data(), eprosima::safedds::serialization::RepresentationHeader::ENCAPSULATION_OPTIONS_SIZE); + } + + if (eprosima::safedds::ReturnCode::OK == ret && sample_size > 0) + { + eprosima::safedds::memory::byte_array::ByteArrayView payload_view = { + &buffer[ser_rh.serializer_used_size()], + ser_rh.serializer_remaining_size() + }; + + eprosima::safedds::gen::SafeDDSTypeSupportSerializer ser(payload_view, eprosima::safedds::portable::MACHINE_ENDIANNESS, xcdr_version); + + ret = EdgeGatewayStatusSerialization::serialize(ser, sample); + + // Add padding + for (uint32_t i = 0; (eprosima::safedds::ReturnCode::OK == ret) && (i < required_padding); ++i) + { + ret = ser.serialize('\0'); + } + } + } + + return ret; + } + + eprosima::safedds::ReturnCode deserialize( + const eprosima::safedds::memory::IConstByteArrayView& buffer, + EdgeGatewayStatus& sample) const noexcept override + { + eprosima::safedds::serialization::RepresentationHeader representation_header{}; + + eprosima::safedds::serialization::cdr::Deserializer deserializer_rh(buffer, eprosima::safedds::portable::MACHINE_ENDIANNESS, eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1); + eprosima::safedds::ReturnCode ret = eprosima::safedds::protocol::rtps::RTPSTypeSupport::deserialize(deserializer_rh, representation_header); + + // Check expected RepresentationHeader type to be valid and supported + const bool is_cdr_v1 = representation_header.encapsulation_kind[0U] == 0U && (representation_header.encapsulation_kind[1U] <= 0x03U); + const bool is_cdr_v2 = representation_header.encapsulation_kind[0U] == 0U && (representation_header.encapsulation_kind[1U] >= 0x06U && representation_header.encapsulation_kind[1U] <= 0x0BU); + ret = (eprosima::safedds::ReturnCode::OK == ret && (is_cdr_v1 || is_cdr_v2)) ? eprosima::safedds::ReturnCode::OK : eprosima::safedds::ReturnCode::ERROR; + + // Skip payload + eprosima::safedds::memory::byte_array::ByteArrayView payload_view = {nullptr, 0U}; + uint32_t remaining_size = deserializer_rh.deserializer_remaining_size(); + if (eprosima::safedds::ReturnCode::OK == ret && remaining_size > 0) + { + uint32_t padding_size = static_cast(representation_header.encapsulation_options[1] & 0x03); + if (remaining_size >= padding_size) + { + remaining_size -= padding_size; + ret = deserializer_rh.deserializer_skip(remaining_size, payload_view); + } + else + { + ret = eprosima::safedds::ReturnCode::SERIALIZATION_INVALID_REPRESENTATION; + } + } + + if (eprosima::safedds::ReturnCode::OK == ret && remaining_size > 0) + { + // Get received endianness and deserialize payload + eprosima::safedds::gen::SafeDDSTypeSupportDeserializer deserializer(payload_view, + representation_header.get_endianness(), + is_cdr_v1 ? eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 : eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV2); + + ret = EdgeGatewayStatusSerialization::deserialize(deserializer, sample); + } + + return ret; + } + + eprosima::safedds::dds::ReturnCode get_key( + const EdgeGatewayStatus& data, + eprosima::safedds::dds::KeyHash& key_hash) const noexcept override + { + key_hash = {}; + + static_cast(data); + + return eprosima::safedds::dds::ReturnCode::ILLEGAL_OPERATION; + } + + eprosima::safedds::dds::ReturnCode get_key_from_payload( + const eprosima::safedds::memory::IConstByteArrayView& view, + const eprosima::safedds::protocol::PayloadKind& kind, + eprosima::safedds::dds::KeyHash& key_hash) const noexcept override + { + key_hash = {}; + + static_cast(view); + static_cast(kind); + + return eprosima::safedds::dds::ReturnCode::ILLEGAL_OPERATION; + } + + bool has_keys() const noexcept override + { + return false; + } + + private: + + eprosima::safedds::ReturnCode sample_serialized_size( + const EdgeGatewayStatus& sample, + eprosima::safedds::serialization::cdr::XCDRVersion xcdr_version, + uint32_t & serialized_size) const noexcept + { + serialized_size = 0; + + // Create a fake serializer to calculate the serialized size + eprosima::safedds::gen::SafeDDSTypeSupportSerializer ser(eprosima::safedds::portable::MACHINE_ENDIANNESS, xcdr_version); + eprosima::safedds::ReturnCode ret = EdgeGatewayStatusSerialization::serialize(ser, sample); + + if(eprosima::safedds::ReturnCode::OK == ret) + { + serialized_size = ser.serializer_used_size(); + } + + return ret; + } + + }; + + + } // namespace edge +} // namespace safe_edge + +#endif // SAFEDDS_GENERATED__SAFE_EDGE_EDGE_EDGE_HPP \ No newline at end of file diff --git a/safe_dds/idl/pilot_server.hpp b/safe_dds/idl/pilot_server.hpp new file mode 100644 index 0000000..a29173c --- /dev/null +++ b/safe_dds/idl/pilot_server.hpp @@ -0,0 +1,2781 @@ +// This file was generated by Safe DDS code generator, which is +// Copyright (C) 2023, Proyectos y Sistemas de Mantenimiento SL (eProsima) +// +// This program is commercial software licensed under the terms of the +// eProsima Software License Agreement Rev 03 (the "License") +// +// You may obtain a copy of the License at +// https://www.eprosima.com/licenses/LICENSE-REV03 + +/*! + * @file pilot_server.hpp + * This header file contains the declaration of the types described in the IDL file. + * + * This file was generated by Safe-DDS-gen. + */ + +#ifndef SAFEDDS_GENERATED__SAFE_EDGE_PILOT_SERVER_PILOT_SERVER_HPP +#define SAFEDDS_GENERATED__SAFE_EDGE_PILOT_SERVER_PILOT_SERVER_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + + +#include "common.hpp" + +namespace safe_edge { + namespace pilot_server { + const uint32_t MAX_CHARGER_LOCATIONS = 200; + + const uint32_t MAX_CHARGER_TYPES = 64; + + const uint32_t MAX_CHARGING_SESSIONS = 1000; + + const uint32_t MAX_ROUTE_METRICS = 512; + + + // Forward declaration + struct ChargerLocationSerialization; + + /*! + * @brief This struct represents the structure ChargerLocation defined by the user in the IDL file. + * @ingroup pilot_server + */ + struct ChargerLocation + { + using SerializationStruct = ChargerLocationSerialization; + + static constexpr eprosima::safedds::gen::IDLExtensibilityKind IDL_EXTENSIBILITY = eprosima::safedds::gen::IDLExtensibilityKind::APPENDABLE; + + /// Member id + int32_t id = 0; + /// Member name + std::string name ; + /// Member position + safe_edge::common::GeoPoint position ; + + // Ensure bounds + static_assert(255 != 0, "name shall be bounded or --default_unbounded_max_size shall be used"); + + }; + + struct ChargerLocationSerialization + { + static constexpr uint32_t max_serialized_size() + { + // Return the precalculated max_serialized_size plus required: + // - Representation Header size (+4 B) since it is serialized in the typesupport serialization method + // - Alignment to 4 B since the serialization method adds padding + return eprosima::safedds::memory::align_to<288ULL + 4ULL, 4U>(); + } + + static constexpr uint32_t max_key_serialized_size() + { + return 0ULL; + } + + static eprosima::safedds::ReturnCode serialize( + eprosima::safedds::gen::SafeDDSTypeSupportSerializer& ser, + const ChargerLocation& sample) + { + using namespace safe_edge::pilot_server; + + eprosima::safedds::gen::EncodingAlgorithm prev_encoding = ser.get_encoding_algorithm(); + eprosima::safedds::ReturnCode ret = ser.set_encoding_algorithm( + ser.get_xcdr_version() == eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 ? + eprosima::safedds::gen::EncodingAlgorithm::PLAIN_CDR : + eprosima::safedds::gen::EncodingAlgorithm::DELIMITED_CDR); + + ret = ((eprosima::safedds::ReturnCode::OK == ret) && (sample.name.size() <= 255)) ? ret : eprosima::safedds::ReturnCode::ERROR; + + + + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.begin_serialize_type() : ret; + + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type(0, sample.id) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type(1, sample.name) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type(2, sample.position) : ret; + + if(eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser.end_serialize_type(); + } + + if(eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser.set_encoding_algorithm(prev_encoding); + } + + return ret; + } + + static eprosima::safedds::ReturnCode deserialize( + eprosima::safedds::gen::SafeDDSTypeSupportDeserializer& deser, + ChargerLocation& sample) + { + using namespace safe_edge::pilot_server; + + // Store the values of the external members in auxiliary variables + + sample = {}; + + // Restore the values of the external members + + const eprosima::safedds::gen::EncodingAlgorithm encoding = + deser.get_xcdr_version() == eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 ? + eprosima::safedds::gen::EncodingAlgorithm::PLAIN_CDR : + eprosima::safedds::gen::EncodingAlgorithm::DELIMITED_CDR; + + return deser.deserialize_type(encoding, + [&sample](eprosima::safedds::gen::SafeDDSTypeSupportDeserializer& inner_deser, const uint32_t id) -> eprosima::safedds::ReturnCode + { + eprosima::safedds::ReturnCode ret_value = eprosima::safedds::ReturnCode::OK; + switch (id) + { + case 0: + ret_value = inner_deser.deserialize_member(sample.id); + break; + + case 1: + ret_value = inner_deser.deserialize_member(sample.name); + break; + + case 2: + ret_value = inner_deser.deserialize_member(sample.position); + break; + + default: + ret_value = eprosima::safedds::ReturnCode::UNIMPLEMENTED; + break; + } + return ret_value; + }); + } + + static eprosima::safedds::ReturnCode serialize_key( + eprosima::safedds::gen::SafeDDSTypeSupportSerializer& ser, + const ChargerLocation& sample) + { + using namespace safe_edge::pilot_server; + + + eprosima::safedds::gen::EncodingAlgorithm prev_encoding = ser.get_encoding_algorithm(); + eprosima::safedds::ReturnCode ret = ser.set_encoding_algorithm(eprosima::safedds::gen::EncodingAlgorithm::PLAIN_CDR2); + + ret = ((eprosima::safedds::ReturnCode::OK == ret) && (sample.name.size() <= 255)) ? ret : eprosima::safedds::ReturnCode::ERROR; + + + + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.begin_serialize_type() : ret; + + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type_key(0, sample.id) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type_key(1, sample.name) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type_key(2, sample.position) : ret; + + + if(eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser.end_serialize_type(); + } + + if(eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser.set_encoding_algorithm(prev_encoding); + } + + return ret; + + } + + static bool compare( + const ChargerLocation& first, + const ChargerLocation& second) + { + using namespace safe_edge::pilot_server; + + bool ret = true; + + ret = ret && eprosima::safedds::gen::SafeDDSTypeSupportComparator::equal(first.id, second.id); + ret = ret && eprosima::safedds::gen::SafeDDSTypeSupportComparator::equal(first.name, second.name); + ret = ret && eprosima::safedds::gen::SafeDDSTypeSupportComparator::equal(first.position, second.position); + + return ret; + } + }; + + + struct ChargerLocationTypeSupport : + public eprosima::safedds::dds::TypedTypeSupport + { + using DataType = ChargerLocation; + + eprosima::safedds::dds::ReturnCode register_type( + eprosima::safedds::dds::DomainParticipant& participant, + const eprosima::safedds::memory::IStringView& type_name) noexcept override + { + return participant.register_type(*this, type_name); + } + + const eprosima::safedds::memory::IStringView& get_type_name() const noexcept override + { + static constexpr char const* default_name = "safe_edge::pilot_server::ChargerLocation"; + static const eprosima::safedds::memory::container::StaticString256 typesupport_name(default_name); + return typesupport_name; + } + + uint32_t max_serialized_size() const noexcept override + { + return ChargerLocationSerialization::max_serialized_size(); + } + + uint32_t serialized_size( + const ChargerLocation& sample, + eprosima::safedds::serialization::cdr::XCDRVersion xcdr_version) const noexcept override + { + uint32_t sample_size = 0; + + if (eprosima::safedds::ReturnCode::OK == sample_serialized_size(sample, xcdr_version, sample_size)) + { + sample_size = eprosima::safedds::memory::align_to( + eprosima::safedds::portable::safe_sizeof() + + sample_size, 4); + } + + return sample_size; + } + + eprosima::safedds::ReturnCode serialize( + const ChargerLocation& sample, + eprosima::safedds::memory::IByteArrayView& buffer, + eprosima::safedds::serialization::cdr::XCDRVersion xcdr_version) const noexcept override + { + eprosima::safedds::ReturnCode ret = + (eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 == xcdr_version) || (eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV2 == xcdr_version) ? + eprosima::safedds::ReturnCode::OK : eprosima::safedds::ReturnCode::ERROR; + + eprosima::safedds::serialization::RepresentationHeader representation_header{}; + + if (eprosima::safedds::ReturnCode::OK == ret) + { + if(eprosima::safedds::portable::MACHINE_ENDIANNESS == eprosima::safedds::platform::Endianness::SAFEDDS_BIG_ENDIAN) + { + representation_header = + eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 == xcdr_version ? + eprosima::safedds::serialization::REPRESENTATION_HEADER_CDR_BE : + eprosima::safedds::serialization::REPRESENTATION_HEADER_DELIMITED_CDR_BE; + } + else + { + representation_header = + eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 == xcdr_version ? + eprosima::safedds::serialization::REPRESENTATION_HEADER_CDR_LE : + eprosima::safedds::serialization::REPRESENTATION_HEADER_DELIMITED_CDR_LE; + } + } + + uint32_t sample_size = 0; + + if (eprosima::safedds::ReturnCode::OK == ret) + { + ret = sample_serialized_size(sample, xcdr_version, sample_size); + } + + uint32_t aligned_size = eprosima::safedds::memory::align_to(sample_size, 4); + uint32_t payload_size = eprosima::safedds::portable::safe_sizeof() + aligned_size; + + if (eprosima::safedds::ReturnCode::OK == ret && buffer.size() >= payload_size) + { + // Indicate the number of padding bytes in the encapsulation options + uint32_t required_padding = aligned_size - sample_size; + representation_header.encapsulation_options[1] = static_cast(required_padding); + + eprosima::safedds::gen::SafeDDSTypeSupportSerializer ser_rh(buffer, eprosima::safedds::portable::MACHINE_ENDIANNESS, xcdr_version); + ret = ser_rh.serialize_array( + representation_header.encapsulation_kind.data(), + eprosima::safedds::serialization::RepresentationHeader::ENCAPSULATION_KIND_SIZE); + + if (eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser_rh.serialize_array( + representation_header.encapsulation_options.data(), eprosima::safedds::serialization::RepresentationHeader::ENCAPSULATION_OPTIONS_SIZE); + } + + if (eprosima::safedds::ReturnCode::OK == ret && sample_size > 0) + { + eprosima::safedds::memory::byte_array::ByteArrayView payload_view = { + &buffer[ser_rh.serializer_used_size()], + ser_rh.serializer_remaining_size() + }; + + eprosima::safedds::gen::SafeDDSTypeSupportSerializer ser(payload_view, eprosima::safedds::portable::MACHINE_ENDIANNESS, xcdr_version); + + ret = ChargerLocationSerialization::serialize(ser, sample); + + // Add padding + for (uint32_t i = 0; (eprosima::safedds::ReturnCode::OK == ret) && (i < required_padding); ++i) + { + ret = ser.serialize('\0'); + } + } + } + + return ret; + } + + eprosima::safedds::ReturnCode deserialize( + const eprosima::safedds::memory::IConstByteArrayView& buffer, + ChargerLocation& sample) const noexcept override + { + eprosima::safedds::serialization::RepresentationHeader representation_header{}; + + eprosima::safedds::serialization::cdr::Deserializer deserializer_rh(buffer, eprosima::safedds::portable::MACHINE_ENDIANNESS, eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1); + eprosima::safedds::ReturnCode ret = eprosima::safedds::protocol::rtps::RTPSTypeSupport::deserialize(deserializer_rh, representation_header); + + // Check expected RepresentationHeader type to be valid and supported + const bool is_cdr_v1 = representation_header.encapsulation_kind[0U] == 0U && (representation_header.encapsulation_kind[1U] <= 0x03U); + const bool is_cdr_v2 = representation_header.encapsulation_kind[0U] == 0U && (representation_header.encapsulation_kind[1U] >= 0x06U && representation_header.encapsulation_kind[1U] <= 0x0BU); + ret = (eprosima::safedds::ReturnCode::OK == ret && (is_cdr_v1 || is_cdr_v2)) ? eprosima::safedds::ReturnCode::OK : eprosima::safedds::ReturnCode::ERROR; + + // Skip payload + eprosima::safedds::memory::byte_array::ByteArrayView payload_view = {nullptr, 0U}; + uint32_t remaining_size = deserializer_rh.deserializer_remaining_size(); + if (eprosima::safedds::ReturnCode::OK == ret && remaining_size > 0) + { + uint32_t padding_size = static_cast(representation_header.encapsulation_options[1] & 0x03); + if (remaining_size >= padding_size) + { + remaining_size -= padding_size; + ret = deserializer_rh.deserializer_skip(remaining_size, payload_view); + } + else + { + ret = eprosima::safedds::ReturnCode::SERIALIZATION_INVALID_REPRESENTATION; + } + } + + if (eprosima::safedds::ReturnCode::OK == ret && remaining_size > 0) + { + // Get received endianness and deserialize payload + eprosima::safedds::gen::SafeDDSTypeSupportDeserializer deserializer(payload_view, + representation_header.get_endianness(), + is_cdr_v1 ? eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 : eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV2); + + ret = ChargerLocationSerialization::deserialize(deserializer, sample); + } + + return ret; + } + + eprosima::safedds::dds::ReturnCode get_key( + const ChargerLocation& data, + eprosima::safedds::dds::KeyHash& key_hash) const noexcept override + { + key_hash = {}; + + static_cast(data); + + return eprosima::safedds::dds::ReturnCode::ILLEGAL_OPERATION; + } + + eprosima::safedds::dds::ReturnCode get_key_from_payload( + const eprosima::safedds::memory::IConstByteArrayView& view, + const eprosima::safedds::protocol::PayloadKind& kind, + eprosima::safedds::dds::KeyHash& key_hash) const noexcept override + { + key_hash = {}; + + static_cast(view); + static_cast(kind); + + return eprosima::safedds::dds::ReturnCode::ILLEGAL_OPERATION; + } + + bool has_keys() const noexcept override + { + return false; + } + + private: + + eprosima::safedds::ReturnCode sample_serialized_size( + const ChargerLocation& sample, + eprosima::safedds::serialization::cdr::XCDRVersion xcdr_version, + uint32_t & serialized_size) const noexcept + { + serialized_size = 0; + + // Create a fake serializer to calculate the serialized size + eprosima::safedds::gen::SafeDDSTypeSupportSerializer ser(eprosima::safedds::portable::MACHINE_ENDIANNESS, xcdr_version); + eprosima::safedds::ReturnCode ret = ChargerLocationSerialization::serialize(ser, sample); + + if(eprosima::safedds::ReturnCode::OK == ret) + { + serialized_size = ser.serializer_used_size(); + } + + return ret; + } + + }; + + + typedef std::vector ChargerLocationSeq; + + + + // Forward declaration + struct ChargerTypeSerialization; + + /*! + * @brief This struct represents the structure ChargerType defined by the user in the IDL file. + * @ingroup pilot_server + */ + struct ChargerType + { + using SerializationStruct = ChargerTypeSerialization; + + static constexpr eprosima::safedds::gen::IDLExtensibilityKind IDL_EXTENSIBILITY = eprosima::safedds::gen::IDLExtensibilityKind::APPENDABLE; + + /// Member id + int32_t id = 0; + /// Member charger_type + std::string charger_type ; + + // Ensure bounds + static_assert(255 != 0, "charger_type shall be bounded or --default_unbounded_max_size shall be used"); + }; + + struct ChargerTypeSerialization + { + static constexpr uint32_t max_serialized_size() + { + // Return the precalculated max_serialized_size plus required: + // - Representation Header size (+4 B) since it is serialized in the typesupport serialization method + // - Alignment to 4 B since the serialization method adds padding + return eprosima::safedds::memory::align_to<268ULL + 4ULL, 4U>(); + } + + static constexpr uint32_t max_key_serialized_size() + { + return 0ULL; + } + + static eprosima::safedds::ReturnCode serialize( + eprosima::safedds::gen::SafeDDSTypeSupportSerializer& ser, + const ChargerType& sample) + { + using namespace safe_edge::pilot_server; + + eprosima::safedds::gen::EncodingAlgorithm prev_encoding = ser.get_encoding_algorithm(); + eprosima::safedds::ReturnCode ret = ser.set_encoding_algorithm( + ser.get_xcdr_version() == eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 ? + eprosima::safedds::gen::EncodingAlgorithm::PLAIN_CDR : + eprosima::safedds::gen::EncodingAlgorithm::DELIMITED_CDR); + + ret = ((eprosima::safedds::ReturnCode::OK == ret) && (sample.charger_type.size() <= 255)) ? ret : eprosima::safedds::ReturnCode::ERROR; + + + + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.begin_serialize_type() : ret; + + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type(0, sample.id) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type(1, sample.charger_type) : ret; + + if(eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser.end_serialize_type(); + } + + if(eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser.set_encoding_algorithm(prev_encoding); + } + + return ret; + } + + static eprosima::safedds::ReturnCode deserialize( + eprosima::safedds::gen::SafeDDSTypeSupportDeserializer& deser, + ChargerType& sample) + { + using namespace safe_edge::pilot_server; + + // Store the values of the external members in auxiliary variables + + sample = {}; + + // Restore the values of the external members + + const eprosima::safedds::gen::EncodingAlgorithm encoding = + deser.get_xcdr_version() == eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 ? + eprosima::safedds::gen::EncodingAlgorithm::PLAIN_CDR : + eprosima::safedds::gen::EncodingAlgorithm::DELIMITED_CDR; + + return deser.deserialize_type(encoding, + [&sample](eprosima::safedds::gen::SafeDDSTypeSupportDeserializer& inner_deser, const uint32_t id) -> eprosima::safedds::ReturnCode + { + eprosima::safedds::ReturnCode ret_value = eprosima::safedds::ReturnCode::OK; + switch (id) + { + case 0: + ret_value = inner_deser.deserialize_member(sample.id); + break; + + case 1: + ret_value = inner_deser.deserialize_member(sample.charger_type); + break; + + default: + ret_value = eprosima::safedds::ReturnCode::UNIMPLEMENTED; + break; + } + return ret_value; + }); + } + + static eprosima::safedds::ReturnCode serialize_key( + eprosima::safedds::gen::SafeDDSTypeSupportSerializer& ser, + const ChargerType& sample) + { + using namespace safe_edge::pilot_server; + + + eprosima::safedds::gen::EncodingAlgorithm prev_encoding = ser.get_encoding_algorithm(); + eprosima::safedds::ReturnCode ret = ser.set_encoding_algorithm(eprosima::safedds::gen::EncodingAlgorithm::PLAIN_CDR2); + + ret = ((eprosima::safedds::ReturnCode::OK == ret) && (sample.charger_type.size() <= 255)) ? ret : eprosima::safedds::ReturnCode::ERROR; + + + + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.begin_serialize_type() : ret; + + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type_key(0, sample.id) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type_key(1, sample.charger_type) : ret; + + + if(eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser.end_serialize_type(); + } + + if(eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser.set_encoding_algorithm(prev_encoding); + } + + return ret; + + } + + static bool compare( + const ChargerType& first, + const ChargerType& second) + { + using namespace safe_edge::pilot_server; + + bool ret = true; + + ret = ret && eprosima::safedds::gen::SafeDDSTypeSupportComparator::equal(first.id, second.id); + ret = ret && eprosima::safedds::gen::SafeDDSTypeSupportComparator::equal(first.charger_type, second.charger_type); + + return ret; + } + }; + + + struct ChargerTypeTypeSupport : + public eprosima::safedds::dds::TypedTypeSupport + { + using DataType = ChargerType; + + eprosima::safedds::dds::ReturnCode register_type( + eprosima::safedds::dds::DomainParticipant& participant, + const eprosima::safedds::memory::IStringView& type_name) noexcept override + { + return participant.register_type(*this, type_name); + } + + const eprosima::safedds::memory::IStringView& get_type_name() const noexcept override + { + static constexpr char const* default_name = "safe_edge::pilot_server::ChargerType"; + static const eprosima::safedds::memory::container::StaticString256 typesupport_name(default_name); + return typesupport_name; + } + + uint32_t max_serialized_size() const noexcept override + { + return ChargerTypeSerialization::max_serialized_size(); + } + + uint32_t serialized_size( + const ChargerType& sample, + eprosima::safedds::serialization::cdr::XCDRVersion xcdr_version) const noexcept override + { + uint32_t sample_size = 0; + + if (eprosima::safedds::ReturnCode::OK == sample_serialized_size(sample, xcdr_version, sample_size)) + { + sample_size = eprosima::safedds::memory::align_to( + eprosima::safedds::portable::safe_sizeof() + + sample_size, 4); + } + + return sample_size; + } + + eprosima::safedds::ReturnCode serialize( + const ChargerType& sample, + eprosima::safedds::memory::IByteArrayView& buffer, + eprosima::safedds::serialization::cdr::XCDRVersion xcdr_version) const noexcept override + { + eprosima::safedds::ReturnCode ret = + (eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 == xcdr_version) || (eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV2 == xcdr_version) ? + eprosima::safedds::ReturnCode::OK : eprosima::safedds::ReturnCode::ERROR; + + eprosima::safedds::serialization::RepresentationHeader representation_header{}; + + if (eprosima::safedds::ReturnCode::OK == ret) + { + if(eprosima::safedds::portable::MACHINE_ENDIANNESS == eprosima::safedds::platform::Endianness::SAFEDDS_BIG_ENDIAN) + { + representation_header = + eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 == xcdr_version ? + eprosima::safedds::serialization::REPRESENTATION_HEADER_CDR_BE : + eprosima::safedds::serialization::REPRESENTATION_HEADER_DELIMITED_CDR_BE; + } + else + { + representation_header = + eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 == xcdr_version ? + eprosima::safedds::serialization::REPRESENTATION_HEADER_CDR_LE : + eprosima::safedds::serialization::REPRESENTATION_HEADER_DELIMITED_CDR_LE; + } + } + + uint32_t sample_size = 0; + + if (eprosima::safedds::ReturnCode::OK == ret) + { + ret = sample_serialized_size(sample, xcdr_version, sample_size); + } + + uint32_t aligned_size = eprosima::safedds::memory::align_to(sample_size, 4); + uint32_t payload_size = eprosima::safedds::portable::safe_sizeof() + aligned_size; + + if (eprosima::safedds::ReturnCode::OK == ret && buffer.size() >= payload_size) + { + // Indicate the number of padding bytes in the encapsulation options + uint32_t required_padding = aligned_size - sample_size; + representation_header.encapsulation_options[1] = static_cast(required_padding); + + eprosima::safedds::gen::SafeDDSTypeSupportSerializer ser_rh(buffer, eprosima::safedds::portable::MACHINE_ENDIANNESS, xcdr_version); + ret = ser_rh.serialize_array( + representation_header.encapsulation_kind.data(), + eprosima::safedds::serialization::RepresentationHeader::ENCAPSULATION_KIND_SIZE); + + if (eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser_rh.serialize_array( + representation_header.encapsulation_options.data(), eprosima::safedds::serialization::RepresentationHeader::ENCAPSULATION_OPTIONS_SIZE); + } + + if (eprosima::safedds::ReturnCode::OK == ret && sample_size > 0) + { + eprosima::safedds::memory::byte_array::ByteArrayView payload_view = { + &buffer[ser_rh.serializer_used_size()], + ser_rh.serializer_remaining_size() + }; + + eprosima::safedds::gen::SafeDDSTypeSupportSerializer ser(payload_view, eprosima::safedds::portable::MACHINE_ENDIANNESS, xcdr_version); + + ret = ChargerTypeSerialization::serialize(ser, sample); + + // Add padding + for (uint32_t i = 0; (eprosima::safedds::ReturnCode::OK == ret) && (i < required_padding); ++i) + { + ret = ser.serialize('\0'); + } + } + } + + return ret; + } + + eprosima::safedds::ReturnCode deserialize( + const eprosima::safedds::memory::IConstByteArrayView& buffer, + ChargerType& sample) const noexcept override + { + eprosima::safedds::serialization::RepresentationHeader representation_header{}; + + eprosima::safedds::serialization::cdr::Deserializer deserializer_rh(buffer, eprosima::safedds::portable::MACHINE_ENDIANNESS, eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1); + eprosima::safedds::ReturnCode ret = eprosima::safedds::protocol::rtps::RTPSTypeSupport::deserialize(deserializer_rh, representation_header); + + // Check expected RepresentationHeader type to be valid and supported + const bool is_cdr_v1 = representation_header.encapsulation_kind[0U] == 0U && (representation_header.encapsulation_kind[1U] <= 0x03U); + const bool is_cdr_v2 = representation_header.encapsulation_kind[0U] == 0U && (representation_header.encapsulation_kind[1U] >= 0x06U && representation_header.encapsulation_kind[1U] <= 0x0BU); + ret = (eprosima::safedds::ReturnCode::OK == ret && (is_cdr_v1 || is_cdr_v2)) ? eprosima::safedds::ReturnCode::OK : eprosima::safedds::ReturnCode::ERROR; + + // Skip payload + eprosima::safedds::memory::byte_array::ByteArrayView payload_view = {nullptr, 0U}; + uint32_t remaining_size = deserializer_rh.deserializer_remaining_size(); + if (eprosima::safedds::ReturnCode::OK == ret && remaining_size > 0) + { + uint32_t padding_size = static_cast(representation_header.encapsulation_options[1] & 0x03); + if (remaining_size >= padding_size) + { + remaining_size -= padding_size; + ret = deserializer_rh.deserializer_skip(remaining_size, payload_view); + } + else + { + ret = eprosima::safedds::ReturnCode::SERIALIZATION_INVALID_REPRESENTATION; + } + } + + if (eprosima::safedds::ReturnCode::OK == ret && remaining_size > 0) + { + // Get received endianness and deserialize payload + eprosima::safedds::gen::SafeDDSTypeSupportDeserializer deserializer(payload_view, + representation_header.get_endianness(), + is_cdr_v1 ? eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 : eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV2); + + ret = ChargerTypeSerialization::deserialize(deserializer, sample); + } + + return ret; + } + + eprosima::safedds::dds::ReturnCode get_key( + const ChargerType& data, + eprosima::safedds::dds::KeyHash& key_hash) const noexcept override + { + key_hash = {}; + + static_cast(data); + + return eprosima::safedds::dds::ReturnCode::ILLEGAL_OPERATION; + } + + eprosima::safedds::dds::ReturnCode get_key_from_payload( + const eprosima::safedds::memory::IConstByteArrayView& view, + const eprosima::safedds::protocol::PayloadKind& kind, + eprosima::safedds::dds::KeyHash& key_hash) const noexcept override + { + key_hash = {}; + + static_cast(view); + static_cast(kind); + + return eprosima::safedds::dds::ReturnCode::ILLEGAL_OPERATION; + } + + bool has_keys() const noexcept override + { + return false; + } + + private: + + eprosima::safedds::ReturnCode sample_serialized_size( + const ChargerType& sample, + eprosima::safedds::serialization::cdr::XCDRVersion xcdr_version, + uint32_t & serialized_size) const noexcept + { + serialized_size = 0; + + // Create a fake serializer to calculate the serialized size + eprosima::safedds::gen::SafeDDSTypeSupportSerializer ser(eprosima::safedds::portable::MACHINE_ENDIANNESS, xcdr_version); + eprosima::safedds::ReturnCode ret = ChargerTypeSerialization::serialize(ser, sample); + + if(eprosima::safedds::ReturnCode::OK == ret) + { + serialized_size = ser.serializer_used_size(); + } + + return ret; + } + + }; + + + typedef std::vector ChargerTypeSeq; + + + + // Forward declaration + struct ChargingSessionSerialization; + + /*! + * @brief This struct represents the structure ChargingSession defined by the user in the IDL file. + * @ingroup pilot_server + */ + struct ChargingSession + { + using SerializationStruct = ChargingSessionSerialization; + + static constexpr eprosima::safedds::gen::IDLExtensibilityKind IDL_EXTENSIBILITY = eprosima::safedds::gen::IDLExtensibilityKind::APPENDABLE; + + /// Member id + int32_t id = 0; + /// Member station_id + int32_t station_id = 0; + /// Member charger_type_id + std::string charger_type_id ; + /// Member consume_wh + double consume_wh = 0.0; + /// Member duration_min + int32_t duration_min = 0; + /// Member date_iso8601 + std::string date_iso8601 ; + /// Member ingested_at_iso8601 + std::string ingested_at_iso8601 ; + + // Ensure bounds + static_assert(255 != 0, "charger_type_id shall be bounded or --default_unbounded_max_size shall be used"); + + + static_assert(255 != 0, "date_iso8601 shall be bounded or --default_unbounded_max_size shall be used"); + static_assert(255 != 0, "ingested_at_iso8601 shall be bounded or --default_unbounded_max_size shall be used"); + }; + + struct ChargingSessionSerialization + { + static constexpr uint32_t max_serialized_size() + { + // Return the precalculated max_serialized_size plus required: + // - Representation Header size (+4 B) since it is serialized in the typesupport serialization method + // - Alignment to 4 B since the serialization method adds padding + return eprosima::safedds::memory::align_to<804ULL + 4ULL, 4U>(); + } + + static constexpr uint32_t max_key_serialized_size() + { + return 0ULL; + } + + static eprosima::safedds::ReturnCode serialize( + eprosima::safedds::gen::SafeDDSTypeSupportSerializer& ser, + const ChargingSession& sample) + { + using namespace safe_edge::pilot_server; + + eprosima::safedds::gen::EncodingAlgorithm prev_encoding = ser.get_encoding_algorithm(); + eprosima::safedds::ReturnCode ret = ser.set_encoding_algorithm( + ser.get_xcdr_version() == eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 ? + eprosima::safedds::gen::EncodingAlgorithm::PLAIN_CDR : + eprosima::safedds::gen::EncodingAlgorithm::DELIMITED_CDR); + + ret = ((eprosima::safedds::ReturnCode::OK == ret) && (sample.charger_type_id.size() <= 255)) ? ret : eprosima::safedds::ReturnCode::ERROR; + ret = ((eprosima::safedds::ReturnCode::OK == ret) && (sample.date_iso8601.size() <= 255)) ? ret : eprosima::safedds::ReturnCode::ERROR; + ret = ((eprosima::safedds::ReturnCode::OK == ret) && (sample.ingested_at_iso8601.size() <= 255)) ? ret : eprosima::safedds::ReturnCode::ERROR; + + + + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.begin_serialize_type() : ret; + + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type(0, sample.id) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type(1, sample.station_id) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type(2, sample.charger_type_id) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type(3, sample.consume_wh) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type(4, sample.duration_min) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type(5, sample.date_iso8601) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type(6, sample.ingested_at_iso8601) : ret; + + if(eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser.end_serialize_type(); + } + + if(eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser.set_encoding_algorithm(prev_encoding); + } + + return ret; + } + + static eprosima::safedds::ReturnCode deserialize( + eprosima::safedds::gen::SafeDDSTypeSupportDeserializer& deser, + ChargingSession& sample) + { + using namespace safe_edge::pilot_server; + + // Store the values of the external members in auxiliary variables + + sample = {}; + + // Restore the values of the external members + + const eprosima::safedds::gen::EncodingAlgorithm encoding = + deser.get_xcdr_version() == eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 ? + eprosima::safedds::gen::EncodingAlgorithm::PLAIN_CDR : + eprosima::safedds::gen::EncodingAlgorithm::DELIMITED_CDR; + + return deser.deserialize_type(encoding, + [&sample](eprosima::safedds::gen::SafeDDSTypeSupportDeserializer& inner_deser, const uint32_t id) -> eprosima::safedds::ReturnCode + { + eprosima::safedds::ReturnCode ret_value = eprosima::safedds::ReturnCode::OK; + switch (id) + { + case 0: + ret_value = inner_deser.deserialize_member(sample.id); + break; + + case 1: + ret_value = inner_deser.deserialize_member(sample.station_id); + break; + + case 2: + ret_value = inner_deser.deserialize_member(sample.charger_type_id); + break; + + case 3: + ret_value = inner_deser.deserialize_member(sample.consume_wh); + break; + + case 4: + ret_value = inner_deser.deserialize_member(sample.duration_min); + break; + + case 5: + ret_value = inner_deser.deserialize_member(sample.date_iso8601); + break; + + case 6: + ret_value = inner_deser.deserialize_member(sample.ingested_at_iso8601); + break; + + default: + ret_value = eprosima::safedds::ReturnCode::UNIMPLEMENTED; + break; + } + return ret_value; + }); + } + + static eprosima::safedds::ReturnCode serialize_key( + eprosima::safedds::gen::SafeDDSTypeSupportSerializer& ser, + const ChargingSession& sample) + { + using namespace safe_edge::pilot_server; + + + eprosima::safedds::gen::EncodingAlgorithm prev_encoding = ser.get_encoding_algorithm(); + eprosima::safedds::ReturnCode ret = ser.set_encoding_algorithm(eprosima::safedds::gen::EncodingAlgorithm::PLAIN_CDR2); + + ret = ((eprosima::safedds::ReturnCode::OK == ret) && (sample.charger_type_id.size() <= 255)) ? ret : eprosima::safedds::ReturnCode::ERROR; + ret = ((eprosima::safedds::ReturnCode::OK == ret) && (sample.date_iso8601.size() <= 255)) ? ret : eprosima::safedds::ReturnCode::ERROR; + ret = ((eprosima::safedds::ReturnCode::OK == ret) && (sample.ingested_at_iso8601.size() <= 255)) ? ret : eprosima::safedds::ReturnCode::ERROR; + + + + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.begin_serialize_type() : ret; + + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type_key(0, sample.id) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type_key(1, sample.station_id) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type_key(2, sample.charger_type_id) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type_key(3, sample.consume_wh) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type_key(4, sample.duration_min) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type_key(5, sample.date_iso8601) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type_key(6, sample.ingested_at_iso8601) : ret; + + + if(eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser.end_serialize_type(); + } + + if(eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser.set_encoding_algorithm(prev_encoding); + } + + return ret; + + } + + static bool compare( + const ChargingSession& first, + const ChargingSession& second) + { + using namespace safe_edge::pilot_server; + + bool ret = true; + + ret = ret && eprosima::safedds::gen::SafeDDSTypeSupportComparator::equal(first.id, second.id); + ret = ret && eprosima::safedds::gen::SafeDDSTypeSupportComparator::equal(first.station_id, second.station_id); + ret = ret && eprosima::safedds::gen::SafeDDSTypeSupportComparator::equal(first.charger_type_id, second.charger_type_id); + ret = ret && eprosima::safedds::gen::SafeDDSTypeSupportComparator::equal(first.consume_wh, second.consume_wh); + ret = ret && eprosima::safedds::gen::SafeDDSTypeSupportComparator::equal(first.duration_min, second.duration_min); + ret = ret && eprosima::safedds::gen::SafeDDSTypeSupportComparator::equal(first.date_iso8601, second.date_iso8601); + ret = ret && eprosima::safedds::gen::SafeDDSTypeSupportComparator::equal(first.ingested_at_iso8601, second.ingested_at_iso8601); + + return ret; + } + }; + + + struct ChargingSessionTypeSupport : + public eprosima::safedds::dds::TypedTypeSupport + { + using DataType = ChargingSession; + + eprosima::safedds::dds::ReturnCode register_type( + eprosima::safedds::dds::DomainParticipant& participant, + const eprosima::safedds::memory::IStringView& type_name) noexcept override + { + return participant.register_type(*this, type_name); + } + + const eprosima::safedds::memory::IStringView& get_type_name() const noexcept override + { + static constexpr char const* default_name = "safe_edge::pilot_server::ChargingSession"; + static const eprosima::safedds::memory::container::StaticString256 typesupport_name(default_name); + return typesupport_name; + } + + uint32_t max_serialized_size() const noexcept override + { + return ChargingSessionSerialization::max_serialized_size(); + } + + uint32_t serialized_size( + const ChargingSession& sample, + eprosima::safedds::serialization::cdr::XCDRVersion xcdr_version) const noexcept override + { + uint32_t sample_size = 0; + + if (eprosima::safedds::ReturnCode::OK == sample_serialized_size(sample, xcdr_version, sample_size)) + { + sample_size = eprosima::safedds::memory::align_to( + eprosima::safedds::portable::safe_sizeof() + + sample_size, 4); + } + + return sample_size; + } + + eprosima::safedds::ReturnCode serialize( + const ChargingSession& sample, + eprosima::safedds::memory::IByteArrayView& buffer, + eprosima::safedds::serialization::cdr::XCDRVersion xcdr_version) const noexcept override + { + eprosima::safedds::ReturnCode ret = + (eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 == xcdr_version) || (eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV2 == xcdr_version) ? + eprosima::safedds::ReturnCode::OK : eprosima::safedds::ReturnCode::ERROR; + + eprosima::safedds::serialization::RepresentationHeader representation_header{}; + + if (eprosima::safedds::ReturnCode::OK == ret) + { + if(eprosima::safedds::portable::MACHINE_ENDIANNESS == eprosima::safedds::platform::Endianness::SAFEDDS_BIG_ENDIAN) + { + representation_header = + eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 == xcdr_version ? + eprosima::safedds::serialization::REPRESENTATION_HEADER_CDR_BE : + eprosima::safedds::serialization::REPRESENTATION_HEADER_DELIMITED_CDR_BE; + } + else + { + representation_header = + eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 == xcdr_version ? + eprosima::safedds::serialization::REPRESENTATION_HEADER_CDR_LE : + eprosima::safedds::serialization::REPRESENTATION_HEADER_DELIMITED_CDR_LE; + } + } + + uint32_t sample_size = 0; + + if (eprosima::safedds::ReturnCode::OK == ret) + { + ret = sample_serialized_size(sample, xcdr_version, sample_size); + } + + uint32_t aligned_size = eprosima::safedds::memory::align_to(sample_size, 4); + uint32_t payload_size = eprosima::safedds::portable::safe_sizeof() + aligned_size; + + if (eprosima::safedds::ReturnCode::OK == ret && buffer.size() >= payload_size) + { + // Indicate the number of padding bytes in the encapsulation options + uint32_t required_padding = aligned_size - sample_size; + representation_header.encapsulation_options[1] = static_cast(required_padding); + + eprosima::safedds::gen::SafeDDSTypeSupportSerializer ser_rh(buffer, eprosima::safedds::portable::MACHINE_ENDIANNESS, xcdr_version); + ret = ser_rh.serialize_array( + representation_header.encapsulation_kind.data(), + eprosima::safedds::serialization::RepresentationHeader::ENCAPSULATION_KIND_SIZE); + + if (eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser_rh.serialize_array( + representation_header.encapsulation_options.data(), eprosima::safedds::serialization::RepresentationHeader::ENCAPSULATION_OPTIONS_SIZE); + } + + if (eprosima::safedds::ReturnCode::OK == ret && sample_size > 0) + { + eprosima::safedds::memory::byte_array::ByteArrayView payload_view = { + &buffer[ser_rh.serializer_used_size()], + ser_rh.serializer_remaining_size() + }; + + eprosima::safedds::gen::SafeDDSTypeSupportSerializer ser(payload_view, eprosima::safedds::portable::MACHINE_ENDIANNESS, xcdr_version); + + ret = ChargingSessionSerialization::serialize(ser, sample); + + // Add padding + for (uint32_t i = 0; (eprosima::safedds::ReturnCode::OK == ret) && (i < required_padding); ++i) + { + ret = ser.serialize('\0'); + } + } + } + + return ret; + } + + eprosima::safedds::ReturnCode deserialize( + const eprosima::safedds::memory::IConstByteArrayView& buffer, + ChargingSession& sample) const noexcept override + { + eprosima::safedds::serialization::RepresentationHeader representation_header{}; + + eprosima::safedds::serialization::cdr::Deserializer deserializer_rh(buffer, eprosima::safedds::portable::MACHINE_ENDIANNESS, eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1); + eprosima::safedds::ReturnCode ret = eprosima::safedds::protocol::rtps::RTPSTypeSupport::deserialize(deserializer_rh, representation_header); + + // Check expected RepresentationHeader type to be valid and supported + const bool is_cdr_v1 = representation_header.encapsulation_kind[0U] == 0U && (representation_header.encapsulation_kind[1U] <= 0x03U); + const bool is_cdr_v2 = representation_header.encapsulation_kind[0U] == 0U && (representation_header.encapsulation_kind[1U] >= 0x06U && representation_header.encapsulation_kind[1U] <= 0x0BU); + ret = (eprosima::safedds::ReturnCode::OK == ret && (is_cdr_v1 || is_cdr_v2)) ? eprosima::safedds::ReturnCode::OK : eprosima::safedds::ReturnCode::ERROR; + + // Skip payload + eprosima::safedds::memory::byte_array::ByteArrayView payload_view = {nullptr, 0U}; + uint32_t remaining_size = deserializer_rh.deserializer_remaining_size(); + if (eprosima::safedds::ReturnCode::OK == ret && remaining_size > 0) + { + uint32_t padding_size = static_cast(representation_header.encapsulation_options[1] & 0x03); + if (remaining_size >= padding_size) + { + remaining_size -= padding_size; + ret = deserializer_rh.deserializer_skip(remaining_size, payload_view); + } + else + { + ret = eprosima::safedds::ReturnCode::SERIALIZATION_INVALID_REPRESENTATION; + } + } + + if (eprosima::safedds::ReturnCode::OK == ret && remaining_size > 0) + { + // Get received endianness and deserialize payload + eprosima::safedds::gen::SafeDDSTypeSupportDeserializer deserializer(payload_view, + representation_header.get_endianness(), + is_cdr_v1 ? eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 : eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV2); + + ret = ChargingSessionSerialization::deserialize(deserializer, sample); + } + + return ret; + } + + eprosima::safedds::dds::ReturnCode get_key( + const ChargingSession& data, + eprosima::safedds::dds::KeyHash& key_hash) const noexcept override + { + key_hash = {}; + + static_cast(data); + + return eprosima::safedds::dds::ReturnCode::ILLEGAL_OPERATION; + } + + eprosima::safedds::dds::ReturnCode get_key_from_payload( + const eprosima::safedds::memory::IConstByteArrayView& view, + const eprosima::safedds::protocol::PayloadKind& kind, + eprosima::safedds::dds::KeyHash& key_hash) const noexcept override + { + key_hash = {}; + + static_cast(view); + static_cast(kind); + + return eprosima::safedds::dds::ReturnCode::ILLEGAL_OPERATION; + } + + bool has_keys() const noexcept override + { + return false; + } + + private: + + eprosima::safedds::ReturnCode sample_serialized_size( + const ChargingSession& sample, + eprosima::safedds::serialization::cdr::XCDRVersion xcdr_version, + uint32_t & serialized_size) const noexcept + { + serialized_size = 0; + + // Create a fake serializer to calculate the serialized size + eprosima::safedds::gen::SafeDDSTypeSupportSerializer ser(eprosima::safedds::portable::MACHINE_ENDIANNESS, xcdr_version); + eprosima::safedds::ReturnCode ret = ChargingSessionSerialization::serialize(ser, sample); + + if(eprosima::safedds::ReturnCode::OK == ret) + { + serialized_size = ser.serializer_used_size(); + } + + return ret; + } + + }; + + + typedef std::vector ChargingSessionSeq; + + + + // Forward declaration + struct TransitHealthSerialization; + + /*! + * @brief This struct represents the structure TransitHealth defined by the user in the IDL file. + * @ingroup pilot_server + */ + struct TransitHealth + { + using SerializationStruct = TransitHealthSerialization; + + static constexpr eprosima::safedds::gen::IDLExtensibilityKind IDL_EXTENSIBILITY = eprosima::safedds::gen::IDLExtensibilityKind::APPENDABLE; + + /// Member status + std::string status ; + /// Member last_fetch_ts + double last_fetch_ts = 0.0; + + // Ensure bounds + static_assert(255 != 0, "status shall be bounded or --default_unbounded_max_size shall be used"); + + }; + + struct TransitHealthSerialization + { + static constexpr uint32_t max_serialized_size() + { + // Return the precalculated max_serialized_size plus required: + // - Representation Header size (+4 B) since it is serialized in the typesupport serialization method + // - Alignment to 4 B since the serialization method adds padding + return eprosima::safedds::memory::align_to<272ULL + 4ULL, 4U>(); + } + + static constexpr uint32_t max_key_serialized_size() + { + return 0ULL; + } + + static eprosima::safedds::ReturnCode serialize( + eprosima::safedds::gen::SafeDDSTypeSupportSerializer& ser, + const TransitHealth& sample) + { + using namespace safe_edge::pilot_server; + + eprosima::safedds::gen::EncodingAlgorithm prev_encoding = ser.get_encoding_algorithm(); + eprosima::safedds::ReturnCode ret = ser.set_encoding_algorithm( + ser.get_xcdr_version() == eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 ? + eprosima::safedds::gen::EncodingAlgorithm::PLAIN_CDR : + eprosima::safedds::gen::EncodingAlgorithm::DELIMITED_CDR); + + ret = ((eprosima::safedds::ReturnCode::OK == ret) && (sample.status.size() <= 255)) ? ret : eprosima::safedds::ReturnCode::ERROR; + + + + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.begin_serialize_type() : ret; + + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type(0, sample.status) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type(1, sample.last_fetch_ts) : ret; + + if(eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser.end_serialize_type(); + } + + if(eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser.set_encoding_algorithm(prev_encoding); + } + + return ret; + } + + static eprosima::safedds::ReturnCode deserialize( + eprosima::safedds::gen::SafeDDSTypeSupportDeserializer& deser, + TransitHealth& sample) + { + using namespace safe_edge::pilot_server; + + // Store the values of the external members in auxiliary variables + + sample = {}; + + // Restore the values of the external members + + const eprosima::safedds::gen::EncodingAlgorithm encoding = + deser.get_xcdr_version() == eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 ? + eprosima::safedds::gen::EncodingAlgorithm::PLAIN_CDR : + eprosima::safedds::gen::EncodingAlgorithm::DELIMITED_CDR; + + return deser.deserialize_type(encoding, + [&sample](eprosima::safedds::gen::SafeDDSTypeSupportDeserializer& inner_deser, const uint32_t id) -> eprosima::safedds::ReturnCode + { + eprosima::safedds::ReturnCode ret_value = eprosima::safedds::ReturnCode::OK; + switch (id) + { + case 0: + ret_value = inner_deser.deserialize_member(sample.status); + break; + + case 1: + ret_value = inner_deser.deserialize_member(sample.last_fetch_ts); + break; + + default: + ret_value = eprosima::safedds::ReturnCode::UNIMPLEMENTED; + break; + } + return ret_value; + }); + } + + static eprosima::safedds::ReturnCode serialize_key( + eprosima::safedds::gen::SafeDDSTypeSupportSerializer& ser, + const TransitHealth& sample) + { + using namespace safe_edge::pilot_server; + + + eprosima::safedds::gen::EncodingAlgorithm prev_encoding = ser.get_encoding_algorithm(); + eprosima::safedds::ReturnCode ret = ser.set_encoding_algorithm(eprosima::safedds::gen::EncodingAlgorithm::PLAIN_CDR2); + + ret = ((eprosima::safedds::ReturnCode::OK == ret) && (sample.status.size() <= 255)) ? ret : eprosima::safedds::ReturnCode::ERROR; + + + + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.begin_serialize_type() : ret; + + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type_key(0, sample.status) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type_key(1, sample.last_fetch_ts) : ret; + + + if(eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser.end_serialize_type(); + } + + if(eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser.set_encoding_algorithm(prev_encoding); + } + + return ret; + + } + + static bool compare( + const TransitHealth& first, + const TransitHealth& second) + { + using namespace safe_edge::pilot_server; + + bool ret = true; + + ret = ret && eprosima::safedds::gen::SafeDDSTypeSupportComparator::equal(first.status, second.status); + ret = ret && eprosima::safedds::gen::SafeDDSTypeSupportComparator::equal(first.last_fetch_ts, second.last_fetch_ts); + + return ret; + } + }; + + + struct TransitHealthTypeSupport : + public eprosima::safedds::dds::TypedTypeSupport + { + using DataType = TransitHealth; + + eprosima::safedds::dds::ReturnCode register_type( + eprosima::safedds::dds::DomainParticipant& participant, + const eprosima::safedds::memory::IStringView& type_name) noexcept override + { + return participant.register_type(*this, type_name); + } + + const eprosima::safedds::memory::IStringView& get_type_name() const noexcept override + { + static constexpr char const* default_name = "safe_edge::pilot_server::TransitHealth"; + static const eprosima::safedds::memory::container::StaticString256 typesupport_name(default_name); + return typesupport_name; + } + + uint32_t max_serialized_size() const noexcept override + { + return TransitHealthSerialization::max_serialized_size(); + } + + uint32_t serialized_size( + const TransitHealth& sample, + eprosima::safedds::serialization::cdr::XCDRVersion xcdr_version) const noexcept override + { + uint32_t sample_size = 0; + + if (eprosima::safedds::ReturnCode::OK == sample_serialized_size(sample, xcdr_version, sample_size)) + { + sample_size = eprosima::safedds::memory::align_to( + eprosima::safedds::portable::safe_sizeof() + + sample_size, 4); + } + + return sample_size; + } + + eprosima::safedds::ReturnCode serialize( + const TransitHealth& sample, + eprosima::safedds::memory::IByteArrayView& buffer, + eprosima::safedds::serialization::cdr::XCDRVersion xcdr_version) const noexcept override + { + eprosima::safedds::ReturnCode ret = + (eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 == xcdr_version) || (eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV2 == xcdr_version) ? + eprosima::safedds::ReturnCode::OK : eprosima::safedds::ReturnCode::ERROR; + + eprosima::safedds::serialization::RepresentationHeader representation_header{}; + + if (eprosima::safedds::ReturnCode::OK == ret) + { + if(eprosima::safedds::portable::MACHINE_ENDIANNESS == eprosima::safedds::platform::Endianness::SAFEDDS_BIG_ENDIAN) + { + representation_header = + eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 == xcdr_version ? + eprosima::safedds::serialization::REPRESENTATION_HEADER_CDR_BE : + eprosima::safedds::serialization::REPRESENTATION_HEADER_DELIMITED_CDR_BE; + } + else + { + representation_header = + eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 == xcdr_version ? + eprosima::safedds::serialization::REPRESENTATION_HEADER_CDR_LE : + eprosima::safedds::serialization::REPRESENTATION_HEADER_DELIMITED_CDR_LE; + } + } + + uint32_t sample_size = 0; + + if (eprosima::safedds::ReturnCode::OK == ret) + { + ret = sample_serialized_size(sample, xcdr_version, sample_size); + } + + uint32_t aligned_size = eprosima::safedds::memory::align_to(sample_size, 4); + uint32_t payload_size = eprosima::safedds::portable::safe_sizeof() + aligned_size; + + if (eprosima::safedds::ReturnCode::OK == ret && buffer.size() >= payload_size) + { + // Indicate the number of padding bytes in the encapsulation options + uint32_t required_padding = aligned_size - sample_size; + representation_header.encapsulation_options[1] = static_cast(required_padding); + + eprosima::safedds::gen::SafeDDSTypeSupportSerializer ser_rh(buffer, eprosima::safedds::portable::MACHINE_ENDIANNESS, xcdr_version); + ret = ser_rh.serialize_array( + representation_header.encapsulation_kind.data(), + eprosima::safedds::serialization::RepresentationHeader::ENCAPSULATION_KIND_SIZE); + + if (eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser_rh.serialize_array( + representation_header.encapsulation_options.data(), eprosima::safedds::serialization::RepresentationHeader::ENCAPSULATION_OPTIONS_SIZE); + } + + if (eprosima::safedds::ReturnCode::OK == ret && sample_size > 0) + { + eprosima::safedds::memory::byte_array::ByteArrayView payload_view = { + &buffer[ser_rh.serializer_used_size()], + ser_rh.serializer_remaining_size() + }; + + eprosima::safedds::gen::SafeDDSTypeSupportSerializer ser(payload_view, eprosima::safedds::portable::MACHINE_ENDIANNESS, xcdr_version); + + ret = TransitHealthSerialization::serialize(ser, sample); + + // Add padding + for (uint32_t i = 0; (eprosima::safedds::ReturnCode::OK == ret) && (i < required_padding); ++i) + { + ret = ser.serialize('\0'); + } + } + } + + return ret; + } + + eprosima::safedds::ReturnCode deserialize( + const eprosima::safedds::memory::IConstByteArrayView& buffer, + TransitHealth& sample) const noexcept override + { + eprosima::safedds::serialization::RepresentationHeader representation_header{}; + + eprosima::safedds::serialization::cdr::Deserializer deserializer_rh(buffer, eprosima::safedds::portable::MACHINE_ENDIANNESS, eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1); + eprosima::safedds::ReturnCode ret = eprosima::safedds::protocol::rtps::RTPSTypeSupport::deserialize(deserializer_rh, representation_header); + + // Check expected RepresentationHeader type to be valid and supported + const bool is_cdr_v1 = representation_header.encapsulation_kind[0U] == 0U && (representation_header.encapsulation_kind[1U] <= 0x03U); + const bool is_cdr_v2 = representation_header.encapsulation_kind[0U] == 0U && (representation_header.encapsulation_kind[1U] >= 0x06U && representation_header.encapsulation_kind[1U] <= 0x0BU); + ret = (eprosima::safedds::ReturnCode::OK == ret && (is_cdr_v1 || is_cdr_v2)) ? eprosima::safedds::ReturnCode::OK : eprosima::safedds::ReturnCode::ERROR; + + // Skip payload + eprosima::safedds::memory::byte_array::ByteArrayView payload_view = {nullptr, 0U}; + uint32_t remaining_size = deserializer_rh.deserializer_remaining_size(); + if (eprosima::safedds::ReturnCode::OK == ret && remaining_size > 0) + { + uint32_t padding_size = static_cast(representation_header.encapsulation_options[1] & 0x03); + if (remaining_size >= padding_size) + { + remaining_size -= padding_size; + ret = deserializer_rh.deserializer_skip(remaining_size, payload_view); + } + else + { + ret = eprosima::safedds::ReturnCode::SERIALIZATION_INVALID_REPRESENTATION; + } + } + + if (eprosima::safedds::ReturnCode::OK == ret && remaining_size > 0) + { + // Get received endianness and deserialize payload + eprosima::safedds::gen::SafeDDSTypeSupportDeserializer deserializer(payload_view, + representation_header.get_endianness(), + is_cdr_v1 ? eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 : eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV2); + + ret = TransitHealthSerialization::deserialize(deserializer, sample); + } + + return ret; + } + + eprosima::safedds::dds::ReturnCode get_key( + const TransitHealth& data, + eprosima::safedds::dds::KeyHash& key_hash) const noexcept override + { + key_hash = {}; + + static_cast(data); + + return eprosima::safedds::dds::ReturnCode::ILLEGAL_OPERATION; + } + + eprosima::safedds::dds::ReturnCode get_key_from_payload( + const eprosima::safedds::memory::IConstByteArrayView& view, + const eprosima::safedds::protocol::PayloadKind& kind, + eprosima::safedds::dds::KeyHash& key_hash) const noexcept override + { + key_hash = {}; + + static_cast(view); + static_cast(kind); + + return eprosima::safedds::dds::ReturnCode::ILLEGAL_OPERATION; + } + + bool has_keys() const noexcept override + { + return false; + } + + private: + + eprosima::safedds::ReturnCode sample_serialized_size( + const TransitHealth& sample, + eprosima::safedds::serialization::cdr::XCDRVersion xcdr_version, + uint32_t & serialized_size) const noexcept + { + serialized_size = 0; + + // Create a fake serializer to calculate the serialized size + eprosima::safedds::gen::SafeDDSTypeSupportSerializer ser(eprosima::safedds::portable::MACHINE_ENDIANNESS, xcdr_version); + eprosima::safedds::ReturnCode ret = TransitHealthSerialization::serialize(ser, sample); + + if(eprosima::safedds::ReturnCode::OK == ret) + { + serialized_size = ser.serializer_used_size(); + } + + return ret; + } + + }; + + + + // Forward declaration + struct RouteMetricSerialization; + + /*! + * @brief This struct represents the structure RouteMetric defined by the user in the IDL file. + * @ingroup pilot_server + */ + struct RouteMetric + { + using SerializationStruct = RouteMetricSerialization; + + static constexpr eprosima::safedds::gen::IDLExtensibilityKind IDL_EXTENSIBILITY = eprosima::safedds::gen::IDLExtensibilityKind::APPENDABLE; + + /// Member route_id + std::string route_id ; + /// Member updates_count + int32_t updates_count = 0; + + // Ensure bounds + static_assert(255 != 0, "route_id shall be bounded or --default_unbounded_max_size shall be used"); + + }; + + struct RouteMetricSerialization + { + static constexpr uint32_t max_serialized_size() + { + // Return the precalculated max_serialized_size plus required: + // - Representation Header size (+4 B) since it is serialized in the typesupport serialization method + // - Alignment to 4 B since the serialization method adds padding + return eprosima::safedds::memory::align_to<268ULL + 4ULL, 4U>(); + } + + static constexpr uint32_t max_key_serialized_size() + { + return 0ULL; + } + + static eprosima::safedds::ReturnCode serialize( + eprosima::safedds::gen::SafeDDSTypeSupportSerializer& ser, + const RouteMetric& sample) + { + using namespace safe_edge::pilot_server; + + eprosima::safedds::gen::EncodingAlgorithm prev_encoding = ser.get_encoding_algorithm(); + eprosima::safedds::ReturnCode ret = ser.set_encoding_algorithm( + ser.get_xcdr_version() == eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 ? + eprosima::safedds::gen::EncodingAlgorithm::PLAIN_CDR : + eprosima::safedds::gen::EncodingAlgorithm::DELIMITED_CDR); + + ret = ((eprosima::safedds::ReturnCode::OK == ret) && (sample.route_id.size() <= 255)) ? ret : eprosima::safedds::ReturnCode::ERROR; + + + + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.begin_serialize_type() : ret; + + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type(0, sample.route_id) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type(1, sample.updates_count) : ret; + + if(eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser.end_serialize_type(); + } + + if(eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser.set_encoding_algorithm(prev_encoding); + } + + return ret; + } + + static eprosima::safedds::ReturnCode deserialize( + eprosima::safedds::gen::SafeDDSTypeSupportDeserializer& deser, + RouteMetric& sample) + { + using namespace safe_edge::pilot_server; + + // Store the values of the external members in auxiliary variables + + sample = {}; + + // Restore the values of the external members + + const eprosima::safedds::gen::EncodingAlgorithm encoding = + deser.get_xcdr_version() == eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 ? + eprosima::safedds::gen::EncodingAlgorithm::PLAIN_CDR : + eprosima::safedds::gen::EncodingAlgorithm::DELIMITED_CDR; + + return deser.deserialize_type(encoding, + [&sample](eprosima::safedds::gen::SafeDDSTypeSupportDeserializer& inner_deser, const uint32_t id) -> eprosima::safedds::ReturnCode + { + eprosima::safedds::ReturnCode ret_value = eprosima::safedds::ReturnCode::OK; + switch (id) + { + case 0: + ret_value = inner_deser.deserialize_member(sample.route_id); + break; + + case 1: + ret_value = inner_deser.deserialize_member(sample.updates_count); + break; + + default: + ret_value = eprosima::safedds::ReturnCode::UNIMPLEMENTED; + break; + } + return ret_value; + }); + } + + static eprosima::safedds::ReturnCode serialize_key( + eprosima::safedds::gen::SafeDDSTypeSupportSerializer& ser, + const RouteMetric& sample) + { + using namespace safe_edge::pilot_server; + + + eprosima::safedds::gen::EncodingAlgorithm prev_encoding = ser.get_encoding_algorithm(); + eprosima::safedds::ReturnCode ret = ser.set_encoding_algorithm(eprosima::safedds::gen::EncodingAlgorithm::PLAIN_CDR2); + + ret = ((eprosima::safedds::ReturnCode::OK == ret) && (sample.route_id.size() <= 255)) ? ret : eprosima::safedds::ReturnCode::ERROR; + + + + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.begin_serialize_type() : ret; + + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type_key(0, sample.route_id) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type_key(1, sample.updates_count) : ret; + + + if(eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser.end_serialize_type(); + } + + if(eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser.set_encoding_algorithm(prev_encoding); + } + + return ret; + + } + + static bool compare( + const RouteMetric& first, + const RouteMetric& second) + { + using namespace safe_edge::pilot_server; + + bool ret = true; + + ret = ret && eprosima::safedds::gen::SafeDDSTypeSupportComparator::equal(first.route_id, second.route_id); + ret = ret && eprosima::safedds::gen::SafeDDSTypeSupportComparator::equal(first.updates_count, second.updates_count); + + return ret; + } + }; + + + struct RouteMetricTypeSupport : + public eprosima::safedds::dds::TypedTypeSupport + { + using DataType = RouteMetric; + + eprosima::safedds::dds::ReturnCode register_type( + eprosima::safedds::dds::DomainParticipant& participant, + const eprosima::safedds::memory::IStringView& type_name) noexcept override + { + return participant.register_type(*this, type_name); + } + + const eprosima::safedds::memory::IStringView& get_type_name() const noexcept override + { + static constexpr char const* default_name = "safe_edge::pilot_server::RouteMetric"; + static const eprosima::safedds::memory::container::StaticString256 typesupport_name(default_name); + return typesupport_name; + } + + uint32_t max_serialized_size() const noexcept override + { + return RouteMetricSerialization::max_serialized_size(); + } + + uint32_t serialized_size( + const RouteMetric& sample, + eprosima::safedds::serialization::cdr::XCDRVersion xcdr_version) const noexcept override + { + uint32_t sample_size = 0; + + if (eprosima::safedds::ReturnCode::OK == sample_serialized_size(sample, xcdr_version, sample_size)) + { + sample_size = eprosima::safedds::memory::align_to( + eprosima::safedds::portable::safe_sizeof() + + sample_size, 4); + } + + return sample_size; + } + + eprosima::safedds::ReturnCode serialize( + const RouteMetric& sample, + eprosima::safedds::memory::IByteArrayView& buffer, + eprosima::safedds::serialization::cdr::XCDRVersion xcdr_version) const noexcept override + { + eprosima::safedds::ReturnCode ret = + (eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 == xcdr_version) || (eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV2 == xcdr_version) ? + eprosima::safedds::ReturnCode::OK : eprosima::safedds::ReturnCode::ERROR; + + eprosima::safedds::serialization::RepresentationHeader representation_header{}; + + if (eprosima::safedds::ReturnCode::OK == ret) + { + if(eprosima::safedds::portable::MACHINE_ENDIANNESS == eprosima::safedds::platform::Endianness::SAFEDDS_BIG_ENDIAN) + { + representation_header = + eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 == xcdr_version ? + eprosima::safedds::serialization::REPRESENTATION_HEADER_CDR_BE : + eprosima::safedds::serialization::REPRESENTATION_HEADER_DELIMITED_CDR_BE; + } + else + { + representation_header = + eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 == xcdr_version ? + eprosima::safedds::serialization::REPRESENTATION_HEADER_CDR_LE : + eprosima::safedds::serialization::REPRESENTATION_HEADER_DELIMITED_CDR_LE; + } + } + + uint32_t sample_size = 0; + + if (eprosima::safedds::ReturnCode::OK == ret) + { + ret = sample_serialized_size(sample, xcdr_version, sample_size); + } + + uint32_t aligned_size = eprosima::safedds::memory::align_to(sample_size, 4); + uint32_t payload_size = eprosima::safedds::portable::safe_sizeof() + aligned_size; + + if (eprosima::safedds::ReturnCode::OK == ret && buffer.size() >= payload_size) + { + // Indicate the number of padding bytes in the encapsulation options + uint32_t required_padding = aligned_size - sample_size; + representation_header.encapsulation_options[1] = static_cast(required_padding); + + eprosima::safedds::gen::SafeDDSTypeSupportSerializer ser_rh(buffer, eprosima::safedds::portable::MACHINE_ENDIANNESS, xcdr_version); + ret = ser_rh.serialize_array( + representation_header.encapsulation_kind.data(), + eprosima::safedds::serialization::RepresentationHeader::ENCAPSULATION_KIND_SIZE); + + if (eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser_rh.serialize_array( + representation_header.encapsulation_options.data(), eprosima::safedds::serialization::RepresentationHeader::ENCAPSULATION_OPTIONS_SIZE); + } + + if (eprosima::safedds::ReturnCode::OK == ret && sample_size > 0) + { + eprosima::safedds::memory::byte_array::ByteArrayView payload_view = { + &buffer[ser_rh.serializer_used_size()], + ser_rh.serializer_remaining_size() + }; + + eprosima::safedds::gen::SafeDDSTypeSupportSerializer ser(payload_view, eprosima::safedds::portable::MACHINE_ENDIANNESS, xcdr_version); + + ret = RouteMetricSerialization::serialize(ser, sample); + + // Add padding + for (uint32_t i = 0; (eprosima::safedds::ReturnCode::OK == ret) && (i < required_padding); ++i) + { + ret = ser.serialize('\0'); + } + } + } + + return ret; + } + + eprosima::safedds::ReturnCode deserialize( + const eprosima::safedds::memory::IConstByteArrayView& buffer, + RouteMetric& sample) const noexcept override + { + eprosima::safedds::serialization::RepresentationHeader representation_header{}; + + eprosima::safedds::serialization::cdr::Deserializer deserializer_rh(buffer, eprosima::safedds::portable::MACHINE_ENDIANNESS, eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1); + eprosima::safedds::ReturnCode ret = eprosima::safedds::protocol::rtps::RTPSTypeSupport::deserialize(deserializer_rh, representation_header); + + // Check expected RepresentationHeader type to be valid and supported + const bool is_cdr_v1 = representation_header.encapsulation_kind[0U] == 0U && (representation_header.encapsulation_kind[1U] <= 0x03U); + const bool is_cdr_v2 = representation_header.encapsulation_kind[0U] == 0U && (representation_header.encapsulation_kind[1U] >= 0x06U && representation_header.encapsulation_kind[1U] <= 0x0BU); + ret = (eprosima::safedds::ReturnCode::OK == ret && (is_cdr_v1 || is_cdr_v2)) ? eprosima::safedds::ReturnCode::OK : eprosima::safedds::ReturnCode::ERROR; + + // Skip payload + eprosima::safedds::memory::byte_array::ByteArrayView payload_view = {nullptr, 0U}; + uint32_t remaining_size = deserializer_rh.deserializer_remaining_size(); + if (eprosima::safedds::ReturnCode::OK == ret && remaining_size > 0) + { + uint32_t padding_size = static_cast(representation_header.encapsulation_options[1] & 0x03); + if (remaining_size >= padding_size) + { + remaining_size -= padding_size; + ret = deserializer_rh.deserializer_skip(remaining_size, payload_view); + } + else + { + ret = eprosima::safedds::ReturnCode::SERIALIZATION_INVALID_REPRESENTATION; + } + } + + if (eprosima::safedds::ReturnCode::OK == ret && remaining_size > 0) + { + // Get received endianness and deserialize payload + eprosima::safedds::gen::SafeDDSTypeSupportDeserializer deserializer(payload_view, + representation_header.get_endianness(), + is_cdr_v1 ? eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 : eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV2); + + ret = RouteMetricSerialization::deserialize(deserializer, sample); + } + + return ret; + } + + eprosima::safedds::dds::ReturnCode get_key( + const RouteMetric& data, + eprosima::safedds::dds::KeyHash& key_hash) const noexcept override + { + key_hash = {}; + + static_cast(data); + + return eprosima::safedds::dds::ReturnCode::ILLEGAL_OPERATION; + } + + eprosima::safedds::dds::ReturnCode get_key_from_payload( + const eprosima::safedds::memory::IConstByteArrayView& view, + const eprosima::safedds::protocol::PayloadKind& kind, + eprosima::safedds::dds::KeyHash& key_hash) const noexcept override + { + key_hash = {}; + + static_cast(view); + static_cast(kind); + + return eprosima::safedds::dds::ReturnCode::ILLEGAL_OPERATION; + } + + bool has_keys() const noexcept override + { + return false; + } + + private: + + eprosima::safedds::ReturnCode sample_serialized_size( + const RouteMetric& sample, + eprosima::safedds::serialization::cdr::XCDRVersion xcdr_version, + uint32_t & serialized_size) const noexcept + { + serialized_size = 0; + + // Create a fake serializer to calculate the serialized size + eprosima::safedds::gen::SafeDDSTypeSupportSerializer ser(eprosima::safedds::portable::MACHINE_ENDIANNESS, xcdr_version); + eprosima::safedds::ReturnCode ret = RouteMetricSerialization::serialize(ser, sample); + + if(eprosima::safedds::ReturnCode::OK == ret) + { + serialized_size = ser.serializer_used_size(); + } + + return ret; + } + + }; + + + typedef std::vector RouteMetricSeq; + + + + // Forward declaration + struct TransitMetricsSerialization; + + /*! + * @brief This struct represents the structure TransitMetrics defined by the user in the IDL file. + * @ingroup pilot_server + */ + struct TransitMetrics + { + using SerializationStruct = TransitMetricsSerialization; + + static constexpr eprosima::safedds::gen::IDLExtensibilityKind IDL_EXTENSIBILITY = eprosima::safedds::gen::IDLExtensibilityKind::APPENDABLE; + + /// Member by_route + safe_edge::pilot_server::RouteMetricSeq by_route ; + /// Member vehicles_seen + int32_t vehicles_seen = 0; + + // Ensure bounds + static_assert(512 != 0, "by_route shall be bounded or --default_unbounded_max_size shall be used"); + + }; + + struct TransitMetricsSerialization + { + static constexpr uint32_t max_serialized_size() + { + // Return the precalculated max_serialized_size plus required: + // - Representation Header size (+4 B) since it is serialized in the typesupport serialization method + // - Alignment to 4 B since the serialization method adds padding + return eprosima::safedds::memory::align_to<137232ULL + 4ULL, 4U>(); + } + + static constexpr uint32_t max_key_serialized_size() + { + return 0ULL; + } + + static eprosima::safedds::ReturnCode serialize( + eprosima::safedds::gen::SafeDDSTypeSupportSerializer& ser, + const TransitMetrics& sample) + { + using namespace safe_edge::pilot_server; + + eprosima::safedds::gen::EncodingAlgorithm prev_encoding = ser.get_encoding_algorithm(); + eprosima::safedds::ReturnCode ret = ser.set_encoding_algorithm( + ser.get_xcdr_version() == eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 ? + eprosima::safedds::gen::EncodingAlgorithm::PLAIN_CDR : + eprosima::safedds::gen::EncodingAlgorithm::DELIMITED_CDR); + + ret = ((eprosima::safedds::ReturnCode::OK == ret) && (sample.by_route.size() <= 512)) ? ret : eprosima::safedds::ReturnCode::ERROR; + + + + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.begin_serialize_type() : ret; + + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type(0, sample.by_route) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type(1, sample.vehicles_seen) : ret; + + if(eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser.end_serialize_type(); + } + + if(eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser.set_encoding_algorithm(prev_encoding); + } + + return ret; + } + + static eprosima::safedds::ReturnCode deserialize( + eprosima::safedds::gen::SafeDDSTypeSupportDeserializer& deser, + TransitMetrics& sample) + { + using namespace safe_edge::pilot_server; + + // Store the values of the external members in auxiliary variables + + sample = {}; + + // Restore the values of the external members + + const eprosima::safedds::gen::EncodingAlgorithm encoding = + deser.get_xcdr_version() == eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 ? + eprosima::safedds::gen::EncodingAlgorithm::PLAIN_CDR : + eprosima::safedds::gen::EncodingAlgorithm::DELIMITED_CDR; + + return deser.deserialize_type(encoding, + [&sample](eprosima::safedds::gen::SafeDDSTypeSupportDeserializer& inner_deser, const uint32_t id) -> eprosima::safedds::ReturnCode + { + eprosima::safedds::ReturnCode ret_value = eprosima::safedds::ReturnCode::OK; + switch (id) + { + case 0: + ret_value = inner_deser.deserialize_member(sample.by_route); + break; + + case 1: + ret_value = inner_deser.deserialize_member(sample.vehicles_seen); + break; + + default: + ret_value = eprosima::safedds::ReturnCode::UNIMPLEMENTED; + break; + } + return ret_value; + }); + } + + static eprosima::safedds::ReturnCode serialize_key( + eprosima::safedds::gen::SafeDDSTypeSupportSerializer& ser, + const TransitMetrics& sample) + { + using namespace safe_edge::pilot_server; + + + eprosima::safedds::gen::EncodingAlgorithm prev_encoding = ser.get_encoding_algorithm(); + eprosima::safedds::ReturnCode ret = ser.set_encoding_algorithm(eprosima::safedds::gen::EncodingAlgorithm::PLAIN_CDR2); + + ret = ((eprosima::safedds::ReturnCode::OK == ret) && (sample.by_route.size() <= 512)) ? ret : eprosima::safedds::ReturnCode::ERROR; + + + + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.begin_serialize_type() : ret; + + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type_key(0, sample.by_route) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type_key(1, sample.vehicles_seen) : ret; + + + if(eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser.end_serialize_type(); + } + + if(eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser.set_encoding_algorithm(prev_encoding); + } + + return ret; + + } + + static bool compare( + const TransitMetrics& first, + const TransitMetrics& second) + { + using namespace safe_edge::pilot_server; + + bool ret = true; + + ret = ret && eprosima::safedds::gen::SafeDDSTypeSupportComparator::equal(first.by_route, second.by_route); + ret = ret && eprosima::safedds::gen::SafeDDSTypeSupportComparator::equal(first.vehicles_seen, second.vehicles_seen); + + return ret; + } + }; + + + struct TransitMetricsTypeSupport : + public eprosima::safedds::dds::TypedTypeSupport + { + using DataType = TransitMetrics; + + eprosima::safedds::dds::ReturnCode register_type( + eprosima::safedds::dds::DomainParticipant& participant, + const eprosima::safedds::memory::IStringView& type_name) noexcept override + { + return participant.register_type(*this, type_name); + } + + const eprosima::safedds::memory::IStringView& get_type_name() const noexcept override + { + static constexpr char const* default_name = "safe_edge::pilot_server::TransitMetrics"; + static const eprosima::safedds::memory::container::StaticString256 typesupport_name(default_name); + return typesupport_name; + } + + uint32_t max_serialized_size() const noexcept override + { + return TransitMetricsSerialization::max_serialized_size(); + } + + uint32_t serialized_size( + const TransitMetrics& sample, + eprosima::safedds::serialization::cdr::XCDRVersion xcdr_version) const noexcept override + { + uint32_t sample_size = 0; + + if (eprosima::safedds::ReturnCode::OK == sample_serialized_size(sample, xcdr_version, sample_size)) + { + sample_size = eprosima::safedds::memory::align_to( + eprosima::safedds::portable::safe_sizeof() + + sample_size, 4); + } + + return sample_size; + } + + eprosima::safedds::ReturnCode serialize( + const TransitMetrics& sample, + eprosima::safedds::memory::IByteArrayView& buffer, + eprosima::safedds::serialization::cdr::XCDRVersion xcdr_version) const noexcept override + { + eprosima::safedds::ReturnCode ret = + (eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 == xcdr_version) || (eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV2 == xcdr_version) ? + eprosima::safedds::ReturnCode::OK : eprosima::safedds::ReturnCode::ERROR; + + eprosima::safedds::serialization::RepresentationHeader representation_header{}; + + if (eprosima::safedds::ReturnCode::OK == ret) + { + if(eprosima::safedds::portable::MACHINE_ENDIANNESS == eprosima::safedds::platform::Endianness::SAFEDDS_BIG_ENDIAN) + { + representation_header = + eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 == xcdr_version ? + eprosima::safedds::serialization::REPRESENTATION_HEADER_CDR_BE : + eprosima::safedds::serialization::REPRESENTATION_HEADER_DELIMITED_CDR_BE; + } + else + { + representation_header = + eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 == xcdr_version ? + eprosima::safedds::serialization::REPRESENTATION_HEADER_CDR_LE : + eprosima::safedds::serialization::REPRESENTATION_HEADER_DELIMITED_CDR_LE; + } + } + + uint32_t sample_size = 0; + + if (eprosima::safedds::ReturnCode::OK == ret) + { + ret = sample_serialized_size(sample, xcdr_version, sample_size); + } + + uint32_t aligned_size = eprosima::safedds::memory::align_to(sample_size, 4); + uint32_t payload_size = eprosima::safedds::portable::safe_sizeof() + aligned_size; + + if (eprosima::safedds::ReturnCode::OK == ret && buffer.size() >= payload_size) + { + // Indicate the number of padding bytes in the encapsulation options + uint32_t required_padding = aligned_size - sample_size; + representation_header.encapsulation_options[1] = static_cast(required_padding); + + eprosima::safedds::gen::SafeDDSTypeSupportSerializer ser_rh(buffer, eprosima::safedds::portable::MACHINE_ENDIANNESS, xcdr_version); + ret = ser_rh.serialize_array( + representation_header.encapsulation_kind.data(), + eprosima::safedds::serialization::RepresentationHeader::ENCAPSULATION_KIND_SIZE); + + if (eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser_rh.serialize_array( + representation_header.encapsulation_options.data(), eprosima::safedds::serialization::RepresentationHeader::ENCAPSULATION_OPTIONS_SIZE); + } + + if (eprosima::safedds::ReturnCode::OK == ret && sample_size > 0) + { + eprosima::safedds::memory::byte_array::ByteArrayView payload_view = { + &buffer[ser_rh.serializer_used_size()], + ser_rh.serializer_remaining_size() + }; + + eprosima::safedds::gen::SafeDDSTypeSupportSerializer ser(payload_view, eprosima::safedds::portable::MACHINE_ENDIANNESS, xcdr_version); + + ret = TransitMetricsSerialization::serialize(ser, sample); + + // Add padding + for (uint32_t i = 0; (eprosima::safedds::ReturnCode::OK == ret) && (i < required_padding); ++i) + { + ret = ser.serialize('\0'); + } + } + } + + return ret; + } + + eprosima::safedds::ReturnCode deserialize( + const eprosima::safedds::memory::IConstByteArrayView& buffer, + TransitMetrics& sample) const noexcept override + { + eprosima::safedds::serialization::RepresentationHeader representation_header{}; + + eprosima::safedds::serialization::cdr::Deserializer deserializer_rh(buffer, eprosima::safedds::portable::MACHINE_ENDIANNESS, eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1); + eprosima::safedds::ReturnCode ret = eprosima::safedds::protocol::rtps::RTPSTypeSupport::deserialize(deserializer_rh, representation_header); + + // Check expected RepresentationHeader type to be valid and supported + const bool is_cdr_v1 = representation_header.encapsulation_kind[0U] == 0U && (representation_header.encapsulation_kind[1U] <= 0x03U); + const bool is_cdr_v2 = representation_header.encapsulation_kind[0U] == 0U && (representation_header.encapsulation_kind[1U] >= 0x06U && representation_header.encapsulation_kind[1U] <= 0x0BU); + ret = (eprosima::safedds::ReturnCode::OK == ret && (is_cdr_v1 || is_cdr_v2)) ? eprosima::safedds::ReturnCode::OK : eprosima::safedds::ReturnCode::ERROR; + + // Skip payload + eprosima::safedds::memory::byte_array::ByteArrayView payload_view = {nullptr, 0U}; + uint32_t remaining_size = deserializer_rh.deserializer_remaining_size(); + if (eprosima::safedds::ReturnCode::OK == ret && remaining_size > 0) + { + uint32_t padding_size = static_cast(representation_header.encapsulation_options[1] & 0x03); + if (remaining_size >= padding_size) + { + remaining_size -= padding_size; + ret = deserializer_rh.deserializer_skip(remaining_size, payload_view); + } + else + { + ret = eprosima::safedds::ReturnCode::SERIALIZATION_INVALID_REPRESENTATION; + } + } + + if (eprosima::safedds::ReturnCode::OK == ret && remaining_size > 0) + { + // Get received endianness and deserialize payload + eprosima::safedds::gen::SafeDDSTypeSupportDeserializer deserializer(payload_view, + representation_header.get_endianness(), + is_cdr_v1 ? eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 : eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV2); + + ret = TransitMetricsSerialization::deserialize(deserializer, sample); + } + + return ret; + } + + eprosima::safedds::dds::ReturnCode get_key( + const TransitMetrics& data, + eprosima::safedds::dds::KeyHash& key_hash) const noexcept override + { + key_hash = {}; + + static_cast(data); + + return eprosima::safedds::dds::ReturnCode::ILLEGAL_OPERATION; + } + + eprosima::safedds::dds::ReturnCode get_key_from_payload( + const eprosima::safedds::memory::IConstByteArrayView& view, + const eprosima::safedds::protocol::PayloadKind& kind, + eprosima::safedds::dds::KeyHash& key_hash) const noexcept override + { + key_hash = {}; + + static_cast(view); + static_cast(kind); + + return eprosima::safedds::dds::ReturnCode::ILLEGAL_OPERATION; + } + + bool has_keys() const noexcept override + { + return false; + } + + private: + + eprosima::safedds::ReturnCode sample_serialized_size( + const TransitMetrics& sample, + eprosima::safedds::serialization::cdr::XCDRVersion xcdr_version, + uint32_t & serialized_size) const noexcept + { + serialized_size = 0; + + // Create a fake serializer to calculate the serialized size + eprosima::safedds::gen::SafeDDSTypeSupportSerializer ser(eprosima::safedds::portable::MACHINE_ENDIANNESS, xcdr_version); + eprosima::safedds::ReturnCode ret = TransitMetricsSerialization::serialize(ser, sample); + + if(eprosima::safedds::ReturnCode::OK == ret) + { + serialized_size = ser.serializer_used_size(); + } + + return ret; + } + + }; + + + enum class RequestedDataType : int32_t + { + CHARGER_LOCATION , + CHARGER_TYPE , + CHARGING_SESSION , + TRANSIT_HEALTH , + TRANSIT_METRICS + }; + + + // Forward declaration + struct ServerQuerySerialization; + + /*! + * @brief This struct represents the structure ServerQuery defined by the user in the IDL file. + * @ingroup pilot_server + */ + struct ServerQuery + { + using SerializationStruct = ServerQuerySerialization; + + static constexpr eprosima::safedds::gen::IDLExtensibilityKind IDL_EXTENSIBILITY = eprosima::safedds::gen::IDLExtensibilityKind::APPENDABLE; + + /// Member requested_by + std::string requested_by ; + /// Member requested_data_type + safe_edge::pilot_server::RequestedDataType requested_data_type = safe_edge::pilot_server::RequestedDataType::CHARGER_LOCATION; + + // Ensure bounds + static_assert(255 != 0, "requested_by shall be bounded or --default_unbounded_max_size shall be used"); + + }; + + struct ServerQuerySerialization + { + static constexpr uint32_t max_serialized_size() + { + // Return the precalculated max_serialized_size plus required: + // - Representation Header size (+4 B) since it is serialized in the typesupport serialization method + // - Alignment to 4 B since the serialization method adds padding + return eprosima::safedds::memory::align_to<268ULL + 4ULL, 4U>(); + } + + static constexpr uint32_t max_key_serialized_size() + { + return 0ULL; + } + + static eprosima::safedds::ReturnCode serialize( + eprosima::safedds::gen::SafeDDSTypeSupportSerializer& ser, + const ServerQuery& sample) + { + using namespace safe_edge::pilot_server; + + eprosima::safedds::gen::EncodingAlgorithm prev_encoding = ser.get_encoding_algorithm(); + eprosima::safedds::ReturnCode ret = ser.set_encoding_algorithm( + ser.get_xcdr_version() == eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 ? + eprosima::safedds::gen::EncodingAlgorithm::PLAIN_CDR : + eprosima::safedds::gen::EncodingAlgorithm::DELIMITED_CDR); + + ret = ((eprosima::safedds::ReturnCode::OK == ret) && (sample.requested_by.size() <= 255)) ? ret : eprosima::safedds::ReturnCode::ERROR; + + + + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.begin_serialize_type() : ret; + + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type(0, sample.requested_by) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type(1, sample.requested_data_type) : ret; + + if(eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser.end_serialize_type(); + } + + if(eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser.set_encoding_algorithm(prev_encoding); + } + + return ret; + } + + static eprosima::safedds::ReturnCode deserialize( + eprosima::safedds::gen::SafeDDSTypeSupportDeserializer& deser, + ServerQuery& sample) + { + using namespace safe_edge::pilot_server; + + // Store the values of the external members in auxiliary variables + + sample = {}; + + // Restore the values of the external members + + const eprosima::safedds::gen::EncodingAlgorithm encoding = + deser.get_xcdr_version() == eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 ? + eprosima::safedds::gen::EncodingAlgorithm::PLAIN_CDR : + eprosima::safedds::gen::EncodingAlgorithm::DELIMITED_CDR; + + return deser.deserialize_type(encoding, + [&sample](eprosima::safedds::gen::SafeDDSTypeSupportDeserializer& inner_deser, const uint32_t id) -> eprosima::safedds::ReturnCode + { + eprosima::safedds::ReturnCode ret_value = eprosima::safedds::ReturnCode::OK; + switch (id) + { + case 0: + ret_value = inner_deser.deserialize_member(sample.requested_by); + break; + + case 1: + ret_value = inner_deser.deserialize_member(sample.requested_data_type); + break; + + default: + ret_value = eprosima::safedds::ReturnCode::UNIMPLEMENTED; + break; + } + return ret_value; + }); + } + + static eprosima::safedds::ReturnCode serialize_key( + eprosima::safedds::gen::SafeDDSTypeSupportSerializer& ser, + const ServerQuery& sample) + { + using namespace safe_edge::pilot_server; + + + eprosima::safedds::gen::EncodingAlgorithm prev_encoding = ser.get_encoding_algorithm(); + eprosima::safedds::ReturnCode ret = ser.set_encoding_algorithm(eprosima::safedds::gen::EncodingAlgorithm::PLAIN_CDR2); + + ret = ((eprosima::safedds::ReturnCode::OK == ret) && (sample.requested_by.size() <= 255)) ? ret : eprosima::safedds::ReturnCode::ERROR; + + + + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.begin_serialize_type() : ret; + + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type_key(0, sample.requested_by) : ret; + ret = (eprosima::safedds::ReturnCode::OK == ret) ? ser.serialize_type_key(1, sample.requested_data_type) : ret; + + + if(eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser.end_serialize_type(); + } + + if(eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser.set_encoding_algorithm(prev_encoding); + } + + return ret; + + } + + static bool compare( + const ServerQuery& first, + const ServerQuery& second) + { + using namespace safe_edge::pilot_server; + + bool ret = true; + + ret = ret && eprosima::safedds::gen::SafeDDSTypeSupportComparator::equal(first.requested_by, second.requested_by); + ret = ret && eprosima::safedds::gen::SafeDDSTypeSupportComparator::equal(first.requested_data_type, second.requested_data_type); + + return ret; + } + }; + + + struct ServerQueryTypeSupport : + public eprosima::safedds::dds::TypedTypeSupport + { + using DataType = ServerQuery; + + eprosima::safedds::dds::ReturnCode register_type( + eprosima::safedds::dds::DomainParticipant& participant, + const eprosima::safedds::memory::IStringView& type_name) noexcept override + { + return participant.register_type(*this, type_name); + } + + const eprosima::safedds::memory::IStringView& get_type_name() const noexcept override + { + static constexpr char const* default_name = "safe_edge::pilot_server::ServerQuery"; + static const eprosima::safedds::memory::container::StaticString256 typesupport_name(default_name); + return typesupport_name; + } + + uint32_t max_serialized_size() const noexcept override + { + return ServerQuerySerialization::max_serialized_size(); + } + + uint32_t serialized_size( + const ServerQuery& sample, + eprosima::safedds::serialization::cdr::XCDRVersion xcdr_version) const noexcept override + { + uint32_t sample_size = 0; + + if (eprosima::safedds::ReturnCode::OK == sample_serialized_size(sample, xcdr_version, sample_size)) + { + sample_size = eprosima::safedds::memory::align_to( + eprosima::safedds::portable::safe_sizeof() + + sample_size, 4); + } + + return sample_size; + } + + eprosima::safedds::ReturnCode serialize( + const ServerQuery& sample, + eprosima::safedds::memory::IByteArrayView& buffer, + eprosima::safedds::serialization::cdr::XCDRVersion xcdr_version) const noexcept override + { + eprosima::safedds::ReturnCode ret = + (eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 == xcdr_version) || (eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV2 == xcdr_version) ? + eprosima::safedds::ReturnCode::OK : eprosima::safedds::ReturnCode::ERROR; + + eprosima::safedds::serialization::RepresentationHeader representation_header{}; + + if (eprosima::safedds::ReturnCode::OK == ret) + { + if(eprosima::safedds::portable::MACHINE_ENDIANNESS == eprosima::safedds::platform::Endianness::SAFEDDS_BIG_ENDIAN) + { + representation_header = + eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 == xcdr_version ? + eprosima::safedds::serialization::REPRESENTATION_HEADER_CDR_BE : + eprosima::safedds::serialization::REPRESENTATION_HEADER_DELIMITED_CDR_BE; + } + else + { + representation_header = + eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 == xcdr_version ? + eprosima::safedds::serialization::REPRESENTATION_HEADER_CDR_LE : + eprosima::safedds::serialization::REPRESENTATION_HEADER_DELIMITED_CDR_LE; + } + } + + uint32_t sample_size = 0; + + if (eprosima::safedds::ReturnCode::OK == ret) + { + ret = sample_serialized_size(sample, xcdr_version, sample_size); + } + + uint32_t aligned_size = eprosima::safedds::memory::align_to(sample_size, 4); + uint32_t payload_size = eprosima::safedds::portable::safe_sizeof() + aligned_size; + + if (eprosima::safedds::ReturnCode::OK == ret && buffer.size() >= payload_size) + { + // Indicate the number of padding bytes in the encapsulation options + uint32_t required_padding = aligned_size - sample_size; + representation_header.encapsulation_options[1] = static_cast(required_padding); + + eprosima::safedds::gen::SafeDDSTypeSupportSerializer ser_rh(buffer, eprosima::safedds::portable::MACHINE_ENDIANNESS, xcdr_version); + ret = ser_rh.serialize_array( + representation_header.encapsulation_kind.data(), + eprosima::safedds::serialization::RepresentationHeader::ENCAPSULATION_KIND_SIZE); + + if (eprosima::safedds::ReturnCode::OK == ret) + { + ret = ser_rh.serialize_array( + representation_header.encapsulation_options.data(), eprosima::safedds::serialization::RepresentationHeader::ENCAPSULATION_OPTIONS_SIZE); + } + + if (eprosima::safedds::ReturnCode::OK == ret && sample_size > 0) + { + eprosima::safedds::memory::byte_array::ByteArrayView payload_view = { + &buffer[ser_rh.serializer_used_size()], + ser_rh.serializer_remaining_size() + }; + + eprosima::safedds::gen::SafeDDSTypeSupportSerializer ser(payload_view, eprosima::safedds::portable::MACHINE_ENDIANNESS, xcdr_version); + + ret = ServerQuerySerialization::serialize(ser, sample); + + // Add padding + for (uint32_t i = 0; (eprosima::safedds::ReturnCode::OK == ret) && (i < required_padding); ++i) + { + ret = ser.serialize('\0'); + } + } + } + + return ret; + } + + eprosima::safedds::ReturnCode deserialize( + const eprosima::safedds::memory::IConstByteArrayView& buffer, + ServerQuery& sample) const noexcept override + { + eprosima::safedds::serialization::RepresentationHeader representation_header{}; + + eprosima::safedds::serialization::cdr::Deserializer deserializer_rh(buffer, eprosima::safedds::portable::MACHINE_ENDIANNESS, eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1); + eprosima::safedds::ReturnCode ret = eprosima::safedds::protocol::rtps::RTPSTypeSupport::deserialize(deserializer_rh, representation_header); + + // Check expected RepresentationHeader type to be valid and supported + const bool is_cdr_v1 = representation_header.encapsulation_kind[0U] == 0U && (representation_header.encapsulation_kind[1U] <= 0x03U); + const bool is_cdr_v2 = representation_header.encapsulation_kind[0U] == 0U && (representation_header.encapsulation_kind[1U] >= 0x06U && representation_header.encapsulation_kind[1U] <= 0x0BU); + ret = (eprosima::safedds::ReturnCode::OK == ret && (is_cdr_v1 || is_cdr_v2)) ? eprosima::safedds::ReturnCode::OK : eprosima::safedds::ReturnCode::ERROR; + + // Skip payload + eprosima::safedds::memory::byte_array::ByteArrayView payload_view = {nullptr, 0U}; + uint32_t remaining_size = deserializer_rh.deserializer_remaining_size(); + if (eprosima::safedds::ReturnCode::OK == ret && remaining_size > 0) + { + uint32_t padding_size = static_cast(representation_header.encapsulation_options[1] & 0x03); + if (remaining_size >= padding_size) + { + remaining_size -= padding_size; + ret = deserializer_rh.deserializer_skip(remaining_size, payload_view); + } + else + { + ret = eprosima::safedds::ReturnCode::SERIALIZATION_INVALID_REPRESENTATION; + } + } + + if (eprosima::safedds::ReturnCode::OK == ret && remaining_size > 0) + { + // Get received endianness and deserialize payload + eprosima::safedds::gen::SafeDDSTypeSupportDeserializer deserializer(payload_view, + representation_header.get_endianness(), + is_cdr_v1 ? eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV1 : eprosima::safedds::serialization::cdr::XCDRVersion::XCDRV2); + + ret = ServerQuerySerialization::deserialize(deserializer, sample); + } + + return ret; + } + + eprosima::safedds::dds::ReturnCode get_key( + const ServerQuery& data, + eprosima::safedds::dds::KeyHash& key_hash) const noexcept override + { + key_hash = {}; + + static_cast(data); + + return eprosima::safedds::dds::ReturnCode::ILLEGAL_OPERATION; + } + + eprosima::safedds::dds::ReturnCode get_key_from_payload( + const eprosima::safedds::memory::IConstByteArrayView& view, + const eprosima::safedds::protocol::PayloadKind& kind, + eprosima::safedds::dds::KeyHash& key_hash) const noexcept override + { + key_hash = {}; + + static_cast(view); + static_cast(kind); + + return eprosima::safedds::dds::ReturnCode::ILLEGAL_OPERATION; + } + + bool has_keys() const noexcept override + { + return false; + } + + private: + + eprosima::safedds::ReturnCode sample_serialized_size( + const ServerQuery& sample, + eprosima::safedds::serialization::cdr::XCDRVersion xcdr_version, + uint32_t & serialized_size) const noexcept + { + serialized_size = 0; + + // Create a fake serializer to calculate the serialized size + eprosima::safedds::gen::SafeDDSTypeSupportSerializer ser(eprosima::safedds::portable::MACHINE_ENDIANNESS, xcdr_version); + eprosima::safedds::ReturnCode ret = ServerQuerySerialization::serialize(ser, sample); + + if(eprosima::safedds::ReturnCode::OK == ret) + { + serialized_size = ser.serializer_used_size(); + } + + return ret; + } + + }; + + + } // namespace pilot_server +} // namespace safe_edge + +#endif // SAFEDDS_GENERATED__SAFE_EDGE_PILOT_SERVER_PILOT_SERVER_HPP \ No newline at end of file diff --git a/safe_dds/server/CMakeLists.txt b/safe_dds/server/CMakeLists.txt new file mode 100644 index 0000000..81bad19 --- /dev/null +++ b/safe_dds/server/CMakeLists.txt @@ -0,0 +1,149 @@ +cmake_minimum_required(VERSION 3.16) + +project(safe_edge_server LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +find_package(safedds REQUIRED) +find_package(CURL REQUIRED) + +if(CMAKE_SYSTEM_NAME STREQUAL "QNX") + set(SAFE_EDGE_PLATFORM_SOCKET_LIB socket) +endif() + +set(SAFE_EDGE_SERVER_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include") +set(SAFE_EDGE_IDL_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../idl") +set(SAFE_EDGE_SERVER_COMMON_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../common_server") + +function(safe_edge_apply_common_build_settings target_name) + target_include_directories( + "${target_name}" + PUBLIC + "${SAFE_EDGE_SERVER_INCLUDE_DIR}" + ) + + target_compile_options( + "${target_name}" + PRIVATE + -fno-exceptions + -fno-rtti + -Wall + -Werror + -Wextra + -Wpedantic + ) +endfunction() + +add_library( + safe_edge_server_common + STATIC + ${SAFE_EDGE_SERVER_COMMON_DIR}/src/PilotServerClient.cpp + ${SAFE_EDGE_SERVER_COMMON_DIR}/src/PilotServerPayloadParser.cpp + src/common/PilotServerPublishHelper.cpp + src/common/RuntimeConfig.cpp + src/common/TopicNames.cpp +) +safe_edge_apply_common_build_settings(safe_edge_server_common) +target_include_directories( + safe_edge_server_common + PUBLIC + "${SAFE_EDGE_IDL_INCLUDE_DIR}" + "${SAFE_EDGE_SERVER_COMMON_DIR}/include" +) +target_link_libraries( + safe_edge_server_common + PUBLIC + safedds + CURL::libcurl +) + +add_executable( + safe_edge_server + src/apps/server_main.cpp + src/nodes/ServerNode.cpp +) +safe_edge_apply_common_build_settings(safe_edge_server) +target_include_directories( + safe_edge_server + PRIVATE + "${SAFE_EDGE_IDL_INCLUDE_DIR}" +) +target_link_libraries( + safe_edge_server + PRIVATE + safe_edge_server_common + safedds + ${SAFE_EDGE_PLATFORM_SOCKET_LIB} +) + +install( + TARGETS + safe_edge_server + RUNTIME DESTINATION bin +) + +# --------------------------------------------------------------------------- +# Tests +# --------------------------------------------------------------------------- +option(SAFE_EDGE_BUILD_TESTS "Build integration tests" ON) + +if(SAFE_EDGE_BUILD_TESTS) + # Try system GTest first; fall back to fetching from source. + find_package(GTest QUIET) + + if(NOT GTest_FOUND) + message(STATUS "GTest not found — fetching from source") + include(FetchContent) + FetchContent_Declare( + googletest + URL https://github.com/google/googletest/archive/refs/tags/v1.14.0.tar.gz + URL_HASH SHA256=8ad598c73ad796e0d8280b082cebd82a630d73e73cd3c70057938a6501bba5d7 + DOWNLOAD_EXTRACT_TIMESTAMP TRUE + ) + # Do not install GTest alongside the project + set(INSTALL_GTEST OFF CACHE BOOL "" FORCE) + FetchContent_MakeAvailable(googletest) + + # Alias to the same target name used when found via find_package + if(NOT TARGET GTest::gtest) + add_library(GTest::gtest ALIAS gtest) + endif() + endif() + + add_executable( + test_server_integration + test/test_server_integration.cpp + ) + + # Tests need exceptions and RTTI (GTest requirement). + # Do not reuse safe_edge_apply_common_build_settings which disables them. + target_include_directories( + test_server_integration + PRIVATE + "${SAFE_EDGE_SERVER_INCLUDE_DIR}" + "${SAFE_EDGE_IDL_INCLUDE_DIR}" + ) + target_compile_options( + test_server_integration + PRIVATE + -Wall -Wextra -Wpedantic + ) + target_link_libraries( + test_server_integration + PRIVATE + safe_edge_server_common + safedds + ${SAFE_EDGE_PLATFORM_SOCKET_LIB} + GTest::gtest + ) + + enable_testing() + add_test(NAME server_integration COMMAND test_server_integration) + + install( + TARGETS test_server_integration + RUNTIME DESTINATION bin + ) +endif() diff --git a/safe_dds/server/include/safe_edge/server/common/PilotServerPublishHelper.hpp b/safe_dds/server/include/safe_edge/server/common/PilotServerPublishHelper.hpp new file mode 100644 index 0000000..c5c288d --- /dev/null +++ b/safe_dds/server/include/safe_edge/server/common/PilotServerPublishHelper.hpp @@ -0,0 +1,28 @@ +#ifndef SAFE_EDGE_SERVER_COMMON_PILOTSERVERPUBLISHHELPER_HPP +#define SAFE_EDGE_SERVER_COMMON_PILOTSERVERPUBLISHHELPER_HPP + +#include + +#include + +#include + +#include + +namespace safe_edge { +namespace server { +namespace common { + +struct PilotServerPublishHelper +{ + static void publish_charger_locations( + eprosima::safedds::dds::TypedDataWriter< + safe_edge::pilot_server::ChargerLocationTypeSupport>& writer, + const std::vector& parsed); +}; + +} // namespace common +} // namespace server +} // namespace safe_edge + +#endif // SAFE_EDGE_SERVER_COMMON_PILOTSERVERPUBLISHHELPER_HPP diff --git a/safe_dds/server/include/safe_edge/server/common/RuntimeConfig.hpp b/safe_dds/server/include/safe_edge/server/common/RuntimeConfig.hpp new file mode 100644 index 0000000..c7577c4 --- /dev/null +++ b/safe_dds/server/include/safe_edge/server/common/RuntimeConfig.hpp @@ -0,0 +1,32 @@ +#ifndef SAFE_EDGE_SERVER_COMMON_RUNTIMECONFIG_HPP +#define SAFE_EDGE_SERVER_COMMON_RUNTIMECONFIG_HPP + +#include +#include + +namespace safe_edge { +namespace server { +namespace common { + +struct RuntimeConfig +{ + std::string participant_name; + uint32_t domain_id = 0U; + uint16_t participant_port = 0U; + + std::string pilot_server_base_url; + std::string pilot_server_api_key; + std::string charger_locations_endpoint; + std::string charger_types_endpoint; + std::string charging_sessions_endpoint; + std::string transit_health_endpoint; + std::string transit_metrics_endpoint; +}; + +RuntimeConfig make_server_runtime_config(); + +} // namespace common +} // namespace server +} // namespace safe_edge + +#endif // SAFE_EDGE_SERVER_COMMON_RUNTIMECONFIG_HPP diff --git a/safe_dds/server/include/safe_edge/server/common/TopicNames.hpp b/safe_dds/server/include/safe_edge/server/common/TopicNames.hpp new file mode 100644 index 0000000..6838cf5 --- /dev/null +++ b/safe_dds/server/include/safe_edge/server/common/TopicNames.hpp @@ -0,0 +1,18 @@ +#ifndef SAFE_EDGE_SERVER_COMMON_TOPICNAMES_HPP +#define SAFE_EDGE_SERVER_COMMON_TOPICNAMES_HPP + +namespace safe_edge { +namespace server { +namespace common { +namespace topic_names { + +const char* charger_locations() noexcept; +const char* server_query() noexcept; +const char* service_heartbeat() noexcept; + +} // namespace topic_names +} // namespace common +} // namespace server +} // namespace safe_edge + +#endif // SAFE_EDGE_SERVER_COMMON_TOPICNAMES_HPP diff --git a/safe_dds/server/include/safe_edge/server/nodes/ServerNode.hpp b/safe_dds/server/include/safe_edge/server/nodes/ServerNode.hpp new file mode 100644 index 0000000..4ef534d --- /dev/null +++ b/safe_dds/server/include/safe_edge/server/nodes/ServerNode.hpp @@ -0,0 +1,149 @@ +#ifndef SAFE_EDGE_SERVER_NODES_SERVERNODE_HPP +#define SAFE_EDGE_SERVER_NODES_SERVERNODE_HPP + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace safe_edge { +namespace server { +namespace nodes { + +class ServerNode +{ +public: + + explicit ServerNode(const common::RuntimeConfig& runtime_config); + + int run(); + +private: + + class ParticipantListener : + public eprosima::safedds::dds::DomainParticipantListener + { + public: + + explicit ParticipantListener(ServerNode& owner); + + void on_subscription_matched( + eprosima::safedds::dds::DataReader& reader, + const eprosima::safedds::dds::SubscriptionMatchedStatus& info) noexcept override; + + void on_publication_matched( + eprosima::safedds::dds::DataWriter& writer, + const eprosima::safedds::dds::PublicationMatchedStatus& info) noexcept override; + + private: + + ServerNode& owner_; + }; + + class ServerQueryListener : + public eprosima::safedds::dds::DataReaderListener + { + public: + + explicit ServerQueryListener(ServerNode& owner); + + void on_data_available( + eprosima::safedds::dds::DataReader& reader) noexcept override; + + private: + + ServerNode& owner_; + }; + + bool initialize(); + bool create_participant(); + bool register_types(); + bool create_topics(); + bool create_endpoints(); + bool enable_entities(); + bool create_executor(); + + void on_server_query_received(const safe_edge::pilot_server::ServerQuery& query); + void publish_heartbeat(); + + void request_pilot_server_data(safe_edge::pilot_server::RequestedDataType resource) noexcept; + void periodic_refresh_all_resources() noexcept; + const char* resolve_endpoint(safe_edge::pilot_server::RequestedDataType resource) const noexcept; + void log_uptime() const noexcept; + + void log_subscription_match(const char* topic_name, int32_t total_count) const; + void log_publication_match(const char* topic_name, int32_t total_count) const; + eprosima::safedds::execution::TimePoint next_wakeup_time() const noexcept; + + eprosima::safedds::dds::DomainParticipantFactory factory_; + common::RuntimeConfig runtime_config_; + common::PilotServerClient pilot_client_; + + ParticipantListener participant_listener_; + ServerQueryListener server_query_listener_; + + eprosima::safedds::execution::Timer heartbeat_timer_; + eprosima::safedds::execution::Timer refresh_timer_; + eprosima::safedds::execution::Timer uptime_timer_; + std::chrono::steady_clock::time_point start_time_; + + eprosima::safedds::dds::DomainParticipant* participant_ = nullptr; + eprosima::safedds::dds::Publisher* publisher_ = nullptr; + eprosima::safedds::dds::Subscriber* subscriber_ = nullptr; + eprosima::safedds::execution::ISpinnable* executor_ = nullptr; + + eprosima::safedds::dds::Topic* charger_locations_topic_ = nullptr; + eprosima::safedds::dds::Topic* server_query_topic_ = nullptr; + eprosima::safedds::dds::Topic* service_heartbeat_topic_ = nullptr; + + eprosima::safedds::memory::container::StaticString256 charger_locations_topic_name_; + eprosima::safedds::memory::container::StaticString256 server_query_topic_name_; + eprosima::safedds::memory::container::StaticString256 service_heartbeat_topic_name_; + + eprosima::safedds::dds::DataWriter* charger_locations_datawriter_ = nullptr; + eprosima::safedds::dds::DataWriter* service_heartbeat_datawriter_ = nullptr; + + eprosima::safedds::dds::DataReader* server_query_datareader_ = nullptr; + + void configure_participant_qos( + eprosima::safedds::dds::DomainParticipantQos& qos) noexcept; + +protected: + + safe_edge::pilot_server::ServerQueryTypeSupport server_query_type_support_; + + eprosima::safedds::dds::TypedDataReader* server_query_reader_ = nullptr; + + safe_edge::pilot_server::ChargerLocationTypeSupport charger_locations_type_support_; + + eprosima::safedds::dds::TypedDataWriter* charger_locations_writer_ = nullptr; + + safe_edge::common::ServiceHeartbeatTypeSupport service_heartbeat_type_support_; + + eprosima::safedds::dds::TypedDataWriter* service_heartbeat_writer_ = nullptr; +}; + +} // namespace nodes +} // namespace server +} // namespace safe_edge + +#endif // SAFE_EDGE_SERVER_NODES_SERVERNODE_HPP diff --git a/safe_dds/server/src/apps/server_main.cpp b/safe_dds/server/src/apps/server_main.cpp new file mode 100644 index 0000000..b8fa6db --- /dev/null +++ b/safe_dds/server/src/apps/server_main.cpp @@ -0,0 +1,11 @@ +#include +#include + +int main() +{ + const safe_edge::server::common::RuntimeConfig config = + safe_edge::server::common::make_server_runtime_config(); + + safe_edge::server::nodes::ServerNode node(config); + return node.run(); +} diff --git a/safe_dds/server/src/common/PilotServerPublishHelper.cpp b/safe_dds/server/src/common/PilotServerPublishHelper.cpp new file mode 100644 index 0000000..8d05cd8 --- /dev/null +++ b/safe_dds/server/src/common/PilotServerPublishHelper.cpp @@ -0,0 +1,35 @@ +#include + +#include + +#include + +namespace safe_edge { +namespace server { +namespace common { + +void PilotServerPublishHelper::publish_charger_locations( + eprosima::safedds::dds::TypedDataWriter< + safe_edge::pilot_server::ChargerLocationTypeSupport>& writer, + const std::vector& parsed) +{ + for (size_t i = 0U; i < parsed.size(); ++i) + { + safe_edge::pilot_server::ChargerLocation loc; + loc.id = parsed[i].id; + loc.name = parsed[i].name.c_str(); + loc.position.latitude = parsed[i].latitude; + loc.position.longitude = parsed[i].longitude; + + if (eprosima::safedds::dds::ReturnCode::OK != + writer.write(loc, eprosima::safedds::dds::HANDLE_NIL)) + { + std::cerr << "[publish_helper] Failed to write ChargerLocation id=" + << parsed[i].id << std::endl; + } + } +} + +} // namespace common +} // namespace server +} // namespace safe_edge diff --git a/safe_dds/server/src/common/RuntimeConfig.cpp b/safe_dds/server/src/common/RuntimeConfig.cpp new file mode 100644 index 0000000..0034c96 --- /dev/null +++ b/safe_dds/server/src/common/RuntimeConfig.cpp @@ -0,0 +1,27 @@ +#include + +namespace safe_edge { +namespace server { +namespace common { + +RuntimeConfig make_server_runtime_config() +{ + RuntimeConfig config; + config.participant_name = "SafeEdgeServerParticipant"; + config.domain_id = 0U; + config.participant_port = 8020U; + + config.pilot_server_base_url = "https://pilot2.dumitru-alexandru.work"; + // api_key moved to /etc/safe-edge/server.ini — do not hardcode here + config.charger_locations_endpoint = "/api/chargers/locations"; + config.charger_types_endpoint = "/api/chargers/types"; + config.charging_sessions_endpoint = "/api/chargers/sessions"; + config.transit_health_endpoint = "/api/transit/health"; + config.transit_metrics_endpoint = "/api/transit/metrics"; + + return config; +} + +} // namespace common +} // namespace server +} // namespace safe_edge diff --git a/safe_dds/server/src/common/TopicNames.cpp b/safe_dds/server/src/common/TopicNames.cpp new file mode 100644 index 0000000..2c20bea --- /dev/null +++ b/safe_dds/server/src/common/TopicNames.cpp @@ -0,0 +1,26 @@ +#include + +namespace safe_edge { +namespace server { +namespace common { +namespace topic_names { + +const char* charger_locations() noexcept +{ + return "safe_edge.pilot_server.charger_locations"; +} + +const char* server_query() noexcept +{ + return "safe_edge.pilot_server.server_query"; +} + +const char* service_heartbeat() noexcept +{ + return "safe_edge.common.service_heartbeat"; +} + +} // namespace topic_names +} // namespace common +} // namespace server +} // namespace safe_edge diff --git a/safe_dds/server/src/nodes/ServerNode.cpp b/safe_dds/server/src/nodes/ServerNode.cpp new file mode 100644 index 0000000..716396c --- /dev/null +++ b/safe_dds/server/src/nodes/ServerNode.cpp @@ -0,0 +1,535 @@ +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace safe_edge { +namespace server { +namespace nodes { + +namespace { + +static safe_edge::pilot_server::ChargerLocationSeq build_charger_locations() +{ + safe_edge::pilot_server::ChargerLocationSeq locations; + + safe_edge::pilot_server::ChargerLocation loc1; + loc1.id = 1; + loc1.name = "Madrid North Hub"; + loc1.position.latitude = 40.4637F; + loc1.position.longitude = -3.7492F; + locations.push_back(loc1); + + safe_edge::pilot_server::ChargerLocation loc2; + loc2.id = 2; + loc2.name = "Barcelona Port Station"; + loc2.position.latitude = 41.3851F; + loc2.position.longitude = 2.1734F; + locations.push_back(loc2); + + safe_edge::pilot_server::ChargerLocation loc3; + loc3.id = 3; + loc3.name = "Valencia Depot"; + loc3.position.latitude = 39.4699F; + loc3.position.longitude = -0.3763F; + locations.push_back(loc3); + + return locations; +} + +static eprosima::safedds::memory::container::StaticList< + eprosima::safedds::transport::Locator, 2U> SERVER_INITIAL_PEERS; + +static bool init_server_peers() +{ + static constexpr uint16_t ports[] = { 8011U, 8030U }; + for (uint16_t port : ports) + { + SERVER_INITIAL_PEERS.add( + eprosima::safedds::transport::Locator::from_ipv4({127, 0, 0, 1}, port)); + } + return true; +} + +static const bool SERVER_PEERS_INITIALIZED = init_server_peers(); + +template +bool register_type( + eprosima::safedds::dds::DomainParticipant& participant, + TypeSupportT& type_support, + const char* label) +{ + if (eprosima::safedds::dds::ReturnCode::OK != type_support.register_type(participant, type_support.get_type_name())) + { + std::cerr << "[server] Failed to register type: " << label << std::endl; + return false; + } + + return true; +} + +template +eprosima::safedds::dds::Topic* create_topic( + eprosima::safedds::dds::DomainParticipant& participant, + eprosima::safedds::memory::container::StaticString256& topic_name, + TypeSupportT& type_support) +{ + return participant.create_topic( + topic_name, + type_support.get_type_name(), + eprosima::safedds::dds::TopicQos{}, + nullptr, + eprosima::safedds::dds::NONE_STATUS_MASK); +} + +template +eprosima::safedds::dds::TypedDataWriter* downcast_writer( + eprosima::safedds::dds::DataWriter* writer) +{ + if (nullptr == writer) + { + return nullptr; + } + + return eprosima::safedds::dds::TypedDataWriter::downcast(*writer); +} + +template +eprosima::safedds::dds::TypedDataReader* downcast_reader( + eprosima::safedds::dds::DataReader* reader) +{ + if (nullptr == reader) + { + return nullptr; + } + + return eprosima::safedds::dds::TypedDataReader::downcast(*reader); +} + +} // namespace + +ServerNode::ParticipantListener::ParticipantListener( + ServerNode& owner) + : owner_(owner) +{ +} + +void ServerNode::ParticipantListener::on_subscription_matched( + eprosima::safedds::dds::DataReader& reader, + const eprosima::safedds::dds::SubscriptionMatchedStatus& info) noexcept +{ + owner_.log_subscription_match(reader.get_topicdescription().get_name().const_string_data(), info.total_count); +} + +void ServerNode::ParticipantListener::on_publication_matched( + eprosima::safedds::dds::DataWriter& writer, + const eprosima::safedds::dds::PublicationMatchedStatus& info) noexcept +{ + owner_.log_publication_match(writer.get_topic().get_name().const_string_data(), info.total_count); + + if (&writer == owner_.charger_locations_datawriter_ && info.total_count_change > 0) + { + owner_.request_pilot_server_data(safe_edge::pilot_server::RequestedDataType::CHARGER_LOCATION); + } +} + +ServerNode::ServerQueryListener::ServerQueryListener( + ServerNode& owner) + : owner_(owner) +{ +} + +void ServerNode::ServerQueryListener::on_data_available( + eprosima::safedds::dds::DataReader& reader) noexcept +{ + auto* typed_reader = eprosima::safedds::dds::TypedDataReader::downcast(reader); + if (nullptr == typed_reader) + { + std::cerr << "[server] Failed to downcast server_query reader" << std::endl; + return; + } + + safe_edge::pilot_server::ServerQuery sample{}; + eprosima::safedds::dds::SampleInfo info{}; + while (typed_reader->take_next_sample(sample, info) == eprosima::safedds::dds::ReturnCode::OK) + { + if (info.valid_data) + { + owner_.on_server_query_received(sample); + } + } +} + +ServerNode::ServerNode( + const common::RuntimeConfig& runtime_config) + : runtime_config_(runtime_config) + , pilot_client_(runtime_config.pilot_server_base_url, "/etc/safe-edge/server.ini") + , participant_listener_(*this) + , server_query_listener_(*this) + , heartbeat_timer_({5, 0}) + , refresh_timer_({30, 0}) + , uptime_timer_({300, 0}) + , start_time_(std::chrono::steady_clock::now()) +{ +} + +void ServerNode::configure_participant_qos( + eprosima::safedds::dds::DomainParticipantQos& qos) noexcept +{ + qos.wire_protocol_qos().use_multicast_discovery = false; + qos.wire_protocol_qos().initial_peers = &SERVER_INITIAL_PEERS; +} + +int ServerNode::run() +{ + if (!initialize()) + { + return 1; + } + + heartbeat_timer_.start(); + refresh_timer_.start(); + uptime_timer_.start(); + + std::cout << "[server] [START] Running with participant port " << runtime_config_.participant_port << std::endl; + std::cout << "[server] PilotServer base_url=" << runtime_config_.pilot_server_base_url + << " api_key=***" << std::endl; + + while (true) + { + while (executor_->has_pending_work()) + { + executor_->spin(eprosima::safedds::execution::TIME_ZERO); + } + + if (heartbeat_timer_.is_triggered_and_reset()) + { + publish_heartbeat(); + } + + if (refresh_timer_.is_triggered_and_reset()) + { + periodic_refresh_all_resources(); + } + + if (uptime_timer_.is_triggered_and_reset()) + { + log_uptime(); + } + + executor_->spin(next_wakeup_time()); + } + + return 0; +} + +bool ServerNode::initialize() +{ + return create_participant() && + register_types() && + create_topics() && + create_endpoints() && + enable_entities() && + create_executor(); +} + +bool ServerNode::create_participant() +{ + eprosima::safedds::dds::DomainParticipantQos participant_qos{}; + eprosima::safedds::memory::container::StaticString256 participant_name(runtime_config_.participant_name.c_str()); + participant_qos.participant_name() = participant_name; + participant_qos.wire_protocol_qos().announced_locator = eprosima::safedds::transport::Locator::from_ipv4( + {127, 0, 0, 1}, + runtime_config_.participant_port); + + configure_participant_qos(participant_qos); + + participant_ = factory_.create_participant( + runtime_config_.domain_id, + participant_qos, + &participant_listener_, + eprosima::safedds::dds::PUBLICATION_MATCHED_STATUS | + eprosima::safedds::dds::SUBSCRIPTION_MATCHED_STATUS); + + if (nullptr == participant_) + { + std::cerr << "[server] Failed to create participant" << std::endl; + return false; + } + + return true; +} + +bool ServerNode::register_types() +{ + return register_type(*participant_, charger_locations_type_support_, "ChargerLocation") && + register_type(*participant_, server_query_type_support_, "ServerQuery") && + register_type(*participant_, service_heartbeat_type_support_, "ServiceHeartbeat"); +} + +bool ServerNode::create_topics() +{ + charger_locations_topic_name_ = eprosima::safedds::memory::container::StaticString256(common::topic_names::charger_locations()); + charger_locations_topic_ = create_topic(*participant_, charger_locations_topic_name_, charger_locations_type_support_); + if (nullptr == charger_locations_topic_) { std::cerr << "[server] Failed to create topic: charger_locations" << std::endl; return false; } + + server_query_topic_name_ = eprosima::safedds::memory::container::StaticString256(common::topic_names::server_query()); + server_query_topic_ = create_topic(*participant_, server_query_topic_name_, server_query_type_support_); + if (nullptr == server_query_topic_) { std::cerr << "[server] Failed to create topic: server_query" << std::endl; return false; } + + service_heartbeat_topic_name_ = eprosima::safedds::memory::container::StaticString256(common::topic_names::service_heartbeat()); + service_heartbeat_topic_ = create_topic(*participant_, service_heartbeat_topic_name_, service_heartbeat_type_support_); + if (nullptr == service_heartbeat_topic_) { std::cerr << "[server] Failed to create topic: service_heartbeat" << std::endl; return false; } + + return true; +} + +bool ServerNode::create_endpoints() +{ + eprosima::safedds::dds::PublisherQos publisher_qos{}; + publisher_ = participant_->create_publisher( + publisher_qos, + nullptr, + eprosima::safedds::dds::NONE_STATUS_MASK); + + eprosima::safedds::dds::SubscriberQos subscriber_qos{}; + subscriber_ = participant_->create_subscriber( + subscriber_qos, + nullptr, + eprosima::safedds::dds::NONE_STATUS_MASK); + + if (nullptr == publisher_ || nullptr == subscriber_) + { + std::cerr << "[server] Failed to create publisher or subscriber" << std::endl; + return false; + } + + eprosima::safedds::dds::DataWriterQos writer_qos{}; + writer_qos.reliability().kind = eprosima::safedds::dds::ReliabilityQosPolicyKind::RELIABLE_RELIABILITY_QOS; + + charger_locations_datawriter_ = publisher_->create_datawriter(*charger_locations_topic_, writer_qos, nullptr, eprosima::safedds::dds::NONE_STATUS_MASK); + charger_locations_writer_ = downcast_writer(charger_locations_datawriter_); + + service_heartbeat_datawriter_ = publisher_->create_datawriter(*service_heartbeat_topic_, writer_qos, nullptr, eprosima::safedds::dds::NONE_STATUS_MASK); + service_heartbeat_writer_ = downcast_writer(service_heartbeat_datawriter_); + + eprosima::safedds::dds::DataReaderQos reader_qos{}; + reader_qos.reliability().kind = eprosima::safedds::dds::ReliabilityQosPolicyKind::RELIABLE_RELIABILITY_QOS; + + server_query_datareader_ = subscriber_->create_datareader( + *server_query_topic_, + reader_qos, + &server_query_listener_, + eprosima::safedds::dds::DATA_AVAILABLE_STATUS); + server_query_reader_ = downcast_reader(server_query_datareader_); + + const bool success = + nullptr != charger_locations_writer_ && + nullptr != service_heartbeat_writer_ && + nullptr != server_query_reader_; + + if (!success) + { + std::cerr << "[server] Failed to create endpoints" << std::endl; + } + + return success; +} + +bool ServerNode::enable_entities() +{ + bool enabled = true; + enabled = enabled && (eprosima::safedds::dds::ReturnCode::OK == publisher_->enable()); + enabled = enabled && (eprosima::safedds::dds::ReturnCode::OK == charger_locations_datawriter_->enable()); + enabled = enabled && (eprosima::safedds::dds::ReturnCode::OK == service_heartbeat_datawriter_->enable()); + enabled = enabled && (eprosima::safedds::dds::ReturnCode::OK == subscriber_->enable()); + enabled = enabled && (eprosima::safedds::dds::ReturnCode::OK == server_query_datareader_->enable()); + enabled = enabled && (eprosima::safedds::dds::ReturnCode::OK == participant_->enable()); + + if (!enabled) + { + std::cerr << "[server] Failed to enable DDS entities" << std::endl; + } + + return enabled; +} + +bool ServerNode::create_executor() +{ + executor_ = factory_.create_default_executor(); + + if (nullptr == executor_) + { + std::cerr << "[server] Failed to create executor" << std::endl; + return false; + } + + return true; +} + +void ServerNode::on_server_query_received( + const safe_edge::pilot_server::ServerQuery& query) +{ + std::cout << "[server] DDS query from=" << query.requested_by + << " type=" << static_cast(query.requested_data_type) << std::endl; + request_pilot_server_data(query.requested_data_type); +} + +void ServerNode::log_subscription_match( + const char* topic_name, + int32_t total_count) const +{ + std::cout << "[server] Subscription matched on " << topic_name + << " total_count=" << total_count << std::endl; +} + +void ServerNode::log_publication_match( + const char* topic_name, + int32_t total_count) const +{ + std::cout << "[server] Publication matched on " << topic_name + << " total_count=" << total_count << std::endl; +} + +const char* ServerNode::resolve_endpoint( + safe_edge::pilot_server::RequestedDataType resource) const noexcept +{ + switch (resource) + { + case safe_edge::pilot_server::RequestedDataType::CHARGER_LOCATION: + return runtime_config_.charger_locations_endpoint.c_str(); + case safe_edge::pilot_server::RequestedDataType::CHARGER_TYPE: + return runtime_config_.charger_types_endpoint.c_str(); + case safe_edge::pilot_server::RequestedDataType::CHARGING_SESSION: + return runtime_config_.charging_sessions_endpoint.c_str(); + case safe_edge::pilot_server::RequestedDataType::TRANSIT_HEALTH: + return runtime_config_.transit_health_endpoint.c_str(); + case safe_edge::pilot_server::RequestedDataType::TRANSIT_METRICS: + return runtime_config_.transit_metrics_endpoint.c_str(); + default: + return nullptr; + } +} + +void ServerNode::request_pilot_server_data( + safe_edge::pilot_server::RequestedDataType resource) noexcept +{ + const char* endpoint = resolve_endpoint(resource); + if (nullptr == endpoint) + { + std::cerr << "[server] Unsupported resource=" << static_cast(resource) << std::endl; + return; + } + + std::cout << "[server] Request resource=" << static_cast(resource) + << " endpoint=" << endpoint << std::endl; + + const std::string body = pilot_client_.fetch(endpoint); + if (body.empty()) + { + std::cerr << "[server] HTTP fetch failed endpoint=" << endpoint << std::endl; + } + else if (resource == safe_edge::pilot_server::RequestedDataType::CHARGER_LOCATION + && nullptr != charger_locations_writer_) + { + const auto parsed = + safe_edge::server::common::PilotServerPayloadParser::parse_charger_locations(body); + safe_edge::server::common::PilotServerPublishHelper::publish_charger_locations( + *charger_locations_writer_, parsed); + std::cout << "[server] Published charger_locations count=" << parsed.size() + << " (from HTTP)" << std::endl; + } + else if (!body.empty()) + { + // TODO: add writers and parsers for other resource types + std::cout << "[server] HTTP response received resource=" + << static_cast(resource) + << " bytes=" << body.size() + << " (parse not yet implemented)" << std::endl; + } + + // Stub: preserve existing charger_locations publication until HTTP response is confirmed correct + if (resource == safe_edge::pilot_server::RequestedDataType::CHARGER_LOCATION + && nullptr != charger_locations_writer_) + { + const auto locations = build_charger_locations(); + for (size_t i = 0; i < locations.size(); ++i) + { + charger_locations_writer_->write(locations[i], eprosima::safedds::dds::HANDLE_NIL); + } + std::cout << "[server] Published charger_locations count=" << locations.size() + << " (stub)" << std::endl; + } +} + +void ServerNode::periodic_refresh_all_resources() noexcept +{ + static constexpr safe_edge::pilot_server::RequestedDataType all_resources[] = { + safe_edge::pilot_server::RequestedDataType::CHARGER_LOCATION, + safe_edge::pilot_server::RequestedDataType::CHARGER_TYPE, + safe_edge::pilot_server::RequestedDataType::CHARGING_SESSION, + safe_edge::pilot_server::RequestedDataType::TRANSIT_HEALTH, + safe_edge::pilot_server::RequestedDataType::TRANSIT_METRICS, + }; + + for (const auto resource : all_resources) + { + std::cout << "[server] Periodic refresh resource=" << static_cast(resource) << std::endl; + request_pilot_server_data(resource); + } +} + +void ServerNode::log_uptime() const noexcept +{ + const auto elapsed = std::chrono::steady_clock::now() - start_time_; + const auto seconds = std::chrono::duration_cast(elapsed).count(); + std::cout << "[server] Uptime=" << seconds << "s" << std::endl; +} + +void ServerNode::publish_heartbeat() +{ + safe_edge::common::ServiceHeartbeat heartbeat{}; + heartbeat.header_st.source = "server"; + heartbeat.service_name = "server"; + heartbeat.status = safe_edge::common::HealthStatus::HEALTH_OK; + heartbeat.detail = "running"; + + if (eprosima::safedds::dds::ReturnCode::OK != + service_heartbeat_writer_->write(heartbeat, eprosima::safedds::dds::HANDLE_NIL)) + { + std::cerr << "[server] Failed to publish ServiceHeartbeat" << std::endl; + return; + } + + std::cout << "[server] Published ServiceHeartbeat" << std::endl; +} + +eprosima::safedds::execution::TimePoint ServerNode::next_wakeup_time() const noexcept +{ + eprosima::safedds::execution::TimePoint next = executor_->get_next_work_timepoint(); + next = eprosima::safedds::execution::TimePoint::min(next, heartbeat_timer_.next_trigger()); + next = eprosima::safedds::execution::TimePoint::min(next, refresh_timer_.next_trigger()); + next = eprosima::safedds::execution::TimePoint::min(next, uptime_timer_.next_trigger()); + return next; +} + +} // namespace nodes +} // namespace server +} // namespace safe_edge diff --git a/safe_dds/server/test/test_server_integration.cpp b/safe_dds/server/test/test_server_integration.cpp new file mode 100644 index 0000000..61f681d --- /dev/null +++ b/safe_dds/server/test/test_server_integration.cpp @@ -0,0 +1,518 @@ +// test_server_integration.cpp +// +// Single binary integration test for safe_edge_server. +// Starts the server as a subprocess, runs all test suites, stops the server. +// +// Usage: +// ./test_server_integration +// ./test_server_integration --gtest_output=xml:results.xml (CI / JUnit) +// +// Environment variables: +// SAFE_EDGE_SERVER_BIN path to safe_edge_server binary (default: safe_edge_server) + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +static eprosima::safedds::memory::container::StaticList< + eprosima::safedds::transport::Locator, 1U> g_peers; + +static bool init_peers() +{ + g_peers.add(eprosima::safedds::transport::Locator::from_ipv4({127, 0, 0, 1}, 8020U)); + return true; +} + +static const bool PEERS_INIT = init_peers(); +static const char* SERVER_PID_FILE = "/tmp/safe_edge_server_test.pid"; +static const char* SERVER_LOG_FILE = "/tmp/safe_edge_server_test.log"; + +static eprosima::safedds::dds::DomainParticipant* make_participant( + eprosima::safedds::dds::DomainParticipantFactory& factory, + const char* name, + uint16_t port) +{ + eprosima::safedds::dds::DomainParticipantQos qos{}; + eprosima::safedds::memory::container::StaticString256 sname(name); + qos.participant_name() = sname; + qos.wire_protocol_qos().announced_locator = + eprosima::safedds::transport::Locator::from_ipv4({127, 0, 0, 1}, port); + qos.wire_protocol_qos().use_multicast_discovery = false; + qos.wire_protocol_qos().initial_peers = &g_peers; + return factory.create_participant(0U, qos, nullptr, + eprosima::safedds::dds::NONE_STATUS_MASK); +} + +static void destroy_participant( + eprosima::safedds::dds::DomainParticipantFactory& factory, + eprosima::safedds::dds::DomainParticipant*& participant, + eprosima::safedds::dds::Publisher*& publisher, + eprosima::safedds::dds::Subscriber*& subscriber, + eprosima::safedds::dds::Topic*& topic_a, + eprosima::safedds::dds::Topic*& topic_b, + eprosima::safedds::dds::DataWriter*& writer, + eprosima::safedds::dds::DataReader*& reader) noexcept +{ + writer = nullptr; + reader = nullptr; + + if (participant != nullptr) + { + (void)participant->delete_contained_entities(); + (void)factory.delete_participant(participant); + participant = nullptr; + std::this_thread::sleep_for(std::chrono::milliseconds(250)); + } + + publisher = nullptr; + subscriber = nullptr; + topic_a = nullptr; + topic_b = nullptr; +} + +class ServerEnvironment : public ::testing::Environment +{ +public: + void SetUp() override + { + const char* bin = std::getenv("SAFE_EDGE_SERVER_BIN"); + const std::string server_bin = (bin != nullptr ? bin : "safe_edge_server"); + const std::string cmd = + "sh -c 'rm -f " + std::string(SERVER_PID_FILE) + + "; " + server_bin + " >" + SERVER_LOG_FILE + " 2>&1 & echo $! > " + + SERVER_PID_FILE + "'"; + ASSERT_EQ(0, std::system(cmd.c_str())) + << "Failed to launch safe_edge_server. " + "Set SAFE_EDGE_SERVER_BIN to the full path if needed."; + + std::cout << "[env] safe_edge_server started — waiting 5 s for init...\n"; + std::this_thread::sleep_for(std::chrono::seconds(5)); + std::cout << "[env] Server ready.\n"; + } + + void TearDown() override + { + std::cout << "[env] safe_edge_server log:\n"; + std::system((std::string("sh -c 'if [ -f ") + SERVER_LOG_FILE + + " ]; then cat " + SERVER_LOG_FILE + "; else echo missing log; fi'").c_str()); + std::cout << "[env] Stopping safe_edge_server...\n"; + const std::string stop_cmd = + "sh -c '" + "if [ -f " + std::string(SERVER_PID_FILE) + " ]; then " + "pid=$(cat " + std::string(SERVER_PID_FILE) + "); " + "kill \"$pid\" 2>/dev/null || true; " + "sleep 1; " + "kill -9 \"$pid\" 2>/dev/null || true; " + "rm -f " + std::string(SERVER_PID_FILE) + "; " + "fi; " + "pkill -f safe_edge_server 2>/dev/null || true" + "'"; + std::system(stop_cmd.c_str()); + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + } +}; + +static bool wait_for_charger_location( + eprosima::safedds::execution::ISpinnable& executor, + eprosima::safedds::dds::TypedDataReader< + safe_edge::pilot_server::ChargerLocationTypeSupport>& reader, + int timeout_s) +{ + const auto deadline = + std::chrono::steady_clock::now() + std::chrono::seconds(timeout_s); + + while (std::chrono::steady_clock::now() < deadline) + { + while (executor.has_pending_work()) + { + executor.spin(eprosima::safedds::execution::TIME_ZERO); + } + + safe_edge::pilot_server::ChargerLocation sample{}; + eprosima::safedds::dds::SampleInfo info{}; + if (reader.take_next_sample(sample, info) == + eprosima::safedds::dds::ReturnCode::OK && info.valid_data) + { + std::cout << "[dds] Received ChargerLocation id=" << sample.id + << " name=" << sample.name << "\n"; + return true; + } + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + return false; +} + +static void drain_charger_locations( + eprosima::safedds::execution::ISpinnable& executor, + eprosima::safedds::dds::TypedDataReader< + safe_edge::pilot_server::ChargerLocationTypeSupport>& reader) +{ + while (executor.has_pending_work()) + { + executor.spin(eprosima::safedds::execution::TIME_ZERO); + } + + safe_edge::pilot_server::ChargerLocation sample{}; + eprosima::safedds::dds::SampleInfo info{}; + while (reader.take_next_sample(sample, info) == + eprosima::safedds::dds::ReturnCode::OK) + { + } +} + +static bool wait_for_query_response( + eprosima::safedds::execution::ISpinnable& executor, + eprosima::safedds::dds::TypedDataWriter< + safe_edge::pilot_server::ServerQueryTypeSupport>& writer, + eprosima::safedds::dds::TypedDataReader< + safe_edge::pilot_server::ChargerLocationTypeSupport>& reader, + safe_edge::pilot_server::RequestedDataType type, + int timeout_s) +{ + const auto deadline = + std::chrono::steady_clock::now() + std::chrono::seconds(timeout_s); + + while (std::chrono::steady_clock::now() < deadline) + { + safe_edge::pilot_server::ServerQuery q{}; + q.requested_by = "test_query_dispatch"; + q.requested_data_type = type; + if (writer.write(q, eprosima::safedds::dds::HANDLE_NIL) == + eprosima::safedds::dds::ReturnCode::OK && + wait_for_charger_location(executor, reader, 1)) + { + return true; + } + + std::this_thread::sleep_for(std::chrono::milliseconds(250)); + } + + return false; +} + +static void spin_for( + eprosima::safedds::execution::ISpinnable& executor, + std::chrono::milliseconds duration) +{ + const auto deadline = std::chrono::steady_clock::now() + duration; + + while (std::chrono::steady_clock::now() < deadline) + { + while (executor.has_pending_work()) + { + executor.spin(eprosima::safedds::execution::TIME_ZERO); + } + + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + } +} + +struct QueryDispatchContext +{ + eprosima::safedds::dds::DomainParticipantFactory factory; + eprosima::safedds::dds::DomainParticipant* participant = nullptr; + eprosima::safedds::dds::Publisher* publisher = nullptr; + eprosima::safedds::dds::Subscriber* subscriber = nullptr; + eprosima::safedds::dds::Topic* charger_topic = nullptr; + eprosima::safedds::dds::Topic* query_topic = nullptr; + eprosima::safedds::dds::DataWriter* query_writer_base = nullptr; + eprosima::safedds::dds::DataReader* charger_reader_base = nullptr; + eprosima::safedds::execution::ISpinnable* executor = nullptr; + safe_edge::pilot_server::ChargerLocationTypeSupport charger_ts; + safe_edge::pilot_server::ServerQueryTypeSupport query_ts; + eprosima::safedds::dds::TypedDataWriter< + safe_edge::pilot_server::ServerQueryTypeSupport>* query_writer = nullptr; + eprosima::safedds::dds::TypedDataReader< + safe_edge::pilot_server::ChargerLocationTypeSupport>* charger_reader = nullptr; +}; + +static QueryDispatchContext& query_dispatch_context() +{ + static QueryDispatchContext* ctx = new QueryDispatchContext(); + return *ctx; +} + +static void create_query_dispatch_context(QueryDispatchContext& ctx); +static void destroy_query_dispatch_context(QueryDispatchContext& ctx) noexcept; + +class QueryDispatchSuite : public ::testing::Test +{ +protected: + static void SetUpTestSuite() + { + create_query_dispatch_context(query_dispatch_context()); + } + + static void TearDownTestSuite() + { + destroy_query_dispatch_context(query_dispatch_context()); + } +}; + +static void create_query_dispatch_context( + QueryDispatchContext& ctx) +{ + (void)PEERS_INIT; + + ctx.participant = make_participant(ctx.factory, "TestQueryDispatch", 8011U); + ASSERT_NE(nullptr, ctx.participant); + + ASSERT_EQ(eprosima::safedds::dds::ReturnCode::OK, + ctx.charger_ts.register_type(*ctx.participant, ctx.charger_ts.get_type_name())); + ASSERT_EQ(eprosima::safedds::dds::ReturnCode::OK, + ctx.query_ts.register_type(*ctx.participant, ctx.query_ts.get_type_name())); + + eprosima::safedds::memory::container::StaticString256 cname( + safe_edge::server::common::topic_names::charger_locations()); + eprosima::safedds::memory::container::StaticString256 qname( + safe_edge::server::common::topic_names::server_query()); + + ctx.charger_topic = ctx.participant->create_topic( + cname, ctx.charger_ts.get_type_name(), + eprosima::safedds::dds::TopicQos{}, nullptr, + eprosima::safedds::dds::NONE_STATUS_MASK); + ctx.query_topic = ctx.participant->create_topic( + qname, ctx.query_ts.get_type_name(), + eprosima::safedds::dds::TopicQos{}, nullptr, + eprosima::safedds::dds::NONE_STATUS_MASK); + ASSERT_NE(nullptr, ctx.charger_topic); + ASSERT_NE(nullptr, ctx.query_topic); + + ctx.publisher = ctx.participant->create_publisher( + eprosima::safedds::dds::PublisherQos{}, nullptr, + eprosima::safedds::dds::NONE_STATUS_MASK); + ctx.subscriber = ctx.participant->create_subscriber( + eprosima::safedds::dds::SubscriberQos{}, nullptr, + eprosima::safedds::dds::NONE_STATUS_MASK); + ASSERT_NE(nullptr, ctx.publisher); + ASSERT_NE(nullptr, ctx.subscriber); + + eprosima::safedds::dds::DataWriterQos wqos{}; + wqos.reliability().kind = + eprosima::safedds::dds::ReliabilityQosPolicyKind::RELIABLE_RELIABILITY_QOS; + eprosima::safedds::dds::DataReaderQos rqos{}; + rqos.reliability().kind = + eprosima::safedds::dds::ReliabilityQosPolicyKind::RELIABLE_RELIABILITY_QOS; + + ctx.query_writer_base = ctx.publisher->create_datawriter( + *ctx.query_topic, wqos, nullptr, + eprosima::safedds::dds::NONE_STATUS_MASK); + ctx.charger_reader_base = ctx.subscriber->create_datareader( + *ctx.charger_topic, rqos, nullptr, + eprosima::safedds::dds::NONE_STATUS_MASK); + ASSERT_NE(nullptr, ctx.query_writer_base); + ASSERT_NE(nullptr, ctx.charger_reader_base); + + ctx.query_writer = eprosima::safedds::dds::TypedDataWriter< + safe_edge::pilot_server::ServerQueryTypeSupport>::downcast(*ctx.query_writer_base); + ctx.charger_reader = eprosima::safedds::dds::TypedDataReader< + safe_edge::pilot_server::ChargerLocationTypeSupport>::downcast(*ctx.charger_reader_base); + ASSERT_NE(nullptr, ctx.query_writer); + ASSERT_NE(nullptr, ctx.charger_reader); + + ASSERT_EQ(eprosima::safedds::dds::ReturnCode::OK, ctx.publisher->enable()); + ASSERT_EQ(eprosima::safedds::dds::ReturnCode::OK, ctx.subscriber->enable()); + ASSERT_EQ(eprosima::safedds::dds::ReturnCode::OK, ctx.query_writer_base->enable()); + ASSERT_EQ(eprosima::safedds::dds::ReturnCode::OK, ctx.charger_reader_base->enable()); + ASSERT_EQ(eprosima::safedds::dds::ReturnCode::OK, ctx.participant->enable()); + + ctx.executor = ctx.factory.create_default_executor(); + ASSERT_NE(nullptr, ctx.executor); + + spin_for(*ctx.executor, std::chrono::seconds(3)); +} + +static void destroy_query_dispatch_context( + QueryDispatchContext& ctx) noexcept +{ + if (nullptr == ctx.participant) + { + return; + } + + destroy_participant(ctx.factory, ctx.participant, ctx.publisher, ctx.subscriber, + ctx.charger_topic, ctx.query_topic, ctx.query_writer_base, ctx.charger_reader_base); + ctx.executor = nullptr; + ctx.query_writer = nullptr; + ctx.charger_reader = nullptr; +} + +static void send_query( + eprosima::safedds::dds::TypedDataWriter< + safe_edge::pilot_server::ServerQueryTypeSupport>& writer, + safe_edge::pilot_server::RequestedDataType type) +{ + safe_edge::pilot_server::ServerQuery q{}; + q.requested_by = "test_query_dispatch"; + q.requested_data_type = type; + EXPECT_EQ(eprosima::safedds::dds::ReturnCode::OK, + writer.write(q, eprosima::safedds::dds::HANDLE_NIL)); +} + +TEST_F(QueryDispatchSuite, ChargerLocationReturnsData) +{ + auto& ctx = query_dispatch_context(); + drain_charger_locations(*ctx.executor, *ctx.charger_reader); + EXPECT_TRUE(wait_for_query_response( + *ctx.executor, + *ctx.query_writer, + *ctx.charger_reader, + safe_edge::pilot_server::RequestedDataType::CHARGER_LOCATION, + 10)) << "No ChargerLocation received after query within 10 s"; +} + +TEST_F(QueryDispatchSuite, ChargerTypeHandledWithoutCrash) +{ + auto& ctx = query_dispatch_context(); + send_query(*ctx.query_writer, + safe_edge::pilot_server::RequestedDataType::CHARGER_TYPE); + spin_for(*ctx.executor, std::chrono::milliseconds(500)); +} + +TEST_F(QueryDispatchSuite, ChargingSessionHandledWithoutCrash) +{ + auto& ctx = query_dispatch_context(); + send_query(*ctx.query_writer, + safe_edge::pilot_server::RequestedDataType::CHARGING_SESSION); + spin_for(*ctx.executor, std::chrono::milliseconds(500)); +} + +TEST_F(QueryDispatchSuite, TransitHealthHandledWithoutCrash) +{ + auto& ctx = query_dispatch_context(); + send_query(*ctx.query_writer, + safe_edge::pilot_server::RequestedDataType::TRANSIT_HEALTH); + spin_for(*ctx.executor, std::chrono::milliseconds(500)); +} + +TEST_F(QueryDispatchSuite, TransitMetricsHandledWithoutCrash) +{ + auto& ctx = query_dispatch_context(); + send_query(*ctx.query_writer, + safe_edge::pilot_server::RequestedDataType::TRANSIT_METRICS); + spin_for(*ctx.executor, std::chrono::milliseconds(500)); +} + +TEST(PeriodicRefresh, TwoBurstsIn35Seconds) +{ + (void)PEERS_INIT; + + eprosima::safedds::dds::DomainParticipantFactory factory; + auto* participant = make_participant(factory, "TestPeriodicRefresh", 8030U); + ASSERT_NE(nullptr, participant); + + safe_edge::pilot_server::ChargerLocationTypeSupport charger_ts; + ASSERT_EQ(eprosima::safedds::dds::ReturnCode::OK, + charger_ts.register_type(*participant, charger_ts.get_type_name())); + + eprosima::safedds::memory::container::StaticString256 tname( + safe_edge::server::common::topic_names::charger_locations()); + auto* topic = participant->create_topic( + tname, charger_ts.get_type_name(), + eprosima::safedds::dds::TopicQos{}, nullptr, + eprosima::safedds::dds::NONE_STATUS_MASK); + ASSERT_NE(nullptr, topic); + + auto* sub = participant->create_subscriber( + eprosima::safedds::dds::SubscriberQos{}, nullptr, + eprosima::safedds::dds::NONE_STATUS_MASK); + ASSERT_NE(nullptr, sub); + + eprosima::safedds::dds::DataReaderQos rqos{}; + rqos.reliability().kind = + eprosima::safedds::dds::ReliabilityQosPolicyKind::RELIABLE_RELIABILITY_QOS; + + auto* reader_base = sub->create_datareader( + *topic, rqos, nullptr, + eprosima::safedds::dds::NONE_STATUS_MASK); + ASSERT_NE(nullptr, reader_base); + + auto* reader = eprosima::safedds::dds::TypedDataReader< + safe_edge::pilot_server::ChargerLocationTypeSupport>::downcast(*reader_base); + ASSERT_NE(nullptr, reader); + + ASSERT_EQ(eprosima::safedds::dds::ReturnCode::OK, sub->enable()); + ASSERT_EQ(eprosima::safedds::dds::ReturnCode::OK, reader_base->enable()); + ASSERT_EQ(eprosima::safedds::dds::ReturnCode::OK, participant->enable()); + + auto* executor = factory.create_default_executor(); + ASSERT_NE(nullptr, executor); + + spin_for(*executor, std::chrono::seconds(3)); + + int burst_count = 0; + const auto t0 = std::chrono::steady_clock::now(); + const auto end = t0 + std::chrono::seconds(45); + auto last_sample = t0 - std::chrono::seconds(10); + + while (std::chrono::steady_clock::now() < end) + { + while (executor->has_pending_work()) + { + executor->spin(eprosima::safedds::execution::TIME_ZERO); + } + + safe_edge::pilot_server::ChargerLocation sample{}; + eprosima::safedds::dds::SampleInfo info{}; + if (reader->take_next_sample(sample, info) == + eprosima::safedds::dds::ReturnCode::OK && info.valid_data) + { + const auto now = std::chrono::steady_clock::now(); + if (std::chrono::duration_cast( + now - last_sample).count() > 2000) + { + burst_count++; + std::cout << "[dds] Burst " << burst_count << " at t=" + << std::chrono::duration_cast( + now - t0).count() << " s\n"; + } + last_sample = now; + } + else + { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + } + + EXPECT_GE(burst_count, 2) + << "Expected >=2 bursts (publication_match + periodic refresh), " + << "got " << burst_count; + + eprosima::safedds::dds::Publisher* unused_publisher = nullptr; + eprosima::safedds::dds::DataWriter* unused_writer = nullptr; + destroy_participant(factory, participant, unused_publisher, sub, + topic, topic, unused_writer, reader_base); +} + +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + ::testing::AddGlobalTestEnvironment(new ServerEnvironment()); + return RUN_ALL_TESTS(); +} diff --git a/scripts/build_qnx.sh b/scripts/build_qnx.sh new file mode 100755 index 0000000..c976085 --- /dev/null +++ b/scripts/build_qnx.sh @@ -0,0 +1,236 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +WORKSPACE_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)" + +QNX_USER="${USER:-$(id -un)}" +: "${QNX_SDP_ROOT:=/home/${QNX_USER}/qnx800}" +: "${QNX_HOST:=${QNX_SDP_ROOT}/host/linux/x86_64}" +: "${QNX_TARGET:=${QNX_SDP_ROOT}/target/qnx}" +: "${QNX_ARCH:=x86_64}" +: "${CMAKE_BUILD_TYPE:=Release}" +: "${CMAKE_GENERATOR:=Unix Makefiles}" +: "${QNX_COMMON_CXXFLAGS:=-D_QNX_SOURCE}" +: "${QNX_TOOLCHAIN_FILE:=${WORKSPACE_ROOT}/qnx/toolchains/qnx8.cmake}" +: "${COMMON_SERVER_BUILD_FOLDER:=${WORKSPACE_ROOT}/common_server/build/server-common-qnx8-${QNX_ARCH}-${CMAKE_BUILD_TYPE}}" +: "${COMMON_SERVER_INSTALL_FOLDER:=${WORKSPACE_ROOT}/common_server/install/server-common-qnx8-${QNX_ARCH}-${CMAKE_BUILD_TYPE}}" +: "${SERVER_BUILD_FOLDER:=${WORKSPACE_ROOT}/safe_dds/build/server-qnx8-${QNX_ARCH}-${CMAKE_BUILD_TYPE}}" +: "${SERVER_INSTALL_FOLDER:=${WORKSPACE_ROOT}/safe_dds/install/server-qnx8-${QNX_ARCH}-${CMAKE_BUILD_TYPE}}" +: "${EDGE_BUILD_FOLDER:=${WORKSPACE_ROOT}/safe_dds/build/edge-qnx8-${QNX_ARCH}-${CMAKE_BUILD_TYPE}}" +: "${EDGE_INSTALL_FOLDER:=${WORKSPACE_ROOT}/safe_dds/install/edge-qnx8-${QNX_ARCH}-${CMAKE_BUILD_TYPE}}" +: "${SAFE_DDS_IDL_GENERATOR:-}" +: "${SAFE_DDS_IDL_GENERATOR_ARGS:-}" +: "${SAFEDDS_DIR:=${WORKSPACE_ROOT}/qnx/install/safedds-qnx8-${QNX_ARCH}/safedds}" + +COMMON_IDL_SOURCE_DIR="${WORKSPACE_ROOT}/idl" +SAFE_DDS_IDL_DIR="${WORKSPACE_ROOT}/safe_dds/idl" + +REGEN_IDL=0 +EXTRA_BUILD_ARGS=() + +usage() { + cat <] + +Options: + -i, --idl regenerate safe_dds/idl from the shared idl/*.idl sources + -h, --help show this help message + +Environment variables: + SAFE_DDS_IDL_GENERATOR command used to regenerate Safe DDS IDL artifacts + SAFE_DDS_IDL_GENERATOR_ARGS extra args appended to the IDL generator command + QNX_TOOLCHAIN_FILE path to the QNX toolchain file + SAFEDDS_DIR path to cross-compiled Safe DDS CMake package for QNX + QNX_ARCH x86_64 or aarch64le (default: x86_64) + CMAKE_BUILD_TYPE CMake configuration type (default: Release) + +The script always configures and builds: + - common_server + - safe_dds/server + - safe_dds/edge + +If there are no source changes, CMake will skip recompilation internally. +EOF +} + +while [[ $# -gt 0 ]]; do + case "$1" in + -i|--idl) + REGEN_IDL=1 + shift + ;; + -h|--help) + usage + exit 0 + ;; + --) + shift + EXTRA_BUILD_ARGS=("$@") + break + ;; + *) + echo "Unknown option: $1" >&2 + usage + exit 1 + ;; + esac +done + +find_idl_generator() { + if [[ -n "${SAFE_DDS_IDL_GENERATOR:-}" ]]; then + local generator_bin="${SAFE_DDS_IDL_GENERATOR%% *}" + if command -v "${generator_bin}" >/dev/null 2>&1; then + echo "${SAFE_DDS_IDL_GENERATOR}" + return 0 + fi + fi + + local candidates=(safeddsgen safedds-idl-gen safedds-gen eprosima_safeddsgen) + for prog in "${candidates[@]}"; do + if command -v "${prog}" >/dev/null 2>&1; then + echo "${prog}" + return 0 + fi + done + + return 1 +} + +regenerate_idl() { + local generator + generator="$(find_idl_generator)" || { + echo "No IDL generator found. Set SAFE_DDS_IDL_GENERATOR to a valid command." >&2 + exit 1 + } + + if [[ ! -d "${COMMON_IDL_SOURCE_DIR}" ]]; then + echo "Shared IDL source directory not found at '${COMMON_IDL_SOURCE_DIR}'" >&2 + exit 1 + fi + + mkdir -p "${SAFE_DDS_IDL_DIR}" + + local cleanup_links=() + local idl_file + for idl_file in "${COMMON_IDL_SOURCE_DIR}"/*.idl; do + if [[ ! -e "${idl_file}" ]]; then + echo "No .idl files found in '${COMMON_IDL_SOURCE_DIR}'" >&2 + exit 1 + fi + + local link_target="${SAFE_DDS_IDL_DIR}/$(basename "${idl_file}")" + ln -sfn "${idl_file}" "${link_target}" + cleanup_links+=("${link_target}") + done + + echo "Regenerating Safe DDS IDL artifacts" + echo " source : ${COMMON_IDL_SOURCE_DIR}" + echo " generated: ${SAFE_DDS_IDL_DIR}" + echo " generator: ${generator} ${SAFE_DDS_IDL_GENERATOR_ARGS:-}" + + pushd "${SAFE_DDS_IDL_DIR}" >/dev/null + if ! bash -lc "${generator} ${SAFE_DDS_IDL_GENERATOR_ARGS:-}"; then + popd >/dev/null + rm -f "${cleanup_links[@]}" + exit 1 + fi + popd >/dev/null + + rm -f "${cleanup_links[@]}" +} + +configure_and_build() { + local src_dir="$1" + local build_dir="$2" + local install_dir="$3" + local name="$4" + shift 4 + local extra_cmake_args=("$@") + local cache_file="${build_dir}/CMakeCache.txt" + + if [[ -f "${cache_file}" ]]; then + local cached_source + cached_source="$(sed -n 's/^CMAKE_HOME_DIRECTORY:INTERNAL=//p' "${cache_file}")" + if [[ -n "${cached_source}" && "${cached_source}" != "${src_dir}" ]]; then + echo "Removing stale CMake cache for ${name}" + echo " cached source: ${cached_source}" + rm -rf "${build_dir}" + mkdir -p "${build_dir}" + fi + fi + + local cmake_args=( + -S "${src_dir}" + -B "${build_dir}" + -G "${CMAKE_GENERATOR}" + -DCMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE}" + -DCMAKE_TOOLCHAIN_FILE="${QNX_TOOLCHAIN_FILE}" + -DQNX_ARCH="${QNX_ARCH}" + -DCMAKE_CXX_FLAGS="${CMAKE_CXX_FLAGS:-${QNX_COMMON_CXXFLAGS}}" + -DCMAKE_INSTALL_PREFIX="${install_dir}" + ) + + cmake_args+=("-Dsafedds_DIR=${SAFEDDS_DIR}") + cmake_args+=("${extra_cmake_args[@]}") + + echo "Configuring ${name}" + echo " source : ${src_dir}" + echo " build : ${build_dir}" + echo " install: ${install_dir}" + cmake "${cmake_args[@]}" + cmake --build "${build_dir}" --target install "${EXTRA_BUILD_ARGS[@]}" + echo -e "Finished building ${name}\n" +} + +case "${QNX_ARCH}" in + x86_64|aarch64le) ;; + *) + echo "Unsupported QNX_ARCH='${QNX_ARCH}'. Use x86_64 or aarch64le." >&2 + exit 1 + ;; +esac + +if [[ ! -d "${QNX_HOST}" || ! -d "${QNX_TARGET}" ]]; then + echo "QNX SDK paths not found. QNX_HOST='${QNX_HOST}', QNX_TARGET='${QNX_TARGET}'" >&2 + exit 1 +fi + +if [[ ! -f "${QNX_TOOLCHAIN_FILE}" ]]; then + echo "QNX toolchain file not found. QNX_TOOLCHAIN_FILE='${QNX_TOOLCHAIN_FILE}'" >&2 + exit 1 +fi + +if [[ ! -d "${SAFEDDS_DIR}" ]]; then + echo "Safe DDS QNX install not found at '${SAFEDDS_DIR}'" >&2 + echo "Build it first with: bash build_safedds_qnx.sh -- -j2" >&2 + exit 1 +fi + +if [[ ! -d "${COMMON_IDL_SOURCE_DIR}" ]]; then + echo "Shared IDL source directory not found at '${COMMON_IDL_SOURCE_DIR}'" >&2 + exit 1 +fi + +if [[ ! -d "${SAFE_DDS_IDL_DIR}" ]]; then + echo "Safe DDS generated IDL directory not found at '${SAFE_DDS_IDL_DIR}'" >&2 + exit 1 +fi + +export QNX_HOST +export QNX_TARGET +export PATH="${QNX_HOST}/usr/bin:${PATH}" + +if (( REGEN_IDL )); then + regenerate_idl +fi + +mkdir -p "${COMMON_SERVER_BUILD_FOLDER}" "${COMMON_SERVER_INSTALL_FOLDER}" \ + "${SERVER_BUILD_FOLDER}" "${SERVER_INSTALL_FOLDER}" \ + "${EDGE_BUILD_FOLDER}" "${EDGE_INSTALL_FOLDER}" + +configure_and_build "${WORKSPACE_ROOT}/common_server" "${COMMON_SERVER_BUILD_FOLDER}" "${COMMON_SERVER_INSTALL_FOLDER}" "common_server" +configure_and_build "${WORKSPACE_ROOT}/safe_dds/server" "${SERVER_BUILD_FOLDER}" "${SERVER_INSTALL_FOLDER}" "safe_dds/server" +configure_and_build "${WORKSPACE_ROOT}/safe_dds/edge" "${EDGE_BUILD_FOLDER}" "${EDGE_INSTALL_FOLDER}" "safe_dds/edge" + +echo "All SafeEDGE QNX targets built successfully." diff --git a/scripts/build_safedds_qnx.sh b/scripts/build_safedds_qnx.sh new file mode 100755 index 0000000..b1580a7 --- /dev/null +++ b/scripts/build_safedds_qnx.sh @@ -0,0 +1,66 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +WORKSPACE_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)" + +QNX_USER="${USER:-$(id -un)}" +: "${QNX_SDP_ROOT:=/home/${QNX_USER}/qnx800}" +: "${QNX_HOST:=${QNX_SDP_ROOT}/host/linux/x86_64}" +: "${QNX_TARGET:=${QNX_SDP_ROOT}/target/qnx}" +: "${QNX_ARCH:=x86_64}" +: "${CMAKE_BUILD_TYPE:=Release}" +: "${CMAKE_GENERATOR:=Unix Makefiles}" +: "${QNX_COMMON_CXXFLAGS:=-D_QNX_SOURCE}" +: "${QNX_BUILD_SAFEDDS_FOLDER:=${WORKSPACE_ROOT}/qnx/build/safedds-qnx8-${QNX_ARCH}}" +: "${QNX_INSTALL_SAFEDDS_FOLDER:=${WORKSPACE_ROOT}/qnx/install/safedds-qnx8-${QNX_ARCH}}" + +if [[ -z "${SAFE_DDS_PATH:-}" ]]; then + echo "SAFE_DDS_PATH is not defined." >&2 + echo "Set it to the Safe-DDS source tree, for example:" >&2 + echo " export SAFE_DDS_PATH=/path/to/Safe-DDS-source-release" >&2 + exit 1 +fi + +if [[ ! -d "${SAFE_DDS_PATH}" ]]; then + echo "Safe-DDS source path not found: ${SAFE_DDS_PATH}" >&2 + exit 1 +fi + +if [[ ! -d "${QNX_HOST}" || ! -d "${QNX_TARGET}" ]]; then + echo "QNX SDK paths not found. QNX_HOST='${QNX_HOST}', QNX_TARGET='${QNX_TARGET}'" >&2 + exit 1 +fi + +case "${QNX_ARCH}" in + x86_64|aarch64le) ;; + *) + echo "Unsupported QNX_ARCH='${QNX_ARCH}'. Use x86_64 or aarch64le." >&2 + exit 1 + ;; +esac + +export QNX_HOST +export QNX_TARGET +export PATH="${QNX_HOST}/usr/bin:${PATH}" + +mkdir -p "${QNX_BUILD_SAFEDDS_FOLDER}" "${QNX_INSTALL_SAFEDDS_FOLDER}" + +echo "Configuring Safe-DDS for QNX 8" +echo " source : ${SAFE_DDS_PATH}" +echo " build : ${QNX_BUILD_SAFEDDS_FOLDER}" +echo " install: ${QNX_INSTALL_SAFEDDS_FOLDER}" +echo " arch : ${QNX_ARCH}" + +cmake \ + -S "${SAFE_DDS_PATH}" \ + -B "${QNX_BUILD_SAFEDDS_FOLDER}" \ + -G "${CMAKE_GENERATOR}" \ + -DCMAKE_TOOLCHAIN_FILE="${WORKSPACE_ROOT}/qnx/toolchains/qnx8.cmake" \ + -DQNX_ARCH="${QNX_ARCH}" \ + -DCMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE}" \ + -DCMAKE_CXX_FLAGS="${CMAKE_CXX_FLAGS:-${QNX_COMMON_CXXFLAGS}}" \ + -DCMAKE_INSTALL_PREFIX="${QNX_INSTALL_SAFEDDS_FOLDER}" \ + -DSAFEDDS_LOG_LEVEL="WARNING" + +cmake --build "${QNX_BUILD_SAFEDDS_FOLDER}" --target install "$@" diff --git a/scripts/build_ubuntu.sh b/scripts/build_ubuntu.sh new file mode 100755 index 0000000..9f7b36a --- /dev/null +++ b/scripts/build_ubuntu.sh @@ -0,0 +1,95 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +WORKSPACE_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)" + +: "${FASTDDS_BASE_IMAGE:=eprosima/vulcanexus:kilted-base}" +: "${CMAKE_BUILD_TYPE:=Release}" + +BUILD_TESTS=0 + +usage() { + cat <&2 + usage >&2 + exit 1 + ;; + esac +done + +cd "${WORKSPACE_ROOT}" + +echo "Building safe-edge-server:fast ..." +docker build \ + --build-arg FASTDDS_BASE_IMAGE="${FASTDDS_BASE_IMAGE}" \ + --build-arg CMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE}" \ + -f fast_dds/docker/server.Dockerfile \ + -t safe-edge-server:fast \ + . + +echo "Building safe-edge-edge:fast ..." +docker build \ + --build-arg FASTDDS_BASE_IMAGE="${FASTDDS_BASE_IMAGE}" \ + --build-arg CMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE}" \ + -f fast_dds/docker/edge.Dockerfile \ + -t safe-edge-edge:fast \ + . + +if (( BUILD_TESTS )); then + echo "Building safe-edge-server:fast-test ..." + docker build \ + --build-arg FASTDDS_BASE_IMAGE="${FASTDDS_BASE_IMAGE}" \ + --build-arg CMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE}" \ + -f fast_dds/docker/server.test.Dockerfile \ + -t safe-edge-server:fast-test \ + . + + echo "Building safe-edge-edge:fast-test ..." + docker build \ + --build-arg FASTDDS_BASE_IMAGE="${FASTDDS_BASE_IMAGE}" \ + --build-arg CMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE}" \ + -f fast_dds/docker/edge.test.Dockerfile \ + -t safe-edge-edge:fast-test \ + . +fi + +echo "Done. Images built:" +echo " safe-edge-server:fast" +echo " safe-edge-edge:fast" +if (( BUILD_TESTS )); then + echo " safe-edge-server:fast-test" + echo " safe-edge-edge:fast-test" +fi diff --git a/scripts/check_setup.sh b/scripts/check_setup.sh new file mode 100755 index 0000000..4140b63 --- /dev/null +++ b/scripts/check_setup.sh @@ -0,0 +1,130 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +WORKSPACE_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)" + +QNX_USER="${USER:-$(id -un)}" +: "${QNX_SDP_ROOT:=/home/${QNX_USER}/qnx800}" +: "${QNX_HOST:=${QNX_SDP_ROOT}/host/linux/x86_64}" +: "${QNX_TARGET:=${QNX_SDP_ROOT}/target/qnx}" +: "${QNX_ARCH:=x86_64}" + +LINUX_ONLY=0 + +usage() { + cat <&2 + usage >&2 + exit 1 + ;; + esac +done + +require_cmd() { + local cmd="$1" + if ! command -v "${cmd}" >/dev/null 2>&1; then + echo "Missing command: ${cmd}" >&2 + echo "For Ubuntu/Debian host packages, run: bash install_host_deps.sh" >&2 + return 1 + fi +} + +require_path() { + local path="$1" + if [[ ! -e "${path}" ]]; then + echo "Missing path: ${path}" >&2 + return 1 + fi +} + +echo "Checking common prerequisites..." +require_cmd bash +require_cmd cmake +require_cmd tee +require_cmd curl-config +require_path "${WORKSPACE_ROOT}/README.md" +require_path "${WORKSPACE_ROOT}/common_server/CMakeLists.txt" +require_path "${WORKSPACE_ROOT}/safe_dds/server/CMakeLists.txt" +require_path "${WORKSPACE_ROOT}/safe_dds/edge/CMakeLists.txt" +require_path "${WORKSPACE_ROOT}/scripts/build_qnx.sh" +require_path "${WORKSPACE_ROOT}/scripts/build_safedds_qnx.sh" +require_path "${WORKSPACE_ROOT}/scripts/launch_tpi_2_1_test.sh" +require_path "${WORKSPACE_ROOT}/scripts/launch_tpi_2_2_test.sh" +require_path "${WORKSPACE_ROOT}/scripts/launch_tpi_2_3_test.sh" + +if (( LINUX_ONLY )); then + echo "Linux-only setup check completed." + exit 0 +fi + +echo "Checking QNX SDK..." +if [[ ! -e "${QNX_SDP_ROOT}/qnxsdp-env.sh" ]]; then + echo "Missing QNX SDK environment file: ${QNX_SDP_ROOT}/qnxsdp-env.sh" >&2 + echo "Install QNX SDP 8 and/or set QNX_SDP_ROOT to its installation path." >&2 + exit 1 +fi +require_path "${QNX_HOST}" +require_path "${QNX_TARGET}" + +echo "Checking QNX host tools..." +require_cmd qemu-system-x86_64 +require_cmd sshpass +require_cmd brctl +require_cmd file + +echo "Checking repo-local QNX assets..." +require_path "${WORKSPACE_ROOT}/qnx/toolchains/qnx8.cmake" +require_path "${WORKSPACE_ROOT}/qnx/targets/qemu-qnx800-${QNX_ARCH}" +require_path "${WORKSPACE_ROOT}/qnx/targets/qemu-qnx800-${QNX_ARCH}/mkqnximage-wrapper.sh" +require_path "${WORKSPACE_ROOT}/qnx/targets/qemu-qnx800-${QNX_ARCH}/local/options" +require_path "${WORKSPACE_ROOT}/qnx/targets/qemu-qnx800-${QNX_ARCH}/local/valgrind.files" +require_path "${WORKSPACE_ROOT}/qnx/targets/qemu-qnx800-${QNX_ARCH}/local/snippets" +require_path "${WORKSPACE_ROOT}/qnx/targets/qemu-qnx800-${QNX_ARCH}/local/snippets/data_files.custom" +require_path "${WORKSPACE_ROOT}/qnx/targets/qemu-qnx800-${QNX_ARCH}/local/snippets/ifs_files.custom" +require_path "${WORKSPACE_ROOT}/qnx/targets/qemu-qnx800-${QNX_ARCH}/local/snippets/profile.custom" + +if [[ ! -d "${WORKSPACE_ROOT}/qnx/targets/qemu-qnx800-${QNX_ARCH}/local/misc_files" ]]; then + echo "QNX local misc_files directory not found yet. Test launchers create it when needed." +fi + +if [[ -e "${WORKSPACE_ROOT}/qnx/targets/qemu-qnx800-${QNX_ARCH}/local/ssh-ident" ]]; then + echo "Found local QNX ssh-ident file. It is local/generated and intentionally ignored by git." +fi + +echo "Checking Safe-DDS source configuration..." +if [[ -z "${SAFE_DDS_PATH:-}" ]]; then + echo "SAFE_DDS_PATH is not defined." >&2 + echo "Set it to the Safe-DDS source tree before building SafeDDS for QNX." >&2 + echo "Example: export SAFE_DDS_PATH=/path/to/Safe-DDS-source-release" >&2 + exit 1 +fi +require_path "${SAFE_DDS_PATH}" + +if [[ ! -d "${WORKSPACE_ROOT}/qnx/install/safedds-qnx8-${QNX_ARCH}/safedds" ]]; then + echo "Safe DDS QNX install not found yet." + echo "Build it with: bash build_safedds_qnx.sh -- -j2" +fi + +echo "Setup check completed." +echo "QNX_SDP_ROOT=${QNX_SDP_ROOT}" +echo "QNX_HOST=${QNX_HOST}" +echo "QNX_TARGET=${QNX_TARGET}" +echo "SAFE_DDS_PATH=${SAFE_DDS_PATH}" +echo "QNX target=${WORKSPACE_ROOT}/qnx/targets/qemu-qnx800-${QNX_ARCH}" diff --git a/scripts/env.example b/scripts/env.example new file mode 100644 index 0000000..3106564 --- /dev/null +++ b/scripts/env.example @@ -0,0 +1,14 @@ +# SafeEDGE environment example. +# Copy values into your shell or source a local copy adapted to your machine. + +# QNX SDP 8 installation root. This tree is external and is not stored in this repository. +export QNX_SDP_ROOT="/path/to/qnx800" +export QNX_HOST="$QNX_SDP_ROOT/host/linux/x86_64" +export QNX_TARGET="$QNX_SDP_ROOT/target/qnx" + +# Safe-DDS source tree. This tree is external and is not stored in this repository. +export SAFE_DDS_PATH="/path/to/Safe-DDS-source-release" + +# Optional build settings. +export QNX_ARCH="x86_64" +export CMAKE_BUILD_TYPE="Release" diff --git a/scripts/launch_fast_edge_test.sh b/scripts/launch_fast_edge_test.sh new file mode 100755 index 0000000..ba5be0e --- /dev/null +++ b/scripts/launch_fast_edge_test.sh @@ -0,0 +1,57 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +WORKSPACE_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)" + +IMAGE="safe-edge-edge:fast-test" +LOG_DIR="${SCRIPT_DIR}/logs" +LOG_FILE="${LOG_DIR}/launch_fast_edge_test.log" + +usage() { + cat <&2; usage >&2; exit 1 ;; + esac +done + +mkdir -p "${LOG_DIR}" + +if ! docker image inspect "${IMAGE}" > /dev/null 2>&1; then + echo "[launch_fast_edge_test] Image ${IMAGE} not found — building..." + bash "${SCRIPT_DIR}/build_ubuntu.sh" --tests +fi + +# Remove stale FastDDS shared-memory artifacts that can cause false failures. +sudo rm -f /dev/shm/fastdds_* /dev/shm/sem.fastdds_* 2>/dev/null || true + +echo "[launch_fast_edge_test] Running edge integration test..." +echo "[launch_fast_edge_test] Log: ${LOG_FILE}" + +set +e +docker run --rm --network host "${IMAGE}" 2>&1 | tee "${LOG_FILE}" +TEST_EXIT=${PIPESTATUS[0]} +set -e + +if [[ ${TEST_EXIT} -eq 0 ]]; then + echo "[launch_fast_edge_test] PASSED" +else + echo "[launch_fast_edge_test] FAILED (exit ${TEST_EXIT})" >&2 +fi + +exit "${TEST_EXIT}" diff --git a/scripts/launch_fast_server_test.sh b/scripts/launch_fast_server_test.sh new file mode 100755 index 0000000..4aa7be5 --- /dev/null +++ b/scripts/launch_fast_server_test.sh @@ -0,0 +1,56 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +WORKSPACE_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)" + +IMAGE="safe-edge-server:fast-test" +LOG_DIR="${SCRIPT_DIR}/logs" +LOG_FILE="${LOG_DIR}/launch_fast_server_test.log" + +usage() { + cat <&2; usage >&2; exit 1 ;; + esac +done + +mkdir -p "${LOG_DIR}" + +if ! docker image inspect "${IMAGE}" > /dev/null 2>&1; then + echo "[launch_fast_server_test] Image ${IMAGE} not found — building..." + bash "${SCRIPT_DIR}/build_ubuntu.sh" --tests +fi + +# Remove stale FastDDS shared-memory artifacts that can cause false failures. +sudo rm -f /dev/shm/fastdds_* /dev/shm/sem.fastdds_* 2>/dev/null || true + +echo "[launch_fast_server_test] Running server integration test..." +echo "[launch_fast_server_test] Log: ${LOG_FILE}" + +set +e +docker run --rm --network host "${IMAGE}" 2>&1 | tee "${LOG_FILE}" +TEST_EXIT=${PIPESTATUS[0]} +set -e + +if [[ ${TEST_EXIT} -eq 0 ]]; then + echo "[launch_fast_server_test] PASSED" +else + echo "[launch_fast_server_test] FAILED (exit ${TEST_EXIT})" >&2 +fi + +exit "${TEST_EXIT}" diff --git a/scripts/launch_tpi_2_1_test.sh b/scripts/launch_tpi_2_1_test.sh new file mode 100755 index 0000000..283c4c8 --- /dev/null +++ b/scripts/launch_tpi_2_1_test.sh @@ -0,0 +1,254 @@ +#!/usr/bin/env bash +# Run the Safe DDS server integration test on a QNX VM. +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +WORKSPACE_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)" +LOG_DIR="${SCRIPT_DIR}/logs" +LOG_FILE="${LOG_DIR}/launch_tpi_2_1.log" + +QNX_USER="${USER:-$(id -un)}" +: "${QNX_SDP_ROOT:=/home/${QNX_USER}/qnx800}" +: "${QNX_ARCH:=x86_64}" +: "${CMAKE_BUILD_TYPE:=Release}" +: "${TARGET_DIR:=${WORKSPACE_ROOT}/qnx/targets/qemu-qnx800-${QNX_ARCH}}" +: "${SERVER_BIN_DIR:=${WORKSPACE_ROOT}/safe_dds/install/server-qnx8-${QNX_ARCH}-${CMAKE_BUILD_TYPE}/bin}" + +_SSH_PASS="root" +_SSH_USER="root" +_SSH_OPTS="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o ConnectTimeout=30 -o LogLevel=ERROR" + +mkdir -p "${LOG_DIR}" +exec > >(tee "${LOG_FILE}") 2>&1 + +OPT_NO_REBUILD=0 +OPT_STOP=0 + +usage() { + cat <&2 + usage >&2 + exit 1 + ;; + esac +done + +if [[ ! -f "${QNX_SDP_ROOT}/qnxsdp-env.sh" ]]; then + echo "QNX SDK not found at QNX_SDP_ROOT='${QNX_SDP_ROOT}'" >&2 + exit 1 +fi + +if [[ ! -d "${TARGET_DIR}" ]]; then + echo "QNX target directory not found: ${TARGET_DIR}" >&2 + exit 1 +fi + +if ! command -v sshpass >/dev/null 2>&1; then + echo "sshpass not found. Install with: sudo apt install sshpass" >&2 + exit 1 +fi + +# shellcheck source=/dev/null +source "${QNX_SDP_ROOT}/qnxsdp-env.sh" >/dev/null 2>&1 + +if ! command -v qemu-system-x86_64 >/dev/null 2>&1; then + echo "qemu-system-x86_64 not found. Install with: sudo apt install qemu-system-x86" >&2 + exit 1 +fi + +if ! command -v brctl >/dev/null 2>&1; then + echo "brctl not found. Install with: sudo apt install bridge-utils" >&2 + exit 1 +fi + +_get_ip_address() { + local max_tries=20 + local ip + local i + + for ((i = 0; i < max_tries; i++)); do + set +e + ip="$(mkqnximage --getip 2>/dev/null)" + set -e + if [[ -n "${ip}" ]]; then + echo "${ip}" + return 0 + fi + sleep 2 + done + + echo "Timed out waiting for VM IP address." >&2 + return 1 +} + +_ssh_run() { + local ip="$1" + local cmd="$2" + # shellcheck disable=SC2086 + sshpass -p "${_SSH_PASS}" ssh ${_SSH_OPTS} "${_SSH_USER}@${ip}" "${cmd}" +} + +_wait_for_ssh() { + local ip="$1" + local max_tries=45 + local i + + for ((i = 1; i <= max_tries; i++)); do + if _ssh_run "${ip}" "true" >/dev/null 2>&1; then + return 0 + fi + if (( i == 1 || i % 5 == 0 )); then + echo " waiting for SSH (${i}/${max_tries})..." + fi + sleep 2 + done + + echo "Timed out waiting for SSH on ${ip}." >&2 + return 1 +} + +_validate_qnx_binary() { + local bin="$1" + local description + + if ! description="$(file "${bin}")"; then + echo "Failed to inspect binary: ${bin}" >&2 + return 1 + fi + + if grep -Fq "GNU/Linux" <<<"${description}"; then + echo "Binary appears to be a Linux executable, not a QNX executable:" >&2 + echo " ${description}" >&2 + echo "Rebuild with: bash scripts/build_qnx.sh" >&2 + return 1 + fi +} + +_refresh_test_system_files_snippet() { + local snippet="${TARGET_DIR}/local/snippets/system_files.custom" + mkdir -p "$(dirname "${snippet}")" + cat > "${snippet}" < "${snippet}" <<'EOF' +# local/snippets/ifs_start.custom +# Generated by scripts/launch_tpi_2_1_test.sh +EOF +} + +_refresh_test_post_start_snippet() { + local snippet="${TARGET_DIR}/local/snippets/post_start.custom" + mkdir -p "$(dirname "${snippet}")" + cat > "${snippet}" <<'EOF' +# local/snippets/post_start.custom +# Generated by scripts/launch_tpi_2_1_test.sh +route add -net 224.0.0.0/4 vtnet0 +EOF +} + +_reset_generated_target_output() { + rm -rf "${TARGET_DIR}/output" +} + +_prepare_local_target_dirs() { + mkdir -p "${TARGET_DIR}/local/misc_files" "${TARGET_DIR}/local/snippets" +} + +_prepare_local_target_dirs +cd "${TARGET_DIR}" + +if [[ "${OPT_STOP}" -eq 1 ]]; then + echo "Stopping QNX VM..." + mkqnximage --stop 2>/dev/null || true + kill "$(pgrep -f qemu-system-x86_64)" 2>/dev/null || true + echo "VM stopped." + exit 0 +fi + +kill "$(pgrep -f qemu-system-x86_64)" 2>/dev/null || true + +if [[ "${OPT_NO_REBUILD}" -eq 0 ]]; then + for bin in \ + "${SERVER_BIN_DIR}/safe_edge_server" \ + "${SERVER_BIN_DIR}/test_server_integration"; do + if [[ ! -f "${bin}" ]]; then + echo "Binary not found: ${bin}" >&2 + echo "Build with: bash scripts/build_qnx.sh" >&2 + exit 1 + fi + _validate_qnx_binary "${bin}" + done + + _refresh_test_ifs_start_snippet + _refresh_test_post_start_snippet + _refresh_test_system_files_snippet + _reset_generated_target_output +fi + +if [[ "${OPT_NO_REBUILD}" -eq 0 ]]; then + echo "Building QNX image and starting QEMU..." + mkqnximage --noprompt --run=-h --clean >/dev/null 2>&1 +else + echo "Starting QNX QEMU (skipping rebuild)..." + mkqnximage --noprompt --run=-h >/dev/null 2>&1 +fi + +echo "Waiting for VM IP..." +VM_IP="$(_get_ip_address)" +echo "VM is up: ${VM_IP}" +echo "Waiting for SSH..." +_wait_for_ssh "${VM_IP}" +echo "VM is reachable." + +echo "" +echo "Running test_server_integration on QNX..." +echo "---------------------------------------------" + +TEST_RC=0 +_ssh_run "${VM_IP}" \ + "SAFE_EDGE_SERVER_BIN=/system/bin/safe_edge_server /system/bin/test_server_integration" \ + || TEST_RC=$? + +echo "---------------------------------------------" +echo "" +echo "Stopping QNX VM..." +mkqnximage --stop 2>/dev/null || true + +if [[ "${TEST_RC}" -eq 0 ]]; then + echo "PASSED" +else + echo "FAILED (exit code ${TEST_RC})" + exit "${TEST_RC}" +fi diff --git a/scripts/launch_tpi_2_2_test.sh b/scripts/launch_tpi_2_2_test.sh new file mode 100755 index 0000000..4e6b41e --- /dev/null +++ b/scripts/launch_tpi_2_2_test.sh @@ -0,0 +1,254 @@ +#!/usr/bin/env bash +# Run the Safe DDS edge integration test on a QNX VM. +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +WORKSPACE_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)" +LOG_DIR="${SCRIPT_DIR}/logs" +LOG_FILE="${LOG_DIR}/launch_tpi_2_2.log" + +QNX_USER="${USER:-$(id -un)}" +: "${QNX_SDP_ROOT:=/home/${QNX_USER}/qnx800}" +: "${QNX_ARCH:=x86_64}" +: "${CMAKE_BUILD_TYPE:=Release}" +: "${TARGET_DIR:=${WORKSPACE_ROOT}/qnx/targets/qemu-qnx800-${QNX_ARCH}}" +: "${EDGE_BIN_DIR:=${WORKSPACE_ROOT}/safe_dds/install/edge-qnx8-${QNX_ARCH}-${CMAKE_BUILD_TYPE}/bin}" + +_SSH_PASS="root" +_SSH_USER="root" +_SSH_OPTS="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o ConnectTimeout=30 -o LogLevel=ERROR" + +mkdir -p "${LOG_DIR}" +exec > >(tee "${LOG_FILE}") 2>&1 + +OPT_NO_REBUILD=0 +OPT_STOP=0 + +usage() { + cat <&2 + usage >&2 + exit 1 + ;; + esac +done + +if [[ ! -f "${QNX_SDP_ROOT}/qnxsdp-env.sh" ]]; then + echo "QNX SDK not found at QNX_SDP_ROOT='${QNX_SDP_ROOT}'" >&2 + exit 1 +fi + +if [[ ! -d "${TARGET_DIR}" ]]; then + echo "QNX target directory not found: ${TARGET_DIR}" >&2 + exit 1 +fi + +if ! command -v sshpass >/dev/null 2>&1; then + echo "sshpass not found. Install with: sudo apt install sshpass" >&2 + exit 1 +fi + +# shellcheck source=/dev/null +source "${QNX_SDP_ROOT}/qnxsdp-env.sh" >/dev/null 2>&1 + +if ! command -v qemu-system-x86_64 >/dev/null 2>&1; then + echo "qemu-system-x86_64 not found. Install with: sudo apt install qemu-system-x86" >&2 + exit 1 +fi + +if ! command -v brctl >/dev/null 2>&1; then + echo "brctl not found. Install with: sudo apt install bridge-utils" >&2 + exit 1 +fi + +_get_ip_address() { + local max_tries=20 + local ip + local i + + for ((i = 0; i < max_tries; i++)); do + set +e + ip="$(mkqnximage --getip 2>/dev/null)" + set -e + if [[ -n "${ip}" ]]; then + echo "${ip}" + return 0 + fi + sleep 2 + done + + echo "Timed out waiting for VM IP address." >&2 + return 1 +} + +_ssh_run() { + local ip="$1" + local cmd="$2" + # shellcheck disable=SC2086 + sshpass -p "${_SSH_PASS}" ssh ${_SSH_OPTS} "${_SSH_USER}@${ip}" "${cmd}" +} + +_wait_for_ssh() { + local ip="$1" + local max_tries=45 + local i + + for ((i = 1; i <= max_tries; i++)); do + if _ssh_run "${ip}" "true" >/dev/null 2>&1; then + return 0 + fi + if (( i == 1 || i % 5 == 0 )); then + echo " waiting for SSH (${i}/${max_tries})..." + fi + sleep 2 + done + + echo "Timed out waiting for SSH on ${ip}." >&2 + return 1 +} + +_validate_qnx_binary() { + local bin="$1" + local description + + if ! description="$(file "${bin}")"; then + echo "Failed to inspect binary: ${bin}" >&2 + return 1 + fi + + if grep -Fq "GNU/Linux" <<<"${description}"; then + echo "Binary appears to be a Linux executable, not a QNX executable:" >&2 + echo " ${description}" >&2 + echo "Rebuild with: bash scripts/build_qnx.sh" >&2 + return 1 + fi +} + +_refresh_test_system_files_snippet() { + local snippet="${TARGET_DIR}/local/snippets/system_files.custom" + mkdir -p "$(dirname "${snippet}")" + cat > "${snippet}" < "${snippet}" <<'EOF' +# local/snippets/ifs_start.custom +# Generated by scripts/launch_tpi_2_2_test.sh +EOF +} + +_refresh_test_post_start_snippet() { + local snippet="${TARGET_DIR}/local/snippets/post_start.custom" + mkdir -p "$(dirname "${snippet}")" + cat > "${snippet}" <<'EOF' +# local/snippets/post_start.custom +# Generated by scripts/launch_tpi_2_2_test.sh +route add -net 224.0.0.0/4 vtnet0 +EOF +} + +_reset_generated_target_output() { + rm -rf "${TARGET_DIR}/output" +} + +_prepare_local_target_dirs() { + mkdir -p "${TARGET_DIR}/local/misc_files" "${TARGET_DIR}/local/snippets" +} + +_prepare_local_target_dirs +cd "${TARGET_DIR}" + +if [[ "${OPT_STOP}" -eq 1 ]]; then + echo "Stopping QNX VM..." + mkqnximage --stop 2>/dev/null || true + kill "$(pgrep -f qemu-system-x86_64)" 2>/dev/null || true + echo "VM stopped." + exit 0 +fi + +kill "$(pgrep -f qemu-system-x86_64)" 2>/dev/null || true + +if [[ "${OPT_NO_REBUILD}" -eq 0 ]]; then + for bin in \ + "${EDGE_BIN_DIR}/safe_edge_edge_gateway" \ + "${EDGE_BIN_DIR}/test_edge_integration"; do + if [[ ! -f "${bin}" ]]; then + echo "Binary not found: ${bin}" >&2 + echo "Build with: bash scripts/build_qnx.sh" >&2 + exit 1 + fi + _validate_qnx_binary "${bin}" + done + + _refresh_test_ifs_start_snippet + _refresh_test_post_start_snippet + _refresh_test_system_files_snippet + _reset_generated_target_output +fi + +if [[ "${OPT_NO_REBUILD}" -eq 0 ]]; then + echo "Building QNX image and starting QEMU..." + mkqnximage --noprompt --run=-h --clean >/dev/null 2>&1 +else + echo "Starting QNX QEMU (skipping rebuild)..." + mkqnximage --noprompt --run=-h >/dev/null 2>&1 +fi + +echo "Waiting for VM IP..." +VM_IP="$(_get_ip_address)" +echo "VM is up: ${VM_IP}" +echo "Waiting for SSH..." +_wait_for_ssh "${VM_IP}" +echo "VM is reachable." + +echo "" +echo "Running test_edge_integration on QNX..." +echo "---------------------------------------------" + +TEST_RC=0 +_ssh_run "${VM_IP}" \ + "SAFE_EDGE_EDGE_BIN=/system/bin/safe_edge_edge_gateway /system/bin/test_edge_integration" \ + || TEST_RC=$? + +echo "---------------------------------------------" +echo "" +echo "Stopping QNX VM..." +mkqnximage --stop 2>/dev/null || true + +if [[ "${TEST_RC}" -eq 0 ]]; then + echo "PASSED" +else + echo "FAILED (exit code ${TEST_RC})" + exit "${TEST_RC}" +fi diff --git a/scripts/launch_tpi_2_3_test.sh b/scripts/launch_tpi_2_3_test.sh new file mode 100755 index 0000000..08f5851 --- /dev/null +++ b/scripts/launch_tpi_2_3_test.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash +# Run KPI/TPI 2.3 on Linux/Ubuntu. +# This KPI validates the shared common_server component and does not require QNX. +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +WORKSPACE_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)" +LOG_DIR="${SCRIPT_DIR}/logs" +LOG_FILE="${LOG_DIR}/launch_tpi_2_3.log" + +mkdir -p "${LOG_DIR}" +exec > >(tee "${LOG_FILE}") 2>&1 + +bash "${WORKSPACE_ROOT}/common_server/test/launch_server_common_test.sh" "$@"