mirror of https://github.com/PentHertz/srsLTE.git
Use MAC PDU pointer instead of tti_rx and rnti as a key to associate buffers. Decouple crc_info() and push_pdu() functions. This allows for different timing architectures in the PHY
This commit is contained in:
parent
0498439d41
commit
f9a02299f9
|
@ -160,6 +160,9 @@ public:
|
||||||
/**
|
/**
|
||||||
* Informs MAC about a received PUSCH transmission for given RNTI, TTI and eNb Cell/carrier.
|
* Informs MAC about a received PUSCH transmission for given RNTI, TTI and eNb Cell/carrier.
|
||||||
*
|
*
|
||||||
|
* This function does not deallocate the uplink buffer. The function push_pdu() must be called after this
|
||||||
|
* to inform the MAC that the uplink buffer can be discarded or pushed to the stack
|
||||||
|
*
|
||||||
* @param tti the given TTI
|
* @param tti the given TTI
|
||||||
* @param rnti the UE identifier in the eNb
|
* @param rnti the UE identifier in the eNb
|
||||||
* @param cc_idx the eNb Cell/Carrier identifier
|
* @param cc_idx the eNb Cell/Carrier identifier
|
||||||
|
@ -169,6 +172,18 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual int crc_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, uint32_t nof_bytes, bool crc_res) = 0;
|
virtual int crc_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, uint32_t nof_bytes, bool crc_res) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pushes an uplink PDU through the stack if crc_res==true or discards it if crc_res==false
|
||||||
|
*
|
||||||
|
* @param tti the given TTI
|
||||||
|
* @param rnti the UE identifier in the eNb
|
||||||
|
* @param pdu_ptr pointer to the uplink buffer
|
||||||
|
* @param nof_bytes the number of grants carrierd by the PUSCH message
|
||||||
|
* @param crc_res the CRC check, set to true if the message was decoded succesfully
|
||||||
|
* @return SRSLTE_SUCCESS if no error occurs, SRSLTE_ERROR* if an error occurs
|
||||||
|
*/
|
||||||
|
virtual int push_pdu(uint32_t tti_rx, uint16_t rnti, const uint8_t* pdu_ptr, uint32_t nof_bytes, bool crc_res) = 0;
|
||||||
|
|
||||||
virtual int get_dl_sched(uint32_t tti, dl_sched_list_t& dl_sched_res) = 0;
|
virtual int get_dl_sched(uint32_t tti, dl_sched_list_t& dl_sched_res) = 0;
|
||||||
virtual int get_mch_sched(uint32_t tti, bool is_mcch, dl_sched_list_t& dl_sched_res) = 0;
|
virtual int get_mch_sched(uint32_t tti, bool is_mcch, dl_sched_list_t& dl_sched_res) = 0;
|
||||||
virtual int get_ul_sched(uint32_t tti, ul_sched_list_t& ul_sched_res) = 0;
|
virtual int get_ul_sched(uint32_t tti, ul_sched_list_t& ul_sched_res) = 0;
|
||||||
|
|
|
@ -37,8 +37,8 @@ public:
|
||||||
void init(process_callback* callback, log_ref log_h_);
|
void init(process_callback* callback, log_ref log_h_);
|
||||||
|
|
||||||
uint8_t* request(uint32_t len);
|
uint8_t* request(uint32_t len);
|
||||||
void deallocate(uint8_t* pdu);
|
void deallocate(const uint8_t* pdu);
|
||||||
void push(uint8_t* ptr, uint32_t len, channel_t channel = DCH);
|
void push(const uint8_t* ptr, uint32_t len, channel_t channel = DCH);
|
||||||
|
|
||||||
bool process_pdus();
|
bool process_pdus();
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ uint8_t* pdu_queue::request(uint32_t len)
|
||||||
return pdu->ptr;
|
return pdu->ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pdu_queue::deallocate(uint8_t* pdu)
|
void pdu_queue::deallocate(const uint8_t* pdu)
|
||||||
{
|
{
|
||||||
if (!pool.deallocate((pdu_t*)pdu)) {
|
if (!pool.deallocate((pdu_t*)pdu)) {
|
||||||
log_h->warning("Error deallocating from buffer pool in deallocate(): buffer not created in this pool.\n");
|
log_h->warning("Error deallocating from buffer pool in deallocate(): buffer not created in this pool.\n");
|
||||||
|
@ -53,7 +53,7 @@ void pdu_queue::deallocate(uint8_t* pdu)
|
||||||
* This function enqueues the packet and returns quicly because ACK
|
* This function enqueues the packet and returns quicly because ACK
|
||||||
* deadline is important here.
|
* deadline is important here.
|
||||||
*/
|
*/
|
||||||
void pdu_queue::push(uint8_t* ptr, uint32_t len, channel_t channel)
|
void pdu_queue::push(const uint8_t* ptr, uint32_t len, channel_t channel)
|
||||||
{
|
{
|
||||||
if (ptr) {
|
if (ptr) {
|
||||||
pdu_t* pdu = (pdu_t*)ptr;
|
pdu_t* pdu = (pdu_t*)ptr;
|
||||||
|
|
|
@ -81,6 +81,10 @@ public:
|
||||||
{
|
{
|
||||||
return mac.crc_info(tti, rnti, enb_cc_idx, nof_bytes, crc_res);
|
return mac.crc_info(tti, rnti, enb_cc_idx, nof_bytes, crc_res);
|
||||||
}
|
}
|
||||||
|
int push_pdu(uint32_t tti, uint16_t rnti, const uint8_t* pdu_ptr, uint32_t nof_bytes, bool crc_res) final
|
||||||
|
{
|
||||||
|
return mac.push_pdu(tti, rnti, pdu_ptr, nof_bytes, crc_res);
|
||||||
|
}
|
||||||
int get_dl_sched(uint32_t tti, dl_sched_list_t& dl_sched_res) final { return mac.get_dl_sched(tti, dl_sched_res); }
|
int get_dl_sched(uint32_t tti, dl_sched_list_t& dl_sched_res) final { return mac.get_dl_sched(tti, dl_sched_res); }
|
||||||
int get_mch_sched(uint32_t tti, bool is_mcch, dl_sched_list_t& dl_sched_res) final
|
int get_mch_sched(uint32_t tti, bool is_mcch, dl_sched_list_t& dl_sched_res) final
|
||||||
{
|
{
|
||||||
|
|
|
@ -56,6 +56,7 @@ public:
|
||||||
int ta_info(uint32_t tti, uint16_t rnti, float ta_us) override;
|
int ta_info(uint32_t tti, uint16_t rnti, float ta_us) override;
|
||||||
int ack_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t tb_idx, bool ack) override;
|
int ack_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t tb_idx, bool ack) override;
|
||||||
int crc_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t nof_bytes, bool crc_res) override;
|
int crc_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t nof_bytes, bool crc_res) override;
|
||||||
|
int push_pdu(uint32_t tti, uint16_t rnti, const uint8_t* pdu_ptr, uint32_t nof_bytes, bool crc_res) override;
|
||||||
|
|
||||||
int get_dl_sched(uint32_t tti_tx_dl, dl_sched_list_t& dl_sched_res) override;
|
int get_dl_sched(uint32_t tti_tx_dl, dl_sched_list_t& dl_sched_res) override;
|
||||||
int get_ul_sched(uint32_t tti_tx_ul, ul_sched_list_t& ul_sched_res) override;
|
int get_ul_sched(uint32_t tti_tx_ul, ul_sched_list_t& ul_sched_res) override;
|
||||||
|
|
|
@ -71,10 +71,10 @@ public:
|
||||||
srslte_softbuffer_rx_t* get_rx_softbuffer(const uint32_t ue_cc_idx, const uint32_t tti);
|
srslte_softbuffer_rx_t* get_rx_softbuffer(const uint32_t ue_cc_idx, const uint32_t tti);
|
||||||
|
|
||||||
bool process_pdus();
|
bool process_pdus();
|
||||||
uint8_t* request_buffer(const uint32_t ue_cc_idx, const uint32_t tti, const uint32_t len);
|
uint8_t* request_buffer(const uint32_t len);
|
||||||
void process_pdu(uint8_t* pdu, uint32_t nof_bytes, srslte::pdu_queue::channel_t channel) override;
|
void process_pdu(uint8_t* pdu, uint32_t nof_bytes, srslte::pdu_queue::channel_t channel) override;
|
||||||
void push_pdu(const uint32_t ue_cc_idx, const uint32_t tti, uint32_t len);
|
void push_pdu(const uint8_t* pdu_ptr, uint32_t len);
|
||||||
void deallocate_pdu(const uint32_t ue_cc_idx, const uint32_t tti);
|
void deallocate_pdu(const uint8_t* pdu_ptr);
|
||||||
|
|
||||||
void metrics_read(mac_ue_metrics_t* metrics_);
|
void metrics_read(mac_ue_metrics_t* metrics_);
|
||||||
void metrics_rx(bool crc, uint32_t tbs);
|
void metrics_rx(bool crc, uint32_t tbs);
|
||||||
|
@ -118,9 +118,6 @@ private:
|
||||||
cc_softbuffer_rx_list_t; ///< List of Rx softbuffers for all HARQ processes of one carrier
|
cc_softbuffer_rx_list_t; ///< List of Rx softbuffers for all HARQ processes of one carrier
|
||||||
std::vector<cc_softbuffer_rx_list_t> softbuffer_rx; ///< List of softbuffer lists for Rx
|
std::vector<cc_softbuffer_rx_list_t> softbuffer_rx; ///< List of softbuffer lists for Rx
|
||||||
|
|
||||||
typedef std::vector<uint8_t*> cc_buffer_ptr_t; ///< List of buffer pointers for RX HARQ processes of one carrier
|
|
||||||
std::vector<cc_buffer_ptr_t> pending_buffers; ///< List of buffer pointer list for Rx
|
|
||||||
|
|
||||||
// One buffer per TB per HARQ process and per carrier is needed for each UE.
|
// One buffer per TB per HARQ process and per carrier is needed for each UE.
|
||||||
std::vector<std::array<std::array<srslte::unique_byte_buffer_t, SRSLTE_MAX_TB>, SRSLTE_FDD_NOF_HARQ> >
|
std::vector<std::array<std::array<srslte::unique_byte_buffer_t, SRSLTE_MAX_TB>, SRSLTE_FDD_NOF_HARQ> >
|
||||||
tx_payload_buffer;
|
tx_payload_buffer;
|
||||||
|
|
|
@ -373,7 +373,8 @@ void cc_worker::decode_pusch(stack_interface_phy_lte::ul_sched_grant_t* grants,
|
||||||
if (ul_grant.data != nullptr) {
|
if (ul_grant.data != nullptr) {
|
||||||
// Inform MAC about the CRC result
|
// Inform MAC about the CRC result
|
||||||
phy->stack->crc_info(tti_rx, rnti, cc_idx, ul_cfg.pusch.grant.tb.tbs / 8, pusch_res.crc);
|
phy->stack->crc_info(tti_rx, rnti, cc_idx, ul_cfg.pusch.grant.tb.tbs / 8, pusch_res.crc);
|
||||||
|
// Push PDU buffer
|
||||||
|
phy->stack->push_pdu(tti_rx, rnti, grants[i].data, ul_cfg.pusch.grant.tb.tbs / 8, pusch_res.crc);
|
||||||
// Logging
|
// Logging
|
||||||
if (log_h->get_level() >= srslte::LOG_LEVEL_INFO) {
|
if (log_h->get_level() >= srslte::LOG_LEVEL_INFO) {
|
||||||
char str[512];
|
char str[512];
|
||||||
|
|
|
@ -320,24 +320,28 @@ int mac::crc_info(uint32_t tti_rx, uint16_t rnti, uint32_t enb_cc_idx, uint32_t
|
||||||
ue_db[rnti]->set_tti(tti_rx);
|
ue_db[rnti]->set_tti(tti_rx);
|
||||||
ue_db[rnti]->metrics_rx(crc, nof_bytes);
|
ue_db[rnti]->metrics_rx(crc, nof_bytes);
|
||||||
|
|
||||||
std::array<int, SRSLTE_MAX_CARRIERS> enb_ue_cc_map = scheduler.get_enb_ue_cc_map(rnti);
|
// Scheduler uses eNB's CC mapping
|
||||||
if (enb_ue_cc_map[enb_cc_idx] < 0) {
|
return scheduler.ul_crc_info(tti_rx, rnti, enb_cc_idx, crc);
|
||||||
Error("User rnti=0x%x is not activated for carrier %d\n", rnti, enb_cc_idx);
|
}
|
||||||
|
|
||||||
|
int mac::push_pdu(uint32_t tti_rx, uint16_t rnti, const uint8_t* pdu_ptr, uint32_t nof_bytes, bool crc)
|
||||||
|
{
|
||||||
|
srslte::rwlock_read_guard lock(rwlock);
|
||||||
|
|
||||||
|
if (not check_ue_exists(rnti)) {
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
}
|
}
|
||||||
uint32_t ue_cc_idx = enb_ue_cc_map[enb_cc_idx];
|
|
||||||
|
|
||||||
// push the pdu through the queue if received correctly
|
// push the pdu through the queue if received correctly
|
||||||
if (crc) {
|
if (crc) {
|
||||||
Info("Pushing PDU rnti=0x%x, tti_rx=%d, nof_bytes=%d\n", rnti, tti_rx, nof_bytes);
|
Info("Pushing PDU rnti=0x%x, tti_rx=%d, nof_bytes=%d\n", rnti, tti_rx, nof_bytes);
|
||||||
ue_db[rnti]->push_pdu(ue_cc_idx, tti_rx, nof_bytes);
|
ue_db[rnti]->push_pdu(pdu_ptr, nof_bytes);
|
||||||
stack_task_queue.push([this]() { process_pdus(); });
|
stack_task_queue.push([this]() { process_pdus(); });
|
||||||
} else {
|
} else {
|
||||||
ue_db[rnti]->deallocate_pdu(ue_cc_idx, tti_rx);
|
Debug("Discarting PDU rnti=0x%x, tti_rx=%d, nof_bytes=%d\n", rnti, tti_rx, nof_bytes);
|
||||||
|
ue_db[rnti]->deallocate_pdu(pdu_ptr);
|
||||||
}
|
}
|
||||||
|
return SRSLTE_SUCCESS;
|
||||||
// Scheduler uses eNB's CC mapping
|
|
||||||
return scheduler.ul_crc_info(tti_rx, rnti, enb_cc_idx, crc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int mac::ri_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t ri_value)
|
int mac::ri_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t ri_value)
|
||||||
|
@ -894,8 +898,7 @@ int mac::get_ul_sched(uint32_t tti_tx_ul, ul_sched_list_t& ul_sched_res_list)
|
||||||
if (sched_result.pusch[n].current_tx_nb == 0) {
|
if (sched_result.pusch[n].current_tx_nb == 0) {
|
||||||
srslte_softbuffer_rx_reset_tbs(phy_ul_sched_res->pusch[n].softbuffer_rx, sched_result.pusch[i].tbs * 8);
|
srslte_softbuffer_rx_reset_tbs(phy_ul_sched_res->pusch[n].softbuffer_rx, sched_result.pusch[i].tbs * 8);
|
||||||
}
|
}
|
||||||
phy_ul_sched_res->pusch[n].data =
|
phy_ul_sched_res->pusch[n].data = ue_db[rnti]->request_buffer(sched_result.pusch[i].tbs);
|
||||||
ue_db[rnti]->request_buffer(sched_result.pusch[i].dci.ue_cc_idx, tti_tx_ul, sched_result.pusch[i].tbs);
|
|
||||||
phy_ul_sched_res->nof_grants++;
|
phy_ul_sched_res->nof_grants++;
|
||||||
n++;
|
n++;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -94,15 +94,6 @@ void ue::reset()
|
||||||
srslte_softbuffer_tx_reset(&buffer);
|
srslte_softbuffer_tx_reset(&buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& cc_buffers : pending_buffers) {
|
|
||||||
for (auto& harq_buffer : cc_buffers) {
|
|
||||||
if (harq_buffer) {
|
|
||||||
pdus.deallocate(harq_buffer);
|
|
||||||
harq_buffer = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -123,12 +114,6 @@ uint32_t ue::allocate_cc_buffers(const uint32_t num_cc)
|
||||||
srslte_softbuffer_rx_init(&buffer, nof_prb);
|
srslte_softbuffer_rx_init(&buffer, nof_prb);
|
||||||
}
|
}
|
||||||
|
|
||||||
pending_buffers.emplace_back();
|
|
||||||
pending_buffers.back().resize(nof_rx_harq_proc);
|
|
||||||
for (auto& buffer : pending_buffers.back()) {
|
|
||||||
buffer = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create and init Tx buffers for Pcell
|
// Create and init Tx buffers for Pcell
|
||||||
softbuffer_tx.emplace_back();
|
softbuffer_tx.emplace_back();
|
||||||
softbuffer_tx.back().resize(nof_tx_harq_proc);
|
softbuffer_tx.back().resize(nof_tx_harq_proc);
|
||||||
|
@ -176,20 +161,14 @@ ue::get_tx_softbuffer(const uint32_t ue_cc_idx, const uint32_t harq_process, con
|
||||||
return &softbuffer_tx.at(ue_cc_idx).at((harq_process * SRSLTE_MAX_TB + tb_idx) % nof_tx_harq_proc);
|
return &softbuffer_tx.at(ue_cc_idx).at((harq_process * SRSLTE_MAX_TB + tb_idx) % nof_tx_harq_proc);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t* ue::request_buffer(const uint32_t ue_cc_idx, const uint32_t tti, const uint32_t len)
|
uint8_t* ue::request_buffer(const uint32_t len)
|
||||||
{
|
{
|
||||||
uint8_t* ret = nullptr;
|
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
if (!pending_buffers.at(ue_cc_idx).at(tti % nof_rx_harq_proc)) {
|
return pdus.request(len);
|
||||||
ret = pdus.request(len);
|
|
||||||
pending_buffers.at(ue_cc_idx).at(tti % nof_rx_harq_proc) = ret;
|
|
||||||
} else {
|
|
||||||
log_h->error("Requesting buffer for pid %d, not pushed yet\n", tti % nof_rx_harq_proc);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
log_h->warning("Requesting buffer for zero bytes\n");
|
log_h->warning("Requesting buffer for zero bytes\n");
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ue::process_pdus()
|
bool ue::process_pdus()
|
||||||
|
@ -314,25 +293,21 @@ void ue::process_pdu(uint8_t* pdu, uint32_t nof_bytes, srslte::pdu_queue::channe
|
||||||
Debug("MAC PDU processed\n");
|
Debug("MAC PDU processed\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ue::deallocate_pdu(const uint32_t ue_cc_idx, const uint32_t tti)
|
void ue::deallocate_pdu(const uint8_t* pdu_ptr)
|
||||||
{
|
{
|
||||||
if (pending_buffers.at(ue_cc_idx).at(tti % nof_rx_harq_proc)) {
|
if (pdu_ptr) {
|
||||||
pdus.deallocate(pending_buffers.at(ue_cc_idx).at(tti % nof_rx_harq_proc));
|
pdus.deallocate(pdu_ptr);
|
||||||
pending_buffers.at(ue_cc_idx).at(tti % nof_rx_harq_proc) = nullptr;
|
|
||||||
} else {
|
} else {
|
||||||
srslte::console(
|
Error("Error deallocating PDU: null ptr\n");
|
||||||
"Error deallocating buffer for ue_cc_idx=%d, pid=%d. Not requested\n", ue_cc_idx, tti % nof_rx_harq_proc);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ue::push_pdu(const uint32_t ue_cc_idx, const uint32_t tti, uint32_t len)
|
void ue::push_pdu(const uint8_t* pdu_ptr, uint32_t len)
|
||||||
{
|
{
|
||||||
if (pending_buffers.at(ue_cc_idx).at(tti % nof_rx_harq_proc)) {
|
if (pdu_ptr && len > 0) {
|
||||||
pdus.push(pending_buffers.at(ue_cc_idx).at(tti % nof_rx_harq_proc), len);
|
pdus.push(pdu_ptr, len);
|
||||||
pending_buffers.at(ue_cc_idx).at(tti % nof_rx_harq_proc) = nullptr;
|
|
||||||
} else {
|
} else {
|
||||||
srslte::console(
|
Error("Error pushing PDU: ptr=%p, len=%d\n", pdu_ptr, len);
|
||||||
"Error pushing buffer for ue_cc_idx=%d, pid=%d. Not requested\n", ue_cc_idx, tti % nof_rx_harq_proc);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -289,6 +289,7 @@ private:
|
||||||
CALLBACK(ta_info);
|
CALLBACK(ta_info);
|
||||||
CALLBACK(ack_info);
|
CALLBACK(ack_info);
|
||||||
CALLBACK(crc_info);
|
CALLBACK(crc_info);
|
||||||
|
CALLBACK(push_pdu);
|
||||||
CALLBACK(get_dl_sched);
|
CALLBACK(get_dl_sched);
|
||||||
CALLBACK(get_mch_sched);
|
CALLBACK(get_mch_sched);
|
||||||
CALLBACK(get_ul_sched);
|
CALLBACK(get_ul_sched);
|
||||||
|
@ -492,6 +493,13 @@ public:
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
int push_pdu(uint32_t tti, uint16_t rnti, const uint8_t* pdu_ptr, uint32_t nof_bytes, bool crc_res) override
|
||||||
|
{
|
||||||
|
log_h.info("Received push_pdu tti=%d; rnti=0x%x; ack=%d;\n", tti, rnti, crc_res);
|
||||||
|
notify_push_pdu();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
int get_dl_sched(uint32_t tti, dl_sched_list_t& dl_sched_res) override
|
int get_dl_sched(uint32_t tti, dl_sched_list_t& dl_sched_res) override
|
||||||
{
|
{
|
||||||
// Notify test engine
|
// Notify test engine
|
||||||
|
|
Loading…
Reference in New Issue