From ac22ab2c2c526053ed101805ef77ea01f29a3d8f Mon Sep 17 00:00:00 2001 From: Haoran Wan Date: Mon, 9 Sep 2024 20:34:54 -0400 Subject: [PATCH 01/15] add worker pool --- nrscope/config/config.yaml | 1 + nrscope/hdr/dci_decoder.h | 26 ++- nrscope/hdr/nrscope_def.h | 65 +++++-- nrscope/hdr/nrscope_worker.h | 82 ++++++++ nrscope/hdr/rach_decoder.h | 19 +- nrscope/hdr/radio_nr.h | 3 +- nrscope/hdr/sibs_decoder.h | 10 +- nrscope/hdr/task_scheduler.h | 187 +++++++++--------- nrscope/src/libs/dci_decoder.cc | 118 +++++++----- nrscope/src/libs/load_config.cc | 6 + nrscope/src/libs/nrscope_worker.cc | 112 +++++++++++ nrscope/src/libs/rach_decoder.cc | 59 +++--- nrscope/src/libs/radio_nr.cc | 70 +++++-- nrscope/src/libs/sibs_decoder.cc | 65 +++---- nrscope/src/libs/task_scheduler.cc | 297 +++++++++++++++++------------ 15 files changed, 750 insertions(+), 370 deletions(-) create mode 100644 nrscope/hdr/nrscope_worker.h create mode 100644 nrscope/src/libs/nrscope_worker.cc diff --git a/nrscope/config/config.yaml b/nrscope/config/config.yaml index 6f4255b8..e6e93763 100644 --- a/nrscope/config/config.yaml +++ b/nrscope/config/config.yaml @@ -12,6 +12,7 @@ usrp_setting_0: rf_log_level: "debug" nof_rnti_worker_groups: 1 nof_bwps: 2 + nof_workers: 4 log_name: "a.csv" #"/home/wanhr/Documents/data/nrscope/evaluation/coverage_amarisoft/dci_tx_50.csv" # x (0-10), y(0-8) coordinates google_dataset_id: "ngscope5g_dci_log_wanhr" diff --git a/nrscope/hdr/dci_decoder.h b/nrscope/hdr/dci_decoder.h index 3b0d21d6..119a3be3 100644 --- a/nrscope/hdr/dci_decoder.h +++ b/nrscope/hdr/dci_decoder.h @@ -55,13 +55,29 @@ class DCIDecoder{ ~DCIDecoder(); int dci_decoder_and_reception_init(srsran_ue_dl_nr_sratescs_info arg_scs_, - TaskSchedulerNRScope* task_scheduler_nrscope, - cf_t* input[SRSRAN_MAX_PORTS], - u_int8_t bwp_id); + srsran_carrier_nr_t* base_carrier_, + cell_search_result_t cell_, + srsran_coreset_t* coreset0_t_, + asn1::rrc_nr::sib1_s sib1_, + asn1::rrc_nr::cell_group_cfg_s master_cell_group_, + asn1::rrc_nr::rrc_setup_s rrc_setup_, + srsue::nr::cell_search::cfg_t srsran_searcher_cfg_t_, + u_int8_t bwp_id, + cf_t* input[SRSRAN_MAX_PORTS]); int decode_and_parse_dci_from_slot(srsran_slot_cfg_t* slot, - TaskSchedulerNRScope* task_scheduler_nrscope, - cf_t * raw_buffer); + bool rach_found, + bool dci_inited, + uint32_t nof_known_rntis, + uint32_t nof_rnti_worker_groups, + std::vector & sharded_results, + std::vector >& sharded_rntis, + std::vector& nof_sharded_rntis, + std::vector& known_rntis, + std::vector & dl_prb_rate, + std::vector & dl_prb_bits_rate, + std::vector & ul_prb_rate, + std::vector & ul_prb_bits_rate); // int dci_thread(TaskSchedulerNRScope* task_scheduler_nrscope); }; diff --git a/nrscope/hdr/nrscope_def.h b/nrscope/hdr/nrscope_def.h index e7aba751..79580f8a 100644 --- a/nrscope/hdr/nrscope_def.h +++ b/nrscope/hdr/nrscope_def.h @@ -163,18 +163,59 @@ typedef struct ScanLogNode_ ScanLogNode; uint32 pci; }; -struct sib1_task_element{ - srsran_ue_sync_nr_outcome_t outcome; - srsran_slot_cfg_t slot; -}; - -struct rach_task_element{ - -}; - -struct dci_task_element{ - -}; +typedef struct WorkState_ WorkState; + struct WorkState_{ + uint32_t nof_threads; + uint32_t nof_rnti_worker_groups; + uint8_t nof_bwps; + + uint32_t slot_sz; + + cell_searcher_args_t args_t; + cell_search_result_t cell; + srsue::nr::cell_search::ret_t cs_ret; + srsue::nr::cell_search::cfg_t srsran_searcher_cfg_t; + coreset0_args coreset0_args_t; + srsran_coreset_t coreset0_t; + + srsran_ue_dl_nr_sratescs_info arg_scs; + + asn1::rrc_nr::sib1_s sib1; + std::vector sibs; + std::vector found_sib; + + asn1::rrc_nr::rrc_setup_s rrc_setup; + asn1::rrc_nr::cell_group_cfg_s master_cell_group; + asn1::rrc_nr::rrc_recfg_s rrc_recfg; + + bool sib1_found; // SIB 1 decoded, we can start the RACH thread + bool rach_found; + + bool sibs_vec_inited; // Is the vector for other SIBs set according to SIB? + bool all_sibs_found; // All SIBs are decoded, we can stop the SIB thread from now. + + bool sib1_inited; // SIBsDecoder is initialized. + bool rach_inited; // RACHDecoder is initialized. + bool dci_inited; // DCIDecoder is initialized. + + uint32_t nof_known_rntis; + std::vector known_rntis; + + std::vector nof_sharded_rntis; + std::vector > sharded_rntis; + std::vector sharded_results; + uint32_t nof_threads; + uint32_t nof_rnti_worker_groups; + uint8_t nof_bwps; + + std::vector dl_prb_rate; + std::vector ul_prb_rate; + std::vector dl_prb_bits_rate; + std::vector ul_prb_bits_rate; + + uint32_t new_rnti_number; + std::vector new_rntis_found; + }; /** * @brief Function brought from phch_cfg_nr.c diff --git a/nrscope/hdr/nrscope_worker.h b/nrscope/hdr/nrscope_worker.h new file mode 100644 index 00000000..b5a9efae --- /dev/null +++ b/nrscope/hdr/nrscope_worker.h @@ -0,0 +1,82 @@ +#ifndef NRSCOPE_WORKER_H +#define NRSCOPE_WORKER_H + +#include "nrscope/hdr/nrscope_def.h" +#include "nrscope/hdr/rach_decoder.h" +#include "nrscope/hdr/sibs_decoder.h" +#include "nrscope/hdr/dci_decoder.h" + +namespace NRScopeTask{ + +class NRScopeWorker{ +public: + srsran::rf_buffer_t rf_buffer_t; + cf_t* rx_buffer; + + WorkState worker_state; + RachDecoder rach_decoder; + SIBsDecoder sibs_decoder; + std::vector > dci_decoders; + + // uint32_t nof_threads; + // uint32_t nof_rnti_worker_groups; + // uint8_t nof_bwps; + + /* Job indicator */ + sem_t smph_has_job; + + // bool sib1_inited; /* SIBsDecoder is initialized, set by task_scheduler. */ + // bool rach_inited; /* RACHDecoder is initialized, set by task_scheduler. */ + // bool dci_inited; /* DCIDecoder is initialized, set by task_scheduler. */ + + // /* Params for the sib decoder. */ + // bool sib1_found; + // bool sibs_vec_inited; + // bool all_sibs_found; + // std::vector found_sib; + // std::vector sibs; + // asn1::rrc_nr::sib1_s sib1; + + // /* Params for the rach decoder. */ + // bool rach_inited; + // asn1::rrc_nr::rrc_setup_s* rrc_setup; + // asn1::rrc_nr::cell_group_cfg_s* master_cell_group; + // bool rach_found; + // uint32_t new_rnti_number; + // std::vector new_rntis_found; + + // /* Params for the dci decoders */ + // bool dci_inited; + // uint32_t nof_known_rntis; + // uint32_t nof_rnti_worker_groups; + // std::vector sharded_results; + // std::vector > sharded_rntis; + // std::vector nof_sharded_rntis; + // std::vector known_rntis; + // std::vector dl_prb_rate; + // std::vector dl_prb_bits_rate; + // std::vector ul_prb_rate; + // std::vector ul_prb_bits_rate; + + srsran_slot_cfg_t slot; /* Current slot. */ + + NRScopeWorker(); + ~NRScopeWorker(); + + /* This is called right after entering the radio_nr.cc, + The cell's information is set to the worker, + so the worker can set its buffer.*/ + int InitWorker(WorkState task_scheduler_state); + + void StartWorker(); + int InitSIBDecoder(); + int InitRACHDecoder(); + int InitDCIDecoders(); + +private: + void Run(); +}; + +} + +#endif \ No newline at end of file diff --git a/nrscope/hdr/rach_decoder.h b/nrscope/hdr/rach_decoder.h index 11ea0ef9..43ac2cd2 100644 --- a/nrscope/hdr/rach_decoder.h +++ b/nrscope/hdr/rach_decoder.h @@ -50,15 +50,26 @@ class RachDecoder{ RachDecoder(); ~RachDecoder(); - int rach_decoder_init(TaskSchedulerNRScope* task_scheduler_nrscope); + int rach_decoder_init(asn1::rrc_nr::sib1_s sib1_, + srsran_carrier_nr_t base_carrier_); int rach_reception_init(srsran_ue_dl_nr_sratescs_info arg_scs_, - TaskSchedulerNRScope* task_scheduler_nrscope, + srsran_coreset_t* coreset0_t_, + srsran_carrier_nr_t* base_carrier_, + cell_search_result_t cell_, + double ssb_freq_hz_, + srsran_subcarrier_spacing_t ssb_scs_, + coreset0_args coreset0_args_t, cf_t* input[SRSRAN_MAX_PORTS]); int decode_and_parse_msg4_from_slot(srsran_slot_cfg_t* slot, - TaskSchedulerNRScope* task_scheduler_nrscope, - cf_t * raw_buffer); + bool sib1_found, + bool rach_inited, + asn1::rrc_nr::rrc_setup_s* rrc_setup, + asn1::rrc_nr::cell_group_cfg_s* master_cell_group, + bool* rach_found, + uint32_t* new_rnti_number, + std::vector& new_rntis_found); // int rach_thread(TaskSchedulerNRScope* task_scheduler_nrscope); }; diff --git a/nrscope/hdr/radio_nr.h b/nrscope/hdr/radio_nr.h index b37ba6b0..3537d380 100644 --- a/nrscope/hdr/radio_nr.h +++ b/nrscope/hdr/radio_nr.h @@ -60,7 +60,7 @@ class Radio{ srsran_ssb_cfg_t ssb_cfg; - TaskSchedulerNRScope task_scheduler_nrscope; + NRScopeTask::TaskSchedulerNRScope task_scheduler_nrscope; RachDecoder rach_decoder; // processing for uplink in rach SIBsDecoder sibs_decoder; HarqTracker harq_tracker; @@ -68,6 +68,7 @@ class Radio{ uint32_t nof_threads; uint32_t nof_rnti_worker_groups; uint8_t nof_bwps; + uint32_t nof_workers; std::vector > dci_decoders; // a better coordination between producer (fetch) and consumer (resample and decode) diff --git a/nrscope/hdr/sibs_decoder.h b/nrscope/hdr/sibs_decoder.h index 81988412..ce1cd2d6 100644 --- a/nrscope/hdr/sibs_decoder.h +++ b/nrscope/hdr/sibs_decoder.h @@ -51,8 +51,7 @@ class SIBsDecoder{ * @return SRSRAN_SUCCESS (0) if everything goes well. * SRSRAN_ERROR (-1) if something is wrong in the function. */ - int sib_decoder_and_reception_init(srsran_ue_dl_nr_sratescs_info arg_scs_, - TaskSchedulerNRScope* task_scheduler_nrscope, + int sib_decoder_and_reception_init(WorkState* state, cf_t* input[SRSRAN_MAX_PORTS]); /** @@ -66,8 +65,11 @@ class SIBsDecoder{ * SRSRAN_ERROR (-1) if something is wrong in the function. */ int decode_and_parse_sib1_from_slot(srsran_slot_cfg_t* slot, - TaskSchedulerNRScope* task_scheduler_nrscope, - cf_t * raw_buffer); + bool* sibs_vec_inited, + bool* all_sibs_found, + std::vector& found_sib, + std::vector& sibs, + asn1::rrc_nr::sib1_s* sib1_); // /** // * A function that represents the SIB thread for a producer-consumer threading design, diff --git a/nrscope/hdr/task_scheduler.h b/nrscope/hdr/task_scheduler.h index a7263ed2..7fb36c73 100644 --- a/nrscope/hdr/task_scheduler.h +++ b/nrscope/hdr/task_scheduler.h @@ -6,104 +6,101 @@ /* A class that stores some intermediate results and schedules the SIB, RACH and DCI loops. */ #include "nrscope/hdr/nrscope_def.h" +#include "nrscope/hdr/nrscope_worker.h" +namespace NRScopeTask{ class TaskSchedulerNRScope{ - public: - cell_searcher_args_t args_t; - cell_search_result_t cell; - srsue::nr::cell_search::ret_t cs_ret; - srsue::nr::cell_search::cfg_t srsran_searcher_cfg_t; - coreset0_args coreset0_args_t; - srsran_coreset_t coreset0_t; - - asn1::rrc_nr::sib1_s sib1; - std::vector sibs; - std::vector found_sib; - - asn1::rrc_nr::rrc_setup_s rrc_setup; - asn1::rrc_nr::cell_group_cfg_s master_cell_group; - - asn1::rrc_nr::rrc_recfg_s rrc_recfg; - // srsran::mac_rar_pdu_nr rar_pdu; // rar pdu - - bool sib1_found; // SIB 1 decoded, we can start the RACH thread - bool rach_found; - - bool sibs_vec_inited; // Is the vector for other SIBs set according to SIB? - bool all_sibs_found; // All SIBs are decoded, we can stop the SIB thread from now. - - bool sib1_inited; // SIBsDecoder is initialized. - bool rach_inited; // RACHDecoder is initialized. - bool dci_inited; // DCIDecoder is initialized. - - uint32_t nof_known_rntis; - std::vector known_rntis; - - std::vector nof_sharded_rntis; - std::vector > sharded_rntis; - std::vector sharded_results; - uint32_t nof_threads; - uint32_t nof_rnti_worker_groups; - uint8_t nof_bwps; - - std::vector dl_prb_rate; - std::vector ul_prb_rate; - std::vector dl_prb_bits_rate; - std::vector ul_prb_bits_rate; - - uint32_t new_rnti_number; - std::vector new_rntis_found; - - std::mutex lock; - - TaskSchedulerNRScope(); - ~TaskSchedulerNRScope(); - - int decode_mib(cell_searcher_args_t* args_t_, - srsue::nr::cell_search::ret_t* cs_ret_, - srsue::nr::cell_search::cfg_t* srsran_searcher_cfg_t, - float resample_ratio_, - uint32_t raw_srate_); - - int merge_results(); - - int update_known_rntis(); - - std::vector get_results(){ - return results; - } - - // per bwp DCI decoding result for current TTI - std::vector results; - - // resampler tools - float resample_ratio; - msresamp_crcf resampler; - float resampler_delay; - uint32_t temp_x_sz; - uint32_t temp_y_sz; - std::complex * temp_x; - std::complex * temp_y; - uint32_t pre_resampling_slot_sz; - - static int copy_c_to_cpp_complex_arr_and_zero_padding(cf_t* src, std::complex* dst, uint32_t sz1, uint32_t sz2) { - for (uint32_t i = 0; i < sz2; i++) { - // indeed copy right? https://en.cppreference.com/w/cpp/numeric/complex/operator%3D - dst[i] = i < sz1 ? src[i] : 0; - } - - return 0; - } - - static int copy_cpp_to_c_complex_arr(std::complex* src, cf_t* dst, uint32_t sz) { - for (uint32_t i = 0; i < sz; i++) { - // https://en.cppreference.com/w/cpp/numeric/complex - dst[i] = { src[i].real(), src[i].imag() }; - } - - return 0; - } +public: + /* Task scheduler stores all the latest global params that each worker + should sync with it each time the task is assigned. */ + // cell_searcher_args_t args_t; + // cell_search_result_t cell; + // srsue::nr::cell_search::ret_t cs_ret; + // srsue::nr::cell_search::cfg_t srsran_searcher_cfg_t; + // coreset0_args coreset0_args_t; + // srsran_coreset_t coreset0_t; + + // asn1::rrc_nr::sib1_s sib1; + // std::vector sibs; + // std::vector found_sib; + + // asn1::rrc_nr::rrc_setup_s rrc_setup; + // asn1::rrc_nr::cell_group_cfg_s master_cell_group; + // asn1::rrc_nr::rrc_recfg_s rrc_recfg; + + // bool sib1_found; // SIB 1 decoded, we can start the RACH thread + // bool rach_found; + + // bool sibs_vec_inited; // Is the vector for other SIBs set according to SIB? + // bool all_sibs_found; // All SIBs are decoded, we can stop the SIB thread from now. + + // bool sib1_inited; // SIBsDecoder is initialized. + // bool rach_inited; // RACHDecoder is initialized. + // bool dci_inited; // DCIDecoder is initialized. + + // uint32_t nof_known_rntis; + // std::vector known_rntis; + + // std::vector nof_sharded_rntis; + // std::vector > sharded_rntis; + // std::vector sharded_results; + // uint32_t nof_threads; + // uint32_t nof_rnti_worker_groups; + // uint8_t nof_bwps; + + // std::vector dl_prb_rate; + // std::vector ul_prb_rate; + // std::vector dl_prb_bits_rate; + // std::vector ul_prb_bits_rate; + + // uint32_t new_rnti_number; + // std::vector new_rntis_found; + WorkState task_scheduler_state; + uint32_t nof_workers; + + std::vector > workers; + + std::mutex lock; + + TaskSchedulerNRScope(); + ~TaskSchedulerNRScope(); + + /* Start the workers and the receiving result thread, called before the + radio reception. */ + int TaskSchedulerNRScope::InitandStart(int32_t nof_threads, + uint32_t nof_rnti_worker_groups, + uint8_t nof_bwps, + cell_searcher_args_t args_t, + uint32_t nof_workers_); + + int decode_mib(cell_searcher_args_t* args_t_, + srsue::nr::cell_search::ret_t* cs_ret_, + srsue::nr::cell_search::cfg_t* srsran_searcher_cfg_t, + float resample_ratio_, + uint32_t raw_srate_); + + int merge_results(); + + int update_known_rntis(); + + std::vector get_results(){ + return results; + } + + // per bwp DCI decoding result for current TTI + std::vector results; + + // resampler tools + float resample_ratio; + msresamp_crcf resampler; + float resampler_delay; + uint32_t temp_x_sz; + uint32_t temp_y_sz; + std::complex * temp_x; + std::complex * temp_y; + uint32_t pre_resampling_slot_sz; }; +} #endif \ No newline at end of file diff --git a/nrscope/src/libs/dci_decoder.cc b/nrscope/src/libs/dci_decoder.cc index 5296e42d..837eb52d 100644 --- a/nrscope/src/libs/dci_decoder.cc +++ b/nrscope/src/libs/dci_decoder.cc @@ -15,14 +15,20 @@ DCIDecoder::~DCIDecoder(){ } int DCIDecoder::dci_decoder_and_reception_init(srsran_ue_dl_nr_sratescs_info arg_scs_, - TaskSchedulerNRScope* task_scheduler_nrscope, - cf_t* input[SRSRAN_MAX_PORTS], - u_int8_t bwp_id){ + srsran_carrier_nr_t* base_carrier_, + cell_search_result_t cell_, + srsran_coreset_t* coreset0_t_, + asn1::rrc_nr::sib1_s sib1_, + asn1::rrc_nr::cell_group_cfg_s master_cell_group_, + asn1::rrc_nr::rrc_setup_s rrc_setup_, + srsue::nr::cell_search::cfg_t srsran_searcher_cfg_t_, + u_int8_t bwp_id, + cf_t* input[SRSRAN_MAX_PORTS]){ - memcpy(&base_carrier, &task_scheduler_nrscope->args_t.base_carrier, sizeof(srsran_carrier_nr_t)); + memcpy(&base_carrier, base_carrier_, sizeof(srsran_carrier_nr_t)); arg_scs = arg_scs_; - cell = task_scheduler_nrscope->cell; + cell = cell_; bwp_worker_id = bwp_id; @@ -34,10 +40,10 @@ int DCIDecoder::dci_decoder_and_reception_init(srsran_ue_dl_nr_sratescs_info arg ue_dl_args.pdcch.measure_evm = true; ue_dl_args.nof_max_prb = 275; - memcpy(&coreset0_t, &task_scheduler_nrscope->coreset0_t, sizeof(srsran_coreset_t)); - sib1 = task_scheduler_nrscope->sib1; - master_cell_group = task_scheduler_nrscope->master_cell_group; - rrc_setup = task_scheduler_nrscope->rrc_setup; + memcpy(&coreset0_t, coreset0_t_, sizeof(srsran_coreset_t)); + sib1 = sib1_; + master_cell_group = master_cell_group_; + rrc_setup = rrc_setup_; dci_cfg.bwp_dl_initial_bw = 275; dci_cfg.bwp_ul_initial_bw = 275; @@ -251,7 +257,7 @@ int DCIDecoder::dci_decoder_and_reception_init(srsran_ue_dl_nr_sratescs_info arg } // For FR1 offset_to_point_a uses prbs with 15kHz scs. - srsran_searcher_cfg_t = task_scheduler_nrscope->srsran_searcher_cfg_t; + srsran_searcher_cfg_t = srsran_searcher_cfg_t_; double pointA = srsran_searcher_cfg_t.ssb_freq_hz - (SRSRAN_SSB_BW_SUBC / 2) * cell.abs_ssb_scs - cell.k_ssb * SRSRAN_SUBC_SPACING_NR(srsran_subcarrier_spacing_15kHz) - sib1.serving_cell_cfg_common.dl_cfg_common.freq_info_dl.offset_to_point_a * @@ -723,51 +729,61 @@ int DCIDecoder::dci_decoder_and_reception_init(srsran_ue_dl_nr_sratescs_info arg int DCIDecoder::decode_and_parse_dci_from_slot(srsran_slot_cfg_t* slot, - TaskSchedulerNRScope* task_scheduler_nrscope, - cf_t * raw_buffer){ - if(!task_scheduler_nrscope->rach_found or !task_scheduler_nrscope->dci_inited){ + bool rach_found, + bool dci_inited, + uint32_t nof_known_rntis, + uint32_t nof_rnti_worker_groups, + std::vector & sharded_results, + std::vector >& sharded_rntis, + std::vector& nof_sharded_rntis, + std::vector& known_rntis, + std::vector & dl_prb_rate, + std::vector & dl_prb_bits_rate, + std::vector & ul_prb_rate, + std::vector & ul_prb_bits_rate){ + if(!rach_found or !dci_inited){ std::cout << "RACH not found or DCI decoder not initialized, quitting..." << std::endl; return SRSRAN_SUCCESS; } - uint32_t n_rntis = (uint32_t) ceil((float) task_scheduler_nrscope->nof_known_rntis / (float) task_scheduler_nrscope->nof_rnti_worker_groups); + uint32_t n_rntis = (uint32_t) ceil((float) nof_known_rntis / (float) nof_rnti_worker_groups); uint32_t rnti_s = rnti_worker_group_id * n_rntis; uint32_t rnti_e = rnti_worker_group_id * n_rntis + n_rntis; - if(rnti_s >= task_scheduler_nrscope->nof_known_rntis){ - std::cout << "DCI decoder " << dci_decoder_id << "|" << rnti_worker_group_id << " exits because it's excessive.." << std::endl; + if(rnti_s >= nof_known_rntis){ + // std::cout << "DCI decoder " << dci_decoder_id << "|" << rnti_worker_group_id << " exits because it's excessive.." << std::endl; return SRSRAN_SUCCESS; } - if(rnti_e > task_scheduler_nrscope->nof_known_rntis){ - rnti_e = task_scheduler_nrscope->nof_known_rntis; + if(rnti_e > nof_known_rntis){ + rnti_e = nof_known_rntis; n_rntis = rnti_e - rnti_s; } - std::cout << "DCI decoder " << dci_decoder_id << " processing: [" << rnti_s << ", " << rnti_e << ")" << std::endl; + std::cout << "DCI decoder " << dci_decoder_id + << " processing: [" << rnti_s << ", " << rnti_e << ")" << std::endl; DCIFeedback new_result; - task_scheduler_nrscope->sharded_results[dci_decoder_id] = new_result; - - task_scheduler_nrscope->sharded_results[dci_decoder_id].dl_grants.resize(n_rntis); - task_scheduler_nrscope->sharded_results[dci_decoder_id].ul_grants.resize(n_rntis); - task_scheduler_nrscope->sharded_results[dci_decoder_id].spare_dl_prbs.resize(n_rntis); - task_scheduler_nrscope->sharded_results[dci_decoder_id].spare_dl_tbs.resize(n_rntis); - task_scheduler_nrscope->sharded_results[dci_decoder_id].spare_dl_bits.resize(n_rntis); - task_scheduler_nrscope->sharded_results[dci_decoder_id].spare_ul_prbs.resize(n_rntis); - task_scheduler_nrscope->sharded_results[dci_decoder_id].spare_ul_tbs.resize(n_rntis); - task_scheduler_nrscope->sharded_results[dci_decoder_id].spare_ul_bits.resize(n_rntis); - task_scheduler_nrscope->sharded_results[dci_decoder_id].dl_dcis.resize(n_rntis); - task_scheduler_nrscope->sharded_results[dci_decoder_id].ul_dcis.resize(n_rntis); - - task_scheduler_nrscope->sharded_rntis[dci_decoder_id].resize(n_rntis); - task_scheduler_nrscope->nof_sharded_rntis[dci_decoder_id] = n_rntis; - // std::cout << "task_scheduler_nrscope->nof_sharded_rntis[dci_decoder_id]: " << task_scheduler_nrscope->nof_sharded_rntis[dci_decoder_id] << std::endl; + sharded_results[dci_decoder_id] = new_result; + sharded_results[dci_decoder_id].dl_grants.resize(n_rntis); + sharded_results[dci_decoder_id].ul_grants.resize(n_rntis); + sharded_results[dci_decoder_id].spare_dl_prbs.resize(n_rntis); + sharded_results[dci_decoder_id].spare_dl_tbs.resize(n_rntis); + sharded_results[dci_decoder_id].spare_dl_bits.resize(n_rntis); + sharded_results[dci_decoder_id].spare_ul_prbs.resize(n_rntis); + sharded_results[dci_decoder_id].spare_ul_tbs.resize(n_rntis); + sharded_results[dci_decoder_id].spare_ul_bits.resize(n_rntis); + sharded_results[dci_decoder_id].dl_dcis.resize(n_rntis); + sharded_results[dci_decoder_id].ul_dcis.resize(n_rntis); + + sharded_rntis[dci_decoder_id].resize(n_rntis); + nof_sharded_rntis[dci_decoder_id] = n_rntis; + // std::cout << "nof_sharded_rntis[dci_decoder_id]: " << nof_sharded_rntis[dci_decoder_id] << std::endl; // std::cout << "sharded_rntis: "; for(uint32_t i = 0; i < n_rntis; i++){ - task_scheduler_nrscope->sharded_rntis[dci_decoder_id][i] = task_scheduler_nrscope->known_rntis[rnti_s + i]; - // std::cout << task_scheduler_nrscope->sharded_rntis[dci_decoder_id][i] << ", "; + sharded_rntis[dci_decoder_id][i] = known_rntis[rnti_s + i]; + // std::cout << sharded_rntis[dci_decoder_id][i] << ", "; } // std::cout << std::endl; @@ -787,14 +803,14 @@ int DCIDecoder::decode_and_parse_dci_from_slot(srsran_slot_cfg_t* slot, memcpy(ue_dl_tmp, &ue_dl_dci, sizeof(srsran_ue_dl_nr_t)); memcpy(slot_tmp, slot, sizeof(srsran_slot_cfg_t)); - int nof_dl_dci = srsran_ue_dl_nr_find_dl_dci_nrscope_dciloop(ue_dl_tmp, slot_tmp, task_scheduler_nrscope->sharded_rntis[dci_decoder_id][rnti_idx], + int nof_dl_dci = srsran_ue_dl_nr_find_dl_dci_nrscope_dciloop(ue_dl_tmp, slot_tmp, sharded_rntis[dci_decoder_id][rnti_idx], srsran_rnti_type_c, dci_dl_tmp, 4); if (nof_dl_dci < SRSRAN_SUCCESS) { ERROR("Error in blind search"); } - int nof_ul_dci = srsran_ue_dl_nr_find_ul_dci(ue_dl_tmp, slot_tmp, task_scheduler_nrscope->sharded_rntis[dci_decoder_id][rnti_idx], srsran_rnti_type_c, dci_ul_tmp, 4); + int nof_ul_dci = srsran_ue_dl_nr_find_ul_dci(ue_dl_tmp, slot_tmp, sharded_rntis[dci_decoder_id][rnti_idx], srsran_rnti_type_c, dci_ul_tmp, 4); if(nof_dl_dci > 0){ dci_dl[rnti_idx] = dci_dl_tmp[0]; @@ -810,8 +826,8 @@ int DCIDecoder::decode_and_parse_dci_from_slot(srsran_slot_cfg_t* slot, if(total_dl_dci > 0){ for (uint32_t dci_idx_dl = 0; dci_idx_dl < n_rntis; dci_idx_dl++){ // the rnti will not be copied if no dci found - if(dci_dl[dci_idx_dl].ctx.rnti == task_scheduler_nrscope->sharded_rntis[dci_decoder_id][dci_idx_dl]){ - task_scheduler_nrscope->sharded_results[dci_decoder_id].dl_dcis[dci_idx_dl] = dci_dl[dci_idx_dl]; + if(dci_dl[dci_idx_dl].ctx.rnti == sharded_rntis[dci_decoder_id][dci_idx_dl]){ + sharded_results[dci_decoder_id].dl_dcis[dci_idx_dl] = dci_dl[dci_idx_dl]; char str[1024] = {}; srsran_dci_dl_nr_to_str(&(ue_dl_dci.dci), &dci_dl[dci_idx_dl], str, (uint32_t)sizeof(str)); printf("DCIDecoder -- Found DCI: %s\n", str); @@ -830,12 +846,12 @@ int DCIDecoder::decode_and_parse_dci_from_slot(srsran_slot_cfg_t* slot, srsran_sch_cfg_nr_info(&pdsch_cfg, str, (uint32_t)sizeof(str)); printf("DCIDecoder -- PDSCH_cfg:\n%s", str); - task_scheduler_nrscope->sharded_results[dci_decoder_id].dl_grants[dci_idx_dl] = pdsch_cfg; - task_scheduler_nrscope->sharded_results[dci_decoder_id].nof_dl_used_prbs += pdsch_cfg.grant.nof_prb * pdsch_cfg.grant.L; + sharded_results[dci_decoder_id].dl_grants[dci_idx_dl] = pdsch_cfg; + sharded_results[dci_decoder_id].nof_dl_used_prbs += pdsch_cfg.grant.nof_prb * pdsch_cfg.grant.L; - task_scheduler_nrscope->dl_prb_rate[dci_idx_dl+rnti_s] = (float)(pdsch_cfg.grant.tb[0].tbs + + dl_prb_rate[dci_idx_dl+rnti_s] = (float)(pdsch_cfg.grant.tb[0].tbs + pdsch_cfg.grant.tb[1].tbs) / (float)pdsch_cfg.grant.nof_prb / (float)pdsch_cfg.grant.L; - task_scheduler_nrscope->dl_prb_bits_rate[dci_idx_dl+rnti_s] = (float)(pdsch_cfg.grant.tb[0].nof_bits + + dl_prb_bits_rate[dci_idx_dl+rnti_s] = (float)(pdsch_cfg.grant.tb[0].nof_bits + pdsch_cfg.grant.tb[1].nof_bits) / (float)pdsch_cfg.grant.nof_prb / (float)pdsch_cfg.grant.L; } } @@ -860,8 +876,8 @@ int DCIDecoder::decode_and_parse_dci_from_slot(srsran_slot_cfg_t* slot, if(total_ul_dci > 0){ for (uint32_t dci_idx_ul = 0; dci_idx_ul < n_rntis; dci_idx_ul++){ - if(dci_ul[dci_idx_ul].ctx.rnti == task_scheduler_nrscope->sharded_rntis[dci_decoder_id][dci_idx_ul]){ - task_scheduler_nrscope->sharded_results[dci_decoder_id].ul_dcis[dci_idx_ul] = dci_ul[dci_idx_ul]; + if(dci_ul[dci_idx_ul].ctx.rnti == sharded_rntis[dci_decoder_id][dci_idx_ul]){ + sharded_results[dci_decoder_id].ul_dcis[dci_idx_ul] = dci_ul[dci_idx_ul]; char str[1024] = {}; srsran_dci_ul_nr_to_str(&(ue_dl_dci.dci), &dci_ul[dci_idx_ul], str, (uint32_t)sizeof(str)); printf("DCIDecoder -- Found DCI: %s\n", str); @@ -877,12 +893,12 @@ int DCIDecoder::decode_and_parse_dci_from_slot(srsran_slot_cfg_t* slot, srsran_sch_cfg_nr_info(&pusch_cfg, str, (uint32_t)sizeof(str)); printf("DCIDecoder -- PUSCH_cfg:\n%s", str); - task_scheduler_nrscope->sharded_results[dci_decoder_id].ul_grants[dci_idx_ul] = pusch_cfg; - task_scheduler_nrscope->sharded_results[dci_decoder_id].nof_ul_used_prbs += pusch_cfg.grant.nof_prb * pusch_cfg.grant.L; + sharded_results[dci_decoder_id].ul_grants[dci_idx_ul] = pusch_cfg; + sharded_results[dci_decoder_id].nof_ul_used_prbs += pusch_cfg.grant.nof_prb * pusch_cfg.grant.L; - task_scheduler_nrscope->ul_prb_rate[dci_idx_ul+rnti_s] = (float)(pusch_cfg.grant.tb[0].tbs + + ul_prb_rate[dci_idx_ul+rnti_s] = (float)(pusch_cfg.grant.tb[0].tbs + pusch_cfg.grant.tb[1].tbs) / (float)pusch_cfg.grant.nof_prb / (float)pusch_cfg.grant.L; - task_scheduler_nrscope->ul_prb_bits_rate[dci_idx_ul+rnti_s] = (float)(pusch_cfg.grant.tb[0].nof_bits + + ul_prb_bits_rate[dci_idx_ul+rnti_s] = (float)(pusch_cfg.grant.tb[0].nof_bits + pusch_cfg.grant.tb[1].nof_bits) / (float)pusch_cfg.grant.nof_prb / (float)pusch_cfg.grant.L; } } diff --git a/nrscope/src/libs/load_config.cc b/nrscope/src/libs/load_config.cc index dcb1a592..dfdca9a3 100644 --- a/nrscope/src/libs/load_config.cc +++ b/nrscope/src/libs/load_config.cc @@ -143,6 +143,12 @@ int load_config(std::vector& radios, std::string file_name){ radios[i].nof_bwps = 1; } + if(config_yaml[setting_name]["nof_workers"]){ + radios[i].nof_workers = config_yaml[setting_name]["nof_workers"].as(); + }else{ + radios[i].nof_workers = 1; + } + radios[i].nof_threads = radios[i].nof_threads * radios[i].nof_bwps; // std::cout << " nof_thread: " << radios[i].nof_thread << std::endl; diff --git a/nrscope/src/libs/nrscope_worker.cc b/nrscope/src/libs/nrscope_worker.cc new file mode 100644 index 00000000..dc9b6f0a --- /dev/null +++ b/nrscope/src/libs/nrscope_worker.cc @@ -0,0 +1,112 @@ +#include "nrscope/hdr/nrscope_worker.h" +#include +#include + +namespace NRScopeTask{ +NRScopeWorker::NRScopeWorker() : + rf_buffer_t(1), + rach_decoder(), + sibs_decoder() +{ + worker_state.sib1_inited = false; + worker_state.rach_inited = false; + worker_state.dci_inited = false; + + worker_state.sib1_found = false; + worker_state.rach_found = false; + worker_state.sibs_vec_inited = false; + + worker_state.nof_known_rntis = 0; + worker_state.known_rntis.resize(worker_state.nof_known_rntis); + sem_init(&smph_has_job, 0, 0); +} + +NRScopeWorker::~NRScopeWorker(){ } + +int NRScopeWorker::InitWorker(WorkState task_scheduler_state){ + /* Copy initial values */ + worker_state.nof_threads = task_scheduler_state.nof_threads; + worker_state.nof_rnti_worker_groups = + task_scheduler_state.nof_rnti_worker_groups; + worker_state.nof_bwps = task_scheduler_state.nof_bwps; + worker_state.args_t = task_scheduler_state.args_t; + worker_state.slot_sz = task_scheduler_state.slot_sz; + /* Size of one subframe */ + rx_buffer = srsran_vec_cf_malloc(SRSRAN_NOF_SLOTS_PER_SF_NR( + worker_state.args_t.ssb_scs) * worker_state.slot_sz); + + /* An wrapper for the rx_buffer */ + rf_buffer_t = srsran::rf_buffer_t(rx_buffer, + SRSRAN_NOF_SLOTS_PER_SF_NR(worker_state.args_t.ssb_scs) * + worker_state.slot_sz); + /* Start the worker thread */ + StartWorker(); + return SRSRAN_SUCCESS; +} + +void NRScopeWorker::StartWorker(){ + std::thread worker_thread {&NRScopeWorker::Run, this}; +} + +int NRScopeWorker::InitSIBDecoder(){ + /* Will always be called before any tasks */ + if(sibs_decoder.sib_decoder_and_reception_init(&worker_state, + rf_buffer_t.to_cf_t()) < SRSASN_SUCCESS){ + return NR_FAILURE; + } + return SRSRAN_SUCCESS; +} + +void NRScopeWorker::Run() { + while (true) { + /* When there is a job, the semaphore is set and buffer is copied */ + sem_wait(&smph_has_job); + + /* If we accidentally assign the job without initializing the SIB decoder */ + if(!worker_state.sib1_inited){ + continue; + } + + std::thread sibs_thread; + /* If sib1 is not found, we run the sibs_thread; if it's found, we skip. */ + if (!worker_state.sib1_found) { + sibs_thread = std::thread {&SIBsDecoder::decode_and_parse_sib1_from_slot, + &sibs_decoder, &slot, &sibs_vec_inited, &all_sibs_found, found_sib, + sibs, &sib1}; + } + + std::thread rach_thread {&RachDecoder::decode_and_parse_msg4_from_slot, + &rach_decoder, &slot, sib1_found, rach_inited, &rrc_setup, + &master_cell_group, &rach_found, &new_rnti_number, &new_rntis_found}; + + std::vector dci_threads; + if(dci_inited){ + for (uint32_t i = 0; i < nof_threads; i++){ + dci_threads.emplace_back(&DCIDecoder::decode_and_parse_dci_from_slot, + dci_decoders[i].get(), &slot, nof_known_rntis, nof_rnti_worker_groups, + sharded_results, sharded_rntis, nof_sharded_rntis, known_rntis, + dl_prb_rate, dl_prb_bits_rate, ul_prb_rate, ul_prb_bits_rate); + } + } + + if(sibs_thread.joinable()){ + sibs_thread.join(); + } + + if(rach_thread.joinable()){ + rach_thread.join(); + } + + if(dci_inited){ + for (uint32_t i = 0; i < nof_threads; i++){ + if(dci_threads[i].joinable()){ + dci_threads[i].join(); + } + } + } + + /* TODO: Post result to a global result queue */ + + } +} +} \ No newline at end of file diff --git a/nrscope/src/libs/rach_decoder.cc b/nrscope/src/libs/rach_decoder.cc index f0f5aee2..b6239462 100644 --- a/nrscope/src/libs/rach_decoder.cc +++ b/nrscope/src/libs/rach_decoder.cc @@ -21,9 +21,10 @@ RachDecoder::~RachDecoder(){ } -int RachDecoder::rach_decoder_init(TaskSchedulerNRScope* task_scheduler_nrscope){ - sib1 = task_scheduler_nrscope->sib1; - base_carrier = task_scheduler_nrscope->args_t.base_carrier; +int RachDecoder::rach_decoder_init(asn1::rrc_nr::sib1_s sib1_, + srsran_carrier_nr_t base_carrier_){ + sib1 = sib1_; + base_carrier = base_carrier_; srsran::srsran_band_helper bands; uint16_t band = bands.get_band_from_dl_freq_Hz(base_carrier.dl_center_frequency_hz); @@ -106,9 +107,14 @@ int RachDecoder::rach_decoder_init(TaskSchedulerNRScope* task_scheduler_nrscope) } int RachDecoder::rach_reception_init(srsran_ue_dl_nr_sratescs_info arg_scs_, - TaskSchedulerNRScope* task_scheduler_nrscope, + srsran_coreset_t* coreset0_t_, + srsran_carrier_nr_t* base_carrier_, + cell_search_result_t cell_, + double ssb_freq_hz_, + srsran_subcarrier_spacing_t ssb_scs_, + coreset0_args coreset0_args_t, cf_t* input[SRSRAN_MAX_PORTS]){ - memcpy(&coreset0_t, &task_scheduler_nrscope->coreset0_t, sizeof(srsran_coreset_t)); + memcpy(&coreset0_t, coreset0_t_, sizeof(srsran_coreset_t)); dci_cfg.bwp_dl_initial_bw = 275; dci_cfg.bwp_ul_initial_bw = 275; @@ -159,8 +165,8 @@ int RachDecoder::rach_reception_init(srsran_ue_dl_nr_sratescs_info arg_scs_, nrof_candidates.aggregation_level16; arg_scs = arg_scs_; - memcpy(&base_carrier, &task_scheduler_nrscope->args_t.base_carrier, sizeof(srsran_carrier_nr_t)); - cell = task_scheduler_nrscope->cell; + memcpy(&base_carrier, base_carrier_, sizeof(srsran_carrier_nr_t)); + cell = cell_; pdsch_hl_cfg.typeA_pos = cell.mib.dmrs_typeA_pos; for (uint32_t pdsch_time_id = 0; pdsch_time_id < sib1.serving_cell_cfg_common.dl_cfg_common.init_dl_bwp.pdsch_cfg_common.setup().pdsch_time_domain_alloc_list.size(); pdsch_time_id++){ if(sib1.serving_cell_cfg_common.dl_cfg_common.init_dl_bwp.pdsch_cfg_common.setup().pdsch_time_domain_alloc_list[pdsch_time_id].k0_present){ @@ -214,17 +220,17 @@ int RachDecoder::rach_reception_init(srsran_ue_dl_nr_sratescs_info arg_scs_, pdsch_carrier = base_carrier; arg_scs_pdsch = arg_scs; - double pointA = task_scheduler_nrscope->srsran_searcher_cfg_t.ssb_freq_hz - (SRSRAN_SSB_BW_SUBC / 2) * + double pointA = ssb_freq_hz_ - (SRSRAN_SSB_BW_SUBC / 2) * cell.abs_ssb_scs - cell.k_ssb * SRSRAN_SUBC_SPACING_NR(srsran_subcarrier_spacing_15kHz) - sib1.serving_cell_cfg_common.dl_cfg_common.freq_info_dl.offset_to_point_a * SRSRAN_SUBC_SPACING_NR(srsran_subcarrier_spacing_15kHz) * NRSCOPE_NSC_PER_RB_NR; pdsch_carrier.nof_prb = sib1.serving_cell_cfg_common.dl_cfg_common.freq_info_dl.scs_specific_carrier_list[0].carrier_bw; - double dl_center_frequency = pointA + pdsch_carrier.nof_prb * NRSCOPE_NSC_PER_RB_NR * SRSRAN_SUBC_SPACING_NR(task_scheduler_nrscope->srsran_searcher_cfg_t.ssb_scs) / 2; + double dl_center_frequency = pointA + pdsch_carrier.nof_prb * NRSCOPE_NSC_PER_RB_NR * SRSRAN_SUBC_SPACING_NR(ssb_scs_) / 2; std::cout << "dl_center_frequency: " << dl_center_frequency << std::endl; std::cout << "pointA: " << pointA << std::endl; - arg_scs_pdsch.coreset_offset_scs = (task_scheduler_nrscope->srsran_searcher_cfg_t.ssb_freq_hz - dl_center_frequency) / cell.abs_pdcch_scs; + arg_scs_pdsch.coreset_offset_scs = (ssb_freq_hz_ - dl_center_frequency) / cell.abs_pdcch_scs; // The lower boundary of PDSCH can be not aligned with the lower boundary of PDCCH if (srsran_ue_dl_nr_init_nrscope(&ue_dl_pdsch, input, &ue_dl_args, arg_scs_pdsch)) { @@ -237,7 +243,7 @@ int RachDecoder::rach_reception_init(srsran_ue_dl_nr_sratescs_info arg_scs_, return SRSRAN_ERROR; } - start_rb = (task_scheduler_nrscope->coreset0_args_t.coreset0_lower_freq_hz - pointA) / SRSRAN_SUBC_SPACING_NR(arg_scs_pdsch.scs) / 12; + start_rb = (coreset0_args_t.coreset0_lower_freq_hz - pointA) / SRSRAN_SUBC_SPACING_NR(arg_scs_pdsch.scs) / 12; if (srsran_ue_dl_nr_set_pdcch_config(&ue_dl_pdsch, &pdcch_cfg, &dci_cfg)) { ERROR("Error setting CORESET"); @@ -249,9 +255,14 @@ int RachDecoder::rach_reception_init(srsran_ue_dl_nr_sratescs_info arg_scs_, int RachDecoder::decode_and_parse_msg4_from_slot(srsran_slot_cfg_t* slot, - TaskSchedulerNRScope* task_scheduler_nrscope, - cf_t * raw_buffer){ - if(!task_scheduler_nrscope->sib1_found or !task_scheduler_nrscope->rach_inited){ + bool sib1_found, + bool rach_inited, + asn1::rrc_nr::rrc_setup_s* rrc_setup, + asn1::rrc_nr::cell_group_cfg_s* master_cell_group, + bool* rach_found, + uint32_t* new_rnti_number, + std::vector& new_rntis_found){ + if(!sib1_found or !rach_inited){ // If the SIB 1 is not detected or the RACH decoder is not initialized. std::cout << "SIB 1 not found or decoder not initialized, quitting..." << std::endl; return SRSRAN_SUCCESS; @@ -383,7 +394,7 @@ int RachDecoder::decode_and_parse_msg4_from_slot(srsran_slot_cfg_t* slot, ERROR("Failed to unpack DL-CCCH message (%d B)", pdsch_cfg.grant.tb[0].tbs / 8 - bytes_offset); } - task_scheduler_nrscope->rrc_setup = dlcch_msg.msg.c1().rrc_setup(); + *rrc_setup = dlcch_msg.msg.c1().rrc_setup(); std::cout << "Msg 4 Decoded." << std::endl; switch (dlcch_msg.msg.c1().type().value) { case asn1::rrc_nr::dl_ccch_msg_type_c::c1_c_::types::rrc_reject: { @@ -392,7 +403,7 @@ int RachDecoder::decode_and_parse_msg4_from_slot(srsran_slot_cfg_t* slot, }break; case asn1::rrc_nr::dl_ccch_msg_type_c::c1_c_::types::rrc_setup: { std::cout << "It's a rrc_setup, hooray!" << std::endl; - printf("rrc-TransactionIdentifier: %u\n", (task_scheduler_nrscope->rrc_setup).rrc_transaction_id); + printf("rrc-TransactionIdentifier: %u\n", (*rrc_setup).rrc_transaction_id); }break; default: { std::cout << "None detected, skip." << std::endl; @@ -404,9 +415,9 @@ int RachDecoder::decode_and_parse_msg4_from_slot(srsran_slot_cfg_t* slot, // asn1::json_writer js_msg4; // task_scheduler_nrscope->rrc_setup.to_json(js_msg4); // printf("rrcSetup content: %s\n", js_msg4.to_string().c_str()); - asn1::cbit_ref bref_cg((task_scheduler_nrscope->rrc_setup).crit_exts.rrc_setup().master_cell_group.data(), - (task_scheduler_nrscope->rrc_setup).crit_exts.rrc_setup().master_cell_group.size()); - if (task_scheduler_nrscope->master_cell_group.unpack(bref_cg) != asn1::SRSASN_SUCCESS) { + asn1::cbit_ref bref_cg((*rrc_setup).crit_exts.rrc_setup().master_cell_group.data(), + (*rrc_setup).crit_exts.rrc_setup().master_cell_group.size()); + if ((*master_cell_group).unpack(bref_cg) != asn1::SRSASN_SUCCESS) { ERROR("Could not unpack master cell group config."); return SRSRAN_ERROR; } @@ -416,18 +427,18 @@ int RachDecoder::decode_and_parse_msg4_from_slot(srsran_slot_cfg_t* slot, // printf("masterCellGroup: %s\n", js.to_string().c_str()); // Tells the task scheduler that the RACH is decoded and there are some entries in the know_rntis vector. - task_scheduler_nrscope->rach_found = true; + *rach_found = true; - if (!task_scheduler_nrscope->master_cell_group.sp_cell_cfg.recfg_with_sync.new_ue_id){ + if (!(*master_cell_group).sp_cell_cfg.recfg_with_sync.new_ue_id){ c_rnti = tc_rnti; }else{ - c_rnti = task_scheduler_nrscope->master_cell_group.sp_cell_cfg.recfg_with_sync.new_ue_id; + c_rnti = (*master_cell_group).sp_cell_cfg.recfg_with_sync.new_ue_id; } std::cout << "c-rnti: " << c_rnti << std::endl; // Add the new rntis into a different list and update the known_rnti vector in the end of the threads. - task_scheduler_nrscope->new_rnti_number += 1; - task_scheduler_nrscope->new_rntis_found.emplace_back(c_rnti); + *new_rnti_number += 1; + new_rntis_found.emplace_back(c_rnti); // task_scheduler_nrscope->nof_known_rntis += 1; // task_scheduler_nrscope->known_rntis.emplace_back(c_rnti); diff --git a/nrscope/src/libs/radio_nr.cc b/nrscope/src/libs/radio_nr.cc index 63d3362e..27b2f92c 100644 --- a/nrscope/src/libs/radio_nr.cc +++ b/nrscope/src/libs/radio_nr.cc @@ -8,6 +8,9 @@ std::mutex lock_radio_nr; +namespace NRScopeTask{ + /* Add some global variables for the task_scheduler and workers */ +} Radio::Radio() : logger(srslog::fetch_basic_logger("PHY")), @@ -51,8 +54,38 @@ int Radio::ScanThread(){ return SRSRAN_SUCCESS; } -static int resample_partially(msresamp_crcf * q, std::complex *in, std::complex *temp_out, uint8_t worker_id, uint32_t splitted_nx, uint32_t * actual_size) { - msresamp_crcf_execute(*q, (in + splitted_nx * worker_id), splitted_nx, temp_out, actual_size); +static int resample_partially(msresamp_crcf * q, + std::complex *in, + std::complex *temp_out, + uint8_t worker_id, + uint32_t splitted_nx, + uint32_t * actual_size) { + msresamp_crcf_execute(*q, (in + splitted_nx * worker_id), + splitted_nx, temp_out, actual_size); + return 0; +} + +static int copy_c_to_cpp_complex_arr_and_zero_padding(cf_t* src, + std::complex* dst, + uint32_t sz1, + uint32_t sz2) { + for (uint32_t i = 0; i < sz2; i++) { + /* indeed copy right? + https://en.cppreference.com/w/cpp/numeric/complex/operator%3D */ + dst[i] = i < sz1 ? src[i] : 0; + } + + return 0; +} + +static int copy_cpp_to_c_complex_arr(std::complex* src, + cf_t* dst, + uint32_t sz) { + for (uint32_t i = 0; i < sz; i++) { + // https://en.cppreference.com/w/cpp/numeric/complex + dst[i] = { src[i].real(), src[i].imag() }; + } + return 0; } @@ -263,7 +296,8 @@ int Radio::ScanInitandStart(){ int Radio::RadioInitandStart(){ - srsran_assert(raido_shared->init(rf_args, nullptr) == SRSRAN_SUCCESS, "Failed Radio initialisation"); + srsran_assert(raido_shared->init(rf_args, nullptr) == + SRSRAN_SUCCESS, "Failed Radio initialisation"); radio = std::move(raido_shared); // Cell Searcher parameters @@ -370,6 +404,11 @@ int Radio::RadioInitandStart(){ rk_initialized = true; } + /* Initialize the task_scheduler and the workers in it. + They will all remain inactive until the MIB is found. */ + task_scheduler_nrscope.InitandStart(nof_threads, nof_rnti_worker_groups, + nof_bwps, args_t, nof_workers); + while (not ss.end()) { // Get SSB center frequency cs_args.ssb_freq_hz = ss.get_frequency(); @@ -428,11 +467,9 @@ int Radio::RadioInitandStart(){ return SRSRAN_ERROR; } - struct timeval t0, t1; - if (resample_needed) { // srsran_vec_fprint2_c(fp_time_series_pre_resample, pre_resampling_rx_buffer, pre_resampling_slot_sz); - TaskSchedulerNRScope::copy_c_to_cpp_complex_arr_and_zero_padding(pre_resampling_rx_buffer, temp_x, pre_resampling_slot_sz, temp_x_sz); + copy_c_to_cpp_complex_arr_and_zero_padding(pre_resampling_rx_buffer, temp_x, pre_resampling_slot_sz, temp_x_sz); uint32_t splitted_nx = pre_resampling_slot_sz / RESAMPLE_WORKER_NUM; std::vector ssb_scan_resample_threads; for (uint8_t k = 0; k < RESAMPLE_WORKER_NUM; k++) { @@ -449,7 +486,7 @@ int Radio::RadioInitandStart(){ // sequentially merge back cf_t * buf_split_ptr = rx_buffer; for (uint8_t k = 0; k < RESAMPLE_WORKER_NUM; k++){ - TaskSchedulerNRScope::copy_cpp_to_c_complex_arr(temp_y[k], buf_split_ptr, actual_slot_szs[k]); + copy_cpp_to_c_complex_arr(temp_y[k], buf_split_ptr, actual_slot_szs[k]); buf_split_ptr += actual_slot_szs[k]; } @@ -473,7 +510,9 @@ int Radio::RadioInitandStart(){ std::cout << "N_id: " << cs_ret.ssb_res.N_id << std::endl; std::cout << "Decoding MIB..." << std::endl; - if(task_scheduler_nrscope.decode_mib(&args_t, &cs_ret, &srsran_searcher_cfg_t, r, rf_args.srate_hz) < SRSRAN_SUCCESS){ + /* And the states are updated in the task_scheduler*/ + if(task_scheduler_nrscope.decode_mib(&args_t, &cs_ret, + &srsran_searcher_cfg_t, r, rf_args.srate_hz) < SRSRAN_SUCCESS){ ERROR("Error init task scheduler"); return NR_FAILURE; } @@ -490,8 +529,6 @@ int Radio::RadioInitandStart(){ } } - // fclose(fp_time_series_pre_resample); - // fclose(fp_time_series_post_resample); if (resample_needed) { for (uint8_t k = 0; k < RESAMPLE_WORKER_NUM; k++) { msresamp_crcf_destroy(q[k]); @@ -511,7 +548,7 @@ static int slot_sync_recv_callback(void* ptr, cf_t** buffer, uint32_t nsamples, cf_t* buffer_ptr[SRSRAN_MAX_CHANNELS] = {}; buffer_ptr[0] = buffer[0]; - std::cout << "[xuyang debug 3] find fetch nsamples: " << nsamples << std::endl; + // std::cout << "[xuyang debug 3] find fetch nsamples: " << nsamples << std::endl; srsran::rf_buffer_t rf_buffer(buffer_ptr, nsamples); srsran::rf_timestamp_t a; @@ -623,7 +660,7 @@ int Radio::FetchAndResample(){ int Radio::DecodeAndProcess(){ uint32_t pre_resampling_sf_sz = SRSRAN_NOF_SLOTS_PER_SF_NR(task_scheduler_nrscope.args_t.ssb_scs) * pre_resampling_slot_sz; if(!task_scheduler_nrscope.sib1_inited){ - // std::thread sib_init_thread {&SIBsDecoder::sib_decoder_and_reception_init, &sibs_decoder, arg_scs, &task_scheduler_nrscope, rf_buffer_t.to_cf_t()}; + /* Initialize all the worker's sib decoder */ srsran::rf_buffer_t rf_buffer_wrapper(rx_buffer, pre_resampling_sf_sz); if(sibs_decoder.sib_decoder_and_reception_init(arg_scs, &task_scheduler_nrscope, rf_buffer_wrapper.to_cf_t()) < SRSASN_SUCCESS){ ERROR("SIBsDecoder Init Error"); @@ -673,12 +710,11 @@ int Radio::DecodeAndProcess(){ task_scheduler_nrscope.nof_rnti_worker_groups = nof_rnti_worker_groups; task_scheduler_nrscope.nof_bwps = nof_bwps; task_scheduler_nrscope.results.resize(nof_bwps); - srsran::rf_buffer_t rf_buffer_wrapper(rx_buffer, pre_resampling_sf_sz); for(uint32_t i = 0; i < nof_rnti_worker_groups; i++){ // for each rnti worker group, for each bwp, spawn a decoder for(uint8_t j = 0; j < nof_bwps; j++){ DCIDecoder *decoder = new DCIDecoder(100); - if(decoder->dci_decoder_and_reception_init(arg_scs, &task_scheduler_nrscope, rf_buffer_wrapper.to_cf_t(), j) < SRSASN_SUCCESS){ + if(decoder->dci_decoder_and_reception_init(arg_scs, &task_scheduler_nrscope, j) < SRSASN_SUCCESS){ ERROR("DCIDecoder Init Error"); return NR_FAILURE; } @@ -701,14 +737,14 @@ int Radio::DecodeAndProcess(){ // To save computing resources for dci decoders: assume SIB1 info should be static std::thread sibs_thread; if (!task_scheduler_nrscope.sib1_found) { - sibs_thread = std::thread {&SIBsDecoder::decode_and_parse_sib1_from_slot, &sibs_decoder, &slot, &task_scheduler_nrscope, rx_buffer}; + sibs_thread = std::thread {&SIBsDecoder::decode_and_parse_sib1_from_slot, &sibs_decoder, &slot, &task_scheduler_nrscope}; } - std::thread rach_thread {&RachDecoder::decode_and_parse_msg4_from_slot, &rach_decoder, &slot, &task_scheduler_nrscope, rx_buffer}; + std::thread rach_thread {&RachDecoder::decode_and_parse_msg4_from_slot, &rach_decoder, &slot, &task_scheduler_nrscope}; std::vector dci_threads; if(task_scheduler_nrscope.dci_inited){ for (uint32_t i = 0; i < nof_threads; i++){ - dci_threads.emplace_back(&DCIDecoder::decode_and_parse_dci_from_slot, dci_decoders[i].get(), &slot, &task_scheduler_nrscope, rx_buffer); + dci_threads.emplace_back(&DCIDecoder::decode_and_parse_dci_from_slot, dci_decoders[i].get(), &slot, &task_scheduler_nrscope); } } diff --git a/nrscope/src/libs/sibs_decoder.cc b/nrscope/src/libs/sibs_decoder.cc index 5920ea21..1d234111 100644 --- a/nrscope/src/libs/sibs_decoder.cc +++ b/nrscope/src/libs/sibs_decoder.cc @@ -11,10 +11,9 @@ SIBsDecoder::~SIBsDecoder(){ } -int SIBsDecoder::sib_decoder_and_reception_init(srsran_ue_dl_nr_sratescs_info arg_scs_, - TaskSchedulerNRScope* task_scheduler_nrscope, +int SIBsDecoder::sib_decoder_and_reception_init(WorkState* state, cf_t* input[SRSRAN_MAX_PORTS]){ - memcpy(&coreset0_t, &task_scheduler_nrscope->coreset0_t, sizeof(srsran_coreset_t)); + memcpy(&coreset0_t, &state->coreset0_t, sizeof(srsran_coreset_t)); dci_cfg.bwp_dl_initial_bw = 275; dci_cfg.bwp_ul_initial_bw = 275; @@ -39,9 +38,9 @@ int SIBsDecoder::sib_decoder_and_reception_init(srsran_ue_dl_nr_sratescs_info ar } pdcch_cfg.coreset[0] = coreset0_t; - arg_scs = arg_scs_; - memcpy(&base_carrier, &task_scheduler_nrscope->args_t.base_carrier, sizeof(srsran_carrier_nr_t)); - cell = task_scheduler_nrscope->cell; + arg_scs = state->arg_scs; + memcpy(&base_carrier, &state->args_t.base_carrier, sizeof(srsran_carrier_nr_t)); + cell = state->cell; pdsch_hl_cfg.typeA_pos = cell.mib.dmrs_typeA_pos; ue_dl_args.nof_rx_antennas = 1; @@ -73,25 +72,18 @@ int SIBsDecoder::sib_decoder_and_reception_init(srsran_ue_dl_nr_sratescs_info ar return SRSRAN_ERROR; } - task_scheduler_nrscope->sib1_inited = true; - std::cout << "SIB Decoder Initialized.." << std::endl; + // task_scheduler_nrscope->sib1_inited = true; + // std::cout << "SIB Decoder Initialized.." << std::endl; return SRSRAN_SUCCESS; } int SIBsDecoder::decode_and_parse_sib1_from_slot(srsran_slot_cfg_t* slot, - TaskSchedulerNRScope* task_scheduler_nrscope, - cf_t * raw_buffer){ - - if(!task_scheduler_nrscope->sib1_inited){ - std::cout << "SIB decoder not initialized..." << std::endl; - return SRSASN_SUCCESS; - } - - if(task_scheduler_nrscope->sib1_found){ - std::cout << "SIB 1 found, skipping..." << std::endl; - return SRSRAN_SUCCESS; - } + bool* sibs_vec_inited, + bool* all_sibs_found, + std::vector& found_sib, + std::vector& sibs, + asn1::rrc_nr::sib1_s* sib1_){ memset(&dci_sibs, 0, sizeof(srsran_dci_dl_nr_t)); @@ -111,7 +103,7 @@ int SIBsDecoder::decode_and_parse_sib1_from_slot(srsran_slot_cfg_t* slot, ERROR("SIBDecoder -- Error in blind search"); return SRSRAN_ERROR; } - // Print PDCCH blind search candidates + /* Print PDCCH blind search candidates */ // for (uint32_t pdcch_idx = 0; pdcch_idx < ue_dl_sibs.pdcch_info_count; pdcch_idx++) { // const srsran_ue_dl_nr_pdcch_info_t* info = &(ue_dl_sibs.pdcch_info[pdcch_idx]); // printf("PDCCH: %s-rnti=0x%x, crst_id=%d, ss_type=%s, ncce=%d, al=%d, EPRE=%+.2f, RSRP=%+.2f, corr=%.3f; " @@ -193,46 +185,45 @@ int SIBsDecoder::decode_and_parse_sib1_from_slot(srsran_slot_cfg_t* slot, // Try to decode the SIB if(srsran_unlikely(asn1::rrc_nr::bcch_dl_sch_msg_type_c::c1_c_::types_opts::sib_type1 != dlsch_msg.msg.c1().type())){ // Try to decode other SIBs - if(!task_scheduler_nrscope->sibs_vec_inited){ + if(!(*sibs_vec_inited)){ // Skip since the sib_vec is not intialized return SRSRAN_SUCCESS; }else{ // Get the sib_id, sib_id is uint8_t and is 2 for sib2, 3 for sib 3, etc... auto sib_id = dlsch_msg.msg.c1().sys_info().crit_exts.sys_info().sib_type_and_info[0].type().to_number(); - task_scheduler_nrscope->sibs[sib_id - 2] = dlsch_msg.msg.c1().sys_info(); - task_scheduler_nrscope->found_sib[sib_id - 2] = 1; + sibs[sib_id - 2] = dlsch_msg.msg.c1().sys_info(); + found_sib[sib_id - 2] = 1; // If we collect all the SIBs, we can skip the thread. long unsigned int found_result = 0; - for(long unsigned int i=0; ifound_sib.size(); i++){ - found_result += task_scheduler_nrscope->found_sib[i]; + for(long unsigned int i=0; i= task_scheduler_nrscope->found_sib.size()){ - task_scheduler_nrscope->all_sibs_found = true; + if(found_result >= found_sib.size()){ + *all_sibs_found = true; } std::cout << "SIB " << (int)sib_id << " Decoded." << std::endl; /* Uncomment to print the decode SIBs. */ asn1::json_writer js_sibs; - (task_scheduler_nrscope->sibs[(int)(sib_id - 2)]).to_json(js_sibs); + (sibs[(int)(sib_id - 2)]).to_json(js_sibs); printf("Decoded SIBs: %s\n", js_sibs.to_string().c_str()); } }else if(srsran_unlikely(asn1::rrc_nr::bcch_dl_sch_msg_type_c::c1_c_::types_opts::sys_info != dlsch_msg.msg.c1().type())){ - task_scheduler_nrscope->sib1 = dlsch_msg.msg.c1().sib_type1(); + *sib1_ = dlsch_msg.msg.c1().sib_type1(); std::cout << "SIB 1 Decoded." << std::endl; - task_scheduler_nrscope->sib1_found = true; - if(!task_scheduler_nrscope->sibs_vec_inited){ + if(!(*sibs_vec_inited)){ // Setting the size of the vector for other SIBs decoding. - int nof_sibs = task_scheduler_nrscope->sib1.si_sched_info_present ? task_scheduler_nrscope->sib1.si_sched_info.sched_info_list.size() : 0; - task_scheduler_nrscope->sibs.resize(nof_sibs); - task_scheduler_nrscope->found_sib.resize(nof_sibs); - task_scheduler_nrscope->sibs_vec_inited = true; + int nof_sibs = (*sib1_).si_sched_info_present ? (*sib1_).si_sched_info.sched_info_list.size() : 0; + sibs.resize(nof_sibs); + found_sib.resize(nof_sibs); + (*sibs_vec_inited) = true; } /* Uncomment to print the decode SIB1. */ asn1::json_writer js_sib1; - (task_scheduler_nrscope->sib1).to_json(js_sib1); + (*sib1_).to_json(js_sib1); printf("Decoded SIB1: %s\n", js_sib1.to_string().c_str()); } diff --git a/nrscope/src/libs/task_scheduler.cc b/nrscope/src/libs/task_scheduler.cc index aaf92644..8ccef007 100644 --- a/nrscope/src/libs/task_scheduler.cc +++ b/nrscope/src/libs/task_scheduler.cc @@ -1,125 +1,155 @@ #include "nrscope/hdr/task_scheduler.h" +namespace NRScopeTask{ TaskSchedulerNRScope::TaskSchedulerNRScope(){ - sib1_inited = false; - rach_inited = false; - dci_inited = false; + task_scheduler_state.sib1_inited = false; + task_scheduler_state.rach_inited = false; + task_scheduler_state.dci_inited = false; - sib1_found = false; - rach_found = false; - sibs_vec_inited = false; + task_scheduler_state.sib1_found = false; + task_scheduler_state.rach_found = false; + task_scheduler_state.sibs_vec_inited = false; - nof_known_rntis = 0; - known_rntis.resize(nof_known_rntis); + task_scheduler_state.nof_known_rntis = 0; + task_scheduler_state.known_rntis.resize(task_scheduler_state.nof_known_rntis); } TaskSchedulerNRScope::~TaskSchedulerNRScope(){ - +} + +int TaskSchedulerNRScope::InitandStart(int32_t nof_threads, + uint32_t nof_rnti_worker_groups, + uint8_t nof_bwps, + cell_searcher_args_t args_t, + uint32_t nof_workers_){ + task_scheduler_state.nof_threads = nof_threads; + task_scheduler_state.nof_rnti_worker_groups = nof_rnti_worker_groups; + task_scheduler_state.nof_bwps = nof_bwps; + task_scheduler_state.args_t = args_t; + task_scheduler_state.slot_sz = (uint32_t)(args_t.srate_hz / 1000.0f / + SRSRAN_NOF_SLOTS_PER_SF_NR(args_t.ssb_scs)); + nof_workers = nof_workers_; + for (int i = 0; i < nof_workers; i ++) { + NRScopeWorker *worker = new NRScopeWorker(); + if(worker->InitWorker(task_scheduler_state) < SRSRAN_SUCCESS) { + ERROR("Error initializing worker %d", i); + return NR_FAILURE; + } + workers.emplace_back(std::unique_ptr (worker)); + } + + return SRSRAN_SUCCESS; } int TaskSchedulerNRScope::decode_mib(cell_searcher_args_t* args_t_, - srsue::nr::cell_search::ret_t* cs_ret_, - srsue::nr::cell_search::cfg_t* srsran_searcher_cfg_t_, - float resample_ratio_, - uint32_t raw_srate_){ + srsue::nr::cell_search::ret_t* cs_ret_, + srsue::nr::cell_search::cfg_t* srsran_searcher_cfg_t_, + float resample_ratio_, + uint32_t raw_srate_){ args_t_->base_carrier.pci = cs_ret_->ssb_res.N_id; - if(srsran_pbch_msg_nr_mib_unpack(&(cs_ret_->ssb_res.pbch_msg), &cell.mib) < SRSRAN_SUCCESS){ + if(srsran_pbch_msg_nr_mib_unpack(&(cs_ret_->ssb_res.pbch_msg), + &task_scheduler_state.cell.mib) < SRSRAN_SUCCESS){ ERROR("Error decoding MIB"); return SRSRAN_ERROR; } char str[1024] = {}; - srsran_pbch_msg_nr_mib_info(&cell.mib, str, 1024); + srsran_pbch_msg_nr_mib_info(&task_scheduler_state.cell.mib, str, 1024); printf("MIB: %s\n", str); - printf("MIB payload: "); - for (int i =0; issb_res.pbch_msg.payload[i]); - } - printf("\n"); - // std::cout << "cell.mib.ssb_offset: " << cell.mib.ssb_offset << std::endl; - // std::cout << "((int)cs_ret.ssb_res.pbch_msg.k_ssb_msb): " << ((int)cs_ret_->ssb_res.pbch_msg.k_ssb_msb) << std::endl; + // printf("MIB payload: "); + // for (int i =0; issb_res.pbch_msg.payload[i]); + // } + // printf("\n"); - cell.k_ssb = cell.mib.ssb_offset; // already added the msb of k_ssb + /* already added the msb of k_ssb */ + task_scheduler_state.cell.k_ssb = task_scheduler_state.cell.mib.ssb_offset; // srsran_coreset0_ssb_offset returns the offset_rb relative to ssb - // nearly all bands in FR1 have min bandwidth 5 or 10 MHz, so there are only 5 entries here. - coreset0_args_t.offset_rb = srsran_coreset0_ssb_offset(cell.mib.coreset0_idx, - args_t_->ssb_scs, cell.mib.scs_common); - // std::cout << "Coreset offset in rbs related to SSB: " << coreset0_args_t.offset_rb << std::endl; - // std::cout << "set coreset0 config" << std::endl; - coreset0_t = {}; - // srsran_coreset_zero returns the offset_rb relative to pointA + // nearly all bands in FR1 have min bandwidth 5 or 10 MHz, + // so there are only 5 entries here. + task_scheduler_state.coreset0_args_t.offset_rb = + srsran_coreset0_ssb_offset(task_scheduler_state.cell.mib.coreset0_idx, + args_t_->ssb_scs, task_scheduler_state.cell.mib.scs_common); + + task_scheduler_state.coreset0_t = {}; + /* srsran_coreset_zero returns the offset_rb relative to pointA */ if(srsran_coreset_zero(cs_ret_->ssb_res.N_id, - 0, //cell.k_ssb * SRSRAN_SUBC_SPACING_NR(srsran_subcarrier_spacing_15kHz), - args_t_->ssb_scs, - cell.mib.scs_common, - cell.mib.coreset0_idx, - &coreset0_t) == SRSRAN_SUCCESS){ + 0, + args_t_->ssb_scs, + task_scheduler_state.cell.mib.scs_common, + task_scheduler_state.cell.mib.coreset0_idx, + &task_scheduler_state.coreset0_t) == SRSRAN_SUCCESS){ char freq_res_str[SRSRAN_CORESET_FREQ_DOMAIN_RES_SIZE] = {}; char coreset_info[512] = {}; - srsran_coreset_to_str(&coreset0_t, coreset_info, sizeof(coreset_info)); + srsran_coreset_to_str(&task_scheduler_state.coreset0_t, coreset_info, + sizeof(coreset_info)); printf("Coreset parameter: %s", coreset_info); } - // std::cout << "After calling srsran_coreset_zero()" << std::endl; - - // To find the position of coreset0, we need to use the offset between SSB and CORESET0, - // because we don't know the ssb_pointA_freq_offset_Hz yet required by the srsran_coreset_zero function. - // coreset0_t low bound freq = ssb center freq - 120 * scs (half of sc in ssb) - - // ssb_subcarrierOffset(from MIB) * scs - entry->offset_rb * 12(sc in one rb) * scs - cell.abs_ssb_scs = SRSRAN_SUBC_SPACING_NR(args_t_->ssb_scs); - cell.abs_pdcch_scs = SRSRAN_SUBC_SPACING_NR(cell.mib.scs_common); + + /* To find the position of coreset0, we need to use the offset between SSB + and CORESET0, because we don't know the ssb_pointA_freq_offset_Hz yet + required by the srsran_coreset_zero function. + coreset0_t low bound freq = ssb center freq - 120 * scs (half of sc in ssb) - + ssb_subcarrierOffset(from MIB) * scs - entry->offset_rb * 12(sc in one rb) * scs */ + task_scheduler_state.cell.abs_ssb_scs = + SRSRAN_SUBC_SPACING_NR(args_t_->ssb_scs); + task_scheduler_state.cell.abs_pdcch_scs = + SRSRAN_SUBC_SPACING_NR(task_scheduler_state.cell.mib.scs_common); srsran::srsran_band_helper bands; - coreset0_args_t.coreset0_lower_freq_hz = srsran_searcher_cfg_t_->ssb_freq_hz - (SRSRAN_SSB_BW_SUBC / 2) * - cell.abs_ssb_scs - coreset0_args_t.offset_rb * NRSCOPE_NSC_PER_RB_NR * cell.abs_pdcch_scs - - cell.k_ssb * SRSRAN_SUBC_SPACING_NR(srsran_subcarrier_spacing_15kHz); // defined by standards - coreset0_args_t.coreset0_center_freq_hz = coreset0_args_t.coreset0_lower_freq_hz + srsran_coreset_get_bw(&coreset0_t) / 2 * - cell.abs_pdcch_scs * NRSCOPE_NSC_PER_RB_NR; - - // std::cout << "k_ssb: " << cell.k_ssb << std::endl; - // std::cout << "ssb freq hz: " << srsran_searcher_cfg_t.ssb_freq_hz << std::endl; - // std::cout << "coreset0_lower freq hz: " << coreset0_args_t.coreset0_lower_freq_hz << std::endl; - // std::cout << "coreset0 center freq hz: " << coreset0_args_t.coreset0_center_freq_hz << std::endl; - // std::cout << "ssb_lower_freq hz: " << srsran_searcher_cfg_t.ssb_freq_hz - (SRSRAN_SSB_BW_SUBC / 2) * - // cell.abs_ssb_scs << std::endl; - // std::cout << "coreset0_bw: " << srsran_coreset_get_bw(&coreset0_t) << std::endl; - // std::cout << "coreset0_nof_symb: " << coreset0_t.duration << std::endl; - // std::cout << "scs_common: " << cell.mib.scs_common << std::endl; - // // the total used prb for coreset0 is 48 -> 17.28 MHz bw - - // std::cout << "mib pdcch-configSIB1.coreset0_idx: " << cell.mib.coreset0_idx << std::endl; - // std::cout << "mib pdcch-configSIB1.searchSpaceZero: " << cell.mib.ss0_idx << std::endl; - // printf("mib ssb-index: %u\n", cell.mib.ssb_idx); + /* defined by standards */ + task_scheduler_state.coreset0_args_t.coreset0_lower_freq_hz = + srsran_searcher_cfg_t_->ssb_freq_hz - (SRSRAN_SSB_BW_SUBC / 2) * + task_scheduler_state.cell.abs_ssb_scs - + task_scheduler_state.coreset0_args_t.offset_rb * NRSCOPE_NSC_PER_RB_NR * + task_scheduler_state.cell.abs_pdcch_scs - + task_scheduler_state.cell.k_ssb * + SRSRAN_SUBC_SPACING_NR(srsran_subcarrier_spacing_15kHz); + task_scheduler_state.coreset0_args_t.coreset0_center_freq_hz = + task_scheduler_state.coreset0_args_t.coreset0_lower_freq_hz + + srsran_coreset_get_bw(&task_scheduler_state.coreset0_t) / 2 * + task_scheduler_state.cell.abs_pdcch_scs * NRSCOPE_NSC_PER_RB_NR; coreset_zero_t_f_entry_nrscope coreset_zero_cfg; - // Get coreset_zero's position in time domain, check table 38.213, 13-11, because USRP can only support FR1. - if(coreset_zero_t_f_nrscope(cell.mib.ss0_idx, cell.mib.ssb_idx, coreset0_t.duration, &coreset_zero_cfg) < - SRSRAN_SUCCESS){ + /* Get coreset_zero's position in time domain, check table 38.213, 13-11, + because USRP can only support FR1. */ + if(coreset_zero_t_f_nrscope(task_scheduler_state.cell.mib.ss0_idx, + task_scheduler_state.cell.mib.ssb_idx, + task_scheduler_state.coreset0_t.duration, &coreset_zero_cfg) < + SRSRAN_SUCCESS){ ERROR("Error checking table 13-11"); return SRSRAN_ERROR; } // std::cout << "After calling coreset_zero_t_f_nrscope" << std::endl; - cell.u = (int)args_t_->ssb_scs; - coreset0_args_t.n_0 = (coreset_zero_cfg.O * (int)pow(2, cell.u) + - (int)floor(cell.mib.ssb_idx * coreset_zero_cfg.M)) % SRSRAN_NSLOTS_X_FRAME_NR(cell.u); + task_scheduler_state.cell.u = (int)args_t_->ssb_scs; + task_scheduler_state.coreset0_args_t.n_0 = (coreset_zero_cfg.O * + (int)pow(2, task_scheduler_state.cell.u) + + (int)floor(task_scheduler_state.cell.mib.ssb_idx * coreset_zero_cfg.M)) % + SRSRAN_NSLOTS_X_FRAME_NR(task_scheduler_state.cell.u); // sfn_c = 0, in even system frame, sfn_c = 1, in odd system frame - coreset0_args_t.sfn_c = (int)(floor(coreset_zero_cfg.O * pow(2, cell.u) + - floor(cell.mib.ssb_idx * coreset_zero_cfg.M)) / SRSRAN_NSLOTS_X_FRAME_NR(cell.u)) % 2; - args_t_->base_carrier.nof_prb = srsran_coreset_get_bw(&coreset0_t); + task_scheduler_state.coreset0_args_t.sfn_c = (int)(floor(coreset_zero_cfg.O * + pow(2, task_scheduler_state.cell.u) + + floor(task_scheduler_state.cell.mib.ssb_idx * coreset_zero_cfg.M)) / + SRSRAN_NSLOTS_X_FRAME_NR(task_scheduler_state.cell.u)) % 2; + args_t_->base_carrier.nof_prb = + srsran_coreset_get_bw(&task_scheduler_state.coreset0_t); - args_t = *args_t_; - cs_ret = *cs_ret_; - memcpy(&srsran_searcher_cfg_t, srsran_searcher_cfg_t_, sizeof(srsue::nr::cell_search::cfg_t)); - // std::cout << "After memcpy" << std::endl; + task_scheduler_state.args_t = *args_t_; + task_scheduler_state.cs_ret = *cs_ret_; + memcpy(&task_scheduler_state.srsran_searcher_cfg_t, srsran_searcher_cfg_t_, + sizeof(srsue::nr::cell_search::cfg_t)); // initiate resampler here resample_ratio = resample_ratio_; float As=60.0f; resampler = msresamp_crcf_create(resample_ratio,As); resampler_delay = msresamp_crcf_get_delay(resampler); - pre_resampling_slot_sz = raw_srate_ / 1000 / SRSRAN_NOF_SLOTS_PER_SF_NR(args_t_->ssb_scs); // don't hardcode it; change later + /* don't hardcode it; change later */ + pre_resampling_slot_sz = raw_srate_ / 1000 / + SRSRAN_NOF_SLOTS_PER_SF_NR(args_t_->ssb_scs); temp_x_sz = pre_resampling_slot_sz + (int)ceilf(resampler_delay) + 10; temp_y_sz = (uint32_t)(temp_x_sz * resample_ratio * 2); temp_x = SRSRAN_MEM_ALLOC(std::complex, temp_x_sz); @@ -130,67 +160,91 @@ int TaskSchedulerNRScope::decode_mib(cell_searcher_args_t* args_t_, int TaskSchedulerNRScope::merge_results(){ - for (uint8_t b = 0; b < nof_bwps; b++) { + for (uint8_t b = 0; b < task_scheduler_state.nof_bwps; b++) { DCIFeedback new_result; results[b] = new_result; - results[b].dl_grants.resize(nof_known_rntis); - results[b].ul_grants.resize(nof_known_rntis); - results[b].spare_dl_prbs.resize(nof_known_rntis); - results[b].spare_dl_tbs.resize(nof_known_rntis); - results[b].spare_dl_bits.resize(nof_known_rntis); - results[b].spare_ul_prbs.resize(nof_known_rntis); - results[b].spare_ul_tbs.resize(nof_known_rntis); - results[b].spare_ul_bits.resize(nof_known_rntis); - results[b].dl_dcis.resize(nof_known_rntis); - results[b].ul_dcis.resize(nof_known_rntis); + results[b].dl_grants.resize(task_scheduler_state.nof_known_rntis); + results[b].ul_grants.resize(task_scheduler_state.nof_known_rntis); + results[b].spare_dl_prbs.resize(task_scheduler_state.nof_known_rntis); + results[b].spare_dl_tbs.resize(task_scheduler_state.nof_known_rntis); + results[b].spare_dl_bits.resize(task_scheduler_state.nof_known_rntis); + results[b].spare_ul_prbs.resize(task_scheduler_state.nof_known_rntis); + results[b].spare_ul_tbs.resize(task_scheduler_state.nof_known_rntis); + results[b].spare_ul_bits.resize(task_scheduler_state.nof_known_rntis); + results[b].dl_dcis.resize(task_scheduler_state.nof_known_rntis); + results[b].ul_dcis.resize(task_scheduler_state.nof_known_rntis); uint32_t rnti_s = 0; uint32_t rnti_e = 0; - for(uint32_t i = 0; i < nof_rnti_worker_groups; i++){ + for(uint32_t i = 0; i < task_scheduler_state.nof_rnti_worker_groups; i++){ - if(rnti_s >= nof_known_rntis){ + if(rnti_s >= task_scheduler_state.nof_known_rntis){ continue; } - uint32_t n_rntis = nof_sharded_rntis[i * nof_bwps]; + uint32_t n_rntis = task_scheduler_state.nof_sharded_rntis[i * + task_scheduler_state.nof_bwps]; rnti_e = rnti_s + n_rntis; - if(rnti_e > nof_known_rntis){ - rnti_e = nof_known_rntis; + if(rnti_e > task_scheduler_state.nof_known_rntis){ + rnti_e = task_scheduler_state.nof_known_rntis; } - uint32_t thread_id = i * nof_bwps + b; - results[b].nof_dl_used_prbs += sharded_results[thread_id].nof_dl_used_prbs; - results[b].nof_ul_used_prbs += sharded_results[thread_id].nof_ul_used_prbs; + uint32_t thread_id = i * task_scheduler_state.nof_bwps + b; + results[b].nof_dl_used_prbs += + task_scheduler_state.sharded_results[thread_id].nof_dl_used_prbs; + results[b].nof_ul_used_prbs += + task_scheduler_state.sharded_results[thread_id].nof_ul_used_prbs; for(uint32_t k = 0; k < n_rntis; k++) { - results[b].dl_dcis[k+rnti_s] = sharded_results[thread_id].dl_dcis[k]; - results[b].ul_dcis[k+rnti_s] = sharded_results[thread_id].ul_dcis[k]; - results[b].dl_grants[k+rnti_s] = sharded_results[thread_id].dl_grants[k]; - results[b].ul_grants[k+rnti_s] = sharded_results[thread_id].ul_grants[k]; + results[b].dl_dcis[k+rnti_s] = + task_scheduler_state.sharded_results[thread_id].dl_dcis[k]; + results[b].ul_dcis[k+rnti_s] = + task_scheduler_state.sharded_results[thread_id].ul_dcis[k]; + results[b].dl_grants[k+rnti_s] = + task_scheduler_state.sharded_results[thread_id].dl_grants[k]; + results[b].ul_grants[k+rnti_s] = + task_scheduler_state.sharded_results[thread_id].ul_grants[k]; } rnti_s = rnti_e; } std::cout << "End of nof_threads..." << std::endl; - // TO-DISCUSS: to obtain even more precise result, here maybe we should total user payload prb in that bwp - used prb - results[b].nof_dl_spare_prbs = args_t.base_carrier.nof_prb * (14 - 2) - results[b].nof_dl_used_prbs; - for(uint32_t idx = 0; idx < nof_known_rntis; idx ++){ - results[b].spare_dl_prbs[idx] = results[b].nof_dl_spare_prbs / nof_known_rntis; - if(abs(results[b].spare_dl_prbs[idx]) > args_t.base_carrier.nof_prb * (14 - 2)){ + /* TO-DISCUSS: to obtain even more precise result, + here maybe we should total user payload prb in that bwp - used prb */ + results[b].nof_dl_spare_prbs = + task_scheduler_state.args_t.base_carrier.nof_prb * + (14 - 2) - results[b].nof_dl_used_prbs; + for(uint32_t idx = 0; idx < task_scheduler_state.nof_known_rntis; idx ++){ + results[b].spare_dl_prbs[idx] = results[b].nof_dl_spare_prbs / + task_scheduler_state.nof_known_rntis; + if(abs(results[b].spare_dl_prbs[idx]) > + task_scheduler_state.args_t.base_carrier.nof_prb * (14 - 2)){ results[b].spare_dl_prbs[idx] = 0; } - results[b].spare_dl_tbs[idx] = (int) ((float)results[b].spare_dl_prbs[idx] * dl_prb_rate[idx]); - results[b].spare_dl_bits[idx] = (int) ((float)results[b].spare_dl_prbs[idx] * dl_prb_bits_rate[idx]); + results[b].spare_dl_tbs[idx] = + (int) ((float)results[b].spare_dl_prbs[idx] * + task_scheduler_state.dl_prb_rate[idx]); + results[b].spare_dl_bits[idx] = + (int) ((float)results[b].spare_dl_prbs[idx] * + task_scheduler_state.dl_prb_bits_rate[idx]); } - results[b].nof_ul_spare_prbs = args_t.base_carrier.nof_prb * (14 - 2) - results[b].nof_ul_used_prbs; - for(uint32_t idx = 0; idx < nof_known_rntis; idx ++){ - results[b].spare_ul_prbs[idx] = results[b].nof_ul_spare_prbs / nof_known_rntis; - if(abs(results[b].spare_ul_prbs[idx]) > args_t.base_carrier.nof_prb * (14 - 2)){ + results[b].nof_ul_spare_prbs = + task_scheduler_state.args_t.base_carrier.nof_prb * (14 - 2) - + results[b].nof_ul_used_prbs; + for(uint32_t idx = 0; idx < task_scheduler_state.nof_known_rntis; idx ++){ + results[b].spare_ul_prbs[idx] = results[b].nof_ul_spare_prbs / + task_scheduler_state.nof_known_rntis; + if(abs(results[b].spare_ul_prbs[idx]) > + task_scheduler_state.args_t.base_carrier.nof_prb * (14 - 2)){ results[b].spare_ul_prbs[idx] = 0; } - results[b].spare_ul_tbs[idx] = (int) ((float)results[b].spare_ul_prbs[idx] * ul_prb_rate[idx]); - results[b].spare_ul_bits[idx] = (int) ((float)results[b].spare_ul_prbs[idx] * ul_prb_bits_rate[idx]); + results[b].spare_ul_tbs[idx] = + (int) ((float)results[b].spare_ul_prbs[idx] * + task_scheduler_state.ul_prb_rate[idx]); + results[b].spare_ul_bits[idx] = + (int) ((float)results[b].spare_ul_prbs[idx] * + task_scheduler_state.ul_prb_bits_rate[idx]); } } @@ -198,16 +252,19 @@ int TaskSchedulerNRScope::merge_results(){ } int TaskSchedulerNRScope::update_known_rntis(){ - if(new_rnti_number <= 0){ + if(task_scheduler_state.new_rnti_number <= 0){ return SRSRAN_SUCCESS; } - nof_known_rntis += new_rnti_number; - for(uint32_t i = 0; i < new_rnti_number; i++){ - known_rntis.emplace_back(new_rntis_found[i]); + task_scheduler_state.nof_known_rntis += task_scheduler_state.new_rnti_number; + for(uint32_t i = 0; i < task_scheduler_state.new_rnti_number; i++){ + task_scheduler_state.known_rntis.emplace_back( + task_scheduler_state.new_rntis_found[i]); } - new_rntis_found.clear(); - new_rnti_number = 0; + task_scheduler_state.new_rntis_found.clear(); + task_scheduler_state.new_rnti_number = 0; return SRSRAN_SUCCESS; +} + } \ No newline at end of file From 737c3a38ec6d3d52097f95b131331e2d3934c743 Mon Sep 17 00:00:00 2001 From: Haoran Wan Date: Tue, 10 Sep 2024 13:59:47 -0400 Subject: [PATCH 02/15] worker working with SIB1 decoding --- nrscope/config/config.yaml | 10 +- nrscope/hdr/dci_decoder.h | 2 +- nrscope/hdr/nrscope_def.h | 29 +- nrscope/hdr/nrscope_worker.h | 21 +- nrscope/hdr/rach_decoder.h | 17 +- nrscope/hdr/sibs_decoder.h | 20 +- nrscope/hdr/task_scheduler.h | 23 +- nrscope/hdr/to_google.h | 4 +- nrscope/src/CMakeLists.txt | 2 +- nrscope/src/libs/harq_tracking.cc | 24 +- nrscope/src/libs/nrscope_worker.cc | 159 +++++++++-- nrscope/src/libs/rach_decoder.cc | 232 ++++++++------- nrscope/src/libs/radio_nr.cc | 439 +++++++++++++++++------------ nrscope/src/libs/sibs_decoder.cc | 85 +++--- nrscope/src/libs/task_scheduler.cc | 56 +++- 15 files changed, 710 insertions(+), 413 deletions(-) diff --git a/nrscope/config/config.yaml b/nrscope/config/config.yaml index e6e93763..4c21c755 100644 --- a/nrscope/config/config.yaml +++ b/nrscope/config/config.yaml @@ -1,17 +1,17 @@ nof_usrp_dev: 1 usrp_setting_0: - ssb_freq: 3488160000 #1989850000 #1970450000 #3489600000 #3649440000 #3650880000 # 1970450000 #2600040000 #3488160000 #3685440000 #3561600000 #1842050000 #2528550000 #3565920000 #2524950000 #2523750000 # 3565920000 # 2527350000 #3408960000 # should be set to the ssb frequency of the cell - rf_args: "clock=external,type=x300,master_clock_rate=200000000,sampling_rate=25000000" #"type=x300" #"clock=external" for TwinRX + ssb_freq: 3630720000 #1989850000 #1970450000 #3489600000 #3649440000 #3650880000 # 1970450000 #2600040000 #3488160000 #3685440000 #3561600000 #1842050000 #2528550000 #3565920000 #2524950000 #2523750000 # 3565920000 # 2527350000 #3408960000 # should be set to the ssb frequency of the cell + rf_args: "clock=external,type=x300,master_clock_rate=184320000,sampling_rate=23040000" #"type=x300" #"clock=external" for TwinRX # rf_args: "clock=external,type=x300,sampling_rate=23040000" #"type=x300" #"clock=external" for CBX - rx_gain: 90 # for x310 CBX, max rx gain is 31.5, for b210, it's around 80, for x310 TwinRX, max rx gain is 90 - srate_hz: 25000000 #11520000 #11520000 #23040000 (CBX) + rx_gain: 80 # for x310 CBX, max rx gain is 31.5, for b210, it's around 80, for x310 TwinRX, max rx gain is 90 + srate_hz: 23040000 #11520000 #11520000 #23040000 (CBX) srsran_srate_hz: 23040000 nof_carriers: 1 nof_antennas: 1 scs_index: 1 #(0: 15kHz, 1: 30kHz, ..., the u in standard) rf_log_level: "debug" nof_rnti_worker_groups: 1 - nof_bwps: 2 + nof_bwps: 1 nof_workers: 4 log_name: "a.csv" #"/home/wanhr/Documents/data/nrscope/evaluation/coverage_amarisoft/dci_tx_50.csv" # x (0-10), y(0-8) coordinates diff --git a/nrscope/hdr/dci_decoder.h b/nrscope/hdr/dci_decoder.h index 119a3be3..7d3e2a1b 100644 --- a/nrscope/hdr/dci_decoder.h +++ b/nrscope/hdr/dci_decoder.h @@ -2,7 +2,7 @@ #define DCI_DECODER_H #include "nrscope/hdr/nrscope_def.h" -#include "nrscope/hdr/task_scheduler.h" +// #include "nrscope/hdr/task_scheduler.h" class DCIDecoder{ public: diff --git a/nrscope/hdr/nrscope_def.h b/nrscope/hdr/nrscope_def.h index 79580f8a..9c66eb2d 100644 --- a/nrscope/hdr/nrscope_def.h +++ b/nrscope/hdr/nrscope_def.h @@ -75,13 +75,15 @@ struct cell_searcher_args_t { srsran::srsran_band_helper bands; // Deduce band number - uint16_t band = bands.get_band_from_dl_freq_Hz_and_scs(base_carrier.dl_center_frequency_hz, scs_input); + uint16_t band = bands.get_band_from_dl_freq_Hz_and_scs( + base_carrier.dl_center_frequency_hz, scs_input); srsran_assert(band != UINT16_MAX, "Invalid band"); // Deduce point A in Hz double pointA_Hz = - bands.get_abs_freq_point_a_from_center_freq(base_carrier.nof_prb, base_carrier.dl_center_frequency_hz); + bands.get_abs_freq_point_a_from_center_freq( + base_carrier.nof_prb, base_carrier.dl_center_frequency_hz); // Deduce DL center frequency ARFCN uint32_t pointA_arfcn = bands.freq_to_nr_arfcn(pointA_Hz); @@ -192,7 +194,7 @@ typedef struct WorkState_ WorkState; bool rach_found; bool sibs_vec_inited; // Is the vector for other SIBs set according to SIB? - bool all_sibs_found; // All SIBs are decoded, we can stop the SIB thread from now. + bool all_sibs_found; // All SIBs are decoded, stop the SIB thread now. bool sib1_inited; // SIBsDecoder is initialized. bool rach_inited; // RACHDecoder is initialized. @@ -201,12 +203,27 @@ typedef struct WorkState_ WorkState; uint32_t nof_known_rntis; std::vector known_rntis; + /* May need to change things below this */ + std::vector nof_sharded_rntis; + std::vector > sharded_rntis; + std::vector sharded_results; + + std::vector dl_prb_rate; + std::vector ul_prb_rate; + std::vector dl_prb_bits_rate; + std::vector ul_prb_bits_rate; + + uint32_t new_rnti_number; + std::vector new_rntis_found; + }; + +typedef struct SlotResult_ SlotResult; + struct SlotResult_{ + + /* May need to change things below this */ std::vector nof_sharded_rntis; std::vector > sharded_rntis; std::vector sharded_results; - uint32_t nof_threads; - uint32_t nof_rnti_worker_groups; - uint8_t nof_bwps; std::vector dl_prb_rate; std::vector ul_prb_rate; diff --git a/nrscope/hdr/nrscope_worker.h b/nrscope/hdr/nrscope_worker.h index b5a9efae..512e2b70 100644 --- a/nrscope/hdr/nrscope_worker.h +++ b/nrscope/hdr/nrscope_worker.h @@ -10,21 +10,21 @@ namespace NRScopeTask{ class NRScopeWorker{ public: - srsran::rf_buffer_t rf_buffer_t; cf_t* rx_buffer; + srsran::rf_buffer_t rf_buffer_t; WorkState worker_state; RachDecoder rach_decoder; SIBsDecoder sibs_decoder; std::vector > dci_decoders; - // uint32_t nof_threads; - // uint32_t nof_rnti_worker_groups; - // uint8_t nof_bwps; - /* Job indicator */ sem_t smph_has_job; + bool busy; + std::mutex lock; + /* Worker thread */ + std::thread worker_thread; // bool sib1_inited; /* SIBsDecoder is initialized, set by task_scheduler. */ // bool rach_inited; /* RACHDecoder is initialized, set by task_scheduler. */ // bool dci_inited; /* DCIDecoder is initialized, set by task_scheduler. */ @@ -68,11 +68,20 @@ class NRScopeWorker{ so the worker can set its buffer.*/ int InitWorker(WorkState task_scheduler_state); + /* Start the worker thread */ void StartWorker(); + + /* Set worker's state the same as the scheduler's state, + and initilize the decoders if needed. This function will be called + before the job starts, so don't need to consider about the thread + safe thing. */ + int SyncState(WorkState* task_scheduler_state); + void CopySlotandBuffer(srsran_slot_cfg_t* slot_, cf_t* rx_buffer_); + int InitSIBDecoder(); int InitRACHDecoder(); int InitDCIDecoders(); - + private: void Run(); }; diff --git a/nrscope/hdr/rach_decoder.h b/nrscope/hdr/rach_decoder.h index 43ac2cd2..e23d7dc0 100644 --- a/nrscope/hdr/rach_decoder.h +++ b/nrscope/hdr/rach_decoder.h @@ -10,7 +10,7 @@ #include "srsran/common/band_helper.h" #include "nrscope/hdr/nrscope_def.h" -#include "nrscope/hdr/task_scheduler.h" +// #include "nrscope/hdr/task_scheduler.h" class RachDecoder{ public: @@ -50,19 +50,12 @@ class RachDecoder{ RachDecoder(); ~RachDecoder(); - int rach_decoder_init(asn1::rrc_nr::sib1_s sib1_, - srsran_carrier_nr_t base_carrier_); + int RACHDecoderInit(WorkState state); - int rach_reception_init(srsran_ue_dl_nr_sratescs_info arg_scs_, - srsran_coreset_t* coreset0_t_, - srsran_carrier_nr_t* base_carrier_, - cell_search_result_t cell_, - double ssb_freq_hz_, - srsran_subcarrier_spacing_t ssb_scs_, - coreset0_args coreset0_args_t, - cf_t* input[SRSRAN_MAX_PORTS]); + int RACHReceptionInit(WorkState* state, + cf_t* input[SRSRAN_MAX_PORTS]); - int decode_and_parse_msg4_from_slot(srsran_slot_cfg_t* slot, + int DecodeandParseMS4fromSlot(srsran_slot_cfg_t* slot, bool sib1_found, bool rach_inited, asn1::rrc_nr::rrc_setup_s* rrc_setup, diff --git a/nrscope/hdr/sibs_decoder.h b/nrscope/hdr/sibs_decoder.h index ce1cd2d6..b15fe304 100644 --- a/nrscope/hdr/sibs_decoder.h +++ b/nrscope/hdr/sibs_decoder.h @@ -4,7 +4,7 @@ #include "srsran/support/srsran_assert.h" #include "nrscope/hdr/nrscope_def.h" -#include "nrscope/hdr/task_scheduler.h" +// #include "nrscope/hdr/task_scheduler.h" class SIBsDecoder{ public: @@ -51,8 +51,8 @@ class SIBsDecoder{ * @return SRSRAN_SUCCESS (0) if everything goes well. * SRSRAN_ERROR (-1) if something is wrong in the function. */ - int sib_decoder_and_reception_init(WorkState* state, - cf_t* input[SRSRAN_MAX_PORTS]); + int SIBDecoderandReceptionInit(WorkState* state, + cf_t* input[SRSRAN_MAX_PORTS]); /** * This function decodes the current slot for SIB 1, and the result will reflect in the sib1 parameter. @@ -64,12 +64,14 @@ class SIBsDecoder{ * @return SRSRAN_SUCCESS (0) if everything goes well. * SRSRAN_ERROR (-1) if something is wrong in the function. */ - int decode_and_parse_sib1_from_slot(srsran_slot_cfg_t* slot, - bool* sibs_vec_inited, - bool* all_sibs_found, - std::vector& found_sib, - std::vector& sibs, - asn1::rrc_nr::sib1_s* sib1_); + int DecodeandParseSIB1fromSlot(srsran_slot_cfg_t* slot, + WorkState state); + // srsran_slot_cfg_t* slot, + // bool* sibs_vec_inited, + // bool* all_sibs_found, + // std::vector& found_sib, + // std::vector& sibs, + // asn1::rrc_nr::sib1_s* sib1_); // /** // * A function that represents the SIB thread for a producer-consumer threading design, diff --git a/nrscope/hdr/task_scheduler.h b/nrscope/hdr/task_scheduler.h index 7fb36c73..31fc717e 100644 --- a/nrscope/hdr/task_scheduler.h +++ b/nrscope/hdr/task_scheduler.h @@ -57,9 +57,9 @@ class TaskSchedulerNRScope{ // std::vector new_rntis_found; WorkState task_scheduler_state; uint32_t nof_workers; + std::thread scheduler_thread; std::vector > workers; - std::mutex lock; TaskSchedulerNRScope(); @@ -67,21 +67,23 @@ class TaskSchedulerNRScope{ /* Start the workers and the receiving result thread, called before the radio reception. */ - int TaskSchedulerNRScope::InitandStart(int32_t nof_threads, - uint32_t nof_rnti_worker_groups, - uint8_t nof_bwps, - cell_searcher_args_t args_t, - uint32_t nof_workers_); + int InitandStart(int32_t nof_threads, + uint32_t nof_rnti_worker_groups, + uint8_t nof_bwps, + cell_searcher_args_t args_t, + uint32_t nof_workers_); - int decode_mib(cell_searcher_args_t* args_t_, + int DecodeMIB(cell_searcher_args_t* args_t_, srsue::nr::cell_search::ret_t* cs_ret_, srsue::nr::cell_search::cfg_t* srsran_searcher_cfg_t, float resample_ratio_, uint32_t raw_srate_); - int merge_results(); + int MergeResults(); + int UpdateKnownRNTIs(); - int update_known_rntis(); + /* Assign the current slot to one worker*/ + int AssignTask(srsran_slot_cfg_t* slot, cf_t* rx_buffer_); std::vector get_results(){ return results; @@ -99,6 +101,9 @@ class TaskSchedulerNRScope{ std::complex * temp_x; std::complex * temp_y; uint32_t pre_resampling_slot_sz; + +private: + void Run(); }; } diff --git a/nrscope/hdr/to_google.h b/nrscope/hdr/to_google.h index 1e710222..e423b3be 100644 --- a/nrscope/hdr/to_google.h +++ b/nrscope/hdr/to_google.h @@ -6,7 +6,9 @@ namespace ToGoogle{ - void init_to_google(std::string google_credential_input, std::string google_dataset_id_input, int nof_usrp_input); + void init_to_google(std::string google_credential_input, + std::string google_dataset_id_input, + int nof_usrp_input); void push_google_node(LogNode input_log, int rf_index); diff --git a/nrscope/src/CMakeLists.txt b/nrscope/src/CMakeLists.txt index 6886eaa7..6b4870af 100644 --- a/nrscope/src/CMakeLists.txt +++ b/nrscope/src/CMakeLists.txt @@ -33,7 +33,7 @@ target_link_libraries(nrscope srsue_phy "/usr/local/lib/libliquid.so" "/usr/local/lib/libliquid.a") -target_link_libraries(nrscan srsue_phy +target_link_libraries(nrscan srsue_phy srsran_common srsran_phy srsran_radio diff --git a/nrscope/src/libs/harq_tracking.cc b/nrscope/src/libs/harq_tracking.cc index 641385d1..5de973f6 100644 --- a/nrscope/src/libs/harq_tracking.cc +++ b/nrscope/src/libs/harq_tracking.cc @@ -30,26 +30,34 @@ bool HarqTracker::is_new_data(int ue_id, int ndi, int harq_id, bool is_dl){ assert(ue_id < nof_known_rntis && harq_id < 16 && (ndi == 1 || ndi == 0)); if(is_dl){ - assert(dl_ue_ndi[ue_id][harq_id] == -1 || dl_ue_ndi[ue_id][harq_id] == 1 || dl_ue_ndi[ue_id][harq_id] == 0); - if(dl_ue_ndi[ue_id][harq_id] == -1){ // no previous ndi value + assert(dl_ue_ndi[ue_id][harq_id] == -1 || dl_ue_ndi[ue_id][harq_id] == 1 || + dl_ue_ndi[ue_id][harq_id] == 0); + if(dl_ue_ndi[ue_id][harq_id] == -1){ + /* no previous ndi value */ dl_ue_ndi[ue_id][harq_id] = ndi; return true; - }else if(dl_ue_ndi[ue_id][harq_id] == ndi){ // ndi is not toggled, it's a retransmission + }else if(dl_ue_ndi[ue_id][harq_id] == ndi){ + /* ndi is not toggled, it's a retransmission */ dl_ue_ndi[ue_id][harq_id] = ndi; return false; - }else{ // ndi is toggled, it's a new transmission + }else{ + /* ndi is toggled, it's a new transmission */ dl_ue_ndi[ue_id][harq_id] = ndi; return true; } }else{ - assert(ul_ue_ndi[ue_id][harq_id] == -1 || ul_ue_ndi[ue_id][harq_id] == 1 || ul_ue_ndi[ue_id][harq_id] == 0); - if(ul_ue_ndi[ue_id][harq_id] == -1){ // no previous ndi value + assert(ul_ue_ndi[ue_id][harq_id] == -1 || ul_ue_ndi[ue_id][harq_id] == 1 || + ul_ue_ndi[ue_id][harq_id] == 0); + if(ul_ue_ndi[ue_id][harq_id] == -1){ + /* no previous ndi value */ ul_ue_ndi[ue_id][harq_id] = ndi; return true; - }else if(ul_ue_ndi[ue_id][harq_id] == ndi){ // ndi is not toggled, it's a retransmission + }else if(ul_ue_ndi[ue_id][harq_id] == ndi){ + /* ndi is not toggled, it's a retransmission */ ul_ue_ndi[ue_id][harq_id] = ndi; return false; - }else{ // ndi is toggled, it's a new transmission + }else{ + /* ndi is toggled, it's a new transmission */ ul_ue_ndi[ue_id][harq_id] = ndi; return true; } diff --git a/nrscope/src/libs/nrscope_worker.cc b/nrscope/src/libs/nrscope_worker.cc index dc9b6f0a..f3404cf4 100644 --- a/nrscope/src/libs/nrscope_worker.cc +++ b/nrscope/src/libs/nrscope_worker.cc @@ -19,6 +19,7 @@ NRScopeWorker::NRScopeWorker() : worker_state.nof_known_rntis = 0; worker_state.known_rntis.resize(worker_state.nof_known_rntis); sem_init(&smph_has_job, 0, 0); + busy = false; } NRScopeWorker::~NRScopeWorker(){ } @@ -40,27 +41,127 @@ int NRScopeWorker::InitWorker(WorkState task_scheduler_state){ SRSRAN_NOF_SLOTS_PER_SF_NR(worker_state.args_t.ssb_scs) * worker_state.slot_sz); /* Start the worker thread */ + // std::cout << "Starting the worker..." << std::endl; StartWorker(); return SRSRAN_SUCCESS; } void NRScopeWorker::StartWorker(){ - std::thread worker_thread {&NRScopeWorker::Run, this}; + // std::cout << "Creating the thread. " << std::endl; + worker_thread = std::thread{&NRScopeWorker::Run, this}; + worker_thread.detach(); +} + +void NRScopeWorker::CopySlotandBuffer(srsran_slot_cfg_t* slot_, + cf_t* rx_buffer_) { + slot = *slot_; + srsran_vec_cf_copy(rx_buffer, rx_buffer_, worker_state.slot_sz); } int NRScopeWorker::InitSIBDecoder(){ /* Will always be called before any tasks */ - if(sibs_decoder.sib_decoder_and_reception_init(&worker_state, + if(sibs_decoder.SIBDecoderandReceptionInit(&worker_state, rf_buffer_t.to_cf_t()) < SRSASN_SUCCESS){ return NR_FAILURE; } return SRSRAN_SUCCESS; } +int NRScopeWorker::InitRACHDecoder() { + // std::thread rach_init_thread {&RachDecoder::rach_decoder_init, &rach_decoder, task_scheduler_nrscope.sib1, args_t.base_carrier}; + rach_decoder.RACHDecoderInit(&task_scheduler_nrscope); + srsran::rf_buffer_t rf_buffer_wrapper(rx_buffer, pre_resampling_sf_sz); + if(rach_decoder.rach_reception_init(arg_scs, &task_scheduler_nrscope, rf_buffer_wrapper.to_cf_t()) < SRSASN_SUCCESS){ + ERROR("RACHDecoder Init Error"); + return NR_FAILURE; + } + std::cout << "RACH Decoder Initialized.." << std::endl; + task_scheduler_nrscope.rach_inited = true; + return SRSRAN_SUCCESS; +} + +int NRScopeWorker::SyncState(WorkState* task_scheduler_state) { + + worker_state.args_t = task_scheduler_state->args_t; + worker_state.cell = task_scheduler_state->cell; + worker_state.cs_ret = task_scheduler_state->cs_ret; + memcpy(&worker_state.srsran_searcher_cfg_t, + &task_scheduler_state->srsran_searcher_cfg_t, + sizeof(srsue::nr::cell_search::cfg_t)); + worker_state.coreset0_args_t = task_scheduler_state->coreset0_args_t; + memcpy(&worker_state.coreset0_t, &task_scheduler_state->coreset0_t, + sizeof(srsran_coreset_t)); + + worker_state.arg_scs = task_scheduler_state->arg_scs; + + worker_state.sib1 = task_scheduler_state->sib1; + worker_state.sibs.resize(task_scheduler_state->sibs.size()); + for(long unsigned int i = 0; i < task_scheduler_state->sibs.size(); i++) { + worker_state.sibs[i] = task_scheduler_state->sibs[i]; + } + + worker_state.found_sib.resize(task_scheduler_state->found_sib.size()); + for(long unsigned int i = 0; i < task_scheduler_state->found_sib.size(); i++){ + worker_state.found_sib[i] = task_scheduler_state->found_sib[i]; + } + + worker_state.rrc_setup = task_scheduler_state->rrc_setup; + worker_state.master_cell_group = task_scheduler_state->master_cell_group; + worker_state.rrc_recfg = task_scheduler_state->rrc_recfg; + + /* SIB 1 decoded, we can start the RACH thread */ + worker_state.sib1_found = task_scheduler_state->sib1_found; + worker_state.rach_found = task_scheduler_state->rach_found; + + worker_state.sibs_vec_inited = task_scheduler_state->sibs_vec_inited; + worker_state.all_sibs_found = task_scheduler_state->all_sibs_found; + + if (!worker_state.sib1_inited && task_scheduler_state->sib1_inited) { + InitSIBDecoder(); + worker_state.sib1_inited = task_scheduler_state->sib1_inited; + } + + return SRSRAN_SUCCESS; + + // if (!worker_state.rach_inited && task_scheduler_state->rach_inited) { + // if (srsran_unlikely(!worker_state.sib1_found)) { + // /* Error happens */ + // ERROR("SIB 1 is not found while trying to init RACH decoder."); + // return NR_FAILURE; + // } + // InitRACHDecoder(); + // worker_state.rach_inited = task_scheduler_state->rach_inited; + // } + + // bool dci_inited; // DCIDecoder is initialized. + + // uint32_t nof_known_rntis; + // std::vector known_rntis; + + /* Below this, these variables go to the result structure. */ + // std::vector nof_sharded_rntis; + // std::vector > sharded_rntis; + // std::vector sharded_results; + // uint32_t nof_threads; + // uint32_t nof_rnti_worker_groups; + // uint8_t nof_bwps; + + // std::vector dl_prb_rate; + // std::vector ul_prb_rate; + // std::vector dl_prb_bits_rate; + // std::vector ul_prb_bits_rate; + + // uint32_t new_rnti_number; + // std::vector new_rntis_found; +} + void NRScopeWorker::Run() { while (true) { /* When there is a job, the semaphore is set and buffer is copied */ sem_wait(&smph_has_job); + lock.lock(); + busy = true; + lock.unlock(); /* If we accidentally assign the job without initializing the SIB decoder */ if(!worker_state.sib1_inited){ @@ -70,43 +171,45 @@ void NRScopeWorker::Run() { std::thread sibs_thread; /* If sib1 is not found, we run the sibs_thread; if it's found, we skip. */ if (!worker_state.sib1_found) { - sibs_thread = std::thread {&SIBsDecoder::decode_and_parse_sib1_from_slot, - &sibs_decoder, &slot, &sibs_vec_inited, &all_sibs_found, found_sib, - sibs, &sib1}; + sibs_thread = std::thread {&SIBsDecoder::DecodeandParseSIB1fromSlot, + &sibs_decoder, &slot, worker_state}; } - std::thread rach_thread {&RachDecoder::decode_and_parse_msg4_from_slot, - &rach_decoder, &slot, sib1_found, rach_inited, &rrc_setup, - &master_cell_group, &rach_found, &new_rnti_number, &new_rntis_found}; - - std::vector dci_threads; - if(dci_inited){ - for (uint32_t i = 0; i < nof_threads; i++){ - dci_threads.emplace_back(&DCIDecoder::decode_and_parse_dci_from_slot, - dci_decoders[i].get(), &slot, nof_known_rntis, nof_rnti_worker_groups, - sharded_results, sharded_rntis, nof_sharded_rntis, known_rntis, - dl_prb_rate, dl_prb_bits_rate, ul_prb_rate, ul_prb_bits_rate); - } - } + // std::thread rach_thread {&RachDecoder::decode_and_parse_msg4_from_slot, + // &rach_decoder, &slot, sib1_found, rach_inited, &rrc_setup, + // &master_cell_group, &rach_found, &new_rnti_number, &new_rntis_found}; + + // std::vector dci_threads; + // if(dci_inited){ + // for (uint32_t i = 0; i < nof_threads; i++){ + // dci_threads.emplace_back(&DCIDecoder::decode_and_parse_dci_from_slot, + // dci_decoders[i].get(), &slot, nof_known_rntis, nof_rnti_worker_groups, + // sharded_results, sharded_rntis, nof_sharded_rntis, known_rntis, + // dl_prb_rate, dl_prb_bits_rate, ul_prb_rate, ul_prb_bits_rate); + // } + // } if(sibs_thread.joinable()){ sibs_thread.join(); } - if(rach_thread.joinable()){ - rach_thread.join(); - } + // if(rach_thread.joinable()){ + // rach_thread.join(); + // } - if(dci_inited){ - for (uint32_t i = 0; i < nof_threads; i++){ - if(dci_threads[i].joinable()){ - dci_threads[i].join(); - } - } - } + // if(dci_inited){ + // for (uint32_t i = 0; i < worker_state.nof_threads; i++){ + // if(dci_threads[i].joinable()){ + // dci_threads[i].join(); + // } + // } + // } /* TODO: Post result to a global result queue */ + lock.lock(); + busy = false; + lock.unlock(); } } } \ No newline at end of file diff --git a/nrscope/src/libs/rach_decoder.cc b/nrscope/src/libs/rach_decoder.cc index b6239462..472f0238 100644 --- a/nrscope/src/libs/rach_decoder.cc +++ b/nrscope/src/libs/rach_decoder.cc @@ -9,7 +9,8 @@ RachDecoder::RachDecoder(){ prach = {}; prach_cfg = {}; - dci_rach = (srsran_dci_dl_nr_t*) malloc(sizeof(srsran_dci_dl_nr_t) * (SRSRAN_MAX_DCI_MSG_NR)); + dci_rach = (srsran_dci_dl_nr_t*) malloc(sizeof(srsran_dci_dl_nr_t) * + (SRSRAN_MAX_DCI_MSG_NR)); data_pdcch = srsran_vec_u8_malloc(SRSRAN_SLOT_MAX_NOF_BITS_NR); if (data_pdcch == NULL) { @@ -21,12 +22,12 @@ RachDecoder::~RachDecoder(){ } -int RachDecoder::rach_decoder_init(asn1::rrc_nr::sib1_s sib1_, - srsran_carrier_nr_t base_carrier_){ - sib1 = sib1_; - base_carrier = base_carrier_; +int RachDecoder::RACHDecoderInit(WorkState state){ + sib1 = state.sib1; + base_carrier = state.args_t.base_carrier; srsran::srsran_band_helper bands; - uint16_t band = bands.get_band_from_dl_freq_Hz(base_carrier.dl_center_frequency_hz); + uint16_t band = + bands.get_band_from_dl_freq_Hz(base_carrier.dl_center_frequency_hz); uint32_t cfg_idx = sib1.serving_cell_cfg_common.ul_cfg_common. init_ul_bwp.rach_cfg_common.setup().rach_cfg_generic.prach_cfg_idx; @@ -42,34 +43,45 @@ int RachDecoder::rach_decoder_init(asn1::rrc_nr::sib1_s sib1_, sul_idx = 1; } t_idx.reserve(prach_cfg_nr.nof_subframe_number); - ra_rnti = (uint16_t*) malloc(prach_cfg_nr.nof_subframe_number * sizeof(uint16_t)); + ra_rnti = (uint16_t*) malloc(prach_cfg_nr.nof_subframe_number * + sizeof(uint16_t)); // ra_rnti.reserve(prach_cfg_nr.nof_subframe_number); nof_ra_rnti = prach_cfg_nr.nof_subframe_number; - // printf("rach_uplink.prach_cfg_nr.nof_subframe_number %u\n", prach_cfg_nr.nof_subframe_number); + // printf("rach_uplink.prach_cfg_nr.nof_subframe_number %u\n", + // prach_cfg_nr.nof_subframe_number); // Set the config for prach_cfg prach_cfg.is_nr = true; prach_cfg.config_idx = cfg_idx; - if(sib1.serving_cell_cfg_common.ul_cfg_common.init_ul_bwp.rach_cfg_common.setup().prach_root_seq_idx.type() == 0) { + if(sib1.serving_cell_cfg_common.ul_cfg_common.init_ul_bwp.rach_cfg_common. + setup().prach_root_seq_idx.type() == 0) { // 0 as l839 and 1 as l139, check /lib/include/srsran/asn1/rrc_nr.h - prach_cfg.root_seq_idx = sib1.serving_cell_cfg_common.ul_cfg_common.init_ul_bwp. - rach_cfg_common.setup().prach_root_seq_idx.l839(); - for(uint32_t t_idx_id = 0; t_idx_id < prach_cfg_nr.nof_subframe_number; t_idx_id++){ + prach_cfg.root_seq_idx = sib1.serving_cell_cfg_common.ul_cfg_common. + init_ul_bwp.rach_cfg_common.setup().prach_root_seq_idx.l839(); + for(uint32_t t_idx_id = 0; t_idx_id < prach_cfg_nr.nof_subframe_number; + t_idx_id++){ t_idx[t_idx_id] = prach_cfg_nr.subframe_number[t_idx_id]; } - }else if(sib1.serving_cell_cfg_common.ul_cfg_common.init_ul_bwp.rach_cfg_common.setup().prach_root_seq_idx.type() == 1) { + }else if(sib1.serving_cell_cfg_common.ul_cfg_common.init_ul_bwp. + rach_cfg_common.setup().prach_root_seq_idx.type() == 1) { // 0 as l839 and 1 as l139, check /lib/include/srsran/asn1/rrc_nr.h - t_idx.reserve(prach_cfg_nr.nof_subframe_number * SRSRAN_NSLOTS_PER_SF_NR(base_carrier.scs)); - ra_rnti = (uint16_t*) malloc(prach_cfg_nr.nof_subframe_number * SRSRAN_NSLOTS_PER_SF_NR(base_carrier.scs) * sizeof(uint16_t)); + t_idx.reserve(prach_cfg_nr.nof_subframe_number * + SRSRAN_NSLOTS_PER_SF_NR(base_carrier.scs)); + ra_rnti = (uint16_t*) malloc(prach_cfg_nr.nof_subframe_number * + SRSRAN_NSLOTS_PER_SF_NR(base_carrier.scs) * sizeof(uint16_t)); // ra_rnti.reserve(prach_cfg_nr.nof_subframe_number * SRSRAN_NSLOTS_PER_SF_NR(carrier_input.scs)); - nof_ra_rnti = prach_cfg_nr.nof_subframe_number * SRSRAN_NSLOTS_PER_SF_NR(base_carrier.scs); - prach_cfg.root_seq_idx = sib1.serving_cell_cfg_common.ul_cfg_common.init_ul_bwp. - rach_cfg_common.setup().prach_root_seq_idx.l139(); - for(uint32_t t_idx_id = 0; t_idx_id < prach_cfg_nr.nof_subframe_number; t_idx_id++){ - for(uint32_t slot_idx = 0; slot_idx < SRSRAN_NSLOTS_PER_SF_NR(base_carrier.scs); slot_idx++){ + nof_ra_rnti = prach_cfg_nr.nof_subframe_number * + SRSRAN_NSLOTS_PER_SF_NR(base_carrier.scs); + prach_cfg.root_seq_idx = sib1.serving_cell_cfg_common.ul_cfg_common. + init_ul_bwp.rach_cfg_common.setup().prach_root_seq_idx.l139(); + for(uint32_t t_idx_id = 0; t_idx_id < prach_cfg_nr.nof_subframe_number; + t_idx_id++){ + for(uint32_t slot_idx = 0; + slot_idx < SRSRAN_NSLOTS_PER_SF_NR(base_carrier.scs); slot_idx++){ t_idx[t_idx_id*SRSRAN_NSLOTS_PER_SF_NR(base_carrier.scs) + slot_idx] = - prach_cfg_nr.subframe_number[t_idx_id] * SRSRAN_NSLOTS_PER_SF_NR(base_carrier.scs) + slot_idx; + prach_cfg_nr.subframe_number[t_idx_id] * + SRSRAN_NSLOTS_PER_SF_NR(base_carrier.scs) + slot_idx; // printf("prach_cfg_nr.subframe_number[t_idx_id] * SRSRAN_NSLOTS_PER_SF_NR(carrier_input.scs) + slot_idx: %u\n", prach_cfg_nr.subframe_number[t_idx_id] * SRSRAN_NSLOTS_PER_SF_NR(base_carrier.scs) + slot_idx); } } @@ -85,13 +97,16 @@ int RachDecoder::rach_decoder_init(asn1::rrc_nr::sib1_s sib1_, prach_cfg.tdd_config.configured = true; } - // See 38.321, 5.1.3 - Random Access Preamble transmission. - // RA-RNTI = 1 + s_id + 14 × t_id + 14 × 80 × f_id + 14 × 80 × 8 × ul_carrier_id. - // s_id = index of the first OFDM symbol of the (first, for short formats) PRACH occasion (0 <= s_id < 14). - // t_id = index of the first slot of the PRACH occasion in a system frame (0 <= t_id < 80); the numerology of - // reference for t_id is 15kHz for long PRACH Formats, regardless of the SCS common; whereas, for short PRACH formats, - // it coincides with SCS common (this can be inferred from Section 5.1.3, TS 38.321, and from Section 5.3.2, - // TS 38.211). + /* See 38.321, 5.1.3 - Random Access Preamble transmission. + RA-RNTI = 1 + s_id + 14 × t_id + 14 × 80 × f_id + 14 × 80 × 8 × ul_carrier_id. + s_id = index of the first OFDM symbol of the (first, for short formats) + PRACH occasion (0 <= s_id < 14). + t_id = index of the first slot of the PRACH occasion in a system frame + (0 <= t_id < 80); the numerology of + reference for t_id is 15kHz for long PRACH Formats, regardless of the SCS + common; whereas, for short PRACH formats, + it coincides with SCS common (this can be inferred from Section 5.1.3, + TS 38.321, and from Section 5.3.2, TS 38.211). */ // f_id = index of the PRACH occation in the freq domain (0 <= f_id < 8). // ul_carrier_id = 0 for NUL and 1 for SUL carrier. // printf("nof_ra_rnti: %u\n", nof_ra_rnti); @@ -106,15 +121,9 @@ int RachDecoder::rach_decoder_init(asn1::rrc_nr::sib1_s sib1_, return SRSRAN_SUCCESS; } -int RachDecoder::rach_reception_init(srsran_ue_dl_nr_sratescs_info arg_scs_, - srsran_coreset_t* coreset0_t_, - srsran_carrier_nr_t* base_carrier_, - cell_search_result_t cell_, - double ssb_freq_hz_, - srsran_subcarrier_spacing_t ssb_scs_, - coreset0_args coreset0_args_t, - cf_t* input[SRSRAN_MAX_PORTS]){ - memcpy(&coreset0_t, coreset0_t_, sizeof(srsran_coreset_t)); +int RachDecoder::RACHReceptionInit(WorkState* state, + cf_t* input[SRSRAN_MAX_PORTS]){ + memcpy(&coreset0_t, &state->coreset0_t, sizeof(srsran_coreset_t)); dci_cfg.bwp_dl_initial_bw = 275; dci_cfg.bwp_ul_initial_bw = 275; @@ -135,7 +144,8 @@ int RachDecoder::rach_reception_init(srsran_ue_dl_nr_sratescs_info arg_scs_, search_space->formats[0] = srsran_dci_format_nr_1_0; search_space->nof_formats = 1; for (uint32_t L = 0; L < SRSRAN_SEARCH_SPACE_NOF_AGGREGATION_LEVELS_NR; L++) { - search_space->nof_candidates[L] = srsran_pdcch_nr_max_candidates_coreset(&coreset0_t, L); + search_space->nof_candidates[L] = + srsran_pdcch_nr_max_candidates_coreset(&coreset0_t, L); } pdcch_cfg.coreset[0] = coreset0_t; @@ -148,37 +158,53 @@ int RachDecoder::rach_reception_init(srsran_ue_dl_nr_sratescs_info arg_scs_, pdcch_cfg.coreset[0] = coreset0_t; - pdcch_cfg.search_space[0].nof_candidates[0] = sib1.serving_cell_cfg_common.dl_cfg_common. - init_dl_bwp.pdcch_cfg_common.setup().common_search_space_list[0]. - nrof_candidates.aggregation_level1; - pdcch_cfg.search_space[0].nof_candidates[1] = sib1.serving_cell_cfg_common.dl_cfg_common. - init_dl_bwp.pdcch_cfg_common.setup().common_search_space_list[0]. - nrof_candidates.aggregation_level2; - pdcch_cfg.search_space[0].nof_candidates[2] = sib1.serving_cell_cfg_common.dl_cfg_common. - init_dl_bwp.pdcch_cfg_common.setup().common_search_space_list[0]. - nrof_candidates.aggregation_level4; - pdcch_cfg.search_space[0].nof_candidates[3] = sib1.serving_cell_cfg_common.dl_cfg_common. - init_dl_bwp.pdcch_cfg_common.setup().common_search_space_list[0]. - nrof_candidates.aggregation_level8; - pdcch_cfg.search_space[0].nof_candidates[4] = sib1.serving_cell_cfg_common.dl_cfg_common. - init_dl_bwp.pdcch_cfg_common.setup().common_search_space_list[0]. - nrof_candidates.aggregation_level16; - - arg_scs = arg_scs_; - memcpy(&base_carrier, base_carrier_, sizeof(srsran_carrier_nr_t)); - cell = cell_; + pdcch_cfg.search_space[0].nof_candidates[0] = + sib1.serving_cell_cfg_common.dl_cfg_common. + init_dl_bwp.pdcch_cfg_common.setup().common_search_space_list[0]. + nrof_candidates.aggregation_level1; + pdcch_cfg.search_space[0].nof_candidates[1] = + sib1.serving_cell_cfg_common.dl_cfg_common. + init_dl_bwp.pdcch_cfg_common.setup().common_search_space_list[0]. + nrof_candidates.aggregation_level2; + pdcch_cfg.search_space[0].nof_candidates[2] = + sib1.serving_cell_cfg_common.dl_cfg_common. + init_dl_bwp.pdcch_cfg_common.setup().common_search_space_list[0]. + nrof_candidates.aggregation_level4; + pdcch_cfg.search_space[0].nof_candidates[3] = + sib1.serving_cell_cfg_common.dl_cfg_common. + init_dl_bwp.pdcch_cfg_common.setup().common_search_space_list[0]. + nrof_candidates.aggregation_level8; + pdcch_cfg.search_space[0].nof_candidates[4] = + sib1.serving_cell_cfg_common.dl_cfg_common. + init_dl_bwp.pdcch_cfg_common.setup().common_search_space_list[0]. + nrof_candidates.aggregation_level16; + + arg_scs = state->arg_scs; + memcpy(&base_carrier, &state->args_t.base_carrier, sizeof(srsran_carrier_nr_t)); + cell = state->cell; pdsch_hl_cfg.typeA_pos = cell.mib.dmrs_typeA_pos; - for (uint32_t pdsch_time_id = 0; pdsch_time_id < sib1.serving_cell_cfg_common.dl_cfg_common.init_dl_bwp.pdsch_cfg_common.setup().pdsch_time_domain_alloc_list.size(); pdsch_time_id++){ - if(sib1.serving_cell_cfg_common.dl_cfg_common.init_dl_bwp.pdsch_cfg_common.setup().pdsch_time_domain_alloc_list[pdsch_time_id].k0_present){ - pdsch_hl_cfg.common_time_ra[pdsch_time_id].k = sib1.serving_cell_cfg_common.dl_cfg_common.init_dl_bwp.pdsch_cfg_common.setup().pdsch_time_domain_alloc_list[pdsch_time_id].k0; + for (uint32_t pdsch_time_id = 0; pdsch_time_id < + sib1.serving_cell_cfg_common.dl_cfg_common.init_dl_bwp.pdsch_cfg_common. + setup().pdsch_time_domain_alloc_list.size(); pdsch_time_id++){ + if(sib1.serving_cell_cfg_common.dl_cfg_common.init_dl_bwp.pdsch_cfg_common. + setup().pdsch_time_domain_alloc_list[pdsch_time_id].k0_present){ + pdsch_hl_cfg.common_time_ra[pdsch_time_id].k = + sib1.serving_cell_cfg_common.dl_cfg_common.init_dl_bwp.pdsch_cfg_common. + setup().pdsch_time_domain_alloc_list[pdsch_time_id].k0; } - pdsch_hl_cfg.common_time_ra[pdsch_time_id].sliv = sib1.serving_cell_cfg_common.dl_cfg_common.init_dl_bwp.pdsch_cfg_common.setup().pdsch_time_domain_alloc_list[pdsch_time_id].start_symbol_and_len; - switch(sib1.serving_cell_cfg_common.dl_cfg_common.init_dl_bwp.pdsch_cfg_common.setup().pdsch_time_domain_alloc_list[pdsch_time_id].map_type){ + pdsch_hl_cfg.common_time_ra[pdsch_time_id].sliv = sib1. + serving_cell_cfg_common.dl_cfg_common.init_dl_bwp.pdsch_cfg_common. + setup().pdsch_time_domain_alloc_list[pdsch_time_id].start_symbol_and_len; + switch(sib1.serving_cell_cfg_common.dl_cfg_common.init_dl_bwp. + pdsch_cfg_common.setup().pdsch_time_domain_alloc_list[pdsch_time_id]. + map_type){ case asn1::rrc_nr::pdsch_time_domain_res_alloc_s::map_type_e_::type_a: - pdsch_hl_cfg.common_time_ra[pdsch_time_id].mapping_type = srsran_sch_mapping_type_A; + pdsch_hl_cfg.common_time_ra[pdsch_time_id].mapping_type = + srsran_sch_mapping_type_A; break; case asn1::rrc_nr::pdsch_time_domain_res_alloc_s::map_type_e_::type_b: - pdsch_hl_cfg.common_time_ra[pdsch_time_id].mapping_type = srsran_sch_mapping_type_B; + pdsch_hl_cfg.common_time_ra[pdsch_time_id].mapping_type = + srsran_sch_mapping_type_B; break; case asn1::rrc_nr::pdsch_time_domain_res_alloc_s::map_type_e_::nulltype: break; @@ -186,7 +212,8 @@ int RachDecoder::rach_reception_init(srsran_ue_dl_nr_sratescs_info arg_scs_, break; } } - pdsch_hl_cfg.nof_common_time_ra = sib1.serving_cell_cfg_common.dl_cfg_common.init_dl_bwp.pdsch_cfg_common.setup().pdsch_time_domain_alloc_list.size(); + pdsch_hl_cfg.nof_common_time_ra = sib1.serving_cell_cfg_common.dl_cfg_common. + init_dl_bwp.pdsch_cfg_common.setup().pdsch_time_domain_alloc_list.size(); ue_dl_args.nof_rx_antennas = 1; ue_dl_args.pdsch.sch.disable_simd = false; @@ -211,8 +238,8 @@ int RachDecoder::rach_reception_init(srsran_ue_dl_nr_sratescs_info arg_scs_, return SRSRAN_ERROR; } - if (srsran_softbuffer_rx_init_guru(&softbuffer, SRSRAN_SCH_NR_MAX_NOF_CB_LDPC, SRSRAN_LDPC_MAX_LEN_ENCODED_CB) < - SRSRAN_SUCCESS) { + if (srsran_softbuffer_rx_init_guru(&softbuffer, SRSRAN_SCH_NR_MAX_NOF_CB_LDPC, + SRSRAN_LDPC_MAX_LEN_ENCODED_CB) < SRSRAN_SUCCESS) { ERROR("RACHDecoder -- Error init soft-buffer"); return SRSRAN_ERROR; } @@ -220,17 +247,22 @@ int RachDecoder::rach_reception_init(srsran_ue_dl_nr_sratescs_info arg_scs_, pdsch_carrier = base_carrier; arg_scs_pdsch = arg_scs; - double pointA = ssb_freq_hz_ - (SRSRAN_SSB_BW_SUBC / 2) * - cell.abs_ssb_scs - cell.k_ssb * SRSRAN_SUBC_SPACING_NR(srsran_subcarrier_spacing_15kHz) - - sib1.serving_cell_cfg_common.dl_cfg_common.freq_info_dl.offset_to_point_a * - SRSRAN_SUBC_SPACING_NR(srsran_subcarrier_spacing_15kHz) * NRSCOPE_NSC_PER_RB_NR; - - pdsch_carrier.nof_prb = sib1.serving_cell_cfg_common.dl_cfg_common.freq_info_dl.scs_specific_carrier_list[0].carrier_bw; - double dl_center_frequency = pointA + pdsch_carrier.nof_prb * NRSCOPE_NSC_PER_RB_NR * SRSRAN_SUBC_SPACING_NR(ssb_scs_) / 2; + double pointA = state->srsran_searcher_cfg_t.ssb_freq_hz - + (SRSRAN_SSB_BW_SUBC / 2) * cell.abs_ssb_scs - cell.k_ssb * + SRSRAN_SUBC_SPACING_NR(srsran_subcarrier_spacing_15kHz) - + sib1.serving_cell_cfg_common.dl_cfg_common.freq_info_dl.offset_to_point_a * + SRSRAN_SUBC_SPACING_NR(srsran_subcarrier_spacing_15kHz) * + NRSCOPE_NSC_PER_RB_NR; + + pdsch_carrier.nof_prb = sib1.serving_cell_cfg_common.dl_cfg_common. + freq_info_dl.scs_specific_carrier_list[0].carrier_bw; + double dl_center_frequency = pointA + pdsch_carrier.nof_prb * + NRSCOPE_NSC_PER_RB_NR * SRSRAN_SUBC_SPACING_NR(state->args_t.ssb_scs) / 2; std::cout << "dl_center_frequency: " << dl_center_frequency << std::endl; std::cout << "pointA: " << pointA << std::endl; - arg_scs_pdsch.coreset_offset_scs = (ssb_freq_hz_ - dl_center_frequency) / cell.abs_pdcch_scs; + arg_scs_pdsch.coreset_offset_scs = (state->srsran_searcher_cfg_t.ssb_freq_hz - + dl_center_frequency) / cell.abs_pdcch_scs; // The lower boundary of PDSCH can be not aligned with the lower boundary of PDCCH if (srsran_ue_dl_nr_init_nrscope(&ue_dl_pdsch, input, &ue_dl_args, arg_scs_pdsch)) { @@ -243,7 +275,8 @@ int RachDecoder::rach_reception_init(srsran_ue_dl_nr_sratescs_info arg_scs_, return SRSRAN_ERROR; } - start_rb = (coreset0_args_t.coreset0_lower_freq_hz - pointA) / SRSRAN_SUBC_SPACING_NR(arg_scs_pdsch.scs) / 12; + start_rb = (state->coreset0_args_t.coreset0_lower_freq_hz - pointA) / + SRSRAN_SUBC_SPACING_NR(arg_scs_pdsch.scs) / 12; if (srsran_ue_dl_nr_set_pdcch_config(&ue_dl_pdsch, &pdcch_cfg, &dci_cfg)) { ERROR("Error setting CORESET"); @@ -254,17 +287,18 @@ int RachDecoder::rach_reception_init(srsran_ue_dl_nr_sratescs_info arg_scs_, } -int RachDecoder::decode_and_parse_msg4_from_slot(srsran_slot_cfg_t* slot, - bool sib1_found, - bool rach_inited, - asn1::rrc_nr::rrc_setup_s* rrc_setup, - asn1::rrc_nr::cell_group_cfg_s* master_cell_group, - bool* rach_found, - uint32_t* new_rnti_number, - std::vector& new_rntis_found){ +int RachDecoder::DecodeandParseMS4fromSlot(srsran_slot_cfg_t* slot, + bool sib1_found, + bool rach_inited, + asn1::rrc_nr::rrc_setup_s* rrc_setup, + asn1::rrc_nr::cell_group_cfg_s* master_cell_group, + bool* rach_found, + uint32_t* new_rnti_number, + std::vector& new_rntis_found){ if(!sib1_found or !rach_inited){ // If the SIB 1 is not detected or the RACH decoder is not initialized. - std::cout << "SIB 1 not found or decoder not initialized, quitting..." << std::endl; + std::cout << "SIB 1 not found or decoder not initialized, quitting..." + << std::endl; return SRSRAN_SUCCESS; } @@ -279,7 +313,8 @@ int RachDecoder::decode_and_parse_msg4_from_slot(srsran_slot_cfg_t* slot, srsran_ue_dl_nr_estimate_fft_nrscope(&ue_dl_rach, slot, arg_scs); srsran_ue_dl_nr_estimate_fft_nrscope(&ue_dl_pdsch, slot, arg_scs_pdsch); - int nof_found_dci = srsran_ue_dl_nr_find_dl_dci_nrscope(&ue_dl_rach, slot, ra_rnti, nof_ra_rnti, srsran_rnti_type_tc, dci_rach, 4); + int nof_found_dci = srsran_ue_dl_nr_find_dl_dci_nrscope(&ue_dl_rach, + slot, ra_rnti, nof_ra_rnti, srsran_rnti_type_tc, dci_rach, 4); if (nof_found_dci < SRSRAN_SUCCESS) { ERROR("RACHDecoder -- Error in blind search"); @@ -311,15 +346,16 @@ int RachDecoder::decode_and_parse_msg4_from_slot(srsran_slot_cfg_t* slot, for (int dci_id = 0; dci_id < nof_found_dci; dci_id++){ char str[1024] = {}; - srsran_dci_dl_nr_to_str(&(ue_dl_rach.dci), &dci_rach[dci_id], str, (uint32_t)sizeof(str)); + srsran_dci_dl_nr_to_str(&(ue_dl_rach.dci), &dci_rach[dci_id], str, + (uint32_t)sizeof(str)); printf("RACHDecoder -- Found DCI: %s\n", str); tc_rnti = dci_rach[dci_id].ctx.rnti; srsran_sch_cfg_nr_t pdsch_cfg = {}; dci_rach[dci_id].ctx.coreset_start_rb = start_rb; - if (srsran_ra_dl_dci_to_grant_nr(&pdsch_carrier, slot, &pdsch_hl_cfg, &dci_rach[dci_id], &pdsch_cfg, &pdsch_cfg.grant) < - SRSRAN_SUCCESS) { + if (srsran_ra_dl_dci_to_grant_nr(&pdsch_carrier, slot, &pdsch_hl_cfg, + &dci_rach[dci_id], &pdsch_cfg, &pdsch_cfg.grant) < SRSRAN_SUCCESS) { ERROR("RACHDecoder -- Error decoding PDSCH search"); return SRSRAN_ERROR; } @@ -327,7 +363,8 @@ int RachDecoder::decode_and_parse_msg4_from_slot(srsran_slot_cfg_t* slot, srsran_sch_cfg_nr_info(&pdsch_cfg, str, (uint32_t)sizeof(str)); printf("PDSCH_cfg:\n%s", str); - if (srsran_softbuffer_rx_init_guru(&softbuffer, SRSRAN_SCH_NR_MAX_NOF_CB_LDPC, SRSRAN_LDPC_MAX_LEN_ENCODED_CB) < + if (srsran_softbuffer_rx_init_guru(&softbuffer, + SRSRAN_SCH_NR_MAX_NOF_CB_LDPC, SRSRAN_LDPC_MAX_LEN_ENCODED_CB) < SRSRAN_SUCCESS) { ERROR("Error init soft-buffer"); return SRSRAN_ERROR; @@ -344,7 +381,8 @@ int RachDecoder::decode_and_parse_msg4_from_slot(srsran_slot_cfg_t* slot, pdsch_res.tb[0].payload = data_pdcch; // Decode PDSCH - if (srsran_ue_dl_nr_decode_pdsch(&ue_dl_pdsch, slot, &pdsch_cfg, &pdsch_res) < SRSRAN_SUCCESS) { + if (srsran_ue_dl_nr_decode_pdsch(&ue_dl_pdsch, slot, &pdsch_cfg, &pdsch_res) + < SRSRAN_SUCCESS) { printf("Error decoding PDSCH search\n"); return SRSRAN_ERROR; } @@ -353,8 +391,10 @@ int RachDecoder::decode_and_parse_msg4_from_slot(srsran_slot_cfg_t* slot, // srsran_vec_fprint_byte(stdout, pdsch_res.tb[0].payload, pdsch_cfg.grant.tb[0].tbs / 8); uint32_t bytes_offset = 0; - for (uint32_t pdsch_res_idx = 0; pdsch_res_idx < (uint32_t)pdsch_cfg.grant.tb[0].tbs / 8 - 1; pdsch_res_idx ++){ - if(pdsch_res.tb[0].payload[pdsch_res_idx] == 0x20 && pdsch_res.tb[0].payload[pdsch_res_idx+1] == 0x40){ + for (uint32_t pdsch_res_idx = 0; pdsch_res_idx < + (uint32_t)pdsch_cfg.grant.tb[0].tbs / 8 - 1; pdsch_res_idx ++){ + if(pdsch_res.tb[0].payload[pdsch_res_idx] == 0x20 && pdsch_res.tb[0]. + payload[pdsch_res_idx+1] == 0x40){ bytes_offset = pdsch_res_idx; break; } @@ -388,10 +428,12 @@ int RachDecoder::decode_and_parse_msg4_from_slot(srsran_slot_cfg_t* slot, asn1::rrc_nr::dl_ccch_msg_s dlcch_msg; // What the first few bytes are? In srsgNB there are 10 extra bytes and for small cell there are 3 extra bytes // before the RRCSetup message. - asn1::cbit_ref dlcch_bref(pdsch_res.tb[0].payload + bytes_offset, pdsch_cfg.grant.tb[0].tbs / 8 - bytes_offset); + asn1::cbit_ref dlcch_bref(pdsch_res.tb[0].payload + bytes_offset, + pdsch_cfg.grant.tb[0].tbs / 8 - bytes_offset); asn1::SRSASN_CODE err = dlcch_msg.unpack(dlcch_bref); if (err != asn1::SRSASN_SUCCESS) { - ERROR("Failed to unpack DL-CCCH message (%d B)", pdsch_cfg.grant.tb[0].tbs / 8 - bytes_offset); + ERROR("Failed to unpack DL-CCCH message (%d B)", + pdsch_cfg.grant.tb[0].tbs / 8 - bytes_offset); } *rrc_setup = dlcch_msg.msg.c1().rrc_setup(); diff --git a/nrscope/src/libs/radio_nr.cc b/nrscope/src/libs/radio_nr.cc index 27b2f92c..84db1444 100644 --- a/nrscope/src/libs/radio_nr.cc +++ b/nrscope/src/libs/radio_nr.cc @@ -331,23 +331,29 @@ int Radio::RadioInitandStart(){ args_t.set_ssb_from_band(ssb_scs); args_t.base_carrier.scs = args_t.ssb_scs; if(args_t.duplex_mode == SRSRAN_DUPLEX_MODE_TDD){ - args_t.base_carrier.ul_center_frequency_hz = args_t.base_carrier.dl_center_frequency_hz; + args_t.base_carrier.ul_center_frequency_hz = + args_t.base_carrier.dl_center_frequency_hz; } - pre_resampling_slot_sz = (uint32_t)(rf_args.srate_hz / 1000.0f / SRSRAN_NOF_SLOTS_PER_SF_NR(ssb_scs)); + pre_resampling_slot_sz = (uint32_t)(rf_args.srate_hz / 1000.0f / + SRSRAN_NOF_SLOTS_PER_SF_NR(ssb_scs)); // Allocate receive buffer - slot_sz = (uint32_t)(rf_args.srsran_srate_hz / 1000.0f / SRSRAN_NOF_SLOTS_PER_SF_NR(ssb_scs)); - rx_buffer = srsran_vec_cf_malloc(SRSRAN_NOF_SLOTS_PER_SF_NR(args_t.ssb_scs) * pre_resampling_slot_sz * RING_BUF_SIZE); + slot_sz = (uint32_t)(rf_args.srsran_srate_hz / 1000.0f / + SRSRAN_NOF_SLOTS_PER_SF_NR(ssb_scs)); + rx_buffer = srsran_vec_cf_malloc(SRSRAN_NOF_SLOTS_PER_SF_NR(args_t.ssb_scs) * + pre_resampling_slot_sz * RING_BUF_SIZE); std::cout << "slot_sz: " << slot_sz << std::endl; - // std::cout << "rx_buffer size: " << SRSRAN_NOF_SLOTS_PER_SF_NR(args_t.ssb_scs) * slot_sz << std::endl; srsran_vec_zero(rx_buffer, SRSRAN_NOF_SLOTS_PER_SF_NR(args_t.ssb_scs) * slot_sz); - uint32_t actual_slot_szs[RESAMPLE_WORKER_NUM]; // the actual slot size after resampling + /* the actual slot size after resampling */ + uint32_t actual_slot_szs[RESAMPLE_WORKER_NUM]; // Allocate pre-resampling receive buffer - pre_resampling_rx_buffer = srsran_vec_cf_malloc(SRSRAN_NOF_SLOTS_PER_SF_NR(args_t.ssb_scs) * pre_resampling_slot_sz); + pre_resampling_rx_buffer = srsran_vec_cf_malloc( + SRSRAN_NOF_SLOTS_PER_SF_NR(args_t.ssb_scs) * pre_resampling_slot_sz); std::cout << "pre_resampling_slot_sz: " << pre_resampling_slot_sz << std::endl; - srsran_vec_zero(pre_resampling_rx_buffer, SRSRAN_NOF_SLOTS_PER_SF_NR(args_t.ssb_scs) * pre_resampling_slot_sz); + srsran_vec_zero(pre_resampling_rx_buffer, + SRSRAN_NOF_SLOTS_PER_SF_NR(args_t.ssb_scs) * pre_resampling_slot_sz); cs_args.center_freq_hz = args_t.base_carrier.dl_center_frequency_hz; cs_args.ssb_freq_hz = args_t.base_carrier.dl_center_frequency_hz; @@ -357,15 +363,20 @@ int Radio::RadioInitandStart(){ uint32_t ssb_scs_hz = SRSRAN_SUBC_SPACING_NR(cs_args.ssb_scs); double ssb_bw_hz = SRSRAN_SSB_BW_SUBC * ssb_scs_hz; - double ssb_center_freq_min_hz = args_t.base_carrier.dl_center_frequency_hz - (args_t.srate_hz * 0.7 - ssb_bw_hz) / 2.0; - double ssb_center_freq_max_hz = args_t.base_carrier.dl_center_frequency_hz + (args_t.srate_hz * 0.7 - ssb_bw_hz) / 2.0; - - uint32_t band = bands.get_band_from_dl_freq_Hz_and_scs(args_t.base_carrier.dl_center_frequency_hz, cs_args.ssb_scs); - srsran::srsran_band_helper::sync_raster_t ss = bands.get_sync_raster(band, cs_args.ssb_scs); + double ssb_center_freq_min_hz = args_t.base_carrier.dl_center_frequency_hz - + (args_t.srate_hz * 0.7 - ssb_bw_hz) / 2.0; + double ssb_center_freq_max_hz = args_t.base_carrier.dl_center_frequency_hz + + (args_t.srate_hz * 0.7 - ssb_bw_hz) / 2.0; + + uint32_t band = bands.get_band_from_dl_freq_Hz_and_scs( + args_t.base_carrier.dl_center_frequency_hz, cs_args.ssb_scs); + srsran::srsran_band_helper::sync_raster_t ss = bands.get_sync_raster( + band, cs_args.ssb_scs); srsran_assert(ss.valid(), "Invalid synchronization raster"); // initialize resampling tool - float r = (float)rf_args.srsran_srate_hz/(float)rf_args.srate_hz; // resampling rate (output/input) + // resampling rate (output/input) + float r = (float)rf_args.srsran_srate_hz/(float)rf_args.srate_hz; float As=60.0f; // resampling filter stop-band attenuation [dB] msresamp_crcf q[RESAMPLE_WORKER_NUM]; uint32_t temp_x_sz; @@ -379,13 +390,16 @@ int Radio::RadioInitandStart(){ float delay = resample_needed ? msresamp_crcf_get_delay(q[0]) : 0; // add a few zero padding - temp_x_sz = SRSRAN_NOF_SLOTS_PER_SF_NR(args_t.ssb_scs) * pre_resampling_slot_sz + (int)ceilf(delay) + 10; - temp_x = (std::complex *)malloc(temp_x_sz * sizeof(std::complex)); + temp_x_sz = SRSRAN_NOF_SLOTS_PER_SF_NR(args_t.ssb_scs) * + pre_resampling_slot_sz + (int)ceilf(delay) + 10; + temp_x = (std::complex *)malloc(temp_x_sz * + sizeof(std::complex)); // std::complex temp_x[temp_x_sz]; temp_y_sz = (uint32_t)(temp_x_sz * r * 2); for (uint8_t i = 0; i < RESAMPLE_WORKER_NUM; i++) { - temp_y[i] = (std::complex *)malloc(temp_y_sz * sizeof(std::complex)); + temp_y[i] = (std::complex *)malloc(temp_y_sz * + sizeof(std::complex)); } // std::complex temp_y[RESAMPLE_WORKER_NUM][temp_y_sz]; } @@ -409,30 +423,36 @@ int Radio::RadioInitandStart(){ task_scheduler_nrscope.InitandStart(nof_threads, nof_rnti_worker_groups, nof_bwps, args_t, nof_workers); + std::cout << "Task scheduler started..." << std::endl; while (not ss.end()) { // Get SSB center frequency cs_args.ssb_freq_hz = ss.get_frequency(); // Advance SSB frequency raster ss.next(); - // Calculate frequency offset between the base-band center frequency and the SSB absolute frequency - uint32_t offset_hz = (uint32_t)std::abs(std::round(cs_args.ssb_freq_hz - args_t.base_carrier.dl_center_frequency_hz)); + /* Calculate frequency offset between the base-band center frequency and + the SSB absolute frequency */ + uint32_t offset_hz = (uint32_t)std::abs(std::round(cs_args.ssb_freq_hz - + args_t.base_carrier.dl_center_frequency_hz)); // The SSB absolute frequency is invalid if it is outside the range and // the offset is NOT multiple of the subcarrier spacing - if ((cs_args.ssb_freq_hz < ssb_center_freq_min_hz) or (cs_args.ssb_freq_hz > ssb_center_freq_max_hz) or + if ((cs_args.ssb_freq_hz < ssb_center_freq_min_hz) or + (cs_args.ssb_freq_hz > ssb_center_freq_max_hz) or (offset_hz % ssb_scs_hz != 0)) { // Skip this frequency continue; } - // xuyang debug: skip all other nearby measure and just focus on the wanted SSB freq + /* xuyang debug: skip all other nearby measure and + just focus on the wanted SSB freq */ if (offset_hz > 1) { continue; } - srsran_searcher_cfg_t.srate_hz = args_t.srate_hz; // which is indeed the srsran srate - srsran_searcher_cfg_t.center_freq_hz = cs_args.ssb_freq_hz; //args_t.base_carrier.dl_center_frequency_hz; + /* which is indeed the srsran srate */ + srsran_searcher_cfg_t.srate_hz = args_t.srate_hz; + srsran_searcher_cfg_t.center_freq_hz = cs_args.ssb_freq_hz; srsran_searcher_cfg_t.ssb_freq_hz = cs_args.ssb_freq_hz; srsran_searcher_cfg_t.ssb_scs = args_t.ssb_scs; srsran_searcher_cfg_t.ssb_pattern = args_t.ssb_pattern; @@ -441,8 +461,8 @@ int Radio::RadioInitandStart(){ std::cout << "Searcher: failed to start cell search" << std::endl; return NR_FAILURE; } - // Set the searching frequency to ssb_freq - // Because the srsRAN implementation use the center_freq_hz for cell searching + /* Set the searching frequency to ssb_freq */ + /* Because the srsRAN implementation use the center_freq_hz for cell search */ cs_args.center_freq_hz = cs_args.ssb_freq_hz; // std::cout << cs_args.ssb_freq_hz << std::endl; args_t.base_carrier.ssb_center_freq_hz = cs_args.ssb_freq_hz; @@ -469,11 +489,13 @@ int Radio::RadioInitandStart(){ if (resample_needed) { // srsran_vec_fprint2_c(fp_time_series_pre_resample, pre_resampling_rx_buffer, pre_resampling_slot_sz); - copy_c_to_cpp_complex_arr_and_zero_padding(pre_resampling_rx_buffer, temp_x, pre_resampling_slot_sz, temp_x_sz); + copy_c_to_cpp_complex_arr_and_zero_padding(pre_resampling_rx_buffer, + temp_x, pre_resampling_slot_sz, temp_x_sz); uint32_t splitted_nx = pre_resampling_slot_sz / RESAMPLE_WORKER_NUM; std::vector ssb_scan_resample_threads; for (uint8_t k = 0; k < RESAMPLE_WORKER_NUM; k++) { - ssb_scan_resample_threads.emplace_back(&resample_partially, &q[k], temp_x, temp_y[k], k, splitted_nx, &actual_slot_szs[k]); + ssb_scan_resample_threads.emplace_back(&resample_partially, &q[k], + temp_x, temp_y[k], k, splitted_nx, &actual_slot_szs[k]); } // msresamp_crcf_execute(q, temp_x, pre_resampling_slot_sz, temp_y, &actual_slot_sz); @@ -493,7 +515,8 @@ int Radio::RadioInitandStart(){ // srsran_vec_fprint2_c(fp_time_series_post_resample, rx_buffer, actual_slot_sz); } else { // pre_resampling_slot_sz should be the same as slot_sz as resample ratio is 1 in this case - srsran_vec_cf_copy(rx_buffer, pre_resampling_rx_buffer, pre_resampling_slot_sz); + srsran_vec_cf_copy(rx_buffer, pre_resampling_rx_buffer, + pre_resampling_slot_sz); } *(last_rx_time.get_ptr(0)) = rf_timestamp.get(0); @@ -511,7 +534,7 @@ int Radio::RadioInitandStart(){ std::cout << "Decoding MIB..." << std::endl; /* And the states are updated in the task_scheduler*/ - if(task_scheduler_nrscope.decode_mib(&args_t, &cs_ret, + if(task_scheduler_nrscope.DecodeMIB(&args_t, &cs_ret, &srsran_searcher_cfg_t, r, rf_args.srate_hz) < SRSRAN_SUCCESS){ ERROR("Error init task scheduler"); return NR_FAILURE; @@ -539,7 +562,10 @@ int Radio::RadioInitandStart(){ return SRSRAN_SUCCESS; } -static int slot_sync_recv_callback(void* ptr, cf_t** buffer, uint32_t nsamples, srsran_timestamp_t* ts) +static int slot_sync_recv_callback(void* ptr, + cf_t** buffer, + uint32_t nsamples, + srsran_timestamp_t* ts) { if (ptr == nullptr) { return SRSRAN_ERROR_INVALID_INPUTS; @@ -560,14 +586,20 @@ static int slot_sync_recv_callback(void* ptr, cf_t** buffer, uint32_t nsamples, int Radio::SyncandDownlinkInit(){ //***** DL args Config Start *****// - rf_buffer_t = srsran::rf_buffer_t(rx_buffer, SRSRAN_NOF_SLOTS_PER_SF_NR(task_scheduler_nrscope.args_t.ssb_scs) * pre_resampling_slot_sz * 2); // only one sf here + rf_buffer_t = srsran::rf_buffer_t(rx_buffer, + SRSRAN_NOF_SLOTS_PER_SF_NR(task_scheduler_nrscope.task_scheduler_state.args_t.ssb_scs) * + pre_resampling_slot_sz * 2); // only one sf here // it appears the srsRAN is build on 15kHz scs, we need to use the srate and // scs to calculate the correct subframe size - arg_scs.srate = task_scheduler_nrscope.args_t.srate_hz; - arg_scs.scs = task_scheduler_nrscope.cell.mib.scs_common; - - arg_scs.coreset_offset_scs = (cs_args.ssb_freq_hz - task_scheduler_nrscope.coreset0_args_t.coreset0_center_freq_hz) / task_scheduler_nrscope.cell.abs_pdcch_scs;// + 12; - arg_scs.coreset_slot = (uint32_t)task_scheduler_nrscope.coreset0_args_t.n_0; + arg_scs.srate = task_scheduler_nrscope.task_scheduler_state.args_t.srate_hz; + arg_scs.scs = task_scheduler_nrscope.task_scheduler_state.cell.mib.scs_common; + + arg_scs.coreset_offset_scs = (cs_args.ssb_freq_hz - + task_scheduler_nrscope.task_scheduler_state.coreset0_args_t.coreset0_center_freq_hz) / + task_scheduler_nrscope.task_scheduler_state.cell.abs_pdcch_scs; // + 12; + arg_scs.coreset_slot = + (uint32_t)task_scheduler_nrscope.task_scheduler_state.coreset0_args_t.n_0; + task_scheduler_nrscope.task_scheduler_state.arg_scs = arg_scs; // arg_scs.phase_diff_first_second_half = 0; //***** DL args Config End *****// @@ -581,14 +613,15 @@ int Radio::SyncandDownlinkInit(){ ue_sync_nr_args.recv_obj = radio.get(); ue_sync_nr_args.recv_callback = slot_sync_recv_callback; - ue_sync_nr.resample_ratio = (float)rf_args.srsran_srate_hz/(float)rf_args.srate_hz; + ue_sync_nr.resample_ratio = (float)rf_args.srsran_srate_hz / + (float)rf_args.srate_hz; if (srsran_ue_sync_nr_init(&ue_sync_nr, &ue_sync_nr_args) < SRSRAN_SUCCESS) { std::cout << "Error initiating UE SYNC NR object" << std::endl; logger.error("Error initiating UE SYNC NR object"); return SRSRAN_ERROR; } // Be careful of all the frequency setting (SSB/center downlink and etc.)! - ssb_cfg.srate_hz = task_scheduler_nrscope.args_t.srate_hz; + ssb_cfg.srate_hz = task_scheduler_nrscope.task_scheduler_state.args_t.srate_hz; ssb_cfg.center_freq_hz = cs_args.ssb_freq_hz; ssb_cfg.ssb_freq_hz = cs_args.ssb_freq_hz; ssb_cfg.scs = cs_args.ssb_scs; @@ -596,9 +629,9 @@ int Radio::SyncandDownlinkInit(){ ssb_cfg.duplex_mode = cs_args.duplex_mode; ssb_cfg.periodicity_ms = 20; // for all in FR1 - sync_cfg.N_id = task_scheduler_nrscope.cs_ret.ssb_res.N_id; + sync_cfg.N_id = task_scheduler_nrscope.task_scheduler_state.cs_ret.ssb_res.N_id; sync_cfg.ssb = ssb_cfg; - sync_cfg.ssb.srate_hz = task_scheduler_nrscope.args_t.srate_hz; + sync_cfg.ssb.srate_hz = task_scheduler_nrscope.task_scheduler_state.args_t.srate_hz; if (srsran_ue_sync_nr_set_cfg(&ue_sync_nr, &sync_cfg) < SRSRAN_SUCCESS) { printf("SYNC: failed to set cell configuration for N_id %d", sync_cfg.N_id); logger.error("SYNC: failed to set cell configuration for N_id %d", sync_cfg.N_id); @@ -613,26 +646,37 @@ int Radio::FetchAndResample(){ uint64_t next_produce_at = 0; bool in_sync = false; - uint32_t pre_resampling_sf_sz = SRSRAN_NOF_SLOTS_PER_SF_NR(task_scheduler_nrscope.args_t.ssb_scs) * pre_resampling_slot_sz; + uint32_t pre_resampling_sf_sz = + SRSRAN_NOF_SLOTS_PER_SF_NR(task_scheduler_nrscope.task_scheduler_state.args_t.ssb_scs) * + pre_resampling_slot_sz; while(true){ outcome.timestamp = last_rx_time.get(0); struct timeval t0, t1; gettimeofday(&t0, NULL); - // if not sync, we fetch and sync at the rx_buffer start, otherwise we store from 1 to RING_BUF_MODULUS sf index and back in a ring buffer manner - // i.e., 0 sf index is for sync and moving a sf data there for decoders to process - // note at the first round we start like 0, 2, 3... (skip 1 if you do the math) + /* if not sync, we fetch and sync at the rx_buffer start, + otherwise we store from 1 to RING_BUF_MODULUS sf index + and back in a ring buffer manner + i.e., 0 sf index is for sync and moving a sf data there for decoders to + process, note at the first round we start like 0, 2, 3... + (skip 1 if you do the math) */ rf_buffer_t = !in_sync ? - srsran::rf_buffer_t(rx_buffer, pre_resampling_sf_sz) : - srsran::rf_buffer_t(rx_buffer + (pre_resampling_sf_sz * (next_produce_at % RING_BUF_MODULUS + 1)), pre_resampling_sf_sz); - std::cout << "current_produce_at: " << (!in_sync ? 0 : (next_produce_at % RING_BUF_MODULUS + 1)) << std::endl; - std::cout << "current_produce_ptr: " << (rf_buffer_t.to_cf_t())[0] << std::endl; + srsran::rf_buffer_t(rx_buffer, pre_resampling_sf_sz) : + srsran::rf_buffer_t(rx_buffer + (pre_resampling_sf_sz * + (next_produce_at % RING_BUF_MODULUS + 1)), pre_resampling_sf_sz); + + std::cout << "current_produce_at: " << (!in_sync ? 0 : + (next_produce_at % RING_BUF_MODULUS + 1)) << std::endl; + std::cout << "current_produce_ptr: " << (rf_buffer_t.to_cf_t())[0] << + std::endl; // note fetching the raw samples will temporarily touch area out of the target sf boundary // yet after resampling, all meaningful data will reside the target sf arr area and the original raw extra part // beyond the boundary doesn't matter - if (srsran_ue_sync_nr_zerocopy_twinrx_nrscope(&ue_sync_nr, rf_buffer_t.to_cf_t(), &outcome, rk, resample_needed, RESAMPLE_WORKER_NUM) < SRSRAN_SUCCESS) { + if (srsran_ue_sync_nr_zerocopy_twinrx_nrscope( + &ue_sync_nr, rf_buffer_t.to_cf_t(), &outcome, rk, resample_needed, + RESAMPLE_WORKER_NUM) < SRSRAN_SUCCESS) { std::cout << "SYNC: error in zerocopy" << std::endl; logger.error("SYNC: error in zerocopy"); return false; @@ -651,169 +695,188 @@ int Radio::FetchAndResample(){ } gettimeofday(&t1, NULL); - std::cout << "producer time_spend: " << (t1.tv_usec - t0.tv_usec) << "(us)" << std::endl; + std::cout << "producer time_spend: " << + (t1.tv_usec - t0.tv_usec) << "(us)" << std::endl; } return SRSRAN_SUCCESS; } int Radio::DecodeAndProcess(){ - uint32_t pre_resampling_sf_sz = SRSRAN_NOF_SLOTS_PER_SF_NR(task_scheduler_nrscope.args_t.ssb_scs) * pre_resampling_slot_sz; - if(!task_scheduler_nrscope.sib1_inited){ - /* Initialize all the worker's sib decoder */ - srsran::rf_buffer_t rf_buffer_wrapper(rx_buffer, pre_resampling_sf_sz); - if(sibs_decoder.sib_decoder_and_reception_init(arg_scs, &task_scheduler_nrscope, rf_buffer_wrapper.to_cf_t()) < SRSASN_SUCCESS){ - ERROR("SIBsDecoder Init Error"); - return NR_FAILURE; - } - std::cout << "SIB Decoder Initializing..." << std::endl; - } + uint32_t pre_resampling_sf_sz = + SRSRAN_NOF_SLOTS_PER_SF_NR(task_scheduler_nrscope.task_scheduler_state.args_t.ssb_scs) * + pre_resampling_slot_sz; + // if(!task_scheduler_nrscope.task_scheduler_state.sib1_inited){ + // /* Initialize all the worker's sib decoder */ + // srsran::rf_buffer_t rf_buffer_wrapper(rx_buffer, pre_resampling_sf_sz); + // if(sibs_decoder.sib_decoder_and_reception_init(arg_scs, &task_scheduler_nrscope, rf_buffer_wrapper.to_cf_t()) < SRSASN_SUCCESS){ + // ERROR("SIBsDecoder Init Error"); + // return NR_FAILURE; + // } + // std::cout << "SIB Decoder Initializing..." << std::endl; + // } uint64_t next_consume_at = 0; bool first_time = true; + task_scheduler_nrscope.task_scheduler_state.sib1_inited = true; while (true) { sem_wait(&smph_sf_data_prod_cons); - std::cout << "current_consume_at: " << (first_time ? 0 : ((next_consume_at % RING_BUF_MODULUS + 1))) << std::endl; + std::cout << "current_consume_at: " << (first_time ? 0 : + ((next_consume_at % RING_BUF_MODULUS + 1))) << std::endl; outcome.timestamp = last_rx_time.get(0); struct timeval t0, t1; gettimeofday(&t0, NULL); // consume a sf data for(int slot_idx = 0; slot_idx < SRSRAN_NOF_SLOTS_PER_SF_NR(arg_scs.scs); slot_idx++){ srsran_slot_cfg_t slot = {0}; - slot.idx = (outcome.sf_idx) * SRSRAN_NSLOTS_PER_FRAME_NR(arg_scs.scs) / 10 + slot_idx; - // Move rx_buffer - // here wanted data move to the buffer beginning for decoders to process - // fetch and resample thread will store unprocessed data at 1 to RING_BUF_MODULUS sf index; we copy wanted data to 0 sf idx - // assumption: no way when we are decoding this sf the fetch thread has go around the whole ring and modify this sf again - srsran_vec_cf_copy(rx_buffer, rx_buffer + (first_time ? 0 : ((next_consume_at % RING_BUF_MODULUS + 1) * pre_resampling_sf_sz)) + (slot_idx * slot_sz), slot_sz); - std::cout << "decode slot: " << slot_idx << "; current_consume_ptr: " << rx_buffer + (first_time ? 0 : ((next_consume_at % RING_BUF_MODULUS + 1) * pre_resampling_sf_sz)) + (slot_idx * slot_sz) << std::endl; - - if(!task_scheduler_nrscope.rach_inited and task_scheduler_nrscope.sib1_found){ - // std::thread rach_init_thread {&RachDecoder::rach_decoder_init, &rach_decoder, task_scheduler_nrscope.sib1, args_t.base_carrier}; - rach_decoder.rach_decoder_init(&task_scheduler_nrscope); - srsran::rf_buffer_t rf_buffer_wrapper(rx_buffer, pre_resampling_sf_sz); - if(rach_decoder.rach_reception_init(arg_scs, &task_scheduler_nrscope, rf_buffer_wrapper.to_cf_t()) < SRSASN_SUCCESS){ - ERROR("RACHDecoder Init Error"); - return NR_FAILURE; - } - std::cout << "RACH Decoder Initialized.." << std::endl; - task_scheduler_nrscope.rach_inited = true; + slot.idx = (outcome.sf_idx) * SRSRAN_NSLOTS_PER_FRAME_NR(arg_scs.scs) / + 10 + slot_idx; + /* Move rx_buffer + here wanted data move to the buffer beginning for decoders to process + fetch and resample thread will store unprocessed data at 1 to + RING_BUF_MODULUS sf index; we copy wanted data to 0 sf idx + assumption: no way when we are decoding this sf the fetch thread has + go around the whole ring and modify this sf again */ + srsran_vec_cf_copy(rx_buffer, rx_buffer + + (first_time ? 0 : ((next_consume_at % RING_BUF_MODULUS + 1) * + pre_resampling_sf_sz)) + (slot_idx * slot_sz), slot_sz); + + std::cout << "decode slot: " << slot_idx << "; current_consume_ptr: " + << rx_buffer + (first_time ? 0 : + ((next_consume_at % RING_BUF_MODULUS + 1) * pre_resampling_sf_sz)) + + (slot_idx * slot_sz) << std::endl; + + if (task_scheduler_nrscope.AssignTask(&slot, rx_buffer) < SRSRAN_SUCCESS) { + ERROR("Assign task failed"); } - if(!task_scheduler_nrscope.dci_inited and task_scheduler_nrscope.rach_found){ - std::cout << "Initializing DCI decoder..." << std::endl; - task_scheduler_nrscope.sharded_results.resize(nof_threads); - task_scheduler_nrscope.nof_sharded_rntis.resize(nof_threads); - task_scheduler_nrscope.sharded_rntis.resize(nof_threads); - task_scheduler_nrscope.nof_threads = nof_threads; - task_scheduler_nrscope.nof_rnti_worker_groups = nof_rnti_worker_groups; - task_scheduler_nrscope.nof_bwps = nof_bwps; - task_scheduler_nrscope.results.resize(nof_bwps); - for(uint32_t i = 0; i < nof_rnti_worker_groups; i++){ - // for each rnti worker group, for each bwp, spawn a decoder - for(uint8_t j = 0; j < nof_bwps; j++){ - DCIDecoder *decoder = new DCIDecoder(100); - if(decoder->dci_decoder_and_reception_init(arg_scs, &task_scheduler_nrscope, j) < SRSASN_SUCCESS){ - ERROR("DCIDecoder Init Error"); - return NR_FAILURE; - } - decoder->dci_decoder_id = i * nof_bwps + j; - decoder->rnti_worker_group_id = i; - dci_decoders.push_back(std::unique_ptr (decoder)); - } - } + // if(!task_scheduler_nrscope.rach_inited and task_scheduler_nrscope.sib1_found){ + // // std::thread rach_init_thread {&RachDecoder::rach_decoder_init, &rach_decoder, task_scheduler_nrscope.sib1, args_t.base_carrier}; + // rach_decoder.rach_decoder_init(&task_scheduler_nrscope); + // srsran::rf_buffer_t rf_buffer_wrapper(rx_buffer, pre_resampling_sf_sz); + // if(rach_decoder.rach_reception_init(arg_scs, &task_scheduler_nrscope, rf_buffer_wrapper.to_cf_t()) < SRSASN_SUCCESS){ + // ERROR("RACHDecoder Init Error"); + // return NR_FAILURE; + // } + // std::cout << "RACH Decoder Initialized.." << std::endl; + // task_scheduler_nrscope.rach_inited = true; + // } + + // if(!task_scheduler_nrscope.dci_inited and task_scheduler_nrscope.rach_found){ + // std::cout << "Initializing DCI decoder..." << std::endl; + // task_scheduler_nrscope.sharded_results.resize(nof_threads); + // task_scheduler_nrscope.nof_sharded_rntis.resize(nof_threads); + // task_scheduler_nrscope.sharded_rntis.resize(nof_threads); + // task_scheduler_nrscope.nof_threads = nof_threads; + // task_scheduler_nrscope.nof_rnti_worker_groups = nof_rnti_worker_groups; + // task_scheduler_nrscope.nof_bwps = nof_bwps; + // task_scheduler_nrscope.results.resize(nof_bwps); + // for(uint32_t i = 0; i < nof_rnti_worker_groups; i++){ + // // for each rnti worker group, for each bwp, spawn a decoder + // for(uint8_t j = 0; j < nof_bwps; j++){ + // DCIDecoder *decoder = new DCIDecoder(100); + // if(decoder->dci_decoder_and_reception_init(arg_scs, &task_scheduler_nrscope, j) < SRSASN_SUCCESS){ + // ERROR("DCIDecoder Init Error"); + // return NR_FAILURE; + // } + // decoder->dci_decoder_id = i * nof_bwps + j; + // decoder->rnti_worker_group_id = i; + // dci_decoders.push_back(std::unique_ptr (decoder)); + // } + // } - std::cout << "DCI Decoder Initialized.." << std::endl; - task_scheduler_nrscope.dci_inited = true; - } - - // Then start each type of decoder, TODO - task_scheduler_nrscope.dl_prb_rate.resize(task_scheduler_nrscope.nof_known_rntis); - task_scheduler_nrscope.ul_prb_rate.resize(task_scheduler_nrscope.nof_known_rntis); - task_scheduler_nrscope.dl_prb_bits_rate.resize(task_scheduler_nrscope.nof_known_rntis); - task_scheduler_nrscope.ul_prb_bits_rate.resize(task_scheduler_nrscope.nof_known_rntis); - - // To save computing resources for dci decoders: assume SIB1 info should be static - std::thread sibs_thread; - if (!task_scheduler_nrscope.sib1_found) { - sibs_thread = std::thread {&SIBsDecoder::decode_and_parse_sib1_from_slot, &sibs_decoder, &slot, &task_scheduler_nrscope}; - } - std::thread rach_thread {&RachDecoder::decode_and_parse_msg4_from_slot, &rach_decoder, &slot, &task_scheduler_nrscope}; - - std::vector dci_threads; - if(task_scheduler_nrscope.dci_inited){ - for (uint32_t i = 0; i < nof_threads; i++){ - dci_threads.emplace_back(&DCIDecoder::decode_and_parse_dci_from_slot, dci_decoders[i].get(), &slot, &task_scheduler_nrscope); - } - } - - if(sibs_thread.joinable()){ - sibs_thread.join(); - } - - if(rach_thread.joinable()){ - rach_thread.join(); - } - - if(task_scheduler_nrscope.dci_inited){ - for (uint32_t i = 0; i < nof_threads; i++){ - if(dci_threads[i].joinable()){ - dci_threads[i].join(); - } - } - } - - if(task_scheduler_nrscope.dci_inited){ - task_scheduler_nrscope.merge_results(); - std::vector results = task_scheduler_nrscope.get_results(); - - for (uint8_t b = 0; b < nof_bwps; b++) { - DCIFeedback result = results[b]; - if((result.dl_grants.size()>0 or result.ul_grants.size()>0)){ - for (uint32_t i = 0; i < task_scheduler_nrscope.nof_known_rntis; i++){ - if(result.dl_grants[i].grant.rnti == task_scheduler_nrscope.known_rntis[i]){ - LogNode log_node; - log_node.slot_idx = slot.idx; - log_node.system_frame_idx = outcome.sfn; - log_node.timestamp = get_now_timestamp_in_double(); - log_node.grant = result.dl_grants[i]; - log_node.dci_format = srsran_dci_format_nr_string(result.dl_dcis[i].ctx.format); - log_node.dl_dci = result.dl_dcis[i]; - log_node.bwp_id = result.dl_dcis[i].bwp_id; - if(local_log){ - NRScopeLog::push_node(log_node, rf_index); - } - if(to_google){ - ToGoogle::push_google_node(log_node, rf_index); - } - } - - if(result.ul_grants[i].grant.rnti == task_scheduler_nrscope.known_rntis[i]){ - LogNode log_node; - log_node.slot_idx = slot.idx; - log_node.system_frame_idx = outcome.sfn; - log_node.timestamp = get_now_timestamp_in_double(); - log_node.grant = result.ul_grants[i]; - log_node.dci_format = srsran_dci_format_nr_string(result.ul_dcis[i].ctx.format); - log_node.ul_dci = result.ul_dcis[i]; - log_node.bwp_id = result.ul_dcis[i].bwp_id; - if(local_log){ - NRScopeLog::push_node(log_node, rf_index); - } - if(to_google){ - ToGoogle::push_google_node(log_node, rf_index); - } - } - } - } - } - } - task_scheduler_nrscope.update_known_rntis(); + // std::cout << "DCI Decoder Initialized.." << std::endl; + // task_scheduler_nrscope.dci_inited = true; + // } + + // // Then start each type of decoder, TODO + // task_scheduler_nrscope.dl_prb_rate.resize(task_scheduler_nrscope.nof_known_rntis); + // task_scheduler_nrscope.ul_prb_rate.resize(task_scheduler_nrscope.nof_known_rntis); + // task_scheduler_nrscope.dl_prb_bits_rate.resize(task_scheduler_nrscope.nof_known_rntis); + // task_scheduler_nrscope.ul_prb_bits_rate.resize(task_scheduler_nrscope.nof_known_rntis); + + // // To save computing resources for dci decoders: assume SIB1 info should be static + // std::thread sibs_thread; + // if (!task_scheduler_nrscope.sib1_found) { + // sibs_thread = std::thread {&SIBsDecoder::decode_and_parse_sib1_from_slot, &sibs_decoder, &slot, &task_scheduler_nrscope}; + // } + // std::thread rach_thread {&RachDecoder::decode_and_parse_msg4_from_slot, &rach_decoder, &slot, &task_scheduler_nrscope}; + + // std::vector dci_threads; + // if(task_scheduler_nrscope.dci_inited){ + // for (uint32_t i = 0; i < nof_threads; i++){ + // dci_threads.emplace_back(&DCIDecoder::decode_and_parse_dci_from_slot, dci_decoders[i].get(), &slot, &task_scheduler_nrscope); + // } + // } + + // if(sibs_thread.joinable()){ + // sibs_thread.join(); + // } + + // if(rach_thread.joinable()){ + // rach_thread.join(); + // } + + // if(task_scheduler_nrscope.dci_inited){ + // for (uint32_t i = 0; i < nof_threads; i++){ + // if(dci_threads[i].joinable()){ + // dci_threads[i].join(); + // } + // } + // } + + // if(task_scheduler_nrscope.dci_inited){ + // task_scheduler_nrscope.MergeResults(); + // std::vector results = task_scheduler_nrscope.get_results(); + + // for (uint8_t b = 0; b < nof_bwps; b++) { + // DCIFeedback result = results[b]; + // if((result.dl_grants.size()>0 or result.ul_grants.size()>0)){ + // for (uint32_t i = 0; i < task_scheduler_nrscope.nof_known_rntis; i++){ + // if(result.dl_grants[i].grant.rnti == task_scheduler_nrscope.known_rntis[i]){ + // LogNode log_node; + // log_node.slot_idx = slot.idx; + // log_node.system_frame_idx = outcome.sfn; + // log_node.timestamp = get_now_timestamp_in_double(); + // log_node.grant = result.dl_grants[i]; + // log_node.dci_format = srsran_dci_format_nr_string(result.dl_dcis[i].ctx.format); + // log_node.dl_dci = result.dl_dcis[i]; + // log_node.bwp_id = result.dl_dcis[i].bwp_id; + // if(local_log){ + // NRScopeLog::push_node(log_node, rf_index); + // } + // if(to_google){ + // ToGoogle::push_google_node(log_node, rf_index); + // } + // } + + // if(result.ul_grants[i].grant.rnti == task_scheduler_nrscope.known_rntis[i]){ + // LogNode log_node; + // log_node.slot_idx = slot.idx; + // log_node.system_frame_idx = outcome.sfn; + // log_node.timestamp = get_now_timestamp_in_double(); + // log_node.grant = result.ul_grants[i]; + // log_node.dci_format = srsran_dci_format_nr_string(result.ul_dcis[i].ctx.format); + // log_node.ul_dci = result.ul_dcis[i]; + // log_node.bwp_id = result.ul_dcis[i].bwp_id; + // if(local_log){ + // NRScopeLog::push_node(log_node, rf_index); + // } + // if(to_google){ + // ToGoogle::push_google_node(log_node, rf_index); + // } + // } + // } + // } + // } + // } + // task_scheduler_nrscope.UpdateKnownRNTIs(); } // slot iteration gettimeofday(&t1, NULL); - std::cout << "consumer time_spend: " << (t1.tv_usec - t0.tv_usec) << "(us)" << std::endl; + std::cout << "consumer time_spend: " << (int)(t1.tv_usec - t0.tv_usec) + << "(us)" << std::endl; next_consume_at++; first_time = false; } // true loop diff --git a/nrscope/src/libs/sibs_decoder.cc b/nrscope/src/libs/sibs_decoder.cc index 1d234111..5e50e83d 100644 --- a/nrscope/src/libs/sibs_decoder.cc +++ b/nrscope/src/libs/sibs_decoder.cc @@ -11,8 +11,8 @@ SIBsDecoder::~SIBsDecoder(){ } -int SIBsDecoder::sib_decoder_and_reception_init(WorkState* state, - cf_t* input[SRSRAN_MAX_PORTS]){ +int SIBsDecoder::SIBDecoderandReceptionInit(WorkState* state, + cf_t* input[SRSRAN_MAX_PORTS]){ memcpy(&coreset0_t, &state->coreset0_t, sizeof(srsran_coreset_t)); dci_cfg.bwp_dl_initial_bw = 275; @@ -34,7 +34,8 @@ int SIBsDecoder::sib_decoder_and_reception_init(WorkState* state, search_space->formats[0] = srsran_dci_format_nr_1_0; search_space->nof_formats = 1; for (uint32_t L = 0; L < SRSRAN_SEARCH_SPACE_NOF_AGGREGATION_LEVELS_NR; L++) { - search_space->nof_candidates[L] = srsran_pdcch_nr_max_candidates_coreset(&coreset0_t, L); + search_space->nof_candidates[L] = + srsran_pdcch_nr_max_candidates_coreset(&coreset0_t, L); } pdcch_cfg.coreset[0] = coreset0_t; @@ -66,7 +67,8 @@ int SIBsDecoder::sib_decoder_and_reception_init(WorkState* state, return SRSRAN_ERROR; } - if (srsran_softbuffer_rx_init_guru(&softbuffer, SRSRAN_SCH_NR_MAX_NOF_CB_LDPC, SRSRAN_LDPC_MAX_LEN_ENCODED_CB) < + if (srsran_softbuffer_rx_init_guru(&softbuffer, + SRSRAN_SCH_NR_MAX_NOF_CB_LDPC, SRSRAN_LDPC_MAX_LEN_ENCODED_CB) < SRSRAN_SUCCESS) { ERROR("Error init soft-buffer"); return SRSRAN_ERROR; @@ -78,12 +80,14 @@ int SIBsDecoder::sib_decoder_and_reception_init(WorkState* state, return SRSRAN_SUCCESS; } -int SIBsDecoder::decode_and_parse_sib1_from_slot(srsran_slot_cfg_t* slot, - bool* sibs_vec_inited, - bool* all_sibs_found, - std::vector& found_sib, - std::vector& sibs, - asn1::rrc_nr::sib1_s* sib1_){ +int SIBsDecoder::DecodeandParseSIB1fromSlot(srsran_slot_cfg_t* slot, + WorkState state) { + // srsran_slot_cfg_t* slot, + // bool* sibs_vec_inited, + // bool* all_sibs_found, + // std::vector& found_sib, + // std::vector& sibs, + // asn1::rrc_nr::sib1_s* sib1_){ memset(&dci_sibs, 0, sizeof(srsran_dci_dl_nr_t)); @@ -98,7 +102,7 @@ int SIBsDecoder::decode_and_parse_sib1_from_slot(srsran_slot_cfg_t* slot, srsran_ue_dl_nr_estimate_fft_nrscope(&ue_dl_sibs, slot, arg_scs); // Blind search int nof_found_dci = srsran_ue_dl_nr_find_dl_dci(&ue_dl_sibs, slot, 0xFFFF, - srsran_rnti_type_si, &dci_sibs, 1); + srsran_rnti_type_si, &dci_sibs, 1); if (nof_found_dci < SRSRAN_SUCCESS){ ERROR("SIBDecoder -- Error in blind search"); return SRSRAN_ERROR; @@ -131,8 +135,8 @@ int SIBsDecoder::decode_and_parse_sib1_from_slot(srsran_slot_cfg_t* slot, pdsch_cfg = {}; - if (srsran_ra_dl_dci_to_grant_nr(&base_carrier, slot, &pdsch_hl_cfg, &dci_sibs, &pdsch_cfg, &pdsch_cfg.grant) < - SRSRAN_SUCCESS) { + if (srsran_ra_dl_dci_to_grant_nr(&base_carrier, slot, &pdsch_hl_cfg, + &dci_sibs, &pdsch_cfg, &pdsch_cfg.grant) < SRSRAN_SUCCESS) { ERROR("SIBDecoder -- Error decoding PDSCH search"); return SRSRAN_ERROR; } @@ -140,8 +144,8 @@ int SIBsDecoder::decode_and_parse_sib1_from_slot(srsran_slot_cfg_t* slot, srsran_sch_cfg_nr_info(&pdsch_cfg, str, (uint32_t)sizeof(str)); printf("PDSCH_cfg:\n%s", str); - if (srsran_softbuffer_rx_init_guru(&softbuffer, SRSRAN_SCH_NR_MAX_NOF_CB_LDPC, SRSRAN_LDPC_MAX_LEN_ENCODED_CB) < - SRSRAN_SUCCESS) { + if (srsran_softbuffer_rx_init_guru(&softbuffer, SRSRAN_SCH_NR_MAX_NOF_CB_LDPC, + SRSRAN_LDPC_MAX_LEN_ENCODED_CB) < SRSRAN_SUCCESS) { ERROR("SIBDecoder -- Error init soft-buffer"); return SRSRAN_ERROR; } @@ -154,7 +158,8 @@ int SIBsDecoder::decode_and_parse_sib1_from_slot(srsran_slot_cfg_t* slot, pdsch_res.tb[0].payload = data_pdcch; // Decode PDSCH - if (srsran_ue_dl_nr_decode_pdsch(&ue_dl_sibs, slot, &pdsch_cfg, &pdsch_res) < SRSRAN_SUCCESS) { + if (srsran_ue_dl_nr_decode_pdsch(&ue_dl_sibs, slot, &pdsch_cfg, &pdsch_res) < + SRSRAN_SUCCESS) { printf("SIBDecoder -- Error decoding PDSCH search\n"); return SRSRAN_ERROR; } @@ -182,48 +187,50 @@ int SIBsDecoder::decode_and_parse_sib1_from_slot(srsran_slot_cfg_t* slot, asn1::cbit_ref dlsch_bref(pdsch_res.tb[0].payload, pdsch_cfg.grant.tb[0].tbs / 8); asn1::SRSASN_CODE err = dlsch_msg.unpack(dlsch_bref); - // Try to decode the SIB + /* Try to decode the SIB, we need a better way to provide the result */ if(srsran_unlikely(asn1::rrc_nr::bcch_dl_sch_msg_type_c::c1_c_::types_opts::sib_type1 != dlsch_msg.msg.c1().type())){ // Try to decode other SIBs - if(!(*sibs_vec_inited)){ + if(!(state.sibs_vec_inited)){ // Skip since the sib_vec is not intialized + ERROR("SIBs vec is not initialized"); return SRSRAN_SUCCESS; }else{ // Get the sib_id, sib_id is uint8_t and is 2 for sib2, 3 for sib 3, etc... auto sib_id = dlsch_msg.msg.c1().sys_info().crit_exts.sys_info().sib_type_and_info[0].type().to_number(); - sibs[sib_id - 2] = dlsch_msg.msg.c1().sys_info(); - found_sib[sib_id - 2] = 1; - - // If we collect all the SIBs, we can skip the thread. - long unsigned int found_result = 0; - for(long unsigned int i=0; i= found_sib.size()){ - *all_sibs_found = true; - } + auto decoded_sib = dlsch_msg.msg.c1().sys_info(); + // sibs[sib_id - 2] = dlsch_msg.msg.c1().sys_info(); + // found_sib[sib_id - 2] = 1; + + // // If we collect all the SIBs, we can skip the thread. + // long unsigned int found_result = 0; + // for(long unsigned int i=0; i= found_sib.size()){ + // *all_sibs_found = true; + // } std::cout << "SIB " << (int)sib_id << " Decoded." << std::endl; /* Uncomment to print the decode SIBs. */ asn1::json_writer js_sibs; - (sibs[(int)(sib_id - 2)]).to_json(js_sibs); + (decoded_sib).to_json(js_sibs); printf("Decoded SIBs: %s\n", js_sibs.to_string().c_str()); } }else if(srsran_unlikely(asn1::rrc_nr::bcch_dl_sch_msg_type_c::c1_c_::types_opts::sys_info != dlsch_msg.msg.c1().type())){ - *sib1_ = dlsch_msg.msg.c1().sib_type1(); + auto sib1 = dlsch_msg.msg.c1().sib_type1(); std::cout << "SIB 1 Decoded." << std::endl; - if(!(*sibs_vec_inited)){ - // Setting the size of the vector for other SIBs decoding. - int nof_sibs = (*sib1_).si_sched_info_present ? (*sib1_).si_sched_info.sched_info_list.size() : 0; - sibs.resize(nof_sibs); - found_sib.resize(nof_sibs); - (*sibs_vec_inited) = true; - } + // if(!(*sibs_vec_inited)){ + // // Setting the size of the vector for other SIBs decoding. + // int nof_sibs = (*sib1_).si_sched_info_present ? (*sib1_).si_sched_info.sched_info_list.size() : 0; + // sibs.resize(nof_sibs); + // found_sib.resize(nof_sibs); + // (*sibs_vec_inited) = true; + // } /* Uncomment to print the decode SIB1. */ asn1::json_writer js_sib1; - (*sib1_).to_json(js_sib1); + (sib1).to_json(js_sib1); printf("Decoded SIB1: %s\n", js_sib1.to_string().c_str()); } diff --git a/nrscope/src/libs/task_scheduler.cc b/nrscope/src/libs/task_scheduler.cc index 8ccef007..0c247226 100644 --- a/nrscope/src/libs/task_scheduler.cc +++ b/nrscope/src/libs/task_scheduler.cc @@ -29,8 +29,10 @@ int TaskSchedulerNRScope::InitandStart(int32_t nof_threads, task_scheduler_state.slot_sz = (uint32_t)(args_t.srate_hz / 1000.0f / SRSRAN_NOF_SLOTS_PER_SF_NR(args_t.ssb_scs)); nof_workers = nof_workers_; - for (int i = 0; i < nof_workers; i ++) { + std::cout << "Starting workers..." << std::endl; + for (uint32_t i = 0; i < nof_workers; i ++) { NRScopeWorker *worker = new NRScopeWorker(); + std::cout << "New worker " << i << " is going to start... "<< std::endl; if(worker->InitWorker(task_scheduler_state) < SRSRAN_SUCCESS) { ERROR("Error initializing worker %d", i); return NR_FAILURE; @@ -38,10 +40,15 @@ int TaskSchedulerNRScope::InitandStart(int32_t nof_threads, workers.emplace_back(std::unique_ptr (worker)); } + std::cout << "Workers started..." << std::endl; + + scheduler_thread = std::thread{&TaskSchedulerNRScope::Run, this}; + scheduler_thread.detach(); + return SRSRAN_SUCCESS; } -int TaskSchedulerNRScope::decode_mib(cell_searcher_args_t* args_t_, +int TaskSchedulerNRScope::DecodeMIB(cell_searcher_args_t* args_t_, srsue::nr::cell_search::ret_t* cs_ret_, srsue::nr::cell_search::cfg_t* srsran_searcher_cfg_t_, float resample_ratio_, @@ -158,7 +165,7 @@ int TaskSchedulerNRScope::decode_mib(cell_searcher_args_t* args_t_, return SRSRAN_SUCCESS; } -int TaskSchedulerNRScope::merge_results(){ +int TaskSchedulerNRScope::MergeResults(){ for (uint8_t b = 0; b < task_scheduler_state.nof_bwps; b++) { DCIFeedback new_result; @@ -177,7 +184,6 @@ int TaskSchedulerNRScope::merge_results(){ uint32_t rnti_s = 0; uint32_t rnti_e = 0; for(uint32_t i = 0; i < task_scheduler_state.nof_rnti_worker_groups; i++){ - if(rnti_s >= task_scheduler_state.nof_known_rntis){ continue; } @@ -251,7 +257,7 @@ int TaskSchedulerNRScope::merge_results(){ return SRSRAN_SUCCESS; } -int TaskSchedulerNRScope::update_known_rntis(){ +int TaskSchedulerNRScope::UpdateKnownRNTIs(){ if(task_scheduler_state.new_rnti_number <= 0){ return SRSRAN_SUCCESS; } @@ -267,4 +273,44 @@ int TaskSchedulerNRScope::update_known_rntis(){ return SRSRAN_SUCCESS; } +void TaskSchedulerNRScope::Run(){ + while(true) { + /* Try to extract results from the global result queue*/ + + } +} + +int TaskSchedulerNRScope::AssignTask(srsran_slot_cfg_t* slot, cf_t* rx_buffer_){ + /* Find the first idle worker */ + bool found_worker = false; + for (uint32_t i = 0; i < nof_workers; i ++) { + bool busy; + lock.lock(); + busy = workers[i].get()->busy; + lock.unlock(); + if (!busy) { + found_worker = true; + + /* Copy the rx_buffer_ to the worker's rx_buffer */ + workers[i].get()->CopySlotandBuffer(slot, rx_buffer_); + + /* Update the worker's state */ + workers[i].get()->SyncState(&task_scheduler_state); + + /* Set the worker's sem to let the task run */ + sem_post(&workers[i].get()->smph_has_job); + + break; + } + } + + if (!found_worker) { + ERROR("No available worker, consider increasing the number of workers."); + return SRSRAN_ERROR; + } else { + return SRSRAN_SUCCESS; + } + +} + } \ No newline at end of file From c913d0cbf5338c10b0a8b67f282358774b597e39 Mon Sep 17 00:00:00 2001 From: Haoran Wan Date: Tue, 10 Sep 2024 20:57:11 -0400 Subject: [PATCH 03/15] worker part finished, code style improvement --- nrscope/config/config.yaml | 4 +- nrscope/hdr/dci_decoder.h | 37 +- nrscope/hdr/nrscope_def.h | 45 +- nrscope/hdr/nrscope_worker.h | 46 +- nrscope/hdr/rach_decoder.h | 9 +- nrscope/hdr/radio_nr.h | 50 ++- nrscope/hdr/sibs_decoder.h | 35 +- nrscope/hdr/task_scheduler.h | 14 +- nrscope/src/libs/dci_decoder.cc | 688 ++++++++++++++++++----------- nrscope/src/libs/nrscope_worker.cc | 245 +++++++--- nrscope/src/libs/rach_decoder.cc | 57 +-- nrscope/src/libs/radio_nr.cc | 21 +- nrscope/src/libs/sibs_decoder.cc | 90 ++-- nrscope/src/libs/task_scheduler.cc | 92 ---- nrscope/src/libs/to_google.cc | 49 +- nrscope/src/libs/to_google.py | 18 +- 16 files changed, 863 insertions(+), 637 deletions(-) diff --git a/nrscope/config/config.yaml b/nrscope/config/config.yaml index 4c21c755..075d9885 100644 --- a/nrscope/config/config.yaml +++ b/nrscope/config/config.yaml @@ -1,6 +1,6 @@ nof_usrp_dev: 1 usrp_setting_0: - ssb_freq: 3630720000 #1989850000 #1970450000 #3489600000 #3649440000 #3650880000 # 1970450000 #2600040000 #3488160000 #3685440000 #3561600000 #1842050000 #2528550000 #3565920000 #2524950000 #2523750000 # 3565920000 # 2527350000 #3408960000 # should be set to the ssb frequency of the cell + ssb_freq: 3630720000 # should be set to the ssb frequency of the cell rf_args: "clock=external,type=x300,master_clock_rate=184320000,sampling_rate=23040000" #"type=x300" #"clock=external" for TwinRX # rf_args: "clock=external,type=x300,sampling_rate=23040000" #"type=x300" #"clock=external" for CBX rx_gain: 80 # for x310 CBX, max rx gain is 31.5, for b210, it's around 80, for x310 TwinRX, max rx gain is 90 @@ -18,7 +18,7 @@ usrp_setting_0: google_dataset_id: "ngscope5g_dci_log_wanhr" # usrp_setting_1: -# dl_freq: 3649440000 #3685440000 #3561600000 #1842050000 #2528550000 #3565920000 #2524950000 #2523750000 # 3565920000 # 2527350000 #3408960000 # should be set to the ssb frequency of the cell +# dl_freq: 3649440000 # should be set to the ssb frequency of the cell # rf_args: "serial=31993A8,clock=external,type=b200" #"type=x300" #"clock=external" # rx_gain: 30 # for x310, max rx gain is 31.5, for b210, it's around 80 # srate_hz: 23040000 diff --git a/nrscope/hdr/dci_decoder.h b/nrscope/hdr/dci_decoder.h index 7d3e2a1b..2cda7202 100644 --- a/nrscope/hdr/dci_decoder.h +++ b/nrscope/hdr/dci_decoder.h @@ -54,30 +54,19 @@ class DCIDecoder{ DCIDecoder(uint32_t max_nof_rntis); ~DCIDecoder(); - int dci_decoder_and_reception_init(srsran_ue_dl_nr_sratescs_info arg_scs_, - srsran_carrier_nr_t* base_carrier_, - cell_search_result_t cell_, - srsran_coreset_t* coreset0_t_, - asn1::rrc_nr::sib1_s sib1_, - asn1::rrc_nr::cell_group_cfg_s master_cell_group_, - asn1::rrc_nr::rrc_setup_s rrc_setup_, - srsue::nr::cell_search::cfg_t srsran_searcher_cfg_t_, - u_int8_t bwp_id, - cf_t* input[SRSRAN_MAX_PORTS]); - - int decode_and_parse_dci_from_slot(srsran_slot_cfg_t* slot, - bool rach_found, - bool dci_inited, - uint32_t nof_known_rntis, - uint32_t nof_rnti_worker_groups, - std::vector & sharded_results, - std::vector >& sharded_rntis, - std::vector& nof_sharded_rntis, - std::vector& known_rntis, - std::vector & dl_prb_rate, - std::vector & dl_prb_bits_rate, - std::vector & ul_prb_rate, - std::vector & ul_prb_bits_rate); + int DCIDecoderandReceptionInit(WorkState* state, + int bwp_id, + cf_t* input[SRSRAN_MAX_PORTS]); + + int DecodeandParseDCIfromSlot(srsran_slot_cfg_t* slot, + WorkState* state, + std::vector & sharded_results, + std::vector >& sharded_rntis, + std::vector& nof_sharded_rntis, + std::vector & dl_prb_rate, + std::vector & dl_prb_bits_rate, + std::vector & ul_prb_rate, + std::vector & ul_prb_bits_rate); // int dci_thread(TaskSchedulerNRScope* task_scheduler_nrscope); }; diff --git a/nrscope/hdr/nrscope_def.h b/nrscope/hdr/nrscope_def.h index 9c66eb2d..e9b6f04d 100644 --- a/nrscope/hdr/nrscope_def.h +++ b/nrscope/hdr/nrscope_def.h @@ -94,7 +94,8 @@ struct cell_searcher_args_t { // ssb_scs = srsran_subcarrier_spacing_30kHz; // Deduce SSB center frequency ARFCN - // uint32_t ssb_arfcn = bands.get_abs_freq_ssb_arfcn(band, ssb_scs, pointA_arfcn); + // uint32_t ssb_arfcn = + // bands.get_abs_freq_ssb_arfcn(band, ssb_scs, pointA_arfcn); // srsran_assert(ssb_arfcn, "Invalid SSB center frequency"); duplex_mode = bands.get_duplex_mode(band); @@ -185,6 +186,7 @@ typedef struct WorkState_ WorkState; asn1::rrc_nr::sib1_s sib1; std::vector sibs; std::vector found_sib; + std::vector sibs_to_be_found; asn1::rrc_nr::rrc_setup_s rrc_setup; asn1::rrc_nr::cell_group_cfg_s master_cell_group; @@ -202,36 +204,28 @@ typedef struct WorkState_ WorkState; uint32_t nof_known_rntis; std::vector known_rntis; - - /* May need to change things below this */ - std::vector nof_sharded_rntis; - std::vector > sharded_rntis; - std::vector sharded_results; - - std::vector dl_prb_rate; - std::vector ul_prb_rate; - std::vector dl_prb_bits_rate; - std::vector ul_prb_bits_rate; - - uint32_t new_rnti_number; - std::vector new_rntis_found; }; typedef struct SlotResult_ SlotResult; struct SlotResult_{ - - /* May need to change things below this */ - std::vector nof_sharded_rntis; - std::vector > sharded_rntis; - std::vector sharded_results; - - std::vector dl_prb_rate; - std::vector ul_prb_rate; - std::vector dl_prb_bits_rate; - std::vector ul_prb_bits_rate; + /* The worker works on SIBs decoding */ + bool sib_result; + bool found_sib1; + asn1::rrc_nr::sib1_s sib1; + std::vector sibs; + std::vector found_sib; + /* The worker works on RACH decoding */ + bool rach_result; + bool found_rach; + asn1::rrc_nr::rrc_setup_s rrc_setup; + asn1::rrc_nr::cell_group_cfg_s master_cell_group; uint32_t new_rnti_number; std::vector new_rntis_found; + + /* The worker works on DCI decoding */ + bool dci_result; + std::vector dci_feedback_results; }; /** @@ -273,5 +267,6 @@ uint32_t get_P(uint32_t bwp_nof_prb, bool config_1_or_2); /** * Calculate nof_rbgs, from sched_nr_rb.cc */ -uint32_t get_nof_rbgs(uint32_t bwp_nof_prb, uint32_t bwp_start, bool config1_or_2); +uint32_t get_nof_rbgs(uint32_t bwp_nof_prb, uint32_t bwp_start, + bool config1_or_2); #endif diff --git a/nrscope/hdr/nrscope_worker.h b/nrscope/hdr/nrscope_worker.h index 512e2b70..fa36cff4 100644 --- a/nrscope/hdr/nrscope_worker.h +++ b/nrscope/hdr/nrscope_worker.h @@ -25,38 +25,16 @@ class NRScopeWorker{ /* Worker thread */ std::thread worker_thread; - // bool sib1_inited; /* SIBsDecoder is initialized, set by task_scheduler. */ - // bool rach_inited; /* RACHDecoder is initialized, set by task_scheduler. */ - // bool dci_inited; /* DCIDecoder is initialized, set by task_scheduler. */ - - // /* Params for the sib decoder. */ - // bool sib1_found; - // bool sibs_vec_inited; - // bool all_sibs_found; - // std::vector found_sib; - // std::vector sibs; - // asn1::rrc_nr::sib1_s sib1; - - // /* Params for the rach decoder. */ - // bool rach_inited; - // asn1::rrc_nr::rrc_setup_s* rrc_setup; - // asn1::rrc_nr::cell_group_cfg_s* master_cell_group; - // bool rach_found; - // uint32_t new_rnti_number; - // std::vector new_rntis_found; - - // /* Params for the dci decoders */ - // bool dci_inited; - // uint32_t nof_known_rntis; - // uint32_t nof_rnti_worker_groups; - // std::vector sharded_results; - // std::vector > sharded_rntis; - // std::vector nof_sharded_rntis; - // std::vector known_rntis; - // std::vector dl_prb_rate; - // std::vector dl_prb_bits_rate; - // std::vector ul_prb_rate; - // std::vector ul_prb_bits_rate; + + /* For DCI sharded results */ + std::vector nof_sharded_rntis; + std::vector > sharded_rntis; + std::vector sharded_results; + std::vector results; + std::vector dl_prb_rate; + std::vector dl_prb_bits_rate; + std::vector ul_prb_rate; + std::vector ul_prb_bits_rate; srsran_slot_cfg_t slot; /* Current slot. */ @@ -76,11 +54,15 @@ class NRScopeWorker{ before the job starts, so don't need to consider about the thread safe thing. */ int SyncState(WorkState* task_scheduler_state); + + /* Copy the buffer and the slot structure from the task_scheduler */ void CopySlotandBuffer(srsran_slot_cfg_t* slot_, cf_t* rx_buffer_); int InitSIBDecoder(); int InitRACHDecoder(); int InitDCIDecoders(); + + int MergeResults(); private: void Run(); diff --git a/nrscope/hdr/rach_decoder.h b/nrscope/hdr/rach_decoder.h index e23d7dc0..39ed6672 100644 --- a/nrscope/hdr/rach_decoder.h +++ b/nrscope/hdr/rach_decoder.h @@ -56,13 +56,8 @@ class RachDecoder{ cf_t* input[SRSRAN_MAX_PORTS]); int DecodeandParseMS4fromSlot(srsran_slot_cfg_t* slot, - bool sib1_found, - bool rach_inited, - asn1::rrc_nr::rrc_setup_s* rrc_setup, - asn1::rrc_nr::cell_group_cfg_s* master_cell_group, - bool* rach_found, - uint32_t* new_rnti_number, - std::vector& new_rntis_found); + WorkState* state, + SlotResult* result); // int rach_thread(TaskSchedulerNRScope* task_scheduler_nrscope); }; diff --git a/nrscope/hdr/radio_nr.h b/nrscope/hdr/radio_nr.h index 3537d380..e52d6df6 100644 --- a/nrscope/hdr/radio_nr.h +++ b/nrscope/hdr/radio_nr.h @@ -71,7 +71,8 @@ class Radio{ uint32_t nof_workers; std::vector > dci_decoders; - // a better coordination between producer (fetch) and consumer (resample and decode) + /* a better coordination between producer (fetch) and consumer + (resample and decode) */ sem_t smph_sf_data_prod_cons; bool resample_needed; @@ -106,28 +107,34 @@ class Radio{ int ScanThread(); /** - * This function first sets up some parameters related to the radio sample caputure according to the config file, - * such as sampling frequency, SSB frequency and SCS. Then it will search the MIB within the range of - * [SSB frequency - 0.7 * sampling frequency / 2, SSB frequency + 0.7 * sampling frequency / 2]. - * (1) If a cell is found, this functions notifies the parameters to task_scheduler_nrscope and start decoding - * SIB, RACH and DCIs. - * (2) If no cell is found, it will return and the thread for this USRP ends. + * This function first sets up some parameters related to the radio sample + * caputure according to the config file, such as sampling frequency, + * SSB frequency and SCS. Then it will search the MIB within the range of + * [SSB frequency - 0.7 * sampling frequency / 2, SSB frequency + 0.7 * + * sampling frequency / 2]. + * (1) If a cell is found, this functions notifies the parameters to + * task_scheduler_nrscope and start decoding SIB, RACH and DCIs. + * (2) If no cell is found, it will return and the thread for this + * USRP ends. * - * @return SRSRAN_SUCCESS (0) if no cell is found. NR_FAILURE (-1) if something is wrong in the function. + * @return SRSRAN_SUCCESS (0) if no cell is found. NR_FAILURE (-1) + * if something is wrong in the function. */ int RadioInitandStart(); /** - * This function goes through the per band (denoted by outer loop), and search each GSCN raster point in the band - * (denoted by inner loop) + * This function goes through the per band (denoted by outer loop), and + * search each GSCN raster point in the band (denoted by inner loop) * - * @return SRSRAN_SUCCESS (0) if no cell is found. NR_FAILURE (-1) if something is wrong in the function. + * @return SRSRAN_SUCCESS (0) if no cell is found. NR_FAILURE (-1) + * if something is wrong in the function. */ int ScanInitandStart(); /** - * After finding the cell and decoding the cell and synchronization signal, this function sets up the parameters - * related to downlink synchronization, in terms of mitigating the CFO and time adjustment. + * After finding the cell and decoding the cell and synchronization signal, + * this function sets up the parameters related to downlink synchronization, + * in terms of mitigating the CFO and time adjustment. * * @return SRSRAN_SUCCESS (0) these parameters are successfuly set. * SRSRAN_ERROR (-1) if something goes wrong. @@ -136,11 +143,12 @@ class Radio{ /** * (TASKS HAVE BEEN DELEGATED TO FetchAndResample AND DecodeAndProcess) - * After MIB decoding and synchronization, the USRP grabs 1ms data every time and dispatches the raw radio - * samples among SIB, RACH and DCI decoding threads. Also initialize these threads if they are not. + * After MIB decoding and synchronization, the USRP grabs 1ms data every + * time and dispatches the raw radio samples among SIB, RACH and DCI + * decoding threads. Also initialize these threads if they are not. * - * @return SRSRAN_SUCCESS (0) if the function is stopped or it will run infinitely. - * NR_FAILURE (-1) if something goes wrong. + * @return SRSRAN_SUCCESS (0) if the function is stopped or it will run + * infinitely. NR_FAILURE (-1) if something goes wrong. */ int RadioCapture(); @@ -148,16 +156,16 @@ class Radio{ /** * sync, track sync, and grab 1ms raw samples from USRP continuously * - * @return SRSRAN_SUCCESS (0) if the function is stopped or it will run infinitely. - * NR_FAILURE (-1) if something goes wrong. + * @return SRSRAN_SUCCESS (0) if the function is stopped or it will run + * infinitely. NR_FAILURE (-1) if something goes wrong. */ int FetchAndResample(); /** * resample and decode the signals * - * @return SRSRAN_SUCCESS (0) if the function is stopped or it will run infinitely. - * NR_FAILURE (-1) if something goes wrong. + * @return SRSRAN_SUCCESS (0) if the function is stopped or it will + * run infinitely. NR_FAILURE (-1) if something goes wrong. */ int DecodeAndProcess(); }; diff --git a/nrscope/hdr/sibs_decoder.h b/nrscope/hdr/sibs_decoder.h index b15fe304..4ab4234a 100644 --- a/nrscope/hdr/sibs_decoder.h +++ b/nrscope/hdr/sibs_decoder.h @@ -35,18 +35,20 @@ class SIBsDecoder{ ~SIBsDecoder(); /** - * This function initialize the decoder with the required context for SIB decoding, we can't decode SIB - * without these parameters. + * This function initialize the decoder with the required context for SIB + * decoding, we can't decode SIB without these parameters. * - * @param arg_scs_: it contains basic information about the radio and cell, such as sampling rate, - * SCS and phase difference. - * @param base_carrier_: it contains the information about the carrier of the cell, such as how many - * PRBs are contained in the carrier and SSB center frequency. + * @param arg_scs_: it contains basic information about the radio and cell, + * such as sampling rate, SCS and phase difference. + * @param base_carrier_: it contains the information about the carrier of + * the cell, such as how many PRBs are contained in the carrier and SSB + * center frequency. * @param cell_: cell search result, containing cell's SSB patterns, SCS, etc. - * @param input: the buffer's address, which the USRP use to store radio samples, and it's used for - * setting the ue_dl object so that all thread shares the same buffer for processing. - * @param coreset0_t_: the parameters of CORESET 0, with which this function can localize SIB 1 - * in time and frequency. + * @param input: the buffer's address, which the USRP use to store radio + * samples, and it's used for setting the ue_dl object so that all thread + * shares the same buffer for processing. + * @param coreset0_t_: the parameters of CORESET 0, with which this function + * can localize SIB 1 in time and frequency. * * @return SRSRAN_SUCCESS (0) if everything goes well. * SRSRAN_ERROR (-1) if something is wrong in the function. @@ -55,17 +57,20 @@ class SIBsDecoder{ cf_t* input[SRSRAN_MAX_PORTS]); /** - * This function decodes the current slot for SIB 1, and the result will reflect in the sib1 parameter. + * This function decodes the current slot for SIB 1, and the result will + * reflect in the sib1 parameter. * - * @param slot: current slot index within the system frame (1-20 for 30kHz SCS). - * @param sib1: the pointer to the address where the SIB 1 information should be stored. - * Maybe change this to a task_scheduler_ngscope object. + * @param slot: current slot index within the system frame (1-20 for + * 30kHz SCS). + * @param sib1: the pointer to the address where the SIB 1 information + * should be stored. Maybe change this to a task_scheduler_ngscope object. * * @return SRSRAN_SUCCESS (0) if everything goes well. * SRSRAN_ERROR (-1) if something is wrong in the function. */ int DecodeandParseSIB1fromSlot(srsran_slot_cfg_t* slot, - WorkState state); + WorkState* state, + SlotResult* result); // srsran_slot_cfg_t* slot, // bool* sibs_vec_inited, // bool* all_sibs_found, diff --git a/nrscope/hdr/task_scheduler.h b/nrscope/hdr/task_scheduler.h index 31fc717e..ddc7a89f 100644 --- a/nrscope/hdr/task_scheduler.h +++ b/nrscope/hdr/task_scheduler.h @@ -3,8 +3,6 @@ #include -/* A class that stores some intermediate results and schedules the SIB, RACH and DCI loops. */ - #include "nrscope/hdr/nrscope_def.h" #include "nrscope/hdr/nrscope_worker.h" @@ -85,12 +83,14 @@ class TaskSchedulerNRScope{ /* Assign the current slot to one worker*/ int AssignTask(srsran_slot_cfg_t* slot, cf_t* rx_buffer_); - std::vector get_results(){ - return results; - } + // std::vector nof_sharded_rntis; + // std::vector > sharded_rntis; + // std::vector sharded_results; + - // per bwp DCI decoding result for current TTI - std::vector results; + // std::vector get_results(){ + // return results; + // } // resampler tools float resample_ratio; diff --git a/nrscope/src/libs/dci_decoder.cc b/nrscope/src/libs/dci_decoder.cc index 837eb52d..a5a76690 100644 --- a/nrscope/src/libs/dci_decoder.cc +++ b/nrscope/src/libs/dci_decoder.cc @@ -5,8 +5,10 @@ DCIDecoder::DCIDecoder(uint32_t max_nof_rntis){ ue_dl_tmp = (srsran_ue_dl_nr_t*) malloc(sizeof(srsran_ue_dl_nr_t)); slot_tmp = (srsran_slot_cfg_t*) malloc(sizeof(srsran_slot_cfg_t)); - dci_dl = (srsran_dci_dl_nr_t*) malloc(sizeof(srsran_dci_dl_nr_t) * (max_nof_rntis)); - dci_ul = (srsran_dci_ul_nr_t*) malloc(sizeof(srsran_dci_ul_nr_t) * (max_nof_rntis)); + dci_dl = (srsran_dci_dl_nr_t*) malloc(sizeof(srsran_dci_dl_nr_t) * + (max_nof_rntis)); + dci_ul = (srsran_dci_ul_nr_t*) malloc(sizeof(srsran_dci_ul_nr_t) * + (max_nof_rntis)); } @@ -14,21 +16,15 @@ DCIDecoder::~DCIDecoder(){ } -int DCIDecoder::dci_decoder_and_reception_init(srsran_ue_dl_nr_sratescs_info arg_scs_, - srsran_carrier_nr_t* base_carrier_, - cell_search_result_t cell_, - srsran_coreset_t* coreset0_t_, - asn1::rrc_nr::sib1_s sib1_, - asn1::rrc_nr::cell_group_cfg_s master_cell_group_, - asn1::rrc_nr::rrc_setup_s rrc_setup_, - srsue::nr::cell_search::cfg_t srsran_searcher_cfg_t_, - u_int8_t bwp_id, - cf_t* input[SRSRAN_MAX_PORTS]){ +int DCIDecoder::DCIDecoderandReceptionInit(WorkState* state, + int bwp_id, + cf_t* input[SRSRAN_MAX_PORTS]){ - memcpy(&base_carrier, base_carrier_, sizeof(srsran_carrier_nr_t)); + memcpy(&base_carrier, &state->args_t.base_carrier, + sizeof(srsran_carrier_nr_t)); - arg_scs = arg_scs_; - cell = cell_; + arg_scs = state->arg_scs; + cell = state->cell; bwp_worker_id = bwp_id; @@ -40,10 +36,10 @@ int DCIDecoder::dci_decoder_and_reception_init(srsran_ue_dl_nr_sratescs_info arg ue_dl_args.pdcch.measure_evm = true; ue_dl_args.nof_max_prb = 275; - memcpy(&coreset0_t, coreset0_t_, sizeof(srsran_coreset_t)); - sib1 = sib1_; - master_cell_group = master_cell_group_; - rrc_setup = rrc_setup_; + memcpy(&coreset0_t, &state->coreset0_t, sizeof(srsran_coreset_t)); + sib1 = state->sib1; + master_cell_group = state->master_cell_group; + rrc_setup = state->rrc_setup; dci_cfg.bwp_dl_initial_bw = 275; dci_cfg.bwp_ul_initial_bw = 275; @@ -64,7 +60,8 @@ int DCIDecoder::dci_decoder_and_reception_init(srsran_ue_dl_nr_sratescs_info arg search_space->formats[0] = srsran_dci_format_nr_1_0; search_space->nof_formats = 1; for (uint32_t L = 0; L < SRSRAN_SEARCH_SPACE_NOF_AGGREGATION_LEVELS_NR; L++) { - search_space->nof_candidates[L] = srsran_pdcch_nr_max_candidates_coreset(&coreset0_t, L); + search_space->nof_candidates[L] = + srsran_pdcch_nr_max_candidates_coreset(&coreset0_t, L); } pdcch_cfg.coreset[0] = coreset0_t; @@ -79,14 +76,20 @@ int DCIDecoder::dci_decoder_and_reception_init(srsran_ue_dl_nr_sratescs_info arg // assume ul bwp n and dl bwp n should be activated and used at the same time (lso for sure for TDD) if (bwp_id == 0) { - bwp_dl_ded_s_ptr = &(master_cell_group.sp_cell_cfg.sp_cell_cfg_ded.init_dl_bwp); - bwp_ul_ded_s_ptr = &(master_cell_group.sp_cell_cfg.sp_cell_cfg_ded.ul_cfg.init_ul_bwp); + bwp_dl_ded_s_ptr = + &(master_cell_group.sp_cell_cfg.sp_cell_cfg_ded.init_dl_bwp); + bwp_ul_ded_s_ptr = + &(master_cell_group.sp_cell_cfg.sp_cell_cfg_ded.ul_cfg.init_ul_bwp); } else if (bwp_id <= 3) { - for (uint8_t i = 0; i < master_cell_group.sp_cell_cfg.sp_cell_cfg_ded.dl_bwp_to_add_mod_list.size(); i++) { - if (bwp_id == master_cell_group.sp_cell_cfg.sp_cell_cfg_ded.dl_bwp_to_add_mod_list[i].bwp_id) { - if (master_cell_group.sp_cell_cfg.sp_cell_cfg_ded.dl_bwp_to_add_mod_list[i].bwp_ded_present) { - bwp_dl_ded_s_ptr = &(master_cell_group.sp_cell_cfg.sp_cell_cfg_ded.dl_bwp_to_add_mod_list[i].bwp_ded); + for (uint8_t i = 0; i < master_cell_group.sp_cell_cfg.sp_cell_cfg_ded. + dl_bwp_to_add_mod_list.size(); i++) { + if (bwp_id == master_cell_group.sp_cell_cfg.sp_cell_cfg_ded. + dl_bwp_to_add_mod_list[i].bwp_id) { + if (master_cell_group.sp_cell_cfg.sp_cell_cfg_ded. + dl_bwp_to_add_mod_list[i].bwp_ded_present) { + bwp_dl_ded_s_ptr = &(master_cell_group.sp_cell_cfg.sp_cell_cfg_ded. + dl_bwp_to_add_mod_list[i].bwp_ded); break; } else { @@ -96,10 +99,14 @@ int DCIDecoder::dci_decoder_and_reception_init(srsran_ue_dl_nr_sratescs_info arg } if (master_cell_group.sp_cell_cfg.sp_cell_cfg_ded.ul_cfg_present) { - for (uint8_t i = 0; i < master_cell_group.sp_cell_cfg.sp_cell_cfg_ded.ul_cfg.ul_bwp_to_add_mod_list.size(); i++) { - if (bwp_id == master_cell_group.sp_cell_cfg.sp_cell_cfg_ded.ul_cfg.ul_bwp_to_add_mod_list[i].bwp_id) { - if (master_cell_group.sp_cell_cfg.sp_cell_cfg_ded.ul_cfg.ul_bwp_to_add_mod_list[i].bwp_ded_present) { - bwp_ul_ded_s_ptr = &(master_cell_group.sp_cell_cfg.sp_cell_cfg_ded.ul_cfg.ul_bwp_to_add_mod_list[i].bwp_ded); + for (uint8_t i = 0; i < master_cell_group.sp_cell_cfg.sp_cell_cfg_ded. + ul_cfg.ul_bwp_to_add_mod_list.size(); i++) { + if (bwp_id == master_cell_group.sp_cell_cfg.sp_cell_cfg_ded.ul_cfg. + ul_bwp_to_add_mod_list[i].bwp_id) { + if (master_cell_group.sp_cell_cfg.sp_cell_cfg_ded.ul_cfg. + ul_bwp_to_add_mod_list[i].bwp_ded_present) { + bwp_ul_ded_s_ptr = &(master_cell_group.sp_cell_cfg.sp_cell_cfg_ded. + ul_cfg.ul_bwp_to_add_mod_list[i].bwp_ded); break; } else { @@ -116,27 +123,35 @@ int DCIDecoder::dci_decoder_and_reception_init(srsran_ue_dl_nr_sratescs_info arg } if (bwp_dl_ded_s_ptr == NULL || bwp_ul_ded_s_ptr == NULL) { - ERROR("bwp id %d ul or dl config never appears in RRCSetup (what we assume now only checking in RRCSetup). Currently please bring back nof_bwps back to 1 in config.yaml as we are working on encrypted RRCReconfiguration-based BWP config monitoring.\n", bwp_id); + ERROR("bwp id %d ul or dl config never appears in RRCSetup (what we assume " + "now only checking in RRCSetup). Currently please bring back nof_bwps" + " back to 1 in config.yaml as we are working on encrypted" + "RRCReconfiguration-based BWP config monitoring.\n", bwp_id); return SRSRAN_ERROR; } if(bwp_dl_ded_s_ptr->pdcch_cfg.is_setup()){ pdcch_cfg.search_space[0].id = bwp_dl_ded_s_ptr->pdcch_cfg.setup(). - search_spaces_to_add_mod_list[0].search_space_id; + search_spaces_to_add_mod_list[0]. + search_space_id; pdcch_cfg.search_space[0].coreset_id = bwp_dl_ded_s_ptr->pdcch_cfg.setup(). - ctrl_res_set_to_add_mod_list[0].ctrl_res_set_id; + ctrl_res_set_to_add_mod_list[0]. + ctrl_res_set_id; - printf("pdcch_cfg.search_space[0].coreset_id in bwp%u: %u\n", bwp_id, pdcch_cfg.search_space[0].coreset_id); + printf("pdcch_cfg.search_space[0].coreset_id in bwp%u: %u\n", bwp_id, + pdcch_cfg.search_space[0].coreset_id); pdcch_cfg.search_space[0].type = srsran_search_space_type_ue; if(bwp_dl_ded_s_ptr->pdcch_cfg.setup(). - search_spaces_to_add_mod_list[0].search_space_type.ue_specific().dci_formats.formats0_minus1_and_minus1_minus1){ + search_spaces_to_add_mod_list[0].search_space_type.ue_specific(). + dci_formats.formats0_minus1_and_minus1_minus1){ pdcch_cfg.search_space[0].formats[0] = srsran_dci_format_nr_1_1; pdcch_cfg.search_space[0].formats[1] = srsran_dci_format_nr_0_1; dci_cfg.monitor_0_0_and_1_0 = false; dci_cfg.monitor_common_0_0 = false; - }else if(bwp_dl_ded_s_ptr->pdcch_cfg.setup().search_spaces_to_add_mod_list[0]. - search_space_type.ue_specific().dci_formats.formats0_minus0_and_minus1_minus0){ + }else if(bwp_dl_ded_s_ptr->pdcch_cfg.setup(). + search_spaces_to_add_mod_list[0].search_space_type.ue_specific(). + dci_formats.formats0_minus0_and_minus1_minus0){ pdcch_cfg.search_space[0].formats[0] = srsran_dci_format_nr_1_0; pdcch_cfg.search_space[0].formats[1] = srsran_dci_format_nr_0_0; dci_cfg.monitor_0_1_and_1_1 = false; @@ -148,8 +163,8 @@ int DCIDecoder::dci_decoder_and_reception_init(srsran_ue_dl_nr_sratescs_info arg pdcch_cfg.search_space[0].id = 2; pdcch_cfg.search_space[0].coreset_id = 1; pdcch_cfg.search_space[0].type = srsran_search_space_type_ue; - pdcch_cfg.search_space[0].formats[0] = srsran_dci_format_nr_1_1; // from RRCSetup - pdcch_cfg.search_space[0].formats[1] = srsran_dci_format_nr_0_1; // from RRCSetup + pdcch_cfg.search_space[0].formats[0] = srsran_dci_format_nr_1_1; + pdcch_cfg.search_space[0].formats[1] = srsran_dci_format_nr_0_1; dci_cfg.monitor_0_0_and_1_0 = false; dci_cfg.monitor_common_0_0 = false; pdcch_cfg.search_space[0].nof_formats = 2; @@ -168,7 +183,8 @@ int DCIDecoder::dci_decoder_and_reception_init(srsran_ue_dl_nr_sratescs_info arg ctrl_res_set_to_add_mod_list[0].dur; for(int i = 0; i < 45; i++){ coreset_n.freq_resources[i] = bwp_dl_ded_s_ptr->pdcch_cfg. - setup().ctrl_res_set_to_add_mod_list[0].freq_domain_res.get(45-i-1); + setup().ctrl_res_set_to_add_mod_list[0]. + freq_domain_res.get(45-i-1); } coreset_n.offset_rb = 0; if (bwp_dl_ded_s_ptr->pdcch_cfg. @@ -183,8 +199,8 @@ int DCIDecoder::dci_decoder_and_reception_init(srsran_ue_dl_nr_sratescs_info arg if (bwp_dl_ded_s_ptr->pdcch_cfg. setup().ctrl_res_set_to_add_mod_list[0].cce_reg_map_type.type() == - asn1::rrc_nr::ctrl_res_set_s::cce_reg_map_type_c_::types_opts::non_interleaved || - bwp_dl_ded_s_ptr->pdcch_cfg. + asn1::rrc_nr::ctrl_res_set_s::cce_reg_map_type_c_::types_opts:: + non_interleaved || bwp_dl_ded_s_ptr->pdcch_cfg. setup().ctrl_res_set_to_add_mod_list[0].cce_reg_map_type.type() == asn1::rrc_nr::ctrl_res_set_s::cce_reg_map_type_c_::types_opts::nulltype){ coreset_n.mapping_type = srsran_coreset_mapping_type_non_interleaved; @@ -194,17 +210,22 @@ int DCIDecoder::dci_decoder_and_reception_init(srsran_ue_dl_nr_sratescs_info arg }else{ coreset_n.mapping_type = srsran_coreset_mapping_type_interleaved; switch(bwp_dl_ded_s_ptr->pdcch_cfg. - setup().ctrl_res_set_to_add_mod_list[0].cce_reg_map_type.interleaved().interleaver_size){ - case asn1::rrc_nr::ctrl_res_set_s::cce_reg_map_type_c_::interleaved_s_::interleaver_size_e_::n2: + setup().ctrl_res_set_to_add_mod_list[0].cce_reg_map_type. + interleaved().interleaver_size){ + case asn1::rrc_nr::ctrl_res_set_s::cce_reg_map_type_c_::interleaved_s_:: + interleaver_size_e_::n2: coreset_n.interleaver_size = srsran_coreset_bundle_size_n2; break; - case asn1::rrc_nr::ctrl_res_set_s::cce_reg_map_type_c_::interleaved_s_::interleaver_size_e_::n3: + case asn1::rrc_nr::ctrl_res_set_s::cce_reg_map_type_c_::interleaved_s_:: + interleaver_size_e_::n3: coreset_n.interleaver_size = srsran_coreset_bundle_size_n3; break; - case asn1::rrc_nr::ctrl_res_set_s::cce_reg_map_type_c_::interleaved_s_::interleaver_size_e_::n6: + case asn1::rrc_nr::ctrl_res_set_s::cce_reg_map_type_c_::interleaved_s_:: + interleaver_size_e_::n6: coreset_n.interleaver_size = srsran_coreset_bundle_size_n6; break; - case asn1::rrc_nr::ctrl_res_set_s::cce_reg_map_type_c_::interleaved_s_::reg_bundle_size_e_::nulltype: + case asn1::rrc_nr::ctrl_res_set_s::cce_reg_map_type_c_::interleaved_s_:: + reg_bundle_size_e_::nulltype: ERROR("Interleaved size not found, set as bundle_size_n6\n"); coreset_n.reg_bundle_size = srsran_coreset_bundle_size_n6; break; @@ -214,19 +235,25 @@ int DCIDecoder::dci_decoder_and_reception_init(srsran_ue_dl_nr_sratescs_info arg break; } coreset_n.shift_index = bwp_dl_ded_s_ptr->pdcch_cfg. - setup().ctrl_res_set_to_add_mod_list[0].cce_reg_map_type.interleaved().shift_idx; + setup().ctrl_res_set_to_add_mod_list[0].cce_reg_map_type. + interleaved().shift_idx; switch(bwp_dl_ded_s_ptr->pdcch_cfg. - setup().ctrl_res_set_to_add_mod_list[0].cce_reg_map_type.interleaved().reg_bundle_size){ - case asn1::rrc_nr::ctrl_res_set_s::cce_reg_map_type_c_::interleaved_s_::reg_bundle_size_e_::n2: + setup().ctrl_res_set_to_add_mod_list[0].cce_reg_map_type. + interleaved().reg_bundle_size){ + case asn1::rrc_nr::ctrl_res_set_s::cce_reg_map_type_c_::interleaved_s_:: + reg_bundle_size_e_::n2: coreset_n.reg_bundle_size = srsran_coreset_bundle_size_n2; break; - case asn1::rrc_nr::ctrl_res_set_s::cce_reg_map_type_c_::interleaved_s_::reg_bundle_size_e_::n3: + case asn1::rrc_nr::ctrl_res_set_s::cce_reg_map_type_c_::interleaved_s_:: + reg_bundle_size_e_::n3: coreset_n.reg_bundle_size = srsran_coreset_bundle_size_n3; break; - case asn1::rrc_nr::ctrl_res_set_s::cce_reg_map_type_c_::interleaved_s_::reg_bundle_size_e_::n6: + case asn1::rrc_nr::ctrl_res_set_s::cce_reg_map_type_c_::interleaved_s_:: + reg_bundle_size_e_::n6: coreset_n.reg_bundle_size = srsran_coreset_bundle_size_n6; break; - case asn1::rrc_nr::ctrl_res_set_s::cce_reg_map_type_c_::interleaved_s_::reg_bundle_size_e_::nulltype: + case asn1::rrc_nr::ctrl_res_set_s::cce_reg_map_type_c_::interleaved_s_:: + reg_bundle_size_e_::nulltype: ERROR("Reg bundle size not found, set as bundle_size_n6\n"); coreset_n.reg_bundle_size = srsran_coreset_bundle_size_n6; break; @@ -237,10 +264,10 @@ int DCIDecoder::dci_decoder_and_reception_init(srsran_ue_dl_nr_sratescs_info arg } } coreset_n.dmrs_scrambling_id_present = bwp_dl_ded_s_ptr->pdcch_cfg. - setup().ctrl_res_set_to_add_mod_list[0].pdcch_dmrs_scrambling_id_present; + setup().ctrl_res_set_to_add_mod_list[0].pdcch_dmrs_scrambling_id_present; if (coreset_n.dmrs_scrambling_id_present){ coreset_n.dmrs_scrambling_id = bwp_dl_ded_s_ptr->pdcch_cfg. - setup().ctrl_res_set_to_add_mod_list[0].pdcch_dmrs_scrambling_id; + setup().ctrl_res_set_to_add_mod_list[0].pdcch_dmrs_scrambling_id; } printf("coreset_dmrs_scrambling id: %u\n", coreset_n.dmrs_scrambling_id); @@ -257,39 +284,44 @@ int DCIDecoder::dci_decoder_and_reception_init(srsran_ue_dl_nr_sratescs_info arg } // For FR1 offset_to_point_a uses prbs with 15kHz scs. - srsran_searcher_cfg_t = srsran_searcher_cfg_t_; + srsran_searcher_cfg_t = state->srsran_searcher_cfg_t; double pointA = srsran_searcher_cfg_t.ssb_freq_hz - (SRSRAN_SSB_BW_SUBC / 2) * - cell.abs_ssb_scs - cell.k_ssb * SRSRAN_SUBC_SPACING_NR(srsran_subcarrier_spacing_15kHz) - - sib1.serving_cell_cfg_common.dl_cfg_common.freq_info_dl.offset_to_point_a * - SRSRAN_SUBC_SPACING_NR(srsran_subcarrier_spacing_15kHz) * NRSCOPE_NSC_PER_RB_NR; + cell.abs_ssb_scs - cell.k_ssb * + SRSRAN_SUBC_SPACING_NR(srsran_subcarrier_spacing_15kHz) - + sib1.serving_cell_cfg_common.dl_cfg_common.freq_info_dl.offset_to_point_a * + SRSRAN_SUBC_SPACING_NR(srsran_subcarrier_spacing_15kHz) * + NRSCOPE_NSC_PER_RB_NR; std::cout << "pointA: " << pointA << std::endl; - double coreset1_center_freq_hz = pointA + srsran_coreset_get_bw(&coreset1_t) / 2 * - cell.abs_pdcch_scs * NRSCOPE_NSC_PER_RB_NR; + double coreset1_center_freq_hz = pointA + srsran_coreset_get_bw(&coreset1_t) / + 2 * cell.abs_pdcch_scs * NRSCOPE_NSC_PER_RB_NR; std::cout << "previous offset: " << arg_scs.coreset_offset_scs << std::endl; - arg_scs.coreset_offset_scs = (base_carrier.ssb_center_freq_hz - coreset1_center_freq_hz) / cell.abs_pdcch_scs; + arg_scs.coreset_offset_scs = (base_carrier.ssb_center_freq_hz - + coreset1_center_freq_hz) / cell.abs_pdcch_scs; std::cout << "current offset: " << arg_scs.coreset_offset_scs << std::endl; // set ra search space directly from the RRC Setup pdcch_cfg.search_space[0].nof_candidates[0] = bwp_dl_ded_s_ptr-> - pdcch_cfg.setup().search_spaces_to_add_mod_list[0]. - nrof_candidates.aggregation_level1; + pdcch_cfg.setup().search_spaces_to_add_mod_list[0]. + nrof_candidates.aggregation_level1; pdcch_cfg.search_space[0].nof_candidates[1] = bwp_dl_ded_s_ptr-> - pdcch_cfg.setup().search_spaces_to_add_mod_list[0]. - nrof_candidates.aggregation_level2; + pdcch_cfg.setup().search_spaces_to_add_mod_list[0]. + nrof_candidates.aggregation_level2; pdcch_cfg.search_space[0].nof_candidates[2] = bwp_dl_ded_s_ptr-> - pdcch_cfg.setup().search_spaces_to_add_mod_list[0]. - nrof_candidates.aggregation_level4; + pdcch_cfg.setup().search_spaces_to_add_mod_list[0]. + nrof_candidates.aggregation_level4; pdcch_cfg.search_space[0].nof_candidates[3] = bwp_dl_ded_s_ptr-> - pdcch_cfg.setup().search_spaces_to_add_mod_list[0]. - nrof_candidates.aggregation_level8; + pdcch_cfg.setup().search_spaces_to_add_mod_list[0]. + nrof_candidates.aggregation_level8; pdcch_cfg.search_space[0].nof_candidates[4] = bwp_dl_ded_s_ptr-> - pdcch_cfg.setup().search_spaces_to_add_mod_list[0]. - nrof_candidates.aggregation_level16; + pdcch_cfg.setup().search_spaces_to_add_mod_list[0]. + nrof_candidates.aggregation_level16; - dci_cfg.carrier_indicator_size = 0; // for carrier aggregation, we don't consider this situation. + /* for carrier aggregation, we don't consider this situation. */ + dci_cfg.carrier_indicator_size = 0; - dci_cfg.enable_sul = false; // if the supplementary_ul in sp_cell_cfg_ded is present. + /* if the supplementary_ul in sp_cell_cfg_ded is present. */ + dci_cfg.enable_sul = false; if(master_cell_group.sp_cell_cfg.sp_cell_cfg_ded.supplementary_ul_present){ dci_cfg.enable_sul = true; } @@ -301,18 +333,22 @@ int DCIDecoder::dci_decoder_and_reception_init(srsran_ue_dl_nr_sratescs_info arg /// Format 0_1 specific configuration (for PUSCH only) ///< Number of UL BWPs excluding the initial UL BWP, mentioned in the TS as N_BWP_RRC - dci_cfg.nof_ul_bwp = master_cell_group.sp_cell_cfg.sp_cell_cfg_ded.ul_cfg.ul_bwp_to_add_mod_list.size(); + dci_cfg.nof_ul_bwp = master_cell_group.sp_cell_cfg.sp_cell_cfg_ded.ul_cfg. + ul_bwp_to_add_mod_list.size(); ///< Number of dedicated PUSCH time domain resource assigment, set to 0 for default dci_cfg.nof_ul_time_res = bwp_ul_ded_s_ptr->pusch_cfg.setup(). - pusch_time_domain_alloc_list_present ? - bwp_ul_ded_s_ptr->pusch_cfg.setup(). - pusch_time_domain_alloc_list.setup().size() : - (sib1.serving_cell_cfg_common.ul_cfg_common_present ? - (sib1.serving_cell_cfg_common.ul_cfg_common.init_ul_bwp.pusch_cfg_common_present ? - sib1.serving_cell_cfg_common.ul_cfg_common.init_ul_bwp.pusch_cfg_common.setup().pusch_time_domain_alloc_list.size() : 0) : 0); + pusch_time_domain_alloc_list_present ? + bwp_ul_ded_s_ptr->pusch_cfg.setup(). + pusch_time_domain_alloc_list.setup().size() : + (sib1.serving_cell_cfg_common.ul_cfg_common_present ? + (sib1.serving_cell_cfg_common.ul_cfg_common.init_ul_bwp. + pusch_cfg_common_present ? + sib1.serving_cell_cfg_common.ul_cfg_common.init_ul_bwp.pusch_cfg_common. + setup().pusch_time_domain_alloc_list.size() : 0) : 0); + ///< Number of configured SRS resources dci_cfg.nof_srs = bwp_ul_ded_s_ptr->srs_cfg_present ? bwp_ul_ded_s_ptr->srs_cfg.setup(). - srs_res_to_add_mod_list.size() : 0; ///< Number of configured SRS resources + srs_res_to_add_mod_list.size() : 0; ///< Set to the maximum number of layers for PUSCH if(bwp_ul_ded_s_ptr->pusch_cfg.setup().max_rank_present){ @@ -322,19 +358,25 @@ int DCIDecoder::dci_decoder_and_reception_init(srsran_ue_dl_nr_sratescs_info arg } ///< determined by maxCodeBlockGroupsPerTransportBlock for PUSCH - if(master_cell_group.sp_cell_cfg.sp_cell_cfg_ded.pdsch_serving_cell_cfg.setup().code_block_group_tx_present){ - switch(master_cell_group.sp_cell_cfg.sp_cell_cfg_ded.pdsch_serving_cell_cfg.setup(). - code_block_group_tx.setup().max_code_block_groups_per_transport_block){ - case asn1::rrc_nr::pdsch_code_block_group_tx_s::max_code_block_groups_per_transport_block_opts::n2: + if(master_cell_group.sp_cell_cfg.sp_cell_cfg_ded.pdsch_serving_cell_cfg. + setup().code_block_group_tx_present){ + switch(master_cell_group.sp_cell_cfg.sp_cell_cfg_ded.pdsch_serving_cell_cfg. + setup().code_block_group_tx.setup(). + max_code_block_groups_per_transport_block){ + case asn1::rrc_nr::pdsch_code_block_group_tx_s:: + max_code_block_groups_per_transport_block_opts::n2: dci_cfg.pusch_nof_cbg = 2; break; - case asn1::rrc_nr::pdsch_code_block_group_tx_s::max_code_block_groups_per_transport_block_opts::n4: + case asn1::rrc_nr::pdsch_code_block_group_tx_s:: + max_code_block_groups_per_transport_block_opts::n4: dci_cfg.pusch_nof_cbg = 4; break; - case asn1::rrc_nr::pdsch_code_block_group_tx_s::max_code_block_groups_per_transport_block_opts::n6: + case asn1::rrc_nr::pdsch_code_block_group_tx_s:: + max_code_block_groups_per_transport_block_opts::n6: dci_cfg.pusch_nof_cbg = 6; break; - case asn1::rrc_nr::pdsch_code_block_group_tx_s::max_code_block_groups_per_transport_block_opts::n8: + case asn1::rrc_nr::pdsch_code_block_group_tx_s:: + max_code_block_groups_per_transport_block_opts::n8: dci_cfg.pusch_nof_cbg = 8; break; default: @@ -347,20 +389,24 @@ int DCIDecoder::dci_decoder_and_reception_init(srsran_ue_dl_nr_sratescs_info arg } if(master_cell_group.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg_present){ - dci_cfg.report_trigger_size = master_cell_group.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().report_trigger_size; + dci_cfg.report_trigger_size = master_cell_group.sp_cell_cfg. + sp_cell_cfg_ded.csi_meas_cfg.setup().report_trigger_size; }else{ dci_cfg.report_trigger_size = 0; ///< determined by reportTriggerSize } if(bwp_ul_ded_s_ptr->pusch_cfg.setup().transform_precoder == asn1::rrc_nr::pusch_cfg_s::transform_precoder_opts::disabled){ - dci_cfg.enable_transform_precoding = false; ///< Set to true if PUSCH transform precoding is enabled + /*< Set to true if PUSCH transform precoding is enabled */ + dci_cfg.enable_transform_precoding = false; } else if (bwp_ul_ded_s_ptr->pusch_cfg.setup().transform_precoder == asn1::rrc_nr::pusch_cfg_s::transform_precoder_opts::enabled){ - dci_cfg.enable_transform_precoding = true; ///< Set to true if PUSCH transform precoding is enabled + /*< Set to true if PUSCH transform precoding is enabled */ + dci_cfg.enable_transform_precoding = true; } - dci_cfg.pusch_tx_config_non_codebook = false; ///< Set to true if PUSCH txConfig is set to non-codebook + /* < Set to true if PUSCH txConfig is set to non-codebook */ + dci_cfg.pusch_tx_config_non_codebook = false; if(bwp_ul_ded_s_ptr->pusch_cfg.setup().tx_cfg_present){ if(bwp_ul_ded_s_ptr->pusch_cfg.setup().tx_cfg.value == bwp_ul_ded_s_ptr->pusch_cfg.setup().tx_cfg.codebook){ @@ -371,19 +417,26 @@ int DCIDecoder::dci_decoder_and_reception_init(srsran_ue_dl_nr_sratescs_info arg } } - if(bwp_ul_ded_s_ptr->pusch_cfg.setup().dmrs_ul_for_pusch_map_type_a.setup().phase_tracking_rs_present){ - dci_cfg.pusch_ptrs = true; ///< Set to true if PT-RS are enabled for PUSCH transmissionß + if(bwp_ul_ded_s_ptr->pusch_cfg.setup().dmrs_ul_for_pusch_map_type_a.setup(). + phase_tracking_rs_present){ + /*< Set to true if PT-RS are enabled for PUSCH transmissionß */ + dci_cfg.pusch_ptrs = true; } else { dci_cfg.pusch_ptrs = false; } - if(bwp_ul_ded_s_ptr->pusch_cfg.setup().uci_on_pusch.setup().beta_offsets_present){ - if(bwp_ul_ded_s_ptr->pusch_cfg.setup().uci_on_pusch.setup().beta_offsets.type() == - asn1::rrc_nr::uci_on_pusch_s::beta_offsets_c_::types_opts::dynamic_type){ - dci_cfg.pusch_dynamic_betas = true; ///< Set to true if beta offsets operation is not semi-static - } else if(bwp_ul_ded_s_ptr->pusch_cfg.setup().uci_on_pusch.setup().beta_offsets.type() == - asn1::rrc_nr::uci_on_pusch_s::beta_offsets_c_::types_opts::semi_static){ - dci_cfg.pusch_dynamic_betas = false; ///< Set to true if beta offsets operation is not semi-static + if(bwp_ul_ded_s_ptr->pusch_cfg.setup().uci_on_pusch.setup(). + beta_offsets_present){ + if(bwp_ul_ded_s_ptr->pusch_cfg.setup().uci_on_pusch.setup().beta_offsets. + type() == asn1::rrc_nr::uci_on_pusch_s::beta_offsets_c_::types_opts:: + dynamic_type){ + /* < Set to true if beta offsets operation is not semi-static */ + dci_cfg.pusch_dynamic_betas = true; + } else if(bwp_ul_ded_s_ptr->pusch_cfg.setup().uci_on_pusch.setup(). + beta_offsets.type() == asn1::rrc_nr::uci_on_pusch_s:: + beta_offsets_c_::types_opts::semi_static){ + /* < Set to true if beta offsets operation is not semi-static */ + dci_cfg.pusch_dynamic_betas = false; } else{ dci_cfg.pusch_dynamic_betas = false; } @@ -423,38 +476,47 @@ int DCIDecoder::dci_decoder_and_reception_init(srsran_ue_dl_nr_sratescs_info arg // } if(bwp_ul_ded_s_ptr->pusch_cfg.setup().dmrs_ul_for_pusch_map_type_a_present){ - if(bwp_ul_ded_s_ptr->pusch_cfg.setup().dmrs_ul_for_pusch_map_type_a.setup().dmrs_type_present){ + if(bwp_ul_ded_s_ptr->pusch_cfg.setup().dmrs_ul_for_pusch_map_type_a. + setup().dmrs_type_present){ dci_cfg.pusch_dmrs_type = srsran_dmrs_sch_type_2; } else{ dci_cfg.pusch_dmrs_type = srsran_dmrs_sch_type_1; } - if(bwp_ul_ded_s_ptr->pusch_cfg.setup().dmrs_ul_for_pusch_map_type_a.setup().max_len_present){ + if(bwp_ul_ded_s_ptr->pusch_cfg.setup().dmrs_ul_for_pusch_map_type_a. + setup().max_len_present){ dci_cfg.pusch_dmrs_max_len = srsran_dmrs_sch_len_2; }else{ dci_cfg.pusch_dmrs_max_len = srsran_dmrs_sch_len_1; } - }else if (bwp_ul_ded_s_ptr->pusch_cfg.setup().dmrs_ul_for_pusch_map_type_b_present){ - if(bwp_ul_ded_s_ptr->pusch_cfg.setup().dmrs_ul_for_pusch_map_type_b.setup().dmrs_type_present){ + }else if (bwp_ul_ded_s_ptr->pusch_cfg.setup(). + dmrs_ul_for_pusch_map_type_b_present){ + if(bwp_ul_ded_s_ptr->pusch_cfg.setup().dmrs_ul_for_pusch_map_type_b. + setup().dmrs_type_present){ dci_cfg.pusch_dmrs_type = srsran_dmrs_sch_type_2; } else{ dci_cfg.pusch_dmrs_type = srsran_dmrs_sch_type_1; } - if(bwp_ul_ded_s_ptr->pusch_cfg.setup().dmrs_ul_for_pusch_map_type_b.setup().max_len_present){ + if(bwp_ul_ded_s_ptr->pusch_cfg.setup().dmrs_ul_for_pusch_map_type_b. + setup().max_len_present){ dci_cfg.pusch_dmrs_max_len = srsran_dmrs_sch_len_2; }else{ dci_cfg.pusch_dmrs_max_len = srsran_dmrs_sch_len_1; } }else{ - dci_cfg.pusch_dmrs_type = srsran_dmrs_sch_type_1; ///< PUSCH DMRS type - dci_cfg.pusch_dmrs_max_len = srsran_dmrs_sch_len_1; ///< PUSCH DMRS maximum length + /* < PUSCH DMRS type */ + dci_cfg.pusch_dmrs_type = srsran_dmrs_sch_type_1; + /* < PUSCH DMRS maximum length */ + dci_cfg.pusch_dmrs_max_len = srsran_dmrs_sch_len_1; } /// Format 1_1 specific configuration (for PDSCH only) switch (master_cell_group.phys_cell_group_cfg.pdsch_harq_ack_codebook){ - case asn1::rrc_nr::phys_cell_group_cfg_s::pdsch_harq_ack_codebook_opts::dynamic_value: + case asn1::rrc_nr::phys_cell_group_cfg_s::pdsch_harq_ack_codebook_opts:: + dynamic_value: dci_cfg.harq_ack_codebok = srsran_pdsch_harq_ack_codebook_dynamic; break; - case asn1::rrc_nr::phys_cell_group_cfg_s::pdsch_harq_ack_codebook_opts::semi_static: + case asn1::rrc_nr::phys_cell_group_cfg_s::pdsch_harq_ack_codebook_opts:: + semi_static: dci_cfg.harq_ack_codebok = srsran_pdsch_harq_ack_codebook_semi_static; break; default: @@ -467,26 +529,31 @@ int DCIDecoder::dci_decoder_and_reception_init(srsran_ue_dl_nr_sratescs_info arg ///< Set to true if HARQ-ACK codebook is set to dynamic with 2 sub-codebooks dci_cfg.dynamic_dual_harq_ack_codebook = false; - dci_cfg.nof_dl_bwp = master_cell_group.sp_cell_cfg.sp_cell_cfg_ded.dl_bwp_to_add_mod_list.size(); - dci_cfg.nof_dl_time_res = bwp_dl_ded_s_ptr->pdsch_cfg.setup(). - pdsch_time_domain_alloc_list_present ? - bwp_dl_ded_s_ptr->pdsch_cfg.setup(). - pdsch_time_domain_alloc_list.setup().size() : ( sib1.serving_cell_cfg_common.dl_cfg_common.init_dl_bwp.pdsch_cfg_common_present ? - sib1.serving_cell_cfg_common.dl_cfg_common.init_dl_bwp.pdsch_cfg_common.setup().pdsch_time_domain_alloc_list.size() : 0 - ); - dci_cfg.nof_aperiodic_zp = bwp_dl_ded_s_ptr->pdsch_cfg.setup(). - aperiodic_zp_csi_rs_res_sets_to_add_mod_list.size(); - dci_cfg.pdsch_nof_cbg = bwp_dl_ded_s_ptr->pdsch_cfg.setup(). - max_nrof_code_words_sched_by_dci_present ? - bwp_dl_ded_s_ptr->pdsch_cfg.setup(). - max_nrof_code_words_sched_by_dci : 0; - dci_cfg.nof_dl_to_ul_ack = bwp_ul_ded_s_ptr->pucch_cfg.setup(). - dl_data_to_ul_ack.size(); + dci_cfg.nof_dl_bwp = master_cell_group.sp_cell_cfg.sp_cell_cfg_ded. + dl_bwp_to_add_mod_list.size(); + dci_cfg.nof_dl_time_res = bwp_dl_ded_s_ptr->pdsch_cfg.setup(). + pdsch_time_domain_alloc_list_present ? + bwp_dl_ded_s_ptr->pdsch_cfg.setup().pdsch_time_domain_alloc_list.setup(). + size() : ( sib1.serving_cell_cfg_common.dl_cfg_common.init_dl_bwp. + pdsch_cfg_common_present ? sib1.serving_cell_cfg_common.dl_cfg_common. + init_dl_bwp.pdsch_cfg_common.setup().pdsch_time_domain_alloc_list.size() : 0 + ); + dci_cfg.nof_aperiodic_zp = bwp_dl_ded_s_ptr->pdsch_cfg.setup(). + aperiodic_zp_csi_rs_res_sets_to_add_mod_list.size(); + dci_cfg.pdsch_nof_cbg = bwp_dl_ded_s_ptr->pdsch_cfg.setup(). + max_nrof_code_words_sched_by_dci_present ? + bwp_dl_ded_s_ptr->pdsch_cfg.setup(). + max_nrof_code_words_sched_by_dci : 0; + dci_cfg.nof_dl_to_ul_ack = bwp_ul_ded_s_ptr->pucch_cfg.setup(). + dl_data_to_ul_ack.size(); dci_cfg.pdsch_inter_prb_to_prb = bwp_dl_ded_s_ptr->pdsch_cfg.setup(). - vrb_to_prb_interleaver_present; - dci_cfg.pdsch_rm_pattern1 = bwp_dl_ded_s_ptr->pdsch_cfg.setup().rate_match_pattern_group1.size(); - dci_cfg.pdsch_rm_pattern2 = bwp_dl_ded_s_ptr->pdsch_cfg.setup().rate_match_pattern_group2.size(); - dci_cfg.pdsch_2cw = false; // set to false initially and if maxofcodewordscheduledbydci is 2, set to true. + vrb_to_prb_interleaver_present; + dci_cfg.pdsch_rm_pattern1 = bwp_dl_ded_s_ptr->pdsch_cfg.setup(). + rate_match_pattern_group1.size(); + dci_cfg.pdsch_rm_pattern2 = bwp_dl_ded_s_ptr->pdsch_cfg.setup(). + rate_match_pattern_group2.size(); + /* set to false initially and if maxofcodewordscheduledbydci is 2, set to true. */ + dci_cfg.pdsch_2cw = false; if (bwp_dl_ded_s_ptr->pdsch_cfg.setup().max_nrof_code_words_sched_by_dci_present){ if (bwp_dl_ded_s_ptr->pdsch_cfg.setup().max_nrof_code_words_sched_by_dci == asn1::rrc_nr::pdsch_cfg_s::max_nrof_code_words_sched_by_dci_opts::n2){ @@ -496,16 +563,18 @@ int DCIDecoder::dci_decoder_and_reception_init(srsran_ue_dl_nr_sratescs_info arg // Only consider one serving cell dci_cfg.multiple_scell = false; - dci_cfg.pdsch_tci = bwp_dl_ded_s_ptr->pdcch_cfg.setup().ctrl_res_set_to_add_mod_list[0]. - tci_present_in_dci_present ? true : false; - dci_cfg.pdsch_cbg_flush = master_cell_group.sp_cell_cfg.sp_cell_cfg_ded.pdsch_serving_cell_cfg.setup(). - code_block_group_tx_present ? true : false; + dci_cfg.pdsch_tci = bwp_dl_ded_s_ptr->pdcch_cfg.setup(). + ctrl_res_set_to_add_mod_list[0].tci_present_in_dci_present ? true : false; + dci_cfg.pdsch_cbg_flush = master_cell_group.sp_cell_cfg. + sp_cell_cfg_ded.pdsch_serving_cell_cfg.setup(). + code_block_group_tx_present ? true : false; dci_cfg.pdsch_dynamic_bundling = false; if(bwp_dl_ded_s_ptr->pdsch_cfg.setup().prb_bundling_type.type() == asn1::rrc_nr::pdsch_cfg_s::prb_bundling_type_c_::types_opts::dynamic_bundling){ dci_cfg.pdsch_dynamic_bundling = true; - ERROR("PRB dynamic bundling not implemented, which can cause being unable to find DCIs. We are working on it."); + ERROR("PRB dynamic bundling not implemented, which can cause being unable" + "to find DCIs. We are working on it."); } switch(bwp_dl_ded_s_ptr->pdsch_cfg.setup().res_alloc){ @@ -526,23 +595,28 @@ int DCIDecoder::dci_decoder_and_reception_init(srsran_ue_dl_nr_sratescs_info arg std::cout << "pdsch resource alloc: " << dci_cfg.pdsch_alloc_type << std::endl; if(bwp_dl_ded_s_ptr->pdsch_cfg.setup().dmrs_dl_for_pdsch_map_type_a_present){ - if(bwp_dl_ded_s_ptr->pdsch_cfg.setup().dmrs_dl_for_pdsch_map_type_a.setup().dmrs_type_present){ + if(bwp_dl_ded_s_ptr->pdsch_cfg.setup().dmrs_dl_for_pdsch_map_type_a.setup(). + dmrs_type_present){ dci_cfg.pdsch_dmrs_type = srsran_dmrs_sch_type_2; } else{ dci_cfg.pdsch_dmrs_type = srsran_dmrs_sch_type_1; } - if(bwp_dl_ded_s_ptr->pdsch_cfg.setup().dmrs_dl_for_pdsch_map_type_a.setup().max_len_present){ + if(bwp_dl_ded_s_ptr->pdsch_cfg.setup().dmrs_dl_for_pdsch_map_type_a.setup(). + max_len_present){ dci_cfg.pdsch_dmrs_max_len = srsran_dmrs_sch_len_2; }else{ dci_cfg.pdsch_dmrs_max_len = srsran_dmrs_sch_len_1; } - }else if (bwp_dl_ded_s_ptr->pdsch_cfg.setup().dmrs_dl_for_pdsch_map_type_b_present){ - if(bwp_dl_ded_s_ptr->pdsch_cfg.setup().dmrs_dl_for_pdsch_map_type_b.setup().dmrs_type_present){ + }else if (bwp_dl_ded_s_ptr->pdsch_cfg.setup(). + dmrs_dl_for_pdsch_map_type_b_present){ + if(bwp_dl_ded_s_ptr->pdsch_cfg.setup().dmrs_dl_for_pdsch_map_type_b.setup(). + dmrs_type_present){ dci_cfg.pdsch_dmrs_type = srsran_dmrs_sch_type_2; } else{ dci_cfg.pdsch_dmrs_type = srsran_dmrs_sch_type_1; } - if(bwp_dl_ded_s_ptr->pdsch_cfg.setup().dmrs_dl_for_pdsch_map_type_b.setup().max_len_present){ + if(bwp_dl_ded_s_ptr->pdsch_cfg.setup().dmrs_dl_for_pdsch_map_type_b.setup(). + max_len_present){ dci_cfg.pdsch_dmrs_max_len = srsran_dmrs_sch_len_2; }else{ dci_cfg.pdsch_dmrs_max_len = srsran_dmrs_sch_len_1; @@ -555,8 +629,10 @@ int DCIDecoder::dci_decoder_and_reception_init(srsran_ue_dl_nr_sratescs_info arg pdsch_hl_cfg.typeA_pos = cell.mib.dmrs_typeA_pos; pusch_hl_cfg.typeA_pos = cell.mib.dmrs_typeA_pos; if(bwp_dl_ded_s_ptr->pdsch_cfg.setup().dmrs_dl_for_pdsch_map_type_a_present){ - pdsch_hl_cfg.dmrs_typeA.present = bwp_dl_ded_s_ptr->pdsch_cfg.setup().dmrs_dl_for_pdsch_map_type_a_present; - switch(bwp_dl_ded_s_ptr->pdsch_cfg.setup().dmrs_dl_for_pdsch_map_type_a.setup().dmrs_add_position){ + pdsch_hl_cfg.dmrs_typeA.present = bwp_dl_ded_s_ptr->pdsch_cfg.setup(). + dmrs_dl_for_pdsch_map_type_a_present; + switch(bwp_dl_ded_s_ptr->pdsch_cfg.setup().dmrs_dl_for_pdsch_map_type_a. + setup().dmrs_add_position){ case asn1::rrc_nr::dmrs_dl_cfg_s::dmrs_add_position_opts::pos0: pdsch_hl_cfg.dmrs_typeA.additional_pos = srsran_dmrs_sch_add_pos_0; break; @@ -572,8 +648,10 @@ int DCIDecoder::dci_decoder_and_reception_init(srsran_ue_dl_nr_sratescs_info arg } if(bwp_ul_ded_s_ptr->pusch_cfg.setup().dmrs_ul_for_pusch_map_type_a_present){ - pusch_hl_cfg.dmrs_typeA.present = bwp_ul_ded_s_ptr->pusch_cfg.setup().dmrs_ul_for_pusch_map_type_a_present; - switch(bwp_ul_ded_s_ptr->pusch_cfg.setup().dmrs_ul_for_pusch_map_type_a.setup().dmrs_add_position){ + pusch_hl_cfg.dmrs_typeA.present = bwp_ul_ded_s_ptr->pusch_cfg.setup(). + dmrs_ul_for_pusch_map_type_a_present; + switch(bwp_ul_ded_s_ptr->pusch_cfg.setup().dmrs_ul_for_pusch_map_type_a. + setup().dmrs_add_position){ case asn1::rrc_nr::dmrs_ul_cfg_s::dmrs_add_position_opts::pos0: pusch_hl_cfg.dmrs_typeA.additional_pos = srsran_dmrs_sch_add_pos_0; break; @@ -591,18 +669,29 @@ int DCIDecoder::dci_decoder_and_reception_init(srsran_ue_dl_nr_sratescs_info arg pdsch_hl_cfg.alloc = dci_cfg.pdsch_alloc_type; pusch_hl_cfg.alloc = dci_cfg.pusch_alloc_type; - if(bwp_dl_ded_s_ptr->pdsch_cfg.setup().pdsch_time_domain_alloc_list.setup().size() > 0){ - for (uint32_t pdsch_time_id = 0; pdsch_time_id < bwp_dl_ded_s_ptr->pdsch_cfg.setup().pdsch_time_domain_alloc_list.setup().size(); pdsch_time_id++){ - if(bwp_dl_ded_s_ptr->pdsch_cfg.setup().pdsch_time_domain_alloc_list.setup()[pdsch_time_id].k0_present){ - pdsch_hl_cfg.common_time_ra[pdsch_time_id].k = bwp_dl_ded_s_ptr->pdsch_cfg.setup().pdsch_time_domain_alloc_list.setup()[pdsch_time_id].k0; + if(bwp_dl_ded_s_ptr->pdsch_cfg.setup().pdsch_time_domain_alloc_list.setup(). + size() > 0){ + for (uint32_t pdsch_time_id = 0; + pdsch_time_id < bwp_dl_ded_s_ptr->pdsch_cfg.setup(). + pdsch_time_domain_alloc_list.setup().size(); pdsch_time_id++){ + if(bwp_dl_ded_s_ptr->pdsch_cfg.setup().pdsch_time_domain_alloc_list. + setup()[pdsch_time_id].k0_present){ + pdsch_hl_cfg.common_time_ra[pdsch_time_id].k = + bwp_dl_ded_s_ptr->pdsch_cfg.setup().pdsch_time_domain_alloc_list. + setup()[pdsch_time_id].k0; } - pdsch_hl_cfg.common_time_ra[pdsch_time_id].sliv = bwp_dl_ded_s_ptr->pdsch_cfg.setup().pdsch_time_domain_alloc_list.setup()[pdsch_time_id].start_symbol_and_len; - switch(bwp_dl_ded_s_ptr->pdsch_cfg.setup().pdsch_time_domain_alloc_list.setup()[pdsch_time_id].map_type){ + pdsch_hl_cfg.common_time_ra[pdsch_time_id].sliv = + bwp_dl_ded_s_ptr->pdsch_cfg.setup().pdsch_time_domain_alloc_list. + setup()[pdsch_time_id].start_symbol_and_len; + switch(bwp_dl_ded_s_ptr->pdsch_cfg.setup().pdsch_time_domain_alloc_list. + setup()[pdsch_time_id].map_type){ case asn1::rrc_nr::pdsch_time_domain_res_alloc_s::map_type_e_::type_a: - pdsch_hl_cfg.common_time_ra[pdsch_time_id].mapping_type = srsran_sch_mapping_type_A; + pdsch_hl_cfg.common_time_ra[pdsch_time_id].mapping_type = + srsran_sch_mapping_type_A; break; case asn1::rrc_nr::pdsch_time_domain_res_alloc_s::map_type_e_::type_b: - pdsch_hl_cfg.common_time_ra[pdsch_time_id].mapping_type = srsran_sch_mapping_type_B; + pdsch_hl_cfg.common_time_ra[pdsch_time_id].mapping_type = + srsran_sch_mapping_type_B; break; case asn1::rrc_nr::pdsch_time_domain_res_alloc_s::map_type_e_::nulltype: break; @@ -610,20 +699,34 @@ int DCIDecoder::dci_decoder_and_reception_init(srsran_ue_dl_nr_sratescs_info arg break; } } - pdsch_hl_cfg.nof_common_time_ra = bwp_dl_ded_s_ptr->pdsch_cfg.setup().pdsch_time_domain_alloc_list.setup().size(); + pdsch_hl_cfg.nof_common_time_ra = bwp_dl_ded_s_ptr->pdsch_cfg.setup(). + pdsch_time_domain_alloc_list.setup().size(); }else{ // use SIB 1 config - for (uint32_t pdsch_time_id = 0; pdsch_time_id < sib1.serving_cell_cfg_common.dl_cfg_common.init_dl_bwp.pdsch_cfg_common.setup().pdsch_time_domain_alloc_list.size(); pdsch_time_id++){ - if(sib1.serving_cell_cfg_common.dl_cfg_common.init_dl_bwp.pdsch_cfg_common.setup().pdsch_time_domain_alloc_list[pdsch_time_id].k0_present){ - pdsch_hl_cfg.common_time_ra[pdsch_time_id].k = sib1.serving_cell_cfg_common.dl_cfg_common.init_dl_bwp.pdsch_cfg_common.setup().pdsch_time_domain_alloc_list[pdsch_time_id].k0; + for (uint32_t pdsch_time_id = 0; + pdsch_time_id < sib1.serving_cell_cfg_common.dl_cfg_common.init_dl_bwp. + pdsch_cfg_common.setup().pdsch_time_domain_alloc_list.size(); + pdsch_time_id++){ + if(sib1.serving_cell_cfg_common.dl_cfg_common.init_dl_bwp. + pdsch_cfg_common.setup(). + pdsch_time_domain_alloc_list[pdsch_time_id].k0_present){ + pdsch_hl_cfg.common_time_ra[pdsch_time_id].k = + sib1.serving_cell_cfg_common.dl_cfg_common.init_dl_bwp. + pdsch_cfg_common.setup().pdsch_time_domain_alloc_list[pdsch_time_id].k0; } - pdsch_hl_cfg.common_time_ra[pdsch_time_id].sliv = sib1.serving_cell_cfg_common.dl_cfg_common.init_dl_bwp.pdsch_cfg_common.setup().pdsch_time_domain_alloc_list[pdsch_time_id].start_symbol_and_len; - switch(sib1.serving_cell_cfg_common.dl_cfg_common.init_dl_bwp.pdsch_cfg_common.setup().pdsch_time_domain_alloc_list[pdsch_time_id].map_type){ + pdsch_hl_cfg.common_time_ra[pdsch_time_id].sliv = + sib1.serving_cell_cfg_common.dl_cfg_common.init_dl_bwp.pdsch_cfg_common. + setup().pdsch_time_domain_alloc_list[pdsch_time_id].start_symbol_and_len; + switch(sib1.serving_cell_cfg_common.dl_cfg_common.init_dl_bwp. + pdsch_cfg_common.setup().pdsch_time_domain_alloc_list[pdsch_time_id]. + map_type){ case asn1::rrc_nr::pdsch_time_domain_res_alloc_s::map_type_e_::type_a: - pdsch_hl_cfg.common_time_ra[pdsch_time_id].mapping_type = srsran_sch_mapping_type_A; + pdsch_hl_cfg.common_time_ra[pdsch_time_id].mapping_type = + srsran_sch_mapping_type_A; break; case asn1::rrc_nr::pdsch_time_domain_res_alloc_s::map_type_e_::type_b: - pdsch_hl_cfg.common_time_ra[pdsch_time_id].mapping_type = srsran_sch_mapping_type_B; + pdsch_hl_cfg.common_time_ra[pdsch_time_id].mapping_type = + srsran_sch_mapping_type_B; break; case asn1::rrc_nr::pdsch_time_domain_res_alloc_s::map_type_e_::nulltype: break; @@ -631,21 +734,34 @@ int DCIDecoder::dci_decoder_and_reception_init(srsran_ue_dl_nr_sratescs_info arg break; } } - pdsch_hl_cfg.nof_common_time_ra = sib1.serving_cell_cfg_common.dl_cfg_common.init_dl_bwp.pdsch_cfg_common.setup().pdsch_time_domain_alloc_list.size(); + pdsch_hl_cfg.nof_common_time_ra = sib1.serving_cell_cfg_common. + dl_cfg_common.init_dl_bwp.pdsch_cfg_common.setup(). + pdsch_time_domain_alloc_list.size(); } - if(bwp_ul_ded_s_ptr->pusch_cfg.setup().pusch_time_domain_alloc_list.setup().size() > 0){ - for (uint32_t pusch_time_id = 0; pusch_time_id < bwp_ul_ded_s_ptr->pusch_cfg.setup().pusch_time_domain_alloc_list.setup().size(); pusch_time_id++){ - if(bwp_ul_ded_s_ptr->pusch_cfg.setup().pusch_time_domain_alloc_list.setup()[pusch_time_id].k2_present){ - pusch_hl_cfg.common_time_ra[pusch_time_id].k = bwp_ul_ded_s_ptr->pusch_cfg.setup().pusch_time_domain_alloc_list.setup()[pusch_time_id].k2; + if(bwp_ul_ded_s_ptr->pusch_cfg.setup().pusch_time_domain_alloc_list.setup(). + size() > 0){ + for (uint32_t pusch_time_id = 0; pusch_time_id < + bwp_ul_ded_s_ptr->pusch_cfg.setup().pusch_time_domain_alloc_list. + setup().size(); pusch_time_id++){ + if(bwp_ul_ded_s_ptr->pusch_cfg.setup().pusch_time_domain_alloc_list. + setup()[pusch_time_id].k2_present){ + pusch_hl_cfg.common_time_ra[pusch_time_id].k = + bwp_ul_ded_s_ptr->pusch_cfg.setup().pusch_time_domain_alloc_list. + setup()[pusch_time_id].k2; } - pusch_hl_cfg.common_time_ra[pusch_time_id].sliv = bwp_ul_ded_s_ptr->pusch_cfg.setup().pusch_time_domain_alloc_list.setup()[pusch_time_id].start_symbol_and_len; - switch(bwp_ul_ded_s_ptr->pusch_cfg.setup().pusch_time_domain_alloc_list.setup()[pusch_time_id].map_type){ + pusch_hl_cfg.common_time_ra[pusch_time_id].sliv = + bwp_ul_ded_s_ptr->pusch_cfg.setup().pusch_time_domain_alloc_list. + setup()[pusch_time_id].start_symbol_and_len; + switch(bwp_ul_ded_s_ptr->pusch_cfg.setup().pusch_time_domain_alloc_list. + setup()[pusch_time_id].map_type){ case asn1::rrc_nr::pusch_time_domain_res_alloc_s::map_type_e_::type_a: - pusch_hl_cfg.common_time_ra[pusch_time_id].mapping_type = srsran_sch_mapping_type_A; + pusch_hl_cfg.common_time_ra[pusch_time_id].mapping_type = + srsran_sch_mapping_type_A; break; case asn1::rrc_nr::pusch_time_domain_res_alloc_s::map_type_e_::type_b: - pusch_hl_cfg.common_time_ra[pusch_time_id].mapping_type = srsran_sch_mapping_type_B; + pusch_hl_cfg.common_time_ra[pusch_time_id].mapping_type = + srsran_sch_mapping_type_B; break; case asn1::rrc_nr::pusch_time_domain_res_alloc_s::map_type_e_::nulltype: break; @@ -653,20 +769,34 @@ int DCIDecoder::dci_decoder_and_reception_init(srsran_ue_dl_nr_sratescs_info arg break; } } - pusch_hl_cfg.nof_common_time_ra = bwp_ul_ded_s_ptr->pusch_cfg.setup().pusch_time_domain_alloc_list.setup().size(); + pusch_hl_cfg.nof_common_time_ra = bwp_ul_ded_s_ptr->pusch_cfg.setup(). + pusch_time_domain_alloc_list.setup().size(); }else{ // use SIB 1 config - for (uint32_t pusch_time_id = 0; pusch_time_id < sib1.serving_cell_cfg_common.ul_cfg_common.init_ul_bwp.pusch_cfg_common.setup().pusch_time_domain_alloc_list.size(); pusch_time_id++){ - if(sib1.serving_cell_cfg_common.ul_cfg_common.init_ul_bwp.pusch_cfg_common.setup().pusch_time_domain_alloc_list[pusch_time_id].k2_present){ - pusch_hl_cfg.common_time_ra[pusch_time_id].k = sib1.serving_cell_cfg_common.ul_cfg_common.init_ul_bwp.pusch_cfg_common.setup().pusch_time_domain_alloc_list[pusch_time_id].k2; + for (uint32_t pusch_time_id = 0; pusch_time_id < sib1. + serving_cell_cfg_common.ul_cfg_common.init_ul_bwp.pusch_cfg_common. + setup().pusch_time_domain_alloc_list.size(); pusch_time_id++){ + if(sib1.serving_cell_cfg_common.ul_cfg_common.init_ul_bwp. + pusch_cfg_common.setup().pusch_time_domain_alloc_list[pusch_time_id]. + k2_present){ + pusch_hl_cfg.common_time_ra[pusch_time_id].k = sib1. + serving_cell_cfg_common.ul_cfg_common.init_ul_bwp.pusch_cfg_common. + setup().pusch_time_domain_alloc_list[pusch_time_id].k2; } - pusch_hl_cfg.common_time_ra[pusch_time_id].sliv = sib1.serving_cell_cfg_common.ul_cfg_common.init_ul_bwp.pusch_cfg_common.setup().pusch_time_domain_alloc_list[pusch_time_id].start_symbol_and_len; - switch(sib1.serving_cell_cfg_common.ul_cfg_common.init_ul_bwp.pusch_cfg_common.setup().pusch_time_domain_alloc_list[pusch_time_id].map_type){ + pusch_hl_cfg.common_time_ra[pusch_time_id].sliv = sib1. + serving_cell_cfg_common.ul_cfg_common.init_ul_bwp.pusch_cfg_common. + setup().pusch_time_domain_alloc_list[pusch_time_id]. + start_symbol_and_len; + switch(sib1.serving_cell_cfg_common.ul_cfg_common. + init_ul_bwp.pusch_cfg_common.setup(). + pusch_time_domain_alloc_list[pusch_time_id].map_type){ case asn1::rrc_nr::pdsch_time_domain_res_alloc_s::map_type_e_::type_a: - pusch_hl_cfg.common_time_ra[pusch_time_id].mapping_type = srsran_sch_mapping_type_A; + pusch_hl_cfg.common_time_ra[pusch_time_id].mapping_type = + srsran_sch_mapping_type_A; break; case asn1::rrc_nr::pdsch_time_domain_res_alloc_s::map_type_e_::type_b: - pusch_hl_cfg.common_time_ra[pusch_time_id].mapping_type = srsran_sch_mapping_type_B; + pusch_hl_cfg.common_time_ra[pusch_time_id].mapping_type = + srsran_sch_mapping_type_B; break; case asn1::rrc_nr::pdsch_time_domain_res_alloc_s::map_type_e_::nulltype: break; @@ -674,22 +804,30 @@ int DCIDecoder::dci_decoder_and_reception_init(srsran_ue_dl_nr_sratescs_info arg break; } } - pusch_hl_cfg.nof_common_time_ra = sib1.serving_cell_cfg_common.ul_cfg_common.init_ul_bwp.pusch_cfg_common.setup().pusch_time_domain_alloc_list.size(); + pusch_hl_cfg.nof_common_time_ra = sib1.serving_cell_cfg_common. + ul_cfg_common.init_ul_bwp.pusch_cfg_common.setup(). + pusch_time_domain_alloc_list.size(); } // config according to the SIB 1's UL and DL BWP size - dci_cfg.bwp_dl_initial_bw = sib1.serving_cell_cfg_common.dl_cfg_common.freq_info_dl.scs_specific_carrier_list[0].carrier_bw; - dci_cfg.bwp_dl_active_bw = sib1.serving_cell_cfg_common.dl_cfg_common.freq_info_dl.scs_specific_carrier_list[0].carrier_bw; - dci_cfg.bwp_ul_initial_bw = sib1.serving_cell_cfg_common.ul_cfg_common.freq_info_ul.scs_specific_carrier_list[0].carrier_bw; - dci_cfg.bwp_ul_active_bw = sib1.serving_cell_cfg_common.ul_cfg_common.freq_info_ul.scs_specific_carrier_list[0].carrier_bw; + dci_cfg.bwp_dl_initial_bw = sib1.serving_cell_cfg_common.dl_cfg_common. + freq_info_dl.scs_specific_carrier_list[0].carrier_bw; + dci_cfg.bwp_dl_active_bw = sib1.serving_cell_cfg_common.dl_cfg_common. + freq_info_dl.scs_specific_carrier_list[0].carrier_bw; + dci_cfg.bwp_ul_initial_bw = sib1.serving_cell_cfg_common.ul_cfg_common. + freq_info_ul.scs_specific_carrier_list[0].carrier_bw; + dci_cfg.bwp_ul_active_bw = sib1.serving_cell_cfg_common.ul_cfg_common. + freq_info_ul.scs_specific_carrier_list[0].carrier_bw; base_carrier.nof_prb = srsran_coreset_get_bw(&coreset1_t); carrier_dl = base_carrier; carrier_dl.nof_prb = dci_cfg.bwp_dl_active_bw; // Use a dummy carrier for resource calculation. // Use a fixed value for Amarisoft evaluation - carrier_dl.max_mimo_layers = master_cell_group.sp_cell_cfg.sp_cell_cfg_ded.pdsch_serving_cell_cfg_present ? - master_cell_group.sp_cell_cfg.sp_cell_cfg_ded.pdsch_serving_cell_cfg.setup().max_mimo_layers_present ? - master_cell_group.sp_cell_cfg.sp_cell_cfg_ded.pdsch_serving_cell_cfg.setup().max_mimo_layers : 2 : 2; + carrier_dl.max_mimo_layers = master_cell_group.sp_cell_cfg.sp_cell_cfg_ded. + pdsch_serving_cell_cfg_present ? master_cell_group.sp_cell_cfg. + sp_cell_cfg_ded.pdsch_serving_cell_cfg.setup().max_mimo_layers_present ? + master_cell_group.sp_cell_cfg.sp_cell_cfg_ded.pdsch_serving_cell_cfg. + setup().max_mimo_layers : 2 : 2; carrier_ul = base_carrier; carrier_ul.nof_prb = dci_cfg.bwp_ul_active_bw; @@ -698,10 +836,12 @@ int DCIDecoder::dci_decoder_and_reception_init(srsran_ue_dl_nr_sratescs_info arg dci_cfg.nof_rb_groups = 0; if(dci_cfg.pdsch_alloc_type == srsran_resource_alloc_type0){ - if(bwp_dl_ded_s_ptr->pdsch_cfg.setup().rbg_size == asn1::rrc_nr::pdsch_cfg_s::rbg_size_opts::cfg1){ + if(bwp_dl_ded_s_ptr->pdsch_cfg.setup().rbg_size == + asn1::rrc_nr::pdsch_cfg_s::rbg_size_opts::cfg1){ // BWP start prb is set to 0 since this is the only scenario that we see dci_cfg.nof_rb_groups = get_nof_rbgs(dci_cfg.bwp_dl_active_bw, 0, true); - }else if (bwp_dl_ded_s_ptr->pdsch_cfg.setup().rbg_size == asn1::rrc_nr::pdsch_cfg_s::rbg_size_opts::cfg2){ + }else if (bwp_dl_ded_s_ptr->pdsch_cfg.setup().rbg_size == + asn1::rrc_nr::pdsch_cfg_s::rbg_size_opts::cfg2){ dci_cfg.nof_rb_groups = get_nof_rbgs(dci_cfg.bwp_dl_active_bw, 0, false); } } @@ -718,7 +858,8 @@ int DCIDecoder::dci_decoder_and_reception_init(srsran_ue_dl_nr_sratescs_info arg ERROR("Error setting CORESET"); return SRSRAN_ERROR; } - if (srsran_softbuffer_rx_init_guru(&softbuffer, SRSRAN_SCH_NR_MAX_NOF_CB_LDPC, SRSRAN_LDPC_MAX_LEN_ENCODED_CB) < + if (srsran_softbuffer_rx_init_guru(&softbuffer, + SRSRAN_SCH_NR_MAX_NOF_CB_LDPC, SRSRAN_LDPC_MAX_LEN_ENCODED_CB) < SRSRAN_SUCCESS) { ERROR("Error init soft-buffer"); return SRSRAN_ERROR; @@ -728,35 +869,34 @@ int DCIDecoder::dci_decoder_and_reception_init(srsran_ue_dl_nr_sratescs_info arg } -int DCIDecoder::decode_and_parse_dci_from_slot(srsran_slot_cfg_t* slot, - bool rach_found, - bool dci_inited, - uint32_t nof_known_rntis, - uint32_t nof_rnti_worker_groups, - std::vector & sharded_results, - std::vector >& sharded_rntis, - std::vector& nof_sharded_rntis, - std::vector& known_rntis, - std::vector & dl_prb_rate, - std::vector & dl_prb_bits_rate, - std::vector & ul_prb_rate, - std::vector & ul_prb_bits_rate){ - if(!rach_found or !dci_inited){ - std::cout << "RACH not found or DCI decoder not initialized, quitting..." << std::endl; +int DCIDecoder::DecodeandParseDCIfromSlot(srsran_slot_cfg_t* slot, + WorkState* state, + std::vector & sharded_results, + std::vector >& sharded_rntis, + std::vector & nof_sharded_rntis, + std::vector & dl_prb_rate, + std::vector & dl_prb_bits_rate, + std::vector & ul_prb_rate, + std::vector & ul_prb_bits_rate){ + if(!state->rach_found or !state->dci_inited){ + std::cout << "RACH not found or DCI decoder not initialized, quitting..." + << std::endl; return SRSRAN_SUCCESS; } - uint32_t n_rntis = (uint32_t) ceil((float) nof_known_rntis / (float) nof_rnti_worker_groups); + uint32_t n_rntis = (uint32_t) ceil((float) state->nof_known_rntis / + (float) state->nof_rnti_worker_groups); uint32_t rnti_s = rnti_worker_group_id * n_rntis; uint32_t rnti_e = rnti_worker_group_id * n_rntis + n_rntis; - if(rnti_s >= nof_known_rntis){ - // std::cout << "DCI decoder " << dci_decoder_id << "|" << rnti_worker_group_id << " exits because it's excessive.." << std::endl; + if(rnti_s >= state->nof_known_rntis){ + // std::cout << "DCI decoder " << dci_decoder_id << "|" + // << rnti_worker_group_id << " exits because it's excessive.." << std::endl; return SRSRAN_SUCCESS; } - if(rnti_e > nof_known_rntis){ - rnti_e = nof_known_rntis; + if(rnti_e > state->nof_known_rntis){ + rnti_e = state->nof_known_rntis; n_rntis = rnti_e - rnti_s; } @@ -778,11 +918,12 @@ int DCIDecoder::decode_and_parse_dci_from_slot(srsran_slot_cfg_t* slot, sharded_rntis[dci_decoder_id].resize(n_rntis); nof_sharded_rntis[dci_decoder_id] = n_rntis; - // std::cout << "nof_sharded_rntis[dci_decoder_id]: " << nof_sharded_rntis[dci_decoder_id] << std::endl; + // std::cout << "nof_sharded_rntis[dci_decoder_id]: " + // << nof_sharded_rntis[dci_decoder_id] << std::endl; // std::cout << "sharded_rntis: "; for(uint32_t i = 0; i < n_rntis; i++){ - sharded_rntis[dci_decoder_id][i] = known_rntis[rnti_s + i]; + sharded_rntis[dci_decoder_id][i] = state->known_rntis[rnti_s + i]; // std::cout << sharded_rntis[dci_decoder_id][i] << ", "; } // std::cout << std::endl; @@ -803,14 +944,17 @@ int DCIDecoder::decode_and_parse_dci_from_slot(srsran_slot_cfg_t* slot, memcpy(ue_dl_tmp, &ue_dl_dci, sizeof(srsran_ue_dl_nr_t)); memcpy(slot_tmp, slot, sizeof(srsran_slot_cfg_t)); - int nof_dl_dci = srsran_ue_dl_nr_find_dl_dci_nrscope_dciloop(ue_dl_tmp, slot_tmp, sharded_rntis[dci_decoder_id][rnti_idx], - srsran_rnti_type_c, dci_dl_tmp, 4); + int nof_dl_dci = srsran_ue_dl_nr_find_dl_dci_nrscope_dciloop(ue_dl_tmp, + slot_tmp, sharded_rntis[dci_decoder_id][rnti_idx], srsran_rnti_type_c, + dci_dl_tmp, 4); if (nof_dl_dci < SRSRAN_SUCCESS) { ERROR("Error in blind search"); } - int nof_ul_dci = srsran_ue_dl_nr_find_ul_dci(ue_dl_tmp, slot_tmp, sharded_rntis[dci_decoder_id][rnti_idx], srsran_rnti_type_c, dci_ul_tmp, 4); + int nof_ul_dci = srsran_ue_dl_nr_find_ul_dci(ue_dl_tmp, slot_tmp, + sharded_rntis[dci_decoder_id][rnti_idx], srsran_rnti_type_c, + dci_ul_tmp, 4); if(nof_dl_dci > 0){ dci_dl[rnti_idx] = dci_dl_tmp[0]; @@ -826,20 +970,25 @@ int DCIDecoder::decode_and_parse_dci_from_slot(srsran_slot_cfg_t* slot, if(total_dl_dci > 0){ for (uint32_t dci_idx_dl = 0; dci_idx_dl < n_rntis; dci_idx_dl++){ // the rnti will not be copied if no dci found - if(dci_dl[dci_idx_dl].ctx.rnti == sharded_rntis[dci_decoder_id][dci_idx_dl]){ - sharded_results[dci_decoder_id].dl_dcis[dci_idx_dl] = dci_dl[dci_idx_dl]; + if(dci_dl[dci_idx_dl].ctx.rnti == + sharded_rntis[dci_decoder_id][dci_idx_dl]){ + sharded_results[dci_decoder_id].dl_dcis[dci_idx_dl] = + dci_dl[dci_idx_dl]; char str[1024] = {}; - srsran_dci_dl_nr_to_str(&(ue_dl_dci.dci), &dci_dl[dci_idx_dl], str, (uint32_t)sizeof(str)); + srsran_dci_dl_nr_to_str(&(ue_dl_dci.dci), &dci_dl[dci_idx_dl], + str, (uint32_t)sizeof(str)); printf("DCIDecoder -- Found DCI: %s\n", str); // The grant may not be decoded correctly, since srsRAN's code is not complete. // We can calculate the DL bandwidth for this subframe by ourselves. if(dci_dl[dci_idx_dl].ctx.format == srsran_dci_format_nr_1_1) { srsran_sch_cfg_nr_t pdsch_cfg = {}; pdsch_hl_cfg.mcs_table = srsran_mcs_table_256qam; - // printf("pdsch_hl_cfg.dmrs_typeA.additional_pos: %d\n", pdsch_hl_cfg.dmrs_typeA.additional_pos); + // printf("pdsch_hl_cfg.dmrs_typeA.additional_pos: %d\n", + // pdsch_hl_cfg.dmrs_typeA.additional_pos); - if (srsran_ra_dl_dci_to_grant_nr(&carrier_dl, slot, &pdsch_hl_cfg, &dci_dl[dci_idx_dl], - &pdsch_cfg, &pdsch_cfg.grant) < SRSRAN_SUCCESS) { + if (srsran_ra_dl_dci_to_grant_nr(&carrier_dl, slot, &pdsch_hl_cfg, + &dci_dl[dci_idx_dl], &pdsch_cfg, &pdsch_cfg.grant) < + SRSRAN_SUCCESS) { ERROR("Error decoding PDSCH search"); // return result; } @@ -847,46 +996,68 @@ int DCIDecoder::decode_and_parse_dci_from_slot(srsran_slot_cfg_t* slot, printf("DCIDecoder -- PDSCH_cfg:\n%s", str); sharded_results[dci_decoder_id].dl_grants[dci_idx_dl] = pdsch_cfg; - sharded_results[dci_decoder_id].nof_dl_used_prbs += pdsch_cfg.grant.nof_prb * pdsch_cfg.grant.L; + sharded_results[dci_decoder_id].nof_dl_used_prbs += pdsch_cfg.grant. + nof_prb * pdsch_cfg.grant.L; dl_prb_rate[dci_idx_dl+rnti_s] = (float)(pdsch_cfg.grant.tb[0].tbs + - pdsch_cfg.grant.tb[1].tbs) / (float)pdsch_cfg.grant.nof_prb / (float)pdsch_cfg.grant.L; - dl_prb_bits_rate[dci_idx_dl+rnti_s] = (float)(pdsch_cfg.grant.tb[0].nof_bits + - pdsch_cfg.grant.tb[1].nof_bits) / (float)pdsch_cfg.grant.nof_prb / (float)pdsch_cfg.grant.L; + pdsch_cfg.grant.tb[1].tbs) / (float)pdsch_cfg.grant.nof_prb / + (float)pdsch_cfg.grant.L; + dl_prb_bits_rate[dci_idx_dl+rnti_s] = (float)(pdsch_cfg.grant.tb[0]. + nof_bits + pdsch_cfg.grant.tb[1].nof_bits) / + (float)pdsch_cfg.grant.nof_prb / (float)pdsch_cfg.grant.L; } } } - // task_scheduler_nrscope->result.nof_dl_spare_prbs = carrier_dl.nof_prb * (14 - 2) - task_scheduler_nrscope->result.nof_dl_used_prbs; + // task_scheduler_nrscope->result.nof_dl_spare_prbs = + // carrier_dl.nof_prb * (14 - 2) - + // task_scheduler_nrscope->result.nof_dl_used_prbs; // for(uint32_t idx = 0; idx < task_scheduler_nrscope->nof_known_rntis; idx ++){ - // task_scheduler_nrscope->result.spare_dl_prbs[idx] = task_scheduler_nrscope->result.nof_dl_spare_prbs / task_scheduler_nrscope->nof_known_rntis; - // if(abs(task_scheduler_nrscope->result.spare_dl_prbs[idx]) > carrier_dl.nof_prb * (14 - 2)){ + // task_scheduler_nrscope->result.spare_dl_prbs[idx] = + // task_scheduler_nrscope->result.nof_dl_spare_prbs / + // task_scheduler_nrscope->nof_known_rntis; + // if(abs(task_scheduler_nrscope->result.spare_dl_prbs[idx]) > + // carrier_dl.nof_prb * (14 - 2)){ // task_scheduler_nrscope->result.spare_dl_prbs[idx] = 0; // } - // task_scheduler_nrscope->result.spare_dl_tbs[idx] = (int) ((float)task_scheduler_nrscope->result.spare_dl_prbs[idx] * dl_prb_rate[idx]); - // task_scheduler_nrscope->result.spare_dl_bits[idx] = (int) ((float)task_scheduler_nrscope->result.spare_dl_prbs[idx] * dl_prb_bits_rate[idx]); + // task_scheduler_nrscope->result.spare_dl_tbs[idx] = + // (int) ((float)task_scheduler_nrscope->result.spare_dl_prbs[idx] + // * dl_prb_rate[idx]); + // task_scheduler_nrscope->result.spare_dl_bits[idx] = + // (int) ((float)task_scheduler_nrscope->result.spare_dl_prbs[idx] * + // dl_prb_bits_rate[idx]); // } }else{ - // task_scheduler_nrscope->result.nof_dl_spare_prbs = carrier_dl.nof_prb * (14 - 2); + // task_scheduler_nrscope->result.nof_dl_spare_prbs = + // carrier_dl.nof_prb * (14 - 2); // for(uint32_t idx = 0; idx < task_scheduler_nrscope->nof_known_rntis; idx++){ - // task_scheduler_nrscope->result.spare_dl_prbs[idx] = (int)((float)task_scheduler_nrscope->result.nof_dl_spare_prbs / (float)task_scheduler_nrscope->nof_known_rntis); - // task_scheduler_nrscope->result.spare_dl_tbs[idx] = (int) ((float)task_scheduler_nrscope->result.spare_dl_prbs[idx] * dl_prb_rate[idx]); - // task_scheduler_nrscope->result.spare_dl_bits[idx] = (int) ((float)task_scheduler_nrscope->result.spare_dl_prbs[idx] * dl_prb_bits_rate[idx]); + // task_scheduler_nrscope->result.spare_dl_prbs[idx] = + // (int)((float)task_scheduler_nrscope->result.nof_dl_spare_prbs / + // (float)task_scheduler_nrscope->nof_known_rntis); + // task_scheduler_nrscope->result.spare_dl_tbs[idx] = + // (int) ((float)task_scheduler_nrscope->result.spare_dl_prbs[idx] * + // dl_prb_rate[idx]); + // task_scheduler_nrscope->result.spare_dl_bits[idx] = + // (int) ((float)task_scheduler_nrscope->result.spare_dl_prbs[idx] * + // dl_prb_bits_rate[idx]); // } } if(total_ul_dci > 0){ for (uint32_t dci_idx_ul = 0; dci_idx_ul < n_rntis; dci_idx_ul++){ - if(dci_ul[dci_idx_ul].ctx.rnti == sharded_rntis[dci_decoder_id][dci_idx_ul]){ + if(dci_ul[dci_idx_ul].ctx.rnti == + sharded_rntis[dci_decoder_id][dci_idx_ul]){ sharded_results[dci_decoder_id].ul_dcis[dci_idx_ul] = dci_ul[dci_idx_ul]; char str[1024] = {}; - srsran_dci_ul_nr_to_str(&(ue_dl_dci.dci), &dci_ul[dci_idx_ul], str, (uint32_t)sizeof(str)); + srsran_dci_ul_nr_to_str(&(ue_dl_dci.dci), &dci_ul[dci_idx_ul], str, + (uint32_t)sizeof(str)); printf("DCIDecoder -- Found DCI: %s\n", str); // The grant may not be decoded correctly, since srsRAN's code is not complete. // We can calculate the UL bandwidth for this subframe by ourselves. srsran_sch_cfg_nr_t pusch_cfg = {}; pusch_hl_cfg.mcs_table = srsran_mcs_table_256qam; - if (srsran_ra_ul_dci_to_grant_nr(&carrier_ul, slot, &pusch_hl_cfg, &dci_ul[dci_idx_ul], - &pusch_cfg, &pusch_cfg.grant) < SRSRAN_SUCCESS) { + if (srsran_ra_ul_dci_to_grant_nr(&carrier_ul, slot, + &pusch_hl_cfg, &dci_ul[dci_idx_ul], &pusch_cfg, &pusch_cfg.grant) + < SRSRAN_SUCCESS) { ERROR("Error decoding PUSCH search"); // return result; } @@ -894,29 +1065,48 @@ int DCIDecoder::decode_and_parse_dci_from_slot(srsran_slot_cfg_t* slot, printf("DCIDecoder -- PUSCH_cfg:\n%s", str); sharded_results[dci_decoder_id].ul_grants[dci_idx_ul] = pusch_cfg; - sharded_results[dci_decoder_id].nof_ul_used_prbs += pusch_cfg.grant.nof_prb * pusch_cfg.grant.L; + sharded_results[dci_decoder_id].nof_ul_used_prbs += pusch_cfg.grant. + nof_prb * pusch_cfg.grant.L; ul_prb_rate[dci_idx_ul+rnti_s] = (float)(pusch_cfg.grant.tb[0].tbs + - pusch_cfg.grant.tb[1].tbs) / (float)pusch_cfg.grant.nof_prb / (float)pusch_cfg.grant.L; - ul_prb_bits_rate[dci_idx_ul+rnti_s] = (float)(pusch_cfg.grant.tb[0].nof_bits + - pusch_cfg.grant.tb[1].nof_bits) / (float)pusch_cfg.grant.nof_prb / (float)pusch_cfg.grant.L; + pusch_cfg.grant.tb[1].tbs) / (float)pusch_cfg.grant.nof_prb / + (float)pusch_cfg.grant.L; + ul_prb_bits_rate[dci_idx_ul+rnti_s] = (float)(pusch_cfg.grant.tb[0]. + nof_bits + pusch_cfg.grant.tb[1].nof_bits) / + (float)pusch_cfg.grant.nof_prb / (float)pusch_cfg.grant.L; } } - // task_scheduler_nrscope->result.nof_ul_spare_prbs = carrier_dl.nof_prb * (14 - 2) - task_scheduler_nrscope->result.nof_ul_used_prbs; + // task_scheduler_nrscope->result.nof_ul_spare_prbs = + // carrier_dl.nof_prb * (14 - 2) - + // task_scheduler_nrscope->result.nof_ul_used_prbs; // for(uint32_t idx = 0; idx < task_scheduler_nrscope->nof_known_rntis; idx ++){ - // task_scheduler_nrscope->result.spare_ul_prbs[idx] = task_scheduler_nrscope->result.nof_ul_spare_prbs / task_scheduler_nrscope->nof_known_rntis; - // task_scheduler_nrscope->result.spare_ul_tbs[idx] = (int) ((float)task_scheduler_nrscope->result.spare_ul_prbs[idx] * ul_prb_rate[idx]); - // task_scheduler_nrscope->result.spare_ul_bits[idx] = (int) ((float)task_scheduler_nrscope->result.spare_ul_prbs[idx] * ul_prb_bits_rate[idx]); + // task_scheduler_nrscope->result.spare_ul_prbs[idx] = + // task_scheduler_nrscope->result.nof_ul_spare_prbs / + // task_scheduler_nrscope->nof_known_rntis; + // task_scheduler_nrscope->result.spare_ul_tbs[idx] = + // (int) ((float)task_scheduler_nrscope->result.spare_ul_prbs[idx] * + // ul_prb_rate[idx]); + // task_scheduler_nrscope->result.spare_ul_bits[idx] = + // (int) ((float)task_scheduler_nrscope->result.spare_ul_prbs[idx] * + // ul_prb_bits_rate[idx]); // } }else{ - // task_scheduler_nrscope->result.nof_ul_spare_prbs = carrier_dl.nof_prb * (14 - 2); + // task_scheduler_nrscope->result.nof_ul_spare_prbs = + // carrier_dl.nof_prb * (14 - 2); // for(uint32_t idx = 0; idx < task_scheduler_nrscope->nof_known_rntis; idx ++){ - // task_scheduler_nrscope->result.spare_ul_prbs[idx] = (int)((float)task_scheduler_nrscope->result.nof_ul_spare_prbs / (float)task_scheduler_nrscope->nof_known_rntis); - // if(abs(task_scheduler_nrscope->result.spare_ul_prbs[idx]) > carrier_dl.nof_prb * (14 - 2)){ + // task_scheduler_nrscope->result.spare_ul_prbs[idx] = + // (int)((float)task_scheduler_nrscope->result.nof_ul_spare_prbs / + // (float)task_scheduler_nrscope->nof_known_rntis); + // if(abs(task_scheduler_nrscope->result.spare_ul_prbs[idx]) > + // carrier_dl.nof_prb * (14 - 2)){ // task_scheduler_nrscope->result.spare_ul_prbs[idx] = 0; // } - // task_scheduler_nrscope->result.spare_ul_tbs[idx] = (int) ((float)task_scheduler_nrscope->result.spare_ul_prbs[idx] * ul_prb_rate[idx]); - // task_scheduler_nrscope->result.spare_ul_bits[idx] = (int) ((float)task_scheduler_nrscope->result.spare_ul_prbs[idx] * ul_prb_bits_rate[idx]); + // task_scheduler_nrscope->result.spare_ul_tbs[idx] = + // (int) ((float)task_scheduler_nrscope->result.spare_ul_prbs[idx] * + // ul_prb_rate[idx]); + // task_scheduler_nrscope->result.spare_ul_bits[idx] = + // (int) ((float)task_scheduler_nrscope->result.spare_ul_prbs[idx] * + // ul_prb_bits_rate[idx]); // } } diff --git a/nrscope/src/libs/nrscope_worker.cc b/nrscope/src/libs/nrscope_worker.cc index f3404cf4..c781a67d 100644 --- a/nrscope/src/libs/nrscope_worker.cc +++ b/nrscope/src/libs/nrscope_worker.cc @@ -62,21 +62,44 @@ int NRScopeWorker::InitSIBDecoder(){ /* Will always be called before any tasks */ if(sibs_decoder.SIBDecoderandReceptionInit(&worker_state, rf_buffer_t.to_cf_t()) < SRSASN_SUCCESS){ - return NR_FAILURE; + return SRSRAN_ERROR; } + std::cout << "SIBs decoder initialized..." << std::endl; return SRSRAN_SUCCESS; } int NRScopeWorker::InitRACHDecoder() { - // std::thread rach_init_thread {&RachDecoder::rach_decoder_init, &rach_decoder, task_scheduler_nrscope.sib1, args_t.base_carrier}; - rach_decoder.RACHDecoderInit(&task_scheduler_nrscope); - srsran::rf_buffer_t rf_buffer_wrapper(rx_buffer, pre_resampling_sf_sz); - if(rach_decoder.rach_reception_init(arg_scs, &task_scheduler_nrscope, rf_buffer_wrapper.to_cf_t()) < SRSASN_SUCCESS){ + // std::thread rach_init_thread {&RachDecoder::rach_decoder_init, + // &rach_decoder, task_scheduler_nrscope.sib1, args_t.base_carrier}; + rach_decoder.RACHDecoderInit(worker_state); + if(rach_decoder.RACHReceptionInit(&worker_state, rf_buffer_t.to_cf_t()) < + SRSASN_SUCCESS){ ERROR("RACHDecoder Init Error"); - return NR_FAILURE; + return SRSRAN_ERROR; + } + std::cout << "RACH decoder initialized.." << std::endl; + return SRSRAN_SUCCESS; +} + +int NRScopeWorker::InitDCIDecoders() { + sharded_results.resize(worker_state.nof_threads); + nof_sharded_rntis.resize(worker_state.nof_threads); + sharded_rntis.resize(worker_state.nof_threads); + results.resize(worker_state.nof_bwps); + for(uint32_t i = 0; i < worker_state.nof_rnti_worker_groups; i++){ + // for each rnti worker group, for each bwp, spawn a decoder + for(uint8_t j = 0; j < worker_state.nof_bwps; j++){ + DCIDecoder *decoder = new DCIDecoder(100); + if(decoder->DCIDecoderandReceptionInit(&worker_state, j, + rf_buffer_t.to_cf_t()) < SRSASN_SUCCESS){ + ERROR("DCIDecoder Init Error"); + return SRSRAN_ERROR; + } + decoder->dci_decoder_id = i * worker_state.nof_bwps + j; + decoder->rnti_worker_group_id = i; + dci_decoders.push_back(std::unique_ptr (decoder)); + } } - std::cout << "RACH Decoder Initialized.." << std::endl; - task_scheduler_nrscope.rach_inited = true; return SRSRAN_SUCCESS; } @@ -99,11 +122,17 @@ int NRScopeWorker::SyncState(WorkState* task_scheduler_state) { for(long unsigned int i = 0; i < task_scheduler_state->sibs.size(); i++) { worker_state.sibs[i] = task_scheduler_state->sibs[i]; } - worker_state.found_sib.resize(task_scheduler_state->found_sib.size()); for(long unsigned int i = 0; i < task_scheduler_state->found_sib.size(); i++){ worker_state.found_sib[i] = task_scheduler_state->found_sib[i]; } + worker_state.sibs_to_be_found.resize( + task_scheduler_state->sibs_to_be_found.size()); + for(long unsigned int i = 0; i < + task_scheduler_state->sibs_to_be_found.size(); i++) { + worker_state.sibs_to_be_found[i] = + task_scheduler_state->sibs_to_be_found[i]; + } worker_state.rrc_setup = task_scheduler_state->rrc_setup; worker_state.master_cell_group = task_scheduler_state->master_cell_group; @@ -121,38 +150,107 @@ int NRScopeWorker::SyncState(WorkState* task_scheduler_state) { worker_state.sib1_inited = task_scheduler_state->sib1_inited; } + if (!worker_state.rach_inited && task_scheduler_state->rach_inited) { + InitRACHDecoder(); + worker_state.rach_inited = task_scheduler_state->rach_inited; + } + + if (!worker_state.dci_inited && task_scheduler_state->dci_inited) { + InitDCIDecoders(); + worker_state.dci_inited = task_scheduler_state->dci_inited; + } + + worker_state.nof_known_rntis = task_scheduler_state->nof_known_rntis; + worker_state.known_rntis.resize(worker_state.nof_known_rntis); + for (long unsigned int i = 0; i < worker_state.nof_known_rntis; i ++) { + worker_state.known_rntis[i] = task_scheduler_state->known_rntis[i]; + } + return SRSRAN_SUCCESS; +} - // if (!worker_state.rach_inited && task_scheduler_state->rach_inited) { - // if (srsran_unlikely(!worker_state.sib1_found)) { - // /* Error happens */ - // ERROR("SIB 1 is not found while trying to init RACH decoder."); - // return NR_FAILURE; - // } - // InitRACHDecoder(); - // worker_state.rach_inited = task_scheduler_state->rach_inited; - // } - - // bool dci_inited; // DCIDecoder is initialized. - - // uint32_t nof_known_rntis; - // std::vector known_rntis; - - /* Below this, these variables go to the result structure. */ - // std::vector nof_sharded_rntis; - // std::vector > sharded_rntis; - // std::vector sharded_results; - // uint32_t nof_threads; - // uint32_t nof_rnti_worker_groups; - // uint8_t nof_bwps; - - // std::vector dl_prb_rate; - // std::vector ul_prb_rate; - // std::vector dl_prb_bits_rate; - // std::vector ul_prb_bits_rate; - - // uint32_t new_rnti_number; - // std::vector new_rntis_found; +int NRScopeWorker::MergeResults(){ + for (uint8_t b = 0; b < worker_state.nof_bwps; b++) { + DCIFeedback new_result; + results[b] = new_result; + results[b].dl_grants.resize(worker_state.nof_known_rntis); + results[b].ul_grants.resize(worker_state.nof_known_rntis); + results[b].spare_dl_prbs.resize(worker_state.nof_known_rntis); + results[b].spare_dl_tbs.resize(worker_state.nof_known_rntis); + results[b].spare_dl_bits.resize(worker_state.nof_known_rntis); + results[b].spare_ul_prbs.resize(worker_state.nof_known_rntis); + results[b].spare_ul_tbs.resize(worker_state.nof_known_rntis); + results[b].spare_ul_bits.resize(worker_state.nof_known_rntis); + results[b].dl_dcis.resize(worker_state.nof_known_rntis); + results[b].ul_dcis.resize(worker_state.nof_known_rntis); + + uint32_t rnti_s = 0; + uint32_t rnti_e = 0; + for(uint32_t i = 0; i < worker_state.nof_rnti_worker_groups; i++){ + if(rnti_s >= worker_state.nof_known_rntis){ + continue; + } + uint32_t n_rntis = nof_sharded_rntis[i * worker_state.nof_bwps]; + rnti_e = rnti_s + n_rntis; + if(rnti_e > worker_state.nof_known_rntis){ + rnti_e = worker_state.nof_known_rntis; + } + + uint32_t thread_id = i * worker_state.nof_bwps + b; + results[b].nof_dl_used_prbs += + sharded_results[thread_id].nof_dl_used_prbs; + results[b].nof_ul_used_prbs += + sharded_results[thread_id].nof_ul_used_prbs; + + for(uint32_t k = 0; k < n_rntis; k++) { + results[b].dl_dcis[k+rnti_s] = sharded_results[thread_id].dl_dcis[k]; + results[b].ul_dcis[k+rnti_s] = sharded_results[thread_id].ul_dcis[k]; + results[b].dl_grants[k+rnti_s] = + sharded_results[thread_id].dl_grants[k]; + results[b].ul_grants[k+rnti_s] = + sharded_results[thread_id].ul_grants[k]; + } + rnti_s = rnti_e; + } + + std::cout << "End of nof_threads..." << std::endl; + + /* TO-DISCUSS: to obtain even more precise result, + here maybe we should total user payload prb in that bwp - used prb */ + results[b].nof_dl_spare_prbs = + worker_state.args_t.base_carrier.nof_prb * + (14 - 2) - results[b].nof_dl_used_prbs; + for(uint32_t idx = 0; idx < worker_state.nof_known_rntis; idx ++){ + results[b].spare_dl_prbs[idx] = results[b].nof_dl_spare_prbs / + worker_state.nof_known_rntis; + if(abs(results[b].spare_dl_prbs[idx]) > + worker_state.args_t.base_carrier.nof_prb * (14 - 2)){ + results[b].spare_dl_prbs[idx] = 0; + } + results[b].spare_dl_tbs[idx] = + (int) ((float)results[b].spare_dl_prbs[idx] * dl_prb_rate[idx]); + results[b].spare_dl_bits[idx] = + (int) ((float)results[b].spare_dl_prbs[idx] * dl_prb_bits_rate[idx]); + } + + results[b].nof_ul_spare_prbs = + worker_state.args_t.base_carrier.nof_prb * (14 - 2) - + results[b].nof_ul_used_prbs; + for(uint32_t idx = 0; idx < worker_state.nof_known_rntis; idx ++){ + results[b].spare_ul_prbs[idx] = results[b].nof_ul_spare_prbs / + worker_state.nof_known_rntis; + if(abs(results[b].spare_ul_prbs[idx]) > + worker_state.args_t.base_carrier.nof_prb * (14 - 2)){ + results[b].spare_ul_prbs[idx] = 0; + } + results[b].spare_ul_tbs[idx] = + (int) ((float)results[b].spare_ul_prbs[idx] * ul_prb_rate[idx]); + results[b].spare_ul_bits[idx] = + (int) ((float)results[b].spare_ul_prbs[idx] * ul_prb_bits_rate[idx]); + } + } + + return SRSRAN_SUCCESS; } void NRScopeWorker::Run() { @@ -163,6 +261,13 @@ void NRScopeWorker::Run() { busy = true; lock.unlock(); + SlotResult slot_result = {}; + /* Set the all the results to be false, will be set inside the decoder + threads */ + slot_result.sib_result = false; + slot_result.rach_result = false; + slot_result.dci_result = false; + /* If we accidentally assign the job without initializing the SIB decoder */ if(!worker_state.sib1_inited){ continue; @@ -170,43 +275,53 @@ void NRScopeWorker::Run() { std::thread sibs_thread; /* If sib1 is not found, we run the sibs_thread; if it's found, we skip. */ - if (!worker_state.sib1_found) { + if (worker_state.sib1_inited) { sibs_thread = std::thread {&SIBsDecoder::DecodeandParseSIB1fromSlot, - &sibs_decoder, &slot, worker_state}; + &sibs_decoder, &slot, &worker_state, &slot_result}; } - // std::thread rach_thread {&RachDecoder::decode_and_parse_msg4_from_slot, - // &rach_decoder, &slot, sib1_found, rach_inited, &rrc_setup, - // &master_cell_group, &rach_found, &new_rnti_number, &new_rntis_found}; + std::thread rach_thread; + if (worker_state.rach_inited) { + rach_thread = std::thread {&RachDecoder::DecodeandParseMS4fromSlot, + &rach_decoder, &slot, &worker_state, &slot_result}; + } - // std::vector dci_threads; - // if(dci_inited){ - // for (uint32_t i = 0; i < nof_threads; i++){ - // dci_threads.emplace_back(&DCIDecoder::decode_and_parse_dci_from_slot, - // dci_decoders[i].get(), &slot, nof_known_rntis, nof_rnti_worker_groups, - // sharded_results, sharded_rntis, nof_sharded_rntis, known_rntis, - // dl_prb_rate, dl_prb_bits_rate, ul_prb_rate, ul_prb_bits_rate); - // } - // } + std::vector dci_threads; + if(worker_state.dci_inited){ + slot_result.dci_result = true; + + dl_prb_rate.resize(worker_state.nof_known_rntis); + ul_prb_rate.resize(worker_state.nof_known_rntis); + dl_prb_bits_rate.resize(worker_state.nof_known_rntis); + ul_prb_bits_rate.resize(worker_state.nof_known_rntis); + + for (uint32_t i = 0; i < worker_state.nof_threads; i++){ + dci_threads.emplace_back(&DCIDecoder::DecodeandParseDCIfromSlot, + dci_decoders[i].get(), &slot, &worker_state, &sharded_results, + &sharded_rntis, &nof_sharded_rntis, &dl_prb_rate, &dl_prb_bits_rate, + &ul_prb_rate, &ul_prb_bits_rate); + } + } if(sibs_thread.joinable()){ sibs_thread.join(); } - // if(rach_thread.joinable()){ - // rach_thread.join(); - // } - - // if(dci_inited){ - // for (uint32_t i = 0; i < worker_state.nof_threads; i++){ - // if(dci_threads[i].joinable()){ - // dci_threads[i].join(); - // } - // } - // } + if(rach_thread.joinable()){ + rach_thread.join(); + } - /* TODO: Post result to a global result queue */ + if(worker_state.dci_inited){ + for (uint32_t i = 0; i < worker_state.nof_threads; i++){ + if(dci_threads[i].joinable()){ + dci_threads[i].join(); + } + } + MergeResults(); + slot_result.dci_feedback_results = results; + } + /* Post the result into the result queue*/ lock.lock(); busy = false; lock.unlock(); diff --git a/nrscope/src/libs/rach_decoder.cc b/nrscope/src/libs/rach_decoder.cc index 472f0238..0e5c89e5 100644 --- a/nrscope/src/libs/rach_decoder.cc +++ b/nrscope/src/libs/rach_decoder.cc @@ -265,12 +265,14 @@ int RachDecoder::RACHReceptionInit(WorkState* state, dl_center_frequency) / cell.abs_pdcch_scs; // The lower boundary of PDSCH can be not aligned with the lower boundary of PDCCH - if (srsran_ue_dl_nr_init_nrscope(&ue_dl_pdsch, input, &ue_dl_args, arg_scs_pdsch)) { + if (srsran_ue_dl_nr_init_nrscope(&ue_dl_pdsch, input, &ue_dl_args, + arg_scs_pdsch)) { ERROR("Error UE DL"); return SRSRAN_ERROR; } - if (srsran_ue_dl_nr_set_carrier_nrscope(&ue_dl_pdsch, &pdsch_carrier, arg_scs_pdsch)) { + if (srsran_ue_dl_nr_set_carrier_nrscope(&ue_dl_pdsch, &pdsch_carrier, + arg_scs_pdsch)) { ERROR("Error setting SCH NR carrier"); return SRSRAN_ERROR; } @@ -288,20 +290,21 @@ int RachDecoder::RACHReceptionInit(WorkState* state, int RachDecoder::DecodeandParseMS4fromSlot(srsran_slot_cfg_t* slot, - bool sib1_found, - bool rach_inited, - asn1::rrc_nr::rrc_setup_s* rrc_setup, - asn1::rrc_nr::cell_group_cfg_s* master_cell_group, - bool* rach_found, - uint32_t* new_rnti_number, - std::vector& new_rntis_found){ - if(!sib1_found or !rach_inited){ + WorkState* state, + SlotResult* result){ + if(!state->sib1_found or !state->rach_inited){ // If the SIB 1 is not detected or the RACH decoder is not initialized. std::cout << "SIB 1 not found or decoder not initialized, quitting..." << std::endl; + result->rach_result = false; return SRSRAN_SUCCESS; } + result->rach_result = true; + result->found_rach = false; + result->new_rnti_number = 0; + result->new_rntis_found.clear(); + uint16_t tc_rnti; uint16_t c_rnti; @@ -388,7 +391,8 @@ int RachDecoder::DecodeandParseMS4fromSlot(srsran_slot_cfg_t* slot, } // printf("Decoded PDSCH (%d B)\n", pdsch_cfg.grant.tb[0].tbs / 8); - // srsran_vec_fprint_byte(stdout, pdsch_res.tb[0].payload, pdsch_cfg.grant.tb[0].tbs / 8); + // srsran_vec_fprint_byte(stdout, pdsch_res.tb[0].payload, + // pdsch_cfg.grant.tb[0].tbs / 8); uint32_t bytes_offset = 0; for (uint32_t pdsch_res_idx = 0; pdsch_res_idx < @@ -426,8 +430,8 @@ int RachDecoder::DecodeandParseMS4fromSlot(srsran_slot_cfg_t* slot, std::cout << "Decoding Msg 4..." << std::endl; asn1::rrc_nr::dl_ccch_msg_s dlcch_msg; - // What the first few bytes are? In srsgNB there are 10 extra bytes and for small cell there are 3 extra bytes - // before the RRCSetup message. + /* What the first few bytes are? In srsgNB there are 10 extra bytes and for + small cell there are 3 extra bytes before the RRCSetup message. */ asn1::cbit_ref dlcch_bref(pdsch_res.tb[0].payload + bytes_offset, pdsch_cfg.grant.tb[0].tbs / 8 - bytes_offset); asn1::SRSASN_CODE err = dlcch_msg.unpack(dlcch_bref); @@ -436,7 +440,7 @@ int RachDecoder::DecodeandParseMS4fromSlot(srsran_slot_cfg_t* slot, pdsch_cfg.grant.tb[0].tbs / 8 - bytes_offset); } - *rrc_setup = dlcch_msg.msg.c1().rrc_setup(); + result->rrc_setup = dlcch_msg.msg.c1().rrc_setup(); std::cout << "Msg 4 Decoded." << std::endl; switch (dlcch_msg.msg.c1().type().value) { case asn1::rrc_nr::dl_ccch_msg_type_c::c1_c_::types::rrc_reject: { @@ -445,7 +449,9 @@ int RachDecoder::DecodeandParseMS4fromSlot(srsran_slot_cfg_t* slot, }break; case asn1::rrc_nr::dl_ccch_msg_type_c::c1_c_::types::rrc_setup: { std::cout << "It's a rrc_setup, hooray!" << std::endl; - printf("rrc-TransactionIdentifier: %u\n", (*rrc_setup).rrc_transaction_id); + printf("rrc-TransactionIdentifier: %u\n", + (result->rrc_setup).rrc_transaction_id); + result->found_rach = true; }break; default: { std::cout << "None detected, skip." << std::endl; @@ -457,9 +463,10 @@ int RachDecoder::DecodeandParseMS4fromSlot(srsran_slot_cfg_t* slot, // asn1::json_writer js_msg4; // task_scheduler_nrscope->rrc_setup.to_json(js_msg4); // printf("rrcSetup content: %s\n", js_msg4.to_string().c_str()); - asn1::cbit_ref bref_cg((*rrc_setup).crit_exts.rrc_setup().master_cell_group.data(), - (*rrc_setup).crit_exts.rrc_setup().master_cell_group.size()); - if ((*master_cell_group).unpack(bref_cg) != asn1::SRSASN_SUCCESS) { + asn1::cbit_ref bref_cg((result->rrc_setup).crit_exts.rrc_setup(). + master_cell_group.data(), (result->rrc_setup).crit_exts.rrc_setup(). + master_cell_group.size()); + if ((result->master_cell_group).unpack(bref_cg) != asn1::SRSASN_SUCCESS) { ERROR("Could not unpack master cell group config."); return SRSRAN_ERROR; } @@ -468,19 +475,17 @@ int RachDecoder::DecodeandParseMS4fromSlot(srsran_slot_cfg_t* slot, // task_scheduler_nrscope->master_cell_group.to_json(js); // printf("masterCellGroup: %s\n", js.to_string().c_str()); - // Tells the task scheduler that the RACH is decoded and there are some entries in the know_rntis vector. - *rach_found = true; - - if (!(*master_cell_group).sp_cell_cfg.recfg_with_sync.new_ue_id){ + if (!(result->master_cell_group).sp_cell_cfg.recfg_with_sync.new_ue_id){ c_rnti = tc_rnti; }else{ - c_rnti = (*master_cell_group).sp_cell_cfg.recfg_with_sync.new_ue_id; + c_rnti = result->master_cell_group.sp_cell_cfg.recfg_with_sync.new_ue_id; } std::cout << "c-rnti: " << c_rnti << std::endl; - // Add the new rntis into a different list and update the known_rnti vector in the end of the threads. - *new_rnti_number += 1; - new_rntis_found.emplace_back(c_rnti); + /* Add the new rntis into a different list and update the + known_rnti vector in the end of the threads. */ + result->new_rnti_number += 1; + result->new_rntis_found.emplace_back(c_rnti); // task_scheduler_nrscope->nof_known_rntis += 1; // task_scheduler_nrscope->known_rntis.emplace_back(c_rnti); diff --git a/nrscope/src/libs/radio_nr.cc b/nrscope/src/libs/radio_nr.cc index 84db1444..6ffd3712 100644 --- a/nrscope/src/libs/radio_nr.cc +++ b/nrscope/src/libs/radio_nr.cc @@ -10,6 +10,7 @@ std::mutex lock_radio_nr; namespace NRScopeTask{ /* Add some global variables for the task_scheduler and workers */ + } Radio::Radio() : @@ -587,16 +588,17 @@ static int slot_sync_recv_callback(void* ptr, int Radio::SyncandDownlinkInit(){ //***** DL args Config Start *****// rf_buffer_t = srsran::rf_buffer_t(rx_buffer, - SRSRAN_NOF_SLOTS_PER_SF_NR(task_scheduler_nrscope.task_scheduler_state.args_t.ssb_scs) * - pre_resampling_slot_sz * 2); // only one sf here + SRSRAN_NOF_SLOTS_PER_SF_NR(task_scheduler_nrscope.task_scheduler_state. + args_t.ssb_scs) * pre_resampling_slot_sz * 2); // only one sf here // it appears the srsRAN is build on 15kHz scs, we need to use the srate and // scs to calculate the correct subframe size arg_scs.srate = task_scheduler_nrscope.task_scheduler_state.args_t.srate_hz; arg_scs.scs = task_scheduler_nrscope.task_scheduler_state.cell.mib.scs_common; arg_scs.coreset_offset_scs = (cs_args.ssb_freq_hz - - task_scheduler_nrscope.task_scheduler_state.coreset0_args_t.coreset0_center_freq_hz) / - task_scheduler_nrscope.task_scheduler_state.cell.abs_pdcch_scs; // + 12; + task_scheduler_nrscope.task_scheduler_state.coreset0_args_t. + coreset0_center_freq_hz) / task_scheduler_nrscope.task_scheduler_state. + cell.abs_pdcch_scs; // + 12; arg_scs.coreset_slot = (uint32_t)task_scheduler_nrscope.task_scheduler_state.coreset0_args_t.n_0; task_scheduler_nrscope.task_scheduler_state.arg_scs = arg_scs; @@ -634,7 +636,8 @@ int Radio::SyncandDownlinkInit(){ sync_cfg.ssb.srate_hz = task_scheduler_nrscope.task_scheduler_state.args_t.srate_hz; if (srsran_ue_sync_nr_set_cfg(&ue_sync_nr, &sync_cfg) < SRSRAN_SUCCESS) { printf("SYNC: failed to set cell configuration for N_id %d", sync_cfg.N_id); - logger.error("SYNC: failed to set cell configuration for N_id %d", sync_cfg.N_id); + logger.error("SYNC: failed to set cell configuration for N_id %d", + sync_cfg.N_id); return SRSRAN_ERROR; } @@ -647,8 +650,8 @@ int Radio::FetchAndResample(){ bool in_sync = false; uint32_t pre_resampling_sf_sz = - SRSRAN_NOF_SLOTS_PER_SF_NR(task_scheduler_nrscope.task_scheduler_state.args_t.ssb_scs) * - pre_resampling_slot_sz; + SRSRAN_NOF_SLOTS_PER_SF_NR(task_scheduler_nrscope.task_scheduler_state. + args_t.ssb_scs) * pre_resampling_slot_sz; while(true){ outcome.timestamp = last_rx_time.get(0); @@ -704,8 +707,8 @@ int Radio::FetchAndResample(){ int Radio::DecodeAndProcess(){ uint32_t pre_resampling_sf_sz = - SRSRAN_NOF_SLOTS_PER_SF_NR(task_scheduler_nrscope.task_scheduler_state.args_t.ssb_scs) * - pre_resampling_slot_sz; + SRSRAN_NOF_SLOTS_PER_SF_NR(task_scheduler_nrscope.task_scheduler_state. + args_t.ssb_scs) * pre_resampling_slot_sz; // if(!task_scheduler_nrscope.task_scheduler_state.sib1_inited){ // /* Initialize all the worker's sib decoder */ // srsran::rf_buffer_t rf_buffer_wrapper(rx_buffer, pre_resampling_sf_sz); diff --git a/nrscope/src/libs/sibs_decoder.cc b/nrscope/src/libs/sibs_decoder.cc index 5e50e83d..d13594d6 100644 --- a/nrscope/src/libs/sibs_decoder.cc +++ b/nrscope/src/libs/sibs_decoder.cc @@ -57,7 +57,7 @@ int SIBsDecoder::SIBDecoderandReceptionInit(WorkState* state, return SRSRAN_ERROR; } - if (srsran_ue_dl_nr_set_carrier_nrscope(&ue_dl_sibs, &base_carrier, arg_scs)) { + if (srsran_ue_dl_nr_set_carrier_nrscope(&ue_dl_sibs, &base_carrier, arg_scs)){ ERROR("Error setting SCH NR carrier"); return SRSRAN_ERROR; } @@ -81,14 +81,19 @@ int SIBsDecoder::SIBDecoderandReceptionInit(WorkState* state, } int SIBsDecoder::DecodeandParseSIB1fromSlot(srsran_slot_cfg_t* slot, - WorkState state) { - // srsran_slot_cfg_t* slot, - // bool* sibs_vec_inited, - // bool* all_sibs_found, - // std::vector& found_sib, - // std::vector& sibs, - // asn1::rrc_nr::sib1_s* sib1_){ - + WorkState* state, + SlotResult* result) { + if (state->all_sibs_found) { + result->sib_result = false; + return SRSRAN_SUCCESS; + } + + /* reset the result's elements */ + result->sib_result = true; + result->found_sib1 = false; + result->found_sib.clear(); + result->sibs.clear(); + memset(&dci_sibs, 0, sizeof(srsran_dci_dl_nr_t)); // FILE *fp; @@ -130,7 +135,8 @@ int SIBsDecoder::DecodeandParseSIB1fromSlot(srsran_slot_cfg_t* slot, } char str[1024] = {}; - srsran_dci_dl_nr_to_str(&(ue_dl_sibs.dci), &dci_sibs, str, (uint32_t)sizeof(str)); + srsran_dci_dl_nr_to_str(&(ue_dl_sibs.dci), &dci_sibs, str, + (uint32_t)sizeof(str)); printf("SIBDecoder -- Found DCI: %s\n", str); pdsch_cfg = {}; @@ -168,7 +174,8 @@ int SIBsDecoder::DecodeandParseSIB1fromSlot(srsran_slot_cfg_t* slot, return SRSRAN_ERROR; } // printf("Decoded PDSCH (%d B)\n", pdsch_cfg.grant.tb[0].tbs / 8); - // srsran_vec_fprint_byte(stdout, pdsch_res.tb[0].payload, pdsch_cfg.grant.tb[0].tbs / 8); + // srsran_vec_fprint_byte(stdout, pdsch_res.tb[0].payload, + // pdsch_cfg.grant.tb[0].tbs / 8); // check payload is not all null bool all_zero = true; @@ -184,40 +191,41 @@ int SIBsDecoder::DecodeandParseSIB1fromSlot(srsran_slot_cfg_t* slot, } std::cout << "Try to decode SIBs..." << std::endl; asn1::rrc_nr::bcch_dl_sch_msg_s dlsch_msg; - asn1::cbit_ref dlsch_bref(pdsch_res.tb[0].payload, pdsch_cfg.grant.tb[0].tbs / 8); + asn1::cbit_ref dlsch_bref(pdsch_res.tb[0].payload, + pdsch_cfg.grant.tb[0].tbs / 8); asn1::SRSASN_CODE err = dlsch_msg.unpack(dlsch_bref); /* Try to decode the SIB, we need a better way to provide the result */ - if(srsran_unlikely(asn1::rrc_nr::bcch_dl_sch_msg_type_c::c1_c_::types_opts::sib_type1 != dlsch_msg.msg.c1().type())){ + if(srsran_unlikely(asn1::rrc_nr::bcch_dl_sch_msg_type_c::c1_c_::types_opts:: + sib_type1 != dlsch_msg.msg.c1().type())){ // Try to decode other SIBs - if(!(state.sibs_vec_inited)){ - // Skip since the sib_vec is not intialized - ERROR("SIBs vec is not initialized"); - return SRSRAN_SUCCESS; - }else{ - // Get the sib_id, sib_id is uint8_t and is 2 for sib2, 3 for sib 3, etc... - auto sib_id = dlsch_msg.msg.c1().sys_info().crit_exts.sys_info().sib_type_and_info[0].type().to_number(); - auto decoded_sib = dlsch_msg.msg.c1().sys_info(); - // sibs[sib_id - 2] = dlsch_msg.msg.c1().sys_info(); - // found_sib[sib_id - 2] = 1; - - // // If we collect all the SIBs, we can skip the thread. - // long unsigned int found_result = 0; - // for(long unsigned int i=0; i= found_sib.size()){ - // *all_sibs_found = true; - // } - - std::cout << "SIB " << (int)sib_id << " Decoded." << std::endl; - /* Uncomment to print the decode SIBs. */ - asn1::json_writer js_sibs; - (decoded_sib).to_json(js_sibs); - printf("Decoded SIBs: %s\n", js_sibs.to_string().c_str()); - } - }else if(srsran_unlikely(asn1::rrc_nr::bcch_dl_sch_msg_type_c::c1_c_::types_opts::sys_info != dlsch_msg.msg.c1().type())){ - auto sib1 = dlsch_msg.msg.c1().sib_type1(); + // Get the sib_id, sib_id is uint8_t and is 2 for sib2, 3 for sib 3, etc... + auto sib_id = dlsch_msg.msg.c1().sys_info().crit_exts.sys_info(). + sib_type_and_info[0].type().to_number(); + auto decoded_sib = dlsch_msg.msg.c1().sys_info(); + result->sibs.emplace_back(decoded_sib); + result->found_sib.emplace_back(sib_id); + // sibs[sib_id - 2] = dlsch_msg.msg.c1().sys_info(); + // found_sib[sib_id - 2] = 1; + + // If we collect all the SIBs, we can skip the thread. + // long unsigned int found_result = 0; + // for(long unsigned int i=0; i= found_sib.size()){ + // *all_sibs_found = true; + // } + + std::cout << "SIB " << (int)sib_id << " Decoded." << std::endl; + /* Uncomment to print the decode SIBs. */ + asn1::json_writer js_sibs; + (decoded_sib).to_json(js_sibs); + printf("Decoded SIBs: %s\n", js_sibs.to_string().c_str()); + }else if(srsran_unlikely(asn1::rrc_nr::bcch_dl_sch_msg_type_c::c1_c_:: + types_opts::sys_info != dlsch_msg.msg.c1().type())){ + result->found_sib1 = true; + result->sib1 = dlsch_msg.msg.c1().sib_type1(); std::cout << "SIB 1 Decoded." << std::endl; // if(!(*sibs_vec_inited)){ diff --git a/nrscope/src/libs/task_scheduler.cc b/nrscope/src/libs/task_scheduler.cc index 0c247226..458482f5 100644 --- a/nrscope/src/libs/task_scheduler.cc +++ b/nrscope/src/libs/task_scheduler.cc @@ -165,98 +165,6 @@ int TaskSchedulerNRScope::DecodeMIB(cell_searcher_args_t* args_t_, return SRSRAN_SUCCESS; } -int TaskSchedulerNRScope::MergeResults(){ - - for (uint8_t b = 0; b < task_scheduler_state.nof_bwps; b++) { - DCIFeedback new_result; - results[b] = new_result; - results[b].dl_grants.resize(task_scheduler_state.nof_known_rntis); - results[b].ul_grants.resize(task_scheduler_state.nof_known_rntis); - results[b].spare_dl_prbs.resize(task_scheduler_state.nof_known_rntis); - results[b].spare_dl_tbs.resize(task_scheduler_state.nof_known_rntis); - results[b].spare_dl_bits.resize(task_scheduler_state.nof_known_rntis); - results[b].spare_ul_prbs.resize(task_scheduler_state.nof_known_rntis); - results[b].spare_ul_tbs.resize(task_scheduler_state.nof_known_rntis); - results[b].spare_ul_bits.resize(task_scheduler_state.nof_known_rntis); - results[b].dl_dcis.resize(task_scheduler_state.nof_known_rntis); - results[b].ul_dcis.resize(task_scheduler_state.nof_known_rntis); - - uint32_t rnti_s = 0; - uint32_t rnti_e = 0; - for(uint32_t i = 0; i < task_scheduler_state.nof_rnti_worker_groups; i++){ - if(rnti_s >= task_scheduler_state.nof_known_rntis){ - continue; - } - uint32_t n_rntis = task_scheduler_state.nof_sharded_rntis[i * - task_scheduler_state.nof_bwps]; - rnti_e = rnti_s + n_rntis; - if(rnti_e > task_scheduler_state.nof_known_rntis){ - rnti_e = task_scheduler_state.nof_known_rntis; - } - - uint32_t thread_id = i * task_scheduler_state.nof_bwps + b; - results[b].nof_dl_used_prbs += - task_scheduler_state.sharded_results[thread_id].nof_dl_used_prbs; - results[b].nof_ul_used_prbs += - task_scheduler_state.sharded_results[thread_id].nof_ul_used_prbs; - - for(uint32_t k = 0; k < n_rntis; k++) { - results[b].dl_dcis[k+rnti_s] = - task_scheduler_state.sharded_results[thread_id].dl_dcis[k]; - results[b].ul_dcis[k+rnti_s] = - task_scheduler_state.sharded_results[thread_id].ul_dcis[k]; - results[b].dl_grants[k+rnti_s] = - task_scheduler_state.sharded_results[thread_id].dl_grants[k]; - results[b].ul_grants[k+rnti_s] = - task_scheduler_state.sharded_results[thread_id].ul_grants[k]; - } - rnti_s = rnti_e; - } - - std::cout << "End of nof_threads..." << std::endl; - - /* TO-DISCUSS: to obtain even more precise result, - here maybe we should total user payload prb in that bwp - used prb */ - results[b].nof_dl_spare_prbs = - task_scheduler_state.args_t.base_carrier.nof_prb * - (14 - 2) - results[b].nof_dl_used_prbs; - for(uint32_t idx = 0; idx < task_scheduler_state.nof_known_rntis; idx ++){ - results[b].spare_dl_prbs[idx] = results[b].nof_dl_spare_prbs / - task_scheduler_state.nof_known_rntis; - if(abs(results[b].spare_dl_prbs[idx]) > - task_scheduler_state.args_t.base_carrier.nof_prb * (14 - 2)){ - results[b].spare_dl_prbs[idx] = 0; - } - results[b].spare_dl_tbs[idx] = - (int) ((float)results[b].spare_dl_prbs[idx] * - task_scheduler_state.dl_prb_rate[idx]); - results[b].spare_dl_bits[idx] = - (int) ((float)results[b].spare_dl_prbs[idx] * - task_scheduler_state.dl_prb_bits_rate[idx]); - } - - results[b].nof_ul_spare_prbs = - task_scheduler_state.args_t.base_carrier.nof_prb * (14 - 2) - - results[b].nof_ul_used_prbs; - for(uint32_t idx = 0; idx < task_scheduler_state.nof_known_rntis; idx ++){ - results[b].spare_ul_prbs[idx] = results[b].nof_ul_spare_prbs / - task_scheduler_state.nof_known_rntis; - if(abs(results[b].spare_ul_prbs[idx]) > - task_scheduler_state.args_t.base_carrier.nof_prb * (14 - 2)){ - results[b].spare_ul_prbs[idx] = 0; - } - results[b].spare_ul_tbs[idx] = - (int) ((float)results[b].spare_ul_prbs[idx] * - task_scheduler_state.ul_prb_rate[idx]); - results[b].spare_ul_bits[idx] = - (int) ((float)results[b].spare_ul_prbs[idx] * - task_scheduler_state.ul_prb_bits_rate[idx]); - } - } - - return SRSRAN_SUCCESS; -} - int TaskSchedulerNRScope::UpdateKnownRNTIs(){ if(task_scheduler_state.new_rnti_number <= 0){ return SRSRAN_SUCCESS; diff --git a/nrscope/src/libs/to_google.cc b/nrscope/src/libs/to_google.cc index 14de214e..b77caf94 100644 --- a/nrscope/src/libs/to_google.cc +++ b/nrscope/src/libs/to_google.cc @@ -16,7 +16,9 @@ namespace ToGoogle{ std::string google_dataset_id; - void init_to_google(std::string google_credential_input, std::string google_dataset_id_input, int nof_usrp_input){ + void init_to_google(std::string google_credential_input, + std::string google_dataset_id_input, + int nof_usrp_input){ run_google = true; nof_usrp = nof_usrp_input; google_credential = google_credential_input; @@ -44,7 +46,8 @@ namespace ToGoogle{ PyObject *pName, *pModule, *pCreate, *pPush, *pNofUSRP; PyObject *pClient, *pDict, *pRFID; - PyObject *pInt, *pDouble, *pStr, *pCredential, *pProjectID, *pDatasetID, *pInput; + PyObject *pInt, *pDouble, *pStr, *pCredential, *pProjectID, *pDatasetID; + PyObject *pInput; std::vector pList; setenv("PYTHONPATH", ".", 0); pList.resize(nof_usrp); @@ -56,8 +59,10 @@ namespace ToGoogle{ Py_DECREF(pName); if (pModule != NULL) { - pCreate = PyObject_GetAttrString(pModule, "create_table_with_position_and_time"); - pPush = PyObject_GetAttrString(pModule, "push_data_to_table"); + pCreate = PyObject_GetAttrString(pModule, + "create_table_with_position_and_time"); + pPush = PyObject_GetAttrString(pModule, + "push_data_to_table"); /* pFunc is a new reference */ if (pCreate && PyCallable_Check(pCreate)) { @@ -114,13 +119,15 @@ namespace ToGoogle{ PyDict_SetItemString(pDict, "slot_index", pInt); pInt = PyLong_FromLong(new_entry.grant.grant.rnti); PyDict_SetItemString(pDict, "rnti", pInt); - pStr = PyUnicode_FromString(srsran_rnti_type_str(new_entry.grant.grant.rnti_type)); + pStr = PyUnicode_FromString( + srsran_rnti_type_str(new_entry.grant.grant.rnti_type)); PyDict_SetItemString(pDict, "rnti_type", pStr); pStr = PyUnicode_FromString(new_entry.dci_format.c_str()); PyDict_SetItemString(pDict, "dci_format", pStr); pInt = PyLong_FromLong(new_entry.grant.grant.k); PyDict_SetItemString(pDict, "k", pInt); - pStr = PyUnicode_FromString(sch_mapping_to_str(new_entry.grant.grant.mapping)); + pStr = PyUnicode_FromString( + sch_mapping_to_str(new_entry.grant.grant.mapping)); PyDict_SetItemString(pDict, "mapping", pStr); pInt = PyLong_FromLong(new_entry.grant.grant.S); PyDict_SetItemString(pDict, "time_start", pInt); @@ -130,7 +137,8 @@ namespace ToGoogle{ PyDict_SetItemString(pDict, "frequency_start", pInt); pInt = PyLong_FromLong(new_entry.grant.grant.nof_prb); PyDict_SetItemString(pDict, "frequency_length", pInt); - pInt = PyLong_FromLong(new_entry.grant.grant.nof_dmrs_cdm_groups_without_data); + pInt = PyLong_FromLong( + new_entry.grant.grant.nof_dmrs_cdm_groups_without_data); PyDict_SetItemString(pDict, "nof_dmrs_cdm_groups", pInt); pDouble = PyFloat_FromDouble(new_entry.grant.grant.beta_dmrs); PyDict_SetItemString(pDict, "beta_dmrs", pDouble); @@ -140,7 +148,8 @@ namespace ToGoogle{ PyDict_SetItemString(pDict, "n_scid", pInt); pInt = PyLong_FromLong(new_entry.grant.grant.tb_scaling_field); PyDict_SetItemString(pDict, "tb_scaling_field", pInt); - pStr = PyUnicode_FromString(srsran_mod_string(new_entry.grant.grant.tb[0].mod)); + pStr = PyUnicode_FromString( + srsran_mod_string(new_entry.grant.grant.tb[0].mod)); PyDict_SetItemString(pDict, "modulation", pStr); pInt = PyLong_FromLong(new_entry.grant.grant.tb[0].mcs); PyDict_SetItemString(pDict, "mcs_index", pInt); @@ -156,24 +165,32 @@ namespace ToGoogle{ PyDict_SetItemString(pDict, "nof_re", pInt); pInt = PyLong_FromLong(new_entry.grant.grant.tb[0].nof_bits); PyDict_SetItemString(pDict, "nof_bits", pInt); - pStr = PyUnicode_FromString(srsran_mcs_table_to_str(new_entry.grant.sch_cfg.mcs_table)); + pStr = PyUnicode_FromString(srsran_mcs_table_to_str( + new_entry.grant.sch_cfg.mcs_table)); PyDict_SetItemString(pDict, "mcs_table", pStr); - pStr = PyUnicode_FromString(srsran_mcs_table_to_str(new_entry.grant.sch_cfg.mcs_table)); + pStr = PyUnicode_FromString(srsran_mcs_table_to_str( + new_entry.grant.sch_cfg.mcs_table)); PyDict_SetItemString(pDict, "xoverhead", pStr); - pInt = PyLong_FromLong(new_entry.dci_format == "1_1" ? new_entry.dl_dci.pid : new_entry.ul_dci.pid), + pInt = PyLong_FromLong(new_entry.dci_format == "1_1" ? + new_entry.dl_dci.pid : new_entry.ul_dci.pid), PyDict_SetItemString(pDict, "harq_id", pInt); - pInt = PyLong_FromLong(new_entry.dci_format == "1_1" ? new_entry.dl_dci.dai : new_entry.ul_dci.dai1), + pInt = PyLong_FromLong(new_entry.dci_format == "1_1" ? + new_entry.dl_dci.dai : new_entry.ul_dci.dai1), PyDict_SetItemString(pDict, "downlink_assignment_index", pInt); - pInt = PyLong_FromLong(new_entry.dci_format == "1_1" ? new_entry.dl_dci.tpc : new_entry.ul_dci.tpc), + pInt = PyLong_FromLong(new_entry.dci_format == "1_1" ? + new_entry.dl_dci.tpc : new_entry.ul_dci.tpc), PyDict_SetItemString(pDict, "tpc", pInt); - pInt = PyLong_FromLong(new_entry.dci_format == "1_1" ? new_entry.dl_dci.pucch_resource : 0), + pInt = PyLong_FromLong(new_entry.dci_format == "1_1" ? + new_entry.dl_dci.pucch_resource : 0), PyDict_SetItemString(pDict, "pucch_resource", pInt); - pInt = PyLong_FromLong(new_entry.dci_format == "1_1" ? new_entry.dl_dci.harq_feedback : 0), + pInt = PyLong_FromLong(new_entry.dci_format == "1_1" ? + new_entry.dl_dci.harq_feedback : 0), PyDict_SetItemString(pDict, "harq_feedback", pInt); PyList_SetItem(pList[rf_id], list_count[rf_id], pDict); list_count[rf_id] += 1; - std::cout << "Current list count of radio " << rf_id << ": " << list_count[rf_id] << std::endl; + std::cout << "Current list count of radio " << rf_id << ": " + << list_count[rf_id] << std::endl; if(list_count[rf_id] == list_length){ list_count[rf_id]= 0; diff --git a/nrscope/src/libs/to_google.py b/nrscope/src/libs/to_google.py index dc8ca0f1..d5cd2733 100644 --- a/nrscope/src/libs/to_google.py +++ b/nrscope/src/libs/to_google.py @@ -12,14 +12,18 @@ def create_table_with_position_and_time(credential, dataset_id_input, nof_usrp): print(geo_loc) geo_str = "" if(float(geo_loc[0]) >= 0): - geo_str += "P_" + str(int(geo_loc[0])) + "_" + "{:.4f}".format(geo_loc[0] - int(geo_loc[0]))[2:] + geo_str += "P_" + str(int(geo_loc[0])) + "_" + "{:.4f}".format( + geo_loc[0] - int(geo_loc[0]))[2:] else: - geo_str += "N_" + str(int(abs(geo_loc[0]))) + "_" + "{:.4f}".format(abs(geo_loc[0] - int(geo_loc[0])))[2:] + geo_str += "N_" + str(int(abs(geo_loc[0]))) + "_" + "{:.4f}".format( + abs(geo_loc[0] - int(geo_loc[0])))[2:] if(geo_loc[1] >= 0): - geo_str += "_P_" + str(int(geo_loc[1])) + "_" + "{:.4f}".format(geo_loc[1] - int(geo_loc[1]))[2:] + geo_str += "_P_" + str(int(geo_loc[1])) + "_" + "{:.4f}".format( + geo_loc[1] - int(geo_loc[1]))[2:] else: - geo_str += "_N_" + str(int(abs(geo_loc[1]))) + "_" + "{:.4f}".format(abs(geo_loc[1] - int(geo_loc[1])))[2:] + geo_str += "_N_" + str(int(abs(geo_loc[1]))) + "_" + "{:.4f}".format( + abs(geo_loc[1] - int(geo_loc[1])))[2:] print("Current location is: ", geo_str) # Get current datetime @@ -88,7 +92,8 @@ def create_table_with_position_and_time(credential, dataset_id_input, nof_usrp): clients.append(client) print( - "Create table {}.{}.{}".format(table.project, table.dataset_id, table.table_id) + "Create table {}.{}.{}".format(table.project, table.dataset_id, + table.table_id) ) rows = [] return clients, tables, schema, rows, nof_usrp @@ -104,7 +109,8 @@ def push_data_to_table(clients, tables, schema, rows_input, rf_index): clients[rf_index].insert_rows(tables[rf_index], rows_input, schema) toc = time.perf_counter() - print("Pushed {} entries to the google storage, taking {} s.".format(len(rows_input), toc-tic)) + print("Pushed {} entries to the google storage, taking {} s.".format( + len(rows_input), toc-tic)) except: print('Caught exceptions.') From 4c0e4aa9c8eea9ba7b8aa74dc73bd28b1f3f3130 Mon Sep 17 00:00:00 2001 From: Haoran Wan Date: Tue, 10 Sep 2024 22:19:45 -0400 Subject: [PATCH 04/15] task_scheduler's reorder and state update functions need implementing --- nrscope/hdr/nrscope_def.h | 28 +++++++++++ nrscope/hdr/nrscope_worker.h | 6 ++- nrscope/hdr/radio_nr.h | 8 +-- nrscope/hdr/task_scheduler.h | 59 ++-------------------- nrscope/src/libs/nrscope_worker.cc | 25 +++++++--- nrscope/src/libs/radio_nr.cc | 80 ++++++++++++++++-------------- nrscope/src/libs/task_scheduler.cc | 51 ++++++++++++------- nrscope/src/main.cc | 15 ------ 8 files changed, 133 insertions(+), 139 deletions(-) diff --git a/nrscope/hdr/nrscope_def.h b/nrscope/hdr/nrscope_def.h index e9b6f04d..a2fb3e91 100644 --- a/nrscope/hdr/nrscope_def.h +++ b/nrscope/hdr/nrscope_def.h @@ -208,6 +208,10 @@ typedef struct WorkState_ WorkState; typedef struct SlotResult_ SlotResult; struct SlotResult_{ + /* slot and frame information */ + srsran_slot_cfg_t slot; + srsran_ue_sync_nr_outcome_t outcome; + /* The worker works on SIBs decoding */ bool sib_result; bool found_sib1; @@ -226,8 +230,32 @@ typedef struct SlotResult_ SlotResult; /* The worker works on DCI decoding */ bool dci_result; std::vector dci_feedback_results; + + /* Define the compare operator between structure by sfn and slot idx */ + bool operator<(const SlotResult& other) const { + /* If the sfn is different*/ + if (outcome.sfn < other.outcome.sfn) return true; + if (outcome.sfn > other.outcome.sfn) return false; + + /* If the sfn is the same */ + return slot.idx < other.slot.idx; + } + + bool operator==(const SlotResult& other) const { + return outcome.sfn == other.outcome.sfn && slot.idx == other.slot.idx; + } }; +extern std::vector global_slot_results; +extern std::mutex task_lock; + +// namespace NRScopeTask{ +// /* Add some global variables for the task_scheduler and workers */ +// std::vector global_slot_results; + +// std::mutex task_lock; +// } + /** * @brief Function brought from phch_cfg_nr.c * diff --git a/nrscope/hdr/nrscope_worker.h b/nrscope/hdr/nrscope_worker.h index fa36cff4..eae7a442 100644 --- a/nrscope/hdr/nrscope_worker.h +++ b/nrscope/hdr/nrscope_worker.h @@ -21,7 +21,6 @@ class NRScopeWorker{ /* Job indicator */ sem_t smph_has_job; bool busy; - std::mutex lock; /* Worker thread */ std::thread worker_thread; @@ -37,6 +36,7 @@ class NRScopeWorker{ std::vector ul_prb_bits_rate; srsran_slot_cfg_t slot; /* Current slot. */ + srsran_ue_sync_nr_outcome_t outcome; /* Sync outcome, including the sfn */ NRScopeWorker(); ~NRScopeWorker(); @@ -56,7 +56,9 @@ class NRScopeWorker{ int SyncState(WorkState* task_scheduler_state); /* Copy the buffer and the slot structure from the task_scheduler */ - void CopySlotandBuffer(srsran_slot_cfg_t* slot_, cf_t* rx_buffer_); + void CopySlotandBuffer(srsran_slot_cfg_t* slot_, + srsran_ue_sync_nr_outcome_t* outcome_, + cf_t* rx_buffer_); int InitSIBDecoder(); int InitRACHDecoder(); diff --git a/nrscope/hdr/radio_nr.h b/nrscope/hdr/radio_nr.h index e52d6df6..8b2098e1 100644 --- a/nrscope/hdr/radio_nr.h +++ b/nrscope/hdr/radio_nr.h @@ -41,7 +41,8 @@ class Radio{ srsran::srsran_band_helper bands; srsran_ue_dl_nr_sratescs_info arg_scs; - srsue::nr::cell_search srsran_searcher; // from cell_search.cc + /* from cell_search.cc */ + srsue::nr::cell_search srsran_searcher; srsue::nr::cell_search::cfg_t srsran_searcher_cfg_t; srsue::nr::cell_search::args_t srsran_searcher_args_t; srsue::nr::cell_search::ret_t cs_ret; @@ -54,22 +55,17 @@ class Radio{ srsran_ue_sync_nr_args_t ue_sync_nr_args; srsran_ue_sync_nr_cfg_t sync_cfg; - srsue::nr::slot_sync slot_synchronizer; srsran_ue_sync_nr_t ue_sync_nr; srsran_ue_sync_nr_outcome_t outcome; srsran_ssb_cfg_t ssb_cfg; NRScopeTask::TaskSchedulerNRScope task_scheduler_nrscope; - RachDecoder rach_decoder; // processing for uplink in rach - SIBsDecoder sibs_decoder; - HarqTracker harq_tracker; uint32_t nof_threads; uint32_t nof_rnti_worker_groups; uint8_t nof_bwps; uint32_t nof_workers; - std::vector > dci_decoders; /* a better coordination between producer (fetch) and consumer (resample and decode) */ diff --git a/nrscope/hdr/task_scheduler.h b/nrscope/hdr/task_scheduler.h index ddc7a89f..e293ee46 100644 --- a/nrscope/hdr/task_scheduler.h +++ b/nrscope/hdr/task_scheduler.h @@ -11,54 +11,13 @@ class TaskSchedulerNRScope{ public: /* Task scheduler stores all the latest global params that each worker should sync with it each time the task is assigned. */ - // cell_searcher_args_t args_t; - // cell_search_result_t cell; - // srsue::nr::cell_search::ret_t cs_ret; - // srsue::nr::cell_search::cfg_t srsran_searcher_cfg_t; - // coreset0_args coreset0_args_t; - // srsran_coreset_t coreset0_t; - - // asn1::rrc_nr::sib1_s sib1; - // std::vector sibs; - // std::vector found_sib; - - // asn1::rrc_nr::rrc_setup_s rrc_setup; - // asn1::rrc_nr::cell_group_cfg_s master_cell_group; - // asn1::rrc_nr::rrc_recfg_s rrc_recfg; - - // bool sib1_found; // SIB 1 decoded, we can start the RACH thread - // bool rach_found; - - // bool sibs_vec_inited; // Is the vector for other SIBs set according to SIB? - // bool all_sibs_found; // All SIBs are decoded, we can stop the SIB thread from now. - - // bool sib1_inited; // SIBsDecoder is initialized. - // bool rach_inited; // RACHDecoder is initialized. - // bool dci_inited; // DCIDecoder is initialized. - - // uint32_t nof_known_rntis; - // std::vector known_rntis; - - // std::vector nof_sharded_rntis; - // std::vector > sharded_rntis; - // std::vector sharded_results; - // uint32_t nof_threads; - // uint32_t nof_rnti_worker_groups; - // uint8_t nof_bwps; - - // std::vector dl_prb_rate; - // std::vector ul_prb_rate; - // std::vector dl_prb_bits_rate; - // std::vector ul_prb_bits_rate; - - // uint32_t new_rnti_number; - // std::vector new_rntis_found; WorkState task_scheduler_state; uint32_t nof_workers; std::thread scheduler_thread; std::vector > workers; - std::mutex lock; + /* Slot results reorder buffer */ + std::vector slot_results; TaskSchedulerNRScope(); ~TaskSchedulerNRScope(); @@ -77,20 +36,12 @@ class TaskSchedulerNRScope{ float resample_ratio_, uint32_t raw_srate_); - int MergeResults(); int UpdateKnownRNTIs(); /* Assign the current slot to one worker*/ - int AssignTask(srsran_slot_cfg_t* slot, cf_t* rx_buffer_); - - // std::vector nof_sharded_rntis; - // std::vector > sharded_rntis; - // std::vector sharded_results; - - - // std::vector get_results(){ - // return results; - // } + int AssignTask(srsran_slot_cfg_t* slot, + srsran_ue_sync_nr_outcome_t* outcome, + cf_t* rx_buffer_); // resampler tools float resample_ratio; diff --git a/nrscope/src/libs/nrscope_worker.cc b/nrscope/src/libs/nrscope_worker.cc index c781a67d..17db496d 100644 --- a/nrscope/src/libs/nrscope_worker.cc +++ b/nrscope/src/libs/nrscope_worker.cc @@ -2,7 +2,11 @@ #include #include +std::vector global_slot_results; +std::mutex task_lock; + namespace NRScopeTask{ + NRScopeWorker::NRScopeWorker() : rf_buffer_t(1), rach_decoder(), @@ -53,8 +57,10 @@ void NRScopeWorker::StartWorker(){ } void NRScopeWorker::CopySlotandBuffer(srsran_slot_cfg_t* slot_, + srsran_ue_sync_nr_outcome_t* outcome_, cf_t* rx_buffer_) { slot = *slot_; + outcome = *outcome_; srsran_vec_cf_copy(rx_buffer, rx_buffer_, worker_state.slot_sz); } @@ -257,9 +263,9 @@ void NRScopeWorker::Run() { while (true) { /* When there is a job, the semaphore is set and buffer is copied */ sem_wait(&smph_has_job); - lock.lock(); + task_lock.lock(); busy = true; - lock.unlock(); + task_lock.unlock(); SlotResult slot_result = {}; /* Set the all the results to be false, will be set inside the decoder @@ -267,6 +273,8 @@ void NRScopeWorker::Run() { slot_result.sib_result = false; slot_result.rach_result = false; slot_result.dci_result = false; + slot_result.slot = slot; + slot_result.outcome = outcome; /* If we accidentally assign the job without initializing the SIB decoder */ if(!worker_state.sib1_inited){ @@ -297,9 +305,11 @@ void NRScopeWorker::Run() { for (uint32_t i = 0; i < worker_state.nof_threads; i++){ dci_threads.emplace_back(&DCIDecoder::DecodeandParseDCIfromSlot, - dci_decoders[i].get(), &slot, &worker_state, &sharded_results, - &sharded_rntis, &nof_sharded_rntis, &dl_prb_rate, &dl_prb_bits_rate, - &ul_prb_rate, &ul_prb_bits_rate); + dci_decoders[i].get(), &slot, &worker_state, + std::ref(sharded_results), std::ref(sharded_rntis), + std::ref(nof_sharded_rntis), std::ref(dl_prb_rate), + std::ref(dl_prb_bits_rate), std::ref(ul_prb_rate), + std::ref(ul_prb_bits_rate)); } } @@ -322,9 +332,10 @@ void NRScopeWorker::Run() { } /* Post the result into the result queue*/ - lock.lock(); + task_lock.lock(); + global_slot_results.emplace_back(slot_result); busy = false; - lock.unlock(); + task_lock.unlock(); } } } \ No newline at end of file diff --git a/nrscope/src/libs/radio_nr.cc b/nrscope/src/libs/radio_nr.cc index 6ffd3712..1b93d4be 100644 --- a/nrscope/src/libs/radio_nr.cc +++ b/nrscope/src/libs/radio_nr.cc @@ -6,23 +6,11 @@ #define RING_BUF_SIZE 10000 #define RING_BUF_MODULUS (RING_BUF_SIZE - 1) -std::mutex lock_radio_nr; - -namespace NRScopeTask{ - /* Add some global variables for the task_scheduler and workers */ - -} - Radio::Radio() : logger(srslog::fetch_basic_logger("PHY")), srsran_searcher(logger), rf_buffer_t(1), - slot_synchronizer(logger), - task_scheduler_nrscope(), - rach_decoder(), - sibs_decoder(), - // dci_decoder(100), - harq_tracker(100) + task_scheduler_nrscope() { raido_shared = std::make_shared(); radio = nullptr; @@ -489,7 +477,8 @@ int Radio::RadioInitandStart(){ } if (resample_needed) { - // srsran_vec_fprint2_c(fp_time_series_pre_resample, pre_resampling_rx_buffer, pre_resampling_slot_sz); + // srsran_vec_fprint2_c(fp_time_series_pre_resample, + // pre_resampling_rx_buffer, pre_resampling_slot_sz); copy_c_to_cpp_complex_arr_and_zero_padding(pre_resampling_rx_buffer, temp_x, pre_resampling_slot_sz, temp_x_sz); uint32_t splitted_nx = pre_resampling_slot_sz / RESAMPLE_WORKER_NUM; @@ -498,7 +487,8 @@ int Radio::RadioInitandStart(){ ssb_scan_resample_threads.emplace_back(&resample_partially, &q[k], temp_x, temp_y[k], k, splitted_nx, &actual_slot_szs[k]); } - // msresamp_crcf_execute(q, temp_x, pre_resampling_slot_sz, temp_y, &actual_slot_sz); + // msresamp_crcf_execute(q, temp_x, pre_resampling_slot_sz, + // temp_y, &actual_slot_sz); for (uint8_t k = 0; k < RESAMPLE_WORKER_NUM; k++){ if(ssb_scan_resample_threads[k].joinable()){ @@ -509,13 +499,16 @@ int Radio::RadioInitandStart(){ // sequentially merge back cf_t * buf_split_ptr = rx_buffer; for (uint8_t k = 0; k < RESAMPLE_WORKER_NUM; k++){ - copy_cpp_to_c_complex_arr(temp_y[k], buf_split_ptr, actual_slot_szs[k]); + copy_cpp_to_c_complex_arr(temp_y[k], buf_split_ptr, + actual_slot_szs[k]); buf_split_ptr += actual_slot_szs[k]; } - // srsran_vec_fprint2_c(fp_time_series_post_resample, rx_buffer, actual_slot_sz); + // srsran_vec_fprint2_c(fp_time_series_post_resample, + // rx_buffer, actual_slot_sz); } else { - // pre_resampling_slot_sz should be the same as slot_sz as resample ratio is 1 in this case + // pre_resampling_slot_sz should be the same as slot_sz as + // resample ratio is 1 in this case srsran_vec_cf_copy(rx_buffer, pre_resampling_rx_buffer, pre_resampling_slot_sz); } @@ -575,7 +568,8 @@ static int slot_sync_recv_callback(void* ptr, cf_t* buffer_ptr[SRSRAN_MAX_CHANNELS] = {}; buffer_ptr[0] = buffer[0]; - // std::cout << "[xuyang debug 3] find fetch nsamples: " << nsamples << std::endl; + // std::cout << "[xuyang debug 3] find fetch nsamples: " + // << nsamples << std::endl; srsran::rf_buffer_t rf_buffer(buffer_ptr, nsamples); srsran::rf_timestamp_t a; @@ -623,17 +617,20 @@ int Radio::SyncandDownlinkInit(){ return SRSRAN_ERROR; } // Be careful of all the frequency setting (SSB/center downlink and etc.)! - ssb_cfg.srate_hz = task_scheduler_nrscope.task_scheduler_state.args_t.srate_hz; + ssb_cfg.srate_hz = + task_scheduler_nrscope.task_scheduler_state.args_t.srate_hz; ssb_cfg.center_freq_hz = cs_args.ssb_freq_hz; - ssb_cfg.ssb_freq_hz = cs_args.ssb_freq_hz; - ssb_cfg.scs = cs_args.ssb_scs; - ssb_cfg.pattern = cs_args.ssb_pattern; - ssb_cfg.duplex_mode = cs_args.duplex_mode; + ssb_cfg.ssb_freq_hz = cs_args.ssb_freq_hz; + ssb_cfg.scs = cs_args.ssb_scs; + ssb_cfg.pattern = cs_args.ssb_pattern; + ssb_cfg.duplex_mode = cs_args.duplex_mode; ssb_cfg.periodicity_ms = 20; // for all in FR1 - sync_cfg.N_id = task_scheduler_nrscope.task_scheduler_state.cs_ret.ssb_res.N_id; + sync_cfg.N_id = + task_scheduler_nrscope.task_scheduler_state.cs_ret.ssb_res.N_id; sync_cfg.ssb = ssb_cfg; - sync_cfg.ssb.srate_hz = task_scheduler_nrscope.task_scheduler_state.args_t.srate_hz; + sync_cfg.ssb.srate_hz = + task_scheduler_nrscope.task_scheduler_state.args_t.srate_hz; if (srsran_ue_sync_nr_set_cfg(&ue_sync_nr, &sync_cfg) < SRSRAN_SUCCESS) { printf("SYNC: failed to set cell configuration for N_id %d", sync_cfg.N_id); logger.error("SYNC: failed to set cell configuration for N_id %d", @@ -674,9 +671,10 @@ int Radio::FetchAndResample(){ std::cout << "current_produce_ptr: " << (rf_buffer_t.to_cf_t())[0] << std::endl; - // note fetching the raw samples will temporarily touch area out of the target sf boundary - // yet after resampling, all meaningful data will reside the target sf arr area and the original raw extra part - // beyond the boundary doesn't matter + /* note fetching the raw samples will temporarily touch area out of the + target sf boundary yet after resampling, all meaningful data will reside + the target sf arr area and the original raw extra part + beyond the boundary doesn't matter */ if (srsran_ue_sync_nr_zerocopy_twinrx_nrscope( &ue_sync_nr, rf_buffer_t.to_cf_t(), &outcome, rk, resample_needed, RESAMPLE_WORKER_NUM) < SRSRAN_SUCCESS) { @@ -684,7 +682,8 @@ int Radio::FetchAndResample(){ logger.error("SYNC: error in zerocopy"); return false; } - // If in sync, update slot index. The synced data is stored in rf_buffer_t.to_cf_t()[0] + /* If in sync, update slot index. + The synced data is stored in rf_buffer_t.to_cf_t()[0] */ if (outcome.in_sync){ if (in_sync == false) { printf("in_sync change to true\n"); @@ -712,7 +711,8 @@ int Radio::DecodeAndProcess(){ // if(!task_scheduler_nrscope.task_scheduler_state.sib1_inited){ // /* Initialize all the worker's sib decoder */ // srsran::rf_buffer_t rf_buffer_wrapper(rx_buffer, pre_resampling_sf_sz); - // if(sibs_decoder.sib_decoder_and_reception_init(arg_scs, &task_scheduler_nrscope, rf_buffer_wrapper.to_cf_t()) < SRSASN_SUCCESS){ + // if(sibs_decoder.sib_decoder_and_reception_init(arg_scs, + // &task_scheduler_nrscope, rf_buffer_wrapper.to_cf_t()) < SRSASN_SUCCESS){ // ERROR("SIBsDecoder Init Error"); // return NR_FAILURE; // } @@ -731,7 +731,8 @@ int Radio::DecodeAndProcess(){ struct timeval t0, t1; gettimeofday(&t0, NULL); // consume a sf data - for(int slot_idx = 0; slot_idx < SRSRAN_NOF_SLOTS_PER_SF_NR(arg_scs.scs); slot_idx++){ + for(int slot_idx = 0; slot_idx < SRSRAN_NOF_SLOTS_PER_SF_NR(arg_scs.scs); + slot_idx++){ srsran_slot_cfg_t slot = {0}; slot.idx = (outcome.sf_idx) * SRSRAN_NSLOTS_PER_FRAME_NR(arg_scs.scs) / 10 + slot_idx; @@ -750,15 +751,19 @@ int Radio::DecodeAndProcess(){ ((next_consume_at % RING_BUF_MODULUS + 1) * pre_resampling_sf_sz)) + (slot_idx * slot_sz) << std::endl; - if (task_scheduler_nrscope.AssignTask(&slot, rx_buffer) < SRSRAN_SUCCESS) { + if (task_scheduler_nrscope.AssignTask(&slot, &outcome, rx_buffer) + < SRSRAN_SUCCESS) { ERROR("Assign task failed"); } - // if(!task_scheduler_nrscope.rach_inited and task_scheduler_nrscope.sib1_found){ - // // std::thread rach_init_thread {&RachDecoder::rach_decoder_init, &rach_decoder, task_scheduler_nrscope.sib1, args_t.base_carrier}; + // if(!task_scheduler_nrscope.rach_inited and task_scheduler_nrscope. + // sib1_found){ + // // std::thread rach_init_thread {&RachDecoder::rach_decoder_init, + // // &rach_decoder, task_scheduler_nrscope.sib1, args_t.base_carrier}; // rach_decoder.rach_decoder_init(&task_scheduler_nrscope); // srsran::rf_buffer_t rf_buffer_wrapper(rx_buffer, pre_resampling_sf_sz); - // if(rach_decoder.rach_reception_init(arg_scs, &task_scheduler_nrscope, rf_buffer_wrapper.to_cf_t()) < SRSASN_SUCCESS){ + // if(rach_decoder.rach_reception_init(arg_scs, &task_scheduler_nrscope, + // rf_buffer_wrapper.to_cf_t()) < SRSASN_SUCCESS){ // ERROR("RACHDecoder Init Error"); // return NR_FAILURE; // } @@ -766,7 +771,8 @@ int Radio::DecodeAndProcess(){ // task_scheduler_nrscope.rach_inited = true; // } - // if(!task_scheduler_nrscope.dci_inited and task_scheduler_nrscope.rach_found){ + // if(!task_scheduler_nrscope.dci_inited and task_scheduler_nrscope. + // rach_found){ // std::cout << "Initializing DCI decoder..." << std::endl; // task_scheduler_nrscope.sharded_results.resize(nof_threads); // task_scheduler_nrscope.nof_sharded_rntis.resize(nof_threads); diff --git a/nrscope/src/libs/task_scheduler.cc b/nrscope/src/libs/task_scheduler.cc index 458482f5..0c3accba 100644 --- a/nrscope/src/libs/task_scheduler.cc +++ b/nrscope/src/libs/task_scheduler.cc @@ -1,6 +1,7 @@ #include "nrscope/hdr/task_scheduler.h" namespace NRScopeTask{ + TaskSchedulerNRScope::TaskSchedulerNRScope(){ task_scheduler_state.sib1_inited = false; task_scheduler_state.rach_inited = false; @@ -165,42 +166,56 @@ int TaskSchedulerNRScope::DecodeMIB(cell_searcher_args_t* args_t_, return SRSRAN_SUCCESS; } -int TaskSchedulerNRScope::UpdateKnownRNTIs(){ - if(task_scheduler_state.new_rnti_number <= 0){ - return SRSRAN_SUCCESS; - } +// int TaskSchedulerNRScope::UpdateKnownRNTIs(){ +// if(task_scheduler_state.new_rnti_number <= 0){ +// return SRSRAN_SUCCESS; +// } - task_scheduler_state.nof_known_rntis += task_scheduler_state.new_rnti_number; - for(uint32_t i = 0; i < task_scheduler_state.new_rnti_number; i++){ - task_scheduler_state.known_rntis.emplace_back( - task_scheduler_state.new_rntis_found[i]); - } +// task_scheduler_state.nof_known_rntis += task_scheduler_state.new_rnti_number; +// for(uint32_t i = 0; i < task_scheduler_state.new_rnti_number; i++){ +// task_scheduler_state.known_rntis.emplace_back( +// task_scheduler_state.new_rntis_found[i]); +// } - task_scheduler_state.new_rntis_found.clear(); - task_scheduler_state.new_rnti_number = 0; - return SRSRAN_SUCCESS; -} +// task_scheduler_state.new_rntis_found.clear(); +// task_scheduler_state.new_rnti_number = 0; +// return SRSRAN_SUCCESS; +// } void TaskSchedulerNRScope::Run(){ while(true) { /* Try to extract results from the global result queue*/ + task_lock.lock(); + auto queue_len = global_slot_results.size(); + if (queue_len > 0) { + while (global_slot_results.size() > 0) { + /* dequeue from the head of the queue */ + slot_results.push_back(global_slot_results.front()); + global_slot_results.erase(global_slot_results.begin()); + } + } + task_lock.unlock(); + /* reorder the local slot_results and + wait for the correct data for output */ } } -int TaskSchedulerNRScope::AssignTask(srsran_slot_cfg_t* slot, cf_t* rx_buffer_){ +int TaskSchedulerNRScope::AssignTask(srsran_slot_cfg_t* slot, + srsran_ue_sync_nr_outcome_t* outcome, + cf_t* rx_buffer_){ /* Find the first idle worker */ bool found_worker = false; for (uint32_t i = 0; i < nof_workers; i ++) { - bool busy; - lock.lock(); + bool busy = true; + task_lock.lock(); busy = workers[i].get()->busy; - lock.unlock(); + task_lock.unlock(); if (!busy) { found_worker = true; /* Copy the rx_buffer_ to the worker's rx_buffer */ - workers[i].get()->CopySlotandBuffer(slot, rx_buffer_); + workers[i].get()->CopySlotandBuffer(slot, outcome, rx_buffer_); /* Update the worker's state */ workers[i].get()->SyncState(&task_scheduler_state); diff --git a/nrscope/src/main.cc b/nrscope/src/main.cc index 07ebdf29..6ca0e8a6 100644 --- a/nrscope/src/main.cc +++ b/nrscope/src/main.cc @@ -9,22 +9,7 @@ #include "srsran/common/band_helper.h" #include "srsran/phy/common/phy_common_nr.h" -// void my_handler(int s){ -// printf("Caught signal %d\n",s); -// exit(1); -// } - int main(int argc, char** argv){ - // srsran_debug_handle_crash(argc, argv); - - // struct sigaction sigIntHandler; - - // sigIntHandler.sa_handler = my_handler; - // sigemptyset(&sigIntHandler.sa_mask); - // sigIntHandler.sa_flags = 0; - - // sigaction(SIGINT, &sigIntHandler, NULL); - /* Initialize ASN decoder */ // init_asn_decoder("sample.sib"); From 073ae3b8e208d7eb24e429bc6524857980f79c3c Mon Sep 17 00:00:00 2001 From: Haoran Wan Date: Wed, 11 Sep 2024 15:13:53 -0400 Subject: [PATCH 05/15] worker and task_scheduler done, without reordering --- nrscope/hdr/nrscope_def.h | 7 +- nrscope/hdr/radio_nr.h | 2 - nrscope/hdr/task_scheduler.h | 18 ++- nrscope/src/libs/load_config.cc | 94 +++++++++------- nrscope/src/libs/nrscope_worker.cc | 8 +- nrscope/src/libs/radio_nr.cc | 4 +- nrscope/src/libs/sibs_decoder.cc | 8 -- nrscope/src/libs/task_scheduler.cc | 171 +++++++++++++++++++++++++---- 8 files changed, 226 insertions(+), 86 deletions(-) diff --git a/nrscope/hdr/nrscope_def.h b/nrscope/hdr/nrscope_def.h index a2fb3e91..cbff2b16 100644 --- a/nrscope/hdr/nrscope_def.h +++ b/nrscope/hdr/nrscope_def.h @@ -195,7 +195,6 @@ typedef struct WorkState_ WorkState; bool sib1_found; // SIB 1 decoded, we can start the RACH thread bool rach_found; - bool sibs_vec_inited; // Is the vector for other SIBs set according to SIB? bool all_sibs_found; // All SIBs are decoded, stop the SIB thread now. bool sib1_inited; // SIBsDecoder is initialized. @@ -246,8 +245,10 @@ typedef struct SlotResult_ SlotResult; } }; -extern std::vector global_slot_results; -extern std::mutex task_lock; +namespace NRScopeTask{ + extern std::vector global_slot_results; + extern std::mutex task_lock; +} // namespace NRScopeTask{ // /* Add some global variables for the task_scheduler and workers */ diff --git a/nrscope/hdr/radio_nr.h b/nrscope/hdr/radio_nr.h index 8b2098e1..4487993c 100644 --- a/nrscope/hdr/radio_nr.h +++ b/nrscope/hdr/radio_nr.h @@ -10,8 +10,6 @@ #include "nrscope/hdr/dci_decoder.h" #include "nrscope/hdr/harq_tracking.h" #include "nrscope/hdr/task_scheduler.h" -#include "nrscope/hdr/nrscope_logger.h" -#include "nrscope/hdr/to_google.h" #include #include diff --git a/nrscope/hdr/task_scheduler.h b/nrscope/hdr/task_scheduler.h index e293ee46..c8a609cf 100644 --- a/nrscope/hdr/task_scheduler.h +++ b/nrscope/hdr/task_scheduler.h @@ -5,6 +5,8 @@ #include "nrscope/hdr/nrscope_def.h" #include "nrscope/hdr/nrscope_worker.h" +#include "nrscope/hdr/nrscope_logger.h" +#include "nrscope/hdr/to_google.h" namespace NRScopeTask{ class TaskSchedulerNRScope{ @@ -19,12 +21,20 @@ class TaskSchedulerNRScope{ /* Slot results reorder buffer */ std::vector slot_results; + bool local_log; + bool to_google; + /* USRP's index */ + int rf_index; + TaskSchedulerNRScope(); ~TaskSchedulerNRScope(); /* Start the workers and the receiving result thread, called before the radio reception. */ - int InitandStart(int32_t nof_threads, + int InitandStart(bool local_log_, + bool to_google_, + int rf_index_, + int32_t nof_threads, uint32_t nof_rnti_worker_groups, uint8_t nof_bwps, cell_searcher_args_t args_t, @@ -36,14 +46,16 @@ class TaskSchedulerNRScope{ float resample_ratio_, uint32_t raw_srate_); - int UpdateKnownRNTIs(); + int UpdateStateandLog(); + + int UpdatewithResult(SlotResult now_result); /* Assign the current slot to one worker*/ int AssignTask(srsran_slot_cfg_t* slot, srsran_ue_sync_nr_outcome_t* outcome, cf_t* rx_buffer_); - // resampler tools + /* resampler tools */ float resample_ratio; msresamp_crcf resampler; float resampler_delay; diff --git a/nrscope/src/libs/load_config.cc b/nrscope/src/libs/load_config.cc index dfdca9a3..1106dae7 100644 --- a/nrscope/src/libs/load_config.cc +++ b/nrscope/src/libs/load_config.cc @@ -37,100 +37,107 @@ int load_config(std::vector& radios, std::string file_name){ int nof_usrp = config_yaml["nof_usrp_dev"].as(); - // if(config_yaml["dci_log_config"]){ - // dcilog->nof_cell = nof_usrp; - // dcilog->log_ul = config_yaml["dci_log_config"]["log_ul"].as(); - // dcilog->log_dl = config_yaml["dci_log_config"]["log_dl"].as(); - // }else{ - // std::cout << "Please set the dci_log_config in config.yaml properly." << std::endl; - // return NR_FAILURE; - // } - for(int i = 0; i < nof_usrp; i++){ radios[i].rf_index = i; std::string setting_name = "usrp_setting_"+to_string(i); std::cout << "USRP Device: " << i << std::endl; if(config_yaml[setting_name]){ - // radios[i].rf_args. = config_yaml[setting_name]["rf_freq"].as(); - // cout << " rf_freq: " << radios[i].rf_freq << endl; - - // radios[i].N_id_2 = config_yaml[setting_name]["N_id_2"].as(); - // cout << " N_id: " << radios[i].N_id_2 << endl; srsran::rf_args_t rf_args = {}; if(config_yaml[setting_name]["rf_args"]){ - std::string rf_args_config = config_yaml[setting_name]["rf_args"].as(); + std::string rf_args_config = + config_yaml[setting_name]["rf_args"].as(); radios[i].rf_args.device_args = rf_args_config; } std::cout << " rf_args: " << radios[i].rf_args.device_args << std::endl; if(config_yaml[setting_name]["device_name"]){ - std::string rf_args_devicename = config_yaml[setting_name]["device_name"].as(); + std::string rf_args_devicename = + config_yaml[setting_name]["device_name"].as(); radios[i].rf_args.device_name = rf_args_devicename; } std::cout << " device_name: " << radios[i].rf_args.device_name << endl; if(config_yaml[setting_name]["log_level"]){ - std::string rf_args_loglevel = config_yaml[setting_name]["log_level"].as(); + std::string rf_args_loglevel = + config_yaml[setting_name]["log_level"].as(); radios[i].rf_args.log_level = rf_args_loglevel; } if(config_yaml[setting_name]["srsran_srate_hz"]){ - radios[i].rf_args.srsran_srate_hz = config_yaml[setting_name]["srsran_srate_hz"].as(); + radios[i].rf_args.srsran_srate_hz = + config_yaml[setting_name]["srsran_srate_hz"].as(); } - std::cout << " srsran_srate_hz: " << radios[i].rf_args.srsran_srate_hz / 1e6 << " MHz" << std::endl; + std::cout << " srsran_srate_hz: " << + radios[i].rf_args.srsran_srate_hz / 1e6 << " MHz" << std::endl; if(config_yaml[setting_name]["srate_hz"]){ - radios[i].rf_args.srate_hz = config_yaml[setting_name]["srate_hz"].as(); + radios[i].rf_args.srate_hz = + config_yaml[setting_name]["srate_hz"].as(); } - std::cout << " srate_hz: " << radios[i].rf_args.srate_hz / 1e6 << " MHz" << std::endl; + std::cout << " srate_hz: " << + radios[i].rf_args.srate_hz / 1e6 << " MHz" << std::endl; if(config_yaml[setting_name]["rx_gain"]){ - radios[i].rf_args.rx_gain = config_yaml[setting_name]["rx_gain"].as(); + radios[i].rf_args.rx_gain = + config_yaml[setting_name]["rx_gain"].as(); } std::cout << " rx_gain: " << radios[i].rf_args.rx_gain << std::endl; if(config_yaml[setting_name]["nof_carriers"]){ - radios[i].rf_args.nof_carriers = config_yaml[setting_name]["nof_carriers"].as(); + radios[i].rf_args.nof_carriers = + config_yaml[setting_name]["nof_carriers"].as(); } - std::cout << " nof_carriers: " << radios[i].rf_args.nof_carriers << std::endl; + std::cout << " nof_carriers: " << + radios[i].rf_args.nof_carriers << std::endl; if(config_yaml[setting_name]["nof_antennas"]){ - radios[i].rf_args.nof_antennas = config_yaml[setting_name]["nof_antennas"].as(); + radios[i].rf_args.nof_antennas = + config_yaml[setting_name]["nof_antennas"].as(); } - std::cout << " nof_antennas: " << radios[i].rf_args.nof_antennas << std::endl; + std::cout << " nof_antennas: " << + radios[i].rf_args.nof_antennas << std::endl; if(config_yaml[setting_name]["freq_offset"]){ - radios[i].rf_args.freq_offset = config_yaml[setting_name]["freq_offset"].as(); + radios[i].rf_args.freq_offset = + config_yaml[setting_name]["freq_offset"].as(); } - std::cout << " freq_offset: " << radios[i].rf_args.freq_offset << std::endl; + std::cout << " freq_offset: " << + radios[i].rf_args.freq_offset << std::endl; if(config_yaml[setting_name]["scs_index"]){ - radios[i].ssb_scs = (srsran_subcarrier_spacing_t)config_yaml[setting_name]["scs_index"].as(); + radios[i].ssb_scs = + (srsran_subcarrier_spacing_t)config_yaml[setting_name]["scs_index"]. + as(); } std::cout << " scs: " << radios[i].ssb_scs << std::endl; if(config_yaml[setting_name]["ssb_freq"]){ - radios[i].args_t.base_carrier.dl_center_frequency_hz = config_yaml[setting_name]["ssb_freq"].as(); + radios[i].args_t.base_carrier.dl_center_frequency_hz = + config_yaml[setting_name]["ssb_freq"].as(); } if(config_yaml[setting_name]["rf_log_level"]){ - radios[i].rf_args.log_level = config_yaml[setting_name]["rf_log_level"].as(); + radios[i].rf_args.log_level = + config_yaml[setting_name]["rf_log_level"].as(); }else{ radios[i].rf_args.log_level = "info"; } if(config_yaml[setting_name]["log_name"]){ - radios[i].log_name = config_yaml[setting_name]["log_name"].as(); + radios[i].log_name = + config_yaml[setting_name]["log_name"].as(); } if(config_yaml[setting_name]["google_dataset_id"]){ - radios[i].google_dataset_id = config_yaml[setting_name]["google_dataset_id"].as(); + radios[i].google_dataset_id = + config_yaml[setting_name]["google_dataset_id"].as(); } if(config_yaml[setting_name]["nof_rnti_worker_groups"]){ - radios[i].nof_rnti_worker_groups = config_yaml[setting_name]["nof_rnti_worker_groups"].as(); + radios[i].nof_rnti_worker_groups = + config_yaml[setting_name]["nof_rnti_worker_groups"].as(); }else{ radios[i].nof_rnti_worker_groups = 1; } @@ -144,7 +151,8 @@ int load_config(std::vector& radios, std::string file_name){ } if(config_yaml[setting_name]["nof_workers"]){ - radios[i].nof_workers = config_yaml[setting_name]["nof_workers"].as(); + radios[i].nof_workers = + config_yaml[setting_name]["nof_workers"].as(); }else{ radios[i].nof_workers = 1; } @@ -153,7 +161,8 @@ int load_config(std::vector& radios, std::string file_name){ // std::cout << " nof_thread: " << radios[i].nof_thread << std::endl; }else{ - std::cout << "Please set the usrp_setting_" << i << " in config.yaml properly." << std::endl; + std::cout << "Please set the usrp_setting_" << i + << " in config.yaml properly." << std::endl; return NR_FAILURE; } } @@ -161,7 +170,8 @@ int load_config(std::vector& radios, std::string file_name){ std::string setting_name = "log_config"; if(config_yaml[setting_name]["local_log"]){ for (int i = 0; i < nof_usrp; i++){ - radios[i].local_log = config_yaml[setting_name]["local_log"].as(); + radios[i].local_log = + config_yaml[setting_name]["local_log"].as(); } }else{ for (int i = 0; i < nof_usrp; i++){ @@ -171,13 +181,17 @@ int load_config(std::vector& radios, std::string file_name){ if(config_yaml[setting_name]["push_to_google"]){ for (int i = 0; i < nof_usrp; i++){ - radios[i].to_google = config_yaml[setting_name]["push_to_google"].as(); + radios[i].to_google = + config_yaml[setting_name]["push_to_google"].as(); if(config_yaml[setting_name]["google_service_account_credential"]){ - radios[i].google_credential = config_yaml[setting_name]["google_service_account_credential"].as(); + radios[i].google_credential = + config_yaml[setting_name]["google_service_account_credential"]. + as(); } } // if(config_yaml[setting_name]["google_project_id"]){ - // radios[i].google_project_id = config_yaml[setting_name]["google_project_id"].as(); + // radios[i].google_project_id = + // config_yaml[setting_name]["google_project_id"].as(); // } } diff --git a/nrscope/src/libs/nrscope_worker.cc b/nrscope/src/libs/nrscope_worker.cc index 17db496d..f7cfc3f1 100644 --- a/nrscope/src/libs/nrscope_worker.cc +++ b/nrscope/src/libs/nrscope_worker.cc @@ -2,11 +2,11 @@ #include #include +namespace NRScopeTask{ + std::vector global_slot_results; std::mutex task_lock; -namespace NRScopeTask{ - NRScopeWorker::NRScopeWorker() : rf_buffer_t(1), rach_decoder(), @@ -18,7 +18,6 @@ NRScopeWorker::NRScopeWorker() : worker_state.sib1_found = false; worker_state.rach_found = false; - worker_state.sibs_vec_inited = false; worker_state.nof_known_rntis = 0; worker_state.known_rntis.resize(worker_state.nof_known_rntis); @@ -148,7 +147,6 @@ int NRScopeWorker::SyncState(WorkState* task_scheduler_state) { worker_state.sib1_found = task_scheduler_state->sib1_found; worker_state.rach_found = task_scheduler_state->rach_found; - worker_state.sibs_vec_inited = task_scheduler_state->sibs_vec_inited; worker_state.all_sibs_found = task_scheduler_state->all_sibs_found; if (!worker_state.sib1_inited && task_scheduler_state->sib1_inited) { @@ -219,8 +217,6 @@ int NRScopeWorker::MergeResults(){ rnti_s = rnti_e; } - std::cout << "End of nof_threads..." << std::endl; - /* TO-DISCUSS: to obtain even more precise result, here maybe we should total user payload prb in that bwp - used prb */ results[b].nof_dl_spare_prbs = diff --git a/nrscope/src/libs/radio_nr.cc b/nrscope/src/libs/radio_nr.cc index 1b93d4be..d6936ade 100644 --- a/nrscope/src/libs/radio_nr.cc +++ b/nrscope/src/libs/radio_nr.cc @@ -409,8 +409,8 @@ int Radio::RadioInitandStart(){ /* Initialize the task_scheduler and the workers in it. They will all remain inactive until the MIB is found. */ - task_scheduler_nrscope.InitandStart(nof_threads, nof_rnti_worker_groups, - nof_bwps, args_t, nof_workers); + task_scheduler_nrscope.InitandStart(local_log, to_google, rf_index, + nof_threads, nof_rnti_worker_groups, nof_bwps, args_t, nof_workers); std::cout << "Task scheduler started..." << std::endl; while (not ss.end()) { diff --git a/nrscope/src/libs/sibs_decoder.cc b/nrscope/src/libs/sibs_decoder.cc index d13594d6..b0847f27 100644 --- a/nrscope/src/libs/sibs_decoder.cc +++ b/nrscope/src/libs/sibs_decoder.cc @@ -228,14 +228,6 @@ int SIBsDecoder::DecodeandParseSIB1fromSlot(srsran_slot_cfg_t* slot, result->sib1 = dlsch_msg.msg.c1().sib_type1(); std::cout << "SIB 1 Decoded." << std::endl; - // if(!(*sibs_vec_inited)){ - // // Setting the size of the vector for other SIBs decoding. - // int nof_sibs = (*sib1_).si_sched_info_present ? (*sib1_).si_sched_info.sched_info_list.size() : 0; - // sibs.resize(nof_sibs); - // found_sib.resize(nof_sibs); - // (*sibs_vec_inited) = true; - // } - /* Uncomment to print the decode SIB1. */ asn1::json_writer js_sib1; (sib1).to_json(js_sib1); diff --git a/nrscope/src/libs/task_scheduler.cc b/nrscope/src/libs/task_scheduler.cc index 0c3accba..d9f23251 100644 --- a/nrscope/src/libs/task_scheduler.cc +++ b/nrscope/src/libs/task_scheduler.cc @@ -9,7 +9,6 @@ TaskSchedulerNRScope::TaskSchedulerNRScope(){ task_scheduler_state.sib1_found = false; task_scheduler_state.rach_found = false; - task_scheduler_state.sibs_vec_inited = false; task_scheduler_state.nof_known_rntis = 0; task_scheduler_state.known_rntis.resize(task_scheduler_state.nof_known_rntis); @@ -18,11 +17,17 @@ TaskSchedulerNRScope::TaskSchedulerNRScope(){ TaskSchedulerNRScope::~TaskSchedulerNRScope(){ } -int TaskSchedulerNRScope::InitandStart(int32_t nof_threads, +int TaskSchedulerNRScope::InitandStart(bool local_log_, + bool to_google_, + int rf_index_, + int32_t nof_threads, uint32_t nof_rnti_worker_groups, uint8_t nof_bwps, cell_searcher_args_t args_t, uint32_t nof_workers_){ + local_log = local_log_; + to_google = to_google_; + rf_index = rf_index_; task_scheduler_state.nof_threads = nof_threads; task_scheduler_state.nof_rnti_worker_groups = nof_rnti_worker_groups; task_scheduler_state.nof_bwps = nof_bwps; @@ -99,8 +104,9 @@ int TaskSchedulerNRScope::DecodeMIB(cell_searcher_args_t* args_t_, /* To find the position of coreset0, we need to use the offset between SSB and CORESET0, because we don't know the ssb_pointA_freq_offset_Hz yet required by the srsran_coreset_zero function. - coreset0_t low bound freq = ssb center freq - 120 * scs (half of sc in ssb) - - ssb_subcarrierOffset(from MIB) * scs - entry->offset_rb * 12(sc in one rb) * scs */ + coreset0_t low bound freq = ssb center freq - 120 * scs (half of sc in ssb) + - ssb_subcarrierOffset(from MIB) * scs - entry->offset_rb * + 12(sc in one rb) * scs */ task_scheduler_state.cell.abs_ssb_scs = SRSRAN_SUBC_SPACING_NR(args_t_->ssb_scs); task_scheduler_state.cell.abs_pdcch_scs = @@ -166,23 +172,143 @@ int TaskSchedulerNRScope::DecodeMIB(cell_searcher_args_t* args_t_, return SRSRAN_SUCCESS; } -// int TaskSchedulerNRScope::UpdateKnownRNTIs(){ -// if(task_scheduler_state.new_rnti_number <= 0){ -// return SRSRAN_SUCCESS; -// } +int TaskSchedulerNRScope::UpdatewithResult(SlotResult now_result) { + task_lock.lock(); + /* This slot contains SIBs decoder's result */ + if (now_result.sib_result) { + if (now_result.found_sib1 && !task_scheduler_state.sib1_found) { + /* The sib1 is not found in the task_scheduler's state */ + /* We only process the SIB 1 once */ + task_scheduler_state.sib1 = now_result.sib1; + task_scheduler_state.sib1_found = true; + /* Setting the size of the vector for other SIBs decoding. */ + int nof_sibs = (task_scheduler_state.sib1).si_sched_info_present ? + (task_scheduler_state.sib1).si_sched_info.sched_info_list[0]. + sib_map_info.size() : 0; + for (int i = 0; i < nof_sibs; i++) { + task_scheduler_state.sibs_to_be_found.push_back( + task_scheduler_state.sib1.si_sched_info.sched_info_list[0]. + sib_map_info[i].type.to_number()); + } + /* Since we got the SIB1, we can now init the RACH decoder*/ + task_scheduler_state.rach_inited = true; + } + + if (now_result.found_sib.size() > 0) { + /* Found sibs other than SIB 1 */ + unsigned long int task_sibs_len = + task_scheduler_state.sibs_to_be_found.size(); + if (task_sibs_len > 0) { + /* There are still some sibs to be found */ + for (unsigned long int i = 0; i < now_result.found_sib.size(); i ++) { + int sib_id = now_result.found_sib[i]; + for (unsigned long int j = 0; j < task_sibs_len; j ++) { + if (sib_id == task_scheduler_state.sibs_to_be_found[j]) { + /* If the sib_id is in the to_be_found list */ + task_scheduler_state.found_sib.push_back(sib_id); + task_scheduler_state.sibs.push_back(now_result.sibs[i]); + task_scheduler_state.sibs_to_be_found.erase( + task_scheduler_state.sibs_to_be_found.begin() + j); + break; + } + /* Else skip the data */ + } + } + } + /* Or else, skip the sibs */ + if (task_scheduler_state.sibs_to_be_found.size() == 0) { + task_scheduler_state.all_sibs_found = true; + } + } + } -// task_scheduler_state.nof_known_rntis += task_scheduler_state.new_rnti_number; -// for(uint32_t i = 0; i < task_scheduler_state.new_rnti_number; i++){ -// task_scheduler_state.known_rntis.emplace_back( -// task_scheduler_state.new_rntis_found[i]); -// } + /* This slot contains the RACH decoder's result */ + if (now_result.rach_result) { + if (now_result.found_rach) { + if (!task_scheduler_state.rach_found) { + /* The first time that we found the RACH */ + task_scheduler_state.rrc_setup = now_result.rrc_setup; + task_scheduler_state.master_cell_group = now_result.master_cell_group; + task_scheduler_state.nof_known_rntis += now_result.new_rnti_number; + for (uint32_t i = 0; i < now_result.new_rnti_number; i++) { + task_scheduler_state.known_rntis.push_back( + now_result.new_rntis_found[i]); + } + } else { + /* We already found the RACH, we just append the new RNTIs */ + task_scheduler_state.nof_known_rntis += now_result.new_rnti_number; + for (uint32_t i = 0; i < now_result.new_rnti_number; i++) { + task_scheduler_state.known_rntis.push_back( + now_result.new_rntis_found[i]); + } + } + } + } + task_lock.unlock(); + + /* This slot contains the DCI decoder's result, put all the results to log */ + if (now_result.dci_result) { + std::vector results = now_result.dci_feedback_results; + for (uint8_t b = 0; b < task_scheduler_state.nof_bwps; b++) { + DCIFeedback result = results[b]; + if((result.dl_grants.size()>0 or result.ul_grants.size()>0)){ + for (uint32_t i = 0; i < task_scheduler_state.nof_known_rntis; i++){ + if(result.dl_grants[i].grant.rnti == + task_scheduler_state.known_rntis[i]){ + LogNode log_node; + log_node.slot_idx = now_result.slot.idx; + log_node.system_frame_idx = now_result.outcome.sfn; + log_node.timestamp = get_now_timestamp_in_double(); + log_node.grant = result.dl_grants[i]; + log_node.dci_format = + srsran_dci_format_nr_string(result.dl_dcis[i].ctx.format); + log_node.dl_dci = result.dl_dcis[i]; + log_node.bwp_id = result.dl_dcis[i].bwp_id; + if(local_log){ + NRScopeLog::push_node(log_node, rf_index); + } + if(to_google){ + ToGoogle::push_google_node(log_node, rf_index); + } + } + + if(result.ul_grants[i].grant.rnti == + task_scheduler_state.known_rntis[i]){ + LogNode log_node; + log_node.slot_idx = now_result.slot.idx; + log_node.system_frame_idx = now_result.outcome.sfn; + log_node.timestamp = get_now_timestamp_in_double(); + log_node.grant = result.ul_grants[i]; + log_node.dci_format = + srsran_dci_format_nr_string(result.ul_dcis[i].ctx.format); + log_node.ul_dci = result.ul_dcis[i]; + log_node.bwp_id = result.ul_dcis[i].bwp_id; + if(local_log){ + NRScopeLog::push_node(log_node, rf_index); + } + if(to_google){ + ToGoogle::push_google_node(log_node, rf_index); + } + } + } + } + } + } + return SRSRAN_SUCCESS; +} -// task_scheduler_state.new_rntis_found.clear(); -// task_scheduler_state.new_rnti_number = 0; -// return SRSRAN_SUCCESS; -// } +int TaskSchedulerNRScope::UpdateStateandLog() { + /* Right now there is no re-order function, + just update the state and log*/ + while(slot_results.size() > 0) { + SlotResult now_result = slot_results[0]; + UpdatewithResult(now_result); + slot_results.erase(slot_results.begin()); + } + return SRSRAN_SUCCESS; +} -void TaskSchedulerNRScope::Run(){ +void TaskSchedulerNRScope::Run() { while(true) { /* Try to extract results from the global result queue*/ task_lock.lock(); @@ -198,6 +324,7 @@ void TaskSchedulerNRScope::Run(){ /* reorder the local slot_results and wait for the correct data for output */ + UpdateStateandLog(); } } @@ -213,13 +340,13 @@ int TaskSchedulerNRScope::AssignTask(srsran_slot_cfg_t* slot, task_lock.unlock(); if (!busy) { found_worker = true; - - /* Copy the rx_buffer_ to the worker's rx_buffer */ + /* Copy the rx_buffer_ to the worker's rx_buffer. This won't be + interfering with other threads? */ workers[i].get()->CopySlotandBuffer(slot, outcome, rx_buffer_); - + task_lock.lock(); /* Update the worker's state */ workers[i].get()->SyncState(&task_scheduler_state); - + task_lock.unlock(); /* Set the worker's sem to let the task run */ sem_post(&workers[i].get()->smph_has_job); From 928607066df2ec183a8934dd1930970fec6fe39e Mon Sep 17 00:00:00 2001 From: Haoran Wan Date: Wed, 11 Sep 2024 15:53:47 -0400 Subject: [PATCH 06/15] code tested, now implementing reordering function in task_scheduler --- nrscope/src/libs/sibs_decoder.cc | 2 +- nrscope/src/libs/task_scheduler.cc | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/nrscope/src/libs/sibs_decoder.cc b/nrscope/src/libs/sibs_decoder.cc index b0847f27..4c0a48f2 100644 --- a/nrscope/src/libs/sibs_decoder.cc +++ b/nrscope/src/libs/sibs_decoder.cc @@ -230,7 +230,7 @@ int SIBsDecoder::DecodeandParseSIB1fromSlot(srsran_slot_cfg_t* slot, /* Uncomment to print the decode SIB1. */ asn1::json_writer js_sib1; - (sib1).to_json(js_sib1); + (result->sib1).to_json(js_sib1); printf("Decoded SIB1: %s\n", js_sib1.to_string().c_str()); } diff --git a/nrscope/src/libs/task_scheduler.cc b/nrscope/src/libs/task_scheduler.cc index d9f23251..9ca7a253 100644 --- a/nrscope/src/libs/task_scheduler.cc +++ b/nrscope/src/libs/task_scheduler.cc @@ -234,6 +234,7 @@ int TaskSchedulerNRScope::UpdatewithResult(SlotResult now_result) { task_scheduler_state.known_rntis.push_back( now_result.new_rntis_found[i]); } + task_scheduler_state.rach_found = true; } else { /* We already found the RACH, we just append the new RNTIs */ task_scheduler_state.nof_known_rntis += now_result.new_rnti_number; @@ -242,6 +243,9 @@ int TaskSchedulerNRScope::UpdatewithResult(SlotResult now_result) { now_result.new_rntis_found[i]); } } + + /* Since we got the RACH, we can now init the RACH decoder*/ + task_scheduler_state.dci_inited = true; } } task_lock.unlock(); From ae5d8975f5149e5623606baaf14c1501084e8b51 Mon Sep 17 00:00:00 2001 From: Haoran Wan Date: Wed, 11 Sep 2024 20:39:34 -0400 Subject: [PATCH 07/15] done, testing 40MHz cell --- nrscope/config/config.yaml | 2 +- nrscope/hdr/nrscope_def.h | 21 +++- nrscope/hdr/nrscope_worker.h | 6 +- nrscope/hdr/radio_nr.h | 6 +- nrscope/hdr/sibs_decoder.h | 10 -- nrscope/hdr/task_scheduler.h | 9 +- nrscope/src/libs/asn_decoder.c | 18 ++- nrscope/src/libs/nrscope_def.cc | 31 ++++-- nrscope/src/libs/nrscope_logger.cc | 29 +++-- nrscope/src/libs/nrscope_worker.cc | 54 +++++---- nrscope/src/libs/radio_nr.cc | 172 ++++++----------------------- nrscope/src/libs/task_scheduler.cc | 68 +++++++++--- 12 files changed, 207 insertions(+), 219 deletions(-) diff --git a/nrscope/config/config.yaml b/nrscope/config/config.yaml index 075d9885..ec464e05 100644 --- a/nrscope/config/config.yaml +++ b/nrscope/config/config.yaml @@ -12,7 +12,7 @@ usrp_setting_0: rf_log_level: "debug" nof_rnti_worker_groups: 1 nof_bwps: 1 - nof_workers: 4 + nof_workers: 16 log_name: "a.csv" #"/home/wanhr/Documents/data/nrscope/evaluation/coverage_amarisoft/dci_tx_50.csv" # x (0-10), y(0-8) coordinates google_dataset_id: "ngscope5g_dci_log_wanhr" diff --git a/nrscope/hdr/nrscope_def.h b/nrscope/hdr/nrscope_def.h index cbff2b16..25adad86 100644 --- a/nrscope/hdr/nrscope_def.h +++ b/nrscope/hdr/nrscope_def.h @@ -207,7 +207,10 @@ typedef struct WorkState_ WorkState; typedef struct SlotResult_ SlotResult; struct SlotResult_{ - /* slot and frame information */ + /* 3GPP only marks system frame up to 10.24 seconds, 0-1023. + We want to also capture the level above that. */ + uint64_t sf_round; + /* slot and system frame information */ srsran_slot_cfg_t slot; srsran_ue_sync_nr_outcome_t outcome; @@ -230,9 +233,14 @@ typedef struct SlotResult_ SlotResult; bool dci_result; std::vector dci_feedback_results; - /* Define the compare operator between structure by sfn and slot idx */ + /* Define the compare operator between structure by sf_round, + sfn and slot idx */ bool operator<(const SlotResult& other) const { - /* If the sfn is different*/ + /* If the sf_round is different */ + if (sf_round < other.sf_round) return true; + if (sf_round > other.sf_round) return false; + + /* If the sfn is different */ if (outcome.sfn < other.outcome.sfn) return true; if (outcome.sfn > other.outcome.sfn) return false; @@ -241,10 +249,15 @@ typedef struct SlotResult_ SlotResult; } bool operator==(const SlotResult& other) const { - return outcome.sfn == other.outcome.sfn && slot.idx == other.slot.idx; + return sf_round == other.sf_round && outcome.sfn == other.outcome.sfn && + slot.idx == other.slot.idx; } + + /* The + operator depends on the SCS, so it's not defined here. */ }; +bool CompareSlotResult (SlotResult a, SlotResult b); + namespace NRScopeTask{ extern std::vector global_slot_results; extern std::mutex task_lock; diff --git a/nrscope/hdr/nrscope_worker.h b/nrscope/hdr/nrscope_worker.h index eae7a442..e5b2499c 100644 --- a/nrscope/hdr/nrscope_worker.h +++ b/nrscope/hdr/nrscope_worker.h @@ -35,6 +35,7 @@ class NRScopeWorker{ std::vector ul_prb_rate; std::vector ul_prb_bits_rate; + uint64_t sf_round; srsran_slot_cfg_t slot; /* Current slot. */ srsran_ue_sync_nr_outcome_t outcome; /* Sync outcome, including the sfn */ @@ -56,8 +57,9 @@ class NRScopeWorker{ int SyncState(WorkState* task_scheduler_state); /* Copy the buffer and the slot structure from the task_scheduler */ - void CopySlotandBuffer(srsran_slot_cfg_t* slot_, - srsran_ue_sync_nr_outcome_t* outcome_, + void CopySlotandBuffer(uint64_t sf_round_, + srsran_slot_cfg_t slot_, + srsran_ue_sync_nr_outcome_t outcome_, cf_t* rx_buffer_); int InitSIBDecoder(); diff --git a/nrscope/hdr/radio_nr.h b/nrscope/hdr/radio_nr.h index 4487993c..1957e19f 100644 --- a/nrscope/hdr/radio_nr.h +++ b/nrscope/hdr/radio_nr.h @@ -55,16 +55,17 @@ class Radio{ srsran_ue_sync_nr_t ue_sync_nr; srsran_ue_sync_nr_outcome_t outcome; + uint64_t sf_round; srsran_ssb_cfg_t ssb_cfg; - NRScopeTask::TaskSchedulerNRScope task_scheduler_nrscope; - uint32_t nof_threads; uint32_t nof_rnti_worker_groups; uint8_t nof_bwps; uint32_t nof_workers; + NRScopeTask::TaskSchedulerNRScope task_scheduler_nrscope; + /* a better coordination between producer (fetch) and consumer (resample and decode) */ sem_t smph_sf_data_prod_cons; @@ -78,7 +79,6 @@ class Radio{ bool to_google; std::string google_credential; - // std::string google_project_id; std::string google_dataset_id; Radio(); //constructor diff --git a/nrscope/hdr/sibs_decoder.h b/nrscope/hdr/sibs_decoder.h index 4ab4234a..2d03b5f1 100644 --- a/nrscope/hdr/sibs_decoder.h +++ b/nrscope/hdr/sibs_decoder.h @@ -78,16 +78,6 @@ class SIBsDecoder{ // std::vector& sibs, // asn1::rrc_nr::sib1_s* sib1_); - // /** - // * A function that represents the SIB thread for a producer-consumer threading design, - // * but currently we don't adopt such design. - // * - // * @return SRSRAN_SUCCESS (0) if everything goes well. - // * SRSRAN_ERROR (-1) if something is wrong in the function. - // */ - // int sibs_thread(srsran_ue_dl_nr_sratescs_info arg_scs_, - // TaskSchedulerNRScope* task_scheduler_nrscope, - // cf_t* input[SRSRAN_MAX_PORTS]); }; #endif \ No newline at end of file diff --git a/nrscope/hdr/task_scheduler.h b/nrscope/hdr/task_scheduler.h index c8a609cf..d2bdfd1e 100644 --- a/nrscope/hdr/task_scheduler.h +++ b/nrscope/hdr/task_scheduler.h @@ -20,6 +20,8 @@ class TaskSchedulerNRScope{ std::vector > workers; /* Slot results reorder buffer */ std::vector slot_results; + /* The next slot result that task_scheduler expects*/ + SlotResult next_result; bool local_log; bool to_google; @@ -50,9 +52,12 @@ class TaskSchedulerNRScope{ int UpdatewithResult(SlotResult now_result); + void UpdateNextResult(); + /* Assign the current slot to one worker*/ - int AssignTask(srsran_slot_cfg_t* slot, - srsran_ue_sync_nr_outcome_t* outcome, + int AssignTask(uint64_t sf_round, + srsran_slot_cfg_t slot, + srsran_ue_sync_nr_outcome_t outcome, cf_t* rx_buffer_); /* resampler tools */ diff --git a/nrscope/src/libs/asn_decoder.c b/nrscope/src/libs/asn_decoder.c index 5ca5a94f..71eda490 100644 --- a/nrscope/src/libs/asn_decoder.c +++ b/nrscope/src/libs/asn_decoder.c @@ -100,7 +100,8 @@ void * asn_processor(void * args) free(node->payload); free(node); #else - fprintf(decoder.file, "4G MIB message cannot be decoded: libasn4g is not installed\n"); + fprintf(decoder.file, + "4G MIB message cannot be decoded: libasn4g is not installed\n"); #endif break; case SIB_4G: @@ -110,7 +111,8 @@ void * asn_processor(void * args) free(node->payload); free(node); #else - fprintf(decoder.file, "4G SIB message cannot be decoded: libasn4g is not installed\n"); + fprintf(decoder.file, + "4G SIB message cannot be decoded: libasn4g is not installed\n"); #endif break; case MIB_5G: @@ -120,7 +122,8 @@ void * asn_processor(void * args) free(node->payload); free(node); #else - fprintf(decoder.file, "5G MIB message cannot be decoded: libasn5g is not installed\n"); + fprintf(decoder.file, + "5G MIB message cannot be decoded: libasn5g is not installed\n"); #endif break; case SIB_5G: @@ -130,7 +133,8 @@ void * asn_processor(void * args) free(node->payload); free(node); #else - fprintf(decoder.file, "5G SIB message cannot be decoded: libasn5g is not installed\n"); + fprintf(decoder.file, + "5G SIB message cannot be decoded: libasn5g is not installed\n"); #endif break; @@ -154,7 +158,8 @@ int init_asn_decoder(const char * path) if((decoder.file = fopen(path, "w")) == NULL) { decoder.file = NULL; - printf("Error openning SIB log file %s (%d): %s\n", path, errno, strerror(errno)); + printf("Error openning SIB log file %s (%d): %s\n", + path, errno, strerror(errno)); return 1; } @@ -171,7 +176,8 @@ int push_asn_payload(uint8_t * payload, int len, PayloadType type, uint32_t tti) { Node * node; - /* If the decoder initialization has failed, this fucntion does nothing and returns error */ + /* If the decoder initialization has failed, + this fucntion does nothing and returns error */ if(decoder.file == NULL) return 1; diff --git a/nrscope/src/libs/nrscope_def.cc b/nrscope/src/libs/nrscope_def.cc index b7a491d1..21fb33bc 100644 --- a/nrscope/src/libs/nrscope_def.cc +++ b/nrscope/src/libs/nrscope_def.cc @@ -1,12 +1,12 @@ #include "nrscope/hdr/nrscope_def.h" double get_now_timestamp_in_double(){ - // auto time = std::chrono::system_clock::now().time_since_epoch(); - // std::chrono::seconds seconds = std::chrono::duration_cast< std::chrono::seconds >(time); - // std::chrono::milliseconds ms = std::chrono::duration_cast< std::chrono::milliseconds >(std::chrono::system_clock::now().time_since_epoch()); - std::chrono::microseconds us = std::chrono::duration_cast< std::chrono::microseconds >(std::chrono::system_clock::now().time_since_epoch()); + std::chrono::microseconds us = std::chrono::duration_cast< + std::chrono::microseconds >(std::chrono::system_clock::now(). + time_since_epoch()); - return ((double) us.count()) / 1000000.0; // + ((double) (us.count() % 1000000)/1000000.0); + return ((double) us.count()) / 1000000.0; + // + ((double) (us.count() % 1000000)/1000000.0); } const char* sch_mapping_to_str(srsran_sch_mapping_type_t mapping) @@ -57,9 +57,26 @@ uint32_t get_P(uint32_t bwp_nof_prb, bool config_1_or_2) return 16; } -/// TS 38.214 - total number of RBGs for a uplink bandwidth part of size "bwp_nof_prb" PRBs -uint32_t get_nof_rbgs(uint32_t bwp_nof_prb, uint32_t bwp_start, bool config1_or_2) +/* TS 38.214 - total number of RBGs for a uplink bandwidth part of size +"bwp_nof_prb" PRBs */ +uint32_t get_nof_rbgs(uint32_t bwp_nof_prb, + uint32_t bwp_start, + bool config1_or_2) { uint32_t P = get_P(bwp_nof_prb, config1_or_2); return srsran::ceil_div(bwp_nof_prb + (bwp_start % P), P); +} + +bool CompareSlotResult (SlotResult a, SlotResult b) { + /* Return true if a < b */ + /* If the sf_round is different */ + if (a.sf_round < b.sf_round) return true; + if (a.sf_round > b.sf_round) return false; + + /* If the sfn is different */ + if (a.outcome.sfn < b.outcome.sfn) return true; + if (a.outcome.sfn > b.outcome.sfn) return false; + + /* If the sfn is the same */ + return a.slot.idx < b.slot.idx; } \ No newline at end of file diff --git a/nrscope/src/libs/nrscope_logger.cc b/nrscope/src/libs/nrscope_logger.cc index 1450ea48..9118a885 100644 --- a/nrscope/src/libs/nrscope_logger.cc +++ b/nrscope/src/libs/nrscope_logger.cc @@ -20,10 +20,13 @@ namespace NRScopeLog{ // log_queue.emplace_back(log_queue_empty); FILE* pFile = fopen(filename[f_id].c_str(), "a"); // Transform the input_node into one log entry row. - fprintf(pFile, "%s\n", "timestamp,system_frame_index,slot_index,rnti,rnti_type,dci_format,k,mapping,time_start,time_length," - "frequency_start,frequency_length,nof_dmrs_cdm_groups,beta_dmrs,nof_layers,n_scid,tb_scaling_field," - "modulation,mcs_index,transport_block_size,code_rate,redundancy_version,new_data_indicator," - "nof_re,nof_bits,mcs_table,xoverhead,harq_id,downlink_assignment_index,tpc,pucch_resource,harq_feedback,bwp"); + fprintf(pFile, "%s\n", "timestamp,system_frame_index,slot_index,rnti," + "rnti_type,dci_format,k,mapping,time_start,time_length,frequency_start," + "frequency_length,nof_dmrs_cdm_groups,beta_dmrs,nof_layers,n_scid," + "tb_scaling_field,modulation,mcs_index,transport_block_size,code_rate," + "redundancy_version,new_data_indicator,nof_re,nof_bits,mcs_table," + "xoverhead,harq_id,downlink_assignment_index,tpc,pucch_resource," + "harq_feedback,bwp"); fclose(pFile); } run_log = true; @@ -68,7 +71,8 @@ namespace NRScopeLog{ } } - snprintf(buff, sizeof(buff), "%f,%d,%d,%d,%s,%s,%d,%s,%d,%d,%d,%d,%d,%f,%d,%d,%d,%s,%d,%d,%f,%d,%d,%d,%d,%s,%s,%d,%d,%d,%d,%d,%d", + snprintf(buff, sizeof(buff), "%f,%d,%d,%d,%s,%s,%d,%s,%d,%d,%d,%d,%d,%f,%d," + "%d,%d,%s,%d,%d,%f,%d,%d,%d,%d,%s,%s,%d,%d,%d,%d,%d,%d", input_node.timestamp, input_node.system_frame_idx, input_node.slot_idx, @@ -96,11 +100,16 @@ namespace NRScopeLog{ input_node.grant.grant.tb[0].nof_bits, srsran_mcs_table_to_str(input_node.grant.sch_cfg.mcs_table), sch_xoverhead_to_str(input_node.grant.sch_cfg.xoverhead), - input_node.dci_format == "1_1" ? input_node.dl_dci.pid : input_node.ul_dci.pid, - input_node.dci_format == "1_1" ? input_node.dl_dci.dai : input_node.ul_dci.dai1, - input_node.dci_format == "1_1" ? input_node.dl_dci.tpc : input_node.ul_dci.tpc, - input_node.dci_format == "1_1" ? input_node.dl_dci.pucch_resource : 0, - input_node.dci_format == "1_1" ? input_node.dl_dci.harq_feedback : 0, + input_node.dci_format == + "1_1" ? input_node.dl_dci.pid : input_node.ul_dci.pid, + input_node.dci_format == + "1_1" ? input_node.dl_dci.dai : input_node.ul_dci.dai1, + input_node.dci_format == + "1_1" ? input_node.dl_dci.tpc : input_node.ul_dci.tpc, + input_node.dci_format == + "1_1" ? input_node.dl_dci.pucch_resource : 0, + input_node.dci_format == + "1_1" ? input_node.dl_dci.harq_feedback : 0, input_node.bwp_id ); FILE* pFile = fopen(filename[rf_index].c_str(), "a"); diff --git a/nrscope/src/libs/nrscope_worker.cc b/nrscope/src/libs/nrscope_worker.cc index f7cfc3f1..3cbfa47b 100644 --- a/nrscope/src/libs/nrscope_worker.cc +++ b/nrscope/src/libs/nrscope_worker.cc @@ -55,11 +55,13 @@ void NRScopeWorker::StartWorker(){ worker_thread.detach(); } -void NRScopeWorker::CopySlotandBuffer(srsran_slot_cfg_t* slot_, - srsran_ue_sync_nr_outcome_t* outcome_, +void NRScopeWorker::CopySlotandBuffer(uint64_t sf_round_, + srsran_slot_cfg_t slot_, + srsran_ue_sync_nr_outcome_t outcome_, cf_t* rx_buffer_) { - slot = *slot_; - outcome = *outcome_; + sf_round = sf_round_; + slot = slot_; + outcome = outcome_; srsran_vec_cf_copy(rx_buffer, rx_buffer_, worker_state.slot_sz); } @@ -149,21 +151,6 @@ int NRScopeWorker::SyncState(WorkState* task_scheduler_state) { worker_state.all_sibs_found = task_scheduler_state->all_sibs_found; - if (!worker_state.sib1_inited && task_scheduler_state->sib1_inited) { - InitSIBDecoder(); - worker_state.sib1_inited = task_scheduler_state->sib1_inited; - } - - if (!worker_state.rach_inited && task_scheduler_state->rach_inited) { - InitRACHDecoder(); - worker_state.rach_inited = task_scheduler_state->rach_inited; - } - - if (!worker_state.dci_inited && task_scheduler_state->dci_inited) { - InitDCIDecoders(); - worker_state.dci_inited = task_scheduler_state->dci_inited; - } - worker_state.nof_known_rntis = task_scheduler_state->nof_known_rntis; worker_state.known_rntis.resize(worker_state.nof_known_rntis); for (long unsigned int i = 0; i < worker_state.nof_known_rntis; i ++) { @@ -263,6 +250,9 @@ void NRScopeWorker::Run() { busy = true; task_lock.unlock(); + std::cout << "Processing sf_round: " << sf_round << ", sfn: " << outcome.sfn + << ", slot.idx: " << slot.idx << std::endl; + SlotResult slot_result = {}; /* Set the all the results to be false, will be set inside the decoder threads */ @@ -271,10 +261,22 @@ void NRScopeWorker::Run() { slot_result.dci_result = false; slot_result.slot = slot; slot_result.outcome = outcome; + slot_result.sf_round = sf_round; + + /* Put the initialization delay into the worker's thread */ + if (!worker_state.sib1_inited) { + InitSIBDecoder(); + worker_state.sib1_inited = true; + } - /* If we accidentally assign the job without initializing the SIB decoder */ - if(!worker_state.sib1_inited){ - continue; + if (!worker_state.rach_inited && worker_state.sib1_found) { + InitRACHDecoder(); + worker_state.rach_inited = true; + } + + if (!worker_state.dci_inited && worker_state.rach_found) { + InitDCIDecoders(); + worker_state.dci_inited = true; } std::thread sibs_thread; @@ -327,9 +329,15 @@ void NRScopeWorker::Run() { slot_result.dci_feedback_results = results; } + std::cout << "After processing sf_round: " << sf_round << ", sfn: " + << outcome.sfn << ", slot.idx: " << slot.idx << std::endl; + std::cout << "slot_result sf_round: " << slot_result.sf_round << ", sfn: " + << slot_result.outcome.sfn << ", slot.idx: " << slot_result.slot.idx + << std::endl; + /* Post the result into the result queue*/ task_lock.lock(); - global_slot_results.emplace_back(slot_result); + global_slot_results.push_back(slot_result); busy = false; task_lock.unlock(); } diff --git a/nrscope/src/libs/radio_nr.cc b/nrscope/src/libs/radio_nr.cc index d6936ade..687816c9 100644 --- a/nrscope/src/libs/radio_nr.cc +++ b/nrscope/src/libs/radio_nr.cc @@ -17,6 +17,7 @@ Radio::Radio() : nof_trials = 100; nof_trials_scan = 200; + sf_round = 0; srsran_searcher_args_t.max_srate_hz = 92.16e6; srsran_searcher_args_t.ssb_min_scs = srsran_subcarrier_spacing_15kHz; srsran_searcher.init(srsran_searcher_args_t); @@ -708,16 +709,6 @@ int Radio::DecodeAndProcess(){ uint32_t pre_resampling_sf_sz = SRSRAN_NOF_SLOTS_PER_SF_NR(task_scheduler_nrscope.task_scheduler_state. args_t.ssb_scs) * pre_resampling_slot_sz; - // if(!task_scheduler_nrscope.task_scheduler_state.sib1_inited){ - // /* Initialize all the worker's sib decoder */ - // srsran::rf_buffer_t rf_buffer_wrapper(rx_buffer, pre_resampling_sf_sz); - // if(sibs_decoder.sib_decoder_and_reception_init(arg_scs, - // &task_scheduler_nrscope, rf_buffer_wrapper.to_cf_t()) < SRSASN_SUCCESS){ - // ERROR("SIBsDecoder Init Error"); - // return NR_FAILURE; - // } - // std::cout << "SIB Decoder Initializing..." << std::endl; - // } uint64_t next_consume_at = 0; bool first_time = true; @@ -736,6 +727,11 @@ int Radio::DecodeAndProcess(){ srsran_slot_cfg_t slot = {0}; slot.idx = (outcome.sf_idx) * SRSRAN_NSLOTS_PER_FRAME_NR(arg_scs.scs) / 10 + slot_idx; + + if (slot.idx == 0 && outcome.sfn == 0) { + /* this is a new round of system frame indexes */ + sf_round ++; + } /* Move rx_buffer here wanted data move to the buffer beginning for decoders to process fetch and resample thread will store unprocessed data at 1 to @@ -746,141 +742,41 @@ int Radio::DecodeAndProcess(){ (first_time ? 0 : ((next_consume_at % RING_BUF_MODULUS + 1) * pre_resampling_sf_sz)) + (slot_idx * slot_sz), slot_sz); - std::cout << "decode slot: " << slot_idx << "; current_consume_ptr: " + std::cout << "decode slot: " << (int) slot.idx << "; current_consume_ptr: " << rx_buffer + (first_time ? 0 : ((next_consume_at % RING_BUF_MODULUS + 1) * pre_resampling_sf_sz)) + (slot_idx * slot_sz) << std::endl; - if (task_scheduler_nrscope.AssignTask(&slot, &outcome, rx_buffer) + if (first_time) { + /* If the next result is not set */ + NRScopeTask::task_lock.lock(); + task_scheduler_nrscope.next_result.sf_round = sf_round; + task_scheduler_nrscope.next_result.slot.idx = slot.idx; + if (outcome.sfn == 1023){ + task_scheduler_nrscope.next_result.outcome.sfn = 0; + task_scheduler_nrscope.next_result.sf_round ++; + } else { + task_scheduler_nrscope.next_result.outcome.sfn = outcome.sfn + 1; + } + + NRScopeTask::task_lock.unlock(); + } + + if (task_scheduler_nrscope.AssignTask(sf_round, slot, outcome, rx_buffer) < SRSRAN_SUCCESS) { ERROR("Assign task failed"); + /* Push empty slot result to the queue */ + SlotResult empty_result = {}; + empty_result.sf_round = sf_round; + empty_result.slot = slot; + empty_result.outcome = outcome; + empty_result.sib_result = false; + empty_result.rach_result = false; + empty_result.dci_result = false; + NRScopeTask::task_lock.lock(); + NRScopeTask::global_slot_results.push_back(empty_result); + NRScopeTask::task_lock.unlock(); } - - // if(!task_scheduler_nrscope.rach_inited and task_scheduler_nrscope. - // sib1_found){ - // // std::thread rach_init_thread {&RachDecoder::rach_decoder_init, - // // &rach_decoder, task_scheduler_nrscope.sib1, args_t.base_carrier}; - // rach_decoder.rach_decoder_init(&task_scheduler_nrscope); - // srsran::rf_buffer_t rf_buffer_wrapper(rx_buffer, pre_resampling_sf_sz); - // if(rach_decoder.rach_reception_init(arg_scs, &task_scheduler_nrscope, - // rf_buffer_wrapper.to_cf_t()) < SRSASN_SUCCESS){ - // ERROR("RACHDecoder Init Error"); - // return NR_FAILURE; - // } - // std::cout << "RACH Decoder Initialized.." << std::endl; - // task_scheduler_nrscope.rach_inited = true; - // } - - // if(!task_scheduler_nrscope.dci_inited and task_scheduler_nrscope. - // rach_found){ - // std::cout << "Initializing DCI decoder..." << std::endl; - // task_scheduler_nrscope.sharded_results.resize(nof_threads); - // task_scheduler_nrscope.nof_sharded_rntis.resize(nof_threads); - // task_scheduler_nrscope.sharded_rntis.resize(nof_threads); - // task_scheduler_nrscope.nof_threads = nof_threads; - // task_scheduler_nrscope.nof_rnti_worker_groups = nof_rnti_worker_groups; - // task_scheduler_nrscope.nof_bwps = nof_bwps; - // task_scheduler_nrscope.results.resize(nof_bwps); - // for(uint32_t i = 0; i < nof_rnti_worker_groups; i++){ - // // for each rnti worker group, for each bwp, spawn a decoder - // for(uint8_t j = 0; j < nof_bwps; j++){ - // DCIDecoder *decoder = new DCIDecoder(100); - // if(decoder->dci_decoder_and_reception_init(arg_scs, &task_scheduler_nrscope, j) < SRSASN_SUCCESS){ - // ERROR("DCIDecoder Init Error"); - // return NR_FAILURE; - // } - // decoder->dci_decoder_id = i * nof_bwps + j; - // decoder->rnti_worker_group_id = i; - // dci_decoders.push_back(std::unique_ptr (decoder)); - // } - // } - - // std::cout << "DCI Decoder Initialized.." << std::endl; - // task_scheduler_nrscope.dci_inited = true; - // } - - // // Then start each type of decoder, TODO - // task_scheduler_nrscope.dl_prb_rate.resize(task_scheduler_nrscope.nof_known_rntis); - // task_scheduler_nrscope.ul_prb_rate.resize(task_scheduler_nrscope.nof_known_rntis); - // task_scheduler_nrscope.dl_prb_bits_rate.resize(task_scheduler_nrscope.nof_known_rntis); - // task_scheduler_nrscope.ul_prb_bits_rate.resize(task_scheduler_nrscope.nof_known_rntis); - - // // To save computing resources for dci decoders: assume SIB1 info should be static - // std::thread sibs_thread; - // if (!task_scheduler_nrscope.sib1_found) { - // sibs_thread = std::thread {&SIBsDecoder::decode_and_parse_sib1_from_slot, &sibs_decoder, &slot, &task_scheduler_nrscope}; - // } - // std::thread rach_thread {&RachDecoder::decode_and_parse_msg4_from_slot, &rach_decoder, &slot, &task_scheduler_nrscope}; - - // std::vector dci_threads; - // if(task_scheduler_nrscope.dci_inited){ - // for (uint32_t i = 0; i < nof_threads; i++){ - // dci_threads.emplace_back(&DCIDecoder::decode_and_parse_dci_from_slot, dci_decoders[i].get(), &slot, &task_scheduler_nrscope); - // } - // } - - // if(sibs_thread.joinable()){ - // sibs_thread.join(); - // } - - // if(rach_thread.joinable()){ - // rach_thread.join(); - // } - - // if(task_scheduler_nrscope.dci_inited){ - // for (uint32_t i = 0; i < nof_threads; i++){ - // if(dci_threads[i].joinable()){ - // dci_threads[i].join(); - // } - // } - // } - - // if(task_scheduler_nrscope.dci_inited){ - // task_scheduler_nrscope.MergeResults(); - // std::vector results = task_scheduler_nrscope.get_results(); - - // for (uint8_t b = 0; b < nof_bwps; b++) { - // DCIFeedback result = results[b]; - // if((result.dl_grants.size()>0 or result.ul_grants.size()>0)){ - // for (uint32_t i = 0; i < task_scheduler_nrscope.nof_known_rntis; i++){ - // if(result.dl_grants[i].grant.rnti == task_scheduler_nrscope.known_rntis[i]){ - // LogNode log_node; - // log_node.slot_idx = slot.idx; - // log_node.system_frame_idx = outcome.sfn; - // log_node.timestamp = get_now_timestamp_in_double(); - // log_node.grant = result.dl_grants[i]; - // log_node.dci_format = srsran_dci_format_nr_string(result.dl_dcis[i].ctx.format); - // log_node.dl_dci = result.dl_dcis[i]; - // log_node.bwp_id = result.dl_dcis[i].bwp_id; - // if(local_log){ - // NRScopeLog::push_node(log_node, rf_index); - // } - // if(to_google){ - // ToGoogle::push_google_node(log_node, rf_index); - // } - // } - - // if(result.ul_grants[i].grant.rnti == task_scheduler_nrscope.known_rntis[i]){ - // LogNode log_node; - // log_node.slot_idx = slot.idx; - // log_node.system_frame_idx = outcome.sfn; - // log_node.timestamp = get_now_timestamp_in_double(); - // log_node.grant = result.ul_grants[i]; - // log_node.dci_format = srsran_dci_format_nr_string(result.ul_dcis[i].ctx.format); - // log_node.ul_dci = result.ul_dcis[i]; - // log_node.bwp_id = result.ul_dcis[i].bwp_id; - // if(local_log){ - // NRScopeLog::push_node(log_node, rf_index); - // } - // if(to_google){ - // ToGoogle::push_google_node(log_node, rf_index); - // } - // } - // } - // } - // } - // } - // task_scheduler_nrscope.UpdateKnownRNTIs(); } // slot iteration gettimeofday(&t1, NULL); diff --git a/nrscope/src/libs/task_scheduler.cc b/nrscope/src/libs/task_scheduler.cc index 9ca7a253..36fb74d5 100644 --- a/nrscope/src/libs/task_scheduler.cc +++ b/nrscope/src/libs/task_scheduler.cc @@ -6,12 +6,14 @@ TaskSchedulerNRScope::TaskSchedulerNRScope(){ task_scheduler_state.sib1_inited = false; task_scheduler_state.rach_inited = false; task_scheduler_state.dci_inited = false; - task_scheduler_state.sib1_found = false; task_scheduler_state.rach_found = false; - task_scheduler_state.nof_known_rntis = 0; task_scheduler_state.known_rntis.resize(task_scheduler_state.nof_known_rntis); + + next_result.sf_round = 0; + next_result.slot.idx = 0; + next_result.outcome.sfn = 0; } TaskSchedulerNRScope::~TaskSchedulerNRScope(){ @@ -304,14 +306,49 @@ int TaskSchedulerNRScope::UpdatewithResult(SlotResult now_result) { int TaskSchedulerNRScope::UpdateStateandLog() { /* Right now there is no re-order function, just update the state and log*/ - while(slot_results.size() > 0) { + std::sort(slot_results.begin(), slot_results.end()); + // std::cout << "expected sf_round: " << next_result.sf_round << std::endl; + // std::cout << "expected sfn: " << next_result.outcome.sfn << std::endl; + // std::cout << "expected slot: " << next_result.slot.idx << std::endl; + // for (unsigned long int i = 0; i < slot_results.size(); i++) { + // std::cout << i << ", sfn: " << slot_results[i].outcome.sfn << std::endl; + // std::cout << i << ", sf_round: " << slot_results[i].sf_round << std::endl; + // std::cout << i << ", slot: " << slot_results[i].slot.idx << std::endl; + // } + while (//(slot_results[0] < next_result || slot_results[0] == next_result) && + slot_results.size() > 0) { + // if (slot_results[0] < next_result){ + // slot_results.erase(slot_results.begin()); + // continue; + // } else if (slot_results[0] == next_result){ SlotResult now_result = slot_results[0]; UpdatewithResult(now_result); slot_results.erase(slot_results.begin()); + UpdateNextResult(); + // } else { + // break; + // } } return SRSRAN_SUCCESS; } +void TaskSchedulerNRScope::UpdateNextResult() { + if (next_result.slot.idx == + SRSRAN_NSLOTS_PER_FRAME_NR(task_scheduler_state.args_t.ssb_scs)-1) { + next_result.slot.idx = 0; + /* We will need to increase the outcome.sfn */ + if (next_result.outcome.sfn == 1023) { + /* We will need to increase the sf_round */ + next_result.sf_round ++; + next_result.outcome.sfn = 0; + } else { + next_result.outcome.sfn ++; + } + } else { + next_result.slot.idx ++; + } +} + void TaskSchedulerNRScope::Run() { while(true) { /* Try to extract results from the global result queue*/ @@ -320,7 +357,7 @@ void TaskSchedulerNRScope::Run() { if (queue_len > 0) { while (global_slot_results.size() > 0) { /* dequeue from the head of the queue */ - slot_results.push_back(global_slot_results.front()); + slot_results.push_back(global_slot_results[0]); global_slot_results.erase(global_slot_results.begin()); } } @@ -328,38 +365,43 @@ void TaskSchedulerNRScope::Run() { /* reorder the local slot_results and wait for the correct data for output */ - UpdateStateandLog(); + if (slot_results.size() > 0) + UpdateStateandLog(); } } -int TaskSchedulerNRScope::AssignTask(srsran_slot_cfg_t* slot, - srsran_ue_sync_nr_outcome_t* outcome, +int TaskSchedulerNRScope::AssignTask(uint64_t sf_round, + srsran_slot_cfg_t slot, + srsran_ue_sync_nr_outcome_t outcome, cf_t* rx_buffer_){ /* Find the first idle worker */ bool found_worker = false; + std::cout << "Assigning sf_round: " << sf_round << ", sfn: " << outcome.sfn + << ", slot.idx: " << slot.idx << std::endl; for (uint32_t i = 0; i < nof_workers; i ++) { bool busy = true; task_lock.lock(); busy = workers[i].get()->busy; - task_lock.unlock(); if (!busy) { found_worker = true; /* Copy the rx_buffer_ to the worker's rx_buffer. This won't be interfering with other threads? */ - workers[i].get()->CopySlotandBuffer(slot, outcome, rx_buffer_); - task_lock.lock(); + workers[i].get()->CopySlotandBuffer(sf_round, slot, outcome, rx_buffer_); /* Update the worker's state */ workers[i].get()->SyncState(&task_scheduler_state); - task_lock.unlock(); /* Set the worker's sem to let the task run */ sem_post(&workers[i].get()->smph_has_job); - + } + task_lock.unlock(); + if (found_worker) { break; } } if (!found_worker) { - ERROR("No available worker, consider increasing the number of workers."); + ERROR("No available worker, if this constantly happens not in the intial" + "stage (SIBs, RACH, DCI decoders initialization), please consider " + "increasing the number of workers."); return SRSRAN_ERROR; } else { return SRSRAN_SUCCESS; From 1da1cfbc1a7d0e2f2514ef16aa26439dcb99c011 Mon Sep 17 00:00:00 2001 From: Haoran Wan Date: Thu, 12 Sep 2024 13:26:25 -0400 Subject: [PATCH 08/15] try cpu affinity --- nrscope/config/config.yaml | 13 +++--- nrscope/hdr/nrscope_def.h | 11 ++---- nrscope/hdr/nrscope_worker.h | 3 +- nrscope/hdr/radio_nr.h | 4 +- nrscope/hdr/task_scheduler.h | 1 + nrscope/src/libs/load_config.cc | 32 ++++++++++++++- nrscope/src/libs/nrscope_worker.cc | 63 ++++++++++++++++++++++++------ nrscope/src/libs/radio_nr.cc | 15 +++---- nrscope/src/libs/task_scheduler.cc | 20 +++++----- 9 files changed, 116 insertions(+), 46 deletions(-) diff --git a/nrscope/config/config.yaml b/nrscope/config/config.yaml index ec464e05..f54a0865 100644 --- a/nrscope/config/config.yaml +++ b/nrscope/config/config.yaml @@ -1,18 +1,19 @@ nof_usrp_dev: 1 usrp_setting_0: - ssb_freq: 3630720000 # should be set to the ssb frequency of the cell - rf_args: "clock=external,type=x300,master_clock_rate=184320000,sampling_rate=23040000" #"type=x300" #"clock=external" for TwinRX + ssb_freq: 3660960000 # should be set to the ssb frequency of the cell + rf_args: "clock=external,type=x300,serial=32B0F2F,master_clock_rate=200000000,sampling_rate=50000000" #"type=x300" #"clock=external" for TwinRX # rf_args: "clock=external,type=x300,sampling_rate=23040000" #"type=x300" #"clock=external" for CBX - rx_gain: 80 # for x310 CBX, max rx gain is 31.5, for b210, it's around 80, for x310 TwinRX, max rx gain is 90 - srate_hz: 23040000 #11520000 #11520000 #23040000 (CBX) - srsran_srate_hz: 23040000 + rx_gain: 90 # for x310 CBX, max rx gain is 31.5, for b210, it's around 80, for x310 TwinRX, max rx gain is 90 + srate_hz: 50000000 #11520000 #11520000 #23040000 (CBX) + srsran_srate_hz: 46080000 nof_carriers: 1 nof_antennas: 1 scs_index: 1 #(0: 15kHz, 1: 30kHz, ..., the u in standard) rf_log_level: "debug" nof_rnti_worker_groups: 1 nof_bwps: 1 - nof_workers: 16 + cpu_affinity: true + nof_workers: 2 log_name: "a.csv" #"/home/wanhr/Documents/data/nrscope/evaluation/coverage_amarisoft/dci_tx_50.csv" # x (0-10), y(0-8) coordinates google_dataset_id: "ngscope5g_dci_log_wanhr" diff --git a/nrscope/hdr/nrscope_def.h b/nrscope/hdr/nrscope_def.h index 25adad86..2e84c9af 100644 --- a/nrscope/hdr/nrscope_def.h +++ b/nrscope/hdr/nrscope_def.h @@ -171,6 +171,7 @@ typedef struct WorkState_ WorkState; uint32_t nof_threads; uint32_t nof_rnti_worker_groups; uint8_t nof_bwps; + bool cpu_affinity; uint32_t slot_sz; @@ -260,15 +261,11 @@ bool CompareSlotResult (SlotResult a, SlotResult b); namespace NRScopeTask{ extern std::vector global_slot_results; - extern std::mutex task_lock; + extern std::mutex queue_lock; + extern std::mutex task_scheduler_lock; + extern std::mutex worker_locks[128]; } -// namespace NRScopeTask{ -// /* Add some global variables for the task_scheduler and workers */ -// std::vector global_slot_results; - -// std::mutex task_lock; -// } /** * @brief Function brought from phch_cfg_nr.c diff --git a/nrscope/hdr/nrscope_worker.h b/nrscope/hdr/nrscope_worker.h index e5b2499c..446bf3fc 100644 --- a/nrscope/hdr/nrscope_worker.h +++ b/nrscope/hdr/nrscope_worker.h @@ -21,6 +21,7 @@ class NRScopeWorker{ /* Job indicator */ sem_t smph_has_job; bool busy; + int worker_id; /* Worker thread */ std::thread worker_thread; @@ -45,7 +46,7 @@ class NRScopeWorker{ /* This is called right after entering the radio_nr.cc, The cell's information is set to the worker, so the worker can set its buffer.*/ - int InitWorker(WorkState task_scheduler_state); + int InitWorker(WorkState task_scheduler_state, int worker_id_); /* Start the worker thread */ void StartWorker(); diff --git a/nrscope/hdr/radio_nr.h b/nrscope/hdr/radio_nr.h index 1957e19f..7db8017f 100644 --- a/nrscope/hdr/radio_nr.h +++ b/nrscope/hdr/radio_nr.h @@ -15,7 +15,7 @@ #include #include -#define RESAMPLE_WORKER_NUM 4 +#define RESAMPLE_WORKER_NUM 8 class Radio{ public: @@ -74,6 +74,8 @@ class Radio{ resampler_kit rk[RESAMPLE_WORKER_NUM]; bool rk_initialized = false; + bool cpu_affinity = false; + std::string log_name; bool local_log; diff --git a/nrscope/hdr/task_scheduler.h b/nrscope/hdr/task_scheduler.h index d2bdfd1e..6a2953f0 100644 --- a/nrscope/hdr/task_scheduler.h +++ b/nrscope/hdr/task_scheduler.h @@ -39,6 +39,7 @@ class TaskSchedulerNRScope{ int32_t nof_threads, uint32_t nof_rnti_worker_groups, uint8_t nof_bwps, + bool cpu_affinity, cell_searcher_args_t args_t, uint32_t nof_workers_); diff --git a/nrscope/src/libs/load_config.cc b/nrscope/src/libs/load_config.cc index 1106dae7..efa1cc7c 100644 --- a/nrscope/src/libs/load_config.cc +++ b/nrscope/src/libs/load_config.cc @@ -142,17 +142,26 @@ int load_config(std::vector& radios, std::string file_name){ radios[i].nof_rnti_worker_groups = 1; } - radios[i].nof_threads = radios[i].nof_rnti_worker_groups; - if(config_yaml[setting_name]["nof_bwps"]){ radios[i].nof_bwps = config_yaml[setting_name]["nof_bwps"].as(); }else{ radios[i].nof_bwps = 1; } + if(config_yaml[setting_name]["cpu_affinity"]){ + radios[i].cpu_affinity = + config_yaml[setting_name]["cpu_affinity"].as(); + }else{ + radios[i].cpu_affinity = false; + } + if(config_yaml[setting_name]["nof_workers"]){ radios[i].nof_workers = config_yaml[setting_name]["nof_workers"].as(); + if (radios[i].nof_workers > 128) { + ERROR("Worker number shouldn't be > 128"); + return SRSRAN_ERROR; + } }else{ radios[i].nof_workers = 1; } @@ -167,6 +176,25 @@ int load_config(std::vector& radios, std::string file_name){ } } + /* Check if the config viable */ + const auto nof_cores = std::thread::hardware_concurrency(); + unsigned int required_cores = 0; + for (int i = 0; i < nof_usrp; i ++) { + if (radios[i].cpu_affinity) { + /* One for SIB thread, one RACH thread, + and nof_bwp * nof_rnti_group for DCI decoding*/ + required_cores += radios[i].nof_workers * (3 + + radios[i].nof_bwps * radios[i].nof_rnti_worker_groups); + } + } + if (required_cores > nof_cores) { + ERROR("CPU affinity set, usrp_i's core requirement is: " + "nof_workers * (3 + nof_bwps * nof_rnti_worker_groups)" + ", please make sure the total required cores %d smaller than your total" + "number of cores: %d.", required_cores, nof_cores); + return NR_FAILURE; + } + std::string setting_name = "log_config"; if(config_yaml[setting_name]["local_log"]){ for (int i = 0; i < nof_usrp; i++){ diff --git a/nrscope/src/libs/nrscope_worker.cc b/nrscope/src/libs/nrscope_worker.cc index 3cbfa47b..fb2a28aa 100644 --- a/nrscope/src/libs/nrscope_worker.cc +++ b/nrscope/src/libs/nrscope_worker.cc @@ -5,7 +5,9 @@ namespace NRScopeTask{ std::vector global_slot_results; -std::mutex task_lock; +std::mutex queue_lock; +std::mutex task_scheduler_lock; +std::mutex worker_locks[128]; NRScopeWorker::NRScopeWorker() : rf_buffer_t(1), @@ -27,7 +29,8 @@ NRScopeWorker::NRScopeWorker() : NRScopeWorker::~NRScopeWorker(){ } -int NRScopeWorker::InitWorker(WorkState task_scheduler_state){ +int NRScopeWorker::InitWorker(WorkState task_scheduler_state, int worker_id_){ + worker_id = worker_id_; /* Copy initial values */ worker_state.nof_threads = task_scheduler_state.nof_threads; worker_state.nof_rnti_worker_groups = @@ -35,6 +38,7 @@ int NRScopeWorker::InitWorker(WorkState task_scheduler_state){ worker_state.nof_bwps = task_scheduler_state.nof_bwps; worker_state.args_t = task_scheduler_state.args_t; worker_state.slot_sz = task_scheduler_state.slot_sz; + worker_state.cpu_affinity = task_scheduler_state.cpu_affinity; /* Size of one subframe */ rx_buffer = srsran_vec_cf_malloc(SRSRAN_NOF_SLOTS_PER_SF_NR( worker_state.args_t.ssb_scs) * worker_state.slot_sz); @@ -52,6 +56,14 @@ int NRScopeWorker::InitWorker(WorkState task_scheduler_state){ void NRScopeWorker::StartWorker(){ // std::cout << "Creating the thread. " << std::endl; worker_thread = std::thread{&NRScopeWorker::Run, this}; + // if (worker_state.cpu_affinity){ + // cpu_set_t cpu_set_worker; + // CPU_ZERO(&cpu_set_worker); + // CPU_SET(worker_id * (3 + worker_state.nof_threads), &cpu_set_worker); + // assert(pthread_setaffinity_np(worker_thread.native_handle(), + // sizeof(cpu_set_t), &cpu_set_worker) == 0); + // } + worker_thread.detach(); } @@ -246,12 +258,12 @@ void NRScopeWorker::Run() { while (true) { /* When there is a job, the semaphore is set and buffer is copied */ sem_wait(&smph_has_job); - task_lock.lock(); + worker_locks[worker_id].lock(); busy = true; - task_lock.unlock(); + worker_locks[worker_id].unlock(); - std::cout << "Processing sf_round: " << sf_round << ", sfn: " << outcome.sfn - << ", slot.idx: " << slot.idx << std::endl; + // std::cout << "Processing sf_round: " << sf_round << ", sfn: " << outcome.sfn + // << ", slot.idx: " << slot.idx << std::endl; SlotResult slot_result = {}; /* Set the all the results to be false, will be set inside the decoder @@ -284,12 +296,26 @@ void NRScopeWorker::Run() { if (worker_state.sib1_inited) { sibs_thread = std::thread {&SIBsDecoder::DecodeandParseSIB1fromSlot, &sibs_decoder, &slot, &worker_state, &slot_result}; + // if (worker_state.cpu_affinity){ + // cpu_set_t cpu_set_sib; + // CPU_ZERO(&cpu_set_sib); + // CPU_SET(worker_id * (3+worker_state.nof_threads) + 1, &cpu_set_sib); + // assert(pthread_setaffinity_np(sibs_thread.native_handle(), + // sizeof(cpu_set_t), &cpu_set_sib) == 0); + // } } std::thread rach_thread; if (worker_state.rach_inited) { rach_thread = std::thread {&RachDecoder::DecodeandParseMS4fromSlot, &rach_decoder, &slot, &worker_state, &slot_result}; + // if (worker_state.cpu_affinity) { + // cpu_set_t cpu_set_rach; + // CPU_ZERO(&cpu_set_rach); + // CPU_SET(worker_id * (3+worker_state.nof_threads) + 2, &cpu_set_rach); + // assert(pthread_setaffinity_np(rach_thread.native_handle(), + // sizeof(cpu_set_t), &cpu_set_rach) == 0); + // } } std::vector dci_threads; @@ -309,6 +335,17 @@ void NRScopeWorker::Run() { std::ref(dl_prb_bits_rate), std::ref(ul_prb_rate), std::ref(ul_prb_bits_rate)); } + + // if (worker_state.cpu_affinity) { + // for (uint32_t i = 0; i < worker_state.nof_threads; i ++) { + // cpu_set_t cpu_set_dci; + // CPU_ZERO(&cpu_set_dci); + // CPU_SET(worker_id * (3+worker_state.nof_threads) + i + 3, + // &cpu_set_dci); + // assert(pthread_setaffinity_np(dci_threads[i].native_handle(), + // sizeof(cpu_set_t), &cpu_set_dci) == 0); + // } + // } } if(sibs_thread.joinable()){ @@ -329,17 +366,17 @@ void NRScopeWorker::Run() { slot_result.dci_feedback_results = results; } - std::cout << "After processing sf_round: " << sf_round << ", sfn: " - << outcome.sfn << ", slot.idx: " << slot.idx << std::endl; - std::cout << "slot_result sf_round: " << slot_result.sf_round << ", sfn: " - << slot_result.outcome.sfn << ", slot.idx: " << slot_result.slot.idx - << std::endl; + // std::cout << "After processing sf_round: " << sf_round << ", sfn: " + // << outcome.sfn << ", slot.idx: " << slot.idx << std::endl; + // std::cout << "slot_result sf_round: " << slot_result.sf_round << ", sfn: " + // << slot_result.outcome.sfn << ", slot.idx: " << slot_result.slot.idx + // << std::endl; /* Post the result into the result queue*/ - task_lock.lock(); + queue_lock.lock(); global_slot_results.push_back(slot_result); busy = false; - task_lock.unlock(); + queue_lock.unlock(); } } } \ No newline at end of file diff --git a/nrscope/src/libs/radio_nr.cc b/nrscope/src/libs/radio_nr.cc index 687816c9..0a8324ba 100644 --- a/nrscope/src/libs/radio_nr.cc +++ b/nrscope/src/libs/radio_nr.cc @@ -263,7 +263,8 @@ int Radio::ScanInitandStart(){ } } if(cs_ret.result == srsue::nr::cell_search::ret_t::CELL_FOUND){ - std::cout << "Cell Found! (maybe reported multiple times in the next several GSCN; see README)" << std::endl; + std::cout << "Cell Found! (maybe reported multiple times in the" + " next several GSCN; see README)" << std::endl; std::cout << "N_id: " << cs_ret.ssb_res.N_id << std::endl; if (local_log) { @@ -411,7 +412,8 @@ int Radio::RadioInitandStart(){ /* Initialize the task_scheduler and the workers in it. They will all remain inactive until the MIB is found. */ task_scheduler_nrscope.InitandStart(local_log, to_google, rf_index, - nof_threads, nof_rnti_worker_groups, nof_bwps, args_t, nof_workers); + nof_threads, nof_rnti_worker_groups, nof_bwps, cpu_affinity ,args_t, + nof_workers); std::cout << "Task scheduler started..." << std::endl; while (not ss.end()) { @@ -713,7 +715,6 @@ int Radio::DecodeAndProcess(){ uint64_t next_consume_at = 0; bool first_time = true; task_scheduler_nrscope.task_scheduler_state.sib1_inited = true; - while (true) { sem_wait(&smph_sf_data_prod_cons); std::cout << "current_consume_at: " << (first_time ? 0 : @@ -749,7 +750,7 @@ int Radio::DecodeAndProcess(){ if (first_time) { /* If the next result is not set */ - NRScopeTask::task_lock.lock(); + NRScopeTask::task_scheduler_lock.lock(); task_scheduler_nrscope.next_result.sf_round = sf_round; task_scheduler_nrscope.next_result.slot.idx = slot.idx; if (outcome.sfn == 1023){ @@ -759,7 +760,7 @@ int Radio::DecodeAndProcess(){ task_scheduler_nrscope.next_result.outcome.sfn = outcome.sfn + 1; } - NRScopeTask::task_lock.unlock(); + NRScopeTask::task_scheduler_lock.unlock(); } if (task_scheduler_nrscope.AssignTask(sf_round, slot, outcome, rx_buffer) @@ -773,9 +774,9 @@ int Radio::DecodeAndProcess(){ empty_result.sib_result = false; empty_result.rach_result = false; empty_result.dci_result = false; - NRScopeTask::task_lock.lock(); + NRScopeTask::queue_lock.lock(); NRScopeTask::global_slot_results.push_back(empty_result); - NRScopeTask::task_lock.unlock(); + NRScopeTask::queue_lock.unlock(); } } // slot iteration diff --git a/nrscope/src/libs/task_scheduler.cc b/nrscope/src/libs/task_scheduler.cc index 36fb74d5..72f254f3 100644 --- a/nrscope/src/libs/task_scheduler.cc +++ b/nrscope/src/libs/task_scheduler.cc @@ -25,6 +25,7 @@ int TaskSchedulerNRScope::InitandStart(bool local_log_, int32_t nof_threads, uint32_t nof_rnti_worker_groups, uint8_t nof_bwps, + bool cpu_affinity, cell_searcher_args_t args_t, uint32_t nof_workers_){ local_log = local_log_; @@ -36,12 +37,13 @@ int TaskSchedulerNRScope::InitandStart(bool local_log_, task_scheduler_state.args_t = args_t; task_scheduler_state.slot_sz = (uint32_t)(args_t.srate_hz / 1000.0f / SRSRAN_NOF_SLOTS_PER_SF_NR(args_t.ssb_scs)); + task_scheduler_state.cpu_affinity = cpu_affinity; nof_workers = nof_workers_; std::cout << "Starting workers..." << std::endl; for (uint32_t i = 0; i < nof_workers; i ++) { NRScopeWorker *worker = new NRScopeWorker(); std::cout << "New worker " << i << " is going to start... "<< std::endl; - if(worker->InitWorker(task_scheduler_state) < SRSRAN_SUCCESS) { + if(worker->InitWorker(task_scheduler_state, i) < SRSRAN_SUCCESS) { ERROR("Error initializing worker %d", i); return NR_FAILURE; } @@ -175,7 +177,7 @@ int TaskSchedulerNRScope::DecodeMIB(cell_searcher_args_t* args_t_, } int TaskSchedulerNRScope::UpdatewithResult(SlotResult now_result) { - task_lock.lock(); + task_scheduler_lock.lock(); /* This slot contains SIBs decoder's result */ if (now_result.sib_result) { if (now_result.found_sib1 && !task_scheduler_state.sib1_found) { @@ -250,7 +252,7 @@ int TaskSchedulerNRScope::UpdatewithResult(SlotResult now_result) { task_scheduler_state.dci_inited = true; } } - task_lock.unlock(); + task_scheduler_lock.unlock(); /* This slot contains the DCI decoder's result, put all the results to log */ if (now_result.dci_result) { @@ -352,7 +354,7 @@ void TaskSchedulerNRScope::UpdateNextResult() { void TaskSchedulerNRScope::Run() { while(true) { /* Try to extract results from the global result queue*/ - task_lock.lock(); + queue_lock.lock(); auto queue_len = global_slot_results.size(); if (queue_len > 0) { while (global_slot_results.size() > 0) { @@ -361,7 +363,7 @@ void TaskSchedulerNRScope::Run() { global_slot_results.erase(global_slot_results.begin()); } } - task_lock.unlock(); + queue_lock.unlock(); /* reorder the local slot_results and wait for the correct data for output */ @@ -376,11 +378,11 @@ int TaskSchedulerNRScope::AssignTask(uint64_t sf_round, cf_t* rx_buffer_){ /* Find the first idle worker */ bool found_worker = false; - std::cout << "Assigning sf_round: " << sf_round << ", sfn: " << outcome.sfn - << ", slot.idx: " << slot.idx << std::endl; + // std::cout << "Assigning sf_round: " << sf_round << ", sfn: " << outcome.sfn + // << ", slot.idx: " << slot.idx << std::endl; for (uint32_t i = 0; i < nof_workers; i ++) { + worker_locks[i].lock(); bool busy = true; - task_lock.lock(); busy = workers[i].get()->busy; if (!busy) { found_worker = true; @@ -392,7 +394,7 @@ int TaskSchedulerNRScope::AssignTask(uint64_t sf_round, /* Set the worker's sem to let the task run */ sem_post(&workers[i].get()->smph_has_job); } - task_lock.unlock(); + worker_locks[i].unlock(); if (found_worker) { break; } From 5dba4b579a2d1d8c029a9d78d86465514795a894 Mon Sep 17 00:00:00 2001 From: Haoran Wan Date: Thu, 12 Sep 2024 16:34:08 -0400 Subject: [PATCH 09/15] cpu affinity done --- nrscope/config/config.yaml | 13 ++-- nrscope/hdr/radio_nr.h | 2 +- nrscope/src/libs/load_config.cc | 2 + nrscope/src/libs/nrscope_worker.cc | 95 +++++++++++++++++------------- 4 files changed, 65 insertions(+), 47 deletions(-) diff --git a/nrscope/config/config.yaml b/nrscope/config/config.yaml index f54a0865..deb12f97 100644 --- a/nrscope/config/config.yaml +++ b/nrscope/config/config.yaml @@ -1,19 +1,20 @@ nof_usrp_dev: 1 usrp_setting_0: - ssb_freq: 3660960000 # should be set to the ssb frequency of the cell - rf_args: "clock=external,type=x300,serial=32B0F2F,master_clock_rate=200000000,sampling_rate=50000000" #"type=x300" #"clock=external" for TwinRX + ssb_freq: 3630720000 # should be set to the ssb frequency of the cell + rf_args: "clock=external,type=x300,master_clock_rate=184320000,sampling_rate=23040000" #"type=x300" #"clock=external" for TwinRX # rf_args: "clock=external,type=x300,sampling_rate=23040000" #"type=x300" #"clock=external" for CBX - rx_gain: 90 # for x310 CBX, max rx gain is 31.5, for b210, it's around 80, for x310 TwinRX, max rx gain is 90 - srate_hz: 50000000 #11520000 #11520000 #23040000 (CBX) - srsran_srate_hz: 46080000 + rx_gain: 80 # for x310 CBX, max rx gain is 31.5, for b210, it's around 80, for x310 TwinRX, max rx gain is 90 + srate_hz: 23040000 #11520000 #11520000 #23040000 (CBX) + srsran_srate_hz: 23040000 nof_carriers: 1 nof_antennas: 1 scs_index: 1 #(0: 15kHz, 1: 30kHz, ..., the u in standard) rf_log_level: "debug" nof_rnti_worker_groups: 1 nof_bwps: 1 + nof_workers: 4 cpu_affinity: true - nof_workers: 2 + log_name: "a.csv" #"/home/wanhr/Documents/data/nrscope/evaluation/coverage_amarisoft/dci_tx_50.csv" # x (0-10), y(0-8) coordinates google_dataset_id: "ngscope5g_dci_log_wanhr" diff --git a/nrscope/hdr/radio_nr.h b/nrscope/hdr/radio_nr.h index 7db8017f..80eae4a3 100644 --- a/nrscope/hdr/radio_nr.h +++ b/nrscope/hdr/radio_nr.h @@ -74,7 +74,7 @@ class Radio{ resampler_kit rk[RESAMPLE_WORKER_NUM]; bool rk_initialized = false; - bool cpu_affinity = false; + bool cpu_affinity; std::string log_name; bool local_log; diff --git a/nrscope/src/libs/load_config.cc b/nrscope/src/libs/load_config.cc index efa1cc7c..cb69d16e 100644 --- a/nrscope/src/libs/load_config.cc +++ b/nrscope/src/libs/load_config.cc @@ -142,6 +142,8 @@ int load_config(std::vector& radios, std::string file_name){ radios[i].nof_rnti_worker_groups = 1; } + radios[i].nof_threads = radios[i].nof_rnti_worker_groups; + if(config_yaml[setting_name]["nof_bwps"]){ radios[i].nof_bwps = config_yaml[setting_name]["nof_bwps"].as(); }else{ diff --git a/nrscope/src/libs/nrscope_worker.cc b/nrscope/src/libs/nrscope_worker.cc index fb2a28aa..59daa731 100644 --- a/nrscope/src/libs/nrscope_worker.cc +++ b/nrscope/src/libs/nrscope_worker.cc @@ -55,15 +55,17 @@ int NRScopeWorker::InitWorker(WorkState task_scheduler_state, int worker_id_){ void NRScopeWorker::StartWorker(){ // std::cout << "Creating the thread. " << std::endl; - worker_thread = std::thread{&NRScopeWorker::Run, this}; - // if (worker_state.cpu_affinity){ - // cpu_set_t cpu_set_worker; - // CPU_ZERO(&cpu_set_worker); - // CPU_SET(worker_id * (3 + worker_state.nof_threads), &cpu_set_worker); - // assert(pthread_setaffinity_np(worker_thread.native_handle(), - // sizeof(cpu_set_t), &cpu_set_worker) == 0); - // } - + if (worker_state.cpu_affinity) { + cpu_set_t cpu_set_worker; + CPU_ZERO(&cpu_set_worker); + CPU_SET(worker_id * (3 + worker_state.nof_threads), &cpu_set_worker); + worker_thread = std::thread{&NRScopeWorker::Run, this}; + assert(pthread_setaffinity_np(worker_thread.native_handle(), + sizeof(cpu_set_t), &cpu_set_worker) == 0); + } else { + worker_thread = std::thread{&NRScopeWorker::Run, this}; + } + worker_thread.detach(); } @@ -294,28 +296,34 @@ void NRScopeWorker::Run() { std::thread sibs_thread; /* If sib1 is not found, we run the sibs_thread; if it's found, we skip. */ if (worker_state.sib1_inited) { - sibs_thread = std::thread {&SIBsDecoder::DecodeandParseSIB1fromSlot, - &sibs_decoder, &slot, &worker_state, &slot_result}; - // if (worker_state.cpu_affinity){ - // cpu_set_t cpu_set_sib; - // CPU_ZERO(&cpu_set_sib); - // CPU_SET(worker_id * (3+worker_state.nof_threads) + 1, &cpu_set_sib); - // assert(pthread_setaffinity_np(sibs_thread.native_handle(), - // sizeof(cpu_set_t), &cpu_set_sib) == 0); - // } + if (worker_state.cpu_affinity){ + cpu_set_t cpu_set_sib; + CPU_ZERO(&cpu_set_sib); + CPU_SET(worker_id * (3+worker_state.nof_threads) + 1, &cpu_set_sib); + sibs_thread = std::thread {&SIBsDecoder::DecodeandParseSIB1fromSlot, + &sibs_decoder, &slot, &worker_state, &slot_result}; + assert(pthread_setaffinity_np(sibs_thread.native_handle(), + sizeof(cpu_set_t), &cpu_set_sib) == 0); + } else { + sibs_thread = std::thread {&SIBsDecoder::DecodeandParseSIB1fromSlot, + &sibs_decoder, &slot, &worker_state, &slot_result}; + } } std::thread rach_thread; if (worker_state.rach_inited) { - rach_thread = std::thread {&RachDecoder::DecodeandParseMS4fromSlot, - &rach_decoder, &slot, &worker_state, &slot_result}; - // if (worker_state.cpu_affinity) { - // cpu_set_t cpu_set_rach; - // CPU_ZERO(&cpu_set_rach); - // CPU_SET(worker_id * (3+worker_state.nof_threads) + 2, &cpu_set_rach); - // assert(pthread_setaffinity_np(rach_thread.native_handle(), - // sizeof(cpu_set_t), &cpu_set_rach) == 0); - // } + if (worker_state.cpu_affinity) { + cpu_set_t cpu_set_rach; + CPU_ZERO(&cpu_set_rach); + CPU_SET(worker_id * (3+worker_state.nof_threads) + 2, &cpu_set_rach); + rach_thread = std::thread {&RachDecoder::DecodeandParseMS4fromSlot, + &rach_decoder, &slot, &worker_state, &slot_result}; + assert(pthread_setaffinity_np(rach_thread.native_handle(), + sizeof(cpu_set_t), &cpu_set_rach) == 0); + } else { + rach_thread = std::thread {&RachDecoder::DecodeandParseMS4fromSlot, + &rach_decoder, &slot, &worker_state, &slot_result}; + } } std::vector dci_threads; @@ -327,25 +335,32 @@ void NRScopeWorker::Run() { dl_prb_bits_rate.resize(worker_state.nof_known_rntis); ul_prb_bits_rate.resize(worker_state.nof_known_rntis); - for (uint32_t i = 0; i < worker_state.nof_threads; i++){ - dci_threads.emplace_back(&DCIDecoder::DecodeandParseDCIfromSlot, + + if (worker_state.cpu_affinity) { + for (uint32_t i = 0; i < worker_state.nof_threads; i ++) { + cpu_set_t cpu_set_dci; + CPU_ZERO(&cpu_set_dci); + CPU_SET(worker_id * (3+worker_state.nof_threads) + i + 3, + &cpu_set_dci); + dci_threads.emplace_back(&DCIDecoder::DecodeandParseDCIfromSlot, dci_decoders[i].get(), &slot, &worker_state, std::ref(sharded_results), std::ref(sharded_rntis), std::ref(nof_sharded_rntis), std::ref(dl_prb_rate), std::ref(dl_prb_bits_rate), std::ref(ul_prb_rate), std::ref(ul_prb_bits_rate)); + assert(pthread_setaffinity_np(dci_threads[i].native_handle(), + sizeof(cpu_set_t), &cpu_set_dci) == 0); + } + } else { + for (uint32_t i = 0; i < worker_state.nof_threads; i++){ + dci_threads.emplace_back(&DCIDecoder::DecodeandParseDCIfromSlot, + dci_decoders[i].get(), &slot, &worker_state, + std::ref(sharded_results), std::ref(sharded_rntis), + std::ref(nof_sharded_rntis), std::ref(dl_prb_rate), + std::ref(dl_prb_bits_rate), std::ref(ul_prb_rate), + std::ref(ul_prb_bits_rate)); + } } - - // if (worker_state.cpu_affinity) { - // for (uint32_t i = 0; i < worker_state.nof_threads; i ++) { - // cpu_set_t cpu_set_dci; - // CPU_ZERO(&cpu_set_dci); - // CPU_SET(worker_id * (3+worker_state.nof_threads) + i + 3, - // &cpu_set_dci); - // assert(pthread_setaffinity_np(dci_threads[i].native_handle(), - // sizeof(cpu_set_t), &cpu_set_dci) == 0); - // } - // } } if(sibs_thread.joinable()){ From c21e1faf0b72f3d72571f01866ae32c15dcaed0f Mon Sep 17 00:00:00 2001 From: WanHaoRan Date: Thu, 12 Sep 2024 16:52:28 -0400 Subject: [PATCH 10/15] update config.yaml --- nrscope/config/config.yaml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/nrscope/config/config.yaml b/nrscope/config/config.yaml index deb12f97..f2151975 100644 --- a/nrscope/config/config.yaml +++ b/nrscope/config/config.yaml @@ -1,11 +1,11 @@ nof_usrp_dev: 1 usrp_setting_0: - ssb_freq: 3630720000 # should be set to the ssb frequency of the cell - rf_args: "clock=external,type=x300,master_clock_rate=184320000,sampling_rate=23040000" #"type=x300" #"clock=external" for TwinRX + ssb_freq: 3660960000 # should be set to the ssb frequency of the cell + rf_args: "clock=external,type=x300,serial=32B0F2F,master_clock_rate=200000000,sampling_rate=50000000" #"type=x300" #"clock=external" for TwinRX # rf_args: "clock=external,type=x300,sampling_rate=23040000" #"type=x300" #"clock=external" for CBX rx_gain: 80 # for x310 CBX, max rx gain is 31.5, for b210, it's around 80, for x310 TwinRX, max rx gain is 90 - srate_hz: 23040000 #11520000 #11520000 #23040000 (CBX) - srsran_srate_hz: 23040000 + srate_hz: 50000000 #11520000 #11520000 #23040000 (CBX) + srsran_srate_hz: 46080000 nof_carriers: 1 nof_antennas: 1 scs_index: 1 #(0: 15kHz, 1: 30kHz, ..., the u in standard) @@ -14,7 +14,6 @@ usrp_setting_0: nof_bwps: 1 nof_workers: 4 cpu_affinity: true - log_name: "a.csv" #"/home/wanhr/Documents/data/nrscope/evaluation/coverage_amarisoft/dci_tx_50.csv" # x (0-10), y(0-8) coordinates google_dataset_id: "ngscope5g_dci_log_wanhr" From 2c0328cce35b4293ea3f5f574315e8428f93917e Mon Sep 17 00:00:00 2001 From: Xuyang Cao Date: Fri, 13 Sep 2024 23:06:55 -0400 Subject: [PATCH 11/15] small fix --- nrscope/src/libs/radio_nr.cc | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/nrscope/src/libs/radio_nr.cc b/nrscope/src/libs/radio_nr.cc index 0a8324ba..fb7a3f7a 100644 --- a/nrscope/src/libs/radio_nr.cc +++ b/nrscope/src/libs/radio_nr.cc @@ -335,7 +335,8 @@ int Radio::RadioInitandStart(){ rx_buffer = srsran_vec_cf_malloc(SRSRAN_NOF_SLOTS_PER_SF_NR(args_t.ssb_scs) * pre_resampling_slot_sz * RING_BUF_SIZE); std::cout << "slot_sz: " << slot_sz << std::endl; - srsran_vec_zero(rx_buffer, SRSRAN_NOF_SLOTS_PER_SF_NR(args_t.ssb_scs) * slot_sz); + srsran_vec_zero(rx_buffer, SRSRAN_NOF_SLOTS_PER_SF_NR(args_t.ssb_scs) * + pre_resampling_slot_sz * RING_BUF_SIZE * sizeof(cf_t)); /* the actual slot size after resampling */ uint32_t actual_slot_szs[RESAMPLE_WORKER_NUM]; @@ -344,7 +345,8 @@ int Radio::RadioInitandStart(){ SRSRAN_NOF_SLOTS_PER_SF_NR(args_t.ssb_scs) * pre_resampling_slot_sz); std::cout << "pre_resampling_slot_sz: " << pre_resampling_slot_sz << std::endl; srsran_vec_zero(pre_resampling_rx_buffer, - SRSRAN_NOF_SLOTS_PER_SF_NR(args_t.ssb_scs) * pre_resampling_slot_sz); + SRSRAN_NOF_SLOTS_PER_SF_NR(args_t.ssb_scs) * pre_resampling_slot_sz * + sizeof(cf_t)); cs_args.center_freq_hz = args_t.base_carrier.dl_center_frequency_hz; cs_args.ssb_freq_hz = args_t.base_carrier.dl_center_frequency_hz; @@ -367,8 +369,9 @@ int Radio::RadioInitandStart(){ // initialize resampling tool // resampling rate (output/input) - float r = (float)rf_args.srsran_srate_hz/(float)rf_args.srate_hz; - float As=60.0f; // resampling filter stop-band attenuation [dB] + float r = (float)rf_args.srsran_srate_hz/(float)rf_args.srate_hz; + // resampling filter stop-band attenuation [dB] + float As=60.0f; msresamp_crcf q[RESAMPLE_WORKER_NUM]; uint32_t temp_x_sz; uint32_t temp_y_sz; From a967169512b41e9badeafcb9d15124e71743cab0 Mon Sep 17 00:00:00 2001 From: Xuyang Cao Date: Sat, 14 Sep 2024 12:48:06 -0400 Subject: [PATCH 12/15] new scan --- nrscope/hdr/radio_nr.h | 2 + nrscope/src/libs/radio_nr.cc | 125 +++++++++++++++++++++++++++++------ nrscope/src/scan_main.cc | 17 +++-- 3 files changed, 116 insertions(+), 28 deletions(-) diff --git a/nrscope/hdr/radio_nr.h b/nrscope/hdr/radio_nr.h index 80eae4a3..5b7e2ba3 100644 --- a/nrscope/hdr/radio_nr.h +++ b/nrscope/hdr/radio_nr.h @@ -16,6 +16,8 @@ #include #define RESAMPLE_WORKER_NUM 8 +// For cell scan +#define CS_RESAMPLE_WORKER_NUM 8 class Radio{ public: diff --git a/nrscope/src/libs/radio_nr.cc b/nrscope/src/libs/radio_nr.cc index fb7a3f7a..b8d314c3 100644 --- a/nrscope/src/libs/radio_nr.cc +++ b/nrscope/src/libs/radio_nr.cc @@ -16,7 +16,7 @@ Radio::Radio() : radio = nullptr; nof_trials = 100; - nof_trials_scan = 200; + nof_trials_scan = 100; sf_round = 0; srsran_searcher_args_t.max_srate_hz = 92.16e6; srsran_searcher_args_t.ssb_min_scs = srsran_subcarrier_spacing_15kHz; @@ -81,17 +81,13 @@ static int copy_cpp_to_c_complex_arr(std::complex* src, int Radio::ScanInitandStart(){ - // Static rf parameters - rf_args.srate_hz = 11520000; - rf_args.rx_gain = 30; - rf_args.device_args = "type=x300"; - rf_args.nof_antennas = 1; - rf_args.nof_carriers = 1; - rf_args.log_level = "debug"; - rf_args.dl_freq = srsran_band_helper::get_freq_from_gscn(5279); + srsran_assert(raido_shared->init(rf_args, nullptr) == + SRSRAN_SUCCESS, "Failed Radio initialisation"); + radio = std::move(raido_shared); // Static cell searcher parameters args_t.srate_hz = rf_args.srate_hz; + rf_args.dl_freq = args_t.base_carrier.dl_center_frequency_hz; args_t.rf_device_name = rf_args.device_name; args_t.rf_device_args = rf_args.device_args; args_t.rf_log_level = "info"; @@ -114,13 +110,69 @@ int Radio::ScanInitandStart(){ uint32_t gscn_high; uint32_t gscn_step; - // initialize radio - srsran_assert(raido_shared->init(rf_args, nullptr) == SRSRAN_SUCCESS, "Failed Radio initialisation"); - radio = std::move(raido_shared); radio->set_rx_srate(rf_args.srate_hz); + + if (fabs(rf_args.srsran_srate_hz - rf_args.srate_hz) < 0.1) { + resample_needed = false; + } else { + resample_needed = true; + } + std::cout << "resample_needed: " << resample_needed << std::endl; + radio->set_rx_gain(rf_args.rx_gain); std::cout << "Initialized radio; start cell scanning" << std::endl; + pre_resampling_slot_sz = (uint32_t)(rf_args.srate_hz / 1000.0f / + SRSRAN_NOF_SLOTS_PER_SF_NR(ssb_scs)); + std::cout << "pre_resampling_slot_sz: " << pre_resampling_slot_sz + << std::endl; + slot_sz = (uint32_t)(rf_args.srsran_srate_hz / 1000.0f / + SRSRAN_NOF_SLOTS_PER_SF_NR(ssb_scs)); + std::cout << "slot_sz: " << slot_sz << std::endl; + // Allocate receive buffer + rx_buffer = srsran_vec_cf_malloc(SRSRAN_NOF_SLOTS_PER_SF_NR(args_t.ssb_scs) * + pre_resampling_slot_sz); + srsran_vec_zero(rx_buffer, SRSRAN_NOF_SLOTS_PER_SF_NR(args_t.ssb_scs) * + pre_resampling_slot_sz * sizeof(cf_t)); + /* the actual slot size after resampling */ + uint32_t actual_slot_szs[CS_RESAMPLE_WORKER_NUM]; + + // Allocate pre-resampling receive buffer + pre_resampling_rx_buffer = srsran_vec_cf_malloc( + SRSRAN_NOF_SLOTS_PER_SF_NR(args_t.ssb_scs) * pre_resampling_slot_sz); + srsran_vec_zero(pre_resampling_rx_buffer, + SRSRAN_NOF_SLOTS_PER_SF_NR(args_t.ssb_scs) * pre_resampling_slot_sz * + sizeof(cf_t)); + + // initialize resampling tool + // resampling rate (output/input) + float r = (float)rf_args.srsran_srate_hz/(float)rf_args.srate_hz; + // resampling filter stop-band attenuation [dB] + float As=60.0f; + msresamp_crcf q[CS_RESAMPLE_WORKER_NUM]; + uint32_t temp_x_sz; + uint32_t temp_y_sz; + std::complex * temp_x; + std::complex * temp_y[CS_RESAMPLE_WORKER_NUM]; + if (resample_needed) { + for (uint8_t i = 0; i < CS_RESAMPLE_WORKER_NUM; i++) { + q[i] = msresamp_crcf_create(r,As); + } + + float delay = resample_needed ? msresamp_crcf_get_delay(q[0]) : 0; + // add a few zero padding + temp_x_sz = SRSRAN_NOF_SLOTS_PER_SF_NR(args_t.ssb_scs) * + pre_resampling_slot_sz + (int)ceilf(delay) + 10; + temp_x = (std::complex *)malloc(temp_x_sz * + sizeof(std::complex)); + + temp_y_sz = (uint32_t)(temp_x_sz * r * 2); + for (uint8_t i = 0; i < CS_RESAMPLE_WORKER_NUM; i++) { + temp_y[i] = (std::complex *)malloc(temp_y_sz * + sizeof(std::complex)); + } + } + // Traverse GSCN per band for (const srsran_band_helper::nr_band_ss_raster& ss_raster : srsran_band_helper::nr_band_ss_raster_table) { std::cout << "Start scaning band " << ss_raster.band << " with scs idx " << ss_raster.scs << std::endl; @@ -146,13 +198,6 @@ int Radio::ScanInitandStart(){ args_t.base_carrier.ul_center_frequency_hz = args_t.base_carrier.dl_center_frequency_hz; } - // Allocate receive buffer - slot_sz = (uint32_t)(rf_args.srate_hz / 1000.0f / SRSRAN_NOF_SLOTS_PER_SF_NR(ssb_scs)); - rx_buffer = srsran_vec_cf_malloc(SRSRAN_NOF_SLOTS_PER_SF_NR(args_t.ssb_scs) * slot_sz); - std::cout << "slot_sz: " << slot_sz << std::endl; - std::cout << "rx_buffer size: " << SRSRAN_NOF_SLOTS_PER_SF_NR(args_t.ssb_scs) * slot_sz << std::endl; - srsran_vec_zero(rx_buffer, SRSRAN_NOF_SLOTS_PER_SF_NR(args_t.ssb_scs) * slot_sz); - cs_args.ssb_scs = args_t.ssb_scs; cs_args.ssb_pattern = args_t.ssb_pattern; cs_args.duplex_mode = args_t.duplex_mode; @@ -242,8 +287,8 @@ int Radio::ScanInitandStart(){ args_t.base_carrier.ssb_center_freq_hz = cs_args.ssb_freq_hz; srsran::rf_buffer_t rf_buffer = {}; - rf_buffer.set_nof_samples(slot_sz); - rf_buffer.set(0, rx_buffer); + rf_buffer.set_nof_samples(pre_resampling_slot_sz); + rf_buffer.set(0, pre_resampling_rx_buffer); for(uint32_t trial=0; trial < nof_trials_scan; trial++){ if (trial == 0) { @@ -255,6 +300,35 @@ int Radio::ScanInitandStart(){ if (not radio->rx_now(rf_buffer, rf_timestamp)) { return SRSRAN_ERROR; } + + if (resample_needed) { + copy_c_to_cpp_complex_arr_and_zero_padding(pre_resampling_rx_buffer, + temp_x, pre_resampling_slot_sz, temp_x_sz); + uint32_t splitted_nx = pre_resampling_slot_sz / CS_RESAMPLE_WORKER_NUM; + std::vector ssb_scan_resample_threads; + for (uint8_t k = 0; k < CS_RESAMPLE_WORKER_NUM; k++) { + ssb_scan_resample_threads.emplace_back(&resample_partially, &q[k], + temp_x, temp_y[k], k, splitted_nx, &actual_slot_szs[k]); + } + for (uint8_t k = 0; k < CS_RESAMPLE_WORKER_NUM; k++){ + if(ssb_scan_resample_threads[k].joinable()){ + ssb_scan_resample_threads[k].join(); + } + } + // sequentially merge back + cf_t * buf_split_ptr = rx_buffer; + for (uint8_t k = 0; k < CS_RESAMPLE_WORKER_NUM; k++){ + copy_cpp_to_c_complex_arr(temp_y[k], buf_split_ptr, + actual_slot_szs[k]); + buf_split_ptr += actual_slot_szs[k]; + } + } else { + // pre_resampling_slot_sz should be the same as slot_sz as + // resample ratio is 1 in this case + srsran_vec_cf_copy(rx_buffer, pre_resampling_rx_buffer, + pre_resampling_slot_sz); + } + *(last_rx_time.get_ptr(0)) = rf_timestamp.get(0); cs_ret = srsran_searcher.run_slot(rx_buffer, slot_sz); @@ -276,8 +350,15 @@ int Radio::ScanInitandStart(){ } } } + } - free(rx_buffer); + free(rx_buffer); + if (resample_needed) { + for (uint8_t k = 0; k < CS_RESAMPLE_WORKER_NUM; k++) { + msresamp_crcf_destroy(q[k]); + free(temp_y[k]); + } + free(temp_x); } NRScopeLog::exit_logger(); diff --git a/nrscope/src/scan_main.cc b/nrscope/src/scan_main.cc index 71babf98..250656df 100644 --- a/nrscope/src/scan_main.cc +++ b/nrscope/src/scan_main.cc @@ -14,15 +14,23 @@ int main(int argc, char** argv){ // Initialise logging infrastructure srslog::init(); - std::vector radios(1); + std::string file_name = "config.yaml"; + + int nof_usrp = get_nof_usrp(file_name); + std::vector radios(nof_usrp); + + if(load_config(radios, file_name) == NR_FAILURE){ + std::cout << "Load config fail." << std::endl; + return NR_FAILURE; + } radios[0].log_name = "scan.csv"; radios[0].local_log = true; - radios[0].nof_threads = 4; // All the radios have the same setting for local log or push to google if(radios[0].local_log){ std::vector log_names(1); + // Scan only needs one radio for now for(int i = 0; i < 1; i++){ log_names[i] = radios[i].log_name; } @@ -30,10 +38,7 @@ int main(int argc, char** argv){ } std::vector radio_threads; - - for (auto& my_radio : radios) { - radio_threads.emplace_back(&Radio::ScanThread, &my_radio); - } + radio_threads.emplace_back(&Radio::ScanThread, &radios[0]); for (auto& t : radio_threads) { if(t.joinable()){ From c813755822da1ffb4a6e6f5e675b5d921259d6e4 Mon Sep 17 00:00:00 2001 From: Haoran Wan Date: Sat, 14 Sep 2024 15:25:04 -0400 Subject: [PATCH 13/15] update config.yaml description, readme and wiki --- README.md | 2 +- nrscope/config/config.yaml | 24 ++++++++++++------------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index b925665e..3be4000f 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ sudo ldconfig # to double check, libs should appear at /usr/local/lib and header liquid.h should appear at /usr/local/include/liquid/ ``` -For different USRP daughterboard, different `config.yaml` should be used. +For different USRP daughterboard, different `config.yaml` should be used. Please refer to the sample `config.yaml` in `./nrscope/config/config.yaml` and the explanatory comment in it. CBX: ``` diff --git a/nrscope/config/config.yaml b/nrscope/config/config.yaml index f2151975..cb54e0ed 100644 --- a/nrscope/config/config.yaml +++ b/nrscope/config/config.yaml @@ -1,21 +1,21 @@ nof_usrp_dev: 1 usrp_setting_0: - ssb_freq: 3660960000 # should be set to the ssb frequency of the cell - rf_args: "clock=external,type=x300,serial=32B0F2F,master_clock_rate=200000000,sampling_rate=50000000" #"type=x300" #"clock=external" for TwinRX - # rf_args: "clock=external,type=x300,sampling_rate=23040000" #"type=x300" #"clock=external" for CBX + ssb_freq: 3660960000 # Set to the ssb frequency of the cell, could be obtained with the cell scan function + rf_args: "clock=external,type=x300,serial=32B0F2F,master_clock_rate=200000000,sampling_rate=50000000" # For TwinRX daughterboard + # rf_args: "clock=external,type=x300,sampling_rate=23040000" #"type=x300" #"clock=external" # For CBX daughterboard rx_gain: 80 # for x310 CBX, max rx gain is 31.5, for b210, it's around 80, for x310 TwinRX, max rx gain is 90 - srate_hz: 50000000 #11520000 #11520000 #23040000 (CBX) - srsran_srate_hz: 46080000 - nof_carriers: 1 - nof_antennas: 1 + srate_hz: 50000000 # the sampling rate of USRP, integer division of 200MHz for TwinRX, and 5G sampling rate for CBX: 11520000 or 23040000 + srsran_srate_hz: 46080000 # the sampling for real signal processing, should be in 5G sampling rate, multiple of 1.92 MHz. + nof_carriers: 1 # srsRAN rf setting, always set to be 1 for now. + nof_antennas: 1 # srsRAN rf setting, always set to be 1 for now. scs_index: 1 #(0: 15kHz, 1: 30kHz, ..., the u in standard) rf_log_level: "debug" - nof_rnti_worker_groups: 1 - nof_bwps: 1 - nof_workers: 4 - cpu_affinity: true + nof_rnti_worker_groups: 1 # number of of threads for DCI decoding, each will divide the UEs into small groups + nof_bwps: 1 # number of BWP of the cell + nof_workers: 4 # using worker pool to asynchronously process the slot data + cpu_affinity: true # pin the worker's thread into CPU or not. - log_name: "a.csv" #"/home/wanhr/Documents/data/nrscope/evaluation/coverage_amarisoft/dci_tx_50.csv" # x (0-10), y(0-8) coordinates + log_name: "a.csv" google_dataset_id: "ngscope5g_dci_log_wanhr" # usrp_setting_1: From 1a58c599922a06f10d790ebdd43b8e9e40f892da Mon Sep 17 00:00:00 2001 From: Haoran Wan Date: Sat, 14 Sep 2024 15:30:51 -0400 Subject: [PATCH 14/15] add pointer to wiki page in readme --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3be4000f..41aa99ec 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ Implement on top of srsRAN_4G UE code, decode the DCI and SIB information for 5G ## Requirements -We tested this system on Ubuntu 22.04 system and it may support other version of Ubuntu. To build this project and make it run properly, the following libraries are needed. +We tested this system on Ubuntu 22.04 system and it may support other version of Ubuntu. To build this project and make it run properly, the following libraries are needed. Please refer to the [wiki page](https://github.com/PrincetonUniversity/NG-Scope-5G/wiki) for feature description and detailed build instruction. [UHD libraries](https://files.ettus.com/manual/page_install.html): @@ -52,6 +52,8 @@ sudo ldconfig ``` For different USRP daughterboard, different `config.yaml` should be used. Please refer to the sample `config.yaml` in `./nrscope/config/config.yaml` and the explanatory comment in it. + + CBX: ``` From dbcbee878eab4e25cd1c0bf3d5e92f252ea6cd68 Mon Sep 17 00:00:00 2001 From: Xuyang Cao Date: Sat, 14 Sep 2024 16:36:16 -0400 Subject: [PATCH 15/15] fix and tuning --- nrscope/hdr/radio_nr.h | 2 +- nrscope/src/libs/radio_nr.cc | 86 ++++++++++++++++++++++-------------- 2 files changed, 55 insertions(+), 33 deletions(-) diff --git a/nrscope/hdr/radio_nr.h b/nrscope/hdr/radio_nr.h index 5b7e2ba3..42b6927f 100644 --- a/nrscope/hdr/radio_nr.h +++ b/nrscope/hdr/radio_nr.h @@ -17,7 +17,7 @@ #define RESAMPLE_WORKER_NUM 8 // For cell scan -#define CS_RESAMPLE_WORKER_NUM 8 +#define CS_RESAMPLE_WORKER_NUM 4 class Radio{ public: diff --git a/nrscope/src/libs/radio_nr.cc b/nrscope/src/libs/radio_nr.cc index b8d314c3..56720082 100644 --- a/nrscope/src/libs/radio_nr.cc +++ b/nrscope/src/libs/radio_nr.cc @@ -16,7 +16,7 @@ Radio::Radio() : radio = nullptr; nof_trials = 100; - nof_trials_scan = 100; + nof_trials_scan = 500; sf_round = 0; srsran_searcher_args_t.max_srate_hz = 92.16e6; srsran_searcher_args_t.ssb_min_scs = srsran_subcarrier_spacing_15kHz; @@ -86,7 +86,7 @@ int Radio::ScanInitandStart(){ radio = std::move(raido_shared); // Static cell searcher parameters - args_t.srate_hz = rf_args.srate_hz; + args_t.srate_hz = rf_args.srsran_srate_hz; rf_args.dl_freq = args_t.base_carrier.dl_center_frequency_hz; args_t.rf_device_name = rf_args.device_name; args_t.rf_device_args = rf_args.device_args; @@ -101,8 +101,8 @@ int Radio::ScanInitandStart(){ double ssb_center_freq_min_hz; double ssb_center_freq_max_hz; - // Store the double args_t.base_carrier.dl_center_frequency_hz and cs_args.center_freq_hz in a mirror int version - // for precise diff calculation + /* Store the double args_t.base_carrier.dl_center_frequency_hz and + cs_args.center_freq_hz in a mirror int version for precise diff calculation*/ long long dl_center_frequency_hz_int_ver; long long cs_args_ssb_freq_hz_int_ver; @@ -130,9 +130,9 @@ int Radio::ScanInitandStart(){ SRSRAN_NOF_SLOTS_PER_SF_NR(ssb_scs)); std::cout << "slot_sz: " << slot_sz << std::endl; // Allocate receive buffer - rx_buffer = srsran_vec_cf_malloc(SRSRAN_NOF_SLOTS_PER_SF_NR(args_t.ssb_scs) * + rx_buffer = srsran_vec_cf_malloc(SRSRAN_NOF_SLOTS_PER_SF_NR(args_t.ssb_scs) * pre_resampling_slot_sz); - srsran_vec_zero(rx_buffer, SRSRAN_NOF_SLOTS_PER_SF_NR(args_t.ssb_scs) * + srsran_vec_zero(rx_buffer, SRSRAN_NOF_SLOTS_PER_SF_NR(args_t.ssb_scs) * pre_resampling_slot_sz * sizeof(cf_t)); /* the actual slot size after resampling */ uint32_t actual_slot_szs[CS_RESAMPLE_WORKER_NUM]; @@ -174,12 +174,16 @@ int Radio::ScanInitandStart(){ } // Traverse GSCN per band - for (const srsran_band_helper::nr_band_ss_raster& ss_raster : srsran_band_helper::nr_band_ss_raster_table) { - std::cout << "Start scaning band " << ss_raster.band << " with scs idx " << ss_raster.scs << std::endl; - std::cout << "gscn " << ss_raster.gscn_first << " to gscn " << ss_raster.gscn_last << std::endl; + for (const srsran_band_helper::nr_band_ss_raster& ss_raster : + srsran_band_helper::nr_band_ss_raster_table) { + std::cout << "Start scaning band " << ss_raster.band + << " with scs idx " << ss_raster.scs << std::endl; + std::cout << "gscn " << ss_raster.gscn_first << " to gscn " + << ss_raster.gscn_last << std::endl; // adjust the RF's central meas freq to the first GSCN point of the band - cs_args_ssb_freq_hz_int_ver = (long long)srsran_band_helper::get_freq_from_gscn(ss_raster.gscn_first); + cs_args_ssb_freq_hz_int_ver = + (long long)srsran_band_helper::get_freq_from_gscn(ss_raster.gscn_first); dl_center_frequency_hz_int_ver = cs_args_ssb_freq_hz_int_ver; rf_args.dl_freq = cs_args_ssb_freq_hz_int_ver; args_t.base_carrier.dl_center_frequency_hz = rf_args.dl_freq; @@ -195,7 +199,8 @@ int Radio::ScanInitandStart(){ args_t.set_ssb_from_band(ssb_scs); args_t.base_carrier.scs = args_t.ssb_scs; if(args_t.duplex_mode == SRSRAN_DUPLEX_MODE_TDD){ - args_t.base_carrier.ul_center_frequency_hz = args_t.base_carrier.dl_center_frequency_hz; + args_t.base_carrier.ul_center_frequency_hz = + args_t.base_carrier.dl_center_frequency_hz; } cs_args.ssb_scs = args_t.ssb_scs; @@ -204,12 +209,17 @@ int Radio::ScanInitandStart(){ uint32_t ssb_scs_hz = SRSRAN_SUBC_SPACING_NR(cs_args.ssb_scs); // calculate the bandpass - std::cout << "Update RF's meas central freq to " << cs_args.ssb_freq_hz << std::endl; - ssb_bw_hz = SRSRAN_SSB_BW_SUBC * SRSRAN_SUBC_SPACING_NR(cs_args.ssb_scs); // here might be a logic error - ssb_center_freq_min_hz = args_t.base_carrier.dl_center_frequency_hz - (args_t.srate_hz * 0.7 - ssb_bw_hz) / 2.0; - ssb_center_freq_max_hz = args_t.base_carrier.dl_center_frequency_hz + (args_t.srate_hz * 0.7 - ssb_bw_hz) / 2.0; - std::cout << "Update min ssb center detect boundary to " << ssb_center_freq_min_hz << std::endl; - std::cout << "Update max ssb center detect boundary to " << ssb_center_freq_max_hz << std::endl; + std::cout << "Update RF's meas central freq to " + << cs_args.ssb_freq_hz << std::endl; + ssb_bw_hz = SRSRAN_SSB_BW_SUBC * SRSRAN_SUBC_SPACING_NR(cs_args.ssb_scs); + ssb_center_freq_min_hz = args_t.base_carrier.dl_center_frequency_hz - + (args_t.srate_hz * 0.7 - ssb_bw_hz) / 2.0; + ssb_center_freq_max_hz = args_t.base_carrier.dl_center_frequency_hz + + (args_t.srate_hz * 0.7 - ssb_bw_hz) / 2.0; + std::cout << "Update min ssb center detect boundary to " + << ssb_center_freq_min_hz << std::endl; + std::cout << "Update max ssb center detect boundary to " + << ssb_center_freq_max_hz << std::endl; // Set RF radio->release_freq(0); @@ -223,7 +233,8 @@ int Radio::ScanInitandStart(){ std::cout << "Start scaning GSCN number " << gscn << std::endl; // Get SSB center frequency for this GSCN point - cs_args_ssb_freq_hz_int_ver = (long long)srsran_band_helper::get_freq_from_gscn(gscn); + cs_args_ssb_freq_hz_int_ver = + (long long)srsran_band_helper::get_freq_from_gscn(gscn); cs_args.ssb_freq_hz = cs_args_ssb_freq_hz_int_ver; std::cout << "Absolute freq " << cs_args.ssb_freq_hz << std::endl; @@ -235,11 +246,14 @@ int Radio::ScanInitandStart(){ bool offset_not_scs_aligned = false; bool not_in_bandpass_range = false; - // Calculate frequency offset between the base-band center frequency and the SSB absolute frequency - long long offset_hz = std::abs(cs_args_ssb_freq_hz_int_ver - dl_center_frequency_hz_int_ver); + /* Calculate frequency offset between the base-band center frequency + and the SSB absolute frequency */ + long long offset_hz = std::abs(cs_args_ssb_freq_hz_int_ver - + dl_center_frequency_hz_int_ver); if (offset_hz % ssb_scs_hz != 0) { - std::cout << "the offset " << offset_hz << " is NOT multiple of the subcarrier spacing " << ssb_scs_hz << std::endl; + std::cout << "the offset " << offset_hz << + " is NOT multiple of the subcarrier spacing " << ssb_scs_hz << std::endl; offset_not_scs_aligned = true; } @@ -251,12 +265,17 @@ int Radio::ScanInitandStart(){ if (offset_not_scs_aligned || not_in_bandpass_range) { // update and measure - std::cout << "Update RF's meas central freq to " << cs_args.ssb_freq_hz << std::endl; + std::cout << "Update RF's meas central freq to " + << cs_args.ssb_freq_hz << std::endl; ssb_bw_hz = SRSRAN_SSB_BW_SUBC * SRSRAN_SUBC_SPACING_NR(cs_args.ssb_scs); - ssb_center_freq_min_hz = args_t.base_carrier.dl_center_frequency_hz - (args_t.srate_hz * 0.7 - ssb_bw_hz) / 2.0; - ssb_center_freq_max_hz = args_t.base_carrier.dl_center_frequency_hz + (args_t.srate_hz * 0.7 - ssb_bw_hz) / 2.0; - std::cout << "Update min ssb center detect boundary to " << ssb_center_freq_min_hz << std::endl; - std::cout << "Update max ssb center detect boundary to " << ssb_center_freq_max_hz << std::endl; + ssb_center_freq_min_hz = args_t.base_carrier.dl_center_frequency_hz - + (args_t.srate_hz * 0.7 - ssb_bw_hz) / 2.0; + ssb_center_freq_max_hz = args_t.base_carrier.dl_center_frequency_hz + + (args_t.srate_hz * 0.7 - ssb_bw_hz) / 2.0; + std::cout << "Update min ssb center detect boundary to " << + ssb_center_freq_min_hz << std::endl; + std::cout << "Update max ssb center detect boundary to " << + ssb_center_freq_max_hz << std::endl; rf_args.dl_freq = cs_args.ssb_freq_hz; args_t.base_carrier.dl_center_frequency_hz = rf_args.dl_freq; @@ -267,10 +286,10 @@ int Radio::ScanInitandStart(){ } srsran_searcher_cfg_t.srate_hz = args_t.srate_hz; - // Currently looks like there is some coarse correlation issue - // that the next several GSCN can possibly detect the same ssb - // Just need to add some "deduplicate" logic when using the scanned cell info - // TO-DO: maybe fix this at a later point + /* Currently looks like there is some coarse correlation issue + that the next several GSCN can possibly detect the same ssb + Just need to add some "deduplicate" logic when using the scanned cell info + TO-DO: maybe fix this at a later point */ srsran_searcher_cfg_t.center_freq_hz = cs_args.ssb_freq_hz; srsran_searcher_cfg_t.ssb_freq_hz = cs_args.ssb_freq_hz; srsran_searcher_cfg_t.ssb_scs = args_t.ssb_scs; @@ -292,7 +311,8 @@ int Radio::ScanInitandStart(){ for(uint32_t trial=0; trial < nof_trials_scan; trial++){ if (trial == 0) { - srsran_vec_cf_zero(rx_buffer, slot_sz); + srsran_vec_cf_zero(rx_buffer, pre_resampling_slot_sz); + srsran_vec_cf_zero(pre_resampling_rx_buffer, pre_resampling_slot_sz); } srsran::rf_timestamp_t& rf_timestamp = last_rx_time; @@ -347,6 +367,7 @@ int Radio::ScanInitandStart(){ scan_log_node.freq = cs_args.ssb_freq_hz; scan_log_node.pci = cs_ret.ssb_res.N_id; NRScopeLog::push_node(scan_log_node, rf_index); + printf("scan log triggered here\n"); } } } @@ -361,7 +382,8 @@ int Radio::ScanInitandStart(){ free(temp_x); } - NRScopeLog::exit_logger(); + // Not exit explicitly as early termination might miss last found recording + // NRScopeLog::exit_logger(); return SRSRAN_SUCCESS; }