diff --git a/include/borzoi/borzoi_converter.hpp b/include/borzoi/borzoi_converter.hpp index 10f8918..7036000 100644 --- a/include/borzoi/borzoi_converter.hpp +++ b/include/borzoi/borzoi_converter.hpp @@ -8,14 +8,9 @@ #pragma once -#include "l2/logical_link_control_packet.hpp" #include "l2/slot.hpp" #include struct BorzoiConverter { - static constexpr const int kPacketApiVersion = 0; - static auto to_json(const Slots& slots) -> nlohmann::json; - - static auto to_json(const std::unique_ptr& packet) -> nlohmann::json; }; diff --git a/include/nlohmann_std_unique_ptr_logical_link_control_packet.hpp b/include/nlohmann_std_unique_ptr_logical_link_control_packet.hpp new file mode 100644 index 0000000..a173b44 --- /dev/null +++ b/include/nlohmann_std_unique_ptr_logical_link_control_packet.hpp @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2024 Transit Live Mapping Solutions + * All rights reserved. + * + * Authors: + * Marenz Schmidl + */ + +#pragma once + +#include "l2/logical_link_control_packet.hpp" +#include "l3/circuit_mode_control_entity_packet.hpp" +#include "l3/mobile_link_entity_packet.hpp" +#include "l3/mobile_management_packet.hpp" +#include "l3/short_data_service_packet.hpp" +#include + +static constexpr const int kPacketApiVersion = 0; + +inline static auto get_time() -> std::string { + auto t = std::time(nullptr); + auto tm = *std::localtime(&t); + std::stringstream ss; + ss << std::put_time(&tm, "%FT%T%z"); + return ss.str(); +} + +namespace nlohmann { +template <> struct adl_serializer> { + static void to_json(json& j, const std::unique_ptr& packet) { + j["protocol_version"] = kPacketApiVersion; + j["time"] = get_time(); + + if (auto* mle = dynamic_cast(packet.get())) { + if (auto* cmce = dynamic_cast(mle)) { + if (auto* sds = dynamic_cast(mle)) { + // Emit ShortDataServicePacket packet to json + j["key"] = "ShortDataServicePacket"; + j["value"] = *sds; + } else { + // Emit CircuitModeControlEntityPacket packet to json + j["key"] = "CircuitModeControlEntityPacket"; + j["value"] = *cmce; + } + } else if (auto* mm = dynamic_cast(mle)) { + // Emit MobileManagementPacket packet to json + j["key"] = "MobileManagementPacket"; + j["value"] = *mm; + } else { + // Emit MobileLinkEntityPacket packet to json + j["key"] = "MobileLinkEntityPacket"; + j["value"] = *mle; + } + } else { + // Emit LogicalLinkControlPacket packet to json + j["key"] = "LogicalLinkControlPacket"; + j["value"] = *packet; + } + } + + static void from_json(const json& j, std::unique_ptr& packet) { + auto protocol_version = j["protocol_version"].template get(); + if (protocol_version != kPacketApiVersion) { + throw std::runtime_error("Cannot process packets different API version."); + } + + auto key = j["key"].template get(); + + if (key == "LogicalLinkControlPacket") { + packet = std::make_unique(j["value"].template get()); + } else if (key == "MobileLinkEntityPacket") { + packet = std::make_unique(j["value"].template get()); + } else if (key == "MobileManagementPacket") { + packet = std::make_unique(j["value"].template get()); + } else if (key == "CircuitModeControlEntityPacket") { + packet = + std::make_unique(j["value"].template get()); + } else if (key == "ShortDataServicePacket") { + packet = std::make_unique(j["value"].template get()); + } else { + throw std::runtime_error("Unknown packet type: " + key); + } + } +}; +} // namespace nlohmann diff --git a/src/borzoi/borzoi_converter.cpp b/src/borzoi/borzoi_converter.cpp index 28e0c94..95ffc89 100644 --- a/src/borzoi/borzoi_converter.cpp +++ b/src/borzoi/borzoi_converter.cpp @@ -20,41 +20,6 @@ inline static auto get_time() -> std::string { return ss.str(); } -auto BorzoiConverter::to_json(const std::unique_ptr& packet) -> nlohmann::json { - nlohmann::json data = nlohmann::json::object(); - - data["protocol_version"] = BorzoiConverter::kPacketApiVersion; - data["time"] = get_time(); - - if (auto* mle = dynamic_cast(packet.get())) { - if (auto* cmce = dynamic_cast(mle)) { - if (auto* sds = dynamic_cast(mle)) { - // Emit ShortDataServicePacket packet to json - data["key"] = "ShortDataServicePacket"; - data["value"] = *sds; - } else { - // Emit CircuitModeControlEntityPacket packet to json - data["key"] = "CircuitModeControlEntityPacket"; - data["value"] = *cmce; - } - } else if (auto* mm = dynamic_cast(mle)) { - // Emit MobileManagementPacket packet to json - data["key"] = "MobileManagementPacket"; - data["value"] = *mm; - } else { - // Emit MobileLinkEntityPacket packet to json - data["key"] = "MobileLinkEntityPacket"; - data["value"] = *mle; - } - } else { - // Emit LogicalLinkControlPacket packet to json - data["key"] = "LogicalLinkControlPacket"; - data["value"] = *packet; - } - - return data; -} - auto BorzoiConverter::to_json(const Slots& slots) -> nlohmann::json { auto message = nlohmann::json::object(); diff --git a/src/borzoi/borzoi_sender.cpp b/src/borzoi/borzoi_sender.cpp index d6a354c..8e562df 100644 --- a/src/borzoi/borzoi_sender.cpp +++ b/src/borzoi/borzoi_sender.cpp @@ -13,6 +13,7 @@ #include "l3/mobile_link_entity_packet.hpp" #include "l3/mobile_management_packet.hpp" #include "l3/short_data_service_packet.hpp" +#include "nlohmann_std_unique_ptr_logical_link_control_packet.hpp" // IWYU pragma: keep #include #include #include @@ -41,7 +42,7 @@ BorzoiSender::BorzoiSender(ThreadSafeFifo& packet) { - nlohmann::json json = BorzoiConverter::to_json(packet); + nlohmann::json json = packet; cpr::Response resp = cpr::Post(borzoi_url_sds_, cpr::Body{json.dump()}, cpr::Header{{"Content-Type", "application/json"}});