Merge remote-tracking branch 'origin/develop' into NR_2port_CSIRS

This commit is contained in:
francescomani
2021-11-26 11:34:22 +01:00
67 changed files with 15328 additions and 10776 deletions
+6 -11
View File
@@ -246,17 +246,12 @@ pipeline {
script {
triggerSlaveJob ('RAN-DockerHub-Push', 'Push-to-Docker-Hub')
}
post {
always {
script {
echo "Push to Docker-Hub OK"
}
}
failure {
script {
echo "Push to Docker-Hub KO"
currentBuild.result = 'FAILURE'
}
}
post {
failure {
script {
echo "Push to Docker-Hub KO"
currentBuild.result = 'FAILURE'
}
}
}
+6 -3
View File
@@ -33,9 +33,12 @@ pipeline {
stages {
stage ("gDashboard") {
steps {
script {
//retrieve MR data from gitlab and export to gSheet
sh returnStdout: true, script: 'python3 ci-scripts/ran_dashboard.py'
script {
dir ("ci-scripts/ran_dashboard") {
//retrieve MR data from gitlab / mySQL db, build HTML pages and load them to AWS S3 bucket (configured as static web page hosting)
//deprecated method : sh returnStdout: true, script: 'python3 ran_dashboard.py'
sh returnStdout: true, script: 'python3 Hdashboard.py'
}
}
}
}
+15 -8
View File
@@ -227,6 +227,8 @@ class Containerize():
if result is not None:
forceSharedImageBuild = True
sharedTag = 'ci-temp'
else:
forceSharedImageBuild = True
# Let's remove any previous run artifacts if still there
mySSH.command(self.cli + ' image prune --force', '\$', 30)
@@ -578,6 +580,8 @@ class Containerize():
# Currently support only one
mySSH.command('docker-compose --file ci-docker-compose.yml config', '\$', 5)
result = re.search('container_name: (?P<container_name>[a-zA-Z0-9\-\_]+)', mySSH.getBefore())
if self.eNB_logFile[self.eNB_instance] == '':
self.eNB_logFile[self.eNB_instance] = 'enb_' + HTML.testCase_id + '.log'
if result is not None:
containerName = result.group('container_name')
mySSH.command('docker kill --signal INT ' + containerName, '\$', 30)
@@ -718,7 +722,7 @@ class Containerize():
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'
cmd = 'docker exec ' + self.pingContName + ' /bin/bash -c "ping ' + self.pingOptions + '" 2>&1 | tee ../cmake_targets/log/ping_' + HTML.testCase_id + '.log || true'
logging.debug(cmd)
deployStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=100)
@@ -784,18 +788,18 @@ class Containerize():
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"'
cmd = 'docker exec -d ' + self.svrContName + ' /bin/bash -c "nohup iperf ' + self.svrOptions + ' > /tmp/iperf_server.log 2>&1" || true'
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'
cmd = 'docker exec ' + self.cliContName + ' /bin/bash -c "iperf ' + self.cliOptions + '" 2>&1 | tee ../cmake_targets/log/iperf_client_' + HTML.testCase_id + '.log || true'
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"'
cmd = 'docker exec ' + self.svrContName + ' /bin/bash -c "pkill iperf" || true'
logging.debug(cmd)
serverStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=10)
time.sleep(5)
@@ -812,6 +816,7 @@ class Containerize():
else:
message = 'Server Report and Connection refused Not Found!'
self.IperfExit(HTML, False, message)
logging.error('\u001B[1;37;41m Iperf Test FAIL\u001B[0m')
return
# Computing the requested bandwidth in float
@@ -884,6 +889,8 @@ class Containerize():
self.IperfExit(HTML, iperfStatus, 'problem?')
if iperfStatus:
logging.info('\u001B[1m Iperf Test PASS\u001B[0m')
else:
logging.error('\u001B[1;37;41m Iperf Test FAIL\u001B[0m')
def IperfExit(self, HTML, status, message):
html_queue = SimpleQueue()
@@ -921,7 +928,7 @@ class Containerize():
if result is None:
mySSH.command('echo ' + password + ' | sudo -S sysctl net.ipv4.conf.all.forwarding=1', '\$', 10)
# Check if iptables forwarding is accepted
mySSH.command('echo ' + password + ' | sudo -S iptables -L', '\$', 10)
mySSH.command('echo ' + password + ' | sudo -S iptables -L FORWARD', '\$', 10)
result = re.search('Chain FORWARD .*policy ACCEPT', mySSH.getBefore())
if result is None:
mySSH.command('echo ' + password + ' | sudo -S iptables -P FORWARD ACCEPT', '\$', 10)
@@ -949,7 +956,7 @@ class Containerize():
if result is None:
mySSH.command('echo ' + password + ' | sudo -S sysctl net.ipv4.conf.all.forwarding=1', '\$', 10)
# Check if iptables forwarding is accepted
mySSH.command('echo ' + password + ' | sudo -S iptables -L', '\$', 10)
mySSH.command('echo ' + password + ' | sudo -S iptables -L FORWARD', '\$', 10)
result = re.search('Chain FORWARD .*policy ACCEPT', mySSH.getBefore())
if result is None:
mySSH.command('echo ' + password + ' | sudo -S iptables -P FORWARD ACCEPT', '\$', 10)
@@ -977,7 +984,7 @@ class Containerize():
if result is None:
mySSH.command('echo ' + password + ' | sudo -S sysctl net.ipv4.conf.all.forwarding=1', '\$', 10)
# Check if iptables forwarding is accepted
mySSH.command('echo ' + password + ' | sudo -S iptables -L', '\$', 10)
mySSH.command('echo ' + password + ' | sudo -S iptables -L FORWARD', '\$', 10)
result = re.search('Chain FORWARD .*policy ACCEPT', mySSH.getBefore())
if result is None:
mySSH.command('echo ' + password + ' | sudo -S iptables -P FORWARD ACCEPT', '\$', 10)
@@ -1000,7 +1007,7 @@ class Containerize():
if result is None:
mySSH.command('echo ' + password + ' | sudo -S sysctl net.ipv4.conf.all.forwarding=1', '\$', 10)
# Check if iptables forwarding is accepted
mySSH.command('echo ' + password + ' | sudo -S iptables -L', '\$', 10)
mySSH.command('echo ' + password + ' | sudo -S iptables -L FORWARD', '\$', 10)
result = re.search('Chain FORWARD .*policy ACCEPT', mySSH.getBefore())
if result is None:
mySSH.command('echo ' + password + ' | sudo -S iptables -P FORWARD ACCEPT', '\$', 10)
+3 -3
View File
@@ -76,7 +76,7 @@ class Module_UE:
logging.debug('Starting ' + self.Process['Name'])
mySSH = sshconnection.SSHConnection()
mySSH.open(self.HostIPAddress, self.HostUsername, self.HostPassword)
mySSH.command('echo $USER; echo ' + self.HostPassword + ' | nohup sudo -S ' + self.Process['Cmd'] + ' ' + self.Process['Apn'][CNType] + ' &','\$',5)
mySSH.command('echo $USER; echo ' + self.HostPassword + ' | nohup sudo -S ' + self.Process['Cmd'] + ' ' + self.Process['Apn'][CNType] + ' > /dev/null 2>&1 &','\$',5)
mySSH.close()
#checking the process
time.sleep(5)
@@ -165,7 +165,7 @@ class Module_UE:
#delete old artifacts
mySSH.command('echo ' + self.HostPassword + ' | sudo -S rm -rf ci_qlog','\$',5)
#start Trace, artifact is created in home dir
mySSH.command('echo $USER; nohup sudo -E QLog/QLog -s ci_qlog -f NR5G.cfg &','\$', 5)
mySSH.command('echo $USER; nohup sudo -E QLog/QLog -s ci_qlog -f NR5G.cfg > /dev/null 2>&1 &','\$', 5)
mySSH.close()
def DisableTrace(self):
@@ -192,7 +192,7 @@ class Module_UE:
source='ci_qlog'
destination= self.LogStore + '/ci_qlog_'+now_string+'.zip'
#qlog artifact is zipped into the target folder
mySSH.command('echo $USER; echo ' + self.HostPassword + ' | nohup sudo -S zip -r '+destination+' '+source+' &','\$', 10)
mySSH.command('echo $USER; echo ' + self.HostPassword + ' | nohup sudo -S zip -r '+destination+' '+source+' > /dev/null 2>&1 &','\$', 10)
mySSH.close()
#post action : log cleaning to make sure enough space is reserved for the next run
Log_Mgt=cls_log_mgt.Log_Mgt(self.HostUsername,self.HostIPAddress, self.HostPassword, self.LogStore)
+59 -49
View File
@@ -368,7 +368,7 @@ class OaiCiTest():
except:
os.kill(os.getppid(),signal.SIGUSR1)
def InitializeUE(self,HTML,RAN,EPC, COTS_UE, InfraUE,ue_trace):
def InitializeUE(self,HTML,RAN,EPC, COTS_UE, InfraUE,ue_trace,CONTAINERS):
if self.ue_id=='':#no ID specified, then it is a COTS controlled by ADB
if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '':
HELP.GenericHelp(CONST.Version)
@@ -424,12 +424,12 @@ class OaiCiTest():
Module_UE.CheckModuleMTU()
else: #status==-1 failed to retrieve IP address
HTML.CreateHtmlTestRow('N/A', 'KO', CONST.UE_IP_ADDRESS_ISSUE)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS)
return
def InitializeOAIUE(self,HTML,RAN,EPC,COTS_UE,InfraUE):
def InitializeOAIUE(self,HTML,RAN,EPC,COTS_UE,InfraUE,CONTAINERS):
if self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '' or self.UESourceCodePath == '':
HELP.GenericHelp(CONST.Version)
sys.exit('Insufficient Parameter')
@@ -653,7 +653,7 @@ class OaiCiTest():
HTML.htmlUEFailureMsg='nr-uesoftmodem did NOT synced'
HTML.CreateHtmlTestRow(self.air_interface + ' ' + self.Initialize_OAI_UE_args, 'KO', CONST.OAI_UE_PROCESS_COULD_NOT_SYNC, 'OAI UE')
logging.error('\033[91mInitialize OAI UE Failed! \033[0m')
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS)
def checkDevTTYisUnlocked(self):
SSH = sshconnection.SSHConnection()
@@ -731,7 +731,7 @@ class OaiCiTest():
HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
self.checkDevTTYisUnlocked()
def AttachCatM(self,HTML,RAN,COTS_UE,EPC,InfraUE):
def AttachCatM(self,HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS):
if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '':
HELP.GenericHelp(CONST.Version)
sys.exit('Insufficient Parameter')
@@ -804,9 +804,9 @@ class OaiCiTest():
html_cell = '<pre style="background-color:white">CAT-M module Attachment Failed</pre>'
html_queue.put(html_cell)
HTML.CreateHtmlTestRowQueue('N/A', 'KO', 1, html_queue)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS)
def PingCatM(self,HTML,RAN,EPC,COTS_UE,InfraUE):
def PingCatM(self,HTML,RAN,EPC,COTS_UE,InfraUE,CONTAINERS):
if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.SourceCodePath == '':
HELP.GenericHelp(CONST.Version)
sys.exit('Insufficient Parameter')
@@ -815,7 +815,7 @@ class OaiCiTest():
pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE,RAN,EPC)
if (pStatus < 0):
HTML.CreateHtmlTestRow(self.ping_args, 'KO', pStatus)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS)
return
try:
statusQueue = SimpleQueue()
@@ -836,7 +836,7 @@ class OaiCiTest():
moduleIPAddr = result.group('ipaddr')
else:
HTML.CreateHtmlTestRow(self.ping_args, 'KO', pStatus)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS)
return
ping_time = re.findall("-c (\d+)",str(self.ping_args))
device_id = 'catm'
@@ -900,7 +900,7 @@ class OaiCiTest():
HTML.CreateHtmlTestRowQueue(self.ping_args, 'OK', 1, statusQueue)
else:
HTML.CreateHtmlTestRowQueue(self.ping_args, 'KO', 1, statusQueue)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS)
except:
os.kill(os.getppid(),signal.SIGUSR1)
@@ -992,7 +992,7 @@ class OaiCiTest():
except:
os.kill(os.getppid(),signal.SIGUSR1)
def AttachUE(self,HTML,RAN,EPC,COTS_UE,InfraUE):
def AttachUE(self,HTML,RAN,EPC,COTS_UE,InfraUE,CONTAINERS):
if self.ue_id=='':#no ID specified, then it is a COTS controlled by ADB
if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '':
HELP.GenericHelp(CONST.Version)
@@ -1002,7 +1002,7 @@ class OaiCiTest():
pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE,RAN,EPC)
if (pStatus < 0):
HTML.CreateHtmlTestRow('N/A', 'KO', pStatus)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS)
return
multi_jobs = []
status_queue = SimpleQueue()
@@ -1021,7 +1021,7 @@ class OaiCiTest():
if (status_queue.empty()):
HTML.CreateHtmlTestRow('N/A', 'KO', CONST.ALL_PROCESSES_OK)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS)
return
else:
attach_status = True
@@ -1050,7 +1050,7 @@ class OaiCiTest():
time.sleep(5)
else:
HTML.CreateHtmlTestRowQueue('N/A', 'KO', len(self.UEDevices), html_queue)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS)
else: #if an ID is specified, it is a module from the yaml infrastructure file
#Attention, as opposed to InitializeUE, the connect manager process is not checked as it is supposed to be active already
@@ -1086,7 +1086,7 @@ class OaiCiTest():
Module_UE.CheckModuleMTU()
else: #status==-1 failed to retrieve IP address
HTML.CreateHtmlTestRow('N/A', 'KO', CONST.UE_IP_ADDRESS_ISSUE)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS)
return
def DetachUE_common(self, device_id, idx,COTS_UE):
@@ -1111,7 +1111,7 @@ class OaiCiTest():
except:
os.kill(os.getppid(),signal.SIGUSR1)
def DetachUE(self,HTML,RAN,EPC,COTS_UE,InfraUE):
def DetachUE(self,HTML,RAN,EPC,COTS_UE,InfraUE,CONTAINERS):
if self.ue_id=='':#no ID specified, then it is a COTS controlled by ADB
if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '':
HELP.GenericHelp(CONST.Version)
@@ -1121,7 +1121,7 @@ class OaiCiTest():
pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE,RAN,EPC)
if (pStatus < 0):
HTML.CreateHtmlTestRow('N/A', 'KO', pStatus)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS)
return
multi_jobs = []
cnt = 0
@@ -1396,7 +1396,7 @@ class OaiCiTest():
except:
os.kill(os.getppid(),signal.SIGUSR1)
def CheckStatusUE(self,HTML,RAN,EPC,COTS_UE,InfraUE):
def CheckStatusUE(self,HTML,RAN,EPC,COTS_UE,InfraUE,CONTAINERS):
if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '':
HELP.GenericHelp(CONST.Version)
sys.exit('Insufficient Parameter')
@@ -1443,7 +1443,7 @@ class OaiCiTest():
if (status_queue.empty()):
HTML.CreateHtmlTestRow(htmlOptions, 'KO', CONST.ALL_PROCESSES_OK)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS)
else:
check_status = True
html_queue = SimpleQueue()
@@ -1459,7 +1459,7 @@ class OaiCiTest():
HTML.CreateHtmlTestRowQueue(htmlOptions, 'OK', len(self.UEDevices), html_queue)
else:
HTML.CreateHtmlTestRowQueue(htmlOptions, 'KO', len(self.UEDevices), html_queue)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS)
def GetAllUEIPAddresses(self):
SSH = sshconnection.SSHConnection()
@@ -1686,14 +1686,14 @@ class OaiCiTest():
html_queue.put(html_cell)
HTML.CreateHtmlTestRowQueue(self.ping_args, 'KO', len(self.UEDevices), html_queue)
def PingNoS1(self,HTML,RAN,EPC,COTS_UE,InfraUE):
def PingNoS1(self,HTML,RAN,EPC,COTS_UE,InfraUE,CONTAINERS):
SSH=sshconnection.SSHConnection()
check_eNB = True
check_OAI_UE = True
pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE,RAN,EPC)
if (pStatus < 0):
HTML.CreateHtmlTestRow(self.ping_args, 'KO', pStatus)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS)
return
ping_from_eNB = re.search('oaitun_enb1', str(self.ping_args))
if ping_from_eNB is not None:
@@ -1779,10 +1779,10 @@ class OaiCiTest():
except:
os.kill(os.getppid(),signal.SIGUSR1)
def Ping(self,HTML,RAN,EPC,COTS_UE, InfraUE):
def Ping(self,HTML,RAN,EPC,COTS_UE, InfraUE, CONTAINERS):
result = re.search('noS1', str(RAN.Initialize_eNB_args))
if result is not None:
self.PingNoS1(HTML,RAN,EPC,COTS_UE,InfraUE)
self.PingNoS1(HTML,RAN,EPC,COTS_UE,InfraUE,CONTAINERS)
return
if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.SourceCodePath == '':
HELP.GenericHelp(CONST.Version)
@@ -1795,7 +1795,7 @@ class OaiCiTest():
pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE,RAN,EPC)
if (pStatus < 0):
HTML.CreateHtmlTestRow(self.ping_args, 'KO', pStatus)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS)
return
if self.ue_id=="":
@@ -1803,7 +1803,7 @@ class OaiCiTest():
ueIpStatus = self.GetAllUEIPAddresses()
if (ueIpStatus < 0):
HTML.CreateHtmlTestRow(self.ping_args, 'KO', CONST.UE_IP_ADDRESS_ISSUE)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS)
return
else:
self.UEIPAddresses=[]
@@ -1830,7 +1830,7 @@ class OaiCiTest():
if (status_queue.empty()):
HTML.CreateHtmlTestRow(self.ping_args, 'KO', CONST.ALL_PROCESSES_OK)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS)
else:
ping_status = True
html_queue = SimpleQueue()
@@ -1847,7 +1847,7 @@ class OaiCiTest():
HTML.CreateHtmlTestRowQueue(self.ping_args, 'OK', len(self.UEDevices), html_queue)
else:
HTML.CreateHtmlTestRowQueue(self.ping_args, 'KO', len(self.UEDevices), html_queue)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS)
def Iperf_ComputeTime(self):
result = re.search('-t (?P<iperf_time>\d+)', str(self.iperf_args))
@@ -2647,7 +2647,7 @@ class OaiCiTest():
except:
os.kill(os.getppid(),signal.SIGUSR1)
def IperfNoS1(self,HTML,RAN,EPC,COTS_UE,InfraUE):
def IperfNoS1(self,HTML,RAN,EPC,COTS_UE,InfraUE,CONTAINERS):
SSH = sshconnection.SSHConnection()
if RAN.eNBIPAddress == '' or RAN.eNBUserName == '' or RAN.eNBPassword == '' or self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '':
HELP.GenericHelp(CONST.Version)
@@ -2657,7 +2657,7 @@ class OaiCiTest():
pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE,RAN,EPC)
if (pStatus < 0):
HTML.CreateHtmlTestRow(self.iperf_args, 'KO', pStatus)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS)
return
server_on_enb = re.search('-R', str(self.iperf_args))
if server_on_enb is not None:
@@ -2756,12 +2756,12 @@ class OaiCiTest():
HTML.CreateHtmlTestRowQueue(self.iperf_args, 'OK', len(self.UEDevices), html_queue)
else:
HTML.CreateHtmlTestRowQueue(self.iperf_args, 'KO', len(self.UEDevices), html_queue)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS)
def Iperf(self,HTML,RAN,EPC,COTS_UE, InfraUE):
def Iperf(self,HTML,RAN,EPC,COTS_UE, InfraUE,CONTAINERS):
result = re.search('noS1', str(RAN.Initialize_eNB_args))
if result is not None:
self.IperfNoS1(HTML,RAN,EPC,COTS_UE,InfraUE)
self.IperfNoS1(HTML,RAN,EPC,COTS_UE,InfraUE,CONTAINERS)
return
if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.SourceCodePath == '' or self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '':
HELP.GenericHelp(CONST.Version)
@@ -2774,14 +2774,14 @@ class OaiCiTest():
pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE,RAN,EPC)
if (pStatus < 0):
HTML.CreateHtmlTestRow(self.iperf_args, 'KO', pStatus)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS)
return
if self.ue_id=="":#is not a module, follow legacy code
ueIpStatus = self.GetAllUEIPAddresses()
if (ueIpStatus < 0):
HTML.CreateHtmlTestRow(self.iperf_args, 'KO', CONST.UE_IP_ADDRESS_ISSUE)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS)
return
else: #is a module
self.UEIPAddresses=[]
@@ -2826,7 +2826,7 @@ class OaiCiTest():
if (status_queue.empty()):
HTML.CreateHtmlTestRow(self.iperf_args, 'KO', CONST.ALL_PROCESSES_OK)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS)
else:
iperf_status = True
iperf_noperf = False
@@ -2848,7 +2848,7 @@ class OaiCiTest():
HTML.CreateHtmlTestRowQueue(self.iperf_args, 'OK', len(self.UEDevices), html_queue)
else:
HTML.CreateHtmlTestRowQueue(self.iperf_args, 'KO', len(self.UEDevices), html_queue)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS)
def CheckProcessExist(self, check_eNB, check_OAI_UE,RAN,EPC):
multi_jobs = []
@@ -3280,7 +3280,7 @@ class OaiCiTest():
else:
HTML.CreateHtmlTestRow('QLog trace is disabled', 'OK', CONST.ALL_PROCESSES_OK)
def TerminateOAIUE(self,HTML,RAN,COTS_UE,EPC, InfraUE):
def TerminateOAIUE(self,HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS):
SSH = sshconnection.SSHConnection()
SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword)
SSH.command('cd ' + self.UESourceCodePath + '/cmake_targets', '\$', 5)
@@ -3321,11 +3321,11 @@ class OaiCiTest():
# Not an error then
if (logStatus != CONST.OAI_UE_PROCESS_COULD_NOT_SYNC) or (ueAction != 'Sniffing'):
self.Initialize_OAI_UE_args = ''
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS)
else:
if (logStatus == CONST.OAI_UE_PROCESS_COULD_NOT_SYNC):
self.Initialize_OAI_UE_args = ''
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS)
else:
logging.debug('\u001B[1m' + ueAction + ' Completed \u001B[0m')
HTML.htmlUEFailureMsg='<b>' + ueAction + ' Completed</b>\n' + HTML.htmlUEFailureMsg
@@ -3334,26 +3334,26 @@ class OaiCiTest():
else:
HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
def AutoTerminateUEandeNB(self,HTML,RAN,COTS_UE,EPC,InfraUE):
def AutoTerminateUEandeNB(self,HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS):
if (self.ADBIPAddress != 'none'):
self.testCase_id = 'AUTO-KILL-UE'
HTML.testCase_id=self.testCase_id
HTML.testCase_id = self.testCase_id
self.desc = 'Automatic Termination of UE'
HTML.desc='Automatic Termination of UE'
HTML.desc = self.desc
self.ShowTestID()
self.TerminateUE(HTML,COTS_UE,InfraUE,self.ue_trace)
if (self.Initialize_OAI_UE_args != ''):
self.testCase_id = 'AUTO-KILL-OAI-UE'
HTML.testCase_id=self.testCase_id
HTML.testCase_id = self.testCase_id
self.desc = 'Automatic Termination of OAI-UE'
HTML.desc='Automatic Termination of OAI-UE'
HTML.desc = self.desc
self.ShowTestID()
self.TerminateOAIUE(HTML,RAN,COTS_UE,EPC,InfraUE)
if (RAN.Initialize_eNB_args != ''):
self.testCase_id = 'AUTO-KILL-RAN'
HTML.testCase_id=self.testCase_id
HTML.testCase_id = self.testCase_id
self.desc = 'Automatic Termination of all RAN nodes'
HTML.desc='Automatic Termination of RAN nodes'
HTML.desc = self.desc
self.ShowTestID()
#terminate all RAN nodes eNB/gNB/OCP
for instance in range(0, len(RAN.air_interface)):
@@ -3363,11 +3363,21 @@ class OaiCiTest():
RAN.TerminateeNB(HTML,EPC)
if RAN.flexranCtrlInstalled and RAN.flexranCtrlStarted:
self.testCase_id = 'AUTO-KILL-flexran-ctl'
HTML.testCase_id=self.testCase_id
HTML.testCase_id = self.testCase_id
self.desc = 'Automatic Termination of FlexRan CTL'
HTML.desc='Automatic Termination of FlexRan CTL'
HTML.desc = self.desc
self.ShowTestID()
self.TerminateFlexranCtrl(HTML,RAN,EPC)
if CONTAINERS.yamlPath[0] != '':
self.testCase_id = 'AUTO-KILL-CONTAINERS'
HTML.testCase_id = self.testCase_id
self.desc = 'Automatic Termination of all RAN containers'
HTML.desc = self.desc
self.ShowTestID()
for instance in range(0, len(CONTAINERS.yamlPath)):
if CONTAINERS.yamlPath[instance]!='':
CONTAINERS.eNB_instance=instance
CONTAINERS.UndeployObject(HTML,RAN)
RAN.prematureExit=True
def IdleSleep(self,HTML):
+20 -1
View File
@@ -37,6 +37,7 @@ import html
import os
import re
import time
import subprocess
import sys
import constants as CONST
import helpreadme as HELP
@@ -115,7 +116,7 @@ class PhySim:
else:
imageTag = "develop"
# Check if image is exist on the Red Hat server, before pushing it to OC cluster
mySSH.command("sudo podman image inspect --format='Size = {{.Size}} bytes' oai-physim:" + imageTag, '\$', 60)
mySSH.command('sudo podman image inspect --format="Size = {{.Size}} bytes" oai-physim:' + imageTag, '\$', 60)
if mySSH.getBefore().count('no such image') != 0:
logging.error('\u001B[1m No such image oai-physim\u001B[0m')
mySSH.close()
@@ -264,6 +265,23 @@ class PhySim:
for podName in podNames:
mySSH.command(f'oc logs {podName} >> cmake_targets/log/physim_test.txt 2>&1', '\$', 15, resync=True)
time.sleep(30)
mySSH.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/log/physim_test.txt', '.')
try:
listLogFiles = subprocess.check_output('egrep --colour=never "Execution Log file|Linux oai-" physim_test.txt', shell=True, universal_newlines=True)
for line in listLogFiles.split('\n'):
res1 = re.search('Linux (?P<pod>oai-[a-zA-Z0-9\-]+) ', str(line))
res2 = re.search('Execution Log file = (?P<name>[a-zA-Z0-9\-\/\.\_]+)', str(line))
if res1 is not None:
podName = res1.group('pod')
if res2 is not None:
logFileInPod = res2.group('name')
folderName = re.sub('/opt/oai-physim/cmake_targets/autotests/log/', '', logFileInPod)
folderName = re.sub('/test.*', '', folderName)
fileName = re.sub('/opt/oai-physim/cmake_targets/autotests/log/' + folderName + '/', '', logFileInPod)
mySSH.command('mkdir -p cmake_targets/log/' + folderName, '\$', 5, silent=True)
mySSH.command('oc cp ' + podName + ':' + logFileInPod + ' cmake_targets/log/' + folderName + '/' + fileName, '\$', 20, silent=True)
except Exception as e:
pass
# UnDeploy the physical simulator pods
mySSH.command('helm uninstall physim | tee -a cmake_targets/log/physim_helm_summary.txt 2>&1', '\$', 6)
@@ -305,6 +323,7 @@ class PhySim:
mySSH.command('cd ' + lSourcePath + '/cmake_targets', '\$', 5)
mySSH.command('mkdir -p physim_test_log_' + self.testCase_id, '\$', 5)
mySSH.command('cp log/physim_* ' + 'physim_test_log_' + self.testCase_id, '\$', 5)
mySSH.command('tar cvf physim_test_log_' + self.testCase_id + '/physim_log.tar log/015*', '\$', 180)
if not os.path.exists(f'./physim_test_logs_{self.testCase_id}'):
os.mkdir(f'./physim_test_logs_{self.testCase_id}')
mySSH.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/physim_test_log_' + self.testCase_id + '/*', './physim_test_logs_' + self.testCase_id)
@@ -245,7 +245,7 @@ THREAD_STRUCT =
(
{
#three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
parallel_config = "PARALLEL_RU_L1_TRX_SPLIT";
parallel_config = "PARALLEL_SINGLE_THREAD";
#two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
worker_config = "WORKER_ENABLE";
}
@@ -226,6 +226,7 @@ MACRLCs = (
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
ulsch_max_frame_inactivity = 1;
}
);
@@ -226,6 +226,7 @@ MACRLCs = (
tr_n_preference = "local_RRC";
pusch_TargetSNRx10 = 200;
pucch_TargetSNRx10 = 200;
ulsch_max_frame_inactivity = 1;
}
);
+14
View File
@@ -108,6 +108,14 @@ class EPCManagement():
logging.debug('Using the ltebox simulated HSS')
mySSH.command('if [ -d ' + self.SourceCodePath + '/scripts ]; then echo ' + self.Password + ' | sudo -S rm -Rf ' + self.SourceCodePath + '/scripts ; fi', '\$', 5)
mySSH.command('mkdir -p ' + self.SourceCodePath + '/scripts', '\$', 5)
result = re.search('hss_sim s6as diam_hss', mySSH.getBefore())
if result is not None:
mySSH.command('echo ' + self.Password + ' | sudo -S killall hss_sim', '\$', 5)
mySSH.command('ps aux | grep --colour=never xGw | grep -v grep', '\$', 5, silent=True)
result = re.search('root.*xGw', mySSH.getBefore())
if result is not None:
mySSH.command('cd /opt/ltebox/tools', '\$', 5)
mySSH.command('echo ' + self.Password + ' | sudo -S ./stop_ltebox', '\$', 5)
mySSH.command('cd /opt/hss_sim0609', '\$', 5)
mySSH.command('echo ' + self.Password + ' | sudo -S rm -f hss.log', '\$', 5)
mySSH.command('echo ' + self.Password + ' | sudo -S echo "Starting sudo session" && sudo su -c "screen -dm -S simulated_hss ./starthss"', '\$', 5)
@@ -420,6 +428,11 @@ class EPCManagement():
mySSH.command('cd scripts', '\$', 5)
time.sleep(1)
mySSH.command('echo ' + self.Password + ' | sudo -S screen -S simulated_hss -X quit', '\$', 5)
time.sleep(5)
mySSH.command('ps aux | grep --colour=never hss_sim | grep -v grep', '\$', 5, silent=True)
result = re.search('hss_sim s6as diam_hss', mySSH.getBefore())
if result is not None:
mySSH.command('echo ' + self.Password + ' | sudo -S killall hss_sim', '\$', 5)
else:
logging.error('This should not happen!')
mySSH.close()
@@ -446,6 +459,7 @@ class EPCManagement():
elif re.match('ltebox', self.Type, re.IGNORECASE):
mySSH.command('cd /opt/ltebox/tools', '\$', 5)
mySSH.command('echo ' + self.Password + ' | sudo -S ./stop_mme', '\$', 5)
time.sleep(5)
else:
logging.error('This should not happen!')
mySSH.close()
+11 -11
View File
@@ -544,7 +544,7 @@ elif re.match('^TerminateOAIUE$', mode, re.IGNORECASE):
HELP.GenericHelp(CONST.Version)
sys.exit('Insufficient Parameter')
signal.signal(signal.SIGUSR1, receive_signal)
CiTestObj.TerminateOAIUE(HTML,RAN,COTS_UE,EPC,InfraUE)
CiTestObj.TerminateOAIUE(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS)
elif re.match('^TerminateHSS$', mode, re.IGNORECASE):
if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.Type == '' or EPC.SourceCodePath == '':
HELP.GenericHelp(CONST.Version)
@@ -809,39 +809,39 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re
elif action == 'Terminate_eNB':
RAN.TerminateeNB(HTML, EPC)
elif action == 'Initialize_UE':
CiTestObj.InitializeUE(HTML,RAN, EPC, COTS_UE, InfraUE, CiTestObj.ue_trace)
CiTestObj.InitializeUE(HTML,RAN, EPC, COTS_UE, InfraUE, CiTestObj.ue_trace, CONTAINERS)
elif action == 'Terminate_UE':
CiTestObj.TerminateUE(HTML,COTS_UE, InfraUE, CiTestObj.ue_trace)
elif action == 'Attach_UE':
CiTestObj.AttachUE(HTML,RAN,EPC,COTS_UE,InfraUE)
CiTestObj.AttachUE(HTML,RAN,EPC,COTS_UE,InfraUE,CONTAINERS)
elif action == 'Detach_UE':
CiTestObj.DetachUE(HTML,RAN,EPC,COTS_UE,InfraUE)
CiTestObj.DetachUE(HTML,RAN,EPC,COTS_UE,InfraUE,CONTAINERS)
elif action == 'DataDisable_UE':
CiTestObj.DataDisableUE(HTML)
elif action == 'DataEnable_UE':
CiTestObj.DataEnableUE(HTML)
elif action == 'CheckStatusUE':
CiTestObj.CheckStatusUE(HTML,RAN,EPC,COTS_UE,InfraUE)
CiTestObj.CheckStatusUE(HTML,RAN,EPC,COTS_UE,InfraUE,CONTAINERS)
elif action == 'Build_OAI_UE':
CiTestObj.BuildOAIUE(HTML)
elif action == 'Initialize_OAI_UE':
CiTestObj.InitializeOAIUE(HTML,RAN,EPC,COTS_UE,InfraUE)
CiTestObj.InitializeOAIUE(HTML,RAN,EPC,COTS_UE,InfraUE,CONTAINERS)
elif action == 'Terminate_OAI_UE':
CiTestObj.TerminateOAIUE(HTML,RAN,COTS_UE,EPC,InfraUE)
CiTestObj.TerminateOAIUE(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS)
elif action == 'Initialize_CatM_module':
CiTestObj.InitializeCatM(HTML)
elif action == 'Terminate_CatM_module':
CiTestObj.TerminateCatM(HTML)
elif action == 'Attach_CatM_module':
CiTestObj.AttachCatM(HTML,RAN,COTS_UE,EPC,InfraUE)
CiTestObj.AttachCatM(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS)
elif action == 'Detach_CatM_module':
CiTestObj.TerminateCatM(HTML)
elif action == 'Ping_CatM_module':
CiTestObj.PingCatM(HTML,RAN,EPC,COTS_UE,EPC,InfraUE)
CiTestObj.PingCatM(HTML,RAN,EPC,COTS_UE,EPC,InfraUE,CONTAINERS)
elif action == 'Ping':
CiTestObj.Ping(HTML,RAN,EPC,COTS_UE, InfraUE)
CiTestObj.Ping(HTML,RAN,EPC,COTS_UE, InfraUE, CONTAINERS)
elif action == 'Iperf':
CiTestObj.Iperf(HTML,RAN,EPC,COTS_UE, InfraUE)
CiTestObj.Iperf(HTML,RAN,EPC,COTS_UE, InfraUE, CONTAINERS)
elif action == 'Reboot_UE':
CiTestObj.RebootUE(HTML,RAN,EPC)
elif action == 'Initialize_HSS':
@@ -0,0 +1,12 @@
version: '2'
services:
mysql:
container_name: oaicicd_mysql
restart: always
image: mysql:latest
environment:
MYSQL_ROOT_PASSWORD: 'ucZBc2XRYdvEm59F'
ports:
- "3307:3306"
volumes:
- /home/oaicicd/mysql/data:/var/lib/mysql
@@ -0,0 +1,33 @@
import pymysql
import sys
from datetime import datetime
#This is the script used to write the test results to the mysql DB
#Called by Jenkins pipeline (jenkinsfile)
#Must be located in /home/oaicicid/mysql on the database host
#Usage from Jenkinsfile :
#python3 /home/oaicicd/mysql/sql_connect.py ${JOB_NAME} ${params.eNB_MR} ${params.eNB_Branch} ${env.BUILD_ID} ${env.BUILD_URL} ${StatusForDb} ''
class SQLConnect:
def __init__(self):
self.connection = pymysql.connect(
host='172.22.0.2',
user='root',
password = 'ucZBc2XRYdvEm59F',
db='oaicicd_tests',
port=3306
)
def put(self,TEST,MR,BRANCH,BUILD,BUILD_LINK,STATUS):
now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
cur=self.connection.cursor()
cur.execute ('INSERT INTO test_results (TEST,MR,BRANCH,BUILD,BUILD_LINK,STATUS,DATE) VALUES (%s,%s,%s,%s,%s,%s,%s);' , (TEST, MR, BRANCH, BUILD, BUILD_LINK, STATUS, now))
self.connection.commit()
self.connection.close()
if __name__ == "__main__":
mydb=SQLConnect()
mydb.put(sys.argv[1],sys.argv[2],sys.argv[3],sys.argv[4],sys.argv[5],sys.argv[6])
+19 -7
View File
@@ -374,7 +374,7 @@ class RANManagement():
logging.debug('\u001B[1m Launching tshark on interface ' + eth_interface + '\u001B[0m')
pcapfile = pcapfile_prefix + self.testCase_id + '_log.pcap'
mySSH.command('echo ' + lPassWord + ' | sudo -S rm -f /tmp/' + pcapfile , '\$', 5)
mySSH.command('echo $USER; nohup sudo -E tshark -i ' + eth_interface + ' -w /tmp/' + pcapfile + ' 2>&1 &','\$', 5)
mySSH.command('echo $USER; nohup sudo -E tshark -i ' + eth_interface + ' -w /tmp/' + pcapfile + ' > /dev/null 2>&1 &','\$', 5)
mySSH.close()
@@ -738,8 +738,8 @@ class RANManagement():
mySSH.command('echo ' + self.eNBPassword + ' | sudo -S mv /tmp/enb_*.pcap .','\$',20)
mySSH.command('echo ' + self.eNBPassword + ' | sudo -S mv /tmp/gnb_*.pcap .','\$',20)
mySSH.command('echo ' + self.eNBPassword + ' | sudo -S rm -f enb.log.zip', '\$', 5)
mySSH.command('echo ' + self.eNBPassword + ' | sudo -S zip enb.log.zip enb*.log core* enb_*record.raw enb_*.pcap gnb_*.pcap enb_*txt physim_*.log *stats.log *monitor.pickle *monitor*.png', '\$', 60)
mySSH.command('echo ' + self.eNBPassword + ' | sudo -S rm enb*.log core* enb_*record.raw enb_*.pcap gnb_*.pcap enb_*txt physim_*.log *stats.log *monitor.pickle *monitor*.png', '\$', 5)
mySSH.command('echo ' + self.eNBPassword + ' | sudo -S zip enb.log.zip enb*.log core* enb_*record.raw enb_*.pcap gnb_*.pcap enb_*txt physim_*.log *stats.log *monitor.pickle *monitor*.png log/*/*.log log/*/*.pcap', '\$', 60)
mySSH.command('echo ' + self.eNBPassword + ' | sudo -S rm enb*.log core* enb_*record.raw enb_*.pcap gnb_*.pcap enb_*txt physim_*.log *stats.log *monitor.pickle *monitor*.png log/*/*.log log/*/*.pcap', '\$', 15)
mySSH.close()
def AnalyzeLogFile_eNB(self, eNBlogFile, HTML):
@@ -800,10 +800,21 @@ class RANManagement():
x2ap_pdu = 0
#NSA specific log markers
nsa_markers ={'SgNBReleaseRequestAcknowledge': [],'FAILURE': [], 'scgFailureInformationNR-r15': [], 'SgNBReleaseRequest': []}
nodeB_prefix_found = False
line_cnt=0 #log file line counter
for line in enb_log_file.readlines():
line_cnt+=1
# Detection of eNB/gNB from a container log
result = re.search('Starting eNB soft modem', str(line))
if result is not None:
nodeB_prefix_found = True
nodeB_prefix = 'e'
result = re.search('Starting gNB soft modem', str(line))
if result is not None:
nodeB_prefix_found = True
nodeB_prefix = 'g'
result = re.search('Run time:' ,str(line))
# Runtime statistics
result = re.search('Run time:' ,str(line))
if result is not None:
@@ -1037,10 +1048,11 @@ class RANManagement():
logging.debug(' File analysis (stdout, stats) completed')
#post processing depending on the node type
if (self.air_interface[self.eNB_instance] == 'lte-softmodem') or (self.air_interface[self.eNB_instance] == 'ocp-enb'):
nodeB_prefix = 'e'
else:
nodeB_prefix = 'g'
if not nodeB_prefix_found:
if (self.air_interface[self.eNB_instance] == 'lte-softmodem') or (self.air_interface[self.eNB_instance] == 'ocp-enb'):
nodeB_prefix = 'e'
else:
nodeB_prefix = 'g'
if nodeB_prefix == 'g':
if ulschReceiveOK > 0:
+401
View File
@@ -0,0 +1,401 @@
#/*
# * 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
# */
#---------------------------------------------------------------------
# Merge Requests Dashboard for RAN on googleSheet
#
# Required Python Version
# Python 3.x
#
#---------------------------------------------------------------------
#-----------------------------------------------------------
# Import
#-----------------------------------------------------------
#Author Remi
import boto3
import shlex
import subprocess
import json #json structures
import datetime #now() and date formating
from datetime import datetime
import re
import gitlab
import yaml
import os
import time
from sqlconnect import SQLConnect
#-----------------------------------------------------------
# Class Declaration
#-----------------------------------------------------------
class Dashboard:
def __init__(self):
#init with data sources : git, yaml config file, test results databases
print("Collecting Data")
cmd="""curl --silent "https://gitlab.eurecom.fr/api/v4/projects/oai%2Fopenairinterface5g/merge_requests?state=opened&per_page=100" """
self.git = self.__getGitData(cmd) #git data from Gitlab
self.tests = self.__loadCfg('ran_dashboard_cfg.yaml') #tests table setup from yaml
self.db = self.__loadFromDB() #test results from database
def __loadCfg(self,yaml_file):
with open(yaml_file,'r') as f:
tests = yaml.load(f)
return tests
def __getGitData(self,cmd):
#cmd="""curl --silent "https://gitlab.eurecom.fr/api/v4/projects/oai%2Fopenairinterface5g/merge_requests?state=opened&per_page=100" """
process = subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE)
output = process.stdout.readline()
tmp=output.decode("utf-8")
d = json.loads(tmp)
return d
def __loadFromDB(self):
mr_list=[]
for x in range(len(self.git)):
mr_list.append(str(self.git[x]['iid']))
mydb=SQLConnect()
for MR in mr_list:
mydb.get(MR)
mydb.close_connection()
return mydb.data
def Test_initHTML(self, date):
self.f_html.write('<!DOCTYPE html>\n')
self.f_html.write('<head>\n')
self.f_html.write('<link rel="stylesheet" href="test_styles.css">\n')
self.f_html.write('<title>Test Dashboard</title>\n')
self.f_html.write('</head>\n')
self.f_html.write('<br>\n')
self.f_html.write('<br>\n')
self.f_html.write('<table>\n')
self.f_html.write('<tr>\n')
self.f_html.write('<td class="Main">OAI RAN TEST Status Dashboard</td>\n')
self.f_html.write('</td>\n')
self.f_html.write('<tr>\n')
self.f_html.write('<td class="DashLink"> <a href="https://oairandashboard.s3.eu-west-1.amazonaws.com/index.html">Merge Requests Dashboard</a></td>\n')
self.f_html.write('</td>\n')
self.f_html.write('<tr></tr>\n')
self.f_html.write('<tr>\n')
self.f_html.write('<td class="Date">Update : '+date+'</td>\n')
self.f_html.write('</td>\n')
self.f_html.write('</tr>\n')
self.f_html.write('</table>\n')
self.f_html.write('<br>\n')
self.f_html.write('<br>\n')
def Test_terminateHTML(self):
self.f_html.write('</body>\n')
self.f_html.write('</html>\n')
self.f_html.close()
def MR_initHTML(self,date):
self.f_html.write('<!DOCTYPE html>\n')
self.f_html.write('<head>\n')
self.f_html.write('<link rel="stylesheet" href="mr_styles.css">\n')
self.f_html.write('<title>MR Dashboard</title>\n')
self.f_html.write('</head>\n')
self.f_html.write('<br>\n')
self.f_html.write('<br>\n')
self.f_html.write('<table>\n')
self.f_html.write('<tr>\n')
self.f_html.write('<td class="Main">OAI RAN MR Status Dashboard</td>\n')
self.f_html.write('</td>\n')
self.f_html.write('<tr>\n')
self.f_html.write('<td class="DashLink"> <a href="https://oaitestdashboard.s3.eu-west-1.amazonaws.com/index.html">Tests Dashboard</a></td>\n')
self.f_html.write('</td>\n')
self.f_html.write('<tr></tr>\n')
self.f_html.write('<tr>\n')
self.f_html.write('<td class="Date">Update : '+date+'</td>\n')
self.f_html.write('</td>\n')
self.f_html.write('</tr>\n')
self.f_html.write('</table>\n')
self.f_html.write('<br>\n')
self.f_html.write('<br>\n')
self.f_html.write('<table class="MR_Table">\n')
self.f_html.write('<tr>\n')
self.f_html.write('<th class="MR">MR</th>\n')
self.f_html.write('<th class="CREATED_AT">Created_At</th>\n')
self.f_html.write('<th class="AUTHOR">Author</th>\n')
self.f_html.write('<th class="TITLE">Title</th>\n')
self.f_html.write('<th class="ASSIGNEE">Assignee</th>\n')
self.f_html.write('<th class="REVIEWER">Reviewer</th>\n')
self.f_html.write('<th class="CAN_START">CAN START</th>\n')
self.f_html.write('<th class="IN_PROGRESS">IN PROGRESS</th>\n')
self.f_html.write('<th class="COMPLETED">COMPLETED</th>\n')
self.f_html.write('<th class="REVIEW_FORM">Review Form</th>\n')
self.f_html.write('<th class="OK_MERGE">OK Merge</th>\n')
self.f_html.write('<th class="MERGE_CONFLICTS">Merge Conflicts</th>\n')
self.f_html.write('</tr>\n')
def MR_terminateHTML(self):
self.f_html.write('</table> \n')
self.f_html.write('</body>\n')
self.f_html.write('</html>\n')
self.f_html.close()
def MR_rowHTML(self,row):
self.f_html.write('<tr>\n')
self.f_html.write('<td><a href=\"'+row[0]+'\">'+row[1]+'</a></td>\n')
self.f_html.write('<td>'+row[2]+'</td>\n')
self.f_html.write('<td>'+row[3]+'</td>\n')
self.f_html.write('<td class="title_cell">'+row[4]+'</td>\n')
self.f_html.write('<td>'+row[5]+'</td>\n')
self.f_html.write('<td>'+row[6]+'</td>\n')
if row[7]=='X':
self.f_html.write('<td style="background-color: orange;">'+row[7]+'</td>\n')
else:
self.f_html.write('<td></td>\n')
if row[8]=='X':
self.f_html.write('<td style="background-color: yellow;">'+row[8]+'</td>\n')
else:
self.f_html.write('<td></td>\n')
if row[9]=='X':
self.f_html.write('<td style="background-color: rgb(144, 221, 231);">'+row[9]+'</td>\n')
else:
self.f_html.write('<td></td>\n')
if row[10]=='X':
self.f_html.write('<td style="background-color: rgb(58, 236, 58);">'+row[10]+'</td>\n')
else:
self.f_html.write('<td></td>\n')
if row[11]=='X':
self.f_html.write('<td style="background-color: rgb(58, 236, 58);">'+row[11]+'</td>\n')
else:
self.f_html.write('<td></td>\n')
if row[12]=='YES':
self.f_html.write('<td style="background-color: red;">'+row[12]+'</td>\n')
else:
self.f_html.write('<td></td>\n')
self.f_html.write('</tr>\n')
def Build(self, type, htmlfilename):
if type=='MR':
self.Build_MR_Table(htmlfilename)
elif type=='Tests':
self.Build_Test_Table(htmlfilename)
else :
print("Undefined Dashboard Type, options : MR or Tests")
def Build_Test_Table(self,htmlfilename):
print("Building Tests Dashboard...")
self.f_html=open(htmlfilename,'w')
###update date/time, format dd/mm/YY H:M:S
now = datetime.now()
dt_string = now.strftime("%d/%m/%Y %H:%M")
#HTML table header
self.Test_initHTML(dt_string)
#1 table per MR if test results exist
for x in range(len(self.git)):
mr=str(self.git[x]['iid'])
if 'PASS' not in self.db[mr]:
self.f_html.write('<h3><a href="https://gitlab.eurecom.fr/oai/openairinterface5g/-/merge_requests/'+mr+'">'+mr+'</a>'+' '+self.git[x]['title'] + '</h3>\n')
self.f_html.write('<table class="Test_Table">\n')
self.f_html.write('<tr>\n')
self.f_html.write('<th class="Test_Name">Test Name</th>\n')
self.f_html.write('<th class="Test_Descr">Bench</th> \n')
self.f_html.write('<th class="Test_Descr">Test</th> \n')
self.f_html.write('<th class="Pass"># Pass</th>\n')
self.f_html.write('<th class="Fail"># Fail</th>\n')
self.f_html.write('<th class="Last_Pass">Last Pass</th>\n')
self.f_html.write('<th class="Last_Fail">Last Fail</th>\n')
self.f_html.write('</tr>\n')
#parsing the tests
for t in self.tests:
row=[]
short_name= t
hyperlink= self.tests[t]['link']
job=self.tests[t]['job']
if job in self.db[mr]:
if 'PASS' in self.db[mr][job]:
row.append(self.db[mr][job]['PASS'])
else:
row.append('')
if 'FAIL' in self.db[mr][job]:
row.append(self.db[mr][job]['FAIL'])
else:
row.append('')
#2 columns for last_pass and last_fail links
if 'last_pass' in self.db[mr][job]:
lastpasshyperlink= self.db[mr][job]['last_pass'][1]
lastpasstext= self.db[mr][job]['last_pass'][0]
else:
lastpasshyperlink=''
lastpasstext=''
if 'last_fail' in self.db[mr][job]:
lastfailhyperlink= self.db[mr][job]['last_fail'][1]
lastfailtext= self.db[mr][job]['last_fail'][0]
else:
lastfailhyperlink=''
lastfailtext=''
self.f_html.write('<tr>\n')
self.f_html.write('<td><a href='+hyperlink+'>'+short_name+'</a></td>\n')
self.f_html.write('<td>'+self.tests[t]['bench']+'</td>\n')
self.f_html.write('<td>'+self.tests[t]['test']+'</td>\n')
if row[0]!='':
self.f_html.write('<td style="background-color: rgb(58, 236, 58);">'+str(row[0])+'</td>\n')
else:
self.f_html.write('<td></td>\n')
if row[1]!='':
self.f_html.write('<td style="background-color: red;">'+str(row[1])+'</td>\n')
else:
self.f_html.write('<td></td>\n')
self.f_html.write('<td><a href='+lastpasshyperlink+'>'+lastpasstext+'</a></td>\n')
self.f_html.write('<td><a href='+lastfailhyperlink+'>'+lastfailtext+'</a></td>\n')
self.f_html.write('</tr>\n')
self.f_html.write('</table>\n')
#terminate HTML table and close file
self.Test_terminateHTML()
def Build_MR_Table(self,htmlfilename):
print("Building Merge Requests Dashboard...")
self.f_html=open(htmlfilename,'w')
###update date/time, format dd/mm/YY H:M:S
now = datetime.now()
dt_string = now.strftime("%d/%m/%Y %H:%M")
#HTML table header
self.MR_initHTML(dt_string)
###MR data lines
for x in range(len(self.git)):
hyperlink= 'https://gitlab.eurecom.fr/oai/openairinterface5g/-/merge_requests/'+ str(self.git[x]['iid'])
text= str(self.git[x]['iid'])
date_time_str = self.git[x]['created_at']
date_time_obj = datetime.strptime(date_time_str, '%Y-%m-%dT%H:%M:%S.%fZ')
milestone1=milestone2=milestone3=milestone4=""
if self.git[x]['milestone']!=None:
if self.git[x]['milestone']['title']=="REVIEW_CAN_START":
milestone1="X"
elif self.git[x]['milestone']['title']=="REVIEW_IN_PROGRESS":
milestone2="X"
elif self.git[x]['milestone']['title']=="REVIEW_COMPLETED_AND_APPROVED":
milestone3="X"
elif self.git[x]['milestone']['title']=="OK_TO_BE_MERGED":
milestone4="X"
else:
pass
else:
pass
#check if empty or not
if self.git[x]['assignee']!=None:
assignee = str(self.git[x]['assignee']['name'])
else:
assignee = ""
#check if empty or not
if len(self.git[x]['reviewers'])!=0:
reviewer = str(self.git[x]['reviewers'][0]['name'])
else:
reviewer = ""
if self.git[x]['has_conflicts']==True:
conflicts = "YES"
else:
conflicts = ""
#add a column flagging that the review form is present
#we use gitlab API to parse the MR notes
gl = gitlab.Gitlab.from_config('OAI')
project_id = 223
project = gl.projects.get(project_id)
#get the opened MR in the project
mrs = project.mergerequests.list(state='opened',per_page=100)
review_form=''
for m in range (0,len(mrs)):
if mrs[m].iid==self.git[x]['iid']:#check the iid is the one we are on
mr_notes = mrs[m].notes.list(all=True)
n=0
found=False
while found==False and n<len(mr_notes):
res=re.search('Code Review by',mr_notes[n].body)#this is the marker we are looking for in all notes
if res!=None:
review_form = "X"
found=True
n+=1
#build final row to be inserted
row =[hyperlink, text, str(date_time_obj.date()),str(self.git[x]['author']['name']), str(self.git[x]['title']),\
assignee, reviewer,\
milestone1,milestone2,milestone3,review_form,milestone4,conflicts]
self.MR_rowHTML(row)
#terminate HTML table and close file
self.MR_terminateHTML()
def CopyToS3(self,htmlfilename,bucket,key):
print("Uploading to S3 bucket")
#Creating Session With Boto3.
s3 = boto3.client('s3')
#Creating S3 Resource From the Session.
result = s3.upload_file(htmlfilename, bucket,key, ExtraArgs={'ACL':'public-read','ContentType': 'text/html'})
def main():
htmlDash=Dashboard()
htmlDash.Build('MR','/tmp/MR_index.html')
htmlDash.CopyToS3('/tmp/MR_index.html','oairandashboard','index.html')
htmlDash.Build('Tests','/tmp/Tests_index.html')
htmlDash.CopyToS3('/tmp/Tests_index.html','oaitestdashboard','index.html')
if __name__ == "__main__":
# execute only if run as a script
main()
+136
View File
@@ -0,0 +1,136 @@
body {
font-family: 'lato', sans-serif;
}
.Main {
text-align:left;
font-size: 30px;
font-weight: bold;
}
.DashLink {
text-align:left;
font-size: 16px;
}
.DashLink:hover {
font-weight: bold;
}
.Date {
text-align:left;
font-size: 16px;
font-weight: bold;
}
a { text-decoration: none; }
a:visited { text-decoration: none; color:blue}
a:hover { text-decoration: none; font-weight: bold; color:blue}
.MR_Table {
border-collapse: collapse;
}
.MR_Table tr {
font-size: 12px;
text-align:center;
}
.MR_Table tr:hover {
background-color:lightgray;
}
.MR_Table td {
border: 1px solid black;
padding : 5px;
}
.MR_Table td:hover {
font-weight : bold;
}
.MR_Table th {
font-size: 14px;
text-align:center;
padding : 5px;
}
.title_cell {
text-align:left;
}
.MR {
table-layout: fixed;
width: 50px;
background-color: rgb(143, 154, 216);
}
.CREATED_AT {
table-layout: fixed;
width: 100px;
background-color: rgb(143, 154, 216);
}
.AUTHOR {
table-layout: fixed;
width: 150px;
background-color: rgb(143, 154, 216);
}
.TITLE {
table-layout: fixed;
width: 500px;
background-color: rgb(143, 154, 216);
}
.ASSIGNEE {
table-layout: fixed;
width: 150px;
background-color: rgb(143, 154, 216);
}
.REVIEWER {
table-layout: fixed;
width: 150px;
background-color: rgb(143, 154, 216);
}
.CAN_START {
background-color: orange;
table-layout: fixed;
width: 150px;
}
.IN_PROGRESS {
background-color: yellow;
table-layout: fixed;
width: 150px;
}
.COMPLETED {
background-color: rgb(144, 221, 231);
table-layout: fixed;
width: 150px;
}
.REVIEW_FORM {
table-layout: fixed;
width: 100px;
background-color: rgb(143, 154, 216);
}
.OK_MERGE {
background-color: rgb(58, 236, 58);
table-layout: fixed;
width: 150px;
}
.MERGE_CONFLICTS {
table-layout: fixed;
width: 100px;
background-color: rgb(143, 154, 216);
}
@@ -30,6 +30,8 @@
# Import
#-----------------------------------------------------------
#author Remi
#import google spreadsheet API
import gspread
from oauth2client.service_account import ServiceAccountCredentials
@@ -42,6 +44,13 @@ import datetime #now() and date formating
from datetime import datetime
import re
import gitlab
import yaml
import os
import pickle
import time
from sqlconnect import SQLConnect
#-----------------------------------------------------------
# Class Declaration
@@ -57,48 +66,78 @@ class gDashboard:
#worksheet
self.sheet = self.ss.worksheet(worksheet)
self.ss.del_worksheet(self.sheet) #start by deleting the old sheet
self.sheet = self.ss.add_worksheet(title=worksheet, rows="100", cols="20") #create a new one
self.d = {} #data dictionary
self.sheet = self.ss.add_worksheet(title=worksheet, rows="100", cols="30") #create a new one
#init with data sources : git, yaml config file, test results databases
cmd="""curl --silent "https://gitlab.eurecom.fr/api/v4/projects/oai%2Fopenairinterface5g/merge_requests?state=opened&per_page=100" """
self.git = self.__getGitData(cmd) #git data from Gitlab
self.tests = self.__loadCfg('ran_dashboard_cfg.yaml') #tests table setup from yaml
self.db = self.__loadFromDB() #test results from database
def fetchData(self,cmd):
def __loadCfg(self,yaml_file):
with open(yaml_file,'r') as f:
tests = yaml.load(f)
return tests
def __getGitData(self,cmd):
#cmd="""curl --silent "https://gitlab.eurecom.fr/api/v4/projects/oai%2Fopenairinterface5g/merge_requests?state=opened&per_page=100" """
process = subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE)
output = process.stdout.readline()
tmp=output.decode("utf-8")
self.d = json.loads(tmp)
d = json.loads(tmp)
return d
def __loadFromDB(self):
mr_list=[]
for x in range(len(self.git)):
mr_list.append(str(self.git[x]['iid']))
mydb=SQLConnect()
for MR in mr_list:
mydb.get(MR)
mydb.close_connection()
return mydb.data
def gBuild(self, destinationSheetName):
#line 1 : update date/time, format dd/mm/YY H:M:S
###line 1 : update date/time, format dd/mm/YY H:M:S
now = datetime.now()
dt_string = "Update : " + now.strftime("%d/%m/%Y %H:%M")
row =[dt_string]
self.sheet.insert_row(row, index=1, value_input_option='RAW')
#line 2 empty
#line 3 is for the column names
###line 2 is for the test short names (links to jenkins pipeline), updated at the end
###line 3 is for the column names
i=3
row =["MR","Created_at","Author","Title","Assignee", "Reviewer", "CAN START","IN PROGRESS","COMPLETED","Review Form","OK MERGE","Merge conflicts"]
row =["MR","Created_at","Author","Title","Assignee", "Reviewer", "CAN START","IN PROGRESS","COMPLETED","Review Form","OK MERGE","Merge conflicts",""]
#tests
for t in range(0,len(self.tests)):
row.append("# PASS")
row.append("# FAIL")
row.append("Last Pass")
row.append("Last Fail")
self.sheet.insert_row(row, index=i, value_input_option='RAW')
#line 4 onward, MR data lines
for x in range(len(self.d)):
###line 4 onward, MR data lines
for x in range(len(self.git)):
i=i+1
date_time_str = self.d[x]['created_at']
date_time_str = self.git[x]['created_at']
date_time_obj = datetime.strptime(date_time_str, '%Y-%m-%dT%H:%M:%S.%fZ')
milestone1=milestone2=milestone3=milestone4=""
if self.d[x]['milestone']!=None:
if self.d[x]['milestone']['title']=="REVIEW_CAN_START":
if self.git[x]['milestone']!=None:
if self.git[x]['milestone']['title']=="REVIEW_CAN_START":
milestone1="X"
elif self.d[x]['milestone']['title']=="REVIEW_IN_PROGRESS":
elif self.git[x]['milestone']['title']=="REVIEW_IN_PROGRESS":
milestone2="X"
elif self.d[x]['milestone']['title']=="REVIEW_COMPLETED_AND_APPROVED":
elif self.git[x]['milestone']['title']=="REVIEW_COMPLETED_AND_APPROVED":
milestone3="X"
elif self.d[x]['milestone']['title']=="OK_TO_BE_MERGED":
elif self.git[x]['milestone']['title']=="OK_TO_BE_MERGED":
milestone4="X"
else:
pass
@@ -106,18 +145,18 @@ class gDashboard:
pass
#check if empty or not
if self.d[x]['assignee']!=None:
assignee = str(self.d[x]['assignee']['name'])
if self.git[x]['assignee']!=None:
assignee = str(self.git[x]['assignee']['name'])
else:
assignee = ""
#check if empty or not
if len(self.d[x]['reviewers'])!=0:
reviewer = str(self.d[x]['reviewers'][0]['name'])
if len(self.git[x]['reviewers'])!=0:
reviewer = str(self.git[x]['reviewers'][0]['name'])
else:
reviewer = ""
if self.d[x]['has_conflicts']==True:
if self.git[x]['has_conflicts']==True:
conflicts = "YES"
else:
conflicts = ""
@@ -129,13 +168,13 @@ class gDashboard:
project_id = 223
project = gl.projects.get(project_id)
#get the opened MR in the project
mrs = project.mergerequests.list(state='opened')
mrs = project.mergerequests.list(state='opened',per_page=100)
review_form=''
for m in range (0,len(mrs)):
if mrs[m].iid==self.d[x]['iid']:#check the iid is the one we are on
if mrs[m].iid==self.git[x]['iid']:#check the iid is the one we are on
mr_notes = mrs[m].notes.list(all=True)
n=0
found=False
review_form=""
while found==False and n<len(mr_notes):
res=re.search('Code Review by',mr_notes[n].body)#this is the marker we are looking for in all notes
if res!=None:
@@ -143,29 +182,81 @@ class gDashboard:
found=True
n+=1
#build final row to be inserted, the first column is left empty for now, will be filled afterward with hyperlinks to gitlab MR
row =["", str(date_time_obj.date()),str(self.d[x]['author']['name']),str(self.d[x]['title']),\
row =["", str(date_time_obj.date()),str(self.git[x]['author']['name']), str(self.git[x]['title']),\
assignee, reviewer,\
milestone1,milestone2,milestone3,review_form,milestone4,conflicts]
#insert the row to worksheet
milestone1,milestone2,milestone3,review_form,milestone4,conflicts,""]
#and append the test results coming from self.db
mr=str(self.git[x]['iid'])
for t in self.tests:
if mr in self.db:
job=self.tests[t]['job']
if job in self.db[mr]:
if 'PASS' in self.db[mr][job]:
row.append(self.db[mr][job]['PASS'])
else:
row.append('')
if 'FAIL' in self.db[mr][job]:
row.append(self.db[mr][job]['FAIL'])
else:
row.append('')
#leave 2 columns for last_pass and last_fail links
row.append('')
row.append('')
else:
#4 columns are empty
row.append('')
row.append('')
row.append('')
row.append('')
#insert the final row to worksheet
self.sheet.insert_row(row, index=i, value_input_option='RAW')
time.sleep(10)
#add MR hyperlinks in a list of requests to be sent as one update batch; this to save API calls (quotas)
i=3
requests=[]
for x in range(len(self.d)):
for x in range(len(self.git)):
rowIndex=i
colIndex=0
hyperlink= '\"'+"https://gitlab.eurecom.fr/oai/openairinterface5g/-/merge_requests/"+ str(self.d[x]['iid']) +'\"'
text= '\"'+str(self.d[x]['iid'])+'"'
hyperlink= '\"'+"https://gitlab.eurecom.fr/oai/openairinterface5g/-/merge_requests/"+ str(self.git[x]['iid']) +'\"'
text= '\"'+str(self.git[x]['iid'])+'"'
requests.append(self.addHyperlink(hyperlink, text, destinationSheetName, rowIndex, colIndex))
i=i+1
mr=str(self.git[x]['iid'])
colIndex=15
for t in self.tests:
job=self.tests[t]['job']
if job in self.db[mr]:
if 'last_pass' in self.db[mr][job]:
hyperlink= '\"'+ self.db[mr][job]['last_pass'][1] +'\"'
text= '\"'+self.db[mr][job]['last_pass'][0]+'"'
requests.append(self.addHyperlink(hyperlink, text, destinationSheetName, rowIndex, colIndex))
if 'last_fail' in self.db[mr][job]:
hyperlink= '\"'+ self.db[mr][job]['last_fail'][1] +'\"'
text= '\"'+self.db[mr][job]['last_fail'][0]+'"'
requests.append(self.addHyperlink(hyperlink, text, destinationSheetName, rowIndex, colIndex+1))
colIndex+=4 #move to next test
i=i+1 #increment row index for next MR
body = {"requests": requests}
self.ss.batch_update(body)
###line 2 is for the test names
#add MR hyperlinks in a list of requests to be sent as one update batch; this to save API calls (quotas)
requests=[]
rowIndex=1
colIndex=13
for t in self.tests :
hyperlink= '\"'+self.tests[t]['link']+'\"'
short_name= '\"'+ t +'\"'
requests.append(self.addHyperlink(hyperlink, short_name, destinationSheetName, rowIndex, colIndex))
colIndex+=4
body = {"requests": requests}
self.ss.batch_update(body)
def addHyperlink(self, hyperlink, text, destinationSheetName, rowIndex, colIndex):
@@ -207,17 +298,17 @@ class gDashboard:
"copyPaste": {
"source": {
"sheetId": sourceSheetId,
"startRowIndex": 0,
"startRowIndex": 1,
"endRowIndex": 40,
"startColumnIndex": 0,
"endColumnIndex": 12
"endColumnIndex": 30
},
"destination": {
"sheetId": destinationSheetId,
"startRowIndex": 0,
"startRowIndex": 1,
"endRowIndex": 40,
"startColumnIndex": 0,
"endColumnIndex": 12
"endColumnIndex": 30
},
"pasteType": "PASTE_FORMAT"
}
@@ -280,15 +371,30 @@ class gDashboard:
}
)
body = {"requests": requests}
self.ss.batch_update(body)
#group MR related columns
# sheetId = self.ss.worksheet(destinationSheetName)._properties['sheetId']
# requests.append(
# {
# "addDimensionGroup": {
# "range": {
# "dimension": "COLUMNS",
# "sheetId": sheetId,
# "startIndex": 3,
# "endIndex": 12
# },
# }
# }
# )
#
body = {"requests": requests}
self.ss.batch_update(body)
def main():
my_gDashboard=gDashboard("/opt/dashboard/g_creds.json", 'OAI RAN Dashboard', 'MR Status')
cmd="""curl --silent "https://gitlab.eurecom.fr/api/v4/projects/oai%2Fopenairinterface5g/merge_requests?state=opened&per_page=100" """
my_gDashboard.fetchData(cmd)
my_gDashboard.gBuild("MR Status")
my_gDashboard.gFormat("Formating" , "MR Status")
@@ -0,0 +1,21 @@
LTE-2x2 : #short name used in the dashboard
job : 'RAN-LTE-2x2-Module-OAIEPC' #job name from Jenkins, used in the database
link : 'https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-LTE-2x2-Module-OAIEPC'
bench : 'Obelix-N310-OAIEPC-Quectel(nrmodule2)'
test : 'TDD, 40MHz, MCS9, 26Mb DL, 7Mb UL'
NSA-B200 :
job : 'RAN-NSA-B200-Module-LTEBOX'
link : 'https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-NSA-B200-Module-LTEBOX'
bench : 'Nepes-B200-Obelix-B200-LTEBOX-Quectel(idefix)'
test : '20MHz, 60Mb DL, 3Mb UL'
NSA-2x2 :
job : 'RAN-NSA-2x2-Module-OAIEPC'
link : 'https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-NSA-2x2-Module-OAIEPC'
bench : 'Asterix-N310-Obelix-N310-OAIEPC-Quectel(nrmodule2)'
test : 'TDD, 40MHz, 60Mb DL, 3Mb UL'
SA-N310 :
job : 'RAN-SA-Module-CN5G'
link : 'https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-SA-Module-CN5G'
bench : 'Asterix-N310-OAICN5G-Quectel(nrmodule2)'
test : 'TDD, 40MHz, 60Mb DL, 3Mb UL'
+3
View File
@@ -0,0 +1,3 @@
The code ran_dashboard.py was initially developped to bring MR status and test resuts to a google sheet, using google sheets API.
This method is now deprecated, and replaced by Hdashboard.py that builds the results as HTML page and loads it to AWS S3.
ran_dashboard_cfg.yaml is still used by Hdashboard.py as tests config file.
+107
View File
@@ -0,0 +1,107 @@
#/*
# * 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
# */
#---------------------------------------------------------------------
# Merge Requests Dashboard for RAN on googleSheet
#
# Required Python Version
# Python 3.x
#
#---------------------------------------------------------------------
#author Remi
import pymysql
import sys
from datetime import datetime
import pickle
#This is the script/package used by the dashboard to retrieve the MR test results from the database
class SQLConnect:
def __init__(self):
self.connection = pymysql.connect(
host='172.22.0.2',
user='root',
password = 'ucZBc2XRYdvEm59F',
db='oaicicd_tests',
port=3306
)
self.data={}
#retrieve data from mysql database and organize it in a dictionary (per MR passed as argument)
def get(self,MR):
self.data[MR]={}
cur=self.connection.cursor()
#get counters per test
sql = "select TEST,STATUS, count(*) AS COUNT from test_results where MR=(%s) group by TEST, STATUS;"
cur.execute(sql,MR)
response=cur.fetchall()
if len(response)==0:#no test results yet
self.data[MR]['PASS']=''
self.data[MR]['FAIL']=''
else:
for i in range(0,len(response)):
test=response[i][0]
status=response[i][1]
count=response[i][2]
if test in self.data[MR]:
self.data[MR][test][status]=count
else:
self.data[MR][test]={}
self.data[MR][test][status]=count
#get last failing build and link
sql = "select TEST,BUILD, BUILD_LINK from test_results where MR=(%s) and STATUS='FAIL' order by DATE DESC;"
cur.execute(sql,MR)
response=cur.fetchall()
if len(response)!=0:
for i in range(0,len(response)):
test=response[i][0]
build=response[i][1]
link=response[i][2]
if 'last_fail' not in self.data[MR][test]:
self.data[MR][test]['last_fail']=[]
self.data[MR][test]['last_fail'].append(build)
self.data[MR][test]['last_fail'].append(link)
#get last passing build and link
sql = "select TEST,BUILD, BUILD_LINK from test_results where MR=(%s) and STATUS='PASS' order by DATE DESC;"
cur.execute(sql,MR)
response=cur.fetchall()
if len(response)!=0:
for i in range(0,len(response)):
test=response[i][0]
build=response[i][1]
link=response[i][2]
if 'last_pass' not in self.data[MR][test]:
self.data[MR][test]['last_pass']=[]
self.data[MR][test]['last_pass'].append(build)
self.data[MR][test]['last_pass'].append(link)
#close database connection
def close_connection(self):
self.connection.close()
+103
View File
@@ -0,0 +1,103 @@
body {
font-family: 'lato', sans-serif;
}
.Main {
text-align: left;
font-size: 30px;
font-weight: bold;
}
.DashLink {
text-align:left;
font-size: 16px;
}
.DashLink:hover {
font-weight: bold;
}
.Date {
text-align: left;
font-size: 16px;
font-weight: bold;
}
h3 {
font-size: 16px;
}
a { text-decoration: none; }
a:visited { text-decoration: none; color:blue}
a:hover { text-decoration: none; font-weight: bold; color:blue}
.Test_Table {
border-collapse: collapse;
}
.Test_Table tr {
font-size: 12px;
text-align:center;
}
.Test_Table tr:hover {
background-color:lightgray;
}
.Test_Table td {
border: 1px solid black;
padding : 5px;
}
.Test_Table td:hover {
font-weight : bold;
}
.Test_Table th {
font-size: 14px;
text-align:center;
padding : 5px;
}
.Test_Name {
table-layout: fixed;
width: 100px;
background-color: rgb(143, 154, 216);
}
.Test_Descr {
table-layout: fixed;
width: 400px;
background-color: rgb(143, 154, 216);
}
.Pass {
table-layout: fixed;
width: 100px;
background-color: rgb(143, 154, 216);
}
.Fail {
table-layout: fixed;
width: 100px;
background-color: rgb(143, 154, 216);
}
.Last_Pass {
table-layout: fixed;
width: 100px;
background-color: rgb(143, 154, 216);
}
.Last_Fail {
table-layout: fixed;
width: 100px;
background-color: rgb(143, 154, 216);
}
@@ -24,6 +24,7 @@
<htmlTabRef>rfsim-4glte</htmlTabRef>
<htmlTabName>Testing 4G LTE RF sim in containers</htmlTabName>
<htmlTabIcon>wrench</htmlTabIcon>
<repeatCount>2</repeatCount>
<TestCaseRequestedList>
100011
000011
@@ -24,6 +24,7 @@
<htmlTabRef>rfsim-5gnr</htmlTabRef>
<htmlTabName>Testing 5G NR RF sim in containers</htmlTabName>
<htmlTabIcon>wrench</htmlTabIcon>
<repeatCount>4</repeatCount>
<TestCaseRequestedList>
100001
000001
@@ -115,8 +115,8 @@
<testCase id="070000">
<class>Iperf</class>
<desc>iperf (DL/20Mbps/UDP)(60 sec)(single-ue profile)</desc>
<iperf_args>-u -b 20M -t 60</iperf_args>
<desc>iperf (DL/40Mbps/UDP)(60 sec)(single-ue profile)</desc>
<iperf_args>-u -b 40M -t 60</iperf_args>
<direction>DL</direction>
<id>idefix</id>
<iperf_packetloss_threshold>3</iperf_packetloss_threshold>
@@ -0,0 +1,51 @@
<!--
Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The OpenAirInterface Software Alliance licenses this file to You under
the OAI Public License, Version 1.1 (the "License"); you may not use this file
except in compliance with the License.
You may obtain a copy of the License at
http://www.openairinterface.org/?page_id=698
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
For more information about the OpenAirInterface (OAI) Software Alliance:
contact@openairinterface.org
-->
<testCaseList>
<htmlTabRef>TEST-NSA-FR1-TM1-B200-terminate</htmlTabRef>
<htmlTabName>NSA tear-down in case of problem</htmlTabName>
<htmlTabIcon>tasks</htmlTabIcon>
<repeatCount>1</repeatCount>
<TestCaseRequestedList>
030202
030201
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="030201">
<class>Undeploy_Object</class>
<desc>Undeploy eNB</desc>
<yaml_path>ci-scripts/yaml_files/nsa_b200_enb</yaml_path>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="030202">
<class>Undeploy_Object</class>
<desc>Undeploy gNB</desc>
<yaml_path>ci-scripts/yaml_files/nsa_b200_gnb</yaml_path>
<eNB_instance>1</eNB_instance>
<eNB_serverId>1</eNB_serverId>
</testCase>
</testCaseList>
+1 -1
View File
@@ -73,7 +73,7 @@
<testCase id="040000">
<class>Initialize_eNB</class>
<desc>Initialize gNB</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf -E -q</Initialize_eNB_args>
<Initialize_eNB_args>-O ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf -E -q --usrp-args "serial=30C51D4"</Initialize_eNB_args>
<eNB_instance>1</eNB_instance>
<eNB_serverId>1</eNB_serverId>
<air_interface>nr</air_interface>
+1 -1
View File
@@ -21,7 +21,7 @@
-->
<testCaseList>
<htmlTabRef>TEST-SA-FR1-TM1</htmlTabRef>
<htmlTabRef>TEST-SA-FR1-Tab1</htmlTabRef>
<htmlTabName>SA Ping DL UL with QUECTEL</htmlTabName>
<htmlTabIcon>tasks</htmlTabIcon>
<repeatCount>1</repeatCount>
@@ -0,0 +1,156 @@
<!--
Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The OpenAirInterface Software Alliance licenses this file to You under
the OAI Public License, Version 1.1 (the "License"); you may not use this file
except in compliance with the License.
You may obtain a copy of the License at
http://www.openairinterface.org/?page_id=698
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
For more information about the OpenAirInterface (OAI) Software Alliance:
contact@openairinterface.org
-->
<testCaseList>
<htmlTabRef>TEST-SA-FR1-Tab2</htmlTabRef>
<htmlTabName>SA Staged DL with QUECTEL</htmlTabName>
<htmlTabIcon>tasks</htmlTabIcon>
<repeatCount>1</repeatCount>
<TestCaseRequestedList>
040000
000002
010000
000001
050000
000001
070000
000001
070001
000001
070002
000001
070003
000001
070004
000001
010002
080000
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="010000">
<class>Initialize_UE</class>
<desc>Initialize Quectel</desc>
<id>nrmodule2_quectel</id>
<UE_Trace>yes</UE_Trace>
</testCase>
<testCase id="010002">
<class>Terminate_UE</class>
<desc>Terminate Quectel</desc>
<id>nrmodule2_quectel</id>
</testCase>
<testCase id="040000">
<class>Initialize_eNB</class>
<desc>Initialize gNB</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.conf --sa -q --usrp-tx-thread-config 1 --thread-pool 0,2,4,6</Initialize_eNB_args>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
<air_interface>nr</air_interface>
<eNB_Trace>yes</eNB_Trace>
<eNB_Stats>yes</eNB_Stats>
<USRP_IPAddress>192.168.18.240</USRP_IPAddress>
</testCase>
<testCase id="000001">
<class>IdleSleep</class>
<desc>Sleep</desc>
<idle_sleep_time_in_sec>5</idle_sleep_time_in_sec>
</testCase>
<testCase id="000002">
<class>IdleSleep</class>
<desc>Sleep</desc>
<idle_sleep_time_in_sec>20</idle_sleep_time_in_sec>
</testCase>
<testCase id="050000">
<class>Ping</class>
<desc>Ping: 20pings in 20sec</desc>
<id>nrmodule2_quectel</id>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
<testCase id="070000">
<class>Iperf</class>
<desc>iperf (DL/10Mbps/UDP)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 10M -t 30</iperf_args>
<direction>DL</direction>
<id>nrmodule2_quectel</id>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="070001">
<class>Iperf</class>
<desc>iperf (DL/20Mbps/UDP)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 20M -t 30</iperf_args>
<direction>DL</direction>
<id>nrmodule2_quectel</id>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="070002">
<class>Iperf</class>
<desc>iperf (DL/40Mbps/UDP)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 40M -t 30</iperf_args>
<direction>DL</direction>
<id>nrmodule2_quectel</id>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="070003">
<class>Iperf</class>
<desc>iperf (DL/60Mbps/UDP)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 60M -t 30</iperf_args>
<direction>DL</direction>
<id>nrmodule2_quectel</id>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="070004">
<class>Iperf</class>
<desc>iperf (DL/90Mbps/UDP)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 90M -t 30</iperf_args>
<direction>DL</direction>
<id>nrmodule2_quectel</id>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="080000">
<class>Terminate_eNB</class>
<desc>Terminate gNB</desc>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
<air_interface>nr</air_interface>
</testCase>
</testCaseList>
@@ -30,7 +30,7 @@ services:
FLEXRAN_ENABLED: 'no'
FLEXRAN_INTERFACE_NAME: eth0
FLEXRAN_IPV4_ADDRESS: 192.168.18.210
THREAD_PARALLEL_CONFIG: PARALLEL_RU_L1_TRX_SPLIT
THREAD_PARALLEL_CONFIG: PARALLEL_SINGLE_THREAD
volumes:
- /dev:/dev
networks:
@@ -26,7 +26,7 @@ services:
FLEXRAN_INTERFACE_NAME: eth0
FLEXRAN_IPV4_ADDRESS: 192.168.18.210
THREAD_PARALLEL_CONFIG: PARALLEL_RU_L1_TRX_SPLIT
USE_ADDITIONAL_OPTIONS: '-E -q'
USE_ADDITIONAL_OPTIONS: '-E -q --usrp-args "serial=30C51D4"'
volumes:
- /dev:/dev
networks:
+17
View File
@@ -60,6 +60,13 @@ elseif (${RF_BOARD} STREQUAL "OAI_IRIS")
LINK_DIRECTORIES("/usr/local/lib")
set(option_HW_lib "-lSoapySDR -rdynamic -ldl")
elseif (${RF_BOARD} STREQUAL "OAI_AW2SORI")
include_directories("${OPENAIR_TARGETS}/ARCH/AW2SORI")
set(HW_SOURCE ${HW_SOURCE}
${OPENAIR_TARGETS}/ARCH/AW2SORI/ARCH/AW2SORI/oaiori.c)
LINK_DIRECTORIES("/usr/local/lib")
set(openair_HW_lib "-shared -fPIC -msse4 -g -ggdb -lori")
endif (${RF_BOARD} STREQUAL "OAI_USRP")
message("RU=${RU}")
@@ -894,6 +901,7 @@ add_library(oai_lmssdrdevif MODULE ${HWLIB_LMSSDR_SOURCE} )
target_include_directories(oai_lmssdrdevif PRIVATE /usr/local/include/lime)
target_link_libraries(oai_lmssdrdevif LimeSuite )
include_directories("${OPENAIR_TARGETS}/ARCH/ETHERNET/USERSPACE/LIB/")
set(TPLIB_ETHERNET_SOURCE
${OPENAIR_TARGETS}/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c
@@ -902,6 +910,15 @@ set(TPLIB_ETHERNET_SOURCE
)
add_library(oai_eth_transpro MODULE ${TPLIB_ETHERNET_SOURCE} )
include_directories("${OPENAIR_TARGETS}/ARCH/AW2SORI/")
link_directories("/usr/local/lib")
set(HWLIB_AW2SORI_SOURCE
${OPENAIR_TARGETS}/ARCH/AW2SORI/oaiori.c
)
add_library(aw2sori_transpro MODULE ${HWLIB_AW2SORI_SOURCE})
target_compile_options(aw2sori_transpro PRIVATE -shared -fPIC -msse4 -g -ggdb -DLITE_COMPILATION)
target_link_libraries(aw2sori_transpro libori.so)
include_directories("${OPENAIR_TARGETS}/ARCH/IRIS/USERSPACE/LIB/")
set(option_HWIRISLIB_lib "-l SoapySDR")
set(HWLIB_IRIS_SOURCE
+10 -2
View File
@@ -118,7 +118,7 @@ Options
-a | --agent
Enables agent for software-defined control of the eNB
-w | --hardware
EXMIMO, USRP, BLADERF, LMSSDR, IRIS, ADRV9371_ZC706, SIMU, None (Default)
EXMIMO, USRP, BLADERF, LMSSDR, IRIS, ADRV9371_ZC706, SIMU, AW2SORI, None (Default)
Adds this RF board support (in external packages installation and in compilation)
-P | --phy_simulators
Makes the unitary tests Layer 1 simulators
@@ -293,7 +293,7 @@ function main() {
"EXMIMO")
HW="EXMIMO"
;;
"USRP" | "BLADERF" | "LMSSDR" | "IRIS" | "ADRV9371_ZC706" | "SIMU")
"USRP" | "BLADERF" | "LMSSDR" | "IRIS" | "ADRV9371_ZC706" | "SIMU" | "AW2SORI")
HW="OAI_"$2
;;
"None")
@@ -931,6 +931,14 @@ function main() {
echo_error "== FAILED == Unexpected Kernel $SYRIQ_KMAJ.$SYRIQ_KMIN"
fi
echo_info "liboai_device.so is linked to ADRV9371_ZC706 device library for Kernel $SYRIQ_KMAJ.$SYRIQ_KMIN"
elif [ "$HW" == "OAI_AW2SORI" ] ; then
compilations \
$build_dir aw2sori_transpro \
libaw2sori_transpro.so $dbin/libaw2sori_transpro.so.$REL
ln -sf libaw2sori_transpro.so libthirdparty_transpro.so
ln -sf $dbin/libaw2sori_transpro.so.$REL $dbin/libaw2sori_transpro.so
echo_info "build libthirdparty_transpro.so for AW2SORI fronthaul"
else
echo_info "liboai_device.so is not linked to any device library"
fi
+9 -9
View File
@@ -9,15 +9,15 @@ 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
if [[ -v USE_FDD_DU ]]; then ln -s $PREFIX/etc/du.fdd.conf $PREFIX/etc/enb.conf; fi
if [[ -v USE_FDD_MONO ]]; then ln -s $PREFIX/etc/enb.fdd.conf $PREFIX/etc/enb.conf; fi
if [[ -v USE_TDD_MONO ]]; then ln -s $PREFIX/etc/enb.tdd.conf $PREFIX/etc/enb.conf; fi
if [[ -v USE_FDD_FAPI_RCC ]]; then ln -s $PREFIX/etc/rcc.nfapi.fdd.conf $PREFIX/etc/enb.conf; fi
if [[ -v USE_FDD_IF4P5_RCC ]]; then ln -s $PREFIX/etc/rcc.if4p5.fdd.conf $PREFIX/etc/enb.conf; fi
if [[ -v USE_TDD_IF4P5_RCC ]]; then ln -s $PREFIX/etc/rcc.if4p5.tdd.conf $PREFIX/etc/enb.conf; fi
if [[ -v USE_FDD_RRU ]]; then ln -s $PREFIX/etc/rru.fdd.conf $PREFIX/etc/enb.conf; fi
if [[ -v USE_TDD_RRU ]]; then ln -s $PREFIX/etc/rru.tdd.conf $PREFIX/etc/enb.conf; fi
if [[ -v USE_FDD_CU ]]; then cp $PREFIX/etc/cu.fdd.conf $PREFIX/etc/enb.conf; fi
if [[ -v USE_FDD_DU ]]; then cp $PREFIX/etc/du.fdd.conf $PREFIX/etc/enb.conf; fi
if [[ -v USE_FDD_MONO ]]; then cp $PREFIX/etc/enb.fdd.conf $PREFIX/etc/enb.conf; fi
if [[ -v USE_TDD_MONO ]]; then cp $PREFIX/etc/enb.tdd.conf $PREFIX/etc/enb.conf; fi
if [[ -v USE_FDD_FAPI_RCC ]]; then cp $PREFIX/etc/rcc.nfapi.fdd.conf $PREFIX/etc/enb.conf; fi
if [[ -v USE_FDD_IF4P5_RCC ]]; then cp $PREFIX/etc/rcc.if4p5.fdd.conf $PREFIX/etc/enb.conf; fi
if [[ -v USE_TDD_IF4P5_RCC ]]; then cp $PREFIX/etc/rcc.if4p5.tdd.conf $PREFIX/etc/enb.conf; fi
if [[ -v USE_FDD_RRU ]]; then cp $PREFIX/etc/rru.fdd.conf $PREFIX/etc/enb.conf; fi
if [[ -v USE_TDD_RRU ]]; then cp $PREFIX/etc/rru.tdd.conf $PREFIX/etc/enb.conf; fi
# Only this template will be manipulated
CONFIG_FILES=`ls $PREFIX/etc/enb.conf || true`
+2 -2
View File
@@ -7,8 +7,8 @@ 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
if [[ -v USE_SA_TDD_MONO ]]; then ln -s $PREFIX/etc/gnb.sa.tdd.conf $PREFIX/etc/gnb.conf; fi
if [[ -v USE_NSA_TDD_MONO ]]; then cp $PREFIX/etc/gnb.nsa.tdd.conf $PREFIX/etc/gnb.conf; fi
if [[ -v USE_SA_TDD_MONO ]]; then cp $PREFIX/etc/gnb.sa.tdd.conf $PREFIX/etc/gnb.conf; fi
# Only this template will be manipulated
CONFIG_FILES=`ls $PREFIX/etc/gnb.conf || true`
+2 -2
View File
@@ -5,8 +5,8 @@ set -euo pipefail
PREFIX=/opt/oai-lte-ru
# Based another env var, pick one template to use
if [[ -v USE_FDD_RRU ]]; then ln -s $PREFIX/etc/rru.fdd.conf $PREFIX/etc/rru.conf; fi
if [[ -v USE_TDD_RRU ]]; then ln -s $PREFIX/etc/rru.tdd.conf $PREFIX/etc/rru.conf; fi
if [[ -v USE_FDD_RRU ]]; then cp $PREFIX/etc/rru.fdd.conf $PREFIX/etc/rru.conf; fi
if [[ -v USE_TDD_RRU ]]; then cp $PREFIX/etc/rru.tdd.conf $PREFIX/etc/rru.conf; fi
# Only this template will be manipulated
CONFIG_FILES=`ls $PREFIX/etc/rru.conf || true`
+1 -1
View File
@@ -5,7 +5,7 @@ set -euo pipefail
PREFIX=/opt/oai-lte-ue
# Based another env var, pick one template to use
if [[ -v USE_NFAPI ]]; then ln -s $PREFIX/etc/ue.nfapi.conf $PREFIX/etc/ue.conf; fi
if [[ -v USE_NFAPI ]]; then cp $PREFIX/etc/ue.nfapi.conf $PREFIX/etc/ue.conf; fi
# Only this template will be manipulated and the USIM one!
CONFIG_FILES=`ls $PREFIX/etc/ue.conf $PREFIX/etc/ue_usim.conf || true`
+1 -1
View File
@@ -5,7 +5,7 @@ set -euo pipefail
PREFIX=/opt/oai-nr-ue
# Based another env var, pick one template to use
#if [[ -v USE_NFAPI ]]; then ln -s $PREFIX/etc/ue.nfapi.conf $PREFIX/etc/ue.conf; fi
#if [[ -v USE_NFAPI ]]; then cp $PREFIX/etc/ue.nfapi.conf $PREFIX/etc/ue.conf; fi
# Only this template will be manipulated and the USIM one!
CONFIG_FILES=`ls $PREFIX/etc/ue.conf $PREFIX/etc/nr-ue-sim.conf || true`
+75 -76
View File
@@ -1,76 +1,75 @@
/*
* 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);
}
/*
* 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);
}
@@ -16,6 +16,7 @@
#ifndef _FAPI_NR_UE_INTERFACE_H_
#define _FAPI_NR_UE_INTERFACE_H_
#include <pthread.h>
#include "stddef.h"
#include "platform_types.h"
@@ -349,6 +350,7 @@ typedef struct {
uint16_t slot;
uint8_t number_pdus;
fapi_nr_ul_config_request_pdu_t ul_config_list[FAPI_NR_UL_CONFIG_LIST_NUM];
pthread_mutex_t mutex_ul_config;
} fapi_nr_ul_config_request_t;
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+19 -14
View File
@@ -388,7 +388,7 @@ int nr_rate_matching_ldpc(uint8_t Ilbrm,
uint32_t Ncb,ind,k=0,Nref,N;
if (C==0) {
printf("nr_rate_matching: invalid parameters (C %d\n",C);
LOG_E(PHY,"nr_rate_matching: invalid parameters (C %d\n",C);
return -1;
}
@@ -407,16 +407,15 @@ int nr_rate_matching_ldpc(uint8_t Ilbrm,
#ifdef RM_DEBUG
printf("nr_rate_matching_ldpc: E %d, F %d, Foffset %d, k0 %d, Ncb %d, rvidx %d\n", E, F, Foffset,ind, Ncb, rvidx);
#endif
AssertFatal(Foffset <= E,
"Foffset %d > E %d "
"(Ilbrm %d, Tbslbrm %d, Z %d, BG %d, C %d)\n",
Foffset, E,
Ilbrm, Tbslbrm, Z, BG, C);
AssertFatal(Foffset <= Ncb,
"Foffset %d > Ncb %d "
"(Ilbrm %d, Tbslbrm %d, Z %d, BG %d, C %d)\n",
Foffset, Ncb,
Ilbrm, Tbslbrm, Z, BG, C);
if (Foffset > E) {
LOG_E(PHY,"nr_rate_matching: invalid parameters (Foffset %d > E %d)\n",Foffset,E);
return -1;
}
if (Foffset > Ncb) {
LOG_E(PHY,"nr_rate_matching: invalid parameters (Foffset %d > Ncb %d)\n",Foffset,Ncb);
return -1;
}
if (ind >= Foffset && ind < (F+Foffset)) ind = F+Foffset;
@@ -478,7 +477,7 @@ int nr_rate_matching_ldpc_rx(uint8_t Ilbrm,
#endif
if (C==0) {
printf("nr_rate_matching: invalid parameters (C %d\n",C);
LOG_E(PHY,"nr_rate_matching: invalid parameters (C %d\n",C);
return -1;
}
@@ -493,8 +492,14 @@ int nr_rate_matching_ldpc_rx(uint8_t Ilbrm,
}
ind = (index_k0[BG-1][rvidx]*Ncb/N)*Z;
AssertFatal(Foffset <= E,"Foffset %d > E %d\n",Foffset,E);
AssertFatal(Foffset <= Ncb,"Foffset %d > Ncb %d\n",Foffset,Ncb);
if (Foffset > E) {
LOG_E(PHY,"nr_rate_matching: invalid parameters (Foffset %d > E %d)\n",Foffset,E);
return -1;
}
if (Foffset > Ncb) {
LOG_E(PHY,"nr_rate_matching: invalid parameters (Foffset %d > Ncb %d)\n",Foffset,Ncb);
return -1;
}
#ifdef RM_DEBUG
printf("nr_rate_matching_ldpc_rx: Clear %d, E %d, k0 %d, Ncb %d, rvidx %d\n", clear, E, ind, Ncb, rvidx);
+9 -11
View File
@@ -111,9 +111,9 @@ void nr_pdsch_codeword_scrambling_optim(uint8_t *in,
}
uint8_t nr_generate_pdsch(processingData_L1tx_t *msgTx,
int frame,
int slot) {
void nr_generate_pdsch(processingData_L1tx_t *msgTx,
int frame,
int slot) {
PHY_VARS_gNB *gNB = msgTx->gNB;
NR_gNB_DLSCH_t *dlsch;
@@ -181,11 +181,12 @@ uint8_t nr_generate_pdsch(processingData_L1tx_t *msgTx,
/// CRC, coding, interleaving and rate matching
AssertFatal(harq->pdu!=NULL,"harq->pdu is null\n");
start_meas(dlsch_encoding_stats);
nr_dlsch_encoding(gNB,
harq->pdu, frame, slot, dlsch, frame_parms,tinput,tprep,tparity,toutput,
dlsch_rate_matching_stats,
dlsch_interleaving_stats,
dlsch_segmentation_stats);
if (nr_dlsch_encoding(gNB,
harq->pdu, frame, slot, dlsch, frame_parms,tinput,tprep,tparity,toutput,
dlsch_rate_matching_stats,
dlsch_interleaving_stats,
dlsch_segmentation_stats) == -1)
return;
stop_meas(dlsch_encoding_stats);
#ifdef DEBUG_DLSCH
printf("PDSCH encoding:\nPayload:\n");
@@ -523,9 +524,6 @@ uint8_t nr_generate_pdsch(processingData_L1tx_t *msgTx,
LOG_D(PHY,"beam index for PDSCH allocation already taken\n");
}
}// dlsch loop
return 0;
}
void dump_pdsch_stats(FILE *fd,PHY_VARS_gNB *gNB) {
+3 -3
View File
@@ -67,9 +67,9 @@ void nr_fill_dlsch(processingData_L1tx_t *msgTx,
nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu,
unsigned char *sdu);
uint8_t nr_generate_pdsch(processingData_L1tx_t *msgTx,
int frame,
int slot);
void nr_generate_pdsch(processingData_L1tx_t *msgTx,
int frame,
int slot);
void free_gNB_dlsch(NR_gNB_DLSCH_t **dlschptr, uint16_t N_RB);
void clean_gNB_dlsch(NR_gNB_DLSCH_t *dlsch);
+13 -11
View File
@@ -427,17 +427,19 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
Tbslbrm = nr_compute_tbslbrm(rel15->mcsTable[0],nb_rb,Nl);
start_meas(dlsch_rate_matching_stats);
nr_rate_matching_ldpc(Ilbrm,
Tbslbrm,
harq->BG,
*Zc,
harq->d[r],
harq->e+r_offset,
harq->C,
F,
Kr-F-2*(*Zc),
rel15->rvIndex[0],
E);
if (nr_rate_matching_ldpc(Ilbrm,
Tbslbrm,
harq->BG,
*Zc,
harq->d[r],
harq->e+r_offset,
harq->C,
F,
Kr-F-2*(*Zc),
rel15->rvIndex[0],
E) == -1)
return -1;
stop_meas(dlsch_rate_matching_stats);
#ifdef DEBUG_DLSCH_CODING
for (int i =0; i<16; i++)
+14 -12
View File
@@ -274,7 +274,7 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
#ifdef DEBUG_ULSCH_CODING
printf("encoding thinks this is a new packet \n");
#endif
harq_process->first_tx = 0;
harq_process->first_tx = 0;
///////////////////////// a---->| add CRC |---->b /////////////////////////
///////////
/*
@@ -445,17 +445,19 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
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,
*pz,
harq_process->d[r],
harq_process->e+r_offset,
harq_process->C,
F,
Kr-F-2*(*pz),
harq_process->pusch_pdu.pusch_data.rv_index,
E);
if (nr_rate_matching_ldpc(Ilbrm,
Tbslbrm,
harq_process->BG,
*pz,
harq_process->d[r],
harq_process->e+r_offset,
harq_process->C,
F,
Kr-F-2*(*pz),
harq_process->pusch_pdu.pusch_data.rv_index,
E) == -1)
return -1;
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);
+2 -1
View File
@@ -162,7 +162,8 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
nb_dmrs_re_per_rb, number_dmrs_symbols, mod_order, Nl);
nr_ulsch_encoding(UE, ulsch_ue, frame_parms, harq_pid, G);
if (nr_ulsch_encoding(UE, ulsch_ue, frame_parms, harq_pid, G) == -1)
return;
///////////
////////////////////////////////////////////////////////////////////
+19 -9
View File
@@ -155,6 +155,7 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
fapi_nr_ul_config_request_t *ul_config = scheduled_response->ul_config;
pthread_mutex_lock(&ul_config->mutex_ul_config);
for (i = 0; i < ul_config->number_pdus; ++i){
AssertFatal(ul_config->ul_config_list[i].pdu_type <= FAPI_NR_UL_CONFIG_TYPES,"pdu_type %d out of bounds\n",ul_config->ul_config_list[i].pdu_type);
@@ -176,6 +177,7 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
pusch_config_pdu = &ul_config->ul_config_list[i].pusch_config_pdu;
current_harq_pid = pusch_config_pdu->pusch_data.harq_process_id;
NR_UL_UE_HARQ_t *harq_process_ul_ue = ulsch0->harq_processes[current_harq_pid];
harq_process_ul_ue->status = 0;
if (harq_process_ul_ue){
@@ -185,14 +187,16 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
ulsch0->f_pusch = pusch_config_pdu->absolute_delta_PUSCH;
if (scheduled_response->tx_request){
fapi_nr_tx_request_body_t *tx_req_body = &scheduled_response->tx_request->tx_request_body[i];
LOG_D(PHY,"%d.%d Copying %d bytes to harq_process_ul_ue->a (harq_pid %d)\n",scheduled_response->frame,slot,tx_req_body->pdu_length,current_harq_pid);
memcpy(harq_process_ul_ue->a, tx_req_body->pdu, tx_req_body->pdu_length);
harq_process_ul_ue->status = ACTIVE;
scheduled_response->tx_request->number_of_pdus = 0;
if (scheduled_response->tx_request) {
for (int j=0; j<scheduled_response->tx_request->number_of_pdus; j++) {
fapi_nr_tx_request_body_t *tx_req_body = &scheduled_response->tx_request->tx_request_body[j];
if (tx_req_body->pdu_index == i) {
LOG_D(PHY,"%d.%d Copying %d bytes to harq_process_ul_ue->a (harq_pid %d)\n",scheduled_response->frame,slot,tx_req_body->pdu_length,current_harq_pid);
memcpy(harq_process_ul_ue->a, tx_req_body->pdu, tx_req_body->pdu_length);
harq_process_ul_ue->status = ACTIVE;
break;
}
}
}
} else {
@@ -230,7 +234,13 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
break;
}
}
memset(ul_config, 0, sizeof(fapi_nr_ul_config_request_t));
if (scheduled_response->tx_request)
scheduled_response->tx_request->number_of_pdus = 0;
ul_config->sfn = 0;
ul_config->slot = 0;
ul_config->number_pdus = 0;
memset(ul_config->ul_config_list, 0, sizeof(ul_config->ul_config_list));
pthread_mutex_unlock(&ul_config->mutex_ul_config);
}
}
return 0;
+1 -1
View File
@@ -33,7 +33,7 @@ MESSAGE_DEF(X2AP_SETUP_REQUEST_LOG , MESSAGE_PRIORITY_MED, IttiMsgT
/* eNB application layer -> X2AP messages */
MESSAGE_DEF(X2AP_REGISTER_ENB_REQ , MESSAGE_PRIORITY_MED, x2ap_register_enb_req_t , x2ap_register_enb_req)
MESSAGE_DEF(X2AP_SUBFRAME_PROCESS , MESSAGE_PRIORITY_MED, x2ap_subframe_process_t , x2ap_subframe_process)
MESSAGE_DEF(X2AP_RESET_REQ , MESSAGE_PRIORITY_MED, x2ap_reset_req_t , x2ap_reset_req)
/* X2AP -> eNB application layer messages */
MESSAGE_DEF(X2AP_REGISTER_ENB_CNF , MESSAGE_PRIORITY_MED, x2ap_register_enb_cnf_t , x2ap_register_enb_cnf)
MESSAGE_DEF(X2AP_DEREGISTERED_ENB_IND , MESSAGE_PRIORITY_MED, x2ap_deregistered_enb_ind_t , x2ap_deregistered_enb_ind)
+10
View File
@@ -38,6 +38,8 @@ typedef enum {
#define X2AP_REGISTER_ENB_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_register_enb_req
#define X2AP_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_setup_req
#define X2AP_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.x2ap_setup_resp
#define X2AP_RESET_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_reset_req
#define X2AP_RESET_RESP(mSGpTR) (mSGpTR)->ittiMsg.x2ap_reset_resp
#define X2AP_HANDOVER_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_handover_req
#define X2AP_HANDOVER_REQ_ACK(mSGpTR) (mSGpTR)->ittiMsg.x2ap_handover_req_ack
#define X2AP_REGISTER_ENB_CNF(mSGpTR) (mSGpTR)->ittiMsg.x2ap_register_enb_cnf
@@ -68,6 +70,14 @@ typedef struct x2ap_setup_resp_s {
int num_cc;
} x2ap_setup_resp_t;
typedef struct x2ap_reset_req_s {
uint32_t cause;
} x2ap_reset_req_t;
typedef struct x2ap_reset_resp_s {
int dummy;
} x2ap_reset_resp_t;
/* X2AP UE CONTEXT RELEASE */
typedef struct x2ap_ue_context_release_s {
/* used for X2AP->RRC in source and RRC->X2AP in target */
+2
View File
@@ -660,6 +660,8 @@ int nr_rrc_mac_config_req_ue(
if (mac->scc_SIB->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols>0) num_slots_ul++;
LOG_I(MAC, "Initializing ul_config_request. num_slots_ul = %d\n", num_slots_ul);
mac->ul_config_request = (fapi_nr_ul_config_request_t *)calloc(num_slots_ul, sizeof(fapi_nr_ul_config_request_t));
for (int i=0; i<num_slots_ul; i++)
pthread_mutex_init(&(mac->ul_config_request[i].mutex_ul_config), NULL);
// Setup the SSB to Rach Occasions mapping according to the config
build_ssb_to_ro_map(mac);//->scc, mac->phy_config.config_req.cell_config.frame_duplex_type);
mac->if_module->phy_config_request(&mac->phy_config);
+3
View File
@@ -40,6 +40,7 @@
#include "openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h"
#include "executables/softmodem-common.h"
#include "openair2/LAYER2/nr_pdcp/nr_pdcp.h"
#include <pthread.h>
static NR_UE_MAC_INST_t *nr_ue_mac_inst;
@@ -74,6 +75,8 @@ NR_UE_MAC_INST_t * nr_l2_init_ue(NR_UE_RRC_INST_t* rrc_inst) {
num_slots_ul++;
LOG_D(MAC, "Initializing ul_config_request. num_slots_ul = %d\n", num_slots_ul);
nr_ue_mac_inst->ul_config_request = (fapi_nr_ul_config_request_t *)calloc(num_slots_ul, sizeof(fapi_nr_ul_config_request_t));
for (int i=0; i<num_slots_ul; i++)
pthread_mutex_init(&(nr_ue_mac_inst->ul_config_request[i].mutex_ul_config), NULL);
}
}
else {
+8 -4
View File
@@ -668,15 +668,15 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
LOG_W(MAC, "In %s: ul_config request is NULL. Probably due to unexpected UL DCI in frame.slot %d.%d. Ignoring DCI!\n", __FUNCTION__, frame, slot);
return -1;
}
pthread_mutex_lock(&ul_config->mutex_ul_config);
AssertFatal(ul_config->number_pdus<FAPI_NR_UL_CONFIG_LIST_NUM, "ul_config->number_pdus %d out of bounds\n",ul_config->number_pdus);
nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu;
fill_ul_config(ul_config, frame_tx, slot_tx, FAPI_NR_UL_CONFIG_TYPE_PUSCH);
pthread_mutex_unlock(&ul_config->mutex_ul_config);
// Config PUSCH PDU
ret = nr_config_pusch_pdu(mac, pusch_config_pdu, dci, NULL, rnti, &dci_format);
}
break;
@@ -729,13 +729,15 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
return -1;
}
pthread_mutex_lock(&ul_config->mutex_ul_config);
AssertFatal(ul_config->number_pdus<FAPI_NR_UL_CONFIG_LIST_NUM, "ul_config->number_pdus %d out of bounds\n",ul_config->number_pdus);
nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu;
fill_ul_config(ul_config, frame_tx, slot_tx, FAPI_NR_UL_CONFIG_TYPE_PUSCH);
pthread_mutex_unlock(&ul_config->mutex_ul_config);
// Config PUSCH PDU
ret = nr_config_pusch_pdu(mac, pusch_config_pdu, dci, NULL, rnti, &dci_format);
} else AssertFatal(1==0,"Cannot schedule PUSCH\n");
break;
}
@@ -3944,13 +3946,15 @@ int nr_ue_process_rar(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t
rnti = ra->t_crnti;
}
pthread_mutex_lock(&ul_config->mutex_ul_config);
AssertFatal(ul_config->number_pdus<FAPI_NR_UL_CONFIG_LIST_NUM, "ul_config->number_pdus %d out of bounds\n",ul_config->number_pdus);
nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu;
fill_ul_config(ul_config, frame_tx, slot_tx, FAPI_NR_UL_CONFIG_TYPE_PUSCH);
pthread_mutex_unlock(&ul_config->mutex_ul_config);
// Config Msg3 PDU
nr_config_pusch_pdu(mac, pusch_config_pdu, NULL, &rar_grant, rnti, NULL);
}
} else {
+88 -63
View File
@@ -30,6 +30,7 @@
#include <stdio.h>
#include <math.h>
#include <pthread.h>
/* exe */
#include <common/utils/nr/nr_common.h>
@@ -59,7 +60,6 @@ static prach_association_pattern_t prach_assoc_pattern;
static ssb_list_info_t ssb_list;
void fill_ul_config(fapi_nr_ul_config_request_t *ul_config, frame_t frame_tx, int slot_tx, uint8_t pdu_type){
ul_config->ul_config_list[ul_config->number_pdus].pdu_type = pdu_type;
ul_config->slot = slot_tx;
ul_config->sfn = frame_tx;
@@ -945,77 +945,88 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
// Schedule ULSCH only if the current frame and slot match those in ul_config_req
// AND if a UL grant (UL DCI or Msg3) has been received (as indicated by num_pdus)
if (ul_config && (ul_info->slot_tx == ul_config->slot && ul_info->frame_tx == ul_config->sfn) && ul_config->number_pdus > 0){
if (ul_config){
pthread_mutex_lock(&ul_config->mutex_ul_config);
if ((ul_info->slot_tx == ul_config->slot && ul_info->frame_tx == ul_config->sfn) && ul_config->number_pdus > 0){
LOG_D(NR_MAC, "In %s:[%d.%d]: number of UL PDUs: %d with UL transmission in [%d.%d]\n", __FUNCTION__, frame_tx, slot_tx, ul_config->number_pdus, ul_config->sfn, ul_config->slot);
LOG_D(NR_MAC, "In %s:[%d.%d]: number of UL PDUs: %d with UL transmission in [%d.%d]\n", __FUNCTION__, frame_tx, slot_tx, ul_config->number_pdus, ul_config->sfn, ul_config->slot);
uint8_t ulsch_input_buffer[MAX_ULSCH_PAYLOAD_BYTES];
nr_scheduled_response_t scheduled_response;
fapi_nr_tx_request_t tx_req;
uint8_t ulsch_input_buffer_array[NFAPI_MAX_NUM_UL_PDU][MAX_ULSCH_PAYLOAD_BYTES];
nr_scheduled_response_t scheduled_response;
fapi_nr_tx_request_t tx_req;
tx_req.slot = slot_tx;
tx_req.sfn = frame_tx;
tx_req.number_of_pdus = 0;
for (int j = 0; j < ul_config->number_pdus; j++) {
for (int j = 0; j < ul_config->number_pdus; j++) {
uint8_t *ulsch_input_buffer = &(ulsch_input_buffer_array[tx_req.number_of_pdus][MAX_ULSCH_PAYLOAD_BYTES]);
fapi_nr_ul_config_request_pdu_t *ulcfg_pdu = &ul_config->ul_config_list[j];
fapi_nr_ul_config_request_pdu_t *ulcfg_pdu = &ul_config->ul_config_list[j];
if (ulcfg_pdu->pdu_type == FAPI_NR_UL_CONFIG_TYPE_PUSCH) {
if (ulcfg_pdu->pdu_type == FAPI_NR_UL_CONFIG_TYPE_PUSCH) {
int mac_pdu_exist = 0;
uint16_t TBS_bytes = ulcfg_pdu->pusch_config_pdu.pusch_data.tb_size;
LOG_D(NR_MAC,"harq_id %d, NDI %d NDI_DCI %d, TBS_bytes %d (ra_state %d)\n",
ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id,
mac->UL_ndi[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id],
ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator,
TBS_bytes,ra->ra_state);
if (ra->ra_state == WAIT_RAR && !ra->cfra){
memcpy(ulsch_input_buffer, mac->ulsch_pdu.payload, TBS_bytes);
LOG_D(NR_MAC,"[RAPROC] Msg3 to be transmitted:\n");
for (int k = 0; k < TBS_bytes; k++) {
LOG_D(NR_MAC,"(%i): 0x%x\n",k,mac->ulsch_pdu.payload[k]);
}
LOG_D(NR_MAC,"Flipping NDI for harq_id %d (Msg3)\n",ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator);
mac->UL_ndi[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id] = ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator;
mac->first_ul_tx[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id] = 0;
mac_pdu_exist = 1;
} else {
uint16_t TBS_bytes = ulcfg_pdu->pusch_config_pdu.pusch_data.tb_size;
LOG_D(NR_MAC,"harq_id %d, NDI %d NDI_DCI %d, TBS_bytes %d (ra_state %d)\n",
ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id,
mac->UL_ndi[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id],
ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator,
TBS_bytes,ra->ra_state);
if (ra->ra_state == WAIT_RAR && !ra->cfra){
memcpy(ulsch_input_buffer, mac->ulsch_pdu.payload, TBS_bytes);
LOG_D(NR_MAC,"[RAPROC] Msg3 to be transmitted:\n");
for (int k = 0; k < TBS_bytes; k++) {
LOG_D(NR_MAC,"(%i): 0x%x\n",k,mac->ulsch_pdu.payload[k]);
}
LOG_D(NR_MAC,"Flipping NDI for harq_id %d (Msg3)\n",ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator);
mac->UL_ndi[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id] = ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator;
mac->first_ul_tx[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id] = 0;
} else {
if ((mac->UL_ndi[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id] != ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator ||
mac->first_ul_tx[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id]==1) &&
((get_softmodem_params()->phy_test == 1) ||
(ra->ra_state == RA_SUCCEEDED) ||
(ra->ra_state == WAIT_RAR && ra->cfra))){
if ((mac->UL_ndi[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id] != ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator ||
mac->first_ul_tx[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id]==1) &&
((get_softmodem_params()->phy_test == 1) ||
(ra->ra_state == RA_SUCCEEDED) ||
(ra->ra_state == WAIT_RAR && ra->cfra))){
// Getting IP traffic to be transmitted
nr_ue_get_sdu(mod_id, cc_id,frame_tx, slot_tx, gNB_index, ulsch_input_buffer, TBS_bytes);
mac_pdu_exist = 1;
}
LOG_D(NR_MAC,"Flipping NDI for harq_id %d\n",ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator);
mac->UL_ndi[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id] = ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator;
mac->first_ul_tx[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id] = 0;
// Getting IP traffic to be transmitted
nr_ue_get_sdu(mod_id, cc_id,frame_tx, slot_tx, gNB_index, ulsch_input_buffer, TBS_bytes);
}
LOG_D(NR_MAC,"Flipping NDI for harq_id %d\n",ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator);
mac->UL_ndi[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id] = ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator;
mac->first_ul_tx[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id] = 0;
}
// Config UL TX PDU
tx_req.slot = slot_tx;
tx_req.sfn = frame_tx;
tx_req.number_of_pdus++;
tx_req.tx_request_body[0].pdu_length = TBS_bytes;
tx_req.tx_request_body[0].pdu_index = j;
tx_req.tx_request_body[0].pdu = ulsch_input_buffer;
if (ra->ra_state == WAIT_CONTENTION_RESOLUTION && !ra->cfra){
LOG_I(NR_MAC,"[RAPROC] RA-Msg3 retransmitted\n");
// 38.321 restart the ra-ContentionResolutionTimer at each HARQ retransmission in the first symbol after the end of the Msg3 transmission
nr_Msg3_transmitted(ul_info->module_id, ul_info->cc_id, ul_info->frame_tx, ul_info->slot_tx, ul_info->gNB_index);
}
if (ra->ra_state == WAIT_RAR && !ra->cfra){
LOG_I(NR_MAC,"[RAPROC] RA-Msg3 transmitted\n");
nr_Msg3_transmitted(ul_info->module_id, ul_info->cc_id, ul_info->frame_tx, ul_info->slot_tx, ul_info->gNB_index);
// Config UL TX PDU
if (mac_pdu_exist) {
tx_req.tx_request_body[tx_req.number_of_pdus].pdu_length = TBS_bytes;
tx_req.tx_request_body[tx_req.number_of_pdus].pdu_index = j;
tx_req.tx_request_body[tx_req.number_of_pdus].pdu = ulsch_input_buffer;
tx_req.number_of_pdus++;
}
if (ra->ra_state == WAIT_CONTENTION_RESOLUTION && !ra->cfra){
LOG_I(NR_MAC,"[RAPROC][%d.%d] RA-Msg3 retransmitted\n", frame_tx, slot_tx);
// 38.321 restart the ra-ContentionResolutionTimer at each HARQ retransmission in the first symbol after the end of the Msg3 transmission
nr_Msg3_transmitted(ul_info->module_id, ul_info->cc_id, ul_info->frame_tx, ul_info->slot_tx, ul_info->gNB_index);
}
if (ra->ra_state == WAIT_RAR && !ra->cfra){
LOG_I(NR_MAC,"[RAPROC][%d.%d] RA-Msg3 transmitted\n", frame_tx, slot_tx);
nr_Msg3_transmitted(ul_info->module_id, ul_info->cc_id, ul_info->frame_tx, ul_info->slot_tx, ul_info->gNB_index);
}
}
}
}
pthread_mutex_unlock(&ul_config->mutex_ul_config); // avoid double lock
fill_scheduled_response(&scheduled_response, NULL, ul_config, &tx_req, mod_id, cc_id, rx_frame, rx_slot, ul_info->thread_id);
if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL){
mac->if_module->scheduled_response(&scheduled_response);
fill_scheduled_response(&scheduled_response, NULL, ul_config, &tx_req, mod_id, cc_id, rx_frame, rx_slot, ul_info->thread_id);
if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL){
mac->if_module->scheduled_response(&scheduled_response);
}
pthread_mutex_lock(&ul_config->mutex_ul_config);
}
pthread_mutex_unlock(&ul_config->mutex_ul_config);
}
}
@@ -2095,7 +2106,8 @@ void nr_ue_pucch_scheduler(module_id_t module_idP, frame_t frameP, int slotP, in
}
// CSI
if (mac->ra.ra_state == RA_SUCCEEDED)
if (mac->ra.ra_state == RA_SUCCEEDED ||
get_softmodem_params()->phy_test == 1)
O_CSI = nr_get_csi_measurements(mac, frameP, slotP, pucch);
// ACKNACK
@@ -2144,7 +2156,13 @@ void nr_ue_pucch_scheduler(module_id_t module_idP, frame_t frameP, int slotP, in
pucch->resource_set_id = find_pucch_resource_set(mac, N_UCI);
select_pucch_resource(mac, pucch);
fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slotP);
pthread_mutex_lock(&ul_config->mutex_ul_config);
AssertFatal(ul_config->number_pdus<FAPI_NR_UL_CONFIG_LIST_NUM, "ul_config->number_pdus %d out of bounds\n",ul_config->number_pdus);
fapi_nr_ul_config_pucch_pdu *pucch_pdu = &ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu;
fill_ul_config(ul_config, frameP, slotP, FAPI_NR_UL_CONFIG_TYPE_PUCCH);
pthread_mutex_unlock(&ul_config->mutex_ul_config);
nr_ue_configure_pucch(mac,
slotP,
rnti,
@@ -2152,7 +2170,6 @@ void nr_ue_pucch_scheduler(module_id_t module_idP, frame_t frameP, int slotP, in
pucch_pdu,
O_SR, O_ACK, O_CSI);
LOG_D(NR_MAC,"Configuring pucch, is_common = %d\n",pucch->is_common);
fill_ul_config(ul_config, frameP, slotP, FAPI_NR_UL_CONFIG_TYPE_PUCCH);
nr_scheduled_response_t scheduled_response;
fill_scheduled_response(&scheduled_response, NULL, ul_config, NULL, module_idP, 0 /*TBR fix*/, frameP, slotP, thread_id);
if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL)
@@ -2213,13 +2230,16 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s
format0 = format & 0xff; // single PRACH format
format1 = (format >> 8) & 0xff; // dual PRACH format
pthread_mutex_lock(&ul_config->mutex_ul_config);
AssertFatal(ul_config->number_pdus<FAPI_NR_UL_CONFIG_LIST_NUM, "ul_config->number_pdus %d out of bounds\n",ul_config->number_pdus);
prach_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].prach_config_pdu;
memset(prach_config_pdu, 0, sizeof(fapi_nr_ul_config_prach_pdu));
fill_ul_config(ul_config, frameP, slotP, FAPI_NR_UL_CONFIG_TYPE_PRACH);
pthread_mutex_unlock(&ul_config->mutex_ul_config);
LOG_D(PHY, "In %s: (%p) %d UL PDUs:\n", __FUNCTION__, ul_config, ul_config->number_pdus);
memset(prach_config_pdu, 0, sizeof(fapi_nr_ul_config_prach_pdu));
ncs = get_NCS(rach_ConfigGeneric->zeroCorrelationZoneConfig, format0, setup->restrictedSetConfig);
prach_config_pdu->phys_cell_id = mac->physCellId;
@@ -2295,6 +2315,7 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s
AssertFatal(1 == 0, "Invalid PRACH format");
}
} // if format1
fill_scheduled_response(&scheduled_response, NULL, ul_config, NULL, module_idP, 0 /*TBR fix*/, frameP, slotP, thread_id);
if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL)
mac->if_module->scheduled_response(&scheduled_response);
@@ -2723,7 +2744,11 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP,
if (sdu_length > 0) {
LOG_D(NR_MAC, "In %s: Generating UL MAC sub-PDU for SDU %d, length %d bytes, RB with LCID 0x%02x (buflen (TBS) %d bytes)\n", __FUNCTION__,
LOG_D(NR_MAC, "In %s: [UE %d] [%d.%d] UL-DXCH -> ULSCH, Generating UL MAC sub-PDU for SDU %d, length %d bytes, RB with LCID 0x%02x (buflen (TBS) %d bytes)\n",
__FUNCTION__,
module_idP,
frameP,
subframe,
num_sdus + 1,
sdu_length,
lcid,
+1 -1
View File
@@ -347,7 +347,7 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
if ((slot == 0) && (frame & 127) == 0) {
stats_output[0]='\0';
dump_mac_stats(RC.nrmac[module_idP],stats_output,16384);
dump_mac_stats(RC.nrmac[module_idP],stats_output,16384,true);
LOG_I(NR_MAC,"Frame.Slot %d.%d\n%s\n",frame,slot,stats_output);
}
@@ -1456,7 +1456,7 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
int n_rb=0;
for (int i=0;i<6;i++)
for (int j=0;j<8;j++) {
n_rb+=((coreset->frequencyDomainResources.buf[i]>>j)&1);
n_rb+=((coreset->frequencyDomainResources.buf[i]>>j)&1);
}
n_rb*=6;
const uint16_t N_cce = n_rb * coreset->duration / NR_NB_REG_PER_CCE;
@@ -1752,7 +1752,8 @@ void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, sub_fram
const int current_harq_pid = ra->harq_pid;
NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
NR_UE_harq_t *harq = &UE_info->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid];
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
NR_UE_harq_t *harq = &sched_ctrl->harq_processes[current_harq_pid];
NR_mac_stats_t *stats = &UE_info->mac_stats[UE_id];
LOG_D(NR_MAC, "ue %d, rnti %d, harq is waiting %d, round %d, frame %d %d, harq id %d\n", UE_id, ra->rnti, harq->is_waiting, harq->round, frame, slot, current_harq_pid);
@@ -1764,6 +1765,8 @@ void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, sub_fram
nr_clear_ra_proc(module_id, CC_id, frame, ra);
UE_info->active[UE_id] = true;
UE_info->Msg4_ACKed[UE_id] = true;
if(sched_ctrl->retrans_dl_harq.head>=0)
remove_nr_list(&sched_ctrl->retrans_dl_harq, current_harq_pid);
}
else {
LOG_I(NR_MAC, "(ue %i, rnti 0x%04x) RA Procedure failed at Msg4!\n", UE_id, ra->rnti);
@@ -420,9 +420,9 @@ int get_mcs_from_bler(module_id_t mod_id, int CC_id, frame_t frame, sub_frame_t
return old_mcs; // no update
// last update is longer than x frames ago
const int dtx = stats->dlsch_rounds[0] - bler_stats->dlsch_rounds[0];
const int dretx = stats->dlsch_rounds[1] - bler_stats->dlsch_rounds[1];
const int dretx2 = stats->dlsch_rounds[2] - bler_stats->dlsch_rounds[2];
const int dtx = (int)(stats->dlsch_rounds[0] - bler_stats->dlsch_rounds[0]);
const int dretx = (int)(stats->dlsch_rounds[1] - bler_stats->dlsch_rounds[1]);
const int dretx2 = (int)(stats->dlsch_rounds[2] - bler_stats->dlsch_rounds[2]);
const float bler_window = dtx > 0 ? (float) dretx / dtx : bler_stats->bler;
const float rd2_bler_wnd = dtx > 0 ? (float) dretx2 / dtx : bler_stats->rd2_bler;
bler_stats->bler = BLER_FILTER * bler_stats->bler + (1 - BLER_FILTER) * bler_window;
+24 -20
View File
@@ -801,7 +801,7 @@ static void handle_dl_harq(module_id_t mod_id,
harq->ndi ^= 1;
NR_mac_stats_t *stats = &UE_info->mac_stats[UE_id];
stats->dlsch_errors++;
LOG_D(NR_MAC, "retransmission error for UE %d (total %d)\n", UE_id, stats->dlsch_errors);
LOG_D(NR_MAC, "retransmission error for UE %d (total %"PRIu64")\n", UE_id, stats->dlsch_errors);
} else {
add_tail_nr_list(&UE_info->UE_sched_ctrl[UE_id].retrans_dl_harq, harq_pid);
harq->round++;
@@ -921,7 +921,6 @@ void tci_handling(module_id_t Mod_idP, int UE_id, frame_t frame, slot_t slot) {
uint8_t diff_rsrp_idx = 0;
uint8_t i, j;
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
NR_mac_stats_t *stats = &UE_info->mac_stats[UE_id];
if (n_dl_bwp < 4)
pdsch_bwp_id = bwp_id;
@@ -945,11 +944,8 @@ void tci_handling(module_id_t Mod_idP, int UE_id, frame_t frame, slot_t slot) {
//if strongest measured RSRP is configured
strongest_ssb_rsrp = get_measured_rsrp(sched_ctrl->CSI_report.ssb_cri_report.RSRP);
// including ssb rsrp in mac stats
stats->cumul_rsrp += strongest_ssb_rsrp;
stats->num_rsrp_meas++;
ssb_rsrp[idx * nb_of_csi_ssb_report] = strongest_ssb_rsrp;
LOG_D(MAC,"ssb_rsrp = %d\n",strongest_ssb_rsrp);
LOG_D(NR_MAC,"ssb_rsrp = %d\n",strongest_ssb_rsrp);
//if current ssb rsrp is greater than better rsrp
if(ssb_rsrp[idx * nb_of_csi_ssb_report] > better_rsrp_reported) {
@@ -1087,12 +1083,12 @@ uint8_t pickandreverse_bits(uint8_t *payload, uint16_t bitlen, uint8_t start_bit
void evaluate_rsrp_report(NR_UE_info_t *UE_info,
NR_UE_sched_ctrl_t *sched_ctrl,
int UE_id,
uint8_t csi_report_id,
uint8_t *payload,
int *cumul_bits,
NR_CSI_ReportConfig__reportQuantity_PR reportQuantity_type){
NR_UE_sched_ctrl_t *sched_ctrl,
int UE_id,
uint8_t csi_report_id,
uint8_t *payload,
int *cumul_bits,
NR_CSI_ReportConfig__reportQuantity_PR reportQuantity_type){
nr_csi_report_t *csi_report = &UE_info->csi_report_template[UE_id][csi_report_id];
uint8_t cri_ssbri_bitlen = csi_report->CSI_report_bitlen.cri_ssbri_bitlen;
@@ -1121,15 +1117,18 @@ void evaluate_rsrp_report(NR_UE_info_t *UE_info,
for (int csi_ssb_idx = 0; csi_ssb_idx < sched_ctrl->CSI_report.ssb_cri_report.nr_ssbri_cri ; csi_ssb_idx++) {
curr_payload = pickandreverse_bits(payload, cri_ssbri_bitlen, *cumul_bits);
if (NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP == reportQuantity_type)
sched_ctrl->CSI_report.ssb_cri_report.CRI_SSBRI [csi_ssb_idx] =
if (NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP == reportQuantity_type) {
sched_ctrl->CSI_report.ssb_cri_report.CRI_SSBRI[csi_ssb_idx] =
*(csi_report->SSB_Index_list[cri_ssbri_bitlen>0?((curr_payload)&~(~1<<(cri_ssbri_bitlen-1))):cri_ssbri_bitlen]);
else
sched_ctrl->CSI_report.ssb_cri_report.CRI_SSBRI [csi_ssb_idx] =
LOG_D(MAC,"SSB_index = %d\n",sched_ctrl->CSI_report.ssb_cri_report.CRI_SSBRI[csi_ssb_idx]);
}
else {
sched_ctrl->CSI_report.ssb_cri_report.CRI_SSBRI[csi_ssb_idx] =
*(csi_report->CSI_Index_list[cri_ssbri_bitlen>0?((curr_payload)&~(~1<<(cri_ssbri_bitlen-1))):cri_ssbri_bitlen]);
LOG_D(MAC,"CSI-RS Resource Indicator = %d\n",sched_ctrl->CSI_report.ssb_cri_report.CRI_SSBRI[csi_ssb_idx]);
}
*cumul_bits += cri_ssbri_bitlen;
LOG_D(MAC,"SSB_index = %d\n",sched_ctrl->CSI_report.ssb_cri_report.CRI_SSBRI [csi_ssb_idx]);
}
curr_payload = pickandreverse_bits(payload, 7, *cumul_bits);
@@ -1142,6 +1141,11 @@ void evaluate_rsrp_report(NR_UE_info_t *UE_info,
*cumul_bits += 4;
}
csi_report->nb_of_csi_ssb_report++;
int strongest_ssb_rsrp = get_measured_rsrp(sched_ctrl->CSI_report.ssb_cri_report.RSRP);
NR_mac_stats_t *stats = &UE_info->mac_stats[UE_id];
// including ssb rsrp in mac stats
stats->cumul_rsrp += strongest_ssb_rsrp;
stats->num_rsrp_meas++;
LOG_D(MAC,"rsrp_id = %d rsrp = %d\n",
sched_ctrl->CSI_report.ssb_cri_report.RSRP,
get_measured_rsrp(sched_ctrl->CSI_report.ssb_cri_report.RSRP));
@@ -1489,7 +1493,7 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id,
}
if ((uci_234->pduBitmap >> 2) & 0x01) {
//API to parse the csi report and store it into sched_ctrl
extract_pucch_csi_report (csi_MeasConfig, uci_234, frame, slot, UE_id, mod_id);
extract_pucch_csi_report(csi_MeasConfig, uci_234, frame, slot, UE_id, mod_id);
//TCI handling function
tci_handling(mod_id, UE_id,frame, slot);
}
@@ -1667,7 +1671,7 @@ int nr_acknack_scheduling(int mod_id,
pucch->ul_slot = (s + 1) % n_slots_frame;
}
if (ind_found==-1) {
LOG_W(NR_MAC,
LOG_D(NR_MAC,
"%4d.%2d could not find pdsch_to_harq_feedback for UE %d: earliest "
"ack slot %d\n",
frame,
+1 -1
View File
@@ -451,5 +451,5 @@ bool nr_find_nb_rb(uint16_t Qm,
void nr_sr_reporting(int Mod_idP, frame_t frameP, sub_frame_t slotP);
void dump_mac_stats(gNB_MAC_INST *gNB, char *output, int strlen);
void dump_mac_stats(gNB_MAC_INST *gNB, char *output, int strlen, bool reset_rsrp);
#endif /*__LAYER2_NR_MAC_PROTO_H__*/
+21 -20
View File
@@ -57,7 +57,7 @@ void *nrmac_stats_thread(void *arg) {
AssertFatal(fd!=NULL,"Cannot open nrMAC_stats.log, error %s\n",strerror(errno));
while (oai_exit == 0) {
dump_mac_stats(gNB,output,MACSTATSSTRLEN);
dump_mac_stats(gNB,output,MACSTATSSTRLEN,false);
fprintf(fd,"%s\n",output);
fflush(fd);
usleep(200000);
@@ -71,7 +71,7 @@ void clear_mac_stats(gNB_MAC_INST *gNB) {
memset((void*)gNB->UE_info.mac_stats,0,MAX_MOBILES_PER_GNB*sizeof(NR_mac_stats_t));
}
void dump_mac_stats(gNB_MAC_INST *gNB, char *output, int strlen)
void dump_mac_stats(gNB_MAC_INST *gNB, char *output, int strlen, bool reset_rsrp)
{
NR_UE_info_t *UE_info = &gNB->UE_info;
int num = 1;
@@ -94,36 +94,37 @@ void dump_mac_stats(gNB_MAC_INST *gNB, char *output, int strlen)
avg_rsrp,
stats->num_rsrp_meas);
stroff+=sprintf(output+stroff,"UE %d: dlsch_rounds %d/%d/%d/%d, dlsch_errors %d, pucch0_DTX %d, BLER %.5f MCS %d\n",
UE_id,
stats->dlsch_rounds[0], stats->dlsch_rounds[1],
stats->dlsch_rounds[2], stats->dlsch_rounds[3],
stats->dlsch_errors,
stats->pucch0_DTX,
sched_ctrl->dl_bler_stats.bler,
sched_ctrl->dl_bler_stats.mcs);
stats->num_rsrp_meas = 0;
stats->cumul_rsrp = 0 ;
stroff+=sprintf(output+stroff,"UE %d: dlsch_total_bytes %d\n", UE_id, stats->dlsch_total_bytes);
stroff+=sprintf(output+stroff,"UE %d: ulsch_rounds %d/%d/%d/%d, ulsch_DTX %d, ulsch_errors %d\n",
stroff+=sprintf(output+stroff,"UE %d: dlsch_rounds %"PRIu64"/%"PRIu64"/%"PRIu64"/%"PRIu64", dlsch_errors %"PRIu64", pucch0_DTX %d, BLER %.5f MCS %d\n",
UE_id,
stats->dlsch_rounds[0], stats->dlsch_rounds[1],
stats->dlsch_rounds[2], stats->dlsch_rounds[3],
stats->dlsch_errors,
stats->pucch0_DTX,
sched_ctrl->dl_bler_stats.bler,
sched_ctrl->dl_bler_stats.mcs);
if (reset_rsrp) {
stats->num_rsrp_meas = 0;
stats->cumul_rsrp = 0;
}
stroff+=sprintf(output+stroff,"UE %d: dlsch_total_bytes %"PRIu64"\n", UE_id, stats->dlsch_total_bytes);
stroff+=sprintf(output+stroff,"UE %d: ulsch_rounds %"PRIu64"/%"PRIu64"/%"PRIu64"/%"PRIu64", ulsch_DTX %d, ulsch_errors %"PRIu64"\n",
UE_id,
stats->ulsch_rounds[0], stats->ulsch_rounds[1],
stats->ulsch_rounds[2], stats->ulsch_rounds[3],
stats->ulsch_DTX,
stats->ulsch_errors);
stroff+=sprintf(output+stroff,
"UE %d: ulsch_total_bytes_scheduled %d, ulsch_total_bytes_received %d\n",
"UE %d: ulsch_total_bytes_scheduled %"PRIu64", ulsch_total_bytes_received %"PRIu64"\n",
UE_id,
stats->ulsch_total_bytes_scheduled, stats->ulsch_total_bytes_rx);
for (int lc_id = 0; lc_id < 63; lc_id++) {
if (stats->lc_bytes_tx[lc_id] > 0) {
stroff+=sprintf(output+stroff, "UE %d: LCID %d: %d bytes TX\n", UE_id, lc_id, stats->lc_bytes_tx[lc_id]);
LOG_D(NR_MAC, "UE %d: LCID %d: %d bytes TX\n", UE_id, lc_id, stats->lc_bytes_tx[lc_id]);
stroff+=sprintf(output+stroff, "UE %d: LCID %d: %"PRIu64" bytes TX\n", UE_id, lc_id, stats->lc_bytes_tx[lc_id]);
LOG_D(NR_MAC, "UE %d: LCID %d: %"PRIu64" bytes TX\n", UE_id, lc_id, stats->lc_bytes_tx[lc_id]);
}
if (stats->lc_bytes_rx[lc_id] > 0) {
stroff+=sprintf(output+stroff, "UE %d: LCID %d: %d bytes RX\n", UE_id, lc_id, stats->lc_bytes_rx[lc_id]);
LOG_D(NR_MAC, "UE %d: LCID %d: %d bytes RX\n", UE_id, lc_id, stats->lc_bytes_rx[lc_id]);
stroff+=sprintf(output+stroff, "UE %d: LCID %d: %"PRIu64" bytes RX\n", UE_id, lc_id, stats->lc_bytes_rx[lc_id]);
LOG_D(NR_MAC, "UE %d: LCID %d: %"PRIu64" bytes RX\n", UE_id, lc_id, stats->lc_bytes_rx[lc_id]);
}
}
}
+12 -12
View File
@@ -428,7 +428,7 @@ typedef struct NR_DL_bler_stats {
float bler;
float rd2_bler;
uint8_t mcs;
int dlsch_rounds[8];
uint64_t dlsch_rounds[8];
} NR_DL_bler_stats_t;
//
@@ -618,19 +618,19 @@ typedef struct {
} NRUEcontext_t;
typedef struct {
int lc_bytes_tx[64];
int lc_bytes_rx[64];
int dlsch_rounds[8];
int dlsch_errors;
int dlsch_total_bytes;
uint64_t lc_bytes_tx[64];
uint64_t lc_bytes_rx[64];
uint64_t dlsch_rounds[8];
uint64_t dlsch_errors;
uint64_t dlsch_total_bytes;
int dlsch_current_bytes;
int ulsch_rounds[8];
int ulsch_errors;
int ulsch_DTX;
int ulsch_total_bytes_scheduled;
int ulsch_total_bytes_rx;
uint64_t ulsch_rounds[8];
uint64_t ulsch_errors;
uint32_t ulsch_DTX;
uint64_t ulsch_total_bytes_scheduled;
uint64_t ulsch_total_bytes_rx;
int ulsch_current_bytes;
int pucch0_DTX;
uint32_t pucch0_DTX;
int cumul_rsrp;
uint8_t num_rsrp_meas;
} NR_mac_stats_t;
+1
View File
@@ -3293,6 +3293,7 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t
MeasObj2->measObject.choice.measObjectNR_r15.rs_ConfigSSB_r15.measTimingConfig_r15.periodicityAndOffset_r15.present = LTE_MTC_SSB_NR_r15__periodicityAndOffset_r15_PR_sf20_r15;
MeasObj2->measObject.choice.measObjectNR_r15.rs_ConfigSSB_r15.measTimingConfig_r15.periodicityAndOffset_r15.choice.sf20_r15 = 0;
MeasObj2->measObject.choice.measObjectNR_r15.rs_ConfigSSB_r15.measTimingConfig_r15.ssb_Duration_r15 = LTE_MTC_SSB_NR_r15__ssb_Duration_r15_sf4;
if (rrc_inst->nr_scg_ssb_freq > 2016666) //FR2
MeasObj2->measObject.choice.measObjectNR_r15.rs_ConfigSSB_r15.subcarrierSpacingSSB_r15 = LTE_RS_ConfigSSB_NR_r15__subcarrierSpacingSSB_r15_kHz120;
else
+9 -5
View File
@@ -72,6 +72,8 @@
#include "NR_RRCReestablishmentRequest.h"
#include "NR_UE-CapabilityRequestFilterNR.h"
#include "PHY/defs_nr_common.h"
#include "common/utils/nr/nr_common.h"
#include "openair2/LAYER2/NR_MAC_COMMON/nr_mac.h"
#if defined(NR_Rel16)
#include "NR_SCS-SpecificCarrier.h"
#include "NR_TDD-UL-DL-ConfigCommon.h"
@@ -989,7 +991,7 @@ void fill_initial_SpCellConfig(rnti_t rnti,
NR_SpCellConfig_t *SpCellConfig,
NR_ServingCellConfigCommon_t *scc,
rrc_gNB_carrier_data_t *carrier) {
int curr_bwp = NRRIV2BW(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth,MAX_BWP_SIZE);
SpCellConfig->servCellIndex = NULL;
SpCellConfig->reconfigurationWithSync = NULL;
SpCellConfig->rlmInSyncOutOfSyncThreshold = NULL;
@@ -1018,7 +1020,9 @@ void fill_initial_SpCellConfig(rnti_t rnti,
// one symbol (13)
NR_PUCCH_Resource_t *pucchres0=calloc(1,sizeof(*pucchres0));
pucchres0->pucch_ResourceId=0;
pucchres0->startingPRB=0;
//pucchres0->startingPRB=0;
pucchres0->startingPRB=(8+rnti) % curr_bwp;
LOG_D(NR_RRC, "pucchres0->startPRB %ld rnti %d curr_bwp %d\n", pucchres0->startingPRB, rnti, curr_bwp);
pucchres0->intraSlotFrequencyHopping=NULL;
pucchres0->secondHopPRB=NULL;
pucchres0->format.present= NR_PUCCH_Resource__format_PR_format0;
@@ -1170,9 +1174,9 @@ void fill_initial_SpCellConfig(rnti_t rnti,
AssertFatal(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.subcarrierSpacing==NR_SubcarrierSpacing_kHz30,
"SCS != 30kHz\n");
AssertFatal(scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity==NR_TDD_UL_DL_Pattern__dl_UL_TransmissionPeriodicity_ms5,
"TDD period != 5ms : %ld\n",scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity);
schedulingRequestResourceConfig->periodicityAndOffset->choice.sl40 = 8 + 10*((rnti>>1)&3) + (rnti&1);
"TDD period != 5ms : %ld\n",scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity);
schedulingRequestResourceConfig->periodicityAndOffset->choice.sl40 = 8;
schedulingRequestResourceConfig->resource = calloc(1,sizeof(*schedulingRequestResourceConfig->resource));
*schedulingRequestResourceConfig->resource = 0;
ASN_SEQUENCE_ADD(&pucch_Config->schedulingRequestResourceToAddModList->list,schedulingRequestResourceConfig);
+169 -1
View File
@@ -57,6 +57,17 @@ int x2ap_eNB_handle_x2_setup_response (instance_t instance,
uint32_t stream,
X2AP_X2AP_PDU_t *pdu);
static
int x2ap_eNB_handle_x2_reset_request (instance_t instance,
uint32_t assoc_id,
uint32_t stream,
X2AP_X2AP_PDU_t *pdu);
static
int x2ap_eNB_handle_x2_reset_response (instance_t instance,
uint32_t assoc_id,
uint32_t stream,
X2AP_X2AP_PDU_t *pdu);
static
int x2ap_eNB_handle_x2_setup_failure (instance_t instance,
uint32_t assoc_id,
uint32_t stream,
@@ -166,7 +177,7 @@ x2ap_message_decoded_callback x2ap_messages_callback[][3] = {
{ 0, 0, 0 }, /* snStatusTransfer */
{ x2ap_eNB_handle_ue_context_release, 0, 0 }, /* uEContextRelease */
{ x2ap_eNB_handle_x2_setup_request, x2ap_eNB_handle_x2_setup_response, x2ap_eNB_handle_x2_setup_failure }, /* x2Setup */
{ 0, 0, 0 }, /* reset */
{ x2ap_eNB_handle_x2_reset_request, x2ap_eNB_handle_x2_reset_response, 0 }, /* reset */
{ 0, 0, 0 }, /* eNBConfigurationUpdate */
{ 0, 0, 0 }, /* resourceStatusReportingInitiation */
{ 0, 0, 0 }, /* resourceStatusReporting */
@@ -501,6 +512,163 @@ x2ap_eNB_handle_x2_setup_request(instance_t instance,
return x2ap_eNB_generate_x2_setup_response(instance_p, x2ap_eNB_data);
}
const char *X2AP_cause_str1[4]={"radioNetwork","transport","protocol","misc"};
const char *X2AP_case_str_radio[50]={" X2AP_CauseRadioNetwork_handover_desirable_for_radio_reasons",
"X2AP_CauseRadioNetwork_time_critical_handover",
"X2AP_CauseRadioNetwork_resource_optimisation_handover",
"X2AP_CauseRadioNetwork_reduce_load_in_serving_cell",
"X2AP_CauseRadioNetwork_partial_handover",
"X2AP_CauseRadioNetwork_unknown_new_eNB_UE_X2AP_ID",
"X2AP_CauseRadioNetwork_unknown_old_eNB_UE_X2AP_ID",
"X2AP_CauseRadioNetwork_unknown_pair_of_UE_X2AP_ID",
"X2AP_CauseRadioNetwork_ho_target_not_allowed",
"X2AP_CauseRadioNetwork_tx2relocoverall_expiry",
"X2AP_CauseRadioNetwork_trelocprep_expiry",
"X2AP_CauseRadioNetwork_cell_not_available",
"X2AP_CauseRadioNetwork_no_radio_resources_available_in_target_cell",
"X2AP_CauseRadioNetwork_invalid_MME_GroupID",
"X2AP_CauseRadioNetwork_unknown_MME_Code",
"X2AP_CauseRadioNetwork_encryption_and_or_integrity_protection_algorithms_not_supported",
"X2AP_CauseRadioNetwork_reportCharacteristicsEmpty",
"X2AP_CauseRadioNetwork_noReportPeriodicity",
"X2AP_CauseRadioNetwork_existingMeasurementID",
"X2AP_CauseRadioNetwork_unknown_eNB_Measurement_ID",
"X2AP_CauseRadioNetwork_measurement_temporarily_not_available",
"X2AP_CauseRadioNetwork_unspecified",
"X2AP_CauseRadioNetwork_load_balancing",
"X2AP_CauseRadioNetwork_handover_optimisation",
"X2AP_CauseRadioNetwork_value_out_of_allowed_range",
"X2AP_CauseRadioNetwork_multiple_E_RAB_ID_instances",
"X2AP_CauseRadioNetwork_switch_off_ongoing",
"X2AP_CauseRadioNetwork_not_supported_QCI_value",
"X2AP_CauseRadioNetwork_measurement_not_supported_for_the_object",
"X2AP_CauseRadioNetwork_tDCoverall_expiry",
"X2AP_CauseRadioNetwork_tDCprep_expiry",
"X2AP_CauseRadioNetwork_action_desirable_for_radio_reasons",
"X2AP_CauseRadioNetwork_reduce_load",
"X2AP_CauseRadioNetwork_resource_optimisation",
"X2AP_CauseRadioNetwork_time_critical_action",
"X2AP_CauseRadioNetwork_target_not_allowed",
"X2AP_CauseRadioNetwork_no_radio_resources_available",
"X2AP_CauseRadioNetwork_invalid_QoS_combination",
"X2AP_CauseRadioNetwork_encryption_algorithms_not_supported",
"X2AP_CauseRadioNetwork_procedure_cancelled",
"X2AP_CauseRadioNetwork_rRM_purpose",
"X2AP_CauseRadioNetwork_improve_user_bit_rate",
"X2AP_CauseRadioNetwork_user_inactivity",
"X2AP_CauseRadioNetwork_radio_connection_with_UE_lost",
"X2AP_CauseRadioNetwork_bearer_option_not_supported",
"X2AP_CauseRadioNetwork_mCG_Mobility",
"X2AP_CauseRadioNetwork_sCG_Mobility",
"X2AP_CauseRadioNetwork_count_reaches_max_value",
"X2AP_CauseRadioNetwork_unknown_old_en_gNB_UE_X2AP_ID",
"X2AP_CauseRadioNetwork_pDCP_Overload"};
const char *X2AP_cause_str_radio[2]={"X2AP_CauseTransport_transport_resource_unavailable",
"X2AP_CauseTransport_unspecified"};
const char *X2AP_cause_str_protocol[7]={" X2AP_CauseProtocol_transfer_syntax_error",
"X2AP_CauseProtocol_abstract_syntax_error_reject",
"X2AP_CauseProtocol_abstract_syntax_error_ignore_and_notify",
"X2AP_CauseProtocol_message_not_compatible_with_receiver_state",
"X2AP_CauseProtocol_semantic_error",
"X2AP_CauseProtocol_unspecified",
"X2AP_CauseProtocol_abstract_syntax_error_falsely_constructed_message"};
const char *X2AP_cause_str_misc[5]={"X2AP_CauseMisc_control_processing_overload",
"X2AP_CauseMisc_hardware_failure",
"X2AP_CauseMisc_om_intervention",
"X2AP_CauseMisc_not_enough_user_plane_processing_resources",
"X2AP_CauseMisc_unspecified"};
int
x2ap_eNB_handle_x2_reset_response(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
X2AP_X2AP_PDU_t *pdu)
{
return (0);
}
int
x2ap_eNB_handle_x2_reset_request(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
X2AP_X2AP_PDU_t *pdu)
{
X2AP_ResetRequest_t *ResetRequest;
X2AP_ResetRequest_IEs_t *ie;
x2ap_eNB_instance_t *instance_p;
x2ap_eNB_data_t *x2ap_eNB_data;
MessageDef *msg;
uint32_t eNB_id = 0;
DevAssert (pdu != NULL);
ResetRequest = &pdu->choice.initiatingMessage.value.choice.ResetRequest;
X2AP_DEBUG("Received a new X2 reset request\n");
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_ResetRequest_IEs_t, ie, ResetRequest,
X2AP_ProtocolIE_ID_id_Cause, true);
if (ie == NULL ) {
X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
return -1;
} else {
AssertFatal(ie->value.present <= X2AP_Cause_PR_misc && ie->value.present > 0,"Cause value %d, is impossible\n",ie->value.present);
LOG_I(X2AP,"Received X2AP Reset Request with Cause Type %s\n",X2AP_cause_str1[ie->value.present-1]);
}
X2AP_DEBUG("Adding eNB to the list of associated eNBs\n");
if ((x2ap_eNB_data = x2ap_is_eNB_id_in_list (eNB_id)) == NULL) {
/*
* eNB has not been found in list of associated eNB,
* * * * Add it to the tail of list and initialize data
*/
if ((x2ap_eNB_data = x2ap_is_eNB_assoc_id_in_list (assoc_id)) == NULL) {
/*
* ??
*/
return -1;
} else {
x2ap_eNB_data->state = X2AP_ENB_STATE_RESETTING;
x2ap_eNB_data->eNB_id = eNB_id;
}
} else {
x2ap_eNB_data->state = X2AP_ENB_STATE_RESETTING;
/*
* eNB has been found in list, consider the x2 setup request as a reset connection,
* * * * reseting any previous UE state if sctp association is != than the previous one
*/
if (x2ap_eNB_data->assoc_id != assoc_id) {
/*
* ??: Send an overload cause...
*/
X2AP_ERROR("Reset Request: eNB id %d is already associated to an active sctp association" "Previous known: %d, new one: %d\n", eNB_id, x2ap_eNB_data->assoc_id, assoc_id);
return -1;
}
/*
* TODO: call the reset procedure
*/
}
msg = itti_alloc_new_message(TASK_X2AP, 0, X2AP_RESET_REQ);
X2AP_RESET_REQ(msg).cause = ie->value.present;
instance_p = x2ap_eNB_get_instance(instance);
DevAssert(instance_p != NULL);
itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg);
return x2ap_eNB_generate_x2_setup_response(instance_p, x2ap_eNB_data);
}
static
int x2ap_eNB_handle_x2_setup_response(instance_t instance,
+712
View File
@@ -0,0 +1,712 @@
/*! \file oaiori.c
* \brief AW2S ORI API isolator
* \author Raymond Knopp
* \date 2019
* \version 0.1
* \company Eurecom
* \maintainer: raymond.knopp@eurecom.fr
* \note
* \warning
*/
#include <arpa/inet.h>
#include <linux/if_packet.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/ether.h>
#include <unistd.h>
#include <errno.h>
#include <linux/sysctl.h>
#include <sys/sysctl.h>
#include "common_lib.h"
#include "ethernet_lib.h"
#include "ori.h"
#include "targets/ARCH/COMMON/common_lib.h"
typedef struct eutra_bandentry_s {
int16_t band;
uint32_t ul_min;
uint32_t ul_max;
uint32_t dl_min;
uint32_t dl_max;
uint32_t N_OFFs_DL;
} eutra_bandentry_t;
typedef struct band_info_s {
int nbands;
eutra_bandentry_t band_info[100];
} band_info_t;
static const eutra_bandentry_t eutra_bandtable[] = {
{1, 19200, 19800, 21100, 21700, 0 },
{2, 18500, 19100, 19300, 19900, 6000 },
{3, 17100, 17850, 18050, 18800, 12000 },
{4, 17100, 17550, 21100, 21550, 19500 },
{5, 8240, 8490, 8690, 8940, 24000 },
{6, 8300, 8400, 8750, 8850, 26500 },
{7, 25000, 25700, 26200, 26900, 27500 },
{8, 8800, 9150, 9250, 9600, 34500 },
{9, 17499, 17849, 18449, 18799, 38000 },
{10, 17100, 17700, 21100, 21700, 41500 },
{11, 14279, 14529, 14759, 15009, 47500 },
{12, 6980, 7160, 7280, 7460, 50100 },
{13, 7770, 7870, 7460, 7560, 51800 },
{14, 7880, 7980, 7580, 7680, 52800 },
{17, 7040, 7160, 7340, 7460, 57300 },
{18, 8150, 9650, 8600, 10100, 58500 },
{19, 8300, 8450, 8750, 8900, 60000 },
{20, 8320, 8620, 7910, 8210, 61500 },
{21, 14479, 14629, 14959, 15109, 64500 },
{22, 34100, 34900, 35100, 35900, 66000 },
{23, 20000, 20200, 21800, 22000, 75000 },
{24, 16126, 16605, 15250, 15590, 77000 },
{25, 18500, 19150, 19300, 19950, 80400 },
{26, 8140, 8490, 8590, 8940, 86900 },
{27, 8070, 8240, 8520, 8690, 90400 },
{28, 7030, 7580, 7580, 8130, 92100 },
{29, 0, 0, 7170, 7280, 96600 },
{30, 23050, 23250, 23500, 23600, 97700 },
{31, 45250, 34900, 46250, 35900, 98700 },
{32, 0, 0, 14520, 14960, 99200 },
{33, 19000, 19200, 19000, 19200, 360000},
{34, 20100, 20250, 20100, 20250, 362000},
{35, 18500, 19100, 18500, 19100, 363500},
{36, 19300, 19900, 19300, 19900, 369500},
{37, 19100, 19300, 19100, 19300, 375500},
{38, 25700, 26200, 25700, 26200, 377500},
{39, 18800, 19200, 18800, 19200, 382500},
{40, 23000, 24000, 23000, 24000, 386500},
{41, 24960, 26900, 24960, 26900, 396500},
{42, 34000, 36000, 34000, 36000, 415900},
{43, 36000, 38000, 36000, 38000, 435900},
{44, 7030, 8030, 7030, 8030, 455900},
{45, 14470, 14670, 14470, 14670, 465900},
{46, 51500, 59250, 51500, 59250, 467900},
{65, 19200, 20100, 21100, 22000, 655360},
{66, 17100, 18000, 21100, 22000, 664360},
{67, 0, 0, 7380, 7580, 67336 },
{68, 6980, 7280, 7530, 7830, 67536 }
};
#define BANDTABLE_SIZE (sizeof(eutra_bandtable)/sizeof(eutra_bandentry_t))
uint32_t to_earfcn_DL_aw2s(int eutra_bandP, long long int dl_CarrierFreq, uint32_t bw) {
uint32_t dl_CarrierFreq_by_100k = dl_CarrierFreq / 100000;
int i;
if (eutra_bandP > 68) { printf("eutra_band %d > 68\n", eutra_bandP); exit(-1);}
for (i = 0; i < BANDTABLE_SIZE && eutra_bandtable[i].band != eutra_bandP; i++);
printf("AW2S: band %d, index %d\n",eutra_bandP, i);
if (i >= BANDTABLE_SIZE) { printf(" i = %d , it will trigger out-of-bounds read.\n",i); exit(-1);}
if (dl_CarrierFreq_by_100k < eutra_bandtable[i].dl_min) {
printf("Band %d, bw %u : DL carrier frequency %u .1 MHz < %u\n",
eutra_bandP, bw, dl_CarrierFreq_by_100k,
eutra_bandtable[i].dl_min); exit(-1);}
if(dl_CarrierFreq_by_100k >
(eutra_bandtable[i].dl_max - bw)) {
printf("Band %d, bw %u : DL carrier frequency %u .1MHz > %d\n",
eutra_bandP, bw, dl_CarrierFreq_by_100k,
eutra_bandtable[i].dl_max - bw); exit(-1); }
printf("AW2S: dl_CarrierFreq_by_100k %d, dl_min %d\n",dl_CarrierFreq_by_100k,eutra_bandtable[i].dl_min);
return (dl_CarrierFreq_by_100k - eutra_bandtable[i].dl_min +
(eutra_bandtable[i].N_OFFs_DL / 10));
}
uint32_t to_earfcn_UL_aw2s(int eutra_bandP, long long int ul_CarrierFreq, uint32_t bw) {
uint32_t ul_CarrierFreq_by_100k = ul_CarrierFreq / 100000;
int i;
if(eutra_bandP >= 69) {
printf("eutra_band %d > 68\n", eutra_bandP);
exit(-1);
}
for (i = 0; i < BANDTABLE_SIZE && eutra_bandtable[i].band != eutra_bandP; i++);
if(i >= BANDTABLE_SIZE) {printf("i = %d , it will trigger out-of-bounds read.\n",i); exit(-1);}
if(ul_CarrierFreq_by_100k < eutra_bandtable[i].ul_min) {
printf("Band %d, bw %u : UL carrier frequency %u Hz < %u\n",
eutra_bandP, bw, ul_CarrierFreq_by_100k,
eutra_bandtable[i].ul_min);
exit(-1);
}
if(ul_CarrierFreq_by_100k > (eutra_bandtable[i].ul_max - bw)) {
printf("Band %d, bw %u : UL carrier frequency %u Hz > %d\n",
eutra_bandP, bw, ul_CarrierFreq_by_100k,
eutra_bandtable[i].ul_max - bw);
exit(-1);
}
return (ul_CarrierFreq_by_100k - eutra_bandtable[i].ul_min +
((eutra_bandtable[i].N_OFFs_DL + 180000) / 10));
}
int get_mac_addr(const char *iface,unsigned char *mac)
{
int fd;
struct ifreq ifr;
int ret=0;
memset(&ifr, 0, sizeof(ifr));
fd = socket(AF_INET, SOCK_DGRAM, 0);
ifr.ifr_addr.sa_family = AF_INET;
strncpy(ifr.ifr_name , iface , IFNAMSIZ-1);
if (0 == ioctl(fd, SIOCGIFHWADDR, &ifr)) memcpy((void*)mac,(void *)ifr.ifr_hwaddr.sa_data,6);
else {
printf("No MAC address!\n");
ret = -1;
}
printf("%s : %2x:%2x:%2x:%2x:%2x:%2x\n",iface,mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]);
close(fd);
return(ret);
}
void cb(void * userData, ORI_IndicationType_e type, ORI_IndicationValue_u value)
{
printf("============> Got indication %s\n", ORI_IndicationType_Print(type));
if(type == ORI_IndicationType_ObjectStateChange)
{
ORI_Object_s * obj = value.objectStateChange.object;
printf("State change for %s:%d -> %s : %s\n", ORI_ObjectType_Print(obj->typeRef.type), obj->instanceNumber,
ORI_StateType_Print(value.objectStateChange.stateType),
value.objectStateChange.stateType == ORI_StateType_AST ? ORI_AST_Print(obj->ast) : ORI_FST_Print(obj->fst));
}
else if(type == ORI_IndicationType_FaultChange)
{
ORI_Object_s * obj = value.faultChange.object;
ORI_Fault_s * fault = value.faultChange.fault;
printf("Fault change for %s:%d -> %s : %s\n", ORI_ObjectType_Print(obj->typeRef.type), obj->instanceNumber,
ORI_FaultType_Print(value.faultChange.faultType),
ORI_FaultState_Print(fault->state));
if(fault->state == ORI_FaultState_Active)
{
printf("\t Fault severity: %s\n", ORI_FaultSeverity_Print(fault->severity));
printf("\t Timestamp: %s\n", fault->timestamp);
printf("\t Description: %s\n", fault->desc);
}
}
printf("<============\n");
}
int aw2s_oricleanup(openair0_device *device) {
ORI_s * ori = (ORI_s*)device->thirdparty_priv;
ORI_Disconnect(ori);
ORI_Free(ori);
return(0);
}
int aw2s_startstreaming(openair0_device *device) {
ORI_s * ori = (ORI_s*)device->thirdparty_priv;
ORI_Result_e result;
ORI_Result_e RE_result;
openair0_config_t *openair0_cfg = device->openair0_cfg;
ORI_Object_s *tx0= ORI_FindObject(ori, openair0_cfg->duplex_mode == duplex_mode_FDD ? ORI_ObjectType_TxEUtraFDD :ORI_ObjectType_TxEUtraTDD, 0, NULL);
ORI_Object_s *tx1= (openair0_cfg->tx_num_channels > 1) ? ORI_FindObject(ori, openair0_cfg->duplex_mode == duplex_mode_FDD ?ORI_ObjectType_TxEUtraFDD : ORI_ObjectType_TxEUtraTDD, 1, NULL) : NULL;
ORI_Object_s *rx0= ORI_FindObject(ori, openair0_cfg->duplex_mode == duplex_mode_FDD ?ORI_ObjectType_RxEUtraFDD : ORI_ObjectType_RxEUtraTDD, 0, NULL);
ORI_Object_s *rx1= (openair0_cfg->rx_num_channels > 1) ? ORI_FindObject(ori, openair0_cfg->duplex_mode == duplex_mode_FDD ?ORI_ObjectType_RxEUtraFDD : ORI_ObjectType_RxEUtraTDD, 1, NULL) : NULL;
ORI_Object_s *link= ORI_FindObject(ori, ORI_ObjectType_ORILink, 0, NULL);
if (tx0 == NULL || (tx1 == NULL && openair0_cfg->tx_num_channels > 1) || rx0 == NULL || (rx1 == NULL && openair0_cfg->rx_num_channels > 1) || link == NULL) return (-1);
/*******************************************************************
* UNLOCK Link
*******************************************************************/
result = ORI_ObjectStateModification(ori, link, ORI_AST_Unlocked, &RE_result);
if(result != ORI_Result_SUCCESS)
{
printf("ORI_ObjectStateModify failed with error: %s\n", ORI_Result_Print(result));
aw2s_oricleanup(device);
return -1;
}
/*******************************************************************
* UNLOCK TX0
*******************************************************************/
/* Put Tx0 into service */
result = ORI_ObjectStateModification(ori, tx0, ORI_AST_Unlocked, &RE_result);
if(result != ORI_Result_SUCCESS)
{
printf("ORI_ObjectStateModify failed with error: %s\n", ORI_Result_Print(result));
aw2s_oricleanup(device);
return -1;
}
printf("ORI_ObjectStateModify: %s\n", ORI_Result_Print(RE_result));
/*******************************************************************
* UNLOCK TX1
*******************************************************************/
if (tx1) {
printf("\n\n\n========================================================\n");
/* Put Tx1 into service */
result = ORI_ObjectStateModification(ori, tx1, ORI_AST_Unlocked, &RE_result);
if(result != ORI_Result_SUCCESS)
{
printf("ORI_ObjectStateModify failed with error: %s\n", ORI_Result_Print(result));
aw2s_oricleanup(device);
return -1;
}
printf("ORI_ObjectStateModify: %s\n", ORI_Result_Print(RE_result));
}
/*******************************************************************
* UNLOCK RX0
*******************************************************************/
printf("\n\n\n========================================================\n");
/* Put Rx0 into service */
result = ORI_ObjectStateModification(ori, rx0, ORI_AST_Unlocked, &RE_result);
if(result != ORI_Result_SUCCESS)
{
printf("ORI_ObjectStateModify failed with error: %s\n", ORI_Result_Print(result));
aw2s_oricleanup(device);
return -1;
}
printf("ORI_ObjectStateModify: %s\n", ORI_Result_Print(RE_result));
/*******************************************************************
* UNLOCK RX1
*******************************************************************/
if (rx1) {
printf("\n\n\n========================================================\n");
/* Put Rx1 into service */
result = ORI_ObjectStateModification(ori, rx1, ORI_AST_Unlocked, &RE_result);
if(result != ORI_Result_SUCCESS)
{
printf("ORI_ObjectStateModify failed with error: %s\n", ORI_Result_Print(result));
aw2s_oricleanup(device);
return -1;
}
printf("ORI_ObjectStateModify: %s\n", ORI_Result_Print(RE_result));
}
while (rx0->fst != ORI_FST_Operational ||
(openair0_cfg->rx_num_channels > 1 && rx1->fst != ORI_FST_Operational) ||
tx0->fst != ORI_FST_Operational ||
(openair0_cfg->tx_num_channels > 1 && tx1->fst != ORI_FST_Operational))
{}
// test RX interface
uint64_t TS;
char temp_rx[1024] __attribute__((aligned(32)));
int aid,r0=0,r1=(openair0_cfg->rx_num_channels > 1) ? 0 : 1;
int i;
int Npackets=1024000;
for (i=0;i<Npackets;i++) {
device->trx_read_func2(device,
(openair0_timestamp*)&TS,
(void*)temp_rx,
256,
&aid);
if (aid == 0) r0=1;
if (aid == 1) r1=1;
}
if (r0==1 && r1==1) printf("Streaming started, returning to OAI\n");
else {
printf("Didn't get anything from one antenna port after %d packets %d,%d\n",Npackets,r0,r1);
return(-1);
}
return(0);
}
int aw2s_oriinit(openair0_device *device) {
ORI_s * ori;
ORI_Result_e result;
ORI_Result_e RE_result;
ORI_Object_s * objects[100];
uint32_t numObjects;
uint32_t i;
eth_params_t *eth_params = device->eth_params;
openair0_config_t *openair0_cfg = device->openair0_cfg;
/*******************************************************************
* CREATION AND CONNECTION
*******************************************************************/
printf("Initializing the ORI control interface\n");
/* Create context */
ori = ORI_Create();
if(!ori)
{
printf("Failed to create ORI context\n");
return -1;
}
device->thirdparty_priv = (void *)ori;
ori->userData = (void *)ori;
ori->indicationCallback = cb;
/* Connect... */
printf("Trying to connect to AW2S device on %s : %d\n",eth_params->remote_addr, eth_params->remote_portc);
result = ORI_Connect(ori, eth_params->remote_addr, eth_params->remote_portc, 3000, 0);
if(result != ORI_Result_SUCCESS)
{
printf("ORI_Connect failed with error: %s\n", ORI_Result_Print(result));
aw2s_oricleanup(device);
return -1;
}
/* First health check */
result = ORI_HealthCheck(ori, 6000, &RE_result);
if(result != ORI_Result_SUCCESS)
{
printf("ORI_HealthCheck failed with error: %s\n", ORI_Result_Print(result));
aw2s_oricleanup(device);
return -1;
}
printf("ORI_HealthCheck: %s\n", ORI_Result_Print(RE_result));
/* Set RE time */
result = ORI_SetTime(ori, &RE_result);
if(result != ORI_Result_SUCCESS)
{
printf("ORI_SetTime failed with error: %s\n", ORI_Result_Print(result));
aw2s_oricleanup(device);
return -1;
}
printf("ORI_SetTime: %s\n", ORI_Result_Print(RE_result));
/*******************************************************************
* SOFTWARE PARAMETERS ALIGNMENT
*******************************************************************/
/* Report all current objects parameters */
result = ORI_ObjectParamReport(ori, NULL, 0, ORI_ObjectParam_All, &RE_result);
if(result != ORI_Result_SUCCESS)
{
printf("ORI_ObjectParamReport failed with error: %s\n", ORI_Result_Print(result));
aw2s_oricleanup(device);
return -1;
}
printf("ORI_ObjectParamReport: %s\n", ORI_Result_Print(RE_result));
/*******************************************************************
* TX PATHS CREATION
*******************************************************************/
/* Prepare parameters */
ORI_ObjectTypeRef_s txTypeRef = { NULL, openair0_cfg->duplex_mode == duplex_mode_FDD ? ORI_ObjectType_TxEUtraFDD : ORI_ObjectType_TxEUtraTDD};
ORI_ObjectParams_u txParams;
ORI_ObjectParam_e txParamList[9];
ORI_Result_e txParamResult[9];
int num_txparams;
if (openair0_cfg->duplex_mode == duplex_mode_FDD) {
txParamList[0] = ORI_ObjectParam_SigPath_antPort;
txParamList[1] = ORI_ObjectParam_SigPath_axcW;
txParamList[2] = ORI_ObjectParam_SigPath_axcB;
txParamList[3] = ORI_ObjectParam_SigPath_chanBW;
txParamList[4] = ORI_ObjectParam_SigPath_earfcn;
txParamList[5] = ORI_ObjectParam_TxSigPath_maxTxPwr;
num_txparams = 6;
}
else {
txParamList[0] = ORI_ObjectParam_SigPath_antPort;
txParamList[1] = ORI_ObjectParam_SigPath_axcW;
txParamList[2] = ORI_ObjectParam_SigPath_axcB;
txParamList[3] = ORI_ObjectParam_SigPath_chanBW;
txParamList[4] = ORI_ObjectParam_SigPath_earfcn;
txParamList[5] = ORI_ObjectParam_TxSigPath_maxTxPwr;
txParamList[6] = ORI_ObjectParam_SigPath_tddULDLConfig;
txParamList[7] = ORI_ObjectParam_SigPath_tddSpecialSFConfig;
txParamList[8] = ORI_ObjectParam_TxSigPath_tddCPLengthDL;
num_txparams = 9;
}
/* Create tx0 */
ORI_Object_s * tx0;
printf("AW2S: duplex_mode %d, tx_bw %f, rx_bw %f\n",openair0_cfg->duplex_mode,openair0_cfg->tx_bw,openair0_cfg->rx_bw);
if (openair0_cfg->duplex_mode == duplex_mode_FDD) {
txParams.TxEUtraFDD.antPort = ORI_FindObject(ori, ORI_ObjectType_AntennaPort, 0, NULL);
txParams.TxEUtraFDD.axcW = 1;
txParams.TxEUtraFDD.axcB = 0;
txParams.TxEUtraFDD.chanBW = openair0_cfg->tx_bw/100e3;
txParams.TxEUtraFDD.earfcn = 3350;
txParams.TxEUtraFDD.maxTxPwr = -100;
}
else if (openair0_cfg->duplex_mode == duplex_mode_TDD) {
txParams.TxEUtraTDD.antPort = ORI_FindObject(ori, ORI_ObjectType_AntennaPort, 0, NULL);
txParams.TxEUtraTDD.axcW = 1;
txParams.TxEUtraTDD.axcB = 0;
txParams.TxEUtraTDD.chanBW = openair0_cfg->tx_bw/100e3;
txParams.TxEUtraTDD.earfcn = to_earfcn_DL_aw2s(38,(long long int)openair0_cfg->tx_freq[0],txParams.TxEUtraTDD.chanBW);
txParams.TxEUtraTDD.maxTxPwr = 430-((int)openair0_cfg->tx_gain[0]*10);
txParams.TxEUtraTDD.tddULDLConfig = 1;
txParams.TxEUtraTDD.tddSpecialSFConfig = 0;
txParams.TxEUtraTDD.tddCPLengthDL = ORI_tddCPLength_Normal;
printf("AW2S: Configuring for TDD, EARFCN %u, Power %d, BW %d\n",
txParams.TxEUtraTDD.earfcn,txParams.TxEUtraTDD.maxTxPwr,txParams.TxEUtraTDD.chanBW);
}
else {
aw2s_oricleanup(device);
return -1;
}
result = ORI_ObjectCreation(ori, txTypeRef, txParams, txParamList, num_txparams, txParamResult, &tx0, &RE_result);
if(RE_result != ORI_Result_SUCCESS)
{
printf("ORI_ObjectCreation (txParams0.TxEUtraFDD/TDD) failed with error: %s (%s,%s,%s,%s,%s,%s,%s,%s,%s\n", ORI_Result_Print(result),
ORI_Result_Print(txParamResult[0]),
ORI_Result_Print(txParamResult[1]),
ORI_Result_Print(txParamResult[2]),
ORI_Result_Print(txParamResult[3]),
ORI_Result_Print(txParamResult[4]),
ORI_Result_Print(txParamResult[5]),
ORI_Result_Print(txParamResult[6]),
ORI_Result_Print(txParamResult[7]),
ORI_Result_Print(txParamResult[8]));
aw2s_oricleanup(device);
return -1;
}
printf("ORI_ObjectCreation (txParams0.TxEUtraFDD/TDD): %s\n", ORI_Result_Print(RE_result));
/* Create tx1 */
if (openair0_cfg->tx_num_channels > 1) {
ORI_Object_s * tx1;
if (openair0_cfg->duplex_mode ==duplex_mode_FDD) txParams.TxEUtraFDD.antPort = ORI_FindObject(ori, ORI_ObjectType_AntennaPort, 1, NULL);
else txParams.TxEUtraTDD.antPort = ORI_FindObject(ori, ORI_ObjectType_AntennaPort, 1, NULL);
result = ORI_ObjectCreation(ori, txTypeRef, txParams, txParamList, num_txparams, txParamResult, &tx1, &RE_result);
if(RE_result != ORI_Result_SUCCESS)
{
printf("ORI_ObjectCreation (txParams1.TxEUtraFDD/TDD) failed with error: %s\n", ORI_Result_Print(result));
aw2s_oricleanup(device);
return -1;
}
printf("ORI_ObjectCreation (txParams1.TxEUtraFDD/TDD): %s\n", ORI_Result_Print(RE_result));
}
/*******************************************************************
* RX PATHS CREATION
*******************************************************************/
/* Prepare parameters */
ORI_ObjectTypeRef_s rxTypeRef = { NULL, openair0_cfg->duplex_mode == duplex_mode_FDD ? ORI_ObjectType_RxEUtraFDD : ORI_ObjectType_RxEUtraTDD};
ORI_ObjectParams_u rxParams,rxParams1;
ORI_ObjectParam_e rxParamList[8] = { ORI_ObjectParam_SigPath_antPort, ORI_ObjectParam_SigPath_axcW, ORI_ObjectParam_SigPath_axcB,
ORI_ObjectParam_SigPath_chanBW, ORI_ObjectParam_SigPath_earfcn };
ORI_Result_e rxParamResult[8];
int num_rxparams = 5;
if (openair0_cfg->duplex_mode == duplex_mode_TDD) {
rxParamList[5] = ORI_ObjectParam_SigPath_tddULDLConfig;
rxParamList[6] = ORI_ObjectParam_SigPath_tddSpecialSFConfig;
rxParamList[7] = ORI_ObjectParam_RxSigPath_tddCPLengthUL;
num_rxparams = 8;
}
/* Create rx0 */
ORI_Object_s * rx0;
if (openair0_cfg->duplex_mode == duplex_mode_FDD) {
rxParams.RxEUtraFDD.antPort = ORI_FindObject(ori, ORI_ObjectType_AntennaPort, 0, NULL);
rxParams.RxEUtraFDD.axcW = 1;
rxParams.RxEUtraFDD.axcB = 0;
rxParams.RxEUtraFDD.chanBW = 200;
rxParams.RxEUtraFDD.earfcn = 21350;
result = ORI_ObjectCreation(ori, rxTypeRef, rxParams, rxParamList, num_rxparams, rxParamResult, &rx0, &RE_result);
}
else {
rxParams.RxEUtraTDD.antPort = ORI_FindObject(ori, ORI_ObjectType_AntennaPort, 0, NULL);
rxParams.RxEUtraTDD.axcW = 1;
rxParams.RxEUtraTDD.axcB = 0;
rxParams.RxEUtraTDD.chanBW = txParams.TxEUtraTDD.chanBW;
rxParams.RxEUtraTDD.earfcn = txParams.TxEUtraTDD.earfcn;
rxParams.RxEUtraTDD.tddULDLConfig = 1;
rxParams.RxEUtraTDD.tddSpecialSFConfig = 1;
rxParams.RxEUtraTDD.tddCPLengthUL = ORI_tddCPLength_Normal;
printf("AW2S: Creating RX0 for EARFCN %d\n",rxParams.RxEUtraTDD.earfcn);
result = ORI_ObjectCreation(ori, rxTypeRef, rxParams, rxParamList, num_rxparams, rxParamResult, &rx0, &RE_result);
}
if(result != ORI_Result_SUCCESS)
{
printf("ORI_ObjectCreation (rxParams0.RxEUtraFDD/TDD) failed with error: %s\n", ORI_Result_Print(result));
aw2s_oricleanup(device);
return -1;
}
printf("ORI_ObjectCreation (rxParams0.RxEUtraFDD/TDD): %s\n", ORI_Result_Print(RE_result));
if (openair0_cfg->rx_num_channels > 1) {
/* Create rx1 */
ORI_Object_s * rx1;
memcpy((void*)&rxParams1,(void*)&rxParams,sizeof(rxParams));
if (openair0_cfg->duplex_mode == duplex_mode_FDD) rxParams1.RxEUtraFDD.antPort = ORI_FindObject(ori, ORI_ObjectType_AntennaPort, 1, NULL);
else rxParams1.RxEUtraTDD.antPort = ORI_FindObject(ori, ORI_ObjectType_AntennaPort, 1, NULL);
result = ORI_ObjectCreation(ori, rxTypeRef, rxParams1, rxParamList, num_rxparams, rxParamResult, &rx1, &RE_result);
if(result != ORI_Result_SUCCESS)
{
printf("ORI_ObjectCreation (rxParams1.RxEUtraFDD/TDD) failed with error: %s\n", ORI_Result_Print(result));
aw2s_oricleanup(device);
return -1;
}
printf("ORI_ObjectCreation (rxParams1.RxEUtraFDD/TDD): %s\n", ORI_Result_Print(RE_result));
}
/* Create link */
ORI_ObjectParams_u linkParams;
ORI_ObjectParam_e linkParamList[3] = {ORI_ObjectParam_ORILink_AWS_remoteMAC, ORI_ObjectParam_ORILink_AWS_remoteIP,ORI_ObjectParam_ORILink_AWS_remoteUdpPort};
ORI_Result_e linkParamResult[3];
ORI_Object_s *link= ORI_FindObject(ori, ORI_ObjectType_ORILink, 0, NULL);
linkParams.ORILink.AWS_remoteUdpPort = eth_params->my_portd;
if (get_mac_addr(eth_params->local_if_name,linkParams.ORILink.AWS_remoteMAC) < 0) return(-1);
inet_pton(AF_INET,eth_params->my_addr,(struct in_addr*)linkParams.ORILink.AWS_remoteIP);
result = ORI_ObjectParamModify(ori,link,linkParams,linkParamList,3,linkParamResult,&RE_result);
if(result != ORI_Result_SUCCESS)
{
printf("ORI_ObjectParamModify (linkParams) failed with error: %s\n", ORI_Result_Print(result));
aw2s_oricleanup(device);
return -1;
}
result = ORI_ObjectStateModification(ori, link, ORI_AST_Locked, &RE_result);
if(result != ORI_Result_SUCCESS)
{
printf("ORI_ObjectStateModify failed with error: %s\n", ORI_Result_Print(result));
aw2s_oricleanup(device);
return -1;
}
printf("ORI_ObjectParamModify (linkParams): %s (%d,%d,%d)\n", ORI_Result_Print(RE_result),linkParamResult[0],linkParamResult[1],linkParamResult[2]);
/*******************************************************************
* FULL OBJECT PARAMETERS UPDATE
*******************************************************************/
printf("\n\n\n========================================================\n");
result = ORI_ObjectParamReport(ori, NULL, 0, ORI_ObjectParam_All, &RE_result);
if(result != ORI_Result_SUCCESS)
{
printf("ORI_ObjectParamReport failed with error: %s\n", ORI_Result_Print(result));
aw2s_oricleanup(device);
return -1;
}
printf("ORI_ObjectParamReport: %s\n", ORI_Result_Print(RE_result));
/*******************************************************************
* FULL OBJECT STATES UPDATE
*******************************************************************/
printf("\n\n\n========================================================\n");
result = ORI_ObjectStateReport(ori, NULL, 0, ORI_StateType_All, ORI_EventDrivenReport_True, &RE_result);
if(result != ORI_Result_SUCCESS)
{
printf("ORI_ObjectStateReport failed with error: %s\n", ORI_Result_Print(result));
aw2s_oricleanup(device);
return -1;
}
printf("ORI_ObjectStateReport: %s\n", ORI_Result_Print(RE_result));
/* Print reported states for all objects (some objects have non-applicable states though) */
numObjects = ORI_GetAllObjects(ori, objects, 100, NULL);
for(i=0; i<numObjects; i++)
printf("%s:%d -> %s / %s\n", ORI_ObjectType_Print(objects[i]->typeRef.type), objects[i]->instanceNumber, ORI_AST_Print(objects[i]->ast), ORI_FST_Print(objects[i]->fst));
/*******************************************************************
* FULL OBJECT FAULTS UPDATE
*******************************************************************/
printf("\n\n\n========================================================\n");
result = ORI_ObjectFaultReport(ori, NULL, 0, ORI_EventDrivenReport_True, &RE_result);
if(result != ORI_Result_SUCCESS)
{
printf("ORI_ObjectFaultReport failed with error: %s\n", ORI_Result_Print(result));
aw2s_oricleanup(device);
return -1;
}
printf("ORI_ObjectFaultReport: %s\n", ORI_Result_Print(RE_result));
/*******************************************************************
* PRINT STATES
*******************************************************************/
printf("\n\n\n========================================================\n");
/* Due to event driven reporting set to "true", the states modifications of the objects should be reflected back into the model. Print states for all objects (some objects have non-applicable states though) */
numObjects = ORI_GetAllObjects(ori, objects, 100, NULL);
for(i=0; i<numObjects; i++)
printf("%s:%d -> %s / %s\n", ORI_ObjectType_Print(objects[i]->typeRef.type), objects[i]->instanceNumber, ORI_AST_Print(objects[i]->ast), ORI_FST_Print(objects[i]->fst));
return 0;
}
int transport_init(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t * eth_params ) {
device->thirdparty_init = aw2s_oriinit;
device->thirdparty_cleanup = aw2s_oricleanup;
device->thirdparty_startstreaming = aw2s_startstreaming;
return(0);
}
File diff suppressed because it is too large Load Diff
+8 -8
View File
@@ -1300,13 +1300,13 @@ void fill_rf_config(RU_t *ru,
if (fp->threequarter_fs) {
cfg->sample_rate=23.04e6;
cfg->samples_per_frame = 230400;
cfg->tx_bw = 10e6;
cfg->rx_bw = 10e6;
cfg->tx_bw = 20e6;
cfg->rx_bw = 20e6;
} else {
cfg->sample_rate=30.72e6;
cfg->samples_per_frame = 307200;
cfg->tx_bw = 10e6;
cfg->rx_bw = 10e6;
cfg->tx_bw = 20e6;
cfg->rx_bw = 20e6;
}
} else if(ru->numerology == 1) {
cfg->sample_rate=61.44e6;
@@ -1328,13 +1328,13 @@ void fill_rf_config(RU_t *ru,
} else if(fp->N_RB_DL == 50) {
cfg->sample_rate=15.36e6;
cfg->samples_per_frame = 153600;
cfg->tx_bw = 5e6;
cfg->rx_bw = 5e6;
cfg->tx_bw = 10e6;
cfg->rx_bw = 10e6;
} else if (fp->N_RB_DL == 25) {
cfg->sample_rate=7.68e6;
cfg->samples_per_frame = 76800;
cfg->tx_bw = 2.5e6;
cfg->rx_bw = 2.5e6;
cfg->tx_bw = 5e6;
cfg->rx_bw = 5e6;
} else if (fp->N_RB_DL == 6) {
cfg->sample_rate=1.92e6;
cfg->samples_per_frame = 19200;