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_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:
|
||||
rlc_am* parent = nullptr;
|
||||
rlc_am_nr_tx* tx = nullptr;
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#ifndef 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"
|
||||
|
||||
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,
|
||||
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
|
||||
|
||||
#endif // SRSRAN_RLC_AM_NR_PACKING_H
|
||||
|
|
|
@ -19,9 +19,10 @@
|
|||
#include "srsran/srslog/event_trace.h"
|
||||
#include <iostream>
|
||||
|
||||
#define RLC_AM_NR_WINDOW_SIZE 1024
|
||||
#define RX_MOD_BASE_NR(x) (((x)-rx_next) % RLC_AM_NR_WINDOW_SIZE)
|
||||
//#define TX_MOD_BASE_NR(x) (((x)-vt_a) % RLC_AM_NR_WINDOW_SIZE)
|
||||
#define RLC_AM_NR_WINDOW_SIZE 2048
|
||||
#define MOD_NR 4096
|
||||
#define RX_MOD_BASE_NR(x) (((x)-rx_next) % MOD_NR)
|
||||
//#define TX_MOD_BASE_NR(x) (((x)-vt_a) % MOD_NR)
|
||||
|
||||
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_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
|
||||
if (header.p != 0) {
|
||||
if (header.p) {
|
||||
logger->info("%s Status packet requested through polling bit", parent->rb_name);
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
|
Loading…
Reference in New Issue