mirror of https://github.com/PentHertz/srsLTE.git
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:
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;
|
||||
};
|
||||
|
||||
/*****************************
|
||||
* 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
|
||||
****************************/
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue