merge develop

This commit is contained in:
mjoang
2021-09-23 10:44:43 -04:00
198 changed files with 31431 additions and 13295 deletions
+20
View File
@@ -198,6 +198,26 @@ pipeline {
}
}
}
stage ("RF Simulators") {
when { expression {doMandatoryTests} }
steps {
script {
triggerSlaveJob ('RAN-RF-Sim-Test', 'Test-RF-Sim-Container')
}
}
post {
always {
script {
finalizeSlaveJob('RAN-RF-Sim-Test')
}
}
failure {
script {
currentBuild.result = 'FAILURE'
}
}
}
}
}
}
}
+1 -1
View File
@@ -369,7 +369,7 @@ pipeline {
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password']
]) {
echo '\u2705 \u001B[32mLog Collection (eNB - Run)\u001B[0m'
sh "python3 ci-scripts/main.py --mode=LogCollecteNB --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath}"
sh "python3 ci-scripts/main.py --mode=LogCollecteNB --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath} --BuildId=${env.BUILD_ID}"
echo '\u2705 \u001B[32mLog Transfer (eNB - Run)\u001B[0m'
sh "sshpass -p \'${eNB_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${eNB_Username}@${params.eNB_IPAddress}:${eNB_SourceCodePath}/cmake_targets/enb.log.zip ./enb.log.${env.BUILD_ID}.zip || true"
+3
View File
@@ -266,6 +266,9 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,EPC,ldpc,CONTAINERS,HELP,SCA,PHYSIM):
elif re.match('^\-\-OCProjectName=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-OCProjectName=(.+)$', myArgv, re.IGNORECASE)
PHYSIM.OCProjectName = matchReg.group(1)
elif re.match('^\-\-BuildId=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-BuildId=(.+)$', myArgv, re.IGNORECASE)
RAN.BuildId = matchReg.group(1)
else:
HELP.GenericHelp(CONST.Version)
sys.exit('Invalid Parameter: ' + myArgv)
+303 -1
View File
@@ -36,6 +36,7 @@ import re # reg
import logging
import os
import shutil
import subprocess
import time
from multiprocessing import Process, Lock, SimpleQueue
from zipfile import ZipFile
@@ -76,6 +77,9 @@ class Containerize():
self.eNB_instance = 0
self.eNB_serverId = ['', '', '']
self.yamlPath = ['', '', '']
self.services = ['', '', '']
self.nb_healthy = [0, 0, 0]
self.exitStatus = 0
self.eNB_logFile = ['', '', '']
self.testCase_id = ''
@@ -89,6 +93,14 @@ class Containerize():
self.allImagesSize = {}
self.collectInfo = {}
self.pingContName = ''
self.pingOptions = ''
self.pingLossThreshold = ''
self.svrContName = ''
self.svrOptions = ''
self.cliContName = ''
self.cliOptions = ''
#-----------------------------------------------------------
# Container management functions
#-----------------------------------------------------------
@@ -476,7 +488,6 @@ class Containerize():
HTML.CreateHtmlTestRow('N/A', 'KO', CONST.ALL_PROCESSES_OK)
def UndeployObject(self, HTML, RAN):
logging.info('\u001B[1m Undeploying OAI Object Pass\u001B[0m')
if self.eNB_serverId[self.eNB_instance] == '0':
lIpAddr = self.eNBIPAddress
lUserName = self.eNBUserName
@@ -529,4 +540,295 @@ class Containerize():
HTML.CreateHtmlTestRow(RAN.runtime_stats, 'KO', logStatus)
else:
HTML.CreateHtmlTestRow(RAN.runtime_stats, 'OK', CONST.ALL_PROCESSES_OK)
logging.info('\u001B[1m Undeploying OAI Object Pass\u001B[0m')
def DeployGenObject(self, HTML):
self.exitStatus = 0
logging.info('\u001B[1m Checking Services to deploy\u001B[0m')
cmd = 'cd ' + self.yamlPath[0] + ' && docker-compose config --services'
logging.debug(cmd)
try:
listServices = subprocess.check_output(cmd, shell=True, universal_newlines=True)
except Exception as e:
self.exitStatus = 1
HTML.CreateHtmlTestRow('SVC not Found', 'KO', CONST.ALL_PROCESSES_OK)
return
for reqSvc in self.services[0].split(' '):
res = re.search(reqSvc, listServices)
if res is None:
logging.error(reqSvc + ' not found in specified docker-compose')
self.exitStatus = 1
if (self.exitStatus == 1):
HTML.CreateHtmlTestRow('SVC not Found', 'KO', CONST.ALL_PROCESSES_OK)
return
if (self.ranAllowMerge):
cmd = 'cd ' + self.yamlPath[0] + ' && sed -e "s@develop@ci-temp@" docker-compose.y*ml > docker-compose-ci.yml'
else:
cmd = 'cd ' + self.yamlPath[0] + ' && sed -e "s@develop@develop@" docker-compose.y*ml > docker-compose-ci.yml'
logging.debug(cmd)
subprocess.run(cmd, shell=True)
cmd = 'cd ' + self.yamlPath[0] + ' && docker-compose -f docker-compose-ci.yml up -d ' + self.services[0]
logging.debug(cmd)
try:
deployStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=30)
except Exception as e:
self.exitStatus = 1
logging.error('Could not deploy')
HTML.CreateHtmlTestRow('Could not deploy', 'KO', CONST.ALL_PROCESSES_OK)
return
logging.info('\u001B[1m Checking if all deployed healthy\u001B[0m')
cmd = 'cd ' + self.yamlPath[0] + ' && docker-compose -f docker-compose-ci.yml ps -a'
count = 0
healthy = 0
while (count < 10):
count += 1
deployStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=10)
healthy = 0
for state in deployStatus.split('\n'):
res = re.search('Up \(healthy\)', state)
if res is not None:
healthy += 1
if healthy == self.nb_healthy[0]:
count = 100
else:
time.sleep(10)
if count == 100 and healthy == self.nb_healthy[0]:
HTML.CreateHtmlTestRow('n/a', 'OK', CONST.ALL_PROCESSES_OK)
logging.info('\u001B[1m Deploying OAI Object(s) PASS\u001B[0m')
else:
self.exitStatus = 1
HTML.CreateHtmlTestRow('Could not deploy in time', 'KO', CONST.ALL_PROCESSES_OK)
logging.error('\u001B[1m Deploying OAI Object(s) FAILED\u001B[0m')
def UndeployGenObject(self, HTML):
self.exitStatus = 0
if (self.ranAllowMerge):
cmd = 'cd ' + self.yamlPath[0] + ' && sed -e "s@develop@ci-temp@" docker-compose.y*ml > docker-compose-ci.yml'
else:
cmd = 'cd ' + self.yamlPath[0] + ' && sed -e "s@develop@develop@" docker-compose.y*ml > docker-compose-ci.yml'
logging.debug(cmd)
subprocess.run(cmd, shell=True)
# if the containers are running, recover the logs!
cmd = 'cd ' + self.yamlPath[0] + ' && docker-compose -f docker-compose-ci.yml ps --all'
logging.debug(cmd)
deployStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=10)
anyLogs = False
for state in deployStatus.split('\n'):
res = re.search('Name|----------', state)
if res is not None:
continue
if len(state) == 0:
continue
res = re.search('^(?P<container_name>[a-zA-Z0-9\-\_]+) ', state)
if res is not None:
anyLogs = True
cName = res.group('container_name')
cmd = 'cd ' + self.yamlPath[0] + ' && docker logs ' + cName + ' > ' + cName + '.log 2>&1'
logging.debug(cmd)
deployStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=10)
if anyLogs:
cmd = 'mkdir -p ../cmake_targets/log && mv ' + self.yamlPath[0] + '/*.log ../cmake_targets/log'
logging.debug(cmd)
deployStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=10)
cmd = 'cd ' + self.yamlPath[0] + ' && docker-compose -f docker-compose-ci.yml down'
logging.debug(cmd)
try:
deployStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=100)
except Exception as e:
self.exitStatus = 1
logging.error('Could not undeploy')
HTML.CreateHtmlTestRow('Could not undeploy', 'KO', CONST.ALL_PROCESSES_OK)
logging.error('\u001B[1m Undeploying OAI Object(s) FAILED\u001B[0m')
return
HTML.CreateHtmlTestRow('n/a', 'OK', CONST.ALL_PROCESSES_OK)
logging.info('\u001B[1m Undeploying OAI Object(s) PASS\u001B[0m')
def PingFromContainer(self, HTML):
self.exitStatus = 0
cmd = 'mkdir -p ../cmake_targets/log'
deployStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=10)
cmd = 'docker exec ' + self.pingContName + ' /bin/bash -c "ping ' + self.pingOptions + '" 2>&1 | tee ../cmake_targets/log/ping_' + HTML.testCase_id + '.log'
logging.debug(cmd)
deployStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=100)
result = re.search(', (?P<packetloss>[0-9\.]+)% packet loss, time [0-9\.]+ms', deployStatus)
if result is None:
self.PingExit(HTML, False, 'Packet Loss Not Found')
return
packetloss = result.group('packetloss')
if float(packetloss) == 100:
self.PingExit(HTML, False, 'Packet Loss is 100%')
return
result = re.search('rtt min\/avg\/max\/mdev = (?P<rtt_min>[0-9\.]+)\/(?P<rtt_avg>[0-9\.]+)\/(?P<rtt_max>[0-9\.]+)\/[0-9\.]+ ms', deployStatus)
if result is None:
self.PingExit(HTML, False, 'Ping RTT_Min RTT_Avg RTT_Max Not Found!')
return
rtt_min = result.group('rtt_min')
rtt_avg = result.group('rtt_avg')
rtt_max = result.group('rtt_max')
pal_msg = 'Packet Loss : ' + packetloss + '%'
min_msg = 'RTT(Min) : ' + rtt_min + ' ms'
avg_msg = 'RTT(Avg) : ' + rtt_avg + ' ms'
max_msg = 'RTT(Max) : ' + rtt_max + ' ms'
message = 'ping result\n'
message += ' ' + pal_msg + '\n'
message += ' ' + min_msg + '\n'
message += ' ' + avg_msg + '\n'
message += ' ' + max_msg + '\n'
packetLossOK = True
if float(packetloss) > float(self.pingLossThreshold):
message += '\nPacket Loss too high'
packetLossOK = False
elif float(packetloss) > 0:
message += '\nPacket Loss is not 0%'
self.PingExit(HTML, packetLossOK, message)
if packetLossOK:
logging.debug('\u001B[1;37;44m ping result \u001B[0m')
logging.debug('\u001B[1;34m ' + pal_msg + '\u001B[0m')
logging.debug('\u001B[1;34m ' + min_msg + '\u001B[0m')
logging.debug('\u001B[1;34m ' + avg_msg + '\u001B[0m')
logging.debug('\u001B[1;34m ' + max_msg + '\u001B[0m')
logging.info('\u001B[1m Ping Test PASS\u001B[0m')
def PingExit(self, HTML, status, message):
html_queue = SimpleQueue()
html_cell = '<pre style="background-color:white">UE\n' + message + '</pre>'
html_queue.put(html_cell)
if status:
HTML.CreateHtmlTestRowQueue(self.pingOptions, 'OK', 1, html_queue)
else:
self.exitStatus = 1
logging.error('\u001B[1;37;41m ' + message + ' \u001B[0m')
HTML.CreateHtmlTestRowQueue(self.pingOptions, 'KO', 1, html_queue)
def IperfFromContainer(self, HTML):
self.exitStatus = 0
cmd = 'mkdir -p ../cmake_targets/log'
logStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=10)
# Start the server process
cmd = 'docker exec -d ' + self.svrContName + ' /bin/bash -c "nohup iperf ' + self.svrOptions + ' > /tmp/iperf_server.log 2>&1"'
logging.debug(cmd)
serverStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=10)
time.sleep(5)
# Start the client process
cmd = 'docker exec ' + self.cliContName + ' /bin/bash -c "iperf ' + self.cliOptions + '" 2>&1 | tee ../cmake_targets/log/iperf_client_' + HTML.testCase_id + '.log'
logging.debug(cmd)
clientStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=100)
# Stop the server process
cmd = 'docker exec ' + self.svrContName + ' /bin/bash -c "pkill iperf"'
logging.debug(cmd)
serverStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=10)
time.sleep(5)
cmd = 'docker cp ' + self.svrContName + ':/tmp/iperf_server.log ../cmake_targets/log/iperf_server_' + HTML.testCase_id + '.log'
logging.debug(cmd)
serverStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=10)
# Analyze client output
result = re.search('Server Report:', clientStatus)
if result is None:
result = re.search('read failed: Connection refused', clientStatus)
if result is not None:
message = 'Could not connect to iperf server!'
else:
message = 'Server Report and Connection refused Not Found!'
self.IperfExit(HTML, False, message)
return
# Computing the requested bandwidth in float
result = re.search('-b (?P<iperf_bandwidth>[0-9\.]+)[KMG]', self.cliOptions)
if result is not None:
req_bandwidth = result.group('iperf_bandwidth')
req_bw = float(req_bandwidth)
result = re.search('-b [0-9\.]+K', self.cliOptions)
if result is not None:
req_bandwidth = '%.1f Kbits/sec' % req_bw
req_bw = req_bw * 1000
result = re.search('-b [0-9\.]+M', self.cliOptions)
if result is not None:
req_bandwidth = '%.1f Mbits/sec' % req_bw
req_bw = req_bw * 1000000
reportLine = None
reportLineFound = False
for iLine in clientStatus.split('\n'):
if reportLineFound:
reportLine = iLine
reportLineFound = False
res = re.search('Server Report:', iLine)
if res is not None:
reportLineFound = True
result = None
if reportLine is not None:
result = re.search('(?:|\[ *\d+\].*) (?P<bitrate>[0-9\.]+ [KMG]bits\/sec) +(?P<jitter>[0-9\.]+ ms) +(\d+\/ ..\d+) +(\((?P<packetloss>[0-9\.]+)%\))', reportLine)
iperfStatus = True
if result is not None:
bitrate = result.group('bitrate')
packetloss = result.group('packetloss')
jitter = result.group('jitter')
logging.debug('\u001B[1;37;44m iperf result \u001B[0m')
iperfStatus = True
msg = 'Req Bitrate : ' + req_bandwidth + '\n'
logging.debug('\u001B[1;34m Req Bitrate : ' + req_bandwidth + '\u001B[0m')
if bitrate is not None:
msg += 'Bitrate : ' + bitrate + '\n'
logging.debug('\u001B[1;34m Bitrate : ' + bitrate + '\u001B[0m')
result = re.search('(?P<real_bw>[0-9\.]+) [KMG]bits/sec', str(bitrate))
if result is not None:
actual_bw = float(str(result.group('real_bw')))
result = re.search('[0-9\.]+ K', bitrate)
if result is not None:
actual_bw = actual_bw * 1000
result = re.search('[0-9\.]+ M', bitrate)
if result is not None:
actual_bw = actual_bw * 1000000
br_loss = 100 * actual_bw / req_bw
if br_loss < 90:
iperfStatus = False
bitperf = '%.2f ' % br_loss
msg += 'Bitrate Perf: ' + bitperf + '%\n'
logging.debug('\u001B[1;34m Bitrate Perf: ' + bitperf + '%\u001B[0m')
if packetloss is not None:
msg += 'Packet Loss : ' + packetloss + '%\n'
logging.debug('\u001B[1;34m Packet Loss : ' + packetloss + '%\u001B[0m')
if float(packetloss) > float(5):
msg += 'Packet Loss too high!\n'
logging.debug('\u001B[1;37;41m Packet Loss too high \u001B[0m')
iperfStatus = False
if jitter is not None:
msg += 'Jitter : ' + jitter + '\n'
logging.debug('\u001B[1;34m Jitter : ' + jitter + '\u001B[0m')
self.IperfExit(HTML, iperfStatus, msg)
else:
iperfStatus = False
logging.error('problem?')
self.IperfExit(HTML, iperfStatus, 'problem?')
if iperfStatus:
logging.info('\u001B[1m Iperf Test PASS\u001B[0m')
def IperfExit(self, HTML, status, message):
html_queue = SimpleQueue()
html_cell = '<pre style="background-color:white">UE\n' + message + '</pre>'
html_queue.put(html_cell)
if status:
HTML.CreateHtmlTestRowQueue(self.cliOptions, 'OK', 1, html_queue)
else:
self.exitStatus = 1
HTML.CreateHtmlTestRowQueue(self.cliOptions, 'KO', 1, html_queue)
+9 -5
View File
@@ -2005,6 +2005,7 @@ class OaiCiTest():
curr_br = curr_br * 1000 * 1000
br_sum = curr_br + br_sum
ji_sum = float(ji[0]) + ji_sum
if (row_idx > 0):
br_sum = br_sum / row_idx
ji_sum = ji_sum / row_idx
@@ -2025,10 +2026,12 @@ class OaiCiTest():
pl = float(100 * pl_sum / ps_sum)
packetloss = '%2.1f ' % (pl)
packetloss += '%'
else:
packetloss = 'unknown'
if float(pl) > float(self.iperf_packetloss_threshold):
pal_too_high_msg = 'Packet Loss too high : actual = '+packetloss+', target = '+self.iperf_packetloss_threshold+'%\n'
else:
pal_too_high_msg=''
lock.acquire()
if (br_loss < 90):
if (br_loss < 90) or (float(pl) > float(self.iperf_packetloss_threshold)):
statusQueue.put(1)
else:
statusQueue.put(0)
@@ -2039,13 +2042,14 @@ class OaiCiTest():
brl_msg = 'Bitrate Perf: ' + bitperf
jit_msg = 'Jitter : ' + jitter
pal_msg = 'Packet Loss : ' + packetloss
statusQueue.put(req_msg + '\n' + bir_msg + '\n' + brl_msg + '\n' + jit_msg + '\n' + pal_msg + '\n')
statusQueue.put(req_msg + '\n' + bir_msg + '\n' + brl_msg + '\n' + jit_msg + '\n' + pal_msg + '\n' + pal_too_high_msg + '\n')
logging.debug('\u001B[1;37;45m iperf result (' + UE_IPAddress + ') \u001B[0m')
logging.debug('\u001B[1;35m ' + req_msg + '\u001B[0m')
logging.debug('\u001B[1;35m ' + bir_msg + '\u001B[0m')
logging.debug('\u001B[1;35m ' + brl_msg + '\u001B[0m')
logging.debug('\u001B[1;35m ' + jit_msg + '\u001B[0m')
logging.debug('\u001B[1;35m ' + pal_msg + '\u001B[0m')
logging.debug('\u001B[1;35m ' + pal_too_high_msg + '\u001B[0m')
lock.release()
else:
self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, 'Could not analyze from server log')
@@ -2705,7 +2709,7 @@ class OaiCiTest():
if (status_queue.empty()):
HTML.CreateHtmlTestRow(self.iperf_args, 'KO', CONST.ALL_PROCESSES_OK)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfaUE)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
else:
iperf_status = True
iperf_noperf = False
@@ -235,9 +235,10 @@ MACRLCs = (
L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
pusch_proc_threads = 8;
num_cc = 1;
tr_n_preference = "local_mac";
pusch_proc_threads = 8;
ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0
}
);
@@ -219,6 +219,7 @@ L1s = (
num_cc = 1;
tr_n_preference = "local_mac";
pusch_proc_threads = 8;
ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0
}
);
@@ -231,10 +231,11 @@ MACRLCs = (
L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
num_cc = 1;
tr_n_preference = "local_mac";
pusch_proc_threads = 6;
}
ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0
}
);
RUs = (
+63 -2
View File
@@ -65,6 +65,7 @@ import xml.etree.ElementTree as ET
import logging
import datetime
import signal
import subprocess
from multiprocessing import Process, Lock, SimpleQueue
logging.basicConfig(
level=logging.DEBUG,
@@ -372,6 +373,41 @@ def GetParametersFromXML(action):
if (string_field is not None):
CONTAINERS.yamlPath[CONTAINERS.eNB_instance] = string_field
elif action == 'DeployGenObject' or action == 'UndeployGenObject':
string_field=test.findtext('yaml_path')
if (string_field is not None):
CONTAINERS.yamlPath[0] = string_field
string_field=test.findtext('services')
if (string_field is not None):
CONTAINERS.services[0] = string_field
string_field=test.findtext('nb_healthy')
if (string_field is not None):
CONTAINERS.nb_healthy[0] = int(string_field)
elif action == 'PingFromContainer':
string_field = test.findtext('container_name')
if (string_field is not None):
CONTAINERS.pingContName = string_field
string_field = test.findtext('options')
if (string_field is not None):
CONTAINERS.pingOptions = string_field
string_field = test.findtext('loss_threshold')
if (string_field is not None):
CONTAINERS.pingLossThreshold = string_field
elif action == 'IperfFromContainer':
string_field = test.findtext('server_container_name')
if (string_field is not None):
CONTAINERS.svrContName = string_field
string_field = test.findtext('server_options')
if (string_field is not None):
CONTAINERS.svrOptions = string_field
string_field = test.findtext('client_container_name')
if (string_field is not None):
CONTAINERS.cliContName = string_field
string_field = test.findtext('client_options')
if (string_field is not None):
CONTAINERS.cliOptions = string_field
else: # ie action == 'Run_PhySim':
ldpc.runargs = test.findtext('physim_run_args')
@@ -479,6 +515,8 @@ if re.match('^TerminateeNB$', mode, re.IGNORECASE):
if RAN.eNBIPAddress == '' or RAN.eNBUserName == '' or RAN.eNBPassword == '':
HELP.GenericHelp(CONST.Version)
sys.exit('Insufficient Parameter')
if RAN.eNBIPAddress == 'none':
sys.exit(0)
RAN.eNB_instance=0
RAN.eNB_serverId[0]='0'
RAN.eNBSourceCodePath='/tmp/'
@@ -514,11 +552,18 @@ elif re.match('^LogCollectBuild$', mode, re.IGNORECASE):
if (RAN.eNBIPAddress == '' or RAN.eNBUserName == '' or RAN.eNBPassword == '' or RAN.eNBSourceCodePath == '') and (CiTestObj.UEIPAddress == '' or CiTestObj.UEUserName == '' or CiTestObj.UEPassword == '' or CiTestObj.UESourceCodePath == ''):
HELP.GenericHelp(CONST.Version)
sys.exit('Insufficient Parameter')
if RAN.eNBIPAddress == 'none':
sys.exit(0)
CiTestObj.LogCollectBuild(RAN)
elif re.match('^LogCollecteNB$', mode, re.IGNORECASE):
if RAN.eNBIPAddress == '' or RAN.eNBUserName == '' or RAN.eNBPassword == '' or RAN.eNBSourceCodePath == '':
HELP.GenericHelp(CONST.Version)
sys.exit('Insufficient Parameter')
if RAN.eNBIPAddress == 'none':
cmd = 'zip -r enb.log.' + RAN.BuildId + '.zip cmake_targets/log'
logging.debug(cmd)
zipStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=60)
sys.exit(0)
RAN.LogCollecteNB()
elif re.match('^LogCollectHSS$', mode, re.IGNORECASE):
if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.Type == '' or EPC.SourceCodePath == '':
@@ -802,7 +847,7 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re
elif action == 'Build_PhySim':
HTML=ldpc.Build_PhySim(HTML,CONST)
if ldpc.exitStatus==1:
RAN.prematureExit = False
RAN.prematureExit = True
elif action == 'Run_PhySim':
HTML=ldpc.Run_PhySim(HTML,CONST,id)
elif action == 'Build_Image':
@@ -815,9 +860,25 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re
SCA.CppCheckAnalysis(HTML)
elif action == 'Deploy_Run_PhySim':
PHYSIM.Deploy_PhySim(HTML, RAN)
elif action == 'DeployGenObject':
CONTAINERS.DeployGenObject(HTML)
if CONTAINERS.exitStatus==1:
RAN.prematureExit = True
elif action == 'UndeployGenObject':
CONTAINERS.UndeployGenObject(HTML)
if CONTAINERS.exitStatus==1:
RAN.prematureExit = True
elif action == 'PingFromContainer':
CONTAINERS.PingFromContainer(HTML)
if CONTAINERS.exitStatus==1:
RAN.prematureExit = True
elif action == 'IperfFromContainer':
CONTAINERS.IperfFromContainer(HTML)
if CONTAINERS.exitStatus==1:
RAN.prematureExit = True
else:
sys.exit('Invalid class (action) from xml')
if not RAN.prematureExit:
if RAN.prematureExit:
if CiTestObj.testCase_id == CiTestObj.testMinStableId:
logging.debug('Scenario has reached minimal stability point')
CiTestObj.testStabilityPointReached = True
+4
View File
@@ -41,3 +41,7 @@
- Undeploy_Object
- Cppcheck_Analysis
- Deploy_Run_PhySim
- DeployGenObject
- UndeployGenObject
- PingFromContainer
- IperfFromContainer
+129
View File
@@ -0,0 +1,129 @@
<!--
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>rfsim-4glte</htmlTabRef>
<htmlTabName>Testing 4G LTE RF sim in containers</htmlTabName>
<htmlTabIcon>wrench</htmlTabIcon>
<TestCaseRequestedList>
100011
000011
000001
000012
000002
000013
000001
000014
000002
020011
020012
030011
030012
100011
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="000011">
<class>DeployGenObject</class>
<desc>Deploy Cassandra Database</desc>
<yaml_path>yaml_files/4g_rfsimulator</yaml_path>
<services>cassandra db_init</services>
<nb_healthy>1</nb_healthy>
</testCase>
<testCase id="000001">
<class>IdleSleep</class>
<desc>Sleep</desc>
<idle_sleep_time_in_sec>30</idle_sleep_time_in_sec>
</testCase>
<testCase id="000002">
<class>IdleSleep</class>
<desc>Sleep</desc>
<idle_sleep_time_in_sec>10</idle_sleep_time_in_sec>
</testCase>
<testCase id="000012">
<class>DeployGenObject</class>
<desc>Deploy OAI 4G CoreNetwork</desc>
<yaml_path>yaml_files/4g_rfsimulator</yaml_path>
<services>oai_hss oai_mme oai_spgwc oai_spgwu trf_gen</services>
<nb_healthy>6</nb_healthy>
</testCase>
<testCase id="000013">
<class>DeployGenObject</class>
<desc>Deploy OAI 4G eNB RF sim</desc>
<yaml_path>yaml_files/4g_rfsimulator</yaml_path>
<services>enb</services>
<nb_healthy>7</nb_healthy>
</testCase>
<testCase id="000014">
<class>DeployGenObject</class>
<desc>Deploy OAI 4G NR-UE RF sim</desc>
<yaml_path>yaml_files/4g_rfsimulator</yaml_path>
<services>oai_ue0</services>
<nb_healthy>8</nb_healthy>
</testCase>
<testCase id="020011">
<class>PingFromContainer</class>
<desc>Ping Traffic-Gen from LTE-UE</desc>
<container_name>rfsim4g-oai-lte-ue0</container_name>
<options>-I oaitun_ue1 -c 20 192.168.61.11</options>
<loss_threshold>5</loss_threshold>
</testCase>
<testCase id="020012">
<class>PingFromContainer</class>
<desc>Ping LTE-UE from Traffic-Gen</desc>
<container_name>rfsim4g-trf-gen</container_name>
<options>-c 20 12.0.0.2</options>
<loss_threshold>5</loss_threshold>
</testCase>
<testCase id="030011">
<class>IperfFromContainer</class>
<desc>Iperf UDP Downlink</desc>
<server_container_name>rfsim4g-oai-lte-ue0</server_container_name>
<client_container_name>rfsim4g-trf-gen</client_container_name>
<server_options>-B 12.0.0.2 -u -i 1 -s</server_options>
<client_options>-c 12.0.0.2 -u -i 1 -t 30 -b 2M</client_options>
</testCase>
<testCase id="030012">
<class>IperfFromContainer</class>
<desc>Iperf UDP Uplink</desc>
<server_container_name>rfsim4g-trf-gen</server_container_name>
<client_container_name>rfsim4g-oai-lte-ue0</client_container_name>
<server_options>-u -i 1 -s</server_options>
<client_options>-B 12.0.0.2 -c 192.168.61.11 -u -i 1 -t 30 -b 1M</client_options>
</testCase>
<testCase id="100011">
<class>UndeployGenObject</class>
<desc>Undeploy all OAI 4G stack</desc>
<yaml_path>yaml_files/4g_rfsimulator</yaml_path>
</testCase>
</testCaseList>
@@ -0,0 +1,38 @@
<!--
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>rfsim-4glte-down</htmlTabRef>
<htmlTabName>CleanUp 4G RF</htmlTabName>
<htmlTabIcon>trash</htmlTabIcon>
<TestCaseRequestedList>
100011
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="100011">
<class>UndeployGenObject</class>
<desc>Undeploy all OAI 4G stack</desc>
<yaml_path>yaml_files/4g_rfsimulator</yaml_path>
</testCase>
</testCaseList>
+104
View File
@@ -0,0 +1,104 @@
<!--
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>rfsim-5gnr</htmlTabRef>
<htmlTabName>Testing 5G NR RF sim in containers</htmlTabName>
<htmlTabIcon>wrench</htmlTabIcon>
<TestCaseRequestedList>
100001
000001
000002
000003
020001
020002
030001
030002
100001
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="000001">
<class>DeployGenObject</class>
<desc>Deploy OAI 5G CoreNetwork</desc>
<yaml_path>yaml_files/5g_rfsimulator</yaml_path>
<services>mysql oai-nrf oai-amf oai-smf oai-spgwu oai-ext-dn</services>
<nb_healthy>6</nb_healthy>
</testCase>
<testCase id="000002">
<class>DeployGenObject</class>
<desc>Deploy OAI 5G gNB RF sim SA</desc>
<yaml_path>yaml_files/5g_rfsimulator</yaml_path>
<services>oai-gnb</services>
<nb_healthy>7</nb_healthy>
</testCase>
<testCase id="000003">
<class>DeployGenObject</class>
<desc>Deploy OAI 5G NR-UE RF sim SA</desc>
<yaml_path>yaml_files/5g_rfsimulator</yaml_path>
<services>oai-nr-ue</services>
<nb_healthy>8</nb_healthy>
</testCase>
<testCase id="020001">
<class>PingFromContainer</class>
<desc>Ping ext-dn from NR-UE</desc>
<container_name>rfsim5g-oai-nr-ue</container_name>
<options>-I oaitun_ue1 -c 20 192.168.72.135</options>
<loss_threshold>5</loss_threshold>
</testCase>
<testCase id="020002">
<class>PingFromContainer</class>
<desc>Ping NR-UE from ext-dn</desc>
<container_name>rfsim5g-oai-ext-dn</container_name>
<options>-c 20 12.1.1.2</options>
<loss_threshold>5</loss_threshold>
</testCase>
<testCase id="030001">
<class>IperfFromContainer</class>
<desc>Iperf UDP Downlink</desc>
<server_container_name>rfsim5g-oai-nr-ue</server_container_name>
<client_container_name>rfsim5g-oai-ext-dn</client_container_name>
<server_options>-B 12.1.1.2 -u -i 1 -s</server_options>
<client_options>-c 12.1.1.2 -u -i 1 -t 30 -b 400K</client_options>
</testCase>
<testCase id="030002">
<class>IperfFromContainer</class>
<desc>Iperf UDP Uplink</desc>
<server_container_name>rfsim5g-oai-ext-dn</server_container_name>
<client_container_name>rfsim5g-oai-nr-ue</client_container_name>
<server_options>-u -i 1 -s</server_options>
<client_options>-B 12.1.1.2 -c 192.168.72.135 -u -i 1 -t 30 -b 20K</client_options>
</testCase>
<testCase id="100001">
<class>UndeployGenObject</class>
<desc>Undeploy all OAI 5G stack</desc>
<yaml_path>yaml_files/5g_rfsimulator</yaml_path>
</testCase>
</testCaseList>
@@ -0,0 +1,38 @@
<!--
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>rfsim-5gnr-down</htmlTabRef>
<htmlTabName>CleanUp 5G RF</htmlTabName>
<htmlTabIcon>trash</htmlTabIcon>
<TestCaseRequestedList>
100002
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="100002">
<class>UndeployGenObject</class>
<desc>Undeploy all OAI 5G stack</desc>
<yaml_path>yaml_files/5g_rfsimulator</yaml_path>
</testCase>
</testCaseList>
+4 -4
View File
@@ -97,7 +97,7 @@
<desc>Ping: 20pings in 20sec</desc>
<id>idefix</id>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>50</ping_packetloss_threshold>
<ping_packetloss_threshold>1</ping_packetloss_threshold>
</testCase>
<testCase id="050001">
@@ -105,7 +105,7 @@
<desc>Ping: 100pings in 20sec</desc>
<id>idefix</id>
<ping_args>-c 100 -i 0.2</ping_args>
<ping_packetloss_threshold>50</ping_packetloss_threshold>
<ping_packetloss_threshold>1</ping_packetloss_threshold>
</testCase>
<testCase id="070000">
@@ -114,7 +114,7 @@
<iperf_args>-u -b 20M -t 60</iperf_args>
<direction>DL</direction>
<id>idefix</id>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_packetloss_threshold>3</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
@@ -124,7 +124,7 @@
<iperf_args>-u -b 3M -t 60</iperf_args>
<direction>UL</direction>
<id>idefix</id>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_packetloss_threshold>1</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
@@ -7,7 +7,7 @@
</a>
</td>
<td style="border-collapse: collapse; border: none; vertical-align: center;">
<b><font size = "5">OAI Full Stack RF simulation with containers</font></b>
<b><font size = "5">OAI Full Stack 4G-LTE RF simulation with containers</font></b>
</td>
</tr>
</table>
@@ -81,11 +81,14 @@ How to build the Traffic-Generator image is explained [here](https://github.com/
**Just `docker-compose up -d` WILL NOT WORK!**
All the following commands **SHALL** be run from the `ci-scripts/yaml_files/4g_rfsimulator` folder.
## 2.1. Deploy and Configure Cassandra Database ##
It is very crutial that the Cassandra DB is fully configured before you do anything else!
```bash
$ cd ci-scripts/yaml_files/4g_rfsimulator
$ docker-compose up -d db_init
Creating network "rfsim4g-oai-private-net" with the default driver
Creating network "rfsim4g-oai-public-net" with the default driver
@@ -0,0 +1,368 @@
<table style="border-collapse: collapse; border: none;">
<tr style="border-collapse: collapse; border: none;">
<td style="border-collapse: collapse; border: none;">
<a href="http://www.openairinterface.org/">
<img src="../../../doc/images/oai_final_logo.png" alt="" border=3 height=50 width=150>
</img>
</a>
</td>
<td style="border-collapse: collapse; border: none; vertical-align: center;">
<b><font size = "5">OAI Full Stack 5G-NR RF simulation with containers</font></b>
</td>
</tr>
</table>
This page is only valid for an `Ubuntu18` host.
**TABLE OF CONTENTS**
1. [Retrieving the images on Docker-Hub](#1-retrieving-the-images-on-docker-hub)
2. [Deploy containers](#2-deploy-containers)
1. [Deploy OAI 5G Core Network](#21-deploy-oai-5g-core-network)
2. [Deploy OAI gNB in RF simulator mode and in Standalone Mode](#22-deploy-oai-gnb-in-rf-simulator-mode-and-in-standalone-mode)
3. [Deploy OAI NR-UE in RF simulator mode and in Standalone Mode](#23-deploy-oai-nr-ue-in-rf-simulator-mode-and-in-standalone-mode)
3. [Check traffic](#3-check-traffic)
1. [Check your Internet connectivity](#31-check-your-internet-connectivity)
2. [Start the iperf server inside the NR-UE container](#32-start-the-iperf-server-inside-the-nr-ue-container)
3. [Start the iperf client inside the ext-dn container](#33-start-the-iperf-client-inside-the-ext-dn-container)
4. [Un-deployment](#4-un-deployment)
# 1. Retrieving the images on Docker-Hub #
Currently the images are hosted under the user account `rdefosseoai`.
This may change in the future.
Once again you may need to log on [docker-hub](https://hub.docker.com/) if your organization has reached pulling limit as `anonymous`.
```bash
$ docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username:
Password:
```
Now pull images.
```bash
$ docker pull mysql:5.7
$ docker pull rdefosseoai/oai-amf:latest
$ docker pull rdefosseoai/oai-nrf:latest
$ docker pull rdefosseoai/oai-smf:latest
$ docker pull rdefosseoai/oai-spgwu-tiny:latest
$ docker pull rdefosseoai/oai-gnb:develop
$ docker pull rdefosseoai/oai-nr-ue:develop
```
And **re-tag** them for tutorials' docker-compose file to work.
```bash
$ docker image tag rdefosseoai/oai-amf:latest oai-amf:latest
$ docker image tag rdefosseoai/oai-nrf:latest oai-nrf:latest
$ docker image tag rdefosseoai/oai-smf:latest oai-smf:latest
$ docker image tag rdefosseoai/oai-spgwu-tiny:latest oai-spgwu-tiny:latest
$ docker image tag rdefosseoai/oai-gnb:develop oai-gnb:develop
$ docker image tag rdefosseoai/oai-nr-ue:develop oai-nr-ue:develop
```
```bash
$ docker logout
```
# 2. Deploy containers #
![Deployment](./oai-end-to-end.jpg)
**CAUTION: this SHALL be done in multiple steps.**
**Just `docker-compose up -d` WILL NOT WORK!**
All the following commands **SHALL** be run from the `ci-scripts/yaml_files/5g_rfsimulator` folder.
## 2.1. Deploy OAI 5G Core Network ##
```bash
$ cd ci-scripts/yaml_files/5g_rfsimulator
$ docker-compose up -d mysql oai-nrf oai-amf oai-smf oai-spgwu oai-ext-dn
Creating network "rfsim5g-oai-public-net" with driver "bridge"
Creating network "rfsim5g-oai-traffic_net-net" with driver "bridge"
Creating rfsim5g-oai-nrf ... done
Creating rfsim5g-mysql ... done
Creating rfsim5g-oai-spgwu ... done
Creating rfsim5g-oai-amf ... done
Creating rfsim5g-oai-smf ... done
Creating rfsim5g-oai-ext-dn ... done
```
Wait for a bit.
```bash
$ docker-compose ps -a
Name Command State Ports
-------------------------------------------------------------------------------------------------
rfsim5g-mysql docker-entrypoint.sh mysqld Up (healthy) 3306/tcp, 33060/tcp
rfsim5g-oai-amf /bin/bash /openair-amf/bin ... Up (healthy) 38412/sctp, 80/tcp, 9090/tcp
rfsim5g-oai-ext-dn /bin/bash -c apt update; ... Up (healthy)
rfsim5g-oai-nrf /bin/bash /openair-nrf/bin ... Up (healthy) 80/tcp, 9090/tcp
rfsim5g-oai-smf /bin/bash -c /openair-smf/ ... Up (healthy) 80/tcp, 8805/udp, 9090/tcp
rfsim5g-oai-spgwu /openair-spgwu-tiny/bin/en ... Up (healthy) 2152/udp, 8805/udp
```
At this point, you can prepare a capture on the newly-created public docker bridges:
```bash
$ ifconfig
...
rfsim5g-public: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.71.129 netmask 255.255.255.192 broadcast 192.168.71.191
inet6 fe80::42:c4ff:fe2b:3d38 prefixlen 64 scopeid 0x20<link>
ether 02:42:c4:2b:3d:38 txqueuelen 0 (Ethernet)
RX packets 4 bytes 112 (112.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 7 bytes 626 (626.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
rfsim5g-traffic: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.72.129 netmask 255.255.255.192 broadcast 192.168.72.191
inet6 fe80::42:b5ff:fed3:e732 prefixlen 64 scopeid 0x20<link>
ether 02:42:b5:d3:e7:32 txqueuelen 0 (Ethernet)
RX packets 2652 bytes 142335 (142.3 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 3999 bytes 23367972 (23.3 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
...
```
## 2.2. Deploy OAI gNB in RF simulator mode and in Standalone Mode ##
```bash
$ docker-compose up -d oai-gnb
rfsim5g-oai-nrf is up-to-date
rfsim5g-oai-spgwu is up-to-date
rfsim5g-oai-ext-dn is up-to-date
Creating rfsim5g-oai-gnb ... done
```
Wait for a bit.
```bash
$ docker-compose ps -a
Name Command State Ports
-------------------------------------------------------------------------------------------------
rfsim5g-mysql docker-entrypoint.sh mysqld Up (healthy) 3306/tcp, 33060/tcp
rfsim5g-oai-amf /bin/bash /openair-amf/bin ... Up (healthy) 38412/sctp, 80/tcp, 9090/tcp
rfsim5g-oai-ext-dn /bin/bash -c apt update; ... Up (healthy)
rfsim5g-oai-gnb /opt/oai-gnb/bin/entrypoin ... Up (healthy)
rfsim5g-oai-nrf /bin/bash /openair-nrf/bin ... Up (healthy) 80/tcp, 9090/tcp
rfsim5g-oai-smf /bin/bash -c /openair-smf/ ... Up (healthy) 80/tcp, 8805/udp, 9090/tcp
rfsim5g-oai-spgwu /openair-spgwu-tiny/bin/en ... Up (healthy) 2152/udp, 8805/udp
```
## 2.3. Deploy OAI NR-UE in RF simulator mode and in Standalone Mode ##
```bash
$ docker-compose up -d oai-nr-ue
rfsim5g-mysql is up-to-date
rfsim5g-oai-nrf is up-to-date
rfsim5g-oai-spgwu is up-to-date
rfsim5g-oai-ext-dn is up-to-date
rfsim5g-oai-gnb is up-to-date
Creating rfsim5g-oai-nr-ue ... done
```
Wait for a bit.
```bash
$ docker-compose ps -a
Name Command State Ports
-------------------------------------------------------------------------------------------------
rfsim5g-mysql docker-entrypoint.sh mysqld Up (healthy) 3306/tcp, 33060/tcp
rfsim5g-oai-amf /bin/bash /openair-amf/bin ... Up (healthy) 38412/sctp, 80/tcp, 9090/tcp
rfsim5g-oai-ext-dn /bin/bash -c apt update; ... Up (healthy)
rfsim5g-oai-gnb /opt/oai-gnb/bin/entrypoin ... Up (healthy)
rfsim5g-oai-nr-ue /opt/oai-nr-ue/bin/entrypo ... Up (healthy)
rfsim5g-oai-nrf /bin/bash /openair-nrf/bin ... Up (healthy) 80/tcp, 9090/tcp
rfsim5g-oai-smf /bin/bash -c /openair-smf/ ... Up (healthy) 80/tcp, 8805/udp, 9090/tcp
rfsim5g-oai-spgwu /openair-spgwu-tiny/bin/en ... Up (healthy) 2152/udp, 8805/udp
```
Making sure the OAI UE is connected:
```bash
$ docker exec -it rfsim5g-oai-nr-ue /bin/bash
root@bb4d400a832d:/opt/oai-nr-ue# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.71.137 netmask 255.255.255.192 broadcast 192.168.71.191
ether 02:42:c0:a8:47:89 txqueuelen 0 (Ethernet)
RX packets 224259 bytes 5821372018 (5.8 GB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 235916 bytes 7848786376 (7.8 GB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
loop txqueuelen 1000 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
oaitun_ue1: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST> mtu 1500
inet 12.1.1.2 netmask 255.255.255.0 destination 12.1.1.2
unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 500 (UNSPEC)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
```
# 3. Check traffic #
## 3.1. Check your Internet connectivity ##
```bash
$ docker exec -it rfsim5g-oai-nr-ue /bin/bash
root@bb4d400a832d:/opt/oai-nr-ue# ping -I oaitun_ue1 -c 10 www.lemonde.fr
PING s2.shared.global.fastly.net (151.101.122.217) from 12.1.1.2 oaitun_ue1: 56(84) bytes of data.
64 bytes from 151.101.122.217 (151.101.122.217): icmp_seq=1 ttl=53 time=64.5 ms
64 bytes from 151.101.122.217 (151.101.122.217): icmp_seq=2 ttl=53 time=37.0 ms
64 bytes from 151.101.122.217 (151.101.122.217): icmp_seq=3 ttl=53 time=43.2 ms
64 bytes from 151.101.122.217 (151.101.122.217): icmp_seq=4 ttl=53 time=43.2 ms
64 bytes from 151.101.122.217 (151.101.122.217): icmp_seq=5 ttl=53 time=54.3 ms
64 bytes from 151.101.122.217 (151.101.122.217): icmp_seq=6 ttl=53 time=24.0 ms
64 bytes from 151.101.122.217 (151.101.122.217): icmp_seq=7 ttl=53 time=32.5 ms
64 bytes from 151.101.122.217 (151.101.122.217): icmp_seq=8 ttl=53 time=37.0 ms
64 bytes from 151.101.122.217 (151.101.122.217): icmp_seq=9 ttl=53 time=41.2 ms
64 bytes from 151.101.122.217 (151.101.122.217): icmp_seq=10 ttl=53 time=50.3 ms
--- s2.shared.global.fastly.net ping statistics ---
10 packets transmitted, 10 received, 0% packet loss, time 9011ms
rtt min/avg/max/mdev = 24.035/42.765/64.557/10.904 ms
```
If it does not work, certainly you need to modify the DNS values in the docker-compose.
But you can also check with the `ext-dn` container (IP address is `192.168.72.135` in docker-compose)
```bash
$ docker exec -it rfsim5g-oai-nr-ue /bin/bash
root@bb4d400a832d# ping -I oaitun_ue1 -c 2 192.168.72.135
PING 192.168.72.135 (192.168.72.135) from 12.1.1.2 oaitun_ue1: 56(84) bytes of data.
64 bytes from 192.168.72.135: icmp_seq=1 ttl=63 time=10.9 ms
64 bytes from 192.168.72.135: icmp_seq=2 ttl=63 time=16.5 ms
--- 192.168.72.135 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 10.939/13.747/16.556/2.810 ms
```
Let now try to check UDP traffic in Downlink.
You will need 2 terminals: one in the NR-UE container, one in the ext-dn container.
## 3.2. Start the `iperf` server inside the NR-UE container ##
```bash
$ docker exec -it rfsim5g-oai-nr-ue /bin/bash
root@bb4d400a832d:/opt/oai-nr-ue# iperf -B 12.1.1.2 -u -i 1 -s
------------------------------------------------------------
Server listening on UDP port 5001
Binding to local address 12.1.1.2
Receiving 1470 byte datagrams
UDP buffer size: 208 KByte (default)
------------------------------------------------------------
```
## 3.3. Start the `iperf` client inside the ext-dn container ##
```bash
$ docker exec -it rfsim5g-oai-ext-dn /bin/bash
root@f239e31a0bd0:/# iperf -c 12.1.1.2 -u -i 1 -t 20 -b 500K
------------------------------------------------------------
Client connecting to 12.1.1.2, UDP port 5001
Sending 1470 byte datagrams, IPG target: 22968.75 us (kalman adjust)
UDP buffer size: 208 KByte (default)
------------------------------------------------------------
[ 3] local 192.168.72.135 port 58800 connected with 12.1.1.2 port 5001
[ ID] Interval Transfer Bandwidth
[ 3] 0.0- 1.0 sec 64.6 KBytes 529 Kbits/sec
[ 3] 1.0- 2.0 sec 63.2 KBytes 517 Kbits/sec
[ 3] 2.0- 3.0 sec 61.7 KBytes 506 Kbits/sec
[ 3] 3.0- 4.0 sec 63.2 KBytes 517 Kbits/sec
[ 3] 4.0- 5.0 sec 61.7 KBytes 506 Kbits/sec
[ 3] 5.0- 6.0 sec 63.2 KBytes 517 Kbits/sec
[ 3] 6.0- 7.0 sec 61.7 KBytes 506 Kbits/sec
[ 3] 7.0- 8.0 sec 63.2 KBytes 517 Kbits/sec
[ 3] 8.0- 9.0 sec 61.7 KBytes 506 Kbits/sec
[ 3] 9.0-10.0 sec 63.2 KBytes 517 Kbits/sec
[ 3] 10.0-11.0 sec 61.7 KBytes 506 Kbits/sec
[ 3] 11.0-12.0 sec 63.2 KBytes 517 Kbits/sec
[ 3] 12.0-13.0 sec 61.7 KBytes 506 Kbits/sec
[ 3] 13.0-14.0 sec 63.2 KBytes 517 Kbits/sec
[ 3] 14.0-15.0 sec 63.2 KBytes 517 Kbits/sec
[ 3] 15.0-16.0 sec 61.7 KBytes 506 Kbits/sec
[ 3] 16.0-17.0 sec 63.2 KBytes 517 Kbits/sec
[ 3] 17.0-18.0 sec 61.7 KBytes 506 Kbits/sec
[ 3] 18.0-19.0 sec 63.2 KBytes 517 Kbits/sec
[ 3] 19.0-20.0 sec 61.7 KBytes 506 Kbits/sec
[ 3] 0.0-20.0 sec 1.22 MBytes 512 Kbits/sec
[ 3] Sent 872 datagrams
[ 3] Server Report:
[ 3] 0.0-20.0 sec 1.22 MBytes 510 Kbits/sec 0.000 ms 3/ 872 (0%)
```
Back on your NR-UE terminal you shall see:
```bash
[ 3] local 12.1.1.2 port 5001 connected with 192.168.72.135 port 58800
[ ID] Interval Transfer Bandwidth Jitter Lost/Total Datagrams
[ 3] 0.0- 1.0 sec 63.2 KBytes 517 Kbits/sec 1.113 ms 0/ 44 (0%)
[ 3] 1.0- 2.0 sec 61.7 KBytes 506 Kbits/sec 1.466 ms 0/ 43 (0%)
[ 3] 2.0- 3.0 sec 63.2 KBytes 517 Kbits/sec 1.770 ms 0/ 44 (0%)
[ 3] 3.0- 4.0 sec 61.7 KBytes 506 Kbits/sec 1.378 ms 0/ 43 (0%)
[ 3] 4.0- 5.0 sec 63.2 KBytes 517 Kbits/sec 1.614 ms 0/ 44 (0%)
[ 3] 5.0- 6.0 sec 63.2 KBytes 517 Kbits/sec 1.427 ms 0/ 44 (0%)
[ 3] 6.0- 7.0 sec 60.3 KBytes 494 Kbits/sec 1.507 ms 1/ 43 (2.3%)
[ 3] 7.0- 8.0 sec 63.2 KBytes 517 Kbits/sec 1.409 ms 0/ 44 (0%)
[ 3] 8.0- 9.0 sec 61.7 KBytes 506 Kbits/sec 1.525 ms 0/ 43 (0%)
[ 3] 9.0-10.0 sec 63.2 KBytes 517 Kbits/sec 1.393 ms 0/ 44 (0%)
[ 3] 10.0-11.0 sec 61.7 KBytes 506 Kbits/sec 1.377 ms 0/ 43 (0%)
[ 3] 11.0-12.0 sec 63.2 KBytes 517 Kbits/sec 1.501 ms 0/ 44 (0%)
[ 3] 12.0-13.0 sec 61.7 KBytes 506 Kbits/sec 1.788 ms 0/ 43 (0%)
[ 3] 13.0-14.0 sec 63.2 KBytes 517 Kbits/sec 1.466 ms 0/ 44 (0%)
[ 3] 14.0-15.0 sec 61.7 KBytes 506 Kbits/sec 1.381 ms 0/ 43 (0%)
[ 3] 15.0-16.0 sec 61.7 KBytes 506 Kbits/sec 1.417 ms 1/ 44 (2.3%)
[ 3] 16.0-17.0 sec 61.7 KBytes 506 Kbits/sec 1.569 ms 0/ 43 (0%)
[ 3] 17.0-18.0 sec 63.2 KBytes 517 Kbits/sec 1.492 ms 1/ 45 (2.2%)
[ 3] 18.0-19.0 sec 61.7 KBytes 506 Kbits/sec 1.376 ms 0/ 43 (0%)
[ 3] 19.0-20.0 sec 61.7 KBytes 506 Kbits/sec 1.589 ms 0/ 43 (0%)
[ 3] 0.0-20.0 sec 1.22 MBytes 510 Kbits/sec 1.551 ms 3/ 872 (0.34%)
```
The `500 Kbits/sec` value may change depending on your CPU power!
# 4. Un-deployment #
```bash
$ docker-compose down
Stopping rfsim5g-oai-nr-ue ... done
Stopping rfsim5g-oai-gnb ... done
Stopping rfsim5g-oai-ext-dn ... done
Stopping rfsim5g-oai-smf ... done
Stopping rfsim5g-oai-amf ... done
Stopping rfsim5g-oai-spgwu ... done
Stopping rfsim5g-oai-nrf ... done
Stopping rfsim5g-mysql ... done
Removing rfsim5g-oai-nr-ue ... done
Removing rfsim5g-oai-gnb ... done
Removing rfsim5g-oai-ext-dn ... done
Removing rfsim5g-oai-smf ... done
Removing rfsim5g-oai-amf ... done
Removing rfsim5g-oai-spgwu ... done
Removing rfsim5g-oai-nrf ... done
Removing rfsim5g-mysql ... done
Removing network rfsim5g-oai-public-net
Removing network rfsim5g-oai-traffic_net-net
```
@@ -206,7 +206,7 @@ services:
privileged: true
container_name: rfsim5g-oai-ext-dn
entrypoint: /bin/bash -c \
"apt update; apt install -y iptables iproute2 iperf iputils-ping;"\
"apt update; apt install -y procps iptables iproute2 iperf iputils-ping;"\
"iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE;"\
"ip route add 12.1.1.0/24 via 192.168.72.134 dev eth0; sleep infinity"
depends_on:
Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

+2 -2
View File
@@ -457,8 +457,8 @@ include_directories ("${RRC_FULL_DIR}")
#NR RRC
#######
set (NR_RRC_ASN1_VERSION "NR_Rel16" )
make_version(NR_RRC_VERSION 16 1 0)
set (NR_RRC_GRAMMAR ${OPENAIR2_DIR}/RRC/NR/MESSAGES/asn1c/ASN1_files/nr-rrc-16.1.0.asn1)
make_version(NR_RRC_VERSION 16 4 1)
set (NR_RRC_GRAMMAR ${OPENAIR2_DIR}/RRC/NR/MESSAGES/asn1c/ASN1_files/nr-rrc-16.4.1.asn1)
add_definitions(-DNR_RRC_VERSION=${NR_RRC_VERSION})
set (NR_RRC_FULL_DIR ${asn1_generated_dir}/RRC_${NR_RRC_ASN1_VERSION})
+1 -1
View File
@@ -16,7 +16,7 @@ ID = ENB_PHY_DL_TICK
ID = ENB_PHY_DLSCH_UE_DCI
DESC = eNodeB downlink UE specific DCI as sent by the PHY layer
GROUP = ALL:PHY:GRAPHIC:ENB
FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti : int,dci_format : int,harq_pid : int,mcs : int,TBS
FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti : int,dci_format : int,harq_pid : int,mcs : int,TBS : int,ndi : int,rv : int,rbc : int,nb_rb : int,rb_alloc
ID = ENB_PHY_DLSCH_UE_ACK
DESC = eNodeB downlink UE ACK as seen by the PHY layer in process_HARQ_feedback
GROUP = ALL:PHY:GRAPHIC:ENB
+34
View File
@@ -106,6 +106,40 @@ nr_bandentry_t nr_bandtable[] = {
{261,27500040,28350000,27500040,28350000, 2,2070833, 120}
};
uint16_t get_band(uint64_t downlink_frequency, int32_t delta_duplex)
{
const uint64_t dl_freq_khz = downlink_frequency / 1000;
const int32_t delta_duplex_khz = delta_duplex / 1000;
uint64_t center_freq_diff_khz = 999999999999999999; // 2^64
uint16_t current_band = 0;
for (int ind = 0; ind < nr_bandtable_size; ind++) {
if (dl_freq_khz < nr_bandtable[ind].dl_min || dl_freq_khz > nr_bandtable[ind].dl_max)
continue;
int32_t current_offset_khz = nr_bandtable[ind].ul_min - nr_bandtable[ind].dl_min;
if (current_offset_khz != delta_duplex_khz)
continue;
uint64_t center_frequency_khz = (nr_bandtable[ind].dl_max + nr_bandtable[ind].dl_min) / 2;
if (abs(dl_freq_khz - center_frequency_khz) < center_freq_diff_khz){
current_band = nr_bandtable[ind].band;
center_freq_diff_khz = abs(dl_freq_khz - center_frequency_khz);
}
}
printf("DL frequency %"PRIu64": band %d, UL frequency %"PRIu64"\n",
downlink_frequency, current_band, downlink_frequency+delta_duplex);
AssertFatal(current_band != 0, "Can't find EUTRA band for frequency %"PRIu64" and duplex_spacing %u\n", downlink_frequency, delta_duplex);
return current_band;
}
const size_t nr_bandtable_size = sizeof(nr_bandtable) / sizeof(nr_bandentry_t);
int NRRIV2BW(int locationAndBandwidth,int N_RB) {
+1
View File
@@ -50,6 +50,7 @@ typedef struct nr_bandentry_s {
extern const size_t nr_bandtable_size;
extern nr_bandentry_t nr_bandtable[];
uint16_t get_band(uint64_t downlink_frequency, int32_t delta_duplex);
int NRRIV2BW(int locationAndBandwidth,int N_RB);
int NRRIV2PRBOFFSET(int locationAndBandwidth,int N_RB);
int PRBalloc_to_locationandbandwidth0(int NPRB,int RBstart,int BWPsize);
+4
View File
@@ -209,6 +209,10 @@ int background_system(char *command) {
void start_background_system(void) {
int p[2];
pid_t son;
if (module_initialized == 1)
return;
module_initialized = 1;
if (pipe(p) == -1) {
+141
View File
@@ -0,0 +1,141 @@
# global
xnf is pnf or vnf
The xnf starting functions are configure_nfapi_xnf()
The OAI code that read the configuration parameters call these functions that will create autonomous thread for xnf control part
These control threads create a SCTP socket by Linux API call (no use of OpenAir internal architecture with SCTP itti thread).
The main() function of softmodem has to create and start the other threads+loop on event for appropriate work: RF Rx in pnf, NGAP, GTP-U, X2, RLC, PDCP for vnf
NFAPI has it's own code directly on Linux+Posix, it doesn't reuse any piece of the OpenAir framework: SCTP thread, thread creation and management, ...
## signaling (P5) xnf main loop
nfapi_vnf_start() create the SCTP socket, then do event waiting in a infinite loop while(vnf->terminate == 0). It accepts the pnf connections, then process the messages on reception
nfapi_pnf_start() initiate connection to vnf until it has a link. Then it enter a similar infinite loop in pnf_message_pump()
After some checks, when a message is obtained, it calls pnf_handle_p5_message() or vnf_handle_p4_p5_message() that have a switch on each p5 message types: the enum nfapi_message_id_e
Each message type has it's own processing function in the switch, like
```
case NFAPI_START_RESPONSE:
vnf_handle_start_response(pRecvMsg, recvMsgLen, config, p5_idx);
break;
```
These loops are autonomous in their thread waiting incoming message.
## P7 xnf main loop
When the p5 interface receives appropriate message, it starts the p7 interface by launching a thread (see the calls to pthread_create() in nfapi/oai_integration/nfapi_xnf.c)
The p7 main loops starting is a bit simpler, thanks to UDP non connected protocol. The xnf_dispatch_p7_message() do p7 fragments re-assembly, then
calls xnf_dispatch_p7_message() that have the big switch on message type (as in p5 above description)
So, we have the logic for UL reception in vnf, and DL reception in pnf
## P7 UL transmission by PNF
RF samples are received, and decoding is done by the PNF using control data transmitted by the VNF to the PNF through downlink p7 messages (UL_TTI_req and UL_DCI_req).
After decoding, results are accumulated into the xNB->UL_INFO structure at the PNF.
The data in the UL_INFO struct is transmitted through a socket in the form of 'uplink indication functions' from the PNF to the VNF. Each uplink indication message is transmitted from their respective handle functions in NR_UL_indication(). For example,
```
void handle_nr_rach(NR_UL_IND_t *UL_info) {
if(NFAPI_MODE == NFAPI_MODE_PNF) {
if (UL_info->rach_ind.number_of_pdus>0) {
oai_nfapi_nr_rach_indication(&UL_info->rach_ind); //This function calls the routines required for packing + transmission through socket
UL_info->rach_ind.number_of_pdus = 0;
}
}
```
## P7 UL reception at VNF
Through the infinite loop [while(vnf_p7->terminate == 0)] running in nfapi_nr_vnf_p7_start(), the VNF receives and unpacks the uplink indication message received on its socket. Based on the unpacked messages, UL_INFO struct on the VNF side gets populated.
```
// have a p7 message
if(FD_ISSET(vnf_p7->socket, &rfds))
{
vnf_nr_p7_read_dispatch_message(vnf_p7);
}
```
vnf_nr_dispatch_p7_message() is the function that contains the switch on various message headers so that the appropriate unpack function is called.
## P7 DL Transmission by VNF
DL messages are scheduled at the VNF, through NR_UL_indication(). NR_UL_indication() is called when the SFN/slot in the UL_info structure changes (this acts as a trigger for next slot processing, instead of running a separate clock at the VNF). The SFN/slot at the VNF in UL_info is updated using the slot_indication uplink p7 message, which is sent at the beginning of every slot by the PNF. The slot_indication message contains SFN/slot of the TX_thread, so that the scheduler operates slot_ahead slots ahead of the RX thread. This ensures that UL_tti_req is received before RX slot processing at the PNF.
The function NR_schedule_response calls oai_nfapi_[DL P7 msg]_req(), which contains the routines for packing + transmission of scheduled messages through the socket to the PNF. For example, to send the 'TX_data_req' p7 message
```
if (Sched_INFO->TX_req->Number_of_PDUs > 0)
{
oai_nfapi_tx_data_req(Sched_INFO->TX_req);
}
```
```mermaid
graph TD
pselect[VNF socket pselect] -- timed out : end of slot --> call_sched[Call Scheduler NR_UL_indication] -- oai_nfapi_***_req sends the DL p7 msg--> slot_inc[Increment sfn/slot];
pselect[VNF socket pselect] -- UL p7 xyz msg recvd --> msg_recvd[Read message vnf_nr_p7_read_dispatch_message] --> header_unpack[Unpack Header] -- switch cases on header --> unpack_msg[Handle Message vnf_handle_nr_xyz] --> fill_ul_info[Fill UL info struct with fn pointer vnf_p7->_public.nr_rx_xyz];
fill_ul_info -- update pselect_timeout: next_slot_start - time_xyz_msg_recvd-->pselect;
slot_inc -- next slot --> pselect
```
Note that since DL P7 message reception and TX/RX processing are done on separate threads, there is the issue of the L1 processing threads trying to do their job before the required P7 message is received. In the case of RX processing, since the scheduler operates slot_ahead slots ahead of the RX thread, the required messages conveniently arrive earlier than they are required. However, in the case of TX processing, this cannot be ensured if the scheduler is exactly in sync with the TX thread.
Therefore, we operate the VNF vnf_slot_ahead (which is currently 2) slots ahead of the PNF. This is to ensure that the DL fapi structures for a particular TX slot are all received before TX processing for that slot.
## P7 DL Reception at PNF
Through the infinite loop [while(pnf_p7->terminate == 0)] running in pnf_nr_p7_message_pump(), the PNF receives and unpacks the downlink P7 message received on its socket. Based on the unpacked message, the appropriate message structures are filled in the PNF, and these are used further down the pipeline for processing.
While receiving the DL P7 message, we check whether the message was received within a timing window from which it was sent. The duration of the window can be set by the user (set as a parameter for xnf in the p5 messages). Note that the DL information must be received by the PNF within a timing window at least lesser than the duration of slot_ahead variable (timing_window <= slot_ahead * slot_duration).
```mermaid
graph TB
pselect[PNF socket pselect] -- timed out : end of slot --> slot_inc[Increment sfn/slot];
pselect[PNF socket pselect] -- DL p7 xyz msg recvd --> msg_recvd[Read message pnf_nr_nfapi_p7_read_dispatch_message] --> header_unpack[Unpack Header] -- switch cases on header --> unpack_msg[Unpack Message pnf_handle_nr_xyz] --> fill_pnf_p7[Fill pnf_p7 global structure pnf_handle_nr_xyz] --Data from pnf_p7 struct copied to fapi structures using pnf_phy_***_req. Called every slot from handle_nr_slot_ind-->pselect;
slot_inc -- next slot --> pselect
```
Once the messages are received, they are filled into slot buffers, and are stored until the processing of the slot that they were meant for.
+54
View File
@@ -0,0 +1,54 @@
# Procedure to run nFAPI in 5G NR
## Contributed by 5G Testbed IISc
### Developers: Gokul S, Mahesh A, Aniq U R
## Procedure to Build gNB and UE
The regular commands to build gNB and UE can be used
```
sudo ./build_oai --gNB --nrUE
```
## Procedure to run NR nFAPI using RF-Simulator
### Bring up another loopback interface
If running for the first time on your computer, or you have restarted your computer, bring up another loopback interface with this command:
sudo ifconfig lo: 127.0.0.2 netmask 255.0.0.0 up
### VNF command
```
sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band78.tm1.106PRB.nfapi.conf --nfapi 2 --noS1 --phy-test
```
### PNF command
```
sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/oaiL1.nfapi.usrpx300.conf --nfapi 1 --rfsim --phy-test --rfsimulator.serveraddr server
```
### UE command
```
sudo RFSIMULATOR=127.0.0.1 ./nr-uesoftmodem --rfsim --phy-test --rrc_config_path . -d
```
## Procedure to run NR nFAPI using Hardware (tested with USRP x310)
### VNF command
```
sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band78.tm1.106PRB.nfapi.conf --nfapi 2 --noS1 --phy-test
```
### PNF command
```
sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/oaiL1.nfapi.usrpx300.conf --nfapi 1 --phy-test
```
### UE command
```
sudo ./nr-uesoftmodem --usrp-args "addr=*USRP_ADDRESS*,clock_source=external,time_source=external" --phy-test --rrc_config_path ../../../ci-scripts/rrc-files
```
+1 -3
View File
@@ -37,9 +37,7 @@ RUN /bin/sh oaienv && \
mkdir -p log && \
./build_oai --UE --ninja -w USRP --verbose-ci
RUN yum install -y python3-pip && \
pip3 install --ignore-installed pyyaml && \
python3 ./docker/scripts/generateTemplate.py ./docker/scripts/lte_ue_parameters.yaml && \
RUN python3 ./docker/scripts/generateTemplate.py ./docker/scripts/lte_ue_parameters.yaml && \
python3 ./docker/scripts/generateTemplate.py ./docker/scripts/lte_ue_sim_parameters.yaml
#start from scratch for target executable
+1 -3
View File
@@ -37,9 +37,7 @@ RUN /bin/sh oaienv && \
mkdir -p log && \
./build_oai --UE --ninja -w USRP --verbose-ci
RUN apt-get install -y python3-pip && \
pip3 install --ignore-installed pyyaml && \
python3 ./docker/scripts/generateTemplate.py ./docker/scripts/lte_ue_parameters.yaml && \
RUN python3 ./docker/scripts/generateTemplate.py ./docker/scripts/lte_ue_parameters.yaml && \
python3 ./docker/scripts/generateTemplate.py ./docker/scripts/lte_ue_sim_parameters.yaml
#start from scratch for target executable
+1
View File
@@ -49,6 +49,7 @@ RUN yum update -y && \
nettle \
net-tools \
iputils \
iproute \
atlas \
libXpm \
libX11 \
+1
View File
@@ -6,6 +6,7 @@ PREFIX=/opt/oai-enb
RRC_INACTIVITY_THRESHOLD=${RRC_INACTIVITY_THRESHOLD:-0}
ENABLE_MEASUREMENT_REPORTS=${ENABLE_MEASUREMENT_REPORTS:-no}
ENABLE_X2=${ENABLE_X2:-no}
THREAD_PARALLEL_CONFIG=${THREAD_PARALLEL_CONFIG:-PARALLEL_SINGLE_THREAD}
# Based another env var, pick one template to use
if [[ -v USE_FDD_CU ]]; then ln -s $PREFIX/etc/cu.fdd.conf $PREFIX/etc/enb.conf; fi
+16
View File
@@ -98,6 +98,8 @@
env: "@NID_CELL@"
- key: N_RB_DL
env: "@NB_PRB@"
- key: parallel_config
env: "@THREAD_PARALLEL_CONFIG@"
- filePrefix: rru.fdd
outputfilename: "rru.fdd.conf"
@@ -110,6 +112,8 @@
env: "@RRU_LOCAL_IP_ADDRESS@"
- key: bands
env: "@UTRA_BAND_ID@"
- key: parallel_config
env: "@THREAD_PARALLEL_CONFIG@"
- filePrefix: rru.tdd
outputfilename: "rru.tdd.conf"
@@ -122,6 +126,8 @@
env: "@RRU_LOCAL_IP_ADDRESS@"
- key: bands
env: "@UTRA_BAND_ID@"
- key: parallel_config
env: "@THREAD_PARALLEL_CONFIG@"
- filePrefix: enb.band7.tm1.fr1.25PRB.usrpb210.conf
outputfilename: "enb.fdd.conf"
@@ -171,6 +177,8 @@
env: "@FLEXRAN_INTERFACE_NAME@"
- key: FLEXRAN_IPV4_ADDRESS
env: "@FLEXRAN_IPV4_ADDRESS@"
- key: parallel_config
env: "@THREAD_PARALLEL_CONFIG@"
- filePrefix: enb.band40.tm1.25PRB.FairScheduler.usrpb210
outputfilename: "enb.tdd.conf"
@@ -208,6 +216,8 @@
env: "@F1_CU_IP_ADDRESS@"
- key: ENB_IPV4_ADDRESS_FOR_X2C
env: "@F1_CU_IP_ADDRESS@"
- key: parallel_config
env: "@THREAD_PARALLEL_CONFIG@"
- filePrefix: "rcc.band7.tm1.nfapi"
outputfilename: "rcc.nfapi.fdd.conf"
@@ -251,6 +261,8 @@
env: "@F1_CU_IP_ADDRESS@"
- key: ENB_IPV4_ADDRESS_FOR_X2C
env: "@F1_CU_IP_ADDRESS@"
- key: parallel_config
env: "@THREAD_PARALLEL_CONFIG@"
- filePrefix: "rcc.band7.tm1.if4p5.lo.25PRB"
outputfilename: "rcc.if4p5.fdd.conf"
@@ -294,6 +306,8 @@
env: "@IF4P5_RRU_IP_ADDRESS@"
- key: local_address
env: "@IF4P5_RCC_IP_ADDRESS@"
- key: parallel_config
env: "@THREAD_PARALLEL_CONFIG@"
- filePrefix: "rcc.band40.tm1.25PRB"
outputfilename: "rcc.if4p5.tdd.conf"
@@ -337,4 +351,6 @@
env: "@IF4P5_RRU_IP_ADDRESS@"
- key: local_address
env: "@IF4P5_RCC_IP_ADDRESS@"
- key: parallel_config
env: "@THREAD_PARALLEL_CONFIG@"
+1
View File
@@ -4,6 +4,7 @@ set -euo pipefail
PREFIX=/opt/oai-gnb
ENABLE_X2=${ENABLE_X2:-yes}
THREAD_PARALLEL_CONFIG=${THREAD_PARALLEL_CONFIG:-PARALLEL_SINGLE_THREAD}
# Based another env var, pick one template to use
if [[ -v USE_NSA_TDD_MONO ]]; then ln -s $PREFIX/etc/gnb.nsa.tdd.conf $PREFIX/etc/gnb.conf; fi
+4
View File
@@ -61,6 +61,8 @@
env: "@FLEXRAN_INTERFACE_NAME@"
- key: FLEXRAN_IPV4_ADDRESS
env: "@FLEXRAN_IPV4_ADDRESS@"
- key: parallel_config
env: "@THREAD_PARALLEL_CONFIG@"
- filePrefix: gnb.band78.sa.fr1.106PRB.usrpn310.conf
outputfilename: "gnb.sa.tdd.conf"
@@ -89,4 +91,6 @@
env: "@GNB_NGU_IF_NAME@"
- key: GNB_IPV4_ADDRESS_FOR_NGU
env: "@GNB_NGU_IP_ADDRESS@"
- key: parallel_config
env: "@THREAD_PARALLEL_CONFIG@"
+7 -6
View File
@@ -85,6 +85,7 @@
#include "T.h"
#include "nfapi/oai_integration/vendor_ext.h"
#include "executables/softmodem-common.h"
#include <nfapi/oai_integration/nfapi_pnf.h>
#include <openair1/PHY/NR_TRANSPORT/nr_ulsch.h>
#include <PHY/NR_ESTIMATION/nr_ul_estimation.h>
@@ -146,15 +147,12 @@ void rx_func(void *param) {
start_meas(&softmodem_stats_rxtx_sf);
// *******************************************************************
// NFAPI not yet supported for NR - this code has to be revised
if (NFAPI_MODE == NFAPI_MODE_PNF) {
// I am a PNF and I need to let nFAPI know that we have a (sub)frame tick
//add_subframe(&frame, &subframe, 4);
//oai_subframe_ind(proc->frame_tx, proc->subframe_tx);
//LOG_D(PHY, "oai_subframe_ind(frame:%u, subframe:%d) - NOT CALLED ********\n", frame, subframe);
//LOG_D(PHY, "oai_nfapi_slot_ind(frame:%u, slot:%d) ********\n", frame_rx, slot_rx);
start_meas(&nfapi_meas);
// oai_subframe_ind(frame_rx, slot_rx);
oai_slot_ind(frame_rx, slot_rx);
handle_nr_slot_ind(frame_rx, slot_rx);
stop_meas(&nfapi_meas);
/*if (gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus||
@@ -451,6 +449,8 @@ void init_eNB_afterRU(void) {
PHY_VARS_gNB *gNB;
LOG_I(PHY,"%s() RC.nb_nr_inst:%d\n", __FUNCTION__, RC.nb_nr_inst);
if(NFAPI_MODE == NFAPI_MODE_PNF)
RC.nb_nr_inst = 1;
for (inst=0; inst<RC.nb_nr_inst; inst++) {
LOG_I(PHY,"RC.nb_nr_CC[inst:%d]:%p\n", inst, RC.gNB[inst]);
gNB = RC.gNB[inst];
@@ -535,6 +535,7 @@ void init_gNB(int single_thread_flag,int wait_for_sync) {
gNB->UL_INFO.cqi_ind.cqi_raw_pdu_list = gNB->cqi_raw_pdu_list;*/
gNB->prach_energy_counter = 0;
gNB->prb_interpolation = get_softmodem_params()->prb_interpolation;
}
+4 -2
View File
@@ -64,6 +64,7 @@
#define CONFIG_HLP_NOSNGLT "Disables single-thread mode in lte-softmodem\n"
#define CONFIG_HLP_TADV "Set timing_advance\n"
#define CONFIG_HLP_DLF "Set the downlink frequency for all component carriers\n"
#define CONFIG_HLP_ULOFF "Set the uplink frequnecy offset for all component carriers\n"
#define CONFIG_HLP_CHOFF "Channel id offset\n"
#define CONFIG_HLP_SOFTS "Enable soft scope and L1 and L2 stats (Xforms)\n"
#define CONFIG_HLP_EXMCAL "Calibrate the EXMIMO borad, available files: exmimo2_2arxg.lime exmimo2_2brxg.lime \n"
@@ -71,13 +72,14 @@
#define CONFIG_HLP_DLMCS_PHYTEST "Set the downlink MCS for PHYTEST mode\n"
#define CONFIG_HLP_DLNL_PHYTEST "Set the downlink nrOfLayers for PHYTEST mode\n"
#define CONFIG_HLP_STMON "Enable processing timing measurement of lte softmodem on per subframe basis \n"
#define CONFIG_HLP_PRB "Set the PRB, valid values: 6, 25, 50, 100 \n"
#define CONFIG_HLP_MSLOTS "Skip the missed slots/subframes \n"
#define CONFIG_HLP_ULMCS_PHYTEST "Set the uplink MCS for PHYTEST mode\n"
#define CONFIG_HLP_DLBW_PHYTEST "Set the number of PRBs used for DLSCH in PHYTEST mode\n"
#define CONFIG_HLP_ULBW_PHYTEST "Set the number of PRBs used for ULSCH in PHYTEST mode\n"
#define CONFIG_HLP_PRB_SA "Set the number of PRBs for SA\n"
#define CONFIG_HLP_DLBM_PHYTEST "Bitmap for DLSCH slots (slot 0 starts at LSB)\n"
#define CONFIG_HLP_ULBM_PHYTEST "Bitmap for ULSCH slots (slot 0 starts at LSB)\n"
#define CONFIG_HLP_SSC "Set the start subcarrier \n"
#define CONFIG_HLP_TDD "Set hardware to TDD mode (default: FDD). Used only with -U (otherwise set in config file).\n"
#define CONFIG_HLP_UE "Set the lte softmodem as a UE\n"
#define CONFIG_HLP_L2MONW "Enable L2 wireshark messages on localhost \n"
@@ -119,7 +121,7 @@
{"g" , CONFIG_HLP_LOGL, 0, uptr:&glog_level, defintval:0, TYPE_UINT, 0}, \
{"G" , CONFIG_HLP_LOGV, 0, uptr:&glog_verbosity, defintval:0, TYPE_UINT16, 0}, \
{"telnetsrv", CONFIG_HLP_TELN, PARAMFLAG_BOOL, uptr:&start_telnetsrv, defintval:0, TYPE_UINT, 0}, \
{"msc", CONFIG_HLP_MSC, PARAMFLAG_BOOL, uptr:&START_MSC, defintval:0, TYPE_UINT, 0}, \
{"msc", CONFIG_HLP_MSC, PARAMFLAG_BOOL, uptr:&START_MSC, defintval:0, TYPE_UINT, 0}, \
}
#define CMDLINE_ONLINELOG_IDX 0
+2 -1
View File
@@ -823,7 +823,8 @@ int main( int argc, char **argv ) {
}
printf("About to call end_configmodule() from %s() %s:%d\n", __FUNCTION__, __FILE__, __LINE__);
end_configmodule();
// We have to set PARAMFLAG_NOFREE on right paramters before re-enabling end_configmodule()
//end_configmodule();
printf("Called end_configmodule() from %s() %s:%d\n", __FUNCTION__, __FILE__, __LINE__);
// wait for end of program
printf("TYPE <CTRL-C> TO TERMINATE\n");
+12 -9
View File
@@ -222,7 +222,7 @@ static void UE_synch(void *arg) {
uint64_t dl_carrier, ul_carrier;
nr_get_carrier_frequencies(&UE->frame_parms, &dl_carrier, &ul_carrier);
if (nr_initial_sync(&syncD->proc, UE, 2) == 0) {
if (nr_initial_sync(&syncD->proc, UE, 2, get_softmodem_params()->sa, get_nrUE_params()->nr_dlsch_parallel) == 0) {
freq_offset = UE->common_vars.freq_offset; // frequency offset computed with pss in initial sync
hw_slot_offset = ((UE->rx_offset<<1) / UE->frame_parms.samples_per_subframe * UE->frame_parms.slots_per_subframe) +
round((float)((UE->rx_offset<<1) % UE->frame_parms.samples_per_subframe)/UE->frame_parms.samples_per_slot0);
@@ -717,15 +717,18 @@ void *UE_thread(void *arg) {
if (openair0_cfg[0].duplex_mode == duplex_mode_TDD) {
uint8_t tdd_period = mac->phy_config.config_req.tdd_table.tdd_period_in_slots;
uint8_t tdd_period = mac->phy_config.config_req.tdd_table.tdd_period_in_slots;
int nrofUplinkSlots, nrofUplinkSymbols;
if (mac->scc) {
nrofUplinkSlots = mac->scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots;
nrofUplinkSymbols = mac->scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols;
}
else {
nrofUplinkSlots = mac->scc_SIB->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots;
nrofUplinkSymbols = mac->scc_SIB->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols;
}
uint8_t num_UL_slots = nrofUplinkSlots + (nrofUplinkSymbols != 0);
int nrofUplinkSlots = 0;
if (mac->scc_SIB)
nrofUplinkSlots = mac->scc_SIB->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots;
else if (mac->scc)
nrofUplinkSlots = mac->scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots;
uint8_t num_UL_slots = nrofUplinkSlots + (nrofUplinkSlots != 0);
uint8_t first_tx_slot = tdd_period - num_UL_slots;
if (slot_tx_usrp % tdd_period == first_tx_slot)
+23 -28
View File
@@ -33,6 +33,7 @@
//#include "common/utils/threadPool/thread-pool.h"
#include "common/utils/load_module_shlib.h"
//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all
#include "common/utils/nr/nr_common.h"
#include "../../ARCH/COMMON/common_lib.h"
#include "../../ARCH/ETHERNET/USERSPACE/LIB/if_defs.h"
@@ -252,6 +253,7 @@ void init_tpools(uint8_t nun_dlsch_threads) {
}
static void get_options(void) {
nrUE_params.ofdm_offset_divisor = 8;
paramdef_t cmdline_params[] =CMDLINE_NRUEPARAMS_DESC ;
int numparams = sizeof(cmdline_params)/sizeof(paramdef_t);
config_process_cmdline( cmdline_params,numparams,NULL);
@@ -278,7 +280,7 @@ void set_options(int CC_id, PHY_VARS_NR_UE *UE){
UE->mode = normal_txrx;
config_process_cmdline( cmdline_params,numparams,NULL);
config_get(cmdline_params,numparams,NULL);
int pindex = config_paramidx_fromname(cmdline_params,numparams, CALIBRX_OPT);
if ( (cmdline_params[pindex].paramflags & PARAMFLAG_PARAMSET) != 0) UE->mode = rx_calib_ue;
@@ -317,24 +319,20 @@ void set_options(int CC_id, PHY_VARS_NR_UE *UE){
UE->rf_map.card = card_offset;
UE->rf_map.chain = CC_id + chain_offset;
LOG_I(PHY,"Set UE mode %d, UE_fo_compensation %d, UE_scan_carrier %d, UE_no_timing_correction %d \n",
UE->mode, UE->UE_fo_compensation, UE->UE_scan_carrier, UE->no_timing_correction);
LOG_I(PHY,"Set UE mode %d, UE_fo_compensation %d, UE_scan_carrier %d, UE_no_timing_correction %d \n, do_prb_interpolation %d\n",
UE->mode, UE->UE_fo_compensation, UE->UE_scan_carrier, UE->no_timing_correction, UE->prb_interpolation);
// Set FP variables
if (tddflag){
fp->frame_type = TDD;
LOG_I(PHY, "Set UE frame_type %d\n", fp->frame_type);
}
fp->N_RB_DL = N_RB_DL;
LOG_I(PHY, "Set UE N_RB_DL %d\n", N_RB_DL);
LOG_I(PHY, "Set UE nb_rx_antenna %d, nb_tx_antenna %d, threequarter_fs %d\n", fp->nb_antennas_rx, fp->nb_antennas_tx, fp->threequarter_fs);
fp->ofdm_offset_divisor = nrUE_params.ofdm_offset_divisor;
}
void init_openair0(void) {
@@ -466,36 +464,33 @@ int main( int argc, char **argv ) {
for (int CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
PHY_vars_UE_g[0][CC_id] = (PHY_VARS_NR_UE *)malloc(sizeof(PHY_VARS_NR_UE));
UE[CC_id] = PHY_vars_UE_g[0][CC_id];
memset(UE[CC_id],0,sizeof(PHY_VARS_NR_UE));
set_options(CC_id, UE[CC_id]);
NR_UE_MAC_INST_t *mac = get_mac_inst(0);
if(mac->if_module != NULL && mac->if_module->phy_config_request != NULL)
mac->if_module->phy_config_request(&mac->phy_config);
fapi_nr_config_request_t *nrUE_config = &UE[CC_id]->nrUE_config;
if (get_softmodem_params()->sa) { // set frame config to initial values from command line and assume that the SSB is centered on the grid
nrUE_config->ssb_config.scs_common = get_softmodem_params()->numerology;
nrUE_config->carrier_config.dl_grid_size[nrUE_config->ssb_config.scs_common] = UE[CC_id]->frame_parms.N_RB_DL;
nrUE_config->carrier_config.ul_grid_size[nrUE_config->ssb_config.scs_common] = UE[CC_id]->frame_parms.N_RB_DL;
nrUE_config->carrier_config.dl_frequency = (downlink_frequency[0][0] -(6*UE[CC_id]->frame_parms.N_RB_DL*(15000<<nrUE_config->ssb_config.scs_common)))/1000;
nrUE_config->carrier_config.uplink_frequency = (downlink_frequency[0][0] -(6*UE[CC_id]->frame_parms.N_RB_DL*(15000<<nrUE_config->ssb_config.scs_common)))/1000;
nrUE_config->ssb_table.ssb_offset_point_a = (UE[CC_id]->frame_parms.N_RB_DL - 20)>>1;
if (get_softmodem_params()->sa) {
uint16_t nr_band = get_band(downlink_frequency[CC_id][0],uplink_frequency_offset[CC_id][0]);
mac->nr_band = nr_band;
nr_init_frame_parms_ue_sa(&UE[CC_id]->frame_parms,
downlink_frequency[CC_id][0],
uplink_frequency_offset[CC_id][0],
get_softmodem_params()->numerology,
nr_band);
}
else{
if(mac->if_module != NULL && mac->if_module->phy_config_request != NULL)
mac->if_module->phy_config_request(&mac->phy_config);
// Initialize values, will be updated upon SIB1 reception
nrUE_config->cell_config.frame_duplex_type = TDD;
nrUE_config->ssb_table.ssb_mask_list[0].ssb_mask = 0xFFFFFFFF;
nrUE_config->ssb_table.ssb_period = 1;
fapi_nr_config_request_t *nrUE_config = &UE[CC_id]->nrUE_config;
nr_init_frame_parms_ue(&UE[CC_id]->frame_parms, nrUE_config, *mac->scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]);
}
nr_init_frame_parms_ue(&UE[CC_id]->frame_parms, nrUE_config,
mac->scc == NULL ? 78 : *mac->scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]);
init_symbol_rotation(&UE[CC_id]->frame_parms);
init_timeshift_rotation(&UE[CC_id]->frame_parms);
init_nr_ue_vars(UE[CC_id], 0, abstraction_flag);
#ifdef FR2_TEST
+26 -21
View File
@@ -8,7 +8,8 @@
#define CONFIG_HLP_DLSCH_PARA "number of threads for dlsch processing 0 for no parallelization"
#define CONFIG_HLP_DLSCH_PARA "number of threads for dlsch processing 0 for no parallelization\n"
#define CONFIG_HLP_OFFSET_DIV "Divisor for computing OFDM symbol offset in Rx chain (num samples in CP/<the value>). Default value is 8. To set the sample offset to 0, set this value ~ 10e6\n"
/***************************************************************************************************************************************/
/* command line options definitions, CMDLINE_XXXX_DESC macros are used to initialize paramdef_t arrays which are then used as argument
when calling config_get or config_getlist functions */
@@ -29,6 +30,7 @@
{"usrp-args", CONFIG_HLP_USRP_ARGS, 0, strptr:(char **)&usrp_args, defstrval:"type=b200", TYPE_STRING, 0}, \
{"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&single_thread_flag, defintval:1, TYPE_INT, 0}, \
{"dlsch-parallel", CONFIG_HLP_DLSCH_PARA, 0, iptr:(int32_t *)&nrUE_params.nr_dlsch_parallel, defintval:0, TYPE_UINT8, 0}, \
{"offset-divisor", CONFIG_HLP_OFFSET_DIV, 0, uptr:(uint32_t *)&nrUE_params.ofdm_offset_divisor, defuintval:UINT_MAX, TYPE_UINT32, 0}, \
{"nr-dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&nr_dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \
{"V" , CONFIG_HLP_VCD, PARAMFLAG_BOOL, iptr:&vcdflag, defintval:0, TYPE_INT, 0}, \
{"rrc_config_path", CONFIG_HLP_RRC_CFG_PATH,0, strptr:(char **)&rrc_config_path, defstrval:"./", TYPE_STRING, 0} \
@@ -40,31 +42,34 @@
/* optname helpstr paramflags XXXptr defXXXval type numelt */
/*------------------------------------------------------------------------------------------------------------------------------------------*/
#define CMDLINE_NRUE_PHYPARAMS_DESC { \
{ CALIBRX_OPT, CONFIG_HLP_CALUER, 0, iptr:&rx_input_level_dBm, defintval:0, TYPE_INT, 0}, \
{ CALIBRXMED_OPT, CONFIG_HLP_CALUERM, 0, iptr:&rx_input_level_dBm, defintval:0, TYPE_INT, 0}, \
{ CALIBRXBYP_OPT, CONFIG_HLP_CALUERB, 0, iptr:&rx_input_level_dBm, defintval:0, TYPE_INT, 0}, \
{ DBGPRACH_OPT, CONFIG_HLP_DBGUEPR, PARAMFLAG_BOOL, uptr:NULL, defuintval:1, TYPE_INT, 0}, \
{ NOL2CONNECT_OPT, CONFIG_HLP_NOL2CN, PARAMFLAG_BOOL, uptr:NULL, defuintval:1, TYPE_INT, 0}, \
{CALIBPRACH_OPT, CONFIG_HLP_CALPRACH, PARAMFLAG_BOOL, uptr:NULL, defuintval:1, TYPE_INT, 0}, \
{ DUMPFRAME_OPT, CONFIG_HLP_DUMPFRAME, PARAMFLAG_BOOL, iptr:&dumpframe, defintval:0, TYPE_INT, 0}, \
{"ue-rxgain", CONFIG_HLP_UERXG, 0, dblptr:&(rx_gain[0][0]), defdblval:0, TYPE_DOUBLE, 0}, \
{"ue-rxgain-off", CONFIG_HLP_UERXGOFF, 0, dblptr:&rx_gain_off, defdblval:0, TYPE_DOUBLE, 0}, \
{"ue-txgain", CONFIG_HLP_UETXG, 0, dblptr:&(tx_gain[0][0]), defdblval:0, TYPE_DOUBLE, 0}, \
{"ue-nb-ant-rx", CONFIG_HLP_UENANTR, 0, u8ptr:&(fp->nb_antennas_rx), defuintval:1, TYPE_UINT8, 0}, \
{"ue-nb-ant-tx", CONFIG_HLP_UENANTT, 0, u8ptr:&(fp->nb_antennas_tx), defuintval:1, TYPE_UINT8, 0}, \
{"ue-scan-carrier", CONFIG_HLP_UESCAN, PARAMFLAG_BOOL, iptr:&(UE->UE_scan_carrier), defintval:0, TYPE_INT, 0}, \
{"ue-fo-compensation", CONFIG_HLP_UEFO, PARAMFLAG_BOOL, iptr:&(UE->UE_fo_compensation), defintval:0, TYPE_INT, 0}, \
{"ue-max-power", NULL, 0, iptr:&(tx_max_power[0]), defintval:90, TYPE_INT, 0}, \
{"r" , CONFIG_HLP_PRB, 0, uptr:&(N_RB_DL), defuintval:160, TYPE_UINT, 0}, \
{"A" , CONFIG_HLP_TADV, 0, iptr:&(UE->timing_advance), defintval:0, TYPE_INT, 0}, \
{"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, u8ptr:&(fp->threequarter_fs), defintval:0, TYPE_UINT8, 0}, \
{"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, iptr:&tddflag, defintval:0, TYPE_INT, 0}, \
{"ue-timing-correction-disable", CONFIG_HLP_DISABLETIMECORR, PARAMFLAG_BOOL, iptr:&(UE->no_timing_correction), defintval:0, TYPE_INT, 0}, \
{ CALIBRX_OPT, CONFIG_HLP_CALUER, 0, iptr:&rx_input_level_dBm, defintval:0, TYPE_INT, 0}, \
{ CALIBRXMED_OPT, CONFIG_HLP_CALUERM, 0, iptr:&rx_input_level_dBm, defintval:0, TYPE_INT, 0}, \
{ CALIBRXBYP_OPT, CONFIG_HLP_CALUERB, 0, iptr:&rx_input_level_dBm, defintval:0, TYPE_INT, 0}, \
{ DBGPRACH_OPT, CONFIG_HLP_DBGUEPR, PARAMFLAG_BOOL, uptr:NULL, defuintval:1, TYPE_INT, 0}, \
{ NOL2CONNECT_OPT, CONFIG_HLP_NOL2CN, PARAMFLAG_BOOL, uptr:NULL, defuintval:1, TYPE_INT, 0}, \
{ CALIBPRACH_OPT, CONFIG_HLP_CALPRACH, PARAMFLAG_BOOL, uptr:NULL, defuintval:1, TYPE_INT, 0}, \
{ DUMPFRAME_OPT, CONFIG_HLP_DUMPFRAME, PARAMFLAG_BOOL, iptr:&dumpframe, defintval:0, TYPE_INT, 0}, \
{"ue-rxgain", CONFIG_HLP_UERXG, 0, dblptr:&(rx_gain[0][0]), defdblval:0, TYPE_DOUBLE,0}, \
{"ue-rxgain-off", CONFIG_HLP_UERXGOFF, 0, dblptr:&rx_gain_off, defdblval:0, TYPE_DOUBLE,0}, \
{"ue-txgain", CONFIG_HLP_UETXG, 0, dblptr:&(tx_gain[0][0]), defdblval:0, TYPE_DOUBLE,0}, \
{"ue-nb-ant-rx", CONFIG_HLP_UENANTR, 0, u8ptr:&(fp->nb_antennas_rx), defuintval:1, TYPE_UINT8, 0}, \
{"ue-nb-ant-tx", CONFIG_HLP_UENANTT, 0, u8ptr:&(fp->nb_antennas_tx), defuintval:1, TYPE_UINT8, 0}, \
{"ue-scan-carrier", CONFIG_HLP_UESCAN, PARAMFLAG_BOOL, iptr:&(UE->UE_scan_carrier), defintval:0, TYPE_INT, 0}, \
{"ue-fo-compensation", CONFIG_HLP_UEFO, PARAMFLAG_BOOL, iptr:&(UE->UE_fo_compensation), defintval:0, TYPE_INT, 0}, \
{"ue-max-power", NULL, 0, iptr:&(tx_max_power[0]), defintval:90, TYPE_INT, 0}, \
{"A" , CONFIG_HLP_TADV, 0, iptr:&(UE->timing_advance), defintval:0, TYPE_INT, 0}, \
{"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, u8ptr:&(fp->threequarter_fs), defintval:0, TYPE_UINT8, 0}, \
{"r" , CONFIG_HLP_PRB_SA, 0, iptr:&(fp->N_RB_DL), defintval:106, TYPE_UINT, 0}, \
{"s" , CONFIG_HLP_SSC, 0, u16ptr:&(fp->ssb_start_subcarrier), defintval:516, TYPE_UINT16,0}, \
{"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, iptr:&tddflag, defintval:0, TYPE_INT, 0}, \
{"do-prb-interpolation", CONFIG_HLP_PRBINTER, PARAMFLAG_BOOL, iptr:&(UE->prb_interpolation), defintval:0, TYPE_INT, 0}, \
{"ue-timing-correction-disable", CONFIG_HLP_DISABLETIMECORR, PARAMFLAG_BOOL, iptr:&(UE->no_timing_correction), defintval:0, TYPE_INT, 0}, \
}
typedef struct {
uint64_t optmask; //mask to store boolean config options
uint32_t ofdm_offset_divisor; // Divisor for sample offset computation for each OFDM symbol
uint8_t nr_dlsch_parallel; // number of threads for dlsch decoding, 0 means no parallelization
tpool_t Tpool; // thread pool
} nrUE_params_t;
+8 -4
View File
@@ -72,6 +72,7 @@ extern "C"
#define CONFIG_HLP_DLMCS "Set the maximum downlink MCS\n"
#define CONFIG_HLP_STMON "Enable processing timing measurement of lte softmodem on per subframe basis \n"
#define CONFIG_HLP_256QAM "Use the 256 QAM mcs table for PDSCH\n"
#define CONFIG_HLP_PRBINTER "Do PRB based averaging of channel estimates. Frequency domain linear interpolation by default\n"
#define CONFIG_HLP_NONSTOP "Go back to frame sync mode after 100 consecutive PBCH failures\n"
//#define CONFIG_HLP_NUMUES "Set the number of UEs for the emulation"
@@ -119,6 +120,7 @@ extern "C"
#define SEND_DMRSSYNC softmodem_params.send_dmrs_sync
#define USIM_TEST softmodem_params.usim_test
#define USE_256QAM_TABLE softmodem_params.use_256qam_table
#define PRB_INTERPOLATION softmodem_params.prb_interpolation
#define NFAPI softmodem_params.nfapi
#define NON_STOP softmodem_params.non_stop
@@ -137,8 +139,8 @@ extern int usrp_tx_thread;
{"time-source", CONFIG_HLP_TME, 0, uptr:&TIMING_SOURCE, defintval:0, TYPE_UINT, 0}, \
{"wait-for-sync", NULL, PARAMFLAG_BOOL, iptr:&WAIT_FOR_SYNC, defintval:0, TYPE_INT, 0}, \
{"single-thread-enable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&SINGLE_THREAD_FLAG, defintval:0, TYPE_INT, 0}, \
{"C" , CONFIG_HLP_DLF, 0, u64ptr:&(downlink_frequency[0][0]), defuintval:3619200000, TYPE_UINT64, 0}, \
{"CO" , CONFIG_HLP_ULF, 0, iptr:&(uplink_frequency_offset[0][0]), defintval:0, TYPE_INT, 0}, \
{"C" , CONFIG_HLP_DLF, 0, u64ptr:&(downlink_frequency[0][0]), defuintval:0, TYPE_UINT64, 0}, \
{"CO" , CONFIG_HLP_ULF, 0, iptr:&(uplink_frequency_offset[0][0]), defintval:0, TYPE_INT, 0}, \
{"a" , CONFIG_HLP_CHOFF, 0, iptr:&CHAIN_OFFSET, defintval:0, TYPE_INT, 0}, \
{"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, uptr:(uint32_t *)&do_forms, defintval:0, TYPE_INT8, 0}, \
{"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, iptr:&opp_enabled, defintval:0, TYPE_INT, 0}, \
@@ -153,9 +155,10 @@ extern int usrp_tx_thread;
{"nokrnmod", CONFIG_HLP_NOKRNMOD, PARAMFLAG_BOOL, uptr:&nokrnmod, defintval:0, TYPE_INT, 0}, \
{"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, uptr:&nonbiot, defuintval:0, TYPE_INT, 0}, \
{"use-256qam-table", CONFIG_HLP_256QAM, PARAMFLAG_BOOL, iptr:&USE_256QAM_TABLE, defintval:0, TYPE_INT, 0}, \
{"usrp-tx-thread-config", CONFIG_HLP_USRP_THREAD, 0, iptr:&usrp_tx_thread, defstrval:0, TYPE_INT, 0}, \
{"do-prb-interpolation", CONFIG_HLP_PRBINTER, PARAMFLAG_BOOL, iptr:&PRB_INTERPOLATION, defintval:0, TYPE_INT, 0}, \
{"usrp-tx-thread-config",CONFIG_HLP_USRP_THREAD, 0, iptr:&usrp_tx_thread, defstrval:0, TYPE_INT, 0}, \
{"nfapi", CONFIG_HLP_NFAPI, 0, u8ptr:&nfapi_mode, defintval:0, TYPE_UINT8, 0}, \
{"non-stop", CONFIG_HLP_NONSTOP, PARAMFLAG_BOOL, iptr:&NON_STOP, defintval:0, TYPE_INT, 0}, \
{"non-stop", CONFIG_HLP_NONSTOP, PARAMFLAG_BOOL, iptr:&NON_STOP, defintval:0, TYPE_INT, 0}, \
}
@@ -246,6 +249,7 @@ typedef struct {
int hw_timing_advance;
uint32_t send_dmrs_sync;
int use_256qam_table;
int prb_interpolation;
uint8_t nfapi;
int non_stop;
} softmodem_params_t;
-35
View File
@@ -1,35 +0,0 @@
# Procedure to run nFAPI in 5G NR
## Conributed by 5G Testbed IISC
### Developers: Sudhakar B,Mahesh K,Gokul S,Aniq U.R
## Procedure to Build gNB and UE
The regular commands to build gNB and UE can be used
```
sudo ./build_oai --gNB --UE
```
## Procedure to run NR nFAPI using RF-Simulator
### VNF command
```
sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band78.tm1.106PRB.nfapi.conf --nfapi 2 --noS1 --phy-test
```
### PNF command
```
sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/oaiL1.nfapi.usrpx300.conf --nfapi 1 --rfsim --phy-test --rfsimulator.serveraddr server
```
### UE command
```
sudo RFSIMULATOR=127.0.0.1 ./nr-uesoftmodem --rfsim --phy-test --rrc_config_path . -d
```
## Procedure to run NR nFAPI using Hardware
Will be updated as we have not yet currently tested on hardware
## Notes
* In order to acheive the synchronization between VNF and PNF and receive the P7 messages within the timing window the order in which we should run the modules on different terminals is UE->VNF->PNF
* Currently only downlink is functional and working as we are still working on uplink functionality
+97 -93
View File
@@ -37,8 +37,6 @@
#include "nfapi_pnf.h"
#include "common/ran_context.h"
#include "openair2/PHY_INTERFACE/phy_stub_UE.h"
//#include "openair1/PHY/vars.h"
extern RAN_CONTEXT_t RC;
#include <sys/socket.h>
#include <sys/time.h>
@@ -50,7 +48,7 @@ extern RAN_CONTEXT_t RC;
#include <vendor_ext.h>
#include "fapi_stub.h"
//#include "fapi_l1.h"
#include "common/utils/LOG/log.h"
#include "PHY/INIT/phy_init.h"
@@ -62,7 +60,7 @@ extern RAN_CONTEXT_t RC;
#include <openair1/SCHED/fapi_l1.h>
#include <openair1/PHY/NR_TRANSPORT/nr_transport_proto.h>
#include <targets/RT/USER/lte-softmodem.h>
#include "nfapi/open-nFAPI/pnf/inc/pnf_p7.h"
#define NUM_P5_PHY 2
@@ -70,6 +68,7 @@ extern RAN_CONTEXT_t RC;
extern void phy_init_RU(RU_t *);
extern int config_sync_var;
extern RAN_CONTEXT_t RC;
extern pthread_cond_t nfapi_sync_cond;
extern pthread_mutex_t nfapi_sync_mutex;
@@ -1110,18 +1109,14 @@ int pnf_phy_ul_dci_req(gNB_L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7,
// 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);
//phy_info* phy = (phy_info*)(pnf_p7->user_data);
struct PHY_VARS_gNB_s *gNB = RC.gNB[0];
if (proc ==NULL)
proc = &gNB->proc.L1_proc;
for (int i=0; i<req->numPdus; i++) {
//LOG_D(PHY,"[PNF] HI_DCI0_REQ sfn_sf:%d PDU[%d]\n", NFAPI_SFNSF2DEC(req->sfn_sf), i);
if (req->ul_dci_pdu_list[i].PDUType == 0) {
//LOG_D(PHY,"[PNF] HI_DCI0_REQ sfn_sf:%d PDU[%d] - NFAPI_HI_DCI0_DCI_PDU_TYPE\n", NFAPI_SFNSF2DEC(req->sfn_sf), i);
nfapi_nr_ul_dci_request_pdus_t *ul_dci_req_pdu = &req->ul_dci_pdu_list[i];
int SFN=req->SFN+2;
handle_nfapi_nr_ul_dci_pdu(gNB, SFN, req->Slot, ul_dci_req_pdu);
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);
}
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);
@@ -1181,45 +1176,37 @@ int pnf_phy_dl_tti_req(gNB_L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7,
int sfn = req->SFN;
int slot = req->Slot;
struct PHY_VARS_gNB_s *gNB = RC.gNB[0];
if (proc==NULL)
proc = &gNB->proc.L1_proc;
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdu_list = req->dl_tti_request_body.dl_tti_pdu_list;
if (req->dl_tti_request_body.nPDUs)
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() TX:%d/%d RX:%d/%d; sfn:%d, slot:%d, nGroup:%u, nPDUs: %u, nUE: %u, PduIdx: %u,\n",
__FUNCTION__, proc->frame_tx, proc->slot_tx, proc->frame_rx, proc->slot_rx, // TODO: change subframes to slot
req->SFN,
req->Slot,
req->dl_tti_request_body.nGroup,
req->dl_tti_request_body.nPDUs,
req->dl_tti_request_body.nUe,
req->dl_tti_request_body.PduIdx);
//if (req->dl_tti_request_body.nPDUs)
// NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() TX:%d/%d RX:%d/%d; sfn:%d, slot:%d, nGroup:%u, nPDUs: %u, nUE: %u, PduIdx: %u,\n",
// __FUNCTION__, proc->frame_tx, proc->slot_tx, proc->frame_rx, proc->slot_rx, // TODO: change subframes to slot
// req->SFN,
// req->Slot,
// req->dl_tti_request_body.nGroup,
// req->dl_tti_request_body.nPDUs,
// req->dl_tti_request_body.nUe,
// req->dl_tti_request_body.PduIdx);
for (int i=0; i<req->dl_tti_request_body.nPDUs; i++) {
// TODO: enable after adding gNB PDCCH:
// 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);
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];
memcpy(dl_tti_pdu,&dl_tti_pdu_list[i],sizeof(nfapi_nr_dl_tti_request_pdu_t));
int SFN=sfn+2;
handle_nfapi_nr_pdcch_pdu(gNB, SFN, slot, &dl_tti_pdu->pdcch_pdu);
//dl_tti_pdu_list[i].pdcch_pdu.pdcch_pdu_rel15.numDlDci++; // ?
// NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() pdcch_vars->num_dci:%d\n", __FUNCTION__, pdcch_vars->num_dci);
} 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]);
gNB->pbch_configured=1;
//} else {
// NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() BCH NULL TX PDU SFN/SF:%d PDU_INDEX:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), pdu_index);
//}
} else if (dl_tti_pdu_list[i].PDUType == NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE) {
handle_nfapi_nr_pdcch_pdu(gNB, sfn, slot, &dl_tti_pdu->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]);
gNB->pbch_configured=1;
}
else if (dl_tti_pdu_list[i].PDUType == NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE) {
nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu = &dl_tti_pdu_list[i].pdsch_pdu;
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15_pdu = &pdsch_pdu->pdsch_pdu_rel15;
//nfapi_nr_tx_data_request_t *tx_data = tx_data_request[sfn][slot][rel15_pdu->pduIndex];
nfapi_nr_pdu_t *tx_data = tx_data_request[sfn][slot][0];
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15_pdu = &pdsch_pdu->pdsch_pdu_rel15;
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);
@@ -1232,14 +1219,21 @@ int pnf_phy_dl_tti_req(gNB_L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7,
LOG_E(PHY,"pnf_phy_dl_config_req illegal harq_pid %d\n", harq_pid);
return(-1);
}
//uint8_t *dlsch_sdu = (uint8_t *)tx_data->TLVs[0].value.direct;
uint8_t *dlsch_sdu = nr_tx_pdus[UE_id][harq_pid];
memcpy(dlsch_sdu, tx_data->TLVs[0].value.direct,tx_data->PDU_length);//TODO: Check if required
memcpy(dlsch_sdu, tx_data->TLVs[0].value.direct,tx_data->PDU_length);
//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);
} 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); }
} else {
}
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);
}
}
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);
}
else {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() UNKNOWN:%d\n", __FUNCTION__, dl_tti_pdu_list[i].PDUType);
}
}
@@ -1399,13 +1393,10 @@ int pnf_phy_tx_req(nfapi_pnf_p7_config_t *pnf_p7, nfapi_tx_request_t *req) {
int pnf_phy_ul_tti_req(gNB_L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, nfapi_nr_ul_tti_request_t *req) {
// if (0)LOG_D(PHY,"[PNF] UL_CONFIG_REQ %s() sfn_sf:%d pdu:%d rach_prach_frequency_resources:%d srs_present:%u\n",
// __FUNCTION__,
// NFAPI_SFNSF2DEC(req->sfn_sf),
// req->ul_config_request_body.number_of_pdus,
// req->ul_config_request_body.rach_prach_frequency_resources,
// req->ul_config_request_body.srs_present
// );
LOG_D(PHY,"[PNF] UL_TTI_REQ recvd, writing into structs, SFN/slot:%d.%d pdu:%d \n",
req->SFN,req->Slot,
req->n_pdus
);
if (RC.ru == 0) {
return -1;
@@ -2162,7 +2153,7 @@ void configure_nr_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_add
pnf.phys[0].udp.tx_port = vnf_p7_port;
strcpy(pnf.phys[0].udp.tx_addr, vnf_ip_addr);
strcpy(pnf.phys[0].local_addr, pnf_ip_addr);
printf("%s() VNF:%s:%d PNF_PHY[addr:%s UDP:tx_addr:%s:%u rx:%u]\n",
printf("%s() VNF:%s:%d PNF_PHY[addr:%s UDP:tx_addr:%s:%d rx:%d]\n",
__FUNCTION__,config->vnf_ip_addr, config->vnf_p5_port,
pnf.phys[0].local_addr,
pnf.phys[0].udp.tx_addr, pnf.phys[0].udp.tx_port,
@@ -2213,7 +2204,7 @@ void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr,
pnf.phys[0].udp.tx_port = vnf_p7_port;
strcpy(pnf.phys[0].udp.tx_addr, vnf_ip_addr);
strcpy(pnf.phys[0].local_addr, pnf_ip_addr);
printf("%s() VNF:%s:%d PNF_PHY[addr:%s UDP:tx_addr:%s:%u rx:%u]\n",
printf("%s() VNF:%s:%d PNF_PHY[addr:%s UDP:tx_addr:%s:%d rx:%d]\n",
__FUNCTION__,
config->vnf_ip_addr, config->vnf_p5_port,
pnf.phys[0].local_addr,
@@ -2272,50 +2263,24 @@ void oai_subframe_ind(uint16_t sfn, uint16_t sf) {
}
}
void handle_nr_slot_ind(uint16_t sfn, uint16_t slot) {
long shift_ns,prev_ts_nsec,shift_us;
void oai_slot_ind(uint16_t sfn, uint16_t slot) {
//slow down PNF
LOG_D(PHY,"%s(sfn:%d, slot:%d)\n", __FUNCTION__, sfn, slot);
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
// if (!(sfn == 0 && slot == 0) && ts.tv_nsec > prev_ts_nsec){
// shift_ns = ts.tv_nsec - prev_ts_nsec;
// shift_us = shift_ns/1000;
// printf("previous: %d, current: %d, shift: %d", prev_ts_nsec, ts.tv_nsec, shift_us);
// if(500-shift_us > 0)
// usleep(500-shift_us);
// // usleep(50);
// }
prev_ts_nsec = ts.tv_nsec;
//NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] %s %d.%d (sfn:%u slot:%u) SFN/SLOT(TX):%u\n", __FUNCTION__, ts.tv_sec, ts.tv_nsec, sfn, slot, NFAPI_SFNSLOT2DEC(sfn, slot));
//TODO FIXME - HACK - DJP - using a global to bodge it in
if (p7_config_g != NULL && sync_var==0) {
// DONE: changed for NR x x x x x x x x x x x x x x - - - - - - : x (Frame), - (Slot) (max_numer =2)
uint16_t sfn_slot_tx = sfn<<6 | slot;
// if ((sfn % 100 == 0) && slot==0) { // DOUBT: Why 100?
// struct timespec ts;
// clock_gettime(CLOCK_MONOTONIC, &ts);
// NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] %s %d.%d (sfn:%u slot:%u) SFN/SLOT(TX):%u\n", __FUNCTION__, ts.tv_sec, ts.tv_nsec, sfn, slot, NFAPI_SFNSLOT2DEC(sfn, slot));
// }
//TODO: send p7_config instead of p7_config_g
int slot_ret = nfapi_pnf_p7_slot_ind(p7_config_g, p7_config_g->phy_id, sfn, slot);
//send VNF slot indication, which is aligned with TX thread, so that it can call the scheduler
nfapi_nr_slot_indication_scf_t *ind;
ind = (nfapi_nr_slot_indication_scf_t *) malloc(sizeof(nfapi_nr_slot_indication_scf_t));
uint8_t slot_ahead = 6;
uint32_t sfn_slot_tx = sfnslot_add_slot(sfn, slot, slot_ahead);
uint16_t sfn_tx = NFAPI_SFNSLOT2SFN(sfn_slot_tx);
uint8_t slot_tx = NFAPI_SFNSLOT2SLOT(sfn_slot_tx);
// if (subframe_ret) {
if (slot_ret) {
NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] %s(frame:%u slot:%u) SFN/SLOT(TX):%u - PROBLEM with pnf_p7_slot_ind()\n", __FUNCTION__, sfn, slot, sfn_slot_tx, NFAPI_SFNSLOT2DEC(sfn, slot));
// printing anything causes error: probably because there isn't enough time to accomodate a print statement
} else {
//NFAPI_TRACE(NFAPI_TRACE_INFO, "***NFAPI subframe handler finished *** \n");
}
} else {
}
ind->sfn = sfn_tx;
ind->slot = slot_tx;
oai_nfapi_nr_slot_indication(ind);
//copy data from appropriate p7 slot buffers into channel structures for PHY processing
nfapi_pnf_p7_slot_ind(p7_config_g, p7_config_g->phy_id, sfn, slot);
return;
}
int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind) {
@@ -2366,3 +2331,42 @@ int oai_nfapi_sr_indication(nfapi_sr_indication_t *ind) {
//free(ind.rx_indication_body.rx_pdu_list);
return retval;
}
//NR UPLINK INDICATION
int oai_nfapi_nr_slot_indication(nfapi_nr_slot_indication_scf_t *ind) {
ind->header.phy_id = 1;
ind->header.message_id = NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION;
return nfapi_pnf_p7_nr_slot_ind(p7_config_g, ind);
}
int oai_nfapi_nr_rx_data_indication(nfapi_nr_rx_data_indication_t *ind) {
ind->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
ind->header.message_id = NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION;
return nfapi_pnf_p7_nr_rx_data_ind(p7_config_g, ind);
}
int oai_nfapi_nr_crc_indication(nfapi_nr_crc_indication_t *ind) {
ind->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
ind->header.message_id = NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION;
return nfapi_pnf_p7_nr_crc_ind(p7_config_g, ind);
}
int oai_nfapi_nr_srs_indication(nfapi_nr_srs_indication_t *ind) {
ind->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
ind->header.message_id = NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION;
return nfapi_pnf_p7_nr_srs_ind(p7_config_g, ind);
}
int oai_nfapi_nr_uci_indication(nfapi_nr_uci_indication_t *ind) {
ind->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
ind->header.message_id = NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION;
return nfapi_pnf_p7_nr_uci_ind(p7_config_g, ind);
}
int oai_nfapi_nr_rach_indication(nfapi_nr_rach_indication_t *ind) {
ind->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
ind->header.message_id = NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION;
return nfapi_pnf_p7_nr_rach_ind(p7_config_g, ind);
}
+11 -4
View File
@@ -19,13 +19,20 @@
* contact@openairinterface.org
*/
#if !defined(NFAPI_PNF_H__)
#define NFAPI_PNF_H__
extern nfapi_ue_release_request_body_t release_rntis;
int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind);
void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port);
void configure_nr_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port);
void oai_subframe_ind(uint16_t sfn, uint16_t sf);
void oai_slot_ind(uint16_t sfn, uint16_t slot);
#endif
void handle_nr_slot_ind(uint16_t sfn, uint16_t slot);
uint32_t sfnslot_add_slot(uint16_t sfn, uint16_t slot, int offset);
int oai_nfapi_nr_slot_indication(nfapi_nr_slot_indication_scf_t *ind);
int oai_nfapi_nr_rx_data_indication(nfapi_nr_rx_data_indication_t *ind);
int oai_nfapi_nr_crc_indication(nfapi_nr_crc_indication_t *ind);
int oai_nfapi_nr_srs_indication(nfapi_nr_srs_indication_t *ind);
int oai_nfapi_nr_uci_indication(nfapi_nr_uci_indication_t *ind);
int oai_nfapi_nr_rach_indication(nfapi_nr_rach_indication_t *ind);
+141 -5
View File
@@ -33,10 +33,10 @@
#include "nfapi_nr_interface_scf.h"
#include "nfapi_vnf_interface.h"
#include "nfapi_vnf.h"
#include "nfapi.h"
#include "vendor_ext.h"
#include "nfapi_vnf.h"
#include "PHY/defs_eNB.h"
#include "PHY/LTE_TRANSPORT/transport_proto.h"
#include "openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
@@ -239,6 +239,18 @@ void oai_enb_init(void) {
void oai_create_gnb(void) {
int bodge_counter=0;
if (RC.gNB == NULL) {
RC.gNB = (PHY_VARS_gNB **) calloc(1, sizeof(PHY_VARS_gNB *));
LOG_I(PHY,"gNB L1 structure RC.gNB allocated @ %p\n",RC.gNB);
}
if (RC.gNB[0] == NULL) {
RC.gNB[0] = (PHY_VARS_gNB *) calloc(1, sizeof(PHY_VARS_gNB));
LOG_I(PHY,"[nr-gnb.c] gNB structure RC.gNB[%d] allocated @ %p\n",0,RC.gNB[0]);
}
PHY_VARS_gNB *gNB = RC.gNB[0];
RC.nb_nr_CC = (int *)malloc(sizeof(int)); // TODO: find a better function to place this in
@@ -584,7 +596,7 @@ extern pthread_mutex_t nfapi_sync_mutex;
extern int nfapi_sync_var;
int phy_sync_indication(struct nfapi_vnf_p7_config *config, uint8_t sync) {
printf("[VNF] SYNC %s\n", sync==1 ? "ACHIEVED" : "LOST");
//printf("[VNF] SYNC %s\n", sync==1 ? "ACHIEVED" : "LOST");
if (sync==1 && nfapi_sync_var!=0) {
@@ -1002,6 +1014,124 @@ int phy_cqi_indication(struct nfapi_vnf_p7_config *config, nfapi_cqi_indication_
return 1;
}
//NR phy indication
int phy_nr_slot_indication(nfapi_nr_slot_indication_scf_t *ind) {
uint8_t vnf_slot_ahead = 2;
uint32_t vnf_sfn_slot = sfnslot_add_slot(ind->sfn, ind->slot, vnf_slot_ahead);
uint16_t vnf_sfn = NFAPI_SFNSLOT2SFN(vnf_sfn_slot);
uint8_t vnf_slot = NFAPI_SFNSLOT2SLOT(vnf_sfn_slot); //offsetting the vnf from pnf by vnf_slot_head slots
struct PHY_VARS_gNB_s *gNB = RC.gNB[0];
pthread_mutex_lock(&gNB->UL_INFO_mutex);
gNB->UL_INFO.frame = vnf_sfn;
gNB->UL_INFO.slot = vnf_slot;
pthread_mutex_unlock(&gNB->UL_INFO_mutex);
LOG_D(MAC, "VNF SFN/Slot %d.%d \n", gNB->UL_INFO.frame, gNB->UL_INFO.slot);
return 1;
}
int phy_nr_crc_indication(nfapi_nr_crc_indication_t *ind) {
struct PHY_VARS_gNB_s *gNB = RC.gNB[0];
pthread_mutex_lock(&gNB->UL_INFO_mutex);
gNB->UL_INFO.crc_ind = *ind;
if (ind->number_crcs > 0)
gNB->UL_INFO.crc_ind.crc_list = malloc(sizeof(nfapi_nr_crc_t)*ind->number_crcs);
for (int i=0; i<ind->number_crcs; i++)
memcpy(&gNB->UL_INFO.crc_ind.crc_list[i], &ind->crc_list[i], sizeof(ind->crc_list[0]));
pthread_mutex_unlock(&gNB->UL_INFO_mutex);
return 1;
}
int phy_nr_rx_data_indication(nfapi_nr_rx_data_indication_t *ind) {
struct PHY_VARS_gNB_s *gNB = RC.gNB[0];
pthread_mutex_lock(&gNB->UL_INFO_mutex);
gNB->UL_INFO.rx_ind = *ind;
if (ind->number_of_pdus > 0)
gNB->UL_INFO.rx_ind.pdu_list = malloc(sizeof(nfapi_nr_rx_data_pdu_t)*ind->number_of_pdus);
for (int i=0; i<ind->number_of_pdus; i++)
memcpy(&gNB->UL_INFO.rx_ind.pdu_list[i], &ind->pdu_list[i], sizeof(ind->pdu_list[0]));
pthread_mutex_unlock(&gNB->UL_INFO_mutex);
return 1;
}
int phy_nr_uci_indication(nfapi_nr_uci_indication_t *ind) {
struct PHY_VARS_gNB_s *gNB = RC.gNB[0];
pthread_mutex_lock(&gNB->UL_INFO_mutex);
gNB->UL_INFO.uci_ind = *ind;
if (ind->num_ucis > 0)
gNB->UL_INFO.uci_ind.uci_list = malloc(sizeof(nfapi_nr_uci_t)*ind->num_ucis);
for (int i=0; i<ind->num_ucis; i++)
memcpy(&gNB->UL_INFO.uci_ind.uci_list[i], &ind->uci_list[i], sizeof(ind->uci_list[0]));
//printf("UCI ind written to UL_info: num_ucis: %d, PDU_type : %d. \n", ind->num_ucis, ind->uci_list[0].pdu_type);
pthread_mutex_unlock(&gNB->UL_INFO_mutex);
return 1;
}
int phy_nr_srs_indication(nfapi_nr_srs_indication_t *ind) {
struct PHY_VARS_gNB_s *gNB = RC.gNB[0];
pthread_mutex_lock(&gNB->UL_INFO_mutex);
gNB->UL_INFO.srs_ind = *ind;
if (ind->number_of_pdus > 0)
gNB->UL_INFO.srs_ind.pdu_list = malloc(sizeof(nfapi_nr_srs_indication_pdu_t)*ind->number_of_pdus);
for (int i=0; i<ind->number_of_pdus; i++) {
memcpy(&gNB->UL_INFO.srs_ind.pdu_list[i], &ind->pdu_list[i], sizeof(ind->pdu_list[0]));
LOG_D(MAC, "%s() NFAPI SFN/Slot:%d.%d SRS_IND:number_of_pdus:%d UL_INFO:pdus:%d\n",
__FUNCTION__,
ind->sfn,ind->slot, ind->number_of_pdus, gNB->UL_INFO.srs_ind.number_of_pdus
);
}
pthread_mutex_unlock(&gNB->UL_INFO_mutex);
return 1;
}
int phy_nr_rach_indication(nfapi_nr_rach_indication_t *ind) {
struct PHY_VARS_gNB_s *gNB = RC.gNB[0];
pthread_mutex_lock(&gNB->UL_INFO_mutex);
gNB->UL_INFO.rach_ind = *ind;
if (ind->number_of_pdus > 0)
gNB->UL_INFO.rach_ind.pdu_list = malloc(sizeof(nfapi_nr_prach_indication_pdu_t)*ind->number_of_pdus);
for (int i=0; i<ind->number_of_pdus; i++) {
memcpy(&gNB->UL_INFO.rach_ind.pdu_list[i], &ind->pdu_list[i], sizeof(ind->pdu_list[0]));
LOG_D(MAC, "%s() NFAPI SFN/Slot:%d.%d RACH_IND:number_of_pdus:%d UL_INFO:pdus:%d\n",
__FUNCTION__,
ind->sfn,ind->slot, ind->number_of_pdus, gNB->UL_INFO.rach_ind.number_of_pdus
);
}
pthread_mutex_unlock(&gNB->UL_INFO_mutex);
return 1;
}
//end NR phy indication
int phy_lbt_dl_indication(struct nfapi_vnf_p7_config *config, nfapi_lbt_dl_indication_t *ind) {
// vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data);
//mac_lbt_dl_ind(p7_vnf->mac, ind);
@@ -1167,6 +1297,12 @@ void *vnf_nr_p7_thread_start(void *ptr) {
p7_vnf->config->lbt_dl_indication = &phy_lbt_dl_indication;
p7_vnf->config->nb_harq_indication = &phy_nb_harq_indication;
p7_vnf->config->nrach_indication = &phy_nrach_indication;
p7_vnf->config->nr_crc_indication = &phy_nr_crc_indication;
p7_vnf->config->nr_slot_indication = &phy_nr_slot_indication;
p7_vnf->config->nr_rx_data_indication = &phy_nr_rx_data_indication;
p7_vnf->config->nr_uci_indication = &phy_nr_uci_indication;
p7_vnf->config->nr_rach_indication = &phy_nr_rach_indication;
p7_vnf->config->nr_srs_indication = &phy_nr_srs_indication;
p7_vnf->config->malloc = &vnf_allocate;
p7_vnf->config->free = &vnf_deallocate;
p7_vnf->config->trace = &vnf_trace;
@@ -1501,8 +1637,8 @@ void configure_nr_nfapi_vnf(char *vnf_addr, int vnf_p5_port) {
nfapi_setmode(NFAPI_MODE_VNF);
memset(&vnf, 0, sizeof(vnf));
memset(vnf.p7_vnfs, 0, sizeof(vnf.p7_vnfs));
vnf.p7_vnfs[0].timing_window = 32;
vnf.p7_vnfs[0].periodic_timing_enabled = 1;
vnf.p7_vnfs[0].timing_window = 30;
vnf.p7_vnfs[0].periodic_timing_enabled = 0;
vnf.p7_vnfs[0].aperiodic_timing_enabled = 0;
vnf.p7_vnfs[0].periodic_timing_period = 10;
vnf.p7_vnfs[0].config = nfapi_vnf_p7_config_create();
@@ -1620,7 +1756,7 @@ int oai_nfapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req)
//LOG_I(PHY, "sfn:%d,slot:%d\n",dl_config_req->SFN,dl_config_req->Slot);
//printf("\nEntering oai_nfapi_nr_dl_config_req sfn:%d,slot:%d\n",dl_config_req->SFN,dl_config_req->Slot);
nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config;
dl_config_req->header.message_id= NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST;
dl_config_req->header.message_id= NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST;
dl_config_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
int retval = nfapi_vnf_p7_nr_dl_config_req(p7_config, dl_config_req);
+3 -3
View File
@@ -19,9 +19,9 @@
* contact@openairinterface.org
*/
#if !defined(NFAPI_VNF_H__)
#define NFAPI_VNF_H__
void configure_nfapi_vnf(char *vnf_addr, int vnf_p5_port);
void configure_nr_nfapi_vnf(char *vnf_addr, int vnf_p5_port);
#endif
uint32_t sfnslot_add_slot(uint16_t sfn, uint16_t slot, int offset);
+76 -76
View File
@@ -1,76 +1,76 @@
/*
* Copyright 2017 Cisco Systems, Inc.
*
* Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
*
* 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.
*/
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/types.h>
#include <pthread.h>
#include <syslog.h>
#include <debug.h>
#define MAX_MSG_LENGTH 2096
#define TRACE_HEADER_LENGTH 44
void nfapi_trace_dbg(nfapi_trace_level_t level, const char *format, ...);
// initialize the trace function to 0
void (*nfapi_trace_g)(nfapi_trace_level_t level, const char* format, ...) = &nfapi_trace_dbg;
nfapi_trace_level_t nfapi_trace_level_g = NFAPI_TRACE_INFO;
//nfapi_trace_level_t nfapi_trace_level_g = NFAPI_TRACE_WARN;
void nfapi_set_trace_level(nfapi_trace_level_t new_level)
{
nfapi_trace_level_g = new_level;
}
void nfapi_trace_dbg(nfapi_trace_level_t level, const char *format, ...)
{
char trace_buff[MAX_MSG_LENGTH + TRACE_HEADER_LENGTH];
uint32_t num_chars;
va_list p_args;
struct timeval tv;
pthread_t tid = pthread_self();
(void)gettimeofday(&tv, NULL);
num_chars = (uint32_t)snprintf(trace_buff, TRACE_HEADER_LENGTH, "%04u.%06u: 0x%02x: %10u: ", ((uint32_t)tv.tv_sec) & 0x1FFF, (uint32_t)tv.tv_usec, (uint32_t)level, (uint32_t)tid);
if (num_chars > TRACE_HEADER_LENGTH)
{
printf("trace_dbg: Error, num_chars is too large: %u", num_chars);
return;
}
va_start(p_args, format);
if ((num_chars = (uint32_t)vsnprintf(&trace_buff[num_chars], MAX_MSG_LENGTH, format, p_args)))
{
if (level <= NFAPI_TRACE_WARN)
{
printf("%s", trace_buff);
}
printf("%s", trace_buff);
}
va_end(p_args);
}
/*
* Copyright 2017 Cisco Systems, Inc.
*
* Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
*
* 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.
*/
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/types.h>
#include <pthread.h>
#include <syslog.h>
#include <debug.h>
#define MAX_MSG_LENGTH 2096
#define TRACE_HEADER_LENGTH 44
void nfapi_trace_dbg(nfapi_trace_level_t level, const char *format, ...);
// initialize the trace function to 0
void (*nfapi_trace_g)(nfapi_trace_level_t level, const char* format, ...) = &nfapi_trace_dbg;
nfapi_trace_level_t nfapi_trace_level_g = NFAPI_TRACE_INFO;
//nfapi_trace_level_t nfapi_trace_level_g = NFAPI_TRACE_WARN;
void nfapi_set_trace_level(nfapi_trace_level_t new_level)
{
nfapi_trace_level_g = new_level;
}
void nfapi_trace_dbg(nfapi_trace_level_t level, const char *format, ...)
{
char trace_buff[MAX_MSG_LENGTH + TRACE_HEADER_LENGTH];
uint32_t num_chars;
va_list p_args;
struct timeval tv;
pthread_t tid = pthread_self();
(void)gettimeofday(&tv, NULL);
num_chars = (uint32_t)snprintf(trace_buff, TRACE_HEADER_LENGTH, "%04u.%06u: 0x%02x: %10u: ", ((uint32_t)tv.tv_sec) & 0x1FFF, (uint32_t)tv.tv_usec, (uint32_t)level, (uint32_t)tid);
if (num_chars > TRACE_HEADER_LENGTH)
{
printf("trace_dbg: Error, num_chars is too large: %d", num_chars);
return;
}
va_start(p_args, format);
if ((num_chars = (uint32_t)vsnprintf(&trace_buff[num_chars], MAX_MSG_LENGTH, format, p_args)))
{
if (level <= NFAPI_TRACE_WARN)
{
printf("%s", trace_buff);
}
printf("%s", trace_buff);
}
va_end(p_args);
}
@@ -673,6 +673,7 @@ typedef struct {
#define NFAPI_NR_SLOT_INDICATION_PERIOD_NUMEROLOGY_3 125 //us
typedef struct {
nfapi_p7_message_header_t header;
uint16_t sfn; //0->1023
uint16_t slot;//0->319
@@ -1492,10 +1493,11 @@ typedef struct
typedef struct
{
nfapi_p7_message_header_t header;
uint16_t sfn;
uint16_t slot;
uint16_t number_of_pdus;
nfapi_nr_rx_data_pdu_t* pdu_list;
nfapi_nr_rx_data_pdu_t *pdu_list;
} nfapi_nr_rx_data_indication_t;
@@ -1518,6 +1520,7 @@ typedef struct
typedef struct
{
nfapi_p7_message_header_t header;
uint16_t sfn;
uint16_t slot;
uint16_t number_crcs;
@@ -1653,6 +1656,7 @@ typedef struct
typedef struct
{
nfapi_p7_message_header_t header;
uint16_t sfn;
uint16_t slot;
uint16_t num_ucis;
@@ -1689,6 +1693,7 @@ typedef struct
typedef struct
{
nfapi_p7_message_header_t header;
uint16_t sfn;
uint16_t slot;
uint8_t number_of_pdus;
@@ -1721,6 +1726,7 @@ typedef struct{
typedef struct
{
nfapi_p7_message_header_t header;
uint16_t sfn;
uint16_t slot;
uint8_t number_of_pdus;
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+8 -1
View File
@@ -153,10 +153,17 @@ int pnf_p7_send_message(pnf_p7_t* pnf_p7, uint8_t* msg, uint32_t msg_len);
int pnf_p7_slot_ind(pnf_p7_t* config, uint16_t phy_id, uint16_t sfn, uint16_t slot);
int pnf_p7_subframe_ind(pnf_p7_t* config, uint16_t phy_id, uint16_t sfn_sf);
int nfapi_pnf_p7_nr_slot_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_slot_indication_scf_t* ind);
int nfapi_pnf_p7_nr_rx_data_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_rx_data_indication_t* ind);
int nfapi_pnf_p7_nr_crc_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_crc_indication_t* ind);
int nfapi_pnf_p7_nr_srs_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_srs_indication_t* ind);
int nfapi_pnf_p7_nr_uci_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_uci_indication_t* ind);
int nfapi_pnf_p7_nr_rach_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_rach_indication_t* ind);
pnf_p7_rx_message_t* pnf_p7_rx_reassembly_queue_add_segment(pnf_p7_t* pnf_p7, pnf_p7_rx_reassembly_queue_t* queue, uint32_t rx_hr_time, uint16_t sequence_number, uint16_t segment_number, uint8_t m, uint8_t* data, uint16_t data_len);
void pnf_p7_rx_reassembly_queue_remove_msg(pnf_p7_t* pnf_p7, pnf_p7_rx_reassembly_queue_t* queue, pnf_p7_rx_message_t* msg);
void pnf_p7_rx_reassembly_queue_remove_old_msgs(pnf_p7_t* pnf_p7, pnf_p7_rx_reassembly_queue_t* queue, uint32_t rx_hr_time, uint32_t delta);
int pnf_nr_p7_pack_and_send_p7_message(pnf_p7_t* pnf_p7, nfapi_p7_message_header_t* header, uint32_t msg_len);
#endif /* _PNF_P7_H_ */
@@ -27,6 +27,7 @@ extern "C" {
#include <openair2/PHY_INTERFACE/IF_Module.h>
#include "nfapi_nr_interface.h"
#include "nfapi_nr_interface_scf.h"
#include <sys/types.h>
#include "openair1/PHY/defs_gNB.h"
+122 -183
View File
@@ -156,17 +156,16 @@ nfapi_dl_config_request_t* allocate_nfapi_dl_config_request(pnf_p7_t* pnf_p7)
void deallocate_nfapi_dl_tti_request(nfapi_nr_dl_tti_request_t* req, pnf_p7_t* pnf_p7)
{
//printf("%s() SFN/SF:%d %s req:%p pdu_list:%p\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), pnf_p7->_public.codec_config.deallocate ? "DEALLOCATE" : "FREE", req, req->dl_config_request_body.dl_config_pdu_list);
/*
if(pnf_p7->_public.codec_config.deallocate)
{
//nfapi_nr_dl_tti_request_pdu_t *temp = &req->dl_tti_pdu_list;
(pnf_p7->_public.codec_config.deallocate)(req);
}
else
{
free(req);
}
*/
// if(pnf_p7->_public.codec_config.deallocate)
// {
// (pnf_p7->_public.codec_config.deallocate)(req);
// }
// else
// {
// free(req);
// }
pnf_p7_free(pnf_p7, req);
}
@@ -915,14 +914,13 @@ void send_dummy_subframe(pnf_p7_t* pnf_p7, uint16_t sfn_sf)
int pnf_p7_slot_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn, uint16_t slot)
{
{
//This function is aligned with rx sfn/slot
// We could either send an event to the p7 thread have have it run the
// subframe or we could handle it here and lock access to the subframe
// buffers. If we do it on the p7 thread then we run the risk of blocking
// on the udp send.
//
// todo : start a timer to give us more of the 1 ms tick before send back
// the frame
// todo : consider a more efficent lock mechasium
//uint16_t NUM_SLOTS = 20;//10* 2^mu
@@ -935,21 +933,21 @@ int pnf_p7_slot_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn, uint16_t sl
// save the curren time, sfn and slot
pnf_p7->slot_start_time_hr = pnf_get_current_time_hr();
pnf_p7->sfn = sfn;
pnf_p7->slot = slot;
slot_ahead = 6;
uint32_t sfn_slot_tx = sfnslot_add_slot(sfn, slot, slot_ahead);
uint16_t sfn_tx = sfn_slot_tx>>6;
uint16_t slot_tx = sfn_slot_tx & 0X3F;
uint16_t sfn_tx = NFAPI_SFNSLOT2SFN(sfn_slot_tx);
uint8_t slot_tx = NFAPI_SFNSLOT2SLOT(sfn_slot_tx);
// uint32_t tx_sfn_slot_dec = NFAPI_SFNSLOT2DEC(sfn,slot);
uint32_t tx_slot_dec = NFAPI_SFNSLOT2DEC(sfn,slot);
//We align the pnf_p7 sfn/slot with tx sfn/slot, and vnf is synced with pnf_p7 sfn/slot. This is so that the scheduler runs slot_ahead from rx thread.
pnf_p7->sfn = sfn_tx;
pnf_p7->slot = slot_tx;
//uint32_t tx_sfn_slot_dec = NFAPI_SFNSLOT2DEC(sfn_slot_tx);
uint32_t rx_slot_dec = NFAPI_SFNSLOT2DEC(sfn, slot);
uint8_t buffer_index_rx = rx_slot_dec % 20;
uint32_t tx_slot_dec = NFAPI_SFNSLOT2DEC(sfn_tx,slot_tx);
uint8_t buffer_index_tx = tx_slot_dec % 20;
// If the subframe_buffer has been configured
if(pnf_p7->_public.slot_buffer_size!= 0) // for now value is same as sf_buffer_size
@@ -976,28 +974,20 @@ int pnf_p7_slot_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn, uint16_t sl
pnf_p7->slot_shift = 0;
}
uint32_t slot_dec = NFAPI_SFNSLOT2DEC(sfn, slot);
uint8_t buffer_index = slot_dec % pnf_p7->_public.slot_buffer_size;
nfapi_pnf_p7_slot_buffer_t* rx_slot_buffer = &(pnf_p7->slot_buffer[buffer_index_rx]);
nfapi_pnf_p7_slot_buffer_t* slot_buffer = &(pnf_p7->slot_buffer[buffer_index]);
// see where the PNF_P7 slot buffer its getting filled
nfapi_pnf_p7_slot_buffer_t* tx_slot_buffer = &(pnf_p7->slot_buffer[buffer_index_tx]);
uint8_t tx_buffer_index = tx_slot_dec % pnf_p7->_public.slot_buffer_size;
nfapi_pnf_p7_slot_buffer_t* tx_slot_buffer = &(pnf_p7->slot_buffer[tx_buffer_index]);
if (0) NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() shift:%d slot_buffer->sfn_sf:%d tx_slot_buffer->sfn_slot:%d sfn_sf:%d subframe_buffer[buffer_index:%u dl_config_req:%p tx_req:%p] "
"TX:sfn_sf:%d:tx_buffer_index:%d[dl_config_req:%p tx_req:%p]\n",
__FUNCTION__,
pnf_p7->slot_shift,
NFAPI_SFNSLOT2DEC(slot_buffer->sfn, slot_buffer->slot),
NFAPI_SFNSLOT2DEC(tx_slot_buffer->sfn, tx_slot_buffer->slot),
slot_dec, buffer_index, slot_buffer->dl_tti_req, slot_buffer->tx_data_req,
tx_slot_dec, tx_buffer_index, tx_slot_buffer->dl_tti_req, tx_slot_buffer->tx_data_req);
// if (0) NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() shift:%d slot_buffer->sfn_sf:%d tx_slot_buffer->sfn_slot:%d sfn_sf:%d subframe_buffer[buffer_index:%u dl_config_req:%p tx_req:%p] "
// "TX:sfn_sf:%d:tx_buffer_index:%d[dl_config_req:%p tx_req:%p]\n",
// __FUNCTION__,
// pnf_p7->slot_shift,
// NFAPI_SFNSLOT2DEC(rx_slot_buffer->sfn, rx_slot_buffer->slot),
// NFAPI_SFNSLOT2DEC(tx_slot_buffer->sfn, tx_slot_buffer->slot),
// slot_dec, buffer_index_rx, rx_slot_buffer->dl_tti_req, rx_slot_buffer->tx_data_req,
// tx_slot_dec, buffer_index_tx, tx_slot_buffer->dl_tti_req, tx_slot_buffer->tx_data_req);
//TODO: Change later if required
// if the subframe buffer sfn sf is set then we have atlease 1 message
// from the vnf.
// todo : how to handle the messages we don't have, send dummies for
// now
@@ -1006,37 +996,39 @@ int pnf_p7_slot_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn, uint16_t sl
//printf("tx_slot_buff_sfn - %d, tx_slot_buf_slot - %d, sfn_tx = %d, sllot_tx - %d \n",tx_slot_buffer->sfn,tx_slot_buffer->slot,sfn_tx,slot_tx);
// if(tx_slot_buffer->slot == slot_tx && tx_slot_buffer->sfn == sfn_tx)
// {
if(tx_slot_buffer->tx_data_req != 0)
{
if(pnf_p7->_public.tx_data_req_fn)
{
(pnf_p7->_public.tx_data_req_fn)(&(pnf_p7->_public), tx_slot_buffer->tx_data_req);
}
}
else
{
// send dummy
if(pnf_p7->_public.tx_data_req_fn && pnf_p7->_public.dummy_slot.tx_data_req)
{
pnf_p7->_public.dummy_slot.tx_data_req->SFN = sfn_tx;
pnf_p7->_public.dummy_slot.tx_data_req->Slot = slot_tx;
(pnf_p7->_public.tx_data_req_fn)(&(pnf_p7->_public), pnf_p7->_public.dummy_slot.tx_data_req);
}
}
//}
//checking in the tx slot buffers to see if a p7 msg is present. todo: what if it's a mixed slot?
if( tx_slot_buffer->dl_tti_req != 0) // ADDED & TO BYPASS ERROR
if(tx_slot_buffer->tx_data_req != 0 && tx_slot_buffer->tx_data_req->SFN == sfn_tx && tx_slot_buffer->tx_data_req->Slot == slot_tx)
{
if(pnf_p7->_public.tx_data_req_fn)
{
//NFAPI_TRACE(NFAPI_TRACE_INFO, "Calling tx_data_req_fn in SFN/slot %d.%d \n",sfn,slot);
LOG_D(PHY, "Process tx_data SFN/slot %d.%d buffer index: %d \n",sfn_tx,slot_tx,buffer_index_tx);
(pnf_p7->_public.tx_data_req_fn)(&(pnf_p7->_public), tx_slot_buffer->tx_data_req);
}
}
else
{
// send dummy
if(pnf_p7->_public.tx_data_req_fn && pnf_p7->_public.dummy_slot.tx_data_req)
{
pnf_p7->_public.dummy_slot.tx_data_req->SFN = sfn_tx;
pnf_p7->_public.dummy_slot.tx_data_req->Slot = slot_tx;
(pnf_p7->_public.tx_data_req_fn)(&(pnf_p7->_public), pnf_p7->_public.dummy_slot.tx_data_req);
}
}
if(tx_slot_buffer->dl_tti_req != 0 && tx_slot_buffer->dl_tti_req->SFN == sfn_tx && tx_slot_buffer->dl_tti_req->Slot == slot_tx)
{
if(pnf_p7->_public.dl_tti_req_fn)
{
LOG_D(PHY, "Process dl_tti SFN/slot %d.%d buffer index: %d \n",sfn_tx,slot_tx,buffer_index_tx);
(pnf_p7->_public.dl_tti_req_fn)(NULL, &(pnf_p7->_public), tx_slot_buffer->dl_tti_req);
}
}
else
{
// send dummy
@@ -1048,10 +1040,13 @@ int pnf_p7_slot_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn, uint16_t sl
}
}
if(tx_slot_buffer->ul_dci_req!= 0)
if(tx_slot_buffer->ul_dci_req!= 0 && tx_slot_buffer->ul_dci_req->SFN == sfn_tx && tx_slot_buffer->ul_dci_req->Slot == slot_tx)
{
if(pnf_p7->_public.ul_dci_req_fn)
{
//NFAPI_TRACE(NFAPI_TRACE_INFO, "Calling UL_dci_req_fn in SFN/slot %d.%d \n",sfn,slot);
LOG_D(PHY, "Process ul_dci SFN/slot %d.%d buffer index: %d \n",sfn_tx,slot_tx,buffer_index_tx);
(pnf_p7->_public.ul_dci_req_fn)(NULL, &(pnf_p7->_public), tx_slot_buffer->ul_dci_req);
}
}
@@ -1065,10 +1060,14 @@ int pnf_p7_slot_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn, uint16_t sl
(pnf_p7->_public.ul_dci_req_fn)(NULL, &(pnf_p7->_public), pnf_p7->_public.dummy_slot.ul_dci_req);
}
}
//deallocate slot buffers after passing down the PDUs to PHY processing
if(tx_slot_buffer->dl_tti_req != 0)
{
deallocate_nfapi_dl_tti_request(tx_slot_buffer->dl_tti_req, pnf_p7);
tx_slot_buffer->dl_tti_req = 0;
LOG_D(PHY,"SFN/slot %d.%d Buffer index : %d freed \n",sfn_tx,slot_tx,buffer_index_tx);
}
if(tx_slot_buffer->tx_data_req != 0)
@@ -1082,73 +1081,52 @@ int pnf_p7_slot_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn, uint16_t sl
deallocate_nfapi_ul_dci_request(tx_slot_buffer->ul_dci_req, pnf_p7);
tx_slot_buffer->ul_dci_req = 0;
}
//checking in the rx slot buffers to see if a p7 msg is present.
if(rx_slot_buffer->ul_tti_req != 0 && rx_slot_buffer->ul_tti_req->SFN == sfn && rx_slot_buffer->ul_tti_req->Slot == slot)
{
if(pnf_p7->_public.ul_tti_req_fn)
{
//NFAPI_TRACE(NFAPI_TRACE_INFO, "Calling UL_tti_req_fn in SFN/slot %d.%d \n",sfn,slot);
(pnf_p7->_public.ul_tti_req_fn)(NULL, &(pnf_p7->_public), rx_slot_buffer->ul_tti_req);
}
}
else
{
// If we ever need to "send" a dummy ul_config this won't work!!!
// send_dummy_subframe(pnf_p7, sfn_sf_tx);
// send dummy
if(pnf_p7->_public.ul_tti_req_fn && pnf_p7->_public.dummy_slot.ul_tti_req)
{
pnf_p7->_public.dummy_slot.ul_tti_req->SFN = sfn;
pnf_p7->_public.dummy_slot.ul_tti_req->Slot = slot;
LOG_D(PHY, "Process ul_tti SFN/slot %d.%d buffer index: %d \n",sfn,slot,buffer_index_rx);
(pnf_p7->_public.ul_tti_req_fn)(NULL, &(pnf_p7->_public), pnf_p7->_public.dummy_slot.ul_tti_req);
}
}
if(rx_slot_buffer->ul_tti_req != 0)
{
deallocate_nfapi_ul_tti_request(rx_slot_buffer->ul_tti_req, pnf_p7);
rx_slot_buffer->ul_tti_req = 0;
// send_dummy_slot(pnf_p7, sfn_tx, slot_tx);
}
//reset slot buffer
if(slot_buffer->sfn == sfn && slot_buffer->slot == slot )
if ( rx_slot_buffer->dl_tti_req == 0 &&
rx_slot_buffer->tx_data_req == 0 &&
rx_slot_buffer->ul_tti_req == 0)
{
if(slot_buffer->ul_tti_req != 0)
{
if(pnf_p7->_public.ul_tti_req_fn)
{
(pnf_p7->_public.ul_tti_req_fn)(NULL, &(pnf_p7->_public), slot_buffer->ul_tti_req);
}
//deallocate_nfapi_ul_config_request(subframe_buffer->ul_config_req, pnf_p7);
}
else
{
// send dummy
if(pnf_p7->_public.ul_tti_req_fn && pnf_p7->_public.dummy_slot.ul_tti_req)
{
pnf_p7->_public.dummy_slot.ul_tti_req->SFN = sfn;
pnf_p7->_public.dummy_slot.ul_tti_req->Slot = slot;
(pnf_p7->_public.ul_tti_req_fn)(NULL, &(pnf_p7->_public), pnf_p7->_public.dummy_slot.ul_tti_req);
}
}
//if(subframe_buffer->dl_config_req != 0)
//deallocate_nfapi_dl_config_request(subframe_buffer->dl_config_req, pnf_p7);
//if(subframe_buffer->tx_req != 0)
//deallocate_nfapi_tx_request(subframe_buffer->tx_req, pnf_p7);
if(slot_buffer->ul_tti_req != 0)
{
deallocate_nfapi_ul_tti_request(slot_buffer->ul_tti_req, pnf_p7);
slot_buffer->ul_tti_req = 0;
}
#if 0
if(slot_buffer->lbt_dl_config_req != 0)
{
deallocate_nfapi_lbt_dl_config_request(slot_buffer->lbt_dl_config_req, pnf_p7);
slot_buffer->lbt_dl_config_req = 0;
}
#endif
} // sfn_slot match
if ( slot_buffer->dl_tti_req == 0 &&
slot_buffer->tx_data_req == 0 &&
slot_buffer->ul_tti_req == 0)
//slot_buffer->lbt_dl_config_req == 0 &&
//slot_buffer->ue_release_req == 0)
{
memset(&(pnf_p7->slot_buffer[buffer_index]), 0, sizeof(nfapi_pnf_p7_slot_buffer_t));
pnf_p7->slot_buffer[buffer_index].sfn = -1;
pnf_p7->slot_buffer[buffer_index].slot = -1;
memset(&(pnf_p7->slot_buffer[buffer_index_rx]), 0, sizeof(nfapi_pnf_p7_slot_buffer_t));
pnf_p7->slot_buffer[buffer_index_rx].sfn = -1;
pnf_p7->slot_buffer[buffer_index_rx].slot = -1;
}
//printf("pnf_p7->_public.timing_info_mode_periodic:%d pnf_p7->timing_info_period_counter:%d pnf_p7->_public.timing_info_period:%d\n", pnf_p7->_public.timing_info_mode_periodic, pnf_p7->timing_info_period_counter, pnf_p7->_public.timing_info_period);
//printf("pnf_p7->_public.timing_info_mode_aperiodic:%d pnf_p7->timing_info_aperiodic_send:%d\n", pnf_p7->_public.timing_info_mode_aperiodic, pnf_p7->timing_info_aperiodic_send);
//printf("pnf_p7->timing_info_ms_counter:%d\n", pnf_p7->timing_info_ms_counter);
// send the periodic timing info if configured
//send the periodic timing info if configured
if(pnf_p7->_public.timing_info_mode_periodic && (pnf_p7->timing_info_period_counter++) == pnf_p7->_public.timing_info_period)
{
pnf_nr_pack_and_send_timing_info(pnf_p7);
@@ -1167,26 +1145,6 @@ int pnf_p7_slot_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn, uint16_t sl
}
}
else
{
//send_dummy_subframe(pnf_p7, sfn_sf_tx);
}
//printf("pnf_p7->tick:%d\n", pnf_p7->tick);
// if(pnf_p7->tick == 1000) // why?
// {
// // TODO: change stats to nr_stats
// NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF P7:%d] (ONTIME/LATE) DL:(%d/%d) UL:(%d/%d) HI:(%d/%d) TX:(%d/%d)\n", pnf_p7->_public.phy_id,
// pnf_p7->stats.dl_conf_ontime, pnf_p7->stats.dl_conf_late,
// pnf_p7->stats.ul_conf_ontime, pnf_p7->stats.ul_conf_late,
// pnf_p7->stats.hi_dci0_ontime, pnf_p7->stats.hi_dci0_late,
// pnf_p7->stats.tx_ontime, pnf_p7->stats.tx_late);
// pnf_p7->tick = 0;
// memset(&pnf_p7->stats, 0, sizeof(pnf_p7->stats));
// }
// pnf_p7->tick++;
if(pthread_mutex_unlock(&(pnf_p7->mutex)) != 0)
{
@@ -1495,7 +1453,7 @@ uint8_t is_nr_p7_request_in_window(uint16_t sfn,uint16_t slot, const char* name,
{
uint32_t recv_sfn_slot_dec = NFAPI_SFNSLOT2DEC(sfn,slot);
uint32_t current_sfn_slot_dec = NFAPI_SFNSLOT2DEC(phy->sfn,phy->slot);
printf("p7_msg_sfn: %d, p7_msg_slot: %d, phy_sfn:%d , phy_slot:%d \n",sfn,slot,phy->sfn,phy->slot);
//printf("p7_msg_sfn: %d, p7_msg_slot: %d, phy_sfn:%d , phy_slot:%d \n",sfn,slot,phy->sfn,phy->slot);
uint8_t in_window = 0;
uint8_t timing_window = phy->_public.slot_buffer_size;
@@ -1546,11 +1504,11 @@ uint8_t is_nr_p7_request_in_window(uint16_t sfn,uint16_t slot, const char* name,
// }
if(current_sfn_slot_dec <= recv_sfn_slot_dec + timing_window){
in_window = 1;
NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] %s is in window %d\n", current_sfn_slot_dec, name, recv_sfn_slot_dec);
//NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] %s is in window %d\n", current_sfn_slot_dec, name, recv_sfn_slot_dec);
}
else if(current_sfn_slot_dec + NFAPI_MAX_SFNSLOTDEC <= recv_sfn_slot_dec + timing_window){ //checking for wrap
in_window = 1;
NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] %s is in window %d\n", current_sfn_slot_dec, name, recv_sfn_slot_dec);
//NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] %s is in window %d\n", current_sfn_slot_dec, name, recv_sfn_slot_dec);
}
else
@@ -1630,7 +1588,6 @@ void pnf_handle_dl_tti_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7)
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s failed to alloced nfapi_dl_tti_request structure\n");
return;
}
int unpack_result = nfapi_nr_p7_message_unpack(pRecvMsg, recvMsgLen, req, sizeof(nfapi_nr_dl_tti_request_t), &(pnf_p7->_public.codec_config));
if(unpack_result == 0)
@@ -1640,34 +1597,18 @@ void pnf_handle_dl_tti_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7)
NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to lock mutex\n");
return;
}
#if 0
if (
0 &&
(NFAPI_SFNSF2DEC(req->sfn_sf) % 100 ==0 ||
NFAPI_SFNSF2DEC(req->sfn_sf) % 105 ==0
)
)
NFAPI_TRACE(NFAPI_TRACE_INFO, "DL_CONFIG.req sfn_sf:%d pdcch:%u dci:%u pdu:%u pdsch_rnti:%u pcfich:%u\n",
NFAPI_SFNSF2DEC(req->sfn_sf),
req->dl_config_request_body.number_pdcch_ofdm_symbols,
req->dl_config_request_body.number_dci,
req->dl_config_request_body.number_pdu,
req->dl_config_request_body.number_pdsch_rnti,
req->dl_config_request_body.transmission_power_pcfich
);
#endif
if(is_nr_p7_request_in_window(req->SFN,req->Slot, "dl_tti_request", pnf_p7))
{
uint32_t sfn_slot_dec = NFAPI_SFNSLOT2DEC(req->SFN,req->Slot);
uint8_t buffer_index = sfn_slot_dec % pnf_p7->_public.slot_buffer_size;
if(is_nr_p7_request_in_window(req->SFN,req->Slot, "dl_tti_request", pnf_p7))
{
uint32_t sfn_slot_dec = NFAPI_SFNSLOT2DEC(req->SFN,req->Slot);
uint8_t buffer_index = sfn_slot_dec % 20;
struct timespec t;
clock_gettime(CLOCK_MONOTONIC, &t);
struct timespec t;
clock_gettime(CLOCK_MONOTONIC, &t);
//NFAPI_TRACE(NFAPI_TRACE_INFO,"%s() %ld.%09ld POPULATE DL_TTI_REQ sfn_slot:%d buffer_index:%d\n", __FUNCTION__, t.tv_sec, t.tv_nsec, sfn_slot_dec, buffer_index);
NFAPI_TRACE(NFAPI_TRACE_INFO,"%s() %ld.%09ld POPULATE DL_TTI_REQ current tx sfn/slot:%d.%d p7 msg sfn/slot: %d.%d buffer_index:%d\n", __FUNCTION__, t.tv_sec, t.tv_nsec, pnf_p7->sfn,pnf_p7->slot, req->SFN, req->Slot, buffer_index);
// if there is already an dl_config_req make sure we free it.
// if there is already an dl_tti_req make sure we free it.
if(pnf_p7->slot_buffer[buffer_index].dl_tti_req != 0)
{
NFAPI_TRACE(NFAPI_TRACE_NOTE, "%s() is_nr_p7_request_in_window()=TRUE buffer_index occupied - free it first sfn_slot:%d buffer_index:%d\n", __FUNCTION__, NFAPI_SFNSLOT2DEC(req->SFN,req->Slot), buffer_index);
@@ -1677,7 +1618,7 @@ void pnf_handle_dl_tti_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7)
deallocate_nfapi_dl_tti_request(pnf_p7->slot_buffer[buffer_index].dl_tti_req, pnf_p7);
}
// saving dl_config_request in subframe buffer
// filling dl_tti_request in slot buffer
pnf_p7->slot_buffer[buffer_index].sfn = req->SFN;
pnf_p7->slot_buffer[buffer_index].slot = req->Slot;
pnf_p7->slot_buffer[buffer_index].dl_tti_req = req;
@@ -1826,12 +1767,12 @@ void pnf_handle_ul_tti_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7)
if(is_nr_p7_request_in_window(req->SFN,req->Slot, "ul_tti_request", pnf_p7))
{
uint32_t sfn_slot_dec = NFAPI_SFNSLOT2DEC(req->SFN,req->Slot);
uint8_t buffer_index = sfn_slot_dec % pnf_p7->_public.slot_buffer_size;
uint8_t buffer_index = (sfn_slot_dec % 20);
struct timespec t;
clock_gettime(CLOCK_MONOTONIC, &t);
NFAPI_TRACE(NFAPI_TRACE_INFO,"%s() %ld.%09ld POPULATE UL_TTI_REQ sfn_slot:%d buffer_index:%d\n", __FUNCTION__, t.tv_sec, t.tv_nsec, sfn_slot_dec, buffer_index);
NFAPI_TRACE(NFAPI_TRACE_INFO,"%s() %ld.%09ld POPULATE UL_TTI_REQ current tx sfn/slot:%d.%d p7 msg sfn/slot: %d.%d buffer_index:%d\n", __FUNCTION__, t.tv_sec, t.tv_nsec, pnf_p7->sfn,pnf_p7->slot, req->SFN, req->Slot, buffer_index);
if(pnf_p7->slot_buffer[buffer_index].ul_tti_req != 0)
{
@@ -1841,6 +1782,8 @@ void pnf_handle_ul_tti_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7)
deallocate_nfapi_ul_tti_request(pnf_p7->slot_buffer[buffer_index].ul_tti_req, pnf_p7);
}
//filling slot buffer
pnf_p7->slot_buffer[buffer_index].sfn = req->SFN;
pnf_p7->slot_buffer[buffer_index].slot = req->Slot;
@@ -1972,7 +1915,7 @@ void pnf_handle_ul_dci_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7)
if(is_nr_p7_request_in_window(req->SFN,req->Slot,"ul_dci_request", pnf_p7))
{
uint32_t sfn_slot_dec = NFAPI_SFNSLOT2DEC(req->SFN,req->Slot);
uint8_t buffer_index = sfn_slot_dec % pnf_p7->_public.slot_buffer_size;
uint8_t buffer_index = sfn_slot_dec % 20;
if(pnf_p7->slot_buffer[buffer_index].ul_dci_req!= 0)
{
@@ -2010,7 +1953,7 @@ void pnf_handle_ul_dci_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7)
}
else
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "Failed to unpack hi_dci0_req\n");
NFAPI_TRACE(NFAPI_TRACE_ERROR, "Failed to unpack UL DCI req\n");
deallocate_nfapi_ul_dci_request(req, pnf_p7);
}
}
@@ -2111,12 +2054,12 @@ void pnf_handle_tx_data_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7
if(is_nr_p7_request_in_window(req->SFN, req->Slot,"tx_request", pnf_p7))
{
uint32_t sfn_slot_dec = NFAPI_SFNSLOT2DEC(req->SFN,req->Slot);
uint8_t buffer_index = sfn_slot_dec % pnf_p7->_public.slot_buffer_size;
uint8_t buffer_index = sfn_slot_dec % 20;
struct timespec t;
clock_gettime(CLOCK_MONOTONIC, &t);
NFAPI_TRACE(NFAPI_TRACE_INFO,"%s() %ld.%09ld POPULATE TX_DATA_REQ sfn_sf:%d buffer_index:%d\n", __FUNCTION__, t.tv_sec, t.tv_nsec, sfn_slot_dec, buffer_index);
//NFAPI_TRACE(NFAPI_TRACE_INFO,"%s() %ld.%09ld POPULATE TX_DATA_REQ sfn_sf:%d buffer_index:%d\n", __FUNCTION__, t.tv_sec, t.tv_nsec, sfn_slot_dec, buffer_index);
#if 0
if (0 && NFAPI_SFNSF2DEC(req->sfn_sf)%100==0) NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() TX_REQ.req sfn_sf:%d pdus:%d - TX_REQ is within window\n",
__FUNCTION__,
@@ -2678,9 +2621,7 @@ void pnf_nr_dispatch_p7_message(void *pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7
case NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC:
pnf_nr_handle_dl_node_sync(pRecvMsg, recvMsgLen, pnf_p7, rx_hr_time);
break;
case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST:
//printf("\nEntering pnf_handle_dl_tti_request sfn=%d,slot=%d \n",pnf_p7->sfn,pnf_p7->slot);
pnf_handle_dl_tti_request(pRecvMsg, recvMsgLen, pnf_p7);
break;
case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST:
@@ -2989,13 +2930,11 @@ void pnf_nr_nfapi_p7_read_dispatch_message(pnf_p7_t* pnf_p7, uint32_t now_hr_tim
struct sockaddr_in remote_addr;
socklen_t remote_addr_size = sizeof(remote_addr);
remote_addr.sin_family = 2; //hardcoded
do
{
// peek the header
uint8_t header_buffer[NFAPI_P7_HEADER_LENGTH];
recvfrom_result = recvfrom(pnf_p7->p7_sock, header_buffer, NFAPI_P7_HEADER_LENGTH, MSG_DONTWAIT | MSG_PEEK, (struct sockaddr*)&remote_addr, &remote_addr_size);
if(recvfrom_result > 0)
{
// get the segment size
@@ -3272,7 +3211,7 @@ int pnf_nr_p7_message_pump(pnf_p7_t* pnf_p7)
FD_SET(pnf_p7->p7_sock, &rfds);
struct timeval timeout;
timeout.tv_sec = 1;
timeout.tv_sec = 100;
timeout.tv_usec = 0;
selectRetval = select(pnf_p7->p7_sock+1, &rfds, NULL, NULL, &timeout);
@@ -265,3 +265,77 @@ int nfapi_pnf_ue_release_resp(nfapi_pnf_p7_config_t* config, nfapi_ue_release_re
return pnf_p7_pack_and_send_p7_message(_this, &(resp->header), sizeof(nfapi_ue_release_response_t));
}
//NR UPLINK INDICATION
int nfapi_pnf_p7_nr_slot_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_slot_indication_scf_t* ind)
{
if(config == NULL || ind == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
return -1;
}
pnf_p7_t* _this = (pnf_p7_t*)(config);
return pnf_nr_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_nr_rx_data_indication_t));
}
int nfapi_pnf_p7_nr_rx_data_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_rx_data_indication_t* ind)
{
if(config == NULL || ind == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
return -1;
}
pnf_p7_t* _this = (pnf_p7_t*)(config);
return pnf_nr_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_nr_rx_data_indication_t));
}
int nfapi_pnf_p7_nr_crc_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_crc_indication_t* ind)
{
if(config == NULL || ind == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
return -1;
}
pnf_p7_t* _this = (pnf_p7_t*)(config);
return pnf_nr_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_nr_crc_indication_t));
}
int nfapi_pnf_p7_nr_srs_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_srs_indication_t* ind)
{
if(config == NULL || ind == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
return -1;
}
pnf_p7_t* _this = (pnf_p7_t*)(config);
return pnf_nr_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_nr_srs_indication_t));
}
int nfapi_pnf_p7_nr_uci_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_uci_indication_t* ind)
{
if(config == NULL || ind == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
return -1;
}
pnf_p7_t* _this = (pnf_p7_t*)(config);
return pnf_nr_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_nr_uci_indication_t));
}
int nfapi_pnf_p7_nr_rach_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_rach_indication_t* ind)
{
if(config == NULL || ind == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
return -1;
}
pnf_p7_t* _this = (pnf_p7_t*)(config);
return pnf_nr_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_nr_rach_indication_t));
}
+2 -2
View File
@@ -278,7 +278,7 @@ void *fapi_thread_start(void *ptr) {
if(instance->tick == 1000) {
if(instance->tx_byte_count > 0) {
printf("[FAPI] Tx rate %u bytes/sec\n", instance->tx_byte_count);
printf("[FAPI] Tx rate %d bytes/sec\n", instance->tx_byte_count);
instance->tx_byte_count = 0;
}
@@ -319,7 +319,7 @@ void *fapi_thread_start(void *ptr) {
millisec = now_ts.tv_nsec / 1e6;
if(last_millisec != -1 && ((last_millisec + 1 ) % 1000) != millisec) {
printf("*** missing millisec %u %u\n", last_millisec, millisec);
printf("*** missing millisec %d %d\n", last_millisec, millisec);
catchup = millisec - last_millisec - 1;
}
-1
View File
@@ -25,7 +25,6 @@
#define TIME2TIMEHR(_time) (((uint32_t)(_time.tv_sec) & 0xFFF) << 20 | ((uint32_t)(_time.tv_usec) & 0xFFFFF))
typedef struct {
uint8_t* buffer;
uint16_t length;
@@ -852,7 +852,15 @@ typedef struct nfapi_vnf_p7_config
* use the codec_config.deallocate function to release it at a future point
*/
int (*nrach_indication)(struct nfapi_vnf_p7_config* config, nfapi_nrach_indication_t* ind);
//The NR indication functions below copy uplink information received at the VNF into the UL info struct
int (*nr_slot_indication)(nfapi_nr_slot_indication_scf_t* ind);
int (*nr_crc_indication)(nfapi_nr_crc_indication_t* ind);
int (*nr_rx_data_indication)(nfapi_nr_rx_data_indication_t* ind);
int (*nr_uci_indication)(nfapi_nr_uci_indication_t* ind);
int (*nr_rach_indication)(nfapi_nr_rach_indication_t* ind);
int (*nr_srs_indication)(nfapi_nr_srs_indication_t* ind);
/*! A callback for any vendor extension messages
* \param config A pointer to the vnf p7 configuration
* \param msg A data structure for the decoded vendor extention message allocated
+190 -43
View File
@@ -22,7 +22,7 @@
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include "vnf_p7.h"
#define SYNC_CYCLE_COUNT 2
@@ -456,7 +456,7 @@ int send_mac_subframe_indications(vnf_p7_t* vnf_p7)
int vnf_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_vnf_p7_connection_info_t* p7_info, uint8_t* msg, const uint32_t len)
{
int sendto_result = sendto(vnf_p7->socket, msg, len, 0, (struct sockaddr*)&(p7_info->remote_addr), sizeof(p7_info->remote_addr));
//printf("\nSending p7 message sfn=%d,slot=%d\n",vnf_p7->p7_connections->sfn,vnf_p7->p7_connections->slot);
//printf("P7 msg sent \n");
if(sendto_result != len)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() sendto_result %d %d\n", __FUNCTION__, sendto_result, errno);
@@ -533,6 +533,7 @@ int vnf_nr_p7_pack_and_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_p7_message_header_t*
nfapi_p7_update_transmit_timestamp(buffer, calculate_transmit_timestamp(p7_connection->sfn, p7_connection->slot, vnf_p7->slot_start_time_hr));
send_result = vnf_send_p7_msg(vnf_p7, p7_connection, &tx_buffer[0], segment_size);
}
}
else
@@ -549,7 +550,6 @@ int vnf_nr_p7_pack_and_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_p7_message_header_t*
}
p7_connection->sequence_number++;
return send_result;
}
else
@@ -667,7 +667,6 @@ int vnf_build_send_dl_node_sync(vnf_p7_t* vnf_p7, nfapi_vnf_p7_connection_info_t
int vnf_nr_build_send_dl_node_sync(vnf_p7_t* vnf_p7, nfapi_vnf_p7_connection_info_t* p7_info)
{
nfapi_nr_dl_node_sync_t dl_node_sync;
memset(&dl_node_sync, 0, sizeof(dl_node_sync));
@@ -1290,7 +1289,7 @@ void vnf_handle_ul_node_sync(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
{
if(phy->in_sync == 0)
{
NFAPI_TRACE(NFAPI_TRACE_NOTE, "VNF P7 In Sync with phy (phy_id:%d)\n", phy->phy_id);
//NFAPI_TRACE(NFAPI_TRACE_NOTE, "VNF P7 In Sync with phy (phy_id:%d)\n", phy->phy_id);
if(vnf_p7->_public.sync_indication)
(vnf_p7->_public.sync_indication)(&(vnf_p7->_public), 1);
@@ -1454,6 +1453,161 @@ void vnf_handle_ul_node_sync(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
}
}
//NR HANDLES FOR UPLINK MESSAGES
void vnf_handle_nr_slot_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
{
// ensure it's valid
if (pRecvMsg == NULL || vnf_p7 == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
}
else
{
nfapi_nr_slot_indication_scf_t ind;
if(nfapi_nr_p7_message_unpack(pRecvMsg, recvMsgLen, &ind, sizeof(ind), &vnf_p7->_public.codec_config) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Failed to unpack message\n", __FUNCTION__);
}
else
{
if(vnf_p7->_public.nr_slot_indication)
{
(vnf_p7->_public.nr_slot_indication)(&ind);
}
}
}
}
void vnf_handle_nr_rx_data_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
{
// ensure it's valid
if (pRecvMsg == NULL || vnf_p7 == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
}
else
{
nfapi_nr_rx_data_indication_t ind;
if(nfapi_nr_p7_message_unpack(pRecvMsg, recvMsgLen, &ind, sizeof(ind), &vnf_p7->_public.codec_config) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Failed to unpack message\n", __FUNCTION__);
}
else
{
if(vnf_p7->_public.nr_rx_data_indication)
{
(vnf_p7->_public.nr_rx_data_indication)(&ind);
}
}
}
}
void vnf_handle_nr_crc_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
{
// ensure it's valid
if (pRecvMsg == NULL || vnf_p7 == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
}
else
{
nfapi_nr_crc_indication_t ind;
if(nfapi_nr_p7_message_unpack(pRecvMsg, recvMsgLen, &ind, sizeof(ind), &vnf_p7->_public.codec_config) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Failed to unpack message\n", __FUNCTION__);
}
else
{
if(vnf_p7->_public.nr_crc_indication)
{
(vnf_p7->_public.nr_crc_indication)(&ind);
}
}
}
}
void vnf_handle_nr_srs_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
{
// ensure it's valid
if (pRecvMsg == NULL || vnf_p7 == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
}
else
{
nfapi_nr_srs_indication_t ind;
if(nfapi_nr_p7_message_unpack(pRecvMsg, recvMsgLen, &ind, sizeof(ind), &vnf_p7->_public.codec_config) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Failed to unpack message\n", __FUNCTION__);
}
else
{
if(vnf_p7->_public.nr_srs_indication)
{
(vnf_p7->_public.nr_srs_indication)(&ind);
}
}
}
}
void vnf_handle_nr_uci_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
{
// ensure it's valid
if (pRecvMsg == NULL || vnf_p7 == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
}
else
{
nfapi_nr_uci_indication_t ind;
if(nfapi_nr_p7_message_unpack(pRecvMsg, recvMsgLen, &ind, sizeof(ind), &vnf_p7->_public.codec_config) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Failed to unpack message\n", __FUNCTION__);
}
else
{
if(vnf_p7->_public.nr_uci_indication)
{
(vnf_p7->_public.nr_uci_indication)(&ind);
}
}
}
}
void vnf_handle_nr_rach_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
{
// ensure it's valid
if (pRecvMsg == NULL || vnf_p7 == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
}
else
{
nfapi_nr_rach_indication_t ind;
if(nfapi_nr_p7_message_unpack(pRecvMsg, recvMsgLen, &ind, sizeof(ind), &vnf_p7->_public.codec_config) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Failed to unpack message\n", __FUNCTION__);
}
else
{
if(vnf_p7->_public.nr_rach_indication)
{
(vnf_p7->_public.nr_rach_indication)(&ind);
}
}
}
}
void vnf_nr_handle_ul_node_sync(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
{
//printf("received UL Node sync");
@@ -1484,6 +1638,8 @@ void vnf_nr_handle_ul_node_sync(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7
// divide by 2 using shift operator
uint32_t latency = (tx_2_rx - pnf_proc_time) >> 1;
//phy->in_sync = 1;
if(!(phy->filtered_adjust))
{
phy->latency[phy->min_sync_cycle_count] = latency;
@@ -1533,17 +1689,24 @@ void vnf_nr_handle_ul_node_sync(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
//NFAPI_TRACE(NFAPI_TRACE_NOTE, "(%4d/%1d) %d.%d PNF to VNF phy_id:%2d (t1/2/3/4:%8u, %8u, %8u, %8u) txrx:%4u procT:%3u latency(us):%4d(avg:%4d) offset(us):%8d filtered(us):%8d wrap[t1:%u t2:%u]\n",
// phy->sfn, phy->slot, ts.tv_sec, ts.tv_nsec, ind.header.phy_id,
// ind.t1, ind.t2, ind.t3, t4,
// tx_2_rx, pnf_proc_time, latency, phy->average_latency, phy->slot_offset, phy->slot_offset_filtered,
// (ind.t1<phy->previous_t1), (ind.t2<phy->previous_t2));
// NFAPI_TRACE(NFAPI_TRACE_NOTE, "(%4d/%1d) %d.%d PNF to VNF phy_id:%2d (t1/2/3/4:%8u, %8u, %8u, %8u) txrx:%4u procT:%3u latency(us):%4d(avg:%4d) offset(us):%8d filtered(us):%8d wrap[t1:%u t2:%u]\n",
// phy->sfn, phy->slot, ts.tv_sec, ts.tv_nsec, ind.header.phy_id,
// ind.t1, ind.t2, ind.t3, t4,
// tx_2_rx, pnf_proc_time, latency, phy->average_latency, phy->slot_offset, phy->slot_offset_filtered,
// (ind.t1<phy->previous_t1), (ind.t2<phy->previous_t2));
}
}
if (phy->filtered_adjust && (phy->slot_offset_filtered > 1e6 || phy->slot_offset_filtered < -1e6))
{
{ struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
NFAPI_TRACE(NFAPI_TRACE_NOTE, "(%4d/%1d) %d.%d PNF to VNF phy_id:%2d (t1/2/3/4:%8u, %8u, %8u, %8u) txrx:%4u procT:%3u latency(us):%4d(avg:%4d) offset(us):%8d filtered(us):%8d wrap[t1:%u t2:%u]\n",
phy->sfn, phy->slot, ts.tv_sec, ts.tv_nsec, ind.header.phy_id,
ind.t1, ind.t2, ind.t3, t4,
tx_2_rx, pnf_proc_time, latency, phy->average_latency, phy->slot_offset, phy->slot_offset_filtered,
(ind.t1<phy->previous_t1), (ind.t2<phy->previous_t2));
phy->filtered_adjust = 0;
phy->zero_count=0;
phy->min_sync_cycle_count = 2;
@@ -1575,7 +1738,7 @@ void vnf_nr_handle_ul_node_sync(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7
sfn_slot_dec += (phy->slot_offset / 500);
NFAPI_TRACE(NFAPI_TRACE_NOTE, "PNF to VNF slot offset:%d sfn :%d slot:%d \n",phy->slot_offset,NFAPI_SFNSLOTDEC2SFN(sfn_slot_dec),NFAPI_SFNSLOTDEC2SLOT(sfn_slot_dec) );
//NFAPI_TRACE(NFAPI_TRACE_NOTE, "PNF to VNF slot offset:%d sfn :%d slot:%d \n",phy->slot_offset,NFAPI_SFNSLOTDEC2SFN(sfn_slot_dec),NFAPI_SFNSLOTDEC2SLOT(sfn_slot_dec) );
}
@@ -2033,47 +2196,31 @@ void vnf_nr_dispatch_p7_message(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7
case NFAPI_TIMING_INFO:
vnf_nr_handle_timing_info(pRecvMsg, recvMsgLen, vnf_p7);
break;
case NFAPI_HARQ_INDICATION:
vnf_handle_harq_indication(pRecvMsg, recvMsgLen, vnf_p7);
case NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION:
vnf_handle_nr_slot_indication(pRecvMsg, recvMsgLen, vnf_p7);
break;
case NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION:
vnf_handle_nr_rx_data_indication(pRecvMsg, recvMsgLen, vnf_p7);
break;
case NFAPI_CRC_INDICATION:
vnf_handle_crc_indication(pRecvMsg, recvMsgLen, vnf_p7);
case NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION:
vnf_handle_nr_crc_indication(pRecvMsg, recvMsgLen, vnf_p7);
break;
case NFAPI_RX_ULSCH_INDICATION:
vnf_handle_rx_ulsch_indication(pRecvMsg, recvMsgLen, vnf_p7);
case NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION:
vnf_handle_nr_uci_indication(pRecvMsg, recvMsgLen, vnf_p7);
break;
case NFAPI_RACH_INDICATION:
vnf_handle_rach_indication(pRecvMsg, recvMsgLen, vnf_p7);
case NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION:
vnf_handle_nr_srs_indication(pRecvMsg, recvMsgLen, vnf_p7);
break;
case NFAPI_SRS_INDICATION:
vnf_handle_srs_indication(pRecvMsg, recvMsgLen, vnf_p7);
case NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION:
vnf_handle_nr_rach_indication(pRecvMsg, recvMsgLen, vnf_p7);
break;
case NFAPI_RX_SR_INDICATION:
vnf_handle_rx_sr_indication(pRecvMsg, recvMsgLen, vnf_p7);
break;
case NFAPI_RX_CQI_INDICATION:
vnf_handle_rx_cqi_indication(pRecvMsg, recvMsgLen, vnf_p7);
break;
case NFAPI_LBT_DL_INDICATION:
vnf_handle_lbt_dl_indication(pRecvMsg, recvMsgLen, vnf_p7);
break;
case NFAPI_NB_HARQ_INDICATION:
vnf_handle_nb_harq_indication(pRecvMsg, recvMsgLen, vnf_p7);
break;
case NFAPI_NRACH_INDICATION:
vnf_handle_nrach_indication(pRecvMsg, recvMsgLen, vnf_p7);
break;
case NFAPI_UE_RELEASE_RESPONSE:
vnf_handle_ue_release_resp(pRecvMsg, recvMsgLen, vnf_p7);
break;
+30 -259
View File
@@ -25,9 +25,14 @@
#include <errno.h>
#include "vnf_p7.h"
#include "nfapi_vnf.h"
#include "common/ran_context.h"
#include "openair1/PHY/defs_gNB.h"
#define FAPI2_IP_DSCP 0
extern RAN_CONTEXT_t RC;
nfapi_vnf_p7_config_t* nfapi_vnf_p7_config_create()
{
@@ -92,7 +97,9 @@ struct timespec timespec_sub(struct timespec lhs, struct timespec rhs)
// monitor the p7 endpoints and the timing loop and
// send indications to mac
int nfapi_nr_vnf_p7_start(nfapi_vnf_p7_config_t* config)
{
{
struct PHY_VARS_gNB_s *gNB = RC.gNB[0];
uint8_t prev_slot = 0;
if(config == 0)
return -1;
@@ -145,40 +152,14 @@ int nfapi_nr_vnf_p7_start(nfapi_vnf_p7_config_t* config)
//struct timespec original_pselect_timeout;
struct timespec pselect_timeout;
pselect_timeout.tv_sec = 0;
pselect_timeout.tv_nsec = 500000; // ns in a 0.5 ms
//pselect_timeout.tv_nsec = 500000;
pselect_timeout.tv_sec = 100;
pselect_timeout.tv_nsec = 0;
struct timespec pselect_start;
struct timespec pselect_stop;
//struct timespec sf_end;
long last_millisecond = -1;
// struct timespec sf_duration; //Change to slot_duration?
// sf_duration.tv_sec = 0;
// sf_duration.tv_nsec = 0.5e6; // We want 1ms pause //We want 0.5 ms pause for NR
struct timespec slot_duration;
slot_duration.tv_sec = 0;
//slot_duration.tv_nsec = 0.5e6;
slot_duration.tv_nsec = 0.5e6;
// struct timespec sf_start; //Change to slot_start?
struct timespec slot_start;
// clock_gettime(CLOCK_MONOTONIC, &sf_start);
clock_gettime(CLOCK_MONOTONIC, &slot_start);
long millisecond = slot_start.tv_nsec / 1e6; //Check if we have to change
//long millisecond = slot_start.tv_nsec / 0.5e6;
// sf_start = timespec_add(sf_start, sf_duration);
slot_start = timespec_add(slot_start, slot_duration);
NFAPI_TRACE(NFAPI_TRACE_INFO, "next slot will start at %d.%d\n", slot_start.tv_sec, slot_start.tv_nsec);
struct timespec ref_time;
clock_gettime(CLOCK_MONOTONIC, &ref_time);
uint8_t setup_time;
while(vnf_p7->terminate == 0)
{
{
fd_set rfds;
int maxSock = 0;
FD_ZERO(&rfds);
@@ -188,239 +169,33 @@ int nfapi_nr_vnf_p7_start(nfapi_vnf_p7_config_t* config)
FD_SET(vnf_p7->socket, &rfds);
maxSock = vnf_p7->socket;
clock_gettime(CLOCK_MONOTONIC, &pselect_start);
//long millisecond = pselect_start.tv_nsec / 1e6;
struct timespec curr_time;
clock_gettime(CLOCK_MONOTONIC, &curr_time);
setup_time = curr_time.tv_sec - ref_time.tv_sec;
if((last_millisecond == -1) || (millisecond == last_millisecond) || (millisecond == (last_millisecond + 1) % 1000) )
{
//NFAPI_TRACE(NFAPI_TRACE_INFO, "pselect_start:%d.%d sf_start:%d.%d\n", pselect_start.tv_sec, pselect_start.tv_nsec, sf_start.tv_sec, sf_start.tv_nsec);
if(setup_time > 10 && prev_slot != gNB->UL_INFO.slot){ //Give the VNF sufficient time to setup before starting scheduling
//if((pselect_start.tv_sec > sf_start.tv_sec) ||
// ((pselect_start.tv_sec == sf_start.tv_sec) && (pselect_start.tv_nsec > sf_start.tv_nsec)))
if((pselect_start.tv_sec > slot_start.tv_sec) || ((pselect_start.tv_sec == slot_start.tv_sec) && (pselect_start.tv_nsec > slot_start.tv_nsec)))
{
// overran the end of the subframe we do not want to wait
pselect_timeout.tv_sec = 0;
pselect_timeout.tv_nsec = 0;
//struct timespec overrun = timespec_sub(pselect_start, sf_start);
//NFAPI_TRACE(NFAPI_TRACE_INFO, "Subframe overrun detected of %d.%d running to catchup\n", overrun.tv_sec, overrun.tv_nsec);
}
else
{
// still time before the end of the subframe wait
//pselect_timeout = timespec_sub(sf_start, pselect_start);
pselect_timeout = timespec_sub(slot_start, pselect_start);
}
//original_pselect_timeout = pselect_timeout;
// detemine how long to sleep in ns before the start of the next 1ms
//pselect_timeout.tv_nsec = 1e6 - (pselect_start.tv_nsec % 1000000);
//uint8_t underrun_possible =0;
// if we are not sleeping until the next milisecond due to the
// insycn minor adjment flag it so we don't consider it an error
//uint8_t underrun_possible =0;
/*
{
nfapi_vnf_p7_connection_info_t* phy = vnf_p7->p7_connections;
if(phy && phy->in_sync && phy->insync_minor_adjustment != 0 && phy->insync_minor_adjustment_duration > 0 && pselect_start.tv_nsec != 0)
{
NFAPI_TRACE(NFAPI_TRACE_NOTE, "[VNF] Subframe minor adjustment %d (%d->%d)\n", phy->insync_minor_adjustment,
pselect_timeout.tv_nsec, pselect_timeout.tv_nsec - (phy->insync_minor_adjustment * 1000))
if(phy->insync_minor_adjustment > 0)
{
// todo check we don't go below 0
if((phy->insync_minor_adjustment * 1000) > pselect_timeout.tv_nsec)
pselect_timeout.tv_nsec = 0;
else
pselect_timeout.tv_nsec = pselect_timeout.tv_nsec - (phy->insync_minor_adjustment * 1000);
//underrun_possible = 1;
}
else if(phy->insync_minor_adjustment < 0)
{
// todo check we don't go below 0
pselect_timeout.tv_nsec = pselect_timeout.tv_nsec - (phy->insync_minor_adjustment * 1000);
//phy->insync_minor_adjustment = 0;
phy->insync_minor_adjustment_duration--;
}
}
*/
//long wraps = pselect_timeout.tv_nsec % 1e9;
selectRetval = pselect(maxSock+1, &rfds, NULL, NULL, &pselect_timeout, NULL);
// selectRetval = pselect(120, &rfds, NULL, NULL, &pselect_timeout, NULL);
clock_gettime(CLOCK_MONOTONIC, &pselect_stop);
nfapi_vnf_p7_connection_info_t* phy = vnf_p7->p7_connections;
if (selectRetval==-1 && errno == 22)
{
// NFAPI_TRACE(NFAPI_TRACE_ERROR, "INVAL: pselect_timeout:%d.%ld adj[dur:%d adj:%d], sf_dur:%d.%ld\n",
// pselect_timeout.tv_sec, pselect_timeout.tv_nsec,
// phy->insync_minor_adjustment_duration, phy->insync_minor_adjustment,
// sf_duration.tv_sec, sf_duration.tv_nsec);
NFAPI_TRACE(NFAPI_TRACE_ERROR, "INVAL: pselect_timeout:%d.%ld adj[dur:%d adj:%d], sf_dur:%d.%ld\n",
pselect_timeout.tv_sec, pselect_timeout.tv_nsec,
phy->insync_minor_adjustment_duration, phy->insync_minor_adjustment,
slot_duration.tv_sec, slot_duration.tv_nsec);
}
if(selectRetval == 0)
{
// calculate the start of the next slot
//sf_start = timespec_add(sf_start, sf_duration);
slot_start = timespec_add(slot_start, slot_duration);
//NFAPI_TRACE(NFAPI_TRACE_INFO, "next subframe will start at %d.%d\n", sf_start.tv_sec, sf_start.tv_nsec);
if(phy && phy->in_sync && phy->insync_minor_adjustment != 0 && phy->insync_minor_adjustment_duration > 0)
{
long insync_minor_adjustment_ns = (phy->insync_minor_adjustment * 1000);
//sf_start.tv_nsec -= insync_minor_adjustment_ns;
slot_start.tv_nsec -= insync_minor_adjustment_ns;
#if 1
/* if (sf_start.tv_nsec > 1e9) //Change to 0.5e6?
{
sf_start.tv_sec++;
sf_start.tv_nsec-=1e9;
}
else if (sf_start.tv_nsec < 0)
{
sf_start.tv_sec--;
sf_start.tv_nsec+=1e9;
}*/
if (slot_start.tv_nsec > 1e9)
{
slot_start.tv_sec++;
slot_start.tv_nsec-=1e9;
}
else if (slot_start.tv_nsec < 0)
{
slot_start.tv_sec--;
slot_start.tv_nsec+=1e9;
}
#else
//NFAPI_TRACE(NFAPI_TRACE_NOTE, "[VNF] BEFORE adjustment - Subframe minor adjustment %dus sf_start.tv_nsec:%d\n", phy->insync_minor_adjustment, sf_start.tv_nsec);
if(phy->insync_minor_adjustment > 0)
{
// decrease the subframe duration a little
if (sf_start.tv_nsec > insync_minor_adjustment_ns)
sf_start.tv_nsec -= insync_minor_adjustment_ns;
else
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "[VNF] Adjustment would make it negative sf:%d.%ld adjust:%ld\n\n\n", sf_start.tv_sec, sf_start.tv_nsec, insync_minor_adjustment_ns);
sf_start.tv_sec--;
sf_start.tv_nsec += 1e9 - insync_minor_adjustment_ns;
}
}
else if(phy->insync_minor_adjustment < 0)
{
// todo check we don't go below 0
// increase the subframe duration a little
sf_start.tv_nsec += insync_minor_adjustment_ns;
if (sf_start.tv_nsec < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "[VNF] OVERFLOW %d.%ld\n\n\n\n", sf_start.tv_sec, sf_start.tv_nsec);
sf_start.tv_sec++;
sf_start.tv_nsec += 1e9;
}
}
#endif
//phy->insync_minor_adjustment = 0;
phy->insync_minor_adjustment_duration--;
// NFAPI_TRACE(NFAPI_TRACE_NOTE, "[VNF] AFTER adjustment - Subframe minor adjustment %dus sf_start.tv_nsec:%d duration:%u\n",
// phy->insync_minor_adjustment, sf_start.tv_nsec, phy->insync_minor_adjustment_duration);
// NFAPI_TRACE(NFAPI_TRACE_NOTE, "[VNF] AFTER adjustment - Slot minor adjustment %dus slot_start.tv_nsec:%d duration:%u\n",
// phy->insync_minor_adjustment, slot_start.tv_nsec, phy->insync_minor_adjustment_duration);
if (phy->insync_minor_adjustment_duration==0)
{
phy->insync_minor_adjustment = 0;
}
}
/*
long pselect_stop_millisecond = pselect_stop.tv_nsec / 1e6;
if(millisecond == pselect_stop_millisecond)
{
// we have woke up in the same subframe
if(underrun_possible == 0)
NFAPI_TRACE(NFAPI_TRACE_WARN, "subframe pselect underrun %ld (%d.%d)\n", millisecond, pselect_stop.tv_sec, pselect_stop.tv_nsec);
}
else if(((millisecond + 1) % 1000) != pselect_stop_millisecond)
{
// we have overrun the subframe
NFAPI_TRACE(NFAPI_TRACE_WARN, "subframe pselect overrun %ld %ld\n", millisecond, pselect_stop_millisecond);
NFAPI_TRACE(NFAPI_TRACE_WARN, "subframe underrun %ld\n", millisecond);
}
last_millisecond = millisecond;
*/
//millisecond ++;
millisecond = millisecond + 1;
}
//Call the scheduler
pthread_mutex_lock(&gNB->UL_INFO_mutex);
gNB->UL_INFO.module_id = gNB->Mod_id;
gNB->UL_INFO.CC_id = gNB->CC_id;
gNB->if_inst->NR_UL_indication(&gNB->UL_INFO);
pthread_mutex_unlock(&gNB->UL_INFO_mutex);
prev_slot = gNB->UL_INFO.slot;
}
else
{
// we have overrun the subframe advance to go and collect $200
if((millisecond - last_millisecond) > 3)
NFAPI_TRACE(NFAPI_TRACE_WARN, "subframe overrun %ld %ld (%ld)\n", millisecond, last_millisecond, millisecond - last_millisecond + 1);
last_millisecond = ( last_millisecond + 1 ) % 1000;
selectRetval = 0;
}
selectRetval = pselect(maxSock+1, &rfds, NULL, NULL, &pselect_timeout, NULL);
if(selectRetval == 0)
{
//vnf_p7->sf_start_time_hr = vnf_get_current_time_hr();
vnf_p7->slot_start_time_hr = vnf_get_current_time_hr();
struct timespec current_time;
clock_gettime(CLOCK_MONOTONIC, &current_time);
// pselect timed out
nfapi_vnf_p7_connection_info_t* curr = vnf_p7->p7_connections;
while(curr != 0)
{
if (curr->slot == 19)
{ //curr->slot = 0;
if(curr->sfn == 1023)
curr->sfn=0;
else
curr->sfn++;
curr->slot=0;
}
else
{
curr->slot++;
}
vnf_nr_sync(vnf_p7, curr);
curr = curr->next;
}
send_mac_slot_indications(vnf_p7);
// pselect timed out, continue
}
else if(selectRetval > 0)
{
// have a p7 message
if(FD_ISSET(vnf_p7->socket, &rfds))
{
vnf_nr_p7_read_dispatch_message(vnf_p7);
{
vnf_nr_p7_read_dispatch_message(vnf_p7);
}
}
else
@@ -432,7 +207,7 @@ struct timespec current_time;
}
else
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "P7 select failed result %d errno %d timeout:%d.%d orginal:%d.%d last_ms:%ld ms:%ld\n", selectRetval, errno, pselect_timeout.tv_sec, pselect_timeout.tv_nsec, pselect_timeout.tv_sec, pselect_timeout.tv_nsec, last_millisecond, millisecond);
//NFAPI_TRACE(NFAPI_TRACE_INFO, "P7 select failed result %d errno %d timeout:%d.%d orginal:%d.%d last_ms:%ld ms:%ld\n", selectRetval, errno, pselect_timeout.tv_sec, pselect_timeout.tv_nsec, pselect_timeout.tv_sec, pselect_timeout.tv_nsec, last_millisecond, millisecond);
// should we exit now?
if (selectRetval == -1 && errno == 22) // invalid argument??? not sure about timeout duration
{
@@ -440,10 +215,7 @@ struct timespec current_time;
}
}
}
}
NFAPI_TRACE(NFAPI_TRACE_INFO, "Closing p7 socket\n");
close(vnf_p7->socket);
@@ -862,7 +634,6 @@ int nfapi_vnf_p7_ul_tti_req(nfapi_vnf_p7_config_t* config, nfapi_nr_ul_tti_reque
{
if(config == 0 || req == 0)
return -1;
vnf_p7_t* vnf_p7 = (vnf_p7_t*)config;
return vnf_nr_p7_pack_and_send_p7_msg(vnf_p7, &req->header);
}
+3 -36
View File
@@ -46,42 +46,6 @@
#include "PHY/NR_REFSIG/ul_ref_seq_nr.h"
static
uint16_t get_band(uint64_t downlink_frequency, int32_t delta_duplex)
{
const uint64_t dl_freq_khz = downlink_frequency / 1000;
const int32_t delta_duplex_khz = delta_duplex / 1000;
uint64_t center_freq_diff_khz = 999999999999999999; // 2^64
uint16_t current_band = 0;
for (int ind = 0; ind < nr_bandtable_size; ind++) {
LOG_D(PHY, "Scanning band %d, dl_min %"PRIu64", ul_min %"PRIu64"\n", nr_bandtable[ind].band, nr_bandtable[ind].dl_min, nr_bandtable[ind].ul_min);
if (dl_freq_khz < nr_bandtable[ind].dl_min || dl_freq_khz > nr_bandtable[ind].dl_max)
continue;
int32_t current_offset_khz = nr_bandtable[ind].ul_min - nr_bandtable[ind].dl_min;
if (current_offset_khz != delta_duplex_khz)
continue;
uint64_t center_frequency_khz = (nr_bandtable[ind].dl_max + nr_bandtable[ind].dl_min) / 2;
if (abs(dl_freq_khz - center_frequency_khz) < center_freq_diff_khz){
current_band = nr_bandtable[ind].band;
center_freq_diff_khz = abs(dl_freq_khz - center_frequency_khz);
}
}
LOG_I(PHY, "DL frequency %"PRIu64": band %d, UL frequency %"PRIu64"\n",
downlink_frequency, current_band, downlink_frequency+delta_duplex);
AssertFatal(current_band != 0, "Can't find EUTRA band for frequency %"PRIu64" and duplex_spacing %u\n", downlink_frequency, delta_duplex);
return current_band;
}
int l1_north_init_gNB() {
@@ -495,6 +459,7 @@ void nr_phy_config_request_sim(PHY_VARS_gNB *gNB,
gNB_config->carrier_config.dl_bandwidth.value = config_bandwidth(mu, N_RB_DL, fp->nr_band);
nr_init_frame_parms(gNB_config, fp);
fp->ofdm_offset_divisor = UINT_MAX;
gNB->configured = 1;
LOG_I(PHY,"gNB configured\n");
}
@@ -546,7 +511,9 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config) {
// }
RC.gNB[Mod_id]->configured = 1;
fp->ofdm_offset_divisor = RC.gNB[Mod_id]->ofdm_offset_divisor;
init_symbol_rotation(fp);
init_timeshift_rotation(fp);
LOG_I(PHY,"gNB %d configured\n",Mod_id);
}
+1 -1
View File
@@ -124,7 +124,7 @@ void phy_init_nr_ue_PUSCH(NR_UE_PUSCH *const pusch,
AssertFatal( pusch, "pusch==0" );
for (int i=0; i<NR_MAX_NB_LAYERS; i++) {
pusch->txdataF_layers[i] = (int32_t *)malloc16_clear((NR_MAX_PUSCH_ENCODED_LENGTH)*sizeof(int32_t *));
pusch->txdataF_layers[i] = (int32_t *)malloc16_clear(NR_MAX_PUSCH_ENCODED_LENGTH*sizeof(int32_t));
}
}
+54 -19
View File
@@ -20,6 +20,7 @@
*/
#include "phy_init.h"
#include "common/utils/nr/nr_common.h"
#include "common/utils/LOG/log.h"
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
@@ -27,6 +28,20 @@
uint32_t nr_subcarrier_spacing[MAX_NUM_SUBCARRIER_SPACING] = {15e3, 30e3, 60e3, 120e3, 240e3};
uint16_t nr_slots_per_subframe[MAX_NUM_SUBCARRIER_SPACING] = {1, 2, 4, 8, 16};
void set_Lmax(NR_DL_FRAME_PARMS *fp) {
// definition of Lmax according to ts 38.213 section 4.1
if (fp->dl_CarrierFreq < 6e9) {
if(fp->frame_type && (fp->ssb_type==2))
fp->Lmax = (fp->dl_CarrierFreq < 2.4e9)? 4 : 8;
else
fp->Lmax = (fp->dl_CarrierFreq < 3e9)? 4 : 8;
} else {
fp->Lmax = 64;
}
}
int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp,uint8_t i_ssb) {
int mu = fp->numerology_index;
@@ -217,15 +232,7 @@ int nr_init_frame_parms(nfapi_nr_config_request_scf_t* cfg,
fp->Ncp = Ncp;
// definition of Lmax according to ts 38.213 section 4.1
if (fp->dl_CarrierFreq < 6e9) {
if(fp->frame_type && (fp->ssb_type==2))
fp->Lmax = (fp->dl_CarrierFreq < 2.4e9)? 4 : 8;
else
fp->Lmax = (fp->dl_CarrierFreq < 3e9)? 4 : 8;
} else {
fp->Lmax = 64;
}
set_Lmax(fp);
fp->N_ssb = 0;
int num_tx_ant = cfg->carrier_config.num_tx_ant.value;
@@ -316,16 +323,7 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp,
sco = config->ssb_table.ssb_subcarrier_offset;
fp->ssb_start_subcarrier = (12 * config->ssb_table.ssb_offset_point_a + sco);
// definition of Lmax according to ts 38.213 section 4.1
if (fp->dl_CarrierFreq < 6e9) {
if(fp->frame_type && (fp->ssb_type==2))
fp->Lmax = (fp->dl_CarrierFreq < 2.4e9)? 4 : 8;
else
fp->Lmax = (fp->dl_CarrierFreq < 3e9)? 4 : 8;
} else {
fp->Lmax = 64;
}
set_Lmax(fp);
fp->L_ssb = (((uint64_t) config->ssb_table.ssb_mask_list[0].ssb_mask)<<32) | config->ssb_table.ssb_mask_list[1].ssb_mask;
@@ -336,6 +334,43 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp,
return 0;
}
void nr_init_frame_parms_ue_sa(NR_DL_FRAME_PARMS *frame_parms, uint64_t downlink_frequency, int32_t delta_duplex, uint8_t mu, uint16_t nr_band) {
LOG_I(PHY,"SA init parameters. DL freq %lu UL offset %d SSB numerology %d N_RB_DL %d\n",
downlink_frequency,
delta_duplex,
mu,
frame_parms->N_RB_DL);
frame_parms->numerology_index = mu;
frame_parms->dl_CarrierFreq = downlink_frequency;
frame_parms->ul_CarrierFreq = downlink_frequency + delta_duplex;
frame_parms->freq_range = (frame_parms->dl_CarrierFreq < 6e9)? nr_FR1 : nr_FR2;
frame_parms->N_RB_UL = frame_parms->N_RB_DL;
frame_parms->nr_band = nr_band;
frame_parms->frame_type = get_frame_type(frame_parms->nr_band, frame_parms->numerology_index);
frame_parms->Ncp = NORMAL;
set_scs_parameters(frame_parms, frame_parms->numerology_index, frame_parms->N_RB_DL);
set_Lmax(frame_parms);
frame_parms->slots_per_frame = 10* frame_parms->slots_per_subframe;
frame_parms->symbols_per_slot = ((frame_parms->Ncp == NORMAL)? 14 : 12); // to redefine for different slot formats
frame_parms->samples_per_subframe_wCP = frame_parms->ofdm_symbol_size * frame_parms->symbols_per_slot * frame_parms->slots_per_subframe;
frame_parms->samples_per_frame_wCP = 10 * frame_parms->samples_per_subframe_wCP;
frame_parms->samples_per_slot_wCP = frame_parms->symbols_per_slot*frame_parms->ofdm_symbol_size;
frame_parms->samples_per_slotN0 = (frame_parms->nb_prefix_samples + frame_parms->ofdm_symbol_size) * frame_parms->symbols_per_slot;
frame_parms->samples_per_slot0 = frame_parms->nb_prefix_samples0 + ((frame_parms->symbols_per_slot-1)*frame_parms->nb_prefix_samples) + (frame_parms->symbols_per_slot*frame_parms->ofdm_symbol_size);
frame_parms->samples_per_subframe = (frame_parms->nb_prefix_samples0 + frame_parms->ofdm_symbol_size) * 2 +
(frame_parms->nb_prefix_samples + frame_parms->ofdm_symbol_size) * (frame_parms->symbols_per_slot * frame_parms->slots_per_subframe - 2);
frame_parms->get_samples_per_slot = &get_samples_per_slot;
frame_parms->get_samples_slot_timestamp = &get_samples_slot_timestamp;
frame_parms->samples_per_frame = 10 * frame_parms->samples_per_subframe;
}
void nr_dump_frame_parms(NR_DL_FRAME_PARMS *fp)
{
LOG_I(PHY,"fp->scs=%d\n",fp->subcarrier_spacing);
+1 -1
View File
@@ -389,12 +389,12 @@ void phy_config_request(PHY_Config_t *phy_config);
void phy_config_update_sib2_request(PHY_Config_t *phy_config);
void phy_config_update_sib13_request(PHY_Config_t *phy_config);
int init_frame_parms(LTE_DL_FRAME_PARMS *frame_parms,uint8_t osf);
void dump_frame_parms(LTE_DL_FRAME_PARMS *frame_parms);
int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp,uint8_t i_ssb);
int nr_init_frame_parms(nfapi_nr_config_request_scf_t *config, NR_DL_FRAME_PARMS *frame_parms);
int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *frame_parms, fapi_nr_config_request_t *config, uint16_t nr_band);
void nr_init_frame_parms_ue_sa(NR_DL_FRAME_PARMS *frame_parms, uint64_t downlink_frequency, int32_t uplink_frequency_offset, uint8_t mu, uint16_t nr_band);
int init_nr_ue_signal(PHY_VARS_NR_UE *ue,int nb_connected_eNB,uint8_t abstraction_flag);
void init_nr_ue_transport(PHY_VARS_NR_UE *ue,int abstraction_flag);
void init_N_TA_offset(PHY_VARS_NR_UE *ue);
+3 -1
View File
@@ -1527,7 +1527,9 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,
if (dlsch0->active)
T(T_ENB_PHY_DLSCH_UE_DCI, T_INT(0), T_INT(frame), T_INT(subframe),
T_INT(rel8->rnti), T_INT(rel8->dci_format), T_INT(rel8->harq_process),
T_INT(rel8->mcs_1), T_INT(dlsch0_harq->TBS));
T_INT(rel8->mcs_1), T_INT(dlsch0_harq->TBS), T_INT(rel8->new_data_indicator_1),
T_INT(rel8->redundancy_version_1), T_INT(rel8->resource_block_coding),
T_INT(dlsch0_harq->nb_rb), T_INT(dlsch0_harq->rb_alloc[0]));
#endif
}
+1 -1
View File
@@ -49,7 +49,7 @@ void PHY_ofdm_mod(int *input,
void normal_prefix_mod(int32_t *txdataF,int32_t *txdata,uint8_t nsymb,LTE_DL_FRAME_PARMS *frame_parms);
void nr_normal_prefix_mod(int32_t *txdataF,int32_t *txdata,uint8_t nsymb,NR_DL_FRAME_PARMS *frame_parms);
void nr_normal_prefix_mod(int32_t *txdataF,int32_t *txdata,uint8_t nsymb,NR_DL_FRAME_PARMS *frame_parms, uint32_t slot);
void do_OFDM_mod(int32_t **txdataF, int32_t **txdata, uint32_t frame,uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms);
+17
View File
@@ -745,6 +745,23 @@ void init_symbol_rotation(NR_DL_FRAME_PARMS *fp) {
}
}
void init_timeshift_rotation(NR_DL_FRAME_PARMS *fp)
{
for (int i = 0; i < fp->ofdm_symbol_size; i++) {
double poff = -i * 2.0 * M_PI * 144.0 / 2048.0 / fp->ofdm_offset_divisor;
double exp_re = cos(poff);
double exp_im = sin(-poff);
fp->timeshift_symbol_rotation[i*2] = (int16_t)round(exp_re * 32767);
fp->timeshift_symbol_rotation[i*2+1] = (int16_t)round(exp_im * 32767);
if (i < 10)
LOG_I(PHY,"Timeshift symbol rotation %d => (%d,%d) %f\n",i,
fp->timeshift_symbol_rotation[i*2],
fp->timeshift_symbol_rotation[i*2+1],
poff);
}
}
int nr_layer_precoder(int16_t **datatx_F_precoding, char *prec_matrix, uint8_t n_layers, int32_t re_offset)
{
int32_t precodatatx_F = 0;
+2
View File
@@ -117,6 +117,8 @@ void apply_nr_rotation(NR_DL_FRAME_PARMS *fp,
void init_symbol_rotation(NR_DL_FRAME_PARMS *fp);
void init_timeshift_rotation(NR_DL_FRAME_PARMS *fp);
void apply_nr_rotation_ul(NR_DL_FRAME_PARMS *frame_parms,
int32_t *rxdataF,
int slot,
+55 -13
View File
@@ -63,20 +63,62 @@ void normal_prefix_mod(int32_t *txdataF,int32_t *txdata,uint8_t nsymb,LTE_DL_FRA
}
void nr_normal_prefix_mod(int32_t *txdataF,int32_t *txdata,uint8_t nsymb,NR_DL_FRAME_PARMS *frame_parms)
void nr_normal_prefix_mod(int32_t *txdataF,int32_t *txdata,uint8_t nsymb,NR_DL_FRAME_PARMS *frame_parms, uint32_t slot)
{
PHY_ofdm_mod(txdataF, // input
txdata, // output
frame_parms->ofdm_symbol_size,
1, // number of symbols
frame_parms->nb_prefix_samples0, // number of prefix samples
CYCLIC_PREFIX);
PHY_ofdm_mod(txdataF+frame_parms->ofdm_symbol_size, // input
txdata + frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples0, // output
frame_parms->ofdm_symbol_size,
nsymb - 1,
frame_parms->nb_prefix_samples, // number of prefix samples
CYCLIC_PREFIX);
// This function works only slot wise. For more generic symbol generation refer nr_feptx0()
if (frame_parms->numerology_index != 0) { // case where numerology != 0
if (!(slot%(frame_parms->slots_per_subframe/2))) {
PHY_ofdm_mod(txdataF,
txdata,
frame_parms->ofdm_symbol_size,
1,
frame_parms->nb_prefix_samples0,
CYCLIC_PREFIX);
PHY_ofdm_mod(txdataF+frame_parms->ofdm_symbol_size,
txdata + frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples0,
frame_parms->ofdm_symbol_size,
nsymb - 1,
frame_parms->nb_prefix_samples,
CYCLIC_PREFIX);
}
else {
PHY_ofdm_mod(txdataF,
txdata,
frame_parms->ofdm_symbol_size,
nsymb,
frame_parms->nb_prefix_samples,
CYCLIC_PREFIX);
}
}
else { // numerology = 0, longer CP for every 7th symbol
PHY_ofdm_mod(txdataF,
txdata,
frame_parms->ofdm_symbol_size,
1,
frame_parms->nb_prefix_samples0,
CYCLIC_PREFIX);
PHY_ofdm_mod(txdataF+frame_parms->ofdm_symbol_size,
txdata + frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples0,
frame_parms->ofdm_symbol_size,
6,
frame_parms->nb_prefix_samples,
CYCLIC_PREFIX);
PHY_ofdm_mod(txdataF + 7*frame_parms->ofdm_symbol_size,
txdata + 6*(frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples) +
frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples0,
frame_parms->ofdm_symbol_size,
1,
frame_parms->nb_prefix_samples0,
CYCLIC_PREFIX);
PHY_ofdm_mod(txdataF + 8*frame_parms->ofdm_symbol_size,
txdata + 6*(frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples) +
2*(frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples0),
frame_parms->ofdm_symbol_size,
6,
frame_parms->nb_prefix_samples,
CYCLIC_PREFIX);
}
}
void PHY_ofdm_mod(int *input, /// pointer to complex input
+27 -11
View File
@@ -107,7 +107,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
rx_offset += frame_parms->ofdm_symbol_size * symbol;
// use OFDM symbol from within 1/8th of the CP to avoid ISI
rx_offset -= nb_prefix_samples / 8;
rx_offset -= (nb_prefix_samples / frame_parms->ofdm_offset_divisor);
#ifdef DEBUG_FEP
// if (ue->frame <100)
@@ -157,6 +157,15 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
(int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],
frame_parms->ofdm_symbol_size,
15);
int16_t *shift_rot = frame_parms->timeshift_symbol_rotation;
multadd_cpx_vector((int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],
shift_rot,
(int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],
1,
frame_parms->ofdm_symbol_size,
15);
}
#ifdef DEBUG_FEP
@@ -292,14 +301,15 @@ int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms,
// This is for misalignment issues
int32_t tmp_dft_in[8192] __attribute__ ((aligned (32)));
unsigned int slot_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0);
// offset of first OFDM symbol
int32_t rxdata_offset = slot_offset + nb_prefix_samples0;
// offset of n-th OFDM symbol
rxdata_offset += symbol * (frame_parms->ofdm_symbol_size + nb_prefix_samples);
unsigned int rxdata_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0);
unsigned int abs_symbol = Ns * frame_parms->symbols_per_slot + symbol;
for (int idx_symb = Ns*frame_parms->symbols_per_slot; idx_symb <= abs_symbol; idx_symb++)
rxdata_offset += (idx_symb%(0x7<<frame_parms->numerology_index)) ? nb_prefix_samples : nb_prefix_samples0;
rxdata_offset += frame_parms->ofdm_symbol_size * symbol;
// use OFDM symbol from within 1/8th of the CP to avoid ISI
rxdata_offset -= nb_prefix_samples / 8;
rxdata_offset -= (nb_prefix_samples / frame_parms->ofdm_offset_divisor);
int16_t *rxdata_ptr;
@@ -333,9 +343,6 @@ int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms,
(int16_t *)&rxdataF[symbol * frame_parms->ofdm_symbol_size],
1);
// clear DC carrier from OFDM symbols
rxdataF[symbol * frame_parms->ofdm_symbol_size] = 0;
return 0;
}
@@ -349,7 +356,7 @@ void apply_nr_rotation_ul(NR_DL_FRAME_PARMS *frame_parms,
int symb_offset = (slot%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot;
for (int symbol=0;symbol<nsymb;symbol++) {
for (int symbol=first_symbol;symbol<nsymb;symbol++) {
uint32_t rot2 = ((uint32_t*)frame_parms->symbol_rotation[1])[symbol + symb_offset];
((int16_t*)&rot2)[1]=-((int16_t*)&rot2)[1];
@@ -359,5 +366,14 @@ void apply_nr_rotation_ul(NR_DL_FRAME_PARMS *frame_parms,
(int16_t *)&rxdataF[frame_parms->ofdm_symbol_size*symbol],
length,
15);
int16_t *shift_rot = frame_parms->timeshift_symbol_rotation;
multadd_cpx_vector((int16_t *)&rxdataF[frame_parms->ofdm_symbol_size*symbol],
shift_rot,
(int16_t *)&rxdataF[frame_parms->ofdm_symbol_size*symbol],
1,
length,
15);
}
}
@@ -39,23 +39,22 @@ extern openair0_config_t openair0_cfg[MAX_CARDS];
int nr_est_timing_advance_pusch(PHY_VARS_gNB* gNB, int UE_id)
{
int i, aa, max_pos = 0, max_val = 0;
int max_pos = 0, max_val = 0;
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
NR_gNB_PUSCH *gNB_pusch_vars = gNB->pusch_vars[UE_id];
int32_t **ul_ch_estimates_time = gNB_pusch_vars->ul_ch_estimates_time;
int sync_pos = frame_parms->nb_prefix_samples / 8;
for (i = 0; i < frame_parms->ofdm_symbol_size; i++) {
const int sync_pos = 0;
for (int i = 0; i < frame_parms->ofdm_symbol_size; i++) {
int temp = 0;
for (aa = 0; aa < frame_parms->nb_antennas_rx; aa++) {
short Re = ((int16_t*)ul_ch_estimates_time[aa])[(i<<1)];
short Im = ((int16_t*)ul_ch_estimates_time[aa])[1+(i<<1)];
for (int aa = 0; aa < frame_parms->nb_antennas_rx; aa++) {
int Re = ((int16_t*)ul_ch_estimates_time[aa])[(i<<1)];
int Im = ((int16_t*)ul_ch_estimates_time[aa])[1+(i<<1)];
temp += (Re*Re/2) + (Im*Im/2);
}
if (temp > max_val) {
max_pos = i;
max_val = temp;
@@ -65,7 +64,6 @@ int nr_est_timing_advance_pusch(PHY_VARS_gNB* gNB, int UE_id)
if (max_pos > frame_parms->ofdm_symbol_size/2)
max_pos = max_pos - frame_parms->ofdm_symbol_size;
return max_pos - sync_pos;
}
@@ -31,11 +31,13 @@
#include "PHY/NR_UE_ESTIMATION/filt16a_32.h"
#include "PHY/NR_REFSIG/ul_ref_seq_nr.h"
#include "executables/softmodem-common.h"
//#define DEBUG_CH
//#define DEBUG_PUSCH
#define NO_INTERP 1
#define dBc(x,y) (dB_fixed(((int32_t)(x))*(x) + ((int32_t)(y))*(y)))
int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
@@ -187,8 +189,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
#endif
//if ((gNB->frame_parms.N_RB_UL&1)==0) {
if (pusch_pdu->dmrs_config_type == pusch_dmrs_type1){
if (pusch_pdu->dmrs_config_type == pusch_dmrs_type1 && gNB->prb_interpolation == 0){
LOG_D(PHY,"PUSCH estimation DMRS type 1, Freq-domain interpolation");
// Treat first 2 pilots specially (left edge)
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
@@ -212,7 +214,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
ch,
ul_ch,
8);
pil+=2;
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
//for (int i= 0; i<8; i++)
@@ -243,7 +245,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
ch,
ul_ch,
8);
pil+=2;
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
//printf("ul_ch addr %p\n",ul_ch);
@@ -277,12 +279,12 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
//for (int i= 0; i<16; i++)
//printf("ul_ch addr %p %d\n", ul_ch+i, *(ul_ch+i));
pil+=2;
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ul_ch+=8;
ul_ch += 8;
for (pilot_cnt=3; pilot_cnt<(6*nb_rb_pusch-3); pilot_cnt+=2) {
for (pilot_cnt=3; pilot_cnt<(6*nb_rb_pusch-3); pilot_cnt += 2) {
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
@@ -295,7 +297,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
ch,
ul_ch,
8);
pil+=2;
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
//printf("ul_ch addr %p\n",ul_ch);
@@ -315,10 +317,10 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
//for (int i= 0; i<16; i++)
//printf("ul_ch addr %p %d\n", ul_ch+i, *(ul_ch+i));
pil+=2;
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ul_ch+=8;
ul_ch += 8;
}
@@ -337,7 +339,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
//for (int i= 0; i<8; i++)
//printf("ul_ch addr %p %d\n", ul_ch+i, *(ul_ch+i));
pil+=2;
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
@@ -353,10 +355,10 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
ul_ch,
8);
pil+=2;
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ul_ch+=8;
ul_ch += 8;
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
@@ -425,15 +427,15 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
#ifdef DEBUG_PUSCH
ul_ch = (int16_t *)&ul_ch_estimates[p*gNB->frame_parms.nb_antennas_rx+aarx][ch_offset];
for(uint16_t idxP=0; idxP<ceil((float)nb_rb_pusch*12/8); idxP++) {
for(uint8_t idxI=0; idxI<16; idxI+=2) {
for(uint8_t idxI=0; idxI<16; idxI += 2) {
printf("%d\t%d\t",ul_ch[idxP*16+idxI],ul_ch[idxP*16+idxI+1]);
}
printf("%d\n",idxP);
}
#endif
}
else { //pusch_dmrs_type2 |p_r,p_l,d,d,d,d,p_r,p_l,d,d,d,d|
else if (pusch_pdu->dmrs_config_type == pusch_dmrs_type2 && gNB->prb_interpolation == 0) { //pusch_dmrs_type2 |p_r,p_l,d,d,d,d,p_r,p_l,d,d,d,d|
LOG_D(PHY,"PUSCH estimation DMRS type 2, Freq-domain interpolation");
// Treat first DMRS specially (left edge)
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
@@ -441,12 +443,12 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
ul_ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ul_ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
pil+=2;
ul_ch+=2;
pil += 2;
ul_ch += 2;
re_offset = (re_offset + 1)%gNB->frame_parms.ofdm_symbol_size;
ch_offset++;
for (re_cnt = 1; re_cnt < (nb_rb_pusch*NR_NB_SC_PER_RB) - 5; re_cnt+=6){
for (re_cnt = 1; re_cnt < (nb_rb_pusch*NR_NB_SC_PER_RB) - 5; re_cnt += 6){
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
@@ -456,8 +458,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
ul_ch[0] = ch_l[0];
ul_ch[1] = ch_l[1];
pil+=2;
ul_ch+=2;
pil += 2;
ul_ch += 2;
ch_offset++;
multadd_real_four_symbols_vector_complex_scalar(filt8_ml2,
@@ -476,17 +478,17 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
ch_r,
ul_ch);
//for (int re_idx = 0; re_idx < 8; re_idx+=2)
//for (int re_idx = 0; re_idx < 8; re_idx += 2)
//printf("ul_ch = %d + j*%d\n", ul_ch[re_idx], ul_ch[re_idx+1]);
ul_ch+=8;
ch_offset+=4;
ul_ch += 8;
ch_offset += 4;
ul_ch[0] = ch_r[0];
ul_ch[1] = ch_r[1];
pil+=2;
ul_ch+=2;
pil += 2;
ul_ch += 2;
ch_offset++;
re_offset = (re_offset + 1)%gNB->frame_parms.ofdm_symbol_size;
@@ -502,7 +504,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
ul_ch[0] = ch_l[0];
ul_ch[1] = ch_l[1];
ul_ch+=2;
ul_ch += 2;
ch_offset++;
multadd_real_four_symbols_vector_complex_scalar(filt8_rr1,
@@ -518,6 +520,385 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
ul_ch_128[0] = _mm_slli_epi16 (ul_ch_128[0], 2);
}
else if (pusch_pdu->dmrs_config_type == pusch_dmrs_type1) {// this is case without frequency-domain linear interpolation, just take average of LS channel estimates of 6 DMRS REs and use a common value for the whole PRB
LOG_D(PHY,"PUSCH estimation DMRS type 1, no Freq-domain interpolation");
int32_t ch_0, ch_1;
// First PRB
ch_0 = ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 = ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch[0] = ch_0 / 6;
ch[1] = ch_1 / 6;
#if NO_INTERP
for (int i=0;i<12;i++) ((int32_t*)ul_ch)[i] = *(int32_t*)ch;
ul_ch+=24;
#else
multadd_real_vector_complex_scalar(filt8_avlip0,
ch,
ul_ch,
8);
ul_ch += 16;
multadd_real_vector_complex_scalar(filt8_avlip1,
ch,
ul_ch,
8);
ul_ch += 16;
multadd_real_vector_complex_scalar(filt8_avlip2,
ch,
ul_ch,
8);
ul_ch -= 24;
#endif
for (pilot_cnt=6; pilot_cnt<6*(nb_rb_pusch-1); pilot_cnt += 6) {
ch_0 = ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 = ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch[0] = ch_0 / 6;
ch[1] = ch_1 / 6;
#if NO_INTERP
for (int i=0;i<12;i++) ((int32_t*)ul_ch)[i] = *(int32_t*)ch;
ul_ch+=24;
#else
ul_ch[6] += (ch[0] * 1365)>>15; // 1/12*16384
ul_ch[7] += (ch[1] * 1365)>>15; // 1/12*16384
ul_ch += 8;
multadd_real_vector_complex_scalar(filt8_avlip3,
ch,
ul_ch,
8);
ul_ch += 16;
multadd_real_vector_complex_scalar(filt8_avlip4,
ch,
ul_ch,
8);
ul_ch += 16;
multadd_real_vector_complex_scalar(filt8_avlip5,
ch,
ul_ch,
8);
ul_ch -= 16;
#endif
}
// Last PRB
ch_0 = ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 = ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch[0] = ch_0 / 6;
ch[1] = ch_1 / 6;
#if NO_INTERP
for (int i=0;i<12;i++) ((int32_t*)ul_ch)[i] = *(int32_t*)ch;
ul_ch+=24;
#else
ul_ch[6] += (ch[0] * 1365)>>15; // 1/12*16384
ul_ch[7] += (ch[1] * 1365)>>15; // 1/12*16384
ul_ch += 8;
multadd_real_vector_complex_scalar(filt8_avlip3,
ch,
ul_ch,
8);
ul_ch += 16;
multadd_real_vector_complex_scalar(filt8_avlip6,
ch,
ul_ch,
8);
#endif
}
else { // this is case without frequency-domain linear interpolation, just take average of LS channel estimates of 4 DMRS REs and use a common value for the whole PRB
LOG_D(PHY,"PUSCH estimation DMRS type 2, no Freq-domain interpolation");
int32_t ch_0, ch_1;
//First PRB
ch_0 = ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 = ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+1) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+5) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+1) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+5) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch[0] = ch_0 / 4;
ch[1] = ch_1 / 4;
multadd_real_vector_complex_scalar(filt8_avlip0,
ch,
ul_ch,
8);
ul_ch += 16;
multadd_real_vector_complex_scalar(filt8_avlip1,
ch,
ul_ch,
8);
ul_ch += 16;
multadd_real_vector_complex_scalar(filt8_avlip2,
ch,
ul_ch,
8);
ul_ch -= 24;
for (pilot_cnt=4; pilot_cnt<4*(nb_rb_pusch-1); pilot_cnt += 4) {
ch_0 = ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 = ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+1) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+5) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+1) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+5) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch[0] = ch_0 / 4;
ch[1] = ch_1 / 4;
ul_ch[6] += (ch[0] * 1365)>>15; // 1/12*16384
ul_ch[7] += (ch[1] * 1365)>>15; // 1/12*16384
ul_ch += 8;
multadd_real_vector_complex_scalar(filt8_avlip3,
ch,
ul_ch,
8);
ul_ch += 16;
multadd_real_vector_complex_scalar(filt8_avlip4,
ch,
ul_ch,
8);
ul_ch += 16;
multadd_real_vector_complex_scalar(filt8_avlip5,
ch,
ul_ch,
8);
ul_ch -= 16;
}
// Last PRB
ch_0 = ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 = ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+1) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+5) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+1) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+5) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch[0] = ch_0 / 4;
ch[1] = ch_1 / 4;
ul_ch[6] += (ch[0] * 1365)>>15; // 1/12*16384
ul_ch[7] += (ch[1] * 1365)>>15; // 1/12*16384
ul_ch += 8;
multadd_real_vector_complex_scalar(filt8_avlip3,
ch,
ul_ch,
8);
ul_ch += 16;
multadd_real_vector_complex_scalar(filt8_avlip6,
ch,
ul_ch,
8);
}
#ifdef DEBUG_PUSCH
ul_ch = (int16_t *)&ul_ch_estimates[p*gNB->frame_parms.nb_antennas_rx+aarx][ch_offset];
for(uint16_t idxP=0; idxP<ceil((float)nb_rb_pusch*12/8); idxP++) {
for(uint8_t idxI=0; idxI<16; idxI += 2) {
printf("%d\t%d\t",ul_ch[idxP*16+idxI],ul_ch[idxP*16+idxI+1]);
}
printf("%d\n",idxP);
}
#endif
// Convert to time domain
+1 -1
View File
@@ -213,7 +213,7 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB,
nr_pdsch_codeword_scrambling_optim(harq->f,
encoded_length,
q,
rel15->dlDmrsScramblingId,
rel15->dataScramblingId,
rel15->rnti,
scrambled_output[q]);
+2 -1
View File
@@ -292,7 +292,8 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
}
G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs,mod_order,rel15->nrOfLayers);
LOG_D(NR_PHY,"dlsch coding A %d G %d (nb_rb %d, nb_symb_sch %d, nb_re_dmrs %d, length_dmrs %d, mod_order %d)\n", A,G, nb_rb,nb_symb_sch,nb_re_dmrs,length_dmrs,mod_order);
LOG_D(PHY,"dlsch coding A %d G %d (nb_rb %d, nb_symb_sch %d, nb_re_dmrs %d, length_dmrs %d, mod_order %d)\n",
A,G, nb_rb,nb_symb_sch,nb_re_dmrs,length_dmrs,(int)mod_order);
if (A > 3824) {
// Add 24-bit crc (polynomial A) to payload
+5 -1
View File
@@ -174,7 +174,11 @@ void rx_nr_prach_ru(RU_t *ru,
int msg1_frequencystart = ru->config.prach_config.num_prach_fd_occasions_list[numRA].k1.value;
int sample_offset_slot = (prachStartSymbol==0?0:fp->ofdm_symbol_size*prachStartSymbol+fp->nb_prefix_samples0+fp->nb_prefix_samples*(prachStartSymbol-1));
int sample_offset_slot;
if (!(slot%(fp->slots_per_subframe/2)))
sample_offset_slot = (prachStartSymbol==0?0:fp->ofdm_symbol_size*prachStartSymbol+fp->nb_prefix_samples0+fp->nb_prefix_samples*(prachStartSymbol-1));
else
sample_offset_slot = (prachStartSymbol==0?0:prachStartSymbol*(fp->ofdm_symbol_size+fp->nb_prefix_samples));
//to be checked for mu=0;
LOG_D(PHY,"frame %d, slot %d: doing rx_nr_prach_ru for format %d, numRA %d, prachStartSymbol %d, prachOccasion %d\n",frame,slot,prachFormat,numRA,prachStartSymbol,prachOccasion);
+3 -1
View File
@@ -48,6 +48,8 @@
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "nfapi/oai_integration/vendor_ext.h"
#include "T.h"
//#define DEBUG_NR_PUCCH_RX 1
@@ -1437,7 +1439,7 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
corr_tmp += corr_re*corr_re + corr_im*corr_im;
} // aa loop
}// group loop
LOG_D(PHY,"cw %d, metric %f dB\n",cw,10*log10(corr_tmp));
if (corr_tmp > corr) {
corr = corr_tmp;
cw_ML=cw;
@@ -239,3 +239,24 @@ short filt8_dcll2[8] = {
short filt8_dclh2[8] = {
0,0,0,0,1489,2979,4468,5958};
short filt8_avlip0[8] = {
16384,16384,16384,16384,16384,16384,16384,15019};
short filt8_avlip1[8] = {
13653,12288,10923,9557,8192,6827,5461,4096};
short filt8_avlip2[8] = {
2731,1365,0,0,0,0,0,0};
short filt8_avlip3[8] = {
2731,4096,5461,6827,8192,9557,10923,12288};
short filt8_avlip4[8] = {
13653,15019,16384,15019,13653,12288,10923,9557};
short filt8_avlip5[8] = {
8192,6827,5461,4096,2731,1365,0,0};
short filt8_avlip6[8] = {
13653,15019,16384,16384,16384,16384,16384,16384};
+14 -1
View File
@@ -169,4 +169,17 @@ extern short filt8_dcll2[8];
extern short filt8_dclh2[8];
#endif
extern short filt8_avlip0[8];
extern short filt8_avlip1[8];
extern short filt8_avlip2[8];
extern short filt8_avlip3[8];
extern short filt8_avlip4[8];
extern short filt8_avlip5[8];
extern short filt8_avlip6[8];
#endif
@@ -45,25 +45,23 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
static int max_pos_fil = 0;
static int count_max_pos_ok = 0;
static int first_time = 1;
int temp = 0, i, aa, max_val = 0, max_pos = 0;
int diff;
short Re,Im,ncoef;
int max_val = 0, max_pos = 0;
const int sync_pos = 0;
uint8_t sync_offset = 0;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ADJUST_SYNCH, VCD_FUNCTION_IN);
ncoef = 32767 - coef;
short ncoef = 32767 - coef;
LOG_D(PHY,"AbsSubframe %d: rx_offset (before) = %d\n",subframe,ue->rx_offset);
// we only use channel estimates from tx antenna 0 here
for (i = 0; i < frame_parms->nb_prefix_samples; i++) {
temp = 0;
for (int i = 0; i < frame_parms->nb_prefix_samples; i++) {
int temp = 0;
for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
Re = ((int16_t*)ue->pbch_vars[gNB_id]->dl_ch_estimates_time[aa])[(i<<1)];
Im = ((int16_t*)ue->pbch_vars[gNB_id]->dl_ch_estimates_time[aa])[1+(i<<1)];
for (int aa = 0; aa < frame_parms->nb_antennas_rx; aa++) {
int Re = ((int16_t*)ue->pbch_vars[gNB_id]->dl_ch_estimates_time[aa])[(i<<1)];
int Im = ((int16_t*)ue->pbch_vars[gNB_id]->dl_ch_estimates_time[aa])[1+(i<<1)];
temp += (Re*Re/2) + (Im*Im/2);
}
@@ -73,6 +71,9 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
}
}
if (max_pos > frame_parms->ofdm_symbol_size/2)
max_pos = max_pos - frame_parms->ofdm_symbol_size;
// filter position to reduce jitter
if (clear == 1)
max_pos_fil = max_pos;
@@ -82,61 +83,58 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
// do not filter to have proactive timing adjustment
//max_pos_fil = max_pos;
diff = max_pos_fil - (frame_parms->nb_prefix_samples>>3);
int diff = max_pos_fil - sync_pos;
if (frame_parms->freq_range==nr_FR2)
sync_offset = 2;
else
sync_offset = 0;
if ( abs(diff) < (SYNCH_HYST+sync_offset) )
ue->rx_offset = 0;
else
ue->rx_offset = diff;
if (frame_parms->freq_range==nr_FR2)
sync_offset = 2;
else
sync_offset = 0;
if(abs(diff)<5)
count_max_pos_ok ++;
else
count_max_pos_ok = 0;
//printf("adjust sync count_max_pos_ok = %d\n",count_max_pos_ok);
if ( abs(diff) < (SYNCH_HYST+sync_offset) )
ue->rx_offset = 0;
else
ue->rx_offset = diff;
if(count_max_pos_ok > 10 && first_time == 1)
{
first_time = 0;
ue->time_sync_cell = 1;
if (get_softmodem_params()->do_ra || get_softmodem_params()->sa) {
LOG_I(PHY,"[UE%d] Sending synch status to higher layers\n",ue->Mod_id);
//mac_resynch();
//dl_phy_sync_success(ue->Mod_id,frame,0,1);//ue->common_vars.eNb_id);
ue->UE_mode[0] = PRACH;
ue->prach_resources[gNB_id]->sync_frame = frame;
ue->prach_resources[gNB_id]->init_msg1 = 0;
} else {
ue->UE_mode[0] = PUSCH;
}
}
if(abs(diff)<5)
count_max_pos_ok ++;
else
count_max_pos_ok = 0;
//printf("adjust sync count_max_pos_ok = %d\n",count_max_pos_ok);
if (ue->rx_offset < 0)
ue->rx_offset += frame_parms->samples_per_frame;
if(count_max_pos_ok > 10 && first_time == 1)
{
first_time = 0;
ue->time_sync_cell = 1;
if (get_softmodem_params()->do_ra || get_softmodem_params()->sa) {
LOG_I(PHY,"[UE%d] Sending synch status to higher layers\n",ue->Mod_id);
//mac_resynch();
//dl_phy_sync_success(ue->Mod_id,frame,0,1);//ue->common_vars.eNb_id);
ue->UE_mode[0] = PRACH;
ue->prach_resources[gNB_id]->sync_frame = frame;
ue->prach_resources[gNB_id]->init_msg1 = 0;
} else {
ue->UE_mode[0] = PUSCH;
}
}
if (ue->rx_offset >= frame_parms->samples_per_frame)
ue->rx_offset -= frame_parms->samples_per_frame;
if (ue->rx_offset < 0)
ue->rx_offset += frame_parms->samples_per_frame;
if (ue->rx_offset >= frame_parms->samples_per_frame)
ue->rx_offset -= frame_parms->samples_per_frame;
#ifdef DEBUG_PHY
LOG_D(PHY,"AbsSubframe %d: diff = %i, rx_offset (final) = %i : clear = %d, max_pos = %d, max_pos_fil = %d, max_val = %d, sync_pos %d\n",
subframe,
diff,
ue->rx_offset,
clear,
max_pos,
max_pos_fil,
max_val,
sync_pos);
#endif //DEBUG_PHY
#ifdef DEBUG_PHY
LOG_D(PHY,"AbsSubframe %d: diff =%i rx_offset (final) = %i : clear %d,max_pos = %d,max_pos_fil = %d (peak %d) max_val %d target_pos %d \n",
subframe,
diff,
ue->rx_offset,
clear,
max_pos,
max_pos_fil,
temp,max_val,
(frame_parms->nb_prefix_samples>>3));
#endif //DEBUG_PHY
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ADJUST_SYNCH, VCD_FUNCTION_OUT);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ADJUST_SYNCH, VCD_FUNCTION_OUT);
}
File diff suppressed because it is too large Load Diff
+127 -134
View File
@@ -715,106 +715,102 @@ void pdcch_siso(NR_DL_FRAME_PARMS *frame_parms,
#ifdef NR_PDCCH_DCI_RUN
int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc) {
UE_nr_rxtx_proc_t *proc,
fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15) {
uint32_t frame = proc->frame_rx;
uint32_t slot = proc->nr_slot_rx;
NR_UE_COMMON *common_vars = &ue->common_vars;
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
NR_UE_PDCCH *pdcch_vars = ue->pdcch_vars[proc->thread_id][0];
fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15;
uint8_t log2_maxh, aarx;
int32_t avgs;
int32_t avgP[4];
for (int i=0;i<pdcch_vars->nb_search_space;i++) {
int n_rb,rb_offset;
get_coreset_rballoc(rel15->coreset.frequency_domain_resource,&n_rb,&rb_offset);
LOG_D(PHY,"pdcch coreset: freq %x, n_rb %d, rb_offset %d\n",
rel15->coreset.frequency_domain_resource[0],n_rb,rb_offset);
for (int s=rel15->coreset.StartSymbolIndex; s<(rel15->coreset.StartSymbolIndex+rel15->coreset.duration); s++) {
LOG_D(PHY,"in nr_pdcch_extract_rbs_single(rxdataF -> rxdataF_ext || dl_ch_estimates -> dl_ch_estimates_ext)\n");
rel15 = &pdcch_vars->pdcch_config[i];
int n_rb,rb_offset;
get_coreset_rballoc(rel15->coreset.frequency_domain_resource,&n_rb,&rb_offset);
nr_pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF,
pdcch_vars->dl_ch_estimates,
pdcch_vars->rxdataF_ext,
pdcch_vars->dl_ch_estimates_ext,
s,
frame_parms,
rel15->coreset.frequency_domain_resource,
n_rb,
rel15->BWPStart);
LOG_D(PHY,"pdcch coreset: freq %x, n_rb %d, rb_offset %d\n",
rel15->coreset.frequency_domain_resource[0],n_rb,rb_offset);
LOG_D(PHY,"we enter nr_pdcch_channel_level(avgP=%d) => compute channel level based on ofdm symbol 0, pdcch_vars[eNB_id]->dl_ch_estimates_ext\n",*avgP);
LOG_D(PHY,"in nr_pdcch_channel_level(dl_ch_estimates_ext -> dl_ch_estimates_ext)\n");
// compute channel level based on ofdm symbol 0
nr_pdcch_channel_level(pdcch_vars->dl_ch_estimates_ext,
frame_parms,
avgP,
n_rb);
avgs = 0;
for (int s=rel15->coreset.StartSymbolIndex; s<(rel15->coreset.StartSymbolIndex+rel15->coreset.duration); s++) {
LOG_D(PHY,"in nr_pdcch_extract_rbs_single(rxdataF -> rxdataF_ext || dl_ch_estimates -> dl_ch_estimates_ext)\n");
for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++)
avgs = cmax(avgs, avgP[aarx]);
nr_pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF,
pdcch_vars->dl_ch_estimates,
pdcch_vars->rxdataF_ext,
pdcch_vars->dl_ch_estimates_ext,
s,
frame_parms,
rel15->coreset.frequency_domain_resource,
n_rb,
rel15->BWPStart);
log2_maxh = (log2_approx(avgs) / 2) + 5; //+frame_parms->nb_antennas_rx;
LOG_D(PHY,"we enter nr_pdcch_channel_level(avgP=%d) => compute channel level based on ofdm symbol 0, pdcch_vars[eNB_id]->dl_ch_estimates_ext\n",*avgP);
LOG_D(PHY,"in nr_pdcch_channel_level(dl_ch_estimates_ext -> dl_ch_estimates_ext)\n");
// compute channel level based on ofdm symbol 0
nr_pdcch_channel_level(pdcch_vars->dl_ch_estimates_ext,
frame_parms,
avgP,
n_rb);
avgs = 0;
for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++)
avgs = cmax(avgs, avgP[aarx]);
log2_maxh = (log2_approx(avgs) / 2) + 1; //+frame_parms->nb_antennas_rx;
#ifdef UE_DEBUG_TRACE
LOG_D(PHY,"slot %d: pdcch log2_maxh = %d (%d,%d)\n",slot,log2_maxh,avgP[0],avgs);
LOG_D(PHY,"slot %d: pdcch log2_maxh = %d (%d,%d)\n",slot,log2_maxh,avgP[0],avgs);
#endif
#if T_TRACER
T(T_UE_PHY_PDCCH_ENERGY, T_INT(0), T_INT(0), T_INT(frame%1024), T_INT(slot),
T_INT(avgP[0]), T_INT(avgP[1]), T_INT(avgP[2]), T_INT(avgP[3]));
T(T_UE_PHY_PDCCH_ENERGY, T_INT(0), T_INT(0), T_INT(frame%1024), T_INT(slot),
T_INT(avgP[0]), T_INT(avgP[1]), T_INT(avgP[2]), T_INT(avgP[3]));
#endif
LOG_D(PHY,"we enter nr_pdcch_channel_compensation(log2_maxh=%d)\n",log2_maxh);
LOG_D(PHY,"in nr_pdcch_channel_compensation(rxdataF_ext x dl_ch_estimates_ext -> rxdataF_comp)\n");
// compute LLRs for ofdm symbol 0 only
nr_pdcch_channel_compensation(pdcch_vars->rxdataF_ext,
pdcch_vars->dl_ch_estimates_ext,
pdcch_vars->rxdataF_comp,
NULL,
frame_parms,
s,
log2_maxh,
n_rb); // log2_maxh+I0_shift
if (frame_parms->nb_antennas_rx > 1) {
LOG_D(PHY,"we enter nr_pdcch_detection_mrc(frame_parms->nb_antennas_rx=%d)\n", frame_parms->nb_antennas_rx);
nr_pdcch_detection_mrc(frame_parms, pdcch_vars->rxdataF_comp,s);
}
LOG_D(PHY,"we enter nr_pdcch_channel_compensation(log2_maxh=%d)\n",log2_maxh);
LOG_D(PHY,"in nr_pdcch_channel_compensation(rxdataF_ext x dl_ch_estimates_ext -> rxdataF_comp)\n");
// compute LLRs for ofdm symbol 0 only
nr_pdcch_channel_compensation(pdcch_vars->rxdataF_ext,
pdcch_vars->dl_ch_estimates_ext,
pdcch_vars->rxdataF_comp,
NULL,
frame_parms,
s,
log2_maxh,
n_rb); // log2_maxh+I0_shift
if (frame_parms->nb_antennas_rx > 1) {
LOG_D(PHY,"we enter nr_pdcch_detection_mrc(frame_parms->nb_antennas_rx=%d)\n", frame_parms->nb_antennas_rx);
nr_pdcch_detection_mrc(frame_parms, pdcch_vars->rxdataF_comp,s);
}
LOG_D(PHY,"we enter nr_pdcch_llr(for symbol %d), pdcch_vars[eNB_id]->rxdataF_comp ---> pdcch_vars[eNB_id]->llr \n",s);
LOG_D(PHY,"in nr_pdcch_llr(rxdataF_comp -> llr)\n");
nr_pdcch_llr(frame_parms,
pdcch_vars->rxdataF_comp,
pdcch_vars->llr,
s,
n_rb);
LOG_D(PHY,"we enter nr_pdcch_llr(for symbol %d), pdcch_vars[eNB_id]->rxdataF_comp ---> pdcch_vars[eNB_id]->llr \n",s);
LOG_D(PHY,"in nr_pdcch_llr(rxdataF_comp -> llr)\n");
nr_pdcch_llr(frame_parms,
pdcch_vars->rxdataF_comp,
pdcch_vars->llr,
s,
n_rb);
#if T_TRACER
// T(T_UE_PHY_PDCCH_IQ, T_INT(frame_parms->N_RB_DL), T_INT(frame_parms->N_RB_DL),
// T_INT(n_pdcch_symbols),
// T_BUFFER(pdcch_vars[eNB_id]->rxdataF_comp, frame_parms->N_RB_DL*12*n_pdcch_symbols* 4));
// T(T_UE_PHY_PDCCH_IQ, T_INT(frame_parms->N_RB_DL), T_INT(frame_parms->N_RB_DL),
// T_INT(n_pdcch_symbols),
// T_BUFFER(pdcch_vars[eNB_id]->rxdataF_comp, frame_parms->N_RB_DL*12*n_pdcch_symbols* 4));
#endif
#ifdef DEBUG_DCI_DECODING
printf("demapping: slot %d, mi %d\n",slot,get_mi(frame_parms,slot));
printf("demapping: slot %d, mi %d\n",slot,get_mi(frame_parms,slot));
#endif
}
}
LOG_D(PHY,"we enter nr_pdcch_demapping_deinterleaving()\n");
nr_pdcch_demapping_deinterleaving((uint32_t *) pdcch_vars->llr,
(uint32_t *) pdcch_vars->e_rx,
rel15->coreset.duration,
n_rb,
rel15->coreset.RegBundleSize,
rel15->coreset.InterleaverSize,
rel15->coreset.ShiftIndex,
rel15->number_of_candidates,
rel15->CCE,
rel15->L);
LOG_D(PHY,"we enter nr_pdcch_demapping_deinterleaving()\n");
nr_pdcch_demapping_deinterleaving((uint32_t *) pdcch_vars->llr,
(uint32_t *) pdcch_vars->e_rx,
rel15->coreset.duration,
n_rb,
rel15->coreset.RegBundleSize,
rel15->coreset.InterleaverSize,
rel15->coreset.ShiftIndex,
rel15->number_of_candidates,
rel15->CCE,
rel15->L);
/*
nr_pdcch_unscrambling(rel15->rnti,
frame_parms,
@@ -824,10 +820,9 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue,
// get_nCCE(n_pdcch_symbols, frame_parms, mi) * 72,
rel15->coreset.pdcch_dmrs_scrambling_id);
*/
LOG_D(PHY,"we end nr_pdcch_unscrambling()\n");
LOG_D(PHY,"Ending nr_rx_pdcch() function\n");
LOG_D(PHY,"we end nr_pdcch_unscrambling()\n");
LOG_D(PHY,"Ending nr_rx_pdcch() function\n");
}
return (0);
}
@@ -923,75 +918,73 @@ uint16_t nr_dci_false_detection(uint64_t *dci,
uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
fapi_nr_dci_indication_t *dci_ind) {
fapi_nr_dci_indication_t *dci_ind,
fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15) {
NR_UE_PDCCH *pdcch_vars = ue->pdcch_vars[proc->thread_id][0];
fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15;
for (int i=0;i<pdcch_vars->nb_search_space;i++) {
NR_UE_PDCCH *pdcch_vars = ue->pdcch_vars[proc->thread_id][0];
rel15 = &pdcch_vars->pdcch_config[i];
//int gNB_id = 0;
int16_t tmp_e[16*108];
rnti_t n_rnti;
//int gNB_id = 0;
int16_t tmp_e[16*108];
rnti_t n_rnti;
for (int j=0;j<rel15->number_of_candidates;j++) {
int CCEind = rel15->CCE[j];
int L = rel15->L[j];
for (int j=0;j<rel15->number_of_candidates;j++) {
int CCEind = rel15->CCE[j];
int L = rel15->L[j];
// Loop over possible DCI lengths
for (int k = 0; k < rel15->num_dci_options; k++) {
int dci_length = rel15->dci_length_options[k];
uint64_t dci_estimation[2]= {0};
const t_nrPolar_params *currentPtrDCI = nr_polar_params(NR_POLAR_DCI_MESSAGE_TYPE, dci_length, L, 1, &ue->polarList);
// Loop over possible DCI lengths
for (int k = 0; k < rel15->num_dci_options; k++) {
int dci_length = rel15->dci_length_options[k];
uint64_t dci_estimation[2]= {0};
const t_nrPolar_params *currentPtrDCI = nr_polar_params(NR_POLAR_DCI_MESSAGE_TYPE, dci_length, L, 1, &ue->polarList);
LOG_D(PHY, "Trying DCI candidate %d of %d number of candidates, CCE %d (%d), L %d\n", j, rel15->number_of_candidates, CCEind, CCEind*9*6*2, L);
LOG_D(PHY, "Trying DCI candidate %d of %d number of candidates, CCE %d (%d), L %d\n", j, rel15->number_of_candidates, CCEind, CCEind*9*6*2, L);
nr_pdcch_unscrambling(&pdcch_vars->e_rx[CCEind*108], rel15->coreset.scrambling_rnti, L*108, rel15->coreset.pdcch_dmrs_scrambling_id, tmp_e);
nr_pdcch_unscrambling(&pdcch_vars->e_rx[CCEind*108], rel15->coreset.scrambling_rnti, L*108, rel15->coreset.pdcch_dmrs_scrambling_id, tmp_e);
#ifdef DEBUG_DCI_DECODING
uint32_t * z = (uint32_t *) &pdcch_vars->e_rx[CCEind*108];
for (int index_z = 0; index_z < 96; index_z++){
for (int i=0; i<9; i++) {
LOG_D(PHY,"z[%d]=(%d,%d) \n", (9*index_z + i), *(int16_t *) &z[index_z + i],*(1 + (int16_t *) &z[index_z + i]));
}
}
#endif
uint16_t crc = polar_decoder_int16(tmp_e,
dci_estimation,
1,
currentPtrDCI);
n_rnti = rel15->rnti;
LOG_D(PHY, "(%i.%i) dci indication (rnti %x,dci format %s,n_CCE %d,payloadSize %d)\n",
proc->frame_rx, proc->nr_slot_rx,n_rnti,nr_dci_format_string[rel15->dci_format_options[k]],CCEind,dci_length);
if (crc == n_rnti) {
LOG_D(PHY, "(%i.%i) Received dci indication (rnti %x,dci format %s,n_CCE %d,payloadSize %d,payload %llx)\n",
proc->frame_rx, proc->nr_slot_rx,n_rnti,nr_dci_format_string[rel15->dci_format_options[k]],CCEind,dci_length,*(unsigned long long*)dci_estimation);
uint16_t mb = nr_dci_false_detection(dci_estimation,tmp_e,currentPtrDCI,L*108,n_rnti);
ue->dci_thres = (ue->dci_thres + mb) / 2;
if (mb > (ue->dci_thres+20)) {
LOG_W(PHY,"DCI false positive. Dropping DCI index %d. Mismatched bits: %d/%d. Current DCI threshold: %d\n",j,mb,L*108,ue->dci_thres);
continue;
}
else {
dci_ind->SFN = proc->frame_rx;
dci_ind->slot = proc->nr_slot_rx;
dci_ind->dci_list[dci_ind->number_of_dcis].rnti = n_rnti;
dci_ind->dci_list[dci_ind->number_of_dcis].n_CCE = CCEind;
dci_ind->dci_list[dci_ind->number_of_dcis].N_CCE = L;
dci_ind->dci_list[dci_ind->number_of_dcis].dci_format = rel15->dci_format_options[k];
dci_ind->dci_list[dci_ind->number_of_dcis].payloadSize = dci_length;
memcpy((void*)dci_ind->dci_list[dci_ind->number_of_dcis].payloadBits,(void*)dci_estimation,8);
dci_ind->number_of_dcis++;
break; // If DCI is found, no need to check for remaining DCI lengths
}
} else {
LOG_D(PHY,"(%i.%i) Decoded crc %x does not match rnti %x for DCI format %d\n", proc->frame_rx, proc->nr_slot_rx, crc, n_rnti, rel15->dci_format_options[k]);
#ifdef DEBUG_DCI_DECODING
uint32_t * z = (uint32_t *) &pdcch_vars->e_rx[CCEind*108];
for (int index_z = 0; index_z < 96; index_z++){
for (int i=0; i<9; i++) {
LOG_D(PHY,"z[%d]=(%d,%d) \n", (9*index_z + i), *(int16_t *) &z[index_z + i],*(1 + (int16_t *) &z[index_z + i]));
}
}
#endif
uint16_t crc = polar_decoder_int16(tmp_e,
dci_estimation,
1,
currentPtrDCI);
n_rnti = rel15->rnti;
LOG_D(PHY, "(%i.%i) dci indication (rnti %x,dci format %s,n_CCE %d,payloadSize %d)\n",
proc->frame_rx, proc->nr_slot_rx,n_rnti,nr_dci_format_string[rel15->dci_format_options[k]],CCEind,dci_length);
if (crc == n_rnti) {
LOG_D(PHY, "(%i.%i) Received dci indication (rnti %x,dci format %s,n_CCE %d,payloadSize %d,payload %llx)\n",
proc->frame_rx, proc->nr_slot_rx,n_rnti,nr_dci_format_string[rel15->dci_format_options[k]],CCEind,dci_length,*(unsigned long long*)dci_estimation);
uint16_t mb = nr_dci_false_detection(dci_estimation,tmp_e,currentPtrDCI,L*108,n_rnti);
ue->dci_thres = (ue->dci_thres + mb) / 2;
if (mb > (ue->dci_thres+20)) {
LOG_W(PHY,"DCI false positive. Dropping DCI index %d. Mismatched bits: %d/%d. Current DCI threshold: %d\n",j,mb,L*108,ue->dci_thres);
continue;
}
else {
dci_ind->SFN = proc->frame_rx;
dci_ind->slot = proc->nr_slot_rx;
dci_ind->dci_list[dci_ind->number_of_dcis].rnti = n_rnti;
dci_ind->dci_list[dci_ind->number_of_dcis].n_CCE = CCEind;
dci_ind->dci_list[dci_ind->number_of_dcis].N_CCE = L;
dci_ind->dci_list[dci_ind->number_of_dcis].dci_format = rel15->dci_format_options[k];
dci_ind->dci_list[dci_ind->number_of_dcis].payloadSize = dci_length;
memcpy((void*)dci_ind->dci_list[dci_ind->number_of_dcis].payloadBits,(void*)dci_estimation,8);
dci_ind->number_of_dcis++;
break; // If DCI is found, no need to check for remaining DCI lengths
}
} else {
LOG_D(PHY,"(%i.%i) Decoded crc %x does not match rnti %x for DCI format %d\n", proc->frame_rx, proc->nr_slot_rx, crc, n_rnti, rel15->dci_format_options[k]);
}
}
}
pdcch_vars->nb_search_space = 0;
return(dci_ind->number_of_dcis);
}
@@ -155,7 +155,7 @@ NR_UE_DLSCH_t *new_nr_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint
if (dlsch->harq_processes[i]) {
memset(dlsch->harq_processes[i],0,sizeof(NR_DL_UE_HARQ_t));
init_downlink_harq_status(dlsch->harq_processes[i]);
dlsch->harq_processes[i]->first_tx=1;
dlsch->harq_processes[i]->first_rx=1;
dlsch->harq_processes[i]->b = (uint8_t *)malloc16(dlsch_bytes);
if (dlsch->harq_processes[i]->b)
@@ -327,7 +327,9 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
dlsch->last_iteration_cnt = ret;
harq_process->G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, dmrs_length, harq_process->Qm,harq_process->Nl);
G = harq_process->G;
LOG_D(PHY,"DLSCH Decoding, harq_pid %d TBS %d (%d) G %d nb_re_dmrs %d mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,A/8,G, nb_re_dmrs,harq_process->mcs, harq_process->Nl, nb_symb_sch,nb_rb);
LOG_D(PHY,"DLSCH Decoding, harq_pid %d TBS %d (%d) G %d nb_re_dmrs %d length dmrs %d mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",
harq_pid,A,A/8,G, nb_re_dmrs, dmrs_length, harq_process->mcs, harq_process->Nl, nb_symb_sch,nb_rb);
if ((harq_process->R)<1024)
Coderate = (float) (harq_process->R) /(float) 1024;
@@ -358,7 +360,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
}
}
if (harq_process->round == 0) {
if (harq_process->first_rx == 1) {
// This is a new packet, so compute quantities regarding segmentation
if (A > NR_MAX_PDSCH_TBS)
harq_process->B = A+24;
@@ -448,7 +450,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
harq_process->w[r],
harq_process->C,
harq_process->rvidx,
(harq_process->round==0)?1:0,
(harq_process->first_rx==1)?1:0,
E,
harq_process->F,
Kr-harq_process->F-2*(p_decParams->Z))==-1) {
@@ -771,7 +773,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
}
}
if (harq_process->round == 0) {
if (harq_process->first_rx == 1) {
// This is a new packet, so compute quantities regarding segmentation
if (A > NR_MAX_PDSCH_TBS)
harq_process->B = A+24;
@@ -909,7 +911,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
harq_process->w[r],
harq_process->C,
harq_process->rvidx,
(harq_process->round==0)?1:0,
(harq_process->first_rx==1)?1:0,
E,
harq_process->F,
Kr-harq_process->F-2*(p_decParams->Z))==-1) {
@@ -1229,25 +1231,23 @@ void nr_dlsch_decoding_process(void *arg) {
}
}
harq_process->round =0;
if (harq_process->first_rx == 1) {
// This is a new packet, so compute quantities regarding segmentation
if (A > NR_MAX_PDSCH_TBS)
harq_process->B = A+24;
else
harq_process->B = A+16;
// if (harq_process->round == 0) {
// This is a new packet, so compute quantities regarding segmentation
if (A > NR_MAX_PDSCH_TBS)
harq_process->B = A+24;
else
harq_process->B = A+16;
nr_segmentation(NULL,
NULL,
harq_process->B,
&harq_process->C,
&harq_process->K,
&harq_process->Z,
&harq_process->F,
p_decParams->BG);
p_decParams->Z = harq_process->Z;
// }
nr_segmentation(NULL,
NULL,
harq_process->B,
&harq_process->C,
&harq_process->K,
&harq_process->Z,
&harq_process->F,
p_decParams->BG);
p_decParams->Z = harq_process->Z;
}
LOG_D(PHY,"round %d Z %d K %d BG %d\n", harq_process->round, p_decParams->Z, harq_process->K, p_decParams->BG);
p_decParams->numMaxIter = dlsch->max_ldpc_iterations;
p_decParams->outMode= 0;
@@ -1314,7 +1314,7 @@ void nr_dlsch_decoding_process(void *arg) {
harq_process->w[r],
harq_process->C,
harq_process->rvidx,
(harq_process->round==0)?1:0,
(harq_process->first_rx==1)?1:0,
E,
harq_process->F,
Kr-harq_process->F-2*(p_decParams->Z))==-1) {
@@ -445,8 +445,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
//LOG_I(PHY, "avgs Power per SC is %d\n", avgs);
median[(aatx*frame_parms->nb_antennas_rx)+aarx] = avg[(aatx*frame_parms->nb_antennas_rx)+aarx];
}
pdsch_vars[gNB_id]->log2_maxh = (log2_approx(avgs)/2) + 1;
//LOG_I(PHY, "avgs Power per SC is %d lg2_maxh %d\n", avgs, pdsch_vars[gNB_id]->log2_maxh);
if (dlsch0_harq->mimo_mode == NR_DUALSTREAM) {
nr_dlsch_channel_level_median(pdsch_vars[gNB_id]->dl_ch_estimates_ext,
@@ -461,8 +459,10 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
avgs = cmax(avgs, median[aatx*n_rx + aarx]);
}
}
pdsch_vars[gNB_id]->log2_maxh = (log2_approx(avgs)/2) + 1;
}
pdsch_vars[gNB_id]->log2_maxh = (log2_approx(avgs)/2) + 1;
//LOG_I(PHY, "avgs Power per SC is %d lg2_maxh %d\n", avgs, pdsch_vars[gNB_id]->log2_maxh);
}
LOG_D(PHY,"[DLSCH] AbsSubframe %d.%d log2_maxh = %d [log2_maxh0 %d log2_maxh1 %d] (%d,%d)\n",
frame%1024,
@@ -738,11 +738,11 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
}
void nr_dlsch_deinterleaving(uint8_t symbol,
uint8_t start_symbol,
uint16_t L,
uint16_t *llr,
uint16_t *llr_deint,
uint16_t nb_rb_pdsch)
uint8_t start_symbol,
uint16_t L,
uint16_t *llr,
uint16_t *llr_deint,
uint16_t nb_rb_pdsch)
{
uint32_t bundle_idx, N_bundle, R, C, r,c;
+77 -4
View File
@@ -36,8 +36,7 @@
#include "PHY/MODULATION/modulation_UE.h"
#include "nr_transport_proto_ue.h"
#include "PHY/NR_UE_ESTIMATION/nr_estimation.h"
//#include "SCHED/defs.h"
//#include "SCHED/extern.h"
#include "SCHED_NR_UE/defs.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "common_lib.h"
@@ -46,6 +45,7 @@
#include "PHY/NR_REFSIG/pss_nr.h"
#include "PHY/NR_REFSIG/sss_nr.h"
#include "PHY/NR_REFSIG/refsig_defs_ue.h"
#include "PHY/NR_TRANSPORT/nr_dci.h"
extern openair0_config_t openair0_cfg[];
//static nfapi_nr_config_request_t config_t;
@@ -201,7 +201,10 @@ int nr_pbch_detection(UE_nr_rxtx_proc_t * proc, PHY_VARS_NR_UE *ue, int pbch_ini
char duplex_string[2][4] = {"FDD","TDD"};
char prefix_string[2][9] = {"NORMAL","EXTENDED"};
int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, int n_frames)
int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
PHY_VARS_NR_UE *ue,
int n_frames, int sa,
int dlsch_parallel)
{
int32_t sync_pos, sync_pos_frame; // k_ssb, N_ssb_crb, sync_pos2,
@@ -349,7 +352,7 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, int n_frames)
}
}
else {
ret = -1;
ret = -1;
}
/* Consider this is a false detection if the offset is > 1000 Hz
@@ -479,6 +482,76 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, int n_frames)
}
// if stand alone and sync on ssb do sib1 detection as part of initial sync
if (sa==1 && ret==0) {
bool dec = false;
NR_UE_PDCCH *pdcch_vars = ue->pdcch_vars[proc->thread_id][0];
int gnb_id = 0; //FIXME
int coreset_nb_rb=0;
int coreset_start_rb=0;
for(int n_ss = 0; n_ss<pdcch_vars->nb_search_space; n_ss++) {
uint8_t nb_symb_pdcch = pdcch_vars->pdcch_config[n_ss].coreset.duration;
get_coreset_rballoc(pdcch_vars->pdcch_config[n_ss].coreset.frequency_domain_resource,&coreset_nb_rb,&coreset_start_rb);
for (uint16_t l=0; l<nb_symb_pdcch; l++) {
nr_slot_fep_init_sync(ue,
proc,
l, // the UE PHY has no notion of the symbols to be monitored in the search space
pdcch_vars->slot,
is*fp->samples_per_frame+pdcch_vars->sfn*fp->samples_per_frame+ue->rx_offset);
if (coreset_nb_rb > 0)
nr_pdcch_channel_estimation(ue,
proc,
0,
pdcch_vars->slot,
l,
fp->first_carrier_offset+(pdcch_vars->pdcch_config[n_ss].BWPStart + coreset_start_rb)*12,
coreset_nb_rb);
}
int dci_cnt = nr_ue_pdcch_procedures(gnb_id, ue, proc, n_ss);
if (dci_cnt>0){
NR_UE_DLSCH_t *dlsch = ue->dlsch_SI[gnb_id];
if (dlsch && (dlsch->active == 1)) {
uint8_t harq_pid = dlsch->current_harq_pid;
NR_DL_UE_HARQ_t *dlsch0_harq = dlsch->harq_processes[harq_pid];
uint16_t nb_symb_sch = dlsch0_harq->nb_symbols;
uint16_t start_symb_sch = dlsch0_harq->start_symbol;
for (uint16_t m=start_symb_sch;m<(nb_symb_sch+start_symb_sch) ; m++){
nr_slot_fep_init_sync(ue,
proc,
m,
pdcch_vars->slot, // same slot and offset as pdcch
is*fp->samples_per_frame+pdcch_vars->sfn*fp->samples_per_frame+ue->rx_offset);
}
int ret = nr_ue_pdsch_procedures(ue,
proc,
gnb_id,
SI_PDSCH,
ue->dlsch_SI[gnb_id],
NULL);
if (ret >= 0)
dec = nr_ue_dlsch_procedures(ue,
proc,
gnb_id,
SI_PDSCH,
ue->dlsch_SI[gnb_id],
NULL,
&ue->dlsch_SI_errors[gnb_id],
dlsch_parallel);
// deactivate dlsch once dlsch proc is done
ue->dlsch_SI[gnb_id]->active = 0;
}
}
}
if (dec == false) // sib1 not decoded
ret = -1;
}
// exit_fun("debug exit");
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_INITIAL_UE_SYNC, VCD_FUNCTION_OUT);
return ret;
+5 -1
View File
@@ -102,7 +102,11 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
nrUE_config->prach_config.num_prach_fd_occasions_list[fd_occasion].prach_root_sequence_index,
ue->X_u);
sample_offset_slot = (prachStartSymbol==0?0:fp->ofdm_symbol_size*prachStartSymbol+fp->nb_prefix_samples0+fp->nb_prefix_samples*(prachStartSymbol-1));
if (slot % (fp->slots_per_subframe / 2) == 0)
sample_offset_slot = (prachStartSymbol==0?0:fp->ofdm_symbol_size*prachStartSymbol+fp->nb_prefix_samples0+fp->nb_prefix_samples*(prachStartSymbol-1));
else
sample_offset_slot = (fp->ofdm_symbol_size + fp->nb_prefix_samples) * prachStartSymbol;
prach_start = fp->get_samples_slot_timestamp(slot, fp, 0) + sample_offset_slot;
//printf("prachstartsymbold %d, sample_offset_slot %d, prach_start %d\n",prachStartSymbol, sample_offset_slot, prach_start);
@@ -1044,7 +1044,8 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
uint8_t is_crnti,
uint8_t llr8_flag);
int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
NR_UE_ULSCH_t *ulsch,
NR_DL_FRAME_PARMS* frame_parms,
uint8_t harq_pid,
unsigned int G);
@@ -1119,7 +1120,8 @@ uint32_t dlsch_decoding_emul(PHY_VARS_NR_UE *phy_vars_ue,
uint8_t eNB_id);
int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc);
UE_nr_rxtx_proc_t *proc,
fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15);
/*! \brief Extract PSS and SSS resource elements
@@ -1454,7 +1456,9 @@ void generate_RIV_tables(void);
*/
int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
PHY_VARS_NR_UE *phy_vars_ue,
int n_frames);
int n_frames,
int sa,
int dlsch_parallel);
/*!
\brief This function gets the carrier frequencies either from FP or command-line-set global variables, depending on the availability of the latter
@@ -1708,7 +1712,8 @@ uint32_t lte_gold_generic(uint32_t *x1, uint32_t *x2, uint8_t reset);
uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
fapi_nr_dci_indication_t *dci_ind);
fapi_nr_dci_indication_t *dci_ind,
fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15);
/** \brief This function is the top-level entry point to PDSCH demodulation, after frequency-domain transformation and channel estimation. It performs
@@ -1744,6 +1749,8 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe);
void dump_nrdlsch(PHY_VARS_NR_UE *ue,uint8_t gNB_id,uint8_t nr_slot_rx,unsigned int *coded_bits_per_codeword,int round, unsigned char harq_pid);
void *dlsch_thread(void *arg);
/**@}*/
#endif
@@ -206,8 +206,8 @@ typedef struct {
} NR_UE_ULSCH_t;
typedef struct {
/// Indicator of first transmission
uint8_t first_tx;
/// Indicator of first reception
uint8_t first_rx;
/// Last Ndi received for this process on DCI (used for C-RNTI only)
uint8_t DCINdi;
/// DLSCH status flag indicating
+12 -11
View File
@@ -215,11 +215,13 @@ NR_UE_ULSCH_t *new_nr_ue_ulsch(uint16_t N_RB_UL,
}
int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
NR_UE_ULSCH_t *ulsch,
NR_DL_FRAME_PARMS* frame_parms,
uint8_t harq_pid,
unsigned int G)
{
start_meas(&ue->ulsch_encoding_stats);
/////////////////////////parameters and variables declaration/////////////////////////
///////////
@@ -332,6 +334,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_SEGMENTATION, VCD_FUNCTION_IN);
start_meas(&ue->ulsch_segmentation_stats);
Kb=nr_segmentation(harq_process->b,
harq_process->c,
harq_process->B,
@@ -340,6 +343,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
pz,
&harq_process->F,
harq_process->BG);
stop_meas(&ue->ulsch_segmentation_stats);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_SEGMENTATION, VCD_FUNCTION_OUT);
F = harq_process->F;
@@ -374,14 +378,6 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
//for (int i=0;i<68*384;i++)
// printf("channel_input[%d]=%d\n",i,channel_input[i]);
int temp_opp = 0;
if (opp_enabled) {
opp_enabled = 0;
temp_opp = 1;
}
/*printf("output %d %d %d %d %d \n", harq_process->d[0][0], harq_process->d[0][1], harq_process->d[r][2],harq_process->d[0][3], harq_process->d[0][4]);
for (int cnt =0 ; cnt < 66*(*pz); cnt ++){
printf("%d \n", harq_process->d[0][cnt]);
@@ -397,11 +393,13 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_LDPC_ENCODER_OPTIM, VCD_FUNCTION_IN);
start_meas(&ue->ulsch_ldpc_encoding_stats);
for(int j = 0; j < (harq_process->C/8 + 1); j++)
{
impp.macro_num = j;
nrLDPC_encoder(harq_process->c,harq_process->d,*pz,Kb,Kr,harq_process->BG,&impp);
}
stop_meas(&ue->ulsch_ldpc_encoding_stats);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_LDPC_ENCODER_OPTIM, VCD_FUNCTION_OUT);
@@ -412,8 +410,6 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
write_output("ulsch_enc_output0.m","enc0",&harq_process->d[0][0],(3*8*Kr_bytes)+12,1,4);
#endif
if (temp_opp) opp_enabled = 1;
///////////
///////////////////////////////////////////////////////////////////////////////
LOG_D(PHY,"setting ndi to %d from pusch_data\n", harq_process->pusch_pdu.pusch_data.new_data_indicator);
@@ -449,6 +445,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
Tbslbrm = nr_compute_tbslbrm(0,nb_rb,harq_process->pusch_pdu.nrOfLayers);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_RATE_MATCHING_LDPC, VCD_FUNCTION_IN);
start_meas(&ue->ulsch_rate_matching_stats);
nr_rate_matching_ldpc(Ilbrm,
Tbslbrm,
harq_process->BG,
@@ -460,6 +457,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
Kr-F-2*(*pz),
harq_process->pusch_pdu.pusch_data.rv_index,
E);
stop_meas(&ue->ulsch_rate_matching_stats);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_RATE_MATCHING_LDPC, VCD_FUNCTION_OUT);
@@ -481,10 +479,12 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
//start_meas(i_stats);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_INTERLEAVING_LDPC, VCD_FUNCTION_IN);
start_meas(&ue->ulsch_interleaving_stats);
nr_interleaving_ldpc(E,
mod_order,
harq_process->e+r_offset,
harq_process->f+r_offset);
stop_meas(&ue->ulsch_interleaving_stats);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_INTERLEAVING_LDPC, VCD_FUNCTION_OUT);
//stop_meas(i_stats);
@@ -509,5 +509,6 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_UE_ULSCH_ENCODING, VCD_FUNCTION_OUT);
stop_meas(&ue->ulsch_encoding_stats);
return(0);
}
+3 -2
View File
@@ -159,7 +159,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
nb_dmrs_re_per_rb, number_dmrs_symbols, mod_order, Nl);
nr_ulsch_encoding(ulsch_ue, frame_parms, harq_pid, G);
nr_ulsch_encoding(UE, ulsch_ue, frame_parms, harq_pid, G);
///////////
////////////////////////////////////////////////////////////////////
@@ -529,7 +529,8 @@ uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE,
nr_normal_prefix_mod(txdataF[ap],
&txdata[ap][tx_offset],
14,
frame_parms);
frame_parms,
slot);
}
}
+5 -4
View File
@@ -318,7 +318,7 @@ int do_pss_sss_extract_nr(PHY_VARS_NR_UE *ue,
int32_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR],
int32_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR],
uint8_t doPss, uint8_t doSss,
uint8_t subframe) // add flag to indicate extracting only PSS, only SSS, or both
uint8_t subframe) // add flag to indicate extracting only PSS, only SSS, or both
{
uint8_t aarx;
int32_t *pss_rxF,*pss_rxF_ext;
@@ -329,8 +329,8 @@ int do_pss_sss_extract_nr(PHY_VARS_NR_UE *ue,
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
pss_symbol = 0;
sss_symbol = SSS_SYMBOL_NB-PSS_SYMBOL_NB;
pss_symbol = 0;
sss_symbol = SSS_SYMBOL_NB-PSS_SYMBOL_NB;
rxdataF = ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF;
@@ -343,6 +343,7 @@ int do_pss_sss_extract_nr(PHY_VARS_NR_UE *ue,
sss_rxF_ext = &sss_ext[aarx][0];
unsigned int k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + 56;
if (k>= frame_parms->ofdm_symbol_size) k-=frame_parms->ofdm_symbol_size;
for (int i=0; i < LENGTH_PSS_NR; i++) {
@@ -401,7 +402,7 @@ int pss_sss_extract_nr(PHY_VARS_NR_UE *phy_vars_ue,
UE_nr_rxtx_proc_t *proc,
int32_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR],
int32_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR],
uint8_t subframe)
uint8_t subframe)
{
return do_pss_sss_extract_nr(phy_vars_ue, proc, pss_ext, sss_ext, 1 /* doPss */, 1 /* doSss */, subframe);
}
+2 -2
View File
@@ -264,7 +264,7 @@ double signal_energy_fp(double *s_re[2],double *s_im[2],uint32_t nb_antennas,uin
return(V/length/nb_antennas);
}
double signal_energy_fp2(struct complex *s,uint32_t length)
double signal_energy_fp2(struct complexd *s,uint32_t length)
{
int32_t i;
@@ -273,7 +273,7 @@ double signal_energy_fp2(struct complex *s,uint32_t length)
for (i=0; i<length; i++) {
// printf("signal_energy_fp2 : %f,%f => %f\n",s[i].x,s[i].y,V);
// V= V + (s[i].y*s[i].x) + (s[i].y*s[i].x);
V= V + (s[i].x*s[i].x) + (s[i].y*s[i].y);
V= V + (s[i].r*s[i].r) + (s[i].i*s[i].i);
}
return(V/length);
+1 -6
View File
@@ -39,11 +39,6 @@ extern "C" {
#define CEILIDIV(a,b) ((a+b-1)/b)
#define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1))
struct complex {
double x;
double y;
};
struct complexd {
double r;
double i;
@@ -468,7 +463,7 @@ double signal_energy_fp(double *s_re[2], double *s_im[2], uint32_t nb_antennas,
/*!\fn double signal_energy_fp2(struct complex *, uint32_t);
\brief Computes the signal energy per subcarrier
*/
double signal_energy_fp2(struct complex *s, uint32_t length);
double signal_energy_fp2(struct complexd *s, uint32_t length);
int32_t iSqrt(int32_t value);
+4
View File
@@ -819,6 +819,8 @@ typedef struct PHY_VARS_gNB_s {
uint32_t max_peak_val;
/// OFDM symbol offset divisor for UL
uint32_t ofdm_offset_divisor;
/// \brief sinr for all subcarriers of the current link (used only for abstraction).
/// first index: ? [0..N_RB_DL*12[
double *sinr_dB;
@@ -838,6 +840,8 @@ typedef struct PHY_VARS_gNB_s {
int **dl_precoder_SgNB[3];
char log2_maxp; /// holds the maximum channel/precoder coefficient
int prb_interpolation;
/// if ==0 enables phy only test mode
int mac_enabled;
/// counter to average prach energh over first 100 prach opportunities
+7 -1
View File
@@ -639,6 +639,9 @@ typedef struct {
uint8_t agregationLevel;
int nb_search_space;
fapi_nr_dl_config_dci_dl_pdu_rel15_t pdcch_config[FAPI_NR_MAX_SS_PER_CORESET];
// frame and slot for sib1 in initial sync
uint16_t sfn;
uint16_t slot;
/*
#ifdef NR_PDCCH_DEFS_NR_UE
int nb_searchSpaces;
@@ -865,7 +868,9 @@ typedef struct {
uint32_t perfect_ce;
// flag to activate PRB based averaging of channel estimates
// when off, defaults to frequency domain interpolation
int prb_interpolation;
int generate_ul_signal[NUMBER_OF_CONNECTED_gNB_MAX];
UE_NR_SCAN_INFO_t scan_info[NB_BANDS_MAX];
@@ -1002,6 +1007,7 @@ typedef struct {
time_stats_t ofdm_mod_stats;
time_stats_t ulsch_encoding_stats;
time_stats_t ulsch_ldpc_encoding_stats;
time_stats_t ulsch_modulation_stats;
time_stats_t ulsch_segmentation_stats;
time_stats_t ulsch_rate_matching_stats;
+5
View File
@@ -329,6 +329,9 @@ struct NR_DL_FRAME_PARMS {
/// sequence which is computed based on carrier frequency and numerology to rotate/derotate each OFDM symbol according to Section 5.3 in 38.211
/// First dimension is for the direction of the link (0 DL, 1 UL)
int16_t symbol_rotation[2][224*2];
/// sequence used to compensate the phase rotation due to timeshifted OFDM symbols
/// First dimenstion is for different CP lengths
int16_t timeshift_symbol_rotation[4096*2] __attribute__ ((aligned (16)));
/// shift of pilot position in one RB
uint8_t nushift;
/// SRS configuration from TS 38.331 RRC
@@ -362,6 +365,8 @@ struct NR_DL_FRAME_PARMS {
uint8_t ssb_index;
/// PBCH polar encoder params
t_nrPolar_params pbch_polar_params;
/// OFDM symbol offset divisor for UL
uint32_t ofdm_offset_divisor;
};
+4
View File
@@ -17,6 +17,10 @@ void handle_nr_nfapi_pdsch_pdu(PHY_VARS_gNB *gNB,int frame,int slot,
nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu,
uint8_t *sdu){
}
void handle_nfapi_nr_csirs_pdu(PHY_VARS_gNB *gNB,
int frame, int slot,
nfapi_nr_dl_tti_csi_rs_pdu *csirs_pdu){
}
int l1_north_init_gNB(void){return 0;}
uint8_t slot_ahead=6;
+4
View File
@@ -17,6 +17,10 @@ void handle_nr_nfapi_pdsch_pdu(PHY_VARS_gNB *gNB,int frame,int slot,
nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu,
uint8_t *sdu){
}
void handle_nfapi_nr_csirs_pdu(PHY_VARS_gNB *gNB,
int frame, int slot,
nfapi_nr_dl_tti_csi_rs_pdu *csirs_pdu){
}
int l1_north_init_gNB(void){return 0;}
uint8_t slot_ahead=6;
+61 -76
View File
@@ -181,71 +181,64 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){
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;
uint8_t number_tx_data_pdu = (TX_req == NULL) ? 0 : TX_req->Number_of_PDUs;
if (DL_req != NULL && TX_req!=NULL)
LOG_D(PHY,"NFAPI: Sched_INFO:SFN/SLOT:%04d/%d DL_req:SFN/SLO:%04d/%d:dl_pdu:%d tx_req:SFN/SLOT:%04d/%d:pdus:%d;ul_dci %d ul_tti %d\n",
frame,slot,
DL_req->SFN,DL_req->Slot,number_dl_pdu,
TX_req->SFN,TX_req->Slot,TX_req->Number_of_PDUs,
number_ul_dci_pdu,number_ul_tti_pdu);
if (NFAPI_MODE == NFAPI_MONOLITHIC){
if (DL_req != NULL && TX_req!=NULL)
LOG_D(PHY,"NFAPI: Sched_INFO:SFN/SLOT:%04d/%d DL_req:SFN/SLO:%04d/%d:dl_pdu:%d tx_req:SFN/SLOT:%04d/%d:pdus:%d;ul_dci %d ul_tti %d\n",
frame,slot,
DL_req->SFN,DL_req->Slot,number_dl_pdu,
TX_req->SFN,TX_req->Slot,TX_req->Number_of_PDUs,
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;
}
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;
}
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:
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,
dl_tti_pdu);
break;
if(NFAPI_MODE != NFAPI_MODE_VNF)
handle_nr_nfapi_ssb_pdu(gNB,frame,slot,
dl_tti_pdu);
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);
pdcch_received = 1;
break;
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,
&dl_tti_pdu->csi_rs_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");
if(NFAPI_MODE != NFAPI_MODE_VNF)
handle_nfapi_nr_pdcch_pdu(gNB,
frame, slot,
&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,
&dl_tti_pdu->csi_rs_pdu);
break;
case NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE:
{
LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE for %d.%d\n",frame,slot,DL_req->SFN,DL_req->Slot);
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdu->pdsch_pdu.pdsch_pdu_rel15;
uint16_t pduIndex = pdsch_pdu_rel15->pduIndex;
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;
if(NFAPI_MODE != NFAPI_MODE_VNF)
handle_nr_nfapi_pdsch_pdu(gNB,frame,slot,&dl_tti_pdu->pdsch_pdu, sdu);
case NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE:
LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE for %d.%d\n",frame,slot,DL_req->SFN,DL_req->Slot);
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdu->pdsch_pdu.pdsch_pdu_rel15;
uint16_t pduIndex = pdsch_pdu_rel15->pduIndex;
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;
}
}
}
// if (UL_tti_req!=NULL) memcpy(&gNB->UL_tti_req,UL_tti_req,sizeof(nfapi_nr_ul_tti_request_t));
if(NFAPI_MODE != NFAPI_MODE_VNF)
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]);
}
if(NFAPI_MODE != NFAPI_MODE_VNF)
for (int i = 0; i < number_ul_tti_pdu; i++) {
switch (UL_tti_req->pdus_list[i].pdu_type) {
case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE:
@@ -264,30 +257,22 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){
break;
}
}
if(NFAPI_MODE != NFAPI_MONOLITHIC && number_ul_tti_pdu>0)
{
oai_nfapi_ul_tti_req(UL_tti_req);
}
if (NFAPI_MODE != NFAPI_MONOLITHIC && Sched_INFO->UL_dci_req->numPdus!=0)
{
oai_nfapi_ul_dci_req(Sched_INFO->UL_dci_req);
if (NFAPI_MODE == NFAPI_MODE_VNF) { //If VNF, oai_nfapi functions send respective p7 msgs to PNF for which nPDUs is greater than 0
if(number_ul_tti_pdu>0)
oai_nfapi_ul_tti_req(UL_tti_req);
if (number_ul_dci_pdu>0)
oai_nfapi_ul_dci_req(UL_dci_req);
if (number_dl_pdu>0)
oai_nfapi_dl_tti_req(DL_req);
if (number_tx_data_pdu>0)
oai_nfapi_tx_data_req(TX_req);
}
if (NFAPI_MODE != NFAPI_MONOLITHIC)
{
if(Sched_INFO->DL_req->dl_tti_request_body.nPDUs>0)
{
Sched_INFO->DL_req->SFN = frame;
Sched_INFO->DL_req->Slot = slot;
oai_nfapi_dl_tti_req(Sched_INFO->DL_req);
}
if (Sched_INFO->TX_req->Number_of_PDUs > 0)
{
oai_nfapi_tx_data_req(Sched_INFO->TX_req);
}
}
}
+2
View File
@@ -119,6 +119,7 @@ void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa) {
fp->nb_prefix_samples,
CYCLIC_PREFIX);
slot_offset += fp->nb_prefix_samples+fp->ofdm_symbol_size;
slot_offsetF += fp->ofdm_symbol_size;
}
else {
PHY_ofdm_mod(&ru->common.txdataF_BF[aa][slot_offsetF],
@@ -128,6 +129,7 @@ void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa) {
fp->nb_prefix_samples0,
CYCLIC_PREFIX);
slot_offset += fp->nb_prefix_samples0+fp->ofdm_symbol_size;
slot_offsetF += fp->ofdm_symbol_size;
}
}
}
+13 -7
View File
@@ -147,14 +147,14 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_COMMON_TX,1);
if (NFAPI_MODE == NFAPI_MONOLITHIC || NFAPI_MODE == NFAPI_MODE_PNF) {
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;
}
for (int i=0; i<fp->Lmax; i++) {
if (gNB->ssb[i].active) {
nr_common_signal_procedures(gNB,frame,slot,gNB->ssb[i].ssb_pdu);
gNB->ssb[i].active = false;
}
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_COMMON_TX,0);
int pdcch_pdu_id=find_nr_pdcch(frame,slot,gNB,SEARCH_EXIST);
@@ -383,7 +383,13 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH
// scale the 16 factor in N_TA calculation in 38.213 section 4.2 according to the used FFT size
uint16_t bw_scaling = 16 * gNB->frame_parms.ofdm_symbol_size / 2048;
timing_advance_update = sync_pos / bw_scaling;
int sync_pos_rounded;
// do some integer rounding to improve TA accuracy
if (sync_pos > 0)
sync_pos_rounded = sync_pos + (bw_scaling / 2) - 1;
else
sync_pos_rounded = sync_pos - (bw_scaling / 2) - 1;
timing_advance_update = sync_pos_rounded / bw_scaling;
// put timing advance command in 0..63 range
timing_advance_update += 31;
+19
View File
@@ -420,6 +420,25 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind,
NR_UE_DLSCH_t *dlsch1,
uint16_t n_pdus);
bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
int gNB_id,
PDSCH_t pdsch,
NR_UE_DLSCH_t *dlsch0,
NR_UE_DLSCH_t *dlsch1,
int *dlsch_errors,
uint8_t dlsch_parallel);
int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
int eNB_id, PDSCH_t pdsch,
NR_UE_DLSCH_t *dlsch0, NR_UE_DLSCH_t *dlsch1);
int nr_ue_pdcch_procedures(uint8_t gNB_id,
PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
int n_ss);
#endif

Some files were not shown because too many files have changed in this diff Show More