mirror of https://github.com/PentHertz/srsLTE.git
RLC AM NR: Added some logging functions to better debug the state and the received headers. Added initial handling of data pdu. Updating rx_next and rx_status_highest now.
This commit is contained in:
parent
2d29e4005c
commit
8ae4d379aa
|
@ -111,6 +111,13 @@ public:
|
||||||
uint32_t get_status_pdu(rlc_am_nr_status_pdu_t* status, uint32_t len);
|
uint32_t get_status_pdu(rlc_am_nr_status_pdu_t* status, uint32_t len);
|
||||||
uint32_t get_status_pdu_length();
|
uint32_t get_status_pdu_length();
|
||||||
|
|
||||||
|
// Data handling methods
|
||||||
|
void handle_data_pdu_full(uint8_t* payload, uint32_t nof_bytes, rlc_am_nr_pdu_header_t& header);
|
||||||
|
bool inside_rx_window(uint32_t sn);
|
||||||
|
|
||||||
|
// Helpers
|
||||||
|
void debug_state();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
rlc_am* parent = nullptr;
|
rlc_am* parent = nullptr;
|
||||||
rlc_am_nr_tx* tx = nullptr;
|
rlc_am_nr_tx* tx = nullptr;
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#ifndef SRSRAN_RLC_AM_NR_PACKING_H
|
#ifndef SRSRAN_RLC_AM_NR_PACKING_H
|
||||||
#define SRSRAN_RLC_AM_NR_PACKING_H
|
#define SRSRAN_RLC_AM_NR_PACKING_H
|
||||||
|
|
||||||
|
#include "srsran/common/string_helpers.h"
|
||||||
#include "srsran/rlc/rlc_am_base.h"
|
#include "srsran/rlc/rlc_am_base.h"
|
||||||
|
|
||||||
namespace srsran {
|
namespace srsran {
|
||||||
|
@ -79,6 +80,55 @@ int32_t rlc_am_nr_write_status_pdu(const rlc_am_nr_status_pdu_t& status_pdu,
|
||||||
const rlc_am_nr_sn_size_t sn_size,
|
const rlc_am_nr_sn_size_t sn_size,
|
||||||
byte_buffer_t* pdu);
|
byte_buffer_t* pdu);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs Status PDU into provided log channel, using fmt_str as format string
|
||||||
|
*/
|
||||||
|
template <typename... Args>
|
||||||
|
void log_rlc_am_nr_status_pdu_to_string(srslog::log_channel& log_ch,
|
||||||
|
const char* fmt_str,
|
||||||
|
rlc_am_nr_status_pdu_t* status,
|
||||||
|
Args&&... args)
|
||||||
|
{
|
||||||
|
if (not log_ch.enabled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fmt::memory_buffer buffer;
|
||||||
|
fmt::format_to(buffer, "ACK_SN = {}, N_nack = {}", status->ack_sn, status->N_nack);
|
||||||
|
if (status->N_nack > 0) {
|
||||||
|
fmt::format_to(buffer, ", NACK_SN = ");
|
||||||
|
for (uint32_t i = 0; i < status->N_nack; ++i) {
|
||||||
|
if (status->nacks[i].has_so) {
|
||||||
|
fmt::format_to(
|
||||||
|
buffer, "[{} {}:{}]", status->nacks[i].nack_sn, status->nacks[i].so_start, status->nacks[i].so_end);
|
||||||
|
} else {
|
||||||
|
fmt::format_to(buffer, "[{}]", status->nacks[i].nack_sn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log_ch(fmt_str, std::forward<Args>(args)..., to_c_str(buffer));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Log NR AMD PDUs
|
||||||
|
*/
|
||||||
|
inline void log_rlc_am_nr_pdu_header_to_string(srslog::log_channel& log_ch, const rlc_am_nr_pdu_header_t& header)
|
||||||
|
{
|
||||||
|
if (not log_ch.enabled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fmt::memory_buffer buffer;
|
||||||
|
fmt::format_to(buffer,
|
||||||
|
"[{}, P={}, SI={}, SN_SIZE={}, SN={}, SO={}",
|
||||||
|
rlc_dc_field_text[header.dc],
|
||||||
|
(header.p ? "1" : "0"),
|
||||||
|
to_string_short(header.si),
|
||||||
|
header.sn,
|
||||||
|
header.sn,
|
||||||
|
header.so);
|
||||||
|
fmt::format_to(buffer, "]");
|
||||||
|
|
||||||
|
log_ch("%s", to_c_str(buffer));
|
||||||
|
}
|
||||||
} // namespace srsran
|
} // namespace srsran
|
||||||
|
|
||||||
#endif // SRSRAN_RLC_AM_NR_PACKING_H
|
#endif // SRSRAN_RLC_AM_NR_PACKING_H
|
||||||
|
|
|
@ -19,9 +19,10 @@
|
||||||
#include "srsran/srslog/event_trace.h"
|
#include "srsran/srslog/event_trace.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#define RLC_AM_NR_WINDOW_SIZE 1024
|
#define RLC_AM_NR_WINDOW_SIZE 2048
|
||||||
#define RX_MOD_BASE_NR(x) (((x)-rx_next) % RLC_AM_NR_WINDOW_SIZE)
|
#define MOD_NR 4096
|
||||||
//#define TX_MOD_BASE_NR(x) (((x)-vt_a) % RLC_AM_NR_WINDOW_SIZE)
|
#define RX_MOD_BASE_NR(x) (((x)-rx_next) % MOD_NR)
|
||||||
|
//#define TX_MOD_BASE_NR(x) (((x)-vt_a) % MOD_NR)
|
||||||
|
|
||||||
namespace srsran {
|
namespace srsran {
|
||||||
|
|
||||||
|
@ -232,17 +233,92 @@ void rlc_am_nr_rx::handle_data_pdu(uint8_t* payload, uint32_t nof_bytes)
|
||||||
rlc_am_nr_pdu_header_t header = {};
|
rlc_am_nr_pdu_header_t header = {};
|
||||||
rlc_am_nr_read_data_pdu_header(payload, nof_bytes, rlc_am_nr_sn_size_t::size12bits, &header);
|
rlc_am_nr_read_data_pdu_header(payload, nof_bytes, rlc_am_nr_sn_size_t::size12bits, &header);
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
// if (header.rf != 0) {
|
||||||
|
// handle_data_pdu_segment(payload, payload_len, header); TODO
|
||||||
|
//} else {
|
||||||
|
handle_data_pdu_full(payload, nof_bytes, header);
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
void rlc_am_nr_rx::handle_data_pdu_full(uint8_t* payload, uint32_t nof_bytes, rlc_am_nr_pdu_header_t& header)
|
||||||
|
{
|
||||||
|
std::map<uint32_t, rlc_amd_rx_pdu_nr>::iterator it;
|
||||||
|
|
||||||
|
logger->info(payload, nof_bytes, "%s Rx data PDU SN=%d (%d B)", parent->rb_name, header.sn, nof_bytes);
|
||||||
|
log_rlc_am_nr_pdu_header_to_string(logger->debug, header);
|
||||||
|
|
||||||
|
// sanity check for segments not exceeding PDU length
|
||||||
|
// TODO
|
||||||
|
|
||||||
|
if (!inside_rx_window(header.sn)) {
|
||||||
|
logger->info("%s SN=%d outside rx window [%d:%d] - discarding",
|
||||||
|
parent->rb_name,
|
||||||
|
header.sn,
|
||||||
|
rx_next,
|
||||||
|
rx_next + RLC_AM_NR_WINDOW_SIZE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Section 5.2.3.2.2, discard duplicate PDUs
|
||||||
|
if (rx_window.has_sn(header.sn)) {
|
||||||
|
logger->info("%s Discarding duplicate SN=%d", parent->rb_name, header.sn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write to rx window
|
||||||
|
rlc_amd_rx_pdu_nr& pdu = rx_window.add_pdu(header.sn);
|
||||||
|
pdu.buf = srsran::make_byte_buffer();
|
||||||
|
if (pdu.buf == nullptr) {
|
||||||
|
logger->error("Fatal Error: Couldn't allocate PDU in handle_data_pdu().");
|
||||||
|
rx_window.remove_pdu(header.sn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pdu.buf->set_timestamp();
|
||||||
|
|
||||||
|
// check available space for payload
|
||||||
|
if (nof_bytes > pdu.buf->get_tailroom()) {
|
||||||
|
logger->error("%s Discarding SN=%d of size %d B (available space %d B)",
|
||||||
|
parent->rb_name,
|
||||||
|
header.sn,
|
||||||
|
nof_bytes,
|
||||||
|
pdu.buf->get_tailroom());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
memcpy(pdu.buf->msg, payload, nof_bytes);
|
||||||
|
pdu.buf->N_bytes = nof_bytes;
|
||||||
|
pdu.header = header;
|
||||||
|
|
||||||
|
// Update Rx_Next_Highest
|
||||||
|
if (RX_MOD_BASE_NR(header.sn) >= RX_MOD_BASE_NR(rx_next_highest)) {
|
||||||
|
rx_next_highest = (header.sn + 1) % MOD;
|
||||||
|
}
|
||||||
|
|
||||||
// Check poll bit
|
// Check poll bit
|
||||||
if (header.p != 0) {
|
if (header.p) {
|
||||||
logger->info("%s Status packet requested through polling bit", parent->rb_name);
|
logger->info("%s Status packet requested through polling bit", parent->rb_name);
|
||||||
do_status = true;
|
do_status = true;
|
||||||
|
|
||||||
// 36.322 v10 Section 5.2.3
|
|
||||||
// if (RX_MOD_BASE(header.sn) < RX_MOD_BASE(vr_ms) || RX_MOD_BASE(header.sn) >= RX_MOD_BASE(vr_mr)) {
|
|
||||||
// do_status = true;
|
|
||||||
//}
|
|
||||||
// else delay for reordering timer
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update RX_Highest_Status
|
||||||
|
if (RX_MOD_BASE_NR(header.sn) == RX_MOD_BASE_NR(rx_highest_status)) {
|
||||||
|
rx_highest_status = header.sn % MOD;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update RX_Next
|
||||||
|
if (RX_MOD_BASE_NR(header.sn) == RX_MOD_BASE_NR(rx_highest_status)) {
|
||||||
|
rx_highest_status = header.sn % MOD;
|
||||||
|
}
|
||||||
|
// Update reordering variables and timers (36.322 v10.0.0 Section 5.1.3.2.3)
|
||||||
|
// TODO
|
||||||
|
|
||||||
|
debug_state();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool rlc_am_nr_rx::inside_rx_window(uint32_t sn)
|
||||||
|
{
|
||||||
|
return (RX_MOD_BASE_NR(sn) >= RX_MOD_BASE_NR(rx_next)) &&
|
||||||
|
(RX_MOD_BASE_NR(sn) < RX_MOD_BASE_NR(rx_next + RLC_AM_NR_WINDOW_SIZE));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -303,4 +379,16 @@ uint32_t rlc_am_nr_rx::get_rx_buffered_bytes()
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Helpers
|
||||||
|
*/
|
||||||
|
void rlc_am_nr_rx::debug_state()
|
||||||
|
{
|
||||||
|
logger->debug("RX entity state: Rx_Next %d, Rx_Next_Status_Trigger %d, Rx_Highest_Status %d, Rx_Next_Highest",
|
||||||
|
rx_next,
|
||||||
|
rx_next_status_trigger,
|
||||||
|
rx_highest_status,
|
||||||
|
rx_next_highest);
|
||||||
|
}
|
||||||
} // namespace srsran
|
} // namespace srsran
|
||||||
|
|
Loading…
Reference in New Issue