diff --git a/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf index 0c7508039856bb00cff9b70ad7a8eb96d4266589..835e334bbb5fcc50c6af67ceae64e757d467dfc3 100644 --- a/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf +++ b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf @@ -219,7 +219,7 @@ RUs = ( ## beamforming 4x4 matrix: #bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff]; - sdr_addrs = "addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=192.168.18.85"; + sdr_addrs = "addr=192.168.10.2,second_addr=192.168.20.2"; } ); diff --git a/ci-scripts/datalog_rt_stats.2x2.yaml b/ci-scripts/datalog_rt_stats.2x2.yaml index a93ef6aa8c879cee167e27360709511a1233ac97..eccde746cc773bba350961a45ce4bbb8ea1c2d4c 100644 --- a/ci-scripts/datalog_rt_stats.2x2.yaml +++ b/ci-scripts/datalog_rt_stats.2x2.yaml @@ -16,7 +16,7 @@ Ref : L1 Rx processing : 175.0 PUSCH inner-receiver : 100.0 PUSCH decoding : 180.0 - DL & UL scheduling timing stats : 37.0 + DL & UL scheduling timing : 37.0 UL Indication : 38.0 Threshold : feprx : 1.25 @@ -28,5 +28,5 @@ Threshold : L1 Rx processing : 1.25 PUSCH inner-receiver : 1.25 PUSCH decoding : 1.25 - DL & UL scheduling timing stats : 1.25 + DL & UL scheduling timing : 1.25 UL Indication : 1.25 diff --git a/ci-scripts/datalog_rt_stats.default.yaml b/ci-scripts/datalog_rt_stats.default.yaml index 0da04dcaed23dc9d4a4869bee4fd2075d94636d8..97591a766dcd1cc8a18a831b0a48d6c481695473 100644 --- a/ci-scripts/datalog_rt_stats.default.yaml +++ b/ci-scripts/datalog_rt_stats.default.yaml @@ -17,7 +17,7 @@ Ref : PUSCH inner-receiver : 100.0 #PUSCH decoding : 180.0 PUSCH decoding : 240.0 - DL & UL scheduling timing stats : 37.0 + DL & UL scheduling timing : 37.0 UL Indication : 38.0 Threshold : feprx : 1.25 @@ -29,5 +29,5 @@ Threshold : L1 Rx processing : 1.25 PUSCH inner-receiver : 1.25 PUSCH decoding : 1.25 - DL & UL scheduling timing stats : 1.25 + DL & UL scheduling timing : 1.25 UL Indication : 1.25 diff --git a/ci-scripts/stats_monitor_conf.yaml b/ci-scripts/stats_monitor_conf.yaml index 9a2ececd1833b93072844d6668a8120ecb50a307..4e1f87ed176e2dd1350bd82eb0742a46924b2b81 100644 --- a/ci-scripts/stats_monitor_conf.yaml +++ b/ci-scripts/stats_monitor_conf.yaml @@ -25,7 +25,7 @@ gnb : L1 Rx processing: PUSCH inner-receiver: PUSCH decoding: - DL & UL scheduling timing stats: + DL & UL scheduling timing: UL Indication: graph : page1: @@ -45,5 +45,5 @@ gnb : page4: rt.PUSCH inner-receiver: rt.PUSCH decoding: - rt.DL & UL scheduling timing stats: + rt.DL & UL scheduling timing: rt.UL Indication: diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml index a2c68e9ef6a31d6f560006d43f17847b82c654e1..1fdc3446d9ce19d0a85abeeca4a04db77ec37b25 100755 --- a/cmake_targets/autotests/test_case_list.xml +++ b/cmake_targets/autotests/test_case_list.xml @@ -1134,7 +1134,7 @@ -n100 -s2 -U 2 1 3 -n10 -s20 -U 3 0 0 2 -gR -x1 -y4 -z4 -n10 -s20 -U 3 0 0 2 -gR -x2 -y4 -z4 - -n100 -m0 -e0 -R25 -b25 -i</main_exec_args> + -n100 -m0 -e0 -R25 -b25 -i 2 1 0</main_exec_args> <tags>nr_dlsim.test1 nr_dlsim.test2 nr_dlsim.test3 nr_dlsim.test4 nr_dlsim.test5 nr_dlsim.test6 nr_dlsim.test7 nr_dlsim.test8 nr_dlsim.test9 nr_dlsim.test10 nr_dlsim.test11 nr_dlsim.test12 nr_dlsim.test13 nr_dlsim.test14 nr_dlsim.test15 nr_dlsim.test16 nr_dlsim.test17 nr_dlsim.test18 nr_dlsim.test19 nr_dlsim.test20 nr_dlsim.test21 nr_dlsim.test22 nr_dlsim.test23</tags> <search_expr_true>PDSCH test OK</search_expr_true> <search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false> @@ -1311,7 +1311,10 @@ (Test15: MCS 19 50 PRBs 2 RX_Antenna), (Test16: MCS 9 106 PRBs MIMO 2 layers), (Test17: MCS 9 106 PRBs MIMO 4 layers), - (Test18: 25 PRBs, 15 kHz SCS)</desc> + (Test18: 25 PRBs, 15 kHz SCS), + (Test19: 3GPP G-FR1-A4-13 2 RX Antennas Requirements Test), + (Test20: 3GPP G-FR1-A4-13 4 RX Antennas Requirements Test), + (Test21: 3GPP G-FR1-A4-13 8 RX Antennas Requirements Test)</desc> <pre_compile_prog></pre_compile_prog> <compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</compile_prog> <compile_prog_args> --phy_simulators -c </compile_prog_args> @@ -1323,20 +1326,24 @@ -n100 -m28 -s20 -n100 -m9 -R217 -r217 -s5 -n100 -m9 -R273 -r273 -s5 - -n100 -s5 -U 2 0 1 - -n100 -s5 -T 2 1 2 -U 2 0 2 - -n100 -s5 -T 2 2 2 -U 2 1 2 - -n100 -s5 -a4 -b8 -T 2 1 2 -U 2 1 3 - -n100 -Z -s5 + -n100 -s5 -U 4 0 1 1 1 + -n100 -s5 -T 2 1 2 -U 4 0 2 1 1 + -n100 -s5 -T 2 2 2 -U 4 1 2 1 1 + -n100 -s5 -a4 -b8 -T 2 1 2 -U 4 1 3 1 1 + -n100 -s5 -Z -n100 -s5 -Z -r75 -n50 -s5 -Z -r216 -R217 -n50 -s5 -Z -r270 -R273 - -n100 -s5 -Z -U 2 0 2 + -n100 -s5 -Z -U 4 0 2 1 2 -n100 -m19 -s10 -S15 -z2 -n100 -m9 -r106 -s10 -W2 -y2 -z2 -n100 -m9 -r106 -s20 -W4 -y4 -z4 - -n100 -u0 -m0 -R25 -r25 -i</main_exec_args> - <tags>nr_ulsim.test1 nr_ulsim.test2 nr_ulsim.test3 nr_ulsim.test4 nr_ulsim.test5 nr_ulsim.test6 nr_ulsim.test7 nr_ulsim.test8 nr_ulsim.test9 nr_ulsim.test10 nr_ulsim.test11 nr_ulsim.test12 nr_ulsim.test13 nr_ulsim.test14 nr_ulsim.test15 nr_ulsim.test16 nr_ulsim.test17 nr_ulsim.test18</tags> + -n100 -u0 -m0 -R25 -r25 -i 2 1 0 + -m16 -r106 -s8.8 -S9.4 -z2 -n200 -U 4 1 1 1 2 -gI -b14 -t70 -I15 -i 2 1 0 + -m16 -r106 -s5.4 -S6 -z4 -n200 -U 4 1 1 1 2 -gI -b14 -t70 -I15 -i 2 1 0 + -m16 -r106 -s3.4 -S3.8 -z8 -n200 -U 4 1 1 1 2 -gI -b14 -t70 -I15 -i 2 1 0</main_exec_args> + + <tags>nr_ulsim.test1 nr_ulsim.test2 nr_ulsim.test3 nr_ulsim.test4 nr_ulsim.test5 nr_ulsim.test6 nr_ulsim.test7 nr_ulsim.test8 nr_ulsim.test9 nr_ulsim.test10 nr_ulsim.test11 nr_ulsim.test12 nr_ulsim.test13 nr_ulsim.test14 nr_ulsim.test15 nr_ulsim.test16 nr_ulsim.test17 nr_ulsim.test18 nr_ulsim.test19 nr_ulsim.test20 nr_ulsim.test21</tags> <search_expr_true>PUSCH test OK</search_expr_true> <search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false> <nruns>3</nruns> diff --git a/common/utils/nr/nr_common.c b/common/utils/nr/nr_common.c index af31c83d6e1f5dce62d2b54818a74dab3fac8c16..6add03c324db9f3d6903cd341c425511f47f5500 100644 --- a/common/utils/nr/nr_common.c +++ b/common/utils/nr/nr_common.c @@ -191,6 +191,19 @@ int PRBalloc_to_locationandbandwidth(int NPRB,int RBstart) { return(PRBalloc_to_locationandbandwidth0(NPRB,RBstart,275)); } +int cce_to_reg_interleaving(const int R, int k, int n_shift, const int C, int L, const int N_regs) { + + int f; // interleaving function + if(R==0) + f = k; + else { + int c = k/R; + int r = k%R; + f = (r*C + c + n_shift)%(N_regs/L); + } + return f; +} + void get_coreset_rballoc(uint8_t *FreqDomainResource,int *n_rb,int *rb_offset) { uint8_t count=0, start=0, start_set=0; diff --git a/common/utils/nr/nr_common.h b/common/utils/nr/nr_common.h index 5258ce8809b66a45f737f032057a50ea88414db1..5f7f670ce92938f058410d0f698f61e9fde2fa8e 100644 --- a/common/utils/nr/nr_common.h +++ b/common/utils/nr/nr_common.h @@ -57,7 +57,7 @@ static inline int get_num_dmrs(uint16_t dmrs_mask ) { return(num_dmrs); } - +int cce_to_reg_interleaving(const int R, int k, int n_shift, const int C, int L, const int N_regs); int get_SLIV(uint8_t S, uint8_t L); void get_coreset_rballoc(uint8_t *FreqDomainResource,int *n_rb,int *rb_offset); uint16_t config_bandwidth(int mu, int nb_rb, int nr_band); diff --git a/common/utils/time_meas.c b/common/utils/time_meas.c index df2bfd64de32b6c8b97c3450170e2ff5f9cc71a5..9d1215b5e5b255e979401dc2fa8089c2bd903bcb 100644 --- a/common/utils/time_meas.c +++ b/common/utils/time_meas.c @@ -111,13 +111,15 @@ void print_meas(time_stats_t *ts, } } -int print_meas_log(time_stats_t *ts, - const char *name, - time_stats_t *total_exec_time, - time_stats_t *sf_exec_time, - char *output) +size_t print_meas_log(time_stats_t *ts, + const char *name, + time_stats_t *total_exec_time, + time_stats_t *sf_exec_time, + char *output, + size_t outputlen) { - int stroff = 0; + const char *begin = output; + const char *end = output + outputlen; static int first_time = 0; static double cpu_freq_GHz = 0.0; @@ -128,30 +130,49 @@ int print_meas_log(time_stats_t *ts, first_time=1; if ((total_exec_time == NULL) || (sf_exec_time== NULL)) - stroff += sprintf(output, "%25s %25s %25s %25s %25s %6f\n","Name","Total","Per Trials", "Num Trials","CPU_F_GHz", cpu_freq_GHz); + output += snprintf(output, + end - output, + "%25s %25s %25s %25s %25s %6f\n", + "Name", + "Total", + "Per Trials", + "Num Trials", + "CPU_F_GHz", + cpu_freq_GHz); else - stroff += sprintf(output+stroff, "%25s %25s %25s %20s %15s %6f\n","Name","Total","Average/Frame","Trials", "CPU_F_GHz", cpu_freq_GHz); + output += snprintf(output, + end - output, + "%25s %25s %25s %20s %15s %6f\n", + "Name", + "Total", + "Average/Frame", + "Trials", + "CPU_F_GHz", + cpu_freq_GHz); } if (ts->trials>0) { - //printf("%20s: total: %10.3f ms, average: %10.3f us (%10d trials)\n", name, ts->diff/cpu_freq_GHz/1000000.0, ts->diff/ts->trials/cpu_freq_GHz/1000.0, ts->trials); if ((total_exec_time == NULL) || (sf_exec_time== NULL)) { - stroff += sprintf(output+stroff, "%25s: %15.3f us; %15d; %15.3f us;\n", - name, - (ts->diff/ts->trials/cpu_freq_GHz/1000.0), - ts->trials, - ts->max/cpu_freq_GHz/1000.0); + output += snprintf(output, + end - output, + "%25s: %15.3f us; %15d; %15.3f us;\n", + name, + ts->diff / ts->trials / cpu_freq_GHz / 1000.0, + ts->trials, + ts->max / cpu_freq_GHz / 1000.0); } else { - stroff += sprintf(output+stroff, "%25s: %15.3f ms (%5.2f%%); %15.3f us (%5.2f%%); %15d;\n", - name, - (ts->diff/cpu_freq_GHz/1000000.0), - ((ts->diff/cpu_freq_GHz/1000000.0)/(total_exec_time->diff/cpu_freq_GHz/1000000.0))*100, // percentage - (ts->diff/ts->trials/cpu_freq_GHz/1000.0), - ((ts->diff/ts->trials/cpu_freq_GHz/1000.0)/(sf_exec_time->diff/sf_exec_time->trials/cpu_freq_GHz/1000.0))*100, // percentage - ts->trials); + output += snprintf(output, + end - output, + "%25s: %15.3f ms (%5.2f%%); %15.3f us (%5.2f%%); %15d;\n", + name, + ts->diff / cpu_freq_GHz / 1000000.0, + ((ts->diff / cpu_freq_GHz / 1000000.0) / (total_exec_time->diff / cpu_freq_GHz / 1000000.0))*100, // percentage + ts->diff / ts->trials / cpu_freq_GHz / 1000.0, + ((ts->diff / ts->trials / cpu_freq_GHz / 1000.0) / (sf_exec_time->diff / sf_exec_time->trials / cpu_freq_GHz / 1000.0)) * 100, // percentage + ts->trials); } } - return stroff; + return output - begin; } double get_time_meas_us(time_stats_t *ts) diff --git a/common/utils/time_meas.h b/common/utils/time_meas.h index 382dd7455a0e4a5d44146b4c6054c971071d7809..fded7f1a9c9a3195535f8c5b279d0124c8ed1c1c 100644 --- a/common/utils/time_meas.h +++ b/common/utils/time_meas.h @@ -83,7 +83,12 @@ static inline void stop_meas(time_stats_t *ts) __attribute__((always_inline)); void print_meas_now(time_stats_t *ts, const char *name, FILE *file_name); void print_meas(time_stats_t *ts, const char *name, time_stats_t *total_exec_time, time_stats_t *sf_exec_time); -int print_meas_log(time_stats_t *ts, const char *name, time_stats_t *total_exec_time, time_stats_t *sf_exec_time, char *output); +size_t print_meas_log(time_stats_t *ts, + const char *name, + time_stats_t *total_exec_time, + time_stats_t *sf_exec_time, + char *output, + size_t outputlen); double get_time_meas_us(time_stats_t *ts); double get_cpu_freq_GHz(void); diff --git a/doc/NR_SA_CN5G_gNB_B210_COTS_UE_Tutorial.md b/doc/NR_SA_CN5G_gNB_B210_COTS_UE_Tutorial.md new file mode 100644 index 0000000000000000000000000000000000000000..1110a5bc6cd8ca5b25aaf3326894384e0c6c41a3 --- /dev/null +++ b/doc/NR_SA_CN5G_gNB_B210_COTS_UE_Tutorial.md @@ -0,0 +1,234 @@ +<table style="border-collapse: collapse; border: none;"> + <tr style="border-collapse: collapse; border: none;"> + <td style="border-collapse: collapse; border: none;"> + <a href="http://www.openairinterface.org/"> + <img src="./images/oai_final_logo.png" alt="" border=3 height=50 width=150> + </img> + </a> + </td> + <td style="border-collapse: collapse; border: none; vertical-align: center;"> + <b><font size = "5">OAI 5G SA tutorial</font></b> + </td> + </tr> +</table> + +**TABLE OF CONTENTS** + +1. [Scenario](#1-scenario) +2. [OAI CN5G](#2-oai-cn5g) + 1. [OAI CN5G pre-requisites](#21-oai-cn5g-pre-requisites) + 2. [OAI CN5G Setup](#22-oai-cn5g-setup) + 3. [OAI CN5G Configuration files](#23-oai-cn5g-configuration-files) + 4. [SIM Card](#24-sim-card) +3. [OAI gNB](#3-oai-gnb) + 1. [OAI gNB pre-requisites](#31-oai-gnb-pre-requisites) + 2. [Build OAI gNB](#32-build-oai-gnb) +4. [Run OAI CN5G and OAI gNB with USRP B210](#4-run-oai-cn5g-and-oai-gnb-with-usrp-b210) + 1. [Run OAI CN5G](#41-run-oai-cn5g) + 2. [Run OAI gNB](#42-run-oai-gnb) +5. [Testing with QUECTEL RM500Q](#5-testing-with-quectel-rm500q) + 1. [Setup QUECTEL](#51-setup-quectel) + 2. [Ping test](#52-ping-test) + 3. [Downlink iPerf test](#53-downlink-iperf-test) + + +# 1. Scenario +In this tutorial we describe how to configure and run a 5G end-to-end setup with OAI CN5G, OAI gNB and COTS UE. + +Minimum hardware requirements: +- Laptop/Desktop/Server for OAI CN5G and OAI gNB + - Operating System: [Ubuntu 20.04.4 LTS](https://releases.ubuntu.com/20.04.4/ubuntu-20.04.4-desktop-amd64.iso) + - CPU: 8 cores x86_64 @ 3.5 GHz + - RAM: 32 GB +- Laptop for UE + - Operating System: Microsoft Windows 10 x64 + - CPU: 4 cores x86_64 + - RAM: 8 GB + - Windows driver for Quectel MUST be equal or higher than version **2.2.4** +- [USRP B210](https://www.ettus.com/all-products/ub210-kit/) +- Quectel RM500Q + - Module, M.2 to USB adapter, antennas and SIM card + - Firmware version of Quectel MUST be equal or higher than **RM500QGLABR11A06M4G** + + +# 2. OAI CN5G + +## 2.1 OAI CN5G pre-requisites + +```bash +sudo apt install -y git net-tools putty + +sudo apt install -y apt-transport-https ca-certificates curl software-properties-common +curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - +sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" +sudo apt update +sudo apt install -y docker docker-ce + +# Add your username to the docker group, otherwise you will have to run in sudo mode. +sudo usermod -a -G docker $(whoami) +reboot + +# https://docs.docker.com/compose/install/ +sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose +sudo chmod +x /usr/local/bin/docker-compose + +docker network create --driver=bridge --subnet=192.168.70.128/26 -o "com.docker.network.bridge.name"="demo-oai" demo-oai-public-net +sudo service docker restart + +``` + +## 2.2 OAI CN5G Setup + +```bash +# Git oai-cn5g-fed repository +git clone https://gitlab.eurecom.fr/oai/cn5g/oai-cn5g-fed.git ~/oai-cn5g-fed +cd ~/oai-cn5g-fed +git checkout master +./scripts/syncComponents.sh --nrf-branch develop --amf-branch develop --smf-branch develop --spgwu-tiny-branch develop --ausf-branch develop --udm-branch develop --udr-branch develop --upf-vpp-branch develop --nssf-branch develop + +docker pull oaisoftwarealliance/oai-amf:develop +docker pull oaisoftwarealliance/oai-nrf:develop +docker pull oaisoftwarealliance/oai-smf:develop +docker pull oaisoftwarealliance/oai-udr:develop +docker pull oaisoftwarealliance/oai-udm:develop +docker pull oaisoftwarealliance/oai-ausf:develop +docker pull oaisoftwarealliance/oai-upf-vpp:develop +docker pull oaisoftwarealliance/oai-spgwu-tiny:develop +docker pull oaisoftwarealliance/oai-nssf:develop + +docker image tag oaisoftwarealliance/oai-amf:develop oai-amf:develop +docker image tag oaisoftwarealliance/oai-nrf:develop oai-nrf:develop +docker image tag oaisoftwarealliance/oai-smf:develop oai-smf:develop +docker image tag oaisoftwarealliance/oai-udr:develop oai-udr:develop +docker image tag oaisoftwarealliance/oai-udm:develop oai-udm:develop +docker image tag oaisoftwarealliance/oai-ausf:develop oai-ausf:develop +docker image tag oaisoftwarealliance/oai-upf-vpp:develop oai-upf-vpp:develop +docker image tag oaisoftwarealliance/oai-spgwu-tiny:develop oai-spgwu-tiny:develop +docker image tag oaisoftwarealliance/oai-nssf:develop oai-nssf:develop +``` + +## 2.3 OAI CN5G Configuration files +Download and copy the configuration files to ~/oai-cn5g-fed/docker-compose: +- [docker-compose-basic-nrf.yaml](tutorial_resources/docker-compose-basic-nrf.yaml) +- [oai_db.sql](tutorial_resources/oai_db.sql) + +Change permissions on oai_db.sql to prevent mysql permission denied error: +```bash +chmod 644 ~/oai-cn5g-fed/docker-compose/oai_db.sql +``` + +## 2.4 SIM Card +Program SIM Card with [Open Cells Project](https://open-cells.com/) application [uicc-v2.6](https://open-cells.com/d5138782a8739209ec5760865b1e53b0/uicc-v2.6.tgz). + +```bash +sudo ./program_uicc --adm 12345678 --imsi 208990000000001 --isdn 00000001 --acc 0001 --key fec86ba6eb707ed08905757b1bb44b8f --opc C42449363BBAD02B66D16BC975D77CC1 -spn "OpenAirInterface" --authenticate +``` + + +# 3. OAI gNB + +## 3.1 OAI gNB pre-requisites + +### Build UHD from source +```bash +sudo apt install -y libboost-all-dev libusb-1.0-0-dev doxygen python3-docutils python3-mako python3-numpy python3-requests python3-ruamel.yaml python3-setuptools cmake build-essential + +git clone https://github.com/EttusResearch/uhd.git ~/uhd +cd ~/uhd +git checkout v4.0.0.0 +cd host +mkdir build +cd build +cmake ../ +make -j 4 +make test # This step is optional +sudo make install +sudo ldconfig +sudo uhd_images_downloader +``` + +## 3.2 Build OAI gNB + +```bash +# Get openairinterface5g source code +git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git ~/openairinterface5g +cd ~/openairinterface5g +git checkout develop + +# Install dependencies in Ubuntu 20.04 +cd ~/openairinterface5g +source oaienv +cd cmake_targets +./build_oai -I + +# Build OAI gNB +cd ~/openairinterface5g +source oaienv +cd cmake_targets +./build_oai -w USRP --nrUE --gNB --build-lib all -c +``` + + +# 4. Run OAI CN5G and OAI gNB with USRP B210 + +## 4.1 Run OAI CN5G + +```bash +cd ~/oai-cn5g-fed/docker-compose +python3 core-network.py --type start-basic --fqdn yes --scenario 1 +``` + +## 4.2 Run OAI gNB + +```bash +cd ~/openairinterface5g +source oaienv +cd cmake_targets/ran_build/build +sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf --sa -E --continuous-tx +``` + +Make sure that during USRP initialization, it shows that USB 3 is used. + +# 5. Testing with Quectel RM500Q + +## 5.1 Setup Quectel +With [PuTTY](https://the.earth.li/~sgtatham/putty/latest/w64/putty.exe), send the following AT commands to the module using a serial interface (ex: COM2) at 115200 bps: +```bash +# MUST be sent at least once everytime there is a firmware upgrade! +AT+QMBNCFG="Select","ROW_Commercial" +AT+QMBNCFG="AutoSel",0 +AT+CFUN=1,1 +AT+CGDCONT=1 +AT+CGDCONT=2 +AT+CGDCONT=3 +AT+CGDCONT=1,"IP","oai" + +# (Optional, debug only, AT commands) Activate PDP context, retrieve IP address and test with ping +AT+CGACT=1,1 +AT+CGPADDR=1 +AT+QPING=1,"openairinterface.org" +``` + +## 5.2 Ping test +- UE host +```bash +ping 192.168.70.135 -n 1000 -S 12.1.1.2 +``` +- CN5G host +```bash +docker exec -it oai-ext-dn ping 12.1.1.2 +``` + +## 5.3 Downlink iPerf test +- UE host + - Download iPerf for Microsoft Windows from [here](https://iperf.fr/download/windows/iperf-2.0.9-win64.zip). + - Extract to Desktop and run with Command Prompt: +```bash +cd C:\Users\User\Desktop\iPerf\iperf-2.0.9-win64\iperf-2.0.9-win64 +iperf -s -u -i 1 -B 12.1.1.2 +``` + +- CN5G host +```bash +docker exec -it oai-ext-dn iperf -u -t 86400 -i 1 -fk -B 192.168.70.135 -b 125M -c 12.1.1.2 +``` diff --git a/doc/NR_SA_CN5G_gNB_N300_COTS_UE_Tutorial.md b/doc/NR_SA_CN5G_gNB_N300_COTS_UE_Tutorial.md new file mode 100644 index 0000000000000000000000000000000000000000..ed917e09eaf2a0769754ff7e736d1cde3655da67 --- /dev/null +++ b/doc/NR_SA_CN5G_gNB_N300_COTS_UE_Tutorial.md @@ -0,0 +1,251 @@ +<table style="border-collapse: collapse; border: none;"> + <tr style="border-collapse: collapse; border: none;"> + <td style="border-collapse: collapse; border: none;"> + <a href="http://www.openairinterface.org/"> + <img src="./images/oai_final_logo.png" alt="" border=3 height=50 width=150> + </img> + </a> + </td> + <td style="border-collapse: collapse; border: none; vertical-align: center;"> + <b><font size = "5">OAI 5G SA tutorial</font></b> + </td> + </tr> +</table> + +**TABLE OF CONTENTS** + +1. [Scenario](#1-scenario) +2. [OAI CN5G](#2-oai-cn5g) + 1. [OAI CN5G pre-requisites](#21-oai-cn5g-pre-requisites) + 2. [OAI CN5G Setup](#22-oai-cn5g-setup) + 3. [OAI CN5G Configuration files](#23-oai-cn5g-configuration-files) + 4. [SIM Card](#24-sim-card) +3. [OAI gNB](#3-oai-gnb) + 1. [OAI gNB pre-requisites](#31-oai-gnb-pre-requisites) + 2. [Build OAI gNB](#32-build-oai-gnb) + 3. [N300 Ethernet Tuning](#33-n300-ethernet-tuning) +4. [Run OAI CN5G and OAI gNB with USRP N300](#4-run-oai-cn5g-and-oai-gnb-with-usrp-n300) + 1. [Run OAI CN5G](#41-run-oai-cn5g) + 2. [Run OAI gNB](#42-run-oai-gnb) +5. [Testing with QUECTEL RM500Q](#5-testing-with-quectel-rm500q) + 1. [Setup QUECTEL](#51-setup-quectel) + 2. [Ping test](#52-ping-test) + 3. [Downlink iPerf test](#53-downlink-iperf-test) + + +# 1. Scenario +In this tutorial we describe how to configure and run a 5G end-to-end setup with OAI CN5G, OAI gNB and COTS UE. + +Minimum hardware requirements: +- Laptop/Desktop/Server for OAI CN5G and OAI gNB + - Operating System: [Ubuntu 20.04.4 LTS](https://releases.ubuntu.com/20.04.4/ubuntu-20.04.4-desktop-amd64.iso) + - CPU: 8 cores x86_64 @ 3.5 GHz + - RAM: 32 GB +- Laptop for UE + - Operating System: Microsoft Windows 10 x64 + - CPU: 4 cores x86_64 + - RAM: 8 GB + - Windows driver for Quectel MUST be equal or higher than version **2.2.4** +- [USRP N300](https://www.ettus.com/all-products/USRP-N300/): Please identify the network interface(s) on which the N300 is connected. +- Quectel RM500Q + - Module, M.2 to USB adapter, antennas and SIM card + - Firmware version of Quectel MUST be equal or higher than **RM500QGLABR11A06M4G** + + +# 2. OAI CN5G + +## 2.1 OAI CN5G pre-requisites + +```bash +sudo apt install -y git net-tools putty + +sudo apt install -y apt-transport-https ca-certificates curl software-properties-common +curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - +sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" +sudo apt update +sudo apt install -y docker docker-ce + +# Add your username to the docker group, otherwise you will have to run in sudo mode. +sudo usermod -a -G docker $(whoami) +reboot + +# https://docs.docker.com/compose/install/ +sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose +sudo chmod +x /usr/local/bin/docker-compose + +docker network create --driver=bridge --subnet=192.168.70.128/26 -o "com.docker.network.bridge.name"="demo-oai" demo-oai-public-net +sudo service docker restart + +``` + +## 2.2 OAI CN5G Setup + +```bash +# Git oai-cn5g-fed repository +git clone https://gitlab.eurecom.fr/oai/cn5g/oai-cn5g-fed.git ~/oai-cn5g-fed +cd ~/oai-cn5g-fed +git checkout master +./scripts/syncComponents.sh --nrf-branch develop --amf-branch develop --smf-branch develop --spgwu-tiny-branch develop --ausf-branch develop --udm-branch develop --udr-branch develop --upf-vpp-branch develop --nssf-branch develop + +docker pull oaisoftwarealliance/oai-amf:develop +docker pull oaisoftwarealliance/oai-nrf:develop +docker pull oaisoftwarealliance/oai-smf:develop +docker pull oaisoftwarealliance/oai-udr:develop +docker pull oaisoftwarealliance/oai-udm:develop +docker pull oaisoftwarealliance/oai-ausf:develop +docker pull oaisoftwarealliance/oai-upf-vpp:develop +docker pull oaisoftwarealliance/oai-spgwu-tiny:develop +docker pull oaisoftwarealliance/oai-nssf:develop + +docker image tag oaisoftwarealliance/oai-amf:develop oai-amf:develop +docker image tag oaisoftwarealliance/oai-nrf:develop oai-nrf:develop +docker image tag oaisoftwarealliance/oai-smf:develop oai-smf:develop +docker image tag oaisoftwarealliance/oai-udr:develop oai-udr:develop +docker image tag oaisoftwarealliance/oai-udm:develop oai-udm:develop +docker image tag oaisoftwarealliance/oai-ausf:develop oai-ausf:develop +docker image tag oaisoftwarealliance/oai-upf-vpp:develop oai-upf-vpp:develop +docker image tag oaisoftwarealliance/oai-spgwu-tiny:develop oai-spgwu-tiny:develop +docker image tag oaisoftwarealliance/oai-nssf:develop oai-nssf:develop +``` + +## 2.3 OAI CN5G Configuration files +Download and copy the configuration files to ~/oai-cn5g-fed/docker-compose: +- [docker-compose-basic-nrf.yaml](tutorial_resources/docker-compose-basic-nrf.yaml) +- [oai_db.sql](tutorial_resources/oai_db.sql) + +Change permissions on oai_db.sql to prevent mysql permission denied error: +```bash +chmod 644 ~/oai-cn5g-fed/docker-compose/oai_db.sql +``` + +## 2.4 SIM Card +Program SIM Card with [Open Cells Project](https://open-cells.com/) application [uicc-v2.6](https://open-cells.com/d5138782a8739209ec5760865b1e53b0/uicc-v2.6.tgz). + +```bash +sudo ./program_uicc --adm 12345678 --imsi 208990000000001 --isdn 00000001 --acc 0001 --key fec86ba6eb707ed08905757b1bb44b8f --opc C42449363BBAD02B66D16BC975D77CC1 -spn "OpenAirInterface" --authenticate +``` + + +# 3. OAI gNB + +## 3.1 OAI gNB pre-requisites + +### Build UHD from source +```bash +sudo apt install -y libboost-all-dev libusb-1.0-0-dev doxygen python3-docutils python3-mako python3-numpy python3-requests python3-ruamel.yaml python3-setuptools cmake build-essential + +git clone https://github.com/EttusResearch/uhd.git ~/uhd +cd ~/uhd +git checkout v4.0.0.0 +cd host +mkdir build +cd build +cmake ../ +make -j 4 +make test # This step is optional +sudo make install +sudo ldconfig +sudo uhd_images_downloader +``` + +## 3.2 Build OAI gNB + +```bash +# Get openairinterface5g source code +git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git ~/openairinterface5g +cd ~/openairinterface5g +git checkout develop + +# Install dependencies in Ubuntu 20.04 +cd ~/openairinterface5g +source oaienv +cd cmake_targets +./build_oai -I + +# Build OAI gNB +cd ~/openairinterface5g +source oaienv +cd cmake_targets +./build_oai -w USRP --nrUE --gNB --build-lib all -c +``` + +## 3.3 N300 Ethernet Tuning + +Please also refer to the official [USRP Host Performance Tuning Tips and Tricks](https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks) tuning guide. + +The following steps are recommended. Please change the network interface(s) as required. Also, you should have 10Gbps interface(s): if you use two cables, you should have the XG interface. Refer to the [N300 Getting Started Guide](https://kb.ettus.com/USRP_N300/N310/N320/N321_Getting_Started_Guide) for more information. + +* Use an MTU of 9000: how to change this depends on the network management tool. In the case of Network Manager, this can be done from the GUI. +* Increase the kernel socket buffer (also done by the USRP driver in OAI): + ``` + sysctl -w net.core.rmem_max=8388608 + sysctl -w net.core.wmem_max=8388608 + sysctl -w net.core.rmem_default=65536 + sysctl -w net.core.wmem_default=65536 + ``` +* Increase Ethernet Ring Buffers: `sudo ethtool -G <ifname> rx 4096 tx 4096` +* Disable hyper-threading in the BIOS +* Disable KPTI Protections for Spectre/Meltdown for more performance. **This is a security risk.** Add `mitigations=off nosmt` in your grub config and update grub. + +# 4. Run OAI CN5G and OAI gNB with USRP N300 + +## 4.1 Run OAI CN5G + +```bash +cd ~/oai-cn5g-fed/docker-compose +python3 core-network.py --type start-basic --fqdn yes --scenario 1 +``` + +## 4.2 Run OAI gNB + +```bash +cd ~/openairinterface5g +source oaienv +cd cmake_targets/ran_build/build +sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.162PRB.2x2.usrpn300.conf --sa --usrp-tx-thread-config 1 +``` + + +# 5. Testing with Quectel RM500Q + +## 5.1 Setup Quectel +With [PuTTY](https://the.earth.li/~sgtatham/putty/latest/w64/putty.exe), send the following AT commands to the module using a serial interface (ex: COM2) at 115200 bps: +```bash +# MUST be sent at least once everytime there is a firmware upgrade! +AT+QMBNCFG="Select","ROW_Commercial" +AT+QMBNCFG="AutoSel",0 +AT+CFUN=1,1 +AT+CGDCONT=1 +AT+CGDCONT=2 +AT+CGDCONT=3 +AT+CGDCONT=1,"IP","oai" + +# (Optional, debug only, AT commands) Activate PDP context, retrieve IP address and test with ping +AT+CGACT=1,1 +AT+CGPADDR=1 +AT+QPING=1,"openairinterface.org" +``` + +## 5.2 Ping test +- UE host +```bash +ping 192.168.70.135 -n 1000 -S 12.1.1.2 +``` +- CN5G host +```bash +docker exec -it oai-ext-dn ping 12.1.1.2 +``` + +## 5.3 Downlink iPerf test +- UE host + - Download iPerf for Microsoft Windows from [here](https://iperf.fr/download/windows/iperf-2.0.9-win64.zip). + - Extract to Desktop and run with Command Prompt: +```bash +cd C:\Users\User\Desktop\iPerf\iperf-2.0.9-win64\iperf-2.0.9-win64 +iperf -s -u -i 1 -B 12.1.1.2 +``` + +- CN5G host +```bash +docker exec -it oai-ext-dn iperf -u -t 86400 -i 1 -fk -B 192.168.70.135 -b 200M -c 12.1.1.2 +``` diff --git a/doc/tutorial_resources/docker-compose-basic-nrf.yaml b/doc/tutorial_resources/docker-compose-basic-nrf.yaml new file mode 100644 index 0000000000000000000000000000000000000000..6750cb78bec7d39448a0f5cc562ff76f61e87ada --- /dev/null +++ b/doc/tutorial_resources/docker-compose-basic-nrf.yaml @@ -0,0 +1,316 @@ +version: '3.8' +services: + mysql: + container_name: "mysql" + image: mysql:5.7 + volumes: + - ./oai_db.sql:/docker-entrypoint-initdb.d/oai_db.sql + - ./mysql-healthcheck2.sh:/tmp/mysql-healthcheck.sh + environment: + - TZ=Europe/Paris + - MYSQL_DATABASE=oai_db + - MYSQL_USER=test + - MYSQL_PASSWORD=test + - MYSQL_ROOT_PASSWORD=linux + healthcheck: + test: /bin/bash -c "/tmp/mysql-healthcheck.sh" + interval: 10s + timeout: 5s + retries: 5 + networks: + public_net: + ipv4_address: 192.168.70.131 + oai-udr: + container_name: oai-udr + image: oai-udr:develop + environment: + - TZ=Europe/Paris + - INSTANCE=0 + - PID_DIRECTORY=/var/run + - UDR_INTERFACE_NAME_FOR_NUDR=eth0 + - UDR_INTERFACE_PORT_FOR_NUDR=80 + - UDR_INTERFACE_HTTP2_PORT_FOR_NUDR=8080 + - UDR_API_VERSION=v1 + - MYSQL_IPV4_ADDRESS=192.168.70.131 + - MYSQL_USER=test + - MYSQL_PASS=test + - MYSQL_DB=oai_db + - WAIT_MYSQL=120 + depends_on: + - mysql + networks: + public_net: + ipv4_address: 192.168.70.136 + volumes: + - ./udr-healthcheck.sh:/openair-udr/bin/udr-healthcheck.sh + healthcheck: + test: /bin/bash -c "/openair-udr/bin/udr-healthcheck.sh" + interval: 10s + timeout: 5s + retries: 5 + oai-udm: + container_name: oai-udm + image: oai-udm:develop + environment: + - TZ=Europe/Paris + - INSTANCE=0 + - PID_DIRECTORY=/var/run + - UDM_NAME=OAI_UDM + - SBI_IF_NAME=eth0 + - SBI_PORT=80 + - UDM_VERSION_NB=v1 + - USE_FQDN_DNS=yes + - UDR_IP_ADDRESS=192.168.70.136 + - UDR_PORT=80 + - UDR_VERSION_NB=v1 + - UDR_FQDN=oai-udr + depends_on: + - oai-udr + networks: + public_net: + ipv4_address: 192.168.70.137 + volumes: + - ./udm-healthcheck.sh:/openair-udm/bin/udm-healthcheck.sh + healthcheck: + test: /bin/bash -c "/openair-udm/bin/udm-healthcheck.sh" + interval: 10s + timeout: 5s + retries: 5 + oai-ausf: + container_name: oai-ausf + image: oai-ausf:develop + environment: + - TZ=Europe/Paris + - INSTANCE_ID=0 + - PID_DIR=/var/run + - AUSF_NAME=OAI_AUSF + - SBI_IF_NAME=eth0 + - SBI_PORT=80 + - USE_FQDN_DNS=yes + - UDM_IP_ADDRESS=192.168.70.137 + - UDM_PORT=80 + - UDM_VERSION_NB=v1 + - UDM_FQDN=oai-udm + depends_on: + - oai-udm + networks: + public_net: + ipv4_address: 192.168.70.138 + volumes: + - ./ausf-healthcheck.sh:/openair-ausf/bin/ausf-healthcheck.sh + healthcheck: + test: /bin/bash -c "/openair-ausf/bin/ausf-healthcheck.sh" + interval: 10s + timeout: 5s + retries: 5 + oai-nrf: + container_name: "oai-nrf" + image: oai-nrf:develop + environment: + - NRF_INTERFACE_NAME_FOR_SBI=eth0 + - NRF_INTERFACE_PORT_FOR_SBI=80 + - NRF_INTERFACE_HTTP2_PORT_FOR_SBI=9090 + - NRF_API_VERSION=v1 + - INSTANCE=0 + - PID_DIRECTORY=/var/run + networks: + public_net: + ipv4_address: 192.168.70.130 + volumes: + - ./nrf-healthcheck.sh:/openair-nrf/bin/nrf-healthcheck.sh + healthcheck: + test: /bin/bash -c "/openair-nrf/bin/nrf-healthcheck.sh" + interval: 10s + timeout: 5s + retries: 5 + oai-amf: + container_name: "oai-amf" + image: oai-amf:develop + environment: + - TZ=Europe/paris + - INSTANCE=0 + - PID_DIRECTORY=/var/run + - MCC=208 + - MNC=99 + - REGION_ID=128 + - AMF_SET_ID=1 + - SERVED_GUAMI_MCC_0=208 + - SERVED_GUAMI_MNC_0=99 + - SERVED_GUAMI_REGION_ID_0=128 + - SERVED_GUAMI_AMF_SET_ID_0=1 + - SERVED_GUAMI_MCC_1=460 + - SERVED_GUAMI_MNC_1=11 + - SERVED_GUAMI_REGION_ID_1=10 + - SERVED_GUAMI_AMF_SET_ID_1=1 + - PLMN_SUPPORT_MCC=208 + - PLMN_SUPPORT_MNC=99 + - PLMN_SUPPORT_TAC=0x0001 + - SST_0=1 + - SD_0=1 + - SST_1=1 + - SD_1=12 + - AMF_INTERFACE_NAME_FOR_NGAP=eth0 + - AMF_INTERFACE_NAME_FOR_N11=eth0 + - SMF_INSTANCE_ID_0=1 + - SMF_FQDN_0=oai-smf + - SMF_IPV4_ADDR_0=192.168.70.133 + - SMF_HTTP_VERSION_0=v1 + - SELECTED_0=true + - SMF_INSTANCE_ID_1=2 + - SMF_FQDN_1=oai-smf + - SMF_IPV4_ADDR_1=0.0.0.0 + - SMF_HTTP_VERSION_1=v1 + - SELECTED_1=false + - MYSQL_SERVER=192.168.70.131 + - MYSQL_USER=root + - MYSQL_PASS=linux + - MYSQL_DB=oai_db + - OPERATOR_KEY=1006020f0a478bf6b699f15c062e42b3 + - NRF_IPV4_ADDRESS=192.168.70.130 + - NRF_PORT=80 + - NF_REGISTRATION=yes + - SMF_SELECTION=yes + - USE_FQDN_DNS=yes + - EXTERNAL_AUSF=yes + - NRF_API_VERSION=v1 + - NRF_FQDN=oai-nrf + - AUSF_IPV4_ADDRESS=192.168.70.138 + - AUSF_PORT=80 + - AUSF_API_VERSION=v1 + - AUSF_FQDN=oai-ausf + depends_on: + - mysql + - oai-nrf + - oai-ausf + volumes: + - ./amf-healthcheck.sh:/openair-amf/bin/amf-healthcheck.sh + healthcheck: + test: /bin/bash -c "/openair-amf/bin/amf-healthcheck.sh" + interval: 10s + timeout: 15s + retries: 5 + networks: + public_net: + ipv4_address: 192.168.70.132 + oai-smf: + container_name: "oai-smf" + image: oai-smf:develop + environment: + - TZ=Europe/Paris + - INSTANCE=0 + - PID_DIRECTORY=/var/run + - SMF_INTERFACE_NAME_FOR_N4=eth0 + - SMF_INTERFACE_NAME_FOR_SBI=eth0 + - SMF_INTERFACE_PORT_FOR_SBI=80 + - SMF_INTERFACE_HTTP2_PORT_FOR_SBI=9090 + - SMF_API_VERSION=v1 + - DEFAULT_DNS_IPV4_ADDRESS=8.8.8.8 + - DEFAULT_DNS_SEC_IPV4_ADDRESS=4.4.4.4 + - AMF_IPV4_ADDRESS=192.168.70.132 + - AMF_PORT=80 + - AMF_API_VERSION=v1 + - AMF_FQDN=oai-amf + - UDM_IPV4_ADDRESS=192.168.70.137 + - UDM_PORT=80 + - UDM_API_VERSION=v1 + - UDM_FQDN=oai-udm + - UPF_IPV4_ADDRESS=192.168.70.134 + - UPF_FQDN_0=oai-spgwu + - NRF_IPV4_ADDRESS=192.168.70.130 + - NRF_PORT=80 + - NRF_API_VERSION=v1 + - USE_LOCAL_SUBSCRIPTION_INFO=yes + - NRF_FQDN=oai-nrf + - REGISTER_NRF=yes + - DISCOVER_UPF=yes + - USE_FQDN_DNS=yes + - DNN_RANGE1=12.1.1.2 - 12.1.1.128 + - DNN_RANGE0=12.2.1.2 - 12.2.1.128 + - DNN_NI1=oai + depends_on: + - oai-nrf + - oai-amf + volumes: + - ./smf-healthcheck.sh:/openair-smf/bin/smf-healthcheck.sh + healthcheck: + test: /bin/bash -c "/openair-smf/bin/smf-healthcheck.sh" + interval: 10s + timeout: 5s + retries: 5 + networks: + public_net: + ipv4_address: 192.168.70.133 + oai-spgwu: + container_name: "oai-spgwu" + image: oai-spgwu-tiny:develop + environment: + - TZ=Europe/Paris + - PID_DIRECTORY=/var/run + - SGW_INTERFACE_NAME_FOR_S1U_S12_S4_UP=eth0 + - SGW_INTERFACE_NAME_FOR_SX=eth0 + - PGW_INTERFACE_NAME_FOR_SGI=eth0 + - NETWORK_UE_NAT_OPTION=yes + - NETWORK_UE_IP=12.1.1.0/24 + - SPGWC0_IP_ADDRESS=192.168.70.133 + - BYPASS_UL_PFCP_RULES=no + - MCC=208 + - MNC=99 + - MNC03=099 + - TAC=1 + - GW_ID=1 + - REALM=openairinterface.org + - ENABLE_5G_FEATURES=yes + - REGISTER_NRF=yes + - USE_FQDN_NRF=no + - UPF_FQDN_5G=oai-spgwu + - NRF_IPV4_ADDRESS=192.168.70.130 + - NRF_PORT=80 + - NRF_API_VERSION=v1 + - NRF_FQDN=oai-nrf + - NSSAI_SST_0=1 + - NSSAI_SD_0=1 + - DNN_0=oai + depends_on: + - oai-nrf + - oai-smf + cap_add: + - NET_ADMIN + - SYS_ADMIN + cap_drop: + - ALL + privileged: true + volumes: + - ./spgwu-healthcheck.sh:/openair-spgwu-tiny/bin/spgwu-healthcheck.sh + healthcheck: + test: /bin/bash -c "/openair-spgwu-tiny/bin/spgwu-healthcheck.sh" + interval: 10s + timeout: 5s + retries: 5 + networks: + public_net: + ipv4_address: 192.168.70.134 + oai-ext-dn: + image: ubuntu:bionic + privileged: true + container_name: oai-ext-dn + entrypoint: /bin/bash -c \ + "apt update; apt install -y iptables iproute2 iperf iperf3 iputils-ping;"\ + "iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE;"\ + "ip route add 12.1.1.0/24 via 192.168.70.134 dev eth0; sleep infinity" + depends_on: + - oai-spgwu + networks: + public_net: + ipv4_address: 192.168.70.135 +networks: + public_net: + external: + name: demo-oai-public-net +# public_net: +# driver: bridge +# name: demo-oai-public-net +# ipam: +# config: +# - subnet: 192.168.70.128/26 +# driver_opts: +# com.docker.network.bridge.name: "demo-oai" diff --git a/doc/tutorial_resources/oai_db.sql b/doc/tutorial_resources/oai_db.sql new file mode 100644 index 0000000000000000000000000000000000000000..e019c60e8623b9779e3f6d43053fd3ed69a31472 --- /dev/null +++ b/doc/tutorial_resources/oai_db.sql @@ -0,0 +1,312 @@ +-- phpMyAdmin SQL Dump +-- version 5.1.0 +-- https://www.phpmyadmin.net/ +-- +-- Host: 172.16.200.10:3306 +-- Generation Time: Mar 22, 2021 at 10:31 AM +-- Server version: 5.7.33 +-- PHP Version: 7.4.15 + +SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; +START TRANSACTION; +SET time_zone = "+00:00"; + + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8mb4 */; + +-- +-- Database: `oai_db` +-- + +-- -------------------------------------------------------- + +-- +-- Table structure for table `AccessAndMobilitySubscriptionData` +-- + +CREATE TABLE `AccessAndMobilitySubscriptionData` ( + `ueid` varchar(15) NOT NULL, + `servingPlmnid` varchar(15) NOT NULL, + `supportedFeatures` varchar(50) DEFAULT NULL, + `gpsis` json DEFAULT NULL, + `internalGroupIds` json DEFAULT NULL, + `sharedVnGroupDataIds` json DEFAULT NULL, + `subscribedUeAmbr` json DEFAULT NULL, + `nssai` json DEFAULT NULL, + `ratRestrictions` json DEFAULT NULL, + `forbiddenAreas` json DEFAULT NULL, + `serviceAreaRestriction` json DEFAULT NULL, + `coreNetworkTypeRestrictions` json DEFAULT NULL, + `rfspIndex` int(10) DEFAULT NULL, + `subsRegTimer` int(10) DEFAULT NULL, + `ueUsageType` int(10) DEFAULT NULL, + `mpsPriority` tinyint(1) DEFAULT NULL, + `mcsPriority` tinyint(1) DEFAULT NULL, + `activeTime` int(10) DEFAULT NULL, + `sorInfo` json DEFAULT NULL, + `sorInfoExpectInd` tinyint(1) DEFAULT NULL, + `sorafRetrieval` tinyint(1) DEFAULT NULL, + `sorUpdateIndicatorList` json DEFAULT NULL, + `upuInfo` json DEFAULT NULL, + `micoAllowed` tinyint(1) DEFAULT NULL, + `sharedAmDataIds` json DEFAULT NULL, + `odbPacketServices` json DEFAULT NULL, + `serviceGapTime` int(10) DEFAULT NULL, + `mdtUserConsent` json DEFAULT NULL, + `mdtConfiguration` json DEFAULT NULL, + `traceData` json DEFAULT NULL, + `cagData` json DEFAULT NULL, + `stnSr` varchar(50) DEFAULT NULL, + `cMsisdn` varchar(50) DEFAULT NULL, + `nbIoTUePriority` int(10) DEFAULT NULL, + `nssaiInclusionAllowed` tinyint(1) DEFAULT NULL, + `rgWirelineCharacteristics` varchar(50) DEFAULT NULL, + `ecRestrictionDataWb` json DEFAULT NULL, + `ecRestrictionDataNb` tinyint(1) DEFAULT NULL, + `expectedUeBehaviourList` json DEFAULT NULL, + `primaryRatRestrictions` json DEFAULT NULL, + `secondaryRatRestrictions` json DEFAULT NULL, + `edrxParametersList` json DEFAULT NULL, + `ptwParametersList` json DEFAULT NULL, + `iabOperationAllowed` tinyint(1) DEFAULT NULL, + `wirelineForbiddenAreas` json DEFAULT NULL, + `wirelineServiceAreaRestriction` json DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `Amf3GppAccessRegistration` +-- + +CREATE TABLE `Amf3GppAccessRegistration` ( + `ueid` varchar(15) NOT NULL, + `amfInstanceId` varchar(50) NOT NULL, + `supportedFeatures` varchar(50) DEFAULT NULL, + `purgeFlag` tinyint(1) DEFAULT NULL, + `pei` varchar(50) DEFAULT NULL, + `imsVoPs` json DEFAULT NULL, + `deregCallbackUri` varchar(50) NOT NULL, + `amfServiceNameDereg` json DEFAULT NULL, + `pcscfRestorationCallbackUri` varchar(50) DEFAULT NULL, + `amfServiceNamePcscfRest` json DEFAULT NULL, + `initialRegistrationInd` tinyint(1) DEFAULT NULL, + `guami` json NOT NULL, + `backupAmfInfo` json DEFAULT NULL, + `drFlag` tinyint(1) DEFAULT NULL, + `ratType` json NOT NULL, + `urrpIndicator` tinyint(1) DEFAULT NULL, + `amfEeSubscriptionId` varchar(50) DEFAULT NULL, + `epsInterworkingInfo` json DEFAULT NULL, + `ueSrvccCapability` tinyint(1) DEFAULT NULL, + `registrationTime` varchar(50) DEFAULT NULL, + `vgmlcAddress` json DEFAULT NULL, + `contextInfo` json DEFAULT NULL, + `noEeSubscriptionInd` tinyint(1) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `AuthenticationStatus` +-- + +CREATE TABLE `AuthenticationStatus` ( + `ueid` varchar(20) NOT NULL, + `nfInstanceId` varchar(50) NOT NULL, + `success` tinyint(1) NOT NULL, + `timeStamp` varchar(50) NOT NULL, + `authType` varchar(25) NOT NULL, + `servingNetworkName` varchar(50) NOT NULL, + `authRemovalInd` tinyint(1) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `AuthenticationSubscription` +-- + +CREATE TABLE `AuthenticationSubscription` ( + `ueid` varchar(20) NOT NULL, + `authenticationMethod` varchar(25) NOT NULL, + `encPermanentKey` varchar(50) DEFAULT NULL, + `protectionParameterId` varchar(50) DEFAULT NULL, + `sequenceNumber` json DEFAULT NULL, + `authenticationManagementField` varchar(50) DEFAULT NULL, + `algorithmId` varchar(50) DEFAULT NULL, + `encOpcKey` varchar(50) DEFAULT NULL, + `encTopcKey` varchar(50) DEFAULT NULL, + `vectorGenerationInHss` tinyint(1) DEFAULT NULL, + `n5gcAuthMethod` varchar(15) DEFAULT NULL, + `rgAuthenticationInd` tinyint(1) DEFAULT NULL, + `supi` varchar(20) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `AuthenticationSubscription` +-- + +INSERT INTO `AuthenticationSubscription` (`ueid`, `authenticationMethod`, `encPermanentKey`, `protectionParameterId`, `sequenceNumber`, `authenticationManagementField`, `algorithmId`, `encOpcKey`, `encTopcKey`, `vectorGenerationInHss`, `n5gcAuthMethod`, `rgAuthenticationInd`, `supi`) VALUES +('208950000000031', '5G_AKA', '0C0A34601D4F07677303652C0462535B', '0C0A34601D4F07677303652C0462535B', '{\"sqn\": \"000000000020\", \"sqnScheme\": \"NON_TIME_BASED\", \"lastIndexes\": {\"ausf\": 0}}', '8000', 'milenage', '63bfa50ee6523365ff14c1f45f88737d', NULL, NULL, NULL, NULL, '208950000000031'); + +INSERT INTO `AuthenticationSubscription` (`ueid`, `authenticationMethod`, `encPermanentKey`, `protectionParameterId`, `sequenceNumber`, `authenticationManagementField`, `algorithmId`, `encOpcKey`, `encTopcKey`, `vectorGenerationInHss`, `n5gcAuthMethod`, `rgAuthenticationInd`, `supi`) VALUES +('208990000000001', '5G_AKA', 'fec86ba6eb707ed08905757b1bb44b8f', 'fec86ba6eb707ed08905757b1bb44b8f', '{\"sqn\": \"000000000020\", \"sqnScheme\": \"NON_TIME_BASED\", \"lastIndexes\": {\"ausf\": 0}}', '8000', 'milenage', 'C42449363BBAD02B66D16BC975D77CC1', NULL, NULL, NULL, NULL, '208990000000001'); + +-- -------------------------------------------------------- + +-- +-- Table structure for table `SdmSubscriptions` +-- + +CREATE TABLE `SdmSubscriptions` ( + `ueid` varchar(15) NOT NULL, + `subsId` int(10) UNSIGNED NOT NULL, + `nfInstanceId` varchar(50) NOT NULL, + `implicitUnsubscribe` tinyint(1) DEFAULT NULL, + `expires` varchar(50) DEFAULT NULL, + `callbackReference` varchar(50) NOT NULL, + `amfServiceName` json DEFAULT NULL, + `monitoredResourceUris` json NOT NULL, + `singleNssai` json DEFAULT NULL, + `dnn` varchar(50) DEFAULT NULL, + `subscriptionId` varchar(50) DEFAULT NULL, + `plmnId` json DEFAULT NULL, + `immediateReport` tinyint(1) DEFAULT NULL, + `report` json DEFAULT NULL, + `supportedFeatures` varchar(50) DEFAULT NULL, + `contextInfo` json DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `SessionManagementSubscriptionData` +-- + +CREATE TABLE `SessionManagementSubscriptionData` ( + `ueid` varchar(15) NOT NULL, + `servingPlmnid` varchar(15) NOT NULL, + `singleNssai` json NOT NULL, + `dnnConfigurations` json DEFAULT NULL, + `internalGroupIds` json DEFAULT NULL, + `sharedVnGroupDataIds` json DEFAULT NULL, + `sharedDnnConfigurationsId` varchar(50) DEFAULT NULL, + `odbPacketServices` json DEFAULT NULL, + `traceData` json DEFAULT NULL, + `sharedTraceDataId` varchar(50) DEFAULT NULL, + `expectedUeBehavioursList` json DEFAULT NULL, + `suggestedPacketNumDlList` json DEFAULT NULL, + `3gppChargingCharacteristics` varchar(50) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `SmfRegistrations` +-- + +CREATE TABLE `SmfRegistrations` ( + `ueid` varchar(15) NOT NULL, + `subpduSessionId` int(10) NOT NULL, + `smfInstanceId` varchar(50) NOT NULL, + `smfSetId` varchar(50) DEFAULT NULL, + `supportedFeatures` varchar(50) DEFAULT NULL, + `pduSessionId` int(10) NOT NULL, + `singleNssai` json NOT NULL, + `dnn` varchar(50) DEFAULT NULL, + `emergencyServices` tinyint(1) DEFAULT NULL, + `pcscfRestorationCallbackUri` varchar(50) DEFAULT NULL, + `plmnId` json NOT NULL, + `pgwFqdn` varchar(50) DEFAULT NULL, + `epdgInd` tinyint(1) DEFAULT NULL, + `deregCallbackUri` varchar(50) DEFAULT NULL, + `registrationReason` json DEFAULT NULL, + `registrationTime` varchar(50) DEFAULT NULL, + `contextInfo` json DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `SmfSelectionSubscriptionData` +-- + +CREATE TABLE `SmfSelectionSubscriptionData` ( + `ueid` varchar(15) NOT NULL, + `servingPlmnid` varchar(15) NOT NULL, + `supportedFeatures` varchar(50) DEFAULT NULL, + `subscribedSnssaiInfos` json DEFAULT NULL, + `sharedSnssaiInfosId` varchar(50) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Indexes for dumped tables +-- + +-- +-- Indexes for table `AccessAndMobilitySubscriptionData` +-- +ALTER TABLE `AccessAndMobilitySubscriptionData` + ADD PRIMARY KEY (`ueid`,`servingPlmnid`) USING BTREE; + +-- +-- Indexes for table `Amf3GppAccessRegistration` +-- +ALTER TABLE `Amf3GppAccessRegistration` + ADD PRIMARY KEY (`ueid`); + +-- +-- Indexes for table `AuthenticationStatus` +-- +ALTER TABLE `AuthenticationStatus` + ADD PRIMARY KEY (`ueid`); + +-- +-- Indexes for table `AuthenticationSubscription` +-- +ALTER TABLE `AuthenticationSubscription` + ADD PRIMARY KEY (`ueid`); + +-- +-- Indexes for table `SdmSubscriptions` +-- +ALTER TABLE `SdmSubscriptions` + ADD PRIMARY KEY (`subsId`,`ueid`) USING BTREE; + +-- +-- Indexes for table `SessionManagementSubscriptionData` +-- +ALTER TABLE `SessionManagementSubscriptionData` + ADD PRIMARY KEY (`ueid`,`servingPlmnid`) USING BTREE; + +-- +-- Indexes for table `SmfRegistrations` +-- +ALTER TABLE `SmfRegistrations` + ADD PRIMARY KEY (`ueid`,`subpduSessionId`) USING BTREE; + +-- +-- Indexes for table `SmfSelectionSubscriptionData` +-- +ALTER TABLE `SmfSelectionSubscriptionData` + ADD PRIMARY KEY (`ueid`,`servingPlmnid`) USING BTREE; + +-- +-- AUTO_INCREMENT for dumped tables +-- + +-- +-- AUTO_INCREMENT for table `SdmSubscriptions` +-- +ALTER TABLE `SdmSubscriptions` + MODIFY `subsId` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=3; +COMMIT; + +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; + diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index 8ea7f167121c080d52a2ff4bd20d06f29cc4a7c9..327c01af6a29a80a7051253e08299847351e2961 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -304,32 +304,36 @@ void rx_func(void *param) { ); #endif } -static void dump_L1_meas_stats(PHY_VARS_gNB *gNB, RU_t *ru, char *output) { - int stroff = 0; - stroff += print_meas_log(&gNB->phy_proc_tx, "L1 Tx processing", NULL, NULL, output); - stroff += print_meas_log(&gNB->dlsch_encoding_stats, "DLSCH encoding", NULL, NULL, output+stroff); - stroff += print_meas_log(&gNB->phy_proc_rx, "L1 Rx processing", NULL, NULL, output+stroff); - stroff += print_meas_log(&gNB->ul_indication_stats, "UL Indication", NULL, NULL, output+stroff); - stroff += print_meas_log(&gNB->rx_pusch_stats, "PUSCH inner-receiver", NULL, NULL, output+stroff); - stroff += print_meas_log(&gNB->ulsch_decoding_stats, "PUSCH decoding", NULL, NULL, output+stroff); - stroff += print_meas_log(&gNB->schedule_response_stats, "Schedule Response",NULL,NULL, output+stroff); - if (ru->feprx) stroff += print_meas_log(&ru->ofdm_demod_stats,"feprx",NULL,NULL, output+stroff); +static size_t dump_L1_meas_stats(PHY_VARS_gNB *gNB, RU_t *ru, char *output, size_t outputlen) { + const char *begin = output; + const char *end = output + outputlen; + output += print_meas_log(&gNB->phy_proc_tx, "L1 Tx processing", NULL, NULL, output, end - output); + output += print_meas_log(&gNB->dlsch_encoding_stats, "DLSCH encoding", NULL, NULL, output, end - output); + output += print_meas_log(&gNB->phy_proc_rx, "L1 Rx processing", NULL, NULL, output, end - output); + output += print_meas_log(&gNB->ul_indication_stats, "UL Indication", NULL, NULL, output, end - output); + output += print_meas_log(&gNB->rx_pusch_stats, "PUSCH inner-receiver", NULL, NULL, output, end - output); + output += print_meas_log(&gNB->ulsch_decoding_stats, "PUSCH decoding", NULL, NULL, output, end - output); + output += print_meas_log(&gNB->schedule_response_stats, "Schedule Response", NULL, NULL, output, end - output); + if (ru->feprx) + output += print_meas_log(&ru->ofdm_demod_stats, "feprx", NULL, NULL, output, end - output); if (ru->feptx_ofdm) { - stroff += print_meas_log(&ru->precoding_stats,"feptx_prec",NULL,NULL, output+stroff); - stroff += print_meas_log(&ru->txdataF_copy_stats,"txdataF_copy",NULL,NULL, output+stroff); - stroff += print_meas_log(&ru->ofdm_mod_stats,"feptx_ofdm",NULL,NULL, output+stroff); - stroff += print_meas_log(&ru->ofdm_total_stats,"feptx_total",NULL,NULL, output+stroff); + output += print_meas_log(&ru->precoding_stats,"feptx_prec",NULL,NULL, output, end - output); + output += print_meas_log(&ru->txdataF_copy_stats,"txdataF_copy",NULL,NULL, output, end - output); + output += print_meas_log(&ru->ofdm_mod_stats,"feptx_ofdm",NULL,NULL, output, end - output); + output += print_meas_log(&ru->ofdm_total_stats,"feptx_total",NULL,NULL, output, end - output); } - if (ru->fh_north_asynch_in) stroff += print_meas_log(&ru->rx_fhaul,"rx_fhaul",NULL,NULL, output+stroff); + if (ru->fh_north_asynch_in) + output += print_meas_log(&ru->rx_fhaul,"rx_fhaul",NULL,NULL, output, end - output); - stroff += print_meas_log(&ru->tx_fhaul,"tx_fhaul",NULL,NULL, output+stroff); + output += print_meas_log(&ru->tx_fhaul,"tx_fhaul",NULL,NULL, output, end - output); if (ru->fh_north_out) { - stroff += print_meas_log(&ru->compression,"compression",NULL,NULL, output+stroff); - stroff += print_meas_log(&ru->transport,"transport",NULL,NULL, output+stroff); + output += print_meas_log(&ru->compression,"compression",NULL,NULL, output, end - output); + output += print_meas_log(&ru->transport,"transport",NULL,NULL, output, end - output); } + return output - begin; } void *nrL1_stats_thread(void *param) { @@ -355,7 +359,7 @@ void *nrL1_stats_thread(void *param) { dump_nr_I0_stats(fd,gNB); dump_pdsch_stats(fd,gNB); dump_pusch_stats(fd,gNB); - dump_L1_meas_stats(gNB, ru, output); + dump_L1_meas_stats(gNB, ru, output, L1STATSSTRLEN); fprintf(fd,"%s\n",output); fflush(fd); fseek(fd,0,SEEK_SET); @@ -380,7 +384,7 @@ void *tx_reorder_thread(void* param) { if (resL1Reserve) { resL1=resL1Reserve; if (((processingData_L1tx_t *)NotifiedFifoData(resL1))->slot != next_tx_slot) { - LOG_E(PHY,"order mistake"); + LOG_E(PHY,"order mistake\n"); resL1Reserve=NULL; resL1 = pullTpool(gNB->L1_tx_out, gNB->threadPool); } @@ -600,7 +604,8 @@ void init_gNB(int single_thread_flag,int wait_for_sync) { gNB->UL_INFO.cqi_ind.cqi_raw_pdu_list = gNB->cqi_raw_pdu_list;*/ gNB->prach_energy_counter = 0; - gNB->prb_interpolation = get_softmodem_params()->prb_interpolation; + gNB->chest_time = get_softmodem_params()->chest_time; + gNB->chest_freq = get_softmodem_params()->chest_freq; } diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 6e1864f290b9d13d61f91598eeb414c7d5d8ac39..01e6c6213845563d4618848c7a34d1dedb7b66e9 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -106,23 +106,24 @@ queue_t nr_rach_ind_queue; static void *NRUE_phy_stub_standalone_pnf_task(void *arg); -static int dump_L1_UE_meas_stats(PHY_VARS_NR_UE *ue, char *output, int max_len) +static size_t dump_L1_UE_meas_stats(PHY_VARS_NR_UE *ue, char *output, size_t max_len) { - int stroff = 0; - stroff += print_meas_log(&ue->phy_proc_tx, "L1 TX processing", NULL, NULL, output); - stroff += print_meas_log(&ue->ulsch_encoding_stats, "ULSCH encoding", NULL, NULL, output + stroff); - stroff += print_meas_log(&ue->phy_proc_rx[0], "L1 RX processing t0", NULL, NULL, output + stroff); - stroff += print_meas_log(&ue->phy_proc_rx[1], "L1 RX processing t1", NULL, NULL, output + stroff); - stroff += print_meas_log(&ue->ue_ul_indication_stats, "UL Indication", NULL, NULL, output + stroff); - stroff += print_meas_log(&ue->rx_pdsch_stats, "PDSCH receiver", NULL, NULL, output + stroff); - stroff += print_meas_log(&ue->dlsch_decoding_stats[0], "PDSCH decoding t0", NULL, NULL, output + stroff); - stroff += print_meas_log(&ue->dlsch_decoding_stats[1], "PDSCH decoding t1", NULL, NULL, output + stroff); - stroff += print_meas_log(&ue->dlsch_deinterleaving_stats, " -> Deinterleive", NULL, NULL, output + stroff); - stroff += print_meas_log(&ue->dlsch_rate_unmatching_stats, " -> Rate Unmatch", NULL, NULL, output + stroff); - stroff += print_meas_log(&ue->dlsch_ldpc_decoding_stats, " -> LDPC Decode", NULL, NULL, output + stroff); - stroff += print_meas_log(&ue->dlsch_unscrambling_stats, "PDSCH unscrambling", NULL, NULL, output + stroff); - stroff += print_meas_log(&ue->dlsch_rx_pdcch_stats, "PDCCH handling", NULL, NULL, output + stroff); - return stroff; + const char *begin = output; + const char *end = output + max_len; + output += print_meas_log(&ue->phy_proc_tx, "L1 TX processing", NULL, NULL, output, end - output); + output += print_meas_log(&ue->ulsch_encoding_stats, "ULSCH encoding", NULL, NULL, output, end - output); + output += print_meas_log(&ue->phy_proc_rx[0], "L1 RX processing t0", NULL, NULL, output, end - output); + output += print_meas_log(&ue->phy_proc_rx[1], "L1 RX processing t1", NULL, NULL, output, end - output); + output += print_meas_log(&ue->ue_ul_indication_stats, "UL Indication", NULL, NULL, output, end - output); + output += print_meas_log(&ue->rx_pdsch_stats, "PDSCH receiver", NULL, NULL, output, end - output); + output += print_meas_log(&ue->dlsch_decoding_stats[0], "PDSCH decoding t0", NULL, NULL, output, end - output); + output += print_meas_log(&ue->dlsch_decoding_stats[1], "PDSCH decoding t1", NULL, NULL, output, end - output); + output += print_meas_log(&ue->dlsch_deinterleaving_stats, " -> Deinterleive", NULL, NULL, output, end - output); + output += print_meas_log(&ue->dlsch_rate_unmatching_stats, " -> Rate Unmatch", NULL, NULL, output, end - output); + output += print_meas_log(&ue->dlsch_ldpc_decoding_stats, " -> LDPC Decode", NULL, NULL, output, end - output); + output += print_meas_log(&ue->dlsch_unscrambling_stats, "PDSCH unscrambling", NULL, NULL, output, end - output); + output += print_meas_log(&ue->dlsch_rx_pdcch_stats, "PDCCH handling", NULL, NULL, output, end - output); + return output - begin; } static void *nrL1_UE_stats_thread(void *param) diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 234705540273ac85571d27a216ac910a0e9c2dde..de3c1088412f657081a73ea4978ba5ad657e20d0 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -259,13 +259,11 @@ void init_tpools(uint8_t nun_dlsch_threads) { } static void get_options(void) { - nrUE_params.ofdm_offset_divisor = 8; paramdef_t cmdline_params[] =CMDLINE_NRUEPARAMS_DESC ; int numparams = sizeof(cmdline_params)/sizeof(paramdef_t); + config_get(cmdline_params,numparams,NULL); config_process_cmdline( cmdline_params,numparams,NULL); - - if (vcdflag > 0) ouput_vcd = 1; } @@ -317,8 +315,8 @@ void set_options(int CC_id, PHY_VARS_NR_UE *UE){ UE->rf_map.card = card_offset; UE->rf_map.chain = CC_id + chain_offset; - LOG_I(PHY,"Set UE mode %d, UE_fo_compensation %d, UE_scan_carrier %d, UE_no_timing_correction %d \n, do_prb_interpolation %d\n", - UE->mode, UE->UE_fo_compensation, UE->UE_scan_carrier, UE->no_timing_correction, UE->prb_interpolation); + LOG_I(PHY,"Set UE mode %d, UE_fo_compensation %d, UE_scan_carrier %d, UE_no_timing_correction %d \n, chest-freq %d\n", + UE->mode, UE->UE_fo_compensation, UE->UE_scan_carrier, UE->no_timing_correction, UE->chest_freq); // Set FP variables @@ -330,6 +328,7 @@ void set_options(int CC_id, PHY_VARS_NR_UE *UE){ LOG_I(PHY, "Set UE nb_rx_antenna %d, nb_tx_antenna %d, threequarter_fs %d, ssb_start_subcarrier %d\n", fp->nb_antennas_rx, fp->nb_antennas_tx, fp->threequarter_fs, fp->ssb_start_subcarrier); fp->ofdm_offset_divisor = nrUE_params.ofdm_offset_divisor; + UE->max_ldpc_iterations = nrUE_params.max_ldpc_iterations; } diff --git a/executables/nr-uesoftmodem.h b/executables/nr-uesoftmodem.h index 95914678e5ba84418d7d65ab1c04510e9b664fc6..995d81f19c7aff8dcea7120ef1354e2047b1a3a2 100644 --- a/executables/nr-uesoftmodem.h +++ b/executables/nr-uesoftmodem.h @@ -7,10 +7,11 @@ -#define CONFIG_HLP_IF_FREQ "IF frequency for RF, if needed" -#define CONFIG_HLP_IF_FREQ_OFF "UL IF frequency offset for RF, if needed" +#define CONFIG_HLP_IF_FREQ "IF frequency for RF, if needed\n" +#define CONFIG_HLP_IF_FREQ_OFF "UL IF frequency offset for RF, if needed\n" #define CONFIG_HLP_DLSCH_PARA "number of threads for dlsch processing 0 for no parallelization\n" #define CONFIG_HLP_OFFSET_DIV "Divisor for computing OFDM symbol offset in Rx chain (num samples in CP/<the value>). Default value is 8. To set the sample offset to 0, set this value ~ 10e6\n" +#define CONFIG_HLP_MAX_LDPC_ITERATIONS "Maximum LDPC decoder iterations\n" /***************************************************************************************************************************************/ /* command line options definitions, CMDLINE_XXXX_DESC macros are used to initialize paramdef_t arrays which are then used as argument when calling config_get or config_getlist functions */ @@ -30,8 +31,9 @@ #define CMDLINE_NRUEPARAMS_DESC { \ {"usrp-args", CONFIG_HLP_USRP_ARGS, 0, strptr:(char **)&usrp_args, defstrval:"type=b200", TYPE_STRING, 0}, \ {"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&single_thread_flag, defintval:1, TYPE_INT, 0}, \ - {"dlsch-parallel", CONFIG_HLP_DLSCH_PARA, 0, iptr:(int32_t *)&nrUE_params.nr_dlsch_parallel, defintval:0, TYPE_UINT8, 0}, \ - {"offset-divisor", CONFIG_HLP_OFFSET_DIV, 0, uptr:(uint32_t *)&nrUE_params.ofdm_offset_divisor, defuintval:UINT_MAX, TYPE_UINT32, 0}, \ + {"dlsch-parallel", CONFIG_HLP_DLSCH_PARA, 0, u8ptr:&nrUE_params.nr_dlsch_parallel, defintval:0, TYPE_UINT8, 0}, \ + {"offset-divisor", CONFIG_HLP_OFFSET_DIV, 0, uptr:&nrUE_params.ofdm_offset_divisor, defuintval:8, TYPE_UINT32, 0}, \ + {"max-ldpc-iterations", CONFIG_HLP_MAX_LDPC_ITERATIONS, 0, u8ptr:&nrUE_params.max_ldpc_iterations, defuintval:5, TYPE_UINT8, 0}, \ {"nr-dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&nr_dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \ {"V" , CONFIG_HLP_VCD, PARAMFLAG_BOOL, iptr:&vcdflag, defintval:0, TYPE_INT, 0}, \ {"uecap_file", CONFIG_HLP_UECAP_FILE, 0, strptr:(char **)&uecap_file, defstrval:"./uecap.xml", TYPE_STRING, 0}, \ @@ -67,7 +69,8 @@ {"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, iptr:&tddflag, defintval:0, TYPE_INT, 0}, \ {"if_freq" , CONFIG_HLP_IF_FREQ, 0, u64ptr:&(UE->if_freq), defuintval:0, TYPE_UINT64,0}, \ {"if_freq_off" , CONFIG_HLP_IF_FREQ_OFF, 0, iptr:&(UE->if_freq_off), defuintval:0, TYPE_INT, 0}, \ - {"do-prb-interpolation", CONFIG_HLP_PRBINTER, PARAMFLAG_BOOL, iptr:&(UE->prb_interpolation), defintval:0, TYPE_INT, 0}, \ + {"chest-freq", CONFIG_HLP_CHESTFREQ, 0, iptr:&(UE->chest_freq), defintval:0, TYPE_INT, 0}, \ + {"chest-time", CONFIG_HLP_CHESTTIME, 0, iptr:&(UE->chest_time), defintval:0, TYPE_INT, 0}, \ {"ue-timing-correction-disable", CONFIG_HLP_DISABLETIMECORR, PARAMFLAG_BOOL, iptr:&(UE->no_timing_correction), defintval:0, TYPE_INT, 0}, \ } @@ -76,6 +79,7 @@ typedef struct { uint64_t optmask; //mask to store boolean config options uint32_t ofdm_offset_divisor; // Divisor for sample offset computation for each OFDM symbol uint8_t nr_dlsch_parallel; // number of threads for dlsch decoding, 0 means no parallelization + uint8_t max_ldpc_iterations; // number of maximum LDPC iterations tpool_t Tpool; // thread pool } nrUE_params_t; extern uint64_t get_nrUE_optmask(void); diff --git a/executables/softmodem-common.h b/executables/softmodem-common.h index 72a9491f27f5817337f81961dc01ee368db96488..6c5c6107238921949ce0cf3e447683c60fb582c7 100644 --- a/executables/softmodem-common.h +++ b/executables/softmodem-common.h @@ -72,7 +72,8 @@ extern "C" #define CONFIG_HLP_DLMCS "Set the maximum downlink MCS\n" #define CONFIG_HLP_STMON "Enable processing timing measurement of lte softmodem on per subframe basis \n" #define CONFIG_HLP_256QAM "Use the 256 QAM mcs table for PDSCH\n" -#define CONFIG_HLP_PRBINTER "Do PRB based averaging of channel estimates. Frequency domain linear interpolation by default\n" +#define CONFIG_HLP_CHESTFREQ "Set channel estimation type in frequency domain. 0-Linear interpolation (default). 1-PRB based averaging of channel estimates in frequency. \n" +#define CONFIG_HLP_CHESTTIME "Set channel estimation type in time domain. 0-Symbols take estimates of the last preceding DMRS symbol (default). 1-Symbol based averaging of channel estimates in time. \n" #define CONFIG_HLP_NONSTOP "Go back to frame sync mode after 100 consecutive PBCH failures\n" //#define CONFIG_HLP_NUMUES "Set the number of UEs for the emulation" @@ -122,7 +123,8 @@ extern "C" #define TUNE_OFFSET softmodem_params.tune_offset #define SEND_DMRSSYNC softmodem_params.send_dmrs_sync #define USIM_TEST softmodem_params.usim_test -#define PRB_INTERPOLATION softmodem_params.prb_interpolation +#define CHEST_FREQ softmodem_params.chest_freq +#define CHEST_TIME softmodem_params.chest_time #define NFAPI softmodem_params.nfapi #define NSA softmodem_params.nsa #define NODE_NUMBER softmodem_params.node_number @@ -160,10 +162,11 @@ extern int usrp_tx_thread; {"rfsim", CONFIG_HLP_RFSIM, PARAMFLAG_BOOL, uptr:&rfsim, defintval:0, TYPE_INT, 0}, \ {"nokrnmod", CONFIG_HLP_NOKRNMOD, PARAMFLAG_BOOL, uptr:&nokrnmod, defintval:0, TYPE_INT, 0}, \ {"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, uptr:&nonbiot, defuintval:0, TYPE_INT, 0}, \ + {"chest-freq", CONFIG_HLP_CHESTFREQ, 0, iptr:&CHEST_FREQ, defintval:0, TYPE_INT, 0}, \ + {"chest-time", CONFIG_HLP_CHESTTIME, 0, iptr:&CHEST_TIME, defintval:0, TYPE_INT, 0}, \ {"nsa", CONFIG_HLP_NSA, PARAMFLAG_BOOL, iptr:&NSA, defintval:0, TYPE_INT, 0}, \ {"node-number", NULL, 0, u16ptr:&NODE_NUMBER, defuintval:0, TYPE_UINT16, 0}, \ {"usrp-tx-thread-config", CONFIG_HLP_USRP_THREAD, 0, iptr:&usrp_tx_thread, defstrval:0, TYPE_INT, 0}, \ - {"do-prb-interpolation", CONFIG_HLP_PRBINTER, PARAMFLAG_BOOL, iptr:&PRB_INTERPOLATION, defintval:0, TYPE_INT, 0}, \ {"nfapi", CONFIG_HLP_NFAPI, 0, u8ptr:&nfapi_mode, defintval:0, TYPE_UINT8, 0}, \ {"non-stop", CONFIG_HLP_NONSTOP, PARAMFLAG_BOOL, iptr:&NON_STOP, defintval:0, TYPE_INT, 0}, \ {"emulate-l1", CONFIG_L1_EMULATOR, PARAMFLAG_BOOL, iptr:&EMULATE_L1, defintval:0, TYPE_INT, 0}, \ @@ -251,7 +254,9 @@ typedef struct { double tune_offset; int hw_timing_advance; uint32_t send_dmrs_sync; - int prb_interpolation; + int use_256qam_table; + int chest_time; + int chest_freq; uint8_t nfapi; int nsa; uint16_t node_number; diff --git a/openair1/PHY/CODING/coding_defs.h b/openair1/PHY/CODING/coding_defs.h index 9972a47ee7d9369eabdd7852ac10093cab9cc940..1854f28fa788f6602366f959b191486a861340ec 100644 --- a/openair1/PHY/CODING/coding_defs.h +++ b/openair1/PHY/CODING/coding_defs.h @@ -38,7 +38,6 @@ #define MAX_TURBO_ITERATIONS_MBSFN 8 #define MAX_TURBO_ITERATIONS max_turbo_iterations -#define MAX_LDPC_ITERATIONS 5 #define MAX_LDPC_ITERATIONS_MBSFN 4 #define LTE_NULL 2 diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index 56327a9b0fb7e3bb337abf7b3ecf45592f2b3372..e2139a9903c22871cfca7292c544b0a97a424fba 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -544,8 +544,8 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, gNB->nr_gold_pdsch_dmrs = (uint32_t ****)malloc16(fp->slots_per_frame*sizeof(uint32_t ***)); uint32_t ****pdsch_dmrs = gNB->nr_gold_pdsch_dmrs; - // ceil(((NB_RB*6(k)*2(QPSK)/32) // 3 RE *2(QPSK) - int pdsch_dmrs_init_length = ((fp->N_RB_DL*12)>>5)+1; + // ceil(((NB_RB*12(k)*2(QPSK)/32) // 3 RE *2(QPSK) + const int pdsch_dmrs_init_length = ((fp->N_RB_DL*24)>>5)+1; for (int slot=0; slot<fp->slots_per_frame; slot++) { pdsch_dmrs[slot] = (uint32_t ***)malloc16(fp->symbols_per_slot*sizeof(uint32_t **)); AssertFatal(pdsch_dmrs[slot]!=NULL, "NR init: pdsch_dmrs for slot %d - malloc failed\n", slot); @@ -1050,7 +1050,7 @@ void init_nr_transport(PHY_VARS_gNB *gNB) { LOG_I(PHY,"Allocating Transport Channel Buffers for ULSCH %d/%d\n",i,gNB->number_of_nr_ulsch_max); - gNB->ulsch[i] = new_gNB_ulsch(MAX_LDPC_ITERATIONS, fp->N_RB_UL); + gNB->ulsch[i] = new_gNB_ulsch(gNB->max_ldpc_iterations, fp->N_RB_UL); if (!gNB->ulsch[i]) { LOG_E(PHY,"Can't get gNB ulsch structures\n"); diff --git a/openair1/PHY/INIT/nr_init_ru.c b/openair1/PHY/INIT/nr_init_ru.c index b1a01fb3dc8531e6cdd6aa22a493f738b97f177c..c96aeab432477c356d5762cbd2e7d62f0d146383 100644 --- a/openair1/PHY/INIT/nr_init_ru.c +++ b/openair1/PHY/INIT/nr_init_ru.c @@ -60,7 +60,7 @@ int nr_phy_init_RU(RU_t *ru) { for (i=0; i<ru->nb_tx; i++) { // Allocate 10 subframes of I/Q TX signal data (time) if not - ru->common.txdata[i] = (int32_t*)malloc16_clear( ru->sf_extension + (fp->samples_per_frame*sizeof(int32_t) )); + ru->common.txdata[i] = (int32_t*)malloc16_clear((ru->sf_extension +fp->samples_per_frame) *sizeof(int32_t)); LOG_I(PHY,"[INIT] common.txdata[%d] = %p (%lu bytes,sf_extension %d)\n",i,ru->common.txdata[i], (ru->sf_extension + fp->samples_per_frame)*sizeof(int32_t),ru->sf_extension); ru->common.txdata[i] = &ru->common.txdata[i][ru->sf_extension]; diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index 95ca53e85f3efef289a774a1e2b6e2f56fa17429..077302b20795bdea4b59187f54cff6b1452ec411 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -587,7 +587,7 @@ void init_nr_ue_transport(PHY_VARS_NR_UE *ue) { for (int i = 0; i < NUMBER_OF_CONNECTED_gNB_MAX; i++) { for (int j=0; j<num_codeword; j++) { for (int k=0; k<RX_NB_TH_MAX; k++) { - AssertFatal((ue->dlsch[k][i][j] = new_nr_ue_dlsch(1,NR_MAX_DLSCH_HARQ_PROCESSES,NSOFT,MAX_LDPC_ITERATIONS,ue->frame_parms.N_RB_DL))!=NULL,"Can't get ue dlsch structures\n"); + AssertFatal((ue->dlsch[k][i][j] = new_nr_ue_dlsch(1,NR_MAX_DLSCH_HARQ_PROCESSES,NSOFT,ue->max_ldpc_iterations,ue->frame_parms.N_RB_DL))!=NULL,"Can't get ue dlsch structures\n"); LOG_D(PHY,"dlsch[%d][%d][%d] => %p\n",k,i,j,ue->dlsch[k][i][j]); if (j==0) { AssertFatal((ue->ulsch[k][i] = new_nr_ue_ulsch(ue->frame_parms.N_RB_UL, NR_MAX_ULSCH_HARQ_PROCESSES,&ue->frame_parms))!=NULL,"Can't get ue ulsch structures\n"); @@ -596,8 +596,8 @@ void init_nr_ue_transport(PHY_VARS_NR_UE *ue) { } } - ue->dlsch_SI[i] = new_nr_ue_dlsch(1,1,NSOFT,MAX_LDPC_ITERATIONS,ue->frame_parms.N_RB_DL); - ue->dlsch_ra[i] = new_nr_ue_dlsch(1,1,NSOFT,MAX_LDPC_ITERATIONS,ue->frame_parms.N_RB_DL); + ue->dlsch_SI[i] = new_nr_ue_dlsch(1,1,NSOFT,ue->max_ldpc_iterations,ue->frame_parms.N_RB_DL); + ue->dlsch_ra[i] = new_nr_ue_dlsch(1,1,NSOFT,ue->max_ldpc_iterations,ue->frame_parms.N_RB_DL); ue->transmission_mode[i] = ue->frame_parms.nb_antenna_ports_gNB==1 ? 1 : 2; } diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index 7b526876da771e997b4343a2413b6ce15f12fef4..cd3b535b3fd8024b1a3040bd1d1ecd53823bb446 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -92,6 +92,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, int16_t *fl,*fm,*fr,*fml,*fmr,*fmm,*fdcl,*fdcr,*fdclh,*fdcrh; int ch_offset,symbol_offset ; int32_t **ul_ch_estimates_time = gNB->pusch_vars[ul_id]->ul_ch_estimates_time; + int chest_freq = gNB->chest_freq; __m128i *ul_ch_128; #ifdef DEBUG_CH @@ -225,8 +226,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, LOG_I(PHY, "In %s ul_ch addr %p nushift %d\n", __FUNCTION__, ul_ch, nushift); #endif - if (pusch_pdu->dmrs_config_type == pusch_dmrs_type1 && gNB->prb_interpolation == 0) { - + if (pusch_pdu->dmrs_config_type == pusch_dmrs_type1 && chest_freq == 0){ LOG_D(PHY,"PUSCH estimation DMRS type 1, Freq-domain interpolation"); // For configuration type 1: k = 4*n + 2*k' + delta, @@ -329,7 +329,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, } #endif } - else if (pusch_pdu->dmrs_config_type == pusch_dmrs_type2 && gNB->prb_interpolation == 0) { //pusch_dmrs_type2 |p_r,p_l,d,d,d,d,p_r,p_l,d,d,d,d| + else if (pusch_pdu->dmrs_config_type == pusch_dmrs_type2 && chest_freq == 0) { //pusch_dmrs_type2 |p_r,p_l,d,d,d,d,p_r,p_l,d,d,d,d| LOG_D(PHY,"PUSCH estimation DMRS type 2, Freq-domain interpolation"); // Treat first DMRS specially (left edge) diff --git a/openair1/PHY/NR_REFSIG/dmrs_nr.c b/openair1/PHY/NR_REFSIG/dmrs_nr.c index ca901e1452c698b5ec1b0a3dadf755dfd11e62e3..1fd502a93e1369526ac012dd7905a24b6a94e3a8 100644 --- a/openair1/PHY/NR_REFSIG/dmrs_nr.c +++ b/openair1/PHY/NR_REFSIG/dmrs_nr.c @@ -338,3 +338,81 @@ int8_t get_valid_dmrs_idx_for_channel_est(uint16_t dmrs_symb_pos, uint8_t count } return symbIdx; } + +/* perform averaging of channel estimates and store result in first symbol buffer */ +void nr_chest_time_domain_avg(NR_DL_FRAME_PARMS *frame_parms, + int **ch_est, + uint8_t num_symbols, + uint8_t start_symbol, + uint16_t dmrs_bitmap, + uint16_t num_rbs) +{ + __m128i *ul_ch128_0; + __m128i *ul_ch128_1; + int16_t *ul_ch16_0; + int total_symbols = start_symbol + num_symbols; + int num_dmrs_symb = get_dmrs_symbols_in_slot(dmrs_bitmap, total_symbols); + int first_dmrs_symb = get_next_dmrs_symbol_in_slot(dmrs_bitmap, start_symbol, total_symbols); + AssertFatal(first_dmrs_symb > -1, "No DMRS symbol present in this slot\n"); + for (int aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) { + for (int symb = first_dmrs_symb+1; symb < total_symbols; symb++) { + ul_ch128_0 = (__m128i *)&ch_est[aarx][first_dmrs_symb*frame_parms->ofdm_symbol_size]; + if ((dmrs_bitmap >> symb) & 0x01) { + ul_ch128_1 = (__m128i *)&ch_est[aarx][symb*frame_parms->ofdm_symbol_size]; + for (int rbIdx = 0; rbIdx < num_rbs; rbIdx++) { + ul_ch128_0[0] = _mm_adds_epi16(ul_ch128_0[0], ul_ch128_1[0]); + ul_ch128_0[1] = _mm_adds_epi16(ul_ch128_0[1], ul_ch128_1[1]); + ul_ch128_0[2] = _mm_adds_epi16(ul_ch128_0[2], ul_ch128_1[2]); + ul_ch128_0 += 3; + ul_ch128_1 += 3; + } + } + } + ul_ch128_0 = (__m128i *)&ch_est[aarx][first_dmrs_symb*frame_parms->ofdm_symbol_size]; + if (num_dmrs_symb == 2) { + for (int rbIdx = 0; rbIdx < num_rbs; rbIdx++) { + ul_ch128_0[0] = _mm_srai_epi16(ul_ch128_0[0], 1); + ul_ch128_0[1] = _mm_srai_epi16(ul_ch128_0[1], 1); + ul_ch128_0[2] = _mm_srai_epi16(ul_ch128_0[2], 1); + ul_ch128_0 += 3; + } + } else if (num_dmrs_symb == 4) { + for (int rbIdx = 0; rbIdx < num_rbs; rbIdx++) { + ul_ch128_0[0] = _mm_srai_epi16(ul_ch128_0[0], 2); + ul_ch128_0[1] = _mm_srai_epi16(ul_ch128_0[1], 2); + ul_ch128_0[2] = _mm_srai_epi16(ul_ch128_0[2], 2); + ul_ch128_0 += 3; + } + } else if (num_dmrs_symb == 3) { + ul_ch16_0 = (int16_t *)&ch_est[aarx][first_dmrs_symb*frame_parms->ofdm_symbol_size]; + for (int rbIdx = 0; rbIdx < num_rbs; rbIdx++) { + ul_ch16_0[0] /= 3; + ul_ch16_0[1] /= 3; + ul_ch16_0[2] /= 3; + ul_ch16_0[3] /= 3; + ul_ch16_0[4] /= 3; + ul_ch16_0[5] /= 3; + ul_ch16_0[6] /= 3; + ul_ch16_0[7] /= 3; + ul_ch16_0[8] /= 3; + ul_ch16_0[9] /= 3; + ul_ch16_0[10] /= 3; + ul_ch16_0[11] /= 3; + ul_ch16_0[12] /= 3; + ul_ch16_0[13] /= 3; + ul_ch16_0[14] /= 3; + ul_ch16_0[15] /= 3; + ul_ch16_0[16] /= 3; + ul_ch16_0[17] /= 3; + ul_ch16_0[18] /= 3; + ul_ch16_0[19] /= 3; + ul_ch16_0[20] /= 3; + ul_ch16_0[21] /= 3; + ul_ch16_0[22] /= 3; + ul_ch16_0[23] /= 3; + ul_ch16_0 += 24; + } + } else AssertFatal((num_dmrs_symb < 5) && (num_dmrs_symb > 0), "Illegal number of DMRS symbols in the slot\n"); + } +} + diff --git a/openair1/PHY/NR_REFSIG/dmrs_nr.h b/openair1/PHY/NR_REFSIG/dmrs_nr.h index 13a83be53f770932e8f350710a65aed371711212..1297a0cc2ff7b2f95c65ccb2259fc77681094ed9 100644 --- a/openair1/PHY/NR_REFSIG/dmrs_nr.h +++ b/openair1/PHY/NR_REFSIG/dmrs_nr.h @@ -65,6 +65,12 @@ void nr_gen_ref_conj_symbols(uint32_t *in, uint32_t length, int16_t *output, uin int8_t get_next_dmrs_symbol_in_slot(uint16_t ul_dmrs_symb_pos, uint8_t counter, uint8_t end_symbol); uint8_t get_dmrs_symbols_in_slot(uint16_t l_prime_mask, uint16_t nb_symb); int8_t get_valid_dmrs_idx_for_channel_est(uint16_t dmrs_symb_pos, uint8_t counter); +void nr_chest_time_domain_avg(NR_DL_FRAME_PARMS *frame_parms, + int **ch_est, + uint8_t num_symbols, + uint8_t start_symbol, + uint16_t dmrs_bitmap, + uint16_t num_rbs); static inline uint8_t is_dmrs_symbol(uint8_t l, uint16_t dmrsSymbMask ) { return ((dmrsSymbMask >> l) & 0x1); } #undef EXTERN diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.c b/openair1/PHY/NR_TRANSPORT/nr_dci.c index 3a95ba49b0c42f41d3320286d81761ff9d714d5e..dc1ed47e0ffd4f7698201a05082a559f4830940e 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dci.c @@ -73,7 +73,6 @@ void nr_generate_dci(PHY_VARS_gNB *gNB, NR_DL_FRAME_PARMS *frame_parms, int slot) { - int16_t mod_dmrs[NR_MAX_CSET_DURATION][NR_MAX_PDCCH_DMRS_LENGTH>>1] __attribute__((aligned(16))); // 3 for the max coreset duration uint16_t cset_start_sc; uint8_t cset_start_symb, cset_nsymb; int k,l,k_prime,dci_idx, dmrs_idx; @@ -82,13 +81,14 @@ void nr_generate_dci(PHY_VARS_gNB *gNB, int rb_offset; int n_rb; - // compute rb_offset and n_prb based on frequency allocation nr_cce_t cce_list[MAX_DCI_CORESET][NR_MAX_PDCCH_AGG_LEVEL]; - nr_fill_cce_list(cce_list,0,pdcch_pdu_rel15); + nr_fill_cce_list(cce_list, pdcch_pdu_rel15); get_coreset_rballoc(pdcch_pdu_rel15->FreqDomainResource,&n_rb,&rb_offset); cset_start_sc = frame_parms->first_carrier_offset + (pdcch_pdu_rel15->BWPStart + rb_offset) * NR_NB_SC_PER_RB; + int16_t mod_dmrs[pdcch_pdu_rel15->StartSymbolIndex+pdcch_pdu_rel15->DurationSymbols][(n_rb+rb_offset)*6] __attribute__((aligned(16))); // 3 for the max coreset duration + for (int d=0;d<pdcch_pdu_rel15->numDlDci;d++) { /*The coreset is initialised * in frequency: the first subcarrier is obtained by adding the first CRB overlapping the SSB and the rb_offset for coreset 0 @@ -119,7 +119,7 @@ void nr_generate_dci(PHY_VARS_gNB *gNB, /// DMRS QPSK modulation for (int symb=cset_start_symb; symb<cset_start_symb + pdcch_pdu_rel15->DurationSymbols; symb++) { - + nr_modulation(gold_pdcch_dmrs[symb], dmrs_length, DMRS_MOD_ORDER, mod_dmrs[symb]); //Qm = 2 as DMRS is QPSK modulated #ifdef DEBUG_PDCCH_DMRS @@ -179,8 +179,10 @@ void nr_generate_dci(PHY_VARS_gNB *gNB, // Get cce_list indices by reg_idx in ascending order int reg_list_index = 0; + int N_regs = n_rb*pdcch_pdu_rel15->DurationSymbols; // nb of REGs per coreset + int N_cces = N_regs / NR_NB_REG_PER_CCE; // nb of cces in coreset int reg_list_order[NR_MAX_PDCCH_AGG_LEVEL] = {}; - for (int p = 0; p < NR_MAX_PDCCH_AGG_LEVEL; p++) { + for (int p = 0; p < N_cces; p++) { for(int p2 = 0; p2 < dci_pdu->AggregationLevel; p2++) { if(cce_list[d][p2].reg_list[0].reg_idx == p * NR_NB_REG_PER_CCE) { reg_list_order[reg_list_index] = p2; @@ -192,24 +194,25 @@ void nr_generate_dci(PHY_VARS_gNB *gNB, /*Mapping the encoded DCI along with the DMRS */ for(int symbol_idx = 0; symbol_idx < pdcch_pdu_rel15->DurationSymbols; symbol_idx++) { - for (int cce_count = 0; cce_count < dci_pdu->AggregationLevel; cce_count+=pdcch_pdu_rel15->DurationSymbols) { + for (int cce_count = 0; cce_count < dci_pdu->AggregationLevel; cce_count++) { int8_t cce_idx = reg_list_order[cce_count]; - for (int reg_in_cce_idx = 0; reg_in_cce_idx < NR_NB_REG_PER_CCE; reg_in_cce_idx++) { + for (int reg_in_cce_idx = 0; reg_in_cce_idx < NR_NB_REG_PER_CCE; reg_in_cce_idx+=pdcch_pdu_rel15->DurationSymbols) { k = cset_start_sc + cce_list[d][cce_idx].reg_list[reg_in_cce_idx].start_sc_idx; - + LOG_D(PHY,"CCE %d REG %d k %d\n",cce_idx,reg_in_cce_idx+symbol_idx,k); if (k >= frame_parms->ofdm_symbol_size) k -= frame_parms->ofdm_symbol_size; l = cset_start_symb + symbol_idx; // dmrs index depends on reference point for k according to 38.211 7.4.1.3.2 + int eff_reg_idx = cce_list[d][cce_idx].reg_list[reg_in_cce_idx].reg_idx/pdcch_pdu_rel15->DurationSymbols; if (pdcch_pdu_rel15->CoreSetType == NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG) - dmrs_idx = (cce_list[d][cce_idx].reg_list[reg_in_cce_idx].reg_idx) * 3; + dmrs_idx = eff_reg_idx * 3; else - dmrs_idx = (cce_list[d][cce_idx].reg_list[reg_in_cce_idx].reg_idx + rb_offset) * 3; + dmrs_idx = (eff_reg_idx + rb_offset) * 3; k_prime = 0; diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.h b/openair1/PHY/NR_TRANSPORT/nr_dci.h index 490a8b528682fa3d64b7a8d0de5f7a8f223372cb..0bf6932bb50685c622236c2b4dfdd095f1ae0e49 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci.h +++ b/openair1/PHY/NR_TRANSPORT/nr_dci.h @@ -55,6 +55,6 @@ void nr_fill_ul_dci(PHY_VARS_gNB *gNB, int slot, nfapi_nr_ul_dci_request_pdus_t *pdcch_pdu); -void nr_fill_cce_list(nr_cce_t cce_list[MAX_DCI_CORESET][NR_MAX_PDCCH_AGG_LEVEL], uint8_t m,nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15); +void nr_fill_cce_list(nr_cce_t cce_list[MAX_DCI_CORESET][NR_MAX_PDCCH_AGG_LEVEL], nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15); #endif //__PHY_NR_TRANSPORT_DCI__H diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c b/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c index 8d5eb4a66072ca56684ebee75c12cc2f69c07a47..e9d3010ce7c4c884ab9c68025ed59be389e21d47 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c @@ -37,89 +37,8 @@ #include "nr_dlsch.h" -/* - Original version to keep code for Y that needs to be moved to MAC - -void nr_fill_cce_list(PHY_VARS_gNB *gNB, uint16_t n_shift, uint8_t m) { - - nr_cce_t* cce; - nr_reg_t* reg; - nfapi_nr_dl_config_pdcch_pdu_rel15_t* pdcch_pdu = gNB->pdcch_pdu.pdcch; - - uint8_t L = dci_alloc->L; - uint8_t bsize = pdcch_params->reg_bundle_size; - uint8_t R = pdcch_params->interleaver_size; - uint16_t N_reg = pdcch_params->n_rb * pdcch_params->n_symb; - uint16_t Y, N_cce, M_s_max, n_CI=0, tmp, C=0; - uint16_t n_RNTI = (pdcch_params->search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC)? pdcch_params->rnti:0; - uint32_t A[3]={39827,39829,39839}; - - if (pdcch_params->config_type == NFAPI_NR_CSET_CONFIG_MIB_SIB1) - AssertFatal(L>=4, "Invalid aggregation level for SIB1 configured PDCCH %d\n", L); - - N_cce = N_reg / NR_NB_REG_PER_CCE; - //Max number of candidates per aggregation level -- SIB1 configured search space only - M_s_max = (L==4)?4:(L==8)?2:1; - - if (pdcch_params->search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_COMMON) - Y = 0; - else { //NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC - Y = (A[0]*n_RNTI)%65537; // Candidate 0, antenna port 0 - } - - if (pdcch_params->cr_mapping_type == NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED) { - uint16_t assertFatalCond = (N_reg%(bsize*R)); - AssertFatal(assertFatalCond == 0,"CCE to REG interleaving: Invalid configuration leading to non integer C (N_reg %us, bsize %d R %d)\n",N_reg, bsize, R); - C = N_reg/(bsize*R); - } - - tmp = L * (( Y + (m*N_cce)/(L*M_s_max) + n_CI ) % CEILIDIV(N_cce,L)); - - LOG_D(PHY, "CCE list generation for candidate %d: bundle size %d ilv size %d tmp %d\n", m, bsize, R, tmp); - for (uint8_t cce_idx=0; cce_idx<L; cce_idx++) { - cce = &dci_alloc->cce_list[cce_idx]; - cce->cce_idx = tmp + cce_idx; - LOG_D(PHY, "cce_idx %d\n", cce->cce_idx); - - if (pdcch_params->cr_mapping_type == NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED) { - LOG_D(PHY, "Interleaved CCE to REG mapping\n"); - uint8_t j = cce->cce_idx, j_prime; - uint8_t r,c,idx; - - for (uint8_t bundle_idx=0; bundle_idx<NR_NB_REG_PER_CCE/bsize; bundle_idx++) { - j_prime = 6*j/bsize + bundle_idx; - r = j_prime%R; - c = (j_prime-r)/R; - idx = (r*C + c + n_shift)%(N_reg/bsize); - LOG_D(PHY, "bundle idx = %d \n j = %d \t j_prime = %d \t r = %d \t c = %d\n", idx, j , j_prime, r, c); - - for (uint8_t reg_idx=0; reg_idx<bsize; reg_idx++) { - reg = &cce->reg_list[reg_idx]; - reg->reg_idx = bsize*idx + reg_idx; - reg->start_sc_idx = (reg->reg_idx/pdcch_params->n_symb) * NR_NB_SC_PER_RB; - reg->symb_idx = reg->reg_idx % pdcch_params->n_symb; - LOG_D(PHY, "reg %d symbol %d start subcarrier %d\n", reg->reg_idx, reg->symb_idx, reg->start_sc_idx); - } - } - } - else { // NFAPI_NR_CCE_REG_MAPPING_NON_INTERLEAVED - LOG_D(PHY, "Non interleaved CCE to REG mapping\n"); - for (uint8_t reg_idx=0; reg_idx<NR_NB_REG_PER_CCE; reg_idx++) { - reg = &cce->reg_list[reg_idx]; - reg->reg_idx = cce->cce_idx*NR_NB_REG_PER_CCE + reg_idx; - reg->start_sc_idx = (reg->reg_idx/pdcch_params->n_symb) * NR_NB_SC_PER_RB; - reg->symb_idx = reg->reg_idx % pdcch_params->n_symb; - LOG_D(PHY, "reg %d symbol %d start subcarrier %d\n", reg->reg_idx, reg->symb_idx, reg->start_sc_idx); - } - - } - } -} - -*/ - -void nr_fill_cce_list(nr_cce_t cce_list[MAX_DCI_CORESET][NR_MAX_PDCCH_AGG_LEVEL], uint8_t m, nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15) { +void nr_fill_cce_list(nr_cce_t cce_list[MAX_DCI_CORESET][NR_MAX_PDCCH_AGG_LEVEL], nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15) { nr_cce_t* cce; nr_reg_t* reg; @@ -128,71 +47,51 @@ void nr_fill_cce_list(nr_cce_t cce_list[MAX_DCI_CORESET][NR_MAX_PDCCH_AGG_LEVEL] int R = pdcch_pdu_rel15->InterleaverSize; int n_shift = pdcch_pdu_rel15->ShiftIndex; - //Max number of candidates per aggregation level -- SIB1 configured search space only - int n_rb,rb_offset; get_coreset_rballoc(pdcch_pdu_rel15->FreqDomainResource,&n_rb,&rb_offset); - - int N_reg = n_rb; - int C=-1; - - AssertFatal(N_reg > 0,"N_reg cannot be 0\n"); - for (int d=0;d<pdcch_pdu_rel15->numDlDci;d++) { + int L = pdcch_pdu_rel15->dci_pdu[d].AggregationLevel; + int dur = pdcch_pdu_rel15->DurationSymbols; + int N_regs = n_rb*dur; // nb of REGs per coreset + AssertFatal(N_regs > 0,"N_reg cannot be 0\n"); if (pdcch_pdu_rel15->CoreSetType == NFAPI_NR_CSET_CONFIG_MIB_SIB1) AssertFatal(L>=4, "Invalid aggregation level for SIB1 configured PDCCH %d\n", L); - + + int C = 0; + if (pdcch_pdu_rel15->CceRegMappingType == NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED) { - uint16_t assertFatalCond = (N_reg%(bsize*R)); - AssertFatal(assertFatalCond == 0,"CCE to REG interleaving: Invalid configuration leading to non integer C (N_reg %us, bsize %d R %d)\n",N_reg, bsize, R); - C = N_reg/(bsize*R); + uint16_t assertFatalCond = (N_regs%(bsize*R)); + AssertFatal(assertFatalCond == 0,"CCE to REG interleaving: Invalid configuration leading to non integer C (N_reg %us, bsize %d R %d)\n",N_regs, bsize, R); + C = N_regs/(bsize*R); } - - if (pdcch_pdu_rel15->dci_pdu[d].RNTI != 0xFFFF) LOG_D(PHY, "CCE list generation for candidate %d: bundle size %d ilv size %d CceIndex %d\n", m, bsize, R, pdcch_pdu_rel15->dci_pdu[d].CceIndex); + + if (pdcch_pdu_rel15->dci_pdu[d].RNTI != 0xFFFF) + LOG_D(PHY, "CCE list generation for candidate %d: bundle size %d ilv size %d CceIndex %d\n", d, bsize, R, pdcch_pdu_rel15->dci_pdu[d].CceIndex); + for (uint8_t cce_idx=0; cce_idx<L; cce_idx++) { cce = &cce_list[d][cce_idx]; cce->cce_idx = pdcch_pdu_rel15->dci_pdu[d].CceIndex + cce_idx; LOG_D(PHY, "cce_idx %d\n", cce->cce_idx); - - if (pdcch_pdu_rel15->CceRegMappingType == NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED) { - LOG_D(PHY, "Interleaved CCE to REG mapping\n"); - uint8_t j = cce->cce_idx, j_prime; - uint8_t r,c,idx; - - for (uint8_t bundle_idx=0; bundle_idx<NR_NB_REG_PER_CCE/bsize; bundle_idx++) { - j_prime = 6*j/bsize + bundle_idx; - r = j_prime%R; - c = (j_prime-r)/R; - idx = (r*C + c + n_shift)%(N_reg/bsize); - LOG_D(PHY, "bundle idx = %d \n j = %d \t j_prime = %d \t r = %d \t c = %d\n", idx, j , j_prime, r, c); - - for (uint8_t reg_idx=0; reg_idx<bsize; reg_idx++) { - reg = &cce->reg_list[reg_idx]; - reg->reg_idx = bsize*idx + reg_idx; - reg->start_sc_idx = reg->reg_idx * NR_NB_SC_PER_RB; - reg->symb_idx = 0; - LOG_D(PHY, "reg %d symbol %d start subcarrier %d\n", reg->reg_idx, reg->symb_idx, reg->start_sc_idx); - } - } - } - else { // NFAPI_NR_CCE_REG_MAPPING_NON_INTERLEAVED - LOG_D(PHY, "Non interleaved CCE to REG mapping\n"); - for (uint8_t reg_idx=0; reg_idx<NR_NB_REG_PER_CCE; reg_idx++) { + + uint8_t j = cce->cce_idx; + for (int k=6*j/bsize; k<(6*j/bsize+6/bsize); k++) { // loop over REG bundles + + int f = cce_to_reg_interleaving(R, k, n_shift, C, bsize, N_regs); + + for (uint8_t reg_idx=0; reg_idx<bsize; reg_idx++) { reg = &cce->reg_list[reg_idx]; - reg->reg_idx = cce->cce_idx*NR_NB_REG_PER_CCE + reg_idx; - reg->start_sc_idx = reg->reg_idx * NR_NB_SC_PER_RB; - reg->symb_idx = 0; + reg->reg_idx = bsize*f + reg_idx; + reg->start_sc_idx = (reg->reg_idx/dur) * NR_NB_SC_PER_RB; + reg->symb_idx = reg_idx%dur; LOG_D(PHY, "reg %d symbol %d start subcarrier %d\n", reg->reg_idx, reg->symb_idx, reg->start_sc_idx); } - } - } } } diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c index 260bfbdfbc32d333da0e3af015e66c310700b61a..4b8315e1ce488b4f43dde0acfca721deb5bed1c0 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c @@ -1963,6 +1963,17 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, } } } + + if (gNB->chest_time == 1) { // averaging time domain channel estimates + nr_chest_time_domain_avg(frame_parms, + gNB->pusch_vars[ulsch_id]->ul_ch_estimates, + rel15_ul->nr_of_symbols, + rel15_ul->start_symbol_index, + rel15_ul->ul_dmrs_symb_pos, + rel15_ul->rb_size); + + gNB->pusch_vars[ulsch_id]->dmrs_symbol = get_next_dmrs_symbol_in_slot(rel15_ul->ul_dmrs_symb_pos, rel15_ul->start_symbol_index, rel15_ul->nr_of_symbols); + } stop_meas(&gNB->ulsch_channel_estimation_stats); #ifdef __AVX2__ @@ -1978,7 +1989,8 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, if ((rel15_ul->ul_dmrs_symb_pos >> ((symbol + 1) % frame_parms->symbols_per_slot)) & 0x01) AssertFatal(1==0,"Double DMRS configuration is not yet supported\n"); - gNB->pusch_vars[ulsch_id]->dmrs_symbol = symbol; + if (gNB->chest_time == 0) // Non averaging time domain channel estimates + gNB->pusch_vars[ulsch_id]->dmrs_symbol = symbol; if (rel15_ul->dmrs_config_type == 0) { // if no data in dmrs cdm group is 1 only even REs have no data diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c index 037851be0c388f218e7561e2252a1787ba79e4ad..082370dff49f8a4470bf9f9aa57c19d54aef9a86 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -683,7 +683,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, int ch_offset,symbol_offset; uint8_t nushift; - int **dl_ch_estimates =ue->pdsch_vars[proc->thread_id][gNB_id]->dl_ch_estimates; + int **dl_ch_estimates = ue->pdsch_vars[proc->thread_id][gNB_id]->dl_ch_estimates; int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF; ch_offset = ue->frame_parms.ofdm_symbol_size*symbol; @@ -808,7 +808,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, printf("rxF addr %p p %d\n", rxF,p); printf("dl_ch addr %p nushift %d\n",dl_ch,nushift); #endif - if (config_type == NFAPI_NR_DMRS_TYPE1 && ue->prb_interpolation == 0) { + if (config_type == NFAPI_NR_DMRS_TYPE1 && ue->chest_freq == 0) { // Treat first 2 pilots specially (left edge) ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); @@ -985,7 +985,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, 8); } } - } else if (config_type == NFAPI_NR_DMRS_TYPE2 && ue->prb_interpolation == 0){ //pdsch_dmrs_type2 |dmrs_r,dmrs_l,0,0,0,0,dmrs_r,dmrs_l,0,0,0,0| + } else if (config_type == NFAPI_NR_DMRS_TYPE2 && ue->chest_freq == 0){ //pdsch_dmrs_type2 |dmrs_r,dmrs_l,0,0,0,0,dmrs_r,dmrs_l,0,0,0,0| // Treat first 4 pilots specially (left edge) ch_l[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c index 336d388d40d794644f9774418bcbfe92399abd78..45eadd2c955f99efd579c6cecffc077d79a99b13 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c @@ -142,7 +142,8 @@ static void nr_pdcch_demapping_deinterleaving(uint32_t *llr, int B_rb = reg_bundle_size_L/coreset_time_dur; // nb of RBs occupied by each REG bundle int num_bundles_per_cce = 6/reg_bundle_size_L; - int max_bundles = NR_MAX_PDCCH_AGG_LEVEL*num_bundles_per_cce; + int n_cce = N_regs/6; + int max_bundles = n_cce*num_bundles_per_cce; int f_bundle_j_list[max_bundles]; // for each bundle @@ -359,10 +360,7 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF, * According to this equations, DM-RS PDCCH are mapped on k where k%12==1 || k%12==5 || k%12==9 * */ - // the bitmap coreset_frq_domain contains 45 bits -#define CORESET_FREQ_DOMAIN_BITMAP_SIZE 45 - // each bit is associated to 6 RBs -#define BIT_TO_NBR_RB_CORESET_FREQ_DOMAIN 6 + #define NBR_RE_PER_RB_WITH_DMRS 12 // after removing the 3 DMRS RE, the RB contains 9 RE with PDCCH #define NBR_RE_PER_RB_WITHOUT_DMRS 9 @@ -686,9 +684,9 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, // Pointers to extracted PDCCH symbols in frequency-domain. int32_t rx_size = 4*273*12; - int32_t rxdataF_ext[4*frame_parms->nb_antennas_rx][rx_size]; - int32_t rxdataF_comp[4*frame_parms->nb_antennas_rx][rx_size]; - int32_t pdcch_dl_ch_estimates_ext[4*frame_parms->nb_antennas_rx][rx_size]; + __attribute__ ((aligned(32))) int32_t rxdataF_ext[4*frame_parms->nb_antennas_rx][rx_size]; + __attribute__ ((aligned(32))) int32_t rxdataF_comp[4*frame_parms->nb_antennas_rx][rx_size]; + __attribute__ ((aligned(32))) int32_t pdcch_dl_ch_estimates_ext[4*frame_parms->nb_antennas_rx][rx_size]; // Pointer to llrs, 4-bit resolution. int32_t llr_size = 2*4*100*12; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index 14da6229394227872946c5cbedf544d85ffba3e0..19a680c6be90ebb3fc409984ae1bd74e2691d30a 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -319,7 +319,8 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, dlsch0_harq->n_dmrs_cdm_groups, dlsch0_harq->Nl, frame_parms, - dlsch0_harq->dlDmrsSymbPos); + dlsch0_harq->dlDmrsSymbPos, + ue->chest_time); stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]); if (cpumeas(CPUMEAS_GETSTATE)) LOG_D(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d type %d: Pilot/Data extraction %5.2f \n", @@ -1610,7 +1611,8 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF, unsigned short nb_rb_pdsch, uint8_t n_dmrs_cdm_groups, NR_DL_FRAME_PARMS *frame_parms, - uint16_t dlDmrsSymbPos) + uint16_t dlDmrsSymbPos, + int chest_time_type) { if (config_type == NFAPI_NR_DMRS_TYPE1) { AssertFatal(n_dmrs_cdm_groups == 1 || n_dmrs_cdm_groups == 2, @@ -1621,7 +1623,12 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF, } const unsigned short start_re = (frame_parms->first_carrier_offset + start_rb * NR_NB_SC_PER_RB) % frame_parms->ofdm_symbol_size; - const int8_t validDmrsEst = get_valid_dmrs_idx_for_channel_est(dlDmrsSymbPos, symbol); + int8_t validDmrsEst; + + if (chest_time_type == 0) + validDmrsEst = get_valid_dmrs_idx_for_channel_est(dlDmrsSymbPos,symbol); + else + validDmrsEst = get_next_dmrs_symbol_in_slot(dlDmrsSymbPos,0,14); // get first dmrs symbol index for (unsigned char aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) { @@ -1708,7 +1715,8 @@ void nr_dlsch_extract_rbs(int **rxdataF, uint8_t n_dmrs_cdm_groups, uint8_t Nl, NR_DL_FRAME_PARMS *frame_parms, - uint16_t dlDmrsSymbPos) + uint16_t dlDmrsSymbPos, + int chest_time_type) { unsigned short k,rb; @@ -1726,7 +1734,10 @@ void nr_dlsch_extract_rbs(int **rxdataF, nushift = (n_dmrs_cdm_groups -1)<<1;//delta in Table 7.4.1.1.2-2 } - validDmrsEst = get_valid_dmrs_idx_for_channel_est(dlDmrsSymbPos,symbol); + if (chest_time_type == 0) + validDmrsEst = get_valid_dmrs_idx_for_channel_est(dlDmrsSymbPos,symbol); + else + validDmrsEst = get_next_dmrs_symbol_in_slot(dlDmrsSymbPos,0,14); // get first dmrs symbol index for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c index 48b08d761ece8f76e29eb3f1e737f8a686ac4393..78e4a8a4e811ad7a1609ac3e2d231a365e7e661e 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c @@ -430,8 +430,8 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, for (symbol=1; symbol<4; symbol++) { const uint16_t nb_re=symbol == 2 ? 72 : 180; - struct complex16 rxdataF_ext[frame_parms->nb_antennas_rx][PBCH_MAX_RE_PER_SYMBOL]; - struct complex16 dl_ch_estimates_ext[frame_parms->nb_antennas_rx][PBCH_MAX_RE_PER_SYMBOL]; + __attribute__ ((aligned(32))) struct complex16 rxdataF_ext[frame_parms->nb_antennas_rx][PBCH_MAX_RE_PER_SYMBOL]; + __attribute__ ((aligned(32))) struct complex16 dl_ch_estimates_ext[frame_parms->nb_antennas_rx][PBCH_MAX_RE_PER_SYMBOL]; memset(dl_ch_estimates_ext,0, sizeof dl_ch_estimates_ext); nr_pbch_extract(nr_ue_common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF, estimateSz, @@ -456,7 +456,7 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, #ifdef DEBUG_PBCH LOG_I(PHY,"[PHY] PBCH log2_maxh = %d (%d)\n",nr_ue_pbch_vars->log2_maxh,max_h); #endif - struct complex16 rxdataF_comp[frame_parms->nb_antennas_rx][PBCH_MAX_RE_PER_SYMBOL]; + __attribute__ ((aligned(32))) struct complex16 rxdataF_comp[frame_parms->nb_antennas_rx][PBCH_MAX_RE_PER_SYMBOL]; nr_pbch_channel_compensation(rxdataF_ext, dl_ch_estimates_ext, nb_re, diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h index b38caa680478c71e617e6dd0523cc3787552c126..30bc0ffe9203fd1e5d0b07f2fbbf4884c254e63c 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -709,7 +709,8 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF, unsigned short nb_rb_pdsch, uint8_t n_dmrs_cdm_groups, NR_DL_FRAME_PARMS *frame_parms, - uint16_t dlDmrsSymbPos); + uint16_t dlDmrsSymbPos, + int chest_time_type); /** \fn dlsch_extract_rbs_multiple(int32_t **rxdataF, int32_t **dl_ch_estimates, @@ -747,7 +748,8 @@ void nr_dlsch_extract_rbs(int **rxdataF, uint8_t n_dmrs_cdm_groups, uint8_t Nl, NR_DL_FRAME_PARMS *frame_parms, - uint16_t dlDmrsSymbPos); + uint16_t dlDmrsSymbPos, + int chest_time_type); /** \fn dlsch_extract_rbs_TM7(int32_t **rxdataF, int32_t **dl_bf_ch_estimates, diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index ace4cf120b3ec87d51104365b5a142c477c9bb3e..f805aec552a5b5a42e3c07fd6dd979a608c849f2 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -826,7 +826,11 @@ typedef struct PHY_VARS_gNB_s { int **dl_precoder_SgNB[3]; char log2_maxp; /// holds the maximum channel/precoder coefficient - int prb_interpolation; + int max_ldpc_iterations; + /// indicate the channel estimation technique in time domain + int chest_time; + /// indicate the channel estimation technique in freq domain + int chest_freq; /// if ==0 enables phy only test mode int mac_enabled; diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index 259367a994f69f408be9520bea8bee4db695a9b9..8ba87b7a67aa790539fb502891d83ff9204c0a08 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -777,7 +777,8 @@ typedef struct { uint32_t perfect_ce; // flag to activate PRB based averaging of channel estimates // when off, defaults to frequency domain interpolation - int prb_interpolation; + int chest_freq; + int chest_time; int generate_ul_signal[NUMBER_OF_CONNECTED_gNB_MAX]; UE_NR_SCAN_INFO_t scan_info[NB_BANDS_MAX]; @@ -865,6 +866,8 @@ typedef struct { /// N0 (used for abstraction) double N0; + uint8_t max_ldpc_iterations; + /// PDSCH Varaibles PDSCH_CONFIG_DEDICATED pdsch_config_dedicated[NUMBER_OF_CONNECTED_gNB_MAX]; diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 9c607cb8b794dc963c8eca41242a0111add1d5e1..0d54caceb3c26f503996903deeb9f6af76b4d181 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -793,10 +793,14 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_power_tot), dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_noise_power_tot),gNB->pusch_thres); gNB->pusch_vars[ULSCH_id]->ulsch_power_tot = gNB->pusch_vars[ULSCH_id]->ulsch_noise_power_tot; - nr_fill_indication(gNB,frame_rx, slot_rx, ULSCH_id, harq_pid, 1,1); gNB->pusch_vars[ULSCH_id]->DTX=1; if (stats) stats->DTX++; - return 1; + if (!get_softmodem_params()->phy_test) { + /* in case of phy_test mode, we still want to decode to measure execution time. + Therefore, we don't yet call nr_fill_indication, it will be called later */ + nr_fill_indication(gNB,frame_rx, slot_rx, ULSCH_id, harq_pid, 1,1); + return 1; + } } else { LOG_D(PHY, "PUSCH detected in %d.%d (%d,%d,%d)\n",frame_rx,slot_rx, dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_power_tot), @@ -856,10 +860,6 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { } stop_meas(&gNB->phy_proc_rx); - // figure out a better way to choose slot_rx, 19 is ok for a particular TDD configuration with 30kHz SCS - if ((frame_rx&127) == 0 && slot_rx==19) { - LOG_I(NR_PHY, "Number of bad PUCCH received: %lu\n", gNB->bad_pucch); - } if (pucch_decode_done || pusch_decode_done) { T(T_GNB_PHY_PUCCH_PUSCH_IQ, T_INT(frame_rx), T_INT(slot_rx), T_BUFFER(&gNB->common_vars.rxdataF[0][0], gNB->frame_parms.symbols_per_slot * gNB->frame_parms.ofdm_symbol_size * 4)); diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index d522271a60f1067d2d28055b25a56fd02834edca..739f6010d48dc326425a8c46a4f1cf7338a17b55 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -36,6 +36,7 @@ #include "assertions.h" #include "defs.h" #include "PHY/defs_nr_UE.h" +#include "PHY/NR_REFSIG/dmrs_nr.h" #include "PHY/phy_extern_nr_ue.h" #include "PHY/MODULATION/modulation_UE.h" #include "PHY/NR_UE_TRANSPORT/nr_transport_ue.h" @@ -615,6 +616,15 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int gNB_ } } + if (ue->chest_time == 1) { // averaging time domain channel estimates + nr_chest_time_domain_avg(&ue->frame_parms, + ue->pdsch_vars[proc->thread_id][gNB_id]->dl_ch_estimates, + dlsch0_harq->nb_symbols, + dlsch0_harq->start_symbol, + dlsch0_harq->dlDmrsSymbPos, + pdsch_nb_rb); + } + uint16_t first_symbol_with_data = s0; uint32_t dmrs_data_re; diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 99236c9a43cc9f3a2c3cad1737cb00fe64e71fe3..bab67e442616fb2b4d2bf060a2e151d74f78ab73 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -66,6 +66,7 @@ #include "NR_RRCReconfiguration.h" #define inMicroS(a) (((double)(a))/(get_cpu_freq_GHz()*1000.0)) #include "SIMULATION/LTE_PHY/common_sim.h" +#include "PHY/NR_REFSIG/dmrs_nr.h" #include <openair2/LAYER2/MAC/mac_vars.h> #include <openair2/RRC/LTE/rrc_vars.h> @@ -263,26 +264,35 @@ void update_ptrs_config(NR_CellGroupConfig_t *secondaryCellGroup, uint16_t *rbSi void update_dmrs_config(NR_CellGroupConfig_t *scg, int8_t* dmrs_arg); extern void fix_scd(NR_ServingCellConfig_t *scd);// forward declaration -/* specific dlsim DL preprocessor: uses rbStart/rbSize/mcs/nrOfLayers from command line of - dlsim, does not search for CCE/PUCCH occasion but simply sets to 0 */ +/* specific dlsim DL preprocessor: uses rbStart/rbSize/mcs/nrOfLayers from command line of dlsim */ int g_mcsIndex = -1, g_mcsTableIdx = 0, g_rbStart = -1, g_rbSize = -1, g_nrOfLayers = 1; void nr_dlsim_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t slot) { + NR_UE_info_t *UE_info = RC.nrmac[module_id]->UE_info.list[0]; AssertFatal(RC.nrmac[module_id]->UE_info.list[1]==NULL, "can have only a single UE\n"); NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl; NR_ServingCellConfigCommon_t *scc = RC.nrmac[0]->common_channels[0].ServingCellConfigCommon; - /* manually set free CCE to 0 */ const int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific; sched_ctrl->search_space = get_searchspace(NULL, scc, sched_ctrl->active_bwp ? sched_ctrl->active_bwp->bwp_Dedicated : NULL, target_ss); uint8_t nr_of_candidates; find_aggregation_candidates(&sched_ctrl->aggregation_level, &nr_of_candidates, sched_ctrl->search_space,4); + sched_ctrl->coreset = get_coreset(RC.nrmac[module_id], scc, sched_ctrl->active_bwp->bwp_Dedicated, sched_ctrl->search_space, target_ss); - sched_ctrl->cce_index = 0; + uint32_t Y = get_Y(sched_ctrl->search_space, slot, UE_info->rnti); + int CCEIndex = find_pdcch_candidate(RC.nrmac[module_id], + /* CC_id = */ 0, + sched_ctrl->aggregation_level, + nr_of_candidates, + &sched_ctrl->sched_pdcch, + sched_ctrl->coreset, + Y); + AssertFatal(CCEIndex>=0, "%4d.%2d could not find CCE for DL DCI UE %d/RNTI %04x\n", frame, slot, 0, UE_info->rnti); + sched_ctrl->cce_index = CCEIndex; NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static; @@ -434,7 +444,8 @@ int main(int argc, char **argv) uint16_t rbSize = 106; uint8_t mcsIndex = 9; uint8_t dlsch_threads = 0; - int prb_inter = 0; + int chest_type[2] = {0}; + uint8_t max_ldpc_iterations = 5; if ( load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) == 0) { exit_fun("[NR_DLSIM] Error, configuration module init failed\n"); } @@ -445,7 +456,7 @@ int main(int argc, char **argv) FILE *scg_fd=NULL; - while ((c = getopt (argc, argv, "f:hA:pf:g:in:s:S:t:x:y:z:M:N:F:GR:dPIL:Ea:b:d:e:q:m:w:T:U:X:")) != -1) { + while ((c = getopt (argc, argv, "f:hA:pf:g:i:n:s:S:t:x:y:z:M:N:F:GR:dPI:L:Ea:b:d:e:m:w:T:U:q:X:Y")) != -1) { switch (c) { case 'f': scg_fd = fopen(optarg,"r"); @@ -502,7 +513,9 @@ int main(int argc, char **argv) break; case 'i': - prb_inter=1; + for(i=0; i < atoi(optarg); i++){ + chest_type[i] = atoi(argv[optind++]); + } break; case 'n': @@ -589,9 +602,7 @@ int main(int argc, char **argv) break; case 'I': - run_initial_sync=1; - //target_error_rate=0.1; - slot = 0; + max_ldpc_iterations = atoi(optarg); break; case 'L': @@ -655,6 +666,12 @@ int main(int argc, char **argv) gNBthreads[sizeof(gNBthreads)-1]=0; break; + case 'Y': + run_initial_sync=1; + //target_error_rate=0.1; + slot = 0; + break; + default: case 'h': printf("%s -h(elp) -p(extended_prefix) -N cell_id -f output_filename -F input_filename -g channel_model -n n_frames -s snr0 -S snr1 -x transmission_mode -y TXant -z RXant -i Intefrence0 -j Interference1 -A interpolation_file -C(alibration offset dB) -N CellId\n", @@ -670,7 +687,7 @@ int main(int argc, char **argv) printf("-g [A,B,C,D,E,F,G,R] Use 3GPP SCM (A,B,C,D) or 36-101 (E-EPA,F-EVA,G-ETU) models or R for MIMO model (ignores delay spread and Ricean factor)\n"); printf("-y Number of TX antennas used in gNB\n"); printf("-z Number of RX antennas used in UE\n"); - printf("-i Activate PRB based averaging for channel estimation. Frequncy domain interpolation by default.\n"); + printf("-i Change channel estimation technique. Arguments list: Frequency domain {0:Linear interpolation, 1:PRB based averaging}, Time domain {0:Estimates of last DMRS symbol, 1:Average of DMRS symbols}\n"); //printf("-j Relative strength of second intefering gNB (in dB) - cell_id mod 3 = 2\n"); printf("-R N_RB_DL\n"); printf("-O oversampling factor (1,2,4,8,16)\n"); @@ -687,12 +704,14 @@ int main(int argc, char **argv) printf("-e MSC index\n"); printf("-q MCS Table index\n"); printf("-t Acceptable effective throughput (in percentage)\n"); + printf("-I Maximum LDPC decoder iterations\n"); printf("-T Enable PTRS, arguments list L_PTRS{0,1,2} K_PTRS{2,4}, e.g. -T 2 0 2 \n"); printf("-U Change DMRS Config, arguments list DMRS TYPE{0=A,1=B} DMRS AddPos{0:2} DMRS ConfType{1:2}, e.g. -U 3 0 2 1 \n"); printf("-P Print DLSCH performances\n"); printf("-w Write txdata to binary file (one frame)\n"); printf("-d number of dlsch threads, 0: no dlsch parallelization\n"); - printf("-X gNB thread pool configuration, n => no threads"); + printf("-X gNB thread pool configuration, n => no threads\n"); + printf("-Y Run initial sync in UE\n"); exit (-1); break; } @@ -948,6 +967,7 @@ int main(int argc, char **argv) PHY_vars_UE_g[0][0] = UE; memcpy(&UE->frame_parms,frame_parms,sizeof(NR_DL_FRAME_PARMS)); UE->frame_parms.nb_antennas_rx = n_rx; + UE->max_ldpc_iterations = max_ldpc_iterations; if (run_initial_sync==1) UE->is_synchronized = 0; else {UE->is_synchronized = 1; UE->UE_mode[0]=PUSCH;} @@ -982,8 +1002,8 @@ int main(int argc, char **argv) UE->if_inst->phy_config_request = nr_ue_phy_config_request; UE->if_inst->dl_indication = nr_ue_dl_indication; UE->if_inst->ul_indication = dummy_nr_ue_ul_indication; - UE->prb_interpolation = prb_inter; - + UE->chest_freq = chest_type[0]; + UE->chest_time = chest_type[1]; UE_mac->if_module = nr_ue_if_module_init(0); @@ -1103,14 +1123,9 @@ int main(int argc, char **argv) while ((round<num_rounds) && (UE_harq_process->ack==0)) { clear_nr_nfapi_information(RC.nrmac[0], 0, frame, slot); - UE_info->UE_sched_ctrl.harq_processes[harq_pid].ndi = !(trial&1); - - UE_info->UE_sched_ctrl.harq_processes[harq_pid].round = round; - for (int i=0; i<MAX_NUM_CORESET; i++) - gNB_mac->pdcch_cand[i] = 0; - + if (css_flag == 0) { nr_schedule_ue_spec(0, frame, slot); } else { diff --git a/openair1/SIMULATION/NR_PHY/ulschsim.c b/openair1/SIMULATION/NR_PHY/ulschsim.c index 8a0a2d51441b383715a3ebae1f968b3b639025f3..5392424285729463be925948ee877d336209cc7d 100644 --- a/openair1/SIMULATION/NR_PHY/ulschsim.c +++ b/openair1/SIMULATION/NR_PHY/ulschsim.c @@ -141,6 +141,7 @@ int main(int argc, char **argv) uint16_t nb_rb = 50; uint8_t Imcs = 9; uint8_t Nl = 1; + uint8_t max_ldpc_iterations = 5; double DS_TDL = .03; @@ -395,6 +396,8 @@ int main(int argc, char **argv) frame_parms->N_RB_DL = N_RB_DL; frame_parms->N_RB_UL = N_RB_UL; frame_parms->Ncp = extended_prefix_flag ? EXTENDED : NORMAL; + gNB->max_ldpc_iterations = max_ldpc_iterations; + crcTableInit(); memcpy(&gNB->frame_parms, frame_parms, sizeof(NR_DL_FRAME_PARMS)); diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 9a3b29a637588485547a82027df24a76e7349b14..2a3730c1d4695bc556a01bca018558c69e847461 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -312,16 +312,15 @@ int main(int argc, char **argv) float roundStats[100]; double effRate[100]; double effTP[100]; - float eff_tp_check = 0.7; + float eff_tp_check = 100; uint8_t snrRun; - int prb_inter = 0; + int chest_type[2] = {0}; int enable_ptrs = 0; int modify_dmrs = 0; /* L_PTRS = ptrs_arg[0], K_PTRS = ptrs_arg[1] */ int ptrs_arg[2] = {-1,-1};// Invalid values - /* mapping type = dmrs_arg[0], Add Pos = dmrs_arg[1], dmrs config type = dmrs_arg[2] */ - int dmrs_arg[3] = {-1,-1,-1};// Invalid values + int dmrs_arg[4] = {-1,-1,-1,-1};// Invalid values uint16_t ptrsSymPos = 0; uint16_t ptrsSymbPerSlot = 0; uint16_t ptrsRePerSymb = 0; @@ -338,6 +337,7 @@ int main(int argc, char **argv) int ibwps=24; int ibwp_rboffset=41; int params_from_file = 0; + int max_ldpc_iterations = 5; if ( load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) == 0 ) { exit_fun("[NR_ULSIM] Error, configuration module init failed\n"); } @@ -348,7 +348,7 @@ int main(int argc, char **argv) /* initialize the sin-cos table */ InitSinLUT(); - while ((c = getopt(argc, argv, "a:b:c:d:ef:g:h:ikl:m:n:p:r:s:t:u:w:y:z:F:G:H:M:N:PR:S:T:U:L:Z:W:")) != -1) { + while ((c = getopt(argc, argv, "a:b:c:d:ef:g:h:i:kl:m:n:p:q:r:s:t:u:w:y:z:F:G:H:I:M:N:PR:S:T:U:L:ZW:")) != -1) { printf("handling optarg %c\n",c); switch (c) { @@ -441,7 +441,9 @@ int main(int argc, char **argv) break; case 'i': - prb_inter=1; + for(i=0; i < atoi(optarg); i++){ + chest_type[i] = atoi(argv[optind++]); + } break; case 'k': @@ -468,6 +470,10 @@ int main(int argc, char **argv) case 'p': extended_prefix_flag = 1; break; + + case 'q': + mcs_table = atoi(optarg); + break; case 'r': nb_rb = atoi(optarg); @@ -487,7 +493,7 @@ int main(int argc, char **argv) break; case 't': - eff_tp_check = (float)atoi(optarg)/100; + eff_tp_check = (float)atoi(optarg); break; /* @@ -519,7 +525,7 @@ int main(int argc, char **argv) exit(-1); } break; - + case 'F': input_fd = fopen(optarg, "r"); if (input_fd == NULL) { @@ -536,6 +542,10 @@ int main(int argc, char **argv) slot = atoi(optarg); break; + case 'I': + max_ldpc_iterations = atoi(optarg); + break; + case 'M': // SSB_positions = atoi(optarg); break; @@ -597,13 +607,14 @@ int main(int argc, char **argv) printf("-f Number of frames to simulate\n"); printf("-g [A,B,C,D,E,F,G] Use 3GPP SCM (A,B,C,D) or 36-101 (E-EPA,F-EVA,G-ETU) models (ignores delay spread and Ricean factor)\n"); printf("-h This message\n"); - printf("-i Activate PRB based averaging for channel estimation. Frequncy domain interpolation by default.\n"); + printf("-i Change channel estimation technique. Arguments list: Number of arguments=2, Frequency domain {0:Linear interpolation, 1:PRB based averaging}, Time domain {0:Estimates of last DMRS symbol, 1:Average of DMRS symbols}. e.g. -i 2 1 0\n"); //printf("-j Relative strength of second intefering eNB (in dB) - cell_id mod 3 = 2\n"); printf("-s Starting SNR, runs from SNR0 to SNR0 + 10 dB if ending SNR isn't given\n"); printf("-m MCS value\n"); printf("-n Number of trials to simulate\n"); printf("-p Use extended prefix mode\n"); - //printf("-t Delay spread for multipath channel\n"); + printf("-q MCS table\n"); + printf("-t Delay spread for multipath channel\n"); printf("-u Set the numerology\n"); printf("-w Start PRB for PUSCH\n"); //printf("-x Transmission mode (1,2,6 for the moment)\n"); @@ -613,7 +624,8 @@ int main(int argc, char **argv) //printf("-C Generate Calibration information for Abstraction (effective SNR adjustment to remove Pe bias w.r.t. AWGN)\n"); printf("-F Input filename (.txt format) for RX conformance testing\n"); printf("-G Offset of samples to read from file (0 default)\n"); - printf("-L <log level, 0(errors), 1(warning), 2(info) 3(debug) 4 (trace)>\n"); + printf("-L <log level, 0(errors), 1(warning), 2(info) 3(debug) 4 (trace)>\n"); + printf("-I Maximum LDPC decoder iterations\n"); printf("-M Multiple SSB positions in burst\n"); printf("-N Nid_cell\n"); printf("-O oversampling factor (1,2,4,8,16)\n"); @@ -621,8 +633,8 @@ int main(int argc, char **argv) printf("-t Acceptable effective throughput (in percentage)\n"); printf("-S Ending SNR, runs from SNR0 to SNR1\n"); printf("-P Print ULSCH performances\n"); - printf("-T Enable PTRS, arguments list L_PTRS{0,1,2} K_PTRS{2,4}, e.g. -T 2 0 2 \n"); - printf("-U Change DMRS Config, arguments list DMRS TYPE{0=A,1=B} DMRS AddPos{0:3}, e.g. -U 2 0 2 \n"); + printf("-T Enable PTRS, arguments list: Number of arguments=2 L_PTRS{0,1,2} K_PTRS{2,4}, e.g. -T 2 0 2 \n"); + printf("-U Change DMRS Config, arguments list: Number of arguments=4, DMRS Mapping Type{0=A,1=B}, DMRS AddPos{0:3}, DMRS Config Type{1,2}, Number of CDM groups without data{1,2,3} e.g. -U 4 0 2 0 1 \n"); printf("-Q If -F used, read parameters from file\n"); printf("-Z If -Z is used, SC-FDMA or transform precoding is enabled in Uplink \n"); printf("-W Num of layer for PUSCH\n"); @@ -717,7 +729,7 @@ int main(int argc, char **argv) gNB->UL_INFO.crc_ind.crc_list = (nfapi_nr_crc_t *)malloc(NB_UE_INST*sizeof(nfapi_nr_crc_t)); gNB->UL_INFO.rx_ind.number_of_pdus = 0; gNB->UL_INFO.crc_ind.number_crcs = 0; - gNB->prb_interpolation = prb_inter; + gNB->max_ldpc_iterations = max_ldpc_iterations; frame_parms = &gNB->frame_parms; //to be initialized I suppose (maybe not necessary for PBCH) frame_parms->N_RB_DL = N_RB_DL; @@ -781,6 +793,8 @@ int main(int argc, char **argv) cfg->carrier_config.num_tx_ant.value = 1; cfg->carrier_config.num_rx_ant.value = n_rx; // nr_phy_config_request_sim(gNB,N_RB_DL,N_RB_DL,mu,0,0x01); + gNB->chest_freq = chest_type[0]; + gNB->chest_time = chest_type[1]; phy_init_nr_gNB(gNB,0,1); N_RB_DL = gNB->frame_parms.N_RB_DL; @@ -796,7 +810,7 @@ int main(int argc, char **argv) PHY_vars_UE_g[0][0] = UE; memcpy(&UE->frame_parms, frame_parms, sizeof(NR_DL_FRAME_PARMS)); UE->frame_parms.nb_antennas_tx = n_tx; - UE->frame_parms.nb_antennas_rx = 1; + UE->frame_parms.nb_antennas_rx = 0; if (init_nr_ue_signal(UE, 1) != 0) { printf("Error at UE NR initialisation\n"); @@ -895,6 +909,7 @@ int main(int argc, char **argv) dmrs_config_type = pusch_dmrs_type1; else if(dmrs_arg[2] == 2) dmrs_config_type = pusch_dmrs_type2; + num_dmrs_cdm_grps_no_data = dmrs_arg[3]; } uint8_t length_dmrs = pusch_len1; @@ -983,7 +998,6 @@ int main(int argc, char **argv) int slot_length = slot_offset - frame_parms->get_samples_slot_timestamp(slot-1,frame_parms,0); if (input_fd != NULL) { - AssertFatal(frame_parms->nb_antennas_rx == 1, "nb_ant != 1\n"); // 800 samples is N_TA_OFFSET for FR1 @ 30.72 Ms/s, AssertFatal(frame_parms->subcarrier_spacing==30000,"only 30 kHz for file input for now (%d)\n",frame_parms->subcarrier_spacing); @@ -1011,18 +1025,21 @@ int main(int argc, char **argv) printf("harq_pid %d\n",harq_pid); } fseek(input_fd,file_offset*sizeof(int16_t)*2,SEEK_SET); - read_errors+=fread((void*)&gNB->common_vars.rxdata[0][slot_offset-delay], - sizeof(int16_t), - slot_length<<1, - input_fd); - if (read_errors==0) { - printf("error reading file\n"); - exit(1); + for (int irx=0; irx<frame_parms->nb_antennas_rx; irx++) { + fseek(input_fd,irx*(slot_length+15)*sizeof(int16_t)*2,SEEK_SET); // matlab adds samlples to the end to emulate channel delay + read_errors+=fread((void*)&gNB->common_vars.rxdata[irx][slot_offset-delay], + sizeof(int16_t), + slot_length<<1, + input_fd); + if (read_errors==0) { + printf("error reading file\n"); + exit(1); + } + for (int i=0;i<16;i+=2) printf("slot_offset %d : %d,%d\n", + slot_offset, + ((int16_t*)&gNB->common_vars.rxdata[irx][slot_offset])[i], + ((int16_t*)&gNB->common_vars.rxdata[irx][slot_offset])[1+i]); } - for (int i=0;i<16;i+=2) printf("slot_offset %d : %d,%d\n", - slot_offset, - ((int16_t*)&gNB->common_vars.rxdata[0][slot_offset])[i], - ((int16_t*)&gNB->common_vars.rxdata[0][slot_offset])[1+i]); mod_order = nr_get_Qm_ul(Imcs, mcs_table); code_rate = nr_get_code_rate_ul(Imcs, mcs_table); @@ -1389,11 +1406,11 @@ int main(int argc, char **argv) &gNB->pusch_vars[0]->llr_layers[0][0],(nb_symb_sch-1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size * mod_order,1,0); if (precod_nbr_layers==2) { - LOG_M("rxsigF1_ext.m","rxsF1_ext", - &gNB->pusch_vars[0]->rxdataF_ext[1][start_symbol*NR_NB_SC_PER_RB * pusch_pdu->rb_size],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); + LOG_M("rxsigF1_ext.m","rxsF1_ext", + &gNB->pusch_vars[0]->rxdataF_ext[1][start_symbol*NR_NB_SC_PER_RB * pusch_pdu->rb_size],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); LOG_M("chestF3.m","chF3", - &gNB->pusch_vars[0]->ul_ch_estimates[3][start_symbol*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size,1,1); + &gNB->pusch_vars[0]->ul_ch_estimates[3][start_symbol*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size,1,1); LOG_M("chestF3_ext.m","chF3_ext", &gNB->pusch_vars[0]->ul_ch_estimates_ext[3][(start_symbol+1)*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))], @@ -1553,7 +1570,12 @@ int main(int argc, char **argv) roundStats[snrRun],effRate[snrRun],effTP[snrRun],TBS); FILE *fd=fopen("nr_ulsim.log","w"); + if (fd == NULL) { + printf("Problem with filename %s\n", "nr_ulsim.log"); + exit(-1); + } dump_pusch_stats(fd,gNB); + fclose(fd); printf("*****************************************\n"); printf("\n"); @@ -1583,7 +1605,7 @@ int main(int argc, char **argv) if(n_trials==1) break; - if (effRate[snrRun] > (eff_tp_check*TBS)) { + if ((float)effTP[snrRun] >= eff_tp_check) { printf("*************\n"); printf("PUSCH test OK\n"); printf("*************\n"); @@ -1613,17 +1635,19 @@ int main(int argc, char **argv) length_dmrs, num_dmrs_cdm_grps_no_data); - LOG_M("ulsimStats.m","SNR",snrStats,snrRun,1,7); - LOG_MM("ulsimStats.m","BLER_round0",blerStats[0],snrRun,1,7); - LOG_MM("ulsimStats.m","BLER_round1",blerStats[1],snrRun,1,7); - LOG_MM("ulsimStats.m","BLER_round2",blerStats[2],snrRun,1,7); - LOG_MM("ulsimStats.m","BLER_round3",blerStats[3],snrRun,1,7); - LOG_MM("ulsimStats.m","BER_round0",berStats[0],snrRun,1,7); - LOG_MM("ulsimStats.m","BER_round1",berStats[1],snrRun,1,7); - LOG_MM("ulsimStats.m","BER_round2",berStats[2],snrRun,1,7); - LOG_MM("ulsimStats.m","BER_round3",berStats[3],snrRun,1,7); - LOG_MM("ulsimStats.m","EffRate",effRate,snrRun,1,7); - LOG_MM("ulsimStats.m","EffTP",effTP,snrRun,1,7); + char opStatsFile[50]; + sprintf(opStatsFile, "ulsimStats_z%d.m", n_rx); + LOG_M(opStatsFile,"SNR",snrStats,snrRun,1,7); + LOG_MM(opStatsFile,"BLER_round0",blerStats[0],snrRun,1,7); + LOG_MM(opStatsFile,"BLER_round1",blerStats[1],snrRun,1,7); + LOG_MM(opStatsFile,"BLER_round2",blerStats[2],snrRun,1,7); + LOG_MM(opStatsFile,"BLER_round3",blerStats[3],snrRun,1,7); + LOG_MM(opStatsFile,"BER_round0",berStats[0],snrRun,1,7); + LOG_MM(opStatsFile,"BER_round1",berStats[1],snrRun,1,7); + LOG_MM(opStatsFile,"BER_round2",berStats[2],snrRun,1,7); + LOG_MM(opStatsFile,"BER_round3",berStats[3],snrRun,1,7); + LOG_MM(opStatsFile,"EffRate",effRate,snrRun,1,7); + LOG_MM(opStatsFile,"EffTP",effTP,snrRun,1,7); free(test_input_bit); free(estimated_output_bit); diff --git a/openair2/GNB_APP/L1_nr_paramdef.h b/openair2/GNB_APP/L1_nr_paramdef.h index 90cd9aae2900054567423a3bcadc822b7c6eedab..1e5122956e0a4532ec79bff7b6083a5b1ed7cdcc 100644 --- a/openair2/GNB_APP/L1_nr_paramdef.h +++ b/openair2/GNB_APP/L1_nr_paramdef.h @@ -51,6 +51,7 @@ #define CONFIG_STRING_L1_PUCCH0_DTX_THRESHOLD "pucch0_dtx_threshold" #define CONFIG_STRING_L1_PRACH_DTX_THRESHOLD "prach_dtx_threshold" #define CONFIG_STRING_L1_PUSCH_DTX_THRESHOLD "pusch_dtx_threshold" +#define CONFIG_STRING_L1_MAX_LDPC_ITERATIONS "max_ldpc_iterations" /*----------------------------------------------------------------------------------------------------------------------------------------------------*/ /* L1 configuration parameters */ /* optname helpstr paramflags XXXptr defXXXval type numelt */ @@ -69,7 +70,8 @@ {CONFIG_STRING_L1_OFDM_OFFSET_DIVISOR, NULL, 0, uptr:NULL, defuintval:8, TYPE_UINT, 0}, \ {CONFIG_STRING_L1_PUCCH0_DTX_THRESHOLD, NULL, 0, uptr:NULL, defintval:100, TYPE_UINT, 0}, \ {CONFIG_STRING_L1_PRACH_DTX_THRESHOLD, NULL, 0, uptr:NULL, defintval:150, TYPE_UINT, 0}, \ -{CONFIG_STRING_L1_PUSCH_DTX_THRESHOLD, NULL, 0, uptr:NULL, defintval:50, TYPE_UINT, 0} \ +{CONFIG_STRING_L1_PUSCH_DTX_THRESHOLD, NULL, 0, uptr:NULL, defintval:50, TYPE_UINT, 0}, \ +{CONFIG_STRING_L1_MAX_LDPC_ITERATIONS, NULL, 0, uptr:NULL, defintval:5, TYPE_UINT, 0}, \ } #define L1_CC_IDX 0 #define L1_TRANSPORT_N_PREFERENCE_IDX 1 @@ -85,6 +87,7 @@ #define L1_PUCCH0_DTX_THRESHOLD 11 #define L1_PRACH_DTX_THRESHOLD 12 #define L1_PUSCH_DTX_THRESHOLD 13 +#define L1_MAX_LDPC_ITERATIONS 14 /*----------------------------------------------------------------------------------------------------------------------------------------------------*/ #endif diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 6ceab3b97d1ea0fb7fad61d2004e5ca403a19d14..21655a74d52e9975eb605578b9cde94309669319 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -727,6 +727,7 @@ void RCconfig_NR_L1(void) { RC.gNB[j]->pucch0_thres = *(L1_ParamList.paramarray[j][L1_PUCCH0_DTX_THRESHOLD].uptr); RC.gNB[j]->prach_thres = *(L1_ParamList.paramarray[j][L1_PRACH_DTX_THRESHOLD].uptr); RC.gNB[j]->pusch_thres = *(L1_ParamList.paramarray[j][L1_PUSCH_DTX_THRESHOLD].uptr); + RC.gNB[j]->max_ldpc_iterations = *(L1_ParamList.paramarray[j][L1_MAX_LDPC_ITERATIONS].uptr); RC.gNB[j]->num_ulprbbl = num_prbbl; RC.gNB[j]->ap_N1 = N1; RC.gNB[j]->ap_N2 = N2; diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index 217f9d74a793ea1de5f26bf599ec78d8c9a6dad8..e2a7efcaa0559f5f15b10e5703455b9e1b8662cb 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -3498,6 +3498,22 @@ void csi_period_offset(NR_CSI_ReportConfig_t *csirep, } } +uint32_t get_Y(NR_SearchSpace_t *ss, int slot, rnti_t rnti) { + + if(ss->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_common) + return 0; + + const int cid = *ss->controlResourceSetId%3; + const uint32_t A[3] = {39827, 39829, 39839}; + const uint32_t D = 65537; + uint32_t Y; + + Y = (A[cid] * rnti) % D; + for (int s = 0; s < slot; s++) + Y = (A[cid] * Y) % D; + + return Y; +} void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config, frame_t frameP, diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h index 102e56ee57907bd9292ec10fc35848f6e00beaa0..2b8d3c6652770bb5df056a1d3c77319f096d2b91 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h @@ -37,6 +37,8 @@ #include "nr_mac.h" #include "openair1/PHY/impl_defs_nr.h" +uint32_t get_Y(NR_SearchSpace_t *ss, int slot, rnti_t rnti); + uint64_t from_nrarfcn(int nr_bandP, uint8_t scs_index, uint32_t dl_nrarfcn); uint32_t to_nrarfcn(int nr_bandP, uint64_t dl_CarrierFreq, uint8_t scs_index, uint32_t bw); diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index f7a21cd80c584b23b558896ce512e6c84c8d0fe6..da39d3e0ed68ccefcaf789b4caa289360bb7007c 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -563,7 +563,6 @@ typedef struct ssb_list_info { } ssb_list_info_t; void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15, fapi_nr_dl_config_request_t *dl_config, int rnti_type, int ss_id); -void fill_dci_search_candidates(NR_SearchSpace_t *ss,fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15); /*@}*/ #endif /*__LAYER2_MAC_DEFS_H__ */ diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index 6ff2c78efbd443af5615ec4d56affd190e45c5b7..01673c22d6f5956744d5b035b792c33782ef7f5e 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -250,10 +250,7 @@ int nr_write_ce_ulsch_pdu(uint8_t *mac_ce, uint16_t *crnti, NR_BSR_SHORT *truncated_bsr, NR_BSR_SHORT *short_bsr, - NR_BSR_LONG *long_bsr - ); - -void fill_dci_search_candidates(NR_SearchSpace_t *ss,fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15); + NR_BSR_LONG *long_bsr); void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15, fapi_nr_dl_config_request_t *dl_config, int rnti_type, int ss_id); @@ -276,7 +273,7 @@ uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac, uint64_t *dci_pdu, dci_pdu_rel15_t *nr_pdci_info_extracted); -NR_PUSCH_TimeDomainResourceAllocationList_t *choose_ul_tda_list(NR_PUSCH_Config_t *pusch_Config,NR_PUSCH_ConfigCommon_t *pusch_ConfigCommon); +NR_PUSCH_TimeDomainResourceAllocationList_t *choose_ul_tda_list(const NR_PUSCH_Config_t *pusch_Config,NR_PUSCH_ConfigCommon_t *pusch_ConfigCommon); NR_PDSCH_TimeDomainResourceAllocationList_t *choose_dl_tda_list(NR_PDSCH_Config_t *pdsch_Config,NR_PDSCH_ConfigCommon_t *pdsch_ConfigCommon); int8_t nr_ue_process_dci_time_dom_resource_assignment(NR_UE_MAC_INST_t *mac, @@ -455,7 +452,7 @@ int8_t nr_ue_process_dci_freq_dom_resource_assignment(nfapi_nr_ue_pusch_pdu_t *p uint16_t riv); void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15, fapi_nr_dl_config_request_t *dl_config, int rnti_type, int ss_id); -void fill_dci_search_candidates(NR_SearchSpace_t *ss,fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15); +void fill_dci_search_candidates(NR_SearchSpace_t *ss,fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15, int slot, int rnti); void build_ssb_to_ro_map(NR_UE_MAC_INST_t *mac); diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c index 0dfbbf2be333c03053be355e2d48b61a93f90915..9b618cdbfb4fda6696a86f305551f2fbb9a56ec1 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c @@ -49,7 +49,9 @@ //#define DEBUG_DCI -void fill_dci_search_candidates(NR_SearchSpace_t *ss,fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15) { +void fill_dci_search_candidates(NR_SearchSpace_t *ss, + fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15, + int slot, int rnti) { LOG_D(NR_MAC,"Filling search candidates for DCI\n"); @@ -57,6 +59,9 @@ void fill_dci_search_candidates(NR_SearchSpace_t *ss,fapi_nr_dl_config_dci_dl_pd uint8_t number_of_candidates=0; rel15->number_of_candidates=0; int i=0; + uint32_t Y = 0; + if (slot >= 0) + Y = get_Y(ss, slot, rnti); for (int maxL=16;maxL>0;maxL>>=1) { find_aggregation_candidates(&aggregation, &number_of_candidates, @@ -65,8 +70,17 @@ void fill_dci_search_candidates(NR_SearchSpace_t *ss,fapi_nr_dl_config_dci_dl_pd if (number_of_candidates>0) { LOG_D(NR_MAC,"L %d, number of candidates %d, aggregation %d\n",maxL,number_of_candidates,aggregation); rel15->number_of_candidates += number_of_candidates; + int N_cce_sym = 0; // nb of rbs of coreset per symbol + for (int i=0;i<6;i++) { + for (int t=0;t<8;t++) { + N_cce_sym+=((rel15->coreset.frequency_domain_resource[i]>>t)&1); + } + } + int N_cces = N_cce_sym*rel15->coreset.duration; for (int j=0; j<number_of_candidates; i++,j++) { - rel15->CCE[i] = j*aggregation; + int first_cce = aggregation * (( Y + CEILIDIV((j*N_cces),(aggregation*number_of_candidates)) + 0 ) % CEILIDIV(N_cces,aggregation)); + LOG_D(NR_MAC,"Candidate %d of %d first_cce %d (L %d N_cces %d Y %d)\n", j, number_of_candidates, first_cce, aggregation, N_cces, Y); + rel15->CCE[i] = first_cce; rel15->L[i] = aggregation; } } @@ -305,14 +319,14 @@ void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl } else { config_dci_pdu(mac, rel15, dl_config, NR_RNTI_RA, ss_id); } - fill_dci_search_candidates(ss, rel15); + fill_dci_search_candidates(ss, rel15, -1, -1); break; case WAIT_CONTENTION_RESOLUTION: LOG_D(NR_MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in Type1-PDCCH common random access search space (RA-Msg4)\n"); rel15->num_dci_options = 1; rel15->dci_format_options[0] = NR_DL_DCI_FORMAT_1_0; config_dci_pdu(mac, rel15, dl_config, NR_RNTI_TC, -1); - fill_dci_search_candidates(ss, rel15); + fill_dci_search_candidates(ss, rel15, -1, -1); break; default: break; @@ -384,7 +398,7 @@ void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl rel15->dci_format_options[0] = NR_DL_DCI_FORMAT_1_1; rel15->dci_format_options[1] = NR_UL_DCI_FORMAT_0_1; config_dci_pdu(mac, rel15, dl_config, NR_RNTI_C, ss_id); - fill_dci_search_candidates(ss, rel15); + fill_dci_search_candidates(ss, rel15, slot, mac->crnti); //#ifdef DEBUG_DCI LOG_D(NR_MAC, "[DCI_CONFIG] ss %d ue_Specific %p searchSpaceType->present %d dci_Formats %d\n", @@ -420,19 +434,4 @@ void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl AssertFatal(1==0,"Handle DCI searching when CellGroup without dedicated BWP\n"); } - // Search space 0, CORESET ID 0 - if (!get_softmodem_params()->nsa) { - NR_SearchSpace_t *ss0 = mac->search_space_zero; - if(ss0) { - fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15 = &dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15; - rel15->num_dci_options = 1; - rel15->dci_format_options[0] = NR_DL_DCI_FORMAT_1_0; - config_dci_pdu(mac, - rel15, - dl_config, - ((frame%2==mac->type0_PDCCH_CSS_config.sfn_c)&&(slot==mac->type0_PDCCH_CSS_config.n_0)) ? NR_RNTI_SI : NR_RNTI_C, - -1); - fill_dci_search_candidates(ss0, rel15); - } - } } diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index da6b45ab67c6fd6409e8da4476d66999b29264b2..8004286413e09cb145347597b0770492da13b2cc 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -253,7 +253,7 @@ NR_PDSCH_TimeDomainResourceAllocationList_t *choose_dl_tda_list(NR_PDSCH_Config_ return(pdsch_TimeDomainAllocationList); } -NR_PUSCH_TimeDomainResourceAllocationList_t *choose_ul_tda_list(NR_PUSCH_Config_t *pusch_Config,NR_PUSCH_ConfigCommon_t *pusch_ConfigCommon) { +NR_PUSCH_TimeDomainResourceAllocationList_t *choose_ul_tda_list(const NR_PUSCH_Config_t *pusch_Config,NR_PUSCH_ConfigCommon_t *pusch_ConfigCommon) { NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList=NULL; @@ -579,7 +579,7 @@ int8_t nr_ue_process_dci_time_dom_resource_assignment(NR_UE_MAC_INST_t *mac, if(pusch_config_pdu != NULL){ if (pusch_TimeDomainAllocationList && use_default==false) { if (time_domain_ind >= pusch_TimeDomainAllocationList->list.count) { - LOG_E(MAC, "time_domain_ind %d >= pusch->TimeDomainAllocationList->list.count %d\n", + LOG_E(NR_MAC, "time_domain_ind %d >= pusch->TimeDomainAllocationList->list.count %d\n", time_domain_ind, pusch_TimeDomainAllocationList->list.count); pusch_config_pdu->start_symbol_index=0; pusch_config_pdu->nr_of_symbols=0; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 49aebb7daa7781684aaceaf64978b22a6315aab5..140fde407fa5caade817e09df6467ae36fd26455 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -697,8 +697,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, pusch_config_pdu->bwp_start = NRRIV2PRBOFFSET(ubwpc->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); pusch_config_pdu->bwp_size = n_RB_ULBWP; - AssertFatal(ubwpd->pusch_Config != NULL,"pusch_Config shouldn't be null\n"); - NR_PUSCH_Config_t *pusch_Config = ubwpd->pusch_Config->choice.setup; + const NR_PUSCH_Config_t *pusch_Config = ubwpd? ubwpd->pusch_Config->choice.setup : NULL; // Basic sanity check for MCS value to check for a false or erroneous DCI if (dci->mcs > 28) { @@ -776,10 +775,10 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, pusch_config_pdu->dfts_ofdm.low_papr_group_number); } else { - if (pusch_config_pdu->scid == 0 && + if (pusch_config_pdu->scid == 0 && NR_DMRS_ulconfig && NR_DMRS_ulconfig->transformPrecodingDisabled->scramblingID0) pusch_config_pdu->ul_dmrs_scrambling_id = *NR_DMRS_ulconfig->transformPrecodingDisabled->scramblingID0; - if (pusch_config_pdu->scid == 1 && + if (pusch_config_pdu->scid == 1 && NR_DMRS_ulconfig && NR_DMRS_ulconfig->transformPrecodingDisabled->scramblingID1) pusch_config_pdu->ul_dmrs_scrambling_id = *NR_DMRS_ulconfig->transformPrecodingDisabled->scramblingID1; } @@ -1100,7 +1099,7 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in if (mac->ra.ra_state == WAIT_CONTENTION_RESOLUTION) rel15->dci_format_options[1] = NR_UL_DCI_FORMAT_0_0; // msg3 retransmission config_dci_pdu(mac, rel15, dl_config, mac->ra.ra_state == WAIT_RAR ? NR_RNTI_RA : NR_RNTI_TC , mac->ra.ss->searchSpaceId); - fill_dci_search_candidates(mac->ra.ss, rel15); + fill_dci_search_candidates(mac->ra.ss, rel15, -1 , -1); dl_config->number_pdus = 1; LOG_D(MAC,"mac->cg %p: Calling fill_scheduled_response rnti %x, type0_pdcch, num_pdus %d\n",mac->cg,rel15->rnti,dl_config->number_pdus); fill_scheduled_response(&scheduled_response, dl_config, NULL, NULL, mod_id, cc_id, rx_frame, rx_slot, dl_info->thread_id, dl_info->phy_data); @@ -2790,7 +2789,7 @@ void nr_ue_sib1_scheduler(module_id_t module_idP, rel15->num_dci_options = 1; rel15->dci_format_options[0] = NR_DL_DCI_FORMAT_1_0; config_dci_pdu(mac, rel15, dl_config, NR_RNTI_SI, -1); - fill_dci_search_candidates(mac->search_space_zero, rel15); + fill_dci_search_candidates(mac->search_space_zero, rel15, -1, -1); if(mac->type0_PDCCH_CSS_config.type0_pdcch_ss_mux_pattern == 1){ // same frame as ssb diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index 7dda0ab5ebc0525a429392095e4a30e52205e06a..b0718067a91543b9c8572f422ca85acb0f5feca1 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -646,13 +646,11 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP, ra->msg3_dcch_dtch = false; LOG_I(NR_MAC,"Added new RA process for UE RNTI %04x with initial CellGroup\n", rnti); } else { // CellGroup has been updated - NR_ServingCellConfigCommon_t *scc = RC.nrmac[Mod_idP]->common_channels[0].ServingCellConfigCommon; NR_UE_info_t * UE = find_nr_UE(&RC.nrmac[Mod_idP]->UE_info,rnti); if (!UE) { LOG_E(NR_MAC, "Can't find UE %04x\n", rnti); return -1; } - int target_ss; UE->CellGroup = CellGroup; LOG_I(NR_MAC,"Modified rnti %04x with CellGroup\n",rnti); @@ -664,30 +662,7 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP, // add all available DL HARQ processes for this UE in SA create_dl_harq_list(sched_ctrl, pdsch); } - // update coreset/searchspace - void *bwpd = NULL; - NR_BWP_t *genericParameters = NULL; - target_ss = NR_SearchSpace__searchSpaceType_PR_common; - if ((sched_ctrl->active_bwp)) { - target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific; - bwpd = (void*)sched_ctrl->active_bwp->bwp_Dedicated; - genericParameters = &sched_ctrl->active_bwp->bwp_Common->genericParameters; - } - else if (CellGroup->spCellConfig && - CellGroup->spCellConfig->spCellConfigDedicated && - (CellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP)) { - target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific; - bwpd = (void*)CellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP; - genericParameters = &scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters; - } - sched_ctrl->search_space = get_searchspace(sib1 ? sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL, scc, bwpd, target_ss); - sched_ctrl->coreset = get_coreset(RC.nrmac[Mod_idP], scc, bwpd, sched_ctrl->search_space, target_ss); - sched_ctrl->sched_pdcch = set_pdcch_structure(RC.nrmac[Mod_idP], - sched_ctrl->search_space, - sched_ctrl->coreset, - scc, - genericParameters, - RC.nrmac[Mod_idP]->type0_PDCCH_CSS_config); + sched_ctrl->maxL = 2; if (CellGroup->spCellConfig && diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c index d7e2c78c3513472468e05fe22691722e964603a4..385cf5af16fe8fee26171a29008f4891b2e6090f 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c @@ -117,8 +117,6 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, protocol_ctxt_t ctxt={0}; PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, NOT_A_RNTI, frame, slot,module_idP); - char stats_output[16384]; - gNB_MAC_INST *gNB = RC.nrmac[module_idP]; NR_COMMON_channels_t *cc = gNB->common_channels; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; @@ -146,8 +144,6 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, nr_rrc_trigger(&ctxt, 0 /*CC_id*/, frame, slot >> *scc->ssbSubcarrierSpacing); } - for (int i=0; i<MAX_NUM_CORESET; i++) - RC.nrmac[module_idP]->pdcch_cand[i] = 0; for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { //mbsfn_status[CC_id] = 0; @@ -180,9 +176,10 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, if ((slot == 0) && (frame & 127) == 0) { - stats_output[0]='\0'; - dump_mac_stats(RC.nrmac[module_idP],stats_output,16384,true); - LOG_I(NR_MAC,"Frame.Slot %d.%d\n%s\n",frame,slot,stats_output); + char stats_output[16384]; + stats_output[0] = '\0'; + dump_mac_stats(RC.nrmac[module_idP], stats_output, sizeof(stats_output), true); + LOG_I(NR_MAC, "Frame.Slot %d.%d\n%s\n", frame, slot, stats_output); } nr_mac_update_timers(module_idP, frame, slot); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index eb05ec5e83569751a8f1bc6711bd8fb28217c265..e3d3a5409d706dd6251f728afdd7f06f2ef3b83f 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -537,167 +537,164 @@ void nr_initiate_ra_proc(module_id_t module_idP, } for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) { + NR_RA_t *ra = &cc->ra[i]; - pr_found = 0; - const NR_UE_info_t * UE = find_nr_UE(&nr_mac->UE_info, ra->rnti); - if (UE) { - // the UE is already registered - LOG_W(NR_MAC, "Received RA for existing RNTI %04x\n", ra->rnti); + if (ra->state != RA_IDLE) continue; - } - if (ra->state == RA_IDLE) { - for(int j = 0; j < ra->preambles.num_preambles; j++) { - //check if the preamble received correspond to one of the listed or configured preambles - if (preamble_index == ra->preambles.preamble_list[j]) { - if (ra->rnti == 0 && get_softmodem_params()->nsa) - continue; - pr_found=1; - break; - } - } - if (pr_found == 0) { - continue; + + pr_found = 0; + + for(int j = 0; j < ra->preambles.num_preambles; j++) { + //check if the preamble received correspond to one of the listed or configured preambles + if (preamble_index == ra->preambles.preamble_list[j]) { + if (ra->rnti == 0 && get_softmodem_params()->nsa) + continue; + pr_found=1; + break; } + } + if (pr_found == 0) { + continue; + } - uint16_t ra_rnti; + uint16_t ra_rnti; - // ra_rnti from 5.1.3 in 38.321 - // FK: in case of long PRACH the phone seems to expect the subframe number instead of the slot number here. - if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.present - == NR_RACH_ConfigCommon__prach_RootSequenceIndex_PR_l839) - ra_rnti = 1 + symbol + (9 /*slotP*/ * 14) + (freq_index * 14 * 80) + (ul_carrier_id * 14 * 80 * 8); - else - ra_rnti = 1 + symbol + (slotP * 14) + (freq_index * 14 * 80) + (ul_carrier_id * 14 * 80 * 8); - - // This should be handled differently when we use the initialBWP for RA - ra->dl_bwp_id = 0;//TODO - ra->ul_bwp_id = 0; - NR_BWP_Downlink_t *bwp=NULL; - if (ra->CellGroup && ra->CellGroup->spCellConfig && ra->CellGroup->spCellConfig->spCellConfigDedicated) { - if (ra->CellGroup->spCellConfig->spCellConfigDedicated->firstActiveDownlinkBWP_Id && - ra->CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList) { - ra->dl_bwp_id = *ra->CellGroup->spCellConfig->spCellConfigDedicated->firstActiveDownlinkBWP_Id; - bwp = ra->CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->dl_bwp_id - 1]; - } - if (ra->CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig && - ra->CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id) - ra->ul_bwp_id = *ra->CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id; - } + // ra_rnti from 5.1.3 in 38.321 + // FK: in case of long PRACH the phone seems to expect the subframe number instead of the slot number here. + if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.present + == NR_RACH_ConfigCommon__prach_RootSequenceIndex_PR_l839) + ra_rnti = 1 + symbol + (9 /*slotP*/ * 14) + (freq_index * 14 * 80) + (ul_carrier_id * 14 * 80 * 8); + else + ra_rnti = 1 + symbol + (slotP * 14) + (freq_index * 14 * 80) + (ul_carrier_id * 14 * 80 * 8); + + // This should be handled differently when we use the initialBWP for RA + ra->dl_bwp_id = 0;//TODO + ra->ul_bwp_id = 0; + NR_BWP_Downlink_t *bwp=NULL; + if (ra->CellGroup && ra->CellGroup->spCellConfig && ra->CellGroup->spCellConfig->spCellConfigDedicated) { + if (ra->CellGroup->spCellConfig->spCellConfigDedicated->firstActiveDownlinkBWP_Id && + ra->CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList) { + ra->dl_bwp_id = *ra->CellGroup->spCellConfig->spCellConfigDedicated->firstActiveDownlinkBWP_Id; + bwp = ra->CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->dl_bwp_id - 1]; + } + if (ra->CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig && + ra->CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id) + ra->ul_bwp_id = *ra->CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id; + } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 1); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 1); - LOG_D(NR_MAC, - "[gNB %d][RAPROC] CC_id %d Frame %d, Slot %d Initiating RA procedure for preamble index %d\n", + LOG_D(NR_MAC, + "[gNB %d][RAPROC] CC_id %d Frame %d, Slot %d Initiating RA procedure for preamble index %d\n", + module_idP, + CC_id, + frameP, + slotP, + preamble_index); + + uint8_t beam_index = ssb_index_from_prach(module_idP, frameP, slotP, preamble_index, freq_index, symbol); + + // the UE sent a RACH either for starting RA procedure or RA procedure failed and UE retries + if (ra->cfra) { + // if the preamble received correspond to one of the listed + if (!(preamble_index == ra->preambles.preamble_list[beam_index])) { + LOG_E( + NR_MAC, + "[gNB %d][RAPROC] FAILURE: preamble %d does not correspond to any of the ones in rach_ConfigDedicated\n", module_idP, - CC_id, - frameP, - slotP, preamble_index); - - uint8_t beam_index = ssb_index_from_prach(module_idP, frameP, slotP, preamble_index, freq_index, symbol); - - // the UE sent a RACH either for starting RA procedure or RA procedure failed and UE retries - if (ra->cfra) { - // if the preamble received correspond to one of the listed - if (!(preamble_index == ra->preambles.preamble_list[beam_index])) { - LOG_E( - NR_MAC, - "[gNB %d][RAPROC] FAILURE: preamble %d does not correspond to any of the ones in rach_ConfigDedicated\n", - module_idP, - preamble_index); - continue; // if the PRACH preamble does not correspond to any of the ones sent through RRC abort RA proc - } + continue; // if the PRACH preamble does not correspond to any of the ones sent through RRC abort RA proc } - LOG_D(NR_MAC, "Frame %d, Slot %d: Activating RA process \n", frameP, slotP); - ra->state = Msg2; - ra->timing_offset = timing_offset; - ra->preamble_slot = slotP; - - NR_SearchSpaceId_t ra_SearchSpace = 0; - struct NR_PDCCH_ConfigCommon__commonSearchSpaceList *commonSearchSpaceList = NULL; - NR_BWP_t *genericParameters = NULL; - if(bwp) { - commonSearchSpaceList = bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList; - ra_SearchSpace = *bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->ra_SearchSpace; - genericParameters = &bwp->bwp_Common->genericParameters; - } else { - commonSearchSpaceList = scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList; - ra_SearchSpace = *scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->ra_SearchSpace; - genericParameters = &scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters; - } - AssertFatal(commonSearchSpaceList->list.count > 0, "common SearchSpace list has 0 elements\n"); + } + LOG_D(NR_MAC, "Frame %d, Slot %d: Activating RA process \n", frameP, slotP); + ra->state = Msg2; + ra->timing_offset = timing_offset; + ra->preamble_slot = slotP; - // Common SearchSpace list - for (int i = 0; i < commonSearchSpaceList->list.count; i++) { - ss = commonSearchSpaceList->list.array[i]; - if (ss->searchSpaceId == ra_SearchSpace) - ra->ra_ss = ss; - } + NR_SearchSpaceId_t ra_SearchSpace = 0; + struct NR_PDCCH_ConfigCommon__commonSearchSpaceList *commonSearchSpaceList = NULL; + NR_BWP_t *genericParameters = NULL; + if(bwp) { + commonSearchSpaceList = bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList; + ra_SearchSpace = *bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->ra_SearchSpace; + genericParameters = &bwp->bwp_Common->genericParameters; + } else { + commonSearchSpaceList = scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList; + ra_SearchSpace = *scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->ra_SearchSpace; + genericParameters = &scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters; + } + AssertFatal(commonSearchSpaceList->list.count > 0, "common SearchSpace list has 0 elements\n"); - AssertFatal(ra->ra_ss!=NULL,"SearchSpace cannot be null for RA\n"); - - ra->coreset = get_coreset(nr_mac, scc, bwp, ra->ra_ss, NR_SearchSpace__searchSpaceType_PR_common); - ra->sched_pdcch = set_pdcch_structure(nr_mac, - ra->ra_ss, - ra->coreset, - scc, - genericParameters, - &nr_mac->type0_PDCCH_CSS_config[ra->beam_id]); - - // retrieving ra pdcch monitoring period and offset - find_monitoring_periodicity_offset_common(ra->ra_ss, &monitoring_slot_period, &monitoring_offset); - - nr_schedule_msg2(frameP, - slotP, - &msg2_frame, - &msg2_slot, - scc, - frame_type, - monitoring_slot_period, - monitoring_offset, - beam_index, - cc->num_active_ssb, - nr_mac->tdd_beam_association, - nr_mac->if_inst->sl_ahead); - - ra->Msg2_frame = msg2_frame; - ra->Msg2_slot = msg2_slot; - - LOG_D(NR_MAC, "%s() Msg2[%04d%d] SFN/SF:%04d%d\n", __FUNCTION__, ra->Msg2_frame, ra->Msg2_slot, frameP, slotP); - - int loop = 0; - if (ra->rnti == 0) { // This condition allows for the usage of a preconfigured rnti for the CFRA - do { - ra->rnti = (taus() % 65518) + 1; - loop++; - } while (loop != 100 - && !((find_nr_UE(&nr_mac->UE_info, ra->rnti) == NULL) && (find_nr_RA_id(module_idP, CC_id, ra->rnti) == -1) - && ra->rnti >= 1 && ra->rnti <= 65519)); - if (loop == 100) { - LOG_E(NR_MAC, "%s:%d:%s: [RAPROC] initialisation random access aborted\n", __FILE__, __LINE__, __FUNCTION__); - abort(); - } - } + // Common SearchSpace list + for (int i = 0; i < commonSearchSpaceList->list.count; i++) { + ss = commonSearchSpaceList->list.array[i]; + if (ss->searchSpaceId == ra_SearchSpace) + ra->ra_ss = ss; + } - ra->RA_rnti = ra_rnti; - ra->preamble_index = preamble_index; - ra->beam_id = beam_index; + AssertFatal(ra->ra_ss!=NULL,"SearchSpace cannot be null for RA\n"); + + ra->coreset = get_coreset(nr_mac, scc, bwp, ra->ra_ss, NR_SearchSpace__searchSpaceType_PR_common); + ra->sched_pdcch = set_pdcch_structure(nr_mac, + ra->ra_ss, + ra->coreset, + scc, + genericParameters, + &nr_mac->type0_PDCCH_CSS_config[ra->beam_id]); + + // retrieving ra pdcch monitoring period and offset + find_monitoring_periodicity_offset_common(ra->ra_ss, &monitoring_slot_period, &monitoring_offset); + + nr_schedule_msg2(frameP, + slotP, + &msg2_frame, + &msg2_slot, + scc, + frame_type, + monitoring_slot_period, + monitoring_offset, + beam_index, + cc->num_active_ssb, + nr_mac->tdd_beam_association, + nr_mac->if_inst->sl_ahead); + + ra->Msg2_frame = msg2_frame; + ra->Msg2_slot = msg2_slot; + + LOG_D(NR_MAC, "%s() Msg2[%04d%d] SFN/SF:%04d%d\n", __FUNCTION__, ra->Msg2_frame, ra->Msg2_slot, frameP, slotP); + + int loop = 0; + if (ra->rnti == 0) { // This condition allows for the usage of a preconfigured rnti for the CFRA + do { + ra->rnti = (taus() % 65518) + 1; + loop++; + } while (loop != 100 + && !((find_nr_UE(&nr_mac->UE_info, ra->rnti) == NULL) && (find_nr_RA_id(module_idP, CC_id, ra->rnti) == -1) + && ra->rnti >= 1 && ra->rnti <= 65519)); + if (loop == 100) { + LOG_E(NR_MAC, "%s:%d:%s: [RAPROC] initialisation random access aborted\n", __FILE__, __LINE__, __FUNCTION__); + abort(); + } + } - LOG_I(NR_MAC, - "[gNB %d][RAPROC] CC_id %d Frame %d Activating Msg2 generation in frame %d, slot %d using RA rnti %x SSB, new rnti %04x " - "index %u RA index %d\n", - module_idP, - CC_id, - frameP, - ra->Msg2_frame, - ra->Msg2_slot, - ra->RA_rnti, - ra->rnti, - cc->ssb_index[beam_index], - i); + ra->RA_rnti = ra_rnti; + ra->preamble_index = preamble_index; + ra->beam_id = beam_index; + + LOG_I(NR_MAC, + "[gNB %d][RAPROC] CC_id %d Frame %d Activating Msg2 generation in frame %d, slot %d using RA rnti %x SSB, new rnti %04x " + "index %u RA index %d\n", + module_idP, + CC_id, + frameP, + ra->Msg2_frame, + ra->Msg2_slot, + ra->RA_rnti, + ra->rnti, + cc->ssb_index[beam_index], + i); - return; - } + return; } LOG_E(NR_MAC, "[gNB %d][RAPROC] FAILURE: CC_id %d Frame %d initiating RA procedure for preamble index %d\n", module_idP, CC_id, frameP, preamble_index); @@ -787,8 +784,9 @@ void nr_generate_Msg3_retransmission(module_id_t module_idP, int CC_id, frame_t uint16_t *vrb_map_UL = &RC.nrmac[module_idP]->common_channels[CC_id].vrb_map_UL[sched_slot * MAX_BWP_SIZE]; - int BWPStart = nr_mac->type0_PDCCH_CSS_config[ra->beam_id].cset_start_rb; - int BWPSize = nr_mac->type0_PDCCH_CSS_config[ra->beam_id].num_rbs; + const int BWPSize = NRRIV2BW(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + const int BWPStart = NRRIV2PRBOFFSET(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + int rbStart = 0; for (int i = 0; (i < ra->msg3_nb_rb) && (rbStart <= (BWPSize - ra->msg3_nb_rb)); i++) { if (vrb_map_UL[rbStart + BWPStart + i]&SL_to_bitmap(StartSymbolIndex, NrOfSymbols)) { @@ -1326,7 +1324,7 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra dl_req->nPDUs+=1; nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15; - LOG_D(NR_MAC,"[gNB %d][RAPROC] CC_id %d Frame %d, slotP %d: Generating RA-Msg2 DCI, rnti 0x%x, state %d, CoreSetType %d\n", + LOG_A(NR_MAC,"[gNB %d][RAPROC] CC_id %d Frame %d, slotP %d: Generating RA-Msg2 DCI, rnti 0x%x, state %d, CoreSetType %d\n", module_idP, CC_id, frameP, slotP, ra->RA_rnti, ra->state,pdcch_pdu_rel15->CoreSetType); // SCF222: PDU index incremented for each PDSCH PDU sent in TX control message. This is used to associate control @@ -1787,7 +1785,7 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra dl_req->nPDUs+=1; nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15; - LOG_D(NR_MAC, "[gNB %d] [RAPROC] CC_id %d Frame %d, slotP %d: Generating RA-Msg4 DCI, state %d\n", module_idP, CC_id, frameP, slotP, ra->state); + LOG_A(NR_MAC, "[gNB %d] [RAPROC] CC_id %d Frame %d, slotP %d: Generating RA-Msg4 DCI, state %d\n", module_idP, CC_id, frameP, slotP, ra->state); // SCF222: PDU index incremented for each PDSCH PDU sent in TX control message. This is used to associate control // information to data and is reset every slot. @@ -1952,7 +1950,7 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra if(ra->msg3_dcch_dtch) { // If the UE used MSG3 to transfer a DCCH or DTCH message, then contention resolution is successful upon transmission of PDCCH - LOG_I(NR_MAC, "(ue rnti 0x%04x) CBRA procedure succeeded!\n", ra->rnti); + LOG_A(NR_MAC, "(ue rnti 0x%04x) CBRA procedure succeeded!\n", ra->rnti); nr_clear_ra_proc(module_idP, CC_id, frameP, ra); UE->Msg4_ACKed = true; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 9b736955825c332b5ec76c7e2d8552b111b4b43a..c502975f7c279863dacfff41d2cee35ed37ba570 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -489,8 +489,8 @@ bool allocate_dl_retransmission(module_id_t module_id, } /* Find a free CCE */ - const int cid = sched_ctrl->coreset->controlResourceSetId; - const uint16_t Y = get_Y(cid%3, slot, UE->rnti); + + const uint32_t Y = get_Y(sched_ctrl->search_space, slot, UE->rnti); uint8_t nr_of_candidates; for (int i=0; i<5; i++) { @@ -528,7 +528,6 @@ bool allocate_dl_retransmission(module_id_t module_id, UE->rnti, frame, slot); - RC.nrmac[module_id]->pdcch_cand[cid]--; return false; } @@ -692,8 +691,7 @@ void pf_dl(module_id_t module_id, } /* Find a free CCE */ - const int cid = sched_ctrl->coreset->controlResourceSetId; - const uint16_t Y = get_Y(cid%3, slot, iterator->UE->rnti); + const uint32_t Y = get_Y(sched_ctrl->search_space, slot, iterator->UE->rnti); uint8_t nr_of_candidates; for (int i=0; i<5; i++) { @@ -732,7 +730,6 @@ void pf_dl(module_id_t module_id, rnti, frame, slot); - mac->pdcch_cand[cid]--; iterator++; continue; } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index 56d14b1458490b7e829cf25dd875427660361917..808fc613f1a854d7b410b7a5e28b82ea05aeaa3f 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -263,8 +263,7 @@ void nr_preprocessor_phytest(module_id_t module_id, } AssertFatal(nr_of_candidates>0,"nr_of_candidates is 0\n"); - const int cid = sched_ctrl->coreset->controlResourceSetId; - const uint16_t Y = get_Y(cid%3, slot, UE->rnti); + const uint32_t Y = get_Y(sched_ctrl->search_space, slot, UE->rnti); int CCEIndex = find_pdcch_candidate(RC.nrmac[module_id], CC_id, @@ -288,7 +287,6 @@ void nr_preprocessor_phytest(module_id_t module_id, rnti, frame, slot); - RC.nrmac[module_id]->pdcch_cand[cid]--; return; } @@ -310,6 +308,7 @@ void nr_preprocessor_phytest(module_id_t module_id, sched_pdsch->rbSize = rbSize; sched_pdsch->mcs = target_dl_mcs; + sched_ctrl->dl_bler_stats.mcs = target_dl_mcs; /* for logging output */ sched_pdsch->Qm = nr_get_Qm_dl(sched_pdsch->mcs, ps->mcsTableIdx); sched_pdsch->R = nr_get_code_rate_dl(sched_pdsch->mcs, ps->mcsTableIdx); sched_pdsch->tb_size = nr_compute_tbs(sched_pdsch->Qm, @@ -439,8 +438,7 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_ } AssertFatal(nr_of_candidates>0,"nr_of_candidates is 0\n"); - const int cid = sched_ctrl->coreset->controlResourceSetId; - const uint16_t Y = get_Y(cid%3, slot, UE->rnti); + const uint32_t Y = get_Y(sched_ctrl->search_space, slot, UE->rnti); int CCEIndex = find_pdcch_candidate(nr_mac, CC_id, @@ -452,7 +450,6 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_ if (CCEIndex < 0) { LOG_E(MAC, "%s(): CCE list not empty, couldn't schedule PUSCH\n", __func__); - nr_mac->pdcch_cand[cid]--; return false; } @@ -461,6 +458,7 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_ const int mcs = target_ul_mcs; NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch; sched_pusch->mcs = mcs; + sched_ctrl->ul_bler_stats.mcs = mcs; /* for logging output */ sched_pusch->rbStart = rbStart; sched_pusch->rbSize = rbSize; /* get the PID of a HARQ process awaiting retransmission, or -1 for "any new" */ diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 4ce4180fa578eaa47027809ce775ad6fa01cace4..c2066f943fee0f5ec5c7bd1667fa9d0ad3cc8192 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -440,36 +440,17 @@ NR_sched_pdcch_t set_pdcch_structure(gNB_MAC_INST *gNB_mac, } -int cce_to_reg_interleaving(const int R, int k, int n_shift, const int C, int L, const int N_regs) { - - int f; // interleaving function - if(R==0) - f = k; - else { - int c = k/R; - int r = k%R; - f = (r*C + c + n_shift)%(N_regs/L); - } - return f; -} - int find_pdcch_candidate(gNB_MAC_INST *mac, int cc_id, int aggregation, int nr_of_candidates, NR_sched_pdcch_t *pdcch, NR_ControlResourceSet_t *coreset, - uint16_t Y){ + uint32_t Y){ uint16_t *vrb_map = mac->common_channels[cc_id].vrb_map; - const int next_cand = mac->pdcch_cand[coreset->controlResourceSetId]; const int N_ci = 0; - if(next_cand>=nr_of_candidates) { - LOG_D(NR_MAC,"No more available candidates for this coreset\n"); - return -1; - } - const int N_rb = pdcch->n_rb; // nb of rbs of coreset per symbol const int N_symb = coreset->duration; // nb of coreset symbols const int N_regs = N_rb*N_symb; // nb of REGs per coreset @@ -481,9 +462,10 @@ int find_pdcch_candidate(gNB_MAC_INST *mac, // loop over all the available candidates // this implements TS 38.211 Sec. 7.3.2.2 - for(int m=next_cand; m<nr_of_candidates; m++) { // loop over candidates + for(int m=0; m<nr_of_candidates; m++) { // loop over candidates bool taken = false; // flag if the resource for a given candidate are taken int first_cce = aggregation * (( Y + CEILIDIV((m*N_cces),(aggregation*nr_of_candidates)) + N_ci ) % CEILIDIV(N_cces,aggregation)); + LOG_D(NR_MAC,"Candidate %d of %d first_cce %d (L %d N_cces %d Y %d)\n", m, nr_of_candidates, first_cce, aggregation, N_cces, Y); for (int j=first_cce; (j<first_cce+aggregation) && !taken; j++) { // loop over CCEs for (int k=6*j/L; (k<(6*j/L+6/L)) && !taken; k++) { // loop over REG bundles int f = cce_to_reg_interleaving(R, k, pdcch->ShiftIndex, C, L, N_regs); @@ -495,10 +477,8 @@ int find_pdcch_candidate(gNB_MAC_INST *mac, } } } - if(!taken){ - mac->pdcch_cand[coreset->controlResourceSetId] = m++; // using candidate m, next available is m+1 + if(!taken) return first_cce; - } } return -1; } @@ -1133,7 +1113,7 @@ void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu, for (int i=0;i<6;i++) pdcch_pdu->FreqDomainResource[i] = coreset->frequencyDomainResources.buf[i]; - LOG_D(MAC,"Coreset : BWPstart %d, BWPsize %d, SCS %d, freq %x, , duration %d, \n", + LOG_D(MAC,"Coreset : BWPstart %d, BWPsize %d, SCS %d, freq %x, , duration %d\n", pdcch_pdu->BWPStart,pdcch_pdu->BWPSize,(int)pdcch_pdu->SubcarrierSpacing,(int)coreset->frequencyDomainResources.buf[0],(int)coreset->duration); pdcch_pdu->CceRegMappingType = pdcch->CceRegMappingType; @@ -2265,30 +2245,17 @@ void remove_front_nr_list(NR_list_t *listP) NR_UE_info_t *find_nr_UE(NR_UEs_t *UEs, rnti_t rntiP) { + UE_iterator(UEs->list, UE) { if (UE->rnti == rntiP) { LOG_D(NR_MAC,"Search and found rnti: %04x\n", rntiP); return UE; } } - LOG_W(NR_MAC,"Search for not existing rnti: %04x\n", rntiP); + LOG_W(NR_MAC,"Search for not existing rnti (ignore for RA): %04x\n", rntiP); return NULL; } -uint16_t get_Y(int cid, int slot, rnti_t rnti) { - - const int A[3] = {39827, 39829, 39839}; - const int D = 65537; - int Y; - - Y = (A[cid] * rnti) % D; - - for (int s = 0; s < slot; s++) - Y = (A[cid] * Y) % D; - - return Y; -} - int find_nr_RA_id(module_id_t mod_idP, int CC_idP, rnti_t rntiP) { //------------------------------------------------------------------------------ int RA_id; @@ -2936,6 +2903,30 @@ void nr_mac_update_timers(module_id_t module_id, cg->spCellConfig->spCellConfigDedicated ? cg->spCellConfig->spCellConfigDedicated->initialDownlinkBWP : NULL; + // update coreset/searchspace + int target_ss = NR_SearchSpace__searchSpaceType_PR_common; + NR_BWP_t *genericParameters = NULL; + if (sched_ctrl->active_bwp) { + target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific; + bwpd = (void*)sched_ctrl->active_bwp->bwp_Dedicated; + genericParameters = &sched_ctrl->active_bwp->bwp_Common->genericParameters; + } + else if (cg->spCellConfig && + cg->spCellConfig->spCellConfigDedicated && + (cg->spCellConfig->spCellConfigDedicated->initialDownlinkBWP)) { + target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific; + genericParameters = &scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters; + } + NR_BCCH_DL_SCH_Message_t *SIB1 = RC.nrmac[module_id]->common_channels[0].sib1; + sched_ctrl->search_space = get_searchspace(SIB1 ? SIB1->message.choice.c1->choice.systemInformationBlockType1 : NULL, scc, bwpd, target_ss); + sched_ctrl->coreset = get_coreset(RC.nrmac[module_id], scc, bwpd, sched_ctrl->search_space, target_ss); + sched_ctrl->sched_pdcch = set_pdcch_structure(RC.nrmac[module_id], + sched_ctrl->search_space, + sched_ctrl->coreset, + scc, + genericParameters, + RC.nrmac[module_id]->type0_PDCCH_CSS_config); + NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static; const uint8_t layers = set_dl_nrOfLayers(sched_ctrl); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index 76c49b825798f92a1cc7b1ce285c66fb3b396033..0a47f523858c0c3a0efea682d0a4f5364150b800 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -413,7 +413,7 @@ void tci_handling(NR_UE_info_t *UE, frame_t frame, slot_t slot) { uint8_t idx = 0; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; - const int bwp_id = sched_ctrl->active_bwp ? 1 : 0; + const int bwp_id = sched_ctrl->active_bwp ? sched_ctrl->active_bwp->bwp_Id : 0; NR_CellGroupConfig_t *CellGroup = UE->CellGroup; //bwp indicator diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 5fe7c18b7b0818b5723a9e4e724696d118bf70a5..693656d7829e7057f2deeca7ba5150674a356a47 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -932,8 +932,7 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac, } /* Find a free CCE */ - const int cid = sched_ctrl->coreset->controlResourceSetId; - const uint16_t Y = get_Y(cid%3, slot, UE->rnti); + const uint32_t Y = get_Y(sched_ctrl->search_space, slot, UE->rnti); uint8_t nr_of_candidates; for (int i=0; i<5; i++) { // for now taking the lowest value among the available aggregation levels @@ -1102,8 +1101,7 @@ void pf_ul(module_id_t module_id, if (B == 0 && do_sched) { /* if no data, pre-allocate 5RB */ /* Find a free CCE */ - const int cid = sched_ctrl->coreset->controlResourceSetId; - const uint16_t Y = get_Y(cid%3, slot, UE->rnti); + const uint32_t Y = get_Y(sched_ctrl->search_space, slot, UE->rnti); uint8_t nr_of_candidates; for (int i=0; i<5; i++) { // for now taking the lowest value among the available aggregation levels @@ -1218,8 +1216,7 @@ void pf_ul(module_id_t module_id, NR_UE_sched_ctrl_t *sched_ctrl = &iterator->UE->UE_sched_ctrl; - const int cid = sched_ctrl->coreset->controlResourceSetId; - const uint16_t Y = get_Y(cid%3, slot, iterator->UE->rnti); + const uint32_t Y = get_Y(sched_ctrl->search_space, slot, iterator->UE->rnti); uint8_t nr_of_candidates; for (int i=0; i<5; i++) { // for now taking the lowest value among the available aggregation levels diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 0368d0186e366d442000bf19aa9306e1407694ab..59db2740e5f66bc0702f4c332a4bae7b8129f0b8 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -290,7 +290,7 @@ int find_pdcch_candidate(gNB_MAC_INST *mac, int nr_of_candidates, NR_sched_pdcch_t *pdcch, NR_ControlResourceSet_t *coreset, - uint16_t Y); + uint32_t Y); void fill_pdcch_vrb_map(gNB_MAC_INST *mac, int CC_id, @@ -373,8 +373,6 @@ void nr_set_pusch_semi_static(const NR_SIB1_t *sib1, uint8_t nrOfLayers, NR_pusch_semi_static_t *ps); -uint16_t get_Y(int cid, int slot, rnti_t rnti); - uint8_t nr_get_tpc(int target, uint8_t cqi, int incr); int get_spf(nfapi_nr_config_request_scf_t *cfg); @@ -412,14 +410,6 @@ void mac_remove_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rnti); void nr_mac_remove_ra_rnti(module_id_t mod_id, rnti_t rnti); -int allocate_nr_CCEs(gNB_MAC_INST *nr_mac, - NR_BWP_Downlink_t *bwp, - NR_ControlResourceSet_t *coreset, - int aggregation, - uint16_t Y, - int m, - int nr_of_candidates); - int nr_get_default_pucch_res(int pucch_ResourceCommon); int get_dlscs(nfapi_nr_config_request_t *cfg); @@ -532,7 +522,7 @@ int get_mcs_from_bler(const NR_bler_options_t *bler_options, void nr_sr_reporting(gNB_MAC_INST *nrmac, frame_t frameP, sub_frame_t slotP); -void dump_mac_stats(gNB_MAC_INST *gNB, char *output, int strlen, bool reset_rsrp); +size_t dump_mac_stats(gNB_MAC_INST *gNB, char *output, size_t strlen, bool reset_rsrp); void process_CellGroup(NR_CellGroupConfig_t *CellGroup, NR_UE_sched_ctrl_t *sched_ctrl); diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c index 6547544a68c76990b1eda25aede0194bf35eeecf..9b9fd4e76cbed3900730877eca4af3d13ecde5c0 100644 --- a/openair2/LAYER2/NR_MAC_gNB/main.c +++ b/openair2/LAYER2/NR_MAC_gNB/main.c @@ -45,25 +45,31 @@ extern RAN_CONTEXT_t RC; -#define MACSTATSSTRLEN 16384 +#define MACSTATSSTRLEN 65536 void *nrmac_stats_thread(void *arg) { gNB_MAC_INST *gNB = (gNB_MAC_INST *)arg; - char output[MACSTATSSTRLEN]; - memset(output,0,MACSTATSSTRLEN); - FILE *fd=fopen("nrMAC_stats.log","w"); - AssertFatal(fd!=NULL,"Cannot open nrMAC_stats.log, error %s\n",strerror(errno)); + char output[MACSTATSSTRLEN] = {0}; + const char *end = output + MACSTATSSTRLEN; + FILE *file = fopen("nrMAC_stats.log","w"); + AssertFatal(file!=NULL,"Cannot open nrMAC_stats.log, error %s\n",strerror(errno)); while (oai_exit == 0) { - dump_mac_stats(gNB,output,MACSTATSSTRLEN,false); - fprintf(fd,"%s\n",output); - fflush(fd); - usleep(200000); - fseek(fd,0,SEEK_SET); + char *p = output; + p += dump_mac_stats(gNB, p, end - p, false); + p += snprintf(p, end - p, "\n"); + p += print_meas_log(&gNB->eNB_scheduler, "DL & UL scheduling timing", NULL, NULL, p, end - p); + p += print_meas_log(&gNB->schedule_dlsch, "dlsch scheduler", NULL, NULL, p, end - p); + p += print_meas_log(&gNB->rlc_data_req, "rlc_data_req", NULL, NULL, p, end - p); + p += print_meas_log(&gNB->rlc_status_ind, "rlc_status_ind", NULL, NULL, p, end - p); + fwrite(output, p - output, 1, file); + fflush(file); + sleep(1); + fseek(file,0,SEEK_SET); } - fclose(fd); + fclose(file); return NULL; } @@ -73,11 +79,12 @@ void clear_mac_stats(gNB_MAC_INST *gNB) { } } -void dump_mac_stats(gNB_MAC_INST *gNB, char *output, int strlen, bool reset_rsrp) +size_t dump_mac_stats(gNB_MAC_INST *gNB, char *output, size_t strlen, bool reset_rsrp) { int num = 1; + const char *begin = output; + const char *end = output + strlen; - int stroff=0; pthread_mutex_lock(&gNB->UE_info.mutex); UE_iterator(gNB->UE_info.list, UE) { NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; @@ -85,63 +92,77 @@ void dump_mac_stats(gNB_MAC_INST *gNB, char *output, int strlen, bool reset_rsrp const int avg_rsrp = stats->num_rsrp_meas > 0 ? stats->cumul_rsrp / stats->num_rsrp_meas : 0; - stroff+=sprintf(output+stroff,"UE RNTI %04x (%d) PH %d dB PCMAX %d dBm, average RSRP %d (%d meas)\n", - UE->rnti, - num++, - sched_ctrl->ph, - sched_ctrl->pcmax, - avg_rsrp, - stats->num_rsrp_meas); - stroff+=sprintf(output+stroff,"UE %04x: CQI %d, RI %d, PMI (%d,%d)\n", - UE->rnti, - UE->UE_sched_ctrl.CSI_report.cri_ri_li_pmi_cqi_report.wb_cqi_1tb, - UE->UE_sched_ctrl.CSI_report.cri_ri_li_pmi_cqi_report.ri+1, - UE->UE_sched_ctrl.CSI_report.cri_ri_li_pmi_cqi_report.pmi_x1, - UE->UE_sched_ctrl.CSI_report.cri_ri_li_pmi_cqi_report.pmi_x2); - - stroff+=sprintf(output+stroff,"UE %04x: dlsch_rounds %"PRIu64"/%"PRIu64"/%"PRIu64"/%"PRIu64", dlsch_errors %"PRIu64", pucch0_DTX %d, BLER %.5f MCS %d\n", - UE->rnti, - - stats->dl.rounds[0], stats->dl.rounds[1], - stats->dl.rounds[2], stats->dl.rounds[3], - stats->dl.errors, - stats->pucch0_DTX, - sched_ctrl->dl_bler_stats.bler, - sched_ctrl->dl_bler_stats.mcs); + output += snprintf(output, + end - output, + "UE RNTI %04x (%d) PH %d dB PCMAX %d dBm, average RSRP %d (%d meas)\n", + UE->rnti, + num++, + sched_ctrl->ph, + sched_ctrl->pcmax, + avg_rsrp, + stats->num_rsrp_meas); + output += snprintf(output, + end - output, + "UE %04x: CQI %d, RI %d, PMI (%d,%d)\n", + UE->rnti, + UE->UE_sched_ctrl.CSI_report.cri_ri_li_pmi_cqi_report.wb_cqi_1tb, + UE->UE_sched_ctrl.CSI_report.cri_ri_li_pmi_cqi_report.ri+1, + UE->UE_sched_ctrl.CSI_report.cri_ri_li_pmi_cqi_report.pmi_x1, + UE->UE_sched_ctrl.CSI_report.cri_ri_li_pmi_cqi_report.pmi_x2); + + output += snprintf(output, + end - output, + "UE %04x: dlsch_rounds %"PRIu64"/%"PRIu64"/%"PRIu64"/%"PRIu64", dlsch_errors %"PRIu64", pucch0_DTX %d, BLER %.5f MCS %d\n", + UE->rnti, + stats->dl.rounds[0], stats->dl.rounds[1], + stats->dl.rounds[2], stats->dl.rounds[3], + stats->dl.errors, + stats->pucch0_DTX, + sched_ctrl->dl_bler_stats.bler, + sched_ctrl->dl_bler_stats.mcs); if (reset_rsrp) { stats->num_rsrp_meas = 0; stats->cumul_rsrp = 0; } - stroff+=sprintf(output+stroff,"UE %04x: dlsch_total_bytes %"PRIu64"\n", UE->rnti, stats->dl.total_bytes); - stroff+=sprintf(output+stroff,"UE %04x: ulsch_rounds %"PRIu64"/%"PRIu64"/%"PRIu64"/%"PRIu64", ulsch_DTX %d, ulsch_errors %"PRIu64", BLER %.5f MCS %d\n", - UE->rnti, - stats->ul.rounds[0], stats->ul.rounds[1], - stats->ul.rounds[2], stats->ul.rounds[3], - stats->ulsch_DTX, - stats->ul.errors, - sched_ctrl->ul_bler_stats.bler, - sched_ctrl->ul_bler_stats.mcs); - stroff+=sprintf(output+stroff, - "UE %04x: ulsch_total_bytes_scheduled %"PRIu64", ulsch_total_bytes_received %"PRIu64"\n", - UE->rnti, - stats->ulsch_total_bytes_scheduled, stats->ul.total_bytes); + output += snprintf(output, + end - output, + "UE %04x: dlsch_total_bytes %"PRIu64"\n", + UE->rnti, + stats->dl.total_bytes); + output += snprintf(output, + end - output, + "UE %04x: ulsch_rounds %"PRIu64"/%"PRIu64"/%"PRIu64"/%"PRIu64", ulsch_DTX %d, ulsch_errors %"PRIu64", BLER %.5f MCS %d\n", + UE->rnti, + stats->ul.rounds[0], stats->ul.rounds[1], + stats->ul.rounds[2], stats->ul.rounds[3], + stats->ulsch_DTX, + stats->ul.errors, + sched_ctrl->ul_bler_stats.bler, + sched_ctrl->ul_bler_stats.mcs); + output += snprintf(output, + end - output, + "UE %04x: ulsch_total_bytes_scheduled %"PRIu64", ulsch_total_bytes_received %"PRIu64"\n", + UE->rnti, + stats->ulsch_total_bytes_scheduled, stats->ul.total_bytes); for (int lc_id = 0; lc_id < 63; lc_id++) { - if (stats->dl.lc_bytes[lc_id] > 0) { - stroff+=sprintf(output+stroff, "UE %04x: LCID %d: %"PRIu64" bytes TX\n", UE->rnti, lc_id, stats->dl.lc_bytes[lc_id]); - LOG_D(NR_MAC, "UE %04x: LCID %d: %"PRIu64" bytes TX\n", UE->rnti, lc_id, stats->dl.lc_bytes[lc_id]); - } - if (stats->ul.lc_bytes[lc_id] > 0) { - stroff+=sprintf(output+stroff, "UE %04x: LCID %d: %"PRIu64" bytes RX\n", UE->rnti, lc_id, stats->ul.lc_bytes[lc_id]); - LOG_D(NR_MAC, "UE %04x: LCID %d: %"PRIu64" bytes RX\n", UE->rnti, lc_id, stats->ul.lc_bytes[lc_id]); - - } + if (stats->dl.lc_bytes[lc_id] > 0) + output += snprintf(output, + end - output, + "UE %04x: LCID %d: %"PRIu64" bytes TX\n", + UE->rnti, + lc_id, + stats->dl.lc_bytes[lc_id]); + if (stats->ul.lc_bytes[lc_id] > 0) + output += snprintf(output, + end - output, + "UE %04x: LCID %d: %"PRIu64" bytes RX\n", + UE->rnti, + lc_id, + stats->ul.lc_bytes[lc_id]); } } pthread_mutex_unlock(&gNB->UE_info.mutex); - print_meas(&gNB->eNB_scheduler, "DL & UL scheduling timing stats", NULL, NULL); - print_meas(&gNB->schedule_dlsch,"dlsch scheduler",NULL,NULL); - print_meas(&gNB->rlc_data_req, "rlc_data_req",NULL,NULL); - print_meas(&gNB->rlc_status_ind,"rlc_status_ind",NULL,NULL); + return output - begin; } diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index ff66f8ab6368fba8c67f8e6c431ec7e350437211..afc441c29d0699fa896662ff5b40acc7d5ed27c6 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -756,7 +756,7 @@ typedef struct gNB_MAC_INST_s { nfapi_nr_ul_dci_request_t UL_dci_req[NFAPI_CC_MAX]; /// NFAPI DL PDU structure nfapi_nr_tx_data_request_t TX_req[NFAPI_CC_MAX]; - int pdcch_cand[MAX_NUM_CORESET]; + NR_UEs_t UE_info; /// UL handle diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c index 8d4de8823bca20f5cd9a365e4c3246a2a9b9b516..ac0e48a91073db86c74f50a7eb22378e53b5d090 100644 --- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c @@ -77,7 +77,7 @@ void handle_nr_rach(NR_UL_IND_t *UL_info) bool in_timewindow = frame_diff == 0 || (frame_diff == 1 && UL_info->slot < 7); if (UL_info->rach_ind.number_of_pdus > 0 && in_timewindow) { - LOG_D(MAC,"UL_info[Frame %d, Slot %d] Calling initiate_ra_proc RACH:SFN/SLOT:%d/%d\n", + LOG_A(MAC,"UL_info[Frame %d, Slot %d] Calling initiate_ra_proc RACH:SFN/SLOT:%d/%d\n", UL_info->frame, UL_info->slot, UL_info->rach_ind.sfn, UL_info->rach_ind.slot); for (int i = 0; i < UL_info->rach_ind.number_of_pdus; i++) { UL_info->rach_ind.number_of_pdus--; diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c index 36d45a490548735170a7d2c011cdf57b231703f6..c332bd703a44c0fa71f581d6ab1f6bac15f59503 100755 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -1041,61 +1041,8 @@ void fill_default_downlinkBWP(NR_BWP_Downlink_t *bwp, int curr_bwp = NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth,MAX_BWP_SIZE); NR_ControlResourceSet_t *coreset = calloc(1,sizeof(*coreset)); - coreset->controlResourceSetId=(bwp->bwp_Id<<1); // To uniquely identify each Coreset lets derive it from the BWPId - // frequency domain resources depends on BWP size - // options are 24, 48 or 96 - coreset->frequencyDomainResources.buf = calloc(1,6); - if (0) { - if (curr_bwp < 48) - coreset->frequencyDomainResources.buf[0] = 0xf0; - else - coreset->frequencyDomainResources.buf[0] = 0xff; - if (curr_bwp < 96) - coreset->frequencyDomainResources.buf[1] = 0; - else - coreset->frequencyDomainResources.buf[1] = 0xff; - } else { - coreset->frequencyDomainResources.buf[0] = 0xf0; - coreset->frequencyDomainResources.buf[1] = 0; - } - coreset->frequencyDomainResources.buf[2] = 0; - coreset->frequencyDomainResources.buf[3] = 0; - coreset->frequencyDomainResources.buf[4] = 0; - coreset->frequencyDomainResources.buf[5] = 0; - coreset->frequencyDomainResources.size = 6; - coreset->frequencyDomainResources.bits_unused = 3; - coreset->duration=1; - coreset->cce_REG_MappingType.present = NR_ControlResourceSet__cce_REG_MappingType_PR_nonInterleaved; - coreset->precoderGranularity = NR_ControlResourceSet__precoderGranularity_sameAsREG_bundle; - - coreset->tci_StatesPDCCH_ToAddList=calloc(1,sizeof(*coreset->tci_StatesPDCCH_ToAddList)); - uint64_t bitmap=0; - switch (scc->ssb_PositionsInBurst->present) { - case 1 : - bitmap = ((uint64_t) scc->ssb_PositionsInBurst->choice.shortBitmap.buf[0])<<56; - break; - case 2 : - bitmap = ((uint64_t) scc->ssb_PositionsInBurst->choice.mediumBitmap.buf[0])<<56; - break; - case 3 : - for (int i=0; i<8; i++) { - bitmap |= (((uint64_t) scc->ssb_PositionsInBurst->choice.longBitmap.buf[i])<<((7-i)*8)); - } - break; - default: - AssertFatal(1==0,"SSB bitmap size value %d undefined (allowed values 1,2,3) \n", scc->ssb_PositionsInBurst->present); - } - NR_TCI_StateId_t *tci[64]; - for (int i=0;i<64;i++) { - if ((bitmap>>(63-i))&0x01){ - tci[i]=calloc(1,sizeof(*tci[i])); - *tci[i] = i; - ASN_SEQUENCE_ADD(&coreset->tci_StatesPDCCH_ToAddList->list,tci[i]); - } - } - coreset->tci_StatesPDCCH_ToReleaseList = NULL; - coreset->tci_PresentInDCI = NULL; - coreset->pdcch_DMRS_ScramblingID = NULL; + uint64_t bitmap = get_ssb_bitmap(scc); + rrc_coreset_config(coreset, bwp->bwp_Id, curr_bwp, bitmap); bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonControlResourceSet = coreset; bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->searchSpaceZero=NULL; @@ -1153,36 +1100,7 @@ void fill_default_downlinkBWP(NR_BWP_Downlink_t *bwp, bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList = calloc(1,sizeof(*bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList)); NR_ControlResourceSet_t *coreset2 = calloc(1,sizeof(*coreset2)); - coreset2->controlResourceSetId=(bwp->bwp_Id<<1)+1; // To uniquely identify each Coreset lets derive it from the BWPId - // frequency domain resources depends on BWP size - // options are 24, 48 or 96 - coreset2->frequencyDomainResources.buf = calloc(1,6); - if (0) { - if (curr_bwp < 48) - coreset2->frequencyDomainResources.buf[0] = 0xf0; - else - coreset2->frequencyDomainResources.buf[0] = 0xff; - if (curr_bwp < 96) - coreset2->frequencyDomainResources.buf[1] = 0; - else - coreset2->frequencyDomainResources.buf[1] = 0xff; - } else { - coreset2->frequencyDomainResources.buf[0] = 0xf0; - coreset2->frequencyDomainResources.buf[1] = 0; - } - coreset2->frequencyDomainResources.buf[2] = 0; - coreset2->frequencyDomainResources.buf[3] = 0; - coreset2->frequencyDomainResources.buf[4] = 0; - coreset2->frequencyDomainResources.buf[5] = 0; - coreset2->frequencyDomainResources.size = 6; - coreset2->frequencyDomainResources.bits_unused = 3; - coreset2->duration=1; - coreset2->cce_REG_MappingType.present = NR_ControlResourceSet__cce_REG_MappingType_PR_nonInterleaved; - coreset2->precoderGranularity = NR_ControlResourceSet__precoderGranularity_sameAsREG_bundle; - coreset2->tci_StatesPDCCH_ToAddList=NULL; - coreset2->tci_StatesPDCCH_ToReleaseList = NULL; - coreset2->tci_PresentInDCI = NULL; - coreset2->pdcch_DMRS_ScramblingID = NULL; + rrc_coreset_config(coreset2, bwp->bwp_Id, curr_bwp, bitmap); ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list, coreset2); bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList = calloc(1,sizeof(*bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList)); @@ -1832,37 +1750,9 @@ void fill_initial_SpCellConfig(int uid, bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList = calloc(1,sizeof(*bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList)); NR_ControlResourceSet_t *coreset = calloc(1,sizeof(*coreset)); - coreset->controlResourceSetId=1; - // frequency domain resources depends on BWP size - // options are 24, 48 or 96 - coreset->frequencyDomainResources.buf = calloc(1,6); - if (0) { - if (curr_bwp < 48) - coreset->frequencyDomainResources.buf[0] = 0xf0; - else - coreset->frequencyDomainResources.buf[0] = 0xff; - if (curr_bwp < 96) - coreset->frequencyDomainResources.buf[1] = 0; - else - coreset->frequencyDomainResources.buf[1] = 0xff; - } else { - coreset->frequencyDomainResources.buf[0] = 0xf0; - coreset->frequencyDomainResources.buf[1] = 0; - } - coreset->frequencyDomainResources.buf[2] = 0; - coreset->frequencyDomainResources.buf[3] = 0; - coreset->frequencyDomainResources.buf[4] = 0; - coreset->frequencyDomainResources.buf[5] = 0; - coreset->frequencyDomainResources.size = 6; - coreset->frequencyDomainResources.bits_unused = 3; - coreset->duration=1; - coreset->cce_REG_MappingType.present = NR_ControlResourceSet__cce_REG_MappingType_PR_nonInterleaved; - coreset->precoderGranularity = NR_ControlResourceSet__precoderGranularity_sameAsREG_bundle; - - coreset->tci_StatesPDCCH_ToAddList=NULL; - coreset->tci_StatesPDCCH_ToReleaseList = NULL; - coreset->tci_PresentInDCI = NULL; - coreset->pdcch_DMRS_ScramblingID = NULL; + + uint64_t bitmap = get_ssb_bitmap(scc); + rrc_coreset_config(coreset, 0, curr_bwp, bitmap); ASN_SEQUENCE_ADD(&bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list, coreset); @@ -1873,7 +1763,7 @@ void fill_initial_SpCellConfig(int uid, ss2->searchSpaceId=2; ss2->controlResourceSetId=calloc(1,sizeof(*ss2->controlResourceSetId)); - *ss2->controlResourceSetId=1; + *ss2->controlResourceSetId=coreset->controlResourceSetId; ss2->monitoringSlotPeriodicityAndOffset=calloc(1,sizeof(*ss2->monitoringSlotPeriodicityAndOffset)); ss2->monitoringSlotPeriodicityAndOffset->present = NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl1; ss2->monitoringSlotPeriodicityAndOffset->choice.sl1=(NULL_t)0; diff --git a/openair2/RRC/NR/nr_rrc_config.c b/openair2/RRC/NR/nr_rrc_config.c index c89761e5c7edaeedf5d37bc48a6928e924f53958..6b82fec20d41ba9fdf42c688c7e4b2a9a24d6431 100644 --- a/openair2/RRC/NR/nr_rrc_config.c +++ b/openair2/RRC/NR/nr_rrc_config.c @@ -34,6 +34,63 @@ const uint8_t slotsperframe[5] = {10, 20, 40, 80, 160}; +void rrc_coreset_config(NR_ControlResourceSet_t *coreset, + int bwp_id, + int curr_bwp, + uint64_t ssb_bitmap) { + + + // frequency domain resources depending on BWP size + coreset->frequencyDomainResources.buf = calloc(1,6); + coreset->frequencyDomainResources.buf[0] = (curr_bwp < 48) ? 0xf0 : 0xff; + coreset->frequencyDomainResources.buf[1] = (curr_bwp < 96) ? 0x00 : 0xff; + coreset->frequencyDomainResources.buf[2] = (curr_bwp < 144) ? 0x00 : 0xff; + coreset->frequencyDomainResources.buf[3] = (curr_bwp < 192) ? 0x00 : 0xff; + coreset->frequencyDomainResources.buf[4] = (curr_bwp < 240) ? 0x00 : 0xff; + coreset->frequencyDomainResources.buf[5] = 0x00; + coreset->frequencyDomainResources.size = 6; + coreset->frequencyDomainResources.bits_unused = 3; + coreset->duration = (curr_bwp < 48) ? 2 : 1; + coreset->cce_REG_MappingType.present = NR_ControlResourceSet__cce_REG_MappingType_PR_nonInterleaved; + coreset->precoderGranularity = NR_ControlResourceSet__precoderGranularity_sameAsREG_bundle; + + // The ID space is used across the BWPs of a Serving Cell as per 38.331 + coreset->controlResourceSetId = bwp_id + 1; + + coreset->tci_StatesPDCCH_ToAddList=calloc(1,sizeof(*coreset->tci_StatesPDCCH_ToAddList)); + NR_TCI_StateId_t *tci[64]; + for (int i=0;i<64;i++) { + if ((ssb_bitmap>>(63-i))&0x01){ + tci[i]=calloc(1,sizeof(*tci[i])); + *tci[i] = i; + ASN_SEQUENCE_ADD(&coreset->tci_StatesPDCCH_ToAddList->list,tci[i]); + } + } + coreset->tci_StatesPDCCH_ToReleaseList = NULL; + coreset->tci_PresentInDCI = NULL; + coreset->pdcch_DMRS_ScramblingID = NULL; +} + +uint64_t get_ssb_bitmap(NR_ServingCellConfigCommon_t *scc) { + uint64_t bitmap=0; + switch (scc->ssb_PositionsInBurst->present) { + case 1 : + bitmap = ((uint64_t) scc->ssb_PositionsInBurst->choice.shortBitmap.buf[0])<<56; + break; + case 2 : + bitmap = ((uint64_t) scc->ssb_PositionsInBurst->choice.mediumBitmap.buf[0])<<56; + break; + case 3 : + for (int i=0; i<8; i++) { + bitmap |= (((uint64_t) scc->ssb_PositionsInBurst->choice.longBitmap.buf[i])<<((7-i)*8)); + } + break; + default: + AssertFatal(1==0,"SSB bitmap size value %d undefined (allowed values 1,2,3) \n", scc->ssb_PositionsInBurst->present); + } + return bitmap; +} + void set_csirs_periodicity(NR_NZP_CSI_RS_Resource_t *nzpcsi0, int uid, int nb_slots_per_period) { nzpcsi0->periodicityAndOffset = calloc(1,sizeof(*nzpcsi0->periodicityAndOffset)); diff --git a/openair2/RRC/NR/nr_rrc_config.h b/openair2/RRC/NR/nr_rrc_config.h index 3d241640b319fa18e493bf5c5071abc990aa240c..dfddafb229bb83ce150a359af244f07c9a4b207a 100644 --- a/openair2/RRC/NR/nr_rrc_config.h +++ b/openair2/RRC/NR/nr_rrc_config.h @@ -111,6 +111,11 @@ typedef struct physicalcellgroup_s{ long RNTI_Value[MAX_NUM_CCs]; }physicalcellgroup_t; +uint64_t get_ssb_bitmap(NR_ServingCellConfigCommon_t *scc); +void rrc_coreset_config(NR_ControlResourceSet_t *coreset, + int bwp_id, + int curr_bwp, + uint64_t ssb_bitmap); void nr_rrc_config_dl_tda(NR_ServingCellConfigCommon_t *scc, NR_PDSCH_TimeDomainResourceAllocationList_t *pdsch_TimeDomainAllocationList, int curr_bwp); diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c index de62035b4889748bd27462f96866e86647838053..0118778582d93feaf09aac3ab450b3a931c21335 100644 --- a/openair2/RRC/NR/rrc_gNB_reconfig.c +++ b/openair2/RRC/NR/rrc_gNB_reconfig.c @@ -119,39 +119,7 @@ void fill_default_nsa_downlinkBWP(NR_BWP_Downlink_t *bwp, int curr_bwp = NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth,275); NR_ControlResourceSet_t *coreset = calloc(1,sizeof(*coreset)); - coreset->controlResourceSetId=bwp->bwp_Id+1; // To uniquely identify each Coreset lets derive it from the BWPId - // frequency domain resources depends on BWP size - // options are 24, 48 or 96 - coreset->frequencyDomainResources.buf = calloc(1,6); - if (curr_bwp < 48) - coreset->frequencyDomainResources.buf[0] = 0xf0; - else - coreset->frequencyDomainResources.buf[0] = 0xff; - if (curr_bwp < 96) - coreset->frequencyDomainResources.buf[1] = 0; - else - coreset->frequencyDomainResources.buf[1] = 0xff; - coreset->frequencyDomainResources.buf[2] = 0; - coreset->frequencyDomainResources.buf[3] = 0; - coreset->frequencyDomainResources.buf[4] = 0; - coreset->frequencyDomainResources.buf[5] = 0; - coreset->frequencyDomainResources.size = 6; - coreset->frequencyDomainResources.bits_unused = 3; - coreset->duration=1; - coreset->cce_REG_MappingType.present = NR_ControlResourceSet__cce_REG_MappingType_PR_nonInterleaved; - coreset->precoderGranularity = NR_ControlResourceSet__precoderGranularity_sameAsREG_bundle; - coreset->tci_StatesPDCCH_ToAddList=calloc(1,sizeof(*coreset->tci_StatesPDCCH_ToAddList)); - NR_TCI_StateId_t *tci[64]; - for (int i=0;i<64;i++) { - if ((bitmap>>(63-i))&0x01){ - tci[i]=calloc(1,sizeof(*tci[i])); - *tci[i] = i; - ASN_SEQUENCE_ADD(&coreset->tci_StatesPDCCH_ToAddList->list,tci[i]); - } - } - coreset->tci_StatesPDCCH_ToReleaseList = NULL; - coreset->tci_PresentInDCI = NULL; - coreset->pdcch_DMRS_ScramblingID = NULL; + rrc_coreset_config(coreset, bwp->bwp_Id, curr_bwp, bitmap); bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonControlResourceSet = coreset; bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->searchSpaceZero=NULL; @@ -663,25 +631,9 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco // where the startPosition = 2 or 3 and sl160 = 17, 17, 27 ... 157 only give us 30 different allocations. AssertFatal(uid>=0 && uid<30, "gNB cannot allocate the SRS resources\n"); + uint64_t bitmap = get_ssb_bitmap(servingcellconfigcommon); fix_servingcellconfigdedicated(servingcellconfigdedicated); - uint64_t bitmap=0; - switch (servingcellconfigcommon->ssb_PositionsInBurst->present) { - case 1 : - bitmap = ((uint64_t) servingcellconfigcommon->ssb_PositionsInBurst->choice.shortBitmap.buf[0])<<56; - break; - case 2 : - bitmap = ((uint64_t) servingcellconfigcommon->ssb_PositionsInBurst->choice.mediumBitmap.buf[0])<<56; - break; - case 3 : - for (int i=0; i<8; i++) { - bitmap |= (((uint64_t) servingcellconfigcommon->ssb_PositionsInBurst->choice.longBitmap.buf[i])<<((7-i)*8)); - } - break; - default: - AssertFatal(1==0,"SSB bitmap size value %d undefined (allowed values 1,2,3) \n", servingcellconfigcommon->ssb_PositionsInBurst->present); - } - memset(secondaryCellGroup,0,sizeof(NR_CellGroupConfig_t)); secondaryCellGroup->cellGroupId = scg_id; NR_RLC_BearerConfig_t *RLC_BearerConfig = calloc(1,sizeof(*RLC_BearerConfig)); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf index 1773e1fb7921be8a563c70001243c37e547b2e44..909c54b858b5042ce33a250132cdaa7dbf881365 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf @@ -182,11 +182,11 @@ gNBs = ); MACRLCs = ( - { - num_cc = 1; - tr_s_preference = "local_L1"; - tr_n_preference = "local_RRC"; - } + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + } ); L1s = ( @@ -194,6 +194,7 @@ L1s = ( num_cc = 1; tr_n_preference = "local_mac"; thread_pool_size = 8; + max_ldpc_iterations = 5; ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0 } );