mirror of https://github.com/PentHertz/srsLTE.git
SRSUE/SRSENB: UCI bits are carrier by the lowest serving cell index
SRSENB: Fix UCI in lowest serving cell index PUSCH transmission
This commit is contained in:
parent
c8b4ba885b
commit
0192130742
|
@ -1383,6 +1383,7 @@ void srslte_ue_dl_gen_ack(const srslte_cell_t* cell,
|
|||
const srslte_pdsch_ack_t* ack_info,
|
||||
srslte_uci_data_t* uci_data)
|
||||
{
|
||||
uci_data->value.ack.valid = true; //< Always true for UE transmitter
|
||||
if (cell->frame_type == SRSLTE_FDD) {
|
||||
gen_ack_fdd(ack_info, uci_data);
|
||||
} else {
|
||||
|
|
|
@ -103,8 +103,7 @@ private:
|
|||
// Do nothing
|
||||
}
|
||||
|
||||
bool is_grant_available = false;
|
||||
srslte_phich_grant_t phich_grant = {};
|
||||
srslte_phich_grant_t phich_grant = {};
|
||||
|
||||
void metrics_read(phy_metrics_t* metrics);
|
||||
void metrics_dl(uint32_t mcs);
|
||||
|
|
|
@ -86,6 +86,7 @@ private:
|
|||
uint8_t last_ri = 0; ///< Last reported rank indicator
|
||||
std::array<srslte_ra_tb_t, SRSLTE_MAX_HARQ_PROC> last_tb = {}; ///< Stores last PUSCH Resource allocation
|
||||
srslte::phy_cfg_t phy_cfg; ///< Configuration, it has a default constructor
|
||||
std::array<bool, TTIMOD_SZ> is_grant_available; ///< Indicates whether there is an available grant
|
||||
} cell_info_t;
|
||||
|
||||
/**
|
||||
|
@ -156,6 +157,18 @@ private:
|
|||
*/
|
||||
inline uint32_t _get_ue_cc_idx(uint16_t rnti, uint32_t enb_cc_idx) const;
|
||||
|
||||
/**
|
||||
* Gets the eNb Cell/Carrier index in which the UCI shall be carried. This corresponds to the serving cell with lowest
|
||||
* index that has an UL grant available.
|
||||
*
|
||||
* If no grant is available in the indicated TTI, it returns the number of the eNb Cells/Carriers.
|
||||
*
|
||||
* @param tti The UL processing TTI
|
||||
* @param rnti Temporal UE ID
|
||||
* @return the eNb Cell/Carrier with lowest serving cell index that has an UL grant
|
||||
*/
|
||||
uint32_t _get_uci_enb_cc_idx(uint32_t tti, uint16_t rnti) const;
|
||||
|
||||
/**
|
||||
* Checks if a given RNTI exists in the database
|
||||
* @param rnti provides UE identifier
|
||||
|
@ -358,7 +371,7 @@ public:
|
|||
* identifier.
|
||||
*
|
||||
* @param rnti the UE temporal ID
|
||||
* @param cc_idx the cell/carrier origin of the transmission
|
||||
* @param enb_cc_idx the cell/carrier origin of the transmission
|
||||
* @param pid HARQ process identifier
|
||||
* @param tb the Resource Allocation for the PUSCH transport block
|
||||
*/
|
||||
|
@ -375,6 +388,14 @@ public:
|
|||
* @return the Resource Allocation for the PUSCH transport block
|
||||
*/
|
||||
srslte_ra_tb_t get_last_ul_tb(uint16_t rnti, uint32_t enb_cc_idx, uint32_t pid) const;
|
||||
|
||||
/**
|
||||
* Flags to true the UL grant available for a given TTI, RNTI and eNb cell/carrier index
|
||||
* @param tti the current TTI
|
||||
* @param rnti
|
||||
* @param enb_cc_idx
|
||||
*/
|
||||
void set_ul_grant_available(uint32_t tti, const stack_interface_phy_lte::ul_sched_list_t& ul_sched_list);
|
||||
};
|
||||
|
||||
} // namespace srsenb
|
||||
|
|
|
@ -227,10 +227,6 @@ void cc_worker::work_ul(const srslte_ul_sf_cfg_t& ul_sf_cfg, stack_interface_phy
|
|||
ul_sf = ul_sf_cfg;
|
||||
log_h->step(ul_sf.tti);
|
||||
|
||||
for (auto& ue : ue_db) {
|
||||
ue.second->is_grant_available = false;
|
||||
}
|
||||
|
||||
// Process UL signal
|
||||
srslte_enb_ul_fft(&enb_ul);
|
||||
|
||||
|
@ -291,11 +287,13 @@ void cc_worker::decode_pusch_rnti(stack_interface_phy_lte::ul_sched_grant_t& ul_
|
|||
// Get UE configuration
|
||||
ul_cfg = phy->ue_db.get_ul_config(rnti, cc_idx);
|
||||
|
||||
// mark this tti as having an ul dci to avoid pucch
|
||||
ue_db[rnti]->is_grant_available = true;
|
||||
|
||||
// Fill UCI configuration
|
||||
phy->ue_db.fill_uci_cfg(tti_rx, cc_idx, rnti, ul_grant.dci.cqi_request, true, ul_cfg.pusch.uci_cfg);
|
||||
bool uci_required =
|
||||
phy->ue_db.fill_uci_cfg(tti_rx, cc_idx, rnti, ul_grant.dci.cqi_request, true, ul_cfg.pusch.uci_cfg);
|
||||
|
||||
if (ul_cfg.pusch.softbuffers.rx) {
|
||||
srslte_softbuffer_rx_reset(ul_cfg.pusch.softbuffers.rx);
|
||||
}
|
||||
|
||||
// Compute UL grant
|
||||
srslte_pusch_grant_t& grant = ul_cfg.pusch.grant;
|
||||
|
@ -347,7 +345,9 @@ void cc_worker::decode_pusch_rnti(stack_interface_phy_lte::ul_sched_grant_t& ul_
|
|||
}
|
||||
|
||||
// Send UCI data to MAC
|
||||
phy->ue_db.send_uci_data(tti_rx, rnti, cc_idx, ul_cfg.pusch.uci_cfg, pusch_res.uci);
|
||||
if (uci_required) {
|
||||
phy->ue_db.send_uci_data(tti_rx, rnti, cc_idx, ul_cfg.pusch.uci_cfg, pusch_res.uci);
|
||||
}
|
||||
|
||||
// Save statistics only if data was provided
|
||||
if (ul_grant.data != nullptr) {
|
||||
|
@ -393,7 +393,7 @@ int cc_worker::decode_pucch()
|
|||
uint16_t rnti = iter.first;
|
||||
|
||||
// If it's a User RNTI and doesn't have PUSCH grant in this TTI
|
||||
if (SRSLTE_RNTI_ISUSER(rnti) and not ue_db[rnti]->is_grant_available and phy->ue_db.is_pcell(rnti, cc_idx)) {
|
||||
if (SRSLTE_RNTI_ISUSER(rnti) and phy->ue_db.is_pcell(rnti, cc_idx)) {
|
||||
srslte_ul_cfg_t ul_cfg = phy->ue_db.get_ul_config(rnti, cc_idx);
|
||||
|
||||
// Check if user needs to receive PUCCH
|
||||
|
|
|
@ -101,6 +101,7 @@ inline void phy_ue_db::_set_common_config_rnti(uint16_t rnti, srslte::phy_cfg_t&
|
|||
phy_cfg.ul_cfg.pucch.threshold_format1 = SRSLTE_PUCCH_DEFAULT_THRESHOLD_FORMAT1;
|
||||
phy_cfg.ul_cfg.pucch.threshold_data_valid_format1a = SRSLTE_PUCCH_DEFAULT_THRESHOLD_FORMAT1A;
|
||||
phy_cfg.ul_cfg.pucch.threshold_data_valid_format2 = SRSLTE_PUCCH_DEFAULT_THRESHOLD_FORMAT2;
|
||||
phy_cfg.ul_cfg.pucch.threshold_data_valid_format3 = SRSLTE_PUCCH_DEFAULT_THRESHOLD_FORMAT3;
|
||||
phy_cfg.ul_cfg.pucch.threshold_dmrs_detection = SRSLTE_PUCCH_DEFAULT_THRESHOLD_DMRS;
|
||||
}
|
||||
|
||||
|
@ -119,6 +120,18 @@ inline uint32_t phy_ue_db::_get_ue_cc_idx(uint16_t rnti, uint32_t enb_cc_idx) co
|
|||
return ue_cc_idx;
|
||||
}
|
||||
|
||||
uint32_t phy_ue_db::_get_uci_enb_cc_idx(uint32_t tti, uint16_t rnti) const
|
||||
{
|
||||
// Find the lowest index available PUSCH grant
|
||||
for (const cell_info_t& cell_info : ue_db.at(rnti).cell_info) {
|
||||
if (cell_info.is_grant_available[TTIMOD(tti)]) {
|
||||
return cell_info.enb_cc_idx;
|
||||
}
|
||||
}
|
||||
|
||||
return (uint32_t)cell_cfg_list->size();
|
||||
}
|
||||
|
||||
inline int phy_ue_db::_assert_rnti(uint16_t rnti) const
|
||||
{
|
||||
if (not ue_db.count(rnti)) {
|
||||
|
@ -456,13 +469,32 @@ 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 PCell
|
||||
if (_assert_enb_pcell(rnti, enb_cc_idx) != SRSLTE_SUCCESS) {
|
||||
// Assert Cell List configuration
|
||||
if (_assert_cell_list_cfg() != SRSLTE_SUCCESS) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Assert Cell List configuration
|
||||
if (_assert_cell_list_cfg() != SRSLTE_SUCCESS) {
|
||||
// Assert eNb Cell/Carrier for the given RNTI
|
||||
if (_assert_active_enb_cc(rnti, enb_cc_idx) != SRSLTE_SUCCESS) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the eNb cell/carrier index with lowest serving cell index (ue_cc_idx) that has an available grant.
|
||||
uint32_t uci_enb_cc_id = _get_uci_enb_cc_idx(tti, rnti);
|
||||
bool pusch_grant_available = (uci_enb_cc_id < (uint32_t)cell_cfg_list->size());
|
||||
|
||||
// There is a PUSCH grant available for the provided RNTI in at least one serving cell and this call is for PUCCH
|
||||
if (pusch_grant_available and not is_pusch_available) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// There is a PUSCH grant and enb_cc_idx with lowest ue_cc_idx with a grant
|
||||
if (pusch_grant_available and uci_enb_cc_id != enb_cc_idx) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// No PUSCH grant for this TTI and cell and no enb_cc_idx is not the PCell
|
||||
if (not pusch_grant_available and _get_ue_cc_idx(rnti, enb_cc_idx) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -524,8 +556,8 @@ void phy_ue_db::send_uci_data(uint32_t tti,
|
|||
{
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
|
||||
// Assert UE RNTI database entry and eNb cell/carrier must be primary cell
|
||||
if (_assert_enb_pcell(rnti, enb_cc_idx) != SRSLTE_SUCCESS) {
|
||||
// Assert UE RNTI database entry and eNb cell/carrier must be active
|
||||
if (_assert_active_enb_cc(rnti, enb_cc_idx) != SRSLTE_SUCCESS) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -639,3 +671,29 @@ srslte_ra_tb_t phy_ue_db::get_last_ul_tb(uint16_t rnti, uint32_t enb_cc_idx, uin
|
|||
// Returns the latest stored UL transmission grant
|
||||
return ue_db.at(rnti).cell_info[_get_ue_cc_idx(rnti, enb_cc_idx)].last_tb[pid % SRSLTE_FDD_NOF_HARQ];
|
||||
}
|
||||
|
||||
void phy_ue_db::set_ul_grant_available(uint32_t tti, const stack_interface_phy_lte::ul_sched_list_t& ul_sched_list)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
|
||||
// Reset all available grants flags for the given TTI
|
||||
for (auto& ue : ue_db) {
|
||||
for (cell_info_t& cell_info : ue.second.cell_info) {
|
||||
cell_info.is_grant_available[TTIMOD(tti)] = false;
|
||||
}
|
||||
}
|
||||
|
||||
// For each eNb Cell/Carrier grant set a flag to the corresponding RNTI
|
||||
for (uint32_t enb_cc_idx = 0; enb_cc_idx < (uint32_t)ul_sched_list.size(); enb_cc_idx++) {
|
||||
const stack_interface_phy_lte::ul_sched_t& ul_sched = ul_sched_list[enb_cc_idx];
|
||||
for (uint32_t i = 0; i < ul_sched.nof_grants; i++) {
|
||||
const stack_interface_phy_lte::ul_sched_grant_t& ul_sched_grant = ul_sched.pusch[i];
|
||||
uint16_t rnti = ul_sched_grant.dci.rnti;
|
||||
// Check that eNb Cell/Carrier is active for the given RNTI
|
||||
if (_assert_active_enb_cc(rnti, enb_cc_idx) == SRSLTE_SUCCESS) {
|
||||
// Rise Grant available flag
|
||||
ue_db[rnti].cell_info[_get_ue_cc_idx(rnti, enb_cc_idx)].is_grant_available[TTIMOD(tti)] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -203,6 +203,9 @@ void sf_worker::work_imp()
|
|||
// Configure UL subframe
|
||||
ul_sf.tti = tti_rx;
|
||||
|
||||
// Set UL grant availability prior to any UL processing
|
||||
phy->ue_db.set_ul_grant_available(tti_rx, ul_grants);
|
||||
|
||||
// Process UL
|
||||
for (uint32_t cc = 0; cc < cc_workers.size(); cc++) {
|
||||
cc_workers[cc]->work_ul(ul_sf, ul_grants[cc]);
|
||||
|
|
|
@ -1127,6 +1127,12 @@ int rrc::ue::fill_scell_to_addmod_list(asn1::rrc::rrc_conn_recfg_r8_ies_s* conn_
|
|||
srslte::set_phy_cfg_t_scell_config(&scell_phy_rrc_ded.phy_cfg, cell);
|
||||
scell_phy_rrc_ded.configured = true;
|
||||
|
||||
// Set PUSCH dedicated configuration following 3GPP TS 36.331 R 10 Section 6.3.2 Radio resource control information
|
||||
// elements - PUSCH-Config
|
||||
// One value applies for all serving cells with an uplink (the associated functionality is common i.e. not
|
||||
// performed independently for each cell).
|
||||
scell_phy_rrc_ded.phy_cfg.ul_cfg.pusch.uci_offset = phy_rrc_dedicated_list[0].phy_cfg.ul_cfg.pusch.uci_offset;
|
||||
|
||||
// Get corresponding eNB CC index
|
||||
scell_phy_rrc_ded.enb_cc_idx = cc_cfg->enb_cc_idx;
|
||||
|
||||
|
|
|
@ -187,8 +187,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
bool tx(srslte::rf_buffer_interface& buffer,
|
||||
const srslte::rf_timestamp_interface& tx_time) override
|
||||
bool tx(srslte::rf_buffer_interface& buffer, const srslte::rf_timestamp_interface& tx_time) override
|
||||
{
|
||||
int err = SRSLTE_SUCCESS;
|
||||
|
||||
|
@ -209,8 +208,7 @@ public:
|
|||
return err >= SRSLTE_SUCCESS;
|
||||
}
|
||||
void tx_end() override {}
|
||||
bool rx_now(srslte::rf_buffer_interface& buffer,
|
||||
srslte::rf_timestamp_interface& rxd_time) override
|
||||
bool rx_now(srslte::rf_buffer_interface& buffer, srslte::rf_timestamp_interface& rxd_time) override
|
||||
{
|
||||
int err = SRSLTE_SUCCESS;
|
||||
|
||||
|
@ -981,8 +979,32 @@ public:
|
|||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
void fill_uci(uint32_t cc_idx,
|
||||
srslte_ue_ul_cfg_t& ue_ul_cfg,
|
||||
srslte_uci_data_t& uci_data,
|
||||
srslte_pdsch_ack_t& pdsch_ack,
|
||||
srslte_pusch_data_t& pusch_data)
|
||||
{
|
||||
// Generate scheduling request
|
||||
srslte_ue_ul_gen_sr(&ue_ul_cfg, &sf_ul_cfg, &uci_data, (bool)(sf_ul_cfg.tti % 20 == 0));
|
||||
|
||||
// Generate Acknowledgements
|
||||
srslte_ue_dl_gen_ack(&ue_dl_v[cc_idx]->cell, &sf_dl_cfg, &pdsch_ack, &uci_data);
|
||||
|
||||
if (uci_data.cfg.cqi.ri_len) {
|
||||
last_ri[uci_data.cfg.cqi.scell_index] = uci_data.value.ri;
|
||||
}
|
||||
|
||||
// Set UCI only for lowest serving cell index
|
||||
pusch_data.uci = uci_data.value;
|
||||
ue_ul_cfg.ul_cfg.pusch.uci_cfg = uci_data.cfg;
|
||||
ue_ul_cfg.ul_cfg.pucch.uci_cfg = uci_data.cfg;
|
||||
}
|
||||
|
||||
int work_ul(srslte_pdsch_ack_t& pdsch_ack, srslte_uci_data_t& uci_data)
|
||||
{
|
||||
bool first_pusch = true;
|
||||
|
||||
// Zero all IQ UL buffers
|
||||
for (auto& buffer : buffers) {
|
||||
srslte_vec_cf_zero(buffer, SRSLTE_SF_LEN_PRB(ue_ul_v[0]->cell.nof_prb));
|
||||
|
@ -1022,28 +1044,15 @@ public:
|
|||
ue_ul_cfg.ul_cfg.pusch.softbuffers.tx = &softbuffer_tx;
|
||||
ue_ul_cfg.grant_available = true;
|
||||
pdsch_ack.is_pusch_available = true;
|
||||
}
|
||||
|
||||
// Generate
|
||||
if (i == 0) {
|
||||
// Generate scheduling request
|
||||
srslte_ue_ul_gen_sr(&ue_ul_cfg, &sf_ul_cfg, &uci_data, (bool)(sf_ul_cfg.tti % 20 == 0));
|
||||
// Generate UCI data
|
||||
if (first_pusch) {
|
||||
fill_uci(cc_idx, ue_ul_cfg, uci_data, pdsch_ack, pusch_data);
|
||||
|
||||
// Generate Acknowledgements
|
||||
srslte_ue_dl_gen_ack(&ue_dl_v[cc_idx]->cell, &sf_dl_cfg, &pdsch_ack, &uci_data);
|
||||
|
||||
if (uci_data.cfg.cqi.ri_len) {
|
||||
last_ri[uci_data.cfg.cqi.scell_index] = uci_data.value.ri;
|
||||
first_pusch = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Set UCI only for PCel
|
||||
if (i == 0) {
|
||||
pusch_data.uci = uci_data.value;
|
||||
ue_ul_cfg.ul_cfg.pusch.uci_cfg = uci_data.cfg;
|
||||
ue_ul_cfg.ul_cfg.pucch.uci_cfg = uci_data.cfg;
|
||||
}
|
||||
|
||||
// Work UL
|
||||
TESTASSERT(srslte_ue_ul_encode(ue_ul_v[cc_idx], &sf_ul_cfg, &ue_ul_cfg, &pusch_data) >= SRSLTE_SUCCESS);
|
||||
|
||||
|
@ -1054,6 +1063,31 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
// If no PUSCH, send PUCCH
|
||||
if (first_pusch) {
|
||||
uint32_t cc_idx = phy_rrc_cfg[0].enb_cc_idx;
|
||||
srslte::phy_cfg_t& dedicated = phy_rrc_cfg[0].phy_cfg;
|
||||
|
||||
srslte_ue_ul_cfg_t ue_ul_cfg = {};
|
||||
ue_ul_cfg.ul_cfg = dedicated.ul_cfg;
|
||||
ue_ul_cfg.ul_cfg.pusch.softbuffers.tx = &softbuffer_tx;
|
||||
ue_ul_cfg.ul_cfg.pucch.rnti = rnti;
|
||||
ue_ul_cfg.cc_idx = 0; // SCell index
|
||||
|
||||
srslte_pusch_data_t pusch_data = {};
|
||||
|
||||
fill_uci(cc_idx, ue_ul_cfg, uci_data, pdsch_ack, pusch_data);
|
||||
|
||||
// Work UL PUCCH
|
||||
TESTASSERT(srslte_ue_ul_encode(ue_ul_v[cc_idx], &sf_ul_cfg, &ue_ul_cfg, &pusch_data) >= SRSLTE_SUCCESS);
|
||||
|
||||
char str[256] = {};
|
||||
srslte_ue_ul_info(&ue_ul_cfg, &sf_ul_cfg, &pusch_data.uci, str, sizeof(str));
|
||||
if (str[0]) {
|
||||
log_h.info("[UL INFO %d] %s\n", 0, str);
|
||||
}
|
||||
}
|
||||
|
||||
// Write eNb Rx
|
||||
radio->write_rx(buffers, sf_len);
|
||||
|
||||
|
@ -1226,6 +1260,8 @@ public:
|
|||
dedicated.ul_cfg.pucch.n1_pucch_an_cs[2][1] = N_pucch_1 + 5;
|
||||
dedicated.ul_cfg.pucch.n1_pucch_an_cs[3][1] = N_pucch_1 + 6;
|
||||
dedicated.ul_cfg.pusch.uci_offset.I_offset_ack = 7;
|
||||
dedicated.ul_cfg.pusch.uci_offset.I_offset_ri = 7;
|
||||
dedicated.ul_cfg.pusch.uci_offset.I_offset_cqi = 7;
|
||||
|
||||
// Configure UE PHY
|
||||
std::array<bool, SRSLTE_MAX_CARRIERS> activation = {}; ///< Activation/Deactivation vector
|
||||
|
|
|
@ -52,6 +52,8 @@ public:
|
|||
void set_crnti(uint16_t rnti);
|
||||
void enable_pregen_signals(bool enabled);
|
||||
|
||||
void set_uci_periodic_cqi(srslte_uci_data_t* uci_data);
|
||||
|
||||
bool work_dl_regular();
|
||||
bool work_dl_mbsfn(srslte_mbsfn_cfg_t mbsfn_cfg);
|
||||
bool work_ul(srslte_uci_data_t* uci_data);
|
||||
|
@ -84,7 +86,6 @@ private:
|
|||
/* Methods for UL */
|
||||
bool encode_uplink(mac_interface_phy_lte::tb_action_ul_t* action, srslte_uci_data_t* uci_data);
|
||||
void set_uci_sr(srslte_uci_data_t* uci_data);
|
||||
void set_uci_periodic_cqi(srslte_uci_data_t* uci_data);
|
||||
void set_uci_aperiodic_cqi(srslte_uci_data_t* uci_data);
|
||||
void set_uci_ack(srslte_uci_data_t* uci_data, bool is_grant_available, uint32_t dai_ul, bool is_pusch_available);
|
||||
uint32_t get_wideband_cqi();
|
||||
|
|
|
@ -130,6 +130,14 @@ public:
|
|||
void set_ul_pending_grant(srslte_dl_sf_cfg_t* sf, uint32_t cc_idx, srslte_dci_ul_t* dci);
|
||||
bool get_ul_pending_grant(srslte_ul_sf_cfg_t* sf, uint32_t cc_idx, uint32_t* pid, srslte_dci_ul_t* dci);
|
||||
|
||||
/**
|
||||
* If there is a UL Grant it returns the lowest index component carrier that has a grant, otherwise it returns 0.
|
||||
*
|
||||
* @param tti_tx TTI in which the transmission is happening
|
||||
* @return The number of carrier if a grant is available, otherwise 0
|
||||
*/
|
||||
uint32_t get_ul_uci_cc(uint32_t tti_tx) const;
|
||||
|
||||
void set_rar_grant_tti(uint32_t tti);
|
||||
|
||||
void set_dl_pending_ack(srslte_dl_sf_cfg_t* sf,
|
||||
|
@ -138,10 +146,7 @@ public:
|
|||
srslte_pdsch_ack_resource_t resource);
|
||||
bool get_dl_pending_ack(srslte_ul_sf_cfg_t* sf, uint32_t cc_idx, srslte_pdsch_ack_cc_t* ack);
|
||||
|
||||
void worker_end(void* h,
|
||||
bool tx_enable,
|
||||
srslte::rf_buffer_t& buffer,
|
||||
srslte::rf_timestamp_t& tx_time);
|
||||
void worker_end(void* h, bool tx_enable, srslte::rf_buffer_t& buffer, srslte::rf_timestamp_t& tx_time);
|
||||
|
||||
void set_cell(const srslte_cell_t& c);
|
||||
void set_nof_workers(uint32_t nof_workers);
|
||||
|
@ -184,7 +189,7 @@ private:
|
|||
std::mutex mtch_mutex;
|
||||
std::condition_variable mtch_cvar;
|
||||
|
||||
uint32_t nof_workers = 0;
|
||||
uint32_t nof_workers = 0;
|
||||
|
||||
bool is_pending_tx_end = false;
|
||||
|
||||
|
@ -216,7 +221,7 @@ private:
|
|||
srslte_dci_ul_t dci;
|
||||
} pending_ul_grant_t;
|
||||
pending_ul_grant_t pending_ul_grant[TTIMOD_SZ][SRSLTE_MAX_CARRIERS] = {};
|
||||
std::mutex pending_ul_grant_mutex;
|
||||
mutable std::mutex pending_ul_grant_mutex;
|
||||
|
||||
typedef struct {
|
||||
bool enable;
|
||||
|
|
|
@ -85,10 +85,10 @@ cc_worker::cc_worker(uint32_t cc_idx_, uint32_t max_prb, srsue::phy_common* phy_
|
|||
phy->set_pdsch_cfg(&pmch_cfg.pdsch_cfg); // set same config in PMCH decoder
|
||||
|
||||
// Define MBSFN subframes channel estimation and save default one
|
||||
chest_mbsfn_cfg.filter_type = SRSLTE_CHEST_FILTER_TRIANGLE;
|
||||
chest_mbsfn_cfg.filter_coef[0] = 0.1;
|
||||
chest_mbsfn_cfg.estimator_alg = SRSLTE_ESTIMATOR_ALG_INTERPOLATE;
|
||||
chest_mbsfn_cfg.noise_alg = SRSLTE_NOISE_ALG_PSS;
|
||||
chest_mbsfn_cfg.filter_type = SRSLTE_CHEST_FILTER_TRIANGLE;
|
||||
chest_mbsfn_cfg.filter_coef[0] = 0.1;
|
||||
chest_mbsfn_cfg.estimator_alg = SRSLTE_ESTIMATOR_ALG_INTERPOLATE;
|
||||
chest_mbsfn_cfg.noise_alg = SRSLTE_NOISE_ALG_PSS;
|
||||
|
||||
chest_default_cfg = ue_dl_cfg.chest_cfg;
|
||||
|
||||
|
@ -641,17 +641,12 @@ bool cc_worker::work_ul(srslte_uci_data_t* uci_data)
|
|||
pid = phy->ul_pidof(CURRENT_TTI_TX, &sf_cfg_ul.tdd_config);
|
||||
}
|
||||
|
||||
/* Generate CQI reports if required, note that in case both aperiodic
|
||||
* and periodic ones present, only aperiodic is sent (36.213 section 7.2) */
|
||||
if (ul_grant_available && dci_ul.cqi_request) {
|
||||
/*
|
||||
* Generate aperiodic CQI report if required, note that in case both aperiodic and periodic ones present, only
|
||||
* aperiodic is sent (36.213 section 7.2)
|
||||
*/
|
||||
if (ul_grant_available and dci_ul.cqi_request and uci_data != nullptr) {
|
||||
set_uci_aperiodic_cqi(uci_data);
|
||||
} else {
|
||||
/* Check PCell and enabled secondary cells */
|
||||
if (cc_idx == 0 || phy->scell_cfg[cc_idx].enabled) {
|
||||
// 3GPP 36.213 Section 7.2
|
||||
// If the UE is configured with more than one serving cell, it transmits CSI for activated serving cell(s) only.
|
||||
set_uci_periodic_cqi(uci_data);
|
||||
}
|
||||
}
|
||||
|
||||
/* Send UL dci or HARQ information (from PHICH) to MAC and receive actions*/
|
||||
|
@ -690,14 +685,14 @@ bool cc_worker::work_ul(srslte_uci_data_t* uci_data)
|
|||
}
|
||||
|
||||
// PCell sends SR and ACK
|
||||
if (cc_idx == 0) {
|
||||
if (uci_data != nullptr) {
|
||||
set_uci_sr(uci_data);
|
||||
// This must be called after set_uci_sr() and set_uci_*_cqi
|
||||
set_uci_ack(uci_data, ul_grant_available, dci_ul.dai, ul_action.tb.enabled);
|
||||
}
|
||||
|
||||
// Generate uplink signal, include uci data on only PCell
|
||||
signal_ready = encode_uplink(&ul_action, (cc_idx == 0) ? uci_data : nullptr);
|
||||
signal_ready = encode_uplink(&ul_action, uci_data);
|
||||
|
||||
// Prepare to receive ACK through PHICH
|
||||
if (ul_action.expect_ack) {
|
||||
|
@ -927,7 +922,7 @@ void cc_worker::set_config(srslte::phy_cfg_t& phy_cfg)
|
|||
}
|
||||
}
|
||||
|
||||
void cc_worker::upd_config_dci(srslte_dci_cfg_t &dci_cfg)
|
||||
void cc_worker::upd_config_dci(srslte_dci_cfg_t& dci_cfg)
|
||||
{
|
||||
ue_dl_cfg.cfg.dci = dci_cfg;
|
||||
}
|
||||
|
|
|
@ -364,6 +364,18 @@ bool phy_common::get_ul_pending_grant(srslte_ul_sf_cfg_t* sf, uint32_t cc_idx, u
|
|||
return ret;
|
||||
}
|
||||
|
||||
uint32_t phy_common::get_ul_uci_cc(uint32_t tti_tx) const
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(pending_ul_grant_mutex);
|
||||
for (uint32_t cc = 0; cc < args->nof_carriers; cc++) {
|
||||
const pending_ul_grant_t& grant = pending_ul_grant[TTIMOD(tti_tx)][cc];
|
||||
if (grant.enable) {
|
||||
return cc;
|
||||
}
|
||||
}
|
||||
return 0; // Return Primary cell
|
||||
}
|
||||
|
||||
// SF->TTI at which PHICH is received
|
||||
void phy_common::set_ul_received_ack(srslte_dl_sf_cfg_t* sf,
|
||||
uint32_t cc_idx,
|
||||
|
|
|
@ -245,12 +245,22 @@ void sf_worker::work_imp()
|
|||
srslte_uci_data_t uci_data;
|
||||
reset_uci(&uci_data);
|
||||
|
||||
// Loop through all carriers. Do in reverse order since control information from SCells is transmitted in PCell
|
||||
uint32_t uci_cc_idx = phy->get_ul_uci_cc(TTI_TX(tti));
|
||||
|
||||
// Fill periodic CQI data; In case of periodic CSI report collision, lower carrier index have preference, so
|
||||
// iterate through all carriers in inverse order.
|
||||
for (int carrier_idx = phy->args->nof_carriers - 1; carrier_idx >= 0; carrier_idx--) {
|
||||
tx_signal_ready |= cc_workers[carrier_idx]->work_ul(&uci_data);
|
||||
if (carrier_idx == 0 or phy->scell_cfg[carrier_idx].configured) {
|
||||
cc_workers[carrier_idx]->set_uci_periodic_cqi(&uci_data);
|
||||
}
|
||||
}
|
||||
|
||||
// Loop through all carriers
|
||||
for (uint32_t carrier_idx = 0; carrier_idx < phy->args->nof_carriers; carrier_idx++) {
|
||||
tx_signal_ready |= cc_workers[carrier_idx]->work_ul(uci_cc_idx == carrier_idx ? &uci_data : nullptr);
|
||||
|
||||
// Set signal pointer based on offset
|
||||
tx_signal_ptr.set((uint32_t)carrier_idx, 0, phy->args->nof_rx_ant, cc_workers[carrier_idx]->get_tx_buffer(0));
|
||||
tx_signal_ptr.set(carrier_idx, 0, phy->args->nof_rx_ant, cc_workers[carrier_idx]->get_tx_buffer(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue