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 +
+ +![Docker deploy 7.2](../../../doc/images/docker-deploy-oai-7-2.png) + +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;