Merge remote-tracking branch 'origin/develop' into ul-phr
This commit is contained in:
@@ -66,7 +66,7 @@ pipeline {
|
|||||||
withCredentials([
|
withCredentials([
|
||||||
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.DH_Credentials}", usernameVariable: 'DH_Username', passwordVariable: 'DH_Password']
|
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.DH_Credentials}", usernameVariable: 'DH_Username', passwordVariable: 'DH_Password']
|
||||||
]) {
|
]) {
|
||||||
def listOfImages = ["oai-enb", "oai-gnb", "oai-lte-ue", "oai-nr-ue"]
|
def listOfImages = ["oai-enb", "oai-gnb", "oai-lte-ue", "oai-nr-ue", "proxy"]
|
||||||
sh "docker login -u ${DH_Username} -p ${DH_Password} > /dev/null 2>&1"
|
sh "docker login -u ${DH_Username} -p ${DH_Password} > /dev/null 2>&1"
|
||||||
listOfImages.eachWithIndex { item, iindex ->
|
listOfImages.eachWithIndex { item, iindex ->
|
||||||
sh "docker image tag ${item}:develop ${DH_Account}/${item}:develop"
|
sh "docker image tag ${item}:develop ${DH_Account}/${item}:develop"
|
||||||
|
|||||||
@@ -36,6 +36,9 @@ def testStageName = params.pipelineTestStageName
|
|||||||
// Name of the phone resource
|
// Name of the phone resource
|
||||||
def ciSmartPhoneResource = params.smartphonesResource
|
def ciSmartPhoneResource = params.smartphonesResource
|
||||||
|
|
||||||
|
// Name of the phone resource
|
||||||
|
def ciEpcResource = params.epcResource
|
||||||
|
|
||||||
// Global Parameters. Normally they should be populated when the master job
|
// Global Parameters. Normally they should be populated when the master job
|
||||||
// triggers the slave job with parameters
|
// triggers the slave job with parameters
|
||||||
def eNB_Repository
|
def eNB_Repository
|
||||||
@@ -51,7 +54,7 @@ pipeline {
|
|||||||
options {
|
options {
|
||||||
disableConcurrentBuilds()
|
disableConcurrentBuilds()
|
||||||
ansiColor('xterm')
|
ansiColor('xterm')
|
||||||
lock (ciSmartPhoneResource)
|
lock(extra: [[resource: ciEpcResource]], resource: ciSmartPhoneResource)
|
||||||
}
|
}
|
||||||
stages {
|
stages {
|
||||||
stage ("Verify Parameters") {
|
stage ("Verify Parameters") {
|
||||||
@@ -216,6 +219,76 @@ pipeline {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
stage ("Terminate") {
|
||||||
|
parallel {
|
||||||
|
stage('Terminate UE') {
|
||||||
|
// Bypassing this stage if there are no abd server defined
|
||||||
|
when {
|
||||||
|
expression { params.ADB_IPAddress != "none" }
|
||||||
|
}
|
||||||
|
steps {
|
||||||
|
echo '\u2705 \u001B[32mTerminate UE\u001B[0m'
|
||||||
|
withCredentials([
|
||||||
|
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.ADB_Credentials}", usernameVariable: 'ADB_Username', passwordVariable: 'ADB_Password']
|
||||||
|
]) {
|
||||||
|
sh "python3 ci-scripts/main.py --mode=TerminateUE --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage('Terminate eNB') {
|
||||||
|
steps {
|
||||||
|
echo '\u2705 \u001B[32mTerminate eNB\u001B[0m'
|
||||||
|
withCredentials([
|
||||||
|
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password']
|
||||||
|
]) {
|
||||||
|
sh "python3 ci-scripts/main.py --mode=TerminateeNB --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage('Terminate SPGW') {
|
||||||
|
// Bypassing this stage if EPC server is not defined
|
||||||
|
when {
|
||||||
|
expression { params.EPC_IPAddress != "none" }
|
||||||
|
}
|
||||||
|
steps {
|
||||||
|
echo '\u2705 \u001B[32mTerminate SPGW\u001B[0m'
|
||||||
|
withCredentials([
|
||||||
|
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password']
|
||||||
|
]) {
|
||||||
|
sh "python3 ci-scripts/main.py --mode=TerminateSPGW --EPCIPAddress=${params.EPC_IPAddress} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCType=${params.EPC_Type} --EPCSourceCodePath=${params.EPC_SourceCodePath}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage('Terminate MME') {
|
||||||
|
// Bypassing this stage if EPC server is not defined
|
||||||
|
when {
|
||||||
|
expression { params.EPC_IPAddress != "none" }
|
||||||
|
}
|
||||||
|
steps {
|
||||||
|
echo '\u2705 \u001B[32mTerminate MME\u001B[0m'
|
||||||
|
withCredentials([
|
||||||
|
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password']
|
||||||
|
]) {
|
||||||
|
sh "python3 ci-scripts/main.py --mode=TerminateMME --EPCIPAddress=${params.EPC_IPAddress} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCType=${params.EPC_Type} --EPCSourceCodePath=${params.EPC_SourceCodePath}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage('Terminate HSS') {
|
||||||
|
// Bypassing this stage if EPC server is not defined
|
||||||
|
when {
|
||||||
|
expression { params.EPC_IPAddress != "none" }
|
||||||
|
}
|
||||||
|
steps {
|
||||||
|
echo '\u2705 \u001B[32mTerminate HSS\u001B[0m'
|
||||||
|
withCredentials([
|
||||||
|
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password']
|
||||||
|
]) {
|
||||||
|
sh "python3 ci-scripts/main.py --mode=TerminateHSS --EPCIPAddress=${params.EPC_IPAddress} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCType=${params.EPC_Type} --EPCSourceCodePath=${params.EPC_SourceCodePath}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
stage('Log Collection') {
|
stage('Log Collection') {
|
||||||
parallel {
|
parallel {
|
||||||
stage('Log Collection (eNB - Build)') {
|
stage('Log Collection (eNB - Build)') {
|
||||||
@@ -242,7 +315,7 @@ pipeline {
|
|||||||
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password']
|
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password']
|
||||||
]) {
|
]) {
|
||||||
echo '\u2705 \u001B[32mLog Collection (eNB - Run)\u001B[0m'
|
echo '\u2705 \u001B[32mLog Collection (eNB - Run)\u001B[0m'
|
||||||
sh "python3 ci-scripts/main.py --mode=LogCollecteNB --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath}"
|
sh "python3 ci-scripts/main.py --mode=LogCollecteNB --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath} --BuildId=${env.BUILD_ID}"
|
||||||
|
|
||||||
echo '\u2705 \u001B[32mLog Transfer (eNB - Run)\u001B[0m'
|
echo '\u2705 \u001B[32mLog Transfer (eNB - Run)\u001B[0m'
|
||||||
sh "sshpass -p \'${eNB_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${eNB_Username}@${params.eNB_IPAddress}:${eNB_SourceCodePath}/cmake_targets/enb.log.zip ./enb.log.${env.BUILD_ID}.zip || true"
|
sh "sshpass -p \'${eNB_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${eNB_Username}@${params.eNB_IPAddress}:${eNB_SourceCodePath}/cmake_targets/enb.log.zip ./enb.log.${env.BUILD_ID}.zip || true"
|
||||||
@@ -259,6 +332,116 @@ pipeline {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
stage('Log Collection (SPGW)') {
|
||||||
|
// Bypassing this stage if EPC server is not defined
|
||||||
|
when {
|
||||||
|
expression { params.EPC_IPAddress != "none" }
|
||||||
|
}
|
||||||
|
steps {
|
||||||
|
withCredentials([
|
||||||
|
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password']
|
||||||
|
]) {
|
||||||
|
echo '\u2705 \u001B[32mLog Collection (SPGW)\u001B[0m'
|
||||||
|
sh "python3 ci-scripts/main.py --mode=LogCollectSPGW --EPCIPAddress=${params.EPC_IPAddress} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --EPCType=${params.EPC_Type}"
|
||||||
|
|
||||||
|
echo '\u2705 \u001B[32mLog Transfer (SPGW)\u001B[0m'
|
||||||
|
sh "sshpass -p \'${EPC_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${EPC_Username}@${params.EPC_IPAddress}:${EPC_SourceCodePath}/scripts/spgw.log.zip ./spgw.log.${env.BUILD_ID}.zip || true"
|
||||||
|
}
|
||||||
|
script {
|
||||||
|
if(fileExists("spgw.log.${env.BUILD_ID}.zip")) {
|
||||||
|
archiveArtifacts "spgw.log.${env.BUILD_ID}.zip"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage('Log Collection (MME)') {
|
||||||
|
// Bypassing this stage if EPC server is not defined
|
||||||
|
when {
|
||||||
|
expression { params.EPC_IPAddress != "none" }
|
||||||
|
}
|
||||||
|
steps {
|
||||||
|
withCredentials([
|
||||||
|
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password']
|
||||||
|
]) {
|
||||||
|
echo '\u2705 \u001B[32mLog Collection (MME)\u001B[0m'
|
||||||
|
sh "python3 ci-scripts/main.py --mode=LogCollectMME --EPCIPAddress=${params.EPC_IPAddress} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --EPCType=${params.EPC_Type}"
|
||||||
|
|
||||||
|
echo '\u2705 \u001B[32mLog Transfer (MME)\u001B[0m'
|
||||||
|
sh "sshpass -p \'${EPC_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${EPC_Username}@${params.EPC_IPAddress}:${EPC_SourceCodePath}/scripts/mme.log.zip ./mme.log.${env.BUILD_ID}.zip || true"
|
||||||
|
}
|
||||||
|
script {
|
||||||
|
if(fileExists("mme.log.${env.BUILD_ID}.zip")) {
|
||||||
|
archiveArtifacts "mme.log.${env.BUILD_ID}.zip"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage('Log Collection (HSS)') {
|
||||||
|
// Bypassing this stage if EPC server is not defined
|
||||||
|
when {
|
||||||
|
expression { params.EPC_IPAddress != "none" }
|
||||||
|
}
|
||||||
|
steps {
|
||||||
|
withCredentials([
|
||||||
|
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password']
|
||||||
|
]) {
|
||||||
|
echo '\u2705 \u001B[32mLog Collection (HSS)\u001B[0m'
|
||||||
|
sh "python3 ci-scripts/main.py --mode=LogCollectHSS --EPCIPAddress=${params.EPC_IPAddress} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --EPCType=${params.EPC_Type}"
|
||||||
|
|
||||||
|
echo '\u2705 \u001B[32mLog Transfer (HSS)\u001B[0m'
|
||||||
|
sh "sshpass -p \'${EPC_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${EPC_Username}@${params.EPC_IPAddress}:${EPC_SourceCodePath}/scripts/hss.log.zip ./hss.log.${env.BUILD_ID}.zip || true"
|
||||||
|
}
|
||||||
|
script {
|
||||||
|
if(fileExists("hss.log.${env.BUILD_ID}.zip")) {
|
||||||
|
archiveArtifacts "hss.log.${env.BUILD_ID}.zip"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage('Log Collection (Ping)') {
|
||||||
|
// Bypassing this stage if EPC server is not defined
|
||||||
|
when {
|
||||||
|
expression { params.EPC_IPAddress != "none" }
|
||||||
|
}
|
||||||
|
steps {
|
||||||
|
withCredentials([
|
||||||
|
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password']
|
||||||
|
]) {
|
||||||
|
echo '\u2705 \u001B[32mLog Collection (Ping)\u001B[0m'
|
||||||
|
sh "python3 ci-scripts/main.py --mode=LogCollectPing --EPCIPAddress=${params.EPC_IPAddress} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --EPCType=${params.EPC_Type}"
|
||||||
|
|
||||||
|
echo '\u2705 \u001B[32mLog Transfer (Ping)\u001B[0m'
|
||||||
|
sh "sshpass -p \'${EPC_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${EPC_Username}@${params.EPC_IPAddress}:${EPC_SourceCodePath}/scripts/ping.log.zip ./ping.log.${env.BUILD_ID}.zip || true"
|
||||||
|
}
|
||||||
|
script {
|
||||||
|
if(fileExists("ping.log.${env.BUILD_ID}.zip")) {
|
||||||
|
archiveArtifacts "ping.log.${env.BUILD_ID}.zip"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage('Log Collection (Iperf)') {
|
||||||
|
// Bypassing this stage if EPC server is not defined
|
||||||
|
when {
|
||||||
|
expression { params.EPC_IPAddress != "none" }
|
||||||
|
}
|
||||||
|
steps {
|
||||||
|
withCredentials([
|
||||||
|
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password']
|
||||||
|
]) {
|
||||||
|
echo '\u2705 \u001B[32mLog Collection (Iperf)\u001B[0m'
|
||||||
|
sh "python3 ci-scripts/main.py --mode=LogCollectIperf --EPCIPAddress=${params.EPC_IPAddress} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --EPCType=${params.EPC_Type}"
|
||||||
|
|
||||||
|
echo '\u2705 \u001B[32mLog Transfer (Iperf)\u001B[0m'
|
||||||
|
sh "sshpass -p \'${EPC_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${EPC_Username}@${params.EPC_IPAddress}:${EPC_SourceCodePath}/scripts/iperf.log.zip ./iperf.log.${env.BUILD_ID}.zip || true"
|
||||||
|
}
|
||||||
|
script {
|
||||||
|
if(fileExists("iperf.log.${env.BUILD_ID}.zip")) {
|
||||||
|
archiveArtifacts "iperf.log.${env.BUILD_ID}.zip"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,9 @@
|
|||||||
* contact@openairinterface.org
|
* contact@openairinterface.org
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// necessary for reading JSON
|
||||||
|
import groovy.json.JsonSlurper
|
||||||
|
|
||||||
// Template Jenkins Declarative Pipeline script to run Test w/ RF HW
|
// Template Jenkins Declarative Pipeline script to run Test w/ RF HW
|
||||||
|
|
||||||
// Location of the python executor node shall be in the same subnet as the others servers
|
// Location of the python executor node shall be in the same subnet as the others servers
|
||||||
@@ -38,11 +41,11 @@ pipeline {
|
|||||||
stage ("Launcher") {
|
stage ("Launcher") {
|
||||||
steps {
|
steps {
|
||||||
script {
|
script {
|
||||||
//retrieve MR that are opened nd with tag NSA
|
// retrieve MR that are opened nd with tag NSA
|
||||||
MR_LIST= sh returnStdout: true, script: 'curl --silent "https://gitlab.eurecom.fr/api/v4/projects/oai%2Fopenairinterface5g/merge_requests?state=opened&per_page=100&labels=NSA" | jq ".[].iid" || true '
|
MR_LIST = sh returnStdout: true, script: 'curl --silent "https://gitlab.eurecom.fr/api/v4/projects/oai%2Fopenairinterface5g/merge_requests?state=opened&per_page=100&labels=NSA" | jq -cj "[.[].iid]"'
|
||||||
echo "List of selected MR:\n${MR_LIST}"
|
echo "List of selected MRs: ${MR_LIST.trim()}"
|
||||||
def MR_ARRAY = MR_LIST.split('\n')
|
def MR_ARRAY = new JsonSlurper().parseText(MR_LIST.trim())
|
||||||
//for every selected MR, retrieve the branch name and the latest commit
|
// for every selected MR, retrieve the branch name and the latest commit
|
||||||
for (MR in MR_ARRAY) {
|
for (MR in MR_ARRAY) {
|
||||||
SRC_BRANCH=sh returnStdout: true, script: """curl --silent "https://gitlab.eurecom.fr/api/v4/projects/oai%2Fopenairinterface5g/merge_requests/${MR}" | jq ".source_branch" || true """
|
SRC_BRANCH=sh returnStdout: true, script: """curl --silent "https://gitlab.eurecom.fr/api/v4/projects/oai%2Fopenairinterface5g/merge_requests/${MR}" | jq ".source_branch" || true """
|
||||||
SRC_BRANCH=SRC_BRANCH.trim()
|
SRC_BRANCH=SRC_BRANCH.trim()
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ amarisoft_ue_1:
|
|||||||
WakeupScript : none
|
WakeupScript : none
|
||||||
DetachScript : none
|
DetachScript : none
|
||||||
#end
|
#end
|
||||||
Cmd : /root/NV17-12-21/ue/lteue
|
Cmd : /root/NV18-06-2022/ue/lteue
|
||||||
Config : /root/NV17-12-21/ue/config/oaicicd-ue-Ping-SATest.cfg
|
Config : /root/NV17-12-21/ue/config/oaicicd-ue-Ping-SATest.cfg
|
||||||
Duration : 60
|
Duration : 60
|
||||||
Ping : /tmp/test_ue1.log
|
Ping : /tmp/test_ue1.log
|
||||||
@@ -71,7 +71,7 @@ amarisoft_ue_2:
|
|||||||
WakeupScript : none
|
WakeupScript : none
|
||||||
DetachScript : none
|
DetachScript : none
|
||||||
#end
|
#end
|
||||||
Cmd : /root/NV17-12-21/ue/lteue
|
Cmd : /root/NV18-06-2022/ue/lteue
|
||||||
Config : /root/NV17-12-21/ue/config/xxxxxxx.cfg #to be updated for an other scenario
|
Config : /root/NV17-12-21/ue/config/xxxxxxx.cfg #to be updated for an other scenario
|
||||||
Duration : 60
|
Duration : 60
|
||||||
Ping :
|
Ping :
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ class Containerize():
|
|||||||
self.eNB2SourceCodePath = ''
|
self.eNB2SourceCodePath = ''
|
||||||
self.forcedWorkspaceCleanup = False
|
self.forcedWorkspaceCleanup = False
|
||||||
self.imageKind = ''
|
self.imageKind = ''
|
||||||
|
self.proxyCommit = None
|
||||||
self.eNB_instance = 0
|
self.eNB_instance = 0
|
||||||
self.eNB_serverId = ['', '', '']
|
self.eNB_serverId = ['', '', '']
|
||||||
self.yamlPath = ['', '', '']
|
self.yamlPath = ['', '', '']
|
||||||
@@ -421,6 +422,124 @@ class Containerize():
|
|||||||
HTML.CreateHtmlTabFooter(False)
|
HTML.CreateHtmlTabFooter(False)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
def BuildProxy(self, HTML):
|
||||||
|
if self.ranRepository == '' or self.ranBranch == '' or self.ranCommitID == '':
|
||||||
|
HELP.GenericHelp(CONST.Version)
|
||||||
|
sys.exit('Insufficient Parameter')
|
||||||
|
if self.eNB_serverId[self.eNB_instance] == '0':
|
||||||
|
lIpAddr = self.eNBIPAddress
|
||||||
|
lUserName = self.eNBUserName
|
||||||
|
lPassWord = self.eNBPassword
|
||||||
|
lSourcePath = self.eNBSourceCodePath
|
||||||
|
elif self.eNB_serverId[self.eNB_instance] == '1':
|
||||||
|
lIpAddr = self.eNB1IPAddress
|
||||||
|
lUserName = self.eNB1UserName
|
||||||
|
lPassWord = self.eNB1Password
|
||||||
|
lSourcePath = self.eNB1SourceCodePath
|
||||||
|
elif self.eNB_serverId[self.eNB_instance] == '2':
|
||||||
|
lIpAddr = self.eNB2IPAddress
|
||||||
|
lUserName = self.eNB2UserName
|
||||||
|
lPassWord = self.eNB2Password
|
||||||
|
lSourcePath = self.eNB2SourceCodePath
|
||||||
|
if lIpAddr == '' or lUserName == '' or lPassWord == '' or lSourcePath == '':
|
||||||
|
HELP.GenericHelp(CONST.Version)
|
||||||
|
sys.exit('Insufficient Parameter')
|
||||||
|
if self.proxyCommit is None:
|
||||||
|
HELP.GenericHelp(CONST.Version)
|
||||||
|
sys.exit('Insufficient Parameter (need proxyCommit for proxy build)')
|
||||||
|
logging.debug('Building on server: ' + lIpAddr)
|
||||||
|
mySSH = SSH.SSHConnection()
|
||||||
|
mySSH.open(lIpAddr, lUserName, lPassWord)
|
||||||
|
|
||||||
|
# Check that we are on Ubuntu
|
||||||
|
mySSH.command('hostnamectl', '\$', 5)
|
||||||
|
result = re.search('Ubuntu', mySSH.getBefore())
|
||||||
|
self.host = result.group(0)
|
||||||
|
if self.host != 'Ubuntu':
|
||||||
|
logging.error('\u001B[1m Can build proxy only on Ubuntu server\u001B[0m')
|
||||||
|
mySSH.close()
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
self.cli = 'docker'
|
||||||
|
self.cliBuildOptions = '--no-cache'
|
||||||
|
|
||||||
|
# Workaround for some servers, we need to erase completely the workspace
|
||||||
|
if self.forcedWorkspaceCleanup:
|
||||||
|
mySSH.command('echo ' + lPassWord + ' | sudo -S rm -Rf ' + lSourcePath, '\$', 15)
|
||||||
|
|
||||||
|
oldRanCommidID = self.ranCommitID
|
||||||
|
oldRanRepository = self.ranRepository
|
||||||
|
oldRanAllowMerge = self.ranAllowMerge
|
||||||
|
self.ranCommitID = self.proxyCommit
|
||||||
|
self.ranRepository = 'https://github.com/EpiSci/oai-lte-5g-multi-ue-proxy.git'
|
||||||
|
self.ranAllowMerge = False
|
||||||
|
self._createWorkspace(mySSH, lPassWord, lSourcePath)
|
||||||
|
# to prevent accidentally overwriting data that might be used later
|
||||||
|
self.ranCommitID = oldRanCommidID
|
||||||
|
self.ranRepository = oldRanRepository
|
||||||
|
self.ranAllowMerge = oldRanAllowMerge
|
||||||
|
|
||||||
|
# Let's remove any previous run artifacts if still there
|
||||||
|
mySSH.command(self.cli + ' image prune --force', '\$', 30)
|
||||||
|
# Remove any previous proxy image
|
||||||
|
mySSH.command(self.cli + ' image rm oai-lte-multi-ue-proxy:latest || true', '\$', 30)
|
||||||
|
|
||||||
|
tag = self.proxyCommit
|
||||||
|
logging.debug('building L2sim proxy image for tag ' + tag)
|
||||||
|
# check if the corresponding proxy image with tag exists. If not, build it
|
||||||
|
mySSH.command(self.cli + ' image inspect --format=\'Size = {{.Size}} bytes\' proxy:' + tag, '\$', 5)
|
||||||
|
buildProxy = mySSH.getBefore().count('o such image') != 0
|
||||||
|
if buildProxy:
|
||||||
|
mySSH.command(self.cli + ' build ' + self.cliBuildOptions + ' --target oai-lte-multi-ue-proxy --tag proxy:' + tag + ' --file docker/Dockerfile.ubuntu18.04 . > cmake_targets/log/proxy-build.log 2>&1', '\$', 180)
|
||||||
|
# Note: at this point, OAI images are flattened, but we cannot do this
|
||||||
|
# here, as the flatten script is not in the proxy repo
|
||||||
|
mySSH.command(self.cli + ' image inspect --format=\'Size = {{.Size}} bytes\' proxy:' + tag, '\$', 5)
|
||||||
|
if mySSH.getBefore().count('o such image') != 0:
|
||||||
|
logging.error('\u001B[1m Build of L2sim proxy failed\u001B[0m')
|
||||||
|
mySSH.close()
|
||||||
|
HTML.CreateHtmlTestRow('commit ' + tag, 'KO', CONST.ALL_PROCESSES_OK)
|
||||||
|
HTML.CreateHtmlTabFooter(False)
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
logging.debug('L2sim proxy image for tag ' + tag + ' already exists, skipping build')
|
||||||
|
|
||||||
|
# retag the build images to that we pick it up later
|
||||||
|
mySSH.command('docker image tag proxy:' + tag + ' oai-lte-multi-ue-proxy:latest', '\$', 5)
|
||||||
|
|
||||||
|
# no merge: is a push to develop, tag the image so we can push it to the registry
|
||||||
|
if not self.ranAllowMerge:
|
||||||
|
mySSH.command('docker image tag proxy:' + tag + ' proxy:develop', '\$', 5)
|
||||||
|
|
||||||
|
# we assume that the host on which this is built will also run the proxy. The proxy
|
||||||
|
# currently requires the following command, and the docker-compose up mechanism of
|
||||||
|
# the CI does not allow to run arbitrary commands. Note that the following actually
|
||||||
|
# belongs to the deployment, not the build of the proxy...
|
||||||
|
logging.warning('the following command belongs to deployment, but no mechanism exists to exec it there!')
|
||||||
|
mySSH.command('sudo ifconfig lo: 127.0.0.2 netmask 255.0.0.0 up', '\$', 5)
|
||||||
|
|
||||||
|
# Analyzing the logs
|
||||||
|
if buildProxy:
|
||||||
|
self.testCase_id = HTML.testCase_id
|
||||||
|
mySSH.command('cd ' + lSourcePath + '/cmake_targets', '\$', 5)
|
||||||
|
mySSH.command('mkdir -p proxy_build_log_' + self.testCase_id, '\$', 5)
|
||||||
|
mySSH.command('mv log/* ' + 'proxy_build_log_' + self.testCase_id, '\$', 5)
|
||||||
|
if (os.path.isfile('./proxy_build_log_' + self.testCase_id + '.zip')):
|
||||||
|
os.remove('./proxy_build_log_' + self.testCase_id + '.zip')
|
||||||
|
if (os.path.isdir('./proxy_build_log_' + self.testCase_id)):
|
||||||
|
shutil.rmtree('./proxy_build_log_' + self.testCase_id)
|
||||||
|
mySSH.command('zip -r -qq proxy_build_log_' + self.testCase_id + '.zip proxy_build_log_' + self.testCase_id, '\$', 5)
|
||||||
|
mySSH.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/build_log_' + self.testCase_id + '.zip', '.')
|
||||||
|
# don't delete such that we might recover the zips
|
||||||
|
#mySSH.command('rm -f build_log_' + self.testCase_id + '.zip','\$', 5)
|
||||||
|
|
||||||
|
# Cleaning any created tmp volume
|
||||||
|
mySSH.command(self.cli + ' volume prune --force || true','\$', 15)
|
||||||
|
mySSH.close()
|
||||||
|
|
||||||
|
logging.info('\u001B[1m Building L2sim Proxy Image Pass\u001B[0m')
|
||||||
|
HTML.CreateHtmlTestRow('commit ' + tag, 'OK', CONST.ALL_PROCESSES_OK)
|
||||||
|
HTML.CreateHtmlNextTabHeaderTestRow(self.collectInfo, self.allImagesSize)
|
||||||
|
|
||||||
def Copy_Image_to_Test_Server(self, HTML):
|
def Copy_Image_to_Test_Server(self, HTML):
|
||||||
imageTag = 'develop'
|
imageTag = 'develop'
|
||||||
if (self.ranAllowMerge):
|
if (self.ranAllowMerge):
|
||||||
|
|||||||
+6
-1
@@ -102,7 +102,7 @@ def AssignParams(params_dict):
|
|||||||
|
|
||||||
|
|
||||||
def GetParametersFromXML(action):
|
def GetParametersFromXML(action):
|
||||||
if action == 'Build_eNB' or action == 'Build_Image':
|
if action == 'Build_eNB' or action == 'Build_Image' or action == 'Build_Proxy':
|
||||||
RAN.Build_eNB_args=test.findtext('Build_eNB_args')
|
RAN.Build_eNB_args=test.findtext('Build_eNB_args')
|
||||||
CONTAINERS.imageKind=test.findtext('kind')
|
CONTAINERS.imageKind=test.findtext('kind')
|
||||||
forced_workspace_cleanup = test.findtext('forced_workspace_cleanup')
|
forced_workspace_cleanup = test.findtext('forced_workspace_cleanup')
|
||||||
@@ -138,6 +138,9 @@ def GetParametersFromXML(action):
|
|||||||
RAN.backgroundBuild=True
|
RAN.backgroundBuild=True
|
||||||
else:
|
else:
|
||||||
RAN.backgroundBuild=False
|
RAN.backgroundBuild=False
|
||||||
|
proxy_commit = test.findtext('proxy_commit')
|
||||||
|
if proxy_commit is not None:
|
||||||
|
CONTAINERS.proxyCommit = proxy_commit
|
||||||
|
|
||||||
elif action == 'WaitEndBuild_eNB':
|
elif action == 'WaitEndBuild_eNB':
|
||||||
RAN.Build_eNB_args=test.findtext('Build_eNB_args')
|
RAN.Build_eNB_args=test.findtext('Build_eNB_args')
|
||||||
@@ -915,6 +918,8 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re
|
|||||||
HTML=ldpc.Run_PhySim(HTML,CONST,id)
|
HTML=ldpc.Run_PhySim(HTML,CONST,id)
|
||||||
elif action == 'Build_Image':
|
elif action == 'Build_Image':
|
||||||
CONTAINERS.BuildImage(HTML)
|
CONTAINERS.BuildImage(HTML)
|
||||||
|
elif action == 'Build_Proxy':
|
||||||
|
CONTAINERS.BuildProxy(HTML)
|
||||||
elif action == 'Copy_Image_to_Test':
|
elif action == 'Copy_Image_to_Test':
|
||||||
CONTAINERS.Copy_Image_to_Test_Server(HTML)
|
CONTAINERS.Copy_Image_to_Test_Server(HTML)
|
||||||
elif action == 'Deploy_Object':
|
elif action == 'Deploy_Object':
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
- Build_Proxy
|
||||||
- Build_PhySim
|
- Build_PhySim
|
||||||
- Run_PhySim
|
- Run_PhySim
|
||||||
- Build_eNB
|
- Build_eNB
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
<!--
|
||||||
|
|
||||||
|
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>l2sim-5gnr-proxy-build</htmlTabRef>
|
||||||
|
<htmlTabName>Build L2sim proxy image</htmlTabName>
|
||||||
|
<htmlTabIcon>wrench</htmlTabIcon>
|
||||||
|
<repeatCount>1</repeatCount>
|
||||||
|
<TestCaseRequestedList>
|
||||||
|
000001
|
||||||
|
</TestCaseRequestedList>
|
||||||
|
<TestCaseExclusionList></TestCaseExclusionList>
|
||||||
|
|
||||||
|
<testCase id="000001">
|
||||||
|
<class>Build_Proxy</class>
|
||||||
|
<desc>Build L2sim Proxy Image</desc>
|
||||||
|
<eNB_instance>1</eNB_instance>
|
||||||
|
<eNB_serverId>1</eNB_serverId>
|
||||||
|
<forced_workspace_cleanup>True</forced_workspace_cleanup>
|
||||||
|
<proxy_commit>56cfdc0</proxy_commit>
|
||||||
|
</testCase>
|
||||||
|
|
||||||
|
</testCaseList>
|
||||||
@@ -271,6 +271,12 @@ if (SANITIZE_ADDRESS)
|
|||||||
# wrong in the pthread library, or something subtly wrong in this CMakeLists.txt. Use Ubuntu 20.04 instead.
|
# wrong in the pthread library, or something subtly wrong in this CMakeLists.txt. Use Ubuntu 20.04 instead.
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
add_boolean_option(SANITIZE_UNDEFINED False "enable the undefined behavior sanitizer (UBSan)")
|
||||||
|
if (SANITIZE_UNDEFINED)
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=undefined -fno-sanitize-recover=all")
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined -fno-sanitize-recover=all")
|
||||||
|
endif ()
|
||||||
|
|
||||||
add_definitions("-DASN_DISABLE_OER_SUPPORT")
|
add_definitions("-DASN_DISABLE_OER_SUPPORT")
|
||||||
|
|
||||||
#########################
|
#########################
|
||||||
@@ -1804,7 +1810,15 @@ set(NR_PDCP_SRC
|
|||||||
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_timer_thread.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_security_nea2.c
|
||||||
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_integrity_nia2.c
|
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_integrity_nia2.c
|
||||||
|
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_integrity_nia1.c
|
||||||
${OPENAIR2_DIR}/LAYER2/nr_pdcp/asn1_utils.c
|
${OPENAIR2_DIR}/LAYER2/nr_pdcp/asn1_utils.c
|
||||||
|
#hack: include these files to compile the nr phy simulators
|
||||||
|
#these files should not be here, will be removed at some point when the
|
||||||
|
#computation is done directly inside nr_pdcp_integrity_nia1.c instead
|
||||||
|
#of reusing code of osa_stream_eia.c
|
||||||
|
${OPENAIR2_DIR}/UTIL/OSA/osa_stream_eia.c
|
||||||
|
${OPENAIR2_DIR}/UTIL/OSA/osa_snow3g.c
|
||||||
|
${OPENAIR2_DIR}/UTIL/OSA/osa_rijndael.c
|
||||||
)
|
)
|
||||||
|
|
||||||
set(NR_SDAP_SRC
|
set(NR_SDAP_SRC
|
||||||
|
|||||||
+11
-1
@@ -171,8 +171,12 @@ Options:
|
|||||||
Skip build for shared libraries to reduce compilation time when building frequently for debugging purposes
|
Skip build for shared libraries to reduce compilation time when building frequently for debugging purposes
|
||||||
--ninja
|
--ninja
|
||||||
Tell cmake to use the Ninja build system. Without, will generate make files
|
Tell cmake to use the Ninja build system. Without, will generate make files
|
||||||
|
--sanitize
|
||||||
|
Shortcut for usage of --sanitize-address --sanitize-undefined
|
||||||
--sanitize-address | -fsanitize=address
|
--sanitize-address | -fsanitize=address
|
||||||
Enable the address sanitizer on all targets
|
Enable the address sanitizer on all targets
|
||||||
|
--sanitize-undefined | -fsanitize=undefined
|
||||||
|
Enable the undefined behavior sanitizer on all targets
|
||||||
--ittiSIM
|
--ittiSIM
|
||||||
Makes the itti simulator
|
Makes the itti simulator
|
||||||
-h | --help
|
-h | --help
|
||||||
@@ -451,10 +455,16 @@ function main() {
|
|||||||
CMAKE_CMD="$CMAKE_CMD -GNinja"
|
CMAKE_CMD="$CMAKE_CMD -GNinja"
|
||||||
MAKE_CMD=ninja
|
MAKE_CMD=ninja
|
||||||
shift;;
|
shift;;
|
||||||
|
--sanitize)
|
||||||
|
CMAKE_CMD="$CMAKE_CMD -DSANITIZE_ADDRESS=True -DSANITIZE_UNDEFINED=True"
|
||||||
|
shift;;
|
||||||
--sanitize-address | -fsanitize=address)
|
--sanitize-address | -fsanitize=address)
|
||||||
grep -sq "Ubuntu 18.04" /etc/os-release && echo_error "Bug in OS with this option, see CMakeLists.txt"
|
grep -sq "Ubuntu 18.04" /etc/os-release && echo_error "Bug in OS with this option, see CMakeLists.txt"
|
||||||
CMAKE_CMD="$CMAKE_CMD -DSANITIZE_ADDRESS=True"
|
CMAKE_CMD="$CMAKE_CMD -DSANITIZE_ADDRESS=True"
|
||||||
shift;;
|
shift;;
|
||||||
|
--sanitize-undefined | -fundefined=address)
|
||||||
|
CMAKE_CMD="$CMAKE_CMD -DSANITIZE_UNDEFINED=True"
|
||||||
|
shift;;
|
||||||
--ittiSIM)
|
--ittiSIM)
|
||||||
ittiSIM=1
|
ittiSIM=1
|
||||||
CMAKE_CMD="$CMAKE_CMD -DITTI_SIM=True"
|
CMAKE_CMD="$CMAKE_CMD -DITTI_SIM=True"
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ typedef struct time_stats {
|
|||||||
oai_cputime_t in; /*!< \brief time at measure starting point */
|
oai_cputime_t in; /*!< \brief time at measure starting point */
|
||||||
oai_cputime_t diff; /*!< \brief average difference between time at starting point and time at endpoint*/
|
oai_cputime_t diff; /*!< \brief average difference between time at starting point and time at endpoint*/
|
||||||
oai_cputime_t p_time; /*!< \brief absolute process duration */
|
oai_cputime_t p_time; /*!< \brief absolute process duration */
|
||||||
oai_cputime_t diff_square; /*!< \brief process duration square */
|
double diff_square; /*!< \brief process duration square */
|
||||||
oai_cputime_t max; /*!< \brief maximum difference between time at starting point and time at endpoint*/
|
oai_cputime_t max; /*!< \brief maximum difference between time at starting point and time at endpoint*/
|
||||||
int trials; /*!< \brief number of start point - end point iterations */
|
int trials; /*!< \brief number of start point - end point iterations */
|
||||||
int meas_flag; /*!< \brief 1: stop_meas not called (consecutive calls of start_meas) */
|
int meas_flag; /*!< \brief 1: stop_meas not called (consecutive calls of start_meas) */
|
||||||
@@ -156,7 +156,7 @@ static inline void stop_meas(time_stats_t *ts) {
|
|||||||
ts->diff += (out-ts->in);
|
ts->diff += (out-ts->in);
|
||||||
/// process duration is the difference between two clock points
|
/// process duration is the difference between two clock points
|
||||||
ts->p_time = (out-ts->in);
|
ts->p_time = (out-ts->in);
|
||||||
ts->diff_square += (out-ts->in)*(out-ts->in);
|
ts->diff_square += ((double)out-ts->in)*((double)out-ts->in);
|
||||||
|
|
||||||
if ((out-ts->in) > ts->max)
|
if ((out-ts->in) > ts->max)
|
||||||
ts->max = out-ts->in;
|
ts->max = out-ts->in;
|
||||||
|
|||||||
+9
-2
@@ -440,6 +440,10 @@ The following features are valid for the gNB and the 5G-NR UE.
|
|||||||
- PTRS support
|
- PTRS support
|
||||||
- Support for 1, 2 and 4 RX antennas
|
- Support for 1, 2 and 4 RX antennas
|
||||||
- Support for up to 2 layers (currently limited to DMRS configuration type 2)
|
- Support for up to 2 layers (currently limited to DMRS configuration type 2)
|
||||||
|
* Measurements based on NR-CSIRS
|
||||||
|
- RI, PMI and CQI computation
|
||||||
|
- Support for 1 and 2 RX antennas
|
||||||
|
- Support for up to 2 layers
|
||||||
* NR-PUSCH (including Segmentation, LDPC encoding, rate matching, scrambling, modulation, RB mapping, etc).
|
* NR-PUSCH (including Segmentation, LDPC encoding, rate matching, scrambling, modulation, RB mapping, etc).
|
||||||
- PUSCH mapping type A and B
|
- PUSCH mapping type A and B
|
||||||
- DMRS configuration type 1 and 2
|
- DMRS configuration type 1 and 2
|
||||||
@@ -488,12 +492,15 @@ The following features are valid for the gNB and the 5G-NR UE.
|
|||||||
* UCI processing
|
* UCI processing
|
||||||
- ACK/NACK processing
|
- ACK/NACK processing
|
||||||
- Triggering periodic SR
|
- Triggering periodic SR
|
||||||
- CSI measurement reporting (SSB RSRP only)
|
- CSI measurement reporting
|
||||||
* DLSH scheduler
|
* DLSCH scheduler
|
||||||
- Configuration of fapi PDU according to DCI
|
- Configuration of fapi PDU according to DCI
|
||||||
- HARQ procedures
|
- HARQ procedures
|
||||||
* ULSCH scheduler
|
* ULSCH scheduler
|
||||||
- Configuration of fapi PDU according to DCI
|
- Configuration of fapi PDU according to DCI
|
||||||
|
* NR-CSIRS scheduler
|
||||||
|
- Scheduling of NR-CSIRS reception
|
||||||
|
- Fill UCI for CSI measurement reporting
|
||||||
* Scheduler procedures for SRS transmission
|
* Scheduler procedures for SRS transmission
|
||||||
- Periodic SRS transmission
|
- Periodic SRS transmission
|
||||||
* Bandwidth part (BWP) operation
|
* Bandwidth part (BWP) operation
|
||||||
|
|||||||
@@ -71,10 +71,6 @@ reboot
|
|||||||
# https://docs.docker.com/compose/install/
|
# https://docs.docker.com/compose/install/
|
||||||
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
|
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
|
||||||
sudo chmod +x /usr/local/bin/docker-compose
|
sudo chmod +x /usr/local/bin/docker-compose
|
||||||
|
|
||||||
docker network create --driver=bridge --subnet=192.168.70.128/26 -o "com.docker.network.bridge.name"="demo-oai" demo-oai-public-net
|
|
||||||
sudo service docker restart
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## 2.2 OAI CN5G Setup
|
## 2.2 OAI CN5G Setup
|
||||||
@@ -82,39 +78,36 @@ sudo service docker restart
|
|||||||
```bash
|
```bash
|
||||||
# Git oai-cn5g-fed repository
|
# Git oai-cn5g-fed repository
|
||||||
git clone https://gitlab.eurecom.fr/oai/cn5g/oai-cn5g-fed.git ~/oai-cn5g-fed
|
git clone https://gitlab.eurecom.fr/oai/cn5g/oai-cn5g-fed.git ~/oai-cn5g-fed
|
||||||
cd ~/oai-cn5g-fed
|
|
||||||
git checkout master
|
|
||||||
./scripts/syncComponents.sh --nrf-branch develop --amf-branch develop --smf-branch develop --spgwu-tiny-branch develop --ausf-branch develop --udm-branch develop --udr-branch develop --upf-vpp-branch develop --nssf-branch develop
|
|
||||||
|
|
||||||
|
# Pull docker images
|
||||||
docker pull oaisoftwarealliance/oai-amf:develop
|
docker pull oaisoftwarealliance/oai-amf:develop
|
||||||
docker pull oaisoftwarealliance/oai-nrf:develop
|
docker pull oaisoftwarealliance/oai-nrf:develop
|
||||||
docker pull oaisoftwarealliance/oai-smf:develop
|
docker pull oaisoftwarealliance/oai-smf:develop
|
||||||
docker pull oaisoftwarealliance/oai-udr:develop
|
docker pull oaisoftwarealliance/oai-udr:develop
|
||||||
docker pull oaisoftwarealliance/oai-udm:develop
|
docker pull oaisoftwarealliance/oai-udm:develop
|
||||||
docker pull oaisoftwarealliance/oai-ausf:develop
|
docker pull oaisoftwarealliance/oai-ausf:develop
|
||||||
docker pull oaisoftwarealliance/oai-upf-vpp:develop
|
|
||||||
docker pull oaisoftwarealliance/oai-spgwu-tiny:develop
|
docker pull oaisoftwarealliance/oai-spgwu-tiny:develop
|
||||||
docker pull oaisoftwarealliance/oai-nssf:develop
|
docker pull oaisoftwarealliance/trf-gen-cn5g:latest
|
||||||
|
|
||||||
|
# Tag docker images
|
||||||
docker image tag oaisoftwarealliance/oai-amf:develop oai-amf:develop
|
docker image tag oaisoftwarealliance/oai-amf:develop oai-amf:develop
|
||||||
docker image tag oaisoftwarealliance/oai-nrf:develop oai-nrf:develop
|
docker image tag oaisoftwarealliance/oai-nrf:develop oai-nrf:develop
|
||||||
docker image tag oaisoftwarealliance/oai-smf:develop oai-smf:develop
|
docker image tag oaisoftwarealliance/oai-smf:develop oai-smf:develop
|
||||||
docker image tag oaisoftwarealliance/oai-udr:develop oai-udr:develop
|
docker image tag oaisoftwarealliance/oai-udr:develop oai-udr:develop
|
||||||
docker image tag oaisoftwarealliance/oai-udm:develop oai-udm:develop
|
docker image tag oaisoftwarealliance/oai-udm:develop oai-udm:develop
|
||||||
docker image tag oaisoftwarealliance/oai-ausf:develop oai-ausf:develop
|
docker image tag oaisoftwarealliance/oai-ausf:develop oai-ausf:develop
|
||||||
docker image tag oaisoftwarealliance/oai-upf-vpp:develop oai-upf-vpp:develop
|
|
||||||
docker image tag oaisoftwarealliance/oai-spgwu-tiny:develop oai-spgwu-tiny:develop
|
docker image tag oaisoftwarealliance/oai-spgwu-tiny:develop oai-spgwu-tiny:develop
|
||||||
docker image tag oaisoftwarealliance/oai-nssf:develop oai-nssf:develop
|
docker image tag oaisoftwarealliance/trf-gen-cn5g:latest trf-gen-cn5g:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
## 2.3 OAI CN5G Configuration files
|
## 2.3 OAI CN5G Configuration files
|
||||||
Download and copy the configuration files to ~/oai-cn5g-fed/docker-compose:
|
Download and copy configuration files:
|
||||||
- [docker-compose-basic-nrf.yaml](tutorial_resources/docker-compose-basic-nrf.yaml)
|
- Copy [docker-compose-basic-nrf.yaml](tutorial_resources/docker-compose-basic-nrf.yaml) to `~/oai-cn5g-fed/docker-compose`
|
||||||
- [oai_db.sql](tutorial_resources/oai_db.sql)
|
- Copy [oai_db.sql](tutorial_resources/oai_db.sql) to `~/oai-cn5g-fed/docker-compose/database`
|
||||||
|
|
||||||
Change permissions on oai_db.sql to prevent mysql permission denied error:
|
Change permissions on oai_db.sql to prevent mysql permission denied error:
|
||||||
```bash
|
```bash
|
||||||
chmod 644 ~/oai-cn5g-fed/docker-compose/oai_db.sql
|
chmod 644 ~/oai-cn5g-fed/docker-compose/database/oai_db.sql
|
||||||
```
|
```
|
||||||
|
|
||||||
## 2.4 SIM Card
|
## 2.4 SIM Card
|
||||||
@@ -175,7 +168,7 @@ cd cmake_targets
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd ~/oai-cn5g-fed/docker-compose
|
cd ~/oai-cn5g-fed/docker-compose
|
||||||
python3 core-network.py --type start-basic --fqdn yes --scenario 1
|
python3 core-network.py --type start-basic --scenario 1
|
||||||
```
|
```
|
||||||
|
|
||||||
## 4.2 Run OAI gNB
|
## 4.2 Run OAI gNB
|
||||||
|
|||||||
@@ -72,10 +72,6 @@ reboot
|
|||||||
# https://docs.docker.com/compose/install/
|
# https://docs.docker.com/compose/install/
|
||||||
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
|
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
|
||||||
sudo chmod +x /usr/local/bin/docker-compose
|
sudo chmod +x /usr/local/bin/docker-compose
|
||||||
|
|
||||||
docker network create --driver=bridge --subnet=192.168.70.128/26 -o "com.docker.network.bridge.name"="demo-oai" demo-oai-public-net
|
|
||||||
sudo service docker restart
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## 2.2 OAI CN5G Setup
|
## 2.2 OAI CN5G Setup
|
||||||
@@ -83,39 +79,36 @@ sudo service docker restart
|
|||||||
```bash
|
```bash
|
||||||
# Git oai-cn5g-fed repository
|
# Git oai-cn5g-fed repository
|
||||||
git clone https://gitlab.eurecom.fr/oai/cn5g/oai-cn5g-fed.git ~/oai-cn5g-fed
|
git clone https://gitlab.eurecom.fr/oai/cn5g/oai-cn5g-fed.git ~/oai-cn5g-fed
|
||||||
cd ~/oai-cn5g-fed
|
|
||||||
git checkout master
|
|
||||||
./scripts/syncComponents.sh --nrf-branch develop --amf-branch develop --smf-branch develop --spgwu-tiny-branch develop --ausf-branch develop --udm-branch develop --udr-branch develop --upf-vpp-branch develop --nssf-branch develop
|
|
||||||
|
|
||||||
|
# Pull docker images
|
||||||
docker pull oaisoftwarealliance/oai-amf:develop
|
docker pull oaisoftwarealliance/oai-amf:develop
|
||||||
docker pull oaisoftwarealliance/oai-nrf:develop
|
docker pull oaisoftwarealliance/oai-nrf:develop
|
||||||
docker pull oaisoftwarealliance/oai-smf:develop
|
docker pull oaisoftwarealliance/oai-smf:develop
|
||||||
docker pull oaisoftwarealliance/oai-udr:develop
|
docker pull oaisoftwarealliance/oai-udr:develop
|
||||||
docker pull oaisoftwarealliance/oai-udm:develop
|
docker pull oaisoftwarealliance/oai-udm:develop
|
||||||
docker pull oaisoftwarealliance/oai-ausf:develop
|
docker pull oaisoftwarealliance/oai-ausf:develop
|
||||||
docker pull oaisoftwarealliance/oai-upf-vpp:develop
|
|
||||||
docker pull oaisoftwarealliance/oai-spgwu-tiny:develop
|
docker pull oaisoftwarealliance/oai-spgwu-tiny:develop
|
||||||
docker pull oaisoftwarealliance/oai-nssf:develop
|
docker pull oaisoftwarealliance/trf-gen-cn5g:latest
|
||||||
|
|
||||||
|
# Tag docker images
|
||||||
docker image tag oaisoftwarealliance/oai-amf:develop oai-amf:develop
|
docker image tag oaisoftwarealliance/oai-amf:develop oai-amf:develop
|
||||||
docker image tag oaisoftwarealliance/oai-nrf:develop oai-nrf:develop
|
docker image tag oaisoftwarealliance/oai-nrf:develop oai-nrf:develop
|
||||||
docker image tag oaisoftwarealliance/oai-smf:develop oai-smf:develop
|
docker image tag oaisoftwarealliance/oai-smf:develop oai-smf:develop
|
||||||
docker image tag oaisoftwarealliance/oai-udr:develop oai-udr:develop
|
docker image tag oaisoftwarealliance/oai-udr:develop oai-udr:develop
|
||||||
docker image tag oaisoftwarealliance/oai-udm:develop oai-udm:develop
|
docker image tag oaisoftwarealliance/oai-udm:develop oai-udm:develop
|
||||||
docker image tag oaisoftwarealliance/oai-ausf:develop oai-ausf:develop
|
docker image tag oaisoftwarealliance/oai-ausf:develop oai-ausf:develop
|
||||||
docker image tag oaisoftwarealliance/oai-upf-vpp:develop oai-upf-vpp:develop
|
|
||||||
docker image tag oaisoftwarealliance/oai-spgwu-tiny:develop oai-spgwu-tiny:develop
|
docker image tag oaisoftwarealliance/oai-spgwu-tiny:develop oai-spgwu-tiny:develop
|
||||||
docker image tag oaisoftwarealliance/oai-nssf:develop oai-nssf:develop
|
docker image tag oaisoftwarealliance/trf-gen-cn5g:latest trf-gen-cn5g:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
## 2.3 OAI CN5G Configuration files
|
## 2.3 OAI CN5G Configuration files
|
||||||
Download and copy the configuration files to ~/oai-cn5g-fed/docker-compose:
|
Download and copy configuration files:
|
||||||
- [docker-compose-basic-nrf.yaml](tutorial_resources/docker-compose-basic-nrf.yaml)
|
- Copy [docker-compose-basic-nrf.yaml](tutorial_resources/docker-compose-basic-nrf.yaml) to `~/oai-cn5g-fed/docker-compose`
|
||||||
- [oai_db.sql](tutorial_resources/oai_db.sql)
|
- Copy [oai_db.sql](tutorial_resources/oai_db.sql) to `~/oai-cn5g-fed/docker-compose/database`
|
||||||
|
|
||||||
Change permissions on oai_db.sql to prevent mysql permission denied error:
|
Change permissions on oai_db.sql to prevent mysql permission denied error:
|
||||||
```bash
|
```bash
|
||||||
chmod 644 ~/oai-cn5g-fed/docker-compose/oai_db.sql
|
chmod 644 ~/oai-cn5g-fed/docker-compose/database/oai_db.sql
|
||||||
```
|
```
|
||||||
|
|
||||||
## 2.4 SIM Card
|
## 2.4 SIM Card
|
||||||
@@ -193,7 +186,7 @@ The following steps are recommended. Please change the network interface(s) as r
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd ~/oai-cn5g-fed/docker-compose
|
cd ~/oai-cn5g-fed/docker-compose
|
||||||
python3 core-network.py --type start-basic --fqdn yes --scenario 1
|
python3 core-network.py --type start-basic --scenario 1
|
||||||
```
|
```
|
||||||
|
|
||||||
## 4.2 Run OAI gNB
|
## 4.2 Run OAI gNB
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ services:
|
|||||||
container_name: "mysql"
|
container_name: "mysql"
|
||||||
image: mysql:5.7
|
image: mysql:5.7
|
||||||
volumes:
|
volumes:
|
||||||
- ./oai_db.sql:/docker-entrypoint-initdb.d/oai_db.sql
|
- ./database/oai_db.sql:/docker-entrypoint-initdb.d/oai_db.sql
|
||||||
- ./mysql-healthcheck2.sh:/tmp/mysql-healthcheck.sh
|
- ./healthscripts/mysql-healthcheck2.sh:/tmp/mysql-healthcheck.sh
|
||||||
environment:
|
environment:
|
||||||
- TZ=Europe/Paris
|
- TZ=Europe/Paris
|
||||||
- MYSQL_DATABASE=oai_db
|
- MYSQL_DATABASE=oai_db
|
||||||
@@ -21,35 +21,45 @@ services:
|
|||||||
public_net:
|
public_net:
|
||||||
ipv4_address: 192.168.70.131
|
ipv4_address: 192.168.70.131
|
||||||
oai-udr:
|
oai-udr:
|
||||||
container_name: oai-udr
|
container_name: "oai-udr"
|
||||||
image: oai-udr:develop
|
image: oai-udr:develop
|
||||||
environment:
|
environment:
|
||||||
- TZ=Europe/Paris
|
- TZ=Europe/Paris
|
||||||
- INSTANCE=0
|
- INSTANCE=0
|
||||||
- PID_DIRECTORY=/var/run
|
- PID_DIRECTORY=/var/run
|
||||||
|
- UDR_NAME=OAI_UDR
|
||||||
- UDR_INTERFACE_NAME_FOR_NUDR=eth0
|
- UDR_INTERFACE_NAME_FOR_NUDR=eth0
|
||||||
- UDR_INTERFACE_PORT_FOR_NUDR=80
|
- UDR_INTERFACE_PORT_FOR_NUDR=80
|
||||||
- UDR_INTERFACE_HTTP2_PORT_FOR_NUDR=8080
|
- UDR_INTERFACE_HTTP2_PORT_FOR_NUDR=8080
|
||||||
|
- USE_HTTP2=no
|
||||||
- UDR_API_VERSION=v1
|
- UDR_API_VERSION=v1
|
||||||
- MYSQL_IPV4_ADDRESS=192.168.70.131
|
- MYSQL_IPV4_ADDRESS=192.168.70.131
|
||||||
- MYSQL_USER=test
|
- MYSQL_USER=test
|
||||||
- MYSQL_PASS=test
|
- MYSQL_PASS=test
|
||||||
|
- DB_CONNECTION_TIMEOUT=300 # Reset the connection to the DB after expiring the timeout (in second) currently can't be changed
|
||||||
- MYSQL_DB=oai_db
|
- MYSQL_DB=oai_db
|
||||||
- WAIT_MYSQL=120
|
- WAIT_MYSQL=120
|
||||||
|
- USE_FQDN_DNS=yes
|
||||||
|
- REGISTER_NRF=yes
|
||||||
|
- NRF_IPV4_ADDRESS=192.168.70.130
|
||||||
|
- NRF_PORT=80
|
||||||
|
- NRF_API_VERSION=v1
|
||||||
|
- NRF_FQDN=oai-nrf
|
||||||
depends_on:
|
depends_on:
|
||||||
- mysql
|
- mysql
|
||||||
|
- oai-nrf
|
||||||
networks:
|
networks:
|
||||||
public_net:
|
public_net:
|
||||||
ipv4_address: 192.168.70.136
|
ipv4_address: 192.168.70.136
|
||||||
volumes:
|
volumes:
|
||||||
- ./udr-healthcheck.sh:/openair-udr/bin/udr-healthcheck.sh
|
- ./healthscripts/udr-healthcheck.sh:/openair-udr/bin/udr-healthcheck.sh
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: /bin/bash -c "/openair-udr/bin/udr-healthcheck.sh"
|
test: /bin/bash -c "/openair-udr/bin/udr-healthcheck.sh"
|
||||||
interval: 10s
|
interval: 10s
|
||||||
timeout: 5s
|
timeout: 5s
|
||||||
retries: 5
|
retries: 5
|
||||||
oai-udm:
|
oai-udm:
|
||||||
container_name: oai-udm
|
container_name: "oai-udm"
|
||||||
image: oai-udm:develop
|
image: oai-udm:develop
|
||||||
environment:
|
environment:
|
||||||
- TZ=Europe/Paris
|
- TZ=Europe/Paris
|
||||||
@@ -58,26 +68,33 @@ services:
|
|||||||
- UDM_NAME=OAI_UDM
|
- UDM_NAME=OAI_UDM
|
||||||
- SBI_IF_NAME=eth0
|
- SBI_IF_NAME=eth0
|
||||||
- SBI_PORT=80
|
- SBI_PORT=80
|
||||||
|
- SBI_HTTP2_PORT=8080
|
||||||
|
- USE_HTTP2=no
|
||||||
- UDM_VERSION_NB=v1
|
- UDM_VERSION_NB=v1
|
||||||
- USE_FQDN_DNS=yes
|
- USE_FQDN_DNS=yes
|
||||||
- UDR_IP_ADDRESS=192.168.70.136
|
- UDR_IP_ADDRESS=192.168.70.136
|
||||||
- UDR_PORT=80
|
- UDR_PORT=80
|
||||||
- UDR_VERSION_NB=v1
|
- UDR_VERSION_NB=v1
|
||||||
- UDR_FQDN=oai-udr
|
- UDR_FQDN=oai-udr
|
||||||
|
- REGISTER_NRF=yes
|
||||||
|
- NRF_IPV4_ADDRESS=192.168.70.130
|
||||||
|
- NRF_PORT=80
|
||||||
|
- NRF_API_VERSION=v1
|
||||||
|
- NRF_FQDN=oai-nrf
|
||||||
depends_on:
|
depends_on:
|
||||||
- oai-udr
|
- oai-udr
|
||||||
networks:
|
networks:
|
||||||
public_net:
|
public_net:
|
||||||
ipv4_address: 192.168.70.137
|
ipv4_address: 192.168.70.137
|
||||||
volumes:
|
volumes:
|
||||||
- ./udm-healthcheck.sh:/openair-udm/bin/udm-healthcheck.sh
|
- ./healthscripts/udm-healthcheck.sh:/openair-udm/bin/udm-healthcheck.sh
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: /bin/bash -c "/openair-udm/bin/udm-healthcheck.sh"
|
test: /bin/bash -c "/openair-udm/bin/udm-healthcheck.sh"
|
||||||
interval: 10s
|
interval: 10s
|
||||||
timeout: 5s
|
timeout: 5s
|
||||||
retries: 5
|
retries: 5
|
||||||
oai-ausf:
|
oai-ausf:
|
||||||
container_name: oai-ausf
|
container_name: "oai-ausf"
|
||||||
image: oai-ausf:develop
|
image: oai-ausf:develop
|
||||||
environment:
|
environment:
|
||||||
- TZ=Europe/Paris
|
- TZ=Europe/Paris
|
||||||
@@ -86,18 +103,25 @@ services:
|
|||||||
- AUSF_NAME=OAI_AUSF
|
- AUSF_NAME=OAI_AUSF
|
||||||
- SBI_IF_NAME=eth0
|
- SBI_IF_NAME=eth0
|
||||||
- SBI_PORT=80
|
- SBI_PORT=80
|
||||||
|
- USE_HTTP2
|
||||||
|
- SBI_HTTP2_PORT
|
||||||
- USE_FQDN_DNS=yes
|
- USE_FQDN_DNS=yes
|
||||||
- UDM_IP_ADDRESS=192.168.70.137
|
- UDM_IP_ADDRESS=192.168.70.137
|
||||||
- UDM_PORT=80
|
- UDM_PORT=80
|
||||||
- UDM_VERSION_NB=v1
|
- UDM_VERSION_NB=v1
|
||||||
- UDM_FQDN=oai-udm
|
- UDM_FQDN=oai-udm
|
||||||
|
- REGISTER_NRF=yes
|
||||||
|
- NRF_IPV4_ADDRESS=192.168.70.130
|
||||||
|
- NRF_PORT=80
|
||||||
|
- NRF_API_VERSION=v1
|
||||||
|
- NRF_FQDN=oai-nrf
|
||||||
depends_on:
|
depends_on:
|
||||||
- oai-udm
|
- oai-udm
|
||||||
networks:
|
networks:
|
||||||
public_net:
|
public_net:
|
||||||
ipv4_address: 192.168.70.138
|
ipv4_address: 192.168.70.138
|
||||||
volumes:
|
volumes:
|
||||||
- ./ausf-healthcheck.sh:/openair-ausf/bin/ausf-healthcheck.sh
|
- ./healthscripts/ausf-healthcheck.sh:/openair-ausf/bin/ausf-healthcheck.sh
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: /bin/bash -c "/openair-ausf/bin/ausf-healthcheck.sh"
|
test: /bin/bash -c "/openair-ausf/bin/ausf-healthcheck.sh"
|
||||||
interval: 10s
|
interval: 10s
|
||||||
@@ -107,9 +131,10 @@ services:
|
|||||||
container_name: "oai-nrf"
|
container_name: "oai-nrf"
|
||||||
image: oai-nrf:develop
|
image: oai-nrf:develop
|
||||||
environment:
|
environment:
|
||||||
|
- TZ=Europe/Paris
|
||||||
- NRF_INTERFACE_NAME_FOR_SBI=eth0
|
- NRF_INTERFACE_NAME_FOR_SBI=eth0
|
||||||
- NRF_INTERFACE_PORT_FOR_SBI=80
|
- NRF_INTERFACE_PORT_FOR_SBI=80
|
||||||
- NRF_INTERFACE_HTTP2_PORT_FOR_SBI=9090
|
- NRF_INTERFACE_HTTP2_PORT_FOR_SBI=8080
|
||||||
- NRF_API_VERSION=v1
|
- NRF_API_VERSION=v1
|
||||||
- INSTANCE=0
|
- INSTANCE=0
|
||||||
- PID_DIRECTORY=/var/run
|
- PID_DIRECTORY=/var/run
|
||||||
@@ -117,7 +142,7 @@ services:
|
|||||||
public_net:
|
public_net:
|
||||||
ipv4_address: 192.168.70.130
|
ipv4_address: 192.168.70.130
|
||||||
volumes:
|
volumes:
|
||||||
- ./nrf-healthcheck.sh:/openair-nrf/bin/nrf-healthcheck.sh
|
- ./healthscripts/nrf-healthcheck.sh:/openair-nrf/bin/nrf-healthcheck.sh
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: /bin/bash -c "/openair-nrf/bin/nrf-healthcheck.sh"
|
test: /bin/bash -c "/openair-nrf/bin/nrf-healthcheck.sh"
|
||||||
interval: 10s
|
interval: 10s
|
||||||
@@ -146,9 +171,7 @@ services:
|
|||||||
- PLMN_SUPPORT_MNC=99
|
- PLMN_SUPPORT_MNC=99
|
||||||
- PLMN_SUPPORT_TAC=0x0001
|
- PLMN_SUPPORT_TAC=0x0001
|
||||||
- SST_0=1
|
- SST_0=1
|
||||||
- SD_0=1
|
- SD_0=0x1
|
||||||
- SST_1=1
|
|
||||||
- SD_1=12
|
|
||||||
- AMF_INTERFACE_NAME_FOR_NGAP=eth0
|
- AMF_INTERFACE_NAME_FOR_NGAP=eth0
|
||||||
- AMF_INTERFACE_NAME_FOR_N11=eth0
|
- AMF_INTERFACE_NAME_FOR_N11=eth0
|
||||||
- SMF_INSTANCE_ID_0=1
|
- SMF_INSTANCE_ID_0=1
|
||||||
@@ -168,22 +191,30 @@ services:
|
|||||||
- OPERATOR_KEY=1006020f0a478bf6b699f15c062e42b3
|
- OPERATOR_KEY=1006020f0a478bf6b699f15c062e42b3
|
||||||
- NRF_IPV4_ADDRESS=192.168.70.130
|
- NRF_IPV4_ADDRESS=192.168.70.130
|
||||||
- NRF_PORT=80
|
- NRF_PORT=80
|
||||||
|
- EXTERNAL_NRF=no
|
||||||
- NF_REGISTRATION=yes
|
- NF_REGISTRATION=yes
|
||||||
- SMF_SELECTION=yes
|
- SMF_SELECTION=yes
|
||||||
- USE_FQDN_DNS=yes
|
- USE_FQDN_DNS=yes
|
||||||
- EXTERNAL_AUSF=yes
|
- EXTERNAL_AUSF=yes
|
||||||
|
- EXTERNAL_UDM=no
|
||||||
|
- EXTERNAL_NSSF=no
|
||||||
|
- USE_HTTP2=no
|
||||||
- NRF_API_VERSION=v1
|
- NRF_API_VERSION=v1
|
||||||
- NRF_FQDN=oai-nrf
|
- NRF_FQDN=oai-nrf
|
||||||
- AUSF_IPV4_ADDRESS=192.168.70.138
|
- AUSF_IPV4_ADDRESS=192.168.70.138
|
||||||
- AUSF_PORT=80
|
- AUSF_PORT=80
|
||||||
- AUSF_API_VERSION=v1
|
- AUSF_API_VERSION=v1
|
||||||
- AUSF_FQDN=oai-ausf
|
- AUSF_FQDN=oai-ausf
|
||||||
|
- UDM_IPV4_ADDRESS=192.168.70.137
|
||||||
|
- UDM_PORT=80
|
||||||
|
- UDM_API_VERSION=v2
|
||||||
|
- UDM_FQDN=oai-udm
|
||||||
depends_on:
|
depends_on:
|
||||||
- mysql
|
- mysql
|
||||||
- oai-nrf
|
- oai-nrf
|
||||||
- oai-ausf
|
- oai-ausf
|
||||||
volumes:
|
volumes:
|
||||||
- ./amf-healthcheck.sh:/openair-amf/bin/amf-healthcheck.sh
|
- ./healthscripts/amf-healthcheck.sh:/openair-amf/bin/amf-healthcheck.sh
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: /bin/bash -c "/openair-amf/bin/amf-healthcheck.sh"
|
test: /bin/bash -c "/openair-amf/bin/amf-healthcheck.sh"
|
||||||
interval: 10s
|
interval: 10s
|
||||||
@@ -212,26 +243,35 @@ services:
|
|||||||
- AMF_FQDN=oai-amf
|
- AMF_FQDN=oai-amf
|
||||||
- UDM_IPV4_ADDRESS=192.168.70.137
|
- UDM_IPV4_ADDRESS=192.168.70.137
|
||||||
- UDM_PORT=80
|
- UDM_PORT=80
|
||||||
- UDM_API_VERSION=v1
|
- UDM_API_VERSION=v2
|
||||||
- UDM_FQDN=oai-udm
|
- UDM_FQDN=oai-udm
|
||||||
- UPF_IPV4_ADDRESS=192.168.70.134
|
- UPF_IPV4_ADDRESS=192.168.70.134
|
||||||
- UPF_FQDN_0=oai-spgwu
|
- UPF_FQDN_0=oai-spgwu
|
||||||
- NRF_IPV4_ADDRESS=192.168.70.130
|
- NRF_IPV4_ADDRESS=192.168.70.130
|
||||||
- NRF_PORT=80
|
- NRF_PORT=80
|
||||||
- NRF_API_VERSION=v1
|
- NRF_API_VERSION=v1
|
||||||
- USE_LOCAL_SUBSCRIPTION_INFO=yes
|
- USE_LOCAL_SUBSCRIPTION_INFO=yes #Set to yes if SMF uses local subscription information instead of from an UDM
|
||||||
|
- USE_NETWORK_INSTANCE=no #Set yes if network instance is to be used for given UPF
|
||||||
- NRF_FQDN=oai-nrf
|
- NRF_FQDN=oai-nrf
|
||||||
- REGISTER_NRF=yes
|
- REGISTER_NRF=yes
|
||||||
- DISCOVER_UPF=yes
|
- DISCOVER_UPF=yes
|
||||||
- USE_FQDN_DNS=yes
|
- USE_FQDN_DNS=yes
|
||||||
- DNN_RANGE1=12.1.1.2 - 12.1.1.128
|
- HTTP_VERSION=1 # Default: 1
|
||||||
- DNN_RANGE0=12.2.1.2 - 12.2.1.128
|
- UE_MTU=1500
|
||||||
- DNN_NI1=oai
|
- DNN_NI0=oai
|
||||||
|
- TYPE0=IPv4
|
||||||
|
- DNN_RANGE0=12.1.1.2 - 12.1.1.253
|
||||||
|
- NSSAI_SST0=1
|
||||||
|
- NSSAI_SD0=0x1
|
||||||
|
- SESSION_AMBR_UL0=1000Mbps
|
||||||
|
- SESSION_AMBR_DL0=1000Mbps
|
||||||
|
- DEFAULT_CSCF_IPV4_ADDRESS=127.0.0.1 # only needed when ims is being used
|
||||||
|
- ENABLE_USAGE_REPORTING=no # Set yes if UE USAGE REPORTING is to be done at UPF
|
||||||
depends_on:
|
depends_on:
|
||||||
- oai-nrf
|
- oai-nrf
|
||||||
- oai-amf
|
- oai-amf
|
||||||
volumes:
|
volumes:
|
||||||
- ./smf-healthcheck.sh:/openair-smf/bin/smf-healthcheck.sh
|
- ./healthscripts/smf-healthcheck.sh:/openair-smf/bin/smf-healthcheck.sh
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: /bin/bash -c "/openair-smf/bin/smf-healthcheck.sh"
|
test: /bin/bash -c "/openair-smf/bin/smf-healthcheck.sh"
|
||||||
interval: 10s
|
interval: 10s
|
||||||
@@ -258,17 +298,23 @@ services:
|
|||||||
- MNC03=099
|
- MNC03=099
|
||||||
- TAC=1
|
- TAC=1
|
||||||
- GW_ID=1
|
- GW_ID=1
|
||||||
|
- THREAD_S1U_PRIO=80
|
||||||
|
- S1U_THREADS=8
|
||||||
|
- THREAD_SX_PRIO=81
|
||||||
|
- SX_THREADS=1
|
||||||
|
- THREAD_SGI_PRIO=80
|
||||||
|
- SGI_THREADS=8
|
||||||
- REALM=openairinterface.org
|
- REALM=openairinterface.org
|
||||||
- ENABLE_5G_FEATURES=yes
|
- ENABLE_5G_FEATURES=yes
|
||||||
- REGISTER_NRF=yes
|
- REGISTER_NRF=yes
|
||||||
- USE_FQDN_NRF=no
|
- USE_FQDN_NRF=yes
|
||||||
- UPF_FQDN_5G=oai-spgwu
|
- UPF_FQDN_5G=oai-spgwu
|
||||||
- NRF_IPV4_ADDRESS=192.168.70.130
|
- NRF_IPV4_ADDRESS=192.168.70.130
|
||||||
- NRF_PORT=80
|
- NRF_PORT=80
|
||||||
- NRF_API_VERSION=v1
|
- NRF_API_VERSION=v1
|
||||||
- NRF_FQDN=oai-nrf
|
- NRF_FQDN=oai-nrf
|
||||||
- NSSAI_SST_0=1
|
- NSSAI_SST_0=1
|
||||||
- NSSAI_SD_0=1
|
- NSSAI_SD_0=0x1
|
||||||
- DNN_0=oai
|
- DNN_0=oai
|
||||||
depends_on:
|
depends_on:
|
||||||
- oai-nrf
|
- oai-nrf
|
||||||
@@ -280,7 +326,7 @@ services:
|
|||||||
- ALL
|
- ALL
|
||||||
privileged: true
|
privileged: true
|
||||||
volumes:
|
volumes:
|
||||||
- ./spgwu-healthcheck.sh:/openair-spgwu-tiny/bin/spgwu-healthcheck.sh
|
- ./healthscripts/spgwu-healthcheck.sh:/openair-spgwu-tiny/bin/spgwu-healthcheck.sh
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: /bin/bash -c "/openair-spgwu-tiny/bin/spgwu-healthcheck.sh"
|
test: /bin/bash -c "/openair-spgwu-tiny/bin/spgwu-healthcheck.sh"
|
||||||
interval: 10s
|
interval: 10s
|
||||||
@@ -290,12 +336,10 @@ services:
|
|||||||
public_net:
|
public_net:
|
||||||
ipv4_address: 192.168.70.134
|
ipv4_address: 192.168.70.134
|
||||||
oai-ext-dn:
|
oai-ext-dn:
|
||||||
image: ubuntu:bionic
|
image: trf-gen-cn5g:latest
|
||||||
privileged: true
|
privileged: true
|
||||||
container_name: oai-ext-dn
|
container_name: oai-ext-dn
|
||||||
entrypoint: /bin/bash -c \
|
entrypoint: /bin/bash -c \
|
||||||
"apt update; apt install -y iptables iproute2 iperf iperf3 iputils-ping;"\
|
|
||||||
"iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE;"\
|
|
||||||
"ip route add 12.1.1.0/24 via 192.168.70.134 dev eth0; sleep infinity"
|
"ip route add 12.1.1.0/24 via 192.168.70.134 dev eth0; sleep infinity"
|
||||||
depends_on:
|
depends_on:
|
||||||
- oai-spgwu
|
- oai-spgwu
|
||||||
@@ -303,14 +347,14 @@ services:
|
|||||||
public_net:
|
public_net:
|
||||||
ipv4_address: 192.168.70.135
|
ipv4_address: 192.168.70.135
|
||||||
networks:
|
networks:
|
||||||
|
# public_net:
|
||||||
|
# external:
|
||||||
|
# name: demo-oai-public-net
|
||||||
public_net:
|
public_net:
|
||||||
external:
|
driver: bridge
|
||||||
name: demo-oai-public-net
|
name: demo-oai-public-net
|
||||||
# public_net:
|
ipam:
|
||||||
# driver: bridge
|
config:
|
||||||
# name: demo-oai-public-net
|
- subnet: 192.168.70.128/26
|
||||||
# ipam:
|
driver_opts:
|
||||||
# config:
|
com.docker.network.bridge.name: "demo-oai"
|
||||||
# - subnet: 192.168.70.128/26
|
|
||||||
# driver_opts:
|
|
||||||
# com.docker.network.bridge.name: "demo-oai"
|
|
||||||
|
|||||||
@@ -151,10 +151,13 @@ CREATE TABLE `AuthenticationSubscription` (
|
|||||||
--
|
--
|
||||||
|
|
||||||
INSERT INTO `AuthenticationSubscription` (`ueid`, `authenticationMethod`, `encPermanentKey`, `protectionParameterId`, `sequenceNumber`, `authenticationManagementField`, `algorithmId`, `encOpcKey`, `encTopcKey`, `vectorGenerationInHss`, `n5gcAuthMethod`, `rgAuthenticationInd`, `supi`) VALUES
|
INSERT INTO `AuthenticationSubscription` (`ueid`, `authenticationMethod`, `encPermanentKey`, `protectionParameterId`, `sequenceNumber`, `authenticationManagementField`, `algorithmId`, `encOpcKey`, `encTopcKey`, `vectorGenerationInHss`, `n5gcAuthMethod`, `rgAuthenticationInd`, `supi`) VALUES
|
||||||
('208950000000031', '5G_AKA', '0C0A34601D4F07677303652C0462535B', '0C0A34601D4F07677303652C0462535B', '{\"sqn\": \"000000000020\", \"sqnScheme\": \"NON_TIME_BASED\", \"lastIndexes\": {\"ausf\": 0}}', '8000', 'milenage', '63bfa50ee6523365ff14c1f45f88737d', NULL, NULL, NULL, NULL, '208950000000031');
|
('2089900007487', '5G_AKA', 'fec86ba6eb707ed08905757b1bb44b8f', 'fec86ba6eb707ed08905757b1bb44b8f', '{\"sqn\": \"000000000000\", \"sqnScheme\": \"NON_TIME_BASED\", \"lastIndexes\": {\"ausf\": 0}}', '8000', 'milenage', 'C42449363BBAD02B66D16BC975D77CC1', NULL, NULL, NULL, NULL, '2089900007487');
|
||||||
|
|
||||||
INSERT INTO `AuthenticationSubscription` (`ueid`, `authenticationMethod`, `encPermanentKey`, `protectionParameterId`, `sequenceNumber`, `authenticationManagementField`, `algorithmId`, `encOpcKey`, `encTopcKey`, `vectorGenerationInHss`, `n5gcAuthMethod`, `rgAuthenticationInd`, `supi`) VALUES
|
INSERT INTO `AuthenticationSubscription` (`ueid`, `authenticationMethod`, `encPermanentKey`, `protectionParameterId`, `sequenceNumber`, `authenticationManagementField`, `algorithmId`, `encOpcKey`, `encTopcKey`, `vectorGenerationInHss`, `n5gcAuthMethod`, `rgAuthenticationInd`, `supi`) VALUES
|
||||||
('208990000000001', '5G_AKA', 'fec86ba6eb707ed08905757b1bb44b8f', 'fec86ba6eb707ed08905757b1bb44b8f', '{\"sqn\": \"000000000020\", \"sqnScheme\": \"NON_TIME_BASED\", \"lastIndexes\": {\"ausf\": 0}}', '8000', 'milenage', 'C42449363BBAD02B66D16BC975D77CC1', NULL, NULL, NULL, NULL, '208990000000001');
|
('208990000000001', '5G_AKA', 'fec86ba6eb707ed08905757b1bb44b8f', 'fec86ba6eb707ed08905757b1bb44b8f', '{\"sqn\": \"000000000000\", \"sqnScheme\": \"NON_TIME_BASED\", \"lastIndexes\": {\"ausf\": 0}}', '8000', 'milenage', 'C42449363BBAD02B66D16BC975D77CC1', NULL, NULL, NULL, NULL, '208990000000001');
|
||||||
|
INSERT INTO `AuthenticationSubscription` (`ueid`, `authenticationMethod`, `encPermanentKey`, `protectionParameterId`, `sequenceNumber`, `authenticationManagementField`, `algorithmId`, `encOpcKey`, `encTopcKey`, `vectorGenerationInHss`, `n5gcAuthMethod`, `rgAuthenticationInd`, `supi`) VALUES
|
||||||
|
('208990000000002', '5G_AKA', 'fec86ba6eb707ed08905757b1bb44b8f', 'fec86ba6eb707ed08905757b1bb44b8f', '{\"sqn\": \"000000000000\", \"sqnScheme\": \"NON_TIME_BASED\", \"lastIndexes\": {\"ausf\": 0}}', '8000', 'milenage', 'C42449363BBAD02B66D16BC975D77CC1', NULL, NULL, NULL, NULL, '208990000000002');
|
||||||
|
INSERT INTO `AuthenticationSubscription` (`ueid`, `authenticationMethod`, `encPermanentKey`, `protectionParameterId`, `sequenceNumber`, `authenticationManagementField`, `algorithmId`, `encOpcKey`, `encTopcKey`, `vectorGenerationInHss`, `n5gcAuthMethod`, `rgAuthenticationInd`, `supi`) VALUES
|
||||||
|
('208990000000003', '5G_AKA', 'fec86ba6eb707ed08905757b1bb44b8f', 'fec86ba6eb707ed08905757b1bb44b8f', '{\"sqn\": \"000000000000\", \"sqnScheme\": \"NON_TIME_BASED\", \"lastIndexes\": {\"ausf\": 0}}', '8000', 'milenage', 'C42449363BBAD02B66D16BC975D77CC1', NULL, NULL, NULL, NULL, '208990000000003');
|
||||||
|
|
||||||
-- --------------------------------------------------------
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
@@ -203,6 +206,19 @@ CREATE TABLE `SessionManagementSubscriptionData` (
|
|||||||
`3gppChargingCharacteristics` varchar(50) DEFAULT NULL
|
`3gppChargingCharacteristics` varchar(50) DEFAULT NULL
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Dumping data for table `SessionManagementSubscriptionData`
|
||||||
|
--
|
||||||
|
|
||||||
|
INSERT INTO `SessionManagementSubscriptionData` (`ueid`, `servingPlmnid`, `singleNssai`, `dnnConfigurations`) VALUES
|
||||||
|
('2089900007487', '20899', '{\"sst\": 1, \"sd\": \"1\"}','{\"oai\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4\"},\"sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 6,\"arp\":{\"priorityLevel\": 1,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"NOT_PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"1000Mbps\", \"downlink\":\"1000Mbps\"},\"staticIpAddress\":[{\"ipv4Addr\": \"12.1.1.2\"}]}}');
|
||||||
|
INSERT INTO `SessionManagementSubscriptionData` (`ueid`, `servingPlmnid`, `singleNssai`, `dnnConfigurations`) VALUES
|
||||||
|
('208990000000001', '20899', '{\"sst\": 1, \"sd\": \"1\"}','{\"oai\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4\"},\"sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 6,\"arp\":{\"priorityLevel\": 1,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"NOT_PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"1000Mbps\", \"downlink\":\"1000Mbps\"},\"staticIpAddress\":[{\"ipv4Addr\": \"12.1.1.2\"}]}}');
|
||||||
|
INSERT INTO `SessionManagementSubscriptionData` (`ueid`, `servingPlmnid`, `singleNssai`, `dnnConfigurations`) VALUES
|
||||||
|
('208990000000002', '20899', '{\"sst\": 1, \"sd\": \"1\"}','{\"oai\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4\"},\"sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 6,\"arp\":{\"priorityLevel\": 1,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"NOT_PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"1000Mbps\", \"downlink\":\"1000Mbps\"},\"staticIpAddress\":[{\"ipv4Addr\": \"12.1.1.3\"}]}}');
|
||||||
|
INSERT INTO `SessionManagementSubscriptionData` (`ueid`, `servingPlmnid`, `singleNssai`, `dnnConfigurations`) VALUES
|
||||||
|
('208990000000003', '20899', '{\"sst\": 1, \"sd\": \"1\"}','{\"oai\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4\"},\"sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 6,\"arp\":{\"priorityLevel\": 1,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"NOT_PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"1000Mbps\", \"downlink\":\"1000Mbps\"},\"staticIpAddress\":[{\"ipv4Addr\": \"12.1.1.4\"}]}}');
|
||||||
|
|
||||||
-- --------------------------------------------------------
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
--
|
--
|
||||||
|
|||||||
@@ -59,9 +59,6 @@ extern void set_function_spec_param(RU_t *ru);
|
|||||||
|
|
||||||
extern void reset_opp_meas(void);
|
extern void reset_opp_meas(void);
|
||||||
extern void print_opp_meas(void);
|
extern void print_opp_meas(void);
|
||||||
|
|
||||||
extern void init_fep_thread(PHY_VARS_gNB *);
|
|
||||||
|
|
||||||
void init_gNB_afterRU(void);
|
void init_gNB_afterRU(void);
|
||||||
|
|
||||||
extern int stop_L1L2(module_id_t gnb_id);
|
extern int stop_L1L2(module_id_t gnb_id);
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#define FAPI_NR_RX_PDU_TYPE_DLSCH 0x03
|
#define FAPI_NR_RX_PDU_TYPE_DLSCH 0x03
|
||||||
#define FAPI_NR_DCI_IND 0x04
|
#define FAPI_NR_DCI_IND 0x04
|
||||||
#define FAPI_NR_RX_PDU_TYPE_RAR 0x05
|
#define FAPI_NR_RX_PDU_TYPE_RAR 0x05
|
||||||
|
#define FAPI_NR_CSIRS_IND 0x06
|
||||||
|
|
||||||
#define FAPI_NR_SIBS_MASK_SIB1 0x1
|
#define FAPI_NR_SIBS_MASK_SIB1 0x1
|
||||||
|
|
||||||
|
|||||||
@@ -36,9 +36,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t uci_format;
|
uint8_t uci_format;
|
||||||
uint8_t uci_channel;
|
uint8_t uci_channel;
|
||||||
@@ -50,7 +47,14 @@ typedef struct {
|
|||||||
uint32_t sr;
|
uint32_t sr;
|
||||||
} fapi_nr_uci_pdu_rel15_t;
|
} fapi_nr_uci_pdu_rel15_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t rsrp;
|
||||||
|
int rsrp_dBm;
|
||||||
|
uint8_t rank_indicator;
|
||||||
|
uint8_t i1;
|
||||||
|
uint8_t i2;
|
||||||
|
uint8_t cqi;
|
||||||
|
} fapi_nr_csirs_measurements_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/// frequency_domain_resource;
|
/// frequency_domain_resource;
|
||||||
@@ -87,7 +91,7 @@ typedef struct {
|
|||||||
// N_CCE is L, or number of CCEs for DCI
|
// N_CCE is L, or number of CCEs for DCI
|
||||||
int N_CCE;
|
int N_CCE;
|
||||||
uint8_t payloadSize;
|
uint8_t payloadSize;
|
||||||
uint8_t payloadBits[16];
|
uint8_t payloadBits[16] __attribute__((aligned(16))); // will be cast as uint64
|
||||||
//fapi_nr_dci_pdu_rel15_t dci;
|
//fapi_nr_dci_pdu_rel15_t dci;
|
||||||
} fapi_nr_dci_indication_pdu_t;
|
} fapi_nr_dci_indication_pdu_t;
|
||||||
|
|
||||||
@@ -130,6 +134,7 @@ typedef struct {
|
|||||||
fapi_nr_pdsch_pdu_t pdsch_pdu;
|
fapi_nr_pdsch_pdu_t pdsch_pdu;
|
||||||
fapi_nr_ssb_pdu_t ssb_pdu;
|
fapi_nr_ssb_pdu_t ssb_pdu;
|
||||||
fapi_nr_sib_pdu_t sib_pdu;
|
fapi_nr_sib_pdu_t sib_pdu;
|
||||||
|
fapi_nr_csirs_measurements_t csirs_measurements;
|
||||||
};
|
};
|
||||||
} fapi_nr_rx_indication_body_t;
|
} fapi_nr_rx_indication_body_t;
|
||||||
|
|
||||||
|
|||||||
@@ -738,7 +738,7 @@ typedef struct {
|
|||||||
// The total DCI length (in bits) including padding bits [TS38.212 sec 7.3.1] Range 0->DCI_PAYLOAD_BYTE_LEN*8
|
// The total DCI length (in bits) including padding bits [TS38.212 sec 7.3.1] Range 0->DCI_PAYLOAD_BYTE_LEN*8
|
||||||
uint16_t PayloadSizeBits;
|
uint16_t PayloadSizeBits;
|
||||||
// DCI payload, where the actual size is defined by PayloadSizeBits. The bit order is as following bit0-bit7 are mapped to first byte of MSB - LSB
|
// DCI payload, where the actual size is defined by PayloadSizeBits. The bit order is as following bit0-bit7 are mapped to first byte of MSB - LSB
|
||||||
uint8_t Payload[DCI_PAYLOAD_BYTE_LEN];
|
uint8_t Payload[DCI_PAYLOAD_BYTE_LEN] __attribute__((aligned(32)));
|
||||||
|
|
||||||
} nfapi_nr_dl_dci_pdu_t;
|
} nfapi_nr_dl_dci_pdu_t;
|
||||||
|
|
||||||
|
|||||||
@@ -814,7 +814,7 @@ uint8_t phy_threegpplte_turbo_decoder8(int16_t *y,
|
|||||||
llr_t *s1,*s2,*yp1,*yp2,*yp;
|
llr_t *s1,*s2,*yp1,*yp2,*yp;
|
||||||
unsigned int i,j,iind;//,pi;
|
unsigned int i,j,iind;//,pi;
|
||||||
unsigned char iteration_cnt=0;
|
unsigned char iteration_cnt=0;
|
||||||
unsigned int crc,oldcrc,crc_len;
|
unsigned int crc, crc_len;
|
||||||
uint8_t temp;
|
uint8_t temp;
|
||||||
#if defined(__x86_64__) || defined(__i386__)
|
#if defined(__x86_64__) || defined(__i386__)
|
||||||
__m128i *yp128;
|
__m128i *yp128;
|
||||||
@@ -1233,8 +1233,8 @@ uint8_t phy_threegpplte_turbo_decoder8(int16_t *y,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check the CRC
|
// check the CRC
|
||||||
oldcrc= *((unsigned int *)(&decoded_bytes[(n>>3)-crc_len]));
|
uint32_t oldcrc;
|
||||||
|
memcpy(&oldcrc, &decoded_bytes[(n >> 3) - crc_len], crc_len);
|
||||||
switch (crc_type) {
|
switch (crc_type) {
|
||||||
case CRC24_A:
|
case CRC24_A:
|
||||||
oldcrc&=0x00ffffff;
|
oldcrc&=0x00ffffff;
|
||||||
|
|||||||
@@ -244,11 +244,11 @@ crc16 (unsigned char * inptr, int bitlen)
|
|||||||
|
|
||||||
while (octetlen-- > 0) {
|
while (octetlen-- > 0) {
|
||||||
|
|
||||||
crc = (crc << 8) ^ (crc16Table[(*inptr++) ^ (crc >> 24)] << 16);
|
crc = (crc << 8) ^ (((uint32_t)crc16Table[(*inptr++) ^ (crc >> 24)]) << 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resbit > 0)
|
if (resbit > 0)
|
||||||
crc = (crc << resbit) ^ (crc16Table[((*inptr) >> (8 - resbit)) ^ (crc >> (32 - resbit))] << 16);
|
crc = (crc << resbit) ^ (((uint32_t)crc16Table[(*inptr) >> (8 - resbit) ^ (crc >> (32 - resbit))]) << 16);
|
||||||
|
|
||||||
return crc;
|
return crc;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -961,7 +961,8 @@ static inline uint32_t nrLDPC_cnProcPc_BG1(t_nrLDPC_lut* p_lut, int8_t* cnProcBu
|
|||||||
|
|
||||||
// If no error pcRes should be 0
|
// If no error pcRes should be 0
|
||||||
// Only use valid CNs
|
// Only use valid CNs
|
||||||
pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem)));
|
if (Mrem)
|
||||||
|
pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem)));
|
||||||
|
|
||||||
// If PC failed we can stop here
|
// If PC failed we can stop here
|
||||||
if (pcResSum > 0)
|
if (pcResSum > 0)
|
||||||
@@ -1028,7 +1029,8 @@ static inline uint32_t nrLDPC_cnProcPc_BG1(t_nrLDPC_lut* p_lut, int8_t* cnProcBu
|
|||||||
|
|
||||||
// If no error pcRes should be 0
|
// If no error pcRes should be 0
|
||||||
// Only use valid CNs
|
// Only use valid CNs
|
||||||
pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem)));
|
if (Mrem)
|
||||||
|
pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem)));
|
||||||
|
|
||||||
// If PC failed we can stop here
|
// If PC failed we can stop here
|
||||||
if (pcResSum > 0)
|
if (pcResSum > 0)
|
||||||
@@ -1096,7 +1098,8 @@ static inline uint32_t nrLDPC_cnProcPc_BG1(t_nrLDPC_lut* p_lut, int8_t* cnProcBu
|
|||||||
|
|
||||||
// If no error pcRes should be 0
|
// If no error pcRes should be 0
|
||||||
// Only use valid CNs
|
// Only use valid CNs
|
||||||
pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem)));
|
if (Mrem)
|
||||||
|
pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem)));
|
||||||
|
|
||||||
// If PC failed we can stop here
|
// If PC failed we can stop here
|
||||||
if (pcResSum > 0)
|
if (pcResSum > 0)
|
||||||
@@ -1163,7 +1166,8 @@ static inline uint32_t nrLDPC_cnProcPc_BG1(t_nrLDPC_lut* p_lut, int8_t* cnProcBu
|
|||||||
|
|
||||||
// If no error pcRes should be 0
|
// If no error pcRes should be 0
|
||||||
// Only use valid CNs
|
// Only use valid CNs
|
||||||
pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem)));
|
if (Mrem)
|
||||||
|
pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem)));
|
||||||
|
|
||||||
// If PC failed we can stop here
|
// If PC failed we can stop here
|
||||||
if (pcResSum > 0)
|
if (pcResSum > 0)
|
||||||
@@ -1230,7 +1234,8 @@ static inline uint32_t nrLDPC_cnProcPc_BG1(t_nrLDPC_lut* p_lut, int8_t* cnProcBu
|
|||||||
|
|
||||||
// If no error pcRes should be 0
|
// If no error pcRes should be 0
|
||||||
// Only use valid CNs
|
// Only use valid CNs
|
||||||
pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem)));
|
if (Mrem)
|
||||||
|
pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem)));
|
||||||
|
|
||||||
// If PC failed we can stop here
|
// If PC failed we can stop here
|
||||||
if (pcResSum > 0)
|
if (pcResSum > 0)
|
||||||
@@ -1297,7 +1302,8 @@ static inline uint32_t nrLDPC_cnProcPc_BG1(t_nrLDPC_lut* p_lut, int8_t* cnProcBu
|
|||||||
|
|
||||||
// If no error pcRes should be 0
|
// If no error pcRes should be 0
|
||||||
// Only use valid CNs
|
// Only use valid CNs
|
||||||
pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem)));
|
if (Mrem)
|
||||||
|
pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem)));
|
||||||
|
|
||||||
// If PC failed we can stop here
|
// If PC failed we can stop here
|
||||||
if (pcResSum > 0)
|
if (pcResSum > 0)
|
||||||
@@ -1364,7 +1370,8 @@ static inline uint32_t nrLDPC_cnProcPc_BG1(t_nrLDPC_lut* p_lut, int8_t* cnProcBu
|
|||||||
|
|
||||||
// If no error pcRes should be 0
|
// If no error pcRes should be 0
|
||||||
// Only use valid CNs
|
// Only use valid CNs
|
||||||
pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem)));
|
if (Mrem)
|
||||||
|
pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem)));
|
||||||
|
|
||||||
// If PC failed we can stop here
|
// If PC failed we can stop here
|
||||||
if (pcResSum > 0)
|
if (pcResSum > 0)
|
||||||
@@ -1431,7 +1438,8 @@ static inline uint32_t nrLDPC_cnProcPc_BG1(t_nrLDPC_lut* p_lut, int8_t* cnProcBu
|
|||||||
|
|
||||||
// If no error pcRes should be 0
|
// If no error pcRes should be 0
|
||||||
// Only use valid CNs
|
// Only use valid CNs
|
||||||
pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem)));
|
if (Mrem)
|
||||||
|
pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem)));
|
||||||
|
|
||||||
// If PC failed we can stop here
|
// If PC failed we can stop here
|
||||||
if (pcResSum > 0)
|
if (pcResSum > 0)
|
||||||
@@ -1498,7 +1506,8 @@ static inline uint32_t nrLDPC_cnProcPc_BG1(t_nrLDPC_lut* p_lut, int8_t* cnProcBu
|
|||||||
|
|
||||||
// If no error pcRes should be 0
|
// If no error pcRes should be 0
|
||||||
// Only use valid CNs
|
// Only use valid CNs
|
||||||
pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem)));
|
if (Mrem)
|
||||||
|
pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem)));
|
||||||
|
|
||||||
// If PC failed we can stop here
|
// If PC failed we can stop here
|
||||||
if (pcResSum > 0)
|
if (pcResSum > 0)
|
||||||
@@ -1593,7 +1602,8 @@ static inline uint32_t nrLDPC_cnProcPc_BG2(t_nrLDPC_lut* p_lut, int8_t* cnProcBu
|
|||||||
|
|
||||||
// If no error pcRes should be 0
|
// If no error pcRes should be 0
|
||||||
// Only use valid CNs
|
// Only use valid CNs
|
||||||
pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem)));
|
if (Mrem)
|
||||||
|
pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem)));
|
||||||
|
|
||||||
// If PC failed we can stop here
|
// If PC failed we can stop here
|
||||||
if (pcResSum > 0)
|
if (pcResSum > 0)
|
||||||
@@ -1660,7 +1670,8 @@ static inline uint32_t nrLDPC_cnProcPc_BG2(t_nrLDPC_lut* p_lut, int8_t* cnProcBu
|
|||||||
|
|
||||||
// If no error pcRes should be 0
|
// If no error pcRes should be 0
|
||||||
// Only use valid CNs
|
// Only use valid CNs
|
||||||
pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem)));
|
if (Mrem)
|
||||||
|
pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem)));
|
||||||
|
|
||||||
// If PC failed we can stop here
|
// If PC failed we can stop here
|
||||||
if (pcResSum > 0)
|
if (pcResSum > 0)
|
||||||
@@ -1727,7 +1738,8 @@ static inline uint32_t nrLDPC_cnProcPc_BG2(t_nrLDPC_lut* p_lut, int8_t* cnProcBu
|
|||||||
|
|
||||||
// If no error pcRes should be 0
|
// If no error pcRes should be 0
|
||||||
// Only use valid CNs
|
// Only use valid CNs
|
||||||
pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem)));
|
if (Mrem)
|
||||||
|
pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem)));
|
||||||
|
|
||||||
// If PC failed we can stop here
|
// If PC failed we can stop here
|
||||||
if (pcResSum > 0)
|
if (pcResSum > 0)
|
||||||
@@ -1794,7 +1806,8 @@ static inline uint32_t nrLDPC_cnProcPc_BG2(t_nrLDPC_lut* p_lut, int8_t* cnProcBu
|
|||||||
|
|
||||||
// If no error pcRes should be 0
|
// If no error pcRes should be 0
|
||||||
// Only use valid CNs
|
// Only use valid CNs
|
||||||
pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem)));
|
if (Mrem)
|
||||||
|
pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem)));
|
||||||
|
|
||||||
// If PC failed we can stop here
|
// If PC failed we can stop here
|
||||||
if (pcResSum > 0)
|
if (pcResSum > 0)
|
||||||
@@ -1861,7 +1874,8 @@ static inline uint32_t nrLDPC_cnProcPc_BG2(t_nrLDPC_lut* p_lut, int8_t* cnProcBu
|
|||||||
|
|
||||||
// If no error pcRes should be 0
|
// If no error pcRes should be 0
|
||||||
// Only use valid CNs
|
// Only use valid CNs
|
||||||
pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem)));
|
if (Mrem)
|
||||||
|
pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem)));
|
||||||
|
|
||||||
// If PC failed we can stop here
|
// If PC failed we can stop here
|
||||||
if (pcResSum > 0)
|
if (pcResSum > 0)
|
||||||
@@ -1928,7 +1942,8 @@ static inline uint32_t nrLDPC_cnProcPc_BG2(t_nrLDPC_lut* p_lut, int8_t* cnProcBu
|
|||||||
|
|
||||||
// If no error pcRes should be 0
|
// If no error pcRes should be 0
|
||||||
// Only use valid CNs
|
// Only use valid CNs
|
||||||
pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem)));
|
if (Mrem)
|
||||||
|
pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem)));
|
||||||
|
|
||||||
// If PC failed we can stop here
|
// If PC failed we can stop here
|
||||||
if (pcResSum > 0)
|
if (pcResSum > 0)
|
||||||
|
|||||||
+11
-11
@@ -596,20 +596,20 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
|
|||||||
// CSI RS init
|
// CSI RS init
|
||||||
// ceil((NB_RB*8(max allocation per RB)*2(QPSK))/32)
|
// ceil((NB_RB*8(max allocation per RB)*2(QPSK))/32)
|
||||||
int csi_dmrs_init_length = ((fp->N_RB_DL<<4)>>5)+1;
|
int csi_dmrs_init_length = ((fp->N_RB_DL<<4)>>5)+1;
|
||||||
gNB->nr_csi_rs_info = (nr_csi_rs_info_t *)malloc16_clear(sizeof(nr_csi_rs_info_t));
|
gNB->nr_csi_info = (nr_csi_info_t *)malloc16_clear(sizeof(nr_csi_info_t));
|
||||||
gNB->nr_csi_rs_info->nr_gold_csi_rs = (uint32_t ***)malloc16(fp->slots_per_frame*sizeof(uint32_t **));
|
gNB->nr_csi_info->nr_gold_csi_rs = (uint32_t ***)malloc16(fp->slots_per_frame * sizeof(uint32_t **));
|
||||||
AssertFatal(gNB->nr_csi_rs_info->nr_gold_csi_rs!=NULL, "NR init: csi reference signal malloc failed\n");
|
AssertFatal(gNB->nr_csi_info->nr_gold_csi_rs != NULL, "NR init: csi reference signal malloc failed\n");
|
||||||
for (int slot=0; slot<fp->slots_per_frame; slot++) {
|
for (int slot=0; slot<fp->slots_per_frame; slot++) {
|
||||||
gNB->nr_csi_rs_info->nr_gold_csi_rs[slot] = (uint32_t **)malloc16(fp->symbols_per_slot*sizeof(uint32_t *));
|
gNB->nr_csi_info->nr_gold_csi_rs[slot] = (uint32_t **)malloc16(fp->symbols_per_slot * sizeof(uint32_t *));
|
||||||
AssertFatal(gNB->nr_csi_rs_info->nr_gold_csi_rs[slot]!=NULL, "NR init: csi reference signal for slot %d - malloc failed\n", slot);
|
AssertFatal(gNB->nr_csi_info->nr_gold_csi_rs[slot] != NULL, "NR init: csi reference signal for slot %d - malloc failed\n", slot);
|
||||||
for (int symb=0; symb<fp->symbols_per_slot; symb++) {
|
for (int symb=0; symb<fp->symbols_per_slot; symb++) {
|
||||||
gNB->nr_csi_rs_info->nr_gold_csi_rs[slot][symb] = (uint32_t *)malloc16(csi_dmrs_init_length*sizeof(uint32_t));
|
gNB->nr_csi_info->nr_gold_csi_rs[slot][symb] = (uint32_t *)malloc16(csi_dmrs_init_length * sizeof(uint32_t));
|
||||||
AssertFatal(gNB->nr_csi_rs_info->nr_gold_csi_rs[slot][symb]!=NULL, "NR init: csi reference signal for slot %d symbol %d - malloc failed\n", slot, symb);
|
AssertFatal(gNB->nr_csi_info->nr_gold_csi_rs[slot][symb] != NULL, "NR init: csi reference signal for slot %d symbol %d - malloc failed\n", slot, symb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gNB->nr_csi_rs_info->csi_gold_init = cfg->cell_config.phy_cell_id.value;
|
gNB->nr_csi_info->csi_gold_init = cfg->cell_config.phy_cell_id.value;
|
||||||
nr_init_csi_rs(&gNB->frame_parms, gNB->nr_csi_rs_info->nr_gold_csi_rs, cfg->cell_config.phy_cell_id.value);
|
nr_init_csi_rs(&gNB->frame_parms, gNB->nr_csi_info->nr_gold_csi_rs, cfg->cell_config.phy_cell_id.value);
|
||||||
|
|
||||||
for (int id=0; id<NUMBER_OF_NR_SRS_MAX; id++) {
|
for (int id=0; id<NUMBER_OF_NR_SRS_MAX; id++) {
|
||||||
gNB->nr_srs_info[id] = (nr_srs_info_t *)malloc16_clear(sizeof(nr_srs_info_t));
|
gNB->nr_srs_info[id] = (nr_srs_info_t *)malloc16_clear(sizeof(nr_srs_info_t));
|
||||||
@@ -760,14 +760,14 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
|
|||||||
}
|
}
|
||||||
free_and_zero(pusch_dmrs);
|
free_and_zero(pusch_dmrs);
|
||||||
|
|
||||||
uint32_t ***nr_gold_csi_rs = gNB->nr_csi_rs_info->nr_gold_csi_rs;
|
uint32_t ***nr_gold_csi_rs = gNB->nr_csi_info->nr_gold_csi_rs;
|
||||||
for (int slot = 0; slot < fp->slots_per_frame; slot++) {
|
for (int slot = 0; slot < fp->slots_per_frame; slot++) {
|
||||||
for (int symb = 0; symb < fp->symbols_per_slot; symb++)
|
for (int symb = 0; symb < fp->symbols_per_slot; symb++)
|
||||||
free_and_zero(nr_gold_csi_rs[slot][symb]);
|
free_and_zero(nr_gold_csi_rs[slot][symb]);
|
||||||
free_and_zero(nr_gold_csi_rs[slot]);
|
free_and_zero(nr_gold_csi_rs[slot]);
|
||||||
}
|
}
|
||||||
free_and_zero(nr_gold_csi_rs);
|
free_and_zero(nr_gold_csi_rs);
|
||||||
free_and_zero(gNB->nr_csi_rs_info);
|
free_and_zero(gNB->nr_csi_info);
|
||||||
|
|
||||||
for (int id = 0; id < NUMBER_OF_NR_SRS_MAX; id++) {
|
for (int id = 0; id < NUMBER_OF_NR_SRS_MAX; id++) {
|
||||||
free_and_zero(gNB->nr_srs_info[id]);
|
free_and_zero(gNB->nr_srs_info[id]);
|
||||||
|
|||||||
@@ -34,19 +34,6 @@
|
|||||||
#include "PHY/NR_REFSIG/nr_refsig.h"
|
#include "PHY/NR_REFSIG/nr_refsig.h"
|
||||||
#include "PHY/MODULATION/nr_modulation.h"
|
#include "PHY/MODULATION/nr_modulation.h"
|
||||||
|
|
||||||
#if 0
|
|
||||||
void phy_config_harq_ue(module_id_t Mod_id,
|
|
||||||
int CC_id,
|
|
||||||
uint8_t gNB_id,
|
|
||||||
uint16_t max_harq_tx) {
|
|
||||||
int num_of_threads,num_of_code_words;
|
|
||||||
PHY_VARS_NR_UE *phy_vars_ue = PHY_vars_UE_g[Mod_id][CC_id];
|
|
||||||
|
|
||||||
for (num_of_threads=0; num_of_threads<RX_NB_TH_MAX; num_of_threads++)
|
|
||||||
for (num_of_code_words=0; num_of_code_words<NR_MAX_NB_CODEWORDS; num_of_code_words++)
|
|
||||||
phy_vars_ue->ulsch[num_of_threads][gNB_id][num_of_code_words]->Mlimit = max_harq_tx;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern uint16_t beta_cqi[16];
|
extern uint16_t beta_cqi[16];
|
||||||
|
|
||||||
@@ -159,7 +146,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
|
|||||||
NR_UE_CSI_RS **const csirs_vars = ue->csirs_vars;
|
NR_UE_CSI_RS **const csirs_vars = ue->csirs_vars;
|
||||||
NR_UE_SRS **const srs_vars = ue->srs_vars;
|
NR_UE_SRS **const srs_vars = ue->srs_vars;
|
||||||
|
|
||||||
int i, j, slot, symb, gNB_id, th_id;
|
int i, slot, symb, gNB_id, th_id;
|
||||||
|
|
||||||
LOG_I(PHY, "Initializing UE vars for gNB TXant %u, UE RXant %u\n", fp->nb_antennas_tx, fp->nb_antennas_rx);
|
LOG_I(PHY, "Initializing UE vars for gNB TXant %u, UE RXant %u\n", fp->nb_antennas_tx, fp->nb_antennas_rx);
|
||||||
|
|
||||||
@@ -347,33 +334,20 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
|
|||||||
|
|
||||||
// ceil((NB_RB*8(max allocation per RB)*2(QPSK))/32)
|
// ceil((NB_RB*8(max allocation per RB)*2(QPSK))/32)
|
||||||
int csi_dmrs_init_length = ((fp->N_RB_DL<<4)>>5)+1;
|
int csi_dmrs_init_length = ((fp->N_RB_DL<<4)>>5)+1;
|
||||||
ue->nr_csi_rs_info = (nr_csi_rs_info_t *)malloc16_clear(sizeof(nr_csi_rs_info_t));
|
ue->nr_csi_info = (nr_csi_info_t *)malloc16_clear(sizeof(nr_csi_info_t));
|
||||||
ue->nr_csi_rs_info->nr_gold_csi_rs = (uint32_t ***)malloc16(fp->slots_per_frame*sizeof(uint32_t **));
|
ue->nr_csi_info->nr_gold_csi_rs = (uint32_t ***)malloc16(fp->slots_per_frame * sizeof(uint32_t **));
|
||||||
AssertFatal(ue->nr_csi_rs_info->nr_gold_csi_rs!=NULL, "NR init: csi reference signal malloc failed\n");
|
AssertFatal(ue->nr_csi_info->nr_gold_csi_rs != NULL, "NR init: csi reference signal malloc failed\n");
|
||||||
for (int slot=0; slot<fp->slots_per_frame; slot++) {
|
for (int slot=0; slot<fp->slots_per_frame; slot++) {
|
||||||
ue->nr_csi_rs_info->nr_gold_csi_rs[slot] = (uint32_t **)malloc16(fp->symbols_per_slot*sizeof(uint32_t *));
|
ue->nr_csi_info->nr_gold_csi_rs[slot] = (uint32_t **)malloc16(fp->symbols_per_slot * sizeof(uint32_t *));
|
||||||
AssertFatal(ue->nr_csi_rs_info->nr_gold_csi_rs[slot]!=NULL, "NR init: csi reference signal for slot %d - malloc failed\n", slot);
|
AssertFatal(ue->nr_csi_info->nr_gold_csi_rs[slot] != NULL, "NR init: csi reference signal for slot %d - malloc failed\n", slot);
|
||||||
for (int symb=0; symb<fp->symbols_per_slot; symb++) {
|
for (int symb=0; symb<fp->symbols_per_slot; symb++) {
|
||||||
ue->nr_csi_rs_info->nr_gold_csi_rs[slot][symb] = (uint32_t *)malloc16(csi_dmrs_init_length*sizeof(uint32_t));
|
ue->nr_csi_info->nr_gold_csi_rs[slot][symb] = (uint32_t *)malloc16(csi_dmrs_init_length * sizeof(uint32_t));
|
||||||
AssertFatal(ue->nr_csi_rs_info->nr_gold_csi_rs[slot][symb]!=NULL, "NR init: csi reference signal for slot %d symbol %d - malloc failed\n", slot, symb);
|
AssertFatal(ue->nr_csi_info->nr_gold_csi_rs[slot][symb] != NULL, "NR init: csi reference signal for slot %d symbol %d - malloc failed\n", slot, symb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ue->nr_csi_rs_info->noise_power = (uint32_t*)malloc16_clear(sizeof(uint32_t));
|
ue->nr_csi_info->csi_rs_generated_signal = (int32_t **)malloc16(NR_MAX_NB_PORTS * sizeof(int32_t *) );
|
||||||
ue->nr_csi_rs_info->csi_rs_generated_signal = (int32_t **)malloc16(NR_MAX_NB_PORTS * sizeof(int32_t *) );
|
|
||||||
for (i=0; i<NR_MAX_NB_PORTS; i++) {
|
for (i=0; i<NR_MAX_NB_PORTS; i++) {
|
||||||
ue->nr_csi_rs_info->csi_rs_generated_signal[i] = (int32_t *) malloc16_clear(fp->samples_per_frame_wCP * sizeof(int32_t));
|
ue->nr_csi_info->csi_rs_generated_signal[i] = (int32_t *) malloc16_clear(fp->samples_per_frame_wCP * sizeof(int32_t));
|
||||||
}
|
|
||||||
ue->nr_csi_rs_info->csi_rs_received_signal = (int32_t **)malloc16(fp->nb_antennas_rx * sizeof(int32_t *) );
|
|
||||||
ue->nr_csi_rs_info->csi_rs_ls_estimated_channel = (int32_t ***)malloc16(fp->nb_antennas_rx * sizeof(int32_t **) );
|
|
||||||
ue->nr_csi_rs_info->csi_rs_estimated_channel_freq = (int32_t ***)malloc16(fp->nb_antennas_rx * sizeof(int32_t **) );
|
|
||||||
for (i=0; i<fp->nb_antennas_rx; i++) {
|
|
||||||
ue->nr_csi_rs_info->csi_rs_received_signal[i] = (int32_t *) malloc16_clear(fp->samples_per_frame_wCP * sizeof(int32_t));
|
|
||||||
ue->nr_csi_rs_info->csi_rs_ls_estimated_channel[i] = (int32_t **) malloc16_clear(NR_MAX_NB_PORTS * sizeof(int32_t *));
|
|
||||||
ue->nr_csi_rs_info->csi_rs_estimated_channel_freq[i] = (int32_t **) malloc16_clear(NR_MAX_NB_PORTS * sizeof(int32_t *));
|
|
||||||
for (j=0; j<NR_MAX_NB_PORTS; j++) {
|
|
||||||
ue->nr_csi_rs_info->csi_rs_ls_estimated_channel[i][j] = (int32_t *) malloc16_clear(fp->ofdm_symbol_size * sizeof(int32_t));
|
|
||||||
ue->nr_csi_rs_info->csi_rs_estimated_channel_freq[i][j] = (int32_t *) malloc16_clear(fp->ofdm_symbol_size * sizeof(int32_t));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ue->nr_srs_info = (nr_srs_info_t *)malloc16_clear(sizeof(nr_srs_info_t));
|
ue->nr_srs_info = (nr_srs_info_t *)malloc16_clear(sizeof(nr_srs_info_t));
|
||||||
@@ -474,35 +448,21 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
|
|||||||
for (int gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) {
|
for (int gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) {
|
||||||
|
|
||||||
for (int th_id = 0; th_id < RX_NB_TH_MAX; th_id++) {
|
for (int th_id = 0; th_id < RX_NB_TH_MAX; th_id++) {
|
||||||
|
|
||||||
free_and_zero(ue->pdcch_vars[th_id][gNB_id]);
|
free_and_zero(ue->pdcch_vars[th_id][gNB_id]);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i=0; i<NR_MAX_NB_PORTS; i++) {
|
for (int i=0; i<NR_MAX_NB_PORTS; i++) {
|
||||||
free_and_zero(ue->nr_csi_rs_info->csi_rs_generated_signal[i]);
|
free_and_zero(ue->nr_csi_info->csi_rs_generated_signal[i]);
|
||||||
}
|
|
||||||
for (int i = 0; i < fp->nb_antennas_rx; i++) {
|
|
||||||
free_and_zero(ue->nr_csi_rs_info->csi_rs_received_signal[i]);
|
|
||||||
for (int j=0; j<NR_MAX_NB_PORTS; j++) {
|
|
||||||
free_and_zero(ue->nr_csi_rs_info->csi_rs_ls_estimated_channel[i][j]);
|
|
||||||
free_and_zero(ue->nr_csi_rs_info->csi_rs_estimated_channel_freq[i][j]);
|
|
||||||
}
|
|
||||||
free_and_zero(ue->nr_csi_rs_info->csi_rs_ls_estimated_channel[i]);
|
|
||||||
free_and_zero(ue->nr_csi_rs_info->csi_rs_estimated_channel_freq[i]);
|
|
||||||
}
|
}
|
||||||
|
free_and_zero(ue->nr_csi_info->csi_rs_generated_signal);
|
||||||
for (int slot=0; slot<fp->slots_per_frame; slot++) {
|
for (int slot=0; slot<fp->slots_per_frame; slot++) {
|
||||||
for (int symb=0; symb<fp->symbols_per_slot; symb++) {
|
for (int symb=0; symb<fp->symbols_per_slot; symb++) {
|
||||||
free_and_zero(ue->nr_csi_rs_info->nr_gold_csi_rs[slot][symb]);
|
free_and_zero(ue->nr_csi_info->nr_gold_csi_rs[slot][symb]);
|
||||||
}
|
}
|
||||||
free_and_zero(ue->nr_csi_rs_info->nr_gold_csi_rs[slot]);
|
free_and_zero(ue->nr_csi_info->nr_gold_csi_rs[slot]);
|
||||||
}
|
}
|
||||||
free_and_zero(ue->nr_csi_rs_info->noise_power);
|
free_and_zero(ue->nr_csi_info->nr_gold_csi_rs);
|
||||||
free_and_zero(ue->nr_csi_rs_info->nr_gold_csi_rs);
|
free_and_zero(ue->nr_csi_info);
|
||||||
free_and_zero(ue->nr_csi_rs_info->csi_rs_generated_signal);
|
|
||||||
free_and_zero(ue->nr_csi_rs_info->csi_rs_received_signal);
|
|
||||||
free_and_zero(ue->nr_csi_rs_info->csi_rs_ls_estimated_channel);
|
|
||||||
free_and_zero(ue->nr_csi_rs_info->csi_rs_estimated_channel_freq);
|
|
||||||
free_and_zero(ue->nr_csi_rs_info);
|
|
||||||
|
|
||||||
free_and_zero(ue->nr_srs_info);
|
free_and_zero(ue->nr_srs_info);
|
||||||
|
|
||||||
|
|||||||
@@ -532,9 +532,12 @@ uint32_t conv_1C_RIV(int32_t rballoc,uint32_t N_RB_DL) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: this function is compting PRB outside the range, so I FORCED in the range
|
||||||
|
// I can't understand the 3GPP spec, see below note
|
||||||
uint32_t get_prb(int N_RB_DL,int odd_slot,int vrb,int Ngap) {
|
uint32_t get_prb(int N_RB_DL,int odd_slot,int vrb,int Ngap) {
|
||||||
|
|
||||||
int offset;
|
int offset;
|
||||||
|
int ret=-1;
|
||||||
|
|
||||||
switch (N_RB_DL) {
|
switch (N_RB_DL) {
|
||||||
|
|
||||||
@@ -545,16 +548,16 @@ uint32_t get_prb(int N_RB_DL,int odd_slot,int vrb,int Ngap) {
|
|||||||
switch (vrb) {
|
switch (vrb) {
|
||||||
case 0: // even: 0->0, 1->2, odd: 0->3, 1->5
|
case 0: // even: 0->0, 1->2, odd: 0->3, 1->5
|
||||||
case 1:
|
case 1:
|
||||||
return ((3*odd_slot) + 2*(vrb&3))%6;
|
ret= ((3*odd_slot) + 2*(vrb&3))%6;
|
||||||
break;
|
break;
|
||||||
case 2: // even: 2->3, 3->5, odd: 2->0, 3->2
|
case 2: // even: 2->3, 3->5, odd: 2->0, 3->2
|
||||||
case 3:
|
case 3:
|
||||||
return ((3*odd_slot) + 2*(vrb&3) + 5)%6;
|
ret= ((3*odd_slot) + 2*(vrb&3) + 5)%6;
|
||||||
break;
|
break;
|
||||||
case 4: // even: 4->1, odd: 4->4
|
case 4: // even: 4->1, odd: 4->4
|
||||||
return ((3*odd_slot) + 1)%6;
|
ret= ((3*odd_slot) + 1)%6;
|
||||||
case 5: // even: 5->4, odd: 5->1
|
case 5: // even: 5->4, odd: 5->1
|
||||||
return ((3*odd_slot) + 4)%6;
|
ret= ((3*odd_slot) + 4)%6;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -562,88 +565,90 @@ uint32_t get_prb(int N_RB_DL,int odd_slot,int vrb,int Ngap) {
|
|||||||
case 15:
|
case 15:
|
||||||
if (vrb<12) {
|
if (vrb<12) {
|
||||||
if ((vrb&3) < 2) // even: 0->0, 1->4, 4->1, 5->5, 8->2, 9->6 odd: 0->7, 1->11
|
if ((vrb&3) < 2) // even: 0->0, 1->4, 4->1, 5->5, 8->2, 9->6 odd: 0->7, 1->11
|
||||||
return(((7*odd_slot) + 4*(vrb&3) + (vrb>>2))%14) + 14*(vrb/14);
|
ret= (((7*odd_slot) + 4*(vrb&3) + (vrb>>2))%14) + 14*(vrb/14);
|
||||||
else if (vrb < 12) // even: 2->7, 3->11, 6->8, 7->12, 10->9, 11->13
|
else if (vrb < 12) // even: 2->7, 3->11, 6->8, 7->12, 10->9, 11->13
|
||||||
return (((7*odd_slot) + 4*(vrb&3) + (vrb>>2) +13 )%14) + 14*(vrb/14);
|
ret= (((7*odd_slot) + 4*(vrb&3) + (vrb>>2) +13 )%14) + 14*(vrb/14);
|
||||||
}
|
}
|
||||||
if (vrb==12)
|
if (vrb==12)
|
||||||
return (3+(7*odd_slot)) % 14;
|
ret= (3+(7*odd_slot)) % 14;
|
||||||
if (vrb==13)
|
if (vrb==13)
|
||||||
return (10+(7*odd_slot)) % 14;
|
ret= (10+(7*odd_slot)) % 14;
|
||||||
return 14;
|
ret= 14;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// Formula in TS 36.211, chap 6.2.3.2
|
||||||
|
// Fix me: returns a PRB number > 24 when vrb is 24
|
||||||
case 25:
|
case 25:
|
||||||
return (((12*odd_slot) + 6*(vrb&3) + (vrb>>2))%24) + 24*(vrb/24);
|
ret= (((12*odd_slot) + 6*(vrb&3) + (vrb>>2))%24) + 24*(vrb/24);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 50: // P=3
|
case 50: // P=3
|
||||||
if (Ngap==0) {
|
if (Ngap==0) {
|
||||||
// Nrow=12,Nnull=2,NVRBDL=46,Ngap1= 27
|
// Nrow=12,Nnull=2,NVRBDL=46,Ngap1= 27
|
||||||
if (vrb>=23)
|
if (vrb>=23)
|
||||||
offset=4;
|
offset=4;
|
||||||
else
|
else
|
||||||
offset=0;
|
offset=0;
|
||||||
if (vrb<44) {
|
if (vrb<44) {
|
||||||
if ((vrb&3)>=2)
|
if ((vrb&3)>=2)
|
||||||
return offset+((23*odd_slot) + 12*(vrb&3) + (vrb>>2) + 45)%46;
|
ret= offset+((23*odd_slot) + 12*(vrb&3) + (vrb>>2) + 45)%46;
|
||||||
else
|
else
|
||||||
return offset+((23*odd_slot) + 12*(vrb&3) + (vrb>>2))%46;
|
ret= offset+((23*odd_slot) + 12*(vrb&3) + (vrb>>2))%46;
|
||||||
}
|
}
|
||||||
if (vrb==44) // even: 44->11, odd: 45->34
|
if (vrb==44) // even: 44->11, odd: 45->34
|
||||||
return offset+((23*odd_slot) + 22-12+1);
|
ret= offset+((23*odd_slot) + 22-12+1);
|
||||||
if (vrb==45) // even: 45->10, odd: 45->33
|
if (vrb==45) // even: 45->10, odd: 45->33
|
||||||
return offset+((23*odd_slot) + 22+12);
|
ret= offset+((23*odd_slot) + 22+12);
|
||||||
if (vrb==46)
|
if (vrb==46)
|
||||||
return offset+46+((23*odd_slot) + 23-12+1) % 46;
|
ret= offset+46+((23*odd_slot) + 23-12+1) % 46;
|
||||||
if (vrb==47)
|
if (vrb==47)
|
||||||
return offset+46+((23*odd_slot) + 23+12) % 46;
|
ret= offset+46+((23*odd_slot) + 23+12) % 46;
|
||||||
if (vrb==48)
|
if (vrb==48)
|
||||||
return offset+46+((23*odd_slot) + 23-12+1) % 46;
|
ret= offset+46+((23*odd_slot) + 23-12+1) % 46;
|
||||||
if (vrb==49)
|
if (vrb==49)
|
||||||
return offset+46+((23*odd_slot) + 23+12) % 46;
|
ret= offset+46+((23*odd_slot) + 23+12) % 46;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Nrow=6,Nnull=6,NVRBDL=18,Ngap1= 27
|
// Nrow=6,Nnull=6,NVRBDL=18,Ngap1= 27
|
||||||
if (vrb>=9)
|
if (vrb>=9)
|
||||||
offset=18;
|
offset=18;
|
||||||
else
|
else
|
||||||
offset=0;
|
offset=0;
|
||||||
|
|
||||||
if (vrb<12) {
|
if (vrb<12) {
|
||||||
if ((vrb&3)>=2)
|
if ((vrb&3)>=2)
|
||||||
return offset+((9*odd_slot) + 6*(vrb&3) + (vrb>>2) + 17)%18;
|
ret= offset+((9*odd_slot) + 6*(vrb&3) + (vrb>>2) + 17)%18;
|
||||||
else
|
else
|
||||||
return offset+((9*odd_slot) + 6*(vrb&3) + (vrb>>2))%18;
|
ret= offset+((9*odd_slot) + 6*(vrb&3) + (vrb>>2))%18;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return offset+((9*odd_slot) + 12*(vrb&1)+(vrb>>1) )%18 + 18*(vrb/18);
|
ret= offset+((9*odd_slot) + 12*(vrb&1)+(vrb>>1) )%18 + 18*(vrb/18);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 75:
|
case 75:
|
||||||
// Ngap1 = 32, NVRBRL=64, P=4, Nrow= 16, Nnull=0
|
// Ngap1 = 32, NVRBRL=64, P=4, Nrow= 16, Nnull=0
|
||||||
if (Ngap ==0) {
|
if (Ngap ==0) {
|
||||||
return ((32*odd_slot) + 16*(vrb&3) + (vrb>>2))%64 + (vrb/64);
|
ret= ((32*odd_slot) + 16*(vrb&3) + (vrb>>2))%64 + (vrb/64);
|
||||||
} else {
|
} else {
|
||||||
// Ngap2 = 16, NVRBDL=32, Nrow=8, Nnull=0
|
// Ngap2 = 16, NVRBDL=32, Nrow=8, Nnull=0
|
||||||
return ((16*odd_slot) + 8*(vrb&3) + (vrb>>2))%32 + (vrb/32);
|
ret= ((16*odd_slot) + 8*(vrb&3) + (vrb>>2))%32 + (vrb/32);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 100:
|
case 100:
|
||||||
// Ngap1 = 48, NVRBDL=96, Nrow=24, Nnull=0
|
// Ngap1 = 48, NVRBDL=96, Nrow=24, Nnull=0
|
||||||
if (Ngap ==0) {
|
if (Ngap ==0) {
|
||||||
return ((48*odd_slot) + 24*(vrb&3) + (vrb>>2))%96 + (vrb/96);
|
ret= ((48*odd_slot) + 24*(vrb&3) + (vrb>>2))%96 + (vrb/96);
|
||||||
} else {
|
} else {
|
||||||
// Ngap2 = 16, NVRBDL=32, Nrow=8, Nnull=0
|
// Ngap2 = 16, NVRBDL=32, Nrow=8, Nnull=0
|
||||||
return ((16*odd_slot) + 8*(vrb&3) + (vrb>>2))%32 + (vrb/32);
|
ret= ((16*odd_slot) + 8*(vrb&3) + (vrb>>2))%32 + (vrb/32);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LOG_E(PHY,"Unknown N_RB_DL %d\n",N_RB_DL);
|
LOG_E(PHY,"Unknown N_RB_DL %d\n",N_RB_DL);
|
||||||
return 0;
|
ret= 0;
|
||||||
}
|
}
|
||||||
return 0;
|
return ret%N_RB_DL;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -677,7 +682,7 @@ void generate_RIV_tables(void)
|
|||||||
|
|
||||||
// printf("RIV %d (%d) : first_rb %d NBRB %d\n",RIV,localRIV2alloc_LUT25[RIV],RBstart,Lcrbs);
|
// printf("RIV %d (%d) : first_rb %d NBRB %d\n",RIV,localRIV2alloc_LUT25[RIV],RBstart,Lcrbs);
|
||||||
localRIV2alloc_LUT6[RIV] = alloc0;
|
localRIV2alloc_LUT6[RIV] = alloc0;
|
||||||
distRIV2alloc_even_LUT6[RIV] = allocdist0_0_even;
|
distRIV2alloc_even_LUT6[RIV] = allocdist0_0_even;
|
||||||
distRIV2alloc_odd_LUT6[RIV] = allocdist0_0_odd;
|
distRIV2alloc_odd_LUT6[RIV] = allocdist0_0_odd;
|
||||||
RIV2nb_rb_LUT6[RIV] = Lcrbs;
|
RIV2nb_rb_LUT6[RIV] = Lcrbs;
|
||||||
RIV2first_rb_LUT6[RIV] = RBstart;
|
RIV2first_rb_LUT6[RIV] = RBstart;
|
||||||
@@ -693,15 +698,14 @@ void generate_RIV_tables(void)
|
|||||||
nVRB = Lcrbs-1+RBstart;
|
nVRB = Lcrbs-1+RBstart;
|
||||||
//printf("RBstart %d, len %d --> ",RBstart,Lcrbs);
|
//printf("RBstart %d, len %d --> ",RBstart,Lcrbs);
|
||||||
alloc0 |= (1<<nVRB);
|
alloc0 |= (1<<nVRB);
|
||||||
allocdist0_0_even |= (1<<get_prb(25,0,nVRB,0));
|
allocdist0_0_even |= 1U << get_prb(25, 0, nVRB, 0);
|
||||||
allocdist0_0_odd |= (1<<get_prb(25,1,nVRB,0));
|
allocdist0_0_odd |= 1U << get_prb(25, 1, nVRB, 0);
|
||||||
|
|
||||||
//printf("alloc 0 %x, allocdist0_even %x, allocdist0_odd %x\n",alloc0,allocdist0_0_even,allocdist0_0_odd);
|
//printf("alloc 0 %x, allocdist0_even %x, allocdist0_odd %x\n",alloc0,allocdist0_0_even,allocdist0_0_odd);
|
||||||
RIV=computeRIV(25,RBstart,Lcrbs);
|
RIV=computeRIV(25,RBstart,Lcrbs);
|
||||||
|
|
||||||
if (RIV>RIV_max25)
|
if (RIV>RIV_max25)
|
||||||
RIV_max25 = RIV;;
|
RIV_max25 = RIV;
|
||||||
|
|
||||||
|
|
||||||
localRIV2alloc_LUT25[RIV] = alloc0;
|
localRIV2alloc_LUT25[RIV] = alloc0;
|
||||||
distRIV2alloc_even_LUT25[RIV] = allocdist0_0_even;
|
distRIV2alloc_even_LUT25[RIV] = allocdist0_0_even;
|
||||||
@@ -730,37 +734,37 @@ void generate_RIV_tables(void)
|
|||||||
|
|
||||||
|
|
||||||
if (nVRB<32)
|
if (nVRB<32)
|
||||||
alloc0 |= (1<<nVRB);
|
alloc0 |= 1U << nVRB;
|
||||||
else
|
else
|
||||||
alloc1 |= (1<<(nVRB-32));
|
alloc1 |= 1U << (nVRB - 32);
|
||||||
|
|
||||||
// Distributed Gap1, even slot
|
// Distributed Gap1, even slot
|
||||||
nVRB_even_dist = get_prb(50,0,nVRB,0);
|
nVRB_even_dist = get_prb(50,0,nVRB,0);
|
||||||
if (nVRB_even_dist<32)
|
if (nVRB_even_dist<32)
|
||||||
allocdist0_0_even |= (1<<nVRB_even_dist);
|
allocdist0_0_even |= 1U << nVRB_even_dist;
|
||||||
else
|
else
|
||||||
allocdist1_0_even |= (1<<(nVRB_even_dist-32));
|
allocdist1_0_even |= 1U << (nVRB_even_dist - 32);
|
||||||
|
|
||||||
// Distributed Gap1, odd slot
|
// Distributed Gap1, odd slot
|
||||||
nVRB_odd_dist = get_prb(50,1,nVRB,0);
|
nVRB_odd_dist = get_prb(50,1,nVRB,0);
|
||||||
if (nVRB_odd_dist<32)
|
if (nVRB_odd_dist<32)
|
||||||
allocdist0_0_odd |= (1<<nVRB_odd_dist);
|
allocdist0_0_odd |= (1U <<nVRB_odd_dist);
|
||||||
else
|
else
|
||||||
allocdist1_0_odd |= (1<<(nVRB_odd_dist-32));
|
allocdist1_0_odd |= (1U <<(nVRB_odd_dist-32));
|
||||||
|
|
||||||
// Distributed Gap2, even slot
|
// Distributed Gap2, even slot
|
||||||
nVRB_even_dist = get_prb(50,0,nVRB,1);
|
nVRB_even_dist = get_prb(50,0,nVRB,1);
|
||||||
if (nVRB_even_dist<32)
|
if (nVRB_even_dist<32)
|
||||||
allocdist0_1_even |= (1<<nVRB_even_dist);
|
allocdist0_1_even |= 1U << nVRB_even_dist;
|
||||||
else
|
else
|
||||||
allocdist1_1_even |= (1<<(nVRB_even_dist-32));
|
allocdist1_1_even |= 1U << (nVRB_even_dist - 32);
|
||||||
|
|
||||||
// Distributed Gap2, odd slot
|
// Distributed Gap2, odd slot
|
||||||
nVRB_odd_dist = get_prb(50,1,nVRB,1);
|
nVRB_odd_dist = get_prb(50,1,nVRB,1);
|
||||||
if (nVRB_odd_dist<32)
|
if (nVRB_odd_dist<32)
|
||||||
allocdist0_1_odd |= (1<<nVRB_odd_dist);
|
allocdist0_1_odd |= 1U << nVRB_odd_dist;
|
||||||
else
|
else
|
||||||
allocdist1_1_odd |= (1<<(nVRB_odd_dist-32));
|
allocdist1_1_odd |= 1U << (nVRB_odd_dist - 32);
|
||||||
|
|
||||||
RIV=computeRIV(50,RBstart,Lcrbs);
|
RIV=computeRIV(50,RBstart,Lcrbs);
|
||||||
|
|
||||||
@@ -811,13 +815,13 @@ void generate_RIV_tables(void)
|
|||||||
nVRB = Lcrbs-1+RBstart;
|
nVRB = Lcrbs-1+RBstart;
|
||||||
|
|
||||||
if (nVRB<32)
|
if (nVRB<32)
|
||||||
alloc0 |= (1<<nVRB);
|
alloc0 |= 1U << nVRB;
|
||||||
else if (nVRB<64)
|
else if (nVRB<64)
|
||||||
alloc1 |= (1<<(nVRB-32));
|
alloc1 |= 1U << (nVRB - 32);
|
||||||
else if (nVRB<96)
|
else if (nVRB<96)
|
||||||
alloc2 |= (1<<(nVRB-64));
|
alloc2 |= 1U << (nVRB - 64);
|
||||||
else
|
else
|
||||||
alloc3 |= (1<<(nVRB-96));
|
alloc3 |= 1U << (nVRB - 96);
|
||||||
|
|
||||||
// Distributed Gap1, even slot
|
// Distributed Gap1, even slot
|
||||||
nVRB_even_dist = get_prb(100,0,nVRB,0);
|
nVRB_even_dist = get_prb(100,0,nVRB,0);
|
||||||
@@ -825,15 +829,14 @@ void generate_RIV_tables(void)
|
|||||||
// if ((RBstart==0) && (Lcrbs<=8))
|
// if ((RBstart==0) && (Lcrbs<=8))
|
||||||
// printf("nVRB %d => nVRB_even_dist %d\n",nVRB,nVRB_even_dist);
|
// printf("nVRB %d => nVRB_even_dist %d\n",nVRB,nVRB_even_dist);
|
||||||
|
|
||||||
|
|
||||||
if (nVRB_even_dist<32)
|
if (nVRB_even_dist<32)
|
||||||
allocdist0_0_even |= (1<<nVRB_even_dist);
|
allocdist0_0_even |= 1U << nVRB_even_dist;
|
||||||
else if (nVRB_even_dist<64)
|
else if (nVRB_even_dist<64)
|
||||||
allocdist1_0_even |= (1<<(nVRB_even_dist-32));
|
allocdist1_0_even |= 1U << (nVRB_even_dist - 32);
|
||||||
else if (nVRB_even_dist<96)
|
else if (nVRB_even_dist<96)
|
||||||
allocdist2_0_even |= (1<<(nVRB_even_dist-64));
|
allocdist2_0_even |= 1U << (nVRB_even_dist - 64);
|
||||||
else
|
else
|
||||||
allocdist3_0_even |= (1<<(nVRB_even_dist-96));
|
allocdist3_0_even |= 1U << (nVRB_even_dist - 96);
|
||||||
/* if ((RBstart==0) && (Lcrbs<=8))
|
/* if ((RBstart==0) && (Lcrbs<=8))
|
||||||
printf("rballoc =>(%08x.%08x.%08x.%08x)\n",
|
printf("rballoc =>(%08x.%08x.%08x.%08x)\n",
|
||||||
allocdist0_0_even,
|
allocdist0_0_even,
|
||||||
@@ -845,38 +848,37 @@ void generate_RIV_tables(void)
|
|||||||
// Distributed Gap1, odd slot
|
// Distributed Gap1, odd slot
|
||||||
nVRB_odd_dist = get_prb(100,1,nVRB,0);
|
nVRB_odd_dist = get_prb(100,1,nVRB,0);
|
||||||
if (nVRB_odd_dist<32)
|
if (nVRB_odd_dist<32)
|
||||||
allocdist0_0_odd |= (1<<nVRB_odd_dist);
|
allocdist0_0_odd |= 1U << nVRB_odd_dist;
|
||||||
else if (nVRB_odd_dist<64)
|
else if (nVRB_odd_dist<64)
|
||||||
allocdist1_0_odd |= (1<<(nVRB_odd_dist-32));
|
allocdist1_0_odd |= 1U << (nVRB_odd_dist - 32);
|
||||||
else if (nVRB_odd_dist<96)
|
else if (nVRB_odd_dist<96)
|
||||||
allocdist2_0_odd |= (1<<(nVRB_odd_dist-64));
|
allocdist2_0_odd |= 1U << (nVRB_odd_dist - 64);
|
||||||
else
|
else
|
||||||
allocdist3_0_odd |= (1<<(nVRB_odd_dist-96));
|
allocdist3_0_odd |= 1U << (nVRB_odd_dist - 96);
|
||||||
|
|
||||||
|
|
||||||
// Distributed Gap2, even slot
|
// Distributed Gap2, even slot
|
||||||
nVRB_even_dist = get_prb(100,0,nVRB,1);
|
nVRB_even_dist = get_prb(100,0,nVRB,1);
|
||||||
if (nVRB_even_dist<32)
|
if (nVRB_even_dist<32)
|
||||||
allocdist0_1_even |= (1<<nVRB_even_dist);
|
allocdist0_1_even |= 1U << nVRB_even_dist;
|
||||||
else if (nVRB_even_dist<64)
|
else if (nVRB_even_dist<64)
|
||||||
allocdist1_1_even |= (1<<(nVRB_even_dist-32));
|
allocdist1_1_even |= 1U << (nVRB_even_dist - 32);
|
||||||
else if (nVRB_even_dist<96)
|
else if (nVRB_even_dist<96)
|
||||||
allocdist2_1_even |= (1<<(nVRB_even_dist-64));
|
allocdist2_1_even |= 1U << (nVRB_even_dist - 64);
|
||||||
else
|
else
|
||||||
allocdist3_1_even |= (1<<(nVRB_even_dist-96));
|
allocdist3_1_even |= 1U << (nVRB_even_dist - 96);
|
||||||
|
|
||||||
|
|
||||||
// Distributed Gap2, odd slot
|
// Distributed Gap2, odd slot
|
||||||
nVRB_odd_dist = get_prb(100,1,nVRB,1);
|
nVRB_odd_dist = get_prb(100,1,nVRB,1);
|
||||||
if (nVRB_odd_dist<32)
|
if (nVRB_odd_dist<32)
|
||||||
allocdist0_1_odd |= (1<<nVRB_odd_dist);
|
allocdist0_1_odd |= 1U << nVRB_odd_dist;
|
||||||
else if (nVRB_odd_dist<64)
|
else if (nVRB_odd_dist<64)
|
||||||
allocdist1_1_odd |= (1<<(nVRB_odd_dist-32));
|
allocdist1_1_odd |= 1U << (nVRB_odd_dist - 32);
|
||||||
else if (nVRB_odd_dist<96)
|
else if (nVRB_odd_dist<96)
|
||||||
allocdist2_1_odd |= (1<<(nVRB_odd_dist-64));
|
allocdist2_1_odd |= 1U << (nVRB_odd_dist - 64);
|
||||||
else
|
else
|
||||||
allocdist3_1_odd |= (1<<(nVRB_odd_dist-96));
|
allocdist3_1_odd |= 1U << (nVRB_odd_dist - 96);
|
||||||
|
|
||||||
|
|
||||||
RIV=computeRIV(100,RBstart,Lcrbs);
|
RIV=computeRIV(100,RBstart,Lcrbs);
|
||||||
|
|
||||||
|
|||||||
@@ -288,7 +288,7 @@ static void TPencode(void * arg) {
|
|||||||
LTE_DL_eNB_HARQ_t *hadlsch=rdata->dlsch->harq_processes[harq_pid];
|
LTE_DL_eNB_HARQ_t *hadlsch=rdata->dlsch->harq_processes[harq_pid];
|
||||||
|
|
||||||
if ( rdata-> round == 0) {
|
if ( rdata-> round == 0) {
|
||||||
uint8_t tmp[96+12+3+3*6144];
|
uint8_t tmp[96+12+3+3*6144] __attribute__((aligned(32)));
|
||||||
memset(tmp,LTE_NULL, TURBO_SIMD_SOFTBITS);
|
memset(tmp,LTE_NULL, TURBO_SIMD_SOFTBITS);
|
||||||
start_meas(rdata->te_stats);
|
start_meas(rdata->te_stats);
|
||||||
encoder(rdata->input,
|
encoder(rdata->input,
|
||||||
|
|||||||
@@ -64,6 +64,12 @@ extern uint16_t beta_cqi[16];
|
|||||||
extern uint16_t beta_ri[16];
|
extern uint16_t beta_ri[16];
|
||||||
extern uint16_t beta_ack[16];
|
extern uint16_t beta_ack[16];
|
||||||
|
|
||||||
|
static int errorRB(int rb, char * table, int line) {
|
||||||
|
LOG_E(PHY,"Received %d rb, impossble in table %s, at line %d\n", rb, table, line);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define rbAllocCheck(RBalL, TabLe) (RBalL) > sizeof(TabLe)/sizeof(*TabLe) ? errorRB(RBalL, #TabLe, __LINE__) : TabLe[RBalL]
|
||||||
void extract_dci1A_info(uint8_t N_RB_DL, frame_type_t frame_type, void *dci_pdu, DCI_INFO_EXTRACTED_t *pdci_info_extarcted)
|
void extract_dci1A_info(uint8_t N_RB_DL, frame_type_t frame_type, void *dci_pdu, DCI_INFO_EXTRACTED_t *pdci_info_extarcted)
|
||||||
{
|
{
|
||||||
uint8_t harq_pid=0;
|
uint8_t harq_pid=0;
|
||||||
@@ -974,28 +980,28 @@ int check_dci_format1_1a_coherency(DCI_format_t dci_format,
|
|||||||
{
|
{
|
||||||
switch (N_RB_DL) {
|
switch (N_RB_DL) {
|
||||||
case 6:
|
case 6:
|
||||||
NPRB = RIV2nb_rb_LUT6[rballoc];//NPRB;
|
NPRB = rbAllocCheck(rballoc, RIV2nb_rb_LUT6);
|
||||||
if(rah)
|
if(rah)
|
||||||
RIV_max = RIV_max6;
|
RIV_max = RIV_max6;
|
||||||
else
|
else
|
||||||
RIV_max = 0x3F;
|
RIV_max = 0x3F;
|
||||||
break;
|
break;
|
||||||
case 25:
|
case 25:
|
||||||
NPRB = RIV2nb_rb_LUT25[rballoc];//NPRB;
|
NPRB = rbAllocCheck(rballoc,RIV2nb_rb_LUT25);
|
||||||
if(rah)
|
if(rah)
|
||||||
RIV_max = RIV_max25;
|
RIV_max = RIV_max25;
|
||||||
else
|
else
|
||||||
RIV_max = 0x1FFF;
|
RIV_max = 0x1FFF;
|
||||||
break;
|
break;
|
||||||
case 50:
|
case 50:
|
||||||
NPRB = RIV2nb_rb_LUT50[rballoc];//NPRB;
|
NPRB = rbAllocCheck(rballoc,RIV2nb_rb_LUT50);
|
||||||
if(rah)
|
if(rah)
|
||||||
RIV_max = RIV_max50;
|
RIV_max = RIV_max50;
|
||||||
else
|
else
|
||||||
RIV_max = 0x1FFFF;
|
RIV_max = 0x1FFFF;
|
||||||
break;
|
break;
|
||||||
case 100:
|
case 100:
|
||||||
NPRB = RIV2nb_rb_LUT100[rballoc];//NPRB;
|
NPRB = rbAllocCheck(rballoc,RIV2nb_rb_LUT100);
|
||||||
if(rah)
|
if(rah)
|
||||||
RIV_max = RIV_max100;
|
RIV_max = RIV_max100;
|
||||||
else
|
else
|
||||||
@@ -1034,9 +1040,14 @@ int check_dci_format1_1a_coherency(DCI_format_t dci_format,
|
|||||||
// this is an eNB issue
|
// this is an eNB issue
|
||||||
// retransmisison but old and new TBS are different !!!
|
// retransmisison but old and new TBS are different !!!
|
||||||
// work around, consider it as a new transmission
|
// work around, consider it as a new transmission
|
||||||
LOG_E(PHY,"Format1A Retransmission but TBS are different: consider it as new transmission !!! \n");
|
LOG_E(PHY,
|
||||||
|
"Format1A Retransmission but TBS are different: consider it as new transmission !!!, round %d, mcs 1 %d, NPRB %d \n",
|
||||||
|
pdlsch0_harq->round,
|
||||||
|
mcs1,
|
||||||
|
NPRB);
|
||||||
pdlsch0_harq->round = 0;
|
pdlsch0_harq->round = 0;
|
||||||
//return(0); // ?? to cross check
|
//return(0); // ?? to cross check
|
||||||
|
return(0); // ?? to cross check
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1272,14 +1272,6 @@ uint32_t get_TBS_DL(uint8_t mcs, uint16_t nb_rb);
|
|||||||
@return Transport block size */
|
@return Transport block size */
|
||||||
uint32_t get_TBS_UL(uint8_t mcs, uint16_t nb_rb);
|
uint32_t get_TBS_UL(uint8_t mcs, uint16_t nb_rb);
|
||||||
|
|
||||||
/* \brief Return bit-map of resource allocation for a given DCI rballoc (RIV format) and vrb type
|
|
||||||
@param N_RB_DL number of PRB on DL
|
|
||||||
@param indicator for even/odd slot
|
|
||||||
@param vrb vrb index
|
|
||||||
@param Ngap Gap indicator
|
|
||||||
*/
|
|
||||||
uint32_t get_prb(int N_RB_DL,int odd_slot,int vrb,int Ngap);
|
|
||||||
|
|
||||||
/* \brief Return prb for a given vrb index
|
/* \brief Return prb for a given vrb index
|
||||||
@param vrb_type VRB type (0=localized,1=distributed)
|
@param vrb_type VRB type (0=localized,1=distributed)
|
||||||
@param rb_alloc_dci rballoc field from DCI
|
@param rb_alloc_dci rballoc field from DCI
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ typedef struct {
|
|||||||
/// Redundancy-version of the current sub-frame
|
/// Redundancy-version of the current sub-frame
|
||||||
uint8_t rvidx;
|
uint8_t rvidx;
|
||||||
/// Turbo-code outputs (36-212 V8.6 2009-03, p.12
|
/// Turbo-code outputs (36-212 V8.6 2009-03, p.12
|
||||||
uint8_t d[MAX_NUM_ULSCH_SEGMENTS][(96+3+(3*6144))];
|
uint8_t *d[MAX_NUM_ULSCH_SEGMENTS];
|
||||||
/// Sub-block interleaver outputs (36-212 V8.6 2009-03, p.16-17)
|
/// Sub-block interleaver outputs (36-212 V8.6 2009-03, p.16-17)
|
||||||
uint8_t w[MAX_NUM_ULSCH_SEGMENTS][3*6144];
|
uint8_t w[MAX_NUM_ULSCH_SEGMENTS][3*6144];
|
||||||
/// Number of code segments (for definition see 36-212 V8.6 2009-03, p.9)
|
/// Number of code segments (for definition see 36-212 V8.6 2009-03, p.9)
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ void free_ue_ulsch(LTE_UE_ULSCH_t *ulsch) {
|
|||||||
for (r=0; r<MAX_NUM_ULSCH_SEGMENTS; r++) {
|
for (r=0; r<MAX_NUM_ULSCH_SEGMENTS; r++) {
|
||||||
if (ulsch->harq_processes[i]->c[r]) {
|
if (ulsch->harq_processes[i]->c[r]) {
|
||||||
free16(ulsch->harq_processes[i]->c[r],((r==0)?8:0) + 3+768);
|
free16(ulsch->harq_processes[i]->c[r],((r==0)?8:0) + 3+768);
|
||||||
|
free16(ulsch->harq_processes[i]->d[r],0);
|
||||||
ulsch->harq_processes[i]->c[r] = NULL;
|
ulsch->harq_processes[i]->c[r] = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -86,7 +87,7 @@ void free_ue_ulsch(LTE_UE_ULSCH_t *ulsch) {
|
|||||||
|
|
||||||
LTE_UE_ULSCH_t *new_ue_ulsch(unsigned char N_RB_UL, uint8_t abstraction_flag) {
|
LTE_UE_ULSCH_t *new_ue_ulsch(unsigned char N_RB_UL, uint8_t abstraction_flag) {
|
||||||
LTE_UE_ULSCH_t *ulsch;
|
LTE_UE_ULSCH_t *ulsch;
|
||||||
unsigned char exit_flag = 0,i,j,r;
|
unsigned char exit_flag = 0;
|
||||||
unsigned char bw_scaling =1;
|
unsigned char bw_scaling =1;
|
||||||
|
|
||||||
switch (N_RB_UL) {
|
switch (N_RB_UL) {
|
||||||
@@ -113,7 +114,7 @@ LTE_UE_ULSCH_t *new_ue_ulsch(unsigned char N_RB_UL, uint8_t abstraction_flag) {
|
|||||||
memset(ulsch,0,sizeof(LTE_UE_ULSCH_t));
|
memset(ulsch,0,sizeof(LTE_UE_ULSCH_t));
|
||||||
ulsch->Mlimit = 4;
|
ulsch->Mlimit = 4;
|
||||||
|
|
||||||
for (i=0; i<8; i++) {
|
for (int i=0; i<8; i++) {
|
||||||
ulsch->harq_processes[i] = (LTE_UL_UE_HARQ_t *)malloc16(sizeof(LTE_UL_UE_HARQ_t));
|
ulsch->harq_processes[i] = (LTE_UL_UE_HARQ_t *)malloc16(sizeof(LTE_UL_UE_HARQ_t));
|
||||||
|
|
||||||
// printf("ulsch->harq_processes[%d] %p\n",i,ulsch->harq_processes[i]);
|
// printf("ulsch->harq_processes[%d] %p\n",i,ulsch->harq_processes[i]);
|
||||||
@@ -129,15 +130,11 @@ LTE_UE_ULSCH_t *new_ue_ulsch(unsigned char N_RB_UL, uint8_t abstraction_flag) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (abstraction_flag==0) {
|
if (abstraction_flag==0) {
|
||||||
for (r=0; r<MAX_NUM_ULSCH_SEGMENTS; r++) {
|
for (int r=0; r<MAX_NUM_ULSCH_SEGMENTS; r++) {
|
||||||
ulsch->harq_processes[i]->c[r] = (unsigned char *)malloc16(((r==0)?8:0) + 3+768); // account for filler in first segment and CRCs for multiple segment case
|
ulsch->harq_processes[i]->c[r] = malloc16_clear(((r==0)?8:0) + 3+768); // account for filler in first segment and CRCs for multiple segment case
|
||||||
|
AssertFatal(ulsch->harq_processes[i]->c[r], "");
|
||||||
if (ulsch->harq_processes[i]->c[r])
|
ulsch->harq_processes[i]->d[r] = malloc16_clear(96+3+(3*6144));
|
||||||
memset(ulsch->harq_processes[i]->c[r],0,((r==0)?8:0) + 3+768);
|
AssertFatal(ulsch->harq_processes[i]->d[r], "");
|
||||||
else {
|
|
||||||
LOG_E(PHY,"Can't get c\n");
|
|
||||||
exit_flag=2;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,15 +145,7 @@ LTE_UE_ULSCH_t *new_ue_ulsch(unsigned char N_RB_UL, uint8_t abstraction_flag) {
|
|||||||
exit_flag=3;
|
exit_flag=3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!exit_flag)
|
||||||
if ((abstraction_flag == 0) && (exit_flag==0)) {
|
|
||||||
for (i=0; i<8; i++)
|
|
||||||
for (j=0; j<96; j++)
|
|
||||||
for (r=0; r<MAX_NUM_ULSCH_SEGMENTS; r++)
|
|
||||||
ulsch->harq_processes[i]->d[r][j] = LTE_NULL;
|
|
||||||
|
|
||||||
return(ulsch);
|
|
||||||
} else if (abstraction_flag==1)
|
|
||||||
return(ulsch);
|
return(ulsch);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,7 +180,7 @@ uint32_t ulsch_encoding(uint8_t *a,
|
|||||||
uint32_t Qprime_ACK=0,Qprime_CQI=0,Qprime_RI=0,len_ACK=0,len_RI=0;
|
uint32_t Qprime_ACK=0,Qprime_CQI=0,Qprime_RI=0,len_ACK=0,len_RI=0;
|
||||||
// uint32_t E;
|
// uint32_t E;
|
||||||
uint8_t ack_parity;
|
uint8_t ack_parity;
|
||||||
uint32_t i,q,j,iprime,j2;
|
uint32_t q,j,iprime,j2;
|
||||||
uint16_t o_RCC;
|
uint16_t o_RCC;
|
||||||
uint8_t o_flip[8];
|
uint8_t o_flip[8];
|
||||||
uint32_t wACK_idx;
|
uint32_t wACK_idx;
|
||||||
@@ -327,6 +316,8 @@ uint32_t ulsch_encoding(uint8_t *a,
|
|||||||
#endif
|
#endif
|
||||||
// offset=0;
|
// offset=0;
|
||||||
start_meas(te_stats);
|
start_meas(te_stats);
|
||||||
|
for (int z=0; z<96; z++)
|
||||||
|
ulsch->harq_processes[harq_pid]->d[r][z] = LTE_NULL;
|
||||||
encoder(ulsch->harq_processes[harq_pid]->c[r],
|
encoder(ulsch->harq_processes[harq_pid]->c[r],
|
||||||
Kr>>3,
|
Kr>>3,
|
||||||
&ulsch->harq_processes[harq_pid]->d[r][96],
|
&ulsch->harq_processes[harq_pid]->d[r][96],
|
||||||
@@ -539,8 +530,6 @@ uint32_t ulsch_encoding(uint8_t *a,
|
|||||||
ulsch->q);
|
ulsch->q);
|
||||||
}
|
}
|
||||||
|
|
||||||
i=0;
|
|
||||||
|
|
||||||
// Do RI coding
|
// Do RI coding
|
||||||
if (ulsch->O_RI == 1) {
|
if (ulsch->O_RI == 1) {
|
||||||
switch (Q_m) {
|
switch (Q_m) {
|
||||||
@@ -691,7 +680,7 @@ uint32_t ulsch_encoding(uint8_t *a,
|
|||||||
|
|
||||||
j=0;
|
j=0;
|
||||||
|
|
||||||
for (i=0; i<Qprime_RI; i++) {
|
for (int i=0; i<Qprime_RI; i++) {
|
||||||
r = Rmux_prime - 1 - (i>>2);
|
r = Rmux_prime - 1 - (i>>2);
|
||||||
|
|
||||||
for (q=0; q<Q_m; q++) {
|
for (q=0; q<Q_m; q++) {
|
||||||
@@ -725,7 +714,7 @@ uint32_t ulsch_encoding(uint8_t *a,
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
for (i=0; i<Qprime_CQI; i++) {
|
for (int i=0; i<Qprime_CQI; i++) {
|
||||||
while (y[Q_m*j] != LTE_NULL) j++;
|
while (y[Q_m*j] != LTE_NULL) j++;
|
||||||
|
|
||||||
for (q=0; q<Q_m; q++) {
|
for (q=0; q<Q_m; q++) {
|
||||||
@@ -788,7 +777,7 @@ uint32_t ulsch_encoding(uint8_t *a,
|
|||||||
|
|
||||||
j=0;
|
j=0;
|
||||||
|
|
||||||
for (i=0; i<Qprime_ACK; i++) {
|
for (int i=0; i<Qprime_ACK; i++) {
|
||||||
r = Rmux_prime - 1 - (i>>2);
|
r = Rmux_prime - 1 - (i>>2);
|
||||||
|
|
||||||
for (q=0; q<Q_m; q++) {
|
for (q=0; q<Q_m; q++) {
|
||||||
@@ -808,7 +797,7 @@ uint32_t ulsch_encoding(uint8_t *a,
|
|||||||
|
|
||||||
switch (Q_m) {
|
switch (Q_m) {
|
||||||
case 2:
|
case 2:
|
||||||
for (i=0; i<Cmux; i++)
|
for (int i=0; i<Cmux; i++)
|
||||||
for (r=0; r<Rmux_prime; r++) {
|
for (r=0; r<Rmux_prime; r++) {
|
||||||
yptr=&y[((r*Cmux)+i)<<1];
|
yptr=&y[((r*Cmux)+i)<<1];
|
||||||
ulsch->h[j++] = *yptr++;
|
ulsch->h[j++] = *yptr++;
|
||||||
@@ -818,7 +807,7 @@ uint32_t ulsch_encoding(uint8_t *a,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
for (i=0; i<Cmux; i++)
|
for (int i=0; i<Cmux; i++)
|
||||||
for (r=0; r<Rmux_prime; r++) {
|
for (r=0; r<Rmux_prime; r++) {
|
||||||
yptr = &y[((r*Cmux)+i)<<2];
|
yptr = &y[((r*Cmux)+i)<<2];
|
||||||
ulsch->h[j++] = *yptr++;
|
ulsch->h[j++] = *yptr++;
|
||||||
@@ -830,7 +819,7 @@ uint32_t ulsch_encoding(uint8_t *a,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 6:
|
case 6:
|
||||||
for (i=0; i<Cmux; i++)
|
for (int i=0; i<Cmux; i++)
|
||||||
for (r=0; r<Rmux_prime; r++) {
|
for (r=0; r<Rmux_prime; r++) {
|
||||||
yptr = &y[((r*Cmux)+i)*6];
|
yptr = &y[((r*Cmux)+i)*6];
|
||||||
ulsch->h[j++] = *yptr++;
|
ulsch->h[j++] = *yptr++;
|
||||||
|
|||||||
@@ -226,10 +226,11 @@ void nr_modulation(uint32_t *in,
|
|||||||
i *= 24;
|
i *= 24;
|
||||||
bit_cnt = i * 8;
|
bit_cnt = i * 8;
|
||||||
while (bit_cnt < length) {
|
while (bit_cnt < length) {
|
||||||
x = *((uint32_t*)(in_bytes+i));
|
uint32_t xx;
|
||||||
x1 = x&4095;
|
memcpy(&xx, in_bytes+i, sizeof(xx));
|
||||||
|
x1 = xx & 4095;
|
||||||
out64[j++] = nr_64qam_mod_table[x1];
|
out64[j++] = nr_64qam_mod_table[x1];
|
||||||
x1 = (x>>12)&4095;
|
x1 = (xx >> 12) & 4095;
|
||||||
out64[j++] = nr_64qam_mod_table[x1];
|
out64[j++] = nr_64qam_mod_table[x1];
|
||||||
i += 3;
|
i += 3;
|
||||||
bit_cnt += 24;
|
bit_cnt += 24;
|
||||||
|
|||||||
@@ -162,7 +162,7 @@ void gNB_I0_measurements(PHY_VARS_gNB *gNB,int slot, int first_symb,int num_symb
|
|||||||
measurements->n0_subband_power[aarx][rb]=0;
|
measurements->n0_subband_power[aarx][rb]=0;
|
||||||
}
|
}
|
||||||
int offset0 = (slot&3)*(frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size) + (frame_parms->first_carrier_offset + (rb*12))%frame_parms->ofdm_symbol_size;
|
int offset0 = (slot&3)*(frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size) + (frame_parms->first_carrier_offset + (rb*12))%frame_parms->ofdm_symbol_size;
|
||||||
if ((gNB->rb_mask_ul[s][rb>>5]&(1<<(rb&31))) == 0) { // check that rb was not used in this subframe
|
if ((gNB->rb_mask_ul[s][rb >> 5] & (1U << (rb & 31))) == 0) { // check that rb was not used in this subframe
|
||||||
nb_symb[rb]++;
|
nb_symb[rb]++;
|
||||||
for (int aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
|
for (int aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
|
||||||
int offset = offset0 + (s*frame_parms->ofdm_symbol_size);
|
int offset = offset0 + (s*frame_parms->ofdm_symbol_size);
|
||||||
|
|||||||
@@ -1115,7 +1115,7 @@ int nr_srs_channel_estimation(const PHY_VARS_gNB *gNB,
|
|||||||
|
|
||||||
const uint64_t subcarrier_offset = frame_parms->first_carrier_offset + srs_pdu->bwp_start*12;
|
const uint64_t subcarrier_offset = frame_parms->first_carrier_offset + srs_pdu->bwp_start*12;
|
||||||
const uint8_t srs_symbols_per_rb = srs_pdu->comb_size == 0 ? 6 : 3;
|
const uint8_t srs_symbols_per_rb = srs_pdu->comb_size == 0 ? 6 : 3;
|
||||||
const uint8_t n_noise_estimates = frame_parms->nb_antennas_rx*srs_symbols_per_rb;
|
const uint8_t n_noise_est = frame_parms->nb_antennas_rx * srs_symbols_per_rb;
|
||||||
uint8_t count_estimates = 0;
|
uint8_t count_estimates = 0;
|
||||||
uint64_t sum_re = 0;
|
uint64_t sum_re = 0;
|
||||||
uint64_t sum_re2 = 0;
|
uint64_t sum_re2 = 0;
|
||||||
@@ -1138,9 +1138,9 @@ int nr_srs_channel_estimation(const PHY_VARS_gNB *gNB,
|
|||||||
sum_im2 = sum_im2 + noise_imag[ant*nr_srs_info->sc_list_length+sc_idx]*noise_imag[ant*nr_srs_info->sc_list_length+sc_idx];
|
sum_im2 = sum_im2 + noise_imag[ant*nr_srs_info->sc_list_length+sc_idx]*noise_imag[ant*nr_srs_info->sc_list_length+sc_idx];
|
||||||
|
|
||||||
count_estimates++;
|
count_estimates++;
|
||||||
if (count_estimates == n_noise_estimates) {
|
if (count_estimates == n_noise_est) {
|
||||||
noise_power_per_rb[rb] = sum_re2/n_noise_estimates - (sum_re/n_noise_estimates)*(sum_re/n_noise_estimates) +
|
noise_power_per_rb[rb] = max(sum_re2 / n_noise_est - (sum_re / n_noise_est) * (sum_re / n_noise_est) +
|
||||||
sum_im2/n_noise_estimates - (sum_im/n_noise_estimates)*(sum_im/n_noise_estimates);
|
sum_im2 / n_noise_est - (sum_im / n_noise_est) * (sum_im / n_noise_est), 1);
|
||||||
snr_per_rb[rb] = dB_fixed((int32_t)((*signal_power<<factor_bits)/noise_power_per_rb[rb])) - factor_dB;
|
snr_per_rb[rb] = dB_fixed((int32_t)((*signal_power<<factor_bits)/noise_power_per_rb[rb])) - factor_dB;
|
||||||
count_estimates = 0;
|
count_estimates = 0;
|
||||||
sum_re = 0;
|
sum_re = 0;
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ void nr_init_pbch_dmrs(PHY_VARS_gNB* gNB);
|
|||||||
*/
|
*/
|
||||||
void nr_init_pdcch_dmrs(PHY_VARS_gNB* gNB, uint32_t Nid);
|
void nr_init_pdcch_dmrs(PHY_VARS_gNB* gNB, uint32_t Nid);
|
||||||
void nr_init_pdsch_dmrs(PHY_VARS_gNB* gNB, uint8_t nscid, uint32_t Nid);
|
void nr_init_pdsch_dmrs(PHY_VARS_gNB* gNB, uint8_t nscid, uint32_t Nid);
|
||||||
void nr_init_csi_rs(NR_DL_FRAME_PARMS *fp, uint32_t ***csi_rs, uint32_t Nid);
|
void nr_init_csi_rs(const NR_DL_FRAME_PARMS *fp, uint32_t ***csi_rs, uint32_t Nid);
|
||||||
|
|
||||||
void nr_gold_pusch(PHY_VARS_gNB* gNB, int nscid, uint32_t nid);
|
void nr_gold_pusch(PHY_VARS_gNB* gNB, int nscid, uint32_t nid);
|
||||||
|
|
||||||
|
|||||||
@@ -68,6 +68,6 @@ void nr_init_pusch_dmrs(PHY_VARS_NR_UE* ue,
|
|||||||
uint16_t N_n_scid,
|
uint16_t N_n_scid,
|
||||||
uint8_t n_scid);
|
uint8_t n_scid);
|
||||||
|
|
||||||
void nr_init_csi_rs(NR_DL_FRAME_PARMS *fp, uint32_t ***csi_rs, uint32_t Nid);
|
void nr_init_csi_rs(const NR_DL_FRAME_PARMS *fp, uint32_t ***csi_rs, uint32_t Nid);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
//#define NR_CSIRS_DEBUG
|
//#define NR_CSIRS_DEBUG
|
||||||
|
|
||||||
|
|
||||||
void nr_init_csi_rs(NR_DL_FRAME_PARMS *fp, uint32_t ***csi_rs, uint32_t Nid) {
|
void nr_init_csi_rs(const NR_DL_FRAME_PARMS *fp, uint32_t ***csi_rs, uint32_t Nid) {
|
||||||
uint32_t x1, x2;
|
uint32_t x1, x2;
|
||||||
uint8_t reset;
|
uint8_t reset;
|
||||||
int csi_dmrs_init_length = ((fp->N_RB_DL<<4)>>5)+1;
|
int csi_dmrs_init_length = ((fp->N_RB_DL<<4)>>5)+1;
|
||||||
@@ -43,12 +43,20 @@ void nr_init_csi_rs(NR_DL_FRAME_PARMS *fp, uint32_t ***csi_rs, uint32_t Nid) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void nr_generate_csi_rs(NR_DL_FRAME_PARMS frame_parms,
|
void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms,
|
||||||
int32_t **dataF,
|
int32_t **dataF,
|
||||||
int16_t amp,
|
const int16_t amp,
|
||||||
nr_csi_rs_info_t *nr_csi_rs_info,
|
nr_csi_info_t *nr_csi_info,
|
||||||
nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csi_params,
|
const nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csi_params,
|
||||||
int slot){
|
const int slot,
|
||||||
|
uint8_t *N_cdm_groups,
|
||||||
|
uint8_t *CDM_group_size,
|
||||||
|
uint8_t *k_prime,
|
||||||
|
uint8_t *l_prime,
|
||||||
|
uint8_t *N_ports,
|
||||||
|
uint8_t *j_cdm,
|
||||||
|
uint8_t *k_overline,
|
||||||
|
uint8_t *l_overline) {
|
||||||
|
|
||||||
#ifdef NR_CSIRS_DEBUG
|
#ifdef NR_CSIRS_DEBUG
|
||||||
LOG_I(NR_PHY, "csi_params->subcarrier_spacing = %i\n", csi_params->subcarrier_spacing);
|
LOG_I(NR_PHY, "csi_params->subcarrier_spacing = %i\n", csi_params->subcarrier_spacing);
|
||||||
@@ -67,11 +75,11 @@ void nr_generate_csi_rs(NR_DL_FRAME_PARMS frame_parms,
|
|||||||
LOG_I(NR_PHY, "csi_params->power_control_offset_ss = %i\n", csi_params->power_control_offset_ss);
|
LOG_I(NR_PHY, "csi_params->power_control_offset_ss = %i\n", csi_params->power_control_offset_ss);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int dataF_offset = slot*frame_parms.samples_per_slot_wCP;
|
int dataF_offset = slot*frame_parms->samples_per_slot_wCP;
|
||||||
uint32_t **nr_gold_csi_rs = nr_csi_rs_info->nr_gold_csi_rs[slot];
|
uint32_t **nr_gold_csi_rs = nr_csi_info->nr_gold_csi_rs[slot];
|
||||||
//*8(max allocation per RB)*2(QPSK))
|
//*8(max allocation per RB)*2(QPSK))
|
||||||
int csi_rs_length = frame_parms.N_RB_DL<<4;
|
int csi_rs_length = frame_parms->N_RB_DL<<4;
|
||||||
int16_t mod_csi[frame_parms.symbols_per_slot][csi_rs_length>>1] __attribute__((aligned(16)));
|
int16_t mod_csi[frame_parms->symbols_per_slot][csi_rs_length>>1] __attribute__((aligned(16)));
|
||||||
uint16_t b = csi_params->freq_domain;
|
uint16_t b = csi_params->freq_domain;
|
||||||
uint16_t n, p, k, l, mprime, na, kpn;
|
uint16_t n, p, k, l, mprime, na, kpn;
|
||||||
uint8_t size, ports, kprime, lprime, i, gs;
|
uint8_t size, ports, kprime, lprime, i, gs;
|
||||||
@@ -81,14 +89,14 @@ void nr_generate_csi_rs(NR_DL_FRAME_PARMS frame_parms,
|
|||||||
uint8_t fi = 0;
|
uint8_t fi = 0;
|
||||||
double rho, alpha;
|
double rho, alpha;
|
||||||
uint32_t beta = amp;
|
uint32_t beta = amp;
|
||||||
nr_csi_rs_info->csi_rs_generated_signal_bits = log2_approx(amp);
|
nr_csi_info->csi_rs_generated_signal_bits = log2_approx(amp);
|
||||||
|
|
||||||
AssertFatal(b!=0, "Invalid CSI frequency domain mapping: no bit selected in bitmap\n");
|
AssertFatal(b!=0, "Invalid CSI frequency domain mapping: no bit selected in bitmap\n");
|
||||||
|
|
||||||
// if the scrambling id is not the one previously used to initialize we need to re-initialize the rs
|
// if the scrambling id is not the one previously used to initialize we need to re-initialize the rs
|
||||||
if (csi_params->scramb_id != nr_csi_rs_info->csi_gold_init) {
|
if (csi_params->scramb_id != nr_csi_info->csi_gold_init) {
|
||||||
nr_csi_rs_info->csi_gold_init = csi_params->scramb_id;
|
nr_csi_info->csi_gold_init = csi_params->scramb_id;
|
||||||
nr_init_csi_rs(&frame_parms, nr_csi_rs_info->nr_gold_csi_rs, csi_params->scramb_id);
|
nr_init_csi_rs(frame_parms, nr_csi_info->nr_gold_csi_rs, csi_params->scramb_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (csi_params->row) {
|
switch (csi_params->row) {
|
||||||
@@ -584,7 +592,7 @@ void nr_generate_csi_rs(NR_DL_FRAME_PARMS frame_parms,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t start_sc = frame_parms.first_carrier_offset;
|
uint16_t start_sc = frame_parms->first_carrier_offset;
|
||||||
|
|
||||||
// resource mapping according to 38.211 7.4.1.5.3
|
// resource mapping according to 38.211 7.4.1.5.3
|
||||||
for (n=csi_params->start_rb; n<(csi_params->start_rb+csi_params->nr_of_rbs); n++) {
|
for (n=csi_params->start_rb; n<(csi_params->start_rb+csi_params->nr_of_rbs); n++) {
|
||||||
@@ -593,7 +601,7 @@ void nr_generate_csi_rs(NR_DL_FRAME_PARMS frame_parms,
|
|||||||
for (int s=0 ; s<gs; s++) { // loop over each CDM group size
|
for (int s=0 ; s<gs; s++) { // loop over each CDM group size
|
||||||
p = s+j[ji]*gs; // port index
|
p = s+j[ji]*gs; // port index
|
||||||
for (kp=0; kp<=kprime; kp++) { // loop over frequency resource elements within a group
|
for (kp=0; kp<=kprime; kp++) { // loop over frequency resource elements within a group
|
||||||
k = (start_sc+(n*NR_NB_SC_PER_RB)+koverline[ji]+kp)%(frame_parms.ofdm_symbol_size); // frequency index of current resource element
|
k = (start_sc+(n*NR_NB_SC_PER_RB)+koverline[ji]+kp)%(frame_parms->ofdm_symbol_size); // frequency index of current resource element
|
||||||
// wf according to tables 7.4.5.3-2 to 7.4.5.3-5
|
// wf according to tables 7.4.5.3-2 to 7.4.5.3-5
|
||||||
if (kp == 0)
|
if (kp == 0)
|
||||||
wf = 1;
|
wf = 1;
|
||||||
@@ -620,17 +628,17 @@ void nr_generate_csi_rs(NR_DL_FRAME_PARMS frame_parms,
|
|||||||
|
|
||||||
// ZP CSI RS
|
// ZP CSI RS
|
||||||
if (csi_params->csi_type == 2) {
|
if (csi_params->csi_type == 2) {
|
||||||
((int16_t*)dataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1)+(2*dataF_offset)] = 0;
|
((int16_t*)dataF[p])[((l*frame_parms->ofdm_symbol_size + k)<<1)+(2*dataF_offset)] = 0;
|
||||||
((int16_t*)dataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1)+1+(2*dataF_offset)] = 0;
|
((int16_t*)dataF[p])[((l*frame_parms->ofdm_symbol_size + k)<<1)+1+(2*dataF_offset)] = 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
((int16_t*)dataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1)+(2*dataF_offset)] = (beta*wt*wf*mod_csi[l][mprime<<1]) >> 15;
|
((int16_t*)dataF[p])[((l*frame_parms->ofdm_symbol_size + k)<<1)+(2*dataF_offset)] = (beta*wt*wf*mod_csi[l][mprime<<1]) >> 15;
|
||||||
((int16_t*)dataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1)+1+(2*dataF_offset)] = (beta*wt*wf*mod_csi[l][(mprime<<1) + 1]) >> 15;
|
((int16_t*)dataF[p])[((l*frame_parms->ofdm_symbol_size + k)<<1)+1+(2*dataF_offset)] = (beta*wt*wf*mod_csi[l][(mprime<<1) + 1]) >> 15;
|
||||||
}
|
}
|
||||||
#ifdef NR_CSIRS_DEBUG
|
#ifdef NR_CSIRS_DEBUG
|
||||||
printf("l,k (%d,%d) seq. index %d \t port %d \t (%d,%d)\n",l,k,mprime,p+3000,
|
printf("l,k (%d,%d) seq. index %d \t port %d \t (%d,%d)\n",l,k,mprime,p+3000,
|
||||||
((int16_t*)dataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1)+(2*dataF_offset)],
|
((int16_t*)dataF[p])[((l*frame_parms->ofdm_symbol_size + k)<<1)+(2*dataF_offset)],
|
||||||
((int16_t*)dataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1)+1+(2*dataF_offset)]);
|
((int16_t*)dataF[p])[((l*frame_parms->ofdm_symbol_size + k)<<1)+1+(2*dataF_offset)]);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -638,23 +646,25 @@ void nr_generate_csi_rs(NR_DL_FRAME_PARMS frame_parms,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nr_csi_rs_info->N_cdm_groups = size;
|
if (N_cdm_groups) *N_cdm_groups = size;
|
||||||
nr_csi_rs_info->CDM_group_size = gs;
|
if (CDM_group_size) *CDM_group_size = gs;
|
||||||
nr_csi_rs_info->kprime = kprime;
|
if (k_prime) *k_prime = kprime;
|
||||||
nr_csi_rs_info->lprime = lprime;
|
if (l_prime) *l_prime = lprime;
|
||||||
nr_csi_rs_info->N_ports = ports;
|
if (N_ports) *N_ports = ports;
|
||||||
memcpy(nr_csi_rs_info->j,j,16*sizeof(uint8_t));
|
if (j_cdm) memcpy(j_cdm,j,16*sizeof(uint8_t));
|
||||||
memcpy(nr_csi_rs_info->koverline,koverline,16*sizeof(uint8_t));
|
if (k_overline) memcpy(k_overline,koverline,16*sizeof(uint8_t));
|
||||||
memcpy(nr_csi_rs_info->loverline,loverline,16*sizeof(uint8_t));
|
if (l_overline) memcpy(l_overline,loverline,16*sizeof(uint8_t));
|
||||||
|
|
||||||
#ifdef NR_CSIRS_DEBUG
|
#ifdef NR_CSIRS_DEBUG
|
||||||
LOG_I(NR_PHY, "nr_csi_rs_info->N_ports = %d\n", nr_csi_rs_info->N_ports);
|
if (N_ports) LOG_I(NR_PHY, "nr_csi_info->N_ports = %d\n", *N_ports);
|
||||||
LOG_I(NR_PHY, "nr_csi_rs_info->N_cdm_groups = %d\n", nr_csi_rs_info->N_cdm_groups);
|
if (N_cdm_groups) LOG_I(NR_PHY, "nr_csi_info->N_cdm_groups = %d\n", *N_cdm_groups);
|
||||||
LOG_I(NR_PHY, "nr_csi_rs_info->CDM_group_size = %d\n", nr_csi_rs_info->CDM_group_size);
|
if (CDM_group_size) LOG_I(NR_PHY, "nr_csi_info->CDM_group_size = %d\n", *CDM_group_size);
|
||||||
LOG_I(NR_PHY, "nr_csi_rs_info->kprime = %d\n", nr_csi_rs_info->kprime);
|
if (k_prime) LOG_I(NR_PHY, "nr_csi_info->kprime = %d\n", *k_prime);
|
||||||
LOG_I(NR_PHY, "nr_csi_rs_info->lprime = %d\n", nr_csi_rs_info->lprime);
|
if (l_prime) LOG_I(NR_PHY, "nr_csi_info->lprime = %d\n", *l_prime);
|
||||||
for(int ji=0; ji<nr_csi_rs_info->N_cdm_groups; ji++) {
|
if (N_cdm_groups) {
|
||||||
LOG_I(NR_PHY, "(CDM group %d) j = %d, koverline = %d, loverline = %d\n", ji, nr_csi_rs_info->j[ji], nr_csi_rs_info->koverline[ji], nr_csi_rs_info->loverline[ji]);
|
for(int ji=0; ji<*N_cdm_groups; ji++) {
|
||||||
|
LOG_I(NR_PHY, "(CDM group %d) j = %d, koverline = %d, loverline = %d\n", ji, j[ji], koverline[ji], loverline[ji]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -111,9 +111,10 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
|
|||||||
// DMRS length is per OFDM symbol
|
// DMRS length is per OFDM symbol
|
||||||
uint32_t dmrs_length = n_rb*6; //2(QPSK)*3(per RB)*6(REG per CCE)
|
uint32_t dmrs_length = n_rb*6; //2(QPSK)*3(per RB)*6(REG per CCE)
|
||||||
uint32_t encoded_length = dci_pdu->AggregationLevel*108; //2(QPSK)*9(per RB)*6(REG per CCE)
|
uint32_t encoded_length = dci_pdu->AggregationLevel*108; //2(QPSK)*9(per RB)*6(REG per CCE)
|
||||||
LOG_D(PHY, "DL_DCI : rb_offset %d, nb_rb %d, DMRS length per symbol %d\t DCI encoded length %d (precoder_granularity %d,reg_mapping %d),Scrambling_Id %d,ScramblingRNTI %x,PayloadSizeBits %d\n",
|
if (dci_pdu->RNTI != 0xFFFF)
|
||||||
rb_offset, n_rb,dmrs_length, encoded_length,pdcch_pdu_rel15->precoderGranularity,pdcch_pdu_rel15->CceRegMappingType,
|
LOG_D(PHY, "DL_DCI : rb_offset %d, nb_rb %d, DMRS length per symbol %d\t DCI encoded length %d (precoder_granularity %d, reg_mapping %d), Scrambling_Id %d, ScramblingRNTI %x, PayloadSizeBits %d\n",
|
||||||
dci_pdu->ScramblingId,dci_pdu->ScramblingRNTI,dci_pdu->PayloadSizeBits);
|
rb_offset, n_rb,dmrs_length, encoded_length,pdcch_pdu_rel15->precoderGranularity,pdcch_pdu_rel15->CceRegMappingType,
|
||||||
|
dci_pdu->ScramblingId,dci_pdu->ScramblingRNTI,dci_pdu->PayloadSizeBits);
|
||||||
dmrs_length += rb_offset*6; // To accommodate more DMRS symbols in case of rb offset
|
dmrs_length += rb_offset*6; // To accommodate more DMRS symbols in case of rb offset
|
||||||
|
|
||||||
/// DMRS QPSK modulation
|
/// DMRS QPSK modulation
|
||||||
@@ -122,11 +123,11 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
|
|||||||
nr_modulation(gold_pdcch_dmrs[symb], dmrs_length, DMRS_MOD_ORDER, mod_dmrs[symb]); //Qm = 2 as DMRS is QPSK modulated
|
nr_modulation(gold_pdcch_dmrs[symb], dmrs_length, DMRS_MOD_ORDER, mod_dmrs[symb]); //Qm = 2 as DMRS is QPSK modulated
|
||||||
|
|
||||||
#ifdef DEBUG_PDCCH_DMRS
|
#ifdef DEBUG_PDCCH_DMRS
|
||||||
if(dci_pdu->RNTI!=0xFFFF) {
|
if(dci_pdu->RNTI!=0xFFFF) {
|
||||||
for (int i=0; i<dmrs_length>>1; i++)
|
for (int i=0; i<dmrs_length>>1; i++)
|
||||||
printf("symb %d i %d %p gold seq 0x%08x mod_dmrs %d %d\n", symb, i,
|
printf("symb %d i %d %p gold seq 0x%08x mod_dmrs %d %d\n", symb, i,
|
||||||
&gold_pdcch_dmrs[symb][i>>5],gold_pdcch_dmrs[symb][i>>5], mod_dmrs[symb][i<<1], mod_dmrs[symb][(i<<1)+1] );
|
&gold_pdcch_dmrs[symb][i>>5],gold_pdcch_dmrs[symb][i>>5], mod_dmrs[symb][i<<1], mod_dmrs[symb][(i<<1)+1]);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -265,7 +266,6 @@ void nr_generate_dci_top(processingData_L1tx_t *msgTx,
|
|||||||
int16_t amp,
|
int16_t amp,
|
||||||
NR_DL_FRAME_PARMS *frame_parms) {
|
NR_DL_FRAME_PARMS *frame_parms) {
|
||||||
|
|
||||||
|
|
||||||
for (int i=0; i<msgTx->num_ul_pdcch; i++)
|
for (int i=0; i<msgTx->num_ul_pdcch; i++)
|
||||||
nr_generate_dci(msgTx->gNB,&msgTx->ul_pdcch_pdu[i].pdcch_pdu.pdcch_pdu_rel15,txdataF,amp,frame_parms,slot);
|
nr_generate_dci(msgTx->gNB,&msgTx->ul_pdcch_pdu[i].pdcch_pdu.pdcch_pdu_rel15,txdataF,amp,frame_parms,slot);
|
||||||
for (int i=0; i<msgTx->num_dl_pdcch; i++)
|
for (int i=0; i<msgTx->num_dl_pdcch; i++)
|
||||||
|
|||||||
@@ -123,7 +123,6 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
|
|||||||
rel15->dlDmrsSymbPos);
|
rel15->dlDmrsSymbPos);
|
||||||
n_ptrs = (rel15->rbSize + rel15->PTRSFreqDensity - 1)/rel15->PTRSFreqDensity;
|
n_ptrs = (rel15->rbSize + rel15->PTRSFreqDensity - 1)/rel15->PTRSFreqDensity;
|
||||||
}
|
}
|
||||||
int16_t mod_ptrs[n_ptrs<<1] __attribute__ ((aligned(16)));
|
|
||||||
|
|
||||||
/// CRC, coding, interleaving and rate matching
|
/// CRC, coding, interleaving and rate matching
|
||||||
AssertFatal(harq->pdu!=NULL,"harq->pdu is null\n");
|
AssertFatal(harq->pdu!=NULL,"harq->pdu is null\n");
|
||||||
@@ -302,12 +301,14 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
|
|||||||
|
|
||||||
/* calculate if current symbol is PTRS symbols */
|
/* calculate if current symbol is PTRS symbols */
|
||||||
ptrs_idx = 0;
|
ptrs_idx = 0;
|
||||||
|
int16_t *mod_ptrs = NULL;
|
||||||
if(rel15->pduBitmap & 0x1) {
|
if(rel15->pduBitmap & 0x1) {
|
||||||
ptrs_symbol = is_ptrs_symbol(l,dlPtrsSymPos);
|
ptrs_symbol = is_ptrs_symbol(l,dlPtrsSymPos);
|
||||||
if(ptrs_symbol) {
|
if(ptrs_symbol) {
|
||||||
/* PTRS QPSK Modulation for each OFDM symbol in a slot */
|
/* PTRS QPSK Modulation for each OFDM symbol in a slot */
|
||||||
LOG_D(PHY,"Doing ptrs modulation for symbol %d, n_ptrs %d\n",l,n_ptrs);
|
LOG_D(PHY,"Doing ptrs modulation for symbol %d, n_ptrs %d\n",l,n_ptrs);
|
||||||
|
int16_t mod_ptrsBuf[n_ptrs<<1] __attribute__ ((aligned(16)));
|
||||||
|
mod_ptrs =mod_ptrsBuf;
|
||||||
nr_modulation(pdsch_dmrs[l][rel15->SCID], (n_ptrs<<1), DMRS_MOD_ORDER, mod_ptrs);
|
nr_modulation(pdsch_dmrs[l][rel15->SCID], (n_ptrs<<1), DMRS_MOD_ORDER, mod_ptrs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -123,7 +123,6 @@ NR_gNB_DLSCH_t *new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms,
|
|||||||
bzero(dlsch,sizeof(NR_gNB_DLSCH_t));
|
bzero(dlsch,sizeof(NR_gNB_DLSCH_t));
|
||||||
dlsch->Kmimo = Kmimo;
|
dlsch->Kmimo = Kmimo;
|
||||||
dlsch->Mdlharq = Mdlharq;
|
dlsch->Mdlharq = Mdlharq;
|
||||||
dlsch->Mlimit = 4;
|
|
||||||
dlsch->Nsoft = Nsoft;
|
dlsch->Nsoft = Nsoft;
|
||||||
|
|
||||||
int txdataf_size = frame_parms->N_RB_DL*NR_SYMBOLS_PER_SLOT*NR_NB_SC_PER_RB*8; // max pdsch encoded length for each layer
|
int txdataf_size = frame_parms->N_RB_DL*NR_SYMBOLS_PER_SLOT*NR_NB_SC_PER_RB*8; // max pdsch encoded length for each layer
|
||||||
|
|||||||
@@ -337,12 +337,20 @@ void init_prach_ru_list(RU_t *ru);
|
|||||||
void free_nr_ru_prach_entry(RU_t *ru, int prach_id);
|
void free_nr_ru_prach_entry(RU_t *ru, int prach_id);
|
||||||
uint8_t get_nr_prach_duration(uint8_t prach_format);
|
uint8_t get_nr_prach_duration(uint8_t prach_format);
|
||||||
|
|
||||||
void nr_generate_csi_rs(NR_DL_FRAME_PARMS frame_parms,
|
void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms,
|
||||||
int32_t **dataF,
|
int32_t **dataF,
|
||||||
int16_t amp,
|
const int16_t amp,
|
||||||
nr_csi_rs_info_t *nr_csi_rs_info,
|
nr_csi_info_t *nr_csi_info,
|
||||||
nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csi_params,
|
const nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csi_params,
|
||||||
int slot);
|
const int slot,
|
||||||
|
uint8_t *N_cdm_groups,
|
||||||
|
uint8_t *CDM_group_size,
|
||||||
|
uint8_t *k_prime,
|
||||||
|
uint8_t *l_prime,
|
||||||
|
uint8_t *N_ports,
|
||||||
|
uint8_t *j_cdm,
|
||||||
|
uint8_t *k_overline,
|
||||||
|
uint8_t *l_overline);
|
||||||
|
|
||||||
void free_nr_prach_entry(PHY_VARS_gNB *gNB, int prach_id);
|
void free_nr_prach_entry(PHY_VARS_gNB *gNB, int prach_id);
|
||||||
|
|
||||||
|
|||||||
@@ -68,12 +68,20 @@ void nr_fill_ulsch(PHY_VARS_gNB *gNB,
|
|||||||
ulsch->rnti = ulsch_pdu->rnti;
|
ulsch->rnti = ulsch_pdu->rnti;
|
||||||
//ulsch->rnti_type;
|
//ulsch->rnti_type;
|
||||||
ulsch->harq_mask |= 1<<harq_pid;
|
ulsch->harq_mask |= 1<<harq_pid;
|
||||||
ulsch->harq_process_id[slot] = harq_pid;
|
|
||||||
|
|
||||||
ulsch->harq_processes[harq_pid]->frame=frame;
|
NR_UL_gNB_HARQ_t *harq = ulsch->harq_processes[harq_pid];
|
||||||
ulsch->harq_processes[harq_pid]->slot=slot;
|
harq->frame=frame;
|
||||||
ulsch->harq_processes[harq_pid]->handled= 0;
|
harq->slot=slot;
|
||||||
ulsch->harq_processes[harq_pid]->status= NR_ACTIVE;
|
harq->handled = 0;
|
||||||
|
harq->status= NR_ACTIVE;
|
||||||
|
harq->new_rx = harq->ndi != ulsch_pdu->pusch_data.new_data_indicator;
|
||||||
|
if (harq->new_rx) {
|
||||||
|
harq->ndi = ulsch_pdu->pusch_data.new_data_indicator;
|
||||||
|
harq->round = 0;
|
||||||
|
} else {
|
||||||
|
harq->round++;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy((void*)&ulsch->harq_processes[harq_pid]->ulsch_pdu, (void*)ulsch_pdu, sizeof(nfapi_nr_pusch_pdu_t));
|
memcpy((void*)&ulsch->harq_processes[harq_pid]->ulsch_pdu, (void*)ulsch_pdu, sizeof(nfapi_nr_pusch_pdu_t));
|
||||||
|
|
||||||
LOG_D(PHY,"Initializing nFAPI for ULSCH, UE %d, harq_pid %d\n",ulsch_id,harq_pid);
|
LOG_D(PHY,"Initializing nFAPI for ULSCH, UE %d, harq_pid %d\n",ulsch_id,harq_pid);
|
||||||
|
|||||||
@@ -101,7 +101,6 @@ NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations, uint16_t N_RB_UL)
|
|||||||
ulsch = (NR_gNB_ULSCH_t *)malloc16_clear(sizeof(NR_gNB_ULSCH_t));
|
ulsch = (NR_gNB_ULSCH_t *)malloc16_clear(sizeof(NR_gNB_ULSCH_t));
|
||||||
|
|
||||||
ulsch->max_ldpc_iterations = max_ldpc_iterations;
|
ulsch->max_ldpc_iterations = max_ldpc_iterations;
|
||||||
ulsch->Mlimit = 4;
|
|
||||||
|
|
||||||
for (i=0; i<NR_MAX_ULSCH_HARQ_PROCESSES; i++) {
|
for (i=0; i<NR_MAX_ULSCH_HARQ_PROCESSES; i++) {
|
||||||
|
|
||||||
@@ -136,10 +135,8 @@ void clean_gNB_ulsch(NR_gNB_ULSCH_t *ulsch)
|
|||||||
ulsch->rnti_type = 0;
|
ulsch->rnti_type = 0;
|
||||||
ulsch->cyclicShift = 0;
|
ulsch->cyclicShift = 0;
|
||||||
ulsch->cooperation_flag = 0;
|
ulsch->cooperation_flag = 0;
|
||||||
ulsch->Mlimit = 0;
|
|
||||||
ulsch->max_ldpc_iterations = 0;
|
ulsch->max_ldpc_iterations = 0;
|
||||||
ulsch->last_iteration_cnt = 0;
|
ulsch->last_iteration_cnt = 0;
|
||||||
for (i=0;i<NR_MAX_SLOTS_PER_FRAME;i++) ulsch->harq_process_id[i] = 0;
|
|
||||||
|
|
||||||
for (i=0; i<NR_MAX_ULSCH_HARQ_PROCESSES; i++) {
|
for (i=0; i<NR_MAX_ULSCH_HARQ_PROCESSES; i++) {
|
||||||
if (ulsch->harq_processes[i]){
|
if (ulsch->harq_processes[i]){
|
||||||
|
|||||||
@@ -331,8 +331,8 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
|
|||||||
corr[aa][l].r += xr[aa][l][n].r * idft12_re[seq_index][n] + xr[aa][l][n].i * idft12_im[seq_index][n];
|
corr[aa][l].r += xr[aa][l][n].r * idft12_re[seq_index][n] + xr[aa][l][n].i * idft12_im[seq_index][n];
|
||||||
corr[aa][l].i += xr[aa][l][n].r * idft12_im[seq_index][n] - xr[aa][l][n].i * idft12_re[seq_index][n];
|
corr[aa][l].i += xr[aa][l][n].r * idft12_im[seq_index][n] - xr[aa][l][n].i * idft12_re[seq_index][n];
|
||||||
}
|
}
|
||||||
corr[aa][l].r >>= 31;
|
corr[aa][l].r >>= 31;
|
||||||
corr[aa][l].i >>= 31;
|
corr[aa][l].i >>= 31;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LOG_D(PHY,"PUCCH IDFT[%d/%d] = (%ld,%ld)=>%f\n",
|
LOG_D(PHY,"PUCCH IDFT[%d/%d] = (%ld,%ld)=>%f\n",
|
||||||
|
|||||||
@@ -33,16 +33,103 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "executables/nr-softmodem-common.h"
|
||||||
#include "nr_transport_proto_ue.h"
|
#include "nr_transport_proto_ue.h"
|
||||||
#include "PHY/phy_extern_nr_ue.h"
|
#include "PHY/phy_extern_nr_ue.h"
|
||||||
#include "common/utils/nr/nr_common.h"
|
#include "common/utils/nr/nr_common.h"
|
||||||
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
|
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
|
||||||
#include "PHY/NR_UE_ESTIMATION/filt16a_32.h"
|
#include "PHY/NR_UE_ESTIMATION/filt16a_32.h"
|
||||||
|
|
||||||
|
// 10*log10(pow(2,30))
|
||||||
|
#define pow_2_30_dB 90
|
||||||
|
|
||||||
//#define NR_CSIRS_DEBUG
|
//#define NR_CSIRS_DEBUG
|
||||||
|
//#define NR_CSIIM_DEBUG
|
||||||
|
|
||||||
bool is_csi_rs_in_symbol(fapi_nr_dl_config_csirs_pdu_rel15_t csirs_config_pdu, int symbol) {
|
void nr_det_A_MF_2x2(int32_t *a_mf_00,
|
||||||
|
int32_t *a_mf_01,
|
||||||
|
int32_t *a_mf_10,
|
||||||
|
int32_t *a_mf_11,
|
||||||
|
int32_t *det_fin,
|
||||||
|
const unsigned short nb_rb) {
|
||||||
|
|
||||||
|
int16_t nr_conjug2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1} ;
|
||||||
|
|
||||||
|
__m128i ad_re_128, bc_re_128, det_re_128;
|
||||||
|
|
||||||
|
__m128i *a_mf_00_128 = (__m128i *)a_mf_00;
|
||||||
|
__m128i *a_mf_01_128 = (__m128i *)a_mf_01;
|
||||||
|
__m128i *a_mf_10_128 = (__m128i *)a_mf_10;
|
||||||
|
__m128i *a_mf_11_128 = (__m128i *)a_mf_11;
|
||||||
|
__m128i *det_fin_128 = (__m128i *)det_fin;
|
||||||
|
|
||||||
|
for (int rb = 0; rb<3*nb_rb; rb++) {
|
||||||
|
|
||||||
|
//complex multiplication (I_a+jQ_a)(I_d+jQ_d) = (I_aI_d - Q_aQ_d) + j(Q_aI_d + I_aQ_d)
|
||||||
|
//The imag part is often zero, we compute only the real part
|
||||||
|
ad_re_128 = _mm_sign_epi16(a_mf_00_128[0],*(__m128i*)&nr_conjug2[0]);
|
||||||
|
ad_re_128 = _mm_madd_epi16(ad_re_128,a_mf_11_128[0]); //Re: I_a0*I_d0 - Q_a1*Q_d1
|
||||||
|
|
||||||
|
//complex multiplication (I_b+jQ_b)(I_c+jQ_c) = (I_bI_c - Q_bQ_c) + j(Q_bI_c + I_bQ_c)
|
||||||
|
//The imag part is often zero, we compute only the real part
|
||||||
|
bc_re_128 = _mm_sign_epi16(a_mf_01_128[0],*(__m128i*)&nr_conjug2[0]);
|
||||||
|
bc_re_128 = _mm_madd_epi16(bc_re_128,a_mf_10_128[0]); //Re: I_b0*I_c0 - Q_b1*Q_c1
|
||||||
|
|
||||||
|
det_re_128 = _mm_sub_epi32(ad_re_128, bc_re_128);
|
||||||
|
|
||||||
|
//det in Q30 format
|
||||||
|
det_fin_128[0] = _mm_abs_epi32(det_re_128);
|
||||||
|
|
||||||
|
det_fin_128+=1;
|
||||||
|
a_mf_00_128+=1;
|
||||||
|
a_mf_01_128+=1;
|
||||||
|
a_mf_10_128+=1;
|
||||||
|
a_mf_11_128+=1;
|
||||||
|
}
|
||||||
|
_mm_empty();
|
||||||
|
_m_empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void nr_squared_matrix_element(int32_t *a,
|
||||||
|
int32_t *a_sq,
|
||||||
|
const unsigned short nb_rb) {
|
||||||
|
__m128i *a_128 = (__m128i *)a;
|
||||||
|
__m128i *a_sq_128 = (__m128i *)a_sq;
|
||||||
|
for (int rb=0; rb<3*nb_rb; rb++) {
|
||||||
|
a_sq_128[0] = _mm_madd_epi16(a_128[0], a_128[0]);
|
||||||
|
a_sq_128+=1;
|
||||||
|
a_128+=1;
|
||||||
|
}
|
||||||
|
_mm_empty();
|
||||||
|
_m_empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void nr_numer_2x2(int32_t *a_00_sq,
|
||||||
|
int32_t *a_01_sq,
|
||||||
|
int32_t *a_10_sq,
|
||||||
|
int32_t *a_11_sq,
|
||||||
|
int32_t *num_fin,
|
||||||
|
const unsigned short nb_rb) {
|
||||||
|
__m128i *a_00_sq_128 = (__m128i *)a_00_sq;
|
||||||
|
__m128i *a_01_sq_128 = (__m128i *)a_01_sq;
|
||||||
|
__m128i *a_10_sq_128 = (__m128i *)a_10_sq;
|
||||||
|
__m128i *a_11_sq_128 = (__m128i *)a_11_sq;
|
||||||
|
__m128i *num_fin_128 = (__m128i *)num_fin;
|
||||||
|
for (int rb=0; rb<3*nb_rb; rb++) {
|
||||||
|
__m128i sq_a_plus_sq_d_128 = _mm_add_epi32(a_00_sq_128[0], a_11_sq_128[0]);
|
||||||
|
__m128i sq_b_plus_sq_c_128 = _mm_add_epi32(a_01_sq_128[0], a_10_sq_128[0]);
|
||||||
|
num_fin_128[0] = _mm_add_epi32(sq_a_plus_sq_d_128, sq_b_plus_sq_c_128);
|
||||||
|
num_fin_128+=1;
|
||||||
|
a_00_sq_128+=1;
|
||||||
|
a_01_sq_128+=1;
|
||||||
|
a_10_sq_128+=1;
|
||||||
|
a_11_sq_128+=1;
|
||||||
|
}
|
||||||
|
_mm_empty();
|
||||||
|
_m_empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_csi_rs_in_symbol(const fapi_nr_dl_config_csirs_pdu_rel15_t csirs_config_pdu, const int symbol) {
|
||||||
|
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
@@ -90,17 +177,27 @@ bool is_csi_rs_in_symbol(fapi_nr_dl_config_csirs_pdu_rel15_t csirs_config_pdu, i
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int nr_get_csi_rs_signal(PHY_VARS_NR_UE *ue,
|
int nr_get_csi_rs_signal(const PHY_VARS_NR_UE *ue,
|
||||||
UE_nr_rxtx_proc_t *proc,
|
const UE_nr_rxtx_proc_t *proc,
|
||||||
fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu,
|
const fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu,
|
||||||
nr_csi_rs_info_t *nr_csi_rs_info,
|
const nr_csi_info_t *nr_csi_info,
|
||||||
int32_t **csi_rs_received_signal) {
|
const uint8_t N_cdm_groups,
|
||||||
|
const uint8_t CDM_group_size,
|
||||||
|
const uint8_t k_prime,
|
||||||
|
const uint8_t l_prime,
|
||||||
|
const uint8_t *j_cdm,
|
||||||
|
const uint8_t *k_overline,
|
||||||
|
const uint8_t *l_overline,
|
||||||
|
int32_t csi_rs_received_signal[][ue->frame_parms.samples_per_slot_wCP],
|
||||||
|
uint32_t *rsrp,
|
||||||
|
int *rsrp_dBm) {
|
||||||
|
|
||||||
int32_t **rxdataF = ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF;
|
int32_t **rxdataF = ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF;
|
||||||
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
|
const NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
|
||||||
|
uint16_t meas_count = 0;
|
||||||
|
uint32_t rsrp_sum = 0;
|
||||||
|
|
||||||
for (int ant_rx = 0; ant_rx < frame_parms->nb_antennas_rx; ant_rx++) {
|
for (int ant_rx = 0; ant_rx < frame_parms->nb_antennas_rx; ant_rx++) {
|
||||||
memset(csi_rs_received_signal[ant_rx], 0, frame_parms->samples_per_frame_wCP*sizeof(int32_t));
|
|
||||||
|
|
||||||
for (int rb = csirs_config_pdu->start_rb; rb < (csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs); rb++) {
|
for (int rb = csirs_config_pdu->start_rb; rb < (csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs); rb++) {
|
||||||
|
|
||||||
@@ -109,36 +206,41 @@ int nr_get_csi_rs_signal(PHY_VARS_NR_UE *ue,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int cdm_id = 0; cdm_id < nr_csi_rs_info->N_cdm_groups; cdm_id++) {
|
for (int cdm_id = 0; cdm_id < N_cdm_groups; cdm_id++) {
|
||||||
for (int s = 0; s < nr_csi_rs_info->CDM_group_size; s++) {
|
for (int s = 0; s < CDM_group_size; s++) {
|
||||||
|
|
||||||
// loop over frequency resource elements within a group
|
// loop over frequency resource elements within a group
|
||||||
for (int kp = 0; kp <= nr_csi_rs_info->kprime; kp++) {
|
for (int kp = 0; kp <= k_prime; kp++) {
|
||||||
|
|
||||||
uint16_t k = (frame_parms->first_carrier_offset + (rb*NR_NB_SC_PER_RB)+nr_csi_rs_info->koverline[cdm_id] + kp) % frame_parms->ofdm_symbol_size;
|
uint16_t k = (frame_parms->first_carrier_offset + (rb*NR_NB_SC_PER_RB)+k_overline[cdm_id] + kp) % frame_parms->ofdm_symbol_size;
|
||||||
|
|
||||||
// loop over time resource elements within a group
|
// loop over time resource elements within a group
|
||||||
for (int lp = 0; lp <= nr_csi_rs_info->lprime; lp++) {
|
for (int lp = 0; lp <= l_prime; lp++) {
|
||||||
uint16_t symb = lp + nr_csi_rs_info->loverline[cdm_id];
|
uint16_t symb = lp + l_overline[cdm_id];
|
||||||
uint64_t symbol_offset = symb*frame_parms->ofdm_symbol_size;
|
uint64_t symbol_offset = symb*frame_parms->ofdm_symbol_size;
|
||||||
int16_t *rx_signal = (int16_t*)&rxdataF[ant_rx][symbol_offset];
|
c16_t *rx_signal = (c16_t*)&rxdataF[ant_rx][symbol_offset];
|
||||||
int16_t *rx_csi_rs_signal = (int16_t*)&csi_rs_received_signal[ant_rx][symbol_offset];
|
c16_t *rx_csi_rs_signal = (c16_t*)&csi_rs_received_signal[ant_rx][symbol_offset];
|
||||||
rx_csi_rs_signal[k<<1] = rx_signal[k<<1];
|
rx_csi_rs_signal[k].r = rx_signal[k].r;
|
||||||
rx_csi_rs_signal[(k<<1)+1] = rx_signal[(k<<1)+1];
|
rx_csi_rs_signal[k].i = rx_signal[k].i;
|
||||||
|
|
||||||
|
rsrp_sum += (((int32_t)(rx_csi_rs_signal[k].r)*rx_csi_rs_signal[k].r) +
|
||||||
|
((int32_t)(rx_csi_rs_signal[k].i)*rx_csi_rs_signal[k].i));
|
||||||
|
|
||||||
|
meas_count++;
|
||||||
|
|
||||||
#ifdef NR_CSIRS_DEBUG
|
#ifdef NR_CSIRS_DEBUG
|
||||||
int dataF_offset = proc->nr_slot_rx*ue->frame_parms.samples_per_slot_wCP;
|
int dataF_offset = proc->nr_slot_rx*ue->frame_parms.samples_per_slot_wCP;
|
||||||
uint16_t port_tx = s+nr_csi_rs_info->j[cdm_id]*nr_csi_rs_info->CDM_group_size;
|
uint16_t port_tx = s+j_cdm[cdm_id]*CDM_group_size;
|
||||||
int16_t *tx_csi_rs_signal = (int16_t*)&nr_csi_rs_info->csi_rs_generated_signal[port_tx][symbol_offset+dataF_offset];
|
c16_t *tx_csi_rs_signal = (c16_t*)&nr_csi_info->csi_rs_generated_signal[port_tx][symbol_offset+dataF_offset];
|
||||||
LOG_I(NR_PHY, "l,k (%2d,%4d) |\tport_tx %d (%4d,%4d)\tant_rx %d (%4d,%4d)\n",
|
LOG_I(NR_PHY, "l,k (%2d,%4d) |\tport_tx %d (%4d,%4d)\tant_rx %d (%4d,%4d)\n",
|
||||||
symb,
|
symb,
|
||||||
k,
|
k,
|
||||||
port_tx+3000,
|
port_tx+3000,
|
||||||
tx_csi_rs_signal[k<<1],
|
tx_csi_rs_signal[k].r,
|
||||||
tx_csi_rs_signal[(k<<1)+1],
|
tx_csi_rs_signal[k].i,
|
||||||
ant_rx,
|
ant_rx,
|
||||||
rx_csi_rs_signal[k<<1],
|
rx_csi_rs_signal[k].r,
|
||||||
rx_csi_rs_signal[(k<<1)+1]);
|
rx_csi_rs_signal[k].i);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -147,10 +249,19 @@ int nr_get_csi_rs_signal(PHY_VARS_NR_UE *ue,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
*rsrp = rsrp_sum/meas_count;
|
||||||
|
*rsrp_dBm = dB_fixed(*rsrp) + 30 - pow_2_30_dB
|
||||||
|
- ((int)openair0_cfg[0].rx_gain[0] - (int)openair0_cfg[0].rx_gain_offset[0]) - dB_fixed(ue->frame_parms.ofdm_symbol_size);
|
||||||
|
|
||||||
|
#ifdef NR_CSIRS_DEBUG
|
||||||
|
LOG_I(NR_PHY, "RSRP = %i (%i dBm)\n", *rsrp, *rsrp_dBm);
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t calc_power_csirs(uint16_t *x, fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu) {
|
uint32_t calc_power_csirs(const uint16_t *x, const fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu) {
|
||||||
uint64_t sum_x = 0;
|
uint64_t sum_x = 0;
|
||||||
uint64_t sum_x2 = 0;
|
uint64_t sum_x2 = 0;
|
||||||
uint16_t size = 0;
|
uint16_t size = 0;
|
||||||
@@ -165,25 +276,38 @@ uint32_t calc_power_csirs(uint16_t *x, fapi_nr_dl_config_csirs_pdu_rel15_t *csir
|
|||||||
return sum_x2/size - (sum_x/size)*(sum_x/size);
|
return sum_x2/size - (sum_x/size)*(sum_x/size);
|
||||||
}
|
}
|
||||||
|
|
||||||
int nr_csi_rs_channel_estimation(PHY_VARS_NR_UE *ue,
|
int nr_csi_rs_channel_estimation(const PHY_VARS_NR_UE *ue,
|
||||||
UE_nr_rxtx_proc_t *proc,
|
const UE_nr_rxtx_proc_t *proc,
|
||||||
fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu,
|
const fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu,
|
||||||
nr_csi_rs_info_t *nr_csi_rs_info,
|
const nr_csi_info_t *nr_csi_info,
|
||||||
int32_t **csi_rs_generated_signal,
|
const int32_t **csi_rs_generated_signal,
|
||||||
int32_t **csi_rs_received_signal,
|
const int32_t csi_rs_received_signal[][ue->frame_parms.samples_per_slot_wCP],
|
||||||
int32_t ***csi_rs_estimated_channel_freq,
|
const uint8_t N_cdm_groups,
|
||||||
|
const uint8_t CDM_group_size,
|
||||||
|
const uint8_t k_prime,
|
||||||
|
const uint8_t l_prime,
|
||||||
|
const uint8_t N_ports,
|
||||||
|
const uint8_t *j_cdm,
|
||||||
|
const uint8_t *k_overline,
|
||||||
|
const uint8_t *l_overline,
|
||||||
|
int32_t csi_rs_ls_estimated_channel[][N_ports][ue->frame_parms.ofdm_symbol_size],
|
||||||
|
int32_t csi_rs_estimated_channel_freq[][N_ports][ue->frame_parms.ofdm_symbol_size],
|
||||||
|
int16_t *log2_re,
|
||||||
|
int16_t *log2_maxh,
|
||||||
uint32_t *noise_power) {
|
uint32_t *noise_power) {
|
||||||
|
|
||||||
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
|
const NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
|
||||||
int dataF_offset = proc->nr_slot_rx*ue->frame_parms.samples_per_slot_wCP;
|
const int dataF_offset = proc->nr_slot_rx*ue->frame_parms.samples_per_slot_wCP;
|
||||||
*noise_power = 0;
|
*noise_power = 0;
|
||||||
|
int maxh = 0;
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
for (int ant_rx = 0; ant_rx < frame_parms->nb_antennas_rx; ant_rx++) {
|
for (int ant_rx = 0; ant_rx < frame_parms->nb_antennas_rx; ant_rx++) {
|
||||||
|
|
||||||
/// LS channel estimation
|
/// LS channel estimation
|
||||||
|
|
||||||
for(uint16_t port_tx = 0; port_tx<nr_csi_rs_info->N_ports; port_tx++) {
|
for(uint16_t port_tx = 0; port_tx<N_ports; port_tx++) {
|
||||||
memset(nr_csi_rs_info->csi_rs_ls_estimated_channel[ant_rx][port_tx], 0, frame_parms->ofdm_symbol_size*sizeof(int32_t));
|
memset(csi_rs_ls_estimated_channel[ant_rx][port_tx], 0, frame_parms->ofdm_symbol_size*sizeof(int32_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int rb = csirs_config_pdu->start_rb; rb < (csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs); rb++) {
|
for (int rb = csirs_config_pdu->start_rb; rb < (csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs); rb++) {
|
||||||
@@ -193,32 +317,32 @@ int nr_csi_rs_channel_estimation(PHY_VARS_NR_UE *ue,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int cdm_id = 0; cdm_id < nr_csi_rs_info->N_cdm_groups; cdm_id++) {
|
for (int cdm_id = 0; cdm_id < N_cdm_groups; cdm_id++) {
|
||||||
for (int s = 0; s < nr_csi_rs_info->CDM_group_size; s++) {
|
for (int s = 0; s < CDM_group_size; s++) {
|
||||||
|
|
||||||
uint16_t port_tx = s+nr_csi_rs_info->j[cdm_id]*nr_csi_rs_info->CDM_group_size;
|
uint16_t port_tx = s+j_cdm[cdm_id]*CDM_group_size;
|
||||||
|
|
||||||
// loop over frequency resource elements within a group
|
// loop over frequency resource elements within a group
|
||||||
for (int kp = 0; kp <= nr_csi_rs_info->kprime; kp++) {
|
for (int kp = 0; kp <= k_prime; kp++) {
|
||||||
|
|
||||||
uint16_t kinit = (frame_parms->first_carrier_offset + rb*NR_NB_SC_PER_RB) % frame_parms->ofdm_symbol_size;
|
uint16_t kinit = (frame_parms->first_carrier_offset + rb*NR_NB_SC_PER_RB) % frame_parms->ofdm_symbol_size;
|
||||||
uint16_t k = kinit + nr_csi_rs_info->koverline[cdm_id] + kp;
|
uint16_t k = kinit + k_overline[cdm_id] + kp;
|
||||||
|
|
||||||
// loop over time resource elements within a group
|
// loop over time resource elements within a group
|
||||||
for (int lp = 0; lp <= nr_csi_rs_info->lprime; lp++) {
|
for (int lp = 0; lp <= l_prime; lp++) {
|
||||||
uint16_t symb = lp + nr_csi_rs_info->loverline[cdm_id];
|
uint16_t symb = lp + l_overline[cdm_id];
|
||||||
uint64_t symbol_offset = symb*frame_parms->ofdm_symbol_size;
|
uint64_t symbol_offset = symb*frame_parms->ofdm_symbol_size;
|
||||||
int16_t *tx_csi_rs_signal = (int16_t*)&csi_rs_generated_signal[port_tx][symbol_offset+dataF_offset];
|
c16_t *tx_csi_rs_signal = (c16_t*)&csi_rs_generated_signal[port_tx][symbol_offset+dataF_offset];
|
||||||
int16_t *rx_csi_rs_signal = (int16_t*)&csi_rs_received_signal[ant_rx][symbol_offset];
|
c16_t *rx_csi_rs_signal = (c16_t*)&csi_rs_received_signal[ant_rx][symbol_offset];
|
||||||
int16_t *csi_rs_ls_estimated_channel = (int16_t*)&nr_csi_rs_info->csi_rs_ls_estimated_channel[ant_rx][port_tx][0];
|
c16_t *csi_rs_ls_estimated_channel16 = (c16_t*)&csi_rs_ls_estimated_channel[ant_rx][port_tx][0];
|
||||||
|
|
||||||
int16_t csi_rs_ls_estimated_channel_re = (int16_t)(((int32_t)tx_csi_rs_signal[k<<1]*rx_csi_rs_signal[k<<1] + (int32_t)tx_csi_rs_signal[(k<<1)+1]*rx_csi_rs_signal[(k<<1)+1])>>nr_csi_rs_info->csi_rs_generated_signal_bits);
|
int16_t csi_rs_ls_estimated_channel_re = (int16_t)(((int32_t)tx_csi_rs_signal[k].r*rx_csi_rs_signal[k].r + (int32_t)tx_csi_rs_signal[k].i*rx_csi_rs_signal[k].i)>>nr_csi_info->csi_rs_generated_signal_bits);
|
||||||
int16_t csi_rs_ls_estimated_channel_im = (int16_t)(((int32_t)tx_csi_rs_signal[k<<1]*rx_csi_rs_signal[(k<<1)+1] - (int32_t)tx_csi_rs_signal[(k<<1)+1]*rx_csi_rs_signal[k<<1])>>nr_csi_rs_info->csi_rs_generated_signal_bits);
|
int16_t csi_rs_ls_estimated_channel_im = (int16_t)(((int32_t)tx_csi_rs_signal[k].r*rx_csi_rs_signal[k].i - (int32_t)tx_csi_rs_signal[k].i*rx_csi_rs_signal[k].r)>>nr_csi_info->csi_rs_generated_signal_bits);
|
||||||
|
|
||||||
// This is not just the LS estimation for each (k,l), but also the sum of the different contributions
|
// This is not just the LS estimation for each (k,l), but also the sum of the different contributions
|
||||||
// for the sake of optimizing the memory used.
|
// for the sake of optimizing the memory used.
|
||||||
csi_rs_ls_estimated_channel[kinit<<1] += csi_rs_ls_estimated_channel_re;
|
csi_rs_ls_estimated_channel16[kinit].r += csi_rs_ls_estimated_channel_re;
|
||||||
csi_rs_ls_estimated_channel[(kinit<<1)+1] += csi_rs_ls_estimated_channel_im;
|
csi_rs_ls_estimated_channel16[kinit].i += csi_rs_ls_estimated_channel_im;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -232,16 +356,16 @@ int nr_csi_rs_channel_estimation(PHY_VARS_NR_UE *ue,
|
|||||||
}
|
}
|
||||||
for(int k = 0; k<frame_parms->ofdm_symbol_size; k++) {
|
for(int k = 0; k<frame_parms->ofdm_symbol_size; k++) {
|
||||||
LOG_I(NR_PHY, "l,k (%2d,%4d) | ", symb, k);
|
LOG_I(NR_PHY, "l,k (%2d,%4d) | ", symb, k);
|
||||||
for(uint16_t port_tx = 0; port_tx<nr_csi_rs_info->N_ports; port_tx++) {
|
for(uint16_t port_tx = 0; port_tx<N_ports; port_tx++) {
|
||||||
uint64_t symbol_offset = symb*frame_parms->ofdm_symbol_size;
|
uint64_t symbol_offset = symb*frame_parms->ofdm_symbol_size;
|
||||||
int16_t *tx_csi_rs_signal = (int16_t*)&csi_rs_generated_signal[port_tx][symbol_offset+dataF_offset];
|
c16_t *tx_csi_rs_signal = (c16_t*)&csi_rs_generated_signal[port_tx][symbol_offset+dataF_offset];
|
||||||
int16_t *rx_csi_rs_signal = (int16_t*)&csi_rs_received_signal[ant_rx][symbol_offset];
|
c16_t *rx_csi_rs_signal = (c16_t*)&csi_rs_received_signal[ant_rx][symbol_offset];
|
||||||
int16_t *csi_rs_ls_estimated_channel = (int16_t*)&nr_csi_rs_info->csi_rs_ls_estimated_channel[ant_rx][port_tx][0];
|
c16_t *csi_rs_ls_estimated_channel16 = (c16_t*)&csi_rs_ls_estimated_channel[ant_rx][port_tx][0];
|
||||||
printf("port_tx %d --> ant_rx %d, tx (%4d,%4d), rx (%4d,%4d), ls (%4d,%4d) | ",
|
printf("port_tx %d --> ant_rx %d, tx (%4d,%4d), rx (%4d,%4d), ls (%4d,%4d) | ",
|
||||||
port_tx+3000, ant_rx,
|
port_tx+3000, ant_rx,
|
||||||
tx_csi_rs_signal[k<<1], tx_csi_rs_signal[(k<<1)+1],
|
tx_csi_rs_signal[k].r, tx_csi_rs_signal[k].i,
|
||||||
rx_csi_rs_signal[k<<1], rx_csi_rs_signal[(k<<1)+1],
|
rx_csi_rs_signal[k].r, rx_csi_rs_signal[k].i,
|
||||||
csi_rs_ls_estimated_channel[k<<1], csi_rs_ls_estimated_channel[(k<<1)+1]);
|
csi_rs_ls_estimated_channel16[k].r, csi_rs_ls_estimated_channel16[k].i);
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
@@ -250,7 +374,7 @@ int nr_csi_rs_channel_estimation(PHY_VARS_NR_UE *ue,
|
|||||||
|
|
||||||
/// Channel interpolation
|
/// Channel interpolation
|
||||||
|
|
||||||
for(uint16_t port_tx = 0; port_tx<nr_csi_rs_info->N_ports; port_tx++) {
|
for(uint16_t port_tx = 0; port_tx<N_ports; port_tx++) {
|
||||||
memset(csi_rs_estimated_channel_freq[ant_rx][port_tx], 0, frame_parms->ofdm_symbol_size*sizeof(int32_t));
|
memset(csi_rs_estimated_channel_freq[ant_rx][port_tx], 0, frame_parms->ofdm_symbol_size*sizeof(int32_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -261,37 +385,40 @@ int nr_csi_rs_channel_estimation(PHY_VARS_NR_UE *ue,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
count++;
|
||||||
|
|
||||||
uint16_t k = (frame_parms->first_carrier_offset + rb*NR_NB_SC_PER_RB) % frame_parms->ofdm_symbol_size;
|
uint16_t k = (frame_parms->first_carrier_offset + rb*NR_NB_SC_PER_RB) % frame_parms->ofdm_symbol_size;
|
||||||
for(uint16_t port_tx = 0; port_tx<nr_csi_rs_info->N_ports; port_tx++) {
|
for(uint16_t port_tx = 0; port_tx<N_ports; port_tx++) {
|
||||||
int16_t *csi_rs_ls_estimated_channel = (int16_t*)&nr_csi_rs_info->csi_rs_ls_estimated_channel[ant_rx][port_tx][k];
|
int16_t *csi_rs_ls_estimated_channel16 = (int16_t*)&csi_rs_ls_estimated_channel[ant_rx][port_tx][k];
|
||||||
int16_t *csi_rs_estimated_channel16 = (int16_t *)&csi_rs_estimated_channel_freq[ant_rx][port_tx][k];
|
int16_t *csi_rs_estimated_channel16 = (int16_t *)&csi_rs_estimated_channel_freq[ant_rx][port_tx][k];
|
||||||
if( (k == 0) || (k == frame_parms->first_carrier_offset) ) { // Start of OFDM symbol case or first occupied subcarrier case
|
if( (k == 0) || (k == frame_parms->first_carrier_offset) ) { // Start of OFDM symbol case or first occupied subcarrier case
|
||||||
multadd_real_vector_complex_scalar(filt24_start, csi_rs_ls_estimated_channel, csi_rs_estimated_channel16, 24);
|
multadd_real_vector_complex_scalar(filt24_start, csi_rs_ls_estimated_channel16, csi_rs_estimated_channel16, 24);
|
||||||
} else if( ( (k + NR_NB_SC_PER_RB) >= frame_parms->ofdm_symbol_size) ||
|
} else if( ( (k + NR_NB_SC_PER_RB) >= frame_parms->ofdm_symbol_size) ||
|
||||||
(rb == (csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs-1)) ) { // End of OFDM symbol case or Last occupied subcarrier case
|
(rb == (csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs-1)) ) { // End of OFDM symbol case or Last occupied subcarrier case
|
||||||
multadd_real_vector_complex_scalar(filt24_end, csi_rs_ls_estimated_channel, csi_rs_estimated_channel16 - 3*sizeof(uint64_t), 24);
|
multadd_real_vector_complex_scalar(filt24_end, csi_rs_ls_estimated_channel16, csi_rs_estimated_channel16 - 3*sizeof(uint64_t), 24);
|
||||||
} else { // Middle case
|
} else { // Middle case
|
||||||
multadd_real_vector_complex_scalar(filt24_middle, csi_rs_ls_estimated_channel, csi_rs_estimated_channel16 - 3*sizeof(uint64_t), 24);
|
multadd_real_vector_complex_scalar(filt24_middle, csi_rs_ls_estimated_channel16, csi_rs_estimated_channel16 - 3*sizeof(uint64_t), 24);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Power noise estimation
|
/// Power noise estimation
|
||||||
uint16_t noise_real[frame_parms->nb_antennas_rx][nr_csi_rs_info->N_ports][csirs_config_pdu->nr_of_rbs];
|
uint16_t noise_real[frame_parms->nb_antennas_rx][N_ports][csirs_config_pdu->nr_of_rbs];
|
||||||
uint16_t noise_imag[frame_parms->nb_antennas_rx][nr_csi_rs_info->N_ports][csirs_config_pdu->nr_of_rbs];
|
uint16_t noise_imag[frame_parms->nb_antennas_rx][N_ports][csirs_config_pdu->nr_of_rbs];
|
||||||
for (int rb = csirs_config_pdu->start_rb; rb < (csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs); rb++) {
|
for (int rb = csirs_config_pdu->start_rb; rb < (csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs); rb++) {
|
||||||
if (csirs_config_pdu->freq_density <= 1 && csirs_config_pdu->freq_density != (rb % 2)) {
|
if (csirs_config_pdu->freq_density <= 1 && csirs_config_pdu->freq_density != (rb % 2)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
uint16_t k = (frame_parms->first_carrier_offset + rb*NR_NB_SC_PER_RB) % frame_parms->ofdm_symbol_size;
|
uint16_t k = (frame_parms->first_carrier_offset + rb*NR_NB_SC_PER_RB) % frame_parms->ofdm_symbol_size;
|
||||||
for(uint16_t port_tx = 0; port_tx<nr_csi_rs_info->N_ports; port_tx++) {
|
for(uint16_t port_tx = 0; port_tx<N_ports; port_tx++) {
|
||||||
int16_t *csi_rs_ls_estimated_channel = (int16_t*)&nr_csi_rs_info->csi_rs_ls_estimated_channel[ant_rx][port_tx][k];
|
c16_t *csi_rs_ls_estimated_channel16 = (c16_t*)&csi_rs_ls_estimated_channel[ant_rx][port_tx][k];
|
||||||
int16_t *csi_rs_estimated_channel16 = (int16_t *)&csi_rs_estimated_channel_freq[ant_rx][port_tx][k];
|
c16_t *csi_rs_estimated_channel16 = (c16_t *)&csi_rs_estimated_channel_freq[ant_rx][port_tx][k];
|
||||||
noise_real[ant_rx][port_tx][rb-csirs_config_pdu->start_rb] = abs(csi_rs_ls_estimated_channel[0]-csi_rs_estimated_channel16[0]);
|
noise_real[ant_rx][port_tx][rb-csirs_config_pdu->start_rb] = abs(csi_rs_ls_estimated_channel16->r-csi_rs_estimated_channel16->r);
|
||||||
noise_imag[ant_rx][port_tx][rb-csirs_config_pdu->start_rb] = abs(csi_rs_ls_estimated_channel[1]-csi_rs_estimated_channel16[1]);
|
noise_imag[ant_rx][port_tx][rb-csirs_config_pdu->start_rb] = abs(csi_rs_ls_estimated_channel16->i-csi_rs_estimated_channel16->i);
|
||||||
|
maxh = cmax3(maxh, abs(csi_rs_estimated_channel16->r), abs(csi_rs_estimated_channel16->i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(uint16_t port_tx = 0; port_tx<nr_csi_rs_info->N_ports; port_tx++) {
|
for(uint16_t port_tx = 0; port_tx<N_ports; port_tx++) {
|
||||||
*noise_power += (calc_power_csirs(noise_real[ant_rx][port_tx], csirs_config_pdu) + calc_power_csirs(noise_imag[ant_rx][port_tx],csirs_config_pdu));
|
*noise_power += (calc_power_csirs(noise_real[ant_rx][port_tx], csirs_config_pdu) + calc_power_csirs(noise_imag[ant_rx][port_tx],csirs_config_pdu));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -301,13 +428,13 @@ int nr_csi_rs_channel_estimation(PHY_VARS_NR_UE *ue,
|
|||||||
(k - frame_parms->first_carrier_offset)/NR_NB_SC_PER_RB :
|
(k - frame_parms->first_carrier_offset)/NR_NB_SC_PER_RB :
|
||||||
(k + frame_parms->ofdm_symbol_size - frame_parms->first_carrier_offset)/NR_NB_SC_PER_RB;
|
(k + frame_parms->ofdm_symbol_size - frame_parms->first_carrier_offset)/NR_NB_SC_PER_RB;
|
||||||
LOG_I(NR_PHY, "(k = %4d) |\t", k);
|
LOG_I(NR_PHY, "(k = %4d) |\t", k);
|
||||||
for(uint16_t port_tx = 0; port_tx<nr_csi_rs_info->N_ports; port_tx++) {
|
for(uint16_t port_tx = 0; port_tx<N_ports; port_tx++) {
|
||||||
int16_t *csi_rs_ls_estimated_channel = (int16_t*)&nr_csi_rs_info->csi_rs_ls_estimated_channel[ant_rx][port_tx][0];
|
c16_t *csi_rs_ls_estimated_channel16 = (c16_t*)&csi_rs_ls_estimated_channel[ant_rx][port_tx][0];
|
||||||
int16_t *csi_rs_estimated_channel16 = (int16_t *)&csi_rs_estimated_channel_freq[ant_rx][port_tx][0];
|
c16_t *csi_rs_estimated_channel16 = (c16_t *)&csi_rs_estimated_channel_freq[ant_rx][port_tx][0];
|
||||||
printf("Channel port_tx %d --> ant_rx %d : ls (%4d,%4d), int (%4d,%4d), noise (%4d,%4d) | ",
|
printf("Channel port_tx %d --> ant_rx %d : ls (%4d,%4d), int (%4d,%4d), noise (%4d,%4d) | ",
|
||||||
port_tx+3000, ant_rx,
|
port_tx+3000, ant_rx,
|
||||||
csi_rs_ls_estimated_channel[k<<1], csi_rs_ls_estimated_channel[(k<<1)+1],
|
csi_rs_ls_estimated_channel16[k].r, csi_rs_ls_estimated_channel16[k].i,
|
||||||
csi_rs_estimated_channel16[k<<1], csi_rs_estimated_channel16[(k<<1)+1],
|
csi_rs_estimated_channel16[k].r, csi_rs_estimated_channel16[k].i,
|
||||||
rb >= csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs ? 0 : noise_real[ant_rx][port_tx][rb-csirs_config_pdu->start_rb],
|
rb >= csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs ? 0 : noise_real[ant_rx][port_tx][rb-csirs_config_pdu->start_rb],
|
||||||
rb >= csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs ? 0 : noise_imag[ant_rx][port_tx][rb-csirs_config_pdu->start_rb]);
|
rb >= csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs ? 0 : noise_imag[ant_rx][port_tx][rb-csirs_config_pdu->start_rb]);
|
||||||
}
|
}
|
||||||
@@ -317,7 +444,9 @@ int nr_csi_rs_channel_estimation(PHY_VARS_NR_UE *ue,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*noise_power /= (frame_parms->nb_antennas_rx*nr_csi_rs_info->N_ports);
|
*noise_power /= (frame_parms->nb_antennas_rx*N_ports);
|
||||||
|
*log2_maxh = log2_approx(maxh-1);
|
||||||
|
*log2_re = log2_approx(count-1);
|
||||||
|
|
||||||
#ifdef NR_CSIRS_DEBUG
|
#ifdef NR_CSIRS_DEBUG
|
||||||
LOG_I(NR_PHY, "Noise power estimation based on CSI-RS: %i\n", *noise_power);
|
LOG_I(NR_PHY, "Noise power estimation based on CSI-RS: %i\n", *noise_power);
|
||||||
@@ -326,7 +455,371 @@ int nr_csi_rs_channel_estimation(PHY_VARS_NR_UE *ue,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int nr_csi_rs_ri_estimation(const PHY_VARS_NR_UE *ue,
|
||||||
|
const fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu,
|
||||||
|
const nr_csi_info_t *nr_csi_info,
|
||||||
|
const uint8_t N_ports,
|
||||||
|
int32_t csi_rs_estimated_channel_freq[][N_ports][ue->frame_parms.ofdm_symbol_size],
|
||||||
|
const int16_t log2_maxh,
|
||||||
|
uint8_t *rank_indicator) {
|
||||||
|
|
||||||
|
const NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
|
||||||
|
const int16_t cond_dB_threshold = 5;
|
||||||
|
int count = 0;
|
||||||
|
*rank_indicator = 0;
|
||||||
|
|
||||||
|
if (ue->frame_parms.nb_antennas_rx == 1 || N_ports == 1) {
|
||||||
|
return 0;
|
||||||
|
} else if( !(ue->frame_parms.nb_antennas_rx == 2 && N_ports == 2) ) {
|
||||||
|
LOG_W(NR_PHY, "Rank indicator computation is not implemented for %i x %i system\n",
|
||||||
|
ue->frame_parms.nb_antennas_rx, N_ports);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Example 2x2: Hh x H =
|
||||||
|
* | conjch00 conjch10 | x | ch00 ch01 | = | conjch00*ch00+conjch10*ch10 conjch00*ch01+conjch10*ch11 |
|
||||||
|
* | conjch01 conjch11 | | ch10 ch11 | | conjch01*ch00+conjch11*ch10 conjch01*ch01+conjch11*ch11 |
|
||||||
|
*/
|
||||||
|
|
||||||
|
int32_t csi_rs_estimated_conjch_ch[frame_parms->nb_antennas_rx][N_ports][frame_parms->nb_antennas_rx][N_ports][frame_parms->ofdm_symbol_size] __attribute__((aligned(32)));
|
||||||
|
int32_t csi_rs_estimated_A_MF[N_ports][N_ports][frame_parms->ofdm_symbol_size] __attribute__((aligned(32)));
|
||||||
|
int32_t csi_rs_estimated_A_MF_sq[N_ports][N_ports][frame_parms->ofdm_symbol_size] __attribute__((aligned(32)));
|
||||||
|
int32_t csi_rs_estimated_determ_fin[frame_parms->ofdm_symbol_size] __attribute__((aligned(32)));
|
||||||
|
int32_t csi_rs_estimated_numer_fin[frame_parms->ofdm_symbol_size] __attribute__((aligned(32)));
|
||||||
|
|
||||||
|
const uint8_t sum_shift = 1; // log2(2x2) = 2, which is a shift of 1 bit
|
||||||
|
|
||||||
|
for (int rb = csirs_config_pdu->start_rb; rb < (csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs); rb++) {
|
||||||
|
|
||||||
|
if (csirs_config_pdu->freq_density <= 1 && csirs_config_pdu->freq_density != (rb % 2)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
uint16_t k = (frame_parms->first_carrier_offset + rb*NR_NB_SC_PER_RB) % frame_parms->ofdm_symbol_size;
|
||||||
|
|
||||||
|
for (int ant_rx_conjch = 0; ant_rx_conjch < frame_parms->nb_antennas_rx; ant_rx_conjch++) {
|
||||||
|
for(uint16_t port_tx_conjch = 0; port_tx_conjch < N_ports; port_tx_conjch++) {
|
||||||
|
for (int ant_rx_ch = 0; ant_rx_ch < frame_parms->nb_antennas_rx; ant_rx_ch++) {
|
||||||
|
for(uint16_t port_tx_ch = 0; port_tx_ch < N_ports; port_tx_ch++) {
|
||||||
|
|
||||||
|
// conjch x ch computation
|
||||||
|
nr_conjch0_mult_ch1(&csi_rs_estimated_channel_freq[ant_rx_conjch][port_tx_conjch][k],
|
||||||
|
&csi_rs_estimated_channel_freq[ant_rx_ch][port_tx_ch][k],
|
||||||
|
&csi_rs_estimated_conjch_ch[ant_rx_conjch][port_tx_conjch][ant_rx_ch][port_tx_ch][k],
|
||||||
|
1,
|
||||||
|
log2_maxh);
|
||||||
|
|
||||||
|
// construct Hh x H elements
|
||||||
|
if(ant_rx_conjch == ant_rx_ch) {
|
||||||
|
nr_a_sum_b((__m128i *)&csi_rs_estimated_A_MF[port_tx_conjch][port_tx_ch][k],
|
||||||
|
(__m128i *)&csi_rs_estimated_conjch_ch[ant_rx_conjch][port_tx_conjch][ant_rx_ch][port_tx_ch][k],
|
||||||
|
1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// compute the determinant of A_MF (denominator)
|
||||||
|
nr_det_A_MF_2x2(&csi_rs_estimated_A_MF[0][0][k],
|
||||||
|
&csi_rs_estimated_A_MF[0][1][k],
|
||||||
|
&csi_rs_estimated_A_MF[1][0][k],
|
||||||
|
&csi_rs_estimated_A_MF[1][1][k],
|
||||||
|
&csi_rs_estimated_determ_fin[k],
|
||||||
|
1);
|
||||||
|
|
||||||
|
// compute the square of A_MF (numerator)
|
||||||
|
nr_squared_matrix_element(&csi_rs_estimated_A_MF[0][0][k], &csi_rs_estimated_A_MF_sq[0][0][k], 1);
|
||||||
|
nr_squared_matrix_element(&csi_rs_estimated_A_MF[0][1][k], &csi_rs_estimated_A_MF_sq[0][1][k], 1);
|
||||||
|
nr_squared_matrix_element(&csi_rs_estimated_A_MF[1][0][k], &csi_rs_estimated_A_MF_sq[1][0][k], 1);
|
||||||
|
nr_squared_matrix_element(&csi_rs_estimated_A_MF[1][1][k], &csi_rs_estimated_A_MF_sq[1][1][k], 1);
|
||||||
|
nr_numer_2x2(&csi_rs_estimated_A_MF_sq[0][0][k],
|
||||||
|
&csi_rs_estimated_A_MF_sq[0][1][k],
|
||||||
|
&csi_rs_estimated_A_MF_sq[1][0][k],
|
||||||
|
&csi_rs_estimated_A_MF_sq[1][1][k],
|
||||||
|
&csi_rs_estimated_numer_fin[k],
|
||||||
|
1);
|
||||||
|
|
||||||
|
#ifdef NR_CSIRS_DEBUG
|
||||||
|
for(uint16_t port_tx_conjch = 0; port_tx_conjch < N_ports; port_tx_conjch++) {
|
||||||
|
for(uint16_t port_tx_ch = 0; port_tx_ch < N_ports; port_tx_ch++) {
|
||||||
|
c16_t *csi_rs_estimated_A_MF_k = (c16_t *) &csi_rs_estimated_A_MF[port_tx_conjch][port_tx_ch][k];
|
||||||
|
LOG_I(NR_PHY, "(%i) csi_rs_estimated_A_MF[%i][%i] = (%i, %i)\n",
|
||||||
|
k, port_tx_conjch, port_tx_ch, csi_rs_estimated_A_MF_k->r, csi_rs_estimated_A_MF_k->i);
|
||||||
|
c16_t *csi_rs_estimated_A_MF_sq_k = (c16_t *) &csi_rs_estimated_A_MF_sq[port_tx_conjch][port_tx_ch][k];
|
||||||
|
LOG_I(NR_PHY, "(%i) csi_rs_estimated_A_MF_sq[%i][%i] = (%i, %i)\n",
|
||||||
|
k, port_tx_conjch, port_tx_ch, csi_rs_estimated_A_MF_sq_k->r, csi_rs_estimated_A_MF_sq_k->i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LOG_I(NR_PHY, "(%i) csi_rs_estimated_determ_fin = %i\n", k, csi_rs_estimated_determ_fin[k]);
|
||||||
|
LOG_I(NR_PHY, "(%i) csi_rs_estimated_numer_fin = %i\n", k, csi_rs_estimated_numer_fin[k]>>sum_shift);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// compute the conditional number
|
||||||
|
for (int sc_idx=0; sc_idx < NR_NB_SC_PER_RB; sc_idx++) {
|
||||||
|
int8_t csi_rs_estimated_denum_db = dB_fixed(csi_rs_estimated_determ_fin[k + sc_idx]);
|
||||||
|
int8_t csi_rs_estimated_numer_db = dB_fixed(csi_rs_estimated_numer_fin[k + sc_idx]>>sum_shift);
|
||||||
|
int8_t cond_db = csi_rs_estimated_numer_db - csi_rs_estimated_denum_db;
|
||||||
|
|
||||||
|
#ifdef NR_CSIRS_DEBUG
|
||||||
|
LOG_I(NR_PHY, "csi_rs_estimated_denum_db = %i\n", csi_rs_estimated_denum_db);
|
||||||
|
LOG_I(NR_PHY, "csi_rs_estimated_numer_db = %i\n", csi_rs_estimated_numer_db);
|
||||||
|
LOG_I(NR_PHY, "cond_db = %i\n", cond_db);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (cond_db < cond_dB_threshold) {
|
||||||
|
count++;
|
||||||
|
} else {
|
||||||
|
count--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// conditional number is lower than cond_dB_threshold in half on more REs
|
||||||
|
if (count > 0) {
|
||||||
|
*rank_indicator = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef NR_CSIRS_DEBUG
|
||||||
|
LOG_I(NR_PHY, "count = %i\n", count);
|
||||||
|
LOG_I(NR_PHY, "rank = %i\n", (*rank_indicator)+1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int nr_csi_rs_pmi_estimation(const PHY_VARS_NR_UE *ue,
|
||||||
|
const fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu,
|
||||||
|
const nr_csi_info_t *nr_csi_info,
|
||||||
|
const uint8_t N_ports,
|
||||||
|
const int32_t csi_rs_estimated_channel_freq[][N_ports][ue->frame_parms.ofdm_symbol_size],
|
||||||
|
const uint32_t interference_plus_noise_power,
|
||||||
|
const uint8_t rank_indicator,
|
||||||
|
const int16_t log2_re,
|
||||||
|
uint8_t *i1,
|
||||||
|
uint8_t *i2,
|
||||||
|
uint32_t *precoded_sinr_dB) {
|
||||||
|
|
||||||
|
const NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
|
||||||
|
memset(i1,0,3*sizeof(uint8_t));
|
||||||
|
i2[0] = 0;
|
||||||
|
|
||||||
|
// i1 is a three-element vector in the form of [i11 i12 i13], when CodebookType is specified as 'Type1SinglePanel'.
|
||||||
|
// Note that i13 is not applicable when the number of transmission layers is one of {1, 5, 6, 7, 8}.
|
||||||
|
// i2, for 'Type1SinglePanel' codebook type, it is a scalar when PMIMode is specified as 'wideband', and when PMIMode
|
||||||
|
// is specified as 'subband' or when PRGSize, the length of the i2 vector equals to the number of subbands or PRGs.
|
||||||
|
// Note that when the number of CSI-RS ports is 2, the applicable codebook type is 'Type1SinglePanel'. In this case,
|
||||||
|
// the precoding matrix is obtained by a single index (i2 field here) based on TS 38.214 Table 5.2.2.2.1-1.
|
||||||
|
// The first column is applicable if the UE is reporting a Rank = 1, whereas the second column is applicable if the
|
||||||
|
// UE is reporting a Rank = 2.
|
||||||
|
|
||||||
|
if(N_ports == 1 || interference_plus_noise_power == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(rank_indicator == 0 || rank_indicator == 1) {
|
||||||
|
|
||||||
|
int32_t sum_re[4] = {0};
|
||||||
|
int32_t sum_im[4] = {0};
|
||||||
|
int32_t sum2_re[4] = {0};
|
||||||
|
int32_t sum2_im[4] = {0};
|
||||||
|
int32_t tested_precoded_sinr[4] = {0};
|
||||||
|
|
||||||
|
for (int rb = csirs_config_pdu->start_rb; rb < (csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs); rb++) {
|
||||||
|
|
||||||
|
if (csirs_config_pdu->freq_density <= 1 && csirs_config_pdu->freq_density != (rb % 2)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
uint16_t k = (frame_parms->first_carrier_offset + rb * NR_NB_SC_PER_RB) % frame_parms->ofdm_symbol_size;
|
||||||
|
|
||||||
|
for (int ant_rx = 0; ant_rx < frame_parms->nb_antennas_rx; ant_rx++) {
|
||||||
|
|
||||||
|
c16_t *csi_rs_estimated_channel_p0 = (c16_t *) &csi_rs_estimated_channel_freq[ant_rx][0][k];
|
||||||
|
c16_t *csi_rs_estimated_channel_p1 = (c16_t *) &csi_rs_estimated_channel_freq[ant_rx][1][k];
|
||||||
|
|
||||||
|
// H_p0 + 1*H_p1 = (H_p0_re + H_p1_re) + 1j*(H_p0_im + H_p1_im)
|
||||||
|
sum_re[0] += (csi_rs_estimated_channel_p0->r+csi_rs_estimated_channel_p1->r);
|
||||||
|
sum_im[0] += (csi_rs_estimated_channel_p0->i+csi_rs_estimated_channel_p1->i);
|
||||||
|
sum2_re[0] += ((csi_rs_estimated_channel_p0->r+csi_rs_estimated_channel_p1->r)*(csi_rs_estimated_channel_p0->r+csi_rs_estimated_channel_p1->r))>>log2_re;
|
||||||
|
sum2_im[0] += ((csi_rs_estimated_channel_p0->i+csi_rs_estimated_channel_p1->i)*(csi_rs_estimated_channel_p0->i+csi_rs_estimated_channel_p1->i))>>log2_re;
|
||||||
|
|
||||||
|
// H_p0 + 1j*H_p1 = (H_p0_re - H_p1_im) + 1j*(H_p0_im + H_p1_re)
|
||||||
|
sum_re[1] += (csi_rs_estimated_channel_p0->r-csi_rs_estimated_channel_p1->i);
|
||||||
|
sum_im[1] += (csi_rs_estimated_channel_p0->i+csi_rs_estimated_channel_p1->r);
|
||||||
|
sum2_re[1] += ((csi_rs_estimated_channel_p0->r-csi_rs_estimated_channel_p1->i)*(csi_rs_estimated_channel_p0->r-csi_rs_estimated_channel_p1->i))>>log2_re;
|
||||||
|
sum2_im[1] += ((csi_rs_estimated_channel_p0->i+csi_rs_estimated_channel_p1->r)*(csi_rs_estimated_channel_p0->i+csi_rs_estimated_channel_p1->r))>>log2_re;
|
||||||
|
|
||||||
|
// H_p0 - 1*H_p1 = (H_p0_re - H_p1_re) + 1j*(H_p0_im - H_p1_im)
|
||||||
|
sum_re[2] += (csi_rs_estimated_channel_p0->r-csi_rs_estimated_channel_p1->r);
|
||||||
|
sum_im[2] += (csi_rs_estimated_channel_p0->i-csi_rs_estimated_channel_p1->i);
|
||||||
|
sum2_re[2] += ((csi_rs_estimated_channel_p0->r-csi_rs_estimated_channel_p1->r)*(csi_rs_estimated_channel_p0->r-csi_rs_estimated_channel_p1->r))>>log2_re;
|
||||||
|
sum2_im[2] += ((csi_rs_estimated_channel_p0->i-csi_rs_estimated_channel_p1->i)*(csi_rs_estimated_channel_p0->i-csi_rs_estimated_channel_p1->i))>>log2_re;
|
||||||
|
|
||||||
|
// H_p0 - 1j*H_p1 = (H_p0_re + H_p1_im) + 1j*(H_p0_im - H_p1_re)
|
||||||
|
sum_re[3] += (csi_rs_estimated_channel_p0->r+csi_rs_estimated_channel_p1->i);
|
||||||
|
sum_im[3] += (csi_rs_estimated_channel_p0->i-csi_rs_estimated_channel_p1->r);
|
||||||
|
sum2_re[3] += ((csi_rs_estimated_channel_p0->r+csi_rs_estimated_channel_p1->i)*(csi_rs_estimated_channel_p0->r+csi_rs_estimated_channel_p1->i))>>log2_re;
|
||||||
|
sum2_im[3] += ((csi_rs_estimated_channel_p0->i-csi_rs_estimated_channel_p1->r)*(csi_rs_estimated_channel_p0->i-csi_rs_estimated_channel_p1->r))>>log2_re;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We should perform >>nr_csi_info->log2_re here for all terms, but since sum2_re and sum2_im can be high values,
|
||||||
|
// we performed this above.
|
||||||
|
for(int p = 0; p<4; p++) {
|
||||||
|
int32_t power_re = sum2_re[p] - (sum_re[p]>>log2_re)*(sum_re[p]>>log2_re);
|
||||||
|
int32_t power_im = sum2_im[p] - (sum_im[p]>>log2_re)*(sum_im[p]>>log2_re);
|
||||||
|
tested_precoded_sinr[p] = (power_re+power_im)/(int32_t)interference_plus_noise_power;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(rank_indicator == 0) {
|
||||||
|
for(int tested_i2 = 0; tested_i2 < 4; tested_i2++) {
|
||||||
|
if(tested_precoded_sinr[tested_i2] > tested_precoded_sinr[i2[0]]) {
|
||||||
|
i2[0] = tested_i2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*precoded_sinr_dB = dB_fixed(tested_precoded_sinr[i2[0]]);
|
||||||
|
} else {
|
||||||
|
i2[0] = tested_precoded_sinr[0]+tested_precoded_sinr[2] > tested_precoded_sinr[1]+tested_precoded_sinr[3] ? 0 : 1;
|
||||||
|
*precoded_sinr_dB = dB_fixed((tested_precoded_sinr[i2[0]] + tested_precoded_sinr[i2[0]+2])>>1);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
LOG_W(NR_PHY, "PMI computation is not implemented for rank indicator %i\n", rank_indicator+1);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int nr_csi_rs_cqi_estimation(const uint32_t precoded_sinr,
|
||||||
|
uint8_t *cqi) {
|
||||||
|
|
||||||
|
*cqi = 0;
|
||||||
|
|
||||||
|
// Default SINR table for an AWGN channel for SISO scenario, considering 0.1 BLER condition and TS 38.214 Table 5.2.2.1-2
|
||||||
|
if(precoded_sinr>0 && precoded_sinr<=2) {
|
||||||
|
*cqi = 4;
|
||||||
|
} else if(precoded_sinr==3) {
|
||||||
|
*cqi = 5;
|
||||||
|
} else if(precoded_sinr>3 && precoded_sinr<=5) {
|
||||||
|
*cqi = 6;
|
||||||
|
} else if(precoded_sinr>5 && precoded_sinr<=7) {
|
||||||
|
*cqi = 7;
|
||||||
|
} else if(precoded_sinr>7 && precoded_sinr<=9) {
|
||||||
|
*cqi = 8;
|
||||||
|
} else if(precoded_sinr==10) {
|
||||||
|
*cqi = 9;
|
||||||
|
} else if(precoded_sinr>10 && precoded_sinr<=12) {
|
||||||
|
*cqi = 10;
|
||||||
|
} else if(precoded_sinr>12 && precoded_sinr<=15) {
|
||||||
|
*cqi = 11;
|
||||||
|
} else if(precoded_sinr==16) {
|
||||||
|
*cqi = 12;
|
||||||
|
} else if(precoded_sinr>16 && precoded_sinr<=18) {
|
||||||
|
*cqi = 13;
|
||||||
|
} else if(precoded_sinr==19) {
|
||||||
|
*cqi = 14;
|
||||||
|
} else if(precoded_sinr>19) {
|
||||||
|
*cqi = 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int nr_csi_im_power_estimation(const PHY_VARS_NR_UE *ue,
|
||||||
|
const UE_nr_rxtx_proc_t *proc,
|
||||||
|
const fapi_nr_dl_config_csiim_pdu_rel15_t *csiim_config_pdu,
|
||||||
|
uint32_t *interference_plus_noise_power) {
|
||||||
|
|
||||||
|
int32_t **rxdataF = ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF;
|
||||||
|
const NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
|
||||||
|
|
||||||
|
const uint16_t end_rb = csiim_config_pdu->start_rb + csiim_config_pdu->nr_of_rbs > csiim_config_pdu->bwp_size ?
|
||||||
|
csiim_config_pdu->bwp_size : csiim_config_pdu->start_rb + csiim_config_pdu->nr_of_rbs;
|
||||||
|
|
||||||
|
int32_t count = 0;
|
||||||
|
int32_t sum_re = 0;
|
||||||
|
int32_t sum_im = 0;
|
||||||
|
int32_t sum2_re = 0;
|
||||||
|
int32_t sum2_im = 0;
|
||||||
|
|
||||||
|
int l_csiim[4] = {-1, -1, -1, -1};
|
||||||
|
|
||||||
|
for(int symb_idx = 0; symb_idx < 4; symb_idx++) {
|
||||||
|
|
||||||
|
uint8_t symb = csiim_config_pdu->l_csiim[symb_idx];
|
||||||
|
bool done = false;
|
||||||
|
for (int symb_idx2 = 0; symb_idx2 < symb_idx; symb_idx2++) {
|
||||||
|
if (l_csiim[symb_idx2] == symb) {
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (done) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
l_csiim[symb_idx] = symb;
|
||||||
|
uint64_t symbol_offset = symb*frame_parms->ofdm_symbol_size;
|
||||||
|
|
||||||
|
for (int ant_rx = 0; ant_rx < frame_parms->nb_antennas_rx; ant_rx++) {
|
||||||
|
|
||||||
|
c16_t *rx_signal = (c16_t*)&rxdataF[ant_rx][symbol_offset];
|
||||||
|
|
||||||
|
for (int rb = csiim_config_pdu->start_rb; rb < end_rb; rb++) {
|
||||||
|
|
||||||
|
uint16_t sc0_offset = (frame_parms->first_carrier_offset + rb*NR_NB_SC_PER_RB) % frame_parms->ofdm_symbol_size;
|
||||||
|
|
||||||
|
for (int sc_idx = 0; sc_idx<4; sc_idx++) {
|
||||||
|
|
||||||
|
uint16_t sc = sc0_offset + csiim_config_pdu->k_csiim[sc_idx];
|
||||||
|
|
||||||
|
#ifdef NR_CSIIM_DEBUG
|
||||||
|
LOG_I(NR_PHY, "(ant_rx %i, sc %i) real %i, imag %i\n", ant_rx, rb, rx_signal[sc].r, rx_signal[sc].i);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
sum_re += rx_signal[sc].r;
|
||||||
|
sum_im += rx_signal[sc].i;
|
||||||
|
sum2_re += rx_signal[sc].r*rx_signal[sc].r;
|
||||||
|
sum2_im += rx_signal[sc].i*rx_signal[sc].i;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t power_re = sum2_re/count - (sum_re/count)*(sum_re/count);
|
||||||
|
int32_t power_im = sum2_im/count - (sum_im/count)*(sum_im/count);
|
||||||
|
|
||||||
|
*interference_plus_noise_power = power_re + power_im;
|
||||||
|
|
||||||
|
#ifdef NR_CSIIM_DEBUG
|
||||||
|
LOG_I(NR_PHY, "interference_plus_noise_power based on CSI-IM = %i\n", *interference_plus_noise_power);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int nr_ue_csi_im_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id) {
|
int nr_ue_csi_im_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id) {
|
||||||
|
|
||||||
|
if(!ue->csiim_vars[gNB_id]->active) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const fapi_nr_dl_config_csiim_pdu_rel15_t *csiim_config_pdu = (fapi_nr_dl_config_csiim_pdu_rel15_t*)&ue->csiim_vars[gNB_id]->csiim_config_pdu;
|
||||||
|
|
||||||
|
#ifdef NR_CSIIM_DEBUG
|
||||||
|
LOG_I(NR_PHY, "csiim_config_pdu->bwp_size = %i\n", csiim_config_pdu->bwp_size);
|
||||||
|
LOG_I(NR_PHY, "csiim_config_pdu->bwp_start = %i\n", csiim_config_pdu->bwp_start);
|
||||||
|
LOG_I(NR_PHY, "csiim_config_pdu->subcarrier_spacing = %i\n", csiim_config_pdu->subcarrier_spacing);
|
||||||
|
LOG_I(NR_PHY, "csiim_config_pdu->start_rb = %i\n", csiim_config_pdu->start_rb);
|
||||||
|
LOG_I(NR_PHY, "csiim_config_pdu->nr_of_rbs = %i\n", csiim_config_pdu->nr_of_rbs);
|
||||||
|
LOG_I(NR_PHY, "csiim_config_pdu->k_csiim = %i.%i.%i.%i\n", csiim_config_pdu->k_csiim[0], csiim_config_pdu->k_csiim[1], csiim_config_pdu->k_csiim[2], csiim_config_pdu->k_csiim[3]);
|
||||||
|
LOG_I(NR_PHY, "csiim_config_pdu->l_csiim = %i.%i.%i.%i\n", csiim_config_pdu->l_csiim[0], csiim_config_pdu->l_csiim[1], csiim_config_pdu->l_csiim[2], csiim_config_pdu->l_csiim[3]);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
nr_csi_im_power_estimation(ue, proc, csiim_config_pdu, &ue->nr_csi_info->interference_plus_noise_power);
|
||||||
|
ue->nr_csi_info->csi_im_meas_computed = true;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -336,7 +829,7 @@ int nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu = (fapi_nr_dl_config_csirs_pdu_rel15_t*)&ue->csirs_vars[gNB_id]->csirs_config_pdu;
|
const fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu = (fapi_nr_dl_config_csirs_pdu_rel15_t*)&ue->csirs_vars[gNB_id]->csirs_config_pdu;
|
||||||
|
|
||||||
#ifdef NR_CSIRS_DEBUG
|
#ifdef NR_CSIRS_DEBUG
|
||||||
LOG_I(NR_PHY, "csirs_config_pdu->subcarrier_spacing = %i\n", csirs_config_pdu->subcarrier_spacing);
|
LOG_I(NR_PHY, "csirs_config_pdu->subcarrier_spacing = %i\n", csirs_config_pdu->subcarrier_spacing);
|
||||||
@@ -355,26 +848,122 @@ int nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t
|
|||||||
LOG_I(NR_PHY, "csirs_config_pdu->power_control_offset_ss = %i\n", csirs_config_pdu->power_control_offset_ss);
|
LOG_I(NR_PHY, "csirs_config_pdu->power_control_offset_ss = %i\n", csirs_config_pdu->power_control_offset_ss);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
nr_generate_csi_rs(ue->frame_parms,
|
const NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
|
||||||
ue->nr_csi_rs_info->csi_rs_generated_signal,
|
int32_t csi_rs_received_signal[frame_parms->nb_antennas_rx][frame_parms->samples_per_slot_wCP];
|
||||||
|
uint8_t N_cdm_groups = 0;
|
||||||
|
uint8_t CDM_group_size = 0;
|
||||||
|
uint8_t k_prime = 0;
|
||||||
|
uint8_t l_prime = 0;
|
||||||
|
uint8_t N_ports = 0;
|
||||||
|
uint8_t j_cdm[16];
|
||||||
|
uint8_t k_overline[16];
|
||||||
|
uint8_t l_overline[16];
|
||||||
|
int16_t log2_re = 0;
|
||||||
|
int16_t log2_maxh = 0;
|
||||||
|
uint32_t rsrp = 0;
|
||||||
|
int rsrp_dBm = 0;
|
||||||
|
uint32_t noise_power = 0;
|
||||||
|
uint8_t rank_indicator = 0;
|
||||||
|
uint32_t precoded_sinr_dB = 0;
|
||||||
|
uint8_t cqi = 0;
|
||||||
|
uint8_t i1[3];
|
||||||
|
uint8_t i2[1];
|
||||||
|
|
||||||
|
nr_generate_csi_rs(frame_parms,
|
||||||
|
ue->nr_csi_info->csi_rs_generated_signal,
|
||||||
AMP,
|
AMP,
|
||||||
ue->nr_csi_rs_info,
|
ue->nr_csi_info,
|
||||||
(nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *) csirs_config_pdu,
|
(nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *) csirs_config_pdu,
|
||||||
proc->nr_slot_rx);
|
proc->nr_slot_rx,
|
||||||
|
&N_cdm_groups,
|
||||||
|
&CDM_group_size,
|
||||||
|
&k_prime,
|
||||||
|
&l_prime,
|
||||||
|
&N_ports,
|
||||||
|
j_cdm,
|
||||||
|
k_overline,
|
||||||
|
l_overline);
|
||||||
|
|
||||||
|
int32_t csi_rs_ls_estimated_channel[frame_parms->nb_antennas_rx][N_ports][frame_parms->ofdm_symbol_size];
|
||||||
|
int32_t csi_rs_estimated_channel_freq[frame_parms->nb_antennas_rx][N_ports][frame_parms->ofdm_symbol_size];
|
||||||
|
|
||||||
nr_get_csi_rs_signal(ue,
|
nr_get_csi_rs_signal(ue,
|
||||||
proc,
|
proc,
|
||||||
csirs_config_pdu,
|
csirs_config_pdu,
|
||||||
ue->nr_csi_rs_info,
|
ue->nr_csi_info,
|
||||||
ue->nr_csi_rs_info->csi_rs_received_signal);
|
N_cdm_groups,
|
||||||
|
CDM_group_size,
|
||||||
|
k_prime,
|
||||||
|
l_prime,
|
||||||
|
j_cdm,
|
||||||
|
k_overline,
|
||||||
|
l_overline,
|
||||||
|
csi_rs_received_signal,
|
||||||
|
&rsrp,
|
||||||
|
&rsrp_dBm);
|
||||||
|
|
||||||
nr_csi_rs_channel_estimation(ue,
|
nr_csi_rs_channel_estimation(ue,
|
||||||
proc,
|
proc,
|
||||||
csirs_config_pdu,
|
csirs_config_pdu,
|
||||||
ue->nr_csi_rs_info,
|
ue->nr_csi_info,
|
||||||
ue->nr_csi_rs_info->csi_rs_generated_signal,
|
(const int32_t **) ue->nr_csi_info->csi_rs_generated_signal,
|
||||||
ue->nr_csi_rs_info->csi_rs_received_signal,
|
csi_rs_received_signal,
|
||||||
ue->nr_csi_rs_info->csi_rs_estimated_channel_freq,
|
N_cdm_groups,
|
||||||
ue->nr_csi_rs_info->noise_power);
|
CDM_group_size,
|
||||||
|
k_prime,
|
||||||
|
l_prime,
|
||||||
|
N_ports,
|
||||||
|
j_cdm,
|
||||||
|
k_overline,
|
||||||
|
l_overline,
|
||||||
|
csi_rs_ls_estimated_channel,
|
||||||
|
csi_rs_estimated_channel_freq,
|
||||||
|
&log2_re,
|
||||||
|
&log2_maxh,
|
||||||
|
&noise_power);
|
||||||
|
|
||||||
|
nr_csi_rs_ri_estimation(ue,
|
||||||
|
csirs_config_pdu,
|
||||||
|
ue->nr_csi_info,
|
||||||
|
N_ports,
|
||||||
|
csi_rs_estimated_channel_freq,
|
||||||
|
log2_maxh,
|
||||||
|
&rank_indicator);
|
||||||
|
|
||||||
|
nr_csi_rs_pmi_estimation(ue,
|
||||||
|
csirs_config_pdu,
|
||||||
|
ue->nr_csi_info,
|
||||||
|
N_ports,
|
||||||
|
csi_rs_estimated_channel_freq,
|
||||||
|
ue->nr_csi_info->csi_im_meas_computed ? ue->nr_csi_info->interference_plus_noise_power : noise_power,
|
||||||
|
rank_indicator,
|
||||||
|
log2_re,
|
||||||
|
i1,
|
||||||
|
i2,
|
||||||
|
&precoded_sinr_dB);
|
||||||
|
|
||||||
|
nr_csi_rs_cqi_estimation(precoded_sinr_dB, &cqi);
|
||||||
|
|
||||||
|
LOG_I(NR_PHY, "RSRP = %i dBm, RI = %i, i1 = %i.%i.%i, i2 = %i, SINR = %i dB, CQI = %i\n",
|
||||||
|
rsrp_dBm, rank_indicator+1, i1[0], i1[1], i1[2], i2[0], precoded_sinr_dB, cqi);
|
||||||
|
|
||||||
|
// Send CSI measurements to MAC
|
||||||
|
fapi_nr_csirs_measurements_t csirs_measurements;
|
||||||
|
csirs_measurements.rsrp = rsrp;
|
||||||
|
csirs_measurements.rsrp_dBm = rsrp_dBm;
|
||||||
|
csirs_measurements.rank_indicator = rank_indicator;
|
||||||
|
csirs_measurements.i1 = *i1;
|
||||||
|
csirs_measurements.i2 = *i2;
|
||||||
|
csirs_measurements.cqi = cqi;
|
||||||
|
nr_downlink_indication_t dl_indication;
|
||||||
|
fapi_nr_rx_indication_t *rx_ind = calloc(sizeof(*rx_ind),1);
|
||||||
|
nr_fill_dl_indication(&dl_indication, NULL, rx_ind, proc, ue, gNB_id, NULL);
|
||||||
|
nr_fill_rx_indication(rx_ind, FAPI_NR_CSIRS_IND, gNB_id, ue, NULL, NULL, 1, proc, (void *)&csirs_measurements);
|
||||||
|
if (ue->if_inst && ue->if_inst->dl_indication) {
|
||||||
|
ue->if_inst->dl_indication(&dl_indication, NULL);
|
||||||
|
} else {
|
||||||
|
free(rx_ind);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -140,7 +140,6 @@ NR_UE_DLSCH_t *new_nr_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint
|
|||||||
dlsch->Mdlharq = Mdlharq;
|
dlsch->Mdlharq = Mdlharq;
|
||||||
dlsch->number_harq_processes_for_pdsch = Mdlharq;
|
dlsch->number_harq_processes_for_pdsch = Mdlharq;
|
||||||
dlsch->Nsoft = Nsoft;
|
dlsch->Nsoft = Nsoft;
|
||||||
dlsch->Mlimit = 4;
|
|
||||||
dlsch->max_ldpc_iterations = max_ldpc_iterations;
|
dlsch->max_ldpc_iterations = max_ldpc_iterations;
|
||||||
|
|
||||||
for (int i=0; i<Mdlharq; i++) {
|
for (int i=0; i<Mdlharq; i++) {
|
||||||
@@ -222,7 +221,6 @@ bool nr_ue_postDecode(PHY_VARS_NR_UE *phy_vars_ue, notifiedFIFO_elt_t *req, bool
|
|||||||
//LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for nr_slot_rx %d TBS %d mcs %d nb_rb %d harq_process->round %d\n",
|
//LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for nr_slot_rx %d TBS %d mcs %d nb_rb %d harq_process->round %d\n",
|
||||||
// phy_vars_ue->Mod_id,nr_slot_rx,harq_process->TBS,harq_process->mcs,harq_process->nb_rb, harq_process->round);
|
// phy_vars_ue->Mod_id,nr_slot_rx,harq_process->TBS,harq_process->mcs,harq_process->nb_rb, harq_process->round);
|
||||||
harq_process->status = SCH_IDLE;
|
harq_process->status = SCH_IDLE;
|
||||||
harq_process->DLround = 0;
|
|
||||||
harq_process->ack = 1;
|
harq_process->ack = 1;
|
||||||
|
|
||||||
//LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d)\n",
|
//LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d)\n",
|
||||||
@@ -237,11 +235,6 @@ bool nr_ue_postDecode(PHY_VARS_NR_UE *phy_vars_ue, notifiedFIFO_elt_t *req, bool
|
|||||||
//LOG_D(PHY,"[UE %d] DLSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d) Kr %d r %d harq_process->round %d\n",
|
//LOG_D(PHY,"[UE %d] DLSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d) Kr %d r %d harq_process->round %d\n",
|
||||||
// phy_vars_ue->Mod_id, frame, nr_slot_rx, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round);
|
// phy_vars_ue->Mod_id, frame, nr_slot_rx, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round);
|
||||||
harq_process->ack = 0;
|
harq_process->ack = 0;
|
||||||
if (harq_process->DLround >= dlsch->Mlimit) {
|
|
||||||
harq_process->status = SCH_IDLE;
|
|
||||||
harq_process->DLround = 0;
|
|
||||||
phy_vars_ue->dl_stats[4]++;
|
|
||||||
}
|
|
||||||
|
|
||||||
//if(is_crnti) {
|
//if(is_crnti) {
|
||||||
// LOG_D(PHY,"[UE %d] DLSCH: Setting NACK for nr_slot_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n",
|
// LOG_D(PHY,"[UE %d] DLSCH: Setting NACK for nr_slot_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n",
|
||||||
@@ -496,8 +489,6 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
nb_rb = harq_process->nb_rb;
|
nb_rb = harq_process->nb_rb;
|
||||||
harq_process->trials[harq_process->DLround]++;
|
|
||||||
|
|
||||||
A = harq_process->TBS;
|
A = harq_process->TBS;
|
||||||
ret = dlsch->max_ldpc_iterations + 1;
|
ret = dlsch->max_ldpc_iterations + 1;
|
||||||
dlsch->last_iteration_cnt = ret;
|
dlsch->last_iteration_cnt = ret;
|
||||||
|
|||||||
@@ -466,88 +466,87 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
|
|||||||
if (cpumeas(CPUMEAS_GETSTATE))
|
if (cpumeas(CPUMEAS_GETSTATE))
|
||||||
LOG_D(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: Channel Combine and zero forcing %5.2f \n",frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0));
|
LOG_D(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: Channel Combine and zero forcing %5.2f \n",frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0));
|
||||||
|
|
||||||
start_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
|
start_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
|
||||||
/* Store the valid DL RE's */
|
/* Store the valid DL RE's */
|
||||||
pdsch_vars[gNB_id]->dl_valid_re[symbol-1] = nb_re_pdsch;
|
pdsch_vars[gNB_id]->dl_valid_re[symbol-1] = nb_re_pdsch;
|
||||||
|
|
||||||
if(dlsch0_harq->status == ACTIVE) {
|
if(dlsch0_harq->status == ACTIVE) {
|
||||||
startSymbIdx = dlsch0_harq->start_symbol;
|
startSymbIdx = dlsch0_harq->start_symbol;
|
||||||
nbSymb = dlsch0_harq->nb_symbols;
|
nbSymb = dlsch0_harq->nb_symbols;
|
||||||
pduBitmap = dlsch0_harq->pduBitmap;
|
pduBitmap = dlsch0_harq->pduBitmap;
|
||||||
}
|
}
|
||||||
if(dlsch1_harq) {
|
if(dlsch1_harq) {
|
||||||
startSymbIdx = dlsch1_harq->start_symbol;
|
startSymbIdx = dlsch1_harq->start_symbol;
|
||||||
nbSymb = dlsch1_harq->nb_symbols;
|
nbSymb = dlsch1_harq->nb_symbols;
|
||||||
pduBitmap = dlsch1_harq->pduBitmap;
|
pduBitmap = dlsch1_harq->pduBitmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for PTRS bitmap and process it respectively */
|
/* Check for PTRS bitmap and process it respectively */
|
||||||
if((pduBitmap & 0x1) && (type == PDSCH)) {
|
if((pduBitmap & 0x1) && (type == PDSCH)) {
|
||||||
nr_pdsch_ptrs_processing(ue,
|
nr_pdsch_ptrs_processing(ue,
|
||||||
pdsch_vars,
|
pdsch_vars,
|
||||||
frame_parms,
|
frame_parms,
|
||||||
dlsch0_harq,
|
dlsch0_harq,
|
||||||
dlsch1_harq,
|
dlsch1_harq,
|
||||||
gNB_id,
|
gNB_id,
|
||||||
nr_slot_rx,
|
nr_slot_rx,
|
||||||
symbol,
|
symbol,
|
||||||
(nb_rb_pdsch*12),
|
(nb_rb_pdsch*12),
|
||||||
dlsch[0]->rnti,rx_type);
|
dlsch[0]->rnti,rx_type);
|
||||||
pdsch_vars[gNB_id]->dl_valid_re[symbol-1] -= pdsch_vars[gNB_id]->ptrs_re_per_slot[0][symbol];
|
pdsch_vars[gNB_id]->dl_valid_re[symbol-1] -= pdsch_vars[gNB_id]->ptrs_re_per_slot[0][symbol];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* at last symbol in a slot calculate LLR's for whole slot */
|
/* at last symbol in a slot calculate LLR's for whole slot */
|
||||||
if(symbol == (startSymbIdx + nbSymb -1)) {
|
if(symbol == (startSymbIdx + nbSymb -1)) {
|
||||||
for(uint8_t i =startSymbIdx; i < (startSymbIdx+nbSymb);i++) {
|
for(uint8_t i =startSymbIdx; i < (startSymbIdx+nbSymb);i++) {
|
||||||
/* re evaluating the first symbol flag as LLR's are done in symbol loop */
|
/* re evaluating the first symbol flag as LLR's are done in symbol loop */
|
||||||
if(i == startSymbIdx && i < 3) {
|
if(i == startSymbIdx && i < 3) {
|
||||||
first_symbol_flag =1;
|
first_symbol_flag =1;
|
||||||
}
|
|
||||||
else {
|
|
||||||
first_symbol_flag=0;
|
|
||||||
}
|
|
||||||
/* Calculate LLR's for each symbol */
|
|
||||||
nr_dlsch_llr(pdsch_vars, frame_parms,
|
|
||||||
rxdataF_comp_ptr, dl_ch_mag_ptr,
|
|
||||||
dlsch0_harq, dlsch1_harq,
|
|
||||||
rx_type, harq_pid,
|
|
||||||
gNB_id, gNB_id_i,
|
|
||||||
first_symbol_flag,
|
|
||||||
i, nb_rb_pdsch,
|
|
||||||
codeword_TB0, codeword_TB1,
|
|
||||||
pdsch_vars[gNB_id]->dl_valid_re[i-1],
|
|
||||||
nr_slot_rx, beamforming_mode);
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
int dmrs_type = dlsch[0]->harq_processes[harq_pid]->dmrsConfigType;
|
first_symbol_flag=0;
|
||||||
uint8_t nb_re_dmrs;
|
|
||||||
uint16_t dmrs_len = get_num_dmrs(dlsch[0]->harq_processes[harq_pid]->dlDmrsSymbPos);
|
|
||||||
if (dmrs_type==NFAPI_NR_DMRS_TYPE1) {
|
|
||||||
nb_re_dmrs = 6*dlsch[0]->harq_processes[harq_pid]->n_dmrs_cdm_groups;
|
|
||||||
} else {
|
|
||||||
nb_re_dmrs = 4*dlsch[0]->harq_processes[harq_pid]->n_dmrs_cdm_groups;
|
|
||||||
}
|
}
|
||||||
dlsch[0]->harq_processes[harq_pid]->G = nr_get_G(dlsch[0]->harq_processes[harq_pid]->nb_rb,
|
/* Calculate LLR's for each symbol */
|
||||||
dlsch[0]->harq_processes[harq_pid]->nb_symbols,
|
nr_dlsch_llr(pdsch_vars, frame_parms,
|
||||||
nb_re_dmrs,
|
rxdataF_comp_ptr, dl_ch_mag_ptr,
|
||||||
dmrs_len,
|
dlsch0_harq, dlsch1_harq,
|
||||||
dlsch[0]->harq_processes[harq_pid]->Qm,
|
rx_type, harq_pid,
|
||||||
dlsch[0]->harq_processes[harq_pid]->Nl);
|
gNB_id, gNB_id_i,
|
||||||
nr_dlsch_layer_demapping(pdsch_vars[gNB_id]->llr,
|
first_symbol_flag,
|
||||||
dlsch[0]->harq_processes[harq_pid]->Nl,
|
i, nb_rb_pdsch,
|
||||||
dlsch[0]->harq_processes[harq_pid]->Qm,
|
codeword_TB0, codeword_TB1,
|
||||||
dlsch[0]->harq_processes[harq_pid]->G,
|
pdsch_vars[gNB_id]->dl_valid_re[i-1],
|
||||||
codeword_TB0,
|
nr_slot_rx, beamforming_mode);
|
||||||
codeword_TB1,
|
|
||||||
pdsch_vars[gNB_id]->layer_llr);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
|
int dmrs_type = dlsch[0]->harq_processes[harq_pid]->dmrsConfigType;
|
||||||
if (cpumeas(CPUMEAS_GETSTATE))
|
uint8_t nb_re_dmrs;
|
||||||
LOG_D(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: LLR Computation %5.2f \n",frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0));
|
uint16_t dmrs_len = get_num_dmrs(dlsch[0]->harq_processes[harq_pid]->dlDmrsSymbPos);
|
||||||
|
if (dmrs_type==NFAPI_NR_DMRS_TYPE1) {
|
||||||
|
nb_re_dmrs = 6*dlsch[0]->harq_processes[harq_pid]->n_dmrs_cdm_groups;
|
||||||
|
} else {
|
||||||
|
nb_re_dmrs = 4*dlsch[0]->harq_processes[harq_pid]->n_dmrs_cdm_groups;
|
||||||
|
}
|
||||||
|
dlsch[0]->harq_processes[harq_pid]->G = nr_get_G(dlsch[0]->harq_processes[harq_pid]->nb_rb,
|
||||||
|
dlsch[0]->harq_processes[harq_pid]->nb_symbols,
|
||||||
|
nb_re_dmrs,
|
||||||
|
dmrs_len,
|
||||||
|
dlsch[0]->harq_processes[harq_pid]->Qm,
|
||||||
|
dlsch[0]->harq_processes[harq_pid]->Nl);
|
||||||
|
nr_dlsch_layer_demapping(pdsch_vars[gNB_id]->llr,
|
||||||
|
dlsch[0]->harq_processes[harq_pid]->Nl,
|
||||||
|
dlsch[0]->harq_processes[harq_pid]->Qm,
|
||||||
|
dlsch[0]->harq_processes[harq_pid]->G,
|
||||||
|
codeword_TB0,
|
||||||
|
codeword_TB1,
|
||||||
|
pdsch_vars[gNB_id]->layer_llr);
|
||||||
|
}
|
||||||
|
|
||||||
// Please keep it: useful for debugging
|
stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
|
||||||
|
if (cpumeas(CPUMEAS_GETSTATE))
|
||||||
|
LOG_D(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: LLR Computation %5.2f \n",frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0));
|
||||||
|
|
||||||
|
// Please keep it: useful for debugging
|
||||||
#ifdef DEBUG_PDSCH_RX
|
#ifdef DEBUG_PDSCH_RX
|
||||||
char filename[50];
|
char filename[50];
|
||||||
uint8_t aa = 0;
|
uint8_t aa = 0;
|
||||||
|
|||||||
@@ -362,7 +362,7 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
|
|||||||
nr_gold_pdsch(ue, i, ue->scramblingID_dlsch[i]);
|
nr_gold_pdsch(ue, i, ue->scramblingID_dlsch[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
nr_init_csi_rs(fp, ue->nr_csi_rs_info->nr_gold_csi_rs, fp->Nid_cell);
|
nr_init_csi_rs(fp, ue->nr_csi_info->nr_gold_csi_rs, fp->Nid_cell);
|
||||||
|
|
||||||
// initialize the pusch dmrs
|
// initialize the pusch dmrs
|
||||||
for (int i=0; i<NR_NB_NSCID; i++) {
|
for (int i=0; i<NR_NB_NSCID; i++) {
|
||||||
|
|||||||
@@ -855,10 +855,6 @@ void construct_HhH_elements(int *ch0conj_ch0,
|
|||||||
int32_t *after_mf_11,
|
int32_t *after_mf_11,
|
||||||
unsigned short nb_rb);
|
unsigned short nb_rb);
|
||||||
|
|
||||||
void squared_matrix_element(int32_t *Hh_h_00,
|
|
||||||
int32_t *Hh_h_00_sq,
|
|
||||||
unsigned short nb_rb);
|
|
||||||
|
|
||||||
void dlsch_channel_level_TM34_meas(int *ch00,
|
void dlsch_channel_level_TM34_meas(int *ch00,
|
||||||
int *ch01,
|
int *ch01,
|
||||||
int *ch10,
|
int *ch10,
|
||||||
@@ -885,19 +881,15 @@ void nr_dlsch_detection_mrc(int **rxdataF_comp,
|
|||||||
unsigned short nb_rb,
|
unsigned short nb_rb,
|
||||||
int length);
|
int length);
|
||||||
|
|
||||||
void det_HhH(int32_t *after_mf_00,
|
void nr_conjch0_mult_ch1(int *ch0,
|
||||||
int32_t *after_mf_01,
|
int *ch1,
|
||||||
int32_t *after_mf_10,
|
int32_t *ch0conj_ch1,
|
||||||
int32_t *after_mf_11,
|
unsigned short nb_rb,
|
||||||
int32_t *det_fin_128,
|
unsigned char output_shift0);
|
||||||
unsigned short nb_rb);
|
|
||||||
|
|
||||||
void numer(int32_t *Hh_h_00_sq,
|
void nr_a_sum_b(__m128i *input_x,
|
||||||
int32_t *Hh_h_01_sq,
|
__m128i *input_y,
|
||||||
int32_t *Hh_h_10_sq,
|
unsigned short nb_rb);
|
||||||
int32_t *Hh_h_11_sq,
|
|
||||||
int32_t *num_fin,
|
|
||||||
unsigned short nb_rb);
|
|
||||||
|
|
||||||
uint8_t rank_estimation_tm3_tm4(int *dl_ch_estimates_00,
|
uint8_t rank_estimation_tm3_tm4(int *dl_ch_estimates_00,
|
||||||
int *dl_ch_estimates_01,
|
int *dl_ch_estimates_01,
|
||||||
|
|||||||
@@ -161,15 +161,13 @@ typedef struct {
|
|||||||
//uint8_t num_cba_dci[10];
|
//uint8_t num_cba_dci[10];
|
||||||
/// allocated CBA RNTI
|
/// allocated CBA RNTI
|
||||||
//uint16_t cba_rnti[4];//NUM_MAX_CBA_GROUP];
|
//uint16_t cba_rnti[4];//NUM_MAX_CBA_GROUP];
|
||||||
/// UL max-harq-retransmission
|
|
||||||
uint16_t Mlimit;
|
|
||||||
} NR_UE_ULSCH_t;
|
} NR_UE_ULSCH_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/// Indicator of first reception
|
/// Indicator of first reception
|
||||||
uint8_t first_rx;
|
uint8_t first_rx;
|
||||||
/// Last Ndi received for this process on DCI (used for C-RNTI only)
|
/// Last Ndi received for this process on DCI (used for C-RNTI only)
|
||||||
uint8_t DCINdi;
|
uint8_t Ndi;
|
||||||
/// DLSCH status flag indicating
|
/// DLSCH status flag indicating
|
||||||
SCH_status_t status;
|
SCH_status_t status;
|
||||||
/// Transport block size
|
/// Transport block size
|
||||||
@@ -241,10 +239,6 @@ typedef struct {
|
|||||||
vrb_t vrb_type;
|
vrb_t vrb_type;
|
||||||
/// downlink power offset field
|
/// downlink power offset field
|
||||||
uint8_t dl_power_off;
|
uint8_t dl_power_off;
|
||||||
/// trials per round statistics
|
|
||||||
uint32_t trials[8];
|
|
||||||
/// error statistics per round
|
|
||||||
uint32_t errors[8];
|
|
||||||
/// codeword this transport block is mapped to
|
/// codeword this transport block is mapped to
|
||||||
uint8_t codeword;
|
uint8_t codeword;
|
||||||
/// HARQ-ACKs
|
/// HARQ-ACKs
|
||||||
@@ -312,8 +306,6 @@ typedef struct {
|
|||||||
uint8_t max_ldpc_iterations;
|
uint8_t max_ldpc_iterations;
|
||||||
/// number of iterations used in last turbo decoding
|
/// number of iterations used in last turbo decoding
|
||||||
uint8_t last_iteration_cnt;
|
uint8_t last_iteration_cnt;
|
||||||
/// Maximum number of HARQ rounds
|
|
||||||
uint8_t Mlimit;
|
|
||||||
} NR_UE_DLSCH_t;
|
} NR_UE_DLSCH_t;
|
||||||
|
|
||||||
typedef enum {format0_0,
|
typedef enum {format0_0,
|
||||||
|
|||||||
@@ -130,10 +130,6 @@ NR_UE_ULSCH_t *new_nr_ue_ulsch(uint16_t N_RB_UL, int number_of_harq_pids, NR_DL_
|
|||||||
memset(ulsch, 0, sizeof(*ulsch));
|
memset(ulsch, 0, sizeof(*ulsch));
|
||||||
|
|
||||||
ulsch->number_harq_processes_for_pusch = NR_MAX_ULSCH_HARQ_PROCESSES;
|
ulsch->number_harq_processes_for_pusch = NR_MAX_ULSCH_HARQ_PROCESSES;
|
||||||
ulsch->Mlimit = 4; // maximum harq retransmissions
|
|
||||||
|
|
||||||
//for (i=0; i<10; i++)
|
|
||||||
//ulsch->harq_ids[i] = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < number_of_harq_pids; i++) {
|
for (int i = 0; i < number_of_harq_pids; i++) {
|
||||||
|
|
||||||
|
|||||||
@@ -188,8 +188,6 @@ typedef struct {
|
|||||||
uint8_t codebook_index;
|
uint8_t codebook_index;
|
||||||
/// Maximum number of HARQ processes
|
/// Maximum number of HARQ processes
|
||||||
uint8_t Mdlharq;
|
uint8_t Mdlharq;
|
||||||
/// Maximum number of HARQ rounds
|
|
||||||
uint8_t Mlimit;
|
|
||||||
/// MIMO transmission mode indicator for this sub-frame
|
/// MIMO transmission mode indicator for this sub-frame
|
||||||
uint8_t Kmimo;
|
uint8_t Kmimo;
|
||||||
/// Nsoft parameter related to UE Category
|
/// Nsoft parameter related to UE Category
|
||||||
@@ -345,8 +343,6 @@ typedef struct {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
/// Pointers to 16 HARQ processes for the ULSCH
|
/// Pointers to 16 HARQ processes for the ULSCH
|
||||||
NR_UL_gNB_HARQ_t *harq_processes[NR_MAX_ULSCH_HARQ_PROCESSES];
|
NR_UL_gNB_HARQ_t *harq_processes[NR_MAX_ULSCH_HARQ_PROCESSES];
|
||||||
/// Current HARQ process id
|
|
||||||
int harq_process_id[NR_MAX_SLOTS_PER_FRAME];
|
|
||||||
/// HARQ process mask, indicates which processes are currently active
|
/// HARQ process mask, indicates which processes are currently active
|
||||||
uint16_t harq_mask;
|
uint16_t harq_mask;
|
||||||
/// ACK/NAK Bundling flag
|
/// ACK/NAK Bundling flag
|
||||||
@@ -373,8 +369,6 @@ typedef struct {
|
|||||||
uint8_t cyclicShift;
|
uint8_t cyclicShift;
|
||||||
/// for cooperative communication
|
/// for cooperative communication
|
||||||
uint8_t cooperation_flag;
|
uint8_t cooperation_flag;
|
||||||
/// Maximum number of HARQ rounds
|
|
||||||
uint8_t Mlimit;
|
|
||||||
/// Maximum number of LDPC iterations
|
/// Maximum number of LDPC iterations
|
||||||
uint8_t max_ldpc_iterations;
|
uint8_t max_ldpc_iterations;
|
||||||
/// number of iterations used in last LDPC decoding
|
/// number of iterations used in last LDPC decoding
|
||||||
@@ -765,8 +759,8 @@ typedef struct PHY_VARS_gNB_s {
|
|||||||
/// SRS variables
|
/// SRS variables
|
||||||
nr_srs_info_t *nr_srs_info[NUMBER_OF_NR_SRS_MAX];
|
nr_srs_info_t *nr_srs_info[NUMBER_OF_NR_SRS_MAX];
|
||||||
|
|
||||||
/// CSI-RS variables
|
/// CSI variables
|
||||||
nr_csi_rs_info_t *nr_csi_rs_info;
|
nr_csi_info_t *nr_csi_info;
|
||||||
|
|
||||||
uint8_t pbch_configured;
|
uint8_t pbch_configured;
|
||||||
char gNB_generate_rar;
|
char gNB_generate_rar;
|
||||||
|
|||||||
@@ -878,8 +878,8 @@ typedef struct {
|
|||||||
/// SRS variables
|
/// SRS variables
|
||||||
nr_srs_info_t *nr_srs_info;
|
nr_srs_info_t *nr_srs_info;
|
||||||
|
|
||||||
/// CSI-RS variables
|
/// CSI variables
|
||||||
nr_csi_rs_info_t *nr_csi_rs_info;
|
nr_csi_info_t *nr_csi_info;
|
||||||
|
|
||||||
//#if defined(UPGRADE_RAT_NR)
|
//#if defined(UPGRADE_RAT_NR)
|
||||||
#if 1
|
#if 1
|
||||||
@@ -978,8 +978,8 @@ typedef struct {
|
|||||||
SLIST_HEAD(ral_thresholds_gen_poll_s, ral_threshold_phy_t) ral_thresholds_gen_polled[RAL_LINK_PARAM_GEN_MAX];
|
SLIST_HEAD(ral_thresholds_gen_poll_s, ral_threshold_phy_t) ral_thresholds_gen_polled[RAL_LINK_PARAM_GEN_MAX];
|
||||||
SLIST_HEAD(ral_thresholds_lte_poll_s, ral_threshold_phy_t) ral_thresholds_lte_polled[RAL_LINK_PARAM_LTE_MAX];
|
SLIST_HEAD(ral_thresholds_lte_poll_s, ral_threshold_phy_t) ral_thresholds_lte_polled[RAL_LINK_PARAM_LTE_MAX];
|
||||||
#endif
|
#endif
|
||||||
|
int dl_errors;
|
||||||
int dl_stats[5];
|
int dl_stats[8];
|
||||||
void* scopeData;
|
void* scopeData;
|
||||||
} PHY_VARS_NR_UE;
|
} PHY_VARS_NR_UE;
|
||||||
|
|
||||||
|
|||||||
@@ -43,6 +43,7 @@
|
|||||||
#define nr_slot_t lte_subframe_t
|
#define nr_slot_t lte_subframe_t
|
||||||
|
|
||||||
#define MAX_NUM_SUBCARRIER_SPACING 5
|
#define MAX_NUM_SUBCARRIER_SPACING 5
|
||||||
|
#define NR_MAX_OFDM_SYMBOL_SIZE 4096
|
||||||
|
|
||||||
#define NR_NB_SC_PER_RB 12
|
#define NR_NB_SC_PER_RB 12
|
||||||
#define NR_NB_REG_PER_CCE 6
|
#define NR_NB_REG_PER_CCE 6
|
||||||
@@ -247,23 +248,13 @@ typedef struct {
|
|||||||
} nr_srs_info_t;
|
} nr_srs_info_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t N_cdm_groups;
|
|
||||||
uint8_t CDM_group_size;
|
|
||||||
uint8_t kprime;
|
|
||||||
uint8_t lprime;
|
|
||||||
uint8_t N_ports;
|
|
||||||
uint8_t j[16];
|
|
||||||
uint8_t koverline[16];
|
|
||||||
uint8_t loverline[16];
|
|
||||||
uint16_t csi_gold_init;
|
uint16_t csi_gold_init;
|
||||||
uint32_t ***nr_gold_csi_rs;
|
uint32_t ***nr_gold_csi_rs;
|
||||||
uint8_t csi_rs_generated_signal_bits;
|
uint8_t csi_rs_generated_signal_bits;
|
||||||
int32_t **csi_rs_generated_signal;
|
int32_t **csi_rs_generated_signal;
|
||||||
int32_t **csi_rs_received_signal;
|
bool csi_im_meas_computed;
|
||||||
int32_t ***csi_rs_ls_estimated_channel;
|
uint32_t interference_plus_noise_power;
|
||||||
int32_t ***csi_rs_estimated_channel_freq;
|
} nr_csi_info_t;
|
||||||
uint32_t *noise_power;
|
|
||||||
} nr_csi_rs_info_t;
|
|
||||||
|
|
||||||
typedef struct NR_DL_FRAME_PARMS NR_DL_FRAME_PARMS;
|
typedef struct NR_DL_FRAME_PARMS NR_DL_FRAME_PARMS;
|
||||||
|
|
||||||
|
|||||||
@@ -71,9 +71,9 @@
|
|||||||
#include "common/utils/system.h"
|
#include "common/utils/system.h"
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include "openair1/SCHED/sched_common_extern.h"
|
||||||
extern int oai_exit;
|
#include "targets/RT/USER/lte-softmodem.h"
|
||||||
|
#include "common/ran_context.h"
|
||||||
|
|
||||||
void feptx0(RU_t *ru,
|
void feptx0(RU_t *ru,
|
||||||
int slot)
|
int slot)
|
||||||
@@ -616,9 +616,11 @@ void init_fep_thread(RU_t *ru,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
extern void kill_fep_thread(RU_t *ru)
|
void kill_fep_thread(RU_t *ru)
|
||||||
{
|
{
|
||||||
RU_proc_t *proc = &ru->proc;
|
RU_proc_t *proc = &ru->proc;
|
||||||
|
if (proc->pthread_fep == 0)
|
||||||
|
return;
|
||||||
pthread_mutex_lock( &proc->mutex_fep );
|
pthread_mutex_lock( &proc->mutex_fep );
|
||||||
proc->instance_cnt_fep = 0;
|
proc->instance_cnt_fep = 0;
|
||||||
pthread_cond_signal(&proc->cond_fep);
|
pthread_cond_signal(&proc->cond_fep);
|
||||||
@@ -630,9 +632,11 @@ extern void kill_fep_thread(RU_t *ru)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
extern void kill_feptx_thread(RU_t *ru)
|
void kill_feptx_thread(RU_t *ru)
|
||||||
{
|
{
|
||||||
RU_proc_t *proc = &ru->proc;
|
RU_proc_t *proc = &ru->proc;
|
||||||
|
if (proc->pthread_feptx == 0)
|
||||||
|
return;
|
||||||
pthread_mutex_lock( &proc->mutex_feptx );
|
pthread_mutex_lock( &proc->mutex_feptx );
|
||||||
proc->instance_cnt_feptx = 0;
|
proc->instance_cnt_feptx = 0;
|
||||||
pthread_cond_signal(&proc->cond_feptx);
|
pthread_cond_signal(&proc->cond_feptx);
|
||||||
|
|||||||
@@ -29,4 +29,6 @@
|
|||||||
extern int16_t hundred_times_delta_TF[100];
|
extern int16_t hundred_times_delta_TF[100];
|
||||||
extern uint16_t hundred_times_log10_NPRB[100];
|
extern uint16_t hundred_times_log10_NPRB[100];
|
||||||
|
|
||||||
|
void kill_fep_thread(RU_t *ru);
|
||||||
|
|
||||||
#endif /*__SCHED_EXTERN_H__ */
|
#endif /*__SCHED_EXTERN_H__ */
|
||||||
|
|||||||
@@ -172,7 +172,7 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx,
|
|||||||
if (csirs->active == 1) {
|
if (csirs->active == 1) {
|
||||||
LOG_D(PHY, "CSI-RS generation started in frame %d.%d\n",frame,slot);
|
LOG_D(PHY, "CSI-RS generation started in frame %d.%d\n",frame,slot);
|
||||||
nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csi_params = &csirs->csirs_pdu.csi_rs_pdu_rel15;
|
nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csi_params = &csirs->csirs_pdu.csi_rs_pdu_rel15;
|
||||||
nr_generate_csi_rs(gNB->frame_parms, gNB->common_vars.txdataF, AMP, gNB->nr_csi_rs_info, csi_params, slot);
|
nr_generate_csi_rs(&gNB->frame_parms, gNB->common_vars.txdataF, AMP, gNB->nr_csi_info, csi_params, slot, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||||
csirs->active = 0;
|
csirs->active = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -242,13 +242,6 @@ void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req) {
|
|||||||
ulsch_harq->ulsch_pdu.rb_size,
|
ulsch_harq->ulsch_pdu.rb_size,
|
||||||
ulsch_harq->TBS,
|
ulsch_harq->TBS,
|
||||||
r);
|
r);
|
||||||
ulsch_harq->round++;
|
|
||||||
if (ulsch_harq->round >= ulsch->Mlimit) {
|
|
||||||
ulsch_harq->status = SCH_IDLE;
|
|
||||||
ulsch_harq->round = 0;
|
|
||||||
ulsch_harq->handled = 0;
|
|
||||||
ulsch->harq_mask &= ~(1 << rdata->harq_pid);
|
|
||||||
}
|
|
||||||
ulsch_harq->handled = 1;
|
ulsch_harq->handled = 1;
|
||||||
|
|
||||||
LOG_D(PHY, "ULSCH %d in error\n",rdata->ulsch_id);
|
LOG_D(PHY, "ULSCH %d in error\n",rdata->ulsch_id);
|
||||||
@@ -413,17 +406,8 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id,
|
|||||||
if (timing_advance_update > 63) timing_advance_update = 63;
|
if (timing_advance_update > 63) timing_advance_update = 63;
|
||||||
|
|
||||||
if (crc_flag == 0) LOG_D(PHY, "%d.%d : Received PUSCH : Estimated timing advance PUSCH is = %d, timing_advance_update is %d \n", frame,slot_rx,sync_pos,timing_advance_update);
|
if (crc_flag == 0) LOG_D(PHY, "%d.%d : Received PUSCH : Estimated timing advance PUSCH is = %d, timing_advance_update is %d \n", frame,slot_rx,sync_pos,timing_advance_update);
|
||||||
else if (harq_process->round>0 || dtx_flag == 0) { // increment round if crc_flag == 1 and not(dtx_flag ==1 and round==0)
|
|
||||||
harq_process->round++;
|
|
||||||
if (harq_process->round >= ulsch->Mlimit) {
|
|
||||||
harq_process->status = SCH_IDLE;
|
|
||||||
harq_process->round = 0;
|
|
||||||
harq_process->handled = 0;
|
|
||||||
ulsch->harq_mask &= ~(1 << harq_pid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// estimate UL_CQI for MAC
|
|
||||||
|
|
||||||
|
// estimate UL_CQI for MAC
|
||||||
int SNRtimes10 = dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_power_tot) -
|
int SNRtimes10 = dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_power_tot) -
|
||||||
dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_noise_power_tot);
|
dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_noise_power_tot);
|
||||||
|
|
||||||
@@ -573,7 +557,7 @@ void fill_ul_rb_mask(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
|
|||||||
LOG_D(PHY,"symbol %d Filling rb_mask_ul rb_size %d\n",symbol,ulsch_harq->ulsch_pdu.rb_size);
|
LOG_D(PHY,"symbol %d Filling rb_mask_ul rb_size %d\n",symbol,ulsch_harq->ulsch_pdu.rb_size);
|
||||||
for (rb=0; rb<ulsch_harq->ulsch_pdu.rb_size; rb++) {
|
for (rb=0; rb<ulsch_harq->ulsch_pdu.rb_size; rb++) {
|
||||||
rb2 = rb+ulsch_harq->ulsch_pdu.rb_start+ulsch_harq->ulsch_pdu.bwp_start;
|
rb2 = rb+ulsch_harq->ulsch_pdu.rb_start+ulsch_harq->ulsch_pdu.bwp_start;
|
||||||
gNB->rb_mask_ul[symbol][rb2>>5] |= (1<<(rb2&31));
|
gNB->rb_mask_ul[symbol][rb2 >> 5] |= 1U << (rb2 & 31);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -858,8 +842,8 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
|
|||||||
uint8_t N_symb_SRS = 1<<srs_pdu->num_symbols;
|
uint8_t N_symb_SRS = 1<<srs_pdu->num_symbols;
|
||||||
int32_t srs_received_signal[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size*N_symb_SRS];
|
int32_t srs_received_signal[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size*N_symb_SRS];
|
||||||
int32_t srs_ls_estimated_channel[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size*N_symb_SRS];
|
int32_t srs_ls_estimated_channel[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size*N_symb_SRS];
|
||||||
int32_t srs_estimated_channel_freq[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size*N_symb_SRS];
|
int32_t srs_estimated_channel_freq[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size*N_symb_SRS] __attribute__ ((aligned(32)));
|
||||||
int32_t srs_estimated_channel_time[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size];
|
int32_t srs_estimated_channel_time[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size] __attribute__ ((aligned(32)));
|
||||||
int32_t srs_estimated_channel_time_shifted[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size];
|
int32_t srs_estimated_channel_time_shifted[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size];
|
||||||
uint32_t noise_power_per_rb[srs_pdu->bwp_size];
|
uint32_t noise_power_per_rb[srs_pdu->bwp_size];
|
||||||
int8_t snr_per_rb[srs_pdu->bwp_size];
|
int8_t snr_per_rb[srs_pdu->bwp_size];
|
||||||
|
|||||||
@@ -405,7 +405,7 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind,
|
|||||||
NR_UE_DLSCH_t *dlsch1,
|
NR_UE_DLSCH_t *dlsch1,
|
||||||
uint16_t n_pdus,
|
uint16_t n_pdus,
|
||||||
UE_nr_rxtx_proc_t *proc,
|
UE_nr_rxtx_proc_t *proc,
|
||||||
void * typeSpecific);
|
void *typeSpecific);
|
||||||
|
|
||||||
bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
|
bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
|
||||||
UE_nr_rxtx_proc_t *proc,
|
UE_nr_rxtx_proc_t *proc,
|
||||||
|
|||||||
@@ -393,7 +393,7 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
|
|||||||
case FAPI_NR_DL_CONFIG_TYPE_CSI_IM:
|
case FAPI_NR_DL_CONFIG_TYPE_CSI_IM:
|
||||||
csiim_config_pdu = &dl_config->dl_config_list[i].csiim_config_pdu.csiim_config_rel15;
|
csiim_config_pdu = &dl_config->dl_config_list[i].csiim_config_pdu.csiim_config_rel15;
|
||||||
memcpy((void*)&(csiim_vars->csiim_config_pdu), (void*)csiim_config_pdu, sizeof(fapi_nr_dl_config_csiim_pdu_rel15_t));
|
memcpy((void*)&(csiim_vars->csiim_config_pdu), (void*)csiim_config_pdu, sizeof(fapi_nr_dl_config_csiim_pdu_rel15_t));
|
||||||
csirs_vars->active = true;
|
csiim_vars->active = true;
|
||||||
break;
|
break;
|
||||||
case FAPI_NR_DL_CONFIG_TYPE_CSI_RS:
|
case FAPI_NR_DL_CONFIG_TYPE_CSI_RS:
|
||||||
csirs_config_pdu = &dl_config->dl_config_list[i].csirs_config_pdu.csirs_config_rel15;
|
csirs_config_pdu = &dl_config->dl_config_list[i].csirs_config_pdu.csirs_config_rel15;
|
||||||
|
|||||||
@@ -308,7 +308,7 @@ void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq)
|
|||||||
dl_harq->status = SCH_IDLE;
|
dl_harq->status = SCH_IDLE;
|
||||||
dl_harq->first_rx = 1;
|
dl_harq->first_rx = 1;
|
||||||
dl_harq->DLround = 0;
|
dl_harq->DLround = 0;
|
||||||
dl_harq->DCINdi = 1;
|
dl_harq->Ndi = 1;
|
||||||
dl_harq->ack = DL_ACKNACK_NO_SET;
|
dl_harq->ack = DL_ACKNACK_NO_SET;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -329,7 +329,7 @@ void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq)
|
|||||||
*
|
*
|
||||||
*********************************************************************/
|
*********************************************************************/
|
||||||
|
|
||||||
void downlink_harq_process(NR_DL_UE_HARQ_t *dl_harq, int harq_pid, int ndi, int rv, uint8_t rnti_type) {
|
void downlink_harq_process(NR_DL_UE_HARQ_t *dl_harq, int harq_pid, int dci_ndi, int rv, uint8_t rnti_type) {
|
||||||
|
|
||||||
if (rnti_type == _SI_RNTI_ ||
|
if (rnti_type == _SI_RNTI_ ||
|
||||||
rnti_type == _P_RNTI_ ||
|
rnti_type == _P_RNTI_ ||
|
||||||
@@ -339,10 +339,9 @@ void downlink_harq_process(NR_DL_UE_HARQ_t *dl_harq, int harq_pid, int ndi, int
|
|||||||
dl_harq->first_rx = 1;
|
dl_harq->first_rx = 1;
|
||||||
} else {
|
} else {
|
||||||
LOG_D(PHY,"receive harq process: %p harqPid=%d, rv=%d, ndi=%d, rntiType=%d new transmission= %s\n",
|
LOG_D(PHY,"receive harq process: %p harqPid=%d, rv=%d, ndi=%d, rntiType=%d new transmission= %s\n",
|
||||||
dl_harq, harq_pid, rv, ndi, rnti_type, dl_harq->DCINdi != ndi ? "yes":"no");
|
dl_harq, harq_pid, rv, dci_ndi, rnti_type, dl_harq->Ndi != dci_ndi ? "yes":"no");
|
||||||
AssertFatal(rv<4 && rv>=0, "invalid redondancy version %d\n", rv);
|
AssertFatal(rv<4 && rv>=0, "invalid redondancy version %d\n", rv);
|
||||||
|
if (dci_ndi!=dl_harq->Ndi) {
|
||||||
if (ndi!=dl_harq->DCINdi) {
|
|
||||||
if (dl_harq->ack == DL_NACK)
|
if (dl_harq->ack == DL_NACK)
|
||||||
LOG_D(PHY,"New transmission on a harq pid (%d) never acknowledged\n", harq_pid);
|
LOG_D(PHY,"New transmission on a harq pid (%d) never acknowledged\n", harq_pid);
|
||||||
else
|
else
|
||||||
@@ -354,7 +353,7 @@ void downlink_harq_process(NR_DL_UE_HARQ_t *dl_harq, int harq_pid, int ndi, int
|
|||||||
LOG_D(PHY,"Starting retransmission on a harq pid (%d), rv (%d)\n", harq_pid, rv);
|
LOG_D(PHY,"Starting retransmission on a harq pid (%d), rv (%d)\n", harq_pid, rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ndi!=dl_harq->DCINdi) {
|
if (dci_ndi!=dl_harq->Ndi) {
|
||||||
dl_harq->first_rx = true;
|
dl_harq->first_rx = true;
|
||||||
dl_harq->DLround = 0;
|
dl_harq->DLround = 0;
|
||||||
} else {
|
} else {
|
||||||
@@ -364,7 +363,7 @@ void downlink_harq_process(NR_DL_UE_HARQ_t *dl_harq, int harq_pid, int ndi, int
|
|||||||
|
|
||||||
dl_harq->status = ACTIVE;
|
dl_harq->status = ACTIVE;
|
||||||
|
|
||||||
dl_harq->DCINdi = ndi;
|
dl_harq->Ndi = dci_ndi;
|
||||||
//dl_harq->status = SCH_IDLE;
|
//dl_harq->status = SCH_IDLE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -121,9 +121,8 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind,
|
|||||||
NR_UE_DLSCH_t *dlsch0,
|
NR_UE_DLSCH_t *dlsch0,
|
||||||
NR_UE_DLSCH_t *dlsch1,
|
NR_UE_DLSCH_t *dlsch1,
|
||||||
uint16_t n_pdus,
|
uint16_t n_pdus,
|
||||||
UE_nr_rxtx_proc_t *proc,
|
UE_nr_rxtx_proc_t *proc,
|
||||||
void * typeSpecific){
|
void *typeSpecific){
|
||||||
|
|
||||||
|
|
||||||
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
|
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
|
||||||
|
|
||||||
@@ -176,6 +175,11 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind,
|
|||||||
rx_ind->rx_indication_body[n_pdus - 1].ssb_pdu.ssb_start_subcarrier = frame_parms->ssb_start_subcarrier;
|
rx_ind->rx_indication_body[n_pdus - 1].ssb_pdu.ssb_start_subcarrier = frame_parms->ssb_start_subcarrier;
|
||||||
rx_ind->rx_indication_body[n_pdus - 1].ssb_pdu.rsrp_dBm = ue->measurements.rsrp_dBm[gNB_id];
|
rx_ind->rx_indication_body[n_pdus - 1].ssb_pdu.rsrp_dBm = ue->measurements.rsrp_dBm[gNB_id];
|
||||||
break;
|
break;
|
||||||
|
case FAPI_NR_CSIRS_IND:
|
||||||
|
memcpy(&rx_ind->rx_indication_body[n_pdus - 1].csirs_measurements,
|
||||||
|
(fapi_nr_csirs_measurements_t*)typeSpecific,
|
||||||
|
sizeof(*(fapi_nr_csirs_measurements_t*)typeSpecific));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1321,8 +1325,7 @@ int is_ssb_in_slot(fapi_nr_config_request_t *config, int frame, int slot, NR_DL_
|
|||||||
//uint8_t half_frame_index = fp->half_frame_bit;
|
//uint8_t half_frame_index = fp->half_frame_bit;
|
||||||
//uint8_t i_ssb = fp->ssb_index;
|
//uint8_t i_ssb = fp->ssb_index;
|
||||||
uint8_t Lmax = fp->Lmax;
|
uint8_t Lmax = fp->Lmax;
|
||||||
|
if ((config->ssb_table.ssb_period > 0) && !(frame % (1 << (config->ssb_table.ssb_period - 1)))) {
|
||||||
if (!(frame%(1<<(config->ssb_table.ssb_period-1)))){
|
|
||||||
|
|
||||||
if(Lmax <= 8) {
|
if(Lmax <= 8) {
|
||||||
if(slot <=3 && (((config->ssb_table.ssb_mask_list[0].ssb_mask << 2*slot)&0x80000000) == 0x80000000 || ((config->ssb_table.ssb_mask_list[0].ssb_mask << (2*slot +1))&0x80000000) == 0x80000000))
|
if(slot <=3 && (((config->ssb_table.ssb_mask_list[0].ssb_mask << 2*slot)&0x80000000) == 0x80000000 || ((config->ssb_table.ssb_mask_list[0].ssb_mask << (2*slot +1))&0x80000000) == 0x80000000))
|
||||||
@@ -1477,7 +1480,17 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
|
|||||||
|
|
||||||
if ((frame_rx%64 == 0) && (nr_slot_rx==0)) {
|
if ((frame_rx%64 == 0) && (nr_slot_rx==0)) {
|
||||||
LOG_I(NR_PHY,"============================================\n");
|
LOG_I(NR_PHY,"============================================\n");
|
||||||
LOG_I(NR_PHY,"Harq round stats for Downlink: %d/%d/%d/%d DLSCH errors: %d\n",ue->dl_stats[0],ue->dl_stats[1],ue->dl_stats[2],ue->dl_stats[3],ue->dl_stats[4]);
|
// fixed text + 8 HARQs rounds à 10 ("999999999/") + NULL
|
||||||
|
// if we use 999999999 HARQs, that should be sufficient for at least 138 hours
|
||||||
|
const size_t harq_output_len = 31 + 10 * 8 + 1;
|
||||||
|
char output[harq_output_len];
|
||||||
|
char *p = output;
|
||||||
|
const char *end = output + harq_output_len;
|
||||||
|
p += snprintf(p, end - p, "Harq round stats for Downlink: %d", ue->dl_stats[0]);
|
||||||
|
for (int round = 1; round < 16 && (round < 3 || ue->dl_stats[round] != 0); ++round)
|
||||||
|
p += snprintf(p, end - p,"/%d", ue->dl_stats[round]);
|
||||||
|
LOG_I(NR_PHY,"%s/0\n", output);
|
||||||
|
|
||||||
LOG_I(NR_PHY,"============================================\n");
|
LOG_I(NR_PHY,"============================================\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1692,6 +1705,19 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
|
|||||||
|
|
||||||
// do procedures for CSI-IM
|
// do procedures for CSI-IM
|
||||||
if ((ue->csiim_vars[gNB_id]) && (ue->csiim_vars[gNB_id]->active == 1)) {
|
if ((ue->csiim_vars[gNB_id]) && (ue->csiim_vars[gNB_id]->active == 1)) {
|
||||||
|
int l_csiim[4] = {-1, -1, -1, -1};
|
||||||
|
for(int symb_idx = 0; symb_idx < 4; symb_idx++) {
|
||||||
|
bool nr_slot_fep_done = false;
|
||||||
|
for (int symb_idx2 = 0; symb_idx2 < symb_idx; symb_idx2++) {
|
||||||
|
if (l_csiim[symb_idx2] == ue->csiim_vars[gNB_id]->csiim_config_pdu.l_csiim[symb_idx]) {
|
||||||
|
nr_slot_fep_done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
l_csiim[symb_idx] = ue->csiim_vars[gNB_id]->csiim_config_pdu.l_csiim[symb_idx];
|
||||||
|
if(nr_slot_fep_done == false) {
|
||||||
|
nr_slot_fep(ue, proc, ue->csiim_vars[gNB_id]->csiim_config_pdu.l_csiim[symb_idx], nr_slot_rx);
|
||||||
|
}
|
||||||
|
}
|
||||||
nr_ue_csi_im_procedures(ue, proc, gNB_id);
|
nr_ue_csi_im_procedures(ue, proc, gNB_id);
|
||||||
ue->csiim_vars[gNB_id]->active = 0;
|
ue->csiim_vars[gNB_id]->active = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -512,12 +512,16 @@ int main(int argc, char **argv) {
|
|||||||
int re;
|
int re;
|
||||||
int s,Kr,Kr_bytes;
|
int s,Kr,Kr_bytes;
|
||||||
LTE_DL_FRAME_PARMS *frame_parms;
|
LTE_DL_FRAME_PARMS *frame_parms;
|
||||||
double s_re0[30720*2],s_im0[30720*2],r_re0[30720*2],r_im0[30720*2];
|
double *tmpTX[4], *tmpRX[4] ;
|
||||||
double s_re1[30720*2],s_im1[30720*2],r_re1[30720*2],r_im1[30720*2];
|
for (int i = 0; i < 4; i++) {
|
||||||
double *s_re[2]= {s_re0,s_re1};
|
tmpTX[i] = malloc(30720 * NB_ANTENNAS_TX * sizeof(*tmpTX));
|
||||||
double *s_im[2]= {s_im0,s_im1};
|
tmpRX[i] = malloc(30720 * NB_ANTENNAS_RX * sizeof(*tmpRX));
|
||||||
double *r_re[2]= {r_re0,r_re1};
|
}
|
||||||
double *r_im[2]= {r_im0,r_im1};
|
double *s_re[NB_ANTENNAS_TX] = {tmpTX[0], tmpTX[1]};
|
||||||
|
double *s_im[NB_ANTENNAS_TX] = {tmpTX[2], tmpTX[3]};
|
||||||
|
double *r_re[NB_ANTENNAS_RX] = {tmpRX[0], tmpRX[1]};
|
||||||
|
double *r_im[NB_ANTENNAS_RX] = {tmpRX[2], tmpRX[3]};
|
||||||
|
|
||||||
uint8_t transmission_mode=1,n_tx_port=1,n_tx_phy=1,n_rx=2;
|
uint8_t transmission_mode=1,n_tx_port=1,n_tx_phy=1,n_rx=2;
|
||||||
int eNB_id = 0;
|
int eNB_id = 0;
|
||||||
unsigned char round;
|
unsigned char round;
|
||||||
|
|||||||
@@ -358,7 +358,7 @@ int main(int argc, char **argv) {
|
|||||||
unsigned short input_buffer_length;
|
unsigned short input_buffer_length;
|
||||||
unsigned int ret;
|
unsigned int ret;
|
||||||
unsigned int coded_bits_per_codeword,nsymb;
|
unsigned int coded_bits_per_codeword,nsymb;
|
||||||
unsigned int tx_lev=0,tx_lev_dB=0,trials,errs[5]= {0,0,0,0,0},round_trials[4]= {0,0,0,0};
|
unsigned int tx_lev = 0, tx_lev_dB = 0, trials, errs[6] = {0}, round_trials[4] = {0};
|
||||||
FILE *bler_fd=NULL;
|
FILE *bler_fd=NULL;
|
||||||
char bler_fname[512];
|
char bler_fname[512];
|
||||||
FILE *time_meas_fd=NULL;
|
FILE *time_meas_fd=NULL;
|
||||||
@@ -387,7 +387,6 @@ int main(int argc, char **argv) {
|
|||||||
double cpu_freq_GHz;
|
double cpu_freq_GHz;
|
||||||
int iter_trials;
|
int iter_trials;
|
||||||
uint32_t UL_alloc_pdu;
|
uint32_t UL_alloc_pdu;
|
||||||
int s,Kr,Kr_bytes;
|
|
||||||
int dump_perf=0;
|
int dump_perf=0;
|
||||||
static int dump_table =0;
|
static int dump_table =0;
|
||||||
double effective_rate=0.0;
|
double effective_rate=0.0;
|
||||||
@@ -1233,20 +1232,21 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
if (n_frames==1) {
|
if (n_frames==1) {
|
||||||
printf("ULSCH errors found o_ACK[0]= %d\n",eNB->ulsch[0]->harq_processes[harq_pid]->o_ACK[0]);
|
printf("ULSCH errors found o_ACK[0]= %d\n",eNB->ulsch[0]->harq_processes[harq_pid]->o_ACK[0]);
|
||||||
|
#ifdef DUMP_EACH_VALUE
|
||||||
|
int Kr_bytes;
|
||||||
for (s=0; s<eNB->ulsch[0]->harq_processes[harq_pid]->C; s++) {
|
for (s=0; s<eNB->ulsch[0]->harq_processes[harq_pid]->C; s++) {
|
||||||
if (s<eNB->ulsch[0]->harq_processes[harq_pid]->Cminus)
|
if (s<eNB->ulsch[0]->harq_processes[harq_pid]->Cminus)
|
||||||
Kr = eNB->ulsch[0]->harq_processes[harq_pid]->Kminus;
|
Kr_bytes = eNB->ulsch[0]->harq_processes[harq_pid]->Kminus;
|
||||||
else
|
else
|
||||||
Kr = eNB->ulsch[0]->harq_processes[harq_pid]->Kplus;
|
Kr_bytes = eNB->ulsch[0]->harq_processes[harq_pid]->Kplus;
|
||||||
|
Kr_bytes = Kr_bytes >> 3;
|
||||||
Kr_bytes = Kr>>3;
|
|
||||||
printf("Decoded_output (Segment %d):\n",s);
|
printf("Decoded_output (Segment %d):\n",s);
|
||||||
|
|
||||||
for (i=0; i<Kr_bytes; i++)
|
for (i=0; i<Kr_bytes; i++)
|
||||||
printf("%d : %x (%x)\n",i,eNB->ulsch[0]->harq_processes[harq_pid]->c[s][i],
|
printf("%d : %x (%x)\n",i,eNB->ulsch[0]->harq_processes[harq_pid]->c[s][i],
|
||||||
eNB->ulsch[0]->harq_processes[harq_pid]->c[s][i]^UE->ulsch[0]->harq_processes[harq_pid]->c[s][i]);
|
eNB->ulsch[0]->harq_processes[harq_pid]->c[s][i]^UE->ulsch[0]->harq_processes[harq_pid]->c[s][i]);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
dump_ulsch(eNB,eNB->proc.frame_rx,subframe,0,round);
|
dump_ulsch(eNB,eNB->proc.frame_rx,subframe,0,round);
|
||||||
round=5;
|
round=5;
|
||||||
|
|||||||
@@ -114,16 +114,16 @@ int main(int argc, char **argv)
|
|||||||
//int run_initial_sync=0;
|
//int run_initial_sync=0;
|
||||||
int loglvl = OAILOG_WARNING;
|
int loglvl = OAILOG_WARNING;
|
||||||
uint8_t dlsch_threads = 0;
|
uint8_t dlsch_threads = 0;
|
||||||
float target_error_rate = 0.01;
|
float target_error_rate = 0.01;
|
||||||
uint64_t SSB_positions=0x01;
|
uint64_t SSB_positions=0x01;
|
||||||
uint16_t nb_symb_sch = 12;
|
uint16_t nb_symb_sch = 12;
|
||||||
uint16_t nb_rb = 50;
|
uint16_t nb_rb = 50;
|
||||||
uint8_t Imcs = 9;
|
uint8_t Imcs = 9;
|
||||||
uint8_t mcs_table = 0;
|
uint8_t mcs_table = 0;
|
||||||
double DS_TDL = .03;
|
double DS_TDL = .03;
|
||||||
cpuf = get_cpu_freq_GHz();
|
cpuf = get_cpu_freq_GHz();
|
||||||
char gNBthreads[128]="n";
|
char gNBthreads[128]="n";
|
||||||
int Tbslbrm = 950984;
|
int Tbslbrm = 950984;
|
||||||
|
|
||||||
if (load_configmodule(argc, argv, CONFIG_ENABLECMDLINEONLY) == 0) {
|
if (load_configmodule(argc, argv, CONFIG_ENABLECMDLINEONLY) == 0) {
|
||||||
exit_fun("[NR_DLSCHSIM] Error, configuration module init failed\n");
|
exit_fun("[NR_DLSCHSIM] Error, configuration module init failed\n");
|
||||||
@@ -299,7 +299,7 @@ int main(int argc, char **argv)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'X':
|
case 'X':
|
||||||
strncpy(gNBthreads, optarg, sizeof(gNBthreads));
|
strncpy(gNBthreads, optarg, sizeof(gNBthreads)-1);
|
||||||
gNBthreads[sizeof(gNBthreads)-1]=0;
|
gNBthreads[sizeof(gNBthreads)-1]=0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@@ -100,9 +100,17 @@ nfapi_ue_release_request_body_t release_rntis;
|
|||||||
//Fixme: Uniq dirty DU instance, by global var, datamodel need better management
|
//Fixme: Uniq dirty DU instance, by global var, datamodel need better management
|
||||||
instance_t DUuniqInstance=0;
|
instance_t DUuniqInstance=0;
|
||||||
instance_t CUuniqInstance=0;
|
instance_t CUuniqInstance=0;
|
||||||
teid_t newGtpuCreateTunnel(instance_t instance, rnti_t rnti, int incoming_bearer_id, int outgoing_bearer_id, teid_t outgoing_teid,
|
teid_t newGtpuCreateTunnel(instance_t instance,
|
||||||
transport_layer_addr_t remoteAddr, int port, gtpCallback callBack) {
|
rnti_t rnti,
|
||||||
return 0;
|
int incoming_bearer_id,
|
||||||
|
int outgoing_bearer_id,
|
||||||
|
teid_t outgoing_teid,
|
||||||
|
int qfi,
|
||||||
|
transport_layer_addr_t remoteAddr,
|
||||||
|
int port,
|
||||||
|
gtpCallback callBack,
|
||||||
|
gtpCallbackSDAP callBackSDAP) {
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int newGtpuDeleteAllTunnels(instance_t instance, rnti_t rnti) {
|
int newGtpuDeleteAllTunnels(instance_t instance, rnti_t rnti) {
|
||||||
@@ -670,7 +678,7 @@ int main(int argc, char **argv)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'X':
|
case 'X':
|
||||||
strncpy(gNBthreads, optarg, sizeof(gNBthreads));
|
strncpy(gNBthreads, optarg, sizeof(gNBthreads)-1);
|
||||||
gNBthreads[sizeof(gNBthreads)-1]=0;
|
gNBthreads[sizeof(gNBthreads)-1]=0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -761,6 +769,8 @@ int main(int argc, char **argv)
|
|||||||
gNB_RRC_INST rrc;
|
gNB_RRC_INST rrc;
|
||||||
memset((void*)&rrc,0,sizeof(rrc));
|
memset((void*)&rrc,0,sizeof(rrc));
|
||||||
|
|
||||||
|
gNB_mac->dl_bler.harq_round_max = num_rounds;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// read in SCGroupConfig
|
// read in SCGroupConfig
|
||||||
AssertFatal(scg_fd != NULL,"no reconfig.raw file\n");
|
AssertFatal(scg_fd != NULL,"no reconfig.raw file\n");
|
||||||
@@ -1142,7 +1152,7 @@ int main(int argc, char **argv)
|
|||||||
Sched_INFO.frame = frame;
|
Sched_INFO.frame = frame;
|
||||||
Sched_INFO.slot = slot;
|
Sched_INFO.slot = slot;
|
||||||
Sched_INFO.DL_req = &gNB_mac->DL_req[0];
|
Sched_INFO.DL_req = &gNB_mac->DL_req[0];
|
||||||
Sched_INFO.UL_tti_req = gNB_mac->UL_tti_req_ahead[slot];
|
Sched_INFO.UL_tti_req = gNB_mac->UL_tti_req_ahead[0];
|
||||||
Sched_INFO.UL_dci_req = NULL;
|
Sched_INFO.UL_dci_req = NULL;
|
||||||
Sched_INFO.TX_req = &gNB_mac->TX_req[0];
|
Sched_INFO.TX_req = &gNB_mac->TX_req[0];
|
||||||
pushNotifiedFIFO(gNB->L1_tx_free,msgL1Tx);
|
pushNotifiedFIFO(gNB->L1_tx_free,msgL1Tx);
|
||||||
|
|||||||
@@ -40,4 +40,4 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind,
|
|||||||
NR_UE_DLSCH_t *dlsch1,
|
NR_UE_DLSCH_t *dlsch1,
|
||||||
uint16_t n_pdus,
|
uint16_t n_pdus,
|
||||||
UE_nr_rxtx_proc_t *proc,
|
UE_nr_rxtx_proc_t *proc,
|
||||||
void * typeSpecific ) {}
|
void *typeSpecific ) {}
|
||||||
|
|||||||
@@ -92,9 +92,17 @@ int oai_nfapi_nr_rach_indication(nfapi_nr_rach_indication_t *ind) { return(0);
|
|||||||
//Fixme: Uniq dirty DU instance, by global var, datamodel need better management
|
//Fixme: Uniq dirty DU instance, by global var, datamodel need better management
|
||||||
instance_t DUuniqInstance=0;
|
instance_t DUuniqInstance=0;
|
||||||
instance_t CUuniqInstance=0;
|
instance_t CUuniqInstance=0;
|
||||||
teid_t newGtpuCreateTunnel(instance_t instance, rnti_t rnti, int incoming_bearer_id, int outgoing_bearer_id, teid_t outgoing_teid,
|
teid_t newGtpuCreateTunnel(instance_t instance,
|
||||||
transport_layer_addr_t remoteAddr, int port, gtpCallback callBack) {
|
rnti_t rnti,
|
||||||
return 0;
|
int incoming_bearer_id,
|
||||||
|
int outgoing_bearer_id,
|
||||||
|
teid_t outgoing_teid,
|
||||||
|
int qfi,
|
||||||
|
transport_layer_addr_t remoteAddr,
|
||||||
|
int port,
|
||||||
|
gtpCallback callBack,
|
||||||
|
gtpCallbackSDAP callBackSDAP) {
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int newGtpuDeleteAllTunnels(instance_t instance, rnti_t rnti) {
|
int newGtpuDeleteAllTunnels(instance_t instance, rnti_t rnti) {
|
||||||
|
|||||||
@@ -95,9 +95,17 @@ nfapi_ue_release_request_body_t release_rntis;
|
|||||||
//Fixme: Uniq dirty DU instance, by global var, datamodel need better management
|
//Fixme: Uniq dirty DU instance, by global var, datamodel need better management
|
||||||
instance_t DUuniqInstance=0;
|
instance_t DUuniqInstance=0;
|
||||||
instance_t CUuniqInstance=0;
|
instance_t CUuniqInstance=0;
|
||||||
teid_t newGtpuCreateTunnel(instance_t instance, rnti_t rnti, int incoming_bearer_id, int outgoing_bearer_id, teid_t outgoing_teid,
|
teid_t newGtpuCreateTunnel(instance_t instance,
|
||||||
transport_layer_addr_t remoteAddr, int port, gtpCallback callBack) {
|
rnti_t rnti,
|
||||||
return 0;
|
int incoming_bearer_id,
|
||||||
|
int outgoing_bearer_id,
|
||||||
|
teid_t outgoing_teid,
|
||||||
|
int qfi,
|
||||||
|
transport_layer_addr_t remoteAddr,
|
||||||
|
int port,
|
||||||
|
gtpCallback callBack,
|
||||||
|
gtpCallbackSDAP callBackSDAP) {
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int newGtpuDeleteAllTunnels(instance_t instance, rnti_t rnti) {
|
int newGtpuDeleteAllTunnels(instance_t instance, rnti_t rnti) {
|
||||||
|
|||||||
@@ -181,6 +181,7 @@ typedef struct gtpv1u_gnb_create_tunnel_req_s {
|
|||||||
int num_tunnels;
|
int num_tunnels;
|
||||||
//teid_t upf_NGu_teid[NR_GTPV1U_MAX_BEARERS_PER_UE]; ///< Tunnel Endpoint Identifier
|
//teid_t upf_NGu_teid[NR_GTPV1U_MAX_BEARERS_PER_UE]; ///< Tunnel Endpoint Identifier
|
||||||
teid_t outgoing_teid[NR_GTPV1U_MAX_BEARERS_PER_UE];
|
teid_t outgoing_teid[NR_GTPV1U_MAX_BEARERS_PER_UE];
|
||||||
|
int outgoing_qfi[NR_GTPV1U_MAX_BEARERS_PER_UE];
|
||||||
pdusessionid_t pdusession_id[NR_GTPV1U_MAX_BEARERS_PER_UE];
|
pdusessionid_t pdusession_id[NR_GTPV1U_MAX_BEARERS_PER_UE];
|
||||||
ebi_t incoming_rb_id[NR_GTPV1U_MAX_BEARERS_PER_UE];
|
ebi_t incoming_rb_id[NR_GTPV1U_MAX_BEARERS_PER_UE];
|
||||||
//ebi_t outgoing_rb_id[NR_GTPV1U_MAX_BEARERS_PER_UE];
|
//ebi_t outgoing_rb_id[NR_GTPV1U_MAX_BEARERS_PER_UE];
|
||||||
|
|||||||
@@ -515,15 +515,16 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance,
|
|||||||
int sz=sizeof(f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_dl_tnl[0].tl_address);
|
int sz=sizeof(f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_dl_tnl[0].tl_address);
|
||||||
memcpy(addr.buffer,&f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_dl_tnl[0].tl_address, sz);
|
memcpy(addr.buffer,&f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_dl_tnl[0].tl_address, sz);
|
||||||
addr.length = sz*8;
|
addr.length = sz*8;
|
||||||
f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl[j].teid=
|
f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl[j].teid = newGtpuCreateTunnel(getCxt(CUtype, instance)->gtpInst,
|
||||||
newGtpuCreateTunnel(getCxt(CUtype, instance)->gtpInst,
|
f1ap_ue_context_setup_req->rnti,
|
||||||
f1ap_ue_context_setup_req->rnti,
|
f1ap_ue_context_setup_req->drbs_to_be_setup[i].drb_id,
|
||||||
f1ap_ue_context_setup_req->drbs_to_be_setup[i].drb_id,
|
f1ap_ue_context_setup_req->drbs_to_be_setup[i].drb_id,
|
||||||
f1ap_ue_context_setup_req->drbs_to_be_setup[i].drb_id,
|
0xFFFF, // We will set the right value from DU answer
|
||||||
0xFFFF, // We will set the right value from DU answer
|
-1, // no qfi
|
||||||
addr,
|
addr,
|
||||||
f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_dl_tnl[0].port,
|
f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_dl_tnl[0].port,
|
||||||
cu_f1u_data_req);
|
cu_f1u_data_req,
|
||||||
|
NULL);
|
||||||
/* 12.3.1 ULTunnels_ToBeSetup_Item */
|
/* 12.3.1 ULTunnels_ToBeSetup_Item */
|
||||||
asn1cSequenceAdd(drbs_toBeSetup_item->uLUPTNLInformation_ToBeSetup_List.list,
|
asn1cSequenceAdd(drbs_toBeSetup_item->uLUPTNLInformation_ToBeSetup_List.list,
|
||||||
F1AP_ULUPTNLInformation_ToBeSetup_Item_t, uLUPTNLInformation_ToBeSetup_Item);
|
F1AP_ULUPTNLInformation_ToBeSetup_Item_t, uLUPTNLInformation_ToBeSetup_Item);
|
||||||
@@ -1491,15 +1492,16 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, f1ap_ue_context
|
|||||||
memcpy(addr.buffer,&f1ap_ue_context_modification_req->drbs_to_be_setup[i].up_dl_tnl[0].tl_address, sz);
|
memcpy(addr.buffer,&f1ap_ue_context_modification_req->drbs_to_be_setup[i].up_dl_tnl[0].tl_address, sz);
|
||||||
addr.length = sz*8;
|
addr.length = sz*8;
|
||||||
|
|
||||||
f1ap_ue_context_modification_req->drbs_to_be_setup[i].up_ul_tnl[j].teid=
|
f1ap_ue_context_modification_req->drbs_to_be_setup[i].up_ul_tnl[j].teid = newGtpuCreateTunnel(getCxt(CUtype, instance)->gtpInst,
|
||||||
newGtpuCreateTunnel(getCxt(CUtype, instance)->gtpInst,
|
f1ap_ue_context_modification_req->rnti,
|
||||||
f1ap_ue_context_modification_req->rnti,
|
f1ap_ue_context_modification_req->drbs_to_be_setup[i].drb_id,
|
||||||
f1ap_ue_context_modification_req->drbs_to_be_setup[i].drb_id,
|
f1ap_ue_context_modification_req->drbs_to_be_setup[i].drb_id,
|
||||||
f1ap_ue_context_modification_req->drbs_to_be_setup[i].drb_id,
|
0xFFFF, // We will set the right value from DU answer
|
||||||
0xFFFF, // We will set the right value from DU answer
|
-1, // no qfi
|
||||||
addr,
|
addr,
|
||||||
f1ap_ue_context_modification_req->drbs_to_be_setup[i].up_dl_tnl[0].port,
|
f1ap_ue_context_modification_req->drbs_to_be_setup[i].up_dl_tnl[0].port,
|
||||||
cu_f1u_data_req);
|
cu_f1u_data_req,
|
||||||
|
NULL);
|
||||||
/* 12.3.1 ULTunnels_ToBeSetup_Item */
|
/* 12.3.1 ULTunnels_ToBeSetup_Item */
|
||||||
asn1cSequenceAdd(drbs_toBeSetupMod_item->uLUPTNLInformation_ToBeSetup_List.list,
|
asn1cSequenceAdd(drbs_toBeSetupMod_item->uLUPTNLInformation_ToBeSetup_List.list,
|
||||||
F1AP_ULUPTNLInformation_ToBeSetup_Item_t, uLUPTNLInformation_ToBeSetup_Item);
|
F1AP_ULUPTNLInformation_ToBeSetup_Item_t, uLUPTNLInformation_ToBeSetup_Item);
|
||||||
|
|||||||
@@ -187,14 +187,16 @@ int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t instance,
|
|||||||
transport_layer_addr_t addr;
|
transport_layer_addr_t addr;
|
||||||
memcpy(addr.buffer, &drb_p->up_ul_tnl[0].tl_address, sizeof(drb_p->up_ul_tnl[0].tl_address));
|
memcpy(addr.buffer, &drb_p->up_ul_tnl[0].tl_address, sizeof(drb_p->up_ul_tnl[0].tl_address));
|
||||||
addr.length=sizeof(drb_p->up_ul_tnl[0].tl_address)*8;
|
addr.length=sizeof(drb_p->up_ul_tnl[0].tl_address)*8;
|
||||||
drb_p->up_dl_tnl[0].teid=newGtpuCreateTunnel(INSTANCE_DEFAULT,
|
drb_p->up_dl_tnl[0].teid = newGtpuCreateTunnel(INSTANCE_DEFAULT,
|
||||||
f1ap_ue_context_setup_req->rnti,
|
f1ap_ue_context_setup_req->rnti,
|
||||||
drb_p->drb_id,
|
drb_p->drb_id,
|
||||||
drb_p->drb_id,
|
drb_p->drb_id,
|
||||||
drb_p->up_ul_tnl[0].teid,
|
drb_p->up_ul_tnl[0].teid,
|
||||||
addr,
|
-1, // no qfi
|
||||||
drb_p->up_ul_tnl[0].port,
|
addr,
|
||||||
lteDURecvCb);
|
drb_p->up_ul_tnl[0].port,
|
||||||
|
lteDURecvCb,
|
||||||
|
NULL);
|
||||||
drb_p->up_dl_tnl_length++;
|
drb_p->up_dl_tnl_length++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1171,14 +1173,16 @@ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance,
|
|||||||
transport_layer_addr_t addr;
|
transport_layer_addr_t addr;
|
||||||
memcpy(addr.buffer, &drb_p->up_ul_tnl[0].tl_address, sizeof(drb_p->up_ul_tnl[0].tl_address));
|
memcpy(addr.buffer, &drb_p->up_ul_tnl[0].tl_address, sizeof(drb_p->up_ul_tnl[0].tl_address));
|
||||||
addr.length=sizeof(drb_p->up_ul_tnl[0].tl_address)*8;
|
addr.length=sizeof(drb_p->up_ul_tnl[0].tl_address)*8;
|
||||||
drb_p->up_dl_tnl[0].teid=newGtpuCreateTunnel(INSTANCE_DEFAULT,
|
drb_p->up_dl_tnl[0].teid = newGtpuCreateTunnel(INSTANCE_DEFAULT,
|
||||||
f1ap_ue_context_modification_req->rnti,
|
f1ap_ue_context_modification_req->rnti,
|
||||||
drb_p->drb_id,
|
drb_p->drb_id,
|
||||||
drb_p->drb_id,
|
drb_p->drb_id,
|
||||||
drb_p->up_ul_tnl[0].teid,
|
drb_p->up_ul_tnl[0].teid,
|
||||||
addr,
|
-1, // no qfi
|
||||||
drb_p->up_ul_tnl[0].port,
|
addr,
|
||||||
lteDURecvCb);
|
drb_p->up_ul_tnl[0].port,
|
||||||
|
lteDURecvCb,
|
||||||
|
NULL);
|
||||||
drb_p->up_dl_tnl_length++;
|
drb_p->up_dl_tnl_length++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,7 +67,8 @@
|
|||||||
#define CONFIG_STRING_MACRLC_UL_BLER_TARGET_UPPER "ul_bler_target_upper"
|
#define CONFIG_STRING_MACRLC_UL_BLER_TARGET_UPPER "ul_bler_target_upper"
|
||||||
#define CONFIG_STRING_MACRLC_UL_BLER_TARGET_LOWER "ul_bler_target_lower"
|
#define CONFIG_STRING_MACRLC_UL_BLER_TARGET_LOWER "ul_bler_target_lower"
|
||||||
#define CONFIG_STRING_MACRLC_UL_MAX_MCS "ul_max_mcs"
|
#define CONFIG_STRING_MACRLC_UL_MAX_MCS "ul_max_mcs"
|
||||||
#define CONFIG_STRING_MACRLC_HARQ_ROUND_MAX "harq_round_max"
|
#define CONFIG_STRING_MACRLC_DL_HARQ_ROUND_MAX "dl_harq_round_max"
|
||||||
|
#define CONFIG_STRING_MACRLC_UL_HARQ_ROUND_MAX "ul_harq_round_max"
|
||||||
#define CONFIG_STRING_MACRLC_MIN_GRANT_PRB "min_grant_prb"
|
#define CONFIG_STRING_MACRLC_MIN_GRANT_PRB "min_grant_prb"
|
||||||
#define CONFIG_STRING_MACRLC_MIN_GRANT_MCS "min_grant_mcs"
|
#define CONFIG_STRING_MACRLC_MIN_GRANT_MCS "min_grant_mcs"
|
||||||
|
|
||||||
@@ -97,7 +98,7 @@
|
|||||||
{CONFIG_STRING_MACRLC_ULSCH_MAX_FRAME_INACTIVITY, NULL, 0, uptr:NULL, defintval:10, TYPE_UINT, 0}, \
|
{CONFIG_STRING_MACRLC_ULSCH_MAX_FRAME_INACTIVITY, NULL, 0, uptr:NULL, defintval:10, TYPE_UINT, 0}, \
|
||||||
{CONFIG_STRING_MACRLC_PUSCHTARGETSNRX10, NULL, 0, iptr:NULL, defintval:200, TYPE_INT, 0}, \
|
{CONFIG_STRING_MACRLC_PUSCHTARGETSNRX10, NULL, 0, iptr:NULL, defintval:200, TYPE_INT, 0}, \
|
||||||
{CONFIG_STRING_MACRLC_PUCCHTARGETSNRX10, NULL, 0, iptr:NULL, defintval:150, TYPE_INT, 0}, \
|
{CONFIG_STRING_MACRLC_PUCCHTARGETSNRX10, NULL, 0, iptr:NULL, defintval:150, TYPE_INT, 0}, \
|
||||||
{CONFIG_STRING_MACRLC_UL_PRBBLACK_SNR_THRESHOLD, "SNR threshold to decide whether a PRB will be blacklisted or not", 0, iptr:NULL, defintval:10, TYPE_INT, 0}, \
|
{CONFIG_STRING_MACRLC_UL_PRBBLACK_SNR_THRESHOLD, "SNR threshold to decide whether a PRB will be blacklisted or not", 0, iptr:NULL, defintval:10, TYPE_INT, 0}, \
|
||||||
{CONFIG_STRING_MACRLC_PUCCHFAILURETHRES, NULL, 0, iptr:NULL, defintval:10, TYPE_INT, 0}, \
|
{CONFIG_STRING_MACRLC_PUCCHFAILURETHRES, NULL, 0, iptr:NULL, defintval:10, TYPE_INT, 0}, \
|
||||||
{CONFIG_STRING_MACRLC_PUSCHFAILURETHRES, NULL, 0, iptr:NULL, defintval:10, TYPE_INT, 0}, \
|
{CONFIG_STRING_MACRLC_PUSCHFAILURETHRES, NULL, 0, iptr:NULL, defintval:10, TYPE_INT, 0}, \
|
||||||
{CONFIG_STRING_MACRLC_DL_BLER_TARGET_UPPER, "Upper threshold of BLER to decrease DL MCS", 0, dblptr:NULL, defdblval:0.15, TYPE_DOUBLE, 0}, \
|
{CONFIG_STRING_MACRLC_DL_BLER_TARGET_UPPER, "Upper threshold of BLER to decrease DL MCS", 0, dblptr:NULL, defdblval:0.15, TYPE_DOUBLE, 0}, \
|
||||||
@@ -106,9 +107,10 @@
|
|||||||
{CONFIG_STRING_MACRLC_UL_BLER_TARGET_UPPER, "Upper threshold of BLER to decrease UL MCS", 0, dblptr:NULL, defdblval:0.15, TYPE_DOUBLE, 0}, \
|
{CONFIG_STRING_MACRLC_UL_BLER_TARGET_UPPER, "Upper threshold of BLER to decrease UL MCS", 0, dblptr:NULL, defdblval:0.15, TYPE_DOUBLE, 0}, \
|
||||||
{CONFIG_STRING_MACRLC_UL_BLER_TARGET_LOWER, "Lower threshold of BLER to increase UL MCS", 0, dblptr:NULL, defdblval:0.05, TYPE_DOUBLE, 0}, \
|
{CONFIG_STRING_MACRLC_UL_BLER_TARGET_LOWER, "Lower threshold of BLER to increase UL MCS", 0, dblptr:NULL, defdblval:0.05, TYPE_DOUBLE, 0}, \
|
||||||
{CONFIG_STRING_MACRLC_UL_MAX_MCS, "Maximum UL MCS that should be used", 0, u8ptr:NULL, defintval:9, TYPE_UINT8, 0}, \
|
{CONFIG_STRING_MACRLC_UL_MAX_MCS, "Maximum UL MCS that should be used", 0, u8ptr:NULL, defintval:9, TYPE_UINT8, 0}, \
|
||||||
{CONFIG_STRING_MACRLC_HARQ_ROUND_MAX, "Maximum number of HARQ rounds", 0, u8ptr:NULL, defintval:4, TYPE_UINT8, 0}, \
|
{CONFIG_STRING_MACRLC_DL_HARQ_ROUND_MAX, "Maximum number of DL HARQ rounds", 0, u8ptr:NULL, defintval:4, TYPE_UINT8, 0}, \
|
||||||
|
{CONFIG_STRING_MACRLC_UL_HARQ_ROUND_MAX, "Maximum number of UL HARQ rounds", 0, u8ptr:NULL, defintval:4, TYPE_UINT8, 0}, \
|
||||||
{CONFIG_STRING_MACRLC_MIN_GRANT_PRB, "Minimal Periodic ULSCH Grant PRBs", 0, u8ptr:NULL, defintval:5, TYPE_UINT8, 0}, \
|
{CONFIG_STRING_MACRLC_MIN_GRANT_PRB, "Minimal Periodic ULSCH Grant PRBs", 0, u8ptr:NULL, defintval:5, TYPE_UINT8, 0}, \
|
||||||
{CONFIG_STRING_MACRLC_MIN_GRANT_MCS, "Minimal Periodic ULSCH Grant MCS", 0, u8ptr:NULL, defintval:9, TYPE_UINT8, 0} \
|
{CONFIG_STRING_MACRLC_MIN_GRANT_MCS, "Minimal Periodic ULSCH Grant MCS", 0, u8ptr:NULL, defintval:9, TYPE_UINT8, 0}, \
|
||||||
}
|
}
|
||||||
#define MACRLC_CC_IDX 0
|
#define MACRLC_CC_IDX 0
|
||||||
#define MACRLC_TRANSPORT_N_PREFERENCE_IDX 1
|
#define MACRLC_TRANSPORT_N_PREFERENCE_IDX 1
|
||||||
@@ -139,9 +141,46 @@
|
|||||||
#define MACRLC_UL_BLER_TARGET_UPPER_IDX 26
|
#define MACRLC_UL_BLER_TARGET_UPPER_IDX 26
|
||||||
#define MACRLC_UL_BLER_TARGET_LOWER_IDX 27
|
#define MACRLC_UL_BLER_TARGET_LOWER_IDX 27
|
||||||
#define MACRLC_UL_MAX_MCS_IDX 28
|
#define MACRLC_UL_MAX_MCS_IDX 28
|
||||||
#define MACRLC_HARQ_ROUND_MAX_IDX 29
|
#define MACRLC_DL_HARQ_ROUND_MAX_IDX 29
|
||||||
#define MACRLC_MIN_GRANT_PRB_IDX 30
|
#define MACRLC_UL_HARQ_ROUND_MAX_IDX 30
|
||||||
#define MACRLC_MIN_GRANT_MCS_IDX 31
|
#define MACRLC_MIN_GRANT_PRB_IDX 31
|
||||||
|
#define MACRLC_MIN_GRANT_MCS_IDX 32
|
||||||
|
|
||||||
|
#define MACRLCPARAMS_CHECK { \
|
||||||
|
{ .s5 = { NULL } }, \
|
||||||
|
{ .s5 = { NULL } }, \
|
||||||
|
{ .s5 = { NULL } }, \
|
||||||
|
{ .s5 = { NULL } }, \
|
||||||
|
{ .s5 = { NULL } }, \
|
||||||
|
{ .s5 = { NULL } }, \
|
||||||
|
{ .s5 = { NULL } }, \
|
||||||
|
{ .s5 = { NULL } }, \
|
||||||
|
{ .s5 = { NULL } }, \
|
||||||
|
{ .s5 = { NULL } }, \
|
||||||
|
{ .s5 = { NULL } }, \
|
||||||
|
{ .s5 = { NULL } }, \
|
||||||
|
{ .s5 = { NULL } }, \
|
||||||
|
{ .s5 = { NULL } }, \
|
||||||
|
{ .s5 = { NULL } }, \
|
||||||
|
{ .s5 = { NULL } }, \
|
||||||
|
{ .s5 = { NULL } }, \
|
||||||
|
{ .s5 = { NULL } }, \
|
||||||
|
{ .s5 = { NULL } }, \
|
||||||
|
{ .s5 = { NULL } }, \
|
||||||
|
{ .s5 = { NULL } }, \
|
||||||
|
{ .s5 = { NULL } }, \
|
||||||
|
{ .s5 = { NULL } }, \
|
||||||
|
{ .s5 = { NULL } }, \
|
||||||
|
{ .s5 = { NULL } }, \
|
||||||
|
{ .s5 = { NULL } }, \
|
||||||
|
{ .s5 = { NULL } }, \
|
||||||
|
{ .s5 = { NULL } }, \
|
||||||
|
{ .s5 = { NULL } }, \
|
||||||
|
{ .s2 = { config_check_intrange, {1, 8} } }, /* DL max HARQ rounds */ \
|
||||||
|
{ .s2 = { config_check_intrange, {1, 8} } }, /* UL max HARQ rounds */ \
|
||||||
|
{ .s5 = { NULL } }, \
|
||||||
|
{ .s5 = { NULL } }, \
|
||||||
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -816,6 +816,10 @@ void RCconfig_nr_macrlc() {
|
|||||||
}
|
}
|
||||||
paramdef_t MacRLC_Params[] = MACRLCPARAMS_DESC;
|
paramdef_t MacRLC_Params[] = MACRLCPARAMS_DESC;
|
||||||
paramlist_def_t MacRLC_ParamList = {CONFIG_STRING_MACRLC_LIST,NULL,0};
|
paramlist_def_t MacRLC_ParamList = {CONFIG_STRING_MACRLC_LIST,NULL,0};
|
||||||
|
/* map parameter checking array instances to parameter definition array instances */
|
||||||
|
checkedparam_t config_check_MacRLCParams [] = MACRLCPARAMS_CHECK;
|
||||||
|
for (int i = 0; i < sizeof(MacRLC_Params) / sizeof(paramdef_t); ++i)
|
||||||
|
MacRLC_Params[i].chkPptr = &(config_check_MacRLCParams[i]);
|
||||||
config_getlist( &MacRLC_ParamList,MacRLC_Params,sizeof(MacRLC_Params)/sizeof(paramdef_t), NULL);
|
config_getlist( &MacRLC_ParamList,MacRLC_Params,sizeof(MacRLC_Params)/sizeof(paramdef_t), NULL);
|
||||||
|
|
||||||
if ( MacRLC_ParamList.numelt > 0) {
|
if ( MacRLC_ParamList.numelt > 0) {
|
||||||
@@ -887,11 +891,12 @@ void RCconfig_nr_macrlc() {
|
|||||||
dl_bler_options->upper = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_BLER_TARGET_UPPER_IDX].dblptr);
|
dl_bler_options->upper = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_BLER_TARGET_UPPER_IDX].dblptr);
|
||||||
dl_bler_options->lower = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_BLER_TARGET_LOWER_IDX].dblptr);
|
dl_bler_options->lower = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_BLER_TARGET_LOWER_IDX].dblptr);
|
||||||
dl_bler_options->max_mcs = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_MAX_MCS_IDX].u8ptr);
|
dl_bler_options->max_mcs = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_MAX_MCS_IDX].u8ptr);
|
||||||
|
dl_bler_options->harq_round_max = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_HARQ_ROUND_MAX_IDX].u8ptr);
|
||||||
NR_bler_options_t *ul_bler_options = &RC.nrmac[j]->ul_bler;
|
NR_bler_options_t *ul_bler_options = &RC.nrmac[j]->ul_bler;
|
||||||
ul_bler_options->upper = *(MacRLC_ParamList.paramarray[j][MACRLC_UL_BLER_TARGET_UPPER_IDX].dblptr);
|
ul_bler_options->upper = *(MacRLC_ParamList.paramarray[j][MACRLC_UL_BLER_TARGET_UPPER_IDX].dblptr);
|
||||||
ul_bler_options->lower = *(MacRLC_ParamList.paramarray[j][MACRLC_UL_BLER_TARGET_LOWER_IDX].dblptr);
|
ul_bler_options->lower = *(MacRLC_ParamList.paramarray[j][MACRLC_UL_BLER_TARGET_LOWER_IDX].dblptr);
|
||||||
ul_bler_options->max_mcs = *(MacRLC_ParamList.paramarray[j][MACRLC_UL_MAX_MCS_IDX].u8ptr);
|
ul_bler_options->max_mcs = *(MacRLC_ParamList.paramarray[j][MACRLC_UL_MAX_MCS_IDX].u8ptr);
|
||||||
RC.nrmac[j]->harq_round_max = *(MacRLC_ParamList.paramarray[j][MACRLC_HARQ_ROUND_MAX_IDX].u8ptr);
|
ul_bler_options->harq_round_max = *(MacRLC_ParamList.paramarray[j][MACRLC_UL_HARQ_ROUND_MAX_IDX].u8ptr);
|
||||||
RC.nrmac[j]->min_grant_prb = *(MacRLC_ParamList.paramarray[j][MACRLC_MIN_GRANT_PRB_IDX].u8ptr);
|
RC.nrmac[j]->min_grant_prb = *(MacRLC_ParamList.paramarray[j][MACRLC_MIN_GRANT_PRB_IDX].u8ptr);
|
||||||
RC.nrmac[j]->min_grant_mcs = *(MacRLC_ParamList.paramarray[j][MACRLC_MIN_GRANT_MCS_IDX].u8ptr);
|
RC.nrmac[j]->min_grant_mcs = *(MacRLC_ParamList.paramarray[j][MACRLC_MIN_GRANT_MCS_IDX].u8ptr);
|
||||||
RC.nrmac[j]->num_ulprbbl = num_prbbl;
|
RC.nrmac[j]->num_ulprbbl = num_prbbl;
|
||||||
|
|||||||
@@ -158,9 +158,9 @@ typedef enum {
|
|||||||
{GNB_CONFIG_STRING_NRCELLID, NULL, 0, u64ptr:NULL, defint64val:1, TYPE_UINT64, 0}, \
|
{GNB_CONFIG_STRING_NRCELLID, NULL, 0, u64ptr:NULL, defint64val:1, TYPE_UINT64, 0}, \
|
||||||
{GNB_CONFIG_STRING_MINRXTXTIME, NULL, 0, iptr:NULL, defintval:2, TYPE_INT, 0}, \
|
{GNB_CONFIG_STRING_MINRXTXTIME, NULL, 0, iptr:NULL, defintval:2, TYPE_INT, 0}, \
|
||||||
{GNB_CONFIG_STRING_ULPRBBLACKLIST, NULL, 0, strptr:NULL, defstrval:"", TYPE_STRING, 0}, \
|
{GNB_CONFIG_STRING_ULPRBBLACKLIST, NULL, 0, strptr:NULL, defstrval:"", TYPE_STRING, 0}, \
|
||||||
{GNB_CONFIG_STRING_UMONDEFAULTDRB, NULL, 0, uptr:NULL, defuintval:0, TYPE_UINT, 0}, \
|
{GNB_CONFIG_STRING_UMONDEFAULTDRB, NULL, 0, uptr:NULL, defuintval:0, TYPE_UINT, 0}, \
|
||||||
{GNB_CONFIG_STRING_FORCE256QAMOFF, GNB_CONFIG_HLP_FORCE256QAMOFF, PARAMFLAG_BOOL, iptr:NULL, defintval:0, TYPE_INT, 0}, \
|
{GNB_CONFIG_STRING_FORCE256QAMOFF, GNB_CONFIG_HLP_FORCE256QAMOFF, PARAMFLAG_BOOL, iptr:NULL, defintval:0, TYPE_INT, 0}, \
|
||||||
{GNB_CONFIG_STRING_ENABLE_SDAP, GNB_CONFIG_HLP_STRING_ENABLE_SDAP, PARAMFLAG_BOOL, iptr:NULL, defintval:0, TYPE_INT, 0} \
|
{GNB_CONFIG_STRING_ENABLE_SDAP, GNB_CONFIG_HLP_STRING_ENABLE_SDAP, PARAMFLAG_BOOL, iptr:NULL, defintval:0, TYPE_INT, 0}, \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define GNB_GNB_ID_IDX 0
|
#define GNB_GNB_ID_IDX 0
|
||||||
|
|||||||
@@ -2366,22 +2366,6 @@ rrc_mac_remove_ue(module_id_t mod_idP,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
* Returns the previous UE_id in the scheduling list in UL or DL
|
|
||||||
*/
|
|
||||||
inline int prev(UE_list_t *listP, int nodeP) {
|
|
||||||
if (nodeP == listP->head)
|
|
||||||
return -1; /* there is no previous of the head */
|
|
||||||
|
|
||||||
for (int j = listP->head; j >= 0; j = listP->next[j])
|
|
||||||
if (listP->next[j] == nodeP)
|
|
||||||
return j;
|
|
||||||
|
|
||||||
LOG_E(MAC, "%s(): could not find previous to %d in UE_list\n", __func__, nodeP);
|
|
||||||
dump_ue_list(listP);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This has to be updated to include BSR information
|
// This has to be updated to include BSR information
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -329,17 +329,7 @@ rx_sdu(const module_id_t enb_mod_idP,
|
|||||||
if (ra->msg3_round >= mac->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx - 1) {
|
if (ra->msg3_round >= mac->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx - 1) {
|
||||||
|
|
||||||
// Release RNTI of LTE PHY when RA does not succeed
|
// Release RNTI of LTE PHY when RA does not succeed
|
||||||
UE_free_list_t *free_list = NULL;
|
put_UE_in_freelist(enb_mod_idP, current_rnti, true);
|
||||||
pthread_mutex_lock(&lock_ue_freelist);
|
|
||||||
free_list = &mac->UE_free_list;
|
|
||||||
free_list->UE_free_ctrl[free_list->tail_freelist].rnti = current_rnti;
|
|
||||||
free_list->UE_free_ctrl[free_list->tail_freelist].removeContextFlg = 1;
|
|
||||||
free_list->UE_free_ctrl[free_list->tail_freelist].raFlag = 1;
|
|
||||||
free_list->num_UEs++;
|
|
||||||
mac->UE_release_req.ue_release_request_body.ue_release_request_TLVs_list[mac->UE_release_req.ue_release_request_body.number_of_TLVs].rnti = current_rnti;
|
|
||||||
mac->UE_release_req.ue_release_request_body.number_of_TLVs++;
|
|
||||||
free_list->tail_freelist = (free_list->tail_freelist + 1) % (NUMBER_OF_UE_MAX+1);
|
|
||||||
pthread_mutex_unlock(&lock_ue_freelist);
|
|
||||||
|
|
||||||
cancel_ra_proc(enb_mod_idP, CC_idP, frameP, current_rnti);
|
cancel_ra_proc(enb_mod_idP, CC_idP, frameP, current_rnti);
|
||||||
nfapi_hi_dci0_request_t *hi_dci0_req = NULL;
|
nfapi_hi_dci0_request_t *hi_dci0_req = NULL;
|
||||||
|
|||||||
@@ -1195,14 +1195,6 @@ typedef struct {
|
|||||||
///remove RA flag
|
///remove RA flag
|
||||||
bool raFlag;
|
bool raFlag;
|
||||||
} UE_free_ctrl_t;
|
} UE_free_ctrl_t;
|
||||||
/*! \brief REMOVE UE list used by eNB to order UEs/CC for deleting*/
|
|
||||||
typedef struct {
|
|
||||||
/// deleting control info
|
|
||||||
UE_free_ctrl_t UE_free_ctrl[NUMBER_OF_UE_MAX+1];
|
|
||||||
int num_UEs;
|
|
||||||
int head_freelist; ///the head position of the delete list
|
|
||||||
int tail_freelist; ///the tail position of the delete list
|
|
||||||
} UE_free_list_t;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* describes contiguous RBs
|
* describes contiguous RBs
|
||||||
@@ -1443,7 +1435,7 @@ typedef struct eNB_MAC_INST_s {
|
|||||||
/// processing time of eNB PCH scheduler
|
/// processing time of eNB PCH scheduler
|
||||||
time_stats_t schedule_pch;
|
time_stats_t schedule_pch;
|
||||||
|
|
||||||
UE_free_list_t UE_free_list;
|
UE_free_ctrl_t UE_free_ctrl[NUMBER_OF_UE_MAX+1];
|
||||||
/// for scheduling selection
|
/// for scheduling selection
|
||||||
SCHEDULER_MODES scheduler_mode;
|
SCHEDULER_MODES scheduler_mode;
|
||||||
/// Default scheduler: Pre-processor implementation. Algorithms for UL/DL
|
/// Default scheduler: Pre-processor implementation. Algorithms for UL/DL
|
||||||
|
|||||||
@@ -39,6 +39,7 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#include "NR_SubcarrierSpacing.h"
|
#include "NR_SubcarrierSpacing.h"
|
||||||
|
#include "NR_CSI-ReportConfig.h"
|
||||||
#include "openair1/SCHED_NR_UE/harq_nr.h"
|
#include "openair1/SCHED_NR_UE/harq_nr.h"
|
||||||
|
|
||||||
#define NR_SHORT_BSR_TABLE_SIZE 32
|
#define NR_SHORT_BSR_TABLE_SIZE 32
|
||||||
@@ -63,6 +64,7 @@
|
|||||||
#define CCCH_PAYLOAD_SIZE_MAX 512
|
#define CCCH_PAYLOAD_SIZE_MAX 512
|
||||||
#define RAR_PAYLOAD_SIZE_MAX 128
|
#define RAR_PAYLOAD_SIZE_MAX 128
|
||||||
#define MAX_BWP_SIZE 275
|
#define MAX_BWP_SIZE 275
|
||||||
|
#define MAX_CSI_REPORTCONFIG 48
|
||||||
|
|
||||||
typedef enum frequency_range_e {
|
typedef enum frequency_range_e {
|
||||||
FR1 = 0,
|
FR1 = 0,
|
||||||
@@ -512,5 +514,37 @@ typedef struct Type0_PDCCH_CSS_config_s {
|
|||||||
bool active;
|
bool active;
|
||||||
} NR_Type0_PDCCH_CSS_config_t;
|
} NR_Type0_PDCCH_CSS_config_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t nb_ssbri_cri;
|
||||||
|
uint8_t cri_ssbri_bitlen;
|
||||||
|
uint8_t rsrp_bitlen;
|
||||||
|
uint8_t diff_rsrp_bitlen;
|
||||||
|
} L1_RSRP_bitlen_t;
|
||||||
|
|
||||||
|
typedef struct{
|
||||||
|
uint8_t ri_restriction;
|
||||||
|
uint8_t cri_bitlen;
|
||||||
|
uint8_t ri_bitlen;
|
||||||
|
uint8_t li_bitlen[8];
|
||||||
|
uint8_t pmi_x1_bitlen[8];
|
||||||
|
uint8_t pmi_x2_bitlen[8];
|
||||||
|
uint8_t cqi_bitlen[8];
|
||||||
|
} CSI_Meas_bitlen_t;
|
||||||
|
|
||||||
|
typedef struct nr_csi_report {
|
||||||
|
NR_CSI_ReportConfig__reportQuantity_PR reportQuantity_type;
|
||||||
|
long periodicity;
|
||||||
|
uint16_t offset;
|
||||||
|
long ** SSB_Index_list;
|
||||||
|
long ** CSI_Index_list;
|
||||||
|
// uint8_t nb_of_nzp_csi_report;
|
||||||
|
uint8_t nb_of_csi_ssb_report;
|
||||||
|
L1_RSRP_bitlen_t CSI_report_bitlen;
|
||||||
|
CSI_Meas_bitlen_t csi_meas_bitlen;
|
||||||
|
int codebook_mode;
|
||||||
|
int N1;
|
||||||
|
int N2;
|
||||||
|
} nr_csi_report_t;
|
||||||
|
|
||||||
#endif /*__LAYER2_MAC_H__ */
|
#endif /*__LAYER2_MAC_H__ */
|
||||||
|
|
||||||
|
|||||||
@@ -4221,3 +4221,521 @@ bool set_ul_ptrs_values(NR_PTRS_UplinkConfig_t *ul_ptrs_config,
|
|||||||
}
|
}
|
||||||
return valid;
|
return valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! Calculating number of bits set
|
||||||
|
uint8_t number_of_bits_set(uint8_t buf) {
|
||||||
|
uint8_t nb_of_bits_set = 0;
|
||||||
|
uint8_t mask = 0xff;
|
||||||
|
uint8_t index = 0;
|
||||||
|
|
||||||
|
for (index=7; (buf & mask) && (index>=0) ; index--){
|
||||||
|
if (buf & (1<<index))
|
||||||
|
nb_of_bits_set++;
|
||||||
|
|
||||||
|
mask>>=1;
|
||||||
|
}
|
||||||
|
return nb_of_bits_set;
|
||||||
|
}
|
||||||
|
|
||||||
|
void compute_rsrp_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||||
|
uint8_t nb_resources,
|
||||||
|
nr_csi_report_t *csi_report) {
|
||||||
|
|
||||||
|
if (NR_CSI_ReportConfig__groupBasedBeamReporting_PR_disabled == csi_reportconfig->groupBasedBeamReporting.present) {
|
||||||
|
if (NULL != csi_reportconfig->groupBasedBeamReporting.choice.disabled->nrofReportedRS)
|
||||||
|
csi_report->CSI_report_bitlen.nb_ssbri_cri = *(csi_reportconfig->groupBasedBeamReporting.choice.disabled->nrofReportedRS)+1;
|
||||||
|
else
|
||||||
|
/*! From Spec 38.331
|
||||||
|
* nrofReportedRS
|
||||||
|
* The number (N) of measured RS resources to be reported per report setting in a non-group-based report. N <= N_max, where N_max is either 2 or 4 depending on UE
|
||||||
|
* capability. FFS: The signaling mechanism for the gNB to select a subset of N beams for the UE to measure and report.
|
||||||
|
* When the field is absent the UE applies the value 1
|
||||||
|
*/
|
||||||
|
csi_report->CSI_report_bitlen.nb_ssbri_cri= 1;
|
||||||
|
} else
|
||||||
|
csi_report->CSI_report_bitlen.nb_ssbri_cri= 2;
|
||||||
|
|
||||||
|
if (nb_resources) {
|
||||||
|
csi_report->CSI_report_bitlen.cri_ssbri_bitlen =ceil(log2 (nb_resources));
|
||||||
|
csi_report->CSI_report_bitlen.rsrp_bitlen = 7; //From spec 38.212 Table 6.3.1.1.2-6: CRI, SSBRI, and RSRP
|
||||||
|
csi_report->CSI_report_bitlen.diff_rsrp_bitlen =4; //From spec 38.212 Table 6.3.1.1.2-6: CRI, SSBRI, and RSRP
|
||||||
|
} else {
|
||||||
|
csi_report->CSI_report_bitlen.cri_ssbri_bitlen =0;
|
||||||
|
csi_report->CSI_report_bitlen.rsrp_bitlen = 0;
|
||||||
|
csi_report->CSI_report_bitlen.diff_rsrp_bitlen =0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t compute_ri_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||||
|
nr_csi_report_t *csi_report) {
|
||||||
|
|
||||||
|
struct NR_CodebookConfig *codebookConfig = csi_reportconfig->codebookConfig;
|
||||||
|
uint8_t nb_allowed_ri, ri_bitlen;
|
||||||
|
uint8_t ri_restriction = 0;
|
||||||
|
|
||||||
|
if (codebookConfig == NULL) {
|
||||||
|
csi_report->csi_meas_bitlen.ri_bitlen=0;
|
||||||
|
return ri_restriction;
|
||||||
|
}
|
||||||
|
|
||||||
|
// codebook type1 single panel
|
||||||
|
if (NR_CodebookConfig__codebookType__type1__subType_PR_typeI_SinglePanel==codebookConfig->codebookType.choice.type1->subType.present){
|
||||||
|
struct NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel *type1single = codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel;
|
||||||
|
if (type1single->nrOfAntennaPorts.present == NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts_PR_two){
|
||||||
|
|
||||||
|
ri_restriction = csi_reportconfig->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.buf[0];
|
||||||
|
|
||||||
|
nb_allowed_ri = number_of_bits_set(ri_restriction);
|
||||||
|
ri_bitlen = ceil(log2(nb_allowed_ri));
|
||||||
|
|
||||||
|
ri_bitlen = ri_bitlen<1?ri_bitlen:1; //from the spec 38.212 and table 6.3.1.1.2-3: RI, LI, CQI, and CRI of codebookType=typeI-SinglePanel
|
||||||
|
csi_report->csi_meas_bitlen.ri_bitlen=ri_bitlen;
|
||||||
|
}
|
||||||
|
if (type1single->nrOfAntennaPorts.present == NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts_PR_moreThanTwo){
|
||||||
|
if (type1single->nrOfAntennaPorts.choice.moreThanTwo->n1_n2.present ==
|
||||||
|
NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_two_one_TypeI_SinglePanel_Restriction) {
|
||||||
|
// 4 ports
|
||||||
|
|
||||||
|
ri_restriction = csi_reportconfig->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.buf[0];
|
||||||
|
|
||||||
|
nb_allowed_ri = number_of_bits_set(ri_restriction);
|
||||||
|
ri_bitlen = ceil(log2(nb_allowed_ri));
|
||||||
|
|
||||||
|
ri_bitlen = ri_bitlen<2?ri_bitlen:2; //from the spec 38.212 and table 6.3.1.1.2-3: RI, LI, CQI, and CRI of codebookType=typeI-SinglePanel
|
||||||
|
csi_report->csi_meas_bitlen.ri_bitlen=ri_bitlen;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// more than 4 ports
|
||||||
|
|
||||||
|
ri_restriction = csi_reportconfig->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.buf[0];
|
||||||
|
|
||||||
|
nb_allowed_ri = number_of_bits_set(ri_restriction);
|
||||||
|
ri_bitlen = ceil(log2(nb_allowed_ri));
|
||||||
|
|
||||||
|
csi_report->csi_meas_bitlen.ri_bitlen=ri_bitlen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ri_restriction;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
AssertFatal(1==0,"Other configurations not yet implemented\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void compute_li_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||||
|
uint8_t ri_restriction,
|
||||||
|
nr_csi_report_t *csi_report) {
|
||||||
|
|
||||||
|
struct NR_CodebookConfig *codebookConfig = csi_reportconfig->codebookConfig;
|
||||||
|
for(int i=0; i<8; i++) {
|
||||||
|
if (codebookConfig == NULL || ((ri_restriction>>i)&0x01) == 0)
|
||||||
|
csi_report->csi_meas_bitlen.li_bitlen[i]=0;
|
||||||
|
else {
|
||||||
|
// codebook type1 single panel
|
||||||
|
if (NR_CodebookConfig__codebookType__type1__subType_PR_typeI_SinglePanel==codebookConfig->codebookType.choice.type1->subType.present)
|
||||||
|
csi_report->csi_meas_bitlen.li_bitlen[i]=ceil(log2(i+1))<2?ceil(log2(i+1)):2;
|
||||||
|
else
|
||||||
|
AssertFatal(1==0,"Other configurations not yet implemented\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void get_n1n2_o1o2_singlepanel(int *n1, int *n2, int *o1, int *o2,
|
||||||
|
struct NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo *morethantwo) {
|
||||||
|
|
||||||
|
// Table 5.2.2.2.1-2 in 38.214 for supported configurations
|
||||||
|
switch(morethantwo->n1_n2.present){
|
||||||
|
case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_two_one_TypeI_SinglePanel_Restriction):
|
||||||
|
*n1 = 2;
|
||||||
|
*n2 = 1;
|
||||||
|
*o1 = 4;
|
||||||
|
*o2 = 1;
|
||||||
|
break;
|
||||||
|
case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_two_two_TypeI_SinglePanel_Restriction):
|
||||||
|
*n1 = 2;
|
||||||
|
*n2 = 2;
|
||||||
|
*o1 = 4;
|
||||||
|
*o2 = 4;
|
||||||
|
break;
|
||||||
|
case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_four_one_TypeI_SinglePanel_Restriction):
|
||||||
|
*n1 = 4;
|
||||||
|
*n2 = 1;
|
||||||
|
*o1 = 4;
|
||||||
|
*o2 = 1;
|
||||||
|
break;
|
||||||
|
case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_three_two_TypeI_SinglePanel_Restriction):
|
||||||
|
*n1 = 3;
|
||||||
|
*n2 = 2;
|
||||||
|
*o1 = 4;
|
||||||
|
*o2 = 4;
|
||||||
|
break;
|
||||||
|
case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_six_one_TypeI_SinglePanel_Restriction):
|
||||||
|
*n1 = 6;
|
||||||
|
*n2 = 1;
|
||||||
|
*o1 = 4;
|
||||||
|
*o2 = 1;
|
||||||
|
break;
|
||||||
|
case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_four_two_TypeI_SinglePanel_Restriction):
|
||||||
|
*n1 = 4;
|
||||||
|
*n2 = 2;
|
||||||
|
*o1 = 4;
|
||||||
|
*o2 = 4;
|
||||||
|
break;
|
||||||
|
case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_eight_one_TypeI_SinglePanel_Restriction):
|
||||||
|
*n1 = 8;
|
||||||
|
*n2 = 1;
|
||||||
|
*o1 = 4;
|
||||||
|
*o2 = 1;
|
||||||
|
break;
|
||||||
|
case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_four_three_TypeI_SinglePanel_Restriction):
|
||||||
|
*n1 = 4;
|
||||||
|
*n2 = 3;
|
||||||
|
*o1 = 4;
|
||||||
|
*o2 = 4;
|
||||||
|
break;
|
||||||
|
case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_six_two_TypeI_SinglePanel_Restriction):
|
||||||
|
*n1 = 4;
|
||||||
|
*n2 = 2;
|
||||||
|
*o1 = 4;
|
||||||
|
*o2 = 4;
|
||||||
|
break;
|
||||||
|
case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_twelve_one_TypeI_SinglePanel_Restriction):
|
||||||
|
*n1 = 12;
|
||||||
|
*n2 = 1;
|
||||||
|
*o1 = 4;
|
||||||
|
*o2 = 1;
|
||||||
|
break;
|
||||||
|
case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_four_four_TypeI_SinglePanel_Restriction):
|
||||||
|
*n1 = 4;
|
||||||
|
*n2 = 4;
|
||||||
|
*o1 = 4;
|
||||||
|
*o2 = 4;
|
||||||
|
break;
|
||||||
|
case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_eight_two_TypeI_SinglePanel_Restriction):
|
||||||
|
*n1 = 8;
|
||||||
|
*n2 = 2;
|
||||||
|
*o1 = 4;
|
||||||
|
*o2 = 4;
|
||||||
|
break;
|
||||||
|
case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_sixteen_one_TypeI_SinglePanel_Restriction):
|
||||||
|
*n1 = 16;
|
||||||
|
*n2 = 1;
|
||||||
|
*o1 = 4;
|
||||||
|
*o2 = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
AssertFatal(1==0,"Not supported configuration for n1_n2 in codebook configuration");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void get_x1x2_bitlen_singlepanel(int n1, int n2, int o1, int o2,
|
||||||
|
int *x1, int *x2, int rank, int codebook_mode) {
|
||||||
|
|
||||||
|
// Table 6.3.1.1.2-1 in 38.212
|
||||||
|
switch(rank){
|
||||||
|
case 1:
|
||||||
|
if(n2>1) {
|
||||||
|
if (codebook_mode == 1) {
|
||||||
|
*x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2));
|
||||||
|
*x2 = 2;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*x1 = ceil(log2(n1*o1/2)) + ceil(log2(n2*o2/2));
|
||||||
|
*x2 = 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
if (codebook_mode == 1) {
|
||||||
|
*x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2));
|
||||||
|
*x2 = 2;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*x1 = ceil(log2(n1*o1/2));
|
||||||
|
*x2 = 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if(n1*n2 == 2) {
|
||||||
|
if (codebook_mode == 1) {
|
||||||
|
*x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2));
|
||||||
|
*x2 = 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*x1 = ceil(log2(n1*o1/2));
|
||||||
|
*x2 = 3;
|
||||||
|
}
|
||||||
|
*x1 += 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(n2>1) {
|
||||||
|
if (codebook_mode == 1) {
|
||||||
|
*x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2));
|
||||||
|
*x2 = 3;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*x1 = ceil(log2(n1*o1/2)) + ceil(log2(n2*o2/2));
|
||||||
|
*x2 = 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
if (codebook_mode == 1) {
|
||||||
|
*x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2));
|
||||||
|
*x2 = 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*x1 = ceil(log2(n1*o1/2));
|
||||||
|
*x2 = 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*x1 += 2;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
case 4:
|
||||||
|
if(n1*n2 == 2) {
|
||||||
|
*x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2));
|
||||||
|
*x2 = 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(n1*n2 >= 8) {
|
||||||
|
*x1 = ceil(log2(n1*o1/2)) + ceil(log2(n2*o2)) + 2;
|
||||||
|
*x2 = 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2)) + 2;
|
||||||
|
*x2 = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
case 6:
|
||||||
|
*x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2));
|
||||||
|
*x2 = 1;
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
case 8:
|
||||||
|
if(n1 == 4 && n2 == 1) {
|
||||||
|
*x1 = ceil(log2(n1*o1/2)) + ceil(log2(n2*o2));
|
||||||
|
*x2 = 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(n1 > 2 && n2 == 2) {
|
||||||
|
*x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2/2));
|
||||||
|
*x2 = 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2));
|
||||||
|
*x2 = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
AssertFatal(1==0,"Invalid rank in x1 x2 bit length computation\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void compute_pmi_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||||
|
uint8_t ri_restriction,
|
||||||
|
nr_csi_report_t *csi_report) {
|
||||||
|
|
||||||
|
struct NR_CodebookConfig *codebookConfig = csi_reportconfig->codebookConfig;
|
||||||
|
for(int i=0; i<8; i++) {
|
||||||
|
csi_report->csi_meas_bitlen.pmi_x1_bitlen[i]=0;
|
||||||
|
csi_report->csi_meas_bitlen.pmi_x2_bitlen[i]=0;
|
||||||
|
if (codebookConfig == NULL || ((ri_restriction>>i)&0x01) == 0)
|
||||||
|
return;
|
||||||
|
else {
|
||||||
|
if(codebookConfig->codebookType.present == NR_CodebookConfig__codebookType_PR_type1) {
|
||||||
|
if(codebookConfig->codebookType.choice.type1->subType.present == NR_CodebookConfig__codebookType__type1__subType_PR_typeI_SinglePanel) {
|
||||||
|
if(codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.present ==
|
||||||
|
NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts_PR_two) {
|
||||||
|
csi_report->N1 = 1;
|
||||||
|
csi_report->N2 = 1;
|
||||||
|
if (i==0)
|
||||||
|
csi_report->csi_meas_bitlen.pmi_x2_bitlen[i]=2;
|
||||||
|
if (i==1)
|
||||||
|
csi_report->csi_meas_bitlen.pmi_x2_bitlen[i]=1;
|
||||||
|
}
|
||||||
|
else { // more than two
|
||||||
|
int n1,n2,o1,o2,x1,x2;
|
||||||
|
get_n1n2_o1o2_singlepanel(&n1,&n2,&o1,&o2,codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.moreThanTwo);
|
||||||
|
get_x1x2_bitlen_singlepanel(n1,n2,o1,o2,&x1,&x2,i+1,codebookConfig->codebookType.choice.type1->codebookMode);
|
||||||
|
csi_report->N1 = n1;
|
||||||
|
csi_report->N2 = n2;
|
||||||
|
csi_report->codebook_mode = codebookConfig->codebookType.choice.type1->codebookMode;
|
||||||
|
csi_report->csi_meas_bitlen.pmi_x1_bitlen[i]=x1;
|
||||||
|
csi_report->csi_meas_bitlen.pmi_x2_bitlen[i]=x2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
AssertFatal(1==0,"Type1 Multi-panel Codebook Config not yet implemented\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
AssertFatal(1==0,"Type2 Codebook Config not yet implemented\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void compute_cqi_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||||
|
uint8_t ri_restriction,
|
||||||
|
nr_csi_report_t *csi_report) {
|
||||||
|
|
||||||
|
struct NR_CodebookConfig *codebookConfig = csi_reportconfig->codebookConfig;
|
||||||
|
struct NR_CSI_ReportConfig__reportFreqConfiguration *freq_config = csi_reportconfig->reportFreqConfiguration;
|
||||||
|
|
||||||
|
if (*freq_config->cqi_FormatIndicator == NR_CSI_ReportConfig__reportFreqConfiguration__cqi_FormatIndicator_widebandCQI) {
|
||||||
|
for(int i=0; i<8; i++) {
|
||||||
|
if ((ri_restriction>>i)&0x01) {
|
||||||
|
csi_report->csi_meas_bitlen.cqi_bitlen[i] = 4;
|
||||||
|
if(codebookConfig != NULL) {
|
||||||
|
if (NR_CodebookConfig__codebookType__type1__subType_PR_typeI_SinglePanel == codebookConfig->codebookType.choice.type1->subType.present){
|
||||||
|
struct NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel *type1single = codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel;
|
||||||
|
if (type1single->nrOfAntennaPorts.present == NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts_PR_moreThanTwo) {
|
||||||
|
if (type1single->nrOfAntennaPorts.choice.moreThanTwo->n1_n2.present >
|
||||||
|
NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_two_one_TypeI_SinglePanel_Restriction) {
|
||||||
|
// more than 4 antenna ports
|
||||||
|
if (i > 4)
|
||||||
|
csi_report->csi_meas_bitlen.cqi_bitlen[i] += 4; // CQI for second TB
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
csi_report->csi_meas_bitlen.cqi_bitlen[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
AssertFatal(1==0,"Sub-band CQI reporting not yet supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
//!TODO : same function can be written to handle csi_resources
|
||||||
|
void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, nr_csi_report_t *csi_report_template) {
|
||||||
|
uint8_t csi_report_id = 0;
|
||||||
|
uint8_t nb_resources = 0;
|
||||||
|
NR_CSI_ReportConfig__reportQuantity_PR reportQuantity_type;
|
||||||
|
NR_CSI_ResourceConfigId_t csi_ResourceConfigId;
|
||||||
|
struct NR_CSI_ResourceConfig *csi_resourceconfig;
|
||||||
|
|
||||||
|
// for each CSI measurement report configuration (list of CSI-ReportConfig)
|
||||||
|
LOG_D(NR_MAC,"Searching %d csi_reports\n",csi_MeasConfig->csi_ReportConfigToAddModList->list.count);
|
||||||
|
for (csi_report_id=0; csi_report_id < csi_MeasConfig->csi_ReportConfigToAddModList->list.count; csi_report_id++){
|
||||||
|
struct NR_CSI_ReportConfig *csi_reportconfig = csi_MeasConfig->csi_ReportConfigToAddModList->list.array[csi_report_id];
|
||||||
|
// MAC structure for CSI measurement reports (per UE and per report)
|
||||||
|
nr_csi_report_t *csi_report = &csi_report_template[csi_report_id];
|
||||||
|
// csi-ResourceConfigId of a CSI-ResourceConfig included in the configuration
|
||||||
|
// (either CSI-RS or SSB)
|
||||||
|
csi_ResourceConfigId = csi_reportconfig->resourcesForChannelMeasurement;
|
||||||
|
// looking for CSI-ResourceConfig
|
||||||
|
int found_resource = 0;
|
||||||
|
int csi_resourceidx = 0;
|
||||||
|
while (found_resource == 0 && csi_resourceidx < csi_MeasConfig->csi_ResourceConfigToAddModList->list.count) {
|
||||||
|
csi_resourceconfig = csi_MeasConfig->csi_ResourceConfigToAddModList->list.array[csi_resourceidx];
|
||||||
|
if ( csi_resourceconfig->csi_ResourceConfigId == csi_ResourceConfigId)
|
||||||
|
found_resource = 1;
|
||||||
|
csi_resourceidx++;
|
||||||
|
}
|
||||||
|
AssertFatal(found_resource==1,"Not able to found any CSI-ResourceConfig with csi-ResourceConfigId %ld\n",
|
||||||
|
csi_ResourceConfigId);
|
||||||
|
|
||||||
|
long resourceType = csi_resourceconfig->resourceType;
|
||||||
|
|
||||||
|
reportQuantity_type = csi_reportconfig->reportQuantity.present;
|
||||||
|
csi_report->reportQuantity_type = reportQuantity_type;
|
||||||
|
|
||||||
|
// setting the CSI or SSB index list
|
||||||
|
if (NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP == csi_report->reportQuantity_type) {
|
||||||
|
for (int csi_idx = 0; csi_idx < csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.count; csi_idx++) {
|
||||||
|
if (csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_idx]->csi_SSB_ResourceSetId ==
|
||||||
|
*(csi_resourceconfig->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->csi_SSB_ResourceSetList->list.array[0])){
|
||||||
|
//We can configure only one SSB resource set from spec 38.331 IE CSI-ResourceConfig
|
||||||
|
nb_resources= csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_idx]->csi_SSB_ResourceList.list.count;
|
||||||
|
csi_report->SSB_Index_list = csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_idx]->csi_SSB_ResourceList.list.array;
|
||||||
|
csi_report->CSI_Index_list = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (resourceType == NR_CSI_ResourceConfig__resourceType_periodic) {
|
||||||
|
AssertFatal(csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList != NULL,
|
||||||
|
"Wrong settings! Report quantity requires CSI-RS but csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList is NULL\n");
|
||||||
|
for (int csi_idx = 0; csi_idx < csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.count; csi_idx++) {
|
||||||
|
if (csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.array[csi_idx]->nzp_CSI_ResourceSetId ==
|
||||||
|
*(csi_resourceconfig->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList->list.array[0])) {
|
||||||
|
//For periodic and semi-persistent CSI Resource Settings, the number of CSI-RS Resource Sets configured is limited to S=1 for spec 38.212
|
||||||
|
nb_resources = csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.array[csi_idx]->nzp_CSI_RS_Resources.list.count;
|
||||||
|
csi_report->CSI_Index_list = csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.array[csi_idx]->nzp_CSI_RS_Resources.list.array;
|
||||||
|
csi_report->SSB_Index_list = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else AssertFatal(1==0,"Only periodic resource configuration currently supported\n");
|
||||||
|
}
|
||||||
|
LOG_D(NR_MAC,"nb_resources %d\n",nb_resources);
|
||||||
|
// computation of bit length depending on the report type
|
||||||
|
switch(reportQuantity_type){
|
||||||
|
case (NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP):
|
||||||
|
compute_rsrp_bitlen(csi_reportconfig, nb_resources, csi_report);
|
||||||
|
break;
|
||||||
|
case (NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP):
|
||||||
|
compute_rsrp_bitlen(csi_reportconfig, nb_resources, csi_report);
|
||||||
|
break;
|
||||||
|
case (NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_CQI):
|
||||||
|
csi_report->csi_meas_bitlen.cri_bitlen=ceil(log2(nb_resources));
|
||||||
|
csi_report->csi_meas_bitlen.ri_restriction = compute_ri_bitlen(csi_reportconfig, csi_report);
|
||||||
|
compute_cqi_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report);
|
||||||
|
break;
|
||||||
|
case (NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_PMI_CQI):
|
||||||
|
csi_report->csi_meas_bitlen.cri_bitlen=ceil(log2(nb_resources));
|
||||||
|
csi_report->csi_meas_bitlen.ri_restriction = compute_ri_bitlen(csi_reportconfig, csi_report);
|
||||||
|
compute_cqi_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report);
|
||||||
|
compute_pmi_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report);
|
||||||
|
break;
|
||||||
|
case (NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_LI_PMI_CQI):
|
||||||
|
csi_report->csi_meas_bitlen.cri_bitlen=ceil(log2(nb_resources));
|
||||||
|
csi_report->csi_meas_bitlen.ri_restriction = compute_ri_bitlen(csi_reportconfig, csi_report);
|
||||||
|
compute_li_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report);
|
||||||
|
compute_cqi_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report);
|
||||||
|
compute_pmi_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
AssertFatal(1==0,"Not yet supported CSI report quantity type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t nr_get_csi_bitlen(nr_csi_report_t *csi_report_template, uint8_t csi_report_id) {
|
||||||
|
|
||||||
|
uint16_t csi_bitlen = 0;
|
||||||
|
uint16_t max_bitlen = 0;
|
||||||
|
L1_RSRP_bitlen_t *CSI_report_bitlen = NULL;
|
||||||
|
CSI_Meas_bitlen_t *csi_meas_bitlen = NULL;
|
||||||
|
|
||||||
|
if (csi_report_template[csi_report_id].reportQuantity_type == NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP ||
|
||||||
|
csi_report_template[csi_report_id].reportQuantity_type == NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP) {
|
||||||
|
CSI_report_bitlen = &(csi_report_template[csi_report_id].CSI_report_bitlen); // This might need to be moodif for Aperiodic CSI-RS measurements
|
||||||
|
csi_bitlen += ((CSI_report_bitlen->cri_ssbri_bitlen * CSI_report_bitlen->nb_ssbri_cri) +
|
||||||
|
CSI_report_bitlen->rsrp_bitlen +(CSI_report_bitlen->diff_rsrp_bitlen *
|
||||||
|
(CSI_report_bitlen->nb_ssbri_cri -1 )));
|
||||||
|
} else {
|
||||||
|
csi_meas_bitlen = &(csi_report_template[csi_report_id].csi_meas_bitlen); //This might need to be moodif for Aperiodic CSI-RS measurements
|
||||||
|
uint16_t temp_bitlen;
|
||||||
|
for (int i=0; i<8; i++) {
|
||||||
|
temp_bitlen = (csi_meas_bitlen->cri_bitlen+
|
||||||
|
csi_meas_bitlen->ri_bitlen+
|
||||||
|
csi_meas_bitlen->li_bitlen[i]+
|
||||||
|
csi_meas_bitlen->cqi_bitlen[i]+
|
||||||
|
csi_meas_bitlen->pmi_x1_bitlen[i]+
|
||||||
|
csi_meas_bitlen->pmi_x2_bitlen[i]);
|
||||||
|
if(temp_bitlen>max_bitlen)
|
||||||
|
max_bitlen = temp_bitlen;
|
||||||
|
}
|
||||||
|
csi_bitlen += max_bitlen;
|
||||||
|
}
|
||||||
|
|
||||||
|
return csi_bitlen;
|
||||||
|
}
|
||||||
@@ -105,7 +105,7 @@ uint8_t get_pusch_mcs_table(long *mcs_Table,
|
|||||||
uint8_t compute_nr_root_seq(NR_RACH_ConfigCommon_t *rach_config,
|
uint8_t compute_nr_root_seq(NR_RACH_ConfigCommon_t *rach_config,
|
||||||
uint8_t nb_preambles,
|
uint8_t nb_preambles,
|
||||||
uint8_t unpaired,
|
uint8_t unpaired,
|
||||||
frequency_range_t);
|
frequency_range_t);
|
||||||
|
|
||||||
int ul_ant_bits(NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig,long transformPrecoder);
|
int ul_ant_bits(NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig,long transformPrecoder);
|
||||||
|
|
||||||
@@ -234,4 +234,36 @@ void nr_mac_gNB_rrc_ul_failure_reset(const module_id_t Mod_instP,
|
|||||||
const frame_t frameP,
|
const frame_t frameP,
|
||||||
const sub_frame_t subframeP,
|
const sub_frame_t subframeP,
|
||||||
const rnti_t rntiP);
|
const rnti_t rntiP);
|
||||||
|
|
||||||
|
uint8_t number_of_bits_set(uint8_t buf);
|
||||||
|
|
||||||
|
void compute_rsrp_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||||
|
uint8_t nb_resources,
|
||||||
|
nr_csi_report_t *csi_report);
|
||||||
|
|
||||||
|
uint8_t compute_ri_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||||
|
nr_csi_report_t *csi_report);
|
||||||
|
|
||||||
|
void compute_li_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||||
|
uint8_t ri_restriction,
|
||||||
|
nr_csi_report_t *csi_report);
|
||||||
|
|
||||||
|
void get_n1n2_o1o2_singlepanel(int *n1, int *n2, int *o1, int *o2,
|
||||||
|
struct NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo *morethantwo);
|
||||||
|
|
||||||
|
void get_x1x2_bitlen_singlepanel(int n1, int n2, int o1, int o2,
|
||||||
|
int *x1, int *x2, int rank, int codebook_mode);
|
||||||
|
|
||||||
|
void compute_pmi_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||||
|
uint8_t ri_restriction,
|
||||||
|
nr_csi_report_t *csi_report);
|
||||||
|
|
||||||
|
void compute_cqi_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||||
|
uint8_t ri_restriction,
|
||||||
|
nr_csi_report_t *csi_report);
|
||||||
|
|
||||||
|
void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, nr_csi_report_t *csi_report_template);
|
||||||
|
|
||||||
|
uint16_t nr_get_csi_bitlen(nr_csi_report_t *csi_report_template, uint8_t csi_report_id);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -190,7 +190,7 @@ void config_common_ue_sa(NR_UE_MAC_INST_t *mac,
|
|||||||
cfg->ssb_table.ssb_subcarrier_offset = mac->ssb_subcarrier_offset;
|
cfg->ssb_table.ssb_subcarrier_offset = mac->ssb_subcarrier_offset;
|
||||||
|
|
||||||
if (mac->frequency_range == FR1){
|
if (mac->frequency_range == FR1){
|
||||||
cfg->ssb_table.ssb_mask_list[0].ssb_mask = scc->ssb_PositionsInBurst.inOneGroup.buf[0]<<24;
|
cfg->ssb_table.ssb_mask_list[0].ssb_mask = ((uint32_t) scc->ssb_PositionsInBurst.inOneGroup.buf[0]) << 24;
|
||||||
cfg->ssb_table.ssb_mask_list[1].ssb_mask = 0;
|
cfg->ssb_table.ssb_mask_list[1].ssb_mask = 0;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
@@ -353,7 +353,7 @@ void config_common_ue(NR_UE_MAC_INST_t *mac,
|
|||||||
cfg->ssb_table.ssb_mask_list[1].ssb_mask = 0;
|
cfg->ssb_table.ssb_mask_list[1].ssb_mask = 0;
|
||||||
break;
|
break;
|
||||||
case 2 :
|
case 2 :
|
||||||
cfg->ssb_table.ssb_mask_list[0].ssb_mask = scc->ssb_PositionsInBurst->choice.mediumBitmap.buf[0]<<24;
|
cfg->ssb_table.ssb_mask_list[0].ssb_mask = ((uint32_t) scc->ssb_PositionsInBurst->choice.mediumBitmap.buf[0]) << 24;
|
||||||
cfg->ssb_table.ssb_mask_list[1].ssb_mask = 0;
|
cfg->ssb_table.ssb_mask_list[1].ssb_mask = 0;
|
||||||
break;
|
break;
|
||||||
case 3 :
|
case 3 :
|
||||||
|
|||||||
@@ -399,6 +399,11 @@ typedef struct {
|
|||||||
/// measured SSB RSRP in dBm
|
/// measured SSB RSRP in dBm
|
||||||
short ssb_rsrp_dBm;
|
short ssb_rsrp_dBm;
|
||||||
|
|
||||||
|
nr_csi_report_t csi_report_template[MAX_CSI_REPORTCONFIG];
|
||||||
|
|
||||||
|
/// measurements from CSI-RS
|
||||||
|
fapi_nr_csirs_measurements_t csirs_measurements;
|
||||||
|
|
||||||
/// Last NDI of UL HARQ processes
|
/// Last NDI of UL HARQ processes
|
||||||
uint8_t UL_ndi[NR_MAX_HARQ_PROCESSES];
|
uint8_t UL_ndi[NR_MAX_HARQ_PROCESSES];
|
||||||
/// first ULTX of UL HARQ processes
|
/// first ULTX of UL HARQ processes
|
||||||
|
|||||||
@@ -194,6 +194,7 @@ int nr_get_sf_retxBSRTimer(uint8_t retxBSR_Timer);
|
|||||||
|
|
||||||
int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, frame_t frame, int slot, dci_pdu_rel15_t *dci, fapi_nr_dci_indication_pdu_t *dci_ind);
|
int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, frame_t frame, int slot, dci_pdu_rel15_t *dci, fapi_nr_dci_indication_pdu_t *dci_ind);
|
||||||
int nr_ue_process_dci_indication_pdu(module_id_t module_id, int cc_id, int gNB_index, frame_t frame, int slot, fapi_nr_dci_indication_pdu_t *dci);
|
int nr_ue_process_dci_indication_pdu(module_id_t module_id, int cc_id, int gNB_index, frame_t frame, int slot, fapi_nr_dci_indication_pdu_t *dci);
|
||||||
|
int8_t nr_ue_process_csirs_measurements(module_id_t module_id, frame_t frame, int slot, fapi_nr_csirs_measurements_t *csirs_measurements);
|
||||||
|
|
||||||
uint32_t get_ssb_frame(uint32_t test);
|
uint32_t get_ssb_frame(uint32_t test);
|
||||||
|
|
||||||
@@ -213,6 +214,18 @@ uint8_t get_ssb_rsrp_payload(NR_UE_MAC_INST_t *mac,
|
|||||||
NR_CSI_ResourceConfigId_t csi_ResourceConfigId,
|
NR_CSI_ResourceConfigId_t csi_ResourceConfigId,
|
||||||
NR_CSI_MeasConfig_t *csi_MeasConfig);
|
NR_CSI_MeasConfig_t *csi_MeasConfig);
|
||||||
|
|
||||||
|
uint8_t get_csirs_RI_PMI_CQI_payload(NR_UE_MAC_INST_t *mac,
|
||||||
|
PUCCH_sched_t *pucch,
|
||||||
|
struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||||
|
NR_CSI_ResourceConfigId_t csi_ResourceConfigId,
|
||||||
|
NR_CSI_MeasConfig_t *csi_MeasConfig);
|
||||||
|
|
||||||
|
uint8_t get_csirs_RSRP_payload(NR_UE_MAC_INST_t *mac,
|
||||||
|
PUCCH_sched_t *pucch,
|
||||||
|
struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||||
|
NR_CSI_ResourceConfigId_t csi_ResourceConfigId,
|
||||||
|
NR_CSI_MeasConfig_t *csi_MeasConfig);
|
||||||
|
|
||||||
uint8_t nr_get_csi_payload(NR_UE_MAC_INST_t *mac,
|
uint8_t nr_get_csi_payload(NR_UE_MAC_INST_t *mac,
|
||||||
PUCCH_sched_t *pucch,
|
PUCCH_sched_t *pucch,
|
||||||
int csi_report_id,
|
int csi_report_id,
|
||||||
@@ -257,13 +270,6 @@ void get_bwp_info(NR_UE_MAC_INST_t *mac,
|
|||||||
|
|
||||||
NR_BWP_DownlinkCommon_t *get_bwp_downlink_common(NR_UE_MAC_INST_t *mac, NR_BWP_Id_t dl_bwp_id);
|
NR_BWP_DownlinkCommon_t *get_bwp_downlink_common(NR_UE_MAC_INST_t *mac, NR_BWP_Id_t dl_bwp_id);
|
||||||
|
|
||||||
uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
|
|
||||||
uint8_t dci_format,
|
|
||||||
uint8_t dci_length,
|
|
||||||
uint16_t rnti,
|
|
||||||
uint64_t *dci_pdu,
|
|
||||||
dci_pdu_rel15_t *nr_pdci_info_extracted);
|
|
||||||
|
|
||||||
NR_PUSCH_TimeDomainResourceAllocationList_t *choose_ul_tda_list(const NR_PUSCH_Config_t *pusch_Config,NR_PUSCH_ConfigCommon_t *pusch_ConfigCommon);
|
NR_PUSCH_TimeDomainResourceAllocationList_t *choose_ul_tda_list(const NR_PUSCH_Config_t *pusch_Config,NR_PUSCH_ConfigCommon_t *pusch_ConfigCommon);
|
||||||
NR_PDSCH_TimeDomainResourceAllocationList_t *choose_dl_tda_list(NR_PDSCH_Config_t *pdsch_Config,NR_PDSCH_ConfigCommon_t *pdsch_ConfigCommon);
|
NR_PDSCH_TimeDomainResourceAllocationList_t *choose_dl_tda_list(NR_PDSCH_Config_t *pdsch_Config,NR_PDSCH_ConfigCommon_t *pdsch_ConfigCommon);
|
||||||
|
|
||||||
|
|||||||
@@ -134,6 +134,13 @@ const initial_pucch_resource_t initial_pucch_resource[16] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
|
||||||
|
uint8_t dci_format,
|
||||||
|
uint8_t dci_length,
|
||||||
|
uint16_t rnti,
|
||||||
|
uint64_t *dci_pdu,
|
||||||
|
dci_pdu_rel15_t *nr_pdci_info_extracted);
|
||||||
|
|
||||||
void nr_ue_init_mac(module_id_t module_idP) {
|
void nr_ue_init_mac(module_id_t module_idP) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@@ -985,7 +992,8 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
|
|||||||
if (dci->tpc == 3) dlsch_config_pdu_1_0->accumulated_delta_PUCCH = 3;
|
if (dci->tpc == 3) dlsch_config_pdu_1_0->accumulated_delta_PUCCH = 3;
|
||||||
// Sanity check for pucch_resource_indicator value received to check for false DCI.
|
// Sanity check for pucch_resource_indicator value received to check for false DCI.
|
||||||
valid = 0;
|
valid = 0;
|
||||||
if (mac->ULbwp[ul_bwp_id-1] &&
|
if (ul_bwp_id > 0 &&
|
||||||
|
mac->ULbwp[ul_bwp_id-1] &&
|
||||||
mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated &&
|
mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated &&
|
||||||
mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pucch_Config &&
|
mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pucch_Config &&
|
||||||
mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup&&
|
mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup&&
|
||||||
@@ -1454,6 +1462,16 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int8_t nr_ue_process_csirs_measurements(module_id_t module_id,
|
||||||
|
frame_t frame,
|
||||||
|
int slot,
|
||||||
|
fapi_nr_csirs_measurements_t *csirs_measurements) {
|
||||||
|
LOG_D(NR_MAC,"(%d.%d) Received CSI-RS measurements\n", frame, slot);
|
||||||
|
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
|
||||||
|
memcpy(&mac->csirs_measurements, csirs_measurements, sizeof(*csirs_measurements));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void set_harq_status(NR_UE_MAC_INST_t *mac,
|
void set_harq_status(NR_UE_MAC_INST_t *mac,
|
||||||
uint8_t pucch_id,
|
uint8_t pucch_id,
|
||||||
uint8_t harq_id,
|
uint8_t harq_id,
|
||||||
@@ -1512,13 +1530,12 @@ void nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac,
|
|||||||
NR_BWP_UplinkCommon_t *initialUplinkBWP;
|
NR_BWP_UplinkCommon_t *initialUplinkBWP;
|
||||||
if (mac->scc) initialUplinkBWP = mac->scc->uplinkConfigCommon->initialUplinkBWP;
|
if (mac->scc) initialUplinkBWP = mac->scc->uplinkConfigCommon->initialUplinkBWP;
|
||||||
else initialUplinkBWP = &mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP;
|
else initialUplinkBWP = &mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP;
|
||||||
NR_BWP_Uplink_t *ubwp = mac->ULbwp[bwp_id-1];
|
if (mac->cg && bwp_id > 1 && mac->ULbwp[bwp_id - 1] &&
|
||||||
if (mac->cg && ubwp &&
|
|
||||||
mac->cg->spCellConfig &&
|
mac->cg->spCellConfig &&
|
||||||
mac->cg->spCellConfig->spCellConfigDedicated &&
|
mac->cg->spCellConfig->spCellConfigDedicated &&
|
||||||
mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig &&
|
mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig &&
|
||||||
mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP) {
|
mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP) {
|
||||||
scs = ubwp->bwp_Common->genericParameters.subcarrierSpacing;
|
scs = mac->ULbwp[bwp_id - 1]->bwp_Common->genericParameters.subcarrierSpacing;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
scs = initialUplinkBWP->genericParameters.subcarrierSpacing;
|
scs = initialUplinkBWP->genericParameters.subcarrierSpacing;
|
||||||
@@ -2340,17 +2357,16 @@ bool trigger_periodic_scheduling_request(NR_UE_MAC_INST_t *mac,
|
|||||||
NR_BWP_Id_t bwp_id = mac->UL_BWP_Id;
|
NR_BWP_Id_t bwp_id = mac->UL_BWP_Id;
|
||||||
NR_PUCCH_Config_t *pucch_Config = NULL;
|
NR_PUCCH_Config_t *pucch_Config = NULL;
|
||||||
int scs;
|
int scs;
|
||||||
NR_BWP_Uplink_t *ubwp = mac->ULbwp[bwp_id-1];
|
|
||||||
NR_BWP_UplinkCommon_t *initialUplinkBWP;
|
NR_BWP_UplinkCommon_t *initialUplinkBWP;
|
||||||
if (mac->scc) initialUplinkBWP = mac->scc->uplinkConfigCommon->initialUplinkBWP;
|
if (mac->scc) initialUplinkBWP = mac->scc->uplinkConfigCommon->initialUplinkBWP;
|
||||||
else initialUplinkBWP = &mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP;
|
else initialUplinkBWP = &mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP;
|
||||||
|
|
||||||
if (mac->cg && ubwp &&
|
if (mac->cg && bwp_id && mac->ULbwp[bwp_id - 1] &&
|
||||||
mac->cg->spCellConfig &&
|
mac->cg->spCellConfig &&
|
||||||
mac->cg->spCellConfig->spCellConfigDedicated &&
|
mac->cg->spCellConfig->spCellConfigDedicated &&
|
||||||
mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig &&
|
mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig &&
|
||||||
mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP) {
|
mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP) {
|
||||||
scs = ubwp->bwp_Common->genericParameters.subcarrierSpacing;
|
scs = mac->ULbwp[bwp_id - 1]->bwp_Common->genericParameters.subcarrierSpacing;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
scs = initialUplinkBWP->genericParameters.subcarrierSpacing;
|
scs = initialUplinkBWP->genericParameters.subcarrierSpacing;
|
||||||
@@ -2558,13 +2574,17 @@ uint8_t nr_get_csi_payload(NR_UE_MAC_INST_t *mac,
|
|||||||
case NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP:
|
case NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP:
|
||||||
n_csi_bits = get_ssb_rsrp_payload(mac,pucch,csi_reportconfig,csi_ResourceConfigId,csi_MeasConfig);
|
n_csi_bits = get_ssb_rsrp_payload(mac,pucch,csi_reportconfig,csi_ResourceConfigId,csi_MeasConfig);
|
||||||
break;
|
break;
|
||||||
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP:
|
|
||||||
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_PMI_CQI:
|
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_PMI_CQI:
|
||||||
|
n_csi_bits = get_csirs_RI_PMI_CQI_payload(mac,pucch,csi_reportconfig,csi_ResourceConfigId,csi_MeasConfig);
|
||||||
|
break;
|
||||||
|
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP:
|
||||||
|
n_csi_bits = get_csirs_RSRP_payload(mac,pucch,csi_reportconfig,csi_ResourceConfigId,csi_MeasConfig);
|
||||||
|
break;
|
||||||
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_i1:
|
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_i1:
|
||||||
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_i1_CQI:
|
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_i1_CQI:
|
||||||
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_CQI:
|
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_CQI:
|
||||||
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_LI_PMI_CQI:
|
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_LI_PMI_CQI:
|
||||||
LOG_E(NR_MAC,"Measurement report based on CSI-RS not available\n");
|
LOG_E(NR_MAC,"Measurement report %d based on CSI-RS is not available\n", csi_reportconfig->reportQuantity.present);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
AssertFatal(1==0,"Invalid CSI report quantity type %d\n",csi_reportconfig->reportQuantity.present);
|
AssertFatal(1==0,"Invalid CSI report quantity type %d\n",csi_reportconfig->reportQuantity.present);
|
||||||
@@ -2652,6 +2672,122 @@ uint8_t get_ssb_rsrp_payload(NR_UE_MAC_INST_t *mac,
|
|||||||
return bits;
|
return bits;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t get_csirs_RI_PMI_CQI_payload(NR_UE_MAC_INST_t *mac,
|
||||||
|
PUCCH_sched_t *pucch,
|
||||||
|
struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||||
|
NR_CSI_ResourceConfigId_t csi_ResourceConfigId,
|
||||||
|
NR_CSI_MeasConfig_t *csi_MeasConfig) {
|
||||||
|
|
||||||
|
int n_bits = 0;
|
||||||
|
uint32_t temp_payload = 0;
|
||||||
|
|
||||||
|
for (int csi_resourceidx = 0; csi_resourceidx < csi_MeasConfig->csi_ResourceConfigToAddModList->list.count; csi_resourceidx++) {
|
||||||
|
|
||||||
|
struct NR_CSI_ResourceConfig *csi_resourceconfig = csi_MeasConfig->csi_ResourceConfigToAddModList->list.array[csi_resourceidx];
|
||||||
|
if (csi_resourceconfig->csi_ResourceConfigId == csi_ResourceConfigId) {
|
||||||
|
|
||||||
|
for (int csi_idx = 0; csi_idx < csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.count; csi_idx++) {
|
||||||
|
if (csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.array[csi_idx]->nzp_CSI_ResourceSetId ==
|
||||||
|
*(csi_resourceconfig->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList->list.array[0])) {
|
||||||
|
|
||||||
|
nr_csi_report_t *csi_report = &mac->csi_report_template[csi_reportconfig->reportConfigId];
|
||||||
|
compute_csi_bitlen(csi_MeasConfig, mac->csi_report_template);
|
||||||
|
n_bits = nr_get_csi_bitlen(mac->csi_report_template, csi_reportconfig->reportConfigId);
|
||||||
|
|
||||||
|
int cri_bitlen = csi_report->csi_meas_bitlen.cri_bitlen;
|
||||||
|
int ri_bitlen = csi_report->csi_meas_bitlen.ri_bitlen;
|
||||||
|
int pmi_x1_bitlen = csi_report->csi_meas_bitlen.pmi_x1_bitlen[mac->csirs_measurements.rank_indicator];
|
||||||
|
int pmi_x2_bitlen = csi_report->csi_meas_bitlen.pmi_x2_bitlen[mac->csirs_measurements.rank_indicator];
|
||||||
|
int cqi_bitlen = csi_report->csi_meas_bitlen.cqi_bitlen[mac->csirs_measurements.rank_indicator];
|
||||||
|
int padding_bitlen = n_bits - (cri_bitlen + ri_bitlen + pmi_x1_bitlen + pmi_x2_bitlen + cqi_bitlen);
|
||||||
|
|
||||||
|
// TODO: Improvements will be needed to cri_bitlen>0 and pmi_x1_bitlen>0
|
||||||
|
temp_payload = (mac->csirs_measurements.rank_indicator<<(cri_bitlen+cqi_bitlen+pmi_x2_bitlen+padding_bitlen+pmi_x1_bitlen)) |
|
||||||
|
(mac->csirs_measurements.i1<<(cri_bitlen+cqi_bitlen+pmi_x2_bitlen)) |
|
||||||
|
(mac->csirs_measurements.i2<<(cri_bitlen+cqi_bitlen)) |
|
||||||
|
(mac->csirs_measurements.cqi<<cri_bitlen) |
|
||||||
|
0;
|
||||||
|
|
||||||
|
reverse_n_bits((uint8_t *)&temp_payload, n_bits);
|
||||||
|
|
||||||
|
LOG_D(NR_MAC, "cri_bitlen = %d\n", cri_bitlen);
|
||||||
|
LOG_D(NR_MAC, "ri_bitlen = %d\n", ri_bitlen);
|
||||||
|
LOG_D(NR_MAC, "pmi_x1_bitlen = %d\n", pmi_x1_bitlen);
|
||||||
|
LOG_D(NR_MAC, "pmi_x2_bitlen = %d\n", pmi_x2_bitlen);
|
||||||
|
LOG_D(NR_MAC, "cqi_bitlen = %d\n", cqi_bitlen);
|
||||||
|
LOG_D(NR_MAC, "csi_part1_payload = 0x%x\n", temp_payload);
|
||||||
|
|
||||||
|
LOG_D(NR_MAC, "n_bits = %d\n", n_bits);
|
||||||
|
LOG_D(NR_MAC, "csi_part1_payload = 0x%x\n", temp_payload);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pucch->csi_part1_payload = temp_payload;
|
||||||
|
return n_bits;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t get_csirs_RSRP_payload(NR_UE_MAC_INST_t *mac,
|
||||||
|
PUCCH_sched_t *pucch,
|
||||||
|
struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||||
|
NR_CSI_ResourceConfigId_t csi_ResourceConfigId,
|
||||||
|
NR_CSI_MeasConfig_t *csi_MeasConfig) {
|
||||||
|
|
||||||
|
int n_bits = 0;
|
||||||
|
uint32_t temp_payload = 0;
|
||||||
|
|
||||||
|
for (int csi_resourceidx = 0; csi_resourceidx < csi_MeasConfig->csi_ResourceConfigToAddModList->list.count; csi_resourceidx++) {
|
||||||
|
|
||||||
|
struct NR_CSI_ResourceConfig *csi_resourceconfig = csi_MeasConfig->csi_ResourceConfigToAddModList->list.array[csi_resourceidx];
|
||||||
|
if (csi_resourceconfig->csi_ResourceConfigId == csi_ResourceConfigId) {
|
||||||
|
|
||||||
|
for (int csi_idx = 0; csi_idx < csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.count; csi_idx++) {
|
||||||
|
if (csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.array[csi_idx]->nzp_CSI_ResourceSetId ==
|
||||||
|
*(csi_resourceconfig->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList->list.array[0])) {
|
||||||
|
|
||||||
|
nr_csi_report_t *csi_report = &mac->csi_report_template[csi_reportconfig->reportConfigId];
|
||||||
|
compute_csi_bitlen(csi_MeasConfig, mac->csi_report_template);
|
||||||
|
n_bits = nr_get_csi_bitlen(mac->csi_report_template, csi_reportconfig->reportConfigId);
|
||||||
|
|
||||||
|
int cri_ssbri_bitlen = csi_report->CSI_report_bitlen.cri_ssbri_bitlen;
|
||||||
|
int rsrp_bitlen = csi_report->CSI_report_bitlen.rsrp_bitlen;
|
||||||
|
int diff_rsrp_bitlen = csi_report->CSI_report_bitlen.diff_rsrp_bitlen;
|
||||||
|
|
||||||
|
if (cri_ssbri_bitlen > 0) {
|
||||||
|
LOG_E(NR_MAC, "Implementation for cri_ssbri_bitlen>0 is not supported yet!\n");;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Improvements will be needed to cri_ssbri_bitlen>0
|
||||||
|
// TS 38.133 - Table 10.1.6.1-1
|
||||||
|
int rsrp_dBm = mac->csirs_measurements.rsrp_dBm;
|
||||||
|
if (rsrp_dBm < -140) {
|
||||||
|
temp_payload = 16;
|
||||||
|
} else if (rsrp_dBm > -44) {
|
||||||
|
temp_payload = 113;
|
||||||
|
} else {
|
||||||
|
temp_payload = mac->csirs_measurements.rsrp_dBm + 157;
|
||||||
|
}
|
||||||
|
|
||||||
|
reverse_n_bits((uint8_t *)&temp_payload, n_bits);
|
||||||
|
|
||||||
|
LOG_D(NR_MAC, "cri_ssbri_bitlen = %d\n", cri_ssbri_bitlen);
|
||||||
|
LOG_D(NR_MAC, "rsrp_bitlen = %d\n", rsrp_bitlen);
|
||||||
|
LOG_D(NR_MAC, "diff_rsrp_bitlen = %d\n", diff_rsrp_bitlen);
|
||||||
|
|
||||||
|
LOG_D(NR_MAC, "n_bits = %d\n", n_bits);
|
||||||
|
LOG_D(NR_MAC, "csi_part1_payload = 0x%x\n", temp_payload);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pucch->csi_part1_payload = temp_payload;
|
||||||
|
return n_bits;
|
||||||
|
}
|
||||||
|
|
||||||
// returns index from RSRP
|
// returns index from RSRP
|
||||||
// according to Table 10.1.6.1-1 in 38.133
|
// according to Table 10.1.6.1-1 in 38.133
|
||||||
@@ -2732,7 +2868,7 @@ int get_n_rb(NR_UE_MAC_INST_t *mac, int rnti_type){
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
|
static uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
|
||||||
uint8_t dci_format,
|
uint8_t dci_format,
|
||||||
uint8_t dci_size,
|
uint8_t dci_size,
|
||||||
uint16_t rnti,
|
uint16_t rnti,
|
||||||
@@ -3580,7 +3716,7 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info,
|
|||||||
#endif
|
#endif
|
||||||
*/
|
*/
|
||||||
|
|
||||||
LOG_I(NR_MAC, "[%d.%d] Received TA_COMMAND %u TAGID %u CC_id %d\n", frameP, slot, ul_time_alignment->ta_command, ul_time_alignment->tag_id, CC_id);
|
LOG_I(NR_MAC, "[%d.%d] Received TA_COMMAND %u TAGID %u CC_id %d\n", frameP, slot, ul_time_alignment->ta_command, ul_time_alignment->tag_id, CC_id);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case DL_SCH_LCID_CON_RES_ID:
|
case DL_SCH_LCID_CON_RES_ID:
|
||||||
|
|||||||
@@ -118,12 +118,13 @@ long get_k2(NR_UE_MAC_INST_t *mac, uint8_t time_domain_ind) {
|
|||||||
|
|
||||||
NR_BWP_Id_t ul_bwp_id = mac->UL_BWP_Id;
|
NR_BWP_Id_t ul_bwp_id = mac->UL_BWP_Id;
|
||||||
// Get K2 from RRC configuration
|
// Get K2 from RRC configuration
|
||||||
NR_PUSCH_Config_t *pusch_config=mac->ULbwp[ul_bwp_id-1] ? mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pusch_Config->choice.setup : NULL;
|
NR_PUSCH_Config_t *pusch_config= ul_bwp_id > 0 && mac->ULbwp[ul_bwp_id-1] ? mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pusch_Config->choice.setup : NULL;
|
||||||
NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList = NULL;
|
NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList = NULL;
|
||||||
if (pusch_config && pusch_config->pusch_TimeDomainAllocationList) {
|
if (pusch_config && pusch_config->pusch_TimeDomainAllocationList) {
|
||||||
pusch_TimeDomainAllocationList = pusch_config->pusch_TimeDomainAllocationList->choice.setup;
|
pusch_TimeDomainAllocationList = pusch_config->pusch_TimeDomainAllocationList->choice.setup;
|
||||||
}
|
}
|
||||||
else if (mac->ULbwp[ul_bwp_id-1] &&
|
else if (ul_bwp_id > 0 &&
|
||||||
|
mac->ULbwp[ul_bwp_id-1] &&
|
||||||
mac->ULbwp[ul_bwp_id-1]->bwp_Common&&
|
mac->ULbwp[ul_bwp_id-1]->bwp_Common&&
|
||||||
mac->ULbwp[ul_bwp_id-1]->bwp_Common->pusch_ConfigCommon&&
|
mac->ULbwp[ul_bwp_id-1]->bwp_Common->pusch_ConfigCommon&&
|
||||||
mac->ULbwp[ul_bwp_id-1]->bwp_Common->pusch_ConfigCommon->choice.setup &&
|
mac->ULbwp[ul_bwp_id-1]->bwp_Common->pusch_ConfigCommon->choice.setup &&
|
||||||
@@ -169,7 +170,7 @@ fapi_nr_ul_config_request_t *get_ul_config_request(NR_UE_MAC_INST_t *mac, int sl
|
|||||||
// Calculate the index of the UL slot in mac->ul_config_request list. This is
|
// Calculate the index of the UL slot in mac->ul_config_request list. This is
|
||||||
// based on the TDD pattern (slot configuration period) and number of UL+mixed
|
// based on the TDD pattern (slot configuration period) and number of UL+mixed
|
||||||
// slots in the period. TS 38.213 Sec 11.1
|
// slots in the period. TS 38.213 Sec 11.1
|
||||||
int mu = mac->ULbwp[ul_bwp_id-1] ?
|
int mu = ul_bwp_id > 0 && mac->ULbwp[ul_bwp_id-1] ?
|
||||||
mac->ULbwp[ul_bwp_id-1]->bwp_Common->genericParameters.subcarrierSpacing :
|
mac->ULbwp[ul_bwp_id-1]->bwp_Common->genericParameters.subcarrierSpacing :
|
||||||
mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.genericParameters.subcarrierSpacing;
|
mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.genericParameters.subcarrierSpacing;
|
||||||
const int n = nr_slots_per_frame[mu];
|
const int n = nr_slots_per_frame[mu];
|
||||||
@@ -205,7 +206,7 @@ void ul_layers_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_con
|
|||||||
srs_config = mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->srs_Config->choice.setup;
|
srs_config = mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->srs_Config->choice.setup;
|
||||||
}
|
}
|
||||||
|
|
||||||
NR_PUSCH_Config_t *pusch_Config = mac->ULbwp[ul_bwp_id-1] ?
|
NR_PUSCH_Config_t *pusch_Config = ul_bwp_id > 0 && mac->ULbwp[ul_bwp_id-1] ?
|
||||||
mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pusch_Config->choice.setup :
|
mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pusch_Config->choice.setup :
|
||||||
(ubwpd?
|
(ubwpd?
|
||||||
ubwpd->pusch_Config->choice.setup:
|
ubwpd->pusch_Config->choice.setup:
|
||||||
@@ -361,7 +362,7 @@ void ul_ports_config(NR_UE_MAC_INST_t *mac, int *n_front_load_symb, nfapi_nr_ue_
|
|||||||
mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP)
|
mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP)
|
||||||
ubwpd = mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP;
|
ubwpd = mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP;
|
||||||
|
|
||||||
NR_PUSCH_Config_t *pusch_Config = mac->ULbwp[ul_bwp_id-1] ? mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pusch_Config->choice.setup : (ubwpd?ubwpd->pusch_Config->choice.setup:NULL);
|
NR_PUSCH_Config_t *pusch_Config = ul_bwp_id > 0 && mac->ULbwp[ul_bwp_id-1] ? mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pusch_Config->choice.setup : (ubwpd?ubwpd->pusch_Config->choice.setup:NULL);
|
||||||
AssertFatal(pusch_Config!=NULL,"pusch_Config shouldn't be null\n");
|
AssertFatal(pusch_Config!=NULL,"pusch_Config shouldn't be null\n");
|
||||||
|
|
||||||
long transformPrecoder;
|
long transformPrecoder;
|
||||||
@@ -581,7 +582,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
|
|||||||
if (rar_grant) {
|
if (rar_grant) {
|
||||||
|
|
||||||
// Note: for Msg3 or MsgA PUSCH transmission the N_PRB_oh is always set to 0
|
// Note: for Msg3 or MsgA PUSCH transmission the N_PRB_oh is always set to 0
|
||||||
NR_BWP_Uplink_t *ubwp = mac->ULbwp[ul_bwp_id-1];
|
NR_BWP_Uplink_t *ubwp = ul_bwp_id > 0 ? mac->ULbwp[ul_bwp_id - 1] : NULL;
|
||||||
NR_BWP_UplinkDedicated_t *ibwp;
|
NR_BWP_UplinkDedicated_t *ibwp;
|
||||||
int scs,abwp_start,abwp_size,startSymbolAndLength,mappingtype;
|
int scs,abwp_start,abwp_size,startSymbolAndLength,mappingtype;
|
||||||
NR_PUSCH_Config_t *pusch_Config=NULL;
|
NR_PUSCH_Config_t *pusch_Config=NULL;
|
||||||
@@ -839,11 +840,15 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
|
|||||||
mappingtype, add_pos, dmrslength,
|
mappingtype, add_pos, dmrslength,
|
||||||
pusch_config_pdu->start_symbol_index,
|
pusch_config_pdu->start_symbol_index,
|
||||||
mac->scc ? mac->scc->dmrs_TypeA_Position : mac->mib->dmrs_TypeA_Position);
|
mac->scc ? mac->scc->dmrs_TypeA_Position : mac->mib->dmrs_TypeA_Position);
|
||||||
if (mac->ULbwp[ul_bwp_id-1] && pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_disabled) {
|
if (ul_bwp_id > 0 &&
|
||||||
if (*dci_format != NR_UL_DCI_FORMAT_0_1) {
|
mac->ULbwp[ul_bwp_id - 1] &&
|
||||||
pusch_config_pdu->num_dmrs_cdm_grps_no_data = 1;
|
pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_disabled &&
|
||||||
}
|
*dci_format != NR_UL_DCI_FORMAT_0_1) {
|
||||||
} else if (*dci_format == NR_UL_DCI_FORMAT_0_0 || (mac->ULbwp[ul_bwp_id-1] && pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_enabled)) {
|
pusch_config_pdu->num_dmrs_cdm_grps_no_data = 1;
|
||||||
|
} else if (*dci_format == NR_UL_DCI_FORMAT_0_0 ||
|
||||||
|
(ul_bwp_id > 0 &&
|
||||||
|
mac->ULbwp[ul_bwp_id-1] &&
|
||||||
|
pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_enabled)) {
|
||||||
pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2;
|
pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -859,7 +864,8 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
|
|||||||
else N_PRB_oh = 0;
|
else N_PRB_oh = 0;
|
||||||
|
|
||||||
/* PTRS */
|
/* PTRS */
|
||||||
if (mac->ULbwp[ul_bwp_id-1] &&
|
if (ul_bwp_id > 0 &&
|
||||||
|
mac->ULbwp[ul_bwp_id-1] &&
|
||||||
mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated &&
|
mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated &&
|
||||||
mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pusch_Config &&
|
mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pusch_Config &&
|
||||||
mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pusch_Config->choice.setup &&
|
mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pusch_Config->choice.setup &&
|
||||||
@@ -1093,9 +1099,10 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
|
|||||||
dcireq.dl_config_req = mac->dl_config_request;
|
dcireq.dl_config_req = mac->dl_config_request;
|
||||||
|
|
||||||
fill_scheduled_response(&scheduled_response, &dcireq.dl_config_req, NULL, NULL, mod_id, cc_id, rx_frame, rx_slot, dl_info->thread_id, dl_info->phy_data);
|
fill_scheduled_response(&scheduled_response, &dcireq.dl_config_req, NULL, NULL, mod_id, cc_id, rx_frame, rx_slot, dl_info->thread_id, dl_info->phy_data);
|
||||||
if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL)
|
if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL) {
|
||||||
LOG_D(NR_MAC,"1# scheduled_response transmitted, %d, %d\n", rx_frame, rx_slot);
|
LOG_D(NR_MAC,"1# scheduled_response transmitted, %d, %d\n", rx_frame, rx_slot);
|
||||||
mac->if_module->scheduled_response(&scheduled_response);
|
mac->if_module->scheduled_response(&scheduled_response);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// this is for Msg2/Msg4
|
// this is for Msg2/Msg4
|
||||||
@@ -1564,15 +1571,14 @@ int nr_ue_pusch_scheduler(NR_UE_MAC_INST_t *mac,
|
|||||||
|
|
||||||
int delta = 0;
|
int delta = 0;
|
||||||
NR_BWP_Id_t ul_bwp_id = mac->UL_BWP_Id;
|
NR_BWP_Id_t ul_bwp_id = mac->UL_BWP_Id;
|
||||||
NR_BWP_Uplink_t *ubwp = mac->ULbwp[ul_bwp_id-1];
|
|
||||||
|
|
||||||
// Get the numerology to calculate the Tx frame and slot
|
// Get the numerology to calculate the Tx frame and slot
|
||||||
int mu = ubwp ?
|
int mu = ul_bwp_id > 0 && mac->ULbwp[ul_bwp_id-1] ?
|
||||||
ubwp->bwp_Common->genericParameters.subcarrierSpacing :
|
mac->ULbwp[ul_bwp_id-1]->bwp_Common->genericParameters.subcarrierSpacing :
|
||||||
mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.genericParameters.subcarrierSpacing;
|
mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.genericParameters.subcarrierSpacing;
|
||||||
|
|
||||||
NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList = ubwp ?
|
NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList = ul_bwp_id > 0 && mac->ULbwp[ul_bwp_id-1] ?
|
||||||
ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList:
|
mac->ULbwp[ul_bwp_id-1]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList:
|
||||||
mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
|
mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
|
||||||
// k2 as per 3GPP TS 38.214 version 15.9.0 Release 15 ch 6.1.2.1.1
|
// k2 as per 3GPP TS 38.214 version 15.9.0 Release 15 ch 6.1.2.1.1
|
||||||
// PUSCH time domain resource allocation is higher layer configured from uschTimeDomainAllocationList in either pusch-ConfigCommon
|
// PUSCH time domain resource allocation is higher layer configured from uschTimeDomainAllocationList in either pusch-ConfigCommon
|
||||||
|
|||||||
@@ -337,7 +337,7 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, int pusch_AntennaPorts,
|
|||||||
// SSB Table Configuration
|
// SSB Table Configuration
|
||||||
uint32_t absolute_diff = (*scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB - scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA);
|
uint32_t absolute_diff = (*scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB - scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA);
|
||||||
const int scaling_5khz = scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA < 600000 ? 3 : 1;
|
const int scaling_5khz = scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA < 600000 ? 3 : 1;
|
||||||
int sco = (absolute_diff*scaling_5khz) % 24;
|
int sco = (absolute_diff/scaling_5khz) % 24;
|
||||||
if(frequency_range == FR2)
|
if(frequency_range == FR2)
|
||||||
sco >>= 1; // this assumes 120kHz SCS for SSB and subCarrierSpacingCommon (only option supported by OAI for
|
sco >>= 1; // this assumes 120kHz SCS for SSB and subCarrierSpacingCommon (only option supported by OAI for
|
||||||
const int scs_scaling = frequency_range == FR2 ? 1 << (*scc->ssbSubcarrierSpacing - 2) : 1 << *scc->ssbSubcarrierSpacing;
|
const int scs_scaling = frequency_range == FR2 ? 1 << (*scc->ssbSubcarrierSpacing - 2) : 1 << *scc->ssbSubcarrierSpacing;
|
||||||
@@ -360,7 +360,7 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, int pusch_AntennaPorts,
|
|||||||
cfg->ssb_table.ssb_mask_list[1].ssb_mask.value = 0;
|
cfg->ssb_table.ssb_mask_list[1].ssb_mask.value = 0;
|
||||||
break;
|
break;
|
||||||
case 2 :
|
case 2 :
|
||||||
cfg->ssb_table.ssb_mask_list[0].ssb_mask.value = scc->ssb_PositionsInBurst->choice.mediumBitmap.buf[0]<<24;
|
cfg->ssb_table.ssb_mask_list[0].ssb_mask.value = ((uint32_t) scc->ssb_PositionsInBurst->choice.mediumBitmap.buf[0]) << 24;
|
||||||
cfg->ssb_table.ssb_mask_list[1].ssb_mask.value = 0;
|
cfg->ssb_table.ssb_mask_list[1].ssb_mask.value = 0;
|
||||||
break;
|
break;
|
||||||
case 3 :
|
case 3 :
|
||||||
|
|||||||
@@ -1090,13 +1090,16 @@ void fill_msg3_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu,
|
|||||||
pusch_pdu->vrb_to_prb_mapping = 0;
|
pusch_pdu->vrb_to_prb_mapping = 0;
|
||||||
|
|
||||||
pusch_pdu->frequency_hopping = fh;
|
pusch_pdu->frequency_hopping = fh;
|
||||||
//pusch_pdu->tx_direct_current_location;//The uplink Tx Direct Current location for the carrier. Only values in the value range of this field between 0 and 3299, which indicate the subcarrier index within the carrier corresponding 1o the numerology of the corresponding uplink BWP and value 3300, which indicates "Outside the carrier" and value 3301, which indicates "Undetermined position within the carrier" are used. [TS38.331, UplinkTxDirectCurrentBWP IE]
|
//pusch_pdu->tx_direct_current_location;
|
||||||
|
//The uplink Tx Direct Current location for the carrier. Only values in the value range of this field between 0 and 3299,
|
||||||
|
//which indicate the subcarrier index within the carrier corresponding 1o the numerology of the corresponding uplink BWP and value 3300,
|
||||||
|
//which indicates "Outside the carrier" and value 3301, which indicates "Undetermined position within the carrier" are used. [TS38.331, UplinkTxDirectCurrentBWP IE]
|
||||||
pusch_pdu->uplink_frequency_shift_7p5khz = 0;
|
pusch_pdu->uplink_frequency_shift_7p5khz = 0;
|
||||||
//Resource Allocation in time domain
|
//Resource Allocation in time domain
|
||||||
pusch_pdu->start_symbol_index = start_symbol_index;
|
pusch_pdu->start_symbol_index = start_symbol_index;
|
||||||
pusch_pdu->nr_of_symbols = nr_of_symbols;
|
pusch_pdu->nr_of_symbols = nr_of_symbols;
|
||||||
//Optional Data only included if indicated in pduBitmap
|
//Optional Data only included if indicated in pduBitmap
|
||||||
pusch_pdu->pusch_data.rv_index = nr_rv_round_map[round];
|
pusch_pdu->pusch_data.rv_index = nr_rv_round_map[round%4];
|
||||||
pusch_pdu->pusch_data.harq_process_id = 0;
|
pusch_pdu->pusch_data.harq_process_id = 0;
|
||||||
pusch_pdu->pusch_data.new_data_indicator = 1;
|
pusch_pdu->pusch_data.new_data_indicator = 1;
|
||||||
pusch_pdu->pusch_data.num_cb = 0;
|
pusch_pdu->pusch_data.num_cb = 0;
|
||||||
@@ -1807,7 +1810,7 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
|
|||||||
pdsch_pdu_rel15->qamModOrder[0] = 2;
|
pdsch_pdu_rel15->qamModOrder[0] = 2;
|
||||||
pdsch_pdu_rel15->mcsIndex[0] = mcsIndex;
|
pdsch_pdu_rel15->mcsIndex[0] = mcsIndex;
|
||||||
pdsch_pdu_rel15->mcsTable[0] = mcsTableIdx;
|
pdsch_pdu_rel15->mcsTable[0] = mcsTableIdx;
|
||||||
pdsch_pdu_rel15->rvIndex[0] = nr_rv_round_map[harq->round];
|
pdsch_pdu_rel15->rvIndex[0] = nr_rv_round_map[harq->round%4];
|
||||||
pdsch_pdu_rel15->dataScramblingId = *scc->physCellId;
|
pdsch_pdu_rel15->dataScramblingId = *scc->physCellId;
|
||||||
pdsch_pdu_rel15->nrOfLayers = 1;
|
pdsch_pdu_rel15->nrOfLayers = 1;
|
||||||
pdsch_pdu_rel15->transmissionScheme = 0;
|
pdsch_pdu_rel15->transmissionScheme = 0;
|
||||||
|
|||||||
@@ -285,7 +285,7 @@ uint32_t schedule_control_sib1(module_id_t module_id,
|
|||||||
int nrOfSymbols,
|
int nrOfSymbols,
|
||||||
uint16_t dlDmrsSymbPos,
|
uint16_t dlDmrsSymbPos,
|
||||||
uint8_t candidate_idx,
|
uint8_t candidate_idx,
|
||||||
int num_total_bytes) {
|
uint16_t num_total_bytes) {
|
||||||
|
|
||||||
gNB_MAC_INST *gNB_mac = RC.nrmac[module_id];
|
gNB_MAC_INST *gNB_mac = RC.nrmac[module_id];
|
||||||
NR_COMMON_channels_t *cc = &gNB_mac->common_channels[CC_id];
|
NR_COMMON_channels_t *cc = &gNB_mac->common_channels[CC_id];
|
||||||
@@ -437,7 +437,7 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP,
|
|||||||
pdsch_pdu_rel15->qamModOrder[0] = 2;
|
pdsch_pdu_rel15->qamModOrder[0] = 2;
|
||||||
pdsch_pdu_rel15->mcsIndex[0] = gNB_mac->sched_ctrlCommon->sched_pdsch.mcs;
|
pdsch_pdu_rel15->mcsIndex[0] = gNB_mac->sched_ctrlCommon->sched_pdsch.mcs;
|
||||||
pdsch_pdu_rel15->mcsTable[0] = 0;
|
pdsch_pdu_rel15->mcsTable[0] = 0;
|
||||||
pdsch_pdu_rel15->rvIndex[0] = nr_rv_round_map[0];
|
pdsch_pdu_rel15->rvIndex[0] = 0;
|
||||||
pdsch_pdu_rel15->dataScramblingId = *scc->physCellId;
|
pdsch_pdu_rel15->dataScramblingId = *scc->physCellId;
|
||||||
pdsch_pdu_rel15->nrOfLayers = 1;
|
pdsch_pdu_rel15->nrOfLayers = 1;
|
||||||
pdsch_pdu_rel15->transmissionScheme = 0;
|
pdsch_pdu_rel15->transmissionScheme = 0;
|
||||||
@@ -571,7 +571,7 @@ void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
|
|||||||
|
|
||||||
// Get SIB1
|
// Get SIB1
|
||||||
uint8_t sib1_payload[NR_MAX_SIB_LENGTH/8];
|
uint8_t sib1_payload[NR_MAX_SIB_LENGTH/8];
|
||||||
uint8_t sib1_sdu_length = mac_rrc_nr_data_req(module_idP, CC_id, frameP, BCCH, SI_RNTI, 1, sib1_payload);
|
uint16_t sib1_sdu_length = mac_rrc_nr_data_req(module_idP, CC_id, frameP, BCCH, SI_RNTI, 1, sib1_payload);
|
||||||
LOG_D(NR_MAC,"sib1_sdu_length = %i\n", sib1_sdu_length);
|
LOG_D(NR_MAC,"sib1_sdu_length = %i\n", sib1_sdu_length);
|
||||||
LOG_D(NR_MAC,"SIB1: \n");
|
LOG_D(NR_MAC,"SIB1: \n");
|
||||||
for (int k=0;k<sib1_sdu_length;k++)
|
for (int k=0;k<sib1_sdu_length;k++)
|
||||||
@@ -599,7 +599,8 @@ void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
|
|||||||
startSymbolIndex,
|
startSymbolIndex,
|
||||||
nrOfSymbols,
|
nrOfSymbols,
|
||||||
dlDmrsSymbPos,
|
dlDmrsSymbPos,
|
||||||
candidate_idx, sib1_sdu_length);
|
candidate_idx,
|
||||||
|
sib1_sdu_length);
|
||||||
|
|
||||||
nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[CC_id].dl_tti_request_body;
|
nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[CC_id].dl_tti_request_body;
|
||||||
int pdu_index = gNB_mac->pdu_index[0]++;
|
int pdu_index = gNB_mac->pdu_index[0]++;
|
||||||
|
|||||||
@@ -643,7 +643,10 @@ void pf_dl(module_id_t module_id,
|
|||||||
const NR_bler_options_t *bo = &mac->dl_bler;
|
const NR_bler_options_t *bo = &mac->dl_bler;
|
||||||
const int max_mcs_table = ps->mcsTableIdx == 1 ? 27 : 28;
|
const int max_mcs_table = ps->mcsTableIdx == 1 ? 27 : 28;
|
||||||
const int max_mcs = min(sched_ctrl->dl_max_mcs, max_mcs_table);
|
const int max_mcs = min(sched_ctrl->dl_max_mcs, max_mcs_table);
|
||||||
sched_pdsch->mcs = get_mcs_from_bler(bo, stats, &sched_ctrl->dl_bler_stats, max_mcs, frame);
|
if (bo->harq_round_max == 1)
|
||||||
|
sched_pdsch->mcs = max_mcs;
|
||||||
|
else
|
||||||
|
sched_pdsch->mcs = get_mcs_from_bler(bo, stats, &sched_ctrl->dl_bler_stats, max_mcs, frame);
|
||||||
UE->layers = set_dl_nrOfLayers(sched_ctrl);
|
UE->layers = set_dl_nrOfLayers(sched_ctrl);
|
||||||
const uint8_t Qm = nr_get_Qm_dl(sched_pdsch->mcs, ps->mcsTableIdx);
|
const uint8_t Qm = nr_get_Qm_dl(sched_pdsch->mcs, ps->mcsTableIdx);
|
||||||
const uint16_t R = nr_get_code_rate_dl(sched_pdsch->mcs, ps->mcsTableIdx);
|
const uint16_t R = nr_get_code_rate_dl(sched_pdsch->mcs, ps->mcsTableIdx);
|
||||||
@@ -927,8 +930,6 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
|||||||
if (!is_xlsch_in_slot(gNB_mac->dlsch_slot_bitmap[slot / 64], slot))
|
if (!is_xlsch_in_slot(gNB_mac->dlsch_slot_bitmap[slot / 64], slot))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//if (slot==7 || slot == 17) return;
|
|
||||||
|
|
||||||
/* PREPROCESSOR */
|
/* PREPROCESSOR */
|
||||||
gNB_mac->pre_processor_dl(module_id, frame, slot);
|
gNB_mac->pre_processor_dl(module_id, frame, slot);
|
||||||
const int CC_id = 0;
|
const int CC_id = 0;
|
||||||
@@ -1017,7 +1018,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
|||||||
TBS,
|
TBS,
|
||||||
current_harq_pid,
|
current_harq_pid,
|
||||||
harq->round,
|
harq->round,
|
||||||
nr_rv_round_map[harq->round],
|
nr_rv_round_map[harq->round%4],
|
||||||
harq->ndi,
|
harq->ndi,
|
||||||
pucch->timing_indicator,
|
pucch->timing_indicator,
|
||||||
pucch->frame,
|
pucch->frame,
|
||||||
@@ -1085,8 +1086,8 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
|||||||
pdsch_pdu->mcsIndex[0] = sched_pdsch->mcs;
|
pdsch_pdu->mcsIndex[0] = sched_pdsch->mcs;
|
||||||
pdsch_pdu->mcsTable[0] = ps->mcsTableIdx;
|
pdsch_pdu->mcsTable[0] = ps->mcsTableIdx;
|
||||||
AssertFatal(harq!=NULL,"harq is null\n");
|
AssertFatal(harq!=NULL,"harq is null\n");
|
||||||
AssertFatal(harq->round<4,"%d",harq->round);
|
AssertFatal(harq->round<gNB_mac->dl_bler.harq_round_max,"%d",harq->round);
|
||||||
pdsch_pdu->rvIndex[0] = nr_rv_round_map[harq->round];
|
pdsch_pdu->rvIndex[0] = nr_rv_round_map[harq->round%4];
|
||||||
pdsch_pdu->TBSize[0] = TBS;
|
pdsch_pdu->TBSize[0] = TBS;
|
||||||
pdsch_pdu->dataScramblingId = *scc->physCellId;
|
pdsch_pdu->dataScramblingId = *scc->physCellId;
|
||||||
pdsch_pdu->nrOfLayers = nrOfLayers;
|
pdsch_pdu->nrOfLayers = nrOfLayers;
|
||||||
@@ -1120,9 +1121,8 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
|||||||
csi_report->codebook_mode);
|
csi_report->codebook_mode);
|
||||||
}
|
}
|
||||||
// TBS_LBRM according to section 5.4.2.1 of 38.212
|
// TBS_LBRM according to section 5.4.2.1 of 38.212
|
||||||
long *maxMIMO_Layers = cg->spCellConfig->spCellConfigDedicated->pdsch_ServingCellConfig->choice.setup->ext1->maxMIMO_Layers;
|
long maxMIMO_Layers = cg && cg->spCellConfig && cg->spCellConfig->spCellConfigDedicated ? *cg->spCellConfig->spCellConfigDedicated->pdsch_ServingCellConfig->choice.setup->ext1->maxMIMO_Layers : 1;
|
||||||
AssertFatal (maxMIMO_Layers != NULL,"Option with max MIMO layers not configured is not supported\n");
|
int nl_tbslbrm = maxMIMO_Layers < 4 ? maxMIMO_Layers : 4;
|
||||||
int nl_tbslbrm = *maxMIMO_Layers < 4 ? *maxMIMO_Layers : 4;
|
|
||||||
// Maximum number of PRBs across all configured DL BWPs
|
// Maximum number of PRBs across all configured DL BWPs
|
||||||
int bw_tbslbrm = get_bw_tbslbrm(genericParameters, cg);
|
int bw_tbslbrm = get_bw_tbslbrm(genericParameters, cg);
|
||||||
pdsch_pdu->maintenance_parms_v3.tbSizeLbrmBytes = nr_compute_tbslbrm(ps->mcsTableIdx,
|
pdsch_pdu->maintenance_parms_v3.tbSizeLbrmBytes = nr_compute_tbslbrm(ps->mcsTableIdx,
|
||||||
@@ -1319,7 +1319,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
|||||||
lcid < 4 ? "DCCH" : "DTCH",
|
lcid < 4 ? "DCCH" : "DTCH",
|
||||||
lcid,
|
lcid,
|
||||||
ndata,
|
ndata,
|
||||||
bufEnd-buf-+sizeof(NR_MAC_SUBHEADER_LONG));
|
bufEnd-buf-sizeof(NR_MAC_SUBHEADER_LONG));
|
||||||
|
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
break;
|
break;
|
||||||
@@ -1350,6 +1350,8 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
|||||||
header->L = htons(bufEnd-buf);
|
header->L = htons(bufEnd-buf);
|
||||||
dlsch_total_bytes += bufEnd-buf;
|
dlsch_total_bytes += bufEnd-buf;
|
||||||
|
|
||||||
|
for (; ((intptr_t)buf) % 4; buf++)
|
||||||
|
*buf = lrand48() & 0xff;
|
||||||
for (; buf < bufEnd - 3; buf += 4) {
|
for (; buf < bufEnd - 3; buf += 4) {
|
||||||
uint32_t *buf32 = (uint32_t *)buf;
|
uint32_t *buf32 = (uint32_t *)buf;
|
||||||
*buf32 = lrand48();
|
*buf32 = lrand48();
|
||||||
|
|||||||
@@ -1445,7 +1445,6 @@ void set_r_pucch_parms(int rsetindex,
|
|||||||
*start_symbol_index = default_pucch_firstsymb[rsetindex];
|
*start_symbol_index = default_pucch_firstsymb[rsetindex];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void prepare_dci(const NR_CellGroupConfig_t *CellGroup,
|
void prepare_dci(const NR_CellGroupConfig_t *CellGroup,
|
||||||
dci_pdu_rel15_t *dci_pdu_rel15,
|
dci_pdu_rel15_t *dci_pdu_rel15,
|
||||||
nr_dci_format_t format,
|
nr_dci_format_t format,
|
||||||
@@ -2395,7 +2394,7 @@ NR_UE_info_t *add_new_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rntiP, NR_CellGroupConf
|
|||||||
CellGroup->spCellConfig->spCellConfigDedicated &&
|
CellGroup->spCellConfig->spCellConfigDedicated &&
|
||||||
CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig &&
|
CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig &&
|
||||||
CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup) {
|
CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup) {
|
||||||
compute_csi_bitlen(CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup, UE);
|
compute_csi_bitlen(CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup, UE->csi_report_template);
|
||||||
}
|
}
|
||||||
|
|
||||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||||
@@ -2446,16 +2445,15 @@ NR_UE_info_t *add_new_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rntiP, NR_CellGroupConf
|
|||||||
sched_ctrl->next_dl_bwp_id = -1;
|
sched_ctrl->next_dl_bwp_id = -1;
|
||||||
sched_ctrl->next_ul_bwp_id = -1;
|
sched_ctrl->next_ul_bwp_id = -1;
|
||||||
const struct NR_UplinkConfig__uplinkBWP_ToAddModList *ubwpList = servingCellConfig ? servingCellConfig->uplinkConfig->uplinkBWP_ToAddModList : NULL;
|
const struct NR_UplinkConfig__uplinkBWP_ToAddModList *ubwpList = servingCellConfig ? servingCellConfig->uplinkConfig->uplinkBWP_ToAddModList : NULL;
|
||||||
if (ubwpList)
|
AssertFatal(ubwpList == NULL || ubwpList->list.count <= NR_MAX_NUM_BWP,
|
||||||
AssertFatal(ubwpList->list.count <= NR_MAX_NUM_BWP,
|
"uplinkBWP_ToAddModList has %d BWP!\n",
|
||||||
"uplinkBWP_ToAddModList has %d BWP!\n",
|
ubwpList->list.count);
|
||||||
ubwpList->list.count);
|
|
||||||
const int ul_bwp_id = servingCellConfig ? *servingCellConfig->uplinkConfig->firstActiveUplinkBWP_Id : 0;
|
const int ul_bwp_id = servingCellConfig ? *servingCellConfig->uplinkConfig->firstActiveUplinkBWP_Id : 0;
|
||||||
sched_ctrl->active_ubwp = ubwpList && ul_bwp_id > 0 ? ubwpList->list.array[ul_bwp_id - 1] : NULL;
|
sched_ctrl->active_ubwp = ubwpList && ul_bwp_id > 0 ? ubwpList->list.array[ul_bwp_id - 1] : NULL;
|
||||||
|
|
||||||
/* get Number of HARQ processes for this UE */
|
/* get Number of HARQ processes for this UE */
|
||||||
if (servingCellConfig)
|
AssertFatal(servingCellConfig == NULL
|
||||||
AssertFatal(servingCellConfig->pdsch_ServingCellConfig->present == NR_SetupRelease_PDSCH_ServingCellConfig_PR_setup,
|
|| servingCellConfig->pdsch_ServingCellConfig->present == NR_SetupRelease_PDSCH_ServingCellConfig_PR_setup,
|
||||||
"no pdsch-ServingCellConfig found for UE %04x\n",
|
"no pdsch-ServingCellConfig found for UE %04x\n",
|
||||||
UE->rnti);
|
UE->rnti);
|
||||||
const NR_PDSCH_ServingCellConfig_t *pdsch = servingCellConfig ? servingCellConfig->pdsch_ServingCellConfig->choice.setup : NULL;
|
const NR_PDSCH_ServingCellConfig_t *pdsch = servingCellConfig ? servingCellConfig->pdsch_ServingCellConfig->choice.setup : NULL;
|
||||||
@@ -2967,6 +2965,10 @@ void nr_mac_update_timers(module_id_t module_id,
|
|||||||
LOG_I(NR_MAC, "(%d.%d) Switching to initialUplinkBWP\n", frame, slot);
|
LOG_I(NR_MAC, "(%d.%d) Switching to initialUplinkBWP\n", frame, slot);
|
||||||
}
|
}
|
||||||
UE->Msg3_dcch_dtch = false;
|
UE->Msg3_dcch_dtch = false;
|
||||||
|
|
||||||
|
// Schedule BWP switching to the first active BWP (previous active BWP before RA with Msg3 carrying DCCH or DTCH message)
|
||||||
|
sched_ctrl->next_dl_bwp_id = current_bwp_id;
|
||||||
|
sched_ctrl->next_ul_bwp_id = current_ubwp_id;
|
||||||
} else if (spCellConfigDedicated &&
|
} else if (spCellConfigDedicated &&
|
||||||
spCellConfigDedicated->downlinkBWP_ToAddModList &&
|
spCellConfigDedicated->downlinkBWP_ToAddModList &&
|
||||||
spCellConfigDedicated->uplinkConfig &&
|
spCellConfigDedicated->uplinkConfig &&
|
||||||
@@ -2979,6 +2981,19 @@ void nr_mac_update_timers(module_id_t module_id,
|
|||||||
if (*spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id != current_ubwp_id) {
|
if (*spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id != current_ubwp_id) {
|
||||||
LOG_I(NR_MAC, "(%d.%d) Switching to UL-BWP %li\n", frame, slot, sched_ctrl->active_ubwp->bwp_Id);
|
LOG_I(NR_MAC, "(%d.%d) Switching to UL-BWP %li\n", frame, slot, sched_ctrl->active_ubwp->bwp_Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update next_dl_bwp_id to not trigger BWP switching, UE should be already on active_bwp
|
||||||
|
sched_ctrl->next_dl_bwp_id = sched_ctrl->active_bwp->bwp_Id;
|
||||||
|
// Update next_ul_bwp_id to not trigger BWP switching, UE should be already on active_ubwp
|
||||||
|
sched_ctrl->next_ul_bwp_id = sched_ctrl->active_ubwp->bwp_Id;
|
||||||
|
} else {
|
||||||
|
sched_ctrl->active_bwp = NULL;
|
||||||
|
sched_ctrl->active_ubwp = NULL;
|
||||||
|
|
||||||
|
// Update next_dl_bwp_id to not trigger BWP switching, UE should be already on Initial BWP
|
||||||
|
sched_ctrl->next_dl_bwp_id = 0;
|
||||||
|
// Update next_ul_bwp_id to not trigger BWP switching, UE should be already on Initial BWP
|
||||||
|
sched_ctrl->next_ul_bwp_id = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update coreset/searchspace
|
// Update coreset/searchspace
|
||||||
@@ -3012,7 +3027,7 @@ void nr_mac_update_timers(module_id_t module_id,
|
|||||||
cg->spCellConfig->spCellConfigDedicated &&
|
cg->spCellConfig->spCellConfigDedicated &&
|
||||||
cg->spCellConfig->spCellConfigDedicated->csi_MeasConfig &&
|
cg->spCellConfig->spCellConfigDedicated->csi_MeasConfig &&
|
||||||
cg->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup) {
|
cg->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup) {
|
||||||
compute_csi_bitlen (cg->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup, UE);
|
compute_csi_bitlen (cg->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup, UE->csi_report_template);
|
||||||
}
|
}
|
||||||
|
|
||||||
NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
|
NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
|
||||||
@@ -3072,14 +3087,27 @@ void schedule_nr_bwp_switch(module_id_t module_id,
|
|||||||
|
|
||||||
UE_iterator(UE_info->list, UE) {
|
UE_iterator(UE_info->list, UE) {
|
||||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||||
if (sched_ctrl->rrc_processing_timer == 0 &&
|
if (sched_ctrl->rrc_processing_timer == 0 && UE->Msg4_ACKed && sched_ctrl->next_dl_bwp_id >= 0) {
|
||||||
UE->Msg4_ACKed &&
|
|
||||||
((sched_ctrl->next_dl_bwp_id >= 0 && sched_ctrl->active_bwp && sched_ctrl->active_bwp->bwp_Id != sched_ctrl->next_dl_bwp_id) ||
|
|
||||||
(sched_ctrl->next_ul_bwp_id >= 0 && sched_ctrl->active_ubwp && sched_ctrl->active_ubwp->bwp_Id != sched_ctrl->next_ul_bwp_id))) {
|
|
||||||
|
|
||||||
LOG_W(NR_MAC,"%4d.%2d UE %04x Schedule BWP switch from dl_bwp_id %ld to %ld and from ul_bwp_id %ld to %ld\n",
|
int schedule_bwp_switching = false;
|
||||||
frame, slot, UE->rnti, sched_ctrl->active_bwp->bwp_Id, sched_ctrl->next_dl_bwp_id, sched_ctrl->active_ubwp->bwp_Id, sched_ctrl->next_ul_bwp_id);
|
if (sched_ctrl->active_bwp == NULL) {
|
||||||
nr_mac_rrc_bwp_switch_req(module_id, frame, slot, UE->rnti, sched_ctrl->next_dl_bwp_id, sched_ctrl->next_ul_bwp_id);
|
// Switching from Initial BWP to Dedicated BWP
|
||||||
|
if (sched_ctrl->next_dl_bwp_id > 0 && sched_ctrl->next_ul_bwp_id > 0) {
|
||||||
|
schedule_bwp_switching = true;
|
||||||
|
LOG_W(NR_MAC,"%4d.%2d UE %04x Schedule BWP switch from Initial DL BWP to %ld and from Initial UL BWP to %ld\n",
|
||||||
|
frame, slot, UE->rnti, sched_ctrl->next_dl_bwp_id, sched_ctrl->next_ul_bwp_id);
|
||||||
|
}
|
||||||
|
} else if (sched_ctrl->active_bwp->bwp_Id != sched_ctrl->next_dl_bwp_id && sched_ctrl->active_ubwp->bwp_Id != sched_ctrl->next_ul_bwp_id) {
|
||||||
|
// Switching between Dedicated BWPs
|
||||||
|
schedule_bwp_switching = true;
|
||||||
|
LOG_W(NR_MAC,"%4d.%2d UE %04x Schedule BWP switch from dl_bwp_id %ld to %ld and from ul_bwp_id %ld to %ld\n",
|
||||||
|
frame, slot, UE->rnti, sched_ctrl->active_bwp->bwp_Id, sched_ctrl->next_dl_bwp_id, sched_ctrl->active_ubwp->bwp_Id, sched_ctrl->next_ul_bwp_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (schedule_bwp_switching) {
|
||||||
|
AssertFatal(sched_ctrl->next_dl_bwp_id > 0 && sched_ctrl->next_ul_bwp_id > 0, "BWP switching from a Dedicated BWP to the Initial BWP not handled yet!");
|
||||||
|
nr_mac_rrc_bwp_switch_req(module_id, frame, slot, UE->rnti, sched_ctrl->next_dl_bwp_id, sched_ctrl->next_ul_bwp_id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -169,530 +169,6 @@ void nr_schedule_pucch(gNB_MAC_INST *nrmac,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//! Calculating number of bits set
|
|
||||||
uint8_t number_of_bits_set (uint8_t buf){
|
|
||||||
uint8_t nb_of_bits_set = 0;
|
|
||||||
uint8_t mask = 0xff;
|
|
||||||
uint8_t index = 0;
|
|
||||||
|
|
||||||
for (index=7; (buf & mask) && (index>=0) ; index--){
|
|
||||||
if (buf & (1<<index))
|
|
||||||
nb_of_bits_set++;
|
|
||||||
|
|
||||||
mask>>=1;
|
|
||||||
}
|
|
||||||
return nb_of_bits_set;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void compute_rsrp_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig,
|
|
||||||
uint8_t nb_resources,
|
|
||||||
nr_csi_report_t *csi_report) {
|
|
||||||
|
|
||||||
if (NR_CSI_ReportConfig__groupBasedBeamReporting_PR_disabled == csi_reportconfig->groupBasedBeamReporting.present) {
|
|
||||||
if (NULL != csi_reportconfig->groupBasedBeamReporting.choice.disabled->nrofReportedRS)
|
|
||||||
csi_report->CSI_report_bitlen.nb_ssbri_cri = *(csi_reportconfig->groupBasedBeamReporting.choice.disabled->nrofReportedRS)+1;
|
|
||||||
else
|
|
||||||
/*! From Spec 38.331
|
|
||||||
* nrofReportedRS
|
|
||||||
* The number (N) of measured RS resources to be reported per report setting in a non-group-based report. N <= N_max, where N_max is either 2 or 4 depending on UE
|
|
||||||
* capability. FFS: The signaling mechanism for the gNB to select a subset of N beams for the UE to measure and report.
|
|
||||||
* When the field is absent the UE applies the value 1
|
|
||||||
*/
|
|
||||||
csi_report->CSI_report_bitlen.nb_ssbri_cri= 1;
|
|
||||||
} else
|
|
||||||
csi_report->CSI_report_bitlen.nb_ssbri_cri= 2;
|
|
||||||
|
|
||||||
if (nb_resources) {
|
|
||||||
csi_report->CSI_report_bitlen.cri_ssbri_bitlen =ceil(log2 (nb_resources));
|
|
||||||
csi_report->CSI_report_bitlen.rsrp_bitlen = 7; //From spec 38.212 Table 6.3.1.1.2-6: CRI, SSBRI, and RSRP
|
|
||||||
csi_report->CSI_report_bitlen.diff_rsrp_bitlen =4; //From spec 38.212 Table 6.3.1.1.2-6: CRI, SSBRI, and RSRP
|
|
||||||
} else {
|
|
||||||
csi_report->CSI_report_bitlen.cri_ssbri_bitlen =0;
|
|
||||||
csi_report->CSI_report_bitlen.rsrp_bitlen = 0;
|
|
||||||
csi_report->CSI_report_bitlen.diff_rsrp_bitlen =0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint8_t compute_ri_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig,
|
|
||||||
nr_csi_report_t *csi_report){
|
|
||||||
|
|
||||||
struct NR_CodebookConfig *codebookConfig = csi_reportconfig->codebookConfig;
|
|
||||||
uint8_t nb_allowed_ri, ri_bitlen;
|
|
||||||
uint8_t ri_restriction = 0;
|
|
||||||
|
|
||||||
if (codebookConfig == NULL) {
|
|
||||||
csi_report->csi_meas_bitlen.ri_bitlen=0;
|
|
||||||
return ri_restriction;
|
|
||||||
}
|
|
||||||
|
|
||||||
// codebook type1 single panel
|
|
||||||
if (NR_CodebookConfig__codebookType__type1__subType_PR_typeI_SinglePanel==codebookConfig->codebookType.choice.type1->subType.present){
|
|
||||||
struct NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel *type1single = codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel;
|
|
||||||
if (type1single->nrOfAntennaPorts.present == NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts_PR_two){
|
|
||||||
|
|
||||||
ri_restriction = csi_reportconfig->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.buf[0];
|
|
||||||
|
|
||||||
nb_allowed_ri = number_of_bits_set(ri_restriction);
|
|
||||||
ri_bitlen = ceil(log2(nb_allowed_ri));
|
|
||||||
|
|
||||||
ri_bitlen = ri_bitlen<1?ri_bitlen:1; //from the spec 38.212 and table 6.3.1.1.2-3: RI, LI, CQI, and CRI of codebookType=typeI-SinglePanel
|
|
||||||
csi_report->csi_meas_bitlen.ri_bitlen=ri_bitlen;
|
|
||||||
}
|
|
||||||
if (type1single->nrOfAntennaPorts.present == NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts_PR_moreThanTwo){
|
|
||||||
if (type1single->nrOfAntennaPorts.choice.moreThanTwo->n1_n2.present ==
|
|
||||||
NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_two_one_TypeI_SinglePanel_Restriction) {
|
|
||||||
// 4 ports
|
|
||||||
|
|
||||||
ri_restriction = csi_reportconfig->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.buf[0];
|
|
||||||
|
|
||||||
nb_allowed_ri = number_of_bits_set(ri_restriction);
|
|
||||||
ri_bitlen = ceil(log2(nb_allowed_ri));
|
|
||||||
|
|
||||||
ri_bitlen = ri_bitlen<2?ri_bitlen:2; //from the spec 38.212 and table 6.3.1.1.2-3: RI, LI, CQI, and CRI of codebookType=typeI-SinglePanel
|
|
||||||
csi_report->csi_meas_bitlen.ri_bitlen=ri_bitlen;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// more than 4 ports
|
|
||||||
|
|
||||||
ri_restriction = csi_reportconfig->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.buf[0];
|
|
||||||
|
|
||||||
nb_allowed_ri = number_of_bits_set(ri_restriction);
|
|
||||||
ri_bitlen = ceil(log2(nb_allowed_ri));
|
|
||||||
|
|
||||||
csi_report->csi_meas_bitlen.ri_bitlen=ri_bitlen;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ri_restriction;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
AssertFatal(1==0,"Other configurations not yet implemented\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void compute_li_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig,
|
|
||||||
uint8_t ri_restriction,
|
|
||||||
nr_csi_report_t *csi_report){
|
|
||||||
|
|
||||||
struct NR_CodebookConfig *codebookConfig = csi_reportconfig->codebookConfig;
|
|
||||||
for(int i=0; i<8; i++) {
|
|
||||||
if (codebookConfig == NULL || ((ri_restriction>>i)&0x01) == 0)
|
|
||||||
csi_report->csi_meas_bitlen.li_bitlen[i]=0;
|
|
||||||
else {
|
|
||||||
// codebook type1 single panel
|
|
||||||
if (NR_CodebookConfig__codebookType__type1__subType_PR_typeI_SinglePanel==codebookConfig->codebookType.choice.type1->subType.present)
|
|
||||||
csi_report->csi_meas_bitlen.li_bitlen[i]=ceil(log2(i+1))<2?ceil(log2(i+1)):2;
|
|
||||||
else
|
|
||||||
AssertFatal(1==0,"Other configurations not yet implemented\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void get_n1n2_o1o2_singlepanel(int *n1, int *n2, int *o1, int *o2,
|
|
||||||
struct NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo *morethantwo) {
|
|
||||||
|
|
||||||
// Table 5.2.2.2.1-2 in 38.214 for supported configurations
|
|
||||||
switch(morethantwo->n1_n2.present){
|
|
||||||
case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_two_one_TypeI_SinglePanel_Restriction):
|
|
||||||
*n1 = 2;
|
|
||||||
*n2 = 1;
|
|
||||||
*o1 = 4;
|
|
||||||
*o2 = 1;
|
|
||||||
break;
|
|
||||||
case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_two_two_TypeI_SinglePanel_Restriction):
|
|
||||||
*n1 = 2;
|
|
||||||
*n2 = 2;
|
|
||||||
*o1 = 4;
|
|
||||||
*o2 = 4;
|
|
||||||
break;
|
|
||||||
case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_four_one_TypeI_SinglePanel_Restriction):
|
|
||||||
*n1 = 4;
|
|
||||||
*n2 = 1;
|
|
||||||
*o1 = 4;
|
|
||||||
*o2 = 1;
|
|
||||||
break;
|
|
||||||
case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_three_two_TypeI_SinglePanel_Restriction):
|
|
||||||
*n1 = 3;
|
|
||||||
*n2 = 2;
|
|
||||||
*o1 = 4;
|
|
||||||
*o2 = 4;
|
|
||||||
break;
|
|
||||||
case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_six_one_TypeI_SinglePanel_Restriction):
|
|
||||||
*n1 = 6;
|
|
||||||
*n2 = 1;
|
|
||||||
*o1 = 4;
|
|
||||||
*o2 = 1;
|
|
||||||
break;
|
|
||||||
case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_four_two_TypeI_SinglePanel_Restriction):
|
|
||||||
*n1 = 4;
|
|
||||||
*n2 = 2;
|
|
||||||
*o1 = 4;
|
|
||||||
*o2 = 4;
|
|
||||||
break;
|
|
||||||
case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_eight_one_TypeI_SinglePanel_Restriction):
|
|
||||||
*n1 = 8;
|
|
||||||
*n2 = 1;
|
|
||||||
*o1 = 4;
|
|
||||||
*o2 = 1;
|
|
||||||
break;
|
|
||||||
case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_four_three_TypeI_SinglePanel_Restriction):
|
|
||||||
*n1 = 4;
|
|
||||||
*n2 = 3;
|
|
||||||
*o1 = 4;
|
|
||||||
*o2 = 4;
|
|
||||||
break;
|
|
||||||
case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_six_two_TypeI_SinglePanel_Restriction):
|
|
||||||
*n1 = 4;
|
|
||||||
*n2 = 2;
|
|
||||||
*o1 = 4;
|
|
||||||
*o2 = 4;
|
|
||||||
break;
|
|
||||||
case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_twelve_one_TypeI_SinglePanel_Restriction):
|
|
||||||
*n1 = 12;
|
|
||||||
*n2 = 1;
|
|
||||||
*o1 = 4;
|
|
||||||
*o2 = 1;
|
|
||||||
break;
|
|
||||||
case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_four_four_TypeI_SinglePanel_Restriction):
|
|
||||||
*n1 = 4;
|
|
||||||
*n2 = 4;
|
|
||||||
*o1 = 4;
|
|
||||||
*o2 = 4;
|
|
||||||
break;
|
|
||||||
case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_eight_two_TypeI_SinglePanel_Restriction):
|
|
||||||
*n1 = 8;
|
|
||||||
*n2 = 2;
|
|
||||||
*o1 = 4;
|
|
||||||
*o2 = 4;
|
|
||||||
break;
|
|
||||||
case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_sixteen_one_TypeI_SinglePanel_Restriction):
|
|
||||||
*n1 = 16;
|
|
||||||
*n2 = 1;
|
|
||||||
*o1 = 4;
|
|
||||||
*o2 = 1;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
AssertFatal(1==0,"Not supported configuration for n1_n2 in codebook configuration");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void get_x1x2_bitlen_singlepanel(int n1, int n2, int o1, int o2,
|
|
||||||
int *x1, int *x2, int rank, int codebook_mode) {
|
|
||||||
|
|
||||||
// Table 6.3.1.1.2-1 in 38.212
|
|
||||||
switch(rank){
|
|
||||||
case 1:
|
|
||||||
if(n2>1) {
|
|
||||||
if (codebook_mode == 1) {
|
|
||||||
*x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2));
|
|
||||||
*x2 = 2;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
*x1 = ceil(log2(n1*o1/2)) + ceil(log2(n2*o2/2));
|
|
||||||
*x2 = 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
if (codebook_mode == 1) {
|
|
||||||
*x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2));
|
|
||||||
*x2 = 2;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
*x1 = ceil(log2(n1*o1/2));
|
|
||||||
*x2 = 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
if(n1*n2 == 2) {
|
|
||||||
if (codebook_mode == 1) {
|
|
||||||
*x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2));
|
|
||||||
*x2 = 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
*x1 = ceil(log2(n1*o1/2));
|
|
||||||
*x2 = 3;
|
|
||||||
}
|
|
||||||
*x1 += 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if(n2>1) {
|
|
||||||
if (codebook_mode == 1) {
|
|
||||||
*x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2));
|
|
||||||
*x2 = 3;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
*x1 = ceil(log2(n1*o1/2)) + ceil(log2(n2*o2/2));
|
|
||||||
*x2 = 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
if (codebook_mode == 1) {
|
|
||||||
*x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2));
|
|
||||||
*x2 = 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
*x1 = ceil(log2(n1*o1/2));
|
|
||||||
*x2 = 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*x1 += 2;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
case 4:
|
|
||||||
if(n1*n2 == 2) {
|
|
||||||
*x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2));
|
|
||||||
*x2 = 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if(n1*n2 >= 8) {
|
|
||||||
*x1 = ceil(log2(n1*o1/2)) + ceil(log2(n2*o2)) + 2;
|
|
||||||
*x2 = 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
*x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2)) + 2;
|
|
||||||
*x2 = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
case 6:
|
|
||||||
*x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2));
|
|
||||||
*x2 = 1;
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
case 8:
|
|
||||||
if(n1 == 4 && n2 == 1) {
|
|
||||||
*x1 = ceil(log2(n1*o1/2)) + ceil(log2(n2*o2));
|
|
||||||
*x2 = 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if(n1 > 2 && n2 == 2) {
|
|
||||||
*x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2/2));
|
|
||||||
*x2 = 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
*x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2));
|
|
||||||
*x2 = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
AssertFatal(1==0,"Invalid rank in x1 x2 bit length computation\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void compute_pmi_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig,
|
|
||||||
uint8_t ri_restriction,
|
|
||||||
nr_csi_report_t *csi_report){
|
|
||||||
|
|
||||||
struct NR_CodebookConfig *codebookConfig = csi_reportconfig->codebookConfig;
|
|
||||||
for(int i=0; i<8; i++) {
|
|
||||||
csi_report->csi_meas_bitlen.pmi_x1_bitlen[i]=0;
|
|
||||||
csi_report->csi_meas_bitlen.pmi_x2_bitlen[i]=0;
|
|
||||||
if (codebookConfig == NULL || ((ri_restriction>>i)&0x01) == 0)
|
|
||||||
return;
|
|
||||||
else {
|
|
||||||
if(codebookConfig->codebookType.present == NR_CodebookConfig__codebookType_PR_type1) {
|
|
||||||
if(codebookConfig->codebookType.choice.type1->subType.present == NR_CodebookConfig__codebookType__type1__subType_PR_typeI_SinglePanel) {
|
|
||||||
if(codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.present ==
|
|
||||||
NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts_PR_two) {
|
|
||||||
csi_report->N1 = 1;
|
|
||||||
csi_report->N2 = 1;
|
|
||||||
if (i==0)
|
|
||||||
csi_report->csi_meas_bitlen.pmi_x2_bitlen[i]=2;
|
|
||||||
if (i==1)
|
|
||||||
csi_report->csi_meas_bitlen.pmi_x2_bitlen[i]=1;
|
|
||||||
}
|
|
||||||
else { // more than two
|
|
||||||
int n1,n2,o1,o2,x1,x2;
|
|
||||||
get_n1n2_o1o2_singlepanel(&n1,&n2,&o1,&o2,codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.moreThanTwo);
|
|
||||||
get_x1x2_bitlen_singlepanel(n1,n2,o1,o2,&x1,&x2,i+1,codebookConfig->codebookType.choice.type1->codebookMode);
|
|
||||||
csi_report->N1 = n1;
|
|
||||||
csi_report->N2 = n2;
|
|
||||||
csi_report->codebook_mode = codebookConfig->codebookType.choice.type1->codebookMode;
|
|
||||||
csi_report->csi_meas_bitlen.pmi_x1_bitlen[i]=x1;
|
|
||||||
csi_report->csi_meas_bitlen.pmi_x2_bitlen[i]=x2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
AssertFatal(1==0,"Type1 Multi-panel Codebook Config not yet implemented\n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
AssertFatal(1==0,"Type2 Codebook Config not yet implemented\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void compute_cqi_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig,
|
|
||||||
uint8_t ri_restriction,
|
|
||||||
nr_csi_report_t *csi_report){
|
|
||||||
|
|
||||||
struct NR_CodebookConfig *codebookConfig = csi_reportconfig->codebookConfig;
|
|
||||||
struct NR_CSI_ReportConfig__reportFreqConfiguration *freq_config = csi_reportconfig->reportFreqConfiguration;
|
|
||||||
|
|
||||||
if (*freq_config->cqi_FormatIndicator == NR_CSI_ReportConfig__reportFreqConfiguration__cqi_FormatIndicator_widebandCQI) {
|
|
||||||
for(int i=0; i<8; i++) {
|
|
||||||
if ((ri_restriction>>i)&0x01) {
|
|
||||||
csi_report->csi_meas_bitlen.cqi_bitlen[i] = 4;
|
|
||||||
if(codebookConfig != NULL) {
|
|
||||||
if (NR_CodebookConfig__codebookType__type1__subType_PR_typeI_SinglePanel == codebookConfig->codebookType.choice.type1->subType.present){
|
|
||||||
struct NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel *type1single = codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel;
|
|
||||||
if (type1single->nrOfAntennaPorts.present == NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts_PR_moreThanTwo) {
|
|
||||||
if (type1single->nrOfAntennaPorts.choice.moreThanTwo->n1_n2.present >
|
|
||||||
NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_two_one_TypeI_SinglePanel_Restriction) {
|
|
||||||
// more than 4 antenna ports
|
|
||||||
if (i > 4)
|
|
||||||
csi_report->csi_meas_bitlen.cqi_bitlen[i] += 4; // CQI for second TB
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
csi_report->csi_meas_bitlen.cqi_bitlen[i] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
AssertFatal(1==0,"Sub-band CQI reporting not yet supported");
|
|
||||||
}
|
|
||||||
|
|
||||||
//!TODO : same function can be written to handle csi_resources
|
|
||||||
void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_UE_info_t *UE){
|
|
||||||
uint8_t csi_report_id = 0;
|
|
||||||
uint8_t nb_resources = 0;
|
|
||||||
NR_CSI_ReportConfig__reportQuantity_PR reportQuantity_type;
|
|
||||||
NR_CSI_ResourceConfigId_t csi_ResourceConfigId;
|
|
||||||
struct NR_CSI_ResourceConfig *csi_resourceconfig;
|
|
||||||
|
|
||||||
// for each CSI measurement report configuration (list of CSI-ReportConfig)
|
|
||||||
LOG_D(NR_MAC,"Searching %d csi_reports\n",csi_MeasConfig->csi_ReportConfigToAddModList->list.count);
|
|
||||||
for (csi_report_id=0; csi_report_id < csi_MeasConfig->csi_ReportConfigToAddModList->list.count; csi_report_id++){
|
|
||||||
struct NR_CSI_ReportConfig *csi_reportconfig = csi_MeasConfig->csi_ReportConfigToAddModList->list.array[csi_report_id];
|
|
||||||
// MAC structure for CSI measurement reports (per UE and per report)
|
|
||||||
nr_csi_report_t *csi_report = &UE->csi_report_template[csi_report_id];
|
|
||||||
// csi-ResourceConfigId of a CSI-ResourceConfig included in the configuration
|
|
||||||
// (either CSI-RS or SSB)
|
|
||||||
csi_ResourceConfigId = csi_reportconfig->resourcesForChannelMeasurement;
|
|
||||||
// looking for CSI-ResourceConfig
|
|
||||||
int found_resource = 0;
|
|
||||||
int csi_resourceidx = 0;
|
|
||||||
while (found_resource == 0 && csi_resourceidx < csi_MeasConfig->csi_ResourceConfigToAddModList->list.count) {
|
|
||||||
csi_resourceconfig = csi_MeasConfig->csi_ResourceConfigToAddModList->list.array[csi_resourceidx];
|
|
||||||
if ( csi_resourceconfig->csi_ResourceConfigId == csi_ResourceConfigId)
|
|
||||||
found_resource = 1;
|
|
||||||
csi_resourceidx++;
|
|
||||||
}
|
|
||||||
AssertFatal(found_resource==1,"Not able to found any CSI-ResourceConfig with csi-ResourceConfigId %ld\n",
|
|
||||||
csi_ResourceConfigId);
|
|
||||||
|
|
||||||
long resourceType = csi_resourceconfig->resourceType;
|
|
||||||
|
|
||||||
reportQuantity_type = csi_reportconfig->reportQuantity.present;
|
|
||||||
csi_report->reportQuantity_type = reportQuantity_type;
|
|
||||||
|
|
||||||
// setting the CSI or SSB index list
|
|
||||||
if (NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP == csi_report->reportQuantity_type) {
|
|
||||||
for (int csi_idx = 0; csi_idx < csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.count; csi_idx++) {
|
|
||||||
if (csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_idx]->csi_SSB_ResourceSetId ==
|
|
||||||
*(csi_resourceconfig->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->csi_SSB_ResourceSetList->list.array[0])){
|
|
||||||
//We can configure only one SSB resource set from spec 38.331 IE CSI-ResourceConfig
|
|
||||||
nb_resources= csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_idx]->csi_SSB_ResourceList.list.count;
|
|
||||||
csi_report->SSB_Index_list = csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_idx]->csi_SSB_ResourceList.list.array;
|
|
||||||
csi_report->CSI_Index_list = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (resourceType == NR_CSI_ResourceConfig__resourceType_periodic) {
|
|
||||||
AssertFatal(csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList != NULL,
|
|
||||||
"Wrong settings! Report quantity requires CSI-RS but csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList is NULL\n");
|
|
||||||
for (int csi_idx = 0; csi_idx < csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.count; csi_idx++) {
|
|
||||||
if (csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.array[csi_idx]->nzp_CSI_ResourceSetId ==
|
|
||||||
*(csi_resourceconfig->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList->list.array[0])) {
|
|
||||||
//For periodic and semi-persistent CSI Resource Settings, the number of CSI-RS Resource Sets configured is limited to S=1 for spec 38.212
|
|
||||||
nb_resources = csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.array[csi_idx]->nzp_CSI_RS_Resources.list.count;
|
|
||||||
csi_report->CSI_Index_list = csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.array[csi_idx]->nzp_CSI_RS_Resources.list.array;
|
|
||||||
csi_report->SSB_Index_list = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else AssertFatal(1==0,"Only periodic resource configuration currently supported\n");
|
|
||||||
}
|
|
||||||
LOG_D(NR_MAC,"nb_resources %d\n",nb_resources);
|
|
||||||
// computation of bit length depending on the report type
|
|
||||||
switch(reportQuantity_type){
|
|
||||||
case (NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP):
|
|
||||||
compute_rsrp_bitlen(csi_reportconfig, nb_resources, csi_report);
|
|
||||||
break;
|
|
||||||
case (NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP):
|
|
||||||
compute_rsrp_bitlen(csi_reportconfig, nb_resources, csi_report);
|
|
||||||
break;
|
|
||||||
case (NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_CQI):
|
|
||||||
csi_report->csi_meas_bitlen.cri_bitlen=ceil(log2(nb_resources));
|
|
||||||
csi_report->csi_meas_bitlen.ri_restriction = compute_ri_bitlen(csi_reportconfig, csi_report);
|
|
||||||
compute_cqi_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report);
|
|
||||||
break;
|
|
||||||
case (NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_PMI_CQI):
|
|
||||||
csi_report->csi_meas_bitlen.cri_bitlen=ceil(log2(nb_resources));
|
|
||||||
csi_report->csi_meas_bitlen.ri_restriction = compute_ri_bitlen(csi_reportconfig, csi_report);
|
|
||||||
compute_cqi_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report);
|
|
||||||
compute_pmi_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report);
|
|
||||||
break;
|
|
||||||
case (NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_LI_PMI_CQI):
|
|
||||||
csi_report->csi_meas_bitlen.cri_bitlen=ceil(log2(nb_resources));
|
|
||||||
csi_report->csi_meas_bitlen.ri_restriction = compute_ri_bitlen(csi_reportconfig, csi_report);
|
|
||||||
compute_li_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report);
|
|
||||||
compute_cqi_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report);
|
|
||||||
compute_pmi_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
AssertFatal(1==0,"Not yet supported CSI report quantity type");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint16_t nr_get_csi_bitlen(NR_UE_info_t *UE,
|
|
||||||
uint8_t csi_report_id) {
|
|
||||||
|
|
||||||
uint16_t csi_bitlen = 0;
|
|
||||||
uint16_t max_bitlen = 0;
|
|
||||||
L1_RSRP_bitlen_t * CSI_report_bitlen = NULL;
|
|
||||||
CSI_Meas_bitlen_t * csi_meas_bitlen = NULL;
|
|
||||||
|
|
||||||
if (NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP==UE->csi_report_template[csi_report_id].reportQuantity_type||
|
|
||||||
NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP==UE->csi_report_template[csi_report_id].reportQuantity_type){
|
|
||||||
CSI_report_bitlen = &(UE->csi_report_template[csi_report_id].CSI_report_bitlen); //This might need to be moodif for Aperiodic CSI-RS measurements
|
|
||||||
csi_bitlen+= ((CSI_report_bitlen->cri_ssbri_bitlen * CSI_report_bitlen->nb_ssbri_cri) +
|
|
||||||
CSI_report_bitlen->rsrp_bitlen +(CSI_report_bitlen->diff_rsrp_bitlen *
|
|
||||||
(CSI_report_bitlen->nb_ssbri_cri -1 )));
|
|
||||||
} else{
|
|
||||||
csi_meas_bitlen = &(UE->csi_report_template[csi_report_id].csi_meas_bitlen); //This might need to be moodif for Aperiodic CSI-RS measurements
|
|
||||||
uint16_t temp_bitlen;
|
|
||||||
for (int i=0; i<8; i++) {
|
|
||||||
temp_bitlen = (csi_meas_bitlen->cri_bitlen+
|
|
||||||
csi_meas_bitlen->ri_bitlen+
|
|
||||||
csi_meas_bitlen->li_bitlen[i]+
|
|
||||||
csi_meas_bitlen->cqi_bitlen[i]+
|
|
||||||
csi_meas_bitlen->pmi_x1_bitlen[i]+
|
|
||||||
csi_meas_bitlen->pmi_x2_bitlen[i]);
|
|
||||||
if(temp_bitlen>max_bitlen)
|
|
||||||
max_bitlen = temp_bitlen;
|
|
||||||
}
|
|
||||||
csi_bitlen += max_bitlen;
|
|
||||||
}
|
|
||||||
|
|
||||||
return csi_bitlen;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void nr_csi_meas_reporting(int Mod_idP,
|
void nr_csi_meas_reporting(int Mod_idP,
|
||||||
frame_t frame,
|
frame_t frame,
|
||||||
sub_frame_t slot) {
|
sub_frame_t slot) {
|
||||||
@@ -700,7 +176,6 @@ void nr_csi_meas_reporting(int Mod_idP,
|
|||||||
NR_ServingCellConfigCommon_t *scc = RC.nrmac[Mod_idP]->common_channels->ServingCellConfigCommon;
|
NR_ServingCellConfigCommon_t *scc = RC.nrmac[Mod_idP]->common_channels->ServingCellConfigCommon;
|
||||||
const int n_slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
|
const int n_slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
|
||||||
|
|
||||||
|
|
||||||
UE_iterator(RC.nrmac[Mod_idP]->UE_info.list, UE ) {
|
UE_iterator(RC.nrmac[Mod_idP]->UE_info.list, UE ) {
|
||||||
const NR_CellGroupConfig_t *CellGroup = UE->CellGroup;
|
const NR_CellGroupConfig_t *CellGroup = UE->CellGroup;
|
||||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||||
@@ -760,7 +235,7 @@ void nr_csi_meas_reporting(int Mod_idP,
|
|||||||
curr_pucch->frame = frame;
|
curr_pucch->frame = frame;
|
||||||
curr_pucch->ul_slot = sched_slot;
|
curr_pucch->ul_slot = sched_slot;
|
||||||
curr_pucch->resource_indicator = res_index;
|
curr_pucch->resource_indicator = res_index;
|
||||||
curr_pucch->csi_bits += nr_get_csi_bitlen(UE,csi_report_id);
|
curr_pucch->csi_bits += nr_get_csi_bitlen(UE->csi_report_template, csi_report_id);
|
||||||
|
|
||||||
const NR_SIB1_t *sib1 = RC.nrmac[Mod_idP]->common_channels[0].sib1 ? RC.nrmac[Mod_idP]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
|
const NR_SIB1_t *sib1 = RC.nrmac[Mod_idP]->common_channels[0].sib1 ? RC.nrmac[Mod_idP]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
|
||||||
NR_BWP_t *genericParameters = get_ul_bwp_genericParameters(sched_ctrl->active_ubwp,
|
NR_BWP_t *genericParameters = get_ul_bwp_genericParameters(sched_ctrl->active_ubwp,
|
||||||
@@ -824,7 +299,6 @@ static void handle_dl_harq(NR_UE_info_t * UE,
|
|||||||
add_tail_nr_list(&UE->UE_sched_ctrl.available_dl_harq, harq_pid);
|
add_tail_nr_list(&UE->UE_sched_ctrl.available_dl_harq, harq_pid);
|
||||||
harq->round = 0;
|
harq->round = 0;
|
||||||
harq->ndi ^= 1;
|
harq->ndi ^= 1;
|
||||||
|
|
||||||
} else if (harq->round >= harq_round_max - 1) {
|
} else if (harq->round >= harq_round_max - 1) {
|
||||||
abort_nr_dl_harq(UE, harq_pid);
|
abort_nr_dl_harq(UE, harq_pid);
|
||||||
LOG_D(NR_MAC, "retransmission error for UE %04x (total %"PRIu64")\n", UE->rnti, UE->mac_stats.dl.errors);
|
LOG_D(NR_MAC, "retransmission error for UE %04x (total %"PRIu64")\n", UE->rnti, UE->mac_stats.dl.errors);
|
||||||
@@ -1177,7 +651,6 @@ void evaluate_rsrp_report(NR_UE_info_t *UE,
|
|||||||
stats->num_rsrp_meas++;
|
stats->num_rsrp_meas++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void evaluate_cri_report(uint8_t *payload,
|
void evaluate_cri_report(uint8_t *payload,
|
||||||
uint8_t cri_bitlen,
|
uint8_t cri_bitlen,
|
||||||
int cumul_bits,
|
int cumul_bits,
|
||||||
@@ -1456,7 +929,7 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id,
|
|||||||
for (int harq_bit = 0; harq_bit < uci_01->harq->num_harq; harq_bit++) {
|
for (int harq_bit = 0; harq_bit < uci_01->harq->num_harq; harq_bit++) {
|
||||||
const uint8_t harq_value = uci_01->harq->harq_list[harq_bit].harq_value;
|
const uint8_t harq_value = uci_01->harq->harq_list[harq_bit].harq_value;
|
||||||
const uint8_t harq_confidence = uci_01->harq->harq_confidence_level;
|
const uint8_t harq_confidence = uci_01->harq->harq_confidence_level;
|
||||||
NR_UE_harq_t *harq = find_harq(frame, slot, UE, RC.nrmac[mod_id]->harq_round_max);
|
NR_UE_harq_t *harq = find_harq(frame, slot, UE, RC.nrmac[mod_id]->dl_bler.harq_round_max);
|
||||||
if (!harq) {
|
if (!harq) {
|
||||||
LOG_E(NR_MAC, "Oh no! Could not find a harq in %s!\n", __FUNCTION__);
|
LOG_E(NR_MAC, "Oh no! Could not find a harq in %s!\n", __FUNCTION__);
|
||||||
break;
|
break;
|
||||||
@@ -1465,7 +938,7 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id,
|
|||||||
const int8_t pid = sched_ctrl->feedback_dl_harq.head;
|
const int8_t pid = sched_ctrl->feedback_dl_harq.head;
|
||||||
remove_front_nr_list(&sched_ctrl->feedback_dl_harq);
|
remove_front_nr_list(&sched_ctrl->feedback_dl_harq);
|
||||||
LOG_D(NR_MAC,"%4d.%2d bit %d pid %d ack/nack %d\n",frame, slot, harq_bit,pid,harq_value);
|
LOG_D(NR_MAC,"%4d.%2d bit %d pid %d ack/nack %d\n",frame, slot, harq_bit,pid,harq_value);
|
||||||
handle_dl_harq(UE, pid, harq_value == 0 && harq_confidence == 0, RC.nrmac[mod_id]->harq_round_max);
|
handle_dl_harq(UE, pid, harq_value == 0 && harq_confidence == 0, RC.nrmac[mod_id]->dl_bler.harq_round_max);
|
||||||
if (harq_confidence == 1) UE->mac_stats.pucch0_DTX++;
|
if (harq_confidence == 1) UE->mac_stats.pucch0_DTX++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1518,13 +991,13 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id,
|
|||||||
// iterate over received harq bits
|
// iterate over received harq bits
|
||||||
for (int harq_bit = 0; harq_bit < uci_234->harq.harq_bit_len; harq_bit++) {
|
for (int harq_bit = 0; harq_bit < uci_234->harq.harq_bit_len; harq_bit++) {
|
||||||
const int acknack = ((uci_234->harq.harq_payload[harq_bit >> 3]) >> harq_bit) & 0x01;
|
const int acknack = ((uci_234->harq.harq_payload[harq_bit >> 3]) >> harq_bit) & 0x01;
|
||||||
NR_UE_harq_t *harq = find_harq(frame, slot, UE, RC.nrmac[mod_id]->harq_round_max);
|
NR_UE_harq_t *harq = find_harq(frame, slot, UE, RC.nrmac[mod_id]->dl_bler.harq_round_max);
|
||||||
if (!harq)
|
if (!harq)
|
||||||
break;
|
break;
|
||||||
DevAssert(harq->is_waiting);
|
DevAssert(harq->is_waiting);
|
||||||
const int8_t pid = sched_ctrl->feedback_dl_harq.head;
|
const int8_t pid = sched_ctrl->feedback_dl_harq.head;
|
||||||
remove_front_nr_list(&sched_ctrl->feedback_dl_harq);
|
remove_front_nr_list(&sched_ctrl->feedback_dl_harq);
|
||||||
handle_dl_harq(UE, pid, uci_234->harq.harq_crc != 1 && acknack, RC.nrmac[mod_id]->harq_round_max);
|
handle_dl_harq(UE, pid, uci_234->harq.harq_crc != 1 && acknack, RC.nrmac[mod_id]->dl_bler.harq_round_max);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((uci_234->pduBitmap >> 2) & 0x01) {
|
if ((uci_234->pduBitmap >> 2) & 0x01) {
|
||||||
@@ -1593,7 +1066,6 @@ bool test_acknack_vrb_occupation(NR_UE_sched_ctrl_t *sched_ctrl,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// this function returns an index to NR_sched_pucch structure
|
// this function returns an index to NR_sched_pucch structure
|
||||||
// currently this structure contains PUCCH0 at index 0 and PUCCH2 at index 1
|
// currently this structure contains PUCCH0 at index 0 and PUCCH2 at index 1
|
||||||
// if the function returns -1 it was not possible to schedule acknack
|
// if the function returns -1 it was not possible to schedule acknack
|
||||||
@@ -1662,7 +1134,7 @@ int nr_acknack_scheduling(int mod_id,
|
|||||||
&& csi_pucch->csi_bits > 0
|
&& csi_pucch->csi_bits > 0
|
||||||
&& csi_pucch->frame == f
|
&& csi_pucch->frame == f
|
||||||
&& csi_pucch->ul_slot == s))
|
&& csi_pucch->ul_slot == s))
|
||||||
nr_fill_nfapi_pucch(RC.nrmac[mod_id], frame, slot, pucch, UE);
|
nr_fill_nfapi_pucch(RC.nrmac[mod_id], frame, slot, pucch, UE);
|
||||||
|
|
||||||
memset(pucch, 0, sizeof(*pucch));
|
memset(pucch, 0, sizeof(*pucch));
|
||||||
pucch->frame = s == n_slots_frame - 1 ? (f + 1) % 1024 : f;
|
pucch->frame = s == n_slots_frame - 1 ? (f + 1) % 1024 : f;
|
||||||
@@ -1735,7 +1207,7 @@ int nr_acknack_scheduling(int mod_id,
|
|||||||
csi_pucch->csi_bits > 0 &&
|
csi_pucch->csi_bits > 0 &&
|
||||||
csi_pucch->frame == f &&
|
csi_pucch->frame == f &&
|
||||||
csi_pucch->ul_slot == s))
|
csi_pucch->ul_slot == s))
|
||||||
nr_fill_nfapi_pucch(RC.nrmac[mod_id], frame, slot, pucch, UE);
|
nr_fill_nfapi_pucch(RC.nrmac[mod_id], frame, slot, pucch, UE);
|
||||||
memset(pucch, 0, sizeof(*pucch));
|
memset(pucch, 0, sizeof(*pucch));
|
||||||
pucch->frame = s == n_slots_frame - 1 ? (f + 1) % 1024 : f;
|
pucch->frame = s == n_slots_frame - 1 ? (f + 1) % 1024 : f;
|
||||||
if(((s + 1)%nr_slots_period) == 0)
|
if(((s + 1)%nr_slots_period) == 0)
|
||||||
@@ -1837,7 +1309,6 @@ int nr_acknack_scheduling(int mod_id,
|
|||||||
// FIXME currently we support at most 11 bits in pucch2 so skip also in that case
|
// FIXME currently we support at most 11 bits in pucch2 so skip also in that case
|
||||||
if(!csi_pucch->simultaneous_harqcsi
|
if(!csi_pucch->simultaneous_harqcsi
|
||||||
|| ((csi_pucch->csi_bits + csi_pucch->dai_c) >= 11)) {
|
|| ((csi_pucch->csi_bits + csi_pucch->dai_c) >= 11)) {
|
||||||
|
|
||||||
LOG_D(NR_MAC,"Cannot multiplex csi_pucch %d +csi_pucch->dai_c %d for %d.%d\n",csi_pucch->csi_bits,csi_pucch->dai_c,csi_pucch->frame,csi_pucch->ul_slot);
|
LOG_D(NR_MAC,"Cannot multiplex csi_pucch %d +csi_pucch->dai_c %d for %d.%d\n",csi_pucch->csi_bits,csi_pucch->dai_c,csi_pucch->frame,csi_pucch->ul_slot);
|
||||||
nr_fill_nfapi_pucch(RC.nrmac[mod_id], frame, slot, csi_pucch, UE);
|
nr_fill_nfapi_pucch(RC.nrmac[mod_id], frame, slot, csi_pucch, UE);
|
||||||
memset(csi_pucch, 0, sizeof(*csi_pucch));
|
memset(csi_pucch, 0, sizeof(*csi_pucch));
|
||||||
|
|||||||
@@ -435,7 +435,7 @@ int nr_process_mac_pdu(instance_t module_idP,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void abort_nr_ul_harq( NR_UE_info_t* UE, int8_t harq_pid)
|
void abort_nr_ul_harq(NR_UE_info_t *UE, int8_t harq_pid)
|
||||||
{
|
{
|
||||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||||
NR_UE_ul_harq_t *harq = &sched_ctrl->ul_harq_processes[harq_pid];
|
NR_UE_ul_harq_t *harq = &sched_ctrl->ul_harq_processes[harq_pid];
|
||||||
@@ -485,7 +485,7 @@ void handle_nr_ul_harq(const int CC_idP,
|
|||||||
remove_front_nr_list(&sched_ctrl->feedback_ul_harq);
|
remove_front_nr_list(&sched_ctrl->feedback_ul_harq);
|
||||||
sched_ctrl->ul_harq_processes[harq_pid].is_waiting = false;
|
sched_ctrl->ul_harq_processes[harq_pid].is_waiting = false;
|
||||||
|
|
||||||
if(sched_ctrl->ul_harq_processes[harq_pid].round >= RC.nrmac[mod_id]->harq_round_max - 1) {
|
if(sched_ctrl->ul_harq_processes[harq_pid].round >= RC.nrmac[mod_id]->ul_bler.harq_round_max - 1) {
|
||||||
abort_nr_ul_harq(UE, harq_pid);
|
abort_nr_ul_harq(UE, harq_pid);
|
||||||
} else {
|
} else {
|
||||||
sched_ctrl->ul_harq_processes[harq_pid].round++;
|
sched_ctrl->ul_harq_processes[harq_pid].round++;
|
||||||
@@ -506,7 +506,7 @@ void handle_nr_ul_harq(const int CC_idP,
|
|||||||
harq_pid,
|
harq_pid,
|
||||||
crc_pdu->rnti);
|
crc_pdu->rnti);
|
||||||
add_tail_nr_list(&sched_ctrl->available_ul_harq, harq_pid);
|
add_tail_nr_list(&sched_ctrl->available_ul_harq, harq_pid);
|
||||||
} else if (harq->round >= RC.nrmac[mod_id]->harq_round_max - 1) {
|
} else if (harq->round >= RC.nrmac[mod_id]->ul_bler.harq_round_max - 1) {
|
||||||
abort_nr_ul_harq(UE, harq_pid);
|
abort_nr_ul_harq(UE, harq_pid);
|
||||||
LOG_D(NR_MAC,
|
LOG_D(NR_MAC,
|
||||||
"RNTI %04x: Ulharq id %d crc failed in all rounds\n",
|
"RNTI %04x: Ulharq id %d crc failed in all rounds\n",
|
||||||
@@ -579,7 +579,6 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
|
|||||||
else{
|
else{
|
||||||
LOG_D(NR_MAC,"[UE %04x] Detected DTX : increasing UE TX power\n",UE->rnti);
|
LOG_D(NR_MAC,"[UE %04x] Detected DTX : increasing UE TX power\n",UE->rnti);
|
||||||
UE_scheduling_control->tpc0 = 1;
|
UE_scheduling_control->tpc0 = 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
|
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
|
||||||
@@ -782,14 +781,13 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ra->msg3_round >= MAX_HARQ_ROUNDS - 1) {
|
if (ra->msg3_round >= gNB_mac->ul_bler.harq_round_max - 1) {
|
||||||
LOG_D(NR_MAC, "Random Access %i failed at state %i (Reached msg3 max harq rounds)\n", i, ra->state);
|
LOG_W(NR_MAC, "Random Access %i failed at state %i (Reached msg3 max harq rounds)\n", i, ra->state);
|
||||||
nr_mac_remove_ra_rnti(gnb_mod_idP, ra->rnti);
|
nr_mac_remove_ra_rnti(gnb_mod_idP, ra->rnti);
|
||||||
nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra);
|
nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LOG_D(NR_MAC, "Random Access %i Msg3 CRC did not pass)\n", i);
|
LOG_D(NR_MAC, "Random Access %i Msg3 CRC did not pass)\n", i);
|
||||||
|
|
||||||
ra->msg3_round++;
|
ra->msg3_round++;
|
||||||
@@ -879,10 +877,8 @@ static bool nr_UE_is_to_be_scheduled(const NR_ServingCellConfigCommon_t *scc,
|
|||||||
const int n = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
|
const int n = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
|
||||||
const int now = frame * n + slot;
|
const int now = frame * n + slot;
|
||||||
|
|
||||||
|
|
||||||
const NR_UE_sched_ctrl_t *sched_ctrl =&UE->UE_sched_ctrl;
|
const NR_UE_sched_ctrl_t *sched_ctrl =&UE->UE_sched_ctrl;
|
||||||
|
|
||||||
|
|
||||||
const NR_TDD_UL_DL_Pattern_t *tdd =
|
const NR_TDD_UL_DL_Pattern_t *tdd =
|
||||||
scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
|
scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
|
||||||
int num_slots_per_period;
|
int num_slots_per_period;
|
||||||
@@ -1148,7 +1144,7 @@ static int comparator(const void *p, const void *q) {
|
|||||||
void pf_ul(module_id_t module_id,
|
void pf_ul(module_id_t module_id,
|
||||||
frame_t frame,
|
frame_t frame,
|
||||||
sub_frame_t slot,
|
sub_frame_t slot,
|
||||||
NR_UE_info_t *UE_list[],
|
NR_UE_info_t *UE_list[],
|
||||||
int max_num_ue,
|
int max_num_ue,
|
||||||
int n_rb_sched,
|
int n_rb_sched,
|
||||||
uint16_t *rballoc_mask) {
|
uint16_t *rballoc_mask) {
|
||||||
@@ -1209,10 +1205,11 @@ void pf_ul(module_id_t module_id,
|
|||||||
/* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */
|
/* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */
|
||||||
remainUEs--;
|
remainUEs--;
|
||||||
|
|
||||||
|
// we have filled all with mandatory retransmissions
|
||||||
|
// no need to schedule new transmissions
|
||||||
if (remainUEs == 0)
|
if (remainUEs == 0)
|
||||||
// we have filled all with mandatory retransmissions
|
return;
|
||||||
// no need to schedule new transmissions
|
|
||||||
return;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const int B = max(0, sched_ctrl->estimated_ul_buffer - sched_ctrl->sched_ul_bytes);
|
const int B = max(0, sched_ctrl->estimated_ul_buffer - sched_ctrl->sched_ul_bytes);
|
||||||
@@ -1220,12 +1217,16 @@ void pf_ul(module_id_t module_id,
|
|||||||
const bool do_sched = nr_UE_is_to_be_scheduled(scc, 0, UE, sched_pusch->frame, sched_pusch->slot, nrmac->ulsch_max_frame_inactivity);
|
const bool do_sched = nr_UE_is_to_be_scheduled(scc, 0, UE, sched_pusch->frame, sched_pusch->slot, nrmac->ulsch_max_frame_inactivity);
|
||||||
|
|
||||||
LOG_D(NR_MAC,"pf_ul: do_sched UE %04x => %s\n",UE->rnti,do_sched ? "yes" : "no");
|
LOG_D(NR_MAC,"pf_ul: do_sched UE %04x => %s\n",UE->rnti,do_sched ? "yes" : "no");
|
||||||
if ((B == 0 && !do_sched) || (sched_ctrl->rrc_processing_timer > 0))
|
if ((B == 0 && !do_sched) || (sched_ctrl->rrc_processing_timer > 0)) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const NR_bler_options_t *bo = &nrmac->ul_bler;
|
const NR_bler_options_t *bo = &nrmac->ul_bler;
|
||||||
const int max_mcs = bo->max_mcs; /* no per-user maximum MCS yet */
|
const int max_mcs = bo->max_mcs; /* no per-user maximum MCS yet */
|
||||||
sched_pusch->mcs = get_mcs_from_bler(bo, stats, &UE->UE_sched_ctrl.ul_bler_stats, max_mcs, frame);
|
if (bo->harq_round_max == 1)
|
||||||
|
sched_pusch->mcs = max_mcs;
|
||||||
|
else
|
||||||
|
sched_pusch->mcs = get_mcs_from_bler(bo, stats, &UE->UE_sched_ctrl.ul_bler_stats, max_mcs, frame);
|
||||||
|
|
||||||
/* Schedule UE on SR or UL inactivity and no data (otherwise, will be scheduled
|
/* Schedule UE on SR or UL inactivity and no data (otherwise, will be scheduled
|
||||||
* based on data to transmit) */
|
* based on data to transmit) */
|
||||||
@@ -1235,12 +1236,12 @@ void pf_ul(module_id_t module_id,
|
|||||||
const uint32_t Y = get_Y(sched_ctrl->search_space, slot, UE->rnti);
|
const uint32_t Y = get_Y(sched_ctrl->search_space, slot, UE->rnti);
|
||||||
uint8_t nr_of_candidates;
|
uint8_t nr_of_candidates;
|
||||||
for (int i=0; i<5; i++) {
|
for (int i=0; i<5; i++) {
|
||||||
// for now taking the lowest value among the available aggregation levels
|
// for now taking the lowest value among the available aggregation levels
|
||||||
find_aggregation_candidates(&sched_ctrl->aggregation_level,
|
find_aggregation_candidates(&sched_ctrl->aggregation_level,
|
||||||
&nr_of_candidates,
|
&nr_of_candidates,
|
||||||
sched_ctrl->search_space,
|
sched_ctrl->search_space,
|
||||||
1<<i);
|
1<<i);
|
||||||
if(nr_of_candidates>0) break;
|
if(nr_of_candidates>0) break;
|
||||||
}
|
}
|
||||||
int CCEIndex = find_pdcch_candidate(RC.nrmac[module_id],
|
int CCEIndex = find_pdcch_candidate(RC.nrmac[module_id],
|
||||||
CC_id,
|
CC_id,
|
||||||
@@ -1251,16 +1252,17 @@ void pf_ul(module_id_t module_id,
|
|||||||
Y);
|
Y);
|
||||||
|
|
||||||
if (CCEIndex<0) {
|
if (CCEIndex<0) {
|
||||||
LOG_D(NR_MAC, "%4d.%2d no free CCE for UL DCI UE %04x (BSR 0)\n", frame, slot, UE->rnti);
|
LOG_D(NR_MAC, "%4d.%2d no free CCE for UL DCI UE %04x (BSR 0)\n", frame, slot, UE->rnti);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */
|
/* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */
|
||||||
remainUEs--;
|
remainUEs--;
|
||||||
|
|
||||||
|
// we have filled all with mandatory retransmissions
|
||||||
|
// no need to schedule new transmissions
|
||||||
if (remainUEs == 0)
|
if (remainUEs == 0)
|
||||||
// we have filled all with mandatory retransmissions
|
return;
|
||||||
// no need to schedule new transmissions
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Save PUSCH field */
|
/* Save PUSCH field */
|
||||||
/* we want to avoid a lengthy deduction of DMRS and other parameters in
|
/* we want to avoid a lengthy deduction of DMRS and other parameters in
|
||||||
@@ -1355,7 +1357,7 @@ void pf_ul(module_id_t module_id,
|
|||||||
sched_ctrl->search_space,
|
sched_ctrl->search_space,
|
||||||
1<<i);
|
1<<i);
|
||||||
if(nr_of_candidates>0)
|
if(nr_of_candidates>0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
int CCEIndex = find_pdcch_candidate(RC.nrmac[module_id],
|
int CCEIndex = find_pdcch_candidate(RC.nrmac[module_id],
|
||||||
CC_id,
|
CC_id,
|
||||||
@@ -1464,8 +1466,8 @@ void pf_ul(module_id_t module_id,
|
|||||||
|
|
||||||
n_rb_sched -= sched_pusch->rbSize;
|
n_rb_sched -= sched_pusch->rbSize;
|
||||||
for (int rb = 0; rb < sched_ctrl->sched_pusch.rbSize; rb++)
|
for (int rb = 0; rb < sched_ctrl->sched_pusch.rbSize; rb++)
|
||||||
|
|
||||||
rballoc_mask[rb + sched_ctrl->sched_pusch.rbStart] ^= slbitmap;
|
rballoc_mask[rb + sched_ctrl->sched_pusch.rbStart] ^= slbitmap;
|
||||||
|
|
||||||
/* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */
|
/* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */
|
||||||
remainUEs--;
|
remainUEs--;
|
||||||
iterator++;
|
iterator++;
|
||||||
@@ -1485,8 +1487,8 @@ bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
|
|||||||
const int mu = scc ? scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing :
|
const int mu = scc ? scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing :
|
||||||
scc_sib1->uplinkConfigCommon->initialUplinkBWP.genericParameters.subcarrierSpacing;
|
scc_sib1->uplinkConfigCommon->initialUplinkBWP.genericParameters.subcarrierSpacing;
|
||||||
|
|
||||||
|
// no UEs
|
||||||
if (nr_mac->UE_info.list[0] == NULL)
|
if (nr_mac->UE_info.list[0] == NULL)
|
||||||
// no UEs
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const int CC_id = 0;
|
const int CC_id = 0;
|
||||||
@@ -1533,8 +1535,7 @@ bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
|
|||||||
UE_iterator(nr_mac->UE_info.list, UE2) {
|
UE_iterator(nr_mac->UE_info.list, UE2) {
|
||||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE2->UE_sched_ctrl;
|
NR_UE_sched_ctrl_t *sched_ctrl = &UE2->UE_sched_ctrl;
|
||||||
AssertFatal(K2 == get_K2(scc,scc_sib1,sched_ctrl->active_ubwp, tda, mu),
|
AssertFatal(K2 == get_K2(scc,scc_sib1,sched_ctrl->active_ubwp, tda, mu),
|
||||||
"Different K2, %d(UE%d) != %ld(UE%04x)\n",
|
"Different K2, %d(UE%d) != %ld(UE%04x)\n", K2, 0, get_K2(scc,scc_sib1,sched_ctrl->active_ubwp, tda, mu), UE2->rnti);
|
||||||
K2, 0, get_K2(scc,scc_sib1,sched_ctrl->active_ubwp, tda, mu), UE2->rnti);
|
|
||||||
sched_ctrl->sched_pusch.slot = sched_slot;
|
sched_ctrl->sched_pusch.slot = sched_slot;
|
||||||
sched_ctrl->sched_pusch.frame = sched_frame;
|
sched_ctrl->sched_pusch.frame = sched_frame;
|
||||||
}
|
}
|
||||||
@@ -1711,7 +1712,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
|
|||||||
NR_pusch_semi_static_t *ps = &sched_ctrl->pusch_semi_static;
|
NR_pusch_semi_static_t *ps = &sched_ctrl->pusch_semi_static;
|
||||||
|
|
||||||
/* Statistics */
|
/* Statistics */
|
||||||
AssertFatal(cur_harq->round < 8, "Indexing ulsch_rounds[%d] is out of bounds\n", cur_harq->round);
|
AssertFatal(cur_harq->round < nr_mac->ul_bler.harq_round_max, "Indexing ulsch_rounds[%d] is out of bounds\n", cur_harq->round);
|
||||||
UE->mac_stats.ul.rounds[cur_harq->round]++;
|
UE->mac_stats.ul.rounds[cur_harq->round]++;
|
||||||
if (cur_harq->round == 0) {
|
if (cur_harq->round == 0) {
|
||||||
UE->mac_stats.ulsch_total_bytes_scheduled += sched_pusch->tb_size;
|
UE->mac_stats.ulsch_total_bytes_scheduled += sched_pusch->tb_size;
|
||||||
@@ -1757,7 +1758,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
|
|||||||
sched_pusch->tb_size,
|
sched_pusch->tb_size,
|
||||||
harq_id,
|
harq_id,
|
||||||
cur_harq->round,
|
cur_harq->round,
|
||||||
nr_rv_round_map[cur_harq->round],
|
nr_rv_round_map[cur_harq->round%4],
|
||||||
cur_harq->ndi,
|
cur_harq->ndi,
|
||||||
sched_ctrl->estimated_ul_buffer,
|
sched_ctrl->estimated_ul_buffer,
|
||||||
sched_ctrl->sched_ul_bytes,
|
sched_ctrl->sched_ul_bytes,
|
||||||
@@ -1853,8 +1854,8 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
|
|||||||
pusch_pdu->nr_of_symbols = ps->nrOfSymbols;
|
pusch_pdu->nr_of_symbols = ps->nrOfSymbols;
|
||||||
|
|
||||||
/* PUSCH PDU */
|
/* PUSCH PDU */
|
||||||
AssertFatal(cur_harq->round < 4, "Indexing nr_rv_round_map[%d] is out of bounds\n", cur_harq->round);
|
AssertFatal(cur_harq->round < nr_mac->ul_bler.harq_round_max, "Indexing nr_rv_round_map[%d] is out of bounds\n", cur_harq->round%4);
|
||||||
pusch_pdu->pusch_data.rv_index = nr_rv_round_map[cur_harq->round];
|
pusch_pdu->pusch_data.rv_index = nr_rv_round_map[cur_harq->round%4];
|
||||||
pusch_pdu->pusch_data.harq_process_id = harq_id;
|
pusch_pdu->pusch_data.harq_process_id = harq_id;
|
||||||
pusch_pdu->pusch_data.new_data_indicator = cur_harq->ndi;
|
pusch_pdu->pusch_data.new_data_indicator = cur_harq->ndi;
|
||||||
pusch_pdu->pusch_data.tb_size = sched_pusch->tb_size;
|
pusch_pdu->pusch_data.tb_size = sched_pusch->tb_size;
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ uint32_t schedule_control_sib1(module_id_t module_id,
|
|||||||
int nrOfSymbols,
|
int nrOfSymbols,
|
||||||
uint16_t dlDmrsSymbPos,
|
uint16_t dlDmrsSymbPos,
|
||||||
uint8_t candidate_idx,
|
uint8_t candidate_idx,
|
||||||
int num_total_bytes);
|
uint16_t num_total_bytes);
|
||||||
|
|
||||||
/* \brief default FR1 DL preprocessor init routine, returns preprocessor to call */
|
/* \brief default FR1 DL preprocessor init routine, returns preprocessor to call */
|
||||||
nr_pp_impl_dl nr_init_fr1_dlsch_preprocessor(module_id_t module_id, int CC_id);
|
nr_pp_impl_dl nr_init_fr1_dlsch_preprocessor(module_id_t module_id, int CC_id);
|
||||||
@@ -201,7 +201,7 @@ void config_uldci(const NR_SIB1_t *sib1,
|
|||||||
int n_ubwp,
|
int n_ubwp,
|
||||||
int bwp_id);
|
int bwp_id);
|
||||||
|
|
||||||
void nr_schedule_pucch(gNB_MAC_INST* nrmac,
|
void nr_schedule_pucch(gNB_MAC_INST *nrmac,
|
||||||
frame_t frameP,
|
frame_t frameP,
|
||||||
sub_frame_t slotP);
|
sub_frame_t slotP);
|
||||||
|
|
||||||
@@ -216,12 +216,12 @@ void nr_csi_meas_reporting(int Mod_idP,
|
|||||||
frame_t frameP,
|
frame_t frameP,
|
||||||
sub_frame_t slotP);
|
sub_frame_t slotP);
|
||||||
|
|
||||||
int nr_acknack_scheduling( int Mod_idP,
|
int nr_acknack_scheduling(int Mod_idP,
|
||||||
NR_UE_info_t * UE,
|
NR_UE_info_t *UE,
|
||||||
frame_t frameP,
|
frame_t frameP,
|
||||||
sub_frame_t slotP,
|
sub_frame_t slotP,
|
||||||
int r_pucch,
|
int r_pucch,
|
||||||
int do_common);
|
int do_common);
|
||||||
|
|
||||||
void get_pdsch_to_harq_feedback(NR_UE_info_t *,
|
void get_pdsch_to_harq_feedback(NR_UE_info_t *,
|
||||||
int bwp_id,
|
int bwp_id,
|
||||||
@@ -410,8 +410,6 @@ void nr_mac_remove_ra_rnti(module_id_t mod_id, rnti_t rnti);
|
|||||||
|
|
||||||
int nr_get_default_pucch_res(int pucch_ResourceCommon);
|
int nr_get_default_pucch_res(int pucch_ResourceCommon);
|
||||||
|
|
||||||
void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_UE_info_t *UE);
|
|
||||||
|
|
||||||
int get_dlscs(nfapi_nr_config_request_t *cfg);
|
int get_dlscs(nfapi_nr_config_request_t *cfg);
|
||||||
|
|
||||||
int get_ulscs(nfapi_nr_config_request_t *cfg);
|
int get_ulscs(nfapi_nr_config_request_t *cfg);
|
||||||
|
|||||||
@@ -105,17 +105,21 @@ size_t dump_mac_stats(gNB_MAC_INST *gNB, char *output, size_t strlen, bool reset
|
|||||||
end - output,
|
end - output,
|
||||||
"UE %04x: CQI %d, RI %d, PMI (%d,%d)\n",
|
"UE %04x: CQI %d, RI %d, PMI (%d,%d)\n",
|
||||||
UE->rnti,
|
UE->rnti,
|
||||||
UE->UE_sched_ctrl.CSI_report.cri_ri_li_pmi_cqi_report.wb_cqi_1tb,
|
sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.wb_cqi_1tb,
|
||||||
UE->UE_sched_ctrl.CSI_report.cri_ri_li_pmi_cqi_report.ri+1,
|
sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.ri+1,
|
||||||
UE->UE_sched_ctrl.CSI_report.cri_ri_li_pmi_cqi_report.pmi_x1,
|
sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.pmi_x1,
|
||||||
UE->UE_sched_ctrl.CSI_report.cri_ri_li_pmi_cqi_report.pmi_x2);
|
sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.pmi_x2);
|
||||||
|
|
||||||
output += snprintf(output,
|
output += snprintf(output,
|
||||||
end - output,
|
end - output,
|
||||||
"UE %04x: dlsch_rounds %"PRIu64"/%"PRIu64"/%"PRIu64"/%"PRIu64", dlsch_errors %"PRIu64", pucch0_DTX %d, BLER %.5f MCS %d\n",
|
"UE %04x: dlsch_rounds ", UE->rnti);
|
||||||
UE->rnti,
|
output += snprintf(output, end - output, "%"PRIu64, stats->dl.rounds[0]);
|
||||||
stats->dl.rounds[0], stats->dl.rounds[1],
|
for (int i = 1; i < gNB->dl_bler.harq_round_max; i++)
|
||||||
stats->dl.rounds[2], stats->dl.rounds[3],
|
output += snprintf(output, end - output, "/%"PRIu64, stats->dl.rounds[i]);
|
||||||
|
|
||||||
|
output += snprintf(output,
|
||||||
|
end - output,
|
||||||
|
", dlsch_errors %"PRIu64", pucch0_DTX %d, BLER %.5f MCS %d\n",
|
||||||
stats->dl.errors,
|
stats->dl.errors,
|
||||||
stats->pucch0_DTX,
|
stats->pucch0_DTX,
|
||||||
sched_ctrl->dl_bler_stats.bler,
|
sched_ctrl->dl_bler_stats.bler,
|
||||||
@@ -127,23 +131,27 @@ size_t dump_mac_stats(gNB_MAC_INST *gNB, char *output, size_t strlen, bool reset
|
|||||||
output += snprintf(output,
|
output += snprintf(output,
|
||||||
end - output,
|
end - output,
|
||||||
"UE %04x: dlsch_total_bytes %"PRIu64"\n",
|
"UE %04x: dlsch_total_bytes %"PRIu64"\n",
|
||||||
UE->rnti,
|
UE->rnti, stats->dl.total_bytes);
|
||||||
stats->dl.total_bytes);
|
|
||||||
output += snprintf(output,
|
output += snprintf(output,
|
||||||
end - output,
|
end - output,
|
||||||
"UE %04x: ulsch_rounds %"PRIu64"/%"PRIu64"/%"PRIu64"/%"PRIu64", ulsch_DTX %d, ulsch_errors %"PRIu64", BLER %.5f MCS %d\n",
|
"UE %04x: ulsch_rounds ", UE->rnti);
|
||||||
UE->rnti,
|
output += snprintf(output, end - output, "%"PRIu64, stats->ul.rounds[0]);
|
||||||
stats->ul.rounds[0], stats->ul.rounds[1],
|
for (int i = 1; i < gNB->ul_bler.harq_round_max; i++)
|
||||||
stats->ul.rounds[2], stats->ul.rounds[3],
|
output += snprintf(output, end - output, "/%"PRIu64, stats->ul.rounds[i]);
|
||||||
|
|
||||||
|
output += snprintf(output,
|
||||||
|
end - output,
|
||||||
|
", ulsch_DTX %d, ulsch_errors %"PRIu64", BLER %.5f MCS %d\n",
|
||||||
stats->ulsch_DTX,
|
stats->ulsch_DTX,
|
||||||
stats->ul.errors,
|
stats->ul.errors,
|
||||||
sched_ctrl->ul_bler_stats.bler,
|
sched_ctrl->ul_bler_stats.bler,
|
||||||
sched_ctrl->ul_bler_stats.mcs);
|
sched_ctrl->ul_bler_stats.mcs);
|
||||||
output += snprintf(output,
|
output += snprintf(output,
|
||||||
end - output,
|
end - output,
|
||||||
"UE %04x: ulsch_total_bytes_scheduled %"PRIu64", ulsch_total_bytes_received %"PRIu64"\n",
|
"UE %04x: ulsch_total_bytes_scheduled %"PRIu64", ulsch_total_bytes_received %"PRIu64"\n",
|
||||||
UE->rnti,
|
UE->rnti,
|
||||||
stats->ulsch_total_bytes_scheduled, stats->ul.total_bytes);
|
stats->ulsch_total_bytes_scheduled, stats->ul.total_bytes);
|
||||||
|
|
||||||
for (int lc_id = 0; lc_id < 63; lc_id++) {
|
for (int lc_id = 0; lc_id < 63; lc_id++) {
|
||||||
if (stats->dl.lc_bytes[lc_id] > 0)
|
if (stats->dl.lc_bytes[lc_id] > 0)
|
||||||
output += snprintf(output,
|
output += snprintf(output,
|
||||||
|
|||||||
@@ -75,7 +75,6 @@
|
|||||||
#define MAX_NUM_BWP 5
|
#define MAX_NUM_BWP 5
|
||||||
#define MAX_NUM_CORESET 12
|
#define MAX_NUM_CORESET 12
|
||||||
#define MAX_NUM_CCE 90
|
#define MAX_NUM_CCE 90
|
||||||
#define MAX_HARQ_ROUNDS 4
|
|
||||||
/*!\brief Maximum number of random access process */
|
/*!\brief Maximum number of random access process */
|
||||||
#define NR_NB_RA_PROC_MAX 4
|
#define NR_NB_RA_PROC_MAX 4
|
||||||
#define MAX_NUM_OF_SSB 64
|
#define MAX_NUM_OF_SSB 64
|
||||||
@@ -510,38 +509,6 @@ struct CSI_Report {
|
|||||||
|
|
||||||
#define MAX_SR_BITLEN 8
|
#define MAX_SR_BITLEN 8
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint8_t nb_ssbri_cri;
|
|
||||||
uint8_t cri_ssbri_bitlen;
|
|
||||||
uint8_t rsrp_bitlen;
|
|
||||||
uint8_t diff_rsrp_bitlen;
|
|
||||||
}L1_RSRP_bitlen_t;
|
|
||||||
|
|
||||||
typedef struct{
|
|
||||||
uint8_t ri_restriction;
|
|
||||||
uint8_t cri_bitlen;
|
|
||||||
uint8_t ri_bitlen;
|
|
||||||
uint8_t li_bitlen[8];
|
|
||||||
uint8_t pmi_x1_bitlen[8];
|
|
||||||
uint8_t pmi_x2_bitlen[8];
|
|
||||||
uint8_t cqi_bitlen[8];
|
|
||||||
} CSI_Meas_bitlen_t;
|
|
||||||
|
|
||||||
typedef struct nr_csi_report {
|
|
||||||
NR_CSI_ReportConfig__reportQuantity_PR reportQuantity_type;
|
|
||||||
long periodicity;
|
|
||||||
uint16_t offset;
|
|
||||||
long ** SSB_Index_list;
|
|
||||||
long ** CSI_Index_list;
|
|
||||||
// uint8_t nb_of_nzp_csi_report;
|
|
||||||
uint8_t nb_of_csi_ssb_report;
|
|
||||||
L1_RSRP_bitlen_t CSI_report_bitlen;
|
|
||||||
CSI_Meas_bitlen_t csi_meas_bitlen;
|
|
||||||
int codebook_mode;
|
|
||||||
int N1;
|
|
||||||
int N2;
|
|
||||||
} nr_csi_report_t;
|
|
||||||
|
|
||||||
/*! As per the spec 38.212 and table: 6.3.1.1.2-12 in a single UCI sequence we can have multiple CSI_report
|
/*! As per the spec 38.212 and table: 6.3.1.1.2-12 in a single UCI sequence we can have multiple CSI_report
|
||||||
the number of CSI_report will depend on number of CSI resource sets that are configured in CSI-ResourceConfig RRC IE
|
the number of CSI_report will depend on number of CSI resource sets that are configured in CSI-ResourceConfig RRC IE
|
||||||
From spec 38.331 from the IE CSI-ResourceConfig for SSB RSRP reporting we can configure only one resource set
|
From spec 38.331 from the IE CSI-ResourceConfig for SSB RSRP reporting we can configure only one resource set
|
||||||
@@ -701,10 +668,10 @@ typedef struct NR_bler_options {
|
|||||||
double upper;
|
double upper;
|
||||||
double lower;
|
double lower;
|
||||||
uint8_t max_mcs;
|
uint8_t max_mcs;
|
||||||
|
uint8_t harq_round_max;
|
||||||
} NR_bler_options_t;
|
} NR_bler_options_t;
|
||||||
|
|
||||||
/*! \brief UE list used by gNB to order UEs/CC for scheduling*/
|
/*! \brief UE list used by gNB to order UEs/CC for scheduling*/
|
||||||
#define MAX_CSI_REPORTCONFIG 48
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
rnti_t rnti;
|
rnti_t rnti;
|
||||||
/// scheduling control info
|
/// scheduling control info
|
||||||
@@ -855,7 +822,6 @@ typedef struct gNB_MAC_INST_s {
|
|||||||
bool first_MIB;
|
bool first_MIB;
|
||||||
NR_bler_options_t dl_bler;
|
NR_bler_options_t dl_bler;
|
||||||
NR_bler_options_t ul_bler;
|
NR_bler_options_t ul_bler;
|
||||||
uint8_t harq_round_max;
|
|
||||||
uint8_t min_grant_prb;
|
uint8_t min_grant_prb;
|
||||||
uint8_t min_grant_mcs;
|
uint8_t min_grant_mcs;
|
||||||
} gNB_MAC_INST;
|
} gNB_MAC_INST;
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
#include "nr_pdcp_security_nea2.h"
|
#include "nr_pdcp_security_nea2.h"
|
||||||
#include "nr_pdcp_integrity_nia2.h"
|
#include "nr_pdcp_integrity_nia2.h"
|
||||||
|
#include "nr_pdcp_integrity_nia1.h"
|
||||||
#include "nr_pdcp_sdu.h"
|
#include "nr_pdcp_sdu.h"
|
||||||
|
|
||||||
#include "LOG/log.h"
|
#include "LOG/log.h"
|
||||||
@@ -240,16 +241,21 @@ static void nr_pdcp_entity_set_security(nr_pdcp_entity_t *entity,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (integrity_algorithm != 0 && integrity_algorithm != -1) {
|
if (integrity_algorithm != 0 && integrity_algorithm != -1) {
|
||||||
if (integrity_algorithm != 2) {
|
|
||||||
LOG_E(PDCP, "FATAL: only nia2 supported for the moment\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
entity->has_integrity = 1;
|
entity->has_integrity = 1;
|
||||||
if (entity->free_integrity != NULL)
|
if (entity->free_integrity != NULL)
|
||||||
entity->free_integrity(entity->integrity_context);
|
entity->free_integrity(entity->integrity_context);
|
||||||
entity->integrity_context = nr_pdcp_integrity_nia2_init(entity->integrity_key);
|
if (integrity_algorithm == 2) {
|
||||||
entity->integrity = nr_pdcp_integrity_nia2_integrity;
|
entity->integrity_context = nr_pdcp_integrity_nia2_init(entity->integrity_key);
|
||||||
entity->free_integrity = nr_pdcp_integrity_nia2_free_integrity;
|
entity->integrity = nr_pdcp_integrity_nia2_integrity;
|
||||||
|
entity->free_integrity = nr_pdcp_integrity_nia2_free_integrity;
|
||||||
|
} else if (integrity_algorithm == 1) {
|
||||||
|
entity->integrity_context = nr_pdcp_integrity_nia1_init(entity->integrity_key);
|
||||||
|
entity->integrity = nr_pdcp_integrity_nia1_integrity;
|
||||||
|
entity->free_integrity = nr_pdcp_integrity_nia1_free_integrity;
|
||||||
|
} else {
|
||||||
|
LOG_E(PDCP, "FATAL: only nia1 and nia2 supported for the moment\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ciphering_algorithm == 0) {
|
if (ciphering_algorithm == 0) {
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* 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_nia1.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <openssl/cmac.h>
|
||||||
|
|
||||||
|
#include "UTIL/OSA/osa_defs.h"
|
||||||
|
|
||||||
|
int stream_compute_integrity_eia1(stream_cipher_t *stream_cipher, uint8_t out[4]);
|
||||||
|
|
||||||
|
void *nr_pdcp_integrity_nia1_init(unsigned char *integrity_key)
|
||||||
|
{
|
||||||
|
stream_cipher_t *ret;
|
||||||
|
|
||||||
|
ret = calloc(1, sizeof(*ret)); if (ret == NULL) abort();
|
||||||
|
ret->key = malloc(16); if (ret->key == NULL) abort();
|
||||||
|
memcpy(ret->key, integrity_key, 16);
|
||||||
|
ret->key_length = 16; /* unused */
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nr_pdcp_integrity_nia1_integrity(void *integrity_context,
|
||||||
|
unsigned char *out,
|
||||||
|
unsigned char *buffer, int length,
|
||||||
|
int bearer, int count, int direction)
|
||||||
|
{
|
||||||
|
stream_cipher_t *ctx = integrity_context;
|
||||||
|
|
||||||
|
ctx->message = buffer;
|
||||||
|
ctx->count = count;
|
||||||
|
ctx->bearer = bearer-1;
|
||||||
|
ctx->direction = direction;
|
||||||
|
ctx->blength = length * 8;
|
||||||
|
|
||||||
|
stream_compute_integrity_eia1(ctx, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nr_pdcp_integrity_nia1_free_integrity(void *integrity_context)
|
||||||
|
{
|
||||||
|
stream_cipher_t *ctx = integrity_context;
|
||||||
|
free(ctx->key);
|
||||||
|
free(ctx);
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* 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_NIA1_H_
|
||||||
|
#define _NR_PDCP_INTEGRITY_NIA1_H_
|
||||||
|
|
||||||
|
void *nr_pdcp_integrity_nia1_init(unsigned char *integrity_key);
|
||||||
|
|
||||||
|
void nr_pdcp_integrity_nia1_integrity(void *integrity_context,
|
||||||
|
unsigned char *out,
|
||||||
|
unsigned char *buffer, int length,
|
||||||
|
int bearer, int count, int direction);
|
||||||
|
|
||||||
|
void nr_pdcp_integrity_nia1_free_integrity(void *integrity_context);
|
||||||
|
|
||||||
|
#endif /* _NR_PDCP_INTEGRITY_NIA1_H_ */
|
||||||
@@ -1103,6 +1103,10 @@ int8_t handle_dlsch(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t *u
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int8_t handle_csirs_measurements(module_id_t module_id, frame_t frame, int slot, fapi_nr_csirs_measurements_t *csirs_measurements) {
|
||||||
|
return nr_ue_process_csirs_measurements(module_id, frame, slot, csirs_measurements);
|
||||||
|
}
|
||||||
|
|
||||||
void update_harq_status(module_id_t module_id, uint8_t harq_pid, uint8_t ack_nack) {
|
void update_harq_status(module_id_t module_id, uint8_t harq_pid, uint8_t ack_nack) {
|
||||||
|
|
||||||
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
|
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
|
||||||
@@ -1228,7 +1232,7 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_
|
|||||||
(dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.ssb_length,
|
(dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.ssb_length,
|
||||||
(dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.ssb_start_subcarrier,
|
(dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.ssb_start_subcarrier,
|
||||||
(dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.cell_id)) << FAPI_NR_RX_PDU_TYPE_SSB;
|
(dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.cell_id)) << FAPI_NR_RX_PDU_TYPE_SSB;
|
||||||
free((dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.pdu);
|
free((dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.pdu);
|
||||||
break;
|
break;
|
||||||
case FAPI_NR_RX_PDU_TYPE_SIB:
|
case FAPI_NR_RX_PDU_TYPE_SIB:
|
||||||
ret_mask |= (handle_bcch_dlsch(dl_info->module_id,
|
ret_mask |= (handle_bcch_dlsch(dl_info->module_id,
|
||||||
@@ -1243,6 +1247,12 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_
|
|||||||
case FAPI_NR_RX_PDU_TYPE_RAR:
|
case FAPI_NR_RX_PDU_TYPE_RAR:
|
||||||
ret_mask |= (handle_dlsch(dl_info, ul_time_alignment, i)) << FAPI_NR_RX_PDU_TYPE_RAR;
|
ret_mask |= (handle_dlsch(dl_info, ul_time_alignment, i)) << FAPI_NR_RX_PDU_TYPE_RAR;
|
||||||
break;
|
break;
|
||||||
|
case FAPI_NR_CSIRS_IND:
|
||||||
|
ret_mask |= (handle_csirs_measurements(dl_info->module_id,
|
||||||
|
dl_info->frame,
|
||||||
|
dl_info->slot,
|
||||||
|
&(dl_info->rx_ind->rx_indication_body+i)->csirs_measurements)) << FAPI_NR_CSIRS_IND;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
+33
-91
@@ -976,28 +976,24 @@ rrc_eNB_free_UE(
|
|||||||
put_UE_in_freelist(enb_mod_idP, rnti, 1);
|
put_UE_in_freelist(enb_mod_idP, rnti, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void remove_UE_from_freelist(module_id_t mod_id, rnti_t rnti) {
|
|
||||||
eNB_MAC_INST *eNB_MAC = RC.mac[mod_id];
|
|
||||||
pthread_mutex_lock(&lock_ue_freelist);
|
|
||||||
UE_free_list_t *free_list = &eNB_MAC->UE_free_list;
|
|
||||||
free_list->UE_free_ctrl[free_list->head_freelist].rnti = 0;
|
|
||||||
free_list->head_freelist = (free_list->head_freelist + 1) % (NUMBER_OF_UE_MAX+1);
|
|
||||||
free_list->num_UEs--;
|
|
||||||
pthread_mutex_unlock(&lock_ue_freelist);
|
|
||||||
}
|
|
||||||
|
|
||||||
void put_UE_in_freelist(module_id_t mod_id, rnti_t rnti, bool removeFlag) {
|
void put_UE_in_freelist(module_id_t mod_id, rnti_t rnti, bool removeFlag) {
|
||||||
UE_free_list_t *free_list = NULL;
|
|
||||||
eNB_MAC_INST *eNB_MAC = RC.mac[mod_id];
|
eNB_MAC_INST *eNB_MAC = RC.mac[mod_id];
|
||||||
pthread_mutex_lock(&lock_ue_freelist);
|
pthread_mutex_lock(&lock_ue_freelist);
|
||||||
free_list = &eNB_MAC->UE_free_list;
|
LOG_I(PHY,"add ue %d in fre list, context flag: %d\n", rnti, removeFlag);
|
||||||
free_list->UE_free_ctrl[free_list->tail_freelist].rnti = rnti;
|
int i;
|
||||||
free_list->UE_free_ctrl[free_list->tail_freelist].removeContextFlg = removeFlag;
|
for (i=0; i < sizeofArray(eNB_MAC->UE_free_ctrl); i++)
|
||||||
free_list->UE_free_ctrl[free_list->tail_freelist].raFlag = 0;
|
if (eNB_MAC->UE_free_ctrl[i].rnti == 0)
|
||||||
free_list->num_UEs++;
|
break;
|
||||||
|
if (i==sizeofArray(eNB_MAC->UE_free_ctrl)) {
|
||||||
|
LOG_E(PHY,"List of UE to free is full\n");
|
||||||
|
pthread_mutex_unlock(&lock_ue_freelist);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
eNB_MAC->UE_free_ctrl[i].rnti = rnti;
|
||||||
|
eNB_MAC->UE_free_ctrl[i].removeContextFlg = removeFlag;
|
||||||
|
eNB_MAC->UE_free_ctrl[i].raFlag = 0;
|
||||||
eNB_MAC->UE_release_req.ue_release_request_body.ue_release_request_TLVs_list[eNB_MAC->UE_release_req.ue_release_request_body.number_of_TLVs].rnti = rnti;
|
eNB_MAC->UE_release_req.ue_release_request_body.ue_release_request_TLVs_list[eNB_MAC->UE_release_req.ue_release_request_body.number_of_TLVs].rnti = rnti;
|
||||||
eNB_MAC->UE_release_req.ue_release_request_body.number_of_TLVs++;
|
eNB_MAC->UE_release_req.ue_release_request_body.number_of_TLVs++;
|
||||||
free_list->tail_freelist = (free_list->tail_freelist + 1) % (NUMBER_OF_UE_MAX+1);
|
|
||||||
pthread_mutex_unlock(&lock_ue_freelist);
|
pthread_mutex_unlock(&lock_ue_freelist);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1007,104 +1003,47 @@ extern void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch);
|
|||||||
extern void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch);
|
extern void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch);
|
||||||
|
|
||||||
void release_UE_in_freeList(module_id_t mod_id) {
|
void release_UE_in_freeList(module_id_t mod_id) {
|
||||||
int i, j, CC_id, pdu_number;
|
|
||||||
protocol_ctxt_t ctxt;
|
|
||||||
nfapi_ul_config_request_body_t *ul_req_tmp = NULL;
|
|
||||||
PHY_VARS_eNB *eNB_PHY = NULL;
|
PHY_VARS_eNB *eNB_PHY = NULL;
|
||||||
struct rrc_eNB_ue_context_s *ue_context_pP = NULL;
|
|
||||||
eNB_MAC_INST *eNB_MAC = RC.mac[mod_id];
|
eNB_MAC_INST *eNB_MAC = RC.mac[mod_id];
|
||||||
bool remove_UEContext;
|
|
||||||
rnti_t rnti;
|
|
||||||
int head, tail, ue_num;
|
|
||||||
pthread_mutex_lock(&lock_ue_freelist);
|
pthread_mutex_lock(&lock_ue_freelist);
|
||||||
head = eNB_MAC->UE_free_list.head_freelist;
|
|
||||||
tail = eNB_MAC->UE_free_list.tail_freelist;
|
|
||||||
|
|
||||||
if(head == tail) {
|
for(int ue_num = 0; ue_num < sizeofArray(eNB_MAC->UE_free_ctrl) ; ue_num++) {
|
||||||
pthread_mutex_unlock(&lock_ue_freelist);
|
rnti_t rnti = eNB_MAC->UE_free_ctrl[ue_num].rnti;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(tail < head) {
|
|
||||||
tail = head + eNB_MAC->UE_free_list.num_UEs;
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_mutex_unlock(&lock_ue_freelist);
|
|
||||||
|
|
||||||
for(ue_num = head; ue_num < tail; ue_num++) {
|
|
||||||
ue_num = ue_num % (NUMBER_OF_UE_MAX+1);
|
|
||||||
rnti = eNB_MAC->UE_free_list.UE_free_ctrl[ue_num].rnti;
|
|
||||||
|
|
||||||
if(rnti != 0) {
|
if(rnti != 0) {
|
||||||
remove_UEContext = eNB_MAC->UE_free_list.UE_free_ctrl[ue_num].removeContextFlg;
|
protocol_ctxt_t ctxt;
|
||||||
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, mod_id, ENB_FLAG_YES, rnti, 0, 0,mod_id);
|
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, mod_id, ENB_FLAG_YES, rnti, 0, 0,mod_id);
|
||||||
|
|
||||||
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
|
for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
|
||||||
eNB_PHY = RC.eNB[mod_id][CC_id];
|
eNB_PHY = RC.eNB[mod_id][CC_id];
|
||||||
int id;
|
int id;
|
||||||
// clean ULSCH entries for rnti
|
// clean ULSCH entries for rnti
|
||||||
id = find_ulsch(rnti,eNB_PHY,eNB_MAC->UE_free_list.UE_free_ctrl[ue_num].raFlag ? SEARCH_EXIST_RA : SEARCH_EXIST);
|
id = find_ulsch(rnti,eNB_PHY,eNB_MAC->UE_free_ctrl[ue_num].raFlag ? SEARCH_EXIST_RA : SEARCH_EXIST);
|
||||||
|
|
||||||
if (id>=0) clean_eNb_ulsch(eNB_PHY->ulsch[id]);
|
if (id>=0) clean_eNb_ulsch(eNB_PHY->ulsch[id]);
|
||||||
|
|
||||||
// clean DLSCH entries for rnti
|
// clean DLSCH entries for rnti
|
||||||
id = find_dlsch(rnti,eNB_PHY,eNB_MAC->UE_free_list.UE_free_ctrl[ue_num].raFlag ? SEARCH_EXIST_RA : SEARCH_EXIST);
|
id = find_dlsch(rnti,eNB_PHY,eNB_MAC->UE_free_ctrl[ue_num].raFlag ? SEARCH_EXIST_RA : SEARCH_EXIST);
|
||||||
|
|
||||||
if (id>=0) clean_eNb_dlsch(eNB_PHY->dlsch[id][0]);
|
if (id>=0) clean_eNb_dlsch(eNB_PHY->dlsch[id][0]);
|
||||||
|
|
||||||
// clean UCI entries for rnti
|
// clean UCI entries for rnti
|
||||||
for (i=0; i<NUMBER_OF_UCI_MAX; i++) {
|
for (int i=0; i<NUMBER_OF_UCI_MAX; i++) {
|
||||||
if(eNB_PHY->uci_vars[i].rnti == rnti) {
|
if(eNB_PHY->uci_vars[i].rnti == rnti) {
|
||||||
LOG_I(MAC, "clean eNb uci_vars[%d] UE %x \n",i, rnti);
|
LOG_I(MAC, "clean eNb uci_vars[%d] UE %x \n",i, rnti);
|
||||||
memset(&eNB_PHY->uci_vars[i],0,sizeof(LTE_eNB_UCI));
|
memset(&eNB_PHY->uci_vars[i],0,sizeof(LTE_eNB_UCI));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
for (i=0; i<MAX_MOBILES_PER_ENB; i++) {
|
|
||||||
ulsch = eNB_PHY->ulsch[i];
|
|
||||||
|
|
||||||
if((ulsch != NULL) && (ulsch->rnti == rnti)) {
|
|
||||||
void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch);
|
|
||||||
LOG_I(RRC, "clean_eNb_ulsch ulsch[%d] UE %x\n", i, rnti);
|
|
||||||
clean_eNb_ulsch(ulsch);
|
|
||||||
}
|
|
||||||
|
|
||||||
dlsch = eNB_PHY->dlsch[i][0];
|
|
||||||
|
|
||||||
if((dlsch != NULL) && (dlsch->rnti == rnti)) {
|
|
||||||
void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch);
|
|
||||||
LOG_I(RRC, "clean_eNb_dlsch dlsch[%d] UE %x \n", i, rnti);
|
|
||||||
clean_eNb_dlsch(dlsch);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ulsch = eNB_PHY->ulsch[i];
|
|
||||||
|
|
||||||
if((ulsch != NULL) && (ulsch->rnti == rnti)) {
|
|
||||||
void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch);
|
|
||||||
LOG_I(RRC, "clean_eNb_ulsch ulsch[%d] UE %x\n", i, rnti);
|
|
||||||
clean_eNb_ulsch(ulsch);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i=0; i<NUMBER_OF_UCI_MAX; i++) {
|
|
||||||
if(eNB_PHY->uci_vars[i].rnti == rnti) {
|
|
||||||
LOG_I(MAC, "clean eNb uci_vars[%d] UE %x \n",i, rnti);
|
|
||||||
memset(&eNB_PHY->uci_vars[i],0,sizeof(LTE_eNB_UCI));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (flexran_agent_get_rrc_xface(mod_id)) {
|
if (flexran_agent_get_rrc_xface(mod_id)) {
|
||||||
flexran_agent_get_rrc_xface(mod_id)->flexran_agent_notify_ue_state_change(
|
flexran_agent_get_rrc_xface(mod_id)->flexran_agent_notify_ue_state_change( mod_id, rnti, PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED);
|
||||||
mod_id, rnti, PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for(j = 0; j < 10; j++) {
|
for(int j = 0; j < 10; j++) {
|
||||||
ul_req_tmp = &eNB_MAC->UL_req_tmp[CC_id][j].ul_config_request_body;
|
nfapi_ul_config_request_body_t *ul_req_tmp = &eNB_MAC->UL_req_tmp[CC_id][j].ul_config_request_body;
|
||||||
|
|
||||||
if(ul_req_tmp) {
|
if(ul_req_tmp) {
|
||||||
pdu_number = ul_req_tmp->number_of_pdus;
|
int pdu_number = ul_req_tmp->number_of_pdus;
|
||||||
|
|
||||||
for(int pdu_index = pdu_number-1; pdu_index >= 0; pdu_index--) {
|
for(int pdu_index = pdu_number-1; pdu_index >= 0; pdu_index--) {
|
||||||
if((ul_req_tmp->ul_config_pdu_list[pdu_index].ulsch_pdu.ulsch_pdu_rel8.rnti == rnti) ||
|
if((ul_req_tmp->ul_config_pdu_list[pdu_index].ulsch_pdu.ulsch_pdu_rel8.rnti == rnti) ||
|
||||||
@@ -1126,7 +1065,8 @@ void release_UE_in_freeList(module_id_t mod_id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!NODE_IS_CU(RC.rrc[mod_id]->node_type)) {
|
if (!NODE_IS_CU(RC.rrc[mod_id]->node_type)) {
|
||||||
rrc_mac_remove_ue(mod_id,rnti);
|
if (!eNB_MAC->UE_free_ctrl[ue_num].raFlag)
|
||||||
|
rrc_mac_remove_ue(mod_id,rnti);
|
||||||
rrc_rlc_remove_ue(&ctxt);
|
rrc_rlc_remove_ue(&ctxt);
|
||||||
pdcp_remove_UE(&ctxt);
|
pdcp_remove_UE(&ctxt);
|
||||||
} else {
|
} else {
|
||||||
@@ -1139,19 +1079,20 @@ void release_UE_in_freeList(module_id_t mod_id) {
|
|||||||
itti_send_msg_to_task(TASK_CU_F1, mod_id, m);
|
itti_send_msg_to_task(TASK_CU_F1, mod_id, m);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(remove_UEContext) {
|
if(eNB_MAC->UE_free_ctrl[ue_num].removeContextFlg) {
|
||||||
ue_context_pP = rrc_eNB_get_ue_context(RC.rrc[mod_id],rnti);
|
struct rrc_eNB_ue_context_s *ue_context_pP = rrc_eNB_get_ue_context(RC.rrc[mod_id],rnti);
|
||||||
|
|
||||||
if(ue_context_pP) {
|
if(ue_context_pP) {
|
||||||
|
LOG_I(PHY, "remove RNTI %04x\n", rnti);
|
||||||
rrc_eNB_remove_ue_context(&ctxt,RC.rrc[mod_id],
|
rrc_eNB_remove_ue_context(&ctxt,RC.rrc[mod_id],
|
||||||
(struct rrc_eNB_ue_context_s *) ue_context_pP);
|
(struct rrc_eNB_ue_context_s *) ue_context_pP);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_I(RRC, "[release_UE_in_freeList] remove UE %x from freeList\n", rnti);
|
LOG_I(RRC, "[release_UE_in_freeList] remove UE %x from freeList ra context: %d\n", rnti, eNB_MAC->UE_free_ctrl[ue_num].raFlag);
|
||||||
remove_UE_from_freelist(mod_id, rnti);
|
eNB_MAC->UE_free_ctrl[ue_num].rnti = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pthread_mutex_unlock(&lock_ue_freelist);
|
||||||
}
|
}
|
||||||
|
|
||||||
int rrc_eNB_previous_SRB2(rrc_eNB_ue_context_t *ue_context_pP) {
|
int rrc_eNB_previous_SRB2(rrc_eNB_ue_context_t *ue_context_pP) {
|
||||||
@@ -7246,6 +7187,7 @@ rrc_eNB_decode_ccch(
|
|||||||
LOG_I(RRC," S-TMSI exists, ue_context_p %p, old rnti %x => %x\n",ue_context_p,ue_context_p->ue_context.rnti,ctxt_pP->rnti);
|
LOG_I(RRC," S-TMSI exists, ue_context_p %p, old rnti %x => %x\n",ue_context_p,ue_context_p->ue_context.rnti,ctxt_pP->rnti);
|
||||||
|
|
||||||
if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) {
|
if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) {
|
||||||
|
LOG_I(PHY, "remove RNTI %04x\n", ue_context_p->ue_context.rnti);
|
||||||
rrc_mac_remove_ue(ctxt_pP->module_id, ue_context_p->ue_context.rnti);
|
rrc_mac_remove_ue(ctxt_pP->module_id, ue_context_p->ue_context.rnti);
|
||||||
} else {
|
} else {
|
||||||
MessageDef *m = itti_alloc_new_message(TASK_RRC_ENB, 0, F1AP_UE_CONTEXT_RELEASE_CMD);
|
MessageDef *m = itti_alloc_new_message(TASK_RRC_ENB, 0, F1AP_UE_CONTEXT_RELEASE_CMD);
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user