lib,rlc_am_nr: added logging macros to make sure that the RB name is allways logged.

master
Pedro Alvarez 3 years ago
parent f60259afb9
commit 5532c514ba

@ -183,6 +183,7 @@ public:
srslog::basic_logger* logger = nullptr;
byte_buffer_pool* pool = nullptr;
rlc_am* parent = nullptr;
std::string rb_name;
protected:
std::atomic<bool> do_status = {false}; // light-weight access from Tx entity

@ -21,6 +21,11 @@
#define RLC_AM_NR_WINDOW_SIZE 2048
#define Debug(fmt, ...) logger->debug("%s: " fmt, rb_name, ##__VA_ARGS__)
#define Info(fmt, ...) logger->info("%s: " fmt, rb_name, ##__VA_ARGS__)
#define Warning(fmt, ...) logger->warning("%s: " fmt, rb_name, ##__VA_ARGS__)
#define Error(fmt, ...) logger->error("%s: " fmt, rb_name, ##__VA_ARGS__)
namespace srsran {
const static uint32_t max_tx_queue_size = 256;
@ -35,17 +40,18 @@ rlc_am_nr_tx::rlc_am_nr_tx(rlc_am* parent_) : parent(parent_), rlc_am_base_tx(&p
bool rlc_am_nr_tx::configure(const rlc_config_t& cfg_)
{
cfg = cfg_.am_nr;
cfg = cfg_.am_nr;
rb_name = parent->rb_name;
if (cfg.tx_sn_field_length != rlc_am_nr_sn_size_t::size12bits) {
logger->warning("RLC AM NR only supports 12 bit SN length.");
Warning("RLC AM NR only supports 12 bit SN length.");
return false;
}
if (cfg_.tx_queue_length > max_tx_queue_size) {
logger->error("Configuring tx queue length of %d PDUs too big. Maximum value is %d.",
cfg_.tx_queue_length,
max_tx_queue_size);
Error("configuring tx queue length of %d PDUs too big. Maximum value is %d.",
cfg_.tx_queue_length,
max_tx_queue_size);
return false;
}
@ -53,6 +59,7 @@ bool rlc_am_nr_tx::configure(const rlc_config_t& cfg_)
tx_enabled = true;
Debug("RLC AM NR tx entity configured.");
return true;
}
@ -64,35 +71,33 @@ bool rlc_am_nr_tx::has_data()
uint32_t rlc_am_nr_tx::read_pdu(uint8_t* payload, uint32_t nof_bytes)
{
logger->debug("MAC opportunity - %d bytes", nof_bytes);
std::lock_guard<std::mutex> lock(mutex);
if (not tx_enabled) {
logger->debug("RLC entity not active. Not generating PDU.");
Debug("RLC entity not active. Not generating PDU.");
return 0;
}
logger->debug("tx_window size - %zu PDUs", tx_window.size());
Debug("MAC opportunity - bytes=%d, tx_window size=%zu PDUs", nof_bytes, tx_window.size());
// Tx STATUS if requested
if (do_status()) {
unique_byte_buffer_t tx_pdu = srsran::make_byte_buffer();
if (tx_pdu == nullptr) {
logger->error("Couldn't allocate PDU in %s().", __FUNCTION__);
Error("couldn't allocate PDU in %s().", __FUNCTION__);
return 0;
}
build_status_pdu(tx_pdu.get(), nof_bytes);
memcpy(payload, tx_pdu->msg, tx_pdu->N_bytes);
logger->debug("Status PDU built - %d bytes", tx_pdu->N_bytes);
Debug("status PDU built - %d bytes", tx_pdu->N_bytes);
return tx_pdu->N_bytes;
}
// Retransmit if required
if (not retx_queue.empty()) {
logger->info("Retransmission required. Retransmission queue size: %d", retx_queue.size());
Info("re-transmission required. Retransmission queue size: %d", retx_queue.size());
unique_byte_buffer_t tx_pdu = srsran::make_byte_buffer();
if (tx_pdu == nullptr) {
logger->error("Couldn't allocate PDU in %s().", __FUNCTION__);
Error("couldn't allocate PDU in %s().", __FUNCTION__);
return 0;
}
int retx_err = build_retx_pdu(tx_pdu, nof_bytes);
@ -106,9 +111,8 @@ uint32_t rlc_am_nr_tx::read_pdu(uint8_t* payload, uint32_t nof_bytes)
if (current_sdu.rlc_sn != INVALID_RLC_SN) {
if (not tx_window.has_sn(current_sdu.rlc_sn)) {
current_sdu.rlc_sn = INVALID_RLC_SN;
logger->error("%s SDU currently being segmented does not exist in tx_window. Aborting segmentation SN=%d",
rb_name,
current_sdu.rlc_sn);
Error("SDU currently being segmented does not exist in tx_window. Aborting segmentation SN=%d",
current_sdu.rlc_sn);
return 0;
}
return build_continuation_sdu_segment(tx_window[current_sdu.rlc_sn], payload, nof_bytes);
@ -116,21 +120,21 @@ uint32_t rlc_am_nr_tx::read_pdu(uint8_t* payload, uint32_t nof_bytes)
// Check whether there is something to TX
if (tx_sdu_queue.is_empty()) {
logger->info("No data available to be sent");
Info("no data available to be sent");
return 0;
}
// Read new SDU from TX queue
unique_byte_buffer_t tx_sdu;
logger->debug("Reading from RLC SDU queue. Queue size %d", tx_sdu_queue.size());
Debug("reading from RLC SDU queue. Queue size %d", tx_sdu_queue.size());
do {
tx_sdu = tx_sdu_queue.read();
} while (tx_sdu == nullptr && tx_sdu_queue.size() != 0);
if (tx_sdu != nullptr) {
logger->debug("Read RLC SDU - %d bytes", tx_sdu->N_bytes);
Debug("read RLC SDU - %d bytes", tx_sdu->N_bytes);
} else {
logger->info("No SDUs left in the tx queue.");
Info("no SDUs left in the tx queue.");
return 0;
}
@ -139,14 +143,14 @@ uint32_t rlc_am_nr_tx::read_pdu(uint8_t* payload, uint32_t nof_bytes)
rlc_amd_tx_pdu_nr& tx_pdu = tx_window.add_pdu(st.tx_next);
tx_pdu.buf = srsran::make_byte_buffer();
if (tx_pdu.buf == nullptr) {
logger->error("Couldn't allocate PDU in %s().", __FUNCTION__);
Error("couldn't allocate PDU in %s().", __FUNCTION__);
return 0;
}
// Segment new SDU if necessary
uint16_t hdr_size = 2;
if (tx_sdu->N_bytes + hdr_size > nof_bytes) {
logger->info("Trying to build PDU segment from SDU.");
Info("trying to build PDU segment from SDU.");
return build_new_sdu_segment(std::move(tx_sdu), tx_pdu, payload, nof_bytes);
}
@ -166,14 +170,14 @@ uint32_t rlc_am_nr_tx::read_pdu(uint8_t* payload, uint32_t nof_bytes)
// Write header
uint32_t len = rlc_am_nr_write_data_pdu_header(hdr, tx_sdu.get());
if (len > nof_bytes) {
logger->error("Error writing AMD PDU header");
Error("error writing AMD PDU header");
}
// Update TX Next
st.tx_next = (st.tx_next + 1) % MOD;
memcpy(payload, tx_sdu->msg, tx_sdu->N_bytes);
logger->debug("Wrote RLC PDU - %d bytes", tx_sdu->N_bytes);
Debug("wrote RLC PDU - %d bytes", tx_sdu->N_bytes);
return tx_sdu->N_bytes;
}
@ -183,22 +187,21 @@ int rlc_am_nr_tx::build_new_sdu_segment(unique_byte_buffer_t tx_sdu,
uint8_t* payload,
uint32_t nof_bytes)
{
logger->info("Creating new SDU segment. Tx SDU (%d B), nof_bytes=%d B ", tx_sdu->N_bytes, nof_bytes);
Info("creating new SDU segment. Tx SDU (%d B), nof_bytes=%d B ", tx_sdu->N_bytes, nof_bytes);
// Sanity check: can this SDU be sent this in a single PDU?
if ((tx_sdu->N_bytes + 2) < nof_bytes) {
logger->error("Calling build_new_sdu_segment(), but there are enough bytes to tx in a single PDU. Tx SDU (%d B), "
"nof_bytes=%d B ",
tx_sdu->N_bytes,
nof_bytes);
Error("calling build_new_sdu_segment(), but there are enough bytes to tx in a single PDU. Tx SDU (%d B), "
"nof_bytes=%d B ",
tx_sdu->N_bytes,
nof_bytes);
return 0;
}
// Sanity check: can this SDU be sent considering header overhead?
if (3 < nof_bytes) { // Only two bytes of header, as SO is 0
logger->error(
"Cannot build new sdu_segment, there are not enough bytes allocated to tx header plus data. nof_bytes=%d",
nof_bytes);
Error("cannot build new sdu_segment, there are not enough bytes allocated to tx header plus data. nof_bytes=%d",
nof_bytes);
return 0;
}
@ -216,7 +219,7 @@ int rlc_am_nr_tx::build_new_sdu_segment(unique_byte_buffer_t tx_sdu,
// Write header
uint32_t hdr_len = rlc_am_nr_write_data_pdu_header(hdr, payload);
if (hdr_len > nof_bytes) {
logger->error("Error writing AMD PDU header");
logger->error("error writing AMD PDU header");
}
// Copy PDU to payload
@ -236,18 +239,18 @@ int rlc_am_nr_tx::build_new_sdu_segment(unique_byte_buffer_t tx_sdu,
int rlc_am_nr_tx::build_continuation_sdu_segment(rlc_amd_tx_pdu_nr& tx_pdu, uint8_t* payload, uint32_t nof_bytes)
{
logger->info("Continuing SDU segment. SN=%d, Tx SDU (%d B), nof_bytes=%d B ",
current_sdu.rlc_sn,
current_sdu.buf->N_bytes,
nof_bytes);
Info("continuing SDU segment. SN=%d, Tx SDU (%d B), nof_bytes=%d B ",
current_sdu.rlc_sn,
current_sdu.buf->N_bytes,
nof_bytes);
// Sanity check: is there an initial SDU segment?
if (tx_pdu.segment_list.empty()) {
logger->error("build_continuation_sdu_segment was called, but there was no initial segment. SN=%d, Tx SDU (%d B), "
"nof_bytes=%d B ",
current_sdu.rlc_sn,
current_sdu.buf->N_bytes,
nof_bytes);
Error("build_continuation_sdu_segment was called, but there was no initial segment. SN=%d, Tx SDU (%d B), "
"nof_bytes=%d B ",
current_sdu.rlc_sn,
current_sdu.buf->N_bytes,
nof_bytes);
current_sdu.rlc_sn = INVALID_RLC_SN;
current_sdu.buf = nullptr;
return 0;
@ -255,9 +258,8 @@ int rlc_am_nr_tx::build_continuation_sdu_segment(rlc_amd_tx_pdu_nr& tx_pdu, uint
// Sanity check: can this SDU be sent considering header overhead?
if (5 < nof_bytes) { // Four bytes of header, as SO is present
logger->error(
"Cannot build new sdu_segment, there are not enough bytes allocated to tx header plus data. nof_bytes=%d",
nof_bytes);
Error("cannot build new sdu_segment, there are not enough bytes allocated to tx header plus data. nof_bytes=%d",
nof_bytes);
return 0;
}
@ -265,12 +267,11 @@ int rlc_am_nr_tx::build_continuation_sdu_segment(rlc_amd_tx_pdu_nr& tx_pdu, uint
std::list<rlc_amd_tx_pdu_nr::pdu_segment>::iterator it = tx_pdu.segment_list.end();
--it;
uint32_t last_byte = it->so + it->payload_len;
logger->debug("Continuing SDU segment. SN=%d, last byte transmitted %d", tx_pdu.rlc_sn, last_byte);
Debug("continuing SDU segment. SN=%d, last byte transmitted %d", tx_pdu.rlc_sn, last_byte);
// Sanity check: last byte must be smaller than SDU
if (current_sdu.buf->N_bytes < last_byte) {
logger->error(
"Last byte transmitted larger than SDU len. SDU len=%d B, last_byte=%d B", tx_pdu.buf->N_bytes, last_byte);
Error("last byte transmitted larger than SDU len. SDU len=%d B, last_byte=%d B", tx_pdu.buf->N_bytes, last_byte);
return 0;
}
@ -280,17 +281,17 @@ int rlc_am_nr_tx::build_continuation_sdu_segment(rlc_amd_tx_pdu_nr& tx_pdu, uint
: rlc_nr_si_field_t::last_segment;
if (si == rlc_nr_si_field_t::neither_first_nor_last_segment) {
logger->info("Grant is not large enough for full SDU. "
"SDU bytes left %d, nof_bytes %d, ",
segment_payload_full_len,
nof_bytes);
Info("grant is not large enough for full SDU. "
"SDU bytes left %d, nof_bytes %d, ",
segment_payload_full_len,
nof_bytes);
segment_payload_len = nof_bytes - 4;
segment_payload_full_len = nof_bytes;
} else {
logger->info("Grant is large enough for full SDU."
"SDU bytes left %d, nof_bytes %d, ",
segment_payload_full_len,
nof_bytes);
Info("grant is large enough for full SDU."
"SDU bytes left %d, nof_bytes %d, ",
segment_payload_full_len,
nof_bytes);
}
// Prepare header
@ -307,7 +308,7 @@ int rlc_am_nr_tx::build_continuation_sdu_segment(rlc_amd_tx_pdu_nr& tx_pdu, uint
// Write header
uint32_t hdr_len = rlc_am_nr_write_data_pdu_header(hdr, payload);
if (hdr_len > nof_bytes) {
logger->error("Error writing AMD PDU header");
Error("error writing AMD PDU header");
return 0;
}
@ -321,11 +322,11 @@ int rlc_am_nr_tx::build_continuation_sdu_segment(rlc_amd_tx_pdu_nr& tx_pdu, uint
tx_pdu.segment_list.push_back(segment_info);
if (si == rlc_nr_si_field_t::neither_first_nor_last_segment) {
logger->info("Grant is not large enough for full SDU."
"Storing SDU segment info");
Info("grant is not large enough for full SDU."
"Storing SDU segment info");
} else {
logger->info("Grant is large enough for full SDU."
"Removing current SDU info");
Info("grant is large enough for full SDU."
"Removing current SDU info");
current_sdu.rlc_sn = INVALID_RLC_SN;
current_sdu.buf = nullptr;
}
@ -337,7 +338,7 @@ int rlc_am_nr_tx::build_retx_pdu(unique_byte_buffer_t& tx_pdu, uint32_t nof_byte
{
// Check there is at least 1 element before calling front()
if (retx_queue.empty()) {
logger->error("In build_retx_pdu(): retx_queue is empty");
Error("in build_retx_pdu(): retx_queue is empty");
return SRSRAN_ERROR;
}
@ -345,12 +346,12 @@ int rlc_am_nr_tx::build_retx_pdu(unique_byte_buffer_t& tx_pdu, uint32_t nof_byte
// Sanity check - drop any retx SNs not present in tx_window
while (not tx_window.has_sn(retx.sn)) {
logger->warning("%s SN=%d not in tx window. Ignoring retx.", parent->rb_name, retx.sn);
Warning("SN=%d not in tx window. Ignoring retx.", retx.sn);
retx_queue.pop();
if (!retx_queue.empty()) {
retx = retx_queue.front();
} else {
logger->warning("%s empty retx queue, cannot provide retx PDU", parent->rb_name);
Warning("empty retx queue, cannot provide retx PDU");
return SRSRAN_ERROR;
}
}
@ -361,7 +362,7 @@ int rlc_am_nr_tx::build_retx_pdu(unique_byte_buffer_t& tx_pdu, uint32_t nof_byte
// Check if we exceed allocated number of bytes
if (hdr_len + tx_window[retx.sn].buf->N_bytes > nof_bytes) {
logger->warning("%s segmentation not supported yet. Cannot provide retx PDU", parent->rb_name);
Warning("segmentation not supported yet. Cannot provide retx PDU");
return SRSRAN_ERROR;
}
// TODO Consider re-segmentation
@ -388,18 +389,18 @@ int rlc_am_nr_tx::build_retx_pdu(unique_byte_buffer_t& tx_pdu, uint32_t nof_byte
uint32_t rlc_am_nr_tx::build_status_pdu(byte_buffer_t* payload, uint32_t nof_bytes)
{
logger->info("Generating Status PDU. Bytes available:%d", nof_bytes);
Info("generating status PDU. Bytes available:%d", nof_bytes);
rlc_am_nr_status_pdu_t tx_status;
int pdu_len = rx->get_status_pdu(&tx_status, nof_bytes);
if (pdu_len == SRSRAN_ERROR) {
logger->debug("%s Deferred Status PDU. Cause: Failed to acquire rx lock", rb_name);
Debug("deferred status PDU. Cause: Failed to acquire rx lock");
pdu_len = 0;
} else if (pdu_len > 0 && nof_bytes >= static_cast<uint32_t>(pdu_len)) {
logger->debug("Generated status PDU. Bytes:%d", pdu_len);
Debug("generated status PDU. Bytes:%d", pdu_len);
log_rlc_am_nr_status_pdu_to_string(logger->info, "%s tx status PDU - %s", &tx_status, rb_name);
pdu_len = rlc_am_nr_write_status_pdu(tx_status, rlc_am_nr_sn_size_t::size12bits, payload);
} else {
logger->info("%s Cannot tx status PDU - %d bytes available, %d bytes required", rb_name, nof_bytes, pdu_len);
Info("cannot tx status PDU - %d bytes available, %d bytes required", nof_bytes, pdu_len);
pdu_len = 0;
}
@ -428,7 +429,7 @@ void rlc_am_nr_tx::handle_control_pdu(uint8_t* payload, uint32_t nof_bytes)
? status.ack_sn
: status.nacks[0].nack_sn - 1; // Stop processing ACKs at the first NACK, if it exists.
if (stop_sn > st.tx_next) {
logger->error("Received ACK or NACK larger than TX_NEXT. Ignoring status report");
Error("Received ACK or NACK larger than TX_NEXT. Ignoring status report");
return;
}
for (uint32_t sn = st.tx_next_ack; sn < stop_sn; sn++) {
@ -437,7 +438,7 @@ void rlc_am_nr_tx::handle_control_pdu(uint8_t* payload, uint32_t nof_bytes)
st.tx_next_ack = sn + 1;
// TODO notify PDCP
} else {
logger->error("Missing ACKed SN from TX window");
Error("Missing ACKed SN from TX window");
break;
}
}
@ -488,35 +489,32 @@ uint32_t rlc_am_nr_tx::get_buffer_state()
void rlc_am_nr_tx::get_buffer_state(uint32_t& n_bytes_new, uint32_t& n_bytes_prio)
{
logger->debug("Buffer state requested, %s", rb_name);
std::lock_guard<std::mutex> lock(mutex);
logger->debug("%s Buffer state - do_status=%s", rb_name, do_status() ? "yes" : "no");
Debug("buffer state - do_status=%s", do_status() ? "yes" : "no");
// Bytes needed for status report
if (do_status()) {
n_bytes_prio += rx->get_status_pdu_length();
logger->debug("%s Buffer state - total status report: %d bytes", rb_name, n_bytes_prio);
Debug("buffer state - total status report: %d bytes", n_bytes_prio);
}
// Bytes needed for retx
if (not retx_queue.empty()) {
rlc_amd_retx_t& retx = retx_queue.front();
logger->debug("%s Buffer state - retx - SN=%d, Segment: %s, %d:%d",
parent->rb_name,
retx.sn,
retx.is_segment ? "true" : "false",
retx.so_start,
retx.so_end);
Debug("buffer state - retx - SN=%d, Segment: %s, %d:%d",
retx.sn,
retx.is_segment ? "true" : "false",
retx.so_start,
retx.so_end);
if (tx_window.has_sn(retx.sn)) {
int req_bytes = retx.so_end - retx.so_start;
int hdr_req_bytes = retx.is_segment ? 4 : 2; // Segmentation not supported yet
if (req_bytes <= 0) {
logger->error("In get_buffer_state(): Removing retx.sn=%d from queue", retx.sn);
Error("in get_buffer_state(): Removing retx with SN=%d from queue", retx.sn);
retx_queue.pop();
} else {
n_bytes_prio += (req_bytes + hdr_req_bytes);
logger->debug("Buffer state - retx: %d bytes", n_bytes_prio);
Debug("buffer state - retx: %d bytes", n_bytes_prio);
}
}
}
@ -527,10 +525,10 @@ void rlc_am_nr_tx::get_buffer_state(uint32_t& n_bytes_new, uint32_t& n_bytes_pri
// Room needed for fixed header of data PDUs
n_bytes_new += 2 * n_sdus; // TODO make header size configurable
logger->debug("%s Total buffer state - %d SDUs (%d B)", rb_name, n_sdus, n_bytes_new + n_bytes_prio);
Debug("total buffer state - %d SDUs (%d B)", n_sdus, n_bytes_new + n_bytes_prio);
if (bsr_callback) {
logger->debug("%s Calling BSR callback - %d new_tx, %d priority bytes", parent->rb_name, n_bytes_new, n_bytes_prio);
Debug("calling BSR callback - %d new_tx, %d priority bytes", n_bytes_new, n_bytes_prio);
bsr_callback(parent->lcid, n_bytes_new, n_bytes_prio);
}
}
@ -596,8 +594,8 @@ rlc_am_nr_rx::rlc_am_nr_rx(rlc_am* parent_) :
bool rlc_am_nr_rx::configure(const rlc_config_t& cfg_)
{
cfg = cfg_.am_nr;
cfg = cfg_.am_nr;
rb_name = parent->rb_name;
// Configure status prohibit timer
if (cfg.t_status_prohibit > 0) {
status_prohibit_timer.set(static_cast<uint32_t>(cfg.t_status_prohibit),
@ -607,10 +605,13 @@ bool rlc_am_nr_rx::configure(const rlc_config_t& cfg_)
// Configure t_reassembly timer
if (cfg.t_reassembly > 0) {
reassembly_timer.set(static_cast<uint32_t>(cfg.t_reassembly), [this](uint32_t timerid) { timer_expired(timerid); });
logger->info("Configured reassembly timer. t-Reassembly=%d ms", cfg.t_reassembly);
Info("configured reassembly timer. t-Reassembly=%d ms", cfg.t_reassembly);
}
mod_nr = (cfg.rx_sn_field_length == rlc_am_nr_sn_size_t::size12bits) ? 4096 : 262144;
Debug("RLC AM NR configured rx entity.");
return true;
}
@ -632,17 +633,13 @@ void rlc_am_nr_rx::handle_data_pdu(uint8_t* payload, uint32_t nof_bytes)
// Check whether SDU is within Rx Window
if (!inside_rx_window(header.sn)) {
logger->info("%s SN=%d outside rx window [%d:%d] - discarding",
parent->rb_name,
header.sn,
st.rx_next,
st.rx_next + RLC_AM_NR_WINDOW_SIZE);
Info("SN=%d outside rx window [%d:%d] - discarding", header.sn, st.rx_next, st.rx_next + RLC_AM_NR_WINDOW_SIZE);
return;
}
// Section 5.2.3.2.2, discard duplicate PDUs
if (rx_window.has_sn(header.sn) && rx_window[header.sn].fully_received) {
logger->info("%s Discarding duplicate SN=%d", parent->rb_name, header.sn);
Info("discarding duplicate SN=%d", header.sn);
return;
}
@ -661,7 +658,7 @@ void rlc_am_nr_rx::handle_data_pdu(uint8_t* payload, uint32_t nof_bytes)
// Check poll bit
if (header.p) {
logger->info("%s Status packet requested through polling bit", parent->rb_name);
Info("status packet requested through polling bit");
do_status = true;
status_prohibit_timer.stop();
}
@ -765,7 +762,7 @@ int rlc_am_nr_rx::handle_full_data_sdu(const rlc_am_nr_pdu_header_t& header, con
rlc_amd_rx_sdu_nr_t& rx_sdu = rx_window.add_pdu(header.sn);
rx_sdu.buf = srsran::make_byte_buffer();
if (rx_sdu.buf == nullptr) {
logger->error("Fatal Error: Couldn't allocate PDU in %s.", __FUNCTION__);
Error("fatal error. Couldn't allocate PDU in %s.", __FUNCTION__);
rx_window.remove_pdu(header.sn);
return SRSRAN_ERROR;
}
@ -773,11 +770,7 @@ int rlc_am_nr_rx::handle_full_data_sdu(const rlc_am_nr_pdu_header_t& header, con
// check available space for payload
if (nof_bytes > rx_sdu.buf->get_tailroom()) {
logger->error("%s Discarding SN=%d of size %d B (available space %d B)",
parent->rb_name,
header.sn,
nof_bytes,
rx_sdu.buf->get_tailroom());
Error("discarding SN=%d of size %d B (available space %d B)", header.sn, nof_bytes, rx_sdu.buf->get_tailroom());
rx_window.remove_pdu(header.sn);
return SRSRAN_ERROR;
}
@ -793,7 +786,7 @@ int rlc_am_nr_rx::handle_segment_data_sdu(const rlc_am_nr_pdu_header_t& header,
uint32_t nof_bytes)
{
if (header.si == rlc_nr_si_field_t::full_sdu) {
logger->error("Called %s but the SI implies a full SDU. SN=%d", __FUNCTION__, header.sn);
Error("called %s but the SI implies a full SDU. SN=%d", __FUNCTION__, header.sn);
return SRSRAN_ERROR;
}
@ -801,11 +794,11 @@ int rlc_am_nr_rx::handle_segment_data_sdu(const rlc_am_nr_pdu_header_t& header,
// Log SDU segment reception
if (header.si == rlc_nr_si_field_t::first_segment) { // Check whether it's a full SDU
logger->info("Initial segment PDU. SN=%d.", header.sn);
Info("Initial segment PDU. SN=%d.", header.sn);
} else if (header.si == rlc_nr_si_field_t::neither_first_nor_last_segment) {
logger->info("Middle segment PDU. SN=%d.", header.sn);
Info("Middle segment PDU. SN=%d.", header.sn);
} else if (header.si == rlc_nr_si_field_t::last_segment) {
logger->info("Final segment PDU. SN=%d.", header.sn);
Info("Final segment PDU. SN=%d.", header.sn);
}
// Add a new SDU to the RX window if necessary
@ -816,7 +809,7 @@ int rlc_am_nr_rx::handle_segment_data_sdu(const rlc_am_nr_pdu_header_t& header,
pdu_segment.header = header;
pdu_segment.buf = srsran::make_byte_buffer();
if (pdu_segment.buf == nullptr) {
logger->error("Fatal Error: Couldn't allocate PDU in %s.", __FUNCTION__);
Error("fatal error. Couldn't allocate PDU in %s.", __FUNCTION__);
return SRSRAN_ERROR;
}
memcpy(pdu_segment.buf->msg, payload + hdr_len, nof_bytes - hdr_len); // Don't copy header
@ -828,10 +821,10 @@ int rlc_am_nr_rx::handle_segment_data_sdu(const rlc_am_nr_pdu_header_t& header,
// Check weather all segments have been received
rx_sdu.fully_received = have_all_segments_been_received(rx_sdu.segments);
if (rx_sdu.fully_received) {
logger->info("Fully received segmented SDU. SN=%d.", header.sn);
Info("Fully received segmented SDU. SN=%d.", header.sn);
rx_sdu.buf = srsran::make_byte_buffer();
if (rx_sdu.buf == nullptr) {
logger->error("Fatal Error: Couldn't allocate PDU in %s.", __FUNCTION__);
Error("fatal error. Couldn't allocate PDU in %s.", __FUNCTION__);
rx_window.remove_pdu(header.sn);
return SRSRAN_ERROR;
}
@ -900,13 +893,13 @@ void rlc_am_nr_rx::timer_expired(uint32_t timeout_id)
// Status Prohibit
if (status_prohibit_timer.is_valid() && status_prohibit_timer.id() == timeout_id) {
logger->debug("%s Status prohibit timer expired after %dms", parent->rb_name, status_prohibit_timer.duration());
Debug("Status prohibit timer expired after %dms", status_prohibit_timer.duration());
return;
}
// Reassembly
if (reassembly_timer.is_valid() && reassembly_timer.id() == timeout_id) {
logger->debug("%s Reassembly timer expired after %dms", parent->rb_name, reassembly_timer.duration());
Debug("Reassembly timer expired after %dms", reassembly_timer.duration());
/*
* 5.2.3.2.4 Actions when t-Reassembly expires:
* - update RX_Highest_Status to the SN of the first RLC SDU with SN >= RX_Next_Status_Trigger for which not
@ -1003,15 +996,16 @@ bool rlc_am_nr_rx::have_all_segments_been_received(const std::list<rlc_amd_rx_pd
}
return true;
}
/*
* Debug 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",
st.rx_next,
st.rx_next_status_trigger,
st.rx_highest_status,
st.rx_next_highest);
Debug("RX entity state: Rx_Next %d, Rx_Next_Status_Trigger %d, Rx_Highest_Status %d, Rx_Next_Highest",
st.rx_next,
st.rx_next_status_trigger,
st.rx_highest_status,
st.rx_next_highest);
}
} // namespace srsran

Loading…
Cancel
Save