diff --git a/ci-scripts/Jenkinsfile-push-registry b/ci-scripts/Jenkinsfile-push-registry
index 541999e8ff..d3bd5e6e64 100644
--- a/ci-scripts/Jenkinsfile-push-registry
+++ b/ci-scripts/Jenkinsfile-push-registry
@@ -76,7 +76,7 @@ pipeline {
withCredentials([
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.DH_Credentials}", usernameVariable: 'DH_Username', passwordVariable: 'DH_Password']
]) {
- def listOfImages = ["oai-enb", "oai-gnb", "oai-lte-ue", "oai-nr-ue", "oai-nr-cuup"]
+ def listOfImages = ["oai-enb", "oai-gnb", "oai-lte-ue", "oai-nr-ue", "oai-nr-cuup", "oai-gnb-fhi72"]
// Logging in on both registries
sh "docker login -u ${DH_Username} -p ${DH_Password} > /dev/null 2>&1"
sh "docker login -u oaicicd -p oaicicd porcepix.sboai.cs.eurecom.fr > /dev/null 2>&1"
diff --git a/ci-scripts/cls_cluster.py b/ci-scripts/cls_cluster.py
index d35b73890b..80d6d95daa 100644
--- a/ci-scripts/cls_cluster.py
+++ b/ci-scripts/cls_cluster.py
@@ -462,6 +462,34 @@ class Cluster:
self.cmd.run(f'oc logs {nrue_job} &> cmake_targets/log/oai-nr-ue.log')
self.cmd.run(f'oc get pods.metrics.k8s.io &>> cmake_targets/log/build-metrics.log', '\$', 10)
+ if status:
+ self._recreate_is_tag('ran-build-fhi72', imageTag, 'openshift/ran-build-fhi72-is.yaml')
+ self._recreate_bc('ran-build-fhi72', imageTag, 'openshift/ran-build-fhi72-bc.yaml')
+ self._retag_image_statement('ran-base', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-base', baseTag, 'docker/Dockerfile.build.fhi72.rhel9')
+ ranbuildfhi72_job = self._start_build('ran-build-fhi72')
+ attemptedImages += ['ran-build-fhi72']
+
+ wait = ranbuildfhi72_job is not None and self._wait_build_end([ranbuildfhi72_job], 1200)
+ if not wait: logging.error('error during build of ranbuildfhi72_job')
+ status = status and wait
+ self.cmd.run(f'oc logs {ranbuildfhi72_job} &> cmake_targets/log/ran-build-fhi72.log')
+ self.cmd.run(f'oc get pods.metrics.k8s.io &>> cmake_targets/log/build-metrics.log', '\$', 10)
+
+ if status:
+ self._recreate_is_tag('oai-gnb-fhi72', imageTag, 'openshift/oai-gnb-fhi72-is.yaml')
+ self._recreate_bc('oai-gnb-fhi72', imageTag, 'openshift/oai-gnb-fhi72-bc.yaml')
+ self._retag_image_statement('ran-base', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-base', baseTag, 'docker/Dockerfile.gNB.fhi72.rhel9')
+ self._retag_image_statement('ran-build-fhi72', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-build-fhi72', imageTag, 'docker/Dockerfile.gNB.fhi72.rhel9')
+ gnb_fhi72_job = self._start_build('oai-gnb-fhi72')
+ attemptedImages += ['oai-gnb-fhi72']
+
+ wait = gnb_fhi72_job is not None and self._wait_build_end([gnb_fhi72_job], 600)
+ if not wait: logging.error('error during build of gNB-fhi72')
+ status = status and wait
+ # recover logs
+ self.cmd.run(f'oc logs {gnb_fhi72_job} &> cmake_targets/log/oai-gnb-fhi72.log')
+ self.cmd.run(f'oc get pods.metrics.k8s.io &>> cmake_targets/log/build-metrics.log', '\$', 10)
+
# split and analyze logs
imageSize = {}
for image in attemptedImages:
diff --git a/ci-scripts/cls_containerize.py b/ci-scripts/cls_containerize.py
index 911a6555b5..94d7526813 100644
--- a/ci-scripts/cls_containerize.py
+++ b/ci-scripts/cls_containerize.py
@@ -58,7 +58,7 @@ import cls_oaicitest
# Helper functions used here and in other classes
# (e.g., cls_cluster.py)
#-----------------------------------------------------------
-IMAGES = ['oai-enb', 'oai-lte-ru', 'oai-lte-ue', 'oai-gnb', 'oai-nr-cuup', 'oai-gnb-aw2s', 'oai-nr-ue', 'oai-gnb-asan', 'oai-nr-ue-asan', 'oai-nr-cuup-asan', 'oai-gnb-aerial']
+IMAGES = ['oai-enb', 'oai-lte-ru', 'oai-lte-ue', 'oai-gnb', 'oai-nr-cuup', 'oai-gnb-aw2s', 'oai-nr-ue', 'oai-gnb-asan', 'oai-nr-ue-asan', 'oai-nr-cuup-asan', 'oai-gnb-aerial', 'oai-gnb-fhi72']
def CreateWorkspace(sshSession, sourcePath, ranRepository, ranCommitID, ranTargetBranch, ranAllowMerge):
if ranCommitID == '':
@@ -319,6 +319,8 @@ class Containerize():
imageNames.append(('oai-gnb', 'gNB', 'oai-gnb-asan', '--build-arg "BUILD_OPTION=--sanitize"'))
imageNames.append(('oai-nr-ue', 'nrUE', 'oai-nr-ue-asan', '--build-arg "BUILD_OPTION=--sanitize"'))
imageNames.append(('oai-nr-cuup', 'nr-cuup', 'oai-nr-cuup-asan', '--build-arg "BUILD_OPTION=--sanitize"'))
+ imageNames.append(('ran-build-fhi72', 'build.fhi72', 'ran-build-fhi72', ''))
+ imageNames.append(('oai-gnb', 'gNB.fhi72', 'oai-gnb-fhi72', ''))
result = re.search('build_cross_arm64', self.imageKind)
if result is not None:
self.dockerfileprefix = '.ubuntu22.cross-arm64'
@@ -409,6 +411,8 @@ class Containerize():
# target images should use the proper ran-build image
if image != 'ran-build' and "-asan" in name:
cmd.run(f'sed -i -e "s#ran-build:latest#ran-build-asan:{imageTag}#" docker/Dockerfile.{pattern}{self.dockerfileprefix}')
+ elif "fhi72" in name:
+ cmd.run(f'sed -i -e "s#ran-build-fhi72:latest#ran-build-fhi72:{imageTag}#" docker/Dockerfile.{pattern}{self.dockerfileprefix}')
elif image != 'ran-build':
cmd.run(f'sed -i -e "s#ran-build:latest#ran-build:{imageTag}#" docker/Dockerfile.{pattern}{self.dockerfileprefix}')
if image == 'oai-gnb-aerial':
@@ -445,7 +449,7 @@ class Containerize():
cmd.run(f"{self.cli} image prune --force")
# Remove all intermediate build images and clean up
- cmd.run(f"{self.cli} image rm ran-build:{imageTag} ran-build-asan:{imageTag}")
+ cmd.run(f"{self.cli} image rm ran-build:{imageTag} ran-build-asan:{imageTag} ran-build-fhi72:{imageTag} || true")
cmd.run(f"{self.cli} volume prune --force")
# Remove some cached artifacts to prevent out of diskspace problem
diff --git a/ci-scripts/yaml_files/5g_rfsimulator/docker-compose.yaml b/ci-scripts/yaml_files/5g_rfsimulator/docker-compose.yaml
index e46e9b1ab4..06c945a250 100644
--- a/ci-scripts/yaml_files/5g_rfsimulator/docker-compose.yaml
+++ b/ci-scripts/yaml_files/5g_rfsimulator/docker-compose.yaml
@@ -109,7 +109,7 @@ services:
- NET_ADMIN # for interface bringup
- NET_RAW # for ping
environment:
- USE_ADDITIONAL_OPTIONS: -E --sa --rfsim -r 106 --numerology 1 --uicc0.imsi 208990100001100 -C 3619200000 --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time
+ USE_ADDITIONAL_OPTIONS: -E --sa --rfsim -r 106 --numerology 1 --uicc0.imsi 208990100001100 -C 3319680000 --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time
depends_on:
- oai-gnb
networks:
@@ -133,7 +133,7 @@ services:
- NET_ADMIN # for interface bringup
- NET_RAW # for ping
environment:
- USE_ADDITIONAL_OPTIONS: -E --sa --rfsim -r 106 --numerology 1 --uicc0.imsi 208990100001101 -C 3619200000 --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time
+ USE_ADDITIONAL_OPTIONS: -E --sa --rfsim -r 106 --numerology 1 --uicc0.imsi 208990100001101 -C 3319680000 --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time
depends_on:
- oai-gnb
networks:
@@ -157,7 +157,7 @@ services:
- NET_ADMIN # for interface bringup
- NET_RAW # for ping
environment:
- USE_ADDITIONAL_OPTIONS: -E --sa --rfsim -r 106 --numerology 1 --uicc0.imsi 208990100001102 -C 3619200000 --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time
+ USE_ADDITIONAL_OPTIONS: -E --sa --rfsim -r 106 --numerology 1 --uicc0.imsi 208990100001102 -C 3319680000 --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time
depends_on:
- oai-gnb
networks:
@@ -181,7 +181,7 @@ services:
- NET_ADMIN # for interface bringup
- NET_RAW # for ping
environment:
- USE_ADDITIONAL_OPTIONS: -E --sa --rfsim -r 106 --numerology 1 --uicc0.imsi 208990100001103 -C 3619200000 --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time
+ USE_ADDITIONAL_OPTIONS: -E --sa --rfsim -r 106 --numerology 1 --uicc0.imsi 208990100001103 -C 3319680000 --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time
depends_on:
- oai-gnb
networks:
@@ -205,7 +205,7 @@ services:
- NET_ADMIN # for interface bringup
- NET_RAW # for ping
environment:
- USE_ADDITIONAL_OPTIONS: -E --sa --rfsim -r 106 --numerology 1 --uicc0.imsi 208990100001104 -C 3619200000 --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time
+ USE_ADDITIONAL_OPTIONS: -E --sa --rfsim -r 106 --numerology 1 --uicc0.imsi 208990100001104 -C 3319680000 --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time
depends_on:
- oai-gnb
networks:
@@ -229,7 +229,7 @@ services:
- NET_ADMIN # for interface bringup
- NET_RAW # for ping
environment:
- USE_ADDITIONAL_OPTIONS: -E --sa --rfsim -r 106 --numerology 1 --uicc0.imsi 208990100001105 -C 3619200000 --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time
+ USE_ADDITIONAL_OPTIONS: -E --sa --rfsim -r 106 --numerology 1 --uicc0.imsi 208990100001105 -C 3319680000 --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time
depends_on:
- oai-gnb
networks:
@@ -253,7 +253,7 @@ services:
- NET_ADMIN # for interface bringup
- NET_RAW # for ping
environment:
- USE_ADDITIONAL_OPTIONS: -E --sa --rfsim -r 106 --numerology 1 --uicc0.imsi 208990100001106 -C 3619200000 --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time
+ USE_ADDITIONAL_OPTIONS: -E --sa --rfsim -r 106 --numerology 1 --uicc0.imsi 208990100001106 -C 3319680000 --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time
depends_on:
- oai-gnb
networks:
@@ -277,7 +277,7 @@ services:
- NET_ADMIN # for interface bringup
- NET_RAW # for ping
environment:
- USE_ADDITIONAL_OPTIONS: -E --sa --rfsim -r 106 --numerology 1 --uicc0.imsi 208990100001107 -C 3619200000 --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time
+ USE_ADDITIONAL_OPTIONS: -E --sa --rfsim -r 106 --numerology 1 --uicc0.imsi 208990100001107 -C 3319680000 --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time
depends_on:
- oai-gnb
networks:
@@ -301,7 +301,7 @@ services:
- NET_ADMIN # for interface bringup
- NET_RAW # for ping
environment:
- USE_ADDITIONAL_OPTIONS: -E --sa --rfsim -r 106 --numerology 1 --uicc0.imsi 208990100001108 -C 3619200000 --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time
+ USE_ADDITIONAL_OPTIONS: -E --sa --rfsim -r 106 --numerology 1 --uicc0.imsi 208990100001108 -C 3319680000 --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time
depends_on:
- oai-gnb
networks:
@@ -325,7 +325,7 @@ services:
- NET_ADMIN # for interface bringup
- NET_RAW # for ping
environment:
- USE_ADDITIONAL_OPTIONS: -E --sa --rfsim -r 106 --numerology 1 --uicc0.imsi 208990100001109 -C 3619200000 --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time
+ USE_ADDITIONAL_OPTIONS: -E --sa --rfsim -r 106 --numerology 1 --uicc0.imsi 208990100001109 -C 3319680000 --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time
depends_on:
- oai-gnb
networks:
diff --git a/ci-scripts/yaml_files/sa_fhi_7.2_gnb/README.md b/ci-scripts/yaml_files/sa_fhi_7.2_gnb/README.md
new file mode 100644
index 0000000000..1acbe7fb86
--- /dev/null
+++ b/ci-scripts/yaml_files/sa_fhi_7.2_gnb/README.md
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+ |
+
+ OAI O-RAN 7.2 Front-haul Docker Compose
+ |
+
+
+
+
+
+This docker-compose is designed to use `OAI-gNB` with a 7.2 compatible Radio Unit. Before using this docker compose you have to configure
+the host machine as per the [ORAN_FHI7.2_Tutorial](../../../doc/ORAN_FHI7.2_Tutorial.md). The container image used by the docker compose file is tested only on `Ubuntu 22.04` docker host.
+
+## Build Image (Optional)
+
+Refer to [OAI Docker/Podman Build and Usage Procedures](../../../docker/README.md)
+
+## Configure Networking
+
+### SR-IOV Virtual Functions (VFs)
+
+In docker-compose environment there is no automated method
+to configure the VFs on the fly. The user will have to manually configure
+C/U plane VFs before starting the container `OAI-gNB`.
+
+You can follow the step
+[configure-network-interfaces-and-dpdk-vfs](../../../doc/ORAN_FHI7.2_Tutorial.md#configure-network-interfaces-and-dpdk-vfs).
+
+### Interface towards AMF (N2)
+
+For `N2` interface we are using `macvlan` driver of docker.
+
+You can use the `bridge` driver, in situation
+
+- When the core network is running on the same machine
+- or different machine but you have configured
+needed `ip route` and forwarding to access the core network from RAN host.
+
+To configure docker `macvlan` network
+you need to choose `ipam.config` and `driver_opts.parent` are per your environment
+
+```
+ oai-net:
+ driver: macvlan
+ name: oai-net
+ ipam:
+ config:
+ - subnet: "172.21.16.0/22"
+ ip_range: "172.21.18.20/32"
+ gateway: "172.21.19.254"
+ driver_opts:
+ com.docker.network.bridge.name: "oai-net"
+ parent: enp193s0f0
+```
+
+To configure `bridge` network you need to choose `ipam.config.subnet` as per your environment.
+
+```
+ oai-net:
+ driver: bridge
+ name: oai-net
+ ipam:
+ config:
+ - subnet: 192.168.72.128/26
+ driver_opts:
+ com.docker.network.bridge.name: "oai-net"
+```
+
+## Deploy OAI-gNB Container
+
+The [configuration file](../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.273prb.fhi72.4x4-benetel650.conf) used by docker compose is configured for Benetel 650 RU (RAN650-1v1.0.4-dda1bf5).
+
+```bash
+docker-compose up -d
+```
+
+To check the logs
+
+```bash
+docker logs oai-gnb -f
+```
diff --git a/ci-scripts/yaml_files/sa_fhi_7.2_gnb/docker-compose.yml b/ci-scripts/yaml_files/sa_fhi_7.2_gnb/docker-compose.yml
new file mode 100644
index 0000000000..e3e93b3b74
--- /dev/null
+++ b/ci-scripts/yaml_files/sa_fhi_7.2_gnb/docker-compose.yml
@@ -0,0 +1,34 @@
+services:
+ oai-gnb:
+ image: oai-gnb-fhi72:latest
+ privileged: true
+ container_name: oai-gnb
+ environment:
+ TZ: Europe/Paris
+ USE_ADDITIONAL_OPTIONS: --sa --thread-pool 13,14,15,16,17,18
+ devices:
+ - /dev/vfio:/dev/vfio/
+ volumes:
+ - ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.273prb.fhi72.4x4-benetel650.conf:/opt/oai-gnb/etc/gnb.conf
+ - /dev/hugepages:/dev/hugepages
+ cpuset: "0,1,2,8,9,10,13,14,15,16,17,18"
+ networks:
+ oai-net:
+ ipv4_address: 172.21.18.20
+ healthcheck:
+ test: /bin/bash -c "pgrep nr-softmodem"
+ interval: 10s
+ timeout: 5s
+ retries: 5
+networks:
+ oai-net:
+ driver: macvlan
+ name: oai-net
+ ipam:
+ config:
+ - subnet: "172.21.16.0/22"
+ ip_range: "172.21.18.20/32"
+ gateway: "172.21.19.254"
+ driver_opts:
+ com.docker.network.bridge.name: "oai-net"
+ parent: enp193s0f0
diff --git a/doc/RUNMODEM.md b/doc/RUNMODEM.md
index 753efdadaf..9ee9083e6d 100644
--- a/doc/RUNMODEM.md
+++ b/doc/RUNMODEM.md
@@ -188,6 +188,18 @@ cd cmake_targets
sudo ./ran_build/build/nr-softmodem -O ../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.25PRB.usrpx300.conf --sa --rfsim --rfsimulator.prop_delay 238.74
```
+### NR UE
+
+At UE side, there are two main parameters to cope with the large NTN propagation delay, cellSpecificKoffset and ta-Common.
+`cellSpecificKoffset` is the same as for gNB and can be provided to the UE via command line parameter `--ntn-koffset`.
+`ta-Common` is a common timong advance and can be provided to the UE via command line parameter `--ntn-ta-common` in milliseconds.
+
+So an example NR UE command for FDD, 5MHz BW, 15 kHz SCS, GEO satellite 5G NR NTN is this:
+```
+cd cmake_targets
+sudo ./ran_build/build/nr-uesoftmodem --band 66 -C 2152680000 --CO -400000000 -r 25 --numerology 0 --ssb 48 --sa --rfsim --rfsimulator.prop_delay 238.74 --ntn-koffset 478 --ntn-ta-common 477.48
+```
+
# Specific OAI modes
## phy-test setup with OAI UE
diff --git a/doc/images/docker-deploy-oai-7-2.drawio.xml b/doc/images/docker-deploy-oai-7-2.drawio.xml
new file mode 100644
index 0000000000..eadd0a5bf5
--- /dev/null
+++ b/doc/images/docker-deploy-oai-7-2.drawio.xml
@@ -0,0 +1,214 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/images/docker-deploy-oai-7-2.png b/doc/images/docker-deploy-oai-7-2.png
new file mode 100644
index 0000000000..58c323b9de
Binary files /dev/null and b/doc/images/docker-deploy-oai-7-2.png differ
diff --git a/docker/Dockerfile.base.rhel9 b/docker/Dockerfile.base.rhel9
index 1fc3fa973f..03b4ccac91 100644
--- a/docker/Dockerfile.base.rhel9
+++ b/docker/Dockerfile.base.rhel9
@@ -21,12 +21,13 @@
#---------------------------------------------------------------------
#
# Dockerfile for the Open-Air-Interface BUILD service
-# Valid for RHEL9
+# Valid for UBI9
#
#---------------------------------------------------------------------
FROM registry.access.redhat.com/ubi9/ubi:latest AS ran-base
+LABEL MAINTAINER OpenAirInterface
ARG NEEDED_GIT_PROXY
ENV TZ=Europe/Paris
ENV BUILD_UHD_FROM_SOURCE=True
@@ -35,10 +36,6 @@ ENV UHD_VERSION=4.4.0.0
# Copy the entitlements
COPY ./etc-pki-entitlement /etc/pki/entitlement
-# Copy the subscription manager configurations
-COPY ./rhsm-conf /etc/rhsm
-COPY ./rhsm-ca /etc/rhsm/ca
-
ENV SMDEV_CONTAINER_OFF=1
#install developers pkg/repo
RUN rm -f /etc/rhsm-host && \
@@ -47,11 +44,21 @@ RUN rm -f /etc/rhsm-host && \
cat /etc/os-release && \
dnf install -y \
#gcc needed for build_oai
- gcc gcc-c++ \
diffutils \
file \
psmisc \
git \
+ meson \
+ wget \
+ xz \
+ pkg-config \
+ pcre2-devel \
+ m4 \
+ python3-devel \
+ numactl-libs \
+ numactl-devel \
+ gcc-toolset-12-gcc \
+ gcc-toolset-12-gcc-c++ \
# python3-pip and pyyaml are used for conf template generation
python3-pip && \
pip3 install --ignore-installed pyyaml && \
@@ -80,8 +87,9 @@ WORKDIR /oai-ran
COPY oaienv .
#run build_oai -I to get the builder image
-RUN /bin/sh oaienv && \
+RUN /bin/sh oaienv && \
cd cmake_targets && \
mkdir -p log && \
- ./build_oai -I --install-optional-packages -w USRP && \
+ scl enable gcc-toolset-12 "\
+ ./build_oai -I --install-optional-packages -w USRP" && \
rm /etc/pki/entitlement/*pem
diff --git a/docker/Dockerfile.base.ubuntu22 b/docker/Dockerfile.base.ubuntu22
index 9ed0cd6beb..d1b90e2dcf 100644
--- a/docker/Dockerfile.base.ubuntu22
+++ b/docker/Dockerfile.base.ubuntu22
@@ -45,6 +45,11 @@ RUN apt-get update && \
gcc-12 \
g++-12 \
xxd \
+ libpcre2-dev \
+ python3-dev \
+ bison \
+ flex \
+ m4 \
# python3-pip for conf template generation
python3-pip && \
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-12 100 --slave /usr/bin/g++ g++ /usr/bin/g++-12 && \
diff --git a/docker/Dockerfile.build.fhi72.rhel9 b/docker/Dockerfile.build.fhi72.rhel9
new file mode 100644
index 0000000000..fc5570a85c
--- /dev/null
+++ b/docker/Dockerfile.build.fhi72.rhel9
@@ -0,0 +1,79 @@
+#/*
+# * 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 RAN Build for FHI 7.2
+# Valid for UBI9
+#
+#---------------------------------------------------------------------
+
+FROM ran-base:latest as ran-base
+ENV TZ=Europe
+
+RUN rm -Rf /oai-ran
+WORKDIR /oai-ran
+COPY . .
+
+## Download and build DPDK
+RUN wget http://fast.dpdk.org/rel/dpdk-20.11.9.tar.xz && \
+ tar -xvf dpdk-20.11.9.tar.xz && \
+ cd dpdk-stable-20.11.9 && \
+ meson build && \
+ ninja -C build && \
+ ninja install -C build
+
+## Build Fronthaul library
+RUN git clone https://gerrit.o-ran-sc.org/r/o-du/phy.git /opt/phy && \
+ cd /opt/phy && \
+ git checkout oran_e_maintenance_release_v1.0 &&\
+ git apply /oai-ran/cmake_targets/tools/oran_fhi_integration_patches/E/oaioran_E.patch && \
+ cd /opt/phy/fhi_lib/lib && \
+ RTE_SDK=/oai-ran/dpdk-stable-20.11.9/ XRAN_DIR=/opt/phy/fhi_lib make XRAN_LIB_SO=1
+
+FROM ran-base as ran-build-fhi72
+ARG E2AP_VERSION=E2AP_V3
+ARG KPM_VERSION=KPM_V3_00
+
+## Build and install OAI
+RUN /bin/sh oaienv && \
+ cd cmake_targets && \
+ mkdir -p log && \
+ scl enable gcc-toolset-12 "\
+ ./build_oai \
+ --gNB \
+ --build-lib 'telnetsrv enbscope uescope nrscope' \
+ -t oran_fhlib_5g --cmake-opt -Dxran_LOCATION=/opt/phy/fhi_lib/lib \
+ --build-e2 --cmake-opt -DXAPP_MULTILANGUAGE=OFF --cmake-opt -DKPM_VERSION=$KPM_VERSION --cmake-opt -DE2AP_VERSION=$E2AP_VERSION" &&\
+ # Mainly to see if the sanitize option was perfectly executed
+ ldd ran_build/build/nr-softmodem && \
+ ldd ran_build/build/liboran_fhlib_5g.so && \
+ ldd /opt/phy/fhi_lib/lib/build/libxran.so
+
+## Build FlexRIC for SM Models
+RUN mkdir -p openair2/E2AP/flexric/build && \
+ cd openair2/E2AP/flexric/build && \
+ scl enable gcc-toolset-12 "\
+ cmake -GNinja -DCMAKE_BUILD_TYPE=Release \
+ -DXAPP_MULTILANGUAGE=OFF \
+ -DKPM_VERSION=$KPM_VERSION \
+ -DE2AP_VERSION=$E2AP_VERSION .. &&\
+ ninja && \
+ ninja install"
diff --git a/docker/Dockerfile.build.fhi72.ubuntu22 b/docker/Dockerfile.build.fhi72.ubuntu22
new file mode 100644
index 0000000000..774f488ed7
--- /dev/null
+++ b/docker/Dockerfile.build.fhi72.ubuntu22
@@ -0,0 +1,91 @@
+#/*
+# * 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 RAN Build for FHI 7.2
+# Valid for UBUNTU 22.04
+#
+#---------------------------------------------------------------------
+
+FROM ran-base:latest as ran-base
+
+ARG E2AP_VERSION=E2AP_V3
+ARG KPM_VERSION=KPM_V3_00
+ENV DEBIAN_FRONTEND=noninteractive
+ENV TZ=Europe
+RUN apt-get update && \
+ DEBIAN_FRONTEND=noninteractive apt-get upgrade --yes && \
+ DEBIAN_FRONTEND=noninteractive apt-get install --yes \
+ meson \
+ wget \
+ xz-utils \
+ pkg-config \
+ libnuma-dev && \
+ rm -rf /var/lib/apt/lists/*
+
+RUN rm -Rf /oai-ran
+WORKDIR /oai-ran
+COPY . .
+
+## Download and build DPDK
+RUN wget http://fast.dpdk.org/rel/dpdk-20.11.9.tar.xz && \
+ tar -xvf dpdk-20.11.9.tar.xz && \
+ cd dpdk-stable-20.11.9 && \
+ meson build && \
+ ninja -C build && \
+ ninja install -C build
+
+## Build Fronthaul library
+RUN git clone https://gerrit.o-ran-sc.org/r/o-du/phy.git /opt/phy && \
+ cd /opt/phy && \
+ git checkout oran_e_maintenance_release_v1.0 &&\
+ git apply /oai-ran/cmake_targets/tools/oran_fhi_integration_patches/E/oaioran_E.patch && \
+ cd /opt/phy/fhi_lib/lib && \
+ RTE_SDK=/oai-ran/dpdk-stable-20.11.9/ XRAN_DIR=/opt/phy/fhi_lib make XRAN_LIB_SO=1
+
+FROM ran-base as ran-build-fhi72
+## Build and install OAI
+#run build_oai to build the target image
+RUN /bin/sh oaienv && \
+ cd cmake_targets && \
+ mkdir -p log && \
+ ./build_oai \
+ --gNB \
+ --build-lib "telnetsrv enbscope uescope nrscope" \
+ -t oran_fhlib_5g --cmake-opt -Dxran_LOCATION=/opt/phy/fhi_lib/lib \
+ --build-e2 --cmake-opt -DXAPP_MULTILANGUAGE=OFF --cmake-opt -DKPM_VERSION=$KPM_VERSION --cmake-opt -DE2AP_VERSION=$E2AP_VERSION && \
+ $BUILD_OPTION && \
+ # Mainly to see if the sanitize option was perfectly executed
+ ldd ran_build/build/nr-softmodem && \
+ ldd ran_build/build/liboran_fhlib_5g.so && \
+ ldd /opt/phy/fhi_lib/lib/build/libxran.so
+
+## Build FlexRIC for SM Models
+RUN mkdir -p openair2/E2AP/flexric/build && \
+ cd openair2/E2AP/flexric/build && \
+ cmake -GNinja -DCMAKE_BUILD_TYPE=Release \
+ -DXAPP_MULTILANGUAGE=OFF \
+ -DKPM_VERSION=$KPM_VERSION \
+ -DE2AP_VERSION=$E2AP_VERSION \
+ -DCMAKE_C_COMPILER=gcc-12 \
+ -DCMAKE_CXX_COMPILER=g++-12 .. && \
+ ninja && \
+ ninja install
diff --git a/docker/Dockerfile.gNB.fhi72.rhel9 b/docker/Dockerfile.gNB.fhi72.rhel9
new file mode 100644
index 0000000000..6bac3c71d9
--- /dev/null
+++ b/docker/Dockerfile.gNB.fhi72.rhel9
@@ -0,0 +1,125 @@
+#/*
+# * 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 7.2 Fronthaul
+# Valid for UBI9
+#
+#---------------------------------------------------------------------
+
+FROM ran-base:latest as gnb-base
+
+FROM ran-build-fhi72:latest as gnb-build
+
+#start from scratch for target executable
+FROM registry.access.redhat.com/ubi9/ubi:latest as oai-gnb-fhi72
+ENV TZ=Europe/Paris
+
+# Copy the entitlements
+COPY ./etc-pki-entitlement /etc/pki/entitlement
+
+RUN rm -f /etc/rhsm-host && \
+ subscription-manager repos --enable codeready-builder-for-rhel-9-x86_64-rpms && \
+ dnf update -y && \
+ cat /etc/os-release && \
+ dnf install -y \
+ procps-ng \
+ libXpm \
+ libX11 \
+ lksctp-tools \
+ xz \
+ numactl-libs \
+ numactl-devel \
+ pkg-config \
+ pciutils \
+ 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 && \
+ subscription-manager repos --disable codeready-builder-for-rhel-9-x86_64-rpms && \
+ rm -rf /etc/pki/entitlement
+
+WORKDIR /opt/oai-gnb/bin
+COPY --from=gnb-build \
+ /oai-ran/cmake_targets/ran_build/build/nr-softmodem ./
+COPY ./docker/scripts/gnb_entrypoint.sh ./entrypoint.sh
+
+COPY --from=gnb-build \
+ /oai-ran/cmake_targets/ran_build/build/librfsimulator.so \
+ /oai-ran/cmake_targets/ran_build/build/liboran_fhlib_5g.so \
+ /oai-ran/cmake_targets/ran_build/build/liboai_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/libtelnetsrv.so \
+ /oai-ran/cmake_targets/ran_build/build/libtelnetsrv_ci.so \
+ /usr/local/lib/
+
+## Libxran library
+COPY --from=gnb-build \
+ /opt/phy/fhi_lib/lib/build/libxran.so \
+ /opt/phy/fhi_lib/lib/build/
+
+## Copy all DPDK libraries as liboran_fhlib_5g.so require most of them
+COPY --from=gnb-build /usr/local/lib64/ /usr/local/lib64/
+
+## Copy E2 SM models
+COPY --from=gnb-build /usr/local/lib64/flexric /usr/local/lib64/flexric
+
+# Copying file for configuration module
+COPY --from=gnb-base \
+ /lib64/libconfig.so.11 \
+ /lib64/libforms.so.2 \
+ /lib64/libblas.so.3 \
+ /lib64/libcblas.so.3 \
+ /lib64/liblapack.so.3 \
+ /lib64/liblapacke.so.3 \
+ /lib64/libicudata.so.67 \
+ /lib64/libicui18n.so.67 \
+ /lib64/libicuuc.so.67 \
+ /lib64/
+
+RUN ldconfig && \
+ echo "---- ldd on executable nr-softmodem ----" && \
+ ldd /opt/oai-gnb/bin/nr-softmodem && \
+ echo "---- ldd on shared libraries ----" && \
+ ldd /usr/local/lib/librfsimulator.so \
+ /usr/local/lib/liboran_fhlib_5g.so \
+ /usr/local/lib/liboai_transpro.so \
+ /usr/local/lib/libcoding.so \
+ /usr/local/lib/libparams_libconfig.so \
+ /usr/local/lib/libdfts.so \
+ /usr/local/lib/libldpc*.so \
+ /usr/local/lib/libtelnetsrv.so \
+ /usr/local/lib/libtelnetsrv_ci.so \
+ /opt/phy/fhi_lib/lib/build/libxran.so
+
+WORKDIR /opt/oai-gnb
+COPY --from=gnb-base /tini /tini
+ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-gnb/bin/entrypoint.sh"]
+CMD ["/opt/oai-gnb/bin/nr-softmodem", "-O", "/opt/oai-gnb/etc/gnb.conf"]
diff --git a/docker/Dockerfile.gNB.fhi72.ubuntu22 b/docker/Dockerfile.gNB.fhi72.ubuntu22
new file mode 100644
index 0000000000..5bb0ad5234
--- /dev/null
+++ b/docker/Dockerfile.gNB.fhi72.ubuntu22
@@ -0,0 +1,113 @@
+#/*
+# * 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 7.2 Fronthaul
+# Valid for Ubuntu22.04
+#
+#---------------------------------------------------------------------
+
+FROM ran-base:latest as gnb-base
+
+FROM ran-build-fhi72:latest as gnb-build
+
+
+#start from scratch for target executable
+FROM ubuntu:jammy as oai-gnb
+ARG BUILD_OPTION
+ENV DEBIAN_FRONTEND=noninteractive
+ENV TZ=Europe
+
+RUN apt-get update && \
+ DEBIAN_FRONTEND=noninteractive apt-get upgrade --yes && \
+ DEBIAN_FRONTEND=noninteractive apt-get install --yes \
+ software-properties-common \
+ procps \
+ pkg-config \
+ libsctp1 \
+ tzdata \
+ libblas3 \
+ libconfig9 \
+ openssl \
+ net-tools \
+ iperf \
+ iproute2 \
+ iputils-ping \
+ gdb \
+ pciutils \
+ libpcap-dev \
+ xz-utils \
+ libnuma-dev \
+ python3 \
+ python3-six \
+ python3-requests &&\
+# if the --sanitize option was used to build, additional packages are required
+ /bin/bash -c 'if [[ "$BUILD_OPTION" = "--sanitize" ]]; then DEBIAN_FRONTEND=noninteractive apt-get install --yes \
+ libasan5 \
+ libubsan1 \
+ liblapacke; fi' && \
+ rm -rf /var/lib/apt/lists/*
+
+WORKDIR /opt/oai-gnb/bin
+COPY --from=gnb-build \
+ /oai-ran/cmake_targets/ran_build/build/nr-softmodem ./
+COPY ./docker/scripts/gnb_entrypoint.sh ./entrypoint.sh
+
+COPY --from=gnb-build \
+ /oai-ran/cmake_targets/ran_build/build/librfsimulator.so \
+ /oai-ran/cmake_targets/ran_build/build/liboai_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/libtelnetsrv.so \
+ /oai-ran/cmake_targets/ran_build/build/libtelnetsrv_ci.so \
+ /usr/local/lib/
+
+## Libxran library
+COPY --from=gnb-build \
+ /opt/phy/fhi_lib/lib/build/libxran.so \
+ /opt/phy/fhi_lib/lib/build/
+
+## Copy all DPDK libraries as liboran_fhlib_5g.so require most of them
+COPY --from=gnb-build /usr/local/lib/x86_64-linux-gnu /usr/local/lib/x86_64-linux-gnu/
+
+## Copy E2 SM models
+COPY --from=gnb-build /usr/local/lib/flexric /usr/local/lib/flexric
+
+RUN ldconfig && \
+ echo "---- ldd on nr-softmodem ----" && \
+ ldd /opt/oai-gnb/bin/nr-softmodem && \
+ echo "---- ldd on shared libraries ----" && \
+ ldd /usr/local/lib/librfsimulator.so \
+ /usr/local/lib/liboai_transpro.so \
+ /usr/local/lib/libcoding.so \
+ /usr/local/lib/libparams_libconfig.so \
+ /usr/local/lib/libdfts.so \
+ /usr/local/lib/libldpc*.so \
+ /usr/local/lib/libtelnetsrv.so \
+ /usr/local/lib/libtelnetsrv_ci.so \
+ /opt/phy/fhi_lib/lib/build/libxran.so
+
+WORKDIR /opt/oai-gnb
+COPY --from=gnb-base /tini /tini
+ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-gnb/bin/entrypoint.sh"]
+CMD ["/opt/oai-gnb/bin/nr-softmodem", "-O", "/opt/oai-gnb/etc/gnb.conf"]
diff --git a/docker/README.md b/docker/README.md
index 483a049f9d..7ec63aacae 100644
--- a/docker/README.md
+++ b/docker/README.md
@@ -33,29 +33,30 @@ For all platforms, the strategy for building docker/podman images is the same:
into which all targets are compiled.
* Then from the `ran-build` shared image, we can build target images for:
- eNB
- - gNB (with UHD)
- - gNB (with AW2S), only on RHEL9
+ - gNB/DU (with UHD)
+ - gNB/DU (with AW2S), only on RHEL9
- lte-UE
- nr-UE
-
+ - nr-cuup
These target images will only contain:
- the generated executable (for example `lte-softmodem`)
- the generated shared libraries (for example `liboai_usrpdevif.so`)
- the needed libraries and packages to run these generated binaries
- Some configuration file templates
- Some tools (such as `ping`, `ifconfig`)
+* From the `ran-build-fhi72` image, we can build target image for:
+ - gNB/DU (with FHI 7.2)
Note that on every push to develop (i.e., typically after integrating merge
requests), we build all images and push them to [Docker Hub](https://hub.docker.com/u/oaisoftwarealliance). To pull them, do
-```
+```bash
docker pull oaisoftwarealliance/oai-gnb:develop
docker pull oaisoftwarealliance/oai-nr-ue:develop
docker pull oaisoftwarealliance/oai-enb:develop
docker pull oaisoftwarealliance/oai-lte-ue:develop
```
-Have a look at [this README](../ci-scripts/yaml_files/5g_rfsimulator/README.md) to get some
-information on how to use the images.
+Have a look at [this README](../ci-scripts/yaml_files/5g_rfsimulator/README.md) to get some information on how to use the images.
# 2. File organization #
@@ -65,18 +66,20 @@ Targets can be:
- `base` for an image named `ran-base` (shared image)
- `build` for an image named `ran-build` (shared image)
+- `build.fhi72` for an image named `ran-build-fhi72`
- `eNB` for an image named `oai-enb`
- `gNB` for an image named `oai-gnb`
- `nr-cuup` for an image named `oai-nr-cuup`
- `gNB.aw2s` for an image named `oai-gnb-aw2s`
+- `gNB.fhi` for an image named `oai-gnb-fhi72`
- `lteUE` for an image named `oai-lte-ue`
- `nrUE` for an image named `oai-nr-ue`
The currently-supported OS are:
-- `rhel9` for Red Hat Entreprise Linux (including images for an OpenShift cluster)
+- `rhel9` for Red Hat Enterprise Linux and Openshift Universal Base Image
- `ubuntu22` for Ubuntu 22.04 LTS
-- `rocky` for Rocky-Linux 8.7
+- `rocky` for Rocky-Linux 9
For more details regarding the build on an Openshift Cluster, see [OpenShift README](../openshift/README.md).
@@ -95,25 +98,28 @@ There are two shared images: one that has all dependencies, and a second that co
```bash
git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git
cd openairinterface5g
-git checkout develop
+# default branch is develop, to change use git checkout
docker build --target ran-base --tag ran-base:latest --file docker/Dockerfile.base.ubuntu22 .
+# if you want use USRP, AW2S and RFSimulator radios
docker build --target ran-build --tag ran-build:latest --file docker/Dockerfile.build.ubuntu22 .
+# if you want to use front-haul 7.2 and RFSimulator radios
+docker build --tag ran-build-fhi72:latest --file docker/Dockerfile.build.fhi72.ubuntu22 .
```
-After building both:
+After building:
```bash
docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
ran-build latest f2633a7f5102 1 minute ago 6.81GB
ran-base latest 5c9c02a5b4a8 1 minute ago 2.4GB
-
+ran-build-fhi72 latest 5190c06dbb4d 1 minute ago 6.86GB
...
```
Note that the steps are identical for `rocky-linux`.
-### 3.2.1. Additional build otions
+### 3.2.1. Additional build options
This is only available for the Ubuntu version of Dockerfiles.
@@ -149,13 +155,18 @@ For example, the eNB:
docker build --target oai-enb --tag oai-enb:latest --file docker/Dockerfile.eNB.ubuntu22 .
```
+To build gNB/DU with 7.2 fronthaul support:
+
+```bash
+docker build --target oai-gnb-fhi72 --tag oai-gnb-fhi72:latest --file docker/Dockerfile.gNB.fhi72.ubuntu22 .
+```
+
After a while:
```
docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
oai-enb latest 25ddbd8b7187 1 minute ago 516MB
- 875ea3b05b60 8 minutes ago 8.18GB
ran-build latest f2633a7f5102 1 hour ago 6.81GB
ran-base latest 5c9c02a5b4a8 1 hour ago 2.4GB
```
@@ -176,16 +187,33 @@ docker build --target oai-gnb --tag oai-gnb:latest --file docker/Dockerfile.gNB.
Normally the target image will be around 200 Mbytes bigger.
-# 4. Building using `podman` under Red Hat Entreprise Linux 8.2 #
+# 4. Building using `podman` under Red Hat Entreprise Linux 9.X #
Analogous to the above steps:
-```
-sudo podman build --target ran-base --tag ran-base:latest --file docker/Dockerfile.base.rhel9 .
-sudo podman build --target ran-build --tag ran-build:latest --file docker/Dockerfile.build.rhel9 .
-sudo podman build --target oai-enb --tag oai-enb:latest --file docker/Dockerfile.eNB.rhel9 .
+
+```bash
+podman build --target ran-base --tag ran-base:latest --file docker/Dockerfile.base.rhel9 .
+# if you want use USRP, AW2S and RFSimulator radios
+podman build --target ran-build --tag ran-build:latest --file docker/Dockerfile.build.rhel9 .
+# if you want to use front-haul 7.2 and RFSimulator radios
+podman build --tag ran-build-fhi72:latest --file docker/Dockerfile.build.fhi72.rhel9 .
```
-# 5. Running modems using `docker` under Ubuntu 18.04 #
+## 4.1 Building target images
+
+For example, the eNB:
+
+```bash
+podman build --target oai-enb --tag oai-gnb:latest --file docker/Dockerfile.eNB.rhel9 .
+```
+
+To build gNB/DU with 7.2 fronthaul support:
+
+```bash
+podman build --target oai-gnb-fhi72 --tag oai-gnb-fhi72:latest --file docker/Dockerfile.gNB.fhi72.rhel9 .
+```
+
+# 5. Running modems using `docker` under Ubuntu #
The easiest is to run them from a `docker-compose` file, which is used by the
CI to test OAI. Some folders under `ci-scripts/yaml_files` have a README that
@@ -200,55 +228,47 @@ file](../ci-scripts/yaml_files/sa_b200_gnb/docker-compose.yml).
It is also possible to mount your own configuration file. The following
docker-compose file can be used to start a gNB using a B210 and your own
config, located at `/tmp/gnb.conf`:
-```
-version: '3.8'
+```yaml
services:
gnb_mono_tdd:
image: oai-gnb:latest
- privileged: true
container_name: sa-b200-gnb
+ cap_drop:
+ - ALL
+ cap_add:
+ - SYS_NICE
+ - IPC_LOCK
+ ulimits:
+ core: -1 # for core dumps
environment:
USE_B2XX: 'yes'
- USE_ADDITIONAL_OPTIONS: --sa -E --continuous-tx
+ USE_ADDITIONAL_OPTIONS: --sa --RUs.[0].sdr_addrs serial=30C51D4 --telnetsrv --telnetsrv.shrmod ci --continuous-tx --log_config.global_log_options level,nocolor,time,line_num,function
+ devices:
+ - /dev/bus/usb/:/dev/bus/usb/
volumes:
- - /dev:/dev
- - /tmp/gnb.conf:/opt/oai-gnb/etc/gnb.conf
- networks:
- public_net:
- ipv4_address: 192.168.68.194
+ - ../../conf_files/gnb.sa.band78.51prb.usrpb200.conf:/opt/oai-gnb/etc/gnb.conf
+ # for performance reasons, we use host mode: in bridge mode, we have
+ # unacceptable DL TCP performance. However, the whole point of
+ # containerization is to not be in host mode, so update this to macvlan
+ # later.
+ network_mode: "host"
+ #entrypoint: /bin/bash -c "sleep infinity"
healthcheck:
# pgrep does NOT work
test: /bin/bash -c "ps aux | grep -v grep | grep -c softmodem"
interval: 10s
timeout: 5s
retries: 5
-
-networks:
- public_net:
- name: sa-b200-gnb-net
- ipam:
- config:
- - subnet: 192.168.68.192/26
- driver_opts:
- com.docker.network.bridge.name: "sa-gnb-net"
```
You should also change the `image` to the right image name and tag of the gNB
you are using. Start like this:
-```
+```bash
docker-compose up # gNB in foreground
docker-compose up -d # gNB in background
```
Stop it like this (in both cases):
-```
+```bash
docker-compose down
```
-
-Note that in the above case, ALL devices are passed into the container (by
-mounting `/dev`), which allows the container to access all devices connected to
-the host!
-
-# 6. Running modems using `podman` under Red Hat Entreprise Linux 8.2 #
-
-TODO.
diff --git a/executables/nr-ue.c b/executables/nr-ue.c
index 8a73bdd311..447c99182b 100644
--- a/executables/nr-ue.c
+++ b/executables/nr-ue.c
@@ -149,6 +149,7 @@ void init_nr_ue_vars(PHY_VARS_NR_UE *ue,
ue->if_inst = nr_ue_if_module_init(UE_id);
ue->dci_thres = 0;
ue->target_Nid_cell = -1;
+ ue->timing_advance = ue->frame_parms.samples_per_subframe * get_nrUE_params()->ntn_ta_common;
// initialize all signal buffers
init_nr_ue_signal(ue, nb_connected_gNB);
diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c
index b85b698021..9e82c9aae8 100644
--- a/executables/nr-uesoftmodem.c
+++ b/executables/nr-uesoftmodem.c
@@ -159,6 +159,9 @@ int oaisim_flag = 0;
int emulate_rf = 0;
uint32_t N_RB_DL = 106;
+// NTN cellSpecificKoffset-r17, but in slots for DL SCS
+unsigned int NTN_UE_Koffset = 0;
+
/* see file openair2/LAYER2/MAC/main.c for why abstraction_flag is needed
* this is very hackish - find a proper solution
*/
@@ -591,6 +594,9 @@ int main(int argc, char **argv)
}
}
+ // NTN cellSpecificKoffset-r17, but in slots for DL SCS
+ NTN_UE_Koffset = nrUE_params.ntn_koffset << PHY_vars_UE_g[0][0]->frame_parms.numerology_index;
+
init_openair0();
lock_memory_to_ram();
diff --git a/executables/nr-uesoftmodem.h b/executables/nr-uesoftmodem.h
index 28de10154d..8e0650b4e4 100644
--- a/executables/nr-uesoftmodem.h
+++ b/executables/nr-uesoftmodem.h
@@ -12,6 +12,8 @@
#define CONFIG_HLP_DLSCH_PARA "number of threads for dlsch processing 0 for no parallelization\n"
#define CONFIG_HLP_OFFSET_DIV "Divisor for computing OFDM symbol offset in Rx chain (num samples in CP/). Default value is 8. To set the sample offset to 0, set this value ~ 10e6\n"
#define CONFIG_HLP_MAX_LDPC_ITERATIONS "Maximum LDPC decoder iterations\n"
+#define CONFIG_HLP_NTN_KOFFSET "NTN cellSpecificKoffset-r17 (number of slots for a given subcarrier spacing of 15 kHz)\n"
+#define CONFIG_HLP_NTN_TA_COMMON "NTN ta-Common, but given in ms\n"
/***************************************************************************************************************************************/
/* command line options definitions, CMDLINE_XXXX_DESC macros are used to initialize paramdef_t arrays which are then used as argument
@@ -63,7 +65,9 @@
{"chest-time", CONFIG_HLP_CHESTTIME, 0, .iptr=&(nrUE_params.chest_time), .defintval=0, TYPE_INT, 0}, \
{"ue-timing-correction-disable", CONFIG_HLP_DISABLETIMECORR, PARAMFLAG_BOOL, .iptr=&(nrUE_params.no_timing_correction), .defintval=0, TYPE_INT, 0}, \
{"SLC", CONFIG_HLP_SLF, 0, .u64ptr=&(sidelink_frequency[0][0]), .defuintval=2600000000,TYPE_UINT64,0}, \
- {"num-ues", NULL, 0, .iptr=&(NB_UE_INST), .defuintval=1, TYPE_INT,0}, \
+ {"num-ues", NULL, 0, .iptr=&(NB_UE_INST), .defuintval=1, TYPE_INT, 0}, \
+ {"ntn-koffset", CONFIG_HLP_NTN_KOFFSET, 0, .uptr=&(nrUE_params.ntn_koffset), .defuintval=0, TYPE_UINT, 0}, \
+ {"ntn-ta-common", CONFIG_HLP_NTN_TA_COMMON, 0, .dblptr=&(nrUE_params.ntn_ta_common), .defdblval=0.0, TYPE_DOUBLE, 0}, \
}
// clang-format on
@@ -84,6 +88,8 @@ typedef struct {
int N_RB_DL;
int ssb_start_subcarrier;
int ldpc_offload_flag;
+ unsigned int ntn_koffset;
+ double ntn_ta_common;
} nrUE_params_t;
extern uint64_t get_nrUE_optmask(void);
extern uint64_t set_nrUE_optmask(uint64_t bitmask);
diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h
index f76647d6af..8a5b101ad4 100644
--- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h
+++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h
@@ -163,7 +163,7 @@ typedef struct {
} fapi_nr_tx_config_t;
typedef struct {
- uint16_t pdu_length;
+ uint32_t pdu_length;
uint8_t* fapiTxPdu;
} fapi_nr_tx_request_body_t;
@@ -359,7 +359,6 @@ typedef struct
//beamforming
nfapi_nr_ue_ul_beamforming_t beamforming;
//OAI specific
- int8_t absolute_delta_PUSCH;
int16_t tx_power;
fapi_nr_tx_request_body_t tx_request_body;
} nfapi_nr_ue_pusch_pdu_t;
diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c
index b856e6b648..9622cd7f5e 100644
--- a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c
+++ b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c
@@ -3177,18 +3177,16 @@ uint8_t pack_nr_slot_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *
static uint8_t pack_nr_rx_data_indication_body(nfapi_nr_rx_data_pdu_t *value, uint8_t **ppWritePackedMsg, uint8_t *end)
{
- AssertFatal(value->pdu_length <= 0xFFFF,"RX_DATA.indication PDU_Length should be within 16 bit, according to SCF222.10.02");
- if(!(push32(value->handle, ppWritePackedMsg, end) &&
- push16(value->rnti, ppWritePackedMsg, end) &&
- push8(value->harq_id, ppWritePackedMsg, end) &&
- push16(value->pdu_length, ppWritePackedMsg, end) &&
- push8(value->ul_cqi, ppWritePackedMsg, end) &&
- push16(value->timing_advance, ppWritePackedMsg, end) &&
- push16(value->rssi, ppWritePackedMsg, end)
- ))
+ if (!(push32(value->handle, ppWritePackedMsg, end)
+ && push16(value->rnti, ppWritePackedMsg, end)
+ && push8(value->harq_id, ppWritePackedMsg, end)
+ && push32(value->pdu_length, ppWritePackedMsg, end)
+ && push8(value->ul_cqi, ppWritePackedMsg, end)
+ && push16(value->timing_advance, ppWritePackedMsg, end)
+ && push16(value->rssi, ppWritePackedMsg, end)))
return 0;
- if(pusharray8(value->pdu, value->pdu_length, value->pdu_length, ppWritePackedMsg, end) == 0)
+ if (pusharray8(value->pdu, value->pdu_length, value->pdu_length, ppWritePackedMsg, end) == 0)
return 0;
return 1;
@@ -6066,19 +6064,18 @@ static uint8_t unpack_nr_rx_data_indication_body(nfapi_nr_rx_data_pdu_t *value,
uint8_t *end,
nfapi_p7_codec_config_t *config)
{
-if (!(pull32(ppReadPackedMsg, &value->handle, end) && pull16(ppReadPackedMsg, &value->rnti, end)
- && pull8(ppReadPackedMsg, &value->harq_id, end) && pull16(ppReadPackedMsg, (uint16_t *)&value->pdu_length, end)
- && pull8(ppReadPackedMsg, &value->ul_cqi, end) && pull16(ppReadPackedMsg, &value->timing_advance, end)
- && pull16(ppReadPackedMsg, &value->rssi, end)))
- return 0;
+ if (!(pull32(ppReadPackedMsg, &value->handle, end) && pull16(ppReadPackedMsg, &value->rnti, end)
+ && pull8(ppReadPackedMsg, &value->harq_id, end) && pull32(ppReadPackedMsg, &value->pdu_length, end)
+ && pull8(ppReadPackedMsg, &value->ul_cqi, end) && pull16(ppReadPackedMsg, &value->timing_advance, end)
+ && pull16(ppReadPackedMsg, &value->rssi, end)))
+ return 0;
-uint32_t length = value->pdu_length;
-value->pdu = nfapi_p7_allocate(sizeof(*value->pdu) * length, config);
-if (pullarray8(ppReadPackedMsg, value->pdu, length, length, end) == 0) {
- NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s pullarray8 failure\n", __FUNCTION__);
- return 0;
-}
-return 1;
+ value->pdu = nfapi_p7_allocate(sizeof(*value->pdu) * value->pdu_length, config);
+ if (pullarray8(ppReadPackedMsg, value->pdu, value->pdu_length, value->pdu_length, end) == 0) {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s pullarray8 failure\n", __FUNCTION__);
+ return 0;
+ }
+ return 1;
}
static uint8_t unpack_nr_rx_data_indication(uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_nr_rx_data_indication_t *msg, nfapi_p7_codec_config_t* config)
diff --git a/openair1/PHY/CODING/nr_rate_matching.c b/openair1/PHY/CODING/nr_rate_matching.c
index 5a6d2885a5..1ed520cf12 100644
--- a/openair1/PHY/CODING/nr_rate_matching.c
+++ b/openair1/PHY/CODING/nr_rate_matching.c
@@ -452,7 +452,7 @@ int nr_rate_matching_ldpc(uint32_t Tbslbrm,
ind = (index_k0[BG-1][rvidx]*Ncb/N)*Z;
#ifdef RM_DEBUG
- printf("nr_rate_matching_ldpc: E %u, F %u, Foffset %u, k0 %u, Ncb %u, rvidx %d, Tbslbrm %u\n", E, F, Foffset,ind, Ncb, rvidx, Tbslbrm);
+ printf("nr_rate_matching_ldpc: E %u, F %u, Foffset %u, k0 %u, Ncb %u, rvidx %d, Tbslbrm %u\n", E, F, Foffset, ind, Ncb, rvidx, Tbslbrm);
#endif
if (Foffset > E) {
@@ -548,7 +548,7 @@ int nr_rate_matching_ldpc_rx(uint32_t Tbslbrm,
}
#ifdef RM_DEBUG
- printf("nr_rate_matching_ldpc_rx: Clear %d, E %u, k0 %u, Ncb %u, rvidx %d, Tbslbrm %u\n", clear, E, ind, Ncb, rvidx, Tbslbrm);
+ printf("nr_rate_matching_ldpc_rx: Clear %d, E %u, Foffset %u, k0 %u, Ncb %u, rvidx %d, Tbslbrm %u\n", clear, E, Foffset, ind, Ncb, rvidx, Tbslbrm);
#endif
if (clear == 1)
diff --git a/openair1/PHY/INIT/nr_parms.c b/openair1/PHY/INIT/nr_parms.c
index 4fc91037b8..6a2c300b72 100644
--- a/openair1/PHY/INIT/nr_parms.c
+++ b/openair1/PHY/INIT/nr_parms.c
@@ -262,15 +262,15 @@ uint32_t get_slot_from_timestamp(openair0_timestamp timestamp_rx, const NR_DL_FR
return slot_idx;
}
-uint32_t get_samples_slot_timestamp(int slot, const NR_DL_FRAME_PARMS *fp, uint8_t sl_ahead)
+uint32_t get_samples_slot_timestamp(int slot, const NR_DL_FRAME_PARMS *fp, unsigned int sl_ahead)
{
uint32_t samp_count = 0;
if(!sl_ahead) {
- for(uint8_t idx_slot = 0; idx_slot < slot; idx_slot++)
+ for(unsigned int idx_slot = 0; idx_slot < slot; idx_slot++)
samp_count += fp->get_samples_per_slot(idx_slot, fp);
} else {
- for(uint8_t idx_slot = slot; idx_slot < slot+sl_ahead; idx_slot++)
+ for(unsigned int idx_slot = slot; idx_slot < slot+sl_ahead; idx_slot++)
samp_count += fp->get_samples_per_slot(idx_slot, fp);
}
return samp_count;
diff --git a/openair1/PHY/NR_REFSIG/dmrs_nr.c b/openair1/PHY/NR_REFSIG/dmrs_nr.c
index 4576f322f3..377eb4d89b 100644
--- a/openair1/PHY/NR_REFSIG/dmrs_nr.c
+++ b/openair1/PHY/NR_REFSIG/dmrs_nr.c
@@ -308,10 +308,10 @@ int8_t get_next_dmrs_symbol_in_slot(uint16_t ul_dmrs_symb_pos, uint8_t counter,
/* return the total number of dmrs symbol in a slot */
-uint8_t get_dmrs_symbols_in_slot(uint16_t l_prime_mask, uint16_t nb_symb)
+uint8_t get_dmrs_symbols_in_slot(uint16_t l_prime_mask, uint16_t nb_symb, uint8_t start)
{
uint8_t tmp = 0;
- for (int i = 0; i < nb_symb; i++) {
+ for (int i = start; i < start + nb_symb; i++) {
tmp += (l_prime_mask >> i) & 0x01;
}
return tmp;
@@ -351,7 +351,7 @@ void nr_chest_time_domain_avg(NR_DL_FRAME_PARMS *frame_parms,
simde__m128i *ul_ch128_1;
int16_t *ul_ch16_0;
int total_symbols = start_symbol + num_symbols;
- int num_dmrs_symb = get_dmrs_symbols_in_slot(dmrs_bitmap, total_symbols);
+ int num_dmrs_symb = get_dmrs_symbols_in_slot(dmrs_bitmap, total_symbols, start_symbol);
int first_dmrs_symb = get_next_dmrs_symbol_in_slot(dmrs_bitmap, start_symbol, total_symbols);
AssertFatal(first_dmrs_symb > -1, "No DMRS symbol present in this slot\n");
for (int aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
diff --git a/openair1/PHY/NR_REFSIG/dmrs_nr.h b/openair1/PHY/NR_REFSIG/dmrs_nr.h
index 8b9da28abc..2c1005a19b 100644
--- a/openair1/PHY/NR_REFSIG/dmrs_nr.h
+++ b/openair1/PHY/NR_REFSIG/dmrs_nr.h
@@ -63,7 +63,7 @@ uint8_t allowed_xlsch_re_in_dmrs_symbol(uint16_t k,
void nr_gen_ref_conj_symbols(uint32_t *in, uint32_t length, int16_t *output, uint16_t offset, int mod_order);
int8_t get_next_dmrs_symbol_in_slot(uint16_t ul_dmrs_symb_pos, uint8_t counter, uint8_t end_symbol);
-uint8_t get_dmrs_symbols_in_slot(uint16_t l_prime_mask, uint16_t nb_symb);
+uint8_t get_dmrs_symbols_in_slot(uint16_t l_prime_mask, uint16_t nb_symb, uint8_t start);
int8_t get_valid_dmrs_idx_for_channel_est(uint16_t dmrs_symb_pos, uint8_t counter);
void nr_chest_time_domain_avg(NR_DL_FRAME_PARMS *frame_parms,
int32_t **ch_estimates,
diff --git a/openair1/PHY/NR_TRANSPORT/nr_scrambling.c b/openair1/PHY/NR_TRANSPORT/nr_scrambling.c
index b54a5c2c0c..353db70454 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_scrambling.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_scrambling.c
@@ -32,16 +32,14 @@ void nr_codeword_scrambling(uint8_t *in,
uint32_t* out)
{
uint32_t x1;
- uint32_t x2 = (n_RNTI<<15) + (q<<14) + Nid;
- uint32_t s = 0;
-
- s=lte_gold_generic(&x1, &x2, 1);
- for (int i=0; i<((size>>5)+((size&0x1f) > 0 ? 1 : 0)); i++) {
+ uint32_t x2 = (n_RNTI << 15) + (q << 14) + Nid;
+ uint32_t s = lte_gold_generic(&x1, &x2, 1);
+ for (int i = 0; i < ((size >> 5) + ((size & 0x1f) > 0 ? 1 : 0)); i++) {
simde__m256i c = ((simde__m256i*)in)[i];
- uint32_t in32 = simde_mm256_movemask_epi8(simde_mm256_slli_epi16(c,7));
- out[i]=(in32^s);
+ uint32_t in32 = simde_mm256_movemask_epi8(simde_mm256_slli_epi16(c, 7));
+ out[i] = (in32 ^ s);
DEBUG_SCRAMBLING(LOG_D(PHY, "in[%d] %x => %x\n", i, in32, out[i]));
- s=lte_gold_generic(&x1, &x2, 0);
+ s = lte_gold_generic(&x1, &x2, 0);
}
}
diff --git a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c
index 6d9aaf7f9a..54d9022e87 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c
@@ -560,7 +560,7 @@ static int pss_search_time_nr(const c16_t **rxdata,
}
for (int pss_index = pss_index_start; pss_index < pss_index_end; pss_index++) {
- for (n = 0; n < length; n += 8) { //
+ for (n = 0; n < length; n += 4) { //
int64_t pss_corr_ue=0;
/* calculate dot product of primary_synchro_time_nr and rxdata[ar][n]
diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h
index 3d0f2efa88..9c2dff22b8 100644
--- a/openair1/PHY/defs_nr_common.h
+++ b/openair1/PHY/defs_nr_common.h
@@ -135,7 +135,7 @@ typedef struct NR_DL_FRAME_PARMS NR_DL_FRAME_PARMS;
typedef uint32_t (*get_samples_per_slot_t)(int slot, const NR_DL_FRAME_PARMS *fp);
typedef uint32_t (*get_slot_from_timestamp_t)(openair0_timestamp timestamp_rx, const NR_DL_FRAME_PARMS *fp);
-typedef uint32_t (*get_samples_slot_timestamp_t)(int slot, const NR_DL_FRAME_PARMS *fp, uint8_t sl_ahead);
+typedef uint32_t (*get_samples_slot_timestamp_t)(int slot, const NR_DL_FRAME_PARMS *fp, unsigned int sl_ahead);
struct NR_DL_FRAME_PARMS {
/// frequency range
diff --git a/openair1/PHY/impl_defs_top.h b/openair1/PHY/impl_defs_top.h
index c06cd13ff7..618a7e6c58 100644
--- a/openair1/PHY/impl_defs_top.h
+++ b/openair1/PHY/impl_defs_top.h
@@ -268,13 +268,24 @@
#define TDD_CONFIG_NB_FRAMES (2)
#define NR_MAX_SLOTS_PER_FRAME (160) /* number of slots per frame */
-/* FFS_NR_TODO it defines ue capability which is the number of slots */
-/* - between reception of pdsch and tarnsmission of its acknowlegment */
-/* - between reception of un uplink grant and its related transmission */
-// should be 2 as per NR standard, but current UE is not able to perform this value
+/* FFS_NR_TODO it defines ue capability which is the number of slots */
+/* - between reception of pdsch and transmission of its acknowlegment (k1) */
+/* - between reception of un uplink grant and its related transmission (k2) */
#define NR_UE_CAPABILITY_SLOT_RX_TO_TX (3)
-#define DURATION_RX_TO_TX (NR_UE_CAPABILITY_SLOT_RX_TO_TX)
+/* When the OAI UE receives RX slot N, it starts sending TX slot N+DURATION_RX_TO_TX.
+ * Therefore DURATION_RX_TO_TX must not be larger than the minimum k1 and k2 values (NR_UE_CAPABILITY_SLOT_RX_TO_TX).
+ * In case of NTN, the propagation delay is so large, that the TX slot needs to be transmitted far in advance.
+ * Therefore, the NTN_UE_Koffset is added to DURATION_RX_TO_TX.
+ *
+ * Note: currently, the UE requires this to be a constant.
+ * But in case of NTN, Koffset is only known after receiving SIB19.
+ * Therefore, support should be added to allow changing DURATION_RX_TO_TX on reception of SIB19 (via FAPI-like interface).
+ * E.g. no transmission before successful reception of SIB19, and re-sync with disabled transmission if Koffset changes.
+ * When this has been implemented, the global variable NTN_UE_Koffset should be removed, too.
+ */
+extern unsigned int NTN_UE_Koffset;
+#define DURATION_RX_TO_TX (NR_UE_CAPABILITY_SLOT_RX_TO_TX + NTN_UE_Koffset)
#define NR_MAX_ULSCH_HARQ_PROCESSES (NR_MAX_HARQ_PROCESSES) /* cf 38.214 6.1 UE procedure for receiving the physical uplink shared channel */
#define NR_MAX_DLSCH_HARQ_PROCESSES (NR_MAX_HARQ_PROCESSES) /* cf 38.214 5.1 UE procedure for receiving the physical downlink shared channel */
diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
index d01f1e3e94..b408b9fed3 100644
--- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
+++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
@@ -373,7 +373,6 @@ static void configure_ta_command(PHY_VARS_NR_UE *ue, fapi_nr_ta_command_pdu *ta_
if (ta_command_pdu->is_rar) {
ue->ta_slot = ta_command_pdu->ta_slot;
ue->ta_frame = ta_command_pdu->ta_frame;
- ue->timing_advance = 0;
ue->ta_command = ta_command_pdu->ta_command + 31; // To use TA adjustment algo in ue_ta_procedures()
} else {
ue->ta_slot = (ta_command_pdu->ta_slot + ul_tx_timing_adjustment) % slots_per_frame;
diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c
index 728163e049..d6be222a9b 100644
--- a/openair1/SIMULATION/NR_PHY/dlsim.c
+++ b/openair1/SIMULATION/NR_PHY/dlsim.c
@@ -95,6 +95,9 @@ nfapi_ue_release_request_body_t release_rntis;
instance_t DUuniqInstance=0;
instance_t CUuniqInstance=0;
+// NTN cellSpecificKoffset-r17, but in slots for DL SCS
+unsigned int NTN_UE_Koffset = 0;
+
void nr_derive_key_ng_ran_star(uint16_t pci, uint64_t nr_arfcn_dl, const uint8_t key[32], uint8_t *key_ng_ran_star)
{
}
diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c
index 822153fd14..b191301513 100644
--- a/openair1/SIMULATION/NR_PHY/ulsim.c
+++ b/openair1/SIMULATION/NR_PHY/ulsim.c
@@ -93,6 +93,9 @@ nfapi_ue_release_request_body_t release_rntis;
instance_t DUuniqInstance=0;
instance_t CUuniqInstance=0;
+// NTN cellSpecificKoffset-r17, but in slots for DL SCS
+unsigned int NTN_UE_Koffset = 0;
+
void nr_derive_key_ng_ran_star(uint16_t pci, uint64_t nr_arfcn_dl, const uint8_t key[32], uint8_t *key_ng_ran_star)
{
}
@@ -775,8 +778,7 @@ int main(int argc, char *argv[])
uint8_t length_dmrs = pusch_len1;
uint16_t l_prime_mask = get_l_prime(nb_symb_sch, mapping_type, add_pos, length_dmrs, start_symbol, NR_MIB__dmrs_TypeA_Position_pos2);
- uint16_t number_dmrs_symbols = get_dmrs_symbols_in_slot(l_prime_mask, nb_symb_sch);
- printf("num dmrs sym %d\n",number_dmrs_symbols);
+ uint16_t number_dmrs_symbols = get_dmrs_symbols_in_slot(l_prime_mask, nb_symb_sch, start_symbol);
uint8_t nb_re_dmrs = (dmrs_config_type == pusch_dmrs_type1) ? 6 : 4;
uint32_t tbslbrm = 0;
@@ -804,8 +806,18 @@ int main(int argc, char *argv[])
nb_re_dmrs = nb_re_dmrs * num_dmrs_cdm_grps_no_data;
unsigned int TBS = nr_compute_tbs(mod_order, code_rate, nb_rb, nb_symb_sch, nb_re_dmrs * number_dmrs_symbols, 0, 0, precod_nbr_layers);
- printf("[ULSIM]: length_dmrs: %u, l_prime_mask: %u number_dmrs_symbols: %u, mapping_type: %u add_pos: %d \n", length_dmrs, l_prime_mask, number_dmrs_symbols, mapping_type, add_pos);
- printf("[ULSIM]: CDM groups: %u, dmrs_config_type: %d, num_rbs: %u, nb_symb_sch: %u\n", num_dmrs_cdm_grps_no_data, dmrs_config_type, nb_rb, nb_symb_sch);
+ printf("[ULSIM]: length_dmrs: %u, l_prime_mask: %u number_dmrs_symbols: %u, mapping_type: %u add_pos: %d \n",
+ length_dmrs,
+ l_prime_mask,
+ number_dmrs_symbols,
+ mapping_type,
+ add_pos);
+ printf("[ULSIM]: CDM groups: %u, dmrs_config_type: %d, num_rbs: %u, nb_symb_sch: %u, start_symbol %u\n",
+ num_dmrs_cdm_grps_no_data,
+ dmrs_config_type,
+ nb_rb,
+ nb_symb_sch,
+ start_symbol);
printf("[ULSIM]: MCS: %d, mod order: %u, code_rate: %u\n", Imcs, mod_order, code_rate);
uint8_t ulsch_input_buffer[TBS/8];
@@ -1119,7 +1131,6 @@ int main(int argc, char *argv[])
pusch_config_pdu->num_dmrs_cdm_grps_no_data = num_dmrs_cdm_grps_no_data;
pusch_config_pdu->nrOfLayers = precod_nbr_layers;
pusch_config_pdu->dmrs_ports = ((1 << precod_nbr_layers) - 1);
- pusch_config_pdu->absolute_delta_PUSCH = 0;
pusch_config_pdu->target_code_rate = code_rate;
pusch_config_pdu->tbslbrm = tbslbrm;
pusch_config_pdu->ldpcBaseGraph = get_BG(TBS, code_rate);
diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_compute_tbs_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_compute_tbs_common.c
index aa1042491b..91c8b9b9c4 100644
--- a/openair2/LAYER2/NR_MAC_COMMON/nr_compute_tbs_common.c
+++ b/openair2/LAYER2/NR_MAC_COMMON/nr_compute_tbs_common.c
@@ -50,8 +50,14 @@ uint32_t nr_compute_tbs(uint16_t Qm,
uint8_t tb_scaling,
uint8_t Nl)
{
-
- LOG_D(NR_MAC, "In %s: nb_symb_sch %d, nb_dmrs_prb %d, nb_rb %d, nb_rb_oh %d, tb_scaling %d Nl %d\n", __FUNCTION__, nb_symb_sch, nb_dmrs_prb, nb_rb, nb_rb_oh, tb_scaling, Nl);
+ LOG_D(NR_MAC,
+ "nb_symb_sch %d, nb_dmrs_prb %d, nb_rb %d, nb_rb_oh %d, tb_scaling %d Nl %d\n",
+ nb_symb_sch,
+ nb_dmrs_prb,
+ nb_rb,
+ nb_rb_oh,
+ tb_scaling,
+ Nl);
const int nb_subcarrier_per_rb = 12;
const uint32_t nbp_re = nb_subcarrier_per_rb * nb_symb_sch - nb_dmrs_prb - nb_rb_oh;
@@ -91,10 +97,9 @@ uint32_t nr_compute_tbs(uint16_t Qm,
}
}
- LOG_D(NR_MAC, "In %s: Ninfo %u nbp_re %d nb_re %d Qm %d, R %d, tbs %d bits\n", __FUNCTION__, Ninfo, nbp_re, nb_re, Qm, R, nr_tbs);
+ LOG_D(NR_MAC, "Ninfo %u nbp_re %d nb_re %d Qm %d, R %d, tbs %d bits\n", Ninfo, nbp_re, nb_re, Qm, R, nr_tbs);
return nr_tbs;
-
}
//tbslbrm calculation according to 5.4.2.1 of 38.212
diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h
index 6973f06103..e43b038266 100644
--- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h
+++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h
@@ -107,12 +107,13 @@ typedef struct {
uint8_t R: 2; // octet 1 [7:6]
} __attribute__ ((__packed__)) NR_MAC_SUBHEADER_FIXED;
-static inline int get_mac_len(uint8_t* pdu, int pdu_len, uint16_t *mac_ce_len, uint16_t *mac_subheader_len) {
- if ( pdu_len < (int)sizeof(NR_MAC_SUBHEADER_SHORT))
+static inline int get_mac_len(uint8_t *pdu, uint32_t pdu_len, uint16_t *mac_ce_len, uint16_t *mac_subheader_len)
+{
+ if (pdu_len < sizeof(NR_MAC_SUBHEADER_SHORT))
return false;
- NR_MAC_SUBHEADER_SHORT *s = (NR_MAC_SUBHEADER_SHORT*) pdu;
- NR_MAC_SUBHEADER_LONG *l = (NR_MAC_SUBHEADER_LONG*) pdu;
- if (s->F && pdu_len < (int)sizeof(NR_MAC_SUBHEADER_LONG))
+ NR_MAC_SUBHEADER_SHORT *s = (NR_MAC_SUBHEADER_SHORT *)pdu;
+ NR_MAC_SUBHEADER_LONG *l = (NR_MAC_SUBHEADER_LONG *)pdu;
+ if (s->F && pdu_len < sizeof(NR_MAC_SUBHEADER_LONG))
return false;
if (s->F) {
*mac_subheader_len = sizeof(*l);
@@ -123,7 +124,7 @@ static inline int get_mac_len(uint8_t* pdu, int pdu_len, uint16_t *mac_ce_len, u
}
return true;
}
-
+
// BSR MAC CEs
// TS 38.321 ch. 6.1.3.1
// Short BSR for a specific logical channel group ID
@@ -597,6 +598,7 @@ typedef struct {
int n_ul_bwp;
int dl_bw_tbslbrm;
int ul_bw_tbslbrm;
+ NR_NTN_Config_r17_t *ntn_Config_r17;
} NR_UE_ServingCell_Info_t;
typedef enum {
diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
index b91da1152b..151cee026d 100644
--- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
+++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
@@ -2473,25 +2473,26 @@ uint8_t getAntPortBitWidth(NR_SetupRelease_DMRS_DownlinkConfig_t *typeA, NR_Setu
*
*********************************************************************/
-uint8_t get_l0_ul(uint8_t mapping_type, uint8_t dmrs_typeA_position) {
-
+uint8_t get_l0_ul(uint8_t mapping_type, uint8_t dmrs_typeA_position)
+{
return ((mapping_type==typeA)?dmrs_typeA_position:0);
-
}
-int32_t get_l_prime(uint8_t duration_in_symbols, uint8_t mapping_type, pusch_dmrs_AdditionalPosition_t additional_pos, pusch_maxLength_t pusch_maxLength, uint8_t start_symbol, uint8_t dmrs_typeA_position) {
-
- uint8_t row, colomn;
- int32_t l_prime;
-
- LOG_D(NR_MAC, "In %s: PUSCH NrofSymbols:%d, startSymbol:%d, mappingtype:%d, dmrs_TypeA_Position:%d additional_pos:%d, pusch_maxLength:%d\n",
- __FUNCTION__,
- duration_in_symbols,
- start_symbol,
- mapping_type,
- dmrs_typeA_position,
- additional_pos,
- pusch_maxLength);
+int32_t get_l_prime(uint8_t duration_in_symbols,
+ uint8_t mapping_type,
+ pusch_dmrs_AdditionalPosition_t additional_pos,
+ pusch_maxLength_t pusch_maxLength,
+ uint8_t start_symbol,
+ uint8_t dmrs_typeA_position)
+{
+ LOG_D(NR_MAC,
+ "PUSCH NrofSymbols:%d, startSymbol:%d, mappingtype:%d, dmrs_TypeA_Position:%d additional_pos:%d, pusch_maxLength:%d\n",
+ duration_in_symbols,
+ start_symbol,
+ mapping_type,
+ dmrs_typeA_position,
+ additional_pos,
+ pusch_maxLength);
// Section 6.4.1.1.3 in Spec 38.211
// For PDSCH Mapping TypeA, ld is duration between first OFDM of the slot and last OFDM symbol of the scheduled PUSCH resources
@@ -2499,16 +2500,18 @@ int32_t get_l_prime(uint8_t duration_in_symbols, uint8_t mapping_type, pusch_dmr
uint8_t ld = (mapping_type == typeA) ? (duration_in_symbols + start_symbol) : duration_in_symbols;
uint8_t l0 = (dmrs_typeA_position == NR_MIB__dmrs_TypeA_Position_pos2) ? 2 : 3 ;
- colomn = additional_pos;
+ uint8_t colomn = additional_pos;
if (mapping_type == typeB)
colomn += 4;
+ uint8_t row;
if (ld < 4)
row = 0;
else
row = ld - 3;
+ uint32_t l_prime;
if (pusch_maxLength == pusch_len1) {
l_prime = table_6_4_1_1_3_3_pusch_dmrs_positions_l[row][colomn];
l0 = 1 << l0;
@@ -2525,7 +2528,6 @@ int32_t get_l_prime(uint8_t duration_in_symbols, uint8_t mapping_type, pusch_dmr
LOG_D(MAC, " PUSCH DMRS MASK in HEX:%x\n", l_prime);
return l_prime;
-
}
/*******************************************************************
diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c
index d8b1ac158d..507b45ebd3 100644
--- a/openair2/LAYER2/NR_MAC_UE/config_ue.c
+++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c
@@ -409,6 +409,13 @@ static void config_common_ue(NR_UE_MAC_INST_t *mac,
// prach_fd_occasion->num_unused_root_sequences = ???
}
}
+
+ // NTN Config
+ if (scc->ext2) {
+ UPDATE_IE(mac->sc_info.ntn_Config_r17, scc->ext2->ntn_Config_r17, NR_NTN_Config_r17_t);
+ } else {
+ asn1cFreeStruc(asn_DEF_NR_NTN_Config_r17, mac->sc_info.ntn_Config_r17);
+ }
}
void release_common_ss_cset(NR_BWP_PDCCH_t *pdcch)
@@ -872,14 +879,21 @@ void nr_rrc_mac_config_req_mib(module_id_t module_id,
nr_ue_decode_mib(mac, cc_idP);
}
-static void setup_puschpowercontrol(NR_PUSCH_PowerControl_t *source, NR_PUSCH_PowerControl_t *target)
+static void setup_puschpowercontrol(NR_UE_MAC_INST_t *mac, NR_PUSCH_PowerControl_t *source, NR_PUSCH_PowerControl_t *target)
{
UPDATE_IE(target->tpc_Accumulation, source->tpc_Accumulation, long);
UPDATE_IE(target->msg3_Alpha, source->msg3_Alpha, NR_Alpha_t);
if (source->p0_NominalWithoutGrant)
UPDATE_IE(target->p0_NominalWithoutGrant, source->p0_NominalWithoutGrant, long);
- if (source->p0_AlphaSets)
+ if (source->p0_AlphaSets) {
UPDATE_IE(target->p0_AlphaSets, source->p0_AlphaSets, struct NR_PUSCH_PowerControl__p0_AlphaSets);
+ if (target->p0_AlphaSets->list.array[0]->alpha) {
+ mac->f_b_f_c = 0;
+ }
+ if (target->p0_AlphaSets->list.array[0]->p0) {
+ mac->f_b_f_c = 0;
+ }
+ }
UPDATE_IE(target->twoPUSCH_PC_AdjustmentStates, source->twoPUSCH_PC_AdjustmentStates, long);
UPDATE_IE(target->deltaMCS, source->deltaMCS, long);
if (source->pathlossReferenceRSToReleaseList) {
@@ -901,6 +915,7 @@ static void setup_puschpowercontrol(NR_PUSCH_PowerControl_t *source, NR_PUSCH_Po
sri_PUSCH_PowerControlId);
}
if (source->sri_PUSCH_MappingToAddModList) {
+ LOG_E(NR_MAC, "NR_SRI_PUSCH_PowerControl not implemented, power control will not work as intended\n");
if (!target->sri_PUSCH_MappingToAddModList)
target->sri_PUSCH_MappingToAddModList = calloc(1, sizeof(*target->sri_PUSCH_MappingToAddModList));
ADDMOD_IE_FROMLIST(source->sri_PUSCH_MappingToAddModList,
@@ -910,7 +925,7 @@ static void setup_puschpowercontrol(NR_PUSCH_PowerControl_t *source, NR_PUSCH_Po
}
}
-static void setup_puschconfig(NR_PUSCH_Config_t *source, NR_PUSCH_Config_t *target)
+static void setup_puschconfig(NR_UE_MAC_INST_t *mac, NR_PUSCH_Config_t *source, NR_PUSCH_Config_t *target)
{
UPDATE_IE(target->dataScramblingIdentityPUSCH, source->dataScramblingIdentityPUSCH, long);
UPDATE_IE(target->txConfig, source->txConfig, long);
@@ -927,7 +942,7 @@ static void setup_puschconfig(NR_PUSCH_Config_t *source, NR_PUSCH_Config_t *targ
if (source->pusch_PowerControl) {
if (!target->pusch_PowerControl)
target->pusch_PowerControl = calloc(1, sizeof(*target->pusch_PowerControl));
- setup_puschpowercontrol(source->pusch_PowerControl, target->pusch_PowerControl);
+ setup_puschpowercontrol(mac, source->pusch_PowerControl, target->pusch_PowerControl);
}
UPDATE_IE(target->frequencyHopping, source->frequencyHopping, long);
if (source->frequencyHoppingOffsetLists)
@@ -1415,7 +1430,7 @@ static void configure_dedicated_BWP_ul(NR_UE_MAC_INST_t *mac, int bwp_id, NR_BWP
if (ul_dedicated->pusch_Config->present == NR_SetupRelease_PUSCH_Config_PR_setup) {
if (!bwp->pusch_Config)
bwp->pusch_Config = calloc(1, sizeof(*bwp->pusch_Config));
- setup_puschconfig(ul_dedicated->pusch_Config->choice.setup, bwp->pusch_Config);
+ setup_puschconfig(mac, ul_dedicated->pusch_Config->choice.setup, bwp->pusch_Config);
}
}
if(ul_dedicated->srs_Config) {
@@ -1585,6 +1600,17 @@ void nr_rrc_mac_config_req_sib1(module_id_t module_id,
mac->phy_config_request_sent = true;
}
+void nr_rrc_mac_config_req_sib19_r17(module_id_t module_id,
+ NR_SIB19_r17_t *sib19_r17)
+{
+ NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
+
+ // ntn-Config-r17
+ UPDATE_IE(mac->sc_info.ntn_Config_r17, sib19_r17->ntn_Config_r17, NR_NTN_Config_r17_t);
+
+ // TODO handle other SIB19 elements
+}
+
static void handle_reconfiguration_with_sync(NR_UE_MAC_INST_t *mac,
int cc_idP,
const NR_ReconfigurationWithSync_t *reconfigurationWithSync)
@@ -1802,6 +1828,17 @@ static void configure_maccellgroup(NR_UE_MAC_INST_t *mac, const NR_MAC_CellGroup
int target_ms = 0;
if (sr->sr_ProhibitTimer)
target_ms = 1 << *sr->sr_ProhibitTimer;
+ if (mcg->ext4 && mcg->ext4->schedulingRequestConfig_v1700) {
+ const NR_SchedulingRequestConfig_v1700_t *src_v1700 = mcg->ext4->schedulingRequestConfig_v1700;
+ if (src_v1700->schedulingRequestToAddModListExt_v1700) {
+ if (i < src_v1700->schedulingRequestToAddModListExt_v1700->list.count) {
+ const NR_SchedulingRequestToAddModExt_v1700_t *sr_v1700 = src_v1700->schedulingRequestToAddModListExt_v1700->list.array[i];
+ if (sr_v1700->sr_ProhibitTimer_v1700) {
+ target_ms = 192 + 64 * *sr_v1700->sr_ProhibitTimer_v1700;
+ }
+ }
+ }
+ }
// length of slot is (1/2^scs)ms
nr_timer_setup(&sr_info->prohibitTimer, target_ms << scs, 1); // 1 slot update rate
}
diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h
index 5c6b0bd93a..781192fbc2 100644
--- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h
+++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h
@@ -593,6 +593,8 @@ typedef struct NR_UE_MAC_INST_s {
// PUCCH closed loop power control state
int G_b_f_c;
bool pucch_power_control_initialized;
+ int f_b_f_c;
+ bool pusch_power_control_initialized;
} NR_UE_MAC_INST_t;
/*@}*/
diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h
index 6b849415f8..d4a6bcfb7d 100644
--- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h
+++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h
@@ -90,6 +90,9 @@ void nr_rrc_mac_config_req_sib1(module_id_t module_id,
NR_SI_SchedulingInfo_t *si_SchedulingInfo,
NR_ServingCellConfigCommonSIB_t *scc);
+void nr_rrc_mac_config_req_sib19_r17(module_id_t module_id,
+ NR_SIB19_r17_t *sib19_r17);
+
void nr_rrc_mac_config_req_reset(module_id_t module_id, NR_UE_MAC_reset_cause_t cause);
/**\brief initialization NR UE MAC instance(s)*/
@@ -190,13 +193,13 @@ uint8_t nr_ue_get_sdu(NR_UE_MAC_INST_t *mac,
sub_frame_t subframe,
uint8_t gNB_index,
uint8_t *ulsch_buffer,
- uint16_t buflen);
+ uint32_t buflen);
void set_harq_status(NR_UE_MAC_INST_t *mac,
uint8_t pucch_id,
uint8_t harq_id,
int8_t delta_pucch,
- uint8_t data_toul_fb,
+ uint16_t data_toul_fb,
uint8_t dai,
int n_CCE,
int N_CCE,
diff --git a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c
index 4d8b79a2ab..f67e8d25c3 100644
--- a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c
+++ b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c
@@ -35,7 +35,7 @@
#include "radio/COMMON/common_lib.h"
//#undef MALLOC
#include "assertions.h"
-#include "executables/softmodem-common.h"
+#include "executables/nr-uesoftmodem.h"
#include "nr_rlc/nr_rlc_oai_api.h"
#include "RRC/NR_UE/rrc_proto.h"
#include
@@ -84,6 +84,28 @@ void nr_ue_init_mac(NR_UE_MAC_INST_t *mac)
memset(&mac->scheduling_info.sr_info[i], 0, sizeof(mac->scheduling_info.sr_info[i]));
mac->pucch_power_control_initialized = false;
+ mac->pusch_power_control_initialized = false;
+
+ // Fake SIB19 reception for NTN
+ // TODO: remove this and implement the actual SIB19 reception instead!
+ if (get_nrUE_params()->ntn_koffset || get_nrUE_params()->ntn_ta_common) {
+ NR_SIB19_r17_t *sib19_r17 = calloc(1, sizeof(*sib19_r17));
+ sib19_r17->ntn_Config_r17 = calloc(1, sizeof(*sib19_r17->ntn_Config_r17));
+
+ // NTN cellSpecificKoffset-r17
+ if (get_nrUE_params()->ntn_koffset) {
+ asn1cCallocOne(sib19_r17->ntn_Config_r17->cellSpecificKoffset_r17, get_nrUE_params()->ntn_koffset);
+ }
+
+ // NTN ta-Common-r17
+ if (get_nrUE_params()->ntn_ta_common) {
+ sib19_r17->ntn_Config_r17->ta_Info_r17 = calloc(1, sizeof(*sib19_r17->ntn_Config_r17->ta_Info_r17));
+ sib19_r17->ntn_Config_r17->ta_Info_r17->ta_Common_r17 = get_nrUE_params()->ntn_ta_common / 4.072e-6; // ta-Common-r17 is in units of 4.072e-3 µs, ntn_ta_common is in ms
+ }
+
+ nr_rrc_mac_config_req_sib19_r17(mac->ue_id, sib19_r17);
+ asn1cFreeStruc(asn_DEF_NR_SIB19_r17, sib19_r17);
+ }
}
void nr_ue_mac_default_configs(NR_UE_MAC_INST_t *mac)
@@ -246,6 +268,7 @@ void release_mac_configuration(NR_UE_MAC_INST_t *mac,
asn1cFreeStruc(asn_DEF_NR_PUSCH_CodeBlockGroupTransmission, sc->pusch_CGB_Transmission);
asn1cFreeStruc(asn_DEF_NR_CSI_MeasConfig, sc->csi_MeasConfig);
asn1cFreeStruc(asn_DEF_NR_CSI_AperiodicTriggerStateList, sc->aperiodicTriggerStateList);
+ asn1cFreeStruc(asn_DEF_NR_NTN_Config_r17, sc->ntn_Config_r17);
free(sc->xOverhead_PDSCH);
free(sc->nrofHARQ_ProcessesForPDSCH);
free(sc->rateMatching_PUSCH);
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c
index ebf3ee2703..dfe1c86e72 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c
@@ -41,6 +41,13 @@
#include
#include "openair2/LAYER2/RLC/rlc.h"
+static double get_ta_Common_ms(NR_NTN_Config_r17_t *ntn_Config_r17)
+{
+ if (ntn_Config_r17 && ntn_Config_r17->ta_Info_r17)
+ return ntn_Config_r17->ta_Info_r17->ta_Common_r17 * 4.072e-6; // ta_Common_r17 is in units of 4.072e-3 µs
+ return 0.0;
+}
+
int16_t get_prach_tx_power(NR_UE_MAC_INST_t *mac)
{
RA_config_t *ra = &mac->ra;
@@ -74,7 +81,8 @@ void init_RA(NR_UE_MAC_INST_t *mac,
fapi_nr_config_request_t *cfg = &mac->phy_config.config_req;
prach_resources->RA_PREAMBLE_BACKOFF = 0;
- AssertFatal(nr_rach_ConfigCommon, "Cannot handle scenario without nr_rach_ConfigCommon\n");
+ AssertFatal(nr_rach_ConfigCommon && nr_rach_ConfigCommon->msg1_SubcarrierSpacing,
+ "Cannot handle yet the scenario without msg1_SubcarrierSpacing (L839)\n");
NR_SubcarrierSpacing_t prach_scs = *nr_rach_ConfigCommon->msg1_SubcarrierSpacing;
int n_prbs = get_N_RA_RB(prach_scs, mac->current_UL_BWP->scs);
int start_prb = rach_ConfigGeneric->msg1_FrequencyStart + mac->current_UL_BWP->BWPStart;
@@ -580,13 +588,17 @@ void nr_Msg3_transmitted(NR_UE_MAC_INST_t *mac, uint8_t CC_id, frame_t frameP, s
{
RA_config_t *ra = &mac->ra;
NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = mac->current_UL_BWP->rach_ConfigCommon;
- long mu = mac->current_UL_BWP->scs;
- int subframes_per_slot = nr_slots_per_frame[mu] / 10;
+ const double ta_Common_ms = get_ta_Common_ms(mac->sc_info.ntn_Config_r17);
+ const int mu = mac->current_UL_BWP->scs;
+ const int slots_per_ms = nr_slots_per_frame[mu] / 10;
// start contention resolution timer
- int RA_contention_resolution_timer_subframes = (nr_rach_ConfigCommon->ra_ContentionResolutionTimer + 1) << 3;
- // timer step 1 slot and timer target given by ra_ContentionResolutionTimer
- nr_timer_setup(&ra->contention_resolution_timer, RA_contention_resolution_timer_subframes * subframes_per_slot, 1);
+ const int RA_contention_resolution_timer_ms = (nr_rach_ConfigCommon->ra_ContentionResolutionTimer + 1) << 3;
+ const int RA_contention_resolution_timer_slots = RA_contention_resolution_timer_ms * slots_per_ms;
+ const int ta_Common_slots = (int)ceil(ta_Common_ms * slots_per_ms);
+
+ // timer step 1 slot and timer target given by ra_ContentionResolutionTimer + ta-Common-r17
+ nr_timer_setup(&ra->contention_resolution_timer, RA_contention_resolution_timer_slots + ta_Common_slots, 1);
nr_timer_start(&ra->contention_resolution_timer);
ra->ra_state = nrRA_WAIT_CONTENTION_RESOLUTION;
@@ -788,11 +800,16 @@ void nr_get_RA_window(NR_UE_MAC_INST_t *mac)
NR_RACH_ConfigCommon_t *setup = mac->current_UL_BWP->rach_ConfigCommon;
AssertFatal(&setup->rach_ConfigGeneric != NULL, "In %s: FATAL! rach_ConfigGeneric is NULL...\n", __FUNCTION__);
NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric;
+ const double ta_Common_ms = get_ta_Common_ms(mac->sc_info.ntn_Config_r17);
+ const int mu = mac->current_DL_BWP->scs;
+ const int slots_per_ms = nr_slots_per_frame[mu] / 10;
- int ra_ResponseWindow = rach_ConfigGeneric->ra_ResponseWindow;
- int mu = mac->current_DL_BWP->scs;
+ const int ra_Offset_slots = ra->RA_offset * nr_slots_per_frame[mu];
+ const int ta_Common_slots = (int)ceil(ta_Common_ms * slots_per_ms);
- ra->RA_window_cnt = ra->RA_offset * nr_slots_per_frame[mu]; // taking into account the 2 frames gap introduced by OAI gNB
+ ra->RA_window_cnt = ra_Offset_slots + ta_Common_slots; // taking into account the 2 frames gap introduced by OAI gNB
+
+ int ra_ResponseWindow = rach_ConfigGeneric->ra_ResponseWindow;
switch (ra_ResponseWindow) {
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl1:
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c
index 02aea8dd4d..01bf59b56f 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c
@@ -522,12 +522,12 @@ int get_pusch_tx_power_ue(NR_UE_MAC_INST_t *mac,
mac->nr_band,
mac->frame_type,
mac->frequency_range,
- 2,
+ qm,
false,
mac->current_UL_BWP->scs,
mac->current_UL_BWP->BWPSize,
transform_precoding,
- 1,
+ num_rb,
start_prb);
int P_O_PUSCH = P_O_NOMINAL_PUSCH + P_O_UE_PUSCH;
@@ -553,12 +553,28 @@ int get_pusch_tx_power_ue(NR_UE_MAC_INST_t *mac,
// TODO: compute pathoss using correct reference
int16_t pathloss = compute_nr_SSB_PL(mac, mac->ssb_measurements.ssb_rsrp_dBm);
+ int P_CMIN = nr_get_Pcmin(mac->current_UL_BWP->scs, mac->nr_band, mac->current_UL_BWP->BWPSize);
+
+ float pusch_power_without_f_b_f_c = P_O_PUSCH + M_pusch_component + alpha * pathloss + DELTA_TF;
int f_b_f_c = 0;
if (has_pusch_power_control_config && pusch_Config->pusch_PowerControl->tpc_Accumulation) {
f_b_f_c = delta_pusch;
} else {
- // TODO: PUSCH power control state
+ if (!mac->pusch_power_control_initialized && is_rar_tx_retx) {
+ NR_PRACH_RESOURCES_t* prach_resources = &mac->ra.prach_resources;
+ float DELTA_P_rampup_requested = (prach_resources->RA_PREAMBLE_POWER_RAMPING_COUNTER - 1) * prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP;
+ float DELTA_P_rampup = P_CMAX - (P_O_PUSCH + M_pusch_component + alpha * pathloss + DELTA_TF + delta_pusch);
+ DELTA_P_rampup = min(DELTA_P_rampup_requested, max(0, DELTA_P_rampup));
+ mac->f_b_f_c = DELTA_P_rampup + delta_pusch;
+ mac->pusch_power_control_initialized = true;
+ } else {
+ if (!((pusch_power_without_f_b_f_c + mac->f_b_f_c >= P_CMAX && delta_pusch > 0) ||
+ (pusch_power_without_f_b_f_c + mac->f_b_f_c <= P_CMIN && delta_pusch < 0))) {
+ mac->f_b_f_c += delta_pusch;
+ }
+ }
+ f_b_f_c = mac->f_b_f_c;
}
LOG_D(NR_MAC,
"PUSCH tx power components P_O_PUSCH=%d, M_pusch_component=%d, alpha*pathloss=%f, delta_TF=%f, f_b_f_c=%d\n",
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
index 2954cf246b..af148e6bd5 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
@@ -148,6 +148,13 @@ static nr_dci_format_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
const uint8_t *dci_pdu,
const int slot);
+static int get_NTN_UE_Koffset(NR_NTN_Config_r17_t *ntn_Config_r17, int scs)
+{
+ if (ntn_Config_r17 && ntn_Config_r17->cellSpecificKoffset_r17)
+ return *ntn_Config_r17->cellSpecificKoffset_r17 << scs;
+ return 0;
+}
+
int get_rnti_type(const NR_UE_MAC_INST_t *mac, const uint16_t rnti)
{
const RA_config_t *ra = &mac->ra;
@@ -492,7 +499,8 @@ static int nr_ue_process_dci_ul_00(NR_UE_MAC_INST_t *mac,
frame_t frame_tx;
int slot_tx;
- if (-1 == nr_ue_pusch_scheduler(mac, 0, frame, slot, &frame_tx, &slot_tx, tda_info.k2)) {
+ const int ntn_ue_koffset = get_NTN_UE_Koffset(mac->sc_info.ntn_Config_r17, mac->current_UL_BWP->scs);
+ if (-1 == nr_ue_pusch_scheduler(mac, 0, frame, slot, &frame_tx, &slot_tx, tda_info.k2 + ntn_ue_koffset)) {
LOG_E(MAC, "Cannot schedule PUSCH\n");
return -1;
}
@@ -589,7 +597,8 @@ static int nr_ue_process_dci_ul_01(NR_UE_MAC_INST_t *mac,
tda_info.k2 = csi_K2;
}
- if (-1 == nr_ue_pusch_scheduler(mac, 0, frame, slot, &frame_tx, &slot_tx, tda_info.k2)) {
+ const int ntn_ue_koffset = get_NTN_UE_Koffset(mac->sc_info.ntn_Config_r17, mac->current_UL_BWP->scs);
+ if (-1 == nr_ue_pusch_scheduler(mac, 0, frame, slot, &frame_tx, &slot_tx, tda_info.k2 + ntn_ue_koffset)) {
LOG_E(MAC, "Cannot schedule PUSCH\n");
return -1;
}
@@ -903,10 +912,15 @@ static int nr_ue_process_dci_dl_10(NR_UE_MAC_INST_t *mac,
return -1;
}
+ /* PDSCH_TO_HARQ_FEEDBACK_TIME_IND */
+ // according to TS 38.213 9.2.3
+ const int ntn_ue_koffset = get_NTN_UE_Koffset(mac->sc_info.ntn_Config_r17, dlsch_pdu->SubcarrierSpacing);
+ const uint16_t feedback_ti = 1 + dci->pdsch_to_harq_feedback_timing_indicator.val + ntn_ue_koffset;
+
if (rnti_type != TYPE_RA_RNTI_ && rnti_type != TYPE_SI_RNTI_) {
- AssertFatal(1 + dci->pdsch_to_harq_feedback_timing_indicator.val > DURATION_RX_TO_TX,
+ AssertFatal(feedback_ti > DURATION_RX_TO_TX,
"PDSCH to HARQ feedback time (%d) needs to be higher than DURATION_RX_TO_TX (%d).\n",
- 1 + dci->pdsch_to_harq_feedback_timing_indicator.val,
+ feedback_ti,
DURATION_RX_TO_TX);
// set the harq status at MAC for feedback
const int tpc[] = {-1, 0, 1, 3};
@@ -914,7 +928,7 @@ static int nr_ue_process_dci_dl_10(NR_UE_MAC_INST_t *mac,
dci->pucch_resource_indicator,
dci->harq_pid,
tpc[dci->tpc],
- 1 + dci->pdsch_to_harq_feedback_timing_indicator.val,
+ feedback_ti,
dci->dai[0].val,
dci_ind->n_CCE,
dci_ind->N_CCE,
@@ -948,9 +962,9 @@ static int nr_ue_process_dci_dl_10(NR_UE_MAC_INST_t *mac,
dlsch_pdu->scaling_factor_S,
dci->tpc,
dci->pucch_resource_indicator,
- 1 + dci->pdsch_to_harq_feedback_timing_indicator.val);
+ feedback_ti);
- dlsch_pdu->k1_feedback = 1 + dci->pdsch_to_harq_feedback_timing_indicator.val;
+ dlsch_pdu->k1_feedback = feedback_ti;
LOG_D(MAC, "(nr_ue_procedures.c) pdu_type=%d\n\n", dl_conf_req->pdu_type);
@@ -1239,7 +1253,8 @@ static int nr_ue_process_dci_dl_11(NR_UE_MAC_INST_t *mac,
/* PDSCH_TO_HARQ_FEEDBACK_TIME_IND */
// according to TS 38.213 Table 9.2.3-1
- uint8_t feedback_ti = pucch_Config->dl_DataToUL_ACK->list.array[dci->pdsch_to_harq_feedback_timing_indicator.val][0];
+ const int ntn_ue_koffset = get_NTN_UE_Koffset(mac->sc_info.ntn_Config_r17, dlsch_pdu->SubcarrierSpacing);
+ const uint16_t feedback_ti = pucch_Config->dl_DataToUL_ACK->list.array[dci->pdsch_to_harq_feedback_timing_indicator.val][0] + ntn_ue_koffset;
AssertFatal(feedback_ti > DURATION_RX_TO_TX,
"PDSCH to HARQ feedback time (%d) needs to be higher than DURATION_RX_TO_TX (%d). Min feedback time set in config "
@@ -1436,7 +1451,7 @@ void set_harq_status(NR_UE_MAC_INST_t *mac,
uint8_t pucch_id,
uint8_t harq_id,
int8_t delta_pucch,
- uint8_t data_toul_fb,
+ uint16_t data_toul_fb,
uint8_t dai,
int n_CCE,
int N_CCE,
@@ -1457,7 +1472,7 @@ void set_harq_status(NR_UE_MAC_INST_t *mac,
current_harq->ul_frame = frame;
current_harq->ul_slot = slot + data_toul_fb;
if (current_harq->ul_slot >= slots_per_frame) {
- current_harq->ul_frame = (frame + 1) % 1024;
+ current_harq->ul_frame = (frame + current_harq->ul_slot / slots_per_frame) % MAX_FRAME_NUMBER;
current_harq->ul_slot %= slots_per_frame;
}
// counter DAI in DCI ranges from 0 to 3
@@ -3544,9 +3559,13 @@ void nr_ue_process_mac_pdu(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_i
NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &mac->ul_time_alignment;
ul_time_alignment->tag_id = tag;
ul_time_alignment->ta_command = ta;
- ul_time_alignment->frame = frameP;
- ul_time_alignment->slot = slot;
ul_time_alignment->ta_apply = adjustment_ta;
+
+ const int ntn_ue_koffset = get_NTN_UE_Koffset(mac->sc_info.ntn_Config_r17, mac->current_UL_BWP->scs);
+ const int n_slots_frame = nr_slots_per_frame[mac->current_UL_BWP->scs];
+ ul_time_alignment->frame = (frameP + (slot + ntn_ue_koffset) / n_slots_frame) % MAX_FRAME_NUMBER;
+ ul_time_alignment->slot = (slot + ntn_ue_koffset) % n_slots_frame;
+
/*
#ifdef DEBUG_HEADER_PARSING
LOG_D(MAC, "[UE] CE %d : UE Timing Advance : %d\n", i, pduP[1]);
@@ -4023,9 +4042,12 @@ static void nr_ue_process_rar(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *d
LOG_E(MAC, "Cannot schedule Msg3. Something wrong in TDA information\n");
return;
}
- ret = nr_ue_pusch_scheduler(mac, is_Msg3, frame, slot, &frame_tx, &slot_tx, tda_info.k2);
- ul_time_alignment->frame = frame_tx;
- ul_time_alignment->slot = slot_tx;
+ const int ntn_ue_koffset = get_NTN_UE_Koffset(mac->sc_info.ntn_Config_r17, mac->current_UL_BWP->scs);
+ ret = nr_ue_pusch_scheduler(mac, is_Msg3, frame, slot, &frame_tx, &slot_tx, tda_info.k2 + ntn_ue_koffset);
+
+ const int n_slots_frame = nr_slots_per_frame[current_UL_BWP->scs];
+ ul_time_alignment->frame = (frame_tx + (slot_tx + ntn_ue_koffset) / n_slots_frame) % MAX_FRAME_NUMBER;
+ ul_time_alignment->slot = (slot_tx + ntn_ue_koffset) % n_slots_frame;
if (ret != -1) {
uint16_t rnti = mac->crnti;
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
index b88ca7e5f3..315f1ef522 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
@@ -662,8 +662,13 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
pusch_config_pdu->pusch_uci.harq_ack_bit_length = 0;
- pusch_config_pdu->bwp_start = current_UL_BWP->BWPStart;
- pusch_config_pdu->bwp_size = current_UL_BWP->BWPSize;
+ if (dci_format == NR_UL_DCI_FORMAT_0_0 && ss_type == NR_SearchSpace__searchSpaceType_PR_common) {
+ pusch_config_pdu->bwp_start = sc_info->initial_ul_BWPStart;
+ pusch_config_pdu->bwp_size = sc_info->initial_ul_BWPSize;
+ } else {
+ pusch_config_pdu->bwp_start = current_UL_BWP->BWPStart;
+ pusch_config_pdu->bwp_size = current_UL_BWP->BWPSize;
+ }
pusch_config_pdu->start_symbol_index = tda_info->startSymbolIndex;
pusch_config_pdu->nr_of_symbols = tda_info->nrOfSymbols;
@@ -753,7 +758,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
if (nr_ue_process_dci_freq_dom_resource_assignment(pusch_config_pdu,
NULL,
NULL,
- current_UL_BWP->BWPSize,
+ pusch_config_pdu->bwp_size,
0,
0,
dci->frequency_domain_assignment) < 0) {
@@ -773,12 +778,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
/* MCS TABLE */
long *mcs_table_config = pusch_Config ? (tp_enabled ? pusch_Config->mcs_TableTransformPrecoder : pusch_Config->mcs_Table) : NULL;
- pusch_config_pdu->mcs_table = get_pusch_mcs_table(mcs_table_config,
- tp_enabled,
- dci_format,
- rnti_type,
- ss_type,
- false);
+ pusch_config_pdu->mcs_table = get_pusch_mcs_table(mcs_table_config, tp_enabled, dci_format, rnti_type, ss_type, false);
/* NDI */
NR_UL_HARQ_INFO_t *harq = &mac->ul_harq_info[dci->harq_pid];
@@ -793,20 +793,6 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
pusch_config_pdu->pusch_data.rv_index = dci->rv;
/* HARQ_PROCESS_NUMBER */
pusch_config_pdu->pusch_data.harq_process_id = dci->harq_pid;
- /* TPC_PUSCH */
- // according to TS 38.213 Table Table 7.1.1-1
- if (dci->tpc == 0) {
- pusch_config_pdu->absolute_delta_PUSCH = -4;
- }
- if (dci->tpc == 1) {
- pusch_config_pdu->absolute_delta_PUSCH = -1;
- }
- if (dci->tpc == 2) {
- pusch_config_pdu->absolute_delta_PUSCH = 1;
- }
- if (dci->tpc == 3) {
- pusch_config_pdu->absolute_delta_PUSCH = 4;
- }
if (NR_DMRS_ulconfig != NULL)
add_pos = (NR_DMRS_ulconfig->dmrs_AdditionalPosition == NULL) ? 2 : *NR_DMRS_ulconfig->dmrs_AdditionalPosition;
@@ -913,6 +899,22 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
pusch_config_pdu->pusch_data.tb_size = mac->ul_harq_info[pid].TBS;
}
+ /* TPC_PUSCH */
+ int delta_pusch = 0;
+ if (dci) {
+ bool stateless_pusch_power_control = mac->current_UL_BWP->pusch_Config != NULL
+ && mac->current_UL_BWP->pusch_Config->pusch_PowerControl != NULL
+ && mac->current_UL_BWP->pusch_Config->pusch_PowerControl->tpc_Accumulation != NULL;
+ int table_38_213_7_1_1_1[2][4] = {{-1, 0, 1, 3}, {-4, -1, 1, 4}};
+ if (stateless_pusch_power_control) {
+ delta_pusch = table_38_213_7_1_1_1[1][dci->tpc];
+ } else {
+ // TODO: This is not entirely correct. In case there is a prevously scheduled PUSCH for a future slot
+ // we should apply its TPC now.
+ delta_pusch = table_38_213_7_1_1_1[0][dci->tpc];
+ }
+ }
+
bool is_rar_tx_retx = rnti_type == TYPE_TC_RNTI_;
pusch_config_pdu->tx_power = get_pusch_tx_power_ue(mac,
@@ -925,7 +927,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
pusch_config_pdu->target_code_rate,
pusch_config_pdu->pusch_uci.beta_offset_csi1,
pusch_config_pdu->pusch_data.tb_size << 3,
- pusch_config_pdu->absolute_delta_PUSCH,
+ delta_pusch,
is_rar_tx_retx,
pusch_config_pdu->transform_precoding);
@@ -1112,7 +1114,7 @@ void nr_ue_aperiodic_srs_scheduling(NR_UE_MAC_INST_t *mac, long resource_trigger
LOG_E(NR_MAC, "Slot for scheduling aperiodic SRS %d is not an UL slot\n", sched_slot);
return;
}
- int sched_frame = frame + (slot + slot_offset >= n_slots_frame) % 1024;
+ int sched_frame = frame + (slot + slot_offset / n_slots_frame) % MAX_FRAME_NUMBER;
fapi_nr_ul_config_request_pdu_t *pdu = lockGet_ul_config(mac, sched_frame, sched_slot, FAPI_NR_UL_CONFIG_TYPE_SRS);
if (!pdu)
return;
@@ -1400,7 +1402,7 @@ void nr_ue_ul_scheduler(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_info)
while (ulcfg_pdu->pdu_type != FAPI_NR_END) {
uint8_t *ulsch_input_buffer = ulsch_input_buffer_array[number_of_pdus];
if (ulcfg_pdu->pdu_type == FAPI_NR_UL_CONFIG_TYPE_PUSCH) {
- uint16_t TBS_bytes = ulcfg_pdu->pusch_config_pdu.pusch_data.tb_size;
+ uint32_t TBS_bytes = ulcfg_pdu->pusch_config_pdu.pusch_data.tb_size;
LOG_D(NR_MAC,
"harq_id %d, new_data_indicator %d, TBS_bytes %d (ra_state %d)\n",
ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id,
@@ -1571,11 +1573,7 @@ int nr_ue_pusch_scheduler(const NR_UE_MAC_INST_t *mac,
DURATION_RX_TO_TX);
*slot_tx = (current_slot + k2 + delta) % nr_slots_per_frame[mu];
- if (current_slot + k2 + delta >= nr_slots_per_frame[mu]){
- *frame_tx = (current_frame + 1) % 1024;
- } else {
- *frame_tx = current_frame;
- }
+ *frame_tx = (current_frame + (current_slot + k2 + delta) / nr_slots_per_frame[mu]) % MAX_FRAME_NUMBER;
} else {
@@ -1593,7 +1591,7 @@ int nr_ue_pusch_scheduler(const NR_UE_MAC_INST_t *mac,
// Calculate TX slot and frame
*slot_tx = (current_slot + k2) % nr_slots_per_frame[mu];
- *frame_tx = ((current_slot + k2) > (nr_slots_per_frame[mu]-1)) ? (current_frame + 1) % 1024 : current_frame;
+ *frame_tx = (current_frame + (current_slot + k2) / nr_slots_per_frame[mu]) % MAX_FRAME_NUMBER;
}
@@ -2759,7 +2757,7 @@ static int nr_ue_get_sdu_mac_ce_pre(NR_UE_MAC_INST_t *mac,
sub_frame_t subframe,
uint8_t gNB_index,
uint8_t *ulsch_buffer,
- uint16_t buflen,
+ uint32_t buflen,
NR_UE_MAC_CE_INFO *mac_ce_p)
{
int num_lcg_id_with_data = 0;
@@ -2822,11 +2820,11 @@ static void nr_ue_get_sdu_mac_ce_post(NR_UE_MAC_INST_t *mac,
frame_t frame,
slot_t slot,
uint8_t *ulsch_buffer,
- uint16_t buflen,
+ uint32_t buflen,
NR_UE_MAC_CE_INFO *mac_ce_p)
{
// Compute BSR Values and update Nb LCGID with data after multiplexing
- unsigned short padding_len = 0;
+ uint32_t padding_len = 0;
int num_lcg_id_with_data = 0;
int lcg_id_bsr_trunc = 0;
NR_UE_SCHEDULING_INFO *sched_info = &mac->scheduling_info;
@@ -3010,8 +3008,8 @@ uint32_t get_count_lcids_same_priority(uint8_t start, uint8_t total_active_lcids
long get_num_bytes_to_reqlc(NR_UE_MAC_INST_t *mac,
uint8_t same_priority_count,
uint8_t lc_num,
- uint16_t buflen_remain_ep,
- int16_t buflen_remain,
+ uint32_t buflen_remain_ep,
+ int32_t buflen_remain,
uint8_t round_id,
uint32_t *bytes_read_fromlc,
long *target)
@@ -3027,7 +3025,7 @@ long get_num_bytes_to_reqlc(NR_UE_MAC_INST_t *mac,
long num_remaining_bytes = 0;
long num_bytes_requested = 0;
if (round_id == 0) { // initial round
- uint16_t pdu_remain = (same_priority_count > 1) ? buflen_remain_ep : buflen_remain;
+ uint32_t pdu_remain = (same_priority_count > 1) ? buflen_remain_ep : buflen_remain;
num_bytes_requested = (pdu_remain < pbr) ? min(pdu_remain, lcid_remain_buffer) : min(pbr, lcid_remain_buffer);
num_remaining_bytes = *target - bytes_read_fromlc[lc_num - 1];
num_bytes_requested = min(num_bytes_requested, num_remaining_bytes);
@@ -3079,13 +3077,13 @@ static bool fill_mac_sdu(NR_UE_MAC_INST_t *mac,
frame_t frame,
slot_t slot,
uint8_t gNB_index,
- uint16_t buflen,
- int16_t *buflen_remain,
+ uint32_t buflen,
+ int32_t *buflen_remain,
int lcid,
uint8_t **pdu,
uint32_t *counter,
uint8_t count_same_priority_lcids,
- uint16_t buflen_ep,
+ uint32_t buflen_ep,
uint32_t *lcids_bytes_tot,
uint16_t *num_sdus,
NR_UE_MAC_CE_INFO *mac_ce_p,
@@ -3236,11 +3234,11 @@ uint8_t nr_ue_get_sdu(NR_UE_MAC_INST_t *mac,
slot_t slot,
uint8_t gNB_index,
uint8_t *ulsch_buffer,
- uint16_t buflen)
+ uint32_t buflen)
{
NR_UE_MAC_CE_INFO mac_ce_info;
NR_UE_MAC_CE_INFO *mac_ce_p=&mac_ce_info;
- int16_t buflen_remain = 0;
+ int32_t buflen_remain = 0;
mac_ce_p->bsr_len = 0;
mac_ce_p->bsr_ce_len = 0;
mac_ce_p->bsr_header_len = 0;
@@ -3271,7 +3269,7 @@ uint8_t nr_ue_get_sdu(NR_UE_MAC_INST_t *mac,
// in the first run all the lc are allocated as per bj and prioritized bit rate but in subsequent runs, no need to consider
uint32_t lcp_allocation_counter = 0;
// bj and prioritized bit rate but just consider priority
- uint16_t buflen_ep = 0; // this variable holds the length in bytes in mac pdu when multiple equal priority channels are present
+ uint32_t buflen_ep = 0; // this variable holds the length in bytes in mac pdu when multiple equal priority channels are present
// because as per standard(TS38.321), all equal priority channels should be served equally
// nr_ue_get_sdu_mac_ce_pre updates all mac_ce related header field related to length
@@ -3393,12 +3391,12 @@ uint8_t nr_ue_get_sdu(NR_UE_MAC_INST_t *mac,
// Compute final offset for padding and fill remainder of ULSCH with 0
if (buflen_remain > 0) {
- LOG_D(NR_MAC, "In %s filling remainder %d bytes to the UL PDU \n", __FUNCTION__, buflen_remain);
+ LOG_D(NR_MAC, "Filling remainder %d bytes to the UL PDU \n", buflen_remain);
((NR_MAC_SUBHEADER_FIXED *) pdu)->R = 0;
((NR_MAC_SUBHEADER_FIXED *) pdu)->LCID = UL_SCH_LCID_PADDING;
#ifdef ENABLE_MAC_PAYLOAD_DEBUG
- LOG_I(NR_MAC, "In %s: padding MAC sub-header with length %ld bytes \n", __FUNCTION__, sizeof(NR_MAC_SUBHEADER_FIXED));
+ LOG_I(NR_MAC, "Padding MAC sub-header with length %ld bytes \n", sizeof(NR_MAC_SUBHEADER_FIXED));
log_dump(NR_MAC, pdu, sizeof(NR_MAC_SUBHEADER_FIXED), LOG_DUMP_CHAR, "\n");
#endif
@@ -3414,13 +3412,13 @@ uint8_t nr_ue_get_sdu(NR_UE_MAC_INST_t *mac,
}
#ifdef ENABLE_MAC_PAYLOAD_DEBUG
- LOG_I(NR_MAC, "In %s: MAC padding sub-PDU with length %d bytes \n", __FUNCTION__, buflen_remain);
+ LOG_I(NR_MAC, "MAC padding sub-PDU with length %d bytes \n", buflen_remain);
log_dump(NR_MAC, pdu, buflen_remain, LOG_DUMP_CHAR, "\n");
#endif
}
#ifdef ENABLE_MAC_PAYLOAD_DEBUG
- LOG_I(NR_MAC, "In %s: dumping MAC PDU with length %d: \n", __FUNCTION__, buflen);
+ LOG_I(NR_MAC, "Dumping MAC PDU with length %d: \n", buflen);
log_dump(NR_MAC, ulsch_buffer, buflen, LOG_DUMP_CHAR, "\n");
#endif
diff --git a/openair2/LAYER2/NR_MAC_UE/tests/test_nr_ue_power_procedures.cpp b/openair2/LAYER2/NR_MAC_UE/tests/test_nr_ue_power_procedures.cpp
index 3f865ec597..a315835df7 100644
--- a/openair2/LAYER2/NR_MAC_UE/tests/test_nr_ue_power_procedures.cpp
+++ b/openair2/LAYER2/NR_MAC_UE/tests/test_nr_ue_power_procedures.cpp
@@ -198,6 +198,7 @@ TEST(pusch_power_control, pusch_power_control_msg3)
NR_PUSCH_PowerControl pusch_PowerControl = {0};
pusch_Config.pusch_PowerControl = &pusch_PowerControl;
pusch_PowerControl.tpc_Accumulation = (long*)1;
+ mac.pusch_power_control_initialized = true;
mac.frame_type = TDD;
// msg3 cofiguration as in 5g_rfsimulator testcase
@@ -358,6 +359,216 @@ TEST(pusch_power_control, pusch_power_data)
EXPECT_EQ(power, P_CMAX) << "Expecting max tx power because of deltaMCS with CSI-only";
}
+TEST(pusch_power_control, pusch_power_control_state_initialization)
+{
+ NR_UE_MAC_INST_t mac = {0};
+ NR_UE_UL_BWP_t current_UL_BWP = {0};
+ current_UL_BWP.scs = 1;
+ current_UL_BWP.BWPSize = 106;
+ mac.current_UL_BWP = ¤t_UL_BWP;
+ NR_RACH_ConfigCommon_t nr_rach_ConfigCommon = {0};
+ current_UL_BWP.rach_ConfigCommon = &nr_rach_ConfigCommon;
+ mac.nr_band = 78;
+ NR_PUSCH_Config_t pusch_Config = {0};
+ current_UL_BWP.pusch_Config = &pusch_Config;
+ NR_PUSCH_PowerControl pusch_PowerControl = {0};
+ pusch_Config.pusch_PowerControl = &pusch_PowerControl;
+ mac.pusch_power_control_initialized = false;
+
+ // msg3 cofiguration as in 5g_rfsimulator testcase
+ int num_rb = 8;
+ int start_prb = 0;
+ uint16_t nb_symb_sch = 3;
+ uint16_t nb_dmrs_prb = 12;
+ uint16_t nb_ptrs_prb = 0;
+ uint16_t Qm = 2;
+ uint16_t R = 1570;
+ uint16_t beta_offset_csi1 = 0;
+ uint32_t sum_bits_in_codeblocks = 56;
+ int delta_pusch = 0;
+ bool is_rar_tx_retx = true;
+ long preambleReceivedTargetPower = -96;
+ nr_rach_ConfigCommon.rach_ConfigGeneric.preambleReceivedTargetPower = preambleReceivedTargetPower;
+
+ get_pusch_tx_power_ue(&mac,
+ num_rb,
+ start_prb,
+ nb_symb_sch,
+ nb_dmrs_prb,
+ nb_ptrs_prb,
+ Qm,
+ R,
+ beta_offset_csi1,
+ sum_bits_in_codeblocks,
+ delta_pusch,
+ is_rar_tx_retx,
+ false);
+ EXPECT_EQ(mac.pusch_power_control_initialized, true);
+}
+
+TEST(pusch_power_control, pusch_power_control_state)
+{
+ NR_UE_MAC_INST_t mac = {0};
+ NR_UE_UL_BWP_t current_UL_BWP = {0};
+ current_UL_BWP.scs = 1;
+ current_UL_BWP.BWPSize = 106;
+ mac.current_UL_BWP = ¤t_UL_BWP;
+ NR_RACH_ConfigCommon_t nr_rach_ConfigCommon = {0};
+ current_UL_BWP.rach_ConfigCommon = &nr_rach_ConfigCommon;
+ mac.nr_band = 78;
+ mac.f_b_f_c = 0;
+ mac.pusch_power_control_initialized = true;
+
+ bool is_rar_tx_retx = false;
+ int num_rb = 5;
+ int start_prb = 0;
+ uint16_t nb_symb_sch = 3;
+ uint16_t nb_dmrs_prb = 6;
+ uint16_t nb_ptrs_prb = 0;
+ uint16_t Qm = 2;
+ uint16_t R = 6790;
+ uint16_t beta_offset_csi1 = 0;
+ uint32_t sum_bits_in_codeblocks = 192;
+ int delta_pusch = 1;
+ bool transform_precoding = false;
+ NR_PUSCH_Config_t pusch_Config = {0};
+ current_UL_BWP.pusch_Config = &pusch_Config;
+ NR_PUSCH_PowerControl pusch_PowerControl = {0};
+ pusch_Config.pusch_PowerControl = &pusch_PowerControl;
+ long p0_NominalWithGrant = 0;
+ current_UL_BWP.p0_NominalWithGrant = &p0_NominalWithGrant;
+ mac.frame_type = TDD;
+
+ int P_CMAX = nr_get_Pcmax(23,
+ mac.nr_band,
+ mac.frame_type,
+ FR1,
+ Qm,
+ false,
+ current_UL_BWP.scs,
+ current_UL_BWP.BWPSize,
+ transform_precoding,
+ num_rb,
+ start_prb);
+
+ int power = get_pusch_tx_power_ue(&mac,
+ num_rb,
+ start_prb,
+ nb_symb_sch,
+ nb_dmrs_prb,
+ nb_ptrs_prb,
+ Qm,
+ R,
+ beta_offset_csi1,
+ sum_bits_in_codeblocks,
+ delta_pusch,
+ is_rar_tx_retx,
+ transform_precoding);
+ EXPECT_LE(power, P_CMAX);
+ EXPECT_EQ(power, 11);
+ for (int i = 0; i < 20; i++) {
+ int increased_power = get_pusch_tx_power_ue(&mac,
+ num_rb,
+ start_prb,
+ nb_symb_sch,
+ nb_dmrs_prb,
+ nb_ptrs_prb,
+ Qm,
+ R,
+ beta_offset_csi1,
+ sum_bits_in_codeblocks,
+ delta_pusch,
+ is_rar_tx_retx,
+ transform_precoding);
+ EXPECT_GE(increased_power, power);
+ EXPECT_LE(increased_power, P_CMAX);
+ power = increased_power;
+ }
+
+ delta_pusch = -1;
+ for (int i = 0; i < 20; i++) {
+ int reduced_power = get_pusch_tx_power_ue(&mac,
+ num_rb,
+ start_prb,
+ nb_symb_sch,
+ nb_dmrs_prb,
+ nb_ptrs_prb,
+ Qm,
+ R,
+ beta_offset_csi1,
+ sum_bits_in_codeblocks,
+ delta_pusch,
+ is_rar_tx_retx,
+ transform_precoding);
+ EXPECT_LE(reduced_power, power);
+ EXPECT_LE(reduced_power, P_CMAX);
+ power = reduced_power;
+ }
+}
+
+TEST(pusch_power_control, pusch_power_100_rb)
+{
+ NR_UE_MAC_INST_t mac = {0};
+ NR_UE_UL_BWP_t current_UL_BWP = {0};
+ current_UL_BWP.scs = 1;
+ current_UL_BWP.BWPSize = 106;
+ mac.current_UL_BWP = ¤t_UL_BWP;
+ NR_RACH_ConfigCommon_t nr_rach_ConfigCommon = {0};
+ current_UL_BWP.rach_ConfigCommon = &nr_rach_ConfigCommon;
+ mac.nr_band = 78;
+ mac.f_b_f_c = 0;
+ mac.pusch_power_control_initialized = true;
+
+ bool is_rar_tx_retx = false;
+ int num_rb = 5;
+ int start_prb = 0;
+ uint16_t nb_symb_sch = 3;
+ uint16_t nb_dmrs_prb = 6;
+ uint16_t nb_ptrs_prb = 0;
+ uint16_t Qm = 2;
+ uint16_t R = 6790;
+ uint16_t beta_offset_csi1 = 0;
+ uint32_t sum_bits_in_codeblocks = 192;
+ int delta_pusch = 1;
+ bool transform_precoding = false;
+ NR_PUSCH_Config_t pusch_Config = {0};
+ current_UL_BWP.pusch_Config = &pusch_Config;
+ NR_PUSCH_PowerControl pusch_PowerControl = {0};
+ pusch_Config.pusch_PowerControl = &pusch_PowerControl;
+ long p0_NominalWithGrant = 0;
+ current_UL_BWP.p0_NominalWithGrant = &p0_NominalWithGrant;
+ int power = get_pusch_tx_power_ue(&mac,
+ num_rb,
+ start_prb,
+ nb_symb_sch,
+ nb_dmrs_prb,
+ nb_ptrs_prb,
+ Qm,
+ R,
+ beta_offset_csi1,
+ sum_bits_in_codeblocks,
+ delta_pusch,
+ is_rar_tx_retx,
+ transform_precoding);
+ num_rb = 100;
+ sum_bits_in_codeblocks = nr_compute_tbs(Qm, R, num_rb, nb_symb_sch, nb_dmrs_prb, 0, 0, 1);
+
+ int power_100_prbs = get_pusch_tx_power_ue(&mac,
+ num_rb,
+ start_prb,
+ nb_symb_sch,
+ nb_dmrs_prb,
+ nb_ptrs_prb,
+ Qm,
+ R,
+ beta_offset_csi1,
+ sum_bits_in_codeblocks,
+ delta_pusch,
+ is_rar_tx_retx,
+ transform_precoding);
+ EXPECT_GT(power_100_prbs, power);
+}
+
int main(int argc, char** argv)
{
logInit();
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
index 89c684ee41..1048be2528 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
@@ -40,7 +40,7 @@
//#define SRS_IND_DEBUG
-static rnti_t lcid_crnti_lookahead(uint8_t *pdu, int pdu_len)
+static rnti_t lcid_crnti_lookahead(uint8_t *pdu, uint32_t pdu_len)
{
uint16_t mac_len = 0;
uint16_t mac_subheader_len = 0;
@@ -55,7 +55,13 @@ static rnti_t lcid_crnti_lookahead(uint8_t *pdu, int pdu_len)
break;
}
pdu += mac_len + mac_subheader_len;
- pdu_len -= mac_len + mac_subheader_len;
+ // if pdu_len can have the value subtracted without underflow, we can subtract
+ if (pdu_len >= mac_len + mac_subheader_len) {
+ pdu_len -= mac_len + mac_subheader_len;
+ } else {
+ // if not, set to 0 to prevent underflow
+ pdu_len = 0;
+ }
}
return 0;
}
@@ -200,7 +206,7 @@ static int nr_process_mac_pdu(instance_t module_idP,
frame_t frameP,
sub_frame_t slot,
uint8_t *pduP,
- int pdu_len,
+ uint32_t pdu_len,
const int8_t harq_pid)
{
@@ -644,7 +650,7 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP,
const sub_frame_t slotP,
const rnti_t rntiP,
uint8_t *sduP,
- const uint16_t sdu_lenP,
+ const uint32_t sdu_lenP,
const uint16_t timing_advance,
const uint8_t ul_cqi,
const uint16_t rssi)
@@ -725,10 +731,10 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP,
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
LOG_I(NR_MAC, "Printing received UL MAC payload at gNB side: %d \n");
- for (int i = 0; i < sdu_lenP ; i++) {
- //harq_process_ul_ue->a[i] = (unsigned char) rand();
- //printf("a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]);
- printf("%02x ",(unsigned char)sduP[i]);
+ for (uint32_t i = 0; i < sdu_lenP; i++) {
+ // harq_process_ul_ue->a[i] = (unsigned char) rand();
+ // printf("a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]);
+ printf("%02x ", (unsigned char)sduP[i]);
}
printf("\n");
@@ -770,8 +776,8 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP,
} else if (sduP) {
bool no_sig = true;
- for (int k = 0; k < sdu_lenP; k++) {
- if(sduP[k] != 0) {
+ for (uint32_t k = 0; k < sdu_lenP; k++) {
+ if (sduP[k] != 0) {
no_sig = false;
break;
}
@@ -856,7 +862,7 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP,
} else {
LOG_A(NR_MAC, "[RAPROC] RA-Msg3 received (sdu_lenP %d)\n", sdu_lenP);
LOG_D(NR_MAC, "[RAPROC] Received Msg3:\n");
- for (int k = 0; k < sdu_lenP; k++) {
+ for (uint32_t k = 0; k < sdu_lenP; k++) {
LOG_D(NR_MAC, "(%i): 0x%x\n", k, sduP[k]);
}
@@ -939,7 +945,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
const sub_frame_t slotP,
const rnti_t rntiP,
uint8_t *sduP,
- const uint16_t sdu_lenP,
+ const uint32_t sdu_lenP,
const uint16_t timing_advance,
const uint8_t ul_cqi,
const uint16_t rssi)
diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
index a23e588a49..fe2fec8ab1 100644
--- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
+++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
@@ -343,7 +343,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
const sub_frame_t subframeP,
const rnti_t rntiP,
uint8_t * sduP,
- const uint16_t sdu_lenP,
+ const uint32_t sdu_lenP,
const uint16_t timing_advance,
const uint8_t ul_cqi,
const uint16_t rssi);
diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c
index 266728fd54..4174eff42a 100644
--- a/openair2/RRC/NR/rrc_gNB.c
+++ b/openair2/RRC/NR/rrc_gNB.c
@@ -487,10 +487,6 @@ static void rrc_gNB_process_RRCSetupComplete(const protocol_ctxt_t *const ctxt_p
AssertFatal(ctxt_pP->rntiMaybeUEid == ue_context_pP->ue_context.rrc_ue_id, "logic bug: inconsistent IDs, must use CU UE ID!\n");
rrc_gNB_send_NGAP_NAS_FIRST_REQ(ctxt_pP, ue_context_pP, rrcSetupComplete);
-
-#ifdef E2_AGENT
- signal_rrc_state_changed_to(&ue_context_pP->ue_context, RC_SM_RRC_CONNECTED);
-#endif
}
//-----------------------------------------------------------------------------
diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c
index 003db92ab7..e1395ce6cd 100644
--- a/openair2/RRC/NR/rrc_gNB_NGAP.c
+++ b/openair2/RRC/NR/rrc_gNB_NGAP.c
@@ -491,6 +491,10 @@ int rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, instance_t
UE->initial_pdus[i] = req->pdusession_param[i];
}
+#ifdef E2_AGENT
+ signal_rrc_state_changed_to(UE, RC_SM_RRC_CONNECTED);
+#endif
+
return 0;
}
diff --git a/openshift/README.md b/openshift/README.md
index 9f0923bd60..5560621e68 100644
--- a/openshift/README.md
+++ b/openshift/README.md
@@ -27,36 +27,37 @@ the ran-build image. If you reinstalled dependencies, you have to restart from
ran-base.
You first need to login. Do:
+
```bash
oc login -u -p --server
```
-## RHEL8 Entitlements
+Create a project/namespace where you will create your images
-To build the RAN images, we use the `codeready-builder-for-rhel-8-x86_64-rpms` repository with all the proper development libraries.
-This repository is not directly accessible from the UBI RHEL8 image (`registry.access.redhat.com/ubi8/ubi:latest`).
-Therefore, we need to copy certificates and subscription manager configuration files from a registered RHEL8 machine.
+```bash
+oc new-project oaicicd-ran
+```
-on a `RHEL8` physical machine (or a virtual machine) connected to the OpenShift Cluster, recover the entitlement and the RH subscription manager configs:
+**NOTE**: If you change the project name then you have to change it in all the `yaml` files.
+
+## RHEL9 Entitlements
+
+To build the RAN images, we use the `codeready-builder-for-rhel-9-x86_64-rpms`
+repository with all the proper development libraries. To access the library you
+will need `etc-pki-entitlement` inside the container image.
+
+To import `etc-pki-entitlement` in your project follow this
+[guide](https://docs.openshift.com/container-platform/4.14/cicd/builds/running-entitled-builds.html#builds-source-secrets-entitlements_running-entitled-builds)
+
+In case you have difficulties in following it then you can copy the
+certificates from an RHEL9 host
```bash
oc create configmap rhsm-conf --from-file /etc/rhsm/rhsm.conf
oc create configmap rhsm-ca --from-file /etc/rhsm/ca/redhat-uep.pem
-
oc create secret generic etc-pki-entitlement --from-file /etc/pki/entitlement/{NUMBER_ON_YOUR_COMPUTER}.pem --from-file /etc/pki/entitlement/{NUMBER_ON_YOUR_COMPUTER}-key.pem
```
-These configmaps and secret will be shared by all the build configs in your OC
-project. No need to do it each time. However, these files expire every month
-or so. If you have done a build on your OC project and try again a few weeks
-later, you may need to re-copy them. (The CI recopies them every time.)
-
-```bash
-oc delete secret etc-pki-entitlement
-oc delete cm rhsm-conf
-oc delete cm rhsm-ca
-```
-
# 2. Build of `base` shared image
Create an image stream and build config that specify image properties and build parameters, then start the build:
diff --git a/openshift/oai-gnb-fhi72-bc.yaml b/openshift/oai-gnb-fhi72-bc.yaml
new file mode 100644
index 0000000000..2d8861e2d6
--- /dev/null
+++ b/openshift/oai-gnb-fhi72-bc.yaml
@@ -0,0 +1,48 @@
+#/*
+# * 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
+# */
+#---------------------------------------------------------------------
+#
+kind: BuildConfig
+apiVersion: build.openshift.io/v1
+metadata:
+ name: "oai-gnb-fhi72"
+spec:
+ runPolicy: "Serial"
+ source:
+ type: "Binary"
+ secrets:
+ - secret:
+ name: etc-pki-entitlement
+ destinationDir: etc-pki-entitlement
+ configMaps:
+ - configMap:
+ name: rhsm-conf
+ destinationDir: rhsm-conf
+ - configMap:
+ name: rhsm-ca
+ destinationDir: rhsm-ca
+ strategy:
+ dockerStrategy:
+ dockerfilePath: "docker/Dockerfile.gNB.fhi72.rhel9"
+ output:
+ to:
+ kind: "ImageStreamTag"
+ name: "oai-gnb-fhi72:latest"
diff --git a/openshift/oai-gnb-fhi72-is.yaml b/openshift/oai-gnb-fhi72-is.yaml
new file mode 100644
index 0000000000..a012434295
--- /dev/null
+++ b/openshift/oai-gnb-fhi72-is.yaml
@@ -0,0 +1,30 @@
+#/*
+# * 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
+# */
+#---------------------------------------------------------------------
+#
+apiVersion: image.openshift.io/v1
+kind: ImageStream
+metadata:
+ name: oai-gnb-fhi72
+ namespace: oaicicd-ran
+spec:
+ lookupPolicy:
+ local: true
diff --git a/openshift/ran-build-fhi72-bc.yaml b/openshift/ran-build-fhi72-bc.yaml
new file mode 100644
index 0000000000..35a7bd55b0
--- /dev/null
+++ b/openshift/ran-build-fhi72-bc.yaml
@@ -0,0 +1,39 @@
+#/*
+# * 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
+# */
+#---------------------------------------------------------------------
+#
+kind: BuildConfig
+apiVersion: build.openshift.io/v1
+metadata:
+ name: "ran-build-fhi72"
+spec:
+ runPolicy: "Serial"
+ nodeSelector:
+ kubernetes.io/hostname: demophon
+ source:
+ type: "Binary"
+ strategy:
+ dockerStrategy:
+ dockerfilePath: "docker/Dockerfile.build.fhi72.rhel9"
+ output:
+ to:
+ kind: "ImageStreamTag"
+ name: "ran-build-fhi72:latest"
diff --git a/openshift/ran-build-fhi72-is.yaml b/openshift/ran-build-fhi72-is.yaml
new file mode 100644
index 0000000000..eb5f9bebf6
--- /dev/null
+++ b/openshift/ran-build-fhi72-is.yaml
@@ -0,0 +1,30 @@
+#/*
+# * 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
+# */
+#---------------------------------------------------------------------
+#
+apiVersion: image.openshift.io/v1
+kind: ImageStream
+metadata:
+ name: ran-build-fhi72
+ namespace: oaicicd-ran
+spec:
+ lookupPolicy:
+ local: true
diff --git a/radio/rfsimulator/simulator.c b/radio/rfsimulator/simulator.c
index e524097898..0a2ece7d21 100644
--- a/radio/rfsimulator/simulator.c
+++ b/radio/rfsimulator/simulator.c
@@ -983,7 +983,7 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
rfsimulator->tx_bw=openair0_cfg->tx_bw;
rfsimulator_readconfig(rfsimulator);
if (rfsimulator->prop_delay_ms > 0.0)
- rfsimulator->chan_offset = rfsimulator->sample_rate * rfsimulator->prop_delay_ms / 1000;
+ rfsimulator->chan_offset = ceil(rfsimulator->sample_rate * rfsimulator->prop_delay_ms / 1000);
if (rfsimulator->chan_offset != 0) {
if (CirSize < minCirSize + rfsimulator->chan_offset) {
CirSize = minCirSize + rfsimulator->chan_offset;