Skip to content

Commit

Permalink
fix from_json implementation for std::unique_ptr<LogicalLinkControlPa…
Browse files Browse the repository at this point in the history
…cket>. fix std variant from_json. add example for downloaded csv back to packets. add print function for std::unique_ptr<LogicalLinkControlPacket>.
  • Loading branch information
marenz2569 committed Jul 31, 2024
1 parent e83f72d commit e7bd52f
Show file tree
Hide file tree
Showing 15 changed files with 302 additions and 71 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
[submodule "lib/ViterbiDecoderCpp"]
path = lib/ViterbiDecoderCpp
url = https://github.com/FiendChain/ViterbiDecoderCpp.git
[submodule "lib/rapidcsv"]
path = lib/rapidcsv
url = https://github.com/d99kris/rapidcsv.git
71 changes: 39 additions & 32 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,36 +5,38 @@ set(CMAKE_CXX_STANDARD 17)

option(NIX_BUILD "Is CMake called by a nix build?" OFF)

add_library(tetra-decoder-library
src/decoder.cpp
src/bit_stream_decoder.cpp
src/iq_stream_decoder.cpp
src/prometheus.cpp
src/borzoi/borzoi_packets.cpp
src/borzoi/borzoi_sender.cpp
src/l2/access_assignment_channel.cpp
src/l2/broadcast_synchronization_channel.cpp
src/l2/logical_link_control_formatter.cpp
src/l2/logical_link_control_packet.cpp
src/l2/lower_mac.cpp
src/l2/slot.cpp
src/l2/timebase_counter.cpp
src/l2/upper_mac.cpp
src/l2/upper_mac_packet.cpp
src/l2/upper_mac_packet_builder.cpp
src/l2/upper_mac_packet_formatter.cpp
src/l3/circuit_mode_control_entity_formatter.cpp
src/l3/circuit_mode_control_entity_packet.cpp
src/l3/mobile_link_entity_formatter.cpp
src/l3/mobile_link_entity_packet.cpp
src/l3/mobile_management_formatter.cpp
src/l3/mobile_management_packet.cpp
src/l3/short_data_service_formatter.cpp
src/l3/short_data_service_packet.cpp
src/utils/address.cpp
src/utils/bit_vector.cpp
src/utils/viter_bi_codec.cpp)

add_executable(tetra-decoder
src/main.cpp
src/decoder.cpp
src/bit_stream_decoder.cpp
src/iq_stream_decoder.cpp
src/prometheus.cpp
src/borzoi/borzoi_packets.cpp
src/borzoi/borzoi_sender.cpp
src/l2/access_assignment_channel.cpp
src/l2/broadcast_synchronization_channel.cpp
src/l2/logical_link_control_formatter.cpp
src/l2/logical_link_control_packet.cpp
src/l2/lower_mac.cpp
src/l2/slot.cpp
src/l2/timebase_counter.cpp
src/l2/upper_mac.cpp
src/l2/upper_mac_packet.cpp
src/l2/upper_mac_packet_builder.cpp
src/l2/upper_mac_packet_formatter.cpp
src/l3/circuit_mode_control_entity_formatter.cpp
src/l3/circuit_mode_control_entity_packet.cpp
src/l3/mobile_link_entity_formatter.cpp
src/l3/mobile_link_entity_packet.cpp
src/l3/mobile_management_formatter.cpp
src/l3/mobile_management_packet.cpp
src/l3/short_data_service_formatter.cpp
src/l3/short_data_service_packet.cpp
src/utils/address.cpp
src/utils/bit_vector.cpp
src/utils/viter_bi_codec.cpp)
src/main.cpp)

add_executable(tetra-puncturing
src/examples/tetra_puncturing.cpp)
Expand All @@ -43,11 +45,13 @@ add_executable(tetra-viterbi
src/examples/viter_bi_codec.cpp
src/examples/tetra_viterbi.cpp)

target_compile_options(tetra-decoder PUBLIC -std=c++17 -Wall -Wno-unused-variable -msse4.1 -O3 -fcolor-diagnostics)
target_compile_options(tetra-decoder-library PUBLIC -std=c++17 -Wall -Wno-unused-variable -msse4.1 -O3 -fcolor-diagnostics)
target_compile_options(tetra-decoder PUBLIC -std=c++17 -Wall -Wno-unused-variable)
target_compile_options(tetra-puncturing PUBLIC -std=c++17 -Wall -Wno-unused-variable)
target_compile_options(tetra-viterbi PUBLIC -std=c++17 -Wall -Wno-unused-variable)

include(lib/ViterbiDecoderCpp/viterbi-config.cmake)
include_directories(lib/rapidcsv/src)

include_directories(src)

Expand All @@ -61,12 +65,15 @@ find_package(cpr REQUIRED)
include_directories(${CMAKE_SOURCE_DIR}/include)

if (NOT NIX_BUILD)
target_link_libraries(tetra-decoder cxxopts::cxxopts)
target_link_libraries(tetra-decoder-library cxxopts::cxxopts)
endif()

target_link_libraries(tetra-decoder ZLIB::ZLIB fmt::fmt nlohmann_json::nlohmann_json viterbi prometheus-cpp::pull cpr::cpr)
target_link_libraries(tetra-decoder-library ZLIB::ZLIB fmt::fmt nlohmann_json::nlohmann_json viterbi prometheus-cpp::pull cpr::cpr)
target_link_libraries(tetra-decoder tetra-decoder-library)
target_link_libraries(tetra-viterbi viterbi)

install(TARGETS tetra-decoder DESTINATION bin)
install(TARGETS tetra-puncturing DESTINATION bin)
install(TARGETS tetra-viterbi DESTINATION bin)

include(src/experiments/CMakeLists.txt)
38 changes: 37 additions & 1 deletion include/borzoi/borzoi_packets.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,53 @@ struct BorzoiSendTetraPacket {
std::string station;
const std::unique_ptr<LogicalLinkControlPacket>& packet;

BorzoiSendTetraPacket() = delete;

/// Construct a packet for Borzoi containing the parsed packet, the current time and the uuid of this instance of
/// tetra decoder.
BorzoiSendTetraPacket(const std::unique_ptr<LogicalLinkControlPacket>& packet, std::string borzoi_uuid);

friend auto operator<<(std::ostream& stream, const BorzoiSendTetraPacket& packet) -> std::ostream&;
};

auto operator<<(std::ostream& stream, const BorzoiSendTetraPacket& packet) -> std::ostream&;

struct BorzoiReceiveTetraPacket {
std::string time;
std::string station;
std::unique_ptr<LogicalLinkControlPacket> packet;

BorzoiReceiveTetraPacket() = default;

friend auto operator<<(std::ostream& stream, const BorzoiReceiveTetraPacket& packet) -> std::ostream&;
};

auto operator<<(std::ostream& stream, const BorzoiReceiveTetraPacket& packet) -> std::ostream&;

struct BorzoiSendTetraSlots {
std::string time;
std::string station;
const Slots& slots;

BorzoiSendTetraSlots() = delete;

/// Construct a packet for Borzoi containing the received slot, the current time and the uuid of this instance of
/// tetra decoder.
BorzoiSendTetraSlots(const Slots& slots, std::string borzoi_uuid);
};

friend auto operator<<(std::ostream& stream, const BorzoiSendTetraSlots& packet) -> std::ostream&;
};

auto operator<<(std::ostream& stream, const BorzoiSendTetraSlots& packet) -> std::ostream&;

struct BorzoiReceiveTetraSlots {
std::string time;
std::string station;
Slots slots;

BorzoiReceiveTetraSlots() = default;

friend auto operator<<(std::ostream& stream, const BorzoiReceiveTetraSlots& packet) -> std::ostream&;
};

auto operator<<(std::ostream& stream, const BorzoiReceiveTetraSlots& packet) -> std::ostream&;
23 changes: 23 additions & 0 deletions include/nlohmann/borzoi_receive_tetra_packet.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright (C) 2024 Transit Live Mapping Solutions
* All rights reserved.
*
* Authors:
* Marenz Schmidl
*/

#pragma once

#include "borzoi/borzoi_packets.hpp"
#include "nlohmann/std_unique_ptr_logical_link_control_packet.hpp"
#include <nlohmann/json.hpp>

namespace nlohmann {
template <> struct adl_serializer<BorzoiReceiveTetraPacket> {
static void from_json(const json& j, BorzoiReceiveTetraPacket& brtp) {
brtp.time = j["time"];
brtp.station = j["station"];
adl_serializer<std::unique_ptr<LogicalLinkControlPacket>>::from_json(j, brtp.packet);
}
};
} // namespace nlohmann
23 changes: 23 additions & 0 deletions include/nlohmann/borzoi_receive_tetra_slots.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright (C) 2024 Transit Live Mapping Solutions
* All rights reserved.
*
* Authors:
* Marenz Schmidl
*/

#pragma once

#include "borzoi/borzoi_packets.hpp"
#include "nlohmann/slots.hpp"
#include <nlohmann/json.hpp>

namespace nlohmann {
template <> struct adl_serializer<BorzoiReceiveTetraSlots> {
static void from_json(const json& j, BorzoiReceiveTetraSlots& brtp) {
brtp.time = j["time"];
brtp.station = j["station"];
adl_serializer<Slots>::from_json(j, brtp.slots);
}
};
} // namespace nlohmann
12 changes: 6 additions & 6 deletions include/nlohmann/std_unique_ptr_logical_link_control_packet.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ template <> struct adl_serializer<std::unique_ptr<LogicalLinkControlPacket>> {
}

static void from_json(const json& j, std::unique_ptr<LogicalLinkControlPacket>& packet) {
auto protocol_version = j["protocol_version"].template get<int>();
auto protocol_version = std::stoi(j["protocol_version"].template get<std::string>());
if (protocol_version != kPacketApiVersion) {
throw std::runtime_error("Cannot process packets different API version.");
}
Expand All @@ -60,14 +60,14 @@ template <> struct adl_serializer<std::unique_ptr<LogicalLinkControlPacket>> {
if (key == "LogicalLinkControlPacket") {
packet = std::make_unique<LogicalLinkControlPacket>(j["value"].template get<LogicalLinkControlPacket>());
} else if (key == "MobileLinkEntityPacket") {
packet = std::make_unique<LogicalLinkControlPacket>(j["value"].template get<MobileLinkEntityPacket>());
packet = std::make_unique<MobileLinkEntityPacket>(j["value"].template get<MobileLinkEntityPacket>());
} else if (key == "MobileManagementPacket") {
packet = std::make_unique<LogicalLinkControlPacket>(j["value"].template get<MobileManagementPacket>());
packet = std::make_unique<MobileManagementPacket>(j["value"].template get<MobileManagementPacket>());
} else if (key == "CircuitModeControlEntityPacket") {
packet =
std::make_unique<LogicalLinkControlPacket>(j["value"].template get<CircuitModeControlEntityPacket>());
packet = std::make_unique<CircuitModeControlEntityPacket>(
j["value"].template get<CircuitModeControlEntityPacket>());
} else if (key == "ShortDataServicePacket") {
packet = std::make_unique<LogicalLinkControlPacket>(j["value"].template get<ShortDataServicePacket>());
packet = std::make_unique<ShortDataServicePacket>(j["value"].template get<ShortDataServicePacket>());
} else {
throw std::runtime_error("Unknown packet type: " + key);
}
Expand Down
5 changes: 3 additions & 2 deletions include/nlohmann/std_variant.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,9 @@ template <typename... Ts> struct adl_serializer<std::variant<Ts...>> {
var = std::variant<Ts...>(typename std::tuple_element<3, std::tuple<Ts...>>::type(variant));
}
}

throw std::runtime_error("Cannot deserialize a std::variant with more than four variants.");
if constexpr (sizeof...(Ts) > 4) {
throw std::runtime_error("Cannot deserialize a std::variant with more than four variants.");
}
}
};
} // namespace nlohmann
36 changes: 36 additions & 0 deletions include/utils/ostream_std_unique_ptr_logical_link_control.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright (C) 2024 Transit Live Mapping Solutions
* All rights reserved.
*
* Authors:
* Marenz Schmidl
*/

#pragma once

#include "l3/mobile_link_entity_packet.hpp"
#include "l3/mobile_management_packet.hpp"
#include "l3/short_data_service_packet.hpp"

inline auto operator<<(std::ostream& stream, const std::unique_ptr<LogicalLinkControlPacket>& packet) -> std::ostream& {
/// process the parsed packet
auto* cplane_signalling = dynamic_cast<UpperMacCPlaneSignallingPacket*>(packet.get());
auto* llc = dynamic_cast<LogicalLinkControlPacket*>(cplane_signalling);

stream << *cplane_signalling;
stream << *llc;
if (auto* mle = dynamic_cast<MobileLinkEntityPacket*>(llc)) {
stream << *mle;
if (auto* cmce = dynamic_cast<CircuitModeControlEntityPacket*>(llc)) {
stream << *cmce;
if (auto* sds = dynamic_cast<ShortDataServicePacket*>(llc)) {
stream << *sds;
}
}
if (auto* mm = dynamic_cast<MobileManagementPacket*>(llc)) {
stream << *mm;
}
}

return stream;
}
1 change: 1 addition & 0 deletions lib/rapidcsv
Submodule rapidcsv added at f438d3
31 changes: 30 additions & 1 deletion src/borzoi/borzoi_packets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*/

#include "borzoi/borzoi_packets.hpp"
#include "utils/ostream_std_unique_ptr_logical_link_control.hpp"

inline static auto get_time() -> std::string {
auto t = std::time(nullptr);
Expand All @@ -27,4 +28,32 @@ BorzoiSendTetraSlots::BorzoiSendTetraSlots(const Slots& slots, std::string borzo
: station(std::move(borzoi_uuid))
, slots(slots) {
time = get_time();
}
}

auto operator<<(std::ostream& stream, const BorzoiSendTetraPacket& packet) -> std::ostream& {
stream << packet.time << std::endl;
stream << packet.station << std::endl;
stream << packet.packet << std::endl;
return stream;
};

auto operator<<(std::ostream& stream, const BorzoiReceiveTetraPacket& packet) -> std::ostream& {
stream << packet.time << std::endl;
stream << packet.station << std::endl;
stream << packet.packet << std::endl;
return stream;
};

auto operator<<(std::ostream& stream, const BorzoiSendTetraSlots& packet) -> std::ostream& {
stream << packet.time << std::endl;
stream << packet.station << std::endl;
stream << packet.slots << std::endl;
return stream;
};

auto operator<<(std::ostream& stream, const BorzoiReceiveTetraSlots& packet) -> std::ostream& {
stream << packet.time << std::endl;
stream << packet.station << std::endl;
stream << packet.slots << std::endl;
return stream;
};
37 changes: 8 additions & 29 deletions src/borzoi/borzoi_sender.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,9 @@

#include "borzoi/borzoi_sender.hpp"
#include "borzoi/borzoi_packets.hpp"
#include "l2/upper_mac_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 "nlohmann/borzoi_send_tetra_packet.hpp" // IWYU pragma: keep
#include "nlohmann/borzoi_send_tetra_slots.hpp" // IWYU pragma: keep
#include "nlohmann/borzoi_send_tetra_packet.hpp" // IWYU pragma: keep
#include "nlohmann/borzoi_send_tetra_slots.hpp" // IWYU pragma: keep
#include "utils/ostream_std_unique_ptr_logical_link_control.hpp" // IWYU pragma: keep
#include <cpr/body.h>
#include <cpr/cprtypes.h>
#include <cpr/payload.h>
Expand Down Expand Up @@ -81,32 +77,15 @@ void BorzoiSender::worker() {
[this](const auto& arg) {
using T = std::decay_t<decltype(arg)>;
if constexpr (std::is_same_v<T, std::unique_ptr<LogicalLinkControlPacket>>) {
/// process the parsed packet
auto* cplane_signalling = dynamic_cast<UpperMacCPlaneSignallingPacket*>(arg.get());
auto* llc = dynamic_cast<LogicalLinkControlPacket*>(cplane_signalling);
send_packet(arg);

// Do not log acknowledgements
if (llc->basic_link_information_ &&
(llc->basic_link_information_->basic_link_type_ == BasicLinkType::kBlAckWithoutFcs ||
llc->basic_link_information_->basic_link_type_ == BasicLinkType::kBlAckWithFcs)) {
if (arg->basic_link_information_ &&
(arg->basic_link_information_->basic_link_type_ == BasicLinkType::kBlAckWithoutFcs ||
arg->basic_link_information_->basic_link_type_ == BasicLinkType::kBlAckWithFcs)) {
return;
}
std::cout << *cplane_signalling;
std::cout << *llc;
if (auto* mle = dynamic_cast<MobileLinkEntityPacket*>(llc)) {
std::cout << *mle;
if (auto* cmce = dynamic_cast<CircuitModeControlEntityPacket*>(llc)) {
std::cout << *cmce;
if (auto* sds = dynamic_cast<ShortDataServicePacket*>(llc)) {
std::cout << *sds;
}
}
if (auto* mm = dynamic_cast<MobileManagementPacket*>(llc)) {
std::cout << *mm;
}
std::cout << std::endl;
}
send_packet(arg);
std::cout << arg << std::endl;
} else if constexpr (std::is_same_v<T, Slots>) {
/// send out the slots which had an error while parsing
send_failed_slots(arg);
Expand Down
1 change: 1 addition & 0 deletions src/experiments/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.csv
Loading

0 comments on commit e7bd52f

Please sign in to comment.