18 #include "../../lib/phy/synchronization/synchronization.h" 19 #include "../../lib/phy/libphy/libphy.h" 20 #include "../../lib/variables/common_variables/common_variables.h" 21 #include "../../lib/utils/sequence_generator/sequence_generator.h" 22 #include "../../lib/phy/transport_channel/transport_channel.h" 27 #include <boost/log/core.hpp> 28 #include <boost/log/trivial.hpp> 29 #include <boost/log/expressions.hpp> 30 #include <boost/log/utility/setup/file.hpp> 31 #include <boost/log/utility/setup/common_attributes.hpp> 32 #include "../../lib/asn1c/nr_rrc/BCCH-DL-SCH-Message.h" 33 #include "../../lib/variables/common_structures/common_structures.h" 34 #include "../../lib/phy/physical_channel/physical_channel.h" 35 #include "../../lib/utils/common_utils/common_utils.h" 36 #include "../../lib/asn1c/nr_rrc/BCCH-DL-SCH-Message.h" 37 #include "../../lib/asn1c/nr_rrc/FrequencyInfoUL-SIB.h" 50 this->rf_device = rf_dev;
51 this->ssb_period = ssb_period;
52 this->fft_size = fft_size;
54 this->band_object = band_obj;
55 l_max = band_obj.
l_max;
56 this->is_extended_cp = 0;
71 BOOST_LOG_TRIVIAL(trace) <<
"PSS synchronization";
73 int n_id_2,synchronisation_index;
77 size_t num_samples = 2 * ssb_period * rf_device->getSampleRate();
80 vector<complex<float>> buff_2_ssb_periods(num_samples);
82 buff.resize(num_samples / 2);
84 complex<float> j(0, 1);
86 time_first_pss = chrono::high_resolution_clock::now();
88 double time_first_sample;
89 rf_device->get_samples(&buff_2_ssb_periods, time_first_sample);
90 }
catch (
const exception& e) {
94 int cp_lengths_pbch[num_symbols_per_subframe_pbch];
95 int cum_sum_pbch[num_symbols_per_subframe_pbch];
101 common_cp_length = cp_lengths_pbch[1];
105 for (
int i = 0; i < num_samples / 2; i ++){
106 buff[i] = buff_2_ssb_periods[i];
113 BOOST_LOG_TRIVIAL(trace) <<
"Peak value: "+ to_string(peak_value/common_cp_length);
117 int symbol_duration = fft_size + common_cp_length;
118 int pss_start_index = synchronisation_index - symbol_duration + 1;
119 int sss_init_index = pss_start_index + 2 * symbol_duration + common_cp_length;
123 if (pss_start_index < 0){
127 index_first_pss = pss_start_index;
129 vector<complex<float>> sss_signal(fft_size);
133 for (
int i = 0; i < fft_size; i++){
134 sss_signal[i] = buff[i + sss_init_index];
139 for (
int i = 0; i < 4 * symbol_duration; i ++){
140 received_power += pow(abs(buff[pss_start_index + i]),2);
142 received_power /= 4 * symbol_duration;
143 received_power = 10 * log10(received_power);
145 float peak_value_sss;
150 BOOST_LOG_TRIVIAL(trace) <<
"SSS synchronization";
152 BOOST_LOG_TRIVIAL(trace) <<
"Peak value: "+ to_string(peak_value_sss);
153 pci = 3 * n_id_1 + n_id_2;
154 BOOST_LOG_TRIVIAL(trace) <<
"PCI : "+ to_string(pci);
160 vector<complex<float>> second_pss(fft_size + common_cp_length), second_sss(fft_size);
161 int second_pss_index = pss_start_index + num_samples / 2;
162 int n_id_1_2, n_id_2_2, sync_index_pss_2;
163 float peak_value_pss_2;
164 for (
int i = 0; i < fft_size + common_cp_length; i++){
165 second_pss[i] = buff_2_ssb_periods[i + second_pss_index];
175 for (
int i = 0; i < fft_size; i++){
176 second_sss[i] = buff_2_ssb_periods[i + second_pss_index + 2 * symbol_duration + common_cp_length];
181 if (3 * n_id_1_2 + n_id_2_2 == pci){
207 BOOST_LOG_TRIVIAL(trace) <<
"Extracting PBCH";
209 size_t num_samples = max(0.03, ssb_period) * rf_device->getSampleRate();
212 buff.resize(num_samples);
215 auto now = chrono::high_resolution_clock::now();
217 double second_frame_time;
218 rf_device->get_samples(&buff, second_frame_time);
219 }
catch (
const exception& e) {
227 auto time_window = chrono::duration_cast<chrono::microseconds>(now - time_first_pss);
228 int offset_to_ssb_period = (int)(time_window.count() - index_first_pss / (128*scs *1e-6)) % ((int) (ssb_period * 1e6));
229 int index_second_pss = (ssb_period * 1e6 - offset_to_ssb_period) * rf_device->getSampleRate() * 1e-6;
232 data.open(
"data.txt");
233 for (
int i = 0; i < num_samples; i ++){
243 int cp_lengths_pbch[num_symbols_per_subframe_pbch];
244 int cum_sum_pbch[num_symbols_per_subframe_pbch];
247 common_cp_length = cp_lengths_pbch[1];
248 int symbol_duration = fft_size + common_cp_length;
250 vector<complex<float>> pss_signal(48 * symbol_duration);
255 int begin_offset = 0;
257 if (pss_signal.size()/2 <= index_second_pss && pss_signal.size()/2 <= num_samples - index_second_pss){
258 begin_offset = pss_signal.size()/2;
259 end_offset = pss_signal.size()/2;
260 }
else if (pss_signal.size()/2 > index_second_pss){
261 begin_offset = index_second_pss;
262 end_offset = pss_signal.size() - index_second_pss;
263 }
else if (pss_signal.size()/2 > num_samples - index_second_pss) {
264 end_offset = num_samples - index_second_pss;
265 begin_offset = pss_signal.size() - (num_samples - index_second_pss);
270 for (
int i = -begin_offset; i < end_offset; i ++){
271 pss_signal[count] = buff[(int) index_second_pss + i];
275 int synchronisation_index;
282 BOOST_LOG_TRIVIAL(trace) <<
"PSS synchronization downsampling factor: " << downsampling_factor;
283 int symbol_duration_downsampled = symbol_duration / downsampling_factor;
285 vector<complex<float>> pss_signal_downsampled(48 * symbol_duration_downsampled);
286 for (
int i = 0; i < 48 * symbol_duration_downsampled; i ++){
287 pss_signal_downsampled[i] = pss_signal[(size_t) downsampling_factor * i];
292 int pss_start_index = downsampling_factor * (synchronisation_index - symbol_duration_downsampled + 1);
297 vector<complex<float>> fine_pss_signal(symbol_duration + (2 * downsampling_factor + 1));
299 for (
int i = pss_start_index - downsampling_factor; i < pss_start_index + symbol_duration + (downsampling_factor + 1); i ++){
300 fine_pss_signal[count] = pss_signal[i];
305 pss_start_index = pss_start_index + (synchronisation_index - symbol_duration + 1 - downsampling_factor);
306 int buffer_pss_index = pss_start_index + index_second_pss - begin_offset;
307 index_first_pss = buffer_pss_index;
308 int sss_init_index = buffer_pss_index + 2 * symbol_duration + common_cp_length;
310 vector<complex<float>> sss_signal(fft_size);
314 for (
int i = 0; i < fft_size; i++){
315 sss_signal[i] = buff[i + sss_init_index];
318 float peak_value_sss;
323 if (pci == 3 * n_id_1 + n_id_2){
324 BOOST_LOG_TRIVIAL(trace) <<
"PCI confirmed";
325 cell_confirmed =
true;
327 BOOST_LOG_TRIVIAL(trace) <<
"PCI not confirmed";
328 cell_confirmed =
false;
336 vector<complex<float>> ssb_signal(4 * symbol_duration);
340 ssb_signal[i] = buff[i + buffer_pss_index];
359 vector<complex<float>> temp_mod_symbols, temp_mod_symbols2,temp_mod_symbols_dmrs;
380 cum_sum_fft[symbol] = symbol * symbol_duration;
392 complex<float>* output_channels[] = {pbch_symbols, dmrs_symbols, sss_symbols};
418 if (snr[i] > max_snr){
426 final_pbch_modulation_symbols[i] = (pbch_symbols[i]) * conj(coefficients[i_b_ssb][channel_indexes[0][0][i]][channel_indexes[0][1][i]]) / (float) pow(abs(coefficients[i_b_ssb][channel_indexes[0][0][i]][channel_indexes[0][1][i]]),2);
431 ss_pwr.ss_rsrp +=pow(abs(sss_symbols[i]),2);
434 ss_pwr.ss_rsrp +=pow(abs(dmrs_symbols[i]),2);
439 for (
int symb = 0 ; symb < free5GRAN::NUM_SYMBOLS_SSB - 1; symb++){
441 ss_pwr.ss_rssi += pow(abs(ssb_symbols[symb][sc]),2);
446 ss_pwr.ss_rssi /= n_rb;
447 ss_pwr.ss_rsrq = 10 * log(n_rb * ss_pwr.ss_rsrp / ss_pwr.ss_rssi);
449 ss_pwr.ss_rsrp = 10 * log10(ss_pwr.ss_rsrp) + 30;
450 ss_pwr.ss_rssi = 10 * log10(ss_pwr.ss_rssi) + 30;
451 ss_pwr.ss_sinr = max_snr;
453 this->i_b_ssb = i_b_ssb;
455 this-> i_ssb = i_b_ssb % 4;
457 this-> i_ssb = i_b_ssb;
464 int bch_bits[free5GRAN::SIZE_SSB_PBCH_SYMBOLS * 2];
482 cout <<
"###### RADIO" << endl;
483 cout <<
"# SS-RSRP: " + to_string(ss_pwr.ss_rsrp) +
" dbm" << endl;
484 cout <<
"# SS-RSSI: " + to_string(ss_pwr.ss_rssi) +
" dbm" << endl;
485 cout <<
"# SS-RSRQ: " + to_string(ss_pwr.ss_rsrq) +
" db" << endl;
486 cout <<
"# SS-SNR: " + to_string(ss_pwr.ss_sinr) +
" db" << endl;
487 cout <<
"# Frequency offset: " + to_string(freq_offset) +
" Hz" << endl;
489 cout <<
"###### CELL" << endl;
490 cout <<
"## PCI: " + to_string(pci) + ((cell_confirmed) ?
" (confirmed)" :
" (not confirmed)") << endl;
492 cout << ((is_extended_cp == 0 ) ?
"Normal" :
"Extended") << endl;
493 cout <<
"## I_B_SSB: " + to_string(i_b_ssb) << endl;
494 cout <<
"## I_SSB: " + to_string(i_ssb) << endl;
496 cout <<
"###### MIB" << endl;
497 cout <<
"## Frame number: " + to_string(mib_object.sfn) << endl;
498 cout <<
"## PDCCH configuration: " + to_string(mib_object.pdcch_config) << endl;
499 cout <<
"## Subcarrier spacing common: " + to_string(mib_object.scs) << endl;
500 cout <<
"## Cell barred: " + to_string(mib_object.cell_barred) << endl;
501 cout <<
"## DMRS type A position : " + to_string(mib_object.dmrs_type_a_position) << endl;
502 cout <<
"## k SSB: " + to_string(mib_object.k_ssb) << endl;
503 cout <<
"## Intra freq reselection: " + to_string(mib_object.intra_freq_reselection) << endl;
505 cout << ((crc_validated) ?
"validated" :
"not validated") << endl;
507 cout <<
"#######################################################################" << endl;
512 this->fft_size = fft_size;
541 if(mib_object.k_ssb > 23){
545 mu = log2(mib_object.scs/15);
546 int symbol_in_frame = band_object.ssb_symbols[this->i_ssb];
547 frame_size = 0.01 * rf_device->getSampleRate();
548 num_slots_per_frame = 10 * mib_object.scs/15;
555 int cp_lengths_pbch[num_symbols_per_subframe_pbch];
556 int cum_sum_pbch[num_symbols_per_subframe_pbch];
561 int num_samples_after_pss = frame_size - num_samples_before_pss;
566 fft_size = (int) (rf_device->getSampleRate() / (1e3 * mib_object.scs));
568 BOOST_LOG_TRIVIAL(trace) <<
"###### PDCCH Search & decode";
569 BOOST_LOG_TRIVIAL(trace) <<
"## INDEX_1: " + to_string(mib_object.pdcch_config/16);
570 BOOST_LOG_TRIVIAL(trace) <<
"## INDEX_2: " + to_string(mib_object.pdcch_config%16);
571 BOOST_LOG_TRIVIAL(trace) <<
"## SYMBOL IN FRAME: " + to_string(symbol_in_frame);
572 BOOST_LOG_TRIVIAL(trace) <<
"## FRAME SIZE: " + to_string(frame_size);
573 BOOST_LOG_TRIVIAL(trace) <<
"## INDEX PSS: " + to_string(index_first_pss);
574 BOOST_LOG_TRIVIAL(trace) <<
"## SLOTS PER FRAME: " + to_string(num_slots_per_frame);
575 BOOST_LOG_TRIVIAL(trace) <<
"## SAMPLES AFTER PSS: " + to_string(num_samples_after_pss);
576 BOOST_LOG_TRIVIAL(trace) <<
"## BUFFER SIZE: " + to_string(buff.size());
577 BOOST_LOG_TRIVIAL(trace) <<
"## FFT SIZE: " + to_string(fft_size);
584 vector<vector<int>> frame_indexes(2, vector<int>(2));
585 int frame_numbers[2];
588 BOOST_LOG_TRIVIAL(trace) <<
"## FRAME 1 FROM: " + to_string(1e3 * frame_indexes[0][0]/rf_device->getSampleRate()) +
" TO: " + to_string(1e3 * frame_indexes[0][1]/rf_device->getSampleRate()) +
" ms";
589 BOOST_LOG_TRIVIAL(trace) <<
"## FRAME 2 FROM: " + to_string(1e3 * frame_indexes[1][0]/rf_device->getSampleRate()) +
" TO: " + to_string(1e3 * frame_indexes[1][1]/rf_device->getSampleRate()) +
" ms";
595 pdcch_ss_mon_occ.n0 = (int)(pdcch_ss_mon_occ.O * pow(2, mu) + floor(i_ssb * pdcch_ss_mon_occ.M)) % num_slots_per_frame;
596 pdcch_ss_mon_occ.sfn_parity = (int)((pdcch_ss_mon_occ.O * pow(2, mu) + floor(i_ssb * pdcch_ss_mon_occ.M)) / num_slots_per_frame) % 2;
598 BOOST_LOG_TRIVIAL(trace) <<
"## n0: " + to_string(pdcch_ss_mon_occ.n0) ;
599 BOOST_LOG_TRIVIAL(trace) <<
"## ODD/EVEN ?: " + to_string(pdcch_ss_mon_occ.sfn_parity);
605 if (frame_numbers[0] % 2 == pdcch_ss_mon_occ.sfn_parity){
611 BOOST_LOG_TRIVIAL(trace) <<
"## FRAME: " + to_string(frame);
616 complex<float> rms = 0;
617 frame_data.resize(frame_size);
618 for (
int i = 0; i < frame_size; i ++){
619 frame_data[i] = buff[i + frame_indexes[frame][0]];
620 rms += abs(pow(frame_data[i],2));
622 rms = sqrt(rms/complex<float>(frame_size,0));
623 for (
int i = 0; i < frame_size; i ++){
624 frame_data[i] = frame_data[i] / rms;
630 float freq_diff = 12 * 1e3 * mib_object.scs * (pdcch_ss_mon_occ.n_rb_coreset / 2 - (10 * ((float) scs / (1e3*mib_object.scs)) + pdcch_ss_mon_occ.offset));
631 float freq_diff2 = - 15e3 * mib_object.k_ssb;
634 BOOST_LOG_TRIVIAL(trace) <<
"## FREQ DIFF 1: " + to_string(freq_diff);
635 BOOST_LOG_TRIVIAL(trace) <<
"## FREQ DIFF 2: " + to_string(freq_diff2);
641 data.open(
"output_files/studied_frame.txt");
642 for (
int i = 0; i < frame_size; i ++){
643 data << frame_data[i];
651 int begin_index = (pdcch_ss_mon_occ.n0-1) * frame_size / num_slots_per_frame;
652 begin_index = max(begin_index,0);
654 data2.open(
"output_files/moniroting_slots.txt");
655 for (
int i = 0; i < 4 * frame_size / num_slots_per_frame; i ++){
656 data2 << frame_data[i + begin_index];
664 int num_sc_coreset_0 = 12 * pdcch_ss_mon_occ.n_rb_coreset;
671 int C = pdcch_ss_mon_occ.n_rb_coreset / (height_reg_rb * R);
673 int reg_index[C * R];
674 for (
int c = 0; c < C; c ++){
675 for (
int r = 0; r < R; r ++){
677 reg_index[j] = (r * C + c + this->pci) % (pdcch_ss_mon_occ.n_rb_coreset/height_reg_rb);
680 for (
int i = 0 ; i < C * R ; i ++){
681 BOOST_LOG_TRIVIAL(trace) <<
"## CCE"+ to_string(i) +
": REG" + to_string(reg_index[i]);
688 int cp_lengths_pdcch[num_symbols_per_subframe_pdcch];
689 int cum_sum_pdcch[num_symbols_per_subframe_pdcch];
694 int K, freq_domain_ra_size;
698 freq_domain_ra_size = ceil(log2(pdcch_ss_mon_occ.n_rb_coreset*(pdcch_ss_mon_occ.n_rb_coreset+1) / 2));
702 K = freq_domain_ra_size + 4 + 1 + 5 + 2 + 1 + 15 + 24;
705 bool validated =
false;
706 int agg_level, num_candidates, dci_decoded_bits[K-24];
707 vector<vector<complex<float>>> global_sequence(pdcch_ss_mon_occ.n_symb_coreset, vector<complex<float>>(pdcch_ss_mon_occ.n_rb_coreset * 3));
708 vector<vector<vector<int>>> ref(2, vector<vector<int>>(pdcch_ss_mon_occ.n_symb_coreset, vector<int>(12 * pdcch_ss_mon_occ.n_rb_coreset)));
709 vector<vector<complex<float>>> coreset_0_samples(pdcch_ss_mon_occ.n_symb_coreset, vector<complex<float>>(num_sc_coreset_0));
710 vector<vector<complex<float>>> coefficients(pdcch_ss_mon_occ.n_symb_coreset, vector<complex<float>>(num_sc_coreset_0));
715 BOOST_LOG_TRIVIAL(trace) <<
"### PDCCH BLIND SEARCH";
716 for (
int monitoring_slot = 0; monitoring_slot < 2; monitoring_slot ++){
717 pdcch_ss_mon_occ.monitoring_slot = monitoring_slot;
718 BOOST_LOG_TRIVIAL(trace) <<
"## MONITORING SLOT: "+ to_string(monitoring_slot);
724 free5GRAN::phy::signal_processing::fft(frame_data, coreset_0_samples,fft_size,cp_lengths_pdcch,cum_sum_pdcch,pdcch_ss_mon_occ.n_symb_coreset,num_sc_coreset_0,pdcch_ss_mon_occ.first_symb_index, (pdcch_ss_mon_occ.n0 + monitoring_slot) * frame_size / num_slots_per_frame);
725 for (
int symb = 0; symb < pdcch_ss_mon_occ.n_symb_coreset; symb ++){
734 for (
int i = 2; i < 5; i ++){
735 agg_level = pow(2, i);
736 if (agg_level <= pdcch_ss_mon_occ.n_rb_coreset / height_reg_rb){
737 vector<vector<vector<int>>> channel_indexes = {vector<vector<int>>(2, vector<int>((size_t) agg_level *
free5GRAN::NUMBER_REG_PER_CCE * 9)), vector<vector<int>>(2, vector<int>((
size_t) agg_level * free5GRAN::NUMBER_REG_PER_CCE * 3))};
739 complex<float> temp_pdcch_symbols[agg_level * free5GRAN::NUMBER_REG_PER_CCE * 9];
740 complex<float> dmrs_symbols[agg_level * free5GRAN::NUMBER_REG_PER_CCE * 3];
741 complex<float> dmrs_sequence[agg_level * free5GRAN::NUMBER_REG_PER_CCE * 3];
742 int reg_bundles[agg_level];
743 int reg_bundles_ns[agg_level];
744 int dci_bits[agg_level * free5GRAN::NUMBER_REG_PER_CCE * 9 * 2];
746 BOOST_LOG_TRIVIAL(trace) <<
"## AGGREGATION LEVEL"+ to_string(agg_level);
747 num_candidates = pdcch_ss_mon_occ.n_rb_coreset / (agg_level * height_reg_rb);
751 for (
int p = 0; p < num_candidates; p ++){
752 BOOST_LOG_TRIVIAL(trace) <<
"## CANDIDATE "+ to_string(p);
756 for (
int l = 0; l < agg_level; l ++){
757 reg_bundles[l] = reg_index[l + p * agg_level];
758 reg_bundles_ns[l] = reg_index[l + p * agg_level];
760 sort(reg_bundles, reg_bundles+agg_level);
764 for (
int symbol = 0; symbol < pdcch_ss_mon_occ.n_symb_coreset; symbol ++) {
765 for (
int sc = 0; sc < 12 * pdcch_ss_mon_occ.n_rb_coreset; sc ++){
766 ref[1][symbol][sc] = 0;
767 ref[0][symbol][sc] = 0;
777 complex<float>* output_channels[] = {temp_pdcch_symbols,dmrs_symbols};
782 for (
int k = 0 ; k < agg_level; k ++){
784 dmrs_sequence[((agg_level * free5GRAN::NUMBER_REG_PER_CCE * 3) / pdcch_ss_mon_occ.n_symb_coreset) * (reg%pdcch_ss_mon_occ.n_symb_coreset) + k * height_reg_rb * 3 + (reg/pdcch_ss_mon_occ.n_symb_coreset) * 3] = global_sequence[reg%pdcch_ss_mon_occ.n_symb_coreset][reg_bundles[k] * height_reg_rb * 3 + (reg/pdcch_ss_mon_occ.n_symb_coreset) * 3];
785 dmrs_sequence[((agg_level * free5GRAN::NUMBER_REG_PER_CCE * 3) / pdcch_ss_mon_occ.n_symb_coreset) * (reg%pdcch_ss_mon_occ.n_symb_coreset) + k * height_reg_rb * 3 + (reg/pdcch_ss_mon_occ.n_symb_coreset) * 3 + 1] = global_sequence[reg%pdcch_ss_mon_occ.n_symb_coreset][reg_bundles[k] * height_reg_rb * 3 + (reg/pdcch_ss_mon_occ.n_symb_coreset) * 3 + 1];
786 dmrs_sequence[((agg_level * free5GRAN::NUMBER_REG_PER_CCE * 3) / pdcch_ss_mon_occ.n_symb_coreset) * (reg%pdcch_ss_mon_occ.n_symb_coreset) + k * height_reg_rb * 3 + (reg/pdcch_ss_mon_occ.n_symb_coreset) * 3 + 2] = global_sequence[reg%pdcch_ss_mon_occ.n_symb_coreset][reg_bundles[k] * height_reg_rb * 3 + (reg/pdcch_ss_mon_occ.n_symb_coreset) * 3 + 2];
796 for (
int sc = 0; sc < agg_level * free5GRAN::NUMBER_REG_PER_CCE * 9; sc ++){
797 pdcch_symbols[sc] = (temp_pdcch_symbols[sc]) * conj(coefficients[channel_indexes[0][0][sc]][channel_indexes[0][1][sc]]) / (float) pow(abs(coefficients[channel_indexes[0][0][sc]][channel_indexes[0][1][sc]]),2);
808 data_pdcch.open(
"output_files/pdcch_constellation.txt");
809 for (
int sc = 0; sc < agg_level * free5GRAN::NUMBER_REG_PER_CCE * 9; sc ++){
810 data_pdcch << pdcch_symbols[sc];
814 goto dci_found_and_validated;
824 dci_found_and_validated:
825 BOOST_LOG_TRIVIAL(trace) <<
"## DCI FOUND AND " << ((validated) ?
"VALIDATED" :
"NOT VALIDATED");
829 parse_dci_1_0_si_rnti(dci_decoded_bits,freq_domain_ra_size,
dci_1_0_si_rnti);
830 n_size_bwp = pdcch_ss_mon_occ.n_rb_coreset;
846 cout <<
"###### DCI" << endl;
852 cout << ((
dci_1_0_si_rnti.
si == 0 ) ?
"# SIB1 message" :
"# Other SIB message") << endl;
853 cout <<
"#######################################################################" << endl;
855 cout <<
"WARNING: Redudancy version " + to_string(
dci_1_0_si_rnti.
rv) <<
" is not supported by current decoder. To decode SIB1 data on this cell, please use CELL_SEARCH function in config and specify the cell frequency. Retry until redundancy version is not 1 or 2" << endl;
856 cout <<
"#######################################################################" << endl;
871 for (
int i = 0 ; i < freq_domain_ra_size; i ++){
872 dci.
RIV += dci_bits[i] * pow(2, freq_domain_ra_size - i - 1);
875 for (
int i = 0; i < 4; i ++){
876 dci.
TD_ra += dci_bits[i + freq_domain_ra_size] * pow(2, 4 - i - 1);
882 for (
int i = 0; i < 5; i ++){
883 dci.
mcs += dci_bits[i + freq_domain_ra_size + 4 + 1] * pow(2, 5 - i - 1);
887 for (
int i = 0; i < 2; i ++){
888 dci.
rv += dci_bits[i + freq_domain_ra_size + 4 + 1 + 5] * pow(2, 2 - i - 1);
891 dci.
si = dci_bits[freq_domain_ra_size + 4 + 1 + 5 + 2];
909 BOOST_LOG_TRIVIAL(trace) <<
"#### DECODING PDSCH";
913 int lrb, rb_start, k0, S, L, mod_order, code_rate, l0;
921 BOOST_LOG_TRIVIAL(trace) <<
"## Frequency domain RA: RB Start " + to_string(rb_start) +
" and LRB " + to_string(lrb) ;
922 BOOST_LOG_TRIVIAL(trace) <<
"## Time domain RA: K0 " + to_string(k0) +
", S " + to_string(S) +
" and L " + to_string(L) +
" (mapping type "+mapping_type+
")";
923 BOOST_LOG_TRIVIAL(trace) <<
"## MCS: Order " + to_string(mod_order) +
" and code rate " + to_string(code_rate);
924 BOOST_LOG_TRIVIAL(trace) <<
"## Slot number " + to_string(pdcch_ss_mon_occ.n0 + pdcch_ss_mon_occ.monitoring_slot + k0);
929 int additionnal_position;
930 if (mapping_type ==
"A"){
931 additionnal_position = 2;
933 if (L == 2 || L == 4){
934 additionnal_position = 0;
936 additionnal_position = 1;
938 additionnal_position = 0;
942 int *dmrs_symbols, num_symbols_dmrs;
950 complex<float> dmrs_sequence[6 * lrb * num_symbols_dmrs];
952 int count_dmrs_symbol = 0;
956 int cp_lengths_pdsch[num_symbols_per_subframe_pdsch];
957 int cum_sum_pdsch[num_symbols_per_subframe_pdsch];
959 vector<vector<complex<float>>> pdsch_ofdm_symbols(L, vector<complex<float>>(12 * pdcch_ss_mon_occ.n_rb_coreset)), pdsch_samples(L, vector<complex<float>>(12 * lrb));
960 vector<vector<vector<int>>> ref(2, vector<vector<int>>(L, vector<int>(12 * lrb)));
961 vector<vector<vector<int>>> channel_indexes = {vector<vector<int>>(2, vector<int>((size_t) 12 * lrb * (L - num_symbols_dmrs))), vector<vector<int>>(2, vector<int>((size_t) 6 * lrb * num_symbols_dmrs))};
962 vector<vector<complex<float>>> coefficients(L, vector<complex<float>>(12 * lrb));
963 complex<float> temp_dmrs_sequence[6 * pdcch_ss_mon_occ.n_rb_coreset], pdsch_samples_only[12 * lrb * (L - num_symbols_dmrs)], dmrs_samples_only[6 * lrb * num_symbols_dmrs];
973 free5GRAN::phy::signal_processing::fft(frame_data, pdsch_ofdm_symbols,fft_size,cp_lengths_pdsch,cum_sum_pdsch,L,12 * pdcch_ss_mon_occ.n_rb_coreset,S, (pdcch_ss_mon_occ.n0 + pdcch_ss_mon_occ.monitoring_slot + k0) * frame_size / num_slots_per_frame);
975 bool dmrs_symbol_array[L];
979 for (
int symb = 0; symb < L; symb ++){
980 bool dmrs_symbol =
false;
984 for (
int j = 0; j < num_symbols_dmrs; j ++){
985 if (symb + S == dmrs_symbols[j]){
990 dmrs_symbol_array[symb] = dmrs_symbol;
996 for (
int i = 0; i < 6 * lrb; i ++){
997 dmrs_sequence[count_dmrs_symbol * 6 * lrb + i] = temp_dmrs_sequence[rb_start * 6 + i];
999 count_dmrs_symbol += 1;
1002 for (
int i = 0; i < 12 * lrb; i ++){
1003 pdsch_samples[symb][i] = pdsch_ofdm_symbols[symb][12 * rb_start + i];
1010 complex<float>* output_channels[] = {pdsch_samples_only,dmrs_samples_only};
1017 for (
int phase_decomp_index = 0; phase_decomp_index < 50; phase_decomp_index++){
1021 f0 += (phase_decomp_index % 2) * pow(2,mu) * 1e3;
1022 float phase_offset = (phase_decomp_index % 2) ? f0 : -f0;
1023 BOOST_LOG_TRIVIAL(trace) <<
"PHASE DECOMP " << phase_offset ;
1024 complex<float> phase_decomp[num_symbols_per_subframe_pdsch];
1032 for (
int samp = 0; samp < 12 * lrb * (L - num_symbols_dmrs); samp ++){
1033 pdsch_samples_only[samp] = pdsch_samples_only[samp] * phase_decomp[((pdcch_ss_mon_occ.n0 + pdcch_ss_mon_occ.monitoring_slot + k0) % (num_slots_per_frame / 10)) *
free5GRAN::NUMBER_SYMBOLS_PER_SLOT_NORMAL_CP + S + channel_indexes[0][0][samp]];
1035 for (
int samp = 0; samp < 6 * lrb * num_symbols_dmrs; samp ++){
1036 dmrs_samples_only[samp] = dmrs_samples_only[samp] * phase_decomp[((pdcch_ss_mon_occ.n0 + pdcch_ss_mon_occ.monitoring_slot + k0) % (num_slots_per_frame / 10)) *
free5GRAN::NUMBER_SYMBOLS_PER_SLOT_NORMAL_CP + S + channel_indexes[1][0][samp]];
1045 vector<complex<float>> pdsch_samples_vector((
size_t) 12 * lrb * (L - num_symbols_dmrs));
1046 for (
int sc = 0; sc < 12 * lrb * (L - num_symbols_dmrs); sc ++){
1047 pdsch_samples_vector[sc] = (pdsch_samples_only[sc]) * conj(coefficients[channel_indexes[0][0][sc]][channel_indexes[0][1][sc]]) / (float) pow(abs(coefficients[channel_indexes[0][0][sc]][channel_indexes[0][1][sc]]),2);
1050 ofstream data_pdsch;
1051 data_pdsch.open(
"output_files/pdsch_constellation.txt");
1052 for (
int i = 0; i < 12 * lrb * (L - num_symbols_dmrs); i ++){
1053 data_pdsch << pdsch_samples_vector[i];
1061 double dl_sch_bits[2 * pdsch_samples_vector.size()];
1070 for (
int i =0; i < desegmented.size(); i ++){
1071 cout << desegmented[i];
1074 int bytes_size = (int) ceil(desegmented.size()/8.0);
1075 uint8_t dl_sch_bytes[bytes_size];
1076 for (
int i = 0; i < desegmented.size(); i ++){
1078 dl_sch_bytes[i/8] = 0;
1080 dl_sch_bytes[i/8] += desegmented[i] * pow(2, 8 - (i%8) - 1);
1082 asn_dec_rval_t dec_rval = asn_decode(0, ATS_UNALIGNED_BASIC_PER, &asn_DEF_BCCH_DL_SCH_Message,(
void **) &sib1, dl_sch_bytes, bytes_size);
1083 if (dec_rval.code == RC_OK) {
1084 BOOST_LOG_TRIVIAL(trace) <<
"SIB1 parsing succeeded";
1087 BOOST_LOG_TRIVIAL(trace) <<
"SIB1 parsing failed";
1100 asn_fprint(stdout, &asn_DEF_BCCH_DL_SCH_Message, sib1);
void compute_phase_decomp(int *cp_lengths, int *cum_sum_symb, float sampling_rate, float f0, int num_symb_per_subframes, complex< float > *phase_decomp_factor)
int NUMBER_SYMBOLS_PER_SLOT_NORMAL_CP
void get_candidates_frames_indexes(vector< vector< int >> &frame_indexes, int *frame_numbers, int sfn, int index_first_pss, int num_samples_before_pss, int frame_size)
void fft(vector< complex< float >> time_domain_signal, vector< vector< complex< float >>> &output_signal, int fft_size, int *cp_lengths, int *cum_sum_symb, int num_symbols, int num_sc_output, int first_symb_index, int offset)
void parse_dci_1_0_si_rnti(int *dci_bits, int freq_domain_ra_size, free5GRAN::dci_1_0_si_rnti &dci)
void get_pdsch_dmrs_symbols(const string &type, int duration, int additionnal_position, int l0, int **output, int &size)
void search_pdcch(bool &validated)
int TS_38_214_TABLE_5_1_2_1_1_2[16][2][4]
free5GRAN::pdcch_t0ss_monitoring_occasions compute_pdcch_t0_ss_monitoring_occasions(int pdcch_config, int pbch_scs, int common_scs, int i)
void search_pss(int &n_id_2, int &synchronisation_index, float &peak_value, int cp_length, vector< complex< float >> &buff, int fft_size)
int SIZE_SSB_DMRS_SYMBOLS
void transpose_signal(vector< complex< float >> *input_signal, float freq_offset, int sample_rate, int input_length)
void decode_pbch(vector< complex< float >> pbch_symbols, int i_ssb, int pci, int *bch_bits)
void decode_pdsch(vector< complex< float >> pdsch_samples, double *unscrambled_soft_bits, int pci)
void compute_rb_start_lrb_dci(int RIV, int n_size_bwp, int &lrb, int &rb_start)
int TS_38_214_TABLE_5_1_3_1_1[29][2]
void generate_pbch_dmrs_sequence(int pci, int i_bar_ssb, complex< float > *output_sequence)
void channelEstimation(complex< float > *pilots, complex< float > *reference_pilot, vector< vector< int >> &pilot_indexes, vector< vector< complex< float >>> &coefficients, float &snr, int num_sc, int num_symbols, int pilot_size)
void generate_pdsch_dmrs_sequence(int n_symb_slot, int slot_number, int symbol_number, int n_scid, int n_id_scid, complex< float > *output_sequence, int size)
void compute_pdcch_indexes(vector< vector< vector< int >>> &ref, free5GRAN::pdcch_t0ss_monitoring_occasions pdcch_ss_mon_occ, int agg_level, int *reg_bundles, int height_reg_rb)
int SIZE_SSB_PBCH_SYMBOLS
BCCH_DL_SCH_Message_t * getSib()
void get_sss(int &n_id_1, float &peak_value, vector< complex< float >> &buff, int fft_size, int n_id_2)
int compute_nre(int num_symb_pdsch, int num_dmrs_symb)
void decode_pdcch(vector< complex< float >> pdcch_symbols, int *dci_bits, int agg_level, int *reg_index, int *reg_index_sorted, int pci)
void channel_demapper(vector< vector< complex< float >>> &input_signal, vector< vector< vector< int >>> &ref, complex< float > **output_channels, vector< vector< vector< int >>> &output_indexes, int num_channels, int num_symbols, int num_sc)
vector< int > decode_dl_sch(double *dl_sch_bits, int n_re, float R, int nrb, int E, bool &validated, free5GRAN::dci_1_0_si_rnti dci_1_0_si_rnti)
void compute_pdsch_indexes(vector< vector< vector< int >>> &ref, bool dmrs_symbol_array[], int L, int lrb)
void compute_cp_lengths(int scs, int nfft, int is_extended_cp, int num_symb_per_subframes, int *cp_lengths, int *cum_sum_cp_lengths)
void compute_fine_frequency_offset(vector< complex< float >> input_signal, int symbol_duration, int fft_size, int cp_length, int scs, float &output, int num_symbols)
void generate_pdcch_dmrs_sequence(int nid, int slot_number, int symbol_number, complex< float > *output_sequence, int size)
void compute_pbch_indexes(vector< vector< vector< int >>> &ref, int pci)
void decode_dci(int *dci_bits, int E, int K, int *rnti, bool &validated, int *decoded_dci_bits)
void parse_mib(int *mib_bits, free5GRAN::mib &mib_object)
int cell_synchronization(float &received_power)
void reconfigure(int fft_size)
void decode_bch(int *bch_bits, bool &crc_validated, int *mib_bits, int pci)
struct free5GRAN::dci_1_0_si_rnti_ dci_1_0_si_rnti