Commit b1a8b065 authored by rmagueta's avatar rmagueta

Merge remote-tracking branch 'origin/integration_2021_wk41' into integration_2021_wk41_bwt-abs

# Conflicts:
#	ci-scripts/xml_files/fr1_sa_quectel.xml
#	openair1/SCHED_NR/fapi_nr_l1.c
#	openair1/SCHED_NR/phy_procedures_nr_gNB.c
#	openair2/GNB_APP/gnb_paramdef.h
parents 614c29ad 563fd66b
......@@ -220,6 +220,21 @@ pipeline {
}
}
}
stage ("Images Push to Registries") {
when { expression {"PUSH".equals(env.gitlabActionType)} }
steps {
script {
triggerSlaveJob ('RAN-DockerHub-Push', 'Push-to-Docker-Hub')
}
post {
failure {
script {
currentBuild.result = 'FAILURE'
}
}
}
}
}
}
post {
always {
......
#!/bin/groovy
/*
* 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
*/
// Location of the python executor node shall be in the same subnet as the others servers
def nodeExecutor = params.nodeExecutor
// Name of the phone resource
def ciServerResource = params.serverResource
pipeline {
agent {
label nodeExecutor
}
options {
disableConcurrentBuilds()
ansiColor('xterm')
lock (ciServerResource)
}
stages {
stage ("Verify Parameters") {
steps {
script {
echo '\u2705 \u001B[32mVerify Parameters\u001B[0m'
def allParametersPresent = true
// It is already to late to check it
if (params.nodeExecutor != null) {
echo "Docker Push executor node : ${nodeExecutor}"
}
if (params.serverResource == null) {
allParametersPresent = false
}
}
}
}
stage ("Push to DockerHub") {
steps {
script {
WEEK_TAG = sh returnStdout: true, script: 'date +"%Y.w%U"'
WEEK_TAG = WEEK_TAG.trim()
withCredentials([
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.DH_Credentials}", usernameVariable: 'DH_Username', passwordVariable: 'DH_Password']
]) {
def listOfImages = ["oai-enb", "oai-gnb", "oai-lte-ue", "oai-nr-ue"]
sh "docker login -u ${DH_Username} -p ${DH_Password} > /dev/null 2>&1"
listOfImages.eachWithIndex { item, iindex ->
sh "docker image tag ${item}:develop ${DH_Username}/${item}:develop"
sh "docker image tag ${item}:develop ${DH_Username}/${item}:${WEEK_TAG}"
sh "docker push --quiet ${DH_Username}/${item}:${WEEK_TAG}"
sh "docker push --quiet ${DH_Username}/${item}:develop"
sh "docker rmi ${DH_Username}/${item}:${WEEK_TAG} ${DH_Username}/${item}:develop"
}
sh "docker logout > /dev/null 2>&1"
}
}
}
}
}
post {
always {
script {
echo "End of Registry Push"
}
}
}
}
......@@ -265,6 +265,21 @@ pipeline {
if(fileExists("enb.log.${env.BUILD_ID}.zip")) {
archiveArtifacts "enb.log.${env.BUILD_ID}.zip"
}
}
}
}
stage('Log Collection (CN)') {
steps {
withCredentials([
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password']
]) {
echo '\u2705 \u001B[32mLog Transfer (CN)\u001B[0m'
sh "sshpass -p \'${EPC_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${EPC_Username}@${params.EPC_IPAddress}:${EPC_SourceCodePath}/logs/oai-cn5g.log.zip ./oai-cn5g.log.${env.BUILD_ID}.zip || true"
}
script {
if(fileExists("oai-cn5g.log.${env.BUILD_ID}.zip")) {
archiveArtifacts "oai-cn5g.log.${env.BUILD_ID}.zip"
}
if(fileExists("ci-scripts/test_results.html")) {
sh "mv ci-scripts/test_results.html test_results-${JOB_NAME}.html"
sh "sed -i -e 's#TEMPLATE_JOB_NAME#${JOB_NAME}#' -e 's@build #TEMPLATE_BUILD_ID@build #${BUILD_ID}@' -e 's#Build-ID: TEMPLATE_BUILD_ID#Build-ID: <a href=\"${BUILD_URL}\">${BUILD_ID}</a>#' -e 's#TEMPLATE_STAGE_NAME#${testStageName}#' test_results-${JOB_NAME}.html"
......
......@@ -47,30 +47,30 @@ pipeline {
COMMIT_ID=sh returnStdout: true, script: """curl --silent "https://gitlab.eurecom.fr/api/v4/projects/oai%2Fopenairinterface5g/merge_requests/${MR}" | jq ".sha" || true """
COMMIT_ID=COMMIT_ID.trim()
echo "Testing NSA on : ${MR} ${SRC_BRANCH} ${COMMIT_ID}"
//calling NSA sub job
build job: "RAN-NSA-Mini-Module", wait : true, propagate : false, parameters: [
//calling NSA B200
build job: "RAN-NSA-B200-Module-LTEBOX", wait : true, propagate : false, parameters: [
string(name: 'eNB_MR', value: String.valueOf(MR)),
string(name: 'eNB_Branch', value: String.valueOf(SRC_BRANCH)),
string(name: 'eNB_CommitID', value: String.valueOf(COMMIT_ID)),
string(name: 'eNB_TargetBranch', value: String.valueOf(TARGET_BRANCH)),
booleanParam(name: 'eNB_AllowMergeRequestProcess', value: Boolean.valueOf(ALLOW_MERGE))
]
//calling NSA long sub job
// build job: "RAN-NSA-Mini-Module-Long", wait : true, propagate : false, parameters: [
// string(name: 'eNB_MR', value: String.valueOf(MR)),
// string(name: 'eNB_Branch', value: String.valueOf(SRC_BRANCH)),
// string(name: 'eNB_CommitID', value: String.valueOf(COMMIT_ID)),
// string(name: 'eNB_TargetBranch', value: String.valueOf(TARGET_BRANCH)),
// booleanParam(name: 'eNB_AllowMergeRequestProcess', value: Boolean.valueOf(ALLOW_MERGE))
// ]
//calling NSA attach/detach job
// build job: "RAN-NSA-Mini-Module-Attach-Detach", wait : true, propagate : false, parameters: [
// string(name: 'eNB_MR', value: String.valueOf(MR)),
// string(name: 'eNB_Branch', value: String.valueOf(SRC_BRANCH)),
// string(name: 'eNB_CommitID', value: String.valueOf(COMMIT_ID)),
// string(name: 'eNB_TargetBranch', value: String.valueOf(TARGET_BRANCH)),
// booleanParam(name: 'eNB_AllowMergeRequestProcess', value: Boolean.valueOf(ALLOW_MERGE))
// ]
//calling NSA 2x2
build job: "RAN-NSA-2x2-Module-OAIEPC", wait : true, propagate : false, parameters: [
string(name: 'eNB_MR', value: String.valueOf(MR)),
string(name: 'eNB_Branch', value: String.valueOf(SRC_BRANCH)),
string(name: 'eNB_CommitID', value: String.valueOf(COMMIT_ID)),
string(name: 'eNB_TargetBranch', value: String.valueOf(TARGET_BRANCH)),
booleanParam(name: 'eNB_AllowMergeRequestProcess', value: Boolean.valueOf(ALLOW_MERGE))
]
//calling LTE 2x2
build job: "RAN-LTE-2x2-Module-OAIEPC", wait : true, propagate : false, parameters: [
string(name: 'eNB_MR', value: String.valueOf(MR)),
string(name: 'eNB_Branch', value: String.valueOf(SRC_BRANCH)),
string(name: 'eNB_CommitID', value: String.valueOf(COMMIT_ID)),
string(name: 'eNB_TargetBranch', value: String.valueOf(TARGET_BRANCH)),
booleanParam(name: 'eNB_AllowMergeRequestProcess', value: Boolean.valueOf(ALLOW_MERGE))
]
}
}
......
......@@ -4,7 +4,9 @@ idefix:
Kind : quectel
Process :
Name : quectel-CM
Cmd : /home/oaicicd/quectel-CM/quectel-CM -s oai.ipv4 -4
Cmd : /home/oaicicd/quectel-CM/quectel-CM -4 -s
Apn :
ltebox : oai.ipv4
WakeupScript : ci_ctl_qtel.py /dev/ttyUSB2 wup
DetachScript : ci_ctl_qtel.py /dev/ttyUSB2 detach
LogStore : /media/usb-drive/ci_qlogs
......@@ -20,16 +22,22 @@ nrmodule2_quectel:
Kind : quectel
Process :
Name : quectel-CM
Cmd : /home/nrmodule2/quectel-CM/quectel-CM -s oai.ipv4 -4
Cmd : /home/nrmodule2/quectel-CM/quectel-CM -4 -s
Apn :
OAICN5G : oai
OAI-Rel14-Docker : oai.ipv4
WakeupScript : ci_ctl_qtel.py /dev/ttyUSB7 wup
DetachScript : ci_ctl_qtel.py /dev/ttyUSB7 detach
LogStore : /media/ci_qlogs
PLMN : 20899
PLMN : 20897
UENetwork : wwan1
HostIPAddress : 192.168.18.189
HostUsername : nrmodule2
HostPassword : linux
HostSourceCodePath : none
StartCommands :
- sudo -S ip link set dev wwan1 mtu 1500
MTU : 1500
dummy:
ID: ''
State : ''
......
......@@ -61,7 +61,7 @@ class Module_UE:
#this method checks if the specified Process is running on the server hosting the module
#if not it will be started
def CheckCMProcess(self):
def CheckCMProcess(self,CNType):
HOST=self.HostUsername+'@'+self.HostIPAddress
COMMAND="ps aux | grep " + self.Process['Name'] + " | grep -v grep "
logging.debug(COMMAND)
......@@ -76,7 +76,7 @@ class Module_UE:
logging.debug('Starting ' + self.Process['Name'])
mySSH = sshconnection.SSHConnection()
mySSH.open(self.HostIPAddress, self.HostUsername, self.HostPassword)
mySSH.command('echo $USER; echo ' + self.HostPassword + ' | nohup sudo -S ' + self.Process['Cmd'] + ' &','\$',5)
mySSH.command('echo $USER; echo ' + self.HostPassword + ' | nohup sudo -S ' + self.Process['Cmd'] + ' ' + self.Process['Apn'][CNType] + ' &','\$',5)
mySSH.close()
#checking the process
time.sleep(5)
......@@ -131,6 +131,33 @@ class Module_UE:
logging.debug('\u001B[1;37;41m Module IP Address Not Found! \u001B[0m')
return -1
def CheckModuleMTU(self):
HOST=self.HostUsername+'@'+self.HostIPAddress
response= []
tentative = 3
while (len(response)==0) and (tentative>0):
COMMAND="ip a show dev " + self.UENetwork + " | grep mtu"
logging.debug(COMMAND)
ssh = subprocess.Popen(["ssh", "%s" % HOST, COMMAND],shell=False,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
response = ssh.stdout.readlines()
tentative-=1
time.sleep(10)
if (tentative==0) and (len(response)==0):
logging.debug('\u001B[1;37;41m Module NIC MTU Not Found! Time expired \u001B[0m')
return -1
else: #check response
result = re.search('mtu (?P<mtu>[0-9]+)', response[0].decode("utf-8") )
if result is not None:
if (result.group('mtu') is not None) and (str(result.group('mtu'))==str(self.MTU)) :
logging.debug('\u001B[1mUE Module NIC MTU is ' + str(self.MTU) + ' as expected\u001B[0m')
return 0
else:
logging.debug('\u001B[1;37;41m Incorrect Module NIC MTU ' + str(result.group('mtu')) + '! Expected : ' + str(self.MTU) + '\u001B[0m')
return -1
else:
logging.debug('\u001B[1;37;41m Module NIC MTU Not Found! \u001B[0m')
return -1
def EnableTrace(self):
if self.ue_trace=="yes":
mySSH = sshconnection.SSHConnection()
......
This diff is collapsed.
......@@ -14,7 +14,7 @@ eNBs =
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = 1;
plmn_list = ( { mcc = 208; mnc = 99; mnc_length = 2; } );
plmn_list = ( { mcc = 208; mnc = 97; mnc_length = 2; } );
tr_s_preference = "local_mac"
......@@ -31,6 +31,7 @@ eNBs =
prefix_type = "NORMAL";
eutra_band = 38;
downlink_frequency = 2605000000L;
nr_scg_ssb_freq = 624608;
uplink_frequency_offset = 0;
Nid_cell = 0;
N_RB_DL = 100;
......@@ -209,8 +210,8 @@ MACRLCs = (
scheduler_mode = "fairRR";
bler_target_upper = 20.0;
bler_target_lower = 10.0;
max_ul_rb_index = 24;
puSch10xSnr = 100;
max_ul_rb_index = 27;
puSch10xSnr = 200;
puCch10xSnr = 150;
}
);
......
......@@ -13,7 +13,7 @@ gNBs =
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = 1;
plmn_list = ({mcc = 208; mnc = 99; mnc_length = 2;});
plmn_list = ({mcc = 208; mnc = 97; mnc_length = 2;});
tr_s_preference = "local_mac"
......@@ -24,6 +24,7 @@ gNBs =
pusch_AntennaPorts = 2;
pusch_TargetSNRx10 = 200;
pucch_TargetSNRx10 = 200;
ul_prbblacklist = "51,52,53,54"
servingCellConfigCommon = (
{
......@@ -33,11 +34,11 @@ gNBs =
# downlinkConfigCommon
#frequencyInfoDL
# this is 3600 MHz + 84 PRBs@30kHz SCS (same as initial BWP)
absoluteFrequencySSB = 641272; //641032; #641968; 641968=start of ssb at 3600MHz + 82 RBs 641032=center of SSB at center of cell
# this is 3350.04 MHz + 53 PRBs@30kHz SCS (same as initial BWP)
absoluteFrequencySSB = 624608;
dl_frequencyBand = 78;
# this is 3600 MHz
dl_absoluteFrequencyPointA = 640000;
# this is 3350.04 MHz
dl_absoluteFrequencyPointA = 623336;
#scs-SpecificCarrierList
dl_offstToCarrier = 0;
# subcarrierSpacing
......@@ -46,7 +47,7 @@ gNBs =
dl_carrierBandwidth = 106;
#initialDownlinkBWP
#genericParameters
# this is RBstart=84,L=13 (275*(L-1))+RBstart
# this is RBstart=43,L=24 (275*(L-1))+RBstart
initialDLBWPlocationAndBandwidth = 6368;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
......@@ -233,7 +234,7 @@ L1s = (
num_cc = 1;
tr_n_preference = "local_mac";
pusch_proc_threads = 8;
prach_dtx_threshold = 100;
prach_dtx_threshold = 120;
}
);
......
......@@ -12,7 +12,8 @@ Ref :
feptx_prec : 8.0
feptx_ofdm : 50.0
feptx_total : 75.0
L1 Tx processing : 300.0
L1 Tx processing thread 0 : 300.0
L1 Tx processing thread 1 : 300.0
DLSCH encoding : 230.0
L1 Rx processing : 175.0
PUSCH inner-receiver : 100.0
......@@ -24,7 +25,8 @@ Threshold :
feptx_prec : 1.25
feptx_ofdm : 1.25
feptx_total : 1.25
L1 Tx processing : 1.25
L1 Tx processing thread 0 : 1.25
L1 Tx processing thread 1 : 1.25
DLSCH encoding : 1.25
L1 Rx processing : 1.25
PUSCH inner-receiver : 1.25
......
......@@ -220,7 +220,7 @@ class EPCManagement():
mySSH = SSH.SSHConnection()
mySSH.open(self.IPAddress, self.UserName, self.Password)
if re.match('ltebox', self.Type, re.IGNORECASE):
logging.debug('Using the sabox simulated HSS')
logging.debug('Using the SABOX simulated HSS')
mySSH.command('if [ -d ' + self.SourceCodePath + '/scripts ]; then echo ' + self.Password + ' | sudo -S rm -Rf ' + self.SourceCodePath + '/scripts ; fi', '\$', 5)
mySSH.command('mkdir -p ' + self.SourceCodePath + '/scripts', '\$', 5)
mySSH.command('cd /opt/hss_sim0609', '\$', 5)
......@@ -229,6 +229,12 @@ class EPCManagement():
logging.debug('Using the sabox')
mySSH.command('cd /opt/ltebox/tools', '\$', 5)
mySSH.command('echo ' + self.Password + ' | sudo -S ./start_sabox', '\$', 5)
elif re.match('OAICN5G', self.Type, re.IGNORECASE):
logging.debug('Starting OAI CN5G')
mySSH.command('if [ -d ' + self.SourceCodePath + '/scripts ]; then echo ' + self.Password + ' | sudo -S rm -Rf ' + self.SourceCodePath + '/scripts ; fi', '\$', 5)
mySSH.command('mkdir -p ' + self.SourceCodePath + '/scripts', '\$', 5)
mySSH.command('cd /opt/oai-cn5g-fed/docker-compose', '\$', 5)
mySSH.command('./core-network.sh start nrf spgwu', '\$', 60)
else:
logging.error('This option should not occur!')
mySSH.close()
......@@ -242,6 +248,16 @@ class EPCManagement():
return
if re.match('ltebox', self.Type, re.IGNORECASE):
self.MmeIPAddress = self.IPAddress
elif re.match('OAICN5G', self.Type, re.IGNORECASE):
mySSH = SSH.SSHConnection()
mySSH.open(self.IPAddress, self.UserName, self.Password)
response=mySSH.command3('docker container ls -f name=oai-amf', 10)
if len(response)>1:
response=mySSH.command3('docker inspect --format=\'{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}\' oai-amf', 10)
tmp = str(response[0],'utf-8')
self.MmeIPAddress = tmp.rstrip()
logging.debug('AMF IP Address ' + self.MmeIPAddress)
mySSH.close()
def CheckHSSProcess(self, status_queue):
try:
......@@ -433,6 +449,7 @@ class EPCManagement():
mySSH = SSH.SSHConnection()
mySSH.open(self.IPAddress, self.UserName, self.Password)
if re.match('ltebox', self.Type, re.IGNORECASE):
logging.debug('Terminating SA BOX')
mySSH.command('cd /opt/ltebox/tools', '\$', 5)
mySSH.command('echo ' + self.Password + ' | sudo -S ./stop_sabox', '\$', 5)
time.sleep(1)
......@@ -440,6 +457,12 @@ class EPCManagement():
mySSH.command('cd scripts', '\$', 5)
time.sleep(1)
mySSH.command('echo ' + self.Password + ' | sudo -S screen -S simulated_5g_hss -X quit', '\$', 5)
elif re.match('OAICN5G', self.Type, re.IGNORECASE):
self.LogCollectOAICN5G()
logging.debug('Terminating OAI CN5G')
mySSH.command('cd /opt/oai-cn5g-fed/docker-compose', '\$', 5)
mySSH.command('docker-compose down', '\$', 5)
mySSH.command('./core-network.sh stop nrf spgwu', '\$', 60)
else:
logging.error('This should not happen!')
mySSH.close()
......@@ -679,3 +702,16 @@ class EPCManagement():
logging.error('This option should not occur!')
mySSH.close()
def LogCollectOAICN5G(self):
mySSH = SSH.SSHConnection()
mySSH.open(self.IPAddress, self.UserName, self.Password)
logging.debug('OAI CN5G Collecting Log files to workspace')
mySSH.command('echo ' + self.Password + ' | sudo rm -rf ' + self.SourceCodePath + '/logs', '\$', 5)
mySSH.command('mkdir ' + self.SourceCodePath + '/logs','\$', 5)
containers_list=['oai-smf','oai-spgwu','oai-amf','oai-nrf']
for c in containers_list:
mySSH.command('docker logs ' + c + ' > ' + self.SourceCodePath + '/logs/' + c + '.log', '\$', 5)
mySSH.command('cd ' + self.SourceCodePath + '/logs', '\$', 5)
mySSH.command('zip oai-cn5g.log.zip *.log', '\$', 60)
mySSH.close()
......@@ -154,6 +154,7 @@ def GetParametersFromXML(action):
elif action == 'Initialize_eNB':
RAN.eNB_Trace=test.findtext('eNB_Trace')
RAN.eNB_Stats=test.findtext('eNB_Stats')
RAN.Initialize_eNB_args=test.findtext('Initialize_eNB_args')
eNB_instance=test.findtext('eNB_instance')
USRPIPAddress=test.findtext('USRP_IPAddress')
......
......@@ -39,7 +39,6 @@ import time
from multiprocessing import Process, Lock, SimpleQueue
import yaml
#-----------------------------------------------------------
# OAI Testing modules
#-----------------------------------------------------------
......@@ -94,6 +93,7 @@ class RANManagement():
self.runtime_stats= ''
self.datalog_rt_stats={}
self.eNB_Trace = '' #if 'yes', Tshark will be launched at initialization
self.eNB_Stats = '' #if 'yes', Statistics Monitor will be launched at initialization
self.USRPIPAddress = ''
......@@ -341,6 +341,8 @@ class RANManagement():
self.testCase_id = HTML.testCase_id
mySSH = SSH.SSHConnection()
cwd = os.getcwd()
mySSH.copyout(lIpAddr,lUserName,lPassWord, cwd + "/active_net_interfaces.awk", "/tmp")
#reboot USRP if requested in xml
if self.USRPIPAddress!='':
......@@ -461,10 +463,36 @@ class RANManagement():
mySSH.command('if [ -e rbconfig.raw ]; then echo ' + lPassWord + ' | sudo -S rm rbconfig.raw; fi', '\$', 5)
mySSH.command('if [ -e reconfig.raw ]; then echo ' + lPassWord + ' | sudo -S rm reconfig.raw; fi', '\$', 5)
# NOTE: WE SHALL do a check if the executable is present (in case build went wrong)
mySSH.command('echo "ulimit -c unlimited && ./ran_build/build/' + self.air_interface[self.eNB_instance] + ' -O ' + lSourcePath + '/' + ci_full_config_file + extra_options + '" > ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5)
#hack UHD_RFNOC_DIR variable for gNB / N310 on RHEL8 server:
#if the USRP address is in the xml then we are using an eth USRP (N3xx)
if (self.air_interface[self.eNB_instance] == 'lte-softmodem') or (self.air_interface[self.eNB_instance] == 'ocp-enb'):
gNB = False
else:
gNB = True
if ((self.USRPIPAddress!='') and (gNB==True)):
mySSH.command('echo ' + lPassWord + ' | echo "ulimit -c unlimited && sudo UHD_RFNOC_DIR=/usr/local/share/uhd/rfnoc ./ran_build/build/' + self.air_interface[self.eNB_instance] + ' -O ' + lSourcePath + '/' + ci_full_config_file + extra_options + '" > ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5)
#otherwise the regular command is ok
else:
mySSH.command('echo "ulimit -c unlimited && ./ran_build/build/' + self.air_interface[self.eNB_instance] + ' -O ' + lSourcePath + '/' + ci_full_config_file + extra_options + '" > ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5)
mySSH.command('chmod 775 ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5)
mySSH.command('echo ' + lPassWord + ' | sudo -S rm -Rf enb_' + self.testCase_id + '.log', '\$', 5)
mySSH.command('echo $USER; nohup sudo -E ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh > ' + lSourcePath + '/cmake_targets/enb_' + self.testCase_id + '.log 2>&1 &', lUserName, 10)
#stats monitoring during runtime
time.sleep(20)
monitor_file='../ci-scripts/stats_monitor.py'
conf_file='../ci-scripts/stats_monitor_conf.yaml'
if self.eNB_Stats=='yes':
if (self.air_interface[self.eNB_instance] == 'lte-softmodem') or (self.air_interface[self.eNB_instance] == 'ocp-enb'):
mySSH.command('echo $USER; nohup python3 ' + monitor_file + ' ' + conf_file + ' enb 2>&1 > enb_stats_monitor_execution.log &', '\$', 5)
else:
mySSH.command('echo $USER; nohup python3 ' + monitor_file + ' ' + conf_file + ' gnb 2>&1 > gnb_stats_monitor_execution.log &', '\$', 5)
self.eNBLogFiles[int(self.eNB_instance)] = 'enb_' + self.testCase_id + '.log'
if extra_options != '':
self.eNBOptions[int(self.eNB_instance)] = extra_options
......@@ -539,6 +567,8 @@ class RANManagement():
self.eNBstatuses[int(self.eNB_instance)] = int(self.eNB_serverId[self.eNB_instance])
mySSH.close()
HTML.CreateHtmlTestRow(self.air_interface[self.eNB_instance] + ' -O ' + config_file + extra_options, 'OK', CONST.ALL_PROCESSES_OK)
logging.debug('\u001B[1m Initialize eNB/gNB/ocp-eNB Completed\u001B[0m')
......@@ -657,6 +687,11 @@ class RANManagement():
fileToAnalyze = self.eNBLogFiles[int(self.eNB_instance)]
self.eNBLogFiles[int(self.eNB_instance)] = ''
if analyzeFile:
#*stats.log files + pickle + png
mySSH.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/*stats.log', '.')
mySSH.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/*.pickle', '.')
mySSH.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/*.png', '.')
#
copyin_res = mySSH.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/' + fileToAnalyze, '.')
if (copyin_res == -1):
logging.debug('\u001B[1;37;41m Could not copy ' + nodeB_prefix + 'NB logfile to analyze it! \u001B[0m')
......@@ -665,12 +700,20 @@ class RANManagement():
self.eNBmbmsEnables[int(self.eNB_instance)] = False
return
if self.eNB_serverId[self.eNB_instance] != '0':
#*stats.log files + pickle + png
#debug / tentative
mySSH.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, './nrL1_stats.log', self.eNBSourceCodePath + '/cmake_targets/')
mySSH.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, './nrMAC_stats.log', self.eNBSourceCodePath + '/cmake_targets/')
mySSH.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, './gnb_stats_monitor.pickle.pickle', self.eNBSourceCodePath + '/cmake_targets/')
mySSH.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, './gnb_stats_monitor.png', self.eNBSourceCodePath + '/cmake_targets/')
#
mySSH.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, './' + fileToAnalyze, self.eNBSourceCodePath + '/cmake_targets/')
logging.debug('\u001B[1m Analyzing ' + nodeB_prefix + 'NB logfile \u001B[0m ' + fileToAnalyze)
logStatus = self.AnalyzeLogFile_eNB(fileToAnalyze, HTML)
if (logStatus < 0):
HTML.CreateHtmlTestRow('N/A', 'KO', logStatus)
self.preamtureExit = True
self.prematureExit = True
self.eNBmbmsEnables[int(self.eNB_instance)] = False
return
else:
......@@ -691,8 +734,8 @@ class RANManagement():
mySSH.command('echo ' + self.eNBPassword + ' | sudo -S mv /tmp/enb_*.pcap .','\$',20)
mySSH.command('echo ' + self.eNBPassword + ' | sudo -S mv /tmp/gnb_*.pcap .','\$',20)
mySSH.command('echo ' + self.eNBPassword + ' | sudo -S rm -f enb.log.zip', '\$', 5)
mySSH.command('echo ' + self.eNBPassword + ' | sudo -S zip enb.log.zip enb*.log core* enb_*record.raw enb_*.pcap gnb_*.pcap enb_*txt physim_*.log *stats.log', '\$', 60)
mySSH.command('echo ' + self.eNBPassword + ' | sudo -S rm enb*.log core* enb_*record.raw enb_*.pcap gnb_*.pcap enb_*txt physim_*.log *stats.log', '\$', 5)
mySSH.command('echo ' + self.eNBPassword + ' | sudo -S zip enb.log.zip enb*.log core* enb_*record.raw enb_*.pcap gnb_*.pcap enb_*txt physim_*.log *stats.log *monitor.pickle *monitor.png', '\$', 60)
mySSH.command('echo ' + self.eNBPassword + ' | sudo -S rm enb*.log core* enb_*record.raw enb_*.pcap gnb_*.pcap enb_*txt physim_*.log *stats.log *.pickle *.png', '\$', 5)
mySSH.close()
def AnalyzeLogFile_eNB(self, eNBlogFile, HTML):
......@@ -1032,7 +1075,7 @@ class RANManagement():
for k in datalog_rt_stats['Data']:
if float(datalog_rt_stats['Data'][k][2])> datalog_rt_stats['Threshold'][k]: #condition for fail : avg/ref is greater than the fixed threshold
#setting prematureExit is ok although not the best option
self.prematureExit=True
self.prematureExit=False #temp for debug : do not stop the test if RT stats are excedeed
else:
statMsg = 'No real time stats found in the log file\n'
logging.debug('No real time stats found in the log file')
......
......@@ -163,6 +163,18 @@ class SSHConnection():
lSsh = subprocess.Popen(["ssh", "%s" % myHost, commandline],shell=False,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
self.cmd2Results = str(lSsh.stdout.readlines())
def command3(self, commandline, timeout, silent=False):
if not silent:
logging.debug(commandline)
self.cmd2Results = ''
myHost = self.username + '@' + self.ipaddress
# CAUTION: THIS METHOD IMPLIES THAT THERE ARE VALID SSH KEYS
# BETWEEN THE PYTHON EXECUTOR NODE AND THE REMOTE HOST
# OTHERWISE IT WON'T WORK
lSsh = subprocess.Popen(["ssh", "%s" % myHost, commandline],shell=False,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
return lSsh.stdout.readlines()
def close(self):
self.ssh.timeout = 5
self.ssh.sendline('exit')
......
"""
To create graphs and pickle from runtime statistics in L1,MAC,RRC,PDCP files
"""
import subprocess
import time
import shlex
import re
import sys
import pickle
import matplotlib.pyplot as plt
import numpy as np
import yaml
class StatMonitor():
def __init__(self,cfg_file):
with open(cfg_file,'r') as file:
self.d = yaml.load(file)
for node in self.d:
for metric in self.d[node]:
self.d[node][metric]=[]
def process_gnb (self,node_type,output):
for line in output:
tmp=line.decode("utf-8")
result=re.match(r'^.*\bdlsch_rounds\b ([0-9]+)\/([0-9]+).*\bdlsch_errors\b ([0-9]+)',tmp)
if result is not None:
self.d[node_type]['dlsch_err'].append(int(result.group(3)))
percentage=float(result.group(2))/float(result.group(1))
self.d[node_type]['dlsch_err_perc_round_1'].append(percentage)
result=re.match(r'^.*\bulsch_rounds\b ([0-9]+)\/([0-9]+).*\bulsch_errors\b ([0-9]+)',tmp)
if result is not None:
self.d[node_type]['ulsch_err'].append(int(result.group(3)))
percentage=float(result.group(2))/float(result.group(1))
self.d[node_type]['ulsch_err_perc_round_1'].append(percentage)
def process_enb (self,node_type,output):
for line in output:
tmp=line.decode("utf-8")
result=re.match(r'^.*\bPHR\b ([0-9]+).+\bbler\b ([0-9]+\.[0-9]+).+\bmcsoff\b ([0-9]+).+\bmcs\b ([0-9]+)',tmp)
if result is not None:
self.d[node_type]['PHR'].append(int(result.group(1)))
self.d[node_type]['bler'].append(float(result.group(2)))
self.d[node_type]['mcsoff'].append(int(result.group(3)))
self.d[node_type]['mcs'].append(int(result.group(4)))
def collect(self,node_type):
if node_type=='enb':
cmd='cat L1_stats.log MAC_stats.log PDCP_stats.log RRC_stats.log'
else: #'gnb'
cmd='cat nrL1_stats.log nrMAC_stats.log nrPDCP_stats.log nrRRC_stats.log'
process=subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE)
output = process.stdout.readlines()
if node_type=='enb':
self.process_enb(node_type,output)
else: #'gnb'
self.process_gnb(node_type,output)
def graph(self,node_type):
col = 1
figure, axis = plt.subplots(len(self.d[node_type]), col ,figsize=(10, 10))
i=0
for metric in self.d[node_type]:
major_ticks = np.arange(0, len(self.d[node_type][metric])+1, 1)
axis[i].set_xticks(major_ticks)
axis[i].set_xticklabels([])
axis[i].plot(self.d[node_type][metric],marker='o')
axis[i].set_xlabel('time')
axis[i].set_ylabel(metric)
axis[i].set_title(metric)
i+=1
plt.tight_layout()
# Combine all the operations and display
plt.savefig(node_type+'_stats_monitor.png')
plt.show()
if __name__ == "__main__":
cfg_filename = sys.argv[1] #yaml file as metrics config
node = sys.argv[2]#enb or gnb
mon=StatMonitor(cfg_filename)
#collecting stats when modem process is stopped
CMD='ps aux | grep mode | grep -v grep'
process=subprocess.Popen(CMD, shell=True, stdout=subprocess.PIPE)
output = process.stdout.readlines()
while len(output)!=0 :
mon.collect(node)
process=subprocess.Popen(CMD, shell=True, stdout=subprocess.PIPE)
output = process.stdout.readlines()
time.sleep(1)
print('Process stopped')
with open(node+'_stats_monitor.pickle', 'wb') as handle:
pickle.dump(mon.d, handle, protocol=pickle.HIGHEST_PROTOCOL)
mon.graph(node)
import subprocess
import time
import shlex
import re
import sys
import matplotlib.pyplot as plt
import pickle
import numpy as np
import os
def collect(d, node_type):
if node_type=='enb':
cmd='cat L1_stats.log MAC_stats.log PDCP_stats.log RRC_stats.log'
else: #'gnb'
cmd='cat nrL1_stats.log nrMAC_stats.log nrPDCP_stats.log nrRRC_stats.log'
process=subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE)
output = process.stdout.readlines()
for l in output:
tmp=l.decode("utf-8")
result=re.match(rf'^.*\bPHR\b ([0-9]+).+\bbler\b ([0-9]+\.[0-9]+).+\bmcsoff\b ([0-9]+).+\bmcs\b ([0-9]+)',tmp)
if result is not None:
d['PHR'].append(int(result.group(1)))
d['bler'].append(float(result.group(2)))
d['mcsoff'].append(int(result.group(3)))
d['mcs'].append(int(result.group(4)))
def graph(d, node_type):
figure, axis = plt.subplots(4, 1,figsize=(10, 10))
major_ticks = np.arange(0, len(d['PHR'])+1, 1)
axis[0].set_xticks(major_ticks)
axis[0].set_xticklabels([])
axis[0].plot(d['PHR'],marker='o')
axis[0].set_xlabel('time')
axis[0].set_ylabel('PHR')
axis[0].set_title("PHR")
major_ticks = np.arange(0, len(d['bler'])+1, 1)
axis[1].set_xticks(major_ticks)
axis[1].set_xticklabels([])
axis[1].plot(d['bler'],marker='o')
axis[1].set_xlabel('time')
axis[1].set_ylabel('bler')
axis[1].set_title("bler")
major_ticks = np.arange(0, len(d['mcsoff'])+1, 1)
axis[2].set_xticks(major_ticks)
axis[2].set_xticklabels([])
axis[2].plot(d['mcsoff'],marker='o')
axis[2].set_xlabel('time')
axis[2].set_ylabel('mcsoff')
axis[2].set_title("mcsoff")
major_ticks = np.arange(0, len(d['mcs'])+1, 1)
axis[3].set_xticks(major_ticks)
axis[3].set_xticklabels([])
axis[3].plot(d['mcs'],marker='o')
axis[3].set_xlabel('time')
axis[3].set_ylabel('mcs')
axis[3].set_title("mcs")
plt.tight_layout()
# Combine all the operations and display
plt.savefig(node_type+'_stats_monitor.png')
plt.show()
if __name__ == "__main__":
node_type = sys.argv[1]#enb or gnb
d={}
d['PHR']=[]
d['bler']=[]
d['mcsoff']=[]
d['mcs']=[]
cmd='ps aux | grep modem | grep -v grep'
process=subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
output = process.stdout.readlines()
while len(output)!=0 :
collect(d, node_type)
process=subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
output = process.stdout.readlines()
time.sleep(1)
print('process stopped')
with open(node_type+'_stats_monitor.pickle', 'wb') as handle:
pickle.dump(d, handle, protocol=pickle.HIGHEST_PROTOCOL)
graph(d, node_type)
enb :
PHR:
bler:
mcsoff:
mcs:
gnb :
dlsch_err:
dlsch_err_perc_round_1:
ulsch_err:
ulsch_err_perc_round_1:
\ No newline at end of file
import subprocess
import time
import shlex
import re
import sys
import matplotlib.pyplot as plt
import pickle
import numpy as np
import os
import yaml
class Stat_Monitor():
def __init__(self,):
with open('stats_monitor_conf.yaml','r') as f:
self.d = yaml.load(f)
for node in self.d:
for metric in self.d[node]:
self.d[node][metric]=[]
def process_gnb (self,node_type,output):
for line in output:
tmp=line.decode("utf-8")
result=re.match(r'^.*\bdlsch_rounds\b ([0-9]+)\/([0-9]+).*\bdlsch_errors\b ([0-9]+)',tmp)
if result is not None:
self.d[node_type]['dlsch_err'].append(int(result.group(3)))
percentage=float(result.group(2))/float(result.group(1))
self.d[node_type]['dlsch_err_perc_round_1'].append(percentage)
result=re.match(r'^.*\bulsch_rounds\b ([0-9]+)\/([0-9]+).*\bulsch_errors\b ([0-9]+)',tmp)
if result is not None:
self.d[node_type]['ulsch_err'].append(int(result.group(3)))
percentage=float(result.group(2))/float(result.group(1))
self.d[node_type]['ulsch_err_perc_round_1'].append(percentage)
def process_enb (self,node_type,output):
for line in output:
tmp=line.decode("utf-8")
result=re.match(r'^.*\bPHR\b ([0-9]+).+\bbler\b ([0-9]+\.[0-9]+).+\bmcsoff\b ([0-9]+).+\bmcs\b ([0-9]+)',tmp)
if result is not None:
self.d[node_type]['PHR'].append(int(result.group(1)))
self.d[node_type]['bler'].append(float(result.group(2)))
self.d[node_type]['mcsoff'].append(int(result.group(3)))
self.d[node_type]['mcs'].append(int(result.group(4)))
def collect(self,node_type):
if node_type=='enb':
cmd='cat L1_stats.log MAC_stats.log PDCP_stats.log RRC_stats.log'
else: #'gnb'
cmd='cat nrL1_stats.log nrMAC_stats.log nrPDCP_stats.log nrRRC_stats.log'
process=subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE)
output = process.stdout.readlines()
if node_type=='enb':
self.process_enb(node_type,output)
else: #'gnb'
self.process_gnb(node_type,output)
def graph(self,node_type):
col = 1
figure, axis = plt.subplots(len(self.d[node_type]), col ,figsize=(10, 10))
i=0
for metric in self.d[node_type]:
major_ticks = np.arange(0, len(self.d[node_type][metric])+1, 1)
axis[i].set_xticks(major_ticks)
axis[i].set_xticklabels([])
axis[i].plot(self.d[node_type][metric],marker='o')
axis[i].set_xlabel('time')
axis[i].set_ylabel(metric)
axis[i].set_title(metric)
i+=1
plt.tight_layout()
# Combine all the operations and display
plt.savefig(node_type+'_stats_monitor.png')
plt.show()
if __name__ == "__main__":
node_type = sys.argv[1]#enb or gnb
mon=Stat_Monitor()
#collecting stats when modem process is stopped
cmd='ps aux | grep mode | grep -v grep'
process=subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
output = process.stdout.readlines()
while len(output)!=0 :
mon.collect(node_type)
process=subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
output = process.stdout.readlines()
time.sleep(1)
print('Process stopped')
with open(node_type+'_stats_monitor.pickle', 'wb') as handle:
pickle.dump(mon.d, handle, protocol=pickle.HIGHEST_PROTOCOL)
mon.graph(node_type)
<!--
Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The OpenAirInterface Software Alliance licenses this file to You under
the OAI Public License, Version 1.1 (the "License"); you may not use this file
except in compliance with the License.
You may obtain a copy of the License at
http://www.openairinterface.org/?page_id=698
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
For more information about the OpenAirInterface (OAI) Software Alliance:
contact@openairinterface.org
-->
<testCaseList>
<htmlTabRef>build-tab</htmlTabRef>
<htmlTabName>Build</htmlTabName>
<htmlTabIcon>wrench</htmlTabIcon>
<TestCaseRequestedList>
000001
000002
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="000001">
<class>Build_eNB</class>
<desc>Build eNB</desc>
<Build_eNB_args>-w USRP -c --eNB --ninja</Build_eNB_args>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
<backgroundBuild>True</backgroundBuild>
<forced_workspace_cleanup>True</forced_workspace_cleanup>
</testCase>
<testCase id="000002">
<class>WaitEndBuild_eNB</class>
<desc>Wait for end of Build eNB</desc>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
</testCaseList>
......@@ -26,7 +26,6 @@
<htmlTabIcon>wrench</htmlTabIcon>
<TestCaseRequestedList>
000001
000002
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
......@@ -36,7 +35,6 @@
<Build_eNB_args>-w USRP -c --gNB --ninja</Build_eNB_args>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
<backgroundBuild>True</backgroundBuild>
<forced_workspace_cleanup>True</forced_workspace_cleanup>
</testCase>
......
<!--
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>TEST-LTE-TM2</htmlTabRef>
<htmlTabName>LTE 2x2 Ping DL UL with QUECTEL</htmlTabName>
<htmlTabIcon>tasks</htmlTabIcon>
<repeatCount>1</repeatCount>
<TestCaseRequestedList>
030000
000002
010000
000001
050000
050001
000002
070000
070001
000001
010002
080000
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="010000">
<class>Initialize_UE</class>
<desc>Initialize Quectel</desc>
<id>nrmodule2_quectel</id>
<UE_Trace>yes</UE_Trace>
</testCase>
<testCase id="010002">
<class>Terminate_UE</class>
<desc>Terminate Quectel</desc>
<id>nrmodule2_quectel</id>
</testCase>
<testCase id="030000">
<class>Initialize_eNB</class>
<desc>Initialize eNB</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/enb.band38.nsa_2x2.100PRB.usrpn310.conf --usrp-tx-thread-config 1 --thread-pool 0,2,4,6</Initialize_eNB_args>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
<air_interface>lte</air_interface>
<eNB_Trace>yes</eNB_Trace>
<eNB_Stats>yes</eNB_Stats>
<USRP_IPAddress>192.168.18.241</USRP_IPAddress>
</testCase>
<testCase id="000001">
<class>IdleSleep</class>
<desc>Sleep</desc>
<idle_sleep_time_in_sec>5</idle_sleep_time_in_sec>
</testCase>
<testCase id="000002">
<class>IdleSleep</class>
<desc>Sleep</desc>
<idle_sleep_time_in_sec>20</idle_sleep_time_in_sec>
</testCase>
<testCase id="050000">
<class>Ping</class>
<desc>Ping: 20 pings</desc>
<id>nrmodule2_quectel</id>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
<testCase id="050001">
<class>Ping</class>
<desc>Ping: 100 pings, size 1024</desc>
<id>nrmodule2_quectel</id>
<ping_args>-c 100 -s 1024 -i 0,2</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
<testCase id="070000">
<class>Iperf</class>
<desc>iperf (DL/26Mbps/UDP)(60 sec)(single-ue profile)</desc>
<iperf_args>-u -b 26M -t 60</iperf_args>
<direction>DL</direction>
<id>nrmodule2_quectel</id>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="070001">
<class>Iperf</class>
<desc>iperf (UL/7Mbps/UDP)(60 sec)(single-ue profile)</desc>
<iperf_args>-u -b 7M -t 60</iperf_args>
<direction>UL</direction>
<id>nrmodule2_quectel</id>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="080000">
<class>Terminate_eNB</class>
<desc>Terminate eNB</desc>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
<air_interface>lte</air_interface>
</testCase>
<testCase id="080001">
<class>Terminate_eNB</class>
<desc>Terminate gNB</desc>
<eNB_instance>1</eNB_instance>
<eNB_serverId>1</eNB_serverId>
<air_interface>nr</air_interface>
</testCase>
</testCaseList>
......@@ -26,7 +26,7 @@
<htmlTabIcon>wrench</htmlTabIcon>
<TestCaseRequestedList>
000001 000002
000003 000004
000004 000005 000003
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
......@@ -64,5 +64,10 @@
<eNB_serverId>1</eNB_serverId>
</testCase>
<testCase id="000005">
<class>IdleSleep</class>
<desc>Sleep</desc>
<idle_sleep_time_in_sec>120</idle_sleep_time_in_sec>
</testCase>
</testCaseList>
......@@ -21,8 +21,8 @@
-->
<testCaseList>
<htmlTabRef>TEST-NSA-FR1-TM1</htmlTabRef>
<htmlTabName>NSA Ping DL UL with QUECTEL</htmlTabName>
<htmlTabRef>TEST-NSA-FR1-TM2</htmlTabRef>
<htmlTabName>NSA 2x2 Ping DL UL with QUECTEL</htmlTabName>
<htmlTabIcon>tasks</htmlTabIcon>
<repeatCount>1</repeatCount>
<TestCaseRequestedList>
......@@ -32,6 +32,9 @@
010000
000001
050000
000002
070000
070001
000001
010002
080001
......@@ -57,11 +60,12 @@
<testCase id="030000">
<class>Initialize_eNB</class>
<desc>Initialize eNB</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/enb.band38.nsa_2x2.100PRB.usrpn310.conf</Initialize_eNB_args>
<Initialize_eNB_args>-O ci-scripts/conf_files/enb.band38.nsa_2x2.100PRB.usrpn310.conf --usrp-tx-thread-config 1 --thread-pool 0,2,4,6</Initialize_eNB_args>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
<air_interface>lte</air_interface>
<eNB_Trace>yes</eNB_Trace>
<eNB_Stats>yes</eNB_Stats>
<USRP_IPAddress>192.168.18.241</USRP_IPAddress>
</testCase>
......@@ -69,10 +73,11 @@
<testCase id="040000">
<class>Initialize_eNB</class>
<desc>Initialize gNB</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/gnb.band78.nsa_2x2.106PRB.usrpn310.conf -q</Initialize_eNB_args>
<Initialize_eNB_args>-O ci-scripts/conf_files/gnb.band78.nsa_2x2.106PRB.usrpn310.conf -q --usrp-tx-thread-config 1 --thread-pool 0,2,4,6</Initialize_eNB_args>
<eNB_instance>1</eNB_instance>
<eNB_serverId>1</eNB_serverId>
<air_interface>nr</air_interface>
<eNB_Stats>yes</eNB_Stats>
<USRP_IPAddress>192.168.18.240</USRP_IPAddress>
</testCase>
......@@ -111,17 +116,17 @@
<iperf_args>-u -b 20M -t 60</iperf_args>
<direction>DL</direction>
<id>nrmodule2_quectel</id>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="070001">
<class>Iperf</class>
<desc>iperf (UL/3Mbps/UDP)(60 sec)(single-ue profile)</desc>
<iperf_args>-u -b 3M -t 60</iperf_args>
<desc>iperf (UL/1Mbps/UDP)(20 sec)(single-ue profile)</desc>
<iperf_args>-u -b 1M -t 20</iperf_args>
<direction>UL</direction>
<id>nrmodule2_quectel</id>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
......
......@@ -33,7 +33,7 @@
<testCase id="000100">
<class>Deploy_EPC</class>
<desc>Deploy all EPC containers</desc>
<parameters>yaml_files/fr1_epc_tim</parameters>
<parameters>yaml_files/fr1_epc_20897</parameters>
</testCase>
</testCaseList>
......@@ -31,6 +31,9 @@
010000
000001
050000
050001
070000
070001
000001
010002
080000
......@@ -82,34 +85,26 @@
<desc>Ping: 20pings in 20sec</desc>
<id>nrmodule2_quectel</id>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>50</ping_packetloss_threshold>
</testCase>
<testCase id="050001">
<class>Ping</class>
<desc>Ping: 100pings in 20sec</desc>
<id>nrmodule2_quectel</id>
<ping_args>-c 100 -i 0.2</ping_args>
<ping_packetloss_threshold>50</ping_packetloss_threshold>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
<testCase id="070000">
<class>Iperf</class>
<desc>iperf (DL/20Mbps/UDP)(60 sec)(single-ue profile)</desc>
<iperf_args>-u -b 20M -t 60</iperf_args>
<desc>iperf (DL/5Mbps/UDP)(60 sec)(single-ue profile)</desc>
<iperf_args>-u -b 5M -t 60</iperf_args>
<direction>DL</direction>
<id>nrmodule2_quectel</id>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="070001">
<class>Iperf</class>
<desc>iperf (UL/3Mbps/UDP)(60 sec)(single-ue profile)</desc>
<iperf_args>-u -b 3M -t 60</iperf_args>
<desc>iperf (UL/1Mbps/UDP)(60 sec)(single-ue profile)</desc>
<iperf_args>-u -b 1M -t 60</iperf_args>
<direction>UL</direction>
<id>nrmodule2_quectel</id>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
......
......@@ -51,7 +51,7 @@ services:
LTE_K: FEC86BA6EB707ED08905757B1BB44B8F
APN1: oai.ipv4
APN2: oai2.ipv4
FIRST_IMSI: 208990100001127
FIRST_IMSI: 208970100001127
NB_USERS: 5
healthcheck:
test: /bin/bash -c "pgrep oai_hss"
......@@ -78,7 +78,7 @@ services:
HSS_FQDN: hss.openairinterface.org
HSS_REALM: openairinterface.org
MCC: '208'
MNC: '99'
MNC: '97'
MME_GID: 32768
MME_CODE: 3
TAC_0: 1
......@@ -97,15 +97,15 @@ services:
PEER_MME_IPV4_ADDRESS_FOR_S10_0: 0.0.0.0
PEER_MME_IPV4_ADDRESS_FOR_S10_1: 0.0.0.0
MCC_SGW_0: '208'
MNC3_SGW_0: '099'
MNC3_SGW_0: '097'
TAC_LB_SGW_0: '01'
TAC_HB_SGW_0: '00'
MCC_MME_0: '208'
MNC3_MME_0: '099'
MNC3_MME_0: '097'
TAC_LB_MME_0: '02'
TAC_HB_MME_0: '00'
MCC_MME_1: '208'
MNC3_MME_1: '099'
MNC3_MME_1: '097'
TAC_LB_MME_1: '03'
TAC_HB_MME_1: '00'
TAC_LB_SGW_TEST_0: '03'
......@@ -138,11 +138,12 @@ services:
UE_IP_ADDRESS_POOL_1: '12.1.1.2 - 12.1.1.254'
UE_IP_ADDRESS_POOL_2: '12.0.0.2 - 12.0.0.254'
MCC: '208'
MNC: '99'
MNC03: '099'
MNC: '97'
MNC03: '097'
TAC: 1
GW_ID: 1
REALM: openairinterface.org
UE_MTU_IPV4: 1500
healthcheck:
test: /bin/bash -c "pgrep oai_spgwc"
interval: 10s
......@@ -168,8 +169,8 @@ services:
NETWORK_UE_IP: '12.1.1.0/24'
NETWORK_UE_NAT_OPTION: 'yes'
MCC: '208'
MNC: '99'
MNC03: '099'
MNC: '97'
MNC03: '097'
TAC: 1
GW_ID: 1
REALM: openairinterface.org
......
version: '3.8'
services:
cassandra:
image: cassandra:2.1
container_name: prod-cassandra
networks:
private_net:
ipv4_address: 192.168.68.2
environment:
CASSANDRA_CLUSTER_NAME: "OAI HSS Cluster"
CASSANDRA_ENDPOINT_SNITCH: GossipingPropertyFileSnitch
healthcheck:
test: /bin/bash -c "nodetool status"
interval: 10s
timeout: 5s
retries: 5
db_init:
image: cassandra:2.1
container_name: prod-db-init
depends_on: [cassandra]
deploy:
restart_policy:
condition: on-failure
max_attempts: 10
networks:
private_net:
ipv4_address: 192.168.68.4
volumes:
- ./oai_db.cql:/home/oai_db.cql
entrypoint: /bin/bash -c "cqlsh --file /home/oai_db.cql 192.168.68.2 && echo 'OK'"
oai_hss:
image: oai-hss:production
container_name: prod-oai-hss
privileged: true
depends_on: [cassandra]
networks:
private_net:
ipv4_address: 192.168.68.3
public_net:
ipv4_address: 192.168.61.2
environment:
REALM: openairinterface.org
HSS_FQDN: hss.openairinterface.org
PREFIX: /openair-hss/etc
cassandra_Server_IP: 192.168.68.2
OP_KEY: 1006020f0a478bf6b699f15c062e42b3
LTE_K: fec86ba6eb707ed08905757b1bb44b8f
APN1: oai.ipv4
APN2: internet
FIRST_IMSI: 222010100001120
NB_USERS: 10
healthcheck:
test: /bin/bash -c "pgrep oai_hss"
interval: 10s
timeout: 5s
retries: 5
oai_mme:
image: oai-mme:production
container_name: prod-oai-mme
privileged: true
depends_on: [oai_hss]
networks:
public_net:
ipv4_address: 192.168.61.3
environment:
REALM: openairinterface.org
PREFIX: /openair-mme/etc
INSTANCE: 1
PID_DIRECTORY: /var/run
HSS_IP_ADDR: 192.168.61.2
HSS_HOSTNAME: hss
HSS_FQDN: hss.openairinterface.org
HSS_REALM: openairinterface.org
MCC: '222'
MNC: '01'
MME_GID: 32768
MME_CODE: 3
TAC_0: 1
TAC_1: 2
TAC_2: 3
MME_FQDN: mme.openairinterface.org
MME_S6A_IP_ADDR: 192.168.61.3
MME_INTERFACE_NAME_FOR_S1_MME: eth0
MME_IPV4_ADDRESS_FOR_S1_MME: 192.168.61.3
MME_INTERFACE_NAME_FOR_S11: eth0
MME_IPV4_ADDRESS_FOR_S11: 192.168.61.3
MME_INTERFACE_NAME_FOR_S10: lo
MME_IPV4_ADDRESS_FOR_S10: 127.0.0.10
OUTPUT: CONSOLE
SGW_IPV4_ADDRESS_FOR_S11_0: 192.168.61.4
PEER_MME_IPV4_ADDRESS_FOR_S10_0: 0.0.0.0
PEER_MME_IPV4_ADDRESS_FOR_S10_1: 0.0.0.0
MCC_SGW_0: '222'
MNC3_SGW_0: '001'
TAC_LB_SGW_0: '01'
TAC_HB_SGW_0: '00'
MCC_MME_0: '222'
MNC3_MME_0: '001'
TAC_LB_MME_0: '02'
TAC_HB_MME_0: '00'
MCC_MME_1: '222'
MNC3_MME_1: '001'
TAC_LB_MME_1: '03'
TAC_HB_MME_1: '00'
TAC_LB_SGW_TEST_0: '03'
TAC_HB_SGW_TEST_0: '00'
SGW_IPV4_ADDRESS_FOR_S11_TEST_0: 0.0.0.0
healthcheck:
test: /bin/bash -c "pgrep oai_mme"
interval: 10s
timeout: 5s
retries: 5
oai_spgwc:
image: oai-spgwc:production
privileged: true
depends_on: [oai_mme]
container_name: prod-oai-spgwc
networks:
public_net:
ipv4_address: 192.168.61.4
environment:
PID_DIRECTORY: /var/run
SGW_INTERFACE_NAME_FOR_S11: eth0
SGW_IP_FOR_S5_S8_CP: 127.0.0.11/8
PGW_IP_FOR_S5_S8_CP: 127.0.0.12/8
PGW_INTERFACE_NAME_FOR_SX: eth0
DEFAULT_APN: oai.ipv4
DEFAULT_DNS_IPV4_ADDRESS: 192.168.18.129
DEFAULT_DNS_SEC_IPV4_ADDRESS: 8.8.4.4
UE_IP_ADDRESS_POOL: '12.1.1.2 - 12.1.1.254'
PUSH_PROTOCOL_OPTION: 'yes'
healthcheck:
test: /bin/bash -c "pgrep oai_spgwc"
interval: 10s
timeout: 5s
retries: 5
oai_spgwu:
image: oai-spgwu-tiny:production
privileged: true
container_name: prod-oai-spgwu-tiny
depends_on: [oai_spgwc]
networks:
public_net:
ipv4_address: 192.168.61.5
environment:
PID_DIRECTORY: /var/run
INSTANCE: 1
SGW_INTERFACE_NAME_FOR_S1U_S12_S4_UP: eth0
PGW_INTERFACE_NAME_FOR_SGI: eth0
SGW_INTERFACE_NAME_FOR_SX: eth0
SPGWC0_IP_ADDRESS: 192.168.61.4
NETWORK_UE_IP: '12.1.1.0/24'
NETWORK_UE_NAT_OPTION: 'yes'
healthcheck:
test: /bin/bash -c "pgrep oai_spgwu"
interval: 10s
timeout: 5s
retries: 5
flexran_rtc:
image: flexran-rtc:production
privileged: true
container_name: prod-flexran-rtc
networks:
public_net:
ipv4_address: 192.168.61.10
healthcheck:
test: /bin/bash -c "pgrep rt_controller"
interval: 10s
timeout: 5s
retries: 5
trf_gen:
image: trf-gen:production
privileged: true
container_name: prod-trf-gen
networks:
public_net:
ipv4_address: 192.168.61.11
entrypoint: /bin/bash -c "ip route add 12.1.1.0/24 via 192.168.61.5 dev eth0; sleep infinity"
healthcheck:
test: /bin/bash -c "ping -c 2 192.168.61.5"
interval: 10s
timeout: 5s
retries: 5
networks:
private_net:
name: prod-oai-private-net
ipam:
config:
- subnet: 192.168.68.0/26
public_net:
name: prod-oai-public-net
ipam:
config:
- subnet: 192.168.61.0/26
......@@ -49,6 +49,7 @@
#include "SCHED_NR/fapi_nr_l1.h"
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "PHY/MODULATION/nr_modulation.h"
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all
//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all
......@@ -115,19 +116,36 @@ time_stats_t softmodem_stats_rx_sf; // total rx time
void tx_func(void *param) {
processingData_L1_t *info = (processingData_L1_t *) param;
processingData_L1tx_t *info = (processingData_L1tx_t *) param;
PHY_VARS_gNB *gNB = info->gNB;
int frame_tx = info->frame_tx;
int slot_tx = info->slot_tx;
phy_procedures_gNB_TX(gNB, frame_tx,slot_tx, 1);
// start FH TX processing
notifiedFIFO_elt_t *res;
int frame_tx = info->frame;
int slot_tx = info->slot;
phy_procedures_gNB_TX(info,
frame_tx,
slot_tx,
1);
info->slot = -1;
if ((frame_tx&127) == 0) dump_pdsch_stats(gNB);
// If the later of the 2 L1 tx thread finishes first,
// we wait for the earlier one to finish and start the RU thread
// to avoid realtime issues with USRP
// Start RU TX processing.
notifiedFIFO_elt_t *res;
res = pullTpool(gNB->resp_RU_tx, gNB->threadPool);
processingData_RU_t *syncMsg = (processingData_RU_t *)NotifiedFifoData(res);
LOG_D(PHY,"waiting for previous tx to finish, next slot %d,%d\n",syncMsg->next_slot,slot_tx);
while (syncMsg->next_slot != slot_tx) {
pushNotifiedFIFO(gNB->resp_RU_tx, res);
res = pullTpool(gNB->resp_RU_tx, gNB->threadPool);
syncMsg = (processingData_RU_t *)NotifiedFifoData(res);
}
LOG_D(PHY,"previous tx finished, next slot %d,%d\n",syncMsg->next_slot,slot_tx);
syncMsg->frame_tx = frame_tx;
syncMsg->slot_tx = slot_tx;
syncMsg->next_slot = get_next_downlink_slot(gNB, &gNB->gNB_config, frame_tx, slot_tx);
syncMsg->timestamp_tx = info->timestamp_tx;
syncMsg->ru = gNB->RU_list[0];
res->key = slot_tx;
......@@ -202,13 +220,6 @@ void rx_func(void *param) {
}
up_removed++;
}
for (j = 0; j < NUMBER_OF_NR_DLSCH_MAX; j++)
if (gNB->dlsch[j][0]->rnti == rnti_to_remove[i]) {
gNB->dlsch[j][0]->rnti = 0;
gNB->dlsch[j][0]->harq_mask = 0;
//clean_gNB_dlsch(gNB->dlsch[j][0]);
down_removed++;
}
for (j = 0; j < NUMBER_OF_NR_PUCCH_MAX; j++)
if (gNB->pucch[j]->active > 0 &&
gNB->pucch[j]->pucch_pdu.rnti == rnti_to_remove[i]) {
......@@ -256,7 +267,6 @@ void rx_func(void *param) {
LOG_D(PHY,"%s() Exit proc[rx:%d%d tx:%d%d]\n", __FUNCTION__, frame_rx, slot_rx, frame_tx, slot_tx);
// Call the scheduler
start_meas(&gNB->ul_indication_stats);
pthread_mutex_lock(&gNB->UL_INFO_mutex);
gNB->UL_INFO.frame = frame_rx;
......@@ -267,16 +277,17 @@ void rx_func(void *param) {
pthread_mutex_unlock(&gNB->UL_INFO_mutex);
stop_meas(&gNB->ul_indication_stats);
notifiedFIFO_elt_t *res;
if (tx_slot_type == NR_DOWNLINK_SLOT || tx_slot_type == NR_MIXED_SLOT) {
notifiedFIFO_elt_t *res;
res = pullTpool(gNB->resp_L1_tx, gNB->threadPool);
processingData_L1_t *syncMsg = (processingData_L1_t *)NotifiedFifoData(res);
processingData_L1tx_t *syncMsg = (processingData_L1tx_t *)NotifiedFifoData(res);
while (syncMsg->slot != slot_tx) {
pushNotifiedFIFO(gNB->resp_L1_tx, res);
res = pullTpool(gNB->resp_L1_tx, gNB->threadPool);
syncMsg = (processingData_L1tx_t *)NotifiedFifoData(res);
}
syncMsg->gNB = gNB;
syncMsg->frame_rx = frame_rx;
syncMsg->slot_rx = slot_rx;
syncMsg->frame_tx = frame_tx;
syncMsg->slot_tx = slot_tx;
AssertFatal(syncMsg->slot == slot_tx, "Thread message slot and logical slot number do not match\n");
syncMsg->timestamp_tx = info->timestamp_tx;
res->key = slot_tx;
pushTpool(gNB->threadPool, res);
......@@ -326,7 +337,6 @@ static void *process_stats_thread(void *param) {
PHY_VARS_gNB *gNB = (PHY_VARS_gNB *)param;
reset_meas(&gNB->phy_proc_tx);
reset_meas(&gNB->dlsch_encoding_stats);
reset_meas(&gNB->phy_proc_rx);
reset_meas(&gNB->ul_indication_stats);
......@@ -338,7 +348,8 @@ static void *process_stats_thread(void *param) {
while(!oai_exit)
{
sleep(1);
print_meas(&gNB->phy_proc_tx, "L1 Tx processing", NULL, NULL);
print_meas(gNB->phy_proc_tx_0, "L1 Tx processing thread 0", NULL, NULL);
print_meas(gNB->phy_proc_tx_1, "L1 Tx processing thread 1", NULL, NULL);
print_meas(&gNB->dlsch_encoding_stats, "DLSCH encoding", NULL, NULL);
print_meas(&gNB->phy_proc_rx, "L1 Rx processing", NULL, NULL);
print_meas(&gNB->ul_indication_stats, "UL Indication", NULL, NULL);
......@@ -392,14 +403,38 @@ void init_gNB_Tpool(int inst) {
// L1 RX result FIFO
gNB->resp_L1 = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
initNotifiedFIFO(gNB->resp_L1);
notifiedFIFO_elt_t *msg = newNotifiedFIFO_elt(sizeof(processingData_L1_t),0,gNB->resp_L1,rx_func);
pushNotifiedFIFO(gNB->resp_L1,msg); // to unblock the process in the beginning
// L1 TX result FIFO
gNB->resp_L1_tx = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
initNotifiedFIFO(gNB->resp_L1_tx);
// we create 2 threads for L1 tx processing
notifiedFIFO_elt_t *msgL1Tx = newNotifiedFIFO_elt(sizeof(processingData_L1tx_t),0,gNB->resp_L1_tx,tx_func);
processingData_L1tx_t *msgDataTx = (processingData_L1tx_t *)NotifiedFifoData(msgL1Tx);
init_DLSCH_struct(gNB, msgDataTx);
msgDataTx->slot = -1;
memset(msgDataTx->ssb, 0, 64*sizeof(NR_gNB_SSB_t));
reset_meas(&msgDataTx->phy_proc_tx);
gNB->phy_proc_tx_0 = &msgDataTx->phy_proc_tx;
pushNotifiedFIFO(gNB->resp_L1_tx,msgL1Tx); // to unblock the process in the beginning
msgL1Tx = newNotifiedFIFO_elt(sizeof(processingData_L1tx_t),0,gNB->resp_L1_tx,tx_func);
msgDataTx = (processingData_L1tx_t *)NotifiedFifoData(msgL1Tx);
init_DLSCH_struct(gNB, msgDataTx);
msgDataTx->slot = -1;
memset(msgDataTx->ssb, 0, 64*sizeof(NR_gNB_SSB_t));
reset_meas(&msgDataTx->phy_proc_tx);
gNB->phy_proc_tx_1 = &msgDataTx->phy_proc_tx;
pushNotifiedFIFO(gNB->resp_L1_tx,msgL1Tx); // to unblock the process in the beginning
// RU TX result FIFO
gNB->resp_RU_tx = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
initNotifiedFIFO(gNB->resp_RU_tx);
notifiedFIFO_elt_t *msgRUTx = newNotifiedFIFO_elt(sizeof(processingData_RU_t),0,gNB->resp_RU_tx,ru_tx_func);
processingData_RU_t *msgData = (processingData_RU_t*)msgRUTx->msgData;
msgData->next_slot = sf_ahead*gNB->frame_parms.slots_per_subframe; // first Tx slot
pushNotifiedFIFO(gNB->resp_RU_tx,msgRUTx); // to unblock the process in the beginning
// Stats measurement thread
if(opp_enabled == 1) threadCreate(&proc->process_stats_thread, process_stats_thread,(void *)gNB, "time_meas", -1, OAI_PRIORITY_RT_LOW);
......
......@@ -1303,14 +1303,9 @@ void *ru_thread( void *param ) {
pthread_cond_signal(&RC.ru_cond);
pthread_mutex_unlock(&RC.ru_mutex);
wait_sync("ru_thread");
notifiedFIFO_elt_t *msg = newNotifiedFIFO_elt(sizeof(processingData_L1_t),0,gNB->resp_L1,rx_func);
notifiedFIFO_elt_t *msgL1Tx = newNotifiedFIFO_elt(sizeof(processingData_L1_t),0,gNB->resp_L1_tx,tx_func);
notifiedFIFO_elt_t *msgRUTx = newNotifiedFIFO_elt(sizeof(processingData_L1_t),0,gNB->resp_RU_tx,ru_tx_func);
processingData_L1_t *syncMsg;
notifiedFIFO_elt_t *res;
pushNotifiedFIFO(gNB->resp_L1,msg); // to unblock the process in the beginning
pushNotifiedFIFO(gNB->resp_L1_tx,msgL1Tx); // to unblock the process in the beginning
pushNotifiedFIFO(gNB->resp_RU_tx,msgRUTx); // to unblock the process in the beginning
if(!emulate_rf) {
// Start RF device if any
......@@ -1453,9 +1448,15 @@ void *ru_thread( void *param ) {
else LOG_I(PHY,"RU %d rf device stopped\n",ru->idx);
}
delNotifiedFIFO_elt(msg);
delNotifiedFIFO_elt(msgL1Tx);
delNotifiedFIFO_elt(msgRUTx);
res = pullNotifiedFIFO(gNB->resp_L1);
delNotifiedFIFO_elt(res);
res = pullNotifiedFIFO(gNB->resp_L1_tx);
delNotifiedFIFO_elt(res);
res = pullNotifiedFIFO(gNB->resp_L1_tx);
delNotifiedFIFO_elt(res);
res = pullNotifiedFIFO(gNB->resp_RU_tx);
delNotifiedFIFO_elt(res);
ru_thread_status = 0;
return &ru_thread_status;
}
......
......@@ -1104,25 +1104,70 @@ void pnf_phy_deallocate_p7_vendor_ext(nfapi_p7_message_header_t *header) {
free(header);
}
notifiedFIFO_elt_t *l1tx_message_extract(PHY_VARS_gNB *gNB, int frame, int slot) {
notifiedFIFO_elt_t *res;
notifiedFIFO_elt_t *freeRes = NULL;
// check first message
res = pullTpool(gNB->resp_L1_tx, gNB->threadPool);
processingData_L1tx_t *msgTx = (processingData_L1tx_t *)NotifiedFifoData(res);
if (msgTx->slot == slot) {
return res;
}
if (msgTx->slot == -1) {
freeRes = res;
}
// check second message
pushNotifiedFIFO(gNB->resp_L1_tx,res);
res = pullTpool(gNB->resp_L1_tx, gNB->threadPool);
msgTx = (processingData_L1tx_t *)NotifiedFifoData(res);
if (msgTx->slot == slot) {
return res;
}
if (msgTx->slot == -1) {
freeRes = res;
}
if (freeRes) {
msgTx = (processingData_L1tx_t *)NotifiedFifoData(res);
msgTx->num_pdsch_slot=0;
msgTx->pdcch_pdu.pdcch_pdu_rel15.numDlDci = 0;
msgTx->ul_pdcch_pdu.pdcch_pdu.pdcch_pdu_rel15.numDlDci = 0;
msgTx->slot = slot;
msgTx->frame = frame;
return freeRes;
}
pushNotifiedFIFO(gNB->resp_L1_tx,res);
AssertFatal(1==0, "It means both L1 Tx messages are still waiting to be processed. This happens when L1 Tx processing is too slow. Message slot %d, scheduled slot %d\n",
msgTx->slot, slot);
}
int pnf_phy_ul_dci_req(gNB_L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, nfapi_nr_ul_dci_request_t *req) {
// LOG_D(PHY,"[PNF] HI_DCI0_REQUEST SFN/SF:%05d dci:%d hi:%d\n", NFAPI_SFNSF2DEC(req->sfn_sf), req->hi_dci0_request_body.number_of_dci, req->hi_dci0_request_body.number_of_hi);
struct PHY_VARS_gNB_s *gNB = RC.gNB[0];
// extract the next available thread message (priority to message with current slot, then free message)
notifiedFIFO_elt_t *res;
res = l1tx_message_extract(gNB, req->SFN, req->Slot);
processingData_L1tx_t *msgTx = (processingData_L1tx_t *)NotifiedFifoData(res);
if (proc ==NULL)
proc = &gNB->proc.L1_proc;
for (int i=0; i<req->numPdus; i++) {
if (req->ul_dci_pdu_list[i].PDUType == 0) {
nfapi_nr_ul_dci_request_pdus_t *ul_dci_req_pdu = &req->ul_dci_pdu_list[i];
handle_nfapi_nr_ul_dci_pdu(gNB, req->SFN, req->Slot, ul_dci_req_pdu);
if (req->numPdus > 0) {
if (req->ul_dci_pdu_list[req->numPdus-1].PDUType == 0) { // copy only the last PDU (PHY can have only one UL PDCCH pdu)
msgTx->ul_pdcch_pdu = req->ul_dci_pdu_list[req->numPdus-1]; // copy the last pdu
}
else {
LOG_E(PHY,"[PNF] UL_DCI_REQ sfn_slot:%d PDU[%d] - unknown pdu type:%d\n", NFAPI_SFNSLOT2DEC(req->SFN, req->Slot), i, req->ul_dci_pdu_list[i].PDUType);
LOG_E(PHY,"[PNF] UL_DCI_REQ sfn_slot:%d PDU[%d] - unknown pdu type:%d\n", NFAPI_SFNSLOT2DEC(req->SFN, req->Slot), req->numPdus-1, req->ul_dci_pdu_list[req->numPdus-1].PDUType);
}
}
pushNotifiedFIFO(gNB->resp_L1_tx,res);
return 0;
}
......@@ -1193,14 +1238,17 @@ int pnf_phy_dl_tti_req(gNB_L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7,
for (int i=0; i<req->dl_tti_request_body.nPDUs; i++) {
// NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() sfn/sf:%d PDU[%d] size:%d pdcch_vars->num_dci:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), i, dl_config_pdu_list[i].pdu_size,pdcch_vars->num_dci);
notifiedFIFO_elt_t *res;
res = l1tx_message_extract(gNB, sfn, slot);
processingData_L1tx_t *msgTx = (processingData_L1tx_t *)NotifiedFifoData(res);
if (dl_tti_pdu_list[i].PDUType == NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE) {
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdu=&dl_tti_pdu_list[i];
handle_nfapi_nr_pdcch_pdu(gNB, sfn, slot, &dl_tti_pdu->pdcch_pdu);
// we trust the scheduler sends only one PDCCH PDU per slot
msgTx->pdcch_pdu = dl_tti_pdu_list[i].pdcch_pdu; // fills the last received PDCCH PDU
}
else if (dl_tti_pdu_list[i].PDUType == NFAPI_NR_DL_TTI_SSB_PDU_TYPE) {
//NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() PDU:%d BCH: pdu_index:%u pdu_length:%d sdu_length:%d BCH_SDU:%x,%x,%x\n", __FUNCTION__, i, pdu_index, bch_pdu->bch_pdu_rel8.length, tx_request_pdu[sfn][sf][pdu_index]->segments[0].segment_length, sdu[0], sdu[1], sdu[2]);
handle_nr_nfapi_ssb_pdu(gNB, sfn, slot, &dl_tti_pdu_list[i]);
handle_nr_nfapi_ssb_pdu(msgTx, sfn, slot, &dl_tti_pdu_list[i]);
gNB->pbch_configured=1;
}
else if (dl_tti_pdu_list[i].PDUType == NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE) {
......@@ -1209,21 +1257,11 @@ int pnf_phy_dl_tti_req(gNB_L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7,
nfapi_nr_pdu_t *tx_data = tx_data_request[sfn][slot][rel15_pdu->pduIndex];
if (tx_data != NULL) {
int UE_id = find_nr_dlsch(rel15_pdu->rnti,gNB,SEARCH_EXIST_OR_FREE);
AssertFatal(UE_id!=-1,"no free or exiting dlsch_context\n");
AssertFatal(UE_id<NUMBER_OF_UE_MAX,"returned UE_id %d >= %d(NUMBER_OF_UE_MAX)\n",UE_id,NUMBER_OF_UE_MAX);
NR_gNB_DLSCH_t *dlsch0 = gNB->dlsch[UE_id][0];
int harq_pid = dlsch0->harq_ids[sfn%2][slot];
if(harq_pid >= dlsch0->Mdlharq) {
LOG_E(PHY,"pnf_phy_dl_config_req illegal harq_pid %d\n", harq_pid);
return(-1);
}
uint8_t *dlsch_sdu = nr_tx_pdus[UE_id][harq_pid];
memcpy(dlsch_sdu, tx_data->TLVs[0].value.direct,tx_data->PDU_length);
uint8_t *dlsch_sdu = (uint8_t *)tx_data->TLVs[0].value.direct;
//NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() DLSCH:pdu_index:%d handle_nfapi_dlsch_pdu(eNB, proc_rxtx, dlsch_pdu, transport_blocks:%d sdu:%p) eNB->pdcch_vars[proc->subframe_tx & 1].num_pdcch_symbols:%d\n", __FUNCTION__, rel8_pdu->pdu_index, rel8_pdu->transport_blocks, dlsch_sdu, eNB->pdcch_vars[proc->subframe_tx & 1].num_pdcch_symbols);
handle_nr_nfapi_pdsch_pdu(gNB, sfn, slot,pdsch_pdu, dlsch_sdu);
AssertFatal(msgTx->num_pdsch_slot < gNB->number_of_nr_dlsch_max,"Number of PDSCH PDUs %d exceeded the limit %d\n",
msgTx->num_pdsch_slot,gNB->number_of_nr_dlsch_max);
handle_nr_nfapi_pdsch_pdu(msgTx, pdsch_pdu, dlsch_sdu);
}
else {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() DLSCH NULL TX PDU SFN/SF:%d PDU_INDEX:%d\n", __FUNCTION__, NFAPI_SFNSLOT2DEC(sfn,slot), rel15_pdu->pduIndex);
......@@ -1231,11 +1269,12 @@ int pnf_phy_dl_tti_req(gNB_L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7,
}
else if (dl_tti_pdu_list[i].PDUType == NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE) {
nfapi_nr_dl_tti_csi_rs_pdu *csi_rs_pdu = &dl_tti_pdu_list[i].csi_rs_pdu;
handle_nfapi_nr_csirs_pdu(gNB, sfn, slot, csi_rs_pdu);
handle_nfapi_nr_csirs_pdu(msgTx, sfn, slot, csi_rs_pdu);
}
else {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() UNKNOWN:%d\n", __FUNCTION__, dl_tti_pdu_list[i].PDUType);
}
pushNotifiedFIFO(gNB->resp_L1_tx,res);
}
if(req->vendor_extension)
......
......@@ -519,45 +519,38 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config) {
LOG_I(PHY,"gNB %d configured\n",Mod_id);
}
void init_DLSCH_struct(PHY_VARS_gNB *gNB, processingData_L1tx_t *msg) {
NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
uint16_t grid_size = cfg->carrier_config.dl_grid_size[fp->numerology_index].value;
msg->num_pdsch_slot = 0;
for (int i=0; i<gNB->number_of_nr_dlsch_max; i++) {
LOG_I(PHY,"Allocating Transport Channel Buffers for DLSCH %d/%d\n",i,gNB->number_of_nr_dlsch_max);
for (int j=0; j<2; j++) {
msg->dlsch[i][j] = new_gNB_dlsch(fp,1,16,NSOFT,0,grid_size);
AssertFatal(msg->dlsch[i][j]!=NULL,"Can't initialize dlsch %d \n", i);
}
}
}
void init_nr_transport(PHY_VARS_gNB *gNB) {
int i;
int j;
NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
LOG_I(PHY, "Initialise nr transport\n");
uint16_t grid_size = cfg->carrier_config.dl_grid_size[fp->numerology_index].value;
memset(gNB->num_pdsch_rnti, 0, sizeof(uint16_t)*80);
for (i=0; i <NUMBER_OF_NR_PDCCH_MAX; i++) {
LOG_I(PHY,"Initializing PDCCH list for PDCCH %d/%d\n",i,NUMBER_OF_NR_PDCCH_MAX);
gNB->pdcch_pdu[i].frame=-1;
LOG_I(PHY,"Initializing UL PDCCH list for UL PDCCH %d/%d\n",i,NUMBER_OF_NR_PDCCH_MAX);
gNB->ul_pdcch_pdu[i].frame=-1;
}
for (i=0; i<NUMBER_OF_NR_PUCCH_MAX; i++) {
for (int i=0; i<NUMBER_OF_NR_PUCCH_MAX; i++) {
LOG_I(PHY,"Allocating Transport Channel Buffers for PUCCH %d/%d\n",i,NUMBER_OF_NR_PUCCH_MAX);
gNB->pucch[i] = new_gNB_pucch();
AssertFatal(gNB->pucch[i]!=NULL,"Can't initialize pucch %d \n", i);
}
for (i=0; i<gNB->number_of_nr_dlsch_max; i++) {
LOG_I(PHY,"Allocating Transport Channel Buffers for DLSCH %d/%d\n",i,gNB->number_of_nr_dlsch_max);
for (j=0; j<2; j++) {
gNB->dlsch[i][j] = new_gNB_dlsch(fp,1,16,NSOFT,0,grid_size);
AssertFatal(gNB->dlsch[i][j]!=NULL,"Can't initialize dlsch %d \n", i);
}
}
for (i=0; i<gNB->number_of_nr_ulsch_max; i++) {
for (int i=0; i<gNB->number_of_nr_ulsch_max; i++) {
LOG_I(PHY,"Allocating Transport Channel Buffer for ULSCH %d/%d\n",i,gNB->number_of_nr_ulsch_max);
for (j=0; j<2; j++) {
for (int j=0; j<2; j++) {
// ULSCH for data
gNB->ulsch[i][j] = new_gNB_ulsch(MAX_LDPC_ITERATIONS, fp->N_RB_UL, 0);
......
......@@ -409,6 +409,7 @@ void init_nr_transport(PHY_VARS_gNB *gNB);
void init_dfts(void);
void fill_subframe_mask(PHY_VARS_eNB *eNB);
void init_DLSCH_struct(PHY_VARS_gNB *gNB, processingData_L1tx_t *msg);
/** @} */
#endif
......
......@@ -73,8 +73,9 @@ void dump_nr_I0_stats(FILE *fd,PHY_VARS_gNB *gNB) {
int min_I0=1000,max_I0=0;
int amin=0,amax=0;
fprintf(fd,"Blacklisted PRBs %d/%d\n",gNB->num_ulprbbl,gNB->frame_parms.N_RB_UL);
for (int i=0; i<gNB->frame_parms.N_RB_UL; i++) {
if (i==(gNB->frame_parms.N_RB_UL>>1) - 1) i+=2;
if (gNB->ulprbbl[i] > 0) continue;
if (gNB->measurements.n0_subband_power_tot_dB[i]<min_I0) {min_I0 = gNB->measurements.n0_subband_power_tot_dB[i]; amin=i;}
......@@ -82,7 +83,8 @@ void dump_nr_I0_stats(FILE *fd,PHY_VARS_gNB *gNB) {
}
for (int i=0; i<gNB->frame_parms.N_RB_UL; i++) {
fprintf(fd,"%2d.",gNB->measurements.n0_subband_power_tot_dB[i]-gNB->measurements.n0_subband_power_avg_dB);
if (gNB->ulprbbl[i] ==0) fprintf(fd,"%2d.",gNB->measurements.n0_subband_power_tot_dB[i]-gNB->measurements.n0_subband_power_avg_dB);
else fprintf(fd," X.");
if (i%25 == 24) fprintf(fd,"\n");
}
fprintf(fd,"\n");
......
......@@ -134,8 +134,8 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
dci_pdu->AggregationLevel,
0,NULL);
polar_encoder_fast((uint64_t*)dci_pdu->Payload, (void*)encoder_output, n_RNTI,1,currentPtr);
#ifdef DEBUG_CHANNEL_CODING
printf("polar rnti %x,length %d, L %d\n",n_RNTI, dci_pdu->PayloadSizeBits,pdcch_pdu_rel15->dci_pdu.AggregationLevel[d]);
#if DEBUG_CHANNEL_CODING
printf("polar rnti %x,length %d, L %d\n",n_RNTI, dci_pdu->PayloadSizeBits,dci_pdu->AggregationLevel);
printf("DCI PDU: [0]->0x%lx \t [1]->0x%lx\n",
((uint64_t*)dci_pdu->Payload)[0], ((uint64_t*)dci_pdu->Payload)[1]);
printf("Encoded Payload (length:%d dwords):\n", encoded_length>>5);
......
......@@ -202,107 +202,3 @@ void nr_fill_cce_list(PHY_VARS_gNB *gNB, uint8_t m, nfapi_nr_dl_tti_pdcch_pdu_r
ret |= ((field>>i)&1)<<(size-i-1);
return ret;
}*/
int16_t find_nr_pdcch(int frame,int slot, PHY_VARS_gNB *gNB,find_type_t type) {
uint16_t i;
int16_t first_free_index=-1;
AssertFatal(gNB!=NULL,"gNB is null\n");
for (i=0; i<NUMBER_OF_NR_PDCCH_MAX; i++) {
LOG_D(PHY,"searching for frame.slot %d.%d : pdcch_index %d frame.slot %d.%d, first_free_index %d\n", frame,slot,i,gNB->pdcch_pdu[i].frame,gNB->pdcch_pdu[i].slot,first_free_index);
if ((gNB->pdcch_pdu[i].frame == frame) &&
(gNB->pdcch_pdu[i].slot==slot)) return i;
else if ( gNB->pdcch_pdu[i].frame==-1 && first_free_index==-1) first_free_index=i;
}
if (type == SEARCH_EXIST) return -1;
return first_free_index;
}
void nr_fill_dci(PHY_VARS_gNB *gNB,
int frame,
int slot,
nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu) {
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = &pdcch_pdu->pdcch_pdu_rel15;
NR_gNB_DLSCH_t *dlsch;
int pdcch_id = find_nr_pdcch(frame,slot,gNB,SEARCH_EXIST_OR_FREE);
AssertFatal(pdcch_id>=0 && pdcch_id<NUMBER_OF_NR_PDCCH_MAX,"Cannot find space for PDCCH, exiting\n");
memcpy((void*)&gNB->pdcch_pdu[pdcch_id].pdcch_pdu,(void*)pdcch_pdu,sizeof(*pdcch_pdu));
gNB->pdcch_pdu[pdcch_id].frame = frame;
gNB->pdcch_pdu[pdcch_id].slot = slot;
for (int i=0;i<pdcch_pdu_rel15->numDlDci;i++) {
//uint64_t *dci_pdu = (uint64_t*)pdcch_pdu_rel15->dci_pdu[i].Payload;
int dlsch_id = find_nr_dlsch(pdcch_pdu_rel15->dci_pdu[i].RNTI,gNB,SEARCH_EXIST_OR_FREE);
if( (dlsch_id<0) || (dlsch_id>=gNB->number_of_nr_dlsch_max) ){
LOG_E(PHY,"illegal dlsch_id found!!! rnti %04x dlsch_id %d\n",(unsigned int)pdcch_pdu_rel15->dci_pdu[i].RNTI,dlsch_id);
return;
}
dlsch = gNB->dlsch[dlsch_id][0];
int harq_pid = 0;
dlsch->slot_tx[slot] = 1;
dlsch->harq_ids[frame % 2][slot] = 0;
AssertFatal(harq_pid < 8 && harq_pid >= 0,
"illegal harq_pid %d\n",harq_pid);
dlsch->harq_mask |= (1<<harq_pid);
dlsch->rnti = pdcch_pdu_rel15->dci_pdu[i].RNTI;
// nr_fill_cce_list(gNB,0);
}
}
int16_t find_nr_ul_dci(int frame,int slot, PHY_VARS_gNB *gNB,find_type_t type) {
uint16_t i;
int16_t first_free_index=-1;
AssertFatal(gNB!=NULL,"gNB is null\n");
for (i=0; i<NUMBER_OF_NR_PDCCH_MAX; i++) {
LOG_D(PHY,"searching for frame.slot %d.%d : ul_pdcch_index %d frame.slot %d.%d, first_free_index %d\n", frame,slot,i,gNB->ul_pdcch_pdu[i].frame,gNB->ul_pdcch_pdu[i].slot,first_free_index);
if ((gNB->ul_pdcch_pdu[i].frame == frame) &&
(gNB->ul_pdcch_pdu[i].slot==slot)) return i;
else if (gNB->ul_pdcch_pdu[i].frame==-1 && first_free_index==-1) first_free_index=i;
}
if (type == SEARCH_EXIST) return -1;
return first_free_index;
}
void nr_fill_ul_dci(PHY_VARS_gNB *gNB,
int frame,
int slot,
nfapi_nr_ul_dci_request_pdus_t *pdcch_pdu) {
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = &pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15;
int pdcch_id = find_nr_ul_dci(frame,slot,gNB,SEARCH_EXIST_OR_FREE);
AssertFatal(pdcch_id>=0 && pdcch_id<NUMBER_OF_NR_PDCCH_MAX,"Cannot find space for UL PDCCH, exiting\n");
memcpy((void*)&gNB->ul_pdcch_pdu[pdcch_id].pdcch_pdu,(void*)pdcch_pdu,sizeof(*pdcch_pdu));
gNB->ul_pdcch_pdu[pdcch_id].frame = frame;
gNB->ul_pdcch_pdu[pdcch_id].slot = slot;
for (int i=0;i<pdcch_pdu_rel15->numDlDci;i++) {
//uint64_t *dci_pdu = (uint64_t*)pdcch_pdu_rel15->dci_pdu[i].Payload;
// if there's no DL DCI then generate CCE list
// nr_fill_cce_list(gNB,0);
/*
LOG_D(PHY, "DCI PDU: [0]->0x%lx \t [1]->0x%lx \n",dci_pdu[0], dci_pdu[1]);
LOG_D(PHY, "DCI type %d payload (size %d) generated on candidate %d\n", dci_alloc->pdcch_params.dci_format, dci_alloc->size, cand_idx);
*/
}
}
......@@ -111,10 +111,11 @@ void nr_pdsch_codeword_scrambling_optim(uint8_t *in,
}
uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB,
uint8_t nr_generate_pdsch(processingData_L1tx_t *msgTx,
int frame,
int slot) {
PHY_VARS_gNB *gNB = msgTx->gNB;
NR_gNB_DLSCH_t *dlsch;
uint32_t ***pdsch_dmrs = gNB->nr_gold_pdsch_dmrs[slot];
int32_t** txdataF = gNB->common_vars.txdataF;
......@@ -132,9 +133,8 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB,
time_stats_t *dlsch_interleaving_stats=&gNB->dlsch_interleaving_stats;
time_stats_t *dlsch_segmentation_stats=&gNB->dlsch_segmentation_stats;
for (int dlsch_id=0;dlsch_id<gNB->number_of_nr_dlsch_max;dlsch_id++) {
dlsch = gNB->dlsch[dlsch_id][0];
if (dlsch->slot_tx[slot] == 0) continue;
for (int dlsch_id=0; dlsch_id<msgTx->num_pdsch_slot; dlsch_id++) {
dlsch = msgTx->dlsch[dlsch_id][0];
NR_DL_gNB_HARQ_t *harq = &dlsch->harq_process;
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &harq->pdsch_pdu.pdsch_pdu_rel15;
......
......@@ -63,13 +63,11 @@ void nr_pdsch_codeword_scrambling(uint8_t *in,
uint32_t n_RNTI,
uint32_t* out);
void nr_fill_dlsch(PHY_VARS_gNB *gNB,
int frame,
int slot,
void nr_fill_dlsch(processingData_L1tx_t *msgTx,
nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu,
unsigned char *sdu);
uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB,
uint8_t nr_generate_pdsch(processingData_L1tx_t *msgTx,
int frame,
int slot);
void free_gNB_dlsch(NR_gNB_DLSCH_t **dlschptr, uint16_t N_RB);
......
......@@ -254,48 +254,16 @@ void nr_emulate_dlsch_payload(uint8_t* pdu, uint16_t size) {
*(pdu+i) = (uint8_t)rand();
}
int16_t find_nr_dlsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type) {
uint16_t i;
int16_t first_free_index=-1;
AssertFatal(gNB!=NULL,"gNB is null\n");
for (i=0; i<gNB->number_of_nr_dlsch_max; i++) {
AssertFatal(gNB->dlsch[i]!=NULL,"gNB->dlsch[%d] is null\n",i);
AssertFatal(gNB->dlsch[i][0]!=NULL,"gNB->dlsch[%d][0] is null\n",i);
LOG_D(PHY,"searching for rnti %x : dlsch_index %d=> harq_mask %x, rnti %x, first_free_index %d\n", rnti,i,
gNB->dlsch[i][0]->harq_mask,gNB->dlsch[i][0]->rnti,first_free_index);
if ((gNB->dlsch[i][0]->harq_mask >0) &&
(gNB->dlsch[i][0]->rnti==rnti)) return i;
else if ((gNB->dlsch[i][0]->harq_mask == 0) && (first_free_index==-1)) first_free_index=i;
}
if (type == SEARCH_EXIST) return -1;
if (first_free_index != -1)
gNB->dlsch[first_free_index][0]->rnti = 0;
return first_free_index;
}
void nr_fill_dlsch(PHY_VARS_gNB *gNB,
int frame,
int slot,
void nr_fill_dlsch(processingData_L1tx_t *msgTx,
nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu,
uint8_t *sdu) {
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &pdsch_pdu->pdsch_pdu_rel15;
int dlsch_id = find_nr_dlsch(rel15->rnti,gNB,SEARCH_EXIST);
AssertFatal( (dlsch_id>=0) && (dlsch_id<gNB->number_of_nr_dlsch_max),
"illegal or no dlsch_id found!!! rnti %04x dlsch_id %d\n",rel15->rnti,dlsch_id);
NR_gNB_DLSCH_t *dlsch = gNB->dlsch[dlsch_id][0];
NR_gNB_DLSCH_t *dlsch = msgTx->dlsch[msgTx->num_pdsch_slot][0];
NR_DL_gNB_HARQ_t *harq = &dlsch->harq_process;
/// DLSCH struct
memcpy((void*)&harq->pdsch_pdu, (void*)pdsch_pdu, sizeof(nfapi_nr_dl_tti_pdsch_pdu));
gNB->num_pdsch_rnti[slot]++;
msgTx->num_pdsch_slot++;
AssertFatal(sdu!=NULL,"sdu is null\n");
harq->pdu = sdu;
}
......@@ -306,8 +306,8 @@ void nr_processULSegment(void* arg) {
int max_ldpc_iterations = p_decoderParms->numMaxIter;
int8_t llrProcBuf[OAI_UL_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32)));
int16_t z [68*384];
int8_t l [68*384];
int16_t z [68*384 + 16] __attribute__ ((aligned(16)));
int8_t l [68*384 + 16] __attribute__ ((aligned(16)));
__m128i *pv = (__m128i*)&z;
__m128i *pl = (__m128i*)&l;
......
......@@ -762,6 +762,7 @@ typedef struct RRU_config_s {
typedef struct processingData_RU {
int frame_tx;
int slot_tx;
int next_slot;
openair0_timestamp timestamp_tx;
RU_t *ru;
} processingData_RU_t;
......
......@@ -122,8 +122,6 @@ typedef struct {
typedef struct {
uint8_t active;
int frame;
int slot;
nfapi_nr_dl_tti_csi_rs_pdu csirs_pdu;
} NR_gNB_CSIRS_t;
......@@ -766,7 +764,6 @@ typedef struct PHY_VARS_gNB_s {
// nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu;
// nfapi_nr_ul_dci_request_pdus_t *ul_dci_pdu;
uint16_t num_pdsch_rnti[80];
NR_gNB_SSB_t ssb[64];
NR_gNB_PBCH pbch;
nr_cce_t cce_list[MAX_DCI_CORESET][NR_MAX_PDCCH_AGG_LEVEL];
NR_gNB_COMMON common_vars;
......@@ -774,7 +771,6 @@ typedef struct PHY_VARS_gNB_s {
NR_gNB_PUSCH *pusch_vars[NUMBER_OF_NR_ULSCH_MAX];
NR_gNB_PUCCH_t *pucch[NUMBER_OF_NR_PUCCH_MAX];
NR_gNB_PDCCH_t pdcch_pdu[NUMBER_OF_NR_PDCCH_MAX];
NR_gNB_CSIRS_t csirs_pdu[NUMBER_OF_NR_CSIRS_MAX];
NR_gNB_UL_PDCCH_t ul_pdcch_pdu[NUMBER_OF_NR_PDCCH_MAX];
NR_gNB_DLSCH_t *dlsch[NUMBER_OF_NR_DLSCH_MAX][2]; // Nusers times two spatial streams
NR_gNB_ULSCH_t *ulsch[NUMBER_OF_NR_ULSCH_MAX][2]; // [Nusers times][2 codewords]
......@@ -857,10 +853,13 @@ typedef struct PHY_VARS_gNB_s {
int pusch_thres;
int prach_thres;
uint64_t bad_pucch;
int num_ulprbbl;
int ulprbbl[275];
/*
time_stats_t phy_proc;
*/
time_stats_t phy_proc_tx;
time_stats_t *phy_proc_tx_0;
time_stats_t *phy_proc_tx_1;
time_stats_t phy_proc_rx;
time_stats_t rx_prach;
/*
......@@ -952,4 +951,24 @@ typedef struct processingData_L1 {
PHY_VARS_gNB *gNB;
} processingData_L1_t;
typedef enum {
FILLED,
FILLING,
NOT_FILLED
} msgStatus_t;
typedef struct processingData_L1tx {
int frame;
int slot;
openair0_timestamp timestamp_tx;
PHY_VARS_gNB *gNB;
nfapi_nr_dl_tti_pdcch_pdu pdcch_pdu;
nfapi_nr_ul_dci_request_pdus_t ul_pdcch_pdu;
NR_gNB_CSIRS_t csirs_pdu[NUMBER_OF_NR_CSIRS_MAX];
NR_gNB_DLSCH_t *dlsch[NUMBER_OF_NR_DLSCH_MAX][2];
NR_gNB_SSB_t ssb[64];
uint16_t num_pdsch_slot;
time_stats_t phy_proc_tx;
} processingData_L1tx_t;
#endif
......@@ -13,11 +13,11 @@ void handle_nr_nfapi_ssb_pdu(PHY_VARS_gNB *gNB,int frame,int slot,
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdu){}
int16_t find_nr_dlsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type){return 0;}
void handle_nr_nfapi_pdsch_pdu(PHY_VARS_gNB *gNB,int frame,int slot,
nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu,
void handle_nr_nfapi_pdsch_pdu(processingData_L1tx_t *msgTx,
nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu,
uint8_t *sdu){
}
void handle_nfapi_nr_csirs_pdu(PHY_VARS_gNB *gNB,
}
void handle_nfapi_nr_csirs_pdu(processingData_L1tx_t *msgTx,
int frame, int slot,
nfapi_nr_dl_tti_csi_rs_pdu *csirs_pdu){
}
......@@ -51,4 +51,5 @@ void nr_phy_config_request(NR_PHY_Config_t *gNB){}
void install_nr_schedule_handlers(NR_IF_Module_t *if_inst){}
void nr_dump_frame_parms(NR_DL_FRAME_PARMS *fp){}
\ No newline at end of file
void nr_dump_frame_parms(NR_DL_FRAME_PARMS *fp){}
......@@ -13,11 +13,11 @@ void handle_nr_nfapi_ssb_pdu(PHY_VARS_gNB *gNB,int frame,int slot,
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdu){}
int16_t find_nr_dlsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type){return 0;}
void handle_nr_nfapi_pdsch_pdu(PHY_VARS_gNB *gNB,int frame,int slot,
nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu,
void handle_nr_nfapi_pdsch_pdu(processingData_L1tx_t *msgTx,
nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu,
uint8_t *sdu){
}
void handle_nfapi_nr_csirs_pdu(PHY_VARS_gNB *gNB,
}
void handle_nfapi_nr_csirs_pdu(processingData_L1tx_t *msgTx,
int frame, int slot,
nfapi_nr_dl_tti_csi_rs_pdu *csirs_pdu){
}
......@@ -53,4 +53,3 @@ void install_nr_schedule_handlers(NR_IF_Module_t *if_inst){}
//void nr_dump_frame_parms(NR_DL_FRAME_PARMS *fp){}
\ No newline at end of file
......@@ -43,7 +43,7 @@ extern int oai_nfapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req);
extern uint8_t nfapi_mode;
void handle_nr_nfapi_ssb_pdu(PHY_VARS_gNB *gNB,int frame,int slot,
void handle_nr_nfapi_ssb_pdu(processingData_L1tx_t *msgTx,int frame,int slot,
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdu)
{
......@@ -53,11 +53,11 @@ void handle_nr_nfapi_ssb_pdu(PHY_VARS_gNB *gNB,int frame,int slot,
uint8_t i_ssb = dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.SsbBlockIndex;
LOG_D(PHY,"%d.%d : ssb index %d pbch_pdu: %x\n",frame,slot,i_ssb,dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.bchPayload);
if (gNB->ssb[i_ssb].active)
if (msgTx->ssb[i_ssb].active)
AssertFatal(1==0,"SSB PDU with index %d already active\n",i_ssb);
else {
gNB->ssb[i_ssb].active = true;
memcpy((void*)&gNB->ssb[i_ssb].ssb_pdu,&dl_tti_pdu->ssb_pdu,sizeof(dl_tti_pdu->ssb_pdu));
msgTx->ssb[i_ssb].active = true;
memcpy((void*)&msgTx->ssb[i_ssb].ssb_pdu,&dl_tti_pdu->ssb_pdu,sizeof(dl_tti_pdu->ssb_pdu));
}
}
......@@ -100,46 +100,16 @@ void handle_nr_nfapi_ssb_pdu(PHY_VARS_gNB *gNB,int frame,int slot,
}*/
void handle_nfapi_nr_pdcch_pdu(PHY_VARS_gNB *gNB,
int frame, int slot,
nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu) {
LOG_D(PHY,"Frame %d, Slot %d: DCI processing - proc:slot_tx:%d pdcch_pdu_rel15->numDlDci:%d\n",frame,slot, slot, pdcch_pdu->pdcch_pdu_rel15.numDlDci);
// copy dci configuration into gNB structure
// gNB->pdcch_pdu = pdcch_pdu;
nr_fill_dci(gNB,frame,slot,pdcch_pdu);
}
void handle_nfapi_nr_ul_dci_pdu(PHY_VARS_gNB *gNB,
int frame, int slot,
nfapi_nr_ul_dci_request_pdus_t *ul_dci_request_pdu) {
LOG_D(PHY,"Frame %d, Slot %d: UL DCI processing - proc:slot_tx:%d pdcch_pdu_rel15->numDlDci:%d\n",frame,slot, slot, ul_dci_request_pdu->pdcch_pdu.pdcch_pdu_rel15.numDlDci);
// copy dci configuration into gNB structure
// gNB->ul_dci_pdu = ul_dci_request_pdu;
nr_fill_ul_dci(gNB,frame,slot,ul_dci_request_pdu);
}
void handle_nfapi_nr_csirs_pdu(PHY_VARS_gNB *gNB,
int frame, int slot,
void handle_nfapi_nr_csirs_pdu(processingData_L1tx_t *msgTx,
int frame,int slot,
nfapi_nr_dl_tti_csi_rs_pdu *csirs_pdu) {
int found = 0;
for (int id=0; id<NUMBER_OF_NR_CSIRS_MAX; id++) {
NR_gNB_CSIRS_t *csirs = &gNB->csirs_pdu[id];
NR_gNB_CSIRS_t *csirs = &msgTx->csirs_pdu[id];
if (csirs->active == 0) {
LOG_D(PHY,"Frame %d Slot %d CSI_RS with ID %d is now active\n",frame,slot,id);
csirs->frame = frame;
csirs->slot = slot;
csirs->active = 1;
memcpy((void*)&csirs->csirs_pdu, (void*)csirs_pdu, sizeof(nfapi_nr_dl_tti_csi_rs_pdu));
found = 1;
......@@ -151,13 +121,13 @@ void handle_nfapi_nr_csirs_pdu(PHY_VARS_gNB *gNB,
}
void handle_nr_nfapi_pdsch_pdu(PHY_VARS_gNB *gNB,int frame,int slot,
void handle_nr_nfapi_pdsch_pdu(processingData_L1tx_t *msgTx,
nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu,
uint8_t *sdu)
{
nr_fill_dlsch(gNB,frame,slot,pdsch_pdu,sdu);
nr_fill_dlsch(msgTx,pdsch_pdu,sdu);
}
......@@ -178,6 +148,10 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){
gNB = RC.gNB[Mod_id];
notifiedFIFO_elt_t *res;
res = pullTpool(gNB->resp_L1_tx, gNB->threadPool);
processingData_L1tx_t *msgTx = (processingData_L1tx_t *)NotifiedFifoData(res);
uint8_t number_dl_pdu = (DL_req==NULL) ? 0 : DL_req->dl_tti_request_body.nPDUs;
uint8_t number_ul_dci_pdu = (UL_dci_req==NULL) ? 0 : UL_dci_req->numPdus;
uint8_t number_ul_tti_pdu = (UL_tti_req==NULL) ? 0 : UL_tti_req->n_pdus;
......@@ -192,33 +166,31 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){
number_ul_dci_pdu,number_ul_tti_pdu);
int pdcch_received=0;
gNB->num_pdsch_rnti[slot]=0;
for (int i=0; i<gNB->number_of_nr_dlsch_max; i++) {
gNB->dlsch[i][0]->rnti=0;
gNB->dlsch[i][0]->harq_mask=0;
}
msgTx->num_pdsch_slot=0;
msgTx->pdcch_pdu.pdcch_pdu_rel15.numDlDci = 0;
msgTx->ul_pdcch_pdu.pdcch_pdu.pdcch_pdu_rel15.numDlDci = 0;
msgTx->slot = slot;
msgTx->frame = frame;
for (int i=0;i<number_dl_pdu;i++) {
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdu = &DL_req->dl_tti_request_body.dl_tti_pdu_list[i];
LOG_D(PHY,"NFAPI: dl_pdu %d : type %d\n",i,dl_tti_pdu->PDUType);
switch (dl_tti_pdu->PDUType) {
case NFAPI_NR_DL_TTI_SSB_PDU_TYPE:
handle_nr_nfapi_ssb_pdu(gNB,frame,slot,
handle_nr_nfapi_ssb_pdu(msgTx,frame,slot,
dl_tti_pdu);
break;
case NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE:
AssertFatal(pdcch_received == 0, "pdcch_received is not 0, we can only handle one PDCCH PDU per slot\n");
handle_nfapi_nr_pdcch_pdu(gNB,
frame, slot,
&dl_tti_pdu->pdcch_pdu);
msgTx->pdcch_pdu = dl_tti_pdu->pdcch_pdu;
pdcch_received = 1;
break;
case NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE:
LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE for %d.%d\n",frame,slot,DL_req->SFN,DL_req->Slot);
handle_nfapi_nr_csirs_pdu(gNB,
frame, slot,
handle_nfapi_nr_csirs_pdu(msgTx,frame,slot,
&dl_tti_pdu->csi_rs_pdu);
break;
......@@ -229,15 +201,16 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){
AssertFatal(TX_req->pdu_list[pduIndex].num_TLV == 1, "TX_req->pdu_list[%d].num_TLV %d != 1\n",
pduIndex,TX_req->pdu_list[pduIndex].num_TLV);
uint8_t *sdu = (uint8_t *)TX_req->pdu_list[pduIndex].TLVs[0].value.direct;
handle_nr_nfapi_pdsch_pdu(gNB,frame,slot,&dl_tti_pdu->pdsch_pdu, sdu);
break;
AssertFatal(msgTx->num_pdsch_slot < gNB->number_of_nr_dlsch_max,"Number of PDSCH PDUs %d exceeded the limit %d\n",
msgTx->num_pdsch_slot,gNB->number_of_nr_dlsch_max);
handle_nr_nfapi_pdsch_pdu(msgTx,&dl_tti_pdu->pdsch_pdu, sdu);
}
}
if (number_ul_dci_pdu > 0)
msgTx->ul_pdcch_pdu = UL_dci_req->ul_dci_pdu_list[number_ul_dci_pdu-1]; // copy the last pdu
for (int i=0;i<number_ul_dci_pdu;i++) {
handle_nfapi_nr_ul_dci_pdu(gNB, frame, slot, &UL_dci_req->ul_dci_pdu_list[i]);
}
pushNotifiedFIFO(gNB->resp_L1_tx,res);
for (int i = 0; i < number_ul_tti_pdu; i++) {
switch (UL_tti_req->pdus_list[i].pdu_type) {
......
......@@ -37,13 +37,13 @@
#include "nfapi_nr_interface_scf.h"
// added
void handle_nr_nfapi_ssb_pdu(PHY_VARS_gNB *gNB,
void handle_nr_nfapi_ssb_pdu(processingData_L1tx_t *msgTx,
int frame,int slot,
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdu);
void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO);
void handle_nfapi_nr_csirs_pdu(PHY_VARS_gNB *gNB,
void handle_nfapi_nr_csirs_pdu(processingData_L1tx_t *msgTx,
int frame, int slot,
nfapi_nr_dl_tti_csi_rs_pdu *csirs_pdu);
......@@ -51,7 +51,7 @@ void handle_nfapi_nr_pdcch_pdu(PHY_VARS_gNB *gNB,
int frame, int subframe,
nfapi_nr_dl_tti_pdcch_pdu *dcl_dl_pdu);
void handle_nr_nfapi_pdsch_pdu(PHY_VARS_gNB *gNB,int frame,int slot,
void handle_nr_nfapi_pdsch_pdu(processingData_L1tx_t *msgTx,
nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu,
uint8_t *sdu);
......
......@@ -30,6 +30,7 @@
************************************************************************/
#include "PHY/defs_nr_common.h"
#include "PHY/defs_gNB.h"
#include "PHY/defs_nr_UE.h"
#include "SCHED_NR/phy_frame_config_nr.h"
......@@ -308,6 +309,21 @@ int set_tdd_configuration_dedicated_nr(NR_DL_FRAME_PARMS *frame_parms) {
*
*********************************************************************/
int get_next_downlink_slot(PHY_VARS_gNB *gNB, nfapi_nr_config_request_scf_t *cfg, int nr_frame, int nr_slot) {
int slot = nr_slot;
int frame = nr_frame;
int slots_per_frame = gNB->frame_parms.slots_per_frame;
while (true) {
slot++;
if (slot/slots_per_frame) frame++;
slot %= slots_per_frame;
int slot_type = nr_slot_select(cfg, frame, slot);
if (slot_type == NR_DOWNLINK_SLOT || slot_type == NR_MIXED_SLOT) return slot;
AssertFatal(frame < (nr_frame+2), "Something went worng. This shouldn't happen\n");
}
}
int nr_slot_select(nfapi_nr_config_request_scf_t *cfg, int nr_frame, int nr_slot) {
/* for FFD all slot can be considered as an uplink */
int mu = cfg->ssb_config.scs_common.value,check_slot=0;
......
......@@ -92,5 +92,7 @@ void free_tdd_configuration_nr(NR_DL_FRAME_PARMS *frame_parms);
void free_tdd_configuration_dedicated_nr(NR_DL_FRAME_PARMS *frame_parms);
int get_next_downlink_slot(PHY_VARS_gNB *gNB, nfapi_nr_config_request_scf_t *cfg, int nr_frame, int nr_slot);
#endif /* PHY_FRAME_CONFIG_NR_H */
......@@ -65,7 +65,7 @@ void nr_set_ssb_first_subcarrier(nfapi_nr_config_request_scf_t *cfg, NR_DL_FRAME
fp->ssb_start_subcarrier = (12 * cfg->ssb_table.ssb_offset_point_a.value + sco);
LOG_D(PHY, "SSB first subcarrier %d (%d,%d)\n", fp->ssb_start_subcarrier,cfg->ssb_table.ssb_offset_point_a.value,sco);
}
}
void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame,int slot,nfapi_nr_dl_tti_ssb_pdu ssb_pdu) {
......@@ -124,10 +124,12 @@ void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame,int slot,nfapi_nr_
}
void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
int frame,int slot,
void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx,
int frame,
int slot,
int do_meas) {
int aa;
PHY_VARS_gNB *gNB = msgTx->gNB;
NR_DL_FRAME_PARMS *fp=&gNB->frame_parms;
nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
int offset = gNB->CC_id;
......@@ -138,7 +140,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_TX+offset,1);
if (do_meas==1) start_meas(&gNB->phy_proc_tx);
if (do_meas==1) start_meas(&msgTx->phy_proc_tx);
// clear the transmit data array and beam index for the current slot
for (aa=0; aa<cfg->carrier_config.num_tx_ant.value; aa++) {
......@@ -147,58 +149,44 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_COMMON_TX,1);
for (int i=0; i<fp->Lmax; i++) {
if (gNB->ssb[i].active) {
nr_common_signal_procedures(gNB,frame,slot,gNB->ssb[i].ssb_pdu);
gNB->ssb[i].active = false;
if (msgTx->ssb[i].active) {
nr_common_signal_procedures(gNB,frame,slot,msgTx->ssb[i].ssb_pdu);
msgTx->ssb[i].active = false;
}
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_COMMON_TX,0);
int pdcch_pdu_id=find_nr_pdcch(frame,slot,gNB,SEARCH_EXIST);
int ul_pdcch_pdu_id=find_nr_ul_dci(frame,slot,gNB,SEARCH_EXIST);
LOG_D(PHY,"[gNB %d] Frame %d slot %d, pdcch_pdu_id %d, ul_pdcch_pdu_id %d\n",
gNB->Mod_id,frame,slot,pdcch_pdu_id,ul_pdcch_pdu_id);
int num_dl_dci = msgTx->pdcch_pdu.pdcch_pdu_rel15.numDlDci;
int num_ul_dci = msgTx->ul_pdcch_pdu.pdcch_pdu.pdcch_pdu_rel15.numDlDci;
if (pdcch_pdu_id >= 0 || ul_pdcch_pdu_id >= 0) {
if (num_dl_dci > 0 || num_ul_dci > 0) {
LOG_D(PHY, "[gNB %d] Frame %d slot %d Calling nr_generate_dci_top (number of UL/DL DCI %d/%d)\n",
gNB->Mod_id, frame, slot,
gNB->ul_pdcch_pdu[ul_pdcch_pdu_id].pdcch_pdu.pdcch_pdu.pdcch_pdu_rel15.numDlDci,
gNB->pdcch_pdu[pdcch_pdu_id].pdcch_pdu.pdcch_pdu_rel15.numDlDci);
gNB->Mod_id, frame, slot, num_ul_dci, num_dl_dci);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_PDCCH_TX,1);
nr_generate_dci_top(gNB,
pdcch_pdu_id>=0 ? &gNB->pdcch_pdu[pdcch_pdu_id].pdcch_pdu : NULL,
ul_pdcch_pdu_id>=0 ? &gNB->ul_pdcch_pdu[ul_pdcch_pdu_id].pdcch_pdu.pdcch_pdu : NULL,
num_dl_dci > 0 ? &msgTx->pdcch_pdu : NULL,
num_ul_dci > 0 ? &msgTx->ul_pdcch_pdu.pdcch_pdu : NULL,
gNB->nr_gold_pdcch_dmrs[slot],
&gNB->common_vars.txdataF[0][txdataF_offset],
AMP, fp);
// free up entry in pdcch tables
if (pdcch_pdu_id>=0) gNB->pdcch_pdu[pdcch_pdu_id].frame = -1;
if (ul_pdcch_pdu_id>=0) gNB->ul_pdcch_pdu[ul_pdcch_pdu_id].frame = -1;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_PDCCH_TX,0);
if (pdcch_pdu_id >= 0) gNB->pdcch_pdu[pdcch_pdu_id].frame = -1;
if (ul_pdcch_pdu_id >= 0) gNB->ul_pdcch_pdu[ul_pdcch_pdu_id].frame = -1;
}
for (int i=0; i<gNB->num_pdsch_rnti[slot]; i++) {
if (msgTx->num_pdsch_slot > 0) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DLSCH,1);
LOG_D(PHY, "PDSCH generation started (%d) in frame %d.%d\n", gNB->num_pdsch_rnti[slot],frame,slot);
nr_generate_pdsch(gNB,frame, slot);
LOG_D(PHY, "PDSCH generation started (%d) in frame %d.%d\n", msgTx->num_pdsch_slot,frame,slot);
nr_generate_pdsch(msgTx, frame, slot);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DLSCH,0);
}
for (int i=0;i<NUMBER_OF_NR_CSIRS_MAX;i++){
NR_gNB_CSIRS_t *csirs = &gNB->csirs_pdu[i];
if ((csirs->active == 1) &&
(csirs->frame == frame) &&
(csirs->slot == slot) ) {
NR_gNB_CSIRS_t *csirs = &msgTx->csirs_pdu[i];
if ((csirs->active == 1)) {
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;
nr_generate_csi_rs(gNB, AMP, csi_params, gNB->gNB_config.cell_config.phy_cell_id.value, slot);
......@@ -206,7 +194,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
}
}
if (do_meas==1) stop_meas(&gNB->phy_proc_tx);
if (do_meas==1) stop_meas(&msgTx->phy_proc_tx);
// if ((frame&127) == 0) dump_pdsch_stats(gNB);
......@@ -262,7 +250,7 @@ void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req) {
}
//int dumpsig=0;
// if all segments are done
// if all segments are done
if (rdata->nbSegments == ulsch_harq->processedSegments) {
if (decodeSuccess) {
LOG_D(PHY,"[gNB %d] ULSCH: Setting ACK for SFN/SF %d.%d (pid %d, ndi %d, status %d, round %d, TBS %d, Max interation (all seg) %d)\n",
......@@ -275,9 +263,15 @@ void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req) {
nr_fill_indication(gNB,ulsch_harq->frame, ulsch_harq->slot, rdata->ulsch_id, rdata->harq_pid, 0,0);
//dumpsig=1;
} else {
LOG_D(PHY,"[gNB %d] ULSCH: Setting NAK for SFN/SF %d/%d (pid %d, ndi %d, status %d, round %d, RV %d, TBS %d) r %d\n",
LOG_I(PHY,"[gNB %d] ULSCH: Setting NAK for SFN/SF %d/%d (pid %d, ndi %d, status %d, round %d, RV %d, prb_start %d, prb_size %d, TBS %d) r %d\n",
gNB->Mod_id, ulsch_harq->frame, ulsch_harq->slot,
rdata->harq_pid,pusch_pdu->pusch_data.new_data_indicator,ulsch_harq->status, ulsch_harq->round, ulsch_harq->ulsch_pdu.pusch_data.rv_index,ulsch_harq->TBS,r);
rdata->harq_pid, pusch_pdu->pusch_data.new_data_indicator, ulsch_harq->status,
ulsch_harq->round,
ulsch_harq->ulsch_pdu.pusch_data.rv_index,
ulsch_harq->ulsch_pdu.rb_start,
ulsch_harq->ulsch_pdu.rb_size,
ulsch_harq->TBS,
r);
ulsch_harq->round++;
if (ulsch_harq->round >= ulsch->Mlimit) {
ulsch_harq->status = SCH_IDLE;
......@@ -290,7 +284,7 @@ void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req) {
LOG_D(PHY, "ULSCH %d in error\n",rdata->ulsch_id);
nr_fill_indication(gNB,ulsch_harq->frame, ulsch_harq->slot, rdata->ulsch_id, rdata->harq_pid, 1,0);
}
/*
/*
if (ulsch_harq->ulsch_pdu.mcs_index == 9 && dumpsig==1) {
#ifdef __AVX2__
int off = ((ulsch_harq->ulsch_pdu.rb_size&1) == 1)? 4:0;
......@@ -492,8 +486,8 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id,
}
exit(-1);
}
}
// crc indication
uint16_t num_crc = gNB->UL_INFO.crc_ind.number_crcs;
gNB->UL_INFO.crc_ind.crc_list = &gNB->crc_pdu_list[0];
......@@ -538,11 +532,20 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id,
// Function to fill UL RB mask to be used for N0 measurements
void fill_ul_rb_mask(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
int rb = 0;
int rb2 = 0;
for (int symbol=0;symbol<14;symbol++)
for (int m=0;m<9;m++) gNB->rb_mask_ul[symbol][m] = 0;
int rb2, rb, nb_rb;
int prbpos;
for (int symbol=0;symbol<14;symbol++) {
if (gNB->gNB_config.tdd_table.max_tdd_periodicity_list[slot_rx].max_num_of_symbol_per_slot_list[symbol].slot_config.value==1){
nb_rb = 0;
for (int m=0;m<9;m++) {
gNB->rb_mask_ul[m] = 0;
for (int i=0;i<32;i++) {
prbpos = (m*32)+i;
if (prbpos>gNB->frame_parms.N_RB_UL) break;
gNB->rb_mask_ul[m] |= (gNB->ulprbbl[prbpos]>0 ? 1 : 0)<<i;
}
}
gNB->ulmask_symb = -1;
for (int i=0;i<NUMBER_OF_NR_PUCCH_MAX;i++){
NR_gNB_PUCCH_t *pucch = gNB->pucch[i];
......@@ -679,7 +682,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
LOG_D(PHY,"frame %d, slot %d: PUCCH signal energy %d\n",frame_rx,slot_rx,power_rxF);
nr_decode_pucch0(gNB,
frame_rx,
frame_rx,
slot_rx,
uci_pdu_format0,
pucch_pdu);
......
......@@ -36,7 +36,7 @@
void fill_ul_rb_mask(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx);
void nr_set_ssb_first_subcarrier(nfapi_nr_config_request_scf_t *cfg, NR_DL_FRAME_PARMS *fp);
void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, int frame_tx, int slot_tx, int do_meas);
void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx, int frame_tx, int slot_tx, int do_meas);
void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx);
int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx);
void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot);
......
......@@ -426,7 +426,9 @@ int main(int argc, char **argv)
UE->dlsch_SI[0] = new_nr_ue_dlsch(1, 1, Nsoft, 5, N_RB_DL, 0);
UE->dlsch_ra[0] = new_nr_ue_dlsch(1, 1, Nsoft, 5, N_RB_DL, 0);
unsigned char harq_pid = 0; //dlsch->harq_ids[subframe];
NR_gNB_DLSCH_t *dlsch = gNB->dlsch[0][0];
processingData_L1tx_t msgDataTx;
init_DLSCH_struct(gNB, &msgDataTx);
NR_gNB_DLSCH_t *dlsch = msgDataTx.dlsch[0][0];
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &dlsch->harq_process.pdsch_pdu.pdsch_pdu_rel15;
//time_stats_t *rm_stats, *te_stats, *i_stats;
uint8_t is_crnti = 0, llr8_flag = 0;
......@@ -634,7 +636,7 @@ int main(int argc, char **argv)
for (i = 0; i < 2; i++) {
printf("gNB %d\n", i);
free_gNB_dlsch(&(gNB->dlsch[0][i]),N_RB_DL);
free_gNB_dlsch(&(msgDataTx.dlsch[0][i]),N_RB_DL);
printf("UE %d\n", i);
free_nr_ue_dlsch(&(UE->dlsch[0][0][i]),N_RB_DL);
}
......
......@@ -933,8 +933,6 @@ int main(int argc, char **argv)
// generate signal
AssertFatal(input_fd==NULL,"Not ready for input signal file\n");
gNB->pbch_configured = 1;
gNB->ssb[0].ssb_pdu.ssb_pdu_rel15.bchPayload=0x001234;
gNB->ssb[0].ssb_pdu.ssb_pdu_rel15.SsbBlockIndex = 0;
//Configure UE
rrc.carrier.MIB = (uint8_t*) malloc(4);
......@@ -964,11 +962,25 @@ int main(int argc, char **argv)
//NR_COMMON_channels_t *cc = RC.nrmac[0]->common_channels;
snrRun = 0;
gNB->threadPool = (tpool_t*)malloc(sizeof(tpool_t));
char tp_param[] = "n";
initTpool(tp_param, gNB->threadPool, true);
gNB->resp_L1_tx = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
initNotifiedFIFO(gNB->resp_L1_tx);
// we create 2 threads for L1 tx processing
notifiedFIFO_elt_t *msgL1Tx = newNotifiedFIFO_elt(sizeof(processingData_L1tx_t),0,gNB->resp_L1_tx,processSlotTX);
processingData_L1tx_t *msgDataTx = (processingData_L1tx_t *)NotifiedFifoData(msgL1Tx);
init_DLSCH_struct(gNB, msgDataTx);
msgDataTx->slot = slot;
msgDataTx->frame = frame;
memset(msgDataTx->ssb, 0, 64*sizeof(NR_gNB_SSB_t));
reset_meas(&msgDataTx->phy_proc_tx);
gNB->phy_proc_tx_0 = &msgDataTx->phy_proc_tx;
pushTpool(gNB->threadPool,msgL1Tx);
for (SNR = snr0; SNR < snr1; SNR += .2) {
varArray_t *table_tx=initVarArray(1000,sizeof(double));
reset_meas(&gNB->phy_proc_tx); // total gNB tx
reset_meas(&gNB->dlsch_scrambling_stats);
reset_meas(&gNB->dlsch_interleaving_stats);
reset_meas(&gNB->dlsch_rate_matching_stats);
......@@ -1009,7 +1021,7 @@ int main(int argc, char **argv)
int harq_pid = slot;
NR_DL_UE_HARQ_t *UE_harq_process = dlsch0->harq_processes[harq_pid];
NR_gNB_DLSCH_t *gNB_dlsch = gNB->dlsch[0][0];
NR_gNB_DLSCH_t *gNB_dlsch = msgDataTx->dlsch[0][0];
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &gNB_dlsch->harq_process.pdsch_pdu.pdsch_pdu_rel15;
UE_harq_process->ack = 0;
......@@ -1060,10 +1072,14 @@ int main(int argc, char **argv)
ptrsRePerSymb = ((rel15->rbSize + rel15->PTRSFreqDensity - 1)/rel15->PTRSFreqDensity);
printf("[DLSIM] PTRS Symbols in a slot: %2u, RE per Symbol: %3u, RE in a slot %4d\n", ptrsSymbPerSlot,ptrsRePerSymb, ptrsSymbPerSlot*ptrsRePerSymb );
}
msgDataTx->ssb[0].ssb_pdu.ssb_pdu_rel15.bchPayload=0x001234;
msgDataTx->ssb[0].ssb_pdu.ssb_pdu_rel15.SsbBlockIndex = 0;
msgDataTx->gNB = gNB;
if (run_initial_sync)
nr_common_signal_procedures(gNB,frame,slot,gNB->ssb[0].ssb_pdu);
nr_common_signal_procedures(gNB,frame,slot,msgDataTx->ssb[0].ssb_pdu);
else
phy_procedures_gNB_TX(gNB,frame,slot,1);
phy_procedures_gNB_TX(msgDataTx,frame,slot,1);
int txdataF_offset = (slot%2) * frame_parms->samples_per_slot_wCP;
......@@ -1272,10 +1288,10 @@ int main(int argc, char **argv)
if (print_perf==1) {
printf("\ngNB TX function statistics (per %d us slot, NPRB %d, mcs %d, TBS %d, Kr %d (Zc %d))\n",
1000>>*scc->ssbSubcarrierSpacing, g_rbSize, g_mcsIndex,
gNB->dlsch[0][0]->harq_process.pdsch_pdu.pdsch_pdu_rel15.TBSize[0]<<3,
gNB->dlsch[0][0]->harq_process.K,
gNB->dlsch[0][0]->harq_process.K/((gNB->dlsch[0][0]->harq_process.pdsch_pdu.pdsch_pdu_rel15.TBSize[0]<<3)>3824?22:10));
printDistribution(&gNB->phy_proc_tx,table_tx,"PHY proc tx");
msgDataTx->dlsch[0][0]->harq_process.pdsch_pdu.pdsch_pdu_rel15.TBSize[0]<<3,
msgDataTx->dlsch[0][0]->harq_process.K,
msgDataTx->dlsch[0][0]->harq_process.K/((msgDataTx->dlsch[0][0]->harq_process.pdsch_pdu.pdsch_pdu_rel15.TBSize[0]<<3)>3824?22:10));
printDistribution(gNB->phy_proc_tx_0,table_tx,"PHY proc tx");
printStatIndent2(&gNB->dlsch_encoding_stats,"DLSCH encoding time");
printStatIndent3(&gNB->dlsch_segmentation_stats,"DLSCH segmentation time");
printStatIndent3(&gNB->tinput,"DLSCH LDPC input processing time");
......
......@@ -565,14 +565,15 @@ int main(int argc, char **argv)
nr_gold_pbch(UE);
processingData_L1tx_t msgDataTx;
// generate signal
if (input_fd==NULL) {
for (i=0; i<frame_parms->Lmax; i++) {
if((SSB_positions >> i) & 0x01) {
gNB->ssb[i].ssb_pdu.ssb_pdu_rel15.bchPayload = 0x55dd33;
gNB->ssb[i].ssb_pdu.ssb_pdu_rel15.SsbBlockIndex = i;
msgDataTx.ssb[i].ssb_pdu.ssb_pdu_rel15.bchPayload = 0x55dd33;
msgDataTx.ssb[i].ssb_pdu.ssb_pdu_rel15.SsbBlockIndex = i;
start_symbol = nr_get_ssb_start_symbol(frame_parms,i);
int slot = start_symbol/14;
......@@ -580,7 +581,7 @@ int main(int argc, char **argv)
for (aa=0; aa<gNB->frame_parms.nb_antennas_tx; aa++)
memset(gNB->common_vars.txdataF[aa],0,frame_parms->samples_per_slot_wCP*sizeof(int32_t));
nr_common_signal_procedures (gNB,frame,slot,gNB->ssb[i].ssb_pdu);
nr_common_signal_procedures (gNB,frame,slot,msgDataTx.ssb[i].ssb_pdu);
for (aa=0; aa<gNB->frame_parms.nb_antennas_tx; aa++) {
if (cyclic_prefix_type == 1) {
......@@ -750,7 +751,7 @@ int main(int argc, char **argv)
payload_ret = (UE->pbch_vars[0]->xtra_byte == gNB_xtra_byte);
for (i=0;i<3;i++){
payload_ret += (UE->pbch_vars[0]->decoded_output[i] == ((gNB->ssb[ssb_index].ssb_pdu.ssb_pdu_rel15.bchPayload>>(8*i)) & 0xff));
payload_ret += (UE->pbch_vars[0]->decoded_output[i] == ((msgDataTx.ssb[ssb_index].ssb_pdu.ssb_pdu_rel15.bchPayload>>(8*i)) & 0xff));
}
//printf("xtra byte gNB: 0x%02x UE: 0x%02x\n",gNB_xtra_byte, UE->pbch_vars[0]->xtra_byte);
//printf("ret %d\n", payload_ret);
......
......@@ -665,6 +665,13 @@ int main(int argc, char **argv)
char tp_param[] = "n";
initTpool(tp_param, gNB->threadPool, false);
initNotifiedFIFO(gNB->respDecode);
gNB->resp_L1_tx = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
initNotifiedFIFO(gNB->resp_L1_tx);
notifiedFIFO_elt_t *msgL1Tx = newNotifiedFIFO_elt(sizeof(processingData_L1tx_t),0,gNB->resp_L1_tx,NULL);
processingData_L1tx_t *msgDataTx = (processingData_L1tx_t *)NotifiedFifoData(msgL1Tx);
msgDataTx->slot = -1;
gNB->phy_proc_tx_0 = &msgDataTx->phy_proc_tx;
pushNotifiedFIFO(gNB->resp_L1_tx,msgL1Tx); // to unblock the process in the beginning
//gNB_config = &gNB->gNB_config;
//memset((void *)&gNB->UL_INFO,0,sizeof(gNB->UL_INFO));
......
......@@ -549,6 +549,32 @@ void RCconfig_nr_flexran()
void RCconfig_NR_L1(void) {
int j;
paramdef_t GNBSParams[] = GNBSPARAMS_DESC;
////////// Identification parameters
paramdef_t GNBParams[] = GNBPARAMS_DESC;
paramlist_def_t GNBParamList = {GNB_CONFIG_STRING_GNB_LIST,NULL,0};
config_get( GNBSParams,sizeof(GNBSParams)/sizeof(paramdef_t),NULL);
int num_gnbs = GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt;
AssertFatal (num_gnbs > 0,"Failed to parse config file no gnbs %s \n",GNB_CONFIG_STRING_ACTIVE_GNBS);
config_getlist( &GNBParamList,GNBParams,sizeof(GNBParams)/sizeof(paramdef_t),NULL);
char *ulprbbl = *GNBParamList.paramarray[0][GNB_ULPRBBLACKLIST_IDX].strptr;
if (ulprbbl) LOG_I(NR_PHY,"PRB blacklist %s\n",ulprbbl);
char *pt = strtok(ulprbbl,",");
int prbbl[275];
int num_prbbl=0;
memset(prbbl,0,275*sizeof(int));
while (pt) {
prbbl[atoi(pt)] = 1;
LOG_I(NR_PHY,"Blacklisting prb %d\n",atoi(pt));
pt = strtok(NULL,",");
num_prbbl++;
}
paramdef_t L1_Params[] = L1PARAMS_DESC;
paramlist_def_t L1_ParamList = {CONFIG_STRING_L1_LIST,NULL,0};
......@@ -577,6 +603,9 @@ void RCconfig_NR_L1(void) {
RC.gNB[j]->pucch0_thres = *(L1_ParamList.paramarray[j][L1_PUCCH0_DTX_THRESHOLD].uptr);
RC.gNB[j]->prach_thres = *(L1_ParamList.paramarray[j][L1_PRACH_DTX_THRESHOLD].uptr);
RC.gNB[j]->pusch_thres = *(L1_ParamList.paramarray[j][L1_PUSCH_DTX_THRESHOLD].uptr);
RC.gNB[j]->num_ulprbbl = num_prbbl;
LOG_I(NR_PHY,"Copying %d blacklisted PRB to L1 context\n",num_prbbl);
memcpy(RC.gNB[j]->ulprbbl,prbbl,275*sizeof(int));
if(strcmp(*(L1_ParamList.paramarray[j][L1_TRANSPORT_N_PREFERENCE_IDX].strptr), "local_mac") == 0) {
//sf_ahead = 2; // Need 4 subframe gap between RX and TX
}else if (strcmp(*(L1_ParamList.paramarray[j][L1_TRANSPORT_N_PREFERENCE_IDX].strptr), "nfapi") == 0) {
......@@ -633,6 +662,30 @@ void RCconfig_NR_L1(void) {
void RCconfig_nr_macrlc() {
int j;
paramdef_t GNBSParams[] = GNBSPARAMS_DESC;
////////// Identification parameters
paramdef_t GNBParams[] = GNBPARAMS_DESC;
paramlist_def_t GNBParamList = {GNB_CONFIG_STRING_GNB_LIST,NULL,0};
config_get( GNBSParams,sizeof(GNBSParams)/sizeof(paramdef_t),NULL);
int num_gnbs = GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt;
AssertFatal (num_gnbs > 0,"Failed to parse config file no gnbs %s \n",GNB_CONFIG_STRING_ACTIVE_GNBS);
config_getlist( &GNBParamList,GNBParams,sizeof(GNBParams)/sizeof(paramdef_t),NULL);
char *ulprbbl = *GNBParamList.paramarray[0][GNB_ULPRBBLACKLIST_IDX].strptr;
char *pt = strtok(ulprbbl,",");
int prbbl[275];
int num_prbbl=0;
int prb;
memset(prbbl,0,275*sizeof(int));
while (pt) {
prb=atoi(pt);
prbbl[prb] = 1;
pt = strtok(NULL,",");
num_prbbl++;
}
paramdef_t MacRLC_Params[] = MACRLCPARAMS_DESC;
paramlist_def_t MacRLC_ParamList = {CONFIG_STRING_MACRLC_LIST,NULL,0};
......@@ -702,6 +755,10 @@ void RCconfig_nr_macrlc() {
AssertFatal(1==0,"MACRLC %d: %s unknown southbound midhaul\n",j,*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_PREFERENCE_IDX].strptr));
}
RC.nrmac[j]->ulsch_max_slots_inactivity = *(MacRLC_ParamList.paramarray[j][MACRLC_ULSCH_MAX_SLOTS_INACTIVITY].uptr);
RC.nrmac[j]->num_ulprbbl = num_prbbl;
LOG_I(NR_MAC,"Blacklisted PRBS %d\n",num_prbbl);
memcpy(RC.nrmac[j]->ulprbbl,prbbl,275*sizeof(prbbl[0]));
}// for (j=0;j<RC.nb_nr_macrlc_inst;j++)
}else {// MacRLC_ParamList.numelt > 0
LOG_E(PHY,"No %s configuration found\n", CONFIG_STRING_MACRLC_LIST);
......
......@@ -120,6 +120,8 @@ typedef enum {
#define GNB_CONFIG_STRING_DOCSIRS "do_CSIRS"
#define GNB_CONFIG_STRING_NRCELLID "nr_cellid"
#define GNB_CONFIG_STRING_MINRXTXTIMEPDSCH "min_rxtxtime_pdsch"
#define GNB_CONFIG_STRING_ULPRBBLACKLIST "ul_prbblacklist"
/*-----------------------------------------------------------------------------------------------------------------------------------------*/
/* cell configuration parameters */
......@@ -147,7 +149,8 @@ typedef enum {
{GNB_CONFIG_STRING_DOCSIRS, NULL, 0, iptr:NULL, defintval:0, TYPE_INT, 0}, \
{GNB_CONFIG_STRING_NRCELLID, NULL, 0, u64ptr:NULL, defint64val:1, TYPE_UINT64, 0}, \
{GNB_CONFIG_STRING_MINRXTXTIMEPDSCH, NULL, 0, iptr:NULL, defintval:2, TYPE_INT, 0} \
}
{GNB_CONFIG_STRING_ULPRBBLACKLIST, NULL, 0, strptr:NULL, defstrval:"", TYPE_STRING, 0} \
}
#define GNB_GNB_ID_IDX 0
#define GNB_CELL_TYPE_IDX 1
......@@ -170,6 +173,7 @@ typedef enum {
#define GNB_DO_CSIRS_IDX 18
#define GNB_NRCELLID_IDX 19
#define GNB_MINRXTXTIMEPDSCH_IDX 20
#define GNB_ULPRBBLACKLIST_IDX 21
#define TRACKING_AREA_CODE_OKRANGE {0x0001,0xFFFD}
#define GNBPARAMS_CHECK { \
......
......@@ -864,7 +864,7 @@ void nr_get_Msg3alloc(module_id_t module_id,
// msg3 is scheduled in mixed slot in the following TDD period
uint16_t msg3_nb_rb = 8 + sizeof(NR_MAC_SUBHEADER_SHORT) + sizeof(NR_MAC_SUBHEADER_SHORT); // sdu has 6 or 8 bytes
uint16_t msg3_nb_rb = 8; // sdu has 6 or 8 bytes
int mu = ubwp ?
ubwp->bwp_Common->genericParameters.subcarrierSpacing :
......
......@@ -1329,6 +1329,9 @@ bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
const uint16_t symb = ((1 << nrOfSymbols) - 1) << startSymbolIndex;
int st = 0, e = 0, len = 0;
for (int i = 0; i < bwpSize; i++)
if (RC.nrmac[module_id]->ulprbbl[i] == 1) vrb_map_UL[i]=symb;
for (int i = 0; i < bwpSize; i++) {
while ((vrb_map_UL[i] & symb) != 0 && i < bwpSize)
i++;
......@@ -1342,6 +1345,8 @@ bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
}
st = e - len + 1;
LOG_D(NR_MAC,"UL %d.%d : start_prb %d, end PRB %d\n",frame,slot,st,e);
uint8_t rballoc_mask[bwpSize];
/* Calculate mask: if any RB in vrb_map_UL is blocked (1), the current RB will be 0 */
......
......@@ -681,7 +681,8 @@ typedef struct gNB_MAC_INST_s {
NR_COMMON_channels_t common_channels[NFAPI_CC_MAX];
/// current PDU index (BCH,DLSCH)
uint16_t pdu_index[NFAPI_CC_MAX];
int num_ulprbbl;
int ulprbbl[275];
/// NFAPI Config Request Structure
nfapi_nr_config_request_scf_t config[NFAPI_CC_MAX];
/// NFAPI DL Config Request Structure
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment