SRSENB: remove assert macros from phy_ue_db.cc

This commit is contained in:
Xavier Arteaga 2020-03-10 17:21:15 +01:00 committed by Andre Puschmann
parent bf6db92f04
commit 47b7c1b72b
2 changed files with 226 additions and 139 deletions

View File

@ -129,10 +129,69 @@ private:
* is found among the configured cells/carriers. Otherwise, it returns SRSLTE_MAX_CARRIERS.
*
* @param rnti identifier of the UE (requires assertion prior to call)
* @param cc_idx the eNb cell/carrier index to look for in the RNTI.
* @param enb_cc_idx the eNb cell/carrier index to look for in the RNTI.
* @return the SCell index as described above.
*/
inline uint32_t _get_cell_idx(uint16_t rnti, uint32_t cc_idx) const;
inline uint32_t _get_ue_cc_idx(uint16_t rnti, uint32_t enb_cc_idx) const;
/**
* Checks if a given RNTI exists in the database
* @param rnti provides UE identifier
* @return SRSLTE_SUCCESS if the indicated RNTI exists, otherwise it returns SRSLTE_ERROR
*/
inline int _assert_rnti(uint16_t rnti) const;
/**
* Checks if an RNTI is configured to use an specified eNb cell/carrier as PCell or SCell
* @param rnti provides UE identifier
* @param enb_cc_idx provides eNb cell/carrier
* @return SRSLTE_SUCCESS if the indicated RNTI exists, otherwise it returns SRSLTE_ERROR
*/
inline int _assert_enb_cc(uint16_t rnti, uint32_t enb_cc_idx) const;
/**
* Checks if an RNTI uses a given eNb cell/carrier as PCell
* @param rnti provides UE identifier
* @param enb_cc_idx provides eNb cell/carrier index
* @return SRSLTE_SUCCESS if the indicated eNb cell/carrier of the RNTI is a PCell, otherwise it returns SRSLTE_ERROR
*/
inline int _assert_enb_pcell(uint16_t rnti, uint32_t enb_cc_idx) const;
/**
* Checks if an RNTI is configured to use an specified UE cell/carrier as PCell or SCell
* @param rnti provides UE identifier
* @param ue_cc_idx UE cell/carrier index that is asserted
* @return SRSLTE_SUCCESS if the indicated cell/carrier index is valid, otherwise it returns SRSLTE_ERROR
*/
inline int _assert_ue_cc(uint16_t rnti, uint32_t ue_cc_idx);
/**
* Checks if an RNTI is configured to use an specified UE cell/carrier as PCell or SCell and it is active
* @param rnti provides UE identifier
* @param ue_cc_idx UE cell/carrier index that is asserted
* @return SRSLTE_SUCCESS if the indicated cell/carrier is active, otherwise it returns SRSLTE_ERROR
*/
inline int _assert_active_ue_cc(uint16_t rnti, uint32_t ue_cc_idx);
/**
* Checks if an RNTI is configured to use an specified eNb cell/carrier as PCell or SCell and it is active
* @param rnti provides UE identifier
* @param enb_cc_idx UE cell/carrier index that is asserted
* @return SRSLTE_SUCCESS if the indicated eNb cell/carrier is active, otherwise it returns SRSLTE_ERROR
*/
inline int _assert_active_enb_cc(uint16_t rnti, uint32_t enb_cc_idx) const;
/**
* Internal eNb stack assertion
* @return SRSLTE_SUCCESS if available, otherwise it returns SRSLTE_ERROR
*/
inline int _assert_stack() const;
/**
* Internal eNb Cell list assertion
* @return SRSLTE_SUCCESS if available, otherwise it returns SRSLTE_ERROR
*/
inline int _assert_cell_list_cfg() const;
public:
/**
@ -166,7 +225,7 @@ public:
* @param scell_idx
* @param activate
*/
void activate_deactivate_scell(uint16_t rnti, uint32_t scell_idx, bool activate);
void activate_deactivate_scell(uint16_t rnti, uint32_t ue_cc_idx, bool activate);
/**
* Get the current physical layer configuration for an RNTI and an eNb cell/carrier
@ -174,7 +233,7 @@ public:
* @param rnti identifier of the UE
* @param cc_idx the eNb cell/carrier identifier
*/
srslte::phy_cfg_t get_config(uint16_t rnti, uint32_t cc_idx) const;
srslte::phy_cfg_t get_config(uint16_t rnti, uint32_t enb_cc_idx) const;
/**
* Removes all the pending ACKs of all the RNTIs for a given TTI
@ -191,7 +250,7 @@ public:
* @param dci carries the Transport Block and required scheduling information
*
*/
void set_ack_pending(uint32_t tti, uint32_t cc_idx, const srslte_dci_dl_t& dci);
void set_ack_pending(uint32_t tti, uint32_t enb_cc_idx, const srslte_dci_dl_t& dci);
/**
* Fills the Uplink Control Information (UCI) configuration and returns true/false idicating if UCI bits are required.
@ -203,7 +262,7 @@ public:
* @return true if UCI decoding is required and false otherwise
*/
bool fill_uci_cfg(uint32_t tti,
uint32_t cc_idx,
uint32_t enb_cc_idx,
uint16_t rnti,
bool aperiodic_cqi_request,
srslte_uci_cfg_t& uci_cfg) const;
@ -217,7 +276,7 @@ public:
*/
void send_uci_data(uint32_t tti,
uint16_t rnti,
uint32_t cc_idx,
uint32_t enb_cc_idx,
const srslte_uci_cfg_t& uci_cfg,
const srslte_uci_value_t& uci_value);
@ -230,7 +289,7 @@ public:
* @param pid HARQ process identifier
* @param tb the Resource Allocation for the PUSCH transport block
*/
void set_last_ul_tb(uint16_t rnti, uint32_t cc_idx, uint32_t pid, srslte_ra_tb_t tb);
void set_last_ul_tb(uint16_t rnti, uint32_t enb_cc_idx, uint32_t pid, srslte_ra_tb_t tb);
/**
* Get the latest UL Transport Block resource allocation for a given RNTI, eNb cell/carrier and UL HARQ process
@ -242,7 +301,7 @@ public:
* @param pid HARQ process identifier
* @return the Resource Allocation for the PUSCH transport block
*/
srslte_ra_tb_t get_last_ul_tb(uint16_t rnti, uint32_t cc_idx, uint32_t pid) const;
srslte_ra_tb_t get_last_ul_tb(uint16_t rnti, uint32_t enb_cc_idx, uint32_t pid) const;
};
} // namespace srsenb

View File

@ -110,19 +110,125 @@ inline void phy_ue_db::_set_common_config_rnti(uint16_t rnti)
}
}
inline uint32_t phy_ue_db::_get_cell_idx(uint16_t rnti, uint32_t cc_idx) const
inline uint32_t phy_ue_db::_get_ue_cc_idx(uint16_t rnti, uint32_t enb_cc_idx) const
{
uint32_t cell_idx = 0;
uint32_t ue_cc_idx = 0;
const common_ue& ue = ue_db.at(rnti);
for (cell_idx = 0; cell_idx < SRSLTE_MAX_CARRIERS; cell_idx++) {
const cell_info_t& scell_info = ue.cell_info[cell_idx];
if (scell_info.enb_cc_idx == cc_idx && scell_info.state != cell_state_secondary_inactive) {
return cell_idx;
for (ue_cc_idx = 0; ue_cc_idx < SRSLTE_MAX_CARRIERS; ue_cc_idx++) {
const cell_info_t& scell_info = ue.cell_info[ue_cc_idx];
if (scell_info.enb_cc_idx == enb_cc_idx and scell_info.state != cell_state_secondary_inactive) {
return ue_cc_idx;
}
}
return cell_idx;
return ue_cc_idx;
}
inline int phy_ue_db::_assert_rnti(uint16_t rnti) const
{
if (not ue_db.count(rnti)) {
ERROR("Trying to access RNTI x%x, it does not exist.\n", rnti);
return SRSLTE_ERROR;
}
return SRSLTE_SUCCESS;
}
inline int phy_ue_db::_assert_enb_cc(uint16_t rnti, uint32_t enb_cc_idx) const
{
// Assert RNTI exist
if (_assert_rnti(rnti) != SRSLTE_SUCCESS) {
return SRSLTE_ERROR;
}
// Check Component Carrier is part of UE SCell map
if (_get_ue_cc_idx(rnti, enb_cc_idx) == SRSLTE_MAX_CARRIERS) {
ERROR("Trying to access cell/carrier index %d in RNTI x%x. It does not exist.\n", enb_cc_idx, rnti);
return SRSLTE_ERROR;
}
return SRSLTE_SUCCESS;
}
inline int phy_ue_db::_assert_enb_pcell(uint16_t rnti, uint32_t enb_cc_idx) const
{
if (_assert_enb_cc(rnti, enb_cc_idx) != SRSLTE_SUCCESS) {
return SRSLTE_ERROR;
}
// Check cell is PCell
const cell_info_t& cell_info = ue_db.at(rnti).cell_info[_get_ue_cc_idx(rnti, enb_cc_idx)];
if (cell_info.state != cell_state_primary) {
return SRSLTE_ERROR;
}
return SRSLTE_SUCCESS;
}
inline int phy_ue_db::_assert_ue_cc(uint16_t rnti, uint32_t ue_cc_idx)
{
if (_assert_rnti(rnti) != SRSLTE_SUCCESS) {
return SRSLTE_ERROR;
}
// Check SCell is active, ignore PCell state
if (ue_cc_idx == SRSLTE_MAX_CARRIERS) {
ERROR("Out-of-bounds UE cell/carrier %d for RNTI x%x.\n", ue_cc_idx, rnti);
return SRSLTE_ERROR;
}
return SRSLTE_SUCCESS;
}
inline int phy_ue_db::_assert_active_ue_cc(uint16_t rnti, uint32_t ue_cc_idx)
{
if (_assert_ue_cc(rnti, ue_cc_idx) != SRSLTE_SUCCESS) {
return SRSLTE_ERROR;
}
// Return error if not PCell or not Active SCell
auto& cell_info = ue_db.at(rnti).cell_info[ue_cc_idx];
if (cell_info.state != cell_state_primary and cell_info.state != cell_state_secondary_active) {
ERROR("Failed to assert active UE cell/carrier %d for RNTI x%x", ue_cc_idx, rnti);
return SRSLTE_ERROR;
}
return SRSLTE_SUCCESS;
}
inline int phy_ue_db::_assert_active_enb_cc(uint16_t rnti, uint32_t enb_cc_idx) const
{
if (_assert_enb_cc(rnti, enb_cc_idx) != SRSLTE_SUCCESS) {
return SRSLTE_ERROR;
}
// Check SCell is active, ignore PCell state
auto& cell_info = ue_db.at(rnti).cell_info[_get_ue_cc_idx(rnti, enb_cc_idx)];
if (cell_info.state != cell_state_primary and cell_info.state != cell_state_secondary_active) {
ERROR("Failed to assert active eNb cell/carrier %d for RNTI x%x", enb_cc_idx, rnti);
return SRSLTE_ERROR;
}
return SRSLTE_SUCCESS;
}
inline int phy_ue_db::_assert_stack() const
{
if (not stack) {
return SRSLTE_ERROR;
}
return SRSLTE_SUCCESS;
}
inline int phy_ue_db::_assert_cell_list_cfg() const
{
if (not cell_cfg_list) {
return SRSLTE_ERROR;
}
return SRSLTE_SUCCESS;
}
void phy_ue_db::clear_tti_pending_ack(uint32_t tti)
@ -188,111 +294,18 @@ void phy_ue_db::rem_rnti(uint16_t rnti)
}
}
/**
* UE Database Assert macros. These macros avoid repeating code for asserting RNTI, eNb cell/carrier index, SCell
* indexes and so on.
*
* They are const friendly. All the methods they use of the attributes are const, so they do not modify any attribute.
*/
#define UE_DB_ASSERT_RNTI(RNTI, RET) \
do { \
if (not ue_db.count(RNTI)) { \
/*ERROR("Trying to access RNTI x%x, it does not exist.\n", RNTI);*/ \
return RET; \
} \
} while (false)
#define UE_DB_ASSERT_CELL(RNTI, CC_IDX, RET) \
do { \
/* Check if the UE exists */ \
UE_DB_ASSERT_RNTI(RNTI, RET); \
\
/* Check Component Carrier is part of UE SCell map*/ \
if (_get_cell_idx(RNTI, CC_IDX) == SRSLTE_MAX_CARRIERS) { \
ERROR("Trying to access cell/carrier index %d in RNTI x%x. It does not exist.\n", CC_IDX, RNTI); \
return RET; \
} \
\
/* Check SCell index is in range */ \
const uint32_t cell_idx = _get_cell_idx(RNTI, CC_IDX); \
if (cell_idx == SRSLTE_MAX_CARRIERS) { \
ERROR("Corrupted Cell index %d for RNTI x%x and cell/carrier index %d\n", cell_idx, RNTI, CC_IDX); \
return RET; \
} \
} while (false)
#define UE_DB_ASSERT_ACTIVE_CELL(RNTI, CC_IDX, RET) \
do { \
/* Assert RNTI exists and eNb cell/carrier is configured */ \
UE_DB_ASSERT_CELL(RNTI, CC_IDX, RET); \
\
/* Check Cell is active */ \
auto& cell_info = ue_db.at(RNTI).cell_info[_get_cell_idx(RNTI, CC_IDX)]; \
if (cell_info.state != cell_state_primary and cell_info.state != cell_state_secondary_active) { \
return RET; \
} \
} while (false)
#define UE_DB_ASSERT_PCELL(RNTI, CC_IDX, RET) \
do { \
/* Assert RNTI exists and eNb cell/carrier is configured */ \
UE_DB_ASSERT_CELL(RNTI, CC_IDX, RET); \
\
/* CC_IDX is the RNTI PCell */ \
if (_get_cell_idx(RNTI, CC_IDX) != 0) { \
return RET; \
} \
} while (false)
#define UE_DB_ASSERT_SCELL(RNTI, CELL_IDX, RET) \
do { \
/* Assert RNTI exists and eNb cell/carrier is configured */ \
UE_DB_ASSERT_RNTI(RNTI, RET); \
\
/* Check SCell index is in range */ \
if (CELL_IDX >= SRSLTE_MAX_CARRIERS) { \
ERROR("Out-of-bounds SCell index %d for RNTI x%x.\n", CELL_IDX, RNTI); \
return RET; \
} \
} while (false)
#define UE_DB_ASSERT_ACTIVE_SCELL(RNTI, CELL_IDX, RET) \
do { \
/* Assert RNTI exists and eNb cell/carrier is configured */ \
UE_DB_ASSERT_SCELL(RNTI, CELL_IDX, RET); \
\
/* Check SCell is active, ignore PCell state */ \
auto& cell_info = ue_db.at(RNTI).cell_info[CELL_IDX]; \
if (CELL_IDX != 0 && cell_info.state != cell_state_secondary_active) { \
ERROR("Failed to assert active SCell %d for RNTI x%x", CELL_IDX, RNTI); \
return RET; \
} \
} while (false)
#define UE_DB_ASSERT_STACK(RET) \
do { \
if (not stack) { \
return RET; \
} \
} while (false)
#define UE_DB_ASSERT_CELL_LIST_CFG(RET) \
do { \
if (not cell_cfg_list) { \
return RET; \
} \
} while (false)
void phy_ue_db::activate_deactivate_scell(uint16_t rnti, uint32_t cell_idx, bool activate)
void phy_ue_db::activate_deactivate_scell(uint16_t rnti, uint32_t ue_cc_idx, bool activate)
{
// Assert RNTI and SCell are valid
UE_DB_ASSERT_SCELL(rnti, cell_idx, /* void */);
if (_assert_ue_cc(rnti, ue_cc_idx) != SRSLTE_SUCCESS) {
return;
}
auto& cell_info = ue_db[rnti].cell_info[cell_idx];
cell_info_t& cell_info = ue_db[rnti].cell_info[ue_cc_idx];
// If scell is default only complain
if (activate and cell_info.state == cell_state_none) {
ERROR("RNTI x%x SCell %d has received an activation MAC command but it was not configured\n", rnti, cell_idx);
ERROR("RNTI x%x SCell %d has received an activation MAC command but it was not configured\n", rnti, ue_cc_idx);
return;
}
@ -300,7 +313,7 @@ void phy_ue_db::activate_deactivate_scell(uint16_t rnti, uint32_t cell_idx, bool
cell_info.state = (activate) ? cell_state_secondary_active : cell_state_secondary_inactive;
}
srslte::phy_cfg_t phy_ue_db::get_config(uint16_t rnti, uint32_t cc_idx) const
srslte::phy_cfg_t phy_ue_db::get_config(uint16_t rnti, uint32_t enb_cc_idx) const
{
std::lock_guard<std::mutex> lock(mutex);
@ -310,32 +323,35 @@ srslte::phy_cfg_t phy_ue_db::get_config(uint16_t rnti, uint32_t cc_idx) const
default_cfg.ul_cfg.pusch.rnti = rnti;
default_cfg.ul_cfg.pucch.rnti = rnti;
UE_DB_ASSERT_ACTIVE_CELL(rnti, cc_idx, default_cfg);
if (_assert_active_enb_cc(rnti, enb_cc_idx) != SRSLTE_SUCCESS) {
return default_cfg;
}
return ue_db.at(rnti).cell_info[_get_cell_idx(rnti, cc_idx)].phy_cfg;
return ue_db.at(rnti).cell_info[_get_ue_cc_idx(rnti, enb_cc_idx)].phy_cfg;
}
void phy_ue_db::set_ack_pending(uint32_t tti, uint32_t cc_idx, const srslte_dci_dl_t& dci)
void phy_ue_db::set_ack_pending(uint32_t tti, uint32_t enb_cc_idx, const srslte_dci_dl_t& dci)
{
std::lock_guard<std::mutex> lock(mutex);
// Assert rnti and cell exits and it is active
UE_DB_ASSERT_ACTIVE_CELL(dci.rnti, cc_idx, /* void */);
if (_assert_active_enb_cc(dci.rnti, enb_cc_idx) != SRSLTE_SUCCESS) {
return;
}
common_ue& ue = ue_db[dci.rnti];
uint32_t scell_idx = _get_cell_idx(dci.rnti, cc_idx);
uint32_t ue_cc_idx = _get_ue_cc_idx(dci.rnti, enb_cc_idx);
srslte_pdsch_ack_cc_t& pdsch_ack_cc = ue.pdsch_ack[TTIMOD(tti)].cc[scell_idx];
srslte_pdsch_ack_cc_t& pdsch_ack_cc = ue.pdsch_ack[TTIMOD(tti)].cc[ue_cc_idx];
pdsch_ack_cc.M = 1; ///< Hardcoded for FDD
// Fill PDSCH ACK information
srslte_pdsch_ack_m_t& pdsch_ack_m = pdsch_ack_cc.m[0]; ///< Assume FDD only
pdsch_ack_m.present = true;
pdsch_ack_m.resource.grant_cc_idx = cc_idx; ///< Assumes no cross-carrier scheduling
pdsch_ack_m.resource.v_dai_dl = 0; ///< Ignore for FDD
pdsch_ack_m.resource.grant_cc_idx = ue_cc_idx; ///< Assumes no cross-carrier scheduling
pdsch_ack_m.resource.v_dai_dl = 0; ///< Ignore for FDD
pdsch_ack_m.resource.n_cce = dci.location.ncce;
pdsch_ack_m.resource.tpc_for_pucch = dci.tpc_pucch;
pdsch_ack_m.resource.grant_cc_idx = scell_idx;
// Set TB info
for (uint32_t i = 0; i < srslte_dci_format_max_tb(dci.format); i++) {
@ -347,7 +363,7 @@ void phy_ue_db::set_ack_pending(uint32_t tti, uint32_t cc_idx, const srslte_dci_
}
bool phy_ue_db::fill_uci_cfg(uint32_t tti,
uint32_t cc_idx,
uint32_t enb_cc_idx,
uint16_t rnti,
bool aperiodic_cqi_request,
srslte_uci_cfg_t& uci_cfg) const
@ -357,11 +373,15 @@ bool phy_ue_db::fill_uci_cfg(uint32_t tti,
// Reset UCI CFG, avoid returning carrying cached information
uci_cfg = {};
// Assert rnti and cell exits and it is active
UE_DB_ASSERT_PCELL(rnti, cc_idx, false);
// Assert rnti and cell exits and it is PCell
if (_assert_enb_pcell(rnti, enb_cc_idx) != SRSLTE_SUCCESS) {
return false;
}
// Assert Cell List configuration
UE_DB_ASSERT_CELL_LIST_CFG(false);
if (_assert_cell_list_cfg() != SRSLTE_SUCCESS) {
return false;
}
const auto& ue = ue_db.at(rnti);
const auto& pcell_cfg = ue.cell_info[0].phy_cfg;
@ -412,17 +432,21 @@ bool phy_ue_db::fill_uci_cfg(uint32_t tti,
void phy_ue_db::send_uci_data(uint32_t tti,
uint16_t rnti,
uint32_t cc_idx,
uint32_t enb_cc_idx,
const srslte_uci_cfg_t& uci_cfg,
const srslte_uci_value_t& uci_value)
{
std::lock_guard<std::mutex> lock(mutex);
// Assert UE RNTI database entry and eNb cell/carrier must be primary cell
UE_DB_ASSERT_PCELL(rnti, cc_idx, /* void */);
if (_assert_enb_pcell(rnti, enb_cc_idx) != SRSLTE_SUCCESS) {
return;
}
// Assert Stack
UE_DB_ASSERT_STACK(/* void */);
if (_assert_stack() != SRSLTE_SUCCESS) {
return;
}
// Notify SR
if (uci_cfg.is_scheduling_request_tti && uci_value.scheduling_request) {
@ -449,7 +473,7 @@ void phy_ue_db::send_uci_data(uint32_t tti,
}
// Assert the SCell exists and it is active
UE_DB_ASSERT_ACTIVE_SCELL(rnti, uci_cfg.cqi.scell_index, /* void */);
_assert_active_ue_cc(rnti, uci_cfg.cqi.scell_index);
// Get CQI carrier index
auto& cqi_scell_info = ue_db.at(rnti).cell_info[uci_cfg.cqi.scell_index];
@ -502,24 +526,28 @@ void phy_ue_db::send_uci_data(uint32_t tti,
}
}
void phy_ue_db::set_last_ul_tb(uint16_t rnti, uint32_t cc_idx, uint32_t pid, srslte_ra_tb_t tb)
void phy_ue_db::set_last_ul_tb(uint16_t rnti, uint32_t enb_cc_idx, uint32_t pid, srslte_ra_tb_t tb)
{
std::lock_guard<std::mutex> lock(mutex);
// Assert UE DB entry
UE_DB_ASSERT_ACTIVE_CELL(rnti, cc_idx, /* void */);
if (_assert_active_enb_cc(rnti, enb_cc_idx) != SRSLTE_SUCCESS) {
return;
}
// Save resource allocation
ue_db.at(rnti).cell_info[_get_cell_idx(rnti, cc_idx)].last_tb[pid % SRSLTE_FDD_NOF_HARQ] = tb;
ue_db.at(rnti).cell_info[_get_ue_cc_idx(rnti, enb_cc_idx)].last_tb[pid % SRSLTE_FDD_NOF_HARQ] = tb;
}
srslte_ra_tb_t phy_ue_db::get_last_ul_tb(uint16_t rnti, uint32_t cc_idx, uint32_t pid) const
srslte_ra_tb_t phy_ue_db::get_last_ul_tb(uint16_t rnti, uint32_t enb_cc_idx, uint32_t pid) const
{
std::lock_guard<std::mutex> lock(mutex);
// Assert UE DB entry
UE_DB_ASSERT_ACTIVE_CELL(rnti, cc_idx, {});
if (_assert_active_enb_cc(rnti, enb_cc_idx) != SRSLTE_SUCCESS) {
return {};
}
// Returns the latest stored UL transmission grant
return ue_db.at(rnti).cell_info[_get_cell_idx(rnti, cc_idx)].last_tb[pid % SRSLTE_FDD_NOF_HARQ];
return ue_db.at(rnti).cell_info[_get_ue_cc_idx(rnti, enb_cc_idx)].last_tb[pid % SRSLTE_FDD_NOF_HARQ];
}