Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement metrics for the Upper MAC #17

Merged
merged 33 commits into from
Jun 19, 2024
Merged
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
2178116
add gauge metrics for the current network time
marenz2569 Jun 13, 2024
273d290
make LowerMacPrometheusCounters constructor explicit
marenz2569 Jun 13, 2024
d59f4ef
Slots: move code to cpp file
marenz2569 Jun 14, 2024
6492cdd
add nolint
marenz2569 Jun 14, 2024
00e8ac2
fix typo in SignallingChannel. add prometheus interface for upper mac…
marenz2569 Jun 14, 2024
475a915
make more function in Slots const. implement decoder error metrics. i…
marenz2569 Jun 14, 2024
183b6ed
fix decode error metric logic
marenz2569 Jun 14, 2024
b1b5881
smaller refactoring. upper mac runs as own thread. a message queue be…
marenz2569 Jun 14, 2024
61d359e
implement code to send the termination token to the upper mac thread
marenz2569 Jun 14, 2024
82feb25
add upper mac processing cpp file
marenz2569 Jun 14, 2024
363c089
support fragmentation over stealing channel
marenz2569 Jun 15, 2024
daeae89
remove debug prints
marenz2569 Jun 15, 2024
a76dd8a
metrics: add packet counter for the upper mac
marenz2569 Jun 15, 2024
8b03b30
rebuild fragmentation with state machine. add metrics for fragmentation.
marenz2569 Jun 15, 2024
ed9ad4a
refactor c plane signalling parsing
marenz2569 Jun 16, 2024
cc3d1e0
add c-plane packet counters
marenz2569 Jun 16, 2024
6cc4df7
split upper mac metrics into its own file
marenz2569 Jun 16, 2024
191c3c1
split lower mac metrics into its own file
marenz2569 Jun 16, 2024
6eca7f6
add docs for the metrics
marenz2569 Jun 16, 2024
8b092f3
add decode error metrics on upper layer errors
marenz2569 Jun 16, 2024
282557f
refactor upper layers
marenz2569 Jun 16, 2024
19bf16d
refactor some error handling
marenz2569 Jun 16, 2024
ce371b3
fix assert warning
marenz2569 Jun 16, 2024
ddbd97a
add counters for logical link control
marenz2569 Jun 16, 2024
d4daa4e
use constants
marenz2569 Jun 16, 2024
dafed2c
refactor upper mac, c-plane and logical link control packet counters
marenz2569 Jun 17, 2024
e6e129e
add metrics for CMCE, MM and MLE.
marenz2569 Jun 17, 2024
6174be1
fix refactored metrics
marenz2569 Jun 17, 2024
b73af85
fix refactored metrics
marenz2569 Jun 17, 2024
32b4efc
add sds metrics
marenz2569 Jun 17, 2024
1434568
fix size of sds pdu description array
marenz2569 Jun 17, 2024
b73720d
update docs for sds metrics
marenz2569 Jun 17, 2024
50b3d7c
sds fix sds data length
marenz2569 Jun 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -9,7 +9,6 @@ add_executable(tetra-decoder
src/main.cpp
src/reporter.cpp
src/decoder.cpp
src/streaming_ordered_output_thread_pool_executor.cpp
src/bit_stream_decoder.cpp
src/iq_stream_decoder.cpp
src/prometheus.cpp
@@ -19,6 +18,7 @@ add_executable(tetra-decoder
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
17 changes: 17 additions & 0 deletions docs/metrics.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Metrics

This TETRA reception stack comes with a lot of usefull metrics for monitoring the health and troughput of a cell.
All metrics are available through a prometheus exposer configurable with the command line arguments `--prometheus-address` and `--prometheus-name`.

Following metrics are supported:

| Metric name | Type | Description | Labels |
|---|---|---|---|
| `burst_received_count` | Counter | Counters for received bursts | `burst_type`: The type of received burst |
| `burst_lower_mac_decode_error_count` | Counter | Counters for decoding errors on received bursts in the lower MAC | `burst_type`: The type of received burst |
| `burst_lower_mac_mismatch_count` | Counter | Counters for mismatched number of bursts in the downlink lower MAC | `mismatch_type`: Any of `Skipped` or `Too many` |
| `lower_mac_time_gauge` | Gauge | Gauges for the network time | `type`: Any of `Synchronization Burst` or `Prediction` |
| `upper_mac_total_slot_count` | Counter | Counters for all received slots | `logical_channel`: The logical channel that is contained in the slot. |
| `upper_mac_slot_error_count` | Counter | Counters for all received slots with errors | `logical_channel`: The logical channel that is contained in the slot. `error_type`: Any of `CRC Error` or `Decode Error`. This includes errors in decoding for the upper mac or any layer on above. Errors in decoding reconstructed fragments are reported in the slot of the last fragment. |
| `upper_mac_fragment_count` | Counter | Counters for all received c-plane fragments | `type`: Any of `Continous` or `Stealing Channel`. `counter_type`: Any of `All` or `Reconstuction Error`. If there was a disallowed state transition in the reconstruction, the counter is incremented. Additional for `Stealing Channel` the counter is incremented if the fragment was not finalized across the stealing channel. |
| `protocol`_`packet_count` | Counter | Counter for all received packets in a protocol layer. | `protocol`: Any of `upper_mac`, `c_plane_signalling` (Before reconstruction. Start fragments are seperated), `logical_link_control`, `mobile_link_entity`, `circuit_mode_control_entity`, `mobile_management` or `short_data_service`. `packet_type`: The packet types of the specific protocol. |
18 changes: 12 additions & 6 deletions include/bit_stream_decoder.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:
@@ -9,11 +9,11 @@

#pragma once

#include "l2/lower_mac.hpp"
#include "streaming_ordered_output_thread_pool_executor.hpp"
#include <memory>
#include <vector>

#include <l2/lower_mac.hpp>

/**
* Tetra downlink decoder for PI/4-DQPSK modulation
*
@@ -34,8 +34,11 @@
*/
class BitStreamDecoder {
public:
BitStreamDecoder(std::shared_ptr<LowerMac> lower_mac, bool is_uplink)
: lower_mac_(std::move(lower_mac))
BitStreamDecoder(
const std::shared_ptr<StreamingOrderedOutputThreadPoolExecutor<LowerMac::return_type>>& lower_mac_worker_queue,
const std::shared_ptr<LowerMac>& lower_mac, bool is_uplink)
: lower_mac_worker_queue_(lower_mac_worker_queue)
, lower_mac_(lower_mac)
, is_uplink_(is_uplink){};
~BitStreamDecoder() = default;

@@ -53,7 +56,10 @@ class BitStreamDecoder {
void process_bit(uint8_t symbol) noexcept;

private:
std::shared_ptr<LowerMac> lower_mac_{};
/// The pointer to the worker queue
std::shared_ptr<StreamingOrderedOutputThreadPoolExecutor<LowerMac::return_type>> lower_mac_worker_queue_;

std::shared_ptr<LowerMac> lower_mac_;

bool is_synchronized_ = false;
bool is_uplink_{};
19 changes: 12 additions & 7 deletions include/decoder.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:
@@ -9,6 +9,7 @@

#pragma once

#include "l2/upper_mac.hpp"
#include <memory>
#include <optional>
#include <string>
@@ -41,16 +42,20 @@ class Decoder {
Decoder(unsigned int receive_port, unsigned int send_port, bool packed, std::optional<std::string> input_file,
std::optional<std::string> output_file, bool iq_or_bit_stream,
std::optional<unsigned int> uplink_scrambling_code,
std::shared_ptr<PrometheusExporter>& prometheus_exporter);
const std::shared_ptr<PrometheusExporter>& prometheus_exporter);
~Decoder();

void main_loop();

private:
std::shared_ptr<LowerMac> lower_mac_{};
std::shared_ptr<Reporter> reporter_{};
std::shared_ptr<BitStreamDecoder> bit_stream_decoder_{};
std::unique_ptr<IQStreamDecoder> iq_stream_decoder_{};
/// The worker queue for the lower mac
std::shared_ptr<StreamingOrderedOutputThreadPoolExecutor<LowerMac::return_type>> lower_mac_work_queue_;

/// The reference to the upper mac thread class
std::unique_ptr<UpperMac> upper_mac_;

std::shared_ptr<BitStreamDecoder> bit_stream_decoder_;
std::unique_ptr<IQStreamDecoder> iq_stream_decoder_;

bool packed_ = false;

@@ -67,5 +72,5 @@ class Decoder {
// bit stream -> false
bool iq_or_bit_stream_;

const std::size_t kRX_BUFFER_SIZE = 4096;
static const std::size_t kRX_BUFFER_SIZE = 4096;
};
15 changes: 6 additions & 9 deletions include/iq_stream_decoder.hpp
Original file line number Diff line number Diff line change
@@ -11,7 +11,6 @@

#include <complex>
#include <memory>
#include <thread>

#include <bit_stream_decoder.hpp>
#include <fixed_queue.hpp>
@@ -26,17 +25,17 @@
*/
class IQStreamDecoder {
public:
IQStreamDecoder(std::shared_ptr<LowerMac> lower_mac, std::shared_ptr<BitStreamDecoder> bit_stream_decoder,
bool is_uplink);
~IQStreamDecoder();
IQStreamDecoder(
const std::shared_ptr<StreamingOrderedOutputThreadPoolExecutor<LowerMac::return_type>>& lower_mac_worker_queue,
const std::shared_ptr<LowerMac>& lower_mac, const std::shared_ptr<BitStreamDecoder>& bit_stream_decoder,
bool is_uplink);
~IQStreamDecoder() = default;

void process_complex(std::complex<float> symbol) noexcept;

private:
using QueueT = FixedQueue<std::complex<float>, 300>;

void upperMacWorker();

static std::complex<float> hard_decision(std::complex<float> const& symbol);

template <class iterator_type> static void symbols_to_bitstream(iterator_type it, uint8_t* bits, std::size_t len);
@@ -71,7 +70,5 @@ class IQStreamDecoder {

bool is_uplink_{};

std::shared_ptr<StreamingOrderedOutputThreadPoolExecutor<std::vector<std::function<void()>>>> thread_pool_;

std::thread upper_mac_worker_thread_;
std::shared_ptr<StreamingOrderedOutputThreadPoolExecutor<LowerMac::return_type>> lower_mac_worker_queue_;
};
20 changes: 10 additions & 10 deletions include/l2/logical_channel.hpp
Original file line number Diff line number Diff line change
@@ -11,23 +11,23 @@
#include "utils/bit_vector.hpp"

enum class LogicalChannel {
kSignalingChannelHalfDownlink,
kSignalingChannelHalfUplink,
kSignallingChannelHalfDownlink,
kSignallingChannelHalfUplink,
kTrafficChannel,
kSignalingChannelFull,
kSignallingChannelFull,
kStealingChannel
};

constexpr auto to_string(LogicalChannel channel) noexcept -> const char* {
switch (channel) {
case LogicalChannel::kSignalingChannelHalfDownlink:
return "SignalingChannelHalfDownlink";
case LogicalChannel::kSignalingChannelHalfUplink:
return "SignalingChannelHalfUplink";
case LogicalChannel::kSignallingChannelHalfDownlink:
return "SignallingChannelHalfDownlink";
case LogicalChannel::kSignallingChannelHalfUplink:
return "SignallingChannelHalfUplink";
case LogicalChannel::kTrafficChannel:
return "TrafficChannel";
case LogicalChannel::kSignalingChannelFull:
return "SignalingChannelFull";
case LogicalChannel::kSignallingChannelFull:
return "SignallingChannelFull";
case LogicalChannel::kStealingChannel:
return "StealingChannel";
}
@@ -38,6 +38,6 @@ struct LogicalChannelDataAndCrc {
LogicalChannel channel;
/// the data on the logical channel
BitVector data;
/// true if the crc of the signaling channels is ok
/// true if the crc of the signalling channels is ok
bool crc_ok;
};
73 changes: 60 additions & 13 deletions include/l2/logical_link_control.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:
@@ -8,29 +8,74 @@

#pragma once

#include "l3/mobile_link_entity.hpp"
#include "utils/address.hpp"
#include "utils/bit_vector.hpp"
#include "utils/packet_counter_metrics.hpp"
#include <cstdint>
#include <iostream>
#include <memory>
#include <utility>
#include <vector>

#include <l3/mobile_link_entity.hpp>
#include <reporter.hpp>
#include <utils/address.hpp>
#include <utils/bit_vector.hpp>

class LogicalLinkControl {
public:
LogicalLinkControl(std::shared_ptr<Reporter> reporter, std::shared_ptr<MobileLinkEntity> mle)
: reporter_(std::move(reporter))
, mle_(std::move(mle)){};
LogicalLinkControl() = delete;
LogicalLinkControl(const std::shared_ptr<PrometheusExporter>& prometheus_exporter, Reporter&& reporter,
bool is_downlink)
: mle_(prometheus_exporter, std::move(reporter), is_downlink) {
llc_pdu_description_ = {"BL-ADATA without FCS",
"BL-DATA without FCS",
"BL-UDATA without FCS",
"BL-ACK without FCS",
"BL-ADATA with FCS",
"BL-DATA with FCS",
"BL-UDATA with FCS",
"BL-ACK with FCS",
"AL-SETUP",
"AL-DATA/AL-DATA-AR/AL-FINAL/AL-FINAL-AR",
"AL-UDATA/AL-UFINAL",
"AL-ACK/AL-RNR",
"AL-RECONNECT",
"Supplementary LLC PDU",
"Layer 2 signalling PDU",
"AL-DISC"};
supplementary_llc_pdu_description_ = {"AL-X-DATA/AL-X-DATA-AR/AL-X-FINAL/AL-X-FINAL-AR",
"AL-X-UDATA/AL-X-UFINAL", "AL-X-ACK/AL-X-RNR",
"ReservedSupplementaryLlcPdu"};
layer_2_signalling_pdu_description_ = {"L2-DATA-PRIORITY",
"L2-SCHEDULE-SYNC",
"L2-LINK-FEEDBACK-CONTROL",
"L2-LINK-FEEDBACK-INFO",
"L2-LINK-FEEDBACK-INFO-AND-RESIDUAL-DATA-PRIORITY",
"ReservedLayer2SignallingPdu5",
"ReservedLayer2SignallingPdu6",
"ReservedLayer2SignallingPdu7",
"ReservedLayer2SignallingPdu8",
"ReservedLayer2SignallingPdu9",
"ReservedLayer2SignallingPdu10",
"ReservedLayer2SignallingPdu11",
"ReservedLayer2SignallingPdu12",
"ReservedLayer2SignallingPdu13",
"ReservedLayer2SignallingPdu14",
"ReservedLayer2SignallingPdu15"};
if (prometheus_exporter) {
metrics_ = std::make_unique<PacketCounterMetrics>(prometheus_exporter, "logical_link_control");
}
};
~LogicalLinkControl() noexcept = default;

void process(Address address, BitVector& vec);

friend auto operator<<(std::ostream& stream, const LogicalLinkControl& llc) -> std::ostream&;

private:
static const auto kSupplementaryLlcPdu = 13;
static const auto kLayer2SignallingPdu = 14;

std::array<std::string, 16> llc_pdu_description_;
std::array<std::string, 4> supplementary_llc_pdu_description_;
std::array<std::string, 16> layer_2_signalling_pdu_description_;

// Basic link (acknowledged service in connectionless mode) without Frame Check Sequence
void process_bl_adata_without_fcs(Address address, BitVector& vec);
// Basic link (acknowledged service in connectionless mode) without Frame Check Sequence
@@ -46,12 +91,14 @@ class LogicalLinkControl {
void process_bl_ack_with_fcs(Address address, BitVector& vec);

void process_supplementary_llc_pdu(Address address, BitVector& vec);
void process_layer_2_signalling_pdu(Address address, BitVector& vec);

static auto compute_fcs(std::vector<uint8_t> const& data) -> uint32_t;
static auto check_fcs(BitVector& vec) -> bool;

std::shared_ptr<Reporter> reporter_{};
std::shared_ptr<MobileLinkEntity> mle_{};
MobileLinkEntity mle_;

std::unique_ptr<PacketCounterMetrics> metrics_;
};

std::ostream& operator<<(std::ostream& stream, const LogicalLinkControl& llc);
auto operator<<(std::ostream& stream, const LogicalLinkControl& llc) -> std::ostream&;
Loading