Skip to content

Commit

Permalink
rebuild fragmentation and integrate into upper mac
Browse files Browse the repository at this point in the history
  • Loading branch information
marenz2569 committed Jun 12, 2024
1 parent 94aa9a5 commit 72c947c
Show file tree
Hide file tree
Showing 9 changed files with 104 additions and 152 deletions.
1 change: 0 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ add_executable(tetra-decoder
src/l2/timebase_counter.cpp
src/l2/upper_mac_packet.cpp
src/l2/upper_mac_packet_builder.cpp
src/l2/upper_mac_fragmentation.cpp
src/l3/mobile_link_entity.cpp
src/l3/mobile_management.cpp
src/l3/circuit_mode_control_entity.cpp
Expand Down
58 changes: 29 additions & 29 deletions include/l2/upper_mac.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2022 Transit Live Mapping Solutions
* Copyright (C) 2022-2024 Transit Live Mapping Solutions
* All rights reserved.
*
* Authors:
Expand All @@ -9,18 +9,17 @@

#pragma once

#include "l2/upper_mac_fragments.hpp"
#include "l2/upper_mac_packet.hpp"
#include "l2/upper_mac_packet_builder.hpp"
#include "utils/bit_vector.hpp"
#include <cstdint>
#include <memory>
#include <optional>
#include <unordered_map>
#include <utility>
#include <vector>

#include <burst_type.hpp>
#include <l2/logical_link_control.hpp>
#include <l3/mobile_link_entity.hpp>
#include <memory>
#include <optional>
#include <reporter.hpp>
#include <utility>
#include <utils/address_type.hpp>

class UpperMac {
Expand All @@ -32,27 +31,28 @@ class UpperMac {
, logical_link_control_(std::make_unique<LogicalLinkControl>(reporter_, mobile_link_entity_)){};
~UpperMac() noexcept = default;

private:
std::shared_ptr<Reporter> reporter_{};
auto process(UpperMacPackets&& packets) -> void {
for (const auto& packet : packets.c_plane_signalling_packets_) {
// TODO: handle fragmentation over STCH
if ((packet.type_ == MacPacketType::kMacResource && packet.fragmentation_) ||
(packet.type_ == MacPacketType::kMacFragmentDownlink) ||
(packet.type_ == MacPacketType::kMacEndDownlink)) {
auto reconstructed_fragment = fragmentation_.push_fragment(packet);
if (reconstructed_fragment) {
auto data = BitVector(*reconstructed_fragment->tm_sdu_);
logical_link_control_->process(reconstructed_fragment->address_, data);
}
} else if (packet.tm_sdu_) {
auto data = BitVector(*packet.tm_sdu_);
logical_link_control_->process(packet.address_, data);
}
}
};

// fragmentation
// XXX: might have to delay processing as SSI may only be known after the Null PDU
void fragmentation_start_burst();
void fragmentation_end_burst();
void fragmentation_push_tm_sdu_start(AddressType address_type, BitVector& vec);
void fragmentation_push_tm_sdu_frag(BitVector& vec);
void fragmentation_push_tm_sdu_end(BitVector& vec);
void fragmentation_push_tm_sdu_end_hu(BitVector& vec);

std::shared_ptr<MobileLinkEntity> mobile_link_entity_{};
std::unique_ptr<LogicalLinkControl> logical_link_control_{};
private:
std::shared_ptr<Reporter> reporter_;
std::shared_ptr<MobileLinkEntity> mobile_link_entity_;
std::unique_ptr<LogicalLinkControl> logical_link_control_;

// hashmap to keep track of framented mac segments
std::unordered_map<AddressType, std::vector<BitVector>> fragment_map_ = {};
std::vector<BitVector> fragment_list_{};
bool fragment_end_received_{};
bool fragment_end_hu_received_{};
AddressType last_address_type_{};
// save the last MAC-ACCESS or MAC-DATA where reservation_requirement is 0b0000 (1 sublot) for END-HU
AddressType last_address_type_end_hu_{};
UpperMacFragmentation fragmentation_;
};
5 changes: 5 additions & 0 deletions include/l2/upper_mac_packet.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,11 @@ struct UpperMacCPlaneSignallingPacket {
std::optional<unsigned _BitInt(1)> random_access_flag_;
std::optional<unsigned _BitInt(4)> power_control_element_;

/// check if this packet is a null pdu
[[nodiscard]] auto is_null_pdu() const -> bool {
return type_ == MacPacketType::kMacResource && address_ == AddressType{};
};

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

Expand Down
17 changes: 17 additions & 0 deletions include/l2/upper_mac_packet_builder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,23 @@ struct UpperMacPackets {
}
}

[[nodiscard]] auto has_user_or_control_plane_data() const -> bool {
for (const auto& packet : c_plane_signalling_packets_) {
if (packet.is_null_pdu()) {
// filter out null pdus
continue;
}
return true;
}
if (u_plane_signalling_packet_.size() > 0) {
return true;
}
if (u_plane_traffic_packet_) {
return true;
}
return false;
};

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

Expand Down
2 changes: 1 addition & 1 deletion include/utils/address_type.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class AddressType {
AddressType() = default;

// explicit operator bool() const = delete;
constexpr bool operator==(AddressType address_type) const {
constexpr auto operator==(AddressType address_type) const -> bool {
return country_code_ == address_type.country_code_ && network_code_ == address_type.network_code_ &&
sna_ == address_type.sna_ && ssi_ == address_type.ssi_ && event_label_ == address_type.event_label_ &&
ussi_ == address_type.ussi_ && smi_ == address_type.smi_ && usage_marker_ == address_type.usage_marker_;
Expand Down
16 changes: 13 additions & 3 deletions src/l2/lower_mac.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -330,14 +330,24 @@ auto LowerMac::process(const std::vector<uint8_t>& frame, BurstType burst_type)
// check if we have crc decode errors in the lower mac
decode_error |= slots.has_crc_error();

callbacks.emplace_back([slots_ref = slots] {
callbacks.emplace_back([this, slots_ref = slots] {
auto slots = Slots(slots_ref);
std::cout << slots;
UpperMacPackets packets;
try {
auto packets = UpperMacPacketBuilder::parseSlots(slots);
std::cout << packets << std::endl;
packets = UpperMacPacketBuilder::parseSlots(slots);
if (packets.has_user_or_control_plane_data()) {
std::cout << packets << std::endl;
}
} catch (std::runtime_error& e) {
std::cout << "Error decoding packets: " << e.what() << std::endl;
return;
}
try {
upper_mac_->process(std::move(packets));

} catch (std::runtime_error& e) {
std::cout << "Error decoding in upper mac: " << e.what() << std::endl;
}
});
}
Expand Down
111 changes: 0 additions & 111 deletions src/l2/upper_mac_fragmentation.cpp

This file was deleted.

38 changes: 31 additions & 7 deletions src/l2/upper_mac_packet_builder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,22 @@
#include "l2/upper_mac_packet_builder.hpp"
#include "burst_type.hpp"
#include "l2/logical_channel.hpp"
#include "l2/slot.hpp"
#include "l2/upper_mac_packet.hpp"
#include "utils/address_type.hpp"
#include "utils/bit_vector.hpp"
#include <cstddef>
#include <optional>
#include <ostream>
#include <stdexcept>

auto operator<<(std::ostream& stream, const UpperMacPackets& packets) -> std::ostream& {
stream << "[UpperMacPacket]" << std::endl;
for (const auto& packet : packets.c_plane_signalling_packets_) {
if (packet.is_null_pdu()) {
// filter out null pdus
continue;
}
stream << packet << std::endl;
}
for (const auto& packet : packets.u_plane_signalling_packet_) {
Expand Down Expand Up @@ -723,7 +730,7 @@ auto UpperMacPacketBuilder::parseCPlaneSignallingPacket(BurstType burst_type, Lo
}
}

auto tm_sdu = data.take_vector(bits_left);
packet.tm_sdu_ = data.take_vector(bits_left);

return packet;
}
Expand Down Expand Up @@ -778,19 +785,36 @@ auto UpperMacPacketBuilder::parseCPlaneSignalling(const BurstType burst_type, co

std::vector<UpperMacCPlaneSignallingPacket> packets;

while (data.bits_left() > 0) {
std::cout << data << std::endl;
// 23.4.3.3 PDU dissociation
// If the remaining size in the MAC block is less than the length of the Null PDU, the MAC shall discard the
// remaining bits.
// NOTE 2: The size of the appropriate Null PDU (as used above) is 16 bits for the downlink, 36 bits for an uplink
// subslot, or 37 bits for an uplink full slot or uplink STCH.
std::size_t min_bit_count = 0;
if (is_downlink_burst(burst_type)) {
min_bit_count = 16;
} else {
if (channel == LogicalChannel::kSignalingChannelHalfUplink) {
min_bit_count = 36;
} else if (channel == LogicalChannel::kSignalingChannelFull || channel == LogicalChannel::kStealingChannel) {
min_bit_count = 37;
}
}

while (data.bits_left() >= min_bit_count) {
if (data.is_mac_padding()) {
std::cout << "Found padding, skipping: " << data << std::endl;
break;
}
auto packet = parseCPlaneSignallingPacket(burst_type, channel, data);
std::cout << packet;
packets.emplace_back(std::move(packet));
}

// TODO: one mac may contain multiple mac headers. proccess all the others
// layers first and then continue with the next
// The Null PDU indicates that there is no more useful data in this MAC block; after receipt of the Null PDU,
// the MAC shall not look for further information in the block.
if (packets.back().is_null_pdu()) {
break;
}
}
return packets;
}

Expand Down
8 changes: 8 additions & 0 deletions src/l3/mobile_link_entity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ void MobileLinkEntity::service_user_pdu(const AddressType address, BitVector& ve
"TETRA management entity protocol",
"Reserved for testing"};

if (vec.bits_left() == 0) {
return;
}

auto pdu_type = vec.take<3>();

std::cout << "MLE " << mle_pdu[pdu_type] << " " << vec << std::endl;
Expand Down Expand Up @@ -61,6 +65,10 @@ void MobileLinkEntity::service_data_pdu(const AddressType address, BitVector& ve
"Reserved", "Reserved", "Reserved", "Reserved", "Reserved", "Reserved", "Reserved", "Reserved",
};

if (vec.bits_left() == 0) {
return;
}

auto pdu_type = vec.take<3>();

std::cout << " " << mle_uplink_pdu_type[pdu_type] << " or " << mle_downlink_pdu_type[pdu_type] << std::endl;
Expand Down

0 comments on commit 72c947c

Please sign in to comment.