diff --git a/srsenb/hdr/stack/mac/nr/ue_nr.h b/srsenb/hdr/stack/mac/nr/ue_nr.h index b5d1cf6a2..59ef98a15 100644 --- a/srsenb/hdr/stack/mac/nr/ue_nr.h +++ b/srsenb/hdr/stack/mac/nr/ue_nr.h @@ -96,6 +96,9 @@ private: ue_rx_pdu_queue; ///< currently only DCH PDUs supported (add BCH, PCH, etc) srsran::unique_byte_buffer_t ue_rlc_buffer; + static constexpr int32_t MIN_RLC_PDU_LEN = + 5; ///< minimum bytes that need to be available in a MAC PDU for attempting to add another RLC SDU + // Mutexes std::mutex mutex; }; diff --git a/srsenb/src/stack/mac/nr/ue_nr.cc b/srsenb/src/stack/mac/nr/ue_nr.cc index 57cc02dbb..0e7a3779b 100644 --- a/srsenb/src/stack/mac/nr/ue_nr.cc +++ b/srsenb/src/stack/mac/nr/ue_nr.cc @@ -76,8 +76,7 @@ int ue_nr::process_pdu(srsran::unique_byte_buffer_t pdu) // Reverse the order in which MAC subPDUs get processed. // First, process MAC CEs, then MAC MAC subPDUs with MAC SDUs - for (uint32_t n = mac_pdu_ul.get_num_subpdus(), i = mac_pdu_ul.get_num_subpdus() - 1; n > 0; - --n, i = n - 1) { + for (uint32_t n = mac_pdu_ul.get_num_subpdus(), i = mac_pdu_ul.get_num_subpdus() - 1; n > 0; --n, i = n - 1) { srsran::mac_sch_subpdu_nr subpdu = mac_pdu_ul.get_subpdu(i); logger.debug("Handling subPDU %d/%d: lcid=%d, sdu_len=%d", i, @@ -145,30 +144,58 @@ int ue_nr::generate_pdu(srsran::byte_buffer_t* pdu, uint32_t grant_size) return SRSRAN_ERROR; } - // read RLC PDU - ue_rlc_buffer->clear(); - int lcid = 4; - int pdu_len = - rlc->read_pdu(rnti, lcid, ue_rlc_buffer->msg, grant_size - mac_pdu_dl.size_header_sdu(lcid, grant_size)); + bool drb_activity = false; // inform RRC about user activity if true + int lcid = 4; // only supporting single DRB right now - // Only create PDU if RLC has something to tx - if (pdu_len > 0) { - logger.debug("Adding MAC PDU for RNTI=%d", rnti); - ue_rlc_buffer->N_bytes = pdu_len; - logger.debug(ue_rlc_buffer->msg, ue_rlc_buffer->N_bytes, "Read %d B from RLC", ue_rlc_buffer->N_bytes); + int32_t remaining_len = mac_pdu_dl.get_remaing_len(); - // add to MAC PDU and pack - mac_pdu_dl.add_sdu(lcid, ue_rlc_buffer->msg, ue_rlc_buffer->N_bytes); + logger.debug("Adding MAC PDU for RNTI=%d (max %d B)", rnti, remaining_len); + while (remaining_len >= MIN_RLC_PDU_LEN) { + // clear read buffer + ue_rlc_buffer->clear(); - // Indicate DRB activity in DL to RRC - if (lcid > 3) { - rrc->set_activity_user(rnti); - logger.debug("DL activity rnti=0x%x, n_bytes=%d", rnti, ue_rlc_buffer->N_bytes); + // Determine space for RLC + remaining_len -= remaining_len >= srsran::mac_sch_subpdu_nr::MAC_SUBHEADER_LEN_THRESHOLD ? 3 : 2; + + // read RLC PDU + int pdu_len = rlc->read_pdu(rnti, lcid, ue_rlc_buffer->msg, remaining_len); + + if (pdu_len > remaining_len) { + logger.error("Can't add SDU of %d B. Available space %d B", pdu_len, remaining_len); + break; + } else { + // Add SDU if RLC has something to tx + if (pdu_len > 0) { + ue_rlc_buffer->N_bytes = pdu_len; + logger.debug(ue_rlc_buffer->msg, ue_rlc_buffer->N_bytes, "Read %d B from RLC", ue_rlc_buffer->N_bytes); + + // add to MAC PDU and pack + if (mac_pdu_dl.add_sdu(lcid, ue_rlc_buffer->msg, ue_rlc_buffer->N_bytes) != SRSRAN_SUCCESS) { + logger.error("Error packing MAC PDU"); + break; + } + + // set DRB activity flag but only notify RRC once + if (lcid > 3) { + drb_activity = true; + } + } else { + break; + } + + remaining_len -= pdu_len; + logger.debug("%d B remaining PDU", remaining_len); } } mac_pdu_dl.pack(); + if (drb_activity) { + // Indicate DRB activity in DL to RRC + rrc->set_activity_user(rnti); + logger.debug("DL activity rnti=0x%x", rnti); + } + if (logger.info.enabled()) { fmt::memory_buffer str_buffer; mac_pdu_dl.to_string(str_buffer);