diff --git a/ci-scripts/Jenkinsfile-GitLab-Container b/ci-scripts/Jenkinsfile-GitLab-Container index 118eb844d4..8f0341a3cd 100644 --- a/ci-scripts/Jenkinsfile-GitLab-Container +++ b/ci-scripts/Jenkinsfile-GitLab-Container @@ -36,7 +36,6 @@ pipeline { label nodeExecutor } options { - disableConcurrentBuilds() timestamps() gitLabConnection('OAI GitLab') ansiColor('xterm') @@ -425,28 +424,26 @@ pipeline { } } } - - //avra is offline, re-enable once it is available - //stage ("T1-Offload-Test") { - // when { expression {do5Gtest} } - // steps { - // script { - // triggerSlaveJob ('RAN-T1-Offload-Test', 'T1-Offload-Test') - // } - // } - // post { - // always { - // script { - // finalizeSlaveJob('RAN-T1-Offload-Test') - // } - // } - // failure { - // script { - // currentBuild.result = 'FAILURE' - // } - // } - // } - //} + stage ("Interop-F1") { + when { expression {do5Gtest} } + steps { + script { + triggerSlaveJob ('RAN-Interop-F1', 'Interop-F1') + } + } + post { + always { + script { + finalizeSlaveJob('RAN-Interop-F1') + } + } + failure { + script { + currentBuild.result = 'FAILURE' + } + } + } + } } } stage ("DockerHub-Push") { diff --git a/ci-scripts/Jenkinsfile-cluster b/ci-scripts/Jenkinsfile-cluster index 013fe744c3..f210275bd9 100644 --- a/ci-scripts/Jenkinsfile-cluster +++ b/ci-scripts/Jenkinsfile-cluster @@ -61,7 +61,6 @@ pipeline { label pythonExecutor } options { - disableConcurrentBuilds() timestamps() ansiColor('xterm') lock(extra: lockResources) diff --git a/ci-scripts/Jenkinsfile-physim-deploy b/ci-scripts/Jenkinsfile-physim-deploy index ef5b1f2852..431db144ff 100644 --- a/ci-scripts/Jenkinsfile-physim-deploy +++ b/ci-scripts/Jenkinsfile-physim-deploy @@ -55,7 +55,6 @@ pipeline { label pythonExecutor } options { - disableConcurrentBuilds() timestamps() ansiColor('xterm') lock(extra: lockResources) diff --git a/ci-scripts/Jenkinsfile-push-registry b/ci-scripts/Jenkinsfile-push-registry index d05c167f6f..541999e8ff 100644 --- a/ci-scripts/Jenkinsfile-push-registry +++ b/ci-scripts/Jenkinsfile-push-registry @@ -36,7 +36,6 @@ pipeline { label nodeExecutor } options { - disableConcurrentBuilds() ansiColor('xterm') lock(extra: lockResources) } diff --git a/ci-scripts/Jenkinsfile-tmp-full-ran b/ci-scripts/Jenkinsfile-tmp-full-ran index a074ef3369..57ac8ea919 100644 --- a/ci-scripts/Jenkinsfile-tmp-full-ran +++ b/ci-scripts/Jenkinsfile-tmp-full-ran @@ -61,7 +61,6 @@ pipeline { label pythonExecutor } options { - disableConcurrentBuilds() ansiColor('xterm') lock(extra: lockResources) } diff --git a/ci-scripts/Jenkinsfile-tmp-multi-enb b/ci-scripts/Jenkinsfile-tmp-multi-enb index f8a0216fff..d5b303d5ac 100644 --- a/ci-scripts/Jenkinsfile-tmp-multi-enb +++ b/ci-scripts/Jenkinsfile-tmp-multi-enb @@ -50,7 +50,6 @@ pipeline { label pythonExecutor } options { - disableConcurrentBuilds() ansiColor('xterm') lock(extra: lockResources) } diff --git a/ci-scripts/Jenkinsfile-tmp-multi-enb-nsa b/ci-scripts/Jenkinsfile-tmp-multi-enb-nsa index 078adb2a68..00690e1298 100644 --- a/ci-scripts/Jenkinsfile-tmp-multi-enb-nsa +++ b/ci-scripts/Jenkinsfile-tmp-multi-enb-nsa @@ -52,7 +52,6 @@ def StatusForDb = "" pipeline { agent {label pythonExecutor} options { - disableConcurrentBuilds() ansiColor('xterm') lock(extra: lockResources) } diff --git a/ci-scripts/Jenkinsfile-tmp-ran b/ci-scripts/Jenkinsfile-tmp-ran index 037f7e6897..f396aad757 100644 --- a/ci-scripts/Jenkinsfile-tmp-ran +++ b/ci-scripts/Jenkinsfile-tmp-ran @@ -63,7 +63,6 @@ pipeline { label pythonExecutor } options { - disableConcurrentBuilds() ansiColor('xterm') lock(extra: lockResources) } diff --git a/ci-scripts/Jenkinsfile-tmp-ue b/ci-scripts/Jenkinsfile-tmp-ue index 97e878cd25..aea976cc3f 100644 --- a/ci-scripts/Jenkinsfile-tmp-ue +++ b/ci-scripts/Jenkinsfile-tmp-ue @@ -63,7 +63,6 @@ pipeline { label pythonExecutor } options { - disableConcurrentBuilds() ansiColor('xterm') lock(extra: lockResources) } diff --git a/ci-scripts/xml_files/container_5g_rfsim_f1_accelleran.xml b/ci-scripts/xml_files/container_5g_rfsim_f1_accelleran.xml new file mode 100644 index 0000000000..d727fdfd1e --- /dev/null +++ b/ci-scripts/xml_files/container_5g_rfsim_f1_accelleran.xml @@ -0,0 +1,74 @@ + + + rfsim-5gnr-f1-accelleran + F1 DU Interop Accelleran CU + wrench + + 111111 + 000020 + 000021 + 020021 + 100021 + 100022 + + + + + Pull_Local_Registry + Pull Images from Local Registry + 0 + oai-gnb oai-nr-ue + + + + DeployGenObject + Deploy OAI-DU + yaml_files/5g_rfsimulator_accelleran + oai-du + 1 + + + + DeployGenObject + Deploy nrUE + yaml_files/5g_rfsimulator_accelleran + oai-nr-ue + 2 + + + + PingFromContainer + Test Connectivity (ping) + rfsim5g-oai-nr-ue + -I oaitun_ue1 -c 20 12.1.1.1 + 0 + + + + UndeployGenObject + Undeploy all OAI 5G stack + yaml_files/5g_rfsimulator_accelleran + + + diff --git a/ci-scripts/xml_files/container_5g_rfsim_f1_accelleran_down.xml b/ci-scripts/xml_files/container_5g_rfsim_f1_accelleran_down.xml new file mode 100644 index 0000000000..0a4f9fcbfa --- /dev/null +++ b/ci-scripts/xml_files/container_5g_rfsim_f1_accelleran_down.xml @@ -0,0 +1,45 @@ + + + rfsim-5gnr-down-f1-accelleran + CleanUp + trash + + 100022 + 222222 + + + + + UndeployGenObject + Undeploy all OAI 5G stack + yaml_files/5g_rfsimulator_accelleran + + + + Clean_Test_Server_Images + Clean Test Images on Test Server + 0 + + + diff --git a/ci-scripts/yaml_files/5g_rfsimulator_accelleran/docker-compose.yaml b/ci-scripts/yaml_files/5g_rfsimulator_accelleran/docker-compose.yaml new file mode 100644 index 0000000000..3551cc27c6 --- /dev/null +++ b/ci-scripts/yaml_files/5g_rfsimulator_accelleran/docker-compose.yaml @@ -0,0 +1,38 @@ +version: '3.8' +services: + oai-du: + image: oaisoftwarealliance/oai-gnb:develop + privileged: true + container_name: rfsim5g-oai-du + network_mode: "host" + environment: + RFSIMULATOR: server + USE_VOLUMED_CONF: 'yes' + USE_ADDITIONAL_OPTIONS: --sa --rfsim --MACRLCs.[0].local_n_address 172.21.16.109 --MACRLCs.[0].remote_n_address 172.21.6.22 --log_config.global_log_options level,nocolor,time + volumes: + - ../../conf_files/gnb-du.band78.106prb.rfsim.conf:/opt/oai-gnb/etc/mounted.conf + healthcheck: + test: /bin/bash -c "pgrep nr-softmodem" + interval: 10s + timeout: 5s + retries: 5 + oai-nr-ue: + image: oaisoftwarealliance/oai-nr-ue:develop + privileged: true + container_name: rfsim5g-oai-nr-ue + network_mode: "host" + environment: + RFSIMULATOR: 127.0.0.1 + FULL_IMSI: '208990100001140' + FULL_KEY: 'fec86ba6eb707ed08905757b1bb44b8f' + OPC: 'C42449363BBAD02B66D16BC975D77CC1' + DNN: oai + NSSAI_SST: 1 + USE_ADDITIONAL_OPTIONS: --sa --rfsim -r 106 --numerology 1 -C 3619200000 --log_config.global_log_options level,nocolor,time + depends_on: + - oai-du + healthcheck: + test: /bin/bash -c "pgrep nr-uesoftmodem" + interval: 10s + timeout: 5s + retries: 5 diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index 79d0d9673e..681ea63a0f 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -33,6 +33,7 @@ OS_RELEASE=$(grep "^VERSION_ID=" /etc/os-release | sed "s/VERSION_ID=//" | sed " case "$OS_DISTRO" in fedora) OS_BASEDISTRO="fedora"; INSTALLER="dnf"; CMAKE="cmake" ;; rhel) OS_BASEDISTRO="fedora"; INSTALLER="yum"; CMAKE="cmake3" ;; + rocky) OS_BASEDISTRO="fedora"; INSTALLER="dnf"; CMAKE="cmake" ;; centos) OS_BASEDISTRO="centos"; INSTALLER="yum"; CMAKE="cmake3" ;; debian) OS_BASEDISTRO="debian"; INSTALLER="apt-get"; CMAKE="cmake" ;; ubuntu) OS_BASEDISTRO="debian"; INSTALLER="apt-get"; CMAKE="cmake" ;; @@ -126,6 +127,12 @@ check_supported_distribution() { "rhel9.3") return 0 ;; "centos7") return 0 ;; "centos8") return 0 ;; + "rocky8.7") return 0 ;; + "rocky8.8") return 0 ;; + "rocky8.9") return 0 ;; + "rocky9.1") return 0 ;; + "rocky9.2") return 0 ;; + "rocky9.3") return 0 ;; esac return 1 } @@ -300,7 +307,7 @@ install_usrp_uhd_driver_from_source(){ if [[ "$OS_DISTRO" == "ubuntu" ]]; then $SUDO /usr/local/lib/uhd/utils/uhd_images_downloader.py fi - if [[ "$OS_DISTRO" == "rhel" ]]; then + if [[ "$OS_DISTRO" == "rhel" ]] || [[ "$OS_DISTRO" == "rocky" ]]; then $SUDO /usr/local/lib64/uhd/utils/uhd_images_downloader.py fi fi @@ -367,7 +374,7 @@ check_install_usrp_uhd_driver(){ $SUDO $INSTALLER -y install $boost_libs_fedora $CMAKE $SUDO pip3 install mako requests fi - if [[ "$OS_DISTRO" == "rhel" ]] || [[ "$OS_DISTRO" == "centos" ]]; then + if [[ "$OS_DISTRO" == "rhel" ]] || [[ "$OS_DISTRO" == "centos" ]] || [[ "$OS_DISTRO" == "rocky" ]]; then if [ $IS_CONTAINER -eq 0 ] then # until EPEL repo hasn't bumped UHD driver to >=3.10 in EPEL, build driver from source @@ -389,13 +396,13 @@ install_usrp_uhd_driver() { # quick workaround for RHE7.6 local distribution=$(get_distribution_release) if [ -z $1 ]; then - if [[ "$OS_DISTRO" == "rhel" ]]; then + if [[ "$OS_DISTRO" == "rhel" ]] || [[ "$OS_DISTRO" == "rocky" ]]; then $SUDO /usr/local/bin/uhd_images_downloader else $SUDO uhd_images_downloader fi else - if [[ "$OS_DISTRO" == "rhel" ]]; then + if [[ "$OS_DISTRO" == "rhel" ]] || [[ "$OS_DISTRO" == "rocky" ]]; then $SUDO /usr/local/bin/uhd_images_downloader -i $1 else $SUDO uhd_images_downloader -i $1 @@ -562,7 +569,7 @@ check_install_additional_tools (){ libforms-bin \ libforms-dev \ xmlstarlet" - elif [[ "$OS_DISTRO" == "rhel" ]] || [[ "$OS_DISTRO" == "centos" ]]; then + elif [[ "$OS_DISTRO" == "rhel" ]] || [[ "$OS_DISTRO" == "centos" ]] || [[ "$OS_DISTRO" == "rocky" ]]; then PACKAGE_LIST="\ doxygen \ ctags \ @@ -623,7 +630,7 @@ check_install_oai_software() { xxd elif [[ "$OS_BASEDISTRO" == "fedora" ]]; then - if [[ "$OS_DISTRO" == "rhel" ]] || [[ "$OS_DISTRO" == "centos" ]]; then + if [[ "$OS_DISTRO" == "rhel" ]] || [[ "$OS_DISTRO" == "centos" ]] || [[ "$OS_DISTRO" == "rocky" ]]; then if rpm -q epel-release > /dev/null; then echo "EPEL repos already present. Good." else diff --git a/doc/F1-design.md b/doc/F1-design.md index 80417b1ae3..7e491f5346 100644 --- a/doc/F1-design.md +++ b/doc/F1-design.md @@ -11,6 +11,7 @@ + # 1. Introduction We use OpenAirInterface source code, and it's regular deployment scheme. @@ -208,3 +209,46 @@ DU rlc north output goes to du_pdcp_data_ind() that push a outgoing packet reque CU pdcp south output calls cu_rlc_data_ind() that do the same symetric processing. +# High-level F1-C code structure + +The F1 interface is used internally between CU (mostly RRC) and DU (mostly MAC) +to exchange information. In DL, the CU sends messages as defined by the +callbacks in `mac_rrc_dl.h`, whose implementation is defined in files +`mac_rrc_dl_direct.c` (monolithic) and `mac_rrc_dl_f1ap.c` (for F1AP). In the +monolithic case, the RRC calls directly into the message handler on the DU side +(`mac_rrc_dl_handler.c`). In the F1 case, an ITTI message is sent to the CU +task, sending an ASN.1-encoded F1AP message. The DU side's DU task decodes the +message, and then calls the corresponding handler in `mac_rrc_dl_handler.c`. +Thus, the message flow is the same in both F1 and monolithic cases, with the +difference that F1AP encodes the messages using ASN.1 and sends over a socket. + +In UL, the callbacks defined in `mac_rrc_ul.h` are implemented by +`mac_rrc_ul_direct.c` (monolithic) and `mac_rrc_ul_f1ap.c` (F1). In the direct +case, an ITTI message is directly sent to the RRC task (hence, there is no +dedicated handler). In F1, the DU task receives the ITTI message, encodes using +ASN.1, and sends it over a network socket. The CU task decodes, and sends the +same ITTI message to the RRC task as done directly in the monolithic case. + +``` + +-------------+ + | | + | CU/RRC | + | | + +-------------+ + | ^ + Callback def: mac_rrc_dl.h | | No handler needed: + F1 impl: mac_rrc_dl_f1ap.c | | RRC has ITTI +Monolithic: mac_rrc_dl_direct.c | | + | | + DL | | UL + | | + | | Callback def: mac_rrc_ul.h + Message handler: | | F1 impl: mac_rrc_ul_f1ap.c + mac_rrc_dl_handler.c | | Monolithic: mac_rrc_ul_direct.c + v | + +-------------+ + | | + | DU/MAC | + | | + +-------------+ +``` diff --git a/doc/TESTBenches.md b/doc/TESTBenches.md index aef3a7f63e..300d9cd56a 100644 --- a/doc/TESTBenches.md +++ b/doc/TESTBenches.md @@ -55,7 +55,7 @@ Note: The available resources, and their current usage, is indicated here: ### 5G AW2S Testbench -**Purpose**: AW2S tests with Amarisoft +**Purpose**: AW2S tests with Amarisoft UE simulator ![5G AW2S Testbench](testbenches_doc_resources/5g-aw2s-bench.png) @@ -82,7 +82,10 @@ Webhook - [RAN-gNB-N300-Timing-Phytest-LDPC](https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-gNB-N300-Timing-Phytest-LDPC/) - caracal + N310 - pure performance test through phy-test scheduler, see command line for more details -- [RAN-L2-Sim-Test-5G](https://jenkins-oai.eurecom.fr/job/RAN-L2-Sim-Test-4G/) +- [RAN-Interop-F1](https://jenkins-oai.eurecom.fr/job/RAN-Interop-F1/) + - ofqot (DU, 1x UE) + - F1 interoperability testing: sets up connection to Accelleran CU, UE connection and connectivity test +- [RAN-L2-Sim-Test-4G](https://jenkins-oai.eurecom.fr/job/RAN-L2-Sim-Test-4G/) - obelix (eNB, 1x UE, OAI EPC) - L2simulator: skips physical layer and uses proxy between eNB and UE - [RAN-L2-Sim-Test-5G](https://jenkins-oai.eurecom.fr/job/RAN-L2-Sim-Test-5G/) @@ -92,7 +95,7 @@ Webhook - hutch + B210, nano w/ ltebox + 2x UE - tests RRC inactivity timers, different bandwidths - [RAN-LTE-TDD-2x2-Container](https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-LTE-TDD-2x2-Container/) - - obelix + N310, porcepix, quectel + - obelix + N310, porcepix, nrmodule2 + Quectel - TM1 and TM2 test - [RAN-LTE-TDD-LTEBOX-Container](https://jenkins-oai.eurecom.fr/job/RAN-LTE-TDD-LTEBOX-Container/) - starsky + B210, nano w/ ltebox + 2x UE @@ -111,14 +114,15 @@ Webhook - uses RFsimulator, TDD 40MHz, FDD 40MHz, F1 split - [RAN-RHEL8-Cluster-Image-Builder](https://jenkins-oai.eurecom.fr/job/RAN-RHEL8-Cluster-Image-Builder/) - cluster (`Asterix-OC-oaicicd-session` resource): RHEL 8 image build using the OpenShift Cluster +- [RAN-SA-AW2S-CN5G](https://jenkins-oai.eurecom.fr/job/RAN-SA-AW2S-CN5G/) + - 5G-NR SA test setup: avra(RHEL9.1) + AW2S, amariue, OAI CN5G + - uses OpenShift cluster for CN deployment and container images for gNB deployment + - multi UE testing - [RAN-SA-B200-Module-SABOX-Container](https://jenkins-oai.eurecom.fr/job/RAN-SA-B200-Module-SABOX-Container/) - ofqot + B200, idefix + Quectel, nepes w/ sabox - basic SA test (20 MHz TDD), F1, reestablishment, ... -- [RAN-Ubuntu20-Image-Builder](https://jenkins-oai.eurecom.fr/job/RAN-Ubuntu18-Image-Builder/) +- [RAN-Ubuntu18-Image-Builder](https://jenkins-oai.eurecom.fr/job/RAN-Ubuntu18-Image-Builder/) - obelix: Ubuntu 20 image build using docker (Note: builds U20 images while pipeline is named U18!) -- [RAN-SA-AW2S-CN5G](https://jenkins-oai.eurecom.fr/job/RAN-SA-AW2S-CN5G/) - - 5G-NR SA test setup: Avra(RHEL9.1)/Manarola(U22PRO) + AW2S, Amarisoft UE x1, OAI CN5G - - uses OpenShift cluster for CN deployment and container images for gNB deployment ### RAN-CI-NSA-Trigger diff --git a/doc/testbenches_doc_resources/5g-aw2s-bench.pdf b/doc/testbenches_doc_resources/5g-aw2s-bench.pdf index 9799887112..b3f259dfaa 100644 Binary files a/doc/testbenches_doc_resources/5g-aw2s-bench.pdf and b/doc/testbenches_doc_resources/5g-aw2s-bench.pdf differ diff --git a/doc/testbenches_doc_resources/5g-aw2s-bench.png b/doc/testbenches_doc_resources/5g-aw2s-bench.png index 49082c04fc..77af2370d4 100644 Binary files a/doc/testbenches_doc_resources/5g-aw2s-bench.png and b/doc/testbenches_doc_resources/5g-aw2s-bench.png differ diff --git a/doc/testbenches_doc_resources/5g-aw2s-bench.tex b/doc/testbenches_doc_resources/5g-aw2s-bench.tex index 243d15babf..24065c7171 100644 --- a/doc/testbenches_doc_resources/5g-aw2s-bench.tex +++ b/doc/testbenches_doc_resources/5g-aw2s-bench.tex @@ -23,9 +23,11 @@ \node[below right=-0.7cm and 0.35cm of b78o.east] (anto2) {\includegraphics[width=0.3cm]{antenna}} edge (b78o); - \node[right=4cm of aw2s, label=above:Amarisoft UE] (amariue) + \node[right=3.5cm of aw2s, label=above:amariue] (amariue) {\includegraphics[width=0.7cm]{amariue}}; - \node[right=3cm of aw2s] (anto3) + \node[right=0.8cm of anto1] (anto3) + {\includegraphics[width=0.3cm]{antenna}} edge (amariue); + \node[right=0.8cm of anto2] (anto4) {\includegraphics[width=0.3cm]{antenna}} edge (amariue); \end{tikzpicture} diff --git a/doc/testbenches_doc_resources/amariue.png b/doc/testbenches_doc_resources/amariue.png index 72acb124c3..ea1fe0b769 100644 Binary files a/doc/testbenches_doc_resources/amariue.png and b/doc/testbenches_doc_resources/amariue.png differ diff --git a/doc/testbenches_doc_resources/aw2s.png b/doc/testbenches_doc_resources/aw2s.png index cc92e4c867..d2b34c6c4c 100644 Binary files a/doc/testbenches_doc_resources/aw2s.png and b/doc/testbenches_doc_resources/aw2s.png differ diff --git a/docker/Dockerfile.base.rocky b/docker/Dockerfile.base.rocky new file mode 100644 index 0000000000..e8eda721d2 --- /dev/null +++ b/docker/Dockerfile.base.rocky @@ -0,0 +1,58 @@ +#/* +# * 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 +# */ +#--------------------------------------------------------------------- +# +# Dockerfile for the Open-Air-Interface BUILD service +# Valid for Rocky 8.7 +# +#--------------------------------------------------------------------- + +ARG BASE_IMAGE=docker.io/rockylinux:8.7 +FROM $BASE_IMAGE AS ran-base + +ENV TZ=Europe/Paris +ENV BUILD_UHD_FROM_SOURCE=True +ENV UHD_VERSION=4.4.0.0 + +RUN dnf install 'dnf-command(config-manager)' -y && \ + dnf config-manager --set-enabled powertools && \ + dnf install epel-release -y && crb enable && \ + dnf update -y && \ + dnf install -y \ + #gcc needed for build_oai + gcc gcc-c++ \ + diffutils \ + file \ + psmisc \ + git \ + # python3-pip and pyyaml are used for conf template generation + python3-pip && \ + pip3 install --ignore-installed pyyaml + +#create the WORKDIR +WORKDIR /oai-ran +COPY . . + +#run build_oai -I to get the builder image +RUN /bin/sh oaienv && \ + cd cmake_targets && \ + mkdir -p log && \ + ./build_oai -I --install-optional-packages -w USRP diff --git a/docker/Dockerfile.build.rhel8.2 b/docker/Dockerfile.build.rhel8.2 index c7f111a01d..5dd370a02d 100644 --- a/docker/Dockerfile.build.rhel8.2 +++ b/docker/Dockerfile.build.rhel8.2 @@ -35,4 +35,4 @@ COPY . . RUN /bin/sh oaienv && \ cd cmake_targets && \ mkdir -p log && \ - ./build_oai --eNB --gNB --RU --UE --nrUE --ninja --build-lib "telnetsrv enbscope uescope nrscope" -w USRP --verbose-ci --noavx512 -c + ./build_oai --eNB --gNB --RU --UE --nrUE --ninja --build-lib "telnetsrv enbscope uescope nrscope" -w USRP --verbose-ci --noavx512 -c --cmake-opt -DCMAKE_C_FLAGS=-Wno-unused-function --cmake-opt -DCMAKE_CXX_FLAGS=-Wno-unused-function diff --git a/docker/Dockerfile.build.rocky b/docker/Dockerfile.build.rocky new file mode 100644 index 0000000000..1522844601 --- /dev/null +++ b/docker/Dockerfile.build.rocky @@ -0,0 +1,38 @@ +#/* +# * 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 +# */ +#--------------------------------------------------------------------- +# +# Dockerfile for the Open-Air-Interface BUILD service +# Valid for Rocky 8.7 +# +#--------------------------------------------------------------------- + +FROM ran-base:latest as ran-build + +RUN rm -Rf /oai-ran +WORKDIR /oai-ran +COPY . . + +#run build_oai to build the target image +RUN /bin/sh oaienv && \ + cd cmake_targets && \ + mkdir -p log && \ + ./build_oai --eNB --gNB --RU --UE --nrUE --ninja --build-lib "telnetsrv enbscope uescope nrscope" -w USRP --verbose-ci --noavx512 -c diff --git a/docker/Dockerfile.build.ubuntu20 b/docker/Dockerfile.build.ubuntu20 index fd4de7c22a..bd350bd780 100644 --- a/docker/Dockerfile.build.ubuntu20 +++ b/docker/Dockerfile.build.ubuntu20 @@ -35,4 +35,4 @@ COPY . . RUN /bin/sh oaienv && \ cd cmake_targets && \ mkdir -p log && \ - ./build_oai --eNB --gNB --RU --UE --nrUE --ninja --build-lib "telnetsrv enbscope uescope nrscope nrqtscope" -w USRP --verbose-ci --noavx512 -c --cmake-opt -DCMAKE_C_FLAGS=-Werror --cmake-opt -DCMAKE_CXX_FLAGS=-Werror + ./build_oai --eNB --gNB --RU --UE --nrUE --ninja --build-lib "telnetsrv enbscope uescope nrscope nrqtscope" -w USRP --verbose-ci --noavx512 -c --cmake-opt -DCMAKE_C_FLAGS=-Werror --cmake-opt -DCMAKE_CXX_FLAGS=-Werror --cmake-opt -DCMAKE_C_FLAGS=-Wno-unused-function --cmake-opt -DCMAKE_CXX_FLAGS=-Wno-unused-function diff --git a/docker/Dockerfile.clang.rhel8.2 b/docker/Dockerfile.clang.rhel8.2 index 11ead620ee..5111597f75 100644 --- a/docker/Dockerfile.clang.rhel8.2 +++ b/docker/Dockerfile.clang.rhel8.2 @@ -40,4 +40,4 @@ RUN /bin/sh oaienv && \ mkdir -p log && \ export CC=/usr/bin/clang && \ export CXX=/usr/bin/clang++ && \ - ./build_oai --phy_simulators --gNB --eNB --nrUE --UE --ninja --verbose-ci --noavx512 -c --cmake-opt -DCMAKE_C_FLAGS=-Werror --cmake-opt -DCMAKE_CXX_FLAGS=-Werror + ./build_oai --phy_simulators --gNB --eNB --nrUE --UE --ninja --verbose-ci --noavx512 -c --cmake-opt -DCMAKE_C_FLAGS=-Werror --cmake-opt -DCMAKE_CXX_FLAGS=-Werror --cmake-opt -DCMAKE_C_FLAGS=-Wno-unused-function --cmake-opt -DCMAKE_CXX_FLAGS=-Wno-unused-function diff --git a/docker/Dockerfile.eNB.rocky b/docker/Dockerfile.eNB.rocky new file mode 100644 index 0000000000..e2cc6d7a4c --- /dev/null +++ b/docker/Dockerfile.eNB.rocky @@ -0,0 +1,130 @@ +#/* +# * 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 +# */ +#--------------------------------------------------------------------- +# +# Dockerfile for the Open-Air-Interface BUILD service +# Valid for Rocky 8.7 +# +#--------------------------------------------------------------------- + +ARG BASE_IMAGE=docker.io/rockylinux:8.7 +FROM ran-base:latest AS enb-base + +FROM ran-build:latest AS enb-build + +RUN python3 ./docker/scripts/generateTemplate.py ./docker/scripts/enb_parameters.yaml && \ + cp /oai-ran/docker/scripts/enb_entrypoint.sh /oai-ran/docker/scripts/entrypoint.sh + +#start from scratch for target executable +FROM $BASE_IMAGE as oai-enb +ENV TZ=Europe/Paris + +RUN dnf update -y && \ + dnf install -y \ + lksctp-tools \ + tzdata \ + procps-ng \ + atlas \ + gdb \ + python3 \ + python3-pip \ + net-tools \ + iputils \ + iproute && \ + pip3 install six && \ + pip3 install requests && \ + echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf && \ + echo "/usr/local/lib64" >> /etc/ld.so.conf.d/local-lib.conf + +WORKDIR /opt/oai-enb/bin +COPY --from=enb-build \ + /oai-ran/cmake_targets/ran_build/build/lte-softmodem \ + /oai-ran/docker/scripts/entrypoint.sh \ + ./ + +COPY --from=enb-build \ + /oai-ran/cmake_targets/ran_build/build/liboai_eth_transpro.so \ + /oai-ran/cmake_targets/ran_build/build/librfsimulator.so \ + /oai-ran/cmake_targets/ran_build/build/liboai_usrpdevif.so \ + /oai-ran/cmake_targets/ran_build/build/libcoding.so \ + /oai-ran/cmake_targets/ran_build/build/libparams_libconfig.so \ + /oai-ran/cmake_targets/ran_build/build/libdfts.so \ + /oai-ran/cmake_targets/ran_build/build/liboai_iqplayer.so \ + /oai-ran/cmake_targets/ran_build/build/libtelnetsrv.so \ + /oai-ran/cmake_targets/ran_build/build/libtelnetsrv_enb.so \ + /usr/local/lib/ + +COPY --from=enb-base \ + /lib64/libconfig.so.9 \ + /lib64/libblas.so.3 \ + /lib64/liblapack.so.3 \ + /lib64/liblapacke.so.3 \ + /lib64/libboost_chrono.so.1.66.0 \ + /lib64/libboost_date_time.so.1.66.0 \ + /lib64/libboost_filesystem.so.1.66.0 \ + /lib64/libboost_program_options.so.1.66.0 \ + /lib64/libboost_serialization.so.1.66.0 \ + /lib64/libboost_thread.so.1.66.0 \ + /lib64/libboost_system.so.1.66.0 \ + /lib64/libboost_unit_test_framework.so.1.66.0 \ + /lib64/libboost_atomic.so.1.66.0 \ + /lib64/libboost_timer.so.1.66.0 \ + /lib64/libboost_regex.so.1.66.0 \ + /lib64/libicudata.so.60 \ + /lib64/libicui18n.so.60 \ + /lib64/libicuuc.so.60 \ + /lib64/ + + +# Now we are copying from builder-image the UHD files. +COPY --from=enb-base /usr/local/bin/uhd_find_devices /usr/local/bin +COPY --from=enb-base /usr/local/lib64/libuhd.so.4.4.0 /usr/local/lib64 +COPY --from=enb-base /usr/local/lib64/uhd/utils/uhd_images_downloader.py /opt/oai-enb/bin + +WORKDIR /usr/local/share/uhd/rfnoc +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" && \ + 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 + +# Copy the relevant configuration files for eNB +WORKDIR /opt/oai-enb/etc +COPY --from=enb-build /oai-ran/docker/etc . + +WORKDIR /opt/oai-enb + +# 2152 --> S1U, GTP/UDP +# 36412 --> S1C, SCTP/UDP +# 36422 --> X2C, SCTP/UDP +EXPOSE 2152/udp 36412/udp 36422/udp + +ENTRYPOINT ["/opt/oai-enb/bin/entrypoint.sh"] +CMD ["/opt/oai-enb/bin/lte-softmodem", "-O", "/opt/oai-enb/etc/enb.conf"] diff --git a/docker/Dockerfile.gNB.aw2s.rocky b/docker/Dockerfile.gNB.aw2s.rocky new file mode 100644 index 0000000000..8d368d1000 --- /dev/null +++ b/docker/Dockerfile.gNB.aw2s.rocky @@ -0,0 +1,105 @@ +#/* +# * 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 +# */ +#--------------------------------------------------------------------- +# +# Dockerfile for the Open-Air-Interface BUILD service +# Valid for Rocky 8.7 +# +#--------------------------------------------------------------------- + +ARG BASE_IMAGE=docker.io/rockylinux:8.7 +FROM ran-base:latest AS gnb-base + +FROM ran-build:latest AS gnb-build + +COPY ./libori.so /usr/local/lib + +# build AW2S fronthaul lib +WORKDIR /oai-ran +RUN /bin/sh oaienv && \ + cd cmake_targets/ran_build/build && \ + ninja aw2sori_transpro + +#start from scratch for target executable +FROM $BASE_IMAGE as oai-gnb-aw2s +ENV TZ=Europe/Paris + +RUN dnf update -y && \ + dnf install -y \ + procps-ng \ + libXpm \ + libX11 \ + atlas \ + lksctp-tools \ + tzdata \ + net-tools \ + iputils && \ + echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf && \ + echo "/usr/local/lib64" >> /etc/ld.so.conf.d/local-lib.conf + +WORKDIR /opt/oai-gnb-aw2s/bin +COPY --from=gnb-build \ + /oai-ran/cmake_targets/ran_build/build/nr-softmodem \ + ./ +COPY ./docker/scripts/gnb-aw2s_entrypoint.sh ./entrypoint.sh + +COPY --from=gnb-build \ + /oai-ran/cmake_targets/ran_build/build/liboai_eth_transpro.so \ + /oai-ran/cmake_targets/ran_build/build/librfsimulator.so \ + /oai-ran/cmake_targets/ran_build/build/libaw2sori_transpro.so \ + /oai-ran/cmake_targets/ran_build/build/libcoding.so \ + /oai-ran/cmake_targets/ran_build/build/libparams_libconfig.so \ + /oai-ran/cmake_targets/ran_build/build/libdfts.so \ + /oai-ran/cmake_targets/ran_build/build/libldpc.so \ + /oai-ran/cmake_targets/ran_build/build/libldpc_optim.so \ + /oai-ran/cmake_targets/ran_build/build/libldpc_optim8seg.so \ + /oai-ran/cmake_targets/ran_build/build/libldpc_orig.so \ + /oai-ran/cmake_targets/ran_build/build/libtelnetsrv.so \ + /usr/local/lib/libori.so \ + /usr/local/lib/ + +COPY --from=gnb-base \ + /lib64/libconfig.so.9 \ + /lib64/libforms.so.2 \ + /lib64/libblas.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" && ldd /usr/local/lib/liboai_eth_transpro.so && \ + echo "ldd on librfsimulator" && ldd /usr/local/lib/librfsimulator.so && \ + echo "ldd on libaw2sori_transpro" && ldd /usr/local/lib/libaw2sori_transpro.so && \ + echo "ldd on libcoding" && ldd /usr/local/lib/libcoding.so && \ + echo "ldd on libparams_libconfig" && ldd /usr/local/lib/libparams_libconfig.so && \ + echo "ldd on libdfts" && ldd /usr/local/lib/libdfts.so && \ + echo "ldd on libldpc" && ldd /usr/local/lib/libldpc.so && \ + echo "ldd on libldpc_optim" && ldd /usr/local/lib/libldpc_optim.so && \ + echo "ldd on libldpc_optim8seg" && ldd /usr/local/lib/libldpc_optim8seg.so && \ + echo "ldd on libldpc_orig" && ldd /usr/local/lib/libldpc_orig.so && \ + echo "ldd on libtelnetsrv" && ldd /usr/local/lib/libtelnetsrv.so + +WORKDIR /opt/oai-gnb-aw2s +ENTRYPOINT ["/opt/oai-gnb-aw2s/bin/entrypoint.sh"] +CMD ["/opt/oai-gnb-aw2s/bin/nr-softmodem", "-O", "/opt/oai-gnb-aw2s/etc/gnb.conf"] diff --git a/docker/Dockerfile.gNB.rocky b/docker/Dockerfile.gNB.rocky new file mode 100644 index 0000000000..bef0094023 --- /dev/null +++ b/docker/Dockerfile.gNB.rocky @@ -0,0 +1,138 @@ +#/* +# * 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 +# */ +#--------------------------------------------------------------------- +# +# Dockerfile for the Open-Air-Interface BUILD service +# Valid for Rocky 8.7 +# +#--------------------------------------------------------------------- + +ARG BASE_IMAGE=docker.io/rockylinux:8.7 +FROM ran-base:latest AS gnb-base + +FROM ran-build:latest AS gnb-build + +RUN python3 ./docker/scripts/generateTemplate.py ./docker/scripts/gnb_parameters.yaml && \ + cp /oai-ran/docker/scripts/gnb_entrypoint.sh /oai-ran/docker/scripts/entrypoint.sh + +#start from scratch for target executable +FROM $BASE_IMAGE as oai-gnb +ENV TZ=Europe/Paris + +RUN dnf update -y && \ + dnf install -y \ + procps-ng \ + libXpm \ + libX11 \ + atlas \ + lksctp-tools \ + tzdata \ + gdb \ + python3 \ + python3-pip \ + net-tools \ + iputils && \ + pip3 install six && \ + pip3 install requests && \ + echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf && \ + echo "/usr/local/lib64" >> /etc/ld.so.conf.d/local-lib.conf + +WORKDIR /opt/oai-gnb/bin +COPY --from=gnb-build \ + /oai-ran/cmake_targets/ran_build/build/nr-softmodem \ + /oai-ran/docker/scripts/entrypoint.sh \ + ./ + +COPY --from=gnb-build \ + /oai-ran/cmake_targets/ran_build/build/liboai_eth_transpro.so \ + /oai-ran/cmake_targets/ran_build/build/librfsimulator.so \ + /oai-ran/cmake_targets/ran_build/build/liboai_usrpdevif.so \ + /oai-ran/cmake_targets/ran_build/build/libcoding.so \ + /oai-ran/cmake_targets/ran_build/build/libparams_libconfig.so \ + /oai-ran/cmake_targets/ran_build/build/libdfts.so \ + /oai-ran/cmake_targets/ran_build/build/libldpc.so \ + /oai-ran/cmake_targets/ran_build/build/libldpc_optim.so \ + /oai-ran/cmake_targets/ran_build/build/libldpc_optim8seg.so \ + /oai-ran/cmake_targets/ran_build/build/libldpc_orig.so \ + /oai-ran/cmake_targets/ran_build/build/libtelnetsrv.so \ + /oai-ran/cmake_targets/ran_build/build/libtelnetsrv_ci.so \ + /usr/local/lib/ + +COPY --from=gnb-base \ + /lib64/libconfig.so.9 \ + /lib64/libforms.so.2 \ + /lib64/libblas.so.3 \ + /lib64/liblapack.so.3 \ + /lib64/liblapacke.so.3 \ + /lib64/libboost_chrono.so.1.66.0 \ + /lib64/libboost_date_time.so.1.66.0 \ + /lib64/libboost_filesystem.so.1.66.0 \ + /lib64/libboost_program_options.so.1.66.0 \ + /lib64/libboost_serialization.so.1.66.0 \ + /lib64/libboost_thread.so.1.66.0 \ + /lib64/libboost_system.so.1.66.0 \ + /lib64/libboost_unit_test_framework.so.1.66.0 \ + /lib64/libboost_atomic.so.1.66.0 \ + /lib64/libboost_timer.so.1.66.0 \ + /lib64/libboost_regex.so.1.66.0 \ + /lib64/libicudata.so.60 \ + /lib64/libicui18n.so.60 \ + /lib64/libicuuc.so.60 \ + /lib64/ + +# Now we are copying from builder-image the UHD files. +COPY --from=gnb-base /usr/local/bin/uhd_find_devices /usr/local/bin +COPY --from=gnb-base /usr/local/lib64/libuhd.so.4.4.0 /usr/local/lib64 +COPY --from=gnb-base /usr/local/lib64/uhd/utils/uhd_images_downloader.py /opt/oai-gnb/bin + +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 && \ + echo "ldd on nr-softmodem" && ldd /opt/oai-gnb/bin/nr-softmodem && \ + echo "ldd on liboai_eth_transpro" && ldd /usr/local/lib/liboai_eth_transpro.so && \ + echo "ldd on librfsimulator" && ldd /usr/local/lib/librfsimulator.so && \ + echo "ldd on liboai_usrpdevif" && ldd /usr/local/lib/liboai_usrpdevif.so && \ + echo "ldd on libcoding" && ldd /usr/local/lib/libcoding.so && \ + echo "ldd on libparams_libconfig" && ldd /usr/local/lib/libparams_libconfig.so && \ + echo "ldd on libdfts" && ldd /usr/local/lib/libdfts.so && \ + echo "ldd on libldpc" && ldd /usr/local/lib/libldpc.so && \ + echo "ldd on libldpc_optim" && ldd /usr/local/lib/libldpc_optim.so && \ + echo "ldd on libldpc_optim8seg" && ldd /usr/local/lib/libldpc_optim8seg.so && \ + echo "ldd on libldpc_orig" && ldd /usr/local/lib/libldpc_orig.so && \ + echo "ldd on libtelnetsrv" && ldd /usr/local/lib/libtelnetsrv.so && \ + echo "ldd on libtelnetsrv_ci" && ldd /usr/local/lib/libtelnetsrv_ci.so + +# Copy the relevant configuration files for gNB +WORKDIR /opt/oai-gnb/etc +COPY --from=gnb-build /oai-ran/docker/etc . + +WORKDIR /opt/oai-gnb +#EXPOSE 2152/udp # S1U, GTP/UDP +#EXPOSE 22100/tcp # ? +#EXPOSE 36412/udp # S1C, SCTP/UDP +#EXPOSE 36422/udp # X2C, SCTP/UDP +#EXPOSE 50000/udp # IF5 / ORI (control) +#EXPOSE 50001/udp # IF5 / ECPRI (data) + +ENTRYPOINT ["/opt/oai-gnb/bin/entrypoint.sh"] +CMD ["/opt/oai-gnb/bin/nr-softmodem", "-O", "/opt/oai-gnb/etc/gnb.conf"] diff --git a/docker/Dockerfile.lteUE.rocky b/docker/Dockerfile.lteUE.rocky new file mode 100644 index 0000000000..168d692e88 --- /dev/null +++ b/docker/Dockerfile.lteUE.rocky @@ -0,0 +1,123 @@ +#/* +# * 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 +# */ +#--------------------------------------------------------------------- +# +# Dockerfile for the Open-Air-Interface BUILD service +# Valid for Rocky 8.7 +# +#--------------------------------------------------------------------- + +ARG BASE_IMAGE=docker.io/rockylinux:8.7 +FROM ran-base:latest AS lte-ue-base + +FROM ran-build:latest AS lte-ue-build + +RUN python3 ./docker/scripts/generateTemplate.py ./docker/scripts/lte_ue_parameters.yaml && \ + python3 ./docker/scripts/generateTemplate.py ./docker/scripts/lte_ue_sim_parameters.yaml && \ + cp /oai-ran/docker/scripts/lte_ue_entrypoint.sh /oai-ran/docker/scripts/entrypoint.sh + +#start from scratch for target executable +FROM $BASE_IMAGE as oai-lte-ue +ENV TZ=Europe/Paris + +RUN dnf update -y && \ + dnf install -y \ + lksctp-tools \ + procps-ng \ + tzdata \ + atlas \ + gdb \ + python3 \ + python3-pip \ + iproute \ + net-tools \ + iputils && \ + pip3 install six && \ + pip3 install requests && \ + echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf && \ + echo "/usr/local/lib64" >> /etc/ld.so.conf.d/local-lib.conf + +WORKDIR /opt/oai-lte-ue/bin +COPY --from=lte-ue-build \ + /oai-ran/cmake_targets/ran_build/build/lte-uesoftmodem \ + /oai-ran/docker/scripts/entrypoint.sh \ + /oai-ran/cmake_targets/nas_sim_tools/build/conf2uedata \ + /oai-ran/cmake_targets/nas_sim_tools/build/nvram \ + /oai-ran/cmake_targets/nas_sim_tools/build/usim \ + ./ + +COPY --from=lte-ue-build \ + /oai-ran/cmake_targets/ran_build/build/liboai_eth_transpro.so \ + /oai-ran/cmake_targets/ran_build/build/librfsimulator.so \ + /oai-ran/cmake_targets/ran_build/build/liboai_usrpdevif.so \ + /oai-ran/cmake_targets/ran_build/build/libcoding.so \ + /oai-ran/cmake_targets/ran_build/build/libparams_libconfig.so \ + /oai-ran/cmake_targets/ran_build/build/libdfts.so \ + /oai-ran/cmake_targets/ran_build/build/libtelnetsrv.so \ + /usr/local/lib/ + +COPY --from=lte-ue-base \ + /lib64/libconfig.so.9 \ + /lib64/libblas.so.3 \ + /lib64/liblapack.so.3 \ + /lib64/liblapacke.so.3 \ + /lib64/libboost_chrono.so.1.66.0 \ + /lib64/libboost_date_time.so.1.66.0 \ + /lib64/libboost_filesystem.so.1.66.0 \ + /lib64/libboost_program_options.so.1.66.0 \ + /lib64/libboost_serialization.so.1.66.0 \ + /lib64/libboost_thread.so.1.66.0 \ + /lib64/libboost_system.so.1.66.0 \ + /lib64/libboost_unit_test_framework.so.1.66.0 \ + /lib64/libboost_atomic.so.1.66.0 \ + /lib64/libboost_timer.so.1.66.0 \ + /lib64/libboost_regex.so.1.66.0 \ + /lib64/libicudata.so.60 \ + /lib64/libicui18n.so.60 \ + /lib64/libicuuc.so.60 \ + /lib64/ + +# Now we are copying from builder-image the UHD files. +COPY --from=lte-ue-base /usr/local/bin/uhd_find_devices /usr/local/bin +COPY --from=lte-ue-base /usr/local/lib64/libuhd.so.4.4.0 /usr/local/lib64 +COPY --from=lte-ue-base /usr/local/lib64/uhd/utils/uhd_images_downloader.py /opt/oai-lte-ue/bin + +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 && \ + echo "ldd on lte-uesoftmodem" && ldd /opt/oai-lte-ue/bin/lte-uesoftmodem && \ + echo "ldd on liboai_eth_transpro" && ldd /usr/local/lib/liboai_eth_transpro.so && \ + echo "ldd on librfsimulator" && ldd /usr/local/lib/librfsimulator.so && \ + echo "ldd on liboai_usrpdevif" && ldd /usr/local/lib/liboai_usrpdevif.so && \ + echo "ldd on libcoding" && ldd /usr/local/lib/libcoding.so && \ + echo "ldd on libparams_libconfig" && ldd /usr/local/lib/libparams_libconfig.so && \ + echo "ldd on libdfts" && ldd /usr/local/lib/libdfts.so && \ + echo "ldd on libtelnetsrv" && ldd /usr/local/lib/libtelnetsrv.so + +# Copy the relevant configuration files for UE +WORKDIR /opt/oai-lte-ue/etc +COPY --from=lte-ue-build /oai-ran/docker/etc . + +WORKDIR /opt/oai-lte-ue +CMD ["/opt/oai-lte-ue/bin/lte-uesoftmodem"] +ENTRYPOINT ["/opt/oai-lte-ue/bin/entrypoint.sh"] diff --git a/docker/Dockerfile.nr-cuup.rocky b/docker/Dockerfile.nr-cuup.rocky new file mode 100644 index 0000000000..d0e670a790 --- /dev/null +++ b/docker/Dockerfile.nr-cuup.rocky @@ -0,0 +1,80 @@ +#/* +# * 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 +# */ +#--------------------------------------------------------------------- +# +# Dockerfile for the Open-Air-Interface BUILD service +# Valid for Rocky 8.7 +# +#--------------------------------------------------------------------- + +ARG BASE_IMAGE=docker.io/rockylinux:8.7 +FROM ran-base:latest AS gnb-base + +FROM ran-build:latest AS gnb-build + +RUN cp /oai-ran/docker/scripts/gnb_entrypoint.sh /oai-ran/docker/scripts/entrypoint.sh + +#start from scratch for target executable +FROM $BASE_IMAGE as oai-nr-cuup +ENV TZ=Europe/Paris + +RUN dnf update -y && \ + dnf install -y \ + procps-ng \ + lksctp-tools \ + tzdata \ + atlas \ + net-tools \ + iputils && \ + echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf && \ + echo "/usr/local/lib64" >> /etc/ld.so.conf.d/local-lib.conf + +WORKDIR /opt/oai-gnb/bin +COPY --from=gnb-build \ + /oai-ran/cmake_targets/ran_build/build/nr-cuup \ + /oai-ran/docker/scripts/entrypoint.sh \ + ./ + +COPY --from=gnb-build \ + /oai-ran/cmake_targets/ran_build/build/librfsimulator.so \ + /oai-ran/cmake_targets/ran_build/build/libparams_libconfig.so \ + /oai-ran/cmake_targets/ran_build/build/libtelnetsrv.so \ + /usr/local/lib/ + +COPY --from=gnb-base \ + /lib64/libconfig.so.9 \ + /lib64/libblas.so.3 \ + /lib64/liblapack.so.3 \ + /lib64/liblapacke.so.3 \ + /lib64/ + +RUN ldconfig && \ + echo "ldd on nr-cuup" && ldd /opt/oai-gnb/bin/nr-cuup && \ + echo "ldd on librfsimulator" && ldd /usr/local/lib/librfsimulator.so && \ + echo "ldd on libparams_libconfig" && ldd /usr/local/lib/libparams_libconfig.so && \ + echo "ldd on libtelnetsrv" && ldd /usr/local/lib/libtelnetsrv.so + +WORKDIR /opt/oai-gnb/etc + +WORKDIR /opt/oai-gnb + +ENTRYPOINT ["/opt/oai-gnb/bin/entrypoint.sh"] +CMD ["/opt/oai-gnb/bin/nr-cuup", "-O", "/opt/oai-gnb/etc/gnb.conf"] diff --git a/docker/Dockerfile.nrUE.rocky b/docker/Dockerfile.nrUE.rocky new file mode 100644 index 0000000000..072d7e5445 --- /dev/null +++ b/docker/Dockerfile.nrUE.rocky @@ -0,0 +1,138 @@ +#/* +# * 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 +# */ +#--------------------------------------------------------------------- +# +# Dockerfile for the Open-Air-Interface BUILD service +# Valid for Rocky 8.7 +# +#--------------------------------------------------------------------- + +ARG BASE_IMAGE=docker.io/rockylinux:8.7 +FROM ran-base:latest AS nr-ue-base + +FROM ran-build:latest AS nr-ue-build + +RUN python3 ./docker/scripts/generateTemplate.py ./docker/scripts/nr_ue_parameters.yaml && \ + cp /oai-ran/docker/scripts/nr_ue_entrypoint.sh /oai-ran/docker/scripts/entrypoint.sh + +#start from scratch for target executable +FROM $BASE_IMAGE as oai-nr-ue +ENV TZ=Europe/Paris + +RUN dnf update -y && \ + dnf install -y \ + lksctp-tools \ + procps-ng \ + tzdata \ + net-tools \ + iputils \ + iproute \ + atlas \ + gdb \ + python3 \ + python3-pip \ + libXpm \ + libX11 && \ + pip3 install six && \ + pip3 install requests && \ + echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf && \ + echo "/usr/local/lib64" >> /etc/ld.so.conf.d/local-lib.conf + +WORKDIR /opt/oai-nr-ue/bin +COPY --from=nr-ue-build \ + /oai-ran/cmake_targets/ran_build/build/nr-uesoftmodem \ + /oai-ran/docker/scripts/entrypoint.sh \ + ./ + +WORKDIR /opt/oai-nr-ue/etc +COPY --from=nr-ue-build \ + /oai-ran/ci-scripts/conf_files/nr-ue-sim.conf \ + /oai-ran/docker/etc/nr-ue.nfapi.conf \ + ./ + +COPY --from=nr-ue-build \ + /oai-ran/cmake_targets/ran_build/build/liboai_eth_transpro.so \ + /oai-ran/cmake_targets/ran_build/build/librfsimulator.so \ + /oai-ran/cmake_targets/ran_build/build/liboai_usrpdevif.so \ + /oai-ran/cmake_targets/ran_build/build/libcoding.so \ + /oai-ran/cmake_targets/ran_build/build/libparams_libconfig.so \ + /oai-ran/cmake_targets/ran_build/build/libdfts.so \ + /oai-ran/cmake_targets/ran_build/build/libldpc.so \ + /oai-ran/cmake_targets/ran_build/build/libldpc_optim.so \ + /oai-ran/cmake_targets/ran_build/build/libldpc_optim8seg.so \ + /oai-ran/cmake_targets/ran_build/build/libldpc_orig.so \ + /oai-ran/cmake_targets/ran_build/build/libtelnetsrv.so \ + /oai-ran/cmake_targets/ran_build/build/libtelnetsrv_5Gue.so \ + /usr/local/lib/ + +COPY --from=nr-ue-base \ + /lib64/libconfig.so.9 \ + /lib64/libblas.so.3 \ + /lib64/liblapack.so.3 \ + /lib64/liblapacke.so.3 \ + /lib64/libforms.so.2 \ + /lib64/libboost_chrono.so.1.66.0 \ + /lib64/libboost_date_time.so.1.66.0 \ + /lib64/libboost_filesystem.so.1.66.0 \ + /lib64/libboost_program_options.so.1.66.0 \ + /lib64/libboost_serialization.so.1.66.0 \ + /lib64/libboost_thread.so.1.66.0 \ + /lib64/libboost_system.so.1.66.0 \ + /lib64/libboost_unit_test_framework.so.1.66.0 \ + /lib64/libboost_atomic.so.1.66.0 \ + /lib64/libboost_timer.so.1.66.0 \ + /lib64/libboost_regex.so.1.66.0 \ + /lib64/libicudata.so.60 \ + /lib64/libicui18n.so.60 \ + /lib64/libicuuc.so.60 \ + /lib64/ + +# Now we are copying from builder-image the UHD files. +COPY --from=nr-ue-base /usr/local/bin/uhd_find_devices /usr/local/bin +COPY --from=nr-ue-base /usr/local/lib64/libuhd.so.4.4.0 /usr/local/lib64 +COPY --from=nr-ue-base /usr/local/lib64/uhd/utils/uhd_images_downloader.py /opt/oai-nr-ue/bin + +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 && \ + echo "ldd on nr-uesoftmodem" && ldd /opt/oai-nr-ue/bin/nr-uesoftmodem && \ + echo "ldd on liboai_eth_transpro" && ldd /usr/local/lib/liboai_eth_transpro.so && \ + echo "ldd on librfsimulator" && ldd /usr/local/lib/librfsimulator.so && \ + echo "ldd on liboai_usrpdevif" && ldd /usr/local/lib/liboai_usrpdevif.so && \ + echo "ldd on libcoding" && ldd /usr/local/lib/libcoding.so && \ + echo "ldd on libparams_libconfig" && ldd /usr/local/lib/libparams_libconfig.so && \ + echo "ldd on libdfts" && ldd /usr/local/lib/libdfts.so && \ + echo "ldd on libldpc" && ldd /usr/local/lib/libldpc.so && \ + echo "ldd on libldpc_optim" && ldd /usr/local/lib/libldpc_optim.so && \ + echo "ldd on libldpc_optim8seg" && ldd /usr/local/lib/libldpc_optim8seg.so && \ + echo "ldd on libldpc_orig" && ldd /usr/local/lib/libldpc_orig.so && \ + echo "ldd on libtelnetsrv" && ldd /usr/local/lib/libtelnetsrv.so && \ + echo "ldd on libtelnetsrv_5Gue" && ldd /usr/local/lib/libtelnetsrv_5Gue.so + +# Copy the relevant configuration files for eNB +WORKDIR /opt/oai-nr-ue/etc +COPY --from=nr-ue-build /oai-ran/ci-scripts/conf_files/ue.* . + +WORKDIR /opt/oai-nr-ue +CMD ["/opt/oai-nr-ue/bin/nr-uesoftmodem", "-O", "/opt/oai-nr-ue/etc/nr-ue.conf"] +ENTRYPOINT ["/opt/oai-nr-ue/bin/entrypoint.sh"] diff --git a/docker/Dockerfile.phySim.rhel8.2 b/docker/Dockerfile.phySim.rhel8.2 index df1e5af51c..691c7e7765 100644 --- a/docker/Dockerfile.phySim.rhel8.2 +++ b/docker/Dockerfile.phySim.rhel8.2 @@ -38,7 +38,7 @@ RUN yum install -y libasan libubsan RUN /bin/sh oaienv && \ cd cmake_targets && \ mkdir -p log && \ - ./build_oai --phy_simulators --ninja --verbose-ci --sanitize --noavx512 -c --cmake-opt -DCMAKE_C_FLAGS=-Werror --cmake-opt -DCMAKE_CXX_FLAGS=-Werror + ./build_oai --phy_simulators --ninja --verbose-ci --sanitize --noavx512 -c --cmake-opt -DCMAKE_C_FLAGS=-Werror --cmake-opt -DCMAKE_CXX_FLAGS=-Werror --cmake-opt -DCMAKE_C_FLAGS=-Wno-unused-function --cmake-opt -DCMAKE_CXX_FLAGS=-Wno-unused-function #start from scratch for target executable FROM registry.access.redhat.com/ubi8/ubi:latest as oai-physim diff --git a/docker/README.md b/docker/README.md index 069799e368..18f955b760 100644 --- a/docker/README.md +++ b/docker/README.md @@ -77,6 +77,7 @@ The currently-supported OS are: - `rhel8.2` for Red Hat Entreprise Linux (including images for an OpenShift cluster) - `ubuntu20` for Ubuntu 20.04 LTS +- `rocky` for Rocky-Linux 8.7 For more details regarding the build on an Openshift Cluster, see [OpenShift README](../openshift/README.md). @@ -111,6 +112,8 @@ ran-base latest 5c9c02a5b4a8 1 minute ago ... ``` +Note that the steps are identical for `rocky-linux`. + ## 3.3. Building any target image ## For example, the eNB: @@ -136,6 +139,8 @@ Do not forget to remove the temporary image: docker image prune --force ``` +Note that the steps are identical for `rocky-linux`. + # 4. Building using `podman` under Red Hat Entreprise Linux 8.2 # Analogous to the above steps: diff --git a/executables/nr-cuup.c b/executables/nr-cuup.c index 90490e327f..832f785551 100644 --- a/executables/nr-cuup.c +++ b/executables/nr-cuup.c @@ -111,7 +111,7 @@ f1ap_cudu_inst_t *getCxt(F1_t isCU, instance_t instanceP) return NULL; } -void fill_DRB_configList(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP) +void fill_DRB_configList(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP, uint8_t xid) { abort(); } diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c index 5a7bd8a020..494e8a7de0 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c @@ -80,16 +80,17 @@ char nr_dci_format_string[8][30] = { static void nr_pdcch_demapping_deinterleaving(uint32_t *llr, - uint32_t *e_rx, - uint8_t coreset_time_dur, - uint8_t start_symbol, - uint32_t coreset_nbr_rb, - uint8_t reg_bundle_size_L, - uint8_t coreset_interleaver_size_R, - uint8_t n_shift, - uint8_t number_of_candidates, - uint16_t *CCE, - uint8_t *L) { + uint32_t *e_rx, + uint8_t coreset_time_dur, + uint8_t start_symbol, + uint32_t coreset_nbr_rb, + uint8_t reg_bundle_size_L, + uint8_t coreset_interleaver_size_R, + uint8_t n_shift, + uint8_t number_of_candidates, + uint16_t *CCE, + uint8_t *L) +{ /* * This function will do demapping and deinterleaving from llr containing demodulated symbols * Demapping will regroup in REG and bundles @@ -130,7 +131,7 @@ static void nr_pdcch_demapping_deinterleaving(uint32_t *llr, uint32_t coreset_C = 0; uint16_t index_z, index_llr; int coreset_interleaved = 0; - int N_regs = coreset_nbr_rb*coreset_time_dur; + int N_regs = coreset_nbr_rb * coreset_time_dur; if (reg_bundle_size_L != 0) { // interleaving will be done only if reg_bundle_size_L != 0 coreset_interleaved = 1; @@ -139,12 +140,11 @@ static void nr_pdcch_demapping_deinterleaving(uint32_t *llr, reg_bundle_size_L = 6; } - int B_rb = reg_bundle_size_L/coreset_time_dur; // nb of RBs occupied by each REG bundle - int num_bundles_per_cce = 6/reg_bundle_size_L; - int n_cce = N_regs/6; - int max_bundles = n_cce*num_bundles_per_cce; + int B_rb = reg_bundle_size_L / coreset_time_dur; // nb of RBs occupied by each REG bundle + int num_bundles_per_cce = 6 / reg_bundle_size_L; + int n_cce = N_regs / 6; + int max_bundles = n_cce * num_bundles_per_cce; int f_bundle_j_list[max_bundles]; - // for each bundle for (int nb = 0; nb < max_bundles; nb++) { if (coreset_interleaved == 0) @@ -163,11 +163,11 @@ static void nr_pdcch_demapping_deinterleaving(uint32_t *llr, // Get cce_list indices by bundle index in ascending order int f_bundle_j_list_ord[number_of_candidates][max_bundles]; for (int c_id = 0; c_id < number_of_candidates; c_id++ ) { - int start_bund_cand = CCE[c_id]*num_bundles_per_cce; - int max_bund_per_cand = L[c_id]*num_bundles_per_cce; + int start_bund_cand = CCE[c_id] * num_bundles_per_cce; + int max_bund_per_cand = L[c_id] * num_bundles_per_cce; int f_bundle_j_list_id = 0; for(int nb = 0; nb < max_bundles; nb++) { - for(int bund_cand = start_bund_cand; bund_cand < start_bund_cand+max_bund_per_cand; bund_cand++){ + for(int bund_cand = start_bund_cand; bund_cand < start_bund_cand + max_bund_per_cand; bund_cand++){ if (f_bundle_j_list[bund_cand] == nb) { f_bundle_j_list_ord[c_id][f_bundle_j_list_id] = nb; f_bundle_j_list_id++; diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index a7465ad99b..1f35072552 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -861,6 +861,7 @@ int main(int argc, char **argv) nr_l2_init_ue(NULL); UE_mac = get_mac_inst(0); + ue_init_config_request(UE_mac, mu); UE->if_inst = nr_ue_if_module_init(0); UE->if_inst->scheduled_response = nr_ue_scheduled_response; @@ -888,7 +889,8 @@ int main(int argc, char **argv) //Configure UE NR_BCCH_BCH_Message_t *mib = get_new_MIB_NR(scc); - nr_rrc_mac_config_req_ue(0, 0, 0, mib->message.choice.mib, NULL, NULL, secondaryCellGroup); + nr_rrc_mac_config_req_mib(0, 0, mib->message.choice.mib, false); + nr_rrc_mac_config_req_scg(0, 0, secondaryCellGroup); nr_dcireq_t dcireq; nr_scheduled_response_t scheduled_response; @@ -1010,7 +1012,10 @@ int main(int argc, char **argv) UE_info->UE_sched_ctrl.harq_processes[harq_pid].ndi = !(trial&1); UE_info->UE_sched_ctrl.harq_processes[harq_pid].round = round; + // nr_schedule_ue_spec() requires the mutex to be locked + NR_SCHED_LOCK(&gNB_mac->sched_lock); nr_schedule_ue_spec(0, frame, slot, &Sched_INFO->DL_req, &Sched_INFO->TX_req); + NR_SCHED_UNLOCK(&gNB_mac->sched_lock); Sched_INFO->module_id = 0; Sched_INFO->CC_id = 0; Sched_INFO->frame = frame; diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 6aaa79bb76..4ee528a6fc 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -744,11 +744,8 @@ int main(int argc, char **argv) UE_mac->if_module = nr_ue_if_module_init(0); -// nr_rrc_mac_config_req_ue(0,0,0,rrc.carrier.mib.message.choice.mib, NULL, NULL, secondaryCellGroup); - nr_ue_phy_config_request(&UE_mac->phy_config); - unsigned char harq_pid = 0; NR_gNB_ULSCH_t *ulsch_gNB = &gNB->ulsch[UE_id]; diff --git a/openair2/COMMON/ngap_messages_types.h b/openair2/COMMON/ngap_messages_types.h index 87426eff98..2f9f56e23a 100644 --- a/openair2/COMMON/ngap_messages_types.h +++ b/openair2/COMMON/ngap_messages_types.h @@ -263,17 +263,6 @@ typedef enum pdu_session_type_e { PDUSessionType_unstructured = 4 }pdu_session_type_t; -typedef struct ngap_transport_layer_addr_s { - /* Length of the transport layer address buffer in bits. NGAP layer received a - * bit string<1..160> containing one of the following addresses: ipv4, - * ipv6, or ipv4 and ipv6. The layer doesn't interpret the buffer but - * silently forward it to NG-U. - */ - uint8_t pdu_session_type; - uint8_t length; - uint8_t buffer[20]; // in network byte order -} ngap_transport_layer_addr_t; - typedef struct pdusession_s { /* Unique pdusession_id for the UE. */ int pdusession_id; @@ -283,11 +272,16 @@ typedef struct pdusession_s { /* Quality of service for this pdusession */ pdusession_level_qos_parameter_t qos[QOSFLOW_MAX_VALUE]; /* The transport layer address for the IP packets */ - ngap_transport_layer_addr_t upf_addr; + pdu_session_type_t pdu_session_type; + transport_layer_addr_t upf_addr; /* S-GW Tunnel endpoint identifier */ uint32_t gtp_teid; /* Stores the DRB ID of the DRBs used by this PDU Session */ uint8_t used_drbs[NGAP_MAX_DRBS_PER_UE]; + uint32_t gNB_teid_N3; + transport_layer_addr_t gNB_addr_N3; + uint32_t UPF_teid_N3; + transport_layer_addr_t UPF_addr_N3; } pdusession_t; typedef enum pdusession_qosflow_mapping_ind_e{ @@ -306,7 +300,8 @@ typedef struct pdusession_setup_s { uint8_t pdusession_id; /* The transport layer address for the IP packets */ - ngap_transport_layer_addr_t gNB_addr; + uint8_t pdu_session_type; + transport_layer_addr_t gNB_addr; /* UPF Tunnel endpoint identifier */ uint32_t gtp_teid; @@ -323,7 +318,8 @@ typedef struct pdusession_tobeswitched_s { uint8_t pdusession_id; /* The transport layer address for the IP packets */ - ngap_transport_layer_addr_t upf_addr; + uint8_t pdu_session_type; + transport_layer_addr_t upf_addr; /* S-GW Tunnel endpoint identifier */ uint32_t gtp_teid; diff --git a/openair2/F1AP/f1ap_cu_interface_management.c b/openair2/F1AP/f1ap_cu_interface_management.c index 8636d1fd08..8638355b88 100644 --- a/openair2/F1AP/f1ap_cu_interface_management.c +++ b/openair2/F1AP/f1ap_cu_interface_management.c @@ -105,12 +105,13 @@ int CU_handle_F1_SETUP_REQUEST(instance_t instance, asn_INTEGER2ulong(&ie->value.choice.GNB_DU_ID, &req->gNB_DU_id); LOG_D(F1AP, "req->gNB_DU_id %lu \n", req->gNB_DU_id); /* gNB_DU_name */ - F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_F1SetupRequestIEs_t, ie, container, - F1AP_ProtocolIE_ID_id_gNB_DU_Name, true); - req->gNB_DU_name = calloc(ie->value.choice.GNB_DU_Name.size + 1, sizeof(char)); - memcpy(req->gNB_DU_name, ie->value.choice.GNB_DU_Name.buf, - ie->value.choice.GNB_DU_Name.size); - LOG_D(F1AP, "req->gNB_DU_name %s \n", req->gNB_DU_name); + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_F1SetupRequestIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_DU_Name, false); + req->gNB_DU_name = NULL; + if (ie != NULL) { + req->gNB_DU_name = calloc(ie->value.choice.GNB_DU_Name.size + 1, sizeof(char)); + memcpy(req->gNB_DU_name, ie->value.choice.GNB_DU_Name.buf, ie->value.choice.GNB_DU_Name.size); + LOG_D(F1AP, "req->gNB_DU_name %s \n", req->gNB_DU_name); + } /* GNB_DU_Served_Cells_List */ F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_F1SetupRequestIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_DU_Served_Cells_List, true); diff --git a/openair2/F1AP/f1ap_du_ue_context_management.c b/openair2/F1AP/f1ap_du_ue_context_management.c index fbe8388714..4c119dd8ad 100644 --- a/openair2/F1AP/f1ap_du_ue_context_management.c +++ b/openair2/F1AP/f1ap_du_ue_context_management.c @@ -35,6 +35,7 @@ #include "f1ap_decoder.h" #include "f1ap_itti_messaging.h" #include "f1ap_du_ue_context_management.h" +#include "openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h" #include "rrc_extern.h" #include "openair2/RRC/NR/rrc_gNB_UE_context.h" @@ -65,13 +66,13 @@ bool lteDURecvCb(protocol_ctxt_t *ctxt_pP, int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t instance, uint32_t assoc_id, uint32_t stream, - F1AP_F1AP_PDU_t *pdu) { - MessageDef *msg_p; // message to RRC + F1AP_F1AP_PDU_t *pdu) +{ F1AP_UEContextSetupRequest_t *container; int i; DevAssert(pdu); - msg_p = itti_alloc_new_message(TASK_DU_F1, 0, F1AP_UE_CONTEXT_SETUP_REQ); - f1ap_ue_context_setup_t *f1ap_ue_context_setup_req = &F1AP_UE_CONTEXT_SETUP_REQ(msg_p); + f1ap_ue_context_setup_t ue_context_setup = {0}; + f1ap_ue_context_setup_t *f1ap_ue_context_setup_req = &ue_context_setup; container = &pdu->choice.initiatingMessage->value.choice.UEContextSetupRequest; /* GNB_CU_UE_F1AP_ID */ F1AP_UEContextSetupRequestIEs_t *ieCU; @@ -224,8 +225,7 @@ int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t instance, LOG_W(F1AP, "can't find RRCContainer in UEContextSetupRequestIEs by id %ld \n", F1AP_ProtocolIE_ID_id_RRCContainer); } - itti_send_msg_to_task(TASK_RRC_GNB, instance, msg_p); - + ue_context_setup_request(f1ap_ue_context_setup_req); return 0; } diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index df0fea421d..aa58bac6ca 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -1554,8 +1554,9 @@ const int64_t *get_prach_config_info(frequency_range_t freq_range, uint8_t index void find_aggregation_candidates(uint8_t *aggregation_level, uint8_t *nr_of_candidates, const NR_SearchSpace_t *ss, - int L) { - AssertFatal(L>=1 && L<=16,"L %d not ok\n",L); + int L) +{ + AssertFatal(L>=1 && L<=16,"L %d not ok\n", L); *nr_of_candidates = 0; switch(L) { case 1: diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index c82e363074..a3bb33868e 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -693,145 +693,133 @@ void configure_current_BWP(NR_UE_MAC_INST_t *mac, } +void ue_init_config_request(NR_UE_MAC_INST_t *mac, int scs) +{ + int slots_per_frame = nr_slots_per_frame[scs]; + LOG_I(NR_MAC, "Initializing dl and ul config_request. num_slots = %d\n", slots_per_frame); + mac->dl_config_request = calloc(slots_per_frame, sizeof(*mac->dl_config_request)); + mac->ul_config_request = calloc(slots_per_frame, sizeof(*mac->ul_config_request)); + for (int i = 0; i < slots_per_frame; i++) + pthread_mutex_init(&(mac->ul_config_request[i].mutex_ul_config), NULL); +} -int nr_rrc_mac_config_req_ue(module_id_t module_id, - int cc_idP, - uint8_t gNB_index, - NR_MIB_t *mibP, - NR_ServingCellConfigCommonSIB_t *sccP, - NR_CellGroupConfig_t *cell_group_config, - NR_CellGroupConfig_t *scell_group_config) +void nr_rrc_mac_config_req_mib(module_id_t module_id, + int cc_idP, + NR_MIB_t *mib, + bool sched_sib1) +{ + NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); + AssertFatal(mib, "MIB should not be NULL\n"); + // initialize dl and ul config_request upon first reception of MIB + mac->mib = mib; // update by every reception + mac->phy_config.Mod_id = module_id; + mac->phy_config.CC_id = cc_idP; + mac->get_sib1 = sched_sib1; +} + +void nr_rrc_mac_config_req_sib1(module_id_t module_id, + int cc_idP, + NR_ServingCellConfigCommonSIB_t *scc) +{ + NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); + AssertFatal(scc, "SIB1 SCC should not be NULL\n"); + mac->scc_SIB = scc; + mac->nr_band = *scc->downlinkConfigCommon.frequencyInfoDL.frequencyBandList.list.array[0]->freqBandIndicatorNR; + config_common_ue_sa(mac, module_id, cc_idP); + configure_current_BWP(mac, scc, NULL); + + // Setup the SSB to Rach Occasionsif (cell_group_config->spCellConfig) { mapping according to the config + build_ssb_to_ro_map(mac); + if (!get_softmodem_params()->emulate_l1) + mac->if_module->phy_config_request(&mac->phy_config); + mac->phy_config_request_sent = true; +} + +void nr_rrc_mac_config_req_mcg(module_id_t module_id, + int cc_idP, + NR_CellGroupConfig_t *cell_group_config) +{ + LOG_I(MAC,"Applying CellGroupConfig from gNodeB\n"); + AssertFatal(cell_group_config, "CellGroupConfig should not be NULL\n"); + NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); + mac->cg = cell_group_config; + if (cell_group_config->spCellConfig) + mac->servCellIndex = cell_group_config->spCellConfig->servCellIndex ? *cell_group_config->spCellConfig->servCellIndex : 0; + else + mac->servCellIndex = 0; + + mac->scheduling_info.periodicBSR_SF = MAC_UE_BSR_TIMER_NOT_RUNNING; + mac->scheduling_info.retxBSR_SF = MAC_UE_BSR_TIMER_NOT_RUNNING; + mac->BSR_reporting_active = NR_BSR_TRIGGER_NONE; + LOG_D(MAC, "[UE %d]: periodic BSR %d (SF), retx BSR %d (SF)\n", + module_id, + mac->scheduling_info.periodicBSR_SF, + mac->scheduling_info.retxBSR_SF); + + configure_current_BWP(mac, NULL, cell_group_config); + config_control_ue(mac); + + RA_config_t *ra = &mac->ra; + if (cell_group_config->spCellConfig && cell_group_config->spCellConfig->reconfigurationWithSync) { + LOG_A(NR_MAC, "Received the reconfigurationWithSync in %s\n", __FUNCTION__); + if (cell_group_config->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated) { + ra->rach_ConfigDedicated = cell_group_config->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink; + } + mac->scc = cell_group_config->spCellConfig->reconfigurationWithSync->spCellConfigCommon; + mac->nr_band = *mac->scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]; + if (mac->scc_SIB) { + ASN_STRUCT_FREE(asn_DEF_NR_ServingCellConfigCommonSIB, mac->scc_SIB); + mac->scc_SIB = NULL; + } + mac->state = UE_NOT_SYNC; + mac->ra.ra_state = RA_UE_IDLE; + mac->physCellId = *mac->scc->physCellId; + if (!get_softmodem_params()->emulate_l1) { + mac->synch_request.Mod_id = module_id; + mac->synch_request.CC_id = cc_idP; + mac->synch_request.synch_req.target_Nid_cell = mac->physCellId; + mac->if_module->synch_request(&mac->synch_request); + } + config_common_ue(mac, module_id, cc_idP); + mac->crnti = cell_group_config->spCellConfig->reconfigurationWithSync->newUE_Identity; + LOG_I(MAC, "Configuring CRNTI %x\n", mac->crnti); + + nr_ue_mac_default_configs(mac); + if (!get_softmodem_params()->emulate_l1) { + mac->if_module->phy_config_request(&mac->phy_config); + mac->phy_config_request_sent = true; + } + + // Setup the SSB to Rach Occasions mapping according to the config + build_ssb_to_ro_map(mac); + } +} + +void nr_rrc_mac_config_req_scg(module_id_t module_id, + int cc_idP, + NR_CellGroupConfig_t *scell_group_config) { NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); RA_config_t *ra = &mac->ra; - fapi_nr_config_request_t *cfg = &mac->phy_config.config_req; - if (mac->dl_config_request == NULL) // for SIB1 reception - mac->dl_config_request = calloc(NR_MAX_SLOTS_PER_FRAME, sizeof(*mac->dl_config_request)); + AssertFatal(scell_group_config, "scell_group_config cannot be NULL\n"); - // TODO do something FAPI-like P5 L1/L2 config interface in config_si, config_mib, etc. - - if(mibP != NULL){ - mac->mib = mibP; // update by every reception - mac->phy_config.Mod_id = module_id; - mac->phy_config.CC_id = cc_idP; + mac->cg = scell_group_config; + mac->servCellIndex = *scell_group_config->spCellConfig->servCellIndex; + if (scell_group_config->spCellConfig->reconfigurationWithSync) { + if (scell_group_config->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated) { + ra->rach_ConfigDedicated = scell_group_config->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink; + } + mac->scc = scell_group_config->spCellConfig->reconfigurationWithSync->spCellConfigCommon; + mac->nr_band = *mac->scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]; + mac->physCellId = *mac->scc->physCellId; + config_common_ue(mac,module_id,cc_idP); + mac->crnti = scell_group_config->spCellConfig->reconfigurationWithSync->newUE_Identity; + LOG_I(MAC,"Configuring CRNTI %x\n",mac->crnti); } - AssertFatal(scell_group_config == NULL || cell_group_config == NULL, - "both scell_group_config and cell_group_config cannot be non-NULL\n"); - - if (sccP != NULL) { - - mac->scc_SIB = sccP; - mac->nr_band = *sccP->downlinkConfigCommon.frequencyInfoDL.frequencyBandList.list.array[0]->freqBandIndicatorNR; - config_common_ue_sa(mac, module_id, cc_idP); - configure_current_BWP(mac, sccP, NULL); - - int num_slots_ul = nr_slots_per_frame[mac->mib->subCarrierSpacingCommon]; - if(cfg->cell_config.frame_duplex_type == TDD){ - num_slots_ul = mac->scc_SIB->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots; - if (mac->scc_SIB->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols > 0) { - num_slots_ul++; - } - } - LOG_I(NR_MAC, "Initializing ul_config_request. num_slots_ul = %d\n", num_slots_ul); - mac->ul_config_request = calloc(num_slots_ul, sizeof(*mac->ul_config_request)); - for (int i=0; iul_config_request[i].mutex_ul_config), NULL); - - int num_slots_dl = nr_slots_per_frame[mac->mib->subCarrierSpacingCommon]; - if (cfg->cell_config.frame_duplex_type == TDD) { - num_slots_dl = mac->scc_SIB->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots; - if (mac->scc_SIB->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSymbols > 0) { - num_slots_dl++; - } - } - LOG_I(NR_MAC, "Initializing dl_config_request. num_slots_dl = %d\n", num_slots_dl); - mac->dl_config_request = realloc(mac->dl_config_request, num_slots_dl*sizeof(*mac->dl_config_request)); - memset(mac->dl_config_request, 0, num_slots_dl*sizeof(fapi_nr_dl_config_request_t)); - - // Setup the SSB to Rach Occasionsif (cell_group_config->spCellConfig) { mapping according to the config - build_ssb_to_ro_map(mac);//->scc, mac->phy_config.config_req.cell_config.frame_duplex_type); - if (!get_softmodem_params()->emulate_l1) - mac->if_module->phy_config_request(&mac->phy_config); - mac->phy_config_request_sent = true; - } - if(scell_group_config != NULL ){ - mac->cg = scell_group_config; - mac->servCellIndex = *scell_group_config->spCellConfig->servCellIndex; - if (scell_group_config->spCellConfig->reconfigurationWithSync) { - if (scell_group_config->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated) { - ra->rach_ConfigDedicated = scell_group_config->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink; - } - mac->scc = scell_group_config->spCellConfig->reconfigurationWithSync->spCellConfigCommon; - mac->nr_band = *mac->scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]; - mac->physCellId = *mac->scc->physCellId; - config_common_ue(mac,module_id,cc_idP); - mac->crnti = scell_group_config->spCellConfig->reconfigurationWithSync->newUE_Identity; - LOG_I(MAC,"Configuring CRNTI %x\n",mac->crnti); - } - configure_current_BWP(mac, NULL, scell_group_config); - config_control_ue(mac); - // Setup the SSB to Rach Occasions mapping according to the config - build_ssb_to_ro_map(mac); - - } else if (cell_group_config != NULL) { - LOG_I(MAC,"Applying CellGroupConfig from gNodeB\n"); - mac->cg = cell_group_config; - if (cell_group_config->spCellConfig) - mac->servCellIndex = cell_group_config->spCellConfig->servCellIndex ? *cell_group_config->spCellConfig->servCellIndex : 0; - else - mac->servCellIndex = 0; - - mac->scheduling_info.periodicBSR_SF = MAC_UE_BSR_TIMER_NOT_RUNNING; - mac->scheduling_info.retxBSR_SF = MAC_UE_BSR_TIMER_NOT_RUNNING; - mac->BSR_reporting_active = NR_BSR_TRIGGER_NONE; - LOG_D(MAC, "[UE %d]: periodic BSR %d (SF), retx BSR %d (SF)\n", - module_id, - mac->scheduling_info.periodicBSR_SF, - mac->scheduling_info.retxBSR_SF); - - configure_current_BWP(mac, NULL, cell_group_config); - config_control_ue(mac); - - if (cell_group_config->spCellConfig && cell_group_config->spCellConfig->reconfigurationWithSync) { - LOG_A(NR_MAC, "Received the reconfigurationWithSync in %s\n", __FUNCTION__); - if (cell_group_config->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated) { - ra->rach_ConfigDedicated = cell_group_config->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink; - } - mac->scc = cell_group_config->spCellConfig->reconfigurationWithSync->spCellConfigCommon; - mac->nr_band = *mac->scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]; - if (mac->scc_SIB) { - free(mac->scc_SIB); - mac->scc_SIB = NULL; - } - int num_slots = mac->scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots; - if (mac->scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols > 0) { - num_slots++; - } - mac->state = UE_NOT_SYNC; - mac->ra.ra_state = RA_UE_IDLE; - mac->physCellId = *mac->scc->physCellId; - if (!get_softmodem_params()->emulate_l1) { - mac->synch_request.Mod_id = module_id; - mac->synch_request.CC_id = cc_idP; - mac->synch_request.synch_req.target_Nid_cell = mac->physCellId; - mac->if_module->synch_request(&mac->synch_request); - } - mac->ul_config_request = calloc(num_slots, sizeof(*mac->ul_config_request)); - config_common_ue(mac, module_id, cc_idP); - mac->crnti = cell_group_config->spCellConfig->reconfigurationWithSync->newUE_Identity; - LOG_I(MAC, "Configuring CRNTI %x\n", mac->crnti); - - nr_ue_init_mac(module_id); - if (!get_softmodem_params()->emulate_l1) { - mac->if_module->phy_config_request(&mac->phy_config); - mac->phy_config_request_sent = true; - } - - // Setup the SSB to Rach Occasions mapping according to the config - build_ssb_to_ro_map(mac); - } - } - return 0; + configure_current_BWP(mac, NULL, scell_group_config); + config_control_ue(mac); + // Setup the SSB to Rach Occasions mapping according to the config + build_ssb_to_ro_map(mac); } diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index e5ffe9c356..cc2f90280e 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -399,7 +399,7 @@ typedef struct { long physCellId; //// MAC config int first_sync_frame; - bool sib1_decoded; + bool get_sib1; NR_DRX_Config_t *drx_Config; NR_SchedulingRequestConfig_t *schedulingRequestConfig; NR_BSR_Config_t *bsr_Config; diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index 0c69ee7d5f..53888c0f1d 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -43,6 +43,10 @@ \param module_id module id */ void nr_ue_init_mac(module_id_t module_idP); +/**\brief apply default configuration values in nr_mac instance + \param mac mac instance */ +void nr_ue_mac_default_configs(NR_UE_MAC_INST_t *mac); + /**\brief decode mib pdu in NR_UE, from if_module ul_ind with P7 tx_ind message \param module_id module id \param cc_id component carrier id @@ -91,22 +95,22 @@ int nr_rrc_mac_config_req_ue_logicalChannelBearer(module_id_t module_id, long logicalChannelIdentity, bool status); -/**\brief primitive from RRC layer to MAC layer for configuration L1/L2, now supported 4 rrc messages: MIB, cell_group_config for MAC/PHY, spcell_config(serving cell config) - \param module_id module id - \param cc_id component carrier id - \param gNB_index gNB index - \param mibP pointer to RRC message MIB - \param sccP pointer to ServingCellConfigCommon structure, - \param spcell_configP pointer to RRC message serving cell config*/ -int nr_rrc_mac_config_req_ue( - module_id_t module_id, - int cc_idP, - uint8_t gNB_index, - NR_MIB_t *mibP, - NR_ServingCellConfigCommonSIB_t *sccP, - NR_CellGroupConfig_t *cell_group_config, - NR_CellGroupConfig_t *scell_group_config -); +void nr_rrc_mac_config_req_scg(module_id_t module_id, + int cc_idP, + NR_CellGroupConfig_t *scell_group_config); + +void nr_rrc_mac_config_req_mcg(module_id_t module_id, + int cc_idP, + NR_CellGroupConfig_t *scell_group_config); + +void nr_rrc_mac_config_req_mib(module_id_t module_id, + int cc_idP, + NR_MIB_t *mibP, + bool sched_sib1); + +void nr_rrc_mac_config_req_sib1(module_id_t module_id, + int cc_idP, + NR_ServingCellConfigCommonSIB_t *scc); /**\brief initialization NR UE MAC instance(s), total number of MAC instance based on NB_NR_UE_MAC_INST*/ NR_UE_MAC_INST_t * nr_l2_init_ue(NR_UE_RRC_INST_t* rrc_inst); @@ -421,6 +425,8 @@ void fill_dci_search_candidates(NR_SearchSpace_t *ss,fapi_nr_dl_config_dci_dl_pd void build_ssb_to_ro_map(NR_UE_MAC_INST_t *mac); +void ue_init_config_request(NR_UE_MAC_INST_t *mac, int scs); + void configure_ss_coreset(NR_UE_MAC_INST_t *mac, NR_ServingCellConfig_t *scd, NR_BWP_Id_t dl_bwp_id); @@ -434,7 +440,7 @@ static uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac, dci_pdu_rel15_t *dci_pdu_rel15, int slot); -fapi_nr_ul_config_request_t *get_ul_config_request(NR_UE_MAC_INST_t *mac, int slot); +fapi_nr_ul_config_request_t *get_ul_config_request(NR_UE_MAC_INST_t *mac, int slot, int fb_time); fapi_nr_dl_config_request_t *get_dl_config_request(NR_UE_MAC_INST_t *mac, int slot); void fill_ul_config(fapi_nr_ul_config_request_t *ul_config, frame_t frame_tx, int slot_tx, uint8_t pdu_type); diff --git a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c index 96a9a3e072..8899be18e6 100644 --- a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c +++ b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c @@ -56,9 +56,17 @@ NR_UE_MAC_INST_t * nr_l2_init_ue(NR_UE_RRC_INST_t* rrc_inst) { for (int j = 0; j < NB_NR_UE_MAC_INST; j++) nr_ue_init_mac(j); + int scs = get_softmodem_params()->sa ? + get_softmodem_params()->numerology : + rrc_inst ? + *rrc_inst->scell_group_config->spCellConfig->reconfigurationWithSync->spCellConfigCommon->ssbSubcarrierSpacing : + - 1; + if (scs > -1) + ue_init_config_request(nr_ue_mac_inst, scs); + if (rrc_inst && rrc_inst->scell_group_config) { - nr_rrc_mac_config_req_ue(0,0,0,NULL,NULL,NULL,rrc_inst->scell_group_config); + nr_rrc_mac_config_req_scg(0, 0, rrc_inst->scell_group_config); AssertFatal(rlc_module_init(0) == 0, "%s: Could not initialize RLC layer\n", __FUNCTION__); if (IS_SOFTMODEM_NOS1){ // get default noS1 configuration @@ -78,24 +86,9 @@ NR_UE_MAC_INST_t * nr_l2_init_ue(NR_UE_RRC_INST_t* rrc_inst) { // free memory free_nr_noS1_bearer_config(&rbconfig, &rlc_rbconfig); } - // Allocate memory for ul_config_request in the mac instance. This is now a pointer and will - // point to a list of structures (one for each UL slot) to store PUSCH scheduling parameters - // received from UL DCI. - if (nr_ue_mac_inst->scc) { - NR_TDD_UL_DL_ConfigCommon_t *tdd = nr_ue_mac_inst->scc->tdd_UL_DL_ConfigurationCommon; - int num_slots_ul = tdd ? tdd->pattern1.nrofUplinkSlots : nr_slots_per_frame[*nr_ue_mac_inst->scc->ssbSubcarrierSpacing]; - if (tdd && nr_ue_mac_inst->scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols > 0) { - num_slots_ul++; - } - LOG_D(NR_MAC, "In %s: Initializing ul_config_request. num_slots_ul = %d\n", __FUNCTION__, num_slots_ul); - nr_ue_mac_inst->ul_config_request = (fapi_nr_ul_config_request_t *)calloc(num_slots_ul, sizeof(fapi_nr_ul_config_request_t)); - for (int i=0; iul_config_request[i].mutex_ul_config), NULL); - } } else { LOG_I(MAC,"Running without CellGroupConfig\n"); - nr_rrc_mac_config_req_ue(0,0,0,NULL,NULL,NULL,NULL); if(get_softmodem_params()->sa == 1) { AssertFatal(rlc_module_init(0) == 0, "%s: Could not initialize RLC layer\n", __FUNCTION__); } diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c index 5aa4438af0..69cdfde879 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c @@ -51,34 +51,34 @@ void fill_dci_search_candidates(NR_SearchSpace_t *ss, fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15, - int slot, int rnti) { - + int slot, int rnti) +{ LOG_D(NR_MAC,"Filling search candidates for DCI\n"); uint8_t aggregation; - uint8_t number_of_candidates=0; - rel15->number_of_candidates=0; - int i=0; + uint8_t number_of_candidates = 0; + rel15->number_of_candidates = 0; uint32_t Y = 0; + int i = 0; if (slot >= 0) Y = get_Y(ss, slot, rnti); - for (int maxL=16;maxL>0;maxL>>=1) { + for (int maxL = 16; maxL > 0; maxL >>= 1) { find_aggregation_candidates(&aggregation, &number_of_candidates, ss,maxL); if (number_of_candidates>0) { - LOG_D(NR_MAC,"L %d, number of candidates %d, aggregation %d\n",maxL,number_of_candidates,aggregation); + LOG_D(NR_MAC,"L %d, number of candidates %d, aggregation %d\n", maxL, number_of_candidates, aggregation); rel15->number_of_candidates += number_of_candidates; int N_cce_sym = 0; // nb of rbs of coreset per symbol - for (int i=0;i<6;i++) { - for (int t=0;t<8;t++) { - N_cce_sym+=((rel15->coreset.frequency_domain_resource[i]>>t)&1); + for (int f = 0; f < 6; f++) { + for (int t = 0; t < 8; t++) { + N_cce_sym += ((rel15->coreset.frequency_domain_resource[f] >> t) & 1); } } - int N_cces = N_cce_sym*rel15->coreset.duration; - for (int j=0; jcoreset.duration; + for (int j = 0; j < number_of_candidates; i++, j++) { + int first_cce = aggregation * ((Y + ((j * N_cces) / (aggregation * number_of_candidates)) + 0) % (N_cces / aggregation)); LOG_D(NR_MAC,"Candidate %d of %d first_cce %d (L %d N_cces %d Y %d)\n", j, number_of_candidates, first_cce, aggregation, N_cces, Y); rel15->CCE[i] = first_cce; rel15->L[i] = aggregation; @@ -220,9 +220,8 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t rel15->rnti = SI_RNTI; // SI-RNTI - 3GPP TS 38.321 Table 7.1-1: RNTI values - if(mac->frequency_range == FR1) - rel15->SubcarrierSpacing = mac->mib->subCarrierSpacingCommon; - else + rel15->SubcarrierSpacing = mac->mib->subCarrierSpacingCommon; + if(mac->frequency_range == FR2) rel15->SubcarrierSpacing = mac->mib->subCarrierSpacingCommon + 2; break; case NR_RNTI_SFI: diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 2cde4d3c07..7326d187a4 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -150,59 +150,55 @@ const initial_pucch_resource_t initial_pucch_resource[16] = { /* 15 */ { 1, 0, 14, 0, 4, { 0, 3, 6, 9 } }, }; - void nr_ue_init_mac(module_id_t module_idP) { - NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP); - // default values as deined in 38.331 sec 9.2.2 LOG_I(NR_MAC, "[UE%d] Applying default macMainConfig\n", module_idP); - //mac->scheduling_info.macConfig=NULL; + NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP); + nr_ue_mac_default_configs(mac); + mac->first_sync_frame = -1; + mac->get_sib1 = false; + mac->phy_config_request_sent = false; + mac->state = UE_NOT_SYNC; +} + +void nr_ue_mac_default_configs(NR_UE_MAC_INST_t *mac) +{ + // default values as defined in 38.331 sec 9.2.2 mac->scheduling_info.retxBSR_Timer = NR_BSR_Config__retxBSR_Timer_sf10240; mac->scheduling_info.periodicBSR_Timer = NR_BSR_Config__periodicBSR_Timer_infinity; -// mac->scheduling_info.periodicPHR_Timer = NR_MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf20; -// mac->scheduling_info.prohibitPHR_Timer = NR_MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf20; -// mac->scheduling_info.PathlossChange_db = NR_MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB1; -// mac->PHR_state = NR_MAC_MainConfig__phr_Config_PR_setup; mac->scheduling_info.SR_COUNTER = 0; mac->scheduling_info.sr_ProhibitTimer = 0; mac->scheduling_info.sr_ProhibitTimer_Running = 0; -// mac->scheduling_info.maxHARQ_Tx = NR_MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5; -// mac->scheduling_info.ttiBundling = 0; -// mac->scheduling_info.extendedBSR_Sizes_r10 = 0; -// mac->scheduling_info.extendedPHR_r10 = 0; -// mac->scheduling_info.drx_config = NULL; -// mac->scheduling_info.phr_config = NULL; - // set init value 0xFFFF, make sure periodic timer and retx time counters are NOT active, after bsr transmission set the value configured by the NW. + + // set init value 0xFFFF, make sure periodic timer and retx time counters are NOT active, after bsr transmission set the value + // configured by the NW. mac->scheduling_info.periodicBSR_SF = MAC_UE_BSR_TIMER_NOT_RUNNING; mac->scheduling_info.retxBSR_SF = MAC_UE_BSR_TIMER_NOT_RUNNING; mac->BSR_reporting_active = BSR_TRIGGER_NONE; -// mac->scheduling_info.periodicPHR_SF = nr_get_sf_perioidicPHR_Timer(mac->scheduling_info.periodicPHR_Timer); -// mac->scheduling_info.prohibitPHR_SF = nr_get_sf_prohibitPHR_Timer(mac->scheduling_info.prohibitPHR_Timer); -// mac->scheduling_info.PathlossChange_db = nr_get_db_dl_PathlossChange(mac->scheduling_info.PathlossChange); -// mac->PHR_reporting_active = 0; + + mac->first_sync_frame = -1; + mac->get_sib1 = false; + mac->phy_config_request_sent = false; + mac->state = UE_NOT_SYNC; + memset(&mac->ssb_measurements, 0, sizeof(mac->ssb_measurements)); for (int i = 0; i < NR_MAX_NUM_LCID; i++) { - LOG_D(NR_MAC, "[UE%d] Applying default logical channel config for LCGID %d\n", - module_idP, i); + LOG_D(NR_MAC, "Applying default logical channel config for LCGID %d\n", i); mac->scheduling_info.Bj[i] = -1; mac->scheduling_info.bucket_size[i] = -1; - if (i < UL_SCH_LCID_DTCH) { // initialize all control channels lcgid to 0 + if (i < UL_SCH_LCID_DTCH) { // initialize all control channels lcgid to 0 mac->scheduling_info.LCGID[i] = 0; - } else { // initialize all the data channels lcgid to 1 + } else { // initialize all the data channels lcgid to 1 mac->scheduling_info.LCGID[i] = 1; } mac->scheduling_info.LCID_status[i] = LCID_EMPTY; mac->scheduling_info.LCID_buffer_remain[i] = 0; - for (int i = 0; i < NR_MAX_HARQ_PROCESSES; i++) - mac->first_ul_tx[i] = 1; + for (int k = 0; k < NR_MAX_HARQ_PROCESSES; k++) + mac->first_ul_tx[k] = 1; } - mac->first_sync_frame = -1; - mac->sib1_decoded = false; - mac->phy_config_request_sent = false; - mac->state = UE_NOT_SYNC; memset(&mac->ssb_measurements, 0, sizeof(mac->ssb_measurements)); memset(&mac->ul_time_alignment, 0, sizeof(mac->ul_time_alignment)); } @@ -323,7 +319,7 @@ int8_t nr_ue_decode_mib(module_id_t module_id, else ssb_sc_offset_norm = ssb_subcarrier_offset; - if (!mac->sib1_decoded) { + if (mac->get_sib1) { nr_ue_sib1_scheduler(module_id, cc_id, ssb_start_symbol, @@ -361,8 +357,6 @@ int8_t nr_ue_decode_BCCH_DL_SCH(module_id_t module_id, uint32_t pdu_len) { if(ack_nack) { LOG_D(NR_MAC, "Decoding NR-BCCH-DL-SCH-Message (SIB1 or SI)\n"); - NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); - mac->sib1_decoded = true; nr_mac_rrc_data_ind_ue(module_id, cc_id, gNB_index, 0, 0, 0, NR_BCCH_DL_SCH, (uint8_t *) pduP, pdu_len); } else @@ -513,7 +507,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr if (ret != -1){ // Get UL config request corresponding slot_tx - fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slot_tx); + fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slot_tx, tda_info.k2); if (!ul_config) { LOG_W(MAC, "In %s: ul_config request is NULL. Probably due to unexpected UL DCI in frame.slot %d.%d. Ignoring DCI!\n", __FUNCTION__, frame, slot); @@ -582,7 +576,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr if (ret != -1){ // Get UL config request corresponding slot_tx - fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slot_tx); + fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slot_tx, tda_info.k2); if (!ul_config) { LOG_W(MAC, "In %s: ul_config request is NULL. Probably due to unexpected UL DCI in frame.slot %d.%d. Ignoring DCI!\n", __FUNCTION__, frame, slot); @@ -672,7 +666,10 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr 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_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_SI_DLSCH; + // in MIB SCS is signaled as 15or60 and 30or120 dlsch_config_pdu_1_0->SubcarrierSpacing = mac->mib->subCarrierSpacingCommon; + if(mac->frequency_range == FR2) + dlsch_config_pdu_1_0->SubcarrierSpacing = mac->mib->subCarrierSpacingCommon + 2; if (pdsch_config) pdsch_config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = NULL; // For PDSCH with mapping type A, the UE shall assume dmrs-AdditionalPosition='pos2' } else { dlsch_config_pdu_1_0->SubcarrierSpacing = current_DL_BWP->scs; @@ -4131,7 +4128,7 @@ int nr_ue_process_rar(nr_downlink_indication_t *dl_info, int pdu_id) if (ret != -1){ - fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slot_tx); + fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slot_tx, tda_info.k2); uint16_t rnti = mac->crnti; if (!ul_config) { diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 80944a5a05..086d80e477 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -107,35 +107,19 @@ void fill_scheduled_response(nr_scheduled_response_t *scheduled_response, * This function returns the UL config corresponding to a given UL slot * from MAC instance . */ -fapi_nr_ul_config_request_t *get_ul_config_request(NR_UE_MAC_INST_t *mac, int slot) +fapi_nr_ul_config_request_t *get_ul_config_request(NR_UE_MAC_INST_t *mac, int slot, int fb_time) { NR_TDD_UL_DL_ConfigCommon_t *tdd_config = mac->scc==NULL ? mac->scc_SIB->tdd_UL_DL_ConfigurationCommon : mac->scc->tdd_UL_DL_ConfigurationCommon; //Check if requested on the right slot - AssertFatal(is_nr_UL_slot(tdd_config, slot, mac->frame_type) != 0, "%s called at wrong slot %d\n", __func__, slot); + AssertFatal(is_nr_UL_slot(tdd_config, slot, mac->frame_type) != 0, "UL config_request called at wrong slot %d\n", slot); - // Calculate the index of the UL slot in mac->ul_config_request list. This is - // based on the TDD pattern (slot configuration period) and number of UL+mixed - // slots in the period. TS 38.213 Sec 11.1 int mu = mac->current_UL_BWP.scs; const int n = nr_slots_per_frame[mu]; - const int num_slots_per_tdd = tdd_config ? (n >> (7 - tdd_config->pattern1.dl_UL_TransmissionPeriodicity)) : n; - const int num_slots_ul = tdd_config ? (tdd_config->pattern1.nrofUplinkSlots + (tdd_config->pattern1.nrofUplinkSymbols != 0)) : n; - int index = slot % num_slots_ul; - - LOG_D(NR_MAC, "In %s slots per %s: %d, num_slots %d, index %d\n", - __FUNCTION__, - tdd_config ? "TDD" : "FDD", - num_slots_per_tdd, - num_slots_ul, - index); - - if (mac->ul_config_request) return &mac->ul_config_request[index]; - else { - LOG_E(NR_MAC, "mac->ul_config_request not set\n"); - return NULL; - } + AssertFatal(fb_time < n, "Cannot schedule to a slot more than 1 frame away, ul_config_request is not big enough\n"); + AssertFatal(mac->ul_config_request != NULL, "mac->ul_config_request not initialized, logic bug\n"); + return &mac->ul_config_request[slot]; } /* @@ -144,37 +128,8 @@ fapi_nr_ul_config_request_t *get_ul_config_request(NR_UE_MAC_INST_t *mac, int sl */ fapi_nr_dl_config_request_t *get_dl_config_request(NR_UE_MAC_INST_t *mac, int slot) { - int index; - if (!mac->scc && !mac->scc_SIB) - index = 0; - else { - NR_TDD_UL_DL_ConfigCommon_t *tdd_config = mac->scc==NULL ? mac->scc_SIB->tdd_UL_DL_ConfigurationCommon : mac->scc->tdd_UL_DL_ConfigurationCommon; - - //Check if requested on the right slot - AssertFatal(is_nr_DL_slot(tdd_config, slot) != 0, "%s called at wrong slot %d\n", __func__, slot); - - // Calculate the index of the DL slot in mac->ul_config_request list. This is - // based on the TDD pattern (slot configuration period) and number of DL+mixed - // slots in the period. TS 38.213 Sec 11.1 - int mu = mac->current_UL_BWP.scs; - const int n = nr_slots_per_frame[mu]; - const int num_slots_per_tdd = tdd_config ? (n >> (7 - tdd_config->pattern1.dl_UL_TransmissionPeriodicity)) : n; - const int num_slots_dl = tdd_config ? (tdd_config->pattern1.nrofDownlinkSlots + (tdd_config->pattern1.nrofDownlinkSymbols != 0)) : n; - - index = slot % num_slots_dl; - LOG_D(NR_MAC, "In %s slots per %s: %d, num_slots %d, index %d\n", - __FUNCTION__, - tdd_config ? "TDD" : "FDD", - num_slots_per_tdd, - num_slots_dl, - index); - } - - if (mac->dl_config_request) return &mac->dl_config_request[index]; - else { - LOG_E(NR_MAC, "mac->dl_config_request not set\n"); - return NULL; - } + AssertFatal(mac->dl_config_request != NULL, "mac->dl_config_request not initialized, logic bug\n"); + return &mac->dl_config_request[slot]; } void ul_layers_config(NR_UE_MAC_INST_t *mac, nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu, dci_pdu_rel15_t *dci, nr_dci_format_t dci_format) @@ -928,7 +883,7 @@ void nr_ue_aperiodic_srs_scheduling(NR_UE_MAC_INST_t *mac, long resource_trigger } int sched_frame = frame + (slot + slot_offset >= n_slots_frame) % 1024; - fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, sched_slot); + fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, sched_slot, slot_offset); fapi_nr_ul_config_srs_pdu *srs_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].srs_config_pdu; configure_srs_pdu(mac, srs_resource, srs_config_pdu, 0, 0); fill_ul_config(ul_config, sched_frame, sched_slot, FAPI_NR_UL_CONFIG_TYPE_SRS); @@ -981,7 +936,7 @@ bool nr_ue_periodic_srs_scheduling(module_id_t mod_id, frame_t frame, slot_t slo // Check if UE should transmit the SRS if((frame*n_slots_frame+slot-offset)%period == 0) { - fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slot); + fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slot, 0); fapi_nr_ul_config_srs_pdu *srs_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].srs_config_pdu; configure_srs_pdu(mac, srs_resource, srs_config_pdu, period, offset); @@ -1070,7 +1025,7 @@ void nr_ue_ul_scheduler(nr_uplink_indication_t *ul_info) NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); RA_config_t *ra = &mac->ra; - fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slot_tx); + fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slot_tx, 0); if (!ul_config) LOG_E(NR_MAC, "mac->ul_config is null!\n"); @@ -2238,7 +2193,7 @@ void nr_ue_pucch_scheduler(module_id_t module_idP, frame_t frameP, int slotP, vo if (num_res > 1) multiplex_pucch_resource(mac, pucch, num_res); - fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slotP); + fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slotP, 0); pthread_mutex_lock(&ul_config->mutex_ul_config); for (int j = 0; j < num_res; j++) { if (pucch[j].n_harq + pucch[j].n_sr + pucch[j].n_csi != 0) { @@ -2503,7 +2458,7 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s if(ra->ra_state != GENERATE_PREAMBLE) return; - fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slotP); + fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slotP, 0); if (!ul_config) { LOG_E(NR_MAC, "mac->ul_config is null! \n"); return; diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index 1a72fa951d..4ba189c4bd 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -99,73 +99,52 @@ static void process_rlcBearerConfig(struct NR_CellGroupConfig__rlc_BearerToAddMo static void process_drx_Config(NR_UE_sched_ctrl_t *sched_ctrl, NR_SetupRelease_DRX_Config_t *drx_Config) { - - if (!drx_Config) return; - AssertFatal(drx_Config->present != NR_SetupRelease_DRX_Config_PR_NOTHING, "Cannot have NR_SetupRelease_DRX_Config_PR_NOTHING\n"); - - if (drx_Config->present == NR_SetupRelease_DRX_Config_PR_setup) { - LOG_I(NR_MAC,"Adding DRX config\n"); - } - else { - LOG_I(NR_MAC,"Removing DRX config\n"); - } + AssertFatal(false, "%s() not implemented\n", __func__); + AssertFatal(drx_Config->present != NR_SetupRelease_DRX_Config_PR_NOTHING, "Cannot have NR_SetupRelease_DRX_Config_PR_NOTHING\n"); } static void process_schedulingRequestConfig(NR_UE_sched_ctrl_t *sched_ctrl, NR_SchedulingRequestConfig_t *schedulingRequestConfig) { - if (!schedulingRequestConfig) return; - - LOG_I(NR_MAC,"Adding SchedulingRequestconfig\n"); + AssertFatal(false, "%s() not implemented\n", __func__); } static void process_bsrConfig(NR_UE_sched_ctrl_t *sched_ctrl, NR_BSR_Config_t *bsr_Config) { - if (!bsr_Config) return; - LOG_I(NR_MAC,"Adding BSR config\n"); + AssertFatal(false, "%s() not implemented\n", __func__); } static void process_tag_Config(NR_UE_sched_ctrl_t *sched_ctrl, NR_TAG_Config_t *tag_Config) { - if (!tag_Config) return; - LOG_I(NR_MAC,"Adding TAG config\n"); + AssertFatal(false, "%s() not implemented\n", __func__); } static void process_phr_Config(NR_UE_sched_ctrl_t *sched_ctrl, NR_SetupRelease_PHR_Config_t *phr_Config) { - if (!phr_Config) return; - AssertFatal(phr_Config->present != NR_SetupRelease_PHR_Config_PR_NOTHING, "Cannot have NR_SetupRelease_PHR_Config_PR_NOTHING\n"); - - if (phr_Config->present == NR_SetupRelease_PHR_Config_PR_setup) { - LOG_I(NR_MAC,"Adding PHR config\n"); - } - else { - LOG_I(NR_MAC,"Removing PHR config\n"); - } + AssertFatal(false, "%s() not implemented\n", __func__); } void process_CellGroup(NR_CellGroupConfig_t *CellGroup, NR_UE_sched_ctrl_t *sched_ctrl) { + /* we assume that this function is mutex-protected from outside */ + NR_SCHED_ENSURE_LOCKED(&RC.nrmac[0]->sched_lock); + AssertFatal(CellGroup, "CellGroup is null\n"); NR_MAC_CellGroupConfig_t *mac_CellGroupConfig = CellGroup->mac_CellGroupConfig; if (mac_CellGroupConfig) { - process_drx_Config(sched_ctrl,mac_CellGroupConfig->drx_Config); - process_schedulingRequestConfig(sched_ctrl,mac_CellGroupConfig->schedulingRequestConfig); - process_bsrConfig(sched_ctrl,mac_CellGroupConfig->bsr_Config); - process_tag_Config(sched_ctrl,mac_CellGroupConfig->tag_Config); - process_phr_Config(sched_ctrl,mac_CellGroupConfig->phr_Config); - } - else { - // apply defaults - + //process_drx_Config(sched_ctrl,mac_CellGroupConfig->drx_Config); + //process_schedulingRequestConfig(sched_ctrl,mac_CellGroupConfig->schedulingRequestConfig); + //process_bsrConfig(sched_ctrl,mac_CellGroupConfig->bsr_Config); + //process_tag_Config(sched_ctrl,mac_CellGroupConfig->tag_Config); + //process_phr_Config(sched_ctrl,mac_CellGroupConfig->phr_Config); } process_rlcBearerConfig(CellGroup->rlc_BearerToAddModList,CellGroup->rlc_BearerToReleaseList,sched_ctrl); } -void config_common(gNB_MAC_INST *nrmac, int pdsch_AntennaPorts, int pusch_AntennaPorts, NR_ServingCellConfigCommon_t *scc) { - +static void config_common(gNB_MAC_INST *nrmac, int pdsch_AntennaPorts, int pusch_AntennaPorts, NR_ServingCellConfigCommon_t *scc) +{ nfapi_nr_config_request_scf_t *cfg = &nrmac->config[0]; nrmac->common_channels[0].ServingCellConfigCommon = scc; @@ -460,19 +439,23 @@ void config_common(gNB_MAC_INST *nrmac, int pdsch_AntennaPorts, int pusch_Antenn } } -int nr_mac_enable_ue_rrc_processing_timer(module_id_t Mod_idP, rnti_t rnti, NR_SubcarrierSpacing_t subcarrierSpacing, uint32_t rrc_reconfiguration_delay) { - +int nr_mac_enable_ue_rrc_processing_timer(module_id_t Mod_idP, rnti_t rnti, NR_SubcarrierSpacing_t subcarrierSpacing, uint32_t rrc_reconfiguration_delay) +{ if (rrc_reconfiguration_delay == 0) { return -1; } - NR_UE_info_t *UE_info = find_nr_UE(&RC.nrmac[Mod_idP]->UE_info,rnti); + gNB_MAC_INST *nrmac = RC.nrmac[Mod_idP]; + NR_SCHED_LOCK(&nrmac->sched_lock); + + NR_UE_info_t *UE_info = find_nr_UE(&nrmac->UE_info,rnti); if (!UE_info) { LOG_W(NR_MAC, "Could not find UE for RNTI 0x%04x\n", rnti); + NR_SCHED_UNLOCK(&nrmac->sched_lock); return -1; } NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl; - const uint16_t sl_ahead = RC.nrmac[Mod_idP]->if_inst->sl_ahead; + const uint16_t sl_ahead = nrmac->if_inst->sl_ahead; sched_ctrl->rrc_processing_timer = (rrc_reconfiguration_delay<rnti, rrc_reconfiguration_delay); @@ -480,8 +463,9 @@ int nr_mac_enable_ue_rrc_processing_timer(module_id_t Mod_idP, rnti_t rnti, NR_S // processing timer. To prevent this, set a variable as if we would have just // sent it. This way, another TA command will for sure be sent in some // frames, after RRC processing timer. - sched_ctrl->ta_frame = (RC.nrmac[Mod_idP]->frame - 1 + 1024) % 1024; + sched_ctrl->ta_frame = (nrmac->frame - 1 + 1024) % 1024; + NR_SCHED_UNLOCK(&nrmac->sched_lock); return 0; } @@ -494,6 +478,7 @@ void nr_mac_config_scc(gNB_MAC_INST *nrmac, { DevAssert(nrmac != NULL); AssertFatal(nrmac->common_channels[0].ServingCellConfigCommon == NULL, "logic error: multiple configurations of SCC\n"); + NR_SCHED_LOCK(&nrmac->sched_lock); DevAssert(scc != NULL); AssertFatal(scc->ssb_PositionsInBurst->present > 0 && scc->ssb_PositionsInBurst->present < 4, @@ -573,26 +558,31 @@ void nr_mac_config_scc(gNB_MAC_INST *nrmac, ra->preambles.preamble_list[i] = i; } } + NR_SCHED_UNLOCK(&nrmac->sched_lock); } void nr_mac_config_mib(gNB_MAC_INST *nrmac, NR_BCCH_BCH_Message_t *mib) { DevAssert(nrmac != NULL); DevAssert(mib != NULL); + NR_SCHED_LOCK(&nrmac->sched_lock); NR_COMMON_channels_t *cc = &nrmac->common_channels[0]; AssertFatal(cc->mib == NULL, "logic bug: updated MIB multiple times\n"); cc->mib = mib; + NR_SCHED_UNLOCK(&nrmac->sched_lock); } void nr_mac_config_sib1(gNB_MAC_INST *nrmac, NR_BCCH_DL_SCH_Message_t *sib1) { DevAssert(nrmac != NULL); DevAssert(sib1 != NULL); + NR_SCHED_LOCK(&nrmac->sched_lock); NR_COMMON_channels_t *cc = &nrmac->common_channels[0]; AssertFatal(cc->sib1 == NULL, "logic bug: updated SIB1 multiple times\n"); cc->sib1 = sib1; + NR_SCHED_UNLOCK(&nrmac->sched_lock); } bool nr_mac_add_test_ue(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig_t *CellGroup) @@ -600,16 +590,17 @@ bool nr_mac_add_test_ue(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig_t DevAssert(nrmac != NULL); DevAssert(CellGroup != NULL); DevAssert(get_softmodem_params()->phy_test); + NR_SCHED_LOCK(&nrmac->sched_lock); NR_UE_info_t* UE = add_new_nr_ue(nrmac, rnti, CellGroup); if (UE) { LOG_I(NR_MAC,"Force-added new UE %x with initial CellGroup\n", rnti); + process_CellGroup(CellGroup,&UE->UE_sched_ctrl); } else { LOG_E(NR_MAC,"Error adding UE %04x\n", rnti); - return false; } - process_CellGroup(CellGroup,&UE->UE_sched_ctrl); - return true; + NR_SCHED_UNLOCK(&nrmac->sched_lock); + return UE != NULL; } bool nr_mac_prepare_ra_nsa_ue(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig_t *CellGroup) @@ -617,6 +608,7 @@ bool nr_mac_prepare_ra_nsa_ue(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupCo DevAssert(nrmac != NULL); DevAssert(CellGroup != NULL); DevAssert(!get_softmodem_params()->phy_test); + NR_SCHED_LOCK(&nrmac->sched_lock); // NSA case: need to pre-configure CFRA const int CC_id = 0; @@ -628,6 +620,7 @@ bool nr_mac_prepare_ra_nsa_ue(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupCo } if (ra_index == NR_NB_RA_PROC_MAX) { LOG_E(NR_MAC, "RA processes are not available for CFRA RNTI %04x\n", rnti); + NR_SCHED_UNLOCK(&nrmac->sched_lock); return false; } NR_RA_t *ra = &cc->ra[ra_index]; @@ -656,12 +649,16 @@ bool nr_mac_prepare_ra_nsa_ue(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupCo } } LOG_I(NR_MAC,"Added new RA process for UE RNTI %04x with initial CellGroup\n", rnti); + NR_SCHED_UNLOCK(&nrmac->sched_lock); return true; } bool nr_mac_update_cellgroup(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig_t *CellGroup) { DevAssert(nrmac != NULL); + /* we assume that this function is mutex-protected from outside */ + NR_SCHED_ENSURE_LOCKED(&nrmac->sched_lock); + DevAssert(CellGroup != NULL); NR_UE_info_t *UE = find_nr_UE(&nrmac->UE_info, rnti); @@ -677,58 +674,7 @@ bool nr_mac_update_cellgroup(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupCon exit(1); } - nr_mac_update_RA(nrmac, rnti, CellGroup); process_CellGroup(CellGroup, &UE->UE_sched_ctrl); return true; } - -bool nr_mac_update_RA(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig_t *CellGroup) -{ - // Checking for free RA process - NR_COMMON_channels_t *cc = &nrmac->common_channels[0]; - uint8_t ra_index = 0; - for (; ra_index < NR_NB_RA_PROC_MAX; ra_index++) { - if ((cc->ra[ra_index].state == RA_IDLE) && (!cc->ra[ra_index].cfra)) - break; - } - if (ra_index == NR_NB_RA_PROC_MAX) { - LOG_E(NR_MAC, "%s() %s:%d RA processes are not available for CFRA RNTI :%x\n", __FUNCTION__, __FILE__, __LINE__, rnti); - return -1; - } - - NR_RA_t *ra = &cc->ra[ra_index]; - if (CellGroup->spCellConfig && CellGroup->spCellConfig->reconfigurationWithSync - && CellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated != NULL) { - if (CellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra != NULL) { - ra->cfra = true; - ra->rnti = rnti; - ra->CellGroup = CellGroup; - struct NR_CFRA *cfra = CellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra; - uint8_t num_preamble = cfra->resources.choice.ssb->ssb_ResourceList.list.count; - ra->preambles.num_preambles = num_preamble; - ra->preambles.preamble_list = (uint8_t *)malloc(num_preamble * sizeof(uint8_t)); - for (int i = 0; i < cc->num_active_ssb; i++) { - for (int j = 0; j < num_preamble; j++) { - if (cc->ssb_index[i] == cfra->resources.choice.ssb->ssb_ResourceList.list.array[j]->ssb) { - // One dedicated preamble for each beam - ra->preambles.preamble_list[i] = cfra->resources.choice.ssb->ssb_ResourceList.list.array[j]->ra_PreambleIndex; - break; - } - } - } - } - } else { - ra->cfra = false; - ra->rnti = 0; - if (ra->preambles.preamble_list == NULL) { - ra->preambles.num_preambles = MAX_NUM_NR_PRACH_PREAMBLES; - ra->preambles.preamble_list = (uint8_t *)malloc(MAX_NUM_NR_PRACH_PREAMBLES * sizeof(uint8_t)); - for (int i = 0; i < MAX_NUM_NR_PRACH_PREAMBLES; i++) - ra->preambles.preamble_list[i] = i; - } - } - LOG_I(NR_MAC, "Added new %s process for UE RNTI %04x with initial CellGroup\n", ra->cfra ? "CFRA" : "CBRA", rnti); - - return true; -} diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c index e831f6d4a8..2d4cd16eb4 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c @@ -63,6 +63,7 @@ void clear_nr_nfapi_information(gNB_MAC_INST *gNB, nfapi_nr_tx_data_request_t *TX_req, nfapi_nr_ul_dci_request_t *UL_dci_req) { + /* called below and in simulators, so we assume a lock but don't require it */ NR_ServingCellConfigCommon_t *scc = gNB->common_channels->ServingCellConfigCommon; const int num_slots = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; @@ -149,6 +150,8 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frame, sub_frame_ NR_COMMON_channels_t *cc = gNB->common_channels; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; + NR_SCHED_LOCK(&gNB->sched_lock); + if (slot==0 && (*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]>=257)) { //FR2 const NR_TDD_UL_DL_Pattern_t *tdd = &scc->tdd_UL_DL_ConfigurationCommon->pattern1; @@ -254,6 +257,6 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frame, sub_frame_ copy_ul_tti_req(&sched_info->UL_tti_req, &gNB->UL_tti_req_ahead[0][current_index]); stop_meas(&gNB->eNB_scheduler); - + NR_SCHED_UNLOCK(&gNB->sched_lock); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_OUT); } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 2461d9618d..fb78ff0d13 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -49,17 +49,32 @@ extern RAN_CONTEXT_t RC; extern const uint8_t nr_slots_per_frame[5]; extern uint16_t sl_ahead; +// forward declaration of functions used in this file +static void fill_msg3_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu, + NR_ServingCellConfigCommon_t *scc, + int round, + int startSymbolAndLength, + rnti_t rnti, + int scs, + int bwp_size, + int bwp_start, + int mappingtype, + int fh, + int msg3_first_rb, + int msg3_nb_rb); +static void nr_fill_rar(uint8_t Mod_idP, NR_RA_t *ra, uint8_t *dlsch_buffer, nfapi_nr_pusch_pdu_t *pusch_pdu); + static const uint8_t DELTA[4] = {2, 3, 4, 6}; static const float ssb_per_rach_occasion[8] = {0.125, 0.25, 0.5, 1, 2, 4, 8}; -int16_t ssb_index_from_prach(module_id_t module_idP, - frame_t frameP, - sub_frame_t slotP, - uint16_t preamble_index, - uint8_t freq_index, - uint8_t symbol) { - +static int16_t ssb_index_from_prach(module_id_t module_idP, + frame_t frameP, + sub_frame_t slotP, + uint16_t preamble_index, + uint8_t freq_index, + uint8_t symbol) +{ gNB_MAC_INST *gNB = RC.nrmac[module_idP]; NR_COMMON_channels_t *cc = &gNB->common_channels[0]; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; @@ -139,10 +154,12 @@ int16_t ssb_index_from_prach(module_id_t module_idP, return index; } - //Compute Total active SSBs and RO available void find_SSB_and_RO_available(gNB_MAC_INST *nrmac) { + /* already mutex protected through nr_mac_config_scc() */ + NR_SCHED_ENSURE_LOCKED(&nrmac->sched_lock); + NR_COMMON_channels_t *cc = &nrmac->common_channels[0]; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; nfapi_nr_config_request_scf_t *cfg = &nrmac->config[0]; @@ -242,6 +259,9 @@ void find_SSB_and_RO_available(gNB_MAC_INST *nrmac) void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) { gNB_MAC_INST *gNB = RC.nrmac[module_idP]; + /* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */ + NR_SCHED_ENSURE_LOCKED(&gNB->sched_lock); + NR_COMMON_channels_t *cc = gNB->common_channels; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; int mu; @@ -399,15 +419,20 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP } } -void nr_schedule_msg2(uint16_t rach_frame, uint16_t rach_slot, - uint16_t *msg2_frame, uint16_t *msg2_slot, - int mu, NR_ServingCellConfigCommon_t *scc, - frame_type_t frame_type, - uint16_t monitoring_slot_period, - uint16_t monitoring_offset,uint8_t beam_index, - uint8_t num_active_ssb, - int16_t *tdd_beam_association, int sl_ahead){ - +static void nr_schedule_msg2(uint16_t rach_frame, + uint16_t rach_slot, + uint16_t *msg2_frame, + uint16_t *msg2_slot, + int mu, + NR_ServingCellConfigCommon_t *scc, + frame_type_t frame_type, + uint16_t monitoring_slot_period, + uint16_t monitoring_offset, + uint8_t beam_index, + uint8_t num_active_ssb, + int16_t *tdd_beam_association, + int sl_ahead) +{ // preferentially we schedule the msg2 in the mixed slot or in the last dl slot // if they are allowed by search space configuration uint8_t response_window = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.ra_ResponseWindow; @@ -516,12 +541,13 @@ void nr_initiate_ra_proc(module_id_t module_idP, uint16_t preamble_index, uint8_t freq_index, uint8_t symbol, - int16_t timing_offset){ + int16_t timing_offset) +{ + gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; + NR_SCHED_LOCK(&nr_mac->sched_lock); uint8_t ul_carrier_id = 0; // 0 for NUL 1 for SUL - uint16_t msg2_frame, msg2_slot,monitoring_slot_period,monitoring_offset; - gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id]; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; frame_type_t frame_type = cc->frame_type; @@ -655,57 +681,22 @@ void nr_initiate_ra_proc(module_id_t module_idP, cc->ssb_index[beam_index], i); + NR_SCHED_UNLOCK(&nr_mac->sched_lock); return; } + + NR_SCHED_UNLOCK(&nr_mac->sched_lock); LOG_E(NR_MAC, "[gNB %d][RAPROC] FAILURE: CC_id %d Frame %d initiating RA procedure for preamble index %d\n", module_idP, CC_id, frameP, preamble_index); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 0); } -void nr_schedule_RA(module_id_t module_idP, - frame_t frameP, - sub_frame_t slotP, - nfapi_nr_ul_dci_request_t *ul_dci_req, - nfapi_nr_dl_tti_request_t *DL_req, - nfapi_nr_tx_data_request_t *TX_req) -{ - gNB_MAC_INST *mac = RC.nrmac[module_idP]; - - start_meas(&mac->schedule_ra); - for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - NR_COMMON_channels_t *cc = &mac->common_channels[CC_id]; - for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) { - NR_RA_t *ra = &cc->ra[i]; - LOG_D(NR_MAC, "RA[state:%d]\n", ra->state); - switch (ra->state) { - case Msg2: - nr_generate_Msg2(module_idP, CC_id, frameP, slotP, ra, DL_req, TX_req); - break; - case Msg3_retransmission: - nr_generate_Msg3_retransmission(module_idP, CC_id, frameP, slotP, ra, ul_dci_req); - break; - case Msg3_dcch_dtch: - nr_generate_Msg3_dcch_dtch_response(module_idP, CC_id, frameP, slotP, ra, DL_req, TX_req); - case Msg4: - nr_generate_Msg4(module_idP, CC_id, frameP, slotP, ra, DL_req, TX_req); - break; - case WAIT_Msg4_ACK: - nr_check_Msg4_Ack(module_idP, CC_id, frameP, slotP, ra); - break; - default: - break; - } - } - } - stop_meas(&mac->schedule_ra); -} - -void nr_generate_Msg3_retransmission(module_id_t module_idP, - int CC_id, - frame_t frame, - sub_frame_t slot, - NR_RA_t *ra, - nfapi_nr_ul_dci_request_t *ul_dci_req) +static void nr_generate_Msg3_retransmission(module_id_t module_idP, + int CC_id, + frame_t frame, + sub_frame_t slot, + NR_RA_t *ra, + nfapi_nr_ul_dci_request_t *ul_dci_req) { gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id]; @@ -877,15 +868,14 @@ void nr_generate_Msg3_retransmission(module_id_t module_idP, } } -void nr_get_Msg3alloc(module_id_t module_id, - int CC_id, - NR_ServingCellConfigCommon_t *scc, - sub_frame_t current_slot, - frame_t current_frame, - NR_RA_t *ra, - int16_t *tdd_beam_association) +static void nr_get_Msg3alloc(module_id_t module_id, + int CC_id, + NR_ServingCellConfigCommon_t *scc, + sub_frame_t current_slot, + frame_t current_frame, + NR_RA_t *ra, + int16_t *tdd_beam_association) { - // msg3 is scheduled in mixed slot in the following TDD period uint16_t msg3_nb_rb = 8; // sdu has 6 or 8 bytes @@ -999,16 +989,19 @@ void nr_get_Msg3alloc(module_id_t module_id, ra->msg3_bwp_start = bwpStart; } - -void fill_msg3_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu, - NR_ServingCellConfigCommon_t *scc, - int round, - int startSymbolAndLength, - rnti_t rnti, int scs, - int bwp_size, int bwp_start, - int mappingtype, int fh, - int msg3_first_rb, int msg3_nb_rb) { - +static void fill_msg3_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu, + NR_ServingCellConfigCommon_t *scc, + int round, + int startSymbolAndLength, + rnti_t rnti, + int scs, + int bwp_size, + int bwp_start, + int mappingtype, + int fh, + int msg3_first_rb, + int msg3_nb_rb) +{ int start_symbol_index,nr_of_symbols; SLIV2SL(startSymbolAndLength, &start_symbol_index, &nr_of_symbols); @@ -1087,7 +1080,7 @@ void fill_msg3_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu, } } -void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra, uint8_t *RAR_pdu) +static void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra, uint8_t *RAR_pdu) { gNB_MAC_INST *mac = RC.nrmac[module_idP]; NR_COMMON_channels_t *cc = &mac->common_channels[CC_id]; @@ -1155,13 +1148,14 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t nr_fill_rar(module_idP, ra, RAR_pdu, pusch_pdu); } -void nr_generate_Msg2(module_id_t module_idP, - int CC_id, - frame_t frameP, - sub_frame_t slotP, - NR_RA_t *ra, - nfapi_nr_dl_tti_request_t *DL_req, - nfapi_nr_tx_data_request_t *TX_req) + +static void nr_generate_Msg2(module_id_t module_idP, + int CC_id, + frame_t frameP, + sub_frame_t slotP, + NR_RA_t *ra, + nfapi_nr_dl_tti_request_t *DL_req, + nfapi_nr_tx_data_request_t *TX_req) { gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id]; @@ -1427,22 +1421,29 @@ void nr_generate_Msg2(module_id_t module_idP, } } -void prepare_dl_pdus(gNB_MAC_INST *nr_mac, - NR_RA_t *ra, - NR_UE_DL_BWP_t *dl_bwp, - nfapi_nr_dl_tti_request_body_t *dl_req, - NR_sched_pucch_t *pucch, - NR_pdsch_dmrs_t dmrs_info, - NR_tda_info_t tda, - int aggregation_level, - int CCEIndex, - int tb_size, int ndi, - int tpc, int delta_PRI, - int current_harq_pid, - int time_domain_assignment, - int CC_id, int rnti, int round, - int mcsIndex, int tb_scaling, - int pduindex, int rbStart, int rbSize) +static void prepare_dl_pdus(gNB_MAC_INST *nr_mac, + NR_RA_t *ra, + NR_UE_DL_BWP_t *dl_bwp, + nfapi_nr_dl_tti_request_body_t *dl_req, + NR_sched_pucch_t *pucch, + NR_pdsch_dmrs_t dmrs_info, + NR_tda_info_t tda, + int aggregation_level, + int CCEIndex, + int tb_size, + int ndi, + int tpc, + int delta_PRI, + int current_harq_pid, + int time_domain_assignment, + int CC_id, + int rnti, + int round, + int mcsIndex, + int tb_scaling, + int pduindex, + int rbStart, + int rbSize) { // look up the PDCCH PDU for this CC, BWP, and CORESET. If it does not exist, create it. This is especially // important if we have multiple RAs, and the DLSCH has to reuse them, so we need to mark them @@ -1613,13 +1614,13 @@ void prepare_dl_pdus(gNB_MAC_INST *nr_mac, LOG_D(NR_MAC,"numDlDci: %i\n", pdcch_pdu_rel15->numDlDci); } -void nr_generate_Msg3_dcch_dtch_response(module_id_t module_idP, - int CC_id, - frame_t frameP, - sub_frame_t slotP, - NR_RA_t *ra, - nfapi_nr_dl_tti_request_t *DL_req, - nfapi_nr_tx_data_request_t *TX_req) +static void nr_generate_Msg3_dcch_dtch_response(module_id_t module_idP, + int CC_id, + frame_t frameP, + sub_frame_t slotP, + NR_RA_t *ra, + nfapi_nr_dl_tti_request_t *DL_req, + nfapi_nr_tx_data_request_t *TX_req) { gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; @@ -1799,13 +1800,13 @@ void nr_generate_Msg3_dcch_dtch_response(module_id_t module_idP, sched_ctrl->ul_failure = 0; } -void nr_generate_Msg4(module_id_t module_idP, - int CC_id, - frame_t frameP, - sub_frame_t slotP, - NR_RA_t *ra, - nfapi_nr_dl_tti_request_t *DL_req, - nfapi_nr_tx_data_request_t *TX_req) +static void nr_generate_Msg4(module_id_t module_idP, + int CC_id, + frame_t frameP, + sub_frame_t slotP, + NR_RA_t *ra, + nfapi_nr_dl_tti_request_t *DL_req, + nfapi_nr_tx_data_request_t *TX_req) { gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id]; @@ -2056,8 +2057,8 @@ void nr_generate_Msg4(module_id_t module_idP, } } -void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, sub_frame_t slot, NR_RA_t *ra) { - +static void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, sub_frame_t slot, NR_RA_t *ra) +{ NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[module_id]->UE_info, ra->rnti); const int current_harq_pid = ra->harq_pid; @@ -2098,7 +2099,10 @@ void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, sub_fram } } -void nr_clear_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP, NR_RA_t *ra){ +void nr_clear_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP, NR_RA_t *ra) +{ + /* we assume that this function is mutex-protected from outside */ + NR_SCHED_ENSURE_LOCKED(&RC.nrmac[module_idP]->sched_lock); LOG_D(NR_MAC,"[gNB %d][RAPROC] CC_id %d Frame %d Clear Random access information rnti %x\n", module_idP, CC_id, frameP, ra->rnti); ra->state = RA_IDLE; ra->timing_offset = 0; @@ -2141,11 +2145,8 @@ void nr_clear_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP, NR_RA_t // - sending only 1 RAR subPDU // - UL Grant: hardcoded CSI, TPC, time alloc // - padding -void nr_fill_rar(uint8_t Mod_idP, - NR_RA_t * ra, - uint8_t * dlsch_buffer, - nfapi_nr_pusch_pdu_t *pusch_pdu){ - +static void nr_fill_rar(uint8_t Mod_idP, NR_RA_t *ra, uint8_t *dlsch_buffer, nfapi_nr_pusch_pdu_t *pusch_pdu) +{ LOG_D(NR_MAC, "[gNB] Generate RAR MAC PDU frame %d slot %d preamble index %u TA command %d \n", ra->Msg2_frame, ra-> Msg2_slot, ra->preamble_index, ra->timing_offset); NR_RA_HEADER_BI *rarbi = (NR_RA_HEADER_BI *) dlsch_buffer; NR_RA_HEADER_RAPID *rarh = (NR_RA_HEADER_RAPID *) (dlsch_buffer + 1); @@ -2239,3 +2240,43 @@ void nr_fill_rar(uint8_t Mod_idP, csi_req, t_crnti); } + +void nr_schedule_RA(module_id_t module_idP, + frame_t frameP, + sub_frame_t slotP, + nfapi_nr_ul_dci_request_t *ul_dci_req, + nfapi_nr_dl_tti_request_t *DL_req, + nfapi_nr_tx_data_request_t *TX_req) +{ + gNB_MAC_INST *mac = RC.nrmac[module_idP]; + /* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */ + NR_SCHED_ENSURE_LOCKED(&mac->sched_lock); + + start_meas(&mac->schedule_ra); + for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + NR_COMMON_channels_t *cc = &mac->common_channels[CC_id]; + for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) { + NR_RA_t *ra = &cc->ra[i]; + LOG_D(NR_MAC, "RA[state:%d]\n", ra->state); + switch (ra->state) { + case Msg2: + nr_generate_Msg2(module_idP, CC_id, frameP, slotP, ra, DL_req, TX_req); + break; + case Msg3_retransmission: + nr_generate_Msg3_retransmission(module_idP, CC_id, frameP, slotP, ra, ul_dci_req); + break; + case Msg3_dcch_dtch: + nr_generate_Msg3_dcch_dtch_response(module_idP, CC_id, frameP, slotP, ra, DL_req, TX_req); + case Msg4: + nr_generate_Msg4(module_idP, CC_id, frameP, slotP, ra, DL_req, TX_req); + break; + case WAIT_Msg4_ACK: + nr_check_Msg4_Ack(module_idP, CC_id, frameP, slotP, ra); + break; + default: + break; + } + } + } + stop_meas(&mac->schedule_ra); +} diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c index f6d1f83e35..0d66ec0842 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c @@ -51,11 +51,15 @@ extern RAN_CONTEXT_t RC; -void schedule_ssb(frame_t frame, sub_frame_t slot, - NR_ServingCellConfigCommon_t *scc, - nfapi_nr_dl_tti_request_body_t *dl_req, - int i_ssb, uint8_t scoffset, uint16_t offset_pointa, uint32_t payload) { - +static void schedule_ssb(frame_t frame, + sub_frame_t slot, + NR_ServingCellConfigCommon_t *scc, + nfapi_nr_dl_tti_request_body_t *dl_req, + int i_ssb, + uint8_t scoffset, + uint16_t offset_pointa, + uint32_t payload) +{ uint8_t beam_index = 0; nfapi_nr_dl_tti_request_pdu_t *dl_config_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs]; memset((void *) dl_config_pdu, 0,sizeof(nfapi_nr_dl_tti_request_pdu_t)); @@ -86,12 +90,25 @@ void schedule_ssb(frame_t frame, sub_frame_t slot, dl_req->nPDUs++; LOG_D(MAC,"Scheduling ssb %d at frame %d and slot %d\n",i_ssb,frame,slot); +} +static void fill_ssb_vrb_map(NR_COMMON_channels_t *cc, int rbStart, int ssb_subcarrier_offset, uint16_t symStart, int CC_id) +{ + AssertFatal(*cc->ServingCellConfigCommon->ssbSubcarrierSpacing != + NR_SubcarrierSpacing_kHz240, + "240kHZ subcarrier won't work with current VRB map because a single SSB might be across 2 slots\n"); + + uint16_t *vrb_map = cc[CC_id].vrb_map; + + const int extra_prb = ssb_subcarrier_offset > 0; + for (int rb = 0; rb < 20+extra_prb; rb++) + vrb_map[rbStart + rb] = SL_to_bitmap(symStart, 4); } void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP, nfapi_nr_dl_tti_request_t *DL_req) { gNB_MAC_INST *gNB = RC.nrmac[module_idP]; + /* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */ NR_COMMON_channels_t *cc; nfapi_nr_dl_tti_request_body_t *dl_req; NR_MIB_t *mib = RC.nrrrc[module_idP]->carrier.mib->message.choice.mib; @@ -254,33 +271,15 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP, } } -void schedule_nr_SI(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) { -//---------------------------------------- -} - -void fill_ssb_vrb_map (NR_COMMON_channels_t *cc, int rbStart, int ssb_subcarrier_offset, uint16_t symStart, int CC_id) { - - AssertFatal(*cc->ServingCellConfigCommon->ssbSubcarrierSpacing != - NR_SubcarrierSpacing_kHz240, - "240kHZ subcarrier won't work with current VRB map because a single SSB might be across 2 slots\n"); - - uint16_t *vrb_map = cc[CC_id].vrb_map; - - const int extra_prb = ssb_subcarrier_offset > 0; - for (int rb = 0; rb < 20+extra_prb; rb++) - vrb_map[rbStart + rb] = SL_to_bitmap(symStart, 4); - -} - -uint32_t schedule_control_sib1(module_id_t module_id, - int CC_id, - NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config, - int time_domain_allocation, - NR_pdsch_dmrs_t *dmrs_parms, - NR_tda_info_t *tda_info, - uint8_t candidate_idx, - uint16_t num_total_bytes) { - +static uint32_t schedule_control_sib1(module_id_t module_id, + int CC_id, + NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config, + int time_domain_allocation, + NR_pdsch_dmrs_t *dmrs_parms, + NR_tda_info_t *tda_info, + uint8_t candidate_idx, + uint16_t num_total_bytes) +{ gNB_MAC_INST *gNB_mac = RC.nrmac[module_id]; NR_COMMON_channels_t *cc = &gNB_mac->common_channels[CC_id]; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; @@ -377,14 +376,14 @@ uint32_t schedule_control_sib1(module_id_t module_id, return TBS; } -void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP, - nfapi_nr_dl_tti_request_body_t *dl_req, - int pdu_index, - NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config, - uint32_t TBS, - int StartSymbolIndex, - int NrOfSymbols) { - +static void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP, + nfapi_nr_dl_tti_request_body_t *dl_req, + int pdu_index, + NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config, + uint32_t TBS, + int StartSymbolIndex, + int NrOfSymbols) +{ gNB_MAC_INST *gNB_mac = RC.nrmac[Mod_idP]; NR_COMMON_channels_t *cc = gNB_mac->common_channels; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; @@ -515,7 +514,6 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP, LOG_D(MAC,"ShiftIndex: %i\n", pdcch_pdu_rel15->ShiftIndex); LOG_D(MAC,"precoderGranularity: %i\n", pdcch_pdu_rel15->precoderGranularity); LOG_D(MAC,"numDlDci: %i\n", pdcch_pdu_rel15->numDlDci); - } void schedule_nr_sib1(module_id_t module_idP, @@ -524,6 +522,7 @@ void schedule_nr_sib1(module_id_t module_idP, nfapi_nr_dl_tti_request_t *DL_req, nfapi_nr_tx_data_request_t *TX_req) { + /* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */ // TODO: Get these values from RRC const int CC_id = 0; uint8_t candidate_idx = 0; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 71b4499c55..4d3d59c12e 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -55,6 +55,7 @@ const int get_dl_tda(const gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon_t *scc, int slot) { + /* we assume that this function is mutex-protected from outside */ const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL; AssertFatal(tdd || nrmac->common_channels->frame_type == FDD, "Dynamic TDD not handled yet\n"); @@ -76,8 +77,12 @@ int nr_write_ce_dlsch_pdu(module_id_t module_idP, const NR_UE_sched_ctrl_t *ue_sched_ctl, unsigned char *mac_pdu, unsigned char drx_cmd, - unsigned char *ue_cont_res_id) { + unsigned char *ue_cont_res_id) +{ gNB_MAC_INST *gNB = RC.nrmac[module_idP]; + /* already mutex protected: called below and in _RA.c */ + NR_SCHED_ENSURE_LOCKED(&gNB->sched_lock); + NR_MAC_SUBHEADER_FIXED *mac_pdu_ptr = (NR_MAC_SUBHEADER_FIXED *) mac_pdu; uint8_t last_size = 0; int offset = 0, mac_ce_size, i, timing_advance_cmd, tag_id = 0; @@ -311,10 +316,8 @@ int nr_write_ce_dlsch_pdu(module_id_t module_idP, return offset; } -void nr_store_dlsch_buffer(module_id_t module_id, - frame_t frame, - sub_frame_t slot) { - +static void nr_store_dlsch_buffer(module_id_t module_id, frame_t frame, sub_frame_t slot) +{ UE_iterator(RC.nrmac[module_id]->UE_info.list, UE) { NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; sched_ctrl->num_total_bytes = 0; @@ -363,8 +366,9 @@ void nr_store_dlsch_buffer(module_id_t module_id, } } -void abort_nr_dl_harq(NR_UE_info_t* UE, int8_t harq_pid) { - +void abort_nr_dl_harq(NR_UE_info_t* UE, int8_t harq_pid) +{ + /* already mutex protected through handle_dl_harq() */ NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; NR_UE_harq_t *harq = &sched_ctrl->harq_processes[harq_pid]; @@ -375,13 +379,13 @@ void abort_nr_dl_harq(NR_UE_info_t* UE, int8_t harq_pid) { } -bool allocate_dl_retransmission(module_id_t module_id, - frame_t frame, - sub_frame_t slot, - uint16_t *rballoc_mask, - int *n_rb_sched, - NR_UE_info_t *UE, - int current_harq_pid) +static bool allocate_dl_retransmission(module_id_t module_id, + frame_t frame, + sub_frame_t slot, + uint16_t *rballoc_mask, + int *n_rb_sched, + NR_UE_info_t *UE, + int current_harq_pid) { int CC_id = 0; @@ -549,15 +553,14 @@ static int comparator(const void *p, const void *q) { return ((UEsched_t*)p)->coef < ((UEsched_t*)q)->coef; } -void pf_dl(module_id_t module_id, - frame_t frame, - sub_frame_t slot, - NR_UE_info_t **UE_list, - int max_num_ue, - int n_rb_sched, - uint16_t *rballoc_mask) +static void pf_dl(module_id_t module_id, + frame_t frame, + sub_frame_t slot, + NR_UE_info_t **UE_list, + int max_num_ue, + int n_rb_sched, + uint16_t *rballoc_mask) { - gNB_MAC_INST *mac = RC.nrmac[module_id]; NR_ServingCellConfigCommon_t *scc=mac->common_channels[0].ServingCellConfigCommon; // UEs that could be scheduled @@ -784,7 +787,7 @@ void pf_dl(module_id_t module_id, } } -void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t slot) +static void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t slot) { NR_UEs_t *UE_info = &RC.nrmac[module_id]->UE_info; @@ -843,6 +846,7 @@ void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t } nr_pp_impl_dl nr_init_fr1_dlsch_preprocessor(int CC_id) { + /* during initialization: no mutex needed */ /* in the PF algorithm, we have to use the TBsize to compute the coefficient. * This would include the number of DMRS symbols, which in turn depends on * the time domain allocation. In case we are in a mixed slot, we do not want @@ -876,6 +880,9 @@ void nr_schedule_ue_spec(module_id_t module_id, nfapi_nr_tx_data_request_t *TX_req) { gNB_MAC_INST *gNB_mac = RC.nrmac[module_id]; + /* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */ + AssertFatal(pthread_mutex_trylock(&gNB_mac->sched_lock) == EBUSY, + "this function should be called with the scheduler mutex locked\n"); if (!is_xlsch_in_slot(gNB_mac->dlsch_slot_bitmap[slot / 64], slot)) return; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index 96756d41cd..d59efafdc2 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -50,6 +50,7 @@ void nr_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_t slot) { + /* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */ if (!is_xlsch_in_slot(dlsch_slot_bitmap, slot)) return; NR_UE_info_t *UE = RC.nrmac[module_id]->UE_info.list[0]; @@ -192,6 +193,7 @@ uint64_t ulsch_slot_bitmap = (1 << 8); bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_t slot) { gNB_MAC_INST *nr_mac = RC.nrmac[module_id]; + /* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */ NR_COMMON_channels_t *cc = nr_mac->common_channels; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; NR_UE_info_t *UE = nr_mac->UE_info.list[0]; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 0deb86a5db..33bd6831d1 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -413,31 +413,31 @@ int find_pdcch_candidate(const gNB_MAC_INST *mac, int nr_of_candidates, const NR_sched_pdcch_t *pdcch, const NR_ControlResourceSet_t *coreset, - uint32_t Y){ - + uint32_t Y) +{ const uint16_t *vrb_map = mac->common_channels[cc_id].vrb_map; const int N_ci = 0; const int N_rb = pdcch->n_rb; // nb of rbs of coreset per symbol const int N_symb = coreset->duration; // nb of coreset symbols - const int N_regs = N_rb*N_symb; // nb of REGs per coreset + const int N_regs = N_rb * N_symb; // nb of REGs per coreset const int N_cces = N_regs / NR_NB_REG_PER_CCE; // nb of cces in coreset const int R = pdcch->InterleaverSize; const int L = pdcch->RegBundleSize; - const int C = R>0 ? N_regs/(L*R) : 0; - const int B_rb = L/N_symb; // nb of RBs occupied by each REG bundle + const int C = R > 0 ? N_regs / (L * R) : 0; + const int B_rb = L / N_symb; // nb of RBs occupied by each REG bundle // loop over all the available candidates // this implements TS 38.211 Sec. 7.3.2.2 - for(int m=0; mShiftIndex, C, L, N_regs); - for(int rb=0; rbBWPStart + f*B_rb + rb]&SL_to_bitmap(pdcch->StartSymbolIndex,N_symb)) { + for(int rb = 0; rb < B_rb; rb++) { // loop over the RBs of the bundle + if(vrb_map[pdcch->BWPStart + f * B_rb + rb] & SL_to_bitmap(pdcch->StartSymbolIndex,N_symb)) { taken = true; break; } @@ -509,7 +509,7 @@ void fill_pdcch_vrb_map(gNB_MAC_INST *mac, } } -bool multiple_2_3_5(int rb) +static bool multiple_2_3_5(int rb) { while (rb % 2 == 0) rb /= 2; @@ -2369,7 +2369,7 @@ NR_UE_info_t *add_new_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rntiP, NR_CellGroupConf reset_srs_stats(UE); - pthread_mutex_lock(&UE_info->mutex); + NR_SCHED_LOCK(&UE_info->mutex); int i; for(i=0; ilist[i] == NULL) { @@ -2380,10 +2380,10 @@ NR_UE_info_t *add_new_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rntiP, NR_CellGroupConf if (i == MAX_MOBILES_PER_GNB) { LOG_E(NR_MAC,"Try to add UE %04x but the list is full\n", rntiP); delete_nr_ue_data(UE, nr_mac->common_channels, &UE_info->uid_allocator); - pthread_mutex_unlock(&UE_info->mutex); + NR_SCHED_UNLOCK(&UE_info->mutex); return NULL; } - pthread_mutex_unlock(&UE_info->mutex); + NR_SCHED_UNLOCK(&UE_info->mutex); LOG_D(NR_MAC, "Add NR rnti %x\n", rntiP); dump_nr_list(UE_info->list); @@ -2487,8 +2487,11 @@ void reset_ul_harq_list(NR_UE_sched_ctrl_t *sched_ctrl) { void mac_remove_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rnti) { + /* already mutex protected */ + NR_SCHED_ENSURE_LOCKED(&nr_mac->sched_lock); + NR_UEs_t *UE_info = &nr_mac->UE_info; - pthread_mutex_lock(&UE_info->mutex); + NR_SCHED_LOCK(&UE_info->mutex); UE_iterator(UE_info->list, UE) { if (UE->rnti==rnti) break; @@ -2496,7 +2499,7 @@ void mac_remove_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rnti) if (!UE) { LOG_W(NR_MAC,"Call to del rnti %04x, but not existing\n", rnti); - pthread_mutex_unlock(&UE_info->mutex); + NR_SCHED_UNLOCK(&UE_info->mutex); return; } @@ -2506,7 +2509,7 @@ void mac_remove_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rnti) if(UE_info->list[i] && UE_info->list[i]->rnti != rnti) newUEs[newListIdx++]=UE_info->list[i]; memcpy(UE_info->list, newUEs, sizeof(UE_info->list)); - pthread_mutex_unlock(&UE_info->mutex); + NR_SCHED_UNLOCK(&UE_info->mutex); delete_nr_ue_data(UE, nr_mac->common_channels, &UE_info->uid_allocator); } @@ -2525,6 +2528,7 @@ uint8_t nr_get_tpc(int target, uint8_t cqi, int incr) { int get_pdsch_to_harq_feedback(NR_PUCCH_Config_t *pucch_Config, nr_dci_format_t dci_format, uint8_t *pdsch_to_harq_feedback) { + /* already mutex protected: held in nr_acknack_scheduling() */ if (dci_format == NR_DL_DCI_FORMAT_1_0) { for (int i = 0; i < 8; i++) @@ -2545,6 +2549,9 @@ void nr_csirs_scheduling(int Mod_idP, frame_t frame, sub_frame_t slot, int n_slo int CC_id = 0; NR_UEs_t *UE_info = &RC.nrmac[Mod_idP]->UE_info; gNB_MAC_INST *gNB_mac = RC.nrmac[Mod_idP]; + + NR_SCHED_ENSURE_LOCKED(&gNB_mac->sched_lock); + uint16_t *vrb_map = gNB_mac->common_channels[CC_id].vrb_map; UE_info->sched_csirs = false; @@ -2770,7 +2777,10 @@ void nr_csirs_scheduling(int Mod_idP, frame_t frame, sub_frame_t slot, int n_slo void nr_mac_update_timers(module_id_t module_id, frame_t frame, - sub_frame_t slot) { + sub_frame_t slot) +{ + /* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */ + NR_SCHED_ENSURE_LOCKED(&RC.nrmac[module_id]->sched_lock); NR_UEs_t *UE_info = &RC.nrmac[module_id]->UE_info; UE_iterator(UE_info->list, UE) { @@ -2824,7 +2834,10 @@ void nr_mac_update_timers(module_id_t module_id, void schedule_nr_bwp_switch(module_id_t module_id, frame_t frame, - sub_frame_t slot) { + sub_frame_t slot) +{ + /* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */ + NR_SCHED_ENSURE_LOCKED(&RC.nrmac[module_id]->sched_lock); NR_UEs_t *UE_info = &RC.nrmac[module_id]->UE_info; @@ -2887,6 +2900,7 @@ void send_initial_ul_rrc_message(gNB_MAC_INST *mac, int rnti, const uint8_t *sdu LOG_W(MAC, "[RAPROC] Received SDU for CCCH length %d for UE %04x\n", sdu_len, rnti); NR_UE_info_t *UE = (NR_UE_info_t *)rawUE; + NR_SCHED_ENSURE_LOCKED(&mac->sched_lock); uint8_t du2cu[1024]; int encoded = encode_cellGroupConfig(UE->CellGroup, du2cu, sizeof(du2cu)); @@ -2904,6 +2918,7 @@ void send_initial_ul_rrc_message(gNB_MAC_INST *mac, int rnti, const uint8_t *sdu void prepare_initial_ul_rrc_message(gNB_MAC_INST *mac, NR_UE_info_t *UE) { + NR_SCHED_ENSURE_LOCKED(&mac->sched_lock); /* create this UE's initial CellGroup */ /* Note: relying on the RRC is a hack, as we are in the DU; there should be * no RRC, remove in the future */ diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c index 8a85448c7f..3309e1af34 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c @@ -42,7 +42,8 @@ const uint16_t m_SRS[64] = { 4, 8, 12, 16, 16, 20, 24, 24, 28, 32, 36, 40, 48, 4 160, 160, 168, 176, 184, 192, 192, 192, 192, 208, 216, 224, 240, 240, 240, 240, 256, 256, 256, 264, 272, 272, 272 }; -uint32_t max4(uint32_t a, uint32_t b,uint32_t c,uint32_t d) { +static uint32_t max4(uint32_t a, uint32_t b, uint32_t c, uint32_t d) +{ int x = max(a, b); x = max(x, c); x = max(x, d); @@ -53,6 +54,9 @@ void nr_srs_ri_computation(const nfapi_nr_srs_normalized_channel_iq_matrix_t *nr const NR_UE_UL_BWP_t *current_BWP, uint8_t *ul_ri) { + /* already mutex protected: held in handle_nr_srs_measurements() */ + NR_SCHED_ENSURE_LOCKED(&RC.nrmac[0]->sched_lock); + // If the gNB or UE has 1 antenna, the rank is always 1, i.e., *ul_ri = 0. // For 2x2 scenario, we compute the rank of channel. // The computation for 2x4, 4x2, 4x4, ... scenarios are not implemented yet. In these cases, the function sets *ul_ri = 0, which is always a valid value. @@ -137,7 +141,14 @@ void nr_srs_ri_computation(const nfapi_nr_srs_normalized_channel_iq_matrix_t *nr } -void nr_configure_srs(nfapi_nr_srs_pdu_t *srs_pdu, int slot, int module_id, int CC_id, NR_UE_info_t *UE, NR_SRS_ResourceSet_t *srs_resource_set, NR_SRS_Resource_t *srs_resource, int buffer_index) +static void nr_configure_srs(nfapi_nr_srs_pdu_t *srs_pdu, + int slot, + int module_id, + int CC_id, + NR_UE_info_t *UE, + NR_SRS_ResourceSet_t *srs_resource_set, + NR_SRS_Resource_t *srs_resource, + int buffer_index) { NR_UE_UL_BWP_t *current_BWP = &UE->current_UL_BWP; @@ -196,7 +207,13 @@ void nr_configure_srs(nfapi_nr_srs_pdu_t *srs_pdu, int slot, int module_id, int vrb_map_UL[i + srs_pdu->bwp_start] |= mask; } -void nr_fill_nfapi_srs(int module_id, int CC_id, NR_UE_info_t* UE, int frame, int slot, NR_SRS_ResourceSet_t *srs_resource_set, NR_SRS_Resource_t *srs_resource) +static void nr_fill_nfapi_srs(int module_id, + int CC_id, + NR_UE_info_t *UE, + int frame, + int slot, + NR_SRS_ResourceSet_t *srs_resource_set, + NR_SRS_Resource_t *srs_resource) { int index = ul_buffer_index(frame, slot, UE->current_UL_BWP.scs, RC.nrmac[module_id]->UL_tti_req_ahead_size); @@ -226,8 +243,10 @@ void nr_fill_nfapi_srs(int module_id, int CC_id, NR_UE_info_t* UE, int frame, in *********************************************************************/ void nr_schedule_srs(int module_id, frame_t frame, int slot) { - + /* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */ gNB_MAC_INST *nrmac = RC.nrmac[module_id]; + NR_SCHED_ENSURE_LOCKED(&nrmac->sched_lock); + NR_UEs_t *UE_info = &nrmac->UE_info; UE_iterator(UE_info->list, UE) { diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index bc1796a6dc..e1716458d2 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -144,7 +144,7 @@ static const int diff_rsrp_ssb_csi_meas_10_1_6_1_2[16] = { -30 // 10 - 15 }; -int get_pucch_index(int frame, int slot, int n_slots_frame, const NR_TDD_UL_DL_Pattern_t *tdd, int sched_pucch_size) +static int get_pucch_index(int frame, int slot, int n_slots_frame, const NR_TDD_UL_DL_Pattern_t *tdd, int sched_pucch_size) { // PUCCH structures are indexed by slot in the PUCCH period determined by sched_pucch_size number of UL slots // this functions return the index to the structure for slot passed to the function @@ -167,6 +167,9 @@ void nr_schedule_pucch(gNB_MAC_INST *nrmac, frame_t frameP, sub_frame_t slotP) { + /* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */ + NR_SCHED_ENSURE_LOCKED(&nrmac->sched_lock); + if (!is_xlsch_in_slot(nrmac->ulsch_slot_bitmap[slotP / 64], slotP)) return; @@ -198,7 +201,10 @@ void nr_csi_meas_reporting(int Mod_idP, frame_t frame, sub_frame_t slot) { + /* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */ gNB_MAC_INST *nrmac = RC.nrmac[Mod_idP]; + NR_SCHED_ENSURE_LOCKED(&nrmac->sched_lock); + UE_iterator(nrmac->UE_info.list, UE ) { NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP; @@ -324,8 +330,8 @@ static void handle_dl_harq(NR_UE_info_t * UE, } } -int checkTargetSSBInFirst64TCIStates_pdschConfig(int ssb_index_t, NR_UE_info_t * UE) { - +static int checkTargetSSBInFirst64TCIStates_pdschConfig(int ssb_index_t, NR_UE_info_t *UE) +{ const NR_PDSCH_Config_t *pdsch_Config = UE->current_DL_BWP.pdsch_Config; int nb_tci_states = pdsch_Config ? pdsch_Config->tci_StatesToAddModList->list.count : 0; NR_TCI_State_t *tci =NULL; @@ -350,8 +356,8 @@ int checkTargetSSBInFirst64TCIStates_pdschConfig(int ssb_index_t, NR_UE_info_t * return -1; } -int checkTargetSSBInTCIStates_pdcchConfig(int ssb_index_t, NR_UE_info_t *UE) { - +static int checkTargetSSBInTCIStates_pdcchConfig(int ssb_index_t, NR_UE_info_t *UE) +{ NR_TCI_State_t *tci =NULL; NR_TCI_StateId_t *tci_id = NULL; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; @@ -390,7 +396,8 @@ int checkTargetSSBInTCIStates_pdcchConfig(int ssb_index_t, NR_UE_info_t *UE) { } //returns the measured RSRP value (upper limit) -int get_measured_rsrp(uint8_t index) { +static int get_measured_rsrp(uint8_t index) +{ //if index is invalid returning minimum rsrp -140 if(index <= 15 || index >= 114) return MIN_RSRP_VALUE; @@ -399,7 +406,7 @@ int get_measured_rsrp(uint8_t index) { } //returns the differential RSRP value (upper limit) -int get_diff_rsrp(uint8_t index, int strongest_rsrp) { +static int get_diff_rsrp(uint8_t index, int strongest_rsrp) { if(strongest_rsrp != -1) { return strongest_rsrp + diff_rsrp_ssb_csi_meas_10_1_6_1_2[index]; } else @@ -409,8 +416,8 @@ int get_diff_rsrp(uint8_t index, int strongest_rsrp) { //identifies the target SSB Beam index //keeps the required date for PDCCH and PDSCH TCI state activation/deactivation CE consutruction globally //handles triggering of PDCCH and PDSCH MAC CEs -void tci_handling(NR_UE_info_t *UE, frame_t frame, slot_t slot) { - +static void tci_handling(NR_UE_info_t *UE, frame_t frame, slot_t slot) +{ int strongest_ssb_rsrp = 0; int cqi_idx = 0; int curr_ssb_beam_index = 0; //ToDo: yet to know how to identify the serving ssb beam index @@ -583,24 +590,23 @@ void tci_handling(NR_UE_info_t *UE, frame_t frame, slot_t slot) { } }//tci_presentInDCI }//is-triggering_beam_switch -}//tci handling +} // tci handling - -uint8_t pickandreverse_bits(uint8_t *payload, uint16_t bitlen, uint8_t start_bit) { +static uint8_t pickandreverse_bits(uint8_t *payload, uint16_t bitlen, uint8_t start_bit) +{ uint8_t rev_bits = 0; for (int i=0; i>((start_bit+i)%8))&0x01)<<(bitlen-i-1); return rev_bits; } - -void evaluate_rsrp_report(NR_UE_info_t *UE, - NR_UE_sched_ctrl_t *sched_ctrl, - uint8_t csi_report_id, - uint8_t *payload, - int *cumul_bits, - NR_CSI_ReportConfig__reportQuantity_PR reportQuantity_type){ - +static void evaluate_rsrp_report(NR_UE_info_t *UE, + NR_UE_sched_ctrl_t *sched_ctrl, + uint8_t csi_report_id, + uint8_t *payload, + int *cumul_bits, + NR_CSI_ReportConfig__reportQuantity_PR reportQuantity_type) +{ nr_csi_report_t *csi_report = &UE->csi_report_template[csi_report_id]; uint8_t cri_ssbri_bitlen = csi_report->CSI_report_bitlen.cri_ssbri_bitlen; uint16_t curr_payload; @@ -659,21 +665,18 @@ void evaluate_rsrp_report(NR_UE_info_t *UE, stats->num_rsrp_meas++; } -void evaluate_cri_report(uint8_t *payload, - uint8_t cri_bitlen, - int cumul_bits, - NR_UE_sched_ctrl_t *sched_ctrl){ - +static void evaluate_cri_report(uint8_t *payload, uint8_t cri_bitlen, int cumul_bits, NR_UE_sched_ctrl_t *sched_ctrl) +{ uint8_t temp_cri = pickandreverse_bits(payload, cri_bitlen, cumul_bits); sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.cri = temp_cri; } -int evaluate_ri_report(uint8_t *payload, - uint8_t ri_bitlen, - uint8_t ri_restriction, - int cumul_bits, - NR_UE_sched_ctrl_t *sched_ctrl){ - +static int evaluate_ri_report(uint8_t *payload, + uint8_t ri_bitlen, + uint8_t ri_restriction, + int cumul_bits, + NR_UE_sched_ctrl_t *sched_ctrl) +{ uint8_t ri_index = pickandreverse_bits(payload, ri_bitlen, cumul_bits); int count=0; for (int i=0; i<8; i++) { @@ -689,13 +692,12 @@ int evaluate_ri_report(uint8_t *payload, AssertFatal(1==0, "Decoded ri %d does not correspond to any valid value in ri_restriction %d\n",ri_index,ri_restriction); } - -void evaluate_cqi_report(uint8_t *payload, - nr_csi_report_t *csi_report, - int cumul_bits, - uint8_t ri, - NR_UE_info_t *UE, - uint8_t cqi_Table) +static void evaluate_cqi_report(uint8_t *payload, + nr_csi_report_t *csi_report, + int cumul_bits, + uint8_t ri, + NR_UE_info_t *UE, + uint8_t cqi_Table) { NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; @@ -723,13 +725,12 @@ void evaluate_cqi_report(uint8_t *payload, sched_ctrl->dl_max_mcs = get_mcs_from_cqi(mcs_table, cqi_Table, cqi_idx); } - -uint8_t evaluate_pmi_report(uint8_t *payload, - nr_csi_report_t *csi_report, - int cumul_bits, - uint8_t ri, - NR_UE_sched_ctrl_t *sched_ctrl){ - +static uint8_t evaluate_pmi_report(uint8_t *payload, + nr_csi_report_t *csi_report, + int cumul_bits, + uint8_t ri, + NR_UE_sched_ctrl_t *sched_ctrl) +{ int x1_bitlen = csi_report->csi_meas_bitlen.pmi_x1_bitlen[ri]; int x2_bitlen = csi_report->csi_meas_bitlen.pmi_x2_bitlen[ri]; int tot_bitlen = x1_bitlen + x2_bitlen; @@ -744,16 +745,14 @@ uint8_t evaluate_pmi_report(uint8_t *payload, sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.pmi_x2); return tot_bitlen; - } - -int evaluate_li_report(uint8_t *payload, - nr_csi_report_t *csi_report, - int cumul_bits, - uint8_t ri, - NR_UE_sched_ctrl_t *sched_ctrl){ - +static int evaluate_li_report(uint8_t *payload, + nr_csi_report_t *csi_report, + int cumul_bits, + uint8_t ri, + NR_UE_sched_ctrl_t *sched_ctrl) +{ int li_bitlen = csi_report->csi_meas_bitlen.li_bitlen[ri]; if (li_bitlen>0) { @@ -762,14 +761,10 @@ int evaluate_li_report(uint8_t *payload, sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.li = temp_li; } return li_bitlen; - } -void skip_zero_padding(int *cumul_bits, - nr_csi_report_t *csi_report, - uint8_t ri, - uint16_t max_bitlen) { - +static void skip_zero_padding(int *cumul_bits, nr_csi_report_t *csi_report, uint8_t ri, uint16_t max_bitlen) +{ // actual number of reported bits depends on the reported rank // zero padding bits are added to have a predetermined max bit length to decode @@ -783,13 +778,12 @@ void skip_zero_padding(int *cumul_bits, *cumul_bits+=(max_bitlen-reported_bitlen); } - -void extract_pucch_csi_report(NR_CSI_MeasConfig_t *csi_MeasConfig, - const nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_pdu, - frame_t frame, - slot_t slot, - NR_UE_info_t *UE, - NR_ServingCellConfigCommon_t *scc) +static void extract_pucch_csi_report(NR_CSI_MeasConfig_t *csi_MeasConfig, + const nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_pdu, + frame_t frame, + slot_t slot, + NR_UE_info_t *UE, + NR_ServingCellConfigCommon_t *scc) { /** From Table 6.3.1.1.2-3: RI, LI, CQI, and CRI of codebookType=typeI-SinglePanel */ uint8_t *payload = uci_pdu->csi_part1.csi_part1_payload; @@ -929,9 +923,12 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id, sub_frame_t slot, const nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_01) { - NR_UE_info_t * UE = find_nr_UE(&RC.nrmac[mod_id]->UE_info, uci_01->rnti); + gNB_MAC_INST *nrmac = RC.nrmac[mod_id]; + NR_SCHED_LOCK(&nrmac->sched_lock); + NR_UE_info_t * UE = find_nr_UE(&nrmac->UE_info, uci_01->rnti); if (!UE) { LOG_E(NR_MAC, "%s(): unknown RNTI %04x in PUCCH UCI\n", __func__, uci_01->rnti); + NR_SCHED_UNLOCK(&nrmac->sched_lock); return; } NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; @@ -941,7 +938,7 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id, for (int harq_bit = 0; harq_bit < uci_01->harq->num_harq; harq_bit++) { const uint8_t harq_value = uci_01->harq->harq_list[harq_bit].harq_value; const uint8_t harq_confidence = uci_01->harq->harq_confidence_level; - NR_UE_harq_t *harq = find_harq(frame, slot, UE, RC.nrmac[mod_id]->dl_bler.harq_round_max); + NR_UE_harq_t *harq = find_harq(frame, slot, UE, nrmac->dl_bler.harq_round_max); if (!harq) { LOG_E(NR_MAC, "Oh no! Could not find a harq in %s!\n", __FUNCTION__); break; @@ -950,13 +947,13 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id, const int8_t pid = sched_ctrl->feedback_dl_harq.head; remove_front_nr_list(&sched_ctrl->feedback_dl_harq); LOG_D(NR_MAC,"%4d.%2d bit %d pid %d ack/nack %d\n",frame, slot, harq_bit,pid,harq_value); - handle_dl_harq(UE, pid, harq_value == 0 && harq_confidence == 0, RC.nrmac[mod_id]->dl_bler.harq_round_max); + handle_dl_harq(UE, pid, harq_value == 0 && harq_confidence == 0, nrmac->dl_bler.harq_round_max); if (harq_confidence == 1) UE->mac_stats.pucch0_DTX++; } // tpc (power control) only if we received AckNack if (uci_01->harq->harq_confidence_level==0) - sched_ctrl->tpc1 = nr_get_tpc(RC.nrmac[mod_id]->pucch_target_snrx10, uci_01->ul_cqi, 30); + sched_ctrl->tpc1 = nr_get_tpc(nrmac->pucch_target_snrx10, uci_01->ul_cqi, 30); else sched_ctrl->tpc1 = 3; sched_ctrl->pucch_snrx10 = uci_01->ul_cqi * 5 - 640; @@ -974,6 +971,7 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id, } free(uci_01->sr); } + NR_SCHED_UNLOCK(&nrmac->sched_lock); } void handle_nr_uci_pucch_2_3_4(module_id_t mod_id, @@ -981,15 +979,21 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id, sub_frame_t slot, const nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_234) { - NR_UE_info_t * UE = find_nr_UE(&RC.nrmac[mod_id]->UE_info, uci_234->rnti); + gNB_MAC_INST *nrmac = RC.nrmac[mod_id]; + NR_SCHED_LOCK(&nrmac->sched_lock); + + NR_UE_info_t * UE = find_nr_UE(&nrmac->UE_info, uci_234->rnti); if (!UE) { + NR_SCHED_UNLOCK(&nrmac->sched_lock); LOG_E(NR_MAC, "%s(): unknown RNTI %04x in PUCCH UCI\n", __func__, uci_234->rnti); return; } NR_CSI_MeasConfig_t *csi_MeasConfig = UE->current_UL_BWP.csi_MeasConfig; - if (csi_MeasConfig==NULL) + if (csi_MeasConfig==NULL) { + NR_SCHED_UNLOCK(&nrmac->sched_lock); return; + } NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; // tpc (power control) @@ -1014,13 +1018,13 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id, DevAssert(harq->is_waiting); const int8_t pid = sched_ctrl->feedback_dl_harq.head; remove_front_nr_list(&sched_ctrl->feedback_dl_harq); - handle_dl_harq(UE, pid, uci_234->harq.harq_crc != 1 && acknack, RC.nrmac[mod_id]->dl_bler.harq_round_max); + handle_dl_harq(UE, pid, uci_234->harq.harq_crc != 1 && acknack, nrmac->dl_bler.harq_round_max); } free(uci_234->harq.harq_payload); } if ((uci_234->pduBitmap >> 2) & 0x01) { //API to parse the csi report and store it into sched_ctrl - extract_pucch_csi_report(csi_MeasConfig, uci_234, frame, slot, UE, RC.nrmac[mod_id]->common_channels->ServingCellConfigCommon); + extract_pucch_csi_report(csi_MeasConfig, uci_234, frame, slot, UE, nrmac->common_channels->ServingCellConfigCommon); //TCI handling function tci_handling(UE,frame, slot); free(uci_234->csi_part1.csi_part1_payload); @@ -1029,9 +1033,10 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id, //@TODO:Handle CSI Report 2 // nothing to free (yet) } + NR_SCHED_UNLOCK(&nrmac->sched_lock); } -void set_pucch_allocation(const NR_UE_UL_BWP_t *ul_bwp, const int r_pucch, const int bwp_size, NR_sched_pucch_t *pucch) +static void set_pucch_allocation(const NR_UE_UL_BWP_t *ul_bwp, const int r_pucch, const int bwp_size, NR_sched_pucch_t *pucch) { if(r_pucch<0){ const NR_PUCCH_Resource_t *resource = ul_bwp->pucch_Config->resourceToAddModList->list.array[0]; @@ -1053,11 +1058,8 @@ void set_pucch_allocation(const NR_UE_UL_BWP_t *ul_bwp, const int r_pucch, const } } -bool test_pucch0_vrb_occupation(const NR_sched_pucch_t *pucch, - uint16_t *vrb_map_UL, - const int bwp_start, - const int bwp_size) { - +static bool test_pucch0_vrb_occupation(const NR_sched_pucch_t *pucch, uint16_t *vrb_map_UL, const int bwp_start, const int bwp_size) +{ // We assume initial cyclic shift is always 0 so different pucch resources can't overlap // verifying occupation of PRBs for ACK/NACK on dedicated pucch @@ -1076,9 +1078,7 @@ bool test_pucch0_vrb_occupation(const NR_sched_pucch_t *pucch, return true; } -void set_pucch0_vrb_occupation(const NR_sched_pucch_t *pucch, - uint16_t *vrb_map_UL, - const int bwp_start) +static void set_pucch0_vrb_occupation(const NR_sched_pucch_t *pucch, uint16_t *vrb_map_UL, const int bwp_start) { for (int l=0; lnr_of_symb; l++) { uint16_t symb = SL_to_bitmap(pucch->start_symb+l, 1); @@ -1100,6 +1100,8 @@ int nr_acknack_scheduling(gNB_MAC_INST *mac, int r_pucch, int is_common) { + /* we assume that this function is mutex-protected from outside. Since it is + * called often, don't try to lock every time */ const int CC_id = 0; const int minfbtime = mac->minRXTXTIMEpdsch; @@ -1204,6 +1206,9 @@ int nr_acknack_scheduling(gNB_MAC_INST *mac, void nr_sr_reporting(gNB_MAC_INST *nrmac, frame_t SFN, sub_frame_t slot) { + /* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */ + NR_SCHED_ENSURE_LOCKED(&nrmac->sched_lock); + if (!is_xlsch_in_slot(nrmac->ulsch_slot_bitmap[slot / 64], slot)) return; const int CC_id = 0; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index e1a4e716ef..80c1652b61 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -39,7 +39,10 @@ //#define SRS_IND_DEBUG -const int get_ul_tda(gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon_t *scc, int frame, int slot) { +const int get_ul_tda(gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon_t *scc, int frame, int slot) +{ + /* we assume that this function is mutex-protected from outside */ + NR_SCHED_ENSURE_LOCKED(&nrmac->sched_lock); /* there is a mixed slot only when in TDD */ const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL; @@ -61,14 +64,8 @@ const int get_ul_tda(gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon_t *sc return 0; // if FDD or not mixed slot in TDD, for now use default TDA (TODO handle CSI-RS slots) } -int compute_ph_factor(int mu, - int tbs_bits, - int rb, - int n_layers, - int n_symbols, - int n_dmrs, - long *deltaMCS) { - +static int compute_ph_factor(int mu, int tbs_bits, int rb, int n_layers, int n_symbols, int n_dmrs, long *deltaMCS) +{ // 38.213 7.1.1 // if the PUSCH transmission is over more than one layer delta_tf = 0 int delta_tf = 0; @@ -109,14 +106,14 @@ int compute_ph_factor(int mu, // F: length of L is 0:8 or 1:16 bits wide // R: Reserved bit, set to zero. -int nr_process_mac_pdu(instance_t module_idP, - NR_UE_info_t* UE, - uint8_t CC_id, - frame_t frameP, - sub_frame_t slot, - uint8_t *pduP, - int pdu_len, - const int8_t harq_pid) +static int nr_process_mac_pdu(instance_t module_idP, + NR_UE_info_t *UE, + uint8_t CC_id, + frame_t frameP, + sub_frame_t slot, + uint8_t *pduP, + int pdu_len, + const int8_t harq_pid) { uint8_t done = 0; @@ -462,7 +459,7 @@ int nr_process_mac_pdu(instance_t module_idP, return 0; } -void abort_nr_ul_harq(NR_UE_info_t *UE, int8_t harq_pid) +static void abort_nr_ul_harq(NR_UE_info_t *UE, int8_t harq_pid) { NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; NR_UE_ul_harq_t *harq = &sched_ctrl->ul_harq_processes[harq_pid]; @@ -479,7 +476,7 @@ void abort_nr_ul_harq(NR_UE_info_t *UE, int8_t harq_pid) sched_ctrl->sched_ul_bytes = 0; } -bool get_UE_waiting_CFRA_msg3(const gNB_MAC_INST *gNB_mac, const int CC_id, const frame_t frame, const sub_frame_t slot) +static bool get_UE_waiting_CFRA_msg3(const gNB_MAC_INST *gNB_mac, const int CC_id, const frame_t frame, const sub_frame_t slot) { bool UE_waiting_CFRA_msg3 = false; for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) { @@ -498,17 +495,22 @@ void handle_nr_ul_harq(const int CC_idP, sub_frame_t slot, const nfapi_nr_crc_t *crc_pdu) { - NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[mod_id]->UE_info, crc_pdu->rnti); - bool UE_waiting_CFRA_msg3 = get_UE_waiting_CFRA_msg3(RC.nrmac[mod_id], CC_idP, frame, slot); + gNB_MAC_INST *nrmac = RC.nrmac[mod_id]; + NR_SCHED_LOCK(&nrmac->sched_lock); + + NR_UE_info_t *UE = find_nr_UE(&nrmac->UE_info, crc_pdu->rnti); + bool UE_waiting_CFRA_msg3 = get_UE_waiting_CFRA_msg3(nrmac, CC_idP, frame, slot); if (!UE || UE_waiting_CFRA_msg3 == true) { LOG_W(NR_MAC, "handle harq for rnti %04x, in RA process\n", crc_pdu->rnti); for (int i = 0; i < NR_NB_RA_PROC_MAX; ++i) { - NR_RA_t *ra = &RC.nrmac[mod_id]->common_channels[CC_idP].ra[i]; - if (ra->state >= WAIT_Msg3 && - ra->rnti == crc_pdu->rnti) + NR_RA_t *ra = &nrmac->common_channels[CC_idP].ra[i]; + if (ra->state >= WAIT_Msg3 && ra->rnti == crc_pdu->rnti) { + NR_SCHED_UNLOCK(&nrmac->sched_lock); return; + } } + NR_SCHED_UNLOCK(&nrmac->sched_lock); LOG_E(NR_MAC, "%s(): unknown RNTI 0x%04x in PUSCH\n", __func__, crc_pdu->rnti); return; } @@ -521,8 +523,10 @@ void handle_nr_ul_harq(const int CC_idP, crc_pdu->harq_id, harq_pid, crc_pdu->rnti); - if (harq_pid < 0) + if (harq_pid < 0) { + NR_SCHED_UNLOCK(&nrmac->sched_lock); return; + } remove_front_nr_list(&sched_ctrl->feedback_ul_harq); sched_ctrl->ul_harq_processes[harq_pid].is_waiting = false; @@ -562,22 +566,23 @@ void handle_nr_ul_harq(const int CC_idP, crc_pdu->rnti); add_tail_nr_list(&sched_ctrl->retrans_ul_harq, harq_pid); } + NR_SCHED_UNLOCK(&nrmac->sched_lock); } /* * When data are received on PHY and transmitted to MAC */ -void nr_rx_sdu(const module_id_t gnb_mod_idP, - const int CC_idP, - const frame_t frameP, - const sub_frame_t slotP, - const rnti_t rntiP, - uint8_t *sduP, - const uint16_t sdu_lenP, - const uint16_t timing_advance, - const uint8_t ul_cqi, - const uint16_t rssi){ - +static void _nr_rx_sdu(const module_id_t gnb_mod_idP, + const int CC_idP, + const frame_t frameP, + const sub_frame_t slotP, + const rnti_t rntiP, + uint8_t *sduP, + const uint16_t sdu_lenP, + const uint16_t timing_advance, + const uint8_t ul_cqi, + const uint16_t rssi) +{ gNB_MAC_INST *gNB_mac = RC.nrmac[gnb_mod_idP]; const int current_rnti = rntiP; @@ -841,8 +846,25 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, } } -uint32_t calc_power_complex(const int16_t *x, const int16_t *y, const uint32_t size) { +void nr_rx_sdu(const module_id_t gnb_mod_idP, + const int CC_idP, + const frame_t frameP, + const sub_frame_t slotP, + const rnti_t rntiP, + uint8_t *sduP, + const uint16_t sdu_lenP, + const uint16_t timing_advance, + const uint8_t ul_cqi, + const uint16_t rssi) +{ + gNB_MAC_INST *gNB_mac = RC.nrmac[gnb_mod_idP]; + NR_SCHED_LOCK(&gNB_mac->sched_lock); + _nr_rx_sdu(gnb_mod_idP, CC_idP, frameP, slotP, rntiP, sduP, sdu_lenP, timing_advance, ul_cqi, rssi); + NR_SCHED_UNLOCK(&gNB_mac->sched_lock); +} +static uint32_t calc_power_complex(const int16_t *x, const int16_t *y, const uint32_t size) +{ // Real part value int64_t sum_x = 0; int64_t sum_x2 = 0; @@ -864,7 +886,8 @@ uint32_t calc_power_complex(const int16_t *x, const int16_t *y, const uint32_t s return power_re+power_im; } -c16_t nr_h_times_w(c16_t h, char w) { +static c16_t nr_h_times_w(c16_t h, char w) +{ c16_t output; switch (w) { case '0': // 0 @@ -893,11 +916,11 @@ c16_t nr_h_times_w(c16_t h, char w) { return output; } -uint8_t get_max_tpmi(const NR_PUSCH_Config_t *pusch_Config, - const uint16_t num_ue_srs_ports, - const uint8_t *nrOfLayers, - int *additional_max_tpmi) { - +static uint8_t get_max_tpmi(const NR_PUSCH_Config_t *pusch_Config, + const uint16_t num_ue_srs_ports, + const uint8_t *nrOfLayers, + int *additional_max_tpmi) +{ uint8_t max_tpmi = 0; if ((pusch_Config && pusch_Config->txConfig != NULL && *pusch_Config->txConfig == NR_PUSCH_Config__txConfig_nonCodebook) || @@ -1056,13 +1079,13 @@ uint8_t get_max_tpmi(const NR_PUSCH_Config_t *pusch_Config, return max_tpmi; } -void get_precoder_matrix_coef(char *w, - const uint8_t ul_ri, - const uint16_t num_ue_srs_ports, - const long transform_precoding, - const uint8_t tpmi, - const uint8_t uI, - int layer_idx) +static void get_precoder_matrix_coef(char *w, + const uint8_t ul_ri, + const uint16_t num_ue_srs_ports, + const long transform_precoding, + const uint8_t tpmi, + const uint8_t uI, + int layer_idx) { if (ul_ri == 0) { if (num_ue_srs_ports == 2) { @@ -1085,15 +1108,16 @@ void get_precoder_matrix_coef(char *w, } } -int nr_srs_tpmi_estimation(const NR_PUSCH_Config_t *pusch_Config, - const long transform_precoding, - const uint8_t *channel_matrix, - const uint8_t normalized_iq_representation, - const uint16_t num_gnb_antenna_elements, - const uint16_t num_ue_srs_ports, - const uint16_t prg_size, - const uint16_t num_prgs, - const uint8_t ul_ri) { +static int nr_srs_tpmi_estimation(const NR_PUSCH_Config_t *pusch_Config, + const long transform_precoding, + const uint8_t *channel_matrix, + const uint8_t normalized_iq_representation, + const uint16_t num_gnb_antenna_elements, + const uint16_t num_ue_srs_ports, + const uint16_t prg_size, + const uint16_t num_prgs, + const uint8_t ul_ri) +{ if (ul_ri > 1) { LOG_D(NR_MAC, "TPMI computation for ul_ri %i is not implemented yet!\n", ul_ri); return 0; @@ -1173,6 +1197,8 @@ void handle_nr_srs_measurements(const module_id_t module_id, const sub_frame_t slot, nfapi_nr_srs_indication_pdu_t *srs_ind) { + gNB_MAC_INST *nrmac = RC.nrmac[module_id]; + NR_SCHED_LOCK(&nrmac->sched_lock); LOG_D(NR_MAC, "(%d.%d) Received SRS indication for UE %04x\n", frame, slot, srs_ind->rnti); #ifdef SRS_IND_DEBUG @@ -1188,11 +1214,13 @@ void handle_nr_srs_measurements(const module_id_t module_id, NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[module_id]->UE_info, srs_ind->rnti); if (!UE) { LOG_W(NR_MAC, "Could not find UE for RNTI %04x\n", srs_ind->rnti); + NR_SCHED_UNLOCK(&nrmac->sched_lock); return; } if (srs_ind->timing_advance_offset == 0xFFFF) { LOG_W(NR_MAC, "Invalid timing advance offset for RNTI %04x\n", srs_ind->rnti); + NR_SCHED_UNLOCK(&nrmac->sched_lock); return; } @@ -1210,6 +1238,7 @@ void handle_nr_srs_measurements(const module_id_t module_id, if (nr_srs_bf_report.wide_band_snr == 0xFF) { LOG_W(NR_MAC, "Invalid wide_band_snr for RNTI %04x\n", srs_ind->rnti); + NR_SCHED_UNLOCK(&nrmac->sched_lock); return; } @@ -1308,12 +1337,14 @@ void handle_nr_srs_measurements(const module_id_t module_id, default: AssertFatal(1 == 0, "Invalid SRS usage\n"); } + NR_SCHED_UNLOCK(&nrmac->sched_lock); } long get_K2(NR_PUSCH_TimeDomainResourceAllocationList_t *tdaList, int time_domain_assignment, int mu) { + /* we assume that this function is mutex-protected from outside */ NR_PUSCH_TimeDomainResourceAllocation_t *tda = tdaList->list.array[time_domain_assignment]; if (tda->k2) @@ -1363,7 +1394,7 @@ static bool nr_UE_is_to_be_scheduled(const NR_ServingCellConfigCommon_t *scc, in return has_data || sched_ctrl->SR || high_inactivity; } -void update_ul_ue_R_Qm(int mcs, int mcs_table, const NR_PUSCH_Config_t *pusch_Config, uint16_t *R, uint8_t *Qm) +static void update_ul_ue_R_Qm(int mcs, int mcs_table, const NR_PUSCH_Config_t *pusch_Config, uint16_t *R, uint8_t *Qm) { *R = nr_get_code_rate_ul(mcs, mcs_table); *Qm = nr_get_Qm_ul(mcs, mcs_table); @@ -1374,7 +1405,14 @@ void update_ul_ue_R_Qm(int mcs, int mcs_table, const NR_PUSCH_Config_t *pusch_Co } } -void nr_ue_max_mcs_min_rb(int mu, int ph_limit, NR_sched_pusch_t *sched_pusch, NR_UE_UL_BWP_t *ul_bwp, uint16_t minRb, uint32_t tbs, uint16_t *Rb, uint8_t *mcs) +static void nr_ue_max_mcs_min_rb(int mu, + int ph_limit, + NR_sched_pusch_t *sched_pusch, + NR_UE_UL_BWP_t *ul_bwp, + uint16_t minRb, + uint32_t tbs, + uint16_t *Rb, + uint8_t *mcs) { AssertFatal(*Rb >= minRb, "illegal Rb %d < minRb %d\n", *Rb, minRb); AssertFatal(*mcs >= 0 && *mcs <= 28, "illegal MCS %d\n", *mcs); @@ -1577,13 +1615,13 @@ static int comparator(const void *p, const void *q) { return ((UEsched_t*)p)->coef < ((UEsched_t*)q)->coef; } -void pf_ul(module_id_t module_id, - frame_t frame, - sub_frame_t slot, - NR_UE_info_t *UE_list[], - int max_num_ue, - int n_rb_sched, - uint16_t *rballoc_mask) +static void pf_ul(module_id_t module_id, + frame_t frame, + sub_frame_t slot, + NR_UE_info_t *UE_list[], + int max_num_ue, + int n_rb_sched, + uint16_t *rballoc_mask) { const int CC_id = 0; @@ -1870,7 +1908,7 @@ void pf_ul(module_id_t module_id, } } -bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t slot) +static bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t slot) { gNB_MAC_INST *nr_mac = RC.nrmac[module_id]; NR_COMMON_channels_t *cc = nr_mac->common_channels; @@ -1971,6 +2009,7 @@ bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t nr_pp_impl_ul nr_init_fr1_ulsch_preprocessor(int CC_id) { + /* during initialization: no mutex needed */ /* in the PF algorithm, we have to use the TBsize to compute the coefficient. * This would include the number of DMRS symbols, which in turn depends on * the time domain allocation. In case we are in a mixed slot, we do not want @@ -2002,6 +2041,9 @@ nr_pp_impl_ul nr_init_fr1_ulsch_preprocessor(int CC_id) void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot, nfapi_nr_ul_dci_request_t *ul_dci_req) { gNB_MAC_INST *nr_mac = RC.nrmac[module_id]; + /* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */ + NR_SCHED_ENSURE_LOCKED(&nr_mac->sched_lock); + /* Uplink data ONLY can be scheduled when the current slot is downlink slot, * because we have to schedule the DCI0 first before schedule uplink data */ if (!is_xlsch_in_slot(nr_mac->dlsch_slot_bitmap[slot / 64], slot)) { diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index a700c5c652..c2cbe8799d 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -40,8 +40,6 @@ void set_cset_offset(uint16_t); void mac_top_init_gNB(ngran_node_t node_type); -void config_common(gNB_MAC_INST *nrmac, int pdsch_AntennaPorts, int pusch_AntennaPorts, NR_ServingCellConfigCommon_t *scc); - int nr_mac_enable_ue_rrc_processing_timer(module_id_t Mod_idP, rnti_t rnti, NR_SubcarrierSpacing_t subcarrierSpacing, @@ -58,7 +56,6 @@ void nr_mac_config_sib1(gNB_MAC_INST *nrmac, NR_BCCH_DL_SCH_Message_t *sib1); bool nr_mac_add_test_ue(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig_t *CellGroup); bool nr_mac_prepare_ra_nsa_ue(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig_t *CellGroup); bool nr_mac_update_cellgroup(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig_t *CellGroup); -bool nr_mac_update_RA(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig_t *CellGroup); void clear_nr_nfapi_information(gNB_MAC_INST *gNB, int CC_idP, @@ -87,15 +84,6 @@ void nr_schedule_ue_spec(module_id_t module_id, nfapi_nr_dl_tti_request_t *DL_req, nfapi_nr_tx_data_request_t *TX_req); -uint32_t schedule_control_sib1(module_id_t module_id, - int CC_id, - NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config, - int time_domain_allocation, - NR_pdsch_dmrs_t *dmrs_parms, - NR_tda_info_t *tda_info, - uint8_t candidate_idx, - uint16_t num_total_bytes); - /* \brief default FR1 DL preprocessor init routine, returns preprocessor to call */ nr_pp_impl_dl nr_init_fr1_dlsch_preprocessor(int CC_id); @@ -139,41 +127,6 @@ void nr_clear_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP, NR_RA_t int nr_allocate_CCEs(int module_idP, int CC_idP, frame_t frameP, sub_frame_t slotP, int test_only); -void nr_get_Msg3alloc(module_id_t module_id, - int CC_id, - NR_ServingCellConfigCommon_t *scc, - sub_frame_t current_subframe, - frame_t current_frame, - NR_RA_t *ra, - int16_t *tdd_beam_association); - -void nr_generate_Msg3_retransmission(module_id_t module_idP, - int CC_id, - frame_t frameP, - sub_frame_t slotP, - NR_RA_t *ra, - nfapi_nr_ul_dci_request_t *ul_dci_req); - -/* \brief Function in gNB to fill RAR pdu when requested by PHY. -@param ra Instance of RA resources of gNB -@param dlsch_buffer Pointer to RAR input buffer -@param N_RB_UL Number of UL resource blocks -*/ -void nr_fill_rar(uint8_t Mod_idP, - NR_RA_t * ra, - uint8_t * dlsch_buffer, - nfapi_nr_pusch_pdu_t *pusch_pdu); - -void fill_msg3_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu, - NR_ServingCellConfigCommon_t *scc, - int round, - int startSymbolAndLength, - rnti_t rnti, int scs, - int bwp_size, int bwp_start, - int mappingtype, int fh, - int msg3_first_rb, int msg3_nb_rb); - - void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP); uint16_t nr_mac_compute_RIV(uint16_t N_RB_DL, uint16_t RBstart, uint16_t Lcrbs); @@ -380,39 +333,10 @@ int nr_write_ce_dlsch_pdu(module_id_t module_idP, unsigned char drx_cmd, unsigned char *ue_cont_res_id); -void nr_generate_Msg2(module_id_t module_idP, - int CC_id, - frame_t frameP, - sub_frame_t slotP, - NR_RA_t *ra, - nfapi_nr_dl_tti_request_t *dl_req, - nfapi_nr_tx_data_request_t *TX_req); - -void nr_generate_Msg4(module_id_t module_idP, - int CC_id, - frame_t frameP, - sub_frame_t slotP, - NR_RA_t *ra, - nfapi_nr_dl_tti_request_t *DL_req, - nfapi_nr_tx_data_request_t *TX_req); - -void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, sub_frame_t slot, NR_RA_t *ra); - -void nr_generate_Msg3_dcch_dtch_response(module_id_t module_idP, - int CC_id, - frame_t frameP, - sub_frame_t slotP, - NR_RA_t *ra, - nfapi_nr_dl_tti_request_t *DL_req, - nfapi_nr_tx_data_request_t *TX_req); - int binomial(int n, int k); bool is_xlsch_in_slot(uint64_t bitmap, sub_frame_t slot); -void fill_ssb_vrb_map (NR_COMMON_channels_t *cc, int rbStart, int ssb_subcarrier_offset, uint16_t symStart, int CC_id); - - /* \brief Function to indicate a received SDU on ULSCH. @param Mod_id Instance ID of gNB @param CC_id Component carrier index @@ -451,13 +375,6 @@ void handle_nr_srs_measurements(const module_id_t module_id, const sub_frame_t slot, nfapi_nr_srs_indication_pdu_t *srs_ind); -int16_t ssb_index_from_prach(module_id_t module_idP, - frame_t frameP, - sub_frame_t slotP, - uint16_t preamble_index, - uint8_t freq_index, - uint8_t symbol); - void find_SSB_and_RO_available(gNB_MAC_INST *nrmac); NR_pdsch_dmrs_t get_dl_dmrs_params(const NR_ServingCellConfigCommon_t *scc, diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c index 0a47699591..4fdad6fb81 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -22,12 +22,130 @@ #include "mac_rrc_dl_handler.h" #include "mac_proto.h" -#include "openair2/RRC/NR/rrc_gNB_UE_context.h" #include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h" +#include "openair2/RRC/NR/MESSAGES/asn1_msg.h" -#include "NR_RRCSetup.h" -#include "NR_DL-CCCH-Message.h" -#include "NR_CellGroupConfig.h" +static NR_RLC_BearerConfig_t *get_bearerconfig_from_srb(const f1ap_srb_to_be_setup_t *srb) +{ + long priority = srb->srb_id; // high priority for SRB + e_NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration bucket = + NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms5; + return get_SRB_RLC_BearerConfig(srb->srb_id, priority, bucket); +} + +static void handle_ue_context_srbs_setup(const f1ap_ue_context_setup_t *req, + f1ap_ue_context_setup_t *resp, + NR_CellGroupConfig_t *cellGroupConfig) +{ + DevAssert(req != NULL && resp != NULL && cellGroupConfig != NULL); + + resp->srbs_to_be_setup_length = req->srbs_to_be_setup_length; + resp->srbs_to_be_setup = calloc(req->srbs_to_be_setup_length, sizeof(*resp->srbs_to_be_setup)); + AssertFatal(resp->srbs_to_be_setup != NULL, "out of memory\n"); + for (int i = 0; i < req->srbs_to_be_setup_length; i++) { + f1ap_srb_to_be_setup_t *srb = &req->srbs_to_be_setup[i]; + NR_RLC_BearerConfig_t *rlc_BearerConfig = get_bearerconfig_from_srb(srb); + nr_rlc_add_srb(req->rnti, srb->srb_id, rlc_BearerConfig); + + resp->srbs_to_be_setup[i] = *srb; + + int ret = ASN_SEQUENCE_ADD(&cellGroupConfig->rlc_BearerToAddModList->list, rlc_BearerConfig); + DevAssert(ret == 0); + } +} + +static NR_RLC_BearerConfig_t *get_bearerconfig_from_drb(const f1ap_drb_to_be_setup_t *drb) +{ + const NR_RLC_Config_PR rlc_conf = drb->rlc_mode == RLC_MODE_UM ? NR_RLC_Config_PR_um_Bi_Directional : NR_RLC_Config_PR_am; + long priority = 13; // hardcoded for the moment + return get_DRB_RLC_BearerConfig(3 + drb->drb_id, drb->drb_id, rlc_conf, priority); +} + +static void handle_ue_context_drbs_setup(const f1ap_ue_context_setup_t *req, + f1ap_ue_context_setup_t *resp, + NR_CellGroupConfig_t *cellGroupConfig) +{ + DevAssert(req != NULL && resp != NULL && cellGroupConfig != NULL); + + /* Note: the actual GTP tunnels are created in the F1AP breanch of + * ue_context_*_response() */ + resp->drbs_to_be_setup_length = req->drbs_to_be_setup_length; + resp->drbs_to_be_setup = calloc(req->drbs_to_be_setup_length, sizeof(*resp->drbs_to_be_setup)); + AssertFatal(resp->drbs_to_be_setup != NULL, "out of memory\n"); + for (int i = 0; i < req->drbs_to_be_setup_length; i++) { + f1ap_drb_to_be_setup_t *drb = &req->drbs_to_be_setup[i]; + NR_RLC_BearerConfig_t *rlc_BearerConfig = get_bearerconfig_from_drb(drb); + nr_rlc_add_drb(req->rnti, drb->drb_id, rlc_BearerConfig); + + resp->drbs_to_be_setup[i] = *drb; + + int ret = ASN_SEQUENCE_ADD(&cellGroupConfig->rlc_BearerToAddModList->list, rlc_BearerConfig); + DevAssert(ret == 0); + } +} + +void ue_context_setup_request(const f1ap_ue_context_setup_t *req) +{ + gNB_MAC_INST *mac = RC.nrmac[0]; + /* response has same type as request... */ + f1ap_ue_context_setup_t resp = { + .gNB_CU_ue_id = req->gNB_CU_ue_id, + .gNB_DU_ue_id = req->gNB_DU_ue_id, + .rnti = req->rnti, + }; + + if (req->cu_to_du_rrc_information != NULL) { + AssertFatal(req->cu_to_du_rrc_information->cG_ConfigInfo == NULL, "CG-ConfigInfo not handled\n"); + AssertFatal(req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList == NULL, "UE capabilities not handled yet\n"); + AssertFatal(req->cu_to_du_rrc_information->measConfig == NULL, "MeasConfig not handled\n"); + } + + NR_SCHED_LOCK(&mac->sched_lock); + + NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[0]->UE_info, req->rnti); + AssertFatal(UE != NULL, "did not find UE with RNTI %04x, but UE Context Setup Failed not implemented\n", UE->rnti); + + if (req->srbs_to_be_setup_length > 0) + handle_ue_context_srbs_setup(req, &resp, UE->CellGroup); + + if (req->drbs_to_be_setup_length > 0) { + handle_ue_context_drbs_setup(req, &resp, NULL); + } + + if (req->rrc_container != NULL) + nr_rlc_srb_recv_sdu(req->rnti, DCCH, req->rrc_container, req->rrc_container_length); + + //nr_mac_update_cellgroup() + resp.du_to_cu_rrc_information = calloc(1, sizeof(du_to_cu_rrc_information_t)); + AssertFatal(resp.du_to_cu_rrc_information != NULL, "out of memory\n"); + resp.du_to_cu_rrc_information->cellGroupConfig = calloc(1,1024); + AssertFatal(resp.du_to_cu_rrc_information->cellGroupConfig != NULL, "out of memory\n"); + asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig, + NULL, + UE->CellGroup, + resp.du_to_cu_rrc_information->cellGroupConfig, + 1024); + AssertFatal(enc_rval.encoded > 0, "Could not encode CellGroup, failed element %s\n", enc_rval.failed_type->name); + resp.du_to_cu_rrc_information->cellGroupConfig_length = (enc_rval.encoded + 7) >> 3; + + /* TODO: need to apply after UE context reconfiguration confirmed? */ + process_CellGroup(UE->CellGroup, &UE->UE_sched_ctrl); + + NR_SCHED_UNLOCK(&mac->sched_lock); + + /* some sanity checks, since we use the same type for request and response */ + DevAssert(resp.cu_to_du_rrc_information == NULL); + DevAssert(resp.du_to_cu_rrc_information != NULL); + DevAssert(resp.rrc_container == NULL && resp.rrc_container_length == 0); + + mac->mac_rrc.ue_context_setup_response(req, &resp); + + /* free the memory we allocated above */ + free(resp.srbs_to_be_setup); + free(resp.drbs_to_be_setup); + free(resp.du_to_cu_rrc_information->cellGroupConfig); + free(resp.du_to_cu_rrc_information); +} int dl_rrc_message(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc) { diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h index ecbc95eef0..25b51c2d84 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h @@ -25,6 +25,8 @@ #include "platform_types.h" #include "f1ap_messages_types.h" +void ue_context_setup_request(const f1ap_ue_context_setup_t *req); + int dl_rrc_message(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc); #endif /* MAC_RRC_DL_HANDLER_H */ diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul.h b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul.h index cb80ba4fa5..53736a1695 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul.h @@ -25,6 +25,8 @@ #include "platform_types.h" #include "f1ap_messages_types.h" +typedef void (*ue_context_setup_response_func_t)(const f1ap_ue_context_setup_t* req, const f1ap_ue_context_setup_t *resp); + typedef void (*initial_ul_rrc_message_transfer_func_t)(module_id_t module_id, const f1ap_initial_ul_rrc_message_t *ul_rrc); struct nr_mac_rrc_ul_if_s; diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c index ace8b17f49..eafa544185 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c @@ -24,6 +24,37 @@ #include "mac_rrc_ul.h" +static void ue_context_setup_response_direct(const f1ap_ue_context_setup_t *req, const f1ap_ue_context_setup_t *resp) +{ + DevAssert(req->drbs_to_be_setup_length == resp->drbs_to_be_setup_length); + AssertFatal(req->drbs_to_be_setup_length == 0, "not implemented\n"); + + (void) req; /* we don't need the request -- it is to set up GTP in F1 case */ + MessageDef *msg = itti_alloc_new_message (TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_SETUP_RESP); + f1ap_ue_context_setup_t *f1ap_msg = &F1AP_UE_CONTEXT_SETUP_RESP(msg); + /* copy all fields, but reallocate memory buffers! */ + *f1ap_msg = *resp; + + if (resp->srbs_to_be_setup_length > 0) { + DevAssert(resp->srbs_to_be_setup != NULL); + f1ap_msg->srbs_to_be_setup_length = resp->srbs_to_be_setup_length; + f1ap_msg->srbs_to_be_setup = calloc(f1ap_msg->srbs_to_be_setup_length, sizeof(*f1ap_msg->srbs_to_be_setup)); + for (int i = 0; i < f1ap_msg->srbs_to_be_setup_length; ++i) + f1ap_msg->srbs_to_be_setup[i] = resp->srbs_to_be_setup[i]; + } + + f1ap_msg->du_to_cu_rrc_information = malloc(sizeof(*resp->du_to_cu_rrc_information)); + AssertFatal(f1ap_msg->du_to_cu_rrc_information != NULL, "out of memory\n"); + f1ap_msg->du_to_cu_rrc_information_length = resp->du_to_cu_rrc_information_length; + du_to_cu_rrc_information_t *du2cu = f1ap_msg->du_to_cu_rrc_information; + du2cu->cellGroupConfig_length = resp->du_to_cu_rrc_information->cellGroupConfig_length; + du2cu->cellGroupConfig = calloc(du2cu->cellGroupConfig_length, sizeof(*du2cu->cellGroupConfig)); + AssertFatal(du2cu->cellGroupConfig != NULL, "out of memory\n"); + memcpy(du2cu->cellGroupConfig, resp->du_to_cu_rrc_information->cellGroupConfig, du2cu->cellGroupConfig_length); + + itti_send_msg_to_task(TASK_RRC_GNB, 0, msg); +} + static void initial_ul_rrc_message_transfer_direct(module_id_t module_id, const f1ap_initial_ul_rrc_message_t *ul_rrc) { MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_INITIAL_UL_RRC_MESSAGE); @@ -46,5 +77,6 @@ static void initial_ul_rrc_message_transfer_direct(module_id_t module_id, const void mac_rrc_ul_direct_init(struct nr_mac_rrc_ul_if_s *mac_rrc) { + mac_rrc->ue_context_setup_response = ue_context_setup_response_direct; mac_rrc->initial_ul_rrc_message_transfer = initial_ul_rrc_message_transfer_direct; } diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c index 13547c5291..c5bcb8814a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c @@ -19,11 +19,47 @@ * conmnc_digit_lengtht@openairinterface.org */ +#include +#include +#include + #include "nr_mac_gNB.h" #include "intertask_interface.h" +#include "openair3/ocp-gtpu/gtp_itf.h" #include "mac_rrc_ul.h" +static void ue_context_setup_response_f1ap(const f1ap_ue_context_setup_t *req, const f1ap_ue_context_setup_t *resp) +{ + DevAssert(req->drbs_to_be_setup_length == resp->drbs_to_be_setup_length); + AssertFatal(req->drbs_to_be_setup_length == 0, "not implmented\n"); + + DevAssert(req->srbs_to_be_setup_length == resp->srbs_to_be_setup_length); + MessageDef *msg = itti_alloc_new_message (TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_SETUP_RESP); + f1ap_ue_context_setup_t *f1ap_msg = &F1AP_UE_CONTEXT_SETUP_RESP(msg); + /* copy all fields, but reallocate rrc_containers! */ + *f1ap_msg = *resp; + + if (resp->srbs_to_be_setup_length > 0) { + DevAssert(resp->srbs_to_be_setup != NULL); + f1ap_msg->srbs_to_be_setup_length = resp->srbs_to_be_setup_length; + f1ap_msg->srbs_to_be_setup = calloc(f1ap_msg->srbs_to_be_setup_length, sizeof(*f1ap_msg->srbs_to_be_setup)); + for (int i = 0; i < f1ap_msg->srbs_to_be_setup_length; ++i) + f1ap_msg->srbs_to_be_setup[i] = resp->srbs_to_be_setup[i]; + } + + f1ap_msg->du_to_cu_rrc_information = malloc(sizeof(*resp->du_to_cu_rrc_information)); + AssertFatal(f1ap_msg->du_to_cu_rrc_information != NULL, "out of memory\n"); + f1ap_msg->du_to_cu_rrc_information_length = resp->du_to_cu_rrc_information_length; + du_to_cu_rrc_information_t *du2cu = f1ap_msg->du_to_cu_rrc_information; + du2cu->cellGroupConfig_length = resp->du_to_cu_rrc_information->cellGroupConfig_length; + du2cu->cellGroupConfig = calloc(du2cu->cellGroupConfig_length, sizeof(*du2cu->cellGroupConfig)); + AssertFatal(du2cu->cellGroupConfig != NULL, "out of memory\n"); + memcpy(du2cu->cellGroupConfig, resp->du_to_cu_rrc_information->cellGroupConfig, du2cu->cellGroupConfig_length); + + itti_send_msg_to_task(TASK_DU_F1, 0, msg); +} + static void initial_ul_rrc_message_transfer_f1ap(module_id_t module_id, const f1ap_initial_ul_rrc_message_t *ul_rrc) { MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_INITIAL_UL_RRC_MESSAGE); @@ -46,6 +82,7 @@ static void initial_ul_rrc_message_transfer_f1ap(module_id_t module_id, const f1 void mac_rrc_ul_f1ap_init(struct nr_mac_rrc_ul_if_s *mac_rrc) { + mac_rrc->ue_context_setup_response = ue_context_setup_response_f1ap; mac_rrc->initial_ul_rrc_message_transfer = initial_ul_rrc_message_transfer_f1ap; } diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c index cd8e16c48b..d7cd8e1b4b 100644 --- a/openair2/LAYER2/NR_MAC_gNB/main.c +++ b/openair2/LAYER2/NR_MAC_gNB/main.c @@ -60,7 +60,9 @@ void *nrmac_stats_thread(void *arg) { while (oai_exit == 0) { char *p = output; + NR_SCHED_LOCK(&gNB->sched_lock); p += dump_mac_stats(gNB, p, end - p, false); + NR_SCHED_UNLOCK(&gNB->sched_lock); p += snprintf(p, end - p, "\n"); p += print_meas_log(&gNB->eNB_scheduler, "DL & UL scheduling timing", NULL, NULL, p, end - p); p += print_meas_log(&gNB->schedule_dlsch, "dlsch scheduler", NULL, NULL, p, end - p); @@ -87,7 +89,11 @@ size_t dump_mac_stats(gNB_MAC_INST *gNB, char *output, size_t strlen, bool reset const char *begin = output; const char *end = output + strlen; - pthread_mutex_lock(&gNB->UE_info.mutex); + /* this function is called from gNB_dlsch_ulsch_scheduler(), so assumes the + * scheduler to be locked*/ + NR_SCHED_ENSURE_LOCKED(&gNB->sched_lock); + + NR_SCHED_LOCK(&gNB->UE_info.mutex); UE_iterator(gNB->UE_info.list, UE) { NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; NR_mac_stats_t *stats = &UE->mac_stats; @@ -175,7 +181,7 @@ size_t dump_mac_stats(gNB_MAC_INST *gNB, char *output, size_t strlen, bool reset stats->ul.lc_bytes[lc_id]); } } - pthread_mutex_unlock(&gNB->UE_info.mutex); + NR_SCHED_UNLOCK(&gNB->UE_info.mutex); return output - begin; } @@ -233,6 +239,8 @@ void mac_top_init_gNB(ngran_node_t node_type) RC.nrmac[i]->first_MIB = true; + pthread_mutex_init(&RC.nrmac[i]->sched_lock, NULL); + pthread_mutex_init(&RC.nrmac[i]->UE_info.mutex, NULL); uid_linear_allocator_init(&RC.nrmac[i]->UE_info.uid_allocator); diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index b8517da55e..5f25713650 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -41,6 +41,25 @@ #include #include #include +#include + +#define NR_SCHED_LOCK(lock) \ + do { \ + int rc = pthread_mutex_lock(lock); \ + AssertFatal(rc == 0, "error while locking scheduler mutex\n"); \ + } while (0) + +#define NR_SCHED_UNLOCK(lock) \ + do { \ + int rc = pthread_mutex_unlock(lock); \ + AssertFatal(rc == 0, "error while locking scheduler mutex\n"); \ + } while (0) + +#define NR_SCHED_ENSURE_LOCKED(lock)\ + do {\ + int rc = pthread_mutex_trylock(lock); \ + AssertFatal(rc == EBUSY, "this function should be called with the scheduler mutex locked\n");\ + } while (0) /* Commmon */ #include "radio/COMMON/common_lib.h" @@ -641,6 +660,7 @@ typedef struct NR_bler_options { typedef struct nr_mac_rrc_ul_if_s { /* TODO add other message types as necessary */ + ue_context_setup_response_func_t ue_context_setup_response; initial_ul_rrc_message_transfer_func_t initial_ul_rrc_message_transfer; } nr_mac_rrc_ul_if_t; @@ -795,6 +815,8 @@ typedef struct gNB_MAC_INST_s { int16_t frame; int16_t slot; + pthread_mutex_t sched_lock; + } gNB_MAC_INST; #endif /*__LAYER2_NR_MAC_GNB_H__ */ diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c index 187976753d..b9876b6773 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c @@ -1144,7 +1144,6 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info) uint32_t ret_mask = 0x0; module_id_t module_id = dl_info->module_id; NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); - fapi_nr_dl_config_request_t *dl_config = get_dl_config_request(mac, dl_info->slot); if ((!dl_info->dci_ind && !dl_info->rx_ind)) { // UL indication to schedule DCI reception @@ -1179,6 +1178,7 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info) if (ret >= 0) { AssertFatal( nr_ue_if_module_inst[module_id] != NULL, "IF module is NULL!\n" ); AssertFatal( nr_ue_if_module_inst[module_id]->scheduled_response != NULL, "scheduled_response is NULL!\n" ); + fapi_nr_dl_config_request_t *dl_config = get_dl_config_request(mac, dl_info->slot); fill_scheduled_response(&scheduled_response, dl_config, NULL, NULL, dl_info->module_id, dl_info->cc_id, dl_info->frame, dl_info->slot, dl_info->phy_data); nr_ue_if_module_inst[module_id]->scheduled_response(&scheduled_response); } diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c index fd3f420466..9128b0f50e 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c @@ -3808,7 +3808,6 @@ do_RRCConnectionReestablishment( LTE_DL_CCCH_Message_t dl_ccch_msg; LTE_RRCConnectionReestablishment_t *rrcConnectionReestablishment = NULL; int i = 0; - ue_context_pP->ue_context.reestablishment_xid = Transaction_id; LTE_SRB_ToAddModList_t **SRB_configList2 = NULL; SRB_configList2 = &ue_context_pP->ue_context.SRB_configList2[Transaction_id]; diff --git a/openair2/RRC/NR/L2_nr_interface.c b/openair2/RRC/NR/L2_nr_interface.c index 2e83c69af2..4e9c077afa 100644 --- a/openair2/RRC/NR/L2_nr_interface.c +++ b/openair2/RRC/NR/L2_nr_interface.c @@ -55,12 +55,17 @@ void nr_rrc_mac_remove_ue(rnti_t rntiMaybeUEid) nr_rlc_remove_ue(rntiMaybeUEid); gNB_MAC_INST *nrmac = RC.nrmac[0]; + NR_SCHED_LOCK(&nrmac->sched_lock); mac_remove_nr_ue(nrmac, rntiMaybeUEid); + NR_SCHED_UNLOCK(&nrmac->sched_lock); } void nr_rrc_mac_update_cellgroup(rnti_t rntiMaybeUEid, NR_CellGroupConfig_t *cgc) { - nr_mac_update_cellgroup(RC.nrmac[0], rntiMaybeUEid, cgc); + gNB_MAC_INST *nrmac = RC.nrmac[0]; + NR_SCHED_LOCK(&nrmac->sched_lock); + nr_mac_update_cellgroup(nrmac, rntiMaybeUEid, cgc); + NR_SCHED_UNLOCK(&nrmac->sched_lock); } uint16_t mac_rrc_nr_data_req(const module_id_t Mod_idP, diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c index 1f14eae9f6..01ba86bc98 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -1139,7 +1139,6 @@ int do_RRCReestablishment(const protocol_ctxt_t *const ctxt_pP, struct NR_SRB_ToAddMod *SRB2_config = NULL; NR_DL_DCCH_Message_t dl_dcch_msg = {0}; NR_RRCReestablishment_t *rrcReestablishment = NULL; - ue_context_pP->ue_context.reestablishment_xid = Transaction_id; NR_SRB_ToAddModList_t **SRB_configList2 = NULL; SRB_configList2 = &ue_context_pP->ue_context.SRB_configList2[Transaction_id]; diff --git a/openair2/RRC/NR/cucp_cuup_direct.c b/openair2/RRC/NR/cucp_cuup_direct.c index 05ec9a837b..d0d4365e70 100644 --- a/openair2/RRC/NR/cucp_cuup_direct.c +++ b/openair2/RRC/NR/cucp_cuup_direct.c @@ -179,13 +179,14 @@ static NR_SRB_ToAddModList_t **generateSRB2_confList(gNB_RRC_UE_t *ue, NR_SRB_To return SRB_configList2; } -static void cucp_cuup_bearer_context_setup_direct(e1ap_bearer_setup_req_t *const req, instance_t instance) { +static void cucp_cuup_bearer_context_setup_direct(e1ap_bearer_setup_req_t *const req, instance_t instance, uint8_t xid) +{ rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[instance], req->rnti); gNB_RRC_UE_t *UE = &ue_context_p->ue_context; protocol_ctxt_t ctxt = {0}; PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, UE->rnti, 0, 0, 0); - fill_DRB_configList(&ctxt, ue_context_p); + fill_DRB_configList(&ctxt, ue_context_p, xid); gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id]; // Fixme: xid not random, but almost! @@ -208,7 +209,7 @@ static void cucp_cuup_bearer_context_setup_direct(e1ap_bearer_setup_req_t *const } } -static void cucp_cuup_bearer_context_mod_direct(e1ap_bearer_setup_req_t *const req, instance_t instance) { +static void cucp_cuup_bearer_context_mod_direct(e1ap_bearer_setup_req_t *const req, instance_t instance, uint8_t xid) { instance_t gtpInst = getCxt(CUtype, instance)->gtpInst; CU_update_UP_DL_tunnel(req, gtpInst, req->rnti); } diff --git a/openair2/RRC/NR/cucp_cuup_e1ap.c b/openair2/RRC/NR/cucp_cuup_e1ap.c index a3311b2ee1..eeea7ed3a9 100644 --- a/openair2/RRC/NR/cucp_cuup_e1ap.c +++ b/openair2/RRC/NR/cucp_cuup_e1ap.c @@ -35,12 +35,13 @@ extern RAN_CONTEXT_t RC; -static void cucp_cuup_bearer_context_setup_e1ap(e1ap_bearer_setup_req_t *const req, instance_t instance) { +static void cucp_cuup_bearer_context_setup_e1ap(e1ap_bearer_setup_req_t *const req, instance_t instance, uint8_t xid) +{ rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[instance], req->rnti); protocol_ctxt_t ctxt = {0}; PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0, 0); - fill_DRB_configList(&ctxt, ue_context_p); + fill_DRB_configList(&ctxt, ue_context_p, xid); MessageDef *msg_p = itti_alloc_new_message(TASK_CUCP_E1, instance, E1AP_BEARER_CONTEXT_SETUP_REQ); e1ap_bearer_setup_req_t *bearer_req = &E1AP_BEARER_CONTEXT_SETUP_REQ(msg_p); memcpy(bearer_req, req, sizeof(e1ap_bearer_setup_req_t)); @@ -48,7 +49,8 @@ static void cucp_cuup_bearer_context_setup_e1ap(e1ap_bearer_setup_req_t *const r itti_send_msg_to_task (TASK_CUCP_E1, instance, msg_p); } -static void cucp_cuup_bearer_context_mod_e1ap(e1ap_bearer_setup_req_t *const req, instance_t instance) { +static void cucp_cuup_bearer_context_mod_e1ap(e1ap_bearer_setup_req_t *const req, instance_t instance, uint8_t xid) +{ MessageDef *msg = itti_alloc_new_message(TASK_CUCP_E1, instance, E1AP_BEARER_CONTEXT_MODIFICATION_REQ); e1ap_bearer_setup_req_t *req_msg = &E1AP_BEARER_CONTEXT_SETUP_REQ(msg); memcpy(req_msg, req, sizeof(*req)); diff --git a/openair2/RRC/NR/cucp_cuup_if.h b/openair2/RRC/NR/cucp_cuup_if.h index 079a32e850..ed4702b4b2 100644 --- a/openair2/RRC/NR/cucp_cuup_if.h +++ b/openair2/RRC/NR/cucp_cuup_if.h @@ -27,7 +27,7 @@ struct e1ap_bearer_setup_req_s; struct e1ap_bearer_setup_resp_s; -typedef void (*cucp_cuup_bearer_context_setup_func_t)(struct e1ap_bearer_setup_req_s *const req, instance_t instance); +typedef void (*cucp_cuup_bearer_context_setup_func_t)(struct e1ap_bearer_setup_req_s *const req, instance_t instance, uint8_t xid); struct gNB_RRC_INST_s; void cucp_cuup_message_transfer_direct_init(struct gNB_RRC_INST_s *rrc); diff --git a/openair2/RRC/NR/mac_rrc_dl.h b/openair2/RRC/NR/mac_rrc_dl.h index 1943490cd6..49ffccd4a7 100644 --- a/openair2/RRC/NR/mac_rrc_dl.h +++ b/openair2/RRC/NR/mac_rrc_dl.h @@ -25,6 +25,8 @@ #include "platform_types.h" #include "f1ap_messages_types.h" +typedef void (*ue_context_setup_request_func_t)(const f1ap_ue_context_setup_t *req); + typedef void (*dl_rrc_message_transfer_func_t)(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc); struct nr_mac_rrc_dl_if_s; diff --git a/openair2/RRC/NR/mac_rrc_dl_direct.c b/openair2/RRC/NR/mac_rrc_dl_direct.c index 5c8d9d9d5b..be416d6921 100644 --- a/openair2/RRC/NR/mac_rrc_dl_direct.c +++ b/openair2/RRC/NR/mac_rrc_dl_direct.c @@ -33,5 +33,6 @@ static void dl_rrc_message_transfer_direct(module_id_t module_id, const f1ap_dl_ void mac_rrc_dl_direct_init(nr_mac_rrc_dl_if_t *mac_rrc) { + mac_rrc->ue_context_setup_request = ue_context_setup_request; mac_rrc->dl_rrc_message_transfer = dl_rrc_message_transfer_direct; } diff --git a/openair2/RRC/NR/mac_rrc_dl_f1ap.c b/openair2/RRC/NR/mac_rrc_dl_f1ap.c index 40f3b4b6ea..bfe19a161b 100644 --- a/openair2/RRC/NR/mac_rrc_dl_f1ap.c +++ b/openair2/RRC/NR/mac_rrc_dl_f1ap.c @@ -19,9 +19,26 @@ * conmnc_digit_lengtht@openairinterface.org */ +#include + #include "mac_rrc_dl.h" #include "nr_rrc_defs.h" +static void ue_context_setup_request_f1ap(const f1ap_ue_context_setup_t *req) +{ + MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_SETUP_REQ); + f1ap_ue_context_setup_t *f1ap_msg = &F1AP_UE_CONTEXT_SETUP_REQ(msg); + *f1ap_msg = *req; + AssertFatal(req->cu_to_du_rrc_information == NULL, "cu_to_du_rrc_information not supported yet\n"); + if (req->rrc_container_length > 0) { + f1ap_msg->rrc_container = calloc(req->rrc_container_length, sizeof(*f1ap_msg->rrc_container)); + AssertFatal(f1ap_msg->rrc_container != NULL, "out of memory\n"); + f1ap_msg->rrc_container_length = req->rrc_container_length; + memcpy(f1ap_msg->rrc_container, req->rrc_container, req->rrc_container_length); + } + itti_send_msg_to_task(TASK_CU_F1, 0, msg); +} + static void dl_rrc_message_transfer_f1ap(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc) { /* TODO call F1AP function directly? no real-time constraint here */ @@ -40,5 +57,6 @@ static void dl_rrc_message_transfer_f1ap(module_id_t module_id, const f1ap_dl_rr void mac_rrc_dl_f1ap_init(nr_mac_rrc_dl_if_t *mac_rrc) { + mac_rrc->ue_context_setup_request = ue_context_setup_request_f1ap; mac_rrc->dl_rrc_message_transfer = dl_rrc_message_transfer_f1ap; } diff --git a/openair2/RRC/NR/nr_rrc_config.c b/openair2/RRC/NR/nr_rrc_config.c index 6626fc2240..20ba902244 100644 --- a/openair2/RRC/NR/nr_rrc_config.c +++ b/openair2/RRC/NR/nr_rrc_config.c @@ -137,50 +137,52 @@ static uint64_t get_ssb_bitmap(const NR_ServingCellConfigCommon_t *scc) return bitmap; } -static void set_csirs_periodicity(NR_NZP_CSI_RS_Resource_t *nzpcsi0, int uid, int nb_slots_per_period) +static void set_csirs_periodicity(NR_NZP_CSI_RS_Resource_t *nzpcsi0, int uid, int nb_slots_per_period, int nb_dl_slots_period) { nzpcsi0->periodicityAndOffset = calloc(1,sizeof(*nzpcsi0->periodicityAndOffset)); - int ideal_period = nb_slots_per_period * MAX_MOBILES_PER_GNB; + const int ideal_period = nb_slots_per_period * MAX_MOBILES_PER_GNB; + const int offset = nb_slots_per_period * uid; - if (ideal_period<5) { + if (ideal_period < 5) { nzpcsi0->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots4; - nzpcsi0->periodicityAndOffset->choice.slots4 = nb_slots_per_period*uid; + nzpcsi0->periodicityAndOffset->choice.slots4 = offset; } - else if (ideal_period<6) { + else if (ideal_period < 6) { nzpcsi0->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots5; - nzpcsi0->periodicityAndOffset->choice.slots5 = nb_slots_per_period*uid; + nzpcsi0->periodicityAndOffset->choice.slots5 = offset; } - else if (ideal_period<9) { + else if (ideal_period < 9) { nzpcsi0->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots8; - nzpcsi0->periodicityAndOffset->choice.slots8 = nb_slots_per_period*uid; + nzpcsi0->periodicityAndOffset->choice.slots8 = offset; } - else if (ideal_period<11) { + else if (ideal_period < 11) { nzpcsi0->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots10; - nzpcsi0->periodicityAndOffset->choice.slots10 = nb_slots_per_period*uid; + nzpcsi0->periodicityAndOffset->choice.slots10 = offset; } - else if (ideal_period<17) { + else if (ideal_period < 17) { nzpcsi0->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots16; - nzpcsi0->periodicityAndOffset->choice.slots16 = nb_slots_per_period*uid; + nzpcsi0->periodicityAndOffset->choice.slots16 = offset; } - else if (ideal_period<21) { + else if (ideal_period < 21) { nzpcsi0->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots20; - nzpcsi0->periodicityAndOffset->choice.slots20 = nb_slots_per_period*uid; + nzpcsi0->periodicityAndOffset->choice.slots20 = offset; } - else if (ideal_period<41) { + else if (ideal_period < 41) { nzpcsi0->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots40; - nzpcsi0->periodicityAndOffset->choice.slots40 = nb_slots_per_period*uid; + nzpcsi0->periodicityAndOffset->choice.slots40 = offset; } - else if (ideal_period<81) { + else if (ideal_period < 81) { nzpcsi0->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots80; - nzpcsi0->periodicityAndOffset->choice.slots80 = nb_slots_per_period*uid; + nzpcsi0->periodicityAndOffset->choice.slots80 = offset; } - else if (ideal_period<161) { + else if (ideal_period < 161) { nzpcsi0->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots160; - nzpcsi0->periodicityAndOffset->choice.slots160 = nb_slots_per_period*uid; + nzpcsi0->periodicityAndOffset->choice.slots160 = offset; } else { nzpcsi0->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots320; - nzpcsi0->periodicityAndOffset->choice.slots320 = (nb_slots_per_period*uid)%320 + (nb_slots_per_period*uid)/320; + AssertFatal(offset / 320 < nb_dl_slots_period, "Cannot allocate %dth UE. Not enough resources for CSI-RS\n", uid); + nzpcsi0->periodicityAndOffset->choice.slots320 = (offset % 320) + (offset / 320); } } @@ -210,10 +212,8 @@ static void config_csirs(const NR_ServingCellConfigCommon_t *servingcellconfigco &servingcellconfigcommon->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL; const int n_slots_frame = slotsperframe[*servingcellconfigcommon->ssbSubcarrierSpacing]; - - int nb_slots_per_period = n_slots_frame; - if (tdd) - nb_slots_per_period = n_slots_frame/get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity); + int nb_slots_per_period = tdd ? n_slots_frame/get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity): n_slots_frame; + int nb_dl_slots_period = tdd ? tdd->nrofDownlinkSlots : n_slots_frame; if(!csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList) csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList = calloc(1,sizeof(*csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList)); @@ -257,13 +257,13 @@ static void config_csirs(const NR_ServingCellConfigCommon_t *servingcellconfigco resourceMapping.density.present = NR_CSI_RS_ResourceMapping__density_PR_one; resourceMapping.density.choice.one = (NULL_t)0; resourceMapping.freqBand.startingRB = 0; - resourceMapping.freqBand.nrofRBs = ((curr_bwp>>2)+(curr_bwp%4>0))<<2; + resourceMapping.freqBand.nrofRBs = ((curr_bwp >> 2) + (curr_bwp % 4 > 0)) << 2; nzpcsi0->resourceMapping = resourceMapping; nzpcsi0->powerControlOffset = 0; - nzpcsi0->powerControlOffsetSS=calloc(1,sizeof(*nzpcsi0->powerControlOffsetSS)); + nzpcsi0->powerControlOffsetSS = calloc(1,sizeof(*nzpcsi0->powerControlOffsetSS)); *nzpcsi0->powerControlOffsetSS = NR_NZP_CSI_RS_Resource__powerControlOffsetSS_db0; nzpcsi0->scramblingID = *servingcellconfigcommon->physCellId; - set_csirs_periodicity(nzpcsi0, uid, nb_slots_per_period); + set_csirs_periodicity(nzpcsi0, uid, nb_slots_per_period, nb_dl_slots_period); nzpcsi0->qcl_InfoPeriodicCSI_RS = calloc(1,sizeof(*nzpcsi0->qcl_InfoPeriodicCSI_RS)); *nzpcsi0->qcl_InfoPeriodicCSI_RS = 0; asn1cSeqAdd(&csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList->list,nzpcsi0); @@ -412,66 +412,68 @@ static struct NR_SRS_Resource__resourceType__periodic *configure_periodic_srs(co const int n_slots_period = tdd ? n_slots_frame/get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity) : n_slots_frame; const int first_full_ul_slot = n_slots_period - ul_slots_period; const int ideal_period = n_slots_period * MAX_MOBILES_PER_GNB; + const int offset = first_full_ul_slot + (uid % ul_slots_period) + (n_slots_period * (uid / ul_slots_period)); + AssertFatal(offset < 2560, "Cannot allocate SRS configuration for uid %d, not enough resources\n", uid); struct NR_SRS_Resource__resourceType__periodic *periodic_srs = calloc(1,sizeof(*periodic_srs)); if (ideal_period < 5) { periodic_srs->periodicityAndOffset_p.present = NR_SRS_PeriodicityAndOffset_PR_sl4; - periodic_srs->periodicityAndOffset_p.choice.sl4 = first_full_ul_slot + (uid % ul_slots_period) + (n_slots_period * (uid / ul_slots_period)); + periodic_srs->periodicityAndOffset_p.choice.sl4 = offset; } else if (ideal_period < 6) { periodic_srs->periodicityAndOffset_p.present = NR_SRS_PeriodicityAndOffset_PR_sl5; - periodic_srs->periodicityAndOffset_p.choice.sl5 = first_full_ul_slot + (uid % ul_slots_period) + (n_slots_period * (uid / ul_slots_period)); + periodic_srs->periodicityAndOffset_p.choice.sl5 = offset; } else if (ideal_period < 9) { periodic_srs->periodicityAndOffset_p.present = NR_SRS_PeriodicityAndOffset_PR_sl8; - periodic_srs->periodicityAndOffset_p.choice.sl8 = first_full_ul_slot + (uid % ul_slots_period) + (n_slots_period * (uid / ul_slots_period)); + periodic_srs->periodicityAndOffset_p.choice.sl8 = offset; } else if (ideal_period < 11) { periodic_srs->periodicityAndOffset_p.present = NR_SRS_PeriodicityAndOffset_PR_sl10; - periodic_srs->periodicityAndOffset_p.choice.sl10 = first_full_ul_slot + (uid % ul_slots_period) + (n_slots_period * (uid / ul_slots_period)); + periodic_srs->periodicityAndOffset_p.choice.sl10 = offset; } else if (ideal_period < 17) { periodic_srs->periodicityAndOffset_p.present = NR_SRS_PeriodicityAndOffset_PR_sl16; - periodic_srs->periodicityAndOffset_p.choice.sl16 = first_full_ul_slot + (uid % ul_slots_period) + (n_slots_period * (uid / ul_slots_period)); + periodic_srs->periodicityAndOffset_p.choice.sl16 = offset; } else if (ideal_period < 21) { periodic_srs->periodicityAndOffset_p.present = NR_SRS_PeriodicityAndOffset_PR_sl20; - periodic_srs->periodicityAndOffset_p.choice.sl20 = first_full_ul_slot + (uid % ul_slots_period) + (n_slots_period * (uid / ul_slots_period)); + periodic_srs->periodicityAndOffset_p.choice.sl20 = offset; } else if (ideal_period < 33) { periodic_srs->periodicityAndOffset_p.present = NR_SRS_PeriodicityAndOffset_PR_sl32; - periodic_srs->periodicityAndOffset_p.choice.sl32 = first_full_ul_slot + (uid % ul_slots_period) + (n_slots_period * (uid / ul_slots_period)); + periodic_srs->periodicityAndOffset_p.choice.sl32 = offset; } else if (ideal_period < 41) { periodic_srs->periodicityAndOffset_p.present = NR_SRS_PeriodicityAndOffset_PR_sl40; - periodic_srs->periodicityAndOffset_p.choice.sl40 = first_full_ul_slot + (uid % ul_slots_period) + (n_slots_period * (uid / ul_slots_period)); + periodic_srs->periodicityAndOffset_p.choice.sl40 = offset; } else if (ideal_period < 65) { periodic_srs->periodicityAndOffset_p.present = NR_SRS_PeriodicityAndOffset_PR_sl64; - periodic_srs->periodicityAndOffset_p.choice.sl64 = first_full_ul_slot + (uid % ul_slots_period) + (n_slots_period * (uid / ul_slots_period)); + periodic_srs->periodicityAndOffset_p.choice.sl64 = offset; } else if (ideal_period < 81) { periodic_srs->periodicityAndOffset_p.present = NR_SRS_PeriodicityAndOffset_PR_sl80; - periodic_srs->periodicityAndOffset_p.choice.sl80 = first_full_ul_slot + (uid % ul_slots_period) + (n_slots_period * (uid / ul_slots_period)); + periodic_srs->periodicityAndOffset_p.choice.sl80 = offset; } else if (ideal_period < 161) { periodic_srs->periodicityAndOffset_p.present = NR_SRS_PeriodicityAndOffset_PR_sl160; - periodic_srs->periodicityAndOffset_p.choice.sl160 = first_full_ul_slot + (uid % ul_slots_period) + (n_slots_period * (uid / ul_slots_period)); + periodic_srs->periodicityAndOffset_p.choice.sl160 = offset; } else if (ideal_period < 321) { periodic_srs->periodicityAndOffset_p.present = NR_SRS_PeriodicityAndOffset_PR_sl320; - periodic_srs->periodicityAndOffset_p.choice.sl320 = first_full_ul_slot + (uid % ul_slots_period) + (n_slots_period * (uid / ul_slots_period)); + periodic_srs->periodicityAndOffset_p.choice.sl320 = offset; } else if (ideal_period < 641) { periodic_srs->periodicityAndOffset_p.present = NR_SRS_PeriodicityAndOffset_PR_sl640; - periodic_srs->periodicityAndOffset_p.choice.sl640 = first_full_ul_slot + (uid % ul_slots_period) + (n_slots_period * (uid / ul_slots_period)); + periodic_srs->periodicityAndOffset_p.choice.sl640 = offset; } else if (ideal_period < 1281) { periodic_srs->periodicityAndOffset_p.present = NR_SRS_PeriodicityAndOffset_PR_sl1280; - periodic_srs->periodicityAndOffset_p.choice.sl1280 = first_full_ul_slot + (uid % ul_slots_period) + (n_slots_period * (uid / ul_slots_period)); + periodic_srs->periodicityAndOffset_p.choice.sl1280 = offset; } else { periodic_srs->periodicityAndOffset_p.present = NR_SRS_PeriodicityAndOffset_PR_sl2560; - periodic_srs->periodicityAndOffset_p.choice.sl2560 = first_full_ul_slot + (uid % ul_slots_period) + (n_slots_period * (uid / ul_slots_period)); + periodic_srs->periodicityAndOffset_p.choice.sl2560 = offset; } return periodic_srs; } @@ -782,26 +784,27 @@ static void config_pucch_resset0(NR_PUCCH_Config_t *pucch_Config, int uid, int c { NR_PUCCH_ResourceSet_t *pucchresset = calloc(1,sizeof(*pucchresset)); pucchresset->pucch_ResourceSetId = 0; - NR_PUCCH_ResourceId_t *pucchid=calloc(1,sizeof(*pucchid)); - *pucchid=0; + NR_PUCCH_ResourceId_t *pucchid = calloc(1,sizeof(*pucchid)); + *pucchid = 0; asn1cSeqAdd(&pucchresset->resourceList.list,pucchid); - pucchresset->maxPayloadSize=NULL; + pucchresset->maxPayloadSize = NULL; if(uecap) { long *pucch_F0_2WithoutFH = uecap->phy_Parameters.phy_ParametersFRX_Diff->pucch_F0_2WithoutFH; AssertFatal(pucch_F0_2WithoutFH == NULL,"UE does not support PUCCH F0 without frequency hopping. Current configuration is without FH\n"); } - NR_PUCCH_Resource_t *pucchres0=calloc(1,sizeof(*pucchres0)); - pucchres0->pucch_ResourceId=*pucchid; - pucchres0->startingPRB= (8 + uid) % curr_bwp; - pucchres0->intraSlotFrequencyHopping=NULL; - pucchres0->secondHopPRB=NULL; - pucchres0->format.present= NR_PUCCH_Resource__format_PR_format0; - pucchres0->format.choice.format0=calloc(1,sizeof(*pucchres0->format.choice.format0)); - pucchres0->format.choice.format0->initialCyclicShift=0; - pucchres0->format.choice.format0->nrofSymbols=1; - pucchres0->format.choice.format0->startingSymbolIndex=13; + NR_PUCCH_Resource_t *pucchres0 = calloc(1,sizeof(*pucchres0)); + pucchres0->pucch_ResourceId = *pucchid; + pucchres0->startingPRB = 8 + uid; + AssertFatal(pucchres0->startingPRB < curr_bwp, "Not enough resources in current BWP (size %d) to allocate uid %d\n", curr_bwp, uid); + pucchres0->intraSlotFrequencyHopping = NULL; + pucchres0->secondHopPRB = NULL; + pucchres0->format.present = NR_PUCCH_Resource__format_PR_format0; + pucchres0->format.choice.format0 = calloc(1,sizeof(*pucchres0->format.choice.format0)); + pucchres0->format.choice.format0->initialCyclicShift = 0; + pucchres0->format.choice.format0->nrofSymbols = 1; + pucchres0->format.choice.format0->startingSymbolIndex = 13; asn1cSeqAdd(&pucch_Config->resourceToAddModList->list,pucchres0); asn1cSeqAdd(&pucch_Config->resourceSetToAddModList->list,pucchresset); @@ -814,44 +817,43 @@ static void config_pucch_resset1(NR_PUCCH_Config_t *pucch_Config, const NR_UE_NR NR_PUCCH_ResourceSet_t *pucchresset=calloc(1,sizeof(*pucchresset)); pucchresset->pucch_ResourceSetId = 1; NR_PUCCH_ResourceId_t *pucchressetid=calloc(1,sizeof(*pucchressetid)); - *pucchressetid=2; + *pucchressetid = 2; asn1cSeqAdd(&pucchresset->resourceList.list,pucchressetid); - pucchresset->maxPayloadSize=NULL; + pucchresset->maxPayloadSize = NULL; if(uecap) { long *pucch_F0_2WithoutFH = uecap->phy_Parameters.phy_ParametersFRX_Diff->pucch_F0_2WithoutFH; AssertFatal(pucch_F0_2WithoutFH == NULL,"UE does not support PUCCH F2 without frequency hopping. Current configuration is without FH\n"); } - NR_PUCCH_Resource_t *pucchres2=calloc(1,sizeof(*pucchres2)); - pucchres2->pucch_ResourceId=*pucchressetid; - pucchres2->startingPRB=0; - pucchres2->intraSlotFrequencyHopping=NULL; - pucchres2->secondHopPRB=NULL; - pucchres2->format.present= NR_PUCCH_Resource__format_PR_format2; - pucchres2->format.choice.format2=calloc(1,sizeof(*pucchres2->format.choice.format2)); - pucchres2->format.choice.format2->nrofPRBs=8; - pucchres2->format.choice.format2->nrofSymbols=1; - pucchres2->format.choice.format2->startingSymbolIndex=13; + NR_PUCCH_Resource_t *pucchres2 = calloc(1,sizeof(*pucchres2)); + pucchres2->pucch_ResourceId = *pucchressetid; + pucchres2->startingPRB = 0; + pucchres2->intraSlotFrequencyHopping = NULL; + pucchres2->secondHopPRB = NULL; + pucchres2->format.present = NR_PUCCH_Resource__format_PR_format2; + pucchres2->format.choice.format2 = calloc(1,sizeof(*pucchres2->format.choice.format2)); + pucchres2->format.choice.format2->nrofPRBs = 8; + pucchres2->format.choice.format2->nrofSymbols = 1; + pucchres2->format.choice.format2->startingSymbolIndex = 13; asn1cSeqAdd(&pucch_Config->resourceToAddModList->list,pucchres2); asn1cSeqAdd(&pucch_Config->resourceSetToAddModList->list,pucchresset); - pucch_Config->format2=calloc(1,sizeof(*pucch_Config->format2)); - pucch_Config->format2->present=NR_SetupRelease_PUCCH_FormatConfig_PR_setup; + pucch_Config->format2 = calloc(1,sizeof(*pucch_Config->format2)); + pucch_Config->format2->present = NR_SetupRelease_PUCCH_FormatConfig_PR_setup; NR_PUCCH_FormatConfig_t *pucchfmt2 = calloc(1,sizeof(*pucchfmt2)); pucch_Config->format2->choice.setup = pucchfmt2; - pucchfmt2->interslotFrequencyHopping=NULL; - pucchfmt2->additionalDMRS=NULL; - pucchfmt2->maxCodeRate=calloc(1,sizeof(*pucchfmt2->maxCodeRate)); - *pucchfmt2->maxCodeRate=NR_PUCCH_MaxCodeRate_zeroDot35; - pucchfmt2->nrofSlots=NULL; - pucchfmt2->pi2BPSK=NULL; + pucchfmt2->interslotFrequencyHopping = NULL; + pucchfmt2->additionalDMRS = NULL; + pucchfmt2->maxCodeRate = calloc(1,sizeof(*pucchfmt2->maxCodeRate)); + *pucchfmt2->maxCodeRate = NR_PUCCH_MaxCodeRate_zeroDot35; + pucchfmt2->nrofSlots = NULL; + pucchfmt2->pi2BPSK = NULL; // to check UE capabilities for that in principle - pucchfmt2->simultaneousHARQ_ACK_CSI=calloc(1,sizeof(*pucchfmt2->simultaneousHARQ_ACK_CSI)); - *pucchfmt2->simultaneousHARQ_ACK_CSI=NR_PUCCH_FormatConfig__simultaneousHARQ_ACK_CSI_true; - + pucchfmt2->simultaneousHARQ_ACK_CSI = calloc(1,sizeof(*pucchfmt2->simultaneousHARQ_ACK_CSI)); + *pucchfmt2->simultaneousHARQ_ACK_CSI = NR_PUCCH_FormatConfig__simultaneousHARQ_ACK_CSI_true; } void set_pucch_power_config(NR_PUCCH_Config_t *pucch_Config, int do_csirs) { @@ -1351,10 +1353,10 @@ static void set_csi_meas_periodicity(const NR_ServingCellConfigCommon_t *scc, NR const int n_ul_slots_period = tdd ? (tdd->nrofUplinkSlots + (tdd->nrofUplinkSymbols > 0)) : n_slots_frame; const int n_slots_period = tdd ? n_slots_frame / get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity) : n_slots_frame; const int ideal_period = MAX_MOBILES_PER_GNB * 2 * n_slots_period / n_ul_slots_period; // 2 reports per UE - AssertFatal(ideal_period < 320, "Not enough UL slots to accomodate all possible UEs. Need to rework the implementation\n"); const int first_ul_slot_period = tdd ? get_first_ul_slot(tdd->nrofDownlinkSlots, tdd->nrofDownlinkSymbols, tdd->nrofUplinkSymbols) : 0; const int idx = (uid << 1) + is_rsrp; const int offset = first_ul_slot_period + idx % n_ul_slots_period + (idx / n_ul_slots_period) * n_slots_period; + AssertFatal(offset < 320, "Not enough UL slots to accomodate all possible UEs. Need to rework the implementation\n"); if (ideal_period < 5) { csirep->reportConfigType.choice.periodic->reportSlotConfig.present = NR_CSI_ReportPeriodicityAndOffset_PR_slots4; @@ -2051,11 +2053,6 @@ static NR_SpCellConfig_t *get_initial_SpCellConfig(int uid, const NR_ServingCellConfig_t *servingcellconfigdedicated, const gNB_RrcConfigurationReq *configuration) { - // This assert will never happen in the current implementation because NUMBER_OF_UE_MAX = 4. - // However, if in the future NUMBER_OF_UE_MAX is increased, it will be necessary to improve the allocation of SRS resources, - // where the startPosition = 2 or 3 and sl160 = 17, 17, 27 ... 157 only give us 30 different allocations. - AssertFatal(uid >= 0 && uid < 30, "gNB cannot allocate the SRS resources\n"); - const int pdsch_AntennaPorts = configuration->pdsch_AntennaPorts.N1 * configuration->pdsch_AntennaPorts.N2 * configuration->pdsch_AntennaPorts.XP; int curr_bwp = NRRIV2BW(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); @@ -2326,6 +2323,8 @@ NR_CellGroupConfig_t *get_initial_cellGroupConfig(int uid, return cellGroupConfig; } +#include "common/ran_context.h" +#include "nr_rrc_defs.h" void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, const int uid, NR_UE_NR_Capability_t *uecap, @@ -2341,6 +2340,13 @@ void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, return; DevAssert(configuration->scc != NULL); + /* This is a hack and will be removed once the CellGroupConfig is fully + * handled at the DU */ + if (NODE_IS_CU(RC.nrrrc[0]->node_type)) { + LOG_W(RRC, "update of CellGroupConfig not yet supported in F1\n"); + return; + } + NR_SpCellConfig_t *SpCellConfig = cellGroupConfig->spCellConfig; NR_ServingCellConfigCommon_t *scc = configuration->scc; diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index 93acdeac7b..9887d89367 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -128,7 +128,7 @@ typedef enum UE_STATE_NR_e { #define NO_SECURITY_MODE 0x20 /* TS 36.331: RRC-TransactionIdentifier ::= INTEGER (0..3) */ -#define NR_RRC_TRANSACTION_IDENTIFIER_NUMBER 3 +#define NR_RRC_TRANSACTION_IDENTIFIER_NUMBER 4 typedef struct { unsigned short transport_block_size; /*!< \brief Minimum PDU size in bytes provided by RLC to MAC layer interface */ @@ -258,14 +258,15 @@ typedef enum pdu_session_satus_e { PDU_SESSION_STATUS_DONE, PDU_SESSION_STATUS_ESTABLISHED, PDU_SESSION_STATUS_REESTABLISHED, // after HO - PDU_SESSION_STATUS_TOMODIFY, // ENDC NSA + PDU_SESSION_STATUS_TOMODIFY, // ENDC NSA PDU_SESSION_STATUS_FAILED, - PDU_SESSION_STATUS_TORELEASE // to release DRB between eNB and UE + PDU_SESSION_STATUS_TORELEASE, // to release DRB between eNB and UE + PDU_SESSION_STATUS_RELEASED } pdu_session_status_t; typedef struct pdu_session_param_s { pdusession_t param; - uint8_t status; + pdu_session_status_t status; uint8_t xid; // transaction_id ngap_Cause_t cause; uint8_t cause_value; @@ -305,6 +306,19 @@ typedef struct drb_s { } pdcp_config; } drb_t; +typedef enum { + RRC_FIRST_RECONF, + RRC_SETUP, + RRC_SETUP_FOR_REESTABLISHMENT, + RRC_REESTABLISH, + RRC_REESTABLISH_COMPLETE, + RRC_DEFAULT_RECONF, + RRC_DEDICATED_RECONF, + RRC_PDUSESSION_ESTABLISH, + RRC_PDUSESSION_MODIFY, + RRC_PDUSESSION_RELEASE +} rrc_action_t; + typedef struct gNB_RRC_UE_s { uint8_t primaryCC_id; NR_SRB_ToAddModList_t *SRB_configList; @@ -369,38 +383,20 @@ typedef struct gNB_RRC_UE_s { nr_rrc_guami_t ue_guami; ngap_security_capabilities_t security_capabilities; - - /* Total number of e_rab already setup in the list */ - uint8_t setup_e_rabs; - /* Number of e_rab to be setup in the list */ + //NSA block + /* Number of NSA e_rab */ uint8_t nb_of_e_rabs; - /* Number of e_rab to be modified in the list */ - uint8_t nb_of_modify_e_rabs; - uint8_t nb_of_failed_e_rabs; - nr_e_rab_param_t modify_e_rab[NB_RB_MAX];//[S1AP_MAX_E_RAB]; - /* Number of pdu session managed for the ue */ - uint8_t nb_of_pdusessions; - /* Number of e_rab to be modified in the list */ - uint8_t nb_of_modify_pdusessions; - uint8_t nb_of_failed_pdusessions; - rrc_pdu_session_param_t modify_pdusession[NR_NB_RB_MAX]; - /* list of e_rab to be setup by RRC layers */ /* list of pdu session to be setup by RRC layers */ nr_e_rab_param_t e_rab[NB_RB_MAX];//[S1AP_MAX_E_RAB]; - rrc_pdu_session_param_t pduSession[NGAP_MAX_PDU_SESSION]; - //release e_rabs - uint8_t nb_release_of_e_rabs; - e_rab_failed_t e_rabs_release_failed[S1AP_MAX_E_RAB]; - uint8_t nb_release_of_pdusessions; - pdusession_failed_t pdusessions_release_failed[NGAP_MAX_PDUSESSION]; - // LG: For GTPV1 TUNNELS - uint32_t gnb_gtp_teid[S1AP_MAX_E_RAB]; - transport_layer_addr_t gnb_gtp_addrs[S1AP_MAX_E_RAB]; - rb_id_t gnb_gtp_ebi[S1AP_MAX_E_RAB]; - rb_id_t gnb_gtp_psi[S1AP_MAX_E_RAB]; - //GTPV1 F1-U TUNNELS - uint32_t incoming_teid[S1AP_MAX_E_RAB]; + uint32_t nsa_gtp_teid[S1AP_MAX_E_RAB]; + transport_layer_addr_t nsa_gtp_addrs[S1AP_MAX_E_RAB]; + rb_id_t nsa_gtp_ebi[S1AP_MAX_E_RAB]; + rb_id_t nsa_gtp_psi[S1AP_MAX_E_RAB]; + //SA block + int nb_of_pdusessions; + rrc_pdu_session_param_t pduSession[NGAP_MAX_PDU_SESSION]; + rrc_action_t xids[NR_RRC_TRANSACTION_IDENTIFIER_NUMBER]; uint32_t ul_failure_timer; uint32_t ue_release_timer; uint32_t ue_release_timer_thres; @@ -412,11 +408,8 @@ typedef struct gNB_RRC_UE_s { uint32_t ue_release_timer_thres_rrc; uint32_t ue_reestablishment_timer; uint32_t ue_reestablishment_timer_thres; - uint8_t e_rab_release_command_flag; - uint8_t pdu_session_release_command_flag; - uint8_t established_pdu_sessions_flag; - uint32_t ue_rrc_inactivity_timer; - int8_t reestablishment_xid; + uint8_t e_rab_release_command_flag; + uint32_t ue_rrc_inactivity_timer; uint32_t ue_reestablishment_counter; uint32_t ue_reconfiguration_after_reestablishment_counter; NR_CellGroupId_t cellGroupId; @@ -481,6 +474,7 @@ typedef struct { typedef struct nr_mac_rrc_dl_if_s { /* TODO add other message types as necessary */ + ue_context_setup_request_func_t ue_context_setup_request; dl_rrc_message_transfer_func_t dl_rrc_message_transfer; } nr_mac_rrc_dl_if_t; diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h index 87d786b773..ee236e1408 100644 --- a/openair2/RRC/NR/nr_rrc_proto.h +++ b/openair2/RRC/NR/nr_rrc_proto.h @@ -164,8 +164,7 @@ void ue_cxt_mod_send_e1ap(MessageDef *msg, void ue_cxt_mod_direct(MessageDef *msg, instance_t instance); -void fill_DRB_configList(const protocol_ctxt_t *const ctxt_pP, - rrc_gNB_ue_context_t *ue_context_pP); +void fill_DRB_configList(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP, uint8_t xid); void prepare_and_send_ue_context_modification_f1(rrc_gNB_ue_context_t *ue_context_p, e1ap_bearer_setup_resp_t *e1ap_resp); diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 2d3628f765..9c7a58c081 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -106,8 +106,7 @@ extern RAN_CONTEXT_t RC; static inline uint64_t bitStr_to_uint64(BIT_STRING_t *asn); -mui_t rrc_gNB_mui = 0; -uint8_t first_rrcreconfiguration = 0; +mui_t rrc_gNB_mui = 0; ///---------------------------------------------------------------------------------------------------------------/// ///---------------------------------------------------------------------------------------------------------------/// @@ -349,7 +348,9 @@ static void rrc_gNB_generate_RRCSetup(instance_t instance, gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; gNB_RRC_INST *rrc = RC.nrrrc[instance]; unsigned char buf[1024]; - int size = do_RRCSetup(ue_context_pP, buf, rrc_gNB_get_next_transaction_identifier(instance), masterCellGroup, masterCellGroup_len, &rrc->configuration); + uint8_t xid = rrc_gNB_get_next_transaction_identifier(instance); + ue_p->xids[xid] = RRC_SETUP; + int size = do_RRCSetup(ue_context_pP, buf, xid, masterCellGroup, masterCellGroup_len, &rrc->configuration); AssertFatal(size > 0, "do_RRCSetup failed\n"); AssertFatal(size <= 1024, "memory corruption\n"); @@ -363,7 +364,6 @@ static void rrc_gNB_generate_RRCSetup(instance_t instance, // remove UE after 10 frames after RRCConnectionRelease is triggered ue_context_pP->ue_context.ue_release_timer_thres = 1000; - /* TODO: this should go through the E1 interface */ nr_pdcp_add_srbs(true, rnti, ue_context_pP->ue_context.SRB_configList, 0, NULL, NULL); f1ap_dl_rrc_message_t dl_rrc = { @@ -377,7 +377,7 @@ static void rrc_gNB_generate_RRCSetup(instance_t instance, } //----------------------------------------------------------------------------- -static void rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id_t module_id, rnti_t rnti, const int CC_id) +static int rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id_t module_id, rnti_t rnti, const int CC_id) //----------------------------------------------------------------------------- { LOG_I(NR_RRC, "generate RRCSetup for RRCReestablishmentRequest \n"); @@ -388,7 +388,9 @@ static void rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id_t gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; unsigned char buf[1024]; - int size = do_RRCSetup(ue_context_pP, buf, rrc_gNB_get_next_transaction_identifier(module_id), NULL, 0, &rrc_instance_p->configuration); + uint8_t xid = rrc_gNB_get_next_transaction_identifier(module_id); + ue_p->xids[xid] = RRC_SETUP_FOR_REESTABLISHMENT; + int size = do_RRCSetup(ue_context_pP, buf, xid, NULL, 0, &rrc_instance_p->configuration); AssertFatal(size > 0, "do_RRCSetup failed\n"); AssertFatal(size <= 1024, "memory corruption\n"); @@ -434,6 +436,7 @@ static void rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id_t .srb_id = CCCH }; rrc_instance_p->mac_rrc.dl_rrc_message_transfer(module_id, &dl_rrc); + return xid; } static void rrc_gNB_generate_RRCReject(module_id_t module_id, rrc_gNB_ue_context_t *const ue_context_pP) @@ -493,10 +496,10 @@ static void rrc_gNB_generate_defaultRRCReconfiguration(const protocol_ctxt_t *co //----------------------------------------------------------------------------- { gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; - uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id); - - /******************** Radio Bearer Config ********************/ gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; + AssertFatal(ue_p->nb_of_pdusessions == 0, "logic bug: PDU sessions present before RRC Connection established\n"); + uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id); + ue_p->xids[xid] = RRC_DEFAULT_RECONF; struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList *dedicatedNAS_MessageList = CALLOC(1, sizeof(*dedicatedNAS_MessageList)); @@ -583,9 +586,8 @@ static void rrc_gNB_generate_defaultRRCReconfiguration(const protocol_ctxt_t *co } } -void fill_DRB_configList(const protocol_ctxt_t *const ctxt_pP, - rrc_gNB_ue_context_t *ue_context_pP) { - +void fill_DRB_configList(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP, uint8_t xid) +{ gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; int qos_flow_index = 0; @@ -594,8 +596,6 @@ void fill_DRB_configList(const protocol_ctxt_t *const ctxt_pP, uint8_t nb_drb_to_setup = rrc->configuration.drbs; long drb_priority[NGAP_MAX_DRBS_PER_UE]; - int xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id); - if (!ue_p->DRB_configList) ue_p->DRB_configList = CALLOC(1, sizeof(*ue_p->DRB_configList)); else @@ -780,58 +780,53 @@ rrc_gNB_modify_dedicatedRRCReconfiguration( rrc_gNB_ue_context_t *ue_context_pP) //----------------------------------------------------------------------------- { - NR_DRB_ToAddMod_t *DRB_config = NULL; - NR_DRB_ToAddModList_t **DRB_configList = NULL; + NR_DRB_ToAddMod_t *DRB_config = NULL; NR_DRB_ToAddModList_t *DRB_configList2 = NULL; struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList *dedicatedNAS_MessageList = NULL; - NR_DedicatedNAS_Message_t *dedicatedNAS_Message = NULL; - int qos_flow_index = 0; - int i, j; - + int qos_flow_index = 0; uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id); gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; - DRB_configList = &ue_p->DRB_configList; + ue_p->xids[xid] = RRC_DEDICATED_RECONF; DRB_configList2 = CALLOC(1, sizeof(NR_DRB_ToAddModList_t)); memset(DRB_configList2, 0, sizeof(NR_DRB_ToAddModList_t)); dedicatedNAS_MessageList = CALLOC(1, sizeof(struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList)); - for (i = 0; i < ue_p->nb_of_modify_pdusessions; i++) { + for (int i = 0; i < ue_p->nb_of_pdusessions; i++) { // bypass the new and already configured pdu sessions - if (ue_p->modify_pdusession[i].status >= PDU_SESSION_STATUS_DONE) { - ue_p->modify_pdusession[i].xid = xid; + if (ue_p->pduSession[i].status >= PDU_SESSION_STATUS_DONE) { + ue_p->pduSession[i].xid = xid; continue; } - if (ue_p->modify_pdusession[i].cause != NGAP_CAUSE_NOTHING) { + if (ue_p->pduSession[i].cause != NGAP_CAUSE_NOTHING) { // set xid of failure pdu session - ue_p->modify_pdusession[i].xid = xid; - ue_p->modify_pdusession[i].status = PDU_SESSION_STATUS_FAILED; + ue_p->pduSession[i].xid = xid; + ue_p->pduSession[i].status = PDU_SESSION_STATUS_FAILED; continue; } // search exist DRB_config - for (j = 0; j < (*DRB_configList)->list.count; j++) { - if ((*DRB_configList)->list.array[j]->cnAssociation->choice.sdap_Config->pdu_Session == ue_p->modify_pdusession[i].param.pdusession_id) { - DRB_config = (*DRB_configList)->list.array[j]; + int j; + for (j = 0; i < NGAP_MAX_DRBS_PER_UE; j++) { + if (ue_p->established_drbs[j].status != DRB_INACTIVE + && ue_p->established_drbs[j].cnAssociation.sdap_config.pdusession_id == ue_p->pduSession[i].param.pdusession_id) break; - } } - if (DRB_config == NULL) { - ue_p->modify_pdusession[i].xid = xid; - ue_p->modify_pdusession[i].status = PDU_SESSION_STATUS_FAILED; - ue_p->modify_pdusession[i].cause = NGAP_CAUSE_RADIO_NETWORK; - ue_p->modify_pdusession[i].cause_value = NGAP_CauseRadioNetwork_unspecified; - ue_p->nb_of_failed_pdusessions++; + if (j == NGAP_MAX_DRBS_PER_UE) { + ue_p->pduSession[i].xid = xid; + ue_p->pduSession[i].status = PDU_SESSION_STATUS_FAILED; + ue_p->pduSession[i].cause = NGAP_CAUSE_RADIO_NETWORK; + ue_p->pduSession[i].cause_value = NGAP_CauseRadioNetwork_unspecified; continue; } // Reference TS23501 Table 5.7.4-1: Standardized 5QI to QoS characteristics mapping - for (qos_flow_index = 0; qos_flow_index < ue_p->modify_pdusession[i].param.nb_qos; qos_flow_index++) { - switch (ue_p->modify_pdusession[i].param.qos[qos_flow_index].fiveQI) { + for (qos_flow_index = 0; qos_flow_index < ue_p->pduSession[i].param.nb_qos; qos_flow_index++) { + switch (ue_p->pduSession[i].param.qos[qos_flow_index].fiveQI) { case 1: //100ms case 2: //150ms case 3: //50ms @@ -845,12 +840,11 @@ rrc_gNB_modify_dedicatedRRCReconfiguration( break; default: - LOG_E(NR_RRC, "not supported 5qi %lu\n", ue_p->modify_pdusession[i].param.qos[qos_flow_index].fiveQI); - ue_p->modify_pdusession[i].status = PDU_SESSION_STATUS_FAILED; - ue_p->modify_pdusession[i].xid = xid; - ue_p->modify_pdusession[i].cause = NGAP_CAUSE_RADIO_NETWORK; - ue_p->modify_pdusession[i].cause_value = NGAP_CauseRadioNetwork_not_supported_5QI_value; - ue_p->nb_of_failed_pdusessions++; + LOG_E(NR_RRC, "not supported 5qi %lu\n", ue_p->pduSession[i].param.qos[qos_flow_index].fiveQI); + ue_p->pduSession[i].status = PDU_SESSION_STATUS_FAILED; + ue_p->pduSession[i].xid = xid; + ue_p->pduSession[i].cause = NGAP_CAUSE_RADIO_NETWORK; + ue_p->pduSession[i].cause_value = NGAP_CauseRadioNetwork_not_supported_5QI_value; continue; } @@ -860,24 +854,20 @@ rrc_gNB_modify_dedicatedRRCReconfiguration( DRB_config->drb_Identity, i, qos_flow_index, - ue_p->modify_pdusession[i].param.qos[qos_flow_index].fiveQI); + ue_p->pduSession[i].param.qos[qos_flow_index].fiveQI); } asn1cSeqAdd(&DRB_configList2->list, DRB_config); - ue_p->modify_pdusession[i].status = PDU_SESSION_STATUS_DONE; - ue_p->modify_pdusession[i].xid = xid; + ue_p->pduSession[i].status = PDU_SESSION_STATUS_DONE; + ue_p->pduSession[i].xid = xid; - if (ue_p->modify_pdusession[i].param.nas_pdu.buffer != NULL) { - dedicatedNAS_Message = CALLOC(1, sizeof(NR_DedicatedNAS_Message_t)); - memset(dedicatedNAS_Message, 0, sizeof(OCTET_STRING_t)); - OCTET_STRING_fromBuf(dedicatedNAS_Message, (char *)ue_p->modify_pdusession[i].param.nas_pdu.buffer, ue_p->modify_pdusession[i].param.nas_pdu.length); - asn1cSeqAdd(&dedicatedNAS_MessageList->list, dedicatedNAS_Message); - - LOG_I(NR_RRC, "add NAS info with size %d (pdusession id %d)\n", ue_p->pduSession[i].param.nas_pdu.length, ue_p->modify_pdusession[i].param.pdusession_id); + if (ue_p->pduSession[i].param.nas_pdu.buffer != NULL) { + asn1cSequenceAdd(dedicatedNAS_MessageList->list,NR_DedicatedNAS_Message_t, dedicatedNAS_Message); + OCTET_STRING_fromBuf(dedicatedNAS_Message, (char *)ue_p->pduSession[i].param.nas_pdu.buffer, ue_p->pduSession[i].param.nas_pdu.length); + LOG_I(NR_RRC, "add NAS info with size %d (pdusession id %d)\n", ue_p->pduSession[i].param.nas_pdu.length, ue_p->pduSession[i].param.pdusession_id); } else { - // TODO - LOG_E(NR_RRC, "no NAS info (pdusession id %d)\n", ue_p->modify_pdusession[i].param.pdusession_id); + LOG_W(NR_RRC, "no NAS info (pdusession id %d)\n", ue_p->pduSession[i].param.pdusession_id); } } @@ -907,11 +897,11 @@ rrc_gNB_modify_dedicatedRRCReconfiguration( LOG_DUMPMSG(NR_RRC, DEBUG_RRC, (char *)buffer, size, "[MSG] RRC Reconfiguration\n"); /* Free all NAS PDUs */ - for (i = 0; i < ue_p->nb_of_modify_pdusessions; i++) { - if (ue_p->modify_pdusession[i].param.nas_pdu.buffer != NULL) { + for (int i = 0; i < ue_p->nb_of_pdusessions; i++) { + if (ue_p->pduSession[i].param.nas_pdu.buffer != NULL) { /* Free the NAS PDU buffer and invalidate it */ - free(ue_p->modify_pdusession[i].param.nas_pdu.buffer); - ue_p->modify_pdusession[i].param.nas_pdu.buffer = NULL; + free(ue_p->pduSession[i].param.nas_pdu.buffer); + ue_p->pduSession[i].param.nas_pdu.buffer = NULL; } } @@ -986,14 +976,24 @@ rrc_gNB_generate_dedicatedRRCReconfiguration_release( } uint8_t buffer[RRC_BUF_SIZE] = {0}; - int size = do_RRCReconfiguration(ctxt_pP, buffer, RRC_BUF_SIZE, xid, NULL, NULL, *DRB_Release_configList2, NULL, NULL, NULL, dedicatedNAS_MessageList, NULL, NULL, NULL, NULL, NULL); - - ue_p->pdu_session_release_command_flag = 1; - + int size = do_RRCReconfiguration(ctxt_pP, + buffer, + RRC_BUF_SIZE, + xid, + NULL, + NULL, + *DRB_Release_configList2, + NULL, + NULL, + NULL, + dedicatedNAS_MessageList, + NULL, + NULL, + NULL, + NULL, + NULL); LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)buffer,size, "[MSG] RRC Reconfiguration\n"); - ue_p->pdu_session_release_command_flag = 1; - /* Free all NAS PDUs */ if (nas_length > 0) { /* Free the NAS PDU buffer and invalidate it */ @@ -1207,16 +1207,18 @@ void rrc_gNB_generate_RRCReestablishment(const protocol_ctxt_t *ctxt_pP, SRB_configList = &(ue_p->SRB_configList); uint8_t buffer[RRC_BUF_SIZE] = {0}; + uint8_t xid = rrc_gNB_get_next_transaction_identifier(module_id); + ue_p->xids[xid] = RRC_REESTABLISH; int size = do_RRCReestablishment(ctxt_pP, - ue_context_pP, - CC_id, - buffer, - RRC_BUF_SIZE, - rrc_gNB_get_next_transaction_identifier(module_id), - SRB_configList, - masterCellGroup_from_DU, - scc, - &rrc->carrier); + ue_context_pP, + CC_id, + buffer, + RRC_BUF_SIZE, + xid, + SRB_configList, + masterCellGroup_from_DU, + scc, + &rrc->carrier); LOG_I(NR_RRC, "[RAPROC] UE %04x Logical Channel DL-DCCH, Generating NR_RRCReestablishment (bytes %d)\n", ue_p->rnti, size); @@ -1462,10 +1464,9 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx int i = 0; uint8_t new_xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id); + ue_p->xids[new_xid] = RRC_REESTABLISH_COMPLETE; ue_p->StatusRrc = NR_RRC_CONNECTED; ue_p->ue_rrc_inactivity_timer = 1; // set rrc inactivity when UE goes into RRC_CONNECTED - ue_p->reestablishment_xid = new_xid; - RRCReestablishmentComplete_fill_SRB2_configList(ctxt_pP, ue_context_pP, xid, new_xid); RRCReestablishmentComplete_fill_DRB_configList(ctxt_pP, ue_context_pP, new_xid); RRCReestablishmentComplete_update_ngu_tunnel(ctxt_pP, ue_context_pP, reestablish_rnti); @@ -1751,14 +1752,14 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, rnti_t rnti, const uint ((cause == NR_ReestablishmentCause_otherFailure) ? "Other Failure" : (cause == NR_ReestablishmentCause_handoverFailure) ? "Handover Failure" : "reconfigurationFailure")); - + uint8_t xid = -1; if (physCellId != gnb_rrc_inst->carrier.physCellId) { /* UE was moving from previous cell so quickly that RRCReestablishment for previous cell was received in this cell */ LOG_E(NR_RRC, " NR_RRCReestablishmentRequest ue_Identity.physCellId(%ld) is not equal to current physCellId(%d), fallback to RRC establishment\n", physCellId, gnb_rrc_inst->carrier.physCellId); - rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id, rnti, 0); + xid = rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id, rnti, 0); break; } @@ -1772,7 +1773,7 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, rnti_t rnti, const uint if (rrcReestablishmentRequest.ue_Identity.c_RNTI < 0x1 || rrcReestablishmentRequest.ue_Identity.c_RNTI > 0xffef) { /* c_RNTI range error should not happen */ LOG_E(NR_RRC, "NR_RRCReestablishmentRequest c_RNTI range error, fallback to RRC establishment\n"); - rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id, rnti, 0); + xid = rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id, rnti, 0); break; } @@ -1782,7 +1783,7 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, rnti_t rnti, const uint gNB_RRC_UE_t *UE = &ue_context_p->ue_context; if (ue_context_p == NULL) { LOG_E(NR_RRC, "NR_RRCReestablishmentRequest without UE context, fallback to RRC establishment\n"); - rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id, c_rnti, 0); + xid = rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id, c_rnti, 0); break; } // c-plane not end @@ -1797,7 +1798,7 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, rnti_t rnti, const uint UE->StatusRrc = NR_RRC_RECONFIGURED; protocol_ctxt_t ctxt_old_p; PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt_old_p, module_id, GNB_FLAG_YES, c_rnti, 0, 0); - rrc_gNB_process_RRCReconfigurationComplete(&ctxt_old_p, ue_context_p, UE->reestablishment_xid); + rrc_gNB_process_RRCReconfigurationComplete(&ctxt_old_p, ue_context_p, xid); for (uint8_t pdusessionid = 0; pdusessionid < UE->nb_of_pdusessions; pdusessionid++) { if (UE->pduSession[pdusessionid].status == PDU_SESSION_STATUS_DONE) { @@ -1814,8 +1815,6 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, rnti_t rnti, const uint UE->ue_reestablishment_timer = 0; // UE->ue_release_timer_s1 = 0; UE->ue_release_timer_rrc = 0; - UE->reestablishment_xid = -1; - // Insert C-RNTI to map for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) { nr_reestablish_rnti_map_t *nr_reestablish_rnti_map = &gnb_rrc_inst->nr_reestablish_rnti_map[i]; @@ -1899,21 +1898,259 @@ static void rrc_gNB_process_MeasurementReport(rrc_gNB_ue_context_t *ue_context, asn1cCallocOne(ue_ctxt->measResults, measurementReport->criticalExtensions.choice.measurementReport->measResults); } +static int handle_rrcReestablishmentComplete(const protocol_ctxt_t *const ctxt_pP, + const NR_RRCReestablishmentComplete_t *reestablishment_complete) +{ + rnti_t reestablish_rnti = 0; + gNB_RRC_INST *gnb_rrc_inst = RC.nrrrc[ctxt_pP->module_id]; + rrc_gNB_ue_context_t *ue_context_p = NULL; + gNB_RRC_UE_t *UE = NULL; + // Select C-RNTI from map + for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) { + nr_reestablish_rnti_map_t *nr_reestablish_rnti_map = &gnb_rrc_inst->nr_reestablish_rnti_map[i]; + LOG_I(NR_RRC, + "nr_reestablish_rnti_map[%d] UEid %lx, RNTI %04x, ctxt_pP->rntiMaybeUEid: %lx\n", + i, + nr_reestablish_rnti_map->ue_id, + nr_reestablish_rnti_map->c_rnti, + ctxt_pP->rntiMaybeUEid); + if (nr_reestablish_rnti_map->ue_id == ctxt_pP->rntiMaybeUEid) { + LOG_I(NR_RRC, + "Removing nr_reestablish_rnti_map[%d] UEid %lx, RNTI %04x\n", + i, + nr_reestablish_rnti_map->ue_id, + nr_reestablish_rnti_map->c_rnti); + reestablish_rnti = nr_reestablish_rnti_map->c_rnti; + ue_context_p = rrc_gNB_get_ue_context_by_rnti(gnb_rrc_inst, reestablish_rnti); + UE = &ue_context_p->ue_context; + break; + } + } + + if (ue_context_p == NULL || UE == NULL) { + LOG_E(RRC, "no UE found for reestablishment. ERROR: should send reply\n"); + return -1; + } + + DevAssert(reestablishment_complete->criticalExtensions.present + == NR_RRCReestablishmentComplete__criticalExtensions_PR_rrcReestablishmentComplete); + rrc_gNB_process_RRCReestablishmentComplete(ctxt_pP, + reestablish_rnti, + ue_context_p, + reestablishment_complete->rrc_TransactionIdentifier); + + nr_rrc_mac_remove_ue(reestablish_rnti); + + UE->ue_reestablishment_counter++; + + // UE->ue_release_timer = 0; + UE->ue_reestablishment_timer = 1; + // remove UE after 100 frames after NR_RRCReestablishmentRelease is triggered + UE->ue_reestablishment_timer_thres = 1000; + return 0; +} + +static int handle_ueCapabilityInformation(const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *ue_context_p, + const NR_UECapabilityInformation_t *ue_cap_info) +{ + AssertFatal(ue_context_p != NULL, "Processing %s() for UE %lx, ue_context_p is NULL\n", __func__, ctxt_pP->rntiMaybeUEid); + gNB_RRC_UE_t *UE = &ue_context_p->ue_context; + + LOG_I(NR_RRC, "got UE capabilities for UE %lx\n", ctxt_pP->rntiMaybeUEid); + int eutra_index = -1; + + if (ue_cap_info->criticalExtensions.present == NR_UECapabilityInformation__criticalExtensions_PR_ueCapabilityInformation) { + const NR_UE_CapabilityRAT_ContainerList_t *ue_CapabilityRAT_ContainerList = + ue_cap_info->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList; + for (int i = 0; i < ue_CapabilityRAT_ContainerList->list.count; i++) { + const NR_UE_CapabilityRAT_Container_t *ue_cap_container = ue_CapabilityRAT_ContainerList->list.array[i]; + if (ue_cap_container->rat_Type == NR_RAT_Type_nr) { + if (UE->UE_Capability_nr) { + ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability, UE->UE_Capability_nr); + UE->UE_Capability_nr = 0; + } + + asn_dec_rval_t dec_rval = uper_decode(NULL, + &asn_DEF_NR_UE_NR_Capability, + (void **)&UE->UE_Capability_nr, + ue_cap_container->ue_CapabilityRAT_Container.buf, + ue_cap_container->ue_CapabilityRAT_Container.size, + 0, + 0); + if (LOG_DEBUGFLAG(DEBUG_ASN1)) { + xer_fprint(stdout, &asn_DEF_NR_UE_NR_Capability, UE->UE_Capability_nr); + } + + if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { + LOG_E(NR_RRC, + PROTOCOL_NR_RRC_CTXT_UE_FMT " Failed to decode nr UE capabilities (%zu bytes)\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), + dec_rval.consumed); + ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability, UE->UE_Capability_nr); + UE->UE_Capability_nr = 0; + } + + UE->UE_Capability_size = ue_cap_container->ue_CapabilityRAT_Container.size; + if (eutra_index != -1) { + LOG_E(NR_RRC, "fatal: more than 1 eutra capability\n"); + exit(1); + } + eutra_index = i; + } + + if (ue_cap_container->rat_Type == NR_RAT_Type_eutra_nr) { + if (UE->UE_Capability_MRDC) { + ASN_STRUCT_FREE(asn_DEF_NR_UE_MRDC_Capability, UE->UE_Capability_MRDC); + UE->UE_Capability_MRDC = 0; + } + asn_dec_rval_t dec_rval = uper_decode(NULL, + &asn_DEF_NR_UE_MRDC_Capability, + (void **)&UE->UE_Capability_MRDC, + ue_cap_container->ue_CapabilityRAT_Container.buf, + ue_cap_container->ue_CapabilityRAT_Container.size, + 0, + 0); + + if (LOG_DEBUGFLAG(DEBUG_ASN1)) { + xer_fprint(stdout, &asn_DEF_NR_UE_MRDC_Capability, UE->UE_Capability_MRDC); + } + + if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { + LOG_E(NR_RRC, + PROTOCOL_NR_RRC_CTXT_FMT " Failed to decode nr UE capabilities (%zu bytes)\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), + dec_rval.consumed); + ASN_STRUCT_FREE(asn_DEF_NR_UE_MRDC_Capability, UE->UE_Capability_MRDC); + UE->UE_Capability_MRDC = 0; + } + UE->UE_MRDC_Capability_size = ue_cap_container->ue_CapabilityRAT_Container.size; + } + + if (ue_cap_container->rat_Type == NR_RAT_Type_eutra) { + // TODO + } + } + + if (eutra_index == -1) + return -1; + } + + if (get_softmodem_params()->sa) { + rrc_gNB_send_NGAP_UE_CAPABILITIES_IND(ctxt_pP, ue_context_p, ue_cap_info); + } + + // we send the UE capabilities request before RRC connection is complete, + // so we cannot have a PDU session yet + AssertFatal(UE->nb_of_pdusessions == 0, "logic bug: received capabilities while PDU session established\n"); + // TODO: send UE context modification response with UE capabilities to + // allow DU configure CellGroupConfig + rrc_gNB_generate_defaultRRCReconfiguration(ctxt_pP, ue_context_p); + + return 0; +} + +static int handle_rrcSetupComplete(const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *ue_context_p, + const NR_RRCSetupComplete_t *setup_complete) +{ + if (!ue_context_p) { + LOG_I(NR_RRC, "Processing NR_RRCSetupComplete UE %lx, ue_context_p is NULL\n", ctxt_pP->rntiMaybeUEid); + return -1; + } + gNB_RRC_UE_t *UE = &ue_context_p->ue_context; + + NR_RRCSetupComplete_IEs_t *setup_complete_ies = setup_complete->criticalExtensions.choice.rrcSetupComplete; + + if (setup_complete_ies->ng_5G_S_TMSI_Value != NULL) { + if (setup_complete_ies->ng_5G_S_TMSI_Value->present == NR_RRCSetupComplete_IEs__ng_5G_S_TMSI_Value_PR_ng_5G_S_TMSI_Part2) { + if (setup_complete_ies->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI_Part2.size != 2) { + LOG_E(NR_RRC, + "wrong ng_5G_S_TMSI_Part2 size, expected 2, provided %lu", + (long unsigned int) + setup_complete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI_Part2.size); + return -1; + } + + if (UE->ng_5G_S_TMSI_Part1 != 0) { + UE->ng_5G_S_TMSI_Part2 = BIT_STRING_to_uint16(&setup_complete_ies->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI_Part2); + } + + /* TODO */ + } else if (setup_complete_ies->ng_5G_S_TMSI_Value->present == NR_RRCSetupComplete_IEs__ng_5G_S_TMSI_Value_PR_ng_5G_S_TMSI) { + if (setup_complete_ies->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.size != 6) { + LOG_E(NR_RRC, + "wrong ng_5G_S_TMSI size, expected 6, provided %lu", + (long unsigned int)setup_complete_ies->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.size); + return -1; + } + + uint64_t fiveg_s_TMSI = bitStr_to_uint64(&setup_complete_ies->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI); + LOG_I(NR_RRC, + "Received rrcSetupComplete, 5g_s_TMSI: 0x%lX, amf_set_id: 0x%lX(%ld), amf_pointer: 0x%lX(%ld), 5g TMSI: 0x%X \n", + fiveg_s_TMSI, + fiveg_s_TMSI >> 38, + fiveg_s_TMSI >> 38, + (fiveg_s_TMSI >> 32) & 0x3F, + (fiveg_s_TMSI >> 32) & 0x3F, + (uint32_t)fiveg_s_TMSI); + if (UE->Initialue_identity_5g_s_TMSI.presence) { + UE->Initialue_identity_5g_s_TMSI.amf_set_id = fiveg_s_TMSI >> 38; + UE->Initialue_identity_5g_s_TMSI.amf_pointer = (fiveg_s_TMSI >> 32) & 0x3F; + UE->Initialue_identity_5g_s_TMSI.fiveg_tmsi = (uint32_t)fiveg_s_TMSI; + } + } + } + + rrc_gNB_process_RRCSetupComplete(ctxt_pP, ue_context_p, setup_complete->criticalExtensions.choice.rrcSetupComplete); + LOG_I(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT " UE State = NR_RRC_CONNECTED \n", PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); + + UE->ue_release_timer = 0; + return 0; +} + +static void handle_rrcReconfigurationComplete(const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *ue_context_p, + const NR_RRCReconfigurationComplete_t *reconfig_complete) +{ + LOG_I(NR_RRC, "Receive RRC Reconfiguration Complete message UE %lx\n", ctxt_pP->rntiMaybeUEid); + AssertFatal(ue_context_p != NULL, "Processing %s() for UE %lx, ue_context_p is NULL\n", __func__, ctxt_pP->rntiMaybeUEid); + gNB_RRC_UE_t *UE = &ue_context_p->ue_context; + + uint8_t xid = reconfig_complete->rrc_TransactionIdentifier; + rrc_gNB_process_RRCReconfigurationComplete(ctxt_pP, ue_context_p, xid); + + if (get_softmodem_params()->sa) { + switch (UE->xids[xid]) { + case RRC_PDUSESSION_RELEASE: { + gtpv1u_gnb_delete_tunnel_req_t req = {0}; + gtpv1u_delete_ngu_tunnel(ctxt_pP->instance, &req); + // NGAP_PDUSESSION_RELEASE_RESPONSE + rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(ctxt_pP, ue_context_p, xid); + } break; + case RRC_PDUSESSION_ESTABLISH: + if (UE->nb_of_pdusessions > 0) + rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(ctxt_pP, ue_context_p, xid); + break; + case RRC_PDUSESSION_MODIFY: + rrc_gNB_send_NGAP_PDUSESSION_MODIFY_RESP(ctxt_pP, ue_context_p, xid); + break; + case RRC_FIRST_RECONF: + rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(ctxt_pP, ue_context_p); + break; + default: + LOG_E(RRC, "Received unexpected xid: %d\n", xid); + } + } +} //----------------------------------------------------------------------------- -int -rrc_gNB_decode_dcch( - const protocol_ctxt_t *const ctxt_pP, - const rb_id_t Srb_id, - const uint8_t *const Rx_sdu, - const sdu_size_t sdu_sizeP -) +int rrc_gNB_decode_dcch(const protocol_ctxt_t *const ctxt_pP, + const rb_id_t Srb_id, + const uint8_t *const Rx_sdu, + const sdu_size_t sdu_sizeP) //----------------------------------------------------------------------------- { - asn_dec_rval_t dec_rval; - NR_UL_DCCH_Message_t *ul_dcch_msg = NULL; - uint8_t xid; gNB_RRC_INST *gnb_rrc_inst = RC.nrrrc[ctxt_pP->module_id]; - int i; if ((Srb_id != 1) && (Srb_id != 2)) { LOG_E(NR_RRC, "Received message on SRB%ld, should not have ...\n", Srb_id); @@ -1922,38 +2159,27 @@ rrc_gNB_decode_dcch( } LOG_D(NR_RRC, "Decoding UL-DCCH Message\n"); - - //for (int i=0;irntiMaybeUEid); - gNB_RRC_UE_t *UE = &ue_context_p->ue_context; if (ul_dcch_msg->message.present == NR_UL_DCCH_MessageType_PR_c1) { switch (ul_dcch_msg->message.choice.c1->present) { @@ -1962,148 +2188,12 @@ rrc_gNB_decode_dcch( break; case NR_UL_DCCH_MessageType__c1_PR_rrcReconfigurationComplete: - LOG_I(NR_RRC, "Receive RRC Reconfiguration Complete message UE %lx\n", ctxt_pP->rntiMaybeUEid); - if(!ue_context_p) { - LOG_E(NR_RRC, "Processing NR_RRCReconfigurationComplete UE %lx, ue_context_p is NULL\n", ctxt_pP->rntiMaybeUEid); - break; - } - - LOG_DUMPMSG(NR_RRC, DEBUG_RRC, (char *)(Rx_sdu), sdu_sizeP, - "[MSG] RRC Connection Reconfiguration Complete\n"); - LOG_D(NR_RRC, - PROTOCOL_NR_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes " - "(RRCReconfigurationComplete) ---> RRC_gNB]\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), - DCCH, - sdu_sizeP); - - if (ul_dcch_msg->message.choice.c1->present == NR_UL_DCCH_MessageType__c1_PR_rrcReconfigurationComplete) { - if (ul_dcch_msg->message.choice.c1->choice.rrcReconfigurationComplete->criticalExtensions.present == - NR_RRCReconfigurationComplete__criticalExtensions_PR_rrcReconfigurationComplete) - rrc_gNB_process_RRCReconfigurationComplete( - ctxt_pP, - ue_context_p, - ul_dcch_msg->message.choice.c1->choice.rrcReconfigurationComplete->rrc_TransactionIdentifier); - } - - if (get_softmodem_params()->sa) { - if (UE->pdu_session_release_command_flag == 1) { - xid = ul_dcch_msg->message.choice.c1->choice.rrcReconfigurationComplete->rrc_TransactionIdentifier; - UE->pdu_session_release_command_flag = 0; - //gtp tunnel delete - gtpv1u_gnb_delete_tunnel_req_t req={0}; - for(i = 0; i < NB_RB_MAX; i++) { - if (xid == UE->pduSession[i].xid) { - req.pdusession_id[req.num_pdusession++] = UE->gnb_gtp_psi[i]; - UE->gnb_gtp_teid[i] = 0; - memset(&UE->gnb_gtp_addrs[i], 0, sizeof(UE->gnb_gtp_addrs[i])); - UE->gnb_gtp_psi[i] = 0; - } - } - gtpv1u_delete_ngu_tunnel(ctxt_pP->instance, &req); - //NGAP_PDUSESSION_RELEASE_RESPONSE - rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(ctxt_pP, ue_context_p, xid); - } else if (UE->established_pdu_sessions_flag != 1) { - if (UE->reestablishment_xid < 0) { - if (UE->nb_of_pdusessions > 0) { - rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(ctxt_pP, ue_context_p, ul_dcch_msg->message.choice.c1->choice.rrcReconfigurationComplete->rrc_TransactionIdentifier); - } - } else { - UE->reestablishment_xid = -1; - } - } - if (UE->nb_of_modify_pdusessions > 0) { - rrc_gNB_send_NGAP_PDUSESSION_MODIFY_RESP(ctxt_pP, - ue_context_p, - ul_dcch_msg->message.choice.c1->choice.rrcReconfigurationComplete->rrc_TransactionIdentifier); - UE->nb_of_modify_pdusessions = 0; - UE->nb_of_failed_pdusessions = 0; - memset(UE->modify_pdusession, 0, sizeof(UE->modify_pdusession)); - - for(int i = 0; i < NR_NB_RB_MAX; i++) { - UE->modify_pdusession[i].xid = -1; - } - } - } - if (first_rrcreconfiguration == 0){ - first_rrcreconfiguration = 1; - rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(ctxt_pP, ue_context_p); - } - + handle_rrcReconfigurationComplete(ctxt_pP, ue_context_p, ul_dcch_msg->message.choice.c1->choice.rrcReconfigurationComplete); break; case NR_UL_DCCH_MessageType__c1_PR_rrcSetupComplete: - if(!ue_context_p) { - LOG_I(NR_RRC, "Processing NR_RRCSetupComplete UE %lx, ue_context_p is NULL\n", ctxt_pP->rntiMaybeUEid); - break; - } - - LOG_DUMPMSG(NR_RRC, DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP, - "[MSG] RRC SetupComplete\n"); - LOG_D(NR_RRC, - PROTOCOL_NR_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes " - "(RRCSetupComplete) ---> RRC_gNB\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), - DCCH, - sdu_sizeP); - - if (ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete->criticalExtensions.present == - NR_RRCSetupComplete__criticalExtensions_PR_rrcSetupComplete) { - if (ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete->criticalExtensions.choice. - rrcSetupComplete->ng_5G_S_TMSI_Value != NULL) { - if (ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete->criticalExtensions.choice. - rrcSetupComplete->ng_5G_S_TMSI_Value->present == NR_RRCSetupComplete_IEs__ng_5G_S_TMSI_Value_PR_ng_5G_S_TMSI_Part2) { - // ng-5G-S-TMSI-Part2 BIT STRING (SIZE (9)) - if (ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete->criticalExtensions.choice. - rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI_Part2.size != 2) { - LOG_E(NR_RRC, "wrong ng_5G_S_TMSI_Part2 size, expected 2, provided %lu", - (long unsigned int)ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete-> - criticalExtensions.choice.rrcSetupComplete-> - ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI_Part2.size); - return -1; - } - - if (UE->ng_5G_S_TMSI_Part1 != 0) { - UE->ng_5G_S_TMSI_Part2 = - BIT_STRING_to_uint16(&ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI_Part2); - } - - /* TODO */ - } else if (ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete->criticalExtensions.choice. - rrcSetupComplete->ng_5G_S_TMSI_Value->present == NR_RRCSetupComplete_IEs__ng_5G_S_TMSI_Value_PR_ng_5G_S_TMSI) { - // NG-5G-S-TMSI ::= BIT STRING (SIZE (48)) - if (ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete->criticalExtensions.choice. - rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.size != 6) { - LOG_E(NR_RRC, "wrong ng_5G_S_TMSI size, expected 6, provided %lu", - (long unsigned int)ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete-> - criticalExtensions.choice.rrcSetupComplete-> - ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.size); - return -1; - } - - uint64_t fiveg_s_TMSI = bitStr_to_uint64(&ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete-> - criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI); - LOG_I(NR_RRC, "Received rrcSetupComplete, 5g_s_TMSI: 0x%lX, amf_set_id: 0x%lX(%ld), amf_pointer: 0x%lX(%ld), 5g TMSI: 0x%X \n", - fiveg_s_TMSI, fiveg_s_TMSI >> 38, fiveg_s_TMSI >> 38, - (fiveg_s_TMSI >> 32) & 0x3F, (fiveg_s_TMSI >> 32) & 0x3F, - (uint32_t)fiveg_s_TMSI); - if (UE->Initialue_identity_5g_s_TMSI.presence == true) { - UE->Initialue_identity_5g_s_TMSI.amf_set_id = fiveg_s_TMSI >> 38; - UE->Initialue_identity_5g_s_TMSI.amf_pointer = (fiveg_s_TMSI >> 32) & 0x3F; - UE->Initialue_identity_5g_s_TMSI.fiveg_tmsi = (uint32_t)fiveg_s_TMSI; - } - } - } - - rrc_gNB_process_RRCSetupComplete( - ctxt_pP, - ue_context_p, - ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete->criticalExtensions.choice.rrcSetupComplete); - LOG_I(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" UE State = NR_RRC_CONNECTED \n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); - } - - UE->ue_release_timer = 0; + if (handle_rrcSetupComplete(ctxt_pP, ue_context_p, ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete) == -1) + return -1; break; case NR_UL_DCCH_MessageType__c1_PR_measurementReport: @@ -2114,43 +2204,41 @@ rrc_gNB_decode_dcch( rrc_gNB_process_MeasurementReport(ue_context_p, ul_dcch_msg->message.choice.c1->choice.measurementReport); break; - case NR_UL_DCCH_MessageType__c1_PR_ulInformationTransfer: - LOG_I(NR_RRC,"Recived RRC GNB UL Information Transfer \n"); - if(!ue_context_p) { - LOG_I(NR_RRC, "Processing ulInformationTransfer UE %lx, ue_context_p is NULL\n", ctxt_pP->rntiMaybeUEid); - break; - } + case NR_UL_DCCH_MessageType__c1_PR_ulInformationTransfer: + LOG_I(NR_RRC, "Recived RRC GNB UL Information Transfer \n"); + if (!ue_context_p) { + LOG_I(NR_RRC, "Processing ulInformationTransfer UE %lx, ue_context_p is NULL\n", ctxt_pP->rntiMaybeUEid); + break; + } - LOG_D(NR_RRC,"[MSG] RRC UL Information Transfer \n"); - LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP, - "[MSG] RRC UL Information Transfer \n"); + LOG_D(NR_RRC, "[MSG] RRC UL Information Transfer \n"); + LOG_DUMPMSG(RRC, DEBUG_RRC, (char *)Rx_sdu, sdu_sizeP, "[MSG] RRC UL Information Transfer \n"); - if (get_softmodem_params()->sa) { - rrc_gNB_send_NGAP_UPLINK_NAS(ctxt_pP, - ue_context_p, - ul_dcch_msg); - } - break; + if (get_softmodem_params()->sa) { + rrc_gNB_send_NGAP_UPLINK_NAS(ctxt_pP, ue_context_p, ul_dcch_msg); + } + break; - case NR_UL_DCCH_MessageType__c1_PR_securityModeComplete: + case NR_UL_DCCH_MessageType__c1_PR_securityModeComplete: // to avoid segmentation fault - if(!ue_context_p) { - LOG_I(NR_RRC, "Processing securityModeComplete UE %lx, ue_context_p is NULL\n", ctxt_pP->rntiMaybeUEid); - break; - } + if (!ue_context_p) { + LOG_I(NR_RRC, "Processing securityModeComplete UE %lx, ue_context_p is NULL\n", ctxt_pP->rntiMaybeUEid); + break; + } LOG_I(NR_RRC, - PROTOCOL_NR_RRC_CTXT_UE_FMT" received securityModeComplete on UL-DCCH %d from UE\n", + PROTOCOL_NR_RRC_CTXT_UE_FMT " received securityModeComplete on UL-DCCH %d from UE\n", PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), DCCH); LOG_D(NR_RRC, - PROTOCOL_NR_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes " + PROTOCOL_NR_RRC_CTXT_UE_FMT + " RLC RB %02d --- RLC_DATA_IND %d bytes " "(securityModeComplete) ---> RRC_eNB\n", PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), DCCH, sdu_sizeP); - if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + if (LOG_DEBUGFLAG(DEBUG_ASN1)) { xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)ul_dcch_msg); } @@ -2159,238 +2247,35 @@ rrc_gNB_decode_dcch( rrc_gNB_generate_UECapabilityEnquiry(ctxt_pP, ue_context_p); break; - case NR_UL_DCCH_MessageType__c1_PR_securityModeFailure: - LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP, - "[MSG] NR RRC Security Mode Failure\n"); - LOG_W(NR_RRC, - PROTOCOL_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes " - "(securityModeFailure) ---> RRC_gNB\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), - DCCH, - sdu_sizeP); - - if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)ul_dcch_msg); - } - - rrc_gNB_generate_UECapabilityEnquiry(ctxt_pP, ue_context_p); - break; + + case NR_UL_DCCH_MessageType__c1_PR_securityModeFailure: + LOG_DUMPMSG(NR_RRC, DEBUG_RRC, (char *)Rx_sdu, sdu_sizeP, "[MSG] NR RRC Security Mode Failure\n"); + LOG_W(NR_RRC, + PROTOCOL_RRC_CTXT_UE_FMT + " RLC RB %02d --- RLC_DATA_IND %d bytes " + "(securityModeFailure) ---> RRC_gNB\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), + DCCH, + sdu_sizeP); + + if (LOG_DEBUGFLAG(DEBUG_ASN1)) { + xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)ul_dcch_msg); + } + + rrc_gNB_generate_UECapabilityEnquiry(ctxt_pP, ue_context_p); + break; case NR_UL_DCCH_MessageType__c1_PR_ueCapabilityInformation: - if(!ue_context_p) { - LOG_I(NR_RRC, "Processing ueCapabilityInformation UE %lx, ue_context_p is NULL\n", ctxt_pP->rntiMaybeUEid); - break; - } + if (handle_ueCapabilityInformation(ctxt_pP, ue_context_p, ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation) + == -1) + return -1; + break; - LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP, - "[MSG] NR_RRC UECapablility Information\n"); - LOG_I(NR_RRC, - PROTOCOL_NR_RRC_CTXT_UE_FMT" received ueCapabilityInformation on UL-DCCH %d from UE\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), - DCCH); - LOG_D(RRC, - PROTOCOL_NR_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes " - "(UECapabilityInformation) ---> RRC_eNB\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), - DCCH, - sdu_sizeP); - if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)ul_dcch_msg); - } - LOG_I(NR_RRC, "got UE capabilities for UE %lx\n", ctxt_pP->rntiMaybeUEid); - int eutra_index = -1; - - if( ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.present == - NR_UECapabilityInformation__criticalExtensions_PR_ueCapabilityInformation ) { - for(i = 0;i < ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.count; i++){ - if(ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i]->rat_Type == - NR_RAT_Type_nr){ - if (UE->UE_Capability_nr) { - ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability, UE->UE_Capability_nr); - UE->UE_Capability_nr = 0; - } - - dec_rval = uper_decode(NULL, - &asn_DEF_NR_UE_NR_Capability, - (void **)&UE->UE_Capability_nr, - ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i] - ->ue_CapabilityRAT_Container.buf, - ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i] - ->ue_CapabilityRAT_Container.size, - 0, - 0); - if(LOG_DEBUGFLAG(DEBUG_ASN1)){ - xer_fprint(stdout, &asn_DEF_NR_UE_NR_Capability, UE->UE_Capability_nr); - } - - if((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)){ - LOG_E(NR_RRC,PROTOCOL_NR_RRC_CTXT_UE_FMT" Failed to decode nr UE capabilities (%zu bytes)\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),dec_rval.consumed); - ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability, UE->UE_Capability_nr); - UE->UE_Capability_nr = 0; - } - - UE->UE_Capability_size = ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i] - ->ue_CapabilityRAT_Container.size; - if(eutra_index != -1){ - LOG_E(NR_RRC,"fatal: more than 1 eutra capability\n"); - exit(1); - } - eutra_index = i; - } - - if(ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i]->rat_Type == - NR_RAT_Type_eutra_nr){ - if (UE->UE_Capability_MRDC) { - ASN_STRUCT_FREE(asn_DEF_NR_UE_MRDC_Capability, UE->UE_Capability_MRDC); - UE->UE_Capability_MRDC = 0; - } - dec_rval = uper_decode(NULL, - &asn_DEF_NR_UE_MRDC_Capability, - (void **)&UE->UE_Capability_MRDC, - ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i] - ->ue_CapabilityRAT_Container.buf, - ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i] - ->ue_CapabilityRAT_Container.size, - 0, - 0); - - if (LOG_DEBUGFLAG(DEBUG_ASN1)) { - xer_fprint(stdout, &asn_DEF_NR_UE_MRDC_Capability, UE->UE_Capability_MRDC); - } - - if((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)){ - LOG_E(NR_RRC,PROTOCOL_NR_RRC_CTXT_FMT" Failed to decode nr UE capabilities (%zu bytes)\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),dec_rval.consumed); - ASN_STRUCT_FREE(asn_DEF_NR_UE_MRDC_Capability, UE->UE_Capability_MRDC); - UE->UE_Capability_MRDC = 0; - } - UE->UE_MRDC_Capability_size = - ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i] - ->ue_CapabilityRAT_Container.size; - } - - if(ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i]->rat_Type == - NR_RAT_Type_eutra){ - //TODO - } - } - - if(eutra_index == -1) - break; - } - if (get_softmodem_params()->sa) { - rrc_gNB_send_NGAP_UE_CAPABILITIES_IND(ctxt_pP, - ue_context_p, - ul_dcch_msg); - } - - if (!NODE_IS_CU(gnb_rrc_inst->node_type)) { - if (UE->established_pdu_sessions_flag == 1) { - rrc_gNB_generate_dedicatedRRCReconfiguration(ctxt_pP, ue_context_p, NULL); - } else { - rrc_gNB_generate_defaultRRCReconfiguration(ctxt_pP, ue_context_p); - } - } else { - /*Generate a UE context setup request message towards the DU to provide the UE - *capability info and get the updates on master cell group config from the DU*/ - MessageDef *message_p; - message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_SETUP_REQ); - f1ap_ue_context_setup_t *req=&F1AP_UE_CONTEXT_SETUP_REQ (message_p); - //UE_IDs will be extracted from F1AP layer - req->gNB_CU_ue_id = 0; - req->gNB_DU_ue_id = 0; - req->rnti = UE->rnti; - req->mcc = gnb_rrc_inst->configuration.mcc[0]; - req->mnc = gnb_rrc_inst->configuration.mnc[0]; - req->mnc_digit_length = gnb_rrc_inst->configuration.mnc_digit_length[0]; - req->nr_cellid = gnb_rrc_inst->nr_cellid; - - if (UE->established_pdu_sessions_flag == 1) { - /*Instruction towards the DU for SRB2 configuration*/ - req->srbs_to_be_setup = malloc(1*sizeof(f1ap_srb_to_be_setup_t)); - req->srbs_to_be_setup_length = 1; - f1ap_srb_to_be_setup_t *SRBs=req->srbs_to_be_setup; - SRBs[0].srb_id = 2; - SRBs[0].lcid = 2; - - /*Instruction towards the DU for DRB configuration and tunnel creation*/ - req->drbs_to_be_setup = malloc(1*sizeof(f1ap_drb_to_be_setup_t)); - req->drbs_to_be_setup_length = 1; - f1ap_drb_to_be_setup_t *DRBs=req->drbs_to_be_setup; - LOG_I(RRC, "Length of DRB list:%d \n", req->drbs_to_be_setup_length); - DRBs[0].drb_id = 1; - DRBs[0].rlc_mode = RLC_MODE_AM; - DRBs[0].up_ul_tnl[0].tl_address = inet_addr(gnb_rrc_inst->eth_params_s.my_addr); - DRBs[0].up_ul_tnl[0].port = gnb_rrc_inst->eth_params_s.my_portd; - DRBs[0].up_ul_tnl_length = 1; - DRBs[0].up_dl_tnl[0].tl_address = inet_addr(gnb_rrc_inst->eth_params_s.remote_addr); - DRBs[0].up_dl_tnl[0].port = gnb_rrc_inst->eth_params_s.remote_portd; - DRBs[0].up_dl_tnl_length = 1; - } - if( ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.present == - NR_UECapabilityInformation__criticalExtensions_PR_ueCapabilityInformation ) { - struct NR_UE_CapabilityRAT_ContainerList *ue_CapabilityRAT_ContainerList = - ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList; - if(ue_CapabilityRAT_ContainerList!=NULL){ - LOG_I(NR_RRC, "ue_CapabilityRAT_ContainerList is present \n"); - req->cu_to_du_rrc_information = calloc(1,sizeof(cu_to_du_rrc_information_t)); - req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList = calloc(1,4096); - asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UE_CapabilityRAT_ContainerList, - NULL, - ue_CapabilityRAT_ContainerList, - req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList, - 4096); - AssertFatal (enc_rval.encoded > 0, "ASN1 ue_CapabilityRAT_ContainerList encoding failed (%s, %jd)!\n", - enc_rval.failed_type->name, enc_rval.encoded); - req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList_length = (enc_rval.encoded+7)>>3; - } - else{ - LOG_I(NR_RRC, "ue_CapabilityRAT_ContainerList is not present \n"); - } - } - itti_send_msg_to_task (TASK_CU_F1, ctxt_pP->module_id, message_p); - } - - break; - - case NR_UL_DCCH_MessageType__c1_PR_rrcReestablishmentComplete: { - LOG_DUMPMSG(NR_RRC, DEBUG_RRC, (char *)Rx_sdu, sdu_sizeP, "[MSG] NR_RRC Connection Reestablishment Complete\n"); - LOG_I(NR_RRC, "RLC RB %02d --- RLC_DATA_IND %d bytes (rrcReestablishmentComplete) ---> RRC_gNB\n", DCCH, sdu_sizeP); - - rnti_t reestablish_rnti = 0; - - // Select C-RNTI from map - for (i = 0; i < MAX_MOBILES_PER_GNB; i++) { - nr_reestablish_rnti_map_t *nr_reestablish_rnti_map = &gnb_rrc_inst->nr_reestablish_rnti_map[i]; - LOG_I(NR_RRC, "nr_reestablish_rnti_map[%d] UEid %lx, RNTI %04x, ctxt_pP->rntiMaybeUEid: %lx\n", i, nr_reestablish_rnti_map->ue_id, nr_reestablish_rnti_map->c_rnti, ctxt_pP->rntiMaybeUEid); - if (nr_reestablish_rnti_map->ue_id == ctxt_pP->rntiMaybeUEid) { - LOG_I(NR_RRC, "Removing nr_reestablish_rnti_map[%d] UEid %lx, RNTI %04x\n", i, nr_reestablish_rnti_map->ue_id, nr_reestablish_rnti_map->c_rnti); - reestablish_rnti = nr_reestablish_rnti_map->c_rnti; - ue_context_p = rrc_gNB_get_ue_context_by_rnti(gnb_rrc_inst, reestablish_rnti); - UE = &ue_context_p->ue_context; - break; - } - } - - if (!ue_context_p) { - LOG_E(NR_RRC, "NR_RRCReestablishmentComplete without UE context, fault\n"); - break; - } - - if (ul_dcch_msg->message.choice.c1->choice.rrcReestablishmentComplete->criticalExtensions.present == NR_RRCReestablishmentComplete__criticalExtensions_PR_rrcReestablishmentComplete) { - rrc_gNB_process_RRCReestablishmentComplete(ctxt_pP, reestablish_rnti, ue_context_p, ul_dcch_msg->message.choice.c1->choice.rrcReestablishmentComplete->rrc_TransactionIdentifier); - - nr_rrc_mac_remove_ue(reestablish_rnti); - - UE->ue_reestablishment_counter++; - } - - // UE->ue_release_timer = 0; - UE->ue_reestablishment_timer = 1; - // remove UE after 100 frames after NR_RRCReestablishmentRelease is triggered - UE->ue_reestablishment_timer_thres = 1000; - } break; + case NR_UL_DCCH_MessageType__c1_PR_rrcReestablishmentComplete: + if (handle_rrcReestablishmentComplete(ctxt_pP, ul_dcch_msg->message.choice.c1->choice.rrcReestablishmentComplete) + == -1) + return -1; + break; default: break; @@ -2525,233 +2410,6 @@ void rrc_gNB_process_dc_overall_timeout(const module_id_t gnb_mod_idP, x2ap_ENDC rrc_remove_nsa_user(rrc, m->rnti); } -static void rrc_DU_process_ue_context_setup_request(MessageDef *msg_p, instance_t instance) -{ - f1ap_ue_context_setup_t * req=&F1AP_UE_CONTEXT_SETUP_REQ(msg_p); - gNB_RRC_INST *rrc = RC.nrrrc[instance]; - gNB_MAC_INST *mac = RC.nrmac[instance]; - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, req->rnti); - gNB_RRC_UE_t *UE = &ue_context_p->ue_context; - MessageDef *message_p; - message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_SETUP_RESP); - f1ap_ue_context_setup_t * resp=&F1AP_UE_CONTEXT_SETUP_RESP(message_p); - uint32_t incoming_teid = 0; - - if(req->cu_to_du_rrc_information!=NULL){ - if(req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList!=NULL){ - LOG_I(NR_RRC, "Length of ue_CapabilityRAT_ContainerList is: %d \n", (int) req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList_length); - struct NR_UE_CapabilityRAT_ContainerList *ue_CapabilityRAT_ContainerList = NULL; - asn_dec_rval_t dec_rval = uper_decode_complete( NULL, - &asn_DEF_NR_UE_CapabilityRAT_ContainerList, - (void **)&ue_CapabilityRAT_ContainerList, - (uint8_t *)req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList, - (int) req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList_length); - - if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { - AssertFatal(1==0,"UE Capability RAT ContainerList decode error\n"); - // free the memory - SEQUENCE_free( &asn_DEF_NR_UE_CapabilityRAT_ContainerList, ue_CapabilityRAT_ContainerList, 1 ); - return; - } - //To fill ue_context.UE_Capability_MRDC, ue_context.UE_Capability_nr ... - int NR_index = -1; - for(int i = 0;i < ue_CapabilityRAT_ContainerList->list.count; i++){ - if(ue_CapabilityRAT_ContainerList->list.array[i]->rat_Type == - NR_RAT_Type_nr){ - LOG_I(NR_RRC, "DU received NR_RAT_Type_nr UE capabilities Info through the UE Context Setup Request from the CU \n"); - if (UE->UE_Capability_nr) { - ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability, UE->UE_Capability_nr); - UE->UE_Capability_nr = 0; - } - - dec_rval = uper_decode(NULL, - &asn_DEF_NR_UE_NR_Capability, - (void **)&UE->UE_Capability_nr, - ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.buf, - ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.size, - 0, - 0); - if(LOG_DEBUGFLAG(DEBUG_ASN1)){ - xer_fprint(stdout, &asn_DEF_NR_UE_NR_Capability, UE->UE_Capability_nr); - } - - if((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)){ - LOG_E(NR_RRC, "UE %04x Failed to decode nr UE capabilities (%zu bytes)\n", req->rnti, dec_rval.consumed); - ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability, UE->UE_Capability_nr); - UE->UE_Capability_nr = 0; - } - - UE->UE_Capability_size = ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.size; - if(NR_index != -1){ - LOG_E(NR_RRC,"fatal: more than 1 eutra capability\n"); - exit(1); - } - NR_index = i; - } - - if(ue_CapabilityRAT_ContainerList->list.array[i]->rat_Type == - NR_RAT_Type_eutra_nr){ - LOG_I(NR_RRC, "DU received NR_RAT_Type_eutra_nr UE capabilities Info through the UE Context Setup Request from the CU \n"); - if (UE->UE_Capability_MRDC) { - ASN_STRUCT_FREE(asn_DEF_NR_UE_MRDC_Capability, UE->UE_Capability_MRDC); - UE->UE_Capability_MRDC = 0; - } - dec_rval = uper_decode(NULL, - &asn_DEF_NR_UE_MRDC_Capability, - (void **)&UE->UE_Capability_MRDC, - ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.buf, - ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.size, - 0, - 0); - if(LOG_DEBUGFLAG(DEBUG_ASN1)){ - xer_fprint(stdout, &asn_DEF_NR_UE_MRDC_Capability, UE->UE_Capability_MRDC); - } - - if((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)){ - LOG_E(NR_RRC, "UE %04x Failed to decode nr UE capabilities (%zu bytes)\n", req->rnti, dec_rval.consumed); - ASN_STRUCT_FREE(asn_DEF_NR_UE_MRDC_Capability, UE->UE_Capability_MRDC); - UE->UE_Capability_MRDC = 0; - } - UE->UE_MRDC_Capability_size = ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.size; - } - - if(ue_CapabilityRAT_ContainerList->list.array[i]->rat_Type == - NR_RAT_Type_eutra){ - //TODO - } - } - } - } - - - /* Configure SRB2 */ - NR_SRB_ToAddMod_t *SRB2_config = NULL; - NR_SRB_ToAddModList_t *SRB_configList = NULL; - uint8_t SRBs_before_new_addition = 0; - - if(req->srbs_to_be_setup_length>0){ - if (UE->SRB_configList == NULL) { - LOG_W(NR_RRC, "The SRB list of the UE context is empty before the addition of new SRB at the DU \n"); - UE->SRB_configList = CALLOC(1, sizeof(*UE->SRB_configList)); - } - SRB_configList = UE->SRB_configList; - SRBs_before_new_addition = SRB_configList->list.count; - for (int i=0; isrbs_to_be_setup_length; i++){ - SRB2_config = CALLOC(1, sizeof(*SRB2_config)); - SRB2_config->srb_Identity = req->srbs_to_be_setup[i].srb_id; - asn1cSeqAdd(&SRB_configList->list, SRB2_config); - } - } - - /* Configure DRB */ - NR_DRB_ToAddMod_t *DRB_config = NULL; - NR_DRB_ToAddModList_t *DRB_configList = NULL; - uint8_t drb_id_to_setup_start = 0; - uint8_t nb_drb_to_setup = 0; - long drb_priority[NGAP_MAX_DRBS_PER_UE]; - if(req->drbs_to_be_setup_length>0){ - if (UE->DRB_configList == NULL) { - UE->DRB_configList = CALLOC(1, sizeof(*UE->DRB_configList)); - } - DRB_configList = UE->DRB_configList; - nb_drb_to_setup = req->drbs_to_be_setup_length; - for (int i=0; idrbs_to_be_setup_length; i++){ - DRB_config = CALLOC(1, sizeof(*DRB_config)); - DRB_config->drb_Identity = req->drbs_to_be_setup[i].drb_id; - if (drb_id_to_setup_start == 0) drb_id_to_setup_start = DRB_config->drb_Identity; - asn1cSeqAdd(&DRB_configList->list, DRB_config); - f1ap_drb_to_be_setup_t drb_p = req->drbs_to_be_setup[i]; - transport_layer_addr_t addr; - memcpy(addr.buffer, &drb_p.up_ul_tnl[0].tl_address, sizeof(drb_p.up_ul_tnl[0].tl_address)); - addr.length=sizeof(drb_p.up_ul_tnl[0].tl_address)*8; - extern instance_t DUuniqInstance; - incoming_teid = newGtpuCreateTunnel(DUuniqInstance, - req->rnti, - drb_p.drb_id, - drb_p.drb_id, - drb_p.up_ul_tnl[0].teid, - -1, // no qfi - addr, - drb_p.up_ul_tnl[0].port, - DURecvCb, - NULL); - /* TODO: hardcoded to 13 for the time being, to be changed? */ - drb_priority[DRB_config->drb_Identity-1] = 13; - } - } - - NR_CellGroupConfig_t *cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t)); - if (req->srbs_to_be_setup_length > 0 || req->drbs_to_be_setup_length>0) - // FIXME: fill_mastercellGroupConfig() won't fill the right priorities or - // bearer IDs for the DRBs - fill_mastercellGroupConfig(cellGroupConfig, UE->masterCellGroup, rrc->um_on_default_drb, SRB2_config ? 1 : 0, drb_id_to_setup_start, nb_drb_to_setup, drb_priority); - protocol_ctxt_t ctxt = {.rntiMaybeUEid = req->rnti, .module_id = instance, .instance = instance, .enb_flag = 1, .eNB_index = instance}; - apply_macrlc_config(rrc, ue_context_p, &ctxt); - - if(req->rrc_container_length > 0){ - mem_block_t *pdcp_pdu_p = get_free_mem_block(req->rrc_container_length, __func__); - memcpy(&pdcp_pdu_p->data[0], req->rrc_container, req->rrc_container_length); - du_rlc_data_req(&ctxt, 1, 0x00, 1, 1, 0, req->rrc_container_length, pdcp_pdu_p); - LOG_I(F1AP, "Printing RRC Container of UE context setup request: \n"); - for (int j=0; jrrc_container_length; j++){ - printf("%02x ", pdcp_pdu_p->data[j]); - } - printf("\n"); - } - - /* Fill the UE context setup response ITTI message to send to F1AP */ - resp->gNB_CU_ue_id = req->gNB_CU_ue_id; - resp->rnti = req->rnti; - if(DRB_configList){ - if(DRB_configList->list.count > 0){ - resp->drbs_to_be_setup = calloc(1,DRB_configList->list.count*sizeof(f1ap_drb_to_be_setup_t)); - resp->drbs_to_be_setup_length = DRB_configList->list.count; - for (int i=0; ilist.count; i++){ - resp->drbs_to_be_setup[i].drb_id = DRB_configList->list.array[i]->drb_Identity; - resp->drbs_to_be_setup[i].rlc_mode = RLC_MODE_AM; - resp->drbs_to_be_setup[i].up_dl_tnl[0].teid = incoming_teid; - resp->drbs_to_be_setup[i].up_dl_tnl[0].tl_address = inet_addr(mac->eth_params_n.my_addr); - resp->drbs_to_be_setup[i].up_dl_tnl_length = 1; - } - } - else{ - LOG_W(NR_RRC, "No DRB added upon reception of F1 UE context setup request with a DRB to setup list\n"); - } - } - if(SRB_configList){ - if(SRB_configList->list.count >0 && SRBs_before_new_addition < SRB_configList->list.count){ - resp->srbs_to_be_setup = calloc(1,req->srbs_to_be_setup_length*sizeof(f1ap_srb_to_be_setup_t)); - resp->srbs_to_be_setup_length = req->srbs_to_be_setup_length; - for (int i=SRBs_before_new_addition; ilist.count; i++){ - resp->srbs_to_be_setup[i-SRBs_before_new_addition].srb_id = SRB_configList->list.array[i]->srb_Identity; - } - } - else{ - LOG_W(NR_RRC, "No SRB added upon reception of F1 UE Context setup request at the DU\n"); - } - } - else{ - LOG_W(NR_RRC, "No SRB added upon reception of F1 UE Context setup request at the DU\n"); - } - /* fixme: - * Here we should be encoding the updates on cellgroupconfig based on the content of UE capabilities - */ - resp->du_to_cu_rrc_information = calloc(1, sizeof(du_to_cu_rrc_information_t)); - resp->du_to_cu_rrc_information->cellGroupConfig = calloc(1,1024); - asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig, - NULL, - UE->masterCellGroup, //(void *)cellGroupConfig, - resp->du_to_cu_rrc_information->cellGroupConfig, - 1024); - if (enc_rval.encoded == -1) { - LOG_E(F1AP,"Could not encode ue_context.masterCellGroup, failed element %s\n",enc_rval.failed_type->name); - exit(-1); - } - resp->du_to_cu_rrc_information->cellGroupConfig_length = (enc_rval.encoded+7)>>3; - free(cellGroupConfig); - itti_send_msg_to_task(TASK_DU_F1, instance, message_p); -} - static void rrc_DU_process_ue_context_modification_request(MessageDef *msg_p, instance_t instance) { f1ap_ue_context_setup_t * req=&F1AP_UE_CONTEXT_MODIFICATION_REQ(msg_p); @@ -2899,54 +2557,29 @@ static void rrc_DU_process_ue_context_modification_request(MessageDef *msg_p, in static void rrc_CU_process_ue_context_setup_response(MessageDef *msg_p, instance_t instance) { f1ap_ue_context_setup_t * resp=&F1AP_UE_CONTEXT_SETUP_RESP(msg_p); - protocol_ctxt_t ctxt = {.rntiMaybeUEid = resp->rnti, .module_id = instance, .instance = instance, .enb_flag = 1, .eNB_index = instance}; - gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id]; + gNB_RRC_INST *rrc = RC.nrrrc[instance]; rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, resp->rnti); gNB_RRC_UE_t *UE = &ue_context_p->ue_context; + NR_CellGroupConfig_t *cellGroupConfig = NULL; + asn_dec_rval_t dec_rval = uper_decode_complete(NULL, + &asn_DEF_NR_CellGroupConfig, + (void **)&cellGroupConfig, + (uint8_t *)resp->du_to_cu_rrc_information->cellGroupConfig, + resp->du_to_cu_rrc_information->cellGroupConfig_length); + AssertFatal(dec_rval.code == RC_OK && dec_rval.consumed > 0, "Cell group config decode error\n"); - asn_dec_rval_t dec_rval = uper_decode_complete( NULL, - &asn_DEF_NR_CellGroupConfig, - (void **)&cellGroupConfig, - (uint8_t *)resp->du_to_cu_rrc_information->cellGroupConfig, - (int) resp->du_to_cu_rrc_information->cellGroupConfig_length); - - if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { - AssertFatal(1==0,"Cell group config decode error\n"); - // free the memory - SEQUENCE_free( &asn_DEF_NR_CellGroupConfig, cellGroupConfig, 1 ); - return; + if (UE->masterCellGroup) { + ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->masterCellGroup); + LOG_I(RRC, "UE %04x replacing existing CellGroupConfig with new one received from DU\n", UE->rnti); } - //xer_fprint(stdout,&asn_DEF_NR_CellGroupConfig, cellGroupConfig); - - if (UE->masterCellGroup == NULL) { - UE->masterCellGroup = calloc(1, sizeof(NR_CellGroupConfig_t)); - } - if(cellGroupConfig->rlc_BearerToAddModList!=NULL){ - if (UE->masterCellGroup->rlc_BearerToAddModList != NULL) { - int ue_ctxt_rlc_Bearers = UE->masterCellGroup->rlc_BearerToAddModList->list.count; - for(int i=ue_ctxt_rlc_Bearers; irlc_BearerToAddModList->list.count; i++){ - asn1cSeqAdd(&UE->masterCellGroup->rlc_BearerToAddModList->list, cellGroupConfig->rlc_BearerToAddModList->list.array[i - ue_ctxt_rlc_Bearers]); - } - } else { - LOG_W(NR_RRC, "Empty rlc_BearerToAddModList at ue_context of the CU before filling the updates from UE context setup response \n"); - UE->masterCellGroup->rlc_BearerToAddModList = calloc(1, sizeof(*cellGroupConfig->rlc_BearerToAddModList)); - memcpy(UE->masterCellGroup->rlc_BearerToAddModList, cellGroupConfig->rlc_BearerToAddModList, sizeof(*cellGroupConfig->rlc_BearerToAddModList)); - } - } - if (LOG_DEBUGFLAG(DEBUG_ASN1)) { + UE->masterCellGroup = cellGroupConfig; + if (LOG_DEBUGFLAG(DEBUG_ASN1)) xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, UE->masterCellGroup); - } - if (UE->established_pdu_sessions_flag == 1) { - fill_DRB_configList(&ctxt, ue_context_p); - rrc_gNB_generate_dedicatedRRCReconfiguration(&ctxt, ue_context_p, cellGroupConfig); - } else { - rrc_gNB_generate_defaultRRCReconfiguration(&ctxt, ue_context_p); - } - - free(cellGroupConfig->rlc_BearerToAddModList); - free(cellGroupConfig); + /* at this point, we don't have to do anything: the UE context setup request + * includes the Security Command, whose response will trigger the following + * messages (UE capability, to be specific) */ } static void rrc_CU_process_ue_context_modification_response(MessageDef *msg_p, instance_t instance) @@ -2975,7 +2608,8 @@ static void rrc_CU_process_ue_context_modification_response(MessageDef *msg_p, i } // send the F1 response message up to update F1-U tunnel info - rrc->cucp_cuup.bearer_context_mod(&req, instance); + // it seems the rrc transaction id (xid) is not needed here + rrc->cucp_cuup.bearer_context_mod(&req, instance, 0); NR_CellGroupConfig_t *cellGroupConfig = NULL; @@ -3508,10 +3142,6 @@ void *rrc_gnb_task(void *args_p) { AssertFatal(NODE_IS_CU(RC.nrrrc[instance]->node_type), "should not receive F1AP_SETUP_REQUEST, need call by CU!\n"); rrc_gNB_process_f1_setup_req(&F1AP_SETUP_REQ(msg_p)); break; - - case F1AP_UE_CONTEXT_SETUP_REQ: - rrc_DU_process_ue_context_setup_request(msg_p, instance); - break; case F1AP_UE_CONTEXT_SETUP_RESP: rrc_CU_process_ue_context_setup_response(msg_p, instance); @@ -3583,6 +3213,27 @@ void *rrc_gnb_task(void *args_p) { } } +static void rrc_deliver_ue_ctxt_setup_req(void *deliver_pdu_data, ue_id_t ue_id, int srb_id, char *buf, int size, int sdu_id) +{ + DevAssert(deliver_pdu_data != NULL); + gNB_RRC_INST *rrc = deliver_pdu_data; + f1ap_ue_context_setup_t ue_context_setup_req = { + .gNB_CU_ue_id = 0xffffffff, /* filled by F1 for the moment */ + .gNB_DU_ue_id = 0xffffffff, /* filled by F1 for the moment */ + .rnti = ue_id, + .mcc = rrc->configuration.mcc[0], + .mnc = rrc->configuration.mnc[0], + .mnc_digit_length = rrc->configuration.mnc_digit_length[0], + .nr_cellid = rrc->nr_cellid, + .servCellId = 0, /* TODO: correct value? */ + .srbs_to_be_setup = 0, /* no new SRBs */ + .drbs_to_be_setup = 0, /* no new DRBs */ + .rrc_container = (uint8_t*) buf, /* security mode command */ + .rrc_container_length = size, + }; + rrc->mac_rrc.ue_context_setup_request(&ue_context_setup_req); +} + //----------------------------------------------------------------------------- void rrc_gNB_generate_SecurityModeCommand( @@ -3604,7 +3255,8 @@ rrc_gNB_generate_SecurityModeCommand( gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; AssertFatal(!NODE_IS_DU(rrc->node_type), "illegal node type DU!\n"); - nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, deliver_pdu_srb_f1, rrc); + /* the callback will fill the UE context setup request and forward it */ + nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, rrc_deliver_ue_ctxt_setup_req, rrc); } void diff --git a/openair2/RRC/NR/rrc_gNB_GTPV1U.c b/openair2/RRC/NR/rrc_gNB_GTPV1U.c index 1322317b3e..e7bbe5835e 100644 --- a/openair2/RRC/NR/rrc_gNB_GTPV1U.c +++ b/openair2/RRC/NR/rrc_gNB_GTPV1U.c @@ -58,14 +58,14 @@ int rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(const protocol_ctxt_t *const ctxt_ return -1; } for (int i = 0; i < create_tunnel_resp_pP->num_tunnels; i++) { - ue_context_p->ue_context.gnb_gtp_teid[inde_list[i]] = create_tunnel_resp_pP->enb_S1u_teid[i]; - ue_context_p->ue_context.gnb_gtp_addrs[inde_list[i]] = create_tunnel_resp_pP->enb_addr; - ue_context_p->ue_context.gnb_gtp_ebi[inde_list[i]] = create_tunnel_resp_pP->eps_bearer_id[i]; + ue_context_p->ue_context.nsa_gtp_teid[inde_list[i]] = create_tunnel_resp_pP->enb_S1u_teid[i]; + ue_context_p->ue_context.nsa_gtp_addrs[inde_list[i]] = create_tunnel_resp_pP->enb_addr; + ue_context_p->ue_context.nsa_gtp_ebi[inde_list[i]] = create_tunnel_resp_pP->eps_bearer_id[i]; LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT " rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP tunnel (%u, %u) bearer UE context index %u, msg index %u, id %u, gtp addr len %d \n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), create_tunnel_resp_pP->enb_S1u_teid[i], - ue_context_p->ue_context.gnb_gtp_teid[inde_list[i]], + ue_context_p->ue_context.nsa_gtp_teid[inde_list[i]], inde_list[i], i, create_tunnel_resp_pP->eps_bearer_id[i], @@ -90,14 +90,14 @@ int nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(const protocol_ctxt_t *const ct } for (int i = 0; i < create_tunnel_resp_pP->num_tunnels; i++) { - ue_context_p->ue_context.gnb_gtp_teid[i + offset] = create_tunnel_resp_pP->gnb_NGu_teid[i]; - ue_context_p->ue_context.gnb_gtp_addrs[i + offset] = create_tunnel_resp_pP->gnb_addr; - ue_context_p->ue_context.gnb_gtp_psi[i + offset] = create_tunnel_resp_pP->pdusession_id[i]; + ue_context_p->ue_context.pduSession[i + offset].param.gNB_teid_N3 = create_tunnel_resp_pP->gnb_NGu_teid[i]; + ue_context_p->ue_context.pduSession[i + offset].param.gNB_addr_N3 = create_tunnel_resp_pP->gnb_addr; + AssertFatal(ue_context_p->ue_context.pduSession[i + offset].param.pdusession_id == create_tunnel_resp_pP->pdusession_id[i], ""); LOG_I(NR_RRC, - PROTOCOL_NR_RRC_CTXT_UE_FMT " nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP tunnel (%u, %u) bearer UE context index %u, id %u, gtp addr len %d \n", + PROTOCOL_NR_RRC_CTXT_UE_FMT + " nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP tunnel (%u) bearer UE context index %u, id %u, gtp addr len %d \n", PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), create_tunnel_resp_pP->gnb_NGu_teid[i], - ue_context_p->ue_context.gnb_gtp_teid[i + offset], i, create_tunnel_resp_pP->pdusession_id[i], create_tunnel_resp_pP->gnb_addr.length); diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index 1f37210b9c..102fb56091 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -319,7 +319,8 @@ static int decodePDUSessionResourceSetup(pdusession_t *session) /* mandatory PDUSessionType */ case NGAP_ProtocolIE_ID_id_PDUSessionType: - session->upf_addr.pdu_session_type = (uint8_t)pdusessionTransfer_ies->value.choice.PDUSessionType; + session->pdu_session_type = (uint8_t)pdusessionTransfer_ies->value.choice.PDUSessionType; + AssertFatal(session->pdu_session_type == PDUSessionType_ipv4, "To be developped: support not IPv4 sessions\n"); break; /* optional SecurityIndication */ @@ -405,7 +406,6 @@ int rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, instance_t } nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(&ctxt, &create_tunnel_resp, 0); - UE->established_pdu_sessions_flag = 1; } /* NAS PDU */ @@ -448,9 +448,11 @@ void rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(const protocol_ctxt_t *const c if (session->status == PDU_SESSION_STATUS_DONE) { pdu_sessions_done++; resp->pdusessions[pdusession].pdusession_id = session->param.pdusession_id; - resp->pdusessions[pdusession].gtp_teid = UE->gnb_gtp_teid[pdusession]; - memcpy(resp->pdusessions[pdusession].gNB_addr.buffer, UE->gnb_gtp_addrs[pdusession].buffer, 20); - resp->pdusessions[pdusession].gNB_addr.length = 4; + resp->pdusessions[pdusession].gtp_teid = session->param.gNB_teid_N3; + memcpy(resp->pdusessions[pdusession].gNB_addr.buffer, + session->param.gNB_addr_N3.buffer, + sizeof(resp->pdusessions[pdusession].gNB_addr.buffer)); + resp->pdusessions[pdusession].gNB_addr.length = 4; // Fixme: IPv4 hard coded here resp->pdusessions[pdusession].nb_of_qos_flow = session->param.nb_qos; for (int qos_flow_index = 0; qos_flow_index < session->param.nb_qos; qos_flow_index++) { resp->pdusessions[pdusession].associated_qos_flows[qos_flow_index].qfi = session->param.qos[qos_flow_index].qfi; @@ -679,10 +681,10 @@ rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP( pdusession_setup_t *tmp = &resp->pdusessions[pdu_sessions_done]; tmp->pdusession_id = session->param.pdusession_id; tmp->nb_of_qos_flow = session->param.nb_qos; - tmp->gtp_teid = UE->gnb_gtp_teid[pdusession]; - tmp->gNB_addr.pdu_session_type = PDUSessionType_ipv4; - tmp->gNB_addr.length = UE->gnb_gtp_addrs[pdusession].length; - memcpy(tmp->gNB_addr.buffer, UE->gnb_gtp_addrs[pdusession].buffer, tmp->gNB_addr.length); + tmp->gtp_teid = session->param.gNB_teid_N3; + tmp->pdu_session_type = session->param.pdu_session_type; // FixMe: IPv4 hardcoded here + tmp->gNB_addr.length = session->param.gNB_addr_N3.length; + memcpy(tmp->gNB_addr.buffer, session->param.gNB_addr_N3.buffer, tmp->gNB_addr.length); for (int qos_flow_index = 0; qos_flow_index < tmp->nb_of_qos_flow; qos_flow_index++) { tmp->associated_qos_flows[qos_flow_index].qfi = session->param.qos[qos_flow_index].qfi; tmp->associated_qos_flows[qos_flow_index].qos_flow_mapping_ind = QOSFLOW_MAPPING_INDICATION_DL; @@ -729,15 +731,13 @@ rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP( void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t instance) //------------------------------------------------------------------------------ { - gNB_RRC_INST *rrc; - rrc_gNB_ue_context_t *ue_context_p = NULL; protocol_ctxt_t ctxt={0}; ngap_pdusession_setup_req_t* msg=&NGAP_PDUSESSION_SETUP_REQ(msg_p); - ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[instance], msg->gNB_ue_ngap_id); + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[instance], msg->gNB_ue_ngap_id); gNB_RRC_UE_t *UE = &ue_context_p->ue_context; PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, UE->rnti, 0, 0, 0); - rrc = RC.nrrrc[ctxt.module_id]; + gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id]; LOG_I(NR_RRC, "[gNB %ld] gNB_ue_ngap_id %u \n", instance, msg->gNB_ue_ngap_id); if (ue_context_p == NULL) { @@ -759,6 +759,7 @@ void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t ins pdusession_t *session = &pduSession->param; LOG_I(NR_RRC, "Adding pdusession %d, total nb of sessions %d\n", session->pdusession_id, UE->nb_of_pdusessions); session->pdusession_id = msg->pdusession_setup_params[i].pdusession_id; + session->pdu_session_type = msg->pdusession_setup_params[i].pdu_session_type; session->nas_pdu = msg->pdusession_setup_params[i].nas_pdu; session->pdusessionTransfer = msg->pdusession_setup_params[i].pdusessionTransfer; decodePDUSessionResourceSetup(session); @@ -818,7 +819,9 @@ void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t ins } } } - rrc->cucp_cuup.bearer_context_setup(&bearer_req, instance); + int xid = rrc_gNB_get_next_transaction_identifier(instance); + UE->xids[xid] = RRC_PDUSESSION_ESTABLISH; + rrc->cucp_cuup.bearer_context_setup(&bearer_req, instance, xid); return; } @@ -929,50 +932,46 @@ int rrc_gNB_process_NGAP_PDUSESSION_MODIFY_REQ(MessageDef *msg_p, instance_t ins gNB_RRC_UE_t *UE = &ue_context_p->ue_context; PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rnti, 0, 0); ctxt.eNB_index = 0; - uint8_t nb_of_failed_pdusessions = 0; - + bool all_failed = true; for (int i = 0; i < req->nb_pdusessions_tomodify; i++) { - int j; - for (j = 0; j < UE->nb_of_pdusessions; j++) - if (UE->modify_pdusession[j].param.pdusession_id == req->pdusession_modify_params[j].pdusession_id) + rrc_pdu_session_param_t *sess; + const pdusession_t *sessMod = req->pdusession_modify_params + i; + for (sess = UE->pduSession; sess < UE->pduSession + UE->nb_of_pdusessions; sess++) + if (sess->param.pdusession_id == sessMod->pdusession_id) break; - if (j == UE->nb_of_pdusessions) { - LOG_W(NR_RRC, "To finish, modify a not existing pdu session\n"); - // handle multiple pdu session id - LOG_D(NR_RRC, "handle multiple pdu session id \n"); - UE->modify_pdusession[j].status = PDU_SESSION_STATUS_NEW; - UE->modify_pdusession[j].param.pdusession_id = req->pdusession_modify_params[j].pdusession_id; - UE->modify_pdusession[j].cause = NGAP_CAUSE_RADIO_NETWORK; - UE->modify_pdusession[i].cause_value = NGAP_CauseRadioNetwork_unknown_PDU_session_ID; - nb_of_failed_pdusessions++; + if (sess == UE->pduSession + UE->nb_of_pdusessions) { + LOG_W(NR_RRC, "Requested modification of non-existing PDU session, refusing modification\n"); + UE->nb_of_pdusessions++; + sess->status = PDU_SESSION_STATUS_FAILED; + sess->param.pdusession_id = sessMod->pdusession_id; + sess->cause = NGAP_CAUSE_RADIO_NETWORK; + UE->pduSession[i].cause_value = NGAP_CauseRadioNetwork_unknown_PDU_session_ID; } else { - UE->modify_pdusession[j].status = PDU_SESSION_STATUS_NEW; - UE->modify_pdusession[j].param.pdusession_id = req->pdusession_modify_params[i].pdusession_id; - UE->modify_pdusession[j].cause = NGAP_CAUSE_RADIO_NETWORK; - UE->modify_pdusession[j].cause_value = NGAP_CauseRadioNetwork_multiple_PDU_session_ID_instances; - UE->modify_pdusession[j].status = PDU_SESSION_STATUS_NEW; - UE->modify_pdusession[j].param.pdusession_id = req->pdusession_modify_params[i].pdusession_id; - UE->modify_pdusession[j].cause = NGAP_CAUSE_NOTHING; - if (req->pdusession_modify_params[i].nas_pdu.buffer != NULL) { - UE->modify_pdusession[i].param.nas_pdu = req->pdusession_modify_params[i].nas_pdu; + all_failed = false; + sess->status = PDU_SESSION_STATUS_NEW; + sess->param.pdusession_id = sessMod->pdusession_id; + sess->cause = NGAP_CAUSE_RADIO_NETWORK; + sess->cause_value = NGAP_CauseRadioNetwork_multiple_PDU_session_ID_instances; + sess->status = PDU_SESSION_STATUS_NEW; + sess->param.pdusession_id = sessMod->pdusession_id; + sess->cause = NGAP_CAUSE_NOTHING; + if (sessMod->nas_pdu.buffer != NULL) { + UE->pduSession[i].param.nas_pdu = sessMod->nas_pdu; } // Save new pdu session parameters, qos, upf addr, teid - decodePDUSessionResourceModify(&UE->modify_pdusession[j].param, UE->modify_pdusession[i].param.pdusessionTransfer); - UE->modify_pdusession[j].param.upf_addr = UE->pduSession[j].param.upf_addr; - UE->modify_pdusession[j].param.gtp_teid = UE->pduSession[j].param.gtp_teid; + decodePDUSessionResourceModify(&sess->param, UE->pduSession[i].param.pdusessionTransfer); + sess->param.UPF_addr_N3 = sessMod->upf_addr; + sess->param.UPF_teid_N3 = sessMod->gtp_teid; } } - UE->nb_of_modify_pdusessions = req->nb_pdusessions_tomodify - nb_of_failed_pdusessions; - UE->nb_of_failed_pdusessions = nb_of_failed_pdusessions; - - if (UE->nb_of_failed_pdusessions < UE->nb_of_modify_pdusessions) { + if (!all_failed) { LOG_D(NR_RRC, "generate RRCReconfiguration \n"); rrc_gNB_modify_dedicatedRRCReconfiguration(&ctxt, ue_context_p); - } else { // all pdu modification failed - LOG_I(NR_RRC, "pdu session modify failed, fill NGAP_PDUSESSION_MODIFY_RESP with the pdu session information that failed to modify \n"); - MessageDef *msg_fail_p = NULL; - msg_fail_p = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_PDUSESSION_MODIFY_RESP); + } else { + LOG_I(NR_RRC, + "pdu session modify failed, fill NGAP_PDUSESSION_MODIFY_RESP with the pdu session information that failed to modify \n"); + MessageDef *msg_fail_p = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_PDUSESSION_MODIFY_RESP); if (msg_fail_p == NULL) { LOG_E(NR_RRC, "itti_alloc_new_message failed, msg_fail_p is NULL \n"); return (-1); @@ -981,21 +980,16 @@ int rrc_gNB_process_NGAP_PDUSESSION_MODIFY_REQ(MessageDef *msg_p, instance_t ins msg->gNB_ue_ngap_id = req->gNB_ue_ngap_id; msg->nb_of_pdusessions = 0; - for (int i = 0; i < UE->nb_of_failed_pdusessions; i++) { - msg->pdusessions_failed[i].pdusession_id = UE->modify_pdusession[i].param.pdusession_id; - msg->pdusessions_failed[i].cause = UE->modify_pdusession[i].cause; - msg->pdusessions_failed[i].cause_value = UE->modify_pdusession[i].cause_value; + for (int i = 0; i < UE->nb_of_pdusessions; i++) { + if (UE->pduSession[i].status == PDU_SESSION_STATUS_FAILED) { + msg->pdusessions_failed[i].pdusession_id = UE->pduSession[i].param.pdusession_id; + msg->pdusessions_failed[i].cause = UE->pduSession[i].cause; + msg->pdusessions_failed[i].cause_value = UE->pduSession[i].cause_value; + } } - - msg->nb_of_pdusessions_failed = UE->nb_of_failed_pdusessions; itti_send_msg_to_task(TASK_NGAP, instance, msg_fail_p); - UE->nb_of_modify_pdusessions = 0; - UE->nb_of_failed_pdusessions = 0; - memset(UE->modify_pdusession, 0, sizeof(UE->modify_pdusession)); - return (0); } - - return 0; + return (0); } //------------------------------------------------------------------------------ @@ -1022,63 +1016,63 @@ rrc_gNB_send_NGAP_PDUSESSION_MODIFY_RESP( resp->gNB_ue_ngap_id = UE->gNB_ue_ngap_id; - for (int i = 0; i < UE->nb_of_modify_pdusessions; i++) { - if (xid != UE->modify_pdusession[i].xid) { - LOG_W(NR_RRC, "xid does not correspond (context pdu session index %d, status %d, xid %d/%d) \n ", i, UE->modify_pdusession[i].status, xid, UE->modify_pdusession[i].xid); + for (int i = 0; i < UE->nb_of_pdusessions; i++) { + if (xid != UE->pduSession[i].xid) { + LOG_W(NR_RRC, "xid does not correspond (context pdu session index %d, status %d, xid %d/%d) \n ", i, UE->pduSession[i].status, xid, UE->pduSession[i].xid); continue; } - if (UE->modify_pdusession[i].status == PDU_SESSION_STATUS_DONE) { - rrc_pdu_session_param_t *pduSession = find_pduSession(UE, UE->modify_pdusession[i].param.pdusession_id, false); + if (UE->pduSession[i].status == PDU_SESSION_STATUS_DONE) { + rrc_pdu_session_param_t *pduSession = find_pduSession(UE, UE->pduSession[i].param.pdusession_id, false); if (pduSession) { LOG_I(NR_RRC, "update pdu session %d \n", pduSession->param.pdusession_id); // Update UE->pduSession pduSession->status = PDU_SESSION_STATUS_ESTABLISHED; pduSession->cause = NGAP_CAUSE_NOTHING; - for (int qos_flow_index = 0; qos_flow_index < UE->modify_pdusession[i].param.nb_qos; qos_flow_index++) { - pduSession->param.qos[qos_flow_index] = UE->modify_pdusession[i].param.qos[qos_flow_index]; + for (int qos_flow_index = 0; qos_flow_index < UE->pduSession[i].param.nb_qos; qos_flow_index++) { + pduSession->param.qos[qos_flow_index] = UE->pduSession[i].param.qos[qos_flow_index]; } - resp->pdusessions[pdu_sessions_done].pdusession_id = UE->modify_pdusession[i].param.pdusession_id; - for (int qos_flow_index = 0; qos_flow_index < UE->modify_pdusession[i].param.nb_qos; qos_flow_index++) { - resp->pdusessions[pdu_sessions_done].qos[qos_flow_index].qfi = UE->modify_pdusession[i].param.qos[qos_flow_index].qfi; + resp->pdusessions[pdu_sessions_done].pdusession_id = UE->pduSession[i].param.pdusession_id; + for (int qos_flow_index = 0; qos_flow_index < UE->pduSession[i].param.nb_qos; qos_flow_index++) { + resp->pdusessions[pdu_sessions_done].qos[qos_flow_index].qfi = UE->pduSession[i].param.qos[qos_flow_index].qfi; } - resp->pdusessions[pdu_sessions_done].pdusession_id = UE->modify_pdusession[i].param.pdusession_id; - resp->pdusessions[pdu_sessions_done].nb_of_qos_flow = UE->modify_pdusession[i].param.nb_qos; + resp->pdusessions[pdu_sessions_done].pdusession_id = UE->pduSession[i].param.pdusession_id; + resp->pdusessions[pdu_sessions_done].nb_of_qos_flow = UE->pduSession[i].param.nb_qos; LOG_I(NR_RRC, - "Modify Resp (msg index %d, pdu session index %d, status %d, xid %d): nb_of_modify_pdusessions %d, pdusession_id %d \n ", + "Modify Resp (msg index %d, pdu session index %d, status %d, xid %d): nb_of_pduSessions %d, pdusession_id %d \n ", pdu_sessions_done, i, - UE->modify_pdusession[i].status, + UE->pduSession[i].status, xid, - UE->nb_of_modify_pdusessions, + UE->nb_of_pdusessions, resp->pdusessions[pdu_sessions_done].pdusession_id); pdu_sessions_done++; } else { - LOG_W(NR_RRC, "PDU SESSION modify of a not existing pdu session %d \n", UE->modify_pdusession[i].param.pdusession_id); - resp->pdusessions_failed[pdu_sessions_failed].pdusession_id = UE->modify_pdusession[i].param.pdusession_id; + LOG_W(NR_RRC, "PDU SESSION modify of a not existing pdu session %d \n", UE->pduSession[i].param.pdusession_id); + resp->pdusessions_failed[pdu_sessions_failed].pdusession_id = UE->pduSession[i].param.pdusession_id; resp->pdusessions_failed[pdu_sessions_failed].cause = NGAP_CAUSE_RADIO_NETWORK; resp->pdusessions_failed[pdu_sessions_failed].cause_value = NGAP_CauseRadioNetwork_unknown_PDU_session_ID; pdu_sessions_failed++; } - } else if ((UE->modify_pdusession[i].status == PDU_SESSION_STATUS_NEW) || (UE->modify_pdusession[i].status == PDU_SESSION_STATUS_ESTABLISHED)) { + } else if ((UE->pduSession[i].status == PDU_SESSION_STATUS_NEW) || (UE->pduSession[i].status == PDU_SESSION_STATUS_ESTABLISHED)) { LOG_D(NR_RRC, "PDU SESSION is NEW or already ESTABLISHED\n"); - } else if (UE->modify_pdusession[i].status == PDU_SESSION_STATUS_FAILED) { - resp->pdusessions_failed[pdu_sessions_failed].pdusession_id = UE->modify_pdusession[i].param.pdusession_id; - resp->pdusessions_failed[pdu_sessions_failed].cause = UE->modify_pdusession[i].cause; - resp->pdusessions_failed[pdu_sessions_failed].cause_value = UE->modify_pdusession[i].cause_value; + } else if (UE->pduSession[i].status == PDU_SESSION_STATUS_FAILED) { + resp->pdusessions_failed[pdu_sessions_failed].pdusession_id = UE->pduSession[i].param.pdusession_id; + resp->pdusessions_failed[pdu_sessions_failed].cause = UE->pduSession[i].cause; + resp->pdusessions_failed[pdu_sessions_failed].cause_value = UE->pduSession[i].cause_value; pdu_sessions_failed++; } else LOG_W(NR_RRC, "Modify pdu session %d, unknown state %d \n ", - UE->modify_pdusession[i].param.pdusession_id, - UE->modify_pdusession[i].status); + UE->pduSession[i].param.pdusession_id, + UE->pduSession[i].status); } resp->nb_of_pdusessions = pdu_sessions_done; resp->nb_of_pdusessions_failed = pdu_sessions_failed; if (pdu_sessions_done > 0 || pdu_sessions_failed > 0) { - LOG_D(NR_RRC, "NGAP_PDUSESSION_MODIFY_RESP: sending the message: nb_of_pdusessions %d, total pdu session %d\n", UE->nb_of_modify_pdusessions, UE->nb_of_pdusessions); + LOG_D(NR_RRC, "NGAP_PDUSESSION_MODIFY_RESP: sending the message (total pdu session %d)\n", UE->nb_of_pdusessions); itti_send_msg_to_task (TASK_NGAP, ctxt_pP->instance, msg_p); } else { itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p); @@ -1179,22 +1173,19 @@ void rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE( itti_send_msg_to_task(TASK_NGAP, instance, msg); } -void -rrc_gNB_send_NGAP_UE_CAPABILITIES_IND( - const protocol_ctxt_t *const ctxt_pP, - rrc_gNB_ue_context_t *const ue_context_pP, - NR_UL_DCCH_Message_t *const ul_dcch_msg -) +void rrc_gNB_send_NGAP_UE_CAPABILITIES_IND(const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *const ue_context_pP, + const NR_UECapabilityInformation_t *const ue_cap_info) //------------------------------------------------------------------------------ { - NR_UE_CapabilityRAT_ContainerList_t *ueCapabilityRATContainerList = ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList; - /* 4096 is arbitrary, should be big enough */ - void *buf; - NR_UERadioAccessCapabilityInformation_t rac = {0}; - gNB_RRC_UE_t *UE = &ue_context_pP->ue_context; + NR_UE_CapabilityRAT_ContainerList_t *ueCapabilityRATContainerList = + ue_cap_info->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList; + void *buf; + NR_UERadioAccessCapabilityInformation_t rac = {0}; + gNB_RRC_UE_t *UE = &ue_context_pP->ue_context; - if (ueCapabilityRATContainerList->list.count == 0) { - LOG_W(RRC, "[gNB %d][UE %x] bad UE capabilities\n", ctxt_pP->module_id, UE->rnti); + if (ueCapabilityRATContainerList->list.count == 0) { + LOG_W(RRC, "[gNB %d][UE %x] bad UE capabilities\n", ctxt_pP->module_id, UE->rnti); } int ret = uper_encode_to_new_buffer(&asn_DEF_NR_UE_CapabilityRAT_ContainerList, NULL, ueCapabilityRATContainerList, &buf); @@ -1242,31 +1233,21 @@ rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE( memset(resp, 0, sizeof(*resp)); resp->gNB_ue_ngap_id = UE->gNB_ue_ngap_id; - for (int i = 0; i < NB_RB_MAX; i++) { + for (int i = 0; i < UE->nb_of_pdusessions; i++) { if (xid == UE->pduSession[i].xid) { resp->pdusession_release[pdu_sessions_released].pdusession_id = UE->pduSession[i].param.pdusession_id; pdu_sessions_released++; //clear memset(&UE->pduSession[i], 0, sizeof(*UE->pduSession)); + UE->pduSession[i].status = PDU_SESSION_STATUS_RELEASED; + LOG_W(NR_RRC, "Released pdu session, but code to finish to free memory\n"); } } resp->nb_of_pdusessions_released = pdu_sessions_released; - resp->nb_of_pdusessions_failed = UE->nb_release_of_pdusessions; - memcpy(resp->pdusessions_failed, UE->pdusessions_release_failed, sizeof(pdusession_failed_t) * UE->nb_release_of_pdusessions); - LOG_E(NR_RRC, "we have to pack the array!!!\n"); - UE->nb_of_pdusessions -= pdu_sessions_released; + resp->nb_of_pdusessions_failed = 0; LOG_I(NR_RRC, "NGAP PDUSESSION RELEASE RESPONSE: GNB_UE_NGAP_ID %u release_pdu_sessions %d\n", resp->gNB_ue_ngap_id, pdu_sessions_released); itti_send_msg_to_task (TASK_NGAP, ctxt_pP->instance, msg_p); - - //clear xid - for(int i = 0; i < NB_RB_MAX; i++) { - UE->pduSession[i].xid = -1; - } - - //clear release pdusessions - UE->nb_release_of_pdusessions = 0; - memset(UE->pdusessions_release_failed, 0, sizeof(UE->pdusessions_release_failed)); } //------------------------------------------------------------------------------ @@ -1275,8 +1256,6 @@ int rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(MessageDef *msg_p, instance_ { uint32_t gNB_ue_ngap_id; protocol_ctxt_t ctxt; - uint8_t xid; - uint8_t pdusession_release_drb = 0; ngap_pdusession_release_command_t *cmd = &NGAP_PDUSESSION_RELEASE_COMMAND(msg_p); gNB_ue_ngap_id = cmd->gNB_ue_ngap_id; if (cmd->nb_pdusessions_torelease > NGAP_MAX_PDUSESSION) { @@ -1293,18 +1272,21 @@ int rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(MessageDef *msg_p, instance_ LOG_I(NR_RRC, "[gNB %ld] gNB_ue_ngap_id %u \n", instance, gNB_ue_ngap_id); gNB_RRC_UE_t *UE = &ue_context_p->ue_context; PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rnti, 0, 0); - xid = rrc_gNB_get_next_transaction_identifier(ctxt.module_id); LOG_I( NR_RRC, "PDU Session Release Command: AMF_UE_NGAP_ID %lu GNB_UE_NGAP_ID %u release_pdusessions %d \n", cmd->amf_ue_ngap_id, gNB_ue_ngap_id, cmd->nb_pdusessions_torelease); - + bool found = false; + uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt.module_id); + UE->xids[xid] = RRC_PDUSESSION_RELEASE; for (int pdusession = 0; pdusession < cmd->nb_pdusessions_torelease; pdusession++) { rrc_pdu_session_param_t *pduSession = find_pduSession(UE, cmd->pdusession_release_params[pdusession].pdusession_id, false); if (!pduSession) { - LOG_I(NR_RRC, "no pdusession_id \n"); - UE->pdusessions_release_failed[UE->nb_release_of_pdusessions].pdusession_id = cmd->pdusession_release_params[pdusession].pdusession_id; - UE->pdusessions_release_failed[UE->nb_release_of_pdusessions].cause = NGAP_CAUSE_RADIO_NETWORK; - UE->pdusessions_release_failed[UE->nb_release_of_pdusessions].cause_value = 30; - UE->nb_release_of_pdusessions++; + LOG_I(NR_RRC, "no pdusession_id, AMF requested to close it id=%d\n", cmd->pdusession_release_params[pdusession].pdusession_id); + int j=UE->nb_of_pdusessions++; + UE->pduSession[j].status = PDU_SESSION_STATUS_FAILED; + UE->pduSession[j].param.pdusession_id = cmd->pdusession_release_params[pdusession].pdusession_id; + UE->pduSession[j].cause = NGAP_CAUSE_RADIO_NETWORK; + UE->pduSession[j].cause_value = 30; + pduSession->xid = xid; continue; } if (pduSession->status == PDU_SESSION_STATUS_FAILED) { @@ -1312,37 +1294,22 @@ int rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(MessageDef *msg_p, instance_ continue; } if (pduSession->status == PDU_SESSION_STATUS_ESTABLISHED) { + found = true; LOG_I(NR_RRC, "RELEASE pdusession %d \n", pduSession->param.pdusession_id); pduSession->status = PDU_SESSION_STATUS_TORELEASE; pduSession->xid = xid; - pdusession_release_drb++; - continue; } - // pdusession_id status NG - UE->pdusessions_release_failed[UE->nb_release_of_pdusessions].pdusession_id = cmd->pdusession_release_params[pdusession].pdusession_id; - UE->pdusessions_release_failed[UE->nb_release_of_pdusessions].cause = NGAP_CAUSE_RADIO_NETWORK; - UE->pdusessions_release_failed[UE->nb_release_of_pdusessions].cause_value = 0; - UE->nb_release_of_pdusessions++; } - if (pdusession_release_drb > 0) { + if (found) { // TODO RRCReconfiguration To UE LOG_I(NR_RRC, "Send RRCReconfiguration To UE \n"); rrc_gNB_generate_dedicatedRRCReconfiguration_release(&ctxt, ue_context_p, xid, cmd->nas_pdu.length, cmd->nas_pdu.buffer); } else { // gtp tunnel delete - LOG_I(NR_RRC, "gtp tunnel delete \n"); + LOG_I(NR_RRC, "gtp tunnel delete all tunnels for UE %04x\n", UE->rnti); gtpv1u_gnb_delete_tunnel_req_t req = {0}; req.ue_id = UE->rnti; - - for (int i = 0; i < NB_RB_MAX; i++) { - if (xid == UE->pduSession[i].xid) { - req.pdusession_id[req.num_pdusession++] = UE->gnb_gtp_psi[i]; - UE->gnb_gtp_teid[i] = 0; - memset(&UE->gnb_gtp_addrs[i], 0, sizeof(UE->gnb_gtp_addrs[i])); - UE->gnb_gtp_psi[i] = 0; - } - } gtpv1u_delete_ngu_tunnel(instance, &req); // NGAP_PDUSESSION_RELEASE_RESPONSE rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(&ctxt, ue_context_p, xid); diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.h b/openair2/RRC/NR/rrc_gNB_NGAP.h index a0c42dcaaf..25e7974632 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.h +++ b/openair2/RRC/NR/rrc_gNB_NGAP.h @@ -96,12 +96,9 @@ int rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_COMMAND(MessageDef *msg_p, instance_ void rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, uint32_t gNB_ue_ngap_id); -void -rrc_gNB_send_NGAP_UE_CAPABILITIES_IND( - const protocol_ctxt_t *const ctxt_pP, - rrc_gNB_ue_context_t *const ue_context_pP, - NR_UL_DCCH_Message_t *const ul_dcch_msg -); +void rrc_gNB_send_NGAP_UE_CAPABILITIES_IND(const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *const ue_context_pP, + const NR_UECapabilityInformation_t *const ue_cap_info); int rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(MessageDef *msg_p, instance_t instance); diff --git a/openair2/RRC/NR/rrc_gNB_UE_context.c b/openair2/RRC/NR/rrc_gNB_UE_context.c index 137ed695f5..b7f7e189ae 100644 --- a/openair2/RRC/NR/rrc_gNB_UE_context.c +++ b/openair2/RRC/NR/rrc_gNB_UE_context.c @@ -68,11 +68,8 @@ rrc_gNB_ue_context_t *rrc_gNB_allocate_new_ue_context(gNB_RRC_INST *rrc_instance } new_p->ue_context.gNB_ue_ngap_id = uid_linear_allocator_new(&rrc_instance_pP->uid_allocator); - for(int i = 0; i < NB_RB_MAX; i++) { - new_p->ue_context.e_rab[i].xid = -1; + for(int i = 0; i < NB_RB_MAX; i++) new_p->ue_context.pduSession[i].xid = -1; - new_p->ue_context.modify_e_rab[i].xid = -1; - } LOG_I(NR_RRC, "Returning new RRC UE context RRC ue id: %d\n", new_p->ue_context.gNB_ue_ngap_id); return(new_p); diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index bf69aa703b..a8d9241b7f 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -401,18 +401,21 @@ void rrc_remove_nsa_user(gNB_RRC_INST *rrc, int rnti) { rrc_rlc_remove_ue(&ctxt); - // WHAT A RACE CONDITION + // lock the scheduler before removing the UE. Note: mac_remove_nr_ue() checks + // that the scheduler is actually locked! + NR_SCHED_LOCK(&RC.nrmac[rrc->module_id]->sched_lock); mac_remove_nr_ue(RC.nrmac[rrc->module_id], rnti); + NR_SCHED_UNLOCK(&RC.nrmac[rrc->module_id]->sched_lock); gtpv1u_enb_delete_tunnel_req_t tmp={0}; tmp.rnti=rnti; tmp.from_gnb=1; LOG_D(RRC, "ue_context->ue_context.nb_of_e_rabs %d will be deleted for rnti %d\n", ue_context->ue_context.nb_of_e_rabs, rnti); for (e_rab = 0; e_rab < ue_context->ue_context.nb_of_e_rabs; e_rab++) { - tmp.eps_bearer_id[tmp.num_erab++]= ue_context->ue_context.gnb_gtp_ebi[e_rab]; + tmp.eps_bearer_id[tmp.num_erab++]= ue_context->ue_context.nsa_gtp_ebi[e_rab]; // erase data - ue_context->ue_context.gnb_gtp_teid[e_rab] = 0; - memset(&ue_context->ue_context.gnb_gtp_addrs[e_rab], 0, sizeof(ue_context->ue_context.gnb_gtp_addrs[e_rab])); - ue_context->ue_context.gnb_gtp_ebi[e_rab] = 0; + ue_context->ue_context.nsa_gtp_teid[e_rab] = 0; + memset(&ue_context->ue_context.nsa_gtp_addrs[e_rab], 0, sizeof(ue_context->ue_context.nsa_gtp_addrs[e_rab])); + ue_context->ue_context.nsa_gtp_ebi[e_rab] = 0; } gtpv1u_delete_s1u_tunnel(rrc->module_id, &tmp); /* remove context */ diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 7ddc2da5d7..0bffcfdc26 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -285,6 +285,9 @@ int8_t nr_rrc_ue_process_rrcReconfiguration(const module_id_t module_id, NR_RRCR NR_UE_rrc_inst[module_id].cell_group_config = cellGroupConfig; nr_rrc_ue_process_scg_config(module_id,cellGroupConfig); } + if (get_softmodem_params()->nsa) { + nr_rrc_mac_config_req_scg(0, 0, cellGroupConfig); + } } else nr_rrc_ue_decode_secondary_cellgroup_config(module_id, @@ -312,7 +315,6 @@ int8_t nr_rrc_ue_process_rrcReconfiguration(const module_id_t module_id, NR_RRCR default: break; } - //nr_rrc_mac_config_req_ue(); return 0; } @@ -340,10 +342,6 @@ int8_t nr_rrc_ue_process_scg_config(const module_id_t module_id, NR_CellGroupCon }else{ // maintain list if(cell_group_config->spCellConfig != NULL){ - if (get_softmodem_params()->nsa) { - nr_rrc_mac_config_req_ue(0, 0, 0, NULL, NULL, cell_group_config, NULL); - LOG_D(NR_RRC, "Filled scc now \n"); - } if(cell_group_config->spCellConfig->spCellConfigDedicated != NULL){ // process element of list to be add by RRC message if(cell_group_config->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList != NULL){ @@ -600,7 +598,10 @@ int8_t nr_rrc_ue_decode_NR_BCCH_BCH_Message(const module_id_t module_id, const u NR_UE_rrc_inst[module_id].mib = bcch_message->message.choice.mib; bcch_message->message.choice.mib = NULL; - nr_rrc_mac_config_req_ue(0, 0, 0, NR_UE_rrc_inst[module_id].mib, NULL, NULL, NULL); + NR_SIB1_t *sib1 = NR_UE_rrc_inst[module_id].sib1[gNB_index]; + // if no sib1 because not acquired yet or expired, get a new one + bool get_sib1 = sib1 == NULL; + nr_rrc_mac_config_req_mib(module_id, 0, NR_UE_rrc_inst[module_id].mib, get_sib1); ret = 0; } ASN_STRUCT_FREE(asn_DEF_NR_BCCH_BCH_Message, bcch_message); @@ -1210,8 +1211,8 @@ int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(module_id_t module_id, } // take ServingCellConfigCommon and configure L1/L2 NR_UE_rrc_inst[module_id].servingCellConfigCommonSIB = sib1->servingCellConfigCommon; - nr_rrc_mac_config_req_ue(module_id,0,0,NULL,sib1->servingCellConfigCommon,NULL,NULL); - nr_rrc_ue_generate_ra_msg(module_id,gNB_index); + nr_rrc_mac_config_req_sib1(module_id, 0, sib1->servingCellConfigCommon); + nr_rrc_ue_generate_ra_msg(module_id, gNB_index); } else { LOG_E(NR_RRC, "SIB1 not decoded\n"); } @@ -1256,12 +1257,9 @@ int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(module_id_t module_id, } //----------------------------------------------------------------------------- -void -nr_rrc_ue_process_masterCellGroup( - const protocol_ctxt_t *const ctxt_pP, - uint8_t gNB_index, - OCTET_STRING_t *masterCellGroup -) +void nr_rrc_ue_process_masterCellGroup(const protocol_ctxt_t *const ctxt_pP, + uint8_t gNB_index, + OCTET_STRING_t *masterCellGroup) //----------------------------------------------------------------------------- { NR_CellGroupConfig_t *cellGroupConfig=NULL; @@ -1342,23 +1340,23 @@ nr_rrc_ue_process_masterCellGroup( sizeof(struct NR_MAC_CellGroupConfig)); } - if( cellGroupConfig->sCellToReleaseList != NULL){ + if(cellGroupConfig->sCellToReleaseList != NULL) { //TODO (perform SCell release as specified in 5.3.5.5.8) } - if( cellGroupConfig->spCellConfig != NULL){ + if(cellGroupConfig->spCellConfig != NULL) { if (NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config && - NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->spCellConfig) { + NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->spCellConfig) { memcpy(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->spCellConfig,cellGroupConfig->spCellConfig, sizeof(struct NR_SpCellConfig)); } else { if (NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config) - NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->spCellConfig = cellGroupConfig->spCellConfig; + NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->spCellConfig = cellGroupConfig->spCellConfig; else - NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config = cellGroupConfig; + NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config = cellGroupConfig; } LOG_D(RRC,"Sending CellGroupConfig to MAC\n"); - nr_rrc_mac_config_req_ue(ctxt_pP->module_id,0,0,NULL,NULL,cellGroupConfig,NULL); + nr_rrc_mac_config_req_mcg(ctxt_pP->module_id, 0, cellGroupConfig); //TODO (configure the SpCell as specified in 5.3.5.5.7) } @@ -2136,12 +2134,9 @@ nr_rrc_ue_establish_srb2( } //----------------------------------------------------------------------------- - static void - rrc_ue_process_rrcReconfiguration( - const protocol_ctxt_t *const ctxt_pP, - NR_RRCReconfiguration_t *rrcReconfiguration, - uint8_t gNB_index - ) + static void rrc_ue_process_rrcReconfiguration(const protocol_ctxt_t *const ctxt_pP, + NR_RRCReconfiguration_t *rrcReconfiguration, + uint8_t gNB_index) //----------------------------------------------------------------------------- { LOG_I(NR_RRC, "[UE %d] Frame %d: Receiving from SRB1 (DL-DCCH), Processing RRCReconfiguration (gNB %d)\n", diff --git a/openair3/NGAP/ngap_gNB_nas_procedures.c b/openair3/NGAP/ngap_gNB_nas_procedures.c index 069f3ce48b..15f4b4b376 100644 --- a/openair3/NGAP/ngap_gNB_nas_procedures.c +++ b/openair3/NGAP/ngap_gNB_nas_procedures.c @@ -58,7 +58,7 @@ static void allocCopy(OCTET_STRING_t *out, ngap_pdu_t in) out->size = in.length; } -static void allocAddrCopy(BIT_STRING_t *out, ngap_transport_layer_addr_t in) +static void allocAddrCopy(BIT_STRING_t *out, transport_layer_addr_t in) { if (in.length) { out->buf = malloc(in.length); diff --git a/openair3/UTILS/conversions.h b/openair3/UTILS/conversions.h index 6e961781f0..2c544c94e0 100644 --- a/openair3/UTILS/conversions.h +++ b/openair3/UTILS/conversions.h @@ -116,6 +116,15 @@ do { \ ((buf)[3]); \ } while(0) +/* Convert an array of char containing vALUE to x */ +#define BUFFER_TO_UINT32(buf, x) \ + do { \ + x = (((uint32_t)(buf)[0] << 24) | \ + (uint32_t)((buf)[1] << 16) | \ + (uint32_t)((buf)[2] << 8) | \ + (uint32_t)((buf)[3]); \ + } while (0) + /* Convert an integer on 32 bits to an octet string from aSN1c tool */ #define INT32_TO_OCTET_STRING(x, aSN) \ do { \ @@ -260,6 +269,12 @@ do { \ BUFFER_TO_INT32((aSN)->buf, x); \ } while(0) +#define OCTET_STRING_TO_UINT32(aSN, x) \ + do { \ + DevCheck((aSN)->size == 4, (aSN)->size, 0, 0); \ + BUFFER_TO_UINT32((aSN)->buf, x); \ + } while (0) + #define BIT_STRING_TO_INT32(aSN, x) \ do { \ DevCheck((aSN)->bits_unused == 0, (aSN)->bits_unused, 0, 0); \ diff --git a/openair3/ocp-gtpu/gtp_itf.cpp b/openair3/ocp-gtpu/gtp_itf.cpp index d8e1dc2314..5a75b8953a 100644 --- a/openair3/ocp-gtpu/gtp_itf.cpp +++ b/openair3/ocp-gtpu/gtp_itf.cpp @@ -762,6 +762,7 @@ int gtpv1u_create_ngu_tunnel(const instance_t instance, create_tunnel_resp->gnb_NGu_teid[i]=teid; memcpy(create_tunnel_resp->gnb_addr.buffer,addr,sizeof(addr)); create_tunnel_resp->gnb_addr.length= sizeof(addr); + create_tunnel_resp->pdusession_id[i] = create_tunnel_req->pdusession_id[i]; } return !GTPNOK;