From 93649429ddcb052f2482197bc6dcde83525b2a58 Mon Sep 17 00:00:00 2001 From: Joaquim Date: Tue, 26 Oct 2021 19:59:45 +0200 Subject: [PATCH] WIP: Fix Coverity issues in PHY lib (#3507) Fix several Coverity issues This commit adrresses the following code issues found by Coverity: CID 339785 Division by zero, in fading_channel_test.c CID 355272 Division by zero, in awgn_channel_test.c CID 355277 NULL ptr dereference, in awgn_channel_test.c CID 359663 NULL ptr dereference, in delay_channel_test.c CID 369544 NULL ptr dereference, in chest_dl_nbiot.c CID 373326 Resource Leak, in dft_fftw.c CID 373329 Resource Leak, in dft_fftw.c CID 372878 Division by zero, in sliv_test.c CID 372871 Division by zero, in dmrs_pdcch.c CID 370622 Negative loop bound, in csr_rs.c CID 370624 Negative loop bound, in csr_rs.c CID 370626 Negative loop bound, in csr_rs.c CID's 369568, 369594 NULL ptr dereference, in ch_awgn.c CID 369540 Logically dead code, in refsignal_dl.c CID 369608 Logically dead code, in refsignal_ul.c CIDs 366291, 366296, 366297 Out-of-bounds access, in zc_sequence.c CID 372209 Division by zero, in cqi.c CID 370992 Uninitialized pointer read, in pdcch_test.c CID 373334 Integer overflow, in ue_sync.h CID 370993, 370995 Undefined division, in pdcch_test.c CID 370994 Undefined division, in ssb_decode_test.c CIDs 353368 353364 353365 359673 353366 353367 Explicit null dereferenced, in psss_file_test.c CID 371865 Unchecked return value, in rf_uhd_imp.cc CID 363810 Undefined division, in ldpc_rm_chain_test.c CID 372209, 372211, 372213, 372216 Undefined modulo, in cqi.c CID 339834 Array compared against 0, in chest_dl.c CID 369589 Out of bounds access, in dmrs_pucch.c CID 371681 Out of bounds access, in ue_sync_nr_test.c CIDs 370761, 370825 Copy-paste error, in ssb.c CID 369599 out of bounds read, in dmrs_pdcch_test.c CID 363795 out of bounds read, in ldpc_dec_c_avx2_flood.c CID 363805 out of bounds read, in ldpc_dec_c_avx2long_flood.c CID 363821 out of bounds read, in ldpc_dec_c_flood.c --- lib/src/phy/ch_estimation/chest_dl.c | 20 +- lib/src/phy/ch_estimation/chest_dl_nbiot.c | 2 +- lib/src/phy/ch_estimation/csi_rs.c | 7 + lib/src/phy/ch_estimation/dmrs_pdcch.c | 5 + lib/src/phy/ch_estimation/dmrs_pucch.c | 8 +- lib/src/phy/ch_estimation/refsignal_dl.c | 23 +- lib/src/phy/ch_estimation/refsignal_ul.c | 6 +- .../phy/ch_estimation/test/dmrs_pdcch_test.c | 3 + lib/src/phy/channel/ch_awgn.c | 1 + lib/src/phy/channel/test/awgn_channel_test.c | 59 ++-- lib/src/phy/channel/test/delay_channel_test.c | 60 ++-- .../phy/channel/test/fading_channel_test.c | 35 ++- lib/src/phy/common/test/sliv_test.c | 35 ++- lib/src/phy/common/zc_sequence.c | 21 +- lib/src/phy/dft/dft_fftw.c | 4 + lib/src/phy/fec/ldpc/ldpc_dec_c_avx2_flood.c | 5 +- .../phy/fec/ldpc/ldpc_dec_c_avx2long_flood.c | 4 +- lib/src/phy/fec/ldpc/ldpc_dec_c_flood.c | 4 +- .../phy/fec/ldpc/test/ldpc_rm_chain_test.c | 282 ++++++++++++------ lib/src/phy/phch/cqi.c | 43 ++- lib/src/phy/phch/test/pdcch_test.c | 7 +- lib/src/phy/resampling/resample_arb.c | 1 + lib/src/phy/rf/rf_uhd_imp.cc | 4 +- lib/src/phy/sync/ssb.c | 4 +- lib/src/phy/sync/test/psss_file_test.c | 54 +++- lib/src/phy/sync/test/ssb_decode_test.c | 5 + lib/src/phy/ue/test/ue_sync_nr_test.c | 6 + lib/src/phy/ue/ue_sync.c | 2 +- 28 files changed, 481 insertions(+), 229 deletions(-) diff --git a/lib/src/phy/ch_estimation/chest_dl.c b/lib/src/phy/ch_estimation/chest_dl.c index 7bfa06c76..b10ab2f24 100644 --- a/lib/src/phy/ch_estimation/chest_dl.c +++ b/lib/src/phy/ch_estimation/chest_dl.c @@ -320,9 +320,9 @@ static float estimate_noise_pilots(srsran_chest_dl_t* q, srsran_dl_sf_cfg_t* sf, float sum_power = 0.0f; uint32_t count = 0; uint32_t npilots = (ch_mode == SRSRAN_SF_MBSFN) ? SRSRAN_REFSIGNAL_NUM_SF_MBSFN(q->cell.nof_prb, port_id) - : srsran_refsignal_cs_nof_re(&q->csr_refs, sf, port_id); - uint32_t nsymbols = (ch_mode == SRSRAN_SF_MBSFN) ? srsran_refsignal_mbsfn_nof_symbols() - : srsran_refsignal_cs_nof_symbols(&q->csr_refs, sf, port_id); + : srsran_refsignal_cs_nof_re(&q->csr_refs, sf, port_id); + uint32_t nsymbols = (ch_mode == SRSRAN_SF_MBSFN) ? srsran_refsignal_mbsfn_nof_symbols() + : srsran_refsignal_cs_nof_symbols(&q->csr_refs, sf, port_id); if (nsymbols == 0) { ERROR("Invalid number of CRS symbols\n"); return SRSRAN_ERROR; @@ -433,8 +433,8 @@ static void interpolate_pilots(srsran_chest_dl_t* q, uint32_t port_id) { /* interpolate the symbols with references in the freq domain */ - uint32_t nsymbols = (sf->sf_type == SRSRAN_SF_MBSFN) ? srsran_refsignal_mbsfn_nof_symbols() + 1 - : srsran_refsignal_cs_nof_symbols(&q->csr_refs, sf, port_id); + uint32_t nsymbols = (sf->sf_type == SRSRAN_SF_MBSFN) ? srsran_refsignal_mbsfn_nof_symbols() + 1 + : srsran_refsignal_cs_nof_symbols(&q->csr_refs, sf, port_id); uint32_t fidx_offset = 0; /* Interpolate in the frequency domain */ @@ -556,7 +556,7 @@ static void average_pilots(srsran_chest_dl_t* q, { uint32_t nsymbols = (sf->sf_type == SRSRAN_SF_MBSFN) ? srsran_refsignal_mbsfn_nof_symbols() : srsran_refsignal_cs_nof_symbols(&q->csr_refs, sf, port_id); - uint32_t nref = (sf->sf_type == SRSRAN_SF_MBSFN) ? 6 * q->cell.nof_prb : 2 * q->cell.nof_prb; + uint32_t nref = (sf->sf_type == SRSRAN_SF_MBSFN) ? 6 * q->cell.nof_prb : 2 * q->cell.nof_prb; // Average in the time domain if enabled if (cfg->estimator_alg == SRSRAN_ESTIMATOR_ALG_AVERAGE && nsymbols > 1) { @@ -967,12 +967,8 @@ static void fill_res(srsran_chest_dl_t* q, srsran_chest_dl_res_t* res) for (uint32_t port_id = 0; port_id < q->cell.nof_ports; port_id++) { res->rsrp_port_dbm[port_id] = srsran_convert_power_to_dBm(get_rsrp_port(q, port_id)); for (uint32_t a = 0; a < q->nof_rx_antennas; a++) { - if (q->noise_estimate[a]) { - res->snr_ant_port_db[a][port_id] = - srsran_convert_power_to_dB(q->rsrp[a][port_id] / q->noise_estimate[a][port_id]); - } else { - res->snr_ant_port_db[a][port_id] = 0.0f; - } + res->snr_ant_port_db[a][port_id] = + srsran_convert_power_to_dB(q->rsrp[a][port_id] / q->noise_estimate[a][port_id]); res->rsrp_ant_port_dbm[a][port_id] = srsran_convert_power_to_dBm(q->rsrp[a][port_id]); res->rsrq_ant_port_db[a][port_id] = srsran_convert_power_to_dB(q->cell.nof_prb * q->rsrp[a][port_id] / q->rssi[a][port_id]); diff --git a/lib/src/phy/ch_estimation/chest_dl_nbiot.c b/lib/src/phy/ch_estimation/chest_dl_nbiot.c index 87337f5b5..1da2e08be 100644 --- a/lib/src/phy/ch_estimation/chest_dl_nbiot.c +++ b/lib/src/phy/ch_estimation/chest_dl_nbiot.c @@ -80,7 +80,7 @@ int srsran_chest_dl_nbiot_init(srsran_chest_dl_nbiot_t* q, uint32_t max_prb) } clean_exit: - if (ret != SRSRAN_SUCCESS) { + if (ret != SRSRAN_SUCCESS && q != NULL) { srsran_chest_dl_nbiot_free(q); } return ret; diff --git a/lib/src/phy/ch_estimation/csi_rs.c b/lib/src/phy/ch_estimation/csi_rs.c index e6ea23c0c..a1194322d 100644 --- a/lib/src/phy/ch_estimation/csi_rs.c +++ b/lib/src/phy/ch_estimation/csi_rs.c @@ -760,6 +760,8 @@ int srsran_csi_rs_nzp_measure_trs(const srsran_carrier_nr_t* carrier, // Perform Measurements csi_rs_nzp_resource_measure_t measurements[SRSRAN_PHCH_CFG_MAX_NOF_CSI_RS_PER_SET]; int ret = csi_rs_nzp_measure_set(carrier, slot_cfg, set, grid, measurements); + + // Return to prevent assigning negative values to count if (ret < SRSRAN_SUCCESS) { ERROR("Error performing measurements"); return SRSRAN_ERROR; @@ -856,6 +858,8 @@ int srsran_csi_rs_nzp_measure_channel(const srsran_carrier_nr_t* carrier // Perform Measurements csi_rs_nzp_resource_measure_t measurements[SRSRAN_PHCH_CFG_MAX_NOF_CSI_RS_PER_SET]; int ret = csi_rs_nzp_measure_set(carrier, slot_cfg, set, grid, measurements); + + // Return to prevent assigning negative values to count if (ret < SRSRAN_SUCCESS) { ERROR("Error performing measurements"); return SRSRAN_ERROR; @@ -1032,8 +1036,11 @@ int srsran_csi_rs_zp_measure_channel(const srsran_carrier_nr_t* carrier, // Perform Measurements csi_rs_zp_resource_measure_t measurements[SRSRAN_PHCH_CFG_MAX_NOF_CSI_RS_PER_SET]; int ret = csi_rs_zp_measure_set(carrier, slot_cfg, set, grid, measurements); + + // Return to prevent assigning negative values to count if (ret < SRSRAN_SUCCESS) { ERROR("Error performing measurements"); + return SRSRAN_ERROR; } uint32_t count = (uint32_t)ret; diff --git a/lib/src/phy/ch_estimation/dmrs_pdcch.c b/lib/src/phy/ch_estimation/dmrs_pdcch.c index e594b10b0..3c862df2a 100644 --- a/lib/src/phy/ch_estimation/dmrs_pdcch.c +++ b/lib/src/phy/ch_estimation/dmrs_pdcch.c @@ -454,6 +454,11 @@ int srsran_dmrs_pdcch_get_measure(const srsran_dmrs_pdcch_estimator_t* q, srsran_vec_apply_cfo(tmp, tmp_sync_err, tmp, nof_pilots); #endif // DMRS_PDCCH_SYNC_PRECOMPENSATE_MEAS + // Prevent undefined division + if (!nof_pilots) { + ERROR("Error in DMRS correlation. nof_pilots cannot be zero"); + return SRSRAN_ERROR; + } // Correlate DMRS corr[l] = srsran_vec_acc_cc(tmp, nof_pilots) / (float)nof_pilots; diff --git a/lib/src/phy/ch_estimation/dmrs_pucch.c b/lib/src/phy/ch_estimation/dmrs_pucch.c index bbe046519..cc8dc5e11 100644 --- a/lib/src/phy/ch_estimation/dmrs_pucch.c +++ b/lib/src/phy/ch_estimation/dmrs_pucch.c @@ -14,6 +14,7 @@ #include "srsran/phy/common/sequence.h" #include "srsran/phy/utils/debug.h" #include "srsran/phy/utils/vector.h" +#include #include // Implements TS 38.211 table 6.4.1.3.1.1-1: Number of DM-RS symbols and the corresponding N_PUCCH... @@ -182,7 +183,11 @@ int srsran_dmrs_pucch_format1_estimate(const srsran_pucch_nr_t* q, return SRSRAN_ERROR; } - cf_t ce[SRSRAN_PUCCH_NR_FORMAT1_N_MAX][SRSRAN_NRE]; + cf_t ce[SRSRAN_PUCCH_NR_FORMAT1_N_MAX][SRSRAN_NRE]; + + // Prevent ce[m] overflow + assert(n_pucch <= SRSRAN_PUCCH_NR_FORMAT1_N_MAX); + uint32_t l_prime = resource->start_symbol_idx; for (uint32_t m = 0; m < n_pucch; m++) { // Clause 6.4.1.3.1.2 specifies l=0,2,4... @@ -213,6 +218,7 @@ int srsran_dmrs_pucch_format1_estimate(const srsran_pucch_nr_t* q, cf_t z[SRSRAN_NRE]; srsran_vec_sc_prod_ccc(r_uv, w_i_m, z, SRSRAN_NRE); + // TODO: can ce[m] overflow? // Calculate least square estimates for this symbol srsran_vec_prod_conj_ccc(slot_symbols_ptr, z, ce[m], SRSRAN_NRE); } diff --git a/lib/src/phy/ch_estimation/refsignal_dl.c b/lib/src/phy/ch_estimation/refsignal_dl.c index 559cfe7bd..74b8a2b25 100644 --- a/lib/src/phy/ch_estimation/refsignal_dl.c +++ b/lib/src/phy/ch_estimation/refsignal_dl.c @@ -27,7 +27,6 @@ */ int srsran_refsignal_cs_init(srsran_refsignal_t* q, uint32_t max_prb) { - int ret = SRSRAN_ERROR_INVALID_INPUTS; if (q != NULL) { @@ -56,7 +55,6 @@ free_and_exit: */ int srsran_refsignal_cs_set_cell(srsran_refsignal_t* q, srsran_cell_t cell) { - uint32_t c_init; uint32_t N_cp, mp; srsran_sequence_t seq; @@ -347,7 +345,6 @@ uint32_t srsran_refsignal_mbsfn_nof_symbols() inline uint32_t srsran_refsignal_mbsfn_fidx(uint32_t l) { - uint32_t ret = 0; if (l == 0) { ret = 0; @@ -447,21 +444,21 @@ free_and_exit: int srsran_refsignal_mbsfn_set_cell(srsran_refsignal_t* q, srsran_cell_t cell, uint16_t mbsfn_area_id) { + int ret = SRSRAN_SUCCESS; - int ret = SRSRAN_ERROR_INVALID_INPUTS; - q->cell = cell; + if (q == NULL) { + ret = SRSRAN_ERROR_INVALID_INPUTS; + goto exit; + } + q->cell = cell; q->mbsfn_area_id = mbsfn_area_id; - if (srsran_refsignal_mbsfn_gen_seq(q, q->cell, q->mbsfn_area_id)) { - goto free_and_exit; + if (srsran_refsignal_mbsfn_gen_seq(q, q->cell, q->mbsfn_area_id) < SRSRAN_SUCCESS) { + ret = SRSRAN_ERROR; + goto exit; } - ret = SRSRAN_SUCCESS; - -free_and_exit: - if (ret == SRSRAN_ERROR) { - srsran_refsignal_free(q); - } +exit: return ret; } diff --git a/lib/src/phy/ch_estimation/refsignal_ul.c b/lib/src/phy/ch_estimation/refsignal_ul.c index 6abcae8cc..8e5c826ae 100644 --- a/lib/src/phy/ch_estimation/refsignal_ul.c +++ b/lib/src/phy/ch_estimation/refsignal_ul.c @@ -724,14 +724,14 @@ int srsran_refsignal_srs_send_cs(uint32_t subframe_config, uint32_t sf_idx) } else { return 1; } - } else if (subframe_config == 14) { + } + // subframe_config == 14 + else { if (((sf_idx % tsfc) == 7) || ((sf_idx % tsfc) == 9)) { return 0; } else { return 1; } - } else { - return 0; } } else { return SRSRAN_ERROR_INVALID_INPUTS; diff --git a/lib/src/phy/ch_estimation/test/dmrs_pdcch_test.c b/lib/src/phy/ch_estimation/test/dmrs_pdcch_test.c index 10d419a41..b367ddd6e 100644 --- a/lib/src/phy/ch_estimation/test/dmrs_pdcch_test.c +++ b/lib/src/phy/ch_estimation/test/dmrs_pdcch_test.c @@ -78,6 +78,9 @@ static int run_test(srsran_dmrs_pdcch_estimator_t* estimator, TESTASSERT(nof_locations == search_space->nof_candidates[aggregation_level]); + // Prevent possible out of bounds read in locations + TESTASSERT(nof_locations <= SRSRAN_SEARCH_SPACE_MAX_NOF_CANDIDATES_NR); + for (uint32_t candidate = 0; candidate < nof_locations; candidate++) { dci_location.ncce = locations[candidate]; diff --git a/lib/src/phy/channel/ch_awgn.c b/lib/src/phy/channel/ch_awgn.c index 9ca580932..e50b8f396 100644 --- a/lib/src/phy/channel/ch_awgn.c +++ b/lib/src/phy/channel/ch_awgn.c @@ -70,6 +70,7 @@ int srsran_channel_awgn_init(srsran_channel_awgn_t* q, uint32_t seed) q->table_log = srsran_vec_f_malloc(AWGN_TABLE_ALLOC_SIZE); if (!q->table_cos || !q->table_log) { ERROR("Malloc"); + return SRSRAN_ERROR; } // Fill tables diff --git a/lib/src/phy/channel/test/awgn_channel_test.c b/lib/src/phy/channel/test/awgn_channel_test.c index 9ebd10c0c..36fdf3747 100644 --- a/lib/src/phy/channel/test/awgn_channel_test.c +++ b/lib/src/phy/channel/test/awgn_channel_test.c @@ -40,7 +40,7 @@ static void usage(char* prog) printf("\t-t tolerance: [Default %.3f]\n", tolerance); } -static void parse_args(int argc, char** argv) +static int parse_args(int argc, char** argv) { int opt; while ((opt = getopt(argc, argv, "nmMst")) != -1) { @@ -62,9 +62,10 @@ static void parse_args(int argc, char** argv) break; default: usage(argv[0]); - exit(-1); + return SRSRAN_ERROR; } } + return SRSRAN_SUCCESS; } int main(int argc, char** argv) @@ -75,8 +76,15 @@ int main(int argc, char** argv) uint64_t count_samples = 0; uint64_t count_us = 0; +#ifdef ENABLE_GUI + cf_t* fft_out = NULL; +#endif + // Parse arguments - parse_args(argc, argv); + if (parse_args(argc, argv) < SRSRAN_SUCCESS) { + ret = SRSRAN_ERROR; + goto clean_exit; + } // Initialise buffers input_buffer = srsran_vec_cf_malloc(nof_samples); @@ -85,6 +93,7 @@ int main(int argc, char** argv) if (!input_buffer || !output_buffer) { ERROR("Error: Allocating memory"); ret = SRSRAN_ERROR; + goto clean_exit; } // Initialise input @@ -104,24 +113,31 @@ int main(int argc, char** argv) plot_scatter_setTitle(&plot_fft, "IQ"); plot_scatter_addToWindowGrid(&plot_fft, (char*)"IQ", 1, 0); - cf_t* fft_out = srsran_vec_cf_malloc(nof_samples); - srsran_dft_plan_t fft = {}; + fft_out = srsran_vec_cf_malloc(nof_samples); + srsran_dft_plan_t fft = {}; if (srsran_dft_plan_c(&fft, nof_samples, SRSRAN_DFT_FORWARD)) { ERROR("Error: init DFT"); ret = SRSRAN_ERROR; + goto clean_exit; } #endif /* ENABLE_GUI */ // Initialise AWGN channel - if (ret == SRSRAN_SUCCESS) { - ret = srsran_channel_awgn_init(&awgn, 0); + if (srsran_channel_awgn_init(&awgn, 0) < SRSRAN_SUCCESS) { + ERROR("Error initialising AWGN channel"); + ret = SRSRAN_ERROR; + goto clean_exit; } float n0 = n0_min; while (!isnan(n0) && !isinf(n0) && n0 < n0_max) { struct timeval t[3] = {}; - srsran_channel_awgn_set_n0(&awgn, n0); + if (srsran_channel_awgn_set_n0(&awgn, n0) < SRSRAN_SUCCESS) { + ERROR("Error setting AWGN n0"); + ret = SRSRAN_ERROR; + goto clean_exit; + } // Run actual test gettimeofday(&t[1], NULL); @@ -166,13 +182,28 @@ int main(int argc, char** argv) n0 += n0_step; } - // Free + // Print result and exit + double msps = 0; + if (count_us) { + msps = (double)nof_samples / (double)count_us; + } else { + ERROR("Error in Msps calculation: undefined division"); + ret = SRSRAN_ERROR; + } + printf("Test n0_min=%.3f; n0_max=%.3f; n0_step=%.3f; nof_samples=%d; %s ... %.1f MSps\n", + n0_min, + n0_max, + n0_step, + nof_samples, + (ret == SRSRAN_SUCCESS) ? "Passed" : "Failed", + msps); + +clean_exit: srsran_channel_awgn_free(&awgn); if (input_buffer) { free(input_buffer); } - if (output_buffer) { free(output_buffer); } @@ -184,13 +215,5 @@ int main(int argc, char** argv) srsran_dft_plan_free(&fft); #endif /* ENABLE_GUI */ - // Print result and exit - printf("Test n0_min=%.3f; n0_max=%.3f; n0_step=%.3f; nof_samples=%d; %s ... %.1f MSps\n", - n0_min, - n0_max, - n0_step, - nof_samples, - (ret == SRSRAN_SUCCESS) ? "Passed" : "Failed", - (double)nof_samples / (double)count_us); return ret; } diff --git a/lib/src/phy/channel/test/delay_channel_test.c b/lib/src/phy/channel/test/delay_channel_test.c index 0920951a2..bbd3fe891 100644 --- a/lib/src/phy/channel/test/delay_channel_test.c +++ b/lib/src/phy/channel/test/delay_channel_test.c @@ -37,7 +37,7 @@ static void usage(char* prog) printf("\t-T Simulation Time in periods: [Default %d]\n", sim_time_periods); } -static void parse_args(int argc, char** argv) +static int parse_args(int argc, char** argv) { int opt; while ((opt = getopt(argc, argv, "mMtsT")) != -1) { @@ -59,14 +59,15 @@ static void parse_args(int argc, char** argv) break; default: usage(argv[0]); - exit(-1); + return SRSRAN_ERROR; } } + return SRSRAN_SUCCESS; } int main(int argc, char** argv) { - int ret = SRSRAN_SUCCESS; + int ret = SRSRAN_ERROR; cf_t* input_buffer = NULL; cf_t* output_buffer = NULL; srsran_timestamp_t ts = {}; // Initialised to zero @@ -74,28 +75,32 @@ int main(int argc, char** argv) struct timeval t[3] = {}; // Parse arguments - parse_args(argc, argv); + if (parse_args(argc, argv) < SRSRAN_SUCCESS) { + goto clean_exit; + } // Initialise buffers uint32_t size = srate_hz / 1000; input_buffer = srsran_vec_cf_malloc(size); output_buffer = srsran_vec_cf_malloc(size); if (!input_buffer || !output_buffer) { - fprintf(stderr, "Error: Allocating memory\n"); - ret = SRSRAN_ERROR; + ERROR("Error: Allocating memory"); + goto clean_exit; } // Generate random samples srsran_random_uniform_complex_dist_vector(random_gen, input_buffer, size, -1.0f, +1.0f); // Initialise delay channel - if (ret == SRSRAN_SUCCESS) { - ret = srsran_channel_delay_init(&delay, delay_min_us, delay_max_us, delay_period_s, delay_init_time_s, srate_hz); + if (srsran_channel_delay_init(&delay, delay_min_us, delay_max_us, delay_period_s, delay_init_time_s, srate_hz) < + SRSRAN_SUCCESS) { + ERROR("Error initialising delay channel"); + goto clean_exit; } // Run actual test gettimeofday(&t[1], NULL); - for (int i = 0; i < sim_time_periods && ret == SRSRAN_SUCCESS; i++) { + for (int i = 0; i < sim_time_periods; i++) { for (int j = 0; j < 1000 * delay_period_s; j++) { // Run delay channel srsran_channel_delay_execute(&delay, input_buffer, output_buffer, size, &ts); @@ -107,21 +112,17 @@ int main(int argc, char** argv) gettimeofday(&t[2], NULL); get_time_interval(t); - // Free - srsran_random_free(random_gen); - srsran_channel_delay_free(&delay); - - if (input_buffer) { - free(input_buffer); - } - - if (output_buffer) { - free(output_buffer); - } - uint64_t nof_samples = sim_time_periods * 1000 * delay_period_s * size; double elapsed_us = t[0].tv_sec * 1e6 + t[0].tv_usec; + double msps = 0; + if (isnormal(elapsed_us)) { + msps = (double)nof_samples / elapsed_us; + ret = SRSRAN_SUCCESS; + } else { + ERROR("Error in Msps calculation: undefined division"); + } + // Print result and exit printf("Test delay_min_us=%d; delay_max_us=%d; delay_period_s=%.1f; srate_hz=%d; periods=%d; %s ... %.1f MSps\n", delay_min_us, @@ -130,6 +131,19 @@ int main(int argc, char** argv) srate_hz, sim_time_periods, (ret == SRSRAN_SUCCESS) ? "Passed" : "Failed", - (double)nof_samples / elapsed_us); - exit(ret); + msps); + +clean_exit: + srsran_random_free(random_gen); + srsran_channel_delay_free(&delay); + + if (input_buffer) { + free(input_buffer); + } + + if (output_buffer) { + free(output_buffer); + } + + return (ret); } diff --git a/lib/src/phy/channel/test/fading_channel_test.c b/lib/src/phy/channel/test/fading_channel_test.c index afc0566e6..ecfbe83db 100644 --- a/lib/src/phy/channel/test/fading_channel_test.c +++ b/lib/src/phy/channel/test/fading_channel_test.c @@ -49,7 +49,7 @@ static void usage(char* prog) #endif /* ENABLE_GUI */ } -static void parse_args(int argc, char** argv) +static int parse_args(int argc, char** argv) { int opt; while ((opt = getopt(argc, argv, "mtsrg")) != -1) { @@ -73,9 +73,10 @@ static void parse_args(int argc, char** argv) break; default: usage(argv[0]); - exit(-1); + return SRSRAN_ERROR; } } + return SRSRAN_SUCCESS; } int main(int argc, char** argv) @@ -86,7 +87,16 @@ int main(int argc, char** argv) struct timeval t[3] = {}; uint64_t time_usec = 0; - parse_args(argc, argv); +#ifdef ENABLE_GUI + cf_t* fft_buffer = NULL; + float* fft_mag = NULL; + float* imp = NULL; +#endif + + // Parse arguments + if (parse_args(argc, argv) < SRSRAN_SUCCESS) { + goto clean_exit; + } srsran_dft_plan_t ifft; srsran_dft_plan_c(&ifft, srate / 1000, SRSRAN_DFT_BACKWARD); @@ -96,10 +106,7 @@ int main(int argc, char** argv) plot_real_t plot_h = NULL; plot_real_t plot_imp = NULL; - srsran_dft_plan_t fft = {}; - cf_t* fft_buffer = NULL; - float* fft_mag = NULL; - float* imp = NULL; + srsran_dft_plan_t fft = {}; if (enable_gui) { sdrgui_init(); @@ -207,15 +214,17 @@ int main(int argc, char** argv) #endif /* ENABLE_GUI */ } - ret = SRSRAN_SUCCESS; - -clean_exit: - if (ret) { - printf("Error\n"); + // Print results and exit + double msps = 0; + if (time_usec) { + msps = duration_ms * (srate / 1000.0) / (double)time_usec; + printf("Ok ... %.1f MSps\n", msps); + ret = SRSRAN_SUCCESS; } else { - printf("Ok ... %.1f MSps\n", duration_ms * (srate / 1000.0) / (double)time_usec); + printf("Error in Msps calculation: undefined division\n"); } +clean_exit: srsran_dft_plan_free(&ifft); #ifdef ENABLE_GUI diff --git a/lib/src/phy/common/test/sliv_test.c b/lib/src/phy/common/test/sliv_test.c index 6a42dadac..a75f3f294 100644 --- a/lib/src/phy/common/test/sliv_test.c +++ b/lib/src/phy/common/test/sliv_test.c @@ -11,6 +11,7 @@ */ #include "srsran/common/test_common.h" #include "srsran/phy/common/sliv.h" +#include #include #include #include @@ -38,34 +39,52 @@ static int test() int main(int argc, char** argv) { + int ret = SRSRAN_ERROR; + // Parse N if (argc >= 2) { N = (uint32_t)strtol(argv[1], NULL, 10); } + // No input arguments are provided + if (argc <= 1) { + ERROR("Error: too few arguments"); + } + // If two arguments, run brute force test - if (argc == 2) { - return test(); + else if (argc == 2) { + ret = test(); } // if three arguments, calculate start and length from sliv - if (argc == 3) { + else if (argc == 3) { uint32_t sliv = (uint32_t)strtol(argv[2], NULL, 10); uint32_t S = 0; uint32_t L = 0; - srsran_sliv_to_s_and_l(N, sliv, &S, &L); - printf("SLIV=%d; Start: %d; Length: %d;\n", sliv, S, L); - return SRSRAN_SUCCESS; + // check that N is not zero to prevent undefined division + if (N) { + srsran_sliv_to_s_and_l(N, sliv, &S, &L); + printf("SLIV=%d; Start: %d; Length: %d;\n", sliv, S, L); + ret = SRSRAN_SUCCESS; + } + else { + ERROR("Error: N cannot be 0 to prevent an undefined division"); + } } // if four arguments, calculate sliv from start and length - if (argc == 4) { + else if (argc == 4) { uint32_t s = (uint32_t)strtol(argv[2], NULL, 10); uint32_t l = (uint32_t)strtol(argv[3], NULL, 10); uint32_t sliv = srsran_sliv_from_s_and_l(N, s, l); printf("SLIV=%d; Start: %d; Length: %d;\n", sliv, s, l); - return SRSRAN_SUCCESS; + ret = SRSRAN_SUCCESS; + } + + else { + ERROR("Error: too many arguments"); } + return ret; } \ No newline at end of file diff --git a/lib/src/phy/common/zc_sequence.c b/lib/src/phy/common/zc_sequence.c index b860b9da2..0d8351b77 100644 --- a/lib/src/phy/common/zc_sequence.c +++ b/lib/src/phy/common/zc_sequence.c @@ -15,10 +15,13 @@ #include "srsran/phy/utils/debug.h" #include "srsran/phy/utils/primes.h" #include "srsran/phy/utils/vector.h" +#include #include +#define NOF_ZC_SEQ 30 + // Phi values for M_sc=12 Table 5.5.1.2-1 in TS 36.211 -static const float zc_sequence_lte_phi_M_sc_12[30][12] = { +static const float zc_sequence_lte_phi_M_sc_12[NOF_ZC_SEQ][12] = { {-1, 1, 3, -3, 3, 3, 1, 1, 3, 1, -3, 3}, {1, 1, 3, 3, 3, -1, 1, -3, -3, 1, -3, 3}, {1, 1, -3, -3, -3, -1, -3, -3, 1, -3, 1, -1}, {-1, 1, 1, 1, 1, -1, -3, -3, 1, -3, 3, -1}, {-1, 3, 1, -1, 1, -1, -3, -1, 1, -1, 1, 3}, {1, -3, 3, -1, -1, 1, 1, -1, -1, 3, -3, 1}, @@ -36,7 +39,7 @@ static const float zc_sequence_lte_phi_M_sc_12[30][12] = { {-1, 3, -3, 3, -1, 3, 3, -3, 3, 3, -1, -1}, {3, -3, -3, -1, -1, -3, -1, 3, -3, 3, 1, -1}}; // Phi values for M_sc=24 Table 5.5.1.2-2 in TS 36.211 -static const float zc_sequence_lte_phi_M_sc_24[30][24] = { +static const float zc_sequence_lte_phi_M_sc_24[NOF_ZC_SEQ][24] = { {-1, 3, 1, -3, 3, -1, 1, 3, -3, 3, 1, 3, -3, 3, 1, 1, -1, 1, 3, -3, 3, -3, -1, -3}, {-3, 3, -3, -3, -3, 1, -3, -3, 3, -1, 1, 1, 1, 3, 1, -1, 3, -3, -3, 1, 3, 1, 1, -3}, {3, -1, 3, 3, 1, 1, -3, 3, 3, 3, 3, 1, -1, 3, -1, 1, 1, -1, -3, -1, -1, 1, 3, 3}, @@ -69,7 +72,7 @@ static const float zc_sequence_lte_phi_M_sc_24[30][24] = { {1, 1, -1, -1, -3, -1, 3, -1, 3, -1, 1, 3, 1, -1, 3, 1, 3, -3, -3, 1, -1, -1, 1, 3}}; // Phi values for M_sc=12 Table 5.2.2.2-1 in TS 38.211 -static const float zc_sequence_nr_phi_M_sc_6[30][6] = { +static const float zc_sequence_nr_phi_M_sc_6[NOF_ZC_SEQ][6] = { {-3, -1, 3, 3, -1, -3}, {-3, 3, -1, -1, 3, -3}, {-3, -3, -3, 3, 1, -3}, {1, 1, 1, 3, -1, -3}, {1, 1, 1, -3, -1, 3}, {-3, 1, -1, -3, -3, -3}, {-3, 1, 3, -3, -3, -3}, {-3, -1, 1, -3, 1, -1}, {-3, -1, -3, 1, -3, -3}, {-3, -3, 1, -3, 3, -3}, {-3, 1, 3, 1, -3, -3}, {-3, -1, -3, 1, 1, -3}, @@ -80,7 +83,7 @@ static const float zc_sequence_nr_phi_M_sc_6[30][6] = { {1, 1, -1, 3, -3, -1}, {1, 1, -3, 1, -1, -1}}; // Phi values for M_sc=12 Table 5.2.2.2-2 in TS 38.211 -static const float zc_sequence_nr_phi_M_sc_12[30][12] = { +static const float zc_sequence_nr_phi_M_sc_12[NOF_ZC_SEQ][12] = { {-3, 1, -3, -3, -3, 3, -3, -1, 1, 1, 1, -3}, {-3, 3, 1, -3, 1, 3, -1, -1, 1, 3, 3, 3}, {-3, 3, 3, 1, -3, 3, -1, 1, 3, -3, 3, -3}, {-3, -3, -1, 3, 3, 3, -3, 3, -3, 1, -1, -3}, {-3, -1, -1, 1, 3, 1, 1, -1, 1, -1, -3, 1}, {-3, -3, 3, 1, -3, -3, -3, -1, 3, -1, 1, 3}, @@ -98,7 +101,7 @@ static const float zc_sequence_nr_phi_M_sc_12[30][12] = { {1, -1, 3, 1, 1, -1, -1, -1, 1, 3, -3, 1}, {-3, 3, -3, 3, -3, -3, 3, -1, -1, 1, 3, -3}}; // Phi values for M_sc=18 Table 5.2.2.2-3 in TS 38.211 -static const float zc_sequence_nr_phi_M_sc_18[30][18] = { +static const float zc_sequence_nr_phi_M_sc_18[NOF_ZC_SEQ][18] = { {-1, 3, -1, -3, 3, 1, -3, -1, 3, -3, -1, -1, 1, 1, 1, -1, -1, -1}, {3, -3, 3, -1, 1, 3, -3, -1, -3, -3, -1, -3, 3, 1, -1, 3, -3, 3}, {-3, 3, 1, -1, -1, 3, -3, -1, 1, 1, 1, 1, 1, -1, 3, -1, -3, -1}, @@ -131,7 +134,7 @@ static const float zc_sequence_nr_phi_M_sc_18[30][18] = { {-3, 3, 1, -1, -1, -1, -1, 1, -1, 3, 3, -3, -1, 1, 3, -1, 3, -1}}; // Phi values for M_sc=18 Table 5.2.2.2-3 in TS 38.211 -static const float zc_sequence_nr_phi_M_sc_24[30][24] = { +static const float zc_sequence_nr_phi_M_sc_24[NOF_ZC_SEQ][24] = { {-1, -3, 3, -1, 3, 1, 3, -1, 1, -3, -1, -3, -1, 1, 3, -3, -1, -3, 3, 3, 3, -3, -3, -3}, {-1, -3, 3, 1, 1, -3, 1, -3, -3, 1, -3, -1, -1, 3, -3, 3, 3, 3, -3, 1, 3, 3, -3, -3}, {-1, -3, -3, 1, -1, -1, -3, 1, 3, -1, -3, -1, -1, -3, 1, 1, 3, 1, -3, -1, -1, 3, -3, -3}, @@ -165,31 +168,37 @@ static const float zc_sequence_nr_phi_M_sc_24[30][24] = { static void zc_sequence_lte_r_uv_arg_1prb(uint32_t u, cf_t* tmp_arg) { + assert(u < NOF_ZC_SEQ); srsran_vec_sc_prod_fcc(zc_sequence_lte_phi_M_sc_12[u], M_PI_4, tmp_arg, SRSRAN_NRE); } static void zc_sequence_lte_r_uv_arg_2prb(uint32_t u, cf_t* tmp_arg) { + assert(u < NOF_ZC_SEQ); srsran_vec_sc_prod_fcc(zc_sequence_lte_phi_M_sc_24[u], M_PI_4, tmp_arg, 2 * SRSRAN_NRE); } static void zc_sequence_nr_r_uv_arg_0dot5prb(uint32_t u, cf_t* tmp_arg) { + assert(u < NOF_ZC_SEQ); srsran_vec_sc_prod_fcc(zc_sequence_nr_phi_M_sc_6[u], M_PI_4, tmp_arg, SRSRAN_NRE / 2); } static void zc_sequence_nr_r_uv_arg_1prb(uint32_t u, cf_t* tmp_arg) { + assert(u < NOF_ZC_SEQ); srsran_vec_sc_prod_fcc(zc_sequence_nr_phi_M_sc_12[u], M_PI_4, tmp_arg, SRSRAN_NRE); } static void zc_sequence_nr_r_uv_arg_1dot5prb(uint32_t u, cf_t* tmp_arg) { + assert(u < NOF_ZC_SEQ); srsran_vec_sc_prod_fcc(zc_sequence_nr_phi_M_sc_18[u], M_PI_4, tmp_arg, (3 * SRSRAN_NRE) / 2); } static void zc_sequence_nr_r_uv_arg_2prb(uint32_t u, cf_t* tmp_arg) { + assert(u < NOF_ZC_SEQ); srsran_vec_sc_prod_fcc(zc_sequence_nr_phi_M_sc_24[u], M_PI_4, tmp_arg, 2 * SRSRAN_NRE); } diff --git a/lib/src/phy/dft/dft_fftw.c b/lib/src/phy/dft/dft_fftw.c index c6e1a6f4e..6c57ff843 100644 --- a/lib/src/phy/dft/dft_fftw.c +++ b/lib/src/phy/dft/dft_fftw.c @@ -57,11 +57,13 @@ __attribute__((constructor)) static void srsran_dft_load() } if (lockf(fileno(fd), F_LOCK, 0) == -1) { perror("lockf()"); + fclose(fd); return; } fftwf_import_wisdom_from_file(fd); if (lockf(fileno(fd), F_ULOCK, 0) == -1) { perror("u-lockf()"); + fclose(fd); return; } fclose(fd); @@ -82,11 +84,13 @@ __attribute__((destructor)) void srsran_dft_exit() } if (lockf(fileno(fd), F_LOCK, 0) == -1) { perror("lockf()"); + fclose(fd); return; } fftwf_export_wisdom_to_file(fd); if (lockf(fileno(fd), F_ULOCK, 0) == -1) { perror("u-lockf()"); + fclose(fd); return; } fclose(fd); diff --git a/lib/src/phy/fec/ldpc/ldpc_dec_c_avx2_flood.c b/lib/src/phy/fec/ldpc/ldpc_dec_c_avx2_flood.c index 1fe7f24b1..d1bcd419b 100644 --- a/lib/src/phy/fec/ldpc/ldpc_dec_c_avx2_flood.c +++ b/lib/src/phy/fec/ldpc/ldpc_dec_c_avx2_flood.c @@ -380,9 +380,8 @@ int update_ldpc_soft_bits_c_avx2_flood(void* p, const int8_t (*these_var_indices for (i_layer = 0; i_layer < vp->bgM; i_layer++) { current_var_index = these_var_indices[i_layer][0]; - this_check_to_var = vp->check_to_var + i_layer * (vp->hrr + 1); - for (i = 0; (current_var_index != -1) && (i < MAX_CNCT); i++) { + for (i = 1; (current_var_index != -1) && (i < MAX_CNCT); i++) { i_bit_tmp_base = (current_var_index <= vp->hrr) ? current_var_index : vp->hrr; tmp_epi8 = _mm256_adds_epi8(this_check_to_var[i_bit_tmp_base], vp->soft_bits.v[current_var_index]); @@ -395,7 +394,7 @@ int update_ldpc_soft_bits_c_avx2_flood(void* p, const int8_t (*these_var_indices mask_epi8 = _mm256_cmpgt_epi8(neg_infty7_epi8, tmp_epi8); vp->soft_bits.v[current_var_index] = _mm256_blendv_epi8(tmp_epi8, neg_infty8_epi8, mask_epi8); - current_var_index = these_var_indices[i_layer][i + 1]; + current_var_index = these_var_indices[i_layer][i]; } } diff --git a/lib/src/phy/fec/ldpc/ldpc_dec_c_avx2long_flood.c b/lib/src/phy/fec/ldpc/ldpc_dec_c_avx2long_flood.c index 583f4865b..fca88ea75 100644 --- a/lib/src/phy/fec/ldpc/ldpc_dec_c_avx2long_flood.c +++ b/lib/src/phy/fec/ldpc/ldpc_dec_c_avx2long_flood.c @@ -434,7 +434,7 @@ int update_ldpc_soft_bits_c_avx2long_flood(void* p, const int8_t (*these_var_ind current_var_index = these_var_indices[i_layer][0]; this_check_to_var = vp->check_to_var + i_layer * (vp->hrr + 1) * vp->n_subnodes; - for (i = 0; (current_var_index != -1) && (i < MAX_CNCT); i++) { + for (i = 1; (current_var_index != -1) && (i < MAX_CNCT); i++) { current_var_index_subnode = current_var_index * vp->n_subnodes; for (j = 0; j < vp->n_subnodes; j++) { i_bit_tmp_base = (current_var_index <= vp->hrr) ? current_var_index : vp->hrr; @@ -450,7 +450,7 @@ int update_ldpc_soft_bits_c_avx2long_flood(void* p, const int8_t (*these_var_ind vp->soft_bits[current_var_index_subnode + j].v = _mm256_blendv_epi8(tmp_epi8, neg_infty8_epi8, mask_epi8); } - current_var_index = these_var_indices[i_layer][i + 1]; + current_var_index = these_var_indices[i_layer][i]; } } diff --git a/lib/src/phy/fec/ldpc/ldpc_dec_c_flood.c b/lib/src/phy/fec/ldpc/ldpc_dec_c_flood.c index dfdb31bd4..cd41d78b8 100644 --- a/lib/src/phy/fec/ldpc/ldpc_dec_c_flood.c +++ b/lib/src/phy/fec/ldpc/ldpc_dec_c_flood.c @@ -317,7 +317,7 @@ int update_ldpc_soft_bits_c_flood(void* p, const int8_t (*these_var_indices)[MAX for (i_layer = 0; i_layer < vp->bgM; i_layer++) { current_var_index = these_var_indices[i_layer][0]; this_check_to_var = vp->check_to_var + i_layer * (vp->hrrN + vp->ls); - for (i = 0; (current_var_index != -1) && (i < MAX_CNCT); i++) { + for (i = 1; (current_var_index != -1) && (i < MAX_CNCT); i++) { // recall that current_var_index depends on i! current_var_index_ext = current_var_index * vp->ls; for (j = 0; j < vp->ls; j++) { @@ -332,7 +332,7 @@ int update_ldpc_soft_bits_c_flood(void* p, const int8_t (*these_var_indices)[MAX } vp->soft_bits[i_bit] = (int8_t)tmp; } - current_var_index = these_var_indices[i_layer][i + 1]; + current_var_index = these_var_indices[i_layer][i]; } } diff --git a/lib/src/phy/fec/ldpc/test/ldpc_rm_chain_test.c b/lib/src/phy/fec/ldpc/test/ldpc_rm_chain_test.c index caabbb059..a6f19546c 100644 --- a/lib/src/phy/fec/ldpc/test/ldpc_rm_chain_test.c +++ b/lib/src/phy/fec/ldpc/test/ldpc_rm_chain_test.c @@ -60,7 +60,7 @@ static uint8_t rv = 0; /*!< \brief Redundancy version { static srsran_mod_t mod_type = SRSRAN_MOD_BPSK; /*!< \brief Modulation type: BPSK, QPSK, QAM16, QAM64, QAM256 = 4 */ static uint32_t Nref = 0; /*!< \brief Limited buffer size. */ static float snr = 0; /*!< \brief Signal-to-Noise Ratio [dB]. */ -static uint8_t rm_aware = 1; /*!< \brief Flag rate matching aware encoding/decoding (1 to enable). */ +static uint8_t rm_aware = 1; /*!< \brief Flag rate matching aware encoding/decoding (1 to enable). */ static int finalK = 0; /*!< \brief Number of uncoded bits (message length, including punctured and filler bits). */ static int finalN = 0; /*!< \brief Number of coded bits (codeword length). */ @@ -93,7 +93,7 @@ void usage(char* prog) /*! * \brief Parses the input line. */ -void parse_args(int argc, char** argv) +int parse_args(int argc, char** argv) { int opt = 0; while ((opt = getopt(argc, argv, "b:l:e:f:r:m:w:M:s:B:N:E:")) != -1) { @@ -136,21 +136,24 @@ void parse_args(int argc, char** argv) break; default: usage(argv[0]); - exit(-1); + return SRSRAN_ERROR; } } + return SRSRAN_SUCCESS; } /*! * \brief Prints decoder statistics. */ -void print_decoder(char* title, int n_batches, int n_errors, double elapsed_time); +int print_decoder(char* title, int n_batches, int n_errors, double elapsed_time); /*! * \brief Main test function. */ int main(int argc, char** argv) { + int ret = SRSRAN_ERROR; + uint8_t* messages_true = NULL; uint8_t* messages_sim_f = NULL; uint8_t* messages_sim_s = NULL; @@ -169,29 +172,68 @@ int main(int argc, char** argv) int16_t* symbols_s = NULL; // unrm_symbols int8_t* symbols_c = NULL; // unrm_symbols + // LDPC encoder + srsran_ldpc_encoder_t encoder = {}; + + // LDPC decoder (8 bit) + srsran_ldpc_decoder_t decoder_c = {}; + // LDPC decoder (8 bit, flooded) + srsran_ldpc_decoder_t decoder_c_flood = {}; + // LDPC decoder (16 bit) + srsran_ldpc_decoder_t decoder_s = {}; + // LDPC decoder (float) + srsran_ldpc_decoder_t decoder_f = {}; + +#ifdef LV_HAVE_AVX2 + // LDPC decoder (8 bit, AVX2 version) + srsran_ldpc_decoder_t decoder_avx = {}; + // LDPC decoder (8 bit, flooded scheduling, AVX2 version) + srsran_ldpc_decoder_t decoder_avx_flood = {}; + +#endif + +#ifdef LV_HAVE_AVX512 + // LDPC decoder (8 bit, AVX512 version) + srsran_ldpc_decoder_t decoder_avx512 = {}; + // LDPC decoder (8 bit, flooded scheduling, AVX512 version) + srsran_ldpc_decoder_t decoder_avx512_flood = {}; +#endif + + // LDPC rate Matcher + srsran_ldpc_rm_t rm_tx = {}; + // LDPC rate DeMatcher + srsran_ldpc_rm_t rm_rx = {}; + // LDPC rate DeMatcher (int16_t) + srsran_ldpc_rm_t rm_rx_s = {}; + // LDPC rate DeMatcher (int8_t) + srsran_ldpc_rm_t rm_rx_c = {}; + + // Create a random generator + srsran_random_t random_gen = NULL; + random_gen = srsran_random_init(0); + int i = 0; int j = 0; - parse_args(argc, argv); - - // create an LDPC encoder - srsran_ldpc_encoder_t encoder; + if (parse_args(argc, argv) < SRSRAN_SUCCESS) { + goto clean_exit; + } #ifdef LV_HAVE_AVX512 if (srsran_ldpc_encoder_init(&encoder, SRSRAN_LDPC_ENCODER_AVX512, base_graph, lift_size) != 0) { perror("encoder init"); - exit(-1); + goto clean_exit; } #else // no AVX512 #ifdef LV_HAVE_AVX2 if (srsran_ldpc_encoder_init(&encoder, SRSRAN_LDPC_ENCODER_AVX2, base_graph, lift_size) != 0) { perror("encoder init"); - exit(-1); + goto clean_exit; } -#else // no AVX2 +#else // no AVX2 if (srsran_ldpc_encoder_init(&encoder, SRSRAN_LDPC_ENCODER_C, base_graph, lift_size) != 0) { perror("encoder init"); - exit(-1); + goto clean_exit; } #endif // LV_HAVE_AVX2 #endif // LV_HAVE_AVX512 @@ -206,32 +248,28 @@ int main(int argc, char** argv) Nref = finalN; } - // create a LDPC rate Matcher - srsran_ldpc_rm_t rm_tx; + // Init the LDPC rate Matcher if (srsran_ldpc_rm_tx_init(&rm_tx) != 0) { perror("rate matcher init"); - exit(-1); + goto clean_exit; } - // create a LDPC rate DeMatcher - srsran_ldpc_rm_t rm_rx; + // Init LDPC rate DeMatcher if (srsran_ldpc_rm_rx_init_f(&rm_rx) != 0) { perror("rate dematcher init"); - exit(-1); + goto clean_exit; } - // create a LDPC rate DeMatcher (int16_t) - srsran_ldpc_rm_t rm_rx_s; + // Init LDPC rate DeMatcher (int16_t) if (srsran_ldpc_rm_rx_init_s(&rm_rx_s) != 0) { perror("rate dematcher init (int16_t)"); - exit(-1); + goto clean_exit; } - // create a LDPC rate DeMatcher (int8_t) - srsran_ldpc_rm_t rm_rx_c; + // Init LDPC rate DeMatcher (int8_t) if (srsran_ldpc_rm_rx_init_c(&rm_rx_c) != 0) { perror("rate dematcher init (int8_t)"); - exit(-1); + goto clean_exit; } // Create LDPC configuration arguments @@ -240,73 +278,62 @@ int main(int argc, char** argv) decoder_args.ls = lift_size; decoder_args.scaling_fctr = MS_SF; - // create an LDPC decoder (float) - srsran_ldpc_decoder_t decoder_f; + // Init the LDPC decoder (float) decoder_args.type = SRSRAN_LDPC_DECODER_F; if (srsran_ldpc_decoder_init(&decoder_f, &decoder_args) != 0) { perror("decoder init"); - exit(-1); + goto clean_exit; } - // create an LDPC decoder (16 bit) - srsran_ldpc_decoder_t decoder_s; + // Init the LDPC decoder (16 bit) decoder_args.type = SRSRAN_LDPC_DECODER_S; if (srsran_ldpc_decoder_init(&decoder_s, &decoder_args) != 0) { perror("decoder init (int16_t)"); - exit(-1); + goto clean_exit; } - // create an LDPC decoder (8 bit) - srsran_ldpc_decoder_t decoder_c; + // Init the LDPC decoder (8 bit) decoder_args.type = SRSRAN_LDPC_DECODER_C; if (srsran_ldpc_decoder_init(&decoder_c, &decoder_args) != 0) { perror("decoder init (int8_t)"); - exit(-1); + goto clean_exit; } - // create an LDPC decoder (8 bit, flooded) - srsran_ldpc_decoder_t decoder_c_flood; + // Init the LDPC decoder (8 bit, flooded) decoder_args.type = SRSRAN_LDPC_DECODER_C_FLOOD; if (srsran_ldpc_decoder_init(&decoder_c_flood, &decoder_args) != 0) { perror("decoder init"); - exit(-1); + goto clean_exit; } #ifdef LV_HAVE_AVX2 - // create an LDPC decoder (8 bit, AVX2 version) - srsran_ldpc_decoder_t decoder_avx; + // Init the LDPC decoder (8 bit, AVX2 version) decoder_args.type = SRSRAN_LDPC_DECODER_C_AVX2; if (srsran_ldpc_decoder_init(&decoder_avx, &decoder_args) != 0) { perror("decoder init"); - exit(-1); + goto clean_exit; } - // create an LDPC decoder (8 bit, flooded scheduling, AVX2 version) - srsran_ldpc_decoder_t decoder_avx_flood; + // Init the LDPC decoder (8 bit, flooded scheduling, AVX2 version) decoder_args.type = SRSRAN_LDPC_DECODER_C_AVX2_FLOOD; if (srsran_ldpc_decoder_init(&decoder_avx_flood, &decoder_args) != 0) { perror("decoder init"); - exit(-1); + goto clean_exit; } #endif // LV_HAVE_AVX2 #ifdef LV_HAVE_AVX512 - // create an LDPC decoder (8 bit, AVX2 version) - srsran_ldpc_decoder_t decoder_avx512; + // Init the LDPC decoder (8 bit, AVX512 version) decoder_args.type = SRSRAN_LDPC_DECODER_C_AVX512; if (srsran_ldpc_decoder_init(&decoder_avx512, &decoder_args) != 0) { perror("decoder init"); - exit(-1); + goto clean_exit; } - // create an LDPC decoder (8 bit, flooded scheduling, AVX512 version) - srsran_ldpc_decoder_t decoder_avx512_flood; + // Init LDPC decoder (8 bit, flooded scheduling, AVX512 version) decoder_args.type = SRSRAN_LDPC_DECODER_C_AVX512_FLOOD; if (srsran_ldpc_decoder_init(&decoder_avx512_flood, &decoder_args) != 0) { perror("decoder init"); - exit(-1); + goto clean_exit; } #endif // LV_HAVE_AVX512 - // create a random generator - srsran_random_t random_gen = srsran_random_init(0); - printf("Test LDPC chain:\n"); printf(" Base Graph -> BG%d\n", encoder.bg + 1); printf(" Lifting Size -> %d\n", encoder.ls); @@ -352,7 +379,7 @@ int main(int argc, char** argv) !messages_sim_avx512_flood || !codewords || !rm_codewords || !rm_symbols || !rm_symbols_s || !rm_symbols_c || !symbols || !symbols_s || !symbols_c) { perror("malloc"); - exit(-1); + goto clean_exit; } int i_bit = 0; @@ -479,7 +506,7 @@ int main(int argc, char** argv) rv, mod_type, Nref)) { - exit(-1); + goto clean_exit; } } @@ -519,7 +546,7 @@ int main(int argc, char** argv) rv, mod_type, Nref)) { - exit(-1); + goto clean_exit; } } @@ -559,7 +586,7 @@ int main(int argc, char** argv) rv, mod_type, Nref) < 0) { - exit(-1); + goto clean_exit; } } @@ -702,63 +729,120 @@ int main(int argc, char** argv) i_batch * batch_size * finalK / elapsed_time_enc, i_batch * batch_size * finalN / elapsed_time_enc); - print_decoder("FLOATING POINT", i_batch, n_error_words_f, elapsed_time_dec_f); - print_decoder("FIXED POINT (16 bits)", i_batch, n_error_words_s, elapsed_time_dec_s); - print_decoder("FIXED POINT (8 bits)", i_batch, n_error_words_c, elapsed_time_dec_c); - print_decoder("FIXED POINT (8 bits, flooded scheduling)", i_batch, n_error_words_c_flood, elapsed_time_dec_c_flood); + if (print_decoder("FLOATING POINT", i_batch, n_error_words_f, elapsed_time_dec_f) < SRSRAN_SUCCESS) { + goto clean_exit; + } + if (print_decoder("FIXED POINT (16 bits)", i_batch, n_error_words_s, elapsed_time_dec_s) < SRSRAN_SUCCESS) { + goto clean_exit; + } + if (print_decoder("FIXED POINT (8 bits)", i_batch, n_error_words_c, elapsed_time_dec_c) < SRSRAN_SUCCESS) { + goto clean_exit; + } + if (print_decoder( + "FIXED POINT (8 bits, flooded scheduling)", i_batch, n_error_words_c_flood, elapsed_time_dec_c_flood) < + SRSRAN_SUCCESS) { + goto clean_exit; + } #ifdef LV_HAVE_AVX2 - print_decoder("FIXED POINT (8 bits - AVX2)", i_batch, n_error_words_avx, elapsed_time_dec_avx); - print_decoder( - "FIXED POINT (8 bits, flooded scheduling - AVX2)", i_batch, n_error_words_avx_flood, elapsed_time_dec_avx_flood); + if (print_decoder("FIXED POINT (8 bits - AVX2)", i_batch, n_error_words_avx, elapsed_time_dec_avx) < SRSRAN_SUCCESS) { + goto clean_exit; + } + if (print_decoder("FIXED POINT (8 bits, flooded scheduling - AVX2)", + i_batch, + n_error_words_avx_flood, + elapsed_time_dec_avx_flood) < SRSRAN_SUCCESS) { + goto clean_exit; + } #endif // LV_HAVE_AVX2 #ifdef LV_HAVE_AVX512 - print_decoder("FIXED POINT (8 bits - AVX512)", i_batch, n_error_words_avx512, elapsed_time_dec_avx512); - print_decoder("FIXED POINT (8 bits, flooded scheduling - AVX512)", - i_batch, - n_error_words_avx512_flood, - elapsed_time_dec_avx512_flood); + if (print_decoder("FIXED POINT (8 bits - AVX512)", i_batch, n_error_words_avx512, elapsed_time_dec_avx512) < + SRSRAN_SUCCESS) { + goto clean_exit; + } + if (print_decoder("FIXED POINT (8 bits, flooded scheduling - AVX512)", + i_batch, + n_error_words_avx512_flood, + elapsed_time_dec_avx512_flood) < SRSRAN_SUCCESS) { + goto clean_exit; + } #endif // LV_HAVE_AVX512 if (n_error_words_s > 10 * n_error_words_f) { perror("16-bit performance too low!"); - exit(-1); + goto clean_exit; } if (n_error_words_c > 10 * n_error_words_f) { perror("8-bit performance too low!"); - exit(-1); + goto clean_exit; } #ifdef LV_HAVE_AVX512 if (n_error_words_avx512 != n_error_words_avx) { perror("The number of errors AVX512 and AVX2 differs !"); - exit(-1); + goto clean_exit; } if (n_error_words_avx512_flood != n_error_words_avx_flood) { perror("The number of errors of flooded AVX512 and AVX2 differs !"); - exit(-1); + goto clean_exit; } #endif // LV_HAVE_AVX512 printf("\nTest completed successfully!\n\n"); + ret = SRSRAN_SUCCESS; - free(symbols); - free(symbols_s); - free(symbols_c); - free(rm_symbols); - free(rm_symbols_s); - free(rm_symbols_c); - free(rm_codewords); - free(codewords); - free(messages_sim_avx); - free(messages_sim_avx_flood); - free(messages_sim_avx512); - free(messages_sim_avx512_flood); - free(messages_sim_c_flood); - free(messages_sim_c); - free(messages_sim_s); - free(messages_sim_f); - free(messages_true); +clean_exit: + if (symbols != NULL) { + free(symbols); + } + if (symbols_s != NULL) { + free(symbols_s); + } + if (symbols_c != NULL) { + free(symbols_c); + } + if (rm_symbols != NULL) { + free(rm_symbols); + } + if (rm_symbols_s != NULL) { + free(rm_symbols_s); + } + if (rm_symbols_c != NULL) { + free(rm_symbols_c); + } + if (rm_codewords != NULL) { + free(rm_codewords); + } + if (codewords != NULL) { + free(codewords); + } + if (messages_sim_avx != NULL) { + free(messages_sim_avx); + } + if (messages_sim_avx_flood != NULL) { + free(messages_sim_avx_flood); + } + if (messages_sim_avx512 != NULL) { + free(messages_sim_avx512); + } + if (messages_sim_avx512_flood != NULL) { + free(messages_sim_avx512_flood); + } + if (messages_sim_c_flood != NULL) { + free(messages_sim_c_flood); + } + if (messages_sim_c != NULL) { + free(messages_sim_c); + } + if (messages_sim_s != NULL) { + free(messages_sim_s); + } + if (messages_sim_f != NULL) { + free(messages_sim_f); + } + if (messages_true != NULL) { + free(messages_true); + } srsran_random_free(random_gen); #ifdef LV_HAVE_AVX2 srsran_ldpc_decoder_free(&decoder_avx); @@ -777,15 +861,23 @@ int main(int argc, char** argv) srsran_ldpc_rm_rx_free_f(&rm_rx); srsran_ldpc_rm_rx_free_s(&rm_rx_s); srsran_ldpc_rm_rx_free_c(&rm_rx_c); + + return ret; } -void print_decoder(char* title, int n_batches, int n_errors, double elapsed_time) +int print_decoder(char* title, int n_batches, int n_errors, double elapsed_time) { printf("\n**** %s ****", title); - printf("\nEstimated word error rate:\n %e (%d errors)\n", (double)n_errors / n_batches / batch_size, n_errors); - - printf("Estimated throughput decoder:\n %e word/s\n %e bit/s (information)\n %e bit/s (encoded)\n", - n_batches * batch_size / elapsed_time, - n_batches * batch_size * finalK / elapsed_time, - n_batches * batch_size * finalN / elapsed_time); + if (!isnormal(elapsed_time)) { + printf("\nError: elapsed time is not a valid number\n"); + return SRSRAN_ERROR; + } else { + printf("\nEstimated word error rate:\n %e (%d errors)\n", (double)n_errors / n_batches / batch_size, n_errors); + + printf("Estimated throughput decoder:\n %e word/s\n %e bit/s (information)\n %e bit/s (encoded)\n", + n_batches * batch_size / elapsed_time, + n_batches * batch_size * finalK / elapsed_time, + n_batches * batch_size * finalN / elapsed_time); + return SRSRAN_SUCCESS; + } } diff --git a/lib/src/phy/phch/cqi.c b/lib/src/phy/phch/cqi.c index e9732506d..da8043150 100644 --- a/lib/src/phy/phch/cqi.c +++ b/lib/src/phy/phch/cqi.c @@ -303,7 +303,7 @@ int srsran_cqi_value_tostring(srsran_cqi_cfg_t* cfg, srsran_cqi_value_t* value, ret = cqi_hl_subband_tostring(cfg, &value->subband_hl, buff, buff_len); break; default: - /* Do nothing */; + /* Do nothing */; } return ret; @@ -523,7 +523,8 @@ static bool ri_send(uint32_t I_cqi_pmi, uint32_t I_ri, uint32_t tti, bool is_fdd static int cqi_hl_get_subband_size(int nof_prb) { if (nof_prb < 7) { - return 0; + ERROR("Error: nof_prb is invalid (< 7)"); + return SRSRAN_ERROR; } else if (nof_prb <= 26) { return 4; } else if (nof_prb <= 63) { @@ -531,7 +532,8 @@ static int cqi_hl_get_subband_size(int nof_prb) } else if (nof_prb <= 110) { return 8; } else { - return -1; + ERROR("Error: nof_prb is invalid (> 110)"); + return SRSRAN_ERROR; } } @@ -541,7 +543,8 @@ static int cqi_hl_get_subband_size(int nof_prb) static int cqi_hl_get_bwp_J(int nof_prb) { if (nof_prb < 7) { - return 0; + ERROR("Error: nof_prb is not valid (< 7)"); + return SRSRAN_ERROR; } else if (nof_prb <= 10) { return 1; } else if (nof_prb <= 26) { @@ -551,7 +554,8 @@ static int cqi_hl_get_bwp_J(int nof_prb) } else if (nof_prb <= 110) { return 4; } else { - return -1; + ERROR("Error: nof_prb is not valid (> 110)"); + return SRSRAN_ERROR; } } @@ -559,12 +563,20 @@ static int cqi_hl_get_bwp_J(int nof_prb) */ static int cqi_sb_get_Nj(uint32_t j, uint32_t nof_prb) { - uint32_t J = cqi_hl_get_bwp_J(nof_prb); + // from Table 7.2.2-2 in TS 36.213 + int J = cqi_hl_get_bwp_J(nof_prb); + int K = cqi_hl_get_subband_size(nof_prb); + + // Catch the J and k errors, and prevent undefined modulo operations + if (J <= 0 || K <= 0) { + return 0; + } + if (J == 1) { - return (uint32_t)ceil((float)nof_prb / cqi_hl_get_subband_size(nof_prb)); + return (uint32_t)ceil((float)nof_prb / K); } else { // all bw parts have the same number of subbands except the last one - uint32_t Nj = (uint32_t)ceil((float)nof_prb / cqi_hl_get_subband_size(nof_prb) / J); + uint32_t Nj = (uint32_t)ceil((float)nof_prb / K / J); if (j < J - 1) { return Nj; } else { @@ -608,6 +620,13 @@ uint32_t cqi_sb_get_H(const srsran_cqi_report_cfg_t* cfg, uint32_t nof_prb) { uint32_t K = cfg->subband_wideband_ratio; uint32_t J = cqi_hl_get_bwp_J(nof_prb); + + // Catch the J errors + if (J <= 0) + { + return 0; + } + uint32_t H = J * K + 1; return H; } @@ -641,9 +660,15 @@ uint32_t srsran_cqi_periodic_sb_bw_part_idx(const srsran_cqi_report_cfg_t* cfg, } } + assert(N_p != 0); uint32_t x = ((tti - N_offset) / N_p) % H; if (x > 0) { - return (x - 1) % cqi_hl_get_bwp_J(nof_prb); + int J = cqi_hl_get_bwp_J(nof_prb); + // Catch the J errors and prevent undefined modulo operation + if (J <= 0) { + return 0; + } + return (x - 1) % J; } else { return 0; } diff --git a/lib/src/phy/phch/test/pdcch_test.c b/lib/src/phy/phch/test/pdcch_test.c index 37c1f21be..93838e0a3 100644 --- a/lib/src/phy/phch/test/pdcch_test.c +++ b/lib/src/phy/phch/test/pdcch_test.c @@ -317,6 +317,11 @@ static int test_case1() } } + if (!t_encode_count || !t_decode_count) { + ERROR("Error in test case 1: undefined division"); + return SRSRAN_ERROR; + } + printf("test_case_1 - format %s - passed - %.1f usec/encode; %.1f usec/llr; %.1f usec/decode; min_corr=%f; " "false_alarm_prob=%f;\n", srsran_dci_format_string(format), @@ -332,7 +337,7 @@ static int test_case1() int main(int argc, char** argv) { - srsran_regs_t regs; + srsran_regs_t regs = {}; int i; int ret = SRSRAN_ERROR; diff --git a/lib/src/phy/resampling/resample_arb.c b/lib/src/phy/resampling/resample_arb.c index 126f029f5..d159c2bc9 100644 --- a/lib/src/phy/resampling/resample_arb.c +++ b/lib/src/phy/resampling/resample_arb.c @@ -143,6 +143,7 @@ int srsran_resample_arb_compute(srsran_resample_arb_t* q, cf_t* input, cf_t* out filter_input, srsran_resample_arb_polyfilt[(idx + 1) % SRSRAN_RESAMPLE_ARB_N], SRSRAN_RESAMPLE_ARB_M); } + // TODO: this condition is never true if (idx == SRSRAN_RESAMPLE_ARB_N) { *output = res1; } else { diff --git a/lib/src/phy/rf/rf_uhd_imp.cc b/lib/src/phy/rf/rf_uhd_imp.cc index ea3aefb98..3111c07d1 100644 --- a/lib/src/phy/rf/rf_uhd_imp.cc +++ b/lib/src/phy/rf/rf_uhd_imp.cc @@ -1235,7 +1235,9 @@ void rf_uhd_get_time(void* h, time_t* secs, double* frac_secs) { rf_uhd_handler_t* handler = (rf_uhd_handler_t*)h; uhd::time_spec_t timespec; - handler->uhd->get_time_now(timespec); + if (handler->uhd->get_time_now(timespec) != UHD_ERROR_NONE) { + return; + } if (secs != nullptr) { *secs = timespec.get_full_secs(); } diff --git a/lib/src/phy/sync/ssb.c b/lib/src/phy/sync/ssb.c index 7ac2352a8..24e616db6 100644 --- a/lib/src/phy/sync/ssb.c +++ b/lib/src/phy/sync/ssb.c @@ -505,7 +505,7 @@ int srsran_ssb_set_cfg(srsran_ssb_t* q, const srsran_ssb_cfg_t* cfg) } if (!isnormal(q->cfg.beta_pbch_dmrs)) { - q->cfg.beta_pbch = SRSRAN_SSB_DEFAULT_BETA; + q->cfg.beta_pbch_dmrs = SRSRAN_SSB_DEFAULT_BETA; } return SRSRAN_SUCCESS; @@ -729,7 +729,7 @@ ssb_measure(srsran_ssb_t* q, const cf_t ssb_grid[SRSRAN_SSB_NOF_RE], uint32_t N_ if (epre_pss > rsrp_pss) { n0_pss = epre - rsrp_pss; } - if (epre_pss > rsrp_pss) { + if (epre_sss > rsrp_sss) { n0_sss = epre - rsrp_sss; } float n0 = (n0_pss + n0_sss) / 2.0f; diff --git a/lib/src/phy/sync/test/psss_file_test.c b/lib/src/phy/sync/test/psss_file_test.c index 7c33801da..02762e887 100644 --- a/lib/src/phy/sync/test/psss_file_test.c +++ b/lib/src/phy/sync/test/psss_file_test.c @@ -24,7 +24,7 @@ #include "srsran/phy/sync/ssss.h" #include "srsran/srsran.h" -char* input_file_name; +char* input_file_name; float frequency_offset = 0.0; float snr = 100.0; srsran_cp_t cp = SRSRAN_CP_NORM; @@ -98,27 +98,41 @@ void parse_args(int argc, char** argv) int main(int argc, char** argv) { + int ret = SRSRAN_ERROR; parse_args(argc, argv); srsran_use_standard_symbol_size(use_standard_lte_rates); + // Init buffers + cf_t* input_buffer = NULL; + cf_t* input_buffer_temp = NULL; + cf_t* sf_buffer = NULL; + + // Init PSSS + srsran_psss_t psss = {}; + if (srsran_psss_init(&psss, nof_prb, cp) < SRSRAN_SUCCESS) { + ERROR("Error initialising the PSSS"); + goto clean_exit; + } + if (!input_file_name || srsran_filesource_init(&fsrc, input_file_name, SRSRAN_COMPLEX_FLOAT_BIN)) { printf("Error opening file %s\n", input_file_name); - return SRSRAN_ERROR; + goto clean_exit; } - // alloc memory + // Allocate memory uint32_t sf_n_samples = SRSRAN_SF_LEN_PRB(nof_prb); printf("I/Q samples per subframe=%d\n", sf_n_samples); - uint32_t sf_n_re = SRSRAN_CP_NSYMB(SRSRAN_CP_NORM) * SRSRAN_NRE * 2 * nof_prb; - cf_t* sf_buffer = srsran_vec_cf_malloc(sf_n_re); + uint32_t sf_n_re = SRSRAN_CP_NSYMB(SRSRAN_CP_NORM) * SRSRAN_NRE * 2 * nof_prb; + sf_buffer = srsran_vec_cf_malloc(sf_n_re); - cf_t* input_buffer = srsran_vec_cf_malloc(sf_n_samples); - cf_t* input_buffer_temp = srsran_vec_cf_malloc(sf_n_samples); + input_buffer = srsran_vec_cf_malloc(sf_n_samples); + input_buffer_temp = srsran_vec_cf_malloc(sf_n_samples); - // init PSSS - srsran_psss_t psss = {}; - srsran_psss_init(&psss, nof_prb, cp); + if (input_buffer == NULL || input_buffer_temp == NULL || sf_buffer == NULL) { + ERROR("Error allocating buffers"); + goto clean_exit; + } struct timeval t[3]; gettimeofday(&t[1], NULL); @@ -135,7 +149,7 @@ int main(int argc, char** argv) break; } else if (samples_read != sf_n_samples) { printf("Could only read %d of %d requested samples\n", samples_read, sf_n_samples); - return SRSRAN_ERROR; + goto clean_exit; } // Find PSSS signal @@ -149,11 +163,21 @@ int main(int argc, char** argv) num_subframes++; } while (samples_read == sf_n_samples && num_subframes < max_subframes); + ret = (sync == SRSRAN_SUCCESS); + +clean_exit: srsran_filesource_free(&fsrc); srsran_psss_free(&psss); - free(input_buffer); - free(input_buffer_temp); - free(sf_buffer); - return (sync == SRSRAN_SUCCESS); + if (input_buffer != NULL) { + free(input_buffer); + } + if (input_buffer_temp != NULL) { + free(input_buffer_temp); + } + if (sf_buffer != NULL) { + free(sf_buffer); + } + + return ret; } diff --git a/lib/src/phy/sync/test/ssb_decode_test.c b/lib/src/phy/sync/test/ssb_decode_test.c index c82ff5046..c59982551 100644 --- a/lib/src/phy/sync/test/ssb_decode_test.c +++ b/lib/src/phy/sync/test/ssb_decode_test.c @@ -199,6 +199,11 @@ static int test_case_1(srsran_ssb_t* ssb) } } + if (!count) { + ERROR("Error in test case 1: undefined division"); + return SRSRAN_ERROR; + } + INFO("test_case_1 - %.1f usec/encode; %.1f usec/decode; %.1f usec/decode;", (double)t_encode_usec / (double)(count), (double)t_decode_usec / (double)(count), diff --git a/lib/src/phy/ue/test/ue_sync_nr_test.c b/lib/src/phy/ue/test/ue_sync_nr_test.c index 4022cb1d1..9b064d3b7 100644 --- a/lib/src/phy/ue/test/ue_sync_nr_test.c +++ b/lib/src/phy/ue/test/ue_sync_nr_test.c @@ -215,6 +215,12 @@ static int test_case_1(srsran_ue_sync_nr_t* ue_sync) { for (uint32_t sf_idx = 0; sf_idx < nof_sf; sf_idx++) { srsran_ue_sync_nr_outcome_t outcome = {}; + + // Prevent buffer overflow in srsran_ue_sync_nr_zerocopy + if (ue_sync->nof_rx_channels > 1) { + ERROR("Error configuring number of RX channels"); + return SRSRAN_ERROR; + } TESTASSERT(srsran_ue_sync_nr_zerocopy(ue_sync, &buffer, &outcome) == SRSRAN_SUCCESS); // Print outcome diff --git a/lib/src/phy/ue/ue_sync.c b/lib/src/phy/ue/ue_sync.c index 3cbd03790..020be7fa1 100644 --- a/lib/src/phy/ue/ue_sync.c +++ b/lib/src/phy/ue/ue_sync.c @@ -958,7 +958,7 @@ int srsran_ue_sync_run_find_gnss_mode(srsran_ue_sync_t* q, srsran_timestamp_sub(&ts_tmp, 0, 0.001); ///< account for samples that have already been rx'ed align_len = srsran_timestamp_uint64(&ts_tmp, q->sf_len * 1000); - if (align_len > q->sf_len * 1000) { + if (align_len > (uint64_t)q->sf_len * 1000) { ts_next_rx.full_secs++; ts_next_rx.frac_secs = 0.0; srsran_timestamp_copy(&ts_tmp, &ts_next_rx);