[0-9\-]+) *bytes', mySSH.getBefore())
+ if result is not None:
+ imageSize = float(result.group('size'))
+ imageSize = imageSize / 1000
+ if imageSize < 1000:
+ logging.debug('\u001B[1m oai-physim size is ' + ('%.0f' % imageSize) + ' kbytes\u001B[0m')
+ else:
+ imageSize = imageSize / 1000
+ if imageSize < 1000:
+ logging.debug('\u001B[1m oai-physim size is ' + ('%.0f' % imageSize) + ' Mbytes\u001B[0m')
+ else:
+ imageSize = imageSize / 1000
+ logging.debug('\u001B[1m oai-physim is ' + ('%.3f' % imageSize) + ' Gbytes\u001B[0m')
+ else:
+ logging.debug('oai-physim size is unknown')
+
+ # logging to OC Cluster and then switch to corresponding project
+ mySSH.command(f'oc login -u {ocUserName} -p {ocPassword}', '\$', 6)
+ if mySSH.getBefore().count('Login successful.') == 0:
+ logging.error('\u001B[1m OC Cluster Login Failed\u001B[0m')
+ mySSH.close()
+ sys.exit(-1)
+ else:
+ logging.debug('\u001B[1m Login to OC Cluster Successfully\u001B[0m')
+ mySSH.command(f'oc project {ocProjectName}', '\$', 6)
+ if mySSH.getBefore().count(f'Already on project "{ocProjectName}"') == 0 and mySSH.getBefore().count(f'Now using project "{self.OCProjectName}"') == 0:
+ logging.error(f'\u001B[1m Unable to access OC project {ocProjectName}\u001B[0m')
+ mySSH.close()
+ sys.exit(-1)
+ else:
+ logging.debug(f'\u001B[1m Now using project {ocProjectName}\u001B[0m')
+
+ # Tag the image and push to the OC cluster
+ mySSH.command('oc whoami -t | sudo podman login -u ' + ocUserName + ' --password-stdin https://default-route-openshift-image-registry.apps.5glab.nsa.eurecom.fr/ --tls-verify=false', '\$', 6)
+ if mySSH.getBefore().count('Login Succeeded!') == 0:
+ logging.error('\u001B[1m Podman Login to OC Cluster Registry Failed\u001B[0m')
+ mySSH.close()
+ sys.exit(-1)
+ else:
+ logging.debug('\u001B[1m Podman Login to OC Cluster Registry Successfully\u001B[0m')
+ time.sleep(2)
+ mySSH.command('oc create -f openshift/oai-physim-image-stream.yml', '\$', 6)
+ if mySSH.getBefore().count('(AlreadyExists):') == 0 and mySSH.getBefore().count('created') == 0:
+ logging.error(f'\u001B[1m Image Stream "oai-physim" Creation Failed on OC Cluster {ocProjectName}\u001B[0m')
+ mySSH.close()
+ sys.exit(-1)
+ else:
+ logging.debug(f'\u001B[1m Image Stream "oai-physim" created on OC project {ocProjectName}\u001B[0m')
+ time.sleep(2)
+ mySSH.command(f'sudo podman tag oai-physim:{imageTag} default-route-openshift-image-registry.apps.5glab.nsa.eurecom.fr/{self.OCProjectName}/oai-physim:{imageTag}', '\$', 6)
+ time.sleep(2)
+ mySSH.command(f'sudo podman push default-route-openshift-image-registry.apps.5glab.nsa.eurecom.fr/{self.OCProjectName}/oai-physim:{imageTag} --tls-verify=false', '\$', 30)
+ if mySSH.getBefore().count('Storing signatures') == 0:
+ logging.error('\u001B[1m Image "oai-physim" push to OC Cluster Registry Failed\u001B[0m')
+ mySSH.close()
+ sys.exit(-1)
+ else:
+ logging.debug('\u001B[1m Image "oai-physim" push to OC Cluster Registry Successfully\u001B[0m')
+
+ # Using helm charts deployment
+ time.sleep(5)
+ mySSH.command(f'sed -i -e "s#TAG#{imageTag}#g" ./charts/physims/values.yaml', '\$', 6)
+ mySSH.command('helm install physim ./charts/physims/ | tee -a cmake_targets/log/physim_helm_summary.txt 2>&1', '\$', 6)
+ if mySSH.getBefore().count('STATUS: deployed') == 0:
+ logging.error('\u001B[1m Deploying PhySim Failed using helm chart on OC Cluster\u001B[0m')
+ mySSH.command('helm uninstall physim >> cmake_targets/log/physim_helm_summary.txt 2>&1', '\$', 6)
+ mySSH.close()
+ self.AnalyzeLogFile_phySim(HTML)
+ sys.exit(-1)
+ else:
+ logging.debug('\u001B[1m Deployed PhySim Successfully using helm chart\u001B[0m')
+ isRunning = False
+ count = 0
+ while(count < 2 and isRunning == False):
+ time.sleep(60)
+ mySSH.command('oc get pods -o wide -l app.kubernetes.io/instance=physim | tee -a cmake_targets/log/physim_pods_summary.txt', '\$', 6, resync=True)
+ if mySSH.getBefore().count('Running') == 12:
+ logging.debug('\u001B[1m Running the physim test Scenarios\u001B[0m')
+ isRunning = True
+ podNames = re.findall('oai-[\S\d\w]+', mySSH.getBefore())
+ count +=1
+ if isRunning == False:
+ logging.error('\u001B[1m Some PODS Running FAILED \u001B[0m')
+ mySSH.command('oc get pods -l app.kubernetes.io/instance=physim 2>&1 | tee -a cmake_targets/log/physim_pods_summary.txt', '\$', 6)
+ mySSH.command('helm uninstall physim >> cmake_targets/log/physim_helm_summary.txt 2>&1', '\$', 6)
+ self.AnalyzeLogFile_phySim(HTML)
+ sys.exit(-1)
+ # Waiting to complete the running test
+ count = 0
+ isFinished = False
+ # doing a deep copy!
+ tmpPodNames = podNames.copy()
+ while(count < 28 and isFinished == False):
+ time.sleep(60)
+ for podName in tmpPodNames:
+ mySSH.command2(f'oc logs --tail=1 {podName} 2>&1', 6, silent=True)
+ if mySSH.cmd2Results.count('FINISHED') != 0:
+ logging.debug(podName + ' is finished')
+ tmpPodNames.remove(podName)
+ if not tmpPodNames:
+ isFinished = True
+ count += 1
+ if isFinished:
+ logging.debug('\u001B[1m PhySim test is Complete\u001B[0m')
+
+ # Getting the logs of each executables running in individual pods
+ for podName in podNames:
+ mySSH.command(f'oc logs {podName} >> cmake_targets/log/physim_test.txt 2>&1', '\$', 15, resync=True)
+ time.sleep(30)
+
+ # UnDeploy the physical simulator pods
+ mySSH.command('helm uninstall physim | tee -a cmake_targets/log/physim_helm_summary.txt 2>&1', '\$', 6)
+ isFinished1 = False
+ while(isFinished1 == False):
+ time.sleep(20)
+ mySSH.command('oc get pods -l app.kubernetes.io/instance=physim', '\$', 6, resync=True)
+ if re.search('No resources found', mySSH.getBefore()):
+ isFinished1 = True
+ if isFinished1 == True:
+ logging.debug('\u001B[1m UnDeployed PhySim Successfully on OC Cluster\u001B[0m')
+ mySSH.command(f'sudo podman rmi default-route-openshift-image-registry.apps.5glab.nsa.eurecom.fr/{self.OCProjectName}/oai-physim:{imageTag}', '\$', 6)
+ mySSH.command('oc delete is oai-physim', '\$', 6)
+ logging.debug('\u001B[1m Deleted the Image and ImageStream\u001B[0m')
+ mySSH.command('oc logout', '\$', 6)
+ mySSH.close()
+ self.AnalyzeLogFile_phySim(HTML)
+ if self.testStatus == False:
+ sys.exit(-1)
+
+ def AnalyzeLogFile_phySim(self, HTML):
+ lIpAddr = self.eNBIPAddress
+ lUserName = self.eNBUserName
+ lPassWord = self.eNBPassword
+ lSourcePath = self.eNBSourceCodePath
+ mySSH = SSH.SSHConnection()
+ mySSH.open(lIpAddr, lUserName, lPassWord)
+ mySSH.command('cd ' + lSourcePath, '\$', 5)
+ 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)
+ 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)
+ mySSH.command('rm -rf ./physim_test_log_'+ self.testCase_id, '\$', 5)
+ mySSH.command('oc logout', '\$', 6)
+ mySSH.close()
+ # physim test log analysis
+ nextt = 0
+ if (os.path.isfile(f'./physim_test_logs_{self.testCase_id}/physim_test.txt')):
+ with open(f'./physim_test_logs_{self.testCase_id}/physim_test.txt', 'r') as logfile:
+ for line in logfile:
+ if re.search('execution 015', str(line)) or re.search('Bypassing compilation', str(line)):
+ nextt = 1
+ elif nextt == 1:
+ if not re.search('Test Results', str(line)):
+ nextt = 0
+ ret2 = re.search('T[^\n]*', str(line))
+ if ret2 is not None:
+ ret3 = ret2.group()
+ ret3 = ret3.replace("[00m", "")
+ if re.search('execution 015', str(line)):
+ self.testCount[0] += 1
+ testName = line.split()
+ ret1 = re.search('Result = PASS', str(line))
+ if ret1 is not None:
+ self.testResult[testName[1]] = [ret3, 'PASS']
+ self.testCount[1] += 1
+ else:
+ self.testResult[testName[1]] = [ret3, 'FAIL']
+ self.testCount[2] += 1
+ self.testSummary['Nbtests'] = self.testCount[0]
+ self.testSummary['Nbpass'] = self.testCount[1]
+ self.testSummary['Nbfail'] = self.testCount[2]
+ if self.testSummary['Nbfail'] == 0:
+ self.testStatus = True
+ HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
+ HTML.CreateHtmlTestRowPhySimTestResult(self.testSummary,self.testResult)
+ logging.info('\u001B[1m Physical Simulator Pass\u001B[0m')
+ return 0
diff --git a/ci-scripts/conf_files/benetel-5g.conf b/ci-scripts/conf_files/benetel-5g.conf
index 5788cd9b36..9adead3a68 100644
--- a/ci-scripts/conf_files/benetel-5g.conf
+++ b/ci-scripts/conf_files/benetel-5g.conf
@@ -66,17 +66,7 @@ gNBs =
initialDLBWPk0_1 = 0; #for mixed slot
initialDLBWPmappingType_1 = 0;
- initialDLBWPstartSymbolAndLength_1 = 53; #this is SS=1,L=5
-
- initialDLBWPk0_2 = 0;
- initialDLBWPmappingType_2 = 0;
- #this is SS=1,L=12
- initialDLBWPstartSymbolAndLength_2 = 54;
-
- initialDLBWPk0_3 = 0;
- initialDLBWPmappingType_3 = 0;
- #this is SS=1,L=4 //5 (4 is for 43, 5 is for 57)
- initialDLBWPstartSymbolAndLength_3 = 57; //43; //57;
+ initialDLBWPstartSymbolAndLength_1 = 57; #this is SS=1,L=5
#uplinkConfigCommon
#frequencyInfoUL
@@ -102,6 +92,8 @@ gNBs =
prach_msg1_FDM = 0;
prach_msg1_FrequencyStart = 74;
zeroCorrelationZoneConfig = 13;
+ #preambleReceivedTargetPower = -118;
+ #preambleReceivedTargetPower = -104;
preambleReceivedTargetPower = -108;
#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
preambleTransMax = 6;
diff --git a/ci-scripts/conf_files/gnb.band261.tm1.32PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.band261.tm1.32PRB.usrpn300.conf
index f0c1caef7e..8fbbc8a7cd 100644
--- a/ci-scripts/conf_files/gnb.band261.tm1.32PRB.usrpn300.conf
+++ b/ci-scripts/conf_files/gnb.band261.tm1.32PRB.usrpn300.conf
@@ -230,6 +230,7 @@ MACRLCs = (
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
+ ulsch_max_slots_inactivity = 1;
}
);
diff --git a/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf
index f125dcd3b2..4afbfdcda0 100644
--- a/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf
+++ b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf
@@ -211,6 +211,7 @@ MACRLCs = (
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
+ ulsch_max_slots_inactivity = 1;
}
);
@@ -231,7 +232,7 @@ RUs = (
att_rx = 0;
bands = [7];
max_pdschReferenceSignalPower = -27;
- max_rxgain = 75;
+ max_rxgain = 50;
eNB_instances = [0];
## beamforming 1x2 matrix: 1 layer x 2 antennas
bf_weights = [0x00007fff, 0x0000];
diff --git a/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpn310.conf b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpn310.conf
index 809203f672..a078ff127c 100644
--- a/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpn310.conf
+++ b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpn310.conf
@@ -61,24 +61,15 @@ gNBs =
initialDLBWPk0_0 = 0;
#initialULBWPmappingType
#0=typeA,1=typeB
- initialDLBWPmappingType_0 = 0;
+ initialDLBWPmappingType_0 = 0;#for DL slot
#this is SS=1,L=13
initialDLBWPstartSymbolAndLength_0 = 40;
- initialDLBWPk0_1 = 0;
+ initialDLBWPk0_1 = 0;#for mixed slot
initialDLBWPmappingType_1 = 0;
- #this is SS=2,L=12
- initialDLBWPstartSymbolAndLength_1 = 53;
+ #this is SS=1,L=5
+ initialDLBWPstartSymbolAndLength_1 = 57;
- initialDLBWPk0_2 = 0;
- initialDLBWPmappingType_2 = 0;
- #this is SS=1,L=12
- initialDLBWPstartSymbolAndLength_2 = 54;
-
- initialDLBWPk0_3 = 0;
- initialDLBWPmappingType_3 = 0;
- #this is SS=1,L=4 //5 (4 is for 43, 5 is for 57)
- initialDLBWPstartSymbolAndLength_3 = 57; //43; //57;
#uplinkConfigCommon
#frequencyInfoUL
ul_frequencyBand = 78;
@@ -103,7 +94,7 @@ gNBs =
prach_msg1_FDM = 0;
prach_msg1_FrequencyStart = 0;
zeroCorrelationZoneConfig = 13;
- preambleReceivedTargetPower = -100;
+ preambleReceivedTargetPower = -90;
#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
preambleTransMax = 6;
#powerRampingStep
@@ -188,7 +179,7 @@ gNBs =
nrofUplinkSlots = 2;
nrofUplinkSymbols = 4; //0; //4;
- ssPBCH_BlockPower = -25;
+ ssPBCH_BlockPower = -15;
}
);
diff --git a/ci-scripts/createVM.sh b/ci-scripts/createVM.sh
index ab859c10d7..f3f8ddaca2 100755
--- a/ci-scripts/createVM.sh
+++ b/ci-scripts/createVM.sh
@@ -87,7 +87,7 @@ function create_vm {
echo "VM_CPU = $VM_CPU"
echo "VM_DISK = $VM_DISK GBytes"
- if [[ "$VM_NAME" == *"-enb-usrp"* ]] || [[ "$VM_NAME" == *"-cppcheck"* ]]
+ if [[ "$VM_NAME" == *"-enb-usrp"* ]] || [[ "$VM_NAME" == *"-cppcheck"* ]] || [[ "$VM_NAME" == *"-phy-sim"* ]]
then
echo "This VM type is no longer supported in the pipeline framework"
return
diff --git a/ci-scripts/datalog_rt_stats.yaml b/ci-scripts/datalog_rt_stats.yaml
new file mode 100644
index 0000000000..3680d2a19b
--- /dev/null
+++ b/ci-scripts/datalog_rt_stats.yaml
@@ -0,0 +1,33 @@
+#this is a configuration file
+#used to build real time processing statistics
+#for 5G NR phy test (gNB terminate)
+Title : Processing Time (us)
+ColNames :
+ - Metric
+ - Average
+ - Max
+ - Average vs Reference Deviation (Reference Value ; Acceptability Threshold)
+Ref :
+ feprx : 60.0
+ feptx_prec : 8.0
+ feptx_ofdm : 85.0
+ feptx_total : 75.0
+ L1 Tx processing : 300.0
+ DLSCH encoding : 230.0
+ L1 Rx processing : 175.0
+ PUSCH inner-receiver : 100.0
+ PUSCH decoding : 140.0
+ DL & UL scheduling timing stats : 15.0
+ UL Indication : 20.0
+Threshold :
+ feprx : 1.25
+ feptx_prec : 1.25
+ feptx_ofdm : 1.25
+ feptx_total : 1.25
+ L1 Tx processing : 1.25
+ DLSCH encoding : 1.25
+ L1 Rx processing : 1.25
+ PUSCH inner-receiver : 1.25
+ PUSCH decoding : 1.25
+ DL & UL scheduling timing stats : 1.25
+ UL Indication : 1.25
diff --git a/ci-scripts/html.py b/ci-scripts/html.py
index a0ac638573..de4e049adb 100644
--- a/ci-scripts/html.py
+++ b/ci-scripts/html.py
@@ -47,7 +47,7 @@ import constants as CONST
class HTMLManagement():
def __init__(self):
-
+
self.htmlFile = ''
self.htmlHeaderCreated = False
self.htmlFooterCreated = False
@@ -86,13 +86,13 @@ class HTMLManagement():
#-----------------------------------------------------------
# Setters and Getters
#-----------------------------------------------------------
-
+
def SethtmlUEConnected(self, nbUEs):
if nbUEs > 0:
self.htmlUEConnected = nbUEs
else:
self.htmlUEConnected = 1
-
+
#-----------------------------------------------------------
@@ -412,7 +412,12 @@ class HTMLManagement():
for image in collectInfo:
files = collectInfo[image]
# TabHeader for image logs on built shared and target images
- self.htmlFile.write(' \n')
+ if allImagesSize[image].count('unknown') > 0:
+ self.htmlFile.write(' \n')
+ elif allImagesSize[image].count('Build Failed') > 0:
+ self.htmlFile.write(' \n')
+ else:
+ self.htmlFile.write(' \n')
self.htmlFile.write(' ---- ' + image + ' IMAGE STATUS ----> Size ' + allImagesSize[image] + ' \n')
self.htmlFile.write(' \n')
self.htmlFile.write(' \n')
@@ -431,21 +436,54 @@ class HTMLManagement():
self.htmlFile.write(' ' + str(parameters['errors']) + ' \n')
else:
self.htmlFile.write(' ' + str(parameters['errors']) + ' \n')
- if (parameters['warnings'] == 0):
+ if (parameters['errors'] > 0):
+ self.htmlFile.write(' ' + str(parameters['warnings']) + ' \n')
+ elif (parameters['warnings'] == 0):
self.htmlFile.write(' ' + str(parameters['warnings']) + ' \n')
elif ((parameters['warnings'] > 0) and (parameters['warnings'] <= 20)):
self.htmlFile.write(' ' + str(parameters['warnings']) + ' \n')
else:
- self.htmlFile.write(' ' + str(parameters['warnings']) + ' \n')
+ self.htmlFile.write(' ' + str(parameters['warnings']) + ' \n')
if (parameters['errors'] == 0) and (parameters['warnings'] == 0):
self.htmlFile.write(' OK \n')
elif (parameters['errors'] == 0) and ((parameters['warnings'] > 0) and (parameters['warnings'] <= 20)):
self.htmlFile.write(' OK \n')
else:
- self.htmlFile.write(' NOT OK \n')
+ self.htmlFile.write(' NOT OK \n')
self.htmlFile.write(' \n')
self.htmlFile.close()
+ #for the moment it is limited to 4 columns, to be made generic later
+ def CreateHtmlDataLogTable(self, DataLog):
+ if (self.htmlFooterCreated or (not self.htmlHeaderCreated)):
+ return
+ self.htmlFile = open('test_results.html', 'a')
+
+ # TabHeader
+ self.htmlFile.write(' \n')
+ self.htmlFile.write(' ---- ' + DataLog['Title'] + ' ---- \n')
+ self.htmlFile.write(' \n')
+ self.htmlFile.write(' \n')
+ self.htmlFile.write(' '+ DataLog['ColNames'][0] +' \n')
+ self.htmlFile.write(' ' + DataLog['ColNames'][1] + ' \n')
+ self.htmlFile.write(' ' + DataLog['ColNames'][2] + ' \n')
+ self.htmlFile.write(' '+ DataLog['ColNames'][3] +' \n')
+ self.htmlFile.write(' \n')
+
+ for k in DataLog['Data']:
+ # TestRow
+ self.htmlFile.write(' \n')
+ self.htmlFile.write(' ' + k + ' \n')
+ self.htmlFile.write(' ' + DataLog['Data'][k][0] + ' \n')
+ self.htmlFile.write(' ' + DataLog['Data'][k][1] + ' \n')
+ if float(DataLog['Data'][k][2])> DataLog['Threshold'][k]:
+ self.htmlFile.write(' ' + DataLog['Data'][k][2] + ' (Ref = ' + str(DataLog['Ref'][k]) + ' ; Thres = ' +str(DataLog['Threshold'][k])+') ' + ' \n')
+ else:
+ self.htmlFile.write(' ' + DataLog['Data'][k][2] + ' (Ref = ' + str(DataLog['Ref'][k]) + ' ; Thres = ' +str(DataLog['Threshold'][k])+') ' + ' \n')
+ self.htmlFile.write(' \n')
+ self.htmlFile.close()
+
+
def CreateHtmlTestRowQueue(self, options, status, ue_status, ue_queue):
if ((not self.htmlFooterCreated) and (self.htmlHeaderCreated)):
self.htmlFile = open('test_results.html', 'a')
@@ -562,5 +600,57 @@ class HTMLManagement():
self.htmlFile.write(' ' + str(CCR.nbWrongScanfArg[vId]) + ' \n')
self.htmlFile.write(' \n')
vId += 1
-
+
+ def CreateHtmlTestRowPhySimTestResult(self, testSummary, testResult):
+ if (self.htmlFooterCreated or (not self.htmlHeaderCreated)):
+ return
+ self.htmlFile = open('test_results.html', 'a')
+ if bool(testResult) == False and bool(testSummary) == False:
+ self.htmlFile.write(' \n')
+ self.htmlFile.write(' ----PHYSIM TESTING FAILED - Unable to recover the test logs ---- \n')
+ self.htmlFile.write(' \n')
+ else:
+ # Tab header
+ self.htmlFile.write(' \n')
+ self.htmlFile.write(' ---- PHYSIM TEST SUMMARY---- \n')
+ self.htmlFile.write(' \n')
+ self.htmlFile.write(' \n')
+ self.htmlFile.write(' LogFile Name \n')
+ self.htmlFile.write(' Nb Tests \n')
+ self.htmlFile.write(' Nb Failure \n')
+ self.htmlFile.write(' Nb Pass \n')
+ self.htmlFile.write(' \n')
+ self.htmlFile.write(' \n')
+ self.htmlFile.write(' physim_test.txt \n')
+ self.htmlFile.write(' ' + str(testSummary['Nbtests']) + ' \n')
+ if testSummary['Nbfail'] == 0:
+ self.htmlFile.write(' ' + str(testSummary['Nbfail']) + ' \n')
+ else:
+ self.htmlFile.write(' ' + str(testSummary['Nbfail']) + ' \n')
+ self.htmlFile.write(' ' + str(testSummary['Nbpass']) + ' \n')
+ self.htmlFile.write(' \n')
+ self.htmlFile.write(' \n')
+ self.htmlFile.write(' ---- PHYSIM TEST DETAIL INFO---- \n')
+ self.htmlFile.write(' \n')
+ self.htmlFile.write(' \n')
+ self.htmlFile.write(' Test Name \n')
+ self.htmlFile.write(' Test Description \n')
+ self.htmlFile.write(' Result \n')
+ self.htmlFile.write(' \n')
+ y = ''
+ for key, value in testResult.items():
+ x = key.split(".")
+ if x[0] != y:
+ self.htmlFile.write(' \n')
+ self.htmlFile.write(' "' + x[0] + '" series \n')
+ self.htmlFile.write(' \n')
+ y = x[0]
+ self.htmlFile.write(' \n')
+ self.htmlFile.write(' ' + key + ' \n')
+ self.htmlFile.write(' ' + value[0] + ' \n')
+ if 'PASS' in value:
+ self.htmlFile.write(' ' + value[1] + ' \n')
+ else:
+ self.htmlFile.write(' ' + value[1] + ' \n')
+
self.htmlFile.close()
diff --git a/ci-scripts/main.py b/ci-scripts/main.py
index f13df9beb5..389e7f8614 100644
--- a/ci-scripts/main.py
+++ b/ci-scripts/main.py
@@ -43,7 +43,8 @@ import cls_physim #class PhySim for physical simulators build and
import cls_cots_ue #class CotsUe for Airplane mode control
import cls_containerize #class Containerize for all container-based operations on RAN/UE objects
import cls_static_code_analysis #class for static code analysis
-
+import cls_ci_ueinfra #class defining the multi Ue infrastrucure
+import cls_physim1 #class PhySim for physical simulators deploy and run
import sshconnection
import epc
@@ -193,6 +194,20 @@ def GetParametersFromXML(action):
else :
RAN.air_interface[RAN.eNB_instance] = 'ocp-enb'
+ elif action == 'Initialize_UE':
+ ue_id = test.findtext('id')
+ if (ue_id is None):
+ CiTestObj.ue_id = ""
+ else:
+ CiTestObj.ue_id = ue_id
+
+ elif action == 'Detach_UE':
+ ue_id = test.findtext('id')
+ if (ue_id is None):
+ CiTestObj.ue_id = ""
+ else:
+ CiTestObj.ue_id = ue_id
+
elif action == 'Attach_UE':
nbMaxUEtoAttach = test.findtext('nbMaxUEtoAttach')
if (nbMaxUEtoAttach is None):
@@ -253,9 +268,20 @@ def GetParametersFromXML(action):
elif (action == 'Ping') or (action == 'Ping_CatM_module'):
CiTestObj.ping_args = test.findtext('ping_args')
CiTestObj.ping_packetloss_threshold = test.findtext('ping_packetloss_threshold')
+ ue_id = test.findtext('id')
+ if (ue_id is None):
+ CiTestObj.ue_id = ""
+ else:
+ CiTestObj.ue_id = ue_id
elif action == 'Iperf':
CiTestObj.iperf_args = test.findtext('iperf_args')
+ ue_id = test.findtext('id')
+ if (ue_id is None):
+ CiTestObj.ue_id = ""
+ else:
+ CiTestObj.ue_id = ue_id
+ CiTestObj.iperf_direction = test.findtext('direction')#used for modules only
CiTestObj.iperf_packetloss_threshold = test.findtext('iperf_packetloss_threshold')
CiTestObj.iperf_profile = test.findtext('iperf_profile')
if (CiTestObj.iperf_profile is None):
@@ -370,6 +396,20 @@ with open(yaml_file,'r') as f:
+#loading UE infrastructure from yaml
+ue_infra_file='ci_ueinfra.yaml'
+if (os.path.isfile(ue_infra_file)):
+ yaml_file=ue_infra_file
+elif (os.path.isfile('ci-scripts/'+ue_infra_file)):
+ yaml_file='ci-scripts/'+ue_infra_file
+else:
+ logging.error("UE infrastructure yaml file cannot be found")
+ sys.exit("UE infrastructure file cannot be found")
+InfraUE=cls_ci_ueinfra.InfraUE() #initialize UE infrastructure class
+InfraUE.Get_UE_Infra(yaml_file) #read the UE infra, filename is hardcoded and unique for the moment but should be passed as parameter from the test suite
+
+
+
mode = ''
CiTestObj = cls_oaicitest.OaiCiTest()
@@ -380,17 +420,17 @@ RAN = ran.RANManagement()
HTML = html.HTMLManagement()
CONTAINERS = cls_containerize.Containerize()
SCA = cls_static_code_analysis.StaticCodeAnalysis()
+PHYSIM = cls_physim1.PhySim()
ldpc=cls_physim.PhySim() #create an instance for LDPC test using GPU or CPU build
-
#-----------------------------------------------------------
# Parsing Command Line Arguments
#-----------------------------------------------------------
import args_parse
-py_param_file_present, py_params, mode = args_parse.ArgsParse(sys.argv,CiTestObj,RAN,HTML,EPC,ldpc,CONTAINERS,HELP,SCA)
+py_param_file_present, py_params, mode = args_parse.ArgsParse(sys.argv,CiTestObj,RAN,HTML,EPC,ldpc,CONTAINERS,HELP,SCA,PHYSIM)
@@ -673,13 +713,13 @@ 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,COTS_UE)
+ CiTestObj.InitializeUE(HTML,RAN, EPC, COTS_UE, InfraUE)
elif action == 'Terminate_UE':
CiTestObj.TerminateUE(HTML,COTS_UE)
elif action == 'Attach_UE':
CiTestObj.AttachUE(HTML,RAN,EPC,COTS_UE)
elif action == 'Detach_UE':
- CiTestObj.DetachUE(HTML,RAN,EPC,COTS_UE)
+ CiTestObj.DetachUE(HTML,RAN,EPC,COTS_UE,InfraUE)
elif action == 'DataDisable_UE':
CiTestObj.DataDisableUE(HTML)
elif action == 'DataEnable_UE':
@@ -703,9 +743,9 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re
elif action == 'Ping_CatM_module':
CiTestObj.PingCatM(HTML,RAN,EPC,COTS_UE,EPC)
elif action == 'Ping':
- CiTestObj.Ping(HTML,RAN,EPC,COTS_UE)
+ CiTestObj.Ping(HTML,RAN,EPC,COTS_UE, InfraUE)
elif action == 'Iperf':
- CiTestObj.Iperf(HTML,RAN,EPC,COTS_UE)
+ CiTestObj.Iperf(HTML,RAN,EPC,COTS_UE, InfraUE)
elif action == 'Reboot_UE':
CiTestObj.RebootUE(HTML,RAN,EPC)
elif action == 'Initialize_HSS':
@@ -745,6 +785,8 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re
CONTAINERS.UndeployObject(HTML, RAN)
elif action == 'Cppcheck_Analysis':
SCA.CppCheckAnalysis(HTML)
+ elif action == 'Deploy_Run_PhySim':
+ PHYSIM.Deploy_PhySim(HTML)
else:
sys.exit('Invalid class (action) from xml')
if not RAN.prematureExit:
diff --git a/ci-scripts/ran.py b/ci-scripts/ran.py
index 53016e87eb..c23541127c 100644
--- a/ci-scripts/ran.py
+++ b/ci-scripts/ran.py
@@ -37,6 +37,8 @@ import logging
import os
import time
from multiprocessing import Process, Lock, SimpleQueue
+import yaml
+
#-----------------------------------------------------------
# OAI Testing modules
@@ -90,6 +92,7 @@ class RANManagement():
self.testCase_id = ''
self.epcPcapFile = ''
self.runtime_stats= ''
+ self.datalog_rt_stats={}
@@ -243,7 +246,6 @@ class RANManagement():
while (count > 0) and buildOAIprocess:
mySSH.command('ps aux | grep --color=never build_ | grep -v grep', '\$', 6)
result = re.search('build_oai', mySSH.getBefore())
- print(result)
if result is None:
buildOAIprocess = False
else:
@@ -637,6 +639,9 @@ class RANManagement():
HTML.CreateHtmlTestRow(self.runtime_stats, 'OK', CONST.ALL_PROCESSES_OK)
else:
HTML.CreateHtmlTestRow(self.runtime_stats, 'OK', CONST.ALL_PROCESSES_OK)
+ #display rt stats for gNB only
+ if len(self.datalog_rt_stats)!=0 and nodeB_prefix == 'g':
+ HTML.CreateHtmlDataLogTable(self.datalog_rt_stats)
self.eNBmbmsEnables[int(self.eNB_instance)] = False
self.eNBstatuses[int(self.eNB_instance)] = -1
@@ -703,6 +708,21 @@ class RANManagement():
#count "problem receiving samples" msg
pb_receiving_samples_cnt = 0
+ #the datalog config file has to be loaded
+ datalog_rt_stats_file='datalog_rt_stats.yaml'
+ if (os.path.isfile(datalog_rt_stats_file)):
+ yaml_file=datalog_rt_stats_file
+ elif (os.path.isfile('ci-scripts/'+datalog_rt_stats_file)):
+ yaml_file='ci-scripts/'+datalog_rt_stats_file
+ else:
+ logging.error("Datalog RT stats yaml file cannot be found")
+ sys.exit("Datalog RT stats yaml file cannot be found")
+
+ with open(yaml_file,'r') as f:
+ datalog_rt_stats = yaml.load(f,Loader=yaml.FullLoader)
+ rt_keys = datalog_rt_stats['Ref'] #we use the keys from the Ref field
+
+
for line in enb_log_file.readlines():
# Runtime statistics
result = re.search('Run time:' ,str(line))
@@ -861,21 +881,21 @@ class RANManagement():
#keys below are the markers we are loooking for, loop over this keys list
#everytime these markers are found in the log file, the previous ones are overwritten in the dict
#eventually we record and print only the last occurence
- keys = {'UE ID','dlsch_rounds','dlsch_total_bytes','ulsch_rounds','ulsch_total_bytes_scheduled', 'scheduling timing stats'}
+ keys = {'UE ID','dlsch_rounds','dlsch_total_bytes','ulsch_rounds','ulsch_total_bytes_scheduled'}
for k in keys:
result = re.search(k, line)
if result is not None:
#remove 1- all useless char before relevant info (ulsch or dlsch) 2- trailing char
dlsch_ulsch_stats[k]=re.sub(r'^.*\]\s+', r'' , line.rstrip())
- #real time statistics
- #same method as above
- keys = {'feprx','feptx_prec','feptx_ofdm','feptx_total','L1 Tx processing','DLSCH encoding','L1 Rx processing','PUSCH inner-receiver','PUSCH decoding'}
- for k in keys:
+ #real time statistics for gNB
+ for k in rt_keys:
result = re.search(k, line)
if result is not None:
#remove 1- all useless char before relevant info 2- trailing char
+ line=line.replace('[0m','')
tmp=re.match(rf'^.*?(\b{k}\b.*)',line.rstrip()) #from python 3.6 we can use literal string interpolation for the variable k, using rf' in the regex
real_time_stats[k]=tmp.group(1)
+
#count "problem receiving samples" msg
result = re.search('\[PHY\]\s+problem receiving samples', str(line))
if result is not None:
@@ -924,13 +944,23 @@ class RANManagement():
logging.debug(dlsch_ulsch_stats[key])
htmleNBFailureMsg += statMsg
- #real time statistics statistics
+ #real time statistics
+ datalog_rt_stats['Data']={}
if len(real_time_stats)!=0: #check if dictionary is not empty
- statMsg=''
- for key in real_time_stats: #for each dictionary key
- statMsg += real_time_stats[key] + '\n'
- logging.debug(real_time_stats[key])
- htmleNBFailureMsg += statMsg
+ for k in real_time_stats:
+ tmp=re.match(r'^(?P.*):\s+(?P\d+\.\d+) us;\s+\d+;\s+(?P\d+\.\d+) us;',real_time_stats[k])
+ if tmp is not None:
+ metric=tmp.group('metric')
+ avg=float(tmp.group('avg'))
+ max=float(tmp.group('max'))
+ datalog_rt_stats['Data'][metric]=["{:.0f}".format(avg),"{:.0f}".format(max),"{:.2f}".format(avg/datalog_rt_stats['Ref'][metric])]
+ #once all metrics are collected, store the data as a class attribute to build a dedicated HTML table afterward
+ self.datalog_rt_stats=datalog_rt_stats
+ #check if there is a fail => will render the test as failed
+ for k in datalog_rt_stats['Data']:
+ if float(datalog_rt_stats['Data'][k][2])> datalog_rt_stats['Threshold'][k]: #condition for fail : avg/ref is greater than the fixed threshold
+ #setting prematureExit is ok although not the best option
+ self.prematureExit=True
else:
statMsg = 'No real time stats found in the log file\n'
logging.debug('No real time stats found in the log file')
diff --git a/ci-scripts/ran_dashboard.py b/ci-scripts/ran_dashboard.py
index 601cda1722..4f18638e68 100644
--- a/ci-scripts/ran_dashboard.py
+++ b/ci-scripts/ran_dashboard.py
@@ -40,6 +40,8 @@ import shlex #lexical analysis
import json #json structures
import datetime #now() and date formating
from datetime import datetime
+import re
+import gitlab
#-----------------------------------------------------------
# Class Declaration
@@ -79,7 +81,7 @@ class gDashboard:
#line 2 empty
#line 3 is for the column names
i=3
- row =["MR","Created_at","Author","Title","Assignee", "Reviewer", "CAN START","IN PROGRESS","COMPLETED","OK MERGE","Merge conflicts"]
+ row =["MR","Created_at","Author","Title","Assignee", "Reviewer", "CAN START","IN PROGRESS","COMPLETED","Review Form","OK MERGE","Merge conflicts"]
self.sheet.insert_row(row, index=i, value_input_option='RAW')
#line 4 onward, MR data lines
@@ -120,10 +122,32 @@ class gDashboard:
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')
+ for m in range (0,len(mrs)):
+ if mrs[m].iid==self.d[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 nUbuntu 16.04 LTS -- Summary" >> ./build_results.html
- if [ -f ./archives/cppcheck/cppcheck.xml ]
- then
- sca_summary_table_header ./archives/cppcheck/cppcheck.xml "OAI Static Code Analysis with CPPCHECK"
- sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Uninitialized variable" uninitvar
- sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Uninitialized struct member" uninitStructMember
- sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Memory leak" memleak
- sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Memory is freed twice" doubleFree
- sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Resource leak" resourceLeak
- sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Possible null pointer dereference" nullPointer
- sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Array access out of bounds" arrayIndexOutOfBounds
- sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Buffer is accessed out of bounds" bufferAccessOutOfBounds
- sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Expression depends on order of evaluation of side effects" unknownEvaluationOrder
- sca_summary_table_footer ./archives/cppcheck/cppcheck.xml
- fi
-
-# summary_table_header "OAI Build: 4G LTE eNB -- USRP option" ./archives/enb_usrp
-# summary_table_row "LTE SoftModem - Release 15" ./archives/enb_usrp/lte-softmodem.Rel15.txt "Built target lte-softmodem" ./enb_usrp_row1.html
-# summary_table_row "Coding - Release 15" ./archives/enb_usrp/coding.Rel15.txt "Built target coding" ./enb_usrp_row2.html
-# summary_table_row "OAI USRP device if - Release 15" ./archives/enb_usrp/oai_usrpdevif.Rel15.txt "Built target oai_usrpdevif" ./enb_usrp_row3.html
-# summary_table_row "OAI ETHERNET transport - Release 15" ./archives/enb_usrp/oai_eth_transpro.Rel15.txt "Built target oai_eth_transpro" ./enb_usrp_row4.html
-# summary_table_row "Parameters Lib Config - Release 15" ./archives/enb_usrp/params_libconfig.Rel15.txt "Built target params_libconfig" ./enb_usrp_row5.html
-# summary_table_row "NASMESH - Release 15" ./archives/enb_usrp/nasmesh.Rel15.txt "Built target nasmesh" ./enb_usrp_row6.html
-# summary_table_row "RB Tool - Release 15" ./archives/enb_usrp/rb_tool.Rel15.txt "Built target rb_tool" ./enb_usrp_row7.html
-# summary_table_row "RF Simulator - Release 15" ./archives/enb_usrp/rfsimulator.Rel15.txt "Built target rfsimulator" ./enb_usrp_row8.html
-# summary_table_row "TCP Bridge - Release 15" ./archives/enb_usrp/tcp_bridge_oai.Rel15.txt "Built target tcp_bridge_oai" ./enb_usrp_row9.html
-# summary_table_footer
-#
summary_table_header "OAI Build: 4G LTE eNB -- USRP option" ./archives/enb_eth
summary_table_row "LTE SoftModem - Release 15" ./archives/enb_eth/lte-softmodem.Rel15.txt "Built target lte-softmodem" ./enb_eth_row1.html
summary_table_row "Coding - Release 15" ./archives/enb_eth/coding.Rel15.txt "Built target coding" ./enb_eth_row2.html
@@ -637,48 +610,6 @@ function report_build {
summary_table_row "NVRAM - Release 15" ./archives/basic_sim/nvram.Rel15.txt "Built target nvram" ./basic_sim_row13.html
summary_table_footer
- summary_table_header "OAI Build: 4G LTE / 5G NR Physical simulators option" ./archives/phy_sim
- summary_table_row "LTE DL Simulator - Release 15" ./archives/phy_sim/dlsim.Rel15.txt "Built target dlsim" ./phy_sim_row1.html
- summary_table_row "LTE UL Simulator - Release 15" ./archives/phy_sim/ulsim.Rel15.txt "Built target ulsim" ./phy_sim_row2.html
- summary_table_row "Coding - Release 15" ./archives/phy_sim/coding.Rel15.txt "Built target coding" ./phy_sim_row3.html
- if [ -f ./archives/phy_sim/ldpctest.Rel15.txt ]
- then
- summary_table_row "NR LDPC Test - Release 15" ./archives/phy_sim/ldpctest.Rel15.txt "Built target ldpctest" ./phy_sim_row4.html
- fi
- if [ -f ./archives/phy_sim/polartest.Rel15.txt ]
- then
- summary_table_row "NR Polar Test - Release 15" ./archives/phy_sim/polartest.Rel15.txt "Built target polartest" ./phy_sim_row5.html
- fi
- if [ -f ./archives/phy_sim/nr_pbchsim.Rel15.txt ]
- then
- summary_table_row "NR PBCH Test - Release 15" ./archives/phy_sim/nr_pbchsim.Rel15.txt "Built target nr_pbchsim" ./phy_sim_row6.html
- fi
- if [ -f ./archives/phy_sim/nr_dlschsim.Rel15.txt ]
- then
- summary_table_row "NR DLSCH Test - Release 15" ./archives/phy_sim/nr_dlschsim.Rel15.txt "Built target nr_dlschsim" ./phy_sim_row7.html
- fi
- if [ -f ./archives/phy_sim/nr_pucchsim.Rel15.txt ]
- then
- summary_table_row "NR PUCCH Test - Release 15" ./archives/phy_sim/nr_pucchsim.Rel15.txt "Built target nr_pucchsim" ./phy_sim_row8.html
- fi
- if [ -f ./archives/phy_sim/smallblocktest.Rel15.txt ]
- then
- summary_table_row "NR Small Block Test - Release 15" ./archives/phy_sim/smallblocktest.Rel15.txt "Built target smallblocktest" ./phy_sim_row9.html
- fi
- if [ -f ./archives/phy_sim/nr_dlsim.Rel15.txt ]
- then
- summary_table_row "NR DL Sim Test - Release 15" ./archives/phy_sim/nr_dlsim.Rel15.txt "Built target nr_dlsim" ./phy_sim_row10.html
- fi
- if [ -f ./archives/phy_sim/nr_ulschsim.Rel15.txt ]
- then
- summary_table_row "NR ULSCH Test - Release 15" ./archives/phy_sim/nr_ulschsim.Rel15.txt "Built target nr_ulschsim" ./phy_sim_row11.html
- fi
- if [ -f ./archives/phy_sim/nr_ulsim.Rel15.txt ]
- then
- summary_table_row "NR UL Sim Test - Release 15" ./archives/phy_sim/nr_ulsim.Rel15.txt "Built target nr_ulsim" ./phy_sim_row12.html
- fi
- summary_table_footer
-
if [ -f archives/gnb_usrp/nr-softmodem.Rel15.txt ]
then
summary_table_header "OAI Build: 5G NR gNB -- USRP option" ./archives/gnb_usrp
@@ -721,13 +652,6 @@ function report_build {
echo " Details for Compilation Errors and Warnings " >> ./build_results.html
echo " " >> ./build_results.html
-# if [ -f ./enb_usrp_row1.html ] || [ -f ./enb_usrp_row2.html ] || [ -f ./enb_usrp_row3.html ] || [ -f ./enb_usrp_row4.html ]
-# then
-# for DETAILS_TABLE in `ls ./enb_usrp_row*.html`
-# do
-# cat $DETAILS_TABLE >> ./build_results.html
-# done
-# fi
if [ -f ./enb_eth_row1.html ] || [ -f ./enb_eth_row2.html ] || [ -f ./enb_eth_row3.html ] || [ -f ./enb_eth_row4.html ] || [ -f ./enb_eth_row5.html ] || [ -f ./enb_eth_row6.html ] || [ -f ./enb_eth_row7.html ] || [ -f ./enb_eth_row8.html ] || [ -f ./enb_eth_row9.html ]
then
for DETAILS_TABLE in `ls ./enb_eth_row*.html`
@@ -749,13 +673,6 @@ function report_build {
cat $DETAILS_TABLE >> ./build_results.html
done
fi
- if [ -f ./phy_sim_row1.html ] || [ -f ./phy_sim_row2.html ] || [ -f ./phy_sim_row3.html ] || [ -f ./phy_sim_row4.html ] || [ -f ./phy_sim_row5.html ] || [ -f ./phy_sim_row6.html ] || [ -f ./phy_sim_row7.html ] || [ -f ./phy_sim_row8.html ]
- then
- for DETAILS_TABLE in `ls ./phy_sim_row*.html`
- do
- cat $DETAILS_TABLE >> ./build_results.html
- done
- fi
if [ -f ./gnb_usrp_row1.html ] || [ -f ./gnb_usrp_row2.html ] || [ -f ./gnb_usrp_row3.html ] || [ -f ./gnb_usrp_row4.html ]
then
for DETAILS_TABLE in `ls ./gnb_usrp_row*.html`
@@ -770,13 +687,6 @@ function report_build {
cat $DETAILS_TABLE >> ./build_results.html
done
fi
- if [ -f ./enb_usrp_rh_row1.html ] || [ -f ./enb_usrp_rh_row2.html ] || [ -f ./enb_usrp_rh_row3.html ] || [ -f ./enb_usrp_rh_row4.html ]
- then
- for DETAILS_TABLE in `ls ./enb_usrp_rh_row*.html`
- do
- cat $DETAILS_TABLE >> ./build_results.html
- done
- fi
rm -f ./*_row*.html
echo "
" >> ./build_results.html
diff --git a/ci-scripts/runTestOnVM.sh b/ci-scripts/runTestOnVM.sh
index 056d018425..fc35370e0a 100755
--- a/ci-scripts/runTestOnVM.sh
+++ b/ci-scripts/runTestOnVM.sh
@@ -1478,13 +1478,13 @@ function run_test_on_vm {
echo "$VM_NAME has for IP addr = $VM_IP_ADDR"
fi
- if [ "$RUN_OPTIONS" == "none" ]
+ if [ "$RUN_OPTIONS" == "none" ] || [[ $RUN_OPTIONS =~ .*run_exec_autotests.* ]]
then
echo "No run on VM testing for this variant currently"
return
fi
- if [[ $RUN_OPTIONS =~ .*run_exec_autotests.* ]]
+ if [[ $RUN_OPTIONS =~ .*run_XXXX_autotests.* ]]
then
echo "############################################################"
echo "Running test script on VM ($VM_NAME)"
diff --git a/ci-scripts/sshconnection.py b/ci-scripts/sshconnection.py
index 5bfe5da70f..b4087c9695 100644
--- a/ci-scripts/sshconnection.py
+++ b/ci-scripts/sshconnection.py
@@ -35,6 +35,7 @@ import pexpect # pexpect
import logging
import time # sleep
import re
+import subprocess
import sys
#-----------------------------------------------------------
@@ -44,6 +45,9 @@ class SSHConnection():
def __init__(self):
self.ssh = ''
self.picocom_closure = False
+ self.ipaddress = ''
+ self.username = ''
+ self.cmd2Results = ''
def disablePicocomClosure(self):
self.picocom_closure = False
@@ -98,6 +102,8 @@ class SSHConnection():
pass
else:
sys.exit('SSH Connection Failed')
+ self.ipaddress = ipaddress
+ self.username = username
@@ -111,11 +117,20 @@ class SSHConnection():
self.sshresponse = self.ssh.expect(expected)
return self.sshresponse
- def command(self, commandline, expectedline, timeout):
- logging.debug(commandline)
+ def command(self, commandline, expectedline, timeout, silent=False, resync=False):
+ if not silent:
+ logging.debug(commandline)
self.ssh.timeout = timeout
- self.ssh.sendline(commandline)
- self.sshresponse = self.ssh.expect([expectedline, pexpect.EOF, pexpect.TIMEOUT])
+ # Nasty patch when pexpect output is out of sync.
+ # Much pronounced when running back-to-back-back oc commands
+ if resync:
+ self.ssh.send(commandline)
+ self.ssh.expect([commandline, pexpect.TIMEOUT])
+ self.ssh.send('\r\n')
+ self.sshresponse = self.ssh.expect([expectedline, pexpect.EOF, pexpect.TIMEOUT])
+ else:
+ self.ssh.sendline(commandline)
+ self.sshresponse = self.ssh.expect([expectedline, pexpect.EOF, pexpect.TIMEOUT])
if self.sshresponse == 0:
return 0
elif self.sshresponse == 1:
@@ -137,10 +152,23 @@ class SSHConnection():
logging.debug('Expected Line : ' + expectedline)
sys.exit(self.sshresponse)
+ def command2(self, commandline, timeout, silent=False):
+ if not silent:
+ logging.debug(commandline)
+ self.cmd2Results = ''
+ myHost = self.username + '@' + self.ipaddress
+ # CAUTION: THIS METHOD IMPLIES THAT THERE ARE VALID SSH KEYS
+ # BETWEEN THE PYTHON EXECUTOR NODE AND THE REMOTE HOST
+ # OTHERWISE IT WON'T WORK
+ lSsh = subprocess.Popen(["ssh", "%s" % myHost, commandline],shell=False,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
+ self.cmd2Results = str(lSsh.stdout.readlines())
+
def close(self):
self.ssh.timeout = 5
self.ssh.sendline('exit')
self.sshresponse = self.ssh.expect([pexpect.EOF, pexpect.TIMEOUT])
+ self.ipaddress = ''
+ self.username = ''
if self.sshresponse == 0:
pass
elif self.sshresponse == 1:
diff --git a/ci-scripts/waitBuildOnVM.sh b/ci-scripts/waitBuildOnVM.sh
index f7e300edf4..4a604a1fe9 100755
--- a/ci-scripts/waitBuildOnVM.sh
+++ b/ci-scripts/waitBuildOnVM.sh
@@ -47,7 +47,7 @@ function wait_on_vm_build {
echo "ARCHIVES_LOC = $ARCHIVES_LOC"
echo "BUILD_OPTIONS = $BUILD_OPTIONS"
- if [[ "$VM_NAME" == *"-enb-usrp"* ]] || [[ "$VM_NAME" == *"-cppcheck"* ]]
+ if [[ "$VM_NAME" == *"-enb-usrp"* ]] || [[ "$VM_NAME" == *"-cppcheck"* ]] || [[ "$VM_NAME" == *"-phy-sim"* ]]
then
echo "This VM type is no longer supported in the pipeline framework"
return
@@ -93,7 +93,7 @@ function wait_on_vm_build {
}
function check_on_vm_build {
- if [[ "$VM_NAME" == *"-enb-usrp"* ]] || [[ "$VM_NAME" == *"-cppcheck"* ]]
+ if [[ "$VM_NAME" == *"-enb-usrp"* ]] || [[ "$VM_NAME" == *"-cppcheck"* ]] || [[ "$VM_NAME" == *"-phy-sim"* ]]
then
echo "This VM type is no longer supported in the pipeline framework"
return
diff --git a/ci-scripts/xml_class_list.yml b/ci-scripts/xml_class_list.yml
index de16116124..2282e101e5 100755
--- a/ci-scripts/xml_class_list.yml
+++ b/ci-scripts/xml_class_list.yml
@@ -38,3 +38,4 @@
- Deploy_Object
- Undeploy_Object
- Cppcheck_Analysis
+ - Deploy_Run_PhySim
\ No newline at end of file
diff --git a/ci-scripts/xml_files/fr1_nsa_base_ref.xml b/ci-scripts/xml_files/benetel_nsa_quectel.xml
similarity index 74%
rename from ci-scripts/xml_files/fr1_nsa_base_ref.xml
rename to ci-scripts/xml_files/benetel_nsa_quectel.xml
index fd47db10b2..7130180753 100644
--- a/ci-scripts/xml_files/fr1_nsa_base_ref.xml
+++ b/ci-scripts/xml_files/benetel_nsa_quectel.xml
@@ -22,64 +22,58 @@
-->
TEST-NSA-FR1-TM1
- NSA FULL
+ NSA Ping DL UL with QUECTEL
tasks
+ 3
- 010000
030000
040000
- 010001
+ 000002
+ 010000
000001
050000
050001
000001
- 060000
- 060001
- 000001
070000
+ 000001
+ 070001
+ 000001
010002
000001
080001
080000
- 010003
+
Initialize_UE
- Initialize UE
+ Initialize Quectel
+ idefix
-
- Terminate_UE
- Terminate UE
-
-
-
- Attach_UE
- Attach UE
-
Detach_UE
Detach UE
+ idefix
Initialize_eNB
Initialize eNB
- -O ci-scripts/conf_files/enb.band7.tm1.fr1.25PRB.usrpb210.conf
+ -O ci-scripts/conf_files/benetel-4g.conf
0
0
lte
-
+
Initialize_eNB
Initialize gNB
- -O ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf -E
+ -O ci-scripts/conf_files/benetel-5g.conf -q
1
1
nr
@@ -88,12 +82,20 @@
IdleSleep
Sleep
- 20
+ 10
+
+ IdleSleep
+ Sleep
+ 30
+
+
+
Ping
Ping: 20pings in 20sec
+ idefix
-c 20
50
@@ -101,32 +103,17 @@
Ping
Ping: 100pings in 20sec
+ idefix
-c 100 -i 0.2
50
-
-
- Iperf
- iperf (DL/3Mbps/UDP)(20 sec)(single-ue profile)
- -u -b 3M -t 20 -i 1
- 50
- single-ue
-
-
-
- Iperf
- iperf (UL/1Mbps/UDP)(20 sec)(single-ue profile)
- -u -b 1M -t 20 -i 1 -R
- 50
- single-ue
-
-
-
Iperf
iperf (DL/20Mbps/UDP)(20 sec)(single-ue profile)
-u -b 20M -t 20 -i 1
+ DL
+ idefix
50
single-ue
@@ -134,13 +121,14 @@
Iperf
iperf (UL/3Mbps/UDP)(20 sec)(single-ue profile)
- -u -b 3M -t 20 -i 1 -R
+ -u -b 3M -t 20 -i 1
+ UL
+ idefix
50
single-ue
-
Terminate_eNB
Terminate eNB
diff --git a/ci-scripts/xml_files/fr1_nsa_quectel.xml b/ci-scripts/xml_files/fr1_nsa_quectel.xml
new file mode 100644
index 0000000000..c48aa70739
--- /dev/null
+++ b/ci-scripts/xml_files/fr1_nsa_quectel.xml
@@ -0,0 +1,149 @@
+
+
+ TEST-NSA-FR1-TM1
+ NSA Ping DL UL with QUECTEL
+ tasks
+ 3
+
+ 030000
+ 040000
+ 000002
+ 010000
+ 000001
+ 050000
+ 050001
+ 000001
+ 070000
+ 000001
+ 070001
+ 000001
+ 010002
+ 000001
+ 080001
+ 080000
+
+
+
+
+
+ Initialize_UE
+ Initialize Quectel
+ idefix
+
+
+
+
+ Detach_UE
+ Detach UE
+ idefix
+
+
+
+
+ Initialize_eNB
+ Initialize eNB
+ -O ci-scripts/conf_files/enb.band7.tm1.fr1.25PRB.usrpb210.conf
+ 0
+ 0
+ lte
+
+
+
+
+ Initialize_eNB
+ Initialize gNB
+ -O ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpn310.conf -q
+ 1
+ 1
+ nr
+
+
+
+ IdleSleep
+ Sleep
+ 10
+
+
+
+ IdleSleep
+ Sleep
+ 30
+
+
+
+
+ Ping
+ Ping: 20pings in 20sec
+ idefix
+ -c 20
+ 50
+
+
+
+ Ping
+ Ping: 100pings in 20sec
+ idefix
+ -c 100 -i 0.2
+ 50
+
+
+
+ Iperf
+ iperf (DL/20Mbps/UDP)(60 sec)(single-ue profile)
+ -u -b 20M -t 60 -i 1
+ DL
+ idefix
+ 50
+ single-ue
+
+
+
+ Iperf
+ iperf (UL/3Mbps/UDP)(60 sec)(single-ue profile)
+ -u -b 3M -t 60 -i 1
+ UL
+ idefix
+ 50
+ single-ue
+
+
+
+
+ Terminate_eNB
+ Terminate eNB
+ 0
+ 0
+ lte
+
+
+
+ Terminate_eNB
+ Terminate gNB
+ 1
+ 1
+ nr
+
+
+
+
diff --git a/ci-scripts/xml_files/gnb_phytest_usrp_run.xml b/ci-scripts/xml_files/gnb_phytest_usrp_run.xml
index 00610d430e..9e798afdc4 100644
--- a/ci-scripts/xml_files/gnb_phytest_usrp_run.xml
+++ b/ci-scripts/xml_files/gnb_phytest_usrp_run.xml
@@ -24,7 +24,7 @@
gNB-PHY-Test
Run-gNB-PHY-Test
tasks
- 2
+ 3
090101 000001 090109
@@ -40,7 +40,7 @@
IdleSleep
Sleep
- 180
+ 300
diff --git a/ci-scripts/xml_files/physim_deploy_run.xml b/ci-scripts/xml_files/physim_deploy_run.xml
new file mode 100644
index 0000000000..63152c1fb5
--- /dev/null
+++ b/ci-scripts/xml_files/physim_deploy_run.xml
@@ -0,0 +1,37 @@
+
+
+ build-tab
+ Physical Simulators Check
+ wrench
+
+ 010201
+
+
+
+
+ Deploy_Run_PhySim
+ Deploy and run physical simulator on openshift
+
+
+
diff --git a/docker/Dockerfile.eNB.rhel8.2 b/docker/Dockerfile.eNB.rhel8.2
index aa8b9aa228..cf012502e0 100644
--- a/docker/Dockerfile.eNB.rhel8.2
+++ b/docker/Dockerfile.eNB.rhel8.2
@@ -25,7 +25,7 @@
#
#---------------------------------------------------------------------
-FROM localhost/ran-build:latest AS enb-build
+FROM ran-build:latest AS enb-build
RUN rm -Rf /oai-ran
WORKDIR /oai-ran
@@ -37,10 +37,9 @@ RUN /bin/sh oaienv && \
mkdir -p log && \
./build_oai --eNB --ninja -w USRP --verbose-ci
-# debug
-#RUN ldconfig -v && ldd /oai-ran/targets/bin/lte-softmodem.Rel15
-#RUN ls -ls /oai-ran/targets/bin
-#RUN ls -ls /oai-ran/cmake_targets/ran_build/build/*.so
+RUN yum install -y python3-pip && \
+ pip3 install --ignore-installed pyyaml && \
+ python3 ./docker/scripts/generateTemplate.py ./docker/scripts/enb_parameters.yaml
#start from scratch for target executable
FROM registry.access.redhat.com/ubi8/ubi:latest as oai-enb
@@ -59,6 +58,7 @@ RUN yum update -y && \
WORKDIR /opt/oai-enb/bin
COPY --from=enb-build /oai-ran/targets/bin/lte-softmodem.Rel15 .
+COPY --from=enb-build /oai-ran/docker/scripts/enb_entrypoint.sh entrypoint.sh
WORKDIR /usr/local/lib/
COPY --from=enb-build /oai-ran/targets/bin/liboai_eth_transpro.so.Rel15 .
@@ -93,34 +93,16 @@ COPY --from=enb-build /usr/local/lib64/libuhd.so.4.0.0 /usr/local/lib64
RUN ldconfig
-#debug
-#RUN ldd /usr/local/lib/liboai_eth_transpro.so.Rel15
-#RUN ldd /usr/local/lib/libtcp_bridge_oai.so.Rel15
-#RUN ldd /usr/local/lib/librfsimulator.so.Rel15
-#RUN ldd /usr/local/lib/liboai_usrpdevif.so.Rel15
-#RUN ldd /usr/local/lib/libcoding.so
-#RUN ldd /usr/local/lib/libparams_libconfig.so
-#RUN ldd /usr/local/lib/libdfts.so
-#RUN ldd /usr/local/lib/liboai_iqplayer.so
-#RUN ldd /opt/oai-enb/bin/lte-softmodem.Rel15
-
# Copy the relevant configuration files for eNB
WORKDIR /opt/oai-enb/etc
-COPY --from=enb-build /oai-ran/ci-scripts/conf_files/enb.* .
-COPY --from=enb-build /oai-ran/ci-scripts/conf_files/rcc.* .
-COPY --from=enb-build /oai-ran/ci-scripts/conf_files/cu.* .
-COPY --from=enb-build /oai-ran/ci-scripts/conf_files/du.* .
-COPY --from=enb-build /oai-ran/ci-scripts/conf_files/rru.* .
+COPY --from=enb-build /oai-ran/docker/etc .
WORKDIR /opt/oai-enb
-#EXPOSE 2152/udp # S1U, GTP/UDP
-#EXPOSE 22100/tcp # ?
-#EXPOSE 36412/udp # S1C, SCTP/UDP
-#EXPOSE 36422/udp # X2C, SCTP/UDP
-#EXPOSE 50000/udp # IF5 / ORI (control)
-#EXPOSE 50001/udp # IF5 / ECPRI (data)
+# 2152 --> S1U, GTP/UDP
+# 36412 --> S1C, SCTP/UDP
+# 36422 --> X2C, SCTP/UDP
+EXPOSE 2152/udp 36412/udp 36422/udp
-#CMD ["/opt/oai-enb/bin/lte-softmodem", "-O", "/opt/oai-enb/etc/enb.conf"]
-#ENTRYPOINT ["/opt/oai-enb/bin/entrypoint.sh"]
-CMD ["sleep", "infinity"]
+ENTRYPOINT ["/opt/oai-enb/bin/entrypoint.sh"]
+CMD ["/opt/oai-enb/bin/lte-softmodem.Rel15", "-O", "/opt/oai-enb/etc/enb.conf"]
diff --git a/docker/Dockerfile.eNB.ubuntu18 b/docker/Dockerfile.eNB.ubuntu18
index 95d7194c31..1f276094d5 100644
--- a/docker/Dockerfile.eNB.ubuntu18
+++ b/docker/Dockerfile.eNB.ubuntu18
@@ -41,11 +41,6 @@ RUN apt-get install -y python3-pip && \
pip3 install --ignore-installed pyyaml && \
python3 ./docker/scripts/generateTemplate.py ./docker/scripts/enb_parameters.yaml
-# debug
-#RUN ldconfig -v && ldd /oai-ran/targets/bin/lte-softmodem.Rel15
-#RUN ls -ls /oai-ran/targets/bin
-#RUN ls -ls /oai-ran/cmake_targets/ran_build/build/*.so
-
#start from scratch for target executable
FROM ubuntu:bionic as oai-enb
ENV DEBIAN_FRONTEND=noninteractive
@@ -98,17 +93,6 @@ COPY --from=enb-build /usr/local/lib/libprotobuf-c.so.1 .
RUN ldconfig
-#debug
-#RUN ldd /usr/local/lib/liboai_eth_transpro.so.Rel15
-#RUN ldd /usr/local/lib/libtcp_bridge_oai.so.Rel15
-#RUN ldd /usr/local/lib/librfsimulator.so.Rel15
-#RUN ldd /usr/local/lib/liboai_usrpdevif.so.Rel15
-#RUN ldd /usr/local/lib/libcoding.so
-#RUN ldd /usr/local/lib/libparams_libconfig.so
-#RUN ldd /usr/local/lib/libdfts.so
-#RUN ldd /usr/local/lib/liboai_iqplayer.so
-#RUN ldd /opt/oai-enb/bin/lte-softmodem.Rel15
-
# Copy the relevant configuration files for eNB
WORKDIR /opt/oai-enb/etc
COPY --from=enb-build /oai-ran/docker/etc .
diff --git a/docker/Dockerfile.lteUE.rhel8.2 b/docker/Dockerfile.lteUE.rhel8.2
index e22343d63c..731abed1a8 100644
--- a/docker/Dockerfile.lteUE.rhel8.2
+++ b/docker/Dockerfile.lteUE.rhel8.2
@@ -25,7 +25,7 @@
#
#---------------------------------------------------------------------
-FROM localhost/ran-build:latest AS lte-ue-build
+FROM ran-build:latest AS lte-ue-build
RUN rm -Rf /oai-ran
WORKDIR /oai-ran
@@ -37,10 +37,10 @@ RUN /bin/sh oaienv && \
mkdir -p log && \
./build_oai --UE --ninja -w USRP --verbose-ci
-# debug
-#RUN ldconfig -v && ldd /oai-ran/targets/bin/lte-uesoftmodem.Rel15
-#RUN ls -lst /oai-ran/targets/bin
-#RUN ls -lst /oai-ran/cmake_targets/ran_build/build/*.so
+RUN yum install -y python3-pip && \
+ pip3 install --ignore-installed pyyaml && \
+ python3 ./docker/scripts/generateTemplate.py ./docker/scripts/lte_ue_parameters.yaml && \
+ python3 ./docker/scripts/generateTemplate.py ./docker/scripts/lte_ue_sim_parameters.yaml
#start from scratch for target executable
FROM registry.access.redhat.com/ubi8/ubi:latest as oai-lte-ue
@@ -59,12 +59,10 @@ RUN yum update -y && \
WORKDIR /opt/oai-lte-ue/bin
COPY --from=lte-ue-build /oai-ran/targets/bin/lte-uesoftmodem.Rel15 .
+COPY --from=lte-ue-build /oai-ran/docker/scripts/lte_ue_entrypoint.sh entrypoint.sh
COPY --from=lte-ue-build /oai-ran/targets/bin/conf2uedata .
COPY --from=lte-ue-build /oai-ran/targets/bin/nvram .
COPY --from=lte-ue-build /oai-ran/targets/bin/usim .
-COPY --from=lte-ue-build /oai-ran/targets/bin/.ue_emm.nvram0 .
-COPY --from=lte-ue-build /oai-ran/targets/bin/.ue.nvram0 .
-COPY --from=lte-ue-build /oai-ran/targets/bin/.usim.nvram0 .
WORKDIR /usr/local/lib/
COPY --from=lte-ue-build /oai-ran/targets/bin/liboai_eth_transpro.so.Rel15 .
@@ -99,26 +97,10 @@ COPY --from=lte-ue-build /usr/local/lib64/libuhd.so.4.0.0 /usr/local/lib64
RUN ldconfig
-#debug
-#RUN ldd /opt/oai-lte-ue/bin/lte-uesoftmodem.Rel15
-#RUN ldd /opt/oai-lte-ue/bin/conf2uedata
-#RUN ldd /opt/oai-lte-ue/bin/nvram
-#RUN ldd /opt/oai-lte-ue/bin/usim
-#RUN ldd /usr/local/lib/liboai_eth_transpro.so.Rel15
-#RUN ldd /usr/local/lib/libtcp_bridge_oai.so.Rel15
-#RUN ldd /usr/local/lib/librfsimulator.so.Rel15
-#RUN ldd /usr/local/lib/liboai_usrpdevif.so.Rel15
-#RUN ldd /usr/local/lib/libcoding.so
-#RUN ldd /usr/local/lib/libparams_libconfig.so
-#RUN ldd /usr/local/lib/libSIMU.so
-#RUN ldd /usr/local/lib/libdfts.so
-
-# Copy the relevant configuration files for eNB
+# Copy the relevant configuration files for UE
WORKDIR /opt/oai-lte-ue/etc
-COPY --from=lte-ue-build /oai-ran/ci-scripts/conf_files/ue.* .
-COPY --from=lte-ue-build /oai-ran/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf ./ue_usim.conf
+COPY --from=lte-ue-build /oai-ran/docker/etc .
WORKDIR /opt/oai-lte-ue
-#CMD ["/opt/oai-lte-ue/bin/lte-uesoftmodem", "-O", "/opt/oai-lte-ue/etc/enb.conf"]
-#ENTRYPOINT ["/opt/oai-lte-ue/bin/entrypoint.sh"]
-CMD ["sleep", "infinity"]
+CMD ["/opt/oai-lte-ue/bin/lte-uesoftmodem.Rel15"]
+ENTRYPOINT ["/opt/oai-lte-ue/bin/entrypoint.sh"]
diff --git a/docker/Dockerfile.lteUE.ubuntu18 b/docker/Dockerfile.lteUE.ubuntu18
index 6af2e61991..6575a81899 100644
--- a/docker/Dockerfile.lteUE.ubuntu18
+++ b/docker/Dockerfile.lteUE.ubuntu18
@@ -37,11 +37,10 @@ RUN /bin/sh oaienv && \
mkdir -p log && \
./build_oai --UE --ninja -w USRP --verbose-ci
-# debug
-#RUN ldconfig -v
-#RUN ldd /oai-ran/targets/bin/lte-uesoftmodem.Rel15
-#RUN ls -lst /oai-ran/targets/bin
-#RUN ls -lst /oai-ran/cmake_targets/ran_build/build/*.so
+RUN apt-get install -y python3-pip && \
+ pip3 install --ignore-installed pyyaml && \
+ python3 ./docker/scripts/generateTemplate.py ./docker/scripts/lte_ue_parameters.yaml && \
+ python3 ./docker/scripts/generateTemplate.py ./docker/scripts/lte_ue_sim_parameters.yaml
#start from scratch for target executable
FROM ubuntu:bionic as oai-lte-ue
@@ -76,12 +75,10 @@ RUN apt-get update && \
WORKDIR /opt/oai-lte-ue/bin
COPY --from=lte-ue-build /oai-ran/targets/bin/lte-uesoftmodem.Rel15 .
+COPY --from=lte-ue-build /oai-ran/docker/scripts/lte_ue_entrypoint.sh entrypoint.sh
COPY --from=lte-ue-build /oai-ran/targets/bin/conf2uedata .
COPY --from=lte-ue-build /oai-ran/targets/bin/nvram .
COPY --from=lte-ue-build /oai-ran/targets/bin/usim .
-COPY --from=lte-ue-build /oai-ran/targets/bin/.ue_emm.nvram0 .
-COPY --from=lte-ue-build /oai-ran/targets/bin/.ue.nvram0 .
-COPY --from=lte-ue-build /oai-ran/targets/bin/.usim.nvram0 .
WORKDIR /usr/local/lib/
COPY --from=lte-ue-build /oai-ran/targets/bin/liboai_eth_transpro.so.Rel15 .
@@ -100,26 +97,10 @@ COPY --from=lte-ue-build /usr/local/lib/libprotobuf-c.so.1 .
RUN ldconfig
-#debug
-#RUN ldd /opt/oai-lte-ue/bin/lte-uesoftmodem.Rel15
-#RUN ldd /opt/oai-lte-ue/bin/conf2uedata
-#RUN ldd /opt/oai-lte-ue/bin/nvram
-#RUN ldd /opt/oai-lte-ue/bin/usim
-#RUN ldd /usr/local/lib/liboai_eth_transpro.so.Rel15
-#RUN ldd /usr/local/lib/libtcp_bridge_oai.so.Rel15
-#RUN ldd /usr/local/lib/librfsimulator.so.Rel15
-#RUN ldd /usr/local/lib/liboai_usrpdevif.so.Rel15
-#RUN ldd /usr/local/lib/libcoding.so
-#RUN ldd /usr/local/lib/libparams_libconfig.so
-#RUN ldd /usr/local/lib/libSIMU.so
-#RUN ldd /usr/local/lib/libdfts.so
-
-# Copy the relevant configuration files for eNB
+# Copy the relevant configuration files for UE
WORKDIR /opt/oai-lte-ue/etc
-COPY --from=lte-ue-build /oai-ran/ci-scripts/conf_files/ue.* ./
-COPY --from=lte-ue-build /oai-ran/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf ./ue_usim.conf
+COPY --from=lte-ue-build /oai-ran/docker/etc .
WORKDIR /opt/oai-lte-ue
-#CMD ["/opt/oai-lte-ue/bin/lte-uesoftmodem", "-O", "/opt/oai-lte-ue/etc/enb.conf"]
-#ENTRYPOINT ["/opt/oai-lte-ue/bin/entrypoint.sh"]
-CMD ["sleep", "infinity"]
+CMD ["/opt/oai-lte-ue/bin/lte-uesoftmodem.Rel15"]
+ENTRYPOINT ["/opt/oai-lte-ue/bin/entrypoint.sh"]
diff --git a/docker/scripts/enb_entrypoint.sh b/docker/scripts/enb_entrypoint.sh
index 31d99b2a67..dbe97360f6 100755
--- a/docker/scripts/enb_entrypoint.sh
+++ b/docker/scripts/enb_entrypoint.sh
@@ -2,17 +2,20 @@
set -euo pipefail
+PREFIX=/opt/oai-enb
+RRC_INACTIVITY_THRESHOLD=${RRC_INACTIVITY_THRESHOLD:-0}
+
# Based another env var, pick one template to use
-if [[ -v USE_FDD_CU ]]; then ln -s /opt/oai-enb/etc/cu.fdd.conf /opt/oai-enb/etc/enb.conf; fi
-if [[ -v USE_FDD_DU ]]; then ln -s /opt/oai-enb/etc/du.fdd.conf /opt/oai-enb/etc/enb.conf; fi
-if [[ -v USE_FDD_MONO ]]; then ln -s /opt/oai-enb/etc/enb.fdd.conf /opt/oai-enb/etc/enb.conf; fi
-if [[ -v USE_TDD_MONO ]]; then ln -s /opt/oai-enb/etc/enb.tdd.conf /opt/oai-enb/etc/enb.conf; fi
-if [[ -v USE_FDD_RCC ]]; then ln -s /opt/oai-enb/etc/rcc.if4p5.enb.fdd.conf /opt/oai-enb/etc/enb.conf; fi
-if [[ -v USE_FDD_RRU ]]; then ln -s /opt/oai-enb/etc/rru.fdd.conf /opt/oai-enb/etc/enb.conf; fi
-if [[ -v USE_TDD_RRU ]]; then ln -s /opt/oai-enb/etc/rru.tdd.conf /opt/oai-enb/etc/enb.conf; fi
+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_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
# Only this template will be manipulated
-CONFIG_FILES=`ls /opt/oai-enb/etc/enb.conf`
+CONFIG_FILES=`ls $PREFIX/etc/enb.conf || true`
for c in ${CONFIG_FILES}; do
# grep variable names (format: ${VAR}) from template to be rendered
diff --git a/docker/scripts/enb_parameters.yaml b/docker/scripts/enb_parameters.yaml
index a60fc20e29..d115d177ab 100644
--- a/docker/scripts/enb_parameters.yaml
+++ b/docker/scripts/enb_parameters.yaml
@@ -159,6 +159,8 @@
env: "@ENB_S1U_IP_ADDRESS@"
- key: ENB_IPV4_ADDRESS_FOR_X2C
env: "@ENB_X2_IP_ADDRESS@"
+ - key: rrc_inactivity_threshold
+ env: "@RRC_INACTIVITY_THRESHOLD@"
- key: FLEXRAN_ENABLED
env: "@FLEXRAN_ENABLED@"
- key: FLEXRAN_INTERFACE_NAME
@@ -204,7 +206,7 @@
env: "@F1_CU_IP_ADDRESS@"
- filePrefix: "rcc.band7.tm1.nfapi"
- outputfilename: "rcc.if4p5.enb.fdd.conf"
+ outputfilename: "rcc.nfapi.fdd.conf"
config:
- key: Active_eNBs
env: "@ENB_NAME@"
diff --git a/docker/scripts/generateTemplate.py b/docker/scripts/generateTemplate.py
index 4949e9cf21..418476d395 100644
--- a/docker/scripts/generateTemplate.py
+++ b/docker/scripts/generateTemplate.py
@@ -35,11 +35,12 @@ def main():
data = yaml.full_load(f)
dir = os.listdir(f'{data[0]["paths"]["source_dir"]}')
-
#identify configs, read and replace corresponding values
for config in data[1]["configurations"]:
filePrefix = config["filePrefix"]
outputfilename = config["outputfilename"]
+ print('filePrefix = ' + filePrefix)
+ print('outputfilename = ' + outputfilename)
for inputfile in dir:
if inputfile.find(filePrefix) >=0:
prefix_outputfile = {"cu": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}',
@@ -48,7 +49,9 @@ def main():
"rru.tdd": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}',
"enb.band7.tm1.25PRB.usrpb210": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}',
"enb.band40.tm1.25PRB.FairScheduler.usrpb210": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}',
- "rcc.band7.tm1.nfapi": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}'
+ "rcc.band7.tm1.nfapi": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}',
+ "ue.nfapi": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}',
+ "ue_sim_ci": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}'
}
if filePrefix in prefix_outputfile:
outputfile1 = prefix_outputfile[filePrefix]
@@ -61,6 +64,9 @@ def main():
open(outputfile1, mode='w') as outputfile:
for line in inputfile:
count = 0
+ if re.search(r'EHPLMN_LIST', line):
+ outputfile.write(line)
+ continue
for key in config["config"]:
if line.find(key["key"]) >= 0:
count += 1
diff --git a/docker/scripts/lte_ue_entrypoint.sh b/docker/scripts/lte_ue_entrypoint.sh
new file mode 100755
index 0000000000..235128f738
--- /dev/null
+++ b/docker/scripts/lte_ue_entrypoint.sh
@@ -0,0 +1,72 @@
+#!/bin/bash
+
+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
+
+# Only this template will be manipulated and the USIM one!
+CONFIG_FILES=`ls $PREFIX/etc/ue.conf $PREFIX/etc/ue_usim.conf || true`
+
+for c in ${CONFIG_FILES}; do
+ # grep variable names (format: ${VAR}) from template to be rendered
+ VARS=$(grep -oP '@[a-zA-Z0-9_]+@' ${c} | sort | uniq | xargs)
+
+ # create sed expressions for substituting each occurrence of ${VAR}
+ # with the value of the environment variable "VAR"
+ EXPRESSIONS=""
+ for v in ${VARS}; do
+ NEW_VAR=`echo $v | sed -e "s#@##g"`
+ if [[ "${!NEW_VAR}x" == "x" ]]; then
+ echo "Error: Environment variable '${NEW_VAR}' is not set." \
+ "Config file '$(basename $c)' requires all of $VARS."
+ exit 1
+ fi
+ EXPRESSIONS="${EXPRESSIONS};s|${v}|${!NEW_VAR}|g"
+ done
+ EXPRESSIONS="${EXPRESSIONS#';'}"
+
+ # render template and inline replace config file
+ sed -i "${EXPRESSIONS}" ${c}
+done
+
+#now generate USIM files
+# At this point all operations will be run from $PREFIX!
+cd $PREFIX
+$PREFIX/bin/conf2uedata -c $PREFIX/etc/ue_usim.conf -o $PREFIX
+
+# Load the USRP binaries
+if [[ -v USE_B2XX ]]; then
+ /usr/lib/uhd/utils/uhd_images_downloader.py -t b2xx
+elif [[ -v USE_X3XX ]]; then
+ /usr/lib/uhd/utils/uhd_images_downloader.py -t x3xx
+elif [[ -v USE_N3XX ]]; then
+ /usr/lib/uhd/utils/uhd_images_downloader.py -t n3xx
+fi
+
+# in case we have conf file, append
+new_args=()
+while [[ $# -gt 0 ]]; do
+ new_args+=("$1")
+ shift
+done
+if [[ -v USE_NFAPI ]]; then
+ new_args+=("-O")
+ new_args+=("$PREFIX/etc/ue.conf")
+fi
+
+echo "=================================="
+echo "== Starting LTE UE soft modem"
+if [[ -v USE_ADDITIONAL_OPTIONS ]]; then
+ echo "Additional option(s): ${USE_ADDITIONAL_OPTIONS}"
+ for word in ${USE_ADDITIONAL_OPTIONS}; do
+ new_args+=("$word")
+ done
+ echo "${new_args[@]}"
+ exec "${new_args[@]}"
+else
+ echo "${new_args[@]}"
+ exec "${new_args[@]}"
+fi
diff --git a/docker/scripts/lte_ue_parameters.yaml b/docker/scripts/lte_ue_parameters.yaml
new file mode 100644
index 0000000000..977659bb54
--- /dev/null
+++ b/docker/scripts/lte_ue_parameters.yaml
@@ -0,0 +1,37 @@
+#/*
+# * 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
+# */
+
+---
+- paths:
+ source_dir: "ci-scripts/conf_files/"
+ dest_dir: docker/etc
+
+- configurations:
+ - filePrefix: ue.nfapi
+ outputfilename: "ue.nfapi.conf"
+ config:
+ - key: remote_n_address
+ env: "@ENB_IP_ADDRESS@"
+ - key: local_n_address
+ env: "@LTE_UE_IP_ADDRESS@"
+ - key: local_n_if_name
+ env: "@UE_NFAPI_IF_NAME@"
+
diff --git a/docker/scripts/lte_ue_sim_parameters.yaml b/docker/scripts/lte_ue_sim_parameters.yaml
new file mode 100644
index 0000000000..a339ed7504
--- /dev/null
+++ b/docker/scripts/lte_ue_sim_parameters.yaml
@@ -0,0 +1,47 @@
+#/*
+# * 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
+# */
+
+---
+- paths:
+ source_dir: "openair3/NAS/TOOLS/"
+ dest_dir: docker/etc
+
+- configurations:
+ - filePrefix: ue_sim_ci
+ outputfilename: "ue_usim.conf"
+ config:
+ - key: MNC
+ env: "@MNC@"
+ - key: MCC
+ env: "@MCC@"
+ - key: MSIN
+ env: "@SHORT_IMSI@"
+ - key: USIM_API_K
+ env: "@LTE_KEY@"
+ - key: OPC
+ env: "@OPC@"
+ - key: MSISDN
+ env: "@MSISDN@"
+ - key: HPLMN
+ env: "@HPLMN@"
+ - key: OPLMN_LIST
+ env: "@HPLMN@"
+
diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c
index 4047ff1386..8b3d6fc64e 100644
--- a/executables/nr-gnb.c
+++ b/executables/nr-gnb.c
@@ -355,7 +355,9 @@ void init_gNB_Tpool(int inst) {
// ULSCH decoding threadpool
gNB->threadPool = (tpool_t*)malloc(sizeof(tpool_t));
int numCPU = sysconf(_SC_NPROCESSORS_ONLN);
+ LOG_I(PHY,"Number of threads requested in config file: %d, Number of threads available on this machine: %d\n",gNB->pusch_proc_threads,numCPU);
int threadCnt = min(numCPU, gNB->pusch_proc_threads);
+ if (threadCnt < 2) LOG_E(PHY,"Number of threads for gNB should be more than 1. Allocated only %d\n",threadCnt);
char ul_pool[80];
sprintf(ul_pool,"-1");
int s_offset = 0;
diff --git a/executables/nr-ue.c b/executables/nr-ue.c
index 2adf373196..a35a11a033 100644
--- a/executables/nr-ue.c
+++ b/executables/nr-ue.c
@@ -27,6 +27,8 @@
#include "SCHED_NR_UE/phy_frame_config_nr.h"
#include "SCHED_NR_UE/defs.h"
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
+#include "executables/softmodem-common.h"
+#include "SCHED_NR_UE/pucch_uci_ue_nr.h"
/*
* NR SLOT PROCESSING SEQUENCE
@@ -85,6 +87,14 @@
*
*/
+#ifndef NO_RAT_NR
+ #define DURATION_RX_TO_TX (NR_UE_CAPABILITY_SLOT_RX_TO_TX) /* for NR this will certainly depends to such UE capability which is not yet defined */
+#else
+ #define DURATION_RX_TO_TX (6) /* For LTE, this duration is fixed to 4 and it is linked to LTE standard for both modes FDD/TDD */
+#endif
+#define RX_JOB_ID 0x1010
+#define TX_JOB_ID 100
+
typedef enum {
pss = 0,
pbch = 1,
@@ -101,6 +111,7 @@ void init_nr_ue_vars(PHY_VARS_NR_UE *ue,
ue->Mod_id = UE_id;
ue->mac_enabled = 1;
ue->if_inst = nr_ue_if_module_init(0);
+ ue->dci_thres = 0;
// Setting UE mode to NOT_SYNCHED by default
for (gNB_id = 0; gNB_id < nb_connected_gNB; gNB_id++){
@@ -123,10 +134,7 @@ void init_nr_ue_vars(PHY_VARS_NR_UE *ue,
* \param arg is a pointer to a \ref PHY_VARS_NR_UE structure.
*/
-typedef struct syncData_s {
- UE_nr_rxtx_proc_t proc;
- PHY_VARS_NR_UE *UE;
-} syncData_t;
+typedef nr_rxtx_thread_data_t syncData_t;
static void UE_synch(void *arg) {
syncData_t *syncD=(syncData_t *) arg;
@@ -273,7 +281,11 @@ static void UE_synch(void *arg) {
}
}
-void processSlotTX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
+void processSlotTX(void *arg) {
+
+ nr_rxtx_thread_data_t *rxtxD = (nr_rxtx_thread_data_t *) arg;
+ UE_nr_rxtx_proc_t *proc = &rxtxD->proc;
+ PHY_VARS_NR_UE *UE = rxtxD->UE;
fapi_nr_config_request_t *cfg = &UE->nrUE_config;
int tx_slot_type = nr_ue_slot_select(cfg, proc->frame_tx, proc->nr_slot_tx);
uint8_t gNB_id = 0;
@@ -304,10 +316,14 @@ void processSlotTX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
}
}
-void processSlotRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
+void processSlotRX(void *arg) {
+ nr_rxtx_thread_data_t *rxtxD = (nr_rxtx_thread_data_t *) arg;
+ UE_nr_rxtx_proc_t *proc = &rxtxD->proc;
+ PHY_VARS_NR_UE *UE = rxtxD->UE;
fapi_nr_config_request_t *cfg = &UE->nrUE_config;
int rx_slot_type = nr_ue_slot_select(cfg, proc->frame_rx, proc->nr_slot_rx);
+ int tx_slot_type = nr_ue_slot_select(cfg, proc->frame_tx, proc->nr_slot_tx);
uint8_t gNB_id = 0;
if (rx_slot_type == NR_DOWNLINK_SLOT || rx_slot_type == NR_MIXED_SLOT){
@@ -323,7 +339,7 @@ void processSlotRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
phy_procedures_slot_parallelization_nrUE_RX( UE, proc, 0, 0, 1, no_relay, NULL );
#else
uint64_t a=rdtsc();
- phy_procedures_nrUE_RX(UE, proc, gNB_id, get_nrUE_params()->nr_dlsch_parallel);
+ phy_procedures_nrUE_RX(UE, proc, gNB_id, get_nrUE_params()->nr_dlsch_parallel, &rxtxD->txFifo);
LOG_D(PHY, "In %s: slot %d, time %lu\n", __FUNCTION__, proc->nr_slot_rx, (rdtsc()-a)/3500);
#endif
@@ -341,34 +357,38 @@ void processSlotRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
nr_pdcp_tick(proc->frame_rx, proc->nr_slot_rx / UE->frame_parms.slots_per_subframe);
}
}
+
+ // Wait for PUSCH processing to finish
+ notifiedFIFO_elt_t *res;
+ res = pullTpool(&rxtxD->txFifo,&(get_nrUE_params()->Tpool));
+ delNotifiedFIFO_elt(res);
+
+ } else {
+ processSlotTX(rxtxD);
}
-}
+ if (tx_slot_type == NR_UPLINK_SLOT || tx_slot_type == NR_MIXED_SLOT){
+ if (UE->UE_mode[gNB_id] <= PUSCH) {
+ if (get_softmodem_params()->usim_test==0) {
+ pucch_procedures_ue_nr(UE,
+ gNB_id,
+ proc,
+ FALSE);
+ }
-/*!
- * \brief This is the UE thread for RX subframe n and TX subframe n+4.
- * This thread performs the phy_procedures_UE_RX() on every received slot.
- * then, if TX is enabled it performs TX for n+4.
- * \param arg is a pointer to a \ref PHY_VARS_NR_UE structure.
- * \returns a pointer to an int. The storage is not on the heap and must not be freed.
- */
+ LOG_D(PHY, "Sending Uplink data \n");
+ nr_ue_pusch_common_procedures(UE,
+ proc->nr_slot_tx,
+ &UE->frame_parms,1);
+ }
-typedef struct processingData_s {
- UE_nr_rxtx_proc_t proc;
- PHY_VARS_NR_UE *UE;
-} processingData_t;
-
-void UE_processing(void *arg) {
- processingData_t *rxtxD = (processingData_t *) arg;
- UE_nr_rxtx_proc_t *proc = &rxtxD->proc;
- PHY_VARS_NR_UE *UE = rxtxD->UE;
- int slot_tx = proc->nr_slot_tx;
- int frame_tx = proc->frame_tx;
-
- processSlotRX(UE, proc);
- processSlotTX(UE, proc);
- ue_ta_procedures(UE, slot_tx, frame_tx);
+ if (UE->UE_mode[gNB_id] > NOT_SYNCHED && UE->UE_mode[gNB_id] < PUSCH) {
+ nr_ue_prach_procedures(UE, proc, gNB_id);
+ }
+ LOG_D(PHY,"****** end TX-Chain for AbsSubframe %d.%d ******\n", proc->frame_tx, proc->nr_slot_tx);
+ }
+ ue_ta_procedures(UE, proc->nr_slot_tx, proc->frame_tx);
}
void dummyWrite(PHY_VARS_NR_UE *UE,openair0_timestamp timestamp, int writeBlockSize) {
@@ -485,25 +505,44 @@ void *UE_thread(void *arg) {
int start_rx_stream = 0;
AssertFatal(0== openair0_device_load(&(UE->rfdevice), &openair0_cfg[0]), "");
UE->rfdevice.host_type = RAU_HOST;
+ UE->lost_sync = 0;
+ UE->is_synchronized = 0;
AssertFatal(UE->rfdevice.trx_start_func(&UE->rfdevice) == 0, "Could not start the device\n");
+
notifiedFIFO_t nf;
initNotifiedFIFO(&nf);
- int nbSlotProcessing=0;
- int thread_idx=0;
+
notifiedFIFO_t freeBlocks;
initNotifiedFIFO_nothreadSafe(&freeBlocks);
+
+ int nbSlotProcessing=0;
+ int thread_idx=0;
NR_UE_MAC_INST_t *mac = get_mac_inst(0);
int timing_advance = UE->timing_advance;
- for (int i=0; iframe_parms.slots_per_frame;
int absolute_slot=0, decoded_frame_rx=INT_MAX, trashed_frames=0;
+ for (int i=0; itxFifo);
+ pushNotifiedFIFO_nothreadSafe(&freeBlocks, newElt);
+ }
+
while (!oai_exit) {
+ if (UE->lost_sync) {
+ int nb = abortTpool(&(get_nrUE_params()->Tpool),RX_JOB_ID);
+ nb += abortNotifiedFIFO(&nf, RX_JOB_ID);
+ LOG_I(PHY,"Number of aborted slots %d\n",nb);
+ for (int i=0; iis_synchronized = 0;
+ UE->lost_sync = 0;
+ }
+
if (syncRunning) {
notifiedFIFO_elt_t *res=tryPullTpool(&nf,&(get_nrUE_params()->Tpool));
@@ -513,9 +552,10 @@ void *UE_thread(void *arg) {
if (UE->is_synchronized) {
decoded_frame_rx=(((mac->mib->systemFrameNumber.buf[0] >> mac->mib->systemFrameNumber.bits_unused)<<4) | tmp->proc.decoded_frame_rx);
// shift the frame index with all the frames we trashed meanwhile we perform the synch search
- decoded_frame_rx=(decoded_frame_rx + (!UE->init_sync_frame) + trashed_frames) % MAX_FRAME_NUMBER;
+ decoded_frame_rx=(decoded_frame_rx + UE->init_sync_frame + trashed_frames) % MAX_FRAME_NUMBER;
}
delNotifiedFIFO_elt(res);
+ start_rx_stream=0;
} else {
readFrame(UE, ×tamp, true);
trashed_frames+=2;
@@ -562,13 +602,13 @@ void *UE_thread(void *arg) {
// whatever means thread_idx
// Fix me: will be wrong when slot 1 is slow, as slot 2 finishes
- // Slot 3 will overlap if RX_NB_TH is 2
+ // Slot 3 will overlap if NR_RX_NB_TH is 2
// this is general failure in UE !!!
- thread_idx = absolute_slot % RX_NB_TH;
+ thread_idx = absolute_slot % NR_RX_NB_TH;
int slot_nr = absolute_slot % nb_slot_frame;
notifiedFIFO_elt_t *msgToPush;
- AssertFatal((msgToPush=pullNotifiedFIFO_nothreadSafe(&freeBlocks)) != NULL,"chained list failure");
- processingData_t *curMsg=(processingData_t *)NotifiedFifoData(msgToPush);
+ AssertFatal((msgToPush=pullTpool(&freeBlocks,&(get_nrUE_params()->Tpool))) != NULL,"chained list failure");
+ nr_rxtx_thread_data_t *curMsg=(nr_rxtx_thread_data_t *)NotifiedFifoData(msgToPush);
curMsg->UE=UE;
// update thread index for received subframe
curMsg->proc.thread_id = thread_idx;
@@ -596,18 +636,18 @@ void *UE_thread(void *arg) {
for (int i=0; iframe_parms.nb_antennas_tx; i++)
txp[i] = (void *)&UE->common_vars.txdata[i][UE->frame_parms.get_samples_slot_timestamp(
- ((slot_nr + DURATION_RX_TO_TX - RX_NB_TH)%nb_slot_frame),&UE->frame_parms,0)];
+ ((slot_nr + DURATION_RX_TO_TX - NR_RX_NB_TH)%nb_slot_frame),&UE->frame_parms,0)];
int readBlockSize, writeBlockSize;
if (slot_nr<(nb_slot_frame - 1)) {
readBlockSize=get_readBlockSize(slot_nr, &UE->frame_parms);
- writeBlockSize=UE->frame_parms.get_samples_per_slot((slot_nr + DURATION_RX_TO_TX - RX_NB_TH) % nb_slot_frame, &UE->frame_parms);
+ writeBlockSize=UE->frame_parms.get_samples_per_slot((slot_nr + DURATION_RX_TO_TX - NR_RX_NB_TH) % nb_slot_frame, &UE->frame_parms);
} else {
UE->rx_offset_diff = computeSamplesShift(UE);
readBlockSize=get_readBlockSize(slot_nr, &UE->frame_parms) -
UE->rx_offset_diff;
- writeBlockSize=UE->frame_parms.get_samples_per_slot((slot_nr + DURATION_RX_TO_TX - RX_NB_TH) % nb_slot_frame, &UE->frame_parms)- UE->rx_offset_diff;
+ writeBlockSize=UE->frame_parms.get_samples_per_slot((slot_nr + DURATION_RX_TO_TX - NR_RX_NB_TH) % nb_slot_frame, &UE->frame_parms)- UE->rx_offset_diff;
}
AssertFatal(readBlockSize ==
@@ -639,27 +679,27 @@ void *UE_thread(void *arg) {
notifiedFIFO_elt_t *res;
- while (nbSlotProcessing >= RX_NB_TH) {
+ while (nbSlotProcessing >= NR_RX_NB_TH) {
res=pullTpool(&nf, &(get_nrUE_params()->Tpool));
nbSlotProcessing--;
- processingData_t *tmp=(processingData_t *)res->msgData;
+ nr_rxtx_thread_data_t *tmp=(nr_rxtx_thread_data_t *)res->msgData;
if (tmp->proc.decoded_frame_rx != -1)
decoded_frame_rx=(((mac->mib->systemFrameNumber.buf[0] >> mac->mib->systemFrameNumber.bits_unused)<<4) | tmp->proc.decoded_frame_rx);
- else
+ else
decoded_frame_rx=-1;
pushNotifiedFIFO_nothreadSafe(&freeBlocks,res);
}
- if ( decoded_frame_rx>0 && decoded_frame_rx != curMsg->proc.frame_rx)
+ if (decoded_frame_rx>0 && decoded_frame_rx != curMsg->proc.frame_rx)
LOG_E(PHY,"Decoded frame index (%d) is not compatible with current context (%d), UE should go back to synch mode\n",
- decoded_frame_rx, curMsg->proc.frame_rx );
+ decoded_frame_rx, curMsg->proc.frame_rx);
// use previous timing_advance value to compute writeTimestamp
writeTimestamp = timestamp+
UE->frame_parms.get_samples_slot_timestamp(slot_nr,&UE->frame_parms,DURATION_RX_TO_TX
- - RX_NB_TH) - firstSymSamp - openair0_cfg[0].tx_sample_advance -
+ - NR_RX_NB_TH) - firstSymSamp - openair0_cfg[0].tx_sample_advance -
UE->N_TA_offset - timing_advance;
// but use current UE->timing_advance value to compute writeBlockSize
@@ -669,7 +709,7 @@ void *UE_thread(void *arg) {
}
int flags = 0;
- int slot_tx_usrp = slot_nr + DURATION_RX_TO_TX - RX_NB_TH;
+ int slot_tx_usrp = slot_nr + DURATION_RX_TO_TX - NR_RX_NB_TH;
if (openair0_cfg[0].duplex_mode == duplex_mode_TDD) {
@@ -701,26 +741,9 @@ void *UE_thread(void *arg) {
memset(txp[i], 0, writeBlockSize);
nbSlotProcessing++;
- msgToPush->key=slot_nr;
+ LOG_D(PHY,"Number of slots being processed at the moment: %d\n",nbSlotProcessing);
pushTpool(&(get_nrUE_params()->Tpool), msgToPush);
- if (IS_SOFTMODEM_RFSIM) { //getenv("RFSIMULATOR")
- // FixMe: Wait previous thread is done, because race conditions seems too bad
- // in case of actual RF board, the overlap between threads mitigate the issue
- // We must receive one message, that proves the slot processing is done
- res=pullTpool(&nf, &(get_nrUE_params()->Tpool));
- nbSlotProcessing--;
- processingData_t *tmp=(processingData_t *)res->msgData;
-
- if (tmp->proc.decoded_frame_rx != -1)
- decoded_frame_rx=(((mac->mib->systemFrameNumber.buf[0] >> mac->mib->systemFrameNumber.bits_unused)<<4) | tmp->proc.decoded_frame_rx);
- else
- decoded_frame_rx=-1;
- //decoded_frame_rx=tmp->proc.decoded_frame_rx;
-
- pushNotifiedFIFO_nothreadSafe(&freeBlocks,res);
- }
-
} // while !oai_exit
return NULL;
diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c
index 174d5409bd..13a191a18a 100644
--- a/executables/nr-uesoftmodem.c
+++ b/executables/nr-uesoftmodem.c
@@ -232,9 +232,16 @@ nrUE_params_t *get_nrUE_params(void) {
}
/* initialie thread pools used for NRUE processing paralleliation */
void init_tpools(uint8_t nun_dlsch_threads) {
- char *params=calloc(1,(RX_NB_TH*3)+1);
- for (int i=0; iStartSymbolIndex;
cset_nsymb = pdcch_pdu_rel15->DurationSymbols;
dci_idx = 0;
- LOG_D(PHY, "Coreset rb_offset %d, nb_rb %d\n",rb_offset,n_rb);
+ LOG_D(PHY, "Coreset rb_offset %d, nb_rb %d BWP Start %d\n",rb_offset,n_rb,pdcch_pdu_rel15->BWPStart);
LOG_D(PHY, "Coreset starting subcarrier %d on symbol %d (%d symbols)\n", cset_start_sc, cset_start_symb, cset_nsymb);
// DMRS length is per OFDM symbol
uint32_t dmrs_length = n_rb*6; //2(QPSK)*3(per RB)*6(REG per CCE)
@@ -196,9 +196,9 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
// dmrs index depends on reference point for k according to 38.211 7.4.1.3.2
if (pdcch_pdu_rel15->CoreSetType == NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG)
- dmrs_idx =gNB->cce_list[d][cce_idx].reg_list[reg_in_cce_idx].reg_idx * 3;
+ dmrs_idx =(gNB->cce_list[d][cce_idx].reg_list[reg_in_cce_idx].reg_idx / pdcch_pdu_rel15->DurationSymbols) * 3;
else
- dmrs_idx = (gNB->cce_list[d][cce_idx].reg_list[reg_in_cce_idx].reg_idx + rb_offset) * 3;
+ dmrs_idx = (gNB->cce_list[d][cce_idx].reg_list[reg_in_cce_idx].reg_idx / pdcch_pdu_rel15->DurationSymbols + rb_offset) * 3;
k_prime = 0;
diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
index 8176514eb4..c1cebc64a8 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
@@ -874,6 +874,33 @@ void nr_pdcch_unscrambling(int16_t *z,
#ifdef NR_PDCCH_DCI_RUN
+/* This function compares the received DCI bits with
+ * re-encoded DCI bits and returns the number of mismatched bits
+ */
+uint16_t nr_dci_false_detection(uint64_t *dci,
+ int16_t *soft_in,
+ const t_nrPolar_params *polar_param,
+ int encoded_length,
+ int rnti) {
+
+ uint32_t encoder_output[NR_MAX_DCI_SIZE_DWORD];
+ polar_encoder_fast(dci, (void*)encoder_output, rnti, 1, polar_param);
+ uint8_t *enout_p = (uint8_t*)encoder_output;
+ uint16_t x = 0;
+
+ for (int i=0; i> 15 ) & 1);
+ x += ( ( enout_p[i] >> 1 ) & 1 ) ^ ( ( soft_in[i*8+1] >> 15 ) & 1 );
+ x += ( ( enout_p[i] >> 2 ) & 1 ) ^ ( ( soft_in[i*8+2] >> 15 ) & 1 );
+ x += ( ( enout_p[i] >> 3 ) & 1 ) ^ ( ( soft_in[i*8+3] >> 15 ) & 1 );
+ x += ( ( enout_p[i] >> 4 ) & 1 ) ^ ( ( soft_in[i*8+4] >> 15 ) & 1 );
+ x += ( ( enout_p[i] >> 5 ) & 1 ) ^ ( ( soft_in[i*8+5] >> 15 ) & 1 );
+ x += ( ( enout_p[i] >> 6 ) & 1 ) ^ ( ( soft_in[i*8+6] >> 15 ) & 1 );
+ x += ( ( enout_p[i] >> 7 ) & 1 ) ^ ( ( soft_in[i*8+7] >> 15 ) & 1 );
+ }
+ return x;
+}
+
uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
fapi_nr_dci_indication_t *dci_ind) {
@@ -920,15 +947,23 @@ uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue,
if (crc == n_rnti) {
LOG_D(PHY, "(%i.%i) Received dci indication (rnti %x,dci format %d,n_CCE %d,payloadSize %d,payload %llx)\n",
proc->frame_rx, proc->nr_slot_rx,n_rnti,rel15->dci_format_options[k],CCEind,dci_length,*(unsigned long long*)dci_estimation);
- dci_ind->SFN = proc->frame_rx;
- dci_ind->slot = proc->nr_slot_rx;
- dci_ind->dci_list[dci_ind->number_of_dcis].rnti = n_rnti;
- dci_ind->dci_list[dci_ind->number_of_dcis].n_CCE = CCEind;
- dci_ind->dci_list[dci_ind->number_of_dcis].dci_format = rel15->dci_format_options[k];
- dci_ind->dci_list[dci_ind->number_of_dcis].payloadSize = dci_length;
- memcpy((void*)dci_ind->dci_list[dci_ind->number_of_dcis].payloadBits,(void*)dci_estimation,8);
- dci_ind->number_of_dcis++;
- break; // If DCI is found, no need to check for remaining DCI lengths
+ uint16_t mb = nr_dci_false_detection(dci_estimation,tmp_e,currentPtrDCI,L*108,n_rnti);
+ ue->dci_thres = (ue->dci_thres + mb) / 2;
+ if (mb > (ue->dci_thres+20)) {
+ LOG_W(PHY,"DCI false positive. Dropping DCI index %d. Mismatched bits: %d/%d. Current DCI threshold: %d\n",j,mb,L*108,ue->dci_thres);
+ continue;
+ }
+ else {
+ dci_ind->SFN = proc->frame_rx;
+ dci_ind->slot = proc->nr_slot_rx;
+ dci_ind->dci_list[dci_ind->number_of_dcis].rnti = n_rnti;
+ dci_ind->dci_list[dci_ind->number_of_dcis].n_CCE = CCEind;
+ dci_ind->dci_list[dci_ind->number_of_dcis].dci_format = rel15->dci_format_options[k];
+ dci_ind->dci_list[dci_ind->number_of_dcis].payloadSize = dci_length;
+ memcpy((void*)dci_ind->dci_list[dci_ind->number_of_dcis].payloadBits,(void*)dci_estimation,8);
+ dci_ind->number_of_dcis++;
+ break; // If DCI is found, no need to check for remaining DCI lengths
+ }
} else {
LOG_D(PHY,"(%i.%i) Decoded crc %x does not match rnti %x for DCI format %d\n", proc->frame_rx, proc->nr_slot_rx, crc, n_rnti, rel15->dci_format_options[k]);
}
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
index bfef89ea85..df35f14869 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
@@ -308,12 +308,15 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, int n_frames)
// every 7*(1<symbol_offset/(7*(1<ofdm_symbol_size + fp->nb_prefix_samples0)+(ue->symbol_offset-n_symb_prefix0)*(fp->ofdm_symbol_size + fp->nb_prefix_samples);
- if (ue->ssb_offset < sync_pos_frame)
+ // for a correct computation of frame number to sync with the one decoded at MIB we need to take into account in which of the n_frames we got sync
+ ue->init_sync_frame = n_frames - 1 - is;
+ // we also need to take into account the shift by samples_per_frame in case the if is true
+ if (ue->ssb_offset < sync_pos_frame){
ue->rx_offset = fp->samples_per_frame - sync_pos_frame + ue->ssb_offset;
+ ue->init_sync_frame += 1;
+ }
else
ue->rx_offset = ue->ssb_offset - sync_pos_frame;
-
- ue->init_sync_frame = is;
}
/*
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c
index ef884512fd..66c3de97ea 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c
@@ -589,7 +589,7 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
frame_parms->ssb_index += (((nr_ue_pbch_vars->xtra_byte>>(7-i))&0x01)<<(3+i));
}
- ue->symbol_offset = nr_get_ssb_start_symbol(frame_parms,i_ssb);
+ ue->symbol_offset = nr_get_ssb_start_symbol(frame_parms,frame_parms->ssb_index);
if (frame_parms->half_frame_bit)
ue->symbol_offset += (frame_parms->slots_per_frame>>1)*frame_parms->symbols_per_slot;
diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h
index bf0a7bc9e5..e3c0737838 100644
--- a/openair1/PHY/defs_nr_UE.h
+++ b/openair1/PHY/defs_nr_UE.h
@@ -763,6 +763,8 @@ typedef struct {
int is_synchronized;
/// \brief Indicates on which frame is synchronized in a two frame synchronization
int is_synchronized_on_frame;
+ /// \brief Indicator that UE lost frame synchronization
+ int lost_sync;
/// Data structure for UE process scheduling
UE_nr_proc_t proc;
/// Flag to indicate the UE shouldn't do timing correction at all
@@ -789,6 +791,8 @@ typedef struct {
uint8_t ho_initiated;
/// \brief indicator that Handover procedure has been triggered
uint8_t ho_triggered;
+ /// threshold for false dci detection
+ int dci_thres;
/// \brief Measurement variables.
PHY_NR_MEASUREMENTS measurements;
NR_DL_FRAME_PARMS frame_parms;
@@ -1080,6 +1084,7 @@ typedef struct {
typedef struct nr_rxtx_thread_data_s {
UE_nr_rxtx_proc_t proc;
PHY_VARS_NR_UE *UE;
+ notifiedFIFO_t txFifo;
} nr_rxtx_thread_data_t;
#include "SIMULATION/ETH_TRANSPORT/defs.h"
diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h
index 398252c37b..d1d69ecabe 100644
--- a/openair1/PHY/defs_nr_common.h
+++ b/openair1/PHY/defs_nr_common.h
@@ -109,6 +109,8 @@
#define MAX_NUM_NR_CHANNEL_BITS (14*273*12*8) // 14 symbols, 273 RB
#define MAX_NUM_NR_RE (14*273*12)
+#define NR_RX_NB_TH 1
+#define NR_NB_TH_SLOT 2
extern const uint8_t nr_rv_round_map[4];
extern const uint8_t nr_rv_round_map_ue[4];
diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
index 9034c76f2c..ce7f5cd524 100644
--- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c
+++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
@@ -564,6 +564,10 @@ void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
gNB->uci_pdu_list[num_ucis].pdu_size = sizeof(nfapi_nr_uci_pucch_pdu_format_0_1_t);
nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu_format0 = &gNB->uci_pdu_list[num_ucis].pucch_pdu_format_0_1;
+ offset = pucch_pdu->start_symbol_index*gNB->frame_parms.ofdm_symbol_size + (gNB->frame_parms.first_carrier_offset+pucch_pdu->prb_start*12);
+ power_rxF = signal_energy_nodc(&gNB->common_vars.rxdataF[0][offset],12);
+ LOG_D(PHY,"frame %d, slot %d: PUCCH signal energy %d\n",frame_rx,slot_rx,power_rxF);
+
nr_decode_pucch0(gNB,
slot_rx,
uci_pdu_format0,
diff --git a/openair1/SCHED_NR_UE/defs.h b/openair1/SCHED_NR_UE/defs.h
index f7f44a520d..2675e46a04 100644
--- a/openair1/SCHED_NR_UE/defs.h
+++ b/openair1/SCHED_NR_UE/defs.h
@@ -115,14 +115,17 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t
@param proc Pointer to proc information
@param gNB_id Local id of eNB on which to act
@param dlsch_parallel use multithreaded dlsch processing
+ @param txFifo Result fifo if PDSCH is run in parallel
*/
int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
uint8_t gNB_id,
- uint8_t dlsch_parallel);
+ uint8_t dlsch_parallel,
+ notifiedFIFO_t *txFifo);
int phy_procedures_slot_parallelization_nrUE_RX(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t eNB_id, uint8_t abstraction_flag, uint8_t do_pdcch_flag, relaying_type_t r_type);
+void processSlotTX(void *arg);
#ifdef UE_SLOT_PARALLELISATION
void *UE_thread_slot1_dl_processing(void *arg);
diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
index 54464446a5..c8ac871bbf 100644
--- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
+++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
@@ -127,6 +127,8 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
// dlsch0_harq->status not ACTIVE may be due to false retransmission. Reset the
// following flag to skip PDSCH procedures in that case.
dlsch0->active = 0;
+ dlsch0_harq->harq_ack.ack = 1;
+ dlsch0_harq->harq_ack.send_harq_status = 1;
}
dlsch0_harq->harq_ack.vDAI_DL = dlsch_config_pdu->dai;
/* PTRS */
diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
index 60fe897456..ba81d9b205 100644
--- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
+++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
@@ -142,7 +142,7 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind,
case FAPI_NR_RX_PDU_TYPE_MIB:
rx_ind->rx_indication_body[n_pdus - 1].mib_pdu.pdu = ue->pbch_vars[gNB_id]->decoded_output;
rx_ind->rx_indication_body[n_pdus - 1].mib_pdu.additional_bits = ue->pbch_vars[gNB_id]->xtra_byte;
- rx_ind->rx_indication_body[n_pdus - 1].mib_pdu.ssb_index = frame_parms->ssb_index;
+ rx_ind->rx_indication_body[n_pdus - 1].mib_pdu.ssb_index = (frame_parms->ssb_index)&0x7;
rx_ind->rx_indication_body[n_pdus - 1].mib_pdu.ssb_length = frame_parms->Lmax;
rx_ind->rx_indication_body[n_pdus - 1].mib_pdu.cell_id = frame_parms->Nid_cell;
break;
@@ -275,26 +275,8 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue,
nr_ue_ulsch_procedures(ue, harq_pid, frame_tx, slot_tx, proc->thread_id, gNB_id);
}
- if (get_softmodem_params()->usim_test==0) {
- LOG_D(PHY, "Generating PUCCH\n");
- pucch_procedures_ue_nr(ue,
- gNB_id,
- proc,
- FALSE);
- }
-
- LOG_D(PHY, "Sending Uplink data \n");
- nr_ue_pusch_common_procedures(ue,
- slot_tx,
- &ue->frame_parms,1);
-
}
- if (ue->UE_mode[gNB_id] > NOT_SYNCHED && ue->UE_mode[gNB_id] < PUSCH) {
- nr_ue_prach_procedures(ue, proc, gNB_id);
- }
- LOG_D(PHY,"****** end TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, slot_tx);
-
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX, VCD_FUNCTION_OUT);
#if UE_TIMING_TRACE
stop_meas(&ue->phy_proc_tx);
@@ -368,7 +350,7 @@ void nr_ue_pbch_procedures(uint8_t gNB_id,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PBCH_PROCEDURES, VCD_FUNCTION_IN);
- LOG_D(PHY,"[UE %d] Frame %d, Trying PBCH (NidCell %d, gNB_id %d)\n",ue->Mod_id,frame_rx,ue->frame_parms.Nid_cell,gNB_id);
+ LOG_D(PHY,"[UE %d] Frame %d Slot %d, Trying PBCH (NidCell %d, gNB_id %d)\n",ue->Mod_id,frame_rx,nr_slot_rx,ue->frame_parms.Nid_cell,gNB_id);
ret = nr_rx_pbch(ue, proc,
ue->pbch_vars[gNB_id],
@@ -435,8 +417,13 @@ void nr_ue_pbch_procedures(uint8_t gNB_id,
ue->pbch_vars[gNB_id]->pdu_errors++;
if (ue->pbch_vars[gNB_id]->pdu_errors_conseq>=100) {
- LOG_E(PHY,"More that 100 consecutive PBCH errors! Exiting!\n");
- exit_fun("More that 100 consecutive PBCH errors! Exiting!\n");
+ if (get_softmodem_params()->non_stop) {
+ LOG_E(PHY,"More that 100 consecutive PBCH errors! Going back to Sync mode!\n");
+ ue->lost_sync = 1;
+ } else {
+ LOG_E(PHY,"More that 100 consecutive PBCH errors! Exiting!\n");
+ exit_fun("More that 100 consecutive PBCH errors! Exiting!\n");
+ }
}
}
@@ -1615,7 +1602,8 @@ int is_pbch_in_slot(fapi_nr_config_request_t *config, int frame, int slot, NR_DL
int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
uint8_t gNB_id,
- uint8_t dlsch_parallel
+ uint8_t dlsch_parallel,
+ notifiedFIFO_t *txFifo
)
{
int frame_rx = proc->frame_rx;
@@ -1772,6 +1760,13 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
}
#endif //NR_PDCCH_SCHED
+
+ // Start PUSCH processing here. It runs in parallel with PDSCH processing
+ notifiedFIFO_elt_t *newElt = newNotifiedFIFO_elt(sizeof(nr_rxtx_thread_data_t), proc->nr_slot_tx,txFifo,processSlotTX);
+ nr_rxtx_thread_data_t *curMsg=(nr_rxtx_thread_data_t *)NotifiedFifoData(newElt);
+ curMsg->proc = *proc;
+ curMsg->UE = ue;
+ pushTpool(&(get_nrUE_params()->Tpool), newElt);
#if UE_TIMING_TRACE
start_meas(&ue->generic_stat);
@@ -1904,6 +1899,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT);
}
+
#if UE_TIMING_TRACE
start_meas(&ue->generic_stat);
#endif
diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c
index de8891d8db..3b265ec407 100644
--- a/openair1/SIMULATION/NR_PHY/dlsim.c
+++ b/openair1/SIMULATION/NR_PHY/dlsim.c
@@ -204,6 +204,8 @@ int is_x2ap_enabled(void)
return 0;
}
+void processSlotTX(void *arg) {}
+
//nFAPI P7 dummy functions
int oai_nfapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req) { return(0); }
@@ -288,6 +290,20 @@ void nr_dlsim_preprocessor(module_id_t module_id,
AssertFatal(ps->mcsTableIdx >= 0 && ps->mcsTableIdx <= 2, "invalid mcsTableIdx %d\n", ps->mcsTableIdx);
}
+typedef struct {
+ uint64_t optmask; //mask to store boolean config options
+ uint8_t nr_dlsch_parallel; // number of threads for dlsch decoding, 0 means no parallelization
+ tpool_t Tpool; // thread pool
+} nrUE_params_t;
+
+nrUE_params_t nrUE_params;
+
+nrUE_params_t *get_nrUE_params(void) {
+ return &nrUE_params;
+}
+
+void do_nothing(void *args) {
+}
int main(int argc, char **argv)
{
@@ -719,13 +735,7 @@ int main(int argc, char **argv)
prepare_scd(scd);
- fill_default_secondaryCellGroup(scc,
- scd,
- secondaryCellGroup,
- 0,
- 1,
- n_tx,
- 0);
+ fill_default_secondaryCellGroup(scc, scd, secondaryCellGroup, 0, 1, n_tx, 0, 0);
/* RRC parameter validation for secondaryCellGroup */
fix_scd(scd);
@@ -887,6 +897,7 @@ int main(int argc, char **argv)
unsigned int errors_bit = 0;
uint32_t errors_scrambling = 0;
+ initTpool("N", &(nrUE_params.Tpool), false);
test_input_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384);
estimated_output_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384);
@@ -1137,7 +1148,8 @@ int main(int argc, char **argv)
phy_procedures_nrUE_RX(UE,
&UE_proc,
0,
- dlsch_threads);
+ dlsch_threads,
+ NULL);
//printf("dlsim round %d ends\n",round);
round++;
diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c
index d6723ba148..bba0a6996f 100644
--- a/openair1/SIMULATION/NR_PHY/prachsim.c
+++ b/openair1/SIMULATION/NR_PHY/prachsim.c
@@ -174,6 +174,20 @@ int nr_derive_key(int alg_type, uint8_t alg_id,
return 0;
}
+typedef struct {
+ uint64_t optmask; //mask to store boolean config options
+ uint8_t nr_dlsch_parallel; // number of threads for dlsch decoding, 0 means no parallelization
+ tpool_t Tpool; // thread pool
+} nrUE_params_t;
+
+nrUE_params_t nrUE_params;
+
+nrUE_params_t *get_nrUE_params(void) {
+ return &nrUE_params;
+}
+
+void processSlotTX(void *arg) {}
+
int main(int argc, char **argv){
char c;
diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c
index 26c442cd4f..d919b48dd1 100644
--- a/openair1/SIMULATION/NR_PHY/ulsim.c
+++ b/openair1/SIMULATION/NR_PHY/ulsim.c
@@ -198,6 +198,19 @@ int nr_derive_key(int alg_type, uint8_t alg_id,
return 0;
}
+typedef struct {
+ uint64_t optmask; //mask to store boolean config options
+ uint8_t nr_dlsch_parallel; // number of threads for dlsch decoding, 0 means no parallelization
+ tpool_t Tpool; // thread pool
+} nrUE_params_t;
+
+void processSlotTX(void *arg) {}
+
+nrUE_params_t nrUE_params;
+
+nrUE_params_t *get_nrUE_params(void) {
+ return &nrUE_params;
+}
// needed for some functions
uint16_t n_rnti = 0x1234;
openair0_config_t openair0_cfg[MAX_CARDS];
@@ -664,13 +677,7 @@ int main(int argc, char **argv)
prepare_scd(scd);
- fill_default_secondaryCellGroup(scc,
- scd,
- secondaryCellGroup,
- 0,
- 1,
- n_tx,
- 0);
+ fill_default_secondaryCellGroup(scc, scd, secondaryCellGroup, 0, 1, n_tx, 0, 0);
// xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void*)secondaryCellGroup);
diff --git a/openair2/GNB_APP/MACRLC_nr_paramdef.h b/openair2/GNB_APP/MACRLC_nr_paramdef.h
index 308af2eeb9..60b40cb349 100644
--- a/openair2/GNB_APP/MACRLC_nr_paramdef.h
+++ b/openair2/GNB_APP/MACRLC_nr_paramdef.h
@@ -55,7 +55,7 @@
#define CONFIG_STRING_MACRLC_REMOTE_S_PORTC "remote_s_portc"
#define CONFIG_STRING_MACRLC_LOCAL_S_PORTD "local_s_portd"
#define CONFIG_STRING_MACRLC_REMOTE_S_PORTD "remote_s_portd"
-
+#define CONFIG_STRING_MACRLC_ULSCH_MAX_SLOTS_INACTIVITY "ulsch_max_slots_inactivity"
/*-------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* MacRLC configuration parameters */
@@ -79,6 +79,7 @@
{CONFIG_STRING_MACRLC_REMOTE_S_PORTC, NULL, 0, uptr:NULL, defintval:50020, TYPE_UINT, 0}, \
{CONFIG_STRING_MACRLC_LOCAL_S_PORTD, NULL, 0, uptr:NULL, defintval:50021, TYPE_UINT, 0}, \
{CONFIG_STRING_MACRLC_REMOTE_S_PORTD, NULL, 0, uptr:NULL, defintval:50021, TYPE_UINT, 0}, \
+{CONFIG_STRING_MACRLC_ULSCH_MAX_SLOTS_INACTIVITY, "Maximum number of slots before a UE is scheduled ULSCH due to inactivity", 0, uptr:NULL, defintval:200, TYPE_UINT, 0}, \
}
#define MACRLC_CC_IDX 0
#define MACRLC_TRANSPORT_N_PREFERENCE_IDX 1
@@ -97,5 +98,6 @@
#define MACRLC_REMOTE_S_PORTC_IDX 14
#define MACRLC_LOCAL_S_PORTD_IDX 15
#define MACRLC_REMOTE_S_PORTD_IDX 16
+#define MACRLC_ULSCH_MAX_SLOTS_INACTIVITY 17
/*---------------------------------------------------------------------------------------------------------------------------------------------------------*/
#endif
diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c
index 1acb962859..e578e98c5e 100644
--- a/openair2/GNB_APP/gnb_config.c
+++ b/openair2/GNB_APP/gnb_config.c
@@ -54,7 +54,7 @@
//#include "L1_paramdef.h"
#include "L1_nr_paramdef.h"
-#include "MACRLC_paramdef.h"
+#include "MACRLC_nr_paramdef.h"
#include "common/config/config_userapi.h"
//#include "RRC_config_tools.h"
#include "gnb_paramdef.h"
@@ -699,6 +699,7 @@ void RCconfig_nr_macrlc() {
}else { // other midhaul
AssertFatal(1==0,"MACRLC %d: %s unknown southbound midhaul\n",j,*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_PREFERENCE_IDX].strptr));
}
+ RC.nrmac[j]->ulsch_max_slots_inactivity = *(MacRLC_ParamList.paramarray[j][MACRLC_ULSCH_MAX_SLOTS_INACTIVITY].uptr);
}// for (j=0;j 0
AssertFatal (0,"No " CONFIG_STRING_MACRLC_LIST " configuration found");
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
index d956bdd1ab..03f8109638 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
@@ -817,7 +817,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
using tables 7.3.1.2.2-1, 7.3.1.2.2-2, 7.3.1.2.2-3, 7.3.1.2.2-4 of 3GPP TS 38.212 */
dlsch_config_pdu_1_1->n_dmrs_cdm_groups = 1;
/* VRB_TO_PRB_MAPPING */
- if (mac->phy_config.config_req.dl_bwp_dedicated.pdsch_config_dedicated.resource_allocation != 0)
+ if ((pdsch_config->resourceAllocation == 1) && (pdsch_config->vrb_ToPRB_Interleaver != NULL))
dlsch_config_pdu_1_1->vrb_to_prb_mapping = (dci->vrb_to_prb_mapping.val == 0) ? vrb_to_prb_mapping_non_interleaved:vrb_to_prb_mapping_interleaved;
/* PRB_BUNDLING_SIZE_IND */
dlsch_config_pdu_1_1->prb_bundling_size_ind = dci->prb_bundling_size_indicator.val;
@@ -876,11 +876,22 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
/* PDSCH_TO_HARQ_FEEDBACK_TIME_IND */
// according to TS 38.213 Table 9.2.3-1
NR_BWP_Id_t ul_bwp_id = mac->UL_BWP_Id;
- dlsch_config_pdu_1_1->pdsch_to_harq_feedback_time_ind = mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->dl_DataToUL_ACK->list.array[dci->pdsch_to_harq_feedback_timing_indicator.val][0];
+ dlsch_config_pdu_1_1->pdsch_to_harq_feedback_time_ind =
+ mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->dl_DataToUL_ACK->list.array[dci->pdsch_to_harq_feedback_timing_indicator.val][0];
+
/* ANTENNA_PORTS */
uint8_t n_codewords = 1; // FIXME!!!
- if ((mac->phy_config.config_req.dl_bwp_dedicated.pdsch_config_dedicated.dmrs_dl_for_pdsch_mapping_type_a.dmrs_type == 1) &&
- (mac->phy_config.config_req.dl_bwp_dedicated.pdsch_config_dedicated.dmrs_dl_for_pdsch_mapping_type_a.max_length == 1)){
+ long *max_length = NULL;
+ long *dmrs_type = NULL;
+ if (pdsch_config->dmrs_DownlinkForPDSCH_MappingTypeA) {
+ max_length = pdsch_config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->maxLength;
+ dmrs_type = pdsch_config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type;
+ }
+ if (pdsch_config->dmrs_DownlinkForPDSCH_MappingTypeB) {
+ max_length = pdsch_config->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->maxLength;
+ dmrs_type = pdsch_config->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->dmrs_Type;
+ }
+ if ((dmrs_type == NULL) && (max_length == NULL)){
// Table 7.3.1.2.2-1: Antenna port(s) (1000 + DMRS port), dmrs-Type=1, maxLength=1
dlsch_config_pdu_1_1->n_dmrs_cdm_groups = table_7_3_2_3_3_1[dci->antenna_ports.val][0];
dlsch_config_pdu_1_1->dmrs_ports[0] = table_7_3_2_3_3_1[dci->antenna_ports.val][1];
@@ -888,8 +899,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
dlsch_config_pdu_1_1->dmrs_ports[2] = table_7_3_2_3_3_1[dci->antenna_ports.val][3];
dlsch_config_pdu_1_1->dmrs_ports[3] = table_7_3_2_3_3_1[dci->antenna_ports.val][4];
}
- if ((mac->phy_config.config_req.dl_bwp_dedicated.pdsch_config_dedicated.dmrs_dl_for_pdsch_mapping_type_a.dmrs_type == 1) &&
- (mac->phy_config.config_req.dl_bwp_dedicated.pdsch_config_dedicated.dmrs_dl_for_pdsch_mapping_type_a.max_length == 2)){
+ if ((dmrs_type == NULL) && (max_length != NULL)){
// Table 7.3.1.2.2-2: Antenna port(s) (1000 + DMRS port), dmrs-Type=1, maxLength=2
if (n_codewords == 1) {
dlsch_config_pdu_1_1->n_dmrs_cdm_groups = table_7_3_2_3_3_2_oneCodeword[dci->antenna_ports.val][0];
@@ -912,8 +922,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
dlsch_config_pdu_1_1->n_front_load_symb = table_7_3_2_3_3_2_twoCodeword[dci->antenna_ports.val][9];
}
}
- if ((mac->phy_config.config_req.dl_bwp_dedicated.pdsch_config_dedicated.dmrs_dl_for_pdsch_mapping_type_a.dmrs_type == 2) &&
- (mac->phy_config.config_req.dl_bwp_dedicated.pdsch_config_dedicated.dmrs_dl_for_pdsch_mapping_type_a.max_length == 1)){
+ if ((dmrs_type != NULL) && (max_length == NULL)){
// Table 7.3.1.2.2-3: Antenna port(s) (1000 + DMRS port), dmrs-Type=2, maxLength=1
if (n_codewords == 1) {
dlsch_config_pdu_1_1->n_dmrs_cdm_groups = table_7_3_2_3_3_3_oneCodeword[dci->antenna_ports.val][0];
@@ -932,8 +941,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
dlsch_config_pdu_1_1->dmrs_ports[5] = table_7_3_2_3_3_3_twoCodeword[dci->antenna_ports.val][6];
}
}
- if ((mac->phy_config.config_req.dl_bwp_dedicated.pdsch_config_dedicated.dmrs_dl_for_pdsch_mapping_type_a.dmrs_type == 2) &&
- (mac->phy_config.config_req.dl_bwp_dedicated.pdsch_config_dedicated.dmrs_dl_for_pdsch_mapping_type_a.max_length == 2)){
+ if ((dmrs_type != NULL) && (max_length != NULL)){
// Table 7.3.1.2.2-4: Antenna port(s) (1000 + DMRS port), dmrs-Type=2, maxLength=2
if (n_codewords == 1) {
dlsch_config_pdu_1_1->n_dmrs_cdm_groups = table_7_3_2_3_3_4_oneCodeword[dci->antenna_ports.val][0];
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
index 2f41e6499c..0011f3fc1f 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
@@ -151,14 +151,25 @@ fapi_nr_ul_config_request_t *get_ul_config_request(NR_UE_MAC_INST_t *mac, int sl
void ul_layers_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu, dci_pdu_rel15_t *dci) {
- fapi_nr_pusch_config_dedicated_t *pusch_config_dedicated = &mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated;
+ NR_ServingCellConfigCommon_t *scc = mac->scc;
NR_PUSCH_Config_t *pusch_Config = mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup;
+ long transformPrecoder;
+ if (pusch_Config->transformPrecoder)
+ transformPrecoder = *pusch_Config->transformPrecoder;
+ else {
+ if(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder)
+ transformPrecoder = NR_PUSCH_Config__transformPrecoder_enabled;
+ else
+ transformPrecoder = NR_PUSCH_Config__transformPrecoder_disabled;
+ }
+
+
/* PRECOD_NBR_LAYERS */
- if ((pusch_config_dedicated->tx_config == tx_config_nonCodebook));
+ if ((*pusch_Config->txConfig == NR_PUSCH_Config__txConfig_nonCodebook));
// 0 bits if the higher layer parameter txConfig = nonCodeBook
- if ((pusch_config_dedicated->tx_config == tx_config_codebook)){
+ if ((*pusch_Config->txConfig == NR_PUSCH_Config__txConfig_codebook)){
uint8_t n_antenna_port = 0; //FIXME!!!
@@ -167,43 +178,43 @@ void ul_layers_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_con
if (n_antenna_port == 4){ // 4 antenna port and the higher layer parameter txConfig = codebook
// Table 7.3.1.1.2-2: transformPrecoder=disabled and maxRank = 2 or 3 or 4
- if ((pusch_config_dedicated->transform_precoder == transform_precoder_disabled)
- && ((pusch_config_dedicated->max_rank == 2) ||
- (pusch_config_dedicated->max_rank == 3) ||
- (pusch_config_dedicated->max_rank == 4))){
+ if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled)
+ && ((*pusch_Config->maxRank == 2) ||
+ (*pusch_Config->maxRank == 3) ||
+ (*pusch_Config->maxRank == 4))){
- if (pusch_config_dedicated->codebook_subset == codebook_subset_fullyAndPartialAndNonCoherent) {
+ if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_fullyAndPartialAndNonCoherent) {
pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][0];
pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][1];
}
- if (pusch_config_dedicated->codebook_subset == codebook_subset_partialAndNonCoherent){
+ if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_partialAndNonCoherent){
pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][2];
pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][3];
}
- if (pusch_config_dedicated->codebook_subset == codebook_subset_nonCoherent){
+ if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_nonCoherent){
pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][4];
pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][5];
}
}
// Table 7.3.1.1.2-3: transformPrecoder= enabled, or transformPrecoder=disabled and maxRank = 1
- if (((pusch_config_dedicated->transform_precoder == transform_precoder_enabled)
- || (pusch_config_dedicated->transform_precoder == transform_precoder_disabled))
- && (pusch_config_dedicated->max_rank == 1)){
+ if (((transformPrecoder == NR_PUSCH_Config__transformPrecoder_enabled)
+ || (transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled))
+ && (*pusch_Config->maxRank == 1)){
- if (pusch_config_dedicated->codebook_subset == codebook_subset_fullyAndPartialAndNonCoherent) {
+ if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_fullyAndPartialAndNonCoherent) {
pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][6];
pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][7];
}
- if (pusch_config_dedicated->codebook_subset == codebook_subset_partialAndNonCoherent){
+ if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_partialAndNonCoherent){
pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][8];
pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][9];
}
- if (pusch_config_dedicated->codebook_subset == codebook_subset_nonCoherent){
+ if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_nonCoherent){
pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][10];
pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][11];
}
@@ -212,14 +223,14 @@ void ul_layers_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_con
if (n_antenna_port == 4){ // 2 antenna port and the higher layer parameter txConfig = codebook
// Table 7.3.1.1.2-4: transformPrecoder=disabled and maxRank = 2
- if ((pusch_config_dedicated->transform_precoder == transform_precoder_disabled) && (pusch_config_dedicated->max_rank == 2)){
+ if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) && (*pusch_Config->maxRank == 2)){
- if (pusch_config_dedicated->codebook_subset == codebook_subset_fullyAndPartialAndNonCoherent) {
+ if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_fullyAndPartialAndNonCoherent) {
pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][12];
pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][13];
}
- if (pusch_config_dedicated->codebook_subset == codebook_subset_nonCoherent){
+ if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_nonCoherent){
pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][14];
pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][15];
}
@@ -227,16 +238,16 @@ void ul_layers_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_con
}
// Table 7.3.1.1.2-5: transformPrecoder= enabled, or transformPrecoder= disabled and maxRank = 1
- if (((pusch_config_dedicated->transform_precoder == transform_precoder_enabled)
- || (pusch_config_dedicated->transform_precoder == transform_precoder_disabled))
- && (pusch_config_dedicated->max_rank == 1)){
+ if (((transformPrecoder == NR_PUSCH_Config__transformPrecoder_enabled)
+ || (transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled))
+ && (*pusch_Config->maxRank == 1)){
- if (pusch_config_dedicated->codebook_subset == codebook_subset_fullyAndPartialAndNonCoherent) {
+ if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_fullyAndPartialAndNonCoherent) {
pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][16];
pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][17];
}
- if (pusch_config_dedicated->codebook_subset == codebook_subset_nonCoherent){
+ if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_nonCoherent){
pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][18];
pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][19];
}
@@ -247,7 +258,7 @@ void ul_layers_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_con
/*-------------------- Changed to enable Transform precoding in RF SIM------------------------------------------------*/
- if (pusch_config_pdu->transform_precoding == transform_precoder_enabled) {
+ /*if (pusch_config_pdu->transform_precoding == transform_precoder_enabled) {
pusch_config_dedicated->transform_precoder = transform_precoder_enabled;
@@ -271,15 +282,7 @@ void ul_layers_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_con
}
} else
- pusch_config_dedicated->transform_precoder = transform_precoder_disabled;
-
- // mapping type b configured from RRC. TBD: Mapping type b is not handled in this function.
- if ((pusch_config_dedicated->transform_precoder == transform_precoder_enabled) &&
- (pusch_config_dedicated->dmrs_ul_for_pusch_mapping_type_b.dmrs_type == 1) &&
- (pusch_config_dedicated->dmrs_ul_for_pusch_mapping_type_b.max_length == 1)) { // tables 7.3.1.1.2-6
- pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2;
- pusch_config_pdu->dmrs_ports = dci->antenna_ports.val;
- }
+ pusch_config_dedicated->transform_precoder = transform_precoder_disabled;*/
}
// todo: this function shall be reviewed completely because of the many comments left by the author
@@ -287,27 +290,47 @@ void ul_ports_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_conf
/* ANTENNA_PORTS */
uint8_t rank = 0; // We need to initialize rank FIXME!!!
- fapi_nr_pusch_config_dedicated_t *pusch_config_dedicated = &mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated;
- if ((pusch_config_dedicated->transform_precoder == transform_precoder_enabled) &&
- (pusch_config_dedicated->dmrs_ul_for_pusch_mapping_type_a.dmrs_type == 1) &&
- (pusch_config_dedicated->dmrs_ul_for_pusch_mapping_type_a.max_length == 1)) { // tables 7.3.1.1.2-6
+ NR_ServingCellConfigCommon_t *scc = mac->scc;
+ NR_PUSCH_Config_t *pusch_Config = mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup;
+
+ long transformPrecoder;
+ if (pusch_Config->transformPrecoder)
+ transformPrecoder = *pusch_Config->transformPrecoder;
+ else {
+ if(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder)
+ transformPrecoder = NR_PUSCH_Config__transformPrecoder_enabled;
+ else
+ transformPrecoder = NR_PUSCH_Config__transformPrecoder_disabled;
+ }
+ long *max_length = NULL;
+ long *dmrs_type = NULL;
+ if (pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA) {
+ max_length = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA->choice.setup->maxLength;
+ dmrs_type = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA->choice.setup->dmrs_Type;
+ }
+ else {
+ max_length = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->maxLength;
+ dmrs_type = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->dmrs_Type;
+ }
+
+
+ if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_enabled) &&
+ (dmrs_type == NULL) && (max_length == NULL)) { // tables 7.3.1.1.2-6
pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; //TBC
pusch_config_pdu->dmrs_ports = dci->antenna_ports.val; //TBC
}
- if ((pusch_config_dedicated->transform_precoder == transform_precoder_enabled) &&
- (pusch_config_dedicated->dmrs_ul_for_pusch_mapping_type_a.dmrs_type == 1) &&
- (pusch_config_dedicated->dmrs_ul_for_pusch_mapping_type_a.max_length == 2)) { // tables 7.3.1.1.2-7
+ if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_enabled) &&
+ (dmrs_type == NULL) && (max_length != NULL)) { // tables 7.3.1.1.2-7
pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; //TBC
pusch_config_pdu->dmrs_ports = (dci->antenna_ports.val > 3)?(dci->antenna_ports.val-4):(dci->antenna_ports.val); //TBC
//pusch_config_pdu->n_front_load_symb = (dci->antenna_ports > 3)?2:1; //FIXME
}
- if ((pusch_config_dedicated->transform_precoder == transform_precoder_disabled) &&
- (pusch_config_dedicated->dmrs_ul_for_pusch_mapping_type_a.dmrs_type == 1) &&
- (pusch_config_dedicated->dmrs_ul_for_pusch_mapping_type_a.max_length == 1)) { // tables 7.3.1.1.2-8/9/10/11
+ if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) &&
+ (dmrs_type == NULL) && (max_length == NULL)) { // tables 7.3.1.1.2-8/9/10/11
if (rank == 1) {
pusch_config_pdu->num_dmrs_cdm_grps_no_data = (dci->antenna_ports.val > 1)?2:1; //TBC
@@ -339,9 +362,8 @@ void ul_ports_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_conf
}
}
- if ((pusch_config_dedicated->transform_precoder == transform_precoder_disabled) &&
- (pusch_config_dedicated->dmrs_ul_for_pusch_mapping_type_a.dmrs_type == 1) &&
- (pusch_config_dedicated->dmrs_ul_for_pusch_mapping_type_a.max_length == 2)) { // tables 7.3.1.1.2-12/13/14/15
+ if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) &&
+ (dmrs_type == NULL) && (max_length != NULL)) { // tables 7.3.1.1.2-12/13/14/15
if (rank == 1){
pusch_config_pdu->num_dmrs_cdm_grps_no_data = (dci->antenna_ports.val > 1)?2:1; //TBC
@@ -377,9 +399,9 @@ void ul_ports_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_conf
}
}
- if ((pusch_config_dedicated->transform_precoder == transform_precoder_disabled) &&
- (pusch_config_dedicated->dmrs_ul_for_pusch_mapping_type_a.dmrs_type == 2) &&
- (pusch_config_dedicated->dmrs_ul_for_pusch_mapping_type_a.max_length == 1)) { // tables 7.3.1.1.2-16/17/18/19
+ if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) &&
+ (dmrs_type != NULL) &&
+ (max_length == NULL)) { // tables 7.3.1.1.2-16/17/18/19
if (rank == 1){
pusch_config_pdu->num_dmrs_cdm_grps_no_data = (dci->antenna_ports.val > 1)?((dci->antenna_ports.val > 5)?3:2):1; //TBC
@@ -411,9 +433,8 @@ void ul_ports_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_conf
}
}
- if ((pusch_config_dedicated->transform_precoder == transform_precoder_disabled) &&
- (pusch_config_dedicated->dmrs_ul_for_pusch_mapping_type_a.dmrs_type == 2) &&
- (pusch_config_dedicated->dmrs_ul_for_pusch_mapping_type_a.max_length == 2)) { // tables 7.3.1.1.2-20/21/22/23
+ if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) &&
+ (dmrs_type != NULL) && (max_length != NULL)) { // tables 7.3.1.1.2-20/21/22/23
if (rank == 1){
pusch_config_pdu->num_dmrs_cdm_grps_no_data = table_7_3_1_1_2_20[dci->antenna_ports.val][0]; //TBC
@@ -571,7 +592,6 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
int target_ss;
bool valid_ptrs_setup = 0;
uint16_t n_RB_ULBWP = NRRIV2BW(mac->ULbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
- fapi_nr_pusch_config_dedicated_t *pusch_config_dedicated = &mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated;
NR_PUSCH_Config_t *pusch_Config = mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup;
// Basic sanity check for MCS value to check for a false or erroneous DCI
@@ -654,7 +674,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
}
/* FREQ_HOPPING_FLAG */
- if ((pusch_config_dedicated->resource_allocation != 0) && (pusch_config_dedicated->frequency_hopping !=0)){
+ if ((pusch_Config->frequencyHopping!=NULL) && (pusch_Config->resourceAllocation != NR_PUSCH_Config__resourceAllocation_resourceAllocationType0)){
pusch_config_pdu->frequency_hopping = dci->frequency_hopping_flag.val;
}
diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c
index 528edc64aa..98e9ce4351 100644
--- a/openair2/LAYER2/NR_MAC_gNB/config.c
+++ b/openair2/LAYER2/NR_MAC_gNB/config.c
@@ -372,14 +372,6 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
AssertFatal(RC.nrmac[Mod_idP]->common_channels[0].vrb_map_UL,
"could not allocate memory for RC.nrmac[]->common_channels[0].vrb_map_UL\n");
- for (int i = 0; i < MAX_NUM_BWP; ++i) {
- RC.nrmac[Mod_idP]->pucch_index_used[i] =
- calloc(n, sizeof(*RC.nrmac[Mod_idP]->pucch_index_used));
- AssertFatal(RC.nrmac[Mod_idP]->pucch_index_used[i],
- "could not allocate memory for RC.nrmac[]->pucch_index_used[%d]\n",
- i);
- }
-
LOG_I(MAC,"Configuring common parameters from NR ServingCellConfig\n");
config_common(Mod_idP,
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
index 7175a129ba..36f687b5cd 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
@@ -402,7 +402,7 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
}
// This schedule SR
- // TODO
+ nr_sr_reporting(module_idP, frame, slot);
// Schedule CSI measurement reporting: check in slot 0 for the whole frame
if (slot == 0)
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c
index 91142c3728..2b94c07e1e 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c
@@ -253,8 +253,8 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
case 3:
// long bitmap FR2 max 64 SSBs
num_ssb = 0;
- for (int i_ssb=0; i_ssb<63; i_ssb++) {
- if ((longBitmap->buf[i_ssb/8]>>(7-i_ssb))&0x01) {
+ for (int i_ssb=0; i_ssb<64; i_ssb++) {
+ if ((longBitmap->buf[i_ssb/8]>>(7-(i_ssb%8)))&0x01) {
ssb_start_symbol = get_ssb_start_symbol(band,scs,i_ssb);
// if start symbol is in current slot, schedule current SSB, fill VRB map and call get_type0_PDCCH_CSS_config_parameters
if ((ssb_start_symbol/14) == rel_slot){
@@ -427,8 +427,8 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP,
bwp);
// TODO: This assignment should be done in function nr_configure_pdcch()
- pdcch_pdu_rel15->BWPSize = gNB_mac->type0_PDCCH_CSS_config->num_rbs;
- pdcch_pdu_rel15->BWPStart = gNB_mac->type0_PDCCH_CSS_config->cset_start_rb;
+ pdcch_pdu_rel15->BWPSize = type0_PDCCH_CSS_config->num_rbs;
+ pdcch_pdu_rel15->BWPStart = type0_PDCCH_CSS_config->cset_start_rb;
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
memset((void*)dl_tti_pdsch_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t));
@@ -589,25 +589,26 @@ void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
uint8_t sib1_sdu_length = mac_rrc_nr_data_req(module_idP, CC_id, frameP, BCCH, SI_RNTI, 1, sib1_payload);
LOG_D(NR_MAC,"sib1_sdu_length = %i\n", sib1_sdu_length);
LOG_D(NR_MAC,"SIB1: \n");
- for (int k=0;kcommon_channels->ServingCellConfigCommon->dmrs_TypeA_Position == 0) {
- startSymbolIndex = table_5_1_2_1_1_2_time_dom_res_alloc_A_dmrs_typeA_pos2[gNB_mac->sched_ctrlCommon->pdsch_semi_static.time_domain_allocation][1];
- nrOfSymbols = table_5_1_2_1_1_2_time_dom_res_alloc_A_dmrs_typeA_pos2[gNB_mac->sched_ctrlCommon->pdsch_semi_static.time_domain_allocation][2];
- } else {
- startSymbolIndex = table_5_1_2_1_1_2_time_dom_res_alloc_A_dmrs_typeA_pos3[gNB_mac->sched_ctrlCommon->pdsch_semi_static.time_domain_allocation][1];
- nrOfSymbols = table_5_1_2_1_1_2_time_dom_res_alloc_A_dmrs_typeA_pos3[gNB_mac->sched_ctrlCommon->pdsch_semi_static.time_domain_allocation][2];
- }
+ int startSymbolIndex = 0;
+ int nrOfSymbols = 0;
+ if(gNB_mac->common_channels->ServingCellConfigCommon->dmrs_TypeA_Position == 0) {
+ startSymbolIndex = table_5_1_2_1_1_2_time_dom_res_alloc_A_dmrs_typeA_pos2[gNB_mac->sched_ctrlCommon->pdsch_semi_static.time_domain_allocation][1];
+ nrOfSymbols = table_5_1_2_1_1_2_time_dom_res_alloc_A_dmrs_typeA_pos2[gNB_mac->sched_ctrlCommon->pdsch_semi_static.time_domain_allocation][2];
+ } else {
+ startSymbolIndex = table_5_1_2_1_1_2_time_dom_res_alloc_A_dmrs_typeA_pos3[gNB_mac->sched_ctrlCommon->pdsch_semi_static.time_domain_allocation][1];
+ nrOfSymbols = table_5_1_2_1_1_2_time_dom_res_alloc_A_dmrs_typeA_pos3[gNB_mac->sched_ctrlCommon->pdsch_semi_static.time_domain_allocation][2];
+ }
- // Calculate number of PRB_DMRS
- uint8_t N_PRB_DMRS = gNB_mac->sched_ctrlCommon->pdsch_semi_static.numDmrsCdmGrpsNoData * 6;
- uint16_t dlDmrsSymbPos = fill_dmrs_mask(NULL, gNB_mac->common_channels->ServingCellConfigCommon->dmrs_TypeA_Position, nrOfSymbols, startSymbolIndex);
- uint16_t dmrs_length = get_num_dmrs(dlDmrsSymbPos);
+ // Calculate number of PRB_DMRS
+ uint8_t N_PRB_DMRS = gNB_mac->sched_ctrlCommon->pdsch_semi_static.numDmrsCdmGrpsNoData * 6;
+ uint16_t dlDmrsSymbPos = fill_dmrs_mask(NULL, gNB_mac->common_channels->ServingCellConfigCommon->dmrs_TypeA_Position, nrOfSymbols, startSymbolIndex);
+ uint16_t dmrs_length = get_num_dmrs(dlDmrsSymbPos);
const uint32_t TBS = nr_compute_tbs(nr_get_Qm_dl(gNB_mac->sched_ctrlCommon->sched_pdsch.mcs, gNB_mac->sched_ctrlCommon->pdsch_semi_static.mcsTableIdx),
nr_get_code_rate_dl(gNB_mac->sched_ctrlCommon->sched_pdsch.mcs, gNB_mac->sched_ctrlCommon->pdsch_semi_static.mcsTableIdx),
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c
index f477066fc6..800c23a9a0 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c
@@ -118,8 +118,13 @@ int diff_rsrp_ssb_csi_meas_10_1_6_1_2[16] = {
void nr_schedule_pucch(int Mod_idP,
frame_t frameP,
- sub_frame_t slotP) {
- NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
+ sub_frame_t slotP)
+{
+ gNB_MAC_INST *nrmac = RC.nrmac[Mod_idP];
+ if (!is_xlsch_in_slot(nrmac->ulsch_slot_bitmap[slotP / 64], slotP))
+ return;
+
+ NR_UE_info_t *UE_info = &nrmac->UE_info;
const NR_list_t *UE_list = &UE_info->list;
for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
@@ -504,11 +509,11 @@ void nr_csi_meas_reporting(int Mod_idP,
// find free PUCCH that is in order with possibly existing PUCCH
// schedulings (other CSI, SR)
- NR_sched_pucch_t *curr_pucch = &sched_ctrl->sched_pucch[2];
+ NR_sched_pucch_t *curr_pucch = &sched_ctrl->sched_pucch[1];
AssertFatal(curr_pucch->csi_bits == 0
&& !curr_pucch->sr_flag
&& curr_pucch->dai_c == 0,
- "PUCCH not free at index 2 for UE %04x\n",
+ "PUCCH not free at index 1 for UE %04x\n",
UE_info->rnti[UE_id]);
curr_pucch->frame = frame;
curr_pucch->ul_slot = sched_slot;
@@ -1007,14 +1012,6 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id,
NR_UE_info_t *UE_info = &RC.nrmac[mod_id]->UE_info;
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
- // tpc (power control)
- sched_ctrl->tpc1 = nr_get_tpc(RC.nrmac[mod_id]->pucch_target_snrx10,
- uci_01->ul_cqi,
- 30);
- sched_ctrl->pucch_snrx10 = uci_01->ul_cqi * 5 - 640;
-
- NR_ServingCellConfigCommon_t *scc = RC.nrmac[mod_id]->common_channels->ServingCellConfigCommon;
- const int num_slots = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
if (((uci_01->pduBitmap >> 1) & 0x01)) {
// iterate over received harq bits
for (int harq_bit = 0; harq_bit < uci_01->harq->num_harq; harq_bit++) {
@@ -1029,6 +1026,20 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id,
handle_dl_harq(mod_id, UE_id, pid, harq_value == 1 && harq_confidence == 0);
}
}
+
+ // check scheduling request result, confidence_level == 0 is good
+ if (uci_01->pduBitmap & 0x1 && uci_01->sr->sr_indication && uci_01->sr->sr_confidence_level == 0 && uci_01->ul_cqi >= 148) {
+ // SR detected with SNR >= 10dB
+ sched_ctrl->SR |= true;
+ LOG_D(MAC, "SR UE %04x ul_cqi %d\n", uci_01->rnti, uci_01->ul_cqi);
+ }
+
+ // tpc (power control) only if we received AckNack or positive SR. For a
+ // negative SR, the UE won't have sent anything, and the SNR is not valid
+ if (((uci_01->pduBitmap >> 1) & 0x1) || sched_ctrl->SR) {
+ sched_ctrl->tpc1 = nr_get_tpc(RC.nrmac[mod_id]->pucch_target_snrx10, uci_01->ul_cqi, 30);
+ sched_ctrl->pucch_snrx10 = uci_01->ul_cqi * 5 - 640;
+ }
}
void handle_nr_uci_pucch_2_3_4(module_id_t mod_id,
@@ -1051,8 +1062,6 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id,
30);
sched_ctrl->pucch_snrx10 = uci_234->ul_cqi * 5 - 640;
- NR_ServingCellConfigCommon_t *scc = RC.nrmac[mod_id]->common_channels->ServingCellConfigCommon;
- const int num_slots = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
if ((uci_234->pduBitmap >> 1) & 0x01) {
// iterate over received harq bits
for (int harq_bit = 0; harq_bit < uci_234->harq.harq_bit_len; harq_bit++) {
@@ -1104,10 +1113,7 @@ bool nr_acknack_scheduling(int mod_id,
* * we do not multiplex with CSI, which is always in pucch_sched[2]
* * SR uses format 0 and is allocated in the first UL (mixed) slot (and not
* later)
- * * that the PUCCH resource set 0 (for up to 2 bits) points to the first N
- * PUCCH resources, where N is the number of resources in the PUCCH
- * resource set. This is used in pucch_index_used, which counts the used
- * resources by index, and not by their ID! */
+ * * each UE has dedicated PUCCH Format 0 resources, and we use index 0! */
NR_UE_sched_ctrl_t *sched_ctrl = &RC.nrmac[mod_id]->UE_info.UE_sched_ctrl[UE_id];
NR_sched_pucch_t *pucch = &sched_ctrl->sched_pucch[0];
AssertFatal(pucch->csi_bits == 0,
@@ -1115,12 +1121,8 @@ bool nr_acknack_scheduling(int mod_id,
__func__,
pucch->csi_bits);
- const int max_acknacks = 2;
- AssertFatal(pucch->dai_c + pucch->sr_flag <= max_acknacks,
- "illegal number of bits in PUCCH of UE %d\n",
- UE_id);
/* if the currently allocated PUCCH of this UE is full, allocate it */
- if (pucch->sr_flag + pucch->dai_c == max_acknacks) {
+ if (pucch->dai_c == 2) {
/* advance the UL slot information in PUCCH by one so we won't schedule in
* the same slot again */
const int f = pucch->frame;
@@ -1130,7 +1132,7 @@ bool nr_acknack_scheduling(int mod_id,
pucch->frame = s == n_slots_frame - 1 ? (f + 1) % 1024 : f;
pucch->ul_slot = (s + 1) % n_slots_frame;
// we assume that only two indices over the array sched_pucch exist
- const NR_sched_pucch_t *csi_pucch = &sched_ctrl->sched_pucch[2];
+ NR_sched_pucch_t *csi_pucch = &sched_ctrl->sched_pucch[1];
// skip the CSI PUCCH if it is present and if in the next frame/slot
if (csi_pucch->csi_bits > 0
&& csi_pucch->frame == pucch->frame
@@ -1142,6 +1144,7 @@ bool nr_acknack_scheduling(int mod_id,
pucch->ul_slot,
UE_id);
nr_fill_nfapi_pucch(mod_id, frame, slot, csi_pucch, UE_id);
+ memset(csi_pucch, 0, sizeof(*csi_pucch));
pucch->frame = s >= n_slots_frame - 2 ? (f + 1) % 1024 : f;
pucch->ul_slot = (s + 2) % n_slots_frame;
}
@@ -1160,9 +1163,8 @@ bool nr_acknack_scheduling(int mod_id,
uint8_t pdsch_to_harq_feedback[8];
get_pdsch_to_harq_feedback(mod_id, UE_id, ss_type, pdsch_to_harq_feedback);
- /* there is a scheduled SR or HARQ. Check whether we can use it for this
- * ACKNACK */
- if (pucch->sr_flag + pucch->dai_c > 0) {
+ /* there is a HARQ. Check whether we can use it for this ACKNACK */
+ if (pucch->dai_c > 0) {
/* this UE already has a PUCCH occasion */
DevAssert(pucch->frame == frame);
@@ -1193,18 +1195,14 @@ bool nr_acknack_scheduling(int mod_id,
/* we need to find a new PUCCH occasion */
- NR_PUCCH_Config_t *pucch_Config = sched_ctrl->active_ubwp->bwp_Dedicated->pucch_Config->choice.setup;
- DevAssert(pucch_Config->resourceToAddModList->list.count > 0);
- DevAssert(pucch_Config->resourceSetToAddModList->list.count > 0);
- const int n_res = pucch_Config->resourceSetToAddModList->list.array[0]->resourceList.list.count;
- int *pucch_index_used = RC.nrmac[mod_id]->pucch_index_used[sched_ctrl->active_ubwp->bwp_Id];
-
/* if time information is outdated (e.g., last PUCCH occasion in last frame),
* set to first possible UL occasion in this frame. Note that if such UE is
* scheduled a lot and used all AckNacks, pucch->frame might have been
* wrapped around to next frame */
if (frame != pucch->frame || pucch->ul_slot < first_ul_slot_tdd) {
- DevAssert(pucch->sr_flag + pucch->dai_c == 0);
+ AssertFatal(pucch->sr_flag + pucch->dai_c == 0,
+ "expected no SR/AckNack for UE %d in %4d.%2d, but has %d/%d for %4d.%2d\n",
+ UE_id, frame, slot, pucch->sr_flag, pucch->dai_c, pucch->frame, pucch->ul_slot);
AssertFatal(frame + 1 != pucch->frame,
"frame wrap around not handled in %s() yet\n",
__func__);
@@ -1212,27 +1210,11 @@ bool nr_acknack_scheduling(int mod_id,
pucch->ul_slot = first_ul_slot_tdd;
}
- // increase to first slot in which PUCCH resources are available
- while (pucch_index_used[pucch->ul_slot] >= n_res) {
- pucch->ul_slot++;
- /* if there is no free resource anymore, abort search */
- if ((pucch->frame == frame
- && pucch->ul_slot >= first_ul_slot_tdd + nr_ulmix_slots)
- || (pucch->frame == frame + 1)) {
- LOG_E(MAC,
- "%4d.%2d no free PUCCH resources anymore while searching for UE %d\n",
- frame,
- slot,
- UE_id);
- return false;
- }
- }
-
// advance ul_slot if it is not reachable by UE
pucch->ul_slot = max(pucch->ul_slot, slot + pdsch_to_harq_feedback[0]);
// is there already CSI in this slot?
- const NR_sched_pucch_t *csi_pucch = &sched_ctrl->sched_pucch[2];
+ NR_sched_pucch_t *csi_pucch = &sched_ctrl->sched_pucch[1];
// skip the CSI PUCCH if it is present and if in the next frame/slot
if (csi_pucch->csi_bits > 0
&& csi_pucch->frame == pucch->frame
@@ -1244,6 +1226,7 @@ bool nr_acknack_scheduling(int mod_id,
pucch->ul_slot,
UE_id);
nr_fill_nfapi_pucch(mod_id, frame, slot, csi_pucch, UE_id);
+ memset(csi_pucch, 0, sizeof(*csi_pucch));
/* advance the UL slot information in PUCCH by one so we won't schedule in
* the same slot again */
const int f = pucch->frame;
@@ -1274,29 +1257,19 @@ bool nr_acknack_scheduling(int mod_id,
pucch->timing_indicator = i; // index in the list of timing indicators
pucch->dai_c++;
- const int pucch_res = pucch_index_used[pucch->ul_slot];
- pucch->resource_indicator = pucch_res;
- pucch_index_used[pucch->ul_slot] += 1;
- AssertFatal(pucch_index_used[pucch->ul_slot] <= n_res,
- "UE %d in %4d.%2d: pucch_index_used is %d (%d available)\n",
- UE_id,
- pucch->frame,
- pucch->ul_slot,
- pucch_index_used[pucch->ul_slot],
- n_res);
+ pucch->resource_indicator = 0; // each UE has dedicated PUCCH resources
/* verify that at that slot and symbol, resources are free. We only do this
* for initialCyclicShift 0 (we assume it always has that one), so other
* initialCyclicShifts can overlap with ICS 0!*/
- const NR_PUCCH_Resource_t *resource =
- pucch_Config->resourceToAddModList->list.array[pucch_res];
+ const NR_PUCCH_Config_t *pucch_Config = sched_ctrl->active_ubwp->bwp_Dedicated->pucch_Config->choice.setup;
+ const NR_PUCCH_Resource_t *resource = pucch_Config->resourceToAddModList->list.array[pucch->resource_indicator];
DevAssert(resource->format.present == NR_PUCCH_Resource__format_PR_format0);
if (resource->format.choice.format0->initialCyclicShift == 0) {
uint16_t *vrb_map_UL = &RC.nrmac[mod_id]->common_channels[CC_id].vrb_map_UL[pucch->ul_slot * MAX_BWP_SIZE];
const uint16_t symb = 1 << resource->format.choice.format0->startingSymbolIndex;
- AssertFatal((vrb_map_UL[resource->startingPRB] & symb) == 0,
- "symbol %x is not free for PUCCH alloc in vrb_map_UL at RB %ld and slot %d\n",
- symb, resource->startingPRB, pucch->ul_slot);
+ if ((vrb_map_UL[resource->startingPRB] & symb) != 0)
+ LOG_W(MAC, "symbol 0x%x is not free for PUCCH alloc in vrb_map_UL at RB %ld and slot %d.%d\n", symb, resource->startingPRB, pucch->frame, pucch->ul_slot);
vrb_map_UL[resource->startingPRB] |= symb;
}
return true;
@@ -1429,3 +1402,154 @@ uint16_t compute_pucch_prb_size(uint8_t format,
AssertFatal(1==0,"Not yet implemented");
}
}
+
+void nr_sr_reporting(int Mod_idP, frame_t SFN, sub_frame_t slot)
+{
+ gNB_MAC_INST *nrmac = RC.nrmac[Mod_idP];
+ if (!is_xlsch_in_slot(nrmac->ulsch_slot_bitmap[slot / 64], slot))
+ return;
+ NR_ServingCellConfigCommon_t *scc = nrmac->common_channels->ServingCellConfigCommon;
+ const int n_slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
+ NR_UE_info_t *UE_info = &nrmac->UE_info;
+ NR_list_t *UE_list = &UE_info->list;
+ for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
+ NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
+ NR_PUCCH_Config_t *pucch_Config = sched_ctrl->active_ubwp->bwp_Dedicated->pucch_Config->choice.setup;
+ AssertFatal(pucch_Config->schedulingRequestResourceToAddModList->list.count>0,"NO SR configuration available");
+
+ for (int SR_resource_id =0; SR_resource_id < pucch_Config->schedulingRequestResourceToAddModList->list.count;SR_resource_id++) {
+ NR_SchedulingRequestResourceConfig_t *SchedulingRequestResourceConfig = pucch_Config->schedulingRequestResourceToAddModList->list.array[SR_resource_id];
+
+ int SR_period; int SR_offset;
+
+ periodicity__SRR(SchedulingRequestResourceConfig,&SR_period,&SR_offset);
+ // convert to int to avoid underflow of uint
+ int sfn_sf = SFN * n_slots_frame + slot;
+ if ((sfn_sf - SR_offset) % SR_period != 0)
+ continue;
+ LOG_D(MAC, "%4d.%2d Scheduling Request identified\n", SFN, slot);
+ NR_PUCCH_ResourceId_t *PucchResourceId = SchedulingRequestResourceConfig->resource;
+
+ int found = -1;
+ NR_PUCCH_ResourceSet_t *pucchresset = pucch_Config->resourceSetToAddModList->list.array[0]; // set with formats 0,1
+ int n_list = pucchresset->resourceList.list.count;
+ for (int i=0; iresourceList.list.array[i] == *PucchResourceId )
+ found = i;
+ }
+ AssertFatal(found>-1,"SR resource not found among PUCCH resources");
+
+ /* loop through nFAPI PUCCH messages: if the UEs is in there in this slot
+ * with the resource_indicator, it means we already allocated that PUCCH
+ * resource for AckNack (e.g., the UE has been scheduled often), and we
+ * just need to add the SR_flag. Otherwise, just allocate in the internal
+ * PUCCH resource, and nr_schedule_pucch() will handle the rest */
+ NR_PUCCH_Resource_t *pucch_res = pucch_Config->resourceToAddModList->list.array[found];
+ /* for the moment, can only handle SR on PUCCH Format 0 */
+ DevAssert(pucch_res->format.present == NR_PUCCH_Resource__format_PR_format0);
+ nfapi_nr_ul_tti_request_t *ul_tti_req = &nrmac->UL_tti_req_ahead[0][slot];
+ bool nfapi_allocated = false;
+ for (int i = 0; i < ul_tti_req->n_pdus; ++i) {
+ if (ul_tti_req->pdus_list[i].pdu_type != NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE)
+ continue;
+ nfapi_nr_pucch_pdu_t *pdu = &ul_tti_req->pdus_list[i].pucch_pdu;
+ /* check that it is our PUCCH F0. Assuming there can be only one */
+ if (pdu->rnti == UE_info->rnti[UE_id]
+ && pdu->format_type == 0 // does not use NR_PUCCH_Resource__format_PR_format0
+ && pdu->initial_cyclic_shift == pucch_res->format.choice.format0->initialCyclicShift
+ && pdu->nr_of_symbols == pucch_res->format.choice.format0->nrofSymbols
+ && pdu->start_symbol_index == pucch_res->format.choice.format0->startingSymbolIndex) {
+ LOG_D(MAC,"%4d.%2d adding SR_flag 1 to PUCCH nFAPI SR for RNTI %04x\n", SFN, slot, pdu->rnti);
+ pdu->sr_flag = 1;
+ nfapi_allocated = true;
+ break;
+ }
+ }
+
+ if (nfapi_allocated) // break scheduling resource loop, continue next UE
+ break;
+
+ /* we did not find it: check if current PUCCH is for the current slot, in
+ * which case we add the SR to it; otherwise, allocate SR separately */
+ NR_sched_pucch_t *curr_pucch = &sched_ctrl->sched_pucch[0];
+ if (curr_pucch->frame == SFN && curr_pucch->ul_slot == slot) {
+ if (curr_pucch->resource_indicator != found) {
+ LOG_W(MAC, "%4d.%2d expected PUCCH in this slot to have resource indicator of SR (%d), skipping SR\n", SFN, slot, found);
+ continue;
+ }
+ curr_pucch->sr_flag = true;
+ } else {
+ NR_sched_pucch_t sched_sr;
+ memset(&sched_sr, 0, sizeof(sched_sr));
+ sched_sr.frame = SFN;
+ sched_sr.ul_slot = slot;
+ sched_sr.resource_indicator = found;
+ sched_sr.sr_flag = true;
+ nr_fill_nfapi_pucch(Mod_idP, SFN, slot, &sched_sr, UE_id);
+ }
+ }
+ }
+}
+
+
+void periodicity__SRR (NR_SchedulingRequestResourceConfig_t *SchedulingReqRec, int *period, int *offset)
+{
+ NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR P_O = SchedulingReqRec->periodicityAndOffset->present;
+ switch (P_O){
+ case NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl1:
+ *period = 1;
+ *offset = SchedulingReqRec->periodicityAndOffset->choice.sl1;
+ break;
+ case NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl2:
+ *period = 2;
+ *offset = SchedulingReqRec->periodicityAndOffset->choice.sl2;
+ break;
+ case NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl4:
+ *period = 4;
+ *offset = SchedulingReqRec->periodicityAndOffset->choice.sl4;
+ break;
+ case NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl5:
+ *period = 5;
+ *offset = SchedulingReqRec->periodicityAndOffset->choice.sl5;
+ break;
+ case NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl8:
+ *period = 8;
+ *offset = SchedulingReqRec->periodicityAndOffset->choice.sl8;
+ break;
+ case NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl10:
+ *period = 10;
+ *offset = SchedulingReqRec->periodicityAndOffset->choice.sl10;
+ break;
+ case NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl16:
+ *period = 16;
+ *offset = SchedulingReqRec->periodicityAndOffset->choice.sl16;
+ break;
+ case NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl20:
+ *period = 20;
+ *offset = SchedulingReqRec->periodicityAndOffset->choice.sl20;
+ break;
+ case NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl40:
+ *period = 40;
+ *offset = SchedulingReqRec->periodicityAndOffset->choice.sl40;
+ break;
+ case NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl80:
+ *period = 80;
+ *offset = SchedulingReqRec->periodicityAndOffset->choice.sl80;
+ break;
+ case NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl160:
+ *period = 160;
+ *offset = SchedulingReqRec->periodicityAndOffset->choice.sl160;
+ break;
+ case NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl320:
+ *period = 320;
+ *offset = SchedulingReqRec->periodicityAndOffset->choice.sl320;
+ break;
+ case NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl640:
+ *period = 640;
+ *offset = SchedulingReqRec->periodicityAndOffset->choice.sl640;
+ break;
+ default:
+ AssertFatal(1==0,"No periodicityAndOffset resources found in schedulingrequestresourceconfig");
+ }
+}
+
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
index a2e066d8c5..323baa48a7 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
@@ -745,6 +745,34 @@ long get_K2(const NR_BWP_Uplink_t *ubwp, int time_domain_assignment, int mu) {
return 3;
}
+bool nr_UE_is_to_be_scheduled(module_id_t mod_id, int CC_id, int UE_id, frame_t frame, sub_frame_t slot)
+{
+ const NR_ServingCellConfigCommon_t *scc = RC.nrmac[mod_id]->common_channels->ServingCellConfigCommon;
+ const uint8_t slots_per_frame[5] = {10, 20, 40, 80, 160};
+ const int n = slots_per_frame[*scc->ssbSubcarrierSpacing];
+ const int now = frame * n + slot;
+
+ const struct gNB_MAC_INST_s *nrmac = RC.nrmac[mod_id];
+ const NR_UE_sched_ctrl_t *sched_ctrl = &nrmac->UE_info.UE_sched_ctrl[UE_id];
+ const int last_ul_sched = sched_ctrl->last_ul_frame * n + sched_ctrl->last_ul_slot;
+
+ const int diff = (now - last_ul_sched + 1024 * n) % (1024 * n);
+ /* UE is to be scheduled if
+ * (1) we think the UE has more bytes awaiting than what we scheduled
+ * (2) there is a scheduling request
+ * (3) or we did not schedule it in more than 10 frames */
+ const bool has_data = sched_ctrl->estimated_ul_buffer > sched_ctrl->sched_ul_bytes;
+ const bool high_inactivity = diff >= nrmac->ulsch_max_slots_inactivity;
+ LOG_D(MAC,
+ "%4d.%2d UL inactivity %d slots has_data %d SR %d\n",
+ frame,
+ slot,
+ diff,
+ has_data,
+ sched_ctrl->SR);
+ return has_data || sched_ctrl->SR || high_inactivity;
+}
+
int next_list_entry_looped(NR_list_t *list, int UE_id)
{
if (UE_id < 0)
@@ -874,7 +902,6 @@ void update_ul_ue_R_Qm(NR_sched_pusch_t *sched_pusch, const NR_pusch_semi_static
float ul_thr_ue[MAX_MOBILES_PER_GNB];
uint32_t ul_pf_tbs[3][28]; // pre-computed, approximate TBS values for PF coefficient
-int bsr0ue = -1;
void pf_ul(module_id_t module_id,
frame_t frame,
sub_frame_t slot,
@@ -894,12 +921,6 @@ void pf_ul(module_id_t module_id,
int ue_array[MAX_MOBILES_PER_GNB];
NR_list_t UE_sched = { .head = -1, .next = ue_array, .tail = -1, .len = MAX_MOBILES_PER_GNB };
- /* Hack: currently, we do not have SR, and need to schedule UEs continuously.
- * To keep the wasted resources low, we switch UEs to be scheduled in a
- * round-robin fashion below, and only schedule a UE with BSR=0 if it is the
- * selected one */
- bsr0ue = next_list_entry_looped(UE_list, bsr0ue);
-
/* Loop UE_list to calculate throughput and coeff */
for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
@@ -931,11 +952,16 @@ void pf_ul(module_id_t module_id,
continue;
}
- /* Check BSR and schedule UE if it is zero to avoid starvation, since we do
- * not have SR (yet) */
- if (sched_ctrl->estimated_ul_buffer - sched_ctrl->sched_ul_bytes <= 0) {
- if (UE_id != bsr0ue)
- continue;
+ const int B = max(0, sched_ctrl->estimated_ul_buffer - sched_ctrl->sched_ul_bytes);
+ /* preprocessor computed sched_frame/sched_slot */
+ const bool do_sched = nr_UE_is_to_be_scheduled(module_id, 0, UE_id, sched_pusch->frame, sched_pusch->slot);
+
+ if (B == 0 && !do_sched)
+ continue;
+
+ /* Schedule UE on SR or UL inactivity and no data (otherwise, will be scheduled
+ * based on data to transmit) */
+ if (B == 0 && do_sched) {
/* if no data, pre-allocate 5RB */
bool freeCCE = find_free_CCE(module_id, slot, UE_id);
if (!freeCCE) {
@@ -1106,7 +1132,7 @@ bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
int K2 = get_K2(sched_ctrl->active_ubwp, tda, mu);
const int sched_frame = frame + (slot + K2 >= nr_slots_per_frame[mu]);
const int sched_slot = (slot + K2) % nr_slots_per_frame[mu];
- if (!is_xlsch_in_slot(nr_mac->ulsch_slot_bitmap[slot / 64], sched_slot))
+ if (!is_xlsch_in_slot(nr_mac->ulsch_slot_bitmap[sched_slot / 64], sched_slot))
return false;
sched_ctrl->sched_pusch.slot = sched_slot;
@@ -1218,6 +1244,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
UE_info->mac_stats[UE_id].ulsch_current_bytes = 0;
+
/* dynamic PUSCH values (RB alloc, MCS, hence R, Qm, TBS) that change in
* every TTI are pre-populated by the preprocessor and used below */
NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
@@ -1225,6 +1252,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
continue;
uint16_t rnti = UE_info->rnti[UE_id];
+ sched_ctrl->SR = false;
int8_t harq_id = sched_pusch->ul_harq_pid;
if (harq_id < 0) {
@@ -1281,6 +1309,8 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
cur_harq->ndi);
}
UE_info->mac_stats[UE_id].ulsch_current_bytes = sched_pusch->tb_size;
+ sched_ctrl->last_ul_frame = sched_pusch->frame;
+ sched_ctrl->last_ul_slot = sched_pusch->slot;
LOG_D(MAC,
"%4d.%2d RNTI %04x UL sched %4d.%2d start %2d RBS %3d startSymbol %2d nb_symbol %2d MCS %2d TBS %4d HARQ PID %2d round %d NDI %d est %6d sched %6d est BSR %6d\n",
diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
index 4256097174..4bf82dd002 100644
--- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
+++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
@@ -414,4 +414,10 @@ bool nr_find_nb_rb(uint16_t Qm,
uint32_t *tbs,
uint16_t *nb_rb);
+void nr_sr_reporting(int Mod_idP, frame_t frameP, sub_frame_t slotP);
+
+void periodicity__SRR (NR_SchedulingRequestResourceConfig_t *SchedulingReqRecconf,
+ int *period,
+ int *offset);
+
#endif /*__LAYER2_NR_MAC_PROTO_H__*/
diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
index c8ea892ca5..52255b8f32 100644
--- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
+++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
@@ -522,11 +522,9 @@ typedef struct {
int cce_index;
uint8_t aggregation_level;
- /// PUCCH scheduling information. Array of three, we assume for the moment:
- /// HARQ in the first field, SR in second, CSI in third (as fixed by RRC
- /// conf., i.e. if actually present). The order is important for
- /// nr_acknack_scheduling()!
- NR_sched_pucch_t sched_pucch[3];
+ /// PUCCH scheduling information. Array of two: HARQ+SR in the first field,
+ /// CSI in second. This order is important for nr_acknack_scheduling()!
+ NR_sched_pucch_t sched_pucch[2];
/// PUSCH semi-static configuration: is not cleared across TTIs
NR_pusch_semi_static_t pusch_semi_static;
@@ -547,6 +545,9 @@ typedef struct {
NR_pdsch_semi_static_t pdsch_semi_static;
/// Sched PDSCH: scheduling decisions, copied into HARQ and cleared every TTI
NR_sched_pdsch_t sched_pdsch;
+ /// For UL synchronization: store last UL scheduling grant
+ frame_t last_ul_frame;
+ sub_frame_t last_ul_slot;
/// total amount of data awaiting for this UE
uint32_t num_total_bytes;
@@ -563,6 +564,8 @@ typedef struct {
int pucch_snrx10;
struct CSI_Report CSI_report[MAX_CSI_REPORTS];
+ bool SR;
+
/// information about every HARQ process
NR_UE_harq_t harq_processes[NR_MAX_NB_HARQ_PROCESSES];
/// HARQ processes that are free
@@ -705,10 +708,6 @@ typedef struct gNB_MAC_INST_s {
int cce_list[MAX_NUM_BWP][MAX_NUM_CORESET][MAX_NUM_CCE];
/// list of allocated beams per period
int16_t *tdd_beam_association;
- /// PUCCH: keep track of the resources has already been used by saving the
- /// highest index not yet been used in a given slot. Dynamically allocated
- /// so we can have it for every slot as a function of the numerology
- int *pucch_index_used[MAX_NUM_BWP];
/// bitmap of DLSCH slots, can hold up to 160 slots
uint64_t dlsch_slot_bitmap[3];
@@ -722,6 +721,9 @@ typedef struct gNB_MAC_INST_s {
/// points to the right UL slot
int *preferred_ul_tda[MAX_NUM_BWP];
+ /// maximum number of slots before a UE will be scheduled ULSCH automatically
+ uint32_t ulsch_max_slots_inactivity;
+
/// DL preprocessor for differentiated scheduling
nr_pp_impl_dl pre_processor_dl;
/// UL preprocessor for differentiated scheduling
diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c
index 88333272cb..66553e813b 100644
--- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c
+++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c
@@ -73,7 +73,8 @@ void nr_rlc_bearer_init_ul_spec(struct NR_LogicalChannelConfig *mac_LogicalChann
mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelGroup = calloc(1,sizeof(*mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelGroup));
*mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelGroup = 1;
- mac_LogicalChannelConfig->ul_SpecificParameters->schedulingRequestID = NULL;
+ mac_LogicalChannelConfig->ul_SpecificParameters->schedulingRequestID = calloc(1,sizeof(*mac_LogicalChannelConfig->ul_SpecificParameters->schedulingRequestID));
+ *mac_LogicalChannelConfig->ul_SpecificParameters->schedulingRequestID = 0;
mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelSR_Mask = false;
mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelSR_DelayTimerApplied = false;
mac_LogicalChannelConfig->ul_SpecificParameters->bitRateQueryProhibitTimer = NULL;
diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c
index e42d19167d..a789f0c34e 100644
--- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c
+++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c
@@ -105,10 +105,6 @@ void handle_nr_uci(NR_UL_IND_t *UL_info)
}
UL_info->uci_ind.num_ucis = 0;
-
- // mark corresponding PUCCH resources as free
- // NOTE: we just assume it is BWP ID 1, to be revised for multiple BWPs
- RC.nrmac[mod_id]->pucch_index_used[1][slot] = 0;
}
diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c
index a26a4ac5b1..39222f814d 100644
--- a/openair2/RRC/NR/MESSAGES/asn1_msg.c
+++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c
@@ -1287,7 +1287,8 @@ uint16_t do_RRCReconfiguration(
// 1,
// 1,
// carrier->pdsch_AntennaPorts,
- // carrier->initial_csi_index[gnb_rrc_inst->Nb_ue]);
+ // carrier->initial_csi_index[ue_context_p->local_uid + 1],
+ // ue_context_pP->local_uid);
/******************** Meas Config ********************/
// measConfig
diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h
index ea7b853c03..7923cf6e05 100644
--- a/openair2/RRC/NR/nr_rrc_proto.h
+++ b/openair2/RRC/NR/nr_rrc_proto.h
@@ -85,14 +85,16 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
int scg_id,
int servCellIndex,
int n_physical_antenna_ports,
- int initial_csi_index);
+ int initial_csi_index,
+ int uid);
void fill_default_reconfig(NR_ServingCellConfigCommon_t *servingcellconfigcommon,
NR_ServingCellConfig_t *servingcellconfigdedicated,
NR_RRCReconfiguration_IEs_t *reconfig,
NR_CellGroupConfig_t *secondaryCellGroup,
int n_physical_antenna_ports,
- int initial_csi_index);
+ int initial_csi_index,
+ int uid);
void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig,
int eps_bearer_id, int rb_id,
diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c
index 2336c758fc..7861f2166c 100644
--- a/openair2/RRC/NR/rrc_gNB_nsa.c
+++ b/openair2/RRC/NR/rrc_gNB_nsa.c
@@ -152,7 +152,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
ue_context_p->ue_context.reconfig->criticalExtensions.present = NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration;
NR_RRCReconfiguration_IEs_t *reconfig_ies=calloc(1,sizeof(NR_RRCReconfiguration_IEs_t));
ue_context_p->ue_context.reconfig->criticalExtensions.choice.rrcReconfiguration = reconfig_ies;
- carrier->initial_csi_index[rrc->Nb_ue] = 0;
+ carrier->initial_csi_index[ue_context_p->local_uid + 1] = 0;
ue_context_p->ue_context.rb_config = calloc(1,sizeof(NR_RRCReconfiguration_t));
if (get_softmodem_params()->phy_test == 1 || get_softmodem_params()->do_ra == 1 || get_softmodem_params()->sa == 1){
fill_default_rbconfig(ue_context_p->ue_context.rb_config,
@@ -245,14 +245,16 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
reconfig_ies,
ue_context_p->ue_context.secondaryCellGroup,
carrier->pdsch_AntennaPorts,
- carrier->initial_csi_index[rrc->Nb_ue]);
+ carrier->initial_csi_index[ue_context_p->local_uid + 1],
+ ue_context_p->local_uid);
} else {
fill_default_reconfig(carrier->servingcellconfigcommon,
NULL,
reconfig_ies,
ue_context_p->ue_context.secondaryCellGroup,
carrier->pdsch_AntennaPorts,
- carrier->initial_csi_index[rrc->Nb_ue]);
+ carrier->initial_csi_index[ue_context_p->local_uid + 1],
+ ue_context_p->local_uid);
}
ue_context_p->ue_id_rnti = ue_context_p->ue_context.secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity;
NR_CG_Config_t *CG_Config = calloc(1,sizeof(*CG_Config));
diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c
index cd5ded9714..e7e60aa312 100644
--- a/openair2/RRC/NR/rrc_gNB_reconfig.c
+++ b/openair2/RRC/NR/rrc_gNB_reconfig.c
@@ -149,7 +149,8 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
int scg_id,
int servCellIndex,
int n_physical_antenna_ports,
- int initial_csi_index) {
+ int initial_csi_index,
+ int uid) {
AssertFatal(servingcellconfigcommon!=NULL,"servingcellconfigcommon is null\n");
AssertFatal(secondaryCellGroup!=NULL,"secondaryCellGroup is null\n");
@@ -184,7 +185,17 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
ASN_SEQUENCE_ADD(&secondaryCellGroup->rlc_BearerToAddModList->list, RLC_BearerConfig);
secondaryCellGroup->mac_CellGroupConfig=calloc(1,sizeof(*secondaryCellGroup->mac_CellGroupConfig));
secondaryCellGroup->mac_CellGroupConfig->drx_Config = NULL;
- secondaryCellGroup->mac_CellGroupConfig->schedulingRequestConfig = NULL;
+
+ secondaryCellGroup->mac_CellGroupConfig->schedulingRequestConfig = calloc(1,sizeof(*secondaryCellGroup->mac_CellGroupConfig->schedulingRequestConfig));
+ secondaryCellGroup->mac_CellGroupConfig->schedulingRequestConfig->schedulingRequestToAddModList = calloc(1,sizeof(*secondaryCellGroup->mac_CellGroupConfig->schedulingRequestConfig->schedulingRequestToAddModList));
+ NR_SchedulingRequestToAddMod_t *SchedulingRequestConf = calloc(1,sizeof(*SchedulingRequestConf));
+ SchedulingRequestConf->schedulingRequestId = 0; //Could be changed
+ SchedulingRequestConf->sr_ProhibitTimer = calloc(1,sizeof(*SchedulingRequestConf->sr_ProhibitTimer));
+ *SchedulingRequestConf->sr_ProhibitTimer = NR_SchedulingRequestToAddMod__sr_ProhibitTimer_ms16;
+ SchedulingRequestConf->sr_TransMax = NR_SchedulingRequestToAddMod__sr_TransMax_n32;
+ ASN_SEQUENCE_ADD(&secondaryCellGroup->mac_CellGroupConfig->schedulingRequestConfig->schedulingRequestToAddModList->list,SchedulingRequestConf);
+ secondaryCellGroup->mac_CellGroupConfig->schedulingRequestConfig->schedulingRequestToReleaseList = NULL;
+
secondaryCellGroup->mac_CellGroupConfig->bsr_Config=calloc(1,sizeof(*secondaryCellGroup->mac_CellGroupConfig->bsr_Config));
secondaryCellGroup->mac_CellGroupConfig->bsr_Config->periodicBSR_Timer = NR_BSR_Config__periodicBSR_Timer_sf10;
secondaryCellGroup->mac_CellGroupConfig->bsr_Config->retxBSR_Timer = NR_BSR_Config__retxBSR_Timer_sf160;
@@ -251,7 +262,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
if ((bitmap>>(63-i))&0x01){
ssbElem[n_ssb] = calloc(1,sizeof(struct NR_CFRA_SSB_Resource));
ssbElem[n_ssb]->ssb = i;
- ssbElem[n_ssb]->ra_PreambleIndex = 63;
+ ssbElem[n_ssb]->ra_PreambleIndex = 63 - (uid % 64);
ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list,ssbElem[n_ssb]);
n_ssb++;
}
@@ -263,8 +274,8 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
secondaryCellGroup->spCellConfig->rlf_TimersAndConstants = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->rlf_TimersAndConstants));
secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->present = NR_SetupRelease_RLF_TimersAndConstants_PR_setup;
secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup=calloc(1,sizeof(*secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup));
- secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup->t310 = NR_RLF_TimersAndConstants__t310_ms2000;
- secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup->n310 = NR_RLF_TimersAndConstants__n310_n10;
+ secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup->t310 = NR_RLF_TimersAndConstants__t310_ms4000;
+ secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup->n310 = NR_RLF_TimersAndConstants__n310_n20;
secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup->n311 = NR_RLF_TimersAndConstants__n311_n1;
secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup->ext1 = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup->ext1));
secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup->ext1->t311 = NR_RLF_TimersAndConstants__ext1__t311_ms30000;
@@ -975,7 +986,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
NR_PUCCH_Resource_t *pucchres2=calloc(1,sizeof(*pucchres2));
NR_PUCCH_Resource_t *pucchres3=calloc(1,sizeof(*pucchres3));
pucchres0->pucch_ResourceId=1;
- pucchres0->startingPRB=8;
+ pucchres0->startingPRB= (8 + uid) % curr_bwp;
pucchres0->intraSlotFrequencyHopping=NULL;
pucchres0->secondHopPRB=NULL;
pucchres0->format.present= NR_PUCCH_Resource__format_PR_format0;
@@ -986,7 +997,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
ASN_SEQUENCE_ADD(&pucch_Config->resourceToAddModList->list,pucchres0);
pucchres1->pucch_ResourceId=2;
- pucchres1->startingPRB=8;
+ pucchres1->startingPRB= (8 + uid) % curr_bwp;
pucchres1->intraSlotFrequencyHopping=NULL;
pucchres1->secondHopPRB=NULL;
pucchres1->format.present= NR_PUCCH_Resource__format_PR_format0;
@@ -1029,7 +1040,19 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
pucchfmt2->nrofSlots=NULL;
pucchfmt2->pi2BPSK=NULL;
pucchfmt2->simultaneousHARQ_ACK_CSI=NULL;
- pucch_Config->schedulingRequestResourceToAddModList=NULL;
+
+ // for scheduling requestresource
+ pucch_Config->schedulingRequestResourceToAddModList = calloc(1,sizeof(*pucch_Config->schedulingRequestResourceToAddModList));
+ NR_SchedulingRequestResourceConfig_t *schedulingRequestResourceConfig = calloc(1,sizeof(*schedulingRequestResourceConfig));
+ schedulingRequestResourceConfig->schedulingRequestResourceId = 1;
+ schedulingRequestResourceConfig->schedulingRequestID = 0;
+ schedulingRequestResourceConfig->periodicityAndOffset = calloc(1,sizeof(*schedulingRequestResourceConfig->periodicityAndOffset));
+ schedulingRequestResourceConfig->periodicityAndOffset->present = NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl10;
+ schedulingRequestResourceConfig->periodicityAndOffset->choice.sl10 = 7;
+ schedulingRequestResourceConfig->resource = calloc(1,sizeof(*schedulingRequestResourceConfig->resource));
+ *schedulingRequestResourceConfig->resource = 1;
+ ASN_SEQUENCE_ADD(&pucch_Config->schedulingRequestResourceToAddModList->list,schedulingRequestResourceConfig);
+
pucch_Config->schedulingRequestResourceToReleaseList=NULL;
pucch_Config->multi_CSI_PUCCH_ResourceList=NULL;
pucch_Config->dl_DataToUL_ACK = calloc(1,sizeof(*pucch_Config->dl_DataToUL_ACK));
@@ -1177,7 +1200,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
csirep1->reportConfigType.present = NR_CSI_ReportConfig__reportConfigType_PR_periodic;
csirep1->reportConfigType.choice.periodic = calloc(1,sizeof(*csirep1->reportConfigType.choice.periodic));
csirep1->reportConfigType.choice.periodic->reportSlotConfig.present=NR_CSI_ReportPeriodicityAndOffset_PR_slots320;
- csirep1->reportConfigType.choice.periodic->reportSlotConfig.choice.slots320 = 49;
+ csirep1->reportConfigType.choice.periodic->reportSlotConfig.choice.slots320 = 9 + (10 * uid) % 320;
NR_PUCCH_CSI_Resource_t *pucchcsires1 = calloc(1,sizeof(*pucchcsires1));
pucchcsires1->uplinkBandwidthPartId=1;
pucchcsires1->pucch_Resource=3;
@@ -1241,14 +1264,22 @@ void fill_default_reconfig(NR_ServingCellConfigCommon_t *servingcellconfigcommon
NR_RRCReconfiguration_IEs_t *reconfig,
NR_CellGroupConfig_t *secondaryCellGroup,
int n_physical_antenna_ports,
- int initial_csi_index) {
+ int initial_csi_index,
+ int uid) {
AssertFatal(servingcellconfigcommon!=NULL,"servingcellconfigcommon is null\n");
AssertFatal(reconfig!=NULL,"reconfig is null\n");
AssertFatal(secondaryCellGroup!=NULL,"secondaryCellGroup is null\n");
// radioBearerConfig
reconfig->radioBearerConfig=NULL;
// secondaryCellGroup
- fill_default_secondaryCellGroup(servingcellconfigcommon,servingcellconfigdedicated,secondaryCellGroup,1,1,n_physical_antenna_ports,initial_csi_index);
+ fill_default_secondaryCellGroup(servingcellconfigcommon,
+ servingcellconfigdedicated,
+ secondaryCellGroup,
+ 1,
+ 1,
+ n_physical_antenna_ports,
+ initial_csi_index,
+ uid);
xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void*)secondaryCellGroup);
char scg_buffer[1024];
diff --git a/openair2/X2AP/x2ap_eNB.c b/openair2/X2AP/x2ap_eNB.c
index 321190015d..0474d417df 100644
--- a/openair2/X2AP/x2ap_eNB.c
+++ b/openair2/X2AP/x2ap_eNB.c
@@ -130,6 +130,18 @@ void x2ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa
DevAssert(x2ap_enb_data_p != NULL);
dump_trees();
+ /* gNB: exit if connection to eNB failed - to be modified if needed.
+ * We may want to try to connect over and over again until we succeed
+ * but the modifications to the code to get this behavior are complex.
+ * Exit on error is a simple solution that can be caught by a script
+ * for example.
+ */
+ if (instance_p->cell_type == CELL_MACRO_GNB
+ && sctp_new_association_resp->sctp_state == SCTP_STATE_UNREACHABLE) {
+ X2AP_ERROR("association with eNB failed, is it running? If no, run it first. If yes, check IP addresses in your configuration file.\n");
+ exit(1);
+ }
+
if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) {
X2AP_WARN("Received unsuccessful result for SCTP association (%u), instance %ld, cnx_id %u\n",
sctp_new_association_resp->sctp_state,
diff --git a/openair3/NAS/TOOLS/ue_sim_ci.conf b/openair3/NAS/TOOLS/ue_sim_ci.conf
new file mode 100644
index 0000000000..5d95c9ba3f
--- /dev/null
+++ b/openair3/NAS/TOOLS/ue_sim_ci.conf
@@ -0,0 +1,45 @@
+# List of known PLMNS
+PLMN: {
+ PLMN0: {
+ FULLNAME="OpenAirInterface";
+ SHORTNAME="OAICN";
+ MNC="96";
+ MCC="208";
+ };
+};
+
+UE0:
+{
+ USER: {
+ IMEI="356113022094149";
+ MANUFACTURER="OAI";
+ MODEL="LTE SoftModem";
+ PIN="0000";
+ };
+
+ SIM: {
+ MSIN="0100001111";
+ USIM_API_K="8baf473f2f8fd09487cccbd7097c6862";
+ OPC="e734f8734007d6c5ce7a0508809e7e9c";
+ MSISDN="33611123456";
+ };
+
+ # Home PLMN Selector with Access Technology
+ HPLMN= "20896";
+
+ # User controlled PLMN Selector with Access Technology
+ UCPLMN_LIST = ();
+
+ # Operator PLMN List
+ OPLMN_LIST = ("20896");
+
+ # Operator controlled PLMN Selector with Access Technology
+ OCPLMN_LIST = ();
+
+ # Forbidden plmns
+ FPLMN_LIST = ();
+
+ # Equivalent home plmns
+ EHPLMN_LIST = ();
+
+};
diff --git a/openshift/oai-physim-image-stream.yml b/openshift/oai-physim-image-stream.yml
new file mode 100644
index 0000000000..9ef338f139
--- /dev/null
+++ b/openshift/oai-physim-image-stream.yml
@@ -0,0 +1,29 @@
+#/*
+# * 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
+# */
+#---------------------------------------------------------------------
+#
+apiVersion: image.openshift.io/v1
+kind: ImageStream
+metadata:
+ name: oai-physim
+spec:
+ lookupPolicy:
+ local: true
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf
index c72ec515dc..4147ec6ae2 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf
@@ -67,17 +67,7 @@ gNBs =
initialDLBWPk0_1 = 0; #for mixed slot
initialDLBWPmappingType_1 = 0;
- initialDLBWPstartSymbolAndLength_1 = 53; #this is SS=1,L=5
-
- initialDLBWPk0_2 = 0;
- initialDLBWPmappingType_2 = 0;
- #this is SS=1,L=12
- initialDLBWPstartSymbolAndLength_2 = 54;
-
- initialDLBWPk0_3 = 0;
- initialDLBWPmappingType_3 = 0;
- #this is SS=1,L=4 //5 (4 is for 43, 5 is for 57)
- initialDLBWPstartSymbolAndLength_3 = 57; //43; //57;
+ initialDLBWPstartSymbolAndLength_1 = 57; #this is SS=1,L=5
#uplinkConfigCommon
#frequencyInfoUL
@@ -103,6 +93,8 @@ gNBs =
prach_msg1_FDM = 0;
prach_msg1_FrequencyStart = 74;
zeroCorrelationZoneConfig = 13;
+ #preambleReceivedTargetPower = -118;
+ #preambleReceivedTargetPower = -104;
preambleReceivedTargetPower = -108;
#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
preambleTransMax = 6;
@@ -285,6 +277,7 @@ RUs = (
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_DISABLE";