diff --git a/common/include/villas/kernel/devices/ip_device.hpp b/common/include/villas/kernel/devices/ip_device.hpp new file mode 100644 index 000000000..0652176fc --- /dev/null +++ b/common/include/villas/kernel/devices/ip_device.hpp @@ -0,0 +1,34 @@ +/* IpDevice + * + * Author: Pascal Bauer + * + * SPDX-FileCopyrightText: 2023-2024 Pascal Bauer + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include + +namespace villas { +namespace kernel { +namespace devices { + +class IpDevice : public PlatformDevice { +public: +public: + static IpDevice from(const std::filesystem::path unsafe_path); + static bool is_path_valid(const std::filesystem::path unsafe_path); + +private: + IpDevice(const std::filesystem::path valid_path) : PlatformDevice(valid_path){}; + +public: + size_t addr() const; + std::string ip_name() const; +}; + +} // namespace devices +} // namespace kernel +} // namespace villas \ No newline at end of file diff --git a/common/lib/kernel/devices/ip_device.cpp b/common/lib/kernel/devices/ip_device.cpp new file mode 100644 index 000000000..5aafb0de9 --- /dev/null +++ b/common/lib/kernel/devices/ip_device.cpp @@ -0,0 +1,55 @@ +/* IpDevice + * + * Author: Pascal Bauer + * + * SPDX-FileCopyrightText: 2023-2024 Pascal Bauer + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#include + +using villas::kernel::devices::IpDevice; + +IpDevice IpDevice::from(const std::filesystem::path unsafe_path) { + if (!is_path_valid(unsafe_path)) + throw std::runtime_error( + "Path \"" + unsafe_path.u8string() + + "\" failed validation as IpDevicePath \"[adress in hex].[name]\". "); + return IpDevice(unsafe_path); +} + +std::string IpDevice::ip_name() const { + int pos = name().find('.'); + return name().substr(pos + 1); +} + +size_t IpDevice::addr() const { + size_t pos = name().find('.'); + std::string addr_hex = name().substr(0, pos); + + // convert from hex string to number + std::stringstream ss; + ss << std::hex << addr_hex; + size_t addr = 0; + ss >> addr; + + return addr; +} + +bool IpDevice::is_path_valid(const std::filesystem::path unsafe_path) { + // Split the string at last slash + int pos = unsafe_path.u8string().rfind('/'); + std::string assumed_device_name = unsafe_path.u8string().substr(pos + 1); + + // Match format of hexaddr.devicename + if (!std::regex_match(assumed_device_name, + std::regex(R"([0-9A-Fa-f]+\..*)"))) { + return false; + } + + return true; +}