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 0c75080398..835e334bbb 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 a93ef6aa8c..eccde746cc 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 0da04dcaed..97591a766d 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 9a2ececd18..4e1f87ed17 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 a2c68e9ef6..1fdc3446d9 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
+ -n100 -m0 -e0 -R25 -b25 -i 2 1 0
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
PDSCH test OK
segmentation fault|assertion|exiting|fatal
@@ -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)
+ (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)
$OPENAIR_DIR/cmake_targets/build_oai
--phy_simulators -c
@@ -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
- 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
+ -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
+
+ 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
PUSCH test OK
segmentation fault|assertion|exiting|fatal
3
diff --git a/common/utils/nr/nr_common.c b/common/utils/nr/nr_common.c
index af31c83d6e..6add03c324 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 5258ce8809..5f7f670ce9 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 df2bfd64de..9d1215b5e5 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 382dd7455a..fded7f1a9c 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 0000000000..1110a5bc6c
--- /dev/null
+++ b/doc/NR_SA_CN5G_gNB_B210_COTS_UE_Tutorial.md
@@ -0,0 +1,234 @@
+
+
+
+
+
+
+
+ |
+
+ OAI 5G SA tutorial
+ |
+
+
+
+**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 0000000000..ed917e09ea
--- /dev/null
+++ b/doc/NR_SA_CN5G_gNB_N300_COTS_UE_Tutorial.md
@@ -0,0 +1,251 @@
+
+
+
+
+
+
+
+ |
+
+ OAI 5G SA tutorial
+ |
+
+
+
+**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 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 0000000000..6750cb78be
--- /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 0000000000..e019c60e86
--- /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 8ea7f16712..327c01af6a 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 6e1864f290..01e6c62138 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 2347055402..de3c108841 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 95914678e5..995d81f19c 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/). 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 72a9491f27..6c5c610723 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 9972a47ee7..1854f28fa7 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 ab2a9ee74e..e2139a9903 100644
--- a/openair1/PHY/INIT/nr_init.c
+++ b/openair1/PHY/INIT/nr_init.c
@@ -545,7 +545,7 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
uint32_t ****pdsch_dmrs = gNB->nr_gold_pdsch_dmrs;
// ceil(((NB_RB*12(k)*2(QPSK)/32) // 3 RE *2(QPSK)
- int pdsch_dmrs_init_length = ((fp->N_RB_DL*24)>>5)+1;
+ const int pdsch_dmrs_init_length = ((fp->N_RB_DL*24)>>5)+1;
for (int slot=0; slotslots_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_ue.c b/openair1/PHY/INIT/nr_init_ue.c
index 15a868fdd4..c6e6ecd463 100644
--- a/openair1/PHY/INIT/nr_init_ue.c
+++ b/openair1/PHY/INIT/nr_init_ue.c
@@ -577,7 +577,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; jdlsch[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");
@@ -586,8 +586,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 7b526876da..cd3b535b3f 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 ca901e1452..1fd502a93e 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 13a83be53f..1297a0cc2f 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 ffbe850fdd..d70d991e7b 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;dnumDlDci;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
@@ -118,7 +118,7 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
/// DMRS QPSK modulation
for (int symb=cset_start_symb; symbDurationSymbols; 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
@@ -178,8 +178,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;
@@ -191,24 +193,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 490a8b5286..0bf6932bb5 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 8d5eb4a660..e9d3010ce7 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_idxcce_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_idxreg_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_idxreg_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;dnumDlDci;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_idxcce_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_idxreg_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_idxcce_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_idxreg_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 260bfbdfbc..4b8315e1ce 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 037851be0c..082370dff4 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 336d388d40..45eadd2c95 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 cd1bc9d3b2..eb43d80525 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; aarxnb_antennas_rx; aarx++) {
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c
index 48b08d761e..78e4a8a4e8 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 a342c93e7c..9e680bf227 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 ace4cf120b..f805aec552 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 259367a994..8ba87b7a67 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 9c607cb8b7..0d54caceb3 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 e38668000f..d366ae9ec1 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"
@@ -611,6 +612,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 99236c9a43..bab67e4426 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
#include
@@ -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 ((roundack==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; ipdcch_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 8a0a2d5144..5392424285 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 9a3b29a637..2a3730c1d4 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 \n");
+ printf("-L \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; irxnb_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 90cd9aae29..1e5122956e 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 6ceab3b97d..21655a74d5 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 bb80ff2a3c..5d6f9a2f2e 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 a658c990bc..6caddcff78 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 335f3be907..800e042464 100644
--- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h
+++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h
@@ -558,7 +558,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 ccd8ed8305..caa4af4144 100644
--- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h
+++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h
@@ -243,10 +243,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);
@@ -269,7 +266,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,
@@ -448,7 +445,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 0dfbbf2be3..9b618cdbfb 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; jCCE[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 c90c9031e5..50ea7cdd34 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 49aebb7daa..140fde407f 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 c99a65b288..84873621d3 100644
--- a/openair2/LAYER2/NR_MAC_gNB/config.c
+++ b/openair2/LAYER2/NR_MAC_gNB/config.c
@@ -633,13 +633,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);
@@ -651,30 +649,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 25a307e804..92867602c8 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
@@ -120,8 +120,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;
@@ -149,8 +147,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; ipdcch_cand[i] = 0;
for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
//mbsfn_status[CC_id] = 0;
@@ -183,9 +179,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 2ea4328b17..e3d3a5409d 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;
+
+ 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 (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;
+ if (pr_found == 0) {
+ continue;
+ }
+
+ 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;
+ }
- uint16_t ra_rnti;
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 1);
- // 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);
+ 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);
- // 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;
- }
+ uint8_t beam_index = ssb_index_from_prach(module_idP, frameP, slotP, preamble_index, freq_index, symbol);
- 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",
+ // 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");
-
- // 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;
- }
-
- 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();
- }
- }
-
- 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;
}
+ 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");
+
+ // 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;
+ }
+
+ 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();
+ }
+ }
+
+ 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;
}
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;
@@ -1991,7 +1989,7 @@ void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, sub_fram
// 3GPP TS 38.331 Section 12 Table 12.1-1: UE performance requirements for RRC procedures for UEs
const NR_COMMON_channels_t *common_channels = &RC.nrmac[module_id]->common_channels[0];
const NR_SIB1_t *sib1 = common_channels->sib1 ? common_channels->sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
- const NR_ServingCellConfig_t *servingCellConfig = UE_info->CellGroup[UE_id] ? UE_info->CellGroup[UE_id]->spCellConfig->spCellConfigDedicated : NULL;
+ const NR_ServingCellConfig_t *servingCellConfig = UE->CellGroup ? UE->CellGroup->spCellConfig->spCellConfigDedicated : NULL;
NR_BWP_t *genericParameters = get_dl_bwp_genericParameters(sched_ctrl->active_bwp,
common_channels->ServingCellConfigCommon,
sib1);
@@ -1999,7 +1997,7 @@ void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, sub_fram
NR_RRC_SETUP_DELAY_MS + NR_RRC_BWP_SWITCHING_DELAY_MS : NR_RRC_SETUP_DELAY_MS;
sched_ctrl->rrc_processing_timer = (delay_ms << genericParameters->subcarrierSpacing);
- LOG_I(NR_MAC, "(%d.%d) Activating RRC processing timer for UE %d with %d ms\n", frame, slot, UE_id, delay_ms);
+ LOG_I(NR_MAC, "(%d.%d) Activating RRC processing timer for UE %04x with %d ms\n", frame, slot, UE->rnti, delay_ms);
} else {
LOG_I(NR_MAC, "(ue rnti 0x%04x) RA Procedure failed at Msg4!\n", ra->rnti);
}
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
index 4b71b40662..3b5c9ffad4 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 56d14b1458..808fc613f1 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 16c428e409..efc83c034f 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; mShiftIndex, 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;
@@ -2266,30 +2246,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;
@@ -2937,6 +2904,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 b47f91fcc9..9d8efda714 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c
@@ -941,7 +941,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 f7f05fd57b..495ca765e6 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
@@ -933,8 +933,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
@@ -1101,8 +1100,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
@@ -1216,8 +1214,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 4fb51cd00b..9dbd745c19 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);
void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_UE_info_t *UE);
@@ -536,7 +526,7 @@ void UL_tti_req_ahead_initialization(gNB_MAC_INST * gNB, NR_ServingCellConfigCom
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 6547544a68..9b9fd4e76c 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,
+ 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);
- 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 %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 63bf7b0595..52ba4bf16a 100644
--- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
+++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
@@ -789,7 +789,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 8d4de8823b..ac0e48a910 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 29948401c5..90998f8450 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));
@@ -1636,38 +1554,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) {
- int curr_bwp = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth;
- 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);
@@ -1678,7 +1567,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 77f9faf361..11460f86af 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 575f642290..1d6db7b64d 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 201e69a70d..2f01017b0f 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;
@@ -561,25 +529,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 1773e1fb79..909c54b858 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
}
);