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

@@ -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;