[0-9]+)', str(line))
if res1 is not None and res2 is not None:
requested_option = int(res1.group('requested_option'))
applied_option = int(res2.group('applied_option'))
if requested_option == applied_option:
- self.htmleNBFailureMsg += ' Command line option(s) correctly applied ' + self.rruOptions + '\n\n'
+ self.htmleNBFailureMsg += ' Command line option(s) correctly applied ' + self.eNBOptions[int(self.eNB_instance)] + '\n\n'
else:
- self.htmleNBFailureMsg += ' Command line option(s) NOT applied ' + self.rruOptions + '\n\n'
+ self.htmleNBFailureMsg += ' Command line option(s) NOT applied ' + self.eNBOptions[int(self.eNB_instance)] + '\n\n'
result = re.search('Exiting OAI softmodem', str(line))
if result is not None:
exitSignalReceived = True
@@ -2562,6 +2666,17 @@ class SSHConnection():
if foundAssertion and (msgLine < 3):
msgLine += 1
msgAssertion += str(line)
+ result = re.search('Setting function for RU', str(line))
+ if result is not None:
+ isRRU = True
+ if isRRU:
+ result = re.search('RU 0 is_slave=yes', str(line))
+ if result is not None:
+ isSlave = True
+ if isSlave:
+ result = re.search('Received RRU_frame_resynch command', str(line))
+ if result is not None:
+ slaveReceivesFrameResyncCmd = True
result = re.search('LTE_RRCConnectionSetupComplete from UE', str(line))
if result is not None:
rrcSetupComplete += 1
@@ -2655,6 +2770,17 @@ class SSHConnection():
rachMsg = 'eNB cancelled ' + str(rachCanceledProcedure) + ' RA procedure(s)'
logging.debug('\u001B[1;30;43m ' + rachMsg + ' \u001B[0m')
self.htmleNBFailureMsg += rachMsg + '\n'
+ if isRRU:
+ if isSlave:
+ if slaveReceivesFrameResyncCmd:
+ rruMsg = 'Slave RRU received the RRU_frame_resynch command from RAU'
+ logging.debug('\u001B[1;30;43m ' + rruMsg + ' \u001B[0m')
+ self.htmleNBFailureMsg += rruMsg + '\n'
+ else:
+ rruMsg = 'Slave RRU DID NOT receive the RRU_frame_resynch command from RAU'
+ logging.debug('\u001B[1;37;41m ' + rruMsg + ' \u001B[0m')
+ self.htmleNBFailureMsg += rruMsg + '\n'
+ return ENB_PROCESS_SLAVE_RRU_NOT_SYNCED
if foundSegFault:
logging.debug('\u001B[1;37;41m eNB ended with a Segmentation Fault! \u001B[0m')
return ENB_PROCESS_SEG_FAULT
@@ -2842,18 +2968,36 @@ class SSHConnection():
return 0
def TerminateeNB(self):
- self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword)
- self.command('cd ' + self.eNBSourceCodePath + '/cmake_targets', '\$', 5)
+ if self.eNB_serverId == '0':
+ lIpAddr = self.eNBIPAddress
+ lUserName = self.eNBUserName
+ lPassWord = self.eNBPassword
+ lSourcePath = self.eNBSourceCodePath
+ elif self.eNB_serverId == '1':
+ lIpAddr = self.eNB1IPAddress
+ lUserName = self.eNB1UserName
+ lPassWord = self.eNB1Password
+ lSourcePath = self.eNB1SourceCodePath
+ elif self.eNB_serverId == '2':
+ lIpAddr = self.eNB2IPAddress
+ lUserName = self.eNB2UserName
+ lPassWord = self.eNB2Password
+ lSourcePath = self.eNB2SourceCodePath
+ if lIpAddr == '' or lUserName == '' or lPassWord == '' or lSourcePath == '':
+ Usage()
+ sys.exit('Insufficient Parameter')
+ self.open(lIpAddr, lUserName, lPassWord)
+ self.command('cd ' + lSourcePath + '/cmake_targets', '\$', 5)
self.command('stdbuf -o0 ps -aux | grep --color=never softmodem | grep -v grep', '\$', 5)
result = re.search('lte-softmodem', str(self.ssh.before))
if result is not None:
- self.command('echo ' + self.eNBPassword + ' | sudo -S daemon --name=enb' + str(self.eNB_instance) + '_daemon --stop', '\$', 5)
- self.command('echo ' + self.eNBPassword + ' | sudo -S killall --signal SIGINT lte-softmodem || true', '\$', 5)
+ self.command('echo ' + lPassWord + ' | sudo -S daemon --name=enb' + str(self.eNB_instance) + '_daemon --stop', '\$', 5)
+ self.command('echo ' + lPassWord + ' | sudo -S killall --signal SIGINT lte-softmodem || true', '\$', 5)
time.sleep(5)
self.command('stdbuf -o0 ps -aux | grep --color=never softmodem | grep -v grep', '\$', 5)
result = re.search('lte-softmodem', str(self.ssh.before))
if result is not None:
- self.command('echo ' + self.eNBPassword + ' | sudo -S killall --signal SIGKILL lte-softmodem || true', '\$', 5)
+ self.command('echo ' + lPassWord + ' | sudo -S killall --signal SIGKILL lte-softmodem || true', '\$', 5)
time.sleep(2)
self.command('rm -f my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5)
self.close()
@@ -2867,44 +3011,40 @@ class SSHConnection():
if self.EPC_PcapFileName != '':
self.command('echo ' + self.EPCPassword + ' | sudo -S chmod 666 /tmp/' + self.EPC_PcapFileName, '\$', 5)
self.copyin(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, '/tmp/' + self.EPC_PcapFileName, '.')
- self.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, self.EPC_PcapFileName, self.eNBSourceCodePath + '/cmake_targets/.')
+ self.copyout(lIpAddr, lUserName, lPassWord, self.EPC_PcapFileName, lSourcePath + '/cmake_targets/.')
self.close()
logging.debug('\u001B[1m Replaying RAW record file\u001B[0m')
- self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword)
- self.command('cd ' + self.eNBSourceCodePath + '/common/utils/T/tracer/', '\$', 5)
- raw_record_file = self.eNBLogFile.replace('.log', '_record.raw')
- replay_log_file = self.eNBLogFile.replace('.log', '_replay.log')
- extracted_txt_file = self.eNBLogFile.replace('.log', '_extracted_messages.txt')
- extracted_log_file = self.eNBLogFile.replace('.log', '_extracted_messages.log')
- self.command('./extract_config -i ' + self.eNBSourceCodePath + '/cmake_targets/' + raw_record_file + ' > ' + self.eNBSourceCodePath + '/cmake_targets/' + extracted_txt_file, '\$', 5)
- self.command('echo $USER; nohup ./replay -i ' + self.eNBSourceCodePath + '/cmake_targets/' + raw_record_file + ' > ' + self.eNBSourceCodePath + '/cmake_targets/' + replay_log_file + ' 2>&1 &', self.eNBUserName, 5)
- self.command('./textlog -d ' + self.eNBSourceCodePath + '/cmake_targets/' + extracted_txt_file + ' -no-gui -ON -full > ' + self.eNBSourceCodePath + '/cmake_targets/' + extracted_log_file, '\$', 5)
+ self.open(lIpAddr, lUserName, lPassWord)
+ self.command('cd ' + lSourcePath + '/common/utils/T/tracer/', '\$', 5)
+ enbLogFile = self.eNBLogFiles[int(self.eNB_instance)]
+ raw_record_file = enbLogFile.replace('.log', '_record.raw')
+ replay_log_file = enbLogFile.replace('.log', '_replay.log')
+ extracted_txt_file = enbLogFile.replace('.log', '_extracted_messages.txt')
+ extracted_log_file = enbLogFile.replace('.log', '_extracted_messages.log')
+ self.command('./extract_config -i ' + lSourcePath + '/cmake_targets/' + raw_record_file + ' > ' + lSourcePath + '/cmake_targets/' + extracted_txt_file, '\$', 5)
+ self.command('echo $USER; nohup ./replay -i ' + lSourcePath + '/cmake_targets/' + raw_record_file + ' > ' + lSourcePath + '/cmake_targets/' + replay_log_file + ' 2>&1 &', lUserName, 5)
+ self.command('./textlog -d ' + lSourcePath + '/cmake_targets/' + extracted_txt_file + ' -no-gui -ON -full > ' + lSourcePath + '/cmake_targets/' + extracted_log_file, '\$', 5)
self.close()
- self.copyin(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, self.eNBSourceCodePath + '/cmake_targets/' + extracted_log_file, '.')
+ self.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/' + extracted_log_file, '.')
logging.debug('\u001B[1m Analyzing eNB replay logfile \u001B[0m')
logStatus = self.AnalyzeLogFile_eNB(extracted_log_file)
self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK)
- self.eNBLogFile = ''
+ self.eNBLogFiles[int(self.eNB_instance)] = ''
else:
- result = re.search('enb_', str(self.eNBLogFile))
analyzeFile = False
- if result is not None:
+ if self.eNBLogFiles[int(self.eNB_instance)] != '':
analyzeFile = True
- fileToAnalyze = str(self.eNBLogFile)
- self.eNBLogFile = ''
- else:
- result = re.search('enb_', str(self.rruLogFile))
- if result is not None:
- analyzeFile = True
- fileToAnalyze = str(self.rruLogFile)
- self.rruLogFile = ''
+ fileToAnalyze = self.eNBLogFiles[int(self.eNB_instance)]
+ self.eNBLogFiles[int(self.eNB_instance)] = ''
if analyzeFile:
- copyin_res = self.copyin(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, self.eNBSourceCodePath + '/cmake_targets/' + fileToAnalyze, '.')
+ copyin_res = self.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/' + fileToAnalyze, '.')
if (copyin_res == -1):
logging.debug('\u001B[1;37;41m Could not copy eNB logfile to analyze it! \u001B[0m')
self.htmleNBFailureMsg = 'Could not copy eNB logfile to analyze it!'
self.CreateHtmlTestRow('N/A', 'KO', ENB_PROCESS_NOLOGFILE_TO_ANALYZE)
return
+ if self.eNB_serverId != '0':
+ self.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, './' + fileToAnalyze, self.eNBSourceCodePath + '/cmake_targets/')
logging.debug('\u001B[1m Analyzing eNB logfile \u001B[0m ' + fileToAnalyze)
logStatus = self.AnalyzeLogFile_eNB(fileToAnalyze)
if (logStatus < 0):
@@ -3276,46 +3416,46 @@ class SSHConnection():
self.htmlFile.write(' \n')
self.htmlFile.write(' \n')
self.htmlFile.write(' GIT Repository | \n')
- self.htmlFile.write(' ' + self.eNBRepository + ' | \n')
+ self.htmlFile.write(' ' + self.ranRepository + ' | \n')
self.htmlFile.write('
\n')
self.htmlFile.write(' \n')
self.htmlFile.write(' Job Trigger | \n')
- if (self.eNB_AllowMerge):
+ if (self.ranAllowMerge):
self.htmlFile.write(' Merge-Request | \n')
else:
self.htmlFile.write(' Push to Branch | \n')
self.htmlFile.write('
\n')
self.htmlFile.write(' \n')
- if (self.eNB_AllowMerge):
+ if (self.ranAllowMerge):
self.htmlFile.write(' Source Branch | \n')
else:
self.htmlFile.write(' Branch | \n')
- self.htmlFile.write(' ' + self.eNBBranch + ' | \n')
+ self.htmlFile.write(' ' + self.ranBranch + ' | \n')
self.htmlFile.write('
\n')
self.htmlFile.write(' \n')
- if (self.eNB_AllowMerge):
+ if (self.ranAllowMerge):
self.htmlFile.write(' Source Commit ID | \n')
else:
self.htmlFile.write(' Commit ID | \n')
- self.htmlFile.write(' ' + self.eNBCommitID + ' | \n')
+ self.htmlFile.write(' ' + self.ranCommitID + ' | \n')
self.htmlFile.write('
\n')
- if self.eNB_AllowMerge != '':
- commit_message = subprocess.check_output("git log -n1 --pretty=format:\"%s\" " + self.eNBCommitID, shell=True, universal_newlines=True)
+ if self.ranAllowMerge != '':
+ commit_message = subprocess.check_output("git log -n1 --pretty=format:\"%s\" " + self.ranCommitID, shell=True, universal_newlines=True)
commit_message = commit_message.strip()
self.htmlFile.write(' \n')
- if (self.eNB_AllowMerge):
+ if (self.ranAllowMerge):
self.htmlFile.write(' Source Commit Message | \n')
else:
self.htmlFile.write(' Commit Message | \n')
self.htmlFile.write(' ' + commit_message + ' | \n')
self.htmlFile.write('
\n')
- if (self.eNB_AllowMerge):
+ if (self.ranAllowMerge):
self.htmlFile.write(' \n')
self.htmlFile.write(' Target Branch | \n')
- if (self.eNBTargetBranch == ''):
+ if (self.ranTargetBranch == ''):
self.htmlFile.write(' develop | \n')
else:
- self.htmlFile.write(' ' + self.eNBTargetBranch + ' | \n')
+ self.htmlFile.write(' ' + self.ranTargetBranch + ' | \n')
self.htmlFile.write('
\n')
self.htmlFile.write(' \n')
@@ -3468,6 +3608,8 @@ class SSHConnection():
self.htmlFile.write(' KO - ' + machine + ' process faced Real Time issue(s) | \n')
elif (processesStatus == ENB_PROCESS_NOLOGFILE_TO_ANALYZE) or (processesStatus == OAI_UE_PROCESS_NOLOGFILE_TO_ANALYZE):
self.htmlFile.write(' OK? | \n')
+ elif (processesStatus == ENB_PROCESS_SLAVE_RRU_NOT_SYNCED):
+ self.htmlFile.write(' KO - ' + machine + ' Slave RRU could not synch | \n')
elif (processesStatus == OAI_UE_PROCESS_COULD_NOT_SYNC):
self.htmlFile.write(' KO - UE could not sync | \n')
elif (processesStatus == HSS_PROCESS_FAILED):
@@ -3563,12 +3705,12 @@ def Usage():
print(' InitiateHtml, FinalizeHtml')
print(' TerminateeNB, TerminateUE, TerminateHSS, TerminateMME, TerminateSPGW')
print(' LogCollectBuild, LogCollecteNB, LogCollectHSS, LogCollectMME, LogCollectSPGW, LogCollectPing, LogCollectIperf')
+ print(' --eNBRepository=[eNB\'s Repository URL] or --ranRepository=[OAI RAN Repository URL]')
+ print(' --eNBBranch=[eNB\'s Branch Name] or --ranBranch=[OAI RAN Repository Branch')
+ print(' --eNBCommitID=[eNB\'s Commit Number] or --ranCommitID=[OAI RAN Repository Commit SHA-1')
+ print(' --eNB_AllowMerge=[eNB\'s Allow Merge Request (with target branch)] or --ranAllowMerge=true/false')
+ print(' --eNBTargetBranch=[eNB\'s Target Branch in case of a Merge Request] or --ranTargetBranch=[Target Branch]')
print(' --eNBIPAddress=[eNB\'s IP Address]')
- print(' --eNBRepository=[eNB\'s Repository URL]')
- print(' --eNBBranch=[eNB\'s Branch Name]')
- print(' --eNBCommitID=[eNB\'s Commit Number]')
- print(' --eNB_AllowMerge=[eNB\'s Allow Merge Request (with target branch)]')
- print(' --eNBTargetBranch=[eNB\'s Target Branch in case of a Merge Request]')
print(' --eNBUserName=[eNB\'s Login User Name]')
print(' --eNBPassword=[eNB\'s Login Password]')
print(' --eNBSourceCodePath=[eNB\'s Source Code Path]')
@@ -3584,7 +3726,7 @@ def Usage():
print('------------------------------------------------------------')
def CheckClassValidity(action,id):
- if action != 'Build_eNB' and action != 'Initialize_eNB' and action != 'Terminate_eNB' and action != 'Initialize_UE' and action != 'Terminate_UE' and action != 'Attach_UE' and action != 'Detach_UE' and action != 'Build_OAI_UE' and action != 'Initialize_OAI_UE' and action != 'Terminate_OAI_UE' and action != 'DataDisable_UE' and action != 'DataEnable_UE' and action != 'CheckStatusUE' and action != 'Ping' and action != 'Iperf' and action != 'Reboot_UE' and action != 'Initialize_FlexranCtrl' and action != 'Terminate_FlexranCtrl' and action != 'Initialize_HSS' and action != 'Terminate_HSS' and action != 'Initialize_MME' and action != 'Terminate_MME' and action != 'Initialize_SPGW' and action != 'Terminate_SPGW' and action != 'Initialize_CatM_module' and action != 'Terminate_CatM_module' and action != 'Attach_CatM_module' and action != 'Detach_CatM_module' and action != 'Ping_CatM_module' and action != 'IdleSleep':
+ if action != 'Build_eNB' and action != 'WaitEndBuild_eNB' and action != 'Initialize_eNB' and action != 'Terminate_eNB' and action != 'Initialize_UE' and action != 'Terminate_UE' and action != 'Attach_UE' and action != 'Detach_UE' and action != 'Build_OAI_UE' and action != 'Initialize_OAI_UE' and action != 'Terminate_OAI_UE' and action != 'DataDisable_UE' and action != 'DataEnable_UE' and action != 'CheckStatusUE' and action != 'Ping' and action != 'Iperf' and action != 'Reboot_UE' and action != 'Initialize_FlexranCtrl' and action != 'Terminate_FlexranCtrl' and action != 'Initialize_HSS' and action != 'Terminate_HSS' and action != 'Initialize_MME' and action != 'Terminate_MME' and action != 'Initialize_SPGW' and action != 'Terminate_SPGW' and action != 'Initialize_CatM_module' and action != 'Terminate_CatM_module' and action != 'Attach_CatM_module' and action != 'Detach_CatM_module' and action != 'Ping_CatM_module' and action != 'IdleSleep':
logging.debug('ERROR: test-case ' + id + ' has wrong class ' + action)
return False
return True
@@ -3592,17 +3734,46 @@ def CheckClassValidity(action,id):
def GetParametersFromXML(action):
if action == 'Build_eNB':
SSH.Build_eNB_args = test.findtext('Build_eNB_args')
+ SSH.eNB_instance = test.findtext('eNB_instance')
+ if (SSH.eNB_instance is None):
+ SSH.eNB_instance = '0'
+ SSH.eNB_serverId = test.findtext('eNB_serverId')
+ if (SSH.eNB_serverId is None):
+ SSH.eNB_serverId = '0'
+ xmlBgBuildField = test.findtext('backgroundBuild')
+ if (xmlBgBuildField is None):
+ SSH.backgroundBuild = False
+ else:
+ if re.match('true', xmlBgBuildField, re.IGNORECASE):
+ SSH.backgroundBuild = True
+ else:
+ SSH.backgroundBuild = False
+
+ if action == 'WaitEndBuild_eNB':
+ SSH.Build_eNB_args = test.findtext('Build_eNB_args')
+ SSH.eNB_instance = test.findtext('eNB_instance')
+ if (SSH.eNB_instance is None):
+ SSH.eNB_instance = '0'
+ SSH.eNB_serverId = test.findtext('eNB_serverId')
+ if (SSH.eNB_serverId is None):
+ SSH.eNB_serverId = '0'
if action == 'Initialize_eNB':
SSH.Initialize_eNB_args = test.findtext('Initialize_eNB_args')
SSH.eNB_instance = test.findtext('eNB_instance')
if (SSH.eNB_instance is None):
SSH.eNB_instance = '0'
+ SSH.eNB_serverId = test.findtext('eNB_serverId')
+ if (SSH.eNB_serverId is None):
+ SSH.eNB_serverId = '0'
if action == 'Terminate_eNB':
SSH.eNB_instance = test.findtext('eNB_instance')
if (SSH.eNB_instance is None):
SSH.eNB_instance = '0'
+ SSH.eNB_serverId = test.findtext('eNB_serverId')
+ if (SSH.eNB_serverId is None):
+ SSH.eNB_serverId = '0'
if action == 'Attach_UE':
nbMaxUEtoAttach = test.findtext('nbMaxUEtoAttach')
@@ -3684,35 +3855,78 @@ while len(argvs) > 1:
elif re.match('^\-\-mode=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-mode=(.+)$', myArgv, re.IGNORECASE)
mode = matchReg.group(1)
- elif re.match('^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE):
- matchReg = re.match('^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE)
- SSH.eNBIPAddress = matchReg.group(1)
- elif re.match('^\-\-eNBRepository=(.+)$', myArgv, re.IGNORECASE):
- matchReg = re.match('^\-\-eNBRepository=(.+)$', myArgv, re.IGNORECASE)
- SSH.eNBRepository = matchReg.group(1)
- elif re.match('^\-\-eNB_AllowMerge=(.+)$', myArgv, re.IGNORECASE):
- matchReg = re.match('^\-\-eNB_AllowMerge=(.+)$', myArgv, re.IGNORECASE)
+ elif re.match('^\-\-eNBRepository=(.+)$|^\-\-ranRepository(.+)$', myArgv, re.IGNORECASE):
+ if re.match('^\-\-eNBRepository=(.+)$', myArgv, re.IGNORECASE):
+ matchReg = re.match('^\-\-eNBRepository=(.+)$', myArgv, re.IGNORECASE)
+ else:
+ matchReg = re.match('^\-\-ranRepository=(.+)$', myArgv, re.IGNORECASE)
+ SSH.ranRepository = matchReg.group(1)
+ elif re.match('^\-\-eNB_AllowMerge=(.+)$|^\-\-ranAllowMerge=(.+)$', myArgv, re.IGNORECASE):
+ if re.match('^\-\-eNB_AllowMerge=(.+)$', myArgv, re.IGNORECASE):
+ matchReg = re.match('^\-\-eNB_AllowMerge=(.+)$', myArgv, re.IGNORECASE)
+ else:
+ matchReg = re.match('^\-\-ranAllowMerge=(.+)$', myArgv, re.IGNORECASE)
doMerge = matchReg.group(1)
if ((doMerge == 'true') or (doMerge == 'True')):
- SSH.eNB_AllowMerge = True
- elif re.match('^\-\-eNBBranch=(.+)$', myArgv, re.IGNORECASE):
- matchReg = re.match('^\-\-eNBBranch=(.+)$', myArgv, re.IGNORECASE)
- SSH.eNBBranch = matchReg.group(1)
- elif re.match('^\-\-eNBCommitID=(.*)$', myArgv, re.IGNORECASE):
- matchReg = re.match('^\-\-eNBCommitID=(.*)$', myArgv, re.IGNORECASE)
- SSH.eNBCommitID = matchReg.group(1)
- elif re.match('^\-\-eNBTargetBranch=(.*)$', myArgv, re.IGNORECASE):
- matchReg = re.match('^\-\-eNBTargetBranch=(.*)$', myArgv, re.IGNORECASE)
- SSH.eNBTargetBranch = matchReg.group(1)
- elif re.match('^\-\-eNBUserName=(.+)$', myArgv, re.IGNORECASE):
- matchReg = re.match('^\-\-eNBUserName=(.+)$', myArgv, re.IGNORECASE)
- SSH.eNBUserName = matchReg.group(1)
- elif re.match('^\-\-eNBPassword=(.+)$', myArgv, re.IGNORECASE):
- matchReg = re.match('^\-\-eNBPassword=(.+)$', myArgv, re.IGNORECASE)
- SSH.eNBPassword = matchReg.group(1)
- elif re.match('^\-\-eNBSourceCodePath=(.+)$', myArgv, re.IGNORECASE):
- matchReg = re.match('^\-\-eNBSourceCodePath=(.+)$', myArgv, re.IGNORECASE)
- SSH.eNBSourceCodePath = matchReg.group(1)
+ SSH.ranAllowMerge = True
+ elif re.match('^\-\-eNBBranch=(.+)$|^\-\-ranBranch=(.+)$', myArgv, re.IGNORECASE):
+ if re.match('^\-\-eNBBranch=(.+)$', myArgv, re.IGNORECASE):
+ matchReg = re.match('^\-\-eNBBranch=(.+)$', myArgv, re.IGNORECASE)
+ else:
+ matchReg = re.match('^\-\-ranBranch=(.+)$', myArgv, re.IGNORECASE)
+ SSH.ranBranch = matchReg.group(1)
+ elif re.match('^\-\-eNBCommitID=(.*)$|^\-\-ranCommitID=(.*)$', myArgv, re.IGNORECASE):
+ if re.match('^\-\-eNBCommitID=(.*)$', myArgv, re.IGNORECASE):
+ matchReg = re.match('^\-\-eNBCommitID=(.*)$', myArgv, re.IGNORECASE)
+ else:
+ matchReg = re.match('^\-\-ranCommitID=(.*)$', myArgv, re.IGNORECASE)
+ SSH.ranCommitID = matchReg.group(1)
+ elif re.match('^\-\-eNBTargetBranch=(.*)$|^\-\-ranTargetBranch=(.*)$', myArgv, re.IGNORECASE):
+ if re.match('^\-\-eNBTargetBranch=(.*)$', myArgv, re.IGNORECASE):
+ matchReg = re.match('^\-\-eNBTargetBranch=(.*)$', myArgv, re.IGNORECASE)
+ else:
+ matchReg = re.match('^\-\-ranTargetBranch=(.*)$', myArgv, re.IGNORECASE)
+ SSH.ranTargetBranch = matchReg.group(1)
+ elif re.match('^\-\-eNBIPAddress=(.+)$|^\-\-eNB[1-2]IPAddress=(.+)$', myArgv, re.IGNORECASE):
+ if re.match('^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE):
+ matchReg = re.match('^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE)
+ SSH.eNBIPAddress = matchReg.group(1)
+ elif re.match('^\-\-eNB1IPAddress=(.+)$', myArgv, re.IGNORECASE):
+ matchReg = re.match('^\-\-eNB1IPAddress=(.+)$', myArgv, re.IGNORECASE)
+ SSH.eNB1IPAddress = matchReg.group(1)
+ elif re.match('^\-\-eNB2IPAddress=(.+)$', myArgv, re.IGNORECASE):
+ matchReg = re.match('^\-\-eNB2IPAddress=(.+)$', myArgv, re.IGNORECASE)
+ SSH.eNB2IPAddress = matchReg.group(1)
+ elif re.match('^\-\-eNBUserName=(.+)$|^\-\-eNB[1-2]UserName=(.+)$', myArgv, re.IGNORECASE):
+ if re.match('^\-\-eNBUserName=(.+)$', myArgv, re.IGNORECASE):
+ matchReg = re.match('^\-\-eNBUserName=(.+)$', myArgv, re.IGNORECASE)
+ SSH.eNBUserName = matchReg.group(1)
+ elif re.match('^\-\-eNB1UserName=(.+)$', myArgv, re.IGNORECASE):
+ matchReg = re.match('^\-\-eNB1UserName=(.+)$', myArgv, re.IGNORECASE)
+ SSH.eNB1UserName = matchReg.group(1)
+ elif re.match('^\-\-eNB2UserName=(.+)$', myArgv, re.IGNORECASE):
+ matchReg = re.match('^\-\-eNB2UserName=(.+)$', myArgv, re.IGNORECASE)
+ SSH.eNB2UserName = matchReg.group(1)
+ elif re.match('^\-\-eNBPassword=(.+)$|^\-\-eNB[1-2]Password=(.+)$', myArgv, re.IGNORECASE):
+ if re.match('^\-\-eNBPassword=(.+)$', myArgv, re.IGNORECASE):
+ matchReg = re.match('^\-\-eNBPassword=(.+)$', myArgv, re.IGNORECASE)
+ SSH.eNBPassword = matchReg.group(1)
+ elif re.match('^\-\-eNB1Password=(.+)$', myArgv, re.IGNORECASE):
+ matchReg = re.match('^\-\-eNB1Password=(.+)$', myArgv, re.IGNORECASE)
+ SSH.eNB1Password = matchReg.group(1)
+ elif re.match('^\-\-eNB2Password=(.+)$', myArgv, re.IGNORECASE):
+ matchReg = re.match('^\-\-eNB2Password=(.+)$', myArgv, re.IGNORECASE)
+ SSH.eNB2Password = matchReg.group(1)
+ elif re.match('^\-\-eNBSourceCodePath=(.+)$|^\-\-eNB[1-2]SourceCodePath=(.+)$', myArgv, re.IGNORECASE):
+ if re.match('^\-\-eNBSourceCodePath=(.+)$', myArgv, re.IGNORECASE):
+ matchReg = re.match('^\-\-eNBSourceCodePath=(.+)$', myArgv, re.IGNORECASE)
+ SSH.eNBSourceCodePath = matchReg.group(1)
+ elif re.match('^\-\-eNB1SourceCodePath=(.+)$', myArgv, re.IGNORECASE):
+ matchReg = re.match('^\-\-eNB1SourceCodePath=(.+)$', myArgv, re.IGNORECASE)
+ SSH.eNB1SourceCodePath = matchReg.group(1)
+ elif re.match('^\-\-eNB2SourceCodePath=(.+)$', myArgv, re.IGNORECASE):
+ matchReg = re.match('^\-\-eNB2SourceCodePath=(.+)$', myArgv, re.IGNORECASE)
+ SSH.eNB2SourceCodePath = matchReg.group(1)
elif re.match('^\-\-EPCIPAddress=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-EPCIPAddress=(.+)$', myArgv, re.IGNORECASE)
SSH.EPCIPAddress = matchReg.group(1)
@@ -3772,6 +3986,9 @@ if re.match('^TerminateeNB$', mode, re.IGNORECASE):
if SSH.eNBIPAddress == '' or SSH.eNBUserName == '' or SSH.eNBPassword == '':
Usage()
sys.exit('Insufficient Parameter')
+ SSH.eNB_serverId = '0'
+ SSH.eNB_instance = '0'
+ SSH.eNBSourceCodePath = '/tmp/'
SSH.TerminateeNB()
elif re.match('^TerminateUE$', mode, re.IGNORECASE):
if (SSH.ADBIPAddress == '' or SSH.ADBUserName == '' or SSH.ADBPassword == ''):
@@ -3864,15 +4081,15 @@ elif re.match('^FinalizeHtml$', mode, re.IGNORECASE):
SSH.CreateHtmlFooter(SSH.finalStatus)
elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re.IGNORECASE):
if re.match('^TesteNB$', mode, re.IGNORECASE):
- if SSH.eNBIPAddress == '' or SSH.eNBRepository == '' or SSH.eNBBranch == '' or SSH.eNBUserName == '' or SSH.eNBPassword == '' or SSH.eNBSourceCodePath == '' or SSH.EPCIPAddress == '' or SSH.EPCUserName == '' or SSH.EPCPassword == '' or SSH.EPCType == '' or SSH.EPCSourceCodePath == '' or SSH.ADBIPAddress == '' or SSH.ADBUserName == '' or SSH.ADBPassword == '':
+ if SSH.eNBIPAddress == '' or SSH.ranRepository == '' or SSH.ranBranch == '' or SSH.eNBUserName == '' or SSH.eNBPassword == '' or SSH.eNBSourceCodePath == '' or SSH.EPCIPAddress == '' or SSH.EPCUserName == '' or SSH.EPCPassword == '' or SSH.EPCType == '' or SSH.EPCSourceCodePath == '' or SSH.ADBIPAddress == '' or SSH.ADBUserName == '' or SSH.ADBPassword == '':
Usage()
sys.exit('Insufficient Parameter')
- if (SSH.EPCIPAddress != ''):
+ if (SSH.EPCIPAddress != '') and (SSH.EPCIPAddress != 'none'):
SSH.copyout(SSH.EPCIPAddress, SSH.EPCUserName, SSH.EPCPassword, cwd + "/tcp_iperf_stats.awk", "/tmp")
SSH.copyout(SSH.EPCIPAddress, SSH.EPCUserName, SSH.EPCPassword, cwd + "/active_net_interfaces.awk", "/tmp")
else:
- if SSH.UEIPAddress == '' or SSH.eNBRepository == '' or SSH.eNBBranch == '' or SSH.UEUserName == '' or SSH.UEPassword == '' or SSH.UESourceCodePath == '':
+ if SSH.UEIPAddress == '' or SSH.ranRepository == '' or SSH.ranBranch == '' or SSH.UEUserName == '' or SSH.UEPassword == '' or SSH.UESourceCodePath == '':
Usage()
sys.exit('UE: Insufficient Parameter')
@@ -3915,7 +4132,8 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re
else:
logging.debug('ERROR: requested test is invalidly formatted: ' + test)
sys.exit(1)
- SSH.CheckFlexranCtrlInstallation()
+ if (SSH.EPCIPAddress != '') and (SSH.EPCIPAddress != 'none'):
+ SSH.CheckFlexranCtrlInstallation()
#get the list of tests to be done
todo_tests=[]
@@ -3948,6 +4166,8 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re
SSH.GetAllUEDevices(terminate_ue_flag)
if action == 'Build_eNB':
SSH.BuildeNB()
+ elif action == 'WaitEndBuild_eNB':
+ SSH.WaitBuildeNBisFinished()
elif action == 'Initialize_eNB':
SSH.InitializeeNB()
elif action == 'Terminate_eNB':
diff --git a/ci-scripts/xml_files/multi_rru_band38_build.xml b/ci-scripts/xml_files/multi_rru_band38_build.xml
new file mode 100644
index 0000000000000000000000000000000000000000..614ef394f3307d89cee917d7f78c2fd9fc790835
--- /dev/null
+++ b/ci-scripts/xml_files/multi_rru_band38_build.xml
@@ -0,0 +1,84 @@
+
+
+ build-tab
+ Build
+ wrench
+
+ 010101 010102 010103
+ 000101 000102 000103
+
+
+
+
+ Build_eNB
+ Build RCC
+ -w USRP -c --eNB
+ 0
+ 0
+ True
+
+
+
+ WaitEndBuild_eNB
+ Wait for end of Build RCC
+ -w USRP -c --eNB
+ 0
+ 0
+
+
+
+ Build_eNB
+ Build Master RRU
+ -w USRP -c --eNB
+ 1
+ 1
+ True
+
+
+
+ WaitEndBuild_eNB
+ Wait for end of Build Master RRU
+ -w USRP -c --eNB
+ 1
+ 1
+
+
+
+ Build_eNB
+ Build Slave RRU
+ -w USRP -c --eNB
+ 2
+ 2
+ True
+
+
+
+ WaitEndBuild_eNB
+ Wait for end of Build Slave RRU
+ -w USRP -c --eNB
+ 2
+ 2
+
+
+
diff --git a/ci-scripts/xml_files/multi_rru_band38_full_termination.xml b/ci-scripts/xml_files/multi_rru_band38_full_termination.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d63c73aec55342220a43486dc2180924baeef882
--- /dev/null
+++ b/ci-scripts/xml_files/multi_rru_band38_full_termination.xml
@@ -0,0 +1,53 @@
+
+
+ test-full-termintation
+ Test-RCC-RRUs-Termination
+ off
+
+ 030211 030212 030213
+
+
+
+
+ Terminate_eNB
+ Terminate RCC
+ 0
+ 0
+
+
+
+ Terminate_eNB
+ Terminate Master RRU
+ 1
+ 1
+
+
+
+ Terminate_eNB
+ Terminate Slave RRU
+ 2
+ 2
+
+
+
diff --git a/ci-scripts/xml_files/multi_rru_band38_test_10mhz_tm1.xml b/ci-scripts/xml_files/multi_rru_band38_test_10mhz_tm1.xml
new file mode 100644
index 0000000000000000000000000000000000000000..70fba65f05ef4c6ad6b7d1b886ecd871288ebd4e
--- /dev/null
+++ b/ci-scripts/xml_files/multi_rru_band38_test_10mhz_tm1.xml
@@ -0,0 +1,86 @@
+
+
+ test-multi-rru-10
+ Test-Multi-RRU-10MHz
+ tasks
+
+ 030211 030212 030213
+ 030111 030112 030113
+ 000001
+ 030211 030212 030213
+
+
+
+
+ IdleSleep
+ Sleep
+ 60
+
+
+
+ Initialize_eNB
+ Initialize RCC (TDD/Band38/10MHz)
+ -O ci-scripts/conf_files/rcc.band38.tm1.50PRB.multi.rru.conf --noS1
+ 0
+ 0
+
+
+
+ Initialize_eNB
+ Initialize Master RRU (TDD/Band38/10MHz)
+ -O ci-scripts/conf_files/rru.band38.tm1.master.conf --noS1
+ 1
+ 1
+
+
+
+ Initialize_eNB
+ Initialize Slave RRU (TDD/Band38/10MHz)
+ -O ci-scripts/conf_files/rru.band38.tm1.slave.conf --noS1
+ 2
+ 2
+
+
+
+ Terminate_eNB
+ Terminate RCC
+ 0
+ 0
+
+
+
+ Terminate_eNB
+ Terminate Master RRU
+ 1
+ 1
+
+
+
+ Terminate_eNB
+ Terminate Slave RRU
+ 2
+ 2
+
+
+
diff --git a/common/utils/T/tracer/macpdu2wireshark.c b/common/utils/T/tracer/macpdu2wireshark.c
index 8720efd8c0834e0a75b5452b12030420f7da082c..c391a9978679731c013d132849bbd13f24fe1bb0 100644
--- a/common/utils/T/tracer/macpdu2wireshark.c
+++ b/common/utils/T/tracer/macpdu2wireshark.c
@@ -52,6 +52,7 @@ typedef struct {
int max_mib;
int max_sib;
int live;
+ int no_bind;
/* runtime vars */
int cur_mib;
int cur_sib;
@@ -264,9 +265,11 @@ void *receiver(void *_d) {
abort();
}
- if (bind(s, (struct sockaddr *)&d->to, sizeof(struct sockaddr_in)) == -1) {
- perror("bind");
- abort();
+ if (d->no_bind == 0) {
+ if (bind(s, (struct sockaddr *)&d->to, sizeof(struct sockaddr_in)) == -1) {
+ perror("bind");
+ abort();
+ }
}
while (1) {
@@ -290,6 +293,7 @@ void usage(void) {
" -live run live\n"
" -live-ip tracee's IP address (default %s)\n"
" -live-port tracee's port (default %d)\n"
+ " -no-bind don't bind to IP address (for remote logging)\n"
"-i and -live are mutually exclusive options. One of them must be provided\n"
"but not both.\n",
DEFAULT_IP,
@@ -318,78 +322,18 @@ int main(int n, char **v) {
for (i = 1; i < n; i++) {
if (!strcmp(v[i], "-h") || !strcmp(v[i], "--help")) usage();
-
- if (!strcmp(v[i], "-d")) {
- if (i > n-2) usage();
-
- database_filename = v[++i];
- continue;
- }
-
- if (!strcmp(v[i], "-i")) {
- if (i > n-2) usage();
-
- input_filename = v[++i];
- continue;
- }
-
- if (!strcmp(v[i], "-ip")) {
- if (i > n-2) usage();
-
- ip = v[++i];
- continue;
- }
-
- if (!strcmp(v[i], "-p")) {
- if(i>n-2)usage();
-
- port=atoi(v[++i]);
- continue;
- }
-
- if (!strcmp(v[i], "-no-mib")) {
- d.no_mib = 1;
- continue;
- }
-
- if (!strcmp(v[i], "-no-sib")) {
- d.no_sib = 1;
- continue;
- }
-
- if (!strcmp(v[i], "-max-mib")) {
- if (i > n-2) usage();
-
- d.max_mib = atoi(v[++i]);
- continue;
- }
-
- if (!strcmp(v[i], "-max-sib")) {
- if (i > n-2) usage();
-
- d.max_sib = atoi(v[++i]);
- continue;
- }
-
- if (!strcmp(v[i], "-live")) {
- live = 1;
- continue;
- }
-
- if (!strcmp(v[i], "-live-ip")) {
- if (i > n-2) usage();
-
- live_ip = v[++i];
- continue;
- }
-
- if (!strcmp(v[i], "-live-port")) {
- if (i > n-2) usage();
-
- live_port = atoi(v[++i]);
- continue;
- }
-
+ if (!strcmp(v[i], "-d")) { if(i>n-2)usage(); database_filename = v[++i]; continue; }
+ if (!strcmp(v[i], "-i")) { if(i>n-2)usage(); input_filename = v[++i]; continue; }
+ if (!strcmp(v[i], "-ip")) { if(i>n-2)usage(); ip = v[++i]; continue; }
+ if (!strcmp(v[i], "-p")) { if(i>n-2)usage(); port = atoi(v[++i]); continue; }
+ if (!strcmp(v[i], "-no-mib")) { d.no_mib = 1; continue; }
+ if (!strcmp(v[i], "-no-sib")) { d.no_sib = 1; continue; }
+ if (!strcmp(v[i], "-max-mib")) { if(i>n-2)usage(); d.max_mib = atoi(v[++i]); continue; }
+ if (!strcmp(v[i], "-max-sib")) { if(i>n-2)usage(); d.max_sib = atoi(v[++i]); continue; }
+ if (!strcmp(v[i], "-live")) { live = 1; continue; }
+ if (!strcmp(v[i], "-live-ip")) { if(i>n-2)usage(); live_ip = v[++i]; continue; }
+ if (!strcmp(v[i], "-live-port")) { if(i>n-2)usage(); live_port = atoi(v[++i]); continue; }
+ if (!strcmp(v[i], "-no-bind")) { d.no_bind = 1; continue; }
usage();
}
diff --git a/common/utils/system.c b/common/utils/system.c
index dcec681e2dcf2596b78352560672439e7bba58ee..31c1035129998da9a8340b1b80895e0dd4d44120 100644
--- a/common/utils/system.c
+++ b/common/utils/system.c
@@ -28,13 +28,23 @@
* separate process solves this problem.
*/
+#define _GNU_SOURCE
#include "system.h"
#include
#include
#include
#include
#include
-
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
#define MAX_COMMAND 4096
static int command_pipe_read;
@@ -50,37 +60,37 @@ static int module_initialized = 0;
/* util functions */
/********************************************************************/
-static void lock_system(void)
-{
+static void lock_system(void) {
if (pthread_mutex_lock(&lock) != 0) {
printf("pthread_mutex_lock fails\n");
abort();
}
}
-static void unlock_system(void)
-{
+static void unlock_system(void) {
if (pthread_mutex_unlock(&lock) != 0) {
printf("pthread_mutex_unlock fails\n");
abort();
}
}
-static void write_pipe(int p, char *b, int size)
-{
+static void write_pipe(int p, char *b, int size) {
while (size) {
int ret = write(p, b, size);
+
if (ret <= 0) exit(0);
+
b += ret;
size -= ret;
}
}
-static void read_pipe(int p, char *b, int size)
-{
+static void read_pipe(int p, char *b, int size) {
while (size) {
int ret = read(p, b, size);
+
if (ret <= 0) exit(0);
+
b += ret;
size -= ret;
}
@@ -95,14 +105,13 @@ static void read_pipe(int p, char *b, int size)
* when the main process exits, because then a "read" on the pipe
* will return 0, in which case "read_pipe" exits.
*/
-static void background_system_process(void)
-{
+static void background_system_process(void) {
int len;
int ret;
char command[MAX_COMMAND+1];
while (1) {
- read_pipe(command_pipe_read, (char*)&len, sizeof(int));
+ read_pipe(command_pipe_read, (char *)&len, sizeof(int));
read_pipe(command_pipe_read, command, len);
ret = system(command);
write_pipe(result_pipe_write, (char *)&ret, sizeof(int));
@@ -114,8 +123,7 @@ static void background_system_process(void)
/* return -1 on error, 0 on success */
/********************************************************************/
-int background_system(char *command)
-{
+int background_system(char *command) {
int res;
int len;
@@ -125,18 +133,22 @@ int background_system(char *command)
}
len = strlen(command)+1;
+
if (len > MAX_COMMAND) {
printf("FATAL: command too long. Increase MAX_COMMAND (%d).\n", MAX_COMMAND);
printf("command was: '%s'\n", command);
abort();
}
+
/* only one command can run at a time, so let's lock/unlock */
lock_system();
- write_pipe(command_pipe_write, (char*)&len, sizeof(int));
+ write_pipe(command_pipe_write, (char *)&len, sizeof(int));
write_pipe(command_pipe_write, command, len);
- read_pipe(result_pipe_read, (char*)&res, sizeof(int));
+ read_pipe(result_pipe_read, (char *)&res, sizeof(int));
unlock_system();
+
if (res == -1 || !WIFEXITED(res) || WEXITSTATUS(res) != 0) return -1;
+
return 0;
}
@@ -146,17 +158,16 @@ int background_system(char *command)
/* to be called very early by the main processing */
/********************************************************************/
-void start_background_system(void)
-{
+void start_background_system(void) {
int p[2];
pid_t son;
-
module_initialized = 1;
if (pipe(p) == -1) {
perror("pipe");
exit(1);
}
+
command_pipe_read = p[0];
command_pipe_write = p[1];
@@ -164,10 +175,11 @@ void start_background_system(void)
perror("pipe");
exit(1);
}
+
result_pipe_read = p[0];
result_pipe_write = p[1];
-
son = fork();
+
if (son == -1) {
perror("fork");
exit(1);
@@ -181,6 +193,56 @@ void start_background_system(void)
close(result_pipe_read);
close(command_pipe_write);
-
background_system_process();
}
+
+
+void threadCreate(pthread_t* t, void * (*func)(void*), void * param, char* name, int affinity, int priority){
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+ pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
+ pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
+ struct sched_param sparam={0};
+ sparam.sched_priority = priority;
+ pthread_attr_setschedparam(&attr, &sparam);
+
+ pthread_create(t, &attr, func, param);
+
+ pthread_setname_np(*t, name);
+ if (affinity != -1 ) {
+ cpu_set_t cpuset;
+ CPU_ZERO(&cpuset);
+ CPU_SET(affinity, &cpuset);
+ AssertFatal( pthread_setaffinity_np(*t, sizeof(cpu_set_t), &cpuset) == 0, "Error setting processor affinity");
+ }
+
+ pthread_attr_destroy(&attr);
+}
+
+// Block CPU C-states deep sleep
+void configure_linux(void) {
+ int ret;
+ static int latency_target_fd=-1;
+ uint32_t latency_target_value=10; // in microseconds
+ if (latency_target_fd == -1) {
+ if ( (latency_target_fd = open("/dev/cpu_dma_latency", O_RDWR)) != -1 ) {
+ ret = write(latency_target_fd, &latency_target_value, sizeof(latency_target_value));
+ if (ret == 0) {
+ printf("# error setting cpu_dma_latency to %d!: %s\n", latency_target_value, strerror(errno));
+ close(latency_target_fd);
+ latency_target_fd=-1;
+ return;
+ }
+ }
+ }
+ if (latency_target_fd != -1)
+ LOG_I(HW,"# /dev/cpu_dma_latency set to %dus\n", latency_target_value);
+ else
+ LOG_E(HW,"Can't set /dev/cpu_dma_latency to %dus\n", latency_target_value);
+
+ // Set CPU frequency to it's maximum
+ if ( 0 != system("for d in /sys/devices/system/cpu/cpu[0-9]*; do cat $d/cpufreq/cpuinfo_max_freq > $d/cpufreq/scaling_min_freq; done"))
+ LOG_W(HW,"Can't set cpu frequency\n");
+
+}
diff --git a/common/utils/system.h b/common/utils/system.h
index 658c17adc1a476ce68c03d1510623c87c382ab29..a89a6c5b1729f0b968fbfd4baed9cfd3cce85b10 100644
--- a/common/utils/system.h
+++ b/common/utils/system.h
@@ -21,6 +21,12 @@
#ifndef _SYSTEM_H_OAI_
#define _SYSTEM_H_OAI_
+#include
+#include
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/****************************************************
* send a command to the background process
@@ -36,4 +42,23 @@ int background_system(char *command);
void start_background_system(void);
+void set_latency_target(void);
+void configure_linux(void);
+
+void threadCreate(pthread_t* t, void * (*func)(void*), void * param, char* name, int affinity, int priority);
+#define OAI_PRIORITY_RT_LOW sched_get_priority_min(SCHED_FIFO)
+#define OAI_PRIORITY_RT sched_get_priority_max(SCHED_FIFO)-10
+#define OAI_PRIORITY_RT_MAX sched_get_priority_max(SCHED_FIFO)
+
+void thread_top_init(char *thread_name,
+ int affinity,
+ uint64_t runtime,
+ uint64_t deadline,
+ uint64_t period);
+
+#ifdef __cplusplus
+}
+#endif
+
+
#endif /* _SYSTEM_H_OAI_ */
diff --git a/openair1/PHY/LTE_TRANSPORT/dci.c b/openair1/PHY/LTE_TRANSPORT/dci.c
index b4b253a297648df6e0dbaa4ae91a358f7e4f9575..1913afab2df61d0dca23cb3d510a66b3eb643c00 100644
--- a/openair1/PHY/LTE_TRANSPORT/dci.c
+++ b/openair1/PHY/LTE_TRANSPORT/dci.c
@@ -291,24 +291,8 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols,
y[0] = &yseq0[0];
y[1] = &yseq1[0];
- if (IS_SOFTMODEM_BASICSIM) {
- /* this should be the normal case
- * but it has to be validated for all the various cases
- * so let's just do it for the basic simulator
- */
- // memset(e, 2, DCI_BITS_MAX);
- } else {
- // reset all bits to , here we set elements as 2
- // memset(e, 2, DCI_BITS_MAX);
- // here we interpret NIL as a random QPSK sequence. That makes power estimation easier.
- for (i=0; i, here we set elements as 2 */
+ memset(e, 2, DCI_BITS_MAX);
e_ptr = e;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DCI0,1);
diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c
index 28dd38b65a1c2a9d803d1fae7813f109c409aa5a..801bc8d4dc6f891e83c2c7adf759f0e269c2a421 100644
--- a/openair1/SCHED/phy_procedures_lte_eNb.c
+++ b/openair1/SCHED/phy_procedures_lte_eNb.c
@@ -230,13 +230,11 @@ void common_signal_procedures (PHY_VARS_eNB *eNB,int frame, int subframe) {
-void pdsch_procedures(PHY_VARS_eNB *eNB,
+bool dlsch_procedures(PHY_VARS_eNB *eNB,
L1_rxtx_proc_t *proc,
int harq_pid,
LTE_eNB_DLSCH_t *dlsch,
- LTE_eNB_DLSCH_t *dlsch1,
- LTE_eNB_UE_stats *ue_stats,
- int ra_flag) {
+ LTE_eNB_UE_stats *ue_stats) {
int frame=proc->frame_tx;
int subframe=proc->subframe_tx;
LTE_DL_eNB_HARQ_t *dlsch_harq=dlsch->harq_processes[harq_pid];
@@ -265,27 +263,6 @@ void pdsch_procedures(PHY_VARS_eNB *eNB,
dlsch_harq->round);
}
- MSC_LOG_TX_MESSAGE(
- MSC_PHY_ENB,MSC_PHY_UE,
- NULL,0,
- "%05u:%02u PDSCH/DLSCH input size = %"PRIu16", G %d, nb_rb %"PRIu16", TBS %"PRIu16", pmi_alloc %"PRIx16", rv %"PRIu8" (round %"PRIu8")",
- frame, subframe,
- dlsch_harq->TBS/8,
- get_G(fp,
- dlsch_harq->nb_rb,
- dlsch_harq->rb_alloc,
- dlsch_harq->Qm,
- dlsch_harq->Nl,
- dlsch_harq->pdsch_start,
- frame,
- subframe,
- dlsch_harq->mimo_mode==TM7?7:0),
- dlsch_harq->nb_rb,
- dlsch_harq->TBS,
- pmi2hex_2Ar1(dlsch_harq->pmi_alloc),
- dlsch_harq->rvidx,
- dlsch_harq->round);
-
if (ue_stats) ue_stats->dlsch_sliding_cnt++;
if (dlsch_harq->round == 0) {
@@ -300,15 +277,17 @@ void pdsch_procedures(PHY_VARS_eNB *eNB,
#endif
}
- if (dlsch->rnti!=0xffff) LOG_D(PHY,"Generating DLSCH/PDSCH pdu:%p pdsch_start:%d frame:%d subframe:%d nb_rb:%d rb_alloc:%d Qm:%d Nl:%d round:%d\n",
- dlsch_harq->pdu,dlsch_harq->pdsch_start,frame,subframe,dlsch_harq->nb_rb,dlsch_harq->rb_alloc[0],dlsch_harq->Qm,dlsch_harq->Nl,dlsch_harq->round);
+ if (dlsch->rnti!=0xffff)
+ LOG_D(PHY,"Generating DLSCH/PDSCH pdu:%p pdsch_start:%d frame:%d subframe:%d nb_rb:%d rb_alloc:%d Qm:%d Nl:%d round:%d\n",
+ dlsch_harq->pdu,dlsch_harq->pdsch_start,frame,subframe,dlsch_harq->nb_rb,dlsch_harq->rb_alloc[0],
+ dlsch_harq->Qm,dlsch_harq->Nl,dlsch_harq->round);
// 36-212
if (NFAPI_MODE==NFAPI_MONOLITHIC || NFAPI_MODE==NFAPI_MODE_PNF) { // monolthic OR PNF - do not need turbo encoding on VNF
if (dlsch_harq->pdu==NULL) {
LOG_E(PHY,"dlsch_harq->pdu == NULL SFN/SF:%04d%d dlsch[rnti:%x] dlsch_harq[pdu:%p pdsch_start:%d Qm:%d Nl:%d round:%d nb_rb:%d rb_alloc[0]:%d]\n", frame,subframe,dlsch->rnti, dlsch_harq->pdu,
dlsch_harq->pdsch_start,dlsch_harq->Qm,dlsch_harq->Nl,dlsch_harq->round,dlsch_harq->nb_rb,dlsch_harq->rb_alloc[0]);
- return;
+ return false;
}
start_meas(&eNB->dlsch_encoding_stats);
@@ -330,44 +309,57 @@ void pdsch_procedures(PHY_VARS_eNB *eNB,
if(eNB->dlsch_encoding_stats.p_time>500*3000 && opp_enabled == 1) {
print_meas_now(&eNB->dlsch_encoding_stats,"total coding",stderr);
}
-
- // 36-211
- start_meas(&eNB->dlsch_scrambling_stats);
- dlsch_scrambling(fp,
- 0,
- dlsch,
- harq_pid,
- get_G(fp,
- dlsch_harq->nb_rb,
- dlsch_harq->rb_alloc,
- dlsch_harq->Qm,
- dlsch_harq->Nl,
- dlsch_harq->pdsch_start,
- frame,subframe,
- 0),
- 0,
- frame,
- subframe<<1);
- stop_meas(&eNB->dlsch_scrambling_stats);
- start_meas(&eNB->dlsch_modulation_stats);
- dlsch_modulation(eNB,
- eNB->common_vars.txdataF,
- AMP,
- frame,
- subframe,
- dlsch_harq->pdsch_start,
- dlsch,
- dlsch->ue_type==0 ? dlsch1 : (LTE_eNB_DLSCH_t *)NULL);
- stop_meas(&eNB->dlsch_modulation_stats);
- }
-
#ifdef PHY_TX_THREAD
- dlsch->active[subframe] = 0;
+ dlsch->active[subframe] = 0;
#else
- dlsch->active = 0;
+ dlsch->active = 0;
#endif
- dlsch_harq->round++;
- LOG_D(PHY,"Generating DLSCH/PDSCH dlsch_harq[round:%d]\n",dlsch_harq->round);
+ dlsch_harq->round++;
+ LOG_D(PHY,"Generated DLSCH dlsch_harq[round:%d]\n",dlsch_harq->round);
+ return true;
+ }
+ return false;
+}
+
+void pdsch_procedures(PHY_VARS_eNB *eNB,
+ L1_rxtx_proc_t *proc,
+ int harq_pid,
+ LTE_eNB_DLSCH_t *dlsch,
+ LTE_eNB_DLSCH_t *dlsch1) {
+ int frame=proc->frame_tx;
+ int subframe=proc->subframe_tx;
+ LTE_DL_eNB_HARQ_t *dlsch_harq=dlsch->harq_processes[harq_pid];
+ LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
+ // 36-211
+ start_meas(&eNB->dlsch_scrambling_stats);
+ dlsch_scrambling(fp,
+ 0,
+ dlsch,
+ harq_pid,
+ get_G(fp,
+ dlsch_harq->nb_rb,
+ dlsch_harq->rb_alloc,
+ dlsch_harq->Qm,
+ dlsch_harq->Nl,
+ dlsch_harq->pdsch_start,
+ frame,subframe,
+ 0),
+ 0,
+ frame,
+ subframe<<1);
+ stop_meas(&eNB->dlsch_scrambling_stats);
+ start_meas(&eNB->dlsch_modulation_stats);
+ dlsch_modulation(eNB,
+ eNB->common_vars.txdataF,
+ AMP,
+ frame,
+ subframe,
+ dlsch_harq->pdsch_start,
+ dlsch,
+ dlsch->ue_type==0 ? dlsch1 : (LTE_eNB_DLSCH_t *)NULL);
+ stop_meas(&eNB->dlsch_modulation_stats);
+
+ LOG_D(PHY,"Generated PDSCH dlsch_harq[round:%d]\n",dlsch_harq->round);
}
@@ -531,14 +523,18 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
dlsch0->harq_ids[frame%2][6],
dlsch0->harq_ids[frame%2][7]);
} else {
- // generate pdsch
- pdsch_procedures(eNB,
+ if (dlsch_procedures(eNB,
proc,
harq_pid,
dlsch0,
- dlsch1,
- &eNB->UE_stats[(uint32_t)UE_id],
- 0);
+ &eNB->UE_stats[(uint32_t)UE_id])) {
+ // if we generate dlsch, we must generate pdsch
+ pdsch_procedures(eNB,
+ proc,
+ harq_pid,
+ dlsch0,
+ dlsch1);
+ }
}
} else if ((dlsch0)&&(dlsch0->rnti>0)&&
#ifdef PHY_TX_THREAD
diff --git a/openair1/SCHED/ru_procedures.c b/openair1/SCHED/ru_procedures.c
index 928b272edd6e6f43e98d1315f562531dc30c9d2f..1f1a36b238eb8a09d847a0eaf009155575e9e18d 100644
--- a/openair1/SCHED/ru_procedures.c
+++ b/openair1/SCHED/ru_procedures.c
@@ -100,7 +100,7 @@ void feptx0(RU_t *ru,int slot) {
*/
int num_symb = 7;
- if (subframe_select(fp,subframe) == SF_S) num_symb=fp->dl_symbols_in_S_subframe;
+ if (subframe_select(fp,subframe) == SF_S) num_symb=fp->dl_symbols_in_S_subframe+1;
if (ru->generate_dmrs_sync == 1 && slot == 0 && subframe == 1 && aa==0) {
//int32_t dmrs[ru->frame_parms.ofdm_symbol_size*14] __attribute__((aligned(32)));
diff --git a/openair1/SIMULATION/TOOLS/random_channel.c b/openair1/SIMULATION/TOOLS/random_channel.c
index 8341c574da2968b8a361cdc82c3801bf8a91b998..f056d51b5d3c49a55a71e058ec2b061f2f911022 100644
--- a/openair1/SIMULATION/TOOLS/random_channel.c
+++ b/openair1/SIMULATION/TOOLS/random_channel.c
@@ -1204,6 +1204,10 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
return(chan_desc);
}
+void free_channel_desc_scm(channel_desc_t * ch) {
+ // Must be made cleanly, a lot of leaks...
+ free(ch);
+}
int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) {
diff --git a/openair2/COMMON/x2ap_messages_types.h b/openair2/COMMON/x2ap_messages_types.h
index d284f4d0b9d8b566511c835e3bcc6645d5f5284d..5a35b85fdb4e413d9f71fd3d475e163cdad09f3d 100644
--- a/openair2/COMMON/x2ap_messages_types.h
+++ b/openair2/COMMON/x2ap_messages_types.h
@@ -205,7 +205,7 @@ typedef struct x2ap_handover_req_s {
x2ap_lastvisitedcell_info_t lastvisitedcell_info;
- uint8_t rrc_buffer[1024 /* arbitrary, big enough */];
+ uint8_t rrc_buffer[8192 /* arbitrary, big enough */];
int rrc_buffer_size;
int target_assoc_id;
diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c
index 4543ff3050d1bc0d4cfa433ee983ba1a0ff9539f..ac22da1b426aa7dac91685fb21529554e813192a 100644
--- a/openair2/RRC/LTE/rrc_eNB.c
+++ b/openair2/RRC/LTE/rrc_eNB.c
@@ -116,6 +116,10 @@ extern int rrc_eNB_process_security(const protocol_ctxt_t *const ctxt_pP, rrc_eN
extern void process_eNB_security_key (const protocol_ctxt_t *const ctxt_pP, rrc_eNB_ue_context_t *const ue_context_pP, uint8_t *security_key_pP);
extern int derive_keNB_star(const uint8_t *kenb_32, const uint16_t pci, const uint32_t earfcn_dl, const bool is_rel8_only, uint8_t * kenb_star);
+pthread_mutex_t rrc_release_freelist;
+RRC_release_list_t rrc_release_info;
+pthread_mutex_t lock_ue_freelist;
+
void
openair_rrc_on(
const protocol_ctxt_t *const ctxt_pP
@@ -4610,10 +4614,10 @@ rrc_eNB_generate_HandoverPreparationInformation(
uint8_t *buffer,
int *_size
) {
- memset(buffer, 0, RRC_BUF_SIZE);
+ memset(buffer, 0, 8192);
char *ho_buf = (char *) buffer;
int ho_size;
- ho_size = do_HandoverPreparation(ho_buf, 1024, ue_context_pP->ue_context.UE_Capability, ue_context_pP->ue_context.UE_Capability_size);
+ ho_size = do_HandoverPreparation(ho_buf, 8192, ue_context_pP->ue_context.UE_Capability, ue_context_pP->ue_context.UE_Capability_size);
*_size = ho_size;
}
diff --git a/openair2/RRC/LTE/rrc_proto.h b/openair2/RRC/LTE/rrc_proto.h
index e7e5e71d8093f4d05bb14ddb1a64dd702f8024d5..a8ee7ecabe043b127ab51a8d1bd45d5e340cbba9 100644
--- a/openair2/RRC/LTE/rrc_proto.h
+++ b/openair2/RRC/LTE/rrc_proto.h
@@ -667,9 +667,11 @@ void openair_rrc_top_init_ue(
uint8_t cba_group_active,
uint8_t HO_active
);
-pthread_mutex_t rrc_release_freelist;
-RRC_release_list_t rrc_release_info;
-pthread_mutex_t lock_ue_freelist;
+
+extern pthread_mutex_t rrc_release_freelist;
+extern RRC_release_list_t rrc_release_info;
+extern pthread_mutex_t lock_ue_freelist;
+
void remove_UE_from_freelist(module_id_t mod_id, rnti_t rnti);
void put_UE_in_freelist(module_id_t mod_id, rnti_t rnti, boolean_t removeFlag);
void release_UE_in_freeList(module_id_t mod_id);
diff --git a/openair2/X2AP/x2ap_eNB_handler.c b/openair2/X2AP/x2ap_eNB_handler.c
index 2a44501a337a3008d7940aed17ba974d03774bcd..41d92a695e0da3b933a190502a44cdab1a831d08 100644
--- a/openair2/X2AP/x2ap_eNB_handler.c
+++ b/openair2/X2AP/x2ap_eNB_handler.c
@@ -730,7 +730,7 @@ int x2ap_eNB_handle_handover_preparation (instance_t instance,
X2AP_RRC_Context_t *c = &ie->value.choice.UE_ContextInformation.rRC_Context;
- if (c->size > 1024 /* TODO: this is the size of rrc_buffer in struct x2ap_handover_req_ack_s*/)
+ if (c->size > 8192 /* TODO: this is the size of rrc_buffer in struct x2ap_handover_req_s */)
{ printf("%s:%d: fatal: buffer too big\n", __FILE__, __LINE__); abort(); }
memcpy(X2AP_HANDOVER_REQ(msg).rrc_buffer, c->buf, c->size);
@@ -821,7 +821,7 @@ int x2ap_eNB_handle_handover_response (instance_t instance,
X2AP_TargeteNBtoSource_eNBTransparentContainer_t *c = &ie->value.choice.TargeteNBtoSource_eNBTransparentContainer;
- if (c->size > 1024 /* TODO: this is the size of rrc_buffer in struct x2ap_handover_req_ack_s*/)
+ if (c->size > 1024 /* TODO: this is the size of rrc_buffer in struct x2ap_handover_req_ack_s */)
{ printf("%s:%d: fatal: buffer too big\n", __FILE__, __LINE__); abort(); }
memcpy(X2AP_HANDOVER_REQ_ACK(msg).rrc_buffer, c->buf, c->size);
diff --git a/openair3/SCTP/sctp_default_values.h b/openair3/SCTP/sctp_default_values.h
index 5008ea0b72bf6d9202bc633f44595e3b415eccce..528ffb5a05114aea3c37ea584e8a55f871210ddc 100644
--- a/openair3/SCTP/sctp_default_values.h
+++ b/openair3/SCTP/sctp_default_values.h
@@ -26,6 +26,6 @@
#define SCTP_IN_STREAMS (16)
#define SCTP_MAX_ATTEMPTS (2)
#define SCTP_TIMEOUT (5)
-#define SCTP_RECV_BUFFER_SIZE (1024)
+#define SCTP_RECV_BUFFER_SIZE (8192)
#endif /* SCTP_DEFAULT_VALUES_H_ */
diff --git a/openair3/SCTP/sctp_eNB_task.c b/openair3/SCTP/sctp_eNB_task.c
index e93488817832d9e52a59a14b9603f2c52cfe351c..3cb64254fccbcc4a9378f68f4b9cc523eb101c27 100644
--- a/openair3/SCTP/sctp_eNB_task.c
+++ b/openair3/SCTP/sctp_eNB_task.c
@@ -955,6 +955,11 @@ sctp_eNB_read_from_socket(
return;
}
+ if (!(flags & MSG_EOR)) {
+ SCTP_ERROR("fatal: partial SCTP messages are not handled\n");
+ exit(1);
+ }
+
if (flags & MSG_NOTIFICATION) {
union sctp_notification *snp;
snp = (union sctp_notification *)buffer;
diff --git a/targets/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.h b/targets/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.h
index 31a7173630801357386e9a478967ca68a20a8d4c..c9d0027bf299be9e2071965fecebb9783b14c3e7 100644
--- a/targets/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.h
+++ b/targets/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.h
@@ -27,7 +27,7 @@
#include
#include "common_lib.h"
-#include "log.h"
+#include "LOG/log.h"
/** @addtogroup _BLADERF_PHY_RF_INTERFACE_
* @{
diff --git a/targets/ARCH/COMMON/common_lib.c b/targets/ARCH/COMMON/common_lib.c
index c1685e11ecd5beab3aeed890c8fee63a634132c1..010f54a3ba4e45d4203256388022dfa15f2a5dcf 100644
--- a/targets/ARCH/COMMON/common_lib.c
+++ b/targets/ARCH/COMMON/common_lib.c
@@ -105,7 +105,7 @@ int load_lib(openair0_device *device, openair0_config_t *openair0_cfg, eth_param
if ( IS_SOFTMODEM_BASICSIM ) {
libname=OAI_BASICSIM_LIBNAME;
shlib_fdesc[0].fname="device_init";
- } else if ( IS_SOFTMODEM_RFSIM ) {
+ } else if ( IS_SOFTMODEM_RFSIM && flag == RAU_LOCAL_RADIO_HEAD) {
libname=OAI_RFSIM_LIBNAME;
shlib_fdesc[0].fname="device_init";
} else if (flag == RAU_LOCAL_RADIO_HEAD) {
diff --git a/targets/ARCH/rfsimulator/simulator.c b/targets/ARCH/rfsimulator/simulator.c
index 3b23d6de066484a5e8d9f440f70fe1d1e9c1a545..d30848609628788682ce08c629b9ec18b633f2b6 100644
--- a/targets/ARCH/rfsimulator/simulator.c
+++ b/targets/ARCH/rfsimulator/simulator.c
@@ -47,8 +47,8 @@ pthread_mutex_t Sockmutex;
typedef struct buffer_s {
int conn_sock;
- bool alreadyRead;
- uint64_t lastReceivedTS;
+ openair0_timestamp lastReceivedTS;
+ openair0_timestamp lastWroteTS;
bool headerMode;
samplesBlockHeader_t th;
char *transferPtr;
@@ -60,7 +60,7 @@ typedef struct buffer_s {
typedef struct {
int listen_sock, epollfd;
- uint64_t nextTimestamp;
+ openair0_timestamp nextTimestamp;
uint64_t typeStamp;
char *ip;
int saveIQfile;
@@ -104,9 +104,9 @@ void rxAddInput( struct complex16 *input_sig, struct complex16 *after_channel_si
// Fixme: how to convert a noise in Watt into a 12 bits value out of the RF ADC ?
// the parameter "-s" is declared as SNR, but the input power is not well defined
// −132.24 dBm is a LTE subcarrier noise, that was used in origin code (15KHz BW thermal noise)
- const double rxGain= 132.24 - snr_dB;
+ const double rxGain= 132.24 - snr_dB;
// sqrt(4*noise_figure_watt) is the thermal noise factor (volts)
- // fixme: the last constant is pure trial results to make decent noise
+ // fixme: the last constant is pure trial results to make decent noise
const double noise_per_sample = sqrt(4*noise_figure_watt) * pow(10,rxGain/20) *10;
// Fixme: we don't fill the offset length samples at begining ?
// anyway, in today code, channel_offset=0
@@ -135,9 +135,6 @@ void rxAddInput( struct complex16 *input_sig, struct complex16 *after_channel_si
}
out_ptr->r += round(rx_tmp.x*pathLossLinear + noise_per_sample*gaussdouble(0.0,1.0));
- printf("in: %d, out %d= %f*%f + %f*%f\n",
- input_sig[((TS+i)*nbTx)%CirSize].r, out_ptr->r , rx_tmp.x,
- pathLossLinear, noise_per_sample,gaussdouble(0.0,1.0));
out_ptr->i += round(rx_tmp.y*pathLossLinear + noise_per_sample*gaussdouble(0.0,1.0));
out_ptr++;
}
@@ -156,8 +153,8 @@ void allocCirBuf(rfsimulator_state_t *bridge, int sock) {
AssertFatal ( (ptr->circularBuf=(sample_t *) malloc(sampleToByte(CirSize,1))) != NULL, "");
ptr->circularBufEnd=((char *)ptr->circularBuf)+sampleToByte(CirSize,1);
ptr->conn_sock=sock;
- ptr->alreadyRead=false;
ptr->lastReceivedTS=0;
+ ptr->lastWroteTS=0;
ptr->headerMode=true;
ptr->transferPtr=(char *)&ptr->th;
ptr->remainToTransfer=sizeof(samplesBlockHeader_t);
@@ -322,21 +319,22 @@ sin_addr:
setblocking(sock, notBlocking);
allocCirBuf(t, sock);
- t->buf[sock].alreadyRead=true; // UE will start blocking on read
return 0;
}
-uint64_t lastW=-1;
int rfsimulator_write(openair0_device *device, openair0_timestamp timestamp, void **samplesVoid, int nsamps, int nbAnt, int flags) {
rfsimulator_state_t *t = device->priv;
LOG_D(HW,"sending %d samples at time: %ld\n", nsamps, timestamp);
+
for (int i=0; ibuf[i];
+ buffer_t *b=&t->buf[i];
- if (ptr->conn_sock >= 0 ) {
+ if (b->conn_sock >= 0 ) {
+ if ( abs((double)b->lastWroteTS-timestamp) > (double)CirSize)
+ LOG_E(HW,"Tx/Rx shift too large Tx:%lu, Rx:%lu\n", b->lastWroteTS, b->lastReceivedTS);
samplesBlockHeader_t header= {t->typeStamp, nsamps, nbAnt, timestamp};
- fullwrite(ptr->conn_sock,&header, sizeof(header), t);
+ fullwrite(b->conn_sock,&header, sizeof(header), t);
sample_t tmpSamples[nsamps][nbAnt];
for(int a=0; aconn_sock >= 0 )
- fullwrite(ptr->conn_sock, (void *)tmpSamples, sampleToByte(nsamps,nbAnt), t);
+ if (b->conn_sock >= 0 ) {
+ fullwrite(b->conn_sock, (void *)tmpSamples, sampleToByte(nsamps,nbAnt), t);
+ b->lastWroteTS=timestamp+nsamps;
+ }
}
}
- lastW=timestamp;
LOG_D(HW,"sent %d samples at time: %ld->%ld, energy in first antenna: %d\n",
nsamps, timestamp, timestamp+nsamps, signal_energy(samplesVoid[0], nsamps) );
// Let's verify we don't have incoming data
// This is mandatory when the opposite side don't transmit
- // This is mandatory when the opposite side don't transmit
flushInput(t, 0);
pthread_mutex_unlock(&Sockmutex);
return nsamps;
@@ -428,7 +426,6 @@ static bool flushInput(rfsimulator_state_t *t, int timeout) {
AssertFatal( (t->typeStamp == UE_MAGICDL_FDD && b->th.magic==ENB_MAGICDL_FDD) ||
(t->typeStamp == ENB_MAGICDL_FDD && b->th.magic==UE_MAGICDL_FDD), "Socket Error in protocol");
b->headerMode=false;
- b->alreadyRead=true;
if ( b->lastReceivedTS != b->th.timestamp) {
int nbAnt= b->th.nbAnt;
@@ -444,8 +441,8 @@ static bool flushInput(rfsimulator_state_t *t, int timeout) {
}
b->lastReceivedTS=b->th.timestamp;
- AssertFatal(lastW == -1 || ( abs((double)lastW-b->lastReceivedTS) < (double)CirSize),
- "Tx/Rx shift too large Tx:%lu, Rx:%lu\n", lastW, b->lastReceivedTS);
+ AssertFatal(b->lastWroteTS == 0 || ( abs((double)b->lastWroteTS-b->lastReceivedTS) < (double)CirSize),
+ "Tx/Rx shift too large Tx:%lu, Rx:%lu\n", b->lastWroteTS, b->lastReceivedTS);
b->transferPtr=(char *)&b->circularBuf[b->lastReceivedTS%CirSize];
b->remainToTransfer=sampleToByte(b->th.size, b->th.nbAnt);
}
@@ -501,15 +498,33 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo
return nsamps;
}
} else {
+
bool have_to_wait;
do {
have_to_wait=false;
for ( int sock=0; sockbuf[sock].circularBuf && t->buf[sock].alreadyRead )
- if ( t->buf[sock].lastReceivedTS == 0 ||
- (t->nextTimestamp+nsamps) > t->buf[sock].lastReceivedTS ) {
+ buffer_t *b=&t->buf[sock];
+ if ( b->circularBuf) {
+ LOG_D(HW,"sock: %d, lastWroteTS: %lu, lastRecvTS: %lu, TS must be avail: %lu\n",
+ sock, b->lastWroteTS,
+ b->lastReceivedTS,
+ t->nextTimestamp+nsamps);
+ if ( b->lastReceivedTS > b->lastWroteTS ) {
+ // The caller momdem (NB, UE, ...) must send Tx in advance, so we fill TX if Rx is in advance
+ // This occurs for example when UE is in sync mode: it doesn't transmit
+ // with USRP, it seems ok: if "tx stream" is off, we may consider it actually cuts the Tx power
+ struct complex16 v={0};
+ void *samplesVoid[b->th.nbAnt];
+ for ( int i=0; i th.nbAnt; i++)
+ samplesVoid[i]=(void*)&v;
+ rfsimulator_write(device, b->lastReceivedTS, samplesVoid, 1, b->th.nbAnt, 0);
+ }
+ }
+
+ if ( b->circularBuf )
+ if ( t->nextTimestamp+nsamps > b->lastReceivedTS ) {
have_to_wait=true;
break;
}
@@ -532,7 +547,7 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo
for (int sock=0; sockbuf[sock];
- if ( ptr->circularBuf && ptr->alreadyRead ) {
+ if ( ptr->circularBuf ) {
bool reGenerateChannel=false;
//fixme: when do we regenerate
diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c
index 3105b7c8554e6197086930f410f0c87b50a75585..76016ba0a654888c5ee14b75c9fc11ec7948e91a 100644
--- a/targets/RT/USER/lte-enb.c
+++ b/targets/RT/USER/lte-enb.c
@@ -635,15 +635,12 @@ void wakeup_prach_eNB(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe) {
AssertFatal((ret=pthread_mutex_lock(&proc->mutex_RU_PRACH))==0,"mutex_lock return %d\n",ret);
for (i=0; inum_RU; i++) {
- if (ru == eNB->RU_list[i]) {
- LOG_D(PHY,"frame %d, subframe %d: RU %d for eNB %d signals PRACH (mask %x, num_RU %d)\n",frame,subframe,i,eNB->Mod_id,proc->RU_mask_prach,eNB->num_RU);
-
- if ((proc->RU_mask_prach&(1< 0)
- LOG_E(PHY,"eNB %d frame %d, subframe %d : previous information (PRACH) from RU %d (num_RU %d, mask %x) has not been served yet!\n",
- eNB->Mod_id,frame,subframe,ru->idx,eNB->num_RU,proc->RU_mask_prach);
-
- proc->RU_mask_prach |= (1<RU_list[i] && eNB->RU_list[i]->wait_cnt == 0) {
+ LOG_D(PHY,"frame %d, subframe %d: RU %d for eNB %d signals PRACH (mask %x, num_RU %d)\n",frame,subframe,i,eNB->Mod_id,proc->RU_mask_prach,eNB->num_RU);
+ proc->RU_mask_prach |= (1<RU_list[i]->state == RU_SYNC || eNB->RU_list[i]->wait_cnt > 0) {
+ proc->RU_mask_prach |= (1<RU_mask_prach != (1<num_RU)-1) { // not all RUs have provided their information so return
diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c
index 8ed220da8e8f5293f5f22ace0a0014c8ea5b6932..3ec08ac7b44e30e72b61039d43cdfaa815602a01 100644
--- a/targets/RT/USER/lte-ru.c
+++ b/targets/RT/USER/lte-ru.c
@@ -217,6 +217,7 @@ void fh_if4p5_south_in(RU_t *ru,int *frame,int *subframe) {
if (proc->symbol_mask[*subframe]==0) { // this is normal case, if not true then we received a PULTICK before the previous subframe was finished
do {
recv_IF4p5(ru, &f, &sf, &packet_type, &symbol_number);
+ LOG_D(PHY,"fh_if4p5_south_in: RU %d, frame %d, subframe %d, f %d, sf %d\n",ru->idx,*frame,*subframe,f,sf);
if (oai_exit == 1 || ru->cmd== STOP_RU) break;
if (packet_type == IF4p5_PULFFT) proc->symbol_mask[sf] = proc->symbol_mask[sf] | (1<symbol_mask[*subframe]);
- } while(proc->symbol_mask[*subframe] != symbol_mask_full);
+ LOG_D(PHY,"rx_fh_if4p5 for RU %d: subframe %d, sf %d, symbol mask %x\n",ru->idx,*subframe,sf,proc->symbol_mask[sf]);
+ } while(proc->symbol_mask[sf] != symbol_mask_full);
}
else {
f = *frame;
@@ -437,10 +438,13 @@ void fh_if4p5_north_asynch_in(RU_t *ru,int *frame,int *subframe) {
proc->first_tx = 0;
symbol_mask_full = ((subframe_select(fp,*subframe) == SF_S) ? (1<dl_symbols_in_S_subframe) : (1<symbols_per_tti))-1;
} else {
- AssertFatal(frame_tx == *frame,
+ /* AssertFatal(frame_tx == *frame,
"frame_tx %d is not what we expect %d\n",frame_tx,*frame);
AssertFatal(subframe_tx == *subframe,
"In frame_tx %d : subframe_tx %d is not what we expect %d\n",frame_tx,subframe_tx,*subframe);
+ */
+ *frame = frame_tx;
+ *subframe = subframe_tx;
}
if (packet_type == IF4p5_PDLFFT) {
@@ -1661,7 +1665,7 @@ void *ru_thread( void *param ) {
proc->instance_cnt_asynch_rxtx=0;
pthread_cond_signal(&proc->cond_asynch_rxtx);
AssertFatal((ret=pthread_mutex_unlock(&proc->mutex_asynch_rxtx))==0,"mutex_unlock returns %d\n",ret);
- } else LOG_I(PHY,"RU %d no asynch_south interface\n",ru->idx);
+ } else LOG_D(PHY,"RU %d no asynch_south interface\n",ru->idx);
// if this is a slave RRU, try to synchronize on the DL frequency
if ((ru->is_slave == 1) && (ru->if_south == LOCAL_RF)) do_ru_synch(ru);
@@ -1872,7 +1876,8 @@ void *ru_thread_synch(void *arg) {
&avg);
LOG_I(PHY,"RU synch cnt %d: %d, val %llu (%d dB,%d dB)\n",cnt,ru->rx_offset,(unsigned long long)peak_val,dB_fixed64(peak_val),dB_fixed64(avg));
cnt++;
- if (/*ru->rx_offset >= 0*/dB_fixed(peak_val)>=85 && cnt>10) {
+ //if (/*ru->rx_offset >= 0*/dB_fixed(peak_val)>=85 && cnt>10) {
+ if (ru->rx_offset >= 0 && avg>0 && dB_fixed(peak_val/avg)>=15 && cnt>10) {
LOG_I(PHY,"Estimated peak_val %d dB, avg %d => timing offset %llu\n",dB_fixed(peak_val),dB_fixed(avg),(unsigned long long int)ru->rx_offset);
ru->in_synch = 1;
/*
@@ -2628,7 +2633,7 @@ void init_RU(char *rf_config_file, clock_source_t clock_source,clock_source_t ti
// NOTE: multiple CC_id are not handled here yet!
ru->openair0_cfg.clock_source = clock_source;
ru->openair0_cfg.time_source = time_source;
-// ru->generate_dmrs_sync = (ru->is_slave == 0) ? 1 : 0;
+ ru->generate_dmrs_sync = (ru->is_slave == 0) ? 1 : 0;
if (ru->generate_dmrs_sync == 1) {
generate_ul_ref_sigs();
ru->dmrssync = (int16_t*)malloc16_clear(ru->frame_parms.ofdm_symbol_size*2*sizeof(int16_t));
@@ -2919,6 +2924,8 @@ void RCconfig_RU(void) {
RC.ru[j]->max_pdschReferenceSignalPower = *(RUParamList.paramarray[j][RU_MAX_RS_EPRE_IDX].uptr);;
RC.ru[j]->max_rxgain = *(RUParamList.paramarray[j][RU_MAX_RXGAIN_IDX].uptr);
RC.ru[j]->num_bands = RUParamList.paramarray[j][RU_BAND_LIST_IDX].numelt;
+ /* sf_extension is in unit of samples for 30.72MHz here, has to be scaled later */
+ RC.ru[j]->sf_extension = *(RUParamList.paramarray[j][RU_SF_EXTENSION_IDX].uptr);
for (i=0;inum_bands;i++) RC.ru[j]->band[i] = RUParamList.paramarray[j][RU_BAND_LIST_IDX].iptr[i];
} //strcmp(local_rf, "yes") == 0
else {