enb,nsa: fix packing of DL MAC PDUs

* use byte_buffer_t as interface type for DL PHY-MAC interface
* fix missing clear() for new DL tx
master
Andre Puschmann 3 years ago
parent 4a828be39f
commit fc35c0ee51

@ -223,8 +223,8 @@ public:
}; };
struct pdsch_t { struct pdsch_t {
srsran_sch_cfg_nr_t sch = {}; ///< PDSCH configuration srsran_sch_cfg_nr_t sch = {}; ///< PDSCH configuration
std::array<uint8_t*, SRSRAN_MAX_TB> data = {}; ///< Data pointer std::array<srsran::byte_buffer_t*, SRSRAN_MAX_TB> data = {}; ///< Data pointer
}; };
struct ssb_t { struct ssb_t {

@ -85,11 +85,13 @@ public:
dl_harq_proc(uint32_t id_, uint32_t nprb); dl_harq_proc(uint32_t id_, uint32_t nprb);
tx_harq_softbuffer& get_softbuffer() { return *softbuffer; } tx_harq_softbuffer& get_softbuffer() { return *softbuffer; }
uint8_t* get_tx_pdu() { return pdu->msg; } srsran::unique_byte_buffer_t* get_tx_pdu() { return &pdu; }
// clear and reset softbuffer and PDU for new tx
bool set_tbs(uint32_t tbs) bool set_tbs(uint32_t tbs)
{ {
softbuffer->reset(); softbuffer->reset();
pdu->clear();
return harq_proc::set_tbs(tbs); return harq_proc::set_tbs(tbs);
} }

@ -48,13 +48,8 @@ public:
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); }
uint8_t* generate_pdu(uint32_t enb_cc_idx, int generate_pdu(srsran::byte_buffer_t* pdu, uint32_t grant_size);
uint32_t harq_pid, int process_pdu(srsran::unique_byte_buffer_t pdu);
uint32_t tb_idx,
const sched_interface::dl_sched_pdu_t pdu[sched_interface::MAX_RLC_PDU_LIST],
uint32_t nof_pdu_elems,
uint32_t grant_size);
int process_pdu(srsran::unique_byte_buffer_t pdu);
std::mutex metrics_mutex = {}; std::mutex metrics_mutex = {};
void metrics_read(mac_ue_metrics_t* metrics_); void metrics_read(mac_ue_metrics_t* metrics_);

@ -295,8 +295,16 @@ bool slot_worker::work_dl()
// Encode PDSCH // Encode PDSCH
for (stack_interface_phy_nr::pdsch_t& pdsch : dl_sched.pdsch) { for (stack_interface_phy_nr::pdsch_t& pdsch : dl_sched.pdsch) {
// convert MAC to PHY buffer data structures
uint8_t* data[SRSRAN_MAX_TB] = {};
for (uint32_t i = 0; i < SRSRAN_MAX_TB; ++i) {
if (pdsch.data[i] != nullptr) {
data[i] = pdsch.data[i]->msg;
}
}
// Put PDSCH message // Put PDSCH message
if (srsran_gnb_dl_pdsch_put(&gnb_dl, &dl_slot_cfg, &pdsch.sch, pdsch.data.data()) < SRSRAN_SUCCESS) { if (srsran_gnb_dl_pdsch_put(&gnb_dl, &dl_slot_cfg, &pdsch.sch, data) < SRSRAN_SUCCESS) {
logger.error("PDSCH: Error putting DL message"); logger.error("PDSCH: Error putting DL message");
return false; return false;
} }

@ -272,7 +272,21 @@ int mac_nr::get_dl_sched(const srsran_slot_cfg_t& slot_cfg, dl_sched_t& dl_sched
pdsch_slot++; pdsch_slot++;
} }
return sched.get_dl_sched(pdsch_slot, 0, dl_sched); int ret = sched.get_dl_sched(pdsch_slot, 0, dl_sched);
for (pdsch_t& pdsch : dl_sched.pdsch) {
for (auto& tb_data : pdsch.data) {
if (tb_data != nullptr) {
// TODO: exclude retx from packing
uint16_t rnti = pdsch.sch.grant.rnti;
srsran::rwlock_read_guard rw_lock(rwlock);
if (not is_rnti_active_unsafe(rnti)) {
continue;
}
ue_db[rnti]->generate_pdu(tb_data, pdsch.sch.grant.tb->tbs / 8);
}
}
}
return SRSRAN_SUCCESS;
} }
int mac_nr::get_ul_sched(const srsran_slot_cfg_t& slot_cfg, ul_sched_t& ul_sched) int mac_nr::get_ul_sched(const srsran_slot_cfg_t& slot_cfg, ul_sched_t& ul_sched)

@ -230,7 +230,7 @@ alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, const prb_grant& dl_gr
bool ret = ue.cfg->phy().get_pdsch_cfg(slot_cfg, pdcch.dci, pdsch.sch); bool ret = ue.cfg->phy().get_pdsch_cfg(slot_cfg, pdcch.dci, pdsch.sch);
srsran_assert(ret, "Error converting DCI to grant"); srsran_assert(ret, "Error converting DCI to grant");
pdsch.sch.grant.tb[0].softbuffer.tx = ue.h_dl->get_softbuffer().get(); pdsch.sch.grant.tb[0].softbuffer.tx = ue.h_dl->get_softbuffer().get();
pdsch.data[0] = ue.h_dl->get_tx_pdu(); pdsch.data[0] = ue.h_dl->get_tx_pdu()->get();
if (ue.h_dl->nof_retx() == 0) { if (ue.h_dl->nof_retx() == 0) {
ue.h_dl->set_tbs(pdsch.sch.grant.tb[0].tbs); // update HARQ with correct TBS ue.h_dl->set_tbs(pdsch.sch.grant.tb[0].tbs); // update HARQ with correct TBS
} else { } else {

@ -16,6 +16,7 @@
#include <string.h> #include <string.h>
#include "srsenb/hdr/stack/mac/nr/ue_nr.h" #include "srsenb/hdr/stack/mac/nr/ue_nr.h"
#include "srsran/common/buffer_pool.h"
#include "srsran/common/string_helpers.h" #include "srsran/common/string_helpers.h"
#include "srsran/interfaces/gnb_interfaces.h" #include "srsran/interfaces/gnb_interfaces.h"
@ -28,7 +29,13 @@ ue_nr::ue_nr(uint16_t rnti_,
rlc_interface_mac* rlc_, rlc_interface_mac* rlc_,
phy_interface_stack_nr* phy_, phy_interface_stack_nr* phy_,
srslog::basic_logger& logger_) : srslog::basic_logger& logger_) :
rnti(rnti_), sched(sched_), rrc(rrc_), rlc(rlc_), phy(phy_), logger(logger_) rnti(rnti_),
sched(sched_),
rrc(rrc_),
rlc(rlc_),
phy(phy_),
logger(logger_),
ue_rlc_buffer(srsran::make_byte_buffer())
{} {}
ue_nr::~ue_nr() {} ue_nr::~ue_nr() {}
@ -82,47 +89,35 @@ uint32_t ue_nr::read_pdu(uint32_t lcid, uint8_t* payload, uint32_t requested_byt
return rlc->read_pdu(rnti, lcid, payload, requested_bytes); return rlc->read_pdu(rnti, lcid, payload, requested_bytes);
} }
uint8_t* ue_nr::generate_pdu(uint32_t enb_cc_idx, int ue_nr::generate_pdu(srsran::byte_buffer_t* pdu, uint32_t grant_size)
uint32_t harq_pid,
uint32_t tb_idx,
const sched_interface::dl_sched_pdu_t pdu[sched_interface::MAX_RLC_PDU_LIST],
uint32_t nof_pdu_elems,
uint32_t grant_size)
{ {
std::lock_guard<std::mutex> lock(mutex); std::lock_guard<std::mutex> lock(mutex);
uint8_t* ret = nullptr;
if (enb_cc_idx < SRSRAN_MAX_CARRIERS && harq_pid < SRSRAN_FDD_NOF_HARQ && tb_idx < SRSRAN_MAX_TB) { mac_pdu_dl.init_tx(pdu, grant_size);
srsran::byte_buffer_t* buffer = nullptr; // TODO: read from scheduler output
buffer->clear(); // read RLC PDU
ue_rlc_buffer->clear();
mac_pdu_dl.init_tx(buffer, grant_size); int lcid = 4;
int pdu_len = rlc->read_pdu(rnti, lcid, ue_rlc_buffer->msg, grant_size - 2);
// read RLC PDU
ue_rlc_buffer->clear(); // Only create PDU if RLC has something to tx
int lcid = 4; if (pdu_len > 0) {
int pdu_len = rlc->read_pdu(rnti, lcid, ue_rlc_buffer->msg, grant_size - 2); logger.info("Adding MAC PDU for RNTI=%d", rnti);
ue_rlc_buffer->N_bytes = pdu_len;
// Only create PDU if RLC has something to tx logger.info(ue_rlc_buffer->msg, ue_rlc_buffer->N_bytes, "Read %d B from RLC", ue_rlc_buffer->N_bytes);
if (pdu_len > 0) {
logger.info("Adding MAC PDU for RNTI=%d", rnti); // add to MAC PDU and pack
ue_rlc_buffer->N_bytes = pdu_len; mac_pdu_dl.add_sdu(lcid, ue_rlc_buffer->msg, ue_rlc_buffer->N_bytes);
logger.info(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 mac_pdu_dl.pack();
mac_pdu_dl.add_sdu(4, ue_rlc_buffer->msg, ue_rlc_buffer->N_bytes);
mac_pdu_dl.pack(); if (logger.info.enabled()) {
} fmt::memory_buffer str_buffer;
// mac_pdu_dl.to_string(str_buffer);
if (logger.info.enabled()) { logger.info("0x%x %s", rnti, srsran::to_c_str(str_buffer));
fmt::memory_buffer str_buffer;
// mac_pdu_dl.to_string(str_buffer);
logger.info("0x%x %s", rnti, srsran::to_c_str(str_buffer));
}
} else {
logger.error(
"Invalid parameters calling generate_pdu: cc_idx=%d, harq_pid=%d, tb_idx=%d", enb_cc_idx, harq_pid, tb_idx);
} }
return ret; return SRSRAN_SUCCESS;
} }
/******* METRICS interface ***************/ /******* METRICS interface ***************/

@ -202,7 +202,7 @@ private:
// Set TBS // Set TBS
// Select grant and set data // Select grant and set data
pdsch.data[0] = tx_harq_proc[slot_cfg.idx].get_tb(pdsch.sch.grant.tb[0].tbs).data(); pdsch.data[0] = tx_harq_proc[slot_cfg.idx].get_tb(pdsch.sch.grant.tb[0].tbs);
// Set softbuffer // Set softbuffer
pdsch.sch.grant.tb[0].softbuffer.tx = &tx_harq_proc[slot_cfg.idx].get_softbuffer(dci.ndi); pdsch.sch.grant.tb[0].softbuffer.tx = &tx_harq_proc[slot_cfg.idx].get_softbuffer(dci.ndi);
@ -422,7 +422,7 @@ public:
for (pdsch_t& pdsch : dl_sched.pdsch) { for (pdsch_t& pdsch : dl_sched.pdsch) {
// Set TBS // Set TBS
// Select grant and set data // Select grant and set data
pdsch.data[0] = tx_harq_proc[slot_cfg.idx].get_tb(pdsch.sch.grant.tb[0].tbs).data(); pdsch.data[0] = tx_harq_proc[slot_cfg.idx].get_tb(pdsch.sch.grant.tb[0].tbs);
pdsch.data[1] = nullptr; pdsch.data[1] = nullptr;
} }

@ -49,12 +49,12 @@ public:
srsran_random_free(random_gen); srsran_random_free(random_gen);
} }
srsran::byte_buffer_t& get_tb(uint32_t tbs_) srsran::byte_buffer_t* get_tb(uint32_t tbs_)
{ {
std::unique_lock<std::mutex> lock(mutex); std::unique_lock<std::mutex> lock(mutex);
tbs = tbs_; tbs = tbs_;
srsran_random_byte_vector(random_gen, data.msg, tbs / 8); srsran_random_byte_vector(random_gen, data.msg, tbs / 8);
return data; return &data;
} }
srsran_softbuffer_tx_t& get_softbuffer(uint32_t ndi_) srsran_softbuffer_tx_t& get_softbuffer(uint32_t ndi_)

@ -86,7 +86,7 @@ public:
return; return;
} }
action->tb.enabled = true; action->tb.enabled = true;
action->tb.payload = &tx_harq_proc[grant.pid].get_tb(grant.tbs); action->tb.payload = tx_harq_proc[grant.pid].get_tb(grant.tbs);
action->tb.softbuffer = &tx_harq_proc[grant.pid].get_softbuffer(grant.ndi); action->tb.softbuffer = &tx_harq_proc[grant.pid].get_softbuffer(grant.ndi);
} }
void prach_sent(uint32_t tti, uint32_t s_id, uint32_t t_id, uint32_t f_id, uint32_t ul_carrier_id) override {} void prach_sent(uint32_t tti, uint32_t s_id, uint32_t t_id, uint32_t f_id, uint32_t ul_carrier_id) override {}

Loading…
Cancel
Save