|
|
|
@ -17,25 +17,25 @@
|
|
|
|
|
|
|
|
|
|
namespace srsue {
|
|
|
|
|
namespace nr {
|
|
|
|
|
cc_worker::cc_worker(uint32_t cc_idx_, srslog::basic_logger& log, state* phy_state_) :
|
|
|
|
|
cc_worker::cc_worker(uint32_t cc_idx_, srslog::basic_logger& log, state& phy_state_) :
|
|
|
|
|
cc_idx(cc_idx_), phy(phy_state_), logger(log)
|
|
|
|
|
{
|
|
|
|
|
cf_t* rx_buffer_c[SRSRAN_MAX_PORTS] = {};
|
|
|
|
|
|
|
|
|
|
// Allocate buffers
|
|
|
|
|
buffer_sz = SRSRAN_SF_LEN_PRB(phy->args.dl.nof_max_prb) * 5;
|
|
|
|
|
for (uint32_t i = 0; i < phy_state_->args.dl.nof_rx_antennas; i++) {
|
|
|
|
|
buffer_sz = SRSRAN_SF_LEN_PRB(phy.args.dl.nof_max_prb) * 5;
|
|
|
|
|
for (uint32_t i = 0; i < phy.args.dl.nof_rx_antennas; i++) {
|
|
|
|
|
rx_buffer[i] = srsran_vec_cf_malloc(buffer_sz);
|
|
|
|
|
rx_buffer_c[i] = rx_buffer[i];
|
|
|
|
|
tx_buffer[i] = srsran_vec_cf_malloc(buffer_sz);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (srsran_ue_dl_nr_init(&ue_dl, rx_buffer.data(), &phy_state_->args.dl) < SRSRAN_SUCCESS) {
|
|
|
|
|
if (srsran_ue_dl_nr_init(&ue_dl, rx_buffer.data(), &phy.args.dl) < SRSRAN_SUCCESS) {
|
|
|
|
|
ERROR("Error initiating UE DL NR");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (srsran_ue_ul_nr_init(&ue_ul, tx_buffer[0], &phy_state_->args.ul) < SRSRAN_SUCCESS) {
|
|
|
|
|
if (srsran_ue_ul_nr_init(&ue_ul, tx_buffer[0], &phy.args.ul) < SRSRAN_SUCCESS) {
|
|
|
|
|
ERROR("Error initiating UE DL NR");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
@ -67,38 +67,38 @@ cc_worker::~cc_worker()
|
|
|
|
|
|
|
|
|
|
bool cc_worker::update_cfg()
|
|
|
|
|
{
|
|
|
|
|
if (srsran_ue_dl_nr_set_carrier(&ue_dl, &phy->cfg.carrier) < SRSRAN_SUCCESS) {
|
|
|
|
|
if (srsran_ue_dl_nr_set_carrier(&ue_dl, &phy.cfg.carrier) < SRSRAN_SUCCESS) {
|
|
|
|
|
ERROR("Error setting carrier");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (srsran_ue_ul_nr_set_carrier(&ue_ul, &phy->cfg.carrier) < SRSRAN_SUCCESS) {
|
|
|
|
|
if (srsran_ue_ul_nr_set_carrier(&ue_ul, &phy.cfg.carrier) < SRSRAN_SUCCESS) {
|
|
|
|
|
ERROR("Error setting carrier");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
srsran_dci_cfg_nr_t dci_cfg = phy->cfg.get_dci_cfg();
|
|
|
|
|
if (srsran_ue_dl_nr_set_pdcch_config(&ue_dl, &phy->cfg.pdcch, &dci_cfg) < SRSRAN_SUCCESS) {
|
|
|
|
|
srsran_dci_cfg_nr_t dci_cfg = phy.cfg.get_dci_cfg();
|
|
|
|
|
if (srsran_ue_dl_nr_set_pdcch_config(&ue_dl, &phy.cfg.pdcch, &dci_cfg) < SRSRAN_SUCCESS) {
|
|
|
|
|
logger.error("Error setting NR PDCCH configuration");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double abs_freq_point_a_freq =
|
|
|
|
|
srsran::srsran_band_helper().nr_arfcn_to_freq(phy->cfg.carrier.absolute_frequency_point_a);
|
|
|
|
|
double abs_freq_ssb_freq = srsran::srsran_band_helper().nr_arfcn_to_freq(phy->cfg.carrier.absolute_frequency_ssb);
|
|
|
|
|
srsran::srsran_band_helper().nr_arfcn_to_freq(phy.cfg.carrier.absolute_frequency_point_a);
|
|
|
|
|
double abs_freq_ssb_freq = srsran::srsran_band_helper().nr_arfcn_to_freq(phy.cfg.carrier.absolute_frequency_ssb);
|
|
|
|
|
|
|
|
|
|
double carrier_center_freq = abs_freq_point_a_freq + (phy->cfg.carrier.nof_prb / 2 *
|
|
|
|
|
SRSRAN_SUBC_SPACING_NR(phy->cfg.carrier.scs) * SRSRAN_NRE);
|
|
|
|
|
double carrier_center_freq =
|
|
|
|
|
abs_freq_point_a_freq + (phy.cfg.carrier.nof_prb / 2 * SRSRAN_SUBC_SPACING_NR(phy.cfg.carrier.scs) * SRSRAN_NRE);
|
|
|
|
|
uint16_t band = srsran::srsran_band_helper().get_band_from_dl_freq_Hz(carrier_center_freq);
|
|
|
|
|
|
|
|
|
|
srsran_ssb_cfg_t ssb_cfg = {};
|
|
|
|
|
ssb_cfg.srate_hz = srsran_min_symbol_sz_rb(phy->cfg.carrier.nof_prb) * SRSRAN_SUBC_SPACING_NR(phy->cfg.carrier.scs);
|
|
|
|
|
ssb_cfg.srate_hz = srsran_min_symbol_sz_rb(phy.cfg.carrier.nof_prb) * SRSRAN_SUBC_SPACING_NR(phy.cfg.carrier.scs);
|
|
|
|
|
ssb_cfg.center_freq_hz = carrier_center_freq;
|
|
|
|
|
ssb_cfg.ssb_freq_hz = abs_freq_ssb_freq;
|
|
|
|
|
ssb_cfg.scs = phy->cfg.ssb.scs;
|
|
|
|
|
ssb_cfg.pattern = srsran::srsran_band_helper().get_ssb_pattern(band, phy->cfg.ssb.scs);
|
|
|
|
|
ssb_cfg.scs = phy.cfg.ssb.scs;
|
|
|
|
|
ssb_cfg.pattern = srsran::srsran_band_helper().get_ssb_pattern(band, phy.cfg.ssb.scs);
|
|
|
|
|
ssb_cfg.duplex_mode = srsran::srsran_band_helper().get_duplex_mode(band);
|
|
|
|
|
ssb_cfg.periodicity_ms = phy->cfg.ssb.periodicity_ms;
|
|
|
|
|
ssb_cfg.periodicity_ms = phy.cfg.ssb.periodicity_ms;
|
|
|
|
|
|
|
|
|
|
if (srsran_ssb_set_cfg(&ssb, &ssb_cfg) < SRSRAN_SUCCESS) {
|
|
|
|
|
logger.error("Error setting SSB configuration");
|
|
|
|
@ -119,7 +119,7 @@ void cc_worker::set_tti(uint32_t tti)
|
|
|
|
|
|
|
|
|
|
cf_t* cc_worker::get_rx_buffer(uint32_t antenna_idx)
|
|
|
|
|
{
|
|
|
|
|
if (antenna_idx >= phy->args.dl.nof_rx_antennas) {
|
|
|
|
|
if (antenna_idx >= phy.args.dl.nof_rx_antennas) {
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -128,7 +128,7 @@ cf_t* cc_worker::get_rx_buffer(uint32_t antenna_idx)
|
|
|
|
|
|
|
|
|
|
cf_t* cc_worker::get_tx_buffer(uint32_t antenna_idx)
|
|
|
|
|
{
|
|
|
|
|
if (antenna_idx >= phy->args.dl.nof_rx_antennas) {
|
|
|
|
|
if (antenna_idx >= phy.args.dl.nof_rx_antennas) {
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -143,7 +143,7 @@ uint32_t cc_worker::get_buffer_len()
|
|
|
|
|
void cc_worker::decode_pdcch_dl()
|
|
|
|
|
{
|
|
|
|
|
std::array<srsran_dci_dl_nr_t, SRSRAN_SEARCH_SPACE_MAX_NOF_CANDIDATES_NR> dci_rx = {};
|
|
|
|
|
srsue::mac_interface_phy_nr::sched_rnti_t rnti = phy->stack->get_dl_sched_rnti_nr(dl_slot_cfg.idx);
|
|
|
|
|
srsue::mac_interface_phy_nr::sched_rnti_t rnti = phy.stack->get_dl_sched_rnti_nr(dl_slot_cfg.idx);
|
|
|
|
|
|
|
|
|
|
// Skip search if no valid RNTI is given
|
|
|
|
|
if (rnti.id == SRSRAN_INVALID_RNTI) {
|
|
|
|
@ -168,7 +168,7 @@ void cc_worker::decode_pdcch_dl()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Enqueue UL grants
|
|
|
|
|
phy->set_dl_pending_grant(dl_slot_cfg, dci_rx[i]);
|
|
|
|
|
phy.set_dl_pending_grant(dl_slot_cfg, dci_rx[i]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (logger.debug.enabled()) {
|
|
|
|
@ -194,7 +194,7 @@ void cc_worker::decode_pdcch_dl()
|
|
|
|
|
void cc_worker::decode_pdcch_ul()
|
|
|
|
|
{
|
|
|
|
|
std::array<srsran_dci_ul_nr_t, SRSRAN_SEARCH_SPACE_MAX_NOF_CANDIDATES_NR> dci_rx = {};
|
|
|
|
|
srsue::mac_interface_phy_nr::sched_rnti_t rnti = phy->stack->get_ul_sched_rnti_nr(ul_slot_cfg.idx);
|
|
|
|
|
srsue::mac_interface_phy_nr::sched_rnti_t rnti = phy.stack->get_ul_sched_rnti_nr(ul_slot_cfg.idx);
|
|
|
|
|
|
|
|
|
|
// Skip search if no valid RNTI is given
|
|
|
|
|
if (rnti.id == SRSRAN_INVALID_RNTI) {
|
|
|
|
@ -219,7 +219,7 @@ void cc_worker::decode_pdcch_ul()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Enqueue UL grants
|
|
|
|
|
phy->set_ul_pending_grant(dl_slot_cfg.idx, dci_rx[i]);
|
|
|
|
|
phy.set_ul_pending_grant(dl_slot_cfg.idx, dci_rx[i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -229,7 +229,7 @@ bool cc_worker::decode_pdsch_dl()
|
|
|
|
|
uint32_t pid = 0;
|
|
|
|
|
srsran_sch_cfg_nr_t pdsch_cfg = {};
|
|
|
|
|
srsran_pdsch_ack_resource_nr_t ack_resource = {};
|
|
|
|
|
if (not phy->get_dl_pending_grant(dl_slot_cfg.idx, pdsch_cfg, ack_resource, pid)) {
|
|
|
|
|
if (not phy.get_dl_pending_grant(dl_slot_cfg.idx, pdsch_cfg, ack_resource, pid)) {
|
|
|
|
|
// Early return if no grant was available
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
@ -242,13 +242,13 @@ bool cc_worker::decode_pdsch_dl()
|
|
|
|
|
mac_dl_grant.ndi = pdsch_cfg.grant.tb[0].ndi;
|
|
|
|
|
mac_dl_grant.tbs = pdsch_cfg.grant.tb[0].tbs / 8;
|
|
|
|
|
mac_dl_grant.tti = dl_slot_cfg.idx;
|
|
|
|
|
phy->stack->new_grant_dl(0, mac_dl_grant, &dl_action);
|
|
|
|
|
phy.stack->new_grant_dl(0, mac_dl_grant, &dl_action);
|
|
|
|
|
|
|
|
|
|
// Abort if MAC says it doesn't need the TB
|
|
|
|
|
if (not dl_action.tb.enabled) {
|
|
|
|
|
// Force positive ACK
|
|
|
|
|
if (pdsch_cfg.grant.rnti_type == srsran_rnti_type_c) {
|
|
|
|
|
phy->set_pending_ack(dl_slot_cfg.idx, ack_resource, true);
|
|
|
|
|
phy.set_pending_ack(dl_slot_cfg.idx, ack_resource, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
logger.info("Decoding not required. Skipping PDSCH. ack_tti_tx=%d", TTI_ADD(dl_slot_cfg.idx, ack_resource.k1));
|
|
|
|
@ -302,17 +302,17 @@ bool cc_worker::decode_pdsch_dl()
|
|
|
|
|
|
|
|
|
|
// Enqueue PDSCH ACK information only if the RNTI is type C
|
|
|
|
|
if (pdsch_cfg.grant.rnti_type == srsran_rnti_type_c) {
|
|
|
|
|
phy->set_pending_ack(dl_slot_cfg.idx, ack_resource, pdsch_res.tb[0].crc);
|
|
|
|
|
phy.set_pending_ack(dl_slot_cfg.idx, ack_resource, pdsch_res.tb[0].crc);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Notify MAC about PDSCH decoding result
|
|
|
|
|
mac_interface_phy_nr::tb_action_dl_result_t mac_dl_result = {};
|
|
|
|
|
mac_dl_result.ack = pdsch_res.tb[0].crc;
|
|
|
|
|
mac_dl_result.payload = mac_dl_result.ack ? std::move(data) : nullptr; // only pass data when successful
|
|
|
|
|
phy->stack->tb_decoded(cc_idx, mac_dl_grant, std::move(mac_dl_result));
|
|
|
|
|
phy.stack->tb_decoded(cc_idx, mac_dl_grant, std::move(mac_dl_result));
|
|
|
|
|
|
|
|
|
|
if (pdsch_cfg.grant.rnti_type == srsran_rnti_type_ra) {
|
|
|
|
|
phy->rar_grant_tti = dl_slot_cfg.idx;
|
|
|
|
|
phy.rar_grant_tti = dl_slot_cfg.idx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pdsch_res.tb[0].crc) {
|
|
|
|
@ -321,7 +321,7 @@ bool cc_worker::decode_pdsch_dl()
|
|
|
|
|
dl_m.mcs = pdsch_cfg.grant.tb[0].mcs;
|
|
|
|
|
dl_m.fec_iters = pdsch_res.tb[0].avg_iter;
|
|
|
|
|
dl_m.evm = pdsch_res.evm[0];
|
|
|
|
|
phy->set_dl_metrics(dl_m);
|
|
|
|
|
phy.set_dl_metrics(dl_m);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
@ -334,7 +334,7 @@ bool cc_worker::measure_csi()
|
|
|
|
|
srsran_csi_trs_measurements_t meas = {};
|
|
|
|
|
|
|
|
|
|
// Iterate all possible candidates
|
|
|
|
|
const std::array<bool, SRSRAN_SSB_NOF_CANDIDATES> position_in_burst = phy->cfg.ssb.position_in_burst;
|
|
|
|
|
const std::array<bool, SRSRAN_SSB_NOF_CANDIDATES> position_in_burst = phy.cfg.ssb.position_in_burst;
|
|
|
|
|
for (uint32_t ssb_idx = 0; ssb_idx < SRSRAN_SSB_NOF_CANDIDATES; ssb_idx++) {
|
|
|
|
|
// Skip SSB candidate if not enabled
|
|
|
|
|
if (not position_in_burst[ssb_idx]) {
|
|
|
|
@ -342,7 +342,7 @@ bool cc_worker::measure_csi()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Measure SSB candidate
|
|
|
|
|
if (srsran_ssb_csi_measure(&ssb, phy->cfg.carrier.pci, ssb_idx, rx_buffer[0], &meas) < SRSRAN_SUCCESS) {
|
|
|
|
|
if (srsran_ssb_csi_measure(&ssb, phy.cfg.carrier.pci, ssb_idx, rx_buffer[0], &meas) < SRSRAN_SUCCESS) {
|
|
|
|
|
logger.error("Error measuring SSB");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
@ -360,13 +360,13 @@ bool cc_worker::measure_csi()
|
|
|
|
|
ch_metrics.rsrq = 0.0f; // Not supported
|
|
|
|
|
ch_metrics.rssi = 0.0f; // Not supported
|
|
|
|
|
ch_metrics.sync_err =
|
|
|
|
|
meas.delay_us / (float)(ue_dl.fft->fft_plan.size * SRSRAN_SUBC_SPACING_NR(phy->cfg.carrier.scs));
|
|
|
|
|
phy->set_channel_metrics(ch_metrics);
|
|
|
|
|
meas.delay_us / (float)(ue_dl.fft->fft_plan.size * SRSRAN_SUBC_SPACING_NR(phy.cfg.carrier.scs));
|
|
|
|
|
phy.set_channel_metrics(ch_metrics);
|
|
|
|
|
|
|
|
|
|
// Compute synch metrics and report it to the PHY state
|
|
|
|
|
sync_metrics_t sync_metrics = {};
|
|
|
|
|
sync_metrics.cfo = meas.cfo_hz;
|
|
|
|
|
phy->set_sync_metrics(sync_metrics);
|
|
|
|
|
phy.set_sync_metrics(sync_metrics);
|
|
|
|
|
|
|
|
|
|
// Report SSB candidate channel measurement to the PHY state
|
|
|
|
|
// ...
|
|
|
|
@ -376,7 +376,7 @@ bool cc_worker::measure_csi()
|
|
|
|
|
// Iterate all NZP-CSI-RS marked as TRS and perform channel measurements
|
|
|
|
|
for (uint32_t resource_set_id = 0; resource_set_id < SRSRAN_PHCH_CFG_MAX_NOF_CSI_RS_SETS; resource_set_id++) {
|
|
|
|
|
// Select NZP-CSI-RS set
|
|
|
|
|
const srsran_csi_rs_nzp_set_t& nzp_set = phy->cfg.pdsch.nzp_csi_rs_sets[resource_set_id];
|
|
|
|
|
const srsran_csi_rs_nzp_set_t& nzp_set = phy.cfg.pdsch.nzp_csi_rs_sets[resource_set_id];
|
|
|
|
|
|
|
|
|
|
// Skip set if not set as TRS (it will be processed later)
|
|
|
|
|
if (not nzp_set.trs_info) {
|
|
|
|
@ -409,13 +409,13 @@ bool cc_worker::measure_csi()
|
|
|
|
|
ch_metrics.rsrq = 0.0f; // Not supported
|
|
|
|
|
ch_metrics.rssi = 0.0f; // Not supported
|
|
|
|
|
ch_metrics.sync_err =
|
|
|
|
|
trs_measurements.delay_us / (float)(ue_dl.fft->fft_plan.size * SRSRAN_SUBC_SPACING_NR(phy->cfg.carrier.scs));
|
|
|
|
|
phy->set_channel_metrics(ch_metrics);
|
|
|
|
|
trs_measurements.delay_us / (float)(ue_dl.fft->fft_plan.size * SRSRAN_SUBC_SPACING_NR(phy.cfg.carrier.scs));
|
|
|
|
|
phy.set_channel_metrics(ch_metrics);
|
|
|
|
|
|
|
|
|
|
// Compute synch metrics and report it to the PHY state
|
|
|
|
|
sync_metrics_t sync_metrics = {};
|
|
|
|
|
sync_metrics.cfo = trs_measurements.cfo_hz;
|
|
|
|
|
phy->set_sync_metrics(sync_metrics);
|
|
|
|
|
phy.set_sync_metrics(sync_metrics);
|
|
|
|
|
|
|
|
|
|
// Convert to CSI channel measurement and report new NZP-CSI-RS measurement to the PHY state
|
|
|
|
|
srsran_csi_channel_measurements_t measurements = {};
|
|
|
|
@ -425,13 +425,13 @@ bool cc_worker::measure_csi()
|
|
|
|
|
measurements.wideband_snr_db = trs_measurements.snr_dB;
|
|
|
|
|
measurements.nof_ports = 1; // Other values are not supported
|
|
|
|
|
measurements.K_csi_rs = (uint32_t)n;
|
|
|
|
|
phy->new_nzp_csi_rs_channel_measurement(measurements, resource_set_id);
|
|
|
|
|
phy.new_nzp_csi_rs_channel_measurement(measurements, resource_set_id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Iterate all NZP-CSI-RS not marked as TRS and perform channel measurements
|
|
|
|
|
for (uint32_t resource_set_id = 0; resource_set_id < SRSRAN_PHCH_CFG_MAX_NOF_CSI_RS_SETS; resource_set_id++) {
|
|
|
|
|
// Select NZP-CSI-RS set
|
|
|
|
|
const srsran_csi_rs_nzp_set_t& nzp_set = phy->cfg.pdsch.nzp_csi_rs_sets[resource_set_id];
|
|
|
|
|
const srsran_csi_rs_nzp_set_t& nzp_set = phy.cfg.pdsch.nzp_csi_rs_sets[resource_set_id];
|
|
|
|
|
|
|
|
|
|
// Skip set if set as TRS (it was processed previously)
|
|
|
|
|
if (nzp_set.trs_info) {
|
|
|
|
@ -458,7 +458,7 @@ bool cc_worker::measure_csi()
|
|
|
|
|
measurements.wideband_snr_db);
|
|
|
|
|
|
|
|
|
|
// Report new measurement to the PHY state
|
|
|
|
|
phy->new_nzp_csi_rs_channel_measurement(measurements, resource_set_id);
|
|
|
|
|
phy.new_nzp_csi_rs_channel_measurement(measurements, resource_set_id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
@ -472,7 +472,7 @@ bool cc_worker::work_dl()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check if it is a DL slot, if not skip
|
|
|
|
|
if (!srsran_tdd_nr_is_dl(&phy->cfg.tdd, 0, dl_slot_cfg.idx)) {
|
|
|
|
|
if (!srsran_tdd_nr_is_dl(&phy.cfg.tdd, 0, dl_slot_cfg.idx)) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -503,7 +503,7 @@ bool cc_worker::work_dl()
|
|
|
|
|
bool cc_worker::work_ul()
|
|
|
|
|
{
|
|
|
|
|
// Check if it is a UL slot, if not skip
|
|
|
|
|
if (!srsran_tdd_nr_is_ul(&phy->cfg.tdd, 0, ul_slot_cfg.idx)) {
|
|
|
|
|
if (!srsran_tdd_nr_is_ul(&phy.cfg.tdd, 0, ul_slot_cfg.idx)) {
|
|
|
|
|
// No NR signal shall be transmitted
|
|
|
|
|
srsran_vec_cf_zero(tx_buffer[0], ue_ul.ifft.sf_sz);
|
|
|
|
|
return true;
|
|
|
|
@ -514,11 +514,11 @@ bool cc_worker::work_ul()
|
|
|
|
|
|
|
|
|
|
// Gather PDSCH ACK information
|
|
|
|
|
srsran_pdsch_ack_nr_t pdsch_ack = {};
|
|
|
|
|
bool has_ul_ack = phy->get_pending_ack(ul_slot_cfg.idx, pdsch_ack);
|
|
|
|
|
bool has_ul_ack = phy.get_pending_ack(ul_slot_cfg.idx, pdsch_ack);
|
|
|
|
|
|
|
|
|
|
// Request grant to PHY state for this transmit TTI
|
|
|
|
|
srsran_sch_cfg_nr_t pusch_cfg = {};
|
|
|
|
|
bool has_pusch_grant = phy->get_ul_pending_grant(ul_slot_cfg.idx, pusch_cfg, pid);
|
|
|
|
|
bool has_pusch_grant = phy.get_ul_pending_grant(ul_slot_cfg.idx, pusch_cfg, pid);
|
|
|
|
|
|
|
|
|
|
// If PDSCH UL ACK is available, load into UCI
|
|
|
|
|
if (has_ul_ack) {
|
|
|
|
@ -531,7 +531,7 @@ bool cc_worker::work_ul()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (srsran_ue_dl_nr_gen_ack(&phy->cfg.harq_ack, &pdsch_ack, &uci_data) < SRSRAN_SUCCESS) {
|
|
|
|
|
if (srsran_ue_dl_nr_gen_ack(&phy.cfg.harq_ack, &pdsch_ack, &uci_data) < SRSRAN_SUCCESS) {
|
|
|
|
|
ERROR("Filling UCI ACK bits");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
@ -539,11 +539,11 @@ bool cc_worker::work_ul()
|
|
|
|
|
|
|
|
|
|
// Add SR to UCI data only if there is no UL grant!
|
|
|
|
|
if (!has_ul_ack) {
|
|
|
|
|
phy->get_pending_sr(ul_slot_cfg.idx, uci_data);
|
|
|
|
|
phy.get_pending_sr(ul_slot_cfg.idx, uci_data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Add CSI reports to UCI data if available
|
|
|
|
|
phy->get_periodic_csi(ul_slot_cfg.idx, uci_data);
|
|
|
|
|
phy.get_periodic_csi(ul_slot_cfg.idx, uci_data);
|
|
|
|
|
|
|
|
|
|
if (has_pusch_grant) {
|
|
|
|
|
// Notify MAC about PUSCH found grant
|
|
|
|
@ -556,7 +556,7 @@ bool cc_worker::work_ul()
|
|
|
|
|
mac_ul_grant.ndi = pusch_cfg.grant.tb[0].ndi;
|
|
|
|
|
mac_ul_grant.rv = pusch_cfg.grant.tb[0].rv;
|
|
|
|
|
mac_ul_grant.is_rar_grant = (pusch_cfg.grant.rnti_type == srsran_rnti_type_ra);
|
|
|
|
|
phy->stack->new_grant_ul(0, mac_ul_grant, &ul_action);
|
|
|
|
|
phy.stack->new_grant_ul(0, mac_ul_grant, &ul_action);
|
|
|
|
|
|
|
|
|
|
// Don't process further if MAC can't provide PDU
|
|
|
|
|
if (not ul_action.tb.enabled) {
|
|
|
|
@ -565,7 +565,7 @@ bool cc_worker::work_ul()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Set UCI configuration following procedures
|
|
|
|
|
srsran_ra_ul_set_grant_uci_nr(&phy->cfg.carrier, &phy->cfg.pusch, &uci_data.cfg, &pusch_cfg);
|
|
|
|
|
srsran_ra_ul_set_grant_uci_nr(&phy.cfg.carrier, &phy.cfg.pusch, &uci_data.cfg, &pusch_cfg);
|
|
|
|
|
|
|
|
|
|
// Assigning MAC provided values to PUSCH config structs
|
|
|
|
|
pusch_cfg.grant.tb[0].softbuffer.tx = ul_action.tb.softbuffer;
|
|
|
|
@ -612,18 +612,18 @@ bool cc_worker::work_ul()
|
|
|
|
|
ul_metrics_t ul_m = {};
|
|
|
|
|
ul_m.mcs = pusch_cfg.grant.tb[0].mcs;
|
|
|
|
|
ul_m.power = srsran_convert_power_to_dB(srsran_vec_avg_power_cf(tx_buffer[0], ue_ul.ifft.sf_sz));
|
|
|
|
|
phy->set_ul_metrics(ul_m);
|
|
|
|
|
phy.set_ul_metrics(ul_m);
|
|
|
|
|
|
|
|
|
|
} else if (srsran_uci_nr_total_bits(&uci_data.cfg) > 0) {
|
|
|
|
|
// Get PUCCH resource
|
|
|
|
|
srsran_pucch_nr_resource_t resource = {};
|
|
|
|
|
if (srsran_ra_ul_nr_pucch_resource(&phy->cfg.pucch, &uci_data.cfg, &resource) < SRSRAN_SUCCESS) {
|
|
|
|
|
if (srsran_ra_ul_nr_pucch_resource(&phy.cfg.pucch, &uci_data.cfg, &resource) < SRSRAN_SUCCESS) {
|
|
|
|
|
ERROR("Selecting PUCCH resource");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Encode PUCCH message
|
|
|
|
|
if (srsran_ue_ul_nr_encode_pucch(&ue_ul, &ul_slot_cfg, &phy->cfg.pucch.common, &resource, &uci_data) <
|
|
|
|
|
if (srsran_ue_ul_nr_encode_pucch(&ue_ul, &ul_slot_cfg, &phy.cfg.pucch.common, &resource, &uci_data) <
|
|
|
|
|
SRSRAN_SUCCESS) {
|
|
|
|
|
ERROR("Encoding PUCCH");
|
|
|
|
|
return false;
|
|
|
|
|