gnb,mac: rework DL MAC PDU packing and add ConRes handling

* store Msg3 when UL-CCCH is received
* add ConRes CE in DL-SCH when indicated by scheduler
* remove fixed LCID for packing SDUs
This commit is contained in:
Andre Puschmann 2021-11-23 15:00:30 +01:00
parent bef3553586
commit 8ddc344cdb
5 changed files with 112 additions and 40 deletions

View File

@ -121,6 +121,17 @@ public:
virtual void write_pdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t pdu) = 0;
};
/*****************************
* MAC internal INTERFACES
****************************/
class mac_interface_pdu_demux_nr
{
public:
// Called by PDU handler from Stack thread to store Msg3 content (According to O-RAN WG8 v3.0, Sec. 9.2.2.3.5 MAC)
virtual void store_msg3(uint16_t rnti, srsran::unique_byte_buffer_t pdu) = 0;
};
/*****************************
* RRC INTERFACES
****************************/

View File

@ -37,7 +37,10 @@ struct mac_nr_args_t {
class sched_nr;
class mac_nr_rx;
class mac_nr final : public mac_interface_phy_nr, public mac_interface_rrc_nr, public mac_interface_rlc_nr
class mac_nr final : public mac_interface_phy_nr,
public mac_interface_rrc_nr,
public mac_interface_rlc_nr,
public mac_interface_pdu_demux_nr
{
public:
explicit mac_nr(srsran::task_sched_handle task_sched_);
@ -71,6 +74,9 @@ public:
int pusch_info(const srsran_slot_cfg_t& slot_cfg, pusch_info_t& pusch_info) override;
void rach_detected(const rach_info_t& rach_info) override;
// MAC-internal interface
void store_msg3(uint16_t rnti, srsran::unique_byte_buffer_t pdu) override;
// Test interface
void ul_bsr(uint16_t rnti, uint32_t lcid, uint32_t bsr);

View File

@ -48,6 +48,7 @@ public:
uint16_t get_rnti() const { return rnti; }
void set_active(bool active) { active_state.store(active, std::memory_order_relaxed); }
bool is_active() const { return active_state.load(std::memory_order_relaxed); }
void store_msg3(srsran::unique_byte_buffer_t pdu);
int generate_pdu(srsran::byte_buffer_t* pdu, uint32_t grant_size, srsran::const_span<uint32_t> subpdu_lcids);
@ -98,6 +99,8 @@ private:
ue_rx_pdu_queue; ///< currently only DCH PDUs supported (add BCH, PCH, etc)
srsran::unique_byte_buffer_t ue_rlc_buffer;
srsran::unique_byte_buffer_t last_msg3; ///< holds UE ID received in Msg3 for ConRes CE
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

View File

@ -24,15 +24,28 @@
namespace srsenb {
/**
* @brief Handles UL PDU processing
*
* This class implements the demuxing of UL PDUs received at the MAC layer.
* When the PHY decodes a valid PUSCH it passes the PDU to the MAC which
* in turn puts them in a thread-safe task queue to return to the calling
* thread as quick as possible.
*
* The demuxing of the PDUs for all users takes place on the Stack thread
* which calls RLC and RRC for SDUs, or the MAC/scheduler for control elements.
*
*/
class mac_nr_rx
{
public:
explicit mac_nr_rx(rlc_interface_mac* rlc_,
rrc_interface_mac_nr* rrc_,
srsran::task_queue_handle& stack_task_queue_,
sched_nr_interface* sched_,
srslog::basic_logger& logger_) :
task_queue(stack_task_queue_), rlc(rlc_), rrc(rrc_), sched(sched_), logger(logger_)
explicit mac_nr_rx(rlc_interface_mac* rlc_,
rrc_interface_mac_nr* rrc_,
srsran::task_queue_handle& stack_task_queue_,
sched_nr_interface* sched_,
mac_interface_pdu_demux_nr& mac_,
srslog::basic_logger& logger_) :
task_queue(stack_task_queue_), rlc(rlc_), rrc(rrc_), sched(sched_), mac(mac_), logger(logger_)
{}
void handle_pdu(uint16_t rnti, srsran::unique_byte_buffer_t pdu)
@ -91,6 +104,9 @@ private:
case srsran::mac_sch_subpdu_nr::nr_lcid_sch_t::CCCH_SIZE_64: {
srsran::mac_sch_subpdu_nr& ccch_subpdu = const_cast<srsran::mac_sch_subpdu_nr&>(subpdu);
rlc->write_pdu(rnti, 0, ccch_subpdu.get_sdu(), ccch_subpdu.get_sdu_length());
// store content for ConRes CE
mac.store_msg3(rnti,
srsran::make_byte_buffer(ccch_subpdu.get_sdu(), ccch_subpdu.get_sdu_length(), __FUNCTION__));
} break;
case srsran::mac_sch_subpdu_nr::nr_lcid_sch_t::CRNTI: {
uint16_t ce_crnti = subpdu.get_c_rnti();
@ -170,6 +186,7 @@ private:
rlc_interface_mac* rlc;
rrc_interface_mac_nr* rrc;
sched_nr_interface* sched;
mac_interface_pdu_demux_nr& mac;
srslog::basic_logger& logger;
srsran::task_queue_handle& task_queue;
@ -279,7 +296,7 @@ int mac_nr::cell_cfg(const std::vector<srsenb::sched_nr_interface::cell_cfg_t>&
bcch_dlsch_payload.push_back(std::move(sib));
}
rx.reset(new mac_nr_rx{rlc, rrc, stack_task_queue, sched.get(), logger});
rx.reset(new mac_nr_rx{rlc, rrc, stack_task_queue, sched.get(), *this, logger});
srsran::phy_cfg_nr_default_t::reference_cfg_t ref_args{};
ref_args.duplex = cell_config[0].duplex.mode == SRSRAN_DUPLEX_MODE_TDD
@ -459,6 +476,16 @@ int mac_nr::slot_indication(const srsran_slot_cfg_t& slot_cfg)
return 0;
}
void mac_nr::store_msg3(uint16_t rnti, srsran::unique_byte_buffer_t pdu)
{
srsran::rwlock_read_guard rw_lock(rwmutex);
if (is_rnti_active_nolock(rnti)) {
ue_db[rnti]->store_msg3(std::move(pdu));
} else {
logger.error("User rnti=0x%x not found. Can't store Msg3.", rnti);
}
}
mac_nr::dl_sched_t* mac_nr::get_dl_sched(const srsran_slot_cfg_t& slot_cfg)
{
slot_point pdsch_slot = srsran::slot_point{NUMEROLOGY_IDX, slot_cfg.idx};

View File

@ -74,46 +74,64 @@ int ue_nr::generate_pdu(srsran::byte_buffer_t* pdu, uint32_t grant_size, srsran:
}
bool drb_activity = false; // inform RRC about user activity if true
int lcid = 4; // only supporting single DRB right now
int32_t remaining_len = mac_pdu_dl.get_remaing_len();
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();
logger.debug("0x%x Generating MAC PDU (%d B)", rnti, remaining_len);
// 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;
// First, add CEs as indicated by scheduler
for (const auto& lcid : subpdu_lcids) {
logger.debug("adding lcid=%d", lcid);
if (lcid == srsran::mac_sch_subpdu_nr::CON_RES_ID) {
if (last_msg3 != nullptr) {
srsran::mac_sch_subpdu_nr::ue_con_res_id_t id;
memcpy(id.data(), last_msg3->msg, id.size());
if (mac_pdu_dl.add_ue_con_res_id_ce(id) != SRSRAN_SUCCESS) {
logger.error("0x%x Failed to add ConRes CE.", rnti);
}
last_msg3 = nullptr; // don't use this Msg3 again
} else {
break;
logger.warning("0x%x Can't add ConRes CE. No Msg3 stored.", rnti);
}
} else {
// add SDUs for given LCID
while (remaining_len >= MIN_RLC_PDU_LEN) {
// clear read buffer
ue_rlc_buffer->clear();
remaining_len -= pdu_len;
logger.debug("%d B remaining PDU", remaining_len);
// 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);
}
}
}
}
@ -236,4 +254,11 @@ void ue_nr::metrics_pusch_sinr(float sinr)
}
}
// Called from Stack thread when demuxing UL PDUs
void ue_nr::store_msg3(srsran::unique_byte_buffer_t pdu)
{
std::lock_guard<std::mutex> lock(mutex);
last_msg3 = std::move(pdu);
}
} // namespace srsenb