diff --git a/lib/examples/pssch_ue.c b/lib/examples/pssch_ue.c index e832fae8f..cb9b28c68 100644 --- a/lib/examples/pssch_ue.c +++ b/lib/examples/pssch_ue.c @@ -323,7 +323,7 @@ int main(int argc, char** argv) // SCI srsran_sci_t sci; - srsran_sci_init(&sci, cell_sl, sl_comm_resource_pool); + srsran_sci_init(&sci, &cell_sl, &sl_comm_resource_pool); uint8_t sci_rx[SRSRAN_SCI_MAX_LEN] = {}; char sci_msg[SRSRAN_SCI_MSG_MAX_LEN] = {}; @@ -346,7 +346,7 @@ int main(int argc, char** argv) return SRSRAN_ERROR; } - if (srsran_pssch_init(&pssch, cell_sl, sl_comm_resource_pool) != SRSRAN_SUCCESS) { + if (srsran_pssch_init(&pssch, &cell_sl, &sl_comm_resource_pool) != SRSRAN_SUCCESS) { ERROR("Error initializing PSSCH"); return SRSRAN_ERROR; } diff --git a/lib/include/srsran/asn1/asn1_utils.h b/lib/include/srsran/asn1/asn1_utils.h index deb8914c1..d74108149 100644 --- a/lib/include/srsran/asn1/asn1_utils.h +++ b/lib/include/srsran/asn1/asn1_utils.h @@ -1317,7 +1317,7 @@ private: bit_ref brefstart; // bit_ref bref0; bit_ref* bref_tracker; - uint8_t buffer[1024]; + uint8_t buffer[2048]; bool align; }; diff --git a/lib/include/srsran/asn1/rrc_nr_utils.h b/lib/include/srsran/asn1/rrc_nr_utils.h index 58436343e..7d19d31e4 100644 --- a/lib/include/srsran/asn1/rrc_nr_utils.h +++ b/lib/include/srsran/asn1/rrc_nr_utils.h @@ -54,6 +54,9 @@ struct pusch_time_domain_res_alloc_s; struct pucch_format_cfg_s; struct pucch_res_s; struct sched_request_res_cfg_s; +struct pusch_cfg_s; +struct pdsch_cfg_s; +struct dmrs_dl_cfg_s; struct dmrs_ul_cfg_s; struct beta_offsets_s; struct uci_on_pusch_s; @@ -96,14 +99,22 @@ bool make_phy_res_config(const asn1::rrc_nr::pucch_res_s& pucch_res, srsran_pucch_nr_resource_t* srsran_pucch_nr_resource); bool make_phy_sr_resource(const asn1::rrc_nr::sched_request_res_cfg_s& sched_request_res_cfg, srsran_pucch_nr_sr_resource_t* srsran_pucch_nr_sr_resource); -bool make_phy_dmrs_additional_pos(const asn1::rrc_nr::dmrs_ul_cfg_s& dmrs_ul_cfg, - srsran_dmrs_sch_add_pos_t* srsran_dmrs_sch_add_pos); +bool make_phy_pusch_alloc_type(const asn1::rrc_nr::pusch_cfg_s& pusch_cfg, + srsran_resource_alloc_t* in_srsran_resource_alloc); +bool make_phy_pdsch_alloc_type(const asn1::rrc_nr::pdsch_cfg_s& pdsch_cfg, + srsran_resource_alloc_t* in_srsran_resource_alloc); +bool make_phy_dmrs_dl_additional_pos(const asn1::rrc_nr::dmrs_dl_cfg_s& dmrs_dl_cfg, + srsran_dmrs_sch_add_pos_t* in_srsran_dmrs_sch_add_pos); +bool make_phy_dmrs_ul_additional_pos(const asn1::rrc_nr::dmrs_ul_cfg_s& dmrs_ul_cfg, + srsran_dmrs_sch_add_pos_t* srsran_dmrs_sch_add_pos); bool make_phy_beta_offsets(const asn1::rrc_nr::beta_offsets_s& beta_offsets, srsran_beta_offsets_t* srsran_beta_offsets); bool make_phy_pusch_scaling(const asn1::rrc_nr::uci_on_pusch_s& uci_on_pusch, float* scaling); -bool make_phy_zp_csi_rs_resource(const asn1::rrc_nr::zp_csi_rs_res_s & zp_csi_rs_res, srsran_csi_rs_zp_resource_t* zp_csi_rs_resource); -bool make_phy_nzp_csi_rs_resource(const asn1::rrc_nr::nzp_csi_rs_res_s & nzp_csi_rs_res, srsran_csi_rs_nzp_resource_t* csi_rs_nzp_resource); -bool make_phy_carrier_cfg(const asn1::rrc_nr::freq_info_dl_s &freq_info_dl, srsran_carrier_nr_t* carrier_nr); +bool make_phy_zp_csi_rs_resource(const asn1::rrc_nr::zp_csi_rs_res_s& zp_csi_rs_res, + srsran_csi_rs_zp_resource_t* zp_csi_rs_resource); +bool make_phy_nzp_csi_rs_resource(const asn1::rrc_nr::nzp_csi_rs_res_s& nzp_csi_rs_res, + srsran_csi_rs_nzp_resource_t* csi_rs_nzp_resource); +bool make_phy_carrier_cfg(const asn1::rrc_nr::freq_info_dl_s& freq_info_dl, srsran_carrier_nr_t* carrier_nr); /*************************** * MAC Config **************************/ diff --git a/lib/include/srsran/interfaces/rrc_nr_interface_types.h b/lib/include/srsran/interfaces/rrc_nr_interface_types.h index bb402aee4..dafe4debf 100644 --- a/lib/include/srsran/interfaces/rrc_nr_interface_types.h +++ b/lib/include/srsran/interfaces/rrc_nr_interface_types.h @@ -52,7 +52,7 @@ struct phy_cfg_nr_t { { srsran_dci_cfg_nr_t dci_cfg = {}; - // Set bandwidths + // Assume BWP bandwidth equals full channel bandwidth dci_cfg.coreset0_bw = pdcch.coreset_present[0] ? srsran_coreset_get_bw(&pdcch.coreset[0]) : 0; dci_cfg.bwp_dl_initial_bw = carrier.nof_prb; dci_cfg.bwp_dl_active_bw = carrier.nof_prb; @@ -88,24 +88,45 @@ struct phy_cfg_nr_t { // Set Format 0_1 and 1_1 parameters dci_cfg.carrier_indicator_size = 0; dci_cfg.harq_ack_codebok = harq_ack.harq_ack_codebook; + dci_cfg.nof_rb_groups = 0; // Format 0_1 specific configuration (for PUSCH only) - dci_cfg.nof_ul_bwp = 1; + dci_cfg.nof_ul_bwp = 0; dci_cfg.nof_ul_time_res = (pusch.nof_dedicated_time_ra > 0) ? pusch.nof_dedicated_time_ra : (pusch.nof_common_time_ra > 0) ? pusch.nof_common_time_ra : SRSRAN_MAX_NOF_TIME_RA; - dci_cfg.nof_srs = 1; - dci_cfg.nof_ul_layers = 1; - dci_cfg.nof_rb_groups = 1; - dci_cfg.pusch_alloc_type = pusch.alloc; + dci_cfg.nof_srs = 1; + dci_cfg.nof_ul_layers = 1; + dci_cfg.pusch_nof_cbg = 0; + dci_cfg.report_trigger_size = 0; + dci_cfg.enable_transform_precoding = false; + dci_cfg.dynamic_dual_harq_ack_codebook = false; + dci_cfg.pusch_tx_config_non_codebook = false; + dci_cfg.pusch_dmrs_type2 = false; + dci_cfg.pusch_dmrs_double = false; + dci_cfg.pusch_ptrs = false; + dci_cfg.pusch_dynamic_betas = false; + dci_cfg.pusch_alloc_type = pusch.alloc; // Format 1_1 specific configuration (for PDSCH only) - dci_cfg.nof_dl_bwp = 1; - dci_cfg.pdsch_alloc_type = pdsch.alloc; - dci_cfg.nof_dl_time_res = (pdsch.nof_dedicated_time_ra > 0) + dci_cfg.nof_dl_bwp = 0; + dci_cfg.nof_dl_time_res = (pdsch.nof_dedicated_time_ra > 0) ? pdsch.nof_dedicated_time_ra : (pdsch.nof_common_time_ra > 0) ? pdsch.nof_common_time_ra : SRSRAN_MAX_NOF_TIME_RA; - dci_cfg.nof_aperiodic_zp = 0; + dci_cfg.nof_aperiodic_zp = 0; + dci_cfg.pdsch_nof_cbg = 0; + dci_cfg.nof_dl_to_ul_ack = harq_ack.nof_dl_data_to_ul_ack; + dci_cfg.pdsch_inter_prb_to_prb = false; + dci_cfg.pdsch_rm_pattern1 = false; + dci_cfg.pdsch_rm_pattern2 = false; + dci_cfg.pdsch_2cw = false; + dci_cfg.multiple_scell = false; + dci_cfg.pdsch_dmrs_type2 = false; + dci_cfg.pdsch_dmrs_double = false; + dci_cfg.pdsch_tci = false; + dci_cfg.pdsch_cbg_flush = false; + dci_cfg.pdsch_dynamic_bundling = false; + dci_cfg.pdsch_alloc_type = pdsch.alloc; return dci_cfg; }; diff --git a/lib/include/srsran/phy/common/phy_common_nr.h b/lib/include/srsran/phy/common/phy_common_nr.h index 3989f52c1..b8ad1406a 100644 --- a/lib/include/srsran/phy/common/phy_common_nr.h +++ b/lib/include/srsran/phy/common/phy_common_nr.h @@ -39,6 +39,11 @@ extern "C" { */ #define SRSRAN_SLOT_LEN_RE_NR(nof_prb) (nof_prb * SRSRAN_NRE * SRSRAN_NSYMB_PER_SLOT_NR) +/** + * @brief Minimum subframe length in samples for a given number of PRB + */ +#define SRSRAN_SF_LEN_PRB_NR(nof_prb) (srsran_min_symbol_sz_rb(nof_prb) * 15) + #define SRSRAN_SLOT_MAX_LEN_RE_NR (SRSRAN_SLOT_LEN_RE_NR(SRSRAN_MAX_PRB_NR)) #define SRSRAN_SLOT_MAX_NOF_BITS_NR (SRSRAN_SLOT_MAX_LEN_RE_NR * SRSRAN_MAX_QM) #define SRSRAN_MAX_LAYERS_NR 8 diff --git a/lib/include/srsran/phy/phch/csi.h b/lib/include/srsran/phy/phch/csi.h index 5a0944335..342c45cc5 100644 --- a/lib/include/srsran/phy/phch/csi.h +++ b/lib/include/srsran/phy/phch/csi.h @@ -46,6 +46,14 @@ SRSRAN_API int srsran_csi_generate_reports(const srsran_csi_hl_cfg_t* cfg, */ SRSRAN_API int srsran_csi_part1_nof_bits(const srsran_csi_report_cfg_t* report_list, uint32_t nof_reports); +/** + * @brief Compute number of CSI bits necessary to transmit all the CSI part 2 reports for a PUCCH transmission + * @param report_list Provides the CSI report list + * @param nof_reports Number of CSI reports in the list + * @return The number of bits if the provided list is valid, SRSRAN_ERROR code otherwise + */ +SRSRAN_API int srsran_csi_part2_nof_bits(const srsran_csi_report_cfg_t* report_list, uint32_t nof_reports); + /** * @brief Checks if the report list contains part 2 CSI report * @param report_list Report list diff --git a/lib/include/srsran/phy/phch/pssch.h b/lib/include/srsran/phy/phch/pssch.h index 5e31179ca..2683c7cd4 100644 --- a/lib/include/srsran/phy/phch/pssch.h +++ b/lib/include/srsran/phy/phch/pssch.h @@ -115,8 +115,9 @@ typedef struct SRSRAN_API { } srsran_pssch_t; -SRSRAN_API int - srsran_pssch_init(srsran_pssch_t* q, srsran_cell_sl_t cell, srsran_sl_comm_resource_pool_t sl_comm_resource_pool); +SRSRAN_API int srsran_pssch_init(srsran_pssch_t* q, + const srsran_cell_sl_t* cell, + const srsran_sl_comm_resource_pool_t* sl_comm_resource_pool); SRSRAN_API int srsran_pssch_set_cfg(srsran_pssch_t* q, srsran_pssch_cfg_t pssch_cfg); SRSRAN_API int srsran_pssch_encode(srsran_pssch_t* q, uint8_t* input, uint32_t input_len, cf_t* sf_buffer); SRSRAN_API int srsran_pssch_decode(srsran_pssch_t* q, cf_t* equalized_sf_syms, uint8_t* output, uint32_t output_len); diff --git a/lib/include/srsran/phy/phch/sci.h b/lib/include/srsran/phy/phch/sci.h index 3a9ac2a8e..a08238d53 100644 --- a/lib/include/srsran/phy/phch/sci.h +++ b/lib/include/srsran/phy/phch/sci.h @@ -98,8 +98,9 @@ typedef struct SRSRAN_API { } srsran_sci_t; -SRSRAN_API int - srsran_sci_init(srsran_sci_t* q, srsran_cell_sl_t cell, srsran_sl_comm_resource_pool_t sl_comm_resource_pool); +SRSRAN_API int srsran_sci_init(srsran_sci_t* q, + const srsran_cell_sl_t* cell, + const srsran_sl_comm_resource_pool_t* sl_comm_resource_pool); SRSRAN_API int srsran_sci_format0_pack(srsran_sci_t* q, uint8_t* output); SRSRAN_API int srsran_sci_format1_pack(srsran_sci_t* q, uint8_t* output); SRSRAN_API int srsran_sci_format0_unpack(srsran_sci_t* q, uint8_t* input); diff --git a/lib/src/asn1/rrc_nr_utils.cc b/lib/src/asn1/rrc_nr_utils.cc index 95d553f59..fb302fd63 100644 --- a/lib/src/asn1/rrc_nr_utils.cc +++ b/lib/src/asn1/rrc_nr_utils.cc @@ -792,8 +792,80 @@ bool make_phy_sr_resource(const sched_request_res_cfg_s& sched_request_res_cfg, return true; } -bool make_phy_dmrs_additional_pos(const dmrs_ul_cfg_s& dmrs_ul_cfg, - srsran_dmrs_sch_add_pos_t* in_srsran_dmrs_sch_add_pos) +bool make_phy_pusch_alloc_type(const asn1::rrc_nr::pusch_cfg_s& pusch_cfg, + srsran_resource_alloc_t* in_srsran_resource_alloc) +{ + srsran_resource_alloc_t srsran_resource_alloc = {}; + + switch (pusch_cfg.res_alloc) { + case asn1::rrc_nr::pusch_cfg_s::res_alloc_e_::res_alloc_type0: + srsran_resource_alloc = srsran_resource_alloc_type0; + break; + case asn1::rrc_nr::pusch_cfg_s::res_alloc_e_::res_alloc_type1: + srsran_resource_alloc = srsran_resource_alloc_type1; + break; + case asn1::rrc_nr::pusch_cfg_s::res_alloc_e_::dynamic_switch: + srsran_resource_alloc = srsran_resource_alloc_dynamic; + break; + default: + asn1::log_warning("Invalid option for pusch::resource_alloc %s", pusch_cfg.res_alloc.to_string()); + return false; + } + *in_srsran_resource_alloc = srsran_resource_alloc; + return true; +} + +bool make_phy_pdsch_alloc_type(const asn1::rrc_nr::pdsch_cfg_s& pdsch_cfg, + srsran_resource_alloc_t* in_srsran_resource_alloc) +{ + srsran_resource_alloc_t srsran_resource_alloc = {}; + + switch (pdsch_cfg.res_alloc) { + case asn1::rrc_nr::pdsch_cfg_s::res_alloc_e_::res_alloc_type0: + srsran_resource_alloc = srsran_resource_alloc_type0; + break; + case asn1::rrc_nr::pdsch_cfg_s::res_alloc_e_::res_alloc_type1: + srsran_resource_alloc = srsran_resource_alloc_type1; + break; + case asn1::rrc_nr::pdsch_cfg_s::res_alloc_e_::dynamic_switch: + srsran_resource_alloc = srsran_resource_alloc_dynamic; + break; + default: + asn1::log_warning("Invalid option for pusch::resource_alloc %s", pdsch_cfg.res_alloc.to_string()); + return false; + } + *in_srsran_resource_alloc = srsran_resource_alloc; + return true; +} + +bool make_phy_dmrs_dl_additional_pos(const dmrs_dl_cfg_s& dmrs_dl_cfg, + srsran_dmrs_sch_add_pos_t* in_srsran_dmrs_sch_add_pos) +{ + srsran_dmrs_sch_add_pos_t srsran_dmrs_sch_add_pos = {}; + if (not dmrs_dl_cfg.dmrs_add_position_present) { + asn1::log_warning("dmrs_add_position option not present"); + } + + switch (dmrs_dl_cfg.dmrs_add_position) { + case dmrs_dl_cfg_s::dmrs_add_position_opts::pos0: + srsran_dmrs_sch_add_pos = srsran_dmrs_sch_add_pos_0; + break; + case dmrs_dl_cfg_s::dmrs_add_position_opts::pos1: + srsran_dmrs_sch_add_pos = srsran_dmrs_sch_add_pos_1; + break; + case dmrs_dl_cfg_s::dmrs_add_position_opts::pos3: + srsran_dmrs_sch_add_pos = srsran_dmrs_sch_add_pos_3; + break; + default: + asn1::log_warning("Invalid option for dmrs_add_position %s", dmrs_dl_cfg.dmrs_add_position.to_string()); + return false; + } + *in_srsran_dmrs_sch_add_pos = srsran_dmrs_sch_add_pos; + return true; +} + +bool make_phy_dmrs_ul_additional_pos(const dmrs_ul_cfg_s& dmrs_ul_cfg, + srsran_dmrs_sch_add_pos_t* in_srsran_dmrs_sch_add_pos) { srsran_dmrs_sch_add_pos_t srsran_dmrs_sch_add_pos = {}; if (not dmrs_ul_cfg.dmrs_add_position_present) { diff --git a/lib/src/common/test/band_helper_test.cc b/lib/src/common/test/band_helper_test.cc index f17e8c39f..03439b0bc 100644 --- a/lib/src/common/test/band_helper_test.cc +++ b/lib/src/common/test/band_helper_test.cc @@ -29,6 +29,34 @@ int bands_test_nr() TESTASSERT(bands.nr_arfcn_to_freq(632628) == 3489.42e6); TESTASSERT(bands.nr_arfcn_to_freq(633928) == 3508.92e6); // default refPointA TESTASSERT(bands.nr_arfcn_to_freq(634240) == 3513.6e6); // default ARFCN with freq divisible by 11.52 MHz + // b28 b67 + TESTASSERT(bands.nr_arfcn_to_freq(140600) == 703.0e6); + TESTASSERT(bands.nr_arfcn_to_freq(145800) == 729.0e6); + TESTASSERT(bands.nr_arfcn_to_freq(153600) == 768.0e6); + TESTASSERT(bands.nr_arfcn_to_freq(157600) == 788.0e6); + // b20 + TESTASSERT(bands.nr_arfcn_to_freq(158200) == 791.0e6); + TESTASSERT(bands.nr_arfcn_to_freq(160200) == 801.0e6); + TESTASSERT(bands.nr_arfcn_to_freq(162200) == 811.0e6); + TESTASSERT(bands.nr_arfcn_to_freq(168400) == 842.0e6); + // b32 b75 + TESTASSERT(bands.nr_arfcn_to_freq(290400) == 1452.0e6); + TESTASSERT(bands.nr_arfcn_to_freq(294400) == 1472.0e6); + // b3 + TESTASSERT(bands.nr_arfcn_to_freq(342000) == 1710.0e6); + TESTASSERT(bands.nr_arfcn_to_freq(348000) == 1740.0e6); + TESTASSERT(bands.nr_arfcn_to_freq(361000) == 1805.0e6); + TESTASSERT(bands.nr_arfcn_to_freq(376000) == 1880.0e6); + // b1 + TESTASSERT(bands.nr_arfcn_to_freq(384000) == 1920.0e6); + TESTASSERT(bands.nr_arfcn_to_freq(388030) == 1940.15e6); + TESTASSERT(bands.nr_arfcn_to_freq(391830) == 1959.15e6); + TESTASSERT(bands.nr_arfcn_to_freq(434000) == 2170.0e6); + // b7 b38 + TESTASSERT(bands.nr_arfcn_to_freq(500000) == 2500.0e6); + TESTASSERT(bands.nr_arfcn_to_freq(508000) == 2540.0e6); + TESTASSERT(bands.nr_arfcn_to_freq(522000) == 2610.0e6); + TESTASSERT(bands.nr_arfcn_to_freq(538000) == 2690.0e6); const uint32_t max_valid_nr_arfcn = 3279165; diff --git a/lib/src/phy/fec/ldpc/ldpc_decoder.c b/lib/src/phy/fec/ldpc/ldpc_decoder.c index 0596d76e4..a84c2e4b7 100644 --- a/lib/src/phy/fec/ldpc/ldpc_decoder.c +++ b/lib/src/phy/fec/ldpc/ldpc_decoder.c @@ -146,8 +146,22 @@ } \ \ update_ldpc_soft_bits_##SUFFIX(q->ptr, q->var_indices); \ + \ + if (crc != NULL) { \ + extract_ldpc_message_##SUFFIX(q->ptr, message, q->liftK); \ + \ + if (srsran_crc_match(crc, message, q->liftK - crc->order)) { \ + return i_iteration + 1; \ + } \ + } \ } \ \ + /* If reached here, and CRC is being checked, it has failed */ \ + if (crc != NULL) { \ + return 0; \ + } \ + \ + /* Without CRC, extract message and return the maximum number of iterations */ \ extract_ldpc_message_##SUFFIX(q->ptr, message, q->liftK); \ \ return q->max_nof_iter; \ diff --git a/lib/src/phy/modem/demod_soft.c b/lib/src/phy/modem/demod_soft.c index 0710c6df7..524392ab1 100644 --- a/lib/src/phy/modem/demod_soft.c +++ b/lib/src/phy/modem/demod_soft.c @@ -30,29 +30,6 @@ #ifdef HAVE_NEONv8 #include -inline static uint8x16_t v_load_s8(int i15, - int i14, - int i13, - int i12, - int i11, - int i10, - int i9, - int i8, - int i7, - int i6, - int i5, - int i4, - int i3, - int i2, - int i1, - int i0) -{ - uint8_t __attribute__((aligned(16))) - data[16] = {i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15}; - return vld1q_u8(data); -} - -#define int8x16_to_8x8x2(v) ((int8x8x2_t){{vget_low_s8(v), vget_high_s8(v)}}) #define vshuff_s32_even(a, imm, res) \ do { \ diff --git a/lib/src/phy/modem/test/modem_test.c b/lib/src/phy/modem/test/modem_test.c index 253bcf864..62d05e814 100644 --- a/lib/src/phy/modem/test/modem_test.c +++ b/lib/src/phy/modem/test/modem_test.c @@ -90,6 +90,7 @@ int main(int argc, char** argv) uint8_t * input, *input_bytes, *output; cf_t * symbols, *symbols_bytes; float* llr; + srsran_random_t random_gen = srsran_random_init(0x1234); parse_args(argc, argv); @@ -142,14 +143,14 @@ int main(int argc, char** argv) /* generate random data */ for (i = 0; i < num_bits; i++) { - input[i] = rand() % 2; + input[i] = (uint8_t)srsran_random_uniform_int_dist(random_gen, 0, 1); } /* modulate */ struct timeval t[3]; gettimeofday(&t[1], NULL); int ntrials = 100; - for (int i = 0; i < ntrials; i++) { + for (int j = 0; j < ntrials; j++) { srsran_mod_modulate(&mod, input, symbols, num_bits); } gettimeofday(&t[2], NULL); @@ -160,16 +161,16 @@ int main(int argc, char** argv) /* Test packed implementation */ srsran_bit_pack_vector(input, input_bytes, num_bits); gettimeofday(&t[1], NULL); - for (int i = 0; i < ntrials; i++) { + for (int j = 0; j < ntrials; j++) { srsran_mod_modulate_bytes(&mod, input_bytes, symbols_bytes, num_bits); } gettimeofday(&t[2], NULL); get_time_interval(t); printf("Byte: %ld us\n", t[0].tv_usec); - for (int i = 0; i < num_bits / mod.nbits_x_symbol; i++) { - if (symbols[i] != symbols_bytes[i]) { - printf("error in symbol %d\n", i); + for (int j = 0; i < num_bits / mod.nbits_x_symbol; j++) { + if (symbols[j] != symbols_bytes[j]) { + printf("error in symbol %d\n", j); exit(-1); } } @@ -200,7 +201,7 @@ int main(int argc, char** argv) free(output); free(input); free(input_bytes); - + srsran_random_free(random_gen); srsran_modem_table_free(&mod); exit(ret); diff --git a/lib/src/phy/phch/csi.c b/lib/src/phy/phch/csi.c index 6812f94ce..75a1787ca 100644 --- a/lib/src/phy/phch/csi.c +++ b/lib/src/phy/phch/csi.c @@ -224,6 +224,18 @@ int srsran_csi_part1_nof_bits(const srsran_csi_report_cfg_t* report_list, uint32 return (int)count; } +int srsran_csi_part2_nof_bits(const srsran_csi_report_cfg_t* report_list, uint32_t nof_reports) +{ + uint32_t count = 0; + + // Check input pointer + if (report_list == NULL) { + return SRSRAN_ERROR_INVALID_INPUTS; + } + + return (int)count; +} + bool srsran_csi_has_part2(const srsran_csi_report_cfg_t* report_list, uint32_t nof_reports) { if (report_list == NULL || nof_reports == 0) { diff --git a/lib/src/phy/phch/dci.c b/lib/src/phy/phch/dci.c index 77d72651b..caa5a9b78 100644 --- a/lib/src/phy/phch/dci.c +++ b/lib/src/phy/phch/dci.c @@ -1645,12 +1645,12 @@ uint32_t srsran_dci_dl_info(const srsran_dci_dl_t* dci_dl, char* info_str, uint3 n = srsran_print_check(info_str, len, n, ", pid=%d", dci_dl->pid); - n = srsran_print_check(info_str, len, n, ", mcs={", 0); + n = srsran_print_check(info_str, len, n, ", mcs={"); n = print_multi(info_str, n, len, dci_dl, 0); - n = srsran_print_check(info_str, len, n, "}", 0); - n = srsran_print_check(info_str, len, n, ", ndi={", 0); + n = srsran_print_check(info_str, len, n, "}"); + n = srsran_print_check(info_str, len, n, ", ndi={"); n = print_multi(info_str, n, len, dci_dl, 2); - n = srsran_print_check(info_str, len, n, "}", 0); + n = srsran_print_check(info_str, len, n, "}"); if (dci_dl->format == SRSRAN_DCI_FORMAT1 || dci_dl->format == SRSRAN_DCI_FORMAT1A || dci_dl->format == SRSRAN_DCI_FORMAT1B || dci_dl->format == SRSRAN_DCI_FORMAT2 || diff --git a/lib/src/phy/phch/dci_nr.c b/lib/src/phy/phch/dci_nr.c index 96c2cae44..97db2150e 100644 --- a/lib/src/phy/phch/dci_nr.c +++ b/lib/src/phy/phch/dci_nr.c @@ -674,16 +674,6 @@ dci_nr_format_0_1_to_str(const srsran_dci_nr_t* q, const srsran_dci_ul_nr_t* dci uint32_t len = 0; const srsran_dci_cfg_nr_t* cfg = &q->cfg; - // Print format - len = srsran_print_check(str, - str_len, - len, - "rnti=%04x L=%d cce=%d dci=%s ", - dci->ctx.rnti, - dci->ctx.location.L, - dci->ctx.location.ncce, - srsran_dci_format_nr_string(dci->ctx.format)); - // Carrier indicator – 0 or 3 bits if (cfg->carrier_indicator_size) { len = srsran_print_check(str, str_len, len, "cc=%d ", dci->cc_id); @@ -1103,10 +1093,6 @@ static int dci_nr_format_1_0_to_str(const srsran_dci_dl_nr_t* dci, char* str, ui uint32_t len = 0; srsran_rnti_type_t rnti_type = dci->ctx.rnti_type; - // Print format - len = srsran_print_check( - str, str_len, len, "rnti=%04x L=%d cce=%d dci=1_0 ", dci->ctx.rnti, dci->ctx.location.L, dci->ctx.location.ncce); - if (rnti_type == srsran_rnti_type_p) { len = srsran_print_check(str, str_len, len, "smi=%d sm=%d ", dci->smi, dci->sm); } @@ -1563,10 +1549,6 @@ dci_nr_format_1_1_to_str(const srsran_dci_nr_t* q, const srsran_dci_dl_nr_t* dci uint32_t len = 0; const srsran_dci_cfg_nr_t* cfg = &q->cfg; - // Print format - len = srsran_print_check( - str, str_len, len, "rnti=%04x L=%d cce=%d dci=0_0 ", dci->ctx.rnti, dci->ctx.location.L, dci->ctx.location.ncce); - // Carrier indicator – 0 or 3 bits if (cfg->carrier_indicator_size > 0) { len = srsran_print_check(str, str_len, len, "cc=%d ", dci->cc_id); @@ -1578,11 +1560,11 @@ dci_nr_format_1_1_to_str(const srsran_dci_nr_t* q, const srsran_dci_dl_nr_t* dci } // Frequency domain resource assignment - len = srsran_print_check(str, str_len, len, "f_alloc=%d ", dci->freq_domain_assigment); + len = srsran_print_check(str, str_len, len, "f_alloc=0x%x ", dci->freq_domain_assigment); // Time domain resource assignment – 0, 1, 2, 3, or 4 bits if (cfg->nof_dl_time_res > 0) { - len = srsran_print_check(str, str_len, len, "t_alloc=%d ", dci->time_domain_assigment); + len = srsran_print_check(str, str_len, len, "t_alloc=0x%x ", dci->time_domain_assigment); } // VRB-to-PRB mapping – 0 or 1 @@ -1885,9 +1867,6 @@ static int dci_nr_rar_to_str(const srsran_dci_ul_nr_t* dci, char* str, uint32_t { uint32_t len = 0; - // Print format - len = srsran_print_check(str, str_len, len, "rnti=%04x dci=rar ", dci->ctx.rnti); - // Frequency hopping flag len = srsran_print_check(str, str_len, len, "hop=%d ", dci->freq_hopping_flag); @@ -1985,15 +1964,16 @@ int srsran_dci_nr_ul_unpack(const srsran_dci_nr_t* q, srsran_dci_msg_nr_t* msg, int srsran_dci_ctx_to_str(const srsran_dci_ctx_t* ctx, char* str, uint32_t str_len) { - // Print format - return srsran_print_check(str, - str_len, - 0, - "rnti=%04x L=%d cce=%d dci=%s ", - ctx->rnti, - ctx->location.L, - ctx->location.ncce, - srsran_dci_format_nr_string(ctx->format)); + uint32_t len = 0; + + // Print base + len = srsran_print_check(str, str_len, len, "rnti=%04x dci=%s ", ctx->rnti, srsran_dci_format_nr_string(ctx->format)); + + if (ctx->format != srsran_dci_format_nr_rar) { + len = srsran_print_check(str, str_len, len, "L=%d cce=%d ", ctx->location.L, ctx->location.ncce); + } + + return len; } int srsran_dci_ul_nr_to_str(const srsran_dci_nr_t* q, const srsran_dci_ul_nr_t* dci, char* str, uint32_t str_len) diff --git a/lib/src/phy/phch/pdcch.c b/lib/src/phy/phch/pdcch.c index b0351441a..e07c3a195 100644 --- a/lib/src/phy/phch/pdcch.c +++ b/lib/src/phy/phch/pdcch.c @@ -412,7 +412,7 @@ int srsran_pdcch_decode_msg(srsran_pdcch_t* q, srsran_dl_sf_cfg_t* sf, srsran_dc INFO("Skipping DCI: nCCE=%d, L=%d, msg_len=%d, mean=%f", msg->location.ncce, msg->location.L, nof_bits, mean); } } - } else { + } else if (msg != NULL) { ERROR("Invalid parameters, location=%d,%d", msg->location.ncce, msg->location.L); } return ret; diff --git a/lib/src/phy/phch/pdsch.c b/lib/src/phy/phch/pdsch.c index c0c15dd0d..ee7845bf8 100644 --- a/lib/src/phy/phch/pdsch.c +++ b/lib/src/phy/phch/pdsch.c @@ -522,25 +522,9 @@ static float apply_power_allocation(srsran_pdsch_t* q, srsran_pdsch_cfg_t* cfg, static void csi_correction(srsran_pdsch_t* q, srsran_pdsch_cfg_t* cfg, uint32_t codeword_idx, uint32_t tb_idx, void* e) { - uint32_t qm = 0; - switch (cfg->grant.tb[tb_idx].mod) { - case SRSRAN_MOD_BPSK: - qm = 1; - break; - case SRSRAN_MOD_QPSK: - qm = 2; - break; - case SRSRAN_MOD_16QAM: - qm = 4; - break; - case SRSRAN_MOD_64QAM: - qm = 6; - break; - case SRSRAN_MOD_256QAM: - qm = 8; - break; - default: - ERROR("No modulation"); + uint32_t qm = srsran_mod_bits_x_symbol(cfg->grant.tb[tb_idx].mod); + if (qm == 0) { + return; } const uint32_t csi_max_idx = srsran_vec_max_fi(q->csi[codeword_idx], cfg->grant.tb[tb_idx].nof_bits / qm); @@ -1189,18 +1173,18 @@ uint32_t srsran_pdsch_grant_rx_info(srsran_pdsch_grant_t* grant, { uint32_t len = srsran_ra_dl_info(grant, str, str_len); - len = srsran_print_check(str, str_len, len, ", crc={", 0); + len = srsran_print_check(str, str_len, len, ", crc={"); for (uint32_t i = 0; i < SRSRAN_MAX_CODEWORDS; i++) { if (grant->tb[i].enabled) { len = srsran_print_check(str, str_len, len, "%s", res[i].crc ? "OK" : "KO"); if (i < SRSRAN_MAX_CODEWORDS - 1) { if (grant->tb[i + 1].enabled) { - len = srsran_print_check(str, str_len, len, "/", 0); + len = srsran_print_check(str, str_len, len, "/"); } } } } - len = srsran_print_check(str, str_len, len, "}", 0); + len = srsran_print_check(str, str_len, len, "}"); // Average iterations between nof TB and divide by 2 to get full decoder iterations len = srsran_print_check( @@ -1216,7 +1200,7 @@ srsran_pdsch_rx_info(srsran_pdsch_cfg_t* cfg, srsran_pdsch_res_t res[SRSRAN_MAX_ len += srsran_pdsch_grant_rx_info(&cfg->grant, res, &str[len], str_len - len); if (cfg->meas_evm_en) { - len = srsran_print_check(str, str_len, len, ", evm={", 0); + len = srsran_print_check(str, str_len, len, ", evm={"); for (uint32_t i = 0; i < SRSRAN_MAX_CODEWORDS; i++) { if (cfg->grant.tb[i].enabled && !isnan(res[i].evm)) { len = srsran_print_check(str, str_len, len, "%.2f", res[i].evm); @@ -1227,7 +1211,7 @@ srsran_pdsch_rx_info(srsran_pdsch_cfg_t* cfg, srsran_pdsch_res_t res[SRSRAN_MAX_ } } } - len = srsran_print_check(str, str_len, len, "}", 0); + len = srsran_print_check(str, str_len, len, "}"); } if (cfg->meas_time_en) { diff --git a/lib/src/phy/phch/pdsch_nr.c b/lib/src/phy/phch/pdsch_nr.c index 368eb5967..4fcfe7b0e 100644 --- a/lib/src/phy/phch/pdsch_nr.c +++ b/lib/src/phy/phch/pdsch_nr.c @@ -488,7 +488,7 @@ int srsran_pdsch_nr_decode(srsran_pdsch_nr_t* q, const srsran_sch_grant_nr_t* grant, srsran_chest_dl_res_t* channel, cf_t* sf_symbols[SRSRAN_MAX_PORTS], - srsran_pdsch_res_nr_t data[SRSRAN_MAX_TB]) + srsran_pdsch_res_nr_t* data) { // Check input pointers if (!q || !cfg || !grant || !data || !sf_symbols) { @@ -547,9 +547,7 @@ int srsran_pdsch_nr_decode(srsran_pdsch_nr_t* q, // SCH decode for (uint32_t tb = 0; tb < SRSRAN_MAX_TB; tb++) { - nof_cw += grant->tb[tb].enabled ? 1 : 0; - - if (pdsch_nr_decode_codeword(q, cfg, &grant->tb[tb], &data[tb], grant->rnti) < SRSRAN_SUCCESS) { + if (pdsch_nr_decode_codeword(q, cfg, &grant->tb[tb], data, grant->rnti) < SRSRAN_SUCCESS) { ERROR("Error encoding TB %d", tb); return SRSRAN_ERROR; } diff --git a/lib/src/phy/phch/pssch.c b/lib/src/phy/phch/pssch.c index 065c39e4f..ec92751cd 100644 --- a/lib/src/phy/phch/pssch.c +++ b/lib/src/phy/phch/pssch.c @@ -30,23 +30,25 @@ #include "srsran/phy/utils/debug.h" #include "srsran/phy/utils/vector.h" -int srsran_pssch_init(srsran_pssch_t* q, srsran_cell_sl_t cell, srsran_sl_comm_resource_pool_t sl_comm_resource_pool) +int srsran_pssch_init(srsran_pssch_t* q, + const srsran_cell_sl_t* cell, + const srsran_sl_comm_resource_pool_t* sl_comm_resource_pool) { - if (q == NULL) { + if (q == NULL || cell == NULL || sl_comm_resource_pool == NULL) { return SRSRAN_ERROR_INVALID_INPUTS; } - q->cell = cell; - q->sl_comm_resource_pool = sl_comm_resource_pool; + q->cell = *cell; + q->sl_comm_resource_pool = *sl_comm_resource_pool; - if (cell.tm == SRSRAN_SIDELINK_TM1 || cell.tm == SRSRAN_SIDELINK_TM2) { - if (cell.cp == SRSRAN_CP_NORM) { + if (cell->tm == SRSRAN_SIDELINK_TM1 || cell->tm == SRSRAN_SIDELINK_TM2) { + if (cell->cp == SRSRAN_CP_NORM) { q->nof_data_symbols = SRSRAN_PSSCH_TM12_NUM_DATA_SYMBOLS; } else { q->nof_data_symbols = SRSRAN_PSSCH_TM12_NUM_DATA_SYMBOLS_CP_EXT; } - } else if (cell.tm == SRSRAN_SIDELINK_TM3 || cell.tm == SRSRAN_SIDELINK_TM4) { - if (cell.cp == SRSRAN_CP_NORM) { + } else if (cell->tm == SRSRAN_SIDELINK_TM3 || cell->tm == SRSRAN_SIDELINK_TM4) { + if (cell->cp == SRSRAN_CP_NORM) { q->nof_data_symbols = SRSRAN_PSSCH_TM34_NUM_DATA_SYMBOLS; } else { ERROR("Invalid CP for PSSCH, SL TM 3/4"); diff --git a/lib/src/phy/phch/pucch.c b/lib/src/phy/phch/pucch.c index 722cdd2c2..6edcddc5d 100644 --- a/lib/src/phy/phch/pucch.c +++ b/lib/src/phy/phch/pucch.c @@ -460,6 +460,11 @@ static int encode_signal_format3(srsran_pucch_t* q, uint32_t N_sf_0 = get_N_sf(cfg->format, 0, sf->shortened); uint32_t N_sf_1 = get_N_sf(cfg->format, 1, sf->shortened); + if (N_sf_1 == 0) { + ERROR("Invalid N_sf_1"); + return SRSRAN_ERROR; + } + uint32_t n_oc_0 = cfg->n_pucch % N_sf_1; uint32_t n_oc_1 = (N_sf_1 == 5) ? ((3 * cfg->n_pucch) % N_sf_1) : (n_oc_0 % N_sf_1); @@ -507,6 +512,11 @@ static int decode_signal_format3(srsran_pucch_t* q, uint32_t N_sf_0 = get_N_sf(cfg->format, 0, sf->shortened); uint32_t N_sf_1 = get_N_sf(cfg->format, 1, sf->shortened); + if (N_sf_1 == 0) { + ERROR("Invalid N_sf_1"); + return SRSRAN_ERROR; + } + uint32_t n_oc_0 = cfg->n_pucch % N_sf_1; uint32_t n_oc_1 = (N_sf_1 == 5) ? ((3 * cfg->n_pucch) % N_sf_1) : (n_oc_0 % N_sf_1); diff --git a/lib/src/phy/phch/pucch_nr.c b/lib/src/phy/phch/pucch_nr.c index 99bc1b567..af59b778b 100644 --- a/lib/src/phy/phch/pucch_nr.c +++ b/lib/src/phy/phch/pucch_nr.c @@ -85,8 +85,7 @@ int srsran_pucch_nr_alpha_idx(const srsran_carrier_nr_t* carrier, // Generate pseudo-random sequence uint32_t cinit = cfg->hopping_id_present ? cfg->hopping_id : carrier->pci; uint8_t cs[SRSRAN_NSYMB_PER_SLOT_NR * SRSRAN_NSLOTS_PER_FRAME_NR(SRSRAN_NR_MAX_NUMEROLOGY) * 8U] = {}; - srsran_sequence_apply_bit( - cs, cs, SRSRAN_NSYMB_PER_SLOT_NR * SRSRAN_NSLOTS_PER_FRAME_NR(carrier->scs) * 8, cinit); + srsran_sequence_apply_bit(cs, cs, SRSRAN_NSYMB_PER_SLOT_NR * SRSRAN_NSLOTS_PER_FRAME_NR(carrier->scs) * 8, cinit); // Create n_cs parameter uint32_t n_cs = 0; @@ -400,11 +399,11 @@ int srsran_pucch_nr_format1_encode(const srsran_pucch_nr_t* q, } // Modulate d - cf_t d = 0; + cf_t d[1] = {}; if (nof_bits == 1) { - srsran_mod_modulate(&q->bpsk, b, &d, nof_bits); + srsran_mod_modulate(&q->bpsk, b, d, 1); } else { - srsran_mod_modulate(&q->qpsk, b, &d, nof_bits); + srsran_mod_modulate(&q->qpsk, b, d, 2); } // Get group sequence @@ -439,7 +438,7 @@ int srsran_pucch_nr_format1_encode(const srsran_pucch_nr_t* q, // Compute y = d(0) * r_uv cf_t y[SRSRAN_NRE]; - srsran_vec_sc_prod_ccc(r_uv, d, y, SRSRAN_NRE); + srsran_vec_sc_prod_ccc(r_uv, d[0], y, SRSRAN_NRE); // Get w_i_m cf_t w_i_m = srsran_pucch_nr_format1_w(q, n_pucch, resource->time_domain_occ, m); @@ -564,7 +563,12 @@ static int pucch_nr_format2_encode(srsran_pucch_nr_t* q, } // Calculate number of encoded symbols - uint32_t E = srsran_uci_nr_pucch_format_2_3_4_E(resource); + int e = srsran_uci_nr_pucch_format_2_3_4_E(resource); + if (e < SRSRAN_SUCCESS) { + ERROR("Error selecting E"); + return SRSRAN_ERROR; + } + uint32_t E = (uint32_t)e; // 6.3.2.5.1 Scrambling uint32_t cinit = pucch_nr_format2_cinit(carrier, cfg, uci_cfg); diff --git a/lib/src/phy/phch/pusch_nr.c b/lib/src/phy/phch/pusch_nr.c index b54fa291e..3669959a4 100644 --- a/lib/src/phy/phch/pusch_nr.c +++ b/lib/src/phy/phch/pusch_nr.c @@ -918,7 +918,7 @@ int srsran_pusch_nr_decode(srsran_pusch_nr_t* q, const srsran_sch_grant_nr_t* grant, srsran_chest_dl_res_t* channel, cf_t* sf_symbols[SRSRAN_MAX_PORTS], - srsran_pusch_res_nr_t data[SRSRAN_MAX_TB]) + srsran_pusch_res_nr_t* data) { // Check input pointers if (!q || !cfg || !grant || !data || !sf_symbols) { @@ -947,7 +947,12 @@ int srsran_pusch_nr_decode(srsran_pusch_nr_t* q, nof_cw += grant->tb[tb].enabled ? 1 : 0; } - uint32_t nof_re = srsran_ra_dl_nr_slot_nof_re(cfg, grant); + int e = srsran_ra_dl_nr_slot_nof_re(cfg, grant); + if (e < SRSRAN_SUCCESS) { + ERROR("Getting number of RE"); + return SRSRAN_ERROR; + } + uint32_t nof_re = (uint32_t)e; if (channel->nof_re != nof_re) { ERROR("Inconsistent number of RE (%d!=%d)", channel->nof_re, nof_re); @@ -983,9 +988,7 @@ int srsran_pusch_nr_decode(srsran_pusch_nr_t* q, // SCH decode for (uint32_t tb = 0; tb < SRSRAN_MAX_TB; tb++) { - nof_cw += grant->tb[tb].enabled ? 1 : 0; - - if (pusch_nr_decode_codeword(q, cfg, &grant->tb[tb], &data[tb], grant->rnti) < SRSRAN_SUCCESS) { + if (pusch_nr_decode_codeword(q, cfg, &grant->tb[tb], data, grant->rnti) < SRSRAN_SUCCESS) { ERROR("Error encoding TB %d", tb); return SRSRAN_ERROR; } diff --git a/lib/src/phy/phch/ra_dl.c b/lib/src/phy/phch/ra_dl.c index 8755a1a64..925785136 100644 --- a/lib/src/phy/phch/ra_dl.c +++ b/lib/src/phy/phch/ra_dl.c @@ -711,15 +711,15 @@ uint32_t srsran_ra_dl_info(srsran_pdsch_grant_t* grant, char* info_str, uint32_t n = srsran_print_check(info_str, len, n, ", nof_prb=%d, nof_re=%d", grant->nof_prb, grant->nof_re); - n = srsran_print_check(info_str, len, n, ", tbs={", 0); + n = srsran_print_check(info_str, len, n, ", tbs={"); n = print_multi(info_str, n, len, grant, 1); - n = srsran_print_check(info_str, len, n, "}", 0); - n = srsran_print_check(info_str, len, n, ", mod={", 0); + n = srsran_print_check(info_str, len, n, "}"); + n = srsran_print_check(info_str, len, n, ", mod={"); n = print_multi(info_str, n, len, grant, 2); - n = srsran_print_check(info_str, len, n, "}", 0); - n = srsran_print_check(info_str, len, n, ", rv={", 0); + n = srsran_print_check(info_str, len, n, "}"); + n = srsran_print_check(info_str, len, n, ", rv={"); n = print_multi(info_str, n, len, grant, 0); - n = srsran_print_check(info_str, len, n, "}", 0); + n = srsran_print_check(info_str, len, n, "}"); if (grant->tx_scheme != SRSRAN_TXSCHEME_PORT0) { n = srsran_print_check(info_str, diff --git a/lib/src/phy/phch/ra_nr.c b/lib/src/phy/phch/ra_nr.c index 45caf0c61..3aab83510 100644 --- a/lib/src/phy/phch/ra_nr.c +++ b/lib/src/phy/phch/ra_nr.c @@ -134,7 +134,7 @@ static const float ra_nr_beta_offset_ack_table[RA_NR_BETA_OFFSET_HARQACK_SIZE] = /** * TS 38.213 V15.10.0 Table 9.3-2: Mapping of beta_offset values for CSI and the index signalled by higher layers */ -static const float ra_nr_beta_offset_csi_table[RA_NR_BETA_OFFSET_HARQACK_SIZE] = { +static const float ra_nr_beta_offset_csi_table[RA_NR_BETA_OFFSET_CSI_SIZE] = { 1.125f, 1.250f, 1.375f, 1.625f, 1.750f, 2.000f, 2.250f, 2.500f, 2.875f, 3.125f, 3.500f, 4.000f, 5.000f, 6.250f, 8.000f, 10.000f, 12.625f, 15.875f, 20.000f, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN}; @@ -147,8 +147,7 @@ static ra_nr_table_t ra_nr_select_table_pusch_noprecoding(srsran_mcs_table_t srsran_rnti_type_t rnti_type) { // Non-implemented parameters - bool mcs_c_rnti = false; - srsran_mcs_table_t configured_grant_table = srsran_mcs_table_64qam; + bool mcs_c_rnti = false; // - if mcs-Table in pusch-Config is set to 'qam256', and // - PUSCH is scheduled by a PDCCH with DCI format 0_1 with @@ -171,25 +170,25 @@ static ra_nr_table_t ra_nr_select_table_pusch_noprecoding(srsran_mcs_table_t // - the UE is configured with MCS-C-RNTI, and // - the PUSCH is scheduled by a PDCCH with // - CRC scrambled by MCS-C-RNTI, - if (mcs_c_rnti && dci_format != srsran_dci_format_nr_rar && rnti_type == srsran_rnti_type_mcs_c) { - return ra_nr_table_3; - } + // if (mcs_c_rnti && dci_format != srsran_dci_format_nr_rar && rnti_type == srsran_rnti_type_mcs_c) { + // return ra_nr_table_3; + // } // - mcs-Table in configuredGrantConfig is set to 'qam256', // - if PUSCH is scheduled by a PDCCH with CRC scrambled by CS-RNTI or // - if PUSCH is transmitted with configured grant - if (configured_grant_table == srsran_mcs_table_256qam && - (rnti_type == srsran_rnti_type_cs || dci_format == srsran_dci_format_nr_cg)) { - return ra_nr_table_2; - } + // if (configured_grant_table == srsran_mcs_table_256qam && + // (rnti_type == srsran_rnti_type_cs || dci_format == srsran_dci_format_nr_cg)) { + // return ra_nr_table_2; + // } // - mcs-Table in configuredGrantConfig is set to 'qam64LowSE' // - if PUSCH is scheduled by a PDCCH with CRC scrambled by CS-RNTI or // - if PUSCH is transmitted with configured grant, - if (configured_grant_table == srsran_mcs_table_qam64LowSE && - (rnti_type == srsran_rnti_type_cs || dci_format == srsran_dci_format_nr_cg)) { - return ra_nr_table_3; - } + // if (configured_grant_table == srsran_mcs_table_qam64LowSE && + // (rnti_type == srsran_rnti_type_cs || dci_format == srsran_dci_format_nr_cg)) { + // return ra_nr_table_3; + // } return ra_nr_table_1; } @@ -200,9 +199,8 @@ static ra_nr_table_t ra_nr_select_table_pdsch(srsran_mcs_table_t mcs_tab srsran_rnti_type_t rnti_type) { // Non-implemented parameters - bool sps_config_mcs_table_present = false; - srsran_mcs_table_t sps_config_mcs_table = srsran_mcs_table_64qam; - bool is_pdcch_sps = false; + bool sps_config_mcs_table_present = false; + bool is_pdcch_sps = false; // - the higher layer parameter mcs-Table given by PDSCH-Config is set to 'qam256', and // - the PDSCH is scheduled by a PDCCH with DCI format 1_1 with @@ -233,10 +231,10 @@ static ra_nr_table_t ra_nr_select_table_pdsch(srsran_mcs_table_t mcs_tab // - the UE is configured with the higher layer parameter mcs-Table given by SPS-Config set to 'qam64LowSE' // - if the PDSCH is scheduled by a PDCCH with CRC scrambled by CS-RNTI or // - if the PDSCH is scheduled without corresponding PDCCH transmission using SPS-Config, - if (sps_config_mcs_table_present && sps_config_mcs_table == srsran_mcs_table_qam64LowSE && - (rnti_type == srsran_rnti_type_cs || is_pdcch_sps)) { - return ra_nr_table_3; - } + // if (sps_config_mcs_table_present && sps_config_mcs_table == srsran_mcs_table_qam64LowSE && + // (rnti_type == srsran_rnti_type_cs || is_pdcch_sps)) { + // return ra_nr_table_3; + // } // else return ra_nr_table_1; @@ -470,8 +468,6 @@ int srsran_ra_nr_fill_tb(const srsran_sch_cfg_nr_t* pdsch_cfg, uint32_t mcs_idx, srsran_sch_tb_t* tb) { - uint32_t cw_idx = 0; - // Get target Rate double R = srsran_ra_nr_R_from_mcs( pdsch_cfg->sch_cfg.mcs_table, grant->dci_format, grant->dci_search_space, grant->rnti_type, mcs_idx); @@ -515,11 +511,10 @@ int srsran_ra_nr_fill_tb(const srsran_sch_cfg_nr_t* pdsch_cfg, return SRSRAN_ERROR; } - // Calculate number of layers accordingly + // Calculate number of layers accordingly, assumes first codeword only uint32_t nof_cw = grant->nof_layers < 5 ? 1 : 2; uint32_t nof_layers_cw1 = grant->nof_layers / nof_cw; - uint32_t nof_layers_cw2 = grant->nof_layers - nof_layers_cw1; - tb->N_L = (cw_idx == 0) ? nof_layers_cw1 : nof_layers_cw2; + tb->N_L = nof_layers_cw1; // Check DMRS and CSI-RS collision according to TS 38.211 7.4.1.5.3 Mapping to physical resources // If there was a collision, the number of RE in the grant would be wrong @@ -835,7 +830,7 @@ static float ra_ul_beta_offset_ack_semistatic(const srsran_beta_offsets_t* beta_ } // Protect table boundary - if (beta_offset_index > RA_NR_BETA_OFFSET_HARQACK_SIZE) { + if (beta_offset_index >= RA_NR_BETA_OFFSET_HARQACK_SIZE) { ERROR("Beta offset index for HARQ-ACK (%d) for O_ack=%d exceeds table size (%d)", beta_offset_index, uci_cfg->o_ack, @@ -860,8 +855,15 @@ static float ra_ul_beta_offset_csi_semistatic(const srsran_beta_offsets_t* beta_ return fix_beta_offset; } + int O_csi1 = srsran_csi_part1_nof_bits(uci_cfg->csi, uci_cfg->nof_csi); + int O_csi2 = srsran_csi_part2_nof_bits(uci_cfg->csi, uci_cfg->nof_csi); + if (O_csi1 < SRSRAN_SUCCESS || O_csi2 < SRSRAN_SUCCESS) { + ERROR("Invalid O_csi1 (%d) or O_csi2(%d)", O_csi1, O_csi2); + return NAN; + } + // Calculate number of CSI bits; CSI part 2 is not supported. - uint32_t O_csi = part2 ? 0 : srsran_csi_part1_nof_bits(uci_cfg->csi, uci_cfg->nof_csi); + uint32_t O_csi = (uint32_t)(part2 ? O_csi2 : O_csi1); // Select Beta Offset index from the number of HARQ-ACK bits uint32_t beta_offset_index = part2 ? beta_offsets->csi2_index1 : beta_offsets->csi1_index1; @@ -870,7 +872,7 @@ static float ra_ul_beta_offset_csi_semistatic(const srsran_beta_offsets_t* beta_ } // Protect table boundary - if (beta_offset_index > RA_NR_BETA_OFFSET_CSI_SIZE) { + if (beta_offset_index >= RA_NR_BETA_OFFSET_CSI_SIZE) { ERROR("Beta offset index for CSI (%d) for O_csi=%d exceeds table size (%d)", beta_offset_index, O_csi, diff --git a/lib/src/phy/phch/ra_sl.c b/lib/src/phy/phch/ra_sl.c index 67960fdd8..bbb116b38 100644 --- a/lib/src/phy/phch/ra_sl.c +++ b/lib/src/phy/phch/ra_sl.c @@ -52,7 +52,7 @@ int srsran_pscch_resources(uint32_t prb_num, } } - if (L == 0) { + if (L < 2) { // ERROR("Invalid PSCCH subframe bitmap"); return SRSRAN_ERROR; } @@ -130,7 +130,7 @@ int srsran_ra_sl_pssch_allowed_sf(uint32_t pssch_sf_idx, uint32_t trp_idx, uint3 int srsran_sci_generate_trp_idx(uint32_t duplex_mode, uint32_t tdd_config, uint32_t k_TRP) { - int retval = SRSRAN_ERROR; + int retval = SRSRAN_ERROR; struct timeval tv; gettimeofday(&tv, NULL); srsran_random_t random = srsran_random_init(tv.tv_usec); @@ -199,8 +199,7 @@ int srsran_sci_generate_trp_idx(uint32_t duplex_mode, uint32_t tdd_config, uint3 retval = srsran_sl_N_TRP_6_k_6[srsran_random_uniform_int_dist(random, 0, sizeof(srsran_sl_N_TRP_6_k_6) - 1)]; break; } - } - else { + } else { retval = SRSRAN_SUCCESS; } diff --git a/lib/src/phy/phch/ra_ul_nr.c b/lib/src/phy/phch/ra_ul_nr.c index b6f39be3c..34c0d9864 100644 --- a/lib/src/phy/phch/ra_ul_nr.c +++ b/lib/src/phy/phch/ra_ul_nr.c @@ -60,7 +60,7 @@ int srsran_ra_ul_nr_pusch_time_resource_default_A(uint32_t scs_cfg, uint32_t m, return SRSRAN_ERROR_INVALID_INPUTS; } - if (scs_cfg > 4) { + if (scs_cfg >= 4) { ERROR("Invalid numerology (%d)", scs_cfg); return SRSRAN_ERROR; } diff --git a/lib/src/phy/phch/sch.c b/lib/src/phy/phch/sch.c index c02e1c272..4cbdc7ca9 100644 --- a/lib/src/phy/phch/sch.c +++ b/lib/src/phy/phch/sch.c @@ -258,7 +258,12 @@ static int encode_tb_off(srsran_sch_t* q, if (cb_segm->C > softbuffer->max_cb) { ERROR("Error number of CB to encode (%d) exceeds soft buffer size (%d CBs)", cb_segm->C, softbuffer->max_cb); - return -1; + return SRSRAN_ERROR; + } + + if (Qm == 0) { + ERROR("Invalid Qm"); + return SRSRAN_ERROR; } uint32_t Gp = nof_e_bits / Qm; @@ -508,7 +513,7 @@ static int decode_tb(srsran_sch_t* q, int16_t* e_bits, uint8_t* data) { - if (q != NULL && data != NULL && softbuffer != NULL && e_bits != NULL && cb_segm != NULL) { + if (q != NULL && data != NULL && softbuffer != NULL && e_bits != NULL && cb_segm != NULL && Qm != 0) { if (cb_segm->tbs == 0 || cb_segm->C == 0) { return SRSRAN_SUCCESS; } @@ -556,11 +561,12 @@ static int decode_tb(srsran_sch_t* q, return SRSRAN_ERROR; } } else { - ERROR("Missing inputs: data=%d, softbuffer=%d, e_bits=%d, cb_segm=%d", + ERROR("Missing inputs: data=%d, softbuffer=%d, e_bits=%d, cb_segm=%d Qm=%d", data != 0, softbuffer != 0, e_bits != 0, - cb_segm != 0); + cb_segm != 0, + Qm); return SRSRAN_ERROR_INVALID_INPUTS; } } @@ -1027,6 +1033,11 @@ static int uci_decode_ri_ack(srsran_sch_t* q, uint32_t nb_q = cfg->grant.tb.nof_bits; uint32_t Qm = srsran_mod_bits_x_symbol(cfg->grant.tb.mod); + if (Qm == 0) { + ERROR("Invalid modulation %s", srsran_mod_string(cfg->grant.tb.mod)); + return SRSRAN_ERROR; + } + // If there is RI and CQI, assume RI = 1 for the purpose of RI/ACK decoding (3GPP 36.212 Clause 5.2.4.1. ) if (cfg->uci_cfg.cqi.data_enable) { if (cfg->uci_cfg.cqi.type == SRSRAN_CQI_TYPE_SUBBAND_HL && cfg->uci_cfg.cqi.ri_len) { @@ -1040,7 +1051,12 @@ static int uci_decode_ri_ack(srsran_sch_t* q, if (srsran_uci_cfg_total_ack(&cfg->uci_cfg) > 0) { float beta = get_beta_harq_offset(cfg->uci_offset.I_offset_ack); if (cfg->grant.tb.tbs == 0) { - beta /= get_beta_cqi_offset(cfg->uci_offset.I_offset_cqi); + float beta_cqi = get_beta_cqi_offset(cfg->uci_offset.I_offset_cqi); + if (!isnormal(beta_cqi)) { + ERROR("Invalid beta_cqi (%d, %f)", cfg->uci_offset.I_offset_cqi, beta_cqi); + return SRSRAN_ERROR; + } + beta /= beta_cqi; } ret = srsran_uci_decode_ack_ri(cfg, q_bits, @@ -1068,7 +1084,12 @@ static int uci_decode_ri_ack(srsran_sch_t* q, if (cfg->uci_cfg.cqi.ri_len > 0) { float beta = get_beta_ri_offset(cfg->uci_offset.I_offset_ri); if (cfg->grant.tb.tbs == 0) { - beta /= get_beta_cqi_offset(cfg->uci_offset.I_offset_cqi); + float beta_cqi = get_beta_cqi_offset(cfg->uci_offset.I_offset_cqi); + if (!isnormal(beta_cqi)) { + ERROR("Invalid beta_cqi (%d, %f)", cfg->uci_offset.I_offset_cqi, beta_cqi); + return SRSRAN_ERROR; + } + beta /= beta_cqi; } ret = srsran_uci_decode_ack_ri(cfg, q_bits, diff --git a/lib/src/phy/phch/sch_nr.c b/lib/src/phy/phch/sch_nr.c index ddc1b4dc4..838b2a4cd 100644 --- a/lib/src/phy/phch/sch_nr.c +++ b/lib/src/phy/phch/sch_nr.c @@ -120,12 +120,13 @@ int srsran_sch_nr_fill_tb_info(const srsran_carrier_nr_t* carrier, cfg->Nl = tb->N_L; // Calculate Nref - uint32_t N_re_lbrm = 156 * sch_nr_n_prb_lbrm(carrier->nof_prb); - double TCR_lbrm = 948.0 / 1024.0; - uint32_t Qm_lbrm = (sch_cfg->mcs_table == srsran_mcs_table_256qam) ? 8 : 6; - uint32_t TBS_LRBM = srsran_ra_nr_tbs(N_re_lbrm, 1.0, TCR_lbrm, Qm_lbrm, carrier->max_mimo_layers); - double R = 2.0 / 3.0; - cfg->Nref = ceil(TBS_LRBM / (cbsegm.C * R)); + uint32_t N_re_lbrm = SRSRAN_MAX_NRE_NR * sch_nr_n_prb_lbrm(carrier->nof_prb); + double TCR_lbrm = 948.0 / 1024.0; + uint32_t Qm_lbrm = (sch_cfg->mcs_table == srsran_mcs_table_256qam) ? 8 : 6; + uint32_t max_mimo_layers = SRSRAN_MAX(carrier->max_mimo_layers, 4); + uint32_t TBS_LRBM = srsran_ra_nr_tbs(N_re_lbrm, 1.0, TCR_lbrm, Qm_lbrm, max_mimo_layers); + double R = 2.0 / 3.0; + cfg->Nref = (uint32_t)ceil((double)TBS_LRBM / (double)(cbsegm.C * R)); // Calculate number of code blocks after applying CBGTI... not implemented, activate all CB for (uint32_t r = 0; r < cbsegm.C; r++) { @@ -614,18 +615,37 @@ static int sch_nr_decode(srsran_sch_nr_t* q, crc = &q->crc_cb; } - // Decode - int n_iter = srsran_ldpc_decoder_decode_crc_c(decoder, rm_buffer, q->temp_cb, n_llr, crc); - if (n_iter < SRSRAN_SUCCESS) { + // Decode. if CRC=KO, then ret=0 + int ret = srsran_ldpc_decoder_decode_crc_c(decoder, rm_buffer, q->temp_cb, n_llr, crc); + if (ret < SRSRAN_SUCCESS) { ERROR("Error decoding CB"); return SRSRAN_ERROR; } - nof_iter_sum += ((n_iter == 0) ? decoder->max_nof_iter : (uint32_t)n_iter); - // Compute CB CRC only if LDPC decoder reached the end - uint32_t cb_len = cfg.Kp - cfg.L_cb; - tb->softbuffer.rx->cb_crc[r] = (n_iter != 0); - SCH_INFO_RX("CB %d/%d CRC=%s", r, cfg.C, tb->softbuffer.rx->cb_crc[r] ? "OK" : "KO"); + // Compute number of iterations + uint32_t n_iter_cb = (ret == 0) ? decoder->max_nof_iter : (uint32_t)ret; + nof_iter_sum += n_iter_cb; + + // Check if CB is all zeros + uint32_t cb_len = cfg.Kp - cfg.L_cb; + bool all_zeros = true; + for (uint32_t i = 0; i < cb_len && all_zeros; i++) { + all_zeros = (q->temp_cb[i] == 0); + } + + tb->softbuffer.rx->cb_crc[r] = (ret != 0) && (!all_zeros); + SCH_INFO_RX("CB %d/%d iter=%d CRC=%s all_zeros=%s", + r, + cfg.C, + n_iter_cb, + tb->softbuffer.rx->cb_crc[r] ? "OK" : "KO", + all_zeros ? "yes" : "no"); + + // CB Debug trace + if (SRSRAN_DEBUG_ENABLED && srsran_verbose >= SRSRAN_VERBOSE_DEBUG && !handler_registered) { + DEBUG("CB %d/%d:", r, cfg.C); + srsran_vec_fprint_hex(stdout, q->temp_cb, cb_len); + } // Pack and count CRC OK only if CRC is match if (tb->softbuffer.rx->cb_crc[r]) { @@ -636,6 +656,14 @@ static int sch_nr_decode(srsran_sch_nr_t* q, input_ptr += E; } + // Set average number of iterations + if (cfg.C > 0) { + res->avg_iter = (float)nof_iter_sum / (float)cfg.C; + } else { + res->avg_iter = NAN; + } + + // Not all CB are decoded, skip TB union and CRC check if (cb_ok != cfg.C) { return SRSRAN_SUCCESS; @@ -656,12 +684,6 @@ static int sch_nr_decode(srsran_sch_nr_t* q, srsran_vec_u8_copy(output_ptr, tb->softbuffer.rx->data[r], cb_len / 8); output_ptr += cb_len / 8; - // CB Debug trace - if (SRSRAN_DEBUG_ENABLED && srsran_verbose >= SRSRAN_VERBOSE_DEBUG && !handler_registered) { - DEBUG("CB %d/%d:", r, cfg.C); - srsran_vec_fprint_byte(stdout, tb->softbuffer.rx->data[r], cb_len / 8); - } - // Compute TB CRC for last block if (cfg.C > 1 && r == cfg.C - 1) { uint8_t tb_crc_unpacked[24] = {}; @@ -671,26 +693,17 @@ static int sch_nr_decode(srsran_sch_nr_t* q, } } - // Check if TB is all zeros - bool all_zeros = true; - for (uint32_t i = 0; i < tb->tbs / 8 && all_zeros; i++) { - all_zeros = (res->payload[i] == 0); - } - // Calculate TB CRC from packed data if (cfg.C == 1) { - res->crc = !all_zeros; SCH_INFO_RX("TB: TBS=%d; CRC=%s", tb->tbs, tb->softbuffer.rx->cb_crc[0] ? "OK" : "KO"); + res->crc = true; } else { // More than one uint32_t checksum1 = srsran_crc_checksum_byte(crc_tb, res->payload, tb->tbs); - res->crc = (checksum1 == checksum2 && !all_zeros); + res->crc = (checksum1 == checksum2); SCH_INFO_RX("TB: TBS=%d; CRC={%06x, %06x}", tb->tbs, checksum1, checksum2); } - // Set average number of iterations - res->avg_iter = (float)nof_iter_sum / (float)cfg.C; - if (SRSRAN_DEBUG_ENABLED && srsran_verbose >= SRSRAN_VERBOSE_DEBUG && !handler_registered) { DEBUG("Decode: "); srsran_vec_fprint_byte(stdout, res->payload, tb->tbs / 8); @@ -756,4 +769,4 @@ int srsran_sch_nr_tb_info(const srsran_sch_tb_t* tb, const srsran_sch_tb_res_nr_ } return len; -} \ No newline at end of file +} diff --git a/lib/src/phy/phch/sci.c b/lib/src/phy/phch/sci.c index ef4a5d7c4..3af1b7cd4 100644 --- a/lib/src/phy/phch/sci.c +++ b/lib/src/phy/phch/sci.c @@ -24,26 +24,28 @@ #include "srsran/phy/phch/sci.h" #include "srsran/phy/utils/bit.h" -int srsran_sci_init(srsran_sci_t* q, srsran_cell_sl_t cell, srsran_sl_comm_resource_pool_t sl_comm_resource_pool) +int srsran_sci_init(srsran_sci_t* q, + const srsran_cell_sl_t* cell, + const srsran_sl_comm_resource_pool_t* sl_comm_resource_pool) { int ret = SRSRAN_ERROR_INVALID_INPUTS; - if (q != NULL) { + if (q != NULL && cell != NULL && sl_comm_resource_pool != NULL) { ret = SRSRAN_ERROR; bzero(q, sizeof(srsran_sci_t)); - q->nof_prb = cell.nof_prb; - q->tm = cell.tm; + q->nof_prb = cell->nof_prb; + q->tm = cell->tm; - if (cell.tm == SRSRAN_SIDELINK_TM1 || cell.tm == SRSRAN_SIDELINK_TM2) { + if (cell->tm == SRSRAN_SIDELINK_TM1 || cell->tm == SRSRAN_SIDELINK_TM2) { q->format = SRSRAN_SCI_FORMAT0; - q->sci_len = srsran_sci_format0_sizeof(cell.nof_prb); + q->sci_len = srsran_sci_format0_sizeof(cell->nof_prb); - } else if (cell.tm == SRSRAN_SIDELINK_TM3 || cell.tm == SRSRAN_SIDELINK_TM4) { + } else if (cell->tm == SRSRAN_SIDELINK_TM3 || cell->tm == SRSRAN_SIDELINK_TM4) { q->format = SRSRAN_SCI_FORMAT1; q->sci_len = SRSRAN_SCI_TM34_LEN; - q->size_sub_channel = sl_comm_resource_pool.size_sub_channel; - q->num_sub_channel = sl_comm_resource_pool.num_sub_channel; + q->size_sub_channel = sl_comm_resource_pool->size_sub_channel; + q->num_sub_channel = sl_comm_resource_pool->num_sub_channel; } else { return SRSRAN_ERROR; diff --git a/lib/src/phy/phch/test/npdsch_test.c b/lib/src/phy/phch/test/npdsch_test.c index 23f9aedf3..939164170 100644 --- a/lib/src/phy/phch/test/npdsch_test.c +++ b/lib/src/phy/phch/test/npdsch_test.c @@ -57,6 +57,8 @@ uint16_t rnti = 1234; uint16_t i_tbs_val = 0; char* input_file = NULL; +static srsran_random_t random_gen = NULL; + void usage(char* prog) { printf("Usage: %s [fmMlsrRFpnv] \n", prog); @@ -172,7 +174,7 @@ int get_ref_res(srsran_nbiot_cell_t cell, int32_t* re_with_refs) return num_ref; } -int extract_re(srsran_nbiot_cell_t cell, uint32_t l_start, uint32_t expected_nof_re) +int extract_re(srsran_nbiot_cell_t cell, uint32_t l_start, uint32_t expected_nof_re2) { srsran_npdsch_t npdsch; bzero(&npdsch, sizeof(srsran_npdsch_t)); @@ -206,8 +208,8 @@ int extract_re(srsran_nbiot_cell_t cell, uint32_t l_start, uint32_t expected_nof #endif // check number of extracted REs - if (nof_ext_syms != expected_nof_re) { - printf("RE extraction failed (expected %d, but got %d)!\n", expected_nof_re, nof_ext_syms); + if (nof_ext_syms != expected_nof_re2) { + printf("RE extraction failed (expected %d, but got %d)!\n", expected_nof_re2, nof_ext_syms); return SRSRAN_ERROR; } @@ -243,7 +245,9 @@ int re_extract_test(int argc, char** argv) // Standalone mode with l_start=0 gives the maximum number of REs cell.mode = mode; cell.base.nof_prb = 1; - cell.base.id = (mode == SRSRAN_NBIOT_MODE_INBAND_SAME_PCI) ? n_id_ncell : rand() % SRSRAN_NUM_PCI; + cell.base.id = (mode == SRSRAN_NBIOT_MODE_INBAND_SAME_PCI) + ? n_id_ncell + : srsran_random_uniform_int_dist(random_gen, 0, SRSRAN_NUM_PCI - 1); cell.n_id_ncell = n_id_ncell; cell.nof_ports = nof_ports_nbiot; cell.base.nof_ports = nof_ports_lte; @@ -388,9 +392,8 @@ int coding_test(int argc, char** argv) } // generate random data - srand(time(NULL)); for (int i = 0; i < grant.mcs[0].tbs / 8; i++) { - data[i] = rand() % 256; + data[i] = (uint8_t)srsran_random_uniform_int_dist(random_gen, 0, 255); } if (!input_file) { @@ -472,8 +475,8 @@ quit: int main(int argc, char** argv) { - int ret = SRSRAN_ERROR; - + int ret = SRSRAN_ERROR; + random_gen = srsran_random_init(0x1234); if (re_extract_test(argc, argv) != SRSRAN_SUCCESS) { printf("Resource element extraction test failed!\n"); return ret; diff --git a/lib/src/phy/phch/test/pbch_test.c b/lib/src/phy/phch/test/pbch_test.c index 86c79ec27..616829494 100644 --- a/lib/src/phy/phch/test/pbch_test.c +++ b/lib/src/phy/phch/test/pbch_test.c @@ -81,6 +81,7 @@ int main(int argc, char** argv) int nof_re; cf_t* sf_symbols[SRSRAN_MAX_PORTS]; uint32_t nof_rx_ports; + srsran_random_t random_gen = srsran_random_init(0x1234); parse_args(argc, argv); @@ -109,9 +110,8 @@ int main(int argc, char** argv) exit(-1); } - srand(time(NULL)); for (i = 0; i < SRSRAN_BCH_PAYLOAD_LEN; i++) { - bch_payload_tx[i] = rand() % 2; + bch_payload_tx[i] = (uint8_t)srsran_random_uniform_int_dist(random_gen, 0, 1); } srsran_pbch_encode(&pbch, bch_payload_tx, sf_symbols, 0); @@ -136,6 +136,7 @@ int main(int argc, char** argv) } srsran_chest_dl_res_free(&chest_dl_res); + srsran_random_free(random_gen); printf("Tx ports: %d - Rx ports: %d\n", cell.nof_ports, nof_rx_ports); printf("Tx payload: "); diff --git a/lib/src/phy/phch/test/pdcch_test.c b/lib/src/phy/phch/test/pdcch_test.c index 050ef51e3..2571f0782 100644 --- a/lib/src/phy/phch/test/pdcch_test.c +++ b/lib/src/phy/phch/test/pdcch_test.c @@ -173,6 +173,7 @@ int main(int argc, char** argv) int nof_dcis; bzero(&testcases, sizeof(testcase_dci_t) * 10); + srsran_random_t random_gen = srsran_random_init(0x1234); int ret = -1; @@ -233,14 +234,14 @@ int main(int argc, char** argv) dci.type0_alloc.rbg_bitmask = 0x5; dci.cif_present = dci_cfg.cif_enabled; if (dci_cfg.cif_enabled) { - dci.cif = (uint32_t)(random() & 0x7); + dci.cif = (uint32_t)srsran_random_uniform_int_dist(random_gen, 0, 7); } /* Format 1 Test case */ if (cell.nof_ports == 1) { testcases[nof_dcis].dci_format = SRSRAN_DCI_FORMAT1; if (dci_cfg.cif_enabled) { - dci.cif = (uint32_t)(random() & 0x7); + dci.cif = (uint32_t)srsran_random_uniform_int_dist(random_gen, 0, 7); } testcases[nof_dcis].ra_dl_tx = dci; nof_dcis++; @@ -249,7 +250,7 @@ int main(int argc, char** argv) dci.tb[0].mcs_idx = 15; testcases[nof_dcis].dci_format = SRSRAN_DCI_FORMAT1; if (dci_cfg.cif_enabled) { - dci.cif = (uint32_t)(random() & 0x7); + dci.cif = (uint32_t)srsran_random_uniform_int_dist(random_gen, 0, 7); } testcases[nof_dcis].ra_dl_tx = dci; nof_dcis++; @@ -262,7 +263,7 @@ int main(int argc, char** argv) dci.tb[1].ndi = true; testcases[nof_dcis].dci_format = SRSRAN_DCI_FORMAT2A; if (dci_cfg.cif_enabled) { - dci.cif = (uint32_t)(random() & 0x7); + dci.cif = (uint32_t)srsran_random_uniform_int_dist(random_gen, 0, 7); } testcases[nof_dcis].ra_dl_tx = dci; nof_dcis++; @@ -275,15 +276,12 @@ int main(int argc, char** argv) dci.tb[1].ndi = false; testcases[nof_dcis].dci_format = SRSRAN_DCI_FORMAT2; if (dci_cfg.cif_enabled) { - dci.cif = (uint32_t)(random() & 0x7); + dci.cif = (uint32_t)srsran_random_uniform_int_dist(random_gen, 0, 7); } testcases[nof_dcis].ra_dl_tx = dci; nof_dcis++; } - srsran_dci_cfg_t dci_cfg; - ZERO_OBJECT(dci_cfg); - srsran_dl_sf_cfg_t dl_sf; ZERO_OBJECT(dl_sf); dl_sf.cfi = cfi; @@ -400,6 +398,7 @@ quit: srsran_pdcch_free(&pdcch_rx); srsran_chest_dl_res_free(&chest_dl_res); srsran_regs_free(®s); + srsran_random_free(random_gen); for (i = 0; i < SRSRAN_MAX_PORTS; i++) { free(slot_symbols[i]); diff --git a/lib/src/phy/phch/test/pdsch_test.c b/lib/src/phy/phch/test/pdsch_test.c index 2d20120fb..d5d6bfc87 100644 --- a/lib/src/phy/phch/test/pdsch_test.c +++ b/lib/src/phy/phch/test/pdsch_test.c @@ -203,6 +203,7 @@ int main(int argc, char** argv) srsran_chest_dl_t chest; srsran_chest_dl_res_t chest_res; srsran_pdsch_res_t pdsch_res[SRSRAN_MAX_CODEWORDS]; + srsran_random_t random_gen = srsran_random_init(0x1234); /* Initialise to zeros */ ZERO_OBJECT(softbuffers_tx); @@ -395,7 +396,7 @@ int main(int argc, char** argv) for (int tb = 0; tb < SRSRAN_MAX_CODEWORDS; tb++) { if (pdsch_cfg.grant.tb[tb].enabled) { for (int byte = 0; byte < pdsch_cfg.grant.tb[tb].tbs / 8; byte++) { - data_tx[tb][byte] = (uint8_t)(rand() % 256); + data_tx[tb][byte] = (uint8_t)srsran_random_uniform_int_dist(random_gen, 0, 255); } } } @@ -575,6 +576,7 @@ quit: free(rx_slot_symbols[i]); } } + srsran_random_free(random_gen); if (ret) { printf("Error\n"); } else { diff --git a/lib/src/phy/phch/test/phich_test.c b/lib/src/phy/phch/test/phich_test.c index 5d29ab2de..649d41e95 100644 --- a/lib/src/phy/phch/test/phich_test.c +++ b/lib/src/phy/phch/test/phich_test.c @@ -98,15 +98,16 @@ void parse_args(int argc, char** argv) int main(int argc, char** argv) { - srsran_phich_t phich; - srsran_regs_t regs; - int i, j; - int nof_re; - cf_t* slot_symbols[SRSRAN_MAX_PORTS]; - uint8_t ack[50][SRSRAN_PHICH_NORM_NSEQUENCES]; - uint32_t nsf; - int cid, max_cid; - uint32_t ngroup, nseq, max_nseq; + srsran_phich_t phich; + srsran_regs_t regs; + int i, j; + int nof_re; + cf_t* slot_symbols[SRSRAN_MAX_PORTS]; + uint8_t ack[50][SRSRAN_PHICH_NORM_NSEQUENCES]; + uint32_t nsf; + int cid, max_cid; + uint32_t ngroup, nseq, max_nseq; + srsran_random_t random_gen = srsran_random_init(0x1234); parse_args(argc, argv); @@ -170,7 +171,7 @@ int main(int argc, char** argv) resource.ngroup = ngroup; resource.nseq = nseq; - ack[ngroup][nseq] = rand() % 2; + ack[ngroup][nseq] = (uint8_t)srsran_random_uniform_int_dist(random_gen, 0, 1); srsran_phich_encode(&phich, &dl_sf, resource, ack[ngroup][nseq], slot_symbols); } @@ -216,7 +217,7 @@ int main(int argc, char** argv) cid++; } srsran_phich_free(&phich); - + srsran_random_free(random_gen); srsran_chest_dl_res_free(&chest_res); for (i = 0; i < SRSRAN_MAX_PORTS; i++) { diff --git a/lib/src/phy/phch/test/prach_test_multi.c b/lib/src/phy/phch/test/prach_test_multi.c index 96152643f..4aad36152 100644 --- a/lib/src/phy/phch/test/prach_test_multi.c +++ b/lib/src/phy/phch/test/prach_test_multi.c @@ -152,11 +152,10 @@ void stagger_prach_powers(srsran_prach_t* prach, int main(int argc, char** argv) { parse_args(argc, argv); - srsran_prach_t prach; - - bool high_speed_flag = false; - srand(0); - cf_t preamble[MAX_LEN]; + srsran_prach_t prach; + srsran_random_t random_gen = srsran_random_init(0x1234); + bool high_speed_flag = false; + cf_t preamble[MAX_LEN]; memset(preamble, 0, sizeof(cf_t) * MAX_LEN); cf_t preamble_sum[MAX_LEN]; memset(preamble_sum, 0, sizeof(cf_t) * MAX_LEN); @@ -191,7 +190,7 @@ int main(int argc, char** argv) printf("limiting number of preambles to 6\n"); if (test_offset_calculation) { for (int i = 0; i < 6; i++) { - offsets[i] = (rand() % 50); + offsets[i] = srsran_random_uniform_int_dist(random_gen, 0, 49); } } } @@ -261,6 +260,7 @@ int main(int argc, char** argv) } srsran_prach_free(&prach); + srsran_random_free(random_gen); printf("Done\n"); exit(0); } diff --git a/lib/src/phy/phch/test/pscch_test.c b/lib/src/phy/phch/test/pscch_test.c index 16edfc3cf..beb3a2bb8 100644 --- a/lib/src/phy/phch/test/pscch_test.c +++ b/lib/src/phy/phch/test/pscch_test.c @@ -107,7 +107,7 @@ int main(int argc, char** argv) // SCI srsran_sci_t sci; - srsran_sci_init(&sci, cell, sl_comm_resource_pool); + srsran_sci_init(&sci, &cell, &sl_comm_resource_pool); sci.mcs_idx = 2; // PSCCH diff --git a/lib/src/phy/phch/test/pssch_pscch_file_test.c b/lib/src/phy/phch/test/pssch_pscch_file_test.c index fa6f73498..9bec2122b 100644 --- a/lib/src/phy/phch/test/pssch_pscch_file_test.c +++ b/lib/src/phy/phch/test/pssch_pscch_file_test.c @@ -160,7 +160,10 @@ int base_init() } srsran_vec_cf_zero(input_buffer, sf_n_samples); - srsran_sci_init(&sci, cell, sl_comm_resource_pool); + if (srsran_sci_init(&sci, &cell, &sl_comm_resource_pool) < SRSRAN_SUCCESS) { + ERROR("Error in SCI init"); + return SRSRAN_ERROR; + } if (srsran_pscch_init(&pscch, SRSRAN_MAX_PRB) != SRSRAN_SUCCESS) { ERROR("Error in PSCCH init"); @@ -177,7 +180,7 @@ int base_init() return SRSRAN_ERROR; } - if (srsran_pssch_init(&pssch, cell, sl_comm_resource_pool) != SRSRAN_SUCCESS) { + if (srsran_pssch_init(&pssch, &cell, &sl_comm_resource_pool) != SRSRAN_SUCCESS) { ERROR("Error initializing PSSCH"); return SRSRAN_ERROR; } diff --git a/lib/src/phy/phch/test/pssch_test.c b/lib/src/phy/phch/test/pssch_test.c index 204cd3533..2ed202415 100644 --- a/lib/src/phy/phch/test/pssch_test.c +++ b/lib/src/phy/phch/test/pssch_test.c @@ -92,7 +92,7 @@ int main(int argc, char** argv) } srsran_pssch_t pssch = {}; - if (srsran_pssch_init(&pssch, cell, sl_comm_resource_pool) != SRSRAN_SUCCESS) { + if (srsran_pssch_init(&pssch, &cell, &sl_comm_resource_pool) != SRSRAN_SUCCESS) { ERROR("Error initializing PSSCH"); return SRSRAN_ERROR; } diff --git a/lib/src/phy/phch/test/sch_nr_test.c b/lib/src/phy/phch/test/sch_nr_test.c index 2baae9fed..7cdf690d9 100644 --- a/lib/src/phy/phch/test/sch_nr_test.c +++ b/lib/src/phy/phch/test/sch_nr_test.c @@ -114,8 +114,11 @@ int main(int argc, char** argv) goto clean_exit; } - srsran_sch_nr_args_t args = {}; - args.disable_simd = false; + srsran_sch_nr_args_t args = {}; + args.disable_simd = false; + args.decoder_use_flooded = false; + args.decoder_scaling_factor = 0.8; + args.max_nof_iter = 20; if (srsran_sch_nr_init_tx(&sch_nr_tx, &args) < SRSRAN_SUCCESS) { ERROR("Error initiating SCH NR for Tx"); goto clean_exit; @@ -152,10 +155,9 @@ int main(int argc, char** argv) } // Use grant default A time resources with m=0 - if (srsran_ra_dl_nr_time_default_A(0, pdsch_cfg.dmrs.typeA_pos, &pdsch_cfg.grant) < SRSRAN_SUCCESS) { - ERROR("Error loading default grant"); - goto clean_exit; - } + pdsch_cfg.grant.S = 1; + pdsch_cfg.grant.L = 13; + pdsch_cfg.grant.k = 0; pdsch_cfg.grant.nof_layers = carrier.max_mimo_layers; pdsch_cfg.grant.dci_format = srsran_dci_format_nr_1_0; diff --git a/lib/src/phy/phch/uci.c b/lib/src/phy/phch/uci.c index f1b7cfdb8..f14147213 100644 --- a/lib/src/phy/phch/uci.c +++ b/lib/src/phy/phch/uci.c @@ -433,6 +433,11 @@ static uint32_t Q_prime_ri_ack(srsran_pusch_cfg_t* cfg, uint32_t O, uint32_t O_c } } + if (K == 0) { + ERROR("K is zero!"); + return 0; + } + uint32_t x = (uint32_t)ceilf((float)O * cfg->grant.L_prb * SRSRAN_NRE * cfg->grant.nof_symb * beta / K); uint32_t Q_prime = SRSRAN_MIN(x, 4 * cfg->grant.L_prb * SRSRAN_NRE); diff --git a/lib/src/phy/phch/uci_nr.c b/lib/src/phy/phch/uci_nr.c index 6ec06b0f0..be0b4c92d 100644 --- a/lib/src/phy/phch/uci_nr.c +++ b/lib/src/phy/phch/uci_nr.c @@ -1106,13 +1106,13 @@ int srsran_uci_nr_decode_pusch_ack(srsran_uci_nr_t* q, int8_t* llr, srsran_uci_value_nr_t* value) { - int A = cfg->o_ack; - // Check inputs if (q == NULL || cfg == NULL || llr == NULL || value == NULL) { return SRSRAN_ERROR_INVALID_INPUTS; } + int A = cfg->o_ack; + // 6.3.2.1 UCI bit sequence generation // 6.3.2.1.1 HARQ-ACK bool has_csi_part2 = srsran_csi_has_part2(cfg->csi, cfg->nof_csi); diff --git a/lib/src/phy/rf/rf_uhd_generic.h b/lib/src/phy/rf/rf_uhd_generic.h index 2de4902c1..8e3bd87d8 100644 --- a/lib/src/phy/rf/rf_uhd_generic.h +++ b/lib/src/phy/rf/rf_uhd_generic.h @@ -222,9 +222,13 @@ public: stream_args.channels[i] = i; } - if (not usrp->get_device()->get_tree()->exists(TREE_DBOARD_RX_FRONTEND_NAME)) { + // Try to get dboard name from property tree + uhd::property_tree::sptr tree = usrp->get_device()->get_tree(); + if (tree == nullptr || not tree->exists(TREE_DBOARD_RX_FRONTEND_NAME)) { + // Couldn't find dboard name in property tree return err; } + std::string dboard_name = usrp->get_device()->get_tree()->access(TREE_DBOARD_RX_FRONTEND_NAME).get(); // Detect if it a AD9361 based device diff --git a/lib/src/phy/sync/psss.c b/lib/src/phy/sync/psss.c index 474b3fd10..c6cc0462b 100644 --- a/lib/src/phy/sync/psss.c +++ b/lib/src/phy/sync/psss.c @@ -192,6 +192,10 @@ void srsran_psss_put_sf_buffer(cf_t* psss_signal, cf_t* sf_buffer, uint32_t nof_ */ int srsran_psss_find(srsran_psss_t* q, cf_t* input, uint32_t nof_prb, srsran_cp_t cp) { + if (q == NULL || input == NULL) { + return SRSRAN_ERROR_INVALID_INPUTS; + } + // One array for each N_id_2 float corr_peak_value[2] = {}; uint32_t corr_peak_pos[2] = {}; diff --git a/lib/src/phy/ue/test/gen_ack_test.c b/lib/src/phy/ue/test/gen_ack_test.c index 58d832e4b..dc24ba043 100644 --- a/lib/src/phy/ue/test/gen_ack_test.c +++ b/lib/src/phy/ue/test/gen_ack_test.c @@ -134,7 +134,8 @@ int fdd_tests(uint32_t max_cc) for (uint32_t i = 0; i < nof_cc; i++) { TESTASSERT(uci_data.cfg.ack[i].ncce[0] == i + 1); for (uint32_t j = 0; j < uci_data.cfg.ack[i].nof_acks; j++) { - TESTASSERT(uci_data.value.ack.ack_value[k++]); + TESTASSERT(uci_data.value.ack.ack_value[k]); + k++; } } TESTASSERT(k == srsran_uci_cfg_total_ack(&uci_data.cfg)); @@ -152,7 +153,6 @@ int fdd_tests(uint32_t max_cc) int main(int argc, char** argv) { - // Test only until Format1B - CS TESTASSERT(fdd_tests(2) == 0); diff --git a/lib/src/phy/utils/test/dft_test.c b/lib/src/phy/utils/test/dft_test.c index b4034ad68..fc99148c1 100644 --- a/lib/src/phy/utils/test/dft_test.c +++ b/lib/src/phy/utils/test/dft_test.c @@ -19,6 +19,8 @@ * */ +#include "srsran/phy/utils/debug.h" +#include "srsran/phy/utils/random.h" #include #include #include @@ -31,10 +33,10 @@ #include "srsran/phy/utils/vector.h" uint32_t N = 256; -bool forward = true; -bool mirror = false; -bool norm = false; -bool dc = false; +bool forward = true; +bool mirror = false; +bool norm = false; +bool dc = false; void usage(char* prog) { @@ -87,30 +89,42 @@ int test_dft(cf_t* in) { int res = 0; - srsran_dft_plan_t plan; - if (forward) { - srsran_dft_plan(&plan, N, SRSRAN_DFT_FORWARD, SRSRAN_DFT_COMPLEX); - } else { - srsran_dft_plan(&plan, N, SRSRAN_DFT_BACKWARD, SRSRAN_DFT_COMPLEX); - } - srsran_dft_plan_set_mirror(&plan, mirror); - srsran_dft_plan_set_norm(&plan, norm); - srsran_dft_plan_set_dc(&plan, dc); - cf_t* out1 = srsran_vec_cf_malloc(N); cf_t* out2 = srsran_vec_cf_malloc(N); srsran_vec_cf_zero(out1, N); srsran_vec_cf_zero(out2, N); + srsran_dft_plan_t plan = {}; + if (forward) { + if (srsran_dft_plan(&plan, N, SRSRAN_DFT_FORWARD, SRSRAN_DFT_COMPLEX) != SRSRAN_SUCCESS) { + ERROR("Error in DFT plan"); + goto clean_exit; + } + } else { + if (srsran_dft_plan(&plan, N, SRSRAN_DFT_BACKWARD, SRSRAN_DFT_COMPLEX) != SRSRAN_SUCCESS) { + ERROR("Error in DFT plan"); + goto clean_exit; + } + } + srsran_dft_plan_set_mirror(&plan, mirror); + srsran_dft_plan_set_norm(&plan, norm); + srsran_dft_plan_set_dc(&plan, dc); + print(in, N); srsran_dft_run(&plan, in, out1); print(out1, N); srsran_dft_plan_t plan_rev; if (!forward) { - srsran_dft_plan(&plan_rev, N, SRSRAN_DFT_FORWARD, SRSRAN_DFT_COMPLEX); + if (srsran_dft_plan(&plan_rev, N, SRSRAN_DFT_FORWARD, SRSRAN_DFT_COMPLEX) != SRSRAN_SUCCESS) { + ERROR("Error in DFT plan"); + goto clean_exit; + } } else { - srsran_dft_plan(&plan_rev, N, SRSRAN_DFT_BACKWARD, SRSRAN_DFT_COMPLEX); + if (srsran_dft_plan(&plan_rev, N, SRSRAN_DFT_BACKWARD, SRSRAN_DFT_COMPLEX) != SRSRAN_SUCCESS) { + ERROR("Error in DFT plan"); + goto clean_exit; + } } srsran_dft_plan_set_mirror(&plan_rev, mirror); srsran_dft_plan_set_norm(&plan_rev, norm); @@ -131,6 +145,7 @@ int test_dft(cf_t* in) res = -1; } +clean_exit: srsran_dft_plan_free(&plan); srsran_dft_plan_free(&plan_rev); free(out1); @@ -141,19 +156,17 @@ int test_dft(cf_t* in) int main(int argc, char** argv) { + srsran_random_t random_gen = srsran_random_init(0x1234); parse_args(argc, argv); cf_t* in = srsran_vec_cf_malloc(N); - srsran_vec_cf_zero(in, N); - for (int i = 1; i < N - 1; i++) { - float re = 100 * rand() / (float)RAND_MAX; - float im = 100 * rand() / (float)RAND_MAX; - in[i] = re + im * I; - } + in[0] = 0.0f; + srsran_random_uniform_complex_dist_vector(random_gen, &in[1], N - 1, -1, 1); if (test_dft(in) != 0) return -1; free(in); + srsran_random_free(random_gen); printf("Done\n"); exit(0); } diff --git a/lib/src/phy/utils/test/vector_test.c b/lib/src/phy/utils/test/vector_test.c index d33a1298f..b666bd40c 100644 --- a/lib/src/phy/utils/test/vector_test.c +++ b/lib/src/phy/utils/test/vector_test.c @@ -133,7 +133,15 @@ TEST( for (int i = 0; i < block_size; i++) { gold += x[i] * y[i]; } - mse = (gold - z) / abs(gold); + // Check... + float abs_gold = abs(gold); + if (isnormal(abs_gold)) { + // Protected zero division + mse = (gold - z) / abs_gold; + } else { + // Flag error + mse = MAX_MSE; + } free(x); free(y);) diff --git a/lib/src/phy/utils/vector.c b/lib/src/phy/utils/vector.c index 0236cff2e..9fcf0587c 100644 --- a/lib/src/phy/utils/vector.c +++ b/lib/src/phy/utils/vector.c @@ -430,12 +430,22 @@ void srsran_vec_save_file(char* filename, const void* buffer, const uint32_t len } } +#define SAFE_READ(PTR, SIZE, N, FILE) \ + do { \ + size_t nbytes = SIZE * N; \ + if (nbytes != fread(PTR, SIZE, N, FILE)) { \ + perror("read"); \ + fclose(FILE); \ + exit(1); \ + } \ + } while (false) + void srsran_vec_load_file(char* filename, void* buffer, const uint32_t len) { FILE* f; f = fopen(filename, "r"); if (f) { - fread(buffer, len, 1, f); + SAFE_READ(buffer, len, 1, f); fclose(f); } else { perror("fopen"); diff --git a/lib/src/upper/rlc_am_lte.cc b/lib/src/upper/rlc_am_lte.cc index 11be0388f..89ac2d7c0 100644 --- a/lib/src/upper/rlc_am_lte.cc +++ b/lib/src/upper/rlc_am_lte.cc @@ -539,16 +539,14 @@ void rlc_am_lte::rlc_am_lte_tx::discard_sdu(uint32_t discard_sn) return false; }); - if (discarded) { - // remove also from undelivered SDUs queue - logger.info("Discarding SDU with PDCP_SN=%d", discard_sn); - if (not undelivered_sdu_info_queue.has_pdcp_sn(discard_sn)) { - logger.info("PDCP SDU info does not exists for discarded SDU. PDCP_SN=%d", discard_sn); - } else { - undelivered_sdu_info_queue.clear_pdcp_sdu(discard_sn); - } + // Discard fails when the PDCP PDU is already in Tx window. + logger.info("%s PDU with PDCP_SN=%d", discarded ? "Discarding" : "Couldn't discard", discard_sn); + + // always try remove from undelivered SDUs queue + if (not undelivered_sdu_info_queue.has_pdcp_sn(discard_sn)) { + logger.info("PDCP SDU info does not exists for discarded SDU. PDCP_SN=%d", discard_sn); } else { - logger.info("Could not find SDU to discard. PDCP_SN=%d", discard_sn); + undelivered_sdu_info_queue.clear_pdcp_sdu(discard_sn); } } @@ -1307,8 +1305,12 @@ void rlc_am_lte::rlc_am_lte_tx::update_notification_ack_info(uint32_t rlc_sn) auto& acked_pdu = tx_window[rlc_sn]; // Iterate over all PDCP SNs of the same RLC PDU that were TX'ed for (rlc_am_pdu_segment& acked_segment : acked_pdu) { - uint32_t pdcp_sn = acked_segment.pdcp_sn(); - pdcp_pdu_info& info = undelivered_sdu_info_queue[pdcp_sn]; + uint32_t pdcp_sn = acked_segment.pdcp_sn(); + if (pdcp_sn == rlc_am_pdu_segment::invalid_pdcp_sn) { + logger.debug("ACKed segment in RLC_SN=%d already discarded in PDCP. No need to notify the PDCP.", rlc_sn); + continue; + } + pdcp_pdu_info& info = undelivered_sdu_info_queue[pdcp_sn]; // Remove RLC SN from PDCP PDU undelivered list info.ack_segment(acked_segment); diff --git a/lib/test/asn1/rrc_nr_utils_test.cc b/lib/test/asn1/rrc_nr_utils_test.cc index 2b767eb24..b58d1390b 100644 --- a/lib/test/asn1/rrc_nr_utils_test.cc +++ b/lib/test/asn1/rrc_nr_utils_test.cc @@ -495,7 +495,7 @@ int make_phy_dmrs_additional_pos_test() dmrs_ul_cfg.dmrs_add_position_present = true; dmrs_ul_cfg.dmrs_add_position = dmrs_ul_cfg_s::dmrs_add_position_opts::pos1; srsran_dmrs_sch_add_pos_t srsran_dmrs_sch_add_pos; - TESTASSERT(make_phy_dmrs_additional_pos(dmrs_ul_cfg, &srsran_dmrs_sch_add_pos) == true); + TESTASSERT(make_phy_dmrs_ul_additional_pos(dmrs_ul_cfg, &srsran_dmrs_sch_add_pos) == true); TESTASSERT(srsran_dmrs_sch_add_pos == srsran_dmrs_sch_add_pos_1); diff --git a/lib/test/phy/CMakeLists.txt b/lib/test/phy/CMakeLists.txt index 215e74025..cad583825 100644 --- a/lib/test/phy/CMakeLists.txt +++ b/lib/test/phy/CMakeLists.txt @@ -64,7 +64,11 @@ add_lte_test(pucch_ca_test pucch_ca_test) add_executable(phy_dl_nr_test phy_dl_nr_test.c) target_link_libraries(phy_dl_nr_test srsran_phy srsran_common srsran_phy ${SEC_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) -add_nr_test(phy_dl_nr_test phy_dl_nr_test -p 100 -m 28) +add_nr_test(phy_dl_nr_test phy_dl_nr_test -p 100 -m 28 ) add_nr_test(phy_dl_nr_test_rvd phy_dl_nr_test -P 52 -p 52 -m 0 -R 0 52 1 010010010010 00000000010000 - -R 0 52 1 100100100100 00000010000000) \ No newline at end of file + -R 0 52 1 100100100100 00000010000000) + +add_nr_test(phy_dl_nr_test_cfo_delay phy_dl_nr_test -P 52 -p 52 -m 27 -C 100.0 -D 4 -n 10) +add_nr_test(phy_dl_nr_test_52prb phy_dl_nr_test -P 52 -p 52 -m 27 -T 256qam -v -d 1 1 -n 10) +add_nr_test(phy_dl_nr_test_270prb phy_dl_nr_test -P 270 -p 270 -m 27 -T 256qam -v -d 1 1 -n 10) diff --git a/lib/test/phy/phy_dl_nr_test.c b/lib/test/phy/phy_dl_nr_test.c index 7e7611a8c..985993dad 100644 --- a/lib/test/phy/phy_dl_nr_test.c +++ b/lib/test/phy/phy_dl_nr_test.c @@ -39,22 +39,25 @@ static srsran_carrier_nr_t carrier = { 1 // max_mimo_layers }; -static uint32_t n_prb = 0; // Set to 0 for steering -static uint32_t mcs = 30; // Set to 30 for steering -static srsran_sch_cfg_nr_t pdsch_cfg = {}; -static uint32_t nof_slots = 10; -static uint32_t rv_idx = 0; -static uint32_t delay_n = 4; // Integer delay -static float cfo_hz = 100.0f; // CFO Hz +static uint32_t n_prb = 0; // Set to 0 for steering +static uint32_t mcs = 30; // Set to 30 for steering +static srsran_sch_cfg_nr_t pdsch_cfg = {}; +static uint32_t nof_slots = 10; +static uint32_t rv_idx = 0; +static uint32_t delay_n = 0; // Integer delay +static float cfo_hz = 0.0f; // CFO Hz +static srsran_dmrs_sch_type_t dmrs_type = srsran_dmrs_sch_type_1; +static srsran_dmrs_sch_add_pos_t dmrs_add_pos = srsran_dmrs_sch_add_pos_2; static void usage(char* prog) { - printf("Usage: %s [pTL] \n", prog); + printf("Usage: %s [rRPdpmnTLDCv] \n", prog); printf("\t-P Number of BWP (Carrier) PRB [Default %d]\n", carrier.nof_prb); printf("\t-p Number of grant PRB, set to 0 for steering [Default %d]\n", n_prb); printf("\t-n Number of slots to simulate [Default %d]\n", nof_slots); printf("\t-m MCS PRB, set to >28 for steering [Default %d]\n", mcs); printf("\t-r Redundancy version, set to >28 for steering [Default %d]\n", mcs); + printf("\t-d DMRS configuration [type 1-2] [add_pos 2-3] [CDM groups 1-3] [Default %d]\n", mcs); printf("\t-T Provide MCS table (64qam, 256qam, 64qamLowSE) [Default %s]\n", srsran_mcs_table_to_str(pdsch_cfg.sch_cfg.mcs_table)); printf("\t-R Reserve RE: [rb_begin] [rb_end] [rb_stride] [sc_mask] [symbol_mask]\n"); @@ -67,7 +70,7 @@ static void usage(char* prog) static int parse_args(int argc, char** argv) { int opt; - while ((opt = getopt(argc, argv, "rRPpmnTLDCv")) != -1) { + while ((opt = getopt(argc, argv, "rRPdpmnTLDCv")) != -1) { switch (opt) { case 'P': carrier.nof_prb = (uint32_t)strtol(argv[optind], NULL, 10); @@ -84,6 +87,30 @@ static int parse_args(int argc, char** argv) case 'r': rv_idx = (uint32_t)strtol(argv[optind], NULL, 10); break; + case 'd': + switch (strtol(argv[optind++], NULL, 10)) { + case 1: + dmrs_type = srsran_dmrs_sch_type_1; + break; + case 2: + dmrs_type = srsran_dmrs_sch_type_2; + break; + } + switch (strtol(argv[optind], NULL, 10)) { + case 0: + dmrs_add_pos = srsran_dmrs_sch_add_pos_0; + break; + case 1: + dmrs_add_pos = srsran_dmrs_sch_add_pos_1; + break; + case 2: + dmrs_add_pos = srsran_dmrs_sch_add_pos_2; + break; + case 3: + dmrs_add_pos = srsran_dmrs_sch_add_pos_3; + break; + } + break; case 'T': pdsch_cfg.sch_cfg.mcs_table = srsran_mcs_table_from_str(argv[optind]); break; @@ -211,7 +238,12 @@ int main(int argc, char** argv) cf_t* buffer_gnb[SRSRAN_MAX_PORTS] = {}; cf_t* buffer_ue[SRSRAN_MAX_PORTS] = {}; - uint32_t sf_len = SRSRAN_SF_LEN_PRB(carrier.nof_prb); + // Set default PDSCH configuration + if (parse_args(argc, argv) < SRSRAN_SUCCESS) { + goto clean_exit; + } + + uint32_t sf_len = SRSRAN_SF_LEN_PRB_NR(carrier.nof_prb); buffer_gnb[0] = srsran_vec_cf_malloc(sf_len); buffer_ue[0] = srsran_vec_cf_malloc(sf_len); if (buffer_gnb[0] == NULL || buffer_ue[0] == NULL) { @@ -219,14 +251,14 @@ int main(int argc, char** argv) goto clean_exit; } - srsran_ue_dl_nr_args_t ue_dl_args = {}; - ue_dl_args.nof_rx_antennas = 1; - ue_dl_args.pdsch.sch.disable_simd = false; - ue_dl_args.pdsch.sch.decoder_use_flooded = false; - ue_dl_args.pdsch.measure_evm = true; - ue_dl_args.pdcch.disable_simd = false; - ue_dl_args.pdcch.measure_evm = true; - ue_dl_args.nof_max_prb = carrier.nof_prb; + srsran_ue_dl_nr_args_t ue_dl_args = {}; + ue_dl_args.nof_rx_antennas = 1; + ue_dl_args.pdsch.sch.disable_simd = false; + ue_dl_args.pdsch.sch.decoder_use_flooded = false; + ue_dl_args.pdsch.measure_evm = true; + ue_dl_args.pdcch.disable_simd = false; + ue_dl_args.pdcch.measure_evm = true; + ue_dl_args.nof_max_prb = carrier.nof_prb; srsran_enb_dl_nr_args_t enb_dl_args = {}; enb_dl_args.nof_tx_antennas = 1; @@ -234,18 +266,12 @@ int main(int argc, char** argv) enb_dl_args.pdcch.disable_simd = false; enb_dl_args.nof_max_prb = carrier.nof_prb; - // Set default PDSCH configuration - pdsch_cfg.sch_cfg.mcs_table = srsran_mcs_table_64qam; - if (parse_args(argc, argv) < SRSRAN_SUCCESS) { - goto clean_exit; - } - srsran_pdcch_cfg_nr_t pdcch_cfg = {}; // Configure CORESET srsran_coreset_t* coreset = &pdcch_cfg.coreset[1]; pdcch_cfg.coreset_present[1] = true; - coreset->duration = 2; + coreset->duration = 1; for (uint32_t i = 0; i < SRSRAN_CORESET_FREQ_DOMAIN_RES_SIZE; i++) { coreset->freq_resources[i] = i < carrier.nof_prb / 6; } @@ -324,11 +350,11 @@ int main(int argc, char** argv) } // Use grant default A time resources with m=0 - pdsch_cfg.dmrs.typeA_pos = srsran_dmrs_sch_typeA_pos_2; - if (srsran_ra_dl_nr_time_default_A(0, pdsch_cfg.dmrs.typeA_pos, &pdsch_cfg.grant) < SRSRAN_SUCCESS) { - ERROR("Error loading default grant"); - goto clean_exit; - } + pdsch_cfg.dmrs.type = dmrs_type; + pdsch_cfg.dmrs.typeA_pos = srsran_dmrs_sch_typeA_pos_2; + pdsch_cfg.dmrs.additional_pos = dmrs_add_pos; + pdsch_cfg.grant.S = 1; + pdsch_cfg.grant.L = 13; pdsch_cfg.grant.nof_layers = carrier.max_mimo_layers; pdsch_cfg.grant.dci_format = srsran_dci_format_nr_1_0; pdsch_cfg.grant.nof_dmrs_cdm_groups_without_data = 1; @@ -380,12 +406,8 @@ int main(int argc, char** argv) // Compute PDCCH candidate locations uint32_t L = 1; uint32_t ncce_candidates[SRSRAN_SEARCH_SPACE_MAX_NOF_CANDIDATES_NR] = {}; - int nof_candidates = srsran_pdcch_nr_locations_coreset(coreset, - search_space, - pdsch_cfg.grant.rnti, - L, - SRSRAN_SLOT_NR_MOD(carrier.scs, slot.idx), - ncce_candidates); + int nof_candidates = srsran_pdcch_nr_locations_coreset( + coreset, search_space, pdsch_cfg.grant.rnti, L, SRSRAN_SLOT_NR_MOD(carrier.scs, slot.idx), ncce_candidates); if (nof_candidates < SRSRAN_SUCCESS) { ERROR("Error getting PDCCH candidates"); goto clean_exit; diff --git a/srsenb/src/stack/mac/mac.cc b/srsenb/src/stack/mac/mac.cc index f5a849b6d..79685d948 100644 --- a/srsenb/src/stack/mac/mac.cc +++ b/srsenb/src/stack/mac/mac.cc @@ -283,11 +283,13 @@ int mac::cell_cfg(const std::vector& cell_cfg_) void mac::get_metrics(mac_metrics_t& metrics) { srsran::rwlock_read_guard lock(rwlock); - int cnt = 0; - metrics.ues.resize(ue_db.size()); + metrics.ues.reserve(ue_db.size()); for (auto& u : ue_db) { - u.second->metrics_read(&metrics.ues[cnt]); - cnt++; + if (not scheduler.ue_exists(u.first)) { + continue; + } + metrics.ues.emplace_back(); + u.second->metrics_read(&metrics.ues.back()); } metrics.cc_rach_counter = detected_rachs; } diff --git a/srsue/src/phy/nr/cc_worker.cc b/srsue/src/phy/nr/cc_worker.cc index fbefd0578..f81a8f22a 100644 --- a/srsue/src/phy/nr/cc_worker.cc +++ b/srsue/src/phy/nr/cc_worker.cc @@ -152,8 +152,9 @@ void cc_worker::decode_pdcch_dl() if (logger.debug.enabled()) { for (uint32_t i = 0; i < ue_dl.pdcch_info_count; i++) { const srsran_ue_dl_nr_pdcch_info_t* info = &ue_dl.pdcch_info[i]; - logger.debug("PDCCH: rnti=0x%x, crst_id=%d, ss_type=%d, ncce=%d, al=%d, EPRE=%+.2f, RSRP=%+.2f, corr=%.3f; " + logger.debug("PDCCH: dci=%s, rnti=%x, crst_id=%d, ss_type=%d, ncce=%d, al=%d, EPRE=%+.2f, RSRP=%+.2f, corr=%.3f; " "nof_bits=%d; crc=%s;", + srsran_dci_format_nr_string(info->dci_ctx.format), info->dci_ctx.rnti, info->dci_ctx.coreset_id, info->dci_ctx.ss_type, @@ -361,8 +362,10 @@ bool cc_worker::work_ul() } } - // Add SR to UCI data if available - phy->get_pending_sr(ul_slot_cfg.idx, uci_data); + // 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); + } // Add CSI reports to UCI data if available phy->get_periodic_csi(ul_slot_cfg.idx, uci_data); diff --git a/srsue/src/stack/rrc/rrc_nr.cc b/srsue/src/stack/rrc/rrc_nr.cc index dfd69a7da..378585641 100644 --- a/srsue/src/stack/rrc/rrc_nr.cc +++ b/srsue/src/stack/rrc/rrc_nr.cc @@ -615,6 +615,31 @@ bool rrc_nr::apply_sp_cell_init_dl_pdcch(const asn1::rrc_nr::pdcch_cfg_s& pdcch_ bool rrc_nr::apply_sp_cell_init_dl_pdsch(const asn1::rrc_nr::pdsch_cfg_s& pdsch_cfg) { + if (pdsch_cfg.dmrs_dl_for_pdsch_map_type_a_present) { + if (pdsch_cfg.dmrs_dl_for_pdsch_map_type_a.type() == setup_release_c::types_opts::setup) { + srsran_dmrs_sch_add_pos_t srsran_dmrs_sch_add_pos; + if (make_phy_dmrs_dl_additional_pos(pdsch_cfg.dmrs_dl_for_pdsch_map_type_a.setup(), &srsran_dmrs_sch_add_pos) == + true) { + phy_cfg.pdsch.dmrs_typeA.additional_pos = srsran_dmrs_sch_add_pos; + phy_cfg.pdsch.dmrs_typeA.present = true; + } else { + logger.warning("Warning while build srsran_dmrs_sch_add_pos structure"); + return false; + } + } else { + logger.warning("Option dmrs_dl_for_pdsch_map_type_a not of type setup"); + return false; + } + } else { + logger.warning("Option dmrs_dl_for_pdsch_map_type_a not present"); + return false; + } + + srsran_resource_alloc_t resource_alloc; + if (make_phy_pdsch_alloc_type(pdsch_cfg, &resource_alloc) == true) { + phy_cfg.pdsch.alloc = resource_alloc; + } + if (pdsch_cfg.zp_csi_rs_res_to_add_mod_list_present) { for (uint32_t i = 0; i < pdsch_cfg.zp_csi_rs_res_to_add_mod_list.size(); i++) { srsran_csi_rs_zp_resource_t zp_csi_rs_resource; @@ -1000,10 +1025,15 @@ bool rrc_nr::apply_sp_cell_ded_ul_pucch(const asn1::rrc_nr::pucch_cfg_s& pucch_c bool rrc_nr::apply_sp_cell_ded_ul_pusch(const asn1::rrc_nr::pusch_cfg_s& pusch_cfg) { + srsran_resource_alloc_t resource_alloc; + if (make_phy_pusch_alloc_type(pusch_cfg, &resource_alloc) == true) { + phy_cfg.pusch.alloc = resource_alloc; + } + if (pusch_cfg.dmrs_ul_for_pusch_map_type_a_present) { if (pusch_cfg.dmrs_ul_for_pusch_map_type_a.type() == setup_release_c::types_opts::setup) { srsran_dmrs_sch_add_pos_t srsran_dmrs_sch_add_pos; - if (make_phy_dmrs_additional_pos(pusch_cfg.dmrs_ul_for_pusch_map_type_a.setup(), &srsran_dmrs_sch_add_pos) == + if (make_phy_dmrs_ul_additional_pos(pusch_cfg.dmrs_ul_for_pusch_map_type_a.setup(), &srsran_dmrs_sch_add_pos) == true) { phy_cfg.pusch.dmrs_typeA.additional_pos = srsran_dmrs_sch_add_pos; phy_cfg.pusch.dmrs_typeA.present = true;