Commit 7f774d5f authored by Robert Schmidt's avatar Robert Schmidt

Merge branch 'develop' into integration_2021_wk13_b

parents f5a1d356 f21ac1a8
......@@ -27,6 +27,9 @@ def nodeExecutor = params.nodeExecutor
def doMandatoryTests = false
def doFullTestsuite = false
//
def gitCommitAuthorEmailAddr
pipeline {
agent {
label nodeExecutor
......@@ -152,21 +155,40 @@ pipeline {
}
}
}
stage ("CppCheck Analysis") {
steps {
script {
triggerSlaveJob ('RAN-cppcheck', 'CppCheck Analysis')
}
}
post {
always {
script {
finalizeSlaveJob('RAN-cppcheck')
}
}
failure {
script {
currentBuild.result = 'FAILURE'
}
}
}
}
}
}
}
post {
always {
script {
def eSubject = JOB_NAME + ' - Build # ' + BUILD_ID + ' - ' + currentBuild.result + '!'
def eBody = "Hi,\n\n"
eBody += "Here are attached HTML report files for " + JOB_NAME + " - Build # " + BUILD_ID + " - " + currentBuild.result + "!\n\n"
eBody += "Regards,\n"
eBody += "OAI CI Team"
emailext attachmentsPattern: '*results*.html',
body: '''Hi,
Here are attached HTML report files for $PROJECT_NAME - Build # $BUILD_NUMBER - $BUILD_STATUS!
Regards,
OAI CI Team''',
body: eBody,
replyTo: 'no-reply@openairinterface.org',
subject: '$PROJECT_NAME - Build # $BUILD_NUMBER - $BUILD_STATUS!',
subject: eSubject,
to: gitCommitAuthorEmailAddr
if (fileExists('.git/CI_COMMIT_MSG')) {
......
......@@ -226,31 +226,12 @@ pipeline {
}
}
stage ("Start VM -- cppcheck") {
steps {
lock (vmResource) {
timeout (time: 7, unit: 'MINUTES') {
sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant cppcheck --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon"
}
}
}
}
stage ("Variant Builds") {
parallel {
stage ("Analysis with cppcheck") {
steps {
gitlabCommitStatus(name: "Analysis with cppcheck") {
timeout (time: 30, unit: 'MINUTES') {
sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant cppcheck --job-name ${JOB_NAME} --build-id ${BUILD_ID}"
}
}
}
}
stage ("Build basic simulator") {
steps {
gitlabCommitStatus(name: "Build basic-sim") {
timeout (time: 30, unit: 'MINUTES') {
timeout (time: 45, unit: 'MINUTES') {
sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant basic-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive"
}
}
......@@ -259,7 +240,7 @@ pipeline {
stage ("Build 5G gNB-USRP") {
steps {
gitlabCommitStatus(name: "Build gNB-USRP") {
timeout (time: 30, unit: 'MINUTES') {
timeout (time: 45, unit: 'MINUTES') {
sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant gnb-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive"
}
}
......@@ -268,7 +249,7 @@ pipeline {
stage ("Build 5G NR-UE-USRP") {
steps {
gitlabCommitStatus(name: "Build nr-UE-USRP") {
timeout (time: 30, unit: 'MINUTES') {
timeout (time: 45, unit: 'MINUTES') {
sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant nr-ue-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive"
}
}
......@@ -277,7 +258,7 @@ pipeline {
stage ("Build physical simulators") {
steps {
gitlabCommitStatus(name: "Build phy-sim") {
timeout (time: 30, unit: 'MINUTES') {
timeout (time: 45, unit: 'MINUTES') {
sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant phy-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive"
}
}
......@@ -286,7 +267,7 @@ pipeline {
stage ("Build eNB-ethernet") {
steps {
gitlabCommitStatus(name: "Build eNB-ethernet") {
timeout (time: 30, unit: 'MINUTES') {
timeout (time: 45, unit: 'MINUTES') {
sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant enb-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive"
}
}
......@@ -297,7 +278,7 @@ pipeline {
// This is typically the last one to finish.
lock (vmResource) {
gitlabCommitStatus(name: "Build UE-ethernet") {
timeout (time: 30, unit: 'MINUTES') {
timeout (time: 45, unit: 'MINUTES') {
sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant ue-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive"
}
}
......@@ -315,9 +296,9 @@ pipeline {
script {
dir ('archives') {
if (fileExists('red_hat')) {
sh "zip -r -qq vm_build_logs.zip basic_sim enb_usrp phy_sim cppcheck enb_eth ue_eth gnb_usrp nr_ue_usrp red_hat"
sh "zip -r -qq vm_build_logs.zip basic_sim phy_sim enb_eth ue_eth gnb_usrp nr_ue_usrp red_hat"
} else {
sh "zip -r -qq vm_build_logs.zip basic_sim enb_usrp phy_sim cppcheck enb_eth ue_eth gnb_usrp nr_ue_usrp"
sh "zip -r -qq vm_build_logs.zip basic_sim phy_sim enb_eth ue_eth gnb_usrp nr_ue_usrp"
}
}
if(fileExists('archives/vm_build_logs.zip')) {
......@@ -325,16 +306,6 @@ pipeline {
}
if ("MERGE".equals(env.gitlabActionType)) {
sh "./ci-scripts/oai-ci-vm-tool report-build --workspace $WORKSPACE --git-url ${GIT_URL} --job-name ${JOB_NAME} --build-id ${BUILD_ID} --trigger merge-request --src-branch ${env.gitlabSourceBranch} --src-commit ${env.gitlabMergeRequestLastCommit} --target-branch ${env.gitlabTargetBranch} --target-commit ${GIT_COMMIT}"
// If the merge request has introduced more CPPCHECK errors or warnings, notifications in GitLab
if (fileExists('oai_cppcheck_added_errors.txt')) {
def ret=readFile('./oai_cppcheck_added_errors.txt').trim();
if ("0".equals(ret)) {
echo "No added cppcheck warnings/errors in this merge request"
} else {
def message = "OAI " + JOB_NAME + " build (" + BUILD_ID + "): Some modified files in Merge Request MAY have INTRODUCED up to " + ret + " CPPCHECK errors/warnings"
addGitLabMRComment comment: message
}
}
// If the merge request has introduced compilation warnings, notifications in GitLab
sh "./ci-scripts/checkAddedWarnings.sh --src-branch ${env.gitlabSourceBranch} --target-branch ${env.gitlabTargetBranch}"
def res=readFile('./oai_warning_files.txt').trim();
......
......@@ -41,7 +41,7 @@ import constants as CONST
#-----------------------------------------------------------
def ArgsParse(argvs,CiTestObj,RAN,HTML,EPC,ldpc,CONTAINERS,HELP):
def ArgsParse(argvs,CiTestObj,RAN,HTML,EPC,ldpc,CONTAINERS,HELP,SCA):
py_param_file_present = False
......@@ -80,6 +80,7 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,EPC,ldpc,CONTAINERS,HELP):
HTML.ranRepository=matchReg.group(1)
ldpc.ranRepository=matchReg.group(1)
CONTAINERS.ranRepository=matchReg.group(1)
SCA.ranRepository=matchReg.group(1)
elif re.match('^\-\-eNB_AllowMerge=(.+)$|^\-\-ranAllowMerge=(.+)$', myArgv, re.IGNORECASE):
if re.match('^\-\-eNB_AllowMerge=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-eNB_AllowMerge=(.+)$', myArgv, re.IGNORECASE)
......@@ -92,6 +93,7 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,EPC,ldpc,CONTAINERS,HELP):
RAN.ranAllowMerge=True
HTML.ranAllowMerge=True
CONTAINERS.ranAllowMerge=True
SCA.ranAllowMerge=True
elif re.match('^\-\-eNBBranch=(.+)$|^\-\-ranBranch=(.+)$', myArgv, re.IGNORECASE):
if re.match('^\-\-eNBBranch=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-eNBBranch=(.+)$', myArgv, re.IGNORECASE)
......@@ -102,6 +104,7 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,EPC,ldpc,CONTAINERS,HELP):
HTML.ranBranch=matchReg.group(1)
ldpc.ranBranch=matchReg.group(1)
CONTAINERS.ranBranch=matchReg.group(1)
SCA.ranBranch=matchReg.group(1)
elif re.match('^\-\-eNBCommitID=(.*)$|^\-\-ranCommitID=(.*)$', myArgv, re.IGNORECASE):
if re.match('^\-\-eNBCommitID=(.*)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-eNBCommitID=(.*)$', myArgv, re.IGNORECASE)
......@@ -112,6 +115,7 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,EPC,ldpc,CONTAINERS,HELP):
HTML.ranCommitID=matchReg.group(1)
ldpc.ranCommitID=matchReg.group(1)
CONTAINERS.ranCommitID=matchReg.group(1)
SCA.ranCommitID=matchReg.group(1)
elif re.match('^\-\-eNBTargetBranch=(.*)$|^\-\-ranTargetBranch=(.*)$', myArgv, re.IGNORECASE):
if re.match('^\-\-eNBTargetBranch=(.*)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-eNBTargetBranch=(.*)$', myArgv, re.IGNORECASE)
......@@ -122,12 +126,14 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,EPC,ldpc,CONTAINERS,HELP):
HTML.ranTargetBranch=matchReg.group(1)
ldpc.ranTargetBranch=matchReg.group(1)
CONTAINERS.ranTargetBranch=matchReg.group(1)
SCA.ranTargetBranch=matchReg.group(1)
elif re.match('^\-\-eNBIPAddress=(.+)$|^\-\-eNB[1-2]IPAddress=(.+)$', myArgv, re.IGNORECASE):
if re.match('^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE)
RAN.eNBIPAddress=matchReg.group(1)
ldpc.eNBIpAddr=matchReg.group(1)
CONTAINERS.eNBIPAddress=matchReg.group(1)
SCA.eNBIPAddress=matchReg.group(1)
elif re.match('^\-\-eNB1IPAddress=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-eNB1IPAddress=(.+)$', myArgv, re.IGNORECASE)
RAN.eNB1IPAddress=matchReg.group(1)
......@@ -142,6 +148,7 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,EPC,ldpc,CONTAINERS,HELP):
RAN.eNBUserName=matchReg.group(1)
ldpc.eNBUserName=matchReg.group(1)
CONTAINERS.eNBUserName=matchReg.group(1)
SCA.eNBUserName=matchReg.group(1)
elif re.match('^\-\-eNB1UserName=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-eNB1UserName=(.+)$', myArgv, re.IGNORECASE)
RAN.eNB1UserName=matchReg.group(1)
......@@ -156,6 +163,7 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,EPC,ldpc,CONTAINERS,HELP):
RAN.eNBPassword=matchReg.group(1)
ldpc.eNBPassWord=matchReg.group(1)
CONTAINERS.eNBPassword=matchReg.group(1)
SCA.eNBPassword=matchReg.group(1)
elif re.match('^\-\-eNB1Password=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-eNB1Password=(.+)$', myArgv, re.IGNORECASE)
RAN.eNB1Password=matchReg.group(1)
......@@ -170,6 +178,7 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,EPC,ldpc,CONTAINERS,HELP):
RAN.eNBSourceCodePath=matchReg.group(1)
ldpc.eNBSourceCodePath=matchReg.group(1)
CONTAINERS.eNBSourceCodePath=matchReg.group(1)
SCA.eNBSourceCodePath=matchReg.group(1)
elif re.match('^\-\-eNB1SourceCodePath=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-eNB1SourceCodePath=(.+)$', myArgv, re.IGNORECASE)
RAN.eNB1SourceCodePath=matchReg.group(1)
......
#!/bin/bash
#/*
# * 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
# */
function usage {
echo "OAI RedHat Build Check script"
echo " Original Author: Raphael Defosseux"
echo ""
echo "Usage:"
echo "------"
echo " buildOnRH.sh [OPTIONS]"
echo ""
echo "Options:"
echo "--------"
echo " --job-name #### OR -jn ####"
echo " Specify the name of the Jenkins job."
echo ""
echo " --build-id #### OR -id ####"
echo " Specify the build ID of the Jenkins job."
echo ""
echo " --workspace #### OR -ws ####"
echo " Specify the workspace."
echo ""
echo " --remote-host #### OR -rh ####"
echo " Specify the RedHat remote server."
echo ""
echo " --remote-user-name #### OR -ru ####"
echo " Specify the RedHat remote server username."
echo ""
echo " --remote-password #### OR -rp ####"
echo " Specify the RedHat remote server password."
echo ""
echo " --remote-path #### OR -ra ####"
echo " Specify the RedHat remote server path to work on."
echo ""
}
if [ $# -lt 1 ] || [ $# -gt 14 ]
then
echo "Syntax Error: not the correct number of arguments"
echo ""
usage
exit 1
fi
RH_HOST=XX
RH_USER=XX
RH_PASSWD=XX
RH_PATH=XX
JOB_NAME=XX
BUILD_ID=XX
while [[ $# -gt 0 ]]
do
key="$1"
case $key in
-h|--help)
shift
usage
exit 0
;;
-jn|--job-name)
JOB_NAME="$2"
shift
shift
;;
-id|--build-id)
BUILD_ID="$2"
shift
shift
;;
-ws|--workspace)
JENKINS_WKSP="$2"
shift
shift
;;
-rh|--remote-host)
RH_HOST="$2"
shift
shift
;;
-ru|--remote-user-name)
RH_USER="$2"
shift
shift
;;
-rp|--remote-password)
RH_PASSWD="$2"
shift
shift
;;
-ra|--remote-path)
RH_PATH="$2"
shift
shift
;;
*)
echo "Syntax Error: unknown option: $key"
echo ""
usage
exit 1
esac
done
if [ ! -f $JENKINS_WKSP/localZip.zip ]
then
echo "Missing localZip.zip file!"
exit 1
fi
if [ "$JOB_NAME" == "XX" ] || [ "$BUILD_ID" == "XX" ] || [ "$RH_HOST" == "XX" ] || [ "$RH_USER" == "XX" ] || [ "$RH_PASSWD" == "XX" ] || [ "$RH_PATH" == "XX" ]
then
echo "Missing options"
usage
exit 1
fi
echo "############################################################"
echo "Copying GIT repo into RedHat Server"
echo "############################################################"
echo "rm -Rf ${RH_PATH}" >> rh-cmd.txt
echo "mkdir -p ${RH_PATH}" >> rh-cmd.txt
sshpass -p ${RH_PASSWD} ssh -o 'StrictHostKeyChecking no' ${RH_USER}@${RH_HOST} < rh-cmd.txt
rm -f rh-cmd.txt
echo "############################################################"
echo "Running install and build script on RedHat Server"
echo "############################################################"
sshpass -p ${RH_PASSWD} scp -o 'StrictHostKeyChecking no' $JENKINS_WKSP/localZip.zip ${RH_USER}@${RH_HOST}:${RH_PATH}
echo "cd ${RH_PATH}" > rh-cmd.txt
echo "unzip -qq localZip.zip" >> rh-cmd.txt
echo "source oaienv" >> rh-cmd.txt
echo "cd cmake_targets" >> rh-cmd.txt
echo "mkdir -p log" >> rh-cmd.txt
echo "./build_oai -I -w USRP --eNB > log/install-build.txt 2>&1" >> rh-cmd.txt
sshpass -p ${RH_PASSWD} ssh -o 'StrictHostKeyChecking no' ${RH_USER}@${RH_HOST} < rh-cmd.txt
rm -f rh-cmd.txt
echo "############################################################"
echo "Creating a tmp folder to store results and artifacts"
echo "############################################################"
if [ ! -d $JENKINS_WKSP/archives ]
then
mkdir -p $JENKINS_WKSP/archives
fi
ARCHIVES_LOC=$JENKINS_WKSP/archives/red_hat
if [ ! -d $ARCHIVES_LOC ]
then
mkdir -p $ARCHIVES_LOC
fi
sshpass -p ${RH_PASSWD} scp -o 'StrictHostKeyChecking no' ${RH_USER}@${RH_HOST}:${RH_PATH}/cmake_targets/log/*.txt $ARCHIVES_LOC
echo "############################################################"
echo "Checking build status"
echo "############################################################"
LOG_PATTERN=.Rel15.txt
NB_PATTERN_FILES=7
LOG_FILES=`ls $ARCHIVES_LOC/*.txt`
STATUS=0
NB_FOUND_FILES=0
for FULLFILE in $LOG_FILES
do
if [[ $FULLFILE == *"$LOG_PATTERN"* ]]
then
filename=$(basename -- "$FULLFILE")
PASS_PATTERN=`echo $filename | sed -e "s#$LOG_PATTERN##"`
LOCAL_STAT=`egrep -c "Built target $PASS_PATTERN" $FULLFILE`
if [ $LOCAL_STAT -eq 0 ]; then STATUS=-1; fi
NB_FOUND_FILES=$((NB_FOUND_FILES + 1))
fi
done
if [ $NB_PATTERN_FILES -ne $NB_FOUND_FILES ]
then
echo "Expecting $NB_PATTERN_FILES log files and found $NB_FOUND_FILES"
STATUS=-1
fi
echo "COMMAND: build_oai -I -w USRP --eNB" > $ARCHIVES_LOC/build_final_status.log
if [ $STATUS -eq 0 ]
then
echo "BUILD_OK" >> $ARCHIVES_LOC/build_final_status.log
echo "STATUS seems OK"
else
echo "BUILD_KO" >> $ARCHIVES_LOC/build_final_status.log
echo "STATUS failed?"
fi
exit $STATUS
......@@ -62,7 +62,7 @@ function build_on_vm {
echo "ARCHIVES_LOC = $ARCHIVES_LOC"
echo "BUILD_OPTIONS = $BUILD_OPTIONS"
if [[ "$VM_NAME" == *"-enb-usrp"* ]]
if [[ "$VM_NAME" == *"-enb-usrp"* ]] || [[ "$VM_NAME" == *"-cppcheck"* ]]
then
echo "This VM type is no longer supported in the pipeline framework"
return
......
......@@ -83,6 +83,7 @@ class Containerize():
self.flexranCtrlDeployed = False
self.flexranCtrlIpAddress = ''
self.cli = ''
self.cliBuildOptions = ''
self.dockerfileprefix = ''
self.host = ''
self.allImagesSize = {}
......@@ -124,9 +125,11 @@ class Containerize():
if self.host == 'Ubuntu':
self.cli = 'docker'
self.dockerfileprefix = '.ubuntu18'
self.cliBuildOptions = '--no-cache'
elif self.host == 'Red Hat':
self.cli = 'sudo podman'
self.dockerfileprefix = '.rhel8.2'
self.cliBuildOptions = '--no-cache --disable-compression'
imageNames = []
result = re.search('eNB', self.imageKind)
......@@ -144,6 +147,8 @@ class Containerize():
imageNames.append(('oai-gnb', 'gNB'))
imageNames.append(('oai-lte-ue', 'lteUE'))
imageNames.append(('oai-nr-ue', 'nrUE'))
if self.host == 'Red Hat':
imageNames.append(('oai-physim', 'phySim'))
if len(imageNames) == 0:
imageNames.append(('oai-enb', 'eNB'))
......@@ -201,7 +206,7 @@ class Containerize():
# Build the shared image only on Push Events (not on Merge Requests)
if (not self.ranAllowMerge):
mySSH.command(self.cli + ' build --target ' + sharedimage + ' --tag ' + sharedimage + ':' + sharedTag + ' --file docker/Dockerfile.ran' + self.dockerfileprefix + ' --build-arg NEEDED_GIT_PROXY="http://proxy.eurecom.fr:8080" . > cmake_targets/log/ran-build.log 2>&1', '\$', 1600)
mySSH.command(self.cli + ' build ' + self.cliBuildOptions + ' --target ' + sharedimage + ' --tag ' + sharedimage + ':' + sharedTag + ' --file docker/Dockerfile.ran' + self.dockerfileprefix + ' --build-arg NEEDED_GIT_PROXY="http://proxy.eurecom.fr:8080" . > cmake_targets/log/ran-build.log 2>&1', '\$', 1600)
# First verify if the shared image was properly created.
status = True
mySSH.command(self.cli + ' image inspect --format=\'Size = {{.Size}} bytes\' ' + sharedimage + ':' + sharedTag, '\$', 5)
......@@ -249,7 +254,7 @@ class Containerize():
# the archived Dockerfiles have "ran-build:latest" as base image
# we need to update them with proper tag
mySSH.command('sed -i -e "s#' + sharedimage + ':latest#' + sharedimage + ':' + sharedTag + '#" docker/Dockerfile.' + pattern + self.dockerfileprefix, '\$', 5)
mySSH.command(self.cli + ' build --target ' + image + ' --tag ' + image + ':' + imageTag + ' --file docker/Dockerfile.' + pattern + self.dockerfileprefix + ' . > cmake_targets/log/' + image + '.log 2>&1', '\$', 1200)
mySSH.command(self.cli + ' build ' + self.cliBuildOptions + ' --target ' + image + ' --tag ' + image + ':' + imageTag + ' --file docker/Dockerfile.' + pattern + self.dockerfileprefix + ' . > cmake_targets/log/' + image + '.log 2>&1', '\$', 1200)
# split the log
mySSH.command('mkdir -p cmake_targets/log/' + image, '\$', 5)
mySSH.command('python3 ci-scripts/docker_log_split.py --logfilename=cmake_targets/log/' + image + '.log', '\$', 5)
......
#/*
# * 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
# */
#---------------------------------------------------------------------
# Python for CI of OAI-eNB + COTS-UE
#
# Required Python Version
# Python 3.x
#
# Required Python Package
# pexpect
#---------------------------------------------------------------------
#-----------------------------------------------------------
# Import
#-----------------------------------------------------------
import sys # arg
import re # reg
import logging
import os
import time
#-----------------------------------------------------------
# OAI Testing modules
#-----------------------------------------------------------
import sshconnection as SSH
import helpreadme as HELP
import constants as CONST
#-----------------------------------------------------------
# Class Declaration
#-----------------------------------------------------------
class CppCheckResults():
def __init__(self):
self.variants = ['xenial', 'bionic']
self.versions = ['','']
self.nbErrors = [0,0]
self.nbWarnings = [0,0]
self.nbNullPtrs = [0,0]
self.nbMemLeaks = [0,0]
self.nbUninitVars = [0,0]
self.nbInvalidPrintf = [0,0]
self.nbModuloAlways = [0,0]
self.nbTooManyBitsShift = [0,0]
self.nbIntegerOverflow = [0,0]
self.nbWrongScanfArg = [0,0]
self.nbPtrAddNotNull = [0,0]
self.nbOppoInnerCondition = [0,0]
class StaticCodeAnalysis():
def __init__(self):
self.ranRepository = ''
self.ranBranch = ''
self.ranAllowMerge = False
self.ranCommitID = ''
self.ranTargetBranch = ''
self.eNBIPAddress = ''
self.eNBUserName = ''
self.eNBPassword = ''
self.eNBSourceCodePath = ''
def CppCheckAnalysis(self, HTML):
if self.ranRepository == '' or self.ranBranch == '' or self.ranCommitID == '':
HELP.GenericHelp(CONST.Version)
sys.exit('Insufficient Parameter')
lIpAddr = self.eNBIPAddress
lUserName = self.eNBUserName
lPassWord = self.eNBPassword
lSourcePath = self.eNBSourceCodePath
if lIpAddr == '' or lUserName == '' or lPassWord == '' or lSourcePath == '':
HELP.GenericHelp(CONST.Version)
sys.exit('Insufficient Parameter')
logging.debug('Building on server: ' + lIpAddr)
mySSH = SSH.SSHConnection()
mySSH.open(lIpAddr, lUserName, lPassWord)
self.testCase_id = HTML.testCase_id
# on RedHat/CentOS .git extension is mandatory
result = re.search('([a-zA-Z0-9\:\-\.\/])+\.git', self.ranRepository)
if result is not None:
full_ran_repo_name = self.ranRepository
else:
full_ran_repo_name = self.ranRepository + '.git'
mySSH.command('mkdir -p ' + lSourcePath, '\$', 5)
mySSH.command('cd ' + lSourcePath, '\$', 5)
mySSH.command('if [ ! -e .git ]; then stdbuf -o0 git clone ' + full_ran_repo_name + ' .; else stdbuf -o0 git fetch --prune; fi', '\$', 600)
# Raphael: here add a check if git clone or git fetch went smoothly
mySSH.command('git config user.email "jenkins@openairinterface.org"', '\$', 5)
mySSH.command('git config user.name "OAI Jenkins"', '\$', 5)
mySSH.command('echo ' + lPassWord + ' | sudo -S git clean -x -d -ff', '\$', 30)
mySSH.command('mkdir -p cmake_targets/log', '\$', 5)
# if the commit ID is provided use it to point to it
if self.ranCommitID != '':
mySSH.command('git checkout -f ' + self.ranCommitID, '\$', 5)
mySSH.command('docker image rm oai-cppcheck:bionic oai-cppcheck:xenial || true', '\$', 60)
mySSH.command('docker build --tag oai-cppcheck:xenial --file ci-scripts/docker/Dockerfile.cppcheck.xenial . > cmake_targets/log/cppcheck-xenial.txt 2>&1', '\$', 600)
mySSH.command('sed -e "s@xenial@bionic@" ci-scripts/docker/Dockerfile.cppcheck.xenial > ci-scripts/docker/Dockerfile.cppcheck.bionic', '\$', 6)
mySSH.command('docker build --tag oai-cppcheck:bionic --file ci-scripts/docker/Dockerfile.cppcheck.bionic . > cmake_targets/log/cppcheck-bionic.txt 2>&1', '\$', 600)
mySSH.command('docker image rm oai-cppcheck:bionic oai-cppcheck:xenial || true', '\$', 60)
# Analyzing the logs
mySSH.command('cd ' + lSourcePath + '/cmake_targets', '\$', 5)
mySSH.command('mkdir -p build_log_' + self.testCase_id, '\$', 5)
mySSH.command('mv log/* ' + 'build_log_' + self.testCase_id, '\$', 5)
mySSH.close()
mySSH.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/build_log_' + self.testCase_id + '/*', '.')
CCR = CppCheckResults()
vId = 0
for variant in CCR.variants:
if (os.path.isfile('./cppcheck-'+ variant + '.txt')):
xmlStart = False
with open('./cppcheck-'+ variant + '.txt', 'r') as logfile:
for line in logfile:
ret = re.search('Unpacking cppcheck \((?P<version>[0-9\.]+)', str(line))
if ret is not None:
CCR.versions[vId] = ret.group('version')
if re.search('RUN cat cmake_targets/log/cppcheck.xml', str(line)) is not None:
xmlStart = True
if xmlStart:
if re.search('severity="error"', str(line)) is not None:
CCR.nbErrors[vId] += 1
if re.search('severity="warning"', str(line)) is not None:
CCR.nbWarnings[vId] += 1
if re.search('id="memleak"', str(line)) is not None:
CCR.nbMemLeaks[vId] += 1
if re.search('id="nullPointer"', str(line)) is not None:
CCR.nbNullPtrs[vId] += 1
if re.search('id="uninitvar"', str(line)) is not None:
CCR.nbUninitVars[vId] += 1
if re.search('id="invalidPrintfArgType_sint"|id="invalidPrintfArgType_uint"', str(line)) is not None:
CCR.nbInvalidPrintf[vId] += 1
if re.search('id="moduloAlwaysTrueFalse"', str(line)) is not None:
CCR.nbModuloAlways[vId] += 1
if re.search('id="shiftTooManyBitsSigned"', str(line)) is not None:
CCR.nbTooManyBitsShift[vId] += 1
if re.search('id="integerOverflow"', str(line)) is not None:
CCR.nbIntegerOverflow[vId] += 1
if re.search('id="wrongPrintfScanfArgNum"|id="invalidScanfArgType_int"', str(line)) is not None:
CCR.nbWrongScanfArg[vId] += 1
if re.search('id="pointerAdditionResultNotNull"', str(line)) is not None:
CCR.nbPtrAddNotNull[vId] += 1
if re.search('id="oppositeInnerCondition"', str(line)) is not None:
CCR.nbOppoInnerCondition[vId] += 1
logging.debug('======== Variant ' + variant + ' - ' + CCR.versions[vId] + ' ========')
logging.debug(' ' + str(CCR.nbErrors[vId]) + ' errors')
logging.debug(' ' + str(CCR.nbWarnings[vId]) + ' warnings')
logging.debug(' -- Details --')
logging.debug(' Memory leak: ' + str(CCR.nbMemLeaks[vId]))
logging.debug(' Possible null pointer deference: ' + str(CCR.nbNullPtrs[vId]))
logging.debug(' Uninitialized variable: ' + str(CCR.nbUninitVars[vId]))
logging.debug(' Undefined behaviour shifting: ' + str(CCR.nbTooManyBitsShift[vId]))
logging.debug(' Signed integer overflow: ' + str(CCR.nbIntegerOverflow[vId]))
logging.debug('')
logging.debug(' Printf formatting issue: ' + str(CCR.nbInvalidPrintf[vId]))
logging.debug(' Modulo result is predetermined: ' + str(CCR.nbModuloAlways[vId]))
logging.debug(' Opposite Condition -> dead code: ' + str(CCR.nbOppoInnerCondition[vId]))
logging.debug(' Wrong Scanf Nb Args: ' + str(CCR.nbWrongScanfArg[vId]))
logging.debug('')
vId += 1
HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
HTML.CreateHtmlTestRowCppCheckResults(CCR)
logging.info('\u001B[1m Static Code Analysis Pass\u001B[0m')
return 0
......@@ -23,6 +23,7 @@ gNBs =
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
pusch_AntennaPorts = 1;
pusch_TargetSNRx10 = 200;
pucch_TargetSNRx10 = 200;
......
......@@ -23,6 +23,7 @@ gNBs =
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
pusch_AntennaPorts = 1;
servingCellConfigCommon = (
{
......@@ -170,7 +171,7 @@ gNBs =
nrofUplinkSlots = 2;
nrofUplinkSymbols = 4;
ssPBCH_BlockPower = 10;
ssPBCH_BlockPower = -25;
}
);
......
......@@ -170,7 +170,7 @@ gNBs =
nrofUplinkSlots = 2;
nrofUplinkSymbols = 4;
ssPBCH_BlockPower = 10;
ssPBCH_BlockPower = -25;
}
);
......
......@@ -22,6 +22,7 @@ gNBs =
ssb_SubcarrierOffset = 31; //0;
pdsch_AntennaPorts = 1;
pusch_AntennaPorts = 1;
pusch_TargetSNRx10 = 200;
pucch_TargetSNRx10 = 200;
......@@ -234,7 +235,7 @@ L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
pusch_proc_threads = 8;
pusch_proc_threads = 6;
}
);
......
......@@ -87,7 +87,7 @@ function create_vm {
echo "VM_CPU = $VM_CPU"
echo "VM_DISK = $VM_DISK GBytes"
if [[ "$VM_NAME" == *"-enb-usrp"* ]]
if [[ "$VM_NAME" == *"-enb-usrp"* ]] || [[ "$VM_NAME" == *"-cppcheck"* ]]
then
echo "This VM type is no longer supported in the pipeline framework"
return
......
FROM ubuntu:xenial AS oai-cppcheck
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get upgrade --yes && \
DEBIAN_FRONTEND=noninteractive apt-get install --yes \
build-essential \
vim \
cppcheck
WORKDIR /oai-ran
COPY . .
WORKDIR /oai-ran/common/utils/T
RUN make
WORKDIR /oai-ran
RUN mkdir -p cmake_targets/log && \
cppcheck --enable=warning --force --xml --xml-version=2 \
-i openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c \
--suppressions-list=ci-scripts/cppcheck_suppressions.list \
-I common/utils \
-I openair3/NAS/COMMON/UTIL \
-j`nproc` . 2> cmake_targets/log/cppcheck.xml 1> cmake_targets/log/cppcheck_build.txt
RUN egrep -c 'severity="error' cmake_targets/log/cppcheck.xml
RUN egrep -c 'severity="warning' cmake_targets/log/cppcheck.xml
RUN cat cmake_targets/log/cppcheck.xml
......@@ -479,3 +479,88 @@ class HTMLManagement():
self.htmlFile.write(' </tr>\n')
self.htmlFile.close()
def CreateHtmlTestRowCppCheckResults(self, CCR):
if (self.htmlFooterCreated or (not self.htmlHeaderCreated)):
return
self.htmlFile = open('test_results.html', 'a')
vId = 0
for version in CCR.versions:
self.htmlFile.write(' <tr bgcolor = "#F0F0F0" >\n')
self.htmlFile.write(' <td colspan=' + str(5+self.htmlUEConnected) + '><b> Results for cppcheck v ' + version + ' </b></td>\n')
self.htmlFile.write(' </tr>\n')
self.htmlFile.write(' <tr>\n')
self.htmlFile.write(' <td></td>\n')
self.htmlFile.write(' <td colspan=2 bgcolor = "lightcyan" ><b> NB ERRORS</b></td>\n')
if CCR.nbErrors[vId] == 0:
myColor = 'lightgreen'
elif CCR.nbErrors[vId] < 20:
myColor = 'orange'
else:
myColor = 'lightcoral'
self.htmlFile.write(' <td colspan=' + str(2+self.htmlUEConnected) + ' bgcolor = "' + myColor + '"><b>' + str(CCR.nbErrors[vId]) + '</b></td>\n')
self.htmlFile.write(' </tr>\n')
self.htmlFile.write(' <tr>\n')
self.htmlFile.write(' <td></td>\n')
self.htmlFile.write(' <td colspan=2 bgcolor = "lightcyan" ><b> NB WARNINGS</b></td>\n')
if CCR.nbWarnings[vId] == 0:
myColor = 'lightgreen'
elif CCR.nbWarnings[vId] < 20:
myColor = 'orange'
else:
myColor = 'lightcoral'
self.htmlFile.write(' <td colspan=' + str(2+self.htmlUEConnected) + ' bgcolor = "' + myColor + '"><b>' + str(CCR.nbWarnings[vId]) + '</b></td>\n')
self.htmlFile.write(' </tr>\n')
self.htmlFile.write(' <tr bgcolor = "#F0F0F0" >\n')
self.htmlFile.write(' <td colspan=' + str(5+self.htmlUEConnected) + '> ----------------- </td>\n')
self.htmlFile.write(' </tr>\n')
self.htmlFile.write(' <tr>\n')
self.htmlFile.write(' <td></td>\n')
self.htmlFile.write(' <td colspan=2 bgcolor = "lightcyan" ><b> Memory leak</b></td>\n')
self.htmlFile.write(' <td colspan=' + str(2+self.htmlUEConnected) + '>' + str(CCR.nbMemLeaks[vId]) + '</td>\n')
self.htmlFile.write(' </tr>\n')
self.htmlFile.write(' <tr>\n')
self.htmlFile.write(' <td></td>\n')
self.htmlFile.write(' <td colspan=2 bgcolor = "lightcyan" ><b> Possible null pointer deference</b></td>\n')
self.htmlFile.write(' <td colspan=' + str(2+self.htmlUEConnected) + '>' + str(CCR.nbNullPtrs[vId]) + '</td>\n')
self.htmlFile.write(' </tr>\n')
self.htmlFile.write(' <tr>\n')
self.htmlFile.write(' <td></td>\n')
self.htmlFile.write(' <td colspan=2 bgcolor = "lightcyan" ><b> Uninitialized variable</b></td>\n')
self.htmlFile.write(' <td colspan=' + str(2+self.htmlUEConnected) + '>' + str(CCR.nbUninitVars[vId]) + '</td>\n')
self.htmlFile.write(' </tr>\n')
self.htmlFile.write(' <tr>\n')
self.htmlFile.write(' <td></td>\n')
self.htmlFile.write(' <td colspan=2 bgcolor = "lightcyan" ><b> Undefined behaviour shifting</b></td>\n')
self.htmlFile.write(' <td colspan=' + str(2+self.htmlUEConnected) + '>' + str(CCR.nbTooManyBitsShift[vId]) + '</td>\n')
self.htmlFile.write(' </tr>\n')
self.htmlFile.write(' <tr>\n')
self.htmlFile.write(' <td></td>\n')
self.htmlFile.write(' <td colspan=2 bgcolor = "lightcyan" ><b> Signed integer overflow</b></td>\n')
self.htmlFile.write(' <td colspan=' + str(2+self.htmlUEConnected) + '>' + str(CCR.nbIntegerOverflow[vId]) + '</td>\n')
self.htmlFile.write(' </tr>\n')
self.htmlFile.write(' <tr bgcolor = "#F0F0F0" >\n')
self.htmlFile.write(' <td colspan=' + str(5+self.htmlUEConnected) + '> </td>\n')
self.htmlFile.write(' </tr>\n')
self.htmlFile.write(' <tr>\n')
self.htmlFile.write(' <td></td>\n')
self.htmlFile.write(' <td colspan=2 bgcolor = "lightcyan" ><b> Printf formatting issues</b></td>\n')
self.htmlFile.write(' <td colspan=' + str(2+self.htmlUEConnected) + '>' + str(CCR.nbInvalidPrintf[vId]) + '</td>\n')
self.htmlFile.write(' </tr>\n')
self.htmlFile.write(' <tr>\n')
self.htmlFile.write(' <td></td>\n')
self.htmlFile.write(' <td colspan=2 bgcolor = "lightcyan" ><b> Modulo result is predetermined</b></td>\n')
self.htmlFile.write(' <td colspan=' + str(2+self.htmlUEConnected) + '>' + str(CCR.nbModuloAlways[vId]) + '</td>\n')
self.htmlFile.write(' </tr>\n')
self.htmlFile.write(' <tr>\n')
self.htmlFile.write(' <td></td>\n')
self.htmlFile.write(' <td colspan=2 bgcolor = "lightcyan" ><b> Opposite Condition -> dead code</b></td>\n')
self.htmlFile.write(' <td colspan=' + str(2+self.htmlUEConnected) + '>' + str(CCR.nbOppoInnerCondition[vId]) + '</td>\n')
self.htmlFile.write(' </tr>\n')
self.htmlFile.write(' <tr>\n')
self.htmlFile.write(' <td></td>\n')
self.htmlFile.write(' <td colspan=2 bgcolor = "lightcyan" ><b> Wrong Scanf Nb Args</b></td>\n')
self.htmlFile.write(' <td colspan=' + str(2+self.htmlUEConnected) + '>' + str(CCR.nbWrongScanfArg[vId]) + '</td>\n')
self.htmlFile.write(' </tr>\n')
vId += 1
self.htmlFile.close()
......@@ -38,10 +38,11 @@ import helpreadme as HELP
import constants as CONST
import cls_oaicitest #main class for OAI CI test framework
import cls_physim #class PhySim for physical simulators build and test
import cls_cots_ue #class CotsUe for Airplane mode control
import cls_containerize #class Containerize for all container-based operations on RAN/UE objects
import cls_oaicitest #main class for OAI CI test framework
import cls_physim #class PhySim for physical simulators build and test
import cls_cots_ue #class CotsUe for Airplane mode control
import cls_containerize #class Containerize for all container-based operations on RAN/UE objects
import cls_static_code_analysis #class for static code analysis
import sshconnection
......@@ -378,6 +379,7 @@ EPC = epc.EPCManagement()
RAN = ran.RANManagement()
HTML = html.HTMLManagement()
CONTAINERS = cls_containerize.Containerize()
SCA = cls_static_code_analysis.StaticCodeAnalysis()
ldpc=cls_physim.PhySim() #create an instance for LDPC test using GPU or CPU build
......@@ -388,7 +390,7 @@ ldpc=cls_physim.PhySim() #create an instance for LDPC test using GPU or CPU b
#-----------------------------------------------------------
import args_parse
py_param_file_present, py_params, mode = args_parse.ArgsParse(sys.argv,CiTestObj,RAN,HTML,EPC,ldpc,CONTAINERS,HELP)
py_param_file_present, py_params, mode = args_parse.ArgsParse(sys.argv,CiTestObj,RAN,HTML,EPC,ldpc,CONTAINERS,HELP,SCA)
......@@ -741,6 +743,8 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re
CONTAINERS.DeployObject(HTML, EPC)
elif action == 'Undeploy_Object':
CONTAINERS.UndeployObject(HTML, RAN)
elif action == 'Cppcheck_Analysis':
SCA.CppCheckAnalysis(HTML)
else:
sys.exit('Invalid class (action) from xml')
if not RAN.prematureExit:
......
......@@ -568,17 +568,20 @@ function report_build {
echo " <h2>Ubuntu 16.04 LTS -- Summary</h2>" >> ./build_results.html
sca_summary_table_header ./archives/cppcheck/cppcheck.xml "OAI Static Code Analysis with CPPCHECK"
sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Uninitialized variable" uninitvar
sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Uninitialized struct member" uninitStructMember
sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Memory leak" memleak
sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Memory is freed twice" doubleFree
sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Resource leak" resourceLeak
sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Possible null pointer dereference" nullPointer
sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Array access out of bounds" arrayIndexOutOfBounds
sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Buffer is accessed out of bounds" bufferAccessOutOfBounds
sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Expression depends on order of evaluation of side effects" unknownEvaluationOrder
sca_summary_table_footer ./archives/cppcheck/cppcheck.xml
if [ -f ./archives/cppcheck/cppcheck.xml ]
then
sca_summary_table_header ./archives/cppcheck/cppcheck.xml "OAI Static Code Analysis with CPPCHECK"
sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Uninitialized variable" uninitvar
sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Uninitialized struct member" uninitStructMember
sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Memory leak" memleak
sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Memory is freed twice" doubleFree
sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Resource leak" resourceLeak
sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Possible null pointer dereference" nullPointer
sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Array access out of bounds" arrayIndexOutOfBounds
sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Buffer is accessed out of bounds" bufferAccessOutOfBounds
sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Expression depends on order of evaluation of side effects" unknownEvaluationOrder
sca_summary_table_footer ./archives/cppcheck/cppcheck.xml
fi
# summary_table_header "OAI Build: 4G LTE eNB -- USRP option" ./archives/enb_usrp
# summary_table_row "LTE SoftModem - Release 15" ./archives/enb_usrp/lte-softmodem.Rel15.txt "Built target lte-softmodem" ./enb_usrp_row1.html
......
......@@ -47,7 +47,7 @@ function wait_on_vm_build {
echo "ARCHIVES_LOC = $ARCHIVES_LOC"
echo "BUILD_OPTIONS = $BUILD_OPTIONS"
if [[ "$VM_NAME" == *"-enb-usrp"* ]]
if [[ "$VM_NAME" == *"-enb-usrp"* ]] || [[ "$VM_NAME" == *"-cppcheck"* ]]
then
echo "This VM type is no longer supported in the pipeline framework"
return
......@@ -73,6 +73,9 @@ function wait_on_vm_build {
echo "############################################################"
echo "Waiting build process to end on VM ($VM_NAME)"
echo "############################################################"
# Since the last VM was cppcheck and is removed
# we are going too fast in wait and the build_oai is not yet started
sleep 120
if [[ "$VM_NAME" == *"-cppcheck"* ]]
then
......@@ -90,7 +93,7 @@ function wait_on_vm_build {
}
function check_on_vm_build {
if [[ "$VM_NAME" == *"-enb-usrp"* ]]
if [[ "$VM_NAME" == *"-enb-usrp"* ]] || [[ "$VM_NAME" == *"-cppcheck"* ]]
then
echo "This VM type is no longer supported in the pipeline framework"
return
......
......@@ -37,3 +37,4 @@
- Build_Image
- Deploy_Object
- Undeploy_Object
- Cppcheck_Analysis
<!--
Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The OpenAirInterface Software Alliance licenses this file to You under
the OAI Public License, Version 1.1 (the "License"); you may not use this file
except in compliance with the License.
You may obtain a copy of the License at
http://www.openairinterface.org/?page_id=698
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
For more information about the OpenAirInterface (OAI) Software Alliance:
contact@openairinterface.org
-->
<testCaseList>
<htmlTabRef>build-tab</htmlTabRef>
<htmlTabName>CPPCHECK Analysis</htmlTabName>
<htmlTabIcon>wrench</htmlTabIcon>
<TestCaseRequestedList>
000001
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="000001">
<class>Cppcheck_Analysis</class>
<desc>Static Code Analysis with cppcheck</desc>
</testCase>
</testCaseList>
......@@ -333,6 +333,11 @@ else (CUDA_FOUND)
)
endif ()
if (SANITIZE_ADDRESS)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address")
endif ()
add_definitions("-DASN_DISABLE_OER_SUPPORT")
#########################
......@@ -1973,6 +1978,7 @@ set(NR_PDCP_SRC
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_sdu.c
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_timer_thread.c
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_security_nea2.c
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_integrity_nia2.c
${OPENAIR2_DIR}/LAYER2/nr_pdcp/asn1_utils.c
)
......@@ -3323,7 +3329,7 @@ add_executable(nr_dlsim
)
target_link_libraries(nr_dlsim
-Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_LTE_NR L2_NR HASHTABLE X2AP_ENB X2AP_LIB SECU_CN NGAP_GNB -Wl,--end-group
m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl
m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} ${OPENSSL_LIBRARIES} dl
)
target_compile_definitions(nr_dlsim PUBLIC -DPHYSICAL_SIMULATOR)
......@@ -3342,7 +3348,7 @@ add_executable(nr_prachsim
${SHLIB_LOADER_SOURCES})
target_link_libraries(nr_prachsim
-Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_RU PHY_NR_UE MAC_NR_COMMON SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_LTE_NR L2_NR HASHTABLE X2AP_ENB X2AP_LIB SECU_CN NGAP_GNB -Wl,--end-group
m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl)
m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} ${OPENSSL_LIBRARIES} dl)
add_executable(nr_ulschsim
${OPENAIR1_DIR}/SIMULATION/NR_PHY/ulschsim.c
......@@ -3375,7 +3381,7 @@ add_executable(nr_ulsim
)
target_link_libraries(nr_ulsim
-Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_LTE_NR L2_NR HASHTABLE X2AP_ENB X2AP_LIB SECU_CN NGAP_GNB -Wl,--end-group
m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl
m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} ${OPENSSL_LIBRARIES} dl
)
target_compile_definitions(nr_ulsim PUBLIC -DPHYSICAL_SIMULATOR)
......
......@@ -1330,7 +1330,8 @@
(Test3: 30kHz SCS, 273 PRBs, Prach format A2),
(Test4: 30kHz SCS, 106 PRBs, Prach format 0),
(Test5: 120kHz SCS, 32 PRBs, Prach format A2),
(Test6: 120kHz SCS, 66 PRBs, Prach format A2)</desc>
(Test6: 120kHz SCS, 66 PRBs, Prach format A2),
(Test7: 120kHz SCS, 66 PRBs, High Speed Enabled)</desc>
<pre_compile_prog></pre_compile_prog>
<compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</compile_prog>
<compile_prog_args> --phy_simulators -c </compile_prog_args>
......@@ -1342,8 +1343,9 @@
-a -s -30 -n 100 -p 63 -R 273
-a -s -30 -n 100 -p 63 -R 106 -c 4
-a -s -30 -n 100 -p 32 -R 32 -m 3 -c52
-a -s -30 -n 100 -p 32 -R 66 -m 3 -c52</main_exec_args>
<tags>nr_prachsim.test1 nr_prachsim.test2 nr_prachsim.test3 nr_prachsim.test4 nr_prachsim.test5 nr_prachsim.test6</tags>
-a -s -30 -n 100 -p 32 -R 66 -m 3 -c52
-a -s -30 -n 100 -R 66 -m 3 -c52 -H</main_exec_args>
<tags>nr_prachsim.test1 nr_prachsim.test2 nr_prachsim.test3 nr_prachsim.test4 nr_prachsim.test5 nr_prachsim.test6 nr_prachsim.test7</tags>
<search_expr_true>PRACH test OK</search_expr_true>
<search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false>
<nruns>3</nruns>
......
......@@ -68,6 +68,7 @@ USRP_REC_PLAY="False"
BUILD_ECLIPSE=0
NR="False"
ITTI_SIM="False"
SANITIZE_ADDRESS="False"
OPTIONAL_LIBRARIES="telnetsrv enbscope uescope nrscope msc"
trap handle_ctrl_c INT
......@@ -424,6 +425,9 @@ function main() {
CMAKE_CMD="$CMAKE_CMD -GNinja"
MAKE_CMD=ninja
shift;;
--sanitize-address | -fsanitize=address)
SANITIZE_ADDRESS=True
shift;;
--ittiSIM)
ittiSIM=1
ITTI_SIM="True"
......@@ -612,6 +616,7 @@ function main() {
echo "set ( USRP_REC_PLAY $USRP_REC_PLAY )" >> $cmake_file
echo "set ( SKIP_SHARED_LIB_FLAG $SKIP_SHARED_LIB_FLAG )" >> $cmake_file
echo "set ( ITTI_SIM $ITTI_SIM )" >> $cmake_file
echo "set ( SANITIZE_ADDRESS $SANITIZE_ADDRESS )" >> $cmake_file
echo 'include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)' >> $cmake_file
cd $DIR/$build_dir/build
eval $CMAKE_CMD
......
......@@ -44,10 +44,11 @@ Our code might not work with all 5G phones yet, but we are constantly improving
* Oppo Reno 5G
* Samsung A90 5G
* Google Pixel 5G
* Google Pixel 5G (note1)
* Simcom SIMCOM8200EA
* Quectel RM500Q-GL
Note1: In the version we have at Eurecom, you need to set the PLMN to 50501, and you also need to change the firmware to "11.0.0 (RD1A.201105.003.B1, Nov 2020, EU carriers)" (see https://developers.google.com/android/images)
## Repository
......
#/*
# * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
# * contributor license agreements. See the NOTICE file distributed with
# * this work for additional information regarding copyright ownership.
# * The OpenAirInterface Software Alliance licenses this file to You under
# * the OAI Public License, Version 1.1 (the "License"); you may not use this file
# * except in compliance with the License.
# * You may obtain a copy of the License at
# *
# * http://www.openairinterface.org/?page_id=698
# *
# * Unless required by applicable law or agreed to in writing, software
# * distributed under the License is distributed on an "AS IS" BASIS,
# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# * See the License for the specific language governing permissions and
# * limitations under the License.
# *-------------------------------------------------------------------------------
# * For more information about the OpenAirInterface (OAI) Software Alliance:
# * contact@openairinterface.org
# */
#---------------------------------------------------------------------
#
# Dockerfile for the Open-Air-Interface BUILD service
# Valid for RHEL8
#
#---------------------------------------------------------------------
FROM localhost/ran-build:develop AS phy-sim-build
RUN rm -Rf /oai-ran
WORKDIR /oai-ran
COPY . .
#run build_oai to build the target image
RUN /bin/sh oaienv && \
cd cmake_targets && \
mkdir -p log && \
./build_oai --phy_simulators --ninja --verbose-ci
#start from scratch for target executable
FROM registry.access.redhat.com/ubi8/ubi:latest as oai-physim
RUN yum update -y && \
yum install -y --enablerepo="ubi-8-codeready-builder" \
lksctp-tools \
nettle \
atlas \
hostname \
sudo \
procps-ng \
net-tools \
iputils \
bc \
iproute \
libyaml && \
echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf && \
echo "/usr/local/lib64" >> /etc/ld.so.conf.d/local-lib.conf
WORKDIR /opt/oai-physim/targets/bin
COPY --from=phy-sim-build /oai-ran/targets/bin/dlsim.Rel15 .
COPY --from=phy-sim-build /oai-ran/targets/bin/nr_dlsim.Rel15 .
COPY --from=phy-sim-build /oai-ran/targets/bin/nr_prachsim.Rel15 .
COPY --from=phy-sim-build /oai-ran/targets/bin/nr_ulschsim.Rel15 .
COPY --from=phy-sim-build /oai-ran/targets/bin/polartest.Rel15 .
COPY --from=phy-sim-build /oai-ran/targets/bin/ulsim.Rel15 .
COPY --from=phy-sim-build /oai-ran/targets/bin/ldpctest.Rel15 .
COPY --from=phy-sim-build /oai-ran/targets/bin/nr_dlschsim.Rel15 .
COPY --from=phy-sim-build /oai-ran/targets/bin/nr_pbchsim.Rel15 .
COPY --from=phy-sim-build /oai-ran/targets/bin/nr_pucchsim.Rel15 .
COPY --from=phy-sim-build /oai-ran/targets/bin/nr_ulsim.Rel15 .
COPY --from=phy-sim-build /oai-ran/targets/bin/smallblocktest.Rel15 .
WORKDIR /usr/local/lib/
COPY --from=phy-sim-build /oai-ran/targets/bin/libcoding.so .
COPY --from=phy-sim-build /lib64/liblapacke.so.3 .
COPY --from=phy-sim-build /lib64/libX11.so.6 .
COPY --from=phy-sim-build /lib64/libXpm.so.4 .
COPY --from=phy-sim-build /lib64/libxcb.so.1 .
COPY --from=phy-sim-build /lib64/libXau.so.6 .
COPY --from=phy-sim-build /lib64/libforms.so.2 .
COPY --from=phy-sim-build /lib64/libblas.so.3 .
COPY --from=phy-sim-build /lib64/liblapack.so.3 .
COPY --from=phy-sim-build /lib64/libexslt.so.0 .
COPY --from=phy-sim-build /lib64/libxslt.so.1 .
COPY --from=phy-sim-build /oai-ran/cmake_targets/phy_simulators/build/libdfts.so .
COPY --from=phy-sim-build /oai-ran/cmake_targets/phy_simulators/build/libSIMU.so .
COPY --from=phy-sim-build /oai-ran/cmake_targets/phy_simulators/build/libldpc.so .
COPY --from=phy-sim-build /oai-ran/cmake_targets/phy_simulators/build/libldpc_orig.so .
RUN ldconfig
#debug
#RUN ldd /opt/oai-physim/targets/bin/dlsim.Rel15
#RUN ldd /opt/oai-physim/targets/bin/nr_dlsim.Rel15
#RUN ldd /opt/oai-physim/targets/bin/nr_prachsim.Rel15
#RUN ldd /opt/oai-physim/targets/bin/nr_ulschsim.Rel15
#RUN ldd /opt/oai-physim/targets/bin/polartest.Rel15
#RUN ldd /opt/oai-physim/targets/bin/ulsim.Rel15
#RUN ldd /opt/oai-physim/targets/bin/ldpctest.Rel15
#RUN ldd /opt/oai-physim/targets/bin/nr_dlschsim.Rel15
#RUN ldd /opt/oai-physim/targets/bin/nr_pbchsim.Rel15
#RUN ldd /opt/oai-physim/targets/bin/nr_pucchsim.Rel15
#RUN ldd /opt/oai-physim/targets/bin/nr_ulsim.Rel15
#RUN ldd /opt/oai-physim/targets/bin/smallblocktest.Rel15
# Copy some executables
WORKDIR /usr/bin/
COPY --from=phy-sim-build /usr/bin/killall .
COPY --from=phy-sim-build /usr/bin/xmlstarlet .
COPY --from=phy-sim-build /usr/bin/svn .
# Copy the relevant configuration files for phySim
WORKDIR /opt/oai-physim/
COPY --from=phy-sim-build /oai-ran/cmake_targets/autotests/run_exec_autotests.bash /opt/oai-physim/cmake_targets/autotests/
COPY --from=phy-sim-build /oai-ran/cmake_targets/autotests/test_case_list.xml /opt/oai-physim/cmake_targets/autotests/
COPY --from=phy-sim-build /oai-ran/cmake_targets/autotests/tools/free_mem.bash /opt/oai-physim/cmake_targets/autotests/tools/
COPY --from=phy-sim-build /oai-ran/cmake_targets/tools/build_helper /opt/oai-physim/cmake_targets/tools/
COPY --from=phy-sim-build /oai-ran/cmake_targets/tools/test_helper /opt/oai-physim/cmake_targets/tools/
#CMD ["sleep", "infinity"]
......@@ -468,15 +468,14 @@ void init_gNB(int single_thread_flag,int wait_for_sync) {
PHY_VARS_gNB *gNB;
if (RC.gNB == NULL) {
RC.gNB = (PHY_VARS_gNB **) malloc((1+RC.nb_nr_L1_inst)*sizeof(PHY_VARS_gNB *));
RC.gNB = (PHY_VARS_gNB **) calloc(1+RC.nb_nr_L1_inst, sizeof(PHY_VARS_gNB *));
LOG_I(PHY,"gNB L1 structure RC.gNB allocated @ %p\n",RC.gNB);
}
for (inst=0; inst<RC.nb_nr_L1_inst; inst++) {
if (RC.gNB[inst] == NULL) {
RC.gNB[inst] = (PHY_VARS_gNB *) malloc(sizeof(PHY_VARS_gNB));
memset((void*)RC.gNB[inst],0,sizeof(PHY_VARS_gNB));
RC.gNB[inst] = (PHY_VARS_gNB *) calloc(1, sizeof(PHY_VARS_gNB));
LOG_I(PHY,"[nr-gnb.c] gNB structure RC.gNB[%d] allocated @ %p\n",inst,RC.gNB[inst]);
}
gNB = RC.gNB[inst];
......
......@@ -332,6 +332,14 @@ void processSlotRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
protocol_ctxt_t ctxt;
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, UE->Mod_id, ENB_FLAG_NO, mac->crnti, proc->frame_rx, proc->nr_slot_rx, 0);
pdcp_run(&ctxt);
/* send tick to RLC and PDCP every ms */
if (proc->nr_slot_rx % UE->frame_parms.slots_per_subframe == 0) {
void nr_rlc_tick(int frame, int subframe);
void nr_pdcp_tick(int frame, int subframe);
nr_rlc_tick(proc->frame_rx, proc->nr_slot_rx / UE->frame_parms.slots_per_subframe);
nr_pdcp_tick(proc->frame_rx, proc->nr_slot_rx / UE->frame_parms.slots_per_subframe);
}
}
}
......
......@@ -972,7 +972,7 @@ typedef struct
typedef struct
{
uint32_t ss_pbch_power;//SSB Block Power Value: TBD (-60..50 dBm)
int ss_pbch_power;//SSB Block Power Value: TBD (-60..50 dBm)
uint8_t bch_payload;//Defines option selected for generation of BCH payload, see Table 3-13 (v0.0.011 Value: 0: MAC generates the full PBCH payload 1: PHY generates the timing PBCH bits 2: PHY generates the full PBCH payload
uint8_t scs_common;//subcarrierSpacing for common, used for initial access and broadcast message. [38.211 sec 4.2] Value:0->3
......
......@@ -357,7 +357,7 @@ typedef struct
//table 3-23
typedef struct
{
nfapi_uint32_tlv_t ss_pbch_power;//SSB Block Power Value: TBD (-60..50 dBm)
nfapi_int32_tlv_t ss_pbch_power;//SSB Block Power Value: TBD (-60..50 dBm)
nfapi_uint8_tlv_t bch_payload;//Defines option selected for generation of BCH payload, see Table 3-13 (v0.0.011 Value: 0: MAC generates the full PBCH payload 1: PHY generates the timing PBCH bits 2: PHY generates the full PBCH payload
nfapi_uint8_tlv_t scs_common;//subcarrierSpacing for common, used for initial access and broadcast message. [38.211 sec 4.2] Value:0->3
......
......@@ -27,12 +27,9 @@
uint32_t nr_subcarrier_spacing[MAX_NUM_SUBCARRIER_SPACING] = {15e3, 30e3, 60e3, 120e3, 240e3};
uint16_t nr_slots_per_subframe[MAX_NUM_SUBCARRIER_SPACING] = {1, 2, 4, 8, 16};
int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp)
{
int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp,uint8_t i_ssb) {
int mu = fp->numerology_index;
uint8_t half_frame_index = fp->half_frame_bit;
uint8_t i_ssb = fp->ssb_index;
int symbol = 0;
uint8_t n, n_temp;
nr_ssb_type_e type = fp->ssb_type;
......@@ -69,9 +66,6 @@ int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp)
AssertFatal(0==1, "Invalid numerology index %d for the synchronization block\n", mu);
}
if (half_frame_index)
symbol += (5 * fp->symbols_per_slot * fp->slots_per_subframe);
return symbol;
}
......
......@@ -392,7 +392,7 @@ void phy_config_update_sib13_request(PHY_Config_t *phy_config);
int init_frame_parms(LTE_DL_FRAME_PARMS *frame_parms,uint8_t osf);
void dump_frame_parms(LTE_DL_FRAME_PARMS *frame_parms);
int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp);
int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp,uint8_t i_ssb);
int nr_init_frame_parms(nfapi_nr_config_request_scf_t *config, NR_DL_FRAME_PARMS *frame_parms);
int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *frame_parms, fapi_nr_config_request_t *config, uint16_t nr_band);
int init_nr_ue_signal(PHY_VARS_NR_UE *ue,int nb_connected_eNB,uint8_t abstraction_flag);
......
......@@ -20,12 +20,12 @@
*/
/*! \file PHY/NR_ESTIMATION/nr_measurements_gNB.c
* \brief TA estimation for TA updates
* \author Ahmed Hussein
* \brief gNB measurement routines
* \author Ahmed Hussein, G. Casati, K. Saaifan
* \date 2019
* \version 0.1
* \company Fraunhofer IIS
* \email: ahmed.hussein@iis.fraunhofer.de
* \email: ahmed.hussein@iis.fraunhofer.de, guido.casati@iis.fraunhofer.de, khodr.saaifan@iis.fraunhofer.de
* \note
* \warning
*/
......@@ -35,6 +35,8 @@
#include "PHY/phy_extern.h"
#include "nr_ul_estimation.h"
extern openair0_config_t openair0_cfg[MAX_CARDS];
int nr_est_timing_advance_pusch(PHY_VARS_gNB* gNB, int UE_id)
{
int i, aa, max_pos = 0, max_val = 0;
......@@ -73,14 +75,17 @@ void gNB_I0_measurements(PHY_VARS_gNB *gNB) {
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
NR_gNB_COMMON *common_vars = &gNB->common_vars;
PHY_MEASUREMENTS_gNB *measurements = &gNB->measurements;
NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
double rx_gain = openair0_cfg[0].rx_gain[0];
double rx_gain_offset = openair0_cfg[0].rx_gain_offset[0];
uint32_t *rb_mask = gNB->rb_mask_ul;
int symbol = gNB->ulmask_symb;
int rb, offset, nb_rb;
uint32_t n0_power_tot, n0_subband_power_temp=0;
uint32_t n0_subband_power_temp = 0;
int32_t *ul_ch;
if (symbol>-1) {
n0_power_tot = 0;
measurements->n0_power_tot = 0;
for (int aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
nb_rb = 0;
for (rb=0; rb<frame_parms->N_RB_UL; rb++) {
......@@ -93,11 +98,76 @@ void gNB_I0_measurements(PHY_VARS_gNB *gNB) {
n0_subband_power_temp += signal_energy_nodc(ul_ch,12);
}
}
measurements->n0_power[aarx] = n0_subband_power_temp/nb_rb;
measurements->n0_power_dB[aarx] = dB_fixed(measurements->n0_power[aarx]);
n0_power_tot += measurements->n0_power[aarx];
if (nb_rb != 0) {
measurements->n0_power[aarx] = n0_subband_power_temp/nb_rb;
measurements->n0_power_dB[aarx] = dB_fixed(measurements->n0_power[aarx]);
measurements->n0_power_tot += measurements->n0_power[aarx];
}
}
measurements->n0_power_tot_dB = dB_fixed(n0_power_tot);
measurements->n0_power_tot_dB = dB_fixed(measurements->n0_power_tot);
measurements->n0_power_tot_dBm = measurements->n0_power_tot_dB + 30 - 10 * log10(pow(2, 30)) - (rx_gain - rx_gain_offset) - dB_fixed(fp->ofdm_symbol_size);
LOG_D(PHY, "In %s: tot n0 power %d dBm for %d RBs (tot N0 power = %d)\n", __FUNCTION__, measurements->n0_power_tot_dBm, nb_rb, measurements->n0_power_tot);
}
}
// Scope: This function computes the UL SNR from the UL channel estimates
//
// Todo:
// - averaging IIR filter for RX power and noise
void nr_gnb_measurements(PHY_VARS_gNB *gNB, uint8_t ulsch_id, unsigned char harq_pid, unsigned char symbol){
int rx_power_tot[NUMBER_OF_NR_ULSCH_MAX];
int rx_power[NUMBER_OF_NR_ULSCH_MAX][NB_ANTENNAS_RX];
unsigned short rx_power_avg_dB[NUMBER_OF_NR_ULSCH_MAX];
unsigned short rx_power_tot_dB[NUMBER_OF_NR_ULSCH_MAX];
double rx_gain = openair0_cfg[0].rx_gain[0];
double rx_gain_offset = openair0_cfg[0].rx_gain_offset[0];
PHY_MEASUREMENTS_gNB *meas = &gNB->measurements;
NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
int ch_offset = fp->ofdm_symbol_size * symbol;
int N_RB_UL = gNB->ulsch[ulsch_id][0]->harq_processes[harq_pid]->ulsch_pdu.rb_size;
rx_power_tot[ulsch_id] = 0;
for (int aarx = 0; aarx < fp->nb_antennas_rx; aarx++){
rx_power[ulsch_id][aarx] = 0;
for (int aatx = 0; aatx < fp->nb_antennas_tx; aatx++){
meas->rx_spatial_power[ulsch_id][aatx][aarx] = (signal_energy_nodc(&gNB->pusch_vars[ulsch_id]->ul_ch_estimates[aarx][ch_offset], N_RB_UL * NR_NB_SC_PER_RB));
if (meas->rx_spatial_power[ulsch_id][aatx][aarx] < 0) {
meas->rx_spatial_power[ulsch_id][aatx][aarx] = 0;
}
meas->rx_spatial_power_dB[ulsch_id][aatx][aarx] = (unsigned short) dB_fixed(meas->rx_spatial_power[ulsch_id][aatx][aarx]);
rx_power[ulsch_id][aarx] += meas->rx_spatial_power[ulsch_id][aatx][aarx];
}
rx_power_tot[ulsch_id] += rx_power[ulsch_id][aarx];
}
rx_power_tot_dB[ulsch_id] = (unsigned short) dB_fixed(rx_power_tot[ulsch_id]);
rx_power_avg_dB[ulsch_id] = rx_power_tot_dB[ulsch_id];
meas->wideband_cqi_tot[ulsch_id] = dB_fixed2(rx_power_tot[ulsch_id], meas->n0_power_tot);
meas->rx_rssi_dBm[ulsch_id] = rx_power_avg_dB[ulsch_id] + 30 - 10 * log10(pow(2, 30)) - (rx_gain - rx_gain_offset) - dB_fixed(fp->ofdm_symbol_size);
LOG_D(PHY, "[ULSCH %d] RSSI %d dBm/RE, RSSI (digital) %d dB (N_RB_UL %d), WBand CQI tot %d dB, N0 Power tot %d\n",
ulsch_id,
meas->rx_rssi_dBm[ulsch_id],
rx_power_avg_dB[ulsch_id],
N_RB_UL,
meas->wideband_cqi_tot[ulsch_id],
meas->n0_power_tot);
}
......@@ -49,8 +49,9 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
void gNB_I0_measurements(PHY_VARS_gNB *gNB);
int nr_est_timing_advance_pusch(PHY_VARS_gNB* phy_vars_gNB, int UE_id);
void nr_gnb_measurements(PHY_VARS_gNB *gNB, uint8_t ulsch_id, unsigned char harq_pid, unsigned char symbol);
int nr_est_timing_advance_pusch(PHY_VARS_gNB* phy_vars_gNB, int UE_id);
void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB,
NR_DL_FRAME_PARMS *frame_parms,
......
......@@ -30,7 +30,7 @@
* \warning
*/
#include <LAYER2/NR_MAC_gNB/nr_mac_gNB.h>
#include "nr_dci.h"
#include "nr_dlsch.h"
#include "nr_sch_dmrs.h"
......@@ -85,10 +85,7 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
// compute rb_offset and n_prb based on frequency allocation
nr_fill_cce_list(gNB,0,pdcch_pdu_rel15);
get_coreset_rballoc(pdcch_pdu_rel15->FreqDomainResource,&n_rb,&rb_offset);
cset_start_sc = frame_parms.first_carrier_offset + rb_offset*NR_NB_SC_PER_RB;
if (pdcch_pdu_rel15->CoreSetType == NFAPI_NR_CSET_CONFIG_MIB_SIB1) {
cset_start_sc = cset_start_sc + RC.nrmac[gNB->Mod_id]->type0_PDCCH_CSS_config.cset_start_rb*NR_NB_SC_PER_RB;
}
cset_start_sc = frame_parms.first_carrier_offset + (pdcch_pdu_rel15->BWPStart + rb_offset) * NR_NB_SC_PER_RB;
for (int d=0;d<pdcch_pdu_rel15->numDlDci;d++) {
/*The coreset is initialised
......
......@@ -241,7 +241,7 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch,
///Payload generation
memset((void *)pbch, 0, sizeof(NR_gNB_PBCH));
pbch->pbch_a=0;
uint8_t ssb_index = frame_parms->ssb_index;
uint8_t ssb_index = ssb_pdu->ssb_pdu_rel15.SsbBlockIndex;
uint8_t *pbch_pdu = (uint8_t*)&ssb_pdu->ssb_pdu_rel15.bchPayload;
uint8_t Lmax = frame_parms->Lmax;
for (int i=0; i<NR_PBCH_PDU_BITS; i++)
......
......@@ -780,7 +780,7 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
}
} else { // This is the high-speed case
new_dft = 0;
nr_fill_du(N_ZC,prach_root_sequence_map);
// set preamble_offset to initial rootSequenceIndex and look if we need more root sequences for this
// preamble index and find the corresponding cyclic shift
// Check if all shifts for that root have been processed
......@@ -788,7 +788,7 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
not_found = 1;
new_dft = 1;
preamble_index0 -= numshift;
(preamble_offset==0 && numshift==0) ? (preamble_offset) : (preamble_offset++);
//(preamble_offset==0 && numshift==0) ? (preamble_offset) : (preamble_offset++);
while (not_found == 1) {
// current root depending on rootSequenceIndex
......
......@@ -73,6 +73,8 @@ void compute_nr_prach_seq(uint8_t short_sequence,
uint8_t rootSequenceIndex,
uint32_t X_u[64][839]);
void nr_fill_du(uint16_t N_ZC,uint16_t *prach_root_sequence_map);
void init_nr_prach_tables(int N_ZC);
/**@}*/
......
......@@ -1217,6 +1217,8 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB,
bwp_start_subcarrier,
rel15_ul);
nr_gnb_measurements(gNB, ulsch_id, harq_pid, symbol);
for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
gNB->pusch_vars[ulsch_id]->ulsch_power[aarx] = signal_energy_nodc(&gNB->pusch_vars[ulsch_id]->ul_ch_estimates[aarx][symbol*frame_parms->ofdm_symbol_size],
rel15_ul->rb_size*12);
......
......@@ -21,16 +21,17 @@
/*! \file nr_ue_measurements.c
* \brief UE measurements routines
* \author R. Knopp, G. Casati
* \author R. Knopp, G. Casati, K. Saaifan
* \date 2020
* \version 0.1
* \company Eurecom, Fraunhofer IIS
* \email: knopp@eurecom.fr, guido.casati@iis.fraunhofer.de
* \email: knopp@eurecom.fr, guido.casati@iis.fraunhofer.de, khodr.saaifan@iis.fraunhofer.de
* \note
* \warning
*/
#include "executables/softmodem-common.h"
#include "executables/nr-softmodem-common.h"
#include "PHY/defs_nr_UE.h"
#include "PHY/phy_extern_nr_ue.h"
#include "common/utils/LOG/log.h"
......@@ -45,7 +46,7 @@
//#define DEBUG_MEAS_UE
//#define DEBUG_RANK_EST
// Returns the pathloss in dBm for the active UL BWP on the selected carrier based on the DL RS associated with the PRACH transmission
// Returns the pathloss in dB for the active UL BWP on the selected carrier based on the DL RS associated with the PRACH transmission
// computation according to clause 7.4 (Physical random access channel) of 3GPP TS 38.213 version 16.3.0 Release 16
// Assumptions:
// - PRACH transmission from a UE is not in response to a detection of a PDCCH order by the UE
......@@ -59,18 +60,17 @@ int16_t get_nr_PL(uint8_t Mod_id, uint8_t CC_id, uint8_t gNB_index){
if (get_softmodem_params()->do_ra){
long referenceSignalPower = ue->nrUE_config.ssb_config.ss_pbch_power;
double rsrp_dBm = 10*log10(ue->measurements.rsrp[gNB_index]) + 30 - ue->rx_total_gain_dB;
pathloss = (int16_t)(10*log10(pow(10, (double)(referenceSignalPower)/10) - pow(10, (double)(rsrp_dBm)/10)));
pathloss = (int16_t)(referenceSignalPower - ue->measurements.rsrp_dBm[gNB_index]);
LOG_D(MAC, "In %s: pathloss %d dBm, UE RX total gain %d dB, referenceSignalPower %ld dBm (%f mW), RSRP %f dBm (%f mW)\n",
LOG_D(MAC, "In %s: pathloss %d dB, UE RX total gain %d dB, referenceSignalPower %ld dBm/RE (%f mW), RSRP %d dBm (%f mW)\n",
__FUNCTION__,
pathloss,
ue->rx_total_gain_dB,
referenceSignalPower,
pow(10, referenceSignalPower/10),
rsrp_dBm,
pow(10, rsrp_dBm/10));
ue->measurements.rsrp_dBm[gNB_index],
pow(10, ue->measurements.rsrp_dBm[gNB_index]/10));
} else {
......@@ -178,9 +178,9 @@ void nr_ue_measurements(PHY_VARS_NR_UE *ue,
ue->measurements.rx_power_avg_dB[gNB_id] = dB_fixed( ue->measurements.rx_power_avg[gNB_id]);
ue->measurements.wideband_cqi_tot[gNB_id] = dB_fixed2(ue->measurements.rx_power_tot[gNB_id], ue->measurements.n0_power_tot);
ue->measurements.wideband_cqi_avg[gNB_id] = dB_fixed2(ue->measurements.rx_power_avg[gNB_id], ue->measurements.n0_power_avg);
ue->measurements.rx_rssi_dBm[gNB_id] = ue->measurements.rx_power_avg_dB[gNB_id] - ue->rx_total_gain_dB;
ue->measurements.rx_rssi_dBm[gNB_id] = ue->measurements.rx_power_avg_dB[gNB_id] + 30 - 10*log10(pow(2, 30)) - ((int)openair0_cfg[0].rx_gain[0] - (int)openair0_cfg[0].rx_gain_offset[0]) - dB_fixed(ue->frame_parms.ofdm_symbol_size);
LOG_D(PHY, "[gNB %d] Slot %d, RSSI %d dBm, RSSI (digital) %d dB, WBandCQI %d dB, rxPwrAvg %d, n0PwrAvg %d\n",
LOG_I(PHY, "[gNB %d] Slot %d, RSSI %d dBm/RE, RSSI (digital) %d dB, WBandCQI %d dB, rxPwrAvg %d, n0PwrAvg %d \n",
gNB_id,
slot,
ue->measurements.rx_rssi_dBm[gNB_id],
......@@ -258,15 +258,20 @@ void nr_ue_rsrp_measurements(PHY_VARS_NR_UE *ue,
ue->measurements.rsrp_filtered[gNB_id] = ue->measurements.rsrp[gNB_id];
LOG_D(PHY, "In %s: [UE %d] slot %d SS-RSRP: %3.1f dBm/RE (%d W)\n",
ue->measurements.rsrp_dBm[gNB_id] = 10*log10(ue->measurements.rsrp[gNB_id]) + 30 - 10*log10(pow(2,30)) - ((int)openair0_cfg[0].rx_gain[0] - (int)openair0_cfg[0].rx_gain_offset[0]) - dB_fixed(ue->frame_parms.ofdm_symbol_size);
LOG_D(PHY, "In %s: [UE %d] slot %d SS-RSRP: %d dBm/RE (%d)\n",
__FUNCTION__,
ue->Mod_id,
slot,
10*log10(ue->measurements.rsrp[gNB_id]) + 30 - ue->rx_total_gain_dB,
ue->measurements.rsrp_dBm[gNB_id],
ue->measurements.rsrp[gNB_id]);
}
// This function computes the received noise power
// Measurement units:
// - psd_awgn (AWGN power spectral density): dBm/Hz
void nr_ue_rrc_measurements(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
uint8_t slot){
......@@ -279,6 +284,9 @@ void nr_ue_rrc_measurements(PHY_VARS_NR_UE *ue,
uint8_t k_length = 8;
uint8_t l_sss = ue->symbol_offset + 2;
unsigned int ssb_offset = ue->frame_parms.first_carrier_offset + ue->frame_parms.ssb_start_subcarrier;
double rx_gain = openair0_cfg[0].rx_gain[0];
double rx_gain_offset = openair0_cfg[0].rx_gain_offset[0];
ue->measurements.n0_power_tot = 0;
LOG_D(PHY, "In %s doing measurements for ssb_offset %d l_sss %d \n", __FUNCTION__, ssb_offset, l_sss);
......@@ -322,10 +330,17 @@ void nr_ue_rrc_measurements(PHY_VARS_NR_UE *ue,
ue->measurements.n0_power_tot_dB = (unsigned short) dB_fixed(ue->measurements.n0_power_tot/aarx);
#ifdef DEBUG_MEAS_RRC
int nf_usrp = ue->measurements.n0_power_tot_dB + 30 - ((int)openair0_cfg[0].rx_gain[0] - (int)openair0_cfg[0].rx_gain_offset[0]) - 90 - (-174 + dB_fixed(30000/*scs*/) + dB_fixed(ue->frame_parms.ofdm_symbol_size));
LOG_D(PHY, "In %s slot %d NF USRP %d dBm\n", __FUNCTION__, nf_usrp);
const int psd_awgn = -174;
const int scs = 15000 * (1 << ue->frame_parms.numerology_index);
const int nf_usrp = ue->measurements.n0_power_tot_dB + 3 + 30 - ((int)rx_gain - (int)rx_gain_offset) - 10 * log10(pow(2, 30)) - (psd_awgn + dB_fixed(scs) + dB_fixed(ue->frame_parms.ofdm_symbol_size));
LOG_D(PHY, "In [%s][slot:%d] NF USRP %d dB\n", __FUNCTION__, slot, nf_usrp);
#endif
LOG_D(PHY, "In %s slot %d Noise Level %d ue->measurements.n0_power_tot_dB %d \n", __FUNCTION__, slot, ue->measurements.n0_power_tot, ue->measurements.n0_power_tot_dB);
LOG_D(PHY, "In [%s][slot:%d] Noise Level %d (digital level %d dB, noise power spectral density %f dBm/RE)\n",
__FUNCTION__,
slot,
ue->measurements.n0_power_tot,
ue->measurements.n0_power_tot_dB,
ue->measurements.n0_power_tot_dB + 30 - 10*log10(pow(2, 30)) - dB_fixed(ue->frame_parms.ofdm_symbol_size) - ((int)rx_gain - (int)rx_gain_offset));
}
......@@ -589,7 +589,9 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
frame_parms->ssb_index += (((nr_ue_pbch_vars->xtra_byte>>(7-i))&0x01)<<(3+i));
}
ue->symbol_offset = nr_get_ssb_start_symbol(frame_parms);
ue->symbol_offset = nr_get_ssb_start_symbol(frame_parms,i_ssb);
if (frame_parms->half_frame_bit)
ue->symbol_offset += (frame_parms->slots_per_frame>>1)*frame_parms->symbols_per_slot;
uint8_t frame_number_4lsb = 0;
for (int i=0; i<4; i++)
......
......@@ -130,6 +130,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
#endif
not_found = 1;
nr_fill_du(N_ZC,prach_root_sequence_map);
preamble_index0 = preamble_index;
// set preamble_offset to initial rootSequenceIndex and look if we need more root sequences for this
// preamble index and find the corresponding cyclic shift
......
......@@ -18,7 +18,7 @@
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
......@@ -3103,10 +3103,12 @@ void dft128(int16_t *x,int16_t *y,unsigned char scale)
dft64((int16_t*)(xtmp),(int16_t*)ytmp,1);
dft64((int16_t*)(xtmp+32),(int16_t*)(ytmp+16),1);
#ifndef MR_MAIN
if (LOG_DUMPFLAG(DEBUG_DFT)) {
LOG_M("dft128a.m","dfta",ytmp,64,1,1);
LOG_M("dft128b.m","dftb",ytmp+16,64,1,1);
}
#endif
for (i=0; i<16; i++) {
bfly2_16(ytmpp,ytmpp+16,
y128p,y128p+16,
......@@ -3155,10 +3157,12 @@ void dft128(int16_t *x,int16_t *y,unsigned char scale)
}
#ifndef MR_MAIN
if (LOG_DUMPFLAG(DEBUG_DFT)) {
LOG_M("dft128out.m","dft128",y,128,1,1);
exit(-1);
}
#endif
_mm_empty();
_m_empty();
......@@ -3183,18 +3187,20 @@ void dft128(int16_t *x,int16_t *y,unsigned char scale)
transpose4_ooff_simd256(x256+10,xtmp+5,8);
transpose4_ooff_simd256(x256+12,xtmp+6,8);
transpose4_ooff_simd256(x256+14,xtmp+7,8);
#ifndef MR_MAIN
if (LOG_DUMPFLAG(DEBUG_DFT)) {
LOG_M("dft128ina_256.m","dftina",xtmp,64,1,1);
LOG_M("dft128inb_256.m","dftinb",xtmp+8,64,1,1);
}
#endif
dft64((int16_t*)(xtmp),(int16_t*)ytmp,1);
dft64((int16_t*)(xtmp+8),(int16_t*)(ytmp+8),1);
#ifndef MR_MAIN
if (LOG_DUMPFLAG(DEBUG_DFT)) {
LOG_M("dft128outa_256.m","dftouta",ytmp,64,1,1);
LOG_M("dft128outb_256.m","dftoutb",ytmp+8,64,1,1);
}
#endif
for (i=0; i<8; i++) {
bfly2_16_256(ytmpp,ytmpp+8,
y256p,y256p+8,
......@@ -3226,10 +3232,12 @@ void dft128(int16_t *x,int16_t *y,unsigned char scale)
y256[15] = mulhi_int16_simd256(y256[15],ONE_OVER_SQRT2_Q15_256);
}
#ifndef MR_MAIN
if (LOG_DUMPFLAG(DEBUG_DFT)) {
LOG_M("dft128.m","dft",y256,128,1,1);
exit(-1);
}
#endif
}
#endif
......@@ -6031,11 +6039,13 @@ void dft1536(int16_t *input, int16_t *output, unsigned char scale)
tmpo[1][i] = tmpo[1][i<<1];
tmpo[2][i] = tmpo[2][i<<1];
}*/
#ifndef MR_MAIN
if (LOG_DUMPFLAG(DEBUG_DFT)) {
LOG_M("dft1536out0.m","o0",tmpo[0],2048,1,1);
LOG_M("dft1536out1.m","o1",tmpo[1],2048,1,1);
LOG_M("dft1536out2.m","o2",tmpo[2],2048,1,1);
}
#endif
for (i=0,i2=0; i<1024; i+=8,i2+=4) {
bfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),(simd_q15_t*)(&tmpo[2][i2]),
(simd_q15_t*)(output+i),(simd_q15_t*)(output+1024+i),(simd_q15_t*)(output+2048+i),
......@@ -6193,14 +6203,14 @@ void idft6144(int16_t *input, int16_t *output,unsigned char scale)
idft2048((int16_t*)(tmp[0]),(int16_t*)(tmpo[0]),1);
idft2048((int16_t*)(tmp[1]),(int16_t*)(tmpo[1]),1);
idft2048((int16_t*)(tmp[2]),(int16_t*)(tmpo[2]),1);
#ifndef MR_MAIN
if (LOG_DUMPFLAG(DEBUG_DFT)) {
LOG_M("idft6144in.m","in",input,6144,1,1);
LOG_M("idft6144out0.m","o0",tmpo[0],2048,1,1);
LOG_M("idft6144out1.m","o1",tmpo[1],2048,1,1);
LOG_M("idft6144out2.m","o2",tmpo[2],2048,1,1);
}
#endif
for (i=0,i2=0; i<4096; i+=8,i2+=4) {
ibfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),((simd_q15_t*)&tmpo[2][i2]),
(simd_q15_t*)(output+i),(simd_q15_t*)(output+4096+i),(simd_q15_t*)(output+8192+i),
......@@ -6260,11 +6270,13 @@ void dft6144(int16_t *input, int16_t *output,unsigned char scale)
tmpo[1][i] = tmpo[1][i<<1];
tmpo[2][i] = tmpo[2][i<<1];
}*/
#ifndef MR_MAIN
if (LOG_DUMPFLAG(DEBUG_DFT)) {
LOG_M("ft6144out0.m","o0",tmpo[0],2048,1,1);
LOG_M("ft6144out1.m","o1",tmpo[1],2048,1,1);
LOG_M("ft6144out2.m","o2",tmpo[2],2048,1,1);
}
#endif
for (i=0,i2=0; i<4096; i+=8,i2+=4) {
bfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),(simd_q15_t*)(&tmpo[2][i2]),
(simd_q15_t*)(output+i),(simd_q15_t*)(output+4096+i),(simd_q15_t*)(output+8192+i),
......@@ -6336,11 +6348,13 @@ void dft12288(int16_t *input, int16_t *output,unsigned char scale)
tmpo[1][i] = tmpo[1][i<<1];
tmpo[2][i] = tmpo[2][i<<1];
}*/
#ifndef MR_MAIN
if (LOG_DUMPFLAG(DEBUG_DFT)) {
LOG_M("dft12288out0.m","o0",tmpo[0],4096,1,1);
LOG_M("dft12288out1.m","o1",tmpo[1],4096,1,1);
LOG_M("dft12288out2.m","o2",tmpo[2],4096,1,1);
}
#endif
for (i=0,i2=0; i<8192; i+=8,i2+=4) {
bfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),(simd_q15_t*)(&tmpo[2][i2]),
(simd_q15_t*)(output+i),(simd_q15_t*)(output+8192+i),(simd_q15_t*)(output+16384+i),
......@@ -6392,14 +6406,14 @@ void idft12288(int16_t *input, int16_t *output,unsigned char scale)
idft4096((int16_t*)(tmp[0]),(int16_t*)(tmpo[0]),scale);
idft4096((int16_t*)(tmp[1]),(int16_t*)(tmpo[1]),scale);
idft4096((int16_t*)(tmp[2]),(int16_t*)(tmpo[2]),scale);
#ifndef MR_MAIN
if (LOG_DUMPFLAG(DEBUG_DFT)) {
LOG_M("idft12288in.m","in",input,12288,1,1);
LOG_M("idft12288out0.m","o0",tmpo[0],4096,1,1);
LOG_M("idft12288out1.m","o1",tmpo[1],4096,1,1);
LOG_M("idft12288out2.m","o2",tmpo[2],4096,1,1);
}
#endif
for (i=0,i2=0; i<8192; i+=8,i2+=4) {
ibfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),((simd_q15_t*)&tmpo[2][i2]),
(simd_q15_t*)(output+i),(simd_q15_t*)(output+8192+i),(simd_q15_t*)(output+16384+i),
......@@ -6429,9 +6443,11 @@ void idft12288(int16_t *input, int16_t *output,unsigned char scale)
}
_mm_empty();
_m_empty();
#ifndef MR_MAIN
if (LOG_DUMPFLAG(DEBUG_DFT)) {
LOG_M("idft12288out.m","out",output,6144,1,1);
}
#endif
}
int16_t twa18432[12288] __attribute__((aligned(32)));
......@@ -6560,11 +6576,13 @@ void dft24576(int16_t *input, int16_t *output,unsigned char scale)
tmpo[1][i] = tmpo[1][i<<1];
tmpo[2][i] = tmpo[2][i<<1];
}*/
#ifndef MR_MAIN
if (LOG_DUMPFLAG(DEBUG_DFT)) {
LOG_M("dft24576out0.m","o0",tmpo[0],8192,1,1);
LOG_M("dft24576out1.m","o1",tmpo[1],8192,1,1);
LOG_M("dft24576out2.m","o2",tmpo[2],8192,1,1);
}
#endif
for (i=0,i2=0; i<16384; i+=8,i2+=4) {
bfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),(simd_q15_t*)(&tmpo[2][i2]),
(simd_q15_t*)(output+i),(simd_q15_t*)(output+16384+i),(simd_q15_t*)(output+32768+i),
......@@ -6595,9 +6613,11 @@ void dft24576(int16_t *input, int16_t *output,unsigned char scale)
}
_mm_empty();
_m_empty();
#ifndef MR_MAIN
if (LOG_DUMPFLAG(DEBUG_DFT)) {
LOG_M("out.m","out",output,24576,1,1);
}
#endif
}
void idft24576(int16_t *input, int16_t *output,unsigned char scale)
......@@ -6617,14 +6637,14 @@ void idft24576(int16_t *input, int16_t *output,unsigned char scale)
idft8192((int16_t*)(tmp[0]),(int16_t*)(tmpo[0]),1);
idft8192((int16_t*)(tmp[1]),(int16_t*)(tmpo[1]),1);
idft8192((int16_t*)(tmp[2]),(int16_t*)(tmpo[2]),1);
#ifndef MR_MAIN
if (LOG_DUMPFLAG(DEBUG_DFT)) {
LOG_M("idft24576in.m","in",input,24576,1,1);
LOG_M("idft24576out0.m","o0",tmpo[0],8192,1,1);
LOG_M("idft24576out1.m","o1",tmpo[1],8192,1,1);
LOG_M("idft24576out2.m","o2",tmpo[2],8192,1,1);
}
#endif
for (i=0,i2=0; i<16384; i+=8,i2+=4) {
ibfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),((simd_q15_t*)&tmpo[2][i2]),
(simd_q15_t*)(output+i),(simd_q15_t*)(output+16384+i),(simd_q15_t*)(output+32768+i),
......@@ -6653,10 +6673,11 @@ void idft24576(int16_t *input, int16_t *output,unsigned char scale)
}
_mm_empty();
_m_empty();
#ifndef MR_MAIN
if (LOG_DUMPFLAG(DEBUG_DFT)) {
LOG_M("idft24576out.m","out",output,24576,1,1);
}
#endif
}
int16_t twa36864[24576] __attribute__((aligned(32)));
......@@ -6680,13 +6701,13 @@ void dft36864(int16_t *input, int16_t *output,uint8_t scale) {
dft12288((int16_t*)(tmp[0]),(int16_t*)(tmpo[0]),1);
dft12288((int16_t*)(tmp[1]),(int16_t*)(tmpo[1]),1);
dft12288((int16_t*)(tmp[2]),(int16_t*)(tmpo[2]),1);
#ifndef MR_MAIN
if (LOG_DUMPFLAG(DEBUG_DFT)) {
LOG_M("dft36864out0.m","o0",tmpo[0],12288,1,1);
LOG_M("dft36864out1.m","o1",tmpo[1],12288,1,1);
LOG_M("dft36864out2.m","o2",tmpo[2],12288,1,1);
}
#endif
for (i=0,i2=0; i<24576; i+=8,i2+=4) {
bfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),(simd_q15_t*)(&tmpo[2][i2]),
(simd_q15_t*)(output+i),(simd_q15_t*)(output+24576+i),(simd_q15_t*)(output+49152+i),
......@@ -6716,9 +6737,11 @@ void dft36864(int16_t *input, int16_t *output,uint8_t scale) {
}
_mm_empty();
_m_empty();
#ifndef MR_MAIN
if (LOG_DUMPFLAG(DEBUG_DFT)) {
LOG_M("out.m","out",output,36864,1,1);
}
#endif
}
void idft36864(int16_t *input, int16_t *output,uint8_t scale) {
......
......@@ -182,7 +182,10 @@ typedef struct {
int16_t sqrt_rho_b;
} NR_gNB_DLSCH_t;
typedef struct {
bool active;
nfapi_nr_dl_tti_ssb_pdu ssb_pdu;
} NR_gNB_SSB_t;
typedef struct {
int frame;
......@@ -711,10 +714,10 @@ typedef struct PHY_VARS_gNB_s {
// nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu;
// nfapi_nr_ul_dci_request_pdus_t *ul_dci_pdu;
nfapi_nr_dl_tti_ssb_pdu ssb_pdu;
uint16_t num_pdsch_rnti[80];
NR_gNB_PBCH pbch;
NR_gNB_SSB_t ssb[64];
NR_gNB_PBCH pbch;
nr_cce_t cce_list[MAX_DCI_CORESET][NR_MAX_PDCCH_AGG_LEVEL];
NR_gNB_COMMON common_vars;
NR_gNB_PRACH prach_vars;
......
......@@ -142,6 +142,7 @@ typedef struct {
uint32_t rsrp[7];
float rsrp_filtered[7]; // after layer 3 filtering
float rsrq_filtered[7];
short rsrp_dBm[7];
// common measurements
//! estimated noise power (linear)
unsigned int n0_power[NB_ANTENNAS_RX];
......
......@@ -50,8 +50,15 @@ void handle_nr_nfapi_ssb_pdu(PHY_VARS_gNB *gNB,int frame,int slot,
AssertFatal(dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.bchPayloadFlag== 1, "bchPayloadFlat %d != 1\n",
dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.bchPayloadFlag);
LOG_D(PHY,"%d.%d : pbch_pdu: %x\n",frame,slot,dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.bchPayload);
memcpy((void*)&gNB->ssb_pdu,&dl_tti_pdu->ssb_pdu,sizeof(dl_tti_pdu->ssb_pdu));
uint8_t i_ssb = dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.SsbBlockIndex;
LOG_D(PHY,"%d.%d : ssb index %d pbch_pdu: %x\n",frame,slot,i_ssb,dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.bchPayload);
if (gNB->ssb[i_ssb].active)
AssertFatal(1==0,"SSB PDU with index %d already active\n",i_ssb);
else {
gNB->ssb[i_ssb].active = true;
memcpy((void*)&gNB->ssb[i_ssb].ssb_pdu,&dl_tti_pdu->ssb_pdu,sizeof(dl_tti_pdu->ssb_pdu));
}
}
/*void handle_nr_nfapi_pdsch_pdu(PHY_VARS_gNB *gNB,int frame,int subframe,gNB_L1_rxtx_proc_t *proc,
......@@ -166,14 +173,11 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){
gNB->dlsch[i][0]->harq_mask=0;
}
gNB->pbch_configured=0;
for (int i=0;i<number_dl_pdu;i++) {
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdu = &DL_req->dl_tti_request_body.dl_tti_pdu_list[i];
LOG_D(PHY,"NFAPI: dl_pdu %d : type %d\n",i,dl_tti_pdu->PDUType);
switch (dl_tti_pdu->PDUType) {
case NFAPI_NR_DL_TTI_SSB_PDU_TYPE:
gNB->pbch_configured=1;
if(NFAPI_MODE != NFAPI_MODE_VNF)
handle_nr_nfapi_ssb_pdu(gNB,frame,slot,
......@@ -257,4 +261,4 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){
}
}
\ No newline at end of file
}
......@@ -67,85 +67,63 @@ void nr_set_ssb_first_subcarrier(nfapi_nr_config_request_scf_t *cfg, NR_DL_FRAME
LOG_D(PHY, "SSB first subcarrier %d (%d,%d)\n", fp->ssb_start_subcarrier,cfg->ssb_table.ssb_offset_point_a.value,sco);
}
void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int slot) {
void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame,int slot,nfapi_nr_dl_tti_ssb_pdu ssb_pdu) {
NR_DL_FRAME_PARMS *fp=&gNB->frame_parms;
nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
int **txdataF = gNB->common_vars.txdataF;
uint8_t ssb_index, ssb_per_slot=0, n_hf;
uint16_t ssb_start_symbol, rel_slot;
uint8_t ssb_index, n_hf;
uint16_t ssb_start_symbol;
int txdataF_offset = (slot%2)*fp->samples_per_slot_wCP;
uint16_t slots_per_hf = (fp->slots_per_frame)>>1;
n_hf = fp->half_frame_bit;
if (slot<slots_per_hf)
n_hf=0;
else
n_hf=1;
// if SSB periodicity is 5ms, they are transmitted in both half frames
if ( cfg->ssb_table.ssb_period.value == 0) {
if (slot<slots_per_hf)
n_hf=0;
else
n_hf=1;
}
ssb_index = ssb_pdu.ssb_pdu_rel15.SsbBlockIndex;
LOG_D(PHY,"common_signal_procedures: frame %d, slot %d ssb index %d\n",frame,slot,ssb_index);
// to set a effective slot number in the half frame where the SSB is supposed to be
rel_slot = (n_hf)? (slot-slots_per_hf) : slot;
LOG_D(PHY,"common_signal_procedures: frame %d, slot %d\n",frame,slot);
if(rel_slot<38 && rel_slot>=0) { // there is no SSB beyond slot 37
for (int i=0; i<2; i++) { // max two SSB per slot
ssb_index = i + SSB_Table[rel_slot]; // computing the ssb_index
if ((ssb_index<64) && ((fp->L_ssb >> (63-ssb_index)) & 0x01)) { // generating the ssb only if the bit of L_ssb at current ssb index is 1
ssb_per_slot++;
fp->ssb_index = ssb_index;
int ssb_start_symbol_abs = nr_get_ssb_start_symbol(fp); // computing the starting symbol for current ssb
ssb_start_symbol = ssb_start_symbol_abs % fp->symbols_per_slot; // start symbol wrt slot
nr_set_ssb_first_subcarrier(cfg, fp); // setting the first subcarrier
LOG_D(PHY,"SS TX: frame %d, slot %d, start_symbol %d\n",frame,slot, ssb_start_symbol);
nr_generate_pss(gNB->d_pss, &txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp);
nr_generate_sss(gNB->d_sss, &txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp);
if (cfg->carrier_config.num_tx_ant.value <= 4)
nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[n_hf][ssb_index&7],&txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp);
else
nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[0][ssb_index&7],&txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp);
if (T_ACTIVE(T_GNB_PHY_MIB)) {
unsigned char bch[3];
bch[0] = gNB->ssb_pdu.ssb_pdu_rel15.bchPayload & 0xff;
bch[1] = (gNB->ssb_pdu.ssb_pdu_rel15.bchPayload >> 8) & 0xff;
bch[2] = (gNB->ssb_pdu.ssb_pdu_rel15.bchPayload >> 16) & 0xff;
T(T_GNB_PHY_MIB, T_INT(0) /* module ID */, T_INT(frame), T_INT(slot), T_BUFFER(bch, 3));
}
int ssb_start_symbol_abs = nr_get_ssb_start_symbol(fp,ssb_index); // computing the starting symbol for current ssb
ssb_start_symbol = ssb_start_symbol_abs % fp->symbols_per_slot; // start symbol wrt slot
nr_generate_pbch(&gNB->pbch,
&gNB->ssb_pdu,
gNB->nr_pbch_interleaver,
&txdataF[0][txdataF_offset],
AMP,
ssb_start_symbol,
n_hf, frame, cfg, fp);
// SSB beamforming is handled at PHY
// currently our PHY does not support switching more than once a slot.
if (ssb_per_slot>1) {
LOG_W(PHY,"beamforming currently not supported for more than one SSB per slot\n");
}
else if (ssb_per_slot==1) {
LOG_D(PHY,"slot %d, ssb_index %d, beam %d\n",slot,ssb_index,cfg->ssb_table.ssb_beam_id_list[ssb_index].beam_id.value);
for (int j=0;j<fp->symbols_per_slot;j++)
gNB->common_vars.beam_id[0][slot*fp->symbols_per_slot+j] = cfg->ssb_table.ssb_beam_id_list[ssb_index].beam_id.value;
}
}
}
nr_set_ssb_first_subcarrier(cfg, fp); // setting the first subcarrier
LOG_D(PHY,"SS TX: frame %d, slot %d, start_symbol %d\n",frame,slot, ssb_start_symbol);
nr_generate_pss(gNB->d_pss, &txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp);
nr_generate_sss(gNB->d_sss, &txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp);
if (cfg->carrier_config.num_tx_ant.value <= 4)
nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[n_hf][ssb_index&7],&txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp);
else
nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[0][ssb_index&7],&txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp);
if (T_ACTIVE(T_GNB_PHY_MIB)) {
unsigned char bch[3];
bch[0] = ssb_pdu.ssb_pdu_rel15.bchPayload & 0xff;
bch[1] = (ssb_pdu.ssb_pdu_rel15.bchPayload >> 8) & 0xff;
bch[2] = (ssb_pdu.ssb_pdu_rel15.bchPayload >> 16) & 0xff;
T(T_GNB_PHY_MIB, T_INT(0) /* module ID */, T_INT(frame), T_INT(slot), T_BUFFER(bch, 3));
}
// Beam_id is currently used only for FR2
if (fp->freq_range==nr_FR2){
LOG_D(PHY,"slot %d, ssb_index %d, beam %d\n",slot,ssb_index,cfg->ssb_table.ssb_beam_id_list[ssb_index].beam_id.value);
for (int j=0;j<fp->symbols_per_slot;j++)
gNB->common_vars.beam_id[0][slot*fp->symbols_per_slot+j] = cfg->ssb_table.ssb_beam_id_list[ssb_index].beam_id.value;
}
nr_generate_pbch(&gNB->pbch,
&ssb_pdu,
gNB->nr_pbch_interleaver,
&txdataF[0][txdataF_offset],
AMP,
ssb_start_symbol,
n_hf, frame, cfg, fp);
}
void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
int frame,int slot,
int do_meas) {
......@@ -153,11 +131,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
NR_DL_FRAME_PARMS *fp=&gNB->frame_parms;
nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
int offset = gNB->CC_id;
uint8_t ssb_frame_periodicity = 1; // every how many frames SSB are generated
int txdataF_offset = (slot%2)*fp->samples_per_slot_wCP;
if (cfg->ssb_table.ssb_period.value > 1)
ssb_frame_periodicity = 1 <<(cfg->ssb_table.ssb_period.value -1) ;
if ((cfg->cell_config.frame_duplex_type.value == TDD) &&
(nr_slot_select(cfg,frame,slot) == NR_UPLINK_SLOT)) return;
......@@ -174,8 +148,12 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_COMMON_TX,1);
if (NFAPI_MODE == NFAPI_MONOLITHIC || NFAPI_MODE == NFAPI_MODE_PNF) {
if ((!(frame%ssb_frame_periodicity))) // generate SSB only for given frames according to SSB periodicity
nr_common_signal_procedures(gNB,frame, slot);
for (int i=0; i<fp->Lmax; i++) {
if (gNB->ssb[i].active) {
nr_common_signal_procedures(gNB,frame,slot,gNB->ssb[i].ssb_pdu);
gNB->ssb[i].active = false;
}
}
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_COMMON_TX,0);
......@@ -468,7 +446,7 @@ void fill_ul_rb_mask(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
(pucch->frame == frame_rx) &&
(pucch->slot == slot_rx) ) {
gNB->ulmask_symb = symbol;
nfapi_nr_pucch_pdu_t *pucch_pdu = &pucch[i].pucch_pdu;
nfapi_nr_pucch_pdu_t *pucch_pdu = &pucch->pucch_pdu;
if ((symbol>=pucch_pdu->start_symbol_index) &&
(symbol<(pucch_pdu->start_symbol_index + pucch_pdu->nr_of_symbols))){
for (rb=0; rb<pucch_pdu->prb_size; rb++) {
......
......@@ -40,7 +40,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, int frame_tx, int slot_tx, int do_
void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx);
void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx);
void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot);
void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int slot);
void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame,int slot,nfapi_nr_dl_tti_ssb_pdu ssb_pdu);
void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx);
void nr_feptx_ofdm_2thread(RU_t *ru,int frame_tx,int tti_tx);
void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa);
......
......@@ -2072,10 +2072,10 @@ void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t
if (ue->mac_enabled == 1) {
int16_t pathloss = get_nr_PL(mod_id, ue->CC_id, gNB_id);
int16_t ra_preamble_rx_power = (int16_t)(10*log10(pow(10, (double)(prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER)/10) + pow(10, (double)(pathloss)/10)));
int16_t ra_preamble_rx_power = (int16_t)(prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER - pathloss + 30);
ue->tx_power_dBm[nr_slot_tx] = min(nr_get_Pcmax(mod_id), ra_preamble_rx_power);
LOG_I(PHY,"[UE %d][RAPROC][%d.%d]: Generating PRACH Msg1 (preamble %d, PL %d, P0_PRACH %d, TARGET_RECEIVED_POWER %d dBm, RA-RNTI %x)\n",
LOG_I(PHY,"DEBUG [UE %d][RAPROC][%d.%d]: Generating PRACH Msg1 (preamble %d, PL %d dB, P0_PRACH %d, TARGET_RECEIVED_POWER %d dBm, RA-RNTI %x)\n",
mod_id,
frame_tx,
nr_slot_tx,
......
......@@ -173,6 +173,7 @@ int nr_derive_key(int alg_type, uint8_t alg_id,
}
void config_common(int Mod_idP,
int ssb_SubcarrierOffset,
int pdsch_AntennaPorts,
int pusch_AntennaPorts,
NR_ServingCellConfigCommon_t *scc
......@@ -702,7 +703,7 @@ int main(int argc, char **argv)
NR_ServingCellConfig_t *scd = calloc(1,sizeof(NR_ServingCellConfig_t));
NR_CellGroupConfig_t *secondaryCellGroup=calloc(1,sizeof(*secondaryCellGroup));
prepare_scc(rrc.carrier.servingcellconfigcommon);
uint64_t ssb_bitmap;
uint64_t ssb_bitmap = 1;
fill_scc(rrc.carrier.servingcellconfigcommon,&ssb_bitmap,N_RB_DL,N_RB_DL,mu,mu);
ssb_bitmap = 1;// Enable only first SSB with index ssb_indx=0
fix_scc(scc,ssb_bitmap);
......@@ -884,7 +885,8 @@ int main(int argc, char **argv)
// generate signal
AssertFatal(input_fd==NULL,"Not ready for input signal file\n");
gNB->pbch_configured = 1;
gNB->ssb_pdu.ssb_pdu_rel15.bchPayload=0x001234;
gNB->ssb[0].ssb_pdu.ssb_pdu_rel15.bchPayload=0x001234;
gNB->ssb[0].ssb_pdu.ssb_pdu_rel15.SsbBlockIndex = 0;
//Configure UE
rrc.carrier.MIB = (uint8_t*) malloc(4);
......@@ -1010,7 +1012,7 @@ int main(int argc, char **argv)
printf("[DLSIM] PTRS Symbols in a slot: %2u, RE per Symbol: %3u, RE in a slot %4d\n", ptrsSymbPerSlot,ptrsRePerSymb, ptrsSymbPerSlot*ptrsRePerSymb );
}
if (run_initial_sync)
nr_common_signal_procedures(gNB,frame,slot);
nr_common_signal_procedures(gNB,frame,slot,gNB->ssb[0].ssb_pdu);
else
phy_procedures_gNB_TX(gNB,frame,slot,0);
......
......@@ -120,7 +120,7 @@ void nr_phy_config_request_sim_pbchsim(PHY_VARS_gNB *gNB,
int main(int argc, char **argv)
{
char c;
int i,aa;//,l;
int i,aa,start_symbol;
double sigma2, sigma2_dB=10,SNR,snr0=-2.0,snr1=2.0;
double cfo=0;
uint8_t snr1set=0;
......@@ -427,29 +427,28 @@ int main(int argc, char **argv)
switch (mu) {
case 1:
scs = 30000;
if (N_RB_DL == 217) {
fs = 122.88e6;
bw = 80e6;
}
else if (N_RB_DL == 245) {
fs = 122.88e6;
bw = 90e6;
}
else if (N_RB_DL == 273) {
fs = 122.88e6;
bw = 100e6;
}
else if (N_RB_DL == 106) {
fs = 61.44e6;
bw = 40e6;
}
else AssertFatal(1==0,"Unsupported numerology for mu %d, N_RB %d\n",mu, N_RB_DL);
break;
scs = 30000;
frame_parms->Lmax = 8;
if (N_RB_DL == 217) {
fs = 122.88e6;
bw = 80e6;
}
else if (N_RB_DL == 245) {
fs = 122.88e6;
bw = 90e6;
}
else if (N_RB_DL == 273) {
fs = 122.88e6;
bw = 100e6;
}
else if (N_RB_DL == 106) {
fs = 61.44e6;
bw = 40e6;
}
else AssertFatal(1==0,"Unsupported numerology for mu %d, N_RB %d\n",mu, N_RB_DL);
break;
case 3:
frame_parms->Lmax = 64;
scs = 120000;
if (N_RB_DL == 66) {
fs = 122.88e6;
......@@ -458,6 +457,7 @@ int main(int argc, char **argv)
else AssertFatal(1==0,"Unsupported numerology for mu %d, N_RB %d\n",mu, N_RB_DL);
break;
}
// cfo with respect to sub-carrier spacing
eps = cfo/scs;
......@@ -511,7 +511,6 @@ int main(int argc, char **argv)
printf("Allocating %d samples for txdata\n",frame_length_complex_samples);
txdata[i] = malloc(frame_length_complex_samples*sizeof(int));
bzero(r_re[i],frame_length_complex_samples*sizeof(int));
}
if (pbch_file_fd!=NULL) {
......@@ -537,60 +536,68 @@ int main(int argc, char **argv)
}
nr_gold_pbch(UE);
// generate signal
if (input_fd==NULL) {
gNB->pbch_configured = 1;
gNB->ssb_pdu.ssb_pdu_rel15.bchPayload = 0x55dd33;
for (int slot=0;slot<frame_parms->slots_per_frame;slot++) {
for (aa=0; aa<gNB->frame_parms.nb_antennas_tx; aa++)
memset(gNB->common_vars.txdataF[aa],0,frame_parms->samples_per_slot_wCP*sizeof(int32_t));
nr_common_signal_procedures (gNB,frame,slot);
for (aa=0; aa<gNB->frame_parms.nb_antennas_tx; aa++) {
if (cyclic_prefix_type == 1) {
PHY_ofdm_mod(gNB->common_vars.txdataF[aa],
&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)],
frame_parms->ofdm_symbol_size,
12,
frame_parms->nb_prefix_samples,
CYCLIC_PREFIX);
} else {
/* nr_normal_prefix_mod(gNB->common_vars.txdataF[aa],
&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)],
14,
frame_parms);*/
PHY_ofdm_mod(gNB->common_vars.txdataF[aa],
(int*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)],
frame_parms->ofdm_symbol_size,
1,
frame_parms->nb_prefix_samples0,
CYCLIC_PREFIX);
apply_nr_rotation(frame_parms,
(int16_t*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)],
slot,
0,
1,
frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples0);
PHY_ofdm_mod(&gNB->common_vars.txdataF[aa][frame_parms->ofdm_symbol_size],
(int*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)+frame_parms->nb_prefix_samples0+frame_parms->ofdm_symbol_size],
frame_parms->ofdm_symbol_size,
13,
frame_parms->nb_prefix_samples,
CYCLIC_PREFIX);
apply_nr_rotation(frame_parms,
(int16_t*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)+frame_parms->nb_prefix_samples0+frame_parms->ofdm_symbol_size],
slot,
1,
13,
frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples);
}
}
for (i=0; i<frame_parms->Lmax; i++) {
if((SSB_positions >> i) & 0x01) {
gNB->ssb[i].ssb_pdu.ssb_pdu_rel15.bchPayload = 0x55dd33;
gNB->ssb[i].ssb_pdu.ssb_pdu_rel15.SsbBlockIndex = i;
start_symbol = nr_get_ssb_start_symbol(frame_parms,i);
int slot = start_symbol/14;
for (aa=0; aa<gNB->frame_parms.nb_antennas_tx; aa++)
memset(gNB->common_vars.txdataF[aa],0,frame_parms->samples_per_slot_wCP*sizeof(int32_t));
nr_common_signal_procedures (gNB,frame,slot,gNB->ssb[i].ssb_pdu);
for (aa=0; aa<gNB->frame_parms.nb_antennas_tx; aa++) {
if (cyclic_prefix_type == 1) {
PHY_ofdm_mod(gNB->common_vars.txdataF[aa],
&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)],
frame_parms->ofdm_symbol_size,
12,
frame_parms->nb_prefix_samples,
CYCLIC_PREFIX);
} else {
/*nr_normal_prefix_mod(gNB->common_vars.txdataF[aa],
&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)],
14,
frame_parms);*/
PHY_ofdm_mod(gNB->common_vars.txdataF[aa],
(int*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)],
frame_parms->ofdm_symbol_size,
1,
frame_parms->nb_prefix_samples0,
CYCLIC_PREFIX);
apply_nr_rotation(frame_parms,
(int16_t*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)],
slot,
0,
1,
frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples0);
PHY_ofdm_mod(&gNB->common_vars.txdataF[aa][frame_parms->ofdm_symbol_size],
(int*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)+frame_parms->nb_prefix_samples0+frame_parms->ofdm_symbol_size],
frame_parms->ofdm_symbol_size,
13,
frame_parms->nb_prefix_samples,
CYCLIC_PREFIX);
apply_nr_rotation(frame_parms,
(int16_t*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)+frame_parms->nb_prefix_samples0+frame_parms->ofdm_symbol_size],
slot,
1,
13,
frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples);
}
}
}
}
LOG_M("txsigF0.m","txsF0", gNB->common_vars.txdataF[0],frame_length_complex_samples_no_prefix,1,1);
if (gNB->frame_parms.nb_antennas_tx>1)
LOG_M("txsigF1.m","txsF1", gNB->common_vars.txdataF[1],frame_length_complex_samples_no_prefix,1,1);
......@@ -599,9 +606,9 @@ int main(int argc, char **argv)
printf("Reading %d samples from file to antenna buffer %d\n",frame_length_complex_samples,0);
UE->UE_fo_compensation = 1; // perform fo compensation when samples from file are used
if (fread(txdata[0],
sizeof(int32_t),
frame_length_complex_samples,
input_fd) != frame_length_complex_samples) {
sizeof(int32_t),
frame_length_complex_samples,
input_fd) != frame_length_complex_samples) {
printf("error reading from file\n");
//exit(-1);
}
......@@ -685,10 +692,9 @@ int main(int argc, char **argv)
UE->rx_offset=0;
uint8_t ssb_index = 0;
while (!((SSB_positions >> ssb_index) & 0x01)) ssb_index++; // to select the first transmitted ssb
frame_parms->ssb_index = ssb_index;
UE->symbol_offset = nr_get_ssb_start_symbol(frame_parms);
UE->symbol_offset = nr_get_ssb_start_symbol(frame_parms,ssb_index);
int ssb_slot = (ssb_index>>1)+(n_hf*frame_parms->slots_per_frame);
int ssb_slot = (UE->symbol_offset/14)+(n_hf*(frame_parms->slots_per_frame>>1));
for (int i=UE->symbol_offset+1; i<UE->symbol_offset+4; i++) {
nr_slot_fep(UE,
&proc,
......@@ -717,7 +723,7 @@ int main(int argc, char **argv)
payload_ret = (UE->pbch_vars[0]->xtra_byte == gNB_xtra_byte);
for (i=0;i<3;i++){
payload_ret += (UE->pbch_vars[0]->decoded_output[i] == ((gNB->ssb_pdu.ssb_pdu_rel15.bchPayload>>(8*i)) & 0xff));
payload_ret += (UE->pbch_vars[0]->decoded_output[i] == ((gNB->ssb[ssb_index].ssb_pdu.ssb_pdu_rel15.bchPayload>>(8*i)) & 0xff));
}
//printf("xtra byte gNB: 0x%02x UE: 0x%02x\n",gNB_xtra_byte, UE->pbch_vars[0]->xtra_byte);
//printf("ret %d\n", payload_ret);
......
......@@ -205,7 +205,7 @@ int main(int argc, char **argv){
randominit(0);
while ((c = getopt (argc, argv, "hHaA:Cc:r:p:g:m:n:s:S:t:x:y:v:V:z:N:F:d:Z:L:R:E")) != -1) {
while ((c = getopt (argc, argv, "hHaA:Cc:l:r:p:g:m:n:s:S:t:x:y:v:V:z:N:F:d:Z:L:R:E")) != -1) {
switch (c) {
case 'a':
printf("Running AWGN simulation\n");
......@@ -218,6 +218,10 @@ int main(int argc, char **argv){
config_index = atoi(optarg);
break;
case 'l':
loglvl = atoi(optarg);
break;
case 'r':
msg1_frequencystart = atoi(optarg);
break;
......
......@@ -36,6 +36,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define TABLE_38213_13_1_NUM_INDEXES 15
#define TABLE_38213_13_2_NUM_INDEXES 14
......@@ -418,14 +419,6 @@ typedef enum {
NR_RNTI_MCS_C,
} nr_rnti_type_t;
typedef enum subcarrier_spacing_e {
scs_15kHz = 0x1,
scs_30kHz = 0x2,
scs_60kHz = 0x4,
scs_120kHz = 0x8,
scs_240kHz = 0x16
} subcarrier_spacing_t;
typedef enum channel_bandwidth_e {
bw_5MHz = 0x1,
bw_10MHz = 0x2,
......@@ -462,6 +455,7 @@ typedef struct Type0_PDCCH_CSS_config_s {
uint32_t ssb_length;
uint32_t ssb_index;
uint32_t cset_start_rb;
bool active;
} NR_Type0_PDCCH_CSS_config_t;
#endif /*__LAYER2_MAC_H__ */
......
......@@ -126,12 +126,18 @@ int32_t get_l_prime(uint8_t duration_in_symbols, uint8_t mapping_type, pusch_dmr
uint8_t get_L_ptrs(uint8_t mcs1, uint8_t mcs2, uint8_t mcs3, uint8_t I_mcs, uint8_t mcs_table);
uint8_t get_K_ptrs(uint16_t nrb0, uint16_t nrb1, uint16_t N_RB);
int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config,
NR_MIB_t *mib,
uint8_t extra_bits,
uint32_t ssb_length,
uint32_t ssb_index,
uint32_t ssb_offset_point_a);
void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config,
frame_t frameP,
NR_MIB_t *mib,
uint8_t num_slot_per_frame,
uint8_t ssb_subcarrier_offset,
uint16_t ssb_start_symbol,
NR_SubcarrierSpacing_t scs_ssb,
frequency_range_t frequency_range,
uint32_t ssb_index,
uint32_t ssb_offset_point_a);
uint16_t get_ssb_start_symbol(const long band, NR_SubcarrierSpacing_t scs, int i_ssb);
int16_t get_N_RA_RB (int delta_f_RA_PRACH,int delta_f_PUSCH);
......
......@@ -318,7 +318,7 @@ typedef struct {
NR_TAG_Config_t *tag_Config;
NR_PHR_Config_t *phr_Config;
NR_RNTI_Value_t *cs_RNTI;
NR_MIB_t *mib;
NR_MIB_t *mib;
NR_BWP_Downlink_t *DLbwp[MAX_NUM_BWP];
NR_BWP_Uplink_t *ULbwp[MAX_NUM_BWP];
......
......@@ -104,7 +104,8 @@ int8_t nr_ue_decode_mib(module_id_t module_id,
LOG_D(MAC,"[L2][MAC] decode mib\n");
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
NR_ServingCellConfigCommon_t *scc = mac->scc;
frequency_range_t frequency_range;
nr_mac_rrc_data_ind_ue( module_id, cc_id, gNB_index, NR_BCCH_BCH, (uint8_t *) pduP, 3 ); // fixed 3 bytes MIB PDU
AssertFatal(mac->mib != NULL, "nr_ue_decode_mib() mac->mib == NULL\n");
......@@ -120,9 +121,11 @@ int8_t nr_ue_decode_mib(module_id_t module_id,
frame = frame << 4;
frame = frame | frame_number_4lsb;
if(ssb_length == 64){
frequency_range = FR2;
for (int i=0; i<3; i++)
ssb_index += (((extra_bits>>(7-i))&0x01)<<(3+i));
}else{
frequency_range = FR1;
if(ssb_subcarrier_offset_msb){
ssb_subcarrier_offset = ssb_subcarrier_offset | 0x10;
}
......@@ -141,13 +144,37 @@ int8_t nr_ue_decode_mib(module_id_t module_id,
//storing ssb index in the mac structure
mac->mib_ssb = ssb_index;
get_type0_PDCCH_CSS_config_parameters(&mac->type0_PDCCH_CSS_config, mac->mib, extra_bits, ssb_length, ssb_index,
mac->phy_config.config_req.ssb_table.ssb_offset_point_a);
if (get_softmodem_params()->sa == 1) {
// TODO these values shouldn't be taken from SCC in SA
uint8_t scs_ssb = *scc->ssbSubcarrierSpacing;
uint32_t band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
int scs_scaling = 1<<scs_ssb;
if (scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA < 600000)
scs_scaling = scs_scaling*3;
if (scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA > 2016666)
scs_scaling = scs_scaling>>2;
uint32_t absolute_diff = (*scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB - scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA);
uint16_t ssb_start_symbol = get_ssb_start_symbol(band,scs_ssb,ssb_index);
get_type0_PDCCH_CSS_config_parameters(&mac->type0_PDCCH_CSS_config,
frame,
mac->mib,
nr_slots_per_frame[scs_ssb],
ssb_subcarrier_offset,
ssb_start_symbol,
scs_ssb,
frequency_range,
ssb_index,
absolute_diff/(12*scs_scaling)-10);
mac->type0_pdcch_ss_mux_pattern = mac->type0_PDCCH_CSS_config.type0_pdcch_ss_mux_pattern;
mac->type0_pdcch_ss_sfn_c = mac->type0_PDCCH_CSS_config.sfn_c;
mac->type0_pdcch_ss_n_c = mac->type0_PDCCH_CSS_config.n_c;
}
ssb_index = mac->type0_PDCCH_CSS_config.ssb_index; // TODO: ssb_index should obtain from L1 in case Lssb != 64
mac->type0_pdcch_ss_mux_pattern = mac->type0_PDCCH_CSS_config.type0_pdcch_ss_mux_pattern;
mac->type0_pdcch_ss_sfn_c = mac->type0_PDCCH_CSS_config.sfn_c;
mac->type0_pdcch_ss_n_c = mac->type0_PDCCH_CSS_config.n_c;
mac->dl_config_request.sfn = mac->type0_PDCCH_CSS_config.frame;
mac->dl_config_request.slot = (ssb_index>>1) + ((ssb_index>>4)<<1); // not valid for 240kHz SCS
......
......@@ -54,7 +54,7 @@ extern RAN_CONTEXT_t RC;
extern void mac_top_init_gNB(void);
extern uint8_t nfapi_mode;
void config_common(int Mod_idP, int pdsch_AntennaPorts, int pusch_AntennaPorts, NR_ServingCellConfigCommon_t *scc) {
void config_common(int Mod_idP, int ssb_SubcarrierOffset, int pdsch_AntennaPorts, int pusch_AntennaPorts, NR_ServingCellConfigCommon_t *scc) {
nfapi_nr_config_request_scf_t *cfg = &RC.nrmac[Mod_idP]->config[0];
RC.nrmac[Mod_idP]->common_channels[0].ServingCellConfigCommon = scc;
......@@ -240,6 +240,9 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, int pusch_AntennaPorts,
cfg->ssb_table.ssb_period.value = *scc->ssb_periodicityServingCell;
cfg->ssb_table.ssb_period.tl.tag = NFAPI_NR_CONFIG_SSB_PERIOD_TAG;
cfg->num_tlv++;
cfg->ssb_table.ssb_subcarrier_offset.value = ssb_SubcarrierOffset;
cfg->ssb_table.ssb_subcarrier_offset.tl.tag = NFAPI_NR_CONFIG_SSB_SUBCARRIER_OFFSET_TAG;
cfg->num_tlv++;
switch (scc->ssb_PositionsInBurst->present) {
case 1 :
......@@ -376,6 +379,7 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
LOG_I(MAC,"Configuring common parameters from NR ServingCellConfig\n");
config_common(Mod_idP,
ssb_SubcarrierOffset,
pdsch_AntennaPorts,
pusch_AntennaPorts,
scc);
......@@ -389,7 +393,8 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
printf("Waiting for PHY_config_req\n");
}
}
RC.nrmac[Mod_idP]->ssb_SubcarrierOffset = ssb_SubcarrierOffset;
RC.nrmac[Mod_idP]->pusch_target_snrx10 = pusch_tgt_snrx10;
RC.nrmac[Mod_idP]->pucch_target_snrx10 = pucch_tgt_snrx10;
NR_PHY_Config_t phycfg;
......@@ -397,10 +402,6 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
phycfg.CC_id = 0;
phycfg.cfg = &RC.nrmac[Mod_idP]->config[0];
phycfg.cfg->ssb_table.ssb_subcarrier_offset.value = ssb_SubcarrierOffset;
phycfg.cfg->ssb_table.ssb_subcarrier_offset.tl.tag = NFAPI_NR_CONFIG_SSB_SUBCARRIER_OFFSET_TAG;
phycfg.cfg->num_tlv++;
if (RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req) RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req(&phycfg);
find_SSB_and_RO_available(Mod_idP);
......
......@@ -1816,6 +1816,7 @@ void mac_remove_nr_ue(module_id_t mod_id, rnti_t rnti)
{
int UE_id;
int i;
int cc_id;
NR_UE_info_t *UE_info = &RC.nrmac[mod_id]->UE_info;
for (i = 0; i < MAX_MOBILES_PER_GNB; i++) {
......@@ -1852,6 +1853,20 @@ void mac_remove_nr_ue(module_id_t mod_id, rnti_t rnti)
rnti_to_remove_count++;
if (pthread_mutex_unlock(&rnti_to_remove_mutex)) exit(1);
}
/* clear RA process(es?) associated to the UE */
for (cc_id = 0; cc_id < NFAPI_CC_MAX; cc_id++) {
NR_COMMON_channels_t *cc = &RC.nrmac[mod_id]->common_channels[cc_id];
for (i = 0; i < NR_NB_RA_PROC_MAX; i++) {
if (cc->ra[i].rnti == rnti) {
LOG_D(MAC, "free RA process %d for rnti %d\n", i, rnti);
/* is it enough? */
cc->ra[i].cfra = false;
cc->ra[i].rnti = 0;
cc->ra[i].crnti = 0;
}
}
}
}
uint8_t nr_get_tpc(int target, uint8_t cqi, int incr) {
......
......@@ -41,6 +41,7 @@ void set_cset_offset(uint16_t);
void mac_top_init_gNB(void);
void config_common(int Mod_idP,
int ssb_SubcarrierOffset,
int pdsch_AntennaPorts,
int pusch_AntennaPorts,
NR_ServingCellConfigCommon_t *scc
......@@ -78,6 +79,7 @@ nr_pp_impl_dl nr_init_fr1_dlsch_preprocessor(module_id_t module_id, int CC_id);
void schedule_control_sib1(module_id_t module_id,
int CC_id,
NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config,
int time_domain_allocation,
uint8_t mcsTableIdx,
uint8_t mcs,
......@@ -349,7 +351,7 @@ int binomial(int n, int k);
bool is_xlsch_in_slot(uint64_t bitmap, sub_frame_t slot);
void fill_ssb_vrb_map (NR_COMMON_channels_t *cc, int rbStart, int CC_id);
void fill_ssb_vrb_map (NR_COMMON_channels_t *cc, int rbStart, uint16_t symStart, int CC_id);
/* \brief Function to indicate a received SDU on ULSCH.
......
......@@ -648,6 +648,8 @@ typedef struct gNB_MAC_INST_s {
int pusch_target_snrx10;
/// Pucch target SNR
int pucch_target_snrx10;
/// Subcarrier Offset
int ssb_SubcarrierOffset;
/// Common cell resources
NR_COMMON_channels_t common_channels[NFAPI_CC_MAX];
/// current PDU index (BCH,DLSCH)
......@@ -727,7 +729,7 @@ typedef struct gNB_MAC_INST_s {
NR_UE_sched_ctrl_t *sched_ctrlCommon;
NR_CellGroupConfig_t *secondaryCellGroupCommon;
NR_Type0_PDCCH_CSS_config_t type0_PDCCH_CSS_config;
NR_Type0_PDCCH_CSS_config_t type0_PDCCH_CSS_config[64];
} gNB_MAC_INST;
......
......@@ -26,6 +26,7 @@
#include <string.h>
#include "nr_pdcp_security_nea2.h"
#include "nr_pdcp_integrity_nia2.h"
#include "nr_pdcp_sdu.h"
#include "LOG/log.h"
......@@ -54,17 +55,21 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity,
}
if (entity->sn_size == 12) {
rcvd_sn = (((unsigned char)buffer[0] & 0xf) << 8) |
(unsigned char)buffer[1];
rcvd_sn = ((buffer[0] & 0xf) << 8) |
buffer[1];
header_size = 2;
} else {
rcvd_sn = (((unsigned char)buffer[0] & 0x3) << 16) |
((unsigned char)buffer[1] << 8) |
(unsigned char)buffer[2];
rcvd_sn = ((buffer[0] & 0x3) << 16) |
(buffer[1] << 8) |
buffer[2];
header_size = 3;
}
integrity_size = 0;
if (entity->has_integrity) {
integrity_size = 4;
} else {
integrity_size = 0;
}
if (size < header_size + integrity_size + 1) {
LOG_E(PDCP, "bad PDU received (size = %d)\n", size);
......@@ -86,9 +91,20 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity,
if (entity->has_ciphering)
entity->cipher(entity->security_context,
(unsigned char *)buffer+header_size, size-header_size,
buffer+header_size, size-header_size,
entity->rb_id, rcvd_count, entity->is_gnb ? 0 : 1);
if (entity->has_integrity) {
unsigned char integrity[4];
entity->integrity(entity->integrity_context, integrity,
buffer, size - integrity_size,
entity->rb_id, rcvd_count, entity->is_gnb ? 0 : 1);
if (memcmp(integrity, buffer, 4) != 0) {
LOG_E(PDCP, "discard NR PDU, integrity failed\n");
return;
}
}
if (rcvd_count < entity->rx_deliv
|| nr_pdcp_sdu_in_list(entity->rx_list, rcvd_count)) {
LOG_D(PDCP, "discard NR PDU rcvd_count=%d\n", rcvd_count);
......@@ -139,39 +155,62 @@ static void nr_pdcp_entity_recv_sdu(nr_pdcp_entity_t *entity,
uint32_t count;
int sn;
int header_size;
char buf[size+3+4];
int integrity_size;
char buf[size + 3 + 4];
int dc_bit;
count = entity->tx_next;
sn = entity->tx_next & entity->sn_max;
/* D/C bit is only to be set for DRBs */
if (entity->type == NR_PDCP_DRB_AM || entity->type == NR_PDCP_DRB_UM) {
dc_bit = 0x80;
} else {
dc_bit = 0;
}
if (entity->sn_size == 12) {
buf[0] = 0x80 | ((sn >> 8) & 0xf);
buf[0] = dc_bit | ((sn >> 8) & 0xf);
buf[1] = sn & 0xff;
header_size = 2;
} else {
buf[0] = 0x80 | ((sn >> 16) & 0x3);
buf[0] = dc_bit | ((sn >> 16) & 0x3);
buf[1] = (sn >> 8) & 0xff;
buf[2] = sn & 0xff;
header_size = 3;
}
memcpy(buf+header_size, buffer, size);
if (entity->has_integrity) {
integrity_size = 4;
} else {
integrity_size = 0;
}
memcpy(buf + header_size, buffer, size);
if (entity->has_integrity)
entity->integrity(entity->integrity_context,
(unsigned char *)buf + header_size + size,
(unsigned char *)buf, header_size + size,
entity->rb_id, count, entity->is_gnb ? 1 : 0);
if (entity->has_ciphering)
entity->cipher(entity->security_context,
(unsigned char *)buf+header_size, size,
(unsigned char *)buf + header_size, size + integrity_size,
entity->rb_id, count, entity->is_gnb ? 1 : 0);
entity->tx_next++;
entity->deliver_pdu(entity->deliver_pdu_data, entity, buf,
size+header_size, sdu_id);
header_size + size + integrity_size, sdu_id);
}
static void nr_pdcp_entity_set_integrity_key(nr_pdcp_entity_t *entity,
char *key)
{
memcpy(entity->integrity_key, key, 16);
LOG_E(PDCP, "%s: %d: %s: TODO? to remove?\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
//memcpy(entity->integrity_key, key, 16);
}
static void check_t_reordering(nr_pdcp_entity_t *entity)
......@@ -232,6 +271,8 @@ void nr_pdcp_entity_delete(nr_pdcp_entity_t *entity)
}
if (entity->free_security != NULL)
entity->free_security(entity->security_context);
if (entity->free_integrity != NULL)
entity->free_integrity(entity->integrity_context);
free(entity);
}
......@@ -298,9 +339,18 @@ nr_pdcp_entity_t *new_nr_pdcp_entity(
}
ret->is_gnb = is_gnb;
if (integrity_key != NULL) {
printf("%s:%d:%s: TODO\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
if (integrity_key != NULL && integrity_algorithm != 0) {
if (integrity_algorithm != 2) {
LOG_E(PDCP, "FATAL: only nia2 supported for the moment\n");
exit(1);
}
ret->has_integrity = 1;
ret->integrity_algorithm = integrity_algorithm;
memcpy(ret->integrity_key, integrity_key, 16);
ret->integrity_context = nr_pdcp_integrity_nia2_init(integrity_key);
ret->integrity = nr_pdcp_integrity_nia2_integrity;
ret->free_integrity = nr_pdcp_integrity_nia2_free_integrity;
}
return ret;
......
......@@ -85,7 +85,12 @@ typedef struct nr_pdcp_entity_t {
unsigned char *buffer, int length,
int bearer, int count, int direction);
void (*free_security)(void *security_context);
/* security algorithms need to know uplink/downlink information
void *integrity_context;
void (*integrity)(void *integrity_context, unsigned char *out,
unsigned char *buffer, int length,
int bearer, int count, int direction);
void (*free_integrity)(void *integrity_context);
/* security/integrity algorithms need to know uplink/downlink information
* which is reverse for gnb and ue, so we need to know if this
* pdcp entity is for a gnb or an ue
*/
......
/*
* 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
*/
#include "nr_pdcp_integrity_nia2.h"
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <openssl/cmac.h>
void *nr_pdcp_integrity_nia2_init(unsigned char *integrity_key)
{
CMAC_CTX *ctx;
ctx = CMAC_CTX_new();
if (ctx == NULL) abort();
CMAC_Init(ctx, integrity_key, 16, EVP_aes_128_cbc(), NULL);
return ctx;
}
static void compute_t(unsigned char *t, uint32_t count, int bearer,
int direction)
{
t[0] = (count >> 24) & 255;
t[1] = (count >> 16) & 255;
t[2] = (count >> 8) & 255;
t[3] = (count ) & 255;
t[4] = (bearer << 3) | (direction << 2);
memset(&t[5], 0, 8-5);
}
void nr_pdcp_integrity_nia2_integrity(void *integrity_context,
unsigned char *out,
unsigned char *buffer, int length,
int bearer, int count, int direction)
{
CMAC_CTX *ctx = integrity_context;
unsigned char t[8];
unsigned char mac[16];
size_t maclen;
/* see 33.401 B.2.3 for the input to 128-EIA2
* (which is identical to 128-NIA2, see 33.501 D.3.1.3) */
compute_t(t, count, bearer, direction);
CMAC_Update(ctx, t, 8);
CMAC_Update(ctx, buffer, length);
CMAC_Final(ctx, mac, &maclen);
/* AES CMAC (RFC 4493) outputs 128 bits but NR PDCP PDUs have a MAC-I of
* 32 bits (see 38.323 6.2). RFC 4493 2.1 says to truncate most significant
* bit first (so seems to say 33.401 B.2.3)
*/
memcpy(out, mac, 4);
}
void nr_pdcp_integrity_nia2_free_integrity(void *integrity_context)
{
CMAC_CTX *ctx = integrity_context;
CMAC_CTX_free(ctx);
}
/*
* 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
*/
#ifndef _NR_PDCP_INTEGRITY_NIA2_H_
#define _NR_PDCP_INTEGRITY_NIA2_H_
void *nr_pdcp_integrity_nia2_init(unsigned char *integrity_key);
void nr_pdcp_integrity_nia2_integrity(void *integrity_context,
unsigned char *out,
unsigned char *buffer, int length,
int bearer, int count, int direction);
void nr_pdcp_integrity_nia2_free_integrity(void *integrity_context);
#endif /* _NR_PDCP_INTEGRITY_NIA2_H_ */
......@@ -650,7 +650,7 @@ control:
control_decoder = decoder;
control_e1 = e1;
while (control_e1) {
nr_rlc_pdu_decoder_get_bits(&control_decoder, entity->sn_field_length); R(control_decoder); /* NACK_SN */
nack_sn = nr_rlc_pdu_decoder_get_bits(&control_decoder, entity->sn_field_length); R(control_decoder);
control_e1 = nr_rlc_pdu_decoder_get_bits(&control_decoder, 1); R(control_decoder);
control_e2 = nr_rlc_pdu_decoder_get_bits(&control_decoder, 1); R(control_decoder);
control_e3 = nr_rlc_pdu_decoder_get_bits(&control_decoder, 1); R(control_decoder);
......@@ -660,17 +660,36 @@ control:
} else {
nr_rlc_pdu_decoder_get_bits(&control_decoder, 1); R(control_decoder);
}
/* check range and so_start/so_end consistency */
if (control_e2) {
nr_rlc_pdu_decoder_get_bits(&control_decoder, 16); R(control_decoder); /* SOstart */
nr_rlc_pdu_decoder_get_bits(&control_decoder, 16); R(control_decoder); /* SOend */
so_start = nr_rlc_pdu_decoder_get_bits(&control_decoder, 16); R(control_decoder);
so_end = nr_rlc_pdu_decoder_get_bits(&control_decoder, 16); R(control_decoder);
} else {
so_start = 0;
so_end = 0xffff;
}
if (control_e3) {
nr_rlc_pdu_decoder_get_bits(&control_decoder, 8); R(control_decoder); /* NACK range */
range = nr_rlc_pdu_decoder_get_bits(&control_decoder, 8); R(control_decoder);
} else {
range = 1;
}
if (range < 1) {
LOG_E(RLC, "%s:%d:%s: error, bad 'range' in RLC NACK (sn %d)\n",
__FILE__, __LINE__, __FUNCTION__, nack_sn);
goto err;
}
/* so_start can be > so_end if more than one range; they don't refer
* to the same PDU then
*/
if (range == 1 && so_end < so_start) {
LOG_E(RLC, "%s:%d:%s: error, bad so start/end (sn %d)\n",
__FILE__, __LINE__, __FUNCTION__, nack_sn);
goto err;
}
}
/* 38.322 5.3.3.3 says to stop t_poll_retransmit if a ACK or NACK is
* received for the SN 'poll_sn'
* received for the SN 'poll_sn' - check ACK case (NACK done below)
*/
if (sn_compare_tx(entity, entity->poll_sn, ack_sn) < 0)
entity->t_poll_retransmit_start = 0;
......@@ -697,28 +716,22 @@ control:
if (e2) {
so_start = nr_rlc_pdu_decoder_get_bits(&decoder, 16); R(decoder);
so_end = nr_rlc_pdu_decoder_get_bits(&decoder, 16); R(decoder);
if (so_end < so_start) {
LOG_W(RLC, "%s:%d:%s: warning, bad so start/end, NACK the whole PDU (sn %d)\n",
__FILE__, __LINE__, __FUNCTION__, nack_sn);
so_start = 0;
so_end = -1;
}
/* special value 0xffff indicates 'all bytes to the end' */
if (so_end == 0xffff)
so_end = -1;
} else {
so_start = 0;
so_end = -1;
so_end = 0xffff;
}
if (e3) {
range = nr_rlc_pdu_decoder_get_bits(&decoder, 8); R(decoder);
} else {
range = 1;
}
/* special value 0xffff indicates 'all bytes to the end' */
if (so_end == 0xffff)
so_end = -1;
process_received_nack(entity, nack_sn, so_start, so_end, range, sn_set);
/* 38.322 5.3.3.3 says to stop t_poll_retransmit if a ACK or NACK is
* received for the SN 'poll_sn'
* received for the SN 'poll_sn' - check NACK case (ACK done above)
*/
if (sn_compare_tx(entity, nack_sn, entity->poll_sn) <= 0 &&
sn_compare_tx(entity, entity->poll_sn, (nack_sn + range) % entity->sn_modulus) < 0)
......
#!/bin/sh
test_count=14
test_count=15
for i in `seq $test_count`
do
......
/*
* am test (SN field size 18):
* test "range" in NACK, generate a case where so_start > so_end
* (so so_start and so_end are not from the same PDU)
*/
TIME, 1,
GNB_AM, 100000, 100000, 45, 35, 0, -1, -1, 8, 18,
UE_AM, 100000, 100000, 45, 35, 0, -1, -1, 8, 18,
GNB_PDU_SIZE, 40,
UE_PDU_SIZE, 80,
GNB_SDU, 0, 50,
GNB_SDU, 1, 50,
GNB_SDU, 2, 50,
TIME, 2,
UE_RECV_FAILS, 1,
TIME, 4,
UE_RECV_FAILS, 0,
TIME, -1
File added
......@@ -67,6 +67,8 @@
#define MAX_NUM_NEIGH_CELLs 6 /* maximum neighbouring cells number */
#define MAX_NUM_GNB_CELLs 1 /* maximum gNB cells number */
#define UE_STATE_NOTIFICATION_INTERVAL 50
#define IPV4_ADDR "%u.%u.%u.%u"
......@@ -804,8 +806,13 @@ typedef struct eNB_RRC_INST_s {
int num_neigh_cells_cc[MAX_NUM_CCs];
uint32_t neigh_cells_id[MAX_NUM_NEIGH_CELLs][MAX_NUM_CCs];
// gNB cells connected to this eNB
int num_gnb_cells;
int num_gnb_cells_cc[MAX_NUM_GNB_CELLs];
uint32_t gnb_cells_id[MAX_NUM_GNB_CELLs][MAX_NUM_CCs];
// Nr scc freq band and SSB absolute frequency
uint32_t nr_neigh_freq_band[MAX_NUM_NEIGH_CELLs][MAX_NUM_CCs];
uint32_t nr_gnb_freq_band[MAX_NUM_GNB_CELLs][MAX_NUM_CCs];
int nr_scg_ssb_freq;
// other RAN parameters
......
......@@ -1283,7 +1283,7 @@ rrc_eNB_generate_UECapabilityEnquiry(
T(T_ENB_RRC_UE_CAPABILITY_ENQUIRY, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
int16_t eutra_band = RC.rrc[ctxt_pP->module_id]->configuration.eutra_band[0];
uint32_t nr_band = RC.rrc[ctxt_pP->module_id]->nr_neigh_freq_band[0][0];
uint32_t nr_band = RC.rrc[ctxt_pP->module_id]->nr_gnb_freq_band[0][0];
size = do_UECapabilityEnquiry(
ctxt_pP,
buffer,
......@@ -1333,7 +1333,7 @@ rrc_eNB_generate_NR_UECapabilityEnquiry(
T(T_ENB_RRC_UE_CAPABILITY_ENQUIRY, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
int16_t eutra_band = RC.rrc[ctxt_pP->module_id]->configuration.eutra_band[0];
uint32_t nr_band = RC.rrc[ctxt_pP->module_id]->nr_neigh_freq_band[0][0];
uint32_t nr_band = RC.rrc[ctxt_pP->module_id]->nr_gnb_freq_band[0][0];
size = do_NR_UECapabilityEnquiry(
ctxt_pP,
buffer,
......@@ -7588,8 +7588,8 @@ is_en_dc_supported(
)
//-----------------------------------------------------------------------------
{
/* to be refined - check that the eNB is connected to a gNB, check that
* the bands supported by the UE include the band of the gNB
/* to be refined - check that the bands supported by the UE include
* the band of the gNB
*/
#define NCE nonCriticalExtension
return c != NULL
......@@ -8289,8 +8289,13 @@ rrc_eNB_decode_dcch(
ue_context_p->ue_context.UE_Capability = 0;
}
if (dec_rval.code == RC_OK)
ue_context_p->ue_context.does_nr = is_en_dc_supported(ue_context_p->ue_context.UE_Capability);
if (dec_rval.code == RC_OK) {
/* do NR only if at least one gNB connected */
if (RC.rrc[ctxt_pP->module_id]->num_gnb_cells != 0)
ue_context_p->ue_context.does_nr = is_en_dc_supported(ue_context_p->ue_context.UE_Capability);
else
ue_context_p->ue_context.does_nr = 0;
}
if (EPC_MODE_ENABLED) {
rrc_eNB_send_S1AP_UE_CAPABILITIES_IND(ctxt_pP,
......@@ -9029,22 +9034,22 @@ void rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) {
}
void rrc_eNB_process_ENDC_x2_setup_request(int mod_id, x2ap_ENDC_setup_req_t *m) {
if (RC.rrc[mod_id]->num_neigh_cells > MAX_NUM_NEIGH_CELLs) {
LOG_E(RRC, "Error: number of neighbouring cells is exceeded \n");
if (RC.rrc[mod_id]->num_gnb_cells >= MAX_NUM_GNB_CELLs) {
LOG_E(RRC, "Error: number of gNB cells is exceeded\n");
return;
}
if (m->num_cc > MAX_NUM_CCs) {
LOG_E(RRC, "Error: number of neighbouring cells carriers is exceeded \n");
LOG_E(RRC, "Error: number of gNB cells carriers is exceeded \n");
return;
}
RC.rrc[mod_id]->num_neigh_cells++;
RC.rrc[mod_id]->num_neigh_cells_cc[RC.rrc[mod_id]->num_neigh_cells-1] = m->num_cc;
RC.rrc[mod_id]->num_gnb_cells++;
RC.rrc[mod_id]->num_gnb_cells_cc[RC.rrc[mod_id]->num_gnb_cells-1] = m->num_cc;
for (int i=0; i<m->num_cc; i++) {
RC.rrc[mod_id]->neigh_cells_id[RC.rrc[mod_id]->num_neigh_cells-1][i] = m->Nid_cell[i];
RC.rrc[mod_id]->nr_neigh_freq_band[RC.rrc[mod_id]->num_neigh_cells-1][i] = m->servedNrCell_band[i];
RC.rrc[mod_id]->gnb_cells_id[RC.rrc[mod_id]->num_gnb_cells-1][i] = m->Nid_cell[i];
RC.rrc[mod_id]->nr_gnb_freq_band[RC.rrc[mod_id]->num_gnb_cells-1][i] = m->servedNrCell_band[i];
}
}
......
......@@ -48,7 +48,8 @@ typedef enum {
NAS_INT_ALG = 0x02,
RRC_ENC_ALG = 0x03,
RRC_INT_ALG = 0x04,
UP_ENC_ALG = 0x05
UP_ENC_ALG = 0x05,
UP_INT_ALG = 0x06
} algorithm_type_dist_t;
//int derive_keNB(const uint8_t kasme[32], const uint32_t nas_count, uint8_t **keNB);
......
......@@ -116,9 +116,7 @@ void x2ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa
/* some sanity check - to be refined at some point */
if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) {
X2AP_ERROR("x2ap_enb_data_p not NULL and sctp state not SCTP_STATE_ESTABLISHED, what to do?\n");
// Allow for a gracious exit when we kill first the gNB, then the eNB
//abort();
return;
exit(1);
}
x2ap_enb_data_p->in_streams = sctp_new_association_resp->in_streams;
......
......@@ -690,9 +690,11 @@ int x2ap_eNB_handle_x2_setup_failure(instance_t instance,
// need a FSM to handle all cases
if ((ie->value.choice.Cause.present == X2AP_Cause_PR_misc) &&
(ie->value.choice.Cause.choice.misc == X2AP_CauseMisc_unspecified)) {
X2AP_WARN("Received X2 setup failure for eNB ... eNB is not ready\n");
X2AP_ERROR("Received X2 setup failure for eNB ... eNB is not ready\n");
exit(1);
} else {
X2AP_ERROR("Received x2 setup failure for eNB... please check your parameters\n");
exit(1);
}
x2ap_eNB_data->state = X2AP_ENB_STATE_WAITING;
......
......@@ -23,6 +23,7 @@ gNBs =
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
pusch_AntennaPorts = 1;
pusch_TargetSNRx10 = 200;
pucch_TargetSNRx10 = 200;
......
......@@ -172,7 +172,7 @@ gNBs =
nrofUplinkSlots = 2;
nrofUplinkSymbols = 4;
ssPBCH_BlockPower = 10;
ssPBCH_BlockPower = -25;
}
);
......
......@@ -171,7 +171,7 @@ gNBs =
nrofUplinkSlots = 10;
nrofUplinkSymbols = 0;
ssPBCH_BlockPower = 10;
ssPBCH_BlockPower = -25;
}
);
......
......@@ -172,7 +172,7 @@ gNBs =
nrofUplinkSlots = 2;
nrofUplinkSymbols = 4;
ssPBCH_BlockPower = 10;
ssPBCH_BlockPower = -25;
}
);
......
......@@ -171,7 +171,7 @@ gNBs =
nrofUplinkSlots = 2;
nrofUplinkSymbols = 4;
ssPBCH_BlockPower = 10;
ssPBCH_BlockPower = -25;
}
);
......
......@@ -171,7 +171,7 @@ gNBs =
nrofUplinkSlots = 2;
nrofUplinkSymbols = 4;
ssPBCH_BlockPower = 10;
ssPBCH_BlockPower = -25;
}
);
......
......@@ -170,7 +170,7 @@ gNBs =
nrofUplinkSlots = 2;
nrofUplinkSymbols = 4;
ssPBCH_BlockPower = 10;
ssPBCH_BlockPower = -25;
}
);
......
......@@ -186,7 +186,7 @@ gNBs =
nrofUplinkSlots = 2;
nrofUplinkSymbols = 4;
ssPBCH_BlockPower = 10;
ssPBCH_BlockPower = -25;
}
);
......
......@@ -170,7 +170,7 @@ gNBs =
nrofUplinkSlots = 2;
nrofUplinkSymbols = 4;
ssPBCH_BlockPower = 10;
ssPBCH_BlockPower = -25;
}
);
......
......@@ -170,7 +170,7 @@ gNBs =
nrofUplinkSlots = 2;
nrofUplinkSymbols = 4;
ssPBCH_BlockPower = 10;
ssPBCH_BlockPower = -25;
}
);
......
......@@ -171,7 +171,7 @@ gNBs =
nrofUplinkSlots = 2;
nrofUplinkSymbols = 4;
ssPBCH_BlockPower = 10;
ssPBCH_BlockPower = -25; // -25 dBm/RE is the maximum measured power from USRP corresponding to att_tx = 0 dB
}
);
......
......@@ -170,7 +170,7 @@ gNBs =
nrofUplinkSlots = 2;
nrofUplinkSymbols = 4;
ssPBCH_BlockPower = 10;
ssPBCH_BlockPower = -25;
}
);
......
......@@ -170,7 +170,7 @@ gNBs =
nrofUplinkSlots = 2;
nrofUplinkSymbols = 4;
ssPBCH_BlockPower = 10;
ssPBCH_BlockPower = -25;
}
);
......
......@@ -187,7 +187,7 @@ gNBs =
nrofUplinkSlots = 2;
nrofUplinkSymbols = 4;
ssPBCH_BlockPower = 10;
ssPBCH_BlockPower = -25;
}
);
......
......@@ -187,7 +187,7 @@ gNBs =
nrofUplinkSlots = 2;
nrofUplinkSymbols = 4;
ssPBCH_BlockPower = 10;
ssPBCH_BlockPower = -25;
}
);
......
......@@ -187,7 +187,7 @@ gNBs =
nrofUplinkSlots = 2;
nrofUplinkSymbols = 4;
ssPBCH_BlockPower = 10;
ssPBCH_BlockPower = -25;
}
);
......
......@@ -170,7 +170,7 @@ gNBs =
nrofUplinkSlots = 2;
nrofUplinkSymbols = 4;
ssPBCH_BlockPower = 10;
ssPBCH_BlockPower = -25;
}
);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment