Merge branch 'integration_2023_w18b' into 'develop'

integration_2023_w18b

See merge request oai/openairinterface5g!2095

* !1879 NR RRC config improvements for multi UE scenario
* !2070 Use F1 internally: UE Context Setup
* !2073 Fix reconfigurationWithSync
* !2086 F1 Setup Request DUname is optional
* !2062 remove pdu session duplicated structs
* !2066 NR UE rework RRC MAC config
* !2075 bugfix in computing CCEs for DCI
* !2089 chore(build): adding docker support for rocky-linux
* !2091 Removal of "disableConcurrentBuilds" option from jenkinsfiles
* !2093 Modification of documentation for CI testbenches
This commit is contained in:
Robert Schmidt
2023-05-08 13:22:01 +00:00
89 changed files with 2862 additions and 2036 deletions
+20 -23
View File
@@ -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") {
-1
View File
@@ -61,7 +61,6 @@ pipeline {
label pythonExecutor
}
options {
disableConcurrentBuilds()
timestamps()
ansiColor('xterm')
lock(extra: lockResources)
-1
View File
@@ -55,7 +55,6 @@ pipeline {
label pythonExecutor
}
options {
disableConcurrentBuilds()
timestamps()
ansiColor('xterm')
lock(extra: lockResources)
-1
View File
@@ -36,7 +36,6 @@ pipeline {
label nodeExecutor
}
options {
disableConcurrentBuilds()
ansiColor('xterm')
lock(extra: lockResources)
}
-1
View File
@@ -61,7 +61,6 @@ pipeline {
label pythonExecutor
}
options {
disableConcurrentBuilds()
ansiColor('xterm')
lock(extra: lockResources)
}
-1
View File
@@ -50,7 +50,6 @@ pipeline {
label pythonExecutor
}
options {
disableConcurrentBuilds()
ansiColor('xterm')
lock(extra: lockResources)
}
-1
View File
@@ -52,7 +52,6 @@ def StatusForDb = ""
pipeline {
agent {label pythonExecutor}
options {
disableConcurrentBuilds()
ansiColor('xterm')
lock(extra: lockResources)
}
-1
View File
@@ -63,7 +63,6 @@ pipeline {
label pythonExecutor
}
options {
disableConcurrentBuilds()
ansiColor('xterm')
lock(extra: lockResources)
}
-1
View File
@@ -63,7 +63,6 @@ pipeline {
label pythonExecutor
}
options {
disableConcurrentBuilds()
ansiColor('xterm')
lock(extra: lockResources)
}
@@ -0,0 +1,74 @@
<!--
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
-->
<testCaseList>
<htmlTabRef>rfsim-5gnr-f1-accelleran</htmlTabRef>
<htmlTabName>F1 DU Interop Accelleran CU</htmlTabName>
<htmlTabIcon>wrench</htmlTabIcon>
<TestCaseRequestedList>
111111
000020
000021
020021
100021
100022
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="111111">
<class>Pull_Local_Registry</class>
<desc>Pull Images from Local Registry</desc>
<test_svr_id>0</test_svr_id>
<images_to_pull>oai-gnb oai-nr-ue</images_to_pull>
</testCase>
<testCase id="000020">
<class>DeployGenObject</class>
<desc>Deploy OAI-DU</desc>
<yaml_path>yaml_files/5g_rfsimulator_accelleran</yaml_path>
<services>oai-du</services>
<nb_healthy>1</nb_healthy>
</testCase>
<testCase id="000021">
<class>DeployGenObject</class>
<desc>Deploy nrUE</desc>
<yaml_path>yaml_files/5g_rfsimulator_accelleran</yaml_path>
<services>oai-nr-ue</services>
<nb_healthy>2</nb_healthy>
</testCase>
<testCase id="020021">
<class>PingFromContainer</class>
<desc>Test Connectivity (ping)</desc>
<container_name>rfsim5g-oai-nr-ue</container_name>
<options>-I oaitun_ue1 -c 20 12.1.1.1</options>
<loss_threshold>0</loss_threshold>
</testCase>
<testCase id="100022">
<class>UndeployGenObject</class>
<desc>Undeploy all OAI 5G stack</desc>
<yaml_path>yaml_files/5g_rfsimulator_accelleran</yaml_path>
</testCase>
</testCaseList>
@@ -0,0 +1,45 @@
<!--
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
-->
<testCaseList>
<htmlTabRef>rfsim-5gnr-down-f1-accelleran</htmlTabRef>
<htmlTabName>CleanUp</htmlTabName>
<htmlTabIcon>trash</htmlTabIcon>
<TestCaseRequestedList>
100022
222222
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="100022">
<class>UndeployGenObject</class>
<desc>Undeploy all OAI 5G stack</desc>
<yaml_path>yaml_files/5g_rfsimulator_accelleran</yaml_path>
</testCase>
<testCase id="222222">
<class>Clean_Test_Server_Images</class>
<desc>Clean Test Images on Test Server</desc>
<test_svr_id>0</test_svr_id>
</testCase>
</testCaseList>
@@ -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
+13 -6
View File
@@ -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
+44
View File
@@ -11,6 +11,7 @@
</td>
</tr>
</table>
# 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 |
| |
+-------------+
```
+11 -7
View File
@@ -55,7 +55,7 @@ Note: The available resources, and their current usage, is indicated here:
### 5G AW2S Testbench
**Purpose**: AW2S tests with Amarisoft
**Purpose**: AW2S tests with Amarisoft UE simulator
![5G AW2S Testbench](testbenches_doc_resources/5g-aw2s-bench.png)
@@ -82,7 +82,10 @@ Webhook
- [RAN-gNB-N300-Timing-Phytest-LDPC](https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-gNB-N300-Timing-Phytest-LDPC/)
- caracal + N310
- pure performance test through phy-test scheduler, see command line for more details
- [RAN-L2-Sim-Test-5G](https://jenkins-oai.eurecom.fr/job/RAN-L2-Sim-Test-4G/)
- [RAN-Interop-F1](https://jenkins-oai.eurecom.fr/job/RAN-Interop-F1/)
- ofqot (DU, 1x UE)
- F1 interoperability testing: sets up connection to Accelleran CU, UE connection and connectivity test
- [RAN-L2-Sim-Test-4G](https://jenkins-oai.eurecom.fr/job/RAN-L2-Sim-Test-4G/)
- obelix (eNB, 1x UE, OAI EPC)
- L2simulator: skips physical layer and uses proxy between eNB and UE
- [RAN-L2-Sim-Test-5G](https://jenkins-oai.eurecom.fr/job/RAN-L2-Sim-Test-5G/)
@@ -92,7 +95,7 @@ Webhook
- hutch + B210, nano w/ ltebox + 2x UE
- tests RRC inactivity timers, different bandwidths
- [RAN-LTE-TDD-2x2-Container](https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-LTE-TDD-2x2-Container/)
- obelix + N310, porcepix, quectel
- obelix + N310, porcepix, nrmodule2 + Quectel
- TM1 and TM2 test
- [RAN-LTE-TDD-LTEBOX-Container](https://jenkins-oai.eurecom.fr/job/RAN-LTE-TDD-LTEBOX-Container/)
- starsky + B210, nano w/ ltebox + 2x UE
@@ -111,14 +114,15 @@ Webhook
- uses RFsimulator, TDD 40MHz, FDD 40MHz, F1 split
- [RAN-RHEL8-Cluster-Image-Builder](https://jenkins-oai.eurecom.fr/job/RAN-RHEL8-Cluster-Image-Builder/)
- cluster (`Asterix-OC-oaicicd-session` resource): RHEL 8 image build using the OpenShift Cluster
- [RAN-SA-AW2S-CN5G](https://jenkins-oai.eurecom.fr/job/RAN-SA-AW2S-CN5G/)
- 5G-NR SA test setup: avra(RHEL9.1) + AW2S, amariue, OAI CN5G
- uses OpenShift cluster for CN deployment and container images for gNB deployment
- multi UE testing
- [RAN-SA-B200-Module-SABOX-Container](https://jenkins-oai.eurecom.fr/job/RAN-SA-B200-Module-SABOX-Container/)
- ofqot + B200, idefix + Quectel, nepes w/ sabox
- basic SA test (20 MHz TDD), F1, reestablishment, ...
- [RAN-Ubuntu20-Image-Builder](https://jenkins-oai.eurecom.fr/job/RAN-Ubuntu18-Image-Builder/)
- [RAN-Ubuntu18-Image-Builder](https://jenkins-oai.eurecom.fr/job/RAN-Ubuntu18-Image-Builder/)
- obelix: Ubuntu 20 image build using docker (Note: builds U20 images while pipeline is named U18!)
- [RAN-SA-AW2S-CN5G](https://jenkins-oai.eurecom.fr/job/RAN-SA-AW2S-CN5G/)
- 5G-NR SA test setup: Avra(RHEL9.1)/Manarola(U22PRO) + AW2S, Amarisoft UE x1, OAI CN5G
- uses OpenShift cluster for CN deployment and container images for gNB deployment
### RAN-CI-NSA-Trigger
Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

@@ -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}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 609 KiB

After

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 453 KiB

After

Width:  |  Height:  |  Size: 138 KiB

+58
View File
@@ -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
+1 -1
View File
@@ -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
+38
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+130
View File
@@ -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"]
+105
View File
@@ -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"]
+138
View File
@@ -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"]
+123
View File
@@ -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"]
+80
View File
@@ -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"]
+138
View File
@@ -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"]
+1 -1
View File
@@ -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
+5
View File
@@ -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:
+1 -1
View File
@@ -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();
}
+19 -19
View File
@@ -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++;
+6 -1
View File
@@ -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;
-3
View File
@@ -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];
+10 -14
View File
@@ -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;
+7 -6
View File
@@ -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);
@@ -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;
}
@@ -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:
+121 -133
View File
@@ -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; i<num_slots_ul; i++)
pthread_mutex_init(&(mac->ul_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);
}
+1 -1
View File
@@ -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;
+23 -17
View File
@@ -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);
+9 -16
View File
@@ -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; i<num_slots_ul; i++)
pthread_mutex_init(&(nr_ue_mac_inst->ul_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__);
}
@@ -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; j<number_of_candidates; i++,j++) {
int first_cce = aggregation * (( Y + CEILIDIV((j*N_cces),(aggregation*number_of_candidates)) + 0 ) % CEILIDIV(N_cces,aggregation));
int N_cces = N_cce_sym * rel15->coreset.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:
+32 -35
View File
@@ -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) {
+12 -57
View File
@@ -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;
+42 -96
View File
@@ -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<<subcarrierSpacing) + sl_ahead;
LOG_I(NR_MAC, "Activating RRC processing timer for UE %04x with %d ms\n", UE_info->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;
}
+4 -1
View File
@@ -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);
}
+169 -128
View File
@@ -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);
}
+40 -41
View File
@@ -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;
@@ -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;
@@ -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];
@@ -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; m<nr_of_candidates; m++) { // loop over candidates
for(int m = 0; m < nr_of_candidates; m++) { // loop over candidates
bool taken = false; // flag if the resource for a given candidate are taken
int first_cce = aggregation * (( Y + CEILIDIV((m*N_cces),(aggregation*nr_of_candidates)) + N_ci ) % CEILIDIV(N_cces,aggregation));
int first_cce = aggregation * ((Y + ((m * N_cces) / (aggregation * nr_of_candidates)) + N_ci) % (N_cces / aggregation));
LOG_D(NR_MAC,"Candidate %d of %d first_cce %d (L %d N_cces %d Y %d)\n", m, nr_of_candidates, first_cce, aggregation, N_cces, Y);
for (int j=first_cce; (j<first_cce+aggregation) && !taken; j++) { // loop over CCEs
for (int k=6*j/L; (k<(6*j/L+6/L)) && !taken; k++) { // loop over REG bundles
for (int j = first_cce; (j < first_cce + aggregation) && !taken; j++) { // loop over CCEs
for (int k = 6 * j / L; (k < (6 * j / L + 6 / L)) && !taken; k++) { // loop over REG bundles
int f = cce_to_reg_interleaving(R, k, pdcch->ShiftIndex, C, L, N_regs);
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)) {
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; i<MAX_MOBILES_PER_GNB; i++) {
if (UE_info->list[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 */
+23 -4
View File
@@ -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) {
+88 -83
View File
@@ -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<bitlen; i++)
rev_bits |= ((payload[(start_bit+i)/8]>>((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; l<pucch->nr_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;
+111 -69
View File
@@ -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)) {
-83
View File
@@ -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,
+122 -4
View File
@@ -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)
{
@@ -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 */
+2
View File
@@ -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;
@@ -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;
}
@@ -19,11 +19,47 @@
* conmnc_digit_lengtht@openairinterface.org
*/
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#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;
}
+10 -2
View File
@@ -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);
+22
View File
@@ -41,6 +41,25 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#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__ */
+1 -1
View File
@@ -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);
}
-1
View File
@@ -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];
+6 -1
View File
@@ -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,
-1
View File
@@ -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];
+4 -3
View File
@@ -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);
}
+5 -3
View File
@@ -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));
+1 -1
View File
@@ -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);
+2
View File
@@ -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;
+1
View File
@@ -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;
}
+18
View File
@@ -19,9 +19,26 @@
* conmnc_digit_lengtht@openairinterface.org
*/
#include <stdlib.h>
#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;
}
+91 -85
View File
@@ -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;
+31 -37
View File
@@ -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;
+1 -2
View File
@@ -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);
+432 -780
View File
File diff suppressed because it is too large Load Diff
+9 -9
View File
@@ -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);
+106 -139
View File
@@ -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);
+3 -6
View File
@@ -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);
+1 -4
View File
@@ -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);
+8 -5
View File
@@ -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 */
+21 -26
View File
@@ -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",
+1 -1
View File
@@ -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);
+15
View File
@@ -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); \
+1
View File
@@ -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;