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
master
Andre Puschmann 3 years ago
parent bef3553586
commit 8ddc344cdb

@ -121,6 +121,17 @@ public:
virtual void write_pdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t pdu) = 0; 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 * RRC INTERFACES
****************************/ ****************************/

@ -37,7 +37,10 @@ struct mac_nr_args_t {
class sched_nr; class sched_nr;
class mac_nr_rx; 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: public:
explicit mac_nr(srsran::task_sched_handle task_sched_); 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; 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; 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 // Test interface
void ul_bsr(uint16_t rnti, uint32_t lcid, uint32_t bsr); void ul_bsr(uint16_t rnti, uint32_t lcid, uint32_t bsr);

@ -48,6 +48,7 @@ public:
uint16_t get_rnti() const { return rnti; } uint16_t get_rnti() const { return rnti; }
void set_active(bool active) { active_state.store(active, std::memory_order_relaxed); } 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); } 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); 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) 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 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 = 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 5; ///< minimum bytes that need to be available in a MAC PDU for attempting to add another RLC SDU

@ -24,6 +24,18 @@
namespace srsenb { 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 class mac_nr_rx
{ {
public: public:
@ -31,8 +43,9 @@ public:
rrc_interface_mac_nr* rrc_, rrc_interface_mac_nr* rrc_,
srsran::task_queue_handle& stack_task_queue_, srsran::task_queue_handle& stack_task_queue_,
sched_nr_interface* sched_, sched_nr_interface* sched_,
mac_interface_pdu_demux_nr& mac_,
srslog::basic_logger& logger_) : srslog::basic_logger& logger_) :
task_queue(stack_task_queue_), rlc(rlc_), rrc(rrc_), sched(sched_), 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) 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: { 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); 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()); 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; } break;
case srsran::mac_sch_subpdu_nr::nr_lcid_sch_t::CRNTI: { case srsran::mac_sch_subpdu_nr::nr_lcid_sch_t::CRNTI: {
uint16_t ce_crnti = subpdu.get_c_rnti(); uint16_t ce_crnti = subpdu.get_c_rnti();
@ -170,6 +186,7 @@ private:
rlc_interface_mac* rlc; rlc_interface_mac* rlc;
rrc_interface_mac_nr* rrc; rrc_interface_mac_nr* rrc;
sched_nr_interface* sched; sched_nr_interface* sched;
mac_interface_pdu_demux_nr& mac;
srslog::basic_logger& logger; srslog::basic_logger& logger;
srsran::task_queue_handle& task_queue; 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)); 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{}; srsran::phy_cfg_nr_default_t::reference_cfg_t ref_args{};
ref_args.duplex = cell_config[0].duplex.mode == SRSRAN_DUPLEX_MODE_TDD 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; 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) 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}; slot_point pdsch_slot = srsran::slot_point{NUMEROLOGY_IDX, slot_cfg.idx};

@ -74,11 +74,27 @@ 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 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(); int32_t remaining_len = mac_pdu_dl.get_remaing_len();
logger.debug("Adding MAC PDU for RNTI=%d (max %d B)", rnti, remaining_len); logger.debug("0x%x Generating MAC PDU (%d B)", rnti, remaining_len);
// 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 {
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) { while (remaining_len >= MIN_RLC_PDU_LEN) {
// clear read buffer // clear read buffer
ue_rlc_buffer->clear(); ue_rlc_buffer->clear();
@ -116,6 +132,8 @@ int ue_nr::generate_pdu(srsran::byte_buffer_t* pdu, uint32_t grant_size, srsran:
logger.debug("%d B remaining PDU", remaining_len); logger.debug("%d B remaining PDU", remaining_len);
} }
} }
}
}
mac_pdu_dl.pack(); mac_pdu_dl.pack();
@ -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 } // namespace srsenb

Loading…
Cancel
Save