diff --git a/ci-scripts/xml_files/t2_offload_dec_nr_ulsim.xml b/ci-scripts/xml_files/t2_offload_dec_nr_ulsim.xml index 4c92d9b937..3b991bafe3 100644 --- a/ci-scripts/xml_files/t2_offload_dec_nr_ulsim.xml +++ b/ci-scripts/xml_files/t2_offload_dec_nr_ulsim.xml @@ -44,7 +44,7 @@ Run nr_ulsim with T2 LDPC offload: SNR = 30, MCS = 5, 106 PRBs, 1 layer nr_ulsim 100 - -n100 -s30 -m5 -r106 -R106 -o -P + -n100 -s30 -m5 -r106 -R106 -o -P --ldpc_offload.dpdk_dev d8:00.0 @@ -60,7 +60,7 @@ Run nr_ulsim with T2 LDPC offload: SNR = 30, MCS = 15, 106 PRBs, 1 layer nr_ulsim 150 - -n100 -s30 -m15 -r106 -R106 -o -P + -n100 -s30 -m15 -r106 -R106 -o -P --ldpc_offload.dpdk_dev d8:00.0 @@ -76,7 +76,7 @@ Run nr_ulsim with T2 LDPC offload: SNR = 30, MCS = 25, 106 PRBs, 1 layer nr_ulsim 250 - -n100 -s30 -m25 -r106 -R106 -o -P + -n100 -s30 -m25 -r106 -R106 -o -P --ldpc_offload.dpdk_dev d8:00.0 @@ -92,7 +92,7 @@ Run nr_ulsim with T2 LDPC offload: SNR = 30, MCS = 5, 273 PRBs, 1 layer nr_ulsim 150 - -n100 -s30 -m5 -r273 -R273 -o -P + -n100 -s30 -m5 -r273 -R273 -o -P --ldpc_offload.dpdk_dev d8:00.0 @@ -108,7 +108,7 @@ Run nr_ulsim with T2 LDPC offload: SNR = 30, MCS = 15, 273 PRBs, 1 layer nr_ulsim 350 - -n100 -s30 -m15 -r273 -R273 -o -P + -n100 -s30 -m15 -r273 -R273 -o -P --ldpc_offload.dpdk_dev d8:00.0 @@ -124,7 +124,7 @@ Run nr_ulsim with T2 LDPC offload: SNR = 30, MCS = 25, 273 PRBs, 1 layer nr_ulsim 550 - -n100 -s30 -m25 -r273 -R273 -o -P + -n100 -s30 -m25 -r273 -R273 -o -P --ldpc_offload.dpdk_dev d8:00.0 @@ -140,7 +140,7 @@ Run nr_ulsim with T2 LDPC offload: SNR = 30, MCS = 5, 273 PRBs, 2 layers nr_ulsim 250 - -n100 -s30 -m5 -r273 -R273 -o -W2 -z2 -y2 -P + -n100 -s30 -m5 -r273 -R273 -o -W2 -z2 -y2 -P --ldpc_offload.dpdk_dev d8:00.0 @@ -156,7 +156,7 @@ Run nr_ulsim with T2 LDPC offload: SNR = 30, MCS = 15, 273 PRBs, 2 layers nr_ulsim 650 - -n100 -s30 -m15 -r273 -R273 -o -W2 -z2 -y2 -P + -n100 -s30 -m15 -r273 -R273 -o -W2 -z2 -y2 -P --ldpc_offload.dpdk_dev d8:00.0 @@ -172,7 +172,7 @@ Run nr_ulsim with T2 LDPC offload: SNR = 30, MCS = 25, 273 PRBs, 2 layers nr_ulsim 1100 - -n100 -s30 -m25 -r273 -R273 -o -W2 -z2 -y2 -P + -n100 -s30 -m25 -r273 -R273 -o -W2 -z2 -y2 -P --ldpc_offload.dpdk_dev d8:00.0 diff --git a/ci-scripts/xml_files/t2_offload_enc_nr_dlsim.xml b/ci-scripts/xml_files/t2_offload_enc_nr_dlsim.xml index 7f29a7d38a..debf1aebf1 100644 --- a/ci-scripts/xml_files/t2_offload_enc_nr_dlsim.xml +++ b/ci-scripts/xml_files/t2_offload_enc_nr_dlsim.xml @@ -44,7 +44,7 @@ Run nr_dlsim with T2 LDPC offload: SNR = 30, MCS = 5, 106 PRBs, 1 layer nr_dlsim 100 - -n100 -s30 -e5 -b106 -R106 -c -P + -n100 -s30 -e5 -b106 -R106 -c -P --ldpc_offload.dpdk_dev d8:00.0 @@ -60,7 +60,7 @@ Run nr_dlsim with T2 LDPC offload: SNR = 30, MCS = 15, 106 PRBs, 1 layer nr_dlsim 100 - -n100 -s30 -e15 -b106 -R106 -c -P + -n100 -s30 -e15 -b106 -R106 -c -P --ldpc_offload.dpdk_dev d8:00.0 @@ -76,7 +76,7 @@ Run nr_dlsim with T2 LDPC offload: SNR = 30, MCS = 25, 106 PRBs, 1 layer nr_dlsim 200 - -n100 -s30 -e25 -b106 -R106 -c -P + -n100 -s30 -e25 -b106 -R106 -c -P --ldpc_offload.dpdk_dev d8:00.0 @@ -92,7 +92,7 @@ Run nr_dlsim with T2 LDPC offload: SNR = 30, MCS = 5, 273 PRBs, 1 layer nr_dlsim 150 - -n100 -s30 -e5 -b273 -R273 -c -P + -n100 -s30 -e5 -b273 -R273 -c -P --ldpc_offload.dpdk_dev d8:00.0 @@ -108,7 +108,7 @@ Run nr_dlsim with T2 LDPC offload: SNR = 30, MCS = 15, 273 PRBs, 1 layer nr_dlsim 250 - -n100 -s30 -e15 -b273 -R273 -c -P + -n100 -s30 -e15 -b273 -R273 -c -P --ldpc_offload.dpdk_dev d8:00.0 @@ -124,7 +124,7 @@ Run nr_dlsim with T2 LDPC offload: SNR = 30, MCS = 25, 273 PRBs, 1 layer nr_dlsim 400 - -n100 -s30 -e25 -b273 -R273 -c -P + -n100 -s30 -e25 -b273 -R273 -c -P --ldpc_offload.dpdk_dev d8:00.0 @@ -140,7 +140,7 @@ Run nr_dlsim with T2 LDPC offload: SNR = 30, MCS = 5, 273 PRBs, 2 layers nr_dlsim 200 - -n100 -s30 -e5 -b273 -R273 -c -x2 -z2 -y2 -P + -n100 -s30 -e5 -b273 -R273 -c -x2 -z2 -y2 -P --ldpc_offload.dpdk_dev d8:00.0 @@ -156,7 +156,7 @@ Run nr_dlsim with T2 LDPC offload: SNR = 30, MCS = 15, 273 PRBs, 2 layers nr_dlsim 500 - -n100 -s30 -e15 -b273 -R273 -c -x2 -z2 -y2 -P + -n100 -s30 -e15 -b273 -R273 -c -x2 -z2 -y2 -P --ldpc_offload.dpdk_dev d8:00.0 @@ -172,7 +172,7 @@ Run nr_dlsim with T2 LDPC offload: SNR = 30, MCS = 25, 273 PRBs, 2 layers nr_dlsim 800 - -n100 -s30 -e25 -b273 -R273 -c -x2 -z2 -y2 -P + -n100 -s30 -e25 -b273 -R273 -c -x2 -z2 -y2 -P --ldpc_offload.dpdk_dev d8:00.0 diff --git a/ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml b/ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml index f768bd7ca1..7eb3998fdd 100644 --- a/ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml +++ b/ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml @@ -113,7 +113,7 @@ services: --log_config.global_log_options level,nocolor,time --rfsimulator.options chanmod --telnetsrv --telnetsrv.listenaddr 192.168.71.171 - ASAN_OPTIONS: detect_leaks=0 + ASAN_OPTIONS: detect_leaks=0:detect_odr_violation=0 depends_on: - oai-cu networks: @@ -143,6 +143,7 @@ services: --rfsimulator.serveraddr 192.168.71.171 --rfsimulator.options chanmod --telnetsrv --telnetsrv.shrmod ciUE --telnetsrv.listenaddr 192.168.71.181 --telnetsrv.listenport 8091 + ASAN_OPTIONS: detect_odr_violation=0 depends_on: - oai-du networks: diff --git a/ci-scripts/yaml_files/5g_rfsimulator/README.md b/ci-scripts/yaml_files/5g_rfsimulator/README.md index 87e98633f3..e815047bda 100644 --- a/ci-scripts/yaml_files/5g_rfsimulator/README.md +++ b/ci-scripts/yaml_files/5g_rfsimulator/README.md @@ -535,3 +535,40 @@ snssais: ``` The `ST` and `SD` values shall also match. + + +# 6. Running with local changes + +You can run the testcase with local changes by substituting the binaries in +execution images. `local-override.yaml` file provides a way to substitute the +gNB and nrUE executables as well as librfsimulator.so. Refer to the `-volumes` +section in the file for details. This includes an image build service as well as +code compilation service. This is necessary as the executable has to be linked +against the same libraries that are present in the executing image. This might +take a while the first time but other that that is very fast. Here is a list of +commands (wait between each command). Tested with `docker compose` v2.27.0 + + +This command deploys OAI 5G Core Network +```bash +docker compose -f docker-compose.yaml -f local-override.yaml up -d mysql oai-amf oai-smf oai-upf oai-ext-dn +``` +This command builds base images locally, builds local gNB & nrUE executable and +runs the gnb service with modified gNB executable. +```bash +docker compose -f docker-compose.yaml -f local-override.yaml up -d oai-gnb +``` +This command rebuilds both the gNB & nrUE and runs the oai-nr-ue container with +modified nrUE executable. +```bash +docker compose -f docker-compose.yaml -f local-override.yaml up -d oai-nr-ue +``` + +## 6.1 Running nrUE in gdb +`local-override-ue-gdb.yaml` is an additional override file which can be used +to run the UE executable in gdb. Replace the last command above with the +following: + +```bash +docker compose -f docker-compose.yaml -f local-override.yaml -f local-override-ue-gdb.yaml run oai-nr-ue +``` diff --git a/ci-scripts/yaml_files/5g_rfsimulator/local-override-ue-gdb.yaml b/ci-scripts/yaml_files/5g_rfsimulator/local-override-ue-gdb.yaml new file mode 100644 index 0000000000..83498e44f7 --- /dev/null +++ b/ci-scripts/yaml_files/5g_rfsimulator/local-override-ue-gdb.yaml @@ -0,0 +1,6 @@ +services: + oai-nr-ue: + privileged: true + stdin_open: true + tty: true + command: gdb --args /opt/oai-nr-ue/bin/nr-uesoftmodem -O /opt/oai-nr-ue/etc/nr-ue.conf -E --sa --rfsim -r 106 --numerology 1 --uicc0.imsi 208990100001100 -C 3619200000 --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time diff --git a/ci-scripts/yaml_files/5g_rfsimulator/local-override.yaml b/ci-scripts/yaml_files/5g_rfsimulator/local-override.yaml new file mode 100644 index 0000000000..40d9b7ecc9 --- /dev/null +++ b/ci-scripts/yaml_files/5g_rfsimulator/local-override.yaml @@ -0,0 +1,27 @@ +include: + - ../local_common_overrides/build_images.yaml + - ../local_common_overrides/rebuild_nr_softmodems.yaml +services: + oai-gnb: + privileged: true + depends_on: + rebuild-nr-softmodems: + condition: service_completed_successfully + volumes: + - ../../../cmake_targets/ran_build/build/nr-softmodem:/opt/oai-gnb/bin/nr-softmodem + - ../../../cmake_targets/ran_build/build/librfsimulator.so:/usr/local/lib/librfsimulator.so + oai-nr-ue: + privileged: true + image: ue-local + depends_on: + build-ran-build: + condition: service_completed_successfully + restart: true + oai-gnb: + condition: service_started + rebuild-nr-softmodems: + condition: service_completed_successfully + volumes: + - ../../../cmake_targets/ran_build/build/nr-uesoftmodem:/opt/oai-nr-ue/bin/nr-uesoftmodem + - ../../../cmake_targets/ran_build/build/librfsimulator.so:/usr/local/lib/librfsimulator.so + - ../../../crashdumps/:/cores/ diff --git a/ci-scripts/yaml_files/5g_rfsimulator_tdd_dora/local-override.yaml b/ci-scripts/yaml_files/5g_rfsimulator_tdd_dora/local-override.yaml new file mode 100644 index 0000000000..c65d52ed29 --- /dev/null +++ b/ci-scripts/yaml_files/5g_rfsimulator_tdd_dora/local-override.yaml @@ -0,0 +1,27 @@ +include: + - ../local_common_overrides/build_images.yaml + - ../local_common_overrides/rebuild_nr_softmodems.yaml +services: + oai-gnb: + privileged: true + depends_on: + rebuild-nr-softmodems: + condition: service_completed_successfully + # volumes: + # replace the gnb executable here + oai-nr-ue: + privileged: true + image: ue-local + depends_on: + build-ran-build: + condition: service_completed_successfully + restart: true + oai-gnb: + condition: service_started + rebuild-nr-softmodems: + condition: service_completed_successfully + container_name: local-oai-nr-ue + volumes: + - ../../../cmake_targets/ran_build/build/nr-uesoftmodem:/opt/oai-nr-ue/bin/nr-uesoftmodem + - ../../../cmake_targets/ran_build/build/librfsimulator.so:/usr/local/lib/librfsimulator.so + - ../../../crashdumps/:/cores/ diff --git a/ci-scripts/yaml_files/local_common_overrides/build_images.yaml b/ci-scripts/yaml_files/local_common_overrides/build_images.yaml new file mode 100644 index 0000000000..a771289ae4 --- /dev/null +++ b/ci-scripts/yaml_files/local_common_overrides/build_images.yaml @@ -0,0 +1,45 @@ +services: + build-ran-base: + image: ran-base + build: + context: ../../../ + dockerfile: docker/Dockerfile.base.ubuntu22 + tags: + - ran-base + + build-ran-build: + image: ran-build + build: + context: ../../../ + dockerfile: docker/Dockerfile.build.ubuntu22 + tags: + - ran-build + depends_on: + build-ran-base: + condition: service_completed_successfully + + build-gnb-image: + image: gnb-local + build: + context: ../../../ + dockerfile: docker/Dockerfile.gNB.ubuntu22 + tags: + - gnb-local + depends_on: + build-ran-build: + condition: service_completed_successfully + entrypoint: "" + command: echo "gnb-image built" + + build-ue-image: + image: ue-local + build: + context: ../../../ + dockerfile: docker/Dockerfile.nrUE.ubuntu22 + tags: + - ue-local + depends_on: + build-ran-build: + condition: service_completed_successfully + entrypoint: "" + command: echo "ue-image built" diff --git a/ci-scripts/yaml_files/local_common_overrides/rebuild_nr_softmodems.yaml b/ci-scripts/yaml_files/local_common_overrides/rebuild_nr_softmodems.yaml new file mode 100644 index 0000000000..ca9cdb334d --- /dev/null +++ b/ci-scripts/yaml_files/local_common_overrides/rebuild_nr_softmodems.yaml @@ -0,0 +1,13 @@ +services: + rebuild-nr-softmodems: + image: ran-build + volumes: + - ../../../:/oai-dir/ + command: + bash -c "cd /oai-dir/ && mkdir -p cmake_targets/ran_build/build && cd cmake_targets/ran_build/build && cmake ../../../ -GNinja && cmake --build . --target nr-uesoftmodem rfsimulator nr-softmodem" + entrypoint: "" + depends_on: + build-gnb-image: + condition: service_completed_successfully + build-ue-image: + condition: service_completed_successfully diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index c4553765e4..9d28197450 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -614,7 +614,6 @@ check_install_oai_software() { gcc \ gcc-c++ \ git \ - atlas-devel \ pkgconfig \ libconfig-devel \ libffi-devel \ diff --git a/common/utils/nr/nr_common.c b/common/utils/nr/nr_common.c index 520dce1ace..2d7e4ce02f 100644 --- a/common/utils/nr/nr_common.c +++ b/common/utils/nr/nr_common.c @@ -644,16 +644,9 @@ int get_dmrs_port(int nl, uint16_t dmrs_ports) frame_type_t get_frame_type(uint16_t current_band, uint8_t scs_index) { - frame_type_t current_type; int32_t delta_duplex = get_delta_duplex(current_band, scs_index); - - if (delta_duplex == 0) - current_type = TDD; - else - current_type = FDD; - - LOG_I(NR_MAC, "NR band %d, duplex mode %s, duplex spacing = %d KHz\n", current_band, duplex_mode[current_type], delta_duplex); - + frame_type_t current_type = delta_duplex == 0 ? TDD : FDD; + LOG_D(NR_MAC, "NR band %d, duplex mode %s, duplex spacing = %d KHz\n", current_band, duplex_mode[current_type], delta_duplex); return current_type; } @@ -664,7 +657,7 @@ int32_t get_delta_duplex(int nr_bandP, uint8_t scs_index) int32_t delta_duplex = (nr_bandtable[nr_table_idx].ul_min - nr_bandtable[nr_table_idx].dl_min); - LOG_I(NR_MAC, "NR band duplex spacing is %d KHz (nr_bandtable[%d].band = %d)\n", delta_duplex, nr_table_idx, nr_bandtable[nr_table_idx].band); + LOG_D(NR_MAC, "NR band duplex spacing is %d KHz (nr_bandtable[%d].band = %d)\n", delta_duplex, nr_table_idx, nr_bandtable[nr_table_idx].band); return delta_duplex; } diff --git a/common/utils/oai_asn1.h b/common/utils/oai_asn1.h index 91d354ddbd..cc8392b0cf 100644 --- a/common/utils/oai_asn1.h +++ b/common/utils/oai_asn1.h @@ -85,7 +85,7 @@ if (eL == TARGET->list.array[iJ]->FIELD) \ break; \ } \ - if (iJ == TARGET->list.count) \ + if (iJ < TARGET->list.count) \ asn_sequence_del(&TARGET->list, iJ, 1); \ else \ LOG_E(NR_MAC, "Element not present in the list, impossible to release\n"); \ diff --git a/doc/LDPC_T2_OFFLOAD_SETUP.md b/doc/LDPC_T2_OFFLOAD_SETUP.md index 10c91fea33..df78590b5d 100644 --- a/doc/LDPC_T2_OFFLOAD_SETUP.md +++ b/doc/LDPC_T2_OFFLOAD_SETUP.md @@ -74,16 +74,11 @@ If DPDK library was installed into custom path, you have to point to the right d ``` export PKG_CONFIG_PATH=/opt/dpdk-t2/lib64/pkgconfig/:$PKG_CONFIG_PATH ``` -## T2 card DPDK initialization -Following lines in `openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder_offload.c` file has to be -modified based on your system requirements. By default, PCI address of the T2 card is set to 41:00.0 and cores 14 and 15 are assigned to the DPDK. -``` - char *dpdk_dev = "41:00.0"; //PCI address of the card - char *argv_re[] = {"bbdev", "-a", dpdk_dev, "-l", "14-15", "--file-prefix=b6", "--"}; -``` -For the DPDK EAL initialization, device is specified by `-a` option and list -of cores to run the DPDK application on is selected by `-l` option. PCI adress of -the T2 card can be detected by `lspci | grep "Xilinx"` command. +## Setup of T2-related DPDK EAL parameters +To configure T2-related DPDK Environment Abstraction Layer (EAL) parameters, you can set the following parameters via the command line: +- `ldpc_offload.dpdk_dev` - **mandatory** parameter, specifies PCI address of the T2 card. PCI address of the T2 card can be detected by `lspci | grep "Xilinx"` command. +- `ldpc_offload.dpdk_cores_list` - CPU cores assigned to DPDK for T2 processing, by default set to *11-12*. Ensure that the CPU cores specified in *ldpc_offload.dpdk_cores_list* are available and not used by other processes to avoid conflicts. +- `ldpc_offload.dpdk_prefix` - DPDK shared data file prefix, by default set to *b6* # OAI Build OTA deployment is precisely described in the following tutorial: @@ -118,7 +113,7 @@ Offload of the channel decoding to the T2 card is in nr_ulsim specified by *-o* cd ~/openairinterface5g source oaienv cd cmake_targets/ran_build/build -sudo ./nr_ulsim -n100 -s20 -m20 -r273 -R273 -o +sudo ./nr_ulsim -n100 -s20 -m20 -r273 -R273 -o --ldpc_offload.dpdk_dev 01:00.0 ``` ## nr_dlsim test Offload of the channel encoding to the AMD Xilinx T2 card is in nr_dlsim specified by *-c* option. Example command for running nr_dlsim with LDPC encoding offload to the T2 card: @@ -126,7 +121,7 @@ Offload of the channel encoding to the AMD Xilinx T2 card is in nr_dlsim specifi cd ~/openairinterface5g source oaienv cd cmake_targets/ran_build/build -sudo ./nr_dlsim -n300 -s30 -R 106 -e 27 -c +sudo ./nr_dlsim -n300 -s30 -R 106 -e 27 -c --ldpc_offload.dpdk_dev 01:00.0 ``` # OTA test @@ -137,7 +132,7 @@ Offload of the channel encoding and decoding to the AMD Xilinx T2 card is enable cd ~/openairinterface5g source oaienv cd cmake_targets/ran_build/build -sudo ./nr-softmodem --sa -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf --ldpc-offload-enable +sudo ./nr-softmodem --sa -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf --ldpc-offload-enable --ldpc_offload.dpdk_dev 01:00.0 ``` # Limitations diff --git a/doc/tutorial_resources/oai-cn5g/database/oai_db.sql b/doc/tutorial_resources/oai-cn5g/database/oai_db.sql index 4fadde5b43..a6eb5c54f2 100644 --- a/doc/tutorial_resources/oai-cn5g/database/oai_db.sql +++ b/doc/tutorial_resources/oai-cn5g/database/oai_db.sql @@ -211,13 +211,13 @@ CREATE TABLE `SessionManagementSubscriptionData` ( -- INSERT INTO `SessionManagementSubscriptionData` (`ueid`, `servingPlmnid`, `singleNssai`, `dnnConfigurations`) VALUES -('001010000000001', '00101', '{\"sst\": 1, \"sd\": \"16777215\"}','{\"oai\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4\"},\"sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 6,\"arp\":{\"priorityLevel\": 15,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"1000Mbps\", \"downlink\":\"1000Mbps\"},\"staticIpAddress\":[{\"ipv4Addr\": \"12.1.1.101\"}]},\"ims\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4V6\"},\"sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 2,\"arp\":{\"priorityLevel\": 15,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"1000Mbps\", \"downlink\":\"1000Mbps\"}}}'); +('001010000000001', '00101', '{\"sst\": 1, \"sd\": \"FFFFFF\"}','{\"oai\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4\"},\"sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 6,\"arp\":{\"priorityLevel\": 15,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"1000Mbps\", \"downlink\":\"1000Mbps\"},\"staticIpAddress\":[{\"ipv4Addr\": \"10.0.0.2\"}]},\"ims\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4V6\"},\"sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 2,\"arp\":{\"priorityLevel\": 15,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"1000Mbps\", \"downlink\":\"1000Mbps\"}}}'); INSERT INTO `SessionManagementSubscriptionData` (`ueid`, `servingPlmnid`, `singleNssai`, `dnnConfigurations`) VALUES -('001010000000002', '00101', '{\"sst\": 1, \"sd\": \"16777215\"}','{\"oai\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4\"},\"sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 6,\"arp\":{\"priorityLevel\": 15,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"1000Mbps\", \"downlink\":\"1000Mbps\"},\"staticIpAddress\":[{\"ipv4Addr\": \"12.1.1.102\"}]},\"ims\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4V6\"},\"sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 2,\"arp\":{\"priorityLevel\": 15,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"1000Mbps\", \"downlink\":\"1000Mbps\"}}}'); +('001010000000002', '00101', '{\"sst\": 1, \"sd\": \"FFFFFF\"}','{\"oai\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4\"},\"sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 6,\"arp\":{\"priorityLevel\": 15,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"1000Mbps\", \"downlink\":\"1000Mbps\"},\"staticIpAddress\":[{\"ipv4Addr\": \"10.0.0.3\"}]},\"ims\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4V6\"},\"sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 2,\"arp\":{\"priorityLevel\": 15,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"1000Mbps\", \"downlink\":\"1000Mbps\"}}}'); INSERT INTO `SessionManagementSubscriptionData` (`ueid`, `servingPlmnid`, `singleNssai`, `dnnConfigurations`) VALUES -('001010000000003', '00101', '{\"sst\": 1, \"sd\": \"16777215\"}','{\"oai\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4\"},\"sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 6,\"arp\":{\"priorityLevel\": 15,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"1000Mbps\", \"downlink\":\"1000Mbps\"},\"staticIpAddress\":[{\"ipv4Addr\": \"12.1.1.103\"}]},\"ims\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4V6\"},\"sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 2,\"arp\":{\"priorityLevel\": 15,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"1000Mbps\", \"downlink\":\"1000Mbps\"}}}'); +('001010000000003', '00101', '{\"sst\": 1, \"sd\": \"FFFFFF\"}','{\"oai\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4\"},\"sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 6,\"arp\":{\"priorityLevel\": 15,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"1000Mbps\", \"downlink\":\"1000Mbps\"},\"staticIpAddress\":[{\"ipv4Addr\": \"10.0.0.4\"}]},\"ims\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4V6\"},\"sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 2,\"arp\":{\"priorityLevel\": 15,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"1000Mbps\", \"downlink\":\"1000Mbps\"}}}'); INSERT INTO `SessionManagementSubscriptionData` (`ueid`, `servingPlmnid`, `singleNssai`, `dnnConfigurations`) VALUES -('001010000000004', '00101', '{\"sst\": 1, \"sd\": \"16777215\"}','{\"oai\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4\"},\"sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 6,\"arp\":{\"priorityLevel\": 15,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"1000Mbps\", \"downlink\":\"1000Mbps\"},\"staticIpAddress\":[{\"ipv4Addr\": \"12.1.1.104\"}]},\"ims\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4V6\"},\"sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 2,\"arp\":{\"priorityLevel\": 15,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"1000Mbps\", \"downlink\":\"1000Mbps\"}}}'); +('001010000000004', '00101', '{\"sst\": 1, \"sd\": \"FFFFFF\"}','{\"oai\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4\"},\"sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 6,\"arp\":{\"priorityLevel\": 15,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"1000Mbps\", \"downlink\":\"1000Mbps\"},\"staticIpAddress\":[{\"ipv4Addr\": \"10.0.0.5\"}]},\"ims\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4V6\"},\"sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 2,\"arp\":{\"priorityLevel\": 15,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"1000Mbps\", \"downlink\":\"1000Mbps\"}}}'); -- -------------------------------------------------------- diff --git a/docker/Dockerfile.base.ubuntu22.cross-arm64 b/docker/Dockerfile.base.ubuntu22.cross-arm64 index 83d891a110..2be24289f5 100644 --- a/docker/Dockerfile.base.ubuntu22.cross-arm64 +++ b/docker/Dockerfile.base.ubuntu22.cross-arm64 @@ -56,7 +56,6 @@ RUN apt-get update && \ tzdata \ xxd \ # ARM64 packages - libatlas-base-dev:arm64 \ libblas-dev:arm64 \ liblapack-dev:arm64 \ liblapacke-dev:arm64 \ diff --git a/docker/Dockerfile.build.rhel9 b/docker/Dockerfile.build.rhel9 index 8f7d276d03..6adeb62b31 100644 --- a/docker/Dockerfile.build.rhel9 +++ b/docker/Dockerfile.build.rhel9 @@ -39,4 +39,8 @@ RUN /bin/sh oaienv && \ --eNB --gNB --RU --UE --nrUE \ --build-lib "telnetsrv enbscope uescope nrscope" \ -w USRP -t Ethernet \ - --noavx512 + --noavx512 && \ + echo "---- ldd on executables ----" && \ + ldd ran_build/build/*softmodem* ran_build/build/nr-cuup ran_build/build/oairu && \ + echo "---- ldd on shared libraries ----" && \ + ldd ran_build/build/*.so diff --git a/docker/Dockerfile.build.ubuntu22 b/docker/Dockerfile.build.ubuntu22 index e92aecceda..6d704cc341 100644 --- a/docker/Dockerfile.build.ubuntu22 +++ b/docker/Dockerfile.build.ubuntu22 @@ -44,4 +44,7 @@ RUN /bin/sh oaienv && \ --noavx512 \ --cmake-opt -DCMAKE_C_FLAGS="-Werror" --cmake-opt -DCMAKE_CXX_FLAGS="-Werror" $BUILD_OPTION && \ # Mainly to see if the sanitize option was perfectly executed - ldd ran_build/build/nr-softmodem + echo "---- ldd on executables ----" && \ + ldd ran_build/build/*softmodem* ran_build/build/nr-cuup ran_build/build/oairu && \ + echo "---- ldd on shared libraries ----" && \ + ldd ran_build/build/*.so diff --git a/docker/Dockerfile.eNB.rhel9 b/docker/Dockerfile.eNB.rhel9 index 191c8eb2b5..c523ac0b1f 100644 --- a/docker/Dockerfile.eNB.rhel9 +++ b/docker/Dockerfile.eNB.rhel9 @@ -39,8 +39,8 @@ RUN dnf update -y && \ lksctp-tools \ tzdata \ procps-ng \ - atlas \ gdb \ + libusbx \ python3 \ python3-pip \ net-tools \ @@ -71,10 +71,6 @@ COPY --from=enb-build \ COPY --from=enb-base \ /lib64/libconfig.so.11 \ - /lib64/libblas.so.3 \ - /lib64/libcblas.so.3 \ - /lib64/liblapack.so.3 \ - /lib64/liblapacke.so.3 \ /lib64/libboost_chrono.so.1.75.0 \ /lib64/libboost_date_time.so.1.75.0 \ /lib64/libboost_filesystem.so.1.75.0 \ @@ -102,8 +98,20 @@ COPY --from=enb-base /usr/local/share/uhd/rfnoc/ . RUN /bin/bash -c "ln -s /usr/local/lib/liboai_usrpdevif.so /usr/local/lib/liboai_device.so" && \ /bin/bash -c "ln -s /usr/local/lib/liboai_eth_transpro.so /usr/local/lib/liboai_transpro.so" && \ - ldconfig - + ldconfig && \ + echo "---- ldd on executable lte-softmodem ----" && \ + ldd /opt/oai-enb/bin/lte-softmodem && \ + echo "---- ldd on shared libraries ----" && \ + ldd /usr/local/lib/liboai_eth_transpro.so \ + /usr/local/lib/librfsimulator.so \ + /usr/local/lib/liboai_usrpdevif.so \ + /usr/local/lib/libcoding.so \ + /usr/local/lib/libparams_libconfig.so \ + /usr/local/lib/libdfts.so \ + /usr/local/lib/liboai_iqplayer.so \ + /usr/local/lib/libtelnetsrv.so \ + /usr/local/lib/libtelnetsrv_enb.so \ + /usr/local/lib64/libuhd.so.4.4.0 WORKDIR /opt/oai-enb diff --git a/docker/Dockerfile.eNB.rocky b/docker/Dockerfile.eNB.rocky index 51705f0e7b..04243dfda2 100644 --- a/docker/Dockerfile.eNB.rocky +++ b/docker/Dockerfile.eNB.rocky @@ -40,8 +40,8 @@ RUN dnf update -y && \ lksctp-tools \ tzdata \ procps-ng \ - atlas \ gdb \ + libusbx \ python3 \ python3-pip \ net-tools \ @@ -72,10 +72,6 @@ COPY --from=enb-build \ COPY --from=enb-base \ /lib64/libconfig.so.11 \ - /lib64/libblas.so.3 \ - /lib64/libcblas.so.3 \ - /lib64/liblapack.so.3 \ - /lib64/liblapacke.so.3 \ /lib64/libboost_chrono.so.1.75.0 \ /lib64/libboost_date_time.so.1.75.0 \ /lib64/libboost_filesystem.so.1.75.0 \ @@ -104,16 +100,19 @@ COPY --from=enb-base /usr/local/share/uhd/rfnoc/ . RUN /bin/bash -c "ln -s /usr/local/lib/liboai_usrpdevif.so /usr/local/lib/liboai_device.so" && \ /bin/bash -c "ln -s /usr/local/lib/liboai_eth_transpro.so /usr/local/lib/liboai_transpro.so" && \ ldconfig && \ - echo "ldd on lte-softmodem" && ldd /opt/oai-enb/bin/lte-softmodem && \ - echo "ldd on liboai_eth_transpro.so" && ldd /usr/local/lib/liboai_eth_transpro.so && \ - echo "ldd on librfsimulator.so" && ldd /usr/local/lib/librfsimulator.so && \ - echo "ldd on liboai_usrpdevif.so" && ldd /usr/local/lib/liboai_usrpdevif.so && \ - echo "ldd on libcoding.so" && ldd /usr/local/lib/libcoding.so && \ - echo "ldd on libparams_libconfig.so" && ldd /usr/local/lib/libparams_libconfig.so && \ - echo "ldd on libdfts.so" && ldd /usr/local/lib/libdfts.so && \ - echo "ldd on liboai_iqplayer.so" && ldd /usr/local/lib/liboai_iqplayer.so && \ - echo "ldd on libtelnetsrv.so" && ldd /usr/local/lib/libtelnetsrv.so && \ - echo "ldd on libtelnetsrv_enb.so" && ldd /usr/local/lib/libtelnetsrv_enb.so + echo "---- ldd on executable lte-softmodem ----" && \ + ldd /opt/oai-enb/bin/lte-softmodem && \ + echo "---- ldd on shared libraries ----" && \ + ldd /usr/local/lib/liboai_eth_transpro.so \ + /usr/local/lib/librfsimulator.so \ + /usr/local/lib/liboai_usrpdevif.so \ + /usr/local/lib/libcoding.so \ + /usr/local/lib/libparams_libconfig.so \ + /usr/local/lib/libdfts.so \ + /usr/local/lib/liboai_iqplayer.so \ + /usr/local/lib/libtelnetsrv.so \ + /usr/local/lib/libtelnetsrv_enb.so \ + /usr/local/lib64/libuhd.so.4.4.0 WORKDIR /opt/oai-enb diff --git a/docker/Dockerfile.eNB.ubuntu22 b/docker/Dockerfile.eNB.ubuntu22 index c57e11a2a5..af580f6258 100644 --- a/docker/Dockerfile.eNB.ubuntu22 +++ b/docker/Dockerfile.eNB.ubuntu22 @@ -52,7 +52,6 @@ RUN apt-get update && \ libboost-program-options1.74.0 \ tzdata \ libblas3 \ - libatlas3-base \ libconfig9 \ openssl \ net-tools \ @@ -111,7 +110,18 @@ COPY --from=enb-base /usr/local/lib/uhd/utils/uhd_images_downloader.py /opt/oai- RUN /bin/bash -c "ln -s /usr/local/lib/liboai_usrpdevif.so /usr/local/lib/liboai_device.so" && \ /bin/bash -c "ln -s /usr/local/lib/liboai_eth_transpro.so /usr/local/lib/liboai_transpro.so" && \ ldconfig && \ - ldd /opt/oai-enb/bin/lte-softmodem + echo "---- ldd on lte-softmodem ----" && \ + ldd /opt/oai-enb/bin/lte-softmodem && \ + echo "---- ldd on shared libraries ----" && \ + ldd /usr/local/lib/liboai_eth_transpro.so \ + /usr/local/lib/librfsimulator.so \ + /usr/local/lib/liboai_usrpdevif.so \ + /usr/local/lib/libparams_libconfig.so \ + /usr/local/lib/libdfts.so \ + /usr/local/lib/liboai_iqplayer.so \ + /usr/local/lib/libtelnetsrv.so \ + /usr/local/lib/libtelnetsrv_enb.so \ + /usr/local/lib/libuhd.so.4.4.0 WORKDIR /opt/oai-enb diff --git a/docker/Dockerfile.gNB.aerial.ubuntu22 b/docker/Dockerfile.gNB.aerial.ubuntu22 index f3cfe7a4be..3259e27baa 100644 --- a/docker/Dockerfile.gNB.aerial.ubuntu22 +++ b/docker/Dockerfile.gNB.aerial.ubuntu22 @@ -69,7 +69,7 @@ RUN apt-get update && \ procps \ libsctp1 \ tzdata \ - libatlas3-base \ + libblas3 \ libconfig9 \ openssl \ net-tools \ @@ -95,6 +95,14 @@ COPY --from=ran-build \ /usr/local/lib/libnvipc.so \ /usr/local/lib/ +RUN ldconfig && \ + echo "---- ldd on nr-softmodem ----" && \ + ldd /opt/oai-gnb/bin/nr-softmodem && \ + echo "---- ldd on shared libraries ----" && \ + ldd /usr/local/lib/libparams_libconfig.so \ + /usr/local/lib/libfmtlog-shared.so \ + /usr/local/lib/libnvlog.so \ + /usr/local/lib/libnvipc.so WORKDIR /opt/oai-gnb COPY --from=ran-build /tini /tini diff --git a/docker/Dockerfile.gNB.aerial.ubuntu22.sanitize-address b/docker/Dockerfile.gNB.aerial.ubuntu22.sanitize-address index 0713d65a2c..919d7b788d 100644 --- a/docker/Dockerfile.gNB.aerial.ubuntu22.sanitize-address +++ b/docker/Dockerfile.gNB.aerial.ubuntu22.sanitize-address @@ -69,7 +69,7 @@ RUN apt-get update && \ procps \ libsctp1 \ tzdata \ - libatlas3-base \ + libblas3 \ libconfig9 \ openssl \ net-tools \ @@ -77,6 +77,7 @@ RUN apt-get update && \ iproute2 \ iputils-ping \ gdb \ + moreutils \ libusb-1.0-0 && \ rm -rf /var/lib/apt/lists/* @@ -100,6 +101,14 @@ COPY --from=ran-build \ /usr/local/lib/libnvipc.so \ /usr/local/lib/ +RUN ldconfig && \ + echo "---- ldd on nr-softmodem ----" && \ + ldd /opt/oai-gnb/bin/nr-softmodem && \ + echo "---- ldd on shared libraries ----" && \ + ldd /usr/local/lib/libparams_libconfig.so \ + /usr/local/lib/libfmtlog-shared.so \ + /usr/local/lib/libnvlog.so \ + /usr/local/lib/libnvipc.so WORKDIR /opt/oai-gnb COPY --from=ran-build /tini /tini diff --git a/docker/Dockerfile.gNB.aw2s.rhel9 b/docker/Dockerfile.gNB.aw2s.rhel9 index 52d3d8b1fc..926e2a2e75 100644 --- a/docker/Dockerfile.gNB.aw2s.rhel9 +++ b/docker/Dockerfile.gNB.aw2s.rhel9 @@ -46,7 +46,6 @@ RUN dnf update -y && \ procps-ng \ libXpm \ libX11 \ - atlas \ gdb \ lksctp-tools \ tzdata \ @@ -75,15 +74,22 @@ COPY --from=gnb-build \ COPY --from=gnb-base \ /lib64/libconfig.so.11 \ /lib64/libforms.so.2 \ - /lib64/libblas.so.3 \ - /lib64/libcblas.so.3 \ - /lib64/liblapack.so.3 \ - /lib64/liblapacke.so.3 \ /lib64/ RUN ln -s /usr/local/lib/libaw2sori_transpro.so /usr/local/lib/libthirdparty_transpro.so && \ ln -s /usr/local/lib/liboai_eth_transpro.so /usr/local/lib/liboai_transpro.so && \ - ldconfig + ldconfig && \ + echo "---- ldd on executable nr-softmodem ----" && \ + ldd /opt/oai-gnb-aw2s/bin/nr-softmodem && \ + echo "---- ldd on shared libraries ----" && \ + ldd /usr/local/lib/liboai_eth_transpro.so \ + /usr/local/lib/librfsimulator.so \ + /usr/local/lib/libaw2sori_transpro.so \ + /usr/local/lib/libcoding.so \ + /usr/local/lib/libparams_libconfig.so \ + /usr/local/lib/libdfts.so \ + /usr/local/lib/libldpc*.so \ + /usr/local/lib/libtelnetsrv.so WORKDIR /opt/oai-gnb-aw2s diff --git a/docker/Dockerfile.gNB.aw2s.rocky b/docker/Dockerfile.gNB.aw2s.rocky index 5758e674f6..269eb4be3f 100644 --- a/docker/Dockerfile.gNB.aw2s.rocky +++ b/docker/Dockerfile.gNB.aw2s.rocky @@ -47,7 +47,6 @@ RUN dnf update -y && \ procps-ng \ libXpm \ libX11 \ - atlas \ gdb \ lksctp-tools \ tzdata \ @@ -76,23 +75,22 @@ COPY --from=gnb-build \ COPY --from=gnb-base \ /lib64/libconfig.so.11 \ /lib64/libforms.so.2 \ - /lib64/libblas.so.3 \ - /lib64/libcblas.so.3 \ - /lib64/liblapack.so.3 \ - /lib64/liblapacke.so.3 \ /lib64/ RUN ln -s /usr/local/lib/libaw2sori_transpro.so /usr/local/lib/libthirdparty_transpro.so && \ ln -s /usr/local/lib/liboai_eth_transpro.so /usr/local/lib/liboai_transpro.so && \ ldconfig && \ - echo "ldd on nr-softmodem" && ldd /opt/oai-gnb-aw2s/bin/nr-softmodem && \ - echo "ldd on liboai_eth_transpro.so" && ldd /usr/local/lib/liboai_eth_transpro.so && \ - echo "ldd on librfsimulator.so" && ldd /usr/local/lib/librfsimulator.so && \ - echo "ldd on libthirdparty_transpro.so" && ldd /usr/local/lib/libthirdparty_transpro.so && \ - echo "ldd on libcoding.so" && ldd /usr/local/lib/libcoding.so && \ - echo "ldd on libparams_libconfig.so" && ldd /usr/local/lib/libparams_libconfig.so && \ - echo "ldd on libdfts.so" && ldd /usr/local/lib/libdfts.so && \ - echo "ldd on libtelnetsrv.so" && ldd /usr/local/lib/libtelnetsrv.so + echo "---- ldd on executable nr-softmodem ----" && \ + ldd /opt/oai-gnb-aw2s/bin/nr-softmodem && \ + echo "---- ldd on shared libraries ----" && \ + ldd /usr/local/lib/liboai_eth_transpro.so \ + /usr/local/lib/librfsimulator.so \ + /usr/local/lib/libaw2sori_transpro.so \ + /usr/local/lib/libcoding.so \ + /usr/local/lib/libparams_libconfig.so \ + /usr/local/lib/libdfts.so \ + /usr/local/lib/libldpc*.so \ + /usr/local/lib/libtelnetsrv.so WORKDIR /opt/oai-gnb-aw2s diff --git a/docker/Dockerfile.gNB.aw2s.ubuntu22 b/docker/Dockerfile.gNB.aw2s.ubuntu22 index a000d9a643..e4645a71e0 100644 --- a/docker/Dockerfile.gNB.aw2s.ubuntu22 +++ b/docker/Dockerfile.gNB.aw2s.ubuntu22 @@ -49,7 +49,7 @@ RUN apt-get update && \ libsctp1 \ tzdata \ libblas3 \ - libatlas3-base \ + libc6 \ libconfig9 \ gdb \ openssl \ @@ -78,7 +78,18 @@ COPY --from=gnb-build \ RUN /bin/bash -c "ln -s /usr/local/lib/libaw2sori_transpro.so /usr/local/lib/libthirdparty_transpro.so" && \ /bin/bash -c "ln -s /usr/local/lib/liboai_eth_transpro.so /usr/local/lib/liboai_transpro.so" && \ - ldconfig + ldconfig && \ + echo "---- ldd on nr-softmodem ----" && \ + ldd /opt/oai-gnb-aw2s/bin/nr-softmodem && \ + echo "---- ldd on shared libraries ----" && \ + ldd /usr/local/lib/liboai_eth_transpro.so \ + /usr/local/lib/librfsimulator.so \ + /usr/local/lib/libaw2sori_transpro.so \ + /usr/local/lib/libcoding.so \ + /usr/local/lib/libparams_libconfig.so \ + /usr/local/lib/libdfts.so \ + /usr/local/lib/libldpc*.so \ + /usr/local/lib/libtelnetsrv.so WORKDIR /opt/oai-gnb-aw2s diff --git a/docker/Dockerfile.gNB.rhel9 b/docker/Dockerfile.gNB.rhel9 index 358782519f..d4f20b1cd0 100644 --- a/docker/Dockerfile.gNB.rhel9 +++ b/docker/Dockerfile.gNB.rhel9 @@ -39,7 +39,7 @@ RUN dnf update -y && \ procps-ng \ libXpm \ libX11 \ - atlas \ + libusbx \ lksctp-tools \ tzdata \ gdb \ @@ -72,10 +72,6 @@ COPY --from=gnb-build \ COPY --from=gnb-base \ /lib64/libconfig.so.11 \ /lib64/libforms.so.2 \ - /lib64/libblas.so.3 \ - /lib64/libcblas.so.3 \ - /lib64/liblapack.so.3 \ - /lib64/liblapacke.so.3 \ /lib64/libboost_chrono.so.1.75.0 \ /lib64/libboost_date_time.so.1.75.0 \ /lib64/libboost_filesystem.so.1.75.0 \ @@ -101,7 +97,20 @@ WORKDIR /usr/local/share/uhd/rfnoc COPY --from=gnb-base /usr/local/share/uhd/rfnoc/ . RUN /bin/bash -c "ln -s /usr/local/lib/liboai_usrpdevif.so /usr/local/lib/liboai_device.so" && \ - ldconfig + ldconfig && \ + echo "---- ldd on executable nr-softmodem ----" && \ + ldd /opt/oai-gnb/bin/nr-softmodem && \ + echo "---- ldd on shared libraries ----" && \ + ldd /usr/local/lib/liboai_eth_transpro.so \ + /usr/local/lib/librfsimulator.so \ + /usr/local/lib/liboai_usrpdevif.so \ + /usr/local/lib/libcoding.so \ + /usr/local/lib/libparams_libconfig.so \ + /usr/local/lib/libdfts.so \ + /usr/local/lib/libldpc*.so \ + /usr/local/lib/libtelnetsrv.so \ + /usr/local/lib/libtelnetsrv_ci.so \ + /usr/local/lib64/libuhd.so.4.4.0 WORKDIR /opt/oai-gnb #EXPOSE 2152/udp # S1U, GTP/UDP diff --git a/docker/Dockerfile.gNB.rocky b/docker/Dockerfile.gNB.rocky index d4c8504bb8..2e59a0d230 100644 --- a/docker/Dockerfile.gNB.rocky +++ b/docker/Dockerfile.gNB.rocky @@ -40,7 +40,7 @@ RUN dnf update -y && \ procps-ng \ libXpm \ libX11 \ - atlas \ + libusbx \ lksctp-tools \ tzdata \ gdb \ @@ -73,10 +73,6 @@ COPY --from=gnb-build \ COPY --from=gnb-base \ /lib64/libconfig.so.11 \ /lib64/libforms.so.2 \ - /lib64/libblas.so.3 \ - /lib64/libcblas.so.3 \ - /lib64/liblapack.so.3 \ - /lib64/liblapacke.so.3 \ /lib64/libboost_chrono.so.1.75.0 \ /lib64/libboost_date_time.so.1.75.0 \ /lib64/libboost_filesystem.so.1.75.0 \ @@ -103,15 +99,19 @@ COPY --from=gnb-base /usr/local/share/uhd/rfnoc/ . RUN /bin/bash -c "ln -s /usr/local/lib/liboai_usrpdevif.so /usr/local/lib/liboai_device.so" && \ ldconfig && \ - echo "ldd on nr-softmodem" && ldd /opt/oai-gnb/bin/nr-softmodem && \ - echo "ldd on liboai_eth_transpro.so" && ldd /usr/local/lib/liboai_eth_transpro.so && \ - echo "ldd on librfsimulator.so" && ldd /usr/local/lib/librfsimulator.so && \ - echo "ldd on liboai_usrpdevif.so" && ldd /usr/local/lib/liboai_usrpdevif.so && \ - echo "ldd on libcoding.so" && ldd /usr/local/lib/libcoding.so && \ - echo "ldd on libparams_libconfig.so" && ldd /usr/local/lib/libparams_libconfig.so && \ - echo "ldd on libdfts.so" && ldd /usr/local/lib/libdfts.so && \ - echo "ldd on libtelnetsrv.so" && ldd /usr/local/lib/libtelnetsrv.so && \ - echo "ldd on libtelnetsrv_ci.so" && ldd /usr/local/lib/libtelnetsrv_ci.so + echo "---- ldd on executable nr-softmodem ----" && \ + ldd /opt/oai-gnb/bin/nr-softmodem && \ + echo "---- ldd on shared libraries ----" && \ + ldd /usr/local/lib/liboai_eth_transpro.so \ + /usr/local/lib/librfsimulator.so \ + /usr/local/lib/liboai_usrpdevif.so \ + /usr/local/lib/libcoding.so \ + /usr/local/lib/libparams_libconfig.so \ + /usr/local/lib/libdfts.so \ + /usr/local/lib/libldpc*.so \ + /usr/local/lib/libtelnetsrv.so \ + /usr/local/lib/libtelnetsrv_ci.so \ + /usr/local/lib64/libuhd.so.4.4.0 WORKDIR /opt/oai-gnb #EXPOSE 2152/udp # S1U, GTP/UDP diff --git a/docker/Dockerfile.gNB.ubuntu22 b/docker/Dockerfile.gNB.ubuntu22 index f039d9dce0..6ac01d7139 100644 --- a/docker/Dockerfile.gNB.ubuntu22 +++ b/docker/Dockerfile.gNB.ubuntu22 @@ -52,7 +52,6 @@ RUN apt-get update && \ libboost-program-options1.74.0 \ tzdata \ libblas3 \ - libatlas3-base \ libconfig9 \ openssl \ net-tools \ @@ -103,7 +102,19 @@ COPY --from=gnb-base /usr/local/lib/uhd/utils/uhd_images_downloader.py /opt/oai- RUN /bin/bash -c "ln -s /usr/local/lib/liboai_usrpdevif.so /usr/local/lib/liboai_device.so" && \ ldconfig && \ - ldd /opt/oai-gnb/bin/nr-softmodem + echo "---- ldd on nr-softmodem ----" && \ + ldd /opt/oai-gnb/bin/nr-softmodem && \ + echo "---- ldd on shared libraries ----" && \ + ldd /usr/local/lib/liboai_eth_transpro.so \ + /usr/local/lib/librfsimulator.so \ + /usr/local/lib/liboai_usrpdevif.so \ + /usr/local/lib/libcoding.so \ + /usr/local/lib/libparams_libconfig.so \ + /usr/local/lib/libdfts.so \ + /usr/local/lib/libldpc*.so \ + /usr/local/lib/libtelnetsrv.so \ + /usr/local/lib/libtelnetsrv_ci.so \ + /usr/local/lib/libuhd.so.4.4.0 WORKDIR /opt/oai-gnb #EXPOSE 2152/udp # S1U, GTP/UDP diff --git a/docker/Dockerfile.lteRU.rhel9 b/docker/Dockerfile.lteRU.rhel9 index 30e996600c..d57c88bbf4 100644 --- a/docker/Dockerfile.lteRU.rhel9 +++ b/docker/Dockerfile.lteRU.rhel9 @@ -38,7 +38,7 @@ RUN dnf update -y && \ dnf install -y \ tzdata \ procps-ng \ - atlas \ + libusbx \ gdb \ python3 \ python3-pip \ @@ -65,10 +65,6 @@ COPY --from=ru-build \ COPY --from=ru-base \ /lib64/libconfig.so.11 \ - /lib64/libblas.so.3 \ - /lib64/libcblas.so.3 \ - /lib64/liblapack.so.3 \ - /lib64/liblapacke.so.3 \ /lib64/libboost_chrono.so.1.75.0 \ /lib64/libboost_date_time.so.1.75.0 \ /lib64/libboost_filesystem.so.1.75.0 \ @@ -91,7 +87,16 @@ WORKDIR /usr/local/share/uhd/rfnoc COPY --from=ru-base /usr/local/share/uhd/rfnoc/ . RUN /bin/bash -c "ln -s /usr/local/lib/liboai_usrpdevif.so /usr/local/lib/liboai_device.so" && \ - ldconfig + ldconfig && \ + echo "---- ldd on executable oairu ----" && \ + ldd /opt/oai-lte-ru/bin/oairu && \ + echo "---- ldd on shared libraries ----" && \ + ldd /usr/local/lib/liboai_eth_transpro.so \ + /usr/local/lib/librfsimulator.so \ + /usr/local/lib/liboai_usrpdevif.so \ + /usr/local/lib/libparams_libconfig.so \ + /usr/local/lib/libdfts.so \ + /usr/local/lib64/libuhd.so.4.4.0 WORKDIR /opt/oai-lte-ru diff --git a/docker/Dockerfile.lteRU.ubuntu22 b/docker/Dockerfile.lteRU.ubuntu22 index 44a7337e40..83a3e950ab 100644 --- a/docker/Dockerfile.lteRU.ubuntu22 +++ b/docker/Dockerfile.lteRU.ubuntu22 @@ -42,7 +42,6 @@ RUN apt-get update && \ procps \ software-properties-common \ libblas3 \ - libatlas3-base \ libconfig9 \ net-tools \ gdb \ @@ -83,7 +82,16 @@ COPY --from=ru-base \ /usr/lib/x86_64-linux-gnu/ RUN /bin/bash -c "ln -s /usr/local/lib/liboai_usrpdevif.so /usr/local/lib/liboai_device.so" && \ - ldconfig + ldconfig && \ + echo "---- ldd on oairu ----" && \ + ldd /opt/oai-lte-ru/bin/oairu && \ + echo "---- ldd on shared libraries ----" && \ + ldd /usr/local/lib/liboai_eth_transpro.so \ + /usr/local/lib/librfsimulator.so \ + /usr/local/lib/liboai_usrpdevif.so \ + /usr/local/lib/libparams_libconfig.so \ + /usr/local/lib/libdfts.so \ + /usr/local/lib/libuhd.so.4.4.0 WORKDIR /opt/oai-lte-ru diff --git a/docker/Dockerfile.lteUE.rhel9 b/docker/Dockerfile.lteUE.rhel9 index a9a95e23a6..84854c2104 100644 --- a/docker/Dockerfile.lteUE.rhel9 +++ b/docker/Dockerfile.lteUE.rhel9 @@ -39,7 +39,8 @@ RUN dnf update -y && \ lksctp-tools \ procps-ng \ tzdata \ - atlas \ + libusbx \ + libgfortran \ gdb \ python3 \ python3-pip \ @@ -101,7 +102,18 @@ WORKDIR /usr/local/share/uhd/rfnoc COPY --from=lte-ue-base /usr/local/share/uhd/rfnoc/ . RUN /bin/bash -c "ln -s /usr/local/lib/liboai_usrpdevif.so /usr/local/lib/liboai_device.so" && \ - ldconfig + ldconfig && \ + echo "---- ldd on executable lte-uesoftmodem ----" && \ + ldd /opt/oai-lte-ue/bin/lte-uesoftmodem && \ + echo "---- ldd on shared libraries ----" && \ + ldd /usr/local/lib/liboai_eth_transpro.so \ + /usr/local/lib/librfsimulator.so \ + /usr/local/lib/liboai_usrpdevif.so \ + /usr/local/lib/libcoding.so \ + /usr/local/lib/libparams_libconfig.so \ + /usr/local/lib/libdfts.so \ + /usr/local/lib/libtelnetsrv.so \ + /usr/local/lib64/libuhd.so.4.4.0 WORKDIR /opt/oai-lte-ue COPY --from=lte-ue-base /tini /tini diff --git a/docker/Dockerfile.lteUE.rocky b/docker/Dockerfile.lteUE.rocky index 95845a0fd4..54b5dfa52a 100644 --- a/docker/Dockerfile.lteUE.rocky +++ b/docker/Dockerfile.lteUE.rocky @@ -40,7 +40,8 @@ RUN dnf update -y && \ lksctp-tools \ procps-ng \ tzdata \ - atlas \ + libusbx \ + libgfortran \ gdb \ python3 \ python3-pip \ @@ -103,17 +104,17 @@ COPY --from=lte-ue-base /usr/local/share/uhd/rfnoc/ . RUN /bin/bash -c "ln -s /usr/local/lib/liboai_usrpdevif.so /usr/local/lib/liboai_device.so" && \ ldconfig && \ - echo "ldd on lte-uesoftmodem" && ldd /opt/oai-lte-ue/bin/lte-uesoftmodem && \ - echo "ldd on conf2uedata" && ldd /opt/oai-lte-ue/bin/conf2uedata && \ - echo "ldd on nvram" && ldd /opt/oai-lte-ue/bin/nvram && \ - echo "ldd on usim" && ldd /opt/oai-lte-ue/bin/usim && \ - echo "ldd on liboai_eth_transpro.so" && ldd /usr/local/lib/liboai_eth_transpro.so && \ - echo "ldd on librfsimulator.so" && ldd /usr/local/lib/librfsimulator.so && \ - echo "ldd on liboai_usrpdevif.so" && ldd /usr/local/lib/liboai_usrpdevif.so && \ - echo "ldd on libcoding.so" && ldd /usr/local/lib/libcoding.so && \ - echo "ldd on libparams_libconfig.so" && ldd /usr/local/lib/libparams_libconfig.so && \ - echo "ldd on libdfts.so" && ldd /usr/local/lib/libdfts.so && \ - echo "ldd on libtelnetsrv.so" && ldd /usr/local/lib/libtelnetsrv.so + echo "---- ldd on executable lte-uesoftmodem ----" && \ + ldd /opt/oai-lte-ue/bin/lte-uesoftmodem && \ + echo "---- ldd on shared libraries ----" && \ + ldd /usr/local/lib/liboai_eth_transpro.so \ + /usr/local/lib/librfsimulator.so \ + /usr/local/lib/liboai_usrpdevif.so \ + /usr/local/lib/libcoding.so \ + /usr/local/lib/libparams_libconfig.so \ + /usr/local/lib/libdfts.so \ + /usr/local/lib/libtelnetsrv.so \ + /usr/local/lib64/libuhd.so.4.4.0 WORKDIR /opt/oai-lte-ue COPY --from=lte-ue-base /tini /tini diff --git a/docker/Dockerfile.lteUE.ubuntu22 b/docker/Dockerfile.lteUE.ubuntu22 index d3d4571782..057b6d17dc 100644 --- a/docker/Dockerfile.lteUE.ubuntu22 +++ b/docker/Dockerfile.lteUE.ubuntu22 @@ -52,7 +52,7 @@ RUN apt-get update && \ libboost-program-options1.74.0 \ tzdata \ liblapacke \ - libatlas3-base \ + libblas3 \ libconfig9 \ openssl \ net-tools \ @@ -112,7 +112,17 @@ COPY --from=lte-ue-base /usr/local/lib/uhd/utils/uhd_images_downloader.py /opt/o RUN /bin/bash -c "ln -s /usr/local/lib/liboai_usrpdevif.so /usr/local/lib/liboai_device.so" && \ ldconfig && \ - ldd /opt/oai-lte-ue/bin/lte-uesoftmodem + echo "---- ldd on lte-uesoftmodem ----" && \ + ldd /opt/oai-lte-ue/bin/lte-uesoftmodem && \ + echo "---- ldd on shared librarues ----" && \ + ldd /usr/local/lib/liboai_eth_transpro.so \ + /usr/local/lib/librfsimulator.so \ + /usr/local/lib/liboai_usrpdevif.so \ + /usr/local/lib/libcoding.so \ + /usr/local/lib/libparams_libconfig.so \ + /usr/local/lib/libdfts.so \ + /usr/local/lib/libtelnetsrv.so \ + /usr/local/lib/libuhd.so.4.4.0 WORKDIR /opt/oai-lte-ue COPY --from=lte-ue-base /tini /tini diff --git a/docker/Dockerfile.nr-cuup.rhel9 b/docker/Dockerfile.nr-cuup.rhel9 index 00d6236bfe..c10560e13f 100644 --- a/docker/Dockerfile.nr-cuup.rhel9 +++ b/docker/Dockerfile.nr-cuup.rhel9 @@ -41,7 +41,6 @@ RUN yum repolist --disablerepo=* && \ procps-ng \ lksctp-tools \ tzdata \ - atlas \ net-tools \ iputils && \ echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf && \ @@ -60,10 +59,6 @@ COPY --from=gnb-build \ COPY --from=gnb-base \ /lib64/libconfig.so.11 \ - /lib64/libblas.so.3 \ - /lib64/libcblas.so.3 \ - /lib64/liblapack.so.3 \ - /lib64/liblapacke.so.3 \ /lib64/ RUN ldconfig && \ diff --git a/docker/Dockerfile.nr-cuup.rocky b/docker/Dockerfile.nr-cuup.rocky index e3dc1bf5be..e6803bce1a 100644 --- a/docker/Dockerfile.nr-cuup.rocky +++ b/docker/Dockerfile.nr-cuup.rocky @@ -42,7 +42,6 @@ RUN yum repolist --disablerepo=* && \ procps-ng \ lksctp-tools \ tzdata \ - atlas \ net-tools \ iputils && \ echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf && \ @@ -61,10 +60,6 @@ COPY --from=gnb-build \ COPY --from=gnb-base \ /lib64/libconfig.so.11 \ - /lib64/libblas.so.3 \ - /lib64/libcblas.so.3 \ - /lib64/liblapack.so.3 \ - /lib64/liblapacke.so.3 \ /lib64/ RUN ldconfig && \ diff --git a/docker/Dockerfile.nrUE.rhel9 b/docker/Dockerfile.nrUE.rhel9 index 14d9f6c7f7..7d5894c618 100644 --- a/docker/Dockerfile.nrUE.rhel9 +++ b/docker/Dockerfile.nrUE.rhel9 @@ -42,7 +42,7 @@ RUN dnf update -y && \ net-tools \ iputils \ iproute \ - atlas \ + libusbx \ gdb \ python3 \ python3-pip \ @@ -74,10 +74,6 @@ COPY --from=nr-ue-build \ COPY --from=nr-ue-base \ /lib64/libconfig.so.11 \ - /lib64/libblas.so.3 \ - /lib64/libcblas.so.3 \ - /lib64/liblapack.so.3 \ - /lib64/liblapacke.so.3 \ /lib64/libforms.so.2 \ /lib64/libboost_chrono.so.1.75.0 \ /lib64/libboost_date_time.so.1.75.0 \ @@ -104,8 +100,20 @@ WORKDIR /usr/local/share/uhd/rfnoc COPY --from=nr-ue-base /usr/local/share/uhd/rfnoc/ . RUN /bin/bash -c "ln -s /usr/local/lib/liboai_usrpdevif.so /usr/local/lib/liboai_device.so" && \ - ldconfig - + ldconfig && \ + echo "---- ldd on executable nr-uesoftmodem ----" && \ + ldd /opt/oai-nr-ue/bin/nr-uesoftmodem && \ + echo "---- ldd on shared libraries ----" && \ + ldd /usr/local/lib/liboai_eth_transpro.so \ + /usr/local/lib/librfsimulator.so \ + /usr/local/lib/liboai_usrpdevif.so \ + /usr/local/lib/libcoding.so \ + /usr/local/lib/libparams_libconfig.so \ + /usr/local/lib/libdfts.so \ + /usr/local/lib/libldpc*.so \ + /usr/local/lib/libtelnetsrv.so \ + /usr/local/lib/libtelnetsrv_5Gue.so \ + /usr/local/lib64/libuhd.so.4.4.0 WORKDIR /opt/oai-nr-ue COPY --from=nr-ue-base /tini /tini diff --git a/docker/Dockerfile.nrUE.rocky b/docker/Dockerfile.nrUE.rocky index 1ffccd60d5..88d6bd73ff 100644 --- a/docker/Dockerfile.nrUE.rocky +++ b/docker/Dockerfile.nrUE.rocky @@ -43,7 +43,7 @@ RUN dnf update -y && \ net-tools \ iputils \ iproute \ - atlas \ + libusbx \ gdb \ python3 \ python3-pip \ @@ -75,10 +75,6 @@ COPY --from=nr-ue-build \ COPY --from=nr-ue-base \ /lib64/libconfig.so.11 \ - /lib64/libblas.so.3 \ - /lib64/libcblas.so.3 \ - /lib64/liblapack.so.3 \ - /lib64/liblapacke.so.3 \ /lib64/libforms.so.2 \ /lib64/libboost_chrono.so.1.75.0 \ /lib64/libboost_date_time.so.1.75.0 \ @@ -106,15 +102,19 @@ COPY --from=nr-ue-base /usr/local/share/uhd/rfnoc/ . RUN /bin/bash -c "ln -s /usr/local/lib/liboai_usrpdevif.so /usr/local/lib/liboai_device.so" && \ ldconfig && \ - echo "ldd on nr-uesoftmodem" && ldd /opt/oai-nr-ue/bin/nr-uesoftmodem && \ - echo "ldd on liboai_eth_transpro.so" && ldd /usr/local/lib/liboai_eth_transpro.so && \ - echo "ldd on librfsimulator.so" && ldd /usr/local/lib/librfsimulator.so && \ - echo "ldd on liboai_usrpdevif.so" && ldd /usr/local/lib/liboai_usrpdevif.so && \ - echo "ldd on libcoding.so" && ldd /usr/local/lib/libcoding.so && \ - echo "ldd on libparams_libconfig.so" && ldd /usr/local/lib/libparams_libconfig.so && \ - echo "ldd on libdfts.so" && ldd /usr/local/lib/libdfts.so && \ - echo "ldd on libtelnetsrv.so" && ldd /usr/local/lib/libtelnetsrv.so && \ - echo "ldd on libtelnetsrv_5Gue.so" && ldd /usr/local/lib/libtelnetsrv_5Gue.so + echo "---- ldd on executable nr-uesoftmodem ----" && \ + ldd /opt/oai-nr-ue/bin/nr-uesoftmodem && \ + echo "---- ldd on shared libraries ----" && \ + ldd /usr/local/lib/liboai_eth_transpro.so \ + /usr/local/lib/librfsimulator.so \ + /usr/local/lib/liboai_usrpdevif.so \ + /usr/local/lib/libcoding.so \ + /usr/local/lib/libparams_libconfig.so \ + /usr/local/lib/libdfts.so \ + /usr/local/lib/libldpc*.so \ + /usr/local/lib/libtelnetsrv.so \ + /usr/local/lib/libtelnetsrv_5Gue.so \ + /usr/local/lib64/libuhd.so.4.4.0 WORKDIR /opt/oai-nr-ue COPY --from=nr-ue-base /tini /tini diff --git a/docker/Dockerfile.nrUE.ubuntu22 b/docker/Dockerfile.nrUE.ubuntu22 index 13387d2523..83aa918045 100644 --- a/docker/Dockerfile.nrUE.ubuntu22 +++ b/docker/Dockerfile.nrUE.ubuntu22 @@ -52,7 +52,7 @@ RUN apt-get update && \ libboost-program-options1.74.0 \ tzdata \ liblapacke \ - libatlas3-base \ + libblas3 \ libconfig9 \ openssl \ net-tools \ @@ -106,7 +106,20 @@ COPY --from=nr-ue-base /usr/local/lib/uhd/utils/uhd_images_downloader.py /opt/oa RUN /bin/bash -c "ln -s /usr/local/lib/liboai_usrpdevif.so /usr/local/lib/liboai_device.so" && \ ldconfig && \ - ldd /opt/oai-nr-ue/bin/nr-uesoftmodem + echo "---- ldd on nr-uesoftmodem ----" && \ + ldd /opt/oai-nr-ue/bin/nr-uesoftmodem && \ + echo "---- ldd on shared libraries ----" && \ + ldd /usr/local/lib/liboai_eth_transpro.so \ + /usr/local/lib/librfsimulator.so \ + /usr/local/lib/liboai_usrpdevif.so \ + /usr/local/lib/libcoding.so \ + /usr/local/lib/libparams_libconfig.so \ + /usr/local/lib/libdfts.so \ + /usr/local/lib/libldpc*.so \ + /usr/local/lib/libtelnetsrv.so \ + /usr/local/lib/libtelnetsrv_ciUE.so \ + /usr/local/lib/libtelnetsrv_5Gue.so \ + /usr/local/lib/libuhd.so.4.4.0 WORKDIR /opt/oai-nr-ue COPY --from=nr-ue-base /tini /tini diff --git a/docker/Dockerfile.phySim.rhel9 b/docker/Dockerfile.phySim.rhel9 index a5a4863a64..ccfe8505a8 100644 --- a/docker/Dockerfile.phySim.rhel9 +++ b/docker/Dockerfile.phySim.rhel9 @@ -47,7 +47,7 @@ RUN dnf update -y && \ dnf install -y \ lksctp-tools \ tzdata \ - atlas \ + libgfortran \ hostname \ sudo \ procps-ng \ @@ -94,7 +94,25 @@ COPY --from=phy-sim-build \ /oai-ran/cmake_targets/ran_build/build/libldpc*.so \ /usr/local/lib/ -RUN ldconfig +RUN ldconfig && \ + echo "---- ldd on physim executables ----" && \ + ldd /opt/oai-physim/bin/dlsim \ + /opt/oai-physim/bin/nr_dlsim \ + /opt/oai-physim/bin/nr_prachsim \ + /opt/oai-physim/bin/nr_ulschsim \ + /opt/oai-physim/bin/polartest \ + /opt/oai-physim/bin/ulsim \ + /opt/oai-physim/bin/ldpctest \ + /opt/oai-physim/bin/nr_dlschsim \ + /opt/oai-physim/bin/nr_pbchsim \ + /opt/oai-physim/bin/nr_psbchsim \ + /opt/oai-physim/bin/nr_pucchsim \ + /opt/oai-physim/bin/nr_ulsim \ + /opt/oai-physim/bin/smallblocktest && \ + echo "---- ldd on shared libraries ----" && \ + ldd /usr/local/lib/libcoding.so \ + /usr/local/lib/libdfts.so \ + /usr/local/lib/libldpc*.so # Copy some executables WORKDIR /usr/bin/ diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 3a11b4e4e3..8a73bdd311 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -146,7 +146,7 @@ void init_nr_ue_vars(PHY_VARS_NR_UE *ue, int nb_connected_gNB = 1; ue->Mod_id = UE_id; - ue->if_inst = nr_ue_if_module_init(0); + ue->if_inst = nr_ue_if_module_init(UE_id); ue->dci_thres = 0; ue->target_Nid_cell = -1; @@ -416,7 +416,7 @@ static void RU_write(nr_rxtx_thread_data_t *rxtxD, bool sl_tx_action) radio_tx_burst_flag_t flags = TX_BURST_INVALID; - NR_UE_MAC_INST_t *mac = get_mac_inst(0); + NR_UE_MAC_INST_t *mac = get_mac_inst(UE->Mod_id); if (mac->phy_config_request_sent && openair0_cfg[0].duplex_mode == duplex_mode_TDD && !get_softmodem_params()->continuous_tx) { @@ -769,7 +769,7 @@ void *UE_thread(void *arg) initNotifiedFIFO_nothreadSafe(&freeBlocks); int timing_advance = UE->timing_advance; - NR_UE_MAC_INST_t *mac = get_mac_inst(0); + NR_UE_MAC_INST_t *mac = get_mac_inst(UE->Mod_id); bool syncRunning = false; const int nb_slot_frame = fp->slots_per_frame; @@ -998,27 +998,22 @@ void init_NR_UE(int nb_inst, char *uecap_file, char *reconfig_file, char *rbconf mac->if_module = nr_ue_if_module_init(i); AssertFatal(mac->if_module, "can not initialize IF module\n"); if (!get_softmodem_params()->sa || !get_softmodem_params()->sl_mode) { - init_nsa_message(rrc_inst, reconfig_file, rbconfig_file); - nr_rlc_activate_srb0(mac_inst->crnti, NULL, send_srb0_rrc); + init_nsa_message(&rrc_inst[i], reconfig_file, rbconfig_file); + nr_rlc_activate_srb0(mac_inst[i].crnti, NULL, send_srb0_rrc); } //TODO: Move this call to RRC start_sidelink((&rrc_inst[i])->ue_id); } } -void init_NR_UE_threads(int nb_inst) { - int inst; - - pthread_t threads[nb_inst]; - - for (inst=0; inst < nb_inst; inst++) { - PHY_VARS_NR_UE *UE = PHY_vars_UE_g[inst][0]; - - LOG_I(PHY,"Intializing UE Threads for instance %d (%p,%p)...\n",inst,PHY_vars_UE_g[inst],PHY_vars_UE_g[inst][0]); - threadCreate(&threads[inst], UE_thread, (void *)UE, "UEthread", -1, OAI_PRIORITY_RT_MAX); - if (!IS_SOFTMODEM_NOSTATS_BIT) { - pthread_t stat_pthread; - threadCreate(&stat_pthread, nrL1_UE_stats_thread, UE, "L1_UE_stats", -1, OAI_PRIORITY_RT_LOW); - } +void init_NR_UE_threads(PHY_VARS_NR_UE *UE) { + pthread_t thread; + char thread_name[16]; + sprintf(thread_name, "UEthread_%d", UE->Mod_id); + threadCreate(&thread, UE_thread, (void *)UE, thread_name, -1, OAI_PRIORITY_RT_MAX); + if (!IS_SOFTMODEM_NOSTATS_BIT) { + pthread_t stat_pthread; + sprintf(thread_name, "L1_UE_stats_%d", UE->Mod_id); + threadCreate(&stat_pthread, nrL1_UE_stats_thread, UE, thread_name, -1, OAI_PRIORITY_RT_LOW); } } diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index befc03a2da..262f0b1631 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -286,6 +286,7 @@ 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; UE->max_ldpc_iterations = nrUE_params.max_ldpc_iterations; + UE->ldpc_offload_enable = nrUE_params.ldpc_offload_flag; UE->UE_scan_carrier = nrUE_params.UE_scan_carrier; UE->UE_fo_compensation = nrUE_params.UE_fo_compensation; UE->if_freq = nrUE_params.if_freq; @@ -490,7 +491,11 @@ int main(int argc, char **argv) cpuf=get_cpu_freq_GHz(); itti_init(TASK_MAX, tasks_info); - init_opt() ; + init_opt(); + + if (nrUE_params.ldpc_offload_flag) + load_LDPClib("_t2", &ldpc_interface_offload); + load_LDPClib(NULL, &ldpc_interface); if (ouput_vcd) { @@ -502,11 +507,13 @@ int main(int argc, char **argv) // strdup to put the sring in the core file for post mortem identification LOG_I(HW, "Version: %s\n", strdup(PACKAGE_VERSION)); - PHY_vars_UE_g = malloc(sizeof(*PHY_vars_UE_g)); - PHY_vars_UE_g[0] = malloc(sizeof(*PHY_vars_UE_g[0]) * MAX_NUM_CCs); - for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - PHY_vars_UE_g[0][CC_id] = malloc(sizeof(*PHY_vars_UE_g[0][CC_id])); - memset(PHY_vars_UE_g[0][CC_id], 0, sizeof(*PHY_vars_UE_g[0][CC_id])); + PHY_vars_UE_g = malloc(sizeof(*PHY_vars_UE_g) * NB_UE_INST); + for (int inst = 0; inst < NB_UE_INST; inst++) { + PHY_vars_UE_g[inst] = malloc(sizeof(*PHY_vars_UE_g[inst]) * MAX_NUM_CCs); + for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + PHY_vars_UE_g[inst][CC_id] = malloc(sizeof(*PHY_vars_UE_g[inst][CC_id])); + memset(PHY_vars_UE_g[inst][CC_id], 0, sizeof(*PHY_vars_UE_g[inst][CC_id])); + } } int mode_offset = get_softmodem_params()->nsa ? NUMBER_OF_UE_MAX : 1; @@ -536,49 +543,51 @@ int main(int argc, char **argv) start_oai_nrue_threads(); if (!get_softmodem_params()->emulate_l1) { - PHY_VARS_NR_UE *UE[MAX_NUM_CCs]; - for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - UE[CC_id] = PHY_vars_UE_g[0][CC_id]; + for (int inst = 0; inst < NB_UE_INST; inst++) { + PHY_VARS_NR_UE *UE[MAX_NUM_CCs]; + for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + UE[CC_id] = PHY_vars_UE_g[inst][CC_id]; - set_options(CC_id, UE[CC_id]); - NR_UE_MAC_INST_t *mac = get_mac_inst(0); + set_options(CC_id, UE[CC_id]); + NR_UE_MAC_INST_t *mac = get_mac_inst(inst); - if (get_softmodem_params()->sa || get_softmodem_params()->sl_mode) { // set frame config to initial values from command line - // and assume that the SSB is centered on the grid - uint16_t nr_band = get_softmodem_params()->band; - mac->nr_band = nr_band; - mac->ssb_start_subcarrier = UE[CC_id]->frame_parms.ssb_start_subcarrier; - nr_init_frame_parms_ue_sa(&UE[CC_id]->frame_parms, - downlink_frequency[CC_id][0], - uplink_frequency_offset[CC_id][0], - get_softmodem_params()->numerology, - nr_band); - } else { - DevAssert(mac->if_module != NULL && mac->if_module->phy_config_request != NULL); - mac->if_module->phy_config_request(&mac->phy_config); - mac->phy_config_request_sent = true; - fapi_nr_config_request_t *nrUE_config = &UE[CC_id]->nrUE_config; + if (get_softmodem_params()->sa || get_softmodem_params()->sl_mode) { // set frame config to initial values from command line + // and assume that the SSB is centered on the grid + uint16_t nr_band = get_softmodem_params()->band; + mac->nr_band = nr_band; + mac->ssb_start_subcarrier = UE[CC_id]->frame_parms.ssb_start_subcarrier; + nr_init_frame_parms_ue_sa(&UE[CC_id]->frame_parms, + downlink_frequency[CC_id][0], + uplink_frequency_offset[CC_id][0], + get_softmodem_params()->numerology, + nr_band); + } else { + DevAssert(mac->if_module != NULL && mac->if_module->phy_config_request != NULL); + mac->if_module->phy_config_request(&mac->phy_config); + mac->phy_config_request_sent = true; + fapi_nr_config_request_t *nrUE_config = &UE[CC_id]->nrUE_config; - nr_init_frame_parms_ue(&UE[CC_id]->frame_parms, nrUE_config, mac->nr_band); - } + nr_init_frame_parms_ue(&UE[CC_id]->frame_parms, nrUE_config, mac->nr_band); + } - UE[CC_id]->sl_mode = get_softmodem_params()->sl_mode; - init_nr_ue_vars(UE[CC_id], 0, abstraction_flag); + UE[CC_id]->sl_mode = get_softmodem_params()->sl_mode; + init_nr_ue_vars(UE[CC_id], inst, abstraction_flag); - if (UE[CC_id]->sl_mode) { - AssertFatal(UE[CC_id]->sl_mode == 2, "Only Sidelink mode 2 supported. Mode 1 not yet supported\n"); - DevAssert(mac->if_module != NULL && mac->if_module->sl_phy_config_request != NULL); - nr_sl_phy_config_t *phycfg = &mac->SL_MAC_PARAMS->sl_phy_config; - phycfg->sl_config_req.sl_carrier_config.sl_num_rx_ant = get_nrUE_params()->nb_antennas_rx; - phycfg->sl_config_req.sl_carrier_config.sl_num_tx_ant = get_nrUE_params()->nb_antennas_tx; - mac->if_module->sl_phy_config_request(phycfg); - mac->phy_config_request_sent = true; - sl_nr_ue_phy_params_t *sl_phy = &UE[CC_id]->SL_UE_PHY_PARAMS; - nr_init_frame_parms_ue_sl(&sl_phy->sl_frame_params, - &sl_phy->sl_config, - get_softmodem_params()->threequarter_fs, - get_nrUE_params()->ofdm_offset_divisor); - sl_ue_phy_init(UE[CC_id]); + if (UE[CC_id]->sl_mode) { + AssertFatal(UE[CC_id]->sl_mode == 2, "Only Sidelink mode 2 supported. Mode 1 not yet supported\n"); + DevAssert(mac->if_module != NULL && mac->if_module->sl_phy_config_request != NULL); + nr_sl_phy_config_t *phycfg = &mac->SL_MAC_PARAMS->sl_phy_config; + phycfg->sl_config_req.sl_carrier_config.sl_num_rx_ant = get_nrUE_params()->nb_antennas_rx; + phycfg->sl_config_req.sl_carrier_config.sl_num_tx_ant = get_nrUE_params()->nb_antennas_tx; + mac->if_module->sl_phy_config_request(phycfg); + mac->phy_config_request_sent = true; + sl_nr_ue_phy_params_t *sl_phy = &UE[CC_id]->SL_UE_PHY_PARAMS; + nr_init_frame_parms_ue_sl(&sl_phy->sl_frame_params, + &sl_phy->sl_config, + get_softmodem_params()->threequarter_fs, + get_nrUE_params()->ofdm_offset_divisor); + sl_ue_phy_init(UE[CC_id]); + } } } @@ -593,7 +602,10 @@ int main(int argc, char **argv) load_softscope("nr",PHY_vars_UE_g[0][0]); } - init_NR_UE_threads(1); + for (int inst = 0; inst < NB_UE_INST; inst++) { + LOG_I(PHY,"Intializing UE Threads for instance %d ...\n", inst); + init_NR_UE_threads(PHY_vars_UE_g[inst][0]); + } printf("UE threads created by %ld\n", gettid()); } diff --git a/executables/nr-uesoftmodem.h b/executables/nr-uesoftmodem.h index 4c3a35b048..28de10154d 100644 --- a/executables/nr-uesoftmodem.h +++ b/executables/nr-uesoftmodem.h @@ -38,6 +38,7 @@ {"dlsch-parallel", CONFIG_HLP_DLSCH_PARA, 0, .u8ptr=NULL, .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, .iptr=&nrUE_params.max_ldpc_iterations, .defuintval=8, TYPE_UINT8, 0}, \ + {"ldpc-offload-enable", CONFIG_HLP_LDPC_OFFLOAD, PARAMFLAG_BOOL, .iptr=&(nrUE_params.ldpc_offload_flag), .defintval=0, TYPE_INT, 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=&uecap_file, .defstrval="./uecap_ports1.xml", TYPE_STRING, 0}, \ @@ -62,6 +63,7 @@ {"chest-time", CONFIG_HLP_CHESTTIME, 0, .iptr=&(nrUE_params.chest_time), .defintval=0, TYPE_INT, 0}, \ {"ue-timing-correction-disable", CONFIG_HLP_DISABLETIMECORR, PARAMFLAG_BOOL, .iptr=&(nrUE_params.no_timing_correction), .defintval=0, TYPE_INT, 0}, \ {"SLC", CONFIG_HLP_SLF, 0, .u64ptr=&(sidelink_frequency[0][0]), .defuintval=2600000000,TYPE_UINT64,0}, \ + {"num-ues", NULL, 0, .iptr=&(NB_UE_INST), .defuintval=1, TYPE_INT,0}, \ } // clang-format on @@ -81,6 +83,7 @@ typedef struct { int nb_antennas_tx; int N_RB_DL; int ssb_start_subcarrier; + int ldpc_offload_flag; } nrUE_params_t; extern uint64_t get_nrUE_optmask(void); extern uint64_t set_nrUE_optmask(uint64_t bitmask); @@ -91,7 +94,7 @@ extern nrUE_params_t *get_nrUE_params(void); extern int setup_nr_ue_buffers(PHY_VARS_NR_UE **phy_vars_ue, openair0_config_t *openair0_cfg); extern void fill_ue_band_info(void); extern void init_NR_UE(int, char *, char *, char *); -extern void init_NR_UE_threads(int); +extern void init_NR_UE_threads(PHY_VARS_NR_UE *ue); extern void reset_opp_meas(void); extern void print_opp_meas(void); void start_oai_nrue_threads(void); diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h index a98595fdd5..f76647d6af 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h @@ -27,6 +27,7 @@ #define NFAPI_UE_MAX_NUM_CB 8 #define NFAPI_MAX_NUM_UL_PDU 255 +#define NFAPI_MAX_NUM_CSI_RATEMATCH 4 /* typedef unsigned int uint32_t; @@ -437,6 +438,24 @@ typedef struct { fapi_nr_dl_config_dci_dl_pdu_rel15_t dci_config_rel15; } fapi_nr_dl_config_dci_pdu; +typedef struct { + uint8_t subcarrier_spacing; // subcarrierSpacing [3GPP TS 38.211, sec 4.2], Value:0->4 + uint8_t cyclic_prefix; // Cyclic prefix type [3GPP TS 38.211, sec 4.2], 0: Normal; 1: Extended + uint16_t start_rb; // PRB where this CSI resource starts related to common resource block #0 (CRB#0). Only multiples of 4 are allowed. [3GPP TS 38.331, sec 6.3.2 parameter CSIFrequencyOccupation], Value: 0 ->274 + uint16_t nr_of_rbs; // Number of PRBs across which this CSI resource spans. Only multiples of 4 are allowed. [3GPP TS 38.331, sec 6.3.2 parameter CSI-FrequencyOccupation], Value: 24 -> 276 + uint8_t csi_type; // CSI Type [3GPP TS 38.211, sec 7.4.1.5], Value: 0:TRS; 1:CSI-RS NZP; 2:CSI-RS ZP + uint8_t row; // Row entry into the CSI Resource location table. [3GPP TS 38.211, sec 7.4.1.5.3 and table 7.4.1.5.3-1], Value: 1-18 + uint16_t freq_domain; // Bitmap defining the frequencyDomainAllocation [3GPP TS 38.211, sec 7.4.1.5.3] [3GPP TS 38.331 CSIResourceMapping], Value: Up to the 12 LSBs, actual size is determined by the Row parameter + uint8_t symb_l0; // The time domain location l0 and firstOFDMSymbolInTimeDomain [3GPP TS 38.211, sec 7.4.1.5.3], Value: 0->13 + uint8_t symb_l1; // The time domain location l1 and firstOFDMSymbolInTimeDomain2 [3GPP TS 38.211, sec 7.4.1.5.3], Value: 2->12 + uint8_t cdm_type; // The cdm-Type field [3GPP TS 38.211, sec 7.4.1.5.3 and table 7.4.1.5.3-1], Value: 0: noCDM; 1: fd-CDM2; 2: cdm4-FD2-TD2; 3: cdm8-FD2-TD4 + uint8_t freq_density; // The density field, p and comb offset (for dot5). [3GPP TS 38.211, sec 7.4.1.5.3 and table 7.4.1.5.3-1], Value: 0: dot5 (even RB); 1: dot5 (odd RB); 2: one; 3: three + uint16_t scramb_id; // ScramblingID of the CSI-RS [3GPP TS 38.214, sec 5.2.2.3.1], Value: 0->1023 + uint8_t power_control_offset; // Ratio of PDSCH EPRE to NZP CSI-RSEPRE [3GPP TS 38.214, sec 5.2.2.3.1], Value: 0->23 representing -8 to 15 dB in 1dB steps; 255: L1 is configured with ProfileSSS + uint8_t power_control_offset_ss; // Ratio of NZP CSI-RS EPRE to SSB/PBCH block EPRE [3GPP TS 38.214, sec 5.2.2.3.1], Values: 0: -3dB; 1: 0dB; 2: 3dB; 3: 6dB; 255: L1 is configured with ProfileSSS + uint8_t measurement_bitmap; // bit 0 RSRP, bit 1 RI, bit 2 LI, bit 3 PMI, bit 4 CQI, bit 5 i1 +} fapi_nr_dl_config_csirs_pdu_rel15_t; + typedef enum{vrb_to_prb_mapping_non_interleaved = 0, vrb_to_prb_mapping_interleaved = 1} vrb_to_prb_mapping_t; typedef struct { @@ -481,7 +500,7 @@ typedef struct { // to be check the fields needed to L1 with NR_DL_UE_HARQ_t and NR_UE_DLSCH_t // PTRS [TS38.214, sec 5.1.6.3] /// PT-RS antenna ports [TS38.214, sec 5.1.6.3] [TS38.211, table 7.4.1.2.2-1] Bitmap occupying the 6 LSBs with: bit 0: antenna port 1000 bit 5: antenna port 1005 and for each bit 0: PTRS port not used 1: PTRS port used - uint8_t PTRSPortIndex ; + uint8_t PTRSPortIndex; /// PT-RS time density [TS38.214, table 5.1.6.3-1] 0: 1 1: 2 2: 4 uint8_t PTRSTimeDensity; /// PT-RS frequency density [TS38.214, table 5.1.6.3-2] 0: 2 1: 4 @@ -499,6 +518,8 @@ typedef struct { uint16_t pduBitmap; uint32_t k1_feedback; uint8_t ldpcBaseGraph; + uint8_t numCsiRsForRateMatching; + fapi_nr_dl_config_csirs_pdu_rel15_t csiRsForRateMatching[NFAPI_MAX_NUM_CSI_RATEMATCH]; } fapi_nr_dl_config_dlsch_pdu_rel15_t; typedef struct { @@ -506,26 +527,6 @@ typedef struct { fapi_nr_dl_config_dlsch_pdu_rel15_t dlsch_config_rel15; } fapi_nr_dl_config_dlsch_pdu; - -typedef struct { - uint8_t subcarrier_spacing; // subcarrierSpacing [3GPP TS 38.211, sec 4.2], Value:0->4 - uint8_t cyclic_prefix; // Cyclic prefix type [3GPP TS 38.211, sec 4.2], 0: Normal; 1: Extended - uint16_t start_rb; // PRB where this CSI resource starts related to common resource block #0 (CRB#0). Only multiples of 4 are allowed. [3GPP TS 38.331, sec 6.3.2 parameter CSIFrequencyOccupation], Value: 0 ->274 - uint16_t nr_of_rbs; // Number of PRBs across which this CSI resource spans. Only multiples of 4 are allowed. [3GPP TS 38.331, sec 6.3.2 parameter CSI-FrequencyOccupation], Value: 24 -> 276 - uint8_t csi_type; // CSI Type [3GPP TS 38.211, sec 7.4.1.5], Value: 0:TRS; 1:CSI-RS NZP; 2:CSI-RS ZP - uint8_t row; // Row entry into the CSI Resource location table. [3GPP TS 38.211, sec 7.4.1.5.3 and table 7.4.1.5.3-1], Value: 1-18 - uint16_t freq_domain; // Bitmap defining the frequencyDomainAllocation [3GPP TS 38.211, sec 7.4.1.5.3] [3GPP TS 38.331 CSIResourceMapping], Value: Up to the 12 LSBs, actual size is determined by the Row parameter - uint8_t symb_l0; // The time domain location l0 and firstOFDMSymbolInTimeDomain [3GPP TS 38.211, sec 7.4.1.5.3], Value: 0->13 - uint8_t symb_l1; // The time domain location l1 and firstOFDMSymbolInTimeDomain2 [3GPP TS 38.211, sec 7.4.1.5.3], Value: 2->12 - uint8_t cdm_type; // The cdm-Type field [3GPP TS 38.211, sec 7.4.1.5.3 and table 7.4.1.5.3-1], Value: 0: noCDM; 1: fd-CDM2; 2: cdm4-FD2-TD2; 3: cdm8-FD2-TD4 - uint8_t freq_density; // The density field, p and comb offset (for dot5). [3GPP TS 38.211, sec 7.4.1.5.3 and table 7.4.1.5.3-1], Value: 0: dot5 (even RB); 1: dot5 (odd RB); 2: one; 3: three - uint16_t scramb_id; // ScramblingID of the CSI-RS [3GPP TS 38.214, sec 5.2.2.3.1], Value: 0->1023 - uint8_t power_control_offset; // Ratio of PDSCH EPRE to NZP CSI-RSEPRE [3GPP TS 38.214, sec 5.2.2.3.1], Value: 0->23 representing -8 to 15 dB in 1dB steps; 255: L1 is configured with ProfileSSS - uint8_t power_control_offset_ss; // Ratio of NZP CSI-RS EPRE to SSB/PBCH block EPRE [3GPP TS 38.214, sec 5.2.2.3.1], Values: 0: -3dB; 1: 0dB; 2: 3dB; 3: 6dB; 255: L1 is configured with ProfileSSS - uint8_t measurement_bitmap; // bit 0 RSRP, bit 1 RI, bit 2 LI, bit 3 PMI, bit 4 CQI, bit 5 i1 -} fapi_nr_dl_config_csirs_pdu_rel15_t; - - typedef struct { uint16_t bwp_size; uint16_t bwp_start; diff --git a/openair1/PHY/CODING/TESTBENCH/ldpctest.c b/openair1/PHY/CODING/TESTBENCH/ldpctest.c index d676a90264..8a87682e4a 100644 --- a/openair1/PHY/CODING/TESTBENCH/ldpctest.c +++ b/openair1/PHY/CODING/TESTBENCH/ldpctest.c @@ -259,7 +259,7 @@ one_measurement_t test_ldpc(short max_iterations, printf("To: %d\n", (Kb + nrows - no_punctured_columns) * Zc - removed_bit); printf("number of undecoded bits: %d\n", (Kb + nrows - no_punctured_columns - 2) * Zc - removed_bit); - encoder_implemparams_t impp = {.Zc = Zc, .Kb = Kb, .E = block_length, .BG = BG, .Kr = block_length, .K = block_length}; + encoder_implemparams_t impp = {.Zc = Zc, .Kb = Kb, .BG = BG, .Kr = block_length, .K = block_length}; impp.gen_code = 2; if (ntrials==0) diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder_offload.c b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder_offload.c index 6cc500cfa7..77a1209709 100644 --- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder_offload.c +++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder_offload.c @@ -3,13 +3,8 @@ */ /*!\file nrLDPC_decoder_offload.c - * \brief Defines the LDPC decoder - * \author openairinterface - * \date 12-06-2021 - * \version 1.0 * \note: based on testbbdev test_bbdev_perf.c functions. Harq buffer offset added. * \mbuf and mempool allocated at the init step, LDPC parameters updated from OAI. - * \warning */ #include @@ -55,17 +50,12 @@ // this socket is the NUMA socket, so the hardware CPU id (numa is complex) #define GET_SOCKET(socket_id) (((socket_id) == SOCKET_ID_ANY) ? 0 : (socket_id)) - -#define MAX_QUEUES 16 - +#define MAX_QUEUES 32 #define OPS_CACHE_SIZE 256U #define OPS_POOL_SIZE_MIN 511U /* 0.5K per queue */ - #define SYNC_WAIT 0 #define SYNC_START 1 -#define INVALID_OPAQUE -1 #define TIME_OUT_POLL 1e8 -#define INVALID_QUEUE_ID -1 /* Increment for next code block in external HARQ memory */ #define HARQ_INCR 32768 /* Headroom for filler LLRs insertion in HARQ buffer */ @@ -102,7 +92,7 @@ struct active_device { static int nb_active_devs; /* Data buffers used by BBDEV ops */ -struct test_buffers { +struct data_buffers { struct rte_bbdev_op_data *inputs; struct rte_bbdev_op_data *hard_outputs; struct rte_bbdev_op_data *soft_outputs; @@ -121,7 +111,7 @@ struct test_op_params { uint16_t num_lcores; int vector_mask; rte_atomic16_t sync; - struct test_buffers q_bufs[RTE_MAX_NUMA_NODES][MAX_QUEUES]; + struct data_buffers q_bufs[RTE_MAX_NUMA_NODES][MAX_QUEUES]; }; /* Contains per lcore params */ @@ -129,16 +119,9 @@ struct thread_params { uint8_t dev_id; uint16_t queue_id; uint32_t lcore_id; - uint64_t start_time; - double ops_per_sec; - double mbps; - uint8_t iter_count; - double iter_average; - double bler; struct nrLDPCoffload_params *p_offloadParams; + uint8_t iter_count; uint8_t *p_out; - uint8_t r; - uint8_t harq_pid; uint8_t ulsch_id; rte_atomic16_t nb_dequeued; rte_atomic16_t processing_status; @@ -176,11 +159,11 @@ optimal_mempool_size(unsigned int val) return rte_align32pow2(val + 1) - 1; } -// DPDK BBDEV modified - sizes passed to the function, use of data_len and nb_segments, remove code related to Soft outputs, HARQ -// inputs, HARQ outputs +// based on DPDK BBDEV create_mempools static int create_mempools(struct active_device *ad, int socket_id, uint16_t num_ops, int out_buff_sz, int in_max_sz) { unsigned int ops_pool_size, mbuf_pool_size, data_room_size = 0; + num_ops = 1; uint8_t nb_segments = 1; ops_pool_size = optimal_mempool_size(RTE_MAX( /* Ops used plus 1 reference op */ @@ -196,23 +179,26 @@ static int create_mempools(struct active_device *ad, int socket_id, uint16_t num ops_pool_size, OPS_CACHE_SIZE, socket_id); if ((ad->bbdev_dec_op_pool == NULL) || (ad->bbdev_enc_op_pool == NULL)) - TEST_ASSERT_NOT_NULL(NULL, "ERROR Failed to create %u items ops pool for dev %u on socket %d.", - ops_pool_size, ad->dev_id, socket_id); + AssertFatal(1 == 0, "ERROR Failed to create %u items ops pool for dev %u on socket %d.", ops_pool_size, ad->dev_id, socket_id); /* Inputs */ mbuf_pool_size = optimal_mempool_size(ops_pool_size * nb_segments); data_room_size = RTE_MAX(in_max_sz + RTE_PKTMBUF_HEADROOM + FILLER_HEADROOM, (unsigned int)RTE_MBUF_DEFAULT_BUF_SIZE); ad->in_mbuf_pool = rte_pktmbuf_pool_create("in_mbuf_pool", mbuf_pool_size, 0, 0, data_room_size, socket_id); - TEST_ASSERT_NOT_NULL(ad->in_mbuf_pool, - "ERROR Failed to create %u items input pktmbuf pool for dev %u on socket %d.", - mbuf_pool_size, ad->dev_id, socket_id); + AssertFatal(ad->in_mbuf_pool != NULL, + "ERROR Failed to create %u items input pktmbuf pool for dev %u on socket %d.", + mbuf_pool_size, + ad->dev_id, + socket_id); /* Hard outputs */ data_room_size = RTE_MAX(out_buff_sz + RTE_PKTMBUF_HEADROOM + FILLER_HEADROOM, (unsigned int)RTE_MBUF_DEFAULT_BUF_SIZE); ad->hard_out_mbuf_pool = rte_pktmbuf_pool_create("hard_out_mbuf_pool", mbuf_pool_size, 0, 0, data_room_size, socket_id); - TEST_ASSERT_NOT_NULL(ad->hard_out_mbuf_pool, - "ERROR Failed to create %u items hard output pktmbuf pool for dev %u on socket %d.", - mbuf_pool_size, ad->dev_id, socket_id); + AssertFatal(ad->hard_out_mbuf_pool != NULL, + "ERROR Failed to create %u items hard output pktmbuf pool for dev %u on socket %d.", + mbuf_pool_size, + ad->dev_id, + socket_id); return 0; } @@ -289,8 +275,7 @@ const char *ldpcdec_flag_bitmask[] = { "RTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_FILLERS", }; -// DPDK BBDEV modified - in DPDK this function is named add_bbdev_dev, removed code for RTE_BASEBAND_ACC100, IMO we can also remove -// RTE_LIBRTE_PMD_BBDEV_FPGA_LTE_FEC and RTE_LIBRTE_PMD_BBDEV_FPGA_5GNR_FEC - to be checked +// based on DPDK BBDEV add_bbdev_dev static int add_dev(uint8_t dev_id, struct rte_bbdev_info *info) { int ret; @@ -329,7 +314,7 @@ static int add_dev(uint8_t dev_id, struct rte_bbdev_info *info) ret = rte_bbdev_setup_queues(dev_id, nb_queues, info->socket_id); if (ret < 0) { printf("rte_bbdev_setup_queues(%u, %u, %d) ret %i\n", dev_id, nb_queues, info->socket_id, ret); - return TEST_FAILED; + return -1; } /* setup device queues */ @@ -346,13 +331,12 @@ static int add_dev(uint8_t dev_id, struct rte_bbdev_info *info) if (ret == 0) { printf("Found LDCP encoding queue (id=%d) at prio%u on dev%u\n", queue_id, qconf.priority, dev_id); qconf.priority++; - //ret = rte_bbdev_queue_configure(ad->dev_id, queue_id, &qconf); ad->enc_queue = queue_id; ad->queue_ids[queue_id] = queue_id; break; } } - TEST_ASSERT(queue_id != nb_queues, "ERROR Failed to configure encoding queues on dev %u", dev_id); + AssertFatal(queue_id != nb_queues, "ERROR Failed to configure encoding queues on dev %u", dev_id); // Search a queue linked to HW capability ldpc encoding qconf.op_type = RTE_BBDEV_OP_LDPC_DEC; @@ -361,39 +345,37 @@ static int add_dev(uint8_t dev_id, struct rte_bbdev_info *info) if (ret == 0) { printf("Found LDCP decoding queue (id=%d) at prio%u on dev%u\n", queue_id, qconf.priority, dev_id); qconf.priority++; - //ret = rte_bbdev_queue_configure(ad->dev_id, queue_id, &qconf); ad->dec_queue = queue_id; ad->queue_ids[queue_id] = queue_id; break; } } - TEST_ASSERT(queue_id != nb_queues, "ERROR Failed to configure encoding queues on dev %u", dev_id); + AssertFatal(queue_id != nb_queues, "ERROR Failed to configure encoding queues on dev %u", dev_id); ad->nb_queues = 2; - return TEST_SUCCESS; + return 0; } -// DPDK BBDEV modified - nb_segments used, we are not using struct op_data_entries *ref_entries, but struct rte_mbuf *m_head, -// rte_pktmbuf_reset(m_head) added? if ((op_type == DATA_INPUT) || (op_type == DATA_HARQ_INPUT)) -> no code in else? -static int init_op_data_objs(struct rte_bbdev_op_data *bufs, - uint8_t *input, - uint32_t data_len, - struct rte_mbuf *m_head, - struct rte_mempool *mbuf_pool, - const uint16_t n, - enum op_data_type op_type, - uint16_t min_alignment) +// based on DPDK BBDEV init_op_data_objs +static int init_op_data_objs_dec(struct rte_bbdev_op_data *bufs, + uint8_t *input, + t_nrLDPCoffload_params *offloadParams, + struct rte_mempool *mbuf_pool, + const uint16_t n, + enum op_data_type op_type, + uint16_t min_alignment) { - int ret; - unsigned int i, j; bool large_input = false; - uint8_t nb_segments = 1; - for (i = 0; i < n; ++i) { + for (int i = 0; i < n; ++i) { + uint32_t data_len = offloadParams->perCB[i].E_cb; char *data; + struct rte_mbuf *m_head = rte_pktmbuf_alloc(mbuf_pool); + AssertFatal(m_head != NULL, + "Not enough mbufs in %d data type mbuf pool (needed %u, available %u)", + op_type, + n, + mbuf_pool->size); + if (data_len > RTE_BBDEV_LDPC_E_MAX_MBUF) { - /* - * Special case when DPDK mbuf cannot handle - * the required input size - */ printf("Warning: Larger input size than DPDK mbuf %u\n", data_len); large_input = true; } @@ -405,68 +387,80 @@ static int init_op_data_objs(struct rte_bbdev_op_data *bufs, if ((op_type == DATA_INPUT) && large_input) { /* Allocate a fake overused mbuf */ data = rte_malloc(NULL, data_len, 0); - TEST_ASSERT_NOT_NULL(data, "rte malloc failed with %u bytes", data_len); - memcpy(data, input, data_len); + AssertFatal(data != NULL, "rte malloc failed with %u bytes", data_len); + memcpy(data, &input[i * LDPC_MAX_CB_SIZE], data_len); m_head->buf_addr = data; m_head->buf_iova = rte_malloc_virt2iova(data); m_head->data_off = 0; m_head->data_len = data_len; } else { - // rte_pktmbuf_reset added rte_pktmbuf_reset(m_head); data = rte_pktmbuf_append(m_head, data_len); - - TEST_ASSERT_NOT_NULL(data, "Couldn't append %u bytes to mbuf from %d data type mbuf pool", data_len, op_type); - - TEST_ASSERT(data == RTE_PTR_ALIGN(data, min_alignment), + AssertFatal(data != NULL, "Couldn't append %u bytes to mbuf from %d data type mbuf pool", data_len, op_type); + AssertFatal(data == RTE_PTR_ALIGN(data, min_alignment), "Data addr in mbuf (%p) is not aligned to device min alignment (%u)", data, min_alignment); - rte_memcpy(data, input, data_len); + rte_memcpy(data, &input[i * LDPC_MAX_CB_SIZE], data_len); } - bufs[i].length += data_len; - - for (j = 1; j < nb_segments; ++j) { - struct rte_mbuf *m_tail = rte_pktmbuf_alloc(mbuf_pool); - TEST_ASSERT_NOT_NULL(m_tail, - "Not enough mbufs in %d data type mbuf pool (needed %d, available %u)", - op_type, - n * nb_segments, - mbuf_pool->size); - - data = rte_pktmbuf_append(m_tail, data_len); - TEST_ASSERT_NOT_NULL(data, "Couldn't append %u bytes to mbuf from %d data type mbuf pool", data_len, op_type); - - TEST_ASSERT(data == RTE_PTR_ALIGN(data, min_alignment), - "Data addr in mbuf (%p) is not aligned to device min alignment (%u)", - data, - min_alignment); - rte_memcpy(data, input, data_len); - bufs[i].length += data_len; - - ret = rte_pktmbuf_chain(m_head, m_tail); - TEST_ASSERT_SUCCESS(ret, "Couldn't chain mbufs from %d data type mbuf pool", op_type); - } - } else { - /* allocate chained-mbuf for output buffer */ - /*for (j = 1; j < nb_segments; ++j) { - struct rte_mbuf *m_tail = - rte_pktmbuf_alloc(mbuf_pool); - TEST_ASSERT_NOT_NULL(m_tail, - "Not enough mbufs in %d data type mbuf pool (needed %u, available %u)", - op_type, - n * nb_segments, - mbuf_pool->size); - - ret = rte_pktmbuf_chain(m_head, m_tail); - TEST_ASSERT_SUCCESS(ret, - "Couldn't chain mbufs from %d data type mbuf pool", - op_type); - }*/ } } + return 0; +} +// based on DPDK BBDEV init_op_data_objs +static int init_op_data_objs_enc(struct rte_bbdev_op_data *bufs, + uint8_t **input_enc, + t_nrLDPCoffload_params *offloadParams, + struct rte_mbuf *m_head, + struct rte_mempool *mbuf_pool, + const uint16_t n, + enum op_data_type op_type, + uint16_t min_alignment) +{ + bool large_input = false; + for (int i = 0; i < n; ++i) { + uint32_t data_len = offloadParams->Kr; + char *data; + struct rte_mbuf *m_head = rte_pktmbuf_alloc(mbuf_pool); + AssertFatal(m_head != NULL, + "Not enough mbufs in %d data type mbuf pool (needed %u, available %u)", + op_type, + n, + mbuf_pool->size); + + if (data_len > RTE_BBDEV_LDPC_E_MAX_MBUF) { + printf("Warning: Larger input size than DPDK mbuf %u\n", data_len); + large_input = true; + } + bufs[i].data = m_head; + bufs[i].offset = 0; + bufs[i].length = 0; + + if ((op_type == DATA_INPUT) || (op_type == DATA_HARQ_INPUT)) { + if ((op_type == DATA_INPUT) && large_input) { + /* Allocate a fake overused mbuf */ + data = rte_malloc(NULL, data_len, 0); + AssertFatal(data != NULL, "rte malloc failed with %u bytes", data_len); + memcpy(data, &input_enc[0], data_len); + m_head->buf_addr = data; + m_head->buf_iova = rte_malloc_virt2iova(data); + m_head->data_off = 0; + m_head->data_len = data_len; + } else { + rte_pktmbuf_reset(m_head); + data = rte_pktmbuf_append(m_head, data_len); + AssertFatal(data != NULL, "Couldn't append %u bytes to mbuf from %d data type mbuf pool", data_len, op_type); + AssertFatal(data == RTE_PTR_ALIGN(data, min_alignment), + "Data addr in mbuf (%p) is not aligned to device min alignment (%u)", + data, + min_alignment); + rte_memcpy(data, input_enc[i], data_len); + } + bufs[i].length += data_len; + } + } return 0; } @@ -486,7 +480,7 @@ static int allocate_buffers_on_socket(struct rte_bbdev_op_data **buffers, const } } - return (*buffers == NULL) ? TEST_FAILED : TEST_SUCCESS; + return (*buffers == NULL) ? -1 : 0; } // DPDK BBDEV copy @@ -501,7 +495,7 @@ free_buffers(struct active_device *ad, struct test_op_params *op_params) rte_mempool_free(ad->harq_in_mbuf_pool); rte_mempool_free(ad->harq_out_mbuf_pool); - for (int i = 0; i < rte_lcore_count(); ++i) { + for (int i = 2; i < rte_lcore_count(); ++i) { for (int j = 0; j < RTE_MAX_NUMA_NODES; ++j) { rte_free(op_params->q_bufs[j][i].inputs); rte_free(op_params->q_bufs[j][i].hard_outputs); @@ -512,27 +506,22 @@ free_buffers(struct active_device *ad, struct test_op_params *op_params) } } -// OAI / DPDK BBDEV modified - in DPDK named copy_reference_dec_op, here we are passing t_nrLDPCoffload_params *p_offloadParams to -// the function, check what is value of n, commented code for code block mode -static void -set_ldpc_dec_op(struct rte_bbdev_dec_op **ops, unsigned int n, - unsigned int start_idx, - struct test_buffers *bufs, - struct rte_bbdev_dec_op *ref_op, - uint8_t r, - uint8_t harq_pid, - uint8_t ulsch_id, - t_nrLDPCoffload_params *p_offloadParams) +// based on DPDK BBDEV copy_reference_ldpc_dec_op +static void set_ldpc_dec_op(struct rte_bbdev_dec_op **ops, + unsigned int start_idx, + struct data_buffers *bufs, + uint8_t ulsch_id, + t_nrLDPCoffload_params *p_offloadParams) { unsigned int i; - for (i = 0; i < n; ++i) { - ops[i]->ldpc_dec.cb_params.e = p_offloadParams->E; + for (i = 0; i < p_offloadParams->C; ++i) { + ops[i]->ldpc_dec.cb_params.e = p_offloadParams->perCB[i].E_cb; ops[i]->ldpc_dec.basegraph = p_offloadParams->BG; ops[i]->ldpc_dec.z_c = p_offloadParams->Z; ops[i]->ldpc_dec.q_m = p_offloadParams->Qm; ops[i]->ldpc_dec.n_filler = p_offloadParams->F; ops[i]->ldpc_dec.n_cb = p_offloadParams->n_cb; - ops[i]->ldpc_dec.iter_max = 20; + ops[i]->ldpc_dec.iter_max = p_offloadParams->numMaxIter; ops[i]->ldpc_dec.rv_index = p_offloadParams->rv; ops[i]->ldpc_dec.op_flags = RTE_BBDEV_LDPC_ITERATION_STOP_ENABLE | RTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_IN_ENABLE | @@ -541,10 +530,13 @@ set_ldpc_dec_op(struct rte_bbdev_dec_op **ops, unsigned int n, if (p_offloadParams->setCombIn) { ops[i]->ldpc_dec.op_flags |= RTE_BBDEV_LDPC_HQ_COMBINE_IN_ENABLE; } - LOG_D(PHY,"ULSCH %02d HARQPID %02d R %02d COMBIN %d RV %d NCB %05d \n", ulsch_id, harq_pid, r, p_offloadParams->setCombIn, p_offloadParams->rv, p_offloadParams->n_cb); - ops[i]->ldpc_dec.code_block_mode = 1; // ldpc_dec->code_block_mode; - ops[i]->ldpc_dec.harq_combined_input.offset = ulsch_id * 64 * LDPC_MAX_CB_SIZE + r * LDPC_MAX_CB_SIZE; - ops[i]->ldpc_dec.harq_combined_output.offset = ulsch_id * 64 * LDPC_MAX_CB_SIZE + r * LDPC_MAX_CB_SIZE; + if (p_offloadParams->C > 1) { + ops[i]->ldpc_dec.op_flags |= RTE_BBDEV_LDPC_CRC_TYPE_24B_DROP; + ops[i]->ldpc_dec.op_flags |= RTE_BBDEV_LDPC_CRC_TYPE_24B_CHECK; + } + ops[i]->ldpc_dec.code_block_mode = 1; + ops[i]->ldpc_dec.harq_combined_input.offset = ulsch_id * NR_LDPC_MAX_NUM_CB * LDPC_MAX_CB_SIZE + i * LDPC_MAX_CB_SIZE; + ops[i]->ldpc_dec.harq_combined_output.offset = ulsch_id * NR_LDPC_MAX_NUM_CB * LDPC_MAX_CB_SIZE + i * LDPC_MAX_CB_SIZE; if (bufs->hard_outputs != NULL) ops[i]->ldpc_dec.hard_output = bufs->hard_outputs[start_idx + i]; if (bufs->inputs != NULL) @@ -558,17 +550,15 @@ set_ldpc_dec_op(struct rte_bbdev_dec_op **ops, unsigned int n, } } +// based on DPDK BBDEV copy_reference_ldpc_enc_op static void set_ldpc_enc_op(struct rte_bbdev_enc_op **ops, - unsigned int n, unsigned int start_idx, struct rte_bbdev_op_data *inputs, struct rte_bbdev_op_data *outputs, - struct rte_bbdev_enc_op *ref_op, t_nrLDPCoffload_params *p_offloadParams) { - // struct rte_bbdev_op_ldpc_enc *ldpc_enc = &ref_op->ldpc_enc; - for (int i = 0; i < n; ++i) { - ops[i]->ldpc_enc.cb_params.e = p_offloadParams->E; + for (int i = 0; i < p_offloadParams->C; ++i) { + ops[i]->ldpc_enc.cb_params.e = p_offloadParams->perCB[i].E_cb; ops[i]->ldpc_enc.basegraph = p_offloadParams->BG; ops[i]->ldpc_enc.z_c = p_offloadParams->Z; ops[i]->ldpc_enc.q_m = p_offloadParams->Qm; @@ -582,47 +572,52 @@ static void set_ldpc_enc_op(struct rte_bbdev_enc_op **ops, } } -// DPDK BBDEV modified - in DPDK called validate_dec_op, int8_t* p_out added, remove code related to op_data_entries, turbo_dec -// replaced by ldpc_dec, removed coderelated to soft_output, memcpy(p_out, data+m->data_off, data_len) -static int retrieve_ldpc_dec_op(struct rte_bbdev_dec_op **ops, - const uint16_t n, - struct rte_bbdev_dec_op *ref_op, - const int vector_mask, - uint8_t *p_out) +static int retrieve_ldpc_dec_op(struct rte_bbdev_dec_op **ops, const uint16_t n, const int vector_mask, uint8_t *p_out) { struct rte_bbdev_op_data *hard_output; + uint16_t data_len = 0; struct rte_mbuf *m; unsigned int i; char *data; + int offset = 0; for (i = 0; i < n; ++i) { hard_output = &ops[i]->ldpc_dec.hard_output; m = hard_output->data; - uint16_t data_len = rte_pktmbuf_data_len(m) - hard_output->offset; + data_len = rte_pktmbuf_data_len(m) - hard_output->offset; data = m->buf_addr; - memcpy(p_out, data + m->data_off, data_len); + memcpy(&p_out[offset], data + m->data_off, data_len); + offset += data_len; + rte_pktmbuf_free(ops[i]->ldpc_dec.hard_output.data); + rte_pktmbuf_free(ops[i]->ldpc_dec.input.data); } return 0; } -static int retrieve_ldpc_enc_op(struct rte_bbdev_enc_op **ops, const uint16_t n, struct rte_bbdev_enc_op *ref_op, uint8_t *p_out) +static int retrieve_ldpc_enc_op(struct rte_bbdev_enc_op **ops, const uint16_t n, uint8_t *p_out, nrLDPC_params_per_cb_t *perCB) { struct rte_bbdev_op_data *output; struct rte_mbuf *m; unsigned int i; char *data; + uint8_t *out; + int offset = 0; for (i = 0; i < n; ++i) { output = &ops[i]->ldpc_enc.output; m = output->data; - uint16_t data_len = min((LDPC_MAX_CB_SIZE) / 8, rte_pktmbuf_data_len(m)); // fix me + uint16_t data_len = rte_pktmbuf_data_len(m) - output->offset; + out = &p_out[offset]; data = m->buf_addr; for (int byte = 0; byte < data_len; byte++) for (int bit = 0; bit < 8; bit++) - p_out[byte * 8 + bit] = (data[m->data_off + byte] >> (7 - bit)) & 1; + out[byte * 8 + bit] = (data[m->data_off + byte] >> (7 - bit)) & 1; + offset += perCB[i].E_cb; + rte_pktmbuf_free(ops[i]->ldpc_enc.output.data); + rte_pktmbuf_free(ops[i]->ldpc_enc.input.data); } return 0; } -// DPDK BBDEV copy +// based on DPDK BBDEV init_test_op_params static int init_test_op_params(struct test_op_params *op_params, enum rte_bbdev_op_type op_type, struct rte_mempool *ops_mp, @@ -632,14 +627,14 @@ static int init_test_op_params(struct test_op_params *op_params, { int ret = 0; if (op_type == RTE_BBDEV_OP_LDPC_DEC) { - ret = rte_bbdev_dec_op_alloc_bulk(ops_mp, &op_params->ref_dec_op, 1); + ret = rte_bbdev_dec_op_alloc_bulk(ops_mp, &op_params->ref_dec_op, num_to_process); op_params->mp_dec = ops_mp; } else { - ret = rte_bbdev_enc_op_alloc_bulk(ops_mp, &op_params->ref_enc_op, 1); + ret = rte_bbdev_enc_op_alloc_bulk(ops_mp, &op_params->ref_enc_op, num_to_process); op_params->mp_enc = ops_mp; } - TEST_ASSERT_SUCCESS(ret, "rte_bbdev_op_alloc_bulk() failed"); + AssertFatal(ret == 0, "rte_bbdev_op_alloc_bulk() failed"); op_params->burst_sz = burst_sz; op_params->num_to_process = num_to_process; @@ -647,201 +642,143 @@ static int init_test_op_params(struct test_op_params *op_params, return 0; } -// DPDK BBDEV modified - in DPDK called throughput_pmd_lcore_ldpc_dec, code related to extDdr removed +// based on DPDK BBDEV throughput_pmd_lcore_ldpc_dec static int pmd_lcore_ldpc_dec(void *arg) { struct thread_params *tp = arg; uint16_t enq, deq; + int time_out = 0; const uint16_t queue_id = tp->queue_id; - const uint16_t burst_sz = tp->op_params->burst_sz; - const uint16_t num_ops = tp->op_params->num_to_process; - struct rte_bbdev_dec_op *ops_enq[num_ops]; - struct rte_bbdev_dec_op *ops_deq[num_ops]; - struct rte_bbdev_dec_op *ref_op = tp->op_params->ref_dec_op; - uint8_t r = tp->r; - uint8_t harq_pid = tp->harq_pid; + const uint16_t num_segments = tp->p_offloadParams->C; + struct rte_bbdev_dec_op *ops_enq[num_segments]; + struct rte_bbdev_dec_op *ops_deq[num_segments]; uint8_t ulsch_id = tp->ulsch_id; - struct test_buffers *bufs = NULL; - int i, j, ret; + struct data_buffers *bufs = NULL; + int i, ret; struct rte_bbdev_info info; uint16_t num_to_enq; uint8_t *p_out = tp->p_out; t_nrLDPCoffload_params *p_offloadParams = tp->p_offloadParams; - TEST_ASSERT_SUCCESS((burst_sz > MAX_BURST), "BURST_SIZE should be <= %u", MAX_BURST); + AssertFatal((num_segments < MAX_BURST), "BURST_SIZE should be <= %u", MAX_BURST); rte_bbdev_info_get(tp->dev_id, &info); - bufs = &tp->op_params->q_bufs[GET_SOCKET(info.socket_id)][queue_id]; while (rte_atomic16_read(&tp->op_params->sync) == SYNC_WAIT) rte_pause(); - ret = rte_mempool_get_bulk(tp->op_params->mp_dec, (void **)ops_enq, num_ops); - // looks like a bbdev internal error for the free operation, workaround here - ops_enq[0]->mempool = tp->op_params->mp_dec; - // ret = rte_bbdev_dec_op_alloc_bulk(tp->op_params->mp, ops_enq, num_ops); - TEST_ASSERT_SUCCESS(ret, "Allocation failed for %d ops", num_ops); - set_ldpc_dec_op(ops_enq, - num_ops, - 0, - bufs, - ref_op, - r, - harq_pid, - ulsch_id, - p_offloadParams); + ret = rte_bbdev_dec_op_alloc_bulk(tp->op_params->mp_dec, ops_enq, num_segments); + AssertFatal(ret == 0, "Allocation failed for %d ops", num_segments); + set_ldpc_dec_op(ops_enq, 0, bufs, ulsch_id, p_offloadParams); - /* Set counter to validate the ordering */ - for (j = 0; j < num_ops; ++j) - ops_enq[j]->opaque_data = (void *)(uintptr_t)j; - - for (enq = 0, deq = 0; enq < num_ops;) { - num_to_enq = burst_sz; - if (unlikely(num_ops - enq < num_to_enq)) - num_to_enq = num_ops - enq; + for (enq = 0, deq = 0; enq < num_segments;) { + num_to_enq = num_segments; + if (unlikely(num_segments - enq < num_to_enq)) + num_to_enq = num_segments - enq; enq += rte_bbdev_enqueue_ldpc_dec_ops(tp->dev_id, queue_id, &ops_enq[enq], num_to_enq); deq += rte_bbdev_dequeue_ldpc_dec_ops(tp->dev_id, queue_id, &ops_deq[deq], enq - deq); } /* dequeue the remaining */ - int time_out = 0; while (deq < enq) { deq += rte_bbdev_dequeue_ldpc_dec_ops(tp->dev_id, queue_id, &ops_deq[deq], enq - deq); time_out++; DevAssert(time_out <= TIME_OUT_POLL); } - - // This if statement is not in DPDK if (deq == enq) { tp->iter_count = 0; /* get the max of iter_count for all dequeued ops */ - for (i = 0; i < num_ops; ++i) { + for (i = 0; i < num_segments; ++i) { + uint8_t *status = tp->p_offloadParams->perCB[i].p_status_cb; tp->iter_count = RTE_MAX(ops_enq[i]->ldpc_dec.iter_count, tp->iter_count); + *status = ops_enq[i]->status; } - ret = retrieve_ldpc_dec_op(ops_deq, num_ops, ref_op, tp->op_params->vector_mask, p_out); - TEST_ASSERT_SUCCESS(ret, "Validation failed!"); + ret = retrieve_ldpc_dec_op(ops_deq, num_segments, tp->op_params->vector_mask, p_out); + AssertFatal(ret == 0, "LDPC offload decoder failed!"); } - if (num_ops > 0) - rte_mempool_put_bulk(ops_enq[0]->mempool, (void **)ops_enq, num_ops); - - // Return the worst decoding number of iterations for all segments + rte_bbdev_dec_op_free_bulk(ops_enq, num_segments); + // Return the max number of iterations accross all segments return tp->iter_count; } -// DPDK BBDEV copy - in DPDK called throughput_pmd_lcore_ldpc_enc +// based on DPDK BBDEV throughput_pmd_lcore_ldpc_enc static int pmd_lcore_ldpc_enc(void *arg) { struct thread_params *tp = arg; uint16_t enq, deq; + int time_out = 0; const uint16_t queue_id = tp->queue_id; - const uint16_t burst_sz = tp->op_params->burst_sz; - const uint16_t num_ops = tp->op_params->num_to_process; - struct rte_bbdev_enc_op *ops_enq[num_ops]; - struct rte_bbdev_enc_op *ops_deq[num_ops]; - struct rte_bbdev_enc_op *ref_op = tp->op_params->ref_enc_op; - int j, ret; + const uint16_t num_segments = tp->p_offloadParams->C; + tp->op_params->num_to_process = num_segments; + struct rte_bbdev_enc_op *ops_enq[num_segments]; + struct rte_bbdev_enc_op *ops_deq[num_segments]; + struct rte_bbdev_info info; + int ret; + struct data_buffers *bufs = NULL; uint16_t num_to_enq; uint8_t *p_out = tp->p_out; t_nrLDPCoffload_params *p_offloadParams = tp->p_offloadParams; - TEST_ASSERT_SUCCESS((burst_sz > MAX_BURST), "BURST_SIZE should be <= %u", MAX_BURST); + AssertFatal((num_segments < MAX_BURST), "BURST_SIZE should be <= %u", MAX_BURST); - struct rte_bbdev_info info; rte_bbdev_info_get(tp->dev_id, &info); - - TEST_ASSERT_SUCCESS((num_ops > info.drv.queue_size_lim), "NUM_OPS cannot exceed %u for this device", info.drv.queue_size_lim); - - struct test_buffers *bufs = &tp->op_params->q_bufs[GET_SOCKET(info.socket_id)][queue_id]; - + bufs = &tp->op_params->q_bufs[GET_SOCKET(info.socket_id)][queue_id]; while (rte_atomic16_read(&tp->op_params->sync) == SYNC_WAIT) rte_pause(); + ret = rte_bbdev_enc_op_alloc_bulk(tp->op_params->mp_enc, ops_enq, num_segments); + AssertFatal(ret == 0, "Allocation failed for %d ops", num_segments); - ret = rte_mempool_get_bulk(tp->op_params->mp_enc, (void **)ops_enq, num_ops); - // ret = rte_bbdev_enc_op_alloc_bulk(tp->op_params->mp, ops_enq, num_ops); - TEST_ASSERT_SUCCESS(ret, "Allocation failed for %d ops", num_ops); - ops_enq[0]->mempool = tp->op_params->mp_enc; - - set_ldpc_enc_op(ops_enq, num_ops, 0, bufs->inputs, bufs->hard_outputs, ref_op, p_offloadParams); - - /* Set counter to validate the ordering */ - for (j = 0; j < num_ops; ++j) - ops_enq[j]->opaque_data = (void *)(uintptr_t)j; - - for (j = 0; j < num_ops; ++j) - mbuf_reset(ops_enq[j]->ldpc_enc.output.data); - - for (enq = 0, deq = 0; enq < num_ops;) { - num_to_enq = burst_sz; - if (unlikely(num_ops - enq < num_to_enq)) - num_to_enq = num_ops - enq; - + set_ldpc_enc_op(ops_enq, 0, bufs->inputs, bufs->hard_outputs, p_offloadParams); + for (enq = 0, deq = 0; enq < num_segments;) { + num_to_enq = num_segments; + if (unlikely(num_segments - enq < num_to_enq)) + num_to_enq = num_segments - enq; enq += rte_bbdev_enqueue_ldpc_enc_ops(tp->dev_id, queue_id, &ops_enq[enq], num_to_enq); deq += rte_bbdev_dequeue_ldpc_enc_ops(tp->dev_id, queue_id, &ops_deq[deq], enq - deq); } /* dequeue the remaining */ - int time_out = 0; while (deq < enq) { deq += rte_bbdev_dequeue_ldpc_enc_ops(tp->dev_id, queue_id, &ops_deq[deq], enq - deq); time_out++; DevAssert(time_out <= TIME_OUT_POLL); } - ret = retrieve_ldpc_enc_op(ops_deq, num_ops, ref_op, p_out); - TEST_ASSERT_SUCCESS(ret, "Validation failed!"); - // rte_bbdev_enc_op_free_bulk(ops_enq, num_ops); - - if (num_ops > 0) - rte_mempool_put_bulk(ops_enq[0]->mempool, (void **)ops_enq, num_ops); - + ret = retrieve_ldpc_enc_op(ops_deq, num_segments, p_out, tp->p_offloadParams->perCB); + AssertFatal(ret == 0, "Failed to retrieve LDPC encoding op!"); + rte_bbdev_enc_op_free_bulk(ops_enq, num_segments); return ret; } - -/* - * Test function that determines how long an enqueue + dequeue of a burst - * takes on available lcores. - */ -// OAI / DPDK BBDEV modified - in DPDK called throughput_test, here we pass more parameters to the function (t_nrLDPCoffload_params -// *p_offloadParams, uint8_t r, ...), many commented lines Removed code which specified which function to use based on the op_type, -// now we are using only pmd_lcore_ldpc_dec for RTE_BBDEV_OP_LDPC_DEC op type. Encoder is RTE_BBDEV_OP_LDPC_ENC op type, -// pmd_lcore_ldpc_enc to be implemented. +// based on DPDK BBDEV throughput_pmd_lcore_dec int start_pmd_dec(struct active_device *ad, struct test_op_params *op_params, t_nrLDPCoffload_params *p_offloadParams, - uint8_t r, - uint8_t harq_pid, uint8_t ulsch_id, uint8_t *p_out) { int ret; unsigned int lcore_id, used_cores = 0; - // struct rte_bbdev_info info; uint16_t num_lcores; - // rte_bbdev_info_get(ad->dev_id, &info); /* Set number of lcores */ num_lcores = (ad->nb_queues < (op_params->num_lcores)) ? ad->nb_queues : op_params->num_lcores; /* Allocate memory for thread parameters structure */ struct thread_params *t_params = rte_zmalloc(NULL, num_lcores * sizeof(struct thread_params), RTE_CACHE_LINE_SIZE); - TEST_ASSERT_NOT_NULL(t_params, - "Failed to alloc %zuB for t_params", - RTE_ALIGN(sizeof(struct thread_params) * num_lcores, RTE_CACHE_LINE_SIZE)); + AssertFatal(t_params != NULL, + "Failed to alloc %zuB for t_params", + RTE_ALIGN(sizeof(struct thread_params) * num_lcores, RTE_CACHE_LINE_SIZE)); rte_atomic16_set(&op_params->sync, SYNC_WAIT); - /* Master core is set at first entry */ t_params[0].dev_id = ad->dev_id; - t_params[0].lcore_id = 15; + t_params[0].lcore_id = rte_lcore_id(); t_params[0].op_params = op_params; t_params[0].queue_id = ad->dec_queue; - used_cores++; t_params[0].iter_count = 0; t_params[0].p_out = p_out; t_params[0].p_offloadParams = p_offloadParams; - t_params[0].r = r; - t_params[0].harq_pid = harq_pid; t_params[0].ulsch_id = ulsch_id; - + used_cores++; // For now, we never enter here, we don't use the DPDK thread pool RTE_LCORE_FOREACH_WORKER(lcore_id) { if (used_cores >= num_lcores) @@ -853,58 +790,38 @@ int start_pmd_dec(struct active_device *ad, t_params[used_cores].iter_count = 0; t_params[used_cores].p_out = p_out; t_params[used_cores].p_offloadParams = p_offloadParams; - t_params[used_cores].r = r; - t_params[used_cores].harq_pid = harq_pid; t_params[used_cores].ulsch_id = ulsch_id; rte_eal_remote_launch(pmd_lcore_ldpc_dec, &t_params[used_cores++], lcore_id); } - rte_atomic16_set(&op_params->sync, SYNC_START); - ret = pmd_lcore_ldpc_dec(&t_params[0]); - /* Master core is always used */ // for (used_cores = 1; used_cores < num_lcores; used_cores++) // ret |= rte_eal_wait_lcore(t_params[used_cores].lcore_id); - - /* Return if test failed */ - if (ret < 0) { - rte_free(t_params); - return ret; - } - rte_free(t_params); return ret; } +// based on DPDK BBDEV throughput_pmd_lcore_enc int32_t start_pmd_enc(struct active_device *ad, struct test_op_params *op_params, t_nrLDPCoffload_params *p_offloadParams, uint8_t *p_out) { - int ret; unsigned int lcore_id, used_cores = 0; - uint16_t num_lcores; + int ret; num_lcores = (ad->nb_queues < (op_params->num_lcores)) ? ad->nb_queues : op_params->num_lcores; - /* Allocate memory for thread parameters structure */ struct thread_params *t_params = rte_zmalloc(NULL, num_lcores * sizeof(struct thread_params), RTE_CACHE_LINE_SIZE); - TEST_ASSERT_NOT_NULL(t_params, - "Failed to alloc %zuB for t_params", - RTE_ALIGN(sizeof(struct thread_params) * num_lcores, RTE_CACHE_LINE_SIZE)); rte_atomic16_set(&op_params->sync, SYNC_WAIT); - - /* Master core is set at first entry */ t_params[0].dev_id = ad->dev_id; - t_params[0].lcore_id = 14; + t_params[0].lcore_id = rte_lcore_id() + 1; t_params[0].op_params = op_params; - // t_params[0].queue_id = ad->queue_ids[used_cores++]; - used_cores++; t_params[0].queue_id = ad->enc_queue; t_params[0].iter_count = 0; t_params[0].p_out = p_out; t_params[0].p_offloadParams = p_offloadParams; - + used_cores++; // For now, we never enter here, we don't use the DPDK thread pool RTE_LCORE_FOREACH_WORKER(lcore_id) { if (used_cores >= num_lcores) @@ -916,14 +833,8 @@ int32_t start_pmd_enc(struct active_device *ad, t_params[used_cores].iter_count = 0; rte_eal_remote_launch(pmd_lcore_ldpc_enc, &t_params[used_cores++], lcore_id); } - rte_atomic16_set(&op_params->sync, SYNC_START); ret = pmd_lcore_ldpc_enc(&t_params[0]); - if (ret) { - rte_free(t_params); - return ret; - } - rte_free(t_params); return ret; } @@ -941,10 +852,19 @@ int32_t LDPCinit() int dev_id = 0; struct rte_bbdev_info info; struct active_device *ad = active_devs; - char *dpdk_dev = "d8:00.0"; //PCI address of the card - char *argv_re[] = {"bbdev", "-a", dpdk_dev, "-l", "14-15", "--file-prefix=b6", "--"}; + char *dpdk_dev = NULL; // PCI address of the card + char *dpdk_core_list = NULL; // cores used by DPDK for T2 + char *dpdk_file_prefix = NULL; + paramdef_t LoaderParams[] = { + {"dpdk_dev", NULL, 0, .strptr = &dpdk_dev, .defstrval = NULL, TYPE_STRING, 0, NULL}, + {"dpdk_core_list", NULL, 0, .strptr = &dpdk_core_list, .defstrval = "11-12", TYPE_STRING, 0, NULL}, + {"dpdk_file_prefix", NULL, 0, .strptr = &dpdk_file_prefix, .defstrval = "b6", TYPE_STRING, 0, NULL} + }; + config_get(config_get_if(), LoaderParams, sizeofArray(LoaderParams), "ldpc_offload"); + AssertFatal(dpdk_dev != NULL, "ldpc_offload.dpdk_dev was not provided"); + char *argv_re[] = {"bbdev", "-a", dpdk_dev, "-l", dpdk_core_list, "--file-prefix", dpdk_file_prefix, "--"}; // EAL initialization, if already initialized (init in xran lib) try to probe DPDK device - ret = rte_eal_init(5, argv_re); + ret = rte_eal_init(sizeofArray(argv_re), argv_re); if (ret < 0) { printf("EAL initialization failed, probing DPDK device %s\n", dpdk_dev); if (rte_dev_probe(dpdk_dev) != 0) { @@ -956,63 +876,32 @@ int32_t LDPCinit() rte_bbdev_info_get(0, &info); // Set number of queues based on number of initialized cores (-l option) and driver // capabilities - TEST_ASSERT_SUCCESS(add_dev(dev_id, &info), "Failed to setup bbdev"); - TEST_ASSERT_SUCCESS(rte_bbdev_stats_reset(dev_id), "Failed to reset stats of bbdev %d", dev_id); - TEST_ASSERT_SUCCESS(rte_bbdev_start(dev_id), "Failed to start bbdev %d", dev_id); + AssertFatal(add_dev(dev_id, &info) == 0, "Failed to setup bbdev"); + AssertFatal(rte_bbdev_stats_reset(dev_id) == 0, "Failed to reset stats of bbdev %d", dev_id); + AssertFatal(rte_bbdev_start(dev_id) == 0, "Failed to start bbdev %d", dev_id); //the previous calls have populated this global variable (beurk) // One more global to remove, not thread safe global op_params op_params = rte_zmalloc(NULL, sizeof(struct test_op_params), RTE_CACHE_LINE_SIZE); - TEST_ASSERT_NOT_NULL(op_params, "Failed to alloc %zuB for op_params", - RTE_ALIGN(sizeof(struct test_op_params), RTE_CACHE_LINE_SIZE)); + AssertFatal(op_params != NULL, + "Failed to alloc %zuB for op_params", + RTE_ALIGN(sizeof(struct test_op_params), RTE_CACHE_LINE_SIZE)); int socket_id = GET_SOCKET(info.socket_id); int out_max_sz = 8448; // max code block size (for BG1), 22 * 384 int in_max_sz = LDPC_MAX_CB_SIZE; // max number of encoded bits (for BG2 and MCS0) - int num_ops = 1; - int f_ret = create_mempools(ad, socket_id, num_ops, out_max_sz, in_max_sz); - if (f_ret != TEST_SUCCESS) { + int num_queues = 1; + int f_ret = create_mempools(ad, socket_id, num_queues, out_max_sz, in_max_sz); + if (f_ret != 0) { printf("Couldn't create mempools"); return -1; } - // get_num_lcores() hardcoded to 1: we use one core for decode, and another for encode - // this code from bbdev test example is not considering encode and decode test - // get_num_ops() replaced by 1: LDPC decode and ldpc encode (7th param) - f_ret = init_test_op_params(op_params, RTE_BBDEV_OP_LDPC_DEC, ad->bbdev_dec_op_pool, 1, 1, 1); - f_ret |= init_test_op_params(op_params, RTE_BBDEV_OP_LDPC_ENC, ad->bbdev_enc_op_pool, 1, 1, 1); - if (f_ret != TEST_SUCCESS) { + f_ret = init_test_op_params(op_params, RTE_BBDEV_OP_LDPC_DEC, ad->bbdev_dec_op_pool, num_queues, num_queues, 1); + f_ret = init_test_op_params(op_params, RTE_BBDEV_OP_LDPC_ENC, ad->bbdev_enc_op_pool, num_queues, num_queues, 1); + if (f_ret != 0) { printf("Couldn't init test op params"); return -1; } - - // fill_queue_buffers -> allocate_buffers_on_socket - for (int i = 0; i < ad->nb_queues; ++i) { - const uint16_t n = op_params->num_to_process; - struct rte_mempool *in_mp = ad->in_mbuf_pool; - struct rte_mempool *hard_out_mp = ad->hard_out_mbuf_pool; - struct rte_mempool *soft_out_mp = ad->soft_out_mbuf_pool; - struct rte_mempool *harq_in_mp = ad->harq_in_mbuf_pool; - struct rte_mempool *harq_out_mp = ad->harq_out_mbuf_pool; - struct rte_mempool *mbuf_pools[DATA_NUM_TYPES] = {in_mp, soft_out_mp, hard_out_mp, harq_in_mp, harq_out_mp}; - uint8_t queue_id = ad->queue_ids[i]; - struct rte_bbdev_op_data **queue_ops[DATA_NUM_TYPES] = {&op_params->q_bufs[socket_id][queue_id].inputs, - &op_params->q_bufs[socket_id][queue_id].soft_outputs, - &op_params->q_bufs[socket_id][queue_id].hard_outputs, - &op_params->q_bufs[socket_id][queue_id].harq_inputs, - &op_params->q_bufs[socket_id][queue_id].harq_outputs}; - - for (enum op_data_type type = DATA_INPUT; type < 3; type += 2) { - int ret = allocate_buffers_on_socket(queue_ops[type], n * sizeof(struct rte_bbdev_op_data), socket_id); - TEST_ASSERT_SUCCESS(ret, "Couldn't allocate memory for rte_bbdev_op_data structs"); - m_head[type] = rte_pktmbuf_alloc(mbuf_pools[type]); - TEST_ASSERT_NOT_NULL(m_head[type], - "Not enough mbufs in %d data type mbuf pool (needed %d, available %u)", - type, - 1, - mbuf_pools[type]->size); - } - } - return 0; } @@ -1023,7 +912,6 @@ int32_t LDPCshutdown() struct rte_bbdev_stats stats; free_buffers(ad, op_params); rte_free(op_params); - // Stop and close bbdev rte_bbdev_stats_get(dev_id, &stats); rte_bbdev_stop(dev_id); rte_bbdev_close(dev_id); @@ -1043,17 +931,23 @@ int32_t LDPCdecoder(struct nrLDPC_dec_params *p_decParams, { pthread_mutex_lock(&decode_mutex); // hardcoded we use first device - struct active_device *ad = active_devs; - t_nrLDPCoffload_params offloadParams = {.E = p_decParams->E, - .n_cb = (p_decParams->BG == 1) ? (66 * p_decParams->Z) : (50 * p_decParams->Z), + t_nrLDPCoffload_params offloadParams = {.n_cb = (p_decParams->BG == 1) ? (66 * p_decParams->Z) : (50 * p_decParams->Z), .BG = p_decParams->BG, .Z = p_decParams->Z, .rv = p_decParams->rv, .F = p_decParams->F, .Qm = p_decParams->Qm, + .numMaxIter = p_decParams->numMaxIter, + .C = C, .setCombIn = p_decParams->setCombIn}; + + for (int r = 0; r < C; r++) { + offloadParams.perCB[r].E_cb = p_decParams->perCB[r].E_cb; + offloadParams.perCB[r].p_status_cb = &(p_decParams->perCB[r].status_cb); + } struct rte_bbdev_info info; + int ret; rte_bbdev_info_get(ad->dev_id, &info); int socket_id = GET_SOCKET(info.socket_id); // fill_queue_buffers -> init_op_data_objs @@ -1069,24 +963,23 @@ int32_t LDPCdecoder(struct nrLDPC_dec_params *p_decParams, &op_params->q_bufs[socket_id][queue_id].hard_outputs, &op_params->q_bufs[socket_id][queue_id].harq_inputs, &op_params->q_bufs[socket_id][queue_id].harq_outputs}; - // this should be modified - // enum rte_bbdev_op_type op_type = RTE_BBDEV_OP_LDPC_DEC; for (enum op_data_type type = DATA_INPUT; type < 3; type += 2) { - int ret = init_op_data_objs(*queue_ops[type], + ret = allocate_buffers_on_socket(queue_ops[type], C * sizeof(struct rte_bbdev_op_data), socket_id); + AssertFatal(ret == 0, "Couldn't allocate memory for rte_bbdev_op_data structs"); + ret = init_op_data_objs_dec(*queue_ops[type], (uint8_t *)p_llr, - p_decParams->E, - m_head[type], + &offloadParams, mbuf_pools[type], - 1, + C, type, info.drv.min_alignment); - TEST_ASSERT_SUCCESS(ret, "Couldn't init rte_bbdev_op_data structs"); + AssertFatal(ret == 0, "Couldn't init rte_bbdev_op_data structs"); } - int ret = start_pmd_dec(ad, op_params, &offloadParams, C, harq_pid, ulsch_id, (uint8_t *)p_out); + ret = start_pmd_dec(ad, op_params, &offloadParams, ulsch_id, (uint8_t *)p_out); if (ret < 0) { printf("Couldn't start pmd dec\n"); pthread_mutex_unlock(&decode_mutex); - return (20); // Fix me: we should propoagate max_iterations properly in the call (impp struct) + return (p_decParams->numMaxIter); } pthread_mutex_unlock(&decode_mutex); return ret; @@ -1097,16 +990,23 @@ int32_t LDPCencoder(unsigned char **input, unsigned char **output, encoder_imple pthread_mutex_lock(&encode_mutex); // hardcoded to use the first found board struct active_device *ad = active_devs; - int Zc = impp->Zc; - int BG = impp->BG; - t_nrLDPCoffload_params offloadParams = {.E = impp->E, - .n_cb = (BG == 1) ? (66 * Zc) : (50 * Zc), - .BG = BG, - .Z = Zc, + int ret; + uint32_t Nref = 0; + t_nrLDPCoffload_params offloadParams = {.n_cb = (impp->BG == 1) ? (66 * impp->Zc) : (50 * impp->Zc), + .BG = impp->BG, + .Z = impp->Zc, .rv = impp->rv, .F = impp->F, .Qm = impp->Qm, + .C = impp->n_segments, .Kr = (impp->K - impp->F + 7) / 8}; + for (int r = 0; r < impp->n_segments; r++) { + offloadParams.perCB[r].E_cb = impp->perCB[r].E_cb; + } + if (impp->Tbslbrm != 0) { + Nref = 3 * impp->Tbslbrm / (2 * impp->n_segments); + offloadParams.n_cb = min(offloadParams.n_cb, Nref); + } struct rte_bbdev_info info; rte_bbdev_info_get(ad->dev_id, &info); int socket_id = GET_SOCKET(info.socket_id); @@ -1124,17 +1024,19 @@ int32_t LDPCencoder(unsigned char **input, unsigned char **output, encoder_imple &op_params->q_bufs[socket_id][queue_id].harq_inputs, &op_params->q_bufs[socket_id][queue_id].harq_outputs}; for (enum op_data_type type = DATA_INPUT; type < 3; type += 2) { - int ret = init_op_data_objs(*queue_ops[type], - *input, - offloadParams.Kr, + ret = allocate_buffers_on_socket(queue_ops[type], impp->n_segments * sizeof(struct rte_bbdev_op_data), socket_id); + AssertFatal(ret == 0, "Couldn't allocate memory for rte_bbdev_op_data structs"); + ret = init_op_data_objs_enc(*queue_ops[type], + input, + &offloadParams, m_head[type], mbuf_pools[type], - 1, + impp->n_segments, type, info.drv.min_alignment); - TEST_ASSERT_SUCCESS(ret, "Couldn't init rte_bbdev_op_data structs"); + AssertFatal(ret == 0, "Couldn't init rte_bbdev_op_data structs"); } - int ret=start_pmd_enc(ad, op_params, &offloadParams, *output); + ret = start_pmd_enc(ad, op_params, &offloadParams, *output); pthread_mutex_unlock(&encode_mutex); return ret; } diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_offload.h b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_offload.h index 80a9395d0b..9da33f4671 100644 --- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_offload.h +++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_offload.h @@ -12,14 +12,7 @@ #include #include -#define TEST_SUCCESS 0 -#define TEST_FAILED -1 -#define TEST_SKIPPED 1 - #define MAX_BURST 512U -#define DEFAULT_BURST 32U -#define DEFAULT_OPS 64U -#define DEFAULT_ITER 6U enum op_data_type { DATA_INPUT = 0, @@ -30,106 +23,4 @@ enum op_data_type { DATA_NUM_TYPES, }; -#define TEST_ASSERT(cond, msg, ...) do { \ - if (!(cond)) { \ - printf("TestCase %s() line %d failed: " \ - msg "\n", __func__, __LINE__, ##__VA_ARGS__); \ - return TEST_FAILED; \ - } \ -} while (0) - -/* Compare two buffers (length in bytes) */ -#define TEST_ASSERT_BUFFERS_ARE_EQUAL(a, b, len, msg, ...) do { \ - if (memcmp((a), (b), len)) { \ - printf("TestCase %s() line %d failed: " \ - msg "\n", __func__, __LINE__, ##__VA_ARGS__); \ - rte_memdump(stdout, "Buffer A", (a), len); \ - rte_memdump(stdout, "Buffer B", (b), len); \ - return TEST_FAILED; \ - } \ -} while (0) - -#define TEST_ASSERT_SUCCESS(val, msg, ...) do { \ - typeof(val) _val = (val); \ - if (!(_val == 0)) { \ - printf("TestCase %s() line %d failed (err %d): " \ - msg "\n", __func__, __LINE__, _val, \ - ##__VA_ARGS__); \ - return TEST_FAILED; \ - } \ -} while (0) - -#define TEST_ASSERT_FAIL(val, msg, ...) \ - TEST_ASSERT_SUCCESS(!(val), msg, ##__VA_ARGS__) - -#define TEST_ASSERT_NOT_NULL(val, msg, ...) do { \ - if ((val) == NULL) { \ - printf("TestCase %s() line %d failed (null): " \ - msg "\n", __func__, __LINE__, ##__VA_ARGS__); \ - return TEST_FAILED; \ - } \ -} while (0) - -struct unit_test_case { - int (*setup)(void); - void (*teardown)(void); - int (*testcase)(void); - const char *name; -}; - -#define TEST_CASE(testcase) {NULL, NULL, testcase, #testcase} - -#define TEST_CASE_ST(setup, teardown, testcase) \ - {setup, teardown, testcase, #testcase} - -#define TEST_CASES_END() {NULL, NULL, NULL, NULL} - -struct unit_test_suite { - const char *suite_name; - int (*setup)(void); - void (*teardown)(void); - struct unit_test_case unit_test_cases[]; -}; - -int unit_test_suite_runner(struct unit_test_suite *suite); - -typedef int (test_callback)(void); -TAILQ_HEAD(test_commands_list, test_command); -struct test_command { - TAILQ_ENTRY(test_command) next; - const char *command; - test_callback *callback; -}; - -void add_test_command(struct test_command *t); - -/* Register a test function */ -#define REGISTER_TEST_COMMAND(name, testsuite) \ - static int test_func_##name(void) \ - { \ - return unit_test_suite_runner(&testsuite); \ - } \ - static struct test_command test_struct_##name = { \ - .command = RTE_STR(name), \ - .callback = test_func_##name, \ - }; \ - RTE_INIT(test_register_##name) \ - { \ - add_test_command(&test_struct_##name); \ - } - -const char *get_vector_filename(void); - -unsigned int get_num_ops(void); - -unsigned int get_burst_sz(void); - -unsigned int get_num_lcores(void); - -double get_snr(void); - -unsigned int get_iter_max(void); - -bool get_init_device(void); - #endif diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_types.h b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_types.h index 63a96645c3..f8d31c8fcd 100644 --- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_types.h +++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_types.h @@ -78,6 +78,15 @@ typedef enum nrLDPC_outMode { nrLDPC_outMode_LLRINT8 /**< Single LLR value per int8_t output */ } e_nrLDPC_outMode; +/** + Structure containing LDPC parameters per CB +*/ +typedef struct nrLDPC_params_per_cb { + uint32_t E_cb; + uint8_t status_cb; + uint8_t* p_status_cb; +} nrLDPC_params_per_cb_t; + /** Structure containing LDPC decoder parameters. */ @@ -94,18 +103,24 @@ typedef struct nrLDPC_dec_params { int crc_type; int (*check_crc)(uint8_t* decoded_bytes, uint32_t n, uint8_t crc_type); uint8_t setCombIn; + nrLDPC_params_per_cb_t perCB[NR_LDPC_MAX_NUM_CB]; } t_nrLDPC_dec_params; +/** + Structure containing LDPC offload parameters. + */ typedef struct nrLDPCoffload_params { uint8_t BG; /**< Base graph */ uint16_t Z; uint16_t Kr; uint8_t rv; - uint32_t E; uint16_t n_cb; uint16_t F; /**< Filler bits */ uint8_t Qm; /**< Modulation */ + uint8_t C; + uint8_t numMaxIter; uint8_t setCombIn; + nrLDPC_params_per_cb_t perCB[NR_LDPC_MAX_NUM_CB]; } t_nrLDPCoffload_params; /** diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPCdecoder_defs.h b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPCdecoder_defs.h index e9e2d1704a..d713340a19 100644 --- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPCdecoder_defs.h +++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPCdecoder_defs.h @@ -99,6 +99,8 @@ /** Maximum number of possible input LLR = NR_LDPC_NCOL_BG1*NR_LDPC_ZMAX */ #define NR_LDPC_MAX_NUM_LLR 27000 +#define NR_LDPC_MAX_NUM_CB 72 + // ============================================================================== // GLOBAL CONSTANT VARIABLES diff --git a/openair1/PHY/CODING/nrLDPC_defs.h b/openair1/PHY/CODING/nrLDPC_defs.h index c9e5454087..3ff2381d0b 100644 --- a/openair1/PHY/CODING/nrLDPC_defs.h +++ b/openair1/PHY/CODING/nrLDPC_defs.h @@ -59,8 +59,9 @@ typedef struct { uint32_t F; /// Modulation order uint8_t Qm; - uint32_t E; + uint32_t Tbslbrm; unsigned int G; + nrLDPC_params_per_cb_t perCB[NR_LDPC_MAX_NUM_CB]; // Redundancy version index uint8_t rv; } encoder_implemparams_t; diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index 0470abcf49..e95451fcd8 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -137,6 +137,9 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB) if (gNB->ldpc_offload_flag) load_LDPClib("_t2", &ldpc_interface_offload); + else + load_LDPClib(NULL, &ldpc_interface); + gNB->max_nb_pdsch = MAX_MOBILES_PER_GNB; init_delay_table(fp->ofdm_symbol_size, MAX_DELAY_COMP, NR_MAX_OFDM_SYMBOL_SIZE, fp->delay_table); diff --git a/openair1/PHY/NR_REFSIG/nr_refsig.h b/openair1/PHY/NR_REFSIG/nr_refsig.h index c8afffa7d3..47afec9ef1 100644 --- a/openair1/PHY/NR_REFSIG/nr_refsig.h +++ b/openair1/PHY/NR_REFSIG/nr_refsig.h @@ -61,6 +61,21 @@ int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB, uint32_t re_offset, uint8_t dmrs_type); +void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms, + int32_t **dataF, + const int16_t amp, + nr_csi_info_t *nr_csi_info, + const nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csi_params, + const int slot, + uint8_t *N_cdm_groups, + uint8_t *CDM_group_size, + uint8_t *k_prime, + uint8_t *l_prime, + uint8_t *N_ports, + uint8_t *j_cdm, + uint8_t *k_overline, + uint8_t *l_overline); + void init_scrambling_luts(void); void nr_generate_modulation_table(void); diff --git a/openair1/PHY/NR_TRANSPORT/nr_csi_rs.c b/openair1/PHY/NR_TRANSPORT/nr_csi_rs.c index 716a8b52be..001ad8ad87 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_csi_rs.c +++ b/openair1/PHY/NR_TRANSPORT/nr_csi_rs.c @@ -19,23 +19,21 @@ * contact@openairinterface.org */ - -#include "PHY/NR_TRANSPORT/nr_transport_proto.h" #include "PHY/MODULATION/nr_modulation.h" #include "PHY/NR_REFSIG/nr_refsig.h" //#define NR_CSIRS_DEBUG -void nr_init_csi_rs(const NR_DL_FRAME_PARMS *fp, uint32_t ***csi_rs, uint32_t Nid) { - uint32_t x1 = 0, x2 = 0; - uint8_t reset; - int csi_dmrs_init_length = ((fp->N_RB_DL<<4)>>5)+1; - for (uint8_t slot=0; slotslots_per_frame; slot++) { - for (uint8_t symb=0; symbsymbols_per_slot; symb++) { - reset = 1; - x2 = ((1<<10) * (fp->symbols_per_slot*slot+symb+1) * ((Nid<<1)+1) + (Nid)); - for (uint32_t n=0; nN_RB_DL << 4) >> 5) + 1; + for (int slot = 0; slot < fp->slots_per_frame; slot++) { + for (int symb = 0; symb < fp->symbols_per_slot; symb++) { + uint8_t reset = 1; + uint32_t x2 = ((1 << 10) * (fp->symbols_per_slot * slot + symb + 1) * ((Nid << 1) + 1) + Nid); + for (uint32_t n = 0; n < csi_dmrs_init_length; n++) { csi_rs[slot][symb][n] = lte_gold_generic(&x1, &x2, reset); reset = 0; } @@ -56,8 +54,8 @@ void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms, uint8_t *N_ports, uint8_t *j_cdm, uint8_t *k_overline, - uint8_t *l_overline) { - + uint8_t *l_overline) +{ #ifdef NR_CSIRS_DEBUG LOG_I(NR_PHY, "csi_params->subcarrier_spacing = %i\n", csi_params->subcarrier_spacing); LOG_I(NR_PHY, "csi_params->cyclic_prefix = %i\n", csi_params->cyclic_prefix); @@ -75,19 +73,12 @@ void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms, LOG_I(NR_PHY, "csi_params->power_control_offset_ss = %i\n", csi_params->power_control_offset_ss); #endif - int dataF_offset = slot*frame_parms->samples_per_slot_wCP; + int dataF_offset = slot * frame_parms->samples_per_slot_wCP; uint32_t **nr_gold_csi_rs = nr_csi_info->nr_gold_csi_rs[slot]; //*8(max allocation per RB)*2(QPSK)) - int csi_rs_length = frame_parms->N_RB_DL<<4; + int csi_rs_length = frame_parms->N_RB_DL << 4; int16_t mod_csi[frame_parms->symbols_per_slot][csi_rs_length>>1] __attribute__((aligned(16))); uint16_t b = csi_params->freq_domain; - uint16_t n, p, k, l, mprime, na, kpn; - uint8_t size, ports, kprime, lprime, i, gs; - uint8_t j[16], k_n[6], koverline[16], loverline[16]; - int found = 0; - int wf, wt, lp, kp, symb; - uint8_t fi = 0; - double rho, alpha; uint32_t beta = amp; nr_csi_info->csi_rs_generated_signal_bits = log2_approx(amp); @@ -99,469 +90,479 @@ void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms, nr_init_csi_rs(frame_parms, nr_csi_info->nr_gold_csi_rs, csi_params->scramb_id); } - switch (csi_params->row) { + int size, ports, kprime, lprime; + int j[16], k_n[6], koverline[16], loverline[16]; + int found = 0; + int fi = 0; + // implementation of table 7.4.1.5.3-1 of 38.211 // lprime and kprime are the max value of l' and k' - case 1: - ports = 1; - kprime = 0; - lprime = 0; - size = 3; - while (found < 1) { - if ((b >> fi) & 0x01) { - k_n[found] = fi; - found++; + switch (csi_params->row) { + case 1: + ports = 1; + kprime = 0; + lprime = 0; + size = 3; + while (found < 1) { + if ((b >> fi) & 0x01) { + k_n[found] = fi; + found++; + } + else + fi++; } - else - fi++; - } - for (i=0; isymb_l0; - koverline[i] = k_n[0] + (i<<2); - } - break; - - case 2: - ports = 1; - kprime = 0; - lprime = 0; - size = 1; - while (found < 1) { - if ((b >> fi) & 0x01) { - k_n[found] = fi; - found++; - } - else - fi++; - } - for (i=0; isymb_l0; - koverline[i] = k_n[0]; - } - break; - - case 3: - ports = 2; - kprime = 1; - lprime = 0; - size = 1; - while (found < 1) { - if ((b >> fi) & 0x01) { - k_n[found] = fi<<1; - found++; - } - else - fi++; - } - for (i=0; isymb_l0; - koverline[i] = k_n[0]; - } - break; - - case 4: - ports = 4; - kprime = 1; - lprime = 0; - size = 2; - while (found < 1) { - if ((b >> fi) & 0x01) { - k_n[found] = fi<<2; - found++; - } - else - fi++; - } - for (i=0; isymb_l0; - koverline[i] = k_n[0] + (i<<1); - } - break; - - case 5: - ports = 4; - kprime = 1; - lprime = 0; - size = 2; - while (found < 1) { - if ((b >> fi) & 0x01) { - k_n[found] = fi<<1; - found++; - } - else - fi++; - } - for (i=0; isymb_l0 + i; - koverline[i] = k_n[0]; - } - break; - - case 6: - ports = 8; - kprime = 1; - lprime = 0; - size = 4; - while (found < 4) { - if ((b >> fi) & 0x01) { - k_n[found] = fi<<1; - found++; - } - fi++; - } - for (i=0; isymb_l0; - koverline[i] = k_n[i]; - } - break; - - case 7: - ports = 8; - kprime = 1; - lprime = 0; - size = 4; - while (found < 2) { - if ((b >> fi) & 0x01) { - k_n[found] = fi<<1; - found++; - } - fi++; - } - for (i=0; isymb_l0 + (i>>1); - koverline[i] = k_n[i%2]; - } - break; - - case 8: - ports = 8; - kprime = 1; - lprime = 1; - size = 2; - while (found < 2) { - if ((b >> fi) & 0x01) { - k_n[found] = fi<<1; - found++; - } - fi++; - } - for (i=0; isymb_l0; - koverline[i] = k_n[i]; - } - break; - - case 9: - ports = 12; - kprime = 1; - lprime = 0; - size = 6; - while (found < 6) { - if ((b >> fi) & 0x01) { - k_n[found] = fi<<1; - found++; - } - fi++; - } - for (i=0; isymb_l0; - koverline[i] = k_n[i]; - } - break; - - case 10: - ports = 12; - kprime = 1; - lprime = 1; - size = 3; - while (found < 3) { - if ((b >> fi) & 0x01) { - k_n[found] = fi<<1; - found++; - } - fi++; - } - for (i=0; isymb_l0; - koverline[i] = k_n[i]; - } - break; - - case 11: - ports = 16; - kprime = 1; - lprime = 0; - size = 8; - while (found < 4) { - if ((b >> fi) & 0x01) { - k_n[found] = fi<<1; - found++; - } - fi++; - } - for (i=0; isymb_l0 + (i>>2); - koverline[i] = k_n[i%4]; - } - break; - - case 12: - ports = 16; - kprime = 1; - lprime = 1; - size = 4; - while (found < 4) { - if ((b >> fi) & 0x01) { - k_n[found] = fi<<1; - found++; - } - fi++; - } - for (i=0; isymb_l0; - koverline[i] = k_n[i]; - } - break; - - case 13: - ports = 24; - kprime = 1; - lprime = 0; - size = 12; - while (found < 3) { - if ((b >> fi) & 0x01) { - k_n[found] = fi<<1; - found++; - } - fi++; - } - for (i=0; isymb_l0 + i/3; - else - loverline[i] = csi_params->symb_l1 + i/9; - koverline[i] = k_n[i%3]; - } - break; - - case 14: - ports = 24; - kprime = 1; - lprime = 1; - size = 6; - while (found < 3) { - if ((b >> fi) & 0x01) { - k_n[found] = fi<<1; - found++; - } - fi++; - } - for (i=0; isymb_l0; - else - loverline[i] = csi_params->symb_l1; - koverline[i] = k_n[i%3]; - } - break; - - case 15: - ports = 24; - kprime = 1; - lprime = 3; - size = 3; - while (found < 3) { - if ((b >> fi) & 0x01) { - k_n[found] = fi<<1; - found++; + koverline[i] = k_n[0] + (i<<2); } - fi++; - } - for (i=0; isymb_l0; - koverline[i] = k_n[i]; - } - break; - - case 16: - ports = 32; - kprime = 1; - lprime = 0; - size = 16; - while (found < 4) { - if ((b >> fi) & 0x01) { - k_n[found] = fi<<1; - found++; + break; + case 2: + ports = 1; + kprime = 0; + lprime = 0; + size = 1; + while (found < 1) { + if ((b >> fi) & 0x01) { + k_n[found] = fi; + found++; + } + else + fi++; } - fi++; - } - for (i=0; isymb_l0 + (i>>2); - else - loverline[i] = csi_params->symb_l1 + (i/12); - koverline[i] = k_n[i%4]; - } - break; - - case 17: - ports = 32; - kprime = 1; - lprime = 1; - size = 8; - while (found < 4) { - if ((b >> fi) & 0x01) { - k_n[found] = fi<<1; - found++; - } - fi++; - } - for (i=0; isymb_l0; - else - loverline[i] = csi_params->symb_l1; - koverline[i] = k_n[i%4]; - } - break; - - case 18: - ports = 32; - kprime = 1; - lprime = 3; - size = 4; - while (found < 4) { - if ((b >> fi) & 0x01) { - k_n[found] = fi<<1; - found++; + koverline[i] = k_n[0]; } - fi++; - } - for (i=0; isymb_l0; - koverline[i] = k_n[i]; - } - break; - - default: - AssertFatal(0==1, "Row %d is not valid for CSI Table 7.4.1.5.3-1\n", csi_params->row); + break; + case 3: + ports = 2; + kprime = 1; + lprime = 0; + size = 1; + while (found < 1) { + if ((b >> fi) & 0x01) { + k_n[found] = fi << 1; + found++; + } + else + fi++; + } + for (int i = 0; i < size; i++) { + j[i] = 0; + loverline[i] = csi_params->symb_l0; + koverline[i] = k_n[0]; + } + break; + case 4: + ports = 4; + kprime = 1; + lprime = 0; + size = 2; + while (found < 1) { + if ((b >> fi) & 0x01) { + k_n[found] = fi << 2; + found++; + } + else + fi++; + } + for (int i = 0; i < size; i++) { + j[i] = i; + loverline[i] = csi_params->symb_l0; + koverline[i] = k_n[0] + (i << 1); + } + break; + case 5: + ports = 4; + kprime = 1; + lprime = 0; + size = 2; + while (found < 1) { + if ((b >> fi) & 0x01) { + k_n[found] = fi << 1; + found++; + } + else + fi++; + } + for (int i = 0; i < size; i++) { + j[i] = i; + loverline[i] = csi_params->symb_l0 + i; + koverline[i] = k_n[0]; + } + break; + case 6: + ports = 8; + kprime = 1; + lprime = 0; + size = 4; + while (found < 4) { + if ((b >> fi) & 0x01) { + k_n[found] = fi << 1; + found++; + } + fi++; + } + for (int i = 0; i < size; i++) { + j[i] = i; + loverline[i] = csi_params->symb_l0; + koverline[i] = k_n[i]; + } + break; + case 7: + ports = 8; + kprime = 1; + lprime = 0; + size = 4; + while (found < 2) { + if ((b >> fi) & 0x01) { + k_n[found] = fi << 1; + found++; + } + fi++; + } + for (int i = 0; i < size; i++) { + j[i] = i; + loverline[i] = csi_params->symb_l0 + (i >> 1); + koverline[i] = k_n[i % 2]; + } + break; + case 8: + ports = 8; + kprime = 1; + lprime = 1; + size = 2; + while (found < 2) { + if ((b >> fi) & 0x01) { + k_n[found] = fi << 1; + found++; + } + fi++; + } + for (int i = 0; i < size; i++) { + j[i] = i; + loverline[i] = csi_params->symb_l0; + koverline[i] = k_n[i]; + } + break; + case 9: + ports = 12; + kprime = 1; + lprime = 0; + size = 6; + while (found < 6) { + if ((b >> fi) & 0x01) { + k_n[found] = fi << 1; + found++; + } + fi++; + } + for (int i = 0; i < size; i++) { + j[i] = i; + loverline[i] = csi_params->symb_l0; + koverline[i] = k_n[i]; + } + break; + case 10: + ports = 12; + kprime = 1; + lprime = 1; + size = 3; + while (found < 3) { + if ((b >> fi) & 0x01) { + k_n[found] = fi << 1; + found++; + } + fi++; + } + for (int i = 0; i < size; i++) { + j[i] = i; + loverline[i] = csi_params->symb_l0; + koverline[i] = k_n[i]; + } + break; + case 11: + ports = 16; + kprime = 1; + lprime = 0; + size = 8; + while (found < 4) { + if ((b >> fi) & 0x01) { + k_n[found] = fi << 1; + found++; + } + fi++; + } + for (int i = 0; i < size; i++) { + j[i] = i; + loverline[i] = csi_params->symb_l0 + (i >> 2); + koverline[i] = k_n[i % 4]; + } + break; + case 12: + ports = 16; + kprime = 1; + lprime = 1; + size = 4; + while (found < 4) { + if ((b >> fi) & 0x01) { + k_n[found] = fi << 1; + found++; + } + fi++; + } + for (int i = 0; i < size; i++) { + j[i] = i; + loverline[i] = csi_params->symb_l0; + koverline[i] = k_n[i]; + } + break; + case 13: + ports = 24; + kprime = 1; + lprime = 0; + size = 12; + while (found < 3) { + if ((b >> fi) & 0x01) { + k_n[found] = fi << 1; + found++; + } + fi++; + } + for (int i = 0; i < size; i++) { + j[i] = i; + if (i < 6) + loverline[i] = csi_params->symb_l0 + i / 3; + else + loverline[i] = csi_params->symb_l1 + i / 9; + koverline[i] = k_n[i % 3]; + } + break; + case 14: + ports = 24; + kprime = 1; + lprime = 1; + size = 6; + while (found < 3) { + if ((b >> fi) & 0x01) { + k_n[found] = fi << 1; + found++; + } + fi++; + } + for (int i = 0; i < size; i++) { + j[i] = i; + if (i < 3) + loverline[i] = csi_params->symb_l0; + else + loverline[i] = csi_params->symb_l1; + koverline[i] = k_n[i%3]; + } + break; + case 15: + ports = 24; + kprime = 1; + lprime = 3; + size = 3; + while (found < 3) { + if ((b >> fi) & 0x01) { + k_n[found] = fi << 1; + found++; + } + fi++; + } + for (int i = 0; i < size; i++) { + j[i] = i; + loverline[i] = csi_params->symb_l0; + koverline[i] = k_n[i]; + } + break; + case 16: + ports = 32; + kprime = 1; + lprime = 0; + size = 16; + while (found < 4) { + if ((b >> fi) & 0x01) { + k_n[found] = fi << 1; + found++; + } + fi++; + } + for (int i = 0; i < size; i++) { + j[i] = i; + if (i < 8) + loverline[i] = csi_params->symb_l0 + (i>>2); + else + loverline[i] = csi_params->symb_l1 + (i/12); + koverline[i] = k_n[i % 4]; + } + break; + case 17: + ports = 32; + kprime = 1; + lprime = 1; + size = 8; + while (found < 4) { + if ((b >> fi) & 0x01) { + k_n[found] = fi << 1; + found++; + } + fi++; + } + for (int i = 0; i < size; i++) { + j[i] = i; + if (i < 4) + loverline[i] = csi_params->symb_l0; + else + loverline[i] = csi_params->symb_l1; + koverline[i] = k_n[i % 4]; + } + break; + case 18: + ports = 32; + kprime = 1; + lprime = 3; + size = 4; + while (found < 4) { + if ((b >> fi) & 0x01) { + k_n[found] = fi << 1; + found++; + } + fi++; + } + for (int i = 0; i < size; i++) { + j[i] = i; + loverline[i] = csi_params->symb_l0; + koverline[i] = k_n[i]; + } + break; + default: + AssertFatal(false, "Row %d is not valid for CSI Table 7.4.1.5.3-1\n", csi_params->row); } #ifdef NR_CSIRS_DEBUG printf(" row %d, n. of ports %d\n k' ",csi_params->row,ports); - for (kp=0; kp<=kprime; kp++) + for (int kp = 0; kp <= kprime; kp++) printf("%d, ",kp); printf("l' "); - for (lp=0; lp<=lprime; lp++) - printf("%d, ",lp); + for (int lp = 0; lp <= lprime; lp++) + printf("%d, ", lp); printf("\n k overline "); - for (i=0; ifreq_density) { - - case 0: - rho = 0.5; - break; - - case 1: - rho = 0.5; - break; - - case 2: - rho = 1; - break; - - case 3: - rho = 3; - break; - - default: - AssertFatal(0==1, "Invalid frequency density index for CSI\n"); + case 0: + rho = 0.5; + break; + case 1: + rho = 0.5; + break; + case 2: + rho = 1; + break; + case 3: + rho = 3; + break; + default: + AssertFatal(false, "Invalid frequency density index for CSI\n"); } + double alpha = 0; if (ports == 1) alpha = rho; else - alpha = 2*rho; + alpha = 2 * rho; #ifdef NR_CSIRS_DEBUG - printf(" rho %f, alpha %f\n",rho,alpha); + printf(" rho %f, alpha %f\n", rho, alpha); #endif // CDM group size from CDM type index + int gs = 0; switch (csi_params->cdm_type) { - - case 0: - gs = 1; - break; - - case 1: - gs = 2; - break; - - case 2: - gs = 4; - break; - - case 3: - gs = 8; - break; - - default: - AssertFatal(0==1, "Invalid cdm type index for CSI\n"); + case 0: + gs = 1; + break; + case 1: + gs = 2; + break; + case 2: + gs = 4; + break; + case 3: + gs = 8; + break; + default: + AssertFatal(false, "Invalid cdm type index for CSI\n"); } - uint16_t csi_length; + int csi_length; if (rho < 1) { if (csi_params->freq_density == 0) { - csi_length = (((csi_params->start_rb + csi_params->nr_of_rbs)>>1)<start_rb + csi_params->nr_of_rbs) >> 1) << kprime) << 1; } else { - csi_length = ((((csi_params->start_rb + csi_params->nr_of_rbs)>>1)<start_rb + csi_params->nr_of_rbs) >> 1) << kprime) + 1) << 1; } } else { - csi_length = (((uint16_t) rho*(csi_params->start_rb + csi_params->nr_of_rbs))<start_rb + csi_params->nr_of_rbs)) << kprime) << 1; } #ifdef NR_CSIRS_DEBUG - printf(" start rb %d, nr of rbs %d, csi length %d\n", csi_params->start_rb, csi_params->nr_of_rbs, csi_length); + printf(" start rb %d, nr of rbs %d, csi length %d\n", csi_params->start_rb, csi_params->nr_of_rbs, csi_length); #endif + if (N_cdm_groups) + *N_cdm_groups = size; + if (CDM_group_size) + *CDM_group_size = gs; + if (k_prime) + *k_prime = kprime; + if (l_prime) + *l_prime = lprime; + if (N_ports) + *N_ports = ports; + if (j_cdm) + memcpy(j_cdm, j, 16 * sizeof(uint8_t)); + if (k_overline) + memcpy(k_overline, koverline, 16 * sizeof(uint8_t)); + if (l_overline) + memcpy(l_overline, loverline, 16 * sizeof(uint8_t)); - // TRS - if (csi_params->csi_type == 0) { - // ??? +#ifdef NR_CSIRS_DEBUG + if (N_ports) + LOG_I(NR_PHY, "nr_csi_info->N_ports = %d\n", *N_ports); + if (N_cdm_groups) + LOG_I(NR_PHY, "nr_csi_info->N_cdm_groups = %d\n", *N_cdm_groups); + if (CDM_group_size) + LOG_I(NR_PHY, "nr_csi_info->CDM_group_size = %d\n", *CDM_group_size); + if (k_prime) + LOG_I(NR_PHY, "nr_csi_info->kprime = %d\n", *k_prime); + if (l_prime) + LOG_I(NR_PHY, "nr_csi_info->lprime = %d\n", *l_prime); + if (N_cdm_groups) { + for(int ji = 0; ji < *N_cdm_groups; ji++) { + LOG_I(NR_PHY, "(CDM group %d) j = %d, koverline = %d, loverline = %d\n", ji, j[ji], koverline[ji], loverline[ji]); + } } +#endif - // NZP CSI RS - if (csi_params->csi_type == 1) { - // assuming amp is the amplitude of SSB channels - switch (csi_params->power_control_offset_ss) { + if (csi_params->csi_type == 2) // ZP-CSI + return; + + // assuming amp is the amplitude of SSB channels + switch (csi_params->power_control_offset_ss) { case 0: beta = (amp*ONE_OVER_SQRT2_Q15)>>15; break; @@ -572,73 +573,68 @@ void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms, beta = (amp*ONE_OVER_SQRT2_Q15)>>14; break; case 3: - beta = amp<<1; + beta = amp << 1; break; default: - AssertFatal(0==1, "Invalid SS power offset density index for CSI\n"); - } + AssertFatal(false, "Invalid SS power offset density index for CSI\n"); + } - for (lp=0; lp<=lprime; lp++){ - symb = csi_params->symb_l0; - nr_modulation(nr_gold_csi_rs[symb+lp], csi_length, DMRS_MOD_ORDER, mod_csi[symb+lp]); - if ((csi_params->row == 5) || (csi_params->row == 7) || (csi_params->row == 11) || (csi_params->row == 13) || (csi_params->row == 16)) - nr_modulation(nr_gold_csi_rs[symb+1], csi_length, DMRS_MOD_ORDER, mod_csi[symb+1]); - if ((csi_params->row == 14) || (csi_params->row == 13) || (csi_params->row == 16) || (csi_params->row == 17)) { - symb = csi_params->symb_l1; - nr_modulation(nr_gold_csi_rs[symb+lp], csi_length, DMRS_MOD_ORDER, mod_csi[symb+lp]); - if ((csi_params->row == 13) || (csi_params->row == 16)) - nr_modulation(nr_gold_csi_rs[symb+1], csi_length, DMRS_MOD_ORDER, mod_csi[symb+1]); - } + for (int lp = 0; lp <= lprime; lp++) { + int symb = csi_params->symb_l0; + nr_modulation(nr_gold_csi_rs[symb + lp], csi_length, DMRS_MOD_ORDER, mod_csi[symb + lp]); + if ((csi_params->row == 5) || (csi_params->row == 7) || (csi_params->row == 11) || (csi_params->row == 13) || (csi_params->row == 16)) + nr_modulation(nr_gold_csi_rs[symb + 1], csi_length, DMRS_MOD_ORDER, mod_csi[symb + 1]); + if ((csi_params->row == 14) || (csi_params->row == 13) || (csi_params->row == 16) || (csi_params->row == 17)) { + symb = csi_params->symb_l1; + nr_modulation(nr_gold_csi_rs[symb + lp], csi_length, DMRS_MOD_ORDER, mod_csi[symb + lp]); + if ((csi_params->row == 13) || (csi_params->row == 16)) + nr_modulation(nr_gold_csi_rs[symb + 1], csi_length, DMRS_MOD_ORDER, mod_csi[symb + 1]); } } uint16_t start_sc = frame_parms->first_carrier_offset; // resource mapping according to 38.211 7.4.1.5.3 - for (n=csi_params->start_rb; n<(csi_params->start_rb+csi_params->nr_of_rbs); n++) { - if ( (csi_params->freq_density > 1) || (csi_params->freq_density == (n%2))) { // for freq density 0.5 checks if even or odd RB - for (int ji=0; jiofdm_symbol_size); // frequency index of current resource element + for (int n = csi_params->start_rb; n < (csi_params->start_rb + csi_params->nr_of_rbs); n++) { + if ((csi_params->freq_density > 1) || (csi_params->freq_density == (n % 2))) { // for freq density 0.5 checks if even or odd RB + for (int ji = 0; ji < size; ji++) { // loop over CDM groups + for (int s = 0 ; s < gs; s++) { // loop over each CDM group size + int p = s + j[ji] * gs; // port index + for (int kp = 0; kp <= kprime; kp++) { // loop over frequency resource elements within a group + // frequency index of current resource element + int k = (start_sc + (n * NR_NB_SC_PER_RB) + koverline[ji] + kp) % (frame_parms->ofdm_symbol_size); // wf according to tables 7.4.5.3-2 to 7.4.5.3-5 - if (kp == 0) - wf = 1; - else - wf = -2*(s%2)+1; - na = n*alpha; - kpn = (rho*koverline[ji])/NR_NB_SC_PER_RB; - mprime = na + kp + kpn; // sequence index - for (lp=0; lp<=lprime; lp++) { // loop over frequency resource elements within a group - l = lp + loverline[ji]; - // wt according to tables 7.4.5.3-2 to 7.4.5.3-5 + int wf = kp == 0 ? 1 : (-2 * (s % 2) + 1); + int na = n * alpha; + int kpn = (rho * koverline[ji]) / NR_NB_SC_PER_RB; + int mprime = na + kp + kpn; // sequence index + for (int lp = 0; lp <= lprime; lp++) { // loop over frequency resource elements within a group + int l = lp + loverline[ji]; + // wt according to tables 7.4.5.3-2 to 7.4.5.3-5 + int wt; if (s < 2) wt = 1; else if (s < 4) - wt = -2*(lp%2)+1; + wt = -2*(lp % 2) + 1; else if (s < 6) - wt = -2*(lp/2)+1; + wt = -2 * (lp / 2) + 1; else { if ((lp == 0) || (lp == 3)) wt = 1; else wt = -1; } - - // ZP CSI RS - if (csi_params->csi_type == 2) { - ((int16_t*)dataF[p])[((l*frame_parms->ofdm_symbol_size + k)<<1)+(2*dataF_offset)] = 0; - ((int16_t*)dataF[p])[((l*frame_parms->ofdm_symbol_size + k)<<1)+1+(2*dataF_offset)] = 0; - } - else { - ((int16_t*)dataF[p])[((l*frame_parms->ofdm_symbol_size + k)<<1)+(2*dataF_offset)] = (beta*wt*wf*mod_csi[l][mprime<<1]) >> 15; - ((int16_t*)dataF[p])[((l*frame_parms->ofdm_symbol_size + k)<<1)+1+(2*dataF_offset)] = (beta*wt*wf*mod_csi[l][(mprime<<1) + 1]) >> 15; - } + int index = ((l * frame_parms->ofdm_symbol_size + k) << 1) + (2 * dataF_offset); + ((int16_t*)dataF[p])[index] = (beta * wt * wf * mod_csi[l][mprime << 1]) >> 15; + ((int16_t*)dataF[p])[index + 1] = (beta * wt * wf * mod_csi[l][(mprime << 1) + 1]) >> 15; #ifdef NR_CSIRS_DEBUG - printf("l,k (%d,%d) seq. index %d \t port %d \t (%d,%d)\n",l,k,mprime,p+3000, - ((int16_t*)dataF[p])[((l*frame_parms->ofdm_symbol_size + k)<<1)+(2*dataF_offset)], - ((int16_t*)dataF[p])[((l*frame_parms->ofdm_symbol_size + k)<<1)+1+(2*dataF_offset)]); + printf("l,k (%d,%d) seq. index %d \t port %d \t (%d,%d)\n", + l, + k, + mprime, + p + 3000, + ((int16_t*)dataF[p])[index], + ((int16_t*)dataF[p])[index + 1]); #endif } } @@ -646,25 +642,4 @@ void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms, } } } - if (N_cdm_groups) *N_cdm_groups = size; - if (CDM_group_size) *CDM_group_size = gs; - if (k_prime) *k_prime = kprime; - if (l_prime) *l_prime = lprime; - if (N_ports) *N_ports = ports; - if (j_cdm) memcpy(j_cdm,j,16*sizeof(uint8_t)); - if (k_overline) memcpy(k_overline,koverline,16*sizeof(uint8_t)); - if (l_overline) memcpy(l_overline,loverline,16*sizeof(uint8_t)); - -#ifdef NR_CSIRS_DEBUG - if (N_ports) LOG_I(NR_PHY, "nr_csi_info->N_ports = %d\n", *N_ports); - if (N_cdm_groups) LOG_I(NR_PHY, "nr_csi_info->N_cdm_groups = %d\n", *N_cdm_groups); - if (CDM_group_size) LOG_I(NR_PHY, "nr_csi_info->CDM_group_size = %d\n", *CDM_group_size); - if (k_prime) LOG_I(NR_PHY, "nr_csi_info->kprime = %d\n", *k_prime); - if (l_prime) LOG_I(NR_PHY, "nr_csi_info->lprime = %d\n", *l_prime); - if (N_cdm_groups) { - for(int ji=0; ji<*N_cdm_groups; ji++) { - LOG_I(NR_PHY, "(CDM group %d) j = %d, koverline = %d, loverline = %d\n", ji, j[ji], koverline[ji], loverline[ji]); - } - } -#endif } diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c index ffea38a6ae..55098f33fa 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c @@ -360,6 +360,7 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, impp.harq = harq; if (gNB->ldpc_offload_flag) { impp.Qm = rel15->qamModOrder[0]; + impp.Tbslbrm = rel15->maintenance_parms_v3.tbSizeLbrmBytes; impp.rv = rel15->rvIndex[0]; int nb_re_dmrs = (rel15->dmrsConfigType == NFAPI_NR_DMRS_TYPE1) ? (6 * rel15->numDmrsCdmGrpsNoData) : (4 * rel15->numDmrsCdmGrpsNoData); @@ -370,13 +371,10 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, harq->unav_res, rel15->qamModOrder[0], rel15->nrOfLayers); - int r_offset = 0; for (int r = 0; r < impp.n_segments; r++) { - impp.E = nr_get_E(impp.G, impp.n_segments, impp.Qm, rel15->nrOfLayers, r); - uint8_t *f = impp.output + r_offset; - ldpc_interface_offload.LDPCencoder(&harq->c[r], &f, &impp); - r_offset += impp.E; + impp.perCB[r].E_cb = nr_get_E(impp.G, impp.n_segments, impp.Qm, rel15->nrOfLayers, r); } + ldpc_interface_offload.LDPCencoder(harq->c, &impp.output, &impp); } else { notifiedFIFO_t nf; initNotifiedFIFO(&nf); diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h index 0f998ebee6..75d77f211a 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h +++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h @@ -310,21 +310,6 @@ void init_prach_ru_list(RU_t *ru); void free_nr_ru_prach_entry(RU_t *ru, int prach_id); uint8_t get_nr_prach_duration(uint8_t prach_format); -void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms, - int32_t **dataF, - const int16_t amp, - nr_csi_info_t *nr_csi_info, - const nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csi_params, - const int slot, - uint8_t *N_cdm_groups, - uint8_t *CDM_group_size, - uint8_t *k_prime, - uint8_t *l_prime, - uint8_t *N_ports, - uint8_t *j_cdm, - uint8_t *k_overline, - uint8_t *l_overline); - void free_nr_prach_entry(PHY_VARS_gNB *gNB, int prach_id); void nr_decode_pucch1(c16_t **rxdataF, diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c index 4c35ee9933..498dae2137 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c @@ -180,6 +180,7 @@ static void nr_processULSegment(void *arg) LOG_E(PHY, "ulsch_decoding.c: Problem in rate_matching\n"); rdata->decodeIterations = max_ldpc_iterations + 1; + set_abort(&ulsch_harq->abort_decode, true); return; } @@ -232,64 +233,60 @@ int decode_offload(PHY_VARS_gNB *phy_vars_gNB, { NR_gNB_ULSCH_t *ulsch = &phy_vars_gNB->ulsch[ULSCH_id]; NR_UL_gNB_HARQ_t *harq_process = ulsch->harq_process; - int16_t z_ol[LDPC_MAX_CB_SIZE] __attribute__((aligned(16))); - int8_t l_ol[LDPC_MAX_CB_SIZE] __attribute__((aligned(16))); - uint8_t Qm = pusch_pdu->qam_mod_order; - uint8_t n_layers = pusch_pdu->nrOfLayers; + int16_t z_ol[NR_LDPC_MAX_NUM_CB * LDPC_MAX_CB_SIZE] __attribute__((aligned(16))); + int8_t l_ol[NR_LDPC_MAX_NUM_CB * LDPC_MAX_CB_SIZE] __attribute__((aligned(16))); + const int kc = decParams->BG == 2 ? 52 : 68; + uint32_t A = (harq_process->TBS) << 3; const int Kr = harq_process->K; const int Kr_bytes = Kr >> 3; - uint32_t A = (harq_process->TBS) << 3; - const int kc = decParams->BG == 2 ? 52 : 68; - ulsch->max_ldpc_iterations = 20; - int decodeIterations = 2; - int r_offset = 0, offset = 0; - for (int r = 0; r < harq_process->C; r++) { - int E = nr_get_E(G, harq_process->C, Qm, n_layers, r); - memset(harq_process->c[r], 0, Kr_bytes); - decParams->R = nr_get_R_ldpc_decoder(pusch_pdu->pusch_data.rv_index, - E, - decParams->BG, - decParams->Z, - &harq_process->llrLen, - harq_process->round); + int8_t decodeIterations = 0; + int r_offset = 0; + int offset = 0; + // new data received, set processedSegments to 0 + if (!decParams->setCombIn) + harq_process->processedSegments = 0; - memcpy(z_ol, ulsch_llr + r_offset, E * sizeof(short)); - simde__m128i *pv_ol128 = (simde__m128i *)&z_ol; - simde__m128i *pl_ol128 = (simde__m128i *)&l_ol; + for (int r = 0; r < harq_process->C; r++) { + decParams->perCB[r].E_cb = nr_get_E(G, harq_process->C, decParams->Qm, pusch_pdu->nrOfLayers, r); + memcpy(&z_ol[offset], ulsch_llr + r_offset, decParams->perCB[r].E_cb * sizeof(*z_ol)); + simde__m128i *pv_ol128 = (simde__m128i *)&z_ol[offset]; + simde__m128i *pl_ol128 = (simde__m128i *)&l_ol[offset]; for (int i = 0, j = 0; j < ((kc * harq_process->Z) >> 4) + 1; i += 2, j++) { pl_ol128[j] = simde_mm_packs_epi16(pv_ol128[i], pv_ol128[i + 1]); } - decParams->E = E; - decParams->rv = pusch_pdu->pusch_data.rv_index; decParams->F = harq_process->F; - decParams->Qm = Qm; - decodeIterations = - ldpc_interface_offload - .LDPCdecoder(decParams, harq_pid, ULSCH_id, r, (int8_t *)&pl_ol128[0], (int8_t *)harq_process->c[r], NULL, NULL); - if (decodeIterations < 0) { - LOG_E(PHY, "ulsch_decoding.c: Problem in LDPC decoder offload\n"); - return -1; - } - bool decodeSuccess = check_crc((uint8_t *)harq_process->c[r], lenWithCrc(harq_process->C, A), crcType(harq_process->C, A)); - if (decodeSuccess) { - memcpy(harq_process->b + offset, harq_process->c[r], Kr_bytes - (harq_process->F >> 3) - ((harq_process->C > 1) ? 3 : 0)); - offset += (Kr_bytes - (harq_process->F >> 3) - ((harq_process->C > 1) ? 3 : 0)); + r_offset += decParams->perCB[r].E_cb; + offset += LDPC_MAX_CB_SIZE; + } + + int8_t p_outDec[harq_process->C * Kr_bytes]; + memset(p_outDec, 0, sizeof(p_outDec)); + decodeIterations = + ldpc_interface_offload.LDPCdecoder(decParams, harq_pid, ULSCH_id, harq_process->C, (int8_t *)l_ol, p_outDec, NULL, NULL); + + if (decodeIterations < 0) { + LOG_E(PHY, "ulsch_decoding.c: Problem in LDPC decoder offload\n"); + return -1; + } + + int offset_b = 0; + for (int r = 0; r < harq_process->C; r++) { + if (decParams->perCB[r].status_cb == 0 || harq_process->C == 1) { + memcpy(harq_process->b + offset_b, &p_outDec[offset_b], Kr_bytes - (harq_process->F >> 3) - ((harq_process->C > 1) ? 3 : 0)); harq_process->processedSegments++; - } else { - LOG_D(PHY, "uplink segment error %d/%d\n", r, harq_process->C); - LOG_D(PHY, "ULSCH %d in error\n", ULSCH_id); } - r_offset += E; + offset_b += (Kr_bytes - (harq_process->F >> 3) - ((harq_process->C > 1) ? 3 : 0)); } + bool crc_valid = false; + // CRC check made by the T2, no need to perform CRC check for a single code block twice if (harq_process->processedSegments == harq_process->C) { - // When the number of code blocks is 1 (C = 1) and ulsch_harq->processedSegments = 1, we can assume a good TB because of the - // CRC check made by the LDPC for early termination, so, no need to perform CRC check twice for a single code block - crc_valid = true; - if (harq_process->C > 1) { - crc_valid = check_crc(harq_process->b, lenWithCrc(1, A), crcType(1, A)); + crc_valid = check_crc(harq_process->b, lenWithCrc(1, A), crcType(1, A)); + if (harq_process->C == 1 && !crc_valid) { + harq_process->processedSegments--; } } + if (crc_valid) { LOG_D(PHY, "ULSCH: Setting ACK for slot %d TBS %d\n", ulsch->slot, harq_process->TBS); nr_fill_indication(phy_vars_gNB, ulsch->frame, ulsch->slot, ULSCH_id, harq_pid, 0, 0); @@ -349,7 +346,6 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, const uint8_t n_layers = pusch_pdu->nrOfLayers; // ------------------------------------------------------------------ - harq_process->processedSegments = 0; harq_process->TBS = pusch_pdu->pusch_data.tb_size; t_nrLDPC_dec_params decParams = {.check_crc = check_crc}; @@ -418,6 +414,8 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, decParams.Z = harq_process->Z; decParams.numMaxIter = ulsch->max_ldpc_iterations; + decParams.Qm = Qm; + decParams.rv = pusch_pdu->pusch_data.rv_index; decParams.outMode = 0; decParams.setCombIn = !harq_process->harq_to_be_cleared; if (harq_process->harq_to_be_cleared) { @@ -428,7 +426,7 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, if (phy_vars_gNB->ldpc_offload_flag) return decode_offload(phy_vars_gNB, ULSCH_id, ulsch_llr, pusch_pdu, &decParams, harq_pid, G); - + harq_process->processedSegments = 0; uint32_t offset = 0, r_offset = 0; set_abort(&harq_process->abort_decode, false); for (int r = 0; r < harq_process->C; r++) { 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 0c3847baaf..89ad4bbc8f 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -28,7 +28,6 @@ #include "PHY/NR_REFSIG/ptrs_nr.h" #include "PHY/NR_REFSIG/nr_mod_table.h" #include "PHY/NR_TRANSPORT/nr_sch_dmrs.h" -#include "PHY/NR_TRANSPORT/nr_transport_proto.h" #include "nr_phy_common.h" #include "filt16a_32.h" #include "T.h" diff --git a/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c b/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c index fbb6113405..180c91f06f 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c +++ b/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c @@ -36,8 +36,8 @@ #include "executables/nr-softmodem-common.h" #include "nr_transport_proto_ue.h" #include "PHY/phy_extern_nr_ue.h" +#include "PHY/NR_REFSIG/nr_refsig.h" #include "common/utils/nr/nr_common.h" -#include "PHY/NR_TRANSPORT/nr_transport_proto.h" #include "PHY/NR_UE_ESTIMATION/filt16a_32.h" // Additional memory allocation, because of applying the filter and the memory offset to ensure memory alignment @@ -191,13 +191,13 @@ int nr_get_csi_rs_signal(const PHY_VARS_NR_UE *ue, int32_t csi_rs_received_signal[][ue->frame_parms.samples_per_slot_wCP], uint32_t *rsrp, int *rsrp_dBm, - c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) { - - const NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; + c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) +{ + const NR_DL_FRAME_PARMS *fp = &ue->frame_parms; uint16_t meas_count = 0; uint32_t rsrp_sum = 0; - for (int ant_rx = 0; ant_rx < frame_parms->nb_antennas_rx; ant_rx++) { + for (int ant_rx = 0; ant_rx < fp->nb_antennas_rx; ant_rx++) { for (int rb = csirs_config_pdu->start_rb; rb < (csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs); rb++) { @@ -212,12 +212,12 @@ int nr_get_csi_rs_signal(const PHY_VARS_NR_UE *ue, // loop over frequency resource elements within a group for (int kp = 0; kp <= k_prime; kp++) { - uint16_t k = (frame_parms->first_carrier_offset + (rb*NR_NB_SC_PER_RB)+k_overline[cdm_id] + kp) % frame_parms->ofdm_symbol_size; + uint16_t k = (fp->first_carrier_offset + (rb * NR_NB_SC_PER_RB) + k_overline[cdm_id] + kp) % fp->ofdm_symbol_size; // loop over time resource elements within a group for (int lp = 0; lp <= l_prime; lp++) { uint16_t symb = lp + l_overline[cdm_id]; - uint64_t symbol_offset = symb*frame_parms->ofdm_symbol_size; + uint64_t symbol_offset = symb * fp->ofdm_symbol_size; c16_t *rx_signal = &rxdataF[ant_rx][symbol_offset]; c16_t *rx_csi_rs_signal = (c16_t*)&csi_rs_received_signal[ant_rx][symbol_offset]; rx_csi_rs_signal[k].r = rx_signal[k].r; @@ -229,10 +229,11 @@ int nr_get_csi_rs_signal(const PHY_VARS_NR_UE *ue, meas_count++; #ifdef NR_CSIRS_DEBUG - int dataF_offset = proc->nr_slot_rx*ue->frame_parms.samples_per_slot_wCP; + int dataF_offset = proc->nr_slot_rx * fp->samples_per_slot_wCP; uint16_t port_tx = s+j_cdm[cdm_id]*CDM_group_size; - c16_t *tx_csi_rs_signal = (c16_t*)&nr_csi_info->csi_rs_generated_signal[port_tx][symbol_offset+dataF_offset]; - LOG_I(NR_PHY, "l,k (%2d,%4d) |\tport_tx %d (%4d,%4d)\tant_rx %d (%4d,%4d)\n", + c16_t *tx_csi_rs_signal = (c16_t*)&nr_csi_info->csi_rs_generated_signal[port_tx][symbol_offset + dataF_offset]; + LOG_I(NR_PHY, + "l,k (%2d,%4d) |\tport_tx %d (%4d,%4d)\tant_rx %d (%4d,%4d)\n", symb, k, port_tx+3000, @@ -728,12 +729,12 @@ int nr_csi_rs_cqi_estimation(const uint32_t precoded_sinr, return 0; } -int nr_csi_im_power_estimation(const PHY_VARS_NR_UE *ue, - const UE_nr_rxtx_proc_t *proc, - const fapi_nr_dl_config_csiim_pdu_rel15_t *csiim_config_pdu, - uint32_t *interference_plus_noise_power, - c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) { - +static void nr_csi_im_power_estimation(const PHY_VARS_NR_UE *ue, + const UE_nr_rxtx_proc_t *proc, + const fapi_nr_dl_config_csiim_pdu_rel15_t *csiim_config_pdu, + uint32_t *interference_plus_noise_power, + c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) +{ const NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; const uint16_t end_rb = csiim_config_pdu->start_rb + csiim_config_pdu->nr_of_rbs > csiim_config_pdu->bwp_size ? @@ -772,7 +773,7 @@ int nr_csi_im_power_estimation(const PHY_VARS_NR_UE *ue, uint16_t sc0_offset = (frame_parms->first_carrier_offset + rb*NR_NB_SC_PER_RB) % frame_parms->ofdm_symbol_size; - for (int sc_idx = 0; sc_idx<4; sc_idx++) { + for (int sc_idx = 0; sc_idx < 4; sc_idx++) { uint16_t sc = sc0_offset + csiim_config_pdu->k_csiim[sc_idx]; if (sc >= frame_parms->ofdm_symbol_size) { @@ -785,34 +786,31 @@ int nr_csi_im_power_estimation(const PHY_VARS_NR_UE *ue, sum_re += rx_signal[sc].r; sum_im += rx_signal[sc].i; - sum2_re += rx_signal[sc].r*rx_signal[sc].r; - sum2_im += rx_signal[sc].i*rx_signal[sc].i; + sum2_re += rx_signal[sc].r * rx_signal[sc].r; + sum2_im += rx_signal[sc].i * rx_signal[sc].i; count++; } } } } - int32_t power_re = sum2_re/count - (sum_re/count)*(sum_re/count); - int32_t power_im = sum2_im/count - (sum_im/count)*(sum_im/count); + int32_t power_re = sum2_re / count - (sum_re / count) * (sum_re / count); + int32_t power_im = sum2_im / count - (sum_im / count) * (sum_im / count); *interference_plus_noise_power = power_re + power_im; #ifdef NR_CSIIM_DEBUG LOG_I(NR_PHY, "interference_plus_noise_power based on CSI-IM = %i\n", *interference_plus_noise_power); #endif - - return 0; } -int nr_ue_csi_im_procedures(PHY_VARS_NR_UE *ue, - const UE_nr_rxtx_proc_t *proc, - c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) +void nr_ue_csi_im_procedures(PHY_VARS_NR_UE *ue, + const UE_nr_rxtx_proc_t *proc, + c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) { int gNB_id = proc->gNB_id; - if(!ue->csiim_vars[gNB_id]->active) { - return -1; - } + if(!ue->csiim_vars[gNB_id]->active) + LOG_E(NR_PHY, "Scheduling reception of CSI-IM that is not active\n"); const fapi_nr_dl_config_csiim_pdu_rel15_t *csiim_config_pdu = (fapi_nr_dl_config_csiim_pdu_rel15_t*)&ue->csiim_vars[gNB_id]->csiim_config_pdu; @@ -828,8 +826,6 @@ int nr_ue_csi_im_procedures(PHY_VARS_NR_UE *ue, nr_csi_im_power_estimation(ue, proc, csiim_config_pdu, &ue->nr_csi_info->interference_plus_noise_power, rxdataF); ue->nr_csi_info->csi_im_meas_computed = true; - - return 0; } static nfapi_nr_dl_tti_csi_rs_pdu_rel15_t convert_csirs_pdu(const fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu) @@ -1004,7 +1000,7 @@ void nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue, switch (csirs_config_pdu->measurement_bitmap) { case 1 : - LOG_I(NR_PHY, "RSRP = %i dBm\n", rsrp_dBm); + LOG_I(NR_PHY, "[UE %d] RSRP = %i dBm\n", ue->Mod_id, rsrp_dBm); break; case 26 : LOG_I(NR_PHY, "RI = %i i1 = %i.%i.%i, i2 = %i, SINR = %i dB, CQI = %i\n", diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c index 1d842e5414..6c57130b3d 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c @@ -119,7 +119,7 @@ static bool nr_ue_postDecode(PHY_VARS_NR_UE *phy_vars_ue, LOG_D(PHY, "DLSCH received nok \n"); return true; //stop } - const int sz=A/8; + const int sz=A / 8; if (b[sz] == 0 && b[sz + 1] == 0) { // We search only a reccuring OAI error that propagates all 0 packets with a 0 CRC, so we // do the check only if the 2 first bytes of the CRC are 0 (it can be CRC16 or CRC24) int i = 0; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index 671764db17..be69351d8f 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -30,7 +30,6 @@ */ #include "PHY/defs_nr_UE.h" #include "PHY/phy_extern.h" -#include "PHY/NR_TRANSPORT/nr_transport_proto.h" #include "nr_transport_proto_ue.h" #include "PHY/sse_intrin.h" #include "T.h" @@ -159,6 +158,7 @@ static void nr_dlsch_extract_rbs(uint32_t rxdataF_sz, uint8_t Nl, NR_DL_FRAME_PARMS *frame_parms, uint16_t dlDmrsSymbPos, + uint32_t csi_res_bitmap, int chest_time_type); static void nr_dlsch_channel_level_median(uint32_t rx_size_symbol, @@ -239,6 +239,82 @@ void nr_dlsch_detection_mrc(uint32_t rx_size_symbol, unsigned short nb_rb, int length); +static bool overlap_csi_symbol(fapi_nr_dl_config_csirs_pdu_rel15_t *csi_pdu, int symbol) +{ + int num_l0 [18] = {1, 1, 1, 1, 2, 1, 2, 2, 1, 2, 2, 2, 2, 2, 4, 2, 2, 4}; + for (int s = 0; s < num_l0[csi_pdu->row - 1]; s++) { + if (symbol == csi_pdu->symb_l0 + s) + return true; + } + // check also l1 if relevant + if (csi_pdu->row == 13 || csi_pdu->row == 14 || csi_pdu->row == 16 || csi_pdu->row == 17) { + for (int s = 0; s < 2; s++) { // two consecutive symbols including l1 + if (symbol == csi_pdu->symb_l1 + s) + return true; + } + } + return false; +} + +static uint32_t build_csi_overlap_bitmap(fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config, int symbol) +{ + // LS 16 bits for even RBs, MS 16 bits for odd RBs + uint32_t csi_res_bitmap = 0; + int num_k[18] = {1, 1, 1, 1, 1, 4, 2, 2, 6, 3, 4, 4, 3, 3, 3, 4, 4, 4}; + for (int i = 0; i < dlsch_config->numCsiRsForRateMatching; i++) { + fapi_nr_dl_config_csirs_pdu_rel15_t *csi_pdu = &dlsch_config->csiRsForRateMatching[i]; + + if (!overlap_csi_symbol(csi_pdu, symbol)) + continue; + + int num_kp = 1; + int mult = 1; + int k0_step = 0; + int num_k0 = 1; + switch (csi_pdu->row) { + case 1: + k0_step = 4; + num_k0 = 3; + break; + case 2: + break; + case 4: + num_kp = 2; + mult = 4; + k0_step = 2; + num_k0 = 2; + break; + default: + num_kp = 2; + mult = 2; + } + int found = 0; + int bit = 0; + uint32_t temp_res_map = 0; + while (found < num_k[csi_pdu->row - 1]) { + if ((csi_pdu->freq_domain >> bit) & 0x01) { + for (int k0 = 0; k0 < num_k0; k0++) { + for (int kp = 0; kp < num_kp; kp++) { + int re = (bit * mult) + (k0 * k0_step) + kp; + temp_res_map |= (1 << re); + } + } + found++; + } + bit++; + AssertFatal(bit < 13, + "Couldn't find %d positive bits in bitmap %d for CSI freq. domain\n", + num_k[csi_pdu->row - 1], + csi_pdu->freq_domain); + } + if (csi_pdu->freq_density < 2) + csi_res_bitmap |= (temp_res_map << (16 * csi_pdu->freq_density)); + else + csi_res_bitmap |= (temp_res_map + (temp_res_map << 16)); + } + return csi_res_bitmap; +} + /* Main Function */ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, @@ -360,10 +436,8 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, return(-1); } - if(symbol > ue->frame_parms.symbols_per_slot>>1) - { - slot = 1; - } + if(symbol > ue->frame_parms.symbols_per_slot >> 1) + slot = 1; uint8_t pilots = (dlsch_config->dlDmrsSymbPos >> symbol) & 1; uint8_t config_type = dlsch_config->dmrsConfigType; @@ -380,6 +454,10 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, __attribute__((aligned(32))) c16_t rxdataF_ext[nbRx][rx_size_symbol]; memset(rxdataF_ext, 0, sizeof(rxdataF_ext)); + uint32_t csi_res_bitmap = build_csi_overlap_bitmap(dlsch_config, symbol); + + LOG_D(PHY, "%d.%d symbol %d csi overlap bitmap %d\n", frame, nr_slot_rx, symbol, csi_res_bitmap); + nr_dlsch_extract_rbs(ue->frame_parms.samples_per_slot_wCP, rxdataF, rx_size_symbol, @@ -396,6 +474,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, nl, frame_parms, dlsch_config->dlDmrsSymbPos, + csi_res_bitmap, ue->chest_time); if (meas_enabled) { stop_meas(&meas); @@ -576,9 +655,22 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, /* Check for PTRS bitmap and process it respectively */ if((pduBitmap & 0x1) && (dlsch[0].rnti_type == TYPE_C_RNTI_)) { - nr_pdsch_ptrs_processing( - ue, nbRx, ptrs_phase_per_slot, ptrs_re_per_slot, rx_size_symbol, rxdataF_comp, frame_parms, dlsch0_harq, dlsch1_harq, gNB_id, nr_slot_rx, symbol, (nb_rb_pdsch * 12), dlsch[0].rnti, dlsch); - dl_valid_re[symbol-1] -= ptrs_re_per_slot[0][symbol]; + nr_pdsch_ptrs_processing(ue, + nbRx, + ptrs_phase_per_slot, + ptrs_re_per_slot, + rx_size_symbol, + rxdataF_comp, + frame_parms, + dlsch0_harq, + dlsch1_harq, + gNB_id, + nr_slot_rx, + symbol, + (nb_rb_pdsch * 12), + dlsch[0].rnti, + dlsch); + dl_valid_re[symbol - 1] -= ptrs_re_per_slot[0][symbol]; } /* at last symbol in a slot calculate LLR's for whole slot */ if(symbol == (startSymbIdx + nbSymb -1)) { @@ -1099,15 +1191,30 @@ static void nr_dlsch_extract_rbs(uint32_t rxdataF_sz, uint8_t Nl, NR_DL_FRAME_PARMS *frame_parms, uint16_t dlDmrsSymbPos, + uint32_t csi_res_bitmap, int chest_time_type) { - if (config_type == NFAPI_NR_DMRS_TYPE1) { - AssertFatal(n_dmrs_cdm_groups == 1 || n_dmrs_cdm_groups == 2, - "n_dmrs_cdm_groups %d is illegal\n",n_dmrs_cdm_groups); - } else { + if (config_type == NFAPI_NR_DMRS_TYPE1) + AssertFatal(n_dmrs_cdm_groups == 1 || n_dmrs_cdm_groups == 2, "n_dmrs_cdm_groups %d is illegal\n",n_dmrs_cdm_groups); + else AssertFatal(n_dmrs_cdm_groups == 1 || n_dmrs_cdm_groups == 2 || n_dmrs_cdm_groups == 3, "n_dmrs_cdm_groups %d is illegal\n",n_dmrs_cdm_groups); - } + + uint32_t dmrs_rb_bitmap = 0xfff; // all REs taken by dmrs + if (config_type == NFAPI_NR_DMRS_TYPE1 && n_dmrs_cdm_groups == 1) + dmrs_rb_bitmap = 0x555; // alternating REs starting from 0 + if (config_type == NFAPI_NR_DMRS_TYPE2 && n_dmrs_cdm_groups == 1) + dmrs_rb_bitmap = 0xc3; // REs 0,1 and 6,7 + if (config_type == NFAPI_NR_DMRS_TYPE2 && n_dmrs_cdm_groups == 2) + dmrs_rb_bitmap = 0x3cf; // REs 0,1,2,3 and 6,7,8,9 + + // csi_res_bitmap LS 16 bits for even RBs, MS 16 bits for odd RBs + uint32_t csi_res_even = csi_res_bitmap & 0xfff; + uint32_t csi_res_odd = (csi_res_bitmap >> 16) & 0xfff; + AssertFatal((dmrs_rb_bitmap & csi_res_even) == 0, "DMRS RE overlapping with CSI RE, it shouldn't happen\n"); + AssertFatal((dmrs_rb_bitmap & csi_res_odd) == 0, "DMRS RE overlapping with CSI RE, it shouldn't happen\n"); + uint32_t dmrs_csi_overlap_even = csi_res_even + dmrs_rb_bitmap; + uint32_t dmrs_csi_overlap_odd = csi_res_odd + dmrs_rb_bitmap; const unsigned short start_re = (frame_parms->first_carrier_offset + start_rb * NR_NB_SC_PER_RB) % frame_parms->ofdm_symbol_size; int8_t validDmrsEst; @@ -1126,7 +1233,7 @@ static void nr_dlsch_extract_rbs(uint32_t rxdataF_sz, int32_t *dl_ch0 = &dl_ch_estimates[(l * frame_parms->nb_antennas_rx) + aarx][validDmrsEst * frame_parms->ofdm_symbol_size]; int32_t *dl_ch0_ext = dl_ch_estimates_ext[(l * frame_parms->nb_antennas_rx) + aarx]; - if (pilots == 0) { //data symbol only + if (pilots == 0 && csi_res_bitmap == 0) { // data symbol only if (l == 0) { if (start_re + nb_rb_pdsch * NR_NB_SC_PER_RB <= frame_parms->ofdm_symbol_size) { memcpy(rxF_ext, &rxF[start_re], nb_rb_pdsch * NR_NB_SC_PER_RB * sizeof(int32_t)); @@ -1139,65 +1246,24 @@ static void nr_dlsch_extract_rbs(uint32_t rxdataF_sz, } memcpy(dl_ch0_ext, dl_ch0, nb_rb_pdsch * NR_NB_SC_PER_RB * sizeof(int32_t)); } - else if (config_type == NFAPI_NR_DMRS_TYPE1){ - if (n_dmrs_cdm_groups == 1) { //data is multiplexed - if (l == 0) { - unsigned short k = start_re; - for (unsigned short j = 0; j < 6*nb_rb_pdsch; j += 3) { - rxF_ext[j] = rxF[k+1]; - rxF_ext[j+1] = rxF[k+3]; - rxF_ext[j+2] = rxF[k+5]; - k += 6; - if (k >= frame_parms->ofdm_symbol_size) - k -= frame_parms->ofdm_symbol_size; + else { + int j = 0; + int k = start_re; + for (int rb = 0; rb < nb_rb_pdsch; rb++) { + uint32_t overlap_map = rb % 2 ? dmrs_csi_overlap_odd : dmrs_csi_overlap_even; + for (int re = 0; re < 12; re++) { + if (((overlap_map >> re) & 0x01) == 0) { + // DATA RE + if (l == 0) + rxF_ext[j] = rxF[k]; + dl_ch0_ext[j] = dl_ch0[re]; + j++; } + k++; + if (k >= frame_parms->ofdm_symbol_size) + k -= frame_parms->ofdm_symbol_size; } - for (unsigned short j = 0; j < 6*nb_rb_pdsch; j += 3) { - dl_ch0_ext[j] = dl_ch0[1]; - dl_ch0_ext[j+1] = dl_ch0[3]; - dl_ch0_ext[j+2] = dl_ch0[5]; - dl_ch0 += 6; - } - } - } - else {//NFAPI_NR_DMRS_TYPE2 - if (n_dmrs_cdm_groups == 1) { //data is multiplexed - if (l == 0) { - unsigned short k = start_re; - for (unsigned short j = 0; j < 8*nb_rb_pdsch; j += 4) { - rxF_ext[j] = rxF[k+2]; - rxF_ext[j+1] = rxF[k+3]; - rxF_ext[j+2] = rxF[k+4]; - rxF_ext[j+3] = rxF[k+5]; - k += 6; - if (k >= frame_parms->ofdm_symbol_size) - k -= frame_parms->ofdm_symbol_size; - } - } - for (unsigned short j = 0; j < 8*nb_rb_pdsch; j += 4) { - dl_ch0_ext[j] = dl_ch0[2]; - dl_ch0_ext[j+1] = dl_ch0[3]; - dl_ch0_ext[j+2] = dl_ch0[4]; - dl_ch0_ext[j+3] = dl_ch0[5]; - dl_ch0 += 6; - } - } - else if (n_dmrs_cdm_groups == 2) { //data is multiplexed - if (l == 0) { - unsigned short k = start_re; - for (unsigned short j = 0; j < 4*nb_rb_pdsch; j += 2) { - rxF_ext[j] = rxF[k+4]; - rxF_ext[j+1] = rxF[k+5]; - k += 6; - if (k >= frame_parms->ofdm_symbol_size) - k -= frame_parms->ofdm_symbol_size; - } - } - for (unsigned short j = 0; j < 4*nb_rb_pdsch; j += 2) { - dl_ch0_ext[j] = dl_ch0[4]; - dl_ch0_ext[j+1] = dl_ch0[5]; - dl_ch0 += 6; - } + dl_ch0 += 12; } } } diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c index ea2d6cec79..1d7a8fd6d8 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c @@ -151,16 +151,13 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue, start_meas(&ue->ulsch_ldpc_encoding_stats); if (ldpc_interface_offload.LDPCencoder) { for (int j = 0; j < impp.n_segments; j++) { - impp.E = nr_get_E(G, impp.n_segments, impp.Qm, ulsch->pusch_pdu.nrOfLayers, j); - uint8_t *f = harq_process->f + r_offset; - ldpc_interface_offload.LDPCencoder(&harq_process->c[j], &f, &impp); - r_offset += impp.E; + impp.perCB[j].E_cb = nr_get_E(G, impp.n_segments, impp.Qm, ulsch->pusch_pdu.nrOfLayers, j); } + ldpc_interface_offload.LDPCencoder(harq_process->c, &harq_process->f, &impp); } else { if (ulsch->pusch_pdu.pusch_data.new_data_indicator) { for (int j = 0; j < (impp.n_segments / 8 + 1); j++) { impp.macro_num = j; - impp.E = nr_get_E(G, impp.n_segments, impp.Qm, ulsch->pusch_pdu.nrOfLayers, j); impp.Kr = impp.K; ldpc_interface.LDPCencoder(harq_process->c, harq_process->d, &impp); } @@ -191,7 +188,7 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue, ulsch->pusch_pdu.pusch_data.rv_index); ///////////////////////// d---->| Rate matching bit selection |---->e ///////////////////////// - impp.E = nr_get_E(G, impp.n_segments, impp.Qm, ulsch->pusch_pdu.nrOfLayers, r); + impp.perCB[r].E_cb = nr_get_E(G, impp.n_segments, impp.Qm, ulsch->pusch_pdu.nrOfLayers, r); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_RATE_MATCHING_LDPC, VCD_FUNCTION_IN); start_meas(&ue->ulsch_rate_matching_stats); @@ -204,7 +201,8 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue, impp.F, impp.Kr - impp.F - 2 * impp.Zc, impp.rv, - impp.E) == -1) + impp.perCB[r].E_cb) + == -1) return -1; stop_meas(&ue->ulsch_rate_matching_stats); @@ -218,10 +216,7 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue, ///////////////////////// e---->| Rate matching bit interleaving |---->f ///////////////////////// VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_INTERLEAVING_LDPC, VCD_FUNCTION_IN); start_meas(&ue->ulsch_interleaving_stats); - nr_interleaving_ldpc(impp.E, - impp.Qm, - harq_process->e + r_offset, - harq_process->f + r_offset); + nr_interleaving_ldpc(impp.perCB[r].E_cb, impp.Qm, harq_process->e + r_offset, harq_process->f + r_offset); stop_meas(&ue->ulsch_interleaving_stats); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_INTERLEAVING_LDPC, VCD_FUNCTION_OUT); @@ -231,7 +226,7 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue, if (r == impp.n_segments - 1) write_output("enc_output.m","enc", harq_process->f, G, 1, 4); #endif - r_offset += impp.E; + r_offset += impp.perCB[r].E_cb; } } /////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index 38f840526c..70b0dc041f 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -510,6 +510,7 @@ typedef struct PHY_VARS_NR_UE_s { uint8_t max_ldpc_iterations; + int ldpc_offload_enable; /// SRS variables nr_srs_info_t *nr_srs_info; diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 8b9134f4a0..a12d203ae7 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -276,10 +276,12 @@ static void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req) bool decodeSuccess = (rdata->decodeIterations <= rdata->decoderParms.numMaxIter); ulsch_harq->processedSegments++; LOG_D(PHY, - "processing result of segment: %d, processed %d/%d\n", + "processing result of segment: %d, processed %d/%d, %s\n", rdata->segment_r, ulsch_harq->processedSegments, - rdata->nbSegments); + rdata->nbSegments, + decodeSuccess ? "Decoded Successfully" : "Decoding Unsuccessful"); + if (decodeSuccess) { memcpy(ulsch_harq->b + rdata->offset, ulsch_harq->c[r], rdata->Kr_bytes - (ulsch_harq->F >> 3) - ((ulsch_harq->C > 1) ? 3 : 0)); @@ -466,11 +468,16 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id, // put timing advance command in 0..63 range timing_advance_update += 31; + timing_advance_update = max(timing_advance_update, 0); + timing_advance_update = min(timing_advance_update, 63); - if (timing_advance_update < 0) timing_advance_update = 0; - if (timing_advance_update > 63) timing_advance_update = 63; - - if (crc_flag == 0) LOG_D(PHY, "%d.%d : Received PUSCH : Estimated timing advance PUSCH is = %d, timing_advance_update is %d \n", frame,slot_rx,sync_pos,timing_advance_update); + if (crc_flag == 0) + LOG_D(PHY, + "%d.%d : Received PUSCH : Estimated timing advance PUSCH is = %d, timing_advance_update is %d \n", + frame, + slot_rx, + sync_pos, + timing_advance_update); // estimate UL_CQI for MAC int SNRtimes10 = diff --git a/openair1/SCHED_NR_UE/defs.h b/openair1/SCHED_NR_UE/defs.h index 785aa409cb..4174e44238 100644 --- a/openair1/SCHED_NR_UE/defs.h +++ b/openair1/SCHED_NR_UE/defs.h @@ -149,9 +149,9 @@ int nr_ue_pdcch_procedures(PHY_VARS_NR_UE *ue, int n_ss, c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]); -int nr_ue_csi_im_procedures(PHY_VARS_NR_UE *ue, - const UE_nr_rxtx_proc_t *proc, - c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]); +void nr_ue_csi_im_procedures(PHY_VARS_NR_UE *ue, + const UE_nr_rxtx_proc_t *proc, + c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]); void nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index d3ce92da26..cfb52f3266 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -637,6 +637,54 @@ static void send_dl_done_to_tx_thread(notifiedFIFO_t *nf, int rx_slot) } } +static uint32_t compute_csi_rm_unav_res(fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config) +{ + uint32_t unav_res = 0; + for (int i = 0; i < dlsch_config->numCsiRsForRateMatching; i++) { + fapi_nr_dl_config_csirs_pdu_rel15_t *csi_pdu = &dlsch_config->csiRsForRateMatching[i]; + // check overlapping symbols + int num_overlap_symb = 0; + // num of consecutive csi symbols from l0 included + int num_l0 [18] = {1, 1, 1, 1, 2, 1, 2, 2, 1, 2, 2, 2, 2, 2, 4, 2, 2, 4}; + int num_symb = num_l0[csi_pdu->row - 1]; + for (int s = 0; s < num_symb; s++) { + int l0_symb = csi_pdu->symb_l0 + s; + if (l0_symb >= dlsch_config->start_symbol && l0_symb <= dlsch_config->start_symbol + dlsch_config->number_symbols) + num_overlap_symb++; + } + // check also l1 if relevant + if (csi_pdu->row == 13 || csi_pdu->row == 14 || csi_pdu->row == 16 || csi_pdu->row == 17) { + num_symb += 2; + for (int s = 0; s < 2; s++) { // two consecutive symbols including l1 + int l1_symb = csi_pdu->symb_l1 + s; + if (l1_symb >= dlsch_config->start_symbol && l1_symb <= dlsch_config->start_symbol + dlsch_config->number_symbols) + num_overlap_symb++; + } + } + if (num_overlap_symb == 0) + continue; + // check number overlapping prbs + // assuming CSI is spanning the whole BW + AssertFatal(dlsch_config->BWPSize <= csi_pdu->nr_of_rbs, "Assuming CSI-RS is spanning the whold BWP this shouldn't happen\n"); + int dlsch_start = dlsch_config->start_rb + dlsch_config->BWPStart; + int num_overlapping_prbs = dlsch_config->number_rbs; + if (num_overlapping_prbs < 1) + continue; // no overlapping prbs + if (csi_pdu->freq_density < 2) { // 0.5 density + num_overlapping_prbs /= 2; + // odd number of prbs and the start PRB is even/odd when CSI is in even/odd PRBs + if ((num_overlapping_prbs % 2) && ((dlsch_start % 2) == csi_pdu->freq_density)) + num_overlapping_prbs += 1; + } + // density is number or res per port per rb (over all symbols) + int ports [18] = {1, 1, 2, 4, 4, 8, 8, 8, 12, 12, 16, 16, 24, 24, 24, 32, 32, 32}; + int num_csi_res_per_prb = csi_pdu->freq_density == 3 ? 3 : 1; + num_csi_res_per_prb *= ports[csi_pdu->row - 1]; + unav_res += num_overlapping_prbs * num_csi_res_per_prb * num_overlap_symb / num_symb; + } + return unav_res; +} + static bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, NR_UE_DLSCH_t dlsch[2], @@ -771,10 +819,10 @@ static bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, int ptrsSymbPerSlot = get_ptrs_symbols_in_slot(ptrsSymbPos, dlsch_config->start_symbol, dlsch_config->number_symbols); unav_res = n_ptrs * ptrsSymbPerSlot; } - int G1 = - nr_get_G(dlsch_config->number_rbs, nb_symb_sch, nb_re_dmrs, dmrs_len, unav_res, dlsch_config->qamModOrder, dlsch[1].Nl); + unav_res += compute_csi_rm_unav_res(dlsch_config); + G = nr_get_G(dlsch_config->number_rbs, nb_symb_sch, nb_re_dmrs, dmrs_len, unav_res, dlsch_config->qamModOrder, dlsch[1].Nl); start_meas(&ue->dlsch_unscrambling_stats); - nr_dlsch_unscrambling(llr[1], G1, 0, dlsch[1].dlsch_config.dlDataScramblingId, dlsch[1].rnti); + nr_dlsch_unscrambling(llr[1], G, 0, dlsch[1].dlsch_config.dlDataScramblingId, dlsch[1].rnti); stop_meas(&ue->dlsch_unscrambling_stats); start_meas(&ue->dlsch_decoding_stats); @@ -797,12 +845,14 @@ static bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, stop_meas(&ue->dlsch_decoding_stats); if (cpumeas(CPUMEAS_GETSTATE)) { - LOG_D(PHY, " --> Unscrambling for CW1 %5.3f\n", - (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0)); - LOG_D(PHY, "AbsSubframe %d.%d --> ldpc Decoding for CW1 %5.3f\n", - frame_rx%1024, nr_slot_rx,(ue->dlsch_decoding_stats.p_time)/(cpuf*1000.0)); - } - LOG_D(PHY, "harq_pid: %d, TBS expected dlsch1: %d \n", harq_pid, dlsch[1].dlsch_config.TBS); + LOG_D(PHY, " --> Unscrambling for CW1 %5.3f\n", (ue->dlsch_unscrambling_stats.p_time) / (cpuf * 1000.0)); + LOG_D(PHY, + "AbsSubframe %d.%d --> ldpc Decoding for CW1 %5.3f\n", + frame_rx % 1024, + nr_slot_rx, + (ue->dlsch_decoding_stats.p_time) / (cpuf * 1000.0)); + } + LOG_D(PHY, "harq_pid: %d, TBS expected dlsch1: %d \n", harq_pid, dlsch[1].dlsch_config.TBS); } // send to mac @@ -944,7 +994,7 @@ int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_ char output[harq_output_len]; char *p = output; const char *end = output + harq_output_len; - p += snprintf(p, end - p, "Harq round stats for Downlink: %d", ue->dl_stats[0]); + p += snprintf(p, end - p, "[UE %d] Harq round stats for Downlink: %d", ue->Mod_id, ue->dl_stats[0]); for (int round = 1; round < 16 && (round < 3 || ue->dl_stats[round] != 0); ++round) p += snprintf(p, end - p,"/%d", ue->dl_stats[round]); LOG_I(NR_PHY,"%s\n", output); @@ -1004,24 +1054,50 @@ void pdsch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_ start_meas(&meas); // do procedures for C-RNTI + bool slot_fep_map[14] = {0}; const uint32_t rxdataF_sz = ue->frame_parms.samples_per_slot_wCP; __attribute__ ((aligned(32))) c16_t rxdataF[ue->frame_parms.nb_antennas_rx][rxdataF_sz]; + + // do procedures for CSI-IM + if ((ue->csiim_vars[gNB_id]) && (ue->csiim_vars[gNB_id]->active == 1)) { + for(int symb_idx = 0; symb_idx < 4; symb_idx++) { + int symb = ue->csiim_vars[gNB_id]->csiim_config_pdu.l_csiim[symb_idx]; + if (!slot_fep_map[symb]) { + nr_slot_fep(ue, &ue->frame_parms, proc, symb, rxdataF, link_type_dl); + slot_fep_map[symb] = true; + } + } + nr_ue_csi_im_procedures(ue, proc, rxdataF); + ue->csiim_vars[gNB_id]->active = 0; + } + + // do procedures for CSI-RS + if ((ue->csirs_vars[gNB_id]) && (ue->csirs_vars[gNB_id]->active == 1)) { + for(int symb = 0; symb < NR_SYMBOLS_PER_SLOT; symb++) { + if(is_csi_rs_in_symbol(ue->csirs_vars[gNB_id]->csirs_config_pdu, symb)) { + if (!slot_fep_map[symb]) { + nr_slot_fep(ue, &ue->frame_parms, proc, symb, rxdataF, link_type_dl); + slot_fep_map[symb] = true; + } + } + } + nr_ue_csi_rs_procedures(ue, proc, rxdataF); + ue->csirs_vars[gNB_id]->active = 0; + } + if (dlsch[0].active) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDSCH, VCD_FUNCTION_IN); fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config = &dlsch[0].dlsch_config; uint16_t nb_symb_sch = dlsch_config->number_symbols; uint16_t start_symb_sch = dlsch_config->start_symbol; - LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR Frame.slot %d.%d ------ \n", frame_rx%1024, nr_slot_rx); - //to update from pdsch config + LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR Frame.slot %d.%d ------ \n", frame_rx % 1024, nr_slot_rx); - for (uint16_t m=start_symb_sch;m<(nb_symb_sch+start_symb_sch) ; m++){ - nr_slot_fep(ue, - &ue->frame_parms, - proc, - m, // to be updated from higher layer - rxdataF, - link_type_dl); + for (int m = start_symb_sch; m < (nb_symb_sch + start_symb_sch) ; m++) { + if (!slot_fep_map[m]) { + nr_slot_fep(ue, &ue->frame_parms, proc, m, rxdataF, link_type_dl); + slot_fep_map[m] = true; + } } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDSCH, VCD_FUNCTION_OUT); @@ -1045,6 +1121,7 @@ void pdsch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_ int ptrsSymbPerSlot = get_ptrs_symbols_in_slot(ptrsSymbPos, dlsch_config->start_symbol, dlsch_config->number_symbols); unav_res = n_ptrs * ptrsSymbPerSlot; } + unav_res += compute_csi_rm_unav_res(dlsch_config); int G = nr_get_G(dlsch_config->number_rbs, dlsch_config->number_symbols, nb_re_dmrs, @@ -1097,36 +1174,6 @@ void pdsch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_ free(llr[i]); } - // do procedures for CSI-IM - if ((ue->csiim_vars[gNB_id]) && (ue->csiim_vars[gNB_id]->active == 1)) { - int l_csiim[4] = {-1, -1, -1, -1}; - for(int symb_idx = 0; symb_idx < 4; symb_idx++) { - bool nr_slot_fep_done = false; - for (int symb_idx2 = 0; symb_idx2 < symb_idx; symb_idx2++) { - if (l_csiim[symb_idx2] == ue->csiim_vars[gNB_id]->csiim_config_pdu.l_csiim[symb_idx]) { - nr_slot_fep_done = true; - } - } - l_csiim[symb_idx] = ue->csiim_vars[gNB_id]->csiim_config_pdu.l_csiim[symb_idx]; - if(nr_slot_fep_done == false) { - nr_slot_fep(ue, &ue->frame_parms, proc, ue->csiim_vars[gNB_id]->csiim_config_pdu.l_csiim[symb_idx], rxdataF, link_type_dl); - } - } - nr_ue_csi_im_procedures(ue, proc, rxdataF); - ue->csiim_vars[gNB_id]->active = 0; - } - - // do procedures for CSI-RS - if ((ue->csirs_vars[gNB_id]) && (ue->csirs_vars[gNB_id]->active == 1)) { - for(int symb = 0; symb < NR_SYMBOLS_PER_SLOT; symb++) { - if(is_csi_rs_in_symbol(ue->csirs_vars[gNB_id]->csirs_config_pdu,symb)) { - nr_slot_fep(ue, &ue->frame_parms, proc, symb, rxdataF, link_type_dl); - } - } - nr_ue_csi_rs_procedures(ue, proc, rxdataF); - ue->csirs_vars[gNB_id]->active = 0; - } - start_meas(&meas); if (nr_slot_rx==9) { diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index 1f043728a1..b91da1152b 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -5218,7 +5218,7 @@ bool supported_bw_comparison(int bw_mhz, NR_SupportedBandwidth_t *supported_BW, return false; } -uint32_t compute_PDU_length(uint32_t num_TLV, uint16_t total_length) +uint32_t compute_PDU_length(uint32_t num_TLV, uint32_t total_length) { uint32_t pdu_length = 8; // 2 bytes PDU_Length + 2 bytes PDU_Index + 4 bytes num_TLV // For each TLV, add 2 bytes tag + 2 bytes length + value size without padding diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h index 32c8242f35..e809c3e521 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h @@ -311,7 +311,7 @@ void compute_csi_bitlen(const NR_CSI_MeasConfig_t *csi_MeasConfig, nr_csi_report uint16_t nr_get_csi_bitlen(nr_csi_report_t *csi_report); -uint32_t compute_PDU_length(uint32_t num_TLV, uint16_t total_length); +uint32_t compute_PDU_length(uint32_t num_TLV, uint32_t total_length); rnti_t nr_get_ra_rnti(uint8_t s_id, uint8_t t_id, uint8_t f_id, uint8_t ul_carrier_id); diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index 50577fc4f7..d8b1ac158d 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -250,7 +250,7 @@ static void config_common_ue(NR_UE_MAC_INST_t *mac, mac->phy_config.CC_id = cc_idP; // carrier config - LOG_D(MAC, "Entering UE Config Common\n"); + LOG_D(MAC, "[UE %d] Entering UE Config Common\n", mac->ue_id); AssertFatal(scc->downlinkConfigCommon, "Not expecting downlinkConfigCommon to be NULL here\n"); @@ -965,6 +965,73 @@ static void setup_puschconfig(NR_PUSCH_Config_t *source, NR_PUSCH_Config_t *targ } } +static void configure_csi_resourcemapping(NR_CSI_RS_ResourceMapping_t *target, NR_CSI_RS_ResourceMapping_t *source) +{ + if (target->frequencyDomainAllocation.present != source->frequencyDomainAllocation.present) { + UPDATE_NP_IE(target->frequencyDomainAllocation, + source->frequencyDomainAllocation, + struct NR_CSI_RS_ResourceMapping__frequencyDomainAllocation); + } + else { + switch (source->frequencyDomainAllocation.present) { + case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row1: + target->frequencyDomainAllocation.choice.row1.size = source->frequencyDomainAllocation.choice.row1.size; + target->frequencyDomainAllocation.choice.row1.bits_unused = source->frequencyDomainAllocation.choice.row1.bits_unused; + if (!target->frequencyDomainAllocation.choice.row1.buf) + target->frequencyDomainAllocation.choice.row1.buf = + calloc(target->frequencyDomainAllocation.choice.row1.size, sizeof(uint8_t)); + for (int i = 0; i < target->frequencyDomainAllocation.choice.row1.size; i++) + target->frequencyDomainAllocation.choice.row1.buf[i] = source->frequencyDomainAllocation.choice.row1.buf[i]; + break; + case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row2: + target->frequencyDomainAllocation.choice.row2.size = source->frequencyDomainAllocation.choice.row2.size; + target->frequencyDomainAllocation.choice.row2.bits_unused = source->frequencyDomainAllocation.choice.row2.bits_unused; + if (!target->frequencyDomainAllocation.choice.row2.buf) + target->frequencyDomainAllocation.choice.row2.buf = + calloc(target->frequencyDomainAllocation.choice.row2.size, sizeof(uint8_t)); + for (int i = 0; i < target->frequencyDomainAllocation.choice.row2.size; i++) + target->frequencyDomainAllocation.choice.row2.buf[i] = source->frequencyDomainAllocation.choice.row2.buf[i]; + break; + case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row4: + target->frequencyDomainAllocation.choice.row4.size = source->frequencyDomainAllocation.choice.row4.size; + target->frequencyDomainAllocation.choice.row4.bits_unused = source->frequencyDomainAllocation.choice.row4.bits_unused; + if (!target->frequencyDomainAllocation.choice.row4.buf) + target->frequencyDomainAllocation.choice.row4.buf = + calloc(target->frequencyDomainAllocation.choice.row4.size, sizeof(uint8_t)); + for (int i = 0; i < target->frequencyDomainAllocation.choice.row4.size; i++) + target->frequencyDomainAllocation.choice.row4.buf[i] = source->frequencyDomainAllocation.choice.row4.buf[i]; + break; + case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_other: + target->frequencyDomainAllocation.choice.other.size = source->frequencyDomainAllocation.choice.other.size; + target->frequencyDomainAllocation.choice.other.bits_unused = source->frequencyDomainAllocation.choice.other.bits_unused; + if (!target->frequencyDomainAllocation.choice.other.buf) + target->frequencyDomainAllocation.choice.other.buf = + calloc(target->frequencyDomainAllocation.choice.other.size, sizeof(uint8_t)); + for (int i = 0; i < target->frequencyDomainAllocation.choice.other.size; i++) + target->frequencyDomainAllocation.choice.other.buf[i] = source->frequencyDomainAllocation.choice.other.buf[i]; + break; + default: + AssertFatal(false, "Invalid entry\n"); + } + } + target->nrofPorts = source->nrofPorts; + target->firstOFDMSymbolInTimeDomain = source->firstOFDMSymbolInTimeDomain; + UPDATE_IE(target->firstOFDMSymbolInTimeDomain2, source->firstOFDMSymbolInTimeDomain2, long); + target->cdm_Type = source->cdm_Type; + target->density = source->density; + target->freqBand = source->freqBand; +} + +static void config_zp_CSI_RS_Resource(NR_ZP_CSI_RS_Resource_t *target, NR_ZP_CSI_RS_Resource_t *source) +{ + target->zp_CSI_RS_ResourceId = source->zp_CSI_RS_ResourceId; + configure_csi_resourcemapping(&target->resourceMapping, &source->resourceMapping); + if (source->periodicityAndOffset) + UPDATE_IE(target->periodicityAndOffset, + source->periodicityAndOffset, + NR_CSI_ResourcePeriodicityAndOffset_t); +} + static void setup_pdschconfig(NR_PDSCH_Config_t *source, NR_PDSCH_Config_t *target) { UPDATE_IE(target->dataScramblingIdentityPDSCH, source->dataScramblingIdentityPDSCH, long); @@ -1022,7 +1089,25 @@ static void setup_pdschconfig(NR_PDSCH_Config_t *source, NR_PDSCH_Config_t *targ UPDATE_IE(target->mcs_Table, source->mcs_Table, long); UPDATE_IE(target->maxNrofCodeWordsScheduledByDCI, source->maxNrofCodeWordsScheduledByDCI, long); UPDATE_NP_IE(target->prb_BundlingType, source->prb_BundlingType, struct NR_PDSCH_Config__prb_BundlingType); - AssertFatal(source->zp_CSI_RS_ResourceToAddModList == NULL, "Not handled\n"); + if (source->zp_CSI_RS_ResourceToAddModList) { + if (!target->zp_CSI_RS_ResourceToAddModList) + target->zp_CSI_RS_ResourceToAddModList = calloc(1, sizeof(*target->zp_CSI_RS_ResourceToAddModList)); + ADDMOD_IE_FROMLIST_WFUNCTION(source->zp_CSI_RS_ResourceToAddModList, + target->zp_CSI_RS_ResourceToAddModList, + zp_CSI_RS_ResourceId, + NR_ZP_CSI_RS_Resource_t, + config_zp_CSI_RS_Resource); + } + if (source->zp_CSI_RS_ResourceToReleaseList) { + RELEASE_IE_FROMLIST(source->zp_CSI_RS_ResourceToReleaseList, + target->zp_CSI_RS_ResourceToAddModList, + zp_CSI_RS_ResourceId); + } + if (source->p_ZP_CSI_RS_ResourceSet) + HANDLE_SETUPRELEASE_IE(target->p_ZP_CSI_RS_ResourceSet, + source->p_ZP_CSI_RS_ResourceSet, + NR_ZP_CSI_RS_ResourceSet_t, + asn_DEF_NR_ZP_CSI_RS_ResourceSet); AssertFatal(source->aperiodic_ZP_CSI_RS_ResourceSetsToAddModList == NULL, "Not handled\n"); AssertFatal(source->sp_ZP_CSI_RS_ResourceSetsToAddModList == NULL, "Not handled\n"); } @@ -1750,63 +1835,6 @@ static void configure_maccellgroup(NR_UE_MAC_INST_t *mac, const NR_MAC_CellGroup } } -static void configure_csi_resourcemapping(NR_CSI_RS_ResourceMapping_t *target, NR_CSI_RS_ResourceMapping_t *source) -{ - if (target->frequencyDomainAllocation.present != source->frequencyDomainAllocation.present) { - UPDATE_NP_IE(target->frequencyDomainAllocation, - source->frequencyDomainAllocation, - struct NR_CSI_RS_ResourceMapping__frequencyDomainAllocation); - } - else { - switch (source->frequencyDomainAllocation.present) { - case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row1: - target->frequencyDomainAllocation.choice.row1.size = source->frequencyDomainAllocation.choice.row1.size; - target->frequencyDomainAllocation.choice.row1.bits_unused = source->frequencyDomainAllocation.choice.row1.bits_unused; - if (!target->frequencyDomainAllocation.choice.row1.buf) - target->frequencyDomainAllocation.choice.row1.buf = - calloc(target->frequencyDomainAllocation.choice.row1.size, sizeof(uint8_t)); - for (int i = 0; i < target->frequencyDomainAllocation.choice.row1.size; i++) - target->frequencyDomainAllocation.choice.row1.buf[i] = source->frequencyDomainAllocation.choice.row1.buf[i]; - break; - case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row2: - target->frequencyDomainAllocation.choice.row2.size = source->frequencyDomainAllocation.choice.row2.size; - target->frequencyDomainAllocation.choice.row2.bits_unused = source->frequencyDomainAllocation.choice.row2.bits_unused; - if (!target->frequencyDomainAllocation.choice.row2.buf) - target->frequencyDomainAllocation.choice.row2.buf = - calloc(target->frequencyDomainAllocation.choice.row2.size, sizeof(uint8_t)); - for (int i = 0; i < target->frequencyDomainAllocation.choice.row2.size; i++) - target->frequencyDomainAllocation.choice.row2.buf[i] = source->frequencyDomainAllocation.choice.row2.buf[i]; - break; - case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row4: - target->frequencyDomainAllocation.choice.row4.size = source->frequencyDomainAllocation.choice.row4.size; - target->frequencyDomainAllocation.choice.row4.bits_unused = source->frequencyDomainAllocation.choice.row4.bits_unused; - if (!target->frequencyDomainAllocation.choice.row4.buf) - target->frequencyDomainAllocation.choice.row4.buf = - calloc(target->frequencyDomainAllocation.choice.row4.size, sizeof(uint8_t)); - for (int i = 0; i < target->frequencyDomainAllocation.choice.row4.size; i++) - target->frequencyDomainAllocation.choice.row4.buf[i] = source->frequencyDomainAllocation.choice.row4.buf[i]; - break; - case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_other: - target->frequencyDomainAllocation.choice.other.size = source->frequencyDomainAllocation.choice.other.size; - target->frequencyDomainAllocation.choice.other.bits_unused = source->frequencyDomainAllocation.choice.other.bits_unused; - if (!target->frequencyDomainAllocation.choice.other.buf) - target->frequencyDomainAllocation.choice.other.buf = - calloc(target->frequencyDomainAllocation.choice.other.size, sizeof(uint8_t)); - for (int i = 0; i < target->frequencyDomainAllocation.choice.other.size; i++) - target->frequencyDomainAllocation.choice.other.buf[i] = source->frequencyDomainAllocation.choice.other.buf[i]; - break; - default: - AssertFatal(false, "Invalid entry\n"); - } - } - target->nrofPorts = source->nrofPorts; - target->firstOFDMSymbolInTimeDomain = source->firstOFDMSymbolInTimeDomain; - UPDATE_IE(target->firstOFDMSymbolInTimeDomain2, source->firstOFDMSymbolInTimeDomain2, long); - target->cdm_Type = source->cdm_Type; - target->density = source->density; - target->freqBand = source->freqBand; -} - static void configure_csirs_resource(NR_NZP_CSI_RS_Resource_t *target, NR_NZP_CSI_RS_Resource_t *source) { configure_csi_resourcemapping(&target->resourceMapping, &source->resourceMapping); @@ -2224,7 +2252,7 @@ void nr_rrc_mac_config_req_cg(module_id_t module_id, NR_CellGroupConfig_t *cell_group_config, NR_UE_NR_Capability_t *ue_Capability) { - LOG_I(MAC,"Applying CellGroupConfig from gNodeB\n"); + LOG_I(MAC,"[UE %d] Applying CellGroupConfig from gNodeB\n", module_id); AssertFatal(cell_group_config, "CellGroupConfig should not be NULL\n"); NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index 88973af849..6b849415f8 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -243,6 +243,7 @@ int nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac, float nr_get_Pcmax(int p_Max, uint16_t nr_band, + frame_type_t frame_type, frequency_range_t frequency_range, int Qm, bool powerBoostPi2BPSK, @@ -268,6 +269,10 @@ and fills the PRACH PDU per each FD occasion. void nr_ue_pucch_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, int slotP); void nr_schedule_csirs_reception(NR_UE_MAC_INST_t *mac, int frame, int slot); void nr_schedule_csi_for_im(NR_UE_MAC_INST_t *mac, int frame, int slot); +void configure_csi_resource_mapping(fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu, + NR_CSI_RS_ResourceMapping_t *resourceMapping, + uint32_t bwp_size, + uint32_t bwp_start); /* \brief This function schedules the Msg3 transmission @param diff --git a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c index 3941488682..4d8b79a2ab 100644 --- a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c +++ b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c @@ -130,7 +130,7 @@ NR_UE_MAC_INST_t *nr_l2_init_ue(int nb_inst) AssertFatal(nr_ue_mac_inst, "Couldn't allocate %d instances of MAC module\n", nb_inst); for (int j = 0; j < nb_inst; j++) { - NR_UE_MAC_INST_t *mac = get_mac_inst(j); + NR_UE_MAC_INST_t *mac = &nr_ue_mac_inst[j]; mac->ue_id = j; nr_ue_init_mac(mac); nr_ue_mac_default_configs(mac); diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index 1fc6f4b6e8..ebf3ee2703 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -81,6 +81,7 @@ void init_RA(NR_UE_MAC_INST_t *mac, // PRACH shall be as specified for QPSK modulated DFT-s-OFDM of equivalent RB allocation (38.101-1) prach_resources->RA_PCMAX = nr_get_Pcmax(mac->p_Max, mac->nr_band, + mac->frame_type, mac->frequency_range, 2, false, diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c index 0dbaa5debf..02aea8dd4d 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c @@ -66,9 +66,8 @@ static int get_deltatf(uint16_t nb_of_prbs, int O_UCI); // ∆MPR according to Table 6.2.2-3 38.101-1 -static float get_delta_mpr(uint16_t nr_band, int scs, int N_RB_UL, int n_prbs, int start_prb, int power_class) +static float get_delta_mpr(uint16_t nr_band, frame_type_t frame_type, int scs, int N_RB_UL, int n_prbs, int start_prb, int power_class) { - frame_type_t frame_type = get_frame_type(nr_band, scs); if (compare_relative_ul_channel_bw(nr_band, scs, N_RB_UL, frame_type)) { if (power_class == 3) { if ((nr_band == 28 || nr_band == 83) && get_supported_bw_mhz(nr_band > 256 ? FR2 : FR1, scs, N_RB_UL) == 30) { @@ -167,6 +166,7 @@ static float get_mpr(int Qm, int N_RB_UL, bool is_transform_precoding, int n_prb // -- no additional MPR (A_MPR_c) float nr_get_Pcmax(int p_Max, uint16_t nr_band, + frame_type_t frame_type, frequency_range_t frequency_range, int Qm, bool powerBoostPi2BPSK, @@ -197,7 +197,7 @@ float nr_get_Pcmax(int p_Max, int delta_TC = 0; float MPR = get_mpr(Qm, N_RB_UL, is_transform_precoding, n_prbs, start_prb, power_class); - float delta_MPR = get_delta_mpr(nr_band, scs, N_RB_UL, n_prbs, start_prb, power_class); + float delta_MPR = get_delta_mpr(nr_band, frame_type, scs, N_RB_UL, n_prbs, start_prb, power_class); int A_MPR = 0; // TODO too complicated to implement for now (see 6.2.3 in 38.101-1) int delta_rx_SRS = 0; // TODO for SRS int P_MPR = 0; // to ensure compliance with applicable electromagnetic energy absorption requirements @@ -339,6 +339,7 @@ int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac, // modulated CP-OFDM of equivalent RB allocation. int P_CMAX = nr_get_Pcmax(mac->p_Max, mac->nr_band, + mac->frame_type, mac->frequency_range, 2, false, @@ -519,6 +520,7 @@ int get_pusch_tx_power_ue(NR_UE_MAC_INST_t *mac, int M_pusch_component = 10 * log10((pow(2, mu)) * num_rb); int P_CMAX = nr_get_Pcmax(mac->p_Max, mac->nr_band, + mac->frame_type, mac->frequency_range, 2, false, diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 82e7a541d5..2954cf246b 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -230,6 +230,57 @@ void nr_ue_decode_mib(NR_UE_MAC_INST_t *mac, int cc_id) mac->state = UE_SYNC; } +static void configure_ratematching_csi(fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_pdu, + fapi_nr_dl_config_request_t *dl_config, + int rnti_type, + int frame, + int slot, + int mu, + NR_PDSCH_Config_t *pdsch_config) +{ + // only for C-RNTI, MCS-C-RNTI, CS-RNTI (and only C-RNTI is supported for now) + if (rnti_type != TYPE_C_RNTI_) + return; + + if (pdsch_config && pdsch_config->zp_CSI_RS_ResourceToAddModList) { + for (int i = 0; i < pdsch_config->zp_CSI_RS_ResourceToAddModList->list.count; i++) { + NR_ZP_CSI_RS_Resource_t *zp_res = pdsch_config->zp_CSI_RS_ResourceToAddModList->list.array[i]; + NR_ZP_CSI_RS_ResourceId_t id = zp_res->zp_CSI_RS_ResourceId; + NR_SetupRelease_ZP_CSI_RS_ResourceSet_t *zp_set = pdsch_config->p_ZP_CSI_RS_ResourceSet; + AssertFatal(zp_set && zp_set->choice.setup, "Only periodic ZP resource set is implemented\n"); + bool found = false; + for (int j = 0; j < zp_set->choice.setup->zp_CSI_RS_ResourceIdList.list.count; j++) { + if (*zp_set->choice.setup->zp_CSI_RS_ResourceIdList.list.array[j] == id) { + found = true; + break; + } + } + AssertFatal(found, "Couldn't find periodic ZP resouce in set\n"); + AssertFatal(zp_res->periodicityAndOffset, "periodicityAndOffset cannot be null for periodic ZP resource\n"); + int period, offset; + csi_period_offset(NULL, zp_res->periodicityAndOffset, &period, &offset); + if((frame * nr_slots_per_frame[mu] + slot - offset) % period != 0) + continue; + AssertFatal(dlsch_pdu->numCsiRsForRateMatching < NFAPI_MAX_NUM_CSI_RATEMATCH, "csiRsForRateMatching out of bounds\n"); + fapi_nr_dl_config_csirs_pdu_rel15_t *csi_pdu = &dlsch_pdu->csiRsForRateMatching[dlsch_pdu->numCsiRsForRateMatching]; + csi_pdu->csi_type = 2; // ZP-CSI + csi_pdu->subcarrier_spacing = mu; + configure_csi_resource_mapping(csi_pdu, &zp_res->resourceMapping, dlsch_pdu->BWPSize, dlsch_pdu->BWPStart); + dlsch_pdu->numCsiRsForRateMatching++; + } + } + + for (int i = 0; i < dl_config->number_pdus; i++) { + // This assumes that CSI-RS are scheduled before this moment which is true in current implementation + fapi_nr_dl_config_request_pdu_t *csi_req = &dl_config->dl_config_list[i]; + if (csi_req->pdu_type == FAPI_NR_DL_CONFIG_TYPE_CSI_RS) { + AssertFatal(dlsch_pdu->numCsiRsForRateMatching < NFAPI_MAX_NUM_CSI_RATEMATCH, "csiRsForRateMatching out of bounds\n"); + dlsch_pdu->csiRsForRateMatching[dlsch_pdu->numCsiRsForRateMatching] = csi_req->csirs_config_pdu.csirs_config_rel15; + dlsch_pdu->numCsiRsForRateMatching++; + } + } +} + int8_t nr_ue_decode_BCCH_DL_SCH(NR_UE_MAC_INST_t *mac, int cc_id, unsigned int gNB_index, @@ -635,8 +686,11 @@ static int nr_ue_process_dci_dl_10(NR_UE_MAC_INST_t *mac, dlsch_pdu->BWPSize = current_DL_BWP->BWPSize; dlsch_pdu->BWPStart = current_DL_BWP->BWPStart; } + + nr_rnti_type_t rnti_type = get_rnti_type(mac, dci_ind->rnti); + int mux_pattern = 1; - if (dci_ind->rnti == SI_RNTI) { + if (rnti_type == TYPE_SI_RNTI_) { NR_Type0_PDCCH_CSS_config_t type0_PDCCH_CSS_config = mac->type0_PDCCH_CSS_config; mux_pattern = type0_PDCCH_CSS_config.type0_pdcch_ss_mux_pattern; dl_conf_req->pdu_type = FAPI_NR_DL_CONFIG_TYPE_SI_DLSCH; @@ -646,13 +700,17 @@ static int nr_ue_process_dci_dl_10(NR_UE_MAC_INST_t *mac, dlsch_pdu->SubcarrierSpacing = mac->mib->subCarrierSpacingCommon + 2; } else { dlsch_pdu->SubcarrierSpacing = current_DL_BWP->scs; - if (mac->ra.RA_window_cnt >= 0 && dci_ind->rnti == mac->ra.ra_rnti) { + if (mac->ra.RA_window_cnt >= 0 && rnti_type == TYPE_RA_RNTI_) { dl_conf_req->pdu_type = FAPI_NR_DL_CONFIG_TYPE_RA_DLSCH; } else { dl_conf_req->pdu_type = FAPI_NR_DL_CONFIG_TYPE_DLSCH; } } + dlsch_pdu->numCsiRsForRateMatching = 0; + configure_ratematching_csi(dlsch_pdu, dl_config, rnti_type, frame, slot, dlsch_pdu->SubcarrierSpacing, pdsch_config); + + /* IDENTIFIER_DCI_FORMATS */ /* FREQ_DOM_RESOURCE_ASSIGNMENT_DL */ if (nr_ue_process_dci_freq_dom_resource_assignment(NULL, @@ -674,7 +732,7 @@ static int nr_ue_process_dci_dl_10(NR_UE_MAC_INST_t *mac, int dmrs_typeA_pos = mac->dmrs_TypeA_Position; const int coreset_type = dci_ind->coreset_type == NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG; // 0 for coreset0, 1 otherwise; - nr_rnti_type_t rnti_type = get_rnti_type(mac, dci_ind->rnti); + NR_tda_info_t tda_info = get_dl_tda_info(current_DL_BWP, dci_ind->ss_type, dci->time_domain_assignment.val, @@ -845,7 +903,7 @@ static int nr_ue_process_dci_dl_10(NR_UE_MAC_INST_t *mac, return -1; } - if (dci_ind->rnti != mac->ra.ra_rnti && dci_ind->rnti != SI_RNTI) { + if (rnti_type != TYPE_RA_RNTI_ && rnti_type != TYPE_SI_RNTI_) { AssertFatal(1 + dci->pdsch_to_harq_feedback_timing_indicator.val > DURATION_RX_TO_TX, "PDSCH to HARQ feedback time (%d) needs to be higher than DURATION_RX_TO_TX (%d).\n", 1 + dci->pdsch_to_harq_feedback_timing_indicator.val, @@ -966,6 +1024,10 @@ static int nr_ue_process_dci_dl_11(NR_UE_MAC_INST_t *mac, dlsch_pdu->BWPStart = current_DL_BWP->BWPStart; dlsch_pdu->SubcarrierSpacing = current_DL_BWP->scs; + nr_rnti_type_t rnti_type = get_rnti_type(mac, dci_ind->rnti); + dlsch_pdu->numCsiRsForRateMatching = 0; + configure_ratematching_csi(dlsch_pdu, dl_config, rnti_type, frame, slot, current_DL_BWP->scs, pdsch_Config); + /* IDENTIFIER_DCI_FORMATS */ /* CARRIER_IND */ /* BANDWIDTH_PART_IND */ @@ -987,7 +1049,7 @@ static int nr_ue_process_dci_dl_11(NR_UE_MAC_INST_t *mac, int dmrs_typeA_pos = mac->dmrs_TypeA_Position; int mux_pattern = 1; const int coreset_type = dci_ind->coreset_type == NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG; // 0 for coreset0, 1 otherwise; - nr_rnti_type_t rnti_type = get_rnti_type(mac, dci_ind->rnti); + NR_tda_info_t tda_info = get_dl_tda_info(current_DL_BWP, dci_ind->ss_type, dci->time_domain_assignment.val, diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 20b0e80f61..b88ca7e5f3 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -1197,15 +1197,16 @@ void nr_ue_dl_scheduler(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_info if (mac->state == UE_NOT_SYNC || mac->state == UE_DETACHING) return; - ue_dci_configuration(mac, dl_config, rx_frame, rx_slot); - - if (mac->ul_time_alignment.ta_apply != no_ta) - schedule_ta_command(dl_config, &mac->ul_time_alignment); if (mac->state == UE_CONNECTED) { nr_schedule_csirs_reception(mac, rx_frame, rx_slot); nr_schedule_csi_for_im(mac, rx_frame, rx_slot); } + ue_dci_configuration(mac, dl_config, rx_frame, rx_slot); + + if (mac->ul_time_alignment.ta_apply != no_ta) + schedule_ta_command(dl_config, &mac->ul_time_alignment); + nr_scheduled_response_t scheduled_response = {.dl_config = dl_config, .module_id = mac->ue_id, .CC_id = dl_info->cc_id, @@ -2418,6 +2419,113 @@ uint8_t set_csirs_measurement_bitmap(NR_CSI_MeasConfig_t *csi_measconfig, NR_CSI return meas_bitmap; } +void configure_csi_resource_mapping(fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu, + NR_CSI_RS_ResourceMapping_t *resourceMapping, + uint32_t bwp_size, + uint32_t bwp_start) +{ + // According to last paragraph of TS 38.214 5.2.2.3.1 + if (resourceMapping->freqBand.startingRB < bwp_start) + csirs_config_pdu->start_rb = bwp_start; + else + csirs_config_pdu->start_rb = resourceMapping->freqBand.startingRB; + if (resourceMapping->freqBand.nrofRBs > (bwp_start + bwp_size - csirs_config_pdu->start_rb)) + csirs_config_pdu->nr_of_rbs = bwp_start + bwp_size - csirs_config_pdu->start_rb; + else + csirs_config_pdu->nr_of_rbs = resourceMapping->freqBand.nrofRBs; + AssertFatal(csirs_config_pdu->nr_of_rbs >= 24, "CSI-RS has %d RBs, but the minimum is 24\n", csirs_config_pdu->nr_of_rbs); + + csirs_config_pdu->symb_l0 = resourceMapping->firstOFDMSymbolInTimeDomain; + if (resourceMapping->firstOFDMSymbolInTimeDomain2) + csirs_config_pdu->symb_l1 = *resourceMapping->firstOFDMSymbolInTimeDomain2; + csirs_config_pdu->cdm_type = resourceMapping->cdm_Type; + + csirs_config_pdu->freq_density = resourceMapping->density.present; + if ((resourceMapping->density.present == NR_CSI_RS_ResourceMapping__density_PR_dot5) + && (resourceMapping->density.choice.dot5 == NR_CSI_RS_ResourceMapping__density__dot5_evenPRBs)) + csirs_config_pdu->freq_density--; + + switch(resourceMapping->frequencyDomainAllocation.present){ + case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row1: + csirs_config_pdu->row = 1; + csirs_config_pdu->freq_domain = ((resourceMapping->frequencyDomainAllocation.choice.row1.buf[0]) >> 4) & 0x0f; + break; + case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row2: + csirs_config_pdu->row = 2; + csirs_config_pdu->freq_domain = (((resourceMapping->frequencyDomainAllocation.choice.row2.buf[1] >> 4) & 0x0f) + | ((resourceMapping->frequencyDomainAllocation.choice.row2.buf[0] << 4) & 0xff0)); + break; + case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row4: + csirs_config_pdu->row = 4; + csirs_config_pdu->freq_domain = ((resourceMapping->frequencyDomainAllocation.choice.row4.buf[0]) >> 5) & 0x07; + break; + case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_other: + csirs_config_pdu->freq_domain = ((resourceMapping->frequencyDomainAllocation.choice.other.buf[0]) >> 2) & 0x3f; + // determining the row of table 7.4.1.5.3-1 in 38.211 + switch (resourceMapping->nrofPorts) { + case NR_CSI_RS_ResourceMapping__nrofPorts_p1: + AssertFatal(1 == 0, "Resource with 1 CSI port shouldn't be within other rows\n"); + break; + case NR_CSI_RS_ResourceMapping__nrofPorts_p2: + csirs_config_pdu->row = 3; + break; + case NR_CSI_RS_ResourceMapping__nrofPorts_p4: + csirs_config_pdu->row = 5; + break; + case NR_CSI_RS_ResourceMapping__nrofPorts_p8: + if (resourceMapping->cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) + csirs_config_pdu->row = 8; + else { + int num_k = 0; + for (int k = 0; k < 6; k++) + num_k += (((csirs_config_pdu->freq_domain) >> k) & 0x01); + if (num_k == 4) + csirs_config_pdu->row = 6; + else + csirs_config_pdu->row = 7; + } + break; + case NR_CSI_RS_ResourceMapping__nrofPorts_p12: + if (resourceMapping->cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) + csirs_config_pdu->row = 10; + else + csirs_config_pdu->row = 9; + break; + case NR_CSI_RS_ResourceMapping__nrofPorts_p16: + if (resourceMapping->cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) + csirs_config_pdu->row = 12; + else + csirs_config_pdu->row = 11; + break; + case NR_CSI_RS_ResourceMapping__nrofPorts_p24: + if (resourceMapping->cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) + csirs_config_pdu->row = 14; + else { + if (resourceMapping->cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm8_FD2_TD4) + csirs_config_pdu->row = 15; + else + csirs_config_pdu->row = 13; + } + break; + case NR_CSI_RS_ResourceMapping__nrofPorts_p32: + if (resourceMapping->cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) + csirs_config_pdu->row = 17; + else { + if (resourceMapping->cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm8_FD2_TD4) + csirs_config_pdu->row = 18; + else + csirs_config_pdu->row = 16; + } + break; + default: + AssertFatal(false, "Invalid number of ports in CSI-RS resource\n"); + } + break; + default: + AssertFatal(false, "Invalid freqency domain allocation in CSI-RS resource\n"); + } +} + void nr_schedule_csirs_reception(NR_UE_MAC_INST_t *mac, int frame, int slot) { if (!mac->sc_info.csi_MeasConfig) @@ -2449,117 +2557,20 @@ void nr_schedule_csirs_reception(NR_UE_MAC_INST_t *mac, int frame, int slot) LOG_D(MAC,"Scheduling reception of CSI-RS in frame %d slot %d\n", frame, slot); fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu = &dl_config->dl_config_list[dl_config->number_pdus].csirs_config_pdu.csirs_config_rel15; csirs_config_pdu->measurement_bitmap = set_csirs_measurement_bitmap(csi_measconfig, csi_res_id); - NR_CSI_RS_ResourceMapping_t resourceMapping = nzpcsi->resourceMapping; csirs_config_pdu->subcarrier_spacing = mu; csirs_config_pdu->cyclic_prefix = current_DL_BWP->cyclicprefix ? *current_DL_BWP->cyclicprefix : 0; - // According to last paragraph of TS 38.214 5.2.2.3.1 - if (resourceMapping.freqBand.startingRB < bwp_start) { - csirs_config_pdu->start_rb = bwp_start; - } else { - csirs_config_pdu->start_rb = resourceMapping.freqBand.startingRB; - } - if (resourceMapping.freqBand.nrofRBs > (bwp_start + bwp_size - csirs_config_pdu->start_rb)) { - csirs_config_pdu->nr_of_rbs = bwp_start + bwp_size - csirs_config_pdu->start_rb; - } else { - csirs_config_pdu->nr_of_rbs = resourceMapping.freqBand.nrofRBs; - } - AssertFatal(csirs_config_pdu->nr_of_rbs >= 24, "CSI-RS has %d RBs, but the minimum is 24\n", csirs_config_pdu->nr_of_rbs); - csirs_config_pdu->csi_type = 1; // NZP-CSI-RS - csirs_config_pdu->symb_l0 = resourceMapping.firstOFDMSymbolInTimeDomain; - if (resourceMapping.firstOFDMSymbolInTimeDomain2) - csirs_config_pdu->symb_l1 = *resourceMapping.firstOFDMSymbolInTimeDomain2; - csirs_config_pdu->cdm_type = resourceMapping.cdm_Type; - csirs_config_pdu->freq_density = resourceMapping.density.present; - if ((resourceMapping.density.present == NR_CSI_RS_ResourceMapping__density_PR_dot5) - && (resourceMapping.density.choice.dot5 == NR_CSI_RS_ResourceMapping__density__dot5_evenPRBs)) - csirs_config_pdu->freq_density--; + csirs_config_pdu->scramb_id = nzpcsi->scramblingID; csirs_config_pdu->power_control_offset = nzpcsi->powerControlOffset + 8; if (nzpcsi->powerControlOffsetSS) csirs_config_pdu->power_control_offset_ss = *nzpcsi->powerControlOffsetSS; else csirs_config_pdu->power_control_offset_ss = 1; // 0 dB - switch(resourceMapping.frequencyDomainAllocation.present){ - case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row1: - csirs_config_pdu->row = 1; - csirs_config_pdu->freq_domain = ((resourceMapping.frequencyDomainAllocation.choice.row1.buf[0]) >> 4) & 0x0f; - break; - case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row2: - csirs_config_pdu->row = 2; - csirs_config_pdu->freq_domain = (((resourceMapping.frequencyDomainAllocation.choice.row2.buf[1] >> 4) & 0x0f) - | ((resourceMapping.frequencyDomainAllocation.choice.row2.buf[0] << 4) & 0xff0)); - break; - case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row4: - csirs_config_pdu->row = 4; - csirs_config_pdu->freq_domain = ((resourceMapping.frequencyDomainAllocation.choice.row4.buf[0]) >> 5) & 0x07; - break; - case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_other: - csirs_config_pdu->freq_domain = ((resourceMapping.frequencyDomainAllocation.choice.other.buf[0]) >> 2) & 0x3f; - // determining the row of table 7.4.1.5.3-1 in 38.211 - switch (resourceMapping.nrofPorts) { - case NR_CSI_RS_ResourceMapping__nrofPorts_p1: - AssertFatal(1 == 0, "Resource with 1 CSI port shouldn't be within other rows\n"); - break; - case NR_CSI_RS_ResourceMapping__nrofPorts_p2: - csirs_config_pdu->row = 3; - break; - case NR_CSI_RS_ResourceMapping__nrofPorts_p4: - csirs_config_pdu->row = 5; - break; - case NR_CSI_RS_ResourceMapping__nrofPorts_p8: - if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) - csirs_config_pdu->row = 8; - else { - int num_k = 0; - for (int k = 0; k < 6; k++) - num_k += (((csirs_config_pdu->freq_domain) >> k) & 0x01); - if (num_k == 4) - csirs_config_pdu->row = 6; - else - csirs_config_pdu->row = 7; - } - break; - case NR_CSI_RS_ResourceMapping__nrofPorts_p12: - if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) - csirs_config_pdu->row = 10; - else - csirs_config_pdu->row = 9; - break; - case NR_CSI_RS_ResourceMapping__nrofPorts_p16: - if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) - csirs_config_pdu->row = 12; - else - csirs_config_pdu->row = 11; - break; - case NR_CSI_RS_ResourceMapping__nrofPorts_p24: - if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) - csirs_config_pdu->row = 14; - else { - if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm8_FD2_TD4) - csirs_config_pdu->row = 15; - else - csirs_config_pdu->row = 13; - } - break; - case NR_CSI_RS_ResourceMapping__nrofPorts_p32: - if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) - csirs_config_pdu->row = 17; - else { - if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm8_FD2_TD4) - csirs_config_pdu->row = 18; - else - csirs_config_pdu->row = 16; - } - break; - default: - AssertFatal(1 == 0, "Invalid number of ports in CSI-RS resource\n"); - } - break; - default: - AssertFatal(1 == 0, "Invalid freqency domain allocation in CSI-RS resource\n"); - } + + configure_csi_resource_mapping(csirs_config_pdu, &nzpcsi->resourceMapping, bwp_size, bwp_start); + dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_CSI_RS; dl_config->number_pdus += 1; } diff --git a/openair2/LAYER2/NR_MAC_UE/tests/test_nr_ue_power_procedures.cpp b/openair2/LAYER2/NR_MAC_UE/tests/test_nr_ue_power_procedures.cpp index 49f2d58f27..3f865ec597 100644 --- a/openair2/LAYER2/NR_MAC_UE/tests/test_nr_ue_power_procedures.cpp +++ b/openair2/LAYER2/NR_MAC_UE/tests/test_nr_ue_power_procedures.cpp @@ -43,24 +43,25 @@ TEST(test_pcmax, test_mpr) int N_RB_UL = 51; // 10Mhz int nr_band = 20; float expected_power = 23 - (1.5 / 2); - EXPECT_EQ(expected_power, nr_get_Pcmax(23, nr_band, FR1, 2, false, 1, N_RB_UL, false, 6, prb_start)); + frame_type_t frame_type = TDD; + EXPECT_EQ(expected_power, nr_get_Pcmax(23, nr_band, frame_type, FR1, 2, false, 1, N_RB_UL, false, 6, prb_start)); // Outer PRB, MPR = 3, no delta MPR prb_start = 0; expected_power = 23 - (3.0 / 2); - EXPECT_EQ(expected_power, nr_get_Pcmax(23, nr_band, FR1, 2, false, 1, N_RB_UL, false, 6, prb_start)); + EXPECT_EQ(expected_power, nr_get_Pcmax(23, nr_band, frame_type, FR1, 2, false, 1, N_RB_UL, false, 6, prb_start)); // Outer PRB on band 28, MPR = 3, delta MPR = 0.5 dB N_RB_UL = 78; nr_band = 28; expected_power = 23 - ((3.0 + 0.5) / 2); - EXPECT_EQ(expected_power, nr_get_Pcmax(23, nr_band, FR1, 2, false, 1, N_RB_UL, false, 100, prb_start)); + EXPECT_EQ(expected_power, nr_get_Pcmax(23, nr_band, frame_type, FR1, 2, false, 1, N_RB_UL, false, 100, prb_start)); } TEST(test_pcmax, test_not_implemented) { int N_RB_UL = 51; - EXPECT_DEATH(nr_get_Pcmax(23, 20, FR1, 1, false, 1, N_RB_UL, false, 6, 0), "MPR for Pi/2 BPSK not implemented yet"); + EXPECT_DEATH(nr_get_Pcmax(23, 20, TDD, FR1, 1, false, 1, N_RB_UL, false, 6, 0), "MPR for Pi/2 BPSK not implemented yet"); } TEST(test_pcmax, test_pucch_max_power) @@ -69,11 +70,11 @@ TEST(test_pcmax, test_pucch_max_power) int prb_start = 0; int N_RB_UL = 51; // 10Mhz float expected_power = 23 - (1.0 / 2); - EXPECT_EQ(expected_power, nr_get_Pcmax(23, 20, FR1, 2, false, 1, N_RB_UL, true, 1, prb_start)); + EXPECT_EQ(expected_power, nr_get_Pcmax(23, 20, TDD, FR1, 2, false, 1, N_RB_UL, true, 1, prb_start)); // Other fromats, no transform precoding, MPR = 3 expected_power = 23 - (3.0 / 2); - EXPECT_EQ(expected_power, nr_get_Pcmax(23, 20, FR1, 2, false, 1, N_RB_UL, false, 1, prb_start)); + EXPECT_EQ(expected_power, nr_get_Pcmax(23, 20, TDD, FR1, 2, false, 1, N_RB_UL, false, 1, prb_start)); } TEST(test_pucch_power_state, test_accumulated_delta_pucch) @@ -91,6 +92,7 @@ TEST(test_pucch_power_state, test_accumulated_delta_pucch) pucch_Config.pucch_PowerControl = &power_config; mac.G_b_f_c = 0; mac.pucch_power_control_initialized = true; + mac.frame_type = TDD; int scs = 1; int sum_delta_pucch = 3; @@ -102,8 +104,17 @@ TEST(test_pucch_power_state, test_accumulated_delta_pucch) int subframe_number = 0; int O_uci = 2; uint16_t start_prb = 0; - int P_CMAX = - nr_get_Pcmax(23, mac.nr_band, FR1, 2, false, current_UL_BWP.scs, current_UL_BWP.BWPSize, false, nb_of_prbs, start_prb); + int P_CMAX = nr_get_Pcmax(23, + mac.nr_band, + mac.frame_type, + FR1, + 2, + false, + current_UL_BWP.scs, + current_UL_BWP.BWPSize, + false, + nb_of_prbs, + start_prb); int pucch_power_prev = get_pucch_tx_power_ue(&mac, scs, &pucch_Config, @@ -187,6 +198,7 @@ TEST(pusch_power_control, pusch_power_control_msg3) NR_PUSCH_PowerControl pusch_PowerControl = {0}; pusch_Config.pusch_PowerControl = &pusch_PowerControl; pusch_PowerControl.tpc_Accumulation = (long*)1; + mac.frame_type = TDD; // msg3 cofiguration as in 5g_rfsimulator testcase int num_rb = 8; @@ -201,7 +213,17 @@ TEST(pusch_power_control, pusch_power_control_msg3) int delta_pusch = 0; bool is_rar_tx_retx = true; - int P_CMAX = nr_get_Pcmax(23, mac.nr_band, FR1, Qm, false, current_UL_BWP.scs, current_UL_BWP.BWPSize, false, num_rb, start_prb); + int P_CMAX = nr_get_Pcmax(23, + mac.nr_band, + mac.frame_type, + FR1, + Qm, + false, + current_UL_BWP.scs, + current_UL_BWP.BWPSize, + false, + num_rb, + start_prb); long preambleReceivedTargetPower = -96; nr_rach_ConfigCommon.rach_ConfigGeneric.preambleReceivedTargetPower = preambleReceivedTargetPower; @@ -236,26 +258,24 @@ TEST(pusch_power_control, pusch_power_control_msg3) delta_pusch, is_rar_tx_retx, false); - EXPECT_EQ(std::min(P_CMAX, power - 2), reduced_power) - << "Incorrect handling of preambleReceivedTargetPower"; + EXPECT_EQ(std::min(P_CMAX, power - 2), reduced_power) << "Incorrect handling of preambleReceivedTargetPower"; EXPECT_LT(reduced_power, P_CMAX) << "Power above P_CMAX"; delta_pusch = 4; int increased_power = get_pusch_tx_power_ue(&mac, - num_rb, - start_prb, - nb_symb_sch, - nb_dmrs_prb, - nb_ptrs_prb, - Qm, - R, - beta_offset_csi1, - sum_bits_in_codeblocks, - delta_pusch, - is_rar_tx_retx, - false); - EXPECT_EQ(std::min(P_CMAX, reduced_power + delta_pusch), increased_power) - << "delta_pusch should increase tx power"; + num_rb, + start_prb, + nb_symb_sch, + nb_dmrs_prb, + nb_ptrs_prb, + Qm, + R, + beta_offset_csi1, + sum_bits_in_codeblocks, + delta_pusch, + is_rar_tx_retx, + false); + EXPECT_EQ(std::min(P_CMAX, reduced_power + delta_pusch), increased_power) << "delta_pusch should increase tx power"; EXPECT_LT(increased_power, P_CMAX) << "Power above P_CMAX"; } @@ -269,6 +289,7 @@ TEST(pusch_power_control, pusch_power_data) NR_RACH_ConfigCommon_t nr_rach_ConfigCommon = {0}; current_UL_BWP.rach_ConfigCommon = &nr_rach_ConfigCommon; mac.nr_band = 78; + mac.frame_type = TDD; bool is_rar_tx_retx = false; int num_rb = 5; @@ -291,7 +312,17 @@ TEST(pusch_power_control, pusch_power_data) current_UL_BWP.p0_NominalWithGrant = &p0_NominalWithGrant; pusch_PowerControl.deltaMCS = (long*)1; - int P_CMAX = nr_get_Pcmax(23, mac.nr_band, FR1, Qm, false, current_UL_BWP.scs, current_UL_BWP.BWPSize, transform_precoding, num_rb, start_prb); + int P_CMAX = nr_get_Pcmax(23, + mac.nr_band, + mac.frame_type, + FR1, + Qm, + false, + current_UL_BWP.scs, + current_UL_BWP.BWPSize, + transform_precoding, + num_rb, + start_prb); int power = get_pusch_tx_power_ue(&mac, num_rb, diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index db04417150..4dbcdd72e7 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -242,7 +242,7 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_ temp_tda, tdaList->list.count); int K2 = get_K2(tdaList, temp_tda, mu, scc); - const int sched_frame = frame + (slot + K2) / nr_slots_per_frame[mu]; + const int sched_frame = (frame + (slot + K2) / nr_slots_per_frame[mu]) % MAX_FRAME_NUMBER; const int sched_slot = (slot + K2) % nr_slots_per_frame[mu]; const int tda = get_ul_tda(nr_mac, scc, sched_frame, sched_slot); if (tda < 0) @@ -276,7 +276,7 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_ if (!tda_info.valid_tda) return false; sched_ctrl->sched_pusch.tda_info = tda_info; - + sched_ctrl->sched_pusch.time_domain_allocation = tda; const int buffer_index = ul_buffer_index(sched_frame, sched_slot, mu, nr_mac->vrb_map_UL_size); uint16_t *vrb_map_UL = &nr_mac->common_channels[CC_id].vrb_map_UL[buffer_index * MAX_BWP_SIZE]; for (int i = rbStart; i < rbStart + rbSize; ++i) { diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 612cbc0eab..89c684ee41 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -390,7 +390,7 @@ static int nr_process_mac_pdu(instance_t module_idP, // fixed length mac_subheader_len = 1; - if ( rx_lcid == UL_SCH_LCID_CCCH1 ) { + if (rx_lcid == UL_SCH_LCID_CCCH1) { // RRCResumeRequest1 message includes the full I-RNTI and has a size of 8 bytes mac_len = 8; @@ -615,6 +615,26 @@ void handle_nr_ul_harq(const int CC_idP, NR_SCHED_UNLOCK(&nrmac->sched_lock); } +static void handle_msg3_failed_rx(NR_RA_t *ra, int i, int harq_round_max) +{ + // for CFRA (NSA) do not schedule retransmission of msg3 + if (ra->cfra) { + LOG_D(NR_MAC, "Random Access %i failed at state %s (NSA msg3 reception failed)\n", i, nrra_text[ra->ra_state]); + nr_clear_ra_proc(ra); + return; + } + + if (ra->msg3_round >= harq_round_max - 1) { + LOG_W(NR_MAC, "Random Access %i failed at state %s (Reached msg3 max harq rounds)\n", i, nrra_text[ra->ra_state]); + nr_clear_ra_proc(ra); + return; + } + + LOG_D(NR_MAC, "Random Access %i Msg3 CRC did not pass\n", i); + ra->msg3_round++; + ra->ra_state = nrRA_Msg3_retransmission; +} + /* * When data are received on PHY and transmitted to MAC */ @@ -714,7 +734,7 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, #endif - if (sduP != NULL){ + if (sduP != NULL) { LOG_D(NR_MAC, "Received PDU at MAC gNB \n"); UE->UE_sched_ctrl.pusch_consecutive_dtx_cnt = 0; @@ -728,7 +748,7 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, else { NR_UE_ul_harq_t *cur_harq = &UE_scheduling_control->ul_harq_processes[harq_pid]; /* reduce sched_ul_bytes when cur_harq->round == 3 */ - if (cur_harq->round == 3){ + if (cur_harq->round == 3) { const uint32_t tb_size = UE_scheduling_control->ul_harq_processes[harq_pid].sched_pusch.tb_size; UE_scheduling_control->sched_ul_bytes -= tb_size; if (UE_scheduling_control->sched_ul_bytes < 0) @@ -747,20 +767,16 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, nr_mac_trigger_ul_failure(&UE->UE_sched_ctrl, UE->current_UL_BWP.scs); } } - } else if(sduP) { + } else if (sduP) { bool no_sig = true; for (int k = 0; k < sdu_lenP; k++) { - if(sduP[k]!=0) { + if(sduP[k] != 0) { no_sig = false; break; } } - if(no_sig) { - LOG_W(NR_MAC, "No signal\n"); - } - T(T_GNB_MAC_UL_PDU_WITH_DATA, T_INT(gnb_mod_idP), T_INT(CC_idP), T_INT(rntiP), T_INT(frameP), T_INT(slotP), T_INT(-1) /* harq_pid */, T_BUFFER(sduP, sdu_lenP)); @@ -774,8 +790,8 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, continue; if (no_sig) { - LOG_D(NR_MAC, "Random Access %i failed at state %s (no signal)\n", i, nrra_text[ra->ra_state]); - nr_clear_ra_proc(ra); + LOG_W(NR_MAC, "Random Access %i ULSCH with no signal\n", i); + handle_msg3_failed_rx(ra, i, gNB_mac->ul_bler.harq_round_max); continue; } @@ -912,23 +928,7 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, if( (frameP!=ra->Msg3_frame) || (slotP!=ra->Msg3_slot)) continue; - // for CFRA (NSA) do not schedule retransmission of msg3 - if (ra->cfra) { - LOG_D(NR_MAC, "Random Access %i failed at state %s (NSA msg3 reception failed)\n", i, nrra_text[ra->ra_state]); - nr_clear_ra_proc(ra); - return; - } - - if (ra->msg3_round >= gNB_mac->ul_bler.harq_round_max - 1) { - LOG_W(NR_MAC, "Random Access %i failed at state %s (Reached msg3 max harq rounds)\n", i, nrra_text[ra->ra_state]); - nr_clear_ra_proc(ra); - return; - } - - LOG_D(NR_MAC, "Random Access %i Msg3 CRC did not pass)\n", i); - - ra->msg3_round++; - ra->ra_state = nrRA_Msg3_retransmission; + handle_msg3_failed_rx(ra, i, gNB_mac->ul_bler.harq_round_max); } } } @@ -1938,7 +1938,7 @@ static void pf_ul(module_id_t module_id, UEsched_t *iterator=UE_sched; /* Loop UE_sched to find max coeff and allocate transmission */ - while (remainUEs> 0 && n_rb_sched >= min_rb && iterator->UE != NULL) { + while (remainUEs > 0 && n_rb_sched >= min_rb && iterator->UE != NULL) { NR_UE_sched_ctrl_t *sched_ctrl = &iterator->UE->UE_sched_ctrl; int CCEIndex = get_cce_index(nrmac, @@ -2332,7 +2332,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot, n const int index = ul_buffer_index(sched_pusch->frame, sched_pusch->slot, current_BWP->scs, nr_mac->UL_tti_req_ahead_size); nfapi_nr_ul_tti_request_t *future_ul_tti_req = &nr_mac->UL_tti_req_ahead[0][index]; if (future_ul_tti_req->SFN != sched_pusch->frame || future_ul_tti_req->Slot != sched_pusch->slot) - LOG_W(MAC, + LOG_W(NR_MAC, "%d.%d future UL_tti_req's frame.slot %d.%d does not match PUSCH %d.%d\n", frame, slot, future_ul_tti_req->SFN, @@ -2349,8 +2349,14 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot, n memset(pusch_pdu, 0, sizeof(nfapi_nr_pusch_pdu_t)); future_ul_tti_req->n_pdus += 1; - LOG_D(NR_MAC, "%4d.%2d Scheduling UE specific PUSCH for sched %d.%d, ul_tti_req %d.%d\n", frame, slot, - sched_pusch->frame,sched_pusch->slot,future_ul_tti_req->SFN,future_ul_tti_req->Slot); + LOG_D(NR_MAC, + "%4d.%2d Scheduling UE specific PUSCH for sched %d.%d, ul_tti_req %d.%d\n", + frame, + slot, + sched_pusch->frame, + sched_pusch->slot, + future_ul_tti_req->SFN, + future_ul_tti_req->Slot); pusch_pdu->pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA; pusch_pdu->rnti = rnti; diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c index db82085ed6..c1eb645ed0 100644 --- a/openair2/LAYER2/NR_MAC_gNB/main.c +++ b/openair2/LAYER2/NR_MAC_gNB/main.c @@ -298,7 +298,8 @@ void mac_top_init_gNB(ngran_node_t node_type, * will output the packets at a local interface, which is in line with * the noS1 mode. Hence, below, we simply hardcode ENB_FLAG_NO */ // setup PDCP, RLC - nr_pdcp_add_drbs(ENB_FLAG_NO, 0x1234, rbconfig->drb_ToAddModList, 0, NULL, NULL); + nr_pdcp_entity_security_keys_and_algos_t null_security_parameters = {0}; + nr_pdcp_add_drbs(ENB_FLAG_NO, 0x1234, rbconfig->drb_ToAddModList, &null_security_parameters); nr_rlc_add_drb(0x1234, rbconfig->drb_ToAddModList->list.array[0]->drb_Identity, rlc_rbconfig); // free memory diff --git a/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c b/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c index 2f7f4afa59..414edb052b 100644 --- a/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c +++ b/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c @@ -187,13 +187,15 @@ void e1_bearer_context_setup(const e1ap_bearer_setup_req_t *req) // create PDCP bearers. This will also create SDAP bearers NR_DRB_ToAddModList_t DRB_configList = {0}; fill_DRB_configList_e1(&DRB_configList, req_pdu); + nr_pdcp_entity_security_keys_and_algos_t security_parameters; + security_parameters.ciphering_algorithm = req->cipheringAlgorithm; + security_parameters.integrity_algorithm = req->integrityProtectionAlgorithm; + memcpy(security_parameters.ciphering_key, req->encryptionKey, NR_K_KEY_SIZE); + memcpy(security_parameters.integrity_key, req->integrityProtectionKey, NR_K_KEY_SIZE); nr_pdcp_add_drbs(true, // set this to notify PDCP that his not UE cu_up_ue_id, &DRB_configList, - (req->integrityProtectionAlgorithm << 4) | req->cipheringAlgorithm, - (uint8_t *)req->encryptionKey, - (uint8_t *)req->integrityProtectionKey); - + &security_parameters); if (f1inst >= 0) { /* we have F1(-U) */ teid_t dummy_teid = 0xffff; // we will update later with answer from DU in_addr_t dummy_address = {0}; // IPv4, updated later with answer from DU @@ -255,7 +257,15 @@ void e1_bearer_context_modif(const e1ap_bearer_mod_req_t *req) modified->id = to_modif->id; if (to_modif->pdcp_config.pDCP_Reestablishment) { - nr_pdcp_reestablishment(req->gNB_cu_up_ue_id, to_modif->id, false); + nr_pdcp_entity_security_keys_and_algos_t security_parameters; + security_parameters.ciphering_algorithm = req->cipheringAlgorithm; + security_parameters.integrity_algorithm = req->integrityProtectionAlgorithm; + memcpy(security_parameters.ciphering_key, req->encryptionKey, NR_K_KEY_SIZE); + memcpy(security_parameters.integrity_key, req->integrityProtectionKey, NR_K_KEY_SIZE); + nr_pdcp_reestablishment(req->gNB_cu_up_ue_id, + to_modif->id, + false, + &security_parameters); } if (f1inst < 0) // no F1-U? diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c index 712bbf6b0c..c125eb41f2 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c @@ -328,38 +328,35 @@ static bool nr_pdcp_entity_check_integrity(struct nr_pdcp_entity_t *entity, } /* may be called several times, take care to clean previous settings */ -static void nr_pdcp_entity_set_security(nr_pdcp_entity_t *entity, - int integrity_algorithm, - char *integrity_key, - int ciphering_algorithm, - char *ciphering_key) +static void nr_pdcp_entity_set_security(struct nr_pdcp_entity_t *entity, + const nr_pdcp_entity_security_keys_and_algos_t *parameters) { - if (integrity_algorithm != -1) - entity->integrity_algorithm = integrity_algorithm; - if (ciphering_algorithm != -1) - entity->ciphering_algorithm = ciphering_algorithm; - if (integrity_key != NULL) - memcpy(entity->integrity_key, integrity_key, 16); - if (ciphering_key != NULL) - memcpy(entity->ciphering_key, ciphering_key, 16); + if (parameters->integrity_algorithm != -1) { + entity->security_keys_and_algos.integrity_algorithm = parameters->integrity_algorithm; + memcpy(entity->security_keys_and_algos.integrity_key, parameters->integrity_key, NR_K_KEY_SIZE); + } + if (parameters->ciphering_algorithm != -1) { + entity->security_keys_and_algos.ciphering_algorithm = parameters->ciphering_algorithm; + memcpy(entity->security_keys_and_algos.ciphering_key, parameters->ciphering_key, NR_K_KEY_SIZE); + } - if (integrity_algorithm == 0) { + if (parameters->integrity_algorithm == 0) { entity->has_integrity = 0; if (entity->free_integrity != NULL) entity->free_integrity(entity->integrity_context); entity->free_integrity = NULL; } - if (integrity_algorithm != 0 && integrity_algorithm != -1) { + if (parameters->integrity_algorithm != 0 && parameters->integrity_algorithm != -1) { entity->has_integrity = 1; if (entity->free_integrity != NULL) entity->free_integrity(entity->integrity_context); - if (integrity_algorithm == 2) { - entity->integrity_context = nr_pdcp_integrity_nia2_init(entity->integrity_key); + if (parameters->integrity_algorithm == 2) { + entity->integrity_context = nr_pdcp_integrity_nia2_init(entity->security_keys_and_algos.integrity_key); entity->integrity = nr_pdcp_integrity_nia2_integrity; entity->free_integrity = nr_pdcp_integrity_nia2_free_integrity; - } else if (integrity_algorithm == 1) { - entity->integrity_context = nr_pdcp_integrity_nia1_init(entity->integrity_key); + } else if (parameters->integrity_algorithm == 1) { + entity->integrity_context = nr_pdcp_integrity_nia1_init(entity->security_keys_and_algos.integrity_key); entity->integrity = nr_pdcp_integrity_nia1_integrity; entity->free_integrity = nr_pdcp_integrity_nia1_free_integrity; } else { @@ -368,22 +365,22 @@ static void nr_pdcp_entity_set_security(nr_pdcp_entity_t *entity, } } - if (ciphering_algorithm == 0) { + if (parameters->ciphering_algorithm == 0) { entity->has_ciphering = 0; if (entity->free_security != NULL) entity->free_security(entity->security_context); entity->free_security = NULL; } - if (ciphering_algorithm != 0 && ciphering_algorithm != -1) { - if (ciphering_algorithm != 2) { + if (parameters->ciphering_algorithm != 0 && parameters->ciphering_algorithm != -1) { + if (parameters->ciphering_algorithm != 2) { LOG_E(PDCP, "FATAL: only nea2 supported for the moment\n"); exit(1); } entity->has_ciphering = 1; if (entity->free_security != NULL) entity->free_security(entity->security_context); - entity->security_context = nr_pdcp_security_nea2_init(entity->ciphering_key); + entity->security_context = nr_pdcp_security_nea2_init(entity->security_keys_and_algos.ciphering_key); entity->cipher = nr_pdcp_security_nea2_cipher; entity->free_security = nr_pdcp_security_nea2_free_security; } @@ -515,23 +512,27 @@ static void free_rx_list(nr_pdcp_entity_t *entity) * @brief PDCP entity re-establishment according to 5.1.2 of 3GPP TS 38.323 * @todo deal with ciphering/integrity algos and keys for transmitting/receiving entity procedures */ -static void nr_pdcp_entity_reestablish_drb_am(nr_pdcp_entity_t *entity) +static void nr_pdcp_entity_reestablish_drb_am(nr_pdcp_entity_t *entity, + const nr_pdcp_entity_security_keys_and_algos_t *security_parameters) { /* transmitting entity procedures */ - /* todo: deal with ciphering/integrity algos and keys */ + /* do nothing */ /* receiving entity procedures */ - /* todo: deal with ciphering/integrity algos and keys */ + /* do nothing */ + + /* ciphering and integrity: common for both tx and rx entities */ + entity->set_security(entity, security_parameters); /* Flag PDCP entity as re-established */ entity->entity_suspended = false; } -static void nr_pdcp_entity_reestablish_drb_um(nr_pdcp_entity_t *entity) +static void nr_pdcp_entity_reestablish_drb_um(nr_pdcp_entity_t *entity, + const nr_pdcp_entity_security_keys_and_algos_t *security_parameters) { /* transmitting entity procedures */ entity->tx_next = 0; - /* todo: deal with ciphering/integrity algos and keys */ /* receiving entity procedures */ /* deliver all SDUs if t_reordering is running */ @@ -542,17 +543,19 @@ static void nr_pdcp_entity_reestablish_drb_um(nr_pdcp_entity_t *entity) /* set rx_next and rx_deliv to the initial value */ entity->rx_next = 0; entity->rx_deliv = 0; - /* todo: deal with ciphering/integrity algos and keys */ + + /* ciphering and integrity: common for both tx and rx entities */ + entity->set_security(entity, security_parameters); /* Flag PDCP entity as re-established */ entity->entity_suspended = false; } -static void nr_pdcp_entity_reestablish_srb(nr_pdcp_entity_t *entity) +static void nr_pdcp_entity_reestablish_srb(nr_pdcp_entity_t *entity, + const nr_pdcp_entity_security_keys_and_algos_t *security_parameters) { /* transmitting entity procedures */ entity->tx_next = 0; - /* todo: deal with ciphering/integrity algos and keys */ /* receiving entity procedures */ free_rx_list(entity); @@ -561,7 +564,9 @@ static void nr_pdcp_entity_reestablish_srb(nr_pdcp_entity_t *entity) /* set rx_next and rx_deliv to the initial value */ entity->rx_next = 0; entity->rx_deliv = 0; - /* todo: deal with ciphering/integrity algos and keys */ + + /* ciphering and integrity: common for both tx and rx entities */ + entity->set_security(entity, security_parameters); /* Flag PDCP entity as re-established */ entity->entity_suspended = false; @@ -606,10 +611,7 @@ nr_pdcp_entity_t *new_nr_pdcp_entity( int sn_size, int t_reordering, int discard_timer, - int ciphering_algorithm, - int integrity_algorithm, - unsigned char *ciphering_key, - unsigned char *integrity_key) + const nr_pdcp_entity_security_keys_and_algos_t *security_parameters) { nr_pdcp_entity_t *ret; @@ -663,9 +665,7 @@ nr_pdcp_entity_t *new_nr_pdcp_entity( ret->is_gnb = is_gnb; - nr_pdcp_entity_set_security(ret, - integrity_algorithm, (char *)integrity_key, - ciphering_algorithm, (char *)ciphering_key); + nr_pdcp_entity_set_security(ret, security_parameters); return ret; } diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h index d26ce83b82..a5ef870749 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h @@ -48,6 +48,13 @@ typedef enum { NR_PDCP_SRB } nr_pdcp_entity_type_t; +typedef struct { + int integrity_algorithm; + int ciphering_algorithm; + uint8_t integrity_key[NR_K_KEY_SIZE]; + uint8_t ciphering_key[NR_K_KEY_SIZE]; +} nr_pdcp_entity_security_keys_and_algos_t; + typedef struct { //nr_pdcp_entity_type_t mode; /* PDU stats */ @@ -91,19 +98,15 @@ typedef struct nr_pdcp_entity_t { void (*delete_entity)(struct nr_pdcp_entity_t *entity); void (*release_entity)(struct nr_pdcp_entity_t *entity); void (*suspend_entity)(struct nr_pdcp_entity_t *entity); - void (*reestablish_entity)(struct nr_pdcp_entity_t *entity); + void (*reestablish_entity)(struct nr_pdcp_entity_t *entity, + const nr_pdcp_entity_security_keys_and_algos_t *parameters); void (*get_stats)(struct nr_pdcp_entity_t *entity, nr_pdcp_statistics_t *out); - /* set_security: pass -1 to integrity_algorithm / ciphering_algorithm - * to keep the current algorithm - * pass NULL to integrity_key / ciphering_key - * to keep the current key + /* set_security: pass -1 to parameters->integrity_algorithm / parameters->ciphering_algorithm + * to keep the corresponding current algorithm and key */ void (*set_security)(struct nr_pdcp_entity_t *entity, - int integrity_algorithm, - char *integrity_key, - int ciphering_algorithm, - char *ciphering_key); + const nr_pdcp_entity_security_keys_and_algos_t *parameters); /* check_integrity is used by RRC */ bool (*check_integrity)(struct nr_pdcp_entity_t *entity, @@ -148,10 +151,7 @@ typedef struct nr_pdcp_entity_t { /* security */ int has_ciphering; int has_integrity; - int ciphering_algorithm; - int integrity_algorithm; - unsigned char ciphering_key[16]; - unsigned char integrity_key[16]; + nr_pdcp_entity_security_keys_and_algos_t security_keys_and_algos; stream_security_context_t *security_context; void (*cipher)(stream_security_context_t *security_context, unsigned char *buffer, int length, @@ -196,10 +196,7 @@ nr_pdcp_entity_t *new_nr_pdcp_entity( int sn_size, int t_reordering, int discard_timer, - int ciphering_algorithm, - int integrity_algorithm, - unsigned char *ciphering_key, - unsigned char *integrity_key); + const nr_pdcp_entity_security_keys_and_algos_t *security_parameters); /* Get maximum PDCP PDU size */ int nr_max_pdcp_pdu_size(sdu_size_t sdu_size); diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index 17b1b02408..4582a85795 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -798,10 +798,7 @@ void deliver_pdu_srb_rlc(void *deliver_pdu_data, ue_id_t ue_id, int srb_id, void add_srb(int is_gnb, ue_id_t UEid, struct NR_SRB_ToAddMod *s, - int ciphering_algorithm, - int integrity_algorithm, - unsigned char *ciphering_key, - unsigned char *integrity_key) + const nr_pdcp_entity_security_keys_and_algos_t *security_parameters) { nr_pdcp_entity_t *pdcp_srb; nr_pdcp_ue_t *ue; @@ -829,10 +826,7 @@ void add_srb(int is_gnb, SHORT_SN_SIZE, t_Reordering, -1, - ciphering_algorithm, - integrity_algorithm, - ciphering_key, - integrity_key); + security_parameters); nr_pdcp_ue_add_srb_pdcp_entity(ue, srb_id, pdcp_srb); LOG_D(PDCP, "added srb %d to UE ID %ld\n", srb_id, UEid); @@ -843,10 +837,7 @@ void add_srb(int is_gnb, void add_drb(int is_gnb, ue_id_t UEid, struct NR_DRB_ToAddMod *s, - int ciphering_algorithm, - int integrity_algorithm, - unsigned char *ciphering_key, - unsigned char *integrity_key) + const nr_pdcp_entity_security_keys_and_algos_t *security_parameters) { nr_pdcp_entity_t *pdcp_drb; nr_pdcp_ue_t *ue; @@ -910,6 +901,10 @@ void add_drb(int is_gnb, exit(1); } + /* get actual ciphering and integrity algorithm based on pdcp_Config */ + nr_pdcp_entity_security_keys_and_algos_t actual_security_parameters = *security_parameters; + actual_security_parameters.ciphering_algorithm = has_ciphering ? security_parameters->ciphering_algorithm : 0; + actual_security_parameters.integrity_algorithm = has_integrity ? security_parameters->integrity_algorithm : 0; nr_pdcp_manager_lock(nr_pdcp_ue_manager); ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, UEid); @@ -922,10 +917,7 @@ void add_drb(int is_gnb, deliver_pdu_drb_gnb : deliver_pdu_drb_ue, ue, sn_size_dl, t_reordering, discard_timer, - has_ciphering ? ciphering_algorithm : 0, - has_integrity ? integrity_algorithm : 0, - has_ciphering ? ciphering_key : NULL, - has_integrity ? integrity_key : NULL); + &actual_security_parameters); nr_pdcp_ue_add_drb_pdcp_entity(ue, drb_id, pdcp_drb); LOG_I(PDCP, "added drb %d to UE ID %ld\n", drb_id, UEid); @@ -946,13 +938,11 @@ void add_drb(int is_gnb, void nr_pdcp_add_srbs(eNB_flag_t enb_flag, ue_id_t UEid, NR_SRB_ToAddModList_t *const srb2add_list, - const uint8_t security_modeP, - uint8_t *const kRRCenc, - uint8_t *const kRRCint) + const nr_pdcp_entity_security_keys_and_algos_t *security_parameters) { if (srb2add_list != NULL) { for (int i = 0; i < srb2add_list->list.count; i++) { - add_srb(enb_flag, UEid, srb2add_list->list.array[i], security_modeP & 0x0f, (security_modeP >> 4) & 0x0f, kRRCenc, kRRCint); + add_srb(enb_flag, UEid, srb2add_list->list.array[i], security_parameters); } } else LOG_W(PDCP, "nr_pdcp_add_srbs() with void list\n"); @@ -961,19 +951,14 @@ void nr_pdcp_add_srbs(eNB_flag_t enb_flag, void nr_pdcp_add_drbs(eNB_flag_t enb_flag, ue_id_t UEid, NR_DRB_ToAddModList_t *const drb2add_list, - const uint8_t security_modeP, - uint8_t *const kUPenc, - uint8_t *const kUPint) + const nr_pdcp_entity_security_keys_and_algos_t *security_parameters) { if (drb2add_list != NULL) { for (int i = 0; i < drb2add_list->list.count; i++) { add_drb(enb_flag, UEid, drb2add_list->list.array[i], - security_modeP & 0x0f, - (security_modeP >> 4) & 0x0f, - kUPenc, - kUPint); + security_parameters); } } else LOG_W(PDCP, "nr_pdcp_add_drbs() with void list\n"); @@ -1026,35 +1011,26 @@ void pdcp_config_set_security(const protocol_ctxt_t *const ctxt_pP, } void nr_pdcp_config_set_security(ue_id_t ue_id, - const rb_id_t rb_id, - const uint8_t security_modeP, - uint8_t *const kRRCenc_pP, - uint8_t *const kRRCint_pP, - uint8_t *const kUPenc_pP) + rb_id_t rb_id, + bool is_srb, + const nr_pdcp_entity_security_keys_and_algos_t *parameters) { nr_pdcp_ue_t *ue; nr_pdcp_entity_t *rb; - int integrity_algorithm; - int ciphering_algorithm; nr_pdcp_manager_lock(nr_pdcp_ue_manager); ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, ue_id); - /* TODO: proper handling of DRBs, for the moment only SRBs are handled */ - - rb = nr_pdcp_get_rb(ue, rb_id, true); + rb = nr_pdcp_get_rb(ue, rb_id, is_srb); if (rb == NULL) { nr_pdcp_manager_unlock(nr_pdcp_ue_manager); - LOG_E(PDCP, "no SRB found (ue_id %ld, rb_id %ld)\n", ue_id, rb_id); + LOG_E(PDCP, "no %s found (ue_id %ld, rb_id %ld)\n", is_srb ? "SRB" : "DRB", ue_id, rb_id); return; } - integrity_algorithm = (security_modeP>>4) & 0xf; - ciphering_algorithm = security_modeP & 0x0f; - rb->set_security(rb, integrity_algorithm, (char *)kRRCint_pP, - ciphering_algorithm, (char *)kRRCenc_pP); + rb->set_security(rb, parameters); nr_pdcp_manager_unlock(nr_pdcp_ue_manager); } @@ -1240,7 +1216,10 @@ void nr_pdcp_release_drb(ue_id_t ue_id, int drb_id) nr_pdcp_manager_unlock(nr_pdcp_ue_manager); } -void nr_pdcp_reestablishment(ue_id_t ue_id, int rb_id, bool srb_flag) +void nr_pdcp_reestablishment(ue_id_t ue_id, + int rb_id, + bool srb_flag, + const nr_pdcp_entity_security_keys_and_algos_t *security_parameters) { nr_pdcp_ue_t *ue; nr_pdcp_entity_t *rb; @@ -1251,7 +1230,7 @@ void nr_pdcp_reestablishment(ue_id_t ue_id, int rb_id, bool srb_flag) if (rb != NULL) { LOG_D(PDCP, "UE %4.4lx re-establishment of %sRB %d\n", ue_id, srb_flag ? "S" : "D", rb_id); - rb->reestablish_entity(rb); + rb->reestablish_entity(rb, security_parameters); LOG_I(PDCP, "%s %d re-established\n", srb_flag ? "SRB" : "DRB" , rb_id); } else { LOG_W(PDCP, "UE %4.4lx cannot re-establish %sRB %d, RB not found\n", ue_id, srb_flag ? "S" : "D", rb_id); diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h index 99f7fcdc81..54a5e0dcbc 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h @@ -49,20 +49,23 @@ bool pdcp_data_ind(const protocol_ctxt_t *const ctxt_pP, void nr_pdcp_add_drbs(eNB_flag_t enb_flag, ue_id_t UEid, NR_DRB_ToAddModList_t *const drb2add_list, - const uint8_t security_modeP, - uint8_t *const kUPenc, - uint8_t *const kUPint); + const nr_pdcp_entity_security_keys_and_algos_t *security_parameters); + +void nr_pdcp_add_srbs(eNB_flag_t enb_flag, + ue_id_t UEid, + NR_SRB_ToAddModList_t *const srb2add_list, + const nr_pdcp_entity_security_keys_and_algos_t *security_parameters); void add_drb(int is_gnb, ue_id_t UEid, struct NR_DRB_ToAddMod *s, - int ciphering_algorithm, - int integrity_algorithm, - unsigned char *ciphering_key, - unsigned char *integrity_key); + const nr_pdcp_entity_security_keys_and_algos_t *security_parameters); void nr_pdcp_remove_UE(ue_id_t ue_id); -void nr_pdcp_reestablishment(ue_id_t ue_id, int rb_id, bool srb_flag); +void nr_pdcp_reestablishment(ue_id_t ue_id, + int rb_id, + bool srb_flag, + const nr_pdcp_entity_security_keys_and_algos_t *security_parameters); void nr_pdcp_suspend_srb(ue_id_t ue_id, int srb_id); void nr_pdcp_suspend_drb(ue_id_t ue_id, int drb_id); @@ -71,21 +74,15 @@ void nr_pdcp_reconfigure_drb(ue_id_t ue_id, int drb_id, NR_PDCP_Config_t *pdcp_c void nr_pdcp_release_srb(ue_id_t ue_id, int srb_id); void nr_pdcp_release_drb(ue_id_t ue_id, int drb_id); - void add_srb(int is_gnb, ue_id_t UEid, struct NR_SRB_ToAddMod *s, - int ciphering_algorithm, - int integrity_algorithm, - unsigned char *ciphering_key, - unsigned char *integrity_key); + const nr_pdcp_entity_security_keys_and_algos_t *security_parameters); void nr_pdcp_config_set_security(ue_id_t ue_id, - const rb_id_t rb_id, - const uint8_t security_modeP, - uint8_t *const kRRCenc_pP, - uint8_t *const kRRCint_pP, - uint8_t *const kUPenc_pP); + rb_id_t rb_id, + bool is_srb, + const nr_pdcp_entity_security_keys_and_algos_t *parameters); bool nr_pdcp_check_integrity_srb(ue_id_t ue_id, int srb_id, diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index 5178ebc1d9..4f34a64999 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -147,7 +147,7 @@ void mac_rlc_data_ind(const module_id_t module_idP, num_tb_t num_tbP, crc_t *crcs_pP) { - if (module_idP != 0 || eNB_index != 0 || /*enb_flagP != 1 ||*/ MBMS_flagP != 0) { + if (eNB_index != 0 || /*enb_flagP != 1 ||*/ MBMS_flagP != 0) { LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); exit(1); } diff --git a/openair2/RRC/NR/MESSAGES/CMakeLists.txt b/openair2/RRC/NR/MESSAGES/CMakeLists.txt index c1982d8a37..f85c39bf73 100644 --- a/openair2/RRC/NR/MESSAGES/CMakeLists.txt +++ b/openair2/RRC/NR/MESSAGES/CMakeLists.txt @@ -36,3 +36,6 @@ target_link_libraries(asn1_nr_rrc PUBLIC asn1_nr_rrc_hdrs) target_compile_options(asn1_nr_rrc PRIVATE -DASN_DISABLE_OER_SUPPORT -w PUBLIC -DNR_RRC_VERSION=${NR_RRC_RELEASE}) +if (ENABLE_TESTS) + add_subdirectory(tests) +endif() diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c index fe41e9e210..3849e157c9 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -241,6 +241,7 @@ int do_SIB23_NR(rrc_gNB_carrier_data_t *carrier) 100); AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); + ASN_STRUCT_FREE(asn_DEF_NR_BCCH_DL_SCH_Message, sib_message); return((enc_rval.encoded+7)/8); } @@ -249,7 +250,6 @@ int do_RRCReject(uint8_t *const buffer) asn_enc_rval_t enc_rval; NR_DL_CCCH_Message_t dl_ccch_msg; NR_RRCReject_t *rrcReject; - NR_RejectWaitTime_t waitTime = 1; memset((void *)&dl_ccch_msg, 0, sizeof(NR_DL_CCCH_Message_t)); dl_ccch_msg.message.present = NR_DL_CCCH_MessageType_PR_c1; @@ -261,9 +261,9 @@ int do_RRCReject(uint8_t *const buffer) rrcReject->criticalExtensions.choice.rrcReject = CALLOC(1, sizeof(struct NR_RRCReject_IEs)); rrcReject->criticalExtensions.choice.rrcReject->waitTime = CALLOC(1, sizeof(NR_RejectWaitTime_t)); + *rrcReject->criticalExtensions.choice.rrcReject->waitTime = 1; rrcReject->criticalExtensions.present = NR_RRCReject__criticalExtensions_PR_rrcReject; - rrcReject->criticalExtensions.choice.rrcReject->waitTime = &waitTime; if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { xer_fprint(stdout, &asn_DEF_NR_DL_CCCH_Message, (void *)&dl_ccch_msg); @@ -277,6 +277,7 @@ int do_RRCReject(uint8_t *const buffer) AssertFatal(enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NR_DL_CCCH_Message, &dl_ccch_msg); LOG_D(NR_RRC,"RRCReject Encoded %zd bits (%zd bytes)\n", enc_rval.encoded,(enc_rval.encoded+7)/8); @@ -608,6 +609,7 @@ int do_NR_SA_UECapabilityEnquiry(const protocol_ctxt_t *const ctxt_pP, if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { xer_fprint(stdout, &asn_DEF_NR_UE_CapabilityRequestFilterNR, (void *)sa_band_filter); } + ASN_STRUCT_FREE(asn_DEF_NR_UE_CapabilityRequestFilterNR, sa_band_filter); ue_capabilityrat_request->capabilityRequestFilter = req_freq; @@ -843,6 +845,7 @@ int do_NR_RRCReconfigurationComplete_for_nsa( buffer_size); AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NR_RRCReconfigurationComplete, &rrc_complete_msg); LOG_A(NR_RRC, "rrcReconfigurationComplete Encoded %zd bits (%zd bytes)\n", enc_rval.encoded, (enc_rval.encoded+7)/8); return((enc_rval.encoded+7)/8); } @@ -962,6 +965,8 @@ int do_NR_ULInformationTransfer(uint8_t **buffer, uint32_t pdu_length, uint8_t * encoded = uper_encode_to_new_buffer (&asn_DEF_NR_UL_DCCH_Message, NULL, (void *) &ul_dcch_msg, (void **) buffer); AssertFatal(encoded > 0,"ASN1 message encoding failed (%s, %ld)!\n", "ULInformationTransfer",encoded); + ulInformationTransfer->dedicatedNAS_Message->buf = NULL; // Let caller decide when to free it + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NR_UL_DCCH_Message, &ul_dcch_msg); LOG_D(NR_RRC,"ULInformationTransfer Encoded %zd bytes\n",encoded); return encoded; @@ -1004,6 +1009,9 @@ int do_RRCReestablishmentRequest(uint8_t *buffer, buffer, 100); AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); + // shortMAC_I.buf is on the stack, cannot free useing ASN_STRUCT_FREE macro + rrcReestablishmentRequest->rrcReestablishmentRequest.ue_Identity.shortMAC_I.buf = NULL; + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NR_UL_CCCH_Message, &ul_ccch_msg); LOG_D(NR_RRC,"[UE] RRCReestablishmentRequest Encoded %zd bits (%zd bytes)\n", enc_rval.encoded, (enc_rval.encoded+7)/8); return((enc_rval.encoded+7)/8); } @@ -1055,6 +1063,7 @@ int do_RRCReestablishment(rrc_gNB_ue_context_t *const ue_context_pP, AssertFatal(enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NR_DL_DCCH_Message, &dl_dcch_msg); LOG_D(NR_RRC, "RRCReestablishment Encoded %u bits (%u bytes)\n", (uint32_t)enc_rval.encoded, (uint32_t)(enc_rval.encoded + 7) / 8); return ((enc_rval.encoded + 7) / 8); @@ -1090,6 +1099,7 @@ int do_RRCReestablishmentComplete(uint8_t *buffer, size_t buffer_size, int64_t r buffer_size); AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); LOG_D(NR_RRC,"[UE] RRCReestablishmentComplete Encoded %zd bits (%zd bytes)\n", enc_rval.encoded, (enc_rval.encoded+7)/8); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NR_UL_DCCH_Message, &ul_dcch_msg); return((enc_rval.encoded+7)/8); } @@ -1336,7 +1346,7 @@ void free_MeasConfig(NR_MeasConfig_t *mc) int do_NR_Paging(uint8_t Mod_id, uint8_t *buffer, uint32_t tmsi) { LOG_D(NR_RRC, "[gNB %d] do_NR_Paging start\n", Mod_id); - NR_PCCH_Message_t pcch_msg; + NR_PCCH_Message_t pcch_msg = {0}; pcch_msg.message.present = NR_PCCH_MessageType_PR_c1; asn1cCalloc(pcch_msg.message.choice.c1, c1); c1->present = NR_PCCH_MessageType__c1_PR_paging; @@ -1359,6 +1369,10 @@ int do_NR_Paging(uint8_t Mod_id, uint8_t *buffer, uint32_t tmsi) Mod_id, c1->choice.paging->pagingRecordList->list.count); asn_enc_rval_t enc_rval = uper_encode_to_buffer( &asn_DEF_NR_PCCH_Message, NULL, (void *)&pcch_msg, buffer, RRC_BUF_SIZE); + + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_NR_PCCH_Message, (void *)&pcch_msg); + } ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NR_PCCH_Message, &pcch_msg); if(enc_rval.encoded == -1) { LOG_I(NR_RRC, "[gNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", @@ -1366,9 +1380,5 @@ int do_NR_Paging(uint8_t Mod_id, uint8_t *buffer, uint32_t tmsi) return -1; } - if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout, &asn_DEF_NR_PCCH_Message, (void *)&pcch_msg); - } - return((enc_rval.encoded+7)/8); } diff --git a/openair2/RRC/NR/MESSAGES/tests/CMakeLists.txt b/openair2/RRC/NR/MESSAGES/tests/CMakeLists.txt new file mode 100644 index 0000000000..3f7bf45c0e --- /dev/null +++ b/openair2/RRC/NR/MESSAGES/tests/CMakeLists.txt @@ -0,0 +1,5 @@ +add_executable(test_asn1_msg test_asn1_msg.cpp) +target_link_libraries(test_asn1_msg PRIVATE nr_rrc SECURITY minimal_lib GTest::gtest UTIL) +add_dependencies(tests test_asn1_msg) +add_test(NAME test_asn1_msg + COMMAND ./test_asn1_msg) diff --git a/openair2/RRC/NR/MESSAGES/tests/test_asn1_msg.cpp b/openair2/RRC/NR/MESSAGES/tests/test_asn1_msg.cpp new file mode 100644 index 0000000000..9d1ee71f9c --- /dev/null +++ b/openair2/RRC/NR/MESSAGES/tests/test_asn1_msg.cpp @@ -0,0 +1,89 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include +extern "C" { +#include "openair2/RRC/NR/MESSAGES/asn1_msg.h" +#include "common/ran_context.h" +#include +#include "common/utils/assertions.h" +#include "common/utils/LOG/log.h" +RAN_CONTEXT_t RC; +} + +TEST(nr_asn1, rrc_reject) +{ + unsigned char buf[1000]; + EXPECT_GT(do_RRCReject(buf), 0); +} + +TEST(nr_asn1, sa_capability_enquiry) +{ + protocol_ctxt_t ctxt = {0}; + unsigned char buf[1000]; + EXPECT_GT(do_NR_SA_UECapabilityEnquiry(&ctxt, buf, 0), 0); +} + +TEST(nr_asn1, rrc_reconfiguration_complete_for_nsa) +{ + unsigned char buf[1000]; + EXPECT_GT(do_NR_RRCReconfigurationComplete_for_nsa(buf, 1000, 0), 0); +} + +TEST(nr_asn1, ul_information_transfer) +{ + unsigned char *buf = NULL; + unsigned char pdu[20] = {0}; + EXPECT_GT(do_NR_ULInformationTransfer(&buf, 20, pdu), 0); + EXPECT_NE(buf, nullptr); + free(buf); +} + +TEST(nr_asn1, rrc_reestablishment_request) +{ + unsigned char buf[1000]; + const uint16_t c_rnti = 1; + const uint32_t cell_id = 177; + EXPECT_GT(do_RRCReestablishmentRequest(buf, NR_ReestablishmentCause_reconfigurationFailure, cell_id, c_rnti), 0); +} + +TEST(nr_asn1, rrc_reestablishment) +{ + rrc_gNB_ue_context_t ue_context_pP; + memset(&ue_context_pP, 0, sizeof(ue_context_pP)); + unsigned char buf[1000]; + const uint32_t physical_cell_id = 177; + NR_ARFCN_ValueNR_t absoluteFrequencySSB = 2700000; + EXPECT_GT(do_RRCReestablishment(&ue_context_pP, buf, 1000, 0, physical_cell_id, absoluteFrequencySSB), 0); +} + +TEST(nr_asn1, paging) +{ + unsigned char buf[1000]; + EXPECT_GT(do_NR_Paging(0, buf, 0), 0); +} + +int main(int argc, char **argv) +{ + logInit(); + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h index 9ae787bd7e..d5aee94aab 100644 --- a/openair2/RRC/NR/nr_rrc_proto.h +++ b/openair2/RRC/NR/nr_rrc_proto.h @@ -145,20 +145,6 @@ void ue_cxt_mod_direct(MessageDef *msg, void prepare_and_send_ue_context_modification_f1(rrc_gNB_ue_context_t *ue_context_p, e1ap_bearer_setup_resp_t *e1ap_resp); -void nr_pdcp_add_srbs(eNB_flag_t enb_flag, - ue_id_t UEid, - NR_SRB_ToAddModList_t *const srb2add_list, - const uint8_t security_modeP, - uint8_t *const kRRCenc, - uint8_t *const kUPint); - -void nr_pdcp_add_drbs(eNB_flag_t enb_flag, - ue_id_t rntiMaybeUEid, - NR_DRB_ToAddModList_t *const drb2add_list, - const uint8_t security_modeP, - uint8_t *const kUPenc, - uint8_t *const kUPint); - void trigger_bearer_setup(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, int n, pdusession_t *sessions, uint64_t ueAggMaxBitRateDownlink); int rrc_gNB_generate_pcch_msg(sctp_assoc_t assoc_id, const NR_SIB1_t *sib, uint32_t tmsi, uint8_t paging_drx); diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index d22e25187d..266728fd54 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -389,19 +389,19 @@ static void activate_srb(gNB_RRC_UE_t *UE, int srb_id) srb->srb_Identity = srb_id; if (srb_id == 1) { - nr_pdcp_add_srbs(true, UE->rrc_ue_id, list, 0, NULL, NULL); + nr_pdcp_entity_security_keys_and_algos_t null_security_parameters = {0}; + nr_pdcp_add_srbs(true, UE->rrc_ue_id, list, &null_security_parameters); } else { - uint8_t kRRCenc[NR_K_KEY_SIZE] = {0}; - uint8_t kRRCint[NR_K_KEY_SIZE] = {0}; - nr_derive_key(RRC_ENC_ALG, UE->ciphering_algorithm, UE->kgnb, kRRCenc); - nr_derive_key(RRC_INT_ALG, UE->integrity_algorithm, UE->kgnb, kRRCint); + nr_pdcp_entity_security_keys_and_algos_t security_parameters; + security_parameters.ciphering_algorithm = UE->ciphering_algorithm; + security_parameters.integrity_algorithm = UE->integrity_algorithm; + nr_derive_key(RRC_ENC_ALG, UE->ciphering_algorithm, UE->kgnb, security_parameters.ciphering_key); + nr_derive_key(RRC_INT_ALG, UE->integrity_algorithm, UE->kgnb, security_parameters.integrity_key); nr_pdcp_add_srbs(true, UE->rrc_ue_id, list, - (UE->integrity_algorithm << 4) | UE->ciphering_algorithm, - kRRCenc, - kRRCint); + &security_parameters); } freeSRBlist(list); } @@ -850,6 +850,12 @@ static void cuup_notify_reestablishment(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue_p) /* increase DRB to modify counter */ pdu_e1->numDRB2Modify += 1; } + + req.cipheringAlgorithm = rrc->security.do_drb_ciphering ? ue_p->ciphering_algorithm : 0; + req.integrityProtectionAlgorithm = rrc->security.do_drb_integrity ? ue_p->integrity_algorithm : 0; + nr_derive_key(UP_ENC_ALG, req.cipheringAlgorithm, ue_p->kgnb, (uint8_t *)req.encryptionKey); + nr_derive_key(UP_INT_ALG, req.integrityProtectionAlgorithm, ue_p->kgnb, (uint8_t *)req.integrityProtectionKey); + /* Send E1 Bearer Context Modification Request (3GPP TS 38.463) */ sctp_assoc_t assoc_id = get_existing_cuup_for_ue(rrc, ue_p); rrc->cucp_cuup.bearer_context_mod(assoc_id, &req); @@ -866,7 +872,6 @@ static void rrc_gNB_generate_RRCReestablishment(rrc_gNB_ue_context_t *ue_context { module_id_t module_id = 0; gNB_RRC_INST *rrc = RC.nrrrc[module_id]; - int enable_ciphering = 0; gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; uint8_t buffer[RRC_BUF_SIZE] = {0}; uint8_t xid = rrc_gNB_get_next_transaction_identifier(module_id); @@ -878,30 +883,33 @@ static void rrc_gNB_generate_RRCReestablishment(rrc_gNB_ue_context_t *ue_context LOG_I(NR_RRC, "[RAPROC] UE %04x Logical Channel DL-DCCH, Generating NR_RRCReestablishment (bytes %d)\n", ue_p->rnti, size); /* Ciphering and Integrity according to TS 33.501 */ - uint8_t kRRCenc[NR_K_KEY_SIZE] = {0}; - uint8_t kRRCint[NR_K_KEY_SIZE] = {0}; - uint8_t kUPenc[NR_K_KEY_SIZE] = {0}; + nr_pdcp_entity_security_keys_and_algos_t security_parameters; /* Derive the keys from kgnb */ - if (ue_p->Srb[1].Active) - nr_derive_key(UP_ENC_ALG, ue_p->ciphering_algorithm, ue_p->kgnb, kUPenc); - nr_derive_key(RRC_ENC_ALG, ue_p->ciphering_algorithm, ue_p->kgnb, kRRCenc); - nr_derive_key(RRC_INT_ALG, ue_p->integrity_algorithm, ue_p->kgnb, kRRCint); + nr_derive_key(RRC_ENC_ALG, ue_p->ciphering_algorithm, ue_p->kgnb, security_parameters.ciphering_key); + nr_derive_key(RRC_INT_ALG, ue_p->integrity_algorithm, ue_p->kgnb, security_parameters.integrity_key); LOG_I(NR_RRC, - "Set PDCP security UE %d RNTI %04x nca %ld nia %d in RRCReestablishment\n", + "Set PDCP security UE %d RNTI %04x nea %ld nia %d in RRCReestablishment\n", ue_p->rrc_ue_id, ue_p->rnti, ue_p->ciphering_algorithm, ue_p->integrity_algorithm); - uint8_t security_mode = - enable_ciphering ? ue_p->ciphering_algorithm | (ue_p->integrity_algorithm << 4) : 0 | (ue_p->integrity_algorithm << 4); + /* RRCReestablishment is integrity protected but not ciphered, + * so let's configure only integrity protection right now. + * Ciphering is enabled below, after generating RRCReestablishment. + */ + security_parameters.integrity_algorithm = ue_p->integrity_algorithm; + security_parameters.ciphering_algorithm = 0; /* SRBs */ for (int srb_id = 1; srb_id < NR_NUM_SRB; srb_id++) { if (ue_p->Srb[srb_id].Active) - nr_pdcp_config_set_security(ue_p->rrc_ue_id, srb_id, security_mode, kRRCenc, kRRCint, kUPenc); + nr_pdcp_config_set_security(ue_p->rrc_ue_id, srb_id, true, &security_parameters); } /* Re-establish PDCP for SRB1, according to 5.3.7.4 of 3GPP TS 38.331 */ - nr_pdcp_reestablishment(ue_p->rrc_ue_id, 1, true); + nr_pdcp_reestablishment(ue_p->rrc_ue_id, + 1, + true, + &security_parameters); /* F1AP DL RRC Message Transfer */ f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rrc_ue_id); RETURN_IF_INVALID_ASSOC_ID(ue_data); @@ -912,6 +920,14 @@ static void rrc_gNB_generate_RRCReestablishment(rrc_gNB_ue_context_t *ue_context .old_gNB_DU_ue_id = &old_gNB_DU_ue_id}; deliver_dl_rrc_message_data_t data = {.rrc = rrc, .dl_rrc = &dl_rrc, .assoc_id = ue_data.du_assoc_id}; nr_pdcp_data_req_srb(ue_p->rrc_ue_id, DCCH, rrc_gNB_mui++, size, (unsigned char *const)buffer, rrc_deliver_dl_rrc_message, &data); + + /* RRCReestablishment has been generated, let's enable ciphering now. */ + security_parameters.ciphering_algorithm = ue_p->ciphering_algorithm; + /* SRBs */ + for (int srb_id = 1; srb_id < NR_NUM_SRB; srb_id++) { + if (ue_p->Srb[srb_id].Active) + nr_pdcp_config_set_security(ue_p->rrc_ue_id, srb_id, true, &security_parameters); + } } /// @brief Function tha processes RRCReestablishmentComplete message sent by the UE, after RRCReestasblishment request. @@ -933,9 +949,6 @@ static void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *co ue_p->Srb[1].Active = 1; - uint8_t send_security_mode_command = false; - nr_rrc_pdcp_config_security(ctxt_pP, ue_context_pP, send_security_mode_command); - gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; NR_CellGroupConfig_t *cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t)); @@ -966,7 +979,13 @@ static void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *co */ int srb_id = 2; if (ue_p->Srb[srb_id].Active) { - nr_pdcp_reestablishment(ue_p->rrc_ue_id, srb_id, true); + nr_pdcp_entity_security_keys_and_algos_t security_parameters; + security_parameters.ciphering_algorithm = ue_p->ciphering_algorithm; + security_parameters.integrity_algorithm = ue_p->integrity_algorithm; + nr_derive_key(RRC_ENC_ALG, ue_p->ciphering_algorithm, ue_p->kgnb, security_parameters.ciphering_key); + nr_derive_key(RRC_INT_ALG, ue_p->integrity_algorithm, ue_p->kgnb, security_parameters.integrity_key); + + nr_pdcp_reestablishment(ue_p->rrc_ue_id, srb_id, true, &security_parameters); } /* PDCP Reestablishment of DRBs according to 5.3.5.6.5 of 3GPP TS 38.331 (over E1) */ cuup_notify_reestablishment(rrc, ue_p); @@ -1891,6 +1910,11 @@ static void e1_send_bearer_updates(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, int n, f DevAssert(req.numPDUSessionsMod > 0); DevAssert(req.numPDUSessions == 0); + req.cipheringAlgorithm = rrc->security.do_drb_ciphering ? UE->ciphering_algorithm : 0; + req.integrityProtectionAlgorithm = rrc->security.do_drb_integrity ? UE->integrity_algorithm : 0; + nr_derive_key(UP_ENC_ALG, req.cipheringAlgorithm, UE->kgnb, (uint8_t *)req.encryptionKey); + nr_derive_key(UP_INT_ALG, req.integrityProtectionAlgorithm, UE->kgnb, (uint8_t *)req.integrityProtectionKey); + // send the E1 bearer modification request message to update F1-U tunnel info sctp_assoc_t assoc_id = get_existing_cuup_for_ue(rrc, UE); rrc->cucp_cuup.bearer_context_mod(assoc_id, &req); diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index d024eff20f..003db92ab7 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -135,33 +135,29 @@ nr_rrc_pdcp_config_security( ) //------------------------------------------------------------------------------ { - uint8_t kRRCenc[NR_K_KEY_SIZE] = {0}; - uint8_t kRRCint[NR_K_KEY_SIZE] = {0}; - uint8_t kUPenc[NR_K_KEY_SIZE] = {0}; //uint8_t *k_kdf = NULL; static int print_keys= 1; gNB_RRC_UE_t *UE = &ue_context_pP->ue_context; /* Derive the keys from kgnb */ - if (UE->Srb[1].Active || UE->Srb[2].Active) { - nr_derive_key(UP_ENC_ALG, UE->ciphering_algorithm, UE->kgnb, kUPenc); - } - - nr_derive_key(RRC_ENC_ALG, UE->ciphering_algorithm, UE->kgnb, kRRCenc); - nr_derive_key(RRC_INT_ALG, UE->integrity_algorithm, UE->kgnb, kRRCint); + nr_pdcp_entity_security_keys_and_algos_t security_parameters; + /* set ciphering algorithm depending on 'enable_ciphering' */ + security_parameters.ciphering_algorithm = enable_ciphering ? UE->ciphering_algorithm : 0; + security_parameters.integrity_algorithm = UE->integrity_algorithm; + /* use current ciphering algorithm, independently of 'enable_ciphering' to derive ciphering key */ + nr_derive_key(RRC_ENC_ALG, UE->ciphering_algorithm, UE->kgnb, security_parameters.ciphering_key); + nr_derive_key(RRC_INT_ALG, UE->integrity_algorithm, UE->kgnb, security_parameters.integrity_key); if ( LOG_DUMPFLAG( DEBUG_SECURITY ) ) { if (print_keys == 1 ) { print_keys =0; LOG_DUMPMSG(NR_RRC, DEBUG_SECURITY, UE->kgnb, 32, "\nKgNB:"); - LOG_DUMPMSG(NR_RRC, DEBUG_SECURITY, kRRCenc, 16,"\nKRRCenc:" ); - LOG_DUMPMSG(NR_RRC, DEBUG_SECURITY, kRRCint, 16,"\nKRRCint:" ); + LOG_DUMPMSG(NR_RRC, DEBUG_SECURITY, security_parameters.ciphering_key, 16,"\nKRRCenc:" ); + LOG_DUMPMSG(NR_RRC, DEBUG_SECURITY, security_parameters.integrity_key, 16,"\nKRRCint:" ); } } - uint8_t security_mode = - enable_ciphering ? UE->ciphering_algorithm | (UE->integrity_algorithm << 4) : 0 | (UE->integrity_algorithm << 4); - nr_pdcp_config_set_security(ctxt_pP->rntiMaybeUEid, DCCH, security_mode, kRRCenc, kRRCint, kUPenc); + nr_pdcp_config_set_security(ctxt_pP->rntiMaybeUEid, DCCH, true, &security_parameters); } //------------------------------------------------------------------------------ @@ -199,6 +195,13 @@ rrc_gNB_send_NGAP_NAS_FIRST_REQ( // NGAP_NAS_FIRST_REQ (message_p).nas_pdu.length, // ue_context_pP); + /* selected_plmn_identity: IE is 1-based, convert to 0-based (C array) */ + int selected_plmn_identity = rrcSetupComplete->selectedPLMN_Identity - 1; + if (selected_plmn_identity != 0) + LOG_E(NGAP, "UE %u: sent selected PLMN identity %ld, but only one PLMN supported\n", req->gNB_ue_ngap_id, rrcSetupComplete->selectedPLMN_Identity); + + req->selected_plmn_identity = 0; /* always zero because we only support one */ + /* Fill UE identities with available information */ if (UE->Initialue_identity_5g_s_TMSI.presence) { /* Fill s-TMSI */ @@ -220,27 +223,6 @@ rrc_gNB_send_NGAP_NAS_FIRST_REQ( UE->ue_guami.amf_set_id = req->ue_identity.guami.amf_set_id; UE->ue_guami.amf_pointer = req->ue_identity.guami.amf_pointer; - if (r_amf->plmn_Identity != NULL) { - AssertFatal(false, "At the moment, OAI RAN does not support multiple PLMN IDs. Therefore, this part has not been tested\n"); - /* selected_plmn_identity: IE is 1-based, convert to 0-based (C array) */ - int selected_plmn_identity = rrcSetupComplete->selectedPLMN_Identity - 1; - req->selected_plmn_identity = selected_plmn_identity; - - if ((r_amf->plmn_Identity->mcc != NULL) && (r_amf->plmn_Identity->mcc->list.count > 0)) { - /* Use first indicated PLMN MCC if it is defined */ - req->ue_identity.guami.mcc = *r_amf->plmn_Identity->mcc->list.array[selected_plmn_identity]; - LOG_I(NGAP, "[gNB %d] Build NGAP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MCC %u ue %x\n", ctxt_pP->module_id, req->ue_identity.guami.mcc, UE->rnti); - } - - if (r_amf->plmn_Identity->mnc.list.count > 0) { - /* Use first indicated PLMN MNC if it is defined */ - req->ue_identity.guami.mnc = *r_amf->plmn_Identity->mnc.list.array[selected_plmn_identity]; - LOG_I(NGAP, "[gNB %d] Build NGAP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MNC %u ue %x\n", ctxt_pP->module_id, req->ue_identity.guami.mnc, UE->rnti); - } - } else { - /* TODO */ - } - LOG_I(NGAP, "[gNB %d] Build NGAP_NAS_FIRST_REQ adding in s_TMSI: GUAMI amf_set_id %u amf_region_id %u ue %x\n", ctxt_pP->module_id, diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index 0aad9ea503..4347b83a19 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -126,8 +126,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a gtpv1u_enb_create_tunnel_req_t create_tunnel_req; gtpv1u_enb_create_tunnel_resp_t create_tunnel_resp; protocol_ctxt_t ctxt={0}; - uint8_t kUPenc[NR_K_KEY_SIZE] = {0}; - uint8_t kUPint[NR_K_KEY_SIZE] = {0}; + nr_pdcp_entity_security_keys_and_algos_t security_parameters = {0}; int i; gNB_RRC_UE_t *UE = &ue_context_p->ue_context; @@ -218,8 +217,10 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a LOG_I(RRC, "selecting integrity algorithm %d\n", UE->integrity_algorithm); /* derive UP security key */ - nr_derive_key(UP_ENC_ALG, UE->ciphering_algorithm, UE->kgnb, kUPenc); - nr_derive_key(UP_INT_ALG, UE->integrity_algorithm, UE->kgnb, kUPint); + security_parameters.ciphering_algorithm = UE->ciphering_algorithm; + security_parameters.integrity_algorithm = UE->integrity_algorithm; + nr_derive_key(UP_ENC_ALG, UE->ciphering_algorithm, UE->kgnb, security_parameters.ciphering_key); + nr_derive_key(UP_INT_ALG, UE->integrity_algorithm, UE->kgnb, security_parameters.integrity_key); e_NR_CipheringAlgorithm cipher_algo; switch (UE->ciphering_algorithm) { @@ -388,9 +389,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a nr_pdcp_add_drbs(ctxt.enb_flag, rrc_ue_id, ue_context_p->ue_context.rb_config->drb_ToAddModList, - (ue_context_p->ue_context.integrity_algorithm << 4) | ue_context_p->ue_context.ciphering_algorithm, - kUPenc, - kUPint); + &security_parameters); ctxt.rntiMaybeUEid = du_ue_id; // assume only a single bearer diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 980f793c0a..c4efe51e8b 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -225,7 +225,7 @@ static void nr_rrc_ue_process_rrcReconfiguration(NR_UE_RRC_INST_t *rrc, nr_rrc_cellgroup_configuration(rrc, cellGroupConfig); AssertFatal(!get_softmodem_params()->sa, "secondaryCellGroup only used in NSA for now\n"); - nr_rrc_mac_config_req_cg(0, 0, cellGroupConfig, rrc->UECap.UE_NR_Capability); + nr_rrc_mac_config_req_cg(rrc->ue_id, 0, cellGroupConfig, rrc->UECap.UE_NR_Capability); asn1cFreeStruc(asn_DEF_NR_CellGroupConfig, cellGroupConfig); } if (ie->measConfig != NULL) { @@ -631,14 +631,14 @@ static void nr_rrc_handle_msg3_indication(NR_UE_RRC_INST_t *rrc, rnti_t rnti) nr_timer_start(&tac->T301); int srb_id = 1; // re-establish PDCP for SRB1 - nr_pdcp_reestablishment(rrc->ue_id, srb_id, true); + // (and suspend integrity protection and ciphering for SRB1) + nr_pdcp_entity_security_keys_and_algos_t null_security_parameters = {0}; + nr_pdcp_reestablishment(rrc->ue_id, srb_id, true, &null_security_parameters); // re-establish RLC for SRB1 int lc_id = nr_rlc_get_lcid_from_rb(rrc->ue_id, true, 1); nr_rlc_reestablish_entity(rrc->ue_id, lc_id); // apply the specified configuration defined in 9.2.1 for SRB1 nr_rlc_reconfigure_entity(rrc->ue_id, lc_id, NULL); - // suspend integrity protection and ciphering for SRB1 - nr_pdcp_config_set_security(rrc->ue_id, srb_id, 0, NULL, NULL, NULL); // resume SRB1 rrc->Srb[srb_id] = RB_ESTABLISHED; break; @@ -1047,21 +1047,19 @@ static void nr_rrc_ue_process_securityModeCommand(NR_UE_RRC_INST_t *ue_rrc, ue_rrc->integrityProtAlgorithm = *securityConfigSMC->securityAlgorithmConfig.integrityProtAlgorithm; } - uint8_t kRRCenc[NR_K_KEY_SIZE] = {0}; - uint8_t kUPenc[NR_K_KEY_SIZE] = {0}; - uint8_t kRRCint[NR_K_KEY_SIZE] = {0}; - nr_derive_key(UP_ENC_ALG, ue_rrc->cipheringAlgorithm, ue_rrc->kgnb, kUPenc); - nr_derive_key(RRC_ENC_ALG, ue_rrc->cipheringAlgorithm, ue_rrc->kgnb, kRRCenc); - nr_derive_key(RRC_INT_ALG, ue_rrc->integrityProtAlgorithm, ue_rrc->kgnb, kRRCint); + nr_pdcp_entity_security_keys_and_algos_t security_parameters; + nr_derive_key(RRC_ENC_ALG, ue_rrc->cipheringAlgorithm, ue_rrc->kgnb, security_parameters.ciphering_key); + nr_derive_key(RRC_INT_ALG, ue_rrc->integrityProtAlgorithm, ue_rrc->kgnb, security_parameters.integrity_key); - log_dump(NR_RRC, ue_rrc->kgnb, 32, LOG_DUMP_CHAR, "deriving kRRCenc, kRRCint and kUPenc from KgNB="); + log_dump(NR_RRC, ue_rrc->kgnb, 32, LOG_DUMP_CHAR, "deriving kRRCenc, kRRCint from KgNB="); /* for SecurityModeComplete, ciphering is not activated yet, only integrity */ - uint8_t security_mode = ue_rrc->integrityProtAlgorithm << 4; + security_parameters.ciphering_algorithm = 0; + security_parameters.integrity_algorithm = ue_rrc->integrityProtAlgorithm; // configure lower layers to apply SRB integrity protection and ciphering for (int i = 1; i < NR_NUM_SRB; i++) { if (ue_rrc->Srb[i] == RB_ESTABLISHED) - nr_pdcp_config_set_security(ue_rrc->ue_id, i, security_mode, kRRCenc, kRRCint, kUPenc); + nr_pdcp_config_set_security(ue_rrc->ue_id, i, true, &security_parameters); } NR_UL_DCCH_Message_t ul_dcch_msg = {0}; @@ -1094,10 +1092,10 @@ static void nr_rrc_ue_process_securityModeCommand(NR_UE_RRC_INST_t *ue_rrc, ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NR_UL_DCCH_Message, &ul_dcch_msg); /* disable both ciphering and integrity */ - security_mode = 0; + nr_pdcp_entity_security_keys_and_algos_t null_security_parameters = {0}; for (int i = 1; i < NR_NUM_SRB; i++) { if (ue_rrc->Srb[i] == RB_ESTABLISHED) - nr_pdcp_config_set_security(ue_rrc->ue_id, i, security_mode, NULL, NULL, NULL); + nr_pdcp_config_set_security(ue_rrc->ue_id, i, true, &null_security_parameters); } srb_id = 1; // SecurityModeFailure in SRB1 @@ -1139,12 +1137,11 @@ static void nr_rrc_ue_process_securityModeCommand(NR_UE_RRC_INST_t *ue_rrc, nr_pdcp_data_req_srb(ue_rrc->ue_id, srb_id, 0, (enc_rval.encoded + 7) / 8, buffer, deliver_pdu_srb_rlc, NULL); /* after encoding SecurityModeComplete we activate both ciphering and integrity */ - security_mode = ue_rrc->cipheringAlgorithm | (ue_rrc->integrityProtAlgorithm << 4); + security_parameters.ciphering_algorithm = ue_rrc->cipheringAlgorithm; // configure lower layers to apply SRB integrity protection and ciphering for (int i = 1; i < NR_NUM_SRB; i++) { if (ue_rrc->Srb[i] == RB_ESTABLISHED) - /* pass NULL to keep current keys */ - nr_pdcp_config_set_security(ue_rrc->ue_id, i, security_mode, NULL, NULL, NULL); + nr_pdcp_config_set_security(ue_rrc->ue_id, i, true, &security_parameters); } } @@ -1416,10 +1413,8 @@ static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc, ue_rrc->Srb[3] = RB_NOT_PRESENT; } - uint8_t kRRCenc[NR_K_KEY_SIZE] = {0}; - uint8_t kRRCint[NR_K_KEY_SIZE] = {0}; - uint8_t kUPenc[NR_K_KEY_SIZE] = {0}; - uint8_t kUPint[NR_K_KEY_SIZE] = {0}; + nr_pdcp_entity_security_keys_and_algos_t security_rrc_parameters = {0}; + nr_pdcp_entity_security_keys_and_algos_t security_up_parameters = {0}; if (ue_rrc->as_security_activated) { if (radioBearerConfig->securityConfig != NULL) { @@ -1435,10 +1430,14 @@ static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc, ue_rrc->integrityProtAlgorithm = *radioBearerConfig->securityConfig->securityAlgorithmConfig->integrityProtAlgorithm; } } - nr_derive_key(RRC_ENC_ALG, ue_rrc->cipheringAlgorithm, ue_rrc->kgnb, kRRCenc); - nr_derive_key(RRC_INT_ALG, ue_rrc->integrityProtAlgorithm, ue_rrc->kgnb, kRRCint); - nr_derive_key(UP_ENC_ALG, ue_rrc->cipheringAlgorithm, ue_rrc->kgnb, kUPenc); - nr_derive_key(UP_INT_ALG, ue_rrc->integrityProtAlgorithm, ue_rrc->kgnb, kUPint); + security_rrc_parameters.ciphering_algorithm = ue_rrc->cipheringAlgorithm; + security_rrc_parameters.integrity_algorithm = ue_rrc->integrityProtAlgorithm; + nr_derive_key(RRC_ENC_ALG, ue_rrc->cipheringAlgorithm, ue_rrc->kgnb, security_rrc_parameters.ciphering_key); + nr_derive_key(RRC_INT_ALG, ue_rrc->integrityProtAlgorithm, ue_rrc->kgnb, security_rrc_parameters.integrity_key); + security_up_parameters.ciphering_algorithm = ue_rrc->cipheringAlgorithm; + security_up_parameters.integrity_algorithm = ue_rrc->integrityProtAlgorithm; + nr_derive_key(UP_ENC_ALG, ue_rrc->cipheringAlgorithm, ue_rrc->kgnb, security_up_parameters.ciphering_key); + nr_derive_key(UP_INT_ALG, ue_rrc->integrityProtAlgorithm, ue_rrc->kgnb, security_up_parameters.integrity_key); } if (radioBearerConfig->srb_ToAddModList != NULL) { @@ -1449,18 +1448,16 @@ static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc, add_srb(false, ue_rrc->ue_id, radioBearerConfig->srb_ToAddModList->list.array[cnt], - ue_rrc->cipheringAlgorithm, - ue_rrc->integrityProtAlgorithm, - kRRCenc, - kRRCint); + &security_rrc_parameters); } else { AssertFatal(srb->discardOnPDCP == NULL, "discardOnPDCP not yet implemented\n"); if (srb->reestablishPDCP) { ue_rrc->Srb[srb->srb_Identity] = RB_ESTABLISHED; - nr_pdcp_reestablishment(ue_rrc->ue_id, srb->srb_Identity, true); - // TODO configure the PDCP entity to apply the integrity protection algorithm - // TODO configure the PDCP entity to apply the ciphering algorithm + nr_pdcp_reestablishment(ue_rrc->ue_id, + srb->srb_Identity, + true, + &security_rrc_parameters); } if (srb->pdcp_Config && srb->pdcp_Config->t_Reordering) nr_pdcp_reconfigure_srb(ue_rrc->ue_id, srb->srb_Identity, *srb->pdcp_Config->t_Reordering); @@ -1489,9 +1486,20 @@ static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc, if (get_DRB_status(ue_rrc, DRB_id) != RB_NOT_PRESENT) { if (drb->reestablishPDCP) { set_DRB_status(ue_rrc, DRB_id, RB_ESTABLISHED); - nr_pdcp_reestablishment(ue_rrc->ue_id, DRB_id, false); - // TODO configure the PDCP entity to apply the integrity protection algorithm - // TODO configure the PDCP entity to apply the ciphering algorithm + /* get integrity and cipehring settings from radioBearerConfig */ + bool has_integrity = drb->pdcp_Config != NULL + && drb->pdcp_Config->drb != NULL + && drb->pdcp_Config->drb->integrityProtection != NULL; + bool has_ciphering = !(drb->pdcp_Config != NULL + && drb->pdcp_Config->ext1 != NULL + && drb->pdcp_Config->ext1->cipheringDisabled != NULL); + security_up_parameters.ciphering_algorithm = has_ciphering ? ue_rrc->cipheringAlgorithm : 0; + security_up_parameters.integrity_algorithm = has_integrity ? ue_rrc->integrityProtAlgorithm : 0; + /* re-establish */ + nr_pdcp_reestablishment(ue_rrc->ue_id, + DRB_id, + false, + &security_up_parameters); } AssertFatal(drb->recoverPDCP == NULL, "recoverPDCP not yet implemented\n"); /* sdap-Config is included (SA mode) */ @@ -1507,10 +1515,7 @@ static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc, add_drb(false, ue_rrc->ue_id, radioBearerConfig->drb_ToAddModList->list.array[cnt], - ue_rrc->cipheringAlgorithm, - ue_rrc->integrityProtAlgorithm, - kUPenc, - kUPint); + &security_up_parameters); } } } // drb_ToAddModList // @@ -1550,17 +1555,13 @@ static void nr_rrc_ue_process_rrcReestablishment(NR_UE_RRC_INST_t *rrc, // update the K gNB key based on the current K gNB key or the NH, using the stored nextHopChainingCount value nr_derive_key_ng_ran_star(rrc->phyCellID, rrc->arfcn_ssb, rrc->kgnb, rrc->kgnb); - // derive the K RRCenc and K UPenc keys associated with the previously configured cipheringAlgorithm - // derive the K RRCint and K UPint keys associated with the previously configured integrityProtAlgorithm - uint8_t kRRCenc[16] = {0}; - uint8_t kRRCint[16] = {0}; - uint8_t kUPenc[16] = {0}; - uint8_t kUPint[16] = {0}; - - nr_derive_key(UP_ENC_ALG, rrc->cipheringAlgorithm, rrc->kgnb, kUPenc); - nr_derive_key(UP_INT_ALG, rrc->integrityProtAlgorithm, rrc->kgnb, kUPint); - nr_derive_key(RRC_ENC_ALG, rrc->cipheringAlgorithm, rrc->kgnb, kRRCenc); - nr_derive_key(RRC_INT_ALG, rrc->integrityProtAlgorithm, rrc->kgnb, kRRCint); + // derive the K RRCenc key associated with the previously configured cipheringAlgorithm + // derive the K RRCint key associated with the previously configured integrityProtAlgorithm + nr_pdcp_entity_security_keys_and_algos_t security_parameters; + security_parameters.ciphering_algorithm = rrc->cipheringAlgorithm; + security_parameters.integrity_algorithm = rrc->integrityProtAlgorithm; + nr_derive_key(RRC_ENC_ALG, rrc->cipheringAlgorithm, rrc->kgnb, security_parameters.ciphering_key); + nr_derive_key(RRC_INT_ALG, rrc->integrityProtAlgorithm, rrc->kgnb, security_parameters.integrity_key); // TODO request lower layers to verify the integrity protection of the RRCReestablishment message // TODO if the integrity protection check of the RRCReestablishment message fails -> go to IDLE @@ -1568,9 +1569,7 @@ static void nr_rrc_ue_process_rrcReestablishment(NR_UE_RRC_INST_t *rrc, // configure lower layers to resume integrity protection for SRB1 // configure lower layers to resume ciphering for SRB1 int srb_id = 1; - int security_mode = (rrc->integrityProtAlgorithm << 4) - | rrc->cipheringAlgorithm; - nr_pdcp_config_set_security(rrc->ue_id, srb_id, security_mode, kRRCenc, kRRCint, kUPenc); + nr_pdcp_config_set_security(rrc->ue_id, srb_id, true, &security_parameters); // release the measurement gap configuration indicated by the measGapConfig, if configured rrcPerNB_t *rrcNB = rrc->perNB + gNB_index;